From gerrit-no-reply at lists.osmocom.org Sat Apr 1 02:41:01 2017 From: gerrit-no-reply at lists.osmocom.org (Tom Tsou) Date: Sat, 1 Apr 2017 02:41:01 +0000 Subject: [PATCH] osmo-trx[master]: radioInterface: Remove UmTRX 'diversity' option In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2186 to look at the new patch set (#3). radioInterface: Remove UmTRX 'diversity' option The 'diversity' option was an experimental 2 antenna receiver implementation for UmTRX. The implementation has not been maintained and current working status is unknown. In addition to code rot, Coverity is triggering errors in the associated code sections. Removal of code cleans up many cases of special handling that were necessary to accommodate the implementation. Change-Id: I46752ccf5dbcffbec806081dec03e69a0fbdcdb7 --- M Transceiver52M/Makefile.am M Transceiver52M/UHDDevice.cpp M Transceiver52M/USRPDevice.cpp M Transceiver52M/osmo-trx.cpp M Transceiver52M/radioDevice.h M Transceiver52M/radioInterface.cpp M Transceiver52M/radioInterface.h D Transceiver52M/radioInterfaceDiversity.cpp M Transceiver52M/sigProcLib.cpp 9 files changed, 16 insertions(+), 406 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-trx refs/changes/86/2186/3 diff --git a/Transceiver52M/Makefile.am b/Transceiver52M/Makefile.am index 68cdf74..c2ab9ca 100644 --- a/Transceiver52M/Makefile.am +++ b/Transceiver52M/Makefile.am @@ -67,8 +67,7 @@ $(COMMON_SOURCES) \ Resampler.cpp \ radioInterfaceResamp.cpp \ - radioInterfaceMulti.cpp \ - radioInterfaceDiversity.cpp + radioInterfaceMulti.cpp bin_PROGRAMS = osmo-trx diff --git a/Transceiver52M/UHDDevice.cpp b/Transceiver52M/UHDDevice.cpp index c5ea4c1..ce6d1be 100644 --- a/Transceiver52M/UHDDevice.cpp +++ b/Transceiver52M/UHDDevice.cpp @@ -139,16 +139,6 @@ #define NUM_UHD_OFFSETS (sizeof(uhd_offsets)/sizeof(uhd_offsets[0])) /* - * Offset handling for special cases. Currently used for UmTRX dual channel - * diversity receiver only. - */ -static struct uhd_dev_offset special_offsets[] = { - { UMTRX, 1, 1, 8.0875e-5, "UmTRX diversity, 1 SPS" }, - { UMTRX, 4, 1, 5.2103e-5, "UmTRX diversity, 4 SPS" }, -}; - - -/* * Select sample rate based on device type and requested samples-per-symbol. * The base rate is either GSM symbol rate, 270.833 kHz, or the minimum * usable channel spacing of 400 kHz. @@ -156,15 +146,6 @@ static double select_rate(uhd_dev_type type, int sps, RadioDevice::InterfaceType iface) { - if (iface == RadioDevice::DIVERSITY) { - if (type == UMTRX) - return GSMRATE * 4; - - LOG(ALERT) << "Diversity supported on UmTRX only"; - return -9999.99; - } - - if ((sps != 4) && (sps != 1)) return -9999.99; @@ -499,30 +480,13 @@ return 0.0; } - /* Special cases (e.g. diversity receiver) */ - if (iface == DIVERSITY) { - if ((dev_type != UMTRX) || (rx_sps != 1)) { - LOG(ALERT) << "Unsupported device configuration"; - return 0.0; - } - - switch (tx_sps) { - case 1: - offset = &special_offsets[0]; + /* Search for matching offset value */ + for (size_t i = 0; i < NUM_UHD_OFFSETS; i++) { + if ((dev_type == uhd_offsets[i].type) && + (tx_sps == uhd_offsets[i].tx_sps) && + (rx_sps == uhd_offsets[i].rx_sps)) { + offset = &uhd_offsets[i]; break; - case 4: - default: - offset = &special_offsets[1]; - } - } else { - /* Search for matching offset value */ - for (size_t i = 0; i < NUM_UHD_OFFSETS; i++) { - if ((dev_type == uhd_offsets[i].type) && - (tx_sps == uhd_offsets[i].tx_sps) && - (rx_sps == uhd_offsets[i].rx_sps)) { - offset = &uhd_offsets[i]; - break; - } } } @@ -860,9 +824,6 @@ double _rx_rate = select_rate(dev_type, rx_sps, iface); double _tx_rate = select_rate(dev_type, tx_sps, iface); - if (iface == DIVERSITY) - _rx_rate = select_rate(dev_type, 1, iface); - if ((_tx_rate < 0.0) || (_rx_rate < 0.0)) return -1; if (set_rates(_tx_rate, _rx_rate) < 0) @@ -873,8 +834,7 @@ // Setting LMS6002D LPF to 500kHz gives us the best signal quality for (size_t i = 0; i < chans; i++) { usrp_dev->set_tx_bandwidth(500*1000*2, i); - if (iface != DIVERSITY) - usrp_dev->set_rx_bandwidth(500*1000*2, i); + usrp_dev->set_rx_bandwidth(500*1000*2, i); } } else if (dev_type == LIMESDR) { for (size_t i = 0; i < chans; i++) { @@ -917,8 +877,6 @@ // Print configuration LOG(INFO) << "\n" << usrp_dev->get_pp_string(); - if (iface == DIVERSITY) - return DIVERSITY; if (iface == MULTI_ARFCN) return MULTI_ARFCN; diff --git a/Transceiver52M/USRPDevice.cpp b/Transceiver52M/USRPDevice.cpp index 1092600..3d20411 100644 --- a/Transceiver52M/USRPDevice.cpp +++ b/Transceiver52M/USRPDevice.cpp @@ -601,7 +601,7 @@ #endif RadioDevice *RadioDevice::make(size_t tx_sps, size_t rx_sps, - size_t chans, bool diversity, double) + size_t chans, double) { return new USRPDevice(tx_sps); } diff --git a/Transceiver52M/osmo-trx.cpp b/Transceiver52M/osmo-trx.cpp index 5e81586..05322c6 100644 --- a/Transceiver52M/osmo-trx.cpp +++ b/Transceiver52M/osmo-trx.cpp @@ -74,7 +74,6 @@ bool extref; bool gpsref; Transceiver::FillerType filler; - bool diversity; bool mcbts; double offset; double rssi_offset; @@ -174,7 +173,6 @@ } edgestr = config->edge ? "Enabled" : "Disabled"; - divstr = config->diversity ? "Enabled" : "Disabled"; mcstr = config->mcbts ? "Enabled" : "Disabled"; if (config->extref) @@ -215,7 +213,6 @@ ost << " Reference............... " << refstr << std::endl; ost << " C0 Filler Table......... " << fillstr << std::endl; ost << " Multi-Carrier........... " << mcstr << std::endl; - ost << " Diversity............... " << divstr << std::endl; ost << " Tuning offset........... " << config->offset << std::endl; ost << " RSSI to dBm offset...... " << config->rssi_offset << std::endl; ost << " Swap channels........... " << config->swap_channels << std::endl; @@ -245,12 +242,6 @@ case RadioDevice::RESAMP_100M: radio = new RadioInterfaceResamp(usrp, config->tx_sps, config->rx_sps); - break; - case RadioDevice::DIVERSITY: - - - radio = new RadioInterfaceDiversity(usrp, config->tx_sps, - config->chans); break; case RadioDevice::MULTI_ARFCN: radio = new RadioInterfaceMulti(usrp, config->tx_sps, @@ -330,7 +321,6 @@ " -i IP address of GSM core\n" " -p Base port number\n" " -e Enable EDGE receiver\n" - " -d Enable dual channel diversity receiver (deprecated)\n" " -m Enable multi-ARFCN transceiver (default=disabled)\n" " -x Enable external 10 MHz reference\n" " -g Enable GPSDO reference\n" @@ -360,7 +350,6 @@ config->gpsref = false; config->filler = Transceiver::FILLER_ZERO; config->mcbts = false; - config->diversity = false; config->offset = 0.0; config->rssi_offset = 0.0; config->swap_channels = false; @@ -389,9 +378,6 @@ break; case 'm': config->mcbts = true; - break; - case 'd': - config->diversity = true; break; case 'x': config->extref = true; @@ -443,24 +429,6 @@ if (config->gpsref && config->extref) { printf("External and GPSDO references unavailable at the same time\n\n"); goto bad_config; - } - - /* Special restrictions on (deprecated) diversity configuration */ - if (config->diversity) { - if (config->mcbts || config->edge) { - std::cout << "Multi-carrier/EDGE diversity unsupported" << std::endl; - goto bad_config; - } - - if (config->rx_sps != 1) { - std::cout << "Diversity only supported with 1 SPS" << std::endl; - goto bad_config; - } - - if (config->chans != 2) { - std::cout << "Diversity only supported with 2 channels" << std::endl; - goto bad_config; - } } if (config->edge && (config->filler == Transceiver::FILLER_NORM_RAND)) diff --git a/Transceiver52M/radioDevice.h b/Transceiver52M/radioDevice.h index 711d678..3624c58 100644 --- a/Transceiver52M/radioDevice.h +++ b/Transceiver52M/radioDevice.h @@ -41,7 +41,6 @@ RESAMP_64M, RESAMP_100M, MULTI_ARFCN, - DIVERSITY, }; enum ReferenceType { diff --git a/Transceiver52M/radioInterface.cpp b/Transceiver52M/radioInterface.cpp index 7a84430..e039d5c 100644 --- a/Transceiver52M/radioInterface.cpp +++ b/Transceiver52M/radioInterface.cpp @@ -31,11 +31,10 @@ #define NUMCHUNKS 4 RadioInterface::RadioInterface(RadioDevice *wRadio, size_t tx_sps, - size_t rx_sps, size_t chans, size_t diversity, + size_t rx_sps, size_t chans, int wReceiveOffset, GSM::Time wStartTime) : mRadio(wRadio), mSPSTx(tx_sps), mSPSRx(rx_sps), mChans(chans), - mMIMO(diversity), underrun(false), overrun(false), - receiveOffset(wReceiveOffset), mOn(false) + underrun(false), overrun(false), receiveOffset(wReceiveOffset), mOn(false) { mClock.set(wStartTime); } @@ -47,7 +46,7 @@ bool RadioInterface::init(int type) { - if ((type != RadioDevice::NORMAL) || (mMIMO > 1) || !mChans) { + if ((type != RadioDevice::NORMAL) || !mChans) { LOG(ALERT) << "Invalid configuration"; return false; } @@ -253,10 +252,8 @@ */ while (recvSz > burstSize) { for (size_t i = 0; i < mChans; i++) { - burst = new radioVector(rcvClock, burstSize, head, mMIMO); - - for (size_t n = 0; n < mMIMO; n++) - unRadioifyVector(burst->getVector(n), i); + burst = new radioVector(rcvClock, burstSize, head); + unRadioifyVector(burst->getVector(), i); if (mReceiveFIFO[i].size() < 32) mReceiveFIFO[i].write(burst); diff --git a/Transceiver52M/radioInterface.h b/Transceiver52M/radioInterface.h index f77cf9e..531e1a8 100644 --- a/Transceiver52M/radioInterface.h +++ b/Transceiver52M/radioInterface.h @@ -41,7 +41,6 @@ size_t mSPSTx; size_t mSPSRx; size_t mChans; - size_t mMIMO; std::vector sendBuffer; std::vector recvBuffer; @@ -86,8 +85,8 @@ /** constructor */ RadioInterface(RadioDevice* wRadio, size_t tx_sps, size_t rx_sps, - size_t chans = 1, size_t diversity = 1, - int receiveOffset = 3, GSM::Time wStartTime = GSM::Time(0)); + size_t chans = 1, int receiveOffset = 3, + GSM::Time wStartTime = GSM::Time(0)); /** destructor */ virtual ~RadioInterface(); @@ -191,26 +190,4 @@ bool tuneTx(double freq, size_t chan); bool tuneRx(double freq, size_t chan); double setRxGain(double dB, size_t chan); -}; - -class RadioInterfaceDiversity : public RadioInterface { -public: - RadioInterfaceDiversity(RadioDevice* wRadio, size_t tx_sps, size_t chans); - - ~RadioInterfaceDiversity(); - - bool init(int type); - void close(); - bool tuneRx(double freq, size_t chan); - -private: - Resampler *dnsampler; - std::vector phases; - signalVector *outerRecvBuffer; - - bool mDiversity; - double mFreqSpacing; - - bool setupDiversityChannels(); - void pullBuffer(); }; diff --git a/Transceiver52M/radioInterfaceDiversity.cpp b/Transceiver52M/radioInterfaceDiversity.cpp deleted file mode 100644 index c78310c..0000000 --- a/Transceiver52M/radioInterfaceDiversity.cpp +++ /dev/null @@ -1,243 +0,0 @@ -/* - * SSE Convolution - * Copyright (C) 2013 Thomas Tsou - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include - -#include "Resampler.h" - -extern "C" { -#include "convert.h" -} - -/* Resampling parameters for 64 MHz clocking */ -#define RESAMP_64M_INRATE 20 -#define RESAMP_64M_OUTRATE 80 - -/* Downlink block size */ -#define CHUNK 625 - -/* Universal resampling parameters */ -#define NUMCHUNKS 48 - -/* - * Resampling filter bandwidth scaling factor - * This narrows the filter cutoff relative to the output bandwidth - * of the polyphase resampler. At 4 samples-per-symbol using the - * 2 pulse Laurent GMSK approximation gives us below 0.5 degrees - * RMS phase error at the resampler output. - */ -#define RESAMP_TX4_FILTER 0.45 - -static size_t resamp_inrate = 0; -static size_t resamp_inchunk = 0; -static size_t resamp_outrate = 0; -static size_t resamp_outchunk = 0; - -RadioInterfaceDiversity::RadioInterfaceDiversity(RadioDevice *wRadio, - size_t tx_sps, size_t chans) - : RadioInterface(wRadio, tx_sps, 1, chans, 2), outerRecvBuffer(NULL), - mDiversity(false), mFreqSpacing(0.0) -{ -} - -RadioInterfaceDiversity::~RadioInterfaceDiversity() -{ - close(); -} - -void RadioInterfaceDiversity::close() -{ - delete outerRecvBuffer; - delete dnsampler; - - dnsampler = NULL; - outerRecvBuffer = NULL; - - if (recvBuffer.size()) - recvBuffer[0] = NULL; - - RadioInterface::close(); -} - -bool RadioInterfaceDiversity::setupDiversityChannels() -{ - size_t inner_rx_len; - - /* Inner and outer rates */ - resamp_inrate = RESAMP_64M_INRATE; - resamp_outrate = RESAMP_64M_OUTRATE; - resamp_inchunk = resamp_inrate * 4; - resamp_outchunk = resamp_outrate * 4; - - /* Buffer lengths */ - inner_rx_len = NUMCHUNKS * resamp_inchunk; - - /* Inside buffer must hold at least 2 bursts */ - if (inner_rx_len < 157 * mSPSRx * 2) { - LOG(ALERT) << "Invalid inner buffer size " << inner_rx_len; - return false; - } - - dnsampler = new Resampler(resamp_inrate, resamp_outrate); - if (!dnsampler->init()) { - LOG(ALERT) << "Rx resampler failed to initialize"; - return false; - } - - /* One Receive buffer and downsampler per diversity channel */ - for (size_t i = 0; i < mMIMO * mChans; i++) { - recvBuffer[i] = new RadioBuffer(NUMCHUNKS, - resamp_inchunk, 0, false); - } - - return true; -} - -/* Initialize I/O specific objects */ -bool RadioInterfaceDiversity::init(int type) -{ - int outer_rx_len; - - if ((mMIMO != 2) || (mChans != 2)) { - LOG(ALERT) << "Unsupported channel configuration " << mChans; - return false; - } - - /* Resize for channel combination */ - sendBuffer.resize(mChans); - recvBuffer.resize(mChans * mMIMO); - convertSendBuffer.resize(mChans); - convertRecvBuffer.resize(mChans); - mReceiveFIFO.resize(mChans); - phases.resize(mChans); - - if (!setupDiversityChannels()) - return false; - - outer_rx_len = resamp_outchunk; - - for (size_t i = 0; i < mChans; i++) { - /* Full rate float and integer outer receive buffers */ - convertRecvBuffer[i] = new short[outer_rx_len * 2]; - - /* Send buffers (not-resampled) */ - sendBuffer[i] = new RadioBuffer(NUMCHUNKS, CHUNK * mSPSTx, 0, true); - convertSendBuffer[i] = new short[CHUNK * mSPSTx * 2]; - } - - outerRecvBuffer = new signalVector(outer_rx_len, dnsampler->len()); - - return true; -} - -bool RadioInterfaceDiversity::tuneRx(double freq, size_t chan) -{ - double f0, f1; - - if (chan > 1) - return false; - - if (!mRadio->setRxFreq(freq, chan)) - return false; - - f0 = mRadio->getRxFreq(0); - f1 = mRadio->getRxFreq(1); - - mFreqSpacing = f1 - f0; - - if (abs(mFreqSpacing) <= 600e3) - mDiversity = true; - else - mDiversity = false; - - return true; -} - -/* Receive a timestamped chunk from the device */ -void RadioInterfaceDiversity::pullBuffer() -{ - bool local_underrun; - int rc, num, path0, path1; - signalVector *shift, *base; - float *in, *out, rate = -mFreqSpacing * 2.0 * M_PI / 1.08333333e6; - - if (recvBuffer[0]->getFreeSegments() <= 0) - return; - - /* Outer buffer access size is fixed */ - num = mRadio->readSamples(convertRecvBuffer, - resamp_outchunk, - &overrun, - readTimestamp, - &local_underrun); - if ((size_t) num != resamp_outchunk) { - LOG(ALERT) << "Receive error " << num; - return; - } - - for (size_t i = 0; i < mChans; i++) { - convert_short_float((float *) outerRecvBuffer->begin(), - convertRecvBuffer[i], 2 * resamp_outchunk); - - if (!i) { - path0 = 0; - path1 = 2; - } else { - path0 = 3; - path1 = 1; - } - - /* Diversity path 1 */ - base = outerRecvBuffer; - in = (float *) base->begin(); - out = (float *) recvBuffer[path0]->getWriteSegment(); - - rc = dnsampler->rotate(in, resamp_outchunk, - out, resamp_inchunk); - if (rc < 0) { - LOG(ALERT) << "Sample rate downsampling error"; - } - - /* Enable path 2 if Nyquist bandwidth is sufficient */ - if (!mDiversity) - continue; - - /* Diversity path 2 */ - shift = new signalVector(base->size(), base->getStart()); - in = (float *) shift->begin(); - out = (float *) recvBuffer[path1]->getWriteSegment(); - - rate = i ? -rate : rate; - if (!frequencyShift(shift, base, rate, phases[i], &phases[i])) { - LOG(ALERT) << "Frequency shift failed"; - } - - rc = dnsampler->rotate(in, resamp_outchunk, - out, resamp_inchunk); - if (rc < 0) { - LOG(ALERT) << "Sample rate downsampling error"; - } - - delete shift; - } - - underrun |= local_underrun; - readTimestamp += (TIMESTAMP) resamp_outchunk; -} diff --git a/Transceiver52M/sigProcLib.cpp b/Transceiver52M/sigProcLib.cpp index c09047b..c51d094 100644 --- a/Transceiver52M/sigProcLib.cpp +++ b/Transceiver52M/sigProcLib.cpp @@ -654,51 +654,6 @@ return pulse; } -signalVector* frequencyShift(signalVector *y, - signalVector *x, - float freq, - float startPhase, - float *finalPhase) -{ - - if (!x) return NULL; - - if (y==NULL) { - y = new signalVector(x->size()); - y->isReal(x->isReal()); - if (y==NULL) return NULL; - } - - if (y->size() < x->size()) return NULL; - - float phase = startPhase; - signalVector::iterator yP = y->begin(); - signalVector::iterator xPEnd = x->end(); - signalVector::iterator xP = x->begin(); - - if (x->isReal()) { - while (xP < xPEnd) { - (*yP++) = expjLookup(phase)*( (xP++)->real() ); - phase += freq; - } - } - else { - while (xP < xPEnd) { - (*yP++) = (*xP++)*expjLookup(phase); - phase += freq; - if (phase > 2 * M_PI) - phase -= 2 * M_PI; - else if (phase < -2 * M_PI) - phase += 2 * M_PI; - } - } - - - if (finalPhase) *finalPhase = phase; - - return y; -} - signalVector* reverseConjugate(signalVector *b) { signalVector *tmp = new signalVector(b->size()); -- To view, visit https://gerrit.osmocom.org/2186 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I46752ccf5dbcffbec806081dec03e69a0fbdcdb7 Gerrit-PatchSet: 3 Gerrit-Project: osmo-trx Gerrit-Branch: master Gerrit-Owner: Tom Tsou Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sat Apr 1 12:15:11 2017 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Sat, 1 Apr 2017 12:15:11 +0000 Subject: openbsc[master]: VTY: add the dyn_ts_allow_tch_f option In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2190 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Id18cab25844dc854a66b4e2713e90c3f43afa712 Gerrit-PatchSet: 2 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Vadim Yanitskiy Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: Vadim Yanitskiy Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Mon Apr 3 09:04:56 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Mon, 3 Apr 2017 09:04:56 +0000 Subject: libosmocore[master]: Add SW Description (de)marshalling In-Reply-To: References: Message-ID: Patch Set 3: > this test does not belong in msgb_test.c Where do you think it belongs to? -- To view, visit https://gerrit.osmocom.org/2165 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ib63b6b5e83b8914864fc7edd789f8958cdc993cd Gerrit-PatchSet: 3 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Mon Apr 3 09:43:17 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Mon, 3 Apr 2017 09:43:17 +0000 Subject: osmo-trx[master]: config: Remove OpenBTS style sqlite configuration In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+1 -- To view, visit https://gerrit.osmocom.org/2185 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I95d7b771fde976818bee76f89163e72c3a44ecdd Gerrit-PatchSet: 2 Gerrit-Project: osmo-trx Gerrit-Branch: master Gerrit-Owner: Tom Tsou Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Mon Apr 3 10:19:31 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Mon, 3 Apr 2017 10:19:31 +0000 Subject: [PATCH] openbsc[master]: gsm_bts: add version and variant details In-Reply-To: References: Message-ID: Hello Neels Hofmeyr, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2161 to look at the new patch set (#3). gsm_bts: add version and variant details * add version string to gsm_bts * add PCU version string to gsm_bts_trx * rename GSM_BTS_TYPE_OSMO_SYSMO -> GSM_BTS_OSMOBTS to avoid confusion between BTS model and variant * add variant enum to gsm_bts_model using eunm with variants for each hw vendor of OsmoBTS This will come in handy when logging details regarding particular BTS reported via OML, see: Related: OS#1614 Change-Id: I6710d53115f34634a7b70969cc05fd5c72ff8ab2 --- M openbsc/include/openbsc/gsm_data.h M openbsc/include/openbsc/gsm_data_shared.h M openbsc/src/libbsc/abis_nm.c M openbsc/src/libbsc/bsc_vty.c M openbsc/src/libbsc/bts_sysmobts.c M openbsc/src/libbsc/e1_config.c M openbsc/src/libbsc/system_information.c M openbsc/src/libcommon/gsm_data.c M openbsc/src/libmsc/gsm_04_08.c 9 files changed, 35 insertions(+), 18 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/61/2161/3 diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h index e9ba173..02d621d 100644 --- a/openbsc/include/openbsc/gsm_data.h +++ b/openbsc/include/openbsc/gsm_data.h @@ -470,7 +470,7 @@ { switch (bts->type) { case GSM_BTS_TYPE_NANOBTS: - case GSM_BTS_TYPE_OSMO_SYSMO: + case GSM_BTS_TYPE_OSMOBTS: return 1; default: break; @@ -481,7 +481,7 @@ static inline int is_sysmobts_v2(struct gsm_bts *bts) { switch (bts->type) { - case GSM_BTS_TYPE_OSMO_SYSMO: + case GSM_BTS_TYPE_OSMOBTS: return 1; default: break; diff --git a/openbsc/include/openbsc/gsm_data_shared.h b/openbsc/include/openbsc/gsm_data_shared.h index 06fa8dd..b733625 100644 --- a/openbsc/include/openbsc/gsm_data_shared.h +++ b/openbsc/include/openbsc/gsm_data_shared.h @@ -64,6 +64,8 @@ #define HARDCODED_BTS1_TS 6 #define HARDCODED_BTS2_TS 11 +#define MAX_VERSION_LENGTH 64 + enum gsm_hooks { GSM_HOOK_NM_SWLOAD, GSM_HOOK_RR_PAGING, @@ -433,6 +435,9 @@ /* Some BTS (specifically Ericsson RBS) have a per-TRX OML Link */ struct e1inp_sign_link *oml_link; + /* Connected PCU version (if any) */ + char pcu_version[MAX_VERSION_LENGTH]; + struct gsm_abis_mo mo; struct tlv_parsed nm_attr; struct { @@ -489,8 +494,17 @@ GSM_BTS_TYPE_NANOBTS, GSM_BTS_TYPE_RBS2000, GSM_BTS_TYPE_NOKIA_SITE, - GSM_BTS_TYPE_OSMO_SYSMO, + GSM_BTS_TYPE_OSMOBTS, _NUM_GSM_BTS_TYPE +}; + +enum gsm_bts_type_variant { + BTS_UNKNOWN, + BTS_LITECELL15, + BTS_OCTPHY, + BTS_SYSMO, + BTS_TRX, + _NUM_BTS_VARIANT }; struct vty; @@ -499,6 +513,7 @@ struct llist_head list; enum gsm_bts_type type; + enum gsm_bts_type_variant variant; const char *name; bool started; @@ -653,6 +668,8 @@ enum gsm_bts_type type; struct gsm_bts_model *model; enum gsm_band band; + char version[MAX_VERSION_LENGTH]; + /* maximum Tx power that the MS is permitted to use in this cell */ int ms_max_power; diff --git a/openbsc/src/libbsc/abis_nm.c b/openbsc/src/libbsc/abis_nm.c index 8b0eec2..394c427 100644 --- a/openbsc/src/libbsc/abis_nm.c +++ b/openbsc/src/libbsc/abis_nm.c @@ -661,7 +661,7 @@ switch (bts_type) { case GSM_BTS_TYPE_NANOBTS: - case GSM_BTS_TYPE_OSMO_SYSMO: + case GSM_BTS_TYPE_OSMOBTS: rc = abis_nm_rx_ipacc(mb); abis_nm_queue_send_next(sign_link->trx->bts); break; @@ -1646,7 +1646,7 @@ } *reason = "Unknown combination"; return -EINVAL; - case GSM_BTS_TYPE_OSMO_SYSMO: + case GSM_BTS_TYPE_OSMOBTS: /* no known restrictions */ return 0; default: diff --git a/openbsc/src/libbsc/bsc_vty.c b/openbsc/src/libbsc/bsc_vty.c index b1747aa..614f0a4 100644 --- a/openbsc/src/libbsc/bsc_vty.c +++ b/openbsc/src/libbsc/bsc_vty.c @@ -649,7 +649,7 @@ bts->early_classmark_allowed ? "allowed" : "forbidden", VTY_NEWLINE); switch (bts->type) { case GSM_BTS_TYPE_NANOBTS: - case GSM_BTS_TYPE_OSMO_SYSMO: + case GSM_BTS_TYPE_OSMOBTS: vty_out(vty, " ip.access unit_id %u %u%s", bts->ip_access.site_id, bts->ip_access.bts_id, VTY_NEWLINE); if (bts->ip_access.rsl_ip) { diff --git a/openbsc/src/libbsc/bts_sysmobts.c b/openbsc/src/libbsc/bts_sysmobts.c index e1bf661..e4b6cdc 100644 --- a/openbsc/src/libbsc/bts_sysmobts.c +++ b/openbsc/src/libbsc/bts_sysmobts.c @@ -46,7 +46,7 @@ { model_sysmobts = bts_model_nanobts; model_sysmobts.name = "sysmobts"; - model_sysmobts.type = GSM_BTS_TYPE_OSMO_SYSMO; + model_sysmobts.type = GSM_BTS_TYPE_OSMOBTS; model_sysmobts.features.data = &model_sysmobts._features_data[0]; model_sysmobts.features.data_len = diff --git a/openbsc/src/libbsc/e1_config.c b/openbsc/src/libbsc/e1_config.c index 8910d21..d57dec5 100644 --- a/openbsc/src/libbsc/e1_config.c +++ b/openbsc/src/libbsc/e1_config.c @@ -179,7 +179,7 @@ /* skip signal link initialization, this is done later for these BTS. */ if (bts->type == GSM_BTS_TYPE_NANOBTS || - bts->type == GSM_BTS_TYPE_OSMO_SYSMO) + bts->type == GSM_BTS_TYPE_OSMOBTS) return e1inp_line_update(line); /* OML link */ diff --git a/openbsc/src/libbsc/system_information.c b/openbsc/src/libbsc/system_information.c index a2dd827..2610331 100644 --- a/openbsc/src/libbsc/system_information.c +++ b/openbsc/src/libbsc/system_information.c @@ -830,7 +830,7 @@ /* ip.access nanoBTS needs l2_plen!! */ switch (bts->type) { case GSM_BTS_TYPE_NANOBTS: - case GSM_BTS_TYPE_OSMO_SYSMO: + case GSM_BTS_TYPE_OSMOBTS: *output++ = GSM48_LEN2PLEN(l2_plen); l2_plen++; break; @@ -865,7 +865,7 @@ /* ip.access nanoBTS needs l2_plen!! */ switch (bts->type) { case GSM_BTS_TYPE_NANOBTS: - case GSM_BTS_TYPE_OSMO_SYSMO: + case GSM_BTS_TYPE_OSMOBTS: *output++ = GSM48_LEN2PLEN(l2_plen); l2_plen++; break; @@ -909,7 +909,7 @@ /* ip.access nanoBTS needs l2_plen!! */ switch (bts->type) { case GSM_BTS_TYPE_NANOBTS: - case GSM_BTS_TYPE_OSMO_SYSMO: + case GSM_BTS_TYPE_OSMOBTS: *output++ = GSM48_LEN2PLEN(l2_plen); l2_plen++; break; @@ -946,7 +946,7 @@ /* ip.access nanoBTS needs l2_plen!! */ switch (bts->type) { case GSM_BTS_TYPE_NANOBTS: - case GSM_BTS_TYPE_OSMO_SYSMO: + case GSM_BTS_TYPE_OSMOBTS: *output++ = GSM48_LEN2PLEN(l2_plen); l2_plen++; break; diff --git a/openbsc/src/libcommon/gsm_data.c b/openbsc/src/libcommon/gsm_data.c index 3e12430..fd34793 100644 --- a/openbsc/src/libcommon/gsm_data.c +++ b/openbsc/src/libcommon/gsm_data.c @@ -96,7 +96,7 @@ { GSM_BTS_TYPE_NANOBTS, "nanobts" }, { GSM_BTS_TYPE_RBS2000, "rbs2000" }, { GSM_BTS_TYPE_NOKIA_SITE, "nokia_site" }, - { GSM_BTS_TYPE_OSMO_SYSMO, "sysmobts" }, + { GSM_BTS_TYPE_OSMOBTS, "sysmobts" }, { 0, NULL } }; @@ -106,7 +106,7 @@ { GSM_BTS_TYPE_NANOBTS, "ip.access nanoBTS or compatible" }, { GSM_BTS_TYPE_RBS2000, "Ericsson RBS2000 Series" }, { GSM_BTS_TYPE_NOKIA_SITE, "Nokia {Metro,Ultra,In}Site" }, - { GSM_BTS_TYPE_OSMO_SYSMO, "sysmocom sysmoBTS" }, + { GSM_BTS_TYPE_OSMOBTS, "sysmocom sysmoBTS" }, { 0, NULL } }; @@ -274,7 +274,7 @@ switch (bts->type) { case GSM_BTS_TYPE_NANOBTS: - case GSM_BTS_TYPE_OSMO_SYSMO: + case GSM_BTS_TYPE_OSMOBTS: /* Set the default OML Stream ID to 0xff */ bts->oml_tei = 0xff; bts->c0->nominal_power = 23; diff --git a/openbsc/src/libmsc/gsm_04_08.c b/openbsc/src/libmsc/gsm_04_08.c index c910d71..ee4e561 100644 --- a/openbsc/src/libmsc/gsm_04_08.c +++ b/openbsc/src/libmsc/gsm_04_08.c @@ -1944,7 +1944,7 @@ // todo: map between different bts types switch (bts->type) { case GSM_BTS_TYPE_NANOBTS: - case GSM_BTS_TYPE_OSMO_SYSMO: + case GSM_BTS_TYPE_OSMOBTS: if (!ipacc_rtp_direct) { if (!lchan->abis_ip.rtp_socket) { LOGP(DHO, LOGL_ERROR, "no RTP socket for " @@ -2035,7 +2035,7 @@ switch (bts->type) { case GSM_BTS_TYPE_NANOBTS: - case GSM_BTS_TYPE_OSMO_SYSMO: + case GSM_BTS_TYPE_OSMOBTS: if (ipacc_rtp_direct) { LOGP(DCC, LOGL_ERROR, "Error: RTP proxy is disabled\n"); return -EINVAL; @@ -3615,7 +3615,7 @@ bts = trans->conn->lchan->ts->trx->bts; switch (bts->type) { case GSM_BTS_TYPE_NANOBTS: - case GSM_BTS_TYPE_OSMO_SYSMO: + case GSM_BTS_TYPE_OSMOBTS: if (!trans->conn->lchan->abis_ip.rtp_socket) { DEBUGP(DMNCC, "TCH frame to lchan without RTP connection\n"); return 0; -- To view, visit https://gerrit.osmocom.org/2161 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I6710d53115f34634a7b70969cc05fd5c72ff8ab2 Gerrit-PatchSet: 3 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Mon Apr 3 10:21:01 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Mon, 3 Apr 2017 10:21:01 +0000 Subject: openbsc[master]: gsm_bts: add version and variant details In-Reply-To: References: Message-ID: Patch Set 2: I think it's better to keep variant name more generic - just in case we'll have to add different variants for non-Osmocom models (RBS2001 or smth like that for example). -- To view, visit https://gerrit.osmocom.org/2161 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I6710d53115f34634a7b70969cc05fd5c72ff8ab2 Gerrit-PatchSet: 2 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Mon Apr 3 10:37:19 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 3 Apr 2017 10:37:19 +0000 Subject: openbsc[master]: gsm_bts: add version and variant details In-Reply-To: References: Message-ID: Patch Set 3: (2 comments) https://gerrit.osmocom.org/#/c/2161/3/openbsc/include/openbsc/gsm_data_shared.h File openbsc/include/openbsc/gsm_data_shared.h: Line 502: BTS_UNKNOWN, better call those BTS__OSMO_... to indicate they're sub-variants of OSMOBTS. https://gerrit.osmocom.org/#/c/2161/3/openbsc/src/libbsc/bts_sysmobts.c File openbsc/src/libbsc/bts_sysmobts.c: Line 48: model_sysmobts.name = "sysmobts"; we need to do something about the string name. Old configurations with 'sysmobts' should map that to 'osmobts' and new config files should be written with 'osmobts'. Also, the code in this file should contain some explanation, i.e. that osmo-bts was primarily written for sysmobts and later extended to other models/vendors, hence this code refers to sysmobts but also works with other models. -- To view, visit https://gerrit.osmocom.org/2161 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I6710d53115f34634a7b70969cc05fd5c72ff8ab2 Gerrit-PatchSet: 3 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Mon Apr 3 10:39:14 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 3 Apr 2017 10:39:14 +0000 Subject: osmo-trx[master]: config: Remove OpenBTS style sqlite configuration In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+1 -- To view, visit https://gerrit.osmocom.org/2185 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I95d7b771fde976818bee76f89163e72c3a44ecdd Gerrit-PatchSet: 2 Gerrit-Project: osmo-trx Gerrit-Branch: master Gerrit-Owner: Tom Tsou Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Mon Apr 3 10:40:41 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 3 Apr 2017 10:40:41 +0000 Subject: osmo-trx[master]: radioInterface: Remove UmTRX 'diversity' option In-Reply-To: References: Message-ID: Patch Set 3: let's see what fairwaves states about whether this is required and/or used and/or working. -- To view, visit https://gerrit.osmocom.org/2186 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I46752ccf5dbcffbec806081dec03e69a0fbdcdb7 Gerrit-PatchSet: 3 Gerrit-Project: osmo-trx Gerrit-Branch: master Gerrit-Owner: Tom Tsou Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Mon Apr 3 10:58:41 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Mon, 3 Apr 2017 10:58:41 +0000 Subject: [PATCH] openbsc[master]: gsm_bts: add version and variant details In-Reply-To: References: Message-ID: Hello Neels Hofmeyr, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2161 to look at the new patch set (#4). gsm_bts: add version and variant details * add version string to gsm_bts * add PCU version string to gsm_bts_trx * rename GSM_BTS_TYPE_OSMO_SYSMO -> GSM_BTS_OSMOBTS to avoid confusion between BTS model and variant * add variant enum to gsm_bts_model using eunm with variants for each hw vendor of OsmoBTS This will come in handy when logging details regarding particular BTS reported via OML, see: Related: OS#1614 Change-Id: I6710d53115f34634a7b70969cc05fd5c72ff8ab2 --- M openbsc/include/openbsc/gsm_data.h M openbsc/include/openbsc/gsm_data_shared.h M openbsc/src/libbsc/abis_nm.c M openbsc/src/libbsc/bsc_vty.c M openbsc/src/libbsc/bts_sysmobts.c M openbsc/src/libbsc/e1_config.c M openbsc/src/libbsc/system_information.c M openbsc/src/libcommon/gsm_data.c M openbsc/src/libmsc/gsm_04_08.c 9 files changed, 35 insertions(+), 18 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/61/2161/4 diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h index e9ba173..02d621d 100644 --- a/openbsc/include/openbsc/gsm_data.h +++ b/openbsc/include/openbsc/gsm_data.h @@ -470,7 +470,7 @@ { switch (bts->type) { case GSM_BTS_TYPE_NANOBTS: - case GSM_BTS_TYPE_OSMO_SYSMO: + case GSM_BTS_TYPE_OSMOBTS: return 1; default: break; @@ -481,7 +481,7 @@ static inline int is_sysmobts_v2(struct gsm_bts *bts) { switch (bts->type) { - case GSM_BTS_TYPE_OSMO_SYSMO: + case GSM_BTS_TYPE_OSMOBTS: return 1; default: break; diff --git a/openbsc/include/openbsc/gsm_data_shared.h b/openbsc/include/openbsc/gsm_data_shared.h index 06fa8dd..6b3157e 100644 --- a/openbsc/include/openbsc/gsm_data_shared.h +++ b/openbsc/include/openbsc/gsm_data_shared.h @@ -64,6 +64,8 @@ #define HARDCODED_BTS1_TS 6 #define HARDCODED_BTS2_TS 11 +#define MAX_VERSION_LENGTH 64 + enum gsm_hooks { GSM_HOOK_NM_SWLOAD, GSM_HOOK_RR_PAGING, @@ -433,6 +435,9 @@ /* Some BTS (specifically Ericsson RBS) have a per-TRX OML Link */ struct e1inp_sign_link *oml_link; + /* Connected PCU version (if any) */ + char pcu_version[MAX_VERSION_LENGTH]; + struct gsm_abis_mo mo; struct tlv_parsed nm_attr; struct { @@ -489,8 +494,17 @@ GSM_BTS_TYPE_NANOBTS, GSM_BTS_TYPE_RBS2000, GSM_BTS_TYPE_NOKIA_SITE, - GSM_BTS_TYPE_OSMO_SYSMO, + GSM_BTS_TYPE_OSMOBTS, _NUM_GSM_BTS_TYPE +}; + +enum gsm_bts_type_variant { + BTS_UNKNOWN, + BTS_OSMO_LITECELL15, + BTS_OSMO_OCTPHY, + BTS_OSMO_SYSMO, + BTS_OSMO_TRX, + _NUM_BTS_VARIANT }; struct vty; @@ -499,6 +513,7 @@ struct llist_head list; enum gsm_bts_type type; + enum gsm_bts_type_variant variant; const char *name; bool started; @@ -653,6 +668,8 @@ enum gsm_bts_type type; struct gsm_bts_model *model; enum gsm_band band; + char version[MAX_VERSION_LENGTH]; + /* maximum Tx power that the MS is permitted to use in this cell */ int ms_max_power; diff --git a/openbsc/src/libbsc/abis_nm.c b/openbsc/src/libbsc/abis_nm.c index 8b0eec2..394c427 100644 --- a/openbsc/src/libbsc/abis_nm.c +++ b/openbsc/src/libbsc/abis_nm.c @@ -661,7 +661,7 @@ switch (bts_type) { case GSM_BTS_TYPE_NANOBTS: - case GSM_BTS_TYPE_OSMO_SYSMO: + case GSM_BTS_TYPE_OSMOBTS: rc = abis_nm_rx_ipacc(mb); abis_nm_queue_send_next(sign_link->trx->bts); break; @@ -1646,7 +1646,7 @@ } *reason = "Unknown combination"; return -EINVAL; - case GSM_BTS_TYPE_OSMO_SYSMO: + case GSM_BTS_TYPE_OSMOBTS: /* no known restrictions */ return 0; default: diff --git a/openbsc/src/libbsc/bsc_vty.c b/openbsc/src/libbsc/bsc_vty.c index b1747aa..614f0a4 100644 --- a/openbsc/src/libbsc/bsc_vty.c +++ b/openbsc/src/libbsc/bsc_vty.c @@ -649,7 +649,7 @@ bts->early_classmark_allowed ? "allowed" : "forbidden", VTY_NEWLINE); switch (bts->type) { case GSM_BTS_TYPE_NANOBTS: - case GSM_BTS_TYPE_OSMO_SYSMO: + case GSM_BTS_TYPE_OSMOBTS: vty_out(vty, " ip.access unit_id %u %u%s", bts->ip_access.site_id, bts->ip_access.bts_id, VTY_NEWLINE); if (bts->ip_access.rsl_ip) { diff --git a/openbsc/src/libbsc/bts_sysmobts.c b/openbsc/src/libbsc/bts_sysmobts.c index e1bf661..e4b6cdc 100644 --- a/openbsc/src/libbsc/bts_sysmobts.c +++ b/openbsc/src/libbsc/bts_sysmobts.c @@ -46,7 +46,7 @@ { model_sysmobts = bts_model_nanobts; model_sysmobts.name = "sysmobts"; - model_sysmobts.type = GSM_BTS_TYPE_OSMO_SYSMO; + model_sysmobts.type = GSM_BTS_TYPE_OSMOBTS; model_sysmobts.features.data = &model_sysmobts._features_data[0]; model_sysmobts.features.data_len = diff --git a/openbsc/src/libbsc/e1_config.c b/openbsc/src/libbsc/e1_config.c index 8910d21..d57dec5 100644 --- a/openbsc/src/libbsc/e1_config.c +++ b/openbsc/src/libbsc/e1_config.c @@ -179,7 +179,7 @@ /* skip signal link initialization, this is done later for these BTS. */ if (bts->type == GSM_BTS_TYPE_NANOBTS || - bts->type == GSM_BTS_TYPE_OSMO_SYSMO) + bts->type == GSM_BTS_TYPE_OSMOBTS) return e1inp_line_update(line); /* OML link */ diff --git a/openbsc/src/libbsc/system_information.c b/openbsc/src/libbsc/system_information.c index a2dd827..2610331 100644 --- a/openbsc/src/libbsc/system_information.c +++ b/openbsc/src/libbsc/system_information.c @@ -830,7 +830,7 @@ /* ip.access nanoBTS needs l2_plen!! */ switch (bts->type) { case GSM_BTS_TYPE_NANOBTS: - case GSM_BTS_TYPE_OSMO_SYSMO: + case GSM_BTS_TYPE_OSMOBTS: *output++ = GSM48_LEN2PLEN(l2_plen); l2_plen++; break; @@ -865,7 +865,7 @@ /* ip.access nanoBTS needs l2_plen!! */ switch (bts->type) { case GSM_BTS_TYPE_NANOBTS: - case GSM_BTS_TYPE_OSMO_SYSMO: + case GSM_BTS_TYPE_OSMOBTS: *output++ = GSM48_LEN2PLEN(l2_plen); l2_plen++; break; @@ -909,7 +909,7 @@ /* ip.access nanoBTS needs l2_plen!! */ switch (bts->type) { case GSM_BTS_TYPE_NANOBTS: - case GSM_BTS_TYPE_OSMO_SYSMO: + case GSM_BTS_TYPE_OSMOBTS: *output++ = GSM48_LEN2PLEN(l2_plen); l2_plen++; break; @@ -946,7 +946,7 @@ /* ip.access nanoBTS needs l2_plen!! */ switch (bts->type) { case GSM_BTS_TYPE_NANOBTS: - case GSM_BTS_TYPE_OSMO_SYSMO: + case GSM_BTS_TYPE_OSMOBTS: *output++ = GSM48_LEN2PLEN(l2_plen); l2_plen++; break; diff --git a/openbsc/src/libcommon/gsm_data.c b/openbsc/src/libcommon/gsm_data.c index 3e12430..fd34793 100644 --- a/openbsc/src/libcommon/gsm_data.c +++ b/openbsc/src/libcommon/gsm_data.c @@ -96,7 +96,7 @@ { GSM_BTS_TYPE_NANOBTS, "nanobts" }, { GSM_BTS_TYPE_RBS2000, "rbs2000" }, { GSM_BTS_TYPE_NOKIA_SITE, "nokia_site" }, - { GSM_BTS_TYPE_OSMO_SYSMO, "sysmobts" }, + { GSM_BTS_TYPE_OSMOBTS, "sysmobts" }, { 0, NULL } }; @@ -106,7 +106,7 @@ { GSM_BTS_TYPE_NANOBTS, "ip.access nanoBTS or compatible" }, { GSM_BTS_TYPE_RBS2000, "Ericsson RBS2000 Series" }, { GSM_BTS_TYPE_NOKIA_SITE, "Nokia {Metro,Ultra,In}Site" }, - { GSM_BTS_TYPE_OSMO_SYSMO, "sysmocom sysmoBTS" }, + { GSM_BTS_TYPE_OSMOBTS, "sysmocom sysmoBTS" }, { 0, NULL } }; @@ -274,7 +274,7 @@ switch (bts->type) { case GSM_BTS_TYPE_NANOBTS: - case GSM_BTS_TYPE_OSMO_SYSMO: + case GSM_BTS_TYPE_OSMOBTS: /* Set the default OML Stream ID to 0xff */ bts->oml_tei = 0xff; bts->c0->nominal_power = 23; diff --git a/openbsc/src/libmsc/gsm_04_08.c b/openbsc/src/libmsc/gsm_04_08.c index c910d71..ee4e561 100644 --- a/openbsc/src/libmsc/gsm_04_08.c +++ b/openbsc/src/libmsc/gsm_04_08.c @@ -1944,7 +1944,7 @@ // todo: map between different bts types switch (bts->type) { case GSM_BTS_TYPE_NANOBTS: - case GSM_BTS_TYPE_OSMO_SYSMO: + case GSM_BTS_TYPE_OSMOBTS: if (!ipacc_rtp_direct) { if (!lchan->abis_ip.rtp_socket) { LOGP(DHO, LOGL_ERROR, "no RTP socket for " @@ -2035,7 +2035,7 @@ switch (bts->type) { case GSM_BTS_TYPE_NANOBTS: - case GSM_BTS_TYPE_OSMO_SYSMO: + case GSM_BTS_TYPE_OSMOBTS: if (ipacc_rtp_direct) { LOGP(DCC, LOGL_ERROR, "Error: RTP proxy is disabled\n"); return -EINVAL; @@ -3615,7 +3615,7 @@ bts = trans->conn->lchan->ts->trx->bts; switch (bts->type) { case GSM_BTS_TYPE_NANOBTS: - case GSM_BTS_TYPE_OSMO_SYSMO: + case GSM_BTS_TYPE_OSMOBTS: if (!trans->conn->lchan->abis_ip.rtp_socket) { DEBUGP(DMNCC, "TCH frame to lchan without RTP connection\n"); return 0; -- To view, visit https://gerrit.osmocom.org/2161 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I6710d53115f34634a7b70969cc05fd5c72ff8ab2 Gerrit-PatchSet: 4 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Mon Apr 3 11:00:14 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Mon, 3 Apr 2017 11:00:14 +0000 Subject: openbsc[master]: gsm_bts: add version and variant details In-Reply-To: References: Message-ID: Patch Set 3: > we need to do something about the string name I think this should be part of separate commit which adds the distinction between osmobts variants via variant-specific features. -- To view, visit https://gerrit.osmocom.org/2161 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I6710d53115f34634a7b70969cc05fd5c72ff8ab2 Gerrit-PatchSet: 3 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Mon Apr 3 11:11:49 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Mon, 3 Apr 2017 11:11:49 +0000 Subject: [PATCH] libosmocore[master]: Add SW Description (de)marshalling In-Reply-To: References: Message-ID: Hello Neels Hofmeyr, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2165 to look at the new patch set (#4). Add SW Description (de)marshalling * data structure representing 3GPP TS 52.021 ?9.4.62 SW Description * function to serialize it into msgb * function to deserialize it from buffer * function to estimate buffer size * test harness There are several similar functions to deal with SW Description in OpenBSC, there's also need to use similar functionality in OsmoBTS. Hence it's better to put the code into common library with proper tests and documentation. Change-Id: Ib63b6b5e83b8914864fc7edd789f8958cdc993cd Related: OS#1614 --- M include/osmocom/gsm/protocol/gsm_12_21.h M src/gsm/abis_nm.c M src/gsm/libosmogsm.map M tests/Makefile.am M tests/msgb/msgb_test.c M tests/msgb/msgb_test.ok 6 files changed, 157 insertions(+), 2 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/65/2165/4 diff --git a/include/osmocom/gsm/protocol/gsm_12_21.h b/include/osmocom/gsm/protocol/gsm_12_21.h index c88f0b1..3e6bb2b 100644 --- a/include/osmocom/gsm/protocol/gsm_12_21.h +++ b/include/osmocom/gsm/protocol/gsm_12_21.h @@ -29,6 +29,7 @@ /*! \file gsm_12_21.h */ #include +#include #include /*! \brief generic header in front of every OML message according to TS 08.59 */ @@ -791,6 +792,22 @@ IPAC_BINF_CELL_ALLOC = (1 << 2), }; +/*! \brief 3GPP TS 52.021 ?9.4.62 SW Description */ +struct abis_nm_sw_descr { + uint8_t file_id[UINT8_MAX]; + uint8_t file_id_len; + + uint8_t file_version[UINT8_MAX]; + uint8_t file_version_len; +}; + +uint16_t abis_nm_sw_descr_len(const struct abis_nm_sw_descr *sw, + bool put_sw_descr); +uint16_t abis_nm_put_sw_descr(struct msgb *msg, const struct abis_nm_sw_descr *sw, + bool put_sw_descr); +bool abis_nm_get_sw_descr(struct abis_nm_sw_descr *sw, const uint8_t * buf, + size_t len); + struct msgb *abis_nm_fail_evt_rep(enum abis_nm_event_type t, enum abis_nm_severity s, enum abis_nm_pcause_type ct, diff --git a/src/gsm/abis_nm.c b/src/gsm/abis_nm.c index 934d7ce..6dbc45a 100644 --- a/src/gsm/abis_nm.c +++ b/src/gsm/abis_nm.c @@ -751,6 +751,81 @@ return nmsg; } +/*! \brief Compute length of given 3GPP TS 52.021 ?9.4.62 SW Description. + * \param[in] sw SW Description struct + * \param[in] put_sw_descr boolean, whether to put NM_ATT_SW_DESCR IE or not + * \returns length of buffer space necessary to store sw + */ +uint16_t abis_nm_sw_descr_len(const struct abis_nm_sw_descr *sw, + bool put_sw_descr) +{ + /* +3: type is 1-byte, length is 2-byte */ + return (put_sw_descr ? 1 : 0) + (sw->file_id_len + 3) + + (sw->file_version_len + 3); +} + +/*! \brief Put given 3GPP TS 52.021 ?9.4.62 SW Description into msgb. + * \param[out] msg message buffer + * \param[in] sw SW Description struct + * \param[in] put_sw_descr boolean, whether to put NM_ATT_SW_DESCR IE or not + * \param[in] simulate boolean, whether to actually modify msg or not + * \returns length of buffer space necessary to store sw + */ +uint16_t abis_nm_put_sw_descr(struct msgb *msg, const struct abis_nm_sw_descr *sw, + bool put_sw_descr) +{ + if (put_sw_descr) + msgb_v_put(msg, NM_ATT_SW_DESCR); + msgb_tl16v_put(msg, NM_ATT_FILE_ID, sw->file_id_len, sw->file_id); + msgb_tl16v_put(msg, NM_ATT_FILE_VERSION, sw->file_version_len, + sw->file_version); + + return abis_nm_sw_descr_len(sw, put_sw_descr); +} + +/*! \brief Parse 3GPP TS 52.021 ?9.4.62 SW Description from buffer. + * \param[out] sw SW Description struct + * \param[in] buf buffer + * \param[in] len buffer length + * \returns true if parsing succeeded, else otherwise + */ +bool abis_nm_get_sw_descr(struct abis_nm_sw_descr *sw, const uint8_t * buf, + size_t len) +{ + static struct tlv_parsed tp; + const struct tlv_definition sw_tlvdef = { + .def = { + [NM_ATT_SW_DESCR] = { TLV_TYPE_TV }, + [NM_ATT_FILE_ID] = { TLV_TYPE_TL16V }, + [NM_ATT_FILE_VERSION] = { TLV_TYPE_TL16V }, + }, + }; + + /* Note: the return value is ignored here because SW Description tag + itself is considered optional. */ + tlv_parse(&tp, &sw_tlvdef, buf, len, 0, 0); + + /* Parsing SW Description is tricky for current implementation of TLV + parser which fails to properly handle TV when V has following + structure: | TL16V | TL16V |. Hence, the need for 2nd call: */ + if (tlv_parse(&tp, &sw_tlvdef, buf + TLVP_LEN(&tp, NM_ATT_SW_DESCR), + len - TLVP_LEN(&tp, NM_ATT_SW_DESCR), 0, 0) < 0) + return false; + + if (!TLVP_PRESENT(&tp, NM_ATT_FILE_ID) || + !TLVP_PRESENT(&tp, NM_ATT_FILE_VERSION)) + return false; + + sw->file_id_len = TLVP_LEN(&tp, NM_ATT_FILE_ID); + sw->file_version_len = TLVP_LEN(&tp, NM_ATT_FILE_VERSION); + + memcpy(sw->file_id, TLVP_VAL(&tp, NM_ATT_FILE_ID), sw->file_id_len); + memcpy(sw->file_version, TLVP_VAL(&tp, NM_ATT_FILE_VERSION), + sw->file_version_len); + + return true; +} + /*! \brief Obtain OML Channel Combination for phnsical channel config */ int abis_nm_chcomb4pchan(enum gsm_phys_chan_config pchan) { diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map index 5649e71..a8ad892 100644 --- a/src/gsm/libosmogsm.map +++ b/src/gsm/libosmogsm.map @@ -31,6 +31,9 @@ abis_nm_pcause_type_names; abis_nm_msgtype_names; abis_nm_att_names; +abis_nm_sw_descr_len; +abis_nm_put_sw_descr; +abis_nm_get_sw_descr; osmo_sitype_strs; osmo_c4; diff --git a/tests/Makefile.am b/tests/Makefile.am index 352b5a7..16b45ea 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -74,7 +74,7 @@ lapd_lapd_test_LDADD = $(top_builddir)/src/libosmocore.la $(top_builddir)/src/gsm/libosmogsm.la msgb_msgb_test_SOURCES = msgb/msgb_test.c -msgb_msgb_test_LDADD = $(top_builddir)/src/libosmocore.la +msgb_msgb_test_LDADD = $(top_builddir)/src/libosmocore.la $(top_builddir)/src/gsm/libosmogsm.la msgfile_msgfile_test_SOURCES = msgfile/msgfile_test.c msgfile_msgfile_test_LDADD = $(top_builddir)/src/libosmocore.la diff --git a/tests/msgb/msgb_test.c b/tests/msgb/msgb_test.c index ac10382..abdcfee 100644 --- a/tests/msgb/msgb_test.c +++ b/tests/msgb/msgb_test.c @@ -23,10 +23,12 @@ #include #include #include +#include + #include #include - +#include #include #define CHECK_RC(rc) \ @@ -177,6 +179,57 @@ msgb_free(msg2); } +static inline void print_chk(const char *what, uint8_t len1, uint8_t len2, + const uint8_t *x1, const uint8_t *x2) +{ + int cmp = memcmp(x1, x2, len2); + printf("\tFILE %s [%u == %u -> %d, %s] %d => %s\n", what, len1, len2, + len1 == len2, len1 != len2 ? "fail" : "ok", + cmp, cmp != 0 ? "FAIL" : "OK"); +} + +static inline void chk_descr(struct msgb *msg, struct abis_nm_sw_descr *get, + struct abis_nm_sw_descr *put, bool h) +{ + bool res; + uint16_t len = abis_nm_put_sw_descr(msg, put, h); + + printf("msgb [%u/%u/%u - %s]: SW DESCR (with%s header) %s\n", msg->len, + msg->data_len, len, len != msg->len ? "fail" : "ok", + h ? "" : "out", + len > put->file_version_len + put->file_id_len ? "OK" : "FAIL"); + + res = abis_nm_get_sw_descr(get, msgb_data(msg), msg->len); + if (res) { + print_chk("ID", get->file_id_len, put->file_id_len, get->file_id, + put->file_id); + print_chk("VERSION", get->file_version_len, + put->file_version_len, get->file_version, + put->file_version); + } else + printf("SW DESCR (with%s header) parsing error!\n", + h ? "" : "out"); + + msgb_reset(msg); +} + +static void test_msg_sw() +{ + const char *f_id = "TEST.L0L", *f_ver = "0.1.666~deadbeeffacefeed-dirty"; + uint8_t lf_id = strlen(f_id), lf_ver = strlen(f_ver); + struct msgb *msg = msgb_alloc_headroom(4096, 128, "sw"); + struct abis_nm_sw_descr sw_get1 = { 0 }, sw_get2 = { 0 }, sw_put = { + .file_id_len = lf_id, + .file_version_len = lf_ver, + }; + + memcpy(sw_put.file_id, f_id, lf_id); + memcpy(sw_put.file_version, f_ver, lf_ver); + + chk_descr(msg, &sw_get1, &sw_put, true); + chk_descr(msg, &sw_get2, &sw_put, false); +} + static void test_msgb_resize_area() { struct msgb *msg = msgb_alloc_headroom(4096, 128, "data"); @@ -287,6 +340,7 @@ test_msgb_api_errors(); test_msgb_copy(); test_msgb_resize_area(); + test_msg_sw(); printf("Success.\n"); diff --git a/tests/msgb/msgb_test.ok b/tests/msgb/msgb_test.ok index 6603fe7..2a35407 100644 --- a/tests/msgb/msgb_test.ok +++ b/tests/msgb/msgb_test.ok @@ -32,4 +32,10 @@ Original: [L1]> 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 [L2]> 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 [L3]> 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 3a 3b [L4]> 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f Extended: [L1]> 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 [L2]> 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [L3]> 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 3a 3b [L4]> 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f Shrinked: [L1]> 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 [L2]> 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [L3]> 28 29 2a 2b 2c 2d 2e 2f 30 31 [L4]> 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f +msgb [45/4096/45 - ok]: SW DESCR (with header) OK + FILE ID [8 == 8 -> 1, ok] 0 => OK + FILE VERSION [30 == 30 -> 1, ok] 0 => OK +msgb [44/4096/44 - ok]: SW DESCR (without header) OK + FILE ID [8 == 8 -> 1, ok] 0 => OK + FILE VERSION [30 == 30 -> 1, ok] 0 => OK Success. -- To view, visit https://gerrit.osmocom.org/2165 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ib63b6b5e83b8914864fc7edd789f8958cdc993cd Gerrit-PatchSet: 4 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Mon Apr 3 11:21:30 2017 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Mon, 3 Apr 2017 11:21:30 +0000 Subject: libosmocore[master]: Add SW Description (de)marshalling In-Reply-To: References: Message-ID: Patch Set 3: (1 comment) > > this test does not belong in msgb_test.c > > Where do you think it belongs to? It tests abis-specific message encoding/decoding, right? I see lapd_test.c has some 'abis' in it, but almost looks like this needs a new separate test suite, but that again seems a bit overkill... no idea https://gerrit.osmocom.org/#/c/2165/3//COMMIT_MSG Commit Message: Line 17: proper tests and documentation. add cross reference to openbsc Ib94db414e94a2a1f234ac6f1cb346dca1c7a8be3 -- To view, visit https://gerrit.osmocom.org/2165 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ib63b6b5e83b8914864fc7edd789f8958cdc993cd Gerrit-PatchSet: 3 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Mon Apr 3 11:35:19 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Mon, 3 Apr 2017 11:35:19 +0000 Subject: [PATCH] libosmocore[master]: Add SW Description (de)marshalling In-Reply-To: References: Message-ID: Hello Neels Hofmeyr, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2165 to look at the new patch set (#5). Add SW Description (de)marshalling * data structure representing 3GPP TS 52.021 ?9.4.62 SW Description * function to serialize it into msgb * function to deserialize it from buffer * function to estimate buffer size * test harness There are several similar functions to deal with SW Description in OpenBSC, there's also need to use similar functionality in OsmoBTS. Hence it's better to put the code into common library with proper tests and documentation. Change-Id: Ib63b6b5e83b8914864fc7edd789f8958cdc993cd Related: OS#1614 --- M include/osmocom/gsm/protocol/gsm_12_21.h M src/gsm/abis_nm.c M src/gsm/libosmogsm.map M tests/Makefile.am M tests/lapd/lapd_test.c M tests/lapd/lapd_test.ok 6 files changed, 160 insertions(+), 2 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/65/2165/5 diff --git a/include/osmocom/gsm/protocol/gsm_12_21.h b/include/osmocom/gsm/protocol/gsm_12_21.h index c88f0b1..3e6bb2b 100644 --- a/include/osmocom/gsm/protocol/gsm_12_21.h +++ b/include/osmocom/gsm/protocol/gsm_12_21.h @@ -29,6 +29,7 @@ /*! \file gsm_12_21.h */ #include +#include #include /*! \brief generic header in front of every OML message according to TS 08.59 */ @@ -791,6 +792,22 @@ IPAC_BINF_CELL_ALLOC = (1 << 2), }; +/*! \brief 3GPP TS 52.021 ?9.4.62 SW Description */ +struct abis_nm_sw_descr { + uint8_t file_id[UINT8_MAX]; + uint8_t file_id_len; + + uint8_t file_version[UINT8_MAX]; + uint8_t file_version_len; +}; + +uint16_t abis_nm_sw_descr_len(const struct abis_nm_sw_descr *sw, + bool put_sw_descr); +uint16_t abis_nm_put_sw_descr(struct msgb *msg, const struct abis_nm_sw_descr *sw, + bool put_sw_descr); +bool abis_nm_get_sw_descr(struct abis_nm_sw_descr *sw, const uint8_t * buf, + size_t len); + struct msgb *abis_nm_fail_evt_rep(enum abis_nm_event_type t, enum abis_nm_severity s, enum abis_nm_pcause_type ct, diff --git a/src/gsm/abis_nm.c b/src/gsm/abis_nm.c index 934d7ce..6dbc45a 100644 --- a/src/gsm/abis_nm.c +++ b/src/gsm/abis_nm.c @@ -751,6 +751,81 @@ return nmsg; } +/*! \brief Compute length of given 3GPP TS 52.021 ?9.4.62 SW Description. + * \param[in] sw SW Description struct + * \param[in] put_sw_descr boolean, whether to put NM_ATT_SW_DESCR IE or not + * \returns length of buffer space necessary to store sw + */ +uint16_t abis_nm_sw_descr_len(const struct abis_nm_sw_descr *sw, + bool put_sw_descr) +{ + /* +3: type is 1-byte, length is 2-byte */ + return (put_sw_descr ? 1 : 0) + (sw->file_id_len + 3) + + (sw->file_version_len + 3); +} + +/*! \brief Put given 3GPP TS 52.021 ?9.4.62 SW Description into msgb. + * \param[out] msg message buffer + * \param[in] sw SW Description struct + * \param[in] put_sw_descr boolean, whether to put NM_ATT_SW_DESCR IE or not + * \param[in] simulate boolean, whether to actually modify msg or not + * \returns length of buffer space necessary to store sw + */ +uint16_t abis_nm_put_sw_descr(struct msgb *msg, const struct abis_nm_sw_descr *sw, + bool put_sw_descr) +{ + if (put_sw_descr) + msgb_v_put(msg, NM_ATT_SW_DESCR); + msgb_tl16v_put(msg, NM_ATT_FILE_ID, sw->file_id_len, sw->file_id); + msgb_tl16v_put(msg, NM_ATT_FILE_VERSION, sw->file_version_len, + sw->file_version); + + return abis_nm_sw_descr_len(sw, put_sw_descr); +} + +/*! \brief Parse 3GPP TS 52.021 ?9.4.62 SW Description from buffer. + * \param[out] sw SW Description struct + * \param[in] buf buffer + * \param[in] len buffer length + * \returns true if parsing succeeded, else otherwise + */ +bool abis_nm_get_sw_descr(struct abis_nm_sw_descr *sw, const uint8_t * buf, + size_t len) +{ + static struct tlv_parsed tp; + const struct tlv_definition sw_tlvdef = { + .def = { + [NM_ATT_SW_DESCR] = { TLV_TYPE_TV }, + [NM_ATT_FILE_ID] = { TLV_TYPE_TL16V }, + [NM_ATT_FILE_VERSION] = { TLV_TYPE_TL16V }, + }, + }; + + /* Note: the return value is ignored here because SW Description tag + itself is considered optional. */ + tlv_parse(&tp, &sw_tlvdef, buf, len, 0, 0); + + /* Parsing SW Description is tricky for current implementation of TLV + parser which fails to properly handle TV when V has following + structure: | TL16V | TL16V |. Hence, the need for 2nd call: */ + if (tlv_parse(&tp, &sw_tlvdef, buf + TLVP_LEN(&tp, NM_ATT_SW_DESCR), + len - TLVP_LEN(&tp, NM_ATT_SW_DESCR), 0, 0) < 0) + return false; + + if (!TLVP_PRESENT(&tp, NM_ATT_FILE_ID) || + !TLVP_PRESENT(&tp, NM_ATT_FILE_VERSION)) + return false; + + sw->file_id_len = TLVP_LEN(&tp, NM_ATT_FILE_ID); + sw->file_version_len = TLVP_LEN(&tp, NM_ATT_FILE_VERSION); + + memcpy(sw->file_id, TLVP_VAL(&tp, NM_ATT_FILE_ID), sw->file_id_len); + memcpy(sw->file_version, TLVP_VAL(&tp, NM_ATT_FILE_VERSION), + sw->file_version_len); + + return true; +} + /*! \brief Obtain OML Channel Combination for phnsical channel config */ int abis_nm_chcomb4pchan(enum gsm_phys_chan_config pchan) { diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map index 5649e71..a8ad892 100644 --- a/src/gsm/libosmogsm.map +++ b/src/gsm/libosmogsm.map @@ -31,6 +31,9 @@ abis_nm_pcause_type_names; abis_nm_msgtype_names; abis_nm_att_names; +abis_nm_sw_descr_len; +abis_nm_put_sw_descr; +abis_nm_get_sw_descr; osmo_sitype_strs; osmo_c4; diff --git a/tests/Makefile.am b/tests/Makefile.am index 352b5a7..16b45ea 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -74,7 +74,7 @@ lapd_lapd_test_LDADD = $(top_builddir)/src/libosmocore.la $(top_builddir)/src/gsm/libosmogsm.la msgb_msgb_test_SOURCES = msgb/msgb_test.c -msgb_msgb_test_LDADD = $(top_builddir)/src/libosmocore.la +msgb_msgb_test_LDADD = $(top_builddir)/src/libosmocore.la $(top_builddir)/src/gsm/libosmogsm.la msgfile_msgfile_test_SOURCES = msgfile/msgfile_test.c msgfile_msgfile_test_LDADD = $(top_builddir)/src/libosmocore.la diff --git a/tests/lapd/lapd_test.c b/tests/lapd/lapd_test.c index e322314..caed84e 100644 --- a/tests/lapd/lapd_test.c +++ b/tests/lapd/lapd_test.c @@ -25,9 +25,10 @@ #include #include #include +#include #include - +#include #include #define CHECK_RC(rc) \ @@ -752,6 +753,59 @@ lapdm_channel_exit(&bts_to_ms_channel); } +static inline void print_chk(const char *what, uint8_t len1, uint8_t len2, + const uint8_t *x1, const uint8_t *x2) +{ + int cmp = memcmp(x1, x2, len2); + printf("\tFILE %s [%u == %u -> %d, %s] %d => %s\n", what, len1, len2, + len1 == len2, len1 != len2 ? "fail" : "ok", + cmp, cmp != 0 ? "FAIL" : "OK"); +} + +static inline void chk_descr(struct msgb *msg, struct abis_nm_sw_descr *get, + struct abis_nm_sw_descr *put, bool h) +{ + bool res; + uint16_t len = abis_nm_put_sw_descr(msg, put, h); + + printf("msgb [%u/%u/%u - %s]: SW DESCR (with%s header) %s\n", msg->len, + msg->data_len, len, len != msg->len ? "fail" : "ok", + h ? "" : "out", + len > put->file_version_len + put->file_id_len ? "OK" : "FAIL"); + + res = abis_nm_get_sw_descr(get, msgb_data(msg), msg->len); + if (res) { + print_chk("ID", get->file_id_len, put->file_id_len, get->file_id, + put->file_id); + print_chk("VERSION", get->file_version_len, + put->file_version_len, get->file_version, + put->file_version); + } else + printf("SW DESCR (with%s header) parsing error!\n", + h ? "" : "out"); + + msgb_reset(msg); +} + +static void test_sw_descr() +{ + const char *f_id = "TEST.L0L", *f_ver = "0.1.666~deadbeeffacefeed-dirty"; + uint8_t lf_id = strlen(f_id), lf_ver = strlen(f_ver); + struct msgb *msg = msgb_alloc_headroom(4096, 128, "sw"); + struct abis_nm_sw_descr sw_get1 = { 0 }, sw_get2 = { 0 }, sw_put = { + .file_id_len = lf_id, + .file_version_len = lf_ver, + }; + + printf("\nI test SW Description (de)serialization.\n"); + + memcpy(sw_put.file_id, f_id, lf_id); + memcpy(sw_put.file_version, f_ver, lf_ver); + + chk_descr(msg, &sw_get1, &sw_put, true); + chk_descr(msg, &sw_get2, &sw_put, false); +} + int main(int argc, char **argv) { osmo_init_logging(&info); @@ -765,6 +819,7 @@ test_lapdm_contention_resolution(); test_lapdm_establishment(); test_lapdm_desync(); + test_sw_descr(); printf("Success.\n"); diff --git a/tests/lapd/lapd_test.ok b/tests/lapd/lapd_test.ok index e188e27..8e91b90 100644 --- a/tests/lapd/lapd_test.ok +++ b/tests/lapd/lapd_test.ok @@ -96,4 +96,12 @@ Took message from DCCH queue: L2 header size 23, L3 size 0, SAP 0x1000000, 0/0, Link 0x03 Message: [L2]> 0d 21 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b + +I test SW Description (de)serialization. +msgb [45/4096/45 - ok]: SW DESCR (with header) OK + FILE ID [8 == 8 -> 1, ok] 0 => OK + FILE VERSION [30 == 30 -> 1, ok] 0 => OK +msgb [44/4096/44 - ok]: SW DESCR (without header) OK + FILE ID [8 == 8 -> 1, ok] 0 => OK + FILE VERSION [30 == 30 -> 1, ok] 0 => OK Success. -- To view, visit https://gerrit.osmocom.org/2165 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ib63b6b5e83b8914864fc7edd789f8958cdc993cd Gerrit-PatchSet: 5 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Mon Apr 3 12:15:28 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Mon, 3 Apr 2017 12:15:28 +0000 Subject: [PATCH] libosmocore[master]: Add SW Description (de)marshalling In-Reply-To: References: Message-ID: Hello Neels Hofmeyr, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2165 to look at the new patch set (#6). Add SW Description (de)marshalling * data structure representing 3GPP TS 52.021 ?9.4.62 SW Description * function to serialize it into msgb * function to deserialize it from buffer * function to estimate buffer size * test harness There are several similar functions to deal with SW Description in OpenBSC, there's also need to use similar functionality in OsmoBTS. Hence it's better to put the code into common library with proper tests and documentation. Change-Id: Ib63b6b5e83b8914864fc7edd789f8958cdc993cd Related: OS#1614 --- M include/osmocom/gsm/protocol/gsm_12_21.h M src/gsm/abis_nm.c M src/gsm/libosmogsm.map M tests/Makefile.am M tests/lapd/lapd_test.c M tests/lapd/lapd_test.ok 6 files changed, 167 insertions(+), 2 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/65/2165/6 diff --git a/include/osmocom/gsm/protocol/gsm_12_21.h b/include/osmocom/gsm/protocol/gsm_12_21.h index c88f0b1..3e6bb2b 100644 --- a/include/osmocom/gsm/protocol/gsm_12_21.h +++ b/include/osmocom/gsm/protocol/gsm_12_21.h @@ -29,6 +29,7 @@ /*! \file gsm_12_21.h */ #include +#include #include /*! \brief generic header in front of every OML message according to TS 08.59 */ @@ -791,6 +792,22 @@ IPAC_BINF_CELL_ALLOC = (1 << 2), }; +/*! \brief 3GPP TS 52.021 ?9.4.62 SW Description */ +struct abis_nm_sw_descr { + uint8_t file_id[UINT8_MAX]; + uint8_t file_id_len; + + uint8_t file_version[UINT8_MAX]; + uint8_t file_version_len; +}; + +uint16_t abis_nm_sw_descr_len(const struct abis_nm_sw_descr *sw, + bool put_sw_descr); +uint16_t abis_nm_put_sw_descr(struct msgb *msg, const struct abis_nm_sw_descr *sw, + bool put_sw_descr); +bool abis_nm_get_sw_descr(struct abis_nm_sw_descr *sw, const uint8_t * buf, + size_t len); + struct msgb *abis_nm_fail_evt_rep(enum abis_nm_event_type t, enum abis_nm_severity s, enum abis_nm_pcause_type ct, diff --git a/src/gsm/abis_nm.c b/src/gsm/abis_nm.c index 934d7ce..6dbc45a 100644 --- a/src/gsm/abis_nm.c +++ b/src/gsm/abis_nm.c @@ -751,6 +751,81 @@ return nmsg; } +/*! \brief Compute length of given 3GPP TS 52.021 ?9.4.62 SW Description. + * \param[in] sw SW Description struct + * \param[in] put_sw_descr boolean, whether to put NM_ATT_SW_DESCR IE or not + * \returns length of buffer space necessary to store sw + */ +uint16_t abis_nm_sw_descr_len(const struct abis_nm_sw_descr *sw, + bool put_sw_descr) +{ + /* +3: type is 1-byte, length is 2-byte */ + return (put_sw_descr ? 1 : 0) + (sw->file_id_len + 3) + + (sw->file_version_len + 3); +} + +/*! \brief Put given 3GPP TS 52.021 ?9.4.62 SW Description into msgb. + * \param[out] msg message buffer + * \param[in] sw SW Description struct + * \param[in] put_sw_descr boolean, whether to put NM_ATT_SW_DESCR IE or not + * \param[in] simulate boolean, whether to actually modify msg or not + * \returns length of buffer space necessary to store sw + */ +uint16_t abis_nm_put_sw_descr(struct msgb *msg, const struct abis_nm_sw_descr *sw, + bool put_sw_descr) +{ + if (put_sw_descr) + msgb_v_put(msg, NM_ATT_SW_DESCR); + msgb_tl16v_put(msg, NM_ATT_FILE_ID, sw->file_id_len, sw->file_id); + msgb_tl16v_put(msg, NM_ATT_FILE_VERSION, sw->file_version_len, + sw->file_version); + + return abis_nm_sw_descr_len(sw, put_sw_descr); +} + +/*! \brief Parse 3GPP TS 52.021 ?9.4.62 SW Description from buffer. + * \param[out] sw SW Description struct + * \param[in] buf buffer + * \param[in] len buffer length + * \returns true if parsing succeeded, else otherwise + */ +bool abis_nm_get_sw_descr(struct abis_nm_sw_descr *sw, const uint8_t * buf, + size_t len) +{ + static struct tlv_parsed tp; + const struct tlv_definition sw_tlvdef = { + .def = { + [NM_ATT_SW_DESCR] = { TLV_TYPE_TV }, + [NM_ATT_FILE_ID] = { TLV_TYPE_TL16V }, + [NM_ATT_FILE_VERSION] = { TLV_TYPE_TL16V }, + }, + }; + + /* Note: the return value is ignored here because SW Description tag + itself is considered optional. */ + tlv_parse(&tp, &sw_tlvdef, buf, len, 0, 0); + + /* Parsing SW Description is tricky for current implementation of TLV + parser which fails to properly handle TV when V has following + structure: | TL16V | TL16V |. Hence, the need for 2nd call: */ + if (tlv_parse(&tp, &sw_tlvdef, buf + TLVP_LEN(&tp, NM_ATT_SW_DESCR), + len - TLVP_LEN(&tp, NM_ATT_SW_DESCR), 0, 0) < 0) + return false; + + if (!TLVP_PRESENT(&tp, NM_ATT_FILE_ID) || + !TLVP_PRESENT(&tp, NM_ATT_FILE_VERSION)) + return false; + + sw->file_id_len = TLVP_LEN(&tp, NM_ATT_FILE_ID); + sw->file_version_len = TLVP_LEN(&tp, NM_ATT_FILE_VERSION); + + memcpy(sw->file_id, TLVP_VAL(&tp, NM_ATT_FILE_ID), sw->file_id_len); + memcpy(sw->file_version, TLVP_VAL(&tp, NM_ATT_FILE_VERSION), + sw->file_version_len); + + return true; +} + /*! \brief Obtain OML Channel Combination for phnsical channel config */ int abis_nm_chcomb4pchan(enum gsm_phys_chan_config pchan) { diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map index 5649e71..a8ad892 100644 --- a/src/gsm/libosmogsm.map +++ b/src/gsm/libosmogsm.map @@ -31,6 +31,9 @@ abis_nm_pcause_type_names; abis_nm_msgtype_names; abis_nm_att_names; +abis_nm_sw_descr_len; +abis_nm_put_sw_descr; +abis_nm_get_sw_descr; osmo_sitype_strs; osmo_c4; diff --git a/tests/Makefile.am b/tests/Makefile.am index 352b5a7..16b45ea 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -74,7 +74,7 @@ lapd_lapd_test_LDADD = $(top_builddir)/src/libosmocore.la $(top_builddir)/src/gsm/libosmogsm.la msgb_msgb_test_SOURCES = msgb/msgb_test.c -msgb_msgb_test_LDADD = $(top_builddir)/src/libosmocore.la +msgb_msgb_test_LDADD = $(top_builddir)/src/libosmocore.la $(top_builddir)/src/gsm/libosmogsm.la msgfile_msgfile_test_SOURCES = msgfile/msgfile_test.c msgfile_msgfile_test_LDADD = $(top_builddir)/src/libosmocore.la diff --git a/tests/lapd/lapd_test.c b/tests/lapd/lapd_test.c index e322314..ee1cd28 100644 --- a/tests/lapd/lapd_test.c +++ b/tests/lapd/lapd_test.c @@ -25,9 +25,10 @@ #include #include #include +#include #include - +#include #include #define CHECK_RC(rc) \ @@ -752,6 +753,64 @@ lapdm_channel_exit(&bts_to_ms_channel); } +static inline void print_chk(const char *what, uint8_t len1, uint8_t len2, + const uint8_t *x1, const uint8_t *x2) +{ + int cmp = memcmp(x1, x2, len2); + printf("\tFILE %s [%u == %u -> %d, %s] %d => %s\n", what, len1, len2, + len1 == len2, len1 != len2 ? "fail" : "ok", + cmp, cmp != 0 ? "FAIL" : "OK"); +} + +static inline void chk_descr(struct msgb *msg, struct abis_nm_sw_descr *get, + struct abis_nm_sw_descr *put, bool h) +{ + bool res; + uint16_t len = abis_nm_put_sw_descr(msg, put, h); + + printf("msgb [%u/%u/%u - %s]: SW DESCR (with%s header) %s:\n", + msg->len, msg->data_len, len, len != msg->len ? "fail" : "ok", + h ? "" : "out", + len > put->file_version_len + put->file_id_len ? "OK" : "FAIL"); + + res = abis_nm_get_sw_descr(get, msgb_data(msg), msg->len); + if (res) { + print_chk("ID", get->file_id_len, put->file_id_len, get->file_id, + put->file_id); + print_chk("VERSION", get->file_version_len, + put->file_version_len, get->file_version, + put->file_version); + } else + printf("SW DESCR (with%s header) parsing error!\n", + h ? "" : "out"); +} + +static void test_sw_descr() +{ + const char *f_id = "TEST.L0L", *f_ver = "0.1.666~deadbeeffacefeed-dirty"; + uint8_t lf_id = strlen(f_id), lf_ver = strlen(f_ver); + struct msgb *msg = msgb_alloc_headroom(4096, 128, "sw"); + struct abis_nm_sw_descr sw_get1 = { 0 }, sw_get2 = { 0 }, sw_get3 = { 0 }, + sw_put = { + .file_id_len = lf_id, + .file_version_len = lf_ver, + }; + + printf("\nI test SW Description (de)serialization.\n"); + + memcpy(sw_put.file_id, f_id, lf_id); + memcpy(sw_put.file_version, f_ver, lf_ver); + + /* check that parsing |SW|ID|VER| works: */ + chk_descr(msg, &sw_get1, &sw_put, true); + msgb_reset(msg); + /* check that parsing |ID|VER| works: */ + chk_descr(msg, &sw_get2, &sw_put, false); + /* check that parsing |ID|VER|SW|ID|VER| fails - notice the lack of + msgb_reset() to create bogus msgb data: */ + chk_descr(msg, &sw_get3, &sw_put, true); +} + int main(int argc, char **argv) { osmo_init_logging(&info); @@ -765,6 +824,7 @@ test_lapdm_contention_resolution(); test_lapdm_establishment(); test_lapdm_desync(); + test_sw_descr(); printf("Success.\n"); diff --git a/tests/lapd/lapd_test.ok b/tests/lapd/lapd_test.ok index e188e27..c6f72f1 100644 --- a/tests/lapd/lapd_test.ok +++ b/tests/lapd/lapd_test.ok @@ -96,4 +96,14 @@ Took message from DCCH queue: L2 header size 23, L3 size 0, SAP 0x1000000, 0/0, Link 0x03 Message: [L2]> 0d 21 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b + +I test SW Description (de)serialization. +msgb [45/4096/45 - ok]: SW DESCR (with header) OK: + FILE ID [8 == 8 -> 1, ok] 0 => OK + FILE VERSION [30 == 30 -> 1, ok] 0 => OK +msgb [44/4096/44 - ok]: SW DESCR (without header) OK: + FILE ID [8 == 8 -> 1, ok] 0 => OK + FILE VERSION [30 == 30 -> 1, ok] 0 => OK +msgb [89/4096/45 - fail]: SW DESCR (with header) OK: +SW DESCR (with header) parsing error! Success. -- To view, visit https://gerrit.osmocom.org/2165 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ib63b6b5e83b8914864fc7edd789f8958cdc993cd Gerrit-PatchSet: 6 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Mon Apr 3 12:17:02 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Mon, 3 Apr 2017 12:17:02 +0000 Subject: libosmocore[master]: Add SW Description (de)marshalling In-Reply-To: References: Message-ID: Patch Set 6: > I think this should be tightened. I think it's already tight - see the updated test routine with failing to parse when SW is in wrong position. Or have you some different test case in mind? -- To view, visit https://gerrit.osmocom.org/2165 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ib63b6b5e83b8914864fc7edd789f8958cdc993cd Gerrit-PatchSet: 6 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Mon Apr 3 14:13:04 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Mon, 3 Apr 2017 14:13:04 +0000 Subject: libosmocore[master]: Add SW Description (de)marshalling In-Reply-To: References: Message-ID: Patch Set 6: > add cross reference to openbsc Ib94db414e94a2a1f234ac6f1cb346dca1c7a8be3 What for? Refs to dependencies and commits already in master make sense as they are persistent, links to smth ephemeral (can be abandoned, split into several commits etc) are pointless. -- To view, visit https://gerrit.osmocom.org/2165 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ib63b6b5e83b8914864fc7edd789f8958cdc993cd Gerrit-PatchSet: 6 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Mon Apr 3 15:43:04 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Mon, 3 Apr 2017 15:43:04 +0000 Subject: [PATCH] libosmocore[master]: Add SW Description (de)marshalling In-Reply-To: References: Message-ID: Hello Neels Hofmeyr, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2165 to look at the new patch set (#7). Add SW Description (de)marshalling * data structure representing 3GPP TS 52.021 ?9.4.62 SW Description * function to serialize it into msgb * function to deserialize it from buffer * function to estimate buffer size * test harness There are several similar functions to deal with SW Description in OpenBSC, there's also need to use similar functionality in OsmoBTS. Hence it's better to put the code into common library with proper tests and documentation. Change-Id: Ib63b6b5e83b8914864fc7edd789f8958cdc993cd Related: OS#1614 --- M include/osmocom/gsm/protocol/gsm_12_21.h M src/gsm/abis_nm.c M src/gsm/libosmogsm.map M tests/Makefile.am M tests/lapd/lapd_test.c M tests/lapd/lapd_test.ok 6 files changed, 172 insertions(+), 2 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/65/2165/7 diff --git a/include/osmocom/gsm/protocol/gsm_12_21.h b/include/osmocom/gsm/protocol/gsm_12_21.h index c88f0b1..90fee36 100644 --- a/include/osmocom/gsm/protocol/gsm_12_21.h +++ b/include/osmocom/gsm/protocol/gsm_12_21.h @@ -29,6 +29,7 @@ /*! \file gsm_12_21.h */ #include +#include #include /*! \brief generic header in front of every OML message according to TS 08.59 */ @@ -791,6 +792,22 @@ IPAC_BINF_CELL_ALLOC = (1 << 2), }; +/*! \brief 3GPP TS 52.021 ?9.4.62 SW Description */ +struct abis_nm_sw_descr { + uint8_t file_id[UINT8_MAX]; + uint8_t file_id_len; + + uint8_t file_version[UINT8_MAX]; + uint8_t file_version_len; +}; + +uint16_t abis_nm_sw_descr_len(const struct abis_nm_sw_descr *sw, + bool put_sw_descr); +uint16_t abis_nm_put_sw_descr(struct msgb *msg, const struct abis_nm_sw_descr *sw, + bool put_sw_descr); +int abis_nm_get_sw_descr(struct abis_nm_sw_descr *sw, const uint8_t * buf, + size_t len); + struct msgb *abis_nm_fail_evt_rep(enum abis_nm_event_type t, enum abis_nm_severity s, enum abis_nm_pcause_type ct, diff --git a/src/gsm/abis_nm.c b/src/gsm/abis_nm.c index 934d7ce..80b232e 100644 --- a/src/gsm/abis_nm.c +++ b/src/gsm/abis_nm.c @@ -751,6 +751,85 @@ return nmsg; } +/*! \brief Compute length of given 3GPP TS 52.021 ?9.4.62 SW Description. + * \param[in] sw SW Description struct + * \param[in] put_sw_descr boolean, whether to put NM_ATT_SW_DESCR IE or not + * \returns length of buffer space necessary to store sw + */ +uint16_t abis_nm_sw_descr_len(const struct abis_nm_sw_descr *sw, + bool put_sw_descr) +{ + /* +3: type is 1-byte, length is 2-byte */ + return (put_sw_descr ? 1 : 0) + (sw->file_id_len + 3) + + (sw->file_version_len + 3); +} + +/*! \brief Put given 3GPP TS 52.021 ?9.4.62 SW Description into msgb. + * \param[out] msg message buffer + * \param[in] sw SW Description struct + * \param[in] put_sw_descr boolean, whether to put NM_ATT_SW_DESCR IE or not + * \param[in] simulate boolean, whether to actually modify msg or not + * \returns length of buffer space necessary to store sw + */ +uint16_t abis_nm_put_sw_descr(struct msgb *msg, const struct abis_nm_sw_descr *sw, + bool put_sw_descr) +{ + if (put_sw_descr) + msgb_v_put(msg, NM_ATT_SW_DESCR); + msgb_tl16v_put(msg, NM_ATT_FILE_ID, sw->file_id_len, sw->file_id); + msgb_tl16v_put(msg, NM_ATT_FILE_VERSION, sw->file_version_len, + sw->file_version); + + return abis_nm_sw_descr_len(sw, put_sw_descr); +} + +/*! \brief Parse 3GPP TS 52.021 ?9.4.62 SW Description from buffer. + * \param[out] sw SW Description struct + * \param[in] buf buffer + * \param[in] len buffer length + * \returns 0 if parsing succeeded, negative error code otherwise + */ +int abis_nm_get_sw_descr(struct abis_nm_sw_descr *sw, const uint8_t * buf, + size_t len) +{ + int rc; + static struct tlv_parsed tp; + const struct tlv_definition sw_tlvdef = { + .def = { + [NM_ATT_SW_DESCR] = { TLV_TYPE_TV }, + [NM_ATT_FILE_ID] = { TLV_TYPE_TL16V }, + [NM_ATT_FILE_VERSION] = { TLV_TYPE_TL16V }, + }, + }; + + /* Note: the return value is ignored here because SW Description tag + itself is considered optional. */ + tlv_parse(&tp, &sw_tlvdef, buf, len, 0, 0); + + /* Parsing SW Description is tricky for current implementation of TLV + parser which fails to properly handle TV when V has following + structure: | TL16V | TL16V |. Hence, the need for 2nd call: */ + rc = tlv_parse(&tp, &sw_tlvdef, buf + TLVP_LEN(&tp, NM_ATT_SW_DESCR), + len - TLVP_LEN(&tp, NM_ATT_SW_DESCR), 0, 0); + if (rc < 0) + return rc; + + if (!TLVP_PRESENT(&tp, NM_ATT_FILE_ID)) + return -EBADF; + + if (!TLVP_PRESENT(&tp, NM_ATT_FILE_VERSION)) + return -EBADMSG; + + sw->file_id_len = TLVP_LEN(&tp, NM_ATT_FILE_ID); + sw->file_version_len = TLVP_LEN(&tp, NM_ATT_FILE_VERSION); + + memcpy(sw->file_id, TLVP_VAL(&tp, NM_ATT_FILE_ID), sw->file_id_len); + memcpy(sw->file_version, TLVP_VAL(&tp, NM_ATT_FILE_VERSION), + sw->file_version_len); + + return 0; +} + /*! \brief Obtain OML Channel Combination for phnsical channel config */ int abis_nm_chcomb4pchan(enum gsm_phys_chan_config pchan) { diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map index 5649e71..a8ad892 100644 --- a/src/gsm/libosmogsm.map +++ b/src/gsm/libosmogsm.map @@ -31,6 +31,9 @@ abis_nm_pcause_type_names; abis_nm_msgtype_names; abis_nm_att_names; +abis_nm_sw_descr_len; +abis_nm_put_sw_descr; +abis_nm_get_sw_descr; osmo_sitype_strs; osmo_c4; diff --git a/tests/Makefile.am b/tests/Makefile.am index 352b5a7..16b45ea 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -74,7 +74,7 @@ lapd_lapd_test_LDADD = $(top_builddir)/src/libosmocore.la $(top_builddir)/src/gsm/libosmogsm.la msgb_msgb_test_SOURCES = msgb/msgb_test.c -msgb_msgb_test_LDADD = $(top_builddir)/src/libosmocore.la +msgb_msgb_test_LDADD = $(top_builddir)/src/libosmocore.la $(top_builddir)/src/gsm/libosmogsm.la msgfile_msgfile_test_SOURCES = msgfile/msgfile_test.c msgfile_msgfile_test_LDADD = $(top_builddir)/src/libosmocore.la diff --git a/tests/lapd/lapd_test.c b/tests/lapd/lapd_test.c index e322314..b5f36b9 100644 --- a/tests/lapd/lapd_test.c +++ b/tests/lapd/lapd_test.c @@ -25,9 +25,10 @@ #include #include #include +#include #include - +#include #include #define CHECK_RC(rc) \ @@ -752,6 +753,65 @@ lapdm_channel_exit(&bts_to_ms_channel); } +static inline void print_chk(const char *what, uint8_t len1, uint8_t len2, + const uint8_t *x1, const uint8_t *x2) +{ + int cmp = memcmp(x1, x2, len2); + printf("\tFILE %s [%u == %u -> %d, %s] %d => %s\n", what, len1, len2, + len1 == len2, len1 != len2 ? "fail" : "ok", + cmp, cmp != 0 ? "FAIL" : "OK"); +} + +static inline void chk_descr(struct msgb *msg, struct abis_nm_sw_descr *get, + struct abis_nm_sw_descr *put, bool h) +{ + int res; + uint16_t len = abis_nm_put_sw_descr(msg, put, h); + + printf("msgb [%u/%u/%u - %s]: SW DESCR (with%s header) %s:\n", + msg->len, msg->data_len, len, len != msg->len ? "fail" : "ok", + h ? "" : "out", + len > put->file_version_len + put->file_id_len ? "OK" : "FAIL"); + + res = abis_nm_get_sw_descr(get, msgb_data(msg), msg->len); + if (res < 0) + printf("SW DESCR (with%s header) parsing error code %d!\n", + h ? "" : "out", -res); + else { + print_chk("ID", get->file_id_len, put->file_id_len, get->file_id, + put->file_id); + print_chk("VERSION", get->file_version_len, + put->file_version_len, get->file_version, + put->file_version); + } +} + +static void test_sw_descr() +{ + const char *f_id = "TEST.L0L", *f_ver = "0.1.666~deadbeeffacefeed-dirty"; + uint8_t lf_id = strlen(f_id), lf_ver = strlen(f_ver); + struct msgb *msg = msgb_alloc_headroom(4096, 128, "sw"); + struct abis_nm_sw_descr sw_get1 = { 0 }, sw_get2 = { 0 }, sw_get3 = { 0 }, + sw_put = { + .file_id_len = lf_id, + .file_version_len = lf_ver, + }; + + printf("\nI test SW Description (de)serialization.\n"); + + memcpy(sw_put.file_id, f_id, lf_id); + memcpy(sw_put.file_version, f_ver, lf_ver); + + /* check that parsing |SW|ID|VER| works: */ + chk_descr(msg, &sw_get1, &sw_put, true); + msgb_reset(msg); + /* check that parsing |ID|VER| works: */ + chk_descr(msg, &sw_get2, &sw_put, false); + /* check that parsing |ID|VER|SW|ID|VER| fails - notice the lack of + msgb_reset() to create bogus msgb data: */ + chk_descr(msg, &sw_get3, &sw_put, true); +} + int main(int argc, char **argv) { osmo_init_logging(&info); @@ -765,6 +825,7 @@ test_lapdm_contention_resolution(); test_lapdm_establishment(); test_lapdm_desync(); + test_sw_descr(); printf("Success.\n"); diff --git a/tests/lapd/lapd_test.ok b/tests/lapd/lapd_test.ok index e188e27..9ba2e47 100644 --- a/tests/lapd/lapd_test.ok +++ b/tests/lapd/lapd_test.ok @@ -96,4 +96,14 @@ Took message from DCCH queue: L2 header size 23, L3 size 0, SAP 0x1000000, 0/0, Link 0x03 Message: [L2]> 0d 21 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b + +I test SW Description (de)serialization. +msgb [45/4096/45 - ok]: SW DESCR (with header) OK: + FILE ID [8 == 8 -> 1, ok] 0 => OK + FILE VERSION [30 == 30 -> 1, ok] 0 => OK +msgb [44/4096/44 - ok]: SW DESCR (without header) OK: + FILE ID [8 == 8 -> 1, ok] 0 => OK + FILE VERSION [30 == 30 -> 1, ok] 0 => OK +msgb [89/4096/45 - fail]: SW DESCR (with header) OK: +SW DESCR (with header) parsing error code 3! Success. -- To view, visit https://gerrit.osmocom.org/2165 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ib63b6b5e83b8914864fc7edd789f8958cdc993cd Gerrit-PatchSet: 7 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Mon Apr 3 15:50:31 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 3 Apr 2017 15:50:31 +0000 Subject: [PATCH] libosmo-sccp[master]: Replace unused m3ua_types.h with protocol/m3ua.h Message-ID: Review at https://gerrit.osmocom.org/2191 Replace unused m3ua_types.h with protocol/m3ua.h This is more in line with what we do for SUA in protocol/sua.h Change-Id: I4a32cb698d28b4ccff9280b8512557ab5a353fe3 --- M include/osmocom/sigtran/Makefile.am D include/osmocom/sigtran/m3ua_types.h A include/osmocom/sigtran/protocol/m3ua.h 3 files changed, 149 insertions(+), 130 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/91/2191/1 diff --git a/include/osmocom/sigtran/Makefile.am b/include/osmocom/sigtran/Makefile.am index e168256..ca7de0f 100644 --- a/include/osmocom/sigtran/Makefile.am +++ b/include/osmocom/sigtran/Makefile.am @@ -1,7 +1,7 @@ -sigtran_HEADERS = m3ua_types.h xua_types.h xua_msg.h m2ua_types.h sccp_sap.h \ +sigtran_HEADERS = xua_types.h xua_msg.h m2ua_types.h sccp_sap.h \ sua.h sigtran_sap.h sccp_helpers.h sigtrandir = $(includedir)/osmocom/sigtran -sigtran_prot_HEADERS = protocol/sua.h +sigtran_prot_HEADERS = protocol/sua.h protocol/m3ua.h sigtran_protdir = $(includedir)/osmocom/sigtran/protocol diff --git a/include/osmocom/sigtran/m3ua_types.h b/include/osmocom/sigtran/m3ua_types.h deleted file mode 100644 index c8e62b4..0000000 --- a/include/osmocom/sigtran/m3ua_types.h +++ /dev/null @@ -1,128 +0,0 @@ -#pragma once - -/** - * Types found in the M3UA RFC 4666 - */ - -#include - - -#define M3UA_VERSION 1 - -enum { - M3UA_CLS_MGMT, /* Management (MGMT) Message [IUA/M2UA/M3UA/SUA] */ - M3UA_CLS_TRANS, /* Transfer Messages [M3UA] */ - M3UA_CLS_SSNM, /* SS7 Signalling Network Management (SSNM) Messages [M3UA/SUA] */ - M3UA_CLS_ASPSM, /* ASP State Maintenance (ASPSM) Messages [IUA/M2UA/M3UA/SUA] */ - M3UA_CLS_ASPTM, /* ASP Traffic Maintenance (ASPTM) Messages [IUA/M2UA/M3UA/SUA] */ - M3UA_CLS_RESERVED1, /* Reserved for Other SIGTRAN Adaptation Layers */ - M3UA_CLS_RESERVED2, /* Reserved for Other SIGTRAN Adaptation Layers */ - M3UA_CLS_RESERVED3, /* Reserved for Other SIGTRAN Adaptation Layers */ - M3UA_CLS_RESERVED4, /* Reserved for Other SIGTRAN Adaptation Layers */ - M3UA_CLS_RKM, /* Routing Key Management (RKM) Messages (M3UA) */ -}; - -/** - * Management (MGMT) messages - */ -enum { - M3UA_MGMT_ERROR, /* Error (ERR) */ - M3UA_MGMT_NTFY, /* Notify (NTFY) */ -}; - -/** - * Transfer Messages - */ -enum { - M3UA_TRANS_RESERVED, /* Reserved */ - M3UA_TRANS_DATA, /* Payload Data (DATA) */ -}; - -/** - * SS7 Signalling Network Management (SSNM) Messages - */ -enum { - M3UA_SSNM_RESERVED, /* Reserved */ - M3UA_SSNM_DUNA, /* Destination Unavailable (DUNA) */ - M3UA_SSNM_DAVA, /* Destination Available (DAVA) */ - M3UA_SSNM_DAUD, /* Destination State Audit (DAUD) */ - M3UA_SSNM_SCON, /* Signalling Congestion (SCON) */ - M3UA_SSNM_DUPU, /* Destination User Part Unavailable (DUPU) */ - M3UA_SSNM_DRST, /* Destination Restricted (DRST) */ -}; - -/** - * Application Server Process State Maintaenance (ASPSM) messages - */ -enum { - M3UA_ASPSM_RESERVED, /* Reserved */ - M3UA_ASPSM_UP, /* ASP Up (UP) */ - M3UA_ASPSM_DOWN, /* ASP Down (DOWN) */ - M3UA_ASPSM_BEAT, /* Heartbeat (BEAT) */ - M3UA_ASPSM_UP_ACK, /* ASP Up Ack (UP ACK) */ - M3UA_ASPSM_DOWN_ACK, /* ASP Down Ack (DOWN ACK) */ - M3UA_ASPSM_BEAT_ACK, /* Heartbeat Ack (BEAT ACK) */ -}; - -/** - * Application Server Process Traffic Maintaenance (ASPTM) messages. - */ -enum { - M3UA_ASPTM_RESERVED, /* Reserved */ - M3UA_ASPTM_ACTIV, /* ASP Active (ACTIVE) */ - M3UA_ASPTM_INACTIV, /* ASP Inactive (INACTIVE) */ - M3UA_ASPTM_ACTIV_ACK, /* ASP Active Ack (ACTIVE ACK) */ - M3UA_ASPTM_INACTIV_ACK, /* ASP Inactive Ack (INACTIVE ACK) */ -}; - -/** - * Routing Key Management (RKM) Messages - */ -enum { - M3UA_RKM_RESERVED, /* Reserved */ - M3UA_RKM_REG_REQ, /* Registration Request (REG REQ) */ - M3UA_RKM_REG_RSP, /* Registration Response (REG RSP) */ - M3UA_RKM_DEREG_REQ, /* Deregistration Request (DEREG REQ) */ - M3UA_RKM_DEREG_RSP, /* Deregistration Response (DEREG RSP) */ -}; - -/** - * Tag Values for M3UA - */ -enum { - M3UA_TAG_NET_APPEAR = 0x0200, /* Network Appearance */ - M3UA_TAG_RESERVED1, /* Reserved */ - M3UA_TAG_RESERVED2, /* Reserved */ - M3UA_TAG_RESERVED3, /* Reserved */ - M3UA_TAG_USER_CAUSE, /* User/Cause */ - M3UA_TAG_CONGEST_IND, /* Congestion Indications */ - M3UA_TAG_CONCERN_DEST, /* Concerned Destination */ - M3UA_TAG_ROUTING_KEY, /* Routing Key */ - M3UA_TAG_REG_RESULT, /* Registration Result */ - M3UA_TAG_DEREG_RESULT, /* Deregistration Result */ - M3UA_TAG_LOCAL_ROUT_KEY_IDENT, /* Local Routing Key Identifier */ - M3UA_TAG_DEST_PC, /* Destination Point Code */ - M3UA_TAG_SERV_IND, /* Service Indicators */ - M3UA_TAG_RESERVED4, /* Reserved */ - M3UA_TAG_ORIG_PC_LIST, /* Originating Point Code List */ - M3UA_TAG_RESERVED5, /* Reserved */ - M3UA_TAG_PROTO_DATA, /* Protocol Data */ - M3UA_TAG_RESERVED6, /* Reserved */ - M3UA_TAG_REG_STATUS, /* Registration Status */ - M3UA_TAG_DEREG_STATUS, /* Deregistration Status */ -}; - - -/** - * Protocol data for transport messages. This is - * replacing the MTP L3 header - */ -struct m3ua_protocol_data { - uint32_t opc; - uint32_t dpc; - uint8_t si; - uint8_t ni; - uint8_t mp; - uint8_t sls; - uint8_t data[0]; -} __attribute__((packed)); diff --git a/include/osmocom/sigtran/protocol/m3ua.h b/include/osmocom/sigtran/protocol/m3ua.h new file mode 100644 index 0000000..d4dc1fe --- /dev/null +++ b/include/osmocom/sigtran/protocol/m3ua.h @@ -0,0 +1,147 @@ +/* RFC 4666 M3UA SCCP User Adaption */ + +/* (C) 2017 by Harald Welte + * + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once +#include + +#define M3UA_VERSION 1 +#define M3UA_PPID 3 +#define M3UA_PORT 2905 + +/* 3.1.2 Message Classes */ +#define M3UA_MSGC_MGMT 0 +#define M3UA_MSGC_XFER 1 +#define M3UA_MSGC_SNM 2 +#define M3UA_MSGC_ASPSM 3 +#define M3UA_MSGC_ASPTM 4 +#define M3UA_MSGC_RKM 9 + +/* 3.1.3 Message Types */ +#define M3UA_MGMT_ERR 0 +#define M3UA_MGMT_NTFY 1 + +#define M3UA_XFER_DATA 1 + +#define M3UA_SNM_DUNA 1 +#define M3UA_SNM_DAVA 2 +#define M3UA_SNM_DAUD 3 +#define M3UA_SNM_SCON 4 +#define M3UA_SNM_DUPU 5 +#define M3UA_SNM_DRST 6 + +#define M3UA_ASPSM_UP 1 +#define M3UA_ASPSM_DOWN 2 +#define M3UA_ASPSM_BEAT 3 +#define M3UA_ASPSM_UP_ACK 4 +#define M3UA_ASPSM_DOWN_ACK 5 +#define M3UA_ASPSM_BEAT_ACK 6 + +#define M3UA_ASPTM_ACTIVE 1 +#define M3UA_ASPTM_INACTIVE 2 +#define M3UA_ASPTM_ACTIVE_ACK 3 +#define M3UA_ASPTM_INACTIVE_ACK 4 + +#define M3UA_RKM_REG_REQ 1 +#define M3UA_RKM_REG_RSP 2 +#define M3UA_RKM_DEREG_REQ 3 +#define M3UA_RKM_DEREG_RSP 4 + +#define M3UA_IEI_INFO_STRING 0x0004 +#define M3UA_IEI_ROUTE_CTX 0x0006 +#define M3UA_IEI_DIAG_INFO 0x0007 +#define M3UA_IEI_HEARDBT_DATA 0x0009 +#define M3UA_IEI_TRAF_MODE_TYP 0x000b +#define M3UA_IEI_ERR_CODE 0x000c +#define M3UA_IEI_STATUS 0x000d +#define M3UA_IEI_ASP_ID 0x0011 +#define M3UA_IEI_AFFECTED_PC 0x0012 +#define M3UA_IEI_CORR_ID 0x0013 + +/* 3.2 M3UA specific parameters */ + +#define M3UA_IEI_NET_APPEAR 0x0200 +#define M3UA_IEI_USER_CAUSE 0x0204 +#define M3UA_IEI_CONG_IND 0x0205 +#define M3UA_IEI_CONC_DEST 0x0206 +#define M3UA_IEI_ROUT_KEY 0x0207 +#define M3UA_IEI_REG_RESULT 0x0208 +#define M3UA_IEI_DEREG_RESULT 0x0209 +#define M3UA_IEI_LOC_RKEY_ID 0x020a +#define M3UA_IEI_DEST_PC 0x020b +#define M3UA_IEI_SVC_IND 0x020c +#define M3UA_IEI_ORIG_PC 0x020e +#define M3UA_IEI_PROT_DATA 0x0210 +#define M3UA_IEI_REG_STATUS 0x0212 +#define M3UA_IEI_DEREG_STATUS 0x0213 + +/* 3.3.1 Payload Data Message */ +struct m3ua_data_hdr { + uint32_t opc; /* Originating Point Code */ + uint32_t dpc; /* Destination Point Code */ + uint8_t si; /* Service Indicator */ + uint8_t ni; /* Network Indicator */ + uint8_t mp; /* Message Priority */ + uint8_t sls; /* Signalling Link Selection */ +} __attribute__ ((packed)); + +/* 3.8.2 Notify */ + +#define M3UA_NOTIFY(type, info) ((info) << 16 | (type)) +#define M3UA_NOTIFY_T_STATCHG 1 +#define M3UA_NOTIFY_T_OTHER 2 + +#define M3UA_NOTIFY_I_RESERVED 1 +#define M3UA_NOTIFY_I_AS_INACT 2 +#define M3UA_NOTIFY_I_AS_ACT 3 +#define M3UA_NOTIFY_I_AS_PEND 4 + +#define M3UA_NOTIFY_I_OT_INS_RES 1 +#define M3UA_NOTIFY_I_OT_ALT_ASP_ACT 2 +#define M3UA_NOTIFY_I_OT_ASP_FAILURE 3 + +/* 3.8.1 Error */ +enum m3ua_error_code { + M3UA_ERR_INVALID_VERSION = 0x01, + /* not used in M3UA */ + M3UA_ERR_UNSUPP_MSG_CLASS = 0x03, + M3UA_ERR_UNSUPP_MSG_TYPE = 0x04, + M3UA_ERR_UNSUPP_TRAF_MOD_TYP = 0x05, + M3UA_ERR_UNEXPECTED_MSG = 0x06, + M3UA_ERR_PROTOCOL_ERR = 0x07, + /* not used in M3UA */ + M3UA_ERR_INVAL_STREAM_ID = 0x09, + /* not used in M3UA */ + /* not used in M3UA */ + /* not used in M3UA */ + M3UA_ERR_REFUSED_MGMT_BLOCKING = 0x0d, + M3UA_ERR_ASP_ID_REQD = 0x0e, + M3UA_ERR_INVAL_ASP_ID = 0x0f, + /* not used in M3UA */ + M3UA_ERR_INVAL_PARAM_VAL = 0x11, + M3UA_ERR_PARAM_FIELD_ERR = 0x12, + M3UA_ERR_UNEXP_PARAM = 0x13, + M3UA_ERR_DEST_STATUS_UNKN = 0x14, + M3UA_ERR_INVAL_NET_APPEAR = 0x15, + M3UA_ERR_MISSING_PARAM = 0x16, + /* not used in M3UA */ + /* not used in M3UA */ + M3UA_ERR_INVAL_ROUT_CTX = 0x19, + M3UA_ERR_NO_CONFGD_AS_FOR_ASP = 0x1a, +}; -- To view, visit https://gerrit.osmocom.org/2191 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I4a32cb698d28b4ccff9280b8512557ab5a353fe3 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Mon Apr 3 15:50:31 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 3 Apr 2017 15:50:31 +0000 Subject: [PATCH] libosmo-sccp[master]: sua.h: Define more IEIs; base definitions on m3ua.h Message-ID: Review at https://gerrit.osmocom.org/2192 sua.h: Define more IEIs; base definitions on m3ua.h A lot of IEIs are identical between the different xUA dialects, so let's base the SUA definitions on the m3ua definitions. Change-Id: I64c7166cf0b5c8a927ab7e14955100f8d13fe16a --- M include/osmocom/sigtran/protocol/sua.h 1 file changed, 13 insertions(+), 2 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/92/2192/1 diff --git a/include/osmocom/sigtran/protocol/sua.h b/include/osmocom/sigtran/protocol/sua.h index d191368..0ae4131 100644 --- a/include/osmocom/sigtran/protocol/sua.h +++ b/include/osmocom/sigtran/protocol/sua.h @@ -21,6 +21,9 @@ #pragma once #include +#include + +#define SUA_VERSION 1 #define SUA_PPID 4 #define SUA_PORT 14001 @@ -76,8 +79,16 @@ #define SUA_CO_COERR 10 #define SUA_CO_COIT 11 /* Connection Oriented Inactiviy Test */ -#define SUA_IEI_ROUTE_CTX 0x0006 -#define SUA_IEI_CORR_ID 0x0013 +#define SUA_IEI_INFO_STRING M3UA_IEI_INFO_STRING +#define SUA_IEI_ROUTE_CTX M3UA_IEI_ROUTE_CTX +#define SUA_IEI_DIAG_INFO M3UA_IEI_DIAG_INFO +#define SUA_IEI_HEARTBT_DATA M3UA_IEI_HEARDBT_DATA +#define SUA_IEI_TRAF_MODE_TYP M3UA_IEI_TRAF_MODE_TYP +#define SUA_IEI_ERR_CODE M3UA_IEI_ERR_CODE +#define SUA_IEI_STATUS M3UA_IEI_STATUS +#define SUA_IEI_ASP_ID M3UA_IEI_ASP_ID +#define SUA_IEI_AFFECTED_PC M3UA_IEI_AFFECTED_PC +#define SUA_IEI_CORR_ID M3UA_IEI_CORR_ID #define SUA_IEI_REG_RESULT 0x0014 #define SUA_IEI_DEREG_RESULT 0x0015 -- To view, visit https://gerrit.osmocom.org/2192 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I64c7166cf0b5c8a927ab7e14955100f8d13fe16a Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Mon Apr 3 15:50:32 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 3 Apr 2017 15:50:32 +0000 Subject: [PATCH] libosmo-sccp[master]: sua.h: Add #define for the varius SUA protocol errors Message-ID: Review at https://gerrit.osmocom.org/2193 sua.h: Add #define for the varius SUA protocol errors again using m3ua.h definitions as base whenever applicable. Change-Id: Iec2563cb158b1c18064671564a7502b5c4d82517 --- M include/osmocom/sigtran/protocol/sua.h 1 file changed, 22 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/93/2193/1 diff --git a/include/osmocom/sigtran/protocol/sua.h b/include/osmocom/sigtran/protocol/sua.h index 0ae4131..de67041 100644 --- a/include/osmocom/sigtran/protocol/sua.h +++ b/include/osmocom/sigtran/protocol/sua.h @@ -136,3 +136,25 @@ #define SUA_CAUSE_T_RELEASE 0x0300 #define SUA_CAUSE_T_RESET 0x0400 #define SUA_CAUSE_T_ERROR 0x0500 + +/* 3.9.12 Error: Identical to M3UA, extended by two at the bottom */ +#define SUA_ERR_INVALID_VERSION M3UA_ERR_INVALID_VERSION +#define SUA_ERR_UNSUPP_MSG_CLASS M3UA_ERR_UNSUPP_MSG_CLASS +#define SUA_ERR_UNSUPP_MSG_TYPE M3UA_ERR_UNSUPP_MSG_TYPE +#define SUA_ERR_UNSUPP_TRAF_MOD_TYP M3UA_ERR_UNSUPP_TRAF_MOD_TYP +#define SUA_ERR_UNEXPECTED_MSG M3UA_ERR_UNEXPECTED_MSG +#define SUA_ERR_PROTOCOL_ERR M3UA_ERR_PROTOCOL_ERR +#define SUA_ERR_INVAL_STREAM_ID M3UA_ERR_INVAL_STREAM_ID +#define SUA_ERR_REFUSED_MGMT_BLOCKING M3UA_ERR_REFUSED_MGMT_BLOCKING +#define SUA_ERR_ASP_ID_REQD M3UA_ERR_ASP_ID_REQD +#define SUA_ERR_INVAL_ASP_ID M3UA_ERR_INVAL_ASP_ID +#define SUA_ERR_INVAL_PARAM_VAL M3UA_ERR_INVAL_PARAM_VAL +#define SUA_ERR_PARAM_FIELD_ERR M3UA_ERR_PARAM_FIELD_ERR +#define SUA_ERR_UNEXP_PARAM M3UA_ERR_UNEXP_PARAM +#define SUA_ERR_DEST_STATUS_UNKN M3UA_ERR_DEST_STATUS_UNKN +#define SUA_ERR_INVAL_NET_APPEAR M3UA_ERR_INVAL_NET_APPEAR +#define SUA_ERR_MISSING_PARAM M3UA_ERR_MISSING_PARAM +#define SUA_ERR_INVAL_ROUT_CTX M3UA_ERR_INVAL_ROUT_CTX +#define SUA_ERR_NO_CONFGD_AS_FOR_ASP M3UA_ERR_NO_CONFGD_AS_FOR_ASP +#define SUA_ERR_SUBSYS_STATUS_UNKN 0x1b +#define SUA_ERR_INVAL_LOADSH_LEVEL 0x1c -- To view, visit https://gerrit.osmocom.org/2193 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Iec2563cb158b1c18064671564a7502b5c4d82517 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Mon Apr 3 15:50:32 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 3 Apr 2017 15:50:32 +0000 Subject: [PATCH] libosmo-sccp[master]: gitignore: add 'tags' files as created by 'make ctags' Message-ID: Review at https://gerrit.osmocom.org/2194 gitignore: add 'tags' files as created by 'make ctags' Change-Id: I9e4ec0e07b996092a1f4e6a01911dc0041111498 --- M .gitignore 1 file changed, 2 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/94/2194/1 diff --git a/.gitignore b/.gitignore index 168690a..abb2458 100644 --- a/.gitignore +++ b/.gitignore @@ -70,3 +70,5 @@ *.pc config.* + +tags -- To view, visit https://gerrit.osmocom.org/2194 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I9e4ec0e07b996092a1f4e6a01911dc0041111498 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Mon Apr 3 15:50:32 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 3 Apr 2017 15:50:32 +0000 Subject: [PATCH] libosmo-sccp[master]: gitignore: use one wildcard line for all test executables Message-ID: Review at https://gerrit.osmocom.org/2195 gitignore: use one wildcard line for all test executables Change-Id: I53ce43fa8e09646dec56c6cc32b09c4618e9b5a5 --- M .gitignore 1 file changed, 1 insertion(+), 8 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/95/2195/1 diff --git a/.gitignore b/.gitignore index abb2458..9d1435f 100644 --- a/.gitignore +++ b/.gitignore @@ -53,14 +53,7 @@ tests/channel/channel_test tests/db/db_test tests/debug/debug_test -tests/gsm0408/gsm0408_test -tests/m2ua/m2ua_test -tests/mtp/mtp_parse_test -tests/sccp/sccp_test -tests/sms/sms_test -tests/timer/timer_test -tests/sigtran/sua_server_test -tests/sigtran/sua_client_test +tests/*/*_test tests/atconfig tests/package.m4 -- To view, visit https://gerrit.osmocom.org/2195 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I53ce43fa8e09646dec56c6cc32b09c4618e9b5a5 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Mon Apr 3 15:50:33 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 3 Apr 2017 15:50:33 +0000 Subject: [PATCH] libosmo-sccp[master]: xua_msg: Add xua_msg_free_tag() and xua_msg_copy_part() Message-ID: Review at https://gerrit.osmocom.org/2196 xua_msg: Add xua_msg_free_tag() and xua_msg_copy_part() ... also, mark input to xua_msg_find_tag as 'const' pointer. Change-Id: I083634db9c3606bcff87700f253054a38a20816d --- M include/osmocom/sigtran/xua_msg.h M src/xua_msg.c 2 files changed, 31 insertions(+), 2 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/96/2196/1 diff --git a/include/osmocom/sigtran/xua_msg.h b/include/osmocom/sigtran/xua_msg.h index 2a6e3ae..23f92c5 100644 --- a/include/osmocom/sigtran/xua_msg.h +++ b/include/osmocom/sigtran/xua_msg.h @@ -50,7 +50,10 @@ int xua_msg_add_data(struct xua_msg *msg, uint16_t tag, uint16_t len, uint8_t *dat); -struct xua_msg_part *xua_msg_find_tag(struct xua_msg *msg, uint16_t tag); +struct xua_msg_part *xua_msg_find_tag(const struct xua_msg *msg, uint16_t tag); +int xua_msg_free_tag(struct xua_msg *xua, uint16_t tag); +int xua_msg_copy_part(struct xua_msg *xua_out, uint16_t tag_out, + const struct xua_msg *xua_in, uint16_t tag_in); struct xua_msg *xua_from_msg(const int version, uint16_t len, uint8_t *data); struct msgb *xua_to_msg(const int version, struct xua_msg *msg); diff --git a/src/xua_msg.c b/src/xua_msg.c index 4a3e013..98c1832 100644 --- a/src/xua_msg.c +++ b/src/xua_msg.c @@ -77,7 +77,7 @@ return 0; } -struct xua_msg_part *xua_msg_find_tag(struct xua_msg *xua, uint16_t tag) +struct xua_msg_part *xua_msg_find_tag(const struct xua_msg *xua, uint16_t tag) { struct xua_msg_part *part; @@ -88,6 +88,32 @@ return NULL; } +int xua_msg_free_tag(struct xua_msg *xua, uint16_t tag) +{ + struct xua_msg_part *part; + + llist_for_each_entry(part, &xua->headers, entry) { + if (part->tag == tag) { + llist_del(&part->entry); + talloc_free(part); + return 1; + } + } + return 0; +} + +int xua_msg_copy_part(struct xua_msg *xua_out, uint16_t tag_out, + const struct xua_msg *xua_in, uint16_t tag_in) +{ + const struct xua_msg_part *part; + + part = xua_msg_find_tag(xua_in, tag_in); + if (!part) + return -1; + + return xua_msg_add_data(xua_out, tag_out, part->len, part->dat); +} + struct xua_msg *xua_from_msg(const int version, uint16_t len, uint8_t *data) { struct xua_parameter_hdr *par; -- To view, visit https://gerrit.osmocom.org/2196 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I083634db9c3606bcff87700f253054a38a20816d Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Mon Apr 3 15:50:33 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 3 Apr 2017 15:50:33 +0000 Subject: [PATCH] libosmo-sccp[master]: xua_msg: Add concept of xua_msg_class and xua_msg_dialect Message-ID: Review at https://gerrit.osmocom.org/2197 xua_msg: Add concept of xua_msg_class and xua_msg_dialect A xua_msg_class repreents one xUA message class (like M3UA XFER or SUA CL). A dialect is then something like SUA or M3UA, each consisting of as many as 256 message classes. Each class contains value_strings of the individual messages, as well as constraint information on mandatory IEs for each message. Change-Id: Ib538aca295b7b50132bc814b2d7b56cbe5d65bfc --- M include/osmocom/sigtran/xua_msg.h M src/xua_msg.c 2 files changed, 130 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/97/2197/1 diff --git a/include/osmocom/sigtran/xua_msg.h b/include/osmocom/sigtran/xua_msg.h index 23f92c5..6e98409 100644 --- a/include/osmocom/sigtran/xua_msg.h +++ b/include/osmocom/sigtran/xua_msg.h @@ -42,6 +42,23 @@ /* TODO: keep small data in the struct for perf reasons */ }; +struct xua_msg_class { + const char *name; + const struct value_string *msgt_names; + const struct value_string *iei_names; + const uint16_t *mand_ies[256]; +}; + +struct xua_dialect { + const char *name; + uint16_t port; + uint16_t ppid; + int log_subsys; + const struct xua_msg_class *class[256]; +}; + +extern const struct xua_dialect xua_dialect_sua; +extern const struct xua_dialect xua_dialect_m3ua; extern int DXUA; @@ -66,3 +83,10 @@ uint32_t xua_msg_part_get_u32(struct xua_msg_part *part); uint32_t xua_msg_get_u32(struct xua_msg *xua, uint16_t iei); int xua_msg_add_sccp_addr(struct xua_msg *xua, uint16_t iei, const struct osmo_sccp_addr *addr); + +const char *xua_class_msg_name(const struct xua_msg_class *xmc, uint16_t msg_type); +const char *xua_class_iei_name(const struct xua_msg_class *xmc, uint16_t iei); +char *xua_hdr_dump(struct xua_msg *xua, const struct xua_dialect *dialect); +char *xua_msg_dump(struct xua_msg *xua, const struct xua_dialect *dialect); +int xua_dialect_check_all_mand_ies(const struct xua_dialect *dialect, struct xua_msg *xua); + diff --git a/src/xua_msg.c b/src/xua_msg.c index 98c1832..3aced08 100644 --- a/src/xua_msg.c +++ b/src/xua_msg.c @@ -301,3 +301,109 @@ return rc; } + +const char *xua_class_msg_name(const struct xua_msg_class *xmc, uint16_t msg_type) +{ + static char class_buf[64]; + + if (xmc && xmc->msgt_names) + return get_value_string(xmc->msgt_names, msg_type); + else { + snprintf(class_buf, sizeof(class_buf), "Unknown 0x%04x", msg_type); + return class_buf; + } +} + +const char *xua_class_iei_name(const struct xua_msg_class *xmc, uint16_t iei) +{ + static char iei_buf[64]; + + if (xmc && xmc->iei_names) + return get_value_string(xmc->iei_names, iei); + else { + snprintf(iei_buf, sizeof(iei_buf), "Unknown 0x%04x", iei); + return iei_buf; + } +} + +char *xua_hdr_dump(struct xua_msg *xua, const struct xua_dialect *dialect) +{ + const struct xua_msg_class *xmc = NULL; + static char buf[128]; + + if (dialect) + xmc = dialect->class[xua->hdr.msg_class]; + if (!xmc) + snprintf(buf, sizeof(buf), "%u:%u", xua->hdr.msg_class, xua->hdr.msg_type); + else + snprintf(buf, sizeof(buf), "%s:%s", xmc->name, + xua_class_msg_name(xmc, xua->hdr.msg_type)); + return buf; +} + +int xua_dialect_check_all_mand_ies(const struct xua_dialect *dialect, struct xua_msg *xua) +{ + uint8_t msg_class = xua->hdr.msg_class; + uint8_t msg_type = xua->hdr.msg_type; + const struct xua_msg_class *xmc = dialect->class[msg_class]; + const uint16_t *ies; + uint16_t ie; + + /* unknown class? */ + if (!xmc) + return 1; + + ies = xmc->mand_ies[msg_type]; + /* no mandatory IEs? */ + if (!ies) + return 1; + + for (ie = *ies; ie; ie = *ies++) { + if (!xua_msg_find_tag(xua, ie)) { + LOGP(dialect->log_subsys, LOGL_ERROR, + "%s Message %s:%s should " + "contain IE %s, but doesn't\n", + dialect->name, xmc->name, + xua_class_msg_name(xmc, msg_type), + xua_class_iei_name(xmc, ie)); + return 0; + } + } + + return 1; +} + +static void append_to_buf(char *buf, bool *comma, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + if (!comma || *comma == true) { + strcat(buf, ","); + } else if (comma) + *comma = true; + vsprintf(buf+strlen(buf), fmt, ap); + va_end(ap); +} + +char *xua_msg_dump(struct xua_msg *xua, const struct xua_dialect *dialect) +{ + static char buf[1024]; + struct xua_msg_part *part; + const struct xua_msg_class *xmc = NULL; + + if (dialect) + xmc = dialect->class[xua->hdr.msg_class]; + + buf[0] = '\0'; + + append_to_buf(buf, NULL, "HDR=(%s,V=%u,LEN=%u)", + xua_hdr_dump(xua, dialect), + xua->hdr.version, xua->hdr.msg_length); + buf[0] = ' '; + llist_for_each_entry(part, &xua->headers, entry) + append_to_buf(buf, NULL, "\n\tPART(T=%s,L=%u,D=%s)", + xua_class_iei_name(xmc, part->tag), part->len, + osmo_hexdump_nospc(part->dat, part->len)); + return buf; +} -- To view, visit https://gerrit.osmocom.org/2197 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ib538aca295b7b50132bc814b2d7b56cbe5d65bfc Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Mon Apr 3 15:50:34 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 3 Apr 2017 15:50:34 +0000 Subject: [PATCH] libosmo-sccp[master]: sccp_sap: Use zero-terminated string for GT digits in osmo_s... Message-ID: Review at https://gerrit.osmocom.org/2198 sccp_sap: Use zero-terminated string for GT digits in osmo_sccp_addr This is more natural to most application code, so simply go for ASCII string with NUL-termination rather than an array with explicit length. Change-Id: I6312208cdfa83184be41157a473c96e9120c63db --- M include/osmocom/sigtran/sccp_sap.h 1 file changed, 1 insertion(+), 2 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/98/2198/1 diff --git a/include/osmocom/sigtran/sccp_sap.h b/include/osmocom/sigtran/sccp_sap.h index 0aa565a..e58e670 100644 --- a/include/osmocom/sigtran/sccp_sap.h +++ b/include/osmocom/sigtran/sccp_sap.h @@ -127,11 +127,10 @@ struct osmo_sccp_gt { uint8_t gti; - uint8_t nr_digits; uint8_t tt; uint32_t npi; uint32_t nai; - uint8_t digits[32]; + char digits[32]; }; struct osmo_sccp_addr { -- To view, visit https://gerrit.osmocom.org/2198 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I6312208cdfa83184be41157a473c96e9120c63db Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Mon Apr 3 15:50:34 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 3 Apr 2017 15:50:34 +0000 Subject: [PATCH] libosmo-sccp[master]: sccp_sap: Add routing indication (RI) to osmo_sccp_addr Message-ID: Review at https://gerrit.osmocom.org/2199 sccp_sap: Add routing indication (RI) to osmo_sccp_addr Change-Id: I4dd23150f4c588b6430c22fc0cb66635994ceea9 --- M include/osmocom/sigtran/sccp_sap.h 1 file changed, 1 insertion(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/99/2199/1 diff --git a/include/osmocom/sigtran/sccp_sap.h b/include/osmocom/sigtran/sccp_sap.h index e58e670..ec021c7 100644 --- a/include/osmocom/sigtran/sccp_sap.h +++ b/include/osmocom/sigtran/sccp_sap.h @@ -135,6 +135,7 @@ struct osmo_sccp_addr { uint32_t presence; + enum osmo_sccp_routing_ind ri; struct osmo_sccp_gt gt; uint32_t pc; uint32_t ssn; -- To view, visit https://gerrit.osmocom.org/2199 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I4dd23150f4c588b6430c22fc0cb66635994ceea9 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Mon Apr 3 15:50:34 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 3 Apr 2017 15:50:34 +0000 Subject: [PATCH] libosmo-sccp[master]: sccp_sap: Add support for N-NOTICE.indication Message-ID: Review at https://gerrit.osmocom.org/2200 sccp_sap: Add support for N-NOTICE.indication Change-Id: I6656889b4333e9909cf1c60c24dfc754281547b4 --- M include/osmocom/sigtran/sccp_sap.h 1 file changed, 10 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/00/2200/1 diff --git a/include/osmocom/sigtran/sccp_sap.h b/include/osmocom/sigtran/sccp_sap.h index ec021c7..139567e 100644 --- a/include/osmocom/sigtran/sccp_sap.h +++ b/include/osmocom/sigtran/sccp_sap.h @@ -198,6 +198,15 @@ /* user data */ }; +/* OSMO_SCU_PRIM_N_NOTICE */ +struct osmo_scu_notice_param { + struct osmo_sccp_addr called_addr; + struct osmo_sccp_addr calling_addr; + uint32_t cause; + uint32_t importance; + /* user data */ +}; + struct osmo_scu_prim { struct osmo_prim_hdr oph; union { @@ -206,6 +215,7 @@ struct osmo_scu_disconn_param disconnect; struct osmo_scu_reset_param reset; struct osmo_scu_unitdata_param unitdata; + struct osmo_scu_notice_param notice; } u; }; -- To view, visit https://gerrit.osmocom.org/2200 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I6656889b4333e9909cf1c60c24dfc754281547b4 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Mon Apr 3 15:50:34 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 3 Apr 2017 15:50:34 +0000 Subject: [PATCH] libosmo-sccp[master]: xua_msg: Add support for encoding Global Title in osmo_sccp_... Message-ID: Review at https://gerrit.osmocom.org/2201 xua_msg: Add support for encoding Global Title in osmo_sccp_addr Change-Id: I4668fd0fba2e1be1ec37e75eeee85ed476320d14 --- M include/osmocom/sigtran/xua_msg.h M src/xua_msg.c 2 files changed, 64 insertions(+), 3 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/01/2201/1 diff --git a/include/osmocom/sigtran/xua_msg.h b/include/osmocom/sigtran/xua_msg.h index 6e98409..18b9e49 100644 --- a/include/osmocom/sigtran/xua_msg.h +++ b/include/osmocom/sigtran/xua_msg.h @@ -25,6 +25,7 @@ struct msgb; struct osmo_sccp_addr; +struct osmo_sccp_gt; struct xua_msg { struct xua_common_hdr hdr; @@ -82,6 +83,7 @@ int xua_msg_add_u32(struct xua_msg *xua, uint16_t iei, uint32_t val); uint32_t xua_msg_part_get_u32(struct xua_msg_part *part); uint32_t xua_msg_get_u32(struct xua_msg *xua, uint16_t iei); +void xua_part_add_gt(struct msgb *msg, const struct osmo_sccp_gt *gt); int xua_msg_add_sccp_addr(struct xua_msg *xua, uint16_t iei, const struct osmo_sccp_addr *addr); const char *xua_class_msg_name(const struct xua_msg_class *xmc, uint16_t msg_type); diff --git a/src/xua_msg.c b/src/xua_msg.c index 3aced08..65ccaa7 100644 --- a/src/xua_msg.c +++ b/src/xua_msg.c @@ -1,5 +1,6 @@ /* Routines for generating and parsing messages */ /* (C) 2011 by Holger Hans Peter Freyther + * (C) 2016-2017 by Harald Welte * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by @@ -271,19 +272,77 @@ return xua_msg_part_get_u32(part); } +void xua_part_add_gt(struct msgb *msg, const struct osmo_sccp_gt *gt) +{ + uint16_t *len_ptr; + unsigned int num_digits = strlen(gt->digits); + unsigned int num_digit_bytes; + unsigned int i, j; + + /* Tag + Length */ + msgb_put_u16(msg, SUA_IEI_GT); + len_ptr = (uint16_t *) msgb_put(msg, sizeof(uint16_t)); + + /* first dword: padding + GT */ + msgb_put_u32(msg, gt->gti); + + /* second header dword */ + msgb_put_u8(msg, strlen(gt->digits)); + msgb_put_u8(msg, gt->tt); + msgb_put_u8(msg, gt->npi); + msgb_put_u8(msg, gt->nai); + + /* actual digits */ + num_digit_bytes = num_digits / 2; + if (num_digits & 1) + num_digit_bytes++; + for (i = 0, j = 0; i < num_digit_bytes; i++) { + uint8_t byte; + byte = osmo_char2bcd(gt->digits[j++]); + if (j < num_digits) { + byte |= osmo_char2bcd(gt->digits[j++]) << 4; + } + msgb_put_u8(msg, byte); + } + /* pad to 32bit */ + if (num_digit_bytes % 4) + msgb_put(msg, 4 - (num_digit_bytes % 4)); + *len_ptr = htons(msg->tail - (uint8_t *)len_ptr + 2); +} + int xua_msg_add_sccp_addr(struct xua_msg *xua, uint16_t iei, const struct osmo_sccp_addr *addr) { struct msgb *tmp = msgb_alloc(128, "SCCP Address"); + uint16_t addr_ind = 0; int rc; if (!tmp) return -ENOMEM; - msgb_put_u16(tmp, SUA_RI_SSN_PC); /* route on SSN + PC */ - msgb_put_u16(tmp, 7); /* always put all addresses on SCCP side */ + switch (addr->ri) { + case OSMO_SCCP_RI_GT: + msgb_put_u16(tmp, SUA_RI_GT); + break; + case OSMO_SCCP_RI_SSN_PC: + msgb_put_u16(tmp, SUA_RI_SSN_PC); + break; + case OSMO_SCCP_RI_SSN_IP: + msgb_put_u16(tmp, SUA_RI_SSN_IP); + break; + default: + return -EINVAL; + } + if (addr->presence & OSMO_SCCP_ADDR_T_SSN) + addr_ind |= 0x0001; + if (addr->presence & OSMO_SCCP_ADDR_T_PC) + addr_ind |= 0x0002; + if (addr->presence & OSMO_SCCP_ADDR_T_GT) + addr_ind |= 0x0004; + + msgb_put_u16(tmp, addr_ind); if (addr->presence & OSMO_SCCP_ADDR_T_GT) { - /* FIXME */ + xua_part_add_gt(tmp, &addr->gt); } if (addr->presence & OSMO_SCCP_ADDR_T_PC) { msgb_t16l16vp_put_u32(tmp, SUA_IEI_PC, addr->pc); -- To view, visit https://gerrit.osmocom.org/2201 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I4668fd0fba2e1be1ec37e75eeee85ed476320d14 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Mon Apr 3 15:50:35 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 3 Apr 2017 15:50:35 +0000 Subject: [PATCH] libosmo-sccp[master]: xua_msg: Add support for encoding IPv4 addr in osmo_sccp_addr Message-ID: Review at https://gerrit.osmocom.org/2202 xua_msg: Add support for encoding IPv4 addr in osmo_sccp_addr Change-Id: I956f069ce4cea78cb0db0470265ca8365093c0e5 --- M src/xua_msg.c 1 file changed, 1 insertion(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/02/2202/1 diff --git a/src/xua_msg.c b/src/xua_msg.c index 65ccaa7..73c5c24 100644 --- a/src/xua_msg.c +++ b/src/xua_msg.c @@ -351,7 +351,7 @@ msgb_t16l16vp_put_u32(tmp, SUA_IEI_SSN, addr->ssn); } if (addr->presence & OSMO_SCCP_ADDR_T_IPv4) { - /* FIXME: IPv4 address */ + msgb_t16l16vp_put_u32(tmp, SUA_IEI_IPv4, ntohl(addr->ip.v4.s_addr)); } else if (addr->presence & OSMO_SCCP_ADDR_T_IPv6) { /* FIXME: IPv6 address */ } -- To view, visit https://gerrit.osmocom.org/2202 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I956f069ce4cea78cb0db0470265ca8365093c0e5 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Mon Apr 3 15:50:35 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 3 Apr 2017 15:50:35 +0000 Subject: [PATCH] libosmo-sccp[master]: Add mtp_sap.h file with definitions for MTP-USER SAP Message-ID: Review at https://gerrit.osmocom.org/2203 Add mtp_sap.h file with definitions for MTP-USER SAP The ITU-T Q.70x series describe a MTP-USER SAP, which we define here for use with osmocom primitives. Change-Id: Id1f8892e5dee877e2ffbeb3925753ab3da5a9420 --- M include/osmocom/sigtran/Makefile.am A include/osmocom/sigtran/mtp_sap.h 2 files changed, 69 insertions(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/03/2203/1 diff --git a/include/osmocom/sigtran/Makefile.am b/include/osmocom/sigtran/Makefile.am index ca7de0f..2f2912f 100644 --- a/include/osmocom/sigtran/Makefile.am +++ b/include/osmocom/sigtran/Makefile.am @@ -1,5 +1,5 @@ sigtran_HEADERS = xua_types.h xua_msg.h m2ua_types.h sccp_sap.h \ - sua.h sigtran_sap.h sccp_helpers.h + sua.h sigtran_sap.h sccp_helpers.h mtp_sap.h sigtrandir = $(includedir)/osmocom/sigtran diff --git a/include/osmocom/sigtran/mtp_sap.h b/include/osmocom/sigtran/mtp_sap.h new file mode 100644 index 0000000..120ae91 --- /dev/null +++ b/include/osmocom/sigtran/mtp_sap.h @@ -0,0 +1,68 @@ +#pragma once + +/* MTP User SAP description in accordance with ITU Q.701 */ + +/* (C) 2017 by Harald Welte + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include +#include +#include + +enum osmo_mtp_prim_type { + OSMO_MTP_PRIM_TRANSFER, + OSMO_MTP_PRIM_PAUSE, + OSMO_MTP_PRIM_RESUME, + OSMO_MTP_PRIM_STATUS, +}; + +#define MTP_SIO(service, net_ind) (((net_ind & 0xF) << 4) | (service & 0xF)) + +struct osmo_mtp_transfer_param { + uint32_t opc; + uint32_t dpc; + uint8_t sls; + uint8_t sio; +}; + +struct osmo_mtp_pause_param { + uint32_t affected_dpc; +}; + +struct osmo_mtp_resume_param { + uint32_t affected_dpc; +}; + +struct osmo_mtp_status_param { + uint32_t affected_dpc; + uint32_t cause; +}; + +struct osmo_mtp_prim { + struct osmo_prim_hdr oph; + union { + struct osmo_mtp_transfer_param transfer; + struct osmo_mtp_pause_param pause; + struct osmo_mtp_resume_param resume; + struct osmo_mtp_status_param status; + } u; +}; + +#define msgb_mtp_prim(msg) ((struct osmo_mtp_prim *)(msg)->l1h) + +char *osmo_mtp_prim_name(struct osmo_prim_hdr *oph); -- To view, visit https://gerrit.osmocom.org/2203 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Id1f8892e5dee877e2ffbeb3925753ab3da5a9420 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Mon Apr 3 15:50:35 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 3 Apr 2017 15:50:35 +0000 Subject: [PATCH] libosmo-sccp[master]: xua_msg: Add MTP routing label to 'struct xua_msg' Message-ID: Review at https://gerrit.osmocom.org/2204 xua_msg: Add MTP routing label to 'struct xua_msg' Higher-layer protocols (particularly SCCP) require knowledge on the MTP-level routing label of a message. Let's add this to the common header of 'struct xua_msg' to communicate it across layer boundaries. Change-Id: I31a6388ac999e02ad779619adb54bbf4040672c9 --- M include/osmocom/sigtran/xua_msg.h 1 file changed, 2 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/04/2204/1 diff --git a/include/osmocom/sigtran/xua_msg.h b/include/osmocom/sigtran/xua_msg.h index 18b9e49..33eb1b0 100644 --- a/include/osmocom/sigtran/xua_msg.h +++ b/include/osmocom/sigtran/xua_msg.h @@ -20,6 +20,7 @@ #include "xua_types.h" #include +#include #define XUA_HDR(class, type) ((struct xua_common_hdr) { .spare = 0, .msg_class = (class), .msg_type = (type) }) @@ -29,6 +30,7 @@ struct xua_msg { struct xua_common_hdr hdr; + struct osmo_mtp_transfer_param mtp; struct llist_head headers; }; -- To view, visit https://gerrit.osmocom.org/2204 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I31a6388ac999e02ad779619adb54bbf4040672c9 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Mon Apr 3 15:50:35 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 3 Apr 2017 15:50:35 +0000 Subject: [PATCH] libosmo-sccp[master]: License headers: Should always have been GPLv2-or-later Message-ID: Review at https://gerrit.osmocom.org/2205 License headers: Should always have been GPLv2-or-later libosmo-sigtran is GPLv2-or-later, there were some files that accidentially had an AGPLv3 license header, which was a copy+paste mistake at that time. Change-Id: I67dfd0ae6157afafd3873a3baaa4c6107c04ddfd --- M debian/copyright M include/osmocom/sigtran/protocol/sua.h M include/osmocom/sigtran/sccp_sap.h M include/osmocom/sigtran/xua_msg.h M src/sccp_helpers.c M src/sua.c M src/xua_msg.c 7 files changed, 25 insertions(+), 27 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/05/2205/1 diff --git a/debian/copyright b/debian/copyright index 78c9f12..436675c 100644 --- a/debian/copyright +++ b/debian/copyright @@ -8,9 +8,7 @@ 2010 Harald Welte License: GPL-2+ -Files: include/sigtran/xua_msg.h - src/xua_msg.c - tests/m2ua/m2ua_test.c +Files: tests/m2ua/m2ua_test.c Copyright: 2011 Holger Hans Peter Freyther License: AGPL-3+ diff --git a/include/osmocom/sigtran/protocol/sua.h b/include/osmocom/sigtran/protocol/sua.h index de67041..70c16ba 100644 --- a/include/osmocom/sigtran/protocol/sua.h +++ b/include/osmocom/sigtran/protocol/sua.h @@ -5,8 +5,8 @@ * All Rights Reserved * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation; either version 3 of the + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, @@ -14,7 +14,7 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU Affero General Public License + * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ diff --git a/include/osmocom/sigtran/sccp_sap.h b/include/osmocom/sigtran/sccp_sap.h index 139567e..0cc1531 100644 --- a/include/osmocom/sigtran/sccp_sap.h +++ b/include/osmocom/sigtran/sccp_sap.h @@ -2,20 +2,20 @@ /* SCCP User SAP description */ -/* (C) 2015 by Harald Welte +/* (C) 2015-2017 by Harald Welte * All Rights Reserved * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation; either version 3 of the License, or + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. + * GNU General Public License for more details. * - * You should have received a copy of the GNU Affero General Public License + * You should have received a copy of the GNU General Public License * along with this program. If not, see . * */ diff --git a/include/osmocom/sigtran/xua_msg.h b/include/osmocom/sigtran/xua_msg.h index 33eb1b0..60dd693 100644 --- a/include/osmocom/sigtran/xua_msg.h +++ b/include/osmocom/sigtran/xua_msg.h @@ -2,16 +2,16 @@ /* (C) 2011 by Holger Hans Peter Freyther * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation; either version 3 of the License, or + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. + * GNU General Public License for more details. * - * You should have received a copy of the GNU Affero General Public License + * You should have received a copy of the GNU General Public License * along with this program. If not, see . * */ diff --git a/src/sccp_helpers.c b/src/sccp_helpers.c index 1fc257c..6264424 100644 --- a/src/sccp_helpers.c +++ b/src/sccp_helpers.c @@ -5,16 +5,16 @@ * All Rights Reserved * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation; either version 3 of the License, or + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. + * GNU General Public License for more details. * - * You should have received a copy of the GNU Affero General Public License + * You should have received a copy of the GNU General Public License * along with this program. If not, see . * */ diff --git a/src/sua.c b/src/sua.c index cdc2cf0..145bf1a 100644 --- a/src/sua.c +++ b/src/sua.c @@ -4,16 +4,16 @@ * All Rights Reserved * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation; either version 3 of the License, or + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. + * GNU General Public License for more details. * - * You should have received a copy of the GNU Affero General Public License + * You should have received a copy of the GNU General Public License * along with this program. If not, see . * */ diff --git a/src/xua_msg.c b/src/xua_msg.c index 73c5c24..32471b9 100644 --- a/src/xua_msg.c +++ b/src/xua_msg.c @@ -3,16 +3,16 @@ * (C) 2016-2017 by Harald Welte * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation; either version 3 of the License, or + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. + * GNU General Public License for more details. * - * You should have received a copy of the GNU Affero General Public License + * You should have received a copy of the GNU General Public License * along with this program. If not, see . * */ -- To view, visit https://gerrit.osmocom.org/2205 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I67dfd0ae6157afafd3873a3baaa4c6107c04ddfd Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Mon Apr 3 15:58:20 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 3 Apr 2017 15:58:20 +0000 Subject: [ABANDON] libosmo-sccp[master]: sccp_sap: Add osmo_sccp_routing_ind to osmo_sccp_addr In-Reply-To: References: Message-ID: Harald Welte has abandoned this change. Change subject: sccp_sap: Add osmo_sccp_routing_ind to osmo_sccp_addr ...................................................................... Abandoned -- To view, visit https://gerrit.osmocom.org/1830 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: abandon Gerrit-Change-Id: I559bc9a5308a46aa1b1c63557a4aec0effb48a0b Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Apr 3 15:58:24 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 3 Apr 2017 15:58:24 +0000 Subject: [ABANDON] libosmo-sccp[master]: xua_msg: Add xua_msg_dump() to print parsed XUA message In-Reply-To: References: Message-ID: Harald Welte has abandoned this change. Change subject: xua_msg: Add xua_msg_dump() to print parsed XUA message ...................................................................... Abandoned -- To view, visit https://gerrit.osmocom.org/1831 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: abandon Gerrit-Change-Id: I2f3ae77f440e0c27f78302cdb80e1d25fe5aebb6 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Apr 3 15:58:32 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 3 Apr 2017 15:58:32 +0000 Subject: [ABANDON] libosmo-sccp[master]: sua: make SUA address parsing available to other code within... In-Reply-To: References: Message-ID: Harald Welte has abandoned this change. Change subject: sua: make SUA address parsing available to other code within library ...................................................................... Abandoned -- To view, visit https://gerrit.osmocom.org/1832 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: abandon Gerrit-Change-Id: Id824ce1000abbb06592e8edda9c2896ac7d0efb3 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Apr 3 15:58:36 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 3 Apr 2017 15:58:36 +0000 Subject: [ABANDON] libosmo-sccp[master]: sua.c: Print xUA IEI always in hex representation In-Reply-To: References: Message-ID: Harald Welte has abandoned this change. Change subject: sua.c: Print xUA IEI always in hex representation ...................................................................... Abandoned -- To view, visit https://gerrit.osmocom.org/1833 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: abandon Gerrit-Change-Id: I9aa8eac82748c4e7656a12c42d9ff28573d8413b Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Apr 3 15:58:41 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 3 Apr 2017 15:58:41 +0000 Subject: [ABANDON] libosmo-sccp[master]: sua: Fix byte order when printing of embedded IEI In-Reply-To: References: Message-ID: Harald Welte has abandoned this change. Change subject: sua: Fix byte order when printing of embedded IEI ...................................................................... Abandoned -- To view, visit https://gerrit.osmocom.org/1834 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: abandon Gerrit-Change-Id: Ib9c3ec39cb1e6879fb652fa6fe04e05ad537a958 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Apr 3 15:58:45 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 3 Apr 2017 15:58:45 +0000 Subject: [ABANDON] libosmo-sccp[master]: sua: Add IPv4 encoding/decoding in SUA SCCP Addresses In-Reply-To: References: Message-ID: Harald Welte has abandoned this change. Change subject: sua: Add IPv4 encoding/decoding in SUA SCCP Addresses ...................................................................... Abandoned -- To view, visit https://gerrit.osmocom.org/1835 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: abandon Gerrit-Change-Id: Ic5c70360c6bf3a0d12f9ffc83a86d70f34c98f62 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Apr 3 15:58:49 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 3 Apr 2017 15:58:49 +0000 Subject: [ABANDON] libosmo-sccp[master]: sua: Parse SUA Global Title (nested in SUA SCCP Addresses) In-Reply-To: References: Message-ID: Harald Welte has abandoned this change. Change subject: sua: Parse SUA Global Title (nested in SUA SCCP Addresses) ...................................................................... Abandoned -- To view, visit https://gerrit.osmocom.org/1836 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: abandon Gerrit-Change-Id: Id6201362a78f2bc183a27bbc2f19e4de724eb88f Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Apr 3 15:58:53 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 3 Apr 2017 15:58:53 +0000 Subject: [ABANDON] libosmo-sccp[master]: sua: Always zero-initialize the output of sua_addr_parse_part() In-Reply-To: References: Message-ID: Harald Welte has abandoned this change. Change subject: sua: Always zero-initialize the output of sua_addr_parse_part() ...................................................................... Abandoned -- To view, visit https://gerrit.osmocom.org/1837 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: abandon Gerrit-Change-Id: Ia41a3f611dc8bb999db21f4e6fbe626f41aeb66e Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Apr 3 15:59:16 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 3 Apr 2017 15:59:16 +0000 Subject: libosmo-sccp[master]: Replace unused m3ua_types.h with protocol/m3ua.h In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2191 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I4a32cb698d28b4ccff9280b8512557ab5a353fe3 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Mon Apr 3 15:59:25 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 3 Apr 2017 15:59:25 +0000 Subject: libosmo-sccp[master]: sua.h: Define more IEIs; base definitions on m3ua.h In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2192 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I64c7166cf0b5c8a927ab7e14955100f8d13fe16a Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Mon Apr 3 15:59:30 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 3 Apr 2017 15:59:30 +0000 Subject: libosmo-sccp[master]: sua.h: Add #define for the varius SUA protocol errors In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2193 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Iec2563cb158b1c18064671564a7502b5c4d82517 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Mon Apr 3 15:59:37 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 3 Apr 2017 15:59:37 +0000 Subject: libosmo-sccp[master]: gitignore: add 'tags' files as created by 'make ctags' In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2194 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I9e4ec0e07b996092a1f4e6a01911dc0041111498 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Mon Apr 3 15:59:41 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 3 Apr 2017 15:59:41 +0000 Subject: libosmo-sccp[master]: gitignore: use one wildcard line for all test executables In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2195 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I53ce43fa8e09646dec56c6cc32b09c4618e9b5a5 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Mon Apr 3 16:00:04 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 3 Apr 2017 16:00:04 +0000 Subject: libosmo-sccp[master]: xua_msg: Add concept of xua_msg_class and xua_msg_dialect In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2197 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ib538aca295b7b50132bc814b2d7b56cbe5d65bfc Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Mon Apr 3 16:00:13 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 3 Apr 2017 16:00:13 +0000 Subject: libosmo-sccp[master]: sccp_sap: Use zero-terminated string for GT digits in osmo_s... In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2198 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I6312208cdfa83184be41157a473c96e9120c63db Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Mon Apr 3 16:00:18 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 3 Apr 2017 16:00:18 +0000 Subject: libosmo-sccp[master]: sccp_sap: Add routing indication (RI) to osmo_sccp_addr In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2199 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I4dd23150f4c588b6430c22fc0cb66635994ceea9 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Mon Apr 3 16:01:02 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 3 Apr 2017 16:01:02 +0000 Subject: libosmo-sccp[master]: xua_msg: Add support for encoding Global Title in osmo_sccp_... In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2201 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I4668fd0fba2e1be1ec37e75eeee85ed476320d14 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Mon Apr 3 16:01:07 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 3 Apr 2017 16:01:07 +0000 Subject: libosmo-sccp[master]: xua_msg: Add support for encoding IPv4 addr in osmo_sccp_addr In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2202 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I956f069ce4cea78cb0db0470265ca8365093c0e5 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Mon Apr 3 16:01:58 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 3 Apr 2017 16:01:58 +0000 Subject: libosmo-sccp[master]: License headers: Should always have been GPLv2-or-later In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2205 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I67dfd0ae6157afafd3873a3baaa4c6107c04ddfd Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Mon Apr 3 16:02:06 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 3 Apr 2017 16:02:06 +0000 Subject: libosmo-sccp[master]: sccp_sap: Add support for N-NOTICE.indication In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2200 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I6656889b4333e9909cf1c60c24dfc754281547b4 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Mon Apr 3 16:02:18 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 3 Apr 2017 16:02:18 +0000 Subject: libosmo-sccp[master]: Add mtp_sap.h file with definitions for MTP-USER SAP In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2203 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Id1f8892e5dee877e2ffbeb3925753ab3da5a9420 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Mon Apr 3 16:08:08 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 3 Apr 2017 16:08:08 +0000 Subject: libosmo-sccp[master]: xua_msg: Add MTP routing label to 'struct xua_msg' In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2204 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I31a6388ac999e02ad779619adb54bbf4040672c9 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Mon Apr 3 16:31:35 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Mon, 3 Apr 2017 16:31:35 +0000 Subject: [PATCH] openbsc[master]: Use libosmocore for SW Description parsing In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2166 to look at the new patch set (#3). Use libosmocore for SW Description parsing Requires libosmocore with Ib63b6b5e83b8914864fc7edd789f8958cdc993cd. Change-Id: Ib94db414e94a2a1f234ac6f1cb346dca1c7a8be3 --- M openbsc/include/openbsc/abis_nm.h M openbsc/src/ipaccess/ipaccess-config.c M openbsc/src/libbsc/abis_nm.c M openbsc/tests/abis/abis_test.c M openbsc/tests/abis/abis_test.ok 5 files changed, 68 insertions(+), 130 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/66/2166/3 diff --git a/openbsc/include/openbsc/abis_nm.h b/openbsc/include/openbsc/abis_nm.h index 2465452..9dcb91f 100644 --- a/openbsc/include/openbsc/abis_nm.h +++ b/openbsc/include/openbsc/abis_nm.h @@ -68,18 +68,6 @@ int (*sw_act_req)(struct msgb *); }; -struct abis_nm_sw_descr { - /* where does it start? how long is it? */ - const uint8_t *start; - size_t len; - - /* the parsed data */ - const uint8_t *file_id; - uint16_t file_id_len; - const uint8_t *file_ver; - uint16_t file_ver_len; -}; - extern int abis_nm_rcvmsg(struct msgb *msg); int abis_nm_tlv_parse(struct tlv_parsed *tp, struct gsm_bts *bts, const uint8_t *buf, int len); @@ -182,7 +170,7 @@ void abis_nm_queue_send_next(struct gsm_bts *bts); /* for bs11_config. */ int abis_nm_parse_sw_config(const uint8_t *data, const size_t len, - struct abis_nm_sw_descr *res, const int res_len); + struct abis_nm_sw_descr *res, const int res_len); int abis_nm_select_newest_sw(const struct abis_nm_sw_descr *sw, const size_t len); /* Helper functions for updating attributes */ diff --git a/openbsc/src/ipaccess/ipaccess-config.c b/openbsc/src/ipaccess/ipaccess-config.c index 0c3f888..ca5f195 100644 --- a/openbsc/src/ipaccess/ipaccess-config.c +++ b/openbsc/src/ipaccess/ipaccess-config.c @@ -52,6 +52,7 @@ #include #include #include +#include struct gsm_network *bsc_gsmnet; @@ -70,17 +71,9 @@ static int found_trx = 0; static int loop_tests = 0; -struct sw_load { - uint8_t file_id[255]; - uint8_t file_id_len; - - uint8_t file_version[255]; - uint8_t file_version_len; -}; - static void *tall_ctx_config = NULL; -static struct sw_load *sw_load1 = NULL; -static struct sw_load *sw_load2 = NULL; +static struct abis_nm_sw_descr *sw_load1 = NULL; +static struct abis_nm_sw_descr *sw_load2 = NULL; /* static uint8_t prim_oml_attr[] = { 0x95, 0x00, 7, 0x88, 192, 168, 100, 11, 0x00, 0x00 }; @@ -344,19 +337,11 @@ msg->l3h = &msg->l2h[3]; /* activate software */ - if (sw_load1) { - msgb_v_put(msg, NM_ATT_SW_DESCR); - msgb_tl16v_put(msg, NM_ATT_FILE_ID, sw_load1->file_id_len, sw_load1->file_id); - msgb_tl16v_put(msg, NM_ATT_FILE_VERSION, sw_load1->file_version_len, - sw_load1->file_version); - } + if (sw_load1) + abis_nm_put_sw_descr(msg, sw_load1, true); - if (sw_load2) { - msgb_v_put(msg, NM_ATT_SW_DESCR); - msgb_tl16v_put(msg, NM_ATT_FILE_ID, sw_load2->file_id_len, sw_load2->file_id); - msgb_tl16v_put(msg, NM_ATT_FILE_VERSION, sw_load2->file_version_len, - sw_load2->file_version); - } + if (sw_load2) + abis_nm_put_sw_descr(msg, sw_load2, true); /* fill in the data */ msg->l2h[0] = NM_ATT_IPACC_CUR_SW_CFG; @@ -618,11 +603,11 @@ return 0; } -static struct sw_load *create_swload(struct sdp_header *header) +static struct abis_nm_sw_descr *create_swload(struct sdp_header *header) { - struct sw_load *load; + struct abis_nm_sw_descr *load; - load = talloc_zero(tall_ctx_config, struct sw_load); + load = talloc_zero(tall_ctx_config, struct abis_nm_sw_descr); strncpy((char *)load->file_id, header->firmware_info.sw_part, 20); load->file_id_len = strlen(header->firmware_info.sw_part) + 1; diff --git a/openbsc/src/libbsc/abis_nm.c b/openbsc/src/libbsc/abis_nm.c index 33a23a2..944ece6 100644 --- a/openbsc/src/libbsc/abis_nm.c +++ b/openbsc/src/libbsc/abis_nm.c @@ -413,93 +413,46 @@ /* Activate the specified software into the BTS */ static int ipacc_sw_activate(struct gsm_bts *bts, uint8_t obj_class, uint8_t i0, uint8_t i1, - uint8_t i2, const uint8_t *sw_desc, uint8_t swdesc_len) + uint8_t i2, const struct abis_nm_sw_descr *sw_desc) { struct abis_om_hdr *oh; struct msgb *msg = nm_msgb_alloc(); - uint8_t len = swdesc_len; - uint8_t *trailer; + uint16_t len = abis_nm_sw_descr_len(sw_desc, true); oh = (struct abis_om_hdr *) msgb_put(msg, ABIS_OM_FOM_HDR_SIZE); fill_om_fom_hdr(oh, len, NM_MT_ACTIVATE_SW, obj_class, i0, i1, i2); - - trailer = msgb_put(msg, swdesc_len); - memcpy(trailer, sw_desc, swdesc_len); + abis_nm_put_sw_descr(msg, sw_desc, true); return abis_nm_sendmsg(bts, msg); } int abis_nm_parse_sw_config(const uint8_t *sw_descr, const size_t sw_descr_len, - struct abis_nm_sw_descr *desc, const int res_len) + struct abis_nm_sw_descr *desc, const int res_len) { - static const struct tlv_definition sw_descr_def = { - .def = { - [NM_ATT_FILE_ID] = { TLV_TYPE_TL16V, }, - [NM_ATT_FILE_VERSION] = { TLV_TYPE_TL16V, }, - }, - }; - - size_t pos = 0; - int desc_pos = 0; - - for (pos = 0; pos < sw_descr_len && desc_pos < res_len; ++desc_pos) { - uint8_t tag; - uint16_t tag_len; - const uint8_t *val; - int len; - + int desc_pos, rc; + printf("parsing till %d -- [%zu] :: %s\t", res_len, sw_descr_len, osmo_hexdump(sw_descr, sw_descr_len)); + for (desc_pos = 0; desc_pos < res_len; ++desc_pos) { memset(&desc[desc_pos], 0, sizeof(desc[desc_pos])); - desc[desc_pos].start = &sw_descr[pos]; - - /* Classic TLV parsing doesn't work well with SW_DESCR because of it's - * nested nature and the fact you have to assume it contains only two sub - * tags NM_ATT_FILE_VERSION & NM_ATT_FILE_ID to parse it */ - if (sw_descr[pos] != NM_ATT_SW_DESCR) { - LOGP(DNM, LOGL_ERROR, - "SW_DESCR attribute identifier not found!\n"); - return -1; - } - - pos += 1; - len = tlv_parse_one(&tag, &tag_len, &val, - &sw_descr_def, &sw_descr[pos], sw_descr_len - pos); - if (len < 0 || (tag != NM_ATT_FILE_ID)) { - LOGP(DNM, LOGL_ERROR, - "FILE_ID attribute identifier not found!\n"); - return -2; - } - desc[desc_pos].file_id = val; - desc[desc_pos].file_id_len = tag_len; - pos += len; - - - len = tlv_parse_one(&tag, &tag_len, &val, - &sw_descr_def, &sw_descr[pos], sw_descr_len - pos); - if (len < 0 || (tag != NM_ATT_FILE_VERSION)) { - LOGP(DNM, LOGL_ERROR, - "FILE_VERSION attribute identifier not found!\n"); - return -3; - } - desc[desc_pos].file_ver = val; - desc[desc_pos].file_ver_len = tag_len; - pos += len; - - /* final size */ - desc[desc_pos].len = &sw_descr[pos] - desc[desc_pos].start; + rc = abis_nm_get_sw_descr(&desc[desc_pos], sw_descr, + sw_descr_len); + if (rc < 0) + {printf("fail at pos %d with %d\n", desc_pos, -rc); + return -EINVAL;} } - +printf("OK at pos %d\n", desc_pos); return desc_pos; } int abis_nm_select_newest_sw(const struct abis_nm_sw_descr *sw_descr, - const size_t size) + const size_t size) { int res = 0; int i; for (i = 1; i < size; ++i) { - if (memcmp(sw_descr[res].file_ver, sw_descr[i].file_ver, - OSMO_MIN(sw_descr[i].file_ver_len, sw_descr[res].file_ver_len)) < 0) { + if (memcmp(sw_descr[res].file_version, sw_descr[i].file_version, + OSMO_MIN(sw_descr[i].file_version_len, + sw_descr[res].file_version_len)) < 0) { res = i; } } @@ -560,7 +513,7 @@ foh->obj_inst.bts_nr, foh->obj_inst.trx_nr, foh->obj_inst.ts_nr, - sw_descr[ret].start, sw_descr[ret].len); + &sw_descr[ret]); } /* Receive a CHANGE_ADM_STATE_ACK, parse the TLV and update local state */ diff --git a/openbsc/tests/abis/abis_test.c b/openbsc/tests/abis/abis_test.c index 496267f..94870f6 100644 --- a/openbsc/tests/abis/abis_test.c +++ b/openbsc/tests/abis/abis_test.c @@ -22,6 +22,7 @@ #include #include +#include #include #include @@ -51,23 +52,26 @@ static void test_simple_sw_config(void) { struct abis_nm_sw_descr descr[1]; + uint16_t len; int rc; rc = abis_nm_parse_sw_config(simple_config, ARRAY_SIZE(simple_config), &descr[0], ARRAY_SIZE(descr)); if (rc != 1) { - printf("FAILED to parse the File Id/File version\n"); + printf("%s(): FAILED to parse the File Id/File version: %d\n", + __func__, rc); abort(); } - if (descr[0].len != 13) { - printf("WRONG SIZE: %zu\n", descr[0].len); + len = abis_nm_sw_descr_len(&descr[0], true); + if (len != 13) { + printf("WRONG SIZE: %u\n", len); abort(); } - printf("Start: %td len: %zu\n", descr[0].start - simple_config, descr[0].len); + printf("len: %u\n", len); printf("file_id: %s\n", osmo_hexdump(descr[0].file_id, descr[0].file_id_len)); - printf("file_ver: %s\n", osmo_hexdump(descr[0].file_ver, descr[0].file_ver_len)); + printf("file_ver: %s\n", osmo_hexdump(descr[0].file_version, descr[0].file_version_len)); } static void test_simple_sw_short(void) @@ -89,53 +93,61 @@ static void test_dual_sw_config(void) { struct abis_nm_sw_descr descr[2]; + uint16_t len0, len1; int rc; rc = abis_nm_parse_sw_config(dual_config, ARRAY_SIZE(dual_config), &descr[0], ARRAY_SIZE(descr)); if (rc != 2) { - printf("FAILED to parse the File Id/File version\n"); - abort(); + printf("%s(): FAILED to parse the File Id/File version: %d\n", + __func__, rc); + //abort(); } - if (descr[0].len != 13) { - printf("WRONG SIZE0: %zu\n", descr[0].len); - abort(); + len0 = abis_nm_sw_descr_len(&descr[0], true); + if (len0 != 13) { + printf("WRONG SIZE0: %u\n", len0); + //abort(); } - if (descr[1].len != 13) { - printf("WRONG SIZE1: %zu\n", descr[1].len); - abort(); + len1 = abis_nm_sw_descr_len(&descr[1], true); + if (len1 != 13) { + printf("WRONG SIZE1: %u\n", len1); + //abort(); } - printf("Start: %td len: %zu\n", descr[0].start - dual_config, descr[0].len); + printf("len: %u\n", len0); printf("file_id: %s\n", osmo_hexdump(descr[0].file_id, descr[0].file_id_len)); - printf("file_ver: %s\n", osmo_hexdump(descr[0].file_ver, descr[0].file_ver_len)); + printf("file_ver: %s\n", osmo_hexdump(descr[0].file_version, descr[0].file_version_len)); - printf("Start: %td len: %zu\n", descr[1].start - dual_config, descr[1].len); + printf("len: %u\n", len1); printf("file_id: %s\n", osmo_hexdump(descr[1].file_id, descr[1].file_id_len)); - printf("file_ver: %s\n", osmo_hexdump(descr[1].file_ver, descr[1].file_ver_len)); + printf("file_ver: %s\n", osmo_hexdump(descr[1].file_version, descr[1].file_version_len)); } static void test_sw_selection(void) { struct abis_nm_sw_descr descr[8], tmp; + uint16_t len0, len1; int rc, pos; rc = abis_nm_parse_sw_config(load_config, ARRAY_SIZE(load_config), &descr[0], ARRAY_SIZE(descr)); if (rc != 2) { - printf("FAILED to parse the File Id/File version\n"); + printf("%s(): FAILED to parse the File Id/File version: %d\n", + __func__, rc); abort(); } - printf("Start: %td len: %zu\n", descr[0].start - load_config, descr[0].len); + len0 = abis_nm_sw_descr_len(&descr[0], true); + printf("len: %u\n", len0); printf("file_id: %s\n", osmo_hexdump(descr[0].file_id, descr[0].file_id_len)); - printf("file_ver: %s\n", osmo_hexdump(descr[0].file_ver, descr[0].file_ver_len)); + printf("file_ver: %s\n", osmo_hexdump(descr[0].file_version, descr[0].file_version_len)); - printf("Start: %td len: %zu\n", descr[1].start - load_config, descr[1].len); + len1 = abis_nm_sw_descr_len(&descr[1], true); + printf("len: %u\n", len1); printf("file_id: %s\n", osmo_hexdump(descr[1].file_id, descr[1].file_id_len)); - printf("file_ver: %s\n", osmo_hexdump(descr[1].file_ver, descr[1].file_ver_len)); + printf("file_ver: %s\n", osmo_hexdump(descr[1].file_version, descr[1].file_version_len)); /* start */ pos = abis_nm_select_newest_sw(descr, rc); diff --git a/openbsc/tests/abis/abis_test.ok b/openbsc/tests/abis/abis_test.ok index 2f99f9d..9cf77f3 100644 --- a/openbsc/tests/abis/abis_test.ok +++ b/openbsc/tests/abis/abis_test.ok @@ -1,16 +1,16 @@ -Start: 0 len: 13 +len: 13 file_id: 01 02 03 file_ver: 03 04 05 -Start: 0 len: 13 +len: 13 file_id: 01 02 03 file_ver: 03 04 05 -Start: 13 len: 13 +len: 13 file_id: 09 07 05 file_ver: 06 07 08 -Start: 0 len: 26 +len: 26 file_id: 31 36 38 64 34 37 32 00 file_ver: 76 32 30 30 62 31 34 33 64 30 00 -Start: 26 len: 26 +len: 26 file_id: 31 36 38 64 34 37 32 00 file_ver: 76 32 30 30 62 31 34 33 64 31 00 SELECTED: 1 -- To view, visit https://gerrit.osmocom.org/2166 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ib94db414e94a2a1f234ac6f1cb346dca1c7a8be3 Gerrit-PatchSet: 3 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Apr 3 16:33:52 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Mon, 3 Apr 2017 16:33:52 +0000 Subject: [PATCH] openbsc[master]: gsm_bts: add version and variant details In-Reply-To: References: Message-ID: Hello Neels Hofmeyr, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2161 to look at the new patch set (#5). gsm_bts: add version and variant details * add version string to gsm_bts * add PCU version string to gsm_bts * rename GSM_BTS_TYPE_OSMO_SYSMO -> GSM_BTS_OSMOBTS to avoid confusion between BTS model and variant * add variant enum to gsm_bts_model using eunm with variants for each hw vendor of OsmoBTS This will come in handy when logging details regarding particular BTS reported via OML, see: Related: OS#1614 Change-Id: I6710d53115f34634a7b70969cc05fd5c72ff8ab2 --- M openbsc/include/openbsc/gsm_data.h M openbsc/include/openbsc/gsm_data_shared.h M openbsc/src/libbsc/abis_nm.c M openbsc/src/libbsc/bsc_vty.c M openbsc/src/libbsc/bts_sysmobts.c M openbsc/src/libbsc/e1_config.c M openbsc/src/libbsc/system_information.c M openbsc/src/libcommon/gsm_data.c M openbsc/src/libmsc/gsm_04_08.c 9 files changed, 35 insertions(+), 18 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/61/2161/5 diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h index e9ba173..02d621d 100644 --- a/openbsc/include/openbsc/gsm_data.h +++ b/openbsc/include/openbsc/gsm_data.h @@ -470,7 +470,7 @@ { switch (bts->type) { case GSM_BTS_TYPE_NANOBTS: - case GSM_BTS_TYPE_OSMO_SYSMO: + case GSM_BTS_TYPE_OSMOBTS: return 1; default: break; @@ -481,7 +481,7 @@ static inline int is_sysmobts_v2(struct gsm_bts *bts) { switch (bts->type) { - case GSM_BTS_TYPE_OSMO_SYSMO: + case GSM_BTS_TYPE_OSMOBTS: return 1; default: break; diff --git a/openbsc/include/openbsc/gsm_data_shared.h b/openbsc/include/openbsc/gsm_data_shared.h index 06fa8dd..242889a 100644 --- a/openbsc/include/openbsc/gsm_data_shared.h +++ b/openbsc/include/openbsc/gsm_data_shared.h @@ -64,6 +64,8 @@ #define HARDCODED_BTS1_TS 6 #define HARDCODED_BTS2_TS 11 +#define MAX_VERSION_LENGTH 64 + enum gsm_hooks { GSM_HOOK_NM_SWLOAD, GSM_HOOK_RR_PAGING, @@ -489,8 +491,17 @@ GSM_BTS_TYPE_NANOBTS, GSM_BTS_TYPE_RBS2000, GSM_BTS_TYPE_NOKIA_SITE, - GSM_BTS_TYPE_OSMO_SYSMO, + GSM_BTS_TYPE_OSMOBTS, _NUM_GSM_BTS_TYPE +}; + +enum gsm_bts_type_variant { + BTS_UNKNOWN, + BTS_OSMO_LITECELL15, + BTS_OSMO_OCTPHY, + BTS_OSMO_SYSMO, + BTS_OSMO_TRX, + _NUM_BTS_VARIANT }; struct vty; @@ -499,6 +510,7 @@ struct llist_head list; enum gsm_bts_type type; + enum gsm_bts_type_variant variant; const char *name; bool started; @@ -653,6 +665,11 @@ enum gsm_bts_type type; struct gsm_bts_model *model; enum gsm_band band; + char version[MAX_VERSION_LENGTH]; + + /* Connected PCU version (if any) */ + char pcu_version[MAX_VERSION_LENGTH]; + /* maximum Tx power that the MS is permitted to use in this cell */ int ms_max_power; diff --git a/openbsc/src/libbsc/abis_nm.c b/openbsc/src/libbsc/abis_nm.c index 8b0eec2..394c427 100644 --- a/openbsc/src/libbsc/abis_nm.c +++ b/openbsc/src/libbsc/abis_nm.c @@ -661,7 +661,7 @@ switch (bts_type) { case GSM_BTS_TYPE_NANOBTS: - case GSM_BTS_TYPE_OSMO_SYSMO: + case GSM_BTS_TYPE_OSMOBTS: rc = abis_nm_rx_ipacc(mb); abis_nm_queue_send_next(sign_link->trx->bts); break; @@ -1646,7 +1646,7 @@ } *reason = "Unknown combination"; return -EINVAL; - case GSM_BTS_TYPE_OSMO_SYSMO: + case GSM_BTS_TYPE_OSMOBTS: /* no known restrictions */ return 0; default: diff --git a/openbsc/src/libbsc/bsc_vty.c b/openbsc/src/libbsc/bsc_vty.c index b1747aa..614f0a4 100644 --- a/openbsc/src/libbsc/bsc_vty.c +++ b/openbsc/src/libbsc/bsc_vty.c @@ -649,7 +649,7 @@ bts->early_classmark_allowed ? "allowed" : "forbidden", VTY_NEWLINE); switch (bts->type) { case GSM_BTS_TYPE_NANOBTS: - case GSM_BTS_TYPE_OSMO_SYSMO: + case GSM_BTS_TYPE_OSMOBTS: vty_out(vty, " ip.access unit_id %u %u%s", bts->ip_access.site_id, bts->ip_access.bts_id, VTY_NEWLINE); if (bts->ip_access.rsl_ip) { diff --git a/openbsc/src/libbsc/bts_sysmobts.c b/openbsc/src/libbsc/bts_sysmobts.c index e1bf661..e4b6cdc 100644 --- a/openbsc/src/libbsc/bts_sysmobts.c +++ b/openbsc/src/libbsc/bts_sysmobts.c @@ -46,7 +46,7 @@ { model_sysmobts = bts_model_nanobts; model_sysmobts.name = "sysmobts"; - model_sysmobts.type = GSM_BTS_TYPE_OSMO_SYSMO; + model_sysmobts.type = GSM_BTS_TYPE_OSMOBTS; model_sysmobts.features.data = &model_sysmobts._features_data[0]; model_sysmobts.features.data_len = diff --git a/openbsc/src/libbsc/e1_config.c b/openbsc/src/libbsc/e1_config.c index 8910d21..d57dec5 100644 --- a/openbsc/src/libbsc/e1_config.c +++ b/openbsc/src/libbsc/e1_config.c @@ -179,7 +179,7 @@ /* skip signal link initialization, this is done later for these BTS. */ if (bts->type == GSM_BTS_TYPE_NANOBTS || - bts->type == GSM_BTS_TYPE_OSMO_SYSMO) + bts->type == GSM_BTS_TYPE_OSMOBTS) return e1inp_line_update(line); /* OML link */ diff --git a/openbsc/src/libbsc/system_information.c b/openbsc/src/libbsc/system_information.c index a2dd827..2610331 100644 --- a/openbsc/src/libbsc/system_information.c +++ b/openbsc/src/libbsc/system_information.c @@ -830,7 +830,7 @@ /* ip.access nanoBTS needs l2_plen!! */ switch (bts->type) { case GSM_BTS_TYPE_NANOBTS: - case GSM_BTS_TYPE_OSMO_SYSMO: + case GSM_BTS_TYPE_OSMOBTS: *output++ = GSM48_LEN2PLEN(l2_plen); l2_plen++; break; @@ -865,7 +865,7 @@ /* ip.access nanoBTS needs l2_plen!! */ switch (bts->type) { case GSM_BTS_TYPE_NANOBTS: - case GSM_BTS_TYPE_OSMO_SYSMO: + case GSM_BTS_TYPE_OSMOBTS: *output++ = GSM48_LEN2PLEN(l2_plen); l2_plen++; break; @@ -909,7 +909,7 @@ /* ip.access nanoBTS needs l2_plen!! */ switch (bts->type) { case GSM_BTS_TYPE_NANOBTS: - case GSM_BTS_TYPE_OSMO_SYSMO: + case GSM_BTS_TYPE_OSMOBTS: *output++ = GSM48_LEN2PLEN(l2_plen); l2_plen++; break; @@ -946,7 +946,7 @@ /* ip.access nanoBTS needs l2_plen!! */ switch (bts->type) { case GSM_BTS_TYPE_NANOBTS: - case GSM_BTS_TYPE_OSMO_SYSMO: + case GSM_BTS_TYPE_OSMOBTS: *output++ = GSM48_LEN2PLEN(l2_plen); l2_plen++; break; diff --git a/openbsc/src/libcommon/gsm_data.c b/openbsc/src/libcommon/gsm_data.c index 3e12430..fd34793 100644 --- a/openbsc/src/libcommon/gsm_data.c +++ b/openbsc/src/libcommon/gsm_data.c @@ -96,7 +96,7 @@ { GSM_BTS_TYPE_NANOBTS, "nanobts" }, { GSM_BTS_TYPE_RBS2000, "rbs2000" }, { GSM_BTS_TYPE_NOKIA_SITE, "nokia_site" }, - { GSM_BTS_TYPE_OSMO_SYSMO, "sysmobts" }, + { GSM_BTS_TYPE_OSMOBTS, "sysmobts" }, { 0, NULL } }; @@ -106,7 +106,7 @@ { GSM_BTS_TYPE_NANOBTS, "ip.access nanoBTS or compatible" }, { GSM_BTS_TYPE_RBS2000, "Ericsson RBS2000 Series" }, { GSM_BTS_TYPE_NOKIA_SITE, "Nokia {Metro,Ultra,In}Site" }, - { GSM_BTS_TYPE_OSMO_SYSMO, "sysmocom sysmoBTS" }, + { GSM_BTS_TYPE_OSMOBTS, "sysmocom sysmoBTS" }, { 0, NULL } }; @@ -274,7 +274,7 @@ switch (bts->type) { case GSM_BTS_TYPE_NANOBTS: - case GSM_BTS_TYPE_OSMO_SYSMO: + case GSM_BTS_TYPE_OSMOBTS: /* Set the default OML Stream ID to 0xff */ bts->oml_tei = 0xff; bts->c0->nominal_power = 23; diff --git a/openbsc/src/libmsc/gsm_04_08.c b/openbsc/src/libmsc/gsm_04_08.c index c910d71..ee4e561 100644 --- a/openbsc/src/libmsc/gsm_04_08.c +++ b/openbsc/src/libmsc/gsm_04_08.c @@ -1944,7 +1944,7 @@ // todo: map between different bts types switch (bts->type) { case GSM_BTS_TYPE_NANOBTS: - case GSM_BTS_TYPE_OSMO_SYSMO: + case GSM_BTS_TYPE_OSMOBTS: if (!ipacc_rtp_direct) { if (!lchan->abis_ip.rtp_socket) { LOGP(DHO, LOGL_ERROR, "no RTP socket for " @@ -2035,7 +2035,7 @@ switch (bts->type) { case GSM_BTS_TYPE_NANOBTS: - case GSM_BTS_TYPE_OSMO_SYSMO: + case GSM_BTS_TYPE_OSMOBTS: if (ipacc_rtp_direct) { LOGP(DCC, LOGL_ERROR, "Error: RTP proxy is disabled\n"); return -EINVAL; @@ -3615,7 +3615,7 @@ bts = trans->conn->lchan->ts->trx->bts; switch (bts->type) { case GSM_BTS_TYPE_NANOBTS: - case GSM_BTS_TYPE_OSMO_SYSMO: + case GSM_BTS_TYPE_OSMOBTS: if (!trans->conn->lchan->abis_ip.rtp_socket) { DEBUGP(DMNCC, "TCH frame to lchan without RTP connection\n"); return 0; -- To view, visit https://gerrit.osmocom.org/2161 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I6710d53115f34634a7b70969cc05fd5c72ff8ab2 Gerrit-PatchSet: 5 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Mon Apr 3 16:38:06 2017 From: gerrit-no-reply at lists.osmocom.org (Vadim Yanitskiy) Date: Mon, 3 Apr 2017 16:38:06 +0000 Subject: [MERGED] openbsc[master]: VTY: add the dyn_ts_allow_tch_f option In-Reply-To: References: Message-ID: Vadim Yanitskiy has submitted this change and it was merged. Change subject: VTY: add the dyn_ts_allow_tch_f option ...................................................................... VTY: add the dyn_ts_allow_tch_f option This option allows to enable or disable TCH/F allocation on the TCH/F_TCH/H_PDCH timeslots. Until now, source code modification was required to enable this feature. Related: OS#1778 Change-Id: Id18cab25844dc854a66b4e2713e90c3f43afa712 --- M openbsc/include/openbsc/gsm_data.h M openbsc/src/libbsc/bsc_vty.c M openbsc/src/libcommon-cs/common_cs_vty.c M openbsc/src/osmo-nitb/bsc_hack.c 4 files changed, 29 insertions(+), 14 deletions(-) Approvals: Neels Hofmeyr: Looks good to me, approved Jenkins Builder: Verified diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h index 17cc804..08e07d8 100644 --- a/openbsc/include/openbsc/gsm_data.h +++ b/openbsc/include/openbsc/gsm_data.h @@ -384,7 +384,6 @@ /* Allow or disallow TCH/F on dynamic TCH/F_TCH/H_PDCH; OS#1778 */ bool dyn_ts_allow_tch_f; - /* TODO: vty for this; related: OS#1781 */ /* all active subscriber connections. */ struct llist_head subscr_conns; diff --git a/openbsc/src/libbsc/bsc_vty.c b/openbsc/src/libbsc/bsc_vty.c index b1747aa..66b30cd 100644 --- a/openbsc/src/libbsc/bsc_vty.c +++ b/openbsc/src/libbsc/bsc_vty.c @@ -821,6 +821,8 @@ vty_out(vty, " timer t3119 %u%s", gsmnet->T3119, VTY_NEWLINE); vty_out(vty, " timer t3122 %u%s", gsmnet->T3122, VTY_NEWLINE); vty_out(vty, " timer t3141 %u%s", gsmnet->T3141, VTY_NEWLINE); + vty_out(vty, " dyn_ts_allow_tch_f %d%s", + gsmnet->dyn_ts_allow_tch_f ? 1 : 0, VTY_NEWLINE); vty_out(vty, " subscriber-keep-in-ram %d%s", gsmnet->subscr_group->keep_subscr, VTY_NEWLINE); if (gsmnet->tz.override != 0) { diff --git a/openbsc/src/libcommon-cs/common_cs_vty.c b/openbsc/src/libcommon-cs/common_cs_vty.c index 08a7581..76336a1 100644 --- a/openbsc/src/libcommon-cs/common_cs_vty.c +++ b/openbsc/src/libcommon-cs/common_cs_vty.c @@ -197,6 +197,18 @@ return CMD_SUCCESS; } +DEFUN(cfg_net_dyn_ts_allow_tch_f, + cfg_net_dyn_ts_allow_tch_f_cmd, + "dyn_ts_allow_tch_f (0|1)", + "Allow or disallow allocating TCH/F on TCH_F_TCH_H_PDCH timeslots\n" + "Disallow TCH/F on TCH_F_TCH_H_PDCH (default)\n" + "Allow TCH/F on TCH_F_TCH_H_PDCH\n") +{ + struct gsm_network *gsmnet = gsmnet_from_vty(vty); + gsmnet->dyn_ts_allow_tch_f = atoi(argv[0]) ? true : false; + return CMD_SUCCESS; +} + DEFUN(cfg_net_subscr_keep, cfg_net_subscr_keep_cmd, "subscriber-keep-in-ram (0|1)", @@ -295,6 +307,7 @@ install_element(GSMNET_NODE, &cfg_net_timezone_cmd); install_element(GSMNET_NODE, &cfg_net_timezone_dst_cmd); install_element(GSMNET_NODE, &cfg_net_no_timezone_cmd); + install_element(GSMNET_NODE, &cfg_net_dyn_ts_allow_tch_f_cmd); return CMD_SUCCESS; } diff --git a/openbsc/src/osmo-nitb/bsc_hack.c b/openbsc/src/osmo-nitb/bsc_hack.c index dd90b8b..d8029cd 100644 --- a/openbsc/src/osmo-nitb/bsc_hack.c +++ b/openbsc/src/osmo-nitb/bsc_hack.c @@ -301,6 +301,20 @@ } else DEBUGP(DMNCC, "Using internal MNCC handler.\n"); + /* + * For osmo-nitb, skip TCH/F for now, because otherwise dyn TS + * always imply the possibility to have a mix of TCH/F and + * TCH/H channels; if two phones request a TCH/F and a TCH/H, + * respectively, they cannot call each other. If we deny TCH/F, + * they will both fall back to TCH/H, and dynamic channels are + * usable. See OS#1778. + * + * A third-party MSC may well be able to handle a TCH/H TCH/F + * mismatch. Moreover, this option may be overwritten in the + * config file or in VTY. + */ + bsc_gsmnet->dyn_ts_allow_tch_f = false; + /* Read the config */ rc = bsc_network_configure(config_file); if (rc < 0) { @@ -312,19 +326,6 @@ smpp_openbsc_start(bsc_gsmnet); #endif bsc_api_init(bsc_gsmnet, msc_bsc_api()); - - /* - * For osmo-nitb, skip TCH/F for now, because otherwise dyn TS - * always imply the possibility to have a mix of TCH/F and - * TCH/H channels; if two phones request a TCH/F and a TCH/H, - * respectively, they cannot call each other. If we deny TCH/F, - * they will both fall back to TCH/H, and dynamic channels are - * usable. See http://osmocom.org/issues/1778. - * - * A third-party MSC may well be able to handle a TCH/H TCH/F - * mismatch. - */ - bsc_gsmnet->dyn_ts_allow_tch_f = false; /* start control interface after reading config for * ctrl_vty_get_bind_addr() */ -- To view, visit https://gerrit.osmocom.org/2190 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Id18cab25844dc854a66b4e2713e90c3f43afa712 Gerrit-PatchSet: 3 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Vadim Yanitskiy Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: Vadim Yanitskiy From gerrit-no-reply at lists.osmocom.org Mon Apr 3 16:40:32 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Mon, 3 Apr 2017 16:40:32 +0000 Subject: [PATCH] osmo-bts[master]: Handle TXT indication from OsmoPCU In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2087 to look at the new patch set (#2). Handle TXT indication from OsmoPCU * handle OML message * handle OsmoPCU version message Requires OpenBSc with I6710d53115f34634a7b70969cc05fd5c72ff8ab2. Change-Id: I16e73198501487a5b1076bf83390b85538d5af73 Related: OS#1614, 1615 --- M src/common/pcu_sock.c M src/common/vty.c 2 files changed, 27 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/87/2087/2 diff --git a/src/common/pcu_sock.c b/src/common/pcu_sock.c index 85bc880..f5732ff 100644 --- a/src/common/pcu_sock.c +++ b/src/common/pcu_sock.c @@ -538,6 +538,27 @@ return rc; } +static int pcu_rx_txt_ind(struct gsm_bts *bts, + struct gsm_pcu_if_txt_ind *txt) +{ + switch (txt->type) { + case PCU_VERSION: + LOGP(DPCU, LOGL_INFO, "OsmoPCU version %s connected\n", + txt->text); + osmo_signal_dispatch(SS_FAIL, OSMO_EVT_PCU_VERS, txt->text); + break; + case PCU_OML_ALERT: + osmo_signal_dispatch(SS_FAIL, OSMO_EVT_EXT_ALARM, txt->text); + break; + default: + LOGP(DPCU, LOGL_ERROR, "Unknown TXT_IND type %u received\n", + txt->type); + return -EINVAL; + } + + return 0; +} + static int pcu_rx_act_req(struct gsm_bts *bts, struct gsm_pcu_if_act_req *act_req) { @@ -586,6 +607,9 @@ case PCU_IF_MSG_ACT_REQ: rc = pcu_rx_act_req(bts, &pcu_prim->u.act_req); break; + case PCU_IF_MSG_TXT_IND: + rc = pcu_rx_txt_ind(bts, &pcu_prim->u.txt_ind); + break; default: LOGP(DPCU, LOGL_ERROR, "Received unknwon PCU msg type %d\n", msg_type); diff --git a/src/common/vty.c b/src/common/vty.c index 3f736c9..a48f809 100644 --- a/src/common/vty.c +++ b/src/common/vty.c @@ -744,6 +744,9 @@ net_dump_nmstate(vty, &bts->mo.nm_state); vty_out(vty, " Site Mgr NM State: "); net_dump_nmstate(vty, &bts->site_mgr.mo.nm_state); + if (strnlen(bts->pcu_version, MAX_VERSION_LENGTH)) + vty_out(vty, " PCU version %s connected%s", + bts->pcu_version, VTY_NEWLINE); vty_out(vty, " Paging: Queue size %u, occupied %u, lifetime %us%s", paging_get_queue_max(btsb->paging_state), paging_queue_length(btsb->paging_state), paging_get_lifetime(btsb->paging_state), VTY_NEWLINE); -- To view, visit https://gerrit.osmocom.org/2087 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I16e73198501487a5b1076bf83390b85538d5af73 Gerrit-PatchSet: 2 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max From gerrit-no-reply at lists.osmocom.org Mon Apr 3 16:46:19 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Mon, 3 Apr 2017 16:46:19 +0000 Subject: [PATCH] osmo-bts[master]: Handle TXT indication from OsmoPCU In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2087 to look at the new patch set (#3). Handle TXT indication from OsmoPCU * handle OML message * handle OsmoPCU version message * show stored PCU version in 'show bts ..' vty command Requires OpenBSc with I6710d53115f34634a7b70969cc05fd5c72ff8ab2. Change-Id: I16e73198501487a5b1076bf83390b85538d5af73 Related: OS#1614, 1615 --- M src/common/pcu_sock.c M src/common/vty.c 2 files changed, 28 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/87/2087/3 diff --git a/src/common/pcu_sock.c b/src/common/pcu_sock.c index 85bc880..fa2c585 100644 --- a/src/common/pcu_sock.c +++ b/src/common/pcu_sock.c @@ -538,6 +538,28 @@ return rc; } +static int pcu_rx_txt_ind(struct gsm_bts *bts, + struct gsm_pcu_if_txt_ind *txt) +{ + switch (txt->type) { + case PCU_VERSION: + LOGP(DPCU, LOGL_INFO, "OsmoPCU version %s connected\n", + txt->text); + osmo_signal_dispatch(SS_FAIL, OSMO_EVT_PCU_VERS, txt->text); + osmo_strlcpy(bts->pcu_version, txt->text, MAX_VERSION_LENGTH); + break; + case PCU_OML_ALERT: + osmo_signal_dispatch(SS_FAIL, OSMO_EVT_EXT_ALARM, txt->text); + break; + default: + LOGP(DPCU, LOGL_ERROR, "Unknown TXT_IND type %u received\n", + txt->type); + return -EINVAL; + } + + return 0; +} + static int pcu_rx_act_req(struct gsm_bts *bts, struct gsm_pcu_if_act_req *act_req) { @@ -586,6 +608,9 @@ case PCU_IF_MSG_ACT_REQ: rc = pcu_rx_act_req(bts, &pcu_prim->u.act_req); break; + case PCU_IF_MSG_TXT_IND: + rc = pcu_rx_txt_ind(bts, &pcu_prim->u.txt_ind); + break; default: LOGP(DPCU, LOGL_ERROR, "Received unknwon PCU msg type %d\n", msg_type); diff --git a/src/common/vty.c b/src/common/vty.c index 3f736c9..a48f809 100644 --- a/src/common/vty.c +++ b/src/common/vty.c @@ -744,6 +744,9 @@ net_dump_nmstate(vty, &bts->mo.nm_state); vty_out(vty, " Site Mgr NM State: "); net_dump_nmstate(vty, &bts->site_mgr.mo.nm_state); + if (strnlen(bts->pcu_version, MAX_VERSION_LENGTH)) + vty_out(vty, " PCU version %s connected%s", + bts->pcu_version, VTY_NEWLINE); vty_out(vty, " Paging: Queue size %u, occupied %u, lifetime %us%s", paging_get_queue_max(btsb->paging_state), paging_queue_length(btsb->paging_state), paging_get_lifetime(btsb->paging_state), VTY_NEWLINE); -- To view, visit https://gerrit.osmocom.org/2087 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I16e73198501487a5b1076bf83390b85538d5af73 Gerrit-PatchSet: 3 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max From gerrit-no-reply at lists.osmocom.org Mon Apr 3 17:38:56 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 3 Apr 2017 17:38:56 +0000 Subject: [PATCH] libosmocore[master]: logging.h: #define DLSS7, DLSCCP, DLSUA, DLM3UA for libosmo-... Message-ID: Review at https://gerrit.osmocom.org/2206 logging.h: #define DLSS7, DLSCCP, DLSUA, DLM3UA for libosmo-sigtran Change-Id: I61f452208088dc7097165deecef7c058ebb4bd4e --- M include/osmocom/core/logging.h 1 file changed, 5 insertions(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/06/2206/1 diff --git a/include/osmocom/core/logging.h b/include/osmocom/core/logging.h index 7b28b2c..41a5d77 100644 --- a/include/osmocom/core/logging.h +++ b/include/osmocom/core/logging.h @@ -102,7 +102,11 @@ #define DLSTATS -10 /*!< Statistics */ #define DLGSUP -11 /*!< Generic Subscriber Update Protocol */ #define DLOAP -12 /*!< Osmocom Authentication Protocol */ -#define OSMO_NUM_DLIB 12 /*!< Number of logging sub-systems in libraries */ +#define DLSS7 -13 /*!< Osmocom SS7 */ +#define DLSCCP -14 /*!< Osmocom SCCP */ +#define DLSUA -15 /*!< Osmocom SUA */ +#define DLM3UA -16 /*!< Osmocom M3UA */ +#define OSMO_NUM_DLIB 16 /*!< Number of logging sub-systems in libraries */ /*! Configuration of singgle log category / sub-system */ struct log_category { -- To view, visit https://gerrit.osmocom.org/2206 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I61f452208088dc7097165deecef7c058ebb4bd4e Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Mon Apr 3 18:06:48 2017 From: gerrit-no-reply at lists.osmocom.org (Tom Tsou) Date: Mon, 3 Apr 2017 18:06:48 +0000 Subject: [MERGED] osmo-trx[master]: Transceiver: Remove unsigned negative compares In-Reply-To: References: Message-ID: Tom Tsou has submitted this change and it was merged. Change subject: Transceiver: Remove unsigned negative compares ...................................................................... Transceiver: Remove unsigned negative compares Change-Id: I49f30699786c52736ef334dae61f7bbd65d878d5 Fixes: Coverity CID 149353, 149356 --- M Transceiver52M/Transceiver.cpp M Transceiver52M/osmo-trx.cpp 2 files changed, 3 insertions(+), 3 deletions(-) Approvals: Tom Tsou: Looks good to me, approved Jenkins Builder: Verified diff --git a/Transceiver52M/Transceiver.cpp b/Transceiver52M/Transceiver.cpp index 4616fea..66eff7f 100644 --- a/Transceiver52M/Transceiver.cpp +++ b/Transceiver52M/Transceiver.cpp @@ -788,9 +788,9 @@ // set TSC unsigned TSC; sscanf(buffer, "%3s %s %d", cmdcheck, command, &TSC); - if ((TSC < 0) || (TSC > 7)) + if (TSC > 7) { sprintf(response, "RSP SETTSC 1 %d", TSC); - else { + } else { LOG(NOTICE) << "Changing TSC from " << mTSC << " to " << TSC; mTSC = TSC; sprintf(response,"RSP SETTSC 0 %d", TSC); diff --git a/Transceiver52M/osmo-trx.cpp b/Transceiver52M/osmo-trx.cpp index 5e81586..b36c081 100644 --- a/Transceiver52M/osmo-trx.cpp +++ b/Transceiver52M/osmo-trx.cpp @@ -168,7 +168,7 @@ if (!config->chans) config->chans = DEFAULT_CHANS; - if (config->mcbts && ((config->chans < 0) || (config->chans > 5))) { + if (config->mcbts && config->chans > 5) { std::cout << "Unsupported number of channels" << std::endl; return false; } -- To view, visit https://gerrit.osmocom.org/2188 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I49f30699786c52736ef334dae61f7bbd65d878d5 Gerrit-PatchSet: 3 Gerrit-Project: osmo-trx Gerrit-Branch: master Gerrit-Owner: Tom Tsou Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Tom Tsou From gerrit-no-reply at lists.osmocom.org Mon Apr 3 18:06:49 2017 From: gerrit-no-reply at lists.osmocom.org (Tom Tsou) Date: Mon, 3 Apr 2017 18:06:49 +0000 Subject: [MERGED] osmo-trx[master]: Resampler: Fix non-array delete for filter taps In-Reply-To: References: Message-ID: Tom Tsou has submitted this change and it was merged. Change subject: Resampler: Fix non-array delete for filter taps ...................................................................... Resampler: Fix non-array delete for filter taps Change-Id: I59cdb01809da5940c74aaae9d17f413aefbf04b2 Fixes: Coverity CID 149349 --- M Transceiver52M/Resampler.cpp 1 file changed, 1 insertion(+), 1 deletion(-) Approvals: Tom Tsou: Looks good to me, approved Jenkins Builder: Verified diff --git a/Transceiver52M/Resampler.cpp b/Transceiver52M/Resampler.cpp index 72b11a9..1927e45 100644 --- a/Transceiver52M/Resampler.cpp +++ b/Transceiver52M/Resampler.cpp @@ -112,7 +112,7 @@ } } - delete proto; + delete[] proto; return true; } -- To view, visit https://gerrit.osmocom.org/2187 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I59cdb01809da5940c74aaae9d17f413aefbf04b2 Gerrit-PatchSet: 2 Gerrit-Project: osmo-trx Gerrit-Branch: master Gerrit-Owner: Tom Tsou Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Tom Tsou From gerrit-no-reply at lists.osmocom.org Mon Apr 3 18:13:50 2017 From: gerrit-no-reply at lists.osmocom.org (Tom Tsou) Date: Mon, 3 Apr 2017 18:13:50 +0000 Subject: osmo-trx[master]: config: Remove OpenBTS style sqlite configuration In-Reply-To: References: Message-ID: Patch Set 3: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2185 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I95d7b771fde976818bee76f89163e72c3a44ecdd Gerrit-PatchSet: 3 Gerrit-Project: osmo-trx Gerrit-Branch: master Gerrit-Owner: Tom Tsou Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Tom Tsou Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Mon Apr 3 20:04:05 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 3 Apr 2017 20:04:05 +0000 Subject: libosmocore[master]: logging.h: #define DLSS7, DLSCCP, DLSUA, DLM3UA for libosmo-... In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2206 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I61f452208088dc7097165deecef7c058ebb4bd4e Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Mon Apr 3 20:04:08 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 3 Apr 2017 20:04:08 +0000 Subject: [MERGED] libosmocore[master]: logging.h: #define DLSS7, DLSCCP, DLSUA, DLM3UA for libosmo-... In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: logging.h: #define DLSS7, DLSCCP, DLSUA, DLM3UA for libosmo-sigtran ...................................................................... logging.h: #define DLSS7, DLSCCP, DLSUA, DLM3UA for libosmo-sigtran Change-Id: I61f452208088dc7097165deecef7c058ebb4bd4e --- M include/osmocom/core/logging.h 1 file changed, 5 insertions(+), 1 deletion(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/include/osmocom/core/logging.h b/include/osmocom/core/logging.h index 7b28b2c..41a5d77 100644 --- a/include/osmocom/core/logging.h +++ b/include/osmocom/core/logging.h @@ -102,7 +102,11 @@ #define DLSTATS -10 /*!< Statistics */ #define DLGSUP -11 /*!< Generic Subscriber Update Protocol */ #define DLOAP -12 /*!< Osmocom Authentication Protocol */ -#define OSMO_NUM_DLIB 12 /*!< Number of logging sub-systems in libraries */ +#define DLSS7 -13 /*!< Osmocom SS7 */ +#define DLSCCP -14 /*!< Osmocom SCCP */ +#define DLSUA -15 /*!< Osmocom SUA */ +#define DLM3UA -16 /*!< Osmocom M3UA */ +#define OSMO_NUM_DLIB 16 /*!< Number of logging sub-systems in libraries */ /*! Configuration of singgle log category / sub-system */ struct log_category { -- To view, visit https://gerrit.osmocom.org/2206 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I61f452208088dc7097165deecef7c058ebb4bd4e Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Apr 3 20:21:38 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 3 Apr 2017 20:21:38 +0000 Subject: [PATCH] libosmocore[master]: logging: Add log_info_cat for DLSS7/DLSCCP/DLSUA/DLM3UA Message-ID: Review at https://gerrit.osmocom.org/2207 logging: Add log_info_cat for DLSS7/DLSCCP/DLSUA/DLM3UA In Change-Id I61f452208088dc7097165deecef7c058ebb4bd4e we introduced the #defines but didn't introduce the new log_info_cat information. Change-Id: I218aa4cb1fc7640a75663be29bac672dfa8770f5 --- M src/logging.c 1 file changed, 20 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/07/2207/1 diff --git a/src/logging.c b/src/logging.c index d900340..05d6b6d 100644 --- a/src/logging.c +++ b/src/logging.c @@ -140,6 +140,26 @@ .description = "Osmocom Authentication Protocol", .enabled = 1, .loglevel = LOGL_NOTICE, }, + [INT2IDX(DLSS7)] = { + .name = "DLSS7", + .description = "libosmo-sigtran Signalling System 7", + .enabled = 1, .loglevel = LOGL_NOTICE, + }, + [INT2IDX(DLSCCP)] = { + .name = "DLSCCP", + .description = "libosmo-sigtran SCCP Implementation", + .enabled = 1, .loglevel = LOGL_NOTICE, + }, + [INT2IDX(DLSUA)] = { + .name = "DLSUA", + .description = "libosmo-sigtran SCCP User Adaptation", + .enabled = 1, .loglevel = LOGL_NOTICE, + }, + [INT2IDX(DLM3UA)] = { + .name = "DLM3UA", + .description = "libosmo-sigtran MTP3 User Adaptation", + .enabled = 1, .loglevel = LOGL_NOTICE, + }, }; /*! \brief descriptive string for each log level */ -- To view, visit https://gerrit.osmocom.org/2207 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I218aa4cb1fc7640a75663be29bac672dfa8770f5 Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Mon Apr 3 20:22:07 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 3 Apr 2017 20:22:07 +0000 Subject: [PATCH] libosmo-sccp[master]: xua_msg: Add xua_msg_free_tag() and xua_msg_copy_part() In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2196 to look at the new patch set (#2). xua_msg: Add xua_msg_free_tag() and xua_msg_copy_part() ... also, mark input to xua_msg_find_tag as 'const' pointer. Change-Id: I083634db9c3606bcff87700f253054a38a20816d --- M include/osmocom/sigtran/xua_msg.h M src/xua_msg.c 2 files changed, 31 insertions(+), 2 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/96/2196/2 diff --git a/include/osmocom/sigtran/xua_msg.h b/include/osmocom/sigtran/xua_msg.h index 2a6e3ae..23f92c5 100644 --- a/include/osmocom/sigtran/xua_msg.h +++ b/include/osmocom/sigtran/xua_msg.h @@ -50,7 +50,10 @@ int xua_msg_add_data(struct xua_msg *msg, uint16_t tag, uint16_t len, uint8_t *dat); -struct xua_msg_part *xua_msg_find_tag(struct xua_msg *msg, uint16_t tag); +struct xua_msg_part *xua_msg_find_tag(const struct xua_msg *msg, uint16_t tag); +int xua_msg_free_tag(struct xua_msg *xua, uint16_t tag); +int xua_msg_copy_part(struct xua_msg *xua_out, uint16_t tag_out, + const struct xua_msg *xua_in, uint16_t tag_in); struct xua_msg *xua_from_msg(const int version, uint16_t len, uint8_t *data); struct msgb *xua_to_msg(const int version, struct xua_msg *msg); diff --git a/src/xua_msg.c b/src/xua_msg.c index 4a3e013..71511a9 100644 --- a/src/xua_msg.c +++ b/src/xua_msg.c @@ -77,7 +77,7 @@ return 0; } -struct xua_msg_part *xua_msg_find_tag(struct xua_msg *xua, uint16_t tag) +struct xua_msg_part *xua_msg_find_tag(const struct xua_msg *xua, uint16_t tag) { struct xua_msg_part *part; @@ -88,6 +88,32 @@ return NULL; } +int xua_msg_free_tag(struct xua_msg *xua, uint16_t tag) +{ + struct xua_msg_part *part; + + llist_for_each_entry(part, &xua->headers, entry) { + if (part->tag == tag) { + llist_del(&part->entry); + talloc_free(part); + return 1; + } + } + return 0; +} + +int xua_msg_copy_part(struct xua_msg *xua_out, uint16_t tag_out, + const struct xua_msg *xua_in, uint16_t tag_in) +{ + const struct xua_msg_part *part; + + part = xua_msg_find_tag(xua_in, tag_in); + if (!part) + return -1; + + return xua_msg_add_data(xua_out, tag_out, part->len, part->dat); +} + struct xua_msg *xua_from_msg(const int version, uint16_t len, uint8_t *data) { struct xua_parameter_hdr *par; -- To view, visit https://gerrit.osmocom.org/2196 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I083634db9c3606bcff87700f253054a38a20816d Gerrit-PatchSet: 2 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Apr 3 20:22:07 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 3 Apr 2017 20:22:07 +0000 Subject: [PATCH] libosmo-sccp[master]: xua_msg: Add support for msg_event_maps Message-ID: Review at https://gerrit.osmocom.org/2208 xua_msg: Add support for msg_event_maps msg_event_maps facilitate the mapping from a xUA message (class + type) to an integer event. This is useful when passing xUA messages to a osmo_fsm. Change-Id: Iee1c7fc2bf64219ebb71a0dbe6fd210749332413 --- M include/osmocom/sigtran/xua_msg.h M src/xua_msg.c 2 files changed, 30 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/08/2208/1 diff --git a/include/osmocom/sigtran/xua_msg.h b/include/osmocom/sigtran/xua_msg.h index 60dd693..320da6a 100644 --- a/include/osmocom/sigtran/xua_msg.h +++ b/include/osmocom/sigtran/xua_msg.h @@ -60,6 +60,12 @@ const struct xua_msg_class *class[256]; }; +struct xua_msg_event_map { + uint8_t msg_class; + uint8_t msg_type; + int event; +}; + extern const struct xua_dialect xua_dialect_sua; extern const struct xua_dialect xua_dialect_m3ua; @@ -94,3 +100,6 @@ char *xua_msg_dump(struct xua_msg *xua, const struct xua_dialect *dialect); int xua_dialect_check_all_mand_ies(const struct xua_dialect *dialect, struct xua_msg *xua); +int xua_msg_event_map(const struct xua_msg *xua, + const struct xua_msg_event_map *maps, + unsigned int num_maps); diff --git a/src/xua_msg.c b/src/xua_msg.c index e094cb6..27279ce 100644 --- a/src/xua_msg.c +++ b/src/xua_msg.c @@ -361,6 +361,27 @@ return rc; } +/*! \brief Map from a xua_msg (class+type) to an event + * \param[in] xua xUA message which is to be mapped + * \param[in] maps Table containing msg type+class -> event maps + * \[aram[in] num_maps number of entries in \ref maps + * \returns event >= 0; negative on error (no map found) */ +int xua_msg_event_map(const struct xua_msg *xua, + const struct xua_msg_event_map *maps, + unsigned int num_maps) +{ + int i; + + for (i= 0; i < num_maps; i++) { + const struct xua_msg_event_map *map = &maps[i]; + if (xua->hdr.msg_class == map->msg_class && + xua->hdr.msg_type == map->msg_type) { + return map->event; + } + } + return -1; +} + const char *xua_class_msg_name(const struct xua_msg_class *xmc, uint16_t msg_type) { static char class_buf[64]; -- To view, visit https://gerrit.osmocom.org/2208 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Iee1c7fc2bf64219ebb71a0dbe6fd210749332413 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Mon Apr 3 20:22:08 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 3 Apr 2017 20:22:08 +0000 Subject: [PATCH] libosmo-sccp[master]: Add new 'osmo_ss7' SS7 core code with M3UA, ASP/AS FSM, ... Message-ID: Review at https://gerrit.osmocom.org/2209 Add new 'osmo_ss7' SS7 core code with M3UA, ASP/AS FSM, ... This is what aims to be a rather complete/proper implementation of the SIGTRAN + SS7 protocol suite. It has proper abstraction between the layers with primitives, finite state machines for things like the AS and ASP state machines, support for point code routing, etc. What's not implemented at this point: * re-integration of pre-existing SUA (pending) * actual MTP2 and physical E1/T1 link support * different trafic modes like broadcast/fail-over/load-balance Change-Id: I375eb80f01acc013094851d91d1d3333ebc12bc7 --- M configure.ac M include/osmocom/sigtran/Makefile.am A include/osmocom/sigtran/osmo_ss7.h A include/osmocom/sigtran/protocol/mtp.h M include/osmocom/sigtran/sigtran_sap.h M src/Makefile.am A src/m3ua.c A src/osmo_ss7.c A src/osmo_ss7_hmrt.c A src/osmo_ss7_vty.c A src/xua_as_fsm.c A src/xua_as_fsm.h A src/xua_asp_fsm.c A src/xua_asp_fsm.h A src/xua_internal.h M tests/Makefile.am A tests/ss7/Makefile.am A tests/ss7/ss7_test.c A tests/ss7/ss7_test.err A tests/ss7/ss7_test.ok M tests/testsuite.at 21 files changed, 4,980 insertions(+), 4 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/09/2209/1 diff --git a/configure.ac b/configure.ac index 4c3c937..2e55c57 100644 --- a/configure.ac +++ b/configure.ac @@ -56,5 +56,6 @@ tests/mtp/Makefile tests/m2ua/Makefile tests/sigtran/Makefile + tests/ss7/Makefile Makefile) diff --git a/include/osmocom/sigtran/Makefile.am b/include/osmocom/sigtran/Makefile.am index 2f2912f..ca7a304 100644 --- a/include/osmocom/sigtran/Makefile.am +++ b/include/osmocom/sigtran/Makefile.am @@ -1,7 +1,7 @@ sigtran_HEADERS = xua_types.h xua_msg.h m2ua_types.h sccp_sap.h \ - sua.h sigtran_sap.h sccp_helpers.h mtp_sap.h + sua.h sigtran_sap.h sccp_helpers.h mtp_sap.h osmo_ss7.h sigtrandir = $(includedir)/osmocom/sigtran -sigtran_prot_HEADERS = protocol/sua.h protocol/m3ua.h +sigtran_prot_HEADERS = protocol/sua.h protocol/m3ua.h protocol/mtp.h sigtran_protdir = $(includedir)/osmocom/sigtran/protocol diff --git a/include/osmocom/sigtran/osmo_ss7.h b/include/osmocom/sigtran/osmo_ss7.h new file mode 100644 index 0000000..5bbcd65 --- /dev/null +++ b/include/osmocom/sigtran/osmo_ss7.h @@ -0,0 +1,408 @@ +#pragma once + +#include +#include + +#include +#include +#include +#include +#include + +struct osmo_ss7_instance; +struct osmo_ss7_user; +struct osmo_sccp_instance; +struct osmo_mtp_prim; + +int osmo_ss7_init(void); + +bool osmo_ss7_pc_is_local(struct osmo_ss7_instance *inst, uint32_t pc); +int osmo_ss7_pointcode_parse(struct osmo_ss7_instance *inst, const char *str); +int osmo_ss7_pointcode_parse_mask_or_len(struct osmo_ss7_instance *inst, const char *in); +const char *osmo_ss7_pointcode_print(struct osmo_ss7_instance *inst, uint32_t pc); + +/*********************************************************************** + * SS7 Routing Tables + ***********************************************************************/ + +struct osmo_ss7_route_table { + /*! member in list of routing tables */ + struct llist_head list; + /*! \ref osmo_ss7_instance to which we belong */ + struct osmo_ss7_instance *inst; + /*! list of \ref osmo_ss7_route */ + struct llist_head routes; + + struct { + char *name; + char *description; + } cfg; +}; + +struct osmo_ss7_route_table * +osmo_ss7_route_table_find(struct osmo_ss7_instance *inst, const char *name); +struct osmo_ss7_route_table * +osmo_ss7_route_table_find_or_create(struct osmo_ss7_instance *inst, const char *name); +void osmo_ss7_route_table_destroy(struct osmo_ss7_route_table *rtbl); + +/*********************************************************************** + * SS7 Instances + ***********************************************************************/ + +struct osmo_ss7_instance { + /*! member of global list of instances */ + struct llist_head list; + /*! list of \ref osmo_ss7_linkset */ + struct llist_head linksets; + /*! list of \ref osmo_ss7_as */ + struct llist_head as_list; + /*! list of \ref osmo_ss7_asp */ + struct llist_head asp_list; + /*! list of \ref osmo_ss7_route_table */ + struct llist_head rtable_list; + /* array for faster lookup of user (indexed by service + * indicator) */ + const struct osmo_ss7_user *user[16]; + + struct osmo_ss7_route_table *rtable_system; + + struct osmo_sccp_instance *sccp; + + struct { + uint32_t id; + char *name; + char *description; + uint32_t primary_pc; + /* secondary PCs */ + /* capability PCs */ + uint8_t network_indicator; + struct { + char delimiter; + uint8_t component_len[3]; + } pc_fmt; + } cfg; +}; + +struct osmo_ss7_instance *osmo_ss7_instance_find(uint32_t id); +struct osmo_ss7_instance * +osmo_ss7_instance_find_or_create(void *ctx, uint32_t id); +void osmo_ss7_instance_destroy(struct osmo_ss7_instance *inst); +int osmo_ss7_instance_set_pc_fmt(struct osmo_ss7_instance *inst, + uint8_t c0, uint8_t c1, uint8_t c2); + +/*********************************************************************** + * MTP Users (Users of MTP, such as SCCP or ISUP) + ***********************************************************************/ + +struct osmo_ss7_user { + /* pointer back to SS7 instance */ + struct osmo_ss7_instance *inst; + /* name of the user */ + const char *name; + /* primitive call-back for incoming MTP primitives */ + osmo_prim_cb prim_cb; + /* private data */ + void *priv; +}; + +int osmo_ss7_user_register(struct osmo_ss7_instance *inst, uint8_t service_ind, + struct osmo_ss7_user *user); + +int osmo_ss7_user_unregister(struct osmo_ss7_instance *inst, uint8_t service_ind, + struct osmo_ss7_user *user); + +int osmo_ss7_mtp_to_user(struct osmo_ss7_instance *inst, struct osmo_mtp_prim *omp); + +/* SS7 User wants to issue MTP-TRANSFER.req */ +int osmo_ss7_user_mtp_xfer_req(struct osmo_ss7_instance *inst, + struct osmo_mtp_prim *omp); + +/*********************************************************************** + * SS7 Links + ***********************************************************************/ + +enum osmo_ss7_link_adm_state { + OSMO_SS7_LS_SHUTDOWN, + OSMO_SS7_LS_INHIBITED, + OSMO_SS7_LS_ENABLED, + _NUM_OSMO_SS7_LS +}; + +struct osmo_ss7_linkset; +struct osmo_ss7_link; + +struct osmo_ss7_link { + /*! \ref osmo_ss7_linkset to which we belong */ + struct osmo_ss7_linkset *linkset; + struct { + char *name; + char *description; + uint32_t id; + + enum osmo_ss7_link_adm_state adm_state; + } cfg; +}; + +void osmo_ss7_link_destroy(struct osmo_ss7_link *link); +struct osmo_ss7_link * +osmo_ss7_link_find_or_create(struct osmo_ss7_linkset *lset, uint32_t id); + +/*********************************************************************** + * SS7 Linksets + ***********************************************************************/ + +struct osmo_ss7_linkset { + struct llist_head list; + /*! \ref osmo_ss7_instance to which we belong */ + struct osmo_ss7_instance *inst; + /*! array of \ref osmo_ss7_link */ + struct osmo_ss7_link *links[16]; + + struct { + char *name; + char *description; + uint32_t adjacent_pc; + uint32_t local_pc; + } cfg; +}; + +void osmo_ss7_linkset_destroy(struct osmo_ss7_linkset *lset); +struct osmo_ss7_linkset * +osmo_ss7_linkset_find_by_name(struct osmo_ss7_instance *inst, const char *name); +struct osmo_ss7_linkset * +osmo_ss7_linkset_find_or_create(struct osmo_ss7_instance *inst, const char *name, uint32_t pc); + + +/*********************************************************************** + * SS7 Routes + ***********************************************************************/ + +struct osmo_ss7_route { + /*! member in \ref osmo_ss7_route_table.routes */ + struct llist_head list; + /*! \ref osmo_ss7_route_table to which we belong */ + struct osmo_ss7_route_table *rtable; + + struct { + /*! pointer to linkset (destination) of route */ + struct osmo_ss7_linkset *linkset; + /*! pointer to Application Server */ + struct osmo_ss7_as *as; + } dest; + + struct { + /* FIXME: presence? */ + uint32_t pc; + uint32_t mask; + /*! human-specified linkset name */ + char *linkset_name; + /*! lower priority is higher */ + uint32_t priority; + uint8_t qos_class; + } cfg; +}; + +struct osmo_ss7_route * +osmo_ss7_route_find_dpc(struct osmo_ss7_route_table *rtbl, uint32_t dpc); +struct osmo_ss7_route * +osmo_ss7_route_find_dpc_mask(struct osmo_ss7_route_table *rtbl, uint32_t dpc, + uint32_t mask); +struct osmo_ss7_route * +osmo_ss7_route_lookup(struct osmo_ss7_instance *inst, uint32_t dpc); +struct osmo_ss7_route * +osmo_ss7_route_create(struct osmo_ss7_route_table *rtbl, uint32_t dpc, + uint32_t mask, const char *linkset_name); +void osmo_ss7_route_destroy(struct osmo_ss7_route *rt); + + +/*********************************************************************** + * SS7 Application Servers + ***********************************************************************/ + +struct osmo_ss7_routing_key { + uint32_t context; + + uint32_t pc; + uint8_t si; + uint32_t ssn; + /* FIXME: more complex routing keys */ +}; + +enum osmo_ss7_as_traffic_mode { + OSMO_SS7_AS_TMOD_BCAST, + OSMO_SS7_AS_TMOD_LOADSHARE, + OSMO_SS7_AS_TMOD_ROUNDROBIN, + OSMO_SS7_AS_TMOD_OVERRIDE, + _NUM_OSMO_SS7_ASP_TMOD +}; + +extern struct value_string osmo_ss7_as_traffic_mode_vals[]; + +static inline const char * +osmo_ss7_as_traffic_mode_name(enum osmo_ss7_as_traffic_mode mode) +{ + return get_value_string(osmo_ss7_as_traffic_mode_vals, mode); +} + +enum osmo_ss7_asp_protocol { + OSMO_SS7_ASP_PROT_NONE, + OSMO_SS7_ASP_PROT_SUA, + OSMO_SS7_ASP_PROT_M3UA, + _NUM_OSMO_SS7_ASP_PROT +}; + +extern struct value_string osmo_ss7_asp_protocol_vals[]; + +static inline const char * +osmo_ss7_asp_protocol_name(enum osmo_ss7_asp_protocol mode) +{ + return get_value_string(osmo_ss7_asp_protocol_vals, mode); +} + +int osmo_ss7_asp_protocol_port(enum osmo_ss7_asp_protocol prot); + +struct osmo_ss7_as { + /*! entry in 'ref osmo_ss7_instance.as_list */ + struct llist_head list; + struct osmo_ss7_instance *inst; + + /*! AS FSM */ + struct osmo_fsm_inst *fi; + + struct { + char *name; + char *description; + enum osmo_ss7_asp_protocol proto; + struct osmo_ss7_routing_key routing_key; + enum osmo_ss7_as_traffic_mode mode; + uint32_t recovery_timeout_msec; + uint8_t qos_class; + + struct osmo_ss7_asp *asps[16]; + } cfg; +}; + +struct osmo_ss7_as * +osmo_ss7_as_find_by_name(struct osmo_ss7_instance *inst, const char *name); +struct osmo_ss7_as * +osmo_ss7_as_find_by_rctx(struct osmo_ss7_instance *inst, uint32_t rctx); +struct osmo_ss7_as * +osmo_ss7_as_find_or_create(struct osmo_ss7_instance *inst, const char *name, + enum osmo_ss7_asp_protocol proto); +int osmo_ss7_as_add_asp(struct osmo_ss7_as *as, const char *asp_name); +int osmo_ss7_as_del_asp(struct osmo_ss7_as *as, const char *asp_name); +void osmo_ss7_as_destroy(struct osmo_ss7_as *as); +bool osmo_ss7_as_has_asp(struct osmo_ss7_as *as, + struct osmo_ss7_asp *asp); + + +/*********************************************************************** + * SS7 Application Server Processes + ***********************************************************************/ + +struct osmo_ss7_asp_peer { + char *host; + uint16_t port; +}; + +enum osmo_ss7_asp_admin_state { + /*! no SCTP association with peer */ + OSMO_SS7_ASP_ADM_S_SHUTDOWN, + /*! SCP association, but reject ASP-ACTIVE */ + OSMO_SS7_ASP_ADM_S_BLOCKED, + /*! in normal operation */ + OSMO_SS7_ASP_ADM_S_ENABLED, +}; + +struct osmo_ss7_asp { + /*! entry in \ref osmo_ss7_instance.asp_list */ + struct llist_head list; + struct osmo_ss7_instance *inst; + + /*! ASP FSM */ + struct osmo_fsm_inst *fi; + + /*! \ref osmo_xua_server over which we were established */ + struct osmo_xua_server *xua_server; + + /*! osmo_stream / libosmo-netif handles */ + struct osmo_stream_cli *client; + struct osmo_stream_srv *server; + /*! pre-formatted human readable local/remote socket name */ + char *sock_name; + + /* ASP Identifier for ASP-UP + NTFY */ + uint32_t asp_id; + bool asp_id_present; + + struct { + char *name; + char *description; + enum osmo_ss7_asp_protocol proto; + enum osmo_ss7_asp_admin_state adm_state; + bool is_server; + + struct osmo_ss7_asp_peer local; + struct osmo_ss7_asp_peer remote; + uint8_t qos_class; + } cfg; +}; + +struct osmo_ss7_asp * +osmo_ss7_asp_find_by_name(struct osmo_ss7_instance *inst, const char *name); +struct osmo_ss7_asp * +osmo_ss7_asp_find_or_create(struct osmo_ss7_instance *inst, const char *name, + uint16_t remote_port, uint16_t local_port, + enum osmo_ss7_asp_protocol proto); +void osmo_ss7_asp_destroy(struct osmo_ss7_asp *asp); +int osmo_ss7_asp_send(struct osmo_ss7_asp *asp, struct msgb *msg); +int osmo_ss7_asp_restart(struct osmo_ss7_asp *asp); + +#define LOGPASP(asp, subsys, level, fmt, args ...) \ + LOGP(subsys, level, "asp-%s: " fmt, (asp)->cfg.name, ## args) + +/*********************************************************************** + * xUA Servers + ***********************************************************************/ + +struct osmo_xua_server { + struct llist_head list; + struct osmo_ss7_instance *inst; + + struct osmo_stream_srv_link *server; + + struct { + struct osmo_ss7_asp_peer local; + enum osmo_ss7_asp_protocol proto; + } cfg; +}; + +struct osmo_xua_server * +osmo_ss7_xua_server_find(struct osmo_ss7_instance *inst, enum osmo_ss7_asp_protocol proto, + uint16_t local_port); + +struct osmo_xua_server * +osmo_ss7_xua_server_create(struct osmo_ss7_instance *inst, enum osmo_ss7_asp_protocol proto, + uint16_t local_port, const char *local_host); + +int +osmo_ss7_xua_server_set_local_host(struct osmo_xua_server *xs, const char *local_host); + +void osmo_ss7_xua_server_destroy(struct osmo_xua_server *xs); + +struct osmo_sccp_instance * +osmo_sccp_simple_client(void *ctx, const char *name, uint32_t pc, + enum osmo_ss7_asp_protocol prot, + int local_port, int remote_port, const char *remote_ip); + +struct osmo_sccp_instance * +osmo_sccp_simple_server(void *ctx, uint32_t pc, + enum osmo_ss7_asp_protocol prot, int local_port, + const char *local_ip); + +struct osmo_sccp_instance * +osmo_sccp_simple_server_add_clnt(struct osmo_sccp_instance *inst, + enum osmo_ss7_asp_protocol prot, + const char *name, uint32_t pc, + int local_port, int remote_port, + const char *remote_ip); diff --git a/include/osmocom/sigtran/protocol/mtp.h b/include/osmocom/sigtran/protocol/mtp.h new file mode 100644 index 0000000..8b990c0 --- /dev/null +++ b/include/osmocom/sigtran/protocol/mtp.h @@ -0,0 +1,24 @@ +#pragma once + +#include + +/* Chapter 15.17.4 of Q.704 + RFC4666 3.4.5. */ +/* Section 5.1 of ETSI EG 201 693: MTP SI code allocations (for NI= 00) */ +enum mtp_si_ni00 { + MTP_SI_SNM = 0, + MTP_SI_STM = 1, + MTP_SI_SCCP = 3, + MTP_SI_TUP = 4, + MTP_SI_ISUP = 5, + MTP_SI_DUP = 6, /* call related */ + MTP_SI_DUP_FAC = 7, /* facility related */ + MTP_SI_TESTING = 8, + MTP_SI_B_ISUP = 9, + MTP_SI_SAT_ISUP = 10, + MTP_SI_SPEECH = 11, /* speech processing element */ + MTP_SI_AAL2_SIG = 12, + MTP_SI_BICC = 13, + MTP_SI_GCP = 14, +}; + +extern const struct value_string mtp_si_vals[]; diff --git a/include/osmocom/sigtran/sigtran_sap.h b/include/osmocom/sigtran/sigtran_sap.h index 544fc44..d29c37d 100644 --- a/include/osmocom/sigtran/sigtran_sap.h +++ b/include/osmocom/sigtran/sigtran_sap.h @@ -3,4 +3,39 @@ enum osmo_sigtran_sap { SCCP_SAP_USER = _SAP_SS7_BASE, + /* xUA Layer Manager */ + XUA_SAP_LM, + MTP_SAP_USER, }; + +enum osmo_xlm_prim_type { + OSMO_XLM_PRIM_M_SCTP_ESTABLISH, + OSMO_XLM_PRIM_M_SCTP_RELEASE, + OSMO_XLM_PRIM_M_SCTP_RESTART, + OSMO_XLM_PRIM_M_SCTP_STATUS, + OSMO_XLM_PRIM_M_ASP_STATUS, + OSMO_XLM_PRIM_M_AS_STATUS, + OSMO_XLM_PRIM_M_NOTIFY, + OSMO_XLM_PRIM_M_ERROR, + OSMO_XLM_PRIM_M_ASP_UP, + OSMO_XLM_PRIM_M_ASP_DOWN, + OSMO_XLM_PRIM_M_ASP_ACTIVE, + OSMO_XLM_PRIM_M_ASP_INACTIVE, + OSMO_XLM_PRIM_M_AS_ACTIVE, + OSMO_XLM_PRIM_M_AS_INACTIVE, + OSMO_XLM_PRIM_M_AS_DOWN, + /* optional as per spec, not implemented yet */ + OSMO_XLM_PRIM_M_RK_REG, + OSMO_XLM_PRIM_M_RK_DEREG, +}; + + +struct osmo_xlm_prim { + struct osmo_prim_hdr oph; + union { + } u; +}; + +#define msgb_xlm_prim(msg) ((struct osmo_xlm_prim *)(msg)->l1h) + +char *osmo_xlm_prim_name(struct osmo_prim_hdr *oph); diff --git a/src/Makefile.am b/src/Makefile.am index 26482a0..f7f4ccc 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,6 +1,8 @@ AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir) AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMONETIF_CFLAGS) +noinst_HEADERS = xua_asp_fsm.h xua_as_fsm.h xua_internal.h + # Legacy static libs sccpdir = $(libdir) @@ -24,6 +26,7 @@ # documentation before making any modification LIBVERSION=0:0:0 -libosmo_sigtran_la_SOURCES = sccp_sap.c sua.c xua_msg.c sccp_helpers.c +libosmo_sigtran_la_SOURCES = sccp_sap.c sua.c m3ua.c xua_msg.c sccp_helpers.c \ + osmo_ss7.c osmo_ss7_hmrt.c xua_asp_fsm.c xua_as_fsm.c libosmo_sigtran_la_LDFLAGS = -version-info $(LIBVERSION) -no-undefined -export-symbols-regex '^osmo_' libosmo_sigtran_la_LIBADD = $(LIBOSMOCORE_LIBS) $(LIBOSMONETIF_LIBS) $(LIBSCTP_LIBS) diff --git a/src/m3ua.c b/src/m3ua.c new file mode 100644 index 0000000..8ec82c5 --- /dev/null +++ b/src/m3ua.c @@ -0,0 +1,669 @@ +/* Minimal implementation of RFC 4666 - MTP3 User Adaptation Layer */ + +/* (C) 2015-2017 by Harald Welte + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include "xua_asp_fsm.h" +#include "xua_internal.h" + +#define M3UA_MSGB_SIZE 1500 + +/*********************************************************************** + * Protocol Definition (string tables, mandatory IE checking) + ***********************************************************************/ + +/* Section 3.8.1 */ +const struct value_string m3ua_err_names[] = { + { M3UA_ERR_INVALID_VERSION, "Invalid Version" }, + { M3UA_ERR_UNSUPP_MSG_CLASS, "Unsupported Message Class" }, + { M3UA_ERR_UNSUPP_MSG_TYPE, "Unsupported Message Type" }, + { M3UA_ERR_UNSUPP_TRAF_MOD_TYP, "Unsupported Traffic Mode Type" }, + { M3UA_ERR_UNEXPECTED_MSG, "Unexpected Message" }, + { M3UA_ERR_PROTOCOL_ERR, "Protocol Error" }, + { M3UA_ERR_INVAL_STREAM_ID, "Invalid Stream Identifier" }, + { M3UA_ERR_REFUSED_MGMT_BLOCKING, "Refused - Management Blocking" }, + { M3UA_ERR_ASP_ID_REQD, "ASP Identifier Required" }, + { M3UA_ERR_INVAL_ASP_ID, "Invalid ASP Identifier" }, + { M3UA_ERR_INVAL_PARAM_VAL, "Invalid Parameter Value" }, + { M3UA_ERR_PARAM_FIELD_ERR, "Parameter Field Error" }, + { M3UA_ERR_UNEXP_PARAM, "Unexpected Parameter" }, + { M3UA_ERR_DEST_STATUS_UNKN, "Destination Status Unknown" }, + { M3UA_ERR_INVAL_NET_APPEAR, "Invalid Network Appearance" }, + { M3UA_ERR_MISSING_PARAM, "Missing Parameter" }, + { M3UA_ERR_INVAL_ROUT_CTX, "Invalid Routing Context" }, + { M3UA_ERR_NO_CONFGD_AS_FOR_ASP,"No Configured AS for ASP" }, + { SUA_ERR_SUBSYS_STATUS_UNKN, "Subsystem Status Unknown" }, + { SUA_ERR_INVAL_LOADSH_LEVEL, "Invalid loadsharing level" }, + { 0, NULL } +}; + +const struct value_string m3ua_ntfy_type_names[] = { + { M3UA_NOTIFY_T_STATCHG, "State Change" }, + { M3UA_NOTIFY_T_OTHER, "Other" }, + { 0, NULL } +}; + +const struct value_string m3ua_ntfy_stchg_names[] = { + { M3UA_NOTIFY_I_RESERVED, "Reserved" }, + { M3UA_NOTIFY_I_AS_INACT, "AS Inactive" }, + { M3UA_NOTIFY_I_AS_ACT, "AS Active" }, + { M3UA_NOTIFY_I_AS_PEND, "AS Pending" }, + { 0, NULL } +}; + +const struct value_string m3ua_ntfy_other_names[] = { + { M3UA_NOTIFY_I_OT_INS_RES, "Insufficient ASP Resouces active in AS" }, + { M3UA_NOTIFY_I_OT_ALT_ASP_ACT, "Alternative ASP Active" }, + { M3UA_NOTIFY_I_OT_ASP_FAILURE, "ASP Failure" }, + { 0, NULL } +}; + +static const struct value_string m3ua_iei_names[] = { + { M3UA_IEI_INFO_STRING, "INFO String" }, + { M3UA_IEI_ROUTE_CTX, "Routing Context" }, + { M3UA_IEI_DIAG_INFO, "Diagnostic Info" }, + { M3UA_IEI_HEARDBT_DATA, "Heartbeat Data" }, + { M3UA_IEI_TRAF_MODE_TYP, "Traffic Mode Type" }, + { M3UA_IEI_ERR_CODE, "Error Code" }, + { M3UA_IEI_STATUS, "Status" }, + { M3UA_IEI_ASP_ID, "ASP Identifier" }, + { M3UA_IEI_AFFECTED_PC, "Affected Point Code" }, + { M3UA_IEI_CORR_ID, "Correlation Id" }, + + { M3UA_IEI_NET_APPEAR, "Network Appearance" }, + { M3UA_IEI_USER_CAUSE, "User/Cause" }, + { M3UA_IEI_CONG_IND, "Congestion Indication" }, + { M3UA_IEI_CONC_DEST, "Concerned Destination" }, + { M3UA_IEI_ROUT_KEY, "Routing Key" }, + { M3UA_IEI_REG_RESULT, "Registration Result" }, + { M3UA_IEI_DEREG_RESULT, "De-Registration Result" }, + { M3UA_IEI_LOC_RKEY_ID, "Local Routing-Key Identifier" }, + { M3UA_IEI_DEST_PC, "Destination Point Code" }, + { M3UA_IEI_SVC_IND, "Service Indicators" }, + { M3UA_IEI_ORIG_PC, "Originating Point Code List" }, + { M3UA_IEI_PROT_DATA, "Protocol Data" }, + { M3UA_IEI_REG_STATUS, "Registration Status" }, + { M3UA_IEI_DEREG_STATUS, "De-Registration Status" }, + { 0, NULL } +}; + +#define MAND_IES(msgt, ies) [msgt] = (ies) + +/* XFER */ +static const uint16_t data_mand_ies[] = { + M3UA_IEI_PROT_DATA, 0 +}; +static const struct value_string m3ua_xfer_msgt_names[] = { + { M3UA_XFER_DATA, "DATA" }, + { 0, NULL } +}; +static const struct xua_msg_class msg_class_xfer = { + .name = "XFER", + .msgt_names = m3ua_xfer_msgt_names, + .mand_ies = { + MAND_IES(M3UA_XFER_DATA, data_mand_ies), + }, +}; + +/* SNM */ +static const uint16_t duna_mand_ies[] = { + M3UA_IEI_AFFECTED_PC, 0 +}; +static const uint16_t dava_mand_ies[] = { + M3UA_IEI_AFFECTED_PC, 0 +}; +static const uint16_t daud_mand_ies[] = { + M3UA_IEI_AFFECTED_PC, 0 +}; +static const uint16_t scon_mand_ies[] = { + M3UA_IEI_AFFECTED_PC, 0 +}; +static const uint16_t dupu_mand_ies[] = { + M3UA_IEI_AFFECTED_PC, M3UA_IEI_USER_CAUSE, 0 +}; +static const uint16_t drst_mand_ies[] = { + M3UA_IEI_AFFECTED_PC, 0 +}; +static const struct value_string m3ua_snm_msgt_names[] = { + { M3UA_SNM_DUNA, "DUNA" }, + { M3UA_SNM_DAVA, "DAVA" }, + { M3UA_SNM_DAUD, "DAUD" }, + { M3UA_SNM_SCON, "SCON" }, + { M3UA_SNM_DUPU, "DUPU" }, + { M3UA_SNM_DRST, "DRST" }, + { 0, NULL } +}; +const struct xua_msg_class m3ua_msg_class_snm = { + .name = "SNM", + .msgt_names = m3ua_snm_msgt_names, + .mand_ies = { + MAND_IES(M3UA_SNM_DUNA, duna_mand_ies), + MAND_IES(M3UA_SNM_DAVA, dava_mand_ies), + MAND_IES(M3UA_SNM_DAUD, daud_mand_ies), + MAND_IES(M3UA_SNM_SCON, scon_mand_ies), + MAND_IES(M3UA_SNM_DUPU, dupu_mand_ies), + MAND_IES(M3UA_SNM_DRST, drst_mand_ies), + }, +}; + +/* ASPSM */ +static const struct value_string m3ua_aspsm_msgt_names[] = { + { M3UA_ASPSM_UP, "UP" }, + { M3UA_ASPSM_DOWN, "DOWN" }, + { M3UA_ASPSM_BEAT, "BEAT" }, + { M3UA_ASPSM_UP_ACK, "UP-ACK" }, + { M3UA_ASPSM_DOWN_ACK, "DOWN-ACK" }, + { M3UA_ASPSM_BEAT_ACK, "BEAT-ACK" }, + { 0, NULL } +}; +const struct xua_msg_class m3ua_msg_class_aspsm = { + .name = "ASPSM", + .msgt_names = m3ua_aspsm_msgt_names, +}; + +/* ASPTM */ +const struct value_string m3ua_asptm_msgt_names[] = { + { M3UA_ASPTM_ACTIVE, "ACTIVE" }, + { M3UA_ASPTM_INACTIVE, "INACTIVE" }, + { M3UA_ASPTM_ACTIVE_ACK,"ACTIVE-ACK" }, + { M3UA_ASPTM_INACTIVE_ACK, "INACTIVE-ACK" }, + { 0, NULL } +}; +const struct xua_msg_class m3ua_msg_class_asptm = { + .name = "ASPTM", + .msgt_names = m3ua_asptm_msgt_names, + .iei_names = m3ua_iei_names, +}; + +/* MGMT */ +static const uint16_t err_req_ies[] = { + M3UA_IEI_ERR_CODE, 0 +}; +static const uint16_t ntfy_req_ies[] = { + M3UA_IEI_STATUS, 0 +}; +static const struct value_string m3ua_mgmt_msgt_names[] = { + { M3UA_MGMT_ERR, "ERROR" }, + { M3UA_MGMT_NTFY, "NOTIFY" }, + { 0, NULL } +}; +const struct xua_msg_class m3ua_msg_class_mgmt = { + .name = "MGMT", + .msgt_names = m3ua_mgmt_msgt_names, + .iei_names = m3ua_iei_names, + .mand_ies = { + MAND_IES(M3UA_MGMT_ERR, err_req_ies), + MAND_IES(M3UA_MGMT_NTFY, ntfy_req_ies), + }, +}; + +/* RKM */ +static const uint16_t reg_req_ies[] = { + M3UA_IEI_ROUT_KEY, 0 +}; +static const uint16_t reg_rsp_ies[] = { + M3UA_IEI_REG_RESULT, 0 +}; +static const uint16_t dereg_req_ies[] = { + M3UA_IEI_ROUT_KEY, 0 +}; +static const uint16_t dereg_rsp_ies[] = { + M3UA_IEI_DEREG_RESULT, 0 +}; +static const struct value_string m3ua_rkm_msgt_names[] = { + { M3UA_RKM_REG_REQ, "REG-REQ" }, + { M3UA_RKM_REG_RSP, "REG-RESP" }, + { M3UA_RKM_DEREG_REQ, "DEREG-REQ" }, + { M3UA_RKM_DEREG_RSP, "DEREG-RESP" }, + { 0, NULL } +}; +const struct xua_msg_class m3ua_msg_class_rkm = { + .name = "RKM", + .msgt_names = m3ua_rkm_msgt_names, + .iei_names = m3ua_iei_names, + .mand_ies = { + MAND_IES(M3UA_RKM_REG_REQ, reg_req_ies), + MAND_IES(M3UA_RKM_REG_RSP, reg_rsp_ies), + MAND_IES(M3UA_RKM_DEREG_REQ, dereg_req_ies), + MAND_IES(M3UA_RKM_DEREG_RSP, dereg_rsp_ies), + }, +}; + +/* M3UA dialect of XUA, MGMT,XFER,SNM,ASPSM,ASPTM,RKM */ +const struct xua_dialect xua_dialect_m3ua = { + .name = "M3UA", + .ppid = M3UA_PPID, + .port = M3UA_PORT, + .log_subsys = DLM3UA, + .class = { + [M3UA_MSGC_MGMT] = &m3ua_msg_class_mgmt, + [M3UA_MSGC_XFER] = &msg_class_xfer, + [M3UA_MSGC_SNM] = &m3ua_msg_class_snm, + [M3UA_MSGC_ASPSM] = &m3ua_msg_class_aspsm, + [M3UA_MSGC_ASPTM] = &m3ua_msg_class_asptm, + [M3UA_MSGC_RKM] = &m3ua_msg_class_rkm, + }, +}; + +/* convert osmo_mtp_transfer_param to m3ua_data_hdr */ +void mtp_xfer_param_to_m3ua_dh(struct m3ua_data_hdr *mdh, + const struct osmo_mtp_transfer_param *param) +{ + mdh->opc = htonl(param->opc); + mdh->dpc = htonl(param->dpc); + mdh->si = param->sio & 0xF; + mdh->ni = (param->sio >> 6) & 0x3; + mdh->mp = (param->sio >> 4) & 0x3; + mdh->sls = param->sls; +} + +/* convert m3ua_data_hdr to osmo_mtp_transfer_param */ +void m3ua_dh_to_xfer_param(struct osmo_mtp_transfer_param *param, + const struct m3ua_data_hdr *mdh) +{ + param->opc = ntohl(mdh->opc); + param->dpc = ntohl(mdh->dpc); + param->sls = mdh->sls; + /* re-construct SIO */ + param->sio = (mdh->si & 0xF) | + (mdh->mp & 0x3 << 4) | + (mdh->ni & 0x3 << 6); +} + +#define M3UA_MSG_SIZE 2048 +#define M3UA_MSG_HEADROOM 512 + +struct msgb *m3ua_msgb_alloc(const char *name) +{ + if (!name) + name = "M3UA"; + return msgb_alloc_headroom(M3UA_MSG_SIZE+M3UA_MSG_HEADROOM, + M3UA_MSG_HEADROOM, name); +} + +/*********************************************************************** + * ERROR generation + ***********************************************************************/ + +static struct xua_msg *m3ua_gen_error(uint32_t err_code) +{ + struct xua_msg *xua = xua_msg_alloc(); + + xua->hdr = XUA_HDR(M3UA_MSGC_MGMT, M3UA_MGMT_ERR); + xua->hdr.version = M3UA_VERSION; + xua_msg_add_u32(xua, M3UA_IEI_ERR_CODE, err_code); + + return xua; +} + +static struct xua_msg *m3ua_gen_error_msg(uint32_t err_code, struct msgb *msg) +{ + struct xua_msg *xua = m3ua_gen_error(err_code); + unsigned int len_max_40 = msgb_length(msg); + + if (len_max_40 > 40) + len_max_40 = 40; + + xua_msg_add_data(xua, M3UA_IEI_DIAG_INFO, len_max_40, msgb_data(msg)); + + return xua; +} + +/*********************************************************************** + * NOTIFY generation + ***********************************************************************/ + +/* RFC4666 Ch. 3.8.2. Notify */ +struct xua_msg *m3ua_encode_notify(const struct m3ua_notify_params *npar) +{ + struct xua_msg *xua = xua_msg_alloc(); + uint32_t status; + + xua->hdr = XUA_HDR(M3UA_MSGC_MGMT, M3UA_MGMT_NTFY); + + status = M3UA_NOTIFY(htons(npar->status_type), htons(npar->status_info)); + /* cannot use xua_msg_add_u32() as it does endian conversion */ + xua_msg_add_data(xua, M3UA_IEI_STATUS, sizeof(status), (uint8_t *) &status); + + /* Conditional: ASP Identifier */ + if (npar->presence & NOTIFY_PAR_P_ASP_ID) + xua_msg_add_u32(xua, M3UA_IEI_ASP_ID, npar->asp_id); + + /* Optional Routing Context */ + if (npar->presence & NOTIFY_PAR_P_ROUTE_CTX) + xua_msg_add_u32(xua, M3UA_IEI_ROUTE_CTX, npar->route_ctx); + + /* Optional: Info String */ + if (npar->info_string) + xua_msg_add_data(xua, M3UA_IEI_INFO_STRING, + strlen(npar->info_string)+1, + (uint8_t *) npar->info_string); + + return xua; +} + +/* RFC4666 Ch. 3.8.2. Notify */ +int m3ua_decode_notify(struct m3ua_notify_params *npar, void *ctx, + const struct xua_msg *xua) +{ + struct xua_msg_part *info_ie, *aspid_ie, *status_ie, *rctx_ie; + uint32_t status; + + /* cannot use xua_msg_get_u32() as it does endian conversion */ + status_ie = xua_msg_find_tag(xua, M3UA_IEI_STATUS); + status = *(uint32_t *) status_ie->dat; + + aspid_ie = xua_msg_find_tag(xua, M3UA_IEI_ASP_ID); + rctx_ie = xua_msg_find_tag(xua, M3UA_IEI_ROUTE_CTX); + info_ie = xua_msg_find_tag(xua, M3UA_IEI_INFO_STRING); + + npar->presence = 0; + npar->status_type = ntohs(status & 0xffff); + npar->status_info = ntohs(status >> 16); + + if (aspid_ie) { + npar->asp_id = xua_msg_part_get_u32(aspid_ie); + npar->presence |= NOTIFY_PAR_P_ASP_ID; + } + + if (rctx_ie) { + npar->route_ctx = xua_msg_part_get_u32(rctx_ie); + npar->presence |= NOTIFY_PAR_P_ROUTE_CTX; + } + + if (info_ie) { + npar->info_string = talloc_size(ctx, info_ie->len); + memcpy(npar->info_string, info_ie->dat, info_ie->len); + } else + npar->info_string = NULL; + + return 0; +} + +/*********************************************************************** + * Transmitting M3UA messsages to SCTP + ***********************************************************************/ + +static int m3ua_tx_xua_asp(struct osmo_ss7_asp *asp, struct xua_msg *xua) +{ + struct msgb *msg = xua_to_msg(M3UA_VERSION, xua); + + OSMO_ASSERT(asp->cfg.proto == OSMO_SS7_ASP_PROT_M3UA); + + xua_msg_free(xua); + + if (!msg) { + LOGP(DLM3UA, LOGL_ERROR, "Error encoding M3UA Msg\n"); + return -1; + } + + msgb_sctp_ppid(msg) = M3UA_PPID; + return osmo_ss7_asp_send(asp, msg); +} + +/*! \brief Send a given xUA message via a given M3UA Application Server + * \param[in] as Application Server through which to send \ref xua + * \param[in] xua xUA message to be sent + * \return 0 on success; negative on error */ +int m3ua_tx_xua_as(struct osmo_ss7_as *as, struct xua_msg *xua) +{ + struct osmo_ss7_asp *asp; + unsigned int i; + + OSMO_ASSERT(as->cfg.proto == OSMO_SS7_ASP_PROT_M3UA); + + for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) { + asp = as->cfg.asps[i]; + if (!asp) + continue; + if (asp) + break; + } + if (!asp) { + LOGP(DLM3UA, LOGL_ERROR, "No ASP entroy in AS, dropping message\n"); + xua_msg_free(xua); + return -ENODEV; + } + + return m3ua_tx_xua_asp(asp, xua); +} + +/*********************************************************************** + * Receiving M3UA messsages from SCTP + ***********************************************************************/ + +/* obtain the destination point code from a M3UA message in XUA fmt * */ +struct m3ua_data_hdr *data_hdr_from_m3ua(struct xua_msg *xua) +{ + struct xua_msg_part *data_ie; + struct m3ua_data_hdr *data_hdr; + + if (xua->hdr.msg_class != M3UA_MSGC_XFER || + xua->hdr.msg_type != M3UA_XFER_DATA) + return NULL; + + data_ie = xua_msg_find_tag(xua, M3UA_IEI_PROT_DATA); + if (!data_ie) + return NULL; + data_hdr = (struct m3ua_data_hdr *) data_ie->dat; + + return data_hdr; +} + +static int m3ua_rx_xfer(struct osmo_ss7_asp *asp, struct xua_msg *xua) +{ + struct m3ua_data_hdr *dh; + + /* store the MTP-level information in the xua_msg for use by + * higher layer protocols */ + dh = data_hdr_from_m3ua(xua); + OSMO_ASSERT(dh); + m3ua_dh_to_xfer_param(&xua->mtp, dh); + + return m3ua_hmdc_rx_from_l2(asp->inst, xua); +} + +static int m3ua_rx_mgmt_err(struct osmo_ss7_asp *asp, struct xua_msg *xua) +{ + uint32_t err_code = xua_msg_get_u32(xua, M3UA_IEI_ERR_CODE); + + LOGPASP(asp, DLM3UA, LOGL_ERROR, "Received MGMT_ERR '%s': %s\n", + get_value_string(m3ua_err_names, err_code), + xua_msg_dump(xua, &xua_dialect_m3ua)); + + /* NEVER return != 0 here, as we cannot respont to an ERR + * message with another ERR! */ + return 0; +} + +static int m3ua_rx_mgmt_ntfy(struct osmo_ss7_asp *asp, struct xua_msg *xua) +{ + struct m3ua_notify_params ntfy; + const char *type_name, *info_name; + + m3ua_decode_notify(&ntfy, asp, xua); + + type_name = get_value_string(m3ua_ntfy_type_names, ntfy.status_type); + + switch (ntfy.status_type) { + case M3UA_NOTIFY_T_STATCHG: + info_name = get_value_string(m3ua_ntfy_stchg_names, + ntfy.status_info); + break; + case M3UA_NOTIFY_T_OTHER: + info_name = get_value_string(m3ua_ntfy_other_names, + ntfy.status_info); + break; + default: + info_name = "NULL"; + break; + } + LOGPASP(asp, DLM3UA, LOGL_NOTICE, "Received NOTIFY Type %s:%s (%s)\n", + type_name, info_name, + ntfy.info_string ? ntfy.info_string : ""); + + if (ntfy.info_string) + talloc_free(ntfy.info_string); + + /* TODO: should we report this soemwhere? */ + return 0; +} + +static int m3ua_rx_mgmt(struct osmo_ss7_asp *asp, struct xua_msg *xua) +{ + switch (xua->hdr.msg_type) { + case M3UA_MGMT_ERR: + return m3ua_rx_mgmt_err(asp, xua); + case M3UA_MGMT_NTFY: + return m3ua_rx_mgmt_ntfy(asp, xua); + default: + return M3UA_ERR_UNSUPP_MSG_TYPE; + } +} + +/* map from M3UA ASPSM/ASPTM to xua_asp_fsm event */ +static const struct xua_msg_event_map m3ua_aspxm_map[] = { + { M3UA_MSGC_ASPSM, M3UA_ASPSM_UP, XUA_ASP_E_ASPSM_ASPUP }, + { M3UA_MSGC_ASPSM, M3UA_ASPSM_DOWN, XUA_ASP_E_ASPSM_ASPDN }, + { M3UA_MSGC_ASPSM, M3UA_ASPSM_BEAT, XUA_ASP_E_ASPSM_BEAT }, + { M3UA_MSGC_ASPSM, M3UA_ASPSM_UP_ACK, XUA_ASP_E_ASPSM_ASPUP_ACK }, + { M3UA_MSGC_ASPSM, M3UA_ASPSM_DOWN_ACK, XUA_ASP_E_ASPSM_ASPDN_ACK }, + { M3UA_MSGC_ASPSM, M3UA_ASPSM_BEAT_ACK, XUA_ASP_E_ASPSM_BEAT_ACK }, + { M3UA_MSGC_ASPTM, M3UA_ASPTM_ACTIVE, XUA_ASP_E_ASPTM_ASPAC }, + { M3UA_MSGC_ASPTM, M3UA_ASPTM_INACTIVE, XUA_ASP_E_ASPTM_ASPIA }, + { M3UA_MSGC_ASPTM, M3UA_ASPTM_ACTIVE_ACK, XUA_ASP_E_ASPTM_ASPAC_ACK }, + { M3UA_MSGC_ASPTM, M3UA_ASPTM_INACTIVE_ACK, XUA_ASP_E_ASPTM_ASPIA_ACK }, +}; + + +static int m3ua_rx_asp(struct osmo_ss7_asp *asp, struct xua_msg *xua) +{ + int event; + + /* map from the M3UA message class and message type to the XUA + * ASP FSM event number */ + event = xua_msg_event_map(xua, m3ua_aspxm_map, + ARRAY_SIZE(m3ua_aspxm_map)); + if (event < 0) + return M3UA_ERR_UNSUPP_MSG_TYPE; + + /* deliver that event to the ASP FSM */ + osmo_fsm_inst_dispatch(asp->fi, event, xua); + + return 0; +} + +/*! \brief process M3UA message received from socket + * \param[in] asp Application Server Process receiving \ref msg + * \param[in] msg received message buffer + * \returns 0 on success; negative on error */ +int m3ua_rx_msg(struct osmo_ss7_asp *asp, struct msgb *msg) +{ + struct xua_msg *xua = NULL, *err = NULL; + int rc = 0; + + OSMO_ASSERT(asp->cfg.proto == OSMO_SS7_ASP_PROT_M3UA); + + /* caller owns msg memory, we shall neither free it here nor + * keep references beyond the executin of this function and its + * callees */ + + xua = xua_from_msg(M3UA_VERSION, msgb_length(msg), msgb_data(msg)); + if (!xua) { + struct xua_common_hdr *hdr = (struct xua_common_hdr *) msg->data; + + LOGPASP(asp, DLM3UA, LOGL_ERROR, "Unable to parse incoming " + "M3UA message\n"); + + if (hdr->version != M3UA_VERSION) + err = m3ua_gen_error_msg(M3UA_ERR_INVALID_VERSION, msg); + else + err = m3ua_gen_error_msg(M3UA_ERR_PARAM_FIELD_ERR, msg); + goto out; + } + + LOGPASP(asp, DLM3UA, LOGL_DEBUG, "Received M3UA Message (%s)\n", + xua_hdr_dump(xua, &xua_dialect_m3ua)); + + if (!xua_dialect_check_all_mand_ies(&xua_dialect_m3ua, xua)) { + err = m3ua_gen_error_msg(M3UA_ERR_MISSING_PARAM, msg); + goto out; + } + + /* TODO: check for SCTP Strema ID */ + /* TODO: check if any AS configured in ASP */ + /* TODO: check for valid routing context */ + + switch (xua->hdr.msg_class) { + case M3UA_MSGC_XFER: + rc = m3ua_rx_xfer(asp, xua); + break; + case M3UA_MSGC_ASPSM: + case M3UA_MSGC_ASPTM: + rc = m3ua_rx_asp(asp, xua); + break; + break; + case M3UA_MSGC_MGMT: + rc = m3ua_rx_mgmt(asp, xua); + break; + case M3UA_MSGC_SNM: + case M3UA_MSGC_RKM: + /* FIXME */ + LOGPASP(asp, DLM3UA, LOGL_NOTICE, "Received unsupported M3UA " + "Message Class %u\n", xua->hdr.msg_class); + err = m3ua_gen_error_msg(M3UA_ERR_UNSUPP_MSG_CLASS, msg); + break; + default: + LOGPASP(asp, DLM3UA, LOGL_NOTICE, "Received unknown M3UA " + "Message Class %u\n", xua->hdr.msg_class); + err = m3ua_gen_error_msg(M3UA_ERR_UNSUPP_MSG_CLASS, msg); + break; + } + + if (rc > 0) + err = m3ua_gen_error_msg(rc, msg); + +out: + if (err) + m3ua_tx_xua_asp(asp, err); + + xua_msg_free(xua); + + return rc; +} diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c new file mode 100644 index 0000000..74c54bb --- /dev/null +++ b/src/osmo_ss7.c @@ -0,0 +1,1490 @@ +/* Core SS7 Instance/Linkset/Link/AS/ASP Handling */ + +/* (C) 2015-2017 by Harald Welte + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "xua_internal.h" +#include "xua_asp_fsm.h" +#include "xua_as_fsm.h" + +#define ASP_MSGB_SIZE 1500 +#define MAX_PC_STR_LEN 32 + +static bool ss7_initialized = false; + +static LLIST_HEAD(ss7_instances); +static LLIST_HEAD(ss7_xua_servers); + +struct value_string osmo_ss7_as_traffic_mode_vals[] = { + { OSMO_SS7_AS_TMOD_BCAST, "broadcast" }, + { OSMO_SS7_AS_TMOD_LOADSHARE, "loadshare" }, + { OSMO_SS7_AS_TMOD_ROUNDROBIN, "round-robin" }, + { OSMO_SS7_AS_TMOD_OVERRIDE, "override" }, + { 0, NULL } +}; + +struct value_string osmo_ss7_asp_protocol_vals[] = { + { OSMO_SS7_ASP_PROT_NONE, "none" }, + { OSMO_SS7_ASP_PROT_SUA, "sua" }, + { OSMO_SS7_ASP_PROT_M3UA, "m3ua" }, + { 0, NULL } +}; + +#define LOGSS7(inst, level, fmt, args ...) \ + LOGP(DLSS7, level, "%u: " fmt, (inst)->cfg.id, ## args) + + +/*********************************************************************** + * SS7 Point Code Parsing / Printing + ***********************************************************************/ + +/* like strcat() but appends a single character */ +static int strnappendchar(char *str, char c, size_t n) +{ + unsigned int curlen = strlen(str); + + if (n < curlen + 2) + return -1; + + str[curlen] = c; + str[curlen+1] = '\0'; + + return curlen+1; +} + +/* generate a format string for formatting a point code. The result can + * e.g. be used with sscanf() or sprintf() */ +static const char *gen_pc_fmtstr(struct osmo_ss7_instance *inst, + unsigned int *num_comp_exp) +{ + static char buf[MAX_PC_STR_LEN]; + unsigned int num_comp = 0; + + buf[0] = '\0'; + strcat(buf, "%u"); + num_comp++; + + if (inst->cfg.pc_fmt.component_len[1] == 0) + goto out; + strnappendchar(buf, inst->cfg.pc_fmt.delimiter, sizeof(buf)); + strcat(buf, "%u"); + num_comp++; + + if (inst->cfg.pc_fmt.component_len[2] == 0) + goto out; + strnappendchar(buf, inst->cfg.pc_fmt.delimiter, sizeof(buf)); + strcat(buf, "%u"); + num_comp++; +out: + if (num_comp_exp) + *num_comp_exp = num_comp; + return buf; +} + +/* get number of components we expect for a point code, depending on the + * configuration of this ss7_instance */ +static unsigned int num_pc_comp_exp(struct osmo_ss7_instance *inst) +{ + unsigned int num_comp_exp = 1; + + if (inst->cfg.pc_fmt.component_len[1]) + num_comp_exp++; + if (inst->cfg.pc_fmt.component_len[2]) + num_comp_exp++; + + return num_comp_exp; +} + +/* get the total width (in bits) of the point-codes in this ss7_instance */ +static unsigned int get_pc_width(struct osmo_ss7_instance *inst) +{ + return inst->cfg.pc_fmt.component_len[0] + + inst->cfg.pc_fmt.component_len[1] + + inst->cfg.pc_fmt.component_len[2]; +} + +/* get the number of bits we must shift the given component of a point + * code in this ss7_instance */ +static unsigned int get_pc_comp_shift(struct osmo_ss7_instance *inst, + unsigned int comp_num) +{ + uint32_t pc_width = get_pc_width(inst); + switch (comp_num) { + case 0: + return pc_width - inst->cfg.pc_fmt.component_len[0]; + case 1: + return pc_width - inst->cfg.pc_fmt.component_len[0] - + inst->cfg.pc_fmt.component_len[1]; + case 2: + return 0; + default: + return -EINVAL; + } +} + +static uint32_t pc_comp_shift_and_mask(struct osmo_ss7_instance *inst, + unsigned int comp_num, uint32_t pc) +{ + unsigned int shift = get_pc_comp_shift(inst, comp_num); + uint32_t mask = (1 << inst->cfg.pc_fmt.component_len[comp_num]) - 1; + + return (pc >> shift) & mask; +} + +/* parse a point code according to the structure configured for this + * ss7_instance */ +int osmo_ss7_pointcode_parse(struct osmo_ss7_instance *inst, const char *str) +{ + unsigned int component[3]; + unsigned int num_comp_exp = num_pc_comp_exp(inst); + const char *fmtstr = gen_pc_fmtstr(inst, &num_comp_exp); + int i, rc; + + rc = sscanf(str, fmtstr, &component[0], &component[1], &component[2]); + /* ensure all components were parsed */ + if (rc != num_comp_exp) + goto err; + + /* check none of the component values exceeds what can be + * represented within its bit-width */ + for (i = 0; i < num_comp_exp; i++) { + if (component[i] >= (1 << inst->cfg.pc_fmt.component_len[i])) + goto err; + } + + /* shift them all together */ + rc = (component[0] << get_pc_comp_shift(inst, 0)); + if (num_comp_exp > 1) + rc |= (component[1] << get_pc_comp_shift(inst, 1)); + if (num_comp_exp > 2) + rc |= (component[2] << get_pc_comp_shift(inst, 2)); + + return rc; + +err: + LOGSS7(inst, LOGL_NOTICE, "Error parsing Pointcode '%s'\n", str); + return -EINVAL; +} + +/* print a pointcode according to the structure configured for this + * ss7_instance */ +const char *osmo_ss7_pointcode_print(struct osmo_ss7_instance *inst, uint32_t pc) +{ + static char buf[MAX_PC_STR_LEN]; + unsigned int num_comp_exp = num_pc_comp_exp(inst); + const char *fmtstr = gen_pc_fmtstr(inst, &num_comp_exp); + + OSMO_ASSERT(fmtstr); + snprintf(buf, sizeof(buf), fmtstr, + pc_comp_shift_and_mask(inst, 0, pc), + pc_comp_shift_and_mask(inst, 1, pc), + pc_comp_shift_and_mask(inst, 2, pc)); + + return buf; +} + +int osmo_ss7_pointcode_parse_mask_or_len(struct osmo_ss7_instance *inst, const char *in) +{ + unsigned int width = get_pc_width(inst); + + if (in[0] == '/') { + /* parse mask by length */ + int masklen = atoi(in+1); + if (masklen < 0 || masklen > 32) + return -EINVAL; + if (masklen == 0) + return 0; + return (0xFFFFFFFF << (width - masklen)) & ((1 << width)-1); + } else { + /* parse mask as point code */ + return osmo_ss7_pointcode_parse(inst, in); + } +} + +static const uint16_t prot2port[] = { + [OSMO_SS7_ASP_PROT_NONE] = 0, + [OSMO_SS7_ASP_PROT_SUA] = SUA_PORT, + [OSMO_SS7_ASP_PROT_M3UA] = M3UA_PORT, +}; + +int osmo_ss7_asp_protocol_port(enum osmo_ss7_asp_protocol prot) +{ + if (prot >= ARRAY_SIZE(prot2port)) + return -EINVAL; + else + return prot2port[prot]; +} + +/*********************************************************************** + * SS7 Instance + ***********************************************************************/ + +/*! \brief Find a SS7 Instance with given ID + * \param[in] id ID for which to search + * \returns \ref osmo_ss7_instance on success; NULL on error */ +struct osmo_ss7_instance * +osmo_ss7_instance_find(uint32_t id) +{ + OSMO_ASSERT(ss7_initialized); + + struct osmo_ss7_instance *inst; + llist_for_each_entry(inst, &ss7_instances, list) { + if (inst->cfg.id == id) + return inst; + } + return NULL; +} + +/*! \brief Find or create a SS7 Instance + * \param[in] ctx talloc allocation context to use for allocations + * \param[in] id ID of SS7 Instance + * \returns \ref osmo_ss7_instance on success; NULL on error */ +struct osmo_ss7_instance * +osmo_ss7_instance_find_or_create(void *ctx, uint32_t id) +{ + struct osmo_ss7_instance *inst; + + OSMO_ASSERT(ss7_initialized); + + inst = osmo_ss7_instance_find(id); + if (!inst) + inst = talloc_zero(ctx, struct osmo_ss7_instance); + if (!inst) + return NULL; + + inst->cfg.id = id; + LOGSS7(inst, LOGL_INFO, "Creating SS7 Instance\n"); + + INIT_LLIST_HEAD(&inst->linksets); + INIT_LLIST_HEAD(&inst->as_list); + INIT_LLIST_HEAD(&inst->asp_list); + INIT_LLIST_HEAD(&inst->rtable_list); + inst->rtable_system = osmo_ss7_route_table_find_or_create(inst, "system"); + + /* default point code structure + formatting */ + inst->cfg.pc_fmt.delimiter = '.'; + inst->cfg.pc_fmt.component_len[0] = 3; + inst->cfg.pc_fmt.component_len[1] = 8; + inst->cfg.pc_fmt.component_len[2] = 3; + + llist_add(&inst->list, &ss7_instances); + + return inst; +} + +/*! \brief Destroy a SS7 Instance + * \param[in] inst SS7 Instance to be destroyed */ +void osmo_ss7_instance_destroy(struct osmo_ss7_instance *inst) +{ + struct osmo_ss7_linkset *lset; + struct osmo_ss7_as *as; + struct osmo_ss7_asp *asp; + + OSMO_ASSERT(ss7_initialized); + LOGSS7(inst, LOGL_INFO, "Destroying SS7 Instance\n"); + + llist_for_each_entry(asp, &inst->asp_list, list) + osmo_ss7_asp_destroy(asp); + + llist_for_each_entry(as, &inst->as_list, list) + osmo_ss7_as_destroy(as); + + llist_for_each_entry(lset, &inst->linksets, list) + osmo_ss7_linkset_destroy(lset); + + llist_del(&inst->list); + talloc_free(inst); +} + +/*! \brief Set the point code format used in given SS7 instance */ +int osmo_ss7_instance_set_pc_fmt(struct osmo_ss7_instance *inst, + uint8_t c0, uint8_t c1, uint8_t c2) +{ + if (c0+c1+c2 > 32) + return -EINVAL; + + if (c0+c1+c2 > 14) + LOGSS7(inst, LOGL_NOTICE, "Point Code Format %u-%u-%u " + "is longer than 14 bits, odd?\n", c0, c1, c2); + + inst->cfg.pc_fmt.component_len[0] = c0; + inst->cfg.pc_fmt.component_len[1] = c1; + inst->cfg.pc_fmt.component_len[2] = c2; + + return 0; +} + +/*********************************************************************** + * MTP Users (Users of MTP, such as SCCP or ISUP) + ***********************************************************************/ + +/*! \brief Register a MTP user for a given service indicator + * \param[in] inst SS7 instance for which we register the user + * \param[in] service_ind Service (ISUP, SCCP, ...) + * \param[in] user SS7 user (including primitive call-back) + * \returns 0 on success; negative on error */ +int osmo_ss7_user_register(struct osmo_ss7_instance *inst, uint8_t service_ind, + struct osmo_ss7_user *user) +{ + if (service_ind >= ARRAY_SIZE(inst->user)) + return -EINVAL; + + if (inst->user[service_ind]) + return -EBUSY; + + DEBUGP(DLSS7, "registering user=%s for SI %u with priv %p\n", + user->name, service_ind, user->priv); + + user->inst = inst; + inst->user[service_ind] = user; + + return 0; +} + +/*! \brief Unregister a MTP user for a given service indicator + * \param[in] inst SS7 instance for which we register the user + * \param[in] service_ind Service (ISUP, SCCP, ...) + * \param[in] user (optional) SS7 user. If present, we will not + * unregister other users + * \returns 0 on success; negative on error */ +int osmo_ss7_user_unregister(struct osmo_ss7_instance *inst, uint8_t service_ind, + struct osmo_ss7_user *user) +{ + if (service_ind >= ARRAY_SIZE(inst->user)) + return -EINVAL; + + if (!inst->user[service_ind]) + return -ENODEV; + + if (user && (inst->user[service_ind] != user)) + return -EINVAL; + + user->inst = NULL; + inst->user[service_ind] = NULL; + + return 0; +} + +/* deliver to a local MTP user */ +int osmo_ss7_mtp_to_user(struct osmo_ss7_instance *inst, struct osmo_mtp_prim *omp) +{ + uint32_t service_ind; + const struct osmo_ss7_user *osu; + + if (omp->oph.sap != MTP_SAP_USER || + omp->oph.primitive != OSMO_MTP_PRIM_TRANSFER || + omp->oph.operation != PRIM_OP_INDICATION) { + LOGP(DLSS7, LOGL_ERROR, "Unsupported Primitive\n"); + return -EINVAL; + } + + service_ind = omp->u.transfer.sio & 0xF; + osu = inst->user[service_ind]; + + if (!osu) { + LOGP(DLSS7, LOGL_NOTICE, "No MTP-User for SI %u\n", service_ind); + return -ENODEV; + } + + DEBUGP(DLSS7, "delivering MTP-TRANSFER.ind to user %s, priv=%p\n", + osu->name, osu->priv); + return osu->prim_cb(&omp->oph, (void *) osu->priv); +} + +/*********************************************************************** + * SS7 Linkset + ***********************************************************************/ + +/*! \brief Destroy a SS7 Linkset + * \param[in] lset Linkset to be destroyed */ +void osmo_ss7_linkset_destroy(struct osmo_ss7_linkset *lset) +{ + unsigned int i; + + OSMO_ASSERT(ss7_initialized); + LOGSS7(lset->inst, LOGL_INFO, "Destroying Linkset %s\n", + lset->cfg.name); + + for (i = 0; i < ARRAY_SIZE(lset->links); i++) { + struct osmo_ss7_link *link = lset->links[i]; + if (!link) + continue; + osmo_ss7_link_destroy(link); + } + llist_del(&lset->list); + talloc_free(lset); +} + +/*! \brief Find SS7 Linkset by given name + * \param[in] inst SS7 Instance in which to look + * \param[in] name Name of SS7 Linkset + * \returns pointer to linkset on success; NULL on error */ +struct osmo_ss7_linkset * +osmo_ss7_linkset_find_by_name(struct osmo_ss7_instance *inst, const char *name) +{ + struct osmo_ss7_linkset *lset; + OSMO_ASSERT(ss7_initialized); + llist_for_each_entry(lset, &inst->linksets, list) { + if (!strcmp(name, lset->cfg.name)) + return lset; + } + return NULL; +} + +/*! \brief Find or allocate SS7 Linkset + * \param[in] inst SS7 Instance in which we operate + * \param[in] name Name of SS7 Linkset + * \param[in] pc Adjacent Pointcode + * \returns pointer to Linkset on success; NULL on error */ +struct osmo_ss7_linkset * +osmo_ss7_linkset_find_or_create(struct osmo_ss7_instance *inst, const char *name, uint32_t pc) +{ + struct osmo_ss7_linkset *lset; + + OSMO_ASSERT(ss7_initialized); + lset = osmo_ss7_linkset_find_by_name(inst, name); + if (lset && lset->cfg.adjacent_pc != pc) + return NULL; + + if (!lset) { + LOGSS7(inst, LOGL_INFO, "Creating Linkset %s\n", name); + lset = talloc_zero(inst, struct osmo_ss7_linkset); + lset->inst = inst; + lset->cfg.adjacent_pc = pc; + lset->cfg.name = talloc_strdup(lset, name); + llist_add_tail(&lset->list, &inst->linksets); + } + + return lset; +} + +/*********************************************************************** + * SS7 Link + ***********************************************************************/ + +/*! \brief Destryo SS7 Link + * \param[in] link SS7 Link to be destroyed */ +void osmo_ss7_link_destroy(struct osmo_ss7_link *link) +{ + struct osmo_ss7_linkset *lset = link->linkset; + + OSMO_ASSERT(ss7_initialized); + LOGSS7(lset->inst, LOGL_INFO, "Destroying Link %s:%u\n", + lset->cfg.name, link->cfg.id); + /* FIXME: do cleanup */ + lset->links[link->cfg.id] = NULL; + talloc_free(link); +} + +/*! \brief Find or create SS7 Link with given ID in given Linkset + * \param[in] lset SS7 Linkset on which we operate + * \param[in] id Link number within Linkset + * \returns pointer to SS7 Link on success; NULL on error */ +struct osmo_ss7_link * +osmo_ss7_link_find_or_create(struct osmo_ss7_linkset *lset, uint32_t id) +{ + struct osmo_ss7_link *link; + + OSMO_ASSERT(ss7_initialized); + if (id >= ARRAY_SIZE(lset->links)) + return NULL; + + if (lset->links[id]) { + link = lset->links[id]; + } else { + LOGSS7(lset->inst, LOGL_INFO, "Creating Link %s:%u\n", + lset->cfg.name, id); + link = talloc_zero(lset, struct osmo_ss7_link); + if (!link) + return NULL; + link->linkset = lset; + lset->links[id] = link; + link->cfg.id = id; + } + + return link; +} + + +/*********************************************************************** + * SS7 Route Tables + ***********************************************************************/ + +struct osmo_ss7_route_table * +osmo_ss7_route_table_find(struct osmo_ss7_instance *inst, const char *name) +{ + struct osmo_ss7_route_table *rtbl; + OSMO_ASSERT(ss7_initialized); + llist_for_each_entry(rtbl, &inst->rtable_list, list) { + if (!strcmp(rtbl->cfg.name, name)) + return rtbl; + } + return NULL; +} + +struct osmo_ss7_route_table * +osmo_ss7_route_table_find_or_create(struct osmo_ss7_instance *inst, const char *name) +{ + struct osmo_ss7_route_table *rtbl; + + OSMO_ASSERT(ss7_initialized); + rtbl = osmo_ss7_route_table_find(inst, name); + if (!rtbl) { + LOGSS7(inst, LOGL_INFO, "Creating Route Table %s\n", name); + rtbl = talloc_zero(inst, struct osmo_ss7_route_table); + rtbl->inst = inst; + rtbl->cfg.name = talloc_strdup(rtbl, name); + INIT_LLIST_HEAD(&rtbl->routes); + llist_add_tail(&rtbl->list, &inst->rtable_list); + } + return rtbl; +} + +void osmo_ss7_route_table_destroy(struct osmo_ss7_route_table *rtbl) +{ + llist_del(&rtbl->list); + /* routes are allocated as children of route table, will be + * automatically freed() */ + talloc_free(rtbl); +} + +/*********************************************************************** + * SS7 Routes + ***********************************************************************/ + +/*! \brief Find a SS7 route for given destination point code in given table */ +struct osmo_ss7_route * +osmo_ss7_route_find_dpc(struct osmo_ss7_route_table *rtbl, uint32_t dpc) +{ + struct osmo_ss7_route *rt; + + OSMO_ASSERT(ss7_initialized); + /* we assume the routes are sorted by mask length, i.e. more + * specific routes first, and less specific routes with shorter + * mask later */ + llist_for_each_entry(rt, &rtbl->routes, list) { + if ((dpc & rt->cfg.mask) == rt->cfg.pc) + return rt; + } + return NULL; +} + +/*! \brief Find a SS7 route for given destination point code + mask in given table */ +struct osmo_ss7_route * +osmo_ss7_route_find_dpc_mask(struct osmo_ss7_route_table *rtbl, uint32_t dpc, + uint32_t mask) +{ + struct osmo_ss7_route *rt; + + OSMO_ASSERT(ss7_initialized); + /* we assume the routes are sorted by mask length, i.e. more + * specific routes first, and less specific routes with shorter + * mask later */ + llist_for_each_entry(rt, &rtbl->routes, list) { + if (dpc == rt->cfg.pc && mask == rt->cfg.mask) + return rt; + } + return NULL; +} + +/*! \brief Find a SS7 route for given destination point code in given SS7 */ +struct osmo_ss7_route * +osmo_ss7_route_lookup(struct osmo_ss7_instance *inst, uint32_t dpc) +{ + OSMO_ASSERT(ss7_initialized); + return osmo_ss7_route_find_dpc(inst->rtable_system, dpc); +} + +/* insert the route in the ordered list of routes. The list is sorted by + * mask length, so that the more specific (longer mask) routes are + * first, while the less specific routes with shorter masks are last. + * Hence, the first matching route in a linear iteration is the most + * specific match. */ +static void route_insert_sorted(struct osmo_ss7_route_table *rtbl, + struct osmo_ss7_route *cmp) +{ + struct osmo_ss7_route *rt; + + llist_for_each_entry(rt, &rtbl->routes, list) { + if (rt->cfg.mask < cmp->cfg.mask) { + /* insert before the current entry */ + llist_add(&cmp->list, rt->list.prev); + return; + } + } + /* not added, i.e. no smaller mask length found: we are the + * smallest mask and thus should go last */ + llist_add_tail(&cmp->list, &rtbl->routes); +} + +/*! \brief Create a new route in the given routing table + * \param[in] rtbl Routing Table in which the route is to be created + * \param[in] pc Point Code of the destination of the route + * \param[in] mask Mask of the destination Point Code \ref pc + * \param[in] linkset_name string name of the linkset to be used + * \returns caller-allocated + initialized route, NULL on error + */ +struct osmo_ss7_route * +osmo_ss7_route_create(struct osmo_ss7_route_table *rtbl, uint32_t pc, + uint32_t mask, const char *linkset_name) +{ + struct osmo_ss7_route *rt; + struct osmo_ss7_linkset *lset; + struct osmo_ss7_as *as; + + OSMO_ASSERT(ss7_initialized); + lset = osmo_ss7_linkset_find_by_name(rtbl->inst, linkset_name); + if (!lset) { + as = osmo_ss7_as_find_by_name(rtbl->inst, linkset_name); + if (!as) + return NULL; + } + + rt = talloc_zero(rtbl, struct osmo_ss7_route); + if (!rt) + return NULL; + + rt->cfg.pc = pc; + rt->cfg.mask = mask; + rt->cfg.linkset_name = talloc_strdup(rt, linkset_name); + if (lset) + rt->dest.linkset = lset; + else + rt->dest.as = as; + rt->rtable = rtbl; + + route_insert_sorted(rtbl, rt); + + return rt; +} + +/*! \brief Destroy a given SS7 route */ +void osmo_ss7_route_destroy(struct osmo_ss7_route *rt) +{ + OSMO_ASSERT(ss7_initialized); + llist_del(&rt->list); + talloc_free(rt); +} + +/*********************************************************************** + * SS7 Application Server + ***********************************************************************/ + +/*! \brief Find Application Server by given name + * \param[in] inst SS7 Instance on which we operate + * \param[in] name Name of AS + * \returns pointer to Application Server on success; NULL otherwise */ +struct osmo_ss7_as * +osmo_ss7_as_find_by_name(struct osmo_ss7_instance *inst, const char *name) +{ + struct osmo_ss7_as *as; + + OSMO_ASSERT(ss7_initialized); + llist_for_each_entry(as, &inst->as_list, list) { + if (!strcmp(name, as->cfg.name)) + return as; + } + return NULL; +} + +/*! \brief Find Application Server by given routing context + * \param[in] inst SS7 Instance on which we operate + * \param[in] rctx Routing Context + * \returns pointer to Application Server on success; NULL otherwise */ +struct osmo_ss7_as * +osmo_ss7_as_find_by_rctx(struct osmo_ss7_instance *inst, uint32_t rctx) +{ + struct osmo_ss7_as *as; + + OSMO_ASSERT(ss7_initialized); + llist_for_each_entry(as, &inst->as_list, list) { + if (as->cfg.routing_key.context == rctx) + return as; + } + return NULL; +} + +/*! \brief Find or Create Application Server + * \param[in] inst SS7 Instance on which we operate + * \param[in] name Name of Application Server + * \param[in] proto Protocol of Application Server + * \returns pointer to Application Server on suuccess; NULL otherwise */ +struct osmo_ss7_as * +osmo_ss7_as_find_or_create(struct osmo_ss7_instance *inst, const char *name, + enum osmo_ss7_asp_protocol proto) +{ + struct osmo_ss7_as *as; + + OSMO_ASSERT(ss7_initialized); + as = osmo_ss7_as_find_by_name(inst, name); + + if (as && as->cfg.proto != proto) + return NULL; + + if (!as) { + LOGSS7(inst, LOGL_INFO, "Creating AS %s\n", name); + as = talloc_zero(inst, struct osmo_ss7_as); + if (!as) + return NULL; + as->inst = inst; + as->cfg.name = talloc_strdup(as, name); + as->cfg.proto = proto; + as->cfg.mode = OSMO_SS7_AS_TMOD_LOADSHARE; + as->cfg.recovery_timeout_msec = 2000; + as->fi = xua_as_fsm_start(as, LOGL_DEBUG); + llist_add_tail(&as->list, &inst->as_list); + } + + return as; +} + +/*! \brief Add given ASP to given AS + * \param[in] as Application Server to which \ref asp is added + * \param[in] asp Application Server Process to be added to \ref as + * \returns 0 on success; negative in case of error */ +int osmo_ss7_as_add_asp(struct osmo_ss7_as *as, const char *asp_name) +{ + struct osmo_ss7_asp *asp; + unsigned int i; + + OSMO_ASSERT(ss7_initialized); + asp = osmo_ss7_asp_find_by_name(as->inst, asp_name); + if (!asp) + return -ENODEV; + + LOGSS7(as->inst, LOGL_INFO, "Adding ASP %s to AS %s\n", + asp->cfg.name, as->cfg.name); + + if (osmo_ss7_as_has_asp(as, asp)) + return 0; + + for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) { + if (!as->cfg.asps[i]) { + as->cfg.asps[i] = asp; + return 0; + } + } + + return -ENOSPC; +} + +/*! \brief Delete given ASP from given AS + * \param[in] as Application Server from which \ref asp is deleted + * \param[in] asp Application Server Process to delete from \ref as + * \returns 0 on success; negative in case of error */ +int osmo_ss7_as_del_asp(struct osmo_ss7_as *as, const char *asp_name) +{ + struct osmo_ss7_asp *asp; + unsigned int i; + + OSMO_ASSERT(ss7_initialized); + asp = osmo_ss7_asp_find_by_name(as->inst, asp_name); + if (!asp) + return -ENODEV; + + LOGSS7(as->inst, LOGL_INFO, "Removing ASP %s from AS %s\n", + asp->cfg.name, as->cfg.name); + + for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) { + if (as->cfg.asps[i] == asp) { + as->cfg.asps[i] = NULL; + return 0; + } + } + + return -EINVAL; +} + +/*! \brief Destroy given Application Server + * \param[in] as Application Server to destroy */ +void osmo_ss7_as_destroy(struct osmo_ss7_as *as) +{ + OSMO_ASSERT(ss7_initialized); + LOGSS7(as->inst, LOGL_INFO, "Destroying AS %s\n", as->cfg.name); + + if (as->fi) + osmo_fsm_inst_term(as->fi, OSMO_FSM_TERM_REQUEST, NULL); + + as->inst = NULL; + llist_del(&as->list); + talloc_free(as); +} + +/*! \brief Determine if given AS contains ASP + * \param[in] as Application Server in which to look for \ref asp + * \param[in] asp Application Server Process to look for in \ref as + * \returns true in case \ref asp is part of \ref as; false otherwise */ +bool osmo_ss7_as_has_asp(struct osmo_ss7_as *as, + struct osmo_ss7_asp *asp) +{ + unsigned int i; + + OSMO_ASSERT(ss7_initialized); + for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) { + if (as->cfg.asps[i] == asp) + return true; + } + return false; +} + +/*********************************************************************** + * SS7 Application Server Process + ***********************************************************************/ + +struct osmo_ss7_asp * +osmo_ss7_asp_find_by_name(struct osmo_ss7_instance *inst, const char *name) +{ + struct osmo_ss7_asp *asp; + + OSMO_ASSERT(ss7_initialized); + llist_for_each_entry(asp, &inst->asp_list, list) { + if (!strcmp(name, asp->cfg.name)) + return asp; + } + return NULL; +} + +static uint16_t get_in_port(struct sockaddr *sa) +{ + switch (sa->sa_family) { + case AF_INET: + return (((struct sockaddr_in*)sa)->sin_port); + case AF_INET6: + return (((struct sockaddr_in6*)sa)->sin6_port); + default: + return 0; + } +} + +/*! \brief Find an ASP definition matching the local+remote IP/PORT of given fd + * \param[in] fd socket descriptor of given socket + * \returns SS7 ASP in case a matching one is found; NULL otherwise */ +static struct osmo_ss7_asp * +osmo_ss7_asp_find_by_socket_addr(int fd) +{ + struct osmo_ss7_instance *inst; + struct sockaddr sa_l, sa_r; + socklen_t sa_len_l = sizeof(sa_l); + socklen_t sa_len_r = sizeof(sa_r); + char hostbuf_l[64], hostbuf_r[64]; + uint16_t local_port, remote_port; + int rc; + + OSMO_ASSERT(ss7_initialized); + /* convert local and remote IP to string */ + rc = getsockname(fd, &sa_l, &sa_len_l); + if (rc < 0) + return NULL; + rc = getnameinfo(&sa_l, sa_len_l, hostbuf_l, sizeof(hostbuf_l), + NULL, 0, NI_NUMERICHOST); + if (rc < 0) + return NULL; + local_port = ntohs(get_in_port(&sa_l)); + + rc = getpeername(fd, &sa_r, &sa_len_r); + if (rc < 0) + return NULL; + rc = getnameinfo(&sa_r, sa_len_r, hostbuf_r, sizeof(hostbuf_r), + NULL, 0, NI_NUMERICHOST); + if (rc < 0) + return NULL; + remote_port = ntohs(get_in_port(&sa_r)); + + /* check all instances for any ASP definition matching the + * address combination of local/remote ip/port */ + llist_for_each_entry(inst, &ss7_instances, list) { + struct osmo_ss7_asp *asp; + llist_for_each_entry(asp, &inst->asp_list, list) { + if (asp->cfg.local.port == local_port && + (!asp->cfg.remote.port ||asp->cfg.remote.port == remote_port) && + (!asp->cfg.local.host || !strcmp(asp->cfg.local.host, hostbuf_l)) && + (!asp->cfg.remote.host || !strcmp(asp->cfg.remote.host, hostbuf_r))) + return asp; + } + } + + return NULL; +} + +struct osmo_ss7_asp * +osmo_ss7_asp_find_or_create(struct osmo_ss7_instance *inst, const char *name, + uint16_t remote_port, uint16_t local_port, + enum osmo_ss7_asp_protocol proto) +{ + struct osmo_ss7_asp *asp; + + OSMO_ASSERT(ss7_initialized); + asp = osmo_ss7_asp_find_by_name(inst, name); + + if (asp && (asp->cfg.remote.port != remote_port || + asp->cfg.local.port != local_port || + asp->cfg.proto != proto)) + return NULL; + + if (!asp) { + /* FIXME: check if local port has SCTP? */ + asp = talloc_zero(inst, struct osmo_ss7_asp); + asp->inst = inst; + asp->cfg.remote.port = remote_port; + asp->cfg.local.port = local_port; + asp->cfg.proto = proto; + asp->cfg.name = talloc_strdup(asp, name); + llist_add_tail(&asp->list, &inst->asp_list); + } + return asp; +} + +void osmo_ss7_asp_destroy(struct osmo_ss7_asp *asp) +{ + struct osmo_ss7_as *as; + + OSMO_ASSERT(ss7_initialized); + LOGSS7(asp->inst, LOGL_INFO, "Destroying ASP %s\n", asp->cfg.name); + + if (asp->server) + osmo_stream_srv_destroy(asp->server); + if (asp->client) + osmo_stream_cli_destroy(asp->client); + if (asp->fi) + osmo_fsm_inst_term(asp->fi, OSMO_FSM_TERM_REQUEST, NULL); + + /* unlink from all ASs we are part of */ + llist_for_each_entry(as, &asp->inst->as_list, list) { + unsigned int i; + for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) { + if (as->cfg.asps[i] == asp) { + as->cfg.asps[i] = NULL; + } + } + } + /* unlink from ss7_instance */ + asp->inst = NULL; + llist_del(&asp->list); + /* release memory */ + talloc_free(asp); +} + +static int xua_cli_read_cb(struct osmo_stream_cli *conn); +static int xua_cli_connect_cb(struct osmo_stream_cli *cli); + +int osmo_ss7_asp_restart(struct osmo_ss7_asp *asp) +{ + int rc; + enum xua_asp_role role; + + OSMO_ASSERT(ss7_initialized); + LOGSS7(asp->inst, LOGL_INFO, "Restarting ASP %s\n", asp->cfg.name); + + if (!asp->cfg.is_server) { + /* We are in client mode now */ + if (asp->server) { + /* if we previously were in server mode, + * destroy it */ + osmo_stream_srv_destroy(asp->server); + asp->server = NULL; + } + if (!asp->client) + asp->client = osmo_stream_cli_create(asp); + if (!asp->client) { + LOGSS7(asp->inst, LOGL_ERROR, "Unable to create stream" + " client for ASP %s\n", asp->cfg.name); + return -1; + } + osmo_stream_cli_set_addr(asp->client, asp->cfg.remote.host); + osmo_stream_cli_set_port(asp->client, asp->cfg.remote.port); + osmo_stream_cli_set_proto(asp->client, IPPROTO_SCTP); + osmo_stream_cli_set_reconnect_timeout(asp->client, 5); + osmo_stream_cli_set_connect_cb(asp->client, xua_cli_connect_cb); + osmo_stream_cli_set_read_cb(asp->client, xua_cli_read_cb); + osmo_stream_cli_set_data(asp->client, asp); + rc = osmo_stream_cli_open2(asp->client, 1); + if (rc < 0) { + LOGSS7(asp->inst, LOGL_ERROR, "Unable to open stream" + " client for ASP %s\n", asp->cfg.name); + } + /* TODO: make this configurable and not implicit */ + role = XUA_ASPFSM_ROLE_ASP; + } else { + /* We are in server mode now */ + if (asp->client) { + /* if we previously were in client mode, + * destroy it */ + osmo_stream_cli_destroy(asp->client); + asp->client = NULL; + } + /* FIXME: ensure we have a SCTP server */ + LOGSS7(asp->inst, LOGL_NOTICE, "ASP Restart for server " + "not implemented yet!\n"); + /* TODO: make this configurable and not implicit */ + role = XUA_ASPFSM_ROLE_SG; + } + + /* (re)start the ASP FSM */ + if (asp->fi) + osmo_fsm_inst_term(asp->fi, OSMO_FSM_TERM_REQUEST, NULL); + asp->fi = xua_asp_fsm_start(asp, role, LOGL_DEBUG); + + return 0; +} + +/*********************************************************************** + * libosmo-netif integration for SCTP stream server/client + ***********************************************************************/ + +static const struct value_string sctp_assoc_chg_vals[] = { + { SCTP_COMM_UP, "COMM_UP" }, + { SCTP_COMM_LOST, "COMM_LOST" }, + { SCTP_RESTART, "RESTART" }, + { SCTP_SHUTDOWN_COMP, "SHUTDOWN_COMP" }, + { SCTP_CANT_STR_ASSOC, "CANT_STR_ASSOC" }, + { 0, NULL } +}; + +static const struct value_string sctp_sn_type_vals[] = { + { SCTP_ASSOC_CHANGE, "ASSOC_CHANGE" }, + { SCTP_PEER_ADDR_CHANGE, "PEER_ADDR_CHANGE" }, + { SCTP_SHUTDOWN_EVENT, "SHUTDOWN_EVENT" }, + { SCTP_SEND_FAILED, "SEND_FAILED" }, + { SCTP_REMOTE_ERROR, "REMOTE_ERROR" }, + { SCTP_PARTIAL_DELIVERY_EVENT, "PARTIAL_DELIVERY_EVENT" }, + { SCTP_ADAPTATION_INDICATION, "ADAPTATION_INDICATION" }, +#ifdef SCTP_AUTHENTICATION_INDICATION + { SCTP_AUTHENTICATION_INDICATION, "UTHENTICATION_INDICATION" }, +#endif +#ifdef SCTP_SENDER_DRY_EVENT + { SCTP_SENDER_DRY_EVENT, "SENDER_DRY_EVENT" }, +#endif + { 0, NULL } +}; + +static int get_logevel_by_sn_type(int sn_type) +{ + switch (sn_type) { + case SCTP_ADAPTATION_INDICATION: + case SCTP_PEER_ADDR_CHANGE: +#ifdef SCTP_AUTHENTICATION_INDICATION + case SCTP_AUTHENTICATION_INDICATION: +#endif +#ifdef SCTP_SENDER_DRY_EVENT + case SCTP_SENDER_DRY_EVENT: +#endif + return LOGL_INFO; + case SCTP_ASSOC_CHANGE: + return LOGL_NOTICE; + case SCTP_SHUTDOWN_EVENT: + case SCTP_PARTIAL_DELIVERY_EVENT: + return LOGL_NOTICE; + case SCTP_SEND_FAILED: + case SCTP_REMOTE_ERROR: + return LOGL_ERROR; + default: + return LOGL_NOTICE; + } +} + +static void log_sctp_notification(struct osmo_ss7_asp *asp, const char *pfx, + union sctp_notification *notif) +{ + int log_level; + + LOGPASP(asp, DLSS7, LOGL_INFO, "%s SCTP NOTIFICATION %u flags=0x%0x\n", + pfx, notif->sn_header.sn_type, + notif->sn_header.sn_flags); + + log_level = get_logevel_by_sn_type(notif->sn_header.sn_type); + + switch (notif->sn_header.sn_type) { + case SCTP_ASSOC_CHANGE: + LOGPASP(asp, DLSS7, log_level, "%s SCTP_ASSOC_CHANGE: %s\n", + pfx, get_value_string(sctp_assoc_chg_vals, + notif->sn_assoc_change.sac_state)); + break; + default: + LOGPASP(asp, DLSS7, log_level, "%s %s\n", + pfx, get_value_string(sctp_sn_type_vals, + notif->sn_header.sn_type)); + break; + } +} + +/* netif code tells us we can read something from the socket */ +static int xua_srv_conn_cb(struct osmo_stream_srv *conn) +{ + struct osmo_fd *ofd = osmo_stream_srv_get_ofd(conn); + struct osmo_ss7_asp *asp = osmo_stream_srv_get_data(conn); + struct msgb *msg = msgb_alloc(ASP_MSGB_SIZE, "xUA Server Rx"); + struct sctp_sndrcvinfo sinfo; + unsigned int ppid; + int flags = 0; + int rc; + + if (!msg) + return -ENOMEM; + + /* read xUA message from socket and process it */ + rc = sctp_recvmsg(ofd->fd, msgb_data(msg), msgb_tailroom(msg), + NULL, NULL, &sinfo, &flags); + LOGPASP(asp, DLSS7, LOGL_DEBUG, "%s(): sctp_recvmsg() returned %d\n", + __func__, rc); + if (rc < 0) { + osmo_stream_srv_destroy(conn); + goto out; + } else if (rc == 0) { + osmo_stream_srv_destroy(conn); + goto out; + } else { + msgb_put(msg, rc); + } + + if (flags & MSG_NOTIFICATION) { + union sctp_notification *notif = (union sctp_notification *) msgb_data(msg); + + log_sctp_notification(asp, "xUA SRV", notif); + + switch (notif->sn_header.sn_type) { + case SCTP_SHUTDOWN_EVENT: + osmo_stream_srv_destroy(conn); + osmo_fsm_inst_dispatch(asp->fi, XUA_ASP_E_SCTP_COMM_DOWN_IND, asp); + break; + default: + break; + } + rc = 0; + goto out; + } + + ppid = ntohl(sinfo.sinfo_ppid); + msgb_sctp_ppid(msg) = ppid; + msgb_sctp_stream(msg) = ntohl(sinfo.sinfo_stream); + msg->dst = asp; + + if (ppid == M3UA_PPID && asp->cfg.proto == OSMO_SS7_ASP_PROT_M3UA) + rc = m3ua_rx_msg(asp, msg); + else { + LOGPASP(asp, DLSS7, LOGL_NOTICE, "SCTP chunk for unknown PPID %u " + "received\n", ppid); + rc = 0; + } + +out: + msgb_free(msg); + return rc; +} + +/* client has established SCTP connection to server */ +static int xua_cli_connect_cb(struct osmo_stream_cli *cli) +{ + struct osmo_fd *ofd = osmo_stream_cli_get_ofd(cli); + struct osmo_ss7_asp *asp = osmo_stream_cli_get_data(cli); + + /* update the socket name */ + osmo_talloc_replace_string(asp, &asp->sock_name, osmo_sock_get_name(asp, ofd->fd)); + + LOGPASP(asp, DLSS7, LOGL_INFO, "Client connected %s\n", asp->sock_name); + + /* Notify the ASP FSM that the connection has just been + * established */ + osmo_fsm_inst_dispatch(asp->fi, XUA_ASP_E_M_ASP_UP_REQ, NULL); + + return 0; +} + +static int xua_cli_read_cb(struct osmo_stream_cli *conn) +{ + struct osmo_fd *ofd = osmo_stream_cli_get_ofd(conn); + struct osmo_ss7_asp *asp = osmo_stream_cli_get_data(conn); + struct msgb *msg = msgb_alloc(ASP_MSGB_SIZE, "xUA Client Rx"); + struct sctp_sndrcvinfo sinfo; + unsigned int ppid; + int flags = 0; + int rc; + + if (!msg) + return -ENOMEM; + + /* read xUA message from socket and process it */ + rc = sctp_recvmsg(ofd->fd, msgb_data(msg), msgb_tailroom(msg), + NULL, NULL, &sinfo, &flags); + LOGPASP(asp, DLSS7, LOGL_DEBUG, "%s(): sctp_recvmsg() returned %d (flags=%d)\n", + __func__, rc, flags); + if (rc < 0) { + osmo_stream_cli_reconnect(conn); + goto out; + } else if (rc == 0) { + osmo_stream_cli_reconnect(conn); + } else { + msgb_put(msg, rc); + } + + if (flags & MSG_NOTIFICATION) { + union sctp_notification *notif = (union sctp_notification *) msgb_data(msg); + + log_sctp_notification(asp, "xUA CLNT", notif); + + switch (notif->sn_header.sn_type) { + case SCTP_SHUTDOWN_EVENT: + osmo_fsm_inst_dispatch(asp->fi, XUA_ASP_E_SCTP_COMM_DOWN_IND, asp); + osmo_stream_cli_reconnect(conn); + break; + default: + break; + } + rc = 0; + goto out; + } + + if (rc == 0) + goto out; + + ppid = ntohl(sinfo.sinfo_ppid); + msgb_sctp_ppid(msg) = ppid; + msgb_sctp_stream(msg) = ntohl(sinfo.sinfo_stream); + msg->dst = asp; + + if (ppid == M3UA_PPID && asp->cfg.proto == OSMO_SS7_ASP_PROT_M3UA) + rc = m3ua_rx_msg(asp, msg); + else { + LOGPASP(asp, DLSS7, LOGL_NOTICE, "SCTP chunk for unknown PPID %u " + "received\n", ppid); + rc = 0; + } + +out: + msgb_free(msg); + return rc; +} + +static int xua_srv_conn_closed_cb(struct osmo_stream_srv *srv) +{ + struct osmo_ss7_asp *asp = osmo_stream_srv_get_data(srv); + + LOGP(DLSS7, LOGL_INFO, "%s: SCTP connection closed\n", + asp ? asp->cfg.name : "?"); + + /* FIXME: somehow notify ASP FSM and everyone else */ + + return 0; +} + + +/* server has accept()ed a new SCTP association, let's find the ASP for + * it (if any) */ +static int xua_accept_cb(struct osmo_stream_srv_link *link, int fd) +{ + struct osmo_xua_server *oxs = osmo_stream_srv_link_get_data(link); + struct osmo_stream_srv *srv; + struct osmo_ss7_asp *asp; + char *sock_name = osmo_sock_get_name(link, fd); + + LOGP(DLSS7, LOGL_INFO, "%s: New SCTP connection accepted\n", + sock_name); + + srv = osmo_stream_srv_create(oxs, link, fd, + xua_srv_conn_cb, + xua_srv_conn_closed_cb, NULL); + if (!srv) { + LOGP(DLSS7, LOGL_ERROR, "%s: Unable to create stream server " + "for SCTP connection\n", sock_name); + close(fd); + talloc_free(sock_name); + return -1; + } + + asp = osmo_ss7_asp_find_by_socket_addr(fd); + if (!asp) { + LOGP(DLSS7, LOGL_NOTICE, "%s: SCTP connection without matching " + "ASP definition, terminating\n", sock_name); + osmo_stream_srv_destroy(srv); + talloc_free(sock_name); + return -1; + } + LOGP(DLSS7, LOGL_INFO, "%s: matched connection to ASP %s\n", + sock_name, asp->cfg.name); + /* update the ASP reference back to the server over which the + * connection came in */ + asp->server = srv; + /* update the ASP socket name */ + if (asp->sock_name) + talloc_free(asp->sock_name); + asp->sock_name = talloc_reparent(link, asp, sock_name); + /* make sure the conn_cb() is called with the asp as private + * data */ + osmo_stream_srv_set_data(srv, asp); + + return 0; +} + +/*! \brief send a fully encoded msgb via a given ASP + * \param[in] asp Application Server Process through which to send + * \param[in] msg message buffer to transmit. Ownership transferred. + * \returns 0 on success; negative in case of error */ +int osmo_ss7_asp_send(struct osmo_ss7_asp *asp, struct msgb *msg) +{ + OSMO_ASSERT(ss7_initialized); + + switch (asp->cfg.proto) { + case OSMO_SS7_ASP_PROT_SUA: + msgb_sctp_ppid(msg) = SUA_PPID; + break; + case OSMO_SS7_ASP_PROT_M3UA: + msgb_sctp_ppid(msg) = M3UA_PPID; + break; + default: + OSMO_ASSERT(0); + } + + if (asp->cfg.is_server) + osmo_stream_srv_send(asp->server, msg); + else + osmo_stream_cli_send(asp->client, msg); + + return 0; +} + +/*********************************************************************** + * SS7 xUA Server + ***********************************************************************/ + +struct osmo_xua_server * +osmo_ss7_xua_server_find(struct osmo_ss7_instance *inst, enum osmo_ss7_asp_protocol proto, + uint16_t local_port) +{ + struct osmo_xua_server *xs; + + OSMO_ASSERT(ss7_initialized); + llist_for_each_entry(xs, &ss7_xua_servers, list) { + if (proto == xs->cfg.proto && + local_port == xs->cfg.local.port) + return xs; + } + return NULL; +} + +/*! \brief create a new xUA server listening to given ip/port + * \param[in] ctx talloc allocation context + * \param[in] proto protocol (xUA variant) to use + * \param[in] local_port local SCTP port to bind/listen to + * \param[in] local_host local IP address to bind/listen to (optional) + * \returns callee-allocated \ref osmo_xua_server in case of success + */ +struct osmo_xua_server * +osmo_ss7_xua_server_create(struct osmo_ss7_instance *inst, enum osmo_ss7_asp_protocol proto, + uint16_t local_port, const char *local_host) +{ + struct osmo_xua_server *oxs = talloc_zero(inst, struct osmo_xua_server); + int rc; + + OSMO_ASSERT(ss7_initialized); + if (!oxs) + return NULL; + + LOGP(DLSS7, LOGL_INFO, "Creating XUA Server %s:%u\n", + local_host, local_port); + + oxs->cfg.proto = proto; + oxs->cfg.local.port = local_port; + oxs->cfg.local.host = talloc_strdup(oxs, local_host); + + oxs->server = osmo_stream_srv_link_create(oxs); + osmo_stream_srv_link_set_data(oxs->server, oxs); + osmo_stream_srv_link_set_accept_cb(oxs->server, xua_accept_cb); + + osmo_stream_srv_link_set_addr(oxs->server, oxs->cfg.local.host); + osmo_stream_srv_link_set_port(oxs->server, oxs->cfg.local.port); + osmo_stream_srv_link_set_proto(oxs->server, IPPROTO_SCTP); + + rc = osmo_stream_srv_link_open(oxs->server); + if (rc < 0) { + osmo_stream_srv_link_destroy(oxs->server); + oxs->server = NULL; + talloc_free(oxs); + } + + oxs->inst = inst; + llist_add_tail(&oxs->list, &ss7_xua_servers); + + return oxs; +} + +int +osmo_ss7_xua_server_set_local_host(struct osmo_xua_server *xs, const char *local_host) +{ + OSMO_ASSERT(ss7_initialized); + if (xs->cfg.local.host) + talloc_free(xs->cfg.local.host); + xs->cfg.local.host = talloc_strdup(xs, local_host); + + osmo_stream_srv_link_set_addr(xs->server, xs->cfg.local.host); + + return 0; +} + +void osmo_ss7_xua_server_destroy(struct osmo_xua_server *xs) +{ + if (xs->server) { + osmo_stream_srv_link_close(xs->server); + osmo_stream_srv_link_destroy(xs->server); + } + /* FIXME: add asp_list to xua_server so we can iterate it here + * and close all connections established in relation with this + * server */ + llist_del(&xs->list); + talloc_free(xs); +} + +bool osmo_ss7_pc_is_local(struct osmo_ss7_instance *inst, uint32_t pc) +{ + OSMO_ASSERT(ss7_initialized); + if (pc == inst->cfg.primary_pc) + return true; + /* FIXME: Secondary and Capability Point Codes */ + return false; +} + +int osmo_ss7_init(void) +{ + if (ss7_initialized) + return 1; + osmo_fsm_register(&xua_as_fsm); + osmo_fsm_register(&xua_asp_fsm); + ss7_initialized = true; + return 0; +} diff --git a/src/osmo_ss7_hmrt.c b/src/osmo_ss7_hmrt.c new file mode 100644 index 0000000..bc2b8e5 --- /dev/null +++ b/src/osmo_ss7_hmrt.c @@ -0,0 +1,219 @@ +/*********************************************************************** + * MTP Level 3 - Signalling message handling (SMH) Figure 23/Q.704 + ***********************************************************************/ + +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include "xua_internal.h" + +/* convert from M3UA message to MTP-TRANSFER.ind osmo_mtp_prim */ +struct osmo_mtp_prim *m3ua_to_xfer_ind(struct xua_msg *xua) +{ + struct osmo_mtp_prim *prim; + struct osmo_mtp_transfer_param *param; + struct xua_msg_part *data_ie = xua_msg_find_tag(xua, M3UA_IEI_PROT_DATA); + struct m3ua_data_hdr *data_hdr; + struct msgb *upmsg = m3ua_msgb_alloc("M3UA MTP-TRANSFER.ind"); + + if (data_ie->len < sizeof(*data_hdr)) { + /* FIXME: ERROR message */ + msgb_free(upmsg); + return NULL; + } + data_hdr = (struct m3ua_data_hdr *) data_ie->dat; + + /* fill primitive */ + prim = (struct osmo_mtp_prim *) msgb_put(upmsg, sizeof(*prim)); + param = &prim->u.transfer; + osmo_prim_init(&prim->oph, MTP_SAP_USER, + OSMO_MTP_PRIM_TRANSFER, + PRIM_OP_INDICATION, upmsg); + + m3ua_dh_to_xfer_param(param, data_hdr); + /* copy data */ + upmsg->l2h = msgb_put(upmsg, data_ie->len - sizeof(*data_hdr)); + memcpy(upmsg->l2h, data_ie->dat+sizeof(*data_hdr), data_ie->len - sizeof(*data_hdr)); + + return prim; +} + +/* convert from MTP-TRANSFER.req to osmo_mtp_prim */ +static struct xua_msg *mtp_prim_to_m3ua(struct osmo_mtp_prim *prim) +{ + struct msgb *msg = prim->oph.msg; + struct xua_msg *xua = xua_msg_alloc(); + struct osmo_mtp_transfer_param *param = &prim->u.transfer; + struct xua_msg_part *data_part; + struct m3ua_data_hdr data_hdr; + + mtp_xfer_param_to_m3ua_dh(&data_hdr, param); + + xua->hdr = XUA_HDR(M3UA_MSGC_XFER, M3UA_XFER_DATA); + /* Network Appearance: Optional */ + /* Routing Context: Conditional */ + /* Protocol Data: Mandatory */ + data_part = talloc_zero(xua, struct xua_msg_part); + data_part->tag = M3UA_IEI_PROT_DATA; + data_part->len = sizeof(data_hdr) + msgb_l2len(msg); + data_part->dat = talloc_size(data_part, data_part->len); + memcpy(data_part->dat, &data_hdr, sizeof(data_hdr)); + memcpy(data_part->dat+sizeof(data_hdr), msgb_l2(msg), msgb_l2len(msg)); + llist_add_tail(&data_part->entry, &xua->headers); + /* Correlation Id: Optional */ + + return xua; +} + +/* delivery given XUA message to given SS7 user */ +static int deliver_to_mtp_user(const struct osmo_ss7_user *osu, + struct xua_msg *xua) +{ + struct osmo_mtp_prim *prim; + + /* Create MTP-TRANSFER.ind and feed to user */ + prim = m3ua_to_xfer_ind(xua); + prim->u.transfer = xua->mtp; + if (!prim) + return -1; + + return osu->prim_cb(&prim->oph, (void *) osu->priv); +} + +/* HMDC -> HMDT: Message for distribution; Figure 25/Q.704 */ +/* This means it is a message we received from remote/L2, and it is to + * be routed to a local user part */ +static int hmdt_message_for_distribution(struct osmo_ss7_instance *inst, struct xua_msg *xua) +{ + struct m3ua_data_hdr *mdh; + const struct osmo_ss7_user *osu; + uint32_t service_ind; + + switch (xua->hdr.msg_class) { + case M3UA_MSGC_XFER: + switch (xua->hdr.msg_type) { + case M3UA_XFER_DATA: + mdh = data_hdr_from_m3ua(xua); + service_ind = mdh->si & 0xf; + break; + default: + LOGP(DLSS7, LOGL_ERROR, "Unknown M3UA XFER Message " + "Type %u\n", xua->hdr.msg_type); + return -1; + } + break; + case M3UA_MSGC_SNM: + /* FIXME */ + /* FIXME: SI = Signalling Network Management -> SRM/SLM/STM */ + /* FIXME: SI = Signalling Network Testing and Maintenance -> SLTC */ + default: + /* Discard Message */ + LOGP(DLSS7, LOGL_ERROR, "Unknown M3UA Message Class %u\n", + xua->hdr.msg_class); + return -1; + } + + /* Check for local SSN registered for this DPC/SSN */ + osu = inst->user[service_ind]; + if (osu) { + return deliver_to_mtp_user(osu, xua); + } else { + LOGP(DLSS7, LOGL_NOTICE, "No MTP-User for SI %u\n", service_ind); + /* Discard Message */ + /* FIXME: User Part Unavailable HMDT -> HMRT */ + return -1; + } +} + +/* HMDC->HMRT Msg For Routing; Figure 26/Q.704 */ +/* local message was receive d from L4, SRM, SLM, STM or SLTC, or + * remote message received from L2 and HMDC determined msg for routing */ +static int hmrt_message_for_routing(struct osmo_ss7_instance *inst, + struct xua_msg *xua) +{ + uint32_t dpc = xua->mtp.dpc; + struct osmo_ss7_route *rt; + + /* find route for DPC */ + /* FIXME: unify with gen_mtp_transfer_req_xua() */ + rt = osmo_ss7_route_lookup(inst, dpc); + if (rt) { + /* FIXME: DPC SP restart? */ + /* FIXME: DPC Congested? */ + /* FIXME: Select link based on SLS */ + /* FIXME: Transmit over respective Link */ + if (rt->dest.as) { + struct osmo_ss7_as *as = rt->dest.as; + switch (as->cfg.proto) { + case OSMO_SS7_ASP_PROT_M3UA: + return m3ua_tx_xua_as(as,xua); + default: + LOGP(DLSS7, LOGL_ERROR, "MTP message " + "for ASP of unknown protocol%u\n", + as->cfg.proto); + break; + } + } else if (rt->dest.linkset) { + LOGP(DLSS7, LOGL_ERROR, "MTP-TRANSFER.req for linkset" + "%s unsupported\n",rt->dest.linkset->cfg.name); + } else + OSMO_ASSERT(0); + } else { + LOGP(DLSS7, LOGL_ERROR, "MTP-TRANSFER.req for DPC %u: " + "no route!\n", dpc); + /* DPC unknown HMRT -> MGMT */ + /* Message Received for inaccesible SP HMRT ->RTPC */ + /* Discard Message */ + } + return -1; +} + +/* HMDC: Received Message L2 -> L3; Figure 24/Q.704 */ +/* This means a message was received from L2 and we have to decide if it + * is for the local stack (HMDT) or for routng (HMRT) */ +int m3ua_hmdc_rx_from_l2(struct osmo_ss7_instance *inst, struct xua_msg *xua) +{ + uint32_t dpc = xua->mtp.dpc; + if (osmo_ss7_pc_is_local(inst, dpc)) { + return hmdt_message_for_distribution(inst, xua); + } else { + return hmrt_message_for_routing(inst, xua); + } +} + +/* MTP-User requests to send a MTP-TRANSFER.req via the stack */ +int osmo_ss7_user_mtp_xfer_req(struct osmo_ss7_instance *inst, + struct osmo_mtp_prim *omp) +{ + struct xua_msg *xua; + + OSMO_ASSERT(omp->oph.sap == MTP_SAP_USER); + + switch (OSMO_PRIM_HDR(&omp->oph)) { + case OSMO_PRIM(OSMO_MTP_PRIM_TRANSFER, PRIM_OP_REQUEST): + xua = mtp_prim_to_m3ua(omp); + xua->mtp = omp->u.transfer; + /* normally we would call hmrt_message_for_routing() + * here, if we were to follow the state diagrams of the + * ITU-T Q.70x specifications. However, what if a local + * MTP user sends a MTP-TRANSFER.req to a local SSN? + * This wouldn't work as per the spec, but I believe it + * is a very useful feature (aka "loopback device" in + * IPv4). So we call m3ua_hmdc_rx_from_l2() just like + * the MTP-TRANSFER had been received from L2. */ + return m3ua_hmdc_rx_from_l2(inst, xua); + default: + LOGP(DLSS7, LOGL_ERROR, "Ignoring unknown primitive %u:%u\n", + omp->oph.primitive, omp->oph.operation); + return -1; + } +} diff --git a/src/osmo_ss7_vty.c b/src/osmo_ss7_vty.c new file mode 100644 index 0000000..80cd4d0 --- /dev/null +++ b/src/osmo_ss7_vty.c @@ -0,0 +1,681 @@ +/* Core SS7 Instance/Linkset/Link/AS/ASP VTY Interface */ + +/* (C) 2015-2017 by Harald Welte + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include + +#define CS7_STR "ITU-T Signaling System 7\n" +#define PC_STR "Point Code\n" + +/*********************************************************************** + * Core CS7 Configuration + ***********************************************************************/ + +static const struct value_string ss7_network_indicator_vals[] = { + { 0, "international" }, + { 1, "spare" }, + { 2, "national" }, + { 3, "reserved" }, + { 0, NULL } +}; + +/* cs7 network-indicator */ +DEFUN(cs7_net_ind, cs7_net_ind_cmd, + "cs7 network-indicator (international | national | reserved | spare)", + CS7_STR "Configure the Network Indicator\n" + "International Network\n" + "National Network\n" + "Reserved Network\n" + "Spare Network\n") +{ + struct osmo_ss7_instance *inst = FIXME; + int ni = get_string_value(ss7_network_indicator_vals, argv[0]); + + inst->cfg.network_indicator = ni; + return CMD_SUCCESS; +} + +/* TODO: cs7 point-code format */ +DEFUN(cs7_pc_format, cs7_pc_format_cmd, + "cs7 point-code format <1-24> [<1-23> [<1-22>]]", + CS7_STR PC_STR "Configure Point Code Format\n" + "Length of first PC component\n" + "Length of second PC component\n" + "Length of third PC component\n") +{ + struct osmo_ss7_instance *inst = FIXME; + int argind = 0; + + inst->cfg.pc_fmt.component_len[0] = atoi(argv[argind++]); + + if (argc >= 2) + inst->cfg.pc_fmt.component_len[1] = atoi(argv[argind++]); + else + inst->cfg.pc_fmt.component_len[1] = 0; + + if (argc >= 3) + inst->cfg.pc_fmt.component_len[2] = atoi(argv[argind++]); + else + inst->cfg.pc_fmt.component_len[2] = 0; + + return CMD_SUCCESS; +} + +DEFUN(cs7_pc_format_def, cs7_pc_format_def_cmd, + "cs7 point-code format default", + CS7_STR PC_STR "Configure Point Code Format\n" + "Default Point Code Format (3.8.3)\n") +{ + struct osmo_ss7_instance *inst = FIXME; + inst->cfg.pc_fmt.component_len[0] = 3; + inst->cfg.pc_fmt.component_len[1] = 8; + inst->cfg.pc_fmt.component_len[2] = 3; + return CMD_SUCCESS; +} + + +/* cs7 point-code delimiter */ +DEFUN(cs7_pc_delimiter, cs7_pc_delimiter_cmd, + "cs7 point-code delimiter (default|dash)", + CS7_STR PC_STR "Configure Point Code Delimiter\n" + "Use dot as delimiter\n" + "User dash as delimiter\n") +{ + struct osmo_ss7_instance *inst = FIXME; + + if (!strcmp(argv[0], "dash")) + inst->cfg.pc_fmt.delimiter = '-'; + else + inst->cfg.pc_fmt.delimiter = '.'; + + return CMD_SUCCESS; +} + +DEFUN(cs7_point_code, cs7_point_code_cmd, + "cs7 point-code POINT_CODE", + CS7_STR "Configure the local Point Code\n" + "Point Code\n") +{ + struct osmo_ss7_instance *inst = FIXME; + uint32_t pc = osmo_ss7_pointcode_parse(inst, argv[0]); + + inst->cfg.primary_pc = pc; + return CMD_SUCCESS; +} +/* TODO: cs7 secondary-pc */ +/* TODO: cs7 capability-pc */ + + +/*********************************************************************** + * Routing Table Configuration + ***********************************************************************/ + +static struct cmd_node rtable_node = { + L_CS7_RTABLE_NODE, + "%s(config-cs7-rt)# ", + 1, +}; + +DEFUN(cs7_route_table, cs7_route_table_cmd, + "cs7 route-table system", + CS7_STR "Specify the name of the route table\n" + "Name of the route table\n") +{ + struct osmo_ss7_instance *inst = FIXME; + struct osmo_ss7_route_table *rtable; + + rtable = inst->rtable_system; + vty->node = L_CS7_RTABLE_NODE; + vty->index = rtable; + vty->index_sub = &rtable->cfg.description; + + return CMD_SUCCESS; +} + +DEFUN(cs7_rt_upd, cs7_rt_upd_cmd, + "update route POINT_CODE [MASK | LENGTH] linkset LS_NAME [priority PRIO] [qos-class (CLASS | default", + "Update the Route\n" + "Update the Route\n" + "Destination Point Code\n" + "Point Code Mask\n" + "Point Code Length\n" + "Specify Destination Linkset\n" + "Linkset Name\n" + "Specity Priority\n" + "Priority\n" + "Specify QoS Class\n" + "QoS Class\n" + "Default QoS Class\n") +{ + struct osmo_ss7_route_table *rtable = vty->index; + struct osmo_ss7_route *rt; + uint32_t dpc = osmo_ss7_pointcode_parse(rtable->inst, argv[0]); + uint32_t mask = osmo_ss7_pointcode_parse_mask_or_len(rtable->inst, argv[1]); + const char *ls_name = argv[2]; + unsigned int argind; + + rt = osmo_ss7_route_create(rtable, dpc, mask, ls_name); + if (!rt) + return CMD_WARNING; + + argind = 3; + if (argc > argind && !strcmp(argv[argind], "priority")) { + argind++; + rt->cfg.priority = atoi(argv[argind++]); + } + + if (argc > argind && !strcmp(argv[argind], "qos-class")) { + argind++; + rt->cfg.qos_class = atoi(argv[argind++]); + } + + return CMD_SUCCESS; +} + +DEFUN(cs7_rt_rem, cs7_rt_rem_cmd, + "remove route POINT_CODE [MASK | LENGTH]", + "Remove a Route\n" + "Remove a Route\n" + "Destination Point Code\n" + "Point Code Mask\n" + "Point Code Length\n") +{ + struct osmo_ss7_route_table *rtable = vty->index; + struct osmo_ss7_route *rt; + uint32_t dpc = osmo_ss7_pointcode_parse(rtable->inst, argv[0]); + uint32_t mask = osmo_ss7_pointcode_parse_mask_or_len(rtable->inst, argv[1]); + + rt = osmo_ss7_route_find_dpc_mask(rtable, dpc, mask); + if (!rt) + return CMD_WARNING; + + osmo_ss7_route_destroy(rt); + return CMD_SUCCESS; +} + +static int config_write_rtable(struct vty *vty) +{ + struct osmo_ss7_route_table *rtable = vty->index; + struct osmo_ss7_route *rt; + + vty_out(vty, "cs7 route-table %s%s", rtable->cfg.name, VTY_NEWLINE); + llist_for_each_entry(rt, &rtable->routes, list) { + vty_out(vty, " update route %s %s linkset %s", + osmo_ss7_pointcode_print(rtable->inst, rt->cfg.pc), + osmo_ss7_pointcode_print(rtable->inst, rt->cfg.mask), + rt->cfg.linkset_name); + if (rt->cfg.priority) + vty_out(vty, " priority %u", rt->cfg.priority); + if (rt->cfg.qos_class) + vty_out(vty, " qos-class %u", rt->cfg.qos_class); + vty_out(vty, "%s", VTY_NEWLINE); + } + return 0; +} + +/*********************************************************************** + * SUA Configuration + ***********************************************************************/ + +static struct cmd_node sua_node = { + L_CS7_SUA_NODE, + "%s(config-cs7-sua)# ", + 1, +}; + +DEFUN(cs7_sua, cs7_sua_cmd, + "cs7 sua <0-65534>", + CS7_STR + "Configure/Enable SUA\n" + "SCTP Port number for SUA\n") +{ + struct osmo_ss7_instance *inst = FIXME; + struct osmo_xua_server *xs; + uint16_t port = atoi(argv[0]); + + xs = osmo_ss7_xua_server_find(inst, OSMO_SS7_ASP_PROT_SUA, port); + if (!xs) { + xs = osmo_ss7_xua_server_create(inst, OSMO_SS7_ASP_PROT_SUA, port, NULL); + if (!xs) + return CMD_SUCCESS; + } + + vty->node = L_CS7_SUA_NODE; + vty->index = xs; + return CMD_SUCCESS; +} + +DEFUN(sua_local_ip, sua_local_ip_cmd, + "local-ip A.B.C.D", + "Configure the Local IP Address for SUA\n" + "IP Address to use for SUA\n") +{ + struct osmo_xua_server *xs = vty->index; + + osmo_ss7_xua_server_set_local_host(xs, argv[0]); + return CMD_SUCCESS; +} + +enum osmo_ss7_asp_protocol parse_asp_proto(const char *protocol) +{ + return get_string_value(osmo_ss7_asp_protocol_vals, protocol); +} + +static int config_write_sua(struct vty *vty) +{ + struct osmo_xua_server *xs = vty->index; + + vty_out(vty, "cs7 sua %u%s", xs->cfg.local.port, VTY_NEWLINE); + vty_out(vty, " local-ip %s%s", xs->cfg.local.host, VTY_NEWLINE); + return 0; +} + +/*********************************************************************** + * M3UA Configuration + ***********************************************************************/ + +static struct cmd_node m3ua_node = { + L_CS7_M3UA_NODE, + "%s(config-cs7-m3ua)# ", + 1, +}; + +DEFUN(cs7_m3ua, cs7_m3ua_cmd, + "cs7 m3ua <0-65534>", + CS7_STR + "Configure/Enable M3UA\n" + "SCTP Port number for M3UA\n") +{ + struct osmo_ss7_instance *inst = FIXME; + struct osmo_xua_server *xs; + uint16_t port = atoi(argv[0]); + + xs = osmo_ss7_xua_server_find(inst, OSMO_SS7_ASP_PROT_M3UA, port); + if (!xs) { + xs = osmo_ss7_xua_server_create(inst, OSMO_SS7_ASP_PROT_M3UA, port, NULL); + if (!xs) + return CMD_SUCCESS; + } + + vty->node = L_CS7_M3UA_NODE; + vty->index = xs; + return CMD_SUCCESS; +} + +DEFUN(m3ua_local_ip, m3ua_local_ip_cmd, + "local-ip A.B.C.D", + "Configure the Local IP Address for M3UA\n" + "IP Address to use for M3UA\n") +{ + struct osmo_xua_server *xs = vty->index; + + osmo_ss7_xua_server_set_local_host(xs, argv[0]); + return CMD_SUCCESS; +} + +static int config_write_m3ua(struct vty *vty) +{ + struct osmo_xua_server *xs = vty->index; + + vty_out(vty, "cs7 m3ua %u%s", xs->cfg.local.port, VTY_NEWLINE); + vty_out(vty, " local-ip %s%s", xs->cfg.local.host, VTY_NEWLINE); + return 0; +} + +/*********************************************************************** + * Application Server Process + ***********************************************************************/ + +static struct cmd_node asp_node = { + L_CS7_ASP_NODE, + "%s(config-cs7-asp)# ", + 1, +}; + +DEFUN(cs7_asp, cs7_asp_cmd, + "cs7 asp NAME <0-65535> <0-65535> [m3ua | sua]", + CS7_STR + "Configure Application Server Process\n" + "Name of ASP\n" + "Remote SCTP port number\n" + "Local SCTP port number\n" + "M3UA Protocol\n" + "SUA Protocol\n") +{ + struct osmo_ss7_instance *inst = FIXME; + const char *name = argv[0]; + uint16_t remote_port = atoi(argv[1]); + uint16_t local_port = atoi(argv[2]); + enum osmo_ss7_asp_protocol protocol = parse_asp_proto(argv[3]); + struct osmo_ss7_asp *asp; + + if (protocol == OSMO_SS7_ASP_PROT_NONE) + return CMD_WARNING; + + asp = osmo_ss7_asp_find_or_create(inst, name, remote_port, local_port, protocol); + if (!asp) + return CMD_WARNING; + + vty->node = L_CS7_ASP_NODE; + vty->index = asp; + vty->index_sub = &asp->cfg.description; + return CMD_SUCCESS; +} + +DEFUN(asp_remote_ip, asp_remote_ip_cmd, + "remote-ip A.B.C.D", + "Specity Remote IP Address of ASP\n" + "Remote IP Address of ASP\n") +{ + struct osmo_ss7_asp *asp = vty->index; + osmo_talloc_replace_string(asp, &asp->cfg.remote.host, argv[0]); + return CMD_SUCCESS; +} + +DEFUN(asp_qos_clas, asp_qos_class_cmd, + "qos-class <0-255>", + "Specity QoS Class of ASP\n" + "QoS Class of ASP\n") +{ + struct osmo_ss7_asp *asp = vty->index; + asp->cfg.qos_class = atoi(argv[0]); + return CMD_SUCCESS; +} + +DEFUN(asp_block, asp_block_cmd, + "block", + "Allows a SCTP Association with ASP, but doesn't let it become active\n") +{ + struct osmo_ss7_asp *asp = vty->index; + vty_out(vty, "Not supported yet\n"); + return CMD_WARNING; +} + +DEFUN(asp_shutdown, asp_shutdown_cmd, + "shutdown", + "Terminates SCTP association; New associations will be rejected\n") +{ + struct osmo_ss7_asp *asp = vty->index; + vty_out(vty, "Not supported yet\n"); + return CMD_WARNING; +} + +static int config_write_asp(struct vty *vty) +{ + struct osmo_ss7_asp *asp = vty->index; + + vty_out(vty, "cs7 asp %s %u %u %s%s", + asp->cfg.name, asp->cfg.remote.port, asp->cfg.local.port, + osmo_ss7_asp_protocol_name(asp->cfg.proto), VTY_NEWLINE); + vty_out(vty, " remote-ip %s%s", asp->cfg.remote.host, VTY_NEWLINE); + if (asp->cfg.qos_class) + vty_out(vty, " qos-class %u%s", asp->cfg.qos_class, VTY_NEWLINE); + return 0; +} + +/*********************************************************************** + * Application Server + ***********************************************************************/ + +static struct cmd_node as_node = { + L_CS7_AS_NODE, + "%s(config-cs7-as)# ", + 1, +}; + +DEFUN(cs7_as, cs7_as_cmd, + "cs7 as NAME [m3ua | sua]", + CS7_STR + "Configure an Application Server\n" + "Name of the Application Server\n" + "M3UA Application Server\n" + "SUA Application Server\n") +{ + struct osmo_ss7_as *as; + const char *name = argv[0]; + enum osmo_ss7_asp_protocol protocol = parse_asp_proto(argv[1]); + + if (protocol == OSMO_SS7_ASP_PROT_NONE) + return CMD_WARNING; + + /* FIXME */ + as->cfg.name = talloc_strdup(as, name); + + vty->node = L_CS7_AS_NODE; + vty->index = as; + vty->index_sub = &as->cfg.description; + + return CMD_SUCCESS; +} + +/* TODO: routing-key */ +DEFUN(as_asp, as_asp_cmd, + "asp NAME", + "Specify that a given ASP is part of this AS\n" + "Name of ASP to be added to AS\n") +{ + struct osmo_ss7_as *as = vty->index; + + if (osmo_ss7_as_add_asp(as, argv[0])) + return CMD_WARNING; + + return CMD_SUCCESS; +} + +DEFUN(as_no_asp, as_no_asp_cmd, + "no asp NAME", + NO_STR "Specify ASP to be removed from this AS\n" + "Name of ASP to be removed\n") +{ + struct osmo_ss7_as *as = vty->index; + + if (osmo_ss7_as_del_asp(as, argv[0])) + return CMD_WARNING; + + return CMD_SUCCESS; +} + +DEFUN(as_traf_mode, as_traf_mode_cmd, + "traffic-mode (broadcast | loadshare | roundrobin | override)", + "Specifies traffic mode of operation of the ASP within the AS\n" + "Broadcast to all ASP within AS\n" + "Share Load among all ASP within AS\n" + "Round-Robin between all ASP within AS\n" + "Override\n") +{ + struct osmo_ss7_as *as = vty->index; + + as->cfg.mode = get_string_value(osmo_ss7_as_traffic_mode_vals, argv[0]); + return CMD_WARNING; +} + +DEFUN(as_recov_tout, as_recov_tout_cmd, + "recovery-timeout <1-2000>", + "Specifies the recovery timeout value in milliseconds\n" + "Recovery Timeout in Milliseconds\n") +{ + struct osmo_ss7_as *as = vty->index; + as->cfg.recovery_timeout_msec = atoi(argv[0]); + return CMD_SUCCESS; +} + +DEFUN(as_qos_clas, as_qos_class_cmd, + "qos-class <0-255>", + "Specity QoS Class of AS\n" + "QoS Class of AS\n") +{ + struct osmo_ss7_as *as = vty->index; + as->cfg.qos_class = atoi(argv[0]); + return CMD_SUCCESS; +} + +const struct value_string mtp_si_vals[] = { + { MTP_SI_SCCP, "sccp" }, + { MTP_SI_TUP, "tup" }, + { MTP_SI_ISUP, "isup" }, + { MTP_SI_DUP, "dup" }, + { MTP_SI_TESTING, "testing" }, + { MTP_SI_B_ISUP, "b-isup" }, + { MTP_SI_SAT_ISUP, "sat-isup" }, + { MTP_SI_AAL2_SIG, "aal2" }, + { MTP_SI_BICC, "bicc" }, + { MTP_SI_GCP, "h248" }, + { 0, NULL } +}; + +DEFUN(as_rout_key, as_rout_key_cmd, + "routing-key RCONTEXT DPC [si {aal2 | bicc | b-isup | h248 | isup | sat-isup | sccp | tup }] [ssn SSN]}", + "Define a routing key\n" + "Routing context number\n" + "Destination Point Code\n" + "Optional Match on Service Indicator\n" + "ATM Adaption Layer 2\n" + "Bearer Independent Call Control\n" + "Broadband ISDN User Part\n" + "H.248\n" + "ISDN User Part\n" + "Sattelite ISDN User Part\n" + "Signalling Connection Control Part\n" + "Telephony User Part\n" + "Optional Match on Sub-System Number\n" + "Sub-System Number to match on\n") +{ + struct osmo_ss7_as *as = vty->index; + uint32_t key = atoi(argv[0]); + struct osmo_ss7_routing_key *rkey; + int argind; + + rkey = osmo_ss7_rkey_find_or_create(as, key); + if (!rkey) + return CMD_WARNING; + + rkey->pc = osmo_ss7_pointcode_parse(as->inst, argv[1]); + argind = 2; + + if (!strcmp(argv[argind], "si")) { + const char *si_str; + argind++; + si_str = argv[argind++]; + /* parse numeric SI from string */ + rkey->si = get_string_value(mtp_si_vals, si_str); + } + if (!strcmp(argv[argind], "ssn")) { + argind++; + rkey->ssn = atoi(argv[argind]); + } + + return CMD_SUCCESS; +} + +static int config_write_as(struct vty *vty) +{ + struct osmo_ss7_as *as = vty->index; + struct osmo_ss7_routing_key *rkey; + unsigned int i; + + vty_out(vty, "cs7 as %s %s%s", as->cfg.name, + osmo_ss7_asp_protocol_name(as->cfg.proto), VTY_NEWLINE); + for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) { + struct osmo_ss7_asp *asp = as->cfg.asps[i]; + if (!asp) + continue; + vty_out(vty, " asp %s%s", asp->cfg.name, VTY_NEWLINE); + } + if (as->cfg.mode != OSMO_SS7_AS_TMOD_LOADSHARE) + vty_out(vty, " traffic-mode %s%s", + osmo_ss7_as_traffic_mode_name(as->cfg.mode), VTY_NEWLINE); + if (as->cfg.recovery_timeout_msec != 2000) { + vty_out(vty, " recovery-timeout %u%s", + as->cfg.recovery_timeout_msec, VTY_NEWLINE); + } + vty_out(vty, " qos-class %u%s", as->cfg.qos_class, VTY_NEWLINE); + rkey = &as->cfg.routing_key; + vty_out(vty, " routing-key %u %s", rkey->context, + osmo_ss7_pointcode_print(as->inst, rkey->pc)); + if (rkey->si) + vty_out(vty, " si %s", + get_value_string(mtp_si_vals, rkey->si)); + if (rkey->ssn) + vty_out(vty, " ssn %u", rkey->ssn); + vty_out(vty, "%s", VTY_NEWLINE); + + return 0; +} + +int osmo_ss7_vty_init(void) +{ + install_element(CONFIG_NODE, &cs7_net_ind_cmd); + install_element(CONFIG_NODE, &cs7_point_code_cmd); + install_element(CONFIG_NODE, &cs7_pc_format_cmd); + install_element(CONFIG_NODE, &cs7_pc_format_def_cmd); + install_element(CONFIG_NODE, &cs7_pc_delimiter_cmd); + + install_node(&rtable_node, config_write_rtable); + vty_install_default(L_CS7_RTABLE_NODE); + install_element(CONFIG_NODE, &cs7_route_table_cmd); + install_element(L_CS7_RTABLE_NODE, &cfg_description_cmd); + install_element(L_CS7_RTABLE_NODE, &cs7_rt_upd_cmd); + install_element(L_CS7_RTABLE_NODE, &cs7_rt_rem_cmd); + + install_node(&sua_node, config_write_sua); + vty_install_default(L_CS7_SUA_NODE); + install_element(CONFIG_NODE, &cs7_sua_cmd); + install_element(L_CS7_SUA_NODE, &sua_local_ip_cmd); + + install_node(&m3ua_node, config_write_m3ua); + vty_install_default(L_CS7_M3UA_NODE); + install_element(CONFIG_NODE, &cs7_m3ua_cmd); + install_element(L_CS7_M3UA_NODE, &m3ua_local_ip_cmd); + + install_node(&asp_node, config_write_asp); + vty_install_default(L_CS7_ASP_NODE); + install_element(CONFIG_NODE, &cs7_asp_cmd); + install_element(L_CS7_ASP_NODE, &cfg_description_cmd); + install_element(L_CS7_ASP_NODE, &asp_remote_ip_cmd); + install_element(L_CS7_ASP_NODE, &asp_qos_class_cmd); + install_element(L_CS7_ASP_NODE, &asp_block_cmd); + install_element(L_CS7_ASP_NODE, &asp_shutdown_cmd); + + install_node(&as_node, config_write_as); + vty_install_default(L_CS7_AS_NODE); + install_element(CONFIG_NODE, &cs7_as_cmd); + install_element(L_CS7_AS_NODE, &cfg_description_cmd); + install_element(L_CS7_AS_NODE, &as_asp_cmd); + install_element(L_CS7_AS_NODE, &as_no_asp_cmd); + install_element(L_CS7_AS_NODE, &as_traf_mode_cmd); + install_element(L_CS7_AS_NODE, &as_recov_tout_cmd); + install_element(L_CS7_AS_NODE, &as_qos_class_cmd); + install_element(L_CS7_AS_NODE, &as_rout_key_cmd); + + return 0; +} diff --git a/src/xua_as_fsm.c b/src/xua_as_fsm.c new file mode 100644 index 0000000..887a9ec --- /dev/null +++ b/src/xua_as_fsm.c @@ -0,0 +1,308 @@ +/* SCCP M3UA / SUA AS osmo_fsm according to RFC3868 4.3.1 / RFC4666 4.3.2 */ +/* (C) Copyright 2017 by Harald Welte + * + * All Rights reserved. + * + * Based on Erlang implementation xua_as_fsm.erl in osmo-ss7.git + */ + +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "xua_asp_fsm.h" +#include "xua_as_fsm.h" +#include "xua_internal.h" + +static struct msgb *encode_notify(const struct m3ua_notify_params *npar) +{ + struct xua_msg *xua = m3ua_encode_notify(npar); + struct msgb *msg = xua_to_msg(M3UA_VERSION, xua); + xua_msg_free(xua); + return msg; +} + +static int asp_notify_all_as(struct osmo_ss7_as *as, struct m3ua_notify_params *npar) +{ + struct msgb *msg; + unsigned int i, sent = 0; + + /* iterate over all non-DOWN ASPs and send them the message */ + for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) { + struct osmo_ss7_asp *asp = as->cfg.asps[i]; + + if (!asp) + continue; + + if (!asp->fi || asp->fi->state == XUA_ASP_S_DOWN) + continue; + + /* Optional: ASP Identifier (if sent in ASP-UP) */ + if (asp->asp_id_present) { + npar->presence |= NOTIFY_PAR_P_ASP_ID; + npar->asp_id = asp->asp_id; + } else + npar->presence &= ~NOTIFY_PAR_P_ASP_ID; + + /* TODO: Optional Routing Context */ + + msg = encode_notify(npar); + osmo_ss7_asp_send(asp, msg); + sent++; + } + + return sent; +} + + +/*********************************************************************** + * Actual FSM + ***********************************************************************/ + +#define S(x) (1 << (x)) + +enum xua_as_state { + XUA_AS_S_DOWN, + XUA_AS_S_INACTIVE, + XUA_AS_S_ACTIVE, + XUA_AS_S_PENDING, +}; + +static const struct value_string xua_as_event_names[] = { + { XUA_ASPAS_ASP_INACTIVE_IND, "ASPAS-ASP_INACTIVE.ind" }, + { XUA_ASPAS_ASP_DOWN_IND, "ASPAS-ASP_DOWN.ind" }, + { XUA_ASPAS_ASP_ACTIVE_IND, "ASPAS-ASP_ACTIVE.ind" }, + { 0, NULL } +}; + +struct xua_as_fsm_priv { + struct osmo_ss7_as *as; +}; + +/* is any other ASP in this AS in state != DOWN? */ +static bool check_any_other_asp_not_down(struct osmo_ss7_as *as, struct osmo_ss7_asp *asp_cmp) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) { + struct osmo_ss7_asp *asp = as->cfg.asps[i]; + if (!asp) + continue; + + if (asp_cmp == asp) + continue; + + if (asp->fi && asp->fi->state != XUA_ASP_S_DOWN) + return true; + } + + return false; +} + +/* is any other ASP in this AS in state ACTIVE? */ +static bool check_any_other_asp_in_active(struct osmo_ss7_as *as, struct osmo_ss7_asp *asp_cmp) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) { + struct osmo_ss7_asp *asp = as->cfg.asps[i]; + if (!asp) + continue; + + if (asp_cmp == asp) + continue; + + if (asp->fi && asp->fi->state == XUA_ASP_S_ACTIVE) + return true; + } + + return false; +} + + +static void xua_as_fsm_down(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + switch (event) { + case XUA_ASPAS_ASP_INACTIVE_IND: + /* one ASP transitions into ASP-INACTIVE */ + osmo_fsm_inst_state_chg(fi, XUA_AS_S_INACTIVE, 0, 0); + break; + case XUA_ASPAS_ASP_DOWN_IND: + /* ignore */ + break; + } +} + +/* onenter call-back responsible of transmitting NTFY to all ASPs in + * case of AS state changes */ +static void xua_as_fsm_onenter(struct osmo_fsm_inst *fi, uint32_t old_state) +{ + struct xua_as_fsm_priv *xafp = (struct xua_as_fsm_priv *) fi->priv; + struct m3ua_notify_params npar = { + .status_type = M3UA_NOTIFY_T_STATCHG, + }; + + switch (fi->state) { + case XUA_AS_S_INACTIVE: + npar.status_info = M3UA_NOTIFY_I_AS_INACT; + break; + case XUA_AS_S_ACTIVE: + npar.status_info = M3UA_NOTIFY_I_AS_ACT; + break; + case XUA_AS_S_PENDING: + npar.status_info = M3UA_NOTIFY_I_AS_PEND; + break; + default: + return; + } + + asp_notify_all_as(xafp->as, &npar); +}; + +static void xua_as_fsm_inactive(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct xua_as_fsm_priv *xafp = (struct xua_as_fsm_priv *) fi->priv; + struct osmo_ss7_asp *asp = data; + + switch (event) { + case XUA_ASPAS_ASP_DOWN_IND: + /* one ASP transitions into ASP-DOWN */ + if (check_any_other_asp_not_down(xafp->as, asp)) { + /* ignore, we stay AS_INACTIVE */ + } else + osmo_fsm_inst_state_chg(fi, XUA_AS_S_DOWN, 0, 0); + break; + case XUA_ASPAS_ASP_ACTIVE_IND: + /* one ASP transitions into ASP-ACTIVE */ + osmo_fsm_inst_state_chg(fi, XUA_AS_S_ACTIVE, 0, 0); + break; + case XUA_ASPAS_ASP_INACTIVE_IND: + /* ignore */ + break; + } +} + +static void xua_as_fsm_active(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct xua_as_fsm_priv *xafp = (struct xua_as_fsm_priv *) fi->priv; + struct osmo_ss7_asp *asp = data; + + switch (event) { + case XUA_ASPAS_ASP_DOWN_IND: + case XUA_ASPAS_ASP_INACTIVE_IND: + if (check_any_other_asp_in_active(xafp->as, asp)) { + /* ignore, we stay AS_ACTIVE */ + } else { + osmo_fsm_inst_state_chg(fi, XUA_AS_S_PENDING, 0, 0); + /* FIXME: Start T(r) */ + /* FIXME: Queue all signalling messages until + * recovery or T(r) expiry */ + } + break; + case XUA_ASPAS_ASP_ACTIVE_IND: + /* ignore */ + break; + } +} + +static void xua_as_fsm_pending(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + switch (event) { + case XUA_ASPAS_ASP_ACTIVE_IND: + /* one ASP transitions into ASP-ACTIVE */ + osmo_fsm_inst_state_chg(fi, XUA_AS_S_ACTIVE, 0, 0); + break; + case XUA_ASPAS_ASP_INACTIVE_IND: + /* ignore */ + break; + case XUA_ASPAS_ASP_DOWN_IND: + /* ignore */ + break; + } +} + +static const struct osmo_fsm_state xua_as_fsm_states[] = { + [XUA_AS_S_DOWN] = { + .in_event_mask = S(XUA_ASPAS_ASP_INACTIVE_IND) | + S(XUA_ASPAS_ASP_DOWN_IND), + .out_state_mask = S(XUA_AS_S_DOWN) | + S(XUA_AS_S_INACTIVE), + .name = "AS_DOWN", + .action = xua_as_fsm_down, + }, + [XUA_AS_S_INACTIVE] = { + .in_event_mask = S(XUA_ASPAS_ASP_DOWN_IND) | + S(XUA_ASPAS_ASP_ACTIVE_IND) | + S(XUA_ASPAS_ASP_INACTIVE_IND), + .out_state_mask = S(XUA_AS_S_DOWN) | + S(XUA_AS_S_INACTIVE) | + S(XUA_AS_S_ACTIVE), + .name = "AS_INACTIVE", + .action = xua_as_fsm_inactive, + .onenter = xua_as_fsm_onenter, + }, + [XUA_AS_S_ACTIVE] = { + .in_event_mask = S(XUA_ASPAS_ASP_DOWN_IND) | + S(XUA_ASPAS_ASP_INACTIVE_IND) | + S(XUA_ASPAS_ASP_ACTIVE_IND), + .out_state_mask = S(XUA_AS_S_ACTIVE) | + S(XUA_AS_S_PENDING), + .name = "AS_ACTIVE", + .action = xua_as_fsm_active, + .onenter = xua_as_fsm_onenter, + }, + [XUA_AS_S_PENDING] = { + .in_event_mask = S(XUA_ASPAS_ASP_INACTIVE_IND) | + S(XUA_ASPAS_ASP_DOWN_IND) | + S(XUA_ASPAS_ASP_ACTIVE_IND), + .out_state_mask = S(XUA_AS_S_DOWN) | + S(XUA_AS_S_INACTIVE) | + S(XUA_AS_S_ACTIVE) | + S(XUA_AS_S_PENDING), + .name = "AS_PENDING", + .action = xua_as_fsm_pending, + .onenter = xua_as_fsm_onenter, + }, +}; + +struct osmo_fsm xua_as_fsm = { + .name = "XUA_AS", + .states = xua_as_fsm_states, + .num_states = ARRAY_SIZE(xua_as_fsm_states), + .log_subsys = DLSS7, + .event_names = xua_as_event_names, +}; + +/*! \brief Start an AS FSM for a given Application Server + * \param[in] as Application Server for which to start the AS FSM + * \param[in] log_level Logging level for logging of this FSM + * \returns FSM instance in case of success; NULL in case of error */ +struct osmo_fsm_inst *xua_as_fsm_start(struct osmo_ss7_as *as, int log_level) +{ + struct osmo_fsm_inst *fi; + struct xua_as_fsm_priv *xafp; + + fi = osmo_fsm_inst_alloc(&xua_as_fsm, as, NULL, log_level, as->cfg.name); + + xafp = talloc_zero(fi, struct xua_as_fsm_priv); + if (!xafp) { + osmo_fsm_inst_term(fi, OSMO_FSM_TERM_ERROR, NULL); + return NULL; + } + xafp->as = as; + + fi->priv = xafp; + + return fi; +} diff --git a/src/xua_as_fsm.h b/src/xua_as_fsm.h new file mode 100644 index 0000000..3b8e5b7 --- /dev/null +++ b/src/xua_as_fsm.h @@ -0,0 +1,13 @@ +#pragma once + +struct osmo_ss7_as; + +enum xua_as_event { + XUA_ASPAS_ASP_INACTIVE_IND, + XUA_ASPAS_ASP_DOWN_IND, + XUA_ASPAS_ASP_ACTIVE_IND, +}; + +extern struct osmo_fsm xua_as_fsm; + +struct osmo_fsm_inst *xua_as_fsm_start(struct osmo_ss7_as *as, int log_level); diff --git a/src/xua_asp_fsm.c b/src/xua_asp_fsm.c new file mode 100644 index 0000000..80faeb2 --- /dev/null +++ b/src/xua_asp_fsm.c @@ -0,0 +1,610 @@ +/* SCCP M3UA / SUA ASP osmo_fsm according to RFC3868 4.3.1 */ +/* (C) Copyright 2017 by Harald Welte + * + * All Rights reserved. + * + * Based on my earlier Erlang implementation xua_asp_fsm.erl in + * osmo-ss7.git + */ + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "xua_asp_fsm.h" +#include "xua_as_fsm.h" + +#define S(x) (1 << (x)) + +/* The general idea is: + * * translate incoming SUA/M3UA msg_class/msg_type to xua_asp_event + * * propagate state transitions to XUA_AS_FSM via _onenter functiosn + * * notify the Layer Management of any relevant changes + * * + */ + +/* According to RFC3868 Section 8 */ +#define XUA_T_A_SEC 2 +#define XUA_T_R_SEC 2 +#define XUA_T_ACK_SEC 2 +#define XUA_T_BEAT_SEC 30 +#define SUA_T_IAS_SEC (7*60) /* SUA only */ +#define SUA_T_IAR_SEC (15*60) /* SUA only */ + +static const struct value_string xua_asp_role_names[] = { + { XUA_ASPFSM_ROLE_ASP, "ASP" }, + { XUA_ASPFSM_ROLE_SG, "SG" }, + { XUA_ASPFSM_ROLE_IPSP, "IPSP" }, + { 0, NULL } +}; + +static const struct value_string xua_asp_event_names[] = { + { XUA_ASP_E_M_ASP_UP_REQ, "M-ASP_UP.req" }, + { XUA_ASP_E_M_ASP_ACTIVE_REQ, "M-ASP_ACTIVE.req" }, + { XUA_ASP_E_M_ASP_DOWN_REQ, "M-ASP_DOWN.req" }, + { XUA_ASP_E_M_ASP_INACTIVE_REQ, "M-ASP_INACTIVE.req" }, + + { XUA_ASP_E_SCTP_COMM_DOWN_IND, "SCTP-COMM_DOWN.ind" }, + { XUA_ASP_E_SCTP_RESTART_IND, "SCTP-RESTART.ind" }, + + { XUA_ASP_E_ASPSM_ASPUP, "ASPSM-ASP_UP" }, + { XUA_ASP_E_ASPSM_ASPUP_ACK, "ASPSM-ASP_UP_ACK" }, + { XUA_ASP_E_ASPTM_ASPAC, "ASPTM-ASP_AC" }, + { XUA_ASP_E_ASPTM_ASPAC_ACK, "ASPTM-ASP_AC_ACK" }, + { XUA_ASP_E_ASPSM_ASPDN, "ASPSM-ASP_DN" }, + { XUA_ASP_E_ASPSM_ASPDN_ACK, "ASPSM-ASP_DN_ACK" }, + { XUA_ASP_E_ASPTM_ASPIA, "ASPTM-ASP_IA" }, + { XUA_ASP_E_ASPTM_ASPIA_ACK, "ASPTM_ASP_IA_ACK" }, + { 0, NULL } +}; + +struct xua_layer_manager { + osmo_prim_cb prim_cb; +}; + +/* private data structure for each FSM instance */ +struct xua_asp_fsm_priv { + /* pointer back to ASP to which we belong */ + struct osmo_ss7_asp *asp; + /* Role (ASP/SG/IPSP) */ + enum xua_asp_role role; + /* Layer Manager to which we talk */ + struct xua_layer_manager *lm; + + /* routing context[s]: list of 32bit integers */ + /* ACTIVE: traffic mode type, tid label, drn label ? */ + + struct { + struct osmo_timer_list timer; + int out_event; + } t_ack; +}; + +static struct msgb *xlm_msgb_alloc(void) +{ + return msgb_alloc_headroom(2048+128, 128, "xua_asp-xlm msgb"); +} + +/* Send a XUA LM Primitive to the XUA Layer Manager (LM) */ +static int send_xlm_prim(struct osmo_fsm_inst *fi, + enum osmo_xlm_prim_type prim_type, + enum osmo_prim_operation op, + const uint8_t *data, unsigned int data_len) +{ + struct xua_asp_fsm_priv *xafp = fi->priv; + struct msgb *xlmsg; + struct osmo_xlm_prim *prim; + struct xua_layer_manager *lm = xafp->lm; + + if (!lm || !lm->prim_cb) + return 0; + + xlmsg = xlm_msgb_alloc(); + if (!xlmsg) + return -ENOMEM; + prim = (struct osmo_xlm_prim *) msgb_put(xlmsg, sizeof(*prim)); + osmo_prim_init(&prim->oph, XUA_SAP_LM, prim_type, op, xlmsg); + + lm->prim_cb(&prim->oph, xafp->asp); + + return 0; +} + +/* wrapper around send_xlm_prim for primitives without data */ +static int send_xlm_prim_simple(struct osmo_fsm_inst *fi, + enum osmo_xlm_prim_type prim, + enum osmo_prim_operation op) +{ + return send_xlm_prim(fi, prim, op, NULL, 0); +} + +/* ask the xUA implementation to transmit a specific message */ +static int peer_send(struct osmo_fsm_inst *fi, int out_event) +{ + struct xua_asp_fsm_priv *xafp = fi->priv; + struct osmo_ss7_asp *asp = xafp->asp; + struct xua_msg *xua = xua_msg_alloc(); + struct msgb *msg; + + switch (out_event) { + case XUA_ASP_E_ASPSM_ASPUP: + /* RFC 3868 Ch. 3.5.1 */ + xua->hdr = XUA_HDR(SUA_MSGC_ASPSM, SUA_ASPSM_UP); + /* Optional: ASP ID */ + if (asp->asp_id_present) + xua_msg_add_u32(xua, SUA_IEI_ASP_ID, asp->asp_id); + /* Optional: Info String */ + break; + case XUA_ASP_E_ASPSM_ASPUP_ACK: + /* RFC3868 Ch. 3.5.2 */ + xua->hdr = XUA_HDR(SUA_MSGC_ASPSM, SUA_ASPSM_UP_ACK); + /* Optional: Info String */ + break; + case XUA_ASP_E_ASPSM_ASPDN: + /* RFC3868 Ch. 3.5.3 */ + xua->hdr = XUA_HDR(SUA_MSGC_ASPSM, SUA_ASPSM_DOWN); + /* Optional: Info String */ + break; + case XUA_ASP_E_ASPSM_ASPDN_ACK: + /* RFC3868 Ch. 3.5.4 */ + xua->hdr = XUA_HDR(SUA_MSGC_ASPSM, SUA_ASPSM_DOWN_ACK); + /* Optional: Info String */ + break; + case XUA_ASP_E_ASPSM_BEAT: + /* RFC3868 Ch. 3.5.5 */ + xua->hdr = XUA_HDR(SUA_MSGC_ASPSM, SUA_ASPSM_BEAT); + /* Optional: Heartbeat Data */ + break; + case XUA_ASP_E_ASPSM_BEAT_ACK: + /* RFC3868 Ch. 3.5.6 */ + xua->hdr = XUA_HDR(SUA_MSGC_ASPSM, SUA_ASPSM_BEAT_ACK); + /* Optional: Heartbeat Data */ + break; + case XUA_ASP_E_ASPTM_ASPAC: + /* RFC3868 Ch. 3.6.1 */ + xua->hdr = XUA_HDR(SUA_MSGC_ASPTM, SUA_ASPTM_ACTIVE); + /* Optional: Traffic Mode Type */ + /* Optional: Routing Context */ + /* Optional: TID Label */ + /* Optional: DRN Label */ + /* Optional: Info String */ + break; + case XUA_ASP_E_ASPTM_ASPAC_ACK: + /* RFC3868 Ch. 3.6.2 */ + xua->hdr = XUA_HDR(SUA_MSGC_ASPTM, SUA_ASPTM_ACTIVE_ACK); + /* Optional: Traffic Mode Type */ + /* Mandatory: Routing Context */ + //FIXME xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, + /* Optional: Info String */ + break; + case XUA_ASP_E_ASPTM_ASPIA: + /* RFC3868 Ch. 3.6.3 */ + xua->hdr = XUA_HDR(SUA_MSGC_ASPTM, SUA_ASPTM_INACTIVE); + /* Optional: Routing Context */ + /* Optional: Info String */ + break; + case XUA_ASP_E_ASPTM_ASPIA_ACK: + /* RFC3868 Ch. 3.6.4 */ + xua->hdr = XUA_HDR(SUA_MSGC_ASPTM, SUA_ASPTM_INACTIVE_ACK); + /* Optional: Routing Context */ + /* Optional: Info String */ + break; + } + + msg = xua_to_msg(SUA_VERSION, xua); + xua_msg_free(xua); + if (!msg) + return -1; + + return osmo_ss7_asp_send(asp, msg); +} + +static void xua_t_ack_cb(void *data) +{ + struct osmo_fsm_inst *fi = data; + struct xua_asp_fsm_priv *xafp = fi->priv; + + LOGPFSML(fi, LOGL_INFO, "T(ack) callback: re-transmitting event %s\n", + osmo_fsm_event_name(fi->fsm, xafp->t_ack.out_event)); + + /* Re-transmit message */ + peer_send(fi, xafp->t_ack.out_event); + + /* Re-start the timer */ + osmo_timer_schedule(&xafp->t_ack.timer, XUA_T_ACK_SEC, 0); +} + +static int peer_send_and_start_t_ack(struct osmo_fsm_inst *fi, + int out_event) +{ + struct xua_asp_fsm_priv *xafp = fi->priv; + int rc; + + rc = peer_send(fi, out_event); + if (rc < 0) + return rc; + + xafp->t_ack.out_event = out_event; + xafp->t_ack.timer.cb = xua_t_ack_cb, + xafp->t_ack.timer.data = fi; + + osmo_timer_schedule(&xafp->t_ack.timer, XUA_T_ACK_SEC, 0); + + return rc; +} + +static const uint32_t evt_ack_map[_NUM_XUA_ASP_E] = { + [XUA_ASP_E_ASPSM_ASPUP] = XUA_ASP_E_ASPSM_ASPUP_ACK, + [XUA_ASP_E_ASPTM_ASPAC] = XUA_ASP_E_ASPTM_ASPAC_ACK, + [XUA_ASP_E_ASPSM_ASPDN] = XUA_ASP_E_ASPSM_ASPDN_ACK, + [XUA_ASP_E_ASPTM_ASPIA] = XUA_ASP_E_ASPTM_ASPIA_ACK, + [XUA_ASP_E_ASPSM_BEAT] = XUA_ASP_E_ASPSM_BEAT_ACK, +}; + + +/* check if expected message was received + stop t_ack */ +static void check_stop_t_ack(struct osmo_fsm_inst *fi, uint32_t event) +{ + struct xua_asp_fsm_priv *xafp = fi->priv; + int exp_ack; + + if (event >= ARRAY_SIZE(evt_ack_map)) + return; + + exp_ack = evt_ack_map[xafp->t_ack.out_event]; + if (exp_ack && event == exp_ack) { + LOGPFSML(fi, LOGL_DEBUG, "T(ack) stopped\n"); + osmo_timer_del(&xafp->t_ack.timer); + } +} + +#define ENSURE_ASP_OR_IPSP(fi, event) \ + do { \ + struct xua_asp_fsm_priv *_xafp = fi->priv; \ + if (_xafp->role != XUA_ASPFSM_ROLE_ASP && \ + _xafp->role != XUA_ASPFSM_ROLE_IPSP) { \ + LOGPFSML(fi, LOGL_ERROR, "event %s not permitted " \ + "in role %s\n", \ + osmo_fsm_event_name(fi->fsm, event), \ + get_value_string(xua_asp_role_names, _xafp->role));\ + return; \ + } \ + } while(0) + +#define ENSURE_SG_OR_IPSP(fi, event) \ + do { \ + struct xua_asp_fsm_priv *_xafp = fi->priv; \ + if (_xafp->role != XUA_ASPFSM_ROLE_SG && \ + _xafp->role != XUA_ASPFSM_ROLE_IPSP) { \ + LOGPFSML(fi, LOGL_ERROR, "event %s not permitted " \ + "in role %s\n", \ + osmo_fsm_event_name(fi->fsm, event), \ + get_value_string(xua_asp_role_names, _xafp->role));\ + return; \ + } \ + } while(0) + +static void xua_asp_fsm_down(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct xua_asp_fsm_priv *xafp = fi->priv; + struct osmo_ss7_asp *asp = xafp->asp; + struct xua_msg_part *asp_id_ie; + + check_stop_t_ack(fi, event); + + switch (event) { + case XUA_ASP_E_M_ASP_UP_REQ: + /* only if role ASP */ + ENSURE_ASP_OR_IPSP(fi, event); + /* Send M3UA_MSGT_ASPSM_ASPUP and start t_ack */ + peer_send_and_start_t_ack(fi, XUA_ASP_E_ASPSM_ASPUP); + break; + case XUA_ASP_E_ASPSM_ASPUP_ACK: + /* only if role ASP */ + ENSURE_ASP_OR_IPSP(fi, event); + osmo_fsm_inst_state_chg(fi, XUA_ASP_S_INACTIVE, 0, 0); + /* inform layer manager */ + send_xlm_prim_simple(fi, OSMO_XLM_PRIM_M_ASP_UP, + PRIM_OP_CONFIRM); + /* FIXME: This hack should be in layer manager? */ + osmo_fsm_inst_dispatch(fi, XUA_ASP_E_M_ASP_ACTIVE_REQ, NULL); + break; + case XUA_ASP_E_ASPSM_ASPUP: + /* only if role SG */ + ENSURE_SG_OR_IPSP(fi, event); + asp_id_ie = xua_msg_find_tag(data, SUA_IEI_ASP_ID); + /* Optional ASP Identifier: Store for NTFY */ + if (asp_id_ie) { + asp->asp_id = xua_msg_part_get_u32(asp_id_ie); + asp->asp_id_present = true; + } + /* send ACK */ + peer_send(fi, XUA_ASP_E_ASPSM_ASPUP_ACK); + /* transition state and inform layer manager */ + osmo_fsm_inst_state_chg(fi, XUA_ASP_S_INACTIVE, 0, 0); + send_xlm_prim_simple(fi, OSMO_XLM_PRIM_M_ASP_UP, + PRIM_OP_INDICATION); + break; + case XUA_ASP_E_ASPSM_ASPDN: + /* only if role SG */ + ENSURE_SG_OR_IPSP(fi, event); + /* The SGP MUST send an ASP Down Ack message in response + * to a received ASP Down message from the ASP even if + * the ASP is already marked as ASP-DOWN at the SGP. */ + peer_send(fi, XUA_ASP_E_ASPSM_ASPDN_ACK); + break; + } +} + +/* Helper function to dispatch an ASP->AS event to all AS of which this + * ASP is a memmber. Ignores routing contexts for now. */ +static void dispatch_to_all_as(struct osmo_fsm_inst *fi, uint32_t event) +{ + struct xua_asp_fsm_priv *xafp = fi->priv; + struct osmo_ss7_asp *asp = xafp->asp; + struct osmo_ss7_instance *inst = asp->inst; + struct osmo_ss7_as *as; + + if (xafp->role != XUA_ASPFSM_ROLE_SG) + return; + + llist_for_each_entry(as, &inst->as_list, list) { + if (!osmo_ss7_as_has_asp(as, asp)) + continue; + osmo_fsm_inst_dispatch(as->fi, event, asp); + } +} + +static void xua_asp_fsm_down_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state) +{ + dispatch_to_all_as(fi, XUA_ASPAS_ASP_DOWN_IND); +} + +static void xua_asp_fsm_inactive(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + check_stop_t_ack(fi, event); + switch (event) { + case XUA_ASP_E_M_ASP_ACTIVE_REQ: + /* send M3UA_MSGT_ASPTM_ASPAC and start t_ack */ + peer_send_and_start_t_ack(fi, XUA_ASP_E_ASPTM_ASPAC); + break; + case XUA_ASP_E_M_ASP_DOWN_REQ: + /* send M3UA_MSGT_ASPSM_ASPDN and start t_ack */ + peer_send_and_start_t_ack(fi, XUA_ASP_E_ASPSM_ASPDN); + break; + case XUA_ASP_E_ASPTM_ASPAC_ACK: + /* only in role ASP */ + ENSURE_ASP_OR_IPSP(fi, event); + /* transition state and inform layer manager */ + osmo_fsm_inst_state_chg(fi, XUA_ASP_S_ACTIVE, 0, 0); + send_xlm_prim_simple(fi, OSMO_XLM_PRIM_M_ASP_ACTIVE, + PRIM_OP_CONFIRM); + break; + case XUA_ASP_E_ASPSM_ASPDN_ACK: + /* only in role ASP */ + ENSURE_ASP_OR_IPSP(fi, event); + /* transition state and inform layer manager */ + osmo_fsm_inst_state_chg(fi, XUA_ASP_S_DOWN, 0, 0); + send_xlm_prim_simple(fi, OSMO_XLM_PRIM_M_ASP_DOWN, + PRIM_OP_CONFIRM); + break; + case XUA_ASP_E_ASPTM_ASPAC: + /* only in role SG */ + ENSURE_SG_OR_IPSP(fi, event); + /* send ACK */ + peer_send(fi, XUA_ASP_E_ASPTM_ASPAC_ACK); + /* transition state and inform layer manager */ + osmo_fsm_inst_state_chg(fi, XUA_ASP_S_ACTIVE, 0, 0); + send_xlm_prim_simple(fi, OSMO_XLM_PRIM_M_ASP_ACTIVE, + PRIM_OP_INDICATION); + break; + case XUA_ASP_E_ASPSM_ASPDN: + /* only in role SG */ + ENSURE_SG_OR_IPSP(fi, event); + /* send ACK */ + peer_send(fi, XUA_ASP_E_ASPSM_ASPDN_ACK); + /* transition state and inform layer manager */ + osmo_fsm_inst_state_chg(fi, XUA_ASP_S_DOWN, 0, 0); + send_xlm_prim_simple(fi, OSMO_XLM_PRIM_M_ASP_DOWN, + PRIM_OP_INDICATION); + break; + case XUA_ASP_E_ASPSM_ASPUP: + /* only if role SG */ + ENSURE_SG_OR_IPSP(fi, event); + /* If an ASP Up message is received and internally the + * remote ASP is already in the ASP-INACTIVE state, an + * ASP Up Ack message is returned and no further action + * is taken. */ + peer_send(fi, XUA_ASP_E_ASPSM_ASPUP_ACK); + break; + } +} + +static void xua_asp_fsm_inactive_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state) +{ + dispatch_to_all_as(fi, XUA_ASPAS_ASP_INACTIVE_IND); +} + +static void xua_asp_fsm_active(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + check_stop_t_ack(fi, event); + switch (event) { + case XUA_ASP_E_ASPSM_ASPDN_ACK: + /* only in role ASP */ + ENSURE_ASP_OR_IPSP(fi, event); + osmo_fsm_inst_state_chg(fi, XUA_ASP_S_DOWN, 0, 0); + /* inform layer manager */ + send_xlm_prim_simple(fi, OSMO_XLM_PRIM_M_ASP_DOWN, + PRIM_OP_CONFIRM); + break; + case XUA_ASP_E_ASPTM_ASPIA_ACK: + /* only in role ASP */ + ENSURE_ASP_OR_IPSP(fi, event); + osmo_fsm_inst_state_chg(fi, XUA_ASP_S_INACTIVE, 0, 0); + /* inform layer manager */ + send_xlm_prim_simple(fi, OSMO_XLM_PRIM_M_ASP_INACTIVE, + PRIM_OP_CONFIRM); + break; + case XUA_ASP_E_M_ASP_DOWN_REQ: + /* only in role ASP */ + ENSURE_ASP_OR_IPSP(fi, event); + /* send M3UA_MSGT_ASPSM_ASPDN and star t_ack */ + peer_send_and_start_t_ack(fi, XUA_ASP_E_ASPSM_ASPDN); + break; + case XUA_ASP_E_M_ASP_INACTIVE_REQ: + /* only in role ASP */ + ENSURE_ASP_OR_IPSP(fi, event); + /* send M3UA_MSGT_ASPTM_ASPIA and star t_ack */ + peer_send_and_start_t_ack(fi, XUA_ASP_E_ASPTM_ASPIA); + break; + case XUA_ASP_E_ASPTM_ASPIA: + /* only in role SG */ + ENSURE_SG_OR_IPSP(fi, event); + /* send ACK */ + peer_send(fi, XUA_ASP_E_ASPTM_ASPIA_ACK); + /* transition state and inform layer manager */ + osmo_fsm_inst_state_chg(fi, XUA_ASP_S_INACTIVE, 0, 0); + send_xlm_prim_simple(fi, OSMO_XLM_PRIM_M_ASP_INACTIVE, + PRIM_OP_INDICATION); + break; + case XUA_ASP_E_ASPSM_ASPDN: + /* only in role SG */ + ENSURE_SG_OR_IPSP(fi, event); + /* send ACK */ + peer_send(fi, XUA_ASP_E_ASPSM_ASPDN_ACK); + /* transition state and inform layer manager */ + osmo_fsm_inst_state_chg(fi, XUA_ASP_S_DOWN, 0, 0); + send_xlm_prim_simple(fi, OSMO_XLM_PRIM_M_ASP_DOWN, + PRIM_OP_INDICATION); + break; + case XUA_ASP_E_ASPSM_ASPUP: + /* only if role SG */ + ENSURE_SG_OR_IPSP(fi, event); + /* an ASP Up Ack message is returned, as well as + * an Error message ("Unexpected Message), and the + * remote ASP state is changed to ASP-INACTIVE in all + * relevant Application Servers */ + /* FIXME: Send ERROR message */ + osmo_fsm_inst_state_chg(fi, XUA_ASP_S_INACTIVE, 0, 0); + send_xlm_prim_simple(fi, OSMO_XLM_PRIM_M_ASP_INACTIVE, + PRIM_OP_INDICATION); + break; + } +} + +static void xua_asp_fsm_active_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state) +{ + dispatch_to_all_as(fi, XUA_ASPAS_ASP_ACTIVE_IND); +} + +static void xua_asp_allstate(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + switch (event) { + case XUA_ASP_E_SCTP_COMM_DOWN_IND: + case XUA_ASP_E_SCTP_RESTART_IND: + osmo_fsm_inst_state_chg(fi, XUA_ASP_S_DOWN, 0, 0); + send_xlm_prim_simple(fi, OSMO_XLM_PRIM_M_ASP_DOWN, + PRIM_OP_INDICATION); + break; + default: + break; + } +} + +static int xua_asp_fsm_timer_cb(struct osmo_fsm_inst *fi) +{ + /* We don't use the fsm timer, so any calls to this are an error */ + OSMO_ASSERT(0); + return 0; +} + +static const struct osmo_fsm_state xua_asp_states[] = { + [XUA_ASP_S_DOWN] = { + .in_event_mask = S(XUA_ASP_E_M_ASP_UP_REQ) | + S(XUA_ASP_E_ASPSM_ASPUP) | + S(XUA_ASP_E_ASPSM_ASPUP_ACK) | + S(XUA_ASP_E_ASPSM_ASPDN), + .out_state_mask = S(XUA_ASP_S_INACTIVE), + .name = "ASP_DOWN", + .action = xua_asp_fsm_down, + .onenter = xua_asp_fsm_down_onenter, + }, + [XUA_ASP_S_INACTIVE] = { + .in_event_mask = S(XUA_ASP_E_M_ASP_ACTIVE_REQ) | + S(XUA_ASP_E_M_ASP_DOWN_REQ) | + S(XUA_ASP_E_ASPTM_ASPAC) | + S(XUA_ASP_E_ASPTM_ASPAC_ACK) | + S(XUA_ASP_E_ASPSM_ASPDN) | + S(XUA_ASP_E_ASPSM_ASPDN_ACK) | + S(XUA_ASP_E_ASPSM_ASPUP), + .out_state_mask = S(XUA_ASP_S_DOWN) | + S(XUA_ASP_S_ACTIVE), + .name = "ASP_INACTIVE", + .action = xua_asp_fsm_inactive, + .onenter = xua_asp_fsm_inactive_onenter, + }, + [XUA_ASP_S_ACTIVE] = { + .in_event_mask = S(XUA_ASP_E_ASPSM_ASPDN) | + S(XUA_ASP_E_ASPSM_ASPDN_ACK) | + S(XUA_ASP_E_ASPSM_ASPUP) | + S(XUA_ASP_E_ASPTM_ASPIA) | + S(XUA_ASP_E_ASPTM_ASPIA_ACK) | + S(XUA_ASP_E_M_ASP_DOWN_REQ) | + S(XUA_ASP_E_M_ASP_INACTIVE_REQ), + .out_state_mask = S(XUA_ASP_S_INACTIVE) | + S(XUA_ASP_S_DOWN), + .name = "ASP_ACTIVE", + .action = xua_asp_fsm_active, + .onenter = xua_asp_fsm_active_onenter, + }, +}; + + +struct osmo_fsm xua_asp_fsm = { + .name = "XUA_ASP", + .states = xua_asp_states, + .num_states = ARRAY_SIZE(xua_asp_states), + .timer_cb = xua_asp_fsm_timer_cb, + .log_subsys = DLSS7, + .event_names = xua_asp_event_names, + .allstate_event_mask = S(XUA_ASP_E_SCTP_COMM_DOWN_IND) | + S(XUA_ASP_E_SCTP_RESTART_IND), + .allstate_action = xua_asp_allstate, +}; + + +/*! \brief Start a new ASP finite stae machine for given ASP + * \param[in] asp Application Server Process for which to start FSM + * \param[in] role Role (ASP, SG, IPSP) of this FSM + * \param[in] log_level Logging Level for ASP FSM logging + * \returns FSM instance on success; NULL on error */ +struct osmo_fsm_inst *xua_asp_fsm_start(struct osmo_ss7_asp *asp, + enum xua_asp_role role, int log_level) +{ + struct osmo_fsm_inst *fi; + struct xua_asp_fsm_priv *xafp; + + /* allocate as child of AS? */ + fi = osmo_fsm_inst_alloc(&xua_asp_fsm, asp, NULL, log_level, asp->cfg.name); + + xafp = talloc_zero(fi, struct xua_asp_fsm_priv); + if (!xafp) { + osmo_fsm_inst_term(fi, OSMO_FSM_TERM_ERROR, NULL); + return NULL; + } + xafp->role = role; + xafp->asp = asp; + + fi->priv = xafp; + + return fi; +} diff --git a/src/xua_asp_fsm.h b/src/xua_asp_fsm.h new file mode 100644 index 0000000..ea62484 --- /dev/null +++ b/src/xua_asp_fsm.h @@ -0,0 +1,42 @@ +#pragma once + +enum xua_asp_state { + XUA_ASP_S_DOWN, + XUA_ASP_S_INACTIVE, + XUA_ASP_S_ACTIVE, +}; + +enum xua_asp_event { + XUA_ASP_E_M_ASP_UP_REQ, + XUA_ASP_E_M_ASP_ACTIVE_REQ, + XUA_ASP_E_M_ASP_DOWN_REQ, + XUA_ASP_E_M_ASP_INACTIVE_REQ, + + XUA_ASP_E_SCTP_COMM_DOWN_IND, + XUA_ASP_E_SCTP_RESTART_IND, + + XUA_ASP_E_ASPSM_ASPUP, + XUA_ASP_E_ASPSM_ASPUP_ACK, + XUA_ASP_E_ASPTM_ASPAC, + XUA_ASP_E_ASPTM_ASPAC_ACK, + XUA_ASP_E_ASPSM_ASPDN, + XUA_ASP_E_ASPSM_ASPDN_ACK, + XUA_ASP_E_ASPTM_ASPIA, + XUA_ASP_E_ASPTM_ASPIA_ACK, + + XUA_ASP_E_ASPSM_BEAT, + XUA_ASP_E_ASPSM_BEAT_ACK, + + _NUM_XUA_ASP_E +}; + +enum xua_asp_role { + XUA_ASPFSM_ROLE_ASP, + XUA_ASPFSM_ROLE_SG, + XUA_ASPFSM_ROLE_IPSP, +}; + +extern struct osmo_fsm xua_asp_fsm; + +struct osmo_fsm_inst *xua_asp_fsm_start(struct osmo_ss7_asp *asp, + enum xua_asp_role role, int log_level); diff --git a/src/xua_internal.h b/src/xua_internal.h new file mode 100644 index 0000000..66b5a26 --- /dev/null +++ b/src/xua_internal.h @@ -0,0 +1,58 @@ +#pragma once + +#include +#include + +struct osmo_sccp_addr; +struct m3ua_data_hdr; + +int sua_addr_parse_part(struct osmo_sccp_addr *out, + const struct xua_msg_part *param); +int sua_addr_parse(struct osmo_sccp_addr *out, struct xua_msg *xua, uint16_t iei); + +int sua_parse_gt(struct osmo_sccp_gt *gt, const uint8_t *data, unsigned int datalen); + +struct xua_msg *osmo_sccp_to_xua(struct msgb *msg); +struct msgb *osmo_sua_to_sccp(struct xua_msg *xua); + +int sua_tx_xua_as(struct osmo_ss7_as *as, struct xua_msg *xua); + +struct osmo_mtp_prim *m3ua_to_xfer_ind(struct xua_msg *xua); +int m3ua_hmdc_rx_from_l2(struct osmo_ss7_instance *inst, struct xua_msg *xua); +int m3ua_tx_xua_as(struct osmo_ss7_as *as, struct xua_msg *xua); +int m3ua_rx_msg(struct osmo_ss7_asp *asp, struct msgb *msg); + +struct msgb *m3ua_msgb_alloc(const char *name); +struct m3ua_data_hdr *data_hdr_from_m3ua(struct xua_msg *xua); +void m3ua_dh_to_xfer_param(struct osmo_mtp_transfer_param *param, + const struct m3ua_data_hdr *mdh); +void mtp_xfer_param_to_m3ua_dh(struct m3ua_data_hdr *mdh, + const struct osmo_mtp_transfer_param *param); + + +extern const struct xua_msg_class m3ua_msg_class_mgmt; +extern const struct xua_msg_class m3ua_msg_class_snm; +extern const struct xua_msg_class m3ua_msg_class_rkm; +extern const struct xua_msg_class m3ua_msg_class_aspsm; +extern const struct xua_msg_class m3ua_msg_class_asptm; + +extern const struct value_string m3ua_err_names[]; +extern const struct value_string m3ua_ntfy_type_names[]; +extern const struct value_string m3ua_ntfy_stchg_names[]; +extern const struct value_string m3ua_ntfy_other_names[]; + +#define NOTIFY_PAR_P_ASP_ID (1 << 0) +#define NOTIFY_PAR_P_ROUTE_CTX (1 << 1) + +struct m3ua_notify_params { + uint32_t presence; + uint16_t status_type; + uint16_t status_info; + uint32_t asp_id; + uint32_t route_ctx; + char *info_string; +}; + +struct xua_msg *m3ua_encode_notify(const struct m3ua_notify_params *npar); +int m3ua_decode_notify(struct m3ua_notify_params *npar, void *ctx, + const struct xua_msg *xua); diff --git a/tests/Makefile.am b/tests/Makefile.am index 6e9b807..9c251fe 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,4 +1,4 @@ -SUBDIRS = sccp mtp m2ua sigtran +SUBDIRS = sccp mtp m2ua sigtran ss7 # The `:;' works around a Bash 3.2 bug when the output is not writeable. $(srcdir)/package.m4: $(top_srcdir)/configure.ac diff --git a/tests/ss7/Makefile.am b/tests/ss7/Makefile.am new file mode 100644 index 0000000..bcfd354 --- /dev/null +++ b/tests/ss7/Makefile.am @@ -0,0 +1,12 @@ +AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -Wall +AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) + +AM_LDFLAGS = -static +LDADD = $(top_builddir)/src/libosmo-sigtran.la \ + $(LIBOSMOCORE_LIBS) $(LIBOSMONETIF_LIBS) -lsctp + +EXTRA_DIST = ss7_test.ok ss7_test.err + +noinst_PROGRAMS = ss7_test + +ss7_test_SOURCES = ss7_test.c diff --git a/tests/ss7/ss7_test.c b/tests/ss7/ss7_test.c new file mode 100644 index 0000000..24eabc9 --- /dev/null +++ b/tests/ss7/ss7_test.c @@ -0,0 +1,321 @@ +#include "../src/xua_internal.h" +#include "../src/xua_asp_fsm.h" + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +static struct osmo_ss7_instance *s7i; + +static void test_pc_transcode(uint32_t pc) +{ + const char *pc_str = osmo_ss7_pointcode_print(s7i, pc); + uint32_t pc_reenc = osmo_ss7_pointcode_parse(s7i, pc_str); + + printf("%s(%u) -> %s -> %u\n", __func__, pc, pc_str, pc_reenc); + OSMO_ASSERT(pc == pc_reenc); +} + +static void test_pc_defaults(void) +{ + /* ensure the default point code format settings apply */ + OSMO_ASSERT(s7i->cfg.pc_fmt.component_len[0] == 3); + OSMO_ASSERT(s7i->cfg.pc_fmt.component_len[1] == 8); + OSMO_ASSERT(s7i->cfg.pc_fmt.component_len[2] == 3); + OSMO_ASSERT(s7i->cfg.pc_fmt.delimiter = '.'); +} + +static void parse_print_mask(const char *in) +{ + uint32_t mask = osmo_ss7_pointcode_parse_mask_or_len(s7i, in); + const char *pc_str = osmo_ss7_pointcode_print(s7i, mask); + printf("mask %s => %u (0x%x) %s\n", in, mask, mask, pc_str); +} + +static void test_pc_parser_itu(void) +{ + /* ITU Style */ + printf("Testing ITU-style point code format\n"); + osmo_ss7_instance_set_pc_fmt(s7i, 3, 8, 3); + test_pc_transcode(0); + test_pc_transcode(1); + test_pc_transcode(1 << 3); + test_pc_transcode(1 << (3+8)); + test_pc_transcode(7 << (3+8)); + test_pc_transcode(100); + test_pc_transcode(2342); + test_pc_transcode((1 << 14)-1); + + parse_print_mask("/1"); + parse_print_mask("7.0.0"); + parse_print_mask("/14"); +} + +static void test_pc_parser_ansi(void) +{ + /* ANSI Style */ + printf("Testing ANSI-style point code format\n"); + osmo_ss7_instance_set_pc_fmt(s7i, 8, 8, 8); + s7i->cfg.pc_fmt.delimiter = '-'; + test_pc_transcode(0); + test_pc_transcode(1); + test_pc_transcode(1 << 8); + test_pc_transcode(1 << 16); + test_pc_transcode(1 << (3+8)); + test_pc_transcode((1 << 24)-1); + test_pc_transcode(100); + test_pc_transcode(2342); + + parse_print_mask("/1"); + parse_print_mask("/16"); + parse_print_mask("/24"); + + /* re-set to default (ITU) */ + osmo_ss7_instance_set_pc_fmt(s7i, 3, 8, 3); + s7i->cfg.pc_fmt.delimiter = '.'; +} + +static int test_user_prim_cb(struct osmo_prim_hdr *oph, void *priv) +{ + OSMO_ASSERT(priv == (void *) 0x1234); + + return 23; +} + +static void test_user(void) +{ + struct osmo_ss7_user user, user2; + struct osmo_mtp_prim omp = { + .oph = { + .sap = MTP_SAP_USER, + .primitive = OSMO_MTP_PRIM_TRANSFER, + .operation = PRIM_OP_INDICATION, + }, + .u.transfer = { + .sio = 1, + }, + }; + + printf("Testing SS7 user\n"); + + user.name = "testuser"; + user.priv = (void *) 0x1234; + user.prim_cb = test_user_prim_cb; + + /* registration */ + OSMO_ASSERT(osmo_ss7_user_register(s7i, 1, &user) == 0); + OSMO_ASSERT(osmo_ss7_user_register(s7i, 1, NULL) == -EBUSY); + OSMO_ASSERT(osmo_ss7_user_register(s7i, 255, NULL) == -EINVAL); + + /* primitive delivery */ + OSMO_ASSERT(osmo_ss7_mtp_to_user(s7i, &omp) == 23); + + /* cleanup */ + OSMO_ASSERT(osmo_ss7_user_unregister(s7i, 255, NULL) == -EINVAL); + OSMO_ASSERT(osmo_ss7_user_unregister(s7i, 10, NULL) == -ENODEV); + OSMO_ASSERT(osmo_ss7_user_unregister(s7i, 1, &user2) == -EINVAL); + OSMO_ASSERT(osmo_ss7_user_unregister(s7i, 1, &user) == 0); + + /* primitive delivery should fail now */ + OSMO_ASSERT(osmo_ss7_mtp_to_user(s7i, &omp) == -ENODEV); + + /* wrong primitive delivery should also fail */ + omp.oph.primitive = OSMO_MTP_PRIM_PAUSE; + OSMO_ASSERT(osmo_ss7_mtp_to_user(s7i, &omp) == -EINVAL); +} + +static void test_route(void) +{ + struct osmo_ss7_route_table *rtbl; + struct osmo_ss7_linkset *lset_a, *lset_b; + struct osmo_ss7_route *rt, *rt12, *rtdef; + + printf("Testing SS7 routing\n"); + + /* creation / destruction */ + OSMO_ASSERT(osmo_ss7_route_table_find(s7i, "foobar") == NULL); + rtbl = osmo_ss7_route_table_find_or_create(s7i, "foobar"); + OSMO_ASSERT(rtbl); + OSMO_ASSERT(osmo_ss7_route_table_find_or_create(s7i, "foobar") == rtbl); + osmo_ss7_route_table_destroy(rtbl); + OSMO_ASSERT(osmo_ss7_route_table_find(s7i, "foobar") == NULL); + + /* we now work with system route table */ + rtbl = osmo_ss7_route_table_find(s7i, "system"); + OSMO_ASSERT(rtbl && rtbl == s7i->rtable_system); + + lset_a = osmo_ss7_linkset_find_or_create(s7i, "a", 100); + OSMO_ASSERT(lset_a); + lset_b = osmo_ss7_linkset_find_or_create(s7i, "b", 200); + OSMO_ASSERT(lset_b); + + /* route with full mask */ + OSMO_ASSERT(osmo_ss7_route_find_dpc(rtbl, 12) == NULL); + rt = osmo_ss7_route_create(rtbl, 12, 0xffff, "a"); + OSMO_ASSERT(rt); + OSMO_ASSERT(osmo_ss7_route_find_dpc(rtbl, 12) == rt); + osmo_ss7_route_destroy(rt); + + /* route with partial mask */ + rt = osmo_ss7_route_create(rtbl, 8, 0xfff8, "a"); + OSMO_ASSERT(osmo_ss7_route_find_dpc(rtbl, 8) == rt); + OSMO_ASSERT(osmo_ss7_route_find_dpc(rtbl, 9) == rt); + OSMO_ASSERT(osmo_ss7_route_find_dpc(rtbl, 12) == rt); + OSMO_ASSERT(osmo_ss7_route_find_dpc(rtbl, 15) == rt); + OSMO_ASSERT(osmo_ss7_route_find_dpc(rtbl, 16) == NULL); + /* insert more specific route for 12, must have higher priority + * than existing one */ + rt12 = osmo_ss7_route_create(rtbl, 12, 0xffff, "b"); + OSMO_ASSERT(osmo_ss7_route_find_dpc(rtbl, 12) == rt12); + OSMO_ASSERT(osmo_ss7_route_find_dpc(rtbl, 15) == rt); + OSMO_ASSERT(osmo_ss7_route_find_dpc(rtbl, 16) == NULL); + /* add a default route, which should have lowest precedence */ + rtdef = osmo_ss7_route_create(rtbl, 0, 0, "a"); + OSMO_ASSERT(osmo_ss7_route_find_dpc(rtbl, 12) == rt12); + OSMO_ASSERT(osmo_ss7_route_find_dpc(rtbl, 15) == rt); + OSMO_ASSERT(osmo_ss7_route_find_dpc(rtbl, 16) == rtdef); + + osmo_ss7_route_destroy(rtdef); + osmo_ss7_route_destroy(rt12); + osmo_ss7_route_destroy(rt); + + osmo_ss7_linkset_destroy(lset_a); + osmo_ss7_linkset_destroy(lset_b); +} + +static void test_linkset(void) +{ + struct osmo_ss7_linkset *lset_a, *lset_b; + struct osmo_ss7_link *l_a1, *l_a2; + + printf("Testing SS7 linkset/link\n"); + + OSMO_ASSERT(osmo_ss7_linkset_find_by_name(s7i, "a") == NULL); + OSMO_ASSERT(osmo_ss7_linkset_find_by_name(s7i, "b") == NULL); + + lset_a = osmo_ss7_linkset_find_or_create(s7i, "a", 100); + OSMO_ASSERT(lset_a); + OSMO_ASSERT(osmo_ss7_linkset_find_by_name(s7i, "a") == lset_a); + + lset_b = osmo_ss7_linkset_find_or_create(s7i, "b", 200); + OSMO_ASSERT(lset_b); + OSMO_ASSERT(osmo_ss7_linkset_find_by_name(s7i, "b") == lset_b); + + l_a1 = osmo_ss7_link_find_or_create(lset_a, 1); + OSMO_ASSERT(l_a1); + l_a2 = osmo_ss7_link_find_or_create(lset_a, 2); + OSMO_ASSERT(l_a2); + + /* ID too high */ + OSMO_ASSERT(osmo_ss7_link_find_or_create(lset_a, 1000) == NULL); + /* already exists */ + OSMO_ASSERT(osmo_ss7_link_find_or_create(lset_a, 1) == l_a1); + + osmo_ss7_link_destroy(l_a1); + osmo_ss7_link_destroy(l_a2); + + osmo_ss7_linkset_destroy(lset_a); + osmo_ss7_linkset_destroy(lset_b); +} + +static void test_as(void) +{ + struct osmo_ss7_as *as; + struct osmo_ss7_asp *asp; + + OSMO_ASSERT(osmo_ss7_as_find_by_name(s7i, "as1") == NULL); + as = osmo_ss7_as_find_or_create(s7i, "as1", OSMO_SS7_ASP_PROT_M3UA); + OSMO_ASSERT(osmo_ss7_as_find_by_name(s7i, "as1") == as); + OSMO_ASSERT(osmo_ss7_as_find_by_rctx(s7i, 2342) == NULL); + as->cfg.routing_key.context = 2342; + OSMO_ASSERT(osmo_ss7_as_find_by_rctx(s7i, 2342) == as); + OSMO_ASSERT(osmo_ss7_as_add_asp(as, "asp1") == -ENODEV); + + asp = osmo_ss7_asp_find_or_create(s7i, "asp1", 0, M3UA_PORT, OSMO_SS7_ASP_PROT_M3UA); + OSMO_ASSERT(asp); + + OSMO_ASSERT(osmo_ss7_as_has_asp(as, asp) == false); + OSMO_ASSERT(osmo_ss7_as_add_asp(as, "asp1") == 0); + + osmo_ss7_asp_restart(asp); + + /* ask FSM to send ASP-UP.req */ + osmo_fsm_inst_dispatch(asp->fi, XUA_ASP_E_M_ASP_UP_REQ, NULL); + osmo_fsm_inst_dispatch(asp->fi, XUA_ASP_E_ASPSM_ASPUP_ACK, NULL); + osmo_fsm_inst_dispatch(asp->fi, XUA_ASP_E_ASPTM_ASPAC_ACK, NULL); + + OSMO_ASSERT(osmo_ss7_as_del_asp(as, "asp1") == 0); + OSMO_ASSERT(osmo_ss7_as_del_asp(as, "asp2") == -ENODEV); + OSMO_ASSERT(osmo_ss7_as_del_asp(as, "asp1") == -EINVAL); + + osmo_ss7_asp_destroy(asp); + osmo_ss7_as_destroy(as); + OSMO_ASSERT(osmo_ss7_as_find_by_name(s7i, "as1") == NULL); +} + +/*********************************************************************** + * Initialization + ***********************************************************************/ + +static const struct log_info_cat log_info_cat[] = { +}; + +static const struct log_info log_info = { + .cat = log_info_cat, + .num_cat = ARRAY_SIZE(log_info_cat), +}; + +static void init_logging(void) +{ + const int log_cats[] = { DLSS7, DLSUA, DLM3UA, DLSCCP, DLINP }; + unsigned int i; + + osmo_init_logging(&log_info); + + log_set_print_filename(osmo_stderr_target, 0); + + for (i = 0; i < ARRAY_SIZE(log_cats); i++) + log_set_category_filter(osmo_stderr_target, log_cats[i], 1, LOGL_DEBUG); +} + +int main(int argc, char **argv) +{ + init_logging(); + osmo_fsm_log_addr(false); + + /* init */ + osmo_ss7_init(); + s7i = osmo_ss7_instance_find_or_create(NULL, 0); + OSMO_ASSERT(osmo_ss7_instance_find(0) == s7i); + OSMO_ASSERT(osmo_ss7_instance_find(23) == NULL); + + /* test osmo_ss7_pc_is_local() */ + s7i->cfg.primary_pc = 55; + OSMO_ASSERT(osmo_ss7_pc_is_local(s7i, 55) == true); + OSMO_ASSERT(osmo_ss7_pc_is_local(s7i, 23) == false); + + /* further tests */ + test_pc_defaults(); + test_pc_parser_itu(); + test_pc_parser_ansi(); + test_user(); + test_route(); + test_linkset(); + test_as(); + + /* destroy */ + osmo_ss7_instance_destroy(s7i); + OSMO_ASSERT(osmo_ss7_instance_find(0) == NULL); + + exit(0); +} diff --git a/tests/ss7/ss7_test.err b/tests/ss7/ss7_test.err new file mode 100644 index 0000000..8823d1c --- /dev/null +++ b/tests/ss7/ss7_test.err @@ -0,0 +1,49 @@ +0: Creating SS7 Instance +0: Creating Route Table system +0: Point Code Format 8-8-8 is longer than 14 bits, odd? +registering user=testuser for SI 1 with priv 0x1234 +delivering MTP-TRANSFER.ind to user testuser, priv=0x1234 +No MTP-User for SI 1 +Unsupported Primitive +0: Creating Route Table foobar +0: Creating Linkset a +0: Creating Linkset b +0: Destroying Linkset a +0: Destroying Linkset b +0: Creating Linkset a +0: Creating Linkset b +0: Creating Link a:1 +0: Creating Link a:2 +0: Destroying Link a:1 +0: Destroying Link a:2 +0: Destroying Linkset a +0: Destroying Linkset b +0: Creating AS as1 +XUA_AS(as1){AS_DOWN}: Allocated +0: Adding ASP asp1 to AS as1 +0: Restarting ASP asp1 +unable to connect/bind socket: (null):0: Connection refused +connection closed +retrying in 5 seconds... +0: Unable to open stream client for ASP asp1 +XUA_ASP(asp1){ASP_DOWN}: Allocated +XUA_ASP(asp1){ASP_DOWN}: Received Event M-ASP_UP.req +XUA_ASP(asp1){ASP_DOWN}: Received Event ASPSM-ASP_UP_ACK +XUA_ASP(asp1){ASP_DOWN}: T(ack) stopped +XUA_ASP(asp1){ASP_DOWN}: state_chg to ASP_INACTIVE +XUA_ASP(asp1){ASP_INACTIVE}: Received Event M-ASP_ACTIVE.req +XUA_ASP(asp1){ASP_INACTIVE}: Received Event ASPTM-ASP_AC_ACK +XUA_ASP(asp1){ASP_INACTIVE}: T(ack) stopped +XUA_ASP(asp1){ASP_INACTIVE}: state_chg to ASP_ACTIVE +0: Removing ASP asp1 from AS as1 +0: Removing ASP asp1 from AS as1 +0: Destroying ASP asp1 +XUA_ASP(asp1){ASP_ACTIVE}: Terminating (cause = OSMO_FSM_TERM_REQUEST) +XUA_ASP(asp1){ASP_ACTIVE}: Freeing instance +XUA_ASP(asp1){ASP_ACTIVE}: Deallocated +0: Destroying AS as1 +XUA_AS(as1){AS_DOWN}: Terminating (cause = OSMO_FSM_TERM_REQUEST) +XUA_AS(as1){AS_DOWN}: Freeing instance +XUA_AS(as1){AS_DOWN}: Deallocated +0: Destroying SS7 Instance + \ No newline at end of file diff --git a/tests/ss7/ss7_test.ok b/tests/ss7/ss7_test.ok new file mode 100644 index 0000000..8aea63d --- /dev/null +++ b/tests/ss7/ss7_test.ok @@ -0,0 +1,27 @@ +Testing ITU-style point code format +test_pc_transcode(0) -> 0.0.0 -> 0 +test_pc_transcode(1) -> 0.0.1 -> 1 +test_pc_transcode(8) -> 0.1.0 -> 8 +test_pc_transcode(2048) -> 1.0.0 -> 2048 +test_pc_transcode(14336) -> 7.0.0 -> 14336 +test_pc_transcode(100) -> 0.12.4 -> 100 +test_pc_transcode(2342) -> 1.36.6 -> 2342 +test_pc_transcode(16383) -> 7.255.7 -> 16383 +mask /1 => 8192 (0x2000) 4.0.0 +mask 7.0.0 => 14336 (0x3800) 7.0.0 +mask /14 => 16383 (0x3fff) 7.255.7 +Testing ANSI-style point code format +test_pc_transcode(0) -> 0-0-0 -> 0 +test_pc_transcode(1) -> 0-0-1 -> 1 +test_pc_transcode(256) -> 0-1-0 -> 256 +test_pc_transcode(65536) -> 1-0-0 -> 65536 +test_pc_transcode(2048) -> 0-8-0 -> 2048 +test_pc_transcode(16777215) -> 255-255-255 -> 16777215 +test_pc_transcode(100) -> 0-0-100 -> 100 +test_pc_transcode(2342) -> 0-9-38 -> 2342 +mask /1 => 8388608 (0x800000) 128-0-0 +mask /16 => 16776960 (0xffff00) 255-255-0 +mask /24 => 16777215 (0xffffff) 255-255-255 +Testing SS7 user +Testing SS7 routing +Testing SS7 linkset/link diff --git a/tests/testsuite.at b/tests/testsuite.at index 8907ffa..171f488 100644 --- a/tests/testsuite.at +++ b/tests/testsuite.at @@ -18,3 +18,9 @@ cat $abs_srcdir/sccp/sccp_test.ok > expout AT_CHECK([$abs_top_builddir/tests/sccp/sccp_test], [], [expout], [ignore]) AT_CLEANUP + +AT_SETUP([ss7]) +AT_KEYWORDS([ss7]) +cat $abs_srcdir/ss7/ss7_test.ok > expout +AT_CHECK([$abs_top_builddir/tests/ss7/ss7_test], [], [expout], [ignore]) +AT_CLEANUP -- To view, visit https://gerrit.osmocom.org/2209 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I375eb80f01acc013094851d91d1d3333ebc12bc7 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Mon Apr 3 20:22:09 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 3 Apr 2017 20:22:09 +0000 Subject: [PATCH] libosmo-sccp[master]: sua: Make use of xua_msg_dialect Message-ID: Review at https://gerrit.osmocom.org/2210 sua: Make use of xua_msg_dialect We fill in the data structures of a xua_msg_dialect and make use of it for generic mandatory IE checking and messageheader printing. Change-Id: I966103f30b9be247ba6905ba8e06b87654d9981a --- M src/sua.c 1 file changed, 162 insertions(+), 8 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/10/2210/1 diff --git a/src/sua.c b/src/sua.c index 145bf1a..36032ff 100644 --- a/src/sua.c +++ b/src/sua.c @@ -37,6 +37,8 @@ #include #include +#include "xua_internal.h" + #define SUA_MSGB_SIZE 1500 /* Appendix C.4 of Q.714 (all in milliseconds) */ @@ -48,6 +50,161 @@ #define INT_TIMER ( 1 * 60 * 100) #define GUARD_TIMER (23 * 60 * 100) #define RESET_TIMER ( 10 * 100) + +/*********************************************************************** + * Protocol Definition (string tables, mandatory IE checking) + ***********************************************************************/ + +static const struct value_string sua_iei_names[] = { + { SUA_IEI_ROUTE_CTX, "Routing Context" }, + { SUA_IEI_CORR_ID, "Correlation Id" }, + { SUA_IEI_REG_RESULT, "Registration Result" }, + { SUA_IEI_DEREG_RESULT, "De-Registration Result" }, + + { SUA_IEI_S7_HOP_CTR, "SS7 Hop Counter" }, + { SUA_IEI_SRC_ADDR, "Source Address" }, + { SUA_IEI_DEST_ADDR, "Destination Address" }, + { SUA_IEI_SRC_REF, "Source Reference" }, + { SUA_IEI_DEST_REF, "Destination Reference" }, + { SUA_IEI_CAUSE, "Cause" }, + { SUA_IEI_SEQ_NR, "Sequence Number" }, + { SUA_IEI_RX_SEQ_NR, "Receive Sequence Number" }, + { SUA_IEI_ASP_CAPA, "ASP Capability" }, + { SUA_IEI_CREDIT, "Credit" }, + { SUA_IEI_DATA, "Data" }, + { SUA_IEI_USER_CAUSE, "User/Cause" }, + { SUA_IEI_NET_APPEARANCE, "Network Appearance" }, + { SUA_IEI_ROUTING_KEY, "Routing Key" }, + { SUA_IEI_DRN, "DRN Label" }, + { SUA_IEI_TID, "TID Label" }, + { SUA_IEI_SMI, "SMI" }, + { SUA_IEI_IMPORTANCE, "Importance" }, + { SUA_IEI_MSG_PRIO, "Message Priority" }, + { SUA_IEI_PROTO_CLASS, "Protocol Class" }, + { SUA_IEI_SEQ_CTRL, "Sequence Control" }, + { SUA_IEI_SEGMENTATION, "Segmentation" }, + { SUA_IEI_CONG_LEVEL, "Congestion Level" }, + + { SUA_IEI_GT, "Global Title" }, + { SUA_IEI_PC, "Point Code" }, + { SUA_IEI_SSN, "Sub-System Number" }, + { SUA_IEI_IPv4, "IPv4 Address" }, + { SUA_IEI_HOST, "Host Name" }, + { SUA_IEI_IPv6, "IPv6 Address" }, + { 0, NULL } +}; + +#define MAND_IES(msgt, ies) [msgt] = (ies) + +static const uint16_t cldt_mand_ies[] = { + SUA_IEI_ROUTE_CTX, SUA_IEI_PROTO_CLASS, SUA_IEI_SRC_ADDR, + SUA_IEI_DEST_ADDR, SUA_IEI_SEQ_CTRL, SUA_IEI_DATA, 0 +}; +static const uint16_t cldr_mand_ies[] = { + SUA_IEI_ROUTE_CTX, SUA_IEI_CAUSE, SUA_IEI_SRC_ADDR, + SUA_IEI_DEST_ADDR, 0 +}; +static const struct value_string sua_cl_msgt_names[] = { + { SUA_CL_CLDT, "CLDT" }, + { SUA_CL_CLDR, "CLDR" }, + { 0, NULL } +}; +static const struct xua_msg_class msg_class_cl = { + .name = "CL", + .msgt_names = sua_cl_msgt_names, + .iei_names = sua_iei_names, + .mand_ies = { + MAND_IES(SUA_CL_CLDT, cldt_mand_ies), + MAND_IES(SUA_CL_CLDR, cldr_mand_ies), + }, +}; + +static const uint16_t codt_mand_ies[] = { + SUA_IEI_ROUTE_CTX, SUA_IEI_DEST_REF, SUA_IEI_DATA, 0 +}; +static const uint16_t coda_mand_ies[] = { + SUA_IEI_ROUTE_CTX, SUA_IEI_DEST_REF, 0 +}; +static const uint16_t core_mand_ies[] = { + SUA_IEI_ROUTE_CTX, SUA_IEI_PROTO_CLASS, SUA_IEI_SRC_REF, + SUA_IEI_DEST_ADDR, SUA_IEI_SEQ_CTRL, 0 +}; +static const uint16_t coak_mand_ies[] = { + SUA_IEI_ROUTE_CTX, SUA_IEI_PROTO_CLASS, SUA_IEI_DEST_REF, + SUA_IEI_SRC_REF, SUA_IEI_SEQ_CTRL, 0 +}; +static const uint16_t coref_mand_ies[] = { + SUA_IEI_ROUTE_CTX, SUA_IEI_DEST_REF, SUA_IEI_CAUSE, 0 +}; +static const uint16_t relre_mand_ies[] = { + SUA_IEI_ROUTE_CTX, SUA_IEI_DEST_REF, SUA_IEI_SRC_REF, + SUA_IEI_CAUSE, 0 +}; +static const uint16_t relco_mand_ies[] = { + SUA_IEI_ROUTE_CTX, SUA_IEI_DEST_REF, SUA_IEI_SRC_REF, 0 +}; +static const uint16_t resre_mand_ies[] = { + SUA_IEI_ROUTE_CTX, SUA_IEI_DEST_REF, SUA_IEI_SRC_REF, + SUA_IEI_CAUSE, 0 +}; +static const uint16_t resco_mand_ies[] = { + SUA_IEI_ROUTE_CTX, SUA_IEI_DEST_REF, SUA_IEI_SRC_REF, 0 +}; +static const uint16_t coerr_mand_ies[] = { + SUA_IEI_ROUTE_CTX, SUA_IEI_DEST_REF, SUA_IEI_CAUSE, 0 +}; +static const uint16_t coit_mand_ies[] = { + SUA_IEI_ROUTE_CTX, SUA_IEI_PROTO_CLASS, SUA_IEI_SRC_REF, + SUA_IEI_DEST_REF, 0 +}; +static const struct value_string sua_co_msgt_names[] = { + { SUA_CO_CODT, "CODT" }, + { SUA_CO_CODA, "CODA" }, + { SUA_CO_CORE, "CORE" }, + { SUA_CO_COAK, "COAK" }, + { SUA_CO_COREF, "COREF" }, + { SUA_CO_RELRE, "RELRE" }, + { SUA_CO_RELCO, "RELCO" }, + { SUA_CO_RESRE, "RESRE" }, + { SUA_CO_RESCO, "RESCO" }, + { SUA_CO_COERR, "COERR" }, + { SUA_CO_COIT, "COIT" }, + { 0, NULL } +}; +static const struct xua_msg_class msg_class_co = { + .name = "CO", + .msgt_names = sua_co_msgt_names, + .iei_names = sua_iei_names, + .mand_ies = { + MAND_IES(SUA_CO_CODT, codt_mand_ies), + MAND_IES(SUA_CO_CODA, coda_mand_ies), + MAND_IES(SUA_CO_CORE, core_mand_ies), + MAND_IES(SUA_CO_COAK, coak_mand_ies), + MAND_IES(SUA_CO_COREF, coref_mand_ies), + MAND_IES(SUA_CO_RELRE, relre_mand_ies), + MAND_IES(SUA_CO_RELCO, relco_mand_ies), + MAND_IES(SUA_CO_RESRE, resre_mand_ies), + MAND_IES(SUA_CO_RESCO, resco_mand_ies), + MAND_IES(SUA_CO_COERR, coerr_mand_ies), + MAND_IES(SUA_CO_COIT, coit_mand_ies), + }, +}; + +const struct xua_dialect xua_dialect_sua = { + .name = "SUA", + .ppid = SUA_PPID, + .port = SUA_PORT, + .class = { + [SUA_MSGC_MGMT] = &m3ua_msg_class_mgmt, + [SUA_MSGC_SNM] = &m3ua_msg_class_snm, + [SUA_MSGC_ASPSM] = &m3ua_msg_class_aspsm, + [SUA_MSGC_ASPTM] = &m3ua_msg_class_asptm, + [SUA_MSGC_CL] = &msg_class_cl, + [SUA_MSGC_CO] = &msg_class_co, + [SUA_MSGC_RKM] = &m3ua_msg_class_rkm, + }, +}; + static int DSUA = -1; @@ -773,9 +930,6 @@ { int rc = -1; - if (!check_all_mand_ies(mand_ies_cl, xua)) - return -1; - switch (xua->hdr.msg_type) { case SUA_CL_CLDT: rc = sua_rx_cldt(link, xua); @@ -1094,9 +1248,6 @@ { int rc = -1; - if (!check_all_mand_ies(mand_ies_co, xua)) - return -1; - switch (xua->hdr.msg_type) { case SUA_CO_CORE: rc = sua_rx_core(link, xua); @@ -1142,8 +1293,11 @@ return -EIO; } - LOGP(DSUA, LOGL_DEBUG, "Received SUA Message (%u:%u)\n", - xua->hdr.msg_class, xua->hdr.msg_type); + LOGP(DSUA, LOGL_DEBUG, "Received SUA Message (%s)\n", + xua_hdr_dump(xua, &xua_dialect_sua)); + + if (!xua_dialect_check_all_mand_ies(&xua_dialect_sua, xua)) + return -1; switch (xua->hdr.msg_class) { case SUA_MSGC_CL: -- To view, visit https://gerrit.osmocom.org/2210 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I966103f30b9be247ba6905ba8e06b87654d9981a Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Mon Apr 3 20:22:09 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 3 Apr 2017 20:22:09 +0000 Subject: [PATCH] libosmo-sccp[master]: sua: Extend address parsing with GT, RI and IPv4 support Message-ID: Review at https://gerrit.osmocom.org/2211 sua: Extend address parsing with GT, RI and IPv4 support Change-Id: I186df77cbdbedfe1a60b855be3626b6766f4681c --- M src/sua.c 1 file changed, 104 insertions(+), 129 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/11/2211/1 diff --git a/src/sua.c b/src/sua.c index 36032ff..e81bce7 100644 --- a/src/sua.c +++ b/src/sua.c @@ -690,117 +690,54 @@ /*********************************************************************** - * Mandatory IE checking - ***********************************************************************/ - -#define MAND_IES(msgt, ies) [msgt] = (ies) - -static const uint16_t cldt_mand_ies[] = { - SUA_IEI_ROUTE_CTX, SUA_IEI_PROTO_CLASS, SUA_IEI_SRC_ADDR, - SUA_IEI_DEST_ADDR, SUA_IEI_SEQ_CTRL, SUA_IEI_DATA, 0 -}; - -static const uint16_t cldr_mand_ies[] = { - SUA_IEI_ROUTE_CTX, SUA_IEI_CAUSE, SUA_IEI_SRC_ADDR, - SUA_IEI_DEST_ADDR, 0 -}; - -static const uint16_t codt_mand_ies[] = { - SUA_IEI_ROUTE_CTX, SUA_IEI_DEST_REF, SUA_IEI_DATA, 0 -}; - -static const uint16_t coda_mand_ies[] = { - SUA_IEI_ROUTE_CTX, SUA_IEI_DEST_REF, 0 -}; - -static const uint16_t core_mand_ies[] = { - SUA_IEI_ROUTE_CTX, SUA_IEI_PROTO_CLASS, SUA_IEI_SRC_REF, - SUA_IEI_DEST_ADDR, SUA_IEI_SEQ_CTRL, 0 -}; - -static const uint16_t coak_mand_ies[] = { - SUA_IEI_ROUTE_CTX, SUA_IEI_PROTO_CLASS, SUA_IEI_DEST_REF, - SUA_IEI_SRC_REF, SUA_IEI_SEQ_CTRL, 0 -}; - -static const uint16_t coref_mand_ies[] = { - SUA_IEI_ROUTE_CTX, SUA_IEI_DEST_REF, SUA_IEI_CAUSE, 0 -}; - -static const uint16_t relre_mand_ies[] = { - SUA_IEI_ROUTE_CTX, SUA_IEI_DEST_REF, SUA_IEI_SRC_REF, - SUA_IEI_CAUSE, 0 -}; - -static const uint16_t relco_mand_ies[] = { - SUA_IEI_ROUTE_CTX, SUA_IEI_DEST_REF, SUA_IEI_SRC_REF, 0 -}; - -static const uint16_t resre_mand_ies[] = { - SUA_IEI_ROUTE_CTX, SUA_IEI_DEST_REF, SUA_IEI_SRC_REF, - SUA_IEI_CAUSE, 0 -}; - -static const uint16_t resco_mand_ies[] = { - SUA_IEI_ROUTE_CTX, SUA_IEI_DEST_REF, SUA_IEI_SRC_REF, 0 -}; - -static const uint16_t coerr_mand_ies[] = { - SUA_IEI_ROUTE_CTX, SUA_IEI_DEST_REF, SUA_IEI_CAUSE, 0 -}; - -static const uint16_t coit_mand_ies[] = { - SUA_IEI_ROUTE_CTX, SUA_IEI_PROTO_CLASS, SUA_IEI_SRC_REF, - SUA_IEI_DEST_REF, 0 -}; - -static const uint16_t *mand_ies_cl[256] = { - MAND_IES(SUA_CL_CLDT, cldt_mand_ies), - MAND_IES(SUA_CL_CLDR, cldr_mand_ies), -}; - -static const uint16_t *mand_ies_co[256] = { - MAND_IES(SUA_CO_CODT, codt_mand_ies), - MAND_IES(SUA_CO_CODA, coda_mand_ies), - MAND_IES(SUA_CO_CORE, core_mand_ies), - MAND_IES(SUA_CO_COAK, coak_mand_ies), - MAND_IES(SUA_CO_COREF, coref_mand_ies), - MAND_IES(SUA_CO_RELRE, relre_mand_ies), - MAND_IES(SUA_CO_RELCO, relco_mand_ies), - MAND_IES(SUA_CO_RESRE, resre_mand_ies), - MAND_IES(SUA_CO_RESCO, resco_mand_ies), - MAND_IES(SUA_CO_COERR, coerr_mand_ies), - MAND_IES(SUA_CO_COIT, coit_mand_ies), -}; - -static int check_all_mand_ies(const uint16_t **mand_ies, struct xua_msg *xua) -{ - uint8_t msg_type = xua->hdr.msg_type; - const uint16_t *ies = mand_ies[msg_type]; - uint16_t ie; - - for (ie = *ies; ie; ie = *ies++) { - if (!xua_msg_find_tag(xua, ie)) { - LOGP(DSUA, LOGL_ERROR, "SUA Message %u:%u should " - "contain IE 0x%04x, but doesn't\n", - xua->hdr.msg_class, msg_type, ie); - return 0; - } - } - - return 1; -} - - -/*********************************************************************** * Receiving SUA messsages from SCTP ***********************************************************************/ -static int sua_parse_addr(struct osmo_sccp_addr *out, - struct xua_msg *xua, - uint16_t iei) +/*! \brief Decode SUA Global Title according to RFC3868 3.10.2.3 + * \param[out] gt User-allocated structure for decoded output + * \param[in] data binary-encoded data + * \param[in] datalen length of \ref data in octets + */ +int sua_parse_gt(struct osmo_sccp_gt *gt, const uint8_t *data, unsigned int datalen) { - const struct xua_msg_part *param = xua_msg_find_tag(xua, iei); + uint8_t num_digits; + char *out_digits; + unsigned int i; + + /* 8 byte header at minimum, plus digits */ + if (datalen < 8) + return -EINVAL; + + /* parse header */ + gt->gti = data[3]; + num_digits = data[4]; + gt->tt = data[5]; + gt->npi = data[6]; + gt->nai = data[7]; + + /* parse digits */ + out_digits = gt->digits; + for (i = 0; i < datalen-8; i++) { + uint8_t byte = data[8+i]; + *out_digits++ = osmo_bcd2char(byte & 0x0F); + if (out_digits - gt->digits >= num_digits) + break; + *out_digits++ = osmo_bcd2char(byte >> 4); + if (out_digits - gt->digits >= num_digits) + break; + } + *out_digits++ = '\0'; + + return 0; +} + +/*! \brief parse SCCP address from given xUA message part + * \param[out] out caller-allocated decoded SCCP address struct + * \param[in] param xUA message part containing address + \returns 0 on success; negative on error */ +int sua_addr_parse_part(struct osmo_sccp_addr *out, + const struct xua_msg_part *param) +{ const struct xua_parameter_hdr *par; uint16_t ri; uint16_t ai; @@ -808,16 +745,15 @@ uint16_t par_tag, par_len, par_datalen; uint32_t *p32; - if (!param) - return -ENODEV; + memset(out, 0, sizeof(*out)); - LOGP(DSUA, LOGL_DEBUG, "sua_parse_addr(IEI=%d) (%d) %s\n", - iei, param->len, + LOGP(DSUA, LOGL_DEBUG, "%s(IEI=0x%04x) (%d) %s\n", __func__, + param->tag, param->len, osmo_hexdump(param->dat, param->len)); if (param->len < 4) { - LOGP(DSUA, LOGL_ERROR, "SUA IEI %d: invalid address length: %d\n", - iei, param->len); + LOGP(DSUA, LOGL_ERROR, "SUA IEI 0x%04x: invalid address length: %d\n", + param->tag, param->len); return -EINVAL; } @@ -827,16 +763,29 @@ ai = ntohs(*(uint16_t*) ¶m->dat[pos]); pos += 2; - if (ri != SUA_RI_SSN_PC) { - LOGP(DSUA, LOGL_ERROR, "SUA IEI %d: Routing Indicator not supported yet: %d\n", - iei, ri); + switch (ri) { + case SUA_RI_GT: + out->ri = OSMO_SCCP_RI_GT; + break; + case SUA_RI_SSN_PC: + out->ri = OSMO_SCCP_RI_SSN_PC; + break; + case SUA_RI_SSN_IP: + out->ri = OSMO_SCCP_RI_SSN_IP; + break; + case SUA_RI_HOST: + default: + LOGP(DSUA, LOGL_ERROR, "SUA IEI 0x%04x: Routing Indicator not supported yet: %d\n", + param->tag, ri); return -ENOTSUP; } if (ai != 7) { - LOGP(DSUA, LOGL_ERROR, "SUA IEI %d: Address Indicator not supported yet: %x\n", - iei, ai); +#if 0 + LOGP(DSUA, LOGL_ERROR, "SUA IEI 0x%04x: Address Indicator not supported yet: %x\n", + param->tag, ai); return -ENOTSUP; +#endif } /* @@ -853,8 +802,8 @@ par_len = ntohs(par->len); par_datalen = par_len - sizeof(*par); - LOGP(DSUA, LOGL_DEBUG, "SUA IEI %hu pos %hu/%hu: subpart tag %hu, len %hu\n", - iei, pos, param->len, par->tag, par->len); + LOGP(DSUA, LOGL_DEBUG, "SUA IEI 0x%04x pos %hu/%hu: subpart tag 0x%04x, len %hu\n", + param->tag, pos, param->len, par_tag, par_len); switch (par_tag) { case SUA_IEI_PC: @@ -872,12 +821,22 @@ out->presence |= OSMO_SCCP_ADDR_T_SSN; break; case SUA_IEI_GT: - /* TODO */ + if (par_datalen < 8) + goto subpar_fail; + sua_parse_gt(&out->gt, par->data, par_datalen); out->presence |= OSMO_SCCP_ADDR_T_GT; break; + case SUA_IEI_IPv4: + if (par_datalen != 4) + goto subpar_fail; + p32 = (uint32_t*)par->data; + /* no endian conversion, both network order */ + out->ip.v4.s_addr = *p32; + out->presence |= OSMO_SCCP_ADDR_T_IPv4; + break; default: - LOGP(DSUA, LOGL_ERROR, "SUA IEI %d: Unknown subpart tag %hd\n", - iei, par_tag); + LOGP(DSUA, LOGL_ERROR, "SUA IEI 0x%04x: Unknown subpart tag %hd\n", + param->tag, par_tag); goto subpar_fail; } @@ -887,9 +846,25 @@ return 0; subpar_fail: - LOGP(DSUA, LOGL_ERROR, "Failed to parse subparts of address IEI=%d\n", - iei); + LOGP(DSUA, LOGL_ERROR, "Failed to parse subparts of address IEI=0x%04x\n", + param->tag); return -EINVAL; +} + +/*! \brief parse SCCP address from given xUA message IE + * \param[out] out caller-allocated decoded SCCP address struct + * \param[in] xua xUA message + * \param[in] iei Information Element Identifier inside \ref xua + \returns 0 on success; negative on error */ +int sua_addr_parse(struct osmo_sccp_addr *out, struct xua_msg *xua, uint16_t iei) +{ + const struct xua_msg_part *param = xua_msg_find_tag(xua, iei); + if (!param) { + memset(out, 0, sizeof(*out)); + return -ENODEV; + } + + return sua_addr_parse_part(out, param); } static int sua_rx_cldt(struct osmo_sccp_link *link, struct xua_msg *xua) @@ -906,8 +881,8 @@ osmo_prim_init(&prim->oph, SCCP_SAP_USER, OSMO_SCU_PRIM_N_UNITDATA, PRIM_OP_INDICATION, upmsg); - sua_parse_addr(¶m->called_addr, xua, SUA_IEI_DEST_ADDR); - sua_parse_addr(¶m->calling_addr, xua, SUA_IEI_SRC_ADDR); + sua_addr_parse(¶m->called_addr, xua, SUA_IEI_DEST_ADDR); + sua_addr_parse(¶m->calling_addr, xua, SUA_IEI_SRC_ADDR); param->in_sequence_control = xua_msg_get_u32(xua, SUA_IEI_SEQ_CTRL); protocol_class = xua_msg_get_u32(xua, SUA_IEI_PROTO_CLASS); param->return_option = protocol_class & 0x80; @@ -953,8 +928,8 @@ /* fill conn */ conn = conn_create(link); - sua_parse_addr(&conn->called_addr, xua, SUA_IEI_DEST_ADDR); - sua_parse_addr(&conn->calling_addr, xua, SUA_IEI_SRC_ADDR); + sua_addr_parse(&conn->called_addr, xua, SUA_IEI_DEST_ADDR); + sua_addr_parse(&conn->calling_addr, xua, SUA_IEI_SRC_ADDR); conn->remote_ref = xua_msg_get_u32(xua, SUA_IEI_SRC_REF); /* fill primitive */ -- To view, visit https://gerrit.osmocom.org/2211 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I186df77cbdbedfe1a60b855be3626b6766f4681c Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Mon Apr 3 20:22:09 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 3 Apr 2017 20:22:09 +0000 Subject: [PATCH] libosmo-sccp[master]: sua.c: Replace sua_msgb_alloc() with new sccp_msgb_alloc() Message-ID: Review at https://gerrit.osmocom.org/2212 sua.c: Replace sua_msgb_alloc() with new sccp_msgb_alloc() Change-Id: I7067a85dcc5dda66f4b17b0fe08da8cb3efe79ef --- M src/Makefile.am A src/sccp_internal.h M src/sua.c 3 files changed, 24 insertions(+), 15 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/12/2212/1 diff --git a/src/Makefile.am b/src/Makefile.am index f7f4ccc..ec3fe99 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,7 +1,7 @@ AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir) AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMONETIF_CFLAGS) -noinst_HEADERS = xua_asp_fsm.h xua_as_fsm.h xua_internal.h +noinst_HEADERS = sccp_internal.h xua_asp_fsm.h xua_as_fsm.h xua_internal.h # Legacy static libs diff --git a/src/sccp_internal.h b/src/sccp_internal.h new file mode 100644 index 0000000..7287a82 --- /dev/null +++ b/src/sccp_internal.h @@ -0,0 +1,5 @@ +#pragma once + +#include + +struct msgb *sccp_msgb_alloc(const char *name); diff --git a/src/sua.c b/src/sua.c index e81bce7..b135c62 100644 --- a/src/sua.c +++ b/src/sua.c @@ -51,6 +51,17 @@ #define GUARD_TIMER (23 * 60 * 100) #define RESET_TIMER ( 10 * 100) +#define SCCP_MSG_SIZE 2048 +#define SCCP_MSG_HEADROOM 512 + +struct msgb *sccp_msgb_alloc(const char *name) +{ + if (!name) + name = "SCCP"; + return msgb_alloc_headroom(SCCP_MSG_SIZE+SCCP_MSG_HEADROOM, + SCCP_MSG_HEADROOM, name); +} + /*********************************************************************** * Protocol Definition (string tables, mandatory IE checking) ***********************************************************************/ @@ -431,13 +442,6 @@ conn_restart_tx_inact_timer(conn); conn_restart_rx_inact_timer(conn); } - - -static struct msgb *sua_msgb_alloc(void) -{ - return msgb_alloc(SUA_MSGB_SIZE, "SUA Primitive"); -} - /*********************************************************************** * Handling of messages from the User SAP @@ -872,7 +876,7 @@ struct osmo_scu_prim *prim; struct osmo_scu_unitdata_param *param; struct xua_msg_part *data_ie = xua_msg_find_tag(xua, SUA_IEI_DATA); - struct msgb *upmsg = sua_msgb_alloc(); + struct msgb *upmsg = sccp_msgb_alloc(__func__); uint32_t protocol_class; /* fill primitive */ @@ -933,7 +937,7 @@ conn->remote_ref = xua_msg_get_u32(xua, SUA_IEI_SRC_REF); /* fill primitive */ - upmsg = sua_msgb_alloc(); + upmsg = sccp_msgb_alloc(__func__); prim = (struct osmo_scu_prim *) msgb_put(upmsg, sizeof(*prim)); param = &prim->u.connect; osmo_prim_init(&prim->oph, SCCP_SAP_USER, @@ -993,7 +997,7 @@ conn->remote_ref = xua_msg_get_u32(xua, SUA_IEI_SRC_REF); /* fill primitive */ - upmsg = sua_msgb_alloc(); + upmsg = sccp_msgb_alloc(__func__); prim = (struct osmo_scu_prim *) msgb_put(upmsg, sizeof(*prim)); param = &prim->u.connect; osmo_prim_init(&prim->oph, SCCP_SAP_USER, @@ -1045,7 +1049,7 @@ conn_restart_rx_inact_timer(conn); /* fill primitive */ - upmsg = sua_msgb_alloc(); + upmsg = sccp_msgb_alloc(__func__); prim = (struct osmo_scu_prim *) msgb_put(upmsg, sizeof(*prim)); param = &prim->u.disconnect; osmo_prim_init(&prim->oph, SCCP_SAP_USER, @@ -1096,7 +1100,7 @@ } /* fill primitive */ - upmsg = sua_msgb_alloc(); + upmsg = sccp_msgb_alloc(__func__); prim = (struct osmo_scu_prim *) msgb_put(upmsg, sizeof(*prim)); param = &prim->u.disconnect; osmo_prim_init(&prim->oph, SCCP_SAP_USER, @@ -1145,7 +1149,7 @@ conn_restart_rx_inact_timer(conn); /* fill primitive */ - upmsg = sua_msgb_alloc(); + upmsg = sccp_msgb_alloc(__func__); prim = (struct osmo_scu_prim *) msgb_put(upmsg, sizeof(*prim)); param = &prim->u.disconnect; osmo_prim_init(&prim->oph, SCCP_SAP_USER, @@ -1197,7 +1201,7 @@ conn_restart_rx_inact_timer(conn); /* fill primitive */ - upmsg = sua_msgb_alloc(); + upmsg = sccp_msgb_alloc(__func__); prim = (struct osmo_scu_prim *) msgb_put(upmsg, sizeof(*prim)); param = &prim->u.data; osmo_prim_init(&prim->oph, SCCP_SAP_USER, -- To view, visit https://gerrit.osmocom.org/2212 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I7067a85dcc5dda66f4b17b0fe08da8cb3efe79ef Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Mon Apr 3 20:22:09 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 3 Apr 2017 20:22:09 +0000 Subject: [PATCH] libosmo-sccp[master]: Add SCCP <-> SUA message transcoding routines Message-ID: Review at https://gerrit.osmocom.org/2213 Add SCCP <-> SUA message transcoding routines Change-Id: I8151a9b08a0b0ca97b9c73105ad4548512ce3be8 --- M src/Makefile.am A src/sccp2sua.c 2 files changed, 1,266 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/13/2213/1 diff --git a/src/Makefile.am b/src/Makefile.am index ec3fe99..4455127 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -27,6 +27,7 @@ LIBVERSION=0:0:0 libosmo_sigtran_la_SOURCES = sccp_sap.c sua.c m3ua.c xua_msg.c sccp_helpers.c \ + sccp2sua.c \ osmo_ss7.c osmo_ss7_hmrt.c xua_asp_fsm.c xua_as_fsm.c libosmo_sigtran_la_LDFLAGS = -version-info $(LIBVERSION) -no-undefined -export-symbols-regex '^osmo_' libosmo_sigtran_la_LIBADD = $(LIBOSMOCORE_LIBS) $(LIBOSMONETIF_LIBS) $(LIBSCTP_LIBS) diff --git a/src/sccp2sua.c b/src/sccp2sua.c new file mode 100644 index 0000000..070a8cb --- /dev/null +++ b/src/sccp2sua.c @@ -0,0 +1,1265 @@ +/* SCCP <-> SUA transcoding routines */ + +/* (C) 2017 by Harald Welte + * All Rights Reserved + * + * based on my 2011 Erlang implementation osmo_ss7/src/sua_sccp_conv.erl + * + * References: ITU-T Q.713 and IETF RFC 3868 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "xua_internal.h" +#include "sccp_internal.h" + +/* libosmocore candidates */ + +static void msgb_put_u24be(struct msgb *msg, uint32_t val) +{ + msgb_put_u8(msg, (val >> 16) & 0xff); + msgb_put_u8(msg, (val >> 8) & 0xff); + msgb_put_u8(msg, val & 0xff); +} + +static void msgb_put_u16le(struct msgb *msg, uint16_t val) +{ + msgb_put_u8(msg, val & 0xff); + msgb_put_u8(msg, (val >> 8) & 0xff); +} + +/*! \brief load a 24bit value as big-endian */ +static uint32_t load_24be(const void *ptr) +{ + const uint8_t *data = ptr; + return (data[0] << 16) | (data[1] << 8) | data[2]; +} + + + +/*! \brief Parse ISUP style address of BCD digets + * \param[out] out_digits user-allocated buffer for ASCII digits + * \param[in] in BCD-encoded digits + * \param[in] in_num_bytes Size of \ref in in bytes + * \param[in] odd Odd (true) or even (false) number of digits + * \returns number of digits generated + * */ +int osmo_isup_party_parse(char *out_digits, const uint8_t *in, + unsigned int in_num_bytes, bool odd) +{ + char *out = out_digits; + unsigned int i; + + for (i = 0; i < in_num_bytes; i++) { + *out_digits++ = osmo_bcd2char(in[i] & 0x0F); + if (i+1 == in_num_bytes && odd) + break; + *out_digits++ = osmo_bcd2char(in[i] >> 4); + } + *out_digits = '\0'; + return (out_digits - out); +} + +/*! \brief Encode an ISUP style address of BCD digits + * \param[out] msg Message to which the encoded address is appended + * \param[in] in_digits NUL-terminated ASCII string of digits + * \returns number of octets used for encoding \ref in_digits */ +int osmo_isup_party_encode(struct msgb *msg, const char *in_digits) +{ + unsigned int num_digits = strlen(in_digits); + unsigned int i, num_octets = num_digits/2; + const char *cur_digit = in_digits; + uint8_t *cur; + + if (num_digits & 1) + num_octets++; + + cur = msgb_put(msg, num_octets); + + for (i = 0; i < num_octets; i++) { + cur[i] = osmo_char2bcd(*cur_digit++); + if (cur_digit - in_digits < num_digits) + cur[i] |= osmo_char2bcd(*cur_digit++) << 4; + } + return num_octets; +} + +/*! \brief Parse wire-encoded SCCP address into omso_sccp_addr + * \param[out] out user-allocated output data structure + * \param[in] addr wire-encoded SCCP address + * \param[in] addrlen Size of \ref addr in bytes + * \returns 0 in case of success, negative on error + * According to Q.713/3.4 and RFC3868/3.10.2 */ +int osmo_sccp_addr_parse(struct osmo_sccp_addr *out, + const uint8_t *addr, unsigned int addrlen) +{ + struct sccp_called_party_address *sca; + uint8_t *cur; + uint8_t encoding; + bool odd; + int rc; + + memset(out, 0, sizeof(*out)); + + sca = (struct sccp_called_party_address *) addr; + cur = sca->data; + + if (sca->routing_indicator) + out->ri = OSMO_SCCP_RI_SSN_PC; + else + out->ri = OSMO_SCCP_RI_GT; + + if (sca->point_code_indicator) { + out->presence |= OSMO_SCCP_ADDR_T_PC; + out->pc = ((cur[1] << 8) & 0x3f) | cur[0]; + cur += 2; + } + + if (sca->ssn_indicator) { + out->presence |= OSMO_SCCP_ADDR_T_SSN; + out->ssn = *cur; + cur += 1; + } + + switch (sca->global_title_indicator) { + case SCCP_TITLE_IND_NONE: + out->gt.gti = OSMO_SCCP_GTI_NO_GT; + return 0; + case SCCP_TITLE_IND_NATURE_ONLY: + out->presence |= OSMO_SCCP_ADDR_T_GT; + out->gt.gti = OSMO_SCCP_GTI_NAI_ONLY; + out->gt.nai = *cur & 0x7f; + if (*cur++ & 0x80) + odd = true; + else + odd = false; + break; + case SCCP_TITLE_IND_TRANSLATION_ONLY: + out->presence |= OSMO_SCCP_ADDR_T_GT; + out->gt.gti = OSMO_SCCP_GTI_TT_ONLY; + out->gt.tt = *cur++; + /* abort, for national use only */ + return -EINVAL; + case SCCP_TITLE_IND_TRANS_NUM_ENC: + out->presence |= OSMO_SCCP_ADDR_T_GT; + out->gt.gti = OSMO_SCCP_GTI_TT_NPL_ENC; + out->gt.tt = *cur++; + out->gt.npi = *cur >> 4; + switch (*cur++ & 0xF) { + case 1: + odd = true; + break; + case 2: + odd = false; + break; + default: + return -1; + } + break; + case SCCP_TITLE_IND_TRANS_NUM_ENC_NATURE: + out->presence |= OSMO_SCCP_ADDR_T_GT; + out->gt.gti = OSMO_SCCP_GTI_TT_NPL_ENC_NAI; + out->gt.tt = *cur++; + out->gt.npi = *cur >> 4; + encoding = *cur++ & 0xF; + switch (encoding) { + case 1: + odd = true; + break; + case 2: + odd = false; + break; + default: + LOGP(DLSUA, LOGL_ERROR, "Unknown GT encoding 0x%x\n", + encoding); + return -EINVAL; + } + out->gt.nai = *cur++ & 0x7f; + break; + default: + LOGP(DLSUA, LOGL_ERROR, "Unknown GTI %u in SCCP message\n", + sca->global_title_indicator); + return -EINVAL; + } + rc = osmo_isup_party_parse(out->gt.digits, cur, (addr+addrlen-cur), odd); + if (rc < 0) + return rc; + + return 0; +} + +/*! \brief encode a SCCP address from parsed format to wire format + * \param[out] msg message buffer to which address is to be appended + * \param[in] in data structure describing SCCP address + * \returns number of bytes written to \ref msg */ +int osmo_sccp_addr_encode(struct msgb *msg, const struct osmo_sccp_addr *in) +{ + struct sccp_called_party_address *sca; + bool odd; + + sca = (struct sccp_called_party_address *) msgb_put(msg, sizeof(*sca)); + switch (in->ri) { + case OSMO_SCCP_RI_SSN_PC: + sca->routing_indicator = 1; + break; + case OSMO_SCCP_RI_GT: + sca->routing_indicator = 0; + break; + default: + LOGP(DLSUA, LOGL_ERROR, "Unknown CCP Routing Indicator %u" + "requested\n", in->ri); + return -EINVAL; + } + + if (in->presence & OSMO_SCCP_ADDR_T_PC) { + sca->point_code_indicator = 1; + msgb_put_u16le(msg, in->pc & 0x3ff); + } + + if (in->presence & OSMO_SCCP_ADDR_T_SSN) { + sca->ssn_indicator = 1; + msgb_put_u8(msg, in->ssn); + } + + if (!(in->presence & OSMO_SCCP_ADDR_T_GT)) { + sca->global_title_indicator = SCCP_TITLE_IND_NONE; + goto out; + } + + odd = strlen(in->gt.digits) & 1; + switch (in->gt.gti) { + case OSMO_SCCP_GTI_NO_GT: + sca->global_title_indicator = SCCP_TITLE_IND_NONE; + goto out; + case OSMO_SCCP_GTI_NAI_ONLY: + sca->global_title_indicator = SCCP_TITLE_IND_NATURE_ONLY; + msgb_put_u8(msg, (odd << 7) | (in->gt.nai & 0x7f)); + break; + case OSMO_SCCP_GTI_TT_ONLY: + sca->global_title_indicator = SCCP_TITLE_IND_TRANSLATION_ONLY; + msgb_put_u8(msg, in->gt.tt); + /* abort, for national use only */ + LOGP(DLSUA, LOGL_ERROR, "Unsupported Translation Type %u" + "requested\n", in->gt.gti); + return -EINVAL; + case OSMO_SCCP_GTI_TT_NPL_ENC: + sca->global_title_indicator = SCCP_TITLE_IND_TRANS_NUM_ENC; + msgb_put_u8(msg, in->gt.tt); + msgb_put_u8(msg, (in->gt.npi << 4) | (odd ? 1 : 2)); + break; + case OSMO_SCCP_GTI_TT_NPL_ENC_NAI: + sca->global_title_indicator = SCCP_TITLE_IND_TRANS_NUM_ENC_NATURE; + msgb_put_u8(msg, in->gt.tt); + msgb_put_u8(msg, (in->gt.npi << 4) | (odd ? 1 : 2)); + msgb_put_u8(msg, in->gt.nai & 0x7f); + break; + } + osmo_isup_party_encode(msg, in->gt.digits); + +out: + /* return number of bytes written */ + return msg->tail - (uint8_t *)sca; +} + +/*! \brief convert SCCP address to SUA address + * \param xua user-provided xUA message to which address shall be added + * \param[in] iei SUA Information Element Identifier for address + * \param[in] addr SCCP wire format binary address + * \param[in] addrlen Size of \ref addr in bytes + * \returns 0 in case of success; negative on error */ +static int sccp_addr_to_sua(struct xua_msg *xua, uint16_t iei, const uint8_t *addr, + unsigned int addrlen) +{ + struct osmo_sccp_addr osa; + int rc; + + /* First decode the address from SCCP wire format to + * osmo_sccp_addr */ + rc = osmo_sccp_addr_parse(&osa, addr, addrlen); + if (rc < 0) + return rc; + + LOGP(DLSUA, LOGL_DEBUG, "Parsed Addr: %s\n", osmo_sccp_addr_dump(&osa)); + + /* Then re-encode it as SUA address */ + return xua_msg_add_sccp_addr(xua, iei, &osa); +} + +/*! \brief convenience wrapper around sccp_addr_to_sua() for variable mandatory addresses */ +static int sccp_addr_to_sua_ptr(struct xua_msg *xua, uint16_t iei, struct msgb *msg, uint8_t *ptr_addr) +{ + uint8_t *addr = ptr_addr + *ptr_addr + 1; + unsigned int addrlen = *(ptr_addr + *ptr_addr); + + return sccp_addr_to_sua(xua, iei, addr, addrlen); +} + +/*! \brief convert SUA address to SCCP address + * \param msg user-provided message buffer to which address shall be * appended + * \param[in] part SUA wire format binary address + * \returns 0 in case of success; negative on error */ +static int sua_addr_to_sccp(struct msgb *msg, struct xua_msg_part *part) +{ + struct osmo_sccp_addr osa; + int rc; + + /* First decode the address from SUA wire format to + * osmo_sccp_addr */ + rc = sua_addr_parse_part(&osa, part); + if (rc < 0) + return rc; + + /* Then re-encode it as SCCP address */ + return osmo_sccp_addr_encode(msg, &osa); +} + +/*! \brief Add a "SCCP Variable Mandatory Part" (Address format) to the given msgb + * \param msg Message buffer to which part shall be added + * \param[out] var_ptr pointer to relative pointer in SCCP header + * \param[in] xua xUA message from which to use address + * \param[in] iei xUA information element identifier of address */ +static int sccp_add_var_addr(struct msgb *msg, uint8_t *var_ptr, struct xua_msg *xua, uint16_t iei) +{ + struct xua_msg_part *part = xua_msg_find_tag(xua, iei); + uint8_t *lenbyte; + int rc; + if (!part) { + LOGP(DLSUA, LOGL_ERROR, "Cannot find IEI %u in SUA message\n", iei); + return -ENODEV; + } + + /* first allocate one byte for the length */ + lenbyte = msgb_put(msg, 1); + /* update the relative pointer to the length byte */ + *var_ptr = lenbyte - var_ptr; + + /* then append the encoded SCCP address */ + rc = sua_addr_to_sccp(msg, part); + if (rc < 0) + return rc; + + /* store the encoded length of the address */ + *lenbyte = rc; + + return rc; +} + +/*! \brief Add a "SCCP Variable Mandatory Part" to the given msgb + * \param msg Message buffer to which part shall be added + * \param[out] var_ptr pointer to relative pointer in SCCP header + * \param[in] xua xUA message from which to use source data + * \param[in] iei xUA information element identifier of source data */ +static int sccp_add_variable_part(struct msgb *msg, uint8_t *var_ptr, struct xua_msg *xua, uint16_t iei) +{ + struct xua_msg_part *part = xua_msg_find_tag(xua, iei); + uint8_t *lenbyte; + uint8_t *cur; + if (!part) { + LOGP(DLSUA, LOGL_ERROR, "Cannot find IEI %u in SUA message\n", iei); + return -ENODEV; + } + + /* first allocate one byte for the length */ + lenbyte = msgb_put(msg, 1); + /* update the relative pointer to the length byte */ + *var_ptr = lenbyte - var_ptr; + + /* then append the encoded SCCP address */ + cur = msgb_put(msg, part->len); + memcpy(cur, part->dat, part->len); + + /* store the encoded length of the address */ + *lenbyte = part->len; + + return part->len; +} + + +/*! \brief validate that SCCP part with pointer + length doesn't exceed msg tail + * \param[in] msg Message containing SCCP address + * \param[in] ptr_addr pointer to byte with relative SCCP pointer + * \returns true if OK; false if message inconsistent */ +static bool sccp_ptr_part_consistent(struct msgb *msg, uint8_t *ptr_addr) +{ + uint8_t *ptr; + + /* check the address of the relative pointer is within msg */ + if (ptr_addr < msg->data || ptr_addr > msg->tail) { + LOGP(DLSUA, LOGL_ERROR, "ptr_addr outside msg boundary\n"); + return false; + } + + ptr = ptr_addr + *ptr_addr; + if (ptr > msg->tail) { + LOGP(DLSUA, LOGL_ERROR, "ptr points outside msg boundary\n"); + return false; + } + + /* at destination of relative pointer is the length */ + if (ptr + 1 + *ptr > msg->tail) { + LOGP(DLSUA, LOGL_ERROR, "ptr + len points outside msg boundary\n"); + return false; + } + return true; +} + +/*! \brief convenience wrapper around xua_msg_add_data() for variable mandatory data */ +static int sccp_data_to_sua_ptr(struct xua_msg *xua, uint16_t iei, struct msgb *msg, uint8_t *ptr_addr) +{ + uint8_t *addr = ptr_addr + *ptr_addr + 1; + unsigned int addrlen = *(ptr_addr + *ptr_addr); + + return xua_msg_add_data(xua, iei, addrlen, addr); +} + +/*! \brief Convert a given SCCP option to SUA and add it to given xua_msg + * \param xua caller-provided xUA message to which option is to be added + * \param[in] sccp_opt_type SCCP option type (PNC) + * \param[in] opt_len size of \ref opt in bytes + * \param[in] opt pointer to wire-format encoded SCCP option data + * \returns 0 in case of success; negative on error */ +static int xua_msg_add_sccp_opt(struct xua_msg *xua, uint8_t sccp_opt_type, + uint16_t opt_len, uint8_t *opt) +{ + switch (sccp_opt_type) { + case SCCP_PNC_DESTINATION_LOCAL_REFERENCE: + if (opt_len != 3) + return -EINVAL; + xua_msg_add_u32(xua, SUA_IEI_DEST_REF, load_24be(opt)); + break; + case SCCP_PNC_SOURCE_LOCAL_REFERENCE: + if (opt_len != 3) + return -EINVAL; + xua_msg_add_u32(xua, SUA_IEI_SRC_REF, load_24be(opt)); + break; + case SCCP_PNC_CALLED_PARTY_ADDRESS: + if (opt_len < 3) + return -EINVAL; + sccp_addr_to_sua(xua, SUA_IEI_DEST_ADDR, opt, opt_len); + break; + case SCCP_PNC_CALLING_PARTY_ADDRESS: + if (opt_len < 3) + return -EINVAL; + sccp_addr_to_sua(xua, SUA_IEI_SRC_ADDR, opt, opt_len); + break; + case SCCP_PNC_PROTOCOL_CLASS: + if (opt_len < 1) + return -EINVAL; + xua_msg_add_u32(xua, SUA_IEI_PROTO_CLASS, *opt); + break; + case SCCP_PNC_CREDIT: + if (opt_len != 1) + return -EINVAL; + xua_msg_add_u32(xua, SUA_IEI_IMPORTANCE, *opt & 0x7); + break; + case SCCP_PNC_RELEASE_CAUSE: + if (opt_len != 1) + return -EINVAL; + xua_msg_add_u32(xua, SUA_IEI_CAUSE, SUA_CAUSE_T_RELEASE | *opt); + break; + case SCCP_PNC_RETURN_CAUSE: + if (opt_len != 1) + return -EINVAL; + xua_msg_add_u32(xua, SUA_IEI_CAUSE, SUA_CAUSE_T_RETURN | *opt); + break; + case SCCP_PNC_RESET_CAUSE: + if (opt_len != 1) + return -EINVAL; + xua_msg_add_u32(xua, SUA_IEI_CAUSE, SUA_CAUSE_T_RESET | *opt); + break; + case SCCP_PNC_ERROR_CAUSE: + if (opt_len != 1) + return -EINVAL; + xua_msg_add_u32(xua, SUA_IEI_CAUSE, SUA_CAUSE_T_ERROR | *opt); + break; + case SCCP_PNC_REFUSAL_CAUSE: + if (opt_len != 1) + return -EINVAL; + xua_msg_add_u32(xua, SUA_IEI_CAUSE, SUA_CAUSE_T_REFUSAL | *opt); + break; + case SCCP_PNC_DATA: + xua_msg_add_data(xua, SUA_IEI_DATA, opt_len, opt); + break; + case SCCP_PNC_HOP_COUNTER: + if (opt_len != 1) + return -EINVAL; + xua_msg_add_u32(xua, SUA_IEI_S7_HOP_CTR, *opt); + break; + case SCCP_PNC_IMPORTANCE: + if (opt_len != 1) + return -EINVAL; + xua_msg_add_u32(xua, SUA_IEI_IMPORTANCE, *opt & 0x7); + break; + case SCCP_PNC_LONG_DATA: + xua_msg_add_data(xua, SUA_IEI_DATA, opt_len, opt); + break; + case SCCP_PNC_SEGMENTATION: + case SCCP_PNC_SEGMENTING: + case SCCP_PNC_RECEIVE_SEQ_NUMBER: + /* only in class 3 */ + case SCCP_PNC_SEQUENCING: + /* only in class 3 */ + default: + LOGP(DLSUA, LOGL_ERROR, "Unsupported SCCP option type %u\n", + sccp_opt_type); + return -1; + } + return 0; +} + +/*! \brief append a SCCP option header to the given message + * \param msg Message to which header is to be appended + * \param[in] pnc PNC of the option header + * \param[in] len length of the option, excluding the header */ +static void msgb_put_sccp_opt_hdr(struct msgb *msg, uint8_t pnc, uint8_t len) +{ + msgb_put_u8(msg, pnc); + msgb_put_u8(msg, len); +} + +/*! \brief append a SCCP option to the given message + * \param msg Message to which option is to be appended + * \param[in] pnc PNC of the option header + * \param[in] len length of the option, excluding the header + * \param[in] data actual data to be appended */ +static void msgb_put_sccp_opt(struct msgb *msg, uint8_t pnc, uint8_t len, const uint8_t *data) +{ + uint8_t *cur; + + msgb_put_sccp_opt_hdr(msg, pnc, len); + cur = msgb_put(msg, len); + memcpy(cur, data, len); +} + +/*! \brief Convert a given SUA option/IE to SCCP and add it to given * msgb + * \param msg caller-provided message buffer to which option is to be appended + * \param[in] opt xUA option/IE (messge part) to be converted+added + * \returns 0 in case of success; negative on error */ +static int sccp_msg_add_sua_opt(struct msgb *msg, struct xua_msg_part *opt) +{ + uint32_t tmp32; + uint8_t pnc, *lenptr; + int rc; + + switch (opt->tag) { + case SUA_IEI_DEST_REF: + msgb_put_sccp_opt_hdr(msg, SCCP_PNC_DESTINATION_LOCAL_REFERENCE, 3); + msgb_put_u24be(msg, xua_msg_part_get_u32(opt)); + break; + case SUA_IEI_SRC_REF: + msgb_put_sccp_opt_hdr(msg, SCCP_PNC_SOURCE_LOCAL_REFERENCE, 3); + msgb_put_u24be(msg, xua_msg_part_get_u32(opt)); + break; + case SUA_IEI_DEST_ADDR: + msgb_put_u8(msg, SCCP_PNC_CALLED_PARTY_ADDRESS); + lenptr = msgb_put(msg, 1); + rc = sua_addr_to_sccp(msg, opt); + if (rc < 0) + return rc; + *lenptr = rc; + break; + case SUA_IEI_SRC_ADDR: + msgb_put_u8(msg, SCCP_PNC_CALLING_PARTY_ADDRESS); + lenptr = msgb_put(msg, 1); + rc = sua_addr_to_sccp(msg, opt); + if (rc < 0) + return rc; + *lenptr = rc; + break; + case SUA_IEI_PROTO_CLASS: + msgb_put_sccp_opt_hdr(msg, SCCP_PNC_PROTOCOL_CLASS, 1); + msgb_put_u8(msg, xua_msg_part_get_u32(opt)); + break; + case SUA_IEI_CREDIT: + msgb_put_sccp_opt_hdr(msg, SCCP_PNC_CREDIT, 1); + msgb_put_u8(msg, xua_msg_part_get_u32(opt) & 0x7); + break; + case SUA_IEI_CAUSE: + tmp32 = xua_msg_part_get_u32(opt); + switch (tmp32 & SUA_CAUSE_T_MASK) { + case SUA_CAUSE_T_RETURN: + pnc = SCCP_PNC_RETURN_CAUSE; + break; + case SUA_CAUSE_T_REFUSAL: + pnc = SCCP_PNC_REFUSAL_CAUSE; + break; + case SUA_CAUSE_T_RELEASE: + pnc = SCCP_PNC_RELEASE_CAUSE; + break; + case SUA_CAUSE_T_RESET: + pnc = SCCP_PNC_RESET_CAUSE; + break; + case SUA_CAUSE_T_ERROR: + pnc = SCCP_PNC_ERROR_CAUSE; + break; + default: + LOGP(DLSUA, LOGL_ERROR, "Unknown SUA Cause Class 0x%04x\n", tmp32); + return -EINVAL; + } + msgb_put_sccp_opt_hdr(msg, pnc, 1); + msgb_put_u8(msg, tmp32 & 0xff); + break; + case SUA_IEI_DATA: + msgb_put_sccp_opt(msg, SCCP_PNC_DATA, opt->len, opt->dat); + break; + case SUA_IEI_S7_HOP_CTR: + msgb_put_sccp_opt_hdr(msg, SCCP_PNC_HOP_COUNTER, 1); + msgb_put_u8(msg, xua_msg_part_get_u32(opt)); + break; + case SUA_IEI_IMPORTANCE: + msgb_put_sccp_opt_hdr(msg, SCCP_PNC_IMPORTANCE, 1); + msgb_put_u8(msg, xua_msg_part_get_u32(opt) & 0x7); + break; + case SUA_IEI_ROUTE_CTX: + break; + case SUA_IEI_SEQ_CTRL: + /* TODO */ + break; + default: + LOGP(DLSUA, LOGL_ERROR, "Unknown SUA IEI 0x%04x\n", opt->tag); + return -1; + } + return 0; +} + +/*! \brief convert SCCP optional part to list of SUA options + * \param[in] msg Message buffer holding SCCP message + * \param[in] ptr_opt address of relative pointer to optional part + * \param xua caller-provided xUA message to which options are added + * \returns \ref xua in case of success, NULL on error (xua not freed!) */ +static struct xua_msg *sccp_to_xua_opt(struct msgb *msg, uint8_t *ptr_opt, struct xua_msg *xua) +{ + uint8_t *opt_start, *oneopt; + + /* some bounds checking */ + if (ptr_opt < msg->data || ptr_opt > msg->tail) + return NULL; + opt_start = ptr_opt + *ptr_opt; + if (opt_start > msg->tail) + return NULL; + + oneopt = opt_start; + + while (oneopt < msg->tail) { + uint8_t opt_type = oneopt[0]; + + if (opt_type == SCCP_PNC_END_OF_OPTIONAL) + return xua; + + if (opt_type == SCCP_PNC_LONG_DATA) { + uint16_t opt_len16; + /* two byte length field */ + if (oneopt + 2 > msg->tail) + return NULL; + opt_len16 = oneopt[1] << 8 | oneopt[2]; + if (oneopt + 3 + opt_len16 > msg->tail) + return NULL; + xua_msg_add_sccp_opt(xua, opt_type, opt_len16, oneopt+3); + oneopt += 3 + opt_len16; + } else { + uint8_t opt_len; + /* one byte length field */ + if (oneopt + 1 > msg->tail) + return NULL; + + opt_len = oneopt[1]; + if (oneopt + 2 + opt_len > msg->tail) + return NULL; + xua_msg_add_sccp_opt(xua, opt_type, opt_len, oneopt+2); + oneopt += 2 + opt_len; + } + } + return NULL; +} + +#define MAX_IES 6 +#define NUM_SCCP_MSGT (SCCP_MSG_TYPE_LUDTS+1) + +/* This table indicates which information elements are mandatory and not + * optional in SCCP, per message type */ +static const uint16_t sccp_mandatory[NUM_SCCP_MSGT][MAX_IES] = { + /* Table 3/Q.713 */ + [SCCP_MSG_TYPE_CR] = { + SUA_IEI_SRC_REF, SUA_IEI_PROTO_CLASS, SUA_IEI_DEST_ADDR , 0 + }, + /* Table 4/Q.713 */ + [SCCP_MSG_TYPE_CC] = { + SUA_IEI_DEST_REF, SUA_IEI_SRC_REF, SUA_IEI_PROTO_CLASS, 0 + }, + /* Table 5/Q.713 */ + [SCCP_MSG_TYPE_CREF] = { + SUA_IEI_DEST_REF, SUA_IEI_CAUSE, 0 + }, + /* Table 6/Q.713 */ + [SCCP_MSG_TYPE_RLSD] = { + SUA_IEI_DEST_REF, SUA_IEI_SRC_REF, SUA_IEI_CAUSE, 0 + }, + /* Table 7/Q.713 */ + [SCCP_MSG_TYPE_RLC] = { + SUA_IEI_DEST_REF, SUA_IEI_SRC_REF, 0 + }, + /* Table 8/Q.713 */ + [SCCP_MSG_TYPE_DT1] = { + SUA_IEI_DEST_REF, SUA_IEI_SEGMENTATION, 0 + }, + /* Table 9/Q.713 */ + [SCCP_MSG_TYPE_DT2] = { + SUA_IEI_DEST_REF, SUA_IEI_SEGMENTATION, 0 + }, + /* Table 10/Q.713 */ + [SCCP_MSG_TYPE_AK] = { + SUA_IEI_DEST_REF, SUA_IEI_RX_SEQ_NR, 0 + }, + /* Table 11/Q.713 */ + [SCCP_MSG_TYPE_UDT] = { + SUA_IEI_PROTO_CLASS, SUA_IEI_DEST_ADDR, + SUA_IEI_SRC_ADDR, SUA_IEI_DATA, 0 + }, + /* Table 12/Q.713 */ + [SCCP_MSG_TYPE_UDTS] = { + SUA_IEI_CAUSE, SUA_IEI_DEST_ADDR, SUA_IEI_SRC_ADDR, SUA_IEI_DATA, 0 + }, + /* Table 13/Q.713 */ + [SCCP_MSG_TYPE_ED] = { + SUA_IEI_DEST_REF, 0 + }, + /* Table 14/Q.713 */ + [SCCP_MSG_TYPE_EA] = { + SUA_IEI_DEST_REF, 0 + }, + /* Table 15/Q.713 */ + [SCCP_MSG_TYPE_RSR] = { + SUA_IEI_DEST_REF, SUA_IEI_SRC_REF, SUA_IEI_CAUSE, 0 + }, + /* Table 16/Q.713 */ + [SCCP_MSG_TYPE_RSC] = { + SUA_IEI_DEST_REF, SUA_IEI_SRC_REF, 0 + }, + /* Table 17/Q.713 */ + [SCCP_MSG_TYPE_ERR] = { + SUA_IEI_DEST_REF, SUA_IEI_CAUSE, 0 + }, + /* Table 18/Q.713 */ + [SCCP_MSG_TYPE_IT] = { + SUA_IEI_DEST_REF, SUA_IEI_SRC_REF, SUA_IEI_PROTO_CLASS, + SUA_IEI_SEGMENTATION, SUA_IEI_CREDIT, 0 + }, + /* Table 19/Q.713 */ + [SCCP_MSG_TYPE_XUDT] = { + SUA_IEI_PROTO_CLASS, SUA_IEI_S7_HOP_CTR, + SUA_IEI_DEST_ADDR, SUA_IEI_SRC_ADDR, SUA_IEI_DATA, 0 + }, + /* Table 20/Q.713 */ + [SCCP_MSG_TYPE_XUDTS] = { + SUA_IEI_CAUSE, SUA_IEI_S7_HOP_CTR, SUA_IEI_DEST_ADDR, + SUA_IEI_SRC_ADDR, SUA_IEI_DATA, 0 + }, + /* Table 21/Q.713 */ + [SCCP_MSG_TYPE_LUDT] = { + SUA_IEI_PROTO_CLASS, SUA_IEI_S7_HOP_CTR, + SUA_IEI_DEST_ADDR, SUA_IEI_SRC_ADDR, SUA_IEI_DATA, 0 + }, + /* Table 22/Q.713 */ + [SCCP_MSG_TYPE_LUDTS] = { + SUA_IEI_CAUSE, SUA_IEI_S7_HOP_CTR, SUA_IEI_DEST_ADDR, + SUA_IEI_SRC_ADDR, SUA_IEI_DATA, 0 + }, +}; + +static bool sccp_is_mandatory(enum sccp_message_types type, const struct xua_msg_part *part) +{ + unsigned int i; + + if (type > ARRAY_SIZE(sccp_mandatory)) + return false; + + for (i = 0; i < MAX_IES; i++) { + uint16_t val = sccp_mandatory[type][i]; + if (val == 0) { + /* end of list, don't iterate further */ + return false; + } + if (val == part->tag) { + /* found in list, it's mandatory */ + return true; + } + } + /* not mandatory */ + return false; +} + +static int xua_ies_to_sccp_opts(struct msgb *msg, uint8_t *ptr_opt, + enum sccp_message_types type, struct xua_msg *xua) +{ + struct xua_msg_part *part; + + /* store relative pointer to start of optional part */ + *ptr_opt = msg->tail - ptr_opt; + + llist_for_each_entry(part, &xua->headers, entry) { + /* make sure we don't add a SCCP option for information + * that is already present in mandatory fixed or + * mandatory variable parts of the header */ + if (!sccp_is_mandatory(type, part)) + sccp_msg_add_sua_opt(msg, part); + } + msgb_put_u8(msg, SCCP_PNC_END_OF_OPTIONAL); + + return 0; +} + +/* store a 'local reference' as big-eidian 24bit value at local_ref */ +static void store_local_ref(struct sccp_source_reference *local_ref, struct xua_msg *xua, uint16_t iei) +{ + uint32_t tmp32 = xua_msg_get_u32(xua, iei); + local_ref->octet1 = (tmp32 >> 16) & 0xff; + local_ref->octet2 = (tmp32 >> 8) & 0xff; + local_ref->octet3 = tmp32 & 0xff; +} + +static struct xua_msg *sccp_to_xua_cr(struct msgb *msg, struct xua_msg *xua) +{ + struct sccp_connection_request *req = (struct sccp_connection_request *)msg->l2h; + + /* Fixed Part */ + xua_msg_add_u32(xua, SUA_IEI_PROTO_CLASS, req->proto_class); + xua_msg_add_u32(xua, SUA_IEI_SRC_REF, load_24be(&req->source_local_reference)); + /* Variable Part */ + if (!sccp_ptr_part_consistent(msg, &req->variable_called)) + return NULL; + sccp_addr_to_sua_ptr(xua, SUA_IEI_DEST_ADDR, msg, &req->variable_called); + /* Optional Part */ + return sccp_to_xua_opt(msg, &req->optional_start, xua); +} + +static int sua_to_sccp_cr(struct msgb *msg, struct xua_msg *xua) +{ + struct sccp_connection_request *req; + req = (struct sccp_connection_request *) msgb_put(msg, sizeof(*req)); + + /* Fixed Part */ + req->type = SCCP_MSG_TYPE_CR; + req->proto_class = xua_msg_get_u32(xua, SUA_IEI_PROTO_CLASS); + store_local_ref(&req->source_local_reference, xua, SUA_IEI_SRC_REF); + /* Variable Part */ + sccp_add_var_addr(msg, &req->variable_called, xua, SUA_IEI_DEST_ADDR); + + /* Optional Part */ + return xua_ies_to_sccp_opts(msg, &req->optional_start, req->type, xua); +} + +static struct xua_msg *sccp_to_xua_cc(struct msgb *msg, struct xua_msg *xua) +{ + struct sccp_connection_confirm *cnf = (struct sccp_connection_confirm *)msg->l2h; + + /* Fixed Part */ + xua_msg_add_u32(xua, SUA_IEI_PROTO_CLASS, cnf->proto_class); + xua_msg_add_u32(xua, SUA_IEI_DEST_REF, load_24be(&cnf->destination_local_reference)); + xua_msg_add_u32(xua, SUA_IEI_SRC_REF, load_24be(&cnf->source_local_reference)); + /* Optional Part */ + return sccp_to_xua_opt(msg, &cnf->optional_start, xua); +} + +static int sua_to_sccp_cc(struct msgb *msg, struct xua_msg *xua) +{ + struct sccp_connection_confirm *cnf; + cnf = (struct sccp_connection_confirm *) msgb_put(msg, sizeof(*cnf)); + + /* Fixed Part */ + cnf->type = SCCP_MSG_TYPE_CC; + cnf->proto_class = xua_msg_get_u32(xua, SUA_IEI_PROTO_CLASS); + store_local_ref(&cnf->destination_local_reference, xua, SUA_IEI_DEST_REF); + store_local_ref(&cnf->source_local_reference, xua, SUA_IEI_SRC_REF); + /* Optional Part */ + return xua_ies_to_sccp_opts(msg, &cnf->optional_start, cnf->type, xua); +} + +static struct xua_msg *sccp_to_xua_cref(struct msgb *msg, struct xua_msg *xua) +{ + struct sccp_connection_refused *ref = (struct sccp_connection_refused *)msg->l2h; + + /* Fixed Part */ + xua_msg_add_u32(xua, SUA_IEI_DEST_REF, load_24be(&ref->destination_local_reference)); + xua_msg_add_u32(xua, SUA_IEI_CAUSE, SUA_CAUSE_T_REFUSAL | ref->cause); + /* Optional Part */ + return sccp_to_xua_opt(msg, &ref->optional_start, xua); +} + +static int sua_to_sccp_cref(struct msgb *msg, struct xua_msg *xua) +{ + struct sccp_connection_refused *ref; + ref = (struct sccp_connection_refused *) msgb_put(msg, sizeof(*ref)); + + /* Fixed Part */ + ref->type = SCCP_MSG_TYPE_CREF; + store_local_ref(&ref->destination_local_reference, xua, SUA_IEI_DEST_REF); + ref->cause = xua_msg_get_u32(xua, SUA_IEI_CAUSE) & 0xff; + /* Optional Part */ + return xua_ies_to_sccp_opts(msg, &ref->optional_start, ref->type, xua); +} + +static struct xua_msg *sccp_to_xua_rlsd(struct msgb *msg, struct xua_msg *xua) +{ + struct sccp_connection_released *rlsd = (struct sccp_connection_released *)msg->l2h; + + /* Fixed Part */ + xua_msg_add_u32(xua, SUA_IEI_DEST_REF, load_24be(&rlsd->destination_local_reference)); + xua_msg_add_u32(xua, SUA_IEI_SRC_REF, load_24be(&rlsd->source_local_reference)); + xua_msg_add_u32(xua, SUA_IEI_CAUSE, SUA_CAUSE_T_RELEASE | rlsd->release_cause); + /* Optional Part */ + return sccp_to_xua_opt(msg, &rlsd->optional_start, xua); +} + +static int sua_to_sccp_rlsd(struct msgb *msg, struct xua_msg *xua) +{ + struct sccp_connection_released *rlsd; + rlsd =(struct sccp_connection_released *) msgb_put(msg, sizeof(*rlsd)); + + /* Fixed Part */ + rlsd->type = SCCP_MSG_TYPE_RLSD; + store_local_ref(&rlsd->destination_local_reference, xua, SUA_IEI_DEST_REF); + store_local_ref(&rlsd->source_local_reference, xua, SUA_IEI_SRC_REF); + rlsd->release_cause = xua_msg_get_u32(xua, SUA_IEI_CAUSE) & 0xff; + + /* Optional Part */ + return xua_ies_to_sccp_opts(msg, &rlsd->optional_start, rlsd->type, xua); +} + +static struct xua_msg *sccp_to_xua_rlc(struct msgb *msg, struct xua_msg *xua) +{ + struct sccp_connection_release_complete *rlc; + rlc = (struct sccp_connection_release_complete *) msg->l2h; + + /* Fixed Part */ + xua_msg_add_u32(xua, SUA_IEI_DEST_REF, load_24be(&rlc->destination_local_reference)); + xua_msg_add_u32(xua, SUA_IEI_SRC_REF, load_24be(&rlc->source_local_reference)); + return xua; +} + +static int sua_to_sccp_rlc(struct msgb *msg, struct xua_msg *xua) +{ + struct sccp_connection_release_complete *rlc; + rlc = (struct sccp_connection_release_complete *) msgb_put(msg, sizeof(*rlc)); + + /* Fixed Part */ + rlc->type = SCCP_MSG_TYPE_RLC; + store_local_ref(&rlc->destination_local_reference, xua, SUA_IEI_DEST_REF); + store_local_ref(&rlc->source_local_reference, xua, SUA_IEI_SRC_REF); + return 0; +} + +static struct xua_msg *sccp_to_xua_dt1(struct msgb *msg, struct xua_msg *xua) +{ + struct sccp_data_form1 *dt1 = (struct sccp_data_form1 *) msg->l2h; + + /* Fixed Part */ + xua_msg_add_u32(xua, SUA_IEI_DEST_REF, load_24be(&dt1->destination_local_reference)); + xua_msg_add_u32(xua, SUA_IEI_SEGMENTATION, dt1->segmenting); + /* Variable Part */ + if (!sccp_ptr_part_consistent(msg, &dt1->variable_start)) + return NULL; + sccp_data_to_sua_ptr(xua, SUA_IEI_DATA, msg, &dt1->variable_start); + return xua; +} + +static int sua_to_sccp_dt1(struct msgb *msg, struct xua_msg *xua) +{ + struct sccp_data_form1 *dt1; + dt1 = (struct sccp_data_form1 *) msgb_put(msg, sizeof(*dt1)); + + /* Fixed Part */ + dt1->type = SCCP_MSG_TYPE_DT1; + store_local_ref(&dt1->destination_local_reference, xua, SUA_IEI_DEST_REF); + dt1->segmenting = xua_msg_get_u32(xua, SUA_IEI_SEGMENTATION); + /* Variable Part */ + sccp_add_variable_part(msg, &dt1->variable_start, xua, SUA_IEI_DATA); + return 0; +} + +static struct xua_msg *sccp_to_xua_udt(struct msgb *msg, struct xua_msg *xua) +{ + struct sccp_data_unitdata *udt = (struct sccp_data_unitdata *)msg->l2h; + + /* Fixed Part */ + xua_msg_add_u32(xua, SUA_IEI_PROTO_CLASS, udt->proto_class); + /* Variable Part */ + if (!sccp_ptr_part_consistent(msg, &udt->variable_called)) + return NULL; + sccp_addr_to_sua_ptr(xua, SUA_IEI_DEST_ADDR, msg, &udt->variable_called); + if (!sccp_ptr_part_consistent(msg, &udt->variable_calling)) + return NULL; + sccp_addr_to_sua_ptr(xua, SUA_IEI_SRC_ADDR, msg, &udt->variable_calling); + if (!sccp_ptr_part_consistent(msg, &udt->variable_data)) + return NULL; + sccp_data_to_sua_ptr(xua, SUA_IEI_DATA, msg, &udt->variable_data); + return xua; + +} + +static int sua_to_sccp_udt(struct msgb *msg, struct xua_msg *xua) +{ + struct sccp_data_unitdata *udt; + udt = (struct sccp_data_unitdata *) msgb_put(msg, sizeof(*udt)); + + /* Fixed Part */ + udt->type = SCCP_MSG_TYPE_UDT; + udt->proto_class = xua_msg_get_u32(xua, SUA_IEI_PROTO_CLASS); + /* Variable Part */ + sccp_add_var_addr(msg, &udt->variable_called, xua, SUA_IEI_DEST_ADDR); + sccp_add_var_addr(msg, &udt->variable_calling, xua, SUA_IEI_SRC_ADDR); + sccp_add_variable_part(msg, &udt->variable_data, xua, SUA_IEI_DATA); + return 0; +} + +static struct xua_msg *sccp_to_xua_udts(struct msgb *msg, struct xua_msg *xua) +{ + struct sccp_data_unitdata_service *udts; + udts =(struct sccp_data_unitdata_service *)msg->l2h; + + /* Fixed Part */ + xua_msg_add_u32(xua, SUA_IEI_CAUSE, SUA_CAUSE_T_RETURN | udts->return_cause); + /* Variable Part */ + if (!sccp_ptr_part_consistent(msg, &udts->variable_called)) + return NULL; + sccp_addr_to_sua_ptr(xua, SUA_IEI_DEST_ADDR, msg, &udts->variable_called); + if (!sccp_ptr_part_consistent(msg, &udts->variable_calling)) + return NULL; + sccp_addr_to_sua_ptr(xua, SUA_IEI_SRC_ADDR, msg, &udts->variable_calling); + if (!sccp_ptr_part_consistent(msg, &udts->variable_data)) + return NULL; + sccp_data_to_sua_ptr(xua, SUA_IEI_DATA, msg, &udts->variable_data); + return xua; + +} + +static int sua_to_sccp_udts(struct msgb *msg, struct xua_msg *xua) +{ + struct sccp_data_unitdata_service *udts; + udts = (struct sccp_data_unitdata_service *) msgb_put(msg, sizeof(*udts)); + + /* Fixed Part */ + udts->type = SCCP_MSG_TYPE_UDTS; + udts->return_cause = xua_msg_get_u32(xua, SUA_IEI_CAUSE) & 0xff; + /* Variable Part */ + sccp_add_var_addr(msg, &udts->variable_called, xua, SUA_IEI_DEST_ADDR); + sccp_add_var_addr(msg, &udts->variable_calling, xua, SUA_IEI_SRC_ADDR); + sccp_add_variable_part(msg, &udts->variable_data, xua, SUA_IEI_DATA); + return 0; +} + +static struct xua_msg *sccp_to_xua_it(struct msgb *msg, struct xua_msg *xua) +{ + struct sccp_data_it *it = (struct sccp_data_it *)msg->l2h; + + /* Fixed Part */ + xua_msg_add_u32(xua, SUA_IEI_PROTO_CLASS, it->proto_class); + xua_msg_add_u32(xua, SUA_IEI_SRC_REF, load_24be(&it->source_local_reference)); + xua_msg_add_u32(xua, SUA_IEI_DEST_REF, load_24be(&it->destination_local_reference)); + if ((it->proto_class & 0xF) == 3) { + //xua_msg_add_u32(xua, SUA_IEI_SEQUENCING, it->sequencing); + xua_msg_add_u32(xua, SUA_IEI_CREDIT, it->credit); + } + return xua; +} + +static int sua_to_sccp_it(struct msgb *msg, struct xua_msg *xua) +{ + struct sccp_data_it *it; + it = (struct sccp_data_it *) msgb_put(msg, sizeof(*it)); + + /* Fixed Part */ + it->type = SCCP_MSG_TYPE_IT; + it->proto_class = xua_msg_get_u32(xua, SUA_IEI_PROTO_CLASS); + store_local_ref(&it->destination_local_reference, xua, SUA_IEI_DEST_REF); + store_local_ref(&it->source_local_reference, xua, SUA_IEI_SRC_REF); + if ((it->proto_class & 0xF) == 3) { + //it->sequencing + it->credit = xua_msg_get_u32(xua, SUA_IEI_CREDIT); + } + + return 0; +} + +static struct xua_msg *sccp_to_xua_err(struct msgb *msg, struct xua_msg *xua) +{ + struct sccp_proto_err *err = (struct sccp_proto_err *)msg->l2h; + + /* Fixed Part */ + xua_msg_add_u32(xua, SUA_IEI_DEST_REF, load_24be(&err->destination_local_reference)); + xua_msg_add_u32(xua, SUA_IEI_CAUSE, SUA_CAUSE_T_ERROR | err->error_cause); + return xua; +} + +static int sua_to_sccp_err(struct msgb *msg, struct xua_msg *xua) +{ + struct sccp_proto_err *err; + err = (struct sccp_proto_err *) msgb_put(msg, sizeof(*err)); + + /* Fixed Part */ + err->type = SCCP_MSG_TYPE_ERR; + store_local_ref(&err->destination_local_reference, xua, SUA_IEI_DEST_REF); + err->error_cause = xua_msg_get_u32(xua, SUA_IEI_CAUSE) & 0xff; + return 0; +} + +/*! \brief convert SCCP message to a SUA message + * \param[in] msg message buffer holding SCCP message at l2h + * \returns callee-allocated xUA message on success; NULL on error */ +struct xua_msg *osmo_sccp_to_xua(struct msgb *msg) +{ + struct xua_msg *xua; + + if (msgb_l2len(msg) < 1) { + LOGP(DLSUA, LOGL_ERROR, "Short SCCP Message, cannot transcode\n"); + return NULL; + } + + xua = xua_msg_alloc(); + if (!xua) + return NULL; + + switch (msg->l2h[0]) { + case SCCP_MSG_TYPE_CR: + xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_CORE); + return sccp_to_xua_cr(msg, xua); + case SCCP_MSG_TYPE_CC: + xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_COAK); + return sccp_to_xua_cc(msg, xua); + case SCCP_MSG_TYPE_CREF: + xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_COREF); + return sccp_to_xua_cref(msg, xua); + case SCCP_MSG_TYPE_RLSD: + xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_RELRE); + return sccp_to_xua_rlsd(msg, xua); + case SCCP_MSG_TYPE_RLC: + xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_RELCO); + return sccp_to_xua_rlc(msg, xua); + case SCCP_MSG_TYPE_DT1: + xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_CODT); + return sccp_to_xua_dt1(msg, xua); + case SCCP_MSG_TYPE_UDT: + xua->hdr = XUA_HDR(SUA_MSGC_CL, SUA_CL_CLDT); + return sccp_to_xua_udt(msg, xua); + case SCCP_MSG_TYPE_UDTS: + xua->hdr = XUA_HDR(SUA_MSGC_CL, SUA_CL_CLDR); + return sccp_to_xua_udts(msg, xua); + case SCCP_MSG_TYPE_IT: + xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_COIT); + return sccp_to_xua_it(msg, xua); + case SCCP_MSG_TYPE_ERR: + xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_COERR); + return sccp_to_xua_err(msg, xua); + /* Unsupported Message Types */ + case SCCP_MSG_TYPE_DT2: + case SCCP_MSG_TYPE_AK: + case SCCP_MSG_TYPE_ED: + case SCCP_MSG_TYPE_EA: + case SCCP_MSG_TYPE_RSR: + case SCCP_MSG_TYPE_RSC: + case SCCP_MSG_TYPE_XUDT: + case SCCP_MSG_TYPE_XUDTS: + case SCCP_MSG_TYPE_LUDT: + case SCCP_MSG_TYPE_LUDTS: + default: + LOGP(DLSUA, LOGL_ERROR, "Unsupported SCCP message type %u\n", + msg->l2h[0]); + xua_msg_free(xua); + return NULL; + } + + return NULL; +} + +/*! \brief convert parsed SUA message to SCCP message + * \param[in] xua parsed SUA message to be converted + * \returns callee-allocated msgb containing encoded SCCP message */ +struct msgb *osmo_sua_to_sccp(struct xua_msg *xua) +{ + struct msgb *msg = sccp_msgb_alloc("SCCP from SUA"); + int rc; + + switch (xua->hdr.msg_class) { + case SUA_MSGC_CL: + switch (xua->hdr.msg_type) { + case SUA_CL_CLDT: + rc = sua_to_sccp_udt(msg, xua); + break; + case SUA_CL_CLDR: + rc = sua_to_sccp_udts(msg, xua); + break; + default: + LOGP(DLSUA, LOGL_ERROR, "Unsupported SUA message %s\n", + xua_hdr_dump(xua, &xua_dialect_sua)); + goto out_err; + } + break; + case SUA_MSGC_CO: + switch (xua->hdr.msg_type) { + case SUA_CO_CORE: + rc = sua_to_sccp_cr(msg, xua); + break; + case SUA_CO_COAK: + rc = sua_to_sccp_cc(msg, xua); + break; + case SUA_CO_COREF: + rc = sua_to_sccp_cref(msg, xua); + break; + case SUA_CO_RELRE: + rc = sua_to_sccp_rlsd(msg, xua); + break; + case SUA_CO_RELCO: + rc = sua_to_sccp_rlc(msg, xua); + break; + case SUA_CO_CODT: + rc = sua_to_sccp_dt1(msg, xua); + break; + case SUA_CO_COIT: + rc = sua_to_sccp_it(msg, xua); + break; + case SUA_CO_COERR: + rc = sua_to_sccp_err(msg, xua); + break; + default: + LOGP(DLSUA, LOGL_ERROR, "Unsupported SUA message %s\n", + xua_hdr_dump(xua, &xua_dialect_sua)); + goto out_err; + } + break; + default: + LOGP(DLSUA, LOGL_ERROR, "Unsupported SUA message class %s\n", + xua_hdr_dump(xua, &xua_dialect_sua)); + goto out_err; + } + + if (rc < 0) + goto out_err; + + return msg; + +out_err: + msgb_free(msg); + return NULL; +} -- To view, visit https://gerrit.osmocom.org/2213 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I8151a9b08a0b0ca97b9c73105ad4548512ce3be8 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Mon Apr 3 20:22:10 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 3 Apr 2017 20:22:10 +0000 Subject: [PATCH] libosmo-sccp[master]: Add tests for xUA code + SCCP/SUA transcoding Message-ID: Review at https://gerrit.osmocom.org/2214 Add tests for xUA code + SCCP/SUA transcoding Change-Id: I7ce038d72dca18fb83d5a12519c9a48267e52ab8 --- M configure.ac M tests/Makefile.am M tests/testsuite.at A tests/xua/Makefile.am A tests/xua/sccp_test_data.c A tests/xua/sccp_test_data.h A tests/xua/xua_test.c A tests/xua/xua_test.ok 8 files changed, 654 insertions(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/14/2214/1 diff --git a/configure.ac b/configure.ac index 2e55c57..09e7adb 100644 --- a/configure.ac +++ b/configure.ac @@ -56,6 +56,7 @@ tests/mtp/Makefile tests/m2ua/Makefile tests/sigtran/Makefile + tests/xua/Makefile tests/ss7/Makefile Makefile) diff --git a/tests/Makefile.am b/tests/Makefile.am index 9c251fe..6d3c96f 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,4 +1,4 @@ -SUBDIRS = sccp mtp m2ua sigtran ss7 +SUBDIRS = xua sccp mtp m2ua sigtran ss7 # The `:;' works around a Bash 3.2 bug when the output is not writeable. $(srcdir)/package.m4: $(top_srcdir)/configure.ac diff --git a/tests/testsuite.at b/tests/testsuite.at index 171f488..b810bdf 100644 --- a/tests/testsuite.at +++ b/tests/testsuite.at @@ -19,6 +19,12 @@ AT_CHECK([$abs_top_builddir/tests/sccp/sccp_test], [], [expout], [ignore]) AT_CLEANUP +AT_SETUP([xua]) +AT_KEYWORDS([xua]) +cat $abs_srcdir/xua/xua_test.ok > expout +AT_CHECK([$abs_top_builddir/tests/xua/xua_test], [], [expout], [ignore]) +AT_CLEANUP + AT_SETUP([ss7]) AT_KEYWORDS([ss7]) cat $abs_srcdir/ss7/ss7_test.ok > expout diff --git a/tests/xua/Makefile.am b/tests/xua/Makefile.am new file mode 100644 index 0000000..8ed65c2 --- /dev/null +++ b/tests/xua/Makefile.am @@ -0,0 +1,13 @@ +AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -Wall +AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) + +AM_LDFLAGS = -static +LDADD = $(top_builddir)/src/libosmo-sigtran.la \ + $(LIBOSMOCORE_LIBS) $(LIBOSMONETIF_LIBS) -lsctp + +EXTRA_DIST = xua_test.ok + +noinst_HEADERS = sccp_test_data.h +noinst_PROGRAMS = xua_test + +xua_test_SOURCES = xua_test.c sccp_test_data.c diff --git a/tests/xua/sccp_test_data.c b/tests/xua/sccp_test_data.c new file mode 100644 index 0000000..c7c8f27 --- /dev/null +++ b/tests/xua/sccp_test_data.c @@ -0,0 +1,102 @@ +#include + +/* BSC -> MSC */ +const uint8_t bssmap_reset[18] = { + 0x09, 0x00, 0x03, 0x05, 0x07, 0x02, 0x42, 0xfe, + 0x02, 0x42, 0xfe, 0x06, 0x00, 0x04, 0x30, 0x04, + 0x01, 0x20, +}; + +/* MSC -> BSC reset ack */ +const uint8_t bssmap_reset_ack[19] = { + 0x09, 0x00, 0x03, 0x07, 0x0b, 0x04, 0x43, 0x01, + 0x00, 0xfe, 0x04, 0x43, 0x5c, 0x00, 0xfe, 0x03, + 0x00, 0x01, 0x31, +}; + +/* MSC -> BSC paging, connection less */ +const uint8_t bssmap_paging[32] = { + 0x09, 0x00, 0x03, 0x07, 0x0b, 0x04, 0x43, 0x01, + 0x00, 0xfe, 0x04, 0x43, 0x5c, 0x00, 0xfe, 0x10, + 0x00, 0x0e, 0x52, 0x08, 0x08, 0x29, 0x47, 0x10, + 0x02, 0x01, 0x31, 0x97, 0x61, 0x1a, 0x01, 0x06, +}; + +/* MSC -> BSC paging, UDT without PC */ +const uint8_t bssmap_udt[28] = { + 0x09, 0x00, 0x03, 0x05, 0x07, 0x02, 0x42, 0xfe, + 0x02, 0x42, 0xfe, 0x10, 0x00, 0x0e, 0x52, 0x08, + 0x08, 0x29, 0x47, 0x10, 0x02, 0x01, 0x31, 0x97, + 0x61, 0x1a, 0x01, 0x06, +}; + +/* BSC -> MSC connection open */ +const uint8_t bssmap_cr[44] = { + 0x01, 0x01, 0x02, 0x03, 0x02, 0x02, 0x04, 0x02, + 0x42, 0xfe, 0x0f, 0x1f, 0x00, 0x1d, 0x57, 0x05, + 0x08, 0x00, 0x72, 0xf4, 0x80, 0x20, 0x12, 0xc3, + 0x50, 0x17, 0x10, 0x05, 0x24, 0x11, 0x03, 0x33, + 0x19, 0xa2, 0x08, 0x29, 0x47, 0x10, 0x02, 0x01, + 0x31, 0x97, 0x61, 0x00 +}; + +/* MSC -> BSC connection confirm */ +const uint8_t bssmap_cc[10] = { + 0x02, 0x01, 0x02, 0x03, 0x00, 0x00, 0x03, 0x02, 0x01, 0x00, +}; + +/* MSC -> BSC DTAP + * + * we fake a bit and make it BSC -> MSC... so the + * payload does not make any sense.. + */ +const uint8_t bssmap_dtap[22] = { + 0x06, 0x00, 0x00, 0x03, 0x00, 0x01, 0x0f, 0x01, 0x00, 0x0c, + 0x03, 0x05, 0x5c, 0x08, 0x11, 0x81, 0x33, 0x66, 0x02, 0x13, + 0x45, 0xf4, +}; + +/* MSC -> BSC clear command */ +const uint8_t bssmap_clear[13] = { + 0x06, 0x00, 0x00, 0x03, 0x00, 0x01, 0x06, 0x00, 0x04, 0x20, + 0x04, 0x01, 0x09, +}; + +/* MSC -> BSC released */ +const uint8_t bssmap_released[14] = { + 0x04, 0x00, 0x00, 0x03, 0x01, 0x02, 0x03, 0x00, 0x01, 0x0f, + 0x02, 0x23, 0x42, 0x00, +}; + +/* BSC -> MSC released */ +const uint8_t bssmap_release_complete[7] = { + 0x05, 0x01, 0x02, 0x03, 0x00, 0x00, 0x03 +}; + +/* message with a SCCP global title */ +const uint8_t tcap_global_title[183] = { + 0x09, + 0x81, 0x03, 0x0d, 0x18, 0x0a, 0x12, 0x07, 0x00, + 0x12, 0x04, 0x53, 0x84, 0x09, 0x00, 0x17, 0x0b, + 0x12, 0x06, 0x00, 0x12, 0x04, 0x44, 0x87, 0x20, + 0x00, 0x20, 0x65, 0x9a, 0x65, 0x81, 0x97, 0x48, + 0x04, 0x26, 0x00, 0x01, 0x98, 0x49, 0x04, 0x51, + 0x01, 0x03, 0xdf, 0x6c, 0x81, 0x88, 0xa1, 0x81, + 0x85, 0x02, 0x01, 0x44, 0x02, 0x01, 0x07, 0x30, + 0x80, 0xa7, 0x80, 0xa0, 0x80, 0x04, 0x01, 0x2b, + 0x30, 0x80, 0x30, 0x12, 0x83, 0x01, 0x10, 0x84, + 0x01, 0x07, 0x85, 0x07, 0x91, 0x44, 0x57, 0x76, + 0x67, 0x16, 0x97, 0x86, 0x01, 0x20, 0x30, 0x06, + 0x82, 0x01, 0x18, 0x84, 0x01, 0x04, 0x00, 0x00, + 0x00, 0x00, 0xa3, 0x06, 0x04, 0x01, 0x42, 0x84, + 0x01, 0x05, 0xa3, 0x06, 0x04, 0x01, 0x51, 0x84, + 0x01, 0x05, 0xa3, 0x06, 0x04, 0x01, 0x31, 0x84, + 0x01, 0x05, 0xa3, 0x09, 0x04, 0x01, 0x12, 0x84, + 0x01, 0x05, 0x82, 0x01, 0x02, 0xa3, 0x09, 0x04, + 0x01, 0x11, 0x84, 0x01, 0x05, 0x81, 0x01, 0x01, + 0xa3, 0x06, 0x04, 0x01, 0x14, 0x84, 0x01, 0x00, + 0xa3, 0x0b, 0x04, 0x01, 0x41, 0x84, 0x01, 0x04, + 0x30, 0x03, 0x83, 0x01, 0x10, 0xa3, 0x0b, 0x04, + 0x01, 0x41, 0x84, 0x01, 0x04, 0x30, 0x03, 0x82, + 0x01, 0x18, 0x00, 0x00, 0x00, 0x00 +}; diff --git a/tests/xua/sccp_test_data.h b/tests/xua/sccp_test_data.h new file mode 100644 index 0000000..3d70549 --- /dev/null +++ b/tests/xua/sccp_test_data.h @@ -0,0 +1,14 @@ +#pragma once +#include + +extern const uint8_t bssmap_reset[18]; +extern const uint8_t bssmap_reset_ack[19]; +extern const uint8_t bssmap_paging[32]; +extern const uint8_t bssmap_udt[28]; +extern const uint8_t bssmap_cr[44]; +extern const uint8_t bssmap_cc[10]; +extern const uint8_t bssmap_dtap[22]; +extern const uint8_t bssmap_clear[13]; +extern const uint8_t bssmap_released[14]; +extern const uint8_t bssmap_release_complete[7]; +extern const uint8_t tcap_global_title[183]; diff --git a/tests/xua/xua_test.c b/tests/xua/xua_test.c new file mode 100644 index 0000000..74d91c4 --- /dev/null +++ b/tests/xua/xua_test.c @@ -0,0 +1,386 @@ +/* (C) 2011 by Holger Hans Peter Freyther + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +#include "sccp_test_data.h" + +#include "../src/xua_internal.h" + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +static void test_isup_parse(void) +{ + const uint8_t party0[] = { 0x10, 0x32, 0x54, 0x76 }; + char digits[23] = ""; + int rc; + + rc = osmo_isup_party_parse(digits, party0, ARRAY_SIZE(party0), false); + printf("digits='%s' (%d)\n", digits, rc); + OSMO_ASSERT(rc == 8); + OSMO_ASSERT(!strcmp(digits, "01234567")); + + rc = osmo_isup_party_parse(digits, party0, ARRAY_SIZE(party0), true); + printf("digits='%s' (%d)\n", digits, rc); + OSMO_ASSERT(rc == 7); + OSMO_ASSERT(!strcmp(digits, "0123456")); +} + +/* SCCP Address Parsing */ + +static struct sccp_addr_testcase { + struct osmo_sccp_addr expected; + uint8_t *bin; + unsigned int bin_len; +}; + +static uint8_t addr_bin0[] = { 0x92, 0x06, 0x00, 0x12, 0x04, 0x19, 0x99, 0x96, 0x76, 0x39, 0x98 }; +static uint8_t addr_bin1[] = { 0x12, 0x08, 0x00, 0x12, 0x04, 0x19, 0x89, 0x96, 0x92, 0x99, 0x29 }; +static uint8_t addr_bin2[] = { 0x42, 0xfe }; + +static const struct sccp_addr_testcase sccp_addr_testcases[] = { + { + .expected = { + .presence = OSMO_SCCP_ADDR_T_GT | OSMO_SCCP_ADDR_T_SSN, + .ri = OSMO_SCCP_RI_GT, + .gt = { + .gti = OSMO_SCCP_GTI_TT_NPL_ENC_NAI, + .tt = 0, + .npi = OSMO_SCCP_NPI_E164_ISDN, + .nai = OSMO_SCCP_NAI_INTL, + .digits = "919969679389", + }, + .ssn = 6, + }, + .bin = addr_bin0, + .bin_len = ARRAY_SIZE(addr_bin0), + }, { + .expected = { + .presence = OSMO_SCCP_ADDR_T_GT | OSMO_SCCP_ADDR_T_SSN, + .ri = OSMO_SCCP_RI_GT, + .gt = { + .gti = OSMO_SCCP_GTI_TT_NPL_ENC_NAI, + .tt = 0, + .npi = OSMO_SCCP_NPI_E164_ISDN, + .nai = OSMO_SCCP_NAI_INTL, + .digits = "919869299992", + }, + .ssn = 8, + }, + .bin = addr_bin1, + .bin_len = ARRAY_SIZE(addr_bin1), + }, { + .expected = { + .presence = OSMO_SCCP_ADDR_T_SSN, + .ri = OSMO_SCCP_RI_SSN_PC, + .ssn = 254, + }, + .bin = addr_bin2, + .bin_len = ARRAY_SIZE(addr_bin2), + + }, +}; + +static int test_sccp_addr_parse(const struct osmo_sccp_addr *cmp, + const uint8_t *in, unsigned int in_len) +{ + struct osmo_sccp_addr osa; + int rc; + + memset(&osa, 0, sizeof(osa)); + rc = osmo_sccp_addr_parse(&osa, in, in_len); + if (rc < 0) + return rc; + + printf("expected: %s\n", osmo_sccp_addr_dump(cmp)); + printf("parsed: %s\n", osmo_sccp_addr_dump(&osa)); + + if (memcmp(&osa, cmp, sizeof(osa))) { + fprintf(stderr, "expected: %s\n", osmo_hexdump_nospc((uint8_t *)cmp, sizeof(*cmp))); + fprintf(stderr, "parsed: %s\n", osmo_hexdump_nospc((uint8_t *)&osa, sizeof(osa))); + } + + return 0; +} + +static void test_sccp_addr_parser(void) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(sccp_addr_testcases); i++) { + const struct sccp_addr_testcase *tcase = &sccp_addr_testcases[i]; + printf("sccp_addr_parse test case %u\n", i); + test_sccp_addr_parse(&tcase->expected, tcase->bin, tcase->bin_len); + } +} + +/* sccp_addr_testcases[0].expected.gt transcoded into a SUA Global Title IE */ +static const uint8_t expected_sua_gt[] = { + 0x80, 0x01, 0x00, 0x14, 0x00, 0x00, 0x00, 0x04, + 0x0c, 0x00, 0x01, 0x04, 0x19, 0x99, 0x96, 0x76, + 0x39, 0x98, 0x00, 0x00 +}; + +static void test_helpers(void) +{ + struct msgb *msg = msgb_alloc(1024, "foo"); + const struct osmo_sccp_gt *gt_in = &sccp_addr_testcases[0].expected.gt; + struct osmo_sccp_gt gt_out; + + printf("Testing Decoded GT -> SUA encoding\n"); + printf("IN: %s\n", osmo_sccp_gt_dump(gt_in)); + + /* encode sccp_addr to SUA GT */ + xua_part_add_gt(msg, gt_in); + OSMO_ASSERT(msgb_length(msg) == sizeof(expected_sua_gt)); + OSMO_ASSERT(!memcmp(msg->data, expected_sua_gt, sizeof(expected_sua_gt))); + + /* pull the tag+length value */ + msgb_pull(msg, 4); + + /* parse + compare */ + sua_parse_gt(>_out, msgb_data(msg), msgb_length(msg)); + printf("OUT:%s\n", osmo_sccp_gt_dump(>_out)); + OSMO_ASSERT(!memcmp(gt_in, >_out, sizeof(gt_out))); + + msgb_free(msg); +} + +/* SCCP Message Transcoding */ + +struct sccp2sua_testcase { + const char *name; + struct { + const uint8_t *bin; + unsigned int length; + } sccp; + struct { + struct xua_common_hdr hdr; + const struct xua_msg_part parts[32]; + } sua; +}; + +#define PANDSIZ(x) { x, ARRAY_SIZE(x) } +#define PARTU32(x, data) { .tag = x, .len = 4, .dat = (uint8_t *) data } +#define PARTARR(x, data) { .tag = x, .len = ARRAY_SIZE(data), .dat = (uint8_t *) data } + +const uint32_t sua_proto_class0 = 0; +const uint32_t sua_proto_class2 = 2; +const uint32_t sua_loc_ref_bsc = 0x10203; +const uint32_t sua_loc_ref_msc = 0x00003; +const uint32_t sua_cause0 = 0x00003; +const uint8_t sua_addr_ssn_bssmap[] = { 0x00, 0x02, 0x00, 0x07, 0x80, 0x03, 0x00, 0x08, 0x00, 0x00, 0x00, 0xfe }; +const uint8_t sua_addr_ssn_bssmap_pc1[] = { 0x00, 0x01, 0x00, 0x07, 0x80, 0x02, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x80, 0x03, 0x00, 0x08, 0x00, 0x00, 0x00, 0xfe }; +const uint8_t sua_addr_ssn_bssmap_pc92[] = { 0x00, 0x01, 0x00, 0x07, 0x80, 0x02, 0x00, 0x08, 0x00, 0x00, 0x00, 0x5c, 0x80, 0x03, 0x00, 0x08, 0x00, 0x00, 0x00, 0xfe }; + +static const struct sccp2sua_testcase sccp2sua_testcases[] = { + { + .name = "BSSMAP-RESET", + .sccp = PANDSIZ(bssmap_reset), + .sua = { + .hdr = XUA_HDR(SUA_MSGC_CL, SUA_CL_CLDT), + .parts = { + PARTU32(SUA_IEI_PROTO_CLASS, &sua_proto_class0), + PARTARR(SUA_IEI_DEST_ADDR, &sua_addr_ssn_bssmap), + PARTARR(SUA_IEI_SRC_ADDR, &sua_addr_ssn_bssmap), + }, + }, + }, { + .name = "BSSMAP-RESET-ACK", + .sccp = PANDSIZ(bssmap_reset_ack), + .sua = { + .hdr = XUA_HDR(SUA_MSGC_CL, SUA_CL_CLDT), + .parts = { + PARTU32(SUA_IEI_PROTO_CLASS, &sua_proto_class0), + PARTARR(SUA_IEI_DEST_ADDR, &sua_addr_ssn_bssmap_pc1), + PARTARR(SUA_IEI_SRC_ADDR, &sua_addr_ssn_bssmap_pc92), + }, + }, + }, { + .name = "BSSMAP-PAGING", + .sccp = PANDSIZ(bssmap_paging), + .sua = { + .hdr = XUA_HDR(SUA_MSGC_CL, SUA_CL_CLDT), + .parts = { + PARTU32(SUA_IEI_PROTO_CLASS, &sua_proto_class0), + PARTARR(SUA_IEI_DEST_ADDR, &sua_addr_ssn_bssmap_pc1), + PARTARR(SUA_IEI_SRC_ADDR, &sua_addr_ssn_bssmap_pc92), + }, + }, + }, { + .name = "BSSMAP-UDT", + .sccp = PANDSIZ(bssmap_udt), + .sua = { + .hdr = XUA_HDR(SUA_MSGC_CL, SUA_CL_CLDT), + .parts = { + PARTU32(SUA_IEI_PROTO_CLASS, &sua_proto_class0), + PARTARR(SUA_IEI_DEST_ADDR, &sua_addr_ssn_bssmap), + PARTARR(SUA_IEI_SRC_ADDR, &sua_addr_ssn_bssmap), + }, + }, + }, { + .name = "BSSMAP-CR", + .sccp = PANDSIZ(bssmap_cr), + .sua = { + .hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_CORE), + .parts = { + PARTU32(SUA_IEI_PROTO_CLASS, &sua_proto_class2), + PARTU32(SUA_IEI_SRC_REF, &sua_loc_ref_bsc), + PARTARR(SUA_IEI_DEST_ADDR, &sua_addr_ssn_bssmap), + }, + }, + }, { + .name = "BSSMAP-CC", + .sccp = PANDSIZ(bssmap_cc), + .sua = { + .hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_COAK), + .parts = { + PARTU32(SUA_IEI_PROTO_CLASS, &sua_proto_class2), + PARTU32(SUA_IEI_SRC_REF, &sua_loc_ref_msc), + PARTARR(SUA_IEI_DEST_ADDR, &sua_loc_ref_bsc), + }, + }, + }, { + .name = "BSSMAP-DTAP", + .sccp = PANDSIZ(bssmap_dtap), + .sua = { + .hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_CODT), + .parts = { + PARTU32(SUA_IEI_SRC_REF, &sua_loc_ref_msc), + }, + }, + }, { + .name = "BSSMAP-CLEAR", + .sccp = PANDSIZ(bssmap_clear), + .sua = { + .hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_CODT), + .parts = { + PARTU32(SUA_IEI_SRC_REF, &sua_loc_ref_msc), + }, + }, + }, { + .name = "BSSMAP-RELEASED", + .sccp = PANDSIZ(bssmap_released), + .sua = { + .hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_RELRE), + .parts = { + PARTU32(SUA_IEI_DEST_REF, &sua_loc_ref_msc), + PARTU32(SUA_IEI_SRC_REF, &sua_loc_ref_bsc), + PARTU32(SUA_IEI_CAUSE, &sua_cause0), + }, + }, + }, { + .name = "BSSMAP-RELEASE_COMPLETE", + .sccp = PANDSIZ(bssmap_release_complete), + .sua = { + .hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_RELCO), + .parts = { + PARTU32(SUA_IEI_DEST_REF, &sua_loc_ref_bsc), + PARTU32(SUA_IEI_SRC_REF, &sua_loc_ref_msc), + }, + }, + }, { + .name = "TCAP", + .sccp = PANDSIZ(tcap_global_title), + .sua = { + .hdr = XUA_HDR(SUA_MSGC_CL, SUA_CL_CLDT), + .parts = { + }, + }, + }, +}; + +static void test_sccp2sua_case(const struct sccp2sua_testcase *tcase) +{ + struct xua_msg *xua; + struct msgb *msg = msgb_alloc(300, "SCCP2SUA Test Input"); + struct msgb *msg2; + + printf("\n=> %s\n", tcase->name); + msg->l2h = msgb_put(msg, tcase->sccp.length); + memcpy(msg->l2h, tcase->sccp.bin, tcase->sccp.length); + printf("SCCP Input: %s\n", msgb_hexdump(msg)); + printf("Transcoding message SCCP -> XUA\n"); + xua = osmo_sccp_to_xua(msg); + OSMO_ASSERT(xua); + + printf("Decoded SUA: "); + printf("%s\n", xua_msg_dump(xua, &xua_dialect_sua)); + + printf("Re-Encoding decoded SUA to SCCP\n"); + msg2 = osmo_sua_to_sccp(xua); + OSMO_ASSERT(msg2); + /* Re-encode xUA to SCCP */ + printf("SCCP Output: %s\n", msgb_hexdump(msg2)); + + if (msgb_length(msg) != msgb_length(msg2) || + memcmp(msgb_data(msg), msgb_data(msg2), msgb_length(msg))) + printf("Input != re-encoded output!\n"); + + /* free related data */ + msgb_free(msg); + msgb_free(msg2); + xua_msg_free(xua); +} + +static void test_sccp2sua(void) +{ + unsigned int i; + for (i = 0; i < ARRAY_SIZE(sccp2sua_testcases); i++) { + test_sccp2sua_case(&sccp2sua_testcases[i]); + } +} + + +static const struct log_info_cat default_categories[] = { + [0] = { + .name = "DSCCP", + .description = "DSCP", + .enabled = 1, .loglevel = LOGL_DEBUG, + }, +}; + +static const struct log_info log_info = { + .cat = default_categories, + .num_cat = ARRAY_SIZE(default_categories), +}; + +int main(int argc, char **argv) +{ + struct log_target *stderr_target; + log_init(&log_info, NULL); + stderr_target = log_target_create_stderr(); + log_add_target(stderr_target); + + test_isup_parse(); + test_sccp_addr_parser(); + test_helpers(); + test_sccp2sua(); + + printf("All tests passed.\n"); + return 0; +} diff --git a/tests/xua/xua_test.ok b/tests/xua/xua_test.ok new file mode 100644 index 0000000..a9fba1d --- /dev/null +++ b/tests/xua/xua_test.ok @@ -0,0 +1,131 @@ +digits='01234567' (8) +digits='0123456' (7) +sccp_addr_parse test case 0 +expected: RI=7,SSN=6,GTI=4,GT=(TT=0,NPL=1,NAI=4,DIG=919969679389) +parsed: RI=7,SSN=6,GTI=4,GT=(TT=0,NPL=1,NAI=4,DIG=919969679389) +sccp_addr_parse test case 1 +expected: RI=7,SSN=8,GTI=4,GT=(TT=0,NPL=1,NAI=4,DIG=919869299992) +parsed: RI=7,SSN=8,GTI=4,GT=(TT=0,NPL=1,NAI=4,DIG=919869299992) +sccp_addr_parse test case 2 +expected: RI=7,SSN=254,GTI=0 +parsed: RI=7,SSN=254,GTI=0 +Testing Decoded GT -> SUA encoding +IN: TT=0,NPL=1,NAI=4,DIG=919969679389 +OUT:TT=0,NPL=1,NAI=4,DIG=919969679389 + +=> BSSMAP-RESET +SCCP Input: [L2]> 09 00 03 05 07 02 42 fe 02 42 fe 06 00 04 30 04 01 20 +Transcoding message SCCP -> XUA +Decoded SUA: HDR=(CL:CLDT,V=0,LEN=0), + PART(T=Protocol Class,L=4,D=00000000), + PART(T=Destination Address,L=12,D=0002000180030008000000fe), + PART(T=Source Address,L=12,D=0002000180030008000000fe), + PART(T=Data,L=6,D=000430040120) +Re-Encoding decoded SUA to SCCP +SCCP Output: 09 00 03 05 07 02 42 fe 02 42 fe 06 00 04 30 04 01 20 + +=> BSSMAP-RESET-ACK +SCCP Input: [L2]> 09 00 03 07 0b 04 43 01 00 fe 04 43 5c 00 fe 03 00 01 31 +Transcoding message SCCP -> XUA +Decoded SUA: HDR=(CL:CLDT,V=0,LEN=0), + PART(T=Protocol Class,L=4,D=00000000), + PART(T=Destination Address,L=20,D=00020003800200080000000180030008000000fe), + PART(T=Source Address,L=20,D=00020003800200080000005c80030008000000fe), + PART(T=Data,L=3,D=000131) +Re-Encoding decoded SUA to SCCP +SCCP Output: 09 00 03 07 0b 04 43 01 00 fe 04 43 5c 00 fe 03 00 01 31 + +=> BSSMAP-PAGING +SCCP Input: [L2]> 09 00 03 07 0b 04 43 01 00 fe 04 43 5c 00 fe 10 00 0e 52 08 08 29 47 10 02 01 31 97 61 1a 01 06 +Transcoding message SCCP -> XUA +Decoded SUA: HDR=(CL:CLDT,V=0,LEN=0), + PART(T=Protocol Class,L=4,D=00000000), + PART(T=Destination Address,L=20,D=00020003800200080000000180030008000000fe), + PART(T=Source Address,L=20,D=00020003800200080000005c80030008000000fe), + PART(T=Data,L=16,D=000e52080829471002013197611a0106) +Re-Encoding decoded SUA to SCCP +SCCP Output: 09 00 03 07 0b 04 43 01 00 fe 04 43 5c 00 fe 10 00 0e 52 08 08 29 47 10 02 01 31 97 61 1a 01 06 + +=> BSSMAP-UDT +SCCP Input: [L2]> 09 00 03 05 07 02 42 fe 02 42 fe 10 00 0e 52 08 08 29 47 10 02 01 31 97 61 1a 01 06 +Transcoding message SCCP -> XUA +Decoded SUA: HDR=(CL:CLDT,V=0,LEN=0), + PART(T=Protocol Class,L=4,D=00000000), + PART(T=Destination Address,L=12,D=0002000180030008000000fe), + PART(T=Source Address,L=12,D=0002000180030008000000fe), + PART(T=Data,L=16,D=000e52080829471002013197611a0106) +Re-Encoding decoded SUA to SCCP +SCCP Output: 09 00 03 05 07 02 42 fe 02 42 fe 10 00 0e 52 08 08 29 47 10 02 01 31 97 61 1a 01 06 + +=> BSSMAP-CR +SCCP Input: [L2]> 01 01 02 03 02 02 04 02 42 fe 0f 1f 00 1d 57 05 08 00 72 f4 80 20 12 c3 50 17 10 05 24 11 03 33 19 a2 08 29 47 10 02 01 31 97 61 00 +Transcoding message SCCP -> XUA +Decoded SUA: HDR=(CO:CORE,V=0,LEN=0), + PART(T=Protocol Class,L=4,D=00000002), + PART(T=Source Reference,L=4,D=00010203), + PART(T=Destination Address,L=12,D=0002000180030008000000fe), + PART(T=Data,L=31,D=001d5705080072f4802012c3501710052411033319a2082947100201319761) +Re-Encoding decoded SUA to SCCP +SCCP Output: 01 01 02 03 02 02 04 02 42 fe 0f 1f 00 1d 57 05 08 00 72 f4 80 20 12 c3 50 17 10 05 24 11 03 33 19 a2 08 29 47 10 02 01 31 97 61 00 + +=> BSSMAP-CC +SCCP Input: [L2]> 02 01 02 03 00 00 03 02 01 00 +Transcoding message SCCP -> XUA +Decoded SUA: HDR=(CO:COAK,V=0,LEN=0), + PART(T=Protocol Class,L=4,D=00000002), + PART(T=Destination Reference,L=4,D=00010203), + PART(T=Source Reference,L=4,D=00000003) +Re-Encoding decoded SUA to SCCP +SCCP Output: 02 01 02 03 00 00 03 02 01 00 + +=> BSSMAP-DTAP +SCCP Input: [L2]> 06 00 00 03 00 01 0f 01 00 0c 03 05 5c 08 11 81 33 66 02 13 45 f4 +Transcoding message SCCP -> XUA +Decoded SUA: HDR=(CO:CODT,V=0,LEN=0), + PART(T=Destination Reference,L=4,D=00000003), + PART(T=Segmentation,L=4,D=00000000), + PART(T=Data,L=15,D=01000c03055c0811813366021345f4) +Re-Encoding decoded SUA to SCCP +SCCP Output: 06 00 00 03 00 01 0f 01 00 0c 03 05 5c 08 11 81 33 66 02 13 45 f4 + +=> BSSMAP-CLEAR +SCCP Input: [L2]> 06 00 00 03 00 01 06 00 04 20 04 01 09 +Transcoding message SCCP -> XUA +Decoded SUA: HDR=(CO:CODT,V=0,LEN=0), + PART(T=Destination Reference,L=4,D=00000003), + PART(T=Segmentation,L=4,D=00000000), + PART(T=Data,L=6,D=000420040109) +Re-Encoding decoded SUA to SCCP +SCCP Output: 06 00 00 03 00 01 06 00 04 20 04 01 09 + +=> BSSMAP-RELEASED +SCCP Input: [L2]> 04 00 00 03 01 02 03 00 01 0f 02 23 42 00 +Transcoding message SCCP -> XUA +Decoded SUA: HDR=(CO:RELRE,V=0,LEN=0), + PART(T=Destination Reference,L=4,D=00000003), + PART(T=Source Reference,L=4,D=00010203), + PART(T=Cause,L=4,D=00000300), + PART(T=Data,L=2,D=2342) +Re-Encoding decoded SUA to SCCP +SCCP Output: 04 00 00 03 01 02 03 00 01 0f 02 23 42 00 + +=> BSSMAP-RELEASE_COMPLETE +SCCP Input: [L2]> 05 01 02 03 00 00 03 +Transcoding message SCCP -> XUA +Decoded SUA: HDR=(CO:RELCO,V=0,LEN=0), + PART(T=Destination Reference,L=4,D=00010203), + PART(T=Source Reference,L=4,D=00000003) +Re-Encoding decoded SUA to SCCP +SCCP Output: 05 01 02 03 00 00 03 + +=> TCAP +SCCP Input: [L2]> 09 81 03 0d 18 0a 12 07 00 12 04 53 84 09 00 17 0b 12 06 00 12 04 44 87 20 00 20 65 9a 65 81 97 48 04 26 00 01 98 49 04 51 01 03 df 6c 81 88 a1 81 85 02 01 44 02 01 07 30 80 a7 80 a0 80 04 01 2b 30 80 30 12 83 01 10 84 01 07 85 07 91 44 57 76 67 16 97 86 01 20 30 06 82 01 18 84 01 04 00 00 00 00 a3 06 04 01 42 84 01 05 a3 06 04 01 51 84 01 05 a3 06 04 01 31 84 01 05 a3 09 04 01 12 84 01 05 82 01 02 a3 09 04 01 11 84 01 05 81 01 01 a3 06 04 01 14 84 01 00 a3 0b 04 01 41 84 01 04 30 03 83 01 10 a3 0b 04 01 41 84 01 04 30 03 82 01 18 00 00 00 00 +Transcoding message SCCP -> XUA +Decoded SUA: HDR=(CL:CLDT,V=0,LEN=0), + PART(T=Protocol Class,L=4,D=00000081), + PART(T=Destination Address,L=32,D=0001000580010014000000040a00010453840900170000008003000800000007), + PART(T=Source Address,L=32,D=0001000580010014000000040c00010444872000206500008003000800000006), + PART(T=Data,L=154,D=6581974804260001984904510103df6c8188a181850201440201073080a780a08004012b30803012830110840107850791445776671697860120300682011884010400000000a306040142840105a306040151840105a306040131840105a309040112840105820102a309040111840105810101a306040114840100a30b0401418401043003830110a30b040141840104300382011800000000) +Re-Encoding decoded SUA to SCCP +SCCP Output: 09 81 03 0d 18 0a 12 07 00 12 04 53 84 09 00 17 0b 12 06 00 12 04 44 87 20 00 20 65 9a 65 81 97 48 04 26 00 01 98 49 04 51 01 03 df 6c 81 88 a1 81 85 02 01 44 02 01 07 30 80 a7 80 a0 80 04 01 2b 30 80 30 12 83 01 10 84 01 07 85 07 91 44 57 76 67 16 97 86 01 20 30 06 82 01 18 84 01 04 00 00 00 00 a3 06 04 01 42 84 01 05 a3 06 04 01 51 84 01 05 a3 06 04 01 31 84 01 05 a3 09 04 01 12 84 01 05 82 01 02 a3 09 04 01 11 84 01 05 81 01 01 a3 06 04 01 14 84 01 00 a3 0b 04 01 41 84 01 04 30 03 83 01 10 a3 0b 04 01 41 84 01 04 30 03 82 01 18 00 00 00 00 +All tests passed. -- To view, visit https://gerrit.osmocom.org/2214 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I7ce038d72dca18fb83d5a12519c9a48267e52ab8 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Mon Apr 3 20:22:10 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 3 Apr 2017 20:22:10 +0000 Subject: [PATCH] libosmo-sccp[master]: Add new SCCP implementation Message-ID: Review at https://gerrit.osmocom.org/2215 Add new SCCP implementation This is an implementation of SCCP as specified in ITO-T Q.71x, particularly the SCRC (routing), SCLC (Connectionless) and SCOC (Connection Oriented) portions. the elaborate state machines of SCOC are implemented using osmo_fsm, with one state machine for each connection. Interfaces to the top (user application) are the SCCP-USER-SAP and on the bottom (network) side the MTP-USER-SAP as provided by osmo_ss7. Contrary to a straight-forward implementation, the code internally always uses a SUA representation of all messages (in struct xua_msg). This enables us to have one common implementation of all related state machines and use them for both SUA and SCCP. If used with real SCCP wire format, all messages are translated from SCCP to SUA on ingress and translated from SUA to SCCP on egress. As SUA is a super-set of SCCP, this can be done "lossless". Change-Id: I916e895d9a4914b05483fe12ab5251f206d10dee --- M include/osmocom/sigtran/sccp_sap.h M src/Makefile.am M src/osmo_ss7.c M src/sccp_internal.h A src/sccp_sclc.c A src/sccp_scoc.c A src/sccp_scrc.c A src/sccp_user.c 8 files changed, 2,968 insertions(+), 2 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/15/2215/1 diff --git a/include/osmocom/sigtran/sccp_sap.h b/include/osmocom/sigtran/sccp_sap.h index 0cc1531..c1464f0 100644 --- a/include/osmocom/sigtran/sccp_sap.h +++ b/include/osmocom/sigtran/sccp_sap.h @@ -222,3 +222,23 @@ #define msgb_scu_prim(msg) ((struct osmo_scu_prim *)(msg)->l1h) char *osmo_scu_prim_name(struct osmo_prim_hdr *oph); + +struct osmo_ss7_instance; +struct osmo_sccp_instance; +struct osmo_sccp_user; + +struct osmo_sccp_instance * +osmo_sccp_instance_create(struct osmo_ss7_instance *ss7, void *priv); +void osmo_sccp_instance_destroy(struct osmo_sccp_instance *inst); + +void osmo_sccp_user_unbind(struct osmo_sccp_user *scu); + +struct osmo_sccp_user * +osmo_sccp_user_bind_pc(struct osmo_sccp_instance *inst, const char *name, + osmo_prim_cb prim_cb, uint16_t ssn, uint32_t pc); + +struct osmo_sccp_user * +osmo_sccp_user_bind(struct osmo_sccp_instance *inst, const char *name, + osmo_prim_cb prim_cb, uint16_t ssn); + +int osmo_sccp_user_sap_down(struct osmo_sccp_user *scu, struct osmo_prim_hdr *oph); diff --git a/src/Makefile.am b/src/Makefile.am index 4455127..a4cfeeb 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -27,7 +27,8 @@ LIBVERSION=0:0:0 libosmo_sigtran_la_SOURCES = sccp_sap.c sua.c m3ua.c xua_msg.c sccp_helpers.c \ - sccp2sua.c \ + sccp2sua.c sccp_scrc.c sccp_sclc.c sccp_scoc.c \ + sccp_user.c \ osmo_ss7.c osmo_ss7_hmrt.c xua_asp_fsm.c xua_as_fsm.c libosmo_sigtran_la_LDFLAGS = -version-info $(LIBVERSION) -no-undefined -export-symbols-regex '^osmo_' libosmo_sigtran_la_LIBADD = $(LIBOSMOCORE_LIBS) $(LIBOSMONETIF_LIBS) $(LIBSCTP_LIBS) diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index 74c54bb..6d0b446 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -41,6 +41,7 @@ #include +#include "sccp_internal.h" #include "xua_internal.h" #include "xua_asp_fsm.h" #include "xua_as_fsm.h" @@ -1483,6 +1484,7 @@ { if (ss7_initialized) return 1; + osmo_fsm_register(&sccp_scoc_fsm); osmo_fsm_register(&xua_as_fsm); osmo_fsm_register(&xua_asp_fsm); ss7_initialized = true; diff --git a/src/sccp_internal.h b/src/sccp_internal.h index 7287a82..c35ef4b 100644 --- a/src/sccp_internal.h +++ b/src/sccp_internal.h @@ -1,5 +1,89 @@ #pragma once -#include +#include +#include +#include +#include + +/* an instance of the SCCP stack */ +struct osmo_sccp_instance { + /* entry in global list of ss7 instances */ + struct llist_head list; + /* list of 'struct sccp_connection' in this instance */ + struct llist_head connections; + /* list of SCCP users in this instance */ + struct llist_head users; + /* routing context to be used in all outbound messages */ + uint32_t route_ctx; + /* next local reference to allocate */ + uint32_t next_id; + struct osmo_ss7_instance *ss7; + void *priv; + + struct osmo_ss7_user ss7_user; +}; + +struct osmo_sccp_user { + /*! \brief entry in list of sccp users of \ref osmo_sccp_instance */ + struct llist_head list; + /*! \brief pointer back to SCCP instance */ + struct osmo_sccp_instance *inst; + /*! \brief human-readable name of this user */ + char *name; + + /*! \brief SSN and/or point code to which we are bound */ + uint16_t ssn; + uint32_t pc; + bool pc_valid; + + /* set if we are a server */ + struct llist_head links; + + /* user call-back function in case of incoming primitives */ + osmo_prim_cb prim_cb; + void *priv; + + /* Application Server FSM Instance */ + struct osmo_fsm_inst *as_fi; +}; + +extern int DSCCP; + +struct xua_msg; + +struct osmo_sccp_user * +sccp_user_find(struct osmo_sccp_instance *inst, uint16_t ssn, uint32_t pc); + +/* Message from SCOC -> SCRC */ +int sccp_scrc_rx_scoc_conn_msg(struct osmo_sccp_instance *inst, + struct xua_msg *xua); + +/* Message from SCLC -> SCRC */ +int sccp_scrc_rx_sclc_msg(struct osmo_sccp_instance *inst, struct xua_msg *xua); + +/* Message from MTP (SUA) -> SCRC */ +int scrc_rx_mtp_xfer_ind_xua(struct osmo_sccp_instance *inst, + struct xua_msg *xua); + +/* Message from SCRC -> SCOC */ +void sccp_scoc_rx_from_scrc(struct osmo_sccp_instance *inst, + struct xua_msg *xua); +void sccp_scoc_rx_scrc_rout_fail(struct osmo_sccp_instance *inst, + struct xua_msg *xua, uint32_t cause); + +void sccp_scoc_flush_connections(struct osmo_sccp_instance *inst); + +/* Message from SCRC -> SCLC */ +int sccp_sclc_rx_from_scrc(struct osmo_sccp_instance *inst, + struct xua_msg *xua); +void sccp_sclc_rx_scrc_rout_fail(struct osmo_sccp_instance *inst, + struct xua_msg *xua, uint32_t cause); + +int sccp_user_prim_up(struct osmo_sccp_user *scut, struct osmo_scu_prim *prim); + +/* SCU -> SCLC */ +int sccp_sclc_user_sap_down(struct osmo_sccp_user *scu, struct osmo_prim_hdr *oph); struct msgb *sccp_msgb_alloc(const char *name); + +struct osmo_fsm sccp_scoc_fsm; diff --git a/src/sccp_sclc.c b/src/sccp_sclc.c new file mode 100644 index 0000000..dae2c36 --- /dev/null +++ b/src/sccp_sclc.c @@ -0,0 +1,337 @@ +/* SCCP Connectionless Control (SCLC) according to ITU-T Q.713/Q.714 */ + +/* (C) 2015-2017 by Harald Welte + * All Rights reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/* This code is a bit of a hybrid between the ITU-T Q.71x specifications + * for SCCP (particularly its connection-oriented part), and the IETF + * RFC 3868 (SUA). The idea here is to have one shared code base of the + * state machines for SCCP Connection Oriented, and use those both from + * SCCP and SUA. + * + * To do so, all SCCP messages are translated to SUA messages in the + * input side, and all generated SUA messages are translated to SCCP on + * the output side. + * + * The Choice of going for SUA messages as the "native" format was based + * on their easier parseability, and the fact that there are features in + * SUA which classic SCCP cannot handle (like IP addresses in GT). + * However, all SCCP features can be expressed in SUA. + * + * The code only supports Class 2. No support for Class 3 is intended, + * but patches are of course alwys welcome. + * + * Missing other features: + * * Segmentation/Reassembly support + * * T(guard) after (re)start + * * freezing of local references + * * parsing/encoding of IPv4/IPv6 addresses + * * use of multiple Routing Contexts in SUA case + */ + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "xua_internal.h" +#include "sccp_internal.h" + +/* generate a 'struct xua_msg' of requested type from primitive data */ +static struct xua_msg *xua_gen_msg_cl(uint32_t event, + struct osmo_scu_prim *prim, int msg_type) +{ + struct xua_msg *xua = xua_msg_alloc(); + struct osmo_scu_unitdata_param *udpar = &prim->u.unitdata; + + if (!xua) + return NULL; + + switch (msg_type) { + case SUA_CL_CLDT: + xua->hdr = XUA_HDR(SUA_MSGC_CL, SUA_CL_CLDT); + xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, 0); /* FIXME */ + xua_msg_add_u32(xua, SUA_IEI_PROTO_CLASS, 0); + xua_msg_add_sccp_addr(xua, SUA_IEI_SRC_ADDR, &udpar->calling_addr); + xua_msg_add_sccp_addr(xua, SUA_IEI_DEST_ADDR, &udpar->called_addr); + xua_msg_add_u32(xua, SUA_IEI_SEQ_CTRL, udpar->in_sequence_control); + /* optional: importance, ... correlation id? */ + if (!prim) + goto prim_needed; + xua_msg_add_data(xua, SUA_IEI_DATA, msgb_l2len(prim->oph.msg), + msgb_l2(prim->oph.msg)); + break; + default: + LOGP(DLSCCP, LOGL_ERROR, "Unknown msg_type %u\n", msg_type); + xua_msg_free(xua); + return NULL; + } + return xua; + +prim_needed: + xua_msg_free(xua); + LOGP(DLSCCP, LOGL_ERROR, "%s must be called with valid 'prim' " + "pointer for msg_type=%u\n", __func__, msg_type); + return NULL; +} + +/* generate xua_msg, encode it and send it to SCRC */ +static int xua_gen_encode_and_send(struct osmo_sccp_user *scu, uint32_t event, + struct osmo_scu_prim *prim, int msg_type) +{ + struct xua_msg *xua; + + xua = xua_gen_msg_cl(event, prim, msg_type); + if (!xua) + return -1; + + return sccp_scrc_rx_sclc_msg(scu->inst, xua); +} + +/*! \brief Main entrance function for primitives from SCCP User + * \param[in] scu SCCP User who is sending the primitive + * \param[on] oph Osmocom primitive header of the primitive + * \returns 0 on success; negtive in case of error */ +int sccp_sclc_user_sap_down(struct osmo_sccp_user *scu, struct osmo_prim_hdr *oph) +{ + struct osmo_scu_prim *prim = (struct osmo_scu_prim *) oph; + struct msgb *msg = prim->oph.msg; + int rc = 0; + + /* we get called from osmo_sccp_user_sap_down() which already + * has debug-logged the primitive */ + + switch (OSMO_PRIM_HDR(&prim->oph)) { + case OSMO_PRIM(OSMO_SCU_PRIM_N_UNITDATA, PRIM_OP_REQUEST): + /* Connectionless by-passes this altogether */ + rc = xua_gen_encode_and_send(scu, -1, prim, SUA_CL_CLDT); + goto out; + default: + LOGP(DLSCCP, LOGL_ERROR, "Received unknown SCCP User " + "primitive %s from user\n", + osmo_scu_prim_name(&prim->oph)); + rc = -1; + goto out; + } + +out: + /* the SAP is supposed to consume the primitive/msgb */ + msgb_free(msg); + + return rc; +} + +/* Process an incoming CLDT message (from a remote peer) */ +static int sclc_rx_cldt(struct osmo_sccp_instance *inst, struct xua_msg *xua) +{ + struct osmo_scu_prim *prim; + struct osmo_scu_unitdata_param *param; + struct xua_msg_part *data_ie = xua_msg_find_tag(xua, SUA_IEI_DATA); + struct msgb *upmsg = sccp_msgb_alloc(__func__); + struct osmo_sccp_user *scu; + uint32_t protocol_class; + + /* fill primitive */ + prim = (struct osmo_scu_prim *) msgb_put(upmsg, sizeof(*prim)); + param = &prim->u.unitdata; + osmo_prim_init(&prim->oph, SCCP_SAP_USER, + OSMO_SCU_PRIM_N_UNITDATA, + PRIM_OP_INDICATION, upmsg); + sua_addr_parse(¶m->called_addr, xua, SUA_IEI_DEST_ADDR); + sua_addr_parse(¶m->calling_addr, xua, SUA_IEI_SRC_ADDR); + param->in_sequence_control = xua_msg_get_u32(xua, SUA_IEI_SEQ_CTRL); + protocol_class = xua_msg_get_u32(xua, SUA_IEI_PROTO_CLASS); + param->return_option = protocol_class & 0x80; + param->importance = xua_msg_get_u32(xua, SUA_IEI_IMPORTANCE); + + scu = sccp_user_find(inst, param->called_addr.ssn, + param->called_addr.pc); + + if (!scu) { + /* FIXME: Send destination unreachable? */ + LOGP(DLSUA, LOGL_NOTICE, "Received SUA message for unequipped SSN %u\n", + param->called_addr.ssn); + msgb_free(upmsg); + return 0; + } + + /* copy data */ + upmsg->l2h = msgb_put(upmsg, data_ie->len); + memcpy(upmsg->l2h, data_ie->dat, data_ie->len); + + /* send to user SAP */ + sccp_user_prim_up(scu, prim); + + /* xua_msg is free'd by our caller */ + return 0; +} + +static int sclc_rx_cldr(struct osmo_sccp_instance *inst, struct xua_msg *xua) +{ + struct osmo_scu_prim *prim; + struct osmo_scu_notice_param *param; + struct xua_msg_part *data_ie = xua_msg_find_tag(xua, SUA_IEI_DATA); + struct msgb *upmsg = sccp_msgb_alloc(__func__); + struct osmo_sccp_user *scu; + + /* fill primitive */ + prim = (struct osmo_scu_prim *) msgb_put(upmsg, sizeof(*prim)); + param = &prim->u.notice; + osmo_prim_init(&prim->oph, SCCP_SAP_USER, + OSMO_SCU_PRIM_N_NOTICE, + PRIM_OP_INDICATION, upmsg); + + sua_addr_parse(¶m->called_addr, xua, SUA_IEI_DEST_ADDR); + sua_addr_parse(¶m->calling_addr, xua, SUA_IEI_SRC_ADDR); + param->importance = xua_msg_get_u32(xua, SUA_IEI_IMPORTANCE); + param->cause = xua_msg_get_u32(xua, SUA_IEI_CAUSE); + + scu = sccp_user_find(inst, param->called_addr.ssn, + param->called_addr.pc); + if (!scu) { + /* FIXME: Send destination unreachable? */ + LOGP(DLSUA, LOGL_NOTICE, "Received CLDR for unequipped SSN %u\n", + param->called_addr.ssn); + msgb_free(upmsg); + return 0; + } + + /* copy data */ + upmsg->l2h = msgb_put(upmsg, data_ie->len); + memcpy(upmsg->l2h, data_ie->dat, data_ie->len); + + /* send to user SAP */ + sccp_user_prim_up(scu, prim); + + /* xua_msg is free'd by our caller */ + return 0; +} + +/*! \brief SCRC -> SCLC (connectionless message) + * \param[in] inst SCCP Instance in which we operate + * \param[in] xua SUA connectionless message + * \returns 0 on success; negative on error */ +int sccp_sclc_rx_from_scrc(struct osmo_sccp_instance *inst, + struct xua_msg *xua) +{ + int rc = -1; + + OSMO_ASSERT(xua->hdr.msg_class == SUA_MSGC_CL); + + switch (xua->hdr.msg_type) { + case SUA_CL_CLDT: + rc = sclc_rx_cldt(inst, xua); + break; + case SUA_CL_CLDR: + rc = sclc_rx_cldr(inst, xua); + break; + default: + LOGP(DLSUA, LOGL_NOTICE, "Received unknown/unsupported " + "message %s\n", xua_hdr_dump(xua, &xua_dialect_sua)); + break; + } + + return rc; +} + +/* generate a return/refusal message (SUA CLDR == SCCP UDTS) based on + * the incoming message. We need to flip all identities between sender + * and receiver */ +static struct xua_msg *gen_ret_msg(struct osmo_sccp_instance *inst, + const struct xua_msg *xua_in, + uint32_t ret_cause) +{ + struct xua_msg *xua_out = xua_msg_alloc(); + struct osmo_sccp_addr called; + + xua_out->hdr = XUA_HDR(SUA_MSGC_CL, SUA_CL_CLDR); + xua_msg_add_u32(xua_out, SUA_IEI_ROUTE_CTX, inst->route_ctx); + xua_msg_add_u32(xua_out, SUA_IEI_CAUSE, + SUA_CAUSE_T_RETURN | ret_cause); + /* Swap Calling and Called Party */ + xua_msg_copy_part(xua_out, SUA_IEI_SRC_ADDR, xua_in, SUA_IEI_DEST_ADDR); + xua_msg_copy_part(xua_out, SUA_IEI_DEST_ADDR, xua_in, SUA_IEI_SRC_ADDR); + /* TODO: Optional: Hop Count */ + /* Optional: Importance */ + xua_msg_copy_part(xua_out, SUA_IEI_IMPORTANCE, + xua_in, SUA_IEI_IMPORTANCE); + /* Optional: Message Priority */ + xua_msg_copy_part(xua_out, SUA_IEI_MSG_PRIO, xua_in, SUA_IEI_MSG_PRIO); + /* Optional: Correlation ID */ + xua_msg_copy_part(xua_out, SUA_IEI_CORR_ID, xua_in, SUA_IEI_CORR_ID); + /* Optional: Segmentation */ + xua_msg_copy_part(xua_out, SUA_IEI_SEGMENTATION, + xua_in, SUA_IEI_SEGMENTATION); + /* Optional: Data */ + xua_msg_copy_part(xua_out, SUA_IEI_DATA, xua_in, SUA_IEI_DATA); + + sua_addr_parse(&called, xua_out, SUA_IEI_DEST_ADDR); + /* Route on PC + SSN ? */ + if (called.ri == OSMO_SCCP_RI_SSN_PC) { + /* if no PC, copy OPC into called addr */ + if (!(called.presence & OSMO_SCCP_ADDR_T_PC)) { + struct osmo_sccp_addr calling; + sua_addr_parse(&calling, xua_out, SUA_IEI_SRC_ADDR); + called.presence |= OSMO_SCCP_ADDR_T_PC; + called.pc = calling.pc; + /* Re-encode / replace called address */ + xua_msg_free_tag(xua_out, SUA_IEI_DEST_ADDR); + xua_msg_add_sccp_addr(xua_out, SUA_IEI_DEST_ADDR, + &called); + } + } + return xua_out; +} + +/*! \brief SCRC -> SCLC (Routing Failure + * \param[in] inst SCCP Instance in which we operate + * \param[in] xua_in Message that failed to be routed + * \param[in] cause SCCP Return Cause */ +void sccp_sclc_rx_scrc_rout_fail(struct osmo_sccp_instance *inst, + struct xua_msg *xua_in, uint32_t cause) +{ + struct xua_msg *xua_out; + + /* Figure C.12/Q.714 (Sheet 8) Node 9 */ + switch (xua_in->hdr.msg_type) { + case SUA_CL_CLDT: + xua_out = gen_ret_msg(inst, xua_in, cause); + /* TODO: Message Return Option? */ + if (!osmo_ss7_pc_is_local(inst->ss7, xua_in->mtp.opc)) { + /* non-local originator: send UDTS */ + /* TODO: Assign SLS */ + sccp_scrc_rx_sclc_msg(inst, xua_out); + } else { + /* local originator: send N-NOTICE to user */ + /* TODO: N-NOTICE.ind SCLC -> SCU */ + sclc_rx_cldr(inst, xua_out); + xua_msg_free(xua_out); + } + break; + case SUA_CL_CLDR: + /* do nothing */ + break; + } +} diff --git a/src/sccp_scoc.c b/src/sccp_scoc.c new file mode 100644 index 0000000..cb592e6 --- /dev/null +++ b/src/sccp_scoc.c @@ -0,0 +1,1672 @@ +/* SCCP Connection Oriented (SCOC) according to ITU-T Q.713/Q.714 */ + +/* (C) 2015-2017 by Harald Welte + * All Rights reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/* This code is a bit of a hybrid between the ITU-T Q.71x specifications + * for SCCP (particularly its connection-oriented part), and the IETF + * RFC 3868 (SUA). The idea here is to have one shared code base of the + * state machines for SCCP Connection Oriented, and use those both from + * SCCP and SUA. + * + * To do so, all SCCP messages are translated to SUA messages in the + * input side, and all generated SUA messages are translated to SCCP on + * the output side. + * + * The Choice of going for SUA messages as the "native" format was based + * on their easier parseability, and the fact that there are features in + * SUA which classic SCCP cannot handle (like IP addresses in GT). + * However, all SCCP features can be expressed in SUA. + * + * The code only supports Class 2. No support for Class 3 is intended, + * but patches are of course alwys welcome. + * + * Missing other features: + * * Segmentation/Reassembly support + * * T(guard) after (re)start + * * freezing of local references + * * parsing/encoding of IPv4/IPv6 addresses + * * use of multiple Routing Contexts in SUA case + */ + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "xua_internal.h" +#include "sccp_internal.h" + +#define S(x) (1 << (x)) +#define SCU_MSGB_SIZE 1024 + +/* Appendix C.4 of Q.714 (all in milliseconds) */ +#define CONNECTION_TIMER ( 1 * 60 * 100) +#define TX_INACT_TIMER ( 7 * 60 * 100) /* RFC 3868 Ch. 8. */ +#define RX_INACT_TIMER (15 * 60 * 100) /* RFC 3868 Ch. 8. */ +#define RELEASE_TIMER ( 10 * 100) +#define RELEASE_REP_TIMER ( 10 * 100) +#define INT_TIMER ( 1 * 60 * 100) +#define GUARD_TIMER (23 * 60 * 100) +#define RESET_TIMER ( 10 * 100) + +/* convert from single value in milliseconds to comma-separated + * "seconds, microseconds" format we use in osmocom/core/timers.h */ +#define MSEC_TO_S_US(x) (x/100), ((x%100)*10) + +/*********************************************************************** + * SCCP connection table + ***********************************************************************/ + +/* a logical connection within the SCCP instance */ +struct sccp_connection { + /* part of osmo_sccp_instance.list */ + struct llist_head list; + /* which instance are we part of? */ + struct osmo_sccp_instance *inst; + /* which user owns us? */ + struct osmo_sccp_user *user; + + /* remote point code */ + uint32_t remote_pc; + + /* local/remote addresses and identiies */ + struct osmo_sccp_addr calling_addr; + struct osmo_sccp_addr called_addr; + uint32_t conn_id; + uint32_t remote_ref; + + uint32_t importance; + uint32_t sccp_class; + uint32_t release_cause; /* WAIT_CONN_CONF */ + + /* Osmo FSM Instance of sccp_scoc_fsm */ + struct osmo_fsm_inst *fi; + + /* Connect timer */ + struct osmo_timer_list t_conn; + + /* inactivity timers */ + struct osmo_timer_list t_ias; + struct osmo_timer_list t_iar; + + /* release timers */ + struct osmo_timer_list t_rel; + struct osmo_timer_list t_int; + struct osmo_timer_list t_rep_rel; +}; + +/*********************************************************************** + * various helper functions + ***********************************************************************/ + +enum sccp_connection_state { + S_IDLE, + S_CONN_PEND_IN, + S_CONN_PEND_OUT, + S_ACTIVE, + S_DISCONN_PEND, + S_RESET_IN, + S_RESET_OUT, + S_BOTHWAY_RESET, + S_WAIT_CONN_CONF, +}; + +/* Events that this FSM can process */ +enum sccp_scoc_event { + /* Primitives from SCCP-User */ + SCOC_E_SCU_N_CONN_REQ, + SCOC_E_SCU_N_CONN_RESP, + SCOC_E_SCU_N_DISC_REQ, + SCOC_E_SCU_N_DATA_REQ, + SCOC_E_SCU_N_EXP_DATA_REQ, + + /* Events from RCOC (Routing for Connection Oriented) */ + SCOC_E_RCOC_CONN_IND, + SCOC_E_RCOC_ROUT_FAIL_IND, + SCOC_E_RCOC_RLSD_IND, + SCOC_E_RCOC_REL_COMPL_IND, + SCOC_E_RCOC_CREF_IND, + SCOC_E_RCOC_CC_IND, + SCOC_E_RCOC_DT1_IND, + SCOC_E_RCOC_DT2_IND, + SCOC_E_RCOC_IT_IND, + SCOC_E_RCOC_OTHER_NPDU, + SCOC_E_RCOC_ERROR_IND, + + /* Timer Events */ + SCOC_E_T_IAR_EXP, + SCOC_E_T_IAS_EXP, + + SCOC_E_CONN_TMR_EXP, + + SCOC_E_T_REL_EXP, + SCOC_E_T_INT_EXP, + SCOC_E_T_REP_REL_EXP, +}; + +static const struct value_string scoc_event_names[] = { + /* Primitives from SCCP-User */ + { SCOC_E_SCU_N_CONN_REQ, "N-CONNECT.req" }, + { SCOC_E_SCU_N_CONN_RESP, "N-CONNECT.resp" }, + { SCOC_E_SCU_N_DISC_REQ, "N-DISCONNECT.req" }, + { SCOC_E_SCU_N_DATA_REQ, "N-DATA.req" }, + { SCOC_E_SCU_N_EXP_DATA_REQ, "N-EXPEDITED_DATA.req" }, + + /* Events from RCOC (Routing for Connection Oriented) */ + { SCOC_E_RCOC_CONN_IND, "RCOC-CONNECT.ind" }, + { SCOC_E_RCOC_ROUT_FAIL_IND, "RCOC-ROUT_FAIL.ind" }, + { SCOC_E_RCOC_RLSD_IND, "RCOC-RELEASED.ind" }, + { SCOC_E_RCOC_REL_COMPL_IND, "RCOC-RELEASE_COMPLETE.ind" }, + { SCOC_E_RCOC_CREF_IND, "RCOC-CONNECT_REFUSED.ind" }, + { SCOC_E_RCOC_CC_IND, "RCOC-CONNECT_CONFIRM.ind" }, + { SCOC_E_RCOC_DT1_IND, "RCOC-DT1.ind" }, + { SCOC_E_RCOC_DT2_IND, "RCOC-DT2.ind" }, + { SCOC_E_RCOC_IT_IND, "RCOC-IT.ind" }, + { SCOC_E_RCOC_OTHER_NPDU, "RCOC-OTHER_NPDU.ind" }, + { SCOC_E_RCOC_ERROR_IND, "RCOC-ERROR.ind" }, + + { SCOC_E_T_IAR_EXP, "T(iar)_expired" }, + { SCOC_E_T_IAS_EXP, "T(ias)_expired" }, + { SCOC_E_CONN_TMR_EXP, "T(conn)_expired" }, + { SCOC_E_T_REL_EXP, "T(rel)_expired" }, + { SCOC_E_T_INT_EXP, "T(int)_expired" }, + { SCOC_E_T_REP_REL_EXP, "T(rep_rel)_expired" }, + + { 0, NULL } +}; + +/* how to map a SCCP CO message to an event */ +static const struct xua_msg_event_map sua_scoc_event_map[] = { + { SUA_MSGC_CO, SUA_CO_CORE, SCOC_E_RCOC_CONN_IND }, + { SUA_MSGC_CO, SUA_CO_RELRE, SCOC_E_RCOC_RLSD_IND }, + { SUA_MSGC_CO, SUA_CO_RELCO, SCOC_E_RCOC_REL_COMPL_IND }, + { SUA_MSGC_CO, SUA_CO_COREF, SCOC_E_RCOC_CREF_IND }, + { SUA_MSGC_CO, SUA_CO_COAK, SCOC_E_RCOC_CC_IND }, + { SUA_MSGC_CO, SUA_CO_CODT, SCOC_E_RCOC_DT1_IND }, + { SUA_MSGC_CO, SUA_CO_COIT, SCOC_E_RCOC_IT_IND }, + { SUA_MSGC_CO, SUA_CO_COERR, SCOC_E_RCOC_ERROR_IND }, +}; + + +/*! \brief magic value to be used as final record of \ref + * osmo_prim_event_map */ +#define OSMO_NO_EVENT 0xFFFFFFFF + +/*! \brief single entry in a SAP/PRIM/OP -> EVENT map */ +struct osmo_prim_event_map { + unsigned int sap; /*!< SAP to match */ + unsigned int primitive; /*!< primtiive to match */ + enum osmo_prim_operation operation; /*!< operation to match */ + uint32_t event; /*!< event as result if above match */ +}; + +/*! \brief resolve the (fsm) event for a given primitive using a map + * \param[in] oph primitive header used as key for match + * \param[in] maps list of mappings from primitive to event + * \returns event determined by map; \ref OSMO_NO_EVENT if no match */ +uint32_t osmo_event_for_prim(const struct osmo_prim_hdr *oph, + const struct osmo_prim_event_map *maps) +{ + const struct osmo_prim_event_map *map; + + for (map = maps; map->event != OSMO_NO_EVENT; map++) { + if (map->sap == oph->sap && + map->primitive == oph->primitive && + map->operation == oph->operation) + return map->event; + } + return OSMO_NO_EVENT; +} + +/* map from SCU-primitives to SCOC FSM events */ +static const struct osmo_prim_event_map scu_scoc_event_map[] = { + { SCCP_SAP_USER, OSMO_SCU_PRIM_N_CONNECT, PRIM_OP_REQUEST, + SCOC_E_SCU_N_CONN_REQ }, + { SCCP_SAP_USER, OSMO_SCU_PRIM_N_CONNECT, PRIM_OP_RESPONSE, + SCOC_E_SCU_N_CONN_RESP }, + { SCCP_SAP_USER, OSMO_SCU_PRIM_N_DATA, PRIM_OP_REQUEST, + SCOC_E_SCU_N_DATA_REQ }, + { SCCP_SAP_USER, OSMO_SCU_PRIM_N_DISCONNECT, PRIM_OP_REQUEST, + SCOC_E_SCU_N_DISC_REQ }, + { SCCP_SAP_USER, OSMO_SCU_PRIM_N_EXPEDITED_DATA, PRIM_OP_REQUEST, + SCOC_E_SCU_N_EXP_DATA_REQ }, + { 0, 0, 0, OSMO_NO_EVENT } +}; + +/*********************************************************************** + * Timer Handling + ***********************************************************************/ + +/* T(ias) has expired, send a COIT message to the peer */ +static void tx_inact_tmr_cb(void *data) +{ + struct sccp_connection *conn = data; + osmo_fsm_inst_dispatch(conn->fi, SCOC_E_T_IAS_EXP, NULL); +} + +/* T(iar) has expired, notify the FSM about it */ +static void rx_inact_tmr_cb(void *data) +{ + struct sccp_connection *conn = data; + osmo_fsm_inst_dispatch(conn->fi, SCOC_E_T_IAR_EXP, NULL); +} + +/* T(rel) has expired, notify the FSM about it */ +static void rel_tmr_cb(void *data) +{ + struct sccp_connection *conn = data; + osmo_fsm_inst_dispatch(conn->fi, SCOC_E_T_REL_EXP, NULL); +} + +/* T(int) has expired, notify the FSM about it */ +static void int_tmr_cb(void *data) +{ + struct sccp_connection *conn = data; + osmo_fsm_inst_dispatch(conn->fi, SCOC_E_T_INT_EXP, NULL); +} + +/* T(repeat_rel) has expired, notify the FSM about it */ +static void rep_rel_tmr_cb(void *data) +{ + struct sccp_connection *conn = data; + osmo_fsm_inst_dispatch(conn->fi, SCOC_E_T_REP_REL_EXP, NULL); +} + +/* T(conn) has expired, notify the FSM about it */ +static void conn_tmr_cb(void *data) +{ + struct sccp_connection *conn = data; + osmo_fsm_inst_dispatch(conn->fi, SCOC_E_CONN_TMR_EXP, NULL); +} + +/* Re-start the Tx inactivity timer */ +static void conn_restart_tx_inact_timer(struct sccp_connection *conn) +{ + osmo_timer_schedule(&conn->t_ias, MSEC_TO_S_US(TX_INACT_TIMER)); +} + +/* Re-start the Rx inactivity timer */ +static void conn_restart_rx_inact_timer(struct sccp_connection *conn) +{ + osmo_timer_schedule(&conn->t_iar, MSEC_TO_S_US(RX_INACT_TIMER)); +} + +/* Re-start both Rx and Tx inactivity timers */ +static void conn_start_inact_timers(struct sccp_connection *conn) +{ + conn_restart_tx_inact_timer(conn); + conn_restart_rx_inact_timer(conn); +} + +/* Stop both Rx and Tx inactivity timers */ +static void conn_stop_inact_timers(struct sccp_connection *conn) +{ + osmo_timer_del(&conn->t_ias); + osmo_timer_del(&conn->t_iar); +} + +/* Start release timer T(rel) */ +static void conn_start_rel_timer(struct sccp_connection *conn) +{ + osmo_timer_schedule(&conn->t_rel, MSEC_TO_S_US(RELEASE_TIMER)); +} + +/* Start repeat release timer T(rep_rel) */ +static void conn_start_rep_rel_timer(struct sccp_connection *conn) +{ + osmo_timer_schedule(&conn->t_rep_rel, MSEC_TO_S_US(RELEASE_REP_TIMER)); +} + +/* Start interval timer T(int) */ +static void conn_start_int_timer(struct sccp_connection *conn) +{ + osmo_timer_schedule(&conn->t_int, MSEC_TO_S_US(INT_TIMER)); +} + +/* Stop all release related timers: T(rel), T(int) and T(rep_rel) */ +static void conn_stop_release_timers(struct sccp_connection *conn) +{ + osmo_timer_del(&conn->t_rel); + osmo_timer_del(&conn->t_int); + osmo_timer_del(&conn->t_rep_rel); +} + +/* Start connect timer T(conn) */ +static void conn_start_connect_timer(struct sccp_connection *conn) +{ + osmo_timer_schedule(&conn->t_conn, MSEC_TO_S_US(CONNECTION_TIMER)); +} + +/* Stop connect timer T(conn) */ +static void conn_stop_connect_timer(struct sccp_connection *conn) +{ + osmo_timer_del(&conn->t_conn); +} + + +/*********************************************************************** + * SUA Instance and Connection handling + ***********************************************************************/ + +static void conn_destroy(struct sccp_connection *conn); + +static struct sccp_connection *conn_find_by_id(struct osmo_sccp_instance *inst, uint32_t id) +{ + struct sccp_connection *conn; + + llist_for_each_entry(conn, &inst->connections, list) { + if (conn->conn_id == id) + return conn; + } + return NULL; +} + +#define INIT_TIMER(x, fn, priv) do { (x)->cb = fn; (x)->data = priv; } while (0) + +/* allocate + init a SCCP Connection with given ID (local reference) */ +static struct sccp_connection *conn_create_id(struct osmo_sccp_instance *inst, + uint32_t conn_id) +{ + struct sccp_connection *conn = talloc_zero(inst, struct sccp_connection); + char name[16]; + + conn->conn_id = conn_id; + conn->inst = inst; + + llist_add_tail(&conn->list, &inst->connections); + + INIT_TIMER(&conn->t_conn, conn_tmr_cb, conn); + INIT_TIMER(&conn->t_ias, tx_inact_tmr_cb, conn); + INIT_TIMER(&conn->t_iar, rx_inact_tmr_cb, conn); + INIT_TIMER(&conn->t_rel, rel_tmr_cb, conn); + INIT_TIMER(&conn->t_int, int_tmr_cb, conn); + INIT_TIMER(&conn->t_rep_rel, rep_rel_tmr_cb, conn); + + /* this might change at runtime, as it is not a constant :/ */ + sccp_scoc_fsm.log_subsys = DLSCCP; + + /* we simply use the local reference as FSM instance name */ + snprintf(name, sizeof(name), "%u", conn->conn_id); + conn->fi = osmo_fsm_inst_alloc(&sccp_scoc_fsm, conn, conn, + LOGL_DEBUG, name); + if (!conn->fi) { + llist_del(&conn->list); + talloc_free(conn); + return NULL; + } + + return conn; +} + +/* Search for next free connection ID (local reference) and allocate conn */ +static struct sccp_connection *conn_create(struct osmo_sccp_instance *inst) +{ + uint32_t conn_id; + + do { + conn_id = inst->next_id++; + } while (conn_find_by_id(inst, conn_id)); + + return conn_create_id(inst, conn_id); +} + +/* destroy a SCCP connection state, releasing all timers, terminating + * FSM and releasing associated memory */ +static void conn_destroy(struct sccp_connection *conn) +{ + conn_stop_connect_timer(conn); + conn_stop_inact_timers(conn); + conn_stop_release_timers(conn); + llist_del(&conn->list); + + osmo_fsm_inst_term(conn->fi, OSMO_FSM_TERM_REQUEST, NULL); + + talloc_free(conn); +} + +/* allocate a message buffer for an SCCP User Primitive */ +static struct msgb *scu_msgb_alloc(void) +{ + return msgb_alloc(SCU_MSGB_SIZE, "SCCP User Primitive"); +} + +/* generate a RELRE (release request) xua_msg for given conn */ +static struct xua_msg *xua_gen_relre(struct sccp_connection *conn, + uint32_t cause, + struct osmo_scu_prim *prim) +{ + struct xua_msg *xua = xua_msg_alloc(); + + if (!xua) + return NULL; + + xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_RELRE); + xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, conn->inst->route_ctx); + xua_msg_add_u32(xua, SUA_IEI_DEST_REF, conn->remote_ref); + xua_msg_add_u32(xua, SUA_IEI_SRC_REF, conn->conn_id); + xua_msg_add_u32(xua, SUA_IEI_CAUSE, SUA_CAUSE_T_RELEASE | cause); + /* optional: importance */ + if (prim && msgb_l2(prim->oph.msg)) + xua_msg_add_data(xua, SUA_IEI_DATA, msgb_l2len(prim->oph.msg), + msgb_l2(prim->oph.msg)); + + return xua; +} + +/* generate xua_msg, encode it and send it to SCRC */ +static int xua_gen_relre_and_send(struct sccp_connection *conn, uint32_t cause, + struct osmo_scu_prim *prim) +{ + struct xua_msg *xua; + + xua = xua_gen_relre(conn, cause, prim); + if (!xua) + return -1; + + /* amend this with point code information; The SUA RELRE + * includes neither called nor calling party address! */ + xua->mtp.dpc = conn->remote_pc; + return sccp_scrc_rx_scoc_conn_msg(conn->inst, xua); +} + +/* generate a 'struct xua_msg' of requested type from connection + + * primitive data */ +static struct xua_msg *xua_gen_msg_co(struct sccp_connection *conn, uint32_t event, + struct osmo_scu_prim *prim, int msg_type) +{ + struct xua_msg *xua = xua_msg_alloc(); + + if (!xua) + return NULL; + + switch (msg_type) { + case SUA_CO_CORE: /* Connect Request == SCCP CR */ + xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_CORE); + xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, conn->inst->route_ctx); + xua_msg_add_u32(xua, SUA_IEI_PROTO_CLASS, conn->sccp_class); + xua_msg_add_u32(xua, SUA_IEI_SRC_REF, conn->conn_id); + xua_msg_add_sccp_addr(xua, SUA_IEI_DEST_ADDR, &conn->called_addr); + xua_msg_add_u32(xua, SUA_IEI_SEQ_CTRL, 0); /* TODO */ + /* optional: sequence number (class 3 only) */ + if (conn->calling_addr.presence) + xua_msg_add_sccp_addr(xua, SUA_IEI_SRC_ADDR, &conn->calling_addr); + /* optional: hop count; importance; priority; credit */ + if (prim && msgb_l2(prim->oph.msg)) + xua_msg_add_data(xua, SUA_IEI_DATA, msgb_l2len(prim->oph.msg), + msgb_l2(prim->oph.msg)); + break; + case SUA_CO_COAK: /* Connect Acknowledge == SCCP CC */ + xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_COAK); + xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, conn->inst->route_ctx); + xua_msg_add_u32(xua, SUA_IEI_PROTO_CLASS, conn->sccp_class); + xua_msg_add_u32(xua, SUA_IEI_DEST_REF, conn->remote_ref); + xua_msg_add_u32(xua, SUA_IEI_SRC_REF, conn->conn_id); + xua_msg_add_u32(xua, SUA_IEI_SEQ_CTRL, 0); /* TODO */ + /* optional: sequence number (class 3 only) */ + if (conn->called_addr.presence) + xua_msg_add_sccp_addr(xua, SUA_IEI_SRC_ADDR, &conn->called_addr); + /* optional: hop count; importance; priority */ + /* FIXME: destination address will [only] be present in + * case the CORE message conveys the source address + * parameter */ + if (conn->calling_addr.presence) + xua_msg_add_sccp_addr(xua, SUA_IEI_DEST_ADDR, &conn->calling_addr); + if (prim && msgb_l2(prim->oph.msg)) + xua_msg_add_data(xua, SUA_IEI_DATA, msgb_l2len(prim->oph.msg), + msgb_l2(prim->oph.msg)); + break; + case SUA_CO_RELRE: /* Release Request == SCCP REL */ + if (!prim) + goto prim_needed; + xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_RELRE); + xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, conn->inst->route_ctx); + xua_msg_add_u32(xua, SUA_IEI_DEST_REF, conn->remote_ref); + xua_msg_add_u32(xua, SUA_IEI_SRC_REF, conn->conn_id); + xua_msg_add_u32(xua, SUA_IEI_CAUSE, SUA_CAUSE_T_RELEASE | prim->u.disconnect.cause); + /* optional: importance */ + if (msgb_l2(prim->oph.msg)) + xua_msg_add_data(xua, SUA_IEI_DATA, msgb_l2len(prim->oph.msg), + msgb_l2(prim->oph.msg)); + break; + case SUA_CO_RELCO: /* Release Confirm == SCCP RLSD */ + xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_RELCO); + xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, conn->inst->route_ctx); + xua_msg_add_u32(xua, SUA_IEI_DEST_REF, conn->remote_ref); + xua_msg_add_u32(xua, SUA_IEI_SRC_REF, conn->conn_id); + /* optional: importance */ + break; + case SUA_CO_CODT: /* Connection Oriented Data Transfer == SCCP DT1 */ + if (!prim) + goto prim_needed; + xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_CODT); + xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, conn->inst->route_ctx); + /* Sequence number only in expedited data */ + xua_msg_add_u32(xua, SUA_IEI_DEST_REF, conn->remote_ref); + /* optional: priority; correlation id */ + xua_msg_add_data(xua, SUA_IEI_DATA, msgb_l2len(prim->oph.msg), + msgb_l2(prim->oph.msg)); + break; + case SUA_CO_COIT: /* Connection Oriented Interval Timer == SCCP IT */ + xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_COIT); + xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, conn->inst->route_ctx); + xua_msg_add_u32(xua, SUA_IEI_PROTO_CLASS, conn->sccp_class); + xua_msg_add_u32(xua, SUA_IEI_SRC_REF, conn->conn_id); + xua_msg_add_u32(xua, SUA_IEI_DEST_REF, conn->remote_ref); + /* optional: sequence number; credit (both class 3 only) */ + break; + case SUA_CO_COREF: /* Connect Refuse == SCCP CREF */ + xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_COREF); + xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, conn->inst->route_ctx); + xua_msg_add_u32(xua, SUA_IEI_DEST_REF, conn->remote_ref); + //xua_msg_add_u32(xua, SUA_IEI_CAUSE, SUA_CAUSE_T_REFUSAL | prim->u.disconnect.cause); + xua_msg_add_u32(xua, SUA_IEI_CAUSE, SUA_CAUSE_T_REFUSAL | SCCP_REFUSAL_UNEQUIPPED_USER); + /* optional: source addr */ + if (conn->called_addr.presence) + xua_msg_add_sccp_addr(xua, SUA_IEI_SRC_ADDR, &conn->called_addr); + /* conditional: dest addr */ + if (conn->calling_addr.presence) + xua_msg_add_sccp_addr(xua, SUA_IEI_DEST_ADDR, &conn->calling_addr); + /* optional: importance */ + /* optional: data */ + if (prim && msgb_l2(prim->oph.msg)) + xua_msg_add_data(xua, SUA_IEI_DATA, msgb_l2len(prim->oph.msg), + msgb_l2(prim->oph.msg)); + break; + /* FIXME */ + default: + LOGP(DLSCCP, LOGL_ERROR, "Don't know how to encode msg_type %u\n", msg_type); + xua_msg_free(xua); + return NULL; + } + return xua; + +prim_needed: + xua_msg_free(xua); + LOGP(DLSCCP, LOGL_ERROR, "%s must be called with valid 'prim' " + "pointer for msg_type=%u\n", __func__, msg_type); + return NULL; +} + +/* generate xua_msg, encode it and send it to SCRC */ +static int xua_gen_encode_and_send(struct sccp_connection *conn, uint32_t event, + struct osmo_scu_prim *prim, int msg_type) +{ + struct xua_msg *xua; + + xua = xua_gen_msg_co(conn, event, prim, msg_type); + if (!xua) + return -1; + + /* amend this with point code information; Many CO msgs + * includes neither called nor calling party address! */ + xua->mtp.dpc = conn->remote_pc; + return sccp_scrc_rx_scoc_conn_msg(conn->inst, xua); +} + +/* allocate a SCU primitive to be sent to the user */ +static struct osmo_scu_prim *scu_prim_alloc(unsigned int primitive, enum osmo_prim_operation operation) +{ + struct msgb *upmsg = scu_msgb_alloc(); + struct osmo_scu_prim *prim; + + prim = (struct osmo_scu_prim *) msgb_put(upmsg, sizeof(*prim)); + osmo_prim_init(&prim->oph, SCCP_SAP_USER, + primitive, operation, upmsg); + return prim; +} + +/* high-level function to generate a SCCP User primitive of requested + * type based on the connection and currently processed XUA message */ +static void scu_gen_encode_and_send(struct sccp_connection *conn, uint32_t event, + struct xua_msg *xua, unsigned int primitive, + enum osmo_prim_operation operation) +{ + struct osmo_scu_prim *scu_prim; + struct osmo_scu_disconn_param *udisp; + struct osmo_scu_connect_param *uconp; + struct osmo_scu_data_param *udatp; + struct xua_msg_part *data_ie; + + scu_prim = scu_prim_alloc(primitive, operation); + + switch (OSMO_PRIM_HDR(&scu_prim->oph)) { + case OSMO_PRIM(OSMO_SCU_PRIM_N_DISCONNECT, PRIM_OP_INDICATION): + udisp = &scu_prim->u.disconnect; + udisp->conn_id = conn->conn_id; + udisp->responding_addr = conn->called_addr; + udisp->originator = OSMO_SCCP_ORIG_UNDEFINED; + //udisp->in_sequence_control; + if (xua) { + udisp->cause = xua_msg_get_u32(xua, SUA_IEI_CAUSE); + if (xua_msg_find_tag(xua, SUA_IEI_SRC_ADDR)) + sua_addr_parse(&udisp->responding_addr, xua, SUA_IEI_SRC_ADDR); + data_ie = xua_msg_find_tag(xua, SUA_IEI_DATA); + udisp->importance = xua_msg_get_u32(xua, SUA_IEI_IMPORTANCE); + if (data_ie) { + struct msgb *upmsg = scu_prim->oph.msg; + upmsg->l2h = msgb_put(upmsg, data_ie->len); + memcpy(upmsg->l2h, data_ie->dat, data_ie->len); + } + } + break; + case OSMO_PRIM(OSMO_SCU_PRIM_N_CONNECT, PRIM_OP_INDICATION): + uconp = &scu_prim->u.connect; + uconp->conn_id = conn->conn_id; + uconp->called_addr = conn->called_addr; + uconp->calling_addr = conn->calling_addr; + uconp->sccp_class = conn->sccp_class; + uconp->importance = conn->importance; + data_ie = xua_msg_find_tag(xua, SUA_IEI_DATA); + if (xua) { + if (data_ie) { + struct msgb *upmsg = scu_prim->oph.msg; + upmsg->l2h = msgb_put(upmsg, data_ie->len); + memcpy(upmsg->l2h, data_ie->dat, data_ie->len); + } + } + break; + case OSMO_PRIM(OSMO_SCU_PRIM_N_CONNECT, PRIM_OP_CONFIRM): + uconp = &scu_prim->u.connect; + uconp->conn_id = conn->conn_id; + uconp->called_addr = conn->called_addr; + uconp->calling_addr = conn->calling_addr; + //scu_prim->u.connect.in_sequence_control + uconp->sccp_class = xua_msg_get_u32(xua, SUA_IEI_PROTO_CLASS) & 3; + uconp->importance = xua_msg_get_u32(xua, SUA_IEI_IMPORTANCE); + data_ie = xua_msg_find_tag(xua, SUA_IEI_DATA); + if (data_ie) { + struct msgb *upmsg = scu_prim->oph.msg; + upmsg->l2h = msgb_put(upmsg, data_ie->len); + memcpy(upmsg->l2h, data_ie->dat, data_ie->len); + } + break; + case OSMO_PRIM(OSMO_SCU_PRIM_N_DATA, PRIM_OP_INDICATION): + udatp = &scu_prim->u.data; + udatp->conn_id = conn->conn_id; + udatp->importance = conn->importance; + data_ie = xua_msg_find_tag(xua, SUA_IEI_DATA); + if (data_ie) { + struct msgb *upmsg = scu_prim->oph.msg; + upmsg->l2h = msgb_put(upmsg, data_ie->len); + memcpy(upmsg->l2h, data_ie->dat, data_ie->len); + } + break; + default: + LOGPFSML(conn->fi, LOGL_ERROR, "Unsupported primitive %u:%u\n", + scu_prim->oph.primitive, scu_prim->oph.operation); + talloc_free(scu_prim->oph.msg); + return; + } + + sccp_user_prim_up(conn->user, scu_prim); +} + + +/*********************************************************************** + * Actual SCCP Connection Oriented Control (SCOC) Finite Stte Machine + ***********************************************************************/ + +/* Figure C.2/Q.714 (sheet 1 of 7) and C.3/Q.714 (sheet 1 of 6) */ +static void scoc_fsm_idle(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct sccp_connection *conn = fi->priv; + struct osmo_scu_prim *prim = NULL; + struct osmo_scu_connect_param *uconp; + struct xua_msg *xua = NULL; + + switch (event) { + case SCOC_E_SCU_N_CONN_REQ: + prim = data; + uconp = &prim->u.connect; + /* copy relevant parameters from prim to conn */ + conn->called_addr = uconp->called_addr; + conn->calling_addr = uconp->calling_addr; + conn->sccp_class = uconp->sccp_class; + /* generate + send CR PDU to SCRC */ + xua_gen_encode_and_send(conn, event, prim, SUA_CO_CORE); + /* start connection timer */ + conn_start_connect_timer(conn); + osmo_fsm_inst_state_chg(fi, S_CONN_PEND_OUT, 0, 0); + break; +#if 0 + case SCOC_E_SCU_N_TYPE1_REQ: + /* ?!? */ + break; +#endif + case SCOC_E_RCOC_RLSD_IND: + /* send release complete to SCRC */ + xua_gen_encode_and_send(conn, event, NULL, SUA_CO_RELCO); + break; + case SCOC_E_RCOC_REL_COMPL_IND: + /* do nothing */ + break; + case SCOC_E_RCOC_OTHER_NPDU: +#if 0 + if (src_ref) { + /* FIXME: send ERROR to SCRC */ + } +#endif + break; + /* destination node / incoming connection */ + /* Figure C.3 / Q.714 (sheet 1 of 6) */ + case SCOC_E_RCOC_CONN_IND: + xua = data; + /* copy relevant parameters from xua to conn */ + sua_addr_parse(&conn->calling_addr, xua, SUA_IEI_SRC_ADDR); + sua_addr_parse(&conn->called_addr, xua, SUA_IEI_DEST_ADDR); + conn->remote_ref = xua_msg_get_u32(xua, SUA_IEI_SRC_REF); + conn->sccp_class = xua_msg_get_u32(xua, SUA_IEI_PROTO_CLASS) & 3; + conn->importance = xua_msg_get_u32(xua, SUA_IEI_IMPORTANCE); + /* 3.1.6.1 The originating node of the CR message + * (identified by the OPC in the calling party address + * or by default by the OPC in the MTP label, [and the + * MTP-SAP instance]) is associated with the incoming + * connection section. */ + if (conn->calling_addr.presence & OSMO_SCCP_ADDR_T_PC) + conn->remote_pc = conn->calling_addr.pc; + else { + /* Hack to get the MTP label here ?!? */ + conn->remote_pc = xua->mtp.opc; + } + + osmo_fsm_inst_state_chg(fi, S_CONN_PEND_IN, 0, 0); + /* N-CONNECT.ind to User */ + scu_gen_encode_and_send(conn, event, xua, OSMO_SCU_PRIM_N_CONNECT, + PRIM_OP_INDICATION); + break; + } +} + +static void scoc_fsm_idle_onenter(struct osmo_fsm_inst *fi, uint32_t old_state) +{ + conn_destroy(fi->priv); +} + +/* Figure C.3 / Q.714 (sheet 2 of 6) */ +static void scoc_fsm_conn_pend_in(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct sccp_connection *conn = fi->priv; + struct osmo_scu_prim *prim = NULL; + + switch (event) { + case SCOC_E_SCU_N_CONN_RESP: + prim = data; + /* FIXME: assign local reference (only now?) */ + /* FIXME: assign sls, protocol class and credit */ + xua_gen_encode_and_send(conn, event, prim, SUA_CO_COAK); + /* start inactivity timers */ + conn_start_inact_timers(conn); + osmo_fsm_inst_state_chg(fi, S_ACTIVE, 0, 0); + break; + case SCOC_E_SCU_N_DISC_REQ: + prim = data; + /* release resources: implicit */ + xua_gen_encode_and_send(conn, event, prim, SUA_CO_COREF); + osmo_fsm_inst_state_chg(fi, S_IDLE, 0, 0); + break; + } +} + +/* Figure C.2/Q.714 (sheet 2 of 7) */ +static void scoc_fsm_conn_pend_out(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct sccp_connection *conn = fi->priv; + struct osmo_scu_prim *prim = NULL; + struct xua_msg *xua = NULL; + + switch (event) { + case SCOC_E_SCU_N_DISC_REQ: + prim = data; + conn->release_cause = prim->u.disconnect.cause; + osmo_fsm_inst_state_chg(fi, S_WAIT_CONN_CONF, 0, 0); + /* keep conn timer running(!) */ + break; + case SCOC_E_CONN_TMR_EXP: + /* N-DISCONNECT.ind to user */ + scu_gen_encode_and_send(conn, event, xua, OSMO_SCU_PRIM_N_DISCONNECT, + PRIM_OP_INDICATION); + /* below implicitly releases resources + local ref */ + osmo_fsm_inst_state_chg(fi, S_IDLE, 0, 0); + break; + case SCOC_E_RCOC_ROUT_FAIL_IND: + case SCOC_E_RCOC_CREF_IND: + xua = data; + /* stop conn timer */ + conn_stop_connect_timer(conn); + /* release local res + ref (implicit by going to idle) */ + /* N-DISCONNECT.ind to user */ + scu_gen_encode_and_send(conn, event, xua, OSMO_SCU_PRIM_N_DISCONNECT, + PRIM_OP_INDICATION); + /* below implicitly releases resources + local ref */ + osmo_fsm_inst_state_chg(fi, S_IDLE, 0, 0); + break; + case SCOC_E_RCOC_RLSD_IND: + xua = data; + /* RLC to SCRC */ + xua_gen_encode_and_send(conn, event, NULL, SUA_CO_RELCO); + /* stop conn timer */ + conn_stop_connect_timer(conn); + /* release local res + ref (implicit) */ + /* N-DISCONNECT.ind to user */ + scu_gen_encode_and_send(conn, event, xua, OSMO_SCU_PRIM_N_DISCONNECT, + PRIM_OP_INDICATION); + osmo_fsm_inst_state_chg(fi, S_IDLE, 0, 0); + break; + case SCOC_E_RCOC_OTHER_NPDU: + xua = data; + conn_start_connect_timer(conn); + /* release local res + ref (implicit) */ + /* N-DISCONNECT.ind to user */ + scu_gen_encode_and_send(conn, event, xua, OSMO_SCU_PRIM_N_DISCONNECT, + PRIM_OP_INDICATION); + osmo_fsm_inst_state_chg(fi, S_IDLE, 0, 0); + break; + case SCOC_E_RCOC_CC_IND: + xua = data; + /* stop conn timer */ + conn_stop_connect_timer(conn); + /* start inactivity timers */ + conn_start_inact_timers(conn); + /* TODO: assign PCU and credit */ + /* associate remote ref to conn */ + conn->remote_ref = xua_msg_get_u32(xua, SUA_IEI_SRC_REF); + /* 3.1.4.2 The node sending the CC message (identified + * by the parameter OPC contained in the + * MTP-TRANSFER.indication primitive which conveyed the + * CC message [plus the MTP-SAP instance]) is associated + * with the connection section. */ + conn->remote_pc = xua->mtp.opc; + + osmo_fsm_inst_state_chg(fi, S_ACTIVE, 0, 0); + /* N-CONNECT.conf to user */ + scu_gen_encode_and_send(conn, event, xua, OSMO_SCU_PRIM_N_CONNECT, + PRIM_OP_CONFIRM); + break; + } +} + +/* Figure C.2/Q.714 (sheet 3 of 7) */ +static void scoc_fsm_wait_conn_conf(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct sccp_connection *conn = fi->priv; + struct xua_msg *xua = NULL; + + switch (event) { + case SCOC_E_RCOC_RLSD_IND: + xua = data; + /* release complete to SCRC */ + xua_gen_encode_and_send(conn, event, NULL, SUA_CO_RELCO); + /* stop conn timer */ + conn_stop_connect_timer(conn); + /* release local res + ref (implicit) */ + osmo_fsm_inst_state_chg(fi, S_IDLE, 0, 0); + break; + case SCOC_E_RCOC_CC_IND: + xua = data; + /* stop conn timer */ + conn_stop_connect_timer(conn); + /* associate rem ref to conn */ + conn->remote_ref = xua_msg_get_u32(xua, SUA_IEI_SRC_REF); + /* released to SCRC */ + xua_gen_relre_and_send(conn, conn->release_cause, NULL); + /* start rel timer */ + conn_start_rel_timer(conn); + osmo_fsm_inst_state_chg(fi, S_DISCONN_PEND, 0, 0); + break; + case SCOC_E_RCOC_OTHER_NPDU: + case SCOC_E_RCOC_CREF_IND: + case SCOC_E_RCOC_ROUT_FAIL_IND: + xua = data; + /* stop conn timer */ + conn_stop_connect_timer(conn); + /* release local res + ref */ + osmo_fsm_inst_state_chg(fi, S_IDLE, 0, 0); + break; + case SCOC_E_CONN_TMR_EXP: + /* release local res + ref */ + osmo_fsm_inst_state_chg(fi, S_IDLE, 0, 0); + break; + } +} + +/* C.2/Q.714 (sheet 4+5 of 7) and C.3/Q714 (sheet 3+4 of 6) */ +static void scoc_fsm_active(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct xua_msg *xua = data; + struct sccp_connection *conn = fi->priv; + struct osmo_scu_prim *prim = NULL; + + switch (event) { + /* TODO: internal disco */ + /* send N-DISCONNECT.ind to user */ + scu_gen_encode_and_send(conn, event, xua, OSMO_SCU_PRIM_N_DISCONNECT, + PRIM_OP_INDICATION); + /* fall-through */ + case SCOC_E_SCU_N_DISC_REQ: + prim = data; + /* stop inact timers */ + conn_stop_inact_timers(conn); + /* send RLSD to SCRC */ + xua_gen_encode_and_send(conn, event, prim, SUA_CO_RELRE); + /* start rel timer */ + conn_start_rel_timer(conn); + osmo_fsm_inst_state_chg(fi, S_DISCONN_PEND, 0, 0); + break; + case SCOC_E_RCOC_CREF_IND: + case SCOC_E_RCOC_CC_IND: + case SCOC_E_RCOC_REL_COMPL_IND: + /* do nothing */ + break; + case SCOC_E_RCOC_RLSD_IND: + /* send N-DISCONNECT.ind to user */ + scu_gen_encode_and_send(conn, event, xua, OSMO_SCU_PRIM_N_DISCONNECT, + PRIM_OP_INDICATION); + /* release res + local ref (implicit) */ + /* stop inact timers */ + conn_stop_inact_timers(conn); + /* RLC to SCRC */ + xua_gen_encode_and_send(conn, event, NULL, SUA_CO_RELCO); + osmo_fsm_inst_state_chg(fi, S_IDLE, 0, 0); + break; + case SCOC_E_RCOC_ERROR_IND: + xua = data; + /* FIXME: check for cause service_class_mismatch */ + /* release res + local ref (implicit) */ + /* send N-DISCONNECT.ind to user */ + scu_gen_encode_and_send(conn, event, xua, OSMO_SCU_PRIM_N_DISCONNECT, + PRIM_OP_INDICATION); + /* stop inact timers */ + conn_stop_inact_timers(conn); + osmo_fsm_inst_state_chg(fi, S_IDLE, 0, 0); + break; + case SCOC_E_T_IAR_EXP: + /* Send N-DISCONNECT.ind to local user */ + scu_gen_encode_and_send(conn, event, NULL, OSMO_SCU_PRIM_N_DISCONNECT, + PRIM_OP_INDICATION); + /* Send RLSD to peer */ + xua_gen_relre_and_send(conn, SCCP_RELEASE_CAUSE_EXPIRATION_INACTIVE, NULL); + conn_start_rel_timer(conn); + osmo_fsm_inst_state_chg(fi, S_DISCONN_PEND, 0, 0); + break; + case SCOC_E_RCOC_ROUT_FAIL_IND: + /* send N-DISCONNECT.ind to user */ + scu_gen_encode_and_send(conn, event, NULL, OSMO_SCU_PRIM_N_DISCONNECT, + PRIM_OP_INDICATION); + /* stop inact timers */ + conn_stop_inact_timers(conn); + /* start release timer */ + conn_start_rel_timer(conn); + osmo_fsm_inst_state_chg(fi, S_DISCONN_PEND, 0, 0); + break; + /* Figure C.4/Q.714 */ + case SCOC_E_SCU_N_DATA_REQ: + case SCOC_E_SCU_N_EXP_DATA_REQ: + prim = data; + xua_gen_encode_and_send(conn, event, prim, SUA_CO_CODT); + conn_restart_tx_inact_timer(conn); + break; + case SCOC_E_RCOC_DT1_IND: + /* restart receive inactivity timer */ + conn_restart_rx_inact_timer(conn); + /* TODO: M-bit */ + scu_gen_encode_and_send(conn, event, xua, OSMO_SCU_PRIM_N_DATA, + PRIM_OP_INDICATION); + break; + /* Figure C.4/Q.714 (sheet 4 of 4) */ + case SCOC_E_RCOC_IT_IND: + xua = data; + /* check if remote reference is what we expect */ + /* check class is what we expect */ + if (xua_msg_get_u32(xua, SUA_IEI_SRC_REF) != conn->remote_ref || + xua_msg_get_u32(xua, SUA_IEI_PROTO_CLASS) != conn->sccp_class) { + /* Release connection */ + /* send N-DISCONNECT.ind to user */ + scu_gen_encode_and_send(conn, event, NULL, + OSMO_SCU_PRIM_N_DISCONNECT, + PRIM_OP_INDICATION); + /* Stop inactivity Timers */ + conn_stop_inact_timers(conn); + /* Send RLSD to SCRC */ + xua_gen_relre_and_send(conn, SCCP_RELEASE_CAUSE_INCONSISTENT_CONN_DATA, NULL); + /* Start release timer */ + conn_start_rel_timer(conn); + osmo_fsm_inst_state_chg(fi, S_DISCONN_PEND, 0, 0); + } + conn_restart_rx_inact_timer(conn); + break; + case SCOC_E_T_IAS_EXP: + /* Send IT to peer */ + xua_gen_encode_and_send(conn, event, NULL, SUA_CO_COIT); + conn_restart_tx_inact_timer(conn); + break; + } +} + +/* C.2/Q.714 (sheet 6+7 of 7) and C.3/Q.714 (sheet 5+6 of 6) */ +static void scoc_fsm_disconn_pend(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct sccp_connection *conn = fi->priv; + + switch (event) { + case SCOC_E_RCOC_REL_COMPL_IND: + case SCOC_E_RCOC_RLSD_IND: + /* release res + local ref (implicit) */ + /* freeze local ref */ + /* stop release + interval timers */ + conn_stop_release_timers(conn); + osmo_fsm_inst_state_chg(fi, S_IDLE, 0, 0); + break; + case SCOC_E_RCOC_ROUT_FAIL_IND: + case SCOC_E_RCOC_OTHER_NPDU: + /* do nothing */ + break; + case SCOC_E_T_REL_EXP: /* release timer exp */ + /* send RLSD */ + xua_gen_relre_and_send(conn, SCCP_RELEASE_CAUSE_UNQUALIFIED, NULL); + /* start interval timer */ + conn_start_int_timer(conn); + /* start repeat release timer */ + conn_start_rep_rel_timer(conn); + break; + case SCOC_E_T_INT_EXP: /* interval timer exp */ + /* TODO: Inform maintenance */ + /* stop release and interval timers */ + conn_stop_release_timers(conn); + osmo_fsm_inst_state_chg(fi, S_IDLE, 0, 0); + break; + case SCOC_E_T_REP_REL_EXP: /* repeat release timer exp */ + /* send RLSD */ + xua_gen_relre_and_send(conn, SCCP_RELEASE_CAUSE_UNQUALIFIED, NULL); + /* re-start repeat release timer */ + conn_start_rep_rel_timer(conn); + break; + } +} + +static const struct osmo_fsm_state sccp_scoc_states[] = { + [S_IDLE] = { + .name = "IDLE", + .action = scoc_fsm_idle, + .onenter= scoc_fsm_idle_onenter, + .in_event_mask = S(SCOC_E_SCU_N_CONN_REQ) | + //S(SCOC_E_SCU_N_TYPE1_REQ) | + S(SCOC_E_RCOC_CONN_IND) | + S(SCOC_E_RCOC_RLSD_IND) | + S(SCOC_E_RCOC_REL_COMPL_IND) | + S(SCOC_E_RCOC_OTHER_NPDU), + .out_state_mask = S(S_CONN_PEND_OUT) | + S(S_CONN_PEND_IN), + }, + [S_CONN_PEND_IN] = { + .name = "CONN_PEND_IN", + .action = scoc_fsm_conn_pend_in, + .in_event_mask = S(SCOC_E_SCU_N_CONN_RESP) | + S(SCOC_E_SCU_N_DISC_REQ), + .out_state_mask = S(S_IDLE) | + S(S_ACTIVE), + }, + [S_CONN_PEND_OUT] = { + .name = "CONN_PEND_OUT", + .action = scoc_fsm_conn_pend_out, + .in_event_mask = S(SCOC_E_SCU_N_DISC_REQ) | + S(SCOC_E_CONN_TMR_EXP) | + S(SCOC_E_RCOC_ROUT_FAIL_IND) | + S(SCOC_E_RCOC_RLSD_IND) | + S(SCOC_E_RCOC_OTHER_NPDU) | + S(SCOC_E_RCOC_CREF_IND) | + S(SCOC_E_RCOC_CC_IND), + .out_state_mask = S(S_IDLE) | + S(S_ACTIVE) | + S(S_WAIT_CONN_CONF), + }, + [S_ACTIVE] = { + .name = "ACTIVE", + .action = scoc_fsm_active, + .in_event_mask = S(SCOC_E_SCU_N_DISC_REQ) | + /* internal disconnect */ + S(SCOC_E_RCOC_CREF_IND) | + S(SCOC_E_RCOC_REL_COMPL_IND) | + S(SCOC_E_RCOC_RLSD_IND) | + S(SCOC_E_RCOC_ERROR_IND) | + S(SCOC_E_T_IAR_EXP) | + S(SCOC_E_T_IAS_EXP) | + S(SCOC_E_RCOC_ROUT_FAIL_IND) | + S(SCOC_E_SCU_N_DATA_REQ) | + S(SCOC_E_SCU_N_EXP_DATA_REQ) | + S(SCOC_E_RCOC_DT1_IND) | + S(SCOC_E_RCOC_IT_IND), + .out_state_mask = S(S_IDLE) | + S(S_DISCONN_PEND), + }, + [S_DISCONN_PEND] = { + .name = "DISCONN_PEND", + .action = scoc_fsm_disconn_pend, + .in_event_mask = S(SCOC_E_RCOC_REL_COMPL_IND) | + S(SCOC_E_RCOC_RLSD_IND) | + S(SCOC_E_RCOC_ROUT_FAIL_IND) | + S(SCOC_E_RCOC_OTHER_NPDU) | + S(SCOC_E_T_REL_EXP) | + S(SCOC_E_T_INT_EXP) | + S(SCOC_E_T_REP_REL_EXP), + .out_state_mask = S(S_IDLE), + }, + [S_RESET_IN] = { + .name = "RESET_IN", + }, + [S_RESET_OUT] = { + .name = "RESET_OUT", + }, + [S_BOTHWAY_RESET] = { + .name = "BOTHWAY_RESET", + }, + [S_WAIT_CONN_CONF] = { + .name = "WAIT_CONN_CONF", + .action = scoc_fsm_wait_conn_conf, + .in_event_mask = S(SCOC_E_RCOC_RLSD_IND) | + S(SCOC_E_RCOC_CC_IND) | + S(SCOC_E_RCOC_OTHER_NPDU) | + S(SCOC_E_CONN_TMR_EXP) | + S(SCOC_E_RCOC_CREF_IND) | + S(SCOC_E_RCOC_ROUT_FAIL_IND), + }, +}; + +struct osmo_fsm sccp_scoc_fsm = { + .name = "SCCP-SCOC", + .states = sccp_scoc_states, + .num_states = ARRAY_SIZE(sccp_scoc_states), + /* ".log_subsys = DLSCCP" doesn't work as DLSCCP is not a constant */ + .event_names = scoc_event_names, +}; + +/* map from SCCP return cause to SCCP Refusal cause */ +static const uint8_t cause_map_cref[] = { + [SCCP_RETURN_CAUSE_SUBSYSTEM_CONGESTION] = + SCCP_REFUSAL_SUBSYTEM_CONGESTION, + [SCCP_RETURN_CAUSE_SUBSYSTEM_FAILURE] = + SCCP_REFUSAL_SUBSYSTEM_FAILURE, + [SCCP_RETURN_CAUSE_UNEQUIPPED_USER] = + SCCP_REFUSAL_UNEQUIPPED_USER, + [SCCP_RETURN_CAUSE_UNQUALIFIED] = + SCCP_REFUSAL_UNQUALIFIED, + [SCCP_RETURN_CAUSE_SCCP_FAILURE] = + SCCP_REFUSAL_SCCP_FAILURE, + [SCCP_RETURN_CAUSE_HOP_COUNTER_VIOLATION] = + SCCP_REFUSAL_HOP_COUNTER_VIOLATION, +}; + +static uint8_t get_cref_cause_for_ret(uint8_t ret_cause) +{ + if (ret_cause < ARRAY_SIZE(cause_map_cref)) + return cause_map_cref[ret_cause]; + else + return SCCP_REFUSAL_UNQUALIFIED; +} + +/* Generate a COREF message purely based on an incoming SUA message, + * without the use of any local connection state */ +static struct xua_msg *gen_coref_without_conn(struct osmo_sccp_instance *inst, + struct xua_msg *xua_in, + uint32_t ref_cause) +{ + struct xua_msg *xua; + + xua = xua_msg_alloc(); + xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_COREF); + xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, inst->route_ctx); + + xua_msg_copy_part(xua, SUA_IEI_DEST_REF, xua_in, SUA_IEI_SRC_REF); + xua_msg_add_u32(xua, SUA_IEI_CAUSE, SUA_CAUSE_T_REFUSAL | ref_cause); + /* optional: source addr */ + xua_msg_copy_part(xua, SUA_IEI_SRC_ADDR, xua_in, SUA_IEI_DEST_ADDR); + /* conditional: dest addr */ + xua_msg_copy_part(xua, SUA_IEI_DEST_ADDR, xua_in, SUA_IEI_SRC_ADDR); + /* optional: importance */ + xua_msg_copy_part(xua, SUA_IEI_IMPORTANCE, xua_in, SUA_IEI_IMPORTANCE); + /* optional: data */ + xua_msg_copy_part(xua, SUA_IEI_DATA, xua_in, SUA_IEI_DATA); + + return xua; +} + +/*! \brief SCOC: Receive SCRC Routing Failure + * \param[in] inst SCCP Instance on which we operate + * \param[in] xua SUA message that was failed to route + * \param[in] return_cause Reason (cause) for routing failure */ +void sccp_scoc_rx_scrc_rout_fail(struct osmo_sccp_instance *inst, + struct xua_msg *xua, uint32_t return_cause) +{ + uint32_t conn_id; + struct sccp_connection *conn; + + /* try to dispatch to connection FSM (if any) */ + conn_id = xua_msg_get_u32(xua, SUA_IEI_DEST_REF); + conn = conn_find_by_id(inst, conn_id); + if (conn) { + osmo_fsm_inst_dispatch(conn->fi, + SCOC_E_RCOC_ROUT_FAIL_IND, xua); + } else { + /* generate + send CREF directly */ + struct xua_msg *cref; + uint8_t cref_cause = get_cref_cause_for_ret(return_cause); + cref = gen_coref_without_conn(inst, xua, cref_cause); + sccp_scrc_rx_scoc_conn_msg(inst, cref); + xua_msg_free(cref); + } +} + +/* Find a SCCP user for given SUA message (based on SUA_IEI_DEST_ADDR */ +static struct osmo_sccp_user *sccp_find_user(struct osmo_sccp_instance *inst, + struct xua_msg *xua) +{ + int rc; + struct osmo_sccp_addr called_addr; + + rc = sua_addr_parse(&called_addr, xua, SUA_IEI_DEST_ADDR); + if (rc < 0) { + LOGP(DLSCCP, LOGL_ERROR, "Cannot find SCCP User for XUA " + "Message %s without valid DEST_ADDR\n", + xua_hdr_dump(xua, &xua_dialect_sua)); + return NULL; + } + + if (!(called_addr.presence & OSMO_SCCP_ADDR_T_SSN)) { + LOGP(DLSCCP, LOGL_ERROR, "Cannot resolve SCCP User for " + "XUA Message %s without SSN in CalledAddr\n", + xua_hdr_dump(xua, &xua_dialect_sua)); + return NULL; + } + + return sccp_user_find(inst, called_addr.ssn, called_addr.pc); +} + +/* Generate a COERR based in input arguments */ +static struct xua_msg *gen_coerr(uint32_t route_ctx, uint32_t dest_ref, + uint32_t err_cause) +{ + struct xua_msg *xua = xua_msg_alloc(); + + xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_COERR); + xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, route_ctx); + xua_msg_add_u32(xua, SUA_IEI_DEST_REF, dest_ref); + xua_msg_add_u32(xua, SUA_IEI_CAUSE, SUA_CAUSE_T_ERROR | err_cause); + + return xua; +} + +/* generate COERR from incoming XUA and send it */ +static void tx_coerr_from_xua(struct osmo_sccp_instance *inst, + struct xua_msg *in, uint32_t err_cause) +{ + struct xua_msg *xua; + uint32_t route_ctx, dest_ref; + + route_ctx = xua_msg_get_u32(in, SUA_IEI_ROUTE_CTX); + /* get *source* reference and use as destination ref */ + dest_ref = xua_msg_get_u32(in, SUA_IEI_SRC_REF); + + xua = gen_coerr(route_ctx, dest_ref, err_cause); + /* copy over the MTP parameters */ + xua->mtp.dpc = in->mtp.opc; + xua->mtp.opc = in->mtp.dpc; + xua->mtp.sio = in->mtp.sio; + + /* sent to SCRC for transmission */ + sccp_scrc_rx_scoc_conn_msg(inst, xua); + xua_msg_free(xua); +} + +/* Generate a RELCO based in input arguments */ +static struct xua_msg *gen_relco(uint32_t route_ctx, uint32_t dest_ref, + uint32_t src_ref) +{ + struct xua_msg *xua = xua_msg_alloc(); + + xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_RELCO); + xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, route_ctx); + xua_msg_add_u32(xua, SUA_IEI_DEST_REF, dest_ref); + xua_msg_add_u32(xua, SUA_IEI_SRC_REF, src_ref); + + return xua; +} + +/* generate RELCO from incoming XUA and send it */ +static void tx_relco_from_xua(struct osmo_sccp_instance *inst, + struct xua_msg *in) +{ + struct xua_msg *xua; + uint32_t route_ctx, dest_ref, src_ref; + + route_ctx = xua_msg_get_u32(in, SUA_IEI_ROUTE_CTX); + /* get *source* reference and use as destination ref */ + dest_ref = xua_msg_get_u32(in, SUA_IEI_SRC_REF); + /* get *dest* reference and use as source ref */ + src_ref = xua_msg_get_u32(in, SUA_IEI_DEST_REF); + + xua = gen_relco(route_ctx, dest_ref, src_ref); + /* copy over the MTP parameters */ + xua->mtp.dpc = in->mtp.opc; + xua->mtp.opc = in->mtp.dpc; + xua->mtp.sio = in->mtp.sio; + + /* send to SCRC for transmission */ + sccp_scrc_rx_scoc_conn_msg(inst, xua); + xua_msg_free(xua); +} + +/* Generate a RLSD based in input arguments */ +static struct xua_msg *gen_rlsd(uint32_t route_ctx, uint32_t dest_ref, + uint32_t src_ref) +{ + struct xua_msg *xua = xua_msg_alloc(); + + xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_RELRE); + xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, route_ctx); + xua_msg_add_u32(xua, SUA_IEI_DEST_REF, dest_ref); + xua_msg_add_u32(xua, SUA_IEI_SRC_REF, src_ref); + + return xua; +} + +/* Generate a RLSD to both the remote side and the local conn */ +static void tx_rlsd_from_xua_twoway(struct sccp_connection *conn, + struct xua_msg *in) +{ + struct xua_msg *xua; + uint32_t route_ctx, dest_ref, src_ref; + + route_ctx = xua_msg_get_u32(in, SUA_IEI_ROUTE_CTX); + /* get *source* reference and use as destination ref */ + dest_ref = xua_msg_get_u32(in, SUA_IEI_SRC_REF); + /* get *source* reference and use as destination ref */ + src_ref = xua_msg_get_u32(in, SUA_IEI_DEST_REF); + + /* Generate RLSD towards remote peer */ + xua = gen_rlsd(route_ctx, dest_ref, src_ref); + /* copy over the MTP parameters */ + xua->mtp.dpc = in->mtp.opc; + xua->mtp.opc = in->mtp.dpc; + xua->mtp.sio = in->mtp.sio; + /* send to SCRC for transmission */ + sccp_scrc_rx_scoc_conn_msg(conn->inst, xua); + xua_msg_free(xua); + + /* Generate RLSD towards local peer */ + xua = gen_rlsd(conn->inst->route_ctx, conn->conn_id, conn->remote_ref); + xua->mtp.dpc = in->mtp.dpc; + xua->mtp.opc = conn->remote_pc; + xua->mtp.sio = in->mtp.sio; + osmo_fsm_inst_dispatch(conn->fi, SCOC_E_RCOC_RLSD_IND, xua); + xua_msg_free(xua); +} + +/* process received message for unasigned local reference */ +static void sccp_scoc_rx_unass_local_ref(struct osmo_sccp_instance *inst, + struct xua_msg *xua) +{ + /* we have received a message with unassigned destination local + * reference and thus apply the action indicated in Table + * B.2/Q.714 */ + switch (xua->hdr.msg_type) { + case SUA_CO_COAK: /* CC */ + case SUA_CO_COIT: /* IT */ + case SUA_CO_RESRE: /* RSR */ + case SUA_CO_RESCO: /* RSC */ + /* Send COERR */ + tx_coerr_from_xua(inst, xua, SCCP_ERROR_LRN_MISMATCH_UNASSIGNED); + break; + case SUA_CO_COREF: /* CREF */ + case SUA_CO_RELCO: /* RLC */ + case SUA_CO_CODT: /* DT1 */ + case SUA_CO_CODA: /* AK */ + case SUA_CO_COERR: /* ERR */ + /* DISCARD */ + break; + case SUA_CO_RELRE: /* RLSD */ + /* Send RLC */ + tx_relco_from_xua(inst, xua); + break; + default: + LOGP(DLSCCP, LOGL_NOTICE, "Unhandled %s\n", + xua_hdr_dump(xua, &xua_dialect_sua)); + break; + } +} + +/* process received message for invalid source local reference */ +static void sccp_scoc_rx_inval_src_ref(struct sccp_connection *conn, + struct xua_msg *xua) +{ + /* we have received a message with invalid source local + * reference and thus apply the action indicated in Table + * B.2/Q.714 */ + switch (xua->hdr.msg_type) { + case SUA_CO_RELRE: /* RLSD */ + case SUA_CO_RESRE: /* RSR */ + case SUA_CO_RESCO: /* RSC */ + /* Send ERR */ + tx_coerr_from_xua(conn->inst, xua, SCCP_ERROR_LRN_MISMATCH_INCONSISTENT); + break; + case SUA_CO_COIT: /* IT */ + /* FIXME: RLSD to both sides */ + tx_rlsd_from_xua_twoway(conn, xua); + break; + case SUA_CO_RELCO: /* RLC */ + /* DISCARD */ + break; + default: + LOGP(DLSCCP, LOGL_NOTICE, "Unhandled %s\n", + xua_hdr_dump(xua, &xua_dialect_sua)); + break; + } +} + +/* process received message for invalid origin point code */ +static void sccp_scoc_rx_inval_opc(struct osmo_sccp_instance *inst, + struct xua_msg *xua) +{ + /* we have received a message with invalid origin PC and thus + * apply the action indiacted in Table B.2/Q.714 */ + switch (xua->hdr.msg_type) { + case SUA_CO_RELRE: /* RLSD */ + case SUA_CO_RESRE: /* RSR */ + case SUA_CO_RESCO: /* RSC */ + /* Send ERR */ + tx_coerr_from_xua(inst, xua, SCCP_ERROR_POINT_CODE_MISMATCH); + break; + case SUA_CO_RELCO: /* RLC */ + case SUA_CO_CODT: /* DT1 */ + case SUA_CO_CODA: /* AK */ + case SUA_CO_COERR: /* ERR */ + /* DISCARD */ + break; + default: + LOGP(DLSCCP, LOGL_NOTICE, "Unhandled %s\n", + xua_hdr_dump(xua, &xua_dialect_sua)); + break; + } +} + +/*! \brief Main entrance function for primitives from the SCRC (Routing Control) + * \param[in] inst SCCP Instance in which we operate + * \param[in] xua SUA message in xua_msg format */ +void sccp_scoc_rx_from_scrc(struct osmo_sccp_instance *inst, + struct xua_msg *xua) +{ + struct sccp_connection *conn; + struct osmo_sccp_user *scu; + uint32_t src_loc_ref; + int event; + + /* we basically try to convert the SUA message into an event, + * and then dispatch the event to the connection-specific FSM. + * If it is a CORE (Connect REquest), we create the connection + * (and imlpicitly its FSM) first */ + + if (xua->hdr.msg_type == SUA_CO_CORE) { + scu = sccp_find_user(inst, xua); + if (!scu) { + /* this shouldn't happen, as the caller should + * have already verified that a local user is + * equipped for this SSN */ + LOGP(DLSCCP, LOGL_ERROR, "Cannot find user for " + "CORE ?!?\n"); + return; + } + /* Allocate new connection */ + conn = conn_create(inst); + conn->user = scu; + } else { + uint32_t conn_id; + /* Resolve existing connection */ + conn_id = xua_msg_get_u32(xua, SUA_IEI_DEST_REF); + conn = conn_find_by_id(inst, conn_id); + if (!conn) { + LOGP(DLSCCP, LOGL_NOTICE, "Cannot find connection for " + "local reference %u\n", conn_id); + sccp_scoc_rx_unass_local_ref(inst, xua); + return; + } + } + OSMO_ASSERT(conn); + OSMO_ASSERT(conn->fi); + + DEBUGP(DLSCCP, "Received %s for local reference %u\n", + xua_hdr_dump(xua, &xua_dialect_sua), conn->conn_id); + + if (xua->hdr.msg_type != SUA_CO_CORE && + xua->hdr.msg_type != SUA_CO_COAK && + xua->hdr.msg_type != SUA_CO_COREF) { + if (xua_msg_find_tag(xua, SUA_IEI_SRC_REF)) { + /* Check if received source local reference != + * the one we saved in local state */ + src_loc_ref = xua_msg_get_u32(xua, SUA_IEI_SRC_REF); + if (src_loc_ref != conn->remote_ref) { + sccp_scoc_rx_inval_src_ref(conn, xua); + return; + } + } + + /* Check if received OPC != the remote_pc we stored locally */ + if (xua->mtp.opc != conn->remote_pc) { + sccp_scoc_rx_inval_opc(inst, xua); + return; + } + } + + /* Map from XUA message to event */ + event = xua_msg_event_map(xua, sua_scoc_event_map, ARRAY_SIZE(sua_scoc_event_map)); + if (event < 0) { + LOGP(DLSCCP, LOGL_ERROR, "Cannot map SCRC msg %s to event\n", + xua_hdr_dump(xua, &xua_dialect_sua)); + /* Table B.1/Q714 states DISCARD for any message with + * unknown type */ + return; + } + + /* Dispatch event to existing connection */ + osmo_fsm_inst_dispatch(conn->fi, event, xua); +} + +/* get the Connection ID of the given SCU primitive */ +static uint32_t scu_prim_conn_id(const struct osmo_scu_prim *prim) +{ + switch (prim->oph.primitive) { + case OSMO_SCU_PRIM_N_CONNECT: + return prim->u.connect.conn_id; + case OSMO_SCU_PRIM_N_DATA: + return prim->u.data.conn_id; + case OSMO_SCU_PRIM_N_DISCONNECT: + return prim->u.disconnect.conn_id; + case OSMO_SCU_PRIM_N_RESET: + return prim->u.reset.conn_id; + default: + return 0; + } +} + +/*! \brief Main entrance function for primitives from SCCP User + * \param[in] scu SCCP User sending us the primitive + * \param[in] oph Osmocom primitive sent by the user + * \returns 0 on success; negative on error */ +int osmo_sccp_user_sap_down(struct osmo_sccp_user *scu, struct osmo_prim_hdr *oph) +{ + struct osmo_scu_prim *prim = (struct osmo_scu_prim *) oph; + struct osmo_sccp_instance *inst = scu->inst; + struct msgb *msg = prim->oph.msg; + struct sccp_connection *conn; + int rc = 0; + int event; + + LOGP(DLSCCP, LOGL_DEBUG, "Received SCCP User Primitive %s)\n", + osmo_scu_prim_name(&prim->oph)); + + switch (OSMO_PRIM_HDR(&prim->oph)) { + case OSMO_PRIM(OSMO_SCU_PRIM_N_UNITDATA, PRIM_OP_REQUEST): + /* other CL primitives? */ + /* Connectionless by-passes this altogether */ + return sccp_sclc_user_sap_down(scu, oph); + case OSMO_PRIM(OSMO_SCU_PRIM_N_CONNECT, PRIM_OP_REQUEST): + /* Allocate new connection structure */ + conn = conn_create_id(inst, prim->u.connect.conn_id); + if (!conn) { + /* FIXME: inform user */ + goto out; + } + conn->user = scu; + break; + case OSMO_PRIM(OSMO_SCU_PRIM_N_CONNECT, PRIM_OP_RESPONSE): + case OSMO_PRIM(OSMO_SCU_PRIM_N_DATA, PRIM_OP_REQUEST): + case OSMO_PRIM(OSMO_SCU_PRIM_N_DISCONNECT, PRIM_OP_REQUEST): + case OSMO_PRIM(OSMO_SCU_PRIM_N_RESET, PRIM_OP_REQUEST): + /* Resolve existing connection structure */ + conn = conn_find_by_id(inst, scu_prim_conn_id(prim)); + if (!conn) { + /* FIXME: inform user */ + goto out; + } + break; + } + + /* Map from primitive to event */ + event = osmo_event_for_prim(oph, scu_scoc_event_map); + + /* Dispatch event into connection */ + rc = osmo_fsm_inst_dispatch(conn->fi, event, prim); +out: + /* the SAP is supposed to consume the primitive/msgb */ + msgb_free(msg); + + return rc; +} + +void sccp_scoc_flush_connections(struct osmo_sccp_instance *inst) +{ + struct sccp_connection *conn, *conn2; + + llist_for_each_entry_safe(conn, conn2, &inst->connections, list) + conn_destroy(conn); +} diff --git a/src/sccp_scrc.c b/src/sccp_scrc.c new file mode 100644 index 0000000..11c52e8 --- /dev/null +++ b/src/sccp_scrc.c @@ -0,0 +1,473 @@ +/* SCCP Routing Control (SCRC) according to ITU-T Q.714 */ + +/* (C) 2015-2017 by Harald Welte + * All Rights reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include "sccp_internal.h" +#include "xua_internal.h" + +/*********************************************************************** + * Helper Functions + ***********************************************************************/ + +static bool sua_is_connectionless(struct xua_msg *xua) +{ + if (xua->hdr.msg_class == SUA_MSGC_CL) + return true; + else + return false; +} + +static bool sua_is_cr(struct xua_msg *xua) +{ + if (xua->hdr.msg_class == SUA_MSGC_CO && + xua->hdr.msg_type == SUA_CO_CORE) + return true; + + return false; +} + +static bool dpc_accessible(struct osmo_sccp_instance *inst, uint32_t pc) +{ + /* TODO: implement this! */ + return true; +} + +static bool sccp_available(struct osmo_sccp_instance *inst, + const struct osmo_sccp_addr *addr) +{ + /* TODO: implement this! */ + return true; +} + +static int sua2sccp_tx_m3ua(struct osmo_sccp_instance *inst, + struct xua_msg *sua) +{ + struct msgb *msg; + struct osmo_mtp_prim *omp; + struct osmo_mtp_transfer_param *param; + struct osmo_ss7_instance *s7i = inst->ss7; + uint32_t remote_pc = sua->mtp.dpc; + + /* 1) encode the SUA in xua_msg to SCCP message */ + msg = osmo_sua_to_sccp(sua); + if (!msg) { + LOGP(DLSCCP, LOGL_ERROR, "Cannot encode SUA to SCCP\n"); + return -1; + } + + /* 2) wrap into MTP-TRANSFER.req primtiive */ + msg->l2h = msg->data; + omp = (struct osmo_mtp_prim *) msgb_push(msg, sizeof(*omp)); + osmo_prim_init(&omp->oph, MTP_SAP_USER, + OSMO_MTP_PRIM_TRANSFER, PRIM_OP_REQUEST, msg); + param = &omp->u.transfer; + if (sua->mtp.opc) + param->opc = sua->mtp.opc; + else + param->opc = s7i->cfg.primary_pc; + param->dpc = remote_pc; + param->sls = sua->mtp.sls; + param->sio = MTP_SIO(MTP_SI_SCCP, s7i->cfg.network_indicator); + + /* 3) send via MTP-SAP (osmo_ss7_instance) */ + return osmo_ss7_user_mtp_xfer_req(s7i, omp); +} + +/* Gererate MTP-TRANSFER.req from xUA message */ +static int gen_mtp_transfer_req_xua(struct osmo_sccp_instance *inst, + struct xua_msg *xua, + const struct osmo_sccp_addr *called) +{ + struct osmo_ss7_route *rt; + + /* this is a bit fishy due to the different requirements of + * classic SSCP/MTP compared to various SIGTRAN stackings. + * Normally, we would expect a fully encoded SCCP message here, + * but then if the route points to a SUA link, we actually need + * the SUA version of the message. + * + * We need to differentiate the following cases: + * a) SUA: encode XUA to SUA and send via ASP + * b) M3UA: encode XUA to SCCP, create MTP-TRANSFER.req + * primitive and send it via ASP + * c) M2UA/M2PA or CS7: encode XUA, create MTP-TRANSFER.req + * primitive and send it via link + */ + + if (called->presence & OSMO_SCCP_ADDR_T_PC) + xua->mtp.dpc = called->pc; + if (!xua->mtp.dpc) { + LOGP(DLSCCP, LOGL_ERROR, "MTP-TRANSFER.req from SCCP " + "without DPC?!?\n"); + return -1; + } + + rt = osmo_ss7_route_lookup(inst->ss7, xua->mtp.dpc); + if (!rt) { + LOGP(DLSCCP, LOGL_ERROR, "MTP-TRANSFER.req from SCCP for " + "DPC %u: no route!\n", xua->mtp.dpc); + return -1; + } + + if (rt->dest.as) { + struct osmo_ss7_as *as = rt->dest.as; + switch (as->cfg.proto) { + case OSMO_SS7_ASP_PROT_M3UA: + return sua2sccp_tx_m3ua(inst, xua); + default: + LOGP(DLSCCP, LOGL_ERROR, "MTP-TRANSFER.req for " + "unknown protocol %u\n", as->cfg.proto); + break; + } + } else if (rt->dest.linkset) { + LOGP(DLSCCP, LOGL_ERROR, "MTP-TRANSFER.req from SCCP for " + "linkset %s unsupported\n", rt->dest.linkset->cfg.name); + } else { + OSMO_ASSERT(0); + } + return -1; +} + +/*********************************************************************** + * Global Title Translation + ***********************************************************************/ + +static int translate(struct osmo_sccp_instance *inst, + const struct osmo_sccp_addr *called, + struct osmo_sccp_addr *translated) +{ + /* TODO: implement this! */ + *translated = *called; + return 0; +} + + +/*********************************************************************** + * Individual SCRC Nodes + ***********************************************************************/ + +static int scrc_local_out_common(struct osmo_sccp_instance *inst, + struct xua_msg *xua, + const struct osmo_sccp_addr *called); + +static int scrc_node_12(struct osmo_sccp_instance *inst, struct xua_msg *xua, + const struct osmo_sccp_addr *called) +{ + /* TODO: Determine restriction */ + /* TODO: Treat Calling Party Addr */ + /* TODO: Hop counter */ + /* MTP-TRANSFER.req to MTP */ + return gen_mtp_transfer_req_xua(inst, xua, called); +} + +static int scrc_node_2(struct osmo_sccp_instance *inst, struct xua_msg *xua, + const struct osmo_sccp_addr *called) +{ + /* Node 2 on Sheet 5, only CO */ + /* Is DPC accessible? */ + if (!dpc_accessible(inst, called->pc)) { + /* Error: MTP Failure */ + /* Routing Failure SCRC -> SCOC */ + sccp_scoc_rx_scrc_rout_fail(inst, xua, + SCCP_RETURN_CAUSE_MTP_FAILURE); + return 0; + } + /* Is SCCP available? */ + if (!sccp_available(inst, called)) { + /* Error: SCCP Failure */ + /* Routing Failure SCRC -> SCOC */ + sccp_scoc_rx_scrc_rout_fail(inst, xua, + SCCP_RETURN_CAUSE_SCCP_FAILURE); + return 0; + } + return scrc_node_12(inst, xua, called); +} + +static int scrc_node_7(struct osmo_sccp_instance *inst, + struct xua_msg *xua, + const struct osmo_sccp_addr *called) +{ + /* Connection Oriented? */ + if (sua_is_connectionless(xua)) { + /* TODO: Perform Capability Test */ + /* TODO: Canges Needed? */ + if (0) { + /* Changes Needed -> SCLC */ + return 0; + } + } else { + /* TODO: Coupling Required? */ + if (0) { + /* Node 13 (Sheet 5) */ + } + } + return scrc_node_12(inst, xua, called); +} + +/* Node 4 (Sheet 3) */ +static int scrc_node_4(struct osmo_sccp_instance *inst, + struct xua_msg *xua, uint32_t return_cause) +{ + /* TODO: Routing Failure SCRC -> OMAP */ + if (sua_is_connectionless(xua)) { + /* Routing Failure SCRC -> SCLC */ + sccp_sclc_rx_scrc_rout_fail(inst, xua, return_cause); + } else { + /* Routing Failure SCRC -> SCOC */ + sccp_scoc_rx_scrc_rout_fail(inst, xua, return_cause); + } + return 0; +} + +static int scrc_translate_node_9(struct osmo_sccp_instance *inst, + struct xua_msg *xua, + const struct osmo_sccp_addr *called) +{ + struct osmo_sccp_addr translated; + int rc; + + /* Translate */ + rc = translate(inst, called, &translated); + /* Node 9 (Sheet 3) */ + if (rc < 0) { + /* Node 4 (Sheet 3) */ + return scrc_node_4(inst, xua, + SCCP_RETURN_CAUSE_NO_TRANSLATION); + } + /* Route on SSN? */ + if (translated.ri != OSMO_SCCP_RI_SSN_PC && + translated.ri != OSMO_SCCP_RI_SSN_IP) { + /* TODO: GT Routing */ + /* Node 7 (Sheet 5) */ + return scrc_node_7(inst, xua, called); + } + + /* Check DPC resultant from GT translation */ + if (osmo_ss7_pc_is_local(inst->ss7, translated.pc)) { + if (sua_is_connectionless(xua)) { + /* CL_MSG -> SCLC */ + sccp_sclc_rx_from_scrc(inst, xua); + } else { + /* Node 1 (Sheet 3) */ + /* CO_MSG -> SCOC */ + sccp_scoc_rx_from_scrc(inst, xua); + } + return 0; + } else { + /* Availability already checked */ + /* Node 7 (Sheet 5) */ + return scrc_node_7(inst, xua, called); + } +} + +/* Node 6 (Sheet 3) */ +static int scrc_node_6(struct osmo_sccp_instance *inst, + struct xua_msg *xua, + const struct osmo_sccp_addr *called) +{ + struct osmo_sccp_user *scu; + + scu = sccp_user_find(inst, called->ssn, called->pc); + + /* Is subsystem equipped? */ + if (!scu) { + /* Error: unequipped user */ + return scrc_node_4(inst, xua, + SCCP_RETURN_CAUSE_UNEQUIPPED_USER); + } + /* Is subsystem available? */ + if (0 /* !subsys_available(scu) */) { + /* Error: subsystem failure */ + /* TODO: SCRC -> SSPC */ + if (sua_is_connectionless(xua)) { + /* Routing Failure SCRC -> SCLC */ + sccp_sclc_rx_scrc_rout_fail(inst, xua, + SCCP_RETURN_CAUSE_SUBSYSTEM_FAILURE); + } else { + /* Routing Failure SCRC -> SCOC */ + sccp_scoc_rx_scrc_rout_fail(inst, xua, + SCCP_RETURN_CAUSE_SUBSYSTEM_FAILURE); + } + return 0; + } + if (sua_is_connectionless(xua)) { + /* CL_MSG -> SCLC */ + sccp_sclc_rx_from_scrc(inst, xua); + } else { + /* Node 1 (Sheet 3) */ + /* CO_MSG -> SCOC */ + sccp_scoc_rx_from_scrc(inst, xua); + } + return 0; +} + +static int scrc_local_out_common(struct osmo_sccp_instance *inst, + struct xua_msg *xua, + const struct osmo_sccp_addr *called) +{ + struct osmo_ss7_instance *s7i = inst->ss7; + + /* Called address includes DPC? */ + if (called->presence & OSMO_SCCP_ADDR_T_PC) { + if (!osmo_ss7_pc_is_local(s7i, called->pc)) { + /* Node 7 of sheet 5 */ + /* Coupling required: no */ + return scrc_node_12(inst, xua, called); + } + /* Called address includes SSN? */ + if (called->presence & OSMO_SCCP_ADDR_T_SSN) { + if (translate && + (called->presence & OSMO_SCCP_ADDR_T_GT)) + return scrc_translate_node_9(inst, xua, called); + else + return scrc_node_6(inst, xua, called); + } + } + /* No SSN in CalledAddr or no DPC included */ + if (!(called->presence & OSMO_SCCP_ADDR_T_GT)) { + /* Error reason: Unqualified */ + /* TODO: Routing Failure SCRC -> OMAP */ + /* Node 4 (Sheet 3) */ + return scrc_node_4(inst, xua, + SCCP_RETURN_CAUSE_UNQUALIFIED); + } else + return scrc_translate_node_9(inst, xua, called); +} + +/*********************************************************************** + * Entrance points from MTP, SCLC, SCOC, ... + ***********************************************************************/ + +/* Figure C.1/Q.714 - SCCP Routing control procedures (SCRC) */ + +/* Connection oriented message SCOC -> SCRC */ +int sccp_scrc_rx_scoc_conn_msg(struct osmo_sccp_instance *inst, + struct xua_msg *xua) +{ + struct osmo_sccp_addr called; + + LOGP(DLSS7, LOGL_DEBUG, "%s: %s\n", __func__, xua_msg_dump(xua, &xua_dialect_sua)); + + sua_addr_parse(&called, xua, SUA_IEI_DEST_ADDR); + + /* Is this a CR message ? */ + if (xua->hdr.msg_type != SUA_CO_CORE) + return scrc_node_2(inst, xua, &called); + + /* TOOD: Coupling performed (not supported) */ + if (0) + return scrc_node_2(inst, xua, &called); + + return scrc_local_out_common(inst, xua, &called); +} + +/* Connectionless Message SCLC -> SCRC */ +int sccp_scrc_rx_sclc_msg(struct osmo_sccp_instance *inst, + struct xua_msg *xua) +{ + struct osmo_sccp_addr called; + + LOGP(DLSS7, LOGL_DEBUG, "%s: %s\n", __func__, xua_msg_dump(xua, &xua_dialect_sua)); + + sua_addr_parse(&called, xua, SUA_IEI_DEST_ADDR); + + /* Message Type */ + if (xua->hdr.msg_type == SUA_CL_CLDR) { + /* UDTS, XUDTS or LUDTS */ + if (called.ri != OSMO_SCCP_RI_GT) + return scrc_node_7(inst, xua, &called); + /* Fall-through */ + } else { + if (0 /* TODO: translation already performed */) { + /* Node 12 (Sheet 5) */ + return scrc_node_12(inst, xua, &called); + } + } + return scrc_local_out_common(inst, xua, &called); +} + +/* Figure C.1/Q.714 Sheet 1 of 12, after we converted the + * MTP-TRANSFER.ind to SUA */ +int scrc_rx_mtp_xfer_ind_xua(struct osmo_sccp_instance *inst, + struct xua_msg *xua) +{ + struct osmo_sccp_addr called; + uint32_t proto_class; + struct xua_msg_part *hop_ctr_part; + + LOGP(DLSS7, LOGL_DEBUG, "%s: %s\n", __func__, xua_msg_dump(xua, &xua_dialect_sua)); + /* TODO: SCCP or nodal congestion? */ + + /* CR or CL message? */ + if (!sua_is_connectionless(xua) && !sua_is_cr(xua)) { + /* Node 1 (Sheet 3) */ + /* deliver to SCOC */ + sccp_scoc_rx_from_scrc(inst, xua); + return 0; + } + /* We only treat connectionless and CR below */ + + sua_addr_parse(&called, xua, SUA_IEI_DEST_ADDR); + + /* Route on GT? */ + if (called.ri != OSMO_SCCP_RI_GT) { + /* Node 6 (Sheet 3) */ + return scrc_node_6(inst, xua, &called); + } + /* Message with hop-counter? */ + hop_ctr_part = xua_msg_find_tag(xua, SUA_IEI_S7_HOP_CTR); + if (hop_ctr_part) { + uint32_t hop_counter = xua_msg_part_get_u32(hop_ctr_part); + if (hop_counter <= 1) { + /* Error: hop-counter violation */ + /* node 4 */ + return scrc_node_4(inst, xua, + SCCP_RETURN_CAUSE_HOP_COUNTER_VIOLATION); + } + /* Decrement hop-counter */ + hop_counter--; + *(uint32_t *)hop_ctr_part->dat = htonl(hop_counter); + } + + /* node 3 (Sheet 2) */ + /* Protocol class 0? */ + proto_class = xua_msg_get_u32(xua, SUA_IEI_PROTO_CLASS); + switch (proto_class) { + case 0: + /* TODO: Assign SLS */ + break; + case 1: + /* TODO: Map incoming SLS to outgoing SLS */ + break; + default: + break; + } + return scrc_translate_node_9(inst, xua, &called); +} diff --git a/src/sccp_user.c b/src/sccp_user.c new file mode 100644 index 0000000..df02486 --- /dev/null +++ b/src/sccp_user.c @@ -0,0 +1,377 @@ +/* SCCP User related routines */ + +/* (C) 2017 by Harald Welte + * All Rights Reserved + * + * based on my 2011 Erlang implementation osmo_ss7/src/sua_sccp_conv.erl + * + * References: ITU-T Q.713 and IETF RFC 3868 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include + +#include +#include + +#include +#include +#include +#include + +#include "sccp_internal.h" +#include "xua_internal.h" + +/*! \brief Find a SCCP User registered for given PC+SSN or SSN only + * \param[in] inst SCCP Instance in which to search + * \param[in] ssn Sub-System Number to search for + * \param[in] pc Point Code to search for + * \returns Matching SCCP User; NULL if none found */ +struct osmo_sccp_user * +sccp_user_find(struct osmo_sccp_instance *inst, uint16_t ssn, uint32_t pc) +{ + struct osmo_sccp_user *scu; + + /* First try to find match for PC + SSN */ + llist_for_each_entry(scu, &inst->users, list) { + if (scu->pc_valid && scu->pc == pc && scu->ssn == ssn) + return scu; + } + + /* Then try to match on SSN only */ + llist_for_each_entry(scu, &inst->users, list) { + if (!scu->pc_valid && scu->ssn == ssn) + return scu; + } + + return NULL; +} + +/*! \brief Bind a SCCP User to a given Point Code + * \param[in] inst SCCP Instance + * \param[in] name human-readable name + * \param[in] ssn Sub-System Number to bind to + * \param[in] pc Point Code to bind to (if any) + * \param[in] pc_valid Whether or not \ref pc is valid/used + * \returns Callee-allocated SCCP User on success; negative otherwise */ +static struct osmo_sccp_user * +sccp_user_bind_pc(struct osmo_sccp_instance *inst, const char *name, + osmo_prim_cb prim_cb, uint16_t ssn, uint32_t pc, bool pc_valid) +{ + struct osmo_sccp_user *scu; + if (!pc_valid) + pc = 0; + + if (sccp_user_find(inst, ssn, pc)) + return NULL; + + LOGP(DLSCCP, LOGL_INFO, "Binding user '%s' to SSN=%u PC=%u (pc_valid=%u)\n", + name, ssn, pc, pc_valid); + + scu = talloc_zero(inst, struct osmo_sccp_user); + scu->name = talloc_strdup(scu, name); + scu->inst = inst; + scu->prim_cb = prim_cb; + scu->ssn = ssn; + scu->pc = pc; + scu->pc_valid = pc_valid; + llist_add_tail(&scu->list, &inst->users); + + return scu; +} + +/*! \brief Bind a given SCCP User to a given SSN+PC + * \param[in] inst SCCP Instance + * \param[in] name human-readable name + * \param[in] ssn Sub-System Number to bind to + * \param[in] pc Point Code to bind to (if any) + * \returns Callee-allocated SCCP User on success; negative otherwise */ +struct osmo_sccp_user * +osmo_sccp_user_bind_pc(struct osmo_sccp_instance *inst, const char *name, + osmo_prim_cb prim_cb, uint16_t ssn, uint32_t pc) +{ + return sccp_user_bind_pc(inst, name, prim_cb, ssn, pc, true); +} + +/*! \brief Bind a given SCCP User to a given SSN (at any PC) + * \param[in] inst SCCP Instance + * \param[in] name human-readable name + * \param[in] ssn Sub-System Number to bind to + * \returns Callee-allocated SCCP User on success; negative otherwise */ +struct osmo_sccp_user * +osmo_sccp_user_bind(struct osmo_sccp_instance *inst, const char *name, + osmo_prim_cb prim_cb, uint16_t ssn) +{ + return sccp_user_bind_pc(inst, name, prim_cb, ssn, 0, false); +} + +/*! \brief Unbind a given SCCP user + * \param[in] scu SCCP User which is to be un-bound. Will be destroyed + * at the time this function returns. */ +void osmo_sccp_user_unbind(struct osmo_sccp_user *scu) +{ + LOGP(DLSCCP, LOGL_INFO, "Unbinding user '%s' from SSN=%u PC=%u " + "(pc_valid=%u)\n", scu->name, scu->ssn, scu->pc, + scu->pc_valid); + /* FIXME: free/release all connections held by this user? */ + llist_del(&scu->list); + talloc_free(scu); +} + +/*! \brief Send a SCCP User SAP Primitive up to the User + * \param[in] scu SCCP User to whom to send the primitive + * \param[in] prim Primitive to send to the user + * \returns return value of the SCCP User's prim_cb() function */ +int sccp_user_prim_up(struct osmo_sccp_user *scu, struct osmo_scu_prim *prim) +{ + LOGP(DLSCCP, LOGL_DEBUG, "Delivering %s to SCCP User '%s'\n", + osmo_scu_prim_name(&prim->oph), scu->name); + return scu->prim_cb(&prim->oph, scu); +} + +/* prim_cb handed to MTP code for incoming MTP-TRANSFER.ind */ +static int mtp_user_prim_cb(struct osmo_prim_hdr *oph, void *ctx) +{ + struct osmo_sccp_instance *inst = ctx; + struct osmo_mtp_prim *omp = (struct osmo_mtp_prim *)oph; + struct xua_msg *xua; + + OSMO_ASSERT(oph->sap == MTP_SAP_USER); + + switch OSMO_PRIM(oph->primitive, oph->operation) { + case OSMO_PRIM(OSMO_MTP_PRIM_TRANSFER, PRIM_OP_INDICATION): + /* Convert from SCCP to SUA in xua_msg format */ + xua = osmo_sccp_to_xua(oph->msg); + xua->mtp = omp->u.transfer; + /* hand this primitive into SCCP via the SCRC code */ + return scrc_rx_mtp_xfer_ind_xua(inst, xua); + default: + LOGP(DLSCCP, LOGL_ERROR, "Unknown primitive %u:%u receivd\n", + oph->primitive, oph->operation); + return -1; + } +} + +static LLIST_HEAD(sccp_instances); + +/*! \brief create a SCCP Instance and register it as user with SS7 inst + * \param[in] ss7 SS7 instance to which this SCCP instance belongs + * \param[in] priv private data to be stored within SCCP instance + * \returns callee-allocated SCCP instance on success; NULL on error */ +struct osmo_sccp_instance * +osmo_sccp_instance_create(struct osmo_ss7_instance *ss7, void *priv) +{ + struct osmo_sccp_instance *inst; + + inst = talloc_zero(ss7, struct osmo_sccp_instance); + if (!inst) + return NULL; + + inst->ss7 = ss7; + inst->priv = priv; + INIT_LLIST_HEAD(&inst->connections); + INIT_LLIST_HEAD(&inst->users); + + inst->ss7_user.inst = ss7; + inst->ss7_user.name = "SCCP"; + inst->ss7_user.prim_cb = mtp_user_prim_cb; + inst->ss7_user.priv = inst; + + osmo_ss7_user_register(ss7, MTP_SI_SCCP, &inst->ss7_user); + + llist_add_tail(&inst->list, &sccp_instances); + + return inst; +} + +void osmo_sccp_instance_destroy(struct osmo_sccp_instance *inst) +{ + struct osmo_sccp_user *scu, *scu2; + + inst->ss7->sccp = NULL; + osmo_ss7_user_unregister(inst->ss7, MTP_SI_SCCP, &inst->ss7_user); + + llist_for_each_entry_safe(scu, scu2, &inst->users, list) { + osmo_sccp_user_unbind(scu); + } + sccp_scoc_flush_connections(inst); + llist_del(&inst->list); + talloc_free(inst); +} + +/*********************************************************************** + * Convenience function for CLIENT + ***********************************************************************/ + +struct osmo_sccp_instance * +osmo_sccp_simple_client(void *ctx, const char *name, uint32_t pc, + enum osmo_ss7_asp_protocol prot, + int local_port, int remote_port, const char *remote_ip) +{ + struct osmo_ss7_instance *ss7; + struct osmo_ss7_as *as; + struct osmo_ss7_route *rt; + struct osmo_ss7_asp *asp; + char *as_name, *asp_name; + + if (!remote_port || remote_port < 0) + remote_port = osmo_ss7_asp_protocol_port(prot); + if (local_port < 0) + local_port = osmo_ss7_asp_protocol_port(prot); + + /* allocate + initialize SS7 instance */ + ss7 = osmo_ss7_instance_find_or_create(ctx, 1); + if (!ss7) + return NULL; + ss7->cfg.primary_pc = pc; + + as_name = talloc_asprintf(ctx, "as-clnt-%s", name); + asp_name = talloc_asprintf(ctx, "asp-clnt-%s", name); + + /* application server */ + as = osmo_ss7_as_find_or_create(ss7, as_name, prot); + if (!as) + goto out_strings; + + /* install default route */ + rt = osmo_ss7_route_create(ss7->rtable_system, 0, 0, as_name); + if (!rt) + goto out_as; + talloc_free(as_name); + + /* application server process */ + asp = osmo_ss7_asp_find_or_create(ss7, asp_name, remote_port, local_port, + prot); + if (!asp) + goto out_rt; + asp->cfg.remote.host = talloc_strdup(asp, remote_ip); + osmo_ss7_as_add_asp(as, asp_name); + talloc_free(asp_name); + osmo_ss7_asp_restart(asp); + + /* Allocate SCCP stack + SCCP user */ + ss7->sccp = osmo_sccp_instance_create(ss7, NULL); + if (!ss7->sccp) + goto out_asp; + + return ss7->sccp; + +out_asp: + osmo_ss7_asp_destroy(asp); +out_rt: + osmo_ss7_route_destroy(rt); +out_as: + osmo_ss7_as_destroy(as); +out_strings: + talloc_free(as_name); + talloc_free(asp_name); + osmo_ss7_instance_destroy(ss7); + + return NULL; +} + +/*********************************************************************** + * Convenience function for SERVER + ***********************************************************************/ + +struct osmo_sccp_instance * +osmo_sccp_simple_server(void *ctx, uint32_t pc, + enum osmo_ss7_asp_protocol prot, int local_port, + const char *local_ip) +{ + struct osmo_ss7_instance *ss7; + struct osmo_xua_server *xs; + + if (local_port < 0) + local_port = osmo_ss7_asp_protocol_port(prot); + + /* allocate + initialize SS7 instance */ + ss7 = osmo_ss7_instance_find_or_create(ctx, 1); + if (!ss7) + return NULL; + ss7->cfg.primary_pc = pc; + + xs = osmo_ss7_xua_server_create(ss7, prot, local_port, local_ip); + if (!xs) + goto out_ss7; + + /* Allocate SCCP stack */ + ss7->sccp = osmo_sccp_instance_create(ss7, NULL); + if (!ss7->sccp) + goto out_xs; + + return ss7->sccp; + +out_xs: + osmo_ss7_xua_server_destroy(xs); +out_ss7: + osmo_ss7_instance_destroy(ss7); + + return NULL; +} + +struct osmo_sccp_instance * +osmo_sccp_simple_server_add_clnt(struct osmo_sccp_instance *inst, + enum osmo_ss7_asp_protocol prot, + const char *name, uint32_t pc, + int local_port, int remote_port, + const char *remote_ip) +{ + struct osmo_ss7_instance *ss7 = inst->ss7; + struct osmo_ss7_as *as; + struct osmo_ss7_route *rt; + struct osmo_ss7_asp *asp; + char *as_name, *asp_name; + + if (local_port < 0) + local_port = osmo_ss7_asp_protocol_port(prot); + + if (remote_port < 0) + remote_port = osmo_ss7_asp_protocol_port(prot); + + as_name = talloc_asprintf(ss7, "as-srv-%s", name); + asp_name = talloc_asprintf(ss7, "asp-srv-%s", name); + + /* application server */ + as = osmo_ss7_as_find_or_create(ss7, as_name, prot); + if (!as) + goto out_strings; + talloc_free(as_name); + + /* route only selected PC to the client */ + rt = osmo_ss7_route_create(ss7->rtable_system, pc, 0xffff, as_name); + if (!rt) + goto out_as; + + asp = osmo_ss7_asp_find_or_create(ss7, asp_name, remote_port, local_port, prot); + if (!asp) + goto out_rt; + asp->cfg.is_server = true; + osmo_ss7_as_add_asp(as, asp_name); + talloc_free(asp_name); + osmo_ss7_asp_restart(asp); + + return ss7->sccp; + +out_rt: + osmo_ss7_route_destroy(rt); +out_as: + osmo_ss7_as_destroy(as); +out_strings: + talloc_free(as_name); + talloc_free(asp_name); + + return NULL; +} -- To view, visit https://gerrit.osmocom.org/2215 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I916e895d9a4914b05483fe12ab5251f206d10dee Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Mon Apr 3 20:22:10 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 3 Apr 2017 20:22:10 +0000 Subject: [PATCH] libosmo-sccp[master]: remove tests/sigtran: it's not a test case Message-ID: Review at https://gerrit.osmocom.org/2216 remove tests/sigtran: it's not a test case in tests/* we have unit tests that are run as part of the autotest suite during 'make check'. The code in tests/sigtran is an example, but not a test. As the API is changing anyway, let's remove it for now and re-introduce actual tests and examples after the changes in API required by the upcoming new SCCP core. Change-Id: Ie471a197856c875eb4987bf9858d757312de24fb --- M configure.ac M tests/Makefile.am D tests/sigtran/Makefile.am D tests/sigtran/sua_client_test.c D tests/sigtran/sua_server_test.c D tests/sigtran/sua_test_common.c D tests/sigtran/sua_test_common.h 7 files changed, 1 insertion(+), 266 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/16/2216/1 diff --git a/configure.ac b/configure.ac index 09e7adb..c7c2b3b 100644 --- a/configure.ac +++ b/configure.ac @@ -55,7 +55,6 @@ tests/sccp/Makefile tests/mtp/Makefile tests/m2ua/Makefile - tests/sigtran/Makefile tests/xua/Makefile tests/ss7/Makefile Makefile) diff --git a/tests/Makefile.am b/tests/Makefile.am index 6d3c96f..70e8a00 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,4 +1,4 @@ -SUBDIRS = xua sccp mtp m2ua sigtran ss7 +SUBDIRS = xua sccp mtp m2ua ss7 # The `:;' works around a Bash 3.2 bug when the output is not writeable. $(srcdir)/package.m4: $(top_srcdir)/configure.ac diff --git a/tests/sigtran/Makefile.am b/tests/sigtran/Makefile.am deleted file mode 100644 index 91c0960..0000000 --- a/tests/sigtran/Makefile.am +++ /dev/null @@ -1,11 +0,0 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir) -AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) - -noinst_HEADERS = sua_test_common.h -noinst_PROGRAMS = sua_server_test sua_client_test - -sua_server_test_SOURCES = sua_server_test.c sua_test_common.c -sua_server_test_LDADD = $(top_builddir)/src/libosmo-sigtran.la $(LIBOSMOCORE_LIBS) $(TALLOC_LIBS) - -sua_client_test_SOURCES = sua_client_test.c sua_test_common.c -sua_client_test_LDADD = $(top_builddir)/src/libosmo-sigtran.la $(LIBOSMOCORE_LIBS) $(TALLOC_LIBS) diff --git a/tests/sigtran/sua_client_test.c b/tests/sigtran/sua_client_test.c deleted file mode 100644 index 3cbd937..0000000 --- a/tests/sigtran/sua_client_test.c +++ /dev/null @@ -1,56 +0,0 @@ -#include "sua_test_common.h" - -struct osmo_sccp_user *g_user; -struct osmo_sccp_link *g_link; - -static int sccp_sap_up(struct osmo_prim_hdr *oph, void *link) -{ - struct osmo_scu_prim *prim = (struct osmo_scu_prim *) oph; - struct osmo_prim_hdr *resp = NULL; - uint8_t payload[] = { 0xa1, 0xa2, 0xa3 }; - - printf("sccp_sap_up(%s)\n", osmo_scu_prim_name(oph)); - - switch (OSMO_PRIM_HDR(oph)) { - case OSMO_PRIM(OSMO_SCU_PRIM_N_CONNECT, PRIM_OP_CONFIRM): - printf("N-CONNECT.ind(%u), issuing DATA.req\n", - prim->u.connect.conn_id); - resp = make_dt1_req(prim->u.connect.conn_id, payload, sizeof(payload)); - break; - } - - if (resp) - osmo_sua_user_link_down(link, resp); - - msgb_free(oph->msg); - return 0; -} - - -int main(int argc, char **argv) -{ - void *ctx = talloc_named_const(NULL, 1, "root"); - int rc; - - osmo_sua_set_log_area(DSUA); - - osmo_init_logging(&test_log_info); - - g_user = osmo_sua_user_create(ctx, sccp_sap_up, NULL); - - rc = osmo_sua_client_connect(g_user, "127.0.0.1", 2342); - if (rc < 0) { - exit(1); - } - - g_link = osmo_sua_client_get_link(g_user); - - int i = 8000; - - while (1) { - if (i < 8010) - tx_conn_req(g_link, i++); - //tx_unitdata(g_link); - osmo_select_main(0); - } -} diff --git a/tests/sigtran/sua_server_test.c b/tests/sigtran/sua_server_test.c deleted file mode 100644 index 97b2baf..0000000 --- a/tests/sigtran/sua_server_test.c +++ /dev/null @@ -1,78 +0,0 @@ -#include "sua_test_common.h" - -struct osmo_prim_hdr *make_conn_resp(struct osmo_scu_connect_param *param) -{ - struct msgb *msg = msgb_alloc(1024, "conn_resp"); - struct osmo_scu_prim *prim; - - prim = (struct osmo_scu_prim *) msgb_put(msg, sizeof(*prim)); - osmo_prim_init(&prim->oph, SCCP_SAP_USER, - OSMO_SCU_PRIM_N_CONNECT, - PRIM_OP_RESPONSE, msg); - memcpy(&prim->u.connect, param, sizeof(prim->u.connect)); - return &prim->oph; -} - -static int sccp_sap_up(struct osmo_prim_hdr *oph, void *link) -{ - struct osmo_scu_prim *prim = (struct osmo_scu_prim *) oph; - struct osmo_prim_hdr *resp = NULL; - const uint8_t payload[] = { 0xb1, 0xb2, 0xb3 }; - - printf("sccp_sap_up(%s)\n", osmo_scu_prim_name(oph)); - - switch (OSMO_PRIM_HDR(oph)) { - case OSMO_PRIM(OSMO_SCU_PRIM_N_CONNECT, PRIM_OP_CONFIRM): - /* confirmation of outbound connection */ - break; - case OSMO_PRIM(OSMO_SCU_PRIM_N_CONNECT, PRIM_OP_INDICATION): - /* indication of new inbound connection request*/ - printf("N-CONNECT.ind(X->%u)\n", prim->u.connect.conn_id); - resp = make_conn_resp(&prim->u.connect); - break; - case OSMO_PRIM(OSMO_SCU_PRIM_N_DISCONNECT, PRIM_OP_INDICATION): - /* indication of disconnect */ - printf("N-DISCONNECT.ind(%u)\n", prim->u.disconnect.conn_id); - break; - case OSMO_PRIM(OSMO_SCU_PRIM_N_DATA, PRIM_OP_INDICATION): - /* connection-oriented data received */ - printf("N-DATA.ind(%u, %s)\n", prim->u.data.conn_id, - osmo_hexdump(msgb_l2(oph->msg), msgb_l2len(oph->msg))); - resp = make_dt1_req(prim->u.data.conn_id, payload, sizeof(payload)); - break; - case OSMO_PRIM(OSMO_SCU_PRIM_N_UNITDATA, PRIM_OP_INDICATION): - /* connection-oriented data received */ - printf("N-UNITDATA.ind(%s)\n", - osmo_hexdump(msgb_l2(oph->msg), msgb_l2len(oph->msg))); - tx_unitdata(link); - break; - } - - if (resp) - osmo_sua_user_link_down(link, resp); - - msgb_free(oph->msg); - return 0; -} - -int main(int argc, char **argv) -{ - struct osmo_sccp_user *user; - void *ctx = talloc_named_const(NULL, 1, "root"); - int rc; - - osmo_sua_set_log_area(DSUA); - - osmo_init_logging(&test_log_info); - - user = osmo_sua_user_create(ctx, sccp_sap_up, NULL); - - rc = osmo_sua_server_listen(user, "127.0.0.1", 2342); - if (rc < 0) { - exit(1); - } - - while (1) { - osmo_select_main(0); - } -} diff --git a/tests/sigtran/sua_test_common.c b/tests/sigtran/sua_test_common.c deleted file mode 100644 index db1f5f3..0000000 --- a/tests/sigtran/sua_test_common.c +++ /dev/null @@ -1,87 +0,0 @@ -#include "sua_test_common.h" - -static const struct log_info_cat log_cat[] = { - [DMAIN] = { - .name = "DMAIN", .loglevel = LOGL_DEBUG, .enabled = 1, - .color = "", - .description = "Main program", - }, - [DSUA] = { - .name = "DSUA", .loglevel = LOGL_DEBUG, .enabled = 1, - .color = "", - .description = "SCCP User Adaption", - }, -}; - -const struct log_info test_log_info = { - .cat = log_cat, - .num_cat = ARRAY_SIZE(log_cat), -}; - -int tx_unitdata(struct osmo_sccp_link *link) -{ - struct msgb *msg = msgb_alloc(1024, "tx_unitdata"); - struct osmo_scu_prim *prim; - struct osmo_scu_unitdata_param *param; - uint8_t *cur; - - prim = (struct osmo_scu_prim *) msgb_put(msg, sizeof(*prim)); - param = &prim->u.unitdata; - param->calling_addr.presence = OSMO_SCCP_ADDR_T_SSN; - param->called_addr.presence = OSMO_SCCP_ADDR_T_SSN; - osmo_prim_init(&prim->oph, SCCP_SAP_USER, OSMO_SCU_PRIM_N_UNITDATA, PRIM_OP_REQUEST, msg); - - cur = msg->l2h = msgb_put(msg, 3); - cur[0] = 1; cur[1] = 2; cur[2] = 3; - - return osmo_sua_user_link_down(link, &prim->oph); -} - -static void sccp_make_addr_pc_ssn(struct osmo_sccp_addr *addr, uint32_t pc, uint32_t ssn) -{ - addr->presence = OSMO_SCCP_ADDR_T_SSN | OSMO_SCCP_ADDR_T_PC; - addr->ssn = ssn; - addr->pc = pc; -} - -struct osmo_prim_hdr *make_conn_req(uint32_t conn_id) -{ - struct msgb *msg = msgb_alloc(1024, "conn_req"); - struct osmo_scu_prim *prim; - - prim = (struct osmo_scu_prim *) msgb_put(msg, sizeof(*prim)); - osmo_prim_init(&prim->oph, SCCP_SAP_USER, - OSMO_SCU_PRIM_N_CONNECT, - PRIM_OP_REQUEST, msg); - /* Set SSN for calling and called addr */ - sccp_make_addr_pc_ssn(&prim->u.connect.called_addr, 2, OSMO_SCCP_SSN_RANAP); - sccp_make_addr_pc_ssn(&prim->u.connect.calling_addr, 1, OSMO_SCCP_SSN_RANAP); - prim->u.connect.sccp_class = 2; - prim->u.connect.conn_id = conn_id; - - return &prim->oph; -} - -int tx_conn_req(struct osmo_sccp_link *link, uint32_t conn_id) -{ - struct osmo_prim_hdr *prim = make_conn_req(conn_id); - return osmo_sua_user_link_down(link, prim); -} - -struct osmo_prim_hdr * -make_dt1_req(uint32_t conn_id, const uint8_t *data, unsigned int len) -{ - struct msgb *msg = msgb_alloc(1024, "dt1"); - struct osmo_scu_prim *prim; - - prim = (struct osmo_scu_prim *) msgb_put(msg, sizeof(*prim)); - osmo_prim_init(&prim->oph, SCCP_SAP_USER, - OSMO_SCU_PRIM_N_DATA, - PRIM_OP_REQUEST, msg); - prim->u.data.conn_id = conn_id; - - msg->l2h = msgb_put(msg, len); - memcpy(msg->l2h, data, len); - - return &prim->oph; -} diff --git a/tests/sigtran/sua_test_common.h b/tests/sigtran/sua_test_common.h deleted file mode 100644 index b1883cd..0000000 --- a/tests/sigtran/sua_test_common.h +++ /dev/null @@ -1,32 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include - - -enum log_cat { - DMAIN, - DSUA, - DXUA, -}; - -extern const struct log_info test_log_info; - -int tx_unitdata(struct osmo_sccp_link *link); -int tx_conn_req(struct osmo_sccp_link *link, uint32_t conn_id); - -struct osmo_prim_hdr *make_conn_req(uint32_t conn_id); -struct osmo_prim_hdr *make_dt1_req(uint32_t conn_id, const uint8_t *data, unsigned int len); -- To view, visit https://gerrit.osmocom.org/2216 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ie471a197856c875eb4987bf9858d757312de24fb Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Mon Apr 3 20:22:10 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 3 Apr 2017 20:22:10 +0000 Subject: [PATCH] libosmo-sccp[master]: sccp_sap license header was missing Message-ID: Review at https://gerrit.osmocom.org/2217 sccp_sap license header was missing Change-Id: I442634ca74d9c4cd386726a9d6b933a12f45afc5 --- M src/sccp_sap.c 1 file changed, 19 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/17/2217/1 diff --git a/src/sccp_sap.c b/src/sccp_sap.c index 51598b0..2211f71 100644 --- a/src/sccp_sap.c +++ b/src/sccp_sap.c @@ -1,3 +1,22 @@ +/* SCCP User SAP related routines */ + +/* (C) 2017 by Harald Welte + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + #include #include #include -- To view, visit https://gerrit.osmocom.org/2217 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I442634ca74d9c4cd386726a9d6b933a12f45afc5 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Mon Apr 3 20:22:11 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 3 Apr 2017 20:22:11 +0000 Subject: [PATCH] libosmo-sccp[master]: SUA: Port to new osmo_ss7 and SCCP code Message-ID: Review at https://gerrit.osmocom.org/2218 SUA: Port to new osmo_ss7 and SCCP code If we use the infrastructure provided by osmo_ss7 on the lower layer and the SCCP SCRC, SCLC and SCOC code on the upper side, not much of the original sua.c code remains. It looks much like the M3UA code now. Change-Id: I193b74f58aa70c443ae17e78b5604246d6bc3f71 --- M include/osmocom/sigtran/Makefile.am M include/osmocom/sigtran/sccp_helpers.h D include/osmocom/sigtran/sua.h M src/osmo_ss7.c M src/sccp_helpers.c M src/sccp_scrc.c M src/sua.c M src/xua_internal.h 8 files changed, 364 insertions(+), 1,294 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/18/2218/1 diff --git a/include/osmocom/sigtran/Makefile.am b/include/osmocom/sigtran/Makefile.am index ca7a304..0aa90cb 100644 --- a/include/osmocom/sigtran/Makefile.am +++ b/include/osmocom/sigtran/Makefile.am @@ -1,5 +1,5 @@ sigtran_HEADERS = xua_types.h xua_msg.h m2ua_types.h sccp_sap.h \ - sua.h sigtran_sap.h sccp_helpers.h mtp_sap.h osmo_ss7.h + sigtran_sap.h sccp_helpers.h mtp_sap.h osmo_ss7.h sigtrandir = $(includedir)/osmocom/sigtran diff --git a/include/osmocom/sigtran/sccp_helpers.h b/include/osmocom/sigtran/sccp_helpers.h index 968c500..05f4770 100644 --- a/include/osmocom/sigtran/sccp_helpers.h +++ b/include/osmocom/sigtran/sccp_helpers.h @@ -1,15 +1,18 @@ #pragma once + #include #include #include #include -int osmo_sccp_tx_unitdata(struct osmo_sccp_link *link, +void osmo_sccp_make_addr_pc_ssn(struct osmo_sccp_addr *addr, uint32_t pc, uint32_t ssn); + +int osmo_sccp_tx_unitdata(struct osmo_sccp_user *scu, const struct osmo_sccp_addr *calling_addr, const struct osmo_sccp_addr *called_addr, - uint8_t *data, unsigned int len); + const uint8_t *data, unsigned int len); -int osmo_sccp_tx_unitdata_msg(struct osmo_sccp_link *link, +int osmo_sccp_tx_unitdata_msg(struct osmo_sccp_user *scu, const struct osmo_sccp_addr *calling_addr, const struct osmo_sccp_addr *called_addr, struct msgb *msg); @@ -17,26 +20,38 @@ void osmo_sccp_make_addr_pc_ssn(struct osmo_sccp_addr *addr, uint32_t pc, uint32_t ssn); -int osmo_sccp_tx_unitdata_ranap(struct osmo_sccp_link *link, +int osmo_sccp_tx_unitdata_ranap(struct osmo_sccp_user *scu, uint32_t src_point_code, uint32_t dst_point_code, - uint8_t *data, unsigned int len); + const uint8_t *data, unsigned int len); -int osmo_sccp_tx_conn_req(struct osmo_sccp_link *link, uint32_t conn_id, +int osmo_sccp_tx_conn_req(struct osmo_sccp_user *scu, uint32_t conn_id, const struct osmo_sccp_addr *calling_addr, const struct osmo_sccp_addr *called_addr, - uint8_t *data, unsigned int len); + const uint8_t *data, unsigned int len); -int osmo_sccp_tx_conn_req_msg(struct osmo_sccp_link *link, uint32_t conn_id, +int osmo_sccp_tx_conn_req_msg(struct osmo_sccp_user *scu, uint32_t conn_id, const struct osmo_sccp_addr *calling_addr, const struct osmo_sccp_addr *called_addr, struct msgb *msg); -int osmo_sccp_tx_data(struct osmo_sccp_link *link, uint32_t conn_id, - uint8_t *data, unsigned int len); +int osmo_sccp_tx_data(struct osmo_sccp_user *scu, uint32_t conn_id, + const uint8_t *data, unsigned int len); -int osmo_sccp_tx_data_msg(struct osmo_sccp_link *link, uint32_t conn_id, +int osmo_sccp_tx_data_msg(struct osmo_sccp_user *scu, uint32_t conn_id, struct msgb *msg); +int osmo_sccp_tx_disconn(struct osmo_sccp_user *scu, uint32_t conn_id, + const struct osmo_sccp_addr *resp_addr, + uint32_t cause); + +int osmo_sccp_tx_conn_resp_msg(struct osmo_sccp_user *scu, uint32_t conn_id, + const struct osmo_sccp_addr *resp_addr, + struct msgb *msg); + +int osmo_sccp_tx_conn_resp(struct osmo_sccp_user *scu, uint32_t conn_id, + const struct osmo_sccp_addr *resp_addr, + const uint8_t *data, unsigned int len); + char *osmo_sccp_gt_dump(const struct osmo_sccp_gt *gt); char *osmo_sccp_addr_dump(const struct osmo_sccp_addr *addr); diff --git a/include/osmocom/sigtran/sua.h b/include/osmocom/sigtran/sua.h deleted file mode 100644 index 766b488..0000000 --- a/include/osmocom/sigtran/sua.h +++ /dev/null @@ -1,23 +0,0 @@ -#pragma once - -#include -#include - -struct osmo_sccp_user; -struct osmo_sccp_link; - -void osmo_sua_set_log_area(int area); - -struct osmo_sccp_user *osmo_sua_user_create(void *ctx, osmo_prim_cb prim_cb, - void *priv); -void osmo_sua_user_destroy(struct osmo_sccp_user *user); - -int osmo_sua_server_listen(struct osmo_sccp_user *user, const char *hostname, uint16_t port); - -int osmo_sua_client_connect(struct osmo_sccp_user *user, const char *hostname, uint16_t port); -struct osmo_sccp_link *osmo_sua_client_get_link(struct osmo_sccp_user *user); - -/* user hands us a SCCP-USER SAP primitive down into the stack */ -int osmo_sua_user_link_down(struct osmo_sccp_link *link, struct osmo_prim_hdr *oph); - -void *osmo_sccp_link_get_user_priv(struct osmo_sccp_link *slink); diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index 6d0b446..ab0636c 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -1197,7 +1197,9 @@ msgb_sctp_stream(msg) = ntohl(sinfo.sinfo_stream); msg->dst = asp; - if (ppid == M3UA_PPID && asp->cfg.proto == OSMO_SS7_ASP_PROT_M3UA) + if (ppid == SUA_PPID && asp->cfg.proto == OSMO_SS7_ASP_PROT_SUA) + rc = sua_rx_msg(asp, msg); + else if (ppid == M3UA_PPID && asp->cfg.proto == OSMO_SS7_ASP_PROT_M3UA) rc = m3ua_rx_msg(asp, msg); else { LOGPASP(asp, DLSS7, LOGL_NOTICE, "SCTP chunk for unknown PPID %u " @@ -1280,7 +1282,9 @@ msgb_sctp_stream(msg) = ntohl(sinfo.sinfo_stream); msg->dst = asp; - if (ppid == M3UA_PPID && asp->cfg.proto == OSMO_SS7_ASP_PROT_M3UA) + if (ppid == SUA_PPID && asp->cfg.proto == OSMO_SS7_ASP_PROT_SUA) + rc = sua_rx_msg(asp, msg); + else if (ppid == M3UA_PPID && asp->cfg.proto == OSMO_SS7_ASP_PROT_M3UA) rc = m3ua_rx_msg(asp, msg); else { LOGPASP(asp, DLSS7, LOGL_NOTICE, "SCTP chunk for unknown PPID %u " diff --git a/src/sccp_helpers.c b/src/sccp_helpers.c index 6264424..ae9918a 100644 --- a/src/sccp_helpers.c +++ b/src/sccp_helpers.c @@ -1,6 +1,6 @@ /* SCCP User SAP helper functions */ -/* (C) 2015 by Harald Welte +/* (C) 2015-2017 by Harald Welte * (C) 2016 by sysmocom s.m.f.c. GmbH * All Rights Reserved * @@ -30,6 +30,13 @@ #include #include +#include "sccp_internal.h" + +static struct msgb *scu_msgb_alloc(const char *name) +{ + return sccp_msgb_alloc("SCU"); +} + void osmo_sccp_make_addr_pc_ssn(struct osmo_sccp_addr *addr, uint32_t pc, uint32_t ssn) { addr->presence = OSMO_SCCP_ADDR_T_SSN | OSMO_SCCP_ADDR_T_PC; @@ -37,12 +44,12 @@ addr->pc = pc; } -int osmo_sccp_tx_unitdata(struct osmo_sccp_link *link, +int osmo_sccp_tx_unitdata(struct osmo_sccp_user *scu, const struct osmo_sccp_addr *calling_addr, const struct osmo_sccp_addr *called_addr, - uint8_t *data, unsigned int len) + const uint8_t *data, unsigned int len) { - struct msgb *msg = msgb_alloc(1024, "sccp_tx_unitdata"); + struct msgb *msg = scu_msgb_alloc(__func__); struct osmo_scu_prim *prim; struct osmo_scu_unitdata_param *param; @@ -55,13 +62,13 @@ msg->l2h = msgb_put(msg, len); memcpy(msg->l2h, data, len); - return osmo_sua_user_link_down(link, &prim->oph); + return osmo_sccp_user_sap_down(scu, &prim->oph); } -int osmo_sccp_tx_unitdata_ranap(struct osmo_sccp_link *link, +int osmo_sccp_tx_unitdata_ranap(struct osmo_sccp_user *scu, uint32_t src_point_code, uint32_t dst_point_code, - uint8_t *data, unsigned int len) + const uint8_t *data, unsigned int len) { struct osmo_sccp_addr calling_addr; struct osmo_sccp_addr called_addr; @@ -69,67 +76,70 @@ OSMO_SCCP_SSN_RANAP); osmo_sccp_make_addr_pc_ssn(&called_addr, dst_point_code, OSMO_SCCP_SSN_RANAP); - return osmo_sccp_tx_unitdata(link, &calling_addr, &called_addr, + return osmo_sccp_tx_unitdata(scu, &calling_addr, &called_addr, data, len); } -int osmo_sccp_tx_unitdata_msg(struct osmo_sccp_link *link, +int osmo_sccp_tx_unitdata_msg(struct osmo_sccp_user *scu, const struct osmo_sccp_addr *calling_addr, const struct osmo_sccp_addr *called_addr, struct msgb *msg) { int rc; - rc = osmo_sccp_tx_unitdata(link, calling_addr, called_addr, + rc = osmo_sccp_tx_unitdata(scu, calling_addr, called_addr, msg->data, msgb_length(msg)); msgb_free(msg); return rc; } -int osmo_sccp_tx_conn_req(struct osmo_sccp_link *link, uint32_t conn_id, +int osmo_sccp_tx_conn_req(struct osmo_sccp_user *scu, uint32_t conn_id, const struct osmo_sccp_addr *calling_addr, const struct osmo_sccp_addr *called_addr, - uint8_t *data, unsigned int len) + const uint8_t *data, unsigned int len) { - struct msgb *msg = msgb_alloc(1024, "sccp_tx_conn_req"); + struct msgb *msg = scu_msgb_alloc(__func__); struct osmo_scu_prim *prim; + struct osmo_scu_connect_param *param; prim = (struct osmo_scu_prim *) msgb_put(msg, sizeof(*prim)); osmo_prim_init(&prim->oph, SCCP_SAP_USER, OSMO_SCU_PRIM_N_CONNECT, PRIM_OP_REQUEST, msg); - osmo_sccp_make_addr_pc_ssn(&prim->u.connect.calling_addr, 1, - OSMO_SCCP_SSN_RANAP); - prim->u.connect.sccp_class = 2; - prim->u.connect.conn_id = conn_id; + param = &prim->u.connect; + if (calling_addr) + memcpy(¶m->calling_addr, calling_addr, sizeof(*calling_addr)); + memcpy(¶m->called_addr, called_addr, sizeof(*called_addr)); + param->sccp_class = 2; + param->conn_id = conn_id; if (data && len) { msg->l2h = msgb_put(msg, len); memcpy(msg->l2h, data, len); } - return osmo_sua_user_link_down(link, &prim->oph); + return osmo_sccp_user_sap_down(scu, &prim->oph); } -int osmo_sccp_tx_conn_req_msg(struct osmo_sccp_link *link, uint32_t conn_id, +int osmo_sccp_tx_conn_req_msg(struct osmo_sccp_user *scu, uint32_t conn_id, const struct osmo_sccp_addr *calling_addr, const struct osmo_sccp_addr *called_addr, struct msgb *msg) { int rc; - rc = osmo_sccp_tx_conn_req(link, conn_id, calling_addr, called_addr, + rc = osmo_sccp_tx_conn_req(scu, conn_id, calling_addr, called_addr, msg->data, msgb_length(msg)); msgb_free(msg); return rc; } -int osmo_sccp_tx_data(struct osmo_sccp_link *link, uint32_t conn_id, - uint8_t *data, unsigned int len) +int osmo_sccp_tx_data(struct osmo_sccp_user *scu, uint32_t conn_id, + const uint8_t *data, unsigned int len) { - struct msgb *msg = msgb_alloc(1024, "sccp_tx_data"); + struct msgb *msg = scu_msgb_alloc(__func__); struct osmo_scu_prim *prim; prim = (struct osmo_scu_prim *) msgb_put(msg, sizeof(*prim)); @@ -141,20 +151,79 @@ msg->l2h = msgb_put(msg, len); memcpy(msg->l2h, data, len); - return osmo_sua_user_link_down(link, &prim->oph); + return osmo_sccp_user_sap_down(scu, &prim->oph); } -int osmo_sccp_tx_data_msg(struct osmo_sccp_link *link, uint32_t conn_id, +int osmo_sccp_tx_data_msg(struct osmo_sccp_user *scu, uint32_t conn_id, struct msgb *msg) { int rc; - rc = osmo_sccp_tx_data(link, conn_id, msg->data, msgb_length(msg)); + rc = osmo_sccp_tx_data(scu, conn_id, msg->data, msgb_length(msg)); msgb_free(msg); return rc; } +/* N-DISCONNECT.req */ +int osmo_sccp_tx_disconn(struct osmo_sccp_user *scu, uint32_t conn_id, + const struct osmo_sccp_addr *resp_addr, + uint32_t cause) +{ + struct msgb *msg = scu_msgb_alloc(__func__); + struct osmo_scu_prim *prim; + struct osmo_scu_disconn_param *param; + + prim = (struct osmo_scu_prim *) msgb_put(msg, sizeof(*prim)); + osmo_prim_init(&prim->oph, SCCP_SAP_USER, + OSMO_SCU_PRIM_N_DISCONNECT, + PRIM_OP_REQUEST, msg); + param = &prim->u.disconnect; + memset(param, 0, sizeof(*param)); + param->originator = OSMO_SCCP_ORIG_NS_USER; + if (resp_addr) + memcpy(¶m->responding_addr, resp_addr, sizeof(*resp_addr)); + param->conn_id = conn_id; + param->cause = cause; + + return osmo_sccp_user_sap_down(scu, &prim->oph); +} + +/* N-CONNECT.resp */ +int osmo_sccp_tx_conn_resp_msg(struct osmo_sccp_user *scu, uint32_t conn_id, + const struct osmo_sccp_addr *resp_addr, + struct msgb *msg) +{ + struct osmo_scu_prim *prim; + struct osmo_scu_connect_param *param; + + msg->l2h = msg->data; + + prim = (struct osmo_scu_prim *) msgb_push(msg, sizeof(*prim)); + osmo_prim_init(&prim->oph, SCCP_SAP_USER, + OSMO_SCU_PRIM_N_CONNECT, + PRIM_OP_RESPONSE, msg); + param = &prim->u.connect; + param->conn_id = conn_id; + memcpy(¶m->responding_addr, resp_addr, sizeof(*resp_addr)); + param->sccp_class = 2; + + return osmo_sccp_user_sap_down(scu, &prim->oph); +} + +int osmo_sccp_tx_conn_resp(struct osmo_sccp_user *scu, uint32_t conn_id, + const struct osmo_sccp_addr *resp_addr, + const uint8_t *data, unsigned int len) +{ + struct msgb *msg = scu_msgb_alloc(__func__); + + if (data && len) { + msg->l2h = msgb_put(msg, len); + memcpy(msg->l2h, data, len); + } + return osmo_sccp_tx_conn_resp_msg(scu, conn_id, resp_addr, msg); +} + static void append_to_buf(char *buf, bool *comma, const char *fmt, ...) { va_list ap; diff --git a/src/sccp_scrc.c b/src/sccp_scrc.c index 11c52e8..5653ea9 100644 --- a/src/sccp_scrc.c +++ b/src/sccp_scrc.c @@ -139,6 +139,8 @@ if (rt->dest.as) { struct osmo_ss7_as *as = rt->dest.as; switch (as->cfg.proto) { + case OSMO_SS7_ASP_PROT_SUA: + return sua_tx_xua_as(as, xua); case OSMO_SS7_ASP_PROT_M3UA: return sua2sccp_tx_m3ua(inst, xua); default: diff --git a/src/sua.c b/src/sua.c index b135c62..04c2a01 100644 --- a/src/sua.c +++ b/src/sua.c @@ -29,17 +29,21 @@ #include #include #include +#include #include #include #include +#include #include +#include #include +#include +#include "xua_asp_fsm.h" #include "xua_internal.h" - -#define SUA_MSGB_SIZE 1500 +#include "sccp_internal.h" /* Appendix C.4 of Q.714 (all in milliseconds) */ #define CONNECTION_TIMER ( 1 * 60 * 100) @@ -205,6 +209,7 @@ .name = "SUA", .ppid = SUA_PPID, .port = SUA_PORT, + .log_subsys = DLSUA, .class = { [SUA_MSGC_MGMT] = &m3ua_msg_class_mgmt, [SUA_MSGC_SNM] = &m3ua_msg_class_snm, @@ -216,482 +221,82 @@ }, }; - -static int DSUA = -1; - -struct osmo_sccp_user { - /* global list of SUA users? */ - struct llist_head list; - /* set if we are a server */ - struct osmo_stream_srv_link *server; - struct osmo_stream_cli *client; - struct llist_head links; - /* user call-back function in case of incoming primitives */ - osmo_prim_cb prim_cb; - void *priv; -}; - -struct osmo_sccp_link { - /* list of SUA links per sua_user */ - struct llist_head list; - /* sua user to which we belong */ - struct osmo_sccp_user *user; - /* local list of (SCCP) connections in this link */ - struct llist_head connections; - /* next connection local reference */ - uint32_t next_id; - int is_server; - void *data; -}; - -enum sua_connection_state { - S_IDLE, - S_CONN_PEND_IN, - S_CONN_PEND_OUT, - S_ACTIVE, - S_DISCONN_PEND, - S_RESET_IN, - S_RESET_OUT, - S_BOTHWAY_RESET, - S_WAIT_CONN_CONF, -}; - -static const struct value_string conn_state_names[] = { - { S_IDLE, "IDLE" }, - { S_CONN_PEND_IN, "CONN_PEND_IN" }, - { S_CONN_PEND_OUT, "CONN_PEND_OUT" }, - { S_ACTIVE, "ACTIVE" }, - { S_DISCONN_PEND, "DISCONN_PEND" }, - { S_RESET_IN, "RESET_IN" }, - { S_RESET_OUT, "RESET_OUT" }, - { S_BOTHWAY_RESET, "BOTHWAY_RESET" }, - { S_WAIT_CONN_CONF, "WAIT_CONN_CONF" }, - { 0, NULL } -}; - -struct sua_connection { - struct llist_head list; - struct osmo_sccp_link *link; - struct osmo_sccp_addr calling_addr; - struct osmo_sccp_addr called_addr; - uint32_t conn_id; - uint32_t remote_ref; - enum sua_connection_state state; - struct osmo_timer_list timer; - /* inactivity timers */ - struct osmo_timer_list tias; - struct osmo_timer_list tiar; -}; - - /*********************************************************************** - * SUA Link and Connection handling + * ERROR generation ***********************************************************************/ -static struct osmo_sccp_link *sua_link_new(struct osmo_sccp_user *user, int is_server) +static struct xua_msg *sua_gen_error(uint32_t err_code) { - struct osmo_sccp_link *link; + struct xua_msg *xua = xua_msg_alloc(); - link = talloc_zero(user, struct osmo_sccp_link); - if (!link) - return NULL; + xua->hdr = XUA_HDR(SUA_MSGC_MGMT, SUA_MGMT_ERR); + xua->hdr.version = SUA_VERSION; + xua_msg_add_u32(xua, SUA_IEI_ERR_CODE, err_code); - link->user = user; - link->is_server = is_server; - INIT_LLIST_HEAD(&link->connections); - - llist_add_tail(&link->list, &user->links); - - return link; + return xua; } -static void conn_destroy(struct sua_connection *conn); - -static void sua_link_destroy(struct osmo_sccp_link *link) +static struct xua_msg *sua_gen_error_msg(uint32_t err_code, struct msgb *msg) { - struct sua_connection *conn; + struct xua_msg *xua = sua_gen_error(err_code); + unsigned int len_max_40 = msgb_length(msg); - llist_for_each_entry(conn, &link->connections, list) - conn_destroy(conn); + if (len_max_40 > 40) + len_max_40 = 40; - llist_del(&link->list); + xua_msg_add_data(xua, SUA_IEI_DIAG_INFO, len_max_40, msgb_data(msg)); - /* FIXME: do we need to cleanup the sccp link? */ - - talloc_free(link); + return xua; } -static int sua_link_send(struct osmo_sccp_link *link, struct msgb *msg) +/*********************************************************************** + * Transmitting SUA messsages to SCTP + ***********************************************************************/ + +static int sua_tx_xua_asp(struct osmo_ss7_asp *asp, struct xua_msg *xua) { + struct msgb *msg = xua_to_msg(SUA_VERSION, xua); + + OSMO_ASSERT(asp->cfg.proto == OSMO_SS7_ASP_PROT_SUA); + + xua_msg_free(xua); + + if (!msg) { + LOGPASP(asp, DLSUA, LOGL_ERROR, "Error encoding SUA Msg\n"); + return -1; + } + msgb_sctp_ppid(msg) = SUA_PPID; - - DEBUGP(DSUA, "sua_link_send(%s)\n", osmo_hexdump(msg->data, msgb_length(msg))); - - if (link->is_server) - osmo_stream_srv_send(link->data, msg); - else - osmo_stream_cli_send(link->data, msg); - - return 0; + return osmo_ss7_asp_send(asp, msg); } -static struct sua_connection *conn_find_by_id(struct osmo_sccp_link *link, uint32_t id) +/*! \brief Send a given xUA message via a given SUA Application Server + * \param[in] as Application Server through which to send \ref xua + * \param[in] xua xUA message to be sent + * \return 0 on success; negative on error */ +int sua_tx_xua_as(struct osmo_ss7_as *as, struct xua_msg *xua) { - struct sua_connection *conn; + struct osmo_ss7_asp *asp; + unsigned int i; - llist_for_each_entry(conn, &link->connections, list) { - if (conn->conn_id == id) - return conn; + OSMO_ASSERT(as->cfg.proto == OSMO_SS7_ASP_PROT_SUA); + + /* FIXME: Select ASP within AS depending on traffic mode */ + for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) { + asp = as->cfg.asps[i]; + if (!asp) + continue; + if (asp) + break; } - return NULL; -} - -static void tx_inact_tmr_cb(void *data) -{ - struct sua_connection *conn = data; - struct xua_msg *xua = xua_msg_alloc(); - struct msgb *outmsg; - - /* encode + send the CLDT */ - xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_COIT); - xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, 0); /* FIXME */ - xua_msg_add_u32(xua, SUA_IEI_PROTO_CLASS, 2); - xua_msg_add_u32(xua, SUA_IEI_SRC_REF, conn->conn_id); - xua_msg_add_u32(xua, SUA_IEI_DEST_REF, conn->remote_ref); - /* optional: sequence number; credit (both class 3 only) */ - - outmsg = xua_to_msg(1, xua); - xua_msg_free(xua); - - sua_link_send(conn->link, outmsg); -} - -static void rx_inact_tmr_cb(void *data) -{ - struct sua_connection *conn = data; - - /* FIXME: release connection */ - /* Send N-DISCONNECT.ind to local user */ - /* Send RLSD to peer */ - /* enter disconnect pending state with release timer pending */ -} - - -static struct sua_connection *conn_create_id(struct osmo_sccp_link *link, uint32_t conn_id) -{ - struct sua_connection *conn = talloc_zero(link, struct sua_connection); - - conn->conn_id = conn_id; - conn->link = link; - conn->state = S_IDLE; - - llist_add_tail(&conn->list, &link->connections); - - conn->tias.cb = tx_inact_tmr_cb; - conn->tias.data = conn; - conn->tiar.cb = rx_inact_tmr_cb; - conn->tiar.data = conn; - - return conn; -} - -static struct sua_connection *conn_create(struct osmo_sccp_link *link) -{ - uint32_t conn_id; - - do { - conn_id = link->next_id++; - } while (conn_find_by_id(link, conn_id)); - - return conn_create_id(link, conn_id); -} - -static void conn_destroy(struct sua_connection *conn) -{ - /* FIXME: do some cleanup; inform user? */ - osmo_timer_del(&conn->tias); - osmo_timer_del(&conn->tiar); - llist_del(&conn->list); - talloc_free(conn); -} - -static void conn_state_set(struct sua_connection *conn, - enum sua_connection_state state) -{ - DEBUGP(DSUA, "(%u) state chg %s->", conn->conn_id, - get_value_string(conn_state_names, conn->state)); - DEBUGPC(DSUA, "%s\n", - get_value_string(conn_state_names, state)); - conn->state = state; -} - -static void conn_restart_tx_inact_timer(struct sua_connection *conn) -{ - osmo_timer_schedule(&conn->tias, TX_INACT_TIMER / 100, - (TX_INACT_TIMER % 100) * 10); -} - -static void conn_restart_rx_inact_timer(struct sua_connection *conn) -{ - osmo_timer_schedule(&conn->tiar, RX_INACT_TIMER / 100, - (RX_INACT_TIMER % 100) * 10); -} - -static void conn_start_inact_timers(struct sua_connection *conn) -{ - conn_restart_tx_inact_timer(conn); - conn_restart_rx_inact_timer(conn); -} - -/*********************************************************************** - * Handling of messages from the User SAP - ***********************************************************************/ - -/* user program sends us a N-CONNNECT.req to initiate a new connection */ -static int sua_connect_req(struct osmo_sccp_link *link, struct osmo_scu_prim *prim) -{ - struct osmo_scu_connect_param *par = &prim->u.connect; - struct xua_msg *xua = xua_msg_alloc(); - struct sua_connection *conn; - struct msgb *outmsg; - - if (par->sccp_class != 2) { - LOGP(DSUA, LOGL_ERROR, "N-CONNECT.req for unsupported " - "SCCP class %u\n", par->sccp_class); - /* FIXME: Send primitive to user */ - return -EINVAL; - } - - conn = conn_create_id(link, par->conn_id); - if (!conn) { - /* FIXME: Send primitive to user */ - return -EINVAL; - } - - memcpy(&conn->called_addr, &par->called_addr, - sizeof(conn->called_addr)); - memcpy(&conn->calling_addr, &par->calling_addr, - sizeof(conn->calling_addr)); - - /* encode + send the CLDT */ - xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_CORE); - xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, 0); /* FIXME */ - xua_msg_add_u32(xua, SUA_IEI_PROTO_CLASS, par->sccp_class); - xua_msg_add_u32(xua, SUA_IEI_SRC_REF, conn->conn_id); - xua_msg_add_sccp_addr(xua, SUA_IEI_DEST_ADDR, &par->called_addr); - xua_msg_add_u32(xua, SUA_IEI_SEQ_CTRL, 0); /* FIXME */ - /* sequence number */ - if (par->calling_addr.presence) - xua_msg_add_sccp_addr(xua, SUA_IEI_SRC_ADDR, &par->calling_addr); - /* optional: hop count; importance; priority; credit */ - if (msgb_l2(prim->oph.msg)) - xua_msg_add_data(xua, SUA_IEI_DATA, msgb_l2len(prim->oph.msg), - msgb_l2(prim->oph.msg)); - - outmsg = xua_to_msg(1, xua); - xua_msg_free(xua); - - /* FIXME: Start CONNECTION_TIMER */ - conn_state_set(conn, S_CONN_PEND_OUT); - - return sua_link_send(link, outmsg); -} - -/* user program sends us a N-CONNNECT.resp, presumably against a - * N-CONNECT.ind */ -static int sua_connect_resp(struct osmo_sccp_link *link, struct osmo_scu_prim *prim) -{ - struct osmo_scu_connect_param *par = &prim->u.connect; - struct xua_msg *xua = xua_msg_alloc(); - struct sua_connection *conn; - struct msgb *outmsg; - - /* check if we already know a connection for this conn_id */ - conn = conn_find_by_id(link, par->conn_id); - if (!conn) { - LOGP(DSUA, LOGL_ERROR, "N-CONNECT.resp for unknown " - "connection ID %u\n", par->conn_id); - /* FIXME: Send primitive to user */ + if (!asp) { + LOGP(DLSUA, LOGL_ERROR, "No ASP in AS, dropping message\n"); + xua_msg_free(xua); return -ENODEV; } - if (conn->state != S_CONN_PEND_IN) { - LOGP(DSUA, LOGL_ERROR, "N-CONNECT.resp in wrong state %s\n", - get_value_string(conn_state_names, conn->state)); - /* FIXME: Send primitive to user */ - return -EINVAL; - } - - /* encode + send the COAK message */ - xua = xua_msg_alloc(); - xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_COAK); - xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, 0); /* FIXME */ - xua_msg_add_u32(xua, SUA_IEI_PROTO_CLASS, par->sccp_class); - xua_msg_add_u32(xua, SUA_IEI_DEST_REF, conn->remote_ref); - xua_msg_add_u32(xua, SUA_IEI_SRC_REF, conn->conn_id); - xua_msg_add_u32(xua, SUA_IEI_SEQ_CTRL, 0); /* FIXME */ - /* sequence number */ - if (par->calling_addr.presence) - xua_msg_add_sccp_addr(xua, SUA_IEI_SRC_ADDR, &par->calling_addr); - /* optional: hop count; importance; priority */ - /* FIXME: destination address will be present in case the CORE - * message conveys the source address parameter */ - if (par->called_addr.presence) - xua_msg_add_sccp_addr(xua, SUA_IEI_DEST_ADDR, &par->called_addr); - if (msgb_l2(prim->oph.msg)) - xua_msg_add_data(xua, SUA_IEI_DATA, msgb_l2len(prim->oph.msg), - msgb_l2(prim->oph.msg)); - - outmsg = xua_to_msg(1, xua); - xua_msg_free(xua); - - conn_state_set(conn, S_ACTIVE); - conn_start_inact_timers(conn); - - return sua_link_send(link, outmsg); + return sua_tx_xua_asp(asp, xua); } - -/* user wants to send connection-oriented data */ -static int sua_data_req(struct osmo_sccp_link *link, struct osmo_scu_prim *prim) -{ - struct osmo_scu_data_param *par = &prim->u.data; - struct xua_msg *xua; - struct sua_connection *conn; - struct msgb *outmsg; - - /* check if we know about this conncetion, and obtain reference */ - conn = conn_find_by_id(link, par->conn_id); - if (!conn) { - LOGP(DSUA, LOGL_ERROR, "N-DATA.req for unknown " - "connection ID %u\n", par->conn_id); - /* FIXME: Send primitive to user */ - return -ENODEV; - } - - if (conn->state != S_ACTIVE) { - LOGP(DSUA, LOGL_ERROR, "N-DATA.req in wrong state %s\n", - get_value_string(conn_state_names, conn->state)); - /* FIXME: Send primitive to user */ - return -EINVAL; - } - - conn_restart_tx_inact_timer(conn); - - /* encode + send the CODT message */ - xua = xua_msg_alloc(); - xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_CODT); - xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, 0); /* FIXME */ - /* Sequence number only in expedited data */ - xua_msg_add_u32(xua, SUA_IEI_DEST_REF, conn->remote_ref); - /* optional: priority; correlation id */ - xua_msg_add_data(xua, SUA_IEI_DATA, msgb_l2len(prim->oph.msg), - msgb_l2(prim->oph.msg)); - - outmsg = xua_to_msg(1, xua); - xua_msg_free(xua); - - return sua_link_send(link, outmsg); -} - -/* user wants to disconnect a connection */ -static int sua_disconnect_req(struct osmo_sccp_link *link, struct osmo_scu_prim *prim) -{ - struct osmo_scu_disconn_param *par = &prim->u.disconnect; - struct xua_msg *xua; - struct sua_connection *conn; - struct msgb *outmsg; - - /* resolve reference of connection */ - conn = conn_find_by_id(link, par->conn_id); - if (!conn) { - LOGP(DSUA, LOGL_ERROR, "N-DISCONNECT.req for unknown " - "connection ID %u\n", par->conn_id); - /* FIXME: Send primitive to user */ - return -ENODEV; - } - - /* encode + send the RELRE */ - xua = xua_msg_alloc(); - xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_RELRE); - xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, 0); /* FIXME */ - xua_msg_add_u32(xua, SUA_IEI_DEST_REF, conn->remote_ref); - xua_msg_add_u32(xua, SUA_IEI_SRC_REF, conn->conn_id); - xua_msg_add_u32(xua, SUA_IEI_CAUSE, par->cause); - /* optional: importance */ - if (msgb_l2(prim->oph.msg)) - xua_msg_add_data(xua, SUA_IEI_DATA, msgb_l2len(prim->oph.msg), - msgb_l2(prim->oph.msg)); - - outmsg = xua_to_msg(1, xua); - xua_msg_free(xua); - - conn_state_set(conn, S_DISCONN_PEND); - conn_destroy(conn); - - LOGP(DSUA, LOGL_NOTICE, "About to send the SUA RELRE\n"); - return sua_link_send(link, outmsg); -} - -/* user wants to send connectionless data */ -static int sua_unitdata_req(struct osmo_sccp_link *link, struct osmo_scu_prim *prim) -{ - struct osmo_scu_unitdata_param *par = &prim->u.unitdata; - struct xua_msg *xua = xua_msg_alloc(); - struct msgb *outmsg; - - /* encode + send the CLDT */ - xua->hdr = XUA_HDR(SUA_MSGC_CL, SUA_CL_CLDT); - xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, 0); /* FIXME */ - xua_msg_add_u32(xua, SUA_IEI_PROTO_CLASS, 0); - xua_msg_add_sccp_addr(xua, SUA_IEI_SRC_ADDR, &par->calling_addr); - xua_msg_add_sccp_addr(xua, SUA_IEI_DEST_ADDR, &par->called_addr); - xua_msg_add_u32(xua, SUA_IEI_SEQ_CTRL, par->in_sequence_control); - /* optional: importance, ... correlation id? */ - xua_msg_add_data(xua, SUA_IEI_DATA, msgb_l2len(prim->oph.msg), - msgb_l2(prim->oph.msg)); - - outmsg = xua_to_msg(1, xua); - xua_msg_free(xua); - - return sua_link_send(link, outmsg); -} - -/* user hands us a SCCP-USER SAP primitive down into the stack */ -int osmo_sua_user_link_down(struct osmo_sccp_link *link, struct osmo_prim_hdr *oph) -{ - struct osmo_scu_prim *prim = (struct osmo_scu_prim *) oph; - struct msgb *msg = prim->oph.msg; - int rc = 0; - - LOGP(DSUA, LOGL_DEBUG, "Received SCCP User Primitive (%s)\n", - osmo_scu_prim_name(&prim->oph)); - - switch (OSMO_PRIM_HDR(&prim->oph)) { - case OSMO_PRIM(OSMO_SCU_PRIM_N_CONNECT, PRIM_OP_REQUEST): - rc = sua_connect_req(link, prim); - break; - case OSMO_PRIM(OSMO_SCU_PRIM_N_CONNECT, PRIM_OP_RESPONSE): - rc = sua_connect_resp(link, prim); - break; - case OSMO_PRIM(OSMO_SCU_PRIM_N_DATA, PRIM_OP_REQUEST): - rc = sua_data_req(link, prim); - break; - case OSMO_PRIM(OSMO_SCU_PRIM_N_DISCONNECT, PRIM_OP_REQUEST): - rc = sua_disconnect_req(link, prim); - break; - case OSMO_PRIM(OSMO_SCU_PRIM_N_UNITDATA, PRIM_OP_REQUEST): - rc = sua_unitdata_req(link, prim); - break; - default: - rc = -1; - } - - if (rc != 1) - msgb_free(msg); - - return rc; -} - /*********************************************************************** * Receiving SUA messsages from SCTP @@ -751,12 +356,12 @@ memset(out, 0, sizeof(*out)); - LOGP(DSUA, LOGL_DEBUG, "%s(IEI=0x%04x) (%d) %s\n", __func__, + LOGP(DLSUA, LOGL_DEBUG, "%s(IEI=0x%04x) (%d) %s\n", __func__, param->tag, param->len, osmo_hexdump(param->dat, param->len)); if (param->len < 4) { - LOGP(DSUA, LOGL_ERROR, "SUA IEI 0x%04x: invalid address length: %d\n", + LOGP(DLSUA, LOGL_ERROR, "SUA IEI 0x%04x: invalid address length: %d\n", param->tag, param->len); return -EINVAL; } @@ -779,14 +384,14 @@ break; case SUA_RI_HOST: default: - LOGP(DSUA, LOGL_ERROR, "SUA IEI 0x%04x: Routing Indicator not supported yet: %d\n", + LOGP(DLSUA, LOGL_ERROR, "SUA IEI 0x%04x: Routing Indicator not supported yet: %d\n", param->tag, ri); return -ENOTSUP; } if (ai != 7) { #if 0 - LOGP(DSUA, LOGL_ERROR, "SUA IEI 0x%04x: Address Indicator not supported yet: %x\n", + LOGP(DLSUA, LOGL_ERROR, "SUA IEI 0x%04x: Address Indicator not supported yet: %x\n", param->tag, ai); return -ENOTSUP; #endif @@ -806,7 +411,7 @@ par_len = ntohs(par->len); par_datalen = par_len - sizeof(*par); - LOGP(DSUA, LOGL_DEBUG, "SUA IEI 0x%04x pos %hu/%hu: subpart tag 0x%04x, len %hu\n", + LOGP(DLSUA, LOGL_DEBUG, "SUA IEI 0x%04x pos %hu/%hu: subpart tag 0x%04x, len %hu\n", param->tag, pos, param->len, par_tag, par_len); switch (par_tag) { @@ -839,7 +444,7 @@ out->presence |= OSMO_SCCP_ADDR_T_IPv4; break; default: - LOGP(DSUA, LOGL_ERROR, "SUA IEI 0x%04x: Unknown subpart tag %hd\n", + LOGP(DLSUA, LOGL_ERROR, "SUA IEI 0x%04x: Unknown subpart tag %hd\n", param->tag, par_tag); goto subpar_fail; } @@ -850,7 +455,7 @@ return 0; subpar_fail: - LOGP(DSUA, LOGL_ERROR, "Failed to parse subparts of address IEI=0x%04x\n", + LOGP(DLSUA, LOGL_ERROR, "Failed to parse subparts of address IEI=0x%04x\n", param->tag); return -EINVAL; } @@ -871,809 +476,205 @@ return sua_addr_parse_part(out, param); } -static int sua_rx_cldt(struct osmo_sccp_link *link, struct xua_msg *xua) +/* connectionless messages received from socket */ +static int sua_rx_cl(struct osmo_ss7_asp *asp, struct xua_msg *xua) { - struct osmo_scu_prim *prim; - struct osmo_scu_unitdata_param *param; - struct xua_msg_part *data_ie = xua_msg_find_tag(xua, SUA_IEI_DATA); - struct msgb *upmsg = sccp_msgb_alloc(__func__); - uint32_t protocol_class; + struct osmo_sccp_instance *inst = asp->inst->sccp; - /* fill primitive */ - prim = (struct osmo_scu_prim *) msgb_put(upmsg, sizeof(*prim)); - param = &prim->u.unitdata; - osmo_prim_init(&prim->oph, SCCP_SAP_USER, - OSMO_SCU_PRIM_N_UNITDATA, - PRIM_OP_INDICATION, upmsg); - sua_addr_parse(¶m->called_addr, xua, SUA_IEI_DEST_ADDR); - sua_addr_parse(¶m->calling_addr, xua, SUA_IEI_SRC_ADDR); - param->in_sequence_control = xua_msg_get_u32(xua, SUA_IEI_SEQ_CTRL); - protocol_class = xua_msg_get_u32(xua, SUA_IEI_PROTO_CLASS); - param->return_option = protocol_class & 0x80; - param->importance = xua_msg_get_u32(xua, SUA_IEI_IMPORTANCE); - - /* copy data */ - upmsg->l2h = msgb_put(upmsg, data_ie->len); - memcpy(upmsg->l2h, data_ie->dat, data_ie->len); - - /* send to user SAP */ - link->user->prim_cb(&prim->oph, link); - - return 0; + /* We feed into SCRC, which then hands the message into + * either SCLC or SCOC, or forwards it to MTP */ + return scrc_rx_mtp_xfer_ind_xua(inst, xua); } - - -/* connectioness messages received from socket */ -static int sua_rx_cl(struct osmo_sccp_link *link, - struct xua_msg *xua, struct msgb *msg) -{ - int rc = -1; - - switch (xua->hdr.msg_type) { - case SUA_CL_CLDT: - rc = sua_rx_cldt(link, xua); - break; - case SUA_CL_CLDR: - default: - break; - } - - return rc; -} - -/* RFC 3868 3.3.3 / SCCP CR (Connection Request) */ -static int sua_rx_core(struct osmo_sccp_link *link, struct xua_msg *xua) -{ - struct osmo_scu_prim *prim; - struct osmo_scu_connect_param *param; - struct xua_msg_part *data_ie = xua_msg_find_tag(xua, SUA_IEI_DATA); - struct msgb *upmsg; - struct sua_connection *conn; - - /* fill conn */ - conn = conn_create(link); - sua_addr_parse(&conn->called_addr, xua, SUA_IEI_DEST_ADDR); - sua_addr_parse(&conn->calling_addr, xua, SUA_IEI_SRC_ADDR); - conn->remote_ref = xua_msg_get_u32(xua, SUA_IEI_SRC_REF); - - /* fill primitive */ - upmsg = sccp_msgb_alloc(__func__); - prim = (struct osmo_scu_prim *) msgb_put(upmsg, sizeof(*prim)); - param = &prim->u.connect; - osmo_prim_init(&prim->oph, SCCP_SAP_USER, - OSMO_SCU_PRIM_N_CONNECT, - PRIM_OP_INDICATION, upmsg); - param->conn_id = conn->conn_id; - memcpy(¶m->called_addr, &conn->called_addr, - sizeof(param->called_addr)); - memcpy(¶m->calling_addr, &conn->calling_addr, - sizeof(param->calling_addr)); - //param->in_sequence_control; - param->sccp_class = xua_msg_get_u32(xua, SUA_IEI_PROTO_CLASS) & 3; - param->importance = xua_msg_get_u32(xua, SUA_IEI_IMPORTANCE); - - if (data_ie) { - /* copy data */ - upmsg->l2h = msgb_put(upmsg, data_ie->len); - memcpy(upmsg->l2h, data_ie->dat, data_ie->len); - } - - conn_state_set(conn, S_CONN_PEND_IN); - - /* send to user SAP */ - link->user->prim_cb(&prim->oph, link); - - return 0; -} - -/* RFC 3868 3.3.4 / SCCP CC (Connection Confirm) */ -static int sua_rx_coak(struct osmo_sccp_link *link, struct xua_msg *xua) -{ - struct osmo_scu_prim *prim; - struct sua_connection *conn; - struct osmo_scu_connect_param *param; - struct xua_msg_part *data_ie = xua_msg_find_tag(xua, SUA_IEI_DATA); - struct msgb *upmsg; - uint32_t conn_id = xua_msg_get_u32(xua, SUA_IEI_DEST_REF); - - /* resolve conn */ - conn = conn_find_by_id(link, conn_id); - if (!conn) { - LOGP(DSUA, LOGL_ERROR, "COAK for unknown reference %u\n", - conn_id); - /* FIXME: send error reply down the sua link? */ - return -1; - } - conn_restart_rx_inact_timer(conn); - - if (conn->state != S_CONN_PEND_OUT) { - LOGP(DSUA, LOGL_ERROR, "COAK in wrong state %s\n", - get_value_string(conn_state_names, conn->state)); - /* FIXME: send error reply down the sua link? */ - return -EINVAL; - } - - /* track remote reference */ - conn->remote_ref = xua_msg_get_u32(xua, SUA_IEI_SRC_REF); - - /* fill primitive */ - upmsg = sccp_msgb_alloc(__func__); - prim = (struct osmo_scu_prim *) msgb_put(upmsg, sizeof(*prim)); - param = &prim->u.connect; - osmo_prim_init(&prim->oph, SCCP_SAP_USER, - OSMO_SCU_PRIM_N_CONNECT, - PRIM_OP_CONFIRM, upmsg); - param->conn_id = conn->conn_id; - memcpy(¶m->called_addr, &conn->called_addr, - sizeof(param->called_addr)); - memcpy(¶m->calling_addr, &conn->calling_addr, - sizeof(param->calling_addr)); - //param->in_sequence_control; - param->sccp_class = xua_msg_get_u32(xua, SUA_IEI_PROTO_CLASS) & 3; - param->importance = xua_msg_get_u32(xua, SUA_IEI_IMPORTANCE); - - if (data_ie) { - /* copy data */ - upmsg->l2h = msgb_put(upmsg, data_ie->len); - memcpy(upmsg->l2h, data_ie->dat, data_ie->len); - } - - conn_state_set(conn, S_ACTIVE); - conn_start_inact_timers(conn); - - /* send to user SAP */ - link->user->prim_cb(&prim->oph, link); - - return 0; -} - -/* RFC 3868 3.3.5 / SCCP CREF (Connection Refused) */ -static int sua_rx_coref(struct osmo_sccp_link *link, struct xua_msg *xua) -{ - struct osmo_scu_prim *prim; - struct sua_connection *conn; - struct osmo_scu_disconn_param *param; - struct xua_msg_part *data_ie = xua_msg_find_tag(xua, SUA_IEI_DATA); - struct msgb *upmsg; - uint32_t conn_id = xua_msg_get_u32(xua, SUA_IEI_DEST_REF); - uint32_t cause; - - /* resolve conn */ - conn = conn_find_by_id(link, conn_id); - if (!conn) { - LOGP(DSUA, LOGL_ERROR, "COREF for unknown reference %u\n", - conn_id); - /* FIXME: send error reply down the sua link? */ - return -1; - } - conn_restart_rx_inact_timer(conn); - - /* fill primitive */ - upmsg = sccp_msgb_alloc(__func__); - prim = (struct osmo_scu_prim *) msgb_put(upmsg, sizeof(*prim)); - param = &prim->u.disconnect; - osmo_prim_init(&prim->oph, SCCP_SAP_USER, - OSMO_SCU_PRIM_N_DISCONNECT, - PRIM_OP_INDICATION, upmsg); - param->conn_id = conn_id; - param->responding_addr = conn->called_addr; - param->originator = OSMO_SCCP_ORIG_UNDEFINED; - //param->in_sequence_control; - /* TODO evaluate cause: - * cause = xua_msg_get_u32(xua, SUA_IEI_CAUSE); */ - /* optional: src addr */ - /* optional: dest addr */ - param->importance = xua_msg_get_u32(xua, SUA_IEI_IMPORTANCE); - if (data_ie) { - /* copy data */ - upmsg->l2h = msgb_put(upmsg, data_ie->len); - memcpy(upmsg->l2h, data_ie->dat, data_ie->len); - } - - /* send to user SAP */ - link->user->prim_cb(&prim->oph, link); - - conn_state_set(conn, S_IDLE); - conn_destroy(conn); - - return 0; -} - -/* RFC 3868 3.3.6 / SCCP RLSD (Released) */ -static int sua_rx_relre(struct osmo_sccp_link *link, struct xua_msg *xua) -{ - struct osmo_scu_prim *prim; - struct sua_connection *conn; - struct osmo_scu_disconn_param *param; - struct xua_msg_part *data_ie = xua_msg_find_tag(xua, SUA_IEI_DATA); - struct msgb *upmsg; - uint32_t conn_id = xua_msg_get_u32(xua, SUA_IEI_DEST_REF); - uint32_t cause; - - /* resolve conn */ - conn = conn_find_by_id(link, conn_id); - if (!conn) { - LOGP(DSUA, LOGL_ERROR, "RELRE for unknown reference %u\n", - conn_id); - /* FIXME: send error reply down the sua link? */ - return -1; - } - - /* fill primitive */ - upmsg = sccp_msgb_alloc(__func__); - prim = (struct osmo_scu_prim *) msgb_put(upmsg, sizeof(*prim)); - param = &prim->u.disconnect; - osmo_prim_init(&prim->oph, SCCP_SAP_USER, - OSMO_SCU_PRIM_N_DISCONNECT, - PRIM_OP_INDICATION, upmsg); /* what primitive? */ - - param->conn_id = conn_id; - /* source reference */ - cause = xua_msg_get_u32(xua, SUA_IEI_CAUSE); - param->importance = xua_msg_get_u32(xua, SUA_IEI_IMPORTANCE); - if (data_ie) { - /* copy data */ - upmsg->l2h = msgb_put(upmsg, data_ie->len); - memcpy(upmsg->l2h, data_ie->dat, data_ie->len); - } - - param->responding_addr = conn->called_addr; - param->originator = OSMO_SCCP_ORIG_UNDEFINED; - - /* send to user SAP */ - link->user->prim_cb(&prim->oph, link); - - conn_state_set(conn, S_IDLE); - conn_destroy(conn); - - return 0; -} - -/* RFC 3868 3.3.7 / SCCP RLC (Release Complete)*/ -static int sua_rx_relco(struct osmo_sccp_link *link, struct xua_msg *xua) -{ - struct osmo_scu_prim *prim; - struct sua_connection *conn; - struct osmo_scu_disconn_param *param; - struct msgb *upmsg; - uint32_t conn_id = xua_msg_get_u32(xua, SUA_IEI_DEST_REF); - - /* resolve conn */ - conn = conn_find_by_id(link, conn_id); - if (!conn) { - LOGP(DSUA, LOGL_ERROR, "RELCO for unknown reference %u\n", - conn_id); - /* FIXME: send error reply down the sua link? */ - return -1; - } - conn_restart_rx_inact_timer(conn); - - /* fill primitive */ - upmsg = sccp_msgb_alloc(__func__); - prim = (struct osmo_scu_prim *) msgb_put(upmsg, sizeof(*prim)); - param = &prim->u.disconnect; - osmo_prim_init(&prim->oph, SCCP_SAP_USER, - OSMO_SCU_PRIM_N_DISCONNECT, - PRIM_OP_CONFIRM, upmsg); /* what primitive? */ - - param->conn_id = conn_id; - /* source reference */ - param->importance = xua_msg_get_u32(xua, SUA_IEI_IMPORTANCE); - - param->responding_addr = conn->called_addr; - param->originator = OSMO_SCCP_ORIG_UNDEFINED; - - /* send to user SAP */ - link->user->prim_cb(&prim->oph, link); - - conn_destroy(conn); - - return 0; - -} - -/* RFC3868 3.3.1 / SCCP DT1 (Data Form 1) */ -static int sua_rx_codt(struct osmo_sccp_link *link, struct xua_msg *xua) -{ - struct osmo_scu_prim *prim; - struct sua_connection *conn; - struct osmo_scu_data_param *param; - struct xua_msg_part *data_ie = xua_msg_find_tag(xua, SUA_IEI_DATA); - struct msgb *upmsg; - uint32_t conn_id = xua_msg_get_u32(xua, SUA_IEI_DEST_REF); - - /* resolve conn */ - conn = conn_find_by_id(link, conn_id); - if (!conn) { - LOGP(DSUA, LOGL_ERROR, "DT1 for unknown reference %u\n", - conn_id); - /* FIXME: send error reply down the sua link? */ - return -1; - } - - if (conn->state != S_ACTIVE) { - LOGP(DSUA, LOGL_ERROR, "DT1 in invalid state %s\n", - get_value_string(conn_state_names, conn->state)); - /* FIXME: send error reply down the sua link? */ - return -1; - } - - conn_restart_rx_inact_timer(conn); - - /* fill primitive */ - upmsg = sccp_msgb_alloc(__func__); - prim = (struct osmo_scu_prim *) msgb_put(upmsg, sizeof(*prim)); - param = &prim->u.data; - osmo_prim_init(&prim->oph, SCCP_SAP_USER, - OSMO_SCU_PRIM_N_DATA, - PRIM_OP_INDICATION, upmsg); - param->conn_id = conn_id; - param->importance = xua_msg_get_u32(xua, SUA_IEI_IMPORTANCE); - - /* copy data */ - upmsg->l2h = msgb_put(upmsg, data_ie->len); - memcpy(upmsg->l2h, data_ie->dat, data_ie->len); - - /* send to user SAP */ - link->user->prim_cb(&prim->oph, link); - - return 0; -} - /* connection-oriented messages received from socket */ -static int sua_rx_co(struct osmo_sccp_link *link, - struct xua_msg *xua, struct msgb *msg) +static int sua_rx_co(struct osmo_ss7_asp *asp, struct xua_msg *xua) { - int rc = -1; + struct osmo_sccp_instance *inst = asp->inst->sccp; - switch (xua->hdr.msg_type) { - case SUA_CO_CORE: - rc = sua_rx_core(link, xua); - break; - case SUA_CO_COAK: - rc = sua_rx_coak(link, xua); - break; - case SUA_CO_COREF: - rc = sua_rx_coref(link, xua); - break; - case SUA_CO_RELRE: - rc = sua_rx_relre(link, xua); - break; - case SUA_CO_RELCO: - rc = sua_rx_relco(link, xua); - break; - case SUA_CO_CODT: - rc = sua_rx_codt(link, xua); - break; - case SUA_CO_RESCO: - case SUA_CO_RESRE: - case SUA_CO_CODA: - case SUA_CO_COERR: - case SUA_CO_COIT: - /* FIXME */ - default: - break; - } - - return rc; + /* We feed into SCRC, which then hands the message into + * either SCLC or SCOC, or forwards it to MTP */ + return scrc_rx_mtp_xfer_ind_xua(inst, xua); } -/* process SUA message received from socket */ -static int sua_rx_msg(struct osmo_sccp_link *link, struct msgb *msg) +static int sua_rx_mgmt_err(struct osmo_ss7_asp *asp, struct xua_msg *xua) { - struct xua_msg *xua; - int rc = -1; + uint32_t err_code = xua_msg_get_u32(xua, SUA_IEI_ERR_CODE); - xua = xua_from_msg(1, msgb_length(msg), msg->data); - if (!xua) { - LOGP(DSUA, LOGL_ERROR, "Unable to parse incoming " - "SUA message\n"); + LOGPASP(asp, DLSUA, LOGL_ERROR, "Received MGMT_ERR '%s': %s\n", + get_value_string(m3ua_err_names, err_code), + xua_msg_dump(xua, &xua_dialect_sua)); + + /* NEVER return != 0 here, as we cannot respont to an ERR + * message with another ERR! */ + return 0; +} + +static int sua_rx_mgmt_ntfy(struct osmo_ss7_asp *asp, struct xua_msg *xua) +{ + struct m3ua_notify_params ntfy; + const char *type_name, *info_name; + + m3ua_decode_notify(&ntfy, asp, xua); + + type_name = get_value_string(m3ua_ntfy_type_names, ntfy.status_type); + + switch (ntfy.status_type) { + case M3UA_NOTIFY_T_STATCHG: + info_name = get_value_string(m3ua_ntfy_stchg_names, + ntfy.status_info); + break; + case M3UA_NOTIFY_T_OTHER: + info_name = get_value_string(m3ua_ntfy_other_names, + ntfy.status_info); + break; + default: + info_name = "NULL"; + break; + } + LOGPASP(asp, DLSUA, LOGL_NOTICE, "Received NOTIFY Type %s:%s (%s)\n", + type_name, info_name, + ntfy.info_string ? ntfy.info_string : ""); + + if (ntfy.info_string) + talloc_free(ntfy.info_string); + + /* TODO: should we report this soemwhere? */ + return 0; +} + +static int sua_rx_mgmt(struct osmo_ss7_asp *asp, struct xua_msg *xua) +{ + switch (xua->hdr.msg_type) { + case SUA_MGMT_ERR: + return sua_rx_mgmt_err(asp, xua); + case SUA_MGMT_NTFY: + return sua_rx_mgmt_ntfy(asp, xua); + default: + return SUA_ERR_UNSUPP_MSG_TYPE; + } +} + +/* map from SUA ASPSM/ASPTM to xua_asp_fsm event */ +static const struct xua_msg_event_map sua_aspxm_map[] = { + { SUA_MSGC_ASPSM, SUA_ASPSM_UP, XUA_ASP_E_ASPSM_ASPUP }, + { SUA_MSGC_ASPSM, SUA_ASPSM_DOWN, XUA_ASP_E_ASPSM_ASPDN }, + { SUA_MSGC_ASPSM, SUA_ASPSM_BEAT, XUA_ASP_E_ASPSM_BEAT }, + { SUA_MSGC_ASPSM, SUA_ASPSM_UP_ACK, XUA_ASP_E_ASPSM_ASPUP_ACK }, + { SUA_MSGC_ASPSM, SUA_ASPSM_DOWN_ACK, XUA_ASP_E_ASPSM_ASPDN_ACK }, + { SUA_MSGC_ASPSM, SUA_ASPSM_BEAT_ACK, XUA_ASP_E_ASPSM_BEAT_ACK }, + { SUA_MSGC_ASPTM, SUA_ASPTM_ACTIVE, XUA_ASP_E_ASPTM_ASPAC }, + { SUA_MSGC_ASPTM, SUA_ASPTM_INACTIVE, XUA_ASP_E_ASPTM_ASPIA }, + { SUA_MSGC_ASPTM, SUA_ASPTM_ACTIVE_ACK, XUA_ASP_E_ASPTM_ASPAC_ACK }, + { SUA_MSGC_ASPTM, SUA_ASPTM_INACTIVE_ACK, XUA_ASP_E_ASPTM_ASPIA_ACK }, +}; + +static int sua_rx_asp(struct osmo_ss7_asp *asp, struct xua_msg *xua) +{ + int event; + + /* map from the SUA message class and message type to the XUA + * ASP FSM event number */ + event = xua_msg_event_map(xua, sua_aspxm_map, + ARRAY_SIZE(sua_aspxm_map)); + if (event < 0) + return SUA_ERR_UNSUPP_MSG_TYPE; + + /* deliver that event to the ASP FSM */ + osmo_fsm_inst_dispatch(asp->fi, event, xua); + + return 0; +} + +/*! \brief process SUA message received from socket + * \param[in] asp Application Server Process receiving \ref msg + * \param[in] msg received message buffer + * \returns 0 on success; negative on error */ +int sua_rx_msg(struct osmo_ss7_asp *asp, struct msgb *msg) +{ + struct xua_msg *xua = NULL, *err = NULL; + int rc = 0; + + OSMO_ASSERT(asp->cfg.proto == OSMO_SS7_ASP_PROT_SUA); + + /* caller owns msg memory, we shall neither free it here nor + * keep references beyon the execution of this function and its + * callees. */ + + if (!asp->inst->sccp) { + LOGP(DLSUA, LOGL_ERROR, "%s(asp->inst->sccp=NULL)\n", __func__); return -EIO; } - LOGP(DSUA, LOGL_DEBUG, "Received SUA Message (%s)\n", + xua = xua_from_msg(1, msgb_length(msg), msg->data); + if (!xua) { + struct xua_common_hdr *hdr = (struct xua_common_hdr *) msg->data; + + LOGPASP(asp, DLSUA, LOGL_ERROR, "Unable to parse incoming " + "SUA message\n"); + + if (hdr->version != SUA_VERSION) + err = sua_gen_error_msg(SUA_ERR_INVALID_VERSION, msg); + else + err = sua_gen_error_msg(SUA_ERR_PARAM_FIELD_ERR, msg); + goto out; + } + +#if 0 + xua->mtp.opc = ; + xua->mtp.dpc = ; +#endif + xua->mtp.sio = MTP_SI_SCCP; + + LOGPASP(asp, DLSUA, LOGL_DEBUG, "Received SUA Message (%s)\n", xua_hdr_dump(xua, &xua_dialect_sua)); - if (!xua_dialect_check_all_mand_ies(&xua_dialect_sua, xua)) - return -1; + if (!xua_dialect_check_all_mand_ies(&xua_dialect_sua, xua)) { + /* FIXME: Return error? */ + err = sua_gen_error_msg(SUA_ERR_MISSING_PARAM, msg); + goto out; + } + + /* TODO: check for SCTP Strema ID */ + /* TODO: check if any AS configured in ASP */ + /* TODO: check for valid routing context */ switch (xua->hdr.msg_class) { case SUA_MSGC_CL: - rc = sua_rx_cl(link, xua, msg); + rc = sua_rx_cl(asp, xua); break; case SUA_MSGC_CO: - rc = sua_rx_co(link, xua, msg); + rc = sua_rx_co(asp, xua); break; - case SUA_MSGC_MGMT: - case SUA_MSGC_SNM: case SUA_MSGC_ASPSM: case SUA_MSGC_ASPTM: + rc = sua_rx_asp(asp, xua); + break; + case SUA_MSGC_MGMT: + rc = sua_rx_mgmt(asp, xua); + break; + case SUA_MSGC_SNM: case SUA_MSGC_RKM: /* FIXME */ + LOGPASP(asp, DLSUA, LOGL_NOTICE, "Received unsupported SUA " + "Message Class %u\n", xua->hdr.msg_class); + err = sua_gen_error_msg(SUA_ERR_UNSUPP_MSG_CLASS, msg); + break; default: + LOGPASP(asp, DLSUA, LOGL_NOTICE, "Received unknown SUA " + "Message Class %u\n", xua->hdr.msg_class); + err = sua_gen_error_msg(SUA_ERR_UNSUPP_MSG_CLASS, msg); break; } + + if (rc > 0) + err = sua_gen_error_msg(rc, msg); + +out: + if (err) + sua_tx_xua_asp(asp, err); xua_msg_free(xua); return rc; } -/*********************************************************************** - * libosmonetif integration - ***********************************************************************/ - -#include -#include - -static const struct value_string sctp_assoc_chg_vals[] = { - { SCTP_COMM_UP, "COMM_UP" }, - { SCTP_COMM_LOST, "COMM_LOST" }, - { SCTP_RESTART, "RESTART" }, - { SCTP_SHUTDOWN_COMP, "SHUTDOWN_COMP" }, - { SCTP_CANT_STR_ASSOC, "CANT_STR_ASSOC" }, - { 0, NULL } -}; - -static const struct value_string sctp_sn_type_vals[] = { - { SCTP_ASSOC_CHANGE, "ASSOC_CHANGE" }, - { SCTP_PEER_ADDR_CHANGE, "PEER_ADDR_CHANGE" }, - { SCTP_SHUTDOWN_EVENT, "SHUTDOWN_EVENT" }, - { SCTP_SEND_FAILED, "SEND_FAILED" }, - { SCTP_REMOTE_ERROR, "REMOTE_ERROR" }, - { SCTP_PARTIAL_DELIVERY_EVENT, "PARTIAL_DELIVERY_EVENT" }, - { SCTP_ADAPTATION_INDICATION, "ADAPTATION_INDICATION" }, -#ifdef SCTP_AUTHENTICATION_INDICATION - { SCTP_AUTHENTICATION_INDICATION, "UTHENTICATION_INDICATION" }, -#endif -#ifdef SCTP_SENDER_DRY_EVENT - { SCTP_SENDER_DRY_EVENT, "SENDER_DRY_EVENT" }, -#endif - { 0, NULL } -}; - -static int get_logevel_by_sn_type(int sn_type) -{ - switch (sn_type) { - case SCTP_ADAPTATION_INDICATION: - case SCTP_PEER_ADDR_CHANGE: -#ifdef SCTP_AUTHENTICATION_INDICATION - case SCTP_AUTHENTICATION_INDICATION: -#endif -#ifdef SCTP_SENDER_DRY_EVENT - case SCTP_SENDER_DRY_EVENT: -#endif - return LOGL_INFO; - case SCTP_ASSOC_CHANGE: - return LOGL_NOTICE; - case SCTP_SHUTDOWN_EVENT: - case SCTP_PARTIAL_DELIVERY_EVENT: - return LOGL_NOTICE; - case SCTP_SEND_FAILED: - case SCTP_REMOTE_ERROR: - return LOGL_ERROR; - default: - return LOGL_NOTICE; - } -} - -static void log_sctp_notification(int fd, const char *pfx, - union sctp_notification *notif) -{ - int log_level; - char *conn_id = osmo_sock_get_name(NULL, fd); - - LOGP(DSUA, LOGL_INFO, "%s %s SCTP NOTIFICATION %u flags=0x%0x\n", - conn_id, pfx, notif->sn_header.sn_type, - notif->sn_header.sn_flags); - - log_level = get_logevel_by_sn_type(notif->sn_header.sn_type); - - switch (notif->sn_header.sn_type) { - case SCTP_ASSOC_CHANGE: - LOGP(DSUA, log_level, "%s %s SCTP_ASSOC_CHANGE: %s\n", - conn_id, pfx, get_value_string(sctp_assoc_chg_vals, - notif->sn_assoc_change.sac_state)); - break; - default: - LOGP(DSUA, log_level, "%s %s %s\n", - conn_id, pfx, get_value_string(sctp_sn_type_vals, - notif->sn_header.sn_type)); - break; - } - - talloc_free(conn_id); -} - -/* netif code tells us we can read something from the socket */ -static int sua_srv_conn_cb(struct osmo_stream_srv *conn) -{ - struct osmo_fd *ofd = osmo_stream_srv_get_ofd(conn); - struct osmo_sccp_link *link = osmo_stream_srv_get_data(conn); - struct msgb *msg = msgb_alloc(SUA_MSGB_SIZE, "SUA Server Rx"); - struct sctp_sndrcvinfo sinfo; - unsigned int ppid; - int flags = 0; - int rc; - - if (!msg) - return -ENOMEM; - - /* read SUA message from socket and process it */ - rc = sctp_recvmsg(ofd->fd, msgb_data(msg), msgb_tailroom(msg), - NULL, NULL, &sinfo, &flags); - LOGP(DSUA, LOGL_DEBUG, "sua_srv_conn_cb(): sctp_recvmsg() returned %d\n", - rc); - if (rc < 0) { - close(ofd->fd); - osmo_fd_unregister(ofd); - ofd->fd = -1; - return rc; - } else if (rc == 0) { - close(ofd->fd); - osmo_fd_unregister(ofd); - ofd->fd = -1; - } else { - msgb_put(msg, rc); - } - - if (flags & MSG_NOTIFICATION) { - union sctp_notification *notif = (union sctp_notification *) msgb_data(msg); - - log_sctp_notification(ofd->fd, "SUA SRV", notif); - - switch (notif->sn_header.sn_type) { - case SCTP_SHUTDOWN_EVENT: - close(ofd->fd); - osmo_fd_unregister(ofd); - ofd->fd = -1; - break; - default: - break; - } - msgb_free(msg); - return 0; - } - - ppid = ntohl(sinfo.sinfo_ppid); - msgb_sctp_ppid(msg) = ppid; - msgb_sctp_stream(msg) = ntohl(sinfo.sinfo_stream); - msg->dst = link; - - switch (ppid) { - case SUA_PPID: - rc = sua_rx_msg(link, msg); - break; - default: - LOGP(DSUA, LOGL_NOTICE, "SCTP chunk for unknown PPID %u " - "received\n", ppid); - rc = 0; - break; - } - - msgb_free(msg); - return rc; -} - -static int sua_srv_conn_closed_cb(struct osmo_stream_srv *srv) -{ - struct osmo_sccp_link *sual = osmo_stream_srv_get_data(srv); - struct sua_connection *conn; - - LOGP(DSUA, LOGL_INFO, "SCTP connection closed\n"); - - /* remove from per-user list of sua links */ - llist_del(&sual->list); - - llist_for_each_entry(conn, &sual->connections, list) { - /* FIXME: send RELEASE request */ - } - talloc_free(sual); - osmo_stream_srv_set_data(srv, NULL); - - return 0; -} - -static int sua_accept_cb(struct osmo_stream_srv_link *link, int fd) -{ - struct osmo_sccp_user *user = osmo_stream_srv_link_get_data(link); - struct osmo_stream_srv *srv; - struct osmo_sccp_link *sual; - - LOGP(DSUA, LOGL_INFO, "New SCTP connection accepted\n"); - - srv = osmo_stream_srv_create(user, link, fd, - sua_srv_conn_cb, - sua_srv_conn_closed_cb, NULL); - if (!srv) { - close(fd); - return -1; - } - - /* create new SUA link and connect both data structures */ - sual = sua_link_new(user, 1); - if (!sual) { - osmo_stream_srv_destroy(srv); - return -1; - } - sual->data = srv; - osmo_stream_srv_set_data(srv, sual); - - return 0; -} - -int osmo_sua_server_listen(struct osmo_sccp_user *user, const char *hostname, uint16_t port) -{ - int rc; - - if (user->server) - osmo_stream_srv_link_close(user->server); - else { - user->server = osmo_stream_srv_link_create(user); - osmo_stream_srv_link_set_data(user->server, user); - osmo_stream_srv_link_set_accept_cb(user->server, sua_accept_cb); - } - - osmo_stream_srv_link_set_addr(user->server, hostname); - osmo_stream_srv_link_set_port(user->server, port); - osmo_stream_srv_link_set_proto(user->server, IPPROTO_SCTP); - - rc = osmo_stream_srv_link_open(user->server); - if (rc < 0) { - osmo_stream_srv_link_destroy(user->server); - user->server = NULL; - return rc; - } - - return 0; -} - -/* netif code tells us we can read something from the socket */ -static int sua_cli_read_cb(struct osmo_stream_cli *conn) -{ - struct osmo_fd *ofd = osmo_stream_cli_get_ofd(conn); - struct osmo_sccp_link *link = osmo_stream_cli_get_data(conn); - struct msgb *msg = msgb_alloc(SUA_MSGB_SIZE, "SUA Client Rx"); - struct sctp_sndrcvinfo sinfo; - unsigned int ppid; - int flags = 0; - int rc; - - LOGP(DSUA, LOGL_DEBUG, "sua_cli_read_cb() rx\n"); - - if (!msg) - return -ENOMEM; - - /* read SUA message from socket and process it */ - rc = sctp_recvmsg(ofd->fd, msgb_data(msg), msgb_tailroom(msg), - NULL, NULL, &sinfo, &flags); - if (rc < 0) { - close(ofd->fd); - osmo_fd_unregister(ofd); - ofd->fd = -1; - return rc; - } else if (rc == 0) { - close(ofd->fd); - osmo_fd_unregister(ofd); - ofd->fd = -1; - } else { - msgb_put(msg, rc); - } - - if (flags & MSG_NOTIFICATION) { - union sctp_notification *notif = (union sctp_notification *) msgb_data(msg); - - log_sctp_notification(ofd->fd, "SUA CLNT", notif); - - switch (notif->sn_header.sn_type) { - case SCTP_SHUTDOWN_EVENT: - close(ofd->fd); - osmo_fd_unregister(ofd); - ofd->fd = -1; - break; - default: - break; - } - msgb_free(msg); - return 0; - } - - ppid = ntohl(sinfo.sinfo_ppid); - msgb_sctp_ppid(msg) = ppid; - msgb_sctp_stream(msg) = ntohl(sinfo.sinfo_stream); - msg->dst = link; - - switch (ppid) { - case SUA_PPID: - rc = sua_rx_msg(link, msg); - break; - default: - LOGP(DSUA, LOGL_NOTICE, "SCTP chunk for unknown PPID %u " - "received\n", ppid); - rc = 0; - break; - } - - msgb_free(msg); - return rc; -} - -int osmo_sua_client_connect(struct osmo_sccp_user *user, const char *hostname, uint16_t port) -{ - struct osmo_stream_cli *cli; - struct osmo_sccp_link *sual; - int rc; - - cli = osmo_stream_cli_create(user); - if (!cli) - return -1; - osmo_stream_cli_set_addr(cli, hostname); - osmo_stream_cli_set_port(cli, port); - osmo_stream_cli_set_proto(cli, IPPROTO_SCTP); - osmo_stream_cli_set_reconnect_timeout(cli, 5); - osmo_stream_cli_set_read_cb(cli, sua_cli_read_cb); - - /* create SUA link and associate it with stream_cli */ - sual = sua_link_new(user, 0); - if (!sual) { - osmo_stream_cli_destroy(cli); - return -1; - } - sual->data = cli; - osmo_stream_cli_set_data(cli, sual); - - rc = osmo_stream_cli_open2(cli, 1); - if (rc < 0) { - sua_link_destroy(sual); - osmo_stream_cli_destroy(cli); - return rc; - } - user->client = cli; - - return 0; -} - -struct osmo_sccp_link *osmo_sua_client_get_link(struct osmo_sccp_user *user) -{ - return osmo_stream_cli_get_data(user->client); -} - -static LLIST_HEAD(sua_users); - -struct osmo_sccp_user *osmo_sua_user_create(void *ctx, osmo_prim_cb prim_cb, - void *priv) -{ - struct osmo_sccp_user *user = talloc_zero(ctx, struct osmo_sccp_user); - - user->prim_cb = prim_cb; - user->priv = priv; - INIT_LLIST_HEAD(&user->links); - - llist_add_tail(&user->list, &sua_users); - - return user; -} - -void *osmo_sccp_link_get_user_priv(struct osmo_sccp_link *slink) -{ - return slink->user->priv; -} - -void osmo_sua_user_destroy(struct osmo_sccp_user *user) -{ - struct osmo_sccp_link *link; - - llist_del(&user->list); - - llist_for_each_entry(link, &user->links, list) - sua_link_destroy(link); - - talloc_free(user); -} - -void osmo_sua_set_log_area(int area) -{ - xua_set_log_area(area); - DSUA = area; -} diff --git a/src/xua_internal.h b/src/xua_internal.h index 66b5a26..c6f79b7 100644 --- a/src/xua_internal.h +++ b/src/xua_internal.h @@ -15,6 +15,8 @@ struct xua_msg *osmo_sccp_to_xua(struct msgb *msg); struct msgb *osmo_sua_to_sccp(struct xua_msg *xua); +int sua_rx_msg(struct osmo_ss7_asp *asp, struct msgb *msg); + int sua_tx_xua_as(struct osmo_ss7_as *as, struct xua_msg *xua); struct osmo_mtp_prim *m3ua_to_xfer_ind(struct xua_msg *xua); -- To view, visit https://gerrit.osmocom.org/2218 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I193b74f58aa70c443ae17e78b5604246d6bc3f71 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Mon Apr 3 20:22:11 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 3 Apr 2017 20:22:11 +0000 Subject: [PATCH] libosmo-sccp[master]: Add example program how to use M3UA+SCCP client and server Message-ID: Review at https://gerrit.osmocom.org/2219 Add example program how to use M3UA+SCCP client and server This is an example tool that can be run either as server (SG) or as client (ASP) with a SCCP+M3UA stacking, and communicate via connectionless and connection-oriented primitives over it Change-Id: Id698ce2da5726e304dfa1773b794671dc80d853c --- M .gitignore M Makefile.am M configure.ac A examples/Makefile.am A examples/internal.h A examples/m3ua_example.c A examples/sccp_test_server.c A examples/sccp_test_vty.c 8 files changed, 393 insertions(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/19/2219/1 diff --git a/.gitignore b/.gitignore index 9d1435f..83f1333 100644 --- a/.gitignore +++ b/.gitignore @@ -60,6 +60,7 @@ tests/testsuite tests/testsuite.log +examples/m3ua_example *.pc config.* diff --git a/Makefile.am b/Makefile.am index b1eff56..dd73ec2 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,7 +1,7 @@ AUTOMAKE_OPTIONS = foreign dist-bzip2 1.6 AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -SUBDIRS = include src tests +SUBDIRS = include src tests examples pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = libosmo-sccp.pc libosmo-mtp.pc libosmo-sigtran.pc libosmo-xua.pc diff --git a/configure.ac b/configure.ac index c7c2b3b..aba34a2 100644 --- a/configure.ac +++ b/configure.ac @@ -27,6 +27,7 @@ PKG_PROG_PKG_CONFIG([0.20]) PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 0.3.0) +PKG_CHECK_MODULES(LIBOSMOVTY, libosmovty >= 0.3.0) PKG_CHECK_MODULES(LIBOSMONETIF, libosmo-netif >= 0.0.6) # The following test is taken from WebKit's webkit.m4 @@ -57,5 +58,6 @@ tests/m2ua/Makefile tests/xua/Makefile tests/ss7/Makefile + examples/Makefile Makefile) diff --git a/examples/Makefile.am b/examples/Makefile.am new file mode 100644 index 0000000..6418aca --- /dev/null +++ b/examples/Makefile.am @@ -0,0 +1,11 @@ +AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include +AM_CFLAGS=-Wall -g $(LIBOSMOCORE_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(LIBOSMONETIF_CFLAGS) $(COVERAGE_FLAGS) +AM_LDFLAGS=$(COVERAGE_LDFLAGS) + +noinst_HEADERS = internal.h + +noinst_PROGRAMS = m3ua_example + +m3ua_example_SOURCES = m3ua_example.c sccp_test_server.c sccp_test_vty.c +m3ua_example_LDADD = $(top_builddir)/src/libosmo-sigtran.la \ + $(LIBOSMOCORE_LIBS) $(LIBOSMOVTY_LIBS) diff --git a/examples/internal.h b/examples/internal.h new file mode 100644 index 0000000..70b9058 --- /dev/null +++ b/examples/internal.h @@ -0,0 +1,12 @@ +#pragma once + +#define SSN_TEST_UNUSED 200 +#define SSN_TEST_REFUSE 201 +#define SSN_TEST_ECHO 202 +#define SSN_TEST_CALLBACK 203 + +struct osmo_sccp_user; + +int sccp_test_user_vty_install(struct osmo_sccp_instance *inst, int ssn); + +int sccp_test_server_init(struct osmo_sccp_instance *sccp); diff --git a/examples/m3ua_example.c b/examples/m3ua_example.c new file mode 100644 index 0000000..710af7b --- /dev/null +++ b/examples/m3ua_example.c @@ -0,0 +1,99 @@ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "internal.h" + +static struct osmo_sccp_instance *sua_server_helper(void) +{ + struct osmo_sccp_instance *sccp; + + sccp = osmo_sccp_simple_server(NULL, 1, OSMO_SS7_ASP_PROT_M3UA, + -1, "127.0.0.2"); + + osmo_sccp_simple_server_add_clnt(sccp, OSMO_SS7_ASP_PROT_M3UA, + "23", 23, -1, 0, NULL); + + return sccp; +} + +/*********************************************************************** + * Initialization + ***********************************************************************/ + +static const struct log_info_cat log_info_cat[] = { +}; + +static const struct log_info log_info = { + .cat = log_info_cat, + .num_cat = ARRAY_SIZE(log_info_cat), +}; + +static void init_logging(void) +{ + const int log_cats[] = { DLSS7, DLSUA, DLM3UA, DLSCCP, DLINP }; + unsigned int i; + + osmo_init_logging(&log_info); + + for (i = 0; i < ARRAY_SIZE(log_cats); i++) + log_set_category_filter(osmo_stderr_target, log_cats[i], 1, LOGL_DEBUG); +} + +static struct vty_app_info vty_info = { + .name = "sccp-test", + .version = 0, +}; + +int main(int argc, char **argv) +{ + struct osmo_sccp_instance *sccp; + bool client; + int rc; + + init_logging(); + osmo_ss7_init(); + osmo_fsm_log_addr(false); + vty_init(&vty_info); + + if (argc <= 1) + client = true; + else + client = false; + + rc = telnet_init_dynif(NULL, NULL, vty_get_bind_addr(), 2324+client); + if (rc < 0) { + perror("Erro binding VTY port\n"); + exit(1); + } + + + if (client) { + sccp = osmo_sccp_simple_client(NULL, "client", 23, OSMO_SS7_ASP_PROT_M3UA, 0, M3UA_PORT, "127.0.0.2"); + sccp_test_user_vty_install(sccp, OSMO_SCCP_SSN_BSC_BSSAP); + } else { + sccp = sua_server_helper(); + sccp_test_server_init(sccp); + } + + while (1) { + osmo_select_main(0); + } +} diff --git a/examples/sccp_test_server.c b/examples/sccp_test_server.c new file mode 100644 index 0000000..c3c658f --- /dev/null +++ b/examples/sccp_test_server.c @@ -0,0 +1,115 @@ + +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include "internal.h" + +unsigned int conn_id; + +/* a simple SCCP User which refuses all connections and discards all + * unitdata */ +static int refuser_prim_cb(struct osmo_prim_hdr *oph, void *_scu) +{ + struct osmo_sccp_user *scu = _scu; + struct osmo_scu_prim *scu_prim = (struct osmo_scu_prim *) oph; + + switch (OSMO_PRIM_HDR(&scu_prim->oph)) { + case OSMO_PRIM(OSMO_SCU_PRIM_N_CONNECT, PRIM_OP_INDICATION): + printf("%s: refusing N-CONNECT.ind (local_ref=%u)\n", + __func__, scu_prim->u.connect.conn_id); + osmo_sccp_tx_disconn(scu, scu_prim->u.connect.conn_id, + &scu_prim->u.connect.called_addr, + 23); + break; + default: + printf("%s: Unknown primitive %u:%u\n", __func__, + oph->primitive, oph->operation); + break; + } + return 0; +} + +/* a simple SCCP User which accepts all connections and echos back all + * DATA + UNITDATA */ +static int echo_prim_cb(struct osmo_prim_hdr *oph, void *_scu) +{ + struct osmo_sccp_user *scu = _scu; + struct osmo_scu_prim *scu_prim = (struct osmo_scu_prim *) oph; + const uint8_t *data = msgb_l2(oph->msg); + unsigned int data_len = msgb_l2len(oph->msg); + + switch (OSMO_PRIM_HDR(&scu_prim->oph)) { + case OSMO_PRIM(OSMO_SCU_PRIM_N_CONNECT, PRIM_OP_INDICATION): + printf("%s: Accepting N-CONNECT.ind (local_ref=%u)\n", + __func__, scu_prim->u.connect.conn_id); + osmo_sccp_tx_conn_resp(scu, scu_prim->u.connect.conn_id, + &scu_prim->u.connect.called_addr, + data, data_len); + break; + case OSMO_PRIM(OSMO_SCU_PRIM_N_DATA, PRIM_OP_INDICATION): + printf("%s: Echoing N-DATA.ind (local_ref=%u)\n", + __func__, scu_prim->u.data.conn_id); + osmo_sccp_tx_data(scu, scu_prim->u.data.conn_id, + data, data_len); + break; + case OSMO_PRIM(OSMO_SCU_PRIM_N_UNITDATA, PRIM_OP_INDICATION): + printf("%s: Echoing N-UNITDATA.ind\n", __func__); + osmo_sccp_tx_unitdata(scu, &scu_prim->u.unitdata.called_addr, + &scu_prim->u.unitdata.calling_addr, + data, data_len); + break; + default: + printf("%s: Unknown primitive %u:%u\n", __func__, + oph->primitive, oph->operation); + break; + } + return 0; +} + +/* a simple SCCP User which receives UNITDATA messages and connects back + * to whoever sents UNITDATA and then echo's back all DATA */ +static int callback_prim_cb(struct osmo_prim_hdr *oph, void *_scu) +{ + struct osmo_sccp_user *scu = _scu; + struct osmo_scu_prim *scu_prim = (struct osmo_scu_prim *) oph; + const uint8_t *data = msgb_l2(oph->msg); + unsigned int data_len = msgb_l2len(oph->msg); + + switch (OSMO_PRIM_HDR(&scu_prim->oph)) { + case OSMO_PRIM(OSMO_SCU_PRIM_N_UNITDATA, PRIM_OP_INDICATION): + printf("%s: N-UNITDATA.ind: Connectiong back to sender\n", __func__); + osmo_sccp_tx_conn_req(scu, conn_id++, + &scu_prim->u.unitdata.called_addr, + &scu_prim->u.unitdata.calling_addr, + data, data_len); + break; + case OSMO_PRIM(OSMO_SCU_PRIM_N_DATA, PRIM_OP_INDICATION): + printf("%s: Echoing N-DATA.ind (local_ref=%u)\n", + __func__, scu_prim->u.data.conn_id); + osmo_sccp_tx_data(scu, scu_prim->u.data.conn_id, + data, data_len); + break; + default: + printf("%s: Unknown primitive %u:%u\n", __func__, + oph->primitive, oph->operation); + break; + } + return 0; +} + +int sccp_test_server_init(struct osmo_sccp_instance *sccp) +{ + osmo_sccp_user_bind(sccp, "refuser", &refuser_prim_cb, SSN_TEST_REFUSE); + osmo_sccp_user_bind(sccp, "echo", &echo_prim_cb, SSN_TEST_ECHO); + osmo_sccp_user_bind(sccp, "callback", &callback_prim_cb, SSN_TEST_CALLBACK); + + return 0; +} diff --git a/examples/sccp_test_vty.c b/examples/sccp_test_vty.c new file mode 100644 index 0000000..1134d57 --- /dev/null +++ b/examples/sccp_test_vty.c @@ -0,0 +1,152 @@ + +#include + +#include +#include + +#include +#include + +#include "internal.h" + +#define SCU_NODE 23 + +static struct osmo_sccp_user *g_scu; + +static struct osmo_sccp_addr g_calling_addr = { + .presence = OSMO_SCCP_ADDR_T_SSN | OSMO_SCCP_ADDR_T_PC, + .ri = OSMO_SCCP_RI_SSN_PC, + .pc = 23, +}; + +static struct osmo_sccp_addr g_called_addr = { + .presence = OSMO_SCCP_ADDR_T_SSN | OSMO_SCCP_ADDR_T_PC, + .ssn = 1, + .ri = OSMO_SCCP_RI_SSN_PC, + .pc = 1, +}; + +DEFUN(scu_called_ssn, scu_called_ssn_cmd, + "called-addr-ssn <0-255>", + "Set SSN of SCCP CalledAddress\n" + "SSN of SCCP CalledAddress\n") +{ + g_called_addr.ssn = atoi(argv[0]); + return CMD_SUCCESS; +} + +DEFUN(scu_conn_req, scu_conn_req_cmd, + "connect-req <0-16777216> [DATA]", + "N-CONNECT.req\n" + "Connection ID\n") +{ + struct osmo_sccp_user *scu = vty->index; + int conn_id = atoi(argv[0]); + const char *data = argv[1]; + + osmo_sccp_tx_conn_req(scu, conn_id, &g_calling_addr, &g_called_addr, + (const uint8_t *)data, data ? strlen(data)+1 : 0); + return CMD_SUCCESS; +} + +DEFUN(scu_conn_resp, scu_conn_resp_cmd, + "connect-resp <0-16777216> [DATA]", + "N-CONNET.resp\n" + "Connection ID\n") +{ + struct osmo_sccp_user *scu = vty->index; + int conn_id = atoi(argv[0]); + const char *data = argv[1]; + + osmo_sccp_tx_conn_resp(scu, conn_id, NULL, + (const uint8_t *)data, data ? strlen(data)+1 : 0); + return CMD_SUCCESS; +} + +DEFUN(scu_data_req, scu_data_req_cmd, + "data-req <0-16777216> DATA", + "N-DATA.req\n" + "Connection ID\n") +{ + struct osmo_sccp_user *scu = vty->index; + int conn_id = atoi(argv[0]); + const char *data = argv[1]; + + osmo_sccp_tx_data(scu, conn_id, (const uint8_t *)data, strlen(data)+1); + return CMD_SUCCESS; +} + +DEFUN(scu_unitdata_req, scu_unitdata_req_cmd, + "unitdata-req DATA", + "N-UNITDATA.req\n") +{ + struct osmo_sccp_user *scu = vty->index; + const char *data = argv[0]; + + osmo_sccp_tx_unitdata(scu, &g_calling_addr, &g_called_addr, + (const uint8_t *)data, strlen(data)+1); + return CMD_SUCCESS; +} + +DEFUN(scu_disc_req, scu_disc_req_cmd, + "disconnect-req <0-16777216>", + "N-DISCONNT.req\n" + "Connection ID\n") +{ + struct osmo_sccp_user *scu = vty->index; + int conn_id = atoi(argv[0]); + + osmo_sccp_tx_disconn(scu, conn_id, NULL, 42); + return CMD_SUCCESS; +} + +static struct cmd_node scu_node = { + SCU_NODE, + "%s(sccp-user)# ", + 1, +}; + +DEFUN(scu, scu_cmd, + "sccp-user", + "Enter SCCP User Node\n") +{ + vty->node = SCU_NODE; + vty->index = g_scu; + return CMD_SUCCESS; +} + +static int testclnt_prim_cb(struct osmo_prim_hdr *oph, void *_scu) +{ + struct osmo_sccp_user *scu = _scu; + struct osmo_scu_prim *scu_prim = (struct osmo_scu_prim *) oph; + + switch (OSMO_PRIM_HDR(&scu_prim->oph)) { + case OSMO_PRIM(OSMO_SCU_PRIM_N_CONNECT, PRIM_OP_INDICATION): + default: + break; + } + return 0; +} + + +int sccp_test_user_vty_install(struct osmo_sccp_instance *inst, int ssn) +{ + g_scu = osmo_sccp_user_bind(inst, "test_client_vty", testclnt_prim_cb, ssn); + if (!g_scu) + return -1; + + g_calling_addr.ssn = ssn; + + install_node(&scu_node, NULL); + vty_install_default(SCU_NODE); + install_element(SCU_NODE, &scu_called_ssn_cmd); + install_element(SCU_NODE, &scu_conn_req_cmd); + install_element(SCU_NODE, &scu_conn_resp_cmd); + install_element(SCU_NODE, &scu_data_req_cmd); + install_element(SCU_NODE, &scu_unitdata_req_cmd); + install_element(SCU_NODE, &scu_disc_req_cmd); + + install_element(ENABLE_NODE, &scu_cmd); + + return 0; +} -- To view, visit https://gerrit.osmocom.org/2219 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Id698ce2da5726e304dfa1773b794671dc80d853c Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Mon Apr 3 20:22:11 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 3 Apr 2017 20:22:11 +0000 Subject: [PATCH] libosmo-sccp[master]: xua: Remove library-internal DXUA log subsystem Message-ID: Review at https://gerrit.osmocom.org/2220 xua: Remove library-internal DXUA log subsystem We don't really need those thre log messages, and we can thus do away with the library-internal log-subsystem of DXUA. The rest of libosmo-sigtran uses the new globa DL... subsystems anyway Change-Id: Iea0d3db34a3674a9c6422b174a879bfdaa25786f --- M include/osmocom/sigtran/xua_msg.h M src/xua_msg.c 2 files changed, 2 insertions(+), 18 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/20/2220/1 diff --git a/include/osmocom/sigtran/xua_msg.h b/include/osmocom/sigtran/xua_msg.h index 320da6a..e0e1bcf 100644 --- a/include/osmocom/sigtran/xua_msg.h +++ b/include/osmocom/sigtran/xua_msg.h @@ -69,8 +69,6 @@ extern const struct xua_dialect xua_dialect_sua; extern const struct xua_dialect xua_dialect_m3ua; -extern int DXUA; - struct xua_msg *xua_msg_alloc(void); void xua_msg_free(struct xua_msg *msg); @@ -83,8 +81,6 @@ struct xua_msg *xua_from_msg(const int version, uint16_t len, uint8_t *data); struct msgb *xua_to_msg(const int version, struct xua_msg *msg); - -void xua_set_log_area(int log_area); int msgb_t16l16vp_put(struct msgb *msg, uint16_t tag, uint16_t len, const uint8_t *data); int msgb_t16l16vp_put_u32(struct msgb *msg, uint16_t tag, uint32_t val); diff --git a/src/xua_msg.c b/src/xua_msg.c index 27279ce..cb487c8 100644 --- a/src/xua_msg.c +++ b/src/xua_msg.c @@ -32,17 +32,14 @@ #include static void *tall_xua; -int DXUA = -1; struct xua_msg *xua_msg_alloc(void) { struct xua_msg *msg; msg = talloc_zero(tall_xua, struct xua_msg); - if (!msg) { - LOGP(DXUA, LOGL_ERROR, "Failed to allocate.\n"); + if (!msg) return NULL; - } INIT_LLIST_HEAD(&msg->headers); return msg; @@ -162,7 +159,6 @@ return msg; fail: - LOGP(DXUA, LOGL_ERROR, "Failed to parse.\n"); xua_msg_free(msg); return NULL; } @@ -175,10 +171,8 @@ uint8_t rest; msg = msgb_alloc_headroom(2048, 512, "xua msg"); - if (!msg) { - LOGP(DXUA, LOGL_ERROR, "Failed to allocate.\n"); + if (!msg) return NULL; - } msg->l2h = msgb_put(msg, sizeof(*hdr)); hdr = (struct xua_common_hdr *) msg->l2h; @@ -208,12 +202,6 @@ hdr->msg_length = htonl(msgb_l2len(msg)); return msg; } - -void xua_set_log_area(int log_area) -{ - DXUA = log_area; -} - /*********************************************************************** * Message encoding helper functions -- To view, visit https://gerrit.osmocom.org/2220 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Iea0d3db34a3674a9c6422b174a879bfdaa25786f Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Mon Apr 3 20:30:05 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 3 Apr 2017 20:30:05 +0000 Subject: libosmocore[master]: logging: Add log_info_cat for DLSS7/DLSCCP/DLSUA/DLM3UA In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2207 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I218aa4cb1fc7640a75663be29bac672dfa8770f5 Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Mon Apr 3 20:32:48 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 3 Apr 2017 20:32:48 +0000 Subject: libosmocore[master]: logging: Add log_info_cat for DLSS7/DLSCCP/DLSUA/DLM3UA In-Reply-To: References: Message-ID: Patch Set 1: Verified+1 -- To view, visit https://gerrit.osmocom.org/2207 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I218aa4cb1fc7640a75663be29bac672dfa8770f5 Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Mon Apr 3 20:32:51 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 3 Apr 2017 20:32:51 +0000 Subject: [MERGED] libosmocore[master]: logging: Add log_info_cat for DLSS7/DLSCCP/DLSUA/DLM3UA In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: logging: Add log_info_cat for DLSS7/DLSCCP/DLSUA/DLM3UA ...................................................................... logging: Add log_info_cat for DLSS7/DLSCCP/DLSUA/DLM3UA In Change-Id I61f452208088dc7097165deecef7c058ebb4bd4e we introduced the #defines but didn't introduce the new log_info_cat information. Change-Id: I218aa4cb1fc7640a75663be29bac672dfa8770f5 --- M src/logging.c 1 file changed, 20 insertions(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved; Verified diff --git a/src/logging.c b/src/logging.c index d900340..05d6b6d 100644 --- a/src/logging.c +++ b/src/logging.c @@ -140,6 +140,26 @@ .description = "Osmocom Authentication Protocol", .enabled = 1, .loglevel = LOGL_NOTICE, }, + [INT2IDX(DLSS7)] = { + .name = "DLSS7", + .description = "libosmo-sigtran Signalling System 7", + .enabled = 1, .loglevel = LOGL_NOTICE, + }, + [INT2IDX(DLSCCP)] = { + .name = "DLSCCP", + .description = "libosmo-sigtran SCCP Implementation", + .enabled = 1, .loglevel = LOGL_NOTICE, + }, + [INT2IDX(DLSUA)] = { + .name = "DLSUA", + .description = "libosmo-sigtran SCCP User Adaptation", + .enabled = 1, .loglevel = LOGL_NOTICE, + }, + [INT2IDX(DLM3UA)] = { + .name = "DLM3UA", + .description = "libosmo-sigtran MTP3 User Adaptation", + .enabled = 1, .loglevel = LOGL_NOTICE, + }, }; /*! \brief descriptive string for each log level */ -- To view, visit https://gerrit.osmocom.org/2207 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I218aa4cb1fc7640a75663be29bac672dfa8770f5 Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Apr 4 01:55:55 2017 From: gerrit-no-reply at lists.osmocom.org (Tom Tsou) Date: Tue, 4 Apr 2017 01:55:55 +0000 Subject: [PATCH] osmo-trx[master]: Configuration: Fix const and signedness compile warnings Message-ID: Review at https://gerrit.osmocom.org/2221 Configuration: Fix const and signedness compile warnings Change-Id: I701559814b2aee6f84f10e612f128da40f6a51c1 --- M CommonLibs/Configuration.cpp M CommonLibs/ConfigurationTest.cpp 2 files changed, 2 insertions(+), 2 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-trx refs/changes/21/2221/1 diff --git a/CommonLibs/Configuration.cpp b/CommonLibs/Configuration.cpp index bfff893..7ca193b 100644 --- a/CommonLibs/Configuration.cpp +++ b/CommonLibs/Configuration.cpp @@ -56,7 +56,7 @@ static std::string replaceAll(const std::string input, const std::string search, const std::string replace) { std::string output = input; - int index = 0; + size_t index = 0; while (true) { index = output.find(search, index); diff --git a/CommonLibs/ConfigurationTest.cpp b/CommonLibs/ConfigurationTest.cpp index 2fd43e9..7042228 100644 --- a/CommonLibs/ConfigurationTest.cpp +++ b/CommonLibs/ConfigurationTest.cpp @@ -47,7 +47,7 @@ gConfig.setUpdateHook(purgeConfig); - char *keys[5] = {"key1", "key2", "key3", "key4", "key5"}; + const char *keys[5] = {"key1", "key2", "key3", "key4", "key5"}; for (int i=0; i<5; i++) { gConfig.set(keys[i],i); -- To view, visit https://gerrit.osmocom.org/2221 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I701559814b2aee6f84f10e612f128da40f6a51c1 Gerrit-PatchSet: 1 Gerrit-Project: osmo-trx Gerrit-Branch: master Gerrit-Owner: Tom Tsou From gerrit-no-reply at lists.osmocom.org Tue Apr 4 10:01:03 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 4 Apr 2017 10:01:03 +0000 Subject: libosmo-abis[master]: configure: Fix compilation with new libortp In-Reply-To: References: Message-ID: Patch Set 2: for some reason this doens't work on FreeBSD 11.x with ortp-0.27. The configure script never any line regarding ortp domain and sets HAVE_ORTP_LOG_DOMAIN to 0, despite it being required. -- To view, visit https://gerrit.osmocom.org/2164 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I46e565f1873c7baf3c3b0aafe73951d20ce083b4 Gerrit-PatchSet: 2 Gerrit-Project: libosmo-abis Gerrit-Branch: master Gerrit-Owner: Pau Espin Pedrol Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Apr 4 11:43:10 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 4 Apr 2017 11:43:10 +0000 Subject: [PATCH] libosmo-sccp[master]: Add new 'osmo_ss7' SS7 core code with M3UA, ASP/AS FSM, ... In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2209 to look at the new patch set (#2). Add new 'osmo_ss7' SS7 core code with M3UA, ASP/AS FSM, ... This is what aims to be a rather complete/proper implementation of the SIGTRAN + SS7 protocol suite. It has proper abstraction between the layers with primitives, finite state machines for things like the AS and ASP state machines, support for point code routing, etc. What's not implemented at this point: * re-integration of pre-existing SUA (pending) * actual MTP2 and physical E1/T1 link support * different trafic modes like broadcast/fail-over/load-balance Change-Id: I375eb80f01acc013094851d91d1d3333ebc12bc7 --- M configure.ac M include/osmocom/sigtran/Makefile.am A include/osmocom/sigtran/osmo_ss7.h A include/osmocom/sigtran/protocol/mtp.h M include/osmocom/sigtran/sigtran_sap.h M src/Makefile.am A src/m3ua.c A src/osmo_ss7.c A src/osmo_ss7_hmrt.c A src/osmo_ss7_vty.c A src/xua_as_fsm.c A src/xua_as_fsm.h A src/xua_asp_fsm.c A src/xua_asp_fsm.h A src/xua_internal.h M tests/Makefile.am A tests/ss7/Makefile.am A tests/ss7/ss7_test.c A tests/ss7/ss7_test.err A tests/ss7/ss7_test.ok M tests/testsuite.at 21 files changed, 4,991 insertions(+), 4 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/09/2209/2 diff --git a/configure.ac b/configure.ac index 4c3c937..116e168 100644 --- a/configure.ac +++ b/configure.ac @@ -29,6 +29,17 @@ PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 0.3.0) PKG_CHECK_MODULES(LIBOSMONETIF, libosmo-netif >= 0.0.6) +old_LIBS=$LIBS +AC_SEARCH_LIBS([sctp_send], [sctp], [ + AC_DEFINE(HAVE_LIBSCTP, 1, [Define 1 to enable SCTP support]) + AC_SUBST(HAVE_LIBSCTP, [1]) + if test -n "$ac_lib"; then + AC_SUBST(LIBSCTP_LIBS, [-l$ac_lib]) + fi + ], [ + AC_MSG_ERROR([sctp_send not found in searched libs])]) +LIBS=$old_LIBS + # The following test is taken from WebKit's webkit.m4 saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -fvisibility=hidden " @@ -56,5 +67,6 @@ tests/mtp/Makefile tests/m2ua/Makefile tests/sigtran/Makefile + tests/ss7/Makefile Makefile) diff --git a/include/osmocom/sigtran/Makefile.am b/include/osmocom/sigtran/Makefile.am index 2f2912f..ca7a304 100644 --- a/include/osmocom/sigtran/Makefile.am +++ b/include/osmocom/sigtran/Makefile.am @@ -1,7 +1,7 @@ sigtran_HEADERS = xua_types.h xua_msg.h m2ua_types.h sccp_sap.h \ - sua.h sigtran_sap.h sccp_helpers.h mtp_sap.h + sua.h sigtran_sap.h sccp_helpers.h mtp_sap.h osmo_ss7.h sigtrandir = $(includedir)/osmocom/sigtran -sigtran_prot_HEADERS = protocol/sua.h protocol/m3ua.h +sigtran_prot_HEADERS = protocol/sua.h protocol/m3ua.h protocol/mtp.h sigtran_protdir = $(includedir)/osmocom/sigtran/protocol diff --git a/include/osmocom/sigtran/osmo_ss7.h b/include/osmocom/sigtran/osmo_ss7.h new file mode 100644 index 0000000..5bbcd65 --- /dev/null +++ b/include/osmocom/sigtran/osmo_ss7.h @@ -0,0 +1,408 @@ +#pragma once + +#include +#include + +#include +#include +#include +#include +#include + +struct osmo_ss7_instance; +struct osmo_ss7_user; +struct osmo_sccp_instance; +struct osmo_mtp_prim; + +int osmo_ss7_init(void); + +bool osmo_ss7_pc_is_local(struct osmo_ss7_instance *inst, uint32_t pc); +int osmo_ss7_pointcode_parse(struct osmo_ss7_instance *inst, const char *str); +int osmo_ss7_pointcode_parse_mask_or_len(struct osmo_ss7_instance *inst, const char *in); +const char *osmo_ss7_pointcode_print(struct osmo_ss7_instance *inst, uint32_t pc); + +/*********************************************************************** + * SS7 Routing Tables + ***********************************************************************/ + +struct osmo_ss7_route_table { + /*! member in list of routing tables */ + struct llist_head list; + /*! \ref osmo_ss7_instance to which we belong */ + struct osmo_ss7_instance *inst; + /*! list of \ref osmo_ss7_route */ + struct llist_head routes; + + struct { + char *name; + char *description; + } cfg; +}; + +struct osmo_ss7_route_table * +osmo_ss7_route_table_find(struct osmo_ss7_instance *inst, const char *name); +struct osmo_ss7_route_table * +osmo_ss7_route_table_find_or_create(struct osmo_ss7_instance *inst, const char *name); +void osmo_ss7_route_table_destroy(struct osmo_ss7_route_table *rtbl); + +/*********************************************************************** + * SS7 Instances + ***********************************************************************/ + +struct osmo_ss7_instance { + /*! member of global list of instances */ + struct llist_head list; + /*! list of \ref osmo_ss7_linkset */ + struct llist_head linksets; + /*! list of \ref osmo_ss7_as */ + struct llist_head as_list; + /*! list of \ref osmo_ss7_asp */ + struct llist_head asp_list; + /*! list of \ref osmo_ss7_route_table */ + struct llist_head rtable_list; + /* array for faster lookup of user (indexed by service + * indicator) */ + const struct osmo_ss7_user *user[16]; + + struct osmo_ss7_route_table *rtable_system; + + struct osmo_sccp_instance *sccp; + + struct { + uint32_t id; + char *name; + char *description; + uint32_t primary_pc; + /* secondary PCs */ + /* capability PCs */ + uint8_t network_indicator; + struct { + char delimiter; + uint8_t component_len[3]; + } pc_fmt; + } cfg; +}; + +struct osmo_ss7_instance *osmo_ss7_instance_find(uint32_t id); +struct osmo_ss7_instance * +osmo_ss7_instance_find_or_create(void *ctx, uint32_t id); +void osmo_ss7_instance_destroy(struct osmo_ss7_instance *inst); +int osmo_ss7_instance_set_pc_fmt(struct osmo_ss7_instance *inst, + uint8_t c0, uint8_t c1, uint8_t c2); + +/*********************************************************************** + * MTP Users (Users of MTP, such as SCCP or ISUP) + ***********************************************************************/ + +struct osmo_ss7_user { + /* pointer back to SS7 instance */ + struct osmo_ss7_instance *inst; + /* name of the user */ + const char *name; + /* primitive call-back for incoming MTP primitives */ + osmo_prim_cb prim_cb; + /* private data */ + void *priv; +}; + +int osmo_ss7_user_register(struct osmo_ss7_instance *inst, uint8_t service_ind, + struct osmo_ss7_user *user); + +int osmo_ss7_user_unregister(struct osmo_ss7_instance *inst, uint8_t service_ind, + struct osmo_ss7_user *user); + +int osmo_ss7_mtp_to_user(struct osmo_ss7_instance *inst, struct osmo_mtp_prim *omp); + +/* SS7 User wants to issue MTP-TRANSFER.req */ +int osmo_ss7_user_mtp_xfer_req(struct osmo_ss7_instance *inst, + struct osmo_mtp_prim *omp); + +/*********************************************************************** + * SS7 Links + ***********************************************************************/ + +enum osmo_ss7_link_adm_state { + OSMO_SS7_LS_SHUTDOWN, + OSMO_SS7_LS_INHIBITED, + OSMO_SS7_LS_ENABLED, + _NUM_OSMO_SS7_LS +}; + +struct osmo_ss7_linkset; +struct osmo_ss7_link; + +struct osmo_ss7_link { + /*! \ref osmo_ss7_linkset to which we belong */ + struct osmo_ss7_linkset *linkset; + struct { + char *name; + char *description; + uint32_t id; + + enum osmo_ss7_link_adm_state adm_state; + } cfg; +}; + +void osmo_ss7_link_destroy(struct osmo_ss7_link *link); +struct osmo_ss7_link * +osmo_ss7_link_find_or_create(struct osmo_ss7_linkset *lset, uint32_t id); + +/*********************************************************************** + * SS7 Linksets + ***********************************************************************/ + +struct osmo_ss7_linkset { + struct llist_head list; + /*! \ref osmo_ss7_instance to which we belong */ + struct osmo_ss7_instance *inst; + /*! array of \ref osmo_ss7_link */ + struct osmo_ss7_link *links[16]; + + struct { + char *name; + char *description; + uint32_t adjacent_pc; + uint32_t local_pc; + } cfg; +}; + +void osmo_ss7_linkset_destroy(struct osmo_ss7_linkset *lset); +struct osmo_ss7_linkset * +osmo_ss7_linkset_find_by_name(struct osmo_ss7_instance *inst, const char *name); +struct osmo_ss7_linkset * +osmo_ss7_linkset_find_or_create(struct osmo_ss7_instance *inst, const char *name, uint32_t pc); + + +/*********************************************************************** + * SS7 Routes + ***********************************************************************/ + +struct osmo_ss7_route { + /*! member in \ref osmo_ss7_route_table.routes */ + struct llist_head list; + /*! \ref osmo_ss7_route_table to which we belong */ + struct osmo_ss7_route_table *rtable; + + struct { + /*! pointer to linkset (destination) of route */ + struct osmo_ss7_linkset *linkset; + /*! pointer to Application Server */ + struct osmo_ss7_as *as; + } dest; + + struct { + /* FIXME: presence? */ + uint32_t pc; + uint32_t mask; + /*! human-specified linkset name */ + char *linkset_name; + /*! lower priority is higher */ + uint32_t priority; + uint8_t qos_class; + } cfg; +}; + +struct osmo_ss7_route * +osmo_ss7_route_find_dpc(struct osmo_ss7_route_table *rtbl, uint32_t dpc); +struct osmo_ss7_route * +osmo_ss7_route_find_dpc_mask(struct osmo_ss7_route_table *rtbl, uint32_t dpc, + uint32_t mask); +struct osmo_ss7_route * +osmo_ss7_route_lookup(struct osmo_ss7_instance *inst, uint32_t dpc); +struct osmo_ss7_route * +osmo_ss7_route_create(struct osmo_ss7_route_table *rtbl, uint32_t dpc, + uint32_t mask, const char *linkset_name); +void osmo_ss7_route_destroy(struct osmo_ss7_route *rt); + + +/*********************************************************************** + * SS7 Application Servers + ***********************************************************************/ + +struct osmo_ss7_routing_key { + uint32_t context; + + uint32_t pc; + uint8_t si; + uint32_t ssn; + /* FIXME: more complex routing keys */ +}; + +enum osmo_ss7_as_traffic_mode { + OSMO_SS7_AS_TMOD_BCAST, + OSMO_SS7_AS_TMOD_LOADSHARE, + OSMO_SS7_AS_TMOD_ROUNDROBIN, + OSMO_SS7_AS_TMOD_OVERRIDE, + _NUM_OSMO_SS7_ASP_TMOD +}; + +extern struct value_string osmo_ss7_as_traffic_mode_vals[]; + +static inline const char * +osmo_ss7_as_traffic_mode_name(enum osmo_ss7_as_traffic_mode mode) +{ + return get_value_string(osmo_ss7_as_traffic_mode_vals, mode); +} + +enum osmo_ss7_asp_protocol { + OSMO_SS7_ASP_PROT_NONE, + OSMO_SS7_ASP_PROT_SUA, + OSMO_SS7_ASP_PROT_M3UA, + _NUM_OSMO_SS7_ASP_PROT +}; + +extern struct value_string osmo_ss7_asp_protocol_vals[]; + +static inline const char * +osmo_ss7_asp_protocol_name(enum osmo_ss7_asp_protocol mode) +{ + return get_value_string(osmo_ss7_asp_protocol_vals, mode); +} + +int osmo_ss7_asp_protocol_port(enum osmo_ss7_asp_protocol prot); + +struct osmo_ss7_as { + /*! entry in 'ref osmo_ss7_instance.as_list */ + struct llist_head list; + struct osmo_ss7_instance *inst; + + /*! AS FSM */ + struct osmo_fsm_inst *fi; + + struct { + char *name; + char *description; + enum osmo_ss7_asp_protocol proto; + struct osmo_ss7_routing_key routing_key; + enum osmo_ss7_as_traffic_mode mode; + uint32_t recovery_timeout_msec; + uint8_t qos_class; + + struct osmo_ss7_asp *asps[16]; + } cfg; +}; + +struct osmo_ss7_as * +osmo_ss7_as_find_by_name(struct osmo_ss7_instance *inst, const char *name); +struct osmo_ss7_as * +osmo_ss7_as_find_by_rctx(struct osmo_ss7_instance *inst, uint32_t rctx); +struct osmo_ss7_as * +osmo_ss7_as_find_or_create(struct osmo_ss7_instance *inst, const char *name, + enum osmo_ss7_asp_protocol proto); +int osmo_ss7_as_add_asp(struct osmo_ss7_as *as, const char *asp_name); +int osmo_ss7_as_del_asp(struct osmo_ss7_as *as, const char *asp_name); +void osmo_ss7_as_destroy(struct osmo_ss7_as *as); +bool osmo_ss7_as_has_asp(struct osmo_ss7_as *as, + struct osmo_ss7_asp *asp); + + +/*********************************************************************** + * SS7 Application Server Processes + ***********************************************************************/ + +struct osmo_ss7_asp_peer { + char *host; + uint16_t port; +}; + +enum osmo_ss7_asp_admin_state { + /*! no SCTP association with peer */ + OSMO_SS7_ASP_ADM_S_SHUTDOWN, + /*! SCP association, but reject ASP-ACTIVE */ + OSMO_SS7_ASP_ADM_S_BLOCKED, + /*! in normal operation */ + OSMO_SS7_ASP_ADM_S_ENABLED, +}; + +struct osmo_ss7_asp { + /*! entry in \ref osmo_ss7_instance.asp_list */ + struct llist_head list; + struct osmo_ss7_instance *inst; + + /*! ASP FSM */ + struct osmo_fsm_inst *fi; + + /*! \ref osmo_xua_server over which we were established */ + struct osmo_xua_server *xua_server; + + /*! osmo_stream / libosmo-netif handles */ + struct osmo_stream_cli *client; + struct osmo_stream_srv *server; + /*! pre-formatted human readable local/remote socket name */ + char *sock_name; + + /* ASP Identifier for ASP-UP + NTFY */ + uint32_t asp_id; + bool asp_id_present; + + struct { + char *name; + char *description; + enum osmo_ss7_asp_protocol proto; + enum osmo_ss7_asp_admin_state adm_state; + bool is_server; + + struct osmo_ss7_asp_peer local; + struct osmo_ss7_asp_peer remote; + uint8_t qos_class; + } cfg; +}; + +struct osmo_ss7_asp * +osmo_ss7_asp_find_by_name(struct osmo_ss7_instance *inst, const char *name); +struct osmo_ss7_asp * +osmo_ss7_asp_find_or_create(struct osmo_ss7_instance *inst, const char *name, + uint16_t remote_port, uint16_t local_port, + enum osmo_ss7_asp_protocol proto); +void osmo_ss7_asp_destroy(struct osmo_ss7_asp *asp); +int osmo_ss7_asp_send(struct osmo_ss7_asp *asp, struct msgb *msg); +int osmo_ss7_asp_restart(struct osmo_ss7_asp *asp); + +#define LOGPASP(asp, subsys, level, fmt, args ...) \ + LOGP(subsys, level, "asp-%s: " fmt, (asp)->cfg.name, ## args) + +/*********************************************************************** + * xUA Servers + ***********************************************************************/ + +struct osmo_xua_server { + struct llist_head list; + struct osmo_ss7_instance *inst; + + struct osmo_stream_srv_link *server; + + struct { + struct osmo_ss7_asp_peer local; + enum osmo_ss7_asp_protocol proto; + } cfg; +}; + +struct osmo_xua_server * +osmo_ss7_xua_server_find(struct osmo_ss7_instance *inst, enum osmo_ss7_asp_protocol proto, + uint16_t local_port); + +struct osmo_xua_server * +osmo_ss7_xua_server_create(struct osmo_ss7_instance *inst, enum osmo_ss7_asp_protocol proto, + uint16_t local_port, const char *local_host); + +int +osmo_ss7_xua_server_set_local_host(struct osmo_xua_server *xs, const char *local_host); + +void osmo_ss7_xua_server_destroy(struct osmo_xua_server *xs); + +struct osmo_sccp_instance * +osmo_sccp_simple_client(void *ctx, const char *name, uint32_t pc, + enum osmo_ss7_asp_protocol prot, + int local_port, int remote_port, const char *remote_ip); + +struct osmo_sccp_instance * +osmo_sccp_simple_server(void *ctx, uint32_t pc, + enum osmo_ss7_asp_protocol prot, int local_port, + const char *local_ip); + +struct osmo_sccp_instance * +osmo_sccp_simple_server_add_clnt(struct osmo_sccp_instance *inst, + enum osmo_ss7_asp_protocol prot, + const char *name, uint32_t pc, + int local_port, int remote_port, + const char *remote_ip); diff --git a/include/osmocom/sigtran/protocol/mtp.h b/include/osmocom/sigtran/protocol/mtp.h new file mode 100644 index 0000000..8b990c0 --- /dev/null +++ b/include/osmocom/sigtran/protocol/mtp.h @@ -0,0 +1,24 @@ +#pragma once + +#include + +/* Chapter 15.17.4 of Q.704 + RFC4666 3.4.5. */ +/* Section 5.1 of ETSI EG 201 693: MTP SI code allocations (for NI= 00) */ +enum mtp_si_ni00 { + MTP_SI_SNM = 0, + MTP_SI_STM = 1, + MTP_SI_SCCP = 3, + MTP_SI_TUP = 4, + MTP_SI_ISUP = 5, + MTP_SI_DUP = 6, /* call related */ + MTP_SI_DUP_FAC = 7, /* facility related */ + MTP_SI_TESTING = 8, + MTP_SI_B_ISUP = 9, + MTP_SI_SAT_ISUP = 10, + MTP_SI_SPEECH = 11, /* speech processing element */ + MTP_SI_AAL2_SIG = 12, + MTP_SI_BICC = 13, + MTP_SI_GCP = 14, +}; + +extern const struct value_string mtp_si_vals[]; diff --git a/include/osmocom/sigtran/sigtran_sap.h b/include/osmocom/sigtran/sigtran_sap.h index 544fc44..d29c37d 100644 --- a/include/osmocom/sigtran/sigtran_sap.h +++ b/include/osmocom/sigtran/sigtran_sap.h @@ -3,4 +3,39 @@ enum osmo_sigtran_sap { SCCP_SAP_USER = _SAP_SS7_BASE, + /* xUA Layer Manager */ + XUA_SAP_LM, + MTP_SAP_USER, }; + +enum osmo_xlm_prim_type { + OSMO_XLM_PRIM_M_SCTP_ESTABLISH, + OSMO_XLM_PRIM_M_SCTP_RELEASE, + OSMO_XLM_PRIM_M_SCTP_RESTART, + OSMO_XLM_PRIM_M_SCTP_STATUS, + OSMO_XLM_PRIM_M_ASP_STATUS, + OSMO_XLM_PRIM_M_AS_STATUS, + OSMO_XLM_PRIM_M_NOTIFY, + OSMO_XLM_PRIM_M_ERROR, + OSMO_XLM_PRIM_M_ASP_UP, + OSMO_XLM_PRIM_M_ASP_DOWN, + OSMO_XLM_PRIM_M_ASP_ACTIVE, + OSMO_XLM_PRIM_M_ASP_INACTIVE, + OSMO_XLM_PRIM_M_AS_ACTIVE, + OSMO_XLM_PRIM_M_AS_INACTIVE, + OSMO_XLM_PRIM_M_AS_DOWN, + /* optional as per spec, not implemented yet */ + OSMO_XLM_PRIM_M_RK_REG, + OSMO_XLM_PRIM_M_RK_DEREG, +}; + + +struct osmo_xlm_prim { + struct osmo_prim_hdr oph; + union { + } u; +}; + +#define msgb_xlm_prim(msg) ((struct osmo_xlm_prim *)(msg)->l1h) + +char *osmo_xlm_prim_name(struct osmo_prim_hdr *oph); diff --git a/src/Makefile.am b/src/Makefile.am index 26482a0..f7f4ccc 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,6 +1,8 @@ AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir) AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMONETIF_CFLAGS) +noinst_HEADERS = xua_asp_fsm.h xua_as_fsm.h xua_internal.h + # Legacy static libs sccpdir = $(libdir) @@ -24,6 +26,7 @@ # documentation before making any modification LIBVERSION=0:0:0 -libosmo_sigtran_la_SOURCES = sccp_sap.c sua.c xua_msg.c sccp_helpers.c +libosmo_sigtran_la_SOURCES = sccp_sap.c sua.c m3ua.c xua_msg.c sccp_helpers.c \ + osmo_ss7.c osmo_ss7_hmrt.c xua_asp_fsm.c xua_as_fsm.c libosmo_sigtran_la_LDFLAGS = -version-info $(LIBVERSION) -no-undefined -export-symbols-regex '^osmo_' libosmo_sigtran_la_LIBADD = $(LIBOSMOCORE_LIBS) $(LIBOSMONETIF_LIBS) $(LIBSCTP_LIBS) diff --git a/src/m3ua.c b/src/m3ua.c new file mode 100644 index 0000000..8ec82c5 --- /dev/null +++ b/src/m3ua.c @@ -0,0 +1,669 @@ +/* Minimal implementation of RFC 4666 - MTP3 User Adaptation Layer */ + +/* (C) 2015-2017 by Harald Welte + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include "xua_asp_fsm.h" +#include "xua_internal.h" + +#define M3UA_MSGB_SIZE 1500 + +/*********************************************************************** + * Protocol Definition (string tables, mandatory IE checking) + ***********************************************************************/ + +/* Section 3.8.1 */ +const struct value_string m3ua_err_names[] = { + { M3UA_ERR_INVALID_VERSION, "Invalid Version" }, + { M3UA_ERR_UNSUPP_MSG_CLASS, "Unsupported Message Class" }, + { M3UA_ERR_UNSUPP_MSG_TYPE, "Unsupported Message Type" }, + { M3UA_ERR_UNSUPP_TRAF_MOD_TYP, "Unsupported Traffic Mode Type" }, + { M3UA_ERR_UNEXPECTED_MSG, "Unexpected Message" }, + { M3UA_ERR_PROTOCOL_ERR, "Protocol Error" }, + { M3UA_ERR_INVAL_STREAM_ID, "Invalid Stream Identifier" }, + { M3UA_ERR_REFUSED_MGMT_BLOCKING, "Refused - Management Blocking" }, + { M3UA_ERR_ASP_ID_REQD, "ASP Identifier Required" }, + { M3UA_ERR_INVAL_ASP_ID, "Invalid ASP Identifier" }, + { M3UA_ERR_INVAL_PARAM_VAL, "Invalid Parameter Value" }, + { M3UA_ERR_PARAM_FIELD_ERR, "Parameter Field Error" }, + { M3UA_ERR_UNEXP_PARAM, "Unexpected Parameter" }, + { M3UA_ERR_DEST_STATUS_UNKN, "Destination Status Unknown" }, + { M3UA_ERR_INVAL_NET_APPEAR, "Invalid Network Appearance" }, + { M3UA_ERR_MISSING_PARAM, "Missing Parameter" }, + { M3UA_ERR_INVAL_ROUT_CTX, "Invalid Routing Context" }, + { M3UA_ERR_NO_CONFGD_AS_FOR_ASP,"No Configured AS for ASP" }, + { SUA_ERR_SUBSYS_STATUS_UNKN, "Subsystem Status Unknown" }, + { SUA_ERR_INVAL_LOADSH_LEVEL, "Invalid loadsharing level" }, + { 0, NULL } +}; + +const struct value_string m3ua_ntfy_type_names[] = { + { M3UA_NOTIFY_T_STATCHG, "State Change" }, + { M3UA_NOTIFY_T_OTHER, "Other" }, + { 0, NULL } +}; + +const struct value_string m3ua_ntfy_stchg_names[] = { + { M3UA_NOTIFY_I_RESERVED, "Reserved" }, + { M3UA_NOTIFY_I_AS_INACT, "AS Inactive" }, + { M3UA_NOTIFY_I_AS_ACT, "AS Active" }, + { M3UA_NOTIFY_I_AS_PEND, "AS Pending" }, + { 0, NULL } +}; + +const struct value_string m3ua_ntfy_other_names[] = { + { M3UA_NOTIFY_I_OT_INS_RES, "Insufficient ASP Resouces active in AS" }, + { M3UA_NOTIFY_I_OT_ALT_ASP_ACT, "Alternative ASP Active" }, + { M3UA_NOTIFY_I_OT_ASP_FAILURE, "ASP Failure" }, + { 0, NULL } +}; + +static const struct value_string m3ua_iei_names[] = { + { M3UA_IEI_INFO_STRING, "INFO String" }, + { M3UA_IEI_ROUTE_CTX, "Routing Context" }, + { M3UA_IEI_DIAG_INFO, "Diagnostic Info" }, + { M3UA_IEI_HEARDBT_DATA, "Heartbeat Data" }, + { M3UA_IEI_TRAF_MODE_TYP, "Traffic Mode Type" }, + { M3UA_IEI_ERR_CODE, "Error Code" }, + { M3UA_IEI_STATUS, "Status" }, + { M3UA_IEI_ASP_ID, "ASP Identifier" }, + { M3UA_IEI_AFFECTED_PC, "Affected Point Code" }, + { M3UA_IEI_CORR_ID, "Correlation Id" }, + + { M3UA_IEI_NET_APPEAR, "Network Appearance" }, + { M3UA_IEI_USER_CAUSE, "User/Cause" }, + { M3UA_IEI_CONG_IND, "Congestion Indication" }, + { M3UA_IEI_CONC_DEST, "Concerned Destination" }, + { M3UA_IEI_ROUT_KEY, "Routing Key" }, + { M3UA_IEI_REG_RESULT, "Registration Result" }, + { M3UA_IEI_DEREG_RESULT, "De-Registration Result" }, + { M3UA_IEI_LOC_RKEY_ID, "Local Routing-Key Identifier" }, + { M3UA_IEI_DEST_PC, "Destination Point Code" }, + { M3UA_IEI_SVC_IND, "Service Indicators" }, + { M3UA_IEI_ORIG_PC, "Originating Point Code List" }, + { M3UA_IEI_PROT_DATA, "Protocol Data" }, + { M3UA_IEI_REG_STATUS, "Registration Status" }, + { M3UA_IEI_DEREG_STATUS, "De-Registration Status" }, + { 0, NULL } +}; + +#define MAND_IES(msgt, ies) [msgt] = (ies) + +/* XFER */ +static const uint16_t data_mand_ies[] = { + M3UA_IEI_PROT_DATA, 0 +}; +static const struct value_string m3ua_xfer_msgt_names[] = { + { M3UA_XFER_DATA, "DATA" }, + { 0, NULL } +}; +static const struct xua_msg_class msg_class_xfer = { + .name = "XFER", + .msgt_names = m3ua_xfer_msgt_names, + .mand_ies = { + MAND_IES(M3UA_XFER_DATA, data_mand_ies), + }, +}; + +/* SNM */ +static const uint16_t duna_mand_ies[] = { + M3UA_IEI_AFFECTED_PC, 0 +}; +static const uint16_t dava_mand_ies[] = { + M3UA_IEI_AFFECTED_PC, 0 +}; +static const uint16_t daud_mand_ies[] = { + M3UA_IEI_AFFECTED_PC, 0 +}; +static const uint16_t scon_mand_ies[] = { + M3UA_IEI_AFFECTED_PC, 0 +}; +static const uint16_t dupu_mand_ies[] = { + M3UA_IEI_AFFECTED_PC, M3UA_IEI_USER_CAUSE, 0 +}; +static const uint16_t drst_mand_ies[] = { + M3UA_IEI_AFFECTED_PC, 0 +}; +static const struct value_string m3ua_snm_msgt_names[] = { + { M3UA_SNM_DUNA, "DUNA" }, + { M3UA_SNM_DAVA, "DAVA" }, + { M3UA_SNM_DAUD, "DAUD" }, + { M3UA_SNM_SCON, "SCON" }, + { M3UA_SNM_DUPU, "DUPU" }, + { M3UA_SNM_DRST, "DRST" }, + { 0, NULL } +}; +const struct xua_msg_class m3ua_msg_class_snm = { + .name = "SNM", + .msgt_names = m3ua_snm_msgt_names, + .mand_ies = { + MAND_IES(M3UA_SNM_DUNA, duna_mand_ies), + MAND_IES(M3UA_SNM_DAVA, dava_mand_ies), + MAND_IES(M3UA_SNM_DAUD, daud_mand_ies), + MAND_IES(M3UA_SNM_SCON, scon_mand_ies), + MAND_IES(M3UA_SNM_DUPU, dupu_mand_ies), + MAND_IES(M3UA_SNM_DRST, drst_mand_ies), + }, +}; + +/* ASPSM */ +static const struct value_string m3ua_aspsm_msgt_names[] = { + { M3UA_ASPSM_UP, "UP" }, + { M3UA_ASPSM_DOWN, "DOWN" }, + { M3UA_ASPSM_BEAT, "BEAT" }, + { M3UA_ASPSM_UP_ACK, "UP-ACK" }, + { M3UA_ASPSM_DOWN_ACK, "DOWN-ACK" }, + { M3UA_ASPSM_BEAT_ACK, "BEAT-ACK" }, + { 0, NULL } +}; +const struct xua_msg_class m3ua_msg_class_aspsm = { + .name = "ASPSM", + .msgt_names = m3ua_aspsm_msgt_names, +}; + +/* ASPTM */ +const struct value_string m3ua_asptm_msgt_names[] = { + { M3UA_ASPTM_ACTIVE, "ACTIVE" }, + { M3UA_ASPTM_INACTIVE, "INACTIVE" }, + { M3UA_ASPTM_ACTIVE_ACK,"ACTIVE-ACK" }, + { M3UA_ASPTM_INACTIVE_ACK, "INACTIVE-ACK" }, + { 0, NULL } +}; +const struct xua_msg_class m3ua_msg_class_asptm = { + .name = "ASPTM", + .msgt_names = m3ua_asptm_msgt_names, + .iei_names = m3ua_iei_names, +}; + +/* MGMT */ +static const uint16_t err_req_ies[] = { + M3UA_IEI_ERR_CODE, 0 +}; +static const uint16_t ntfy_req_ies[] = { + M3UA_IEI_STATUS, 0 +}; +static const struct value_string m3ua_mgmt_msgt_names[] = { + { M3UA_MGMT_ERR, "ERROR" }, + { M3UA_MGMT_NTFY, "NOTIFY" }, + { 0, NULL } +}; +const struct xua_msg_class m3ua_msg_class_mgmt = { + .name = "MGMT", + .msgt_names = m3ua_mgmt_msgt_names, + .iei_names = m3ua_iei_names, + .mand_ies = { + MAND_IES(M3UA_MGMT_ERR, err_req_ies), + MAND_IES(M3UA_MGMT_NTFY, ntfy_req_ies), + }, +}; + +/* RKM */ +static const uint16_t reg_req_ies[] = { + M3UA_IEI_ROUT_KEY, 0 +}; +static const uint16_t reg_rsp_ies[] = { + M3UA_IEI_REG_RESULT, 0 +}; +static const uint16_t dereg_req_ies[] = { + M3UA_IEI_ROUT_KEY, 0 +}; +static const uint16_t dereg_rsp_ies[] = { + M3UA_IEI_DEREG_RESULT, 0 +}; +static const struct value_string m3ua_rkm_msgt_names[] = { + { M3UA_RKM_REG_REQ, "REG-REQ" }, + { M3UA_RKM_REG_RSP, "REG-RESP" }, + { M3UA_RKM_DEREG_REQ, "DEREG-REQ" }, + { M3UA_RKM_DEREG_RSP, "DEREG-RESP" }, + { 0, NULL } +}; +const struct xua_msg_class m3ua_msg_class_rkm = { + .name = "RKM", + .msgt_names = m3ua_rkm_msgt_names, + .iei_names = m3ua_iei_names, + .mand_ies = { + MAND_IES(M3UA_RKM_REG_REQ, reg_req_ies), + MAND_IES(M3UA_RKM_REG_RSP, reg_rsp_ies), + MAND_IES(M3UA_RKM_DEREG_REQ, dereg_req_ies), + MAND_IES(M3UA_RKM_DEREG_RSP, dereg_rsp_ies), + }, +}; + +/* M3UA dialect of XUA, MGMT,XFER,SNM,ASPSM,ASPTM,RKM */ +const struct xua_dialect xua_dialect_m3ua = { + .name = "M3UA", + .ppid = M3UA_PPID, + .port = M3UA_PORT, + .log_subsys = DLM3UA, + .class = { + [M3UA_MSGC_MGMT] = &m3ua_msg_class_mgmt, + [M3UA_MSGC_XFER] = &msg_class_xfer, + [M3UA_MSGC_SNM] = &m3ua_msg_class_snm, + [M3UA_MSGC_ASPSM] = &m3ua_msg_class_aspsm, + [M3UA_MSGC_ASPTM] = &m3ua_msg_class_asptm, + [M3UA_MSGC_RKM] = &m3ua_msg_class_rkm, + }, +}; + +/* convert osmo_mtp_transfer_param to m3ua_data_hdr */ +void mtp_xfer_param_to_m3ua_dh(struct m3ua_data_hdr *mdh, + const struct osmo_mtp_transfer_param *param) +{ + mdh->opc = htonl(param->opc); + mdh->dpc = htonl(param->dpc); + mdh->si = param->sio & 0xF; + mdh->ni = (param->sio >> 6) & 0x3; + mdh->mp = (param->sio >> 4) & 0x3; + mdh->sls = param->sls; +} + +/* convert m3ua_data_hdr to osmo_mtp_transfer_param */ +void m3ua_dh_to_xfer_param(struct osmo_mtp_transfer_param *param, + const struct m3ua_data_hdr *mdh) +{ + param->opc = ntohl(mdh->opc); + param->dpc = ntohl(mdh->dpc); + param->sls = mdh->sls; + /* re-construct SIO */ + param->sio = (mdh->si & 0xF) | + (mdh->mp & 0x3 << 4) | + (mdh->ni & 0x3 << 6); +} + +#define M3UA_MSG_SIZE 2048 +#define M3UA_MSG_HEADROOM 512 + +struct msgb *m3ua_msgb_alloc(const char *name) +{ + if (!name) + name = "M3UA"; + return msgb_alloc_headroom(M3UA_MSG_SIZE+M3UA_MSG_HEADROOM, + M3UA_MSG_HEADROOM, name); +} + +/*********************************************************************** + * ERROR generation + ***********************************************************************/ + +static struct xua_msg *m3ua_gen_error(uint32_t err_code) +{ + struct xua_msg *xua = xua_msg_alloc(); + + xua->hdr = XUA_HDR(M3UA_MSGC_MGMT, M3UA_MGMT_ERR); + xua->hdr.version = M3UA_VERSION; + xua_msg_add_u32(xua, M3UA_IEI_ERR_CODE, err_code); + + return xua; +} + +static struct xua_msg *m3ua_gen_error_msg(uint32_t err_code, struct msgb *msg) +{ + struct xua_msg *xua = m3ua_gen_error(err_code); + unsigned int len_max_40 = msgb_length(msg); + + if (len_max_40 > 40) + len_max_40 = 40; + + xua_msg_add_data(xua, M3UA_IEI_DIAG_INFO, len_max_40, msgb_data(msg)); + + return xua; +} + +/*********************************************************************** + * NOTIFY generation + ***********************************************************************/ + +/* RFC4666 Ch. 3.8.2. Notify */ +struct xua_msg *m3ua_encode_notify(const struct m3ua_notify_params *npar) +{ + struct xua_msg *xua = xua_msg_alloc(); + uint32_t status; + + xua->hdr = XUA_HDR(M3UA_MSGC_MGMT, M3UA_MGMT_NTFY); + + status = M3UA_NOTIFY(htons(npar->status_type), htons(npar->status_info)); + /* cannot use xua_msg_add_u32() as it does endian conversion */ + xua_msg_add_data(xua, M3UA_IEI_STATUS, sizeof(status), (uint8_t *) &status); + + /* Conditional: ASP Identifier */ + if (npar->presence & NOTIFY_PAR_P_ASP_ID) + xua_msg_add_u32(xua, M3UA_IEI_ASP_ID, npar->asp_id); + + /* Optional Routing Context */ + if (npar->presence & NOTIFY_PAR_P_ROUTE_CTX) + xua_msg_add_u32(xua, M3UA_IEI_ROUTE_CTX, npar->route_ctx); + + /* Optional: Info String */ + if (npar->info_string) + xua_msg_add_data(xua, M3UA_IEI_INFO_STRING, + strlen(npar->info_string)+1, + (uint8_t *) npar->info_string); + + return xua; +} + +/* RFC4666 Ch. 3.8.2. Notify */ +int m3ua_decode_notify(struct m3ua_notify_params *npar, void *ctx, + const struct xua_msg *xua) +{ + struct xua_msg_part *info_ie, *aspid_ie, *status_ie, *rctx_ie; + uint32_t status; + + /* cannot use xua_msg_get_u32() as it does endian conversion */ + status_ie = xua_msg_find_tag(xua, M3UA_IEI_STATUS); + status = *(uint32_t *) status_ie->dat; + + aspid_ie = xua_msg_find_tag(xua, M3UA_IEI_ASP_ID); + rctx_ie = xua_msg_find_tag(xua, M3UA_IEI_ROUTE_CTX); + info_ie = xua_msg_find_tag(xua, M3UA_IEI_INFO_STRING); + + npar->presence = 0; + npar->status_type = ntohs(status & 0xffff); + npar->status_info = ntohs(status >> 16); + + if (aspid_ie) { + npar->asp_id = xua_msg_part_get_u32(aspid_ie); + npar->presence |= NOTIFY_PAR_P_ASP_ID; + } + + if (rctx_ie) { + npar->route_ctx = xua_msg_part_get_u32(rctx_ie); + npar->presence |= NOTIFY_PAR_P_ROUTE_CTX; + } + + if (info_ie) { + npar->info_string = talloc_size(ctx, info_ie->len); + memcpy(npar->info_string, info_ie->dat, info_ie->len); + } else + npar->info_string = NULL; + + return 0; +} + +/*********************************************************************** + * Transmitting M3UA messsages to SCTP + ***********************************************************************/ + +static int m3ua_tx_xua_asp(struct osmo_ss7_asp *asp, struct xua_msg *xua) +{ + struct msgb *msg = xua_to_msg(M3UA_VERSION, xua); + + OSMO_ASSERT(asp->cfg.proto == OSMO_SS7_ASP_PROT_M3UA); + + xua_msg_free(xua); + + if (!msg) { + LOGP(DLM3UA, LOGL_ERROR, "Error encoding M3UA Msg\n"); + return -1; + } + + msgb_sctp_ppid(msg) = M3UA_PPID; + return osmo_ss7_asp_send(asp, msg); +} + +/*! \brief Send a given xUA message via a given M3UA Application Server + * \param[in] as Application Server through which to send \ref xua + * \param[in] xua xUA message to be sent + * \return 0 on success; negative on error */ +int m3ua_tx_xua_as(struct osmo_ss7_as *as, struct xua_msg *xua) +{ + struct osmo_ss7_asp *asp; + unsigned int i; + + OSMO_ASSERT(as->cfg.proto == OSMO_SS7_ASP_PROT_M3UA); + + for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) { + asp = as->cfg.asps[i]; + if (!asp) + continue; + if (asp) + break; + } + if (!asp) { + LOGP(DLM3UA, LOGL_ERROR, "No ASP entroy in AS, dropping message\n"); + xua_msg_free(xua); + return -ENODEV; + } + + return m3ua_tx_xua_asp(asp, xua); +} + +/*********************************************************************** + * Receiving M3UA messsages from SCTP + ***********************************************************************/ + +/* obtain the destination point code from a M3UA message in XUA fmt * */ +struct m3ua_data_hdr *data_hdr_from_m3ua(struct xua_msg *xua) +{ + struct xua_msg_part *data_ie; + struct m3ua_data_hdr *data_hdr; + + if (xua->hdr.msg_class != M3UA_MSGC_XFER || + xua->hdr.msg_type != M3UA_XFER_DATA) + return NULL; + + data_ie = xua_msg_find_tag(xua, M3UA_IEI_PROT_DATA); + if (!data_ie) + return NULL; + data_hdr = (struct m3ua_data_hdr *) data_ie->dat; + + return data_hdr; +} + +static int m3ua_rx_xfer(struct osmo_ss7_asp *asp, struct xua_msg *xua) +{ + struct m3ua_data_hdr *dh; + + /* store the MTP-level information in the xua_msg for use by + * higher layer protocols */ + dh = data_hdr_from_m3ua(xua); + OSMO_ASSERT(dh); + m3ua_dh_to_xfer_param(&xua->mtp, dh); + + return m3ua_hmdc_rx_from_l2(asp->inst, xua); +} + +static int m3ua_rx_mgmt_err(struct osmo_ss7_asp *asp, struct xua_msg *xua) +{ + uint32_t err_code = xua_msg_get_u32(xua, M3UA_IEI_ERR_CODE); + + LOGPASP(asp, DLM3UA, LOGL_ERROR, "Received MGMT_ERR '%s': %s\n", + get_value_string(m3ua_err_names, err_code), + xua_msg_dump(xua, &xua_dialect_m3ua)); + + /* NEVER return != 0 here, as we cannot respont to an ERR + * message with another ERR! */ + return 0; +} + +static int m3ua_rx_mgmt_ntfy(struct osmo_ss7_asp *asp, struct xua_msg *xua) +{ + struct m3ua_notify_params ntfy; + const char *type_name, *info_name; + + m3ua_decode_notify(&ntfy, asp, xua); + + type_name = get_value_string(m3ua_ntfy_type_names, ntfy.status_type); + + switch (ntfy.status_type) { + case M3UA_NOTIFY_T_STATCHG: + info_name = get_value_string(m3ua_ntfy_stchg_names, + ntfy.status_info); + break; + case M3UA_NOTIFY_T_OTHER: + info_name = get_value_string(m3ua_ntfy_other_names, + ntfy.status_info); + break; + default: + info_name = "NULL"; + break; + } + LOGPASP(asp, DLM3UA, LOGL_NOTICE, "Received NOTIFY Type %s:%s (%s)\n", + type_name, info_name, + ntfy.info_string ? ntfy.info_string : ""); + + if (ntfy.info_string) + talloc_free(ntfy.info_string); + + /* TODO: should we report this soemwhere? */ + return 0; +} + +static int m3ua_rx_mgmt(struct osmo_ss7_asp *asp, struct xua_msg *xua) +{ + switch (xua->hdr.msg_type) { + case M3UA_MGMT_ERR: + return m3ua_rx_mgmt_err(asp, xua); + case M3UA_MGMT_NTFY: + return m3ua_rx_mgmt_ntfy(asp, xua); + default: + return M3UA_ERR_UNSUPP_MSG_TYPE; + } +} + +/* map from M3UA ASPSM/ASPTM to xua_asp_fsm event */ +static const struct xua_msg_event_map m3ua_aspxm_map[] = { + { M3UA_MSGC_ASPSM, M3UA_ASPSM_UP, XUA_ASP_E_ASPSM_ASPUP }, + { M3UA_MSGC_ASPSM, M3UA_ASPSM_DOWN, XUA_ASP_E_ASPSM_ASPDN }, + { M3UA_MSGC_ASPSM, M3UA_ASPSM_BEAT, XUA_ASP_E_ASPSM_BEAT }, + { M3UA_MSGC_ASPSM, M3UA_ASPSM_UP_ACK, XUA_ASP_E_ASPSM_ASPUP_ACK }, + { M3UA_MSGC_ASPSM, M3UA_ASPSM_DOWN_ACK, XUA_ASP_E_ASPSM_ASPDN_ACK }, + { M3UA_MSGC_ASPSM, M3UA_ASPSM_BEAT_ACK, XUA_ASP_E_ASPSM_BEAT_ACK }, + { M3UA_MSGC_ASPTM, M3UA_ASPTM_ACTIVE, XUA_ASP_E_ASPTM_ASPAC }, + { M3UA_MSGC_ASPTM, M3UA_ASPTM_INACTIVE, XUA_ASP_E_ASPTM_ASPIA }, + { M3UA_MSGC_ASPTM, M3UA_ASPTM_ACTIVE_ACK, XUA_ASP_E_ASPTM_ASPAC_ACK }, + { M3UA_MSGC_ASPTM, M3UA_ASPTM_INACTIVE_ACK, XUA_ASP_E_ASPTM_ASPIA_ACK }, +}; + + +static int m3ua_rx_asp(struct osmo_ss7_asp *asp, struct xua_msg *xua) +{ + int event; + + /* map from the M3UA message class and message type to the XUA + * ASP FSM event number */ + event = xua_msg_event_map(xua, m3ua_aspxm_map, + ARRAY_SIZE(m3ua_aspxm_map)); + if (event < 0) + return M3UA_ERR_UNSUPP_MSG_TYPE; + + /* deliver that event to the ASP FSM */ + osmo_fsm_inst_dispatch(asp->fi, event, xua); + + return 0; +} + +/*! \brief process M3UA message received from socket + * \param[in] asp Application Server Process receiving \ref msg + * \param[in] msg received message buffer + * \returns 0 on success; negative on error */ +int m3ua_rx_msg(struct osmo_ss7_asp *asp, struct msgb *msg) +{ + struct xua_msg *xua = NULL, *err = NULL; + int rc = 0; + + OSMO_ASSERT(asp->cfg.proto == OSMO_SS7_ASP_PROT_M3UA); + + /* caller owns msg memory, we shall neither free it here nor + * keep references beyond the executin of this function and its + * callees */ + + xua = xua_from_msg(M3UA_VERSION, msgb_length(msg), msgb_data(msg)); + if (!xua) { + struct xua_common_hdr *hdr = (struct xua_common_hdr *) msg->data; + + LOGPASP(asp, DLM3UA, LOGL_ERROR, "Unable to parse incoming " + "M3UA message\n"); + + if (hdr->version != M3UA_VERSION) + err = m3ua_gen_error_msg(M3UA_ERR_INVALID_VERSION, msg); + else + err = m3ua_gen_error_msg(M3UA_ERR_PARAM_FIELD_ERR, msg); + goto out; + } + + LOGPASP(asp, DLM3UA, LOGL_DEBUG, "Received M3UA Message (%s)\n", + xua_hdr_dump(xua, &xua_dialect_m3ua)); + + if (!xua_dialect_check_all_mand_ies(&xua_dialect_m3ua, xua)) { + err = m3ua_gen_error_msg(M3UA_ERR_MISSING_PARAM, msg); + goto out; + } + + /* TODO: check for SCTP Strema ID */ + /* TODO: check if any AS configured in ASP */ + /* TODO: check for valid routing context */ + + switch (xua->hdr.msg_class) { + case M3UA_MSGC_XFER: + rc = m3ua_rx_xfer(asp, xua); + break; + case M3UA_MSGC_ASPSM: + case M3UA_MSGC_ASPTM: + rc = m3ua_rx_asp(asp, xua); + break; + break; + case M3UA_MSGC_MGMT: + rc = m3ua_rx_mgmt(asp, xua); + break; + case M3UA_MSGC_SNM: + case M3UA_MSGC_RKM: + /* FIXME */ + LOGPASP(asp, DLM3UA, LOGL_NOTICE, "Received unsupported M3UA " + "Message Class %u\n", xua->hdr.msg_class); + err = m3ua_gen_error_msg(M3UA_ERR_UNSUPP_MSG_CLASS, msg); + break; + default: + LOGPASP(asp, DLM3UA, LOGL_NOTICE, "Received unknown M3UA " + "Message Class %u\n", xua->hdr.msg_class); + err = m3ua_gen_error_msg(M3UA_ERR_UNSUPP_MSG_CLASS, msg); + break; + } + + if (rc > 0) + err = m3ua_gen_error_msg(rc, msg); + +out: + if (err) + m3ua_tx_xua_asp(asp, err); + + xua_msg_free(xua); + + return rc; +} diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c new file mode 100644 index 0000000..74c54bb --- /dev/null +++ b/src/osmo_ss7.c @@ -0,0 +1,1490 @@ +/* Core SS7 Instance/Linkset/Link/AS/ASP Handling */ + +/* (C) 2015-2017 by Harald Welte + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "xua_internal.h" +#include "xua_asp_fsm.h" +#include "xua_as_fsm.h" + +#define ASP_MSGB_SIZE 1500 +#define MAX_PC_STR_LEN 32 + +static bool ss7_initialized = false; + +static LLIST_HEAD(ss7_instances); +static LLIST_HEAD(ss7_xua_servers); + +struct value_string osmo_ss7_as_traffic_mode_vals[] = { + { OSMO_SS7_AS_TMOD_BCAST, "broadcast" }, + { OSMO_SS7_AS_TMOD_LOADSHARE, "loadshare" }, + { OSMO_SS7_AS_TMOD_ROUNDROBIN, "round-robin" }, + { OSMO_SS7_AS_TMOD_OVERRIDE, "override" }, + { 0, NULL } +}; + +struct value_string osmo_ss7_asp_protocol_vals[] = { + { OSMO_SS7_ASP_PROT_NONE, "none" }, + { OSMO_SS7_ASP_PROT_SUA, "sua" }, + { OSMO_SS7_ASP_PROT_M3UA, "m3ua" }, + { 0, NULL } +}; + +#define LOGSS7(inst, level, fmt, args ...) \ + LOGP(DLSS7, level, "%u: " fmt, (inst)->cfg.id, ## args) + + +/*********************************************************************** + * SS7 Point Code Parsing / Printing + ***********************************************************************/ + +/* like strcat() but appends a single character */ +static int strnappendchar(char *str, char c, size_t n) +{ + unsigned int curlen = strlen(str); + + if (n < curlen + 2) + return -1; + + str[curlen] = c; + str[curlen+1] = '\0'; + + return curlen+1; +} + +/* generate a format string for formatting a point code. The result can + * e.g. be used with sscanf() or sprintf() */ +static const char *gen_pc_fmtstr(struct osmo_ss7_instance *inst, + unsigned int *num_comp_exp) +{ + static char buf[MAX_PC_STR_LEN]; + unsigned int num_comp = 0; + + buf[0] = '\0'; + strcat(buf, "%u"); + num_comp++; + + if (inst->cfg.pc_fmt.component_len[1] == 0) + goto out; + strnappendchar(buf, inst->cfg.pc_fmt.delimiter, sizeof(buf)); + strcat(buf, "%u"); + num_comp++; + + if (inst->cfg.pc_fmt.component_len[2] == 0) + goto out; + strnappendchar(buf, inst->cfg.pc_fmt.delimiter, sizeof(buf)); + strcat(buf, "%u"); + num_comp++; +out: + if (num_comp_exp) + *num_comp_exp = num_comp; + return buf; +} + +/* get number of components we expect for a point code, depending on the + * configuration of this ss7_instance */ +static unsigned int num_pc_comp_exp(struct osmo_ss7_instance *inst) +{ + unsigned int num_comp_exp = 1; + + if (inst->cfg.pc_fmt.component_len[1]) + num_comp_exp++; + if (inst->cfg.pc_fmt.component_len[2]) + num_comp_exp++; + + return num_comp_exp; +} + +/* get the total width (in bits) of the point-codes in this ss7_instance */ +static unsigned int get_pc_width(struct osmo_ss7_instance *inst) +{ + return inst->cfg.pc_fmt.component_len[0] + + inst->cfg.pc_fmt.component_len[1] + + inst->cfg.pc_fmt.component_len[2]; +} + +/* get the number of bits we must shift the given component of a point + * code in this ss7_instance */ +static unsigned int get_pc_comp_shift(struct osmo_ss7_instance *inst, + unsigned int comp_num) +{ + uint32_t pc_width = get_pc_width(inst); + switch (comp_num) { + case 0: + return pc_width - inst->cfg.pc_fmt.component_len[0]; + case 1: + return pc_width - inst->cfg.pc_fmt.component_len[0] - + inst->cfg.pc_fmt.component_len[1]; + case 2: + return 0; + default: + return -EINVAL; + } +} + +static uint32_t pc_comp_shift_and_mask(struct osmo_ss7_instance *inst, + unsigned int comp_num, uint32_t pc) +{ + unsigned int shift = get_pc_comp_shift(inst, comp_num); + uint32_t mask = (1 << inst->cfg.pc_fmt.component_len[comp_num]) - 1; + + return (pc >> shift) & mask; +} + +/* parse a point code according to the structure configured for this + * ss7_instance */ +int osmo_ss7_pointcode_parse(struct osmo_ss7_instance *inst, const char *str) +{ + unsigned int component[3]; + unsigned int num_comp_exp = num_pc_comp_exp(inst); + const char *fmtstr = gen_pc_fmtstr(inst, &num_comp_exp); + int i, rc; + + rc = sscanf(str, fmtstr, &component[0], &component[1], &component[2]); + /* ensure all components were parsed */ + if (rc != num_comp_exp) + goto err; + + /* check none of the component values exceeds what can be + * represented within its bit-width */ + for (i = 0; i < num_comp_exp; i++) { + if (component[i] >= (1 << inst->cfg.pc_fmt.component_len[i])) + goto err; + } + + /* shift them all together */ + rc = (component[0] << get_pc_comp_shift(inst, 0)); + if (num_comp_exp > 1) + rc |= (component[1] << get_pc_comp_shift(inst, 1)); + if (num_comp_exp > 2) + rc |= (component[2] << get_pc_comp_shift(inst, 2)); + + return rc; + +err: + LOGSS7(inst, LOGL_NOTICE, "Error parsing Pointcode '%s'\n", str); + return -EINVAL; +} + +/* print a pointcode according to the structure configured for this + * ss7_instance */ +const char *osmo_ss7_pointcode_print(struct osmo_ss7_instance *inst, uint32_t pc) +{ + static char buf[MAX_PC_STR_LEN]; + unsigned int num_comp_exp = num_pc_comp_exp(inst); + const char *fmtstr = gen_pc_fmtstr(inst, &num_comp_exp); + + OSMO_ASSERT(fmtstr); + snprintf(buf, sizeof(buf), fmtstr, + pc_comp_shift_and_mask(inst, 0, pc), + pc_comp_shift_and_mask(inst, 1, pc), + pc_comp_shift_and_mask(inst, 2, pc)); + + return buf; +} + +int osmo_ss7_pointcode_parse_mask_or_len(struct osmo_ss7_instance *inst, const char *in) +{ + unsigned int width = get_pc_width(inst); + + if (in[0] == '/') { + /* parse mask by length */ + int masklen = atoi(in+1); + if (masklen < 0 || masklen > 32) + return -EINVAL; + if (masklen == 0) + return 0; + return (0xFFFFFFFF << (width - masklen)) & ((1 << width)-1); + } else { + /* parse mask as point code */ + return osmo_ss7_pointcode_parse(inst, in); + } +} + +static const uint16_t prot2port[] = { + [OSMO_SS7_ASP_PROT_NONE] = 0, + [OSMO_SS7_ASP_PROT_SUA] = SUA_PORT, + [OSMO_SS7_ASP_PROT_M3UA] = M3UA_PORT, +}; + +int osmo_ss7_asp_protocol_port(enum osmo_ss7_asp_protocol prot) +{ + if (prot >= ARRAY_SIZE(prot2port)) + return -EINVAL; + else + return prot2port[prot]; +} + +/*********************************************************************** + * SS7 Instance + ***********************************************************************/ + +/*! \brief Find a SS7 Instance with given ID + * \param[in] id ID for which to search + * \returns \ref osmo_ss7_instance on success; NULL on error */ +struct osmo_ss7_instance * +osmo_ss7_instance_find(uint32_t id) +{ + OSMO_ASSERT(ss7_initialized); + + struct osmo_ss7_instance *inst; + llist_for_each_entry(inst, &ss7_instances, list) { + if (inst->cfg.id == id) + return inst; + } + return NULL; +} + +/*! \brief Find or create a SS7 Instance + * \param[in] ctx talloc allocation context to use for allocations + * \param[in] id ID of SS7 Instance + * \returns \ref osmo_ss7_instance on success; NULL on error */ +struct osmo_ss7_instance * +osmo_ss7_instance_find_or_create(void *ctx, uint32_t id) +{ + struct osmo_ss7_instance *inst; + + OSMO_ASSERT(ss7_initialized); + + inst = osmo_ss7_instance_find(id); + if (!inst) + inst = talloc_zero(ctx, struct osmo_ss7_instance); + if (!inst) + return NULL; + + inst->cfg.id = id; + LOGSS7(inst, LOGL_INFO, "Creating SS7 Instance\n"); + + INIT_LLIST_HEAD(&inst->linksets); + INIT_LLIST_HEAD(&inst->as_list); + INIT_LLIST_HEAD(&inst->asp_list); + INIT_LLIST_HEAD(&inst->rtable_list); + inst->rtable_system = osmo_ss7_route_table_find_or_create(inst, "system"); + + /* default point code structure + formatting */ + inst->cfg.pc_fmt.delimiter = '.'; + inst->cfg.pc_fmt.component_len[0] = 3; + inst->cfg.pc_fmt.component_len[1] = 8; + inst->cfg.pc_fmt.component_len[2] = 3; + + llist_add(&inst->list, &ss7_instances); + + return inst; +} + +/*! \brief Destroy a SS7 Instance + * \param[in] inst SS7 Instance to be destroyed */ +void osmo_ss7_instance_destroy(struct osmo_ss7_instance *inst) +{ + struct osmo_ss7_linkset *lset; + struct osmo_ss7_as *as; + struct osmo_ss7_asp *asp; + + OSMO_ASSERT(ss7_initialized); + LOGSS7(inst, LOGL_INFO, "Destroying SS7 Instance\n"); + + llist_for_each_entry(asp, &inst->asp_list, list) + osmo_ss7_asp_destroy(asp); + + llist_for_each_entry(as, &inst->as_list, list) + osmo_ss7_as_destroy(as); + + llist_for_each_entry(lset, &inst->linksets, list) + osmo_ss7_linkset_destroy(lset); + + llist_del(&inst->list); + talloc_free(inst); +} + +/*! \brief Set the point code format used in given SS7 instance */ +int osmo_ss7_instance_set_pc_fmt(struct osmo_ss7_instance *inst, + uint8_t c0, uint8_t c1, uint8_t c2) +{ + if (c0+c1+c2 > 32) + return -EINVAL; + + if (c0+c1+c2 > 14) + LOGSS7(inst, LOGL_NOTICE, "Point Code Format %u-%u-%u " + "is longer than 14 bits, odd?\n", c0, c1, c2); + + inst->cfg.pc_fmt.component_len[0] = c0; + inst->cfg.pc_fmt.component_len[1] = c1; + inst->cfg.pc_fmt.component_len[2] = c2; + + return 0; +} + +/*********************************************************************** + * MTP Users (Users of MTP, such as SCCP or ISUP) + ***********************************************************************/ + +/*! \brief Register a MTP user for a given service indicator + * \param[in] inst SS7 instance for which we register the user + * \param[in] service_ind Service (ISUP, SCCP, ...) + * \param[in] user SS7 user (including primitive call-back) + * \returns 0 on success; negative on error */ +int osmo_ss7_user_register(struct osmo_ss7_instance *inst, uint8_t service_ind, + struct osmo_ss7_user *user) +{ + if (service_ind >= ARRAY_SIZE(inst->user)) + return -EINVAL; + + if (inst->user[service_ind]) + return -EBUSY; + + DEBUGP(DLSS7, "registering user=%s for SI %u with priv %p\n", + user->name, service_ind, user->priv); + + user->inst = inst; + inst->user[service_ind] = user; + + return 0; +} + +/*! \brief Unregister a MTP user for a given service indicator + * \param[in] inst SS7 instance for which we register the user + * \param[in] service_ind Service (ISUP, SCCP, ...) + * \param[in] user (optional) SS7 user. If present, we will not + * unregister other users + * \returns 0 on success; negative on error */ +int osmo_ss7_user_unregister(struct osmo_ss7_instance *inst, uint8_t service_ind, + struct osmo_ss7_user *user) +{ + if (service_ind >= ARRAY_SIZE(inst->user)) + return -EINVAL; + + if (!inst->user[service_ind]) + return -ENODEV; + + if (user && (inst->user[service_ind] != user)) + return -EINVAL; + + user->inst = NULL; + inst->user[service_ind] = NULL; + + return 0; +} + +/* deliver to a local MTP user */ +int osmo_ss7_mtp_to_user(struct osmo_ss7_instance *inst, struct osmo_mtp_prim *omp) +{ + uint32_t service_ind; + const struct osmo_ss7_user *osu; + + if (omp->oph.sap != MTP_SAP_USER || + omp->oph.primitive != OSMO_MTP_PRIM_TRANSFER || + omp->oph.operation != PRIM_OP_INDICATION) { + LOGP(DLSS7, LOGL_ERROR, "Unsupported Primitive\n"); + return -EINVAL; + } + + service_ind = omp->u.transfer.sio & 0xF; + osu = inst->user[service_ind]; + + if (!osu) { + LOGP(DLSS7, LOGL_NOTICE, "No MTP-User for SI %u\n", service_ind); + return -ENODEV; + } + + DEBUGP(DLSS7, "delivering MTP-TRANSFER.ind to user %s, priv=%p\n", + osu->name, osu->priv); + return osu->prim_cb(&omp->oph, (void *) osu->priv); +} + +/*********************************************************************** + * SS7 Linkset + ***********************************************************************/ + +/*! \brief Destroy a SS7 Linkset + * \param[in] lset Linkset to be destroyed */ +void osmo_ss7_linkset_destroy(struct osmo_ss7_linkset *lset) +{ + unsigned int i; + + OSMO_ASSERT(ss7_initialized); + LOGSS7(lset->inst, LOGL_INFO, "Destroying Linkset %s\n", + lset->cfg.name); + + for (i = 0; i < ARRAY_SIZE(lset->links); i++) { + struct osmo_ss7_link *link = lset->links[i]; + if (!link) + continue; + osmo_ss7_link_destroy(link); + } + llist_del(&lset->list); + talloc_free(lset); +} + +/*! \brief Find SS7 Linkset by given name + * \param[in] inst SS7 Instance in which to look + * \param[in] name Name of SS7 Linkset + * \returns pointer to linkset on success; NULL on error */ +struct osmo_ss7_linkset * +osmo_ss7_linkset_find_by_name(struct osmo_ss7_instance *inst, const char *name) +{ + struct osmo_ss7_linkset *lset; + OSMO_ASSERT(ss7_initialized); + llist_for_each_entry(lset, &inst->linksets, list) { + if (!strcmp(name, lset->cfg.name)) + return lset; + } + return NULL; +} + +/*! \brief Find or allocate SS7 Linkset + * \param[in] inst SS7 Instance in which we operate + * \param[in] name Name of SS7 Linkset + * \param[in] pc Adjacent Pointcode + * \returns pointer to Linkset on success; NULL on error */ +struct osmo_ss7_linkset * +osmo_ss7_linkset_find_or_create(struct osmo_ss7_instance *inst, const char *name, uint32_t pc) +{ + struct osmo_ss7_linkset *lset; + + OSMO_ASSERT(ss7_initialized); + lset = osmo_ss7_linkset_find_by_name(inst, name); + if (lset && lset->cfg.adjacent_pc != pc) + return NULL; + + if (!lset) { + LOGSS7(inst, LOGL_INFO, "Creating Linkset %s\n", name); + lset = talloc_zero(inst, struct osmo_ss7_linkset); + lset->inst = inst; + lset->cfg.adjacent_pc = pc; + lset->cfg.name = talloc_strdup(lset, name); + llist_add_tail(&lset->list, &inst->linksets); + } + + return lset; +} + +/*********************************************************************** + * SS7 Link + ***********************************************************************/ + +/*! \brief Destryo SS7 Link + * \param[in] link SS7 Link to be destroyed */ +void osmo_ss7_link_destroy(struct osmo_ss7_link *link) +{ + struct osmo_ss7_linkset *lset = link->linkset; + + OSMO_ASSERT(ss7_initialized); + LOGSS7(lset->inst, LOGL_INFO, "Destroying Link %s:%u\n", + lset->cfg.name, link->cfg.id); + /* FIXME: do cleanup */ + lset->links[link->cfg.id] = NULL; + talloc_free(link); +} + +/*! \brief Find or create SS7 Link with given ID in given Linkset + * \param[in] lset SS7 Linkset on which we operate + * \param[in] id Link number within Linkset + * \returns pointer to SS7 Link on success; NULL on error */ +struct osmo_ss7_link * +osmo_ss7_link_find_or_create(struct osmo_ss7_linkset *lset, uint32_t id) +{ + struct osmo_ss7_link *link; + + OSMO_ASSERT(ss7_initialized); + if (id >= ARRAY_SIZE(lset->links)) + return NULL; + + if (lset->links[id]) { + link = lset->links[id]; + } else { + LOGSS7(lset->inst, LOGL_INFO, "Creating Link %s:%u\n", + lset->cfg.name, id); + link = talloc_zero(lset, struct osmo_ss7_link); + if (!link) + return NULL; + link->linkset = lset; + lset->links[id] = link; + link->cfg.id = id; + } + + return link; +} + + +/*********************************************************************** + * SS7 Route Tables + ***********************************************************************/ + +struct osmo_ss7_route_table * +osmo_ss7_route_table_find(struct osmo_ss7_instance *inst, const char *name) +{ + struct osmo_ss7_route_table *rtbl; + OSMO_ASSERT(ss7_initialized); + llist_for_each_entry(rtbl, &inst->rtable_list, list) { + if (!strcmp(rtbl->cfg.name, name)) + return rtbl; + } + return NULL; +} + +struct osmo_ss7_route_table * +osmo_ss7_route_table_find_or_create(struct osmo_ss7_instance *inst, const char *name) +{ + struct osmo_ss7_route_table *rtbl; + + OSMO_ASSERT(ss7_initialized); + rtbl = osmo_ss7_route_table_find(inst, name); + if (!rtbl) { + LOGSS7(inst, LOGL_INFO, "Creating Route Table %s\n", name); + rtbl = talloc_zero(inst, struct osmo_ss7_route_table); + rtbl->inst = inst; + rtbl->cfg.name = talloc_strdup(rtbl, name); + INIT_LLIST_HEAD(&rtbl->routes); + llist_add_tail(&rtbl->list, &inst->rtable_list); + } + return rtbl; +} + +void osmo_ss7_route_table_destroy(struct osmo_ss7_route_table *rtbl) +{ + llist_del(&rtbl->list); + /* routes are allocated as children of route table, will be + * automatically freed() */ + talloc_free(rtbl); +} + +/*********************************************************************** + * SS7 Routes + ***********************************************************************/ + +/*! \brief Find a SS7 route for given destination point code in given table */ +struct osmo_ss7_route * +osmo_ss7_route_find_dpc(struct osmo_ss7_route_table *rtbl, uint32_t dpc) +{ + struct osmo_ss7_route *rt; + + OSMO_ASSERT(ss7_initialized); + /* we assume the routes are sorted by mask length, i.e. more + * specific routes first, and less specific routes with shorter + * mask later */ + llist_for_each_entry(rt, &rtbl->routes, list) { + if ((dpc & rt->cfg.mask) == rt->cfg.pc) + return rt; + } + return NULL; +} + +/*! \brief Find a SS7 route for given destination point code + mask in given table */ +struct osmo_ss7_route * +osmo_ss7_route_find_dpc_mask(struct osmo_ss7_route_table *rtbl, uint32_t dpc, + uint32_t mask) +{ + struct osmo_ss7_route *rt; + + OSMO_ASSERT(ss7_initialized); + /* we assume the routes are sorted by mask length, i.e. more + * specific routes first, and less specific routes with shorter + * mask later */ + llist_for_each_entry(rt, &rtbl->routes, list) { + if (dpc == rt->cfg.pc && mask == rt->cfg.mask) + return rt; + } + return NULL; +} + +/*! \brief Find a SS7 route for given destination point code in given SS7 */ +struct osmo_ss7_route * +osmo_ss7_route_lookup(struct osmo_ss7_instance *inst, uint32_t dpc) +{ + OSMO_ASSERT(ss7_initialized); + return osmo_ss7_route_find_dpc(inst->rtable_system, dpc); +} + +/* insert the route in the ordered list of routes. The list is sorted by + * mask length, so that the more specific (longer mask) routes are + * first, while the less specific routes with shorter masks are last. + * Hence, the first matching route in a linear iteration is the most + * specific match. */ +static void route_insert_sorted(struct osmo_ss7_route_table *rtbl, + struct osmo_ss7_route *cmp) +{ + struct osmo_ss7_route *rt; + + llist_for_each_entry(rt, &rtbl->routes, list) { + if (rt->cfg.mask < cmp->cfg.mask) { + /* insert before the current entry */ + llist_add(&cmp->list, rt->list.prev); + return; + } + } + /* not added, i.e. no smaller mask length found: we are the + * smallest mask and thus should go last */ + llist_add_tail(&cmp->list, &rtbl->routes); +} + +/*! \brief Create a new route in the given routing table + * \param[in] rtbl Routing Table in which the route is to be created + * \param[in] pc Point Code of the destination of the route + * \param[in] mask Mask of the destination Point Code \ref pc + * \param[in] linkset_name string name of the linkset to be used + * \returns caller-allocated + initialized route, NULL on error + */ +struct osmo_ss7_route * +osmo_ss7_route_create(struct osmo_ss7_route_table *rtbl, uint32_t pc, + uint32_t mask, const char *linkset_name) +{ + struct osmo_ss7_route *rt; + struct osmo_ss7_linkset *lset; + struct osmo_ss7_as *as; + + OSMO_ASSERT(ss7_initialized); + lset = osmo_ss7_linkset_find_by_name(rtbl->inst, linkset_name); + if (!lset) { + as = osmo_ss7_as_find_by_name(rtbl->inst, linkset_name); + if (!as) + return NULL; + } + + rt = talloc_zero(rtbl, struct osmo_ss7_route); + if (!rt) + return NULL; + + rt->cfg.pc = pc; + rt->cfg.mask = mask; + rt->cfg.linkset_name = talloc_strdup(rt, linkset_name); + if (lset) + rt->dest.linkset = lset; + else + rt->dest.as = as; + rt->rtable = rtbl; + + route_insert_sorted(rtbl, rt); + + return rt; +} + +/*! \brief Destroy a given SS7 route */ +void osmo_ss7_route_destroy(struct osmo_ss7_route *rt) +{ + OSMO_ASSERT(ss7_initialized); + llist_del(&rt->list); + talloc_free(rt); +} + +/*********************************************************************** + * SS7 Application Server + ***********************************************************************/ + +/*! \brief Find Application Server by given name + * \param[in] inst SS7 Instance on which we operate + * \param[in] name Name of AS + * \returns pointer to Application Server on success; NULL otherwise */ +struct osmo_ss7_as * +osmo_ss7_as_find_by_name(struct osmo_ss7_instance *inst, const char *name) +{ + struct osmo_ss7_as *as; + + OSMO_ASSERT(ss7_initialized); + llist_for_each_entry(as, &inst->as_list, list) { + if (!strcmp(name, as->cfg.name)) + return as; + } + return NULL; +} + +/*! \brief Find Application Server by given routing context + * \param[in] inst SS7 Instance on which we operate + * \param[in] rctx Routing Context + * \returns pointer to Application Server on success; NULL otherwise */ +struct osmo_ss7_as * +osmo_ss7_as_find_by_rctx(struct osmo_ss7_instance *inst, uint32_t rctx) +{ + struct osmo_ss7_as *as; + + OSMO_ASSERT(ss7_initialized); + llist_for_each_entry(as, &inst->as_list, list) { + if (as->cfg.routing_key.context == rctx) + return as; + } + return NULL; +} + +/*! \brief Find or Create Application Server + * \param[in] inst SS7 Instance on which we operate + * \param[in] name Name of Application Server + * \param[in] proto Protocol of Application Server + * \returns pointer to Application Server on suuccess; NULL otherwise */ +struct osmo_ss7_as * +osmo_ss7_as_find_or_create(struct osmo_ss7_instance *inst, const char *name, + enum osmo_ss7_asp_protocol proto) +{ + struct osmo_ss7_as *as; + + OSMO_ASSERT(ss7_initialized); + as = osmo_ss7_as_find_by_name(inst, name); + + if (as && as->cfg.proto != proto) + return NULL; + + if (!as) { + LOGSS7(inst, LOGL_INFO, "Creating AS %s\n", name); + as = talloc_zero(inst, struct osmo_ss7_as); + if (!as) + return NULL; + as->inst = inst; + as->cfg.name = talloc_strdup(as, name); + as->cfg.proto = proto; + as->cfg.mode = OSMO_SS7_AS_TMOD_LOADSHARE; + as->cfg.recovery_timeout_msec = 2000; + as->fi = xua_as_fsm_start(as, LOGL_DEBUG); + llist_add_tail(&as->list, &inst->as_list); + } + + return as; +} + +/*! \brief Add given ASP to given AS + * \param[in] as Application Server to which \ref asp is added + * \param[in] asp Application Server Process to be added to \ref as + * \returns 0 on success; negative in case of error */ +int osmo_ss7_as_add_asp(struct osmo_ss7_as *as, const char *asp_name) +{ + struct osmo_ss7_asp *asp; + unsigned int i; + + OSMO_ASSERT(ss7_initialized); + asp = osmo_ss7_asp_find_by_name(as->inst, asp_name); + if (!asp) + return -ENODEV; + + LOGSS7(as->inst, LOGL_INFO, "Adding ASP %s to AS %s\n", + asp->cfg.name, as->cfg.name); + + if (osmo_ss7_as_has_asp(as, asp)) + return 0; + + for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) { + if (!as->cfg.asps[i]) { + as->cfg.asps[i] = asp; + return 0; + } + } + + return -ENOSPC; +} + +/*! \brief Delete given ASP from given AS + * \param[in] as Application Server from which \ref asp is deleted + * \param[in] asp Application Server Process to delete from \ref as + * \returns 0 on success; negative in case of error */ +int osmo_ss7_as_del_asp(struct osmo_ss7_as *as, const char *asp_name) +{ + struct osmo_ss7_asp *asp; + unsigned int i; + + OSMO_ASSERT(ss7_initialized); + asp = osmo_ss7_asp_find_by_name(as->inst, asp_name); + if (!asp) + return -ENODEV; + + LOGSS7(as->inst, LOGL_INFO, "Removing ASP %s from AS %s\n", + asp->cfg.name, as->cfg.name); + + for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) { + if (as->cfg.asps[i] == asp) { + as->cfg.asps[i] = NULL; + return 0; + } + } + + return -EINVAL; +} + +/*! \brief Destroy given Application Server + * \param[in] as Application Server to destroy */ +void osmo_ss7_as_destroy(struct osmo_ss7_as *as) +{ + OSMO_ASSERT(ss7_initialized); + LOGSS7(as->inst, LOGL_INFO, "Destroying AS %s\n", as->cfg.name); + + if (as->fi) + osmo_fsm_inst_term(as->fi, OSMO_FSM_TERM_REQUEST, NULL); + + as->inst = NULL; + llist_del(&as->list); + talloc_free(as); +} + +/*! \brief Determine if given AS contains ASP + * \param[in] as Application Server in which to look for \ref asp + * \param[in] asp Application Server Process to look for in \ref as + * \returns true in case \ref asp is part of \ref as; false otherwise */ +bool osmo_ss7_as_has_asp(struct osmo_ss7_as *as, + struct osmo_ss7_asp *asp) +{ + unsigned int i; + + OSMO_ASSERT(ss7_initialized); + for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) { + if (as->cfg.asps[i] == asp) + return true; + } + return false; +} + +/*********************************************************************** + * SS7 Application Server Process + ***********************************************************************/ + +struct osmo_ss7_asp * +osmo_ss7_asp_find_by_name(struct osmo_ss7_instance *inst, const char *name) +{ + struct osmo_ss7_asp *asp; + + OSMO_ASSERT(ss7_initialized); + llist_for_each_entry(asp, &inst->asp_list, list) { + if (!strcmp(name, asp->cfg.name)) + return asp; + } + return NULL; +} + +static uint16_t get_in_port(struct sockaddr *sa) +{ + switch (sa->sa_family) { + case AF_INET: + return (((struct sockaddr_in*)sa)->sin_port); + case AF_INET6: + return (((struct sockaddr_in6*)sa)->sin6_port); + default: + return 0; + } +} + +/*! \brief Find an ASP definition matching the local+remote IP/PORT of given fd + * \param[in] fd socket descriptor of given socket + * \returns SS7 ASP in case a matching one is found; NULL otherwise */ +static struct osmo_ss7_asp * +osmo_ss7_asp_find_by_socket_addr(int fd) +{ + struct osmo_ss7_instance *inst; + struct sockaddr sa_l, sa_r; + socklen_t sa_len_l = sizeof(sa_l); + socklen_t sa_len_r = sizeof(sa_r); + char hostbuf_l[64], hostbuf_r[64]; + uint16_t local_port, remote_port; + int rc; + + OSMO_ASSERT(ss7_initialized); + /* convert local and remote IP to string */ + rc = getsockname(fd, &sa_l, &sa_len_l); + if (rc < 0) + return NULL; + rc = getnameinfo(&sa_l, sa_len_l, hostbuf_l, sizeof(hostbuf_l), + NULL, 0, NI_NUMERICHOST); + if (rc < 0) + return NULL; + local_port = ntohs(get_in_port(&sa_l)); + + rc = getpeername(fd, &sa_r, &sa_len_r); + if (rc < 0) + return NULL; + rc = getnameinfo(&sa_r, sa_len_r, hostbuf_r, sizeof(hostbuf_r), + NULL, 0, NI_NUMERICHOST); + if (rc < 0) + return NULL; + remote_port = ntohs(get_in_port(&sa_r)); + + /* check all instances for any ASP definition matching the + * address combination of local/remote ip/port */ + llist_for_each_entry(inst, &ss7_instances, list) { + struct osmo_ss7_asp *asp; + llist_for_each_entry(asp, &inst->asp_list, list) { + if (asp->cfg.local.port == local_port && + (!asp->cfg.remote.port ||asp->cfg.remote.port == remote_port) && + (!asp->cfg.local.host || !strcmp(asp->cfg.local.host, hostbuf_l)) && + (!asp->cfg.remote.host || !strcmp(asp->cfg.remote.host, hostbuf_r))) + return asp; + } + } + + return NULL; +} + +struct osmo_ss7_asp * +osmo_ss7_asp_find_or_create(struct osmo_ss7_instance *inst, const char *name, + uint16_t remote_port, uint16_t local_port, + enum osmo_ss7_asp_protocol proto) +{ + struct osmo_ss7_asp *asp; + + OSMO_ASSERT(ss7_initialized); + asp = osmo_ss7_asp_find_by_name(inst, name); + + if (asp && (asp->cfg.remote.port != remote_port || + asp->cfg.local.port != local_port || + asp->cfg.proto != proto)) + return NULL; + + if (!asp) { + /* FIXME: check if local port has SCTP? */ + asp = talloc_zero(inst, struct osmo_ss7_asp); + asp->inst = inst; + asp->cfg.remote.port = remote_port; + asp->cfg.local.port = local_port; + asp->cfg.proto = proto; + asp->cfg.name = talloc_strdup(asp, name); + llist_add_tail(&asp->list, &inst->asp_list); + } + return asp; +} + +void osmo_ss7_asp_destroy(struct osmo_ss7_asp *asp) +{ + struct osmo_ss7_as *as; + + OSMO_ASSERT(ss7_initialized); + LOGSS7(asp->inst, LOGL_INFO, "Destroying ASP %s\n", asp->cfg.name); + + if (asp->server) + osmo_stream_srv_destroy(asp->server); + if (asp->client) + osmo_stream_cli_destroy(asp->client); + if (asp->fi) + osmo_fsm_inst_term(asp->fi, OSMO_FSM_TERM_REQUEST, NULL); + + /* unlink from all ASs we are part of */ + llist_for_each_entry(as, &asp->inst->as_list, list) { + unsigned int i; + for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) { + if (as->cfg.asps[i] == asp) { + as->cfg.asps[i] = NULL; + } + } + } + /* unlink from ss7_instance */ + asp->inst = NULL; + llist_del(&asp->list); + /* release memory */ + talloc_free(asp); +} + +static int xua_cli_read_cb(struct osmo_stream_cli *conn); +static int xua_cli_connect_cb(struct osmo_stream_cli *cli); + +int osmo_ss7_asp_restart(struct osmo_ss7_asp *asp) +{ + int rc; + enum xua_asp_role role; + + OSMO_ASSERT(ss7_initialized); + LOGSS7(asp->inst, LOGL_INFO, "Restarting ASP %s\n", asp->cfg.name); + + if (!asp->cfg.is_server) { + /* We are in client mode now */ + if (asp->server) { + /* if we previously were in server mode, + * destroy it */ + osmo_stream_srv_destroy(asp->server); + asp->server = NULL; + } + if (!asp->client) + asp->client = osmo_stream_cli_create(asp); + if (!asp->client) { + LOGSS7(asp->inst, LOGL_ERROR, "Unable to create stream" + " client for ASP %s\n", asp->cfg.name); + return -1; + } + osmo_stream_cli_set_addr(asp->client, asp->cfg.remote.host); + osmo_stream_cli_set_port(asp->client, asp->cfg.remote.port); + osmo_stream_cli_set_proto(asp->client, IPPROTO_SCTP); + osmo_stream_cli_set_reconnect_timeout(asp->client, 5); + osmo_stream_cli_set_connect_cb(asp->client, xua_cli_connect_cb); + osmo_stream_cli_set_read_cb(asp->client, xua_cli_read_cb); + osmo_stream_cli_set_data(asp->client, asp); + rc = osmo_stream_cli_open2(asp->client, 1); + if (rc < 0) { + LOGSS7(asp->inst, LOGL_ERROR, "Unable to open stream" + " client for ASP %s\n", asp->cfg.name); + } + /* TODO: make this configurable and not implicit */ + role = XUA_ASPFSM_ROLE_ASP; + } else { + /* We are in server mode now */ + if (asp->client) { + /* if we previously were in client mode, + * destroy it */ + osmo_stream_cli_destroy(asp->client); + asp->client = NULL; + } + /* FIXME: ensure we have a SCTP server */ + LOGSS7(asp->inst, LOGL_NOTICE, "ASP Restart for server " + "not implemented yet!\n"); + /* TODO: make this configurable and not implicit */ + role = XUA_ASPFSM_ROLE_SG; + } + + /* (re)start the ASP FSM */ + if (asp->fi) + osmo_fsm_inst_term(asp->fi, OSMO_FSM_TERM_REQUEST, NULL); + asp->fi = xua_asp_fsm_start(asp, role, LOGL_DEBUG); + + return 0; +} + +/*********************************************************************** + * libosmo-netif integration for SCTP stream server/client + ***********************************************************************/ + +static const struct value_string sctp_assoc_chg_vals[] = { + { SCTP_COMM_UP, "COMM_UP" }, + { SCTP_COMM_LOST, "COMM_LOST" }, + { SCTP_RESTART, "RESTART" }, + { SCTP_SHUTDOWN_COMP, "SHUTDOWN_COMP" }, + { SCTP_CANT_STR_ASSOC, "CANT_STR_ASSOC" }, + { 0, NULL } +}; + +static const struct value_string sctp_sn_type_vals[] = { + { SCTP_ASSOC_CHANGE, "ASSOC_CHANGE" }, + { SCTP_PEER_ADDR_CHANGE, "PEER_ADDR_CHANGE" }, + { SCTP_SHUTDOWN_EVENT, "SHUTDOWN_EVENT" }, + { SCTP_SEND_FAILED, "SEND_FAILED" }, + { SCTP_REMOTE_ERROR, "REMOTE_ERROR" }, + { SCTP_PARTIAL_DELIVERY_EVENT, "PARTIAL_DELIVERY_EVENT" }, + { SCTP_ADAPTATION_INDICATION, "ADAPTATION_INDICATION" }, +#ifdef SCTP_AUTHENTICATION_INDICATION + { SCTP_AUTHENTICATION_INDICATION, "UTHENTICATION_INDICATION" }, +#endif +#ifdef SCTP_SENDER_DRY_EVENT + { SCTP_SENDER_DRY_EVENT, "SENDER_DRY_EVENT" }, +#endif + { 0, NULL } +}; + +static int get_logevel_by_sn_type(int sn_type) +{ + switch (sn_type) { + case SCTP_ADAPTATION_INDICATION: + case SCTP_PEER_ADDR_CHANGE: +#ifdef SCTP_AUTHENTICATION_INDICATION + case SCTP_AUTHENTICATION_INDICATION: +#endif +#ifdef SCTP_SENDER_DRY_EVENT + case SCTP_SENDER_DRY_EVENT: +#endif + return LOGL_INFO; + case SCTP_ASSOC_CHANGE: + return LOGL_NOTICE; + case SCTP_SHUTDOWN_EVENT: + case SCTP_PARTIAL_DELIVERY_EVENT: + return LOGL_NOTICE; + case SCTP_SEND_FAILED: + case SCTP_REMOTE_ERROR: + return LOGL_ERROR; + default: + return LOGL_NOTICE; + } +} + +static void log_sctp_notification(struct osmo_ss7_asp *asp, const char *pfx, + union sctp_notification *notif) +{ + int log_level; + + LOGPASP(asp, DLSS7, LOGL_INFO, "%s SCTP NOTIFICATION %u flags=0x%0x\n", + pfx, notif->sn_header.sn_type, + notif->sn_header.sn_flags); + + log_level = get_logevel_by_sn_type(notif->sn_header.sn_type); + + switch (notif->sn_header.sn_type) { + case SCTP_ASSOC_CHANGE: + LOGPASP(asp, DLSS7, log_level, "%s SCTP_ASSOC_CHANGE: %s\n", + pfx, get_value_string(sctp_assoc_chg_vals, + notif->sn_assoc_change.sac_state)); + break; + default: + LOGPASP(asp, DLSS7, log_level, "%s %s\n", + pfx, get_value_string(sctp_sn_type_vals, + notif->sn_header.sn_type)); + break; + } +} + +/* netif code tells us we can read something from the socket */ +static int xua_srv_conn_cb(struct osmo_stream_srv *conn) +{ + struct osmo_fd *ofd = osmo_stream_srv_get_ofd(conn); + struct osmo_ss7_asp *asp = osmo_stream_srv_get_data(conn); + struct msgb *msg = msgb_alloc(ASP_MSGB_SIZE, "xUA Server Rx"); + struct sctp_sndrcvinfo sinfo; + unsigned int ppid; + int flags = 0; + int rc; + + if (!msg) + return -ENOMEM; + + /* read xUA message from socket and process it */ + rc = sctp_recvmsg(ofd->fd, msgb_data(msg), msgb_tailroom(msg), + NULL, NULL, &sinfo, &flags); + LOGPASP(asp, DLSS7, LOGL_DEBUG, "%s(): sctp_recvmsg() returned %d\n", + __func__, rc); + if (rc < 0) { + osmo_stream_srv_destroy(conn); + goto out; + } else if (rc == 0) { + osmo_stream_srv_destroy(conn); + goto out; + } else { + msgb_put(msg, rc); + } + + if (flags & MSG_NOTIFICATION) { + union sctp_notification *notif = (union sctp_notification *) msgb_data(msg); + + log_sctp_notification(asp, "xUA SRV", notif); + + switch (notif->sn_header.sn_type) { + case SCTP_SHUTDOWN_EVENT: + osmo_stream_srv_destroy(conn); + osmo_fsm_inst_dispatch(asp->fi, XUA_ASP_E_SCTP_COMM_DOWN_IND, asp); + break; + default: + break; + } + rc = 0; + goto out; + } + + ppid = ntohl(sinfo.sinfo_ppid); + msgb_sctp_ppid(msg) = ppid; + msgb_sctp_stream(msg) = ntohl(sinfo.sinfo_stream); + msg->dst = asp; + + if (ppid == M3UA_PPID && asp->cfg.proto == OSMO_SS7_ASP_PROT_M3UA) + rc = m3ua_rx_msg(asp, msg); + else { + LOGPASP(asp, DLSS7, LOGL_NOTICE, "SCTP chunk for unknown PPID %u " + "received\n", ppid); + rc = 0; + } + +out: + msgb_free(msg); + return rc; +} + +/* client has established SCTP connection to server */ +static int xua_cli_connect_cb(struct osmo_stream_cli *cli) +{ + struct osmo_fd *ofd = osmo_stream_cli_get_ofd(cli); + struct osmo_ss7_asp *asp = osmo_stream_cli_get_data(cli); + + /* update the socket name */ + osmo_talloc_replace_string(asp, &asp->sock_name, osmo_sock_get_name(asp, ofd->fd)); + + LOGPASP(asp, DLSS7, LOGL_INFO, "Client connected %s\n", asp->sock_name); + + /* Notify the ASP FSM that the connection has just been + * established */ + osmo_fsm_inst_dispatch(asp->fi, XUA_ASP_E_M_ASP_UP_REQ, NULL); + + return 0; +} + +static int xua_cli_read_cb(struct osmo_stream_cli *conn) +{ + struct osmo_fd *ofd = osmo_stream_cli_get_ofd(conn); + struct osmo_ss7_asp *asp = osmo_stream_cli_get_data(conn); + struct msgb *msg = msgb_alloc(ASP_MSGB_SIZE, "xUA Client Rx"); + struct sctp_sndrcvinfo sinfo; + unsigned int ppid; + int flags = 0; + int rc; + + if (!msg) + return -ENOMEM; + + /* read xUA message from socket and process it */ + rc = sctp_recvmsg(ofd->fd, msgb_data(msg), msgb_tailroom(msg), + NULL, NULL, &sinfo, &flags); + LOGPASP(asp, DLSS7, LOGL_DEBUG, "%s(): sctp_recvmsg() returned %d (flags=%d)\n", + __func__, rc, flags); + if (rc < 0) { + osmo_stream_cli_reconnect(conn); + goto out; + } else if (rc == 0) { + osmo_stream_cli_reconnect(conn); + } else { + msgb_put(msg, rc); + } + + if (flags & MSG_NOTIFICATION) { + union sctp_notification *notif = (union sctp_notification *) msgb_data(msg); + + log_sctp_notification(asp, "xUA CLNT", notif); + + switch (notif->sn_header.sn_type) { + case SCTP_SHUTDOWN_EVENT: + osmo_fsm_inst_dispatch(asp->fi, XUA_ASP_E_SCTP_COMM_DOWN_IND, asp); + osmo_stream_cli_reconnect(conn); + break; + default: + break; + } + rc = 0; + goto out; + } + + if (rc == 0) + goto out; + + ppid = ntohl(sinfo.sinfo_ppid); + msgb_sctp_ppid(msg) = ppid; + msgb_sctp_stream(msg) = ntohl(sinfo.sinfo_stream); + msg->dst = asp; + + if (ppid == M3UA_PPID && asp->cfg.proto == OSMO_SS7_ASP_PROT_M3UA) + rc = m3ua_rx_msg(asp, msg); + else { + LOGPASP(asp, DLSS7, LOGL_NOTICE, "SCTP chunk for unknown PPID %u " + "received\n", ppid); + rc = 0; + } + +out: + msgb_free(msg); + return rc; +} + +static int xua_srv_conn_closed_cb(struct osmo_stream_srv *srv) +{ + struct osmo_ss7_asp *asp = osmo_stream_srv_get_data(srv); + + LOGP(DLSS7, LOGL_INFO, "%s: SCTP connection closed\n", + asp ? asp->cfg.name : "?"); + + /* FIXME: somehow notify ASP FSM and everyone else */ + + return 0; +} + + +/* server has accept()ed a new SCTP association, let's find the ASP for + * it (if any) */ +static int xua_accept_cb(struct osmo_stream_srv_link *link, int fd) +{ + struct osmo_xua_server *oxs = osmo_stream_srv_link_get_data(link); + struct osmo_stream_srv *srv; + struct osmo_ss7_asp *asp; + char *sock_name = osmo_sock_get_name(link, fd); + + LOGP(DLSS7, LOGL_INFO, "%s: New SCTP connection accepted\n", + sock_name); + + srv = osmo_stream_srv_create(oxs, link, fd, + xua_srv_conn_cb, + xua_srv_conn_closed_cb, NULL); + if (!srv) { + LOGP(DLSS7, LOGL_ERROR, "%s: Unable to create stream server " + "for SCTP connection\n", sock_name); + close(fd); + talloc_free(sock_name); + return -1; + } + + asp = osmo_ss7_asp_find_by_socket_addr(fd); + if (!asp) { + LOGP(DLSS7, LOGL_NOTICE, "%s: SCTP connection without matching " + "ASP definition, terminating\n", sock_name); + osmo_stream_srv_destroy(srv); + talloc_free(sock_name); + return -1; + } + LOGP(DLSS7, LOGL_INFO, "%s: matched connection to ASP %s\n", + sock_name, asp->cfg.name); + /* update the ASP reference back to the server over which the + * connection came in */ + asp->server = srv; + /* update the ASP socket name */ + if (asp->sock_name) + talloc_free(asp->sock_name); + asp->sock_name = talloc_reparent(link, asp, sock_name); + /* make sure the conn_cb() is called with the asp as private + * data */ + osmo_stream_srv_set_data(srv, asp); + + return 0; +} + +/*! \brief send a fully encoded msgb via a given ASP + * \param[in] asp Application Server Process through which to send + * \param[in] msg message buffer to transmit. Ownership transferred. + * \returns 0 on success; negative in case of error */ +int osmo_ss7_asp_send(struct osmo_ss7_asp *asp, struct msgb *msg) +{ + OSMO_ASSERT(ss7_initialized); + + switch (asp->cfg.proto) { + case OSMO_SS7_ASP_PROT_SUA: + msgb_sctp_ppid(msg) = SUA_PPID; + break; + case OSMO_SS7_ASP_PROT_M3UA: + msgb_sctp_ppid(msg) = M3UA_PPID; + break; + default: + OSMO_ASSERT(0); + } + + if (asp->cfg.is_server) + osmo_stream_srv_send(asp->server, msg); + else + osmo_stream_cli_send(asp->client, msg); + + return 0; +} + +/*********************************************************************** + * SS7 xUA Server + ***********************************************************************/ + +struct osmo_xua_server * +osmo_ss7_xua_server_find(struct osmo_ss7_instance *inst, enum osmo_ss7_asp_protocol proto, + uint16_t local_port) +{ + struct osmo_xua_server *xs; + + OSMO_ASSERT(ss7_initialized); + llist_for_each_entry(xs, &ss7_xua_servers, list) { + if (proto == xs->cfg.proto && + local_port == xs->cfg.local.port) + return xs; + } + return NULL; +} + +/*! \brief create a new xUA server listening to given ip/port + * \param[in] ctx talloc allocation context + * \param[in] proto protocol (xUA variant) to use + * \param[in] local_port local SCTP port to bind/listen to + * \param[in] local_host local IP address to bind/listen to (optional) + * \returns callee-allocated \ref osmo_xua_server in case of success + */ +struct osmo_xua_server * +osmo_ss7_xua_server_create(struct osmo_ss7_instance *inst, enum osmo_ss7_asp_protocol proto, + uint16_t local_port, const char *local_host) +{ + struct osmo_xua_server *oxs = talloc_zero(inst, struct osmo_xua_server); + int rc; + + OSMO_ASSERT(ss7_initialized); + if (!oxs) + return NULL; + + LOGP(DLSS7, LOGL_INFO, "Creating XUA Server %s:%u\n", + local_host, local_port); + + oxs->cfg.proto = proto; + oxs->cfg.local.port = local_port; + oxs->cfg.local.host = talloc_strdup(oxs, local_host); + + oxs->server = osmo_stream_srv_link_create(oxs); + osmo_stream_srv_link_set_data(oxs->server, oxs); + osmo_stream_srv_link_set_accept_cb(oxs->server, xua_accept_cb); + + osmo_stream_srv_link_set_addr(oxs->server, oxs->cfg.local.host); + osmo_stream_srv_link_set_port(oxs->server, oxs->cfg.local.port); + osmo_stream_srv_link_set_proto(oxs->server, IPPROTO_SCTP); + + rc = osmo_stream_srv_link_open(oxs->server); + if (rc < 0) { + osmo_stream_srv_link_destroy(oxs->server); + oxs->server = NULL; + talloc_free(oxs); + } + + oxs->inst = inst; + llist_add_tail(&oxs->list, &ss7_xua_servers); + + return oxs; +} + +int +osmo_ss7_xua_server_set_local_host(struct osmo_xua_server *xs, const char *local_host) +{ + OSMO_ASSERT(ss7_initialized); + if (xs->cfg.local.host) + talloc_free(xs->cfg.local.host); + xs->cfg.local.host = talloc_strdup(xs, local_host); + + osmo_stream_srv_link_set_addr(xs->server, xs->cfg.local.host); + + return 0; +} + +void osmo_ss7_xua_server_destroy(struct osmo_xua_server *xs) +{ + if (xs->server) { + osmo_stream_srv_link_close(xs->server); + osmo_stream_srv_link_destroy(xs->server); + } + /* FIXME: add asp_list to xua_server so we can iterate it here + * and close all connections established in relation with this + * server */ + llist_del(&xs->list); + talloc_free(xs); +} + +bool osmo_ss7_pc_is_local(struct osmo_ss7_instance *inst, uint32_t pc) +{ + OSMO_ASSERT(ss7_initialized); + if (pc == inst->cfg.primary_pc) + return true; + /* FIXME: Secondary and Capability Point Codes */ + return false; +} + +int osmo_ss7_init(void) +{ + if (ss7_initialized) + return 1; + osmo_fsm_register(&xua_as_fsm); + osmo_fsm_register(&xua_asp_fsm); + ss7_initialized = true; + return 0; +} diff --git a/src/osmo_ss7_hmrt.c b/src/osmo_ss7_hmrt.c new file mode 100644 index 0000000..bc2b8e5 --- /dev/null +++ b/src/osmo_ss7_hmrt.c @@ -0,0 +1,219 @@ +/*********************************************************************** + * MTP Level 3 - Signalling message handling (SMH) Figure 23/Q.704 + ***********************************************************************/ + +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include "xua_internal.h" + +/* convert from M3UA message to MTP-TRANSFER.ind osmo_mtp_prim */ +struct osmo_mtp_prim *m3ua_to_xfer_ind(struct xua_msg *xua) +{ + struct osmo_mtp_prim *prim; + struct osmo_mtp_transfer_param *param; + struct xua_msg_part *data_ie = xua_msg_find_tag(xua, M3UA_IEI_PROT_DATA); + struct m3ua_data_hdr *data_hdr; + struct msgb *upmsg = m3ua_msgb_alloc("M3UA MTP-TRANSFER.ind"); + + if (data_ie->len < sizeof(*data_hdr)) { + /* FIXME: ERROR message */ + msgb_free(upmsg); + return NULL; + } + data_hdr = (struct m3ua_data_hdr *) data_ie->dat; + + /* fill primitive */ + prim = (struct osmo_mtp_prim *) msgb_put(upmsg, sizeof(*prim)); + param = &prim->u.transfer; + osmo_prim_init(&prim->oph, MTP_SAP_USER, + OSMO_MTP_PRIM_TRANSFER, + PRIM_OP_INDICATION, upmsg); + + m3ua_dh_to_xfer_param(param, data_hdr); + /* copy data */ + upmsg->l2h = msgb_put(upmsg, data_ie->len - sizeof(*data_hdr)); + memcpy(upmsg->l2h, data_ie->dat+sizeof(*data_hdr), data_ie->len - sizeof(*data_hdr)); + + return prim; +} + +/* convert from MTP-TRANSFER.req to osmo_mtp_prim */ +static struct xua_msg *mtp_prim_to_m3ua(struct osmo_mtp_prim *prim) +{ + struct msgb *msg = prim->oph.msg; + struct xua_msg *xua = xua_msg_alloc(); + struct osmo_mtp_transfer_param *param = &prim->u.transfer; + struct xua_msg_part *data_part; + struct m3ua_data_hdr data_hdr; + + mtp_xfer_param_to_m3ua_dh(&data_hdr, param); + + xua->hdr = XUA_HDR(M3UA_MSGC_XFER, M3UA_XFER_DATA); + /* Network Appearance: Optional */ + /* Routing Context: Conditional */ + /* Protocol Data: Mandatory */ + data_part = talloc_zero(xua, struct xua_msg_part); + data_part->tag = M3UA_IEI_PROT_DATA; + data_part->len = sizeof(data_hdr) + msgb_l2len(msg); + data_part->dat = talloc_size(data_part, data_part->len); + memcpy(data_part->dat, &data_hdr, sizeof(data_hdr)); + memcpy(data_part->dat+sizeof(data_hdr), msgb_l2(msg), msgb_l2len(msg)); + llist_add_tail(&data_part->entry, &xua->headers); + /* Correlation Id: Optional */ + + return xua; +} + +/* delivery given XUA message to given SS7 user */ +static int deliver_to_mtp_user(const struct osmo_ss7_user *osu, + struct xua_msg *xua) +{ + struct osmo_mtp_prim *prim; + + /* Create MTP-TRANSFER.ind and feed to user */ + prim = m3ua_to_xfer_ind(xua); + prim->u.transfer = xua->mtp; + if (!prim) + return -1; + + return osu->prim_cb(&prim->oph, (void *) osu->priv); +} + +/* HMDC -> HMDT: Message for distribution; Figure 25/Q.704 */ +/* This means it is a message we received from remote/L2, and it is to + * be routed to a local user part */ +static int hmdt_message_for_distribution(struct osmo_ss7_instance *inst, struct xua_msg *xua) +{ + struct m3ua_data_hdr *mdh; + const struct osmo_ss7_user *osu; + uint32_t service_ind; + + switch (xua->hdr.msg_class) { + case M3UA_MSGC_XFER: + switch (xua->hdr.msg_type) { + case M3UA_XFER_DATA: + mdh = data_hdr_from_m3ua(xua); + service_ind = mdh->si & 0xf; + break; + default: + LOGP(DLSS7, LOGL_ERROR, "Unknown M3UA XFER Message " + "Type %u\n", xua->hdr.msg_type); + return -1; + } + break; + case M3UA_MSGC_SNM: + /* FIXME */ + /* FIXME: SI = Signalling Network Management -> SRM/SLM/STM */ + /* FIXME: SI = Signalling Network Testing and Maintenance -> SLTC */ + default: + /* Discard Message */ + LOGP(DLSS7, LOGL_ERROR, "Unknown M3UA Message Class %u\n", + xua->hdr.msg_class); + return -1; + } + + /* Check for local SSN registered for this DPC/SSN */ + osu = inst->user[service_ind]; + if (osu) { + return deliver_to_mtp_user(osu, xua); + } else { + LOGP(DLSS7, LOGL_NOTICE, "No MTP-User for SI %u\n", service_ind); + /* Discard Message */ + /* FIXME: User Part Unavailable HMDT -> HMRT */ + return -1; + } +} + +/* HMDC->HMRT Msg For Routing; Figure 26/Q.704 */ +/* local message was receive d from L4, SRM, SLM, STM or SLTC, or + * remote message received from L2 and HMDC determined msg for routing */ +static int hmrt_message_for_routing(struct osmo_ss7_instance *inst, + struct xua_msg *xua) +{ + uint32_t dpc = xua->mtp.dpc; + struct osmo_ss7_route *rt; + + /* find route for DPC */ + /* FIXME: unify with gen_mtp_transfer_req_xua() */ + rt = osmo_ss7_route_lookup(inst, dpc); + if (rt) { + /* FIXME: DPC SP restart? */ + /* FIXME: DPC Congested? */ + /* FIXME: Select link based on SLS */ + /* FIXME: Transmit over respective Link */ + if (rt->dest.as) { + struct osmo_ss7_as *as = rt->dest.as; + switch (as->cfg.proto) { + case OSMO_SS7_ASP_PROT_M3UA: + return m3ua_tx_xua_as(as,xua); + default: + LOGP(DLSS7, LOGL_ERROR, "MTP message " + "for ASP of unknown protocol%u\n", + as->cfg.proto); + break; + } + } else if (rt->dest.linkset) { + LOGP(DLSS7, LOGL_ERROR, "MTP-TRANSFER.req for linkset" + "%s unsupported\n",rt->dest.linkset->cfg.name); + } else + OSMO_ASSERT(0); + } else { + LOGP(DLSS7, LOGL_ERROR, "MTP-TRANSFER.req for DPC %u: " + "no route!\n", dpc); + /* DPC unknown HMRT -> MGMT */ + /* Message Received for inaccesible SP HMRT ->RTPC */ + /* Discard Message */ + } + return -1; +} + +/* HMDC: Received Message L2 -> L3; Figure 24/Q.704 */ +/* This means a message was received from L2 and we have to decide if it + * is for the local stack (HMDT) or for routng (HMRT) */ +int m3ua_hmdc_rx_from_l2(struct osmo_ss7_instance *inst, struct xua_msg *xua) +{ + uint32_t dpc = xua->mtp.dpc; + if (osmo_ss7_pc_is_local(inst, dpc)) { + return hmdt_message_for_distribution(inst, xua); + } else { + return hmrt_message_for_routing(inst, xua); + } +} + +/* MTP-User requests to send a MTP-TRANSFER.req via the stack */ +int osmo_ss7_user_mtp_xfer_req(struct osmo_ss7_instance *inst, + struct osmo_mtp_prim *omp) +{ + struct xua_msg *xua; + + OSMO_ASSERT(omp->oph.sap == MTP_SAP_USER); + + switch (OSMO_PRIM_HDR(&omp->oph)) { + case OSMO_PRIM(OSMO_MTP_PRIM_TRANSFER, PRIM_OP_REQUEST): + xua = mtp_prim_to_m3ua(omp); + xua->mtp = omp->u.transfer; + /* normally we would call hmrt_message_for_routing() + * here, if we were to follow the state diagrams of the + * ITU-T Q.70x specifications. However, what if a local + * MTP user sends a MTP-TRANSFER.req to a local SSN? + * This wouldn't work as per the spec, but I believe it + * is a very useful feature (aka "loopback device" in + * IPv4). So we call m3ua_hmdc_rx_from_l2() just like + * the MTP-TRANSFER had been received from L2. */ + return m3ua_hmdc_rx_from_l2(inst, xua); + default: + LOGP(DLSS7, LOGL_ERROR, "Ignoring unknown primitive %u:%u\n", + omp->oph.primitive, omp->oph.operation); + return -1; + } +} diff --git a/src/osmo_ss7_vty.c b/src/osmo_ss7_vty.c new file mode 100644 index 0000000..80cd4d0 --- /dev/null +++ b/src/osmo_ss7_vty.c @@ -0,0 +1,681 @@ +/* Core SS7 Instance/Linkset/Link/AS/ASP VTY Interface */ + +/* (C) 2015-2017 by Harald Welte + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include + +#define CS7_STR "ITU-T Signaling System 7\n" +#define PC_STR "Point Code\n" + +/*********************************************************************** + * Core CS7 Configuration + ***********************************************************************/ + +static const struct value_string ss7_network_indicator_vals[] = { + { 0, "international" }, + { 1, "spare" }, + { 2, "national" }, + { 3, "reserved" }, + { 0, NULL } +}; + +/* cs7 network-indicator */ +DEFUN(cs7_net_ind, cs7_net_ind_cmd, + "cs7 network-indicator (international | national | reserved | spare)", + CS7_STR "Configure the Network Indicator\n" + "International Network\n" + "National Network\n" + "Reserved Network\n" + "Spare Network\n") +{ + struct osmo_ss7_instance *inst = FIXME; + int ni = get_string_value(ss7_network_indicator_vals, argv[0]); + + inst->cfg.network_indicator = ni; + return CMD_SUCCESS; +} + +/* TODO: cs7 point-code format */ +DEFUN(cs7_pc_format, cs7_pc_format_cmd, + "cs7 point-code format <1-24> [<1-23> [<1-22>]]", + CS7_STR PC_STR "Configure Point Code Format\n" + "Length of first PC component\n" + "Length of second PC component\n" + "Length of third PC component\n") +{ + struct osmo_ss7_instance *inst = FIXME; + int argind = 0; + + inst->cfg.pc_fmt.component_len[0] = atoi(argv[argind++]); + + if (argc >= 2) + inst->cfg.pc_fmt.component_len[1] = atoi(argv[argind++]); + else + inst->cfg.pc_fmt.component_len[1] = 0; + + if (argc >= 3) + inst->cfg.pc_fmt.component_len[2] = atoi(argv[argind++]); + else + inst->cfg.pc_fmt.component_len[2] = 0; + + return CMD_SUCCESS; +} + +DEFUN(cs7_pc_format_def, cs7_pc_format_def_cmd, + "cs7 point-code format default", + CS7_STR PC_STR "Configure Point Code Format\n" + "Default Point Code Format (3.8.3)\n") +{ + struct osmo_ss7_instance *inst = FIXME; + inst->cfg.pc_fmt.component_len[0] = 3; + inst->cfg.pc_fmt.component_len[1] = 8; + inst->cfg.pc_fmt.component_len[2] = 3; + return CMD_SUCCESS; +} + + +/* cs7 point-code delimiter */ +DEFUN(cs7_pc_delimiter, cs7_pc_delimiter_cmd, + "cs7 point-code delimiter (default|dash)", + CS7_STR PC_STR "Configure Point Code Delimiter\n" + "Use dot as delimiter\n" + "User dash as delimiter\n") +{ + struct osmo_ss7_instance *inst = FIXME; + + if (!strcmp(argv[0], "dash")) + inst->cfg.pc_fmt.delimiter = '-'; + else + inst->cfg.pc_fmt.delimiter = '.'; + + return CMD_SUCCESS; +} + +DEFUN(cs7_point_code, cs7_point_code_cmd, + "cs7 point-code POINT_CODE", + CS7_STR "Configure the local Point Code\n" + "Point Code\n") +{ + struct osmo_ss7_instance *inst = FIXME; + uint32_t pc = osmo_ss7_pointcode_parse(inst, argv[0]); + + inst->cfg.primary_pc = pc; + return CMD_SUCCESS; +} +/* TODO: cs7 secondary-pc */ +/* TODO: cs7 capability-pc */ + + +/*********************************************************************** + * Routing Table Configuration + ***********************************************************************/ + +static struct cmd_node rtable_node = { + L_CS7_RTABLE_NODE, + "%s(config-cs7-rt)# ", + 1, +}; + +DEFUN(cs7_route_table, cs7_route_table_cmd, + "cs7 route-table system", + CS7_STR "Specify the name of the route table\n" + "Name of the route table\n") +{ + struct osmo_ss7_instance *inst = FIXME; + struct osmo_ss7_route_table *rtable; + + rtable = inst->rtable_system; + vty->node = L_CS7_RTABLE_NODE; + vty->index = rtable; + vty->index_sub = &rtable->cfg.description; + + return CMD_SUCCESS; +} + +DEFUN(cs7_rt_upd, cs7_rt_upd_cmd, + "update route POINT_CODE [MASK | LENGTH] linkset LS_NAME [priority PRIO] [qos-class (CLASS | default", + "Update the Route\n" + "Update the Route\n" + "Destination Point Code\n" + "Point Code Mask\n" + "Point Code Length\n" + "Specify Destination Linkset\n" + "Linkset Name\n" + "Specity Priority\n" + "Priority\n" + "Specify QoS Class\n" + "QoS Class\n" + "Default QoS Class\n") +{ + struct osmo_ss7_route_table *rtable = vty->index; + struct osmo_ss7_route *rt; + uint32_t dpc = osmo_ss7_pointcode_parse(rtable->inst, argv[0]); + uint32_t mask = osmo_ss7_pointcode_parse_mask_or_len(rtable->inst, argv[1]); + const char *ls_name = argv[2]; + unsigned int argind; + + rt = osmo_ss7_route_create(rtable, dpc, mask, ls_name); + if (!rt) + return CMD_WARNING; + + argind = 3; + if (argc > argind && !strcmp(argv[argind], "priority")) { + argind++; + rt->cfg.priority = atoi(argv[argind++]); + } + + if (argc > argind && !strcmp(argv[argind], "qos-class")) { + argind++; + rt->cfg.qos_class = atoi(argv[argind++]); + } + + return CMD_SUCCESS; +} + +DEFUN(cs7_rt_rem, cs7_rt_rem_cmd, + "remove route POINT_CODE [MASK | LENGTH]", + "Remove a Route\n" + "Remove a Route\n" + "Destination Point Code\n" + "Point Code Mask\n" + "Point Code Length\n") +{ + struct osmo_ss7_route_table *rtable = vty->index; + struct osmo_ss7_route *rt; + uint32_t dpc = osmo_ss7_pointcode_parse(rtable->inst, argv[0]); + uint32_t mask = osmo_ss7_pointcode_parse_mask_or_len(rtable->inst, argv[1]); + + rt = osmo_ss7_route_find_dpc_mask(rtable, dpc, mask); + if (!rt) + return CMD_WARNING; + + osmo_ss7_route_destroy(rt); + return CMD_SUCCESS; +} + +static int config_write_rtable(struct vty *vty) +{ + struct osmo_ss7_route_table *rtable = vty->index; + struct osmo_ss7_route *rt; + + vty_out(vty, "cs7 route-table %s%s", rtable->cfg.name, VTY_NEWLINE); + llist_for_each_entry(rt, &rtable->routes, list) { + vty_out(vty, " update route %s %s linkset %s", + osmo_ss7_pointcode_print(rtable->inst, rt->cfg.pc), + osmo_ss7_pointcode_print(rtable->inst, rt->cfg.mask), + rt->cfg.linkset_name); + if (rt->cfg.priority) + vty_out(vty, " priority %u", rt->cfg.priority); + if (rt->cfg.qos_class) + vty_out(vty, " qos-class %u", rt->cfg.qos_class); + vty_out(vty, "%s", VTY_NEWLINE); + } + return 0; +} + +/*********************************************************************** + * SUA Configuration + ***********************************************************************/ + +static struct cmd_node sua_node = { + L_CS7_SUA_NODE, + "%s(config-cs7-sua)# ", + 1, +}; + +DEFUN(cs7_sua, cs7_sua_cmd, + "cs7 sua <0-65534>", + CS7_STR + "Configure/Enable SUA\n" + "SCTP Port number for SUA\n") +{ + struct osmo_ss7_instance *inst = FIXME; + struct osmo_xua_server *xs; + uint16_t port = atoi(argv[0]); + + xs = osmo_ss7_xua_server_find(inst, OSMO_SS7_ASP_PROT_SUA, port); + if (!xs) { + xs = osmo_ss7_xua_server_create(inst, OSMO_SS7_ASP_PROT_SUA, port, NULL); + if (!xs) + return CMD_SUCCESS; + } + + vty->node = L_CS7_SUA_NODE; + vty->index = xs; + return CMD_SUCCESS; +} + +DEFUN(sua_local_ip, sua_local_ip_cmd, + "local-ip A.B.C.D", + "Configure the Local IP Address for SUA\n" + "IP Address to use for SUA\n") +{ + struct osmo_xua_server *xs = vty->index; + + osmo_ss7_xua_server_set_local_host(xs, argv[0]); + return CMD_SUCCESS; +} + +enum osmo_ss7_asp_protocol parse_asp_proto(const char *protocol) +{ + return get_string_value(osmo_ss7_asp_protocol_vals, protocol); +} + +static int config_write_sua(struct vty *vty) +{ + struct osmo_xua_server *xs = vty->index; + + vty_out(vty, "cs7 sua %u%s", xs->cfg.local.port, VTY_NEWLINE); + vty_out(vty, " local-ip %s%s", xs->cfg.local.host, VTY_NEWLINE); + return 0; +} + +/*********************************************************************** + * M3UA Configuration + ***********************************************************************/ + +static struct cmd_node m3ua_node = { + L_CS7_M3UA_NODE, + "%s(config-cs7-m3ua)# ", + 1, +}; + +DEFUN(cs7_m3ua, cs7_m3ua_cmd, + "cs7 m3ua <0-65534>", + CS7_STR + "Configure/Enable M3UA\n" + "SCTP Port number for M3UA\n") +{ + struct osmo_ss7_instance *inst = FIXME; + struct osmo_xua_server *xs; + uint16_t port = atoi(argv[0]); + + xs = osmo_ss7_xua_server_find(inst, OSMO_SS7_ASP_PROT_M3UA, port); + if (!xs) { + xs = osmo_ss7_xua_server_create(inst, OSMO_SS7_ASP_PROT_M3UA, port, NULL); + if (!xs) + return CMD_SUCCESS; + } + + vty->node = L_CS7_M3UA_NODE; + vty->index = xs; + return CMD_SUCCESS; +} + +DEFUN(m3ua_local_ip, m3ua_local_ip_cmd, + "local-ip A.B.C.D", + "Configure the Local IP Address for M3UA\n" + "IP Address to use for M3UA\n") +{ + struct osmo_xua_server *xs = vty->index; + + osmo_ss7_xua_server_set_local_host(xs, argv[0]); + return CMD_SUCCESS; +} + +static int config_write_m3ua(struct vty *vty) +{ + struct osmo_xua_server *xs = vty->index; + + vty_out(vty, "cs7 m3ua %u%s", xs->cfg.local.port, VTY_NEWLINE); + vty_out(vty, " local-ip %s%s", xs->cfg.local.host, VTY_NEWLINE); + return 0; +} + +/*********************************************************************** + * Application Server Process + ***********************************************************************/ + +static struct cmd_node asp_node = { + L_CS7_ASP_NODE, + "%s(config-cs7-asp)# ", + 1, +}; + +DEFUN(cs7_asp, cs7_asp_cmd, + "cs7 asp NAME <0-65535> <0-65535> [m3ua | sua]", + CS7_STR + "Configure Application Server Process\n" + "Name of ASP\n" + "Remote SCTP port number\n" + "Local SCTP port number\n" + "M3UA Protocol\n" + "SUA Protocol\n") +{ + struct osmo_ss7_instance *inst = FIXME; + const char *name = argv[0]; + uint16_t remote_port = atoi(argv[1]); + uint16_t local_port = atoi(argv[2]); + enum osmo_ss7_asp_protocol protocol = parse_asp_proto(argv[3]); + struct osmo_ss7_asp *asp; + + if (protocol == OSMO_SS7_ASP_PROT_NONE) + return CMD_WARNING; + + asp = osmo_ss7_asp_find_or_create(inst, name, remote_port, local_port, protocol); + if (!asp) + return CMD_WARNING; + + vty->node = L_CS7_ASP_NODE; + vty->index = asp; + vty->index_sub = &asp->cfg.description; + return CMD_SUCCESS; +} + +DEFUN(asp_remote_ip, asp_remote_ip_cmd, + "remote-ip A.B.C.D", + "Specity Remote IP Address of ASP\n" + "Remote IP Address of ASP\n") +{ + struct osmo_ss7_asp *asp = vty->index; + osmo_talloc_replace_string(asp, &asp->cfg.remote.host, argv[0]); + return CMD_SUCCESS; +} + +DEFUN(asp_qos_clas, asp_qos_class_cmd, + "qos-class <0-255>", + "Specity QoS Class of ASP\n" + "QoS Class of ASP\n") +{ + struct osmo_ss7_asp *asp = vty->index; + asp->cfg.qos_class = atoi(argv[0]); + return CMD_SUCCESS; +} + +DEFUN(asp_block, asp_block_cmd, + "block", + "Allows a SCTP Association with ASP, but doesn't let it become active\n") +{ + struct osmo_ss7_asp *asp = vty->index; + vty_out(vty, "Not supported yet\n"); + return CMD_WARNING; +} + +DEFUN(asp_shutdown, asp_shutdown_cmd, + "shutdown", + "Terminates SCTP association; New associations will be rejected\n") +{ + struct osmo_ss7_asp *asp = vty->index; + vty_out(vty, "Not supported yet\n"); + return CMD_WARNING; +} + +static int config_write_asp(struct vty *vty) +{ + struct osmo_ss7_asp *asp = vty->index; + + vty_out(vty, "cs7 asp %s %u %u %s%s", + asp->cfg.name, asp->cfg.remote.port, asp->cfg.local.port, + osmo_ss7_asp_protocol_name(asp->cfg.proto), VTY_NEWLINE); + vty_out(vty, " remote-ip %s%s", asp->cfg.remote.host, VTY_NEWLINE); + if (asp->cfg.qos_class) + vty_out(vty, " qos-class %u%s", asp->cfg.qos_class, VTY_NEWLINE); + return 0; +} + +/*********************************************************************** + * Application Server + ***********************************************************************/ + +static struct cmd_node as_node = { + L_CS7_AS_NODE, + "%s(config-cs7-as)# ", + 1, +}; + +DEFUN(cs7_as, cs7_as_cmd, + "cs7 as NAME [m3ua | sua]", + CS7_STR + "Configure an Application Server\n" + "Name of the Application Server\n" + "M3UA Application Server\n" + "SUA Application Server\n") +{ + struct osmo_ss7_as *as; + const char *name = argv[0]; + enum osmo_ss7_asp_protocol protocol = parse_asp_proto(argv[1]); + + if (protocol == OSMO_SS7_ASP_PROT_NONE) + return CMD_WARNING; + + /* FIXME */ + as->cfg.name = talloc_strdup(as, name); + + vty->node = L_CS7_AS_NODE; + vty->index = as; + vty->index_sub = &as->cfg.description; + + return CMD_SUCCESS; +} + +/* TODO: routing-key */ +DEFUN(as_asp, as_asp_cmd, + "asp NAME", + "Specify that a given ASP is part of this AS\n" + "Name of ASP to be added to AS\n") +{ + struct osmo_ss7_as *as = vty->index; + + if (osmo_ss7_as_add_asp(as, argv[0])) + return CMD_WARNING; + + return CMD_SUCCESS; +} + +DEFUN(as_no_asp, as_no_asp_cmd, + "no asp NAME", + NO_STR "Specify ASP to be removed from this AS\n" + "Name of ASP to be removed\n") +{ + struct osmo_ss7_as *as = vty->index; + + if (osmo_ss7_as_del_asp(as, argv[0])) + return CMD_WARNING; + + return CMD_SUCCESS; +} + +DEFUN(as_traf_mode, as_traf_mode_cmd, + "traffic-mode (broadcast | loadshare | roundrobin | override)", + "Specifies traffic mode of operation of the ASP within the AS\n" + "Broadcast to all ASP within AS\n" + "Share Load among all ASP within AS\n" + "Round-Robin between all ASP within AS\n" + "Override\n") +{ + struct osmo_ss7_as *as = vty->index; + + as->cfg.mode = get_string_value(osmo_ss7_as_traffic_mode_vals, argv[0]); + return CMD_WARNING; +} + +DEFUN(as_recov_tout, as_recov_tout_cmd, + "recovery-timeout <1-2000>", + "Specifies the recovery timeout value in milliseconds\n" + "Recovery Timeout in Milliseconds\n") +{ + struct osmo_ss7_as *as = vty->index; + as->cfg.recovery_timeout_msec = atoi(argv[0]); + return CMD_SUCCESS; +} + +DEFUN(as_qos_clas, as_qos_class_cmd, + "qos-class <0-255>", + "Specity QoS Class of AS\n" + "QoS Class of AS\n") +{ + struct osmo_ss7_as *as = vty->index; + as->cfg.qos_class = atoi(argv[0]); + return CMD_SUCCESS; +} + +const struct value_string mtp_si_vals[] = { + { MTP_SI_SCCP, "sccp" }, + { MTP_SI_TUP, "tup" }, + { MTP_SI_ISUP, "isup" }, + { MTP_SI_DUP, "dup" }, + { MTP_SI_TESTING, "testing" }, + { MTP_SI_B_ISUP, "b-isup" }, + { MTP_SI_SAT_ISUP, "sat-isup" }, + { MTP_SI_AAL2_SIG, "aal2" }, + { MTP_SI_BICC, "bicc" }, + { MTP_SI_GCP, "h248" }, + { 0, NULL } +}; + +DEFUN(as_rout_key, as_rout_key_cmd, + "routing-key RCONTEXT DPC [si {aal2 | bicc | b-isup | h248 | isup | sat-isup | sccp | tup }] [ssn SSN]}", + "Define a routing key\n" + "Routing context number\n" + "Destination Point Code\n" + "Optional Match on Service Indicator\n" + "ATM Adaption Layer 2\n" + "Bearer Independent Call Control\n" + "Broadband ISDN User Part\n" + "H.248\n" + "ISDN User Part\n" + "Sattelite ISDN User Part\n" + "Signalling Connection Control Part\n" + "Telephony User Part\n" + "Optional Match on Sub-System Number\n" + "Sub-System Number to match on\n") +{ + struct osmo_ss7_as *as = vty->index; + uint32_t key = atoi(argv[0]); + struct osmo_ss7_routing_key *rkey; + int argind; + + rkey = osmo_ss7_rkey_find_or_create(as, key); + if (!rkey) + return CMD_WARNING; + + rkey->pc = osmo_ss7_pointcode_parse(as->inst, argv[1]); + argind = 2; + + if (!strcmp(argv[argind], "si")) { + const char *si_str; + argind++; + si_str = argv[argind++]; + /* parse numeric SI from string */ + rkey->si = get_string_value(mtp_si_vals, si_str); + } + if (!strcmp(argv[argind], "ssn")) { + argind++; + rkey->ssn = atoi(argv[argind]); + } + + return CMD_SUCCESS; +} + +static int config_write_as(struct vty *vty) +{ + struct osmo_ss7_as *as = vty->index; + struct osmo_ss7_routing_key *rkey; + unsigned int i; + + vty_out(vty, "cs7 as %s %s%s", as->cfg.name, + osmo_ss7_asp_protocol_name(as->cfg.proto), VTY_NEWLINE); + for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) { + struct osmo_ss7_asp *asp = as->cfg.asps[i]; + if (!asp) + continue; + vty_out(vty, " asp %s%s", asp->cfg.name, VTY_NEWLINE); + } + if (as->cfg.mode != OSMO_SS7_AS_TMOD_LOADSHARE) + vty_out(vty, " traffic-mode %s%s", + osmo_ss7_as_traffic_mode_name(as->cfg.mode), VTY_NEWLINE); + if (as->cfg.recovery_timeout_msec != 2000) { + vty_out(vty, " recovery-timeout %u%s", + as->cfg.recovery_timeout_msec, VTY_NEWLINE); + } + vty_out(vty, " qos-class %u%s", as->cfg.qos_class, VTY_NEWLINE); + rkey = &as->cfg.routing_key; + vty_out(vty, " routing-key %u %s", rkey->context, + osmo_ss7_pointcode_print(as->inst, rkey->pc)); + if (rkey->si) + vty_out(vty, " si %s", + get_value_string(mtp_si_vals, rkey->si)); + if (rkey->ssn) + vty_out(vty, " ssn %u", rkey->ssn); + vty_out(vty, "%s", VTY_NEWLINE); + + return 0; +} + +int osmo_ss7_vty_init(void) +{ + install_element(CONFIG_NODE, &cs7_net_ind_cmd); + install_element(CONFIG_NODE, &cs7_point_code_cmd); + install_element(CONFIG_NODE, &cs7_pc_format_cmd); + install_element(CONFIG_NODE, &cs7_pc_format_def_cmd); + install_element(CONFIG_NODE, &cs7_pc_delimiter_cmd); + + install_node(&rtable_node, config_write_rtable); + vty_install_default(L_CS7_RTABLE_NODE); + install_element(CONFIG_NODE, &cs7_route_table_cmd); + install_element(L_CS7_RTABLE_NODE, &cfg_description_cmd); + install_element(L_CS7_RTABLE_NODE, &cs7_rt_upd_cmd); + install_element(L_CS7_RTABLE_NODE, &cs7_rt_rem_cmd); + + install_node(&sua_node, config_write_sua); + vty_install_default(L_CS7_SUA_NODE); + install_element(CONFIG_NODE, &cs7_sua_cmd); + install_element(L_CS7_SUA_NODE, &sua_local_ip_cmd); + + install_node(&m3ua_node, config_write_m3ua); + vty_install_default(L_CS7_M3UA_NODE); + install_element(CONFIG_NODE, &cs7_m3ua_cmd); + install_element(L_CS7_M3UA_NODE, &m3ua_local_ip_cmd); + + install_node(&asp_node, config_write_asp); + vty_install_default(L_CS7_ASP_NODE); + install_element(CONFIG_NODE, &cs7_asp_cmd); + install_element(L_CS7_ASP_NODE, &cfg_description_cmd); + install_element(L_CS7_ASP_NODE, &asp_remote_ip_cmd); + install_element(L_CS7_ASP_NODE, &asp_qos_class_cmd); + install_element(L_CS7_ASP_NODE, &asp_block_cmd); + install_element(L_CS7_ASP_NODE, &asp_shutdown_cmd); + + install_node(&as_node, config_write_as); + vty_install_default(L_CS7_AS_NODE); + install_element(CONFIG_NODE, &cs7_as_cmd); + install_element(L_CS7_AS_NODE, &cfg_description_cmd); + install_element(L_CS7_AS_NODE, &as_asp_cmd); + install_element(L_CS7_AS_NODE, &as_no_asp_cmd); + install_element(L_CS7_AS_NODE, &as_traf_mode_cmd); + install_element(L_CS7_AS_NODE, &as_recov_tout_cmd); + install_element(L_CS7_AS_NODE, &as_qos_class_cmd); + install_element(L_CS7_AS_NODE, &as_rout_key_cmd); + + return 0; +} diff --git a/src/xua_as_fsm.c b/src/xua_as_fsm.c new file mode 100644 index 0000000..887a9ec --- /dev/null +++ b/src/xua_as_fsm.c @@ -0,0 +1,308 @@ +/* SCCP M3UA / SUA AS osmo_fsm according to RFC3868 4.3.1 / RFC4666 4.3.2 */ +/* (C) Copyright 2017 by Harald Welte + * + * All Rights reserved. + * + * Based on Erlang implementation xua_as_fsm.erl in osmo-ss7.git + */ + +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "xua_asp_fsm.h" +#include "xua_as_fsm.h" +#include "xua_internal.h" + +static struct msgb *encode_notify(const struct m3ua_notify_params *npar) +{ + struct xua_msg *xua = m3ua_encode_notify(npar); + struct msgb *msg = xua_to_msg(M3UA_VERSION, xua); + xua_msg_free(xua); + return msg; +} + +static int asp_notify_all_as(struct osmo_ss7_as *as, struct m3ua_notify_params *npar) +{ + struct msgb *msg; + unsigned int i, sent = 0; + + /* iterate over all non-DOWN ASPs and send them the message */ + for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) { + struct osmo_ss7_asp *asp = as->cfg.asps[i]; + + if (!asp) + continue; + + if (!asp->fi || asp->fi->state == XUA_ASP_S_DOWN) + continue; + + /* Optional: ASP Identifier (if sent in ASP-UP) */ + if (asp->asp_id_present) { + npar->presence |= NOTIFY_PAR_P_ASP_ID; + npar->asp_id = asp->asp_id; + } else + npar->presence &= ~NOTIFY_PAR_P_ASP_ID; + + /* TODO: Optional Routing Context */ + + msg = encode_notify(npar); + osmo_ss7_asp_send(asp, msg); + sent++; + } + + return sent; +} + + +/*********************************************************************** + * Actual FSM + ***********************************************************************/ + +#define S(x) (1 << (x)) + +enum xua_as_state { + XUA_AS_S_DOWN, + XUA_AS_S_INACTIVE, + XUA_AS_S_ACTIVE, + XUA_AS_S_PENDING, +}; + +static const struct value_string xua_as_event_names[] = { + { XUA_ASPAS_ASP_INACTIVE_IND, "ASPAS-ASP_INACTIVE.ind" }, + { XUA_ASPAS_ASP_DOWN_IND, "ASPAS-ASP_DOWN.ind" }, + { XUA_ASPAS_ASP_ACTIVE_IND, "ASPAS-ASP_ACTIVE.ind" }, + { 0, NULL } +}; + +struct xua_as_fsm_priv { + struct osmo_ss7_as *as; +}; + +/* is any other ASP in this AS in state != DOWN? */ +static bool check_any_other_asp_not_down(struct osmo_ss7_as *as, struct osmo_ss7_asp *asp_cmp) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) { + struct osmo_ss7_asp *asp = as->cfg.asps[i]; + if (!asp) + continue; + + if (asp_cmp == asp) + continue; + + if (asp->fi && asp->fi->state != XUA_ASP_S_DOWN) + return true; + } + + return false; +} + +/* is any other ASP in this AS in state ACTIVE? */ +static bool check_any_other_asp_in_active(struct osmo_ss7_as *as, struct osmo_ss7_asp *asp_cmp) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) { + struct osmo_ss7_asp *asp = as->cfg.asps[i]; + if (!asp) + continue; + + if (asp_cmp == asp) + continue; + + if (asp->fi && asp->fi->state == XUA_ASP_S_ACTIVE) + return true; + } + + return false; +} + + +static void xua_as_fsm_down(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + switch (event) { + case XUA_ASPAS_ASP_INACTIVE_IND: + /* one ASP transitions into ASP-INACTIVE */ + osmo_fsm_inst_state_chg(fi, XUA_AS_S_INACTIVE, 0, 0); + break; + case XUA_ASPAS_ASP_DOWN_IND: + /* ignore */ + break; + } +} + +/* onenter call-back responsible of transmitting NTFY to all ASPs in + * case of AS state changes */ +static void xua_as_fsm_onenter(struct osmo_fsm_inst *fi, uint32_t old_state) +{ + struct xua_as_fsm_priv *xafp = (struct xua_as_fsm_priv *) fi->priv; + struct m3ua_notify_params npar = { + .status_type = M3UA_NOTIFY_T_STATCHG, + }; + + switch (fi->state) { + case XUA_AS_S_INACTIVE: + npar.status_info = M3UA_NOTIFY_I_AS_INACT; + break; + case XUA_AS_S_ACTIVE: + npar.status_info = M3UA_NOTIFY_I_AS_ACT; + break; + case XUA_AS_S_PENDING: + npar.status_info = M3UA_NOTIFY_I_AS_PEND; + break; + default: + return; + } + + asp_notify_all_as(xafp->as, &npar); +}; + +static void xua_as_fsm_inactive(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct xua_as_fsm_priv *xafp = (struct xua_as_fsm_priv *) fi->priv; + struct osmo_ss7_asp *asp = data; + + switch (event) { + case XUA_ASPAS_ASP_DOWN_IND: + /* one ASP transitions into ASP-DOWN */ + if (check_any_other_asp_not_down(xafp->as, asp)) { + /* ignore, we stay AS_INACTIVE */ + } else + osmo_fsm_inst_state_chg(fi, XUA_AS_S_DOWN, 0, 0); + break; + case XUA_ASPAS_ASP_ACTIVE_IND: + /* one ASP transitions into ASP-ACTIVE */ + osmo_fsm_inst_state_chg(fi, XUA_AS_S_ACTIVE, 0, 0); + break; + case XUA_ASPAS_ASP_INACTIVE_IND: + /* ignore */ + break; + } +} + +static void xua_as_fsm_active(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct xua_as_fsm_priv *xafp = (struct xua_as_fsm_priv *) fi->priv; + struct osmo_ss7_asp *asp = data; + + switch (event) { + case XUA_ASPAS_ASP_DOWN_IND: + case XUA_ASPAS_ASP_INACTIVE_IND: + if (check_any_other_asp_in_active(xafp->as, asp)) { + /* ignore, we stay AS_ACTIVE */ + } else { + osmo_fsm_inst_state_chg(fi, XUA_AS_S_PENDING, 0, 0); + /* FIXME: Start T(r) */ + /* FIXME: Queue all signalling messages until + * recovery or T(r) expiry */ + } + break; + case XUA_ASPAS_ASP_ACTIVE_IND: + /* ignore */ + break; + } +} + +static void xua_as_fsm_pending(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + switch (event) { + case XUA_ASPAS_ASP_ACTIVE_IND: + /* one ASP transitions into ASP-ACTIVE */ + osmo_fsm_inst_state_chg(fi, XUA_AS_S_ACTIVE, 0, 0); + break; + case XUA_ASPAS_ASP_INACTIVE_IND: + /* ignore */ + break; + case XUA_ASPAS_ASP_DOWN_IND: + /* ignore */ + break; + } +} + +static const struct osmo_fsm_state xua_as_fsm_states[] = { + [XUA_AS_S_DOWN] = { + .in_event_mask = S(XUA_ASPAS_ASP_INACTIVE_IND) | + S(XUA_ASPAS_ASP_DOWN_IND), + .out_state_mask = S(XUA_AS_S_DOWN) | + S(XUA_AS_S_INACTIVE), + .name = "AS_DOWN", + .action = xua_as_fsm_down, + }, + [XUA_AS_S_INACTIVE] = { + .in_event_mask = S(XUA_ASPAS_ASP_DOWN_IND) | + S(XUA_ASPAS_ASP_ACTIVE_IND) | + S(XUA_ASPAS_ASP_INACTIVE_IND), + .out_state_mask = S(XUA_AS_S_DOWN) | + S(XUA_AS_S_INACTIVE) | + S(XUA_AS_S_ACTIVE), + .name = "AS_INACTIVE", + .action = xua_as_fsm_inactive, + .onenter = xua_as_fsm_onenter, + }, + [XUA_AS_S_ACTIVE] = { + .in_event_mask = S(XUA_ASPAS_ASP_DOWN_IND) | + S(XUA_ASPAS_ASP_INACTIVE_IND) | + S(XUA_ASPAS_ASP_ACTIVE_IND), + .out_state_mask = S(XUA_AS_S_ACTIVE) | + S(XUA_AS_S_PENDING), + .name = "AS_ACTIVE", + .action = xua_as_fsm_active, + .onenter = xua_as_fsm_onenter, + }, + [XUA_AS_S_PENDING] = { + .in_event_mask = S(XUA_ASPAS_ASP_INACTIVE_IND) | + S(XUA_ASPAS_ASP_DOWN_IND) | + S(XUA_ASPAS_ASP_ACTIVE_IND), + .out_state_mask = S(XUA_AS_S_DOWN) | + S(XUA_AS_S_INACTIVE) | + S(XUA_AS_S_ACTIVE) | + S(XUA_AS_S_PENDING), + .name = "AS_PENDING", + .action = xua_as_fsm_pending, + .onenter = xua_as_fsm_onenter, + }, +}; + +struct osmo_fsm xua_as_fsm = { + .name = "XUA_AS", + .states = xua_as_fsm_states, + .num_states = ARRAY_SIZE(xua_as_fsm_states), + .log_subsys = DLSS7, + .event_names = xua_as_event_names, +}; + +/*! \brief Start an AS FSM for a given Application Server + * \param[in] as Application Server for which to start the AS FSM + * \param[in] log_level Logging level for logging of this FSM + * \returns FSM instance in case of success; NULL in case of error */ +struct osmo_fsm_inst *xua_as_fsm_start(struct osmo_ss7_as *as, int log_level) +{ + struct osmo_fsm_inst *fi; + struct xua_as_fsm_priv *xafp; + + fi = osmo_fsm_inst_alloc(&xua_as_fsm, as, NULL, log_level, as->cfg.name); + + xafp = talloc_zero(fi, struct xua_as_fsm_priv); + if (!xafp) { + osmo_fsm_inst_term(fi, OSMO_FSM_TERM_ERROR, NULL); + return NULL; + } + xafp->as = as; + + fi->priv = xafp; + + return fi; +} diff --git a/src/xua_as_fsm.h b/src/xua_as_fsm.h new file mode 100644 index 0000000..3b8e5b7 --- /dev/null +++ b/src/xua_as_fsm.h @@ -0,0 +1,13 @@ +#pragma once + +struct osmo_ss7_as; + +enum xua_as_event { + XUA_ASPAS_ASP_INACTIVE_IND, + XUA_ASPAS_ASP_DOWN_IND, + XUA_ASPAS_ASP_ACTIVE_IND, +}; + +extern struct osmo_fsm xua_as_fsm; + +struct osmo_fsm_inst *xua_as_fsm_start(struct osmo_ss7_as *as, int log_level); diff --git a/src/xua_asp_fsm.c b/src/xua_asp_fsm.c new file mode 100644 index 0000000..80faeb2 --- /dev/null +++ b/src/xua_asp_fsm.c @@ -0,0 +1,610 @@ +/* SCCP M3UA / SUA ASP osmo_fsm according to RFC3868 4.3.1 */ +/* (C) Copyright 2017 by Harald Welte + * + * All Rights reserved. + * + * Based on my earlier Erlang implementation xua_asp_fsm.erl in + * osmo-ss7.git + */ + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "xua_asp_fsm.h" +#include "xua_as_fsm.h" + +#define S(x) (1 << (x)) + +/* The general idea is: + * * translate incoming SUA/M3UA msg_class/msg_type to xua_asp_event + * * propagate state transitions to XUA_AS_FSM via _onenter functiosn + * * notify the Layer Management of any relevant changes + * * + */ + +/* According to RFC3868 Section 8 */ +#define XUA_T_A_SEC 2 +#define XUA_T_R_SEC 2 +#define XUA_T_ACK_SEC 2 +#define XUA_T_BEAT_SEC 30 +#define SUA_T_IAS_SEC (7*60) /* SUA only */ +#define SUA_T_IAR_SEC (15*60) /* SUA only */ + +static const struct value_string xua_asp_role_names[] = { + { XUA_ASPFSM_ROLE_ASP, "ASP" }, + { XUA_ASPFSM_ROLE_SG, "SG" }, + { XUA_ASPFSM_ROLE_IPSP, "IPSP" }, + { 0, NULL } +}; + +static const struct value_string xua_asp_event_names[] = { + { XUA_ASP_E_M_ASP_UP_REQ, "M-ASP_UP.req" }, + { XUA_ASP_E_M_ASP_ACTIVE_REQ, "M-ASP_ACTIVE.req" }, + { XUA_ASP_E_M_ASP_DOWN_REQ, "M-ASP_DOWN.req" }, + { XUA_ASP_E_M_ASP_INACTIVE_REQ, "M-ASP_INACTIVE.req" }, + + { XUA_ASP_E_SCTP_COMM_DOWN_IND, "SCTP-COMM_DOWN.ind" }, + { XUA_ASP_E_SCTP_RESTART_IND, "SCTP-RESTART.ind" }, + + { XUA_ASP_E_ASPSM_ASPUP, "ASPSM-ASP_UP" }, + { XUA_ASP_E_ASPSM_ASPUP_ACK, "ASPSM-ASP_UP_ACK" }, + { XUA_ASP_E_ASPTM_ASPAC, "ASPTM-ASP_AC" }, + { XUA_ASP_E_ASPTM_ASPAC_ACK, "ASPTM-ASP_AC_ACK" }, + { XUA_ASP_E_ASPSM_ASPDN, "ASPSM-ASP_DN" }, + { XUA_ASP_E_ASPSM_ASPDN_ACK, "ASPSM-ASP_DN_ACK" }, + { XUA_ASP_E_ASPTM_ASPIA, "ASPTM-ASP_IA" }, + { XUA_ASP_E_ASPTM_ASPIA_ACK, "ASPTM_ASP_IA_ACK" }, + { 0, NULL } +}; + +struct xua_layer_manager { + osmo_prim_cb prim_cb; +}; + +/* private data structure for each FSM instance */ +struct xua_asp_fsm_priv { + /* pointer back to ASP to which we belong */ + struct osmo_ss7_asp *asp; + /* Role (ASP/SG/IPSP) */ + enum xua_asp_role role; + /* Layer Manager to which we talk */ + struct xua_layer_manager *lm; + + /* routing context[s]: list of 32bit integers */ + /* ACTIVE: traffic mode type, tid label, drn label ? */ + + struct { + struct osmo_timer_list timer; + int out_event; + } t_ack; +}; + +static struct msgb *xlm_msgb_alloc(void) +{ + return msgb_alloc_headroom(2048+128, 128, "xua_asp-xlm msgb"); +} + +/* Send a XUA LM Primitive to the XUA Layer Manager (LM) */ +static int send_xlm_prim(struct osmo_fsm_inst *fi, + enum osmo_xlm_prim_type prim_type, + enum osmo_prim_operation op, + const uint8_t *data, unsigned int data_len) +{ + struct xua_asp_fsm_priv *xafp = fi->priv; + struct msgb *xlmsg; + struct osmo_xlm_prim *prim; + struct xua_layer_manager *lm = xafp->lm; + + if (!lm || !lm->prim_cb) + return 0; + + xlmsg = xlm_msgb_alloc(); + if (!xlmsg) + return -ENOMEM; + prim = (struct osmo_xlm_prim *) msgb_put(xlmsg, sizeof(*prim)); + osmo_prim_init(&prim->oph, XUA_SAP_LM, prim_type, op, xlmsg); + + lm->prim_cb(&prim->oph, xafp->asp); + + return 0; +} + +/* wrapper around send_xlm_prim for primitives without data */ +static int send_xlm_prim_simple(struct osmo_fsm_inst *fi, + enum osmo_xlm_prim_type prim, + enum osmo_prim_operation op) +{ + return send_xlm_prim(fi, prim, op, NULL, 0); +} + +/* ask the xUA implementation to transmit a specific message */ +static int peer_send(struct osmo_fsm_inst *fi, int out_event) +{ + struct xua_asp_fsm_priv *xafp = fi->priv; + struct osmo_ss7_asp *asp = xafp->asp; + struct xua_msg *xua = xua_msg_alloc(); + struct msgb *msg; + + switch (out_event) { + case XUA_ASP_E_ASPSM_ASPUP: + /* RFC 3868 Ch. 3.5.1 */ + xua->hdr = XUA_HDR(SUA_MSGC_ASPSM, SUA_ASPSM_UP); + /* Optional: ASP ID */ + if (asp->asp_id_present) + xua_msg_add_u32(xua, SUA_IEI_ASP_ID, asp->asp_id); + /* Optional: Info String */ + break; + case XUA_ASP_E_ASPSM_ASPUP_ACK: + /* RFC3868 Ch. 3.5.2 */ + xua->hdr = XUA_HDR(SUA_MSGC_ASPSM, SUA_ASPSM_UP_ACK); + /* Optional: Info String */ + break; + case XUA_ASP_E_ASPSM_ASPDN: + /* RFC3868 Ch. 3.5.3 */ + xua->hdr = XUA_HDR(SUA_MSGC_ASPSM, SUA_ASPSM_DOWN); + /* Optional: Info String */ + break; + case XUA_ASP_E_ASPSM_ASPDN_ACK: + /* RFC3868 Ch. 3.5.4 */ + xua->hdr = XUA_HDR(SUA_MSGC_ASPSM, SUA_ASPSM_DOWN_ACK); + /* Optional: Info String */ + break; + case XUA_ASP_E_ASPSM_BEAT: + /* RFC3868 Ch. 3.5.5 */ + xua->hdr = XUA_HDR(SUA_MSGC_ASPSM, SUA_ASPSM_BEAT); + /* Optional: Heartbeat Data */ + break; + case XUA_ASP_E_ASPSM_BEAT_ACK: + /* RFC3868 Ch. 3.5.6 */ + xua->hdr = XUA_HDR(SUA_MSGC_ASPSM, SUA_ASPSM_BEAT_ACK); + /* Optional: Heartbeat Data */ + break; + case XUA_ASP_E_ASPTM_ASPAC: + /* RFC3868 Ch. 3.6.1 */ + xua->hdr = XUA_HDR(SUA_MSGC_ASPTM, SUA_ASPTM_ACTIVE); + /* Optional: Traffic Mode Type */ + /* Optional: Routing Context */ + /* Optional: TID Label */ + /* Optional: DRN Label */ + /* Optional: Info String */ + break; + case XUA_ASP_E_ASPTM_ASPAC_ACK: + /* RFC3868 Ch. 3.6.2 */ + xua->hdr = XUA_HDR(SUA_MSGC_ASPTM, SUA_ASPTM_ACTIVE_ACK); + /* Optional: Traffic Mode Type */ + /* Mandatory: Routing Context */ + //FIXME xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, + /* Optional: Info String */ + break; + case XUA_ASP_E_ASPTM_ASPIA: + /* RFC3868 Ch. 3.6.3 */ + xua->hdr = XUA_HDR(SUA_MSGC_ASPTM, SUA_ASPTM_INACTIVE); + /* Optional: Routing Context */ + /* Optional: Info String */ + break; + case XUA_ASP_E_ASPTM_ASPIA_ACK: + /* RFC3868 Ch. 3.6.4 */ + xua->hdr = XUA_HDR(SUA_MSGC_ASPTM, SUA_ASPTM_INACTIVE_ACK); + /* Optional: Routing Context */ + /* Optional: Info String */ + break; + } + + msg = xua_to_msg(SUA_VERSION, xua); + xua_msg_free(xua); + if (!msg) + return -1; + + return osmo_ss7_asp_send(asp, msg); +} + +static void xua_t_ack_cb(void *data) +{ + struct osmo_fsm_inst *fi = data; + struct xua_asp_fsm_priv *xafp = fi->priv; + + LOGPFSML(fi, LOGL_INFO, "T(ack) callback: re-transmitting event %s\n", + osmo_fsm_event_name(fi->fsm, xafp->t_ack.out_event)); + + /* Re-transmit message */ + peer_send(fi, xafp->t_ack.out_event); + + /* Re-start the timer */ + osmo_timer_schedule(&xafp->t_ack.timer, XUA_T_ACK_SEC, 0); +} + +static int peer_send_and_start_t_ack(struct osmo_fsm_inst *fi, + int out_event) +{ + struct xua_asp_fsm_priv *xafp = fi->priv; + int rc; + + rc = peer_send(fi, out_event); + if (rc < 0) + return rc; + + xafp->t_ack.out_event = out_event; + xafp->t_ack.timer.cb = xua_t_ack_cb, + xafp->t_ack.timer.data = fi; + + osmo_timer_schedule(&xafp->t_ack.timer, XUA_T_ACK_SEC, 0); + + return rc; +} + +static const uint32_t evt_ack_map[_NUM_XUA_ASP_E] = { + [XUA_ASP_E_ASPSM_ASPUP] = XUA_ASP_E_ASPSM_ASPUP_ACK, + [XUA_ASP_E_ASPTM_ASPAC] = XUA_ASP_E_ASPTM_ASPAC_ACK, + [XUA_ASP_E_ASPSM_ASPDN] = XUA_ASP_E_ASPSM_ASPDN_ACK, + [XUA_ASP_E_ASPTM_ASPIA] = XUA_ASP_E_ASPTM_ASPIA_ACK, + [XUA_ASP_E_ASPSM_BEAT] = XUA_ASP_E_ASPSM_BEAT_ACK, +}; + + +/* check if expected message was received + stop t_ack */ +static void check_stop_t_ack(struct osmo_fsm_inst *fi, uint32_t event) +{ + struct xua_asp_fsm_priv *xafp = fi->priv; + int exp_ack; + + if (event >= ARRAY_SIZE(evt_ack_map)) + return; + + exp_ack = evt_ack_map[xafp->t_ack.out_event]; + if (exp_ack && event == exp_ack) { + LOGPFSML(fi, LOGL_DEBUG, "T(ack) stopped\n"); + osmo_timer_del(&xafp->t_ack.timer); + } +} + +#define ENSURE_ASP_OR_IPSP(fi, event) \ + do { \ + struct xua_asp_fsm_priv *_xafp = fi->priv; \ + if (_xafp->role != XUA_ASPFSM_ROLE_ASP && \ + _xafp->role != XUA_ASPFSM_ROLE_IPSP) { \ + LOGPFSML(fi, LOGL_ERROR, "event %s not permitted " \ + "in role %s\n", \ + osmo_fsm_event_name(fi->fsm, event), \ + get_value_string(xua_asp_role_names, _xafp->role));\ + return; \ + } \ + } while(0) + +#define ENSURE_SG_OR_IPSP(fi, event) \ + do { \ + struct xua_asp_fsm_priv *_xafp = fi->priv; \ + if (_xafp->role != XUA_ASPFSM_ROLE_SG && \ + _xafp->role != XUA_ASPFSM_ROLE_IPSP) { \ + LOGPFSML(fi, LOGL_ERROR, "event %s not permitted " \ + "in role %s\n", \ + osmo_fsm_event_name(fi->fsm, event), \ + get_value_string(xua_asp_role_names, _xafp->role));\ + return; \ + } \ + } while(0) + +static void xua_asp_fsm_down(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct xua_asp_fsm_priv *xafp = fi->priv; + struct osmo_ss7_asp *asp = xafp->asp; + struct xua_msg_part *asp_id_ie; + + check_stop_t_ack(fi, event); + + switch (event) { + case XUA_ASP_E_M_ASP_UP_REQ: + /* only if role ASP */ + ENSURE_ASP_OR_IPSP(fi, event); + /* Send M3UA_MSGT_ASPSM_ASPUP and start t_ack */ + peer_send_and_start_t_ack(fi, XUA_ASP_E_ASPSM_ASPUP); + break; + case XUA_ASP_E_ASPSM_ASPUP_ACK: + /* only if role ASP */ + ENSURE_ASP_OR_IPSP(fi, event); + osmo_fsm_inst_state_chg(fi, XUA_ASP_S_INACTIVE, 0, 0); + /* inform layer manager */ + send_xlm_prim_simple(fi, OSMO_XLM_PRIM_M_ASP_UP, + PRIM_OP_CONFIRM); + /* FIXME: This hack should be in layer manager? */ + osmo_fsm_inst_dispatch(fi, XUA_ASP_E_M_ASP_ACTIVE_REQ, NULL); + break; + case XUA_ASP_E_ASPSM_ASPUP: + /* only if role SG */ + ENSURE_SG_OR_IPSP(fi, event); + asp_id_ie = xua_msg_find_tag(data, SUA_IEI_ASP_ID); + /* Optional ASP Identifier: Store for NTFY */ + if (asp_id_ie) { + asp->asp_id = xua_msg_part_get_u32(asp_id_ie); + asp->asp_id_present = true; + } + /* send ACK */ + peer_send(fi, XUA_ASP_E_ASPSM_ASPUP_ACK); + /* transition state and inform layer manager */ + osmo_fsm_inst_state_chg(fi, XUA_ASP_S_INACTIVE, 0, 0); + send_xlm_prim_simple(fi, OSMO_XLM_PRIM_M_ASP_UP, + PRIM_OP_INDICATION); + break; + case XUA_ASP_E_ASPSM_ASPDN: + /* only if role SG */ + ENSURE_SG_OR_IPSP(fi, event); + /* The SGP MUST send an ASP Down Ack message in response + * to a received ASP Down message from the ASP even if + * the ASP is already marked as ASP-DOWN at the SGP. */ + peer_send(fi, XUA_ASP_E_ASPSM_ASPDN_ACK); + break; + } +} + +/* Helper function to dispatch an ASP->AS event to all AS of which this + * ASP is a memmber. Ignores routing contexts for now. */ +static void dispatch_to_all_as(struct osmo_fsm_inst *fi, uint32_t event) +{ + struct xua_asp_fsm_priv *xafp = fi->priv; + struct osmo_ss7_asp *asp = xafp->asp; + struct osmo_ss7_instance *inst = asp->inst; + struct osmo_ss7_as *as; + + if (xafp->role != XUA_ASPFSM_ROLE_SG) + return; + + llist_for_each_entry(as, &inst->as_list, list) { + if (!osmo_ss7_as_has_asp(as, asp)) + continue; + osmo_fsm_inst_dispatch(as->fi, event, asp); + } +} + +static void xua_asp_fsm_down_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state) +{ + dispatch_to_all_as(fi, XUA_ASPAS_ASP_DOWN_IND); +} + +static void xua_asp_fsm_inactive(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + check_stop_t_ack(fi, event); + switch (event) { + case XUA_ASP_E_M_ASP_ACTIVE_REQ: + /* send M3UA_MSGT_ASPTM_ASPAC and start t_ack */ + peer_send_and_start_t_ack(fi, XUA_ASP_E_ASPTM_ASPAC); + break; + case XUA_ASP_E_M_ASP_DOWN_REQ: + /* send M3UA_MSGT_ASPSM_ASPDN and start t_ack */ + peer_send_and_start_t_ack(fi, XUA_ASP_E_ASPSM_ASPDN); + break; + case XUA_ASP_E_ASPTM_ASPAC_ACK: + /* only in role ASP */ + ENSURE_ASP_OR_IPSP(fi, event); + /* transition state and inform layer manager */ + osmo_fsm_inst_state_chg(fi, XUA_ASP_S_ACTIVE, 0, 0); + send_xlm_prim_simple(fi, OSMO_XLM_PRIM_M_ASP_ACTIVE, + PRIM_OP_CONFIRM); + break; + case XUA_ASP_E_ASPSM_ASPDN_ACK: + /* only in role ASP */ + ENSURE_ASP_OR_IPSP(fi, event); + /* transition state and inform layer manager */ + osmo_fsm_inst_state_chg(fi, XUA_ASP_S_DOWN, 0, 0); + send_xlm_prim_simple(fi, OSMO_XLM_PRIM_M_ASP_DOWN, + PRIM_OP_CONFIRM); + break; + case XUA_ASP_E_ASPTM_ASPAC: + /* only in role SG */ + ENSURE_SG_OR_IPSP(fi, event); + /* send ACK */ + peer_send(fi, XUA_ASP_E_ASPTM_ASPAC_ACK); + /* transition state and inform layer manager */ + osmo_fsm_inst_state_chg(fi, XUA_ASP_S_ACTIVE, 0, 0); + send_xlm_prim_simple(fi, OSMO_XLM_PRIM_M_ASP_ACTIVE, + PRIM_OP_INDICATION); + break; + case XUA_ASP_E_ASPSM_ASPDN: + /* only in role SG */ + ENSURE_SG_OR_IPSP(fi, event); + /* send ACK */ + peer_send(fi, XUA_ASP_E_ASPSM_ASPDN_ACK); + /* transition state and inform layer manager */ + osmo_fsm_inst_state_chg(fi, XUA_ASP_S_DOWN, 0, 0); + send_xlm_prim_simple(fi, OSMO_XLM_PRIM_M_ASP_DOWN, + PRIM_OP_INDICATION); + break; + case XUA_ASP_E_ASPSM_ASPUP: + /* only if role SG */ + ENSURE_SG_OR_IPSP(fi, event); + /* If an ASP Up message is received and internally the + * remote ASP is already in the ASP-INACTIVE state, an + * ASP Up Ack message is returned and no further action + * is taken. */ + peer_send(fi, XUA_ASP_E_ASPSM_ASPUP_ACK); + break; + } +} + +static void xua_asp_fsm_inactive_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state) +{ + dispatch_to_all_as(fi, XUA_ASPAS_ASP_INACTIVE_IND); +} + +static void xua_asp_fsm_active(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + check_stop_t_ack(fi, event); + switch (event) { + case XUA_ASP_E_ASPSM_ASPDN_ACK: + /* only in role ASP */ + ENSURE_ASP_OR_IPSP(fi, event); + osmo_fsm_inst_state_chg(fi, XUA_ASP_S_DOWN, 0, 0); + /* inform layer manager */ + send_xlm_prim_simple(fi, OSMO_XLM_PRIM_M_ASP_DOWN, + PRIM_OP_CONFIRM); + break; + case XUA_ASP_E_ASPTM_ASPIA_ACK: + /* only in role ASP */ + ENSURE_ASP_OR_IPSP(fi, event); + osmo_fsm_inst_state_chg(fi, XUA_ASP_S_INACTIVE, 0, 0); + /* inform layer manager */ + send_xlm_prim_simple(fi, OSMO_XLM_PRIM_M_ASP_INACTIVE, + PRIM_OP_CONFIRM); + break; + case XUA_ASP_E_M_ASP_DOWN_REQ: + /* only in role ASP */ + ENSURE_ASP_OR_IPSP(fi, event); + /* send M3UA_MSGT_ASPSM_ASPDN and star t_ack */ + peer_send_and_start_t_ack(fi, XUA_ASP_E_ASPSM_ASPDN); + break; + case XUA_ASP_E_M_ASP_INACTIVE_REQ: + /* only in role ASP */ + ENSURE_ASP_OR_IPSP(fi, event); + /* send M3UA_MSGT_ASPTM_ASPIA and star t_ack */ + peer_send_and_start_t_ack(fi, XUA_ASP_E_ASPTM_ASPIA); + break; + case XUA_ASP_E_ASPTM_ASPIA: + /* only in role SG */ + ENSURE_SG_OR_IPSP(fi, event); + /* send ACK */ + peer_send(fi, XUA_ASP_E_ASPTM_ASPIA_ACK); + /* transition state and inform layer manager */ + osmo_fsm_inst_state_chg(fi, XUA_ASP_S_INACTIVE, 0, 0); + send_xlm_prim_simple(fi, OSMO_XLM_PRIM_M_ASP_INACTIVE, + PRIM_OP_INDICATION); + break; + case XUA_ASP_E_ASPSM_ASPDN: + /* only in role SG */ + ENSURE_SG_OR_IPSP(fi, event); + /* send ACK */ + peer_send(fi, XUA_ASP_E_ASPSM_ASPDN_ACK); + /* transition state and inform layer manager */ + osmo_fsm_inst_state_chg(fi, XUA_ASP_S_DOWN, 0, 0); + send_xlm_prim_simple(fi, OSMO_XLM_PRIM_M_ASP_DOWN, + PRIM_OP_INDICATION); + break; + case XUA_ASP_E_ASPSM_ASPUP: + /* only if role SG */ + ENSURE_SG_OR_IPSP(fi, event); + /* an ASP Up Ack message is returned, as well as + * an Error message ("Unexpected Message), and the + * remote ASP state is changed to ASP-INACTIVE in all + * relevant Application Servers */ + /* FIXME: Send ERROR message */ + osmo_fsm_inst_state_chg(fi, XUA_ASP_S_INACTIVE, 0, 0); + send_xlm_prim_simple(fi, OSMO_XLM_PRIM_M_ASP_INACTIVE, + PRIM_OP_INDICATION); + break; + } +} + +static void xua_asp_fsm_active_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state) +{ + dispatch_to_all_as(fi, XUA_ASPAS_ASP_ACTIVE_IND); +} + +static void xua_asp_allstate(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + switch (event) { + case XUA_ASP_E_SCTP_COMM_DOWN_IND: + case XUA_ASP_E_SCTP_RESTART_IND: + osmo_fsm_inst_state_chg(fi, XUA_ASP_S_DOWN, 0, 0); + send_xlm_prim_simple(fi, OSMO_XLM_PRIM_M_ASP_DOWN, + PRIM_OP_INDICATION); + break; + default: + break; + } +} + +static int xua_asp_fsm_timer_cb(struct osmo_fsm_inst *fi) +{ + /* We don't use the fsm timer, so any calls to this are an error */ + OSMO_ASSERT(0); + return 0; +} + +static const struct osmo_fsm_state xua_asp_states[] = { + [XUA_ASP_S_DOWN] = { + .in_event_mask = S(XUA_ASP_E_M_ASP_UP_REQ) | + S(XUA_ASP_E_ASPSM_ASPUP) | + S(XUA_ASP_E_ASPSM_ASPUP_ACK) | + S(XUA_ASP_E_ASPSM_ASPDN), + .out_state_mask = S(XUA_ASP_S_INACTIVE), + .name = "ASP_DOWN", + .action = xua_asp_fsm_down, + .onenter = xua_asp_fsm_down_onenter, + }, + [XUA_ASP_S_INACTIVE] = { + .in_event_mask = S(XUA_ASP_E_M_ASP_ACTIVE_REQ) | + S(XUA_ASP_E_M_ASP_DOWN_REQ) | + S(XUA_ASP_E_ASPTM_ASPAC) | + S(XUA_ASP_E_ASPTM_ASPAC_ACK) | + S(XUA_ASP_E_ASPSM_ASPDN) | + S(XUA_ASP_E_ASPSM_ASPDN_ACK) | + S(XUA_ASP_E_ASPSM_ASPUP), + .out_state_mask = S(XUA_ASP_S_DOWN) | + S(XUA_ASP_S_ACTIVE), + .name = "ASP_INACTIVE", + .action = xua_asp_fsm_inactive, + .onenter = xua_asp_fsm_inactive_onenter, + }, + [XUA_ASP_S_ACTIVE] = { + .in_event_mask = S(XUA_ASP_E_ASPSM_ASPDN) | + S(XUA_ASP_E_ASPSM_ASPDN_ACK) | + S(XUA_ASP_E_ASPSM_ASPUP) | + S(XUA_ASP_E_ASPTM_ASPIA) | + S(XUA_ASP_E_ASPTM_ASPIA_ACK) | + S(XUA_ASP_E_M_ASP_DOWN_REQ) | + S(XUA_ASP_E_M_ASP_INACTIVE_REQ), + .out_state_mask = S(XUA_ASP_S_INACTIVE) | + S(XUA_ASP_S_DOWN), + .name = "ASP_ACTIVE", + .action = xua_asp_fsm_active, + .onenter = xua_asp_fsm_active_onenter, + }, +}; + + +struct osmo_fsm xua_asp_fsm = { + .name = "XUA_ASP", + .states = xua_asp_states, + .num_states = ARRAY_SIZE(xua_asp_states), + .timer_cb = xua_asp_fsm_timer_cb, + .log_subsys = DLSS7, + .event_names = xua_asp_event_names, + .allstate_event_mask = S(XUA_ASP_E_SCTP_COMM_DOWN_IND) | + S(XUA_ASP_E_SCTP_RESTART_IND), + .allstate_action = xua_asp_allstate, +}; + + +/*! \brief Start a new ASP finite stae machine for given ASP + * \param[in] asp Application Server Process for which to start FSM + * \param[in] role Role (ASP, SG, IPSP) of this FSM + * \param[in] log_level Logging Level for ASP FSM logging + * \returns FSM instance on success; NULL on error */ +struct osmo_fsm_inst *xua_asp_fsm_start(struct osmo_ss7_asp *asp, + enum xua_asp_role role, int log_level) +{ + struct osmo_fsm_inst *fi; + struct xua_asp_fsm_priv *xafp; + + /* allocate as child of AS? */ + fi = osmo_fsm_inst_alloc(&xua_asp_fsm, asp, NULL, log_level, asp->cfg.name); + + xafp = talloc_zero(fi, struct xua_asp_fsm_priv); + if (!xafp) { + osmo_fsm_inst_term(fi, OSMO_FSM_TERM_ERROR, NULL); + return NULL; + } + xafp->role = role; + xafp->asp = asp; + + fi->priv = xafp; + + return fi; +} diff --git a/src/xua_asp_fsm.h b/src/xua_asp_fsm.h new file mode 100644 index 0000000..ea62484 --- /dev/null +++ b/src/xua_asp_fsm.h @@ -0,0 +1,42 @@ +#pragma once + +enum xua_asp_state { + XUA_ASP_S_DOWN, + XUA_ASP_S_INACTIVE, + XUA_ASP_S_ACTIVE, +}; + +enum xua_asp_event { + XUA_ASP_E_M_ASP_UP_REQ, + XUA_ASP_E_M_ASP_ACTIVE_REQ, + XUA_ASP_E_M_ASP_DOWN_REQ, + XUA_ASP_E_M_ASP_INACTIVE_REQ, + + XUA_ASP_E_SCTP_COMM_DOWN_IND, + XUA_ASP_E_SCTP_RESTART_IND, + + XUA_ASP_E_ASPSM_ASPUP, + XUA_ASP_E_ASPSM_ASPUP_ACK, + XUA_ASP_E_ASPTM_ASPAC, + XUA_ASP_E_ASPTM_ASPAC_ACK, + XUA_ASP_E_ASPSM_ASPDN, + XUA_ASP_E_ASPSM_ASPDN_ACK, + XUA_ASP_E_ASPTM_ASPIA, + XUA_ASP_E_ASPTM_ASPIA_ACK, + + XUA_ASP_E_ASPSM_BEAT, + XUA_ASP_E_ASPSM_BEAT_ACK, + + _NUM_XUA_ASP_E +}; + +enum xua_asp_role { + XUA_ASPFSM_ROLE_ASP, + XUA_ASPFSM_ROLE_SG, + XUA_ASPFSM_ROLE_IPSP, +}; + +extern struct osmo_fsm xua_asp_fsm; + +struct osmo_fsm_inst *xua_asp_fsm_start(struct osmo_ss7_asp *asp, + enum xua_asp_role role, int log_level); diff --git a/src/xua_internal.h b/src/xua_internal.h new file mode 100644 index 0000000..66b5a26 --- /dev/null +++ b/src/xua_internal.h @@ -0,0 +1,58 @@ +#pragma once + +#include +#include + +struct osmo_sccp_addr; +struct m3ua_data_hdr; + +int sua_addr_parse_part(struct osmo_sccp_addr *out, + const struct xua_msg_part *param); +int sua_addr_parse(struct osmo_sccp_addr *out, struct xua_msg *xua, uint16_t iei); + +int sua_parse_gt(struct osmo_sccp_gt *gt, const uint8_t *data, unsigned int datalen); + +struct xua_msg *osmo_sccp_to_xua(struct msgb *msg); +struct msgb *osmo_sua_to_sccp(struct xua_msg *xua); + +int sua_tx_xua_as(struct osmo_ss7_as *as, struct xua_msg *xua); + +struct osmo_mtp_prim *m3ua_to_xfer_ind(struct xua_msg *xua); +int m3ua_hmdc_rx_from_l2(struct osmo_ss7_instance *inst, struct xua_msg *xua); +int m3ua_tx_xua_as(struct osmo_ss7_as *as, struct xua_msg *xua); +int m3ua_rx_msg(struct osmo_ss7_asp *asp, struct msgb *msg); + +struct msgb *m3ua_msgb_alloc(const char *name); +struct m3ua_data_hdr *data_hdr_from_m3ua(struct xua_msg *xua); +void m3ua_dh_to_xfer_param(struct osmo_mtp_transfer_param *param, + const struct m3ua_data_hdr *mdh); +void mtp_xfer_param_to_m3ua_dh(struct m3ua_data_hdr *mdh, + const struct osmo_mtp_transfer_param *param); + + +extern const struct xua_msg_class m3ua_msg_class_mgmt; +extern const struct xua_msg_class m3ua_msg_class_snm; +extern const struct xua_msg_class m3ua_msg_class_rkm; +extern const struct xua_msg_class m3ua_msg_class_aspsm; +extern const struct xua_msg_class m3ua_msg_class_asptm; + +extern const struct value_string m3ua_err_names[]; +extern const struct value_string m3ua_ntfy_type_names[]; +extern const struct value_string m3ua_ntfy_stchg_names[]; +extern const struct value_string m3ua_ntfy_other_names[]; + +#define NOTIFY_PAR_P_ASP_ID (1 << 0) +#define NOTIFY_PAR_P_ROUTE_CTX (1 << 1) + +struct m3ua_notify_params { + uint32_t presence; + uint16_t status_type; + uint16_t status_info; + uint32_t asp_id; + uint32_t route_ctx; + char *info_string; +}; + +struct xua_msg *m3ua_encode_notify(const struct m3ua_notify_params *npar); +int m3ua_decode_notify(struct m3ua_notify_params *npar, void *ctx, + const struct xua_msg *xua); diff --git a/tests/Makefile.am b/tests/Makefile.am index 6e9b807..9c251fe 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,4 +1,4 @@ -SUBDIRS = sccp mtp m2ua sigtran +SUBDIRS = sccp mtp m2ua sigtran ss7 # The `:;' works around a Bash 3.2 bug when the output is not writeable. $(srcdir)/package.m4: $(top_srcdir)/configure.ac diff --git a/tests/ss7/Makefile.am b/tests/ss7/Makefile.am new file mode 100644 index 0000000..bc81915 --- /dev/null +++ b/tests/ss7/Makefile.am @@ -0,0 +1,12 @@ +AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -Wall +AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) + +AM_LDFLAGS = -static +LDADD = $(top_builddir)/src/libosmo-sigtran.la \ + $(LIBOSMOCORE_LIBS) $(LIBOSMONETIF_LIBS) $(LIBSCTP_LIBS) + +EXTRA_DIST = ss7_test.ok ss7_test.err + +noinst_PROGRAMS = ss7_test + +ss7_test_SOURCES = ss7_test.c diff --git a/tests/ss7/ss7_test.c b/tests/ss7/ss7_test.c new file mode 100644 index 0000000..24eabc9 --- /dev/null +++ b/tests/ss7/ss7_test.c @@ -0,0 +1,321 @@ +#include "../src/xua_internal.h" +#include "../src/xua_asp_fsm.h" + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +static struct osmo_ss7_instance *s7i; + +static void test_pc_transcode(uint32_t pc) +{ + const char *pc_str = osmo_ss7_pointcode_print(s7i, pc); + uint32_t pc_reenc = osmo_ss7_pointcode_parse(s7i, pc_str); + + printf("%s(%u) -> %s -> %u\n", __func__, pc, pc_str, pc_reenc); + OSMO_ASSERT(pc == pc_reenc); +} + +static void test_pc_defaults(void) +{ + /* ensure the default point code format settings apply */ + OSMO_ASSERT(s7i->cfg.pc_fmt.component_len[0] == 3); + OSMO_ASSERT(s7i->cfg.pc_fmt.component_len[1] == 8); + OSMO_ASSERT(s7i->cfg.pc_fmt.component_len[2] == 3); + OSMO_ASSERT(s7i->cfg.pc_fmt.delimiter = '.'); +} + +static void parse_print_mask(const char *in) +{ + uint32_t mask = osmo_ss7_pointcode_parse_mask_or_len(s7i, in); + const char *pc_str = osmo_ss7_pointcode_print(s7i, mask); + printf("mask %s => %u (0x%x) %s\n", in, mask, mask, pc_str); +} + +static void test_pc_parser_itu(void) +{ + /* ITU Style */ + printf("Testing ITU-style point code format\n"); + osmo_ss7_instance_set_pc_fmt(s7i, 3, 8, 3); + test_pc_transcode(0); + test_pc_transcode(1); + test_pc_transcode(1 << 3); + test_pc_transcode(1 << (3+8)); + test_pc_transcode(7 << (3+8)); + test_pc_transcode(100); + test_pc_transcode(2342); + test_pc_transcode((1 << 14)-1); + + parse_print_mask("/1"); + parse_print_mask("7.0.0"); + parse_print_mask("/14"); +} + +static void test_pc_parser_ansi(void) +{ + /* ANSI Style */ + printf("Testing ANSI-style point code format\n"); + osmo_ss7_instance_set_pc_fmt(s7i, 8, 8, 8); + s7i->cfg.pc_fmt.delimiter = '-'; + test_pc_transcode(0); + test_pc_transcode(1); + test_pc_transcode(1 << 8); + test_pc_transcode(1 << 16); + test_pc_transcode(1 << (3+8)); + test_pc_transcode((1 << 24)-1); + test_pc_transcode(100); + test_pc_transcode(2342); + + parse_print_mask("/1"); + parse_print_mask("/16"); + parse_print_mask("/24"); + + /* re-set to default (ITU) */ + osmo_ss7_instance_set_pc_fmt(s7i, 3, 8, 3); + s7i->cfg.pc_fmt.delimiter = '.'; +} + +static int test_user_prim_cb(struct osmo_prim_hdr *oph, void *priv) +{ + OSMO_ASSERT(priv == (void *) 0x1234); + + return 23; +} + +static void test_user(void) +{ + struct osmo_ss7_user user, user2; + struct osmo_mtp_prim omp = { + .oph = { + .sap = MTP_SAP_USER, + .primitive = OSMO_MTP_PRIM_TRANSFER, + .operation = PRIM_OP_INDICATION, + }, + .u.transfer = { + .sio = 1, + }, + }; + + printf("Testing SS7 user\n"); + + user.name = "testuser"; + user.priv = (void *) 0x1234; + user.prim_cb = test_user_prim_cb; + + /* registration */ + OSMO_ASSERT(osmo_ss7_user_register(s7i, 1, &user) == 0); + OSMO_ASSERT(osmo_ss7_user_register(s7i, 1, NULL) == -EBUSY); + OSMO_ASSERT(osmo_ss7_user_register(s7i, 255, NULL) == -EINVAL); + + /* primitive delivery */ + OSMO_ASSERT(osmo_ss7_mtp_to_user(s7i, &omp) == 23); + + /* cleanup */ + OSMO_ASSERT(osmo_ss7_user_unregister(s7i, 255, NULL) == -EINVAL); + OSMO_ASSERT(osmo_ss7_user_unregister(s7i, 10, NULL) == -ENODEV); + OSMO_ASSERT(osmo_ss7_user_unregister(s7i, 1, &user2) == -EINVAL); + OSMO_ASSERT(osmo_ss7_user_unregister(s7i, 1, &user) == 0); + + /* primitive delivery should fail now */ + OSMO_ASSERT(osmo_ss7_mtp_to_user(s7i, &omp) == -ENODEV); + + /* wrong primitive delivery should also fail */ + omp.oph.primitive = OSMO_MTP_PRIM_PAUSE; + OSMO_ASSERT(osmo_ss7_mtp_to_user(s7i, &omp) == -EINVAL); +} + +static void test_route(void) +{ + struct osmo_ss7_route_table *rtbl; + struct osmo_ss7_linkset *lset_a, *lset_b; + struct osmo_ss7_route *rt, *rt12, *rtdef; + + printf("Testing SS7 routing\n"); + + /* creation / destruction */ + OSMO_ASSERT(osmo_ss7_route_table_find(s7i, "foobar") == NULL); + rtbl = osmo_ss7_route_table_find_or_create(s7i, "foobar"); + OSMO_ASSERT(rtbl); + OSMO_ASSERT(osmo_ss7_route_table_find_or_create(s7i, "foobar") == rtbl); + osmo_ss7_route_table_destroy(rtbl); + OSMO_ASSERT(osmo_ss7_route_table_find(s7i, "foobar") == NULL); + + /* we now work with system route table */ + rtbl = osmo_ss7_route_table_find(s7i, "system"); + OSMO_ASSERT(rtbl && rtbl == s7i->rtable_system); + + lset_a = osmo_ss7_linkset_find_or_create(s7i, "a", 100); + OSMO_ASSERT(lset_a); + lset_b = osmo_ss7_linkset_find_or_create(s7i, "b", 200); + OSMO_ASSERT(lset_b); + + /* route with full mask */ + OSMO_ASSERT(osmo_ss7_route_find_dpc(rtbl, 12) == NULL); + rt = osmo_ss7_route_create(rtbl, 12, 0xffff, "a"); + OSMO_ASSERT(rt); + OSMO_ASSERT(osmo_ss7_route_find_dpc(rtbl, 12) == rt); + osmo_ss7_route_destroy(rt); + + /* route with partial mask */ + rt = osmo_ss7_route_create(rtbl, 8, 0xfff8, "a"); + OSMO_ASSERT(osmo_ss7_route_find_dpc(rtbl, 8) == rt); + OSMO_ASSERT(osmo_ss7_route_find_dpc(rtbl, 9) == rt); + OSMO_ASSERT(osmo_ss7_route_find_dpc(rtbl, 12) == rt); + OSMO_ASSERT(osmo_ss7_route_find_dpc(rtbl, 15) == rt); + OSMO_ASSERT(osmo_ss7_route_find_dpc(rtbl, 16) == NULL); + /* insert more specific route for 12, must have higher priority + * than existing one */ + rt12 = osmo_ss7_route_create(rtbl, 12, 0xffff, "b"); + OSMO_ASSERT(osmo_ss7_route_find_dpc(rtbl, 12) == rt12); + OSMO_ASSERT(osmo_ss7_route_find_dpc(rtbl, 15) == rt); + OSMO_ASSERT(osmo_ss7_route_find_dpc(rtbl, 16) == NULL); + /* add a default route, which should have lowest precedence */ + rtdef = osmo_ss7_route_create(rtbl, 0, 0, "a"); + OSMO_ASSERT(osmo_ss7_route_find_dpc(rtbl, 12) == rt12); + OSMO_ASSERT(osmo_ss7_route_find_dpc(rtbl, 15) == rt); + OSMO_ASSERT(osmo_ss7_route_find_dpc(rtbl, 16) == rtdef); + + osmo_ss7_route_destroy(rtdef); + osmo_ss7_route_destroy(rt12); + osmo_ss7_route_destroy(rt); + + osmo_ss7_linkset_destroy(lset_a); + osmo_ss7_linkset_destroy(lset_b); +} + +static void test_linkset(void) +{ + struct osmo_ss7_linkset *lset_a, *lset_b; + struct osmo_ss7_link *l_a1, *l_a2; + + printf("Testing SS7 linkset/link\n"); + + OSMO_ASSERT(osmo_ss7_linkset_find_by_name(s7i, "a") == NULL); + OSMO_ASSERT(osmo_ss7_linkset_find_by_name(s7i, "b") == NULL); + + lset_a = osmo_ss7_linkset_find_or_create(s7i, "a", 100); + OSMO_ASSERT(lset_a); + OSMO_ASSERT(osmo_ss7_linkset_find_by_name(s7i, "a") == lset_a); + + lset_b = osmo_ss7_linkset_find_or_create(s7i, "b", 200); + OSMO_ASSERT(lset_b); + OSMO_ASSERT(osmo_ss7_linkset_find_by_name(s7i, "b") == lset_b); + + l_a1 = osmo_ss7_link_find_or_create(lset_a, 1); + OSMO_ASSERT(l_a1); + l_a2 = osmo_ss7_link_find_or_create(lset_a, 2); + OSMO_ASSERT(l_a2); + + /* ID too high */ + OSMO_ASSERT(osmo_ss7_link_find_or_create(lset_a, 1000) == NULL); + /* already exists */ + OSMO_ASSERT(osmo_ss7_link_find_or_create(lset_a, 1) == l_a1); + + osmo_ss7_link_destroy(l_a1); + osmo_ss7_link_destroy(l_a2); + + osmo_ss7_linkset_destroy(lset_a); + osmo_ss7_linkset_destroy(lset_b); +} + +static void test_as(void) +{ + struct osmo_ss7_as *as; + struct osmo_ss7_asp *asp; + + OSMO_ASSERT(osmo_ss7_as_find_by_name(s7i, "as1") == NULL); + as = osmo_ss7_as_find_or_create(s7i, "as1", OSMO_SS7_ASP_PROT_M3UA); + OSMO_ASSERT(osmo_ss7_as_find_by_name(s7i, "as1") == as); + OSMO_ASSERT(osmo_ss7_as_find_by_rctx(s7i, 2342) == NULL); + as->cfg.routing_key.context = 2342; + OSMO_ASSERT(osmo_ss7_as_find_by_rctx(s7i, 2342) == as); + OSMO_ASSERT(osmo_ss7_as_add_asp(as, "asp1") == -ENODEV); + + asp = osmo_ss7_asp_find_or_create(s7i, "asp1", 0, M3UA_PORT, OSMO_SS7_ASP_PROT_M3UA); + OSMO_ASSERT(asp); + + OSMO_ASSERT(osmo_ss7_as_has_asp(as, asp) == false); + OSMO_ASSERT(osmo_ss7_as_add_asp(as, "asp1") == 0); + + osmo_ss7_asp_restart(asp); + + /* ask FSM to send ASP-UP.req */ + osmo_fsm_inst_dispatch(asp->fi, XUA_ASP_E_M_ASP_UP_REQ, NULL); + osmo_fsm_inst_dispatch(asp->fi, XUA_ASP_E_ASPSM_ASPUP_ACK, NULL); + osmo_fsm_inst_dispatch(asp->fi, XUA_ASP_E_ASPTM_ASPAC_ACK, NULL); + + OSMO_ASSERT(osmo_ss7_as_del_asp(as, "asp1") == 0); + OSMO_ASSERT(osmo_ss7_as_del_asp(as, "asp2") == -ENODEV); + OSMO_ASSERT(osmo_ss7_as_del_asp(as, "asp1") == -EINVAL); + + osmo_ss7_asp_destroy(asp); + osmo_ss7_as_destroy(as); + OSMO_ASSERT(osmo_ss7_as_find_by_name(s7i, "as1") == NULL); +} + +/*********************************************************************** + * Initialization + ***********************************************************************/ + +static const struct log_info_cat log_info_cat[] = { +}; + +static const struct log_info log_info = { + .cat = log_info_cat, + .num_cat = ARRAY_SIZE(log_info_cat), +}; + +static void init_logging(void) +{ + const int log_cats[] = { DLSS7, DLSUA, DLM3UA, DLSCCP, DLINP }; + unsigned int i; + + osmo_init_logging(&log_info); + + log_set_print_filename(osmo_stderr_target, 0); + + for (i = 0; i < ARRAY_SIZE(log_cats); i++) + log_set_category_filter(osmo_stderr_target, log_cats[i], 1, LOGL_DEBUG); +} + +int main(int argc, char **argv) +{ + init_logging(); + osmo_fsm_log_addr(false); + + /* init */ + osmo_ss7_init(); + s7i = osmo_ss7_instance_find_or_create(NULL, 0); + OSMO_ASSERT(osmo_ss7_instance_find(0) == s7i); + OSMO_ASSERT(osmo_ss7_instance_find(23) == NULL); + + /* test osmo_ss7_pc_is_local() */ + s7i->cfg.primary_pc = 55; + OSMO_ASSERT(osmo_ss7_pc_is_local(s7i, 55) == true); + OSMO_ASSERT(osmo_ss7_pc_is_local(s7i, 23) == false); + + /* further tests */ + test_pc_defaults(); + test_pc_parser_itu(); + test_pc_parser_ansi(); + test_user(); + test_route(); + test_linkset(); + test_as(); + + /* destroy */ + osmo_ss7_instance_destroy(s7i); + OSMO_ASSERT(osmo_ss7_instance_find(0) == NULL); + + exit(0); +} diff --git a/tests/ss7/ss7_test.err b/tests/ss7/ss7_test.err new file mode 100644 index 0000000..8823d1c --- /dev/null +++ b/tests/ss7/ss7_test.err @@ -0,0 +1,49 @@ +0: Creating SS7 Instance +0: Creating Route Table system +0: Point Code Format 8-8-8 is longer than 14 bits, odd? +registering user=testuser for SI 1 with priv 0x1234 +delivering MTP-TRANSFER.ind to user testuser, priv=0x1234 +No MTP-User for SI 1 +Unsupported Primitive +0: Creating Route Table foobar +0: Creating Linkset a +0: Creating Linkset b +0: Destroying Linkset a +0: Destroying Linkset b +0: Creating Linkset a +0: Creating Linkset b +0: Creating Link a:1 +0: Creating Link a:2 +0: Destroying Link a:1 +0: Destroying Link a:2 +0: Destroying Linkset a +0: Destroying Linkset b +0: Creating AS as1 +XUA_AS(as1){AS_DOWN}: Allocated +0: Adding ASP asp1 to AS as1 +0: Restarting ASP asp1 +unable to connect/bind socket: (null):0: Connection refused +connection closed +retrying in 5 seconds... +0: Unable to open stream client for ASP asp1 +XUA_ASP(asp1){ASP_DOWN}: Allocated +XUA_ASP(asp1){ASP_DOWN}: Received Event M-ASP_UP.req +XUA_ASP(asp1){ASP_DOWN}: Received Event ASPSM-ASP_UP_ACK +XUA_ASP(asp1){ASP_DOWN}: T(ack) stopped +XUA_ASP(asp1){ASP_DOWN}: state_chg to ASP_INACTIVE +XUA_ASP(asp1){ASP_INACTIVE}: Received Event M-ASP_ACTIVE.req +XUA_ASP(asp1){ASP_INACTIVE}: Received Event ASPTM-ASP_AC_ACK +XUA_ASP(asp1){ASP_INACTIVE}: T(ack) stopped +XUA_ASP(asp1){ASP_INACTIVE}: state_chg to ASP_ACTIVE +0: Removing ASP asp1 from AS as1 +0: Removing ASP asp1 from AS as1 +0: Destroying ASP asp1 +XUA_ASP(asp1){ASP_ACTIVE}: Terminating (cause = OSMO_FSM_TERM_REQUEST) +XUA_ASP(asp1){ASP_ACTIVE}: Freeing instance +XUA_ASP(asp1){ASP_ACTIVE}: Deallocated +0: Destroying AS as1 +XUA_AS(as1){AS_DOWN}: Terminating (cause = OSMO_FSM_TERM_REQUEST) +XUA_AS(as1){AS_DOWN}: Freeing instance +XUA_AS(as1){AS_DOWN}: Deallocated +0: Destroying SS7 Instance + \ No newline at end of file diff --git a/tests/ss7/ss7_test.ok b/tests/ss7/ss7_test.ok new file mode 100644 index 0000000..8aea63d --- /dev/null +++ b/tests/ss7/ss7_test.ok @@ -0,0 +1,27 @@ +Testing ITU-style point code format +test_pc_transcode(0) -> 0.0.0 -> 0 +test_pc_transcode(1) -> 0.0.1 -> 1 +test_pc_transcode(8) -> 0.1.0 -> 8 +test_pc_transcode(2048) -> 1.0.0 -> 2048 +test_pc_transcode(14336) -> 7.0.0 -> 14336 +test_pc_transcode(100) -> 0.12.4 -> 100 +test_pc_transcode(2342) -> 1.36.6 -> 2342 +test_pc_transcode(16383) -> 7.255.7 -> 16383 +mask /1 => 8192 (0x2000) 4.0.0 +mask 7.0.0 => 14336 (0x3800) 7.0.0 +mask /14 => 16383 (0x3fff) 7.255.7 +Testing ANSI-style point code format +test_pc_transcode(0) -> 0-0-0 -> 0 +test_pc_transcode(1) -> 0-0-1 -> 1 +test_pc_transcode(256) -> 0-1-0 -> 256 +test_pc_transcode(65536) -> 1-0-0 -> 65536 +test_pc_transcode(2048) -> 0-8-0 -> 2048 +test_pc_transcode(16777215) -> 255-255-255 -> 16777215 +test_pc_transcode(100) -> 0-0-100 -> 100 +test_pc_transcode(2342) -> 0-9-38 -> 2342 +mask /1 => 8388608 (0x800000) 128-0-0 +mask /16 => 16776960 (0xffff00) 255-255-0 +mask /24 => 16777215 (0xffffff) 255-255-255 +Testing SS7 user +Testing SS7 routing +Testing SS7 linkset/link diff --git a/tests/testsuite.at b/tests/testsuite.at index 8907ffa..171f488 100644 --- a/tests/testsuite.at +++ b/tests/testsuite.at @@ -18,3 +18,9 @@ cat $abs_srcdir/sccp/sccp_test.ok > expout AT_CHECK([$abs_top_builddir/tests/sccp/sccp_test], [], [expout], [ignore]) AT_CLEANUP + +AT_SETUP([ss7]) +AT_KEYWORDS([ss7]) +cat $abs_srcdir/ss7/ss7_test.ok > expout +AT_CHECK([$abs_top_builddir/tests/ss7/ss7_test], [], [expout], [ignore]) +AT_CLEANUP -- To view, visit https://gerrit.osmocom.org/2209 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I375eb80f01acc013094851d91d1d3333ebc12bc7 Gerrit-PatchSet: 2 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Apr 4 11:43:10 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 4 Apr 2017 11:43:10 +0000 Subject: [PATCH] libosmo-sccp[master]: Add tests for xUA code + SCCP/SUA transcoding In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2214 to look at the new patch set (#2). Add tests for xUA code + SCCP/SUA transcoding Change-Id: I7ce038d72dca18fb83d5a12519c9a48267e52ab8 --- M configure.ac M tests/Makefile.am M tests/testsuite.at A tests/xua/Makefile.am A tests/xua/sccp_test_data.c A tests/xua/sccp_test_data.h A tests/xua/xua_test.c A tests/xua/xua_test.ok 8 files changed, 654 insertions(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/14/2214/2 diff --git a/configure.ac b/configure.ac index 116e168..ed3e25a 100644 --- a/configure.ac +++ b/configure.ac @@ -67,6 +67,7 @@ tests/mtp/Makefile tests/m2ua/Makefile tests/sigtran/Makefile + tests/xua/Makefile tests/ss7/Makefile Makefile) diff --git a/tests/Makefile.am b/tests/Makefile.am index 9c251fe..6d3c96f 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,4 +1,4 @@ -SUBDIRS = sccp mtp m2ua sigtran ss7 +SUBDIRS = xua sccp mtp m2ua sigtran ss7 # The `:;' works around a Bash 3.2 bug when the output is not writeable. $(srcdir)/package.m4: $(top_srcdir)/configure.ac diff --git a/tests/testsuite.at b/tests/testsuite.at index 171f488..b810bdf 100644 --- a/tests/testsuite.at +++ b/tests/testsuite.at @@ -19,6 +19,12 @@ AT_CHECK([$abs_top_builddir/tests/sccp/sccp_test], [], [expout], [ignore]) AT_CLEANUP +AT_SETUP([xua]) +AT_KEYWORDS([xua]) +cat $abs_srcdir/xua/xua_test.ok > expout +AT_CHECK([$abs_top_builddir/tests/xua/xua_test], [], [expout], [ignore]) +AT_CLEANUP + AT_SETUP([ss7]) AT_KEYWORDS([ss7]) cat $abs_srcdir/ss7/ss7_test.ok > expout diff --git a/tests/xua/Makefile.am b/tests/xua/Makefile.am new file mode 100644 index 0000000..8a75e6c --- /dev/null +++ b/tests/xua/Makefile.am @@ -0,0 +1,13 @@ +AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -Wall +AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) + +AM_LDFLAGS = -static +LDADD = $(top_builddir)/src/libosmo-sigtran.la \ + $(LIBOSMOCORE_LIBS) $(LIBOSMONETIF_LIBS) $(LIBSCTP_LIBS) + +EXTRA_DIST = xua_test.ok + +noinst_HEADERS = sccp_test_data.h +noinst_PROGRAMS = xua_test + +xua_test_SOURCES = xua_test.c sccp_test_data.c diff --git a/tests/xua/sccp_test_data.c b/tests/xua/sccp_test_data.c new file mode 100644 index 0000000..c7c8f27 --- /dev/null +++ b/tests/xua/sccp_test_data.c @@ -0,0 +1,102 @@ +#include + +/* BSC -> MSC */ +const uint8_t bssmap_reset[18] = { + 0x09, 0x00, 0x03, 0x05, 0x07, 0x02, 0x42, 0xfe, + 0x02, 0x42, 0xfe, 0x06, 0x00, 0x04, 0x30, 0x04, + 0x01, 0x20, +}; + +/* MSC -> BSC reset ack */ +const uint8_t bssmap_reset_ack[19] = { + 0x09, 0x00, 0x03, 0x07, 0x0b, 0x04, 0x43, 0x01, + 0x00, 0xfe, 0x04, 0x43, 0x5c, 0x00, 0xfe, 0x03, + 0x00, 0x01, 0x31, +}; + +/* MSC -> BSC paging, connection less */ +const uint8_t bssmap_paging[32] = { + 0x09, 0x00, 0x03, 0x07, 0x0b, 0x04, 0x43, 0x01, + 0x00, 0xfe, 0x04, 0x43, 0x5c, 0x00, 0xfe, 0x10, + 0x00, 0x0e, 0x52, 0x08, 0x08, 0x29, 0x47, 0x10, + 0x02, 0x01, 0x31, 0x97, 0x61, 0x1a, 0x01, 0x06, +}; + +/* MSC -> BSC paging, UDT without PC */ +const uint8_t bssmap_udt[28] = { + 0x09, 0x00, 0x03, 0x05, 0x07, 0x02, 0x42, 0xfe, + 0x02, 0x42, 0xfe, 0x10, 0x00, 0x0e, 0x52, 0x08, + 0x08, 0x29, 0x47, 0x10, 0x02, 0x01, 0x31, 0x97, + 0x61, 0x1a, 0x01, 0x06, +}; + +/* BSC -> MSC connection open */ +const uint8_t bssmap_cr[44] = { + 0x01, 0x01, 0x02, 0x03, 0x02, 0x02, 0x04, 0x02, + 0x42, 0xfe, 0x0f, 0x1f, 0x00, 0x1d, 0x57, 0x05, + 0x08, 0x00, 0x72, 0xf4, 0x80, 0x20, 0x12, 0xc3, + 0x50, 0x17, 0x10, 0x05, 0x24, 0x11, 0x03, 0x33, + 0x19, 0xa2, 0x08, 0x29, 0x47, 0x10, 0x02, 0x01, + 0x31, 0x97, 0x61, 0x00 +}; + +/* MSC -> BSC connection confirm */ +const uint8_t bssmap_cc[10] = { + 0x02, 0x01, 0x02, 0x03, 0x00, 0x00, 0x03, 0x02, 0x01, 0x00, +}; + +/* MSC -> BSC DTAP + * + * we fake a bit and make it BSC -> MSC... so the + * payload does not make any sense.. + */ +const uint8_t bssmap_dtap[22] = { + 0x06, 0x00, 0x00, 0x03, 0x00, 0x01, 0x0f, 0x01, 0x00, 0x0c, + 0x03, 0x05, 0x5c, 0x08, 0x11, 0x81, 0x33, 0x66, 0x02, 0x13, + 0x45, 0xf4, +}; + +/* MSC -> BSC clear command */ +const uint8_t bssmap_clear[13] = { + 0x06, 0x00, 0x00, 0x03, 0x00, 0x01, 0x06, 0x00, 0x04, 0x20, + 0x04, 0x01, 0x09, +}; + +/* MSC -> BSC released */ +const uint8_t bssmap_released[14] = { + 0x04, 0x00, 0x00, 0x03, 0x01, 0x02, 0x03, 0x00, 0x01, 0x0f, + 0x02, 0x23, 0x42, 0x00, +}; + +/* BSC -> MSC released */ +const uint8_t bssmap_release_complete[7] = { + 0x05, 0x01, 0x02, 0x03, 0x00, 0x00, 0x03 +}; + +/* message with a SCCP global title */ +const uint8_t tcap_global_title[183] = { + 0x09, + 0x81, 0x03, 0x0d, 0x18, 0x0a, 0x12, 0x07, 0x00, + 0x12, 0x04, 0x53, 0x84, 0x09, 0x00, 0x17, 0x0b, + 0x12, 0x06, 0x00, 0x12, 0x04, 0x44, 0x87, 0x20, + 0x00, 0x20, 0x65, 0x9a, 0x65, 0x81, 0x97, 0x48, + 0x04, 0x26, 0x00, 0x01, 0x98, 0x49, 0x04, 0x51, + 0x01, 0x03, 0xdf, 0x6c, 0x81, 0x88, 0xa1, 0x81, + 0x85, 0x02, 0x01, 0x44, 0x02, 0x01, 0x07, 0x30, + 0x80, 0xa7, 0x80, 0xa0, 0x80, 0x04, 0x01, 0x2b, + 0x30, 0x80, 0x30, 0x12, 0x83, 0x01, 0x10, 0x84, + 0x01, 0x07, 0x85, 0x07, 0x91, 0x44, 0x57, 0x76, + 0x67, 0x16, 0x97, 0x86, 0x01, 0x20, 0x30, 0x06, + 0x82, 0x01, 0x18, 0x84, 0x01, 0x04, 0x00, 0x00, + 0x00, 0x00, 0xa3, 0x06, 0x04, 0x01, 0x42, 0x84, + 0x01, 0x05, 0xa3, 0x06, 0x04, 0x01, 0x51, 0x84, + 0x01, 0x05, 0xa3, 0x06, 0x04, 0x01, 0x31, 0x84, + 0x01, 0x05, 0xa3, 0x09, 0x04, 0x01, 0x12, 0x84, + 0x01, 0x05, 0x82, 0x01, 0x02, 0xa3, 0x09, 0x04, + 0x01, 0x11, 0x84, 0x01, 0x05, 0x81, 0x01, 0x01, + 0xa3, 0x06, 0x04, 0x01, 0x14, 0x84, 0x01, 0x00, + 0xa3, 0x0b, 0x04, 0x01, 0x41, 0x84, 0x01, 0x04, + 0x30, 0x03, 0x83, 0x01, 0x10, 0xa3, 0x0b, 0x04, + 0x01, 0x41, 0x84, 0x01, 0x04, 0x30, 0x03, 0x82, + 0x01, 0x18, 0x00, 0x00, 0x00, 0x00 +}; diff --git a/tests/xua/sccp_test_data.h b/tests/xua/sccp_test_data.h new file mode 100644 index 0000000..3d70549 --- /dev/null +++ b/tests/xua/sccp_test_data.h @@ -0,0 +1,14 @@ +#pragma once +#include + +extern const uint8_t bssmap_reset[18]; +extern const uint8_t bssmap_reset_ack[19]; +extern const uint8_t bssmap_paging[32]; +extern const uint8_t bssmap_udt[28]; +extern const uint8_t bssmap_cr[44]; +extern const uint8_t bssmap_cc[10]; +extern const uint8_t bssmap_dtap[22]; +extern const uint8_t bssmap_clear[13]; +extern const uint8_t bssmap_released[14]; +extern const uint8_t bssmap_release_complete[7]; +extern const uint8_t tcap_global_title[183]; diff --git a/tests/xua/xua_test.c b/tests/xua/xua_test.c new file mode 100644 index 0000000..74d91c4 --- /dev/null +++ b/tests/xua/xua_test.c @@ -0,0 +1,386 @@ +/* (C) 2011 by Holger Hans Peter Freyther + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +#include "sccp_test_data.h" + +#include "../src/xua_internal.h" + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +static void test_isup_parse(void) +{ + const uint8_t party0[] = { 0x10, 0x32, 0x54, 0x76 }; + char digits[23] = ""; + int rc; + + rc = osmo_isup_party_parse(digits, party0, ARRAY_SIZE(party0), false); + printf("digits='%s' (%d)\n", digits, rc); + OSMO_ASSERT(rc == 8); + OSMO_ASSERT(!strcmp(digits, "01234567")); + + rc = osmo_isup_party_parse(digits, party0, ARRAY_SIZE(party0), true); + printf("digits='%s' (%d)\n", digits, rc); + OSMO_ASSERT(rc == 7); + OSMO_ASSERT(!strcmp(digits, "0123456")); +} + +/* SCCP Address Parsing */ + +static struct sccp_addr_testcase { + struct osmo_sccp_addr expected; + uint8_t *bin; + unsigned int bin_len; +}; + +static uint8_t addr_bin0[] = { 0x92, 0x06, 0x00, 0x12, 0x04, 0x19, 0x99, 0x96, 0x76, 0x39, 0x98 }; +static uint8_t addr_bin1[] = { 0x12, 0x08, 0x00, 0x12, 0x04, 0x19, 0x89, 0x96, 0x92, 0x99, 0x29 }; +static uint8_t addr_bin2[] = { 0x42, 0xfe }; + +static const struct sccp_addr_testcase sccp_addr_testcases[] = { + { + .expected = { + .presence = OSMO_SCCP_ADDR_T_GT | OSMO_SCCP_ADDR_T_SSN, + .ri = OSMO_SCCP_RI_GT, + .gt = { + .gti = OSMO_SCCP_GTI_TT_NPL_ENC_NAI, + .tt = 0, + .npi = OSMO_SCCP_NPI_E164_ISDN, + .nai = OSMO_SCCP_NAI_INTL, + .digits = "919969679389", + }, + .ssn = 6, + }, + .bin = addr_bin0, + .bin_len = ARRAY_SIZE(addr_bin0), + }, { + .expected = { + .presence = OSMO_SCCP_ADDR_T_GT | OSMO_SCCP_ADDR_T_SSN, + .ri = OSMO_SCCP_RI_GT, + .gt = { + .gti = OSMO_SCCP_GTI_TT_NPL_ENC_NAI, + .tt = 0, + .npi = OSMO_SCCP_NPI_E164_ISDN, + .nai = OSMO_SCCP_NAI_INTL, + .digits = "919869299992", + }, + .ssn = 8, + }, + .bin = addr_bin1, + .bin_len = ARRAY_SIZE(addr_bin1), + }, { + .expected = { + .presence = OSMO_SCCP_ADDR_T_SSN, + .ri = OSMO_SCCP_RI_SSN_PC, + .ssn = 254, + }, + .bin = addr_bin2, + .bin_len = ARRAY_SIZE(addr_bin2), + + }, +}; + +static int test_sccp_addr_parse(const struct osmo_sccp_addr *cmp, + const uint8_t *in, unsigned int in_len) +{ + struct osmo_sccp_addr osa; + int rc; + + memset(&osa, 0, sizeof(osa)); + rc = osmo_sccp_addr_parse(&osa, in, in_len); + if (rc < 0) + return rc; + + printf("expected: %s\n", osmo_sccp_addr_dump(cmp)); + printf("parsed: %s\n", osmo_sccp_addr_dump(&osa)); + + if (memcmp(&osa, cmp, sizeof(osa))) { + fprintf(stderr, "expected: %s\n", osmo_hexdump_nospc((uint8_t *)cmp, sizeof(*cmp))); + fprintf(stderr, "parsed: %s\n", osmo_hexdump_nospc((uint8_t *)&osa, sizeof(osa))); + } + + return 0; +} + +static void test_sccp_addr_parser(void) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(sccp_addr_testcases); i++) { + const struct sccp_addr_testcase *tcase = &sccp_addr_testcases[i]; + printf("sccp_addr_parse test case %u\n", i); + test_sccp_addr_parse(&tcase->expected, tcase->bin, tcase->bin_len); + } +} + +/* sccp_addr_testcases[0].expected.gt transcoded into a SUA Global Title IE */ +static const uint8_t expected_sua_gt[] = { + 0x80, 0x01, 0x00, 0x14, 0x00, 0x00, 0x00, 0x04, + 0x0c, 0x00, 0x01, 0x04, 0x19, 0x99, 0x96, 0x76, + 0x39, 0x98, 0x00, 0x00 +}; + +static void test_helpers(void) +{ + struct msgb *msg = msgb_alloc(1024, "foo"); + const struct osmo_sccp_gt *gt_in = &sccp_addr_testcases[0].expected.gt; + struct osmo_sccp_gt gt_out; + + printf("Testing Decoded GT -> SUA encoding\n"); + printf("IN: %s\n", osmo_sccp_gt_dump(gt_in)); + + /* encode sccp_addr to SUA GT */ + xua_part_add_gt(msg, gt_in); + OSMO_ASSERT(msgb_length(msg) == sizeof(expected_sua_gt)); + OSMO_ASSERT(!memcmp(msg->data, expected_sua_gt, sizeof(expected_sua_gt))); + + /* pull the tag+length value */ + msgb_pull(msg, 4); + + /* parse + compare */ + sua_parse_gt(>_out, msgb_data(msg), msgb_length(msg)); + printf("OUT:%s\n", osmo_sccp_gt_dump(>_out)); + OSMO_ASSERT(!memcmp(gt_in, >_out, sizeof(gt_out))); + + msgb_free(msg); +} + +/* SCCP Message Transcoding */ + +struct sccp2sua_testcase { + const char *name; + struct { + const uint8_t *bin; + unsigned int length; + } sccp; + struct { + struct xua_common_hdr hdr; + const struct xua_msg_part parts[32]; + } sua; +}; + +#define PANDSIZ(x) { x, ARRAY_SIZE(x) } +#define PARTU32(x, data) { .tag = x, .len = 4, .dat = (uint8_t *) data } +#define PARTARR(x, data) { .tag = x, .len = ARRAY_SIZE(data), .dat = (uint8_t *) data } + +const uint32_t sua_proto_class0 = 0; +const uint32_t sua_proto_class2 = 2; +const uint32_t sua_loc_ref_bsc = 0x10203; +const uint32_t sua_loc_ref_msc = 0x00003; +const uint32_t sua_cause0 = 0x00003; +const uint8_t sua_addr_ssn_bssmap[] = { 0x00, 0x02, 0x00, 0x07, 0x80, 0x03, 0x00, 0x08, 0x00, 0x00, 0x00, 0xfe }; +const uint8_t sua_addr_ssn_bssmap_pc1[] = { 0x00, 0x01, 0x00, 0x07, 0x80, 0x02, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x80, 0x03, 0x00, 0x08, 0x00, 0x00, 0x00, 0xfe }; +const uint8_t sua_addr_ssn_bssmap_pc92[] = { 0x00, 0x01, 0x00, 0x07, 0x80, 0x02, 0x00, 0x08, 0x00, 0x00, 0x00, 0x5c, 0x80, 0x03, 0x00, 0x08, 0x00, 0x00, 0x00, 0xfe }; + +static const struct sccp2sua_testcase sccp2sua_testcases[] = { + { + .name = "BSSMAP-RESET", + .sccp = PANDSIZ(bssmap_reset), + .sua = { + .hdr = XUA_HDR(SUA_MSGC_CL, SUA_CL_CLDT), + .parts = { + PARTU32(SUA_IEI_PROTO_CLASS, &sua_proto_class0), + PARTARR(SUA_IEI_DEST_ADDR, &sua_addr_ssn_bssmap), + PARTARR(SUA_IEI_SRC_ADDR, &sua_addr_ssn_bssmap), + }, + }, + }, { + .name = "BSSMAP-RESET-ACK", + .sccp = PANDSIZ(bssmap_reset_ack), + .sua = { + .hdr = XUA_HDR(SUA_MSGC_CL, SUA_CL_CLDT), + .parts = { + PARTU32(SUA_IEI_PROTO_CLASS, &sua_proto_class0), + PARTARR(SUA_IEI_DEST_ADDR, &sua_addr_ssn_bssmap_pc1), + PARTARR(SUA_IEI_SRC_ADDR, &sua_addr_ssn_bssmap_pc92), + }, + }, + }, { + .name = "BSSMAP-PAGING", + .sccp = PANDSIZ(bssmap_paging), + .sua = { + .hdr = XUA_HDR(SUA_MSGC_CL, SUA_CL_CLDT), + .parts = { + PARTU32(SUA_IEI_PROTO_CLASS, &sua_proto_class0), + PARTARR(SUA_IEI_DEST_ADDR, &sua_addr_ssn_bssmap_pc1), + PARTARR(SUA_IEI_SRC_ADDR, &sua_addr_ssn_bssmap_pc92), + }, + }, + }, { + .name = "BSSMAP-UDT", + .sccp = PANDSIZ(bssmap_udt), + .sua = { + .hdr = XUA_HDR(SUA_MSGC_CL, SUA_CL_CLDT), + .parts = { + PARTU32(SUA_IEI_PROTO_CLASS, &sua_proto_class0), + PARTARR(SUA_IEI_DEST_ADDR, &sua_addr_ssn_bssmap), + PARTARR(SUA_IEI_SRC_ADDR, &sua_addr_ssn_bssmap), + }, + }, + }, { + .name = "BSSMAP-CR", + .sccp = PANDSIZ(bssmap_cr), + .sua = { + .hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_CORE), + .parts = { + PARTU32(SUA_IEI_PROTO_CLASS, &sua_proto_class2), + PARTU32(SUA_IEI_SRC_REF, &sua_loc_ref_bsc), + PARTARR(SUA_IEI_DEST_ADDR, &sua_addr_ssn_bssmap), + }, + }, + }, { + .name = "BSSMAP-CC", + .sccp = PANDSIZ(bssmap_cc), + .sua = { + .hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_COAK), + .parts = { + PARTU32(SUA_IEI_PROTO_CLASS, &sua_proto_class2), + PARTU32(SUA_IEI_SRC_REF, &sua_loc_ref_msc), + PARTARR(SUA_IEI_DEST_ADDR, &sua_loc_ref_bsc), + }, + }, + }, { + .name = "BSSMAP-DTAP", + .sccp = PANDSIZ(bssmap_dtap), + .sua = { + .hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_CODT), + .parts = { + PARTU32(SUA_IEI_SRC_REF, &sua_loc_ref_msc), + }, + }, + }, { + .name = "BSSMAP-CLEAR", + .sccp = PANDSIZ(bssmap_clear), + .sua = { + .hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_CODT), + .parts = { + PARTU32(SUA_IEI_SRC_REF, &sua_loc_ref_msc), + }, + }, + }, { + .name = "BSSMAP-RELEASED", + .sccp = PANDSIZ(bssmap_released), + .sua = { + .hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_RELRE), + .parts = { + PARTU32(SUA_IEI_DEST_REF, &sua_loc_ref_msc), + PARTU32(SUA_IEI_SRC_REF, &sua_loc_ref_bsc), + PARTU32(SUA_IEI_CAUSE, &sua_cause0), + }, + }, + }, { + .name = "BSSMAP-RELEASE_COMPLETE", + .sccp = PANDSIZ(bssmap_release_complete), + .sua = { + .hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_RELCO), + .parts = { + PARTU32(SUA_IEI_DEST_REF, &sua_loc_ref_bsc), + PARTU32(SUA_IEI_SRC_REF, &sua_loc_ref_msc), + }, + }, + }, { + .name = "TCAP", + .sccp = PANDSIZ(tcap_global_title), + .sua = { + .hdr = XUA_HDR(SUA_MSGC_CL, SUA_CL_CLDT), + .parts = { + }, + }, + }, +}; + +static void test_sccp2sua_case(const struct sccp2sua_testcase *tcase) +{ + struct xua_msg *xua; + struct msgb *msg = msgb_alloc(300, "SCCP2SUA Test Input"); + struct msgb *msg2; + + printf("\n=> %s\n", tcase->name); + msg->l2h = msgb_put(msg, tcase->sccp.length); + memcpy(msg->l2h, tcase->sccp.bin, tcase->sccp.length); + printf("SCCP Input: %s\n", msgb_hexdump(msg)); + printf("Transcoding message SCCP -> XUA\n"); + xua = osmo_sccp_to_xua(msg); + OSMO_ASSERT(xua); + + printf("Decoded SUA: "); + printf("%s\n", xua_msg_dump(xua, &xua_dialect_sua)); + + printf("Re-Encoding decoded SUA to SCCP\n"); + msg2 = osmo_sua_to_sccp(xua); + OSMO_ASSERT(msg2); + /* Re-encode xUA to SCCP */ + printf("SCCP Output: %s\n", msgb_hexdump(msg2)); + + if (msgb_length(msg) != msgb_length(msg2) || + memcmp(msgb_data(msg), msgb_data(msg2), msgb_length(msg))) + printf("Input != re-encoded output!\n"); + + /* free related data */ + msgb_free(msg); + msgb_free(msg2); + xua_msg_free(xua); +} + +static void test_sccp2sua(void) +{ + unsigned int i; + for (i = 0; i < ARRAY_SIZE(sccp2sua_testcases); i++) { + test_sccp2sua_case(&sccp2sua_testcases[i]); + } +} + + +static const struct log_info_cat default_categories[] = { + [0] = { + .name = "DSCCP", + .description = "DSCP", + .enabled = 1, .loglevel = LOGL_DEBUG, + }, +}; + +static const struct log_info log_info = { + .cat = default_categories, + .num_cat = ARRAY_SIZE(default_categories), +}; + +int main(int argc, char **argv) +{ + struct log_target *stderr_target; + log_init(&log_info, NULL); + stderr_target = log_target_create_stderr(); + log_add_target(stderr_target); + + test_isup_parse(); + test_sccp_addr_parser(); + test_helpers(); + test_sccp2sua(); + + printf("All tests passed.\n"); + return 0; +} diff --git a/tests/xua/xua_test.ok b/tests/xua/xua_test.ok new file mode 100644 index 0000000..a9fba1d --- /dev/null +++ b/tests/xua/xua_test.ok @@ -0,0 +1,131 @@ +digits='01234567' (8) +digits='0123456' (7) +sccp_addr_parse test case 0 +expected: RI=7,SSN=6,GTI=4,GT=(TT=0,NPL=1,NAI=4,DIG=919969679389) +parsed: RI=7,SSN=6,GTI=4,GT=(TT=0,NPL=1,NAI=4,DIG=919969679389) +sccp_addr_parse test case 1 +expected: RI=7,SSN=8,GTI=4,GT=(TT=0,NPL=1,NAI=4,DIG=919869299992) +parsed: RI=7,SSN=8,GTI=4,GT=(TT=0,NPL=1,NAI=4,DIG=919869299992) +sccp_addr_parse test case 2 +expected: RI=7,SSN=254,GTI=0 +parsed: RI=7,SSN=254,GTI=0 +Testing Decoded GT -> SUA encoding +IN: TT=0,NPL=1,NAI=4,DIG=919969679389 +OUT:TT=0,NPL=1,NAI=4,DIG=919969679389 + +=> BSSMAP-RESET +SCCP Input: [L2]> 09 00 03 05 07 02 42 fe 02 42 fe 06 00 04 30 04 01 20 +Transcoding message SCCP -> XUA +Decoded SUA: HDR=(CL:CLDT,V=0,LEN=0), + PART(T=Protocol Class,L=4,D=00000000), + PART(T=Destination Address,L=12,D=0002000180030008000000fe), + PART(T=Source Address,L=12,D=0002000180030008000000fe), + PART(T=Data,L=6,D=000430040120) +Re-Encoding decoded SUA to SCCP +SCCP Output: 09 00 03 05 07 02 42 fe 02 42 fe 06 00 04 30 04 01 20 + +=> BSSMAP-RESET-ACK +SCCP Input: [L2]> 09 00 03 07 0b 04 43 01 00 fe 04 43 5c 00 fe 03 00 01 31 +Transcoding message SCCP -> XUA +Decoded SUA: HDR=(CL:CLDT,V=0,LEN=0), + PART(T=Protocol Class,L=4,D=00000000), + PART(T=Destination Address,L=20,D=00020003800200080000000180030008000000fe), + PART(T=Source Address,L=20,D=00020003800200080000005c80030008000000fe), + PART(T=Data,L=3,D=000131) +Re-Encoding decoded SUA to SCCP +SCCP Output: 09 00 03 07 0b 04 43 01 00 fe 04 43 5c 00 fe 03 00 01 31 + +=> BSSMAP-PAGING +SCCP Input: [L2]> 09 00 03 07 0b 04 43 01 00 fe 04 43 5c 00 fe 10 00 0e 52 08 08 29 47 10 02 01 31 97 61 1a 01 06 +Transcoding message SCCP -> XUA +Decoded SUA: HDR=(CL:CLDT,V=0,LEN=0), + PART(T=Protocol Class,L=4,D=00000000), + PART(T=Destination Address,L=20,D=00020003800200080000000180030008000000fe), + PART(T=Source Address,L=20,D=00020003800200080000005c80030008000000fe), + PART(T=Data,L=16,D=000e52080829471002013197611a0106) +Re-Encoding decoded SUA to SCCP +SCCP Output: 09 00 03 07 0b 04 43 01 00 fe 04 43 5c 00 fe 10 00 0e 52 08 08 29 47 10 02 01 31 97 61 1a 01 06 + +=> BSSMAP-UDT +SCCP Input: [L2]> 09 00 03 05 07 02 42 fe 02 42 fe 10 00 0e 52 08 08 29 47 10 02 01 31 97 61 1a 01 06 +Transcoding message SCCP -> XUA +Decoded SUA: HDR=(CL:CLDT,V=0,LEN=0), + PART(T=Protocol Class,L=4,D=00000000), + PART(T=Destination Address,L=12,D=0002000180030008000000fe), + PART(T=Source Address,L=12,D=0002000180030008000000fe), + PART(T=Data,L=16,D=000e52080829471002013197611a0106) +Re-Encoding decoded SUA to SCCP +SCCP Output: 09 00 03 05 07 02 42 fe 02 42 fe 10 00 0e 52 08 08 29 47 10 02 01 31 97 61 1a 01 06 + +=> BSSMAP-CR +SCCP Input: [L2]> 01 01 02 03 02 02 04 02 42 fe 0f 1f 00 1d 57 05 08 00 72 f4 80 20 12 c3 50 17 10 05 24 11 03 33 19 a2 08 29 47 10 02 01 31 97 61 00 +Transcoding message SCCP -> XUA +Decoded SUA: HDR=(CO:CORE,V=0,LEN=0), + PART(T=Protocol Class,L=4,D=00000002), + PART(T=Source Reference,L=4,D=00010203), + PART(T=Destination Address,L=12,D=0002000180030008000000fe), + PART(T=Data,L=31,D=001d5705080072f4802012c3501710052411033319a2082947100201319761) +Re-Encoding decoded SUA to SCCP +SCCP Output: 01 01 02 03 02 02 04 02 42 fe 0f 1f 00 1d 57 05 08 00 72 f4 80 20 12 c3 50 17 10 05 24 11 03 33 19 a2 08 29 47 10 02 01 31 97 61 00 + +=> BSSMAP-CC +SCCP Input: [L2]> 02 01 02 03 00 00 03 02 01 00 +Transcoding message SCCP -> XUA +Decoded SUA: HDR=(CO:COAK,V=0,LEN=0), + PART(T=Protocol Class,L=4,D=00000002), + PART(T=Destination Reference,L=4,D=00010203), + PART(T=Source Reference,L=4,D=00000003) +Re-Encoding decoded SUA to SCCP +SCCP Output: 02 01 02 03 00 00 03 02 01 00 + +=> BSSMAP-DTAP +SCCP Input: [L2]> 06 00 00 03 00 01 0f 01 00 0c 03 05 5c 08 11 81 33 66 02 13 45 f4 +Transcoding message SCCP -> XUA +Decoded SUA: HDR=(CO:CODT,V=0,LEN=0), + PART(T=Destination Reference,L=4,D=00000003), + PART(T=Segmentation,L=4,D=00000000), + PART(T=Data,L=15,D=01000c03055c0811813366021345f4) +Re-Encoding decoded SUA to SCCP +SCCP Output: 06 00 00 03 00 01 0f 01 00 0c 03 05 5c 08 11 81 33 66 02 13 45 f4 + +=> BSSMAP-CLEAR +SCCP Input: [L2]> 06 00 00 03 00 01 06 00 04 20 04 01 09 +Transcoding message SCCP -> XUA +Decoded SUA: HDR=(CO:CODT,V=0,LEN=0), + PART(T=Destination Reference,L=4,D=00000003), + PART(T=Segmentation,L=4,D=00000000), + PART(T=Data,L=6,D=000420040109) +Re-Encoding decoded SUA to SCCP +SCCP Output: 06 00 00 03 00 01 06 00 04 20 04 01 09 + +=> BSSMAP-RELEASED +SCCP Input: [L2]> 04 00 00 03 01 02 03 00 01 0f 02 23 42 00 +Transcoding message SCCP -> XUA +Decoded SUA: HDR=(CO:RELRE,V=0,LEN=0), + PART(T=Destination Reference,L=4,D=00000003), + PART(T=Source Reference,L=4,D=00010203), + PART(T=Cause,L=4,D=00000300), + PART(T=Data,L=2,D=2342) +Re-Encoding decoded SUA to SCCP +SCCP Output: 04 00 00 03 01 02 03 00 01 0f 02 23 42 00 + +=> BSSMAP-RELEASE_COMPLETE +SCCP Input: [L2]> 05 01 02 03 00 00 03 +Transcoding message SCCP -> XUA +Decoded SUA: HDR=(CO:RELCO,V=0,LEN=0), + PART(T=Destination Reference,L=4,D=00010203), + PART(T=Source Reference,L=4,D=00000003) +Re-Encoding decoded SUA to SCCP +SCCP Output: 05 01 02 03 00 00 03 + +=> TCAP +SCCP Input: [L2]> 09 81 03 0d 18 0a 12 07 00 12 04 53 84 09 00 17 0b 12 06 00 12 04 44 87 20 00 20 65 9a 65 81 97 48 04 26 00 01 98 49 04 51 01 03 df 6c 81 88 a1 81 85 02 01 44 02 01 07 30 80 a7 80 a0 80 04 01 2b 30 80 30 12 83 01 10 84 01 07 85 07 91 44 57 76 67 16 97 86 01 20 30 06 82 01 18 84 01 04 00 00 00 00 a3 06 04 01 42 84 01 05 a3 06 04 01 51 84 01 05 a3 06 04 01 31 84 01 05 a3 09 04 01 12 84 01 05 82 01 02 a3 09 04 01 11 84 01 05 81 01 01 a3 06 04 01 14 84 01 00 a3 0b 04 01 41 84 01 04 30 03 83 01 10 a3 0b 04 01 41 84 01 04 30 03 82 01 18 00 00 00 00 +Transcoding message SCCP -> XUA +Decoded SUA: HDR=(CL:CLDT,V=0,LEN=0), + PART(T=Protocol Class,L=4,D=00000081), + PART(T=Destination Address,L=32,D=0001000580010014000000040a00010453840900170000008003000800000007), + PART(T=Source Address,L=32,D=0001000580010014000000040c00010444872000206500008003000800000006), + PART(T=Data,L=154,D=6581974804260001984904510103df6c8188a181850201440201073080a780a08004012b30803012830110840107850791445776671697860120300682011884010400000000a306040142840105a306040151840105a306040131840105a309040112840105820102a309040111840105810101a306040114840100a30b0401418401043003830110a30b040141840104300382011800000000) +Re-Encoding decoded SUA to SCCP +SCCP Output: 09 81 03 0d 18 0a 12 07 00 12 04 53 84 09 00 17 0b 12 06 00 12 04 44 87 20 00 20 65 9a 65 81 97 48 04 26 00 01 98 49 04 51 01 03 df 6c 81 88 a1 81 85 02 01 44 02 01 07 30 80 a7 80 a0 80 04 01 2b 30 80 30 12 83 01 10 84 01 07 85 07 91 44 57 76 67 16 97 86 01 20 30 06 82 01 18 84 01 04 00 00 00 00 a3 06 04 01 42 84 01 05 a3 06 04 01 51 84 01 05 a3 06 04 01 31 84 01 05 a3 09 04 01 12 84 01 05 82 01 02 a3 09 04 01 11 84 01 05 81 01 01 a3 06 04 01 14 84 01 00 a3 0b 04 01 41 84 01 04 30 03 83 01 10 a3 0b 04 01 41 84 01 04 30 03 82 01 18 00 00 00 00 +All tests passed. -- To view, visit https://gerrit.osmocom.org/2214 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I7ce038d72dca18fb83d5a12519c9a48267e52ab8 Gerrit-PatchSet: 2 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Apr 4 11:43:10 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 4 Apr 2017 11:43:10 +0000 Subject: [PATCH] libosmo-sccp[master]: SUA: Port to new osmo_ss7 and SCCP code In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2218 to look at the new patch set (#2). SUA: Port to new osmo_ss7 and SCCP code If we use the infrastructure provided by osmo_ss7 on the lower layer and the SCCP SCRC, SCLC and SCOC code on the upper side, not much of the original sua.c code remains. It looks much like the M3UA code now. Change-Id: I193b74f58aa70c443ae17e78b5604246d6bc3f71 --- M include/osmocom/sigtran/Makefile.am M include/osmocom/sigtran/sccp_helpers.h D include/osmocom/sigtran/sua.h M src/osmo_ss7.c M src/sccp_helpers.c M src/sccp_scrc.c M src/sua.c M src/xua_internal.h 8 files changed, 364 insertions(+), 1,297 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/18/2218/2 diff --git a/include/osmocom/sigtran/Makefile.am b/include/osmocom/sigtran/Makefile.am index ca7a304..0aa90cb 100644 --- a/include/osmocom/sigtran/Makefile.am +++ b/include/osmocom/sigtran/Makefile.am @@ -1,5 +1,5 @@ sigtran_HEADERS = xua_types.h xua_msg.h m2ua_types.h sccp_sap.h \ - sua.h sigtran_sap.h sccp_helpers.h mtp_sap.h osmo_ss7.h + sigtran_sap.h sccp_helpers.h mtp_sap.h osmo_ss7.h sigtrandir = $(includedir)/osmocom/sigtran diff --git a/include/osmocom/sigtran/sccp_helpers.h b/include/osmocom/sigtran/sccp_helpers.h index 968c500..bbd0364 100644 --- a/include/osmocom/sigtran/sccp_helpers.h +++ b/include/osmocom/sigtran/sccp_helpers.h @@ -1,15 +1,17 @@ #pragma once + #include #include #include -#include -int osmo_sccp_tx_unitdata(struct osmo_sccp_link *link, +void osmo_sccp_make_addr_pc_ssn(struct osmo_sccp_addr *addr, uint32_t pc, uint32_t ssn); + +int osmo_sccp_tx_unitdata(struct osmo_sccp_user *scu, const struct osmo_sccp_addr *calling_addr, const struct osmo_sccp_addr *called_addr, - uint8_t *data, unsigned int len); + const uint8_t *data, unsigned int len); -int osmo_sccp_tx_unitdata_msg(struct osmo_sccp_link *link, +int osmo_sccp_tx_unitdata_msg(struct osmo_sccp_user *scu, const struct osmo_sccp_addr *calling_addr, const struct osmo_sccp_addr *called_addr, struct msgb *msg); @@ -17,26 +19,38 @@ void osmo_sccp_make_addr_pc_ssn(struct osmo_sccp_addr *addr, uint32_t pc, uint32_t ssn); -int osmo_sccp_tx_unitdata_ranap(struct osmo_sccp_link *link, +int osmo_sccp_tx_unitdata_ranap(struct osmo_sccp_user *scu, uint32_t src_point_code, uint32_t dst_point_code, - uint8_t *data, unsigned int len); + const uint8_t *data, unsigned int len); -int osmo_sccp_tx_conn_req(struct osmo_sccp_link *link, uint32_t conn_id, +int osmo_sccp_tx_conn_req(struct osmo_sccp_user *scu, uint32_t conn_id, const struct osmo_sccp_addr *calling_addr, const struct osmo_sccp_addr *called_addr, - uint8_t *data, unsigned int len); + const uint8_t *data, unsigned int len); -int osmo_sccp_tx_conn_req_msg(struct osmo_sccp_link *link, uint32_t conn_id, +int osmo_sccp_tx_conn_req_msg(struct osmo_sccp_user *scu, uint32_t conn_id, const struct osmo_sccp_addr *calling_addr, const struct osmo_sccp_addr *called_addr, struct msgb *msg); -int osmo_sccp_tx_data(struct osmo_sccp_link *link, uint32_t conn_id, - uint8_t *data, unsigned int len); +int osmo_sccp_tx_data(struct osmo_sccp_user *scu, uint32_t conn_id, + const uint8_t *data, unsigned int len); -int osmo_sccp_tx_data_msg(struct osmo_sccp_link *link, uint32_t conn_id, +int osmo_sccp_tx_data_msg(struct osmo_sccp_user *scu, uint32_t conn_id, struct msgb *msg); +int osmo_sccp_tx_disconn(struct osmo_sccp_user *scu, uint32_t conn_id, + const struct osmo_sccp_addr *resp_addr, + uint32_t cause); + +int osmo_sccp_tx_conn_resp_msg(struct osmo_sccp_user *scu, uint32_t conn_id, + const struct osmo_sccp_addr *resp_addr, + struct msgb *msg); + +int osmo_sccp_tx_conn_resp(struct osmo_sccp_user *scu, uint32_t conn_id, + const struct osmo_sccp_addr *resp_addr, + const uint8_t *data, unsigned int len); + char *osmo_sccp_gt_dump(const struct osmo_sccp_gt *gt); char *osmo_sccp_addr_dump(const struct osmo_sccp_addr *addr); diff --git a/include/osmocom/sigtran/sua.h b/include/osmocom/sigtran/sua.h deleted file mode 100644 index 766b488..0000000 --- a/include/osmocom/sigtran/sua.h +++ /dev/null @@ -1,23 +0,0 @@ -#pragma once - -#include -#include - -struct osmo_sccp_user; -struct osmo_sccp_link; - -void osmo_sua_set_log_area(int area); - -struct osmo_sccp_user *osmo_sua_user_create(void *ctx, osmo_prim_cb prim_cb, - void *priv); -void osmo_sua_user_destroy(struct osmo_sccp_user *user); - -int osmo_sua_server_listen(struct osmo_sccp_user *user, const char *hostname, uint16_t port); - -int osmo_sua_client_connect(struct osmo_sccp_user *user, const char *hostname, uint16_t port); -struct osmo_sccp_link *osmo_sua_client_get_link(struct osmo_sccp_user *user); - -/* user hands us a SCCP-USER SAP primitive down into the stack */ -int osmo_sua_user_link_down(struct osmo_sccp_link *link, struct osmo_prim_hdr *oph); - -void *osmo_sccp_link_get_user_priv(struct osmo_sccp_link *slink); diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index 6d0b446..ab0636c 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -1197,7 +1197,9 @@ msgb_sctp_stream(msg) = ntohl(sinfo.sinfo_stream); msg->dst = asp; - if (ppid == M3UA_PPID && asp->cfg.proto == OSMO_SS7_ASP_PROT_M3UA) + if (ppid == SUA_PPID && asp->cfg.proto == OSMO_SS7_ASP_PROT_SUA) + rc = sua_rx_msg(asp, msg); + else if (ppid == M3UA_PPID && asp->cfg.proto == OSMO_SS7_ASP_PROT_M3UA) rc = m3ua_rx_msg(asp, msg); else { LOGPASP(asp, DLSS7, LOGL_NOTICE, "SCTP chunk for unknown PPID %u " @@ -1280,7 +1282,9 @@ msgb_sctp_stream(msg) = ntohl(sinfo.sinfo_stream); msg->dst = asp; - if (ppid == M3UA_PPID && asp->cfg.proto == OSMO_SS7_ASP_PROT_M3UA) + if (ppid == SUA_PPID && asp->cfg.proto == OSMO_SS7_ASP_PROT_SUA) + rc = sua_rx_msg(asp, msg); + else if (ppid == M3UA_PPID && asp->cfg.proto == OSMO_SS7_ASP_PROT_M3UA) rc = m3ua_rx_msg(asp, msg); else { LOGPASP(asp, DLSS7, LOGL_NOTICE, "SCTP chunk for unknown PPID %u " diff --git a/src/sccp_helpers.c b/src/sccp_helpers.c index 6264424..c588607 100644 --- a/src/sccp_helpers.c +++ b/src/sccp_helpers.c @@ -1,6 +1,6 @@ /* SCCP User SAP helper functions */ -/* (C) 2015 by Harald Welte +/* (C) 2015-2017 by Harald Welte * (C) 2016 by sysmocom s.m.f.c. GmbH * All Rights Reserved * @@ -27,8 +27,14 @@ #include #include -#include #include + +#include "sccp_internal.h" + +static struct msgb *scu_msgb_alloc(const char *name) +{ + return sccp_msgb_alloc("SCU"); +} void osmo_sccp_make_addr_pc_ssn(struct osmo_sccp_addr *addr, uint32_t pc, uint32_t ssn) { @@ -37,12 +43,12 @@ addr->pc = pc; } -int osmo_sccp_tx_unitdata(struct osmo_sccp_link *link, +int osmo_sccp_tx_unitdata(struct osmo_sccp_user *scu, const struct osmo_sccp_addr *calling_addr, const struct osmo_sccp_addr *called_addr, - uint8_t *data, unsigned int len) + const uint8_t *data, unsigned int len) { - struct msgb *msg = msgb_alloc(1024, "sccp_tx_unitdata"); + struct msgb *msg = scu_msgb_alloc(__func__); struct osmo_scu_prim *prim; struct osmo_scu_unitdata_param *param; @@ -55,13 +61,13 @@ msg->l2h = msgb_put(msg, len); memcpy(msg->l2h, data, len); - return osmo_sua_user_link_down(link, &prim->oph); + return osmo_sccp_user_sap_down(scu, &prim->oph); } -int osmo_sccp_tx_unitdata_ranap(struct osmo_sccp_link *link, +int osmo_sccp_tx_unitdata_ranap(struct osmo_sccp_user *scu, uint32_t src_point_code, uint32_t dst_point_code, - uint8_t *data, unsigned int len) + const uint8_t *data, unsigned int len) { struct osmo_sccp_addr calling_addr; struct osmo_sccp_addr called_addr; @@ -69,67 +75,70 @@ OSMO_SCCP_SSN_RANAP); osmo_sccp_make_addr_pc_ssn(&called_addr, dst_point_code, OSMO_SCCP_SSN_RANAP); - return osmo_sccp_tx_unitdata(link, &calling_addr, &called_addr, + return osmo_sccp_tx_unitdata(scu, &calling_addr, &called_addr, data, len); } -int osmo_sccp_tx_unitdata_msg(struct osmo_sccp_link *link, +int osmo_sccp_tx_unitdata_msg(struct osmo_sccp_user *scu, const struct osmo_sccp_addr *calling_addr, const struct osmo_sccp_addr *called_addr, struct msgb *msg) { int rc; - rc = osmo_sccp_tx_unitdata(link, calling_addr, called_addr, + rc = osmo_sccp_tx_unitdata(scu, calling_addr, called_addr, msg->data, msgb_length(msg)); msgb_free(msg); return rc; } -int osmo_sccp_tx_conn_req(struct osmo_sccp_link *link, uint32_t conn_id, +int osmo_sccp_tx_conn_req(struct osmo_sccp_user *scu, uint32_t conn_id, const struct osmo_sccp_addr *calling_addr, const struct osmo_sccp_addr *called_addr, - uint8_t *data, unsigned int len) + const uint8_t *data, unsigned int len) { - struct msgb *msg = msgb_alloc(1024, "sccp_tx_conn_req"); + struct msgb *msg = scu_msgb_alloc(__func__); struct osmo_scu_prim *prim; + struct osmo_scu_connect_param *param; prim = (struct osmo_scu_prim *) msgb_put(msg, sizeof(*prim)); osmo_prim_init(&prim->oph, SCCP_SAP_USER, OSMO_SCU_PRIM_N_CONNECT, PRIM_OP_REQUEST, msg); - osmo_sccp_make_addr_pc_ssn(&prim->u.connect.calling_addr, 1, - OSMO_SCCP_SSN_RANAP); - prim->u.connect.sccp_class = 2; - prim->u.connect.conn_id = conn_id; + param = &prim->u.connect; + if (calling_addr) + memcpy(¶m->calling_addr, calling_addr, sizeof(*calling_addr)); + memcpy(¶m->called_addr, called_addr, sizeof(*called_addr)); + param->sccp_class = 2; + param->conn_id = conn_id; if (data && len) { msg->l2h = msgb_put(msg, len); memcpy(msg->l2h, data, len); } - return osmo_sua_user_link_down(link, &prim->oph); + return osmo_sccp_user_sap_down(scu, &prim->oph); } -int osmo_sccp_tx_conn_req_msg(struct osmo_sccp_link *link, uint32_t conn_id, +int osmo_sccp_tx_conn_req_msg(struct osmo_sccp_user *scu, uint32_t conn_id, const struct osmo_sccp_addr *calling_addr, const struct osmo_sccp_addr *called_addr, struct msgb *msg) { int rc; - rc = osmo_sccp_tx_conn_req(link, conn_id, calling_addr, called_addr, + rc = osmo_sccp_tx_conn_req(scu, conn_id, calling_addr, called_addr, msg->data, msgb_length(msg)); msgb_free(msg); return rc; } -int osmo_sccp_tx_data(struct osmo_sccp_link *link, uint32_t conn_id, - uint8_t *data, unsigned int len) +int osmo_sccp_tx_data(struct osmo_sccp_user *scu, uint32_t conn_id, + const uint8_t *data, unsigned int len) { - struct msgb *msg = msgb_alloc(1024, "sccp_tx_data"); + struct msgb *msg = scu_msgb_alloc(__func__); struct osmo_scu_prim *prim; prim = (struct osmo_scu_prim *) msgb_put(msg, sizeof(*prim)); @@ -141,20 +150,79 @@ msg->l2h = msgb_put(msg, len); memcpy(msg->l2h, data, len); - return osmo_sua_user_link_down(link, &prim->oph); + return osmo_sccp_user_sap_down(scu, &prim->oph); } -int osmo_sccp_tx_data_msg(struct osmo_sccp_link *link, uint32_t conn_id, +int osmo_sccp_tx_data_msg(struct osmo_sccp_user *scu, uint32_t conn_id, struct msgb *msg) { int rc; - rc = osmo_sccp_tx_data(link, conn_id, msg->data, msgb_length(msg)); + rc = osmo_sccp_tx_data(scu, conn_id, msg->data, msgb_length(msg)); msgb_free(msg); return rc; } +/* N-DISCONNECT.req */ +int osmo_sccp_tx_disconn(struct osmo_sccp_user *scu, uint32_t conn_id, + const struct osmo_sccp_addr *resp_addr, + uint32_t cause) +{ + struct msgb *msg = scu_msgb_alloc(__func__); + struct osmo_scu_prim *prim; + struct osmo_scu_disconn_param *param; + + prim = (struct osmo_scu_prim *) msgb_put(msg, sizeof(*prim)); + osmo_prim_init(&prim->oph, SCCP_SAP_USER, + OSMO_SCU_PRIM_N_DISCONNECT, + PRIM_OP_REQUEST, msg); + param = &prim->u.disconnect; + memset(param, 0, sizeof(*param)); + param->originator = OSMO_SCCP_ORIG_NS_USER; + if (resp_addr) + memcpy(¶m->responding_addr, resp_addr, sizeof(*resp_addr)); + param->conn_id = conn_id; + param->cause = cause; + + return osmo_sccp_user_sap_down(scu, &prim->oph); +} + +/* N-CONNECT.resp */ +int osmo_sccp_tx_conn_resp_msg(struct osmo_sccp_user *scu, uint32_t conn_id, + const struct osmo_sccp_addr *resp_addr, + struct msgb *msg) +{ + struct osmo_scu_prim *prim; + struct osmo_scu_connect_param *param; + + msg->l2h = msg->data; + + prim = (struct osmo_scu_prim *) msgb_push(msg, sizeof(*prim)); + osmo_prim_init(&prim->oph, SCCP_SAP_USER, + OSMO_SCU_PRIM_N_CONNECT, + PRIM_OP_RESPONSE, msg); + param = &prim->u.connect; + param->conn_id = conn_id; + memcpy(¶m->responding_addr, resp_addr, sizeof(*resp_addr)); + param->sccp_class = 2; + + return osmo_sccp_user_sap_down(scu, &prim->oph); +} + +int osmo_sccp_tx_conn_resp(struct osmo_sccp_user *scu, uint32_t conn_id, + const struct osmo_sccp_addr *resp_addr, + const uint8_t *data, unsigned int len) +{ + struct msgb *msg = scu_msgb_alloc(__func__); + + if (data && len) { + msg->l2h = msgb_put(msg, len); + memcpy(msg->l2h, data, len); + } + return osmo_sccp_tx_conn_resp_msg(scu, conn_id, resp_addr, msg); +} + static void append_to_buf(char *buf, bool *comma, const char *fmt, ...) { va_list ap; diff --git a/src/sccp_scrc.c b/src/sccp_scrc.c index 11c52e8..5653ea9 100644 --- a/src/sccp_scrc.c +++ b/src/sccp_scrc.c @@ -139,6 +139,8 @@ if (rt->dest.as) { struct osmo_ss7_as *as = rt->dest.as; switch (as->cfg.proto) { + case OSMO_SS7_ASP_PROT_SUA: + return sua_tx_xua_as(as, xua); case OSMO_SS7_ASP_PROT_M3UA: return sua2sccp_tx_m3ua(inst, xua); default: diff --git a/src/sua.c b/src/sua.c index b135c62..836e02e 100644 --- a/src/sua.c +++ b/src/sua.c @@ -29,17 +29,20 @@ #include #include #include +#include #include #include #include +#include #include -#include +#include +#include +#include "xua_asp_fsm.h" #include "xua_internal.h" - -#define SUA_MSGB_SIZE 1500 +#include "sccp_internal.h" /* Appendix C.4 of Q.714 (all in milliseconds) */ #define CONNECTION_TIMER ( 1 * 60 * 100) @@ -205,6 +208,7 @@ .name = "SUA", .ppid = SUA_PPID, .port = SUA_PORT, + .log_subsys = DLSUA, .class = { [SUA_MSGC_MGMT] = &m3ua_msg_class_mgmt, [SUA_MSGC_SNM] = &m3ua_msg_class_snm, @@ -216,482 +220,82 @@ }, }; - -static int DSUA = -1; - -struct osmo_sccp_user { - /* global list of SUA users? */ - struct llist_head list; - /* set if we are a server */ - struct osmo_stream_srv_link *server; - struct osmo_stream_cli *client; - struct llist_head links; - /* user call-back function in case of incoming primitives */ - osmo_prim_cb prim_cb; - void *priv; -}; - -struct osmo_sccp_link { - /* list of SUA links per sua_user */ - struct llist_head list; - /* sua user to which we belong */ - struct osmo_sccp_user *user; - /* local list of (SCCP) connections in this link */ - struct llist_head connections; - /* next connection local reference */ - uint32_t next_id; - int is_server; - void *data; -}; - -enum sua_connection_state { - S_IDLE, - S_CONN_PEND_IN, - S_CONN_PEND_OUT, - S_ACTIVE, - S_DISCONN_PEND, - S_RESET_IN, - S_RESET_OUT, - S_BOTHWAY_RESET, - S_WAIT_CONN_CONF, -}; - -static const struct value_string conn_state_names[] = { - { S_IDLE, "IDLE" }, - { S_CONN_PEND_IN, "CONN_PEND_IN" }, - { S_CONN_PEND_OUT, "CONN_PEND_OUT" }, - { S_ACTIVE, "ACTIVE" }, - { S_DISCONN_PEND, "DISCONN_PEND" }, - { S_RESET_IN, "RESET_IN" }, - { S_RESET_OUT, "RESET_OUT" }, - { S_BOTHWAY_RESET, "BOTHWAY_RESET" }, - { S_WAIT_CONN_CONF, "WAIT_CONN_CONF" }, - { 0, NULL } -}; - -struct sua_connection { - struct llist_head list; - struct osmo_sccp_link *link; - struct osmo_sccp_addr calling_addr; - struct osmo_sccp_addr called_addr; - uint32_t conn_id; - uint32_t remote_ref; - enum sua_connection_state state; - struct osmo_timer_list timer; - /* inactivity timers */ - struct osmo_timer_list tias; - struct osmo_timer_list tiar; -}; - - /*********************************************************************** - * SUA Link and Connection handling + * ERROR generation ***********************************************************************/ -static struct osmo_sccp_link *sua_link_new(struct osmo_sccp_user *user, int is_server) +static struct xua_msg *sua_gen_error(uint32_t err_code) { - struct osmo_sccp_link *link; + struct xua_msg *xua = xua_msg_alloc(); - link = talloc_zero(user, struct osmo_sccp_link); - if (!link) - return NULL; + xua->hdr = XUA_HDR(SUA_MSGC_MGMT, SUA_MGMT_ERR); + xua->hdr.version = SUA_VERSION; + xua_msg_add_u32(xua, SUA_IEI_ERR_CODE, err_code); - link->user = user; - link->is_server = is_server; - INIT_LLIST_HEAD(&link->connections); - - llist_add_tail(&link->list, &user->links); - - return link; + return xua; } -static void conn_destroy(struct sua_connection *conn); - -static void sua_link_destroy(struct osmo_sccp_link *link) +static struct xua_msg *sua_gen_error_msg(uint32_t err_code, struct msgb *msg) { - struct sua_connection *conn; + struct xua_msg *xua = sua_gen_error(err_code); + unsigned int len_max_40 = msgb_length(msg); - llist_for_each_entry(conn, &link->connections, list) - conn_destroy(conn); + if (len_max_40 > 40) + len_max_40 = 40; - llist_del(&link->list); + xua_msg_add_data(xua, SUA_IEI_DIAG_INFO, len_max_40, msgb_data(msg)); - /* FIXME: do we need to cleanup the sccp link? */ - - talloc_free(link); + return xua; } -static int sua_link_send(struct osmo_sccp_link *link, struct msgb *msg) +/*********************************************************************** + * Transmitting SUA messsages to SCTP + ***********************************************************************/ + +static int sua_tx_xua_asp(struct osmo_ss7_asp *asp, struct xua_msg *xua) { + struct msgb *msg = xua_to_msg(SUA_VERSION, xua); + + OSMO_ASSERT(asp->cfg.proto == OSMO_SS7_ASP_PROT_SUA); + + xua_msg_free(xua); + + if (!msg) { + LOGPASP(asp, DLSUA, LOGL_ERROR, "Error encoding SUA Msg\n"); + return -1; + } + msgb_sctp_ppid(msg) = SUA_PPID; - - DEBUGP(DSUA, "sua_link_send(%s)\n", osmo_hexdump(msg->data, msgb_length(msg))); - - if (link->is_server) - osmo_stream_srv_send(link->data, msg); - else - osmo_stream_cli_send(link->data, msg); - - return 0; + return osmo_ss7_asp_send(asp, msg); } -static struct sua_connection *conn_find_by_id(struct osmo_sccp_link *link, uint32_t id) +/*! \brief Send a given xUA message via a given SUA Application Server + * \param[in] as Application Server through which to send \ref xua + * \param[in] xua xUA message to be sent + * \return 0 on success; negative on error */ +int sua_tx_xua_as(struct osmo_ss7_as *as, struct xua_msg *xua) { - struct sua_connection *conn; + struct osmo_ss7_asp *asp; + unsigned int i; - llist_for_each_entry(conn, &link->connections, list) { - if (conn->conn_id == id) - return conn; + OSMO_ASSERT(as->cfg.proto == OSMO_SS7_ASP_PROT_SUA); + + /* FIXME: Select ASP within AS depending on traffic mode */ + for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) { + asp = as->cfg.asps[i]; + if (!asp) + continue; + if (asp) + break; } - return NULL; -} - -static void tx_inact_tmr_cb(void *data) -{ - struct sua_connection *conn = data; - struct xua_msg *xua = xua_msg_alloc(); - struct msgb *outmsg; - - /* encode + send the CLDT */ - xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_COIT); - xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, 0); /* FIXME */ - xua_msg_add_u32(xua, SUA_IEI_PROTO_CLASS, 2); - xua_msg_add_u32(xua, SUA_IEI_SRC_REF, conn->conn_id); - xua_msg_add_u32(xua, SUA_IEI_DEST_REF, conn->remote_ref); - /* optional: sequence number; credit (both class 3 only) */ - - outmsg = xua_to_msg(1, xua); - xua_msg_free(xua); - - sua_link_send(conn->link, outmsg); -} - -static void rx_inact_tmr_cb(void *data) -{ - struct sua_connection *conn = data; - - /* FIXME: release connection */ - /* Send N-DISCONNECT.ind to local user */ - /* Send RLSD to peer */ - /* enter disconnect pending state with release timer pending */ -} - - -static struct sua_connection *conn_create_id(struct osmo_sccp_link *link, uint32_t conn_id) -{ - struct sua_connection *conn = talloc_zero(link, struct sua_connection); - - conn->conn_id = conn_id; - conn->link = link; - conn->state = S_IDLE; - - llist_add_tail(&conn->list, &link->connections); - - conn->tias.cb = tx_inact_tmr_cb; - conn->tias.data = conn; - conn->tiar.cb = rx_inact_tmr_cb; - conn->tiar.data = conn; - - return conn; -} - -static struct sua_connection *conn_create(struct osmo_sccp_link *link) -{ - uint32_t conn_id; - - do { - conn_id = link->next_id++; - } while (conn_find_by_id(link, conn_id)); - - return conn_create_id(link, conn_id); -} - -static void conn_destroy(struct sua_connection *conn) -{ - /* FIXME: do some cleanup; inform user? */ - osmo_timer_del(&conn->tias); - osmo_timer_del(&conn->tiar); - llist_del(&conn->list); - talloc_free(conn); -} - -static void conn_state_set(struct sua_connection *conn, - enum sua_connection_state state) -{ - DEBUGP(DSUA, "(%u) state chg %s->", conn->conn_id, - get_value_string(conn_state_names, conn->state)); - DEBUGPC(DSUA, "%s\n", - get_value_string(conn_state_names, state)); - conn->state = state; -} - -static void conn_restart_tx_inact_timer(struct sua_connection *conn) -{ - osmo_timer_schedule(&conn->tias, TX_INACT_TIMER / 100, - (TX_INACT_TIMER % 100) * 10); -} - -static void conn_restart_rx_inact_timer(struct sua_connection *conn) -{ - osmo_timer_schedule(&conn->tiar, RX_INACT_TIMER / 100, - (RX_INACT_TIMER % 100) * 10); -} - -static void conn_start_inact_timers(struct sua_connection *conn) -{ - conn_restart_tx_inact_timer(conn); - conn_restart_rx_inact_timer(conn); -} - -/*********************************************************************** - * Handling of messages from the User SAP - ***********************************************************************/ - -/* user program sends us a N-CONNNECT.req to initiate a new connection */ -static int sua_connect_req(struct osmo_sccp_link *link, struct osmo_scu_prim *prim) -{ - struct osmo_scu_connect_param *par = &prim->u.connect; - struct xua_msg *xua = xua_msg_alloc(); - struct sua_connection *conn; - struct msgb *outmsg; - - if (par->sccp_class != 2) { - LOGP(DSUA, LOGL_ERROR, "N-CONNECT.req for unsupported " - "SCCP class %u\n", par->sccp_class); - /* FIXME: Send primitive to user */ - return -EINVAL; - } - - conn = conn_create_id(link, par->conn_id); - if (!conn) { - /* FIXME: Send primitive to user */ - return -EINVAL; - } - - memcpy(&conn->called_addr, &par->called_addr, - sizeof(conn->called_addr)); - memcpy(&conn->calling_addr, &par->calling_addr, - sizeof(conn->calling_addr)); - - /* encode + send the CLDT */ - xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_CORE); - xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, 0); /* FIXME */ - xua_msg_add_u32(xua, SUA_IEI_PROTO_CLASS, par->sccp_class); - xua_msg_add_u32(xua, SUA_IEI_SRC_REF, conn->conn_id); - xua_msg_add_sccp_addr(xua, SUA_IEI_DEST_ADDR, &par->called_addr); - xua_msg_add_u32(xua, SUA_IEI_SEQ_CTRL, 0); /* FIXME */ - /* sequence number */ - if (par->calling_addr.presence) - xua_msg_add_sccp_addr(xua, SUA_IEI_SRC_ADDR, &par->calling_addr); - /* optional: hop count; importance; priority; credit */ - if (msgb_l2(prim->oph.msg)) - xua_msg_add_data(xua, SUA_IEI_DATA, msgb_l2len(prim->oph.msg), - msgb_l2(prim->oph.msg)); - - outmsg = xua_to_msg(1, xua); - xua_msg_free(xua); - - /* FIXME: Start CONNECTION_TIMER */ - conn_state_set(conn, S_CONN_PEND_OUT); - - return sua_link_send(link, outmsg); -} - -/* user program sends us a N-CONNNECT.resp, presumably against a - * N-CONNECT.ind */ -static int sua_connect_resp(struct osmo_sccp_link *link, struct osmo_scu_prim *prim) -{ - struct osmo_scu_connect_param *par = &prim->u.connect; - struct xua_msg *xua = xua_msg_alloc(); - struct sua_connection *conn; - struct msgb *outmsg; - - /* check if we already know a connection for this conn_id */ - conn = conn_find_by_id(link, par->conn_id); - if (!conn) { - LOGP(DSUA, LOGL_ERROR, "N-CONNECT.resp for unknown " - "connection ID %u\n", par->conn_id); - /* FIXME: Send primitive to user */ + if (!asp) { + LOGP(DLSUA, LOGL_ERROR, "No ASP in AS, dropping message\n"); + xua_msg_free(xua); return -ENODEV; } - if (conn->state != S_CONN_PEND_IN) { - LOGP(DSUA, LOGL_ERROR, "N-CONNECT.resp in wrong state %s\n", - get_value_string(conn_state_names, conn->state)); - /* FIXME: Send primitive to user */ - return -EINVAL; - } - - /* encode + send the COAK message */ - xua = xua_msg_alloc(); - xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_COAK); - xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, 0); /* FIXME */ - xua_msg_add_u32(xua, SUA_IEI_PROTO_CLASS, par->sccp_class); - xua_msg_add_u32(xua, SUA_IEI_DEST_REF, conn->remote_ref); - xua_msg_add_u32(xua, SUA_IEI_SRC_REF, conn->conn_id); - xua_msg_add_u32(xua, SUA_IEI_SEQ_CTRL, 0); /* FIXME */ - /* sequence number */ - if (par->calling_addr.presence) - xua_msg_add_sccp_addr(xua, SUA_IEI_SRC_ADDR, &par->calling_addr); - /* optional: hop count; importance; priority */ - /* FIXME: destination address will be present in case the CORE - * message conveys the source address parameter */ - if (par->called_addr.presence) - xua_msg_add_sccp_addr(xua, SUA_IEI_DEST_ADDR, &par->called_addr); - if (msgb_l2(prim->oph.msg)) - xua_msg_add_data(xua, SUA_IEI_DATA, msgb_l2len(prim->oph.msg), - msgb_l2(prim->oph.msg)); - - outmsg = xua_to_msg(1, xua); - xua_msg_free(xua); - - conn_state_set(conn, S_ACTIVE); - conn_start_inact_timers(conn); - - return sua_link_send(link, outmsg); + return sua_tx_xua_asp(asp, xua); } - -/* user wants to send connection-oriented data */ -static int sua_data_req(struct osmo_sccp_link *link, struct osmo_scu_prim *prim) -{ - struct osmo_scu_data_param *par = &prim->u.data; - struct xua_msg *xua; - struct sua_connection *conn; - struct msgb *outmsg; - - /* check if we know about this conncetion, and obtain reference */ - conn = conn_find_by_id(link, par->conn_id); - if (!conn) { - LOGP(DSUA, LOGL_ERROR, "N-DATA.req for unknown " - "connection ID %u\n", par->conn_id); - /* FIXME: Send primitive to user */ - return -ENODEV; - } - - if (conn->state != S_ACTIVE) { - LOGP(DSUA, LOGL_ERROR, "N-DATA.req in wrong state %s\n", - get_value_string(conn_state_names, conn->state)); - /* FIXME: Send primitive to user */ - return -EINVAL; - } - - conn_restart_tx_inact_timer(conn); - - /* encode + send the CODT message */ - xua = xua_msg_alloc(); - xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_CODT); - xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, 0); /* FIXME */ - /* Sequence number only in expedited data */ - xua_msg_add_u32(xua, SUA_IEI_DEST_REF, conn->remote_ref); - /* optional: priority; correlation id */ - xua_msg_add_data(xua, SUA_IEI_DATA, msgb_l2len(prim->oph.msg), - msgb_l2(prim->oph.msg)); - - outmsg = xua_to_msg(1, xua); - xua_msg_free(xua); - - return sua_link_send(link, outmsg); -} - -/* user wants to disconnect a connection */ -static int sua_disconnect_req(struct osmo_sccp_link *link, struct osmo_scu_prim *prim) -{ - struct osmo_scu_disconn_param *par = &prim->u.disconnect; - struct xua_msg *xua; - struct sua_connection *conn; - struct msgb *outmsg; - - /* resolve reference of connection */ - conn = conn_find_by_id(link, par->conn_id); - if (!conn) { - LOGP(DSUA, LOGL_ERROR, "N-DISCONNECT.req for unknown " - "connection ID %u\n", par->conn_id); - /* FIXME: Send primitive to user */ - return -ENODEV; - } - - /* encode + send the RELRE */ - xua = xua_msg_alloc(); - xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_RELRE); - xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, 0); /* FIXME */ - xua_msg_add_u32(xua, SUA_IEI_DEST_REF, conn->remote_ref); - xua_msg_add_u32(xua, SUA_IEI_SRC_REF, conn->conn_id); - xua_msg_add_u32(xua, SUA_IEI_CAUSE, par->cause); - /* optional: importance */ - if (msgb_l2(prim->oph.msg)) - xua_msg_add_data(xua, SUA_IEI_DATA, msgb_l2len(prim->oph.msg), - msgb_l2(prim->oph.msg)); - - outmsg = xua_to_msg(1, xua); - xua_msg_free(xua); - - conn_state_set(conn, S_DISCONN_PEND); - conn_destroy(conn); - - LOGP(DSUA, LOGL_NOTICE, "About to send the SUA RELRE\n"); - return sua_link_send(link, outmsg); -} - -/* user wants to send connectionless data */ -static int sua_unitdata_req(struct osmo_sccp_link *link, struct osmo_scu_prim *prim) -{ - struct osmo_scu_unitdata_param *par = &prim->u.unitdata; - struct xua_msg *xua = xua_msg_alloc(); - struct msgb *outmsg; - - /* encode + send the CLDT */ - xua->hdr = XUA_HDR(SUA_MSGC_CL, SUA_CL_CLDT); - xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, 0); /* FIXME */ - xua_msg_add_u32(xua, SUA_IEI_PROTO_CLASS, 0); - xua_msg_add_sccp_addr(xua, SUA_IEI_SRC_ADDR, &par->calling_addr); - xua_msg_add_sccp_addr(xua, SUA_IEI_DEST_ADDR, &par->called_addr); - xua_msg_add_u32(xua, SUA_IEI_SEQ_CTRL, par->in_sequence_control); - /* optional: importance, ... correlation id? */ - xua_msg_add_data(xua, SUA_IEI_DATA, msgb_l2len(prim->oph.msg), - msgb_l2(prim->oph.msg)); - - outmsg = xua_to_msg(1, xua); - xua_msg_free(xua); - - return sua_link_send(link, outmsg); -} - -/* user hands us a SCCP-USER SAP primitive down into the stack */ -int osmo_sua_user_link_down(struct osmo_sccp_link *link, struct osmo_prim_hdr *oph) -{ - struct osmo_scu_prim *prim = (struct osmo_scu_prim *) oph; - struct msgb *msg = prim->oph.msg; - int rc = 0; - - LOGP(DSUA, LOGL_DEBUG, "Received SCCP User Primitive (%s)\n", - osmo_scu_prim_name(&prim->oph)); - - switch (OSMO_PRIM_HDR(&prim->oph)) { - case OSMO_PRIM(OSMO_SCU_PRIM_N_CONNECT, PRIM_OP_REQUEST): - rc = sua_connect_req(link, prim); - break; - case OSMO_PRIM(OSMO_SCU_PRIM_N_CONNECT, PRIM_OP_RESPONSE): - rc = sua_connect_resp(link, prim); - break; - case OSMO_PRIM(OSMO_SCU_PRIM_N_DATA, PRIM_OP_REQUEST): - rc = sua_data_req(link, prim); - break; - case OSMO_PRIM(OSMO_SCU_PRIM_N_DISCONNECT, PRIM_OP_REQUEST): - rc = sua_disconnect_req(link, prim); - break; - case OSMO_PRIM(OSMO_SCU_PRIM_N_UNITDATA, PRIM_OP_REQUEST): - rc = sua_unitdata_req(link, prim); - break; - default: - rc = -1; - } - - if (rc != 1) - msgb_free(msg); - - return rc; -} - /*********************************************************************** * Receiving SUA messsages from SCTP @@ -751,12 +355,12 @@ memset(out, 0, sizeof(*out)); - LOGP(DSUA, LOGL_DEBUG, "%s(IEI=0x%04x) (%d) %s\n", __func__, + LOGP(DLSUA, LOGL_DEBUG, "%s(IEI=0x%04x) (%d) %s\n", __func__, param->tag, param->len, osmo_hexdump(param->dat, param->len)); if (param->len < 4) { - LOGP(DSUA, LOGL_ERROR, "SUA IEI 0x%04x: invalid address length: %d\n", + LOGP(DLSUA, LOGL_ERROR, "SUA IEI 0x%04x: invalid address length: %d\n", param->tag, param->len); return -EINVAL; } @@ -779,14 +383,14 @@ break; case SUA_RI_HOST: default: - LOGP(DSUA, LOGL_ERROR, "SUA IEI 0x%04x: Routing Indicator not supported yet: %d\n", + LOGP(DLSUA, LOGL_ERROR, "SUA IEI 0x%04x: Routing Indicator not supported yet: %d\n", param->tag, ri); return -ENOTSUP; } if (ai != 7) { #if 0 - LOGP(DSUA, LOGL_ERROR, "SUA IEI 0x%04x: Address Indicator not supported yet: %x\n", + LOGP(DLSUA, LOGL_ERROR, "SUA IEI 0x%04x: Address Indicator not supported yet: %x\n", param->tag, ai); return -ENOTSUP; #endif @@ -806,7 +410,7 @@ par_len = ntohs(par->len); par_datalen = par_len - sizeof(*par); - LOGP(DSUA, LOGL_DEBUG, "SUA IEI 0x%04x pos %hu/%hu: subpart tag 0x%04x, len %hu\n", + LOGP(DLSUA, LOGL_DEBUG, "SUA IEI 0x%04x pos %hu/%hu: subpart tag 0x%04x, len %hu\n", param->tag, pos, param->len, par_tag, par_len); switch (par_tag) { @@ -839,7 +443,7 @@ out->presence |= OSMO_SCCP_ADDR_T_IPv4; break; default: - LOGP(DSUA, LOGL_ERROR, "SUA IEI 0x%04x: Unknown subpart tag %hd\n", + LOGP(DLSUA, LOGL_ERROR, "SUA IEI 0x%04x: Unknown subpart tag %hd\n", param->tag, par_tag); goto subpar_fail; } @@ -850,7 +454,7 @@ return 0; subpar_fail: - LOGP(DSUA, LOGL_ERROR, "Failed to parse subparts of address IEI=0x%04x\n", + LOGP(DLSUA, LOGL_ERROR, "Failed to parse subparts of address IEI=0x%04x\n", param->tag); return -EINVAL; } @@ -871,809 +475,205 @@ return sua_addr_parse_part(out, param); } -static int sua_rx_cldt(struct osmo_sccp_link *link, struct xua_msg *xua) +/* connectionless messages received from socket */ +static int sua_rx_cl(struct osmo_ss7_asp *asp, struct xua_msg *xua) { - struct osmo_scu_prim *prim; - struct osmo_scu_unitdata_param *param; - struct xua_msg_part *data_ie = xua_msg_find_tag(xua, SUA_IEI_DATA); - struct msgb *upmsg = sccp_msgb_alloc(__func__); - uint32_t protocol_class; + struct osmo_sccp_instance *inst = asp->inst->sccp; - /* fill primitive */ - prim = (struct osmo_scu_prim *) msgb_put(upmsg, sizeof(*prim)); - param = &prim->u.unitdata; - osmo_prim_init(&prim->oph, SCCP_SAP_USER, - OSMO_SCU_PRIM_N_UNITDATA, - PRIM_OP_INDICATION, upmsg); - sua_addr_parse(¶m->called_addr, xua, SUA_IEI_DEST_ADDR); - sua_addr_parse(¶m->calling_addr, xua, SUA_IEI_SRC_ADDR); - param->in_sequence_control = xua_msg_get_u32(xua, SUA_IEI_SEQ_CTRL); - protocol_class = xua_msg_get_u32(xua, SUA_IEI_PROTO_CLASS); - param->return_option = protocol_class & 0x80; - param->importance = xua_msg_get_u32(xua, SUA_IEI_IMPORTANCE); - - /* copy data */ - upmsg->l2h = msgb_put(upmsg, data_ie->len); - memcpy(upmsg->l2h, data_ie->dat, data_ie->len); - - /* send to user SAP */ - link->user->prim_cb(&prim->oph, link); - - return 0; + /* We feed into SCRC, which then hands the message into + * either SCLC or SCOC, or forwards it to MTP */ + return scrc_rx_mtp_xfer_ind_xua(inst, xua); } - - -/* connectioness messages received from socket */ -static int sua_rx_cl(struct osmo_sccp_link *link, - struct xua_msg *xua, struct msgb *msg) -{ - int rc = -1; - - switch (xua->hdr.msg_type) { - case SUA_CL_CLDT: - rc = sua_rx_cldt(link, xua); - break; - case SUA_CL_CLDR: - default: - break; - } - - return rc; -} - -/* RFC 3868 3.3.3 / SCCP CR (Connection Request) */ -static int sua_rx_core(struct osmo_sccp_link *link, struct xua_msg *xua) -{ - struct osmo_scu_prim *prim; - struct osmo_scu_connect_param *param; - struct xua_msg_part *data_ie = xua_msg_find_tag(xua, SUA_IEI_DATA); - struct msgb *upmsg; - struct sua_connection *conn; - - /* fill conn */ - conn = conn_create(link); - sua_addr_parse(&conn->called_addr, xua, SUA_IEI_DEST_ADDR); - sua_addr_parse(&conn->calling_addr, xua, SUA_IEI_SRC_ADDR); - conn->remote_ref = xua_msg_get_u32(xua, SUA_IEI_SRC_REF); - - /* fill primitive */ - upmsg = sccp_msgb_alloc(__func__); - prim = (struct osmo_scu_prim *) msgb_put(upmsg, sizeof(*prim)); - param = &prim->u.connect; - osmo_prim_init(&prim->oph, SCCP_SAP_USER, - OSMO_SCU_PRIM_N_CONNECT, - PRIM_OP_INDICATION, upmsg); - param->conn_id = conn->conn_id; - memcpy(¶m->called_addr, &conn->called_addr, - sizeof(param->called_addr)); - memcpy(¶m->calling_addr, &conn->calling_addr, - sizeof(param->calling_addr)); - //param->in_sequence_control; - param->sccp_class = xua_msg_get_u32(xua, SUA_IEI_PROTO_CLASS) & 3; - param->importance = xua_msg_get_u32(xua, SUA_IEI_IMPORTANCE); - - if (data_ie) { - /* copy data */ - upmsg->l2h = msgb_put(upmsg, data_ie->len); - memcpy(upmsg->l2h, data_ie->dat, data_ie->len); - } - - conn_state_set(conn, S_CONN_PEND_IN); - - /* send to user SAP */ - link->user->prim_cb(&prim->oph, link); - - return 0; -} - -/* RFC 3868 3.3.4 / SCCP CC (Connection Confirm) */ -static int sua_rx_coak(struct osmo_sccp_link *link, struct xua_msg *xua) -{ - struct osmo_scu_prim *prim; - struct sua_connection *conn; - struct osmo_scu_connect_param *param; - struct xua_msg_part *data_ie = xua_msg_find_tag(xua, SUA_IEI_DATA); - struct msgb *upmsg; - uint32_t conn_id = xua_msg_get_u32(xua, SUA_IEI_DEST_REF); - - /* resolve conn */ - conn = conn_find_by_id(link, conn_id); - if (!conn) { - LOGP(DSUA, LOGL_ERROR, "COAK for unknown reference %u\n", - conn_id); - /* FIXME: send error reply down the sua link? */ - return -1; - } - conn_restart_rx_inact_timer(conn); - - if (conn->state != S_CONN_PEND_OUT) { - LOGP(DSUA, LOGL_ERROR, "COAK in wrong state %s\n", - get_value_string(conn_state_names, conn->state)); - /* FIXME: send error reply down the sua link? */ - return -EINVAL; - } - - /* track remote reference */ - conn->remote_ref = xua_msg_get_u32(xua, SUA_IEI_SRC_REF); - - /* fill primitive */ - upmsg = sccp_msgb_alloc(__func__); - prim = (struct osmo_scu_prim *) msgb_put(upmsg, sizeof(*prim)); - param = &prim->u.connect; - osmo_prim_init(&prim->oph, SCCP_SAP_USER, - OSMO_SCU_PRIM_N_CONNECT, - PRIM_OP_CONFIRM, upmsg); - param->conn_id = conn->conn_id; - memcpy(¶m->called_addr, &conn->called_addr, - sizeof(param->called_addr)); - memcpy(¶m->calling_addr, &conn->calling_addr, - sizeof(param->calling_addr)); - //param->in_sequence_control; - param->sccp_class = xua_msg_get_u32(xua, SUA_IEI_PROTO_CLASS) & 3; - param->importance = xua_msg_get_u32(xua, SUA_IEI_IMPORTANCE); - - if (data_ie) { - /* copy data */ - upmsg->l2h = msgb_put(upmsg, data_ie->len); - memcpy(upmsg->l2h, data_ie->dat, data_ie->len); - } - - conn_state_set(conn, S_ACTIVE); - conn_start_inact_timers(conn); - - /* send to user SAP */ - link->user->prim_cb(&prim->oph, link); - - return 0; -} - -/* RFC 3868 3.3.5 / SCCP CREF (Connection Refused) */ -static int sua_rx_coref(struct osmo_sccp_link *link, struct xua_msg *xua) -{ - struct osmo_scu_prim *prim; - struct sua_connection *conn; - struct osmo_scu_disconn_param *param; - struct xua_msg_part *data_ie = xua_msg_find_tag(xua, SUA_IEI_DATA); - struct msgb *upmsg; - uint32_t conn_id = xua_msg_get_u32(xua, SUA_IEI_DEST_REF); - uint32_t cause; - - /* resolve conn */ - conn = conn_find_by_id(link, conn_id); - if (!conn) { - LOGP(DSUA, LOGL_ERROR, "COREF for unknown reference %u\n", - conn_id); - /* FIXME: send error reply down the sua link? */ - return -1; - } - conn_restart_rx_inact_timer(conn); - - /* fill primitive */ - upmsg = sccp_msgb_alloc(__func__); - prim = (struct osmo_scu_prim *) msgb_put(upmsg, sizeof(*prim)); - param = &prim->u.disconnect; - osmo_prim_init(&prim->oph, SCCP_SAP_USER, - OSMO_SCU_PRIM_N_DISCONNECT, - PRIM_OP_INDICATION, upmsg); - param->conn_id = conn_id; - param->responding_addr = conn->called_addr; - param->originator = OSMO_SCCP_ORIG_UNDEFINED; - //param->in_sequence_control; - /* TODO evaluate cause: - * cause = xua_msg_get_u32(xua, SUA_IEI_CAUSE); */ - /* optional: src addr */ - /* optional: dest addr */ - param->importance = xua_msg_get_u32(xua, SUA_IEI_IMPORTANCE); - if (data_ie) { - /* copy data */ - upmsg->l2h = msgb_put(upmsg, data_ie->len); - memcpy(upmsg->l2h, data_ie->dat, data_ie->len); - } - - /* send to user SAP */ - link->user->prim_cb(&prim->oph, link); - - conn_state_set(conn, S_IDLE); - conn_destroy(conn); - - return 0; -} - -/* RFC 3868 3.3.6 / SCCP RLSD (Released) */ -static int sua_rx_relre(struct osmo_sccp_link *link, struct xua_msg *xua) -{ - struct osmo_scu_prim *prim; - struct sua_connection *conn; - struct osmo_scu_disconn_param *param; - struct xua_msg_part *data_ie = xua_msg_find_tag(xua, SUA_IEI_DATA); - struct msgb *upmsg; - uint32_t conn_id = xua_msg_get_u32(xua, SUA_IEI_DEST_REF); - uint32_t cause; - - /* resolve conn */ - conn = conn_find_by_id(link, conn_id); - if (!conn) { - LOGP(DSUA, LOGL_ERROR, "RELRE for unknown reference %u\n", - conn_id); - /* FIXME: send error reply down the sua link? */ - return -1; - } - - /* fill primitive */ - upmsg = sccp_msgb_alloc(__func__); - prim = (struct osmo_scu_prim *) msgb_put(upmsg, sizeof(*prim)); - param = &prim->u.disconnect; - osmo_prim_init(&prim->oph, SCCP_SAP_USER, - OSMO_SCU_PRIM_N_DISCONNECT, - PRIM_OP_INDICATION, upmsg); /* what primitive? */ - - param->conn_id = conn_id; - /* source reference */ - cause = xua_msg_get_u32(xua, SUA_IEI_CAUSE); - param->importance = xua_msg_get_u32(xua, SUA_IEI_IMPORTANCE); - if (data_ie) { - /* copy data */ - upmsg->l2h = msgb_put(upmsg, data_ie->len); - memcpy(upmsg->l2h, data_ie->dat, data_ie->len); - } - - param->responding_addr = conn->called_addr; - param->originator = OSMO_SCCP_ORIG_UNDEFINED; - - /* send to user SAP */ - link->user->prim_cb(&prim->oph, link); - - conn_state_set(conn, S_IDLE); - conn_destroy(conn); - - return 0; -} - -/* RFC 3868 3.3.7 / SCCP RLC (Release Complete)*/ -static int sua_rx_relco(struct osmo_sccp_link *link, struct xua_msg *xua) -{ - struct osmo_scu_prim *prim; - struct sua_connection *conn; - struct osmo_scu_disconn_param *param; - struct msgb *upmsg; - uint32_t conn_id = xua_msg_get_u32(xua, SUA_IEI_DEST_REF); - - /* resolve conn */ - conn = conn_find_by_id(link, conn_id); - if (!conn) { - LOGP(DSUA, LOGL_ERROR, "RELCO for unknown reference %u\n", - conn_id); - /* FIXME: send error reply down the sua link? */ - return -1; - } - conn_restart_rx_inact_timer(conn); - - /* fill primitive */ - upmsg = sccp_msgb_alloc(__func__); - prim = (struct osmo_scu_prim *) msgb_put(upmsg, sizeof(*prim)); - param = &prim->u.disconnect; - osmo_prim_init(&prim->oph, SCCP_SAP_USER, - OSMO_SCU_PRIM_N_DISCONNECT, - PRIM_OP_CONFIRM, upmsg); /* what primitive? */ - - param->conn_id = conn_id; - /* source reference */ - param->importance = xua_msg_get_u32(xua, SUA_IEI_IMPORTANCE); - - param->responding_addr = conn->called_addr; - param->originator = OSMO_SCCP_ORIG_UNDEFINED; - - /* send to user SAP */ - link->user->prim_cb(&prim->oph, link); - - conn_destroy(conn); - - return 0; - -} - -/* RFC3868 3.3.1 / SCCP DT1 (Data Form 1) */ -static int sua_rx_codt(struct osmo_sccp_link *link, struct xua_msg *xua) -{ - struct osmo_scu_prim *prim; - struct sua_connection *conn; - struct osmo_scu_data_param *param; - struct xua_msg_part *data_ie = xua_msg_find_tag(xua, SUA_IEI_DATA); - struct msgb *upmsg; - uint32_t conn_id = xua_msg_get_u32(xua, SUA_IEI_DEST_REF); - - /* resolve conn */ - conn = conn_find_by_id(link, conn_id); - if (!conn) { - LOGP(DSUA, LOGL_ERROR, "DT1 for unknown reference %u\n", - conn_id); - /* FIXME: send error reply down the sua link? */ - return -1; - } - - if (conn->state != S_ACTIVE) { - LOGP(DSUA, LOGL_ERROR, "DT1 in invalid state %s\n", - get_value_string(conn_state_names, conn->state)); - /* FIXME: send error reply down the sua link? */ - return -1; - } - - conn_restart_rx_inact_timer(conn); - - /* fill primitive */ - upmsg = sccp_msgb_alloc(__func__); - prim = (struct osmo_scu_prim *) msgb_put(upmsg, sizeof(*prim)); - param = &prim->u.data; - osmo_prim_init(&prim->oph, SCCP_SAP_USER, - OSMO_SCU_PRIM_N_DATA, - PRIM_OP_INDICATION, upmsg); - param->conn_id = conn_id; - param->importance = xua_msg_get_u32(xua, SUA_IEI_IMPORTANCE); - - /* copy data */ - upmsg->l2h = msgb_put(upmsg, data_ie->len); - memcpy(upmsg->l2h, data_ie->dat, data_ie->len); - - /* send to user SAP */ - link->user->prim_cb(&prim->oph, link); - - return 0; -} - /* connection-oriented messages received from socket */ -static int sua_rx_co(struct osmo_sccp_link *link, - struct xua_msg *xua, struct msgb *msg) +static int sua_rx_co(struct osmo_ss7_asp *asp, struct xua_msg *xua) { - int rc = -1; + struct osmo_sccp_instance *inst = asp->inst->sccp; - switch (xua->hdr.msg_type) { - case SUA_CO_CORE: - rc = sua_rx_core(link, xua); - break; - case SUA_CO_COAK: - rc = sua_rx_coak(link, xua); - break; - case SUA_CO_COREF: - rc = sua_rx_coref(link, xua); - break; - case SUA_CO_RELRE: - rc = sua_rx_relre(link, xua); - break; - case SUA_CO_RELCO: - rc = sua_rx_relco(link, xua); - break; - case SUA_CO_CODT: - rc = sua_rx_codt(link, xua); - break; - case SUA_CO_RESCO: - case SUA_CO_RESRE: - case SUA_CO_CODA: - case SUA_CO_COERR: - case SUA_CO_COIT: - /* FIXME */ - default: - break; - } - - return rc; + /* We feed into SCRC, which then hands the message into + * either SCLC or SCOC, or forwards it to MTP */ + return scrc_rx_mtp_xfer_ind_xua(inst, xua); } -/* process SUA message received from socket */ -static int sua_rx_msg(struct osmo_sccp_link *link, struct msgb *msg) +static int sua_rx_mgmt_err(struct osmo_ss7_asp *asp, struct xua_msg *xua) { - struct xua_msg *xua; - int rc = -1; + uint32_t err_code = xua_msg_get_u32(xua, SUA_IEI_ERR_CODE); - xua = xua_from_msg(1, msgb_length(msg), msg->data); - if (!xua) { - LOGP(DSUA, LOGL_ERROR, "Unable to parse incoming " - "SUA message\n"); + LOGPASP(asp, DLSUA, LOGL_ERROR, "Received MGMT_ERR '%s': %s\n", + get_value_string(m3ua_err_names, err_code), + xua_msg_dump(xua, &xua_dialect_sua)); + + /* NEVER return != 0 here, as we cannot respont to an ERR + * message with another ERR! */ + return 0; +} + +static int sua_rx_mgmt_ntfy(struct osmo_ss7_asp *asp, struct xua_msg *xua) +{ + struct m3ua_notify_params ntfy; + const char *type_name, *info_name; + + m3ua_decode_notify(&ntfy, asp, xua); + + type_name = get_value_string(m3ua_ntfy_type_names, ntfy.status_type); + + switch (ntfy.status_type) { + case M3UA_NOTIFY_T_STATCHG: + info_name = get_value_string(m3ua_ntfy_stchg_names, + ntfy.status_info); + break; + case M3UA_NOTIFY_T_OTHER: + info_name = get_value_string(m3ua_ntfy_other_names, + ntfy.status_info); + break; + default: + info_name = "NULL"; + break; + } + LOGPASP(asp, DLSUA, LOGL_NOTICE, "Received NOTIFY Type %s:%s (%s)\n", + type_name, info_name, + ntfy.info_string ? ntfy.info_string : ""); + + if (ntfy.info_string) + talloc_free(ntfy.info_string); + + /* TODO: should we report this soemwhere? */ + return 0; +} + +static int sua_rx_mgmt(struct osmo_ss7_asp *asp, struct xua_msg *xua) +{ + switch (xua->hdr.msg_type) { + case SUA_MGMT_ERR: + return sua_rx_mgmt_err(asp, xua); + case SUA_MGMT_NTFY: + return sua_rx_mgmt_ntfy(asp, xua); + default: + return SUA_ERR_UNSUPP_MSG_TYPE; + } +} + +/* map from SUA ASPSM/ASPTM to xua_asp_fsm event */ +static const struct xua_msg_event_map sua_aspxm_map[] = { + { SUA_MSGC_ASPSM, SUA_ASPSM_UP, XUA_ASP_E_ASPSM_ASPUP }, + { SUA_MSGC_ASPSM, SUA_ASPSM_DOWN, XUA_ASP_E_ASPSM_ASPDN }, + { SUA_MSGC_ASPSM, SUA_ASPSM_BEAT, XUA_ASP_E_ASPSM_BEAT }, + { SUA_MSGC_ASPSM, SUA_ASPSM_UP_ACK, XUA_ASP_E_ASPSM_ASPUP_ACK }, + { SUA_MSGC_ASPSM, SUA_ASPSM_DOWN_ACK, XUA_ASP_E_ASPSM_ASPDN_ACK }, + { SUA_MSGC_ASPSM, SUA_ASPSM_BEAT_ACK, XUA_ASP_E_ASPSM_BEAT_ACK }, + { SUA_MSGC_ASPTM, SUA_ASPTM_ACTIVE, XUA_ASP_E_ASPTM_ASPAC }, + { SUA_MSGC_ASPTM, SUA_ASPTM_INACTIVE, XUA_ASP_E_ASPTM_ASPIA }, + { SUA_MSGC_ASPTM, SUA_ASPTM_ACTIVE_ACK, XUA_ASP_E_ASPTM_ASPAC_ACK }, + { SUA_MSGC_ASPTM, SUA_ASPTM_INACTIVE_ACK, XUA_ASP_E_ASPTM_ASPIA_ACK }, +}; + +static int sua_rx_asp(struct osmo_ss7_asp *asp, struct xua_msg *xua) +{ + int event; + + /* map from the SUA message class and message type to the XUA + * ASP FSM event number */ + event = xua_msg_event_map(xua, sua_aspxm_map, + ARRAY_SIZE(sua_aspxm_map)); + if (event < 0) + return SUA_ERR_UNSUPP_MSG_TYPE; + + /* deliver that event to the ASP FSM */ + osmo_fsm_inst_dispatch(asp->fi, event, xua); + + return 0; +} + +/*! \brief process SUA message received from socket + * \param[in] asp Application Server Process receiving \ref msg + * \param[in] msg received message buffer + * \returns 0 on success; negative on error */ +int sua_rx_msg(struct osmo_ss7_asp *asp, struct msgb *msg) +{ + struct xua_msg *xua = NULL, *err = NULL; + int rc = 0; + + OSMO_ASSERT(asp->cfg.proto == OSMO_SS7_ASP_PROT_SUA); + + /* caller owns msg memory, we shall neither free it here nor + * keep references beyon the execution of this function and its + * callees. */ + + if (!asp->inst->sccp) { + LOGP(DLSUA, LOGL_ERROR, "%s(asp->inst->sccp=NULL)\n", __func__); return -EIO; } - LOGP(DSUA, LOGL_DEBUG, "Received SUA Message (%s)\n", + xua = xua_from_msg(1, msgb_length(msg), msg->data); + if (!xua) { + struct xua_common_hdr *hdr = (struct xua_common_hdr *) msg->data; + + LOGPASP(asp, DLSUA, LOGL_ERROR, "Unable to parse incoming " + "SUA message\n"); + + if (hdr->version != SUA_VERSION) + err = sua_gen_error_msg(SUA_ERR_INVALID_VERSION, msg); + else + err = sua_gen_error_msg(SUA_ERR_PARAM_FIELD_ERR, msg); + goto out; + } + +#if 0 + xua->mtp.opc = ; + xua->mtp.dpc = ; +#endif + xua->mtp.sio = MTP_SI_SCCP; + + LOGPASP(asp, DLSUA, LOGL_DEBUG, "Received SUA Message (%s)\n", xua_hdr_dump(xua, &xua_dialect_sua)); - if (!xua_dialect_check_all_mand_ies(&xua_dialect_sua, xua)) - return -1; + if (!xua_dialect_check_all_mand_ies(&xua_dialect_sua, xua)) { + /* FIXME: Return error? */ + err = sua_gen_error_msg(SUA_ERR_MISSING_PARAM, msg); + goto out; + } + + /* TODO: check for SCTP Strema ID */ + /* TODO: check if any AS configured in ASP */ + /* TODO: check for valid routing context */ switch (xua->hdr.msg_class) { case SUA_MSGC_CL: - rc = sua_rx_cl(link, xua, msg); + rc = sua_rx_cl(asp, xua); break; case SUA_MSGC_CO: - rc = sua_rx_co(link, xua, msg); + rc = sua_rx_co(asp, xua); break; - case SUA_MSGC_MGMT: - case SUA_MSGC_SNM: case SUA_MSGC_ASPSM: case SUA_MSGC_ASPTM: + rc = sua_rx_asp(asp, xua); + break; + case SUA_MSGC_MGMT: + rc = sua_rx_mgmt(asp, xua); + break; + case SUA_MSGC_SNM: case SUA_MSGC_RKM: /* FIXME */ + LOGPASP(asp, DLSUA, LOGL_NOTICE, "Received unsupported SUA " + "Message Class %u\n", xua->hdr.msg_class); + err = sua_gen_error_msg(SUA_ERR_UNSUPP_MSG_CLASS, msg); + break; default: + LOGPASP(asp, DLSUA, LOGL_NOTICE, "Received unknown SUA " + "Message Class %u\n", xua->hdr.msg_class); + err = sua_gen_error_msg(SUA_ERR_UNSUPP_MSG_CLASS, msg); break; } + + if (rc > 0) + err = sua_gen_error_msg(rc, msg); + +out: + if (err) + sua_tx_xua_asp(asp, err); xua_msg_free(xua); return rc; } -/*********************************************************************** - * libosmonetif integration - ***********************************************************************/ - -#include -#include - -static const struct value_string sctp_assoc_chg_vals[] = { - { SCTP_COMM_UP, "COMM_UP" }, - { SCTP_COMM_LOST, "COMM_LOST" }, - { SCTP_RESTART, "RESTART" }, - { SCTP_SHUTDOWN_COMP, "SHUTDOWN_COMP" }, - { SCTP_CANT_STR_ASSOC, "CANT_STR_ASSOC" }, - { 0, NULL } -}; - -static const struct value_string sctp_sn_type_vals[] = { - { SCTP_ASSOC_CHANGE, "ASSOC_CHANGE" }, - { SCTP_PEER_ADDR_CHANGE, "PEER_ADDR_CHANGE" }, - { SCTP_SHUTDOWN_EVENT, "SHUTDOWN_EVENT" }, - { SCTP_SEND_FAILED, "SEND_FAILED" }, - { SCTP_REMOTE_ERROR, "REMOTE_ERROR" }, - { SCTP_PARTIAL_DELIVERY_EVENT, "PARTIAL_DELIVERY_EVENT" }, - { SCTP_ADAPTATION_INDICATION, "ADAPTATION_INDICATION" }, -#ifdef SCTP_AUTHENTICATION_INDICATION - { SCTP_AUTHENTICATION_INDICATION, "UTHENTICATION_INDICATION" }, -#endif -#ifdef SCTP_SENDER_DRY_EVENT - { SCTP_SENDER_DRY_EVENT, "SENDER_DRY_EVENT" }, -#endif - { 0, NULL } -}; - -static int get_logevel_by_sn_type(int sn_type) -{ - switch (sn_type) { - case SCTP_ADAPTATION_INDICATION: - case SCTP_PEER_ADDR_CHANGE: -#ifdef SCTP_AUTHENTICATION_INDICATION - case SCTP_AUTHENTICATION_INDICATION: -#endif -#ifdef SCTP_SENDER_DRY_EVENT - case SCTP_SENDER_DRY_EVENT: -#endif - return LOGL_INFO; - case SCTP_ASSOC_CHANGE: - return LOGL_NOTICE; - case SCTP_SHUTDOWN_EVENT: - case SCTP_PARTIAL_DELIVERY_EVENT: - return LOGL_NOTICE; - case SCTP_SEND_FAILED: - case SCTP_REMOTE_ERROR: - return LOGL_ERROR; - default: - return LOGL_NOTICE; - } -} - -static void log_sctp_notification(int fd, const char *pfx, - union sctp_notification *notif) -{ - int log_level; - char *conn_id = osmo_sock_get_name(NULL, fd); - - LOGP(DSUA, LOGL_INFO, "%s %s SCTP NOTIFICATION %u flags=0x%0x\n", - conn_id, pfx, notif->sn_header.sn_type, - notif->sn_header.sn_flags); - - log_level = get_logevel_by_sn_type(notif->sn_header.sn_type); - - switch (notif->sn_header.sn_type) { - case SCTP_ASSOC_CHANGE: - LOGP(DSUA, log_level, "%s %s SCTP_ASSOC_CHANGE: %s\n", - conn_id, pfx, get_value_string(sctp_assoc_chg_vals, - notif->sn_assoc_change.sac_state)); - break; - default: - LOGP(DSUA, log_level, "%s %s %s\n", - conn_id, pfx, get_value_string(sctp_sn_type_vals, - notif->sn_header.sn_type)); - break; - } - - talloc_free(conn_id); -} - -/* netif code tells us we can read something from the socket */ -static int sua_srv_conn_cb(struct osmo_stream_srv *conn) -{ - struct osmo_fd *ofd = osmo_stream_srv_get_ofd(conn); - struct osmo_sccp_link *link = osmo_stream_srv_get_data(conn); - struct msgb *msg = msgb_alloc(SUA_MSGB_SIZE, "SUA Server Rx"); - struct sctp_sndrcvinfo sinfo; - unsigned int ppid; - int flags = 0; - int rc; - - if (!msg) - return -ENOMEM; - - /* read SUA message from socket and process it */ - rc = sctp_recvmsg(ofd->fd, msgb_data(msg), msgb_tailroom(msg), - NULL, NULL, &sinfo, &flags); - LOGP(DSUA, LOGL_DEBUG, "sua_srv_conn_cb(): sctp_recvmsg() returned %d\n", - rc); - if (rc < 0) { - close(ofd->fd); - osmo_fd_unregister(ofd); - ofd->fd = -1; - return rc; - } else if (rc == 0) { - close(ofd->fd); - osmo_fd_unregister(ofd); - ofd->fd = -1; - } else { - msgb_put(msg, rc); - } - - if (flags & MSG_NOTIFICATION) { - union sctp_notification *notif = (union sctp_notification *) msgb_data(msg); - - log_sctp_notification(ofd->fd, "SUA SRV", notif); - - switch (notif->sn_header.sn_type) { - case SCTP_SHUTDOWN_EVENT: - close(ofd->fd); - osmo_fd_unregister(ofd); - ofd->fd = -1; - break; - default: - break; - } - msgb_free(msg); - return 0; - } - - ppid = ntohl(sinfo.sinfo_ppid); - msgb_sctp_ppid(msg) = ppid; - msgb_sctp_stream(msg) = ntohl(sinfo.sinfo_stream); - msg->dst = link; - - switch (ppid) { - case SUA_PPID: - rc = sua_rx_msg(link, msg); - break; - default: - LOGP(DSUA, LOGL_NOTICE, "SCTP chunk for unknown PPID %u " - "received\n", ppid); - rc = 0; - break; - } - - msgb_free(msg); - return rc; -} - -static int sua_srv_conn_closed_cb(struct osmo_stream_srv *srv) -{ - struct osmo_sccp_link *sual = osmo_stream_srv_get_data(srv); - struct sua_connection *conn; - - LOGP(DSUA, LOGL_INFO, "SCTP connection closed\n"); - - /* remove from per-user list of sua links */ - llist_del(&sual->list); - - llist_for_each_entry(conn, &sual->connections, list) { - /* FIXME: send RELEASE request */ - } - talloc_free(sual); - osmo_stream_srv_set_data(srv, NULL); - - return 0; -} - -static int sua_accept_cb(struct osmo_stream_srv_link *link, int fd) -{ - struct osmo_sccp_user *user = osmo_stream_srv_link_get_data(link); - struct osmo_stream_srv *srv; - struct osmo_sccp_link *sual; - - LOGP(DSUA, LOGL_INFO, "New SCTP connection accepted\n"); - - srv = osmo_stream_srv_create(user, link, fd, - sua_srv_conn_cb, - sua_srv_conn_closed_cb, NULL); - if (!srv) { - close(fd); - return -1; - } - - /* create new SUA link and connect both data structures */ - sual = sua_link_new(user, 1); - if (!sual) { - osmo_stream_srv_destroy(srv); - return -1; - } - sual->data = srv; - osmo_stream_srv_set_data(srv, sual); - - return 0; -} - -int osmo_sua_server_listen(struct osmo_sccp_user *user, const char *hostname, uint16_t port) -{ - int rc; - - if (user->server) - osmo_stream_srv_link_close(user->server); - else { - user->server = osmo_stream_srv_link_create(user); - osmo_stream_srv_link_set_data(user->server, user); - osmo_stream_srv_link_set_accept_cb(user->server, sua_accept_cb); - } - - osmo_stream_srv_link_set_addr(user->server, hostname); - osmo_stream_srv_link_set_port(user->server, port); - osmo_stream_srv_link_set_proto(user->server, IPPROTO_SCTP); - - rc = osmo_stream_srv_link_open(user->server); - if (rc < 0) { - osmo_stream_srv_link_destroy(user->server); - user->server = NULL; - return rc; - } - - return 0; -} - -/* netif code tells us we can read something from the socket */ -static int sua_cli_read_cb(struct osmo_stream_cli *conn) -{ - struct osmo_fd *ofd = osmo_stream_cli_get_ofd(conn); - struct osmo_sccp_link *link = osmo_stream_cli_get_data(conn); - struct msgb *msg = msgb_alloc(SUA_MSGB_SIZE, "SUA Client Rx"); - struct sctp_sndrcvinfo sinfo; - unsigned int ppid; - int flags = 0; - int rc; - - LOGP(DSUA, LOGL_DEBUG, "sua_cli_read_cb() rx\n"); - - if (!msg) - return -ENOMEM; - - /* read SUA message from socket and process it */ - rc = sctp_recvmsg(ofd->fd, msgb_data(msg), msgb_tailroom(msg), - NULL, NULL, &sinfo, &flags); - if (rc < 0) { - close(ofd->fd); - osmo_fd_unregister(ofd); - ofd->fd = -1; - return rc; - } else if (rc == 0) { - close(ofd->fd); - osmo_fd_unregister(ofd); - ofd->fd = -1; - } else { - msgb_put(msg, rc); - } - - if (flags & MSG_NOTIFICATION) { - union sctp_notification *notif = (union sctp_notification *) msgb_data(msg); - - log_sctp_notification(ofd->fd, "SUA CLNT", notif); - - switch (notif->sn_header.sn_type) { - case SCTP_SHUTDOWN_EVENT: - close(ofd->fd); - osmo_fd_unregister(ofd); - ofd->fd = -1; - break; - default: - break; - } - msgb_free(msg); - return 0; - } - - ppid = ntohl(sinfo.sinfo_ppid); - msgb_sctp_ppid(msg) = ppid; - msgb_sctp_stream(msg) = ntohl(sinfo.sinfo_stream); - msg->dst = link; - - switch (ppid) { - case SUA_PPID: - rc = sua_rx_msg(link, msg); - break; - default: - LOGP(DSUA, LOGL_NOTICE, "SCTP chunk for unknown PPID %u " - "received\n", ppid); - rc = 0; - break; - } - - msgb_free(msg); - return rc; -} - -int osmo_sua_client_connect(struct osmo_sccp_user *user, const char *hostname, uint16_t port) -{ - struct osmo_stream_cli *cli; - struct osmo_sccp_link *sual; - int rc; - - cli = osmo_stream_cli_create(user); - if (!cli) - return -1; - osmo_stream_cli_set_addr(cli, hostname); - osmo_stream_cli_set_port(cli, port); - osmo_stream_cli_set_proto(cli, IPPROTO_SCTP); - osmo_stream_cli_set_reconnect_timeout(cli, 5); - osmo_stream_cli_set_read_cb(cli, sua_cli_read_cb); - - /* create SUA link and associate it with stream_cli */ - sual = sua_link_new(user, 0); - if (!sual) { - osmo_stream_cli_destroy(cli); - return -1; - } - sual->data = cli; - osmo_stream_cli_set_data(cli, sual); - - rc = osmo_stream_cli_open2(cli, 1); - if (rc < 0) { - sua_link_destroy(sual); - osmo_stream_cli_destroy(cli); - return rc; - } - user->client = cli; - - return 0; -} - -struct osmo_sccp_link *osmo_sua_client_get_link(struct osmo_sccp_user *user) -{ - return osmo_stream_cli_get_data(user->client); -} - -static LLIST_HEAD(sua_users); - -struct osmo_sccp_user *osmo_sua_user_create(void *ctx, osmo_prim_cb prim_cb, - void *priv) -{ - struct osmo_sccp_user *user = talloc_zero(ctx, struct osmo_sccp_user); - - user->prim_cb = prim_cb; - user->priv = priv; - INIT_LLIST_HEAD(&user->links); - - llist_add_tail(&user->list, &sua_users); - - return user; -} - -void *osmo_sccp_link_get_user_priv(struct osmo_sccp_link *slink) -{ - return slink->user->priv; -} - -void osmo_sua_user_destroy(struct osmo_sccp_user *user) -{ - struct osmo_sccp_link *link; - - llist_del(&user->list); - - llist_for_each_entry(link, &user->links, list) - sua_link_destroy(link); - - talloc_free(user); -} - -void osmo_sua_set_log_area(int area) -{ - xua_set_log_area(area); - DSUA = area; -} diff --git a/src/xua_internal.h b/src/xua_internal.h index 66b5a26..c6f79b7 100644 --- a/src/xua_internal.h +++ b/src/xua_internal.h @@ -15,6 +15,8 @@ struct xua_msg *osmo_sccp_to_xua(struct msgb *msg); struct msgb *osmo_sua_to_sccp(struct xua_msg *xua); +int sua_rx_msg(struct osmo_ss7_asp *asp, struct msgb *msg); + int sua_tx_xua_as(struct osmo_ss7_as *as, struct xua_msg *xua); struct osmo_mtp_prim *m3ua_to_xfer_ind(struct xua_msg *xua); -- To view, visit https://gerrit.osmocom.org/2218 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I193b74f58aa70c443ae17e78b5604246d6bc3f71 Gerrit-PatchSet: 2 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Apr 4 11:43:10 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 4 Apr 2017 11:43:10 +0000 Subject: [PATCH] libosmo-sccp[master]: Add example program how to use M3UA+SCCP client and server In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2219 to look at the new patch set (#2). Add example program how to use M3UA+SCCP client and server This is an example tool that can be run either as server (SG) or as client (ASP) with a SCCP+M3UA stacking, and communicate via connectionless and connection-oriented primitives over it Change-Id: Id698ce2da5726e304dfa1773b794671dc80d853c --- M .gitignore M Makefile.am M configure.ac A examples/Makefile.am A examples/internal.h A examples/m3ua_example.c A examples/sccp_test_server.c A examples/sccp_test_vty.c 8 files changed, 392 insertions(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/19/2219/2 diff --git a/.gitignore b/.gitignore index 9d1435f..83f1333 100644 --- a/.gitignore +++ b/.gitignore @@ -60,6 +60,7 @@ tests/testsuite tests/testsuite.log +examples/m3ua_example *.pc config.* diff --git a/Makefile.am b/Makefile.am index b1eff56..dd73ec2 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,7 +1,7 @@ AUTOMAKE_OPTIONS = foreign dist-bzip2 1.6 AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -SUBDIRS = include src tests +SUBDIRS = include src tests examples pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = libosmo-sccp.pc libosmo-mtp.pc libosmo-sigtran.pc libosmo-xua.pc diff --git a/configure.ac b/configure.ac index 3644d22..6dc0ebd 100644 --- a/configure.ac +++ b/configure.ac @@ -27,6 +27,7 @@ PKG_PROG_PKG_CONFIG([0.20]) PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 0.3.0) +PKG_CHECK_MODULES(LIBOSMOVTY, libosmovty >= 0.3.0) PKG_CHECK_MODULES(LIBOSMONETIF, libosmo-netif >= 0.0.6) old_LIBS=$LIBS @@ -68,5 +69,6 @@ tests/m2ua/Makefile tests/xua/Makefile tests/ss7/Makefile + examples/Makefile Makefile) diff --git a/examples/Makefile.am b/examples/Makefile.am new file mode 100644 index 0000000..6418aca --- /dev/null +++ b/examples/Makefile.am @@ -0,0 +1,11 @@ +AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include +AM_CFLAGS=-Wall -g $(LIBOSMOCORE_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(LIBOSMONETIF_CFLAGS) $(COVERAGE_FLAGS) +AM_LDFLAGS=$(COVERAGE_LDFLAGS) + +noinst_HEADERS = internal.h + +noinst_PROGRAMS = m3ua_example + +m3ua_example_SOURCES = m3ua_example.c sccp_test_server.c sccp_test_vty.c +m3ua_example_LDADD = $(top_builddir)/src/libosmo-sigtran.la \ + $(LIBOSMOCORE_LIBS) $(LIBOSMOVTY_LIBS) diff --git a/examples/internal.h b/examples/internal.h new file mode 100644 index 0000000..70b9058 --- /dev/null +++ b/examples/internal.h @@ -0,0 +1,12 @@ +#pragma once + +#define SSN_TEST_UNUSED 200 +#define SSN_TEST_REFUSE 201 +#define SSN_TEST_ECHO 202 +#define SSN_TEST_CALLBACK 203 + +struct osmo_sccp_user; + +int sccp_test_user_vty_install(struct osmo_sccp_instance *inst, int ssn); + +int sccp_test_server_init(struct osmo_sccp_instance *sccp); diff --git a/examples/m3ua_example.c b/examples/m3ua_example.c new file mode 100644 index 0000000..d7b1fc2 --- /dev/null +++ b/examples/m3ua_example.c @@ -0,0 +1,98 @@ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "internal.h" + +static struct osmo_sccp_instance *sua_server_helper(void) +{ + struct osmo_sccp_instance *sccp; + + sccp = osmo_sccp_simple_server(NULL, 1, OSMO_SS7_ASP_PROT_M3UA, + -1, "127.0.0.2"); + + osmo_sccp_simple_server_add_clnt(sccp, OSMO_SS7_ASP_PROT_M3UA, + "23", 23, -1, 0, NULL); + + return sccp; +} + +/*********************************************************************** + * Initialization + ***********************************************************************/ + +static const struct log_info_cat log_info_cat[] = { +}; + +static const struct log_info log_info = { + .cat = log_info_cat, + .num_cat = ARRAY_SIZE(log_info_cat), +}; + +static void init_logging(void) +{ + const int log_cats[] = { DLSS7, DLSUA, DLM3UA, DLSCCP, DLINP }; + unsigned int i; + + osmo_init_logging(&log_info); + + for (i = 0; i < ARRAY_SIZE(log_cats); i++) + log_set_category_filter(osmo_stderr_target, log_cats[i], 1, LOGL_DEBUG); +} + +static struct vty_app_info vty_info = { + .name = "sccp-test", + .version = 0, +}; + +int main(int argc, char **argv) +{ + struct osmo_sccp_instance *sccp; + bool client; + int rc; + + init_logging(); + osmo_ss7_init(); + osmo_fsm_log_addr(false); + vty_init(&vty_info); + + if (argc <= 1) + client = true; + else + client = false; + + rc = telnet_init_dynif(NULL, NULL, vty_get_bind_addr(), 2324+client); + if (rc < 0) { + perror("Erro binding VTY port\n"); + exit(1); + } + + + if (client) { + sccp = osmo_sccp_simple_client(NULL, "client", 23, OSMO_SS7_ASP_PROT_M3UA, 0, M3UA_PORT, "127.0.0.2"); + sccp_test_user_vty_install(sccp, OSMO_SCCP_SSN_BSC_BSSAP); + } else { + sccp = sua_server_helper(); + sccp_test_server_init(sccp); + } + + while (1) { + osmo_select_main(0); + } +} diff --git a/examples/sccp_test_server.c b/examples/sccp_test_server.c new file mode 100644 index 0000000..c3c658f --- /dev/null +++ b/examples/sccp_test_server.c @@ -0,0 +1,115 @@ + +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include "internal.h" + +unsigned int conn_id; + +/* a simple SCCP User which refuses all connections and discards all + * unitdata */ +static int refuser_prim_cb(struct osmo_prim_hdr *oph, void *_scu) +{ + struct osmo_sccp_user *scu = _scu; + struct osmo_scu_prim *scu_prim = (struct osmo_scu_prim *) oph; + + switch (OSMO_PRIM_HDR(&scu_prim->oph)) { + case OSMO_PRIM(OSMO_SCU_PRIM_N_CONNECT, PRIM_OP_INDICATION): + printf("%s: refusing N-CONNECT.ind (local_ref=%u)\n", + __func__, scu_prim->u.connect.conn_id); + osmo_sccp_tx_disconn(scu, scu_prim->u.connect.conn_id, + &scu_prim->u.connect.called_addr, + 23); + break; + default: + printf("%s: Unknown primitive %u:%u\n", __func__, + oph->primitive, oph->operation); + break; + } + return 0; +} + +/* a simple SCCP User which accepts all connections and echos back all + * DATA + UNITDATA */ +static int echo_prim_cb(struct osmo_prim_hdr *oph, void *_scu) +{ + struct osmo_sccp_user *scu = _scu; + struct osmo_scu_prim *scu_prim = (struct osmo_scu_prim *) oph; + const uint8_t *data = msgb_l2(oph->msg); + unsigned int data_len = msgb_l2len(oph->msg); + + switch (OSMO_PRIM_HDR(&scu_prim->oph)) { + case OSMO_PRIM(OSMO_SCU_PRIM_N_CONNECT, PRIM_OP_INDICATION): + printf("%s: Accepting N-CONNECT.ind (local_ref=%u)\n", + __func__, scu_prim->u.connect.conn_id); + osmo_sccp_tx_conn_resp(scu, scu_prim->u.connect.conn_id, + &scu_prim->u.connect.called_addr, + data, data_len); + break; + case OSMO_PRIM(OSMO_SCU_PRIM_N_DATA, PRIM_OP_INDICATION): + printf("%s: Echoing N-DATA.ind (local_ref=%u)\n", + __func__, scu_prim->u.data.conn_id); + osmo_sccp_tx_data(scu, scu_prim->u.data.conn_id, + data, data_len); + break; + case OSMO_PRIM(OSMO_SCU_PRIM_N_UNITDATA, PRIM_OP_INDICATION): + printf("%s: Echoing N-UNITDATA.ind\n", __func__); + osmo_sccp_tx_unitdata(scu, &scu_prim->u.unitdata.called_addr, + &scu_prim->u.unitdata.calling_addr, + data, data_len); + break; + default: + printf("%s: Unknown primitive %u:%u\n", __func__, + oph->primitive, oph->operation); + break; + } + return 0; +} + +/* a simple SCCP User which receives UNITDATA messages and connects back + * to whoever sents UNITDATA and then echo's back all DATA */ +static int callback_prim_cb(struct osmo_prim_hdr *oph, void *_scu) +{ + struct osmo_sccp_user *scu = _scu; + struct osmo_scu_prim *scu_prim = (struct osmo_scu_prim *) oph; + const uint8_t *data = msgb_l2(oph->msg); + unsigned int data_len = msgb_l2len(oph->msg); + + switch (OSMO_PRIM_HDR(&scu_prim->oph)) { + case OSMO_PRIM(OSMO_SCU_PRIM_N_UNITDATA, PRIM_OP_INDICATION): + printf("%s: N-UNITDATA.ind: Connectiong back to sender\n", __func__); + osmo_sccp_tx_conn_req(scu, conn_id++, + &scu_prim->u.unitdata.called_addr, + &scu_prim->u.unitdata.calling_addr, + data, data_len); + break; + case OSMO_PRIM(OSMO_SCU_PRIM_N_DATA, PRIM_OP_INDICATION): + printf("%s: Echoing N-DATA.ind (local_ref=%u)\n", + __func__, scu_prim->u.data.conn_id); + osmo_sccp_tx_data(scu, scu_prim->u.data.conn_id, + data, data_len); + break; + default: + printf("%s: Unknown primitive %u:%u\n", __func__, + oph->primitive, oph->operation); + break; + } + return 0; +} + +int sccp_test_server_init(struct osmo_sccp_instance *sccp) +{ + osmo_sccp_user_bind(sccp, "refuser", &refuser_prim_cb, SSN_TEST_REFUSE); + osmo_sccp_user_bind(sccp, "echo", &echo_prim_cb, SSN_TEST_ECHO); + osmo_sccp_user_bind(sccp, "callback", &callback_prim_cb, SSN_TEST_CALLBACK); + + return 0; +} diff --git a/examples/sccp_test_vty.c b/examples/sccp_test_vty.c new file mode 100644 index 0000000..1134d57 --- /dev/null +++ b/examples/sccp_test_vty.c @@ -0,0 +1,152 @@ + +#include + +#include +#include + +#include +#include + +#include "internal.h" + +#define SCU_NODE 23 + +static struct osmo_sccp_user *g_scu; + +static struct osmo_sccp_addr g_calling_addr = { + .presence = OSMO_SCCP_ADDR_T_SSN | OSMO_SCCP_ADDR_T_PC, + .ri = OSMO_SCCP_RI_SSN_PC, + .pc = 23, +}; + +static struct osmo_sccp_addr g_called_addr = { + .presence = OSMO_SCCP_ADDR_T_SSN | OSMO_SCCP_ADDR_T_PC, + .ssn = 1, + .ri = OSMO_SCCP_RI_SSN_PC, + .pc = 1, +}; + +DEFUN(scu_called_ssn, scu_called_ssn_cmd, + "called-addr-ssn <0-255>", + "Set SSN of SCCP CalledAddress\n" + "SSN of SCCP CalledAddress\n") +{ + g_called_addr.ssn = atoi(argv[0]); + return CMD_SUCCESS; +} + +DEFUN(scu_conn_req, scu_conn_req_cmd, + "connect-req <0-16777216> [DATA]", + "N-CONNECT.req\n" + "Connection ID\n") +{ + struct osmo_sccp_user *scu = vty->index; + int conn_id = atoi(argv[0]); + const char *data = argv[1]; + + osmo_sccp_tx_conn_req(scu, conn_id, &g_calling_addr, &g_called_addr, + (const uint8_t *)data, data ? strlen(data)+1 : 0); + return CMD_SUCCESS; +} + +DEFUN(scu_conn_resp, scu_conn_resp_cmd, + "connect-resp <0-16777216> [DATA]", + "N-CONNET.resp\n" + "Connection ID\n") +{ + struct osmo_sccp_user *scu = vty->index; + int conn_id = atoi(argv[0]); + const char *data = argv[1]; + + osmo_sccp_tx_conn_resp(scu, conn_id, NULL, + (const uint8_t *)data, data ? strlen(data)+1 : 0); + return CMD_SUCCESS; +} + +DEFUN(scu_data_req, scu_data_req_cmd, + "data-req <0-16777216> DATA", + "N-DATA.req\n" + "Connection ID\n") +{ + struct osmo_sccp_user *scu = vty->index; + int conn_id = atoi(argv[0]); + const char *data = argv[1]; + + osmo_sccp_tx_data(scu, conn_id, (const uint8_t *)data, strlen(data)+1); + return CMD_SUCCESS; +} + +DEFUN(scu_unitdata_req, scu_unitdata_req_cmd, + "unitdata-req DATA", + "N-UNITDATA.req\n") +{ + struct osmo_sccp_user *scu = vty->index; + const char *data = argv[0]; + + osmo_sccp_tx_unitdata(scu, &g_calling_addr, &g_called_addr, + (const uint8_t *)data, strlen(data)+1); + return CMD_SUCCESS; +} + +DEFUN(scu_disc_req, scu_disc_req_cmd, + "disconnect-req <0-16777216>", + "N-DISCONNT.req\n" + "Connection ID\n") +{ + struct osmo_sccp_user *scu = vty->index; + int conn_id = atoi(argv[0]); + + osmo_sccp_tx_disconn(scu, conn_id, NULL, 42); + return CMD_SUCCESS; +} + +static struct cmd_node scu_node = { + SCU_NODE, + "%s(sccp-user)# ", + 1, +}; + +DEFUN(scu, scu_cmd, + "sccp-user", + "Enter SCCP User Node\n") +{ + vty->node = SCU_NODE; + vty->index = g_scu; + return CMD_SUCCESS; +} + +static int testclnt_prim_cb(struct osmo_prim_hdr *oph, void *_scu) +{ + struct osmo_sccp_user *scu = _scu; + struct osmo_scu_prim *scu_prim = (struct osmo_scu_prim *) oph; + + switch (OSMO_PRIM_HDR(&scu_prim->oph)) { + case OSMO_PRIM(OSMO_SCU_PRIM_N_CONNECT, PRIM_OP_INDICATION): + default: + break; + } + return 0; +} + + +int sccp_test_user_vty_install(struct osmo_sccp_instance *inst, int ssn) +{ + g_scu = osmo_sccp_user_bind(inst, "test_client_vty", testclnt_prim_cb, ssn); + if (!g_scu) + return -1; + + g_calling_addr.ssn = ssn; + + install_node(&scu_node, NULL); + vty_install_default(SCU_NODE); + install_element(SCU_NODE, &scu_called_ssn_cmd); + install_element(SCU_NODE, &scu_conn_req_cmd); + install_element(SCU_NODE, &scu_conn_resp_cmd); + install_element(SCU_NODE, &scu_data_req_cmd); + install_element(SCU_NODE, &scu_unitdata_req_cmd); + install_element(SCU_NODE, &scu_disc_req_cmd); + + install_element(ENABLE_NODE, &scu_cmd); + + return 0; +} -- To view, visit https://gerrit.osmocom.org/2219 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Id698ce2da5726e304dfa1773b794671dc80d853c Gerrit-PatchSet: 2 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Apr 4 11:46:47 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 4 Apr 2017 11:46:47 +0000 Subject: [PATCH] libosmo-sccp[master]: Add new SCCP implementation In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2215 to look at the new patch set (#3). Add new SCCP implementation This is an implementation of SCCP as specified in ITO-T Q.71x, particularly the SCRC (routing), SCLC (Connectionless) and SCOC (Connection Oriented) portions. the elaborate state machines of SCOC are implemented using osmo_fsm, with one state machine for each connection. Interfaces to the top (user application) are the SCCP-USER-SAP and on the bottom (network) side the MTP-USER-SAP as provided by osmo_ss7. Contrary to a straight-forward implementation, the code internally always uses a SUA representation of all messages (in struct xua_msg). This enables us to have one common implementation of all related state machines and use them for both SUA and SCCP. If used with real SCCP wire format, all messages are translated from SCCP to SUA on ingress and translated from SUA to SCCP on egress. As SUA is a super-set of SCCP, this can be done "lossless". Change-Id: I916e895d9a4914b05483fe12ab5251f206d10dee --- M include/osmocom/sigtran/sccp_sap.h M src/Makefile.am M src/osmo_ss7.c M src/sccp_internal.h A src/sccp_sclc.c A src/sccp_scoc.c A src/sccp_scrc.c A src/sccp_user.c 8 files changed, 2,968 insertions(+), 2 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/15/2215/3 diff --git a/include/osmocom/sigtran/sccp_sap.h b/include/osmocom/sigtran/sccp_sap.h index 0cc1531..c1464f0 100644 --- a/include/osmocom/sigtran/sccp_sap.h +++ b/include/osmocom/sigtran/sccp_sap.h @@ -222,3 +222,23 @@ #define msgb_scu_prim(msg) ((struct osmo_scu_prim *)(msg)->l1h) char *osmo_scu_prim_name(struct osmo_prim_hdr *oph); + +struct osmo_ss7_instance; +struct osmo_sccp_instance; +struct osmo_sccp_user; + +struct osmo_sccp_instance * +osmo_sccp_instance_create(struct osmo_ss7_instance *ss7, void *priv); +void osmo_sccp_instance_destroy(struct osmo_sccp_instance *inst); + +void osmo_sccp_user_unbind(struct osmo_sccp_user *scu); + +struct osmo_sccp_user * +osmo_sccp_user_bind_pc(struct osmo_sccp_instance *inst, const char *name, + osmo_prim_cb prim_cb, uint16_t ssn, uint32_t pc); + +struct osmo_sccp_user * +osmo_sccp_user_bind(struct osmo_sccp_instance *inst, const char *name, + osmo_prim_cb prim_cb, uint16_t ssn); + +int osmo_sccp_user_sap_down(struct osmo_sccp_user *scu, struct osmo_prim_hdr *oph); diff --git a/src/Makefile.am b/src/Makefile.am index 4455127..a4cfeeb 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -27,7 +27,8 @@ LIBVERSION=0:0:0 libosmo_sigtran_la_SOURCES = sccp_sap.c sua.c m3ua.c xua_msg.c sccp_helpers.c \ - sccp2sua.c \ + sccp2sua.c sccp_scrc.c sccp_sclc.c sccp_scoc.c \ + sccp_user.c \ osmo_ss7.c osmo_ss7_hmrt.c xua_asp_fsm.c xua_as_fsm.c libosmo_sigtran_la_LDFLAGS = -version-info $(LIBVERSION) -no-undefined -export-symbols-regex '^osmo_' libosmo_sigtran_la_LIBADD = $(LIBOSMOCORE_LIBS) $(LIBOSMONETIF_LIBS) $(LIBSCTP_LIBS) diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index 74c54bb..6d0b446 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -41,6 +41,7 @@ #include +#include "sccp_internal.h" #include "xua_internal.h" #include "xua_asp_fsm.h" #include "xua_as_fsm.h" @@ -1483,6 +1484,7 @@ { if (ss7_initialized) return 1; + osmo_fsm_register(&sccp_scoc_fsm); osmo_fsm_register(&xua_as_fsm); osmo_fsm_register(&xua_asp_fsm); ss7_initialized = true; diff --git a/src/sccp_internal.h b/src/sccp_internal.h index 7287a82..c35ef4b 100644 --- a/src/sccp_internal.h +++ b/src/sccp_internal.h @@ -1,5 +1,89 @@ #pragma once -#include +#include +#include +#include +#include + +/* an instance of the SCCP stack */ +struct osmo_sccp_instance { + /* entry in global list of ss7 instances */ + struct llist_head list; + /* list of 'struct sccp_connection' in this instance */ + struct llist_head connections; + /* list of SCCP users in this instance */ + struct llist_head users; + /* routing context to be used in all outbound messages */ + uint32_t route_ctx; + /* next local reference to allocate */ + uint32_t next_id; + struct osmo_ss7_instance *ss7; + void *priv; + + struct osmo_ss7_user ss7_user; +}; + +struct osmo_sccp_user { + /*! \brief entry in list of sccp users of \ref osmo_sccp_instance */ + struct llist_head list; + /*! \brief pointer back to SCCP instance */ + struct osmo_sccp_instance *inst; + /*! \brief human-readable name of this user */ + char *name; + + /*! \brief SSN and/or point code to which we are bound */ + uint16_t ssn; + uint32_t pc; + bool pc_valid; + + /* set if we are a server */ + struct llist_head links; + + /* user call-back function in case of incoming primitives */ + osmo_prim_cb prim_cb; + void *priv; + + /* Application Server FSM Instance */ + struct osmo_fsm_inst *as_fi; +}; + +extern int DSCCP; + +struct xua_msg; + +struct osmo_sccp_user * +sccp_user_find(struct osmo_sccp_instance *inst, uint16_t ssn, uint32_t pc); + +/* Message from SCOC -> SCRC */ +int sccp_scrc_rx_scoc_conn_msg(struct osmo_sccp_instance *inst, + struct xua_msg *xua); + +/* Message from SCLC -> SCRC */ +int sccp_scrc_rx_sclc_msg(struct osmo_sccp_instance *inst, struct xua_msg *xua); + +/* Message from MTP (SUA) -> SCRC */ +int scrc_rx_mtp_xfer_ind_xua(struct osmo_sccp_instance *inst, + struct xua_msg *xua); + +/* Message from SCRC -> SCOC */ +void sccp_scoc_rx_from_scrc(struct osmo_sccp_instance *inst, + struct xua_msg *xua); +void sccp_scoc_rx_scrc_rout_fail(struct osmo_sccp_instance *inst, + struct xua_msg *xua, uint32_t cause); + +void sccp_scoc_flush_connections(struct osmo_sccp_instance *inst); + +/* Message from SCRC -> SCLC */ +int sccp_sclc_rx_from_scrc(struct osmo_sccp_instance *inst, + struct xua_msg *xua); +void sccp_sclc_rx_scrc_rout_fail(struct osmo_sccp_instance *inst, + struct xua_msg *xua, uint32_t cause); + +int sccp_user_prim_up(struct osmo_sccp_user *scut, struct osmo_scu_prim *prim); + +/* SCU -> SCLC */ +int sccp_sclc_user_sap_down(struct osmo_sccp_user *scu, struct osmo_prim_hdr *oph); struct msgb *sccp_msgb_alloc(const char *name); + +struct osmo_fsm sccp_scoc_fsm; diff --git a/src/sccp_sclc.c b/src/sccp_sclc.c new file mode 100644 index 0000000..dae2c36 --- /dev/null +++ b/src/sccp_sclc.c @@ -0,0 +1,337 @@ +/* SCCP Connectionless Control (SCLC) according to ITU-T Q.713/Q.714 */ + +/* (C) 2015-2017 by Harald Welte + * All Rights reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/* This code is a bit of a hybrid between the ITU-T Q.71x specifications + * for SCCP (particularly its connection-oriented part), and the IETF + * RFC 3868 (SUA). The idea here is to have one shared code base of the + * state machines for SCCP Connection Oriented, and use those both from + * SCCP and SUA. + * + * To do so, all SCCP messages are translated to SUA messages in the + * input side, and all generated SUA messages are translated to SCCP on + * the output side. + * + * The Choice of going for SUA messages as the "native" format was based + * on their easier parseability, and the fact that there are features in + * SUA which classic SCCP cannot handle (like IP addresses in GT). + * However, all SCCP features can be expressed in SUA. + * + * The code only supports Class 2. No support for Class 3 is intended, + * but patches are of course alwys welcome. + * + * Missing other features: + * * Segmentation/Reassembly support + * * T(guard) after (re)start + * * freezing of local references + * * parsing/encoding of IPv4/IPv6 addresses + * * use of multiple Routing Contexts in SUA case + */ + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "xua_internal.h" +#include "sccp_internal.h" + +/* generate a 'struct xua_msg' of requested type from primitive data */ +static struct xua_msg *xua_gen_msg_cl(uint32_t event, + struct osmo_scu_prim *prim, int msg_type) +{ + struct xua_msg *xua = xua_msg_alloc(); + struct osmo_scu_unitdata_param *udpar = &prim->u.unitdata; + + if (!xua) + return NULL; + + switch (msg_type) { + case SUA_CL_CLDT: + xua->hdr = XUA_HDR(SUA_MSGC_CL, SUA_CL_CLDT); + xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, 0); /* FIXME */ + xua_msg_add_u32(xua, SUA_IEI_PROTO_CLASS, 0); + xua_msg_add_sccp_addr(xua, SUA_IEI_SRC_ADDR, &udpar->calling_addr); + xua_msg_add_sccp_addr(xua, SUA_IEI_DEST_ADDR, &udpar->called_addr); + xua_msg_add_u32(xua, SUA_IEI_SEQ_CTRL, udpar->in_sequence_control); + /* optional: importance, ... correlation id? */ + if (!prim) + goto prim_needed; + xua_msg_add_data(xua, SUA_IEI_DATA, msgb_l2len(prim->oph.msg), + msgb_l2(prim->oph.msg)); + break; + default: + LOGP(DLSCCP, LOGL_ERROR, "Unknown msg_type %u\n", msg_type); + xua_msg_free(xua); + return NULL; + } + return xua; + +prim_needed: + xua_msg_free(xua); + LOGP(DLSCCP, LOGL_ERROR, "%s must be called with valid 'prim' " + "pointer for msg_type=%u\n", __func__, msg_type); + return NULL; +} + +/* generate xua_msg, encode it and send it to SCRC */ +static int xua_gen_encode_and_send(struct osmo_sccp_user *scu, uint32_t event, + struct osmo_scu_prim *prim, int msg_type) +{ + struct xua_msg *xua; + + xua = xua_gen_msg_cl(event, prim, msg_type); + if (!xua) + return -1; + + return sccp_scrc_rx_sclc_msg(scu->inst, xua); +} + +/*! \brief Main entrance function for primitives from SCCP User + * \param[in] scu SCCP User who is sending the primitive + * \param[on] oph Osmocom primitive header of the primitive + * \returns 0 on success; negtive in case of error */ +int sccp_sclc_user_sap_down(struct osmo_sccp_user *scu, struct osmo_prim_hdr *oph) +{ + struct osmo_scu_prim *prim = (struct osmo_scu_prim *) oph; + struct msgb *msg = prim->oph.msg; + int rc = 0; + + /* we get called from osmo_sccp_user_sap_down() which already + * has debug-logged the primitive */ + + switch (OSMO_PRIM_HDR(&prim->oph)) { + case OSMO_PRIM(OSMO_SCU_PRIM_N_UNITDATA, PRIM_OP_REQUEST): + /* Connectionless by-passes this altogether */ + rc = xua_gen_encode_and_send(scu, -1, prim, SUA_CL_CLDT); + goto out; + default: + LOGP(DLSCCP, LOGL_ERROR, "Received unknown SCCP User " + "primitive %s from user\n", + osmo_scu_prim_name(&prim->oph)); + rc = -1; + goto out; + } + +out: + /* the SAP is supposed to consume the primitive/msgb */ + msgb_free(msg); + + return rc; +} + +/* Process an incoming CLDT message (from a remote peer) */ +static int sclc_rx_cldt(struct osmo_sccp_instance *inst, struct xua_msg *xua) +{ + struct osmo_scu_prim *prim; + struct osmo_scu_unitdata_param *param; + struct xua_msg_part *data_ie = xua_msg_find_tag(xua, SUA_IEI_DATA); + struct msgb *upmsg = sccp_msgb_alloc(__func__); + struct osmo_sccp_user *scu; + uint32_t protocol_class; + + /* fill primitive */ + prim = (struct osmo_scu_prim *) msgb_put(upmsg, sizeof(*prim)); + param = &prim->u.unitdata; + osmo_prim_init(&prim->oph, SCCP_SAP_USER, + OSMO_SCU_PRIM_N_UNITDATA, + PRIM_OP_INDICATION, upmsg); + sua_addr_parse(¶m->called_addr, xua, SUA_IEI_DEST_ADDR); + sua_addr_parse(¶m->calling_addr, xua, SUA_IEI_SRC_ADDR); + param->in_sequence_control = xua_msg_get_u32(xua, SUA_IEI_SEQ_CTRL); + protocol_class = xua_msg_get_u32(xua, SUA_IEI_PROTO_CLASS); + param->return_option = protocol_class & 0x80; + param->importance = xua_msg_get_u32(xua, SUA_IEI_IMPORTANCE); + + scu = sccp_user_find(inst, param->called_addr.ssn, + param->called_addr.pc); + + if (!scu) { + /* FIXME: Send destination unreachable? */ + LOGP(DLSUA, LOGL_NOTICE, "Received SUA message for unequipped SSN %u\n", + param->called_addr.ssn); + msgb_free(upmsg); + return 0; + } + + /* copy data */ + upmsg->l2h = msgb_put(upmsg, data_ie->len); + memcpy(upmsg->l2h, data_ie->dat, data_ie->len); + + /* send to user SAP */ + sccp_user_prim_up(scu, prim); + + /* xua_msg is free'd by our caller */ + return 0; +} + +static int sclc_rx_cldr(struct osmo_sccp_instance *inst, struct xua_msg *xua) +{ + struct osmo_scu_prim *prim; + struct osmo_scu_notice_param *param; + struct xua_msg_part *data_ie = xua_msg_find_tag(xua, SUA_IEI_DATA); + struct msgb *upmsg = sccp_msgb_alloc(__func__); + struct osmo_sccp_user *scu; + + /* fill primitive */ + prim = (struct osmo_scu_prim *) msgb_put(upmsg, sizeof(*prim)); + param = &prim->u.notice; + osmo_prim_init(&prim->oph, SCCP_SAP_USER, + OSMO_SCU_PRIM_N_NOTICE, + PRIM_OP_INDICATION, upmsg); + + sua_addr_parse(¶m->called_addr, xua, SUA_IEI_DEST_ADDR); + sua_addr_parse(¶m->calling_addr, xua, SUA_IEI_SRC_ADDR); + param->importance = xua_msg_get_u32(xua, SUA_IEI_IMPORTANCE); + param->cause = xua_msg_get_u32(xua, SUA_IEI_CAUSE); + + scu = sccp_user_find(inst, param->called_addr.ssn, + param->called_addr.pc); + if (!scu) { + /* FIXME: Send destination unreachable? */ + LOGP(DLSUA, LOGL_NOTICE, "Received CLDR for unequipped SSN %u\n", + param->called_addr.ssn); + msgb_free(upmsg); + return 0; + } + + /* copy data */ + upmsg->l2h = msgb_put(upmsg, data_ie->len); + memcpy(upmsg->l2h, data_ie->dat, data_ie->len); + + /* send to user SAP */ + sccp_user_prim_up(scu, prim); + + /* xua_msg is free'd by our caller */ + return 0; +} + +/*! \brief SCRC -> SCLC (connectionless message) + * \param[in] inst SCCP Instance in which we operate + * \param[in] xua SUA connectionless message + * \returns 0 on success; negative on error */ +int sccp_sclc_rx_from_scrc(struct osmo_sccp_instance *inst, + struct xua_msg *xua) +{ + int rc = -1; + + OSMO_ASSERT(xua->hdr.msg_class == SUA_MSGC_CL); + + switch (xua->hdr.msg_type) { + case SUA_CL_CLDT: + rc = sclc_rx_cldt(inst, xua); + break; + case SUA_CL_CLDR: + rc = sclc_rx_cldr(inst, xua); + break; + default: + LOGP(DLSUA, LOGL_NOTICE, "Received unknown/unsupported " + "message %s\n", xua_hdr_dump(xua, &xua_dialect_sua)); + break; + } + + return rc; +} + +/* generate a return/refusal message (SUA CLDR == SCCP UDTS) based on + * the incoming message. We need to flip all identities between sender + * and receiver */ +static struct xua_msg *gen_ret_msg(struct osmo_sccp_instance *inst, + const struct xua_msg *xua_in, + uint32_t ret_cause) +{ + struct xua_msg *xua_out = xua_msg_alloc(); + struct osmo_sccp_addr called; + + xua_out->hdr = XUA_HDR(SUA_MSGC_CL, SUA_CL_CLDR); + xua_msg_add_u32(xua_out, SUA_IEI_ROUTE_CTX, inst->route_ctx); + xua_msg_add_u32(xua_out, SUA_IEI_CAUSE, + SUA_CAUSE_T_RETURN | ret_cause); + /* Swap Calling and Called Party */ + xua_msg_copy_part(xua_out, SUA_IEI_SRC_ADDR, xua_in, SUA_IEI_DEST_ADDR); + xua_msg_copy_part(xua_out, SUA_IEI_DEST_ADDR, xua_in, SUA_IEI_SRC_ADDR); + /* TODO: Optional: Hop Count */ + /* Optional: Importance */ + xua_msg_copy_part(xua_out, SUA_IEI_IMPORTANCE, + xua_in, SUA_IEI_IMPORTANCE); + /* Optional: Message Priority */ + xua_msg_copy_part(xua_out, SUA_IEI_MSG_PRIO, xua_in, SUA_IEI_MSG_PRIO); + /* Optional: Correlation ID */ + xua_msg_copy_part(xua_out, SUA_IEI_CORR_ID, xua_in, SUA_IEI_CORR_ID); + /* Optional: Segmentation */ + xua_msg_copy_part(xua_out, SUA_IEI_SEGMENTATION, + xua_in, SUA_IEI_SEGMENTATION); + /* Optional: Data */ + xua_msg_copy_part(xua_out, SUA_IEI_DATA, xua_in, SUA_IEI_DATA); + + sua_addr_parse(&called, xua_out, SUA_IEI_DEST_ADDR); + /* Route on PC + SSN ? */ + if (called.ri == OSMO_SCCP_RI_SSN_PC) { + /* if no PC, copy OPC into called addr */ + if (!(called.presence & OSMO_SCCP_ADDR_T_PC)) { + struct osmo_sccp_addr calling; + sua_addr_parse(&calling, xua_out, SUA_IEI_SRC_ADDR); + called.presence |= OSMO_SCCP_ADDR_T_PC; + called.pc = calling.pc; + /* Re-encode / replace called address */ + xua_msg_free_tag(xua_out, SUA_IEI_DEST_ADDR); + xua_msg_add_sccp_addr(xua_out, SUA_IEI_DEST_ADDR, + &called); + } + } + return xua_out; +} + +/*! \brief SCRC -> SCLC (Routing Failure + * \param[in] inst SCCP Instance in which we operate + * \param[in] xua_in Message that failed to be routed + * \param[in] cause SCCP Return Cause */ +void sccp_sclc_rx_scrc_rout_fail(struct osmo_sccp_instance *inst, + struct xua_msg *xua_in, uint32_t cause) +{ + struct xua_msg *xua_out; + + /* Figure C.12/Q.714 (Sheet 8) Node 9 */ + switch (xua_in->hdr.msg_type) { + case SUA_CL_CLDT: + xua_out = gen_ret_msg(inst, xua_in, cause); + /* TODO: Message Return Option? */ + if (!osmo_ss7_pc_is_local(inst->ss7, xua_in->mtp.opc)) { + /* non-local originator: send UDTS */ + /* TODO: Assign SLS */ + sccp_scrc_rx_sclc_msg(inst, xua_out); + } else { + /* local originator: send N-NOTICE to user */ + /* TODO: N-NOTICE.ind SCLC -> SCU */ + sclc_rx_cldr(inst, xua_out); + xua_msg_free(xua_out); + } + break; + case SUA_CL_CLDR: + /* do nothing */ + break; + } +} diff --git a/src/sccp_scoc.c b/src/sccp_scoc.c new file mode 100644 index 0000000..cb592e6 --- /dev/null +++ b/src/sccp_scoc.c @@ -0,0 +1,1672 @@ +/* SCCP Connection Oriented (SCOC) according to ITU-T Q.713/Q.714 */ + +/* (C) 2015-2017 by Harald Welte + * All Rights reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/* This code is a bit of a hybrid between the ITU-T Q.71x specifications + * for SCCP (particularly its connection-oriented part), and the IETF + * RFC 3868 (SUA). The idea here is to have one shared code base of the + * state machines for SCCP Connection Oriented, and use those both from + * SCCP and SUA. + * + * To do so, all SCCP messages are translated to SUA messages in the + * input side, and all generated SUA messages are translated to SCCP on + * the output side. + * + * The Choice of going for SUA messages as the "native" format was based + * on their easier parseability, and the fact that there are features in + * SUA which classic SCCP cannot handle (like IP addresses in GT). + * However, all SCCP features can be expressed in SUA. + * + * The code only supports Class 2. No support for Class 3 is intended, + * but patches are of course alwys welcome. + * + * Missing other features: + * * Segmentation/Reassembly support + * * T(guard) after (re)start + * * freezing of local references + * * parsing/encoding of IPv4/IPv6 addresses + * * use of multiple Routing Contexts in SUA case + */ + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "xua_internal.h" +#include "sccp_internal.h" + +#define S(x) (1 << (x)) +#define SCU_MSGB_SIZE 1024 + +/* Appendix C.4 of Q.714 (all in milliseconds) */ +#define CONNECTION_TIMER ( 1 * 60 * 100) +#define TX_INACT_TIMER ( 7 * 60 * 100) /* RFC 3868 Ch. 8. */ +#define RX_INACT_TIMER (15 * 60 * 100) /* RFC 3868 Ch. 8. */ +#define RELEASE_TIMER ( 10 * 100) +#define RELEASE_REP_TIMER ( 10 * 100) +#define INT_TIMER ( 1 * 60 * 100) +#define GUARD_TIMER (23 * 60 * 100) +#define RESET_TIMER ( 10 * 100) + +/* convert from single value in milliseconds to comma-separated + * "seconds, microseconds" format we use in osmocom/core/timers.h */ +#define MSEC_TO_S_US(x) (x/100), ((x%100)*10) + +/*********************************************************************** + * SCCP connection table + ***********************************************************************/ + +/* a logical connection within the SCCP instance */ +struct sccp_connection { + /* part of osmo_sccp_instance.list */ + struct llist_head list; + /* which instance are we part of? */ + struct osmo_sccp_instance *inst; + /* which user owns us? */ + struct osmo_sccp_user *user; + + /* remote point code */ + uint32_t remote_pc; + + /* local/remote addresses and identiies */ + struct osmo_sccp_addr calling_addr; + struct osmo_sccp_addr called_addr; + uint32_t conn_id; + uint32_t remote_ref; + + uint32_t importance; + uint32_t sccp_class; + uint32_t release_cause; /* WAIT_CONN_CONF */ + + /* Osmo FSM Instance of sccp_scoc_fsm */ + struct osmo_fsm_inst *fi; + + /* Connect timer */ + struct osmo_timer_list t_conn; + + /* inactivity timers */ + struct osmo_timer_list t_ias; + struct osmo_timer_list t_iar; + + /* release timers */ + struct osmo_timer_list t_rel; + struct osmo_timer_list t_int; + struct osmo_timer_list t_rep_rel; +}; + +/*********************************************************************** + * various helper functions + ***********************************************************************/ + +enum sccp_connection_state { + S_IDLE, + S_CONN_PEND_IN, + S_CONN_PEND_OUT, + S_ACTIVE, + S_DISCONN_PEND, + S_RESET_IN, + S_RESET_OUT, + S_BOTHWAY_RESET, + S_WAIT_CONN_CONF, +}; + +/* Events that this FSM can process */ +enum sccp_scoc_event { + /* Primitives from SCCP-User */ + SCOC_E_SCU_N_CONN_REQ, + SCOC_E_SCU_N_CONN_RESP, + SCOC_E_SCU_N_DISC_REQ, + SCOC_E_SCU_N_DATA_REQ, + SCOC_E_SCU_N_EXP_DATA_REQ, + + /* Events from RCOC (Routing for Connection Oriented) */ + SCOC_E_RCOC_CONN_IND, + SCOC_E_RCOC_ROUT_FAIL_IND, + SCOC_E_RCOC_RLSD_IND, + SCOC_E_RCOC_REL_COMPL_IND, + SCOC_E_RCOC_CREF_IND, + SCOC_E_RCOC_CC_IND, + SCOC_E_RCOC_DT1_IND, + SCOC_E_RCOC_DT2_IND, + SCOC_E_RCOC_IT_IND, + SCOC_E_RCOC_OTHER_NPDU, + SCOC_E_RCOC_ERROR_IND, + + /* Timer Events */ + SCOC_E_T_IAR_EXP, + SCOC_E_T_IAS_EXP, + + SCOC_E_CONN_TMR_EXP, + + SCOC_E_T_REL_EXP, + SCOC_E_T_INT_EXP, + SCOC_E_T_REP_REL_EXP, +}; + +static const struct value_string scoc_event_names[] = { + /* Primitives from SCCP-User */ + { SCOC_E_SCU_N_CONN_REQ, "N-CONNECT.req" }, + { SCOC_E_SCU_N_CONN_RESP, "N-CONNECT.resp" }, + { SCOC_E_SCU_N_DISC_REQ, "N-DISCONNECT.req" }, + { SCOC_E_SCU_N_DATA_REQ, "N-DATA.req" }, + { SCOC_E_SCU_N_EXP_DATA_REQ, "N-EXPEDITED_DATA.req" }, + + /* Events from RCOC (Routing for Connection Oriented) */ + { SCOC_E_RCOC_CONN_IND, "RCOC-CONNECT.ind" }, + { SCOC_E_RCOC_ROUT_FAIL_IND, "RCOC-ROUT_FAIL.ind" }, + { SCOC_E_RCOC_RLSD_IND, "RCOC-RELEASED.ind" }, + { SCOC_E_RCOC_REL_COMPL_IND, "RCOC-RELEASE_COMPLETE.ind" }, + { SCOC_E_RCOC_CREF_IND, "RCOC-CONNECT_REFUSED.ind" }, + { SCOC_E_RCOC_CC_IND, "RCOC-CONNECT_CONFIRM.ind" }, + { SCOC_E_RCOC_DT1_IND, "RCOC-DT1.ind" }, + { SCOC_E_RCOC_DT2_IND, "RCOC-DT2.ind" }, + { SCOC_E_RCOC_IT_IND, "RCOC-IT.ind" }, + { SCOC_E_RCOC_OTHER_NPDU, "RCOC-OTHER_NPDU.ind" }, + { SCOC_E_RCOC_ERROR_IND, "RCOC-ERROR.ind" }, + + { SCOC_E_T_IAR_EXP, "T(iar)_expired" }, + { SCOC_E_T_IAS_EXP, "T(ias)_expired" }, + { SCOC_E_CONN_TMR_EXP, "T(conn)_expired" }, + { SCOC_E_T_REL_EXP, "T(rel)_expired" }, + { SCOC_E_T_INT_EXP, "T(int)_expired" }, + { SCOC_E_T_REP_REL_EXP, "T(rep_rel)_expired" }, + + { 0, NULL } +}; + +/* how to map a SCCP CO message to an event */ +static const struct xua_msg_event_map sua_scoc_event_map[] = { + { SUA_MSGC_CO, SUA_CO_CORE, SCOC_E_RCOC_CONN_IND }, + { SUA_MSGC_CO, SUA_CO_RELRE, SCOC_E_RCOC_RLSD_IND }, + { SUA_MSGC_CO, SUA_CO_RELCO, SCOC_E_RCOC_REL_COMPL_IND }, + { SUA_MSGC_CO, SUA_CO_COREF, SCOC_E_RCOC_CREF_IND }, + { SUA_MSGC_CO, SUA_CO_COAK, SCOC_E_RCOC_CC_IND }, + { SUA_MSGC_CO, SUA_CO_CODT, SCOC_E_RCOC_DT1_IND }, + { SUA_MSGC_CO, SUA_CO_COIT, SCOC_E_RCOC_IT_IND }, + { SUA_MSGC_CO, SUA_CO_COERR, SCOC_E_RCOC_ERROR_IND }, +}; + + +/*! \brief magic value to be used as final record of \ref + * osmo_prim_event_map */ +#define OSMO_NO_EVENT 0xFFFFFFFF + +/*! \brief single entry in a SAP/PRIM/OP -> EVENT map */ +struct osmo_prim_event_map { + unsigned int sap; /*!< SAP to match */ + unsigned int primitive; /*!< primtiive to match */ + enum osmo_prim_operation operation; /*!< operation to match */ + uint32_t event; /*!< event as result if above match */ +}; + +/*! \brief resolve the (fsm) event for a given primitive using a map + * \param[in] oph primitive header used as key for match + * \param[in] maps list of mappings from primitive to event + * \returns event determined by map; \ref OSMO_NO_EVENT if no match */ +uint32_t osmo_event_for_prim(const struct osmo_prim_hdr *oph, + const struct osmo_prim_event_map *maps) +{ + const struct osmo_prim_event_map *map; + + for (map = maps; map->event != OSMO_NO_EVENT; map++) { + if (map->sap == oph->sap && + map->primitive == oph->primitive && + map->operation == oph->operation) + return map->event; + } + return OSMO_NO_EVENT; +} + +/* map from SCU-primitives to SCOC FSM events */ +static const struct osmo_prim_event_map scu_scoc_event_map[] = { + { SCCP_SAP_USER, OSMO_SCU_PRIM_N_CONNECT, PRIM_OP_REQUEST, + SCOC_E_SCU_N_CONN_REQ }, + { SCCP_SAP_USER, OSMO_SCU_PRIM_N_CONNECT, PRIM_OP_RESPONSE, + SCOC_E_SCU_N_CONN_RESP }, + { SCCP_SAP_USER, OSMO_SCU_PRIM_N_DATA, PRIM_OP_REQUEST, + SCOC_E_SCU_N_DATA_REQ }, + { SCCP_SAP_USER, OSMO_SCU_PRIM_N_DISCONNECT, PRIM_OP_REQUEST, + SCOC_E_SCU_N_DISC_REQ }, + { SCCP_SAP_USER, OSMO_SCU_PRIM_N_EXPEDITED_DATA, PRIM_OP_REQUEST, + SCOC_E_SCU_N_EXP_DATA_REQ }, + { 0, 0, 0, OSMO_NO_EVENT } +}; + +/*********************************************************************** + * Timer Handling + ***********************************************************************/ + +/* T(ias) has expired, send a COIT message to the peer */ +static void tx_inact_tmr_cb(void *data) +{ + struct sccp_connection *conn = data; + osmo_fsm_inst_dispatch(conn->fi, SCOC_E_T_IAS_EXP, NULL); +} + +/* T(iar) has expired, notify the FSM about it */ +static void rx_inact_tmr_cb(void *data) +{ + struct sccp_connection *conn = data; + osmo_fsm_inst_dispatch(conn->fi, SCOC_E_T_IAR_EXP, NULL); +} + +/* T(rel) has expired, notify the FSM about it */ +static void rel_tmr_cb(void *data) +{ + struct sccp_connection *conn = data; + osmo_fsm_inst_dispatch(conn->fi, SCOC_E_T_REL_EXP, NULL); +} + +/* T(int) has expired, notify the FSM about it */ +static void int_tmr_cb(void *data) +{ + struct sccp_connection *conn = data; + osmo_fsm_inst_dispatch(conn->fi, SCOC_E_T_INT_EXP, NULL); +} + +/* T(repeat_rel) has expired, notify the FSM about it */ +static void rep_rel_tmr_cb(void *data) +{ + struct sccp_connection *conn = data; + osmo_fsm_inst_dispatch(conn->fi, SCOC_E_T_REP_REL_EXP, NULL); +} + +/* T(conn) has expired, notify the FSM about it */ +static void conn_tmr_cb(void *data) +{ + struct sccp_connection *conn = data; + osmo_fsm_inst_dispatch(conn->fi, SCOC_E_CONN_TMR_EXP, NULL); +} + +/* Re-start the Tx inactivity timer */ +static void conn_restart_tx_inact_timer(struct sccp_connection *conn) +{ + osmo_timer_schedule(&conn->t_ias, MSEC_TO_S_US(TX_INACT_TIMER)); +} + +/* Re-start the Rx inactivity timer */ +static void conn_restart_rx_inact_timer(struct sccp_connection *conn) +{ + osmo_timer_schedule(&conn->t_iar, MSEC_TO_S_US(RX_INACT_TIMER)); +} + +/* Re-start both Rx and Tx inactivity timers */ +static void conn_start_inact_timers(struct sccp_connection *conn) +{ + conn_restart_tx_inact_timer(conn); + conn_restart_rx_inact_timer(conn); +} + +/* Stop both Rx and Tx inactivity timers */ +static void conn_stop_inact_timers(struct sccp_connection *conn) +{ + osmo_timer_del(&conn->t_ias); + osmo_timer_del(&conn->t_iar); +} + +/* Start release timer T(rel) */ +static void conn_start_rel_timer(struct sccp_connection *conn) +{ + osmo_timer_schedule(&conn->t_rel, MSEC_TO_S_US(RELEASE_TIMER)); +} + +/* Start repeat release timer T(rep_rel) */ +static void conn_start_rep_rel_timer(struct sccp_connection *conn) +{ + osmo_timer_schedule(&conn->t_rep_rel, MSEC_TO_S_US(RELEASE_REP_TIMER)); +} + +/* Start interval timer T(int) */ +static void conn_start_int_timer(struct sccp_connection *conn) +{ + osmo_timer_schedule(&conn->t_int, MSEC_TO_S_US(INT_TIMER)); +} + +/* Stop all release related timers: T(rel), T(int) and T(rep_rel) */ +static void conn_stop_release_timers(struct sccp_connection *conn) +{ + osmo_timer_del(&conn->t_rel); + osmo_timer_del(&conn->t_int); + osmo_timer_del(&conn->t_rep_rel); +} + +/* Start connect timer T(conn) */ +static void conn_start_connect_timer(struct sccp_connection *conn) +{ + osmo_timer_schedule(&conn->t_conn, MSEC_TO_S_US(CONNECTION_TIMER)); +} + +/* Stop connect timer T(conn) */ +static void conn_stop_connect_timer(struct sccp_connection *conn) +{ + osmo_timer_del(&conn->t_conn); +} + + +/*********************************************************************** + * SUA Instance and Connection handling + ***********************************************************************/ + +static void conn_destroy(struct sccp_connection *conn); + +static struct sccp_connection *conn_find_by_id(struct osmo_sccp_instance *inst, uint32_t id) +{ + struct sccp_connection *conn; + + llist_for_each_entry(conn, &inst->connections, list) { + if (conn->conn_id == id) + return conn; + } + return NULL; +} + +#define INIT_TIMER(x, fn, priv) do { (x)->cb = fn; (x)->data = priv; } while (0) + +/* allocate + init a SCCP Connection with given ID (local reference) */ +static struct sccp_connection *conn_create_id(struct osmo_sccp_instance *inst, + uint32_t conn_id) +{ + struct sccp_connection *conn = talloc_zero(inst, struct sccp_connection); + char name[16]; + + conn->conn_id = conn_id; + conn->inst = inst; + + llist_add_tail(&conn->list, &inst->connections); + + INIT_TIMER(&conn->t_conn, conn_tmr_cb, conn); + INIT_TIMER(&conn->t_ias, tx_inact_tmr_cb, conn); + INIT_TIMER(&conn->t_iar, rx_inact_tmr_cb, conn); + INIT_TIMER(&conn->t_rel, rel_tmr_cb, conn); + INIT_TIMER(&conn->t_int, int_tmr_cb, conn); + INIT_TIMER(&conn->t_rep_rel, rep_rel_tmr_cb, conn); + + /* this might change at runtime, as it is not a constant :/ */ + sccp_scoc_fsm.log_subsys = DLSCCP; + + /* we simply use the local reference as FSM instance name */ + snprintf(name, sizeof(name), "%u", conn->conn_id); + conn->fi = osmo_fsm_inst_alloc(&sccp_scoc_fsm, conn, conn, + LOGL_DEBUG, name); + if (!conn->fi) { + llist_del(&conn->list); + talloc_free(conn); + return NULL; + } + + return conn; +} + +/* Search for next free connection ID (local reference) and allocate conn */ +static struct sccp_connection *conn_create(struct osmo_sccp_instance *inst) +{ + uint32_t conn_id; + + do { + conn_id = inst->next_id++; + } while (conn_find_by_id(inst, conn_id)); + + return conn_create_id(inst, conn_id); +} + +/* destroy a SCCP connection state, releasing all timers, terminating + * FSM and releasing associated memory */ +static void conn_destroy(struct sccp_connection *conn) +{ + conn_stop_connect_timer(conn); + conn_stop_inact_timers(conn); + conn_stop_release_timers(conn); + llist_del(&conn->list); + + osmo_fsm_inst_term(conn->fi, OSMO_FSM_TERM_REQUEST, NULL); + + talloc_free(conn); +} + +/* allocate a message buffer for an SCCP User Primitive */ +static struct msgb *scu_msgb_alloc(void) +{ + return msgb_alloc(SCU_MSGB_SIZE, "SCCP User Primitive"); +} + +/* generate a RELRE (release request) xua_msg for given conn */ +static struct xua_msg *xua_gen_relre(struct sccp_connection *conn, + uint32_t cause, + struct osmo_scu_prim *prim) +{ + struct xua_msg *xua = xua_msg_alloc(); + + if (!xua) + return NULL; + + xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_RELRE); + xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, conn->inst->route_ctx); + xua_msg_add_u32(xua, SUA_IEI_DEST_REF, conn->remote_ref); + xua_msg_add_u32(xua, SUA_IEI_SRC_REF, conn->conn_id); + xua_msg_add_u32(xua, SUA_IEI_CAUSE, SUA_CAUSE_T_RELEASE | cause); + /* optional: importance */ + if (prim && msgb_l2(prim->oph.msg)) + xua_msg_add_data(xua, SUA_IEI_DATA, msgb_l2len(prim->oph.msg), + msgb_l2(prim->oph.msg)); + + return xua; +} + +/* generate xua_msg, encode it and send it to SCRC */ +static int xua_gen_relre_and_send(struct sccp_connection *conn, uint32_t cause, + struct osmo_scu_prim *prim) +{ + struct xua_msg *xua; + + xua = xua_gen_relre(conn, cause, prim); + if (!xua) + return -1; + + /* amend this with point code information; The SUA RELRE + * includes neither called nor calling party address! */ + xua->mtp.dpc = conn->remote_pc; + return sccp_scrc_rx_scoc_conn_msg(conn->inst, xua); +} + +/* generate a 'struct xua_msg' of requested type from connection + + * primitive data */ +static struct xua_msg *xua_gen_msg_co(struct sccp_connection *conn, uint32_t event, + struct osmo_scu_prim *prim, int msg_type) +{ + struct xua_msg *xua = xua_msg_alloc(); + + if (!xua) + return NULL; + + switch (msg_type) { + case SUA_CO_CORE: /* Connect Request == SCCP CR */ + xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_CORE); + xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, conn->inst->route_ctx); + xua_msg_add_u32(xua, SUA_IEI_PROTO_CLASS, conn->sccp_class); + xua_msg_add_u32(xua, SUA_IEI_SRC_REF, conn->conn_id); + xua_msg_add_sccp_addr(xua, SUA_IEI_DEST_ADDR, &conn->called_addr); + xua_msg_add_u32(xua, SUA_IEI_SEQ_CTRL, 0); /* TODO */ + /* optional: sequence number (class 3 only) */ + if (conn->calling_addr.presence) + xua_msg_add_sccp_addr(xua, SUA_IEI_SRC_ADDR, &conn->calling_addr); + /* optional: hop count; importance; priority; credit */ + if (prim && msgb_l2(prim->oph.msg)) + xua_msg_add_data(xua, SUA_IEI_DATA, msgb_l2len(prim->oph.msg), + msgb_l2(prim->oph.msg)); + break; + case SUA_CO_COAK: /* Connect Acknowledge == SCCP CC */ + xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_COAK); + xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, conn->inst->route_ctx); + xua_msg_add_u32(xua, SUA_IEI_PROTO_CLASS, conn->sccp_class); + xua_msg_add_u32(xua, SUA_IEI_DEST_REF, conn->remote_ref); + xua_msg_add_u32(xua, SUA_IEI_SRC_REF, conn->conn_id); + xua_msg_add_u32(xua, SUA_IEI_SEQ_CTRL, 0); /* TODO */ + /* optional: sequence number (class 3 only) */ + if (conn->called_addr.presence) + xua_msg_add_sccp_addr(xua, SUA_IEI_SRC_ADDR, &conn->called_addr); + /* optional: hop count; importance; priority */ + /* FIXME: destination address will [only] be present in + * case the CORE message conveys the source address + * parameter */ + if (conn->calling_addr.presence) + xua_msg_add_sccp_addr(xua, SUA_IEI_DEST_ADDR, &conn->calling_addr); + if (prim && msgb_l2(prim->oph.msg)) + xua_msg_add_data(xua, SUA_IEI_DATA, msgb_l2len(prim->oph.msg), + msgb_l2(prim->oph.msg)); + break; + case SUA_CO_RELRE: /* Release Request == SCCP REL */ + if (!prim) + goto prim_needed; + xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_RELRE); + xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, conn->inst->route_ctx); + xua_msg_add_u32(xua, SUA_IEI_DEST_REF, conn->remote_ref); + xua_msg_add_u32(xua, SUA_IEI_SRC_REF, conn->conn_id); + xua_msg_add_u32(xua, SUA_IEI_CAUSE, SUA_CAUSE_T_RELEASE | prim->u.disconnect.cause); + /* optional: importance */ + if (msgb_l2(prim->oph.msg)) + xua_msg_add_data(xua, SUA_IEI_DATA, msgb_l2len(prim->oph.msg), + msgb_l2(prim->oph.msg)); + break; + case SUA_CO_RELCO: /* Release Confirm == SCCP RLSD */ + xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_RELCO); + xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, conn->inst->route_ctx); + xua_msg_add_u32(xua, SUA_IEI_DEST_REF, conn->remote_ref); + xua_msg_add_u32(xua, SUA_IEI_SRC_REF, conn->conn_id); + /* optional: importance */ + break; + case SUA_CO_CODT: /* Connection Oriented Data Transfer == SCCP DT1 */ + if (!prim) + goto prim_needed; + xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_CODT); + xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, conn->inst->route_ctx); + /* Sequence number only in expedited data */ + xua_msg_add_u32(xua, SUA_IEI_DEST_REF, conn->remote_ref); + /* optional: priority; correlation id */ + xua_msg_add_data(xua, SUA_IEI_DATA, msgb_l2len(prim->oph.msg), + msgb_l2(prim->oph.msg)); + break; + case SUA_CO_COIT: /* Connection Oriented Interval Timer == SCCP IT */ + xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_COIT); + xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, conn->inst->route_ctx); + xua_msg_add_u32(xua, SUA_IEI_PROTO_CLASS, conn->sccp_class); + xua_msg_add_u32(xua, SUA_IEI_SRC_REF, conn->conn_id); + xua_msg_add_u32(xua, SUA_IEI_DEST_REF, conn->remote_ref); + /* optional: sequence number; credit (both class 3 only) */ + break; + case SUA_CO_COREF: /* Connect Refuse == SCCP CREF */ + xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_COREF); + xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, conn->inst->route_ctx); + xua_msg_add_u32(xua, SUA_IEI_DEST_REF, conn->remote_ref); + //xua_msg_add_u32(xua, SUA_IEI_CAUSE, SUA_CAUSE_T_REFUSAL | prim->u.disconnect.cause); + xua_msg_add_u32(xua, SUA_IEI_CAUSE, SUA_CAUSE_T_REFUSAL | SCCP_REFUSAL_UNEQUIPPED_USER); + /* optional: source addr */ + if (conn->called_addr.presence) + xua_msg_add_sccp_addr(xua, SUA_IEI_SRC_ADDR, &conn->called_addr); + /* conditional: dest addr */ + if (conn->calling_addr.presence) + xua_msg_add_sccp_addr(xua, SUA_IEI_DEST_ADDR, &conn->calling_addr); + /* optional: importance */ + /* optional: data */ + if (prim && msgb_l2(prim->oph.msg)) + xua_msg_add_data(xua, SUA_IEI_DATA, msgb_l2len(prim->oph.msg), + msgb_l2(prim->oph.msg)); + break; + /* FIXME */ + default: + LOGP(DLSCCP, LOGL_ERROR, "Don't know how to encode msg_type %u\n", msg_type); + xua_msg_free(xua); + return NULL; + } + return xua; + +prim_needed: + xua_msg_free(xua); + LOGP(DLSCCP, LOGL_ERROR, "%s must be called with valid 'prim' " + "pointer for msg_type=%u\n", __func__, msg_type); + return NULL; +} + +/* generate xua_msg, encode it and send it to SCRC */ +static int xua_gen_encode_and_send(struct sccp_connection *conn, uint32_t event, + struct osmo_scu_prim *prim, int msg_type) +{ + struct xua_msg *xua; + + xua = xua_gen_msg_co(conn, event, prim, msg_type); + if (!xua) + return -1; + + /* amend this with point code information; Many CO msgs + * includes neither called nor calling party address! */ + xua->mtp.dpc = conn->remote_pc; + return sccp_scrc_rx_scoc_conn_msg(conn->inst, xua); +} + +/* allocate a SCU primitive to be sent to the user */ +static struct osmo_scu_prim *scu_prim_alloc(unsigned int primitive, enum osmo_prim_operation operation) +{ + struct msgb *upmsg = scu_msgb_alloc(); + struct osmo_scu_prim *prim; + + prim = (struct osmo_scu_prim *) msgb_put(upmsg, sizeof(*prim)); + osmo_prim_init(&prim->oph, SCCP_SAP_USER, + primitive, operation, upmsg); + return prim; +} + +/* high-level function to generate a SCCP User primitive of requested + * type based on the connection and currently processed XUA message */ +static void scu_gen_encode_and_send(struct sccp_connection *conn, uint32_t event, + struct xua_msg *xua, unsigned int primitive, + enum osmo_prim_operation operation) +{ + struct osmo_scu_prim *scu_prim; + struct osmo_scu_disconn_param *udisp; + struct osmo_scu_connect_param *uconp; + struct osmo_scu_data_param *udatp; + struct xua_msg_part *data_ie; + + scu_prim = scu_prim_alloc(primitive, operation); + + switch (OSMO_PRIM_HDR(&scu_prim->oph)) { + case OSMO_PRIM(OSMO_SCU_PRIM_N_DISCONNECT, PRIM_OP_INDICATION): + udisp = &scu_prim->u.disconnect; + udisp->conn_id = conn->conn_id; + udisp->responding_addr = conn->called_addr; + udisp->originator = OSMO_SCCP_ORIG_UNDEFINED; + //udisp->in_sequence_control; + if (xua) { + udisp->cause = xua_msg_get_u32(xua, SUA_IEI_CAUSE); + if (xua_msg_find_tag(xua, SUA_IEI_SRC_ADDR)) + sua_addr_parse(&udisp->responding_addr, xua, SUA_IEI_SRC_ADDR); + data_ie = xua_msg_find_tag(xua, SUA_IEI_DATA); + udisp->importance = xua_msg_get_u32(xua, SUA_IEI_IMPORTANCE); + if (data_ie) { + struct msgb *upmsg = scu_prim->oph.msg; + upmsg->l2h = msgb_put(upmsg, data_ie->len); + memcpy(upmsg->l2h, data_ie->dat, data_ie->len); + } + } + break; + case OSMO_PRIM(OSMO_SCU_PRIM_N_CONNECT, PRIM_OP_INDICATION): + uconp = &scu_prim->u.connect; + uconp->conn_id = conn->conn_id; + uconp->called_addr = conn->called_addr; + uconp->calling_addr = conn->calling_addr; + uconp->sccp_class = conn->sccp_class; + uconp->importance = conn->importance; + data_ie = xua_msg_find_tag(xua, SUA_IEI_DATA); + if (xua) { + if (data_ie) { + struct msgb *upmsg = scu_prim->oph.msg; + upmsg->l2h = msgb_put(upmsg, data_ie->len); + memcpy(upmsg->l2h, data_ie->dat, data_ie->len); + } + } + break; + case OSMO_PRIM(OSMO_SCU_PRIM_N_CONNECT, PRIM_OP_CONFIRM): + uconp = &scu_prim->u.connect; + uconp->conn_id = conn->conn_id; + uconp->called_addr = conn->called_addr; + uconp->calling_addr = conn->calling_addr; + //scu_prim->u.connect.in_sequence_control + uconp->sccp_class = xua_msg_get_u32(xua, SUA_IEI_PROTO_CLASS) & 3; + uconp->importance = xua_msg_get_u32(xua, SUA_IEI_IMPORTANCE); + data_ie = xua_msg_find_tag(xua, SUA_IEI_DATA); + if (data_ie) { + struct msgb *upmsg = scu_prim->oph.msg; + upmsg->l2h = msgb_put(upmsg, data_ie->len); + memcpy(upmsg->l2h, data_ie->dat, data_ie->len); + } + break; + case OSMO_PRIM(OSMO_SCU_PRIM_N_DATA, PRIM_OP_INDICATION): + udatp = &scu_prim->u.data; + udatp->conn_id = conn->conn_id; + udatp->importance = conn->importance; + data_ie = xua_msg_find_tag(xua, SUA_IEI_DATA); + if (data_ie) { + struct msgb *upmsg = scu_prim->oph.msg; + upmsg->l2h = msgb_put(upmsg, data_ie->len); + memcpy(upmsg->l2h, data_ie->dat, data_ie->len); + } + break; + default: + LOGPFSML(conn->fi, LOGL_ERROR, "Unsupported primitive %u:%u\n", + scu_prim->oph.primitive, scu_prim->oph.operation); + talloc_free(scu_prim->oph.msg); + return; + } + + sccp_user_prim_up(conn->user, scu_prim); +} + + +/*********************************************************************** + * Actual SCCP Connection Oriented Control (SCOC) Finite Stte Machine + ***********************************************************************/ + +/* Figure C.2/Q.714 (sheet 1 of 7) and C.3/Q.714 (sheet 1 of 6) */ +static void scoc_fsm_idle(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct sccp_connection *conn = fi->priv; + struct osmo_scu_prim *prim = NULL; + struct osmo_scu_connect_param *uconp; + struct xua_msg *xua = NULL; + + switch (event) { + case SCOC_E_SCU_N_CONN_REQ: + prim = data; + uconp = &prim->u.connect; + /* copy relevant parameters from prim to conn */ + conn->called_addr = uconp->called_addr; + conn->calling_addr = uconp->calling_addr; + conn->sccp_class = uconp->sccp_class; + /* generate + send CR PDU to SCRC */ + xua_gen_encode_and_send(conn, event, prim, SUA_CO_CORE); + /* start connection timer */ + conn_start_connect_timer(conn); + osmo_fsm_inst_state_chg(fi, S_CONN_PEND_OUT, 0, 0); + break; +#if 0 + case SCOC_E_SCU_N_TYPE1_REQ: + /* ?!? */ + break; +#endif + case SCOC_E_RCOC_RLSD_IND: + /* send release complete to SCRC */ + xua_gen_encode_and_send(conn, event, NULL, SUA_CO_RELCO); + break; + case SCOC_E_RCOC_REL_COMPL_IND: + /* do nothing */ + break; + case SCOC_E_RCOC_OTHER_NPDU: +#if 0 + if (src_ref) { + /* FIXME: send ERROR to SCRC */ + } +#endif + break; + /* destination node / incoming connection */ + /* Figure C.3 / Q.714 (sheet 1 of 6) */ + case SCOC_E_RCOC_CONN_IND: + xua = data; + /* copy relevant parameters from xua to conn */ + sua_addr_parse(&conn->calling_addr, xua, SUA_IEI_SRC_ADDR); + sua_addr_parse(&conn->called_addr, xua, SUA_IEI_DEST_ADDR); + conn->remote_ref = xua_msg_get_u32(xua, SUA_IEI_SRC_REF); + conn->sccp_class = xua_msg_get_u32(xua, SUA_IEI_PROTO_CLASS) & 3; + conn->importance = xua_msg_get_u32(xua, SUA_IEI_IMPORTANCE); + /* 3.1.6.1 The originating node of the CR message + * (identified by the OPC in the calling party address + * or by default by the OPC in the MTP label, [and the + * MTP-SAP instance]) is associated with the incoming + * connection section. */ + if (conn->calling_addr.presence & OSMO_SCCP_ADDR_T_PC) + conn->remote_pc = conn->calling_addr.pc; + else { + /* Hack to get the MTP label here ?!? */ + conn->remote_pc = xua->mtp.opc; + } + + osmo_fsm_inst_state_chg(fi, S_CONN_PEND_IN, 0, 0); + /* N-CONNECT.ind to User */ + scu_gen_encode_and_send(conn, event, xua, OSMO_SCU_PRIM_N_CONNECT, + PRIM_OP_INDICATION); + break; + } +} + +static void scoc_fsm_idle_onenter(struct osmo_fsm_inst *fi, uint32_t old_state) +{ + conn_destroy(fi->priv); +} + +/* Figure C.3 / Q.714 (sheet 2 of 6) */ +static void scoc_fsm_conn_pend_in(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct sccp_connection *conn = fi->priv; + struct osmo_scu_prim *prim = NULL; + + switch (event) { + case SCOC_E_SCU_N_CONN_RESP: + prim = data; + /* FIXME: assign local reference (only now?) */ + /* FIXME: assign sls, protocol class and credit */ + xua_gen_encode_and_send(conn, event, prim, SUA_CO_COAK); + /* start inactivity timers */ + conn_start_inact_timers(conn); + osmo_fsm_inst_state_chg(fi, S_ACTIVE, 0, 0); + break; + case SCOC_E_SCU_N_DISC_REQ: + prim = data; + /* release resources: implicit */ + xua_gen_encode_and_send(conn, event, prim, SUA_CO_COREF); + osmo_fsm_inst_state_chg(fi, S_IDLE, 0, 0); + break; + } +} + +/* Figure C.2/Q.714 (sheet 2 of 7) */ +static void scoc_fsm_conn_pend_out(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct sccp_connection *conn = fi->priv; + struct osmo_scu_prim *prim = NULL; + struct xua_msg *xua = NULL; + + switch (event) { + case SCOC_E_SCU_N_DISC_REQ: + prim = data; + conn->release_cause = prim->u.disconnect.cause; + osmo_fsm_inst_state_chg(fi, S_WAIT_CONN_CONF, 0, 0); + /* keep conn timer running(!) */ + break; + case SCOC_E_CONN_TMR_EXP: + /* N-DISCONNECT.ind to user */ + scu_gen_encode_and_send(conn, event, xua, OSMO_SCU_PRIM_N_DISCONNECT, + PRIM_OP_INDICATION); + /* below implicitly releases resources + local ref */ + osmo_fsm_inst_state_chg(fi, S_IDLE, 0, 0); + break; + case SCOC_E_RCOC_ROUT_FAIL_IND: + case SCOC_E_RCOC_CREF_IND: + xua = data; + /* stop conn timer */ + conn_stop_connect_timer(conn); + /* release local res + ref (implicit by going to idle) */ + /* N-DISCONNECT.ind to user */ + scu_gen_encode_and_send(conn, event, xua, OSMO_SCU_PRIM_N_DISCONNECT, + PRIM_OP_INDICATION); + /* below implicitly releases resources + local ref */ + osmo_fsm_inst_state_chg(fi, S_IDLE, 0, 0); + break; + case SCOC_E_RCOC_RLSD_IND: + xua = data; + /* RLC to SCRC */ + xua_gen_encode_and_send(conn, event, NULL, SUA_CO_RELCO); + /* stop conn timer */ + conn_stop_connect_timer(conn); + /* release local res + ref (implicit) */ + /* N-DISCONNECT.ind to user */ + scu_gen_encode_and_send(conn, event, xua, OSMO_SCU_PRIM_N_DISCONNECT, + PRIM_OP_INDICATION); + osmo_fsm_inst_state_chg(fi, S_IDLE, 0, 0); + break; + case SCOC_E_RCOC_OTHER_NPDU: + xua = data; + conn_start_connect_timer(conn); + /* release local res + ref (implicit) */ + /* N-DISCONNECT.ind to user */ + scu_gen_encode_and_send(conn, event, xua, OSMO_SCU_PRIM_N_DISCONNECT, + PRIM_OP_INDICATION); + osmo_fsm_inst_state_chg(fi, S_IDLE, 0, 0); + break; + case SCOC_E_RCOC_CC_IND: + xua = data; + /* stop conn timer */ + conn_stop_connect_timer(conn); + /* start inactivity timers */ + conn_start_inact_timers(conn); + /* TODO: assign PCU and credit */ + /* associate remote ref to conn */ + conn->remote_ref = xua_msg_get_u32(xua, SUA_IEI_SRC_REF); + /* 3.1.4.2 The node sending the CC message (identified + * by the parameter OPC contained in the + * MTP-TRANSFER.indication primitive which conveyed the + * CC message [plus the MTP-SAP instance]) is associated + * with the connection section. */ + conn->remote_pc = xua->mtp.opc; + + osmo_fsm_inst_state_chg(fi, S_ACTIVE, 0, 0); + /* N-CONNECT.conf to user */ + scu_gen_encode_and_send(conn, event, xua, OSMO_SCU_PRIM_N_CONNECT, + PRIM_OP_CONFIRM); + break; + } +} + +/* Figure C.2/Q.714 (sheet 3 of 7) */ +static void scoc_fsm_wait_conn_conf(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct sccp_connection *conn = fi->priv; + struct xua_msg *xua = NULL; + + switch (event) { + case SCOC_E_RCOC_RLSD_IND: + xua = data; + /* release complete to SCRC */ + xua_gen_encode_and_send(conn, event, NULL, SUA_CO_RELCO); + /* stop conn timer */ + conn_stop_connect_timer(conn); + /* release local res + ref (implicit) */ + osmo_fsm_inst_state_chg(fi, S_IDLE, 0, 0); + break; + case SCOC_E_RCOC_CC_IND: + xua = data; + /* stop conn timer */ + conn_stop_connect_timer(conn); + /* associate rem ref to conn */ + conn->remote_ref = xua_msg_get_u32(xua, SUA_IEI_SRC_REF); + /* released to SCRC */ + xua_gen_relre_and_send(conn, conn->release_cause, NULL); + /* start rel timer */ + conn_start_rel_timer(conn); + osmo_fsm_inst_state_chg(fi, S_DISCONN_PEND, 0, 0); + break; + case SCOC_E_RCOC_OTHER_NPDU: + case SCOC_E_RCOC_CREF_IND: + case SCOC_E_RCOC_ROUT_FAIL_IND: + xua = data; + /* stop conn timer */ + conn_stop_connect_timer(conn); + /* release local res + ref */ + osmo_fsm_inst_state_chg(fi, S_IDLE, 0, 0); + break; + case SCOC_E_CONN_TMR_EXP: + /* release local res + ref */ + osmo_fsm_inst_state_chg(fi, S_IDLE, 0, 0); + break; + } +} + +/* C.2/Q.714 (sheet 4+5 of 7) and C.3/Q714 (sheet 3+4 of 6) */ +static void scoc_fsm_active(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct xua_msg *xua = data; + struct sccp_connection *conn = fi->priv; + struct osmo_scu_prim *prim = NULL; + + switch (event) { + /* TODO: internal disco */ + /* send N-DISCONNECT.ind to user */ + scu_gen_encode_and_send(conn, event, xua, OSMO_SCU_PRIM_N_DISCONNECT, + PRIM_OP_INDICATION); + /* fall-through */ + case SCOC_E_SCU_N_DISC_REQ: + prim = data; + /* stop inact timers */ + conn_stop_inact_timers(conn); + /* send RLSD to SCRC */ + xua_gen_encode_and_send(conn, event, prim, SUA_CO_RELRE); + /* start rel timer */ + conn_start_rel_timer(conn); + osmo_fsm_inst_state_chg(fi, S_DISCONN_PEND, 0, 0); + break; + case SCOC_E_RCOC_CREF_IND: + case SCOC_E_RCOC_CC_IND: + case SCOC_E_RCOC_REL_COMPL_IND: + /* do nothing */ + break; + case SCOC_E_RCOC_RLSD_IND: + /* send N-DISCONNECT.ind to user */ + scu_gen_encode_and_send(conn, event, xua, OSMO_SCU_PRIM_N_DISCONNECT, + PRIM_OP_INDICATION); + /* release res + local ref (implicit) */ + /* stop inact timers */ + conn_stop_inact_timers(conn); + /* RLC to SCRC */ + xua_gen_encode_and_send(conn, event, NULL, SUA_CO_RELCO); + osmo_fsm_inst_state_chg(fi, S_IDLE, 0, 0); + break; + case SCOC_E_RCOC_ERROR_IND: + xua = data; + /* FIXME: check for cause service_class_mismatch */ + /* release res + local ref (implicit) */ + /* send N-DISCONNECT.ind to user */ + scu_gen_encode_and_send(conn, event, xua, OSMO_SCU_PRIM_N_DISCONNECT, + PRIM_OP_INDICATION); + /* stop inact timers */ + conn_stop_inact_timers(conn); + osmo_fsm_inst_state_chg(fi, S_IDLE, 0, 0); + break; + case SCOC_E_T_IAR_EXP: + /* Send N-DISCONNECT.ind to local user */ + scu_gen_encode_and_send(conn, event, NULL, OSMO_SCU_PRIM_N_DISCONNECT, + PRIM_OP_INDICATION); + /* Send RLSD to peer */ + xua_gen_relre_and_send(conn, SCCP_RELEASE_CAUSE_EXPIRATION_INACTIVE, NULL); + conn_start_rel_timer(conn); + osmo_fsm_inst_state_chg(fi, S_DISCONN_PEND, 0, 0); + break; + case SCOC_E_RCOC_ROUT_FAIL_IND: + /* send N-DISCONNECT.ind to user */ + scu_gen_encode_and_send(conn, event, NULL, OSMO_SCU_PRIM_N_DISCONNECT, + PRIM_OP_INDICATION); + /* stop inact timers */ + conn_stop_inact_timers(conn); + /* start release timer */ + conn_start_rel_timer(conn); + osmo_fsm_inst_state_chg(fi, S_DISCONN_PEND, 0, 0); + break; + /* Figure C.4/Q.714 */ + case SCOC_E_SCU_N_DATA_REQ: + case SCOC_E_SCU_N_EXP_DATA_REQ: + prim = data; + xua_gen_encode_and_send(conn, event, prim, SUA_CO_CODT); + conn_restart_tx_inact_timer(conn); + break; + case SCOC_E_RCOC_DT1_IND: + /* restart receive inactivity timer */ + conn_restart_rx_inact_timer(conn); + /* TODO: M-bit */ + scu_gen_encode_and_send(conn, event, xua, OSMO_SCU_PRIM_N_DATA, + PRIM_OP_INDICATION); + break; + /* Figure C.4/Q.714 (sheet 4 of 4) */ + case SCOC_E_RCOC_IT_IND: + xua = data; + /* check if remote reference is what we expect */ + /* check class is what we expect */ + if (xua_msg_get_u32(xua, SUA_IEI_SRC_REF) != conn->remote_ref || + xua_msg_get_u32(xua, SUA_IEI_PROTO_CLASS) != conn->sccp_class) { + /* Release connection */ + /* send N-DISCONNECT.ind to user */ + scu_gen_encode_and_send(conn, event, NULL, + OSMO_SCU_PRIM_N_DISCONNECT, + PRIM_OP_INDICATION); + /* Stop inactivity Timers */ + conn_stop_inact_timers(conn); + /* Send RLSD to SCRC */ + xua_gen_relre_and_send(conn, SCCP_RELEASE_CAUSE_INCONSISTENT_CONN_DATA, NULL); + /* Start release timer */ + conn_start_rel_timer(conn); + osmo_fsm_inst_state_chg(fi, S_DISCONN_PEND, 0, 0); + } + conn_restart_rx_inact_timer(conn); + break; + case SCOC_E_T_IAS_EXP: + /* Send IT to peer */ + xua_gen_encode_and_send(conn, event, NULL, SUA_CO_COIT); + conn_restart_tx_inact_timer(conn); + break; + } +} + +/* C.2/Q.714 (sheet 6+7 of 7) and C.3/Q.714 (sheet 5+6 of 6) */ +static void scoc_fsm_disconn_pend(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct sccp_connection *conn = fi->priv; + + switch (event) { + case SCOC_E_RCOC_REL_COMPL_IND: + case SCOC_E_RCOC_RLSD_IND: + /* release res + local ref (implicit) */ + /* freeze local ref */ + /* stop release + interval timers */ + conn_stop_release_timers(conn); + osmo_fsm_inst_state_chg(fi, S_IDLE, 0, 0); + break; + case SCOC_E_RCOC_ROUT_FAIL_IND: + case SCOC_E_RCOC_OTHER_NPDU: + /* do nothing */ + break; + case SCOC_E_T_REL_EXP: /* release timer exp */ + /* send RLSD */ + xua_gen_relre_and_send(conn, SCCP_RELEASE_CAUSE_UNQUALIFIED, NULL); + /* start interval timer */ + conn_start_int_timer(conn); + /* start repeat release timer */ + conn_start_rep_rel_timer(conn); + break; + case SCOC_E_T_INT_EXP: /* interval timer exp */ + /* TODO: Inform maintenance */ + /* stop release and interval timers */ + conn_stop_release_timers(conn); + osmo_fsm_inst_state_chg(fi, S_IDLE, 0, 0); + break; + case SCOC_E_T_REP_REL_EXP: /* repeat release timer exp */ + /* send RLSD */ + xua_gen_relre_and_send(conn, SCCP_RELEASE_CAUSE_UNQUALIFIED, NULL); + /* re-start repeat release timer */ + conn_start_rep_rel_timer(conn); + break; + } +} + +static const struct osmo_fsm_state sccp_scoc_states[] = { + [S_IDLE] = { + .name = "IDLE", + .action = scoc_fsm_idle, + .onenter= scoc_fsm_idle_onenter, + .in_event_mask = S(SCOC_E_SCU_N_CONN_REQ) | + //S(SCOC_E_SCU_N_TYPE1_REQ) | + S(SCOC_E_RCOC_CONN_IND) | + S(SCOC_E_RCOC_RLSD_IND) | + S(SCOC_E_RCOC_REL_COMPL_IND) | + S(SCOC_E_RCOC_OTHER_NPDU), + .out_state_mask = S(S_CONN_PEND_OUT) | + S(S_CONN_PEND_IN), + }, + [S_CONN_PEND_IN] = { + .name = "CONN_PEND_IN", + .action = scoc_fsm_conn_pend_in, + .in_event_mask = S(SCOC_E_SCU_N_CONN_RESP) | + S(SCOC_E_SCU_N_DISC_REQ), + .out_state_mask = S(S_IDLE) | + S(S_ACTIVE), + }, + [S_CONN_PEND_OUT] = { + .name = "CONN_PEND_OUT", + .action = scoc_fsm_conn_pend_out, + .in_event_mask = S(SCOC_E_SCU_N_DISC_REQ) | + S(SCOC_E_CONN_TMR_EXP) | + S(SCOC_E_RCOC_ROUT_FAIL_IND) | + S(SCOC_E_RCOC_RLSD_IND) | + S(SCOC_E_RCOC_OTHER_NPDU) | + S(SCOC_E_RCOC_CREF_IND) | + S(SCOC_E_RCOC_CC_IND), + .out_state_mask = S(S_IDLE) | + S(S_ACTIVE) | + S(S_WAIT_CONN_CONF), + }, + [S_ACTIVE] = { + .name = "ACTIVE", + .action = scoc_fsm_active, + .in_event_mask = S(SCOC_E_SCU_N_DISC_REQ) | + /* internal disconnect */ + S(SCOC_E_RCOC_CREF_IND) | + S(SCOC_E_RCOC_REL_COMPL_IND) | + S(SCOC_E_RCOC_RLSD_IND) | + S(SCOC_E_RCOC_ERROR_IND) | + S(SCOC_E_T_IAR_EXP) | + S(SCOC_E_T_IAS_EXP) | + S(SCOC_E_RCOC_ROUT_FAIL_IND) | + S(SCOC_E_SCU_N_DATA_REQ) | + S(SCOC_E_SCU_N_EXP_DATA_REQ) | + S(SCOC_E_RCOC_DT1_IND) | + S(SCOC_E_RCOC_IT_IND), + .out_state_mask = S(S_IDLE) | + S(S_DISCONN_PEND), + }, + [S_DISCONN_PEND] = { + .name = "DISCONN_PEND", + .action = scoc_fsm_disconn_pend, + .in_event_mask = S(SCOC_E_RCOC_REL_COMPL_IND) | + S(SCOC_E_RCOC_RLSD_IND) | + S(SCOC_E_RCOC_ROUT_FAIL_IND) | + S(SCOC_E_RCOC_OTHER_NPDU) | + S(SCOC_E_T_REL_EXP) | + S(SCOC_E_T_INT_EXP) | + S(SCOC_E_T_REP_REL_EXP), + .out_state_mask = S(S_IDLE), + }, + [S_RESET_IN] = { + .name = "RESET_IN", + }, + [S_RESET_OUT] = { + .name = "RESET_OUT", + }, + [S_BOTHWAY_RESET] = { + .name = "BOTHWAY_RESET", + }, + [S_WAIT_CONN_CONF] = { + .name = "WAIT_CONN_CONF", + .action = scoc_fsm_wait_conn_conf, + .in_event_mask = S(SCOC_E_RCOC_RLSD_IND) | + S(SCOC_E_RCOC_CC_IND) | + S(SCOC_E_RCOC_OTHER_NPDU) | + S(SCOC_E_CONN_TMR_EXP) | + S(SCOC_E_RCOC_CREF_IND) | + S(SCOC_E_RCOC_ROUT_FAIL_IND), + }, +}; + +struct osmo_fsm sccp_scoc_fsm = { + .name = "SCCP-SCOC", + .states = sccp_scoc_states, + .num_states = ARRAY_SIZE(sccp_scoc_states), + /* ".log_subsys = DLSCCP" doesn't work as DLSCCP is not a constant */ + .event_names = scoc_event_names, +}; + +/* map from SCCP return cause to SCCP Refusal cause */ +static const uint8_t cause_map_cref[] = { + [SCCP_RETURN_CAUSE_SUBSYSTEM_CONGESTION] = + SCCP_REFUSAL_SUBSYTEM_CONGESTION, + [SCCP_RETURN_CAUSE_SUBSYSTEM_FAILURE] = + SCCP_REFUSAL_SUBSYSTEM_FAILURE, + [SCCP_RETURN_CAUSE_UNEQUIPPED_USER] = + SCCP_REFUSAL_UNEQUIPPED_USER, + [SCCP_RETURN_CAUSE_UNQUALIFIED] = + SCCP_REFUSAL_UNQUALIFIED, + [SCCP_RETURN_CAUSE_SCCP_FAILURE] = + SCCP_REFUSAL_SCCP_FAILURE, + [SCCP_RETURN_CAUSE_HOP_COUNTER_VIOLATION] = + SCCP_REFUSAL_HOP_COUNTER_VIOLATION, +}; + +static uint8_t get_cref_cause_for_ret(uint8_t ret_cause) +{ + if (ret_cause < ARRAY_SIZE(cause_map_cref)) + return cause_map_cref[ret_cause]; + else + return SCCP_REFUSAL_UNQUALIFIED; +} + +/* Generate a COREF message purely based on an incoming SUA message, + * without the use of any local connection state */ +static struct xua_msg *gen_coref_without_conn(struct osmo_sccp_instance *inst, + struct xua_msg *xua_in, + uint32_t ref_cause) +{ + struct xua_msg *xua; + + xua = xua_msg_alloc(); + xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_COREF); + xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, inst->route_ctx); + + xua_msg_copy_part(xua, SUA_IEI_DEST_REF, xua_in, SUA_IEI_SRC_REF); + xua_msg_add_u32(xua, SUA_IEI_CAUSE, SUA_CAUSE_T_REFUSAL | ref_cause); + /* optional: source addr */ + xua_msg_copy_part(xua, SUA_IEI_SRC_ADDR, xua_in, SUA_IEI_DEST_ADDR); + /* conditional: dest addr */ + xua_msg_copy_part(xua, SUA_IEI_DEST_ADDR, xua_in, SUA_IEI_SRC_ADDR); + /* optional: importance */ + xua_msg_copy_part(xua, SUA_IEI_IMPORTANCE, xua_in, SUA_IEI_IMPORTANCE); + /* optional: data */ + xua_msg_copy_part(xua, SUA_IEI_DATA, xua_in, SUA_IEI_DATA); + + return xua; +} + +/*! \brief SCOC: Receive SCRC Routing Failure + * \param[in] inst SCCP Instance on which we operate + * \param[in] xua SUA message that was failed to route + * \param[in] return_cause Reason (cause) for routing failure */ +void sccp_scoc_rx_scrc_rout_fail(struct osmo_sccp_instance *inst, + struct xua_msg *xua, uint32_t return_cause) +{ + uint32_t conn_id; + struct sccp_connection *conn; + + /* try to dispatch to connection FSM (if any) */ + conn_id = xua_msg_get_u32(xua, SUA_IEI_DEST_REF); + conn = conn_find_by_id(inst, conn_id); + if (conn) { + osmo_fsm_inst_dispatch(conn->fi, + SCOC_E_RCOC_ROUT_FAIL_IND, xua); + } else { + /* generate + send CREF directly */ + struct xua_msg *cref; + uint8_t cref_cause = get_cref_cause_for_ret(return_cause); + cref = gen_coref_without_conn(inst, xua, cref_cause); + sccp_scrc_rx_scoc_conn_msg(inst, cref); + xua_msg_free(cref); + } +} + +/* Find a SCCP user for given SUA message (based on SUA_IEI_DEST_ADDR */ +static struct osmo_sccp_user *sccp_find_user(struct osmo_sccp_instance *inst, + struct xua_msg *xua) +{ + int rc; + struct osmo_sccp_addr called_addr; + + rc = sua_addr_parse(&called_addr, xua, SUA_IEI_DEST_ADDR); + if (rc < 0) { + LOGP(DLSCCP, LOGL_ERROR, "Cannot find SCCP User for XUA " + "Message %s without valid DEST_ADDR\n", + xua_hdr_dump(xua, &xua_dialect_sua)); + return NULL; + } + + if (!(called_addr.presence & OSMO_SCCP_ADDR_T_SSN)) { + LOGP(DLSCCP, LOGL_ERROR, "Cannot resolve SCCP User for " + "XUA Message %s without SSN in CalledAddr\n", + xua_hdr_dump(xua, &xua_dialect_sua)); + return NULL; + } + + return sccp_user_find(inst, called_addr.ssn, called_addr.pc); +} + +/* Generate a COERR based in input arguments */ +static struct xua_msg *gen_coerr(uint32_t route_ctx, uint32_t dest_ref, + uint32_t err_cause) +{ + struct xua_msg *xua = xua_msg_alloc(); + + xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_COERR); + xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, route_ctx); + xua_msg_add_u32(xua, SUA_IEI_DEST_REF, dest_ref); + xua_msg_add_u32(xua, SUA_IEI_CAUSE, SUA_CAUSE_T_ERROR | err_cause); + + return xua; +} + +/* generate COERR from incoming XUA and send it */ +static void tx_coerr_from_xua(struct osmo_sccp_instance *inst, + struct xua_msg *in, uint32_t err_cause) +{ + struct xua_msg *xua; + uint32_t route_ctx, dest_ref; + + route_ctx = xua_msg_get_u32(in, SUA_IEI_ROUTE_CTX); + /* get *source* reference and use as destination ref */ + dest_ref = xua_msg_get_u32(in, SUA_IEI_SRC_REF); + + xua = gen_coerr(route_ctx, dest_ref, err_cause); + /* copy over the MTP parameters */ + xua->mtp.dpc = in->mtp.opc; + xua->mtp.opc = in->mtp.dpc; + xua->mtp.sio = in->mtp.sio; + + /* sent to SCRC for transmission */ + sccp_scrc_rx_scoc_conn_msg(inst, xua); + xua_msg_free(xua); +} + +/* Generate a RELCO based in input arguments */ +static struct xua_msg *gen_relco(uint32_t route_ctx, uint32_t dest_ref, + uint32_t src_ref) +{ + struct xua_msg *xua = xua_msg_alloc(); + + xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_RELCO); + xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, route_ctx); + xua_msg_add_u32(xua, SUA_IEI_DEST_REF, dest_ref); + xua_msg_add_u32(xua, SUA_IEI_SRC_REF, src_ref); + + return xua; +} + +/* generate RELCO from incoming XUA and send it */ +static void tx_relco_from_xua(struct osmo_sccp_instance *inst, + struct xua_msg *in) +{ + struct xua_msg *xua; + uint32_t route_ctx, dest_ref, src_ref; + + route_ctx = xua_msg_get_u32(in, SUA_IEI_ROUTE_CTX); + /* get *source* reference and use as destination ref */ + dest_ref = xua_msg_get_u32(in, SUA_IEI_SRC_REF); + /* get *dest* reference and use as source ref */ + src_ref = xua_msg_get_u32(in, SUA_IEI_DEST_REF); + + xua = gen_relco(route_ctx, dest_ref, src_ref); + /* copy over the MTP parameters */ + xua->mtp.dpc = in->mtp.opc; + xua->mtp.opc = in->mtp.dpc; + xua->mtp.sio = in->mtp.sio; + + /* send to SCRC for transmission */ + sccp_scrc_rx_scoc_conn_msg(inst, xua); + xua_msg_free(xua); +} + +/* Generate a RLSD based in input arguments */ +static struct xua_msg *gen_rlsd(uint32_t route_ctx, uint32_t dest_ref, + uint32_t src_ref) +{ + struct xua_msg *xua = xua_msg_alloc(); + + xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_RELRE); + xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, route_ctx); + xua_msg_add_u32(xua, SUA_IEI_DEST_REF, dest_ref); + xua_msg_add_u32(xua, SUA_IEI_SRC_REF, src_ref); + + return xua; +} + +/* Generate a RLSD to both the remote side and the local conn */ +static void tx_rlsd_from_xua_twoway(struct sccp_connection *conn, + struct xua_msg *in) +{ + struct xua_msg *xua; + uint32_t route_ctx, dest_ref, src_ref; + + route_ctx = xua_msg_get_u32(in, SUA_IEI_ROUTE_CTX); + /* get *source* reference and use as destination ref */ + dest_ref = xua_msg_get_u32(in, SUA_IEI_SRC_REF); + /* get *source* reference and use as destination ref */ + src_ref = xua_msg_get_u32(in, SUA_IEI_DEST_REF); + + /* Generate RLSD towards remote peer */ + xua = gen_rlsd(route_ctx, dest_ref, src_ref); + /* copy over the MTP parameters */ + xua->mtp.dpc = in->mtp.opc; + xua->mtp.opc = in->mtp.dpc; + xua->mtp.sio = in->mtp.sio; + /* send to SCRC for transmission */ + sccp_scrc_rx_scoc_conn_msg(conn->inst, xua); + xua_msg_free(xua); + + /* Generate RLSD towards local peer */ + xua = gen_rlsd(conn->inst->route_ctx, conn->conn_id, conn->remote_ref); + xua->mtp.dpc = in->mtp.dpc; + xua->mtp.opc = conn->remote_pc; + xua->mtp.sio = in->mtp.sio; + osmo_fsm_inst_dispatch(conn->fi, SCOC_E_RCOC_RLSD_IND, xua); + xua_msg_free(xua); +} + +/* process received message for unasigned local reference */ +static void sccp_scoc_rx_unass_local_ref(struct osmo_sccp_instance *inst, + struct xua_msg *xua) +{ + /* we have received a message with unassigned destination local + * reference and thus apply the action indicated in Table + * B.2/Q.714 */ + switch (xua->hdr.msg_type) { + case SUA_CO_COAK: /* CC */ + case SUA_CO_COIT: /* IT */ + case SUA_CO_RESRE: /* RSR */ + case SUA_CO_RESCO: /* RSC */ + /* Send COERR */ + tx_coerr_from_xua(inst, xua, SCCP_ERROR_LRN_MISMATCH_UNASSIGNED); + break; + case SUA_CO_COREF: /* CREF */ + case SUA_CO_RELCO: /* RLC */ + case SUA_CO_CODT: /* DT1 */ + case SUA_CO_CODA: /* AK */ + case SUA_CO_COERR: /* ERR */ + /* DISCARD */ + break; + case SUA_CO_RELRE: /* RLSD */ + /* Send RLC */ + tx_relco_from_xua(inst, xua); + break; + default: + LOGP(DLSCCP, LOGL_NOTICE, "Unhandled %s\n", + xua_hdr_dump(xua, &xua_dialect_sua)); + break; + } +} + +/* process received message for invalid source local reference */ +static void sccp_scoc_rx_inval_src_ref(struct sccp_connection *conn, + struct xua_msg *xua) +{ + /* we have received a message with invalid source local + * reference and thus apply the action indicated in Table + * B.2/Q.714 */ + switch (xua->hdr.msg_type) { + case SUA_CO_RELRE: /* RLSD */ + case SUA_CO_RESRE: /* RSR */ + case SUA_CO_RESCO: /* RSC */ + /* Send ERR */ + tx_coerr_from_xua(conn->inst, xua, SCCP_ERROR_LRN_MISMATCH_INCONSISTENT); + break; + case SUA_CO_COIT: /* IT */ + /* FIXME: RLSD to both sides */ + tx_rlsd_from_xua_twoway(conn, xua); + break; + case SUA_CO_RELCO: /* RLC */ + /* DISCARD */ + break; + default: + LOGP(DLSCCP, LOGL_NOTICE, "Unhandled %s\n", + xua_hdr_dump(xua, &xua_dialect_sua)); + break; + } +} + +/* process received message for invalid origin point code */ +static void sccp_scoc_rx_inval_opc(struct osmo_sccp_instance *inst, + struct xua_msg *xua) +{ + /* we have received a message with invalid origin PC and thus + * apply the action indiacted in Table B.2/Q.714 */ + switch (xua->hdr.msg_type) { + case SUA_CO_RELRE: /* RLSD */ + case SUA_CO_RESRE: /* RSR */ + case SUA_CO_RESCO: /* RSC */ + /* Send ERR */ + tx_coerr_from_xua(inst, xua, SCCP_ERROR_POINT_CODE_MISMATCH); + break; + case SUA_CO_RELCO: /* RLC */ + case SUA_CO_CODT: /* DT1 */ + case SUA_CO_CODA: /* AK */ + case SUA_CO_COERR: /* ERR */ + /* DISCARD */ + break; + default: + LOGP(DLSCCP, LOGL_NOTICE, "Unhandled %s\n", + xua_hdr_dump(xua, &xua_dialect_sua)); + break; + } +} + +/*! \brief Main entrance function for primitives from the SCRC (Routing Control) + * \param[in] inst SCCP Instance in which we operate + * \param[in] xua SUA message in xua_msg format */ +void sccp_scoc_rx_from_scrc(struct osmo_sccp_instance *inst, + struct xua_msg *xua) +{ + struct sccp_connection *conn; + struct osmo_sccp_user *scu; + uint32_t src_loc_ref; + int event; + + /* we basically try to convert the SUA message into an event, + * and then dispatch the event to the connection-specific FSM. + * If it is a CORE (Connect REquest), we create the connection + * (and imlpicitly its FSM) first */ + + if (xua->hdr.msg_type == SUA_CO_CORE) { + scu = sccp_find_user(inst, xua); + if (!scu) { + /* this shouldn't happen, as the caller should + * have already verified that a local user is + * equipped for this SSN */ + LOGP(DLSCCP, LOGL_ERROR, "Cannot find user for " + "CORE ?!?\n"); + return; + } + /* Allocate new connection */ + conn = conn_create(inst); + conn->user = scu; + } else { + uint32_t conn_id; + /* Resolve existing connection */ + conn_id = xua_msg_get_u32(xua, SUA_IEI_DEST_REF); + conn = conn_find_by_id(inst, conn_id); + if (!conn) { + LOGP(DLSCCP, LOGL_NOTICE, "Cannot find connection for " + "local reference %u\n", conn_id); + sccp_scoc_rx_unass_local_ref(inst, xua); + return; + } + } + OSMO_ASSERT(conn); + OSMO_ASSERT(conn->fi); + + DEBUGP(DLSCCP, "Received %s for local reference %u\n", + xua_hdr_dump(xua, &xua_dialect_sua), conn->conn_id); + + if (xua->hdr.msg_type != SUA_CO_CORE && + xua->hdr.msg_type != SUA_CO_COAK && + xua->hdr.msg_type != SUA_CO_COREF) { + if (xua_msg_find_tag(xua, SUA_IEI_SRC_REF)) { + /* Check if received source local reference != + * the one we saved in local state */ + src_loc_ref = xua_msg_get_u32(xua, SUA_IEI_SRC_REF); + if (src_loc_ref != conn->remote_ref) { + sccp_scoc_rx_inval_src_ref(conn, xua); + return; + } + } + + /* Check if received OPC != the remote_pc we stored locally */ + if (xua->mtp.opc != conn->remote_pc) { + sccp_scoc_rx_inval_opc(inst, xua); + return; + } + } + + /* Map from XUA message to event */ + event = xua_msg_event_map(xua, sua_scoc_event_map, ARRAY_SIZE(sua_scoc_event_map)); + if (event < 0) { + LOGP(DLSCCP, LOGL_ERROR, "Cannot map SCRC msg %s to event\n", + xua_hdr_dump(xua, &xua_dialect_sua)); + /* Table B.1/Q714 states DISCARD for any message with + * unknown type */ + return; + } + + /* Dispatch event to existing connection */ + osmo_fsm_inst_dispatch(conn->fi, event, xua); +} + +/* get the Connection ID of the given SCU primitive */ +static uint32_t scu_prim_conn_id(const struct osmo_scu_prim *prim) +{ + switch (prim->oph.primitive) { + case OSMO_SCU_PRIM_N_CONNECT: + return prim->u.connect.conn_id; + case OSMO_SCU_PRIM_N_DATA: + return prim->u.data.conn_id; + case OSMO_SCU_PRIM_N_DISCONNECT: + return prim->u.disconnect.conn_id; + case OSMO_SCU_PRIM_N_RESET: + return prim->u.reset.conn_id; + default: + return 0; + } +} + +/*! \brief Main entrance function for primitives from SCCP User + * \param[in] scu SCCP User sending us the primitive + * \param[in] oph Osmocom primitive sent by the user + * \returns 0 on success; negative on error */ +int osmo_sccp_user_sap_down(struct osmo_sccp_user *scu, struct osmo_prim_hdr *oph) +{ + struct osmo_scu_prim *prim = (struct osmo_scu_prim *) oph; + struct osmo_sccp_instance *inst = scu->inst; + struct msgb *msg = prim->oph.msg; + struct sccp_connection *conn; + int rc = 0; + int event; + + LOGP(DLSCCP, LOGL_DEBUG, "Received SCCP User Primitive %s)\n", + osmo_scu_prim_name(&prim->oph)); + + switch (OSMO_PRIM_HDR(&prim->oph)) { + case OSMO_PRIM(OSMO_SCU_PRIM_N_UNITDATA, PRIM_OP_REQUEST): + /* other CL primitives? */ + /* Connectionless by-passes this altogether */ + return sccp_sclc_user_sap_down(scu, oph); + case OSMO_PRIM(OSMO_SCU_PRIM_N_CONNECT, PRIM_OP_REQUEST): + /* Allocate new connection structure */ + conn = conn_create_id(inst, prim->u.connect.conn_id); + if (!conn) { + /* FIXME: inform user */ + goto out; + } + conn->user = scu; + break; + case OSMO_PRIM(OSMO_SCU_PRIM_N_CONNECT, PRIM_OP_RESPONSE): + case OSMO_PRIM(OSMO_SCU_PRIM_N_DATA, PRIM_OP_REQUEST): + case OSMO_PRIM(OSMO_SCU_PRIM_N_DISCONNECT, PRIM_OP_REQUEST): + case OSMO_PRIM(OSMO_SCU_PRIM_N_RESET, PRIM_OP_REQUEST): + /* Resolve existing connection structure */ + conn = conn_find_by_id(inst, scu_prim_conn_id(prim)); + if (!conn) { + /* FIXME: inform user */ + goto out; + } + break; + } + + /* Map from primitive to event */ + event = osmo_event_for_prim(oph, scu_scoc_event_map); + + /* Dispatch event into connection */ + rc = osmo_fsm_inst_dispatch(conn->fi, event, prim); +out: + /* the SAP is supposed to consume the primitive/msgb */ + msgb_free(msg); + + return rc; +} + +void sccp_scoc_flush_connections(struct osmo_sccp_instance *inst) +{ + struct sccp_connection *conn, *conn2; + + llist_for_each_entry_safe(conn, conn2, &inst->connections, list) + conn_destroy(conn); +} diff --git a/src/sccp_scrc.c b/src/sccp_scrc.c new file mode 100644 index 0000000..9bccc0a --- /dev/null +++ b/src/sccp_scrc.c @@ -0,0 +1,473 @@ +/* SCCP Routing Control (SCRC) according to ITU-T Q.714 */ + +/* (C) 2015-2017 by Harald Welte + * All Rights reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include "sccp_internal.h" +#include "xua_internal.h" + +/*********************************************************************** + * Helper Functions + ***********************************************************************/ + +static bool sua_is_connectionless(struct xua_msg *xua) +{ + if (xua->hdr.msg_class == SUA_MSGC_CL) + return true; + else + return false; +} + +static bool sua_is_cr(struct xua_msg *xua) +{ + if (xua->hdr.msg_class == SUA_MSGC_CO && + xua->hdr.msg_type == SUA_CO_CORE) + return true; + + return false; +} + +static bool dpc_accessible(struct osmo_sccp_instance *inst, uint32_t pc) +{ + /* TODO: implement this! */ + return true; +} + +static bool sccp_available(struct osmo_sccp_instance *inst, + const struct osmo_sccp_addr *addr) +{ + /* TODO: implement this! */ + return true; +} + +static int sua2sccp_tx_m3ua(struct osmo_sccp_instance *inst, + struct xua_msg *sua) +{ + struct msgb *msg; + struct osmo_mtp_prim *omp; + struct osmo_mtp_transfer_param *param; + struct osmo_ss7_instance *s7i = inst->ss7; + uint32_t remote_pc = sua->mtp.dpc; + + /* 1) encode the SUA in xua_msg to SCCP message */ + msg = osmo_sua_to_sccp(sua); + if (!msg) { + LOGP(DLSCCP, LOGL_ERROR, "Cannot encode SUA to SCCP\n"); + return -1; + } + + /* 2) wrap into MTP-TRANSFER.req primtiive */ + msg->l2h = msg->data; + omp = (struct osmo_mtp_prim *) msgb_push(msg, sizeof(*omp)); + osmo_prim_init(&omp->oph, MTP_SAP_USER, + OSMO_MTP_PRIM_TRANSFER, PRIM_OP_REQUEST, msg); + param = &omp->u.transfer; + if (sua->mtp.opc) + param->opc = sua->mtp.opc; + else + param->opc = s7i->cfg.primary_pc; + param->dpc = remote_pc; + param->sls = sua->mtp.sls; + param->sio = MTP_SIO(MTP_SI_SCCP, s7i->cfg.network_indicator); + + /* 3) send via MTP-SAP (osmo_ss7_instance) */ + return osmo_ss7_user_mtp_xfer_req(s7i, omp); +} + +/* Gererate MTP-TRANSFER.req from xUA message */ +static int gen_mtp_transfer_req_xua(struct osmo_sccp_instance *inst, + struct xua_msg *xua, + const struct osmo_sccp_addr *called) +{ + struct osmo_ss7_route *rt; + + /* this is a bit fishy due to the different requirements of + * classic SSCP/MTP compared to various SIGTRAN stackings. + * Normally, we would expect a fully encoded SCCP message here, + * but then if the route points to a SUA link, we actually need + * the SUA version of the message. + * + * We need to differentiate the following cases: + * a) SUA: encode XUA to SUA and send via ASP + * b) M3UA: encode XUA to SCCP, create MTP-TRANSFER.req + * primitive and send it via ASP + * c) M2UA/M2PA or CS7: encode XUA, create MTP-TRANSFER.req + * primitive and send it via link + */ + + if (called->presence & OSMO_SCCP_ADDR_T_PC) + xua->mtp.dpc = called->pc; + if (!xua->mtp.dpc) { + LOGP(DLSCCP, LOGL_ERROR, "MTP-TRANSFER.req from SCCP " + "without DPC?!?\n"); + return -1; + } + + rt = osmo_ss7_route_lookup(inst->ss7, xua->mtp.dpc); + if (!rt) { + LOGP(DLSCCP, LOGL_ERROR, "MTP-TRANSFER.req from SCCP for " + "DPC %u: no route!\n", xua->mtp.dpc); + return -1; + } + + if (rt->dest.as) { + struct osmo_ss7_as *as = rt->dest.as; + switch (as->cfg.proto) { + case OSMO_SS7_ASP_PROT_M3UA: + return sua2sccp_tx_m3ua(inst, xua); + default: + LOGP(DLSCCP, LOGL_ERROR, "MTP-TRANSFER.req for " + "unknown protocol %u\n", as->cfg.proto); + break; + } + } else if (rt->dest.linkset) { + LOGP(DLSCCP, LOGL_ERROR, "MTP-TRANSFER.req from SCCP for " + "linkset %s unsupported\n", rt->dest.linkset->cfg.name); + } else { + OSMO_ASSERT(0); + } + return -1; +} + +/*********************************************************************** + * Global Title Translation + ***********************************************************************/ + +static int translate(struct osmo_sccp_instance *inst, + const struct osmo_sccp_addr *called, + struct osmo_sccp_addr *translated) +{ + /* TODO: implement this! */ + *translated = *called; + return 0; +} + + +/*********************************************************************** + * Individual SCRC Nodes + ***********************************************************************/ + +static int scrc_local_out_common(struct osmo_sccp_instance *inst, + struct xua_msg *xua, + const struct osmo_sccp_addr *called); + +static int scrc_node_12(struct osmo_sccp_instance *inst, struct xua_msg *xua, + const struct osmo_sccp_addr *called) +{ + /* TODO: Determine restriction */ + /* TODO: Treat Calling Party Addr */ + /* TODO: Hop counter */ + /* MTP-TRANSFER.req to MTP */ + return gen_mtp_transfer_req_xua(inst, xua, called); +} + +static int scrc_node_2(struct osmo_sccp_instance *inst, struct xua_msg *xua, + const struct osmo_sccp_addr *called) +{ + /* Node 2 on Sheet 5, only CO */ + /* Is DPC accessible? */ + if (!dpc_accessible(inst, called->pc)) { + /* Error: MTP Failure */ + /* Routing Failure SCRC -> SCOC */ + sccp_scoc_rx_scrc_rout_fail(inst, xua, + SCCP_RETURN_CAUSE_MTP_FAILURE); + return 0; + } + /* Is SCCP available? */ + if (!sccp_available(inst, called)) { + /* Error: SCCP Failure */ + /* Routing Failure SCRC -> SCOC */ + sccp_scoc_rx_scrc_rout_fail(inst, xua, + SCCP_RETURN_CAUSE_SCCP_FAILURE); + return 0; + } + return scrc_node_12(inst, xua, called); +} + +static int scrc_node_7(struct osmo_sccp_instance *inst, + struct xua_msg *xua, + const struct osmo_sccp_addr *called) +{ + /* Connection Oriented? */ + if (sua_is_connectionless(xua)) { + /* TODO: Perform Capability Test */ + /* TODO: Canges Needed? */ + if (0) { + /* Changes Needed -> SCLC */ + return 0; + } + } else { + /* TODO: Coupling Required? */ + if (0) { + /* Node 13 (Sheet 5) */ + } + } + return scrc_node_12(inst, xua, called); +} + +/* Node 4 (Sheet 3) */ +static int scrc_node_4(struct osmo_sccp_instance *inst, + struct xua_msg *xua, uint32_t return_cause) +{ + /* TODO: Routing Failure SCRC -> OMAP */ + if (sua_is_connectionless(xua)) { + /* Routing Failure SCRC -> SCLC */ + sccp_sclc_rx_scrc_rout_fail(inst, xua, return_cause); + } else { + /* Routing Failure SCRC -> SCOC */ + sccp_scoc_rx_scrc_rout_fail(inst, xua, return_cause); + } + return 0; +} + +static int scrc_translate_node_9(struct osmo_sccp_instance *inst, + struct xua_msg *xua, + const struct osmo_sccp_addr *called) +{ + struct osmo_sccp_addr translated; + int rc; + + /* Translate */ + rc = translate(inst, called, &translated); + /* Node 9 (Sheet 3) */ + if (rc < 0) { + /* Node 4 (Sheet 3) */ + return scrc_node_4(inst, xua, + SCCP_RETURN_CAUSE_NO_TRANSLATION); + } + /* Route on SSN? */ + if (translated.ri != OSMO_SCCP_RI_SSN_PC && + translated.ri != OSMO_SCCP_RI_SSN_IP) { + /* TODO: GT Routing */ + /* Node 7 (Sheet 5) */ + return scrc_node_7(inst, xua, called); + } + + /* Check DPC resultant from GT translation */ + if (osmo_ss7_pc_is_local(inst->ss7, translated.pc)) { + if (sua_is_connectionless(xua)) { + /* CL_MSG -> SCLC */ + sccp_sclc_rx_from_scrc(inst, xua); + } else { + /* Node 1 (Sheet 3) */ + /* CO_MSG -> SCOC */ + sccp_scoc_rx_from_scrc(inst, xua); + } + return 0; + } else { + /* Availability already checked */ + /* Node 7 (Sheet 5) */ + return scrc_node_7(inst, xua, called); + } +} + +/* Node 6 (Sheet 3) */ +static int scrc_node_6(struct osmo_sccp_instance *inst, + struct xua_msg *xua, + const struct osmo_sccp_addr *called) +{ + struct osmo_sccp_user *scu; + + scu = sccp_user_find(inst, called->ssn, called->pc); + + /* Is subsystem equipped? */ + if (!scu) { + /* Error: unequipped user */ + return scrc_node_4(inst, xua, + SCCP_RETURN_CAUSE_UNEQUIPPED_USER); + } + /* Is subsystem available? */ + if (0 /* !subsys_available(scu) */) { + /* Error: subsystem failure */ + /* TODO: SCRC -> SSPC */ + if (sua_is_connectionless(xua)) { + /* Routing Failure SCRC -> SCLC */ + sccp_sclc_rx_scrc_rout_fail(inst, xua, + SCCP_RETURN_CAUSE_SUBSYSTEM_FAILURE); + } else { + /* Routing Failure SCRC -> SCOC */ + sccp_scoc_rx_scrc_rout_fail(inst, xua, + SCCP_RETURN_CAUSE_SUBSYSTEM_FAILURE); + } + return 0; + } + if (sua_is_connectionless(xua)) { + /* CL_MSG -> SCLC */ + sccp_sclc_rx_from_scrc(inst, xua); + } else { + /* Node 1 (Sheet 3) */ + /* CO_MSG -> SCOC */ + sccp_scoc_rx_from_scrc(inst, xua); + } + return 0; +} + +static int scrc_local_out_common(struct osmo_sccp_instance *inst, + struct xua_msg *xua, + const struct osmo_sccp_addr *called) +{ + struct osmo_ss7_instance *s7i = inst->ss7; + + /* Called address includes DPC? */ + if (called->presence & OSMO_SCCP_ADDR_T_PC) { + if (!osmo_ss7_pc_is_local(s7i, called->pc)) { + /* Node 7 of sheet 5 */ + /* Coupling required: no */ + return scrc_node_12(inst, xua, called); + } + /* Called address includes SSN? */ + if (called->presence & OSMO_SCCP_ADDR_T_SSN) { + if (translate && + (called->presence & OSMO_SCCP_ADDR_T_GT)) + return scrc_translate_node_9(inst, xua, called); + else + return scrc_node_6(inst, xua, called); + } + } + /* No SSN in CalledAddr or no DPC included */ + if (!(called->presence & OSMO_SCCP_ADDR_T_GT)) { + /* Error reason: Unqualified */ + /* TODO: Routing Failure SCRC -> OMAP */ + /* Node 4 (Sheet 3) */ + return scrc_node_4(inst, xua, + SCCP_RETURN_CAUSE_UNQUALIFIED); + } else + return scrc_translate_node_9(inst, xua, called); +} + +/*********************************************************************** + * Entrance points from MTP, SCLC, SCOC, ... + ***********************************************************************/ + +/* Figure C.1/Q.714 - SCCP Routing control procedures (SCRC) */ + +/* Connection oriented message SCOC -> SCRC */ +int sccp_scrc_rx_scoc_conn_msg(struct osmo_sccp_instance *inst, + struct xua_msg *xua) +{ + struct osmo_sccp_addr called; + + LOGP(DLSS7, LOGL_DEBUG, "%s: %s\n", __func__, xua_msg_dump(xua, &xua_dialect_sua)); + + sua_addr_parse(&called, xua, SUA_IEI_DEST_ADDR); + + /* Is this a CR message ? */ + if (xua->hdr.msg_type != SUA_CO_CORE) + return scrc_node_2(inst, xua, &called); + + /* TOOD: Coupling performed (not supported) */ + if (0) + return scrc_node_2(inst, xua, &called); + + return scrc_local_out_common(inst, xua, &called); +} + +/* Connectionless Message SCLC -> SCRC */ +int sccp_scrc_rx_sclc_msg(struct osmo_sccp_instance *inst, + struct xua_msg *xua) +{ + struct osmo_sccp_addr called; + + LOGP(DLSS7, LOGL_DEBUG, "%s: %s\n", __func__, xua_msg_dump(xua, &xua_dialect_sua)); + + sua_addr_parse(&called, xua, SUA_IEI_DEST_ADDR); + + /* Message Type */ + if (xua->hdr.msg_type == SUA_CL_CLDR) { + /* UDTS, XUDTS or LUDTS */ + if (called.ri != OSMO_SCCP_RI_GT) + return scrc_node_7(inst, xua, &called); + /* Fall-through */ + } else { + if (0 /* TODO: translation already performed */) { + /* Node 12 (Sheet 5) */ + return scrc_node_12(inst, xua, &called); + } + } + return scrc_local_out_common(inst, xua, &called); +} + +/* Figure C.1/Q.714 Sheet 1 of 12, after we converted the + * MTP-TRANSFER.ind to SUA */ +int scrc_rx_mtp_xfer_ind_xua(struct osmo_sccp_instance *inst, + struct xua_msg *xua) +{ + struct osmo_sccp_addr called; + uint32_t proto_class; + struct xua_msg_part *hop_ctr_part; + + LOGP(DLSS7, LOGL_DEBUG, "%s: %s\n", __func__, xua_msg_dump(xua, &xua_dialect_sua)); + /* TODO: SCCP or nodal congestion? */ + + /* CR or CL message? */ + if (!sua_is_connectionless(xua) && !sua_is_cr(xua)) { + /* Node 1 (Sheet 3) */ + /* deliver to SCOC */ + sccp_scoc_rx_from_scrc(inst, xua); + return 0; + } + /* We only treat connectionless and CR below */ + + sua_addr_parse(&called, xua, SUA_IEI_DEST_ADDR); + + /* Route on GT? */ + if (called.ri != OSMO_SCCP_RI_GT) { + /* Node 6 (Sheet 3) */ + return scrc_node_6(inst, xua, &called); + } + /* Message with hop-counter? */ + hop_ctr_part = xua_msg_find_tag(xua, SUA_IEI_S7_HOP_CTR); + if (hop_ctr_part) { + uint32_t hop_counter = xua_msg_part_get_u32(hop_ctr_part); + if (hop_counter <= 1) { + /* Error: hop-counter violation */ + /* node 4 */ + return scrc_node_4(inst, xua, + SCCP_RETURN_CAUSE_HOP_COUNTER_VIOLATION); + } + /* Decrement hop-counter */ + hop_counter--; + *(uint32_t *)hop_ctr_part->dat = htonl(hop_counter); + } + + /* node 3 (Sheet 2) */ + /* Protocol class 0? */ + proto_class = xua_msg_get_u32(xua, SUA_IEI_PROTO_CLASS); + switch (proto_class) { + case 0: + /* TODO: Assign SLS */ + break; + case 1: + /* TODO: Map incoming SLS to outgoing SLS */ + break; + default: + break; + } + return scrc_translate_node_9(inst, xua, &called); +} diff --git a/src/sccp_user.c b/src/sccp_user.c new file mode 100644 index 0000000..df02486 --- /dev/null +++ b/src/sccp_user.c @@ -0,0 +1,377 @@ +/* SCCP User related routines */ + +/* (C) 2017 by Harald Welte + * All Rights Reserved + * + * based on my 2011 Erlang implementation osmo_ss7/src/sua_sccp_conv.erl + * + * References: ITU-T Q.713 and IETF RFC 3868 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include + +#include +#include + +#include +#include +#include +#include + +#include "sccp_internal.h" +#include "xua_internal.h" + +/*! \brief Find a SCCP User registered for given PC+SSN or SSN only + * \param[in] inst SCCP Instance in which to search + * \param[in] ssn Sub-System Number to search for + * \param[in] pc Point Code to search for + * \returns Matching SCCP User; NULL if none found */ +struct osmo_sccp_user * +sccp_user_find(struct osmo_sccp_instance *inst, uint16_t ssn, uint32_t pc) +{ + struct osmo_sccp_user *scu; + + /* First try to find match for PC + SSN */ + llist_for_each_entry(scu, &inst->users, list) { + if (scu->pc_valid && scu->pc == pc && scu->ssn == ssn) + return scu; + } + + /* Then try to match on SSN only */ + llist_for_each_entry(scu, &inst->users, list) { + if (!scu->pc_valid && scu->ssn == ssn) + return scu; + } + + return NULL; +} + +/*! \brief Bind a SCCP User to a given Point Code + * \param[in] inst SCCP Instance + * \param[in] name human-readable name + * \param[in] ssn Sub-System Number to bind to + * \param[in] pc Point Code to bind to (if any) + * \param[in] pc_valid Whether or not \ref pc is valid/used + * \returns Callee-allocated SCCP User on success; negative otherwise */ +static struct osmo_sccp_user * +sccp_user_bind_pc(struct osmo_sccp_instance *inst, const char *name, + osmo_prim_cb prim_cb, uint16_t ssn, uint32_t pc, bool pc_valid) +{ + struct osmo_sccp_user *scu; + if (!pc_valid) + pc = 0; + + if (sccp_user_find(inst, ssn, pc)) + return NULL; + + LOGP(DLSCCP, LOGL_INFO, "Binding user '%s' to SSN=%u PC=%u (pc_valid=%u)\n", + name, ssn, pc, pc_valid); + + scu = talloc_zero(inst, struct osmo_sccp_user); + scu->name = talloc_strdup(scu, name); + scu->inst = inst; + scu->prim_cb = prim_cb; + scu->ssn = ssn; + scu->pc = pc; + scu->pc_valid = pc_valid; + llist_add_tail(&scu->list, &inst->users); + + return scu; +} + +/*! \brief Bind a given SCCP User to a given SSN+PC + * \param[in] inst SCCP Instance + * \param[in] name human-readable name + * \param[in] ssn Sub-System Number to bind to + * \param[in] pc Point Code to bind to (if any) + * \returns Callee-allocated SCCP User on success; negative otherwise */ +struct osmo_sccp_user * +osmo_sccp_user_bind_pc(struct osmo_sccp_instance *inst, const char *name, + osmo_prim_cb prim_cb, uint16_t ssn, uint32_t pc) +{ + return sccp_user_bind_pc(inst, name, prim_cb, ssn, pc, true); +} + +/*! \brief Bind a given SCCP User to a given SSN (at any PC) + * \param[in] inst SCCP Instance + * \param[in] name human-readable name + * \param[in] ssn Sub-System Number to bind to + * \returns Callee-allocated SCCP User on success; negative otherwise */ +struct osmo_sccp_user * +osmo_sccp_user_bind(struct osmo_sccp_instance *inst, const char *name, + osmo_prim_cb prim_cb, uint16_t ssn) +{ + return sccp_user_bind_pc(inst, name, prim_cb, ssn, 0, false); +} + +/*! \brief Unbind a given SCCP user + * \param[in] scu SCCP User which is to be un-bound. Will be destroyed + * at the time this function returns. */ +void osmo_sccp_user_unbind(struct osmo_sccp_user *scu) +{ + LOGP(DLSCCP, LOGL_INFO, "Unbinding user '%s' from SSN=%u PC=%u " + "(pc_valid=%u)\n", scu->name, scu->ssn, scu->pc, + scu->pc_valid); + /* FIXME: free/release all connections held by this user? */ + llist_del(&scu->list); + talloc_free(scu); +} + +/*! \brief Send a SCCP User SAP Primitive up to the User + * \param[in] scu SCCP User to whom to send the primitive + * \param[in] prim Primitive to send to the user + * \returns return value of the SCCP User's prim_cb() function */ +int sccp_user_prim_up(struct osmo_sccp_user *scu, struct osmo_scu_prim *prim) +{ + LOGP(DLSCCP, LOGL_DEBUG, "Delivering %s to SCCP User '%s'\n", + osmo_scu_prim_name(&prim->oph), scu->name); + return scu->prim_cb(&prim->oph, scu); +} + +/* prim_cb handed to MTP code for incoming MTP-TRANSFER.ind */ +static int mtp_user_prim_cb(struct osmo_prim_hdr *oph, void *ctx) +{ + struct osmo_sccp_instance *inst = ctx; + struct osmo_mtp_prim *omp = (struct osmo_mtp_prim *)oph; + struct xua_msg *xua; + + OSMO_ASSERT(oph->sap == MTP_SAP_USER); + + switch OSMO_PRIM(oph->primitive, oph->operation) { + case OSMO_PRIM(OSMO_MTP_PRIM_TRANSFER, PRIM_OP_INDICATION): + /* Convert from SCCP to SUA in xua_msg format */ + xua = osmo_sccp_to_xua(oph->msg); + xua->mtp = omp->u.transfer; + /* hand this primitive into SCCP via the SCRC code */ + return scrc_rx_mtp_xfer_ind_xua(inst, xua); + default: + LOGP(DLSCCP, LOGL_ERROR, "Unknown primitive %u:%u receivd\n", + oph->primitive, oph->operation); + return -1; + } +} + +static LLIST_HEAD(sccp_instances); + +/*! \brief create a SCCP Instance and register it as user with SS7 inst + * \param[in] ss7 SS7 instance to which this SCCP instance belongs + * \param[in] priv private data to be stored within SCCP instance + * \returns callee-allocated SCCP instance on success; NULL on error */ +struct osmo_sccp_instance * +osmo_sccp_instance_create(struct osmo_ss7_instance *ss7, void *priv) +{ + struct osmo_sccp_instance *inst; + + inst = talloc_zero(ss7, struct osmo_sccp_instance); + if (!inst) + return NULL; + + inst->ss7 = ss7; + inst->priv = priv; + INIT_LLIST_HEAD(&inst->connections); + INIT_LLIST_HEAD(&inst->users); + + inst->ss7_user.inst = ss7; + inst->ss7_user.name = "SCCP"; + inst->ss7_user.prim_cb = mtp_user_prim_cb; + inst->ss7_user.priv = inst; + + osmo_ss7_user_register(ss7, MTP_SI_SCCP, &inst->ss7_user); + + llist_add_tail(&inst->list, &sccp_instances); + + return inst; +} + +void osmo_sccp_instance_destroy(struct osmo_sccp_instance *inst) +{ + struct osmo_sccp_user *scu, *scu2; + + inst->ss7->sccp = NULL; + osmo_ss7_user_unregister(inst->ss7, MTP_SI_SCCP, &inst->ss7_user); + + llist_for_each_entry_safe(scu, scu2, &inst->users, list) { + osmo_sccp_user_unbind(scu); + } + sccp_scoc_flush_connections(inst); + llist_del(&inst->list); + talloc_free(inst); +} + +/*********************************************************************** + * Convenience function for CLIENT + ***********************************************************************/ + +struct osmo_sccp_instance * +osmo_sccp_simple_client(void *ctx, const char *name, uint32_t pc, + enum osmo_ss7_asp_protocol prot, + int local_port, int remote_port, const char *remote_ip) +{ + struct osmo_ss7_instance *ss7; + struct osmo_ss7_as *as; + struct osmo_ss7_route *rt; + struct osmo_ss7_asp *asp; + char *as_name, *asp_name; + + if (!remote_port || remote_port < 0) + remote_port = osmo_ss7_asp_protocol_port(prot); + if (local_port < 0) + local_port = osmo_ss7_asp_protocol_port(prot); + + /* allocate + initialize SS7 instance */ + ss7 = osmo_ss7_instance_find_or_create(ctx, 1); + if (!ss7) + return NULL; + ss7->cfg.primary_pc = pc; + + as_name = talloc_asprintf(ctx, "as-clnt-%s", name); + asp_name = talloc_asprintf(ctx, "asp-clnt-%s", name); + + /* application server */ + as = osmo_ss7_as_find_or_create(ss7, as_name, prot); + if (!as) + goto out_strings; + + /* install default route */ + rt = osmo_ss7_route_create(ss7->rtable_system, 0, 0, as_name); + if (!rt) + goto out_as; + talloc_free(as_name); + + /* application server process */ + asp = osmo_ss7_asp_find_or_create(ss7, asp_name, remote_port, local_port, + prot); + if (!asp) + goto out_rt; + asp->cfg.remote.host = talloc_strdup(asp, remote_ip); + osmo_ss7_as_add_asp(as, asp_name); + talloc_free(asp_name); + osmo_ss7_asp_restart(asp); + + /* Allocate SCCP stack + SCCP user */ + ss7->sccp = osmo_sccp_instance_create(ss7, NULL); + if (!ss7->sccp) + goto out_asp; + + return ss7->sccp; + +out_asp: + osmo_ss7_asp_destroy(asp); +out_rt: + osmo_ss7_route_destroy(rt); +out_as: + osmo_ss7_as_destroy(as); +out_strings: + talloc_free(as_name); + talloc_free(asp_name); + osmo_ss7_instance_destroy(ss7); + + return NULL; +} + +/*********************************************************************** + * Convenience function for SERVER + ***********************************************************************/ + +struct osmo_sccp_instance * +osmo_sccp_simple_server(void *ctx, uint32_t pc, + enum osmo_ss7_asp_protocol prot, int local_port, + const char *local_ip) +{ + struct osmo_ss7_instance *ss7; + struct osmo_xua_server *xs; + + if (local_port < 0) + local_port = osmo_ss7_asp_protocol_port(prot); + + /* allocate + initialize SS7 instance */ + ss7 = osmo_ss7_instance_find_or_create(ctx, 1); + if (!ss7) + return NULL; + ss7->cfg.primary_pc = pc; + + xs = osmo_ss7_xua_server_create(ss7, prot, local_port, local_ip); + if (!xs) + goto out_ss7; + + /* Allocate SCCP stack */ + ss7->sccp = osmo_sccp_instance_create(ss7, NULL); + if (!ss7->sccp) + goto out_xs; + + return ss7->sccp; + +out_xs: + osmo_ss7_xua_server_destroy(xs); +out_ss7: + osmo_ss7_instance_destroy(ss7); + + return NULL; +} + +struct osmo_sccp_instance * +osmo_sccp_simple_server_add_clnt(struct osmo_sccp_instance *inst, + enum osmo_ss7_asp_protocol prot, + const char *name, uint32_t pc, + int local_port, int remote_port, + const char *remote_ip) +{ + struct osmo_ss7_instance *ss7 = inst->ss7; + struct osmo_ss7_as *as; + struct osmo_ss7_route *rt; + struct osmo_ss7_asp *asp; + char *as_name, *asp_name; + + if (local_port < 0) + local_port = osmo_ss7_asp_protocol_port(prot); + + if (remote_port < 0) + remote_port = osmo_ss7_asp_protocol_port(prot); + + as_name = talloc_asprintf(ss7, "as-srv-%s", name); + asp_name = talloc_asprintf(ss7, "asp-srv-%s", name); + + /* application server */ + as = osmo_ss7_as_find_or_create(ss7, as_name, prot); + if (!as) + goto out_strings; + talloc_free(as_name); + + /* route only selected PC to the client */ + rt = osmo_ss7_route_create(ss7->rtable_system, pc, 0xffff, as_name); + if (!rt) + goto out_as; + + asp = osmo_ss7_asp_find_or_create(ss7, asp_name, remote_port, local_port, prot); + if (!asp) + goto out_rt; + asp->cfg.is_server = true; + osmo_ss7_as_add_asp(as, asp_name); + talloc_free(asp_name); + osmo_ss7_asp_restart(asp); + + return ss7->sccp; + +out_rt: + osmo_ss7_route_destroy(rt); +out_as: + osmo_ss7_as_destroy(as); +out_strings: + talloc_free(as_name); + talloc_free(asp_name); + + return NULL; +} -- To view, visit https://gerrit.osmocom.org/2215 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I916e895d9a4914b05483fe12ab5251f206d10dee Gerrit-PatchSet: 3 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Apr 4 12:13:06 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 4 Apr 2017 12:13:06 +0000 Subject: [PATCH] libosmo-abis[master]: Fix HAVE_ORTP_LOG_DOMAIN detection on FreeBSD Message-ID: Review at https://gerrit.osmocom.org/2222 Fix HAVE_ORTP_LOG_DOMAIN detection on FreeBSD We need to use the include path[s] resolved by pkg-config for ortp before trying to compile our test program. Without this patch, compilation will fail e.g. on FreeBSD 11. Change-Id: I0c95e37cc449297389bf31dd9d5dcaa922d75d0c --- M configure.ac 1 file changed, 3 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-abis refs/changes/22/2222/1 diff --git a/configure.ac b/configure.ac index 43266be..574aa2e 100644 --- a/configure.ac +++ b/configure.ac @@ -59,6 +59,8 @@ CPPFLAGS+=" -fsanitize=address -fsanitize=undefined" fi +_cflags_save=$CFLAGS +CFLAGS=$ORTP_CFLAGS AC_COMPILE_IFELSE( [AC_LANG_PROGRAM( [[#include ]], @@ -68,6 +70,7 @@ [ortp_set_log_level_mask requires domain parameter])], [AC_DEFINE([HAVE_ORTP_LOG_DOMAIN], [0], [ortp_set_log_level_mask has no domain parameter])]) +CFLAGS=$_cflags_save AC_OUTPUT( libosmoabis.pc -- To view, visit https://gerrit.osmocom.org/2222 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I0c95e37cc449297389bf31dd9d5dcaa922d75d0c Gerrit-PatchSet: 1 Gerrit-Project: libosmo-abis Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Tue Apr 4 12:13:46 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 4 Apr 2017 12:13:46 +0000 Subject: libosmo-sccp[master]: xua_msg: Add support for msg_event_maps In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2208 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Iee1c7fc2bf64219ebb71a0dbe6fd210749332413 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Apr 4 12:14:03 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 4 Apr 2017 12:14:03 +0000 Subject: libosmo-sccp[master]: xua: Remove library-internal DXUA log subsystem In-Reply-To: References: Message-ID: Patch Set 3: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2220 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Iea0d3db34a3674a9c6422b174a879bfdaa25786f Gerrit-PatchSet: 3 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Apr 4 12:14:14 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 4 Apr 2017 12:14:14 +0000 Subject: libosmo-sccp[master]: Add example program how to use M3UA+SCCP client and server In-Reply-To: References: Message-ID: Patch Set 3: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2219 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Id698ce2da5726e304dfa1773b794671dc80d853c Gerrit-PatchSet: 3 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Apr 4 12:14:30 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 4 Apr 2017 12:14:30 +0000 Subject: libosmo-sccp[master]: xua_msg: Add xua_msg_free_tag() and xua_msg_copy_part() In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2196 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I083634db9c3606bcff87700f253054a38a20816d Gerrit-PatchSet: 2 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Apr 4 12:14:59 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 4 Apr 2017 12:14:59 +0000 Subject: libosmo-sccp[master]: sua: Extend address parsing with GT, RI and IPv4 support In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2211 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I186df77cbdbedfe1a60b855be3626b6766f4681c Gerrit-PatchSet: 2 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Apr 4 12:15:11 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 4 Apr 2017 12:15:11 +0000 Subject: libosmo-sccp[master]: sua.c: Replace sua_msgb_alloc() with new sccp_msgb_alloc() In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2212 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I7067a85dcc5dda66f4b17b0fe08da8cb3efe79ef Gerrit-PatchSet: 2 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Apr 4 12:15:20 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 4 Apr 2017 12:15:20 +0000 Subject: libosmo-sccp[master]: Add SCCP <-> SUA message transcoding routines In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2213 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I8151a9b08a0b0ca97b9c73105ad4548512ce3be8 Gerrit-PatchSet: 2 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Apr 4 12:15:25 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 4 Apr 2017 12:15:25 +0000 Subject: libosmo-sccp[master]: Add tests for xUA code + SCCP/SUA transcoding In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2214 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I7ce038d72dca18fb83d5a12519c9a48267e52ab8 Gerrit-PatchSet: 2 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Apr 4 12:15:29 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 4 Apr 2017 12:15:29 +0000 Subject: libosmo-sccp[master]: Add new SCCP implementation In-Reply-To: References: Message-ID: Patch Set 3: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2215 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I916e895d9a4914b05483fe12ab5251f206d10dee Gerrit-PatchSet: 3 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Apr 4 12:15:32 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 4 Apr 2017 12:15:32 +0000 Subject: libosmo-sccp[master]: remove tests/sigtran: it's not a test case In-Reply-To: References: Message-ID: Patch Set 3: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2216 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ie471a197856c875eb4987bf9858d757312de24fb Gerrit-PatchSet: 3 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Apr 4 12:15:35 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 4 Apr 2017 12:15:35 +0000 Subject: libosmo-sccp[master]: sccp_sap license header was missing In-Reply-To: References: Message-ID: Patch Set 3: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2217 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I442634ca74d9c4cd386726a9d6b933a12f45afc5 Gerrit-PatchSet: 3 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Apr 4 12:15:37 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 4 Apr 2017 12:15:37 +0000 Subject: libosmo-sccp[master]: SUA: Port to new osmo_ss7 and SCCP code In-Reply-To: References: Message-ID: Patch Set 3: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2218 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I193b74f58aa70c443ae17e78b5604246d6bc3f71 Gerrit-PatchSet: 3 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Apr 4 12:16:48 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 4 Apr 2017 12:16:48 +0000 Subject: libosmo-sccp[master]: sua: Make use of xua_msg_dialect In-Reply-To: References: Message-ID: Patch Set 2: Code-Review-2 -- To view, visit https://gerrit.osmocom.org/2210 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I966103f30b9be247ba6905ba8e06b87654d9981a Gerrit-PatchSet: 2 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Apr 4 12:17:03 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 4 Apr 2017 12:17:03 +0000 Subject: libosmo-sccp[master]: sua: Extend address parsing with GT, RI and IPv4 support In-Reply-To: References: Message-ID: Patch Set 2: Code-Review-2 -- To view, visit https://gerrit.osmocom.org/2211 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I186df77cbdbedfe1a60b855be3626b6766f4681c Gerrit-PatchSet: 2 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Apr 4 12:19:19 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 4 Apr 2017 12:19:19 +0000 Subject: libosmo-abis[master]: Fix HAVE_ORTP_LOG_DOMAIN detection on FreeBSD In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2222 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I0c95e37cc449297389bf31dd9d5dcaa922d75d0c Gerrit-PatchSet: 1 Gerrit-Project: libosmo-abis Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Apr 4 12:20:51 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 4 Apr 2017 12:20:51 +0000 Subject: osmo-bts[master]: Use system-installed pcuif_proto.h instead of local copy In-Reply-To: References: Message-ID: Patch Set 8: Code-Review-2 actally, I think after some delibration I'll abandon this. I think we should use copies of the respective files. This way we at least ensure that each project has everything it needs locally within the repo to compile. Whether the result is compatible with what has been built elsewehre is a different question, but that's basically than the job of runtime version detection to figure out (and abort if needed). -- To view, visit https://gerrit.osmocom.org/1258 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I4dd2537aeef60c7d154e90f279dc4e7c2392ff76 Gerrit-PatchSet: 8 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Apr 4 12:21:09 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 4 Apr 2017 12:21:09 +0000 Subject: [ABANDON] osmo-bts[master]: Use system-installed pcuif_proto.h instead of local copy In-Reply-To: References: Message-ID: Harald Welte has abandoned this change. Change subject: Use system-installed pcuif_proto.h instead of local copy ...................................................................... Abandoned see last review comment. New strategy. -- To view, visit https://gerrit.osmocom.org/1258 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: abandon Gerrit-Change-Id: I4dd2537aeef60c7d154e90f279dc4e7c2392ff76 Gerrit-PatchSet: 8 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Tue Apr 4 12:21:35 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 4 Apr 2017 12:21:35 +0000 Subject: [ABANDON] libosmocore[master]: vty/vty.c: Check return value of tc{get, set}attr() calls In-Reply-To: References: Message-ID: Harald Welte has abandoned this change. Change subject: vty/vty.c: Check return value of tc{get,set}attr() calls ...................................................................... Abandoned not the right solution -- To view, visit https://gerrit.osmocom.org/1298 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: abandon Gerrit-Change-Id: I488ebf882ea12d5f9136563234c0da1018ea2ccd Gerrit-PatchSet: 2 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Apr 4 12:34:54 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 4 Apr 2017 12:34:54 +0000 Subject: [PATCH] libosmo-abis[master]: Fix HAVE_ORTP_LOG_DOMAIN detection on FreeBSD In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2222 to look at the new patch set (#2). Fix HAVE_ORTP_LOG_DOMAIN detection on FreeBSD We need to use the include path[s] resolved by pkg-config for ortp before trying to compile our test program. Without this patch, compilation will fail e.g. on FreeBSD 11. Change-Id: I0c95e37cc449297389bf31dd9d5dcaa922d75d0c --- M configure.ac 1 file changed, 3 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-abis refs/changes/22/2222/2 diff --git a/configure.ac b/configure.ac index 43266be..9b2f189 100644 --- a/configure.ac +++ b/configure.ac @@ -59,6 +59,8 @@ CPPFLAGS+=" -fsanitize=address -fsanitize=undefined" fi +_cflags_save=$CFLAGS +CFLAGS="$CFLAGS $ORTP_CFLAGS" AC_COMPILE_IFELSE( [AC_LANG_PROGRAM( [[#include ]], @@ -68,6 +70,7 @@ [ortp_set_log_level_mask requires domain parameter])], [AC_DEFINE([HAVE_ORTP_LOG_DOMAIN], [0], [ortp_set_log_level_mask has no domain parameter])]) +CFLAGS=$_cflags_save AC_OUTPUT( libosmoabis.pc -- To view, visit https://gerrit.osmocom.org/2222 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I0c95e37cc449297389bf31dd9d5dcaa922d75d0c Gerrit-PatchSet: 2 Gerrit-Project: libosmo-abis Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Apr 4 12:40:59 2017 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Tue, 4 Apr 2017 12:40:59 +0000 Subject: [PATCH] libosmocore[master]: gsm0808: Add utils for AoIP Transport Layer Address In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2176 to look at the new patch set (#3). gsm0808: Add utils for AoIP Transport Layer Address The planned support for true A over IP requires the encoding and decoding of a so called "AoIP Transport Layer Address" element. This commt adds parsing functionality and tests for the element mentioned above, however, it is not yet actively used. Change-Id: I57933b0a06a3f54ec2a41e6ecb6ced9fbbc89332 --- M include/Makefile.am A include/osmocom/gsm/gsm0808_utils.h M src/gsm/Makefile.am A src/gsm/gsm0808_utils.c M src/gsm/libosmogsm.map M tests/gsm0808/gsm0808_test.c 6 files changed, 220 insertions(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/76/2176/3 diff --git a/include/Makefile.am b/include/Makefile.am index e2a1b12..0383d7a 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -77,6 +77,7 @@ osmocom/coding/gsm0503_interleaving.h \ osmocom/coding/gsm0503_coding.h \ osmocom/gsm/gsm0808.h \ + osmocom/gsm/gsm0808_utils.h \ osmocom/gsm/gsm23003.h \ osmocom/gsm/gsm48.h \ osmocom/gsm/gsm48_ie.h \ diff --git a/include/osmocom/gsm/gsm0808_utils.h b/include/osmocom/gsm/gsm0808_utils.h new file mode 100644 index 0000000..2dcab25 --- /dev/null +++ b/include/osmocom/gsm/gsm0808_utils.h @@ -0,0 +1,30 @@ +/* (C) 2016 by Sysmocom s.f.m.c. GmbH + * All Rights Reserved + * + * Author: Philipp Maier + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#include + +/* Encode AoIP transport address element */ +uint8_t gsm0808_enc_aoip_trasp_addr(struct msgb *msg, + struct sockaddr_storage *ss); + +/* Decode AoIP transport address element */ +int gsm0808_dec_aoip_trasp_addr(struct sockaddr_storage *ss, + const uint8_t *elem, uint8_t len); diff --git a/src/gsm/Makefile.am b/src/gsm/Makefile.am index 3a4a0cd..e64c9e7 100644 --- a/src/gsm/Makefile.am +++ b/src/gsm/Makefile.am @@ -25,7 +25,7 @@ auth_milenage.c milenage/aes-encblock.c gea.c \ milenage/aes-internal.c milenage/aes-internal-enc.c \ milenage/milenage.c gan.c ipa.c gsm0341.c apn.c \ - gsup.c gprs_gea.c gsm0503_conv.c oap.c + gsup.c gprs_gea.c gsm0503_conv.c oap.c gsm0808_utils.c libgsmint_la_LDFLAGS = -no-undefined libgsmint_la_LIBADD = $(top_builddir)/src/libosmocore.la diff --git a/src/gsm/gsm0808_utils.c b/src/gsm/gsm0808_utils.c new file mode 100644 index 0000000..6177086 --- /dev/null +++ b/src/gsm/gsm0808_utils.c @@ -0,0 +1,122 @@ +/* (C) 2016 by Sysmocom s.f.m.c. GmbH + * All Rights Reserved + * + * Author: Philipp Maier + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define IP_V4_ADDR_LEN 4 +#define IP_V6_ADDR_LEN 16 +#define IP_PORT_LEN 2 + +/* Encode AoIP transport address element */ +uint8_t gsm0808_enc_aoip_trasp_addr(struct msgb *msg, + struct sockaddr_storage *ss) +{ + /* See also 3GPP TS 48.008 3.2.2.102 AoIP Transport Layer Address */ + struct sockaddr_in *sin; + struct sockaddr_in6 *sin6; + uint16_t port = 0; + uint8_t *ptr; + uint8_t *old_tail; + uint8_t *tlv_len; + + OSMO_ASSERT(msg); + OSMO_ASSERT(ss); + OSMO_ASSERT(ss->ss_family == AF_INET || ss->ss_family == AF_INET6); + + msgb_put_u8(msg, GSM0808_IE_AOIP_TRASP_ADDR); + tlv_len = msgb_put(msg,1); + old_tail = msg->tail; + + switch (ss->ss_family) { + case AF_INET: + sin = (struct sockaddr_in *)ss; + port = ntohs(sin->sin_port); + ptr = msgb_put(msg, IP_V4_ADDR_LEN); + memcpy(ptr, &sin->sin_addr.s_addr, IP_V4_ADDR_LEN); + break; + case AF_INET6: + sin6 = (struct sockaddr_in6 *)ss; + port = ntohs(sin6->sin6_port); + ptr = msgb_put(msg, IP_V6_ADDR_LEN); + memcpy(ptr, sin6->sin6_addr.s6_addr, IP_V6_ADDR_LEN); + break; + } + + msgb_put_u16(msg, port); + + *tlv_len = (uint8_t) (msg->tail - old_tail); + return *tlv_len + 2; +} + +/* Decode AoIP transport address element */ +int gsm0808_dec_aoip_trasp_addr(struct sockaddr_storage *ss, + const uint8_t *elem, uint8_t len) +{ + /* See also 3GPP TS 48.008 3.2.2.102 AoIP Transport Layer Address */ + struct sockaddr_in sin; + struct sockaddr_in6 sin6; + const uint8_t *old_elem = elem; + + OSMO_ASSERT(ss); + if (!elem) + return -EINVAL; + if (len <= 0) + return -EINVAL; + + memset(ss, 0, sizeof(*ss)); + + switch (len) { + case IP_V4_ADDR_LEN + IP_PORT_LEN: + memset(&sin, 0, sizeof(sin)); + sin.sin_family = AF_INET; + + memcpy(&sin.sin_addr.s_addr, elem, IP_V4_ADDR_LEN); + elem += IP_V4_ADDR_LEN; + sin.sin_port = osmo_load16le(elem); + elem += IP_PORT_LEN; + + memcpy(ss, &sin, sizeof(sin)); + break; + case IP_V6_ADDR_LEN + IP_PORT_LEN: + memset(&sin6, 0, sizeof(sin6)); + sin6.sin6_family = AF_INET6; + + memcpy(sin6.sin6_addr.s6_addr, elem, IP_V6_ADDR_LEN); + elem += IP_V6_ADDR_LEN; + sin6.sin6_port = osmo_load16le(elem); + elem += IP_PORT_LEN; + + memcpy(ss, &sin6, sizeof(sin6)); + break; + default: + /* Malformed element! */ + return -EINVAL; + break; + } + + return (int)(elem - old_elem); +} diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map index 5649e71..3ad847d 100644 --- a/src/gsm/libosmogsm.map +++ b/src/gsm/libosmogsm.map @@ -137,6 +137,8 @@ gsm0808_create_reset; gsm0808_create_sapi_reject; gsm0808_prepend_dtap_header; +gsm0808_enc_aoip_trasp_addr; +gsm0808_dec_aoip_trasp_addr; gsm0858_rsl_ul_meas_enc; diff --git a/tests/gsm0808/gsm0808_test.c b/tests/gsm0808/gsm0808_test.c index 98502b7..26bd1d6 100644 --- a/tests/gsm0808/gsm0808_test.c +++ b/tests/gsm0808/gsm0808_test.c @@ -19,9 +19,14 @@ */ #include +#include +#include #include #include +#include +#include +#include #define VERIFY(msg, data, len) \ if (msgb_l3len(msg) != len) { \ @@ -247,6 +252,63 @@ msgb_free(in_msg); } +static void test_enc_dec_aoip_trasp_addr_v4() +{ + struct sockaddr_storage enc_addr; + struct sockaddr_storage dec_addr; + struct sockaddr_in enc_addr_in; + struct msgb *msg; + uint8_t rc_enc; + int rc_dec; + + memset(&enc_addr_in, 0, sizeof(enc_addr_in)); + enc_addr_in.sin_family = AF_INET; + enc_addr_in.sin_port = htons(1234); + inet_aton("255.0.255.255", &enc_addr_in.sin_addr); + + memset(&enc_addr, 0, sizeof(enc_addr)); + memcpy(&enc_addr, &enc_addr_in, sizeof(enc_addr_in)); + + msg = msgb_alloc(1024, "output buffer"); + rc_enc = gsm0808_enc_aoip_trasp_addr(msg, &enc_addr); + OSMO_ASSERT(rc_enc == 8); + rc_dec = + gsm0808_dec_aoip_trasp_addr(&dec_addr, msg->data + 2, msg->len - 2); + OSMO_ASSERT(rc_dec == 6); + OSMO_ASSERT(memcmp(&enc_addr, &dec_addr, sizeof(enc_addr)) == 0); + + msgb_free(msg); +} + +static void test_enc_dec_aoip_trasp_addr_v6() +{ + struct sockaddr_storage enc_addr; + struct sockaddr_storage dec_addr; + struct sockaddr_in6 enc_addr_in; + struct msgb *msg; + uint8_t rc_enc; + int rc_dec; + + memset(&enc_addr_in, 0, sizeof(enc_addr_in)); + enc_addr_in.sin6_family = AF_INET6; + enc_addr_in.sin6_port = htons(4567); + inet_pton(AF_INET6, "2001:0db8:85a3:08d3:1319:8a2e:0370:7344", + &enc_addr_in.sin6_addr); + + memset(&enc_addr, 0, sizeof(enc_addr)); + memcpy(&enc_addr, &enc_addr_in, sizeof(enc_addr_in)); + + msg = msgb_alloc(1024, "output buffer"); + rc_enc = gsm0808_enc_aoip_trasp_addr(msg, &enc_addr); + OSMO_ASSERT(rc_enc == 20); + rc_dec = + gsm0808_dec_aoip_trasp_addr(&dec_addr, msg->data + 2, msg->len - 2); + OSMO_ASSERT(rc_dec == 18); + OSMO_ASSERT(memcmp(&enc_addr, &dec_addr, sizeof(enc_addr)) == 0); + + msgb_free(msg); +} + int main(int argc, char **argv) { printf("Testing generation of GSM0808 messages\n"); @@ -263,6 +325,8 @@ test_create_clear_rqst(); test_create_dtap(); test_prepend_dtap(); + test_enc_dec_aoip_trasp_addr_v4(); + test_enc_dec_aoip_trasp_addr_v6(); printf("Done\n"); return EXIT_SUCCESS; -- To view, visit https://gerrit.osmocom.org/2176 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I57933b0a06a3f54ec2a41e6ecb6ced9fbbc89332 Gerrit-PatchSet: 3 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Apr 4 12:40:59 2017 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Tue, 4 Apr 2017 12:40:59 +0000 Subject: [PATCH] libosmocore[master]: gsm0808: Add utils for Speech Codec List and Speech Codec In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2177 to look at the new patch set (#3). gsm0808: Add utils for Speech Codec List and Speech Codec The planned support for true A over IP requires the encoding and decoding of a so called "Speech Codec Element" element. This commt adds parsing functionality and tests for the element mentioned above, however, it is not yet actively used. Change-Id: I0e1e2edf47adaa45b22d4b0bcae3640dba7ca200 --- M include/osmocom/gsm/gsm0808_utils.h M include/osmocom/gsm/protocol/gsm_08_08.h M src/gsm/gsm0808_utils.c M src/gsm/libosmogsm.map M tests/gsm0808/gsm0808_test.c 5 files changed, 354 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/77/2177/3 diff --git a/include/osmocom/gsm/gsm0808_utils.h b/include/osmocom/gsm/gsm0808_utils.h index 2dcab25..cc500b6 100644 --- a/include/osmocom/gsm/gsm0808_utils.h +++ b/include/osmocom/gsm/gsm0808_utils.h @@ -21,6 +21,8 @@ #include +#include + /* Encode AoIP transport address element */ uint8_t gsm0808_enc_aoip_trasp_addr(struct msgb *msg, struct sockaddr_storage *ss); @@ -28,3 +30,19 @@ /* Decode AoIP transport address element */ int gsm0808_dec_aoip_trasp_addr(struct sockaddr_storage *ss, const uint8_t *elem, uint8_t len); + +/* Encode Speech Codec element */ +uint8_t gsm0808_enc_speech_codec(struct msgb *msg, + struct gsm0808_speech_codec *sc); + +/* Decode Speech Codec element */ +int gsm0808_dec_speech_codec(struct gsm0808_speech_codec *sc, + const uint8_t *elem, uint8_t len); + +/* Encode Speech Codec list */ +uint8_t gsm0808_enc_speech_codec_list(struct msgb *msg, + struct gsm0808_speech_codec_list *scl); + +/* Decode Speech Codec list */ +int gsm0808_dec_speech_codec_list(struct gsm0808_speech_codec_list *scl, + const uint8_t *elem, uint8_t len); diff --git a/include/osmocom/gsm/protocol/gsm_08_08.h b/include/osmocom/gsm/protocol/gsm_08_08.h index 6fb4e9e..3e5514d 100644 --- a/include/osmocom/gsm/protocol/gsm_08_08.h +++ b/include/osmocom/gsm/protocol/gsm_08_08.h @@ -3,6 +3,9 @@ #pragma once #include +#include +#include +#include /* * this is from GSM 03.03 CGI but is copied in GSM 08.08 @@ -416,3 +419,22 @@ GSM0808_PAGINF_FOR_SMS = 0x01, GSM0808_PAGINF_FOR_USSD = 0x02, }; + +/* 3GPP TS 48.008 3.2.2.104 Speech Codec */ +struct gsm0808_speech_codec { + bool fi; + bool pi; + bool pt; + bool tf; + uint8_t type; + uint16_t cfg; + bool type_extended; + bool cfg_present; +}; + +/* 3GPP TS 48.008 3.2.2.103 Speech Codec List */ +#define SPEECH_CODEC_MAXLEN 255 +struct gsm0808_speech_codec_list { + struct gsm0808_speech_codec codec[SPEECH_CODEC_MAXLEN]; + uint8_t len; +}; diff --git a/src/gsm/gsm0808_utils.c b/src/gsm/gsm0808_utils.c index 6177086..6a83cd4 100644 --- a/src/gsm/gsm0808_utils.c +++ b/src/gsm/gsm0808_utils.c @@ -31,6 +31,7 @@ #define IP_V6_ADDR_LEN 16 #define IP_PORT_LEN 2 + /* Encode AoIP transport address element */ uint8_t gsm0808_enc_aoip_trasp_addr(struct msgb *msg, struct sockaddr_storage *ss) @@ -120,3 +121,188 @@ return (int)(elem - old_elem); } + +/* Helper function for gsm0808_enc_speech_codec() + * and gsm0808_enc_speech_codec_list() */ +static uint8_t enc_speech_codec(struct msgb *msg, + struct gsm0808_speech_codec *sc) +{ + /* See also 3GPP TS 48.008 3.2.2.103 Speech Codec List */ + uint8_t header = 0; + uint8_t *old_tail; + + old_tail = msg->tail; + + if (sc->fi) + header |= (1 << 7); + if (sc->pi) + header |= (1 << 6); + if (sc->pt) + header |= (1 << 5); + if (sc->tf) + header |= (1 << 4); + if (sc->type_extended) { + header |= 0x0f; + msgb_put_u8(msg, header); + } else { + OSMO_ASSERT(sc->type < 0x0f); + header |= sc->type; + msgb_put_u8(msg, header); + return (uint8_t) (msg->tail - old_tail); + } + + msgb_put_u8(msg, sc->type); + + if (sc->cfg_present) + msgb_put_u16(msg, sc->cfg); + + return (uint8_t) (msg->tail - old_tail); +} + +/* Encode Speech Codec element */ +uint8_t gsm0808_enc_speech_codec(struct msgb *msg, + struct gsm0808_speech_codec *sc) +{ + uint8_t *old_tail; + uint8_t *tlv_len; + + OSMO_ASSERT(msg); + OSMO_ASSERT(sc); + + msgb_put_u8(msg, GSM0808_IE_SPEECH_CODEC); + tlv_len = msgb_put(msg, 1); + old_tail = msg->tail; + + enc_speech_codec(msg, sc); + + *tlv_len = (uint8_t) (msg->tail - old_tail); + return *tlv_len + 2; +} + +/* Decode Speech Codec element */ +int gsm0808_dec_speech_codec(struct gsm0808_speech_codec *sc, + const uint8_t *elem, uint8_t len) +{ + /* See also 3GPP TS 48.008 3.2.2.103 Speech Codec List */ + uint8_t header; + const uint8_t *old_elem = elem; + + OSMO_ASSERT(sc); + if (!elem) + return -EINVAL; + if (len <= 0) + return -EINVAL; + + memset(sc, 0, sizeof(*sc)); + + header = *elem; + + /* Malformed elements */ + if ((header & 0x0F) == 0x0F && len < 2) + return -EINVAL; + else if ((header & 0x0F) != 0x0F && len < 1) + return -EINVAL; + + elem++; + len--; + + if (header & (1 << 7)) + sc->fi = true; + if (header & (1 << 6)) + sc->pi = true; + if (header & (1 << 5)) + sc->pt = true; + if (header & (1 << 4)) + sc->tf = true; + + if ((header & 0x0F) != 0x0F) { + sc->type = (header & 0x0F); + return (int)(elem - old_elem); + } + + sc->type = *elem; + elem++; + len--; + + sc->type_extended = true; + + if (len < 2) + return (int)(elem - old_elem); + + sc->cfg = osmo_load16be(elem); + elem += 2; + sc->cfg_present = true; + + return (int)(elem - old_elem); +} + +/* Encode Speech Codec list */ +uint8_t gsm0808_enc_speech_codec_list(struct msgb *msg, + struct gsm0808_speech_codec_list *scl) +{ + uint8_t *old_tail; + uint8_t *tlv_len; + unsigned int i; + uint8_t rc; + unsigned int bytes_used = 0; + + OSMO_ASSERT(msg); + OSMO_ASSERT(scl); + + /* Empty list */ + OSMO_ASSERT(scl->len >= 1); + + msgb_put_u8(msg, GSM0808_IE_SPEECH_CODEC_LIST); + tlv_len = msgb_put(msg, 1); + old_tail = msg->tail; + + for (i = 0; i < scl->len; i++) { + rc = enc_speech_codec(msg, &scl->codec[i]); + OSMO_ASSERT(rc >= 1); + bytes_used += rc; + OSMO_ASSERT(bytes_used <= 255); + } + + *tlv_len = (uint8_t) (msg->tail - old_tail); + return *tlv_len + 2; +} + +/* Decode Speech Codec list */ +int gsm0808_dec_speech_codec_list(struct gsm0808_speech_codec_list *scl, + const uint8_t *elem, uint8_t len) +{ + const uint8_t *old_elem = elem; + unsigned int i; + int rc; + uint8_t decoded = 0; + + OSMO_ASSERT(scl); + if (!elem) + return -EINVAL; + if (len <= 0) + return -EINVAL; + + memset(scl, 0, sizeof(*scl)); + + for (i = 0; i < ARRAY_SIZE(scl->codec); i++) { + if (len <= 0) + break; + + rc = gsm0808_dec_speech_codec(&scl->codec[i], elem, len); + if (rc < 1) + return -EINVAL; + + elem+=rc; + len -= rc; + decoded++; + } + + scl->len = decoded; + + /* Empty list */ + if (decoded < 1) { + return -EINVAL; + } + + return (int)(elem - old_elem); +} diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map index 3ad847d..c89cbe4 100644 --- a/src/gsm/libosmogsm.map +++ b/src/gsm/libosmogsm.map @@ -139,6 +139,10 @@ gsm0808_prepend_dtap_header; gsm0808_enc_aoip_trasp_addr; gsm0808_dec_aoip_trasp_addr; +gsm0808_enc_speech_codec; +gsm0808_dec_speech_codec; +gsm0808_enc_speech_codec_list; +gsm0808_dec_speech_codec_list; gsm0858_rsl_ul_meas_enc; diff --git a/tests/gsm0808/gsm0808_test.c b/tests/gsm0808/gsm0808_test.c index 26bd1d6..b22de9b 100644 --- a/tests/gsm0808/gsm0808_test.c +++ b/tests/gsm0808/gsm0808_test.c @@ -309,6 +309,126 @@ msgb_free(msg); } +static void test_gsm0808_enc_dec_speech_codec() +{ + struct gsm0808_speech_codec enc_sc; + struct gsm0808_speech_codec dec_sc; + struct msgb *msg; + uint8_t rc_enc; + int rc_dec; + + memset(&enc_sc, 0, sizeof(enc_sc)); + enc_sc.fi = true; + enc_sc.pt = true; + enc_sc.type = 0x05; + + msg = msgb_alloc(1024, "output buffer"); + rc_enc = gsm0808_enc_speech_codec(msg, &enc_sc); + OSMO_ASSERT(rc_enc == 3); + + rc_dec = gsm0808_dec_speech_codec(&dec_sc, msg->data + 2, msg->len - 2); + OSMO_ASSERT(rc_dec == 1); + + OSMO_ASSERT(memcmp(&enc_sc, &dec_sc, sizeof(enc_sc)) == 0); + + msgb_free(msg); +} + + +static void test_gsm0808_enc_dec_speech_codec_ext_with_cfg() +{ + struct gsm0808_speech_codec enc_sc; + struct gsm0808_speech_codec dec_sc; + struct msgb *msg; + uint8_t rc_enc; + int rc_dec; + + enc_sc.pi = true; + enc_sc.tf = true; + enc_sc.type = 0xab; + enc_sc.type_extended = true; + enc_sc.cfg_present = true; + enc_sc.cfg = 0xcdef; + + msg = msgb_alloc(1024, "output buffer"); + rc_enc = gsm0808_enc_speech_codec(msg, &enc_sc); + OSMO_ASSERT(rc_enc == 6); + + rc_dec = gsm0808_dec_speech_codec(&dec_sc, msg->data + 2, msg->len - 2); + OSMO_ASSERT(rc_dec == 4); + + OSMO_ASSERT(memcmp(&enc_sc, &dec_sc, sizeof(enc_sc)) == 0); + + msgb_free(msg); +} + +static void test_gsm0808_enc_dec_speech_codec_ext() +{ + struct gsm0808_speech_codec enc_sc; + struct gsm0808_speech_codec dec_sc; + struct msgb *msg; + uint8_t rc_enc; + int rc_dec; + + enc_sc.fi = true; + enc_sc.tf = true; + enc_sc.type = 0xf2; + enc_sc.type_extended = true; + enc_sc.cfg_present = false; + enc_sc.cfg = 0x0000; + + msg = msgb_alloc(1024, "output buffer"); + rc_enc = gsm0808_enc_speech_codec(msg, &enc_sc); + OSMO_ASSERT(rc_enc == 4); + + rc_dec = gsm0808_dec_speech_codec(&dec_sc, msg->data + 2, msg->len - 2); + OSMO_ASSERT(rc_dec == 2); + + OSMO_ASSERT(memcmp(&enc_sc, &dec_sc, sizeof(enc_sc)) == 0); + + msgb_free(msg); +} + +static void test_gsm0808_enc_dec_speech_codec_list() +{ + struct gsm0808_speech_codec_list enc_scl; + struct gsm0808_speech_codec_list dec_scl; + struct msgb *msg; + uint8_t rc_enc; + int rc_dec; + + memset(&enc_scl, 0, sizeof(enc_scl)); + + enc_scl.codec[0].pi = true; + enc_scl.codec[0].tf = true; + enc_scl.codec[0].type = 0xab; + enc_scl.codec[0].type_extended = true; + enc_scl.codec[0].cfg_present = true; + enc_scl.codec[0].cfg = 0xcdef; + + enc_scl.codec[1].fi = true; + enc_scl.codec[1].pt = true; + enc_scl.codec[1].type = 0x05; + + enc_scl.codec[2].fi = true; + enc_scl.codec[2].tf = true; + enc_scl.codec[2].type = 0xf2; + enc_scl.codec[2].type_extended = true; + + enc_scl.len = 3; + + msg = msgb_alloc(1024, "output buffer"); + rc_enc = gsm0808_enc_speech_codec_list(msg, &enc_scl); + OSMO_ASSERT(rc_enc == 9); + + rc_dec = gsm0808_dec_speech_codec_list(&dec_scl, msg->data + 2, msg->len - 2); + OSMO_ASSERT(rc_dec == 7); + + OSMO_ASSERT(memcmp(&enc_scl, &dec_scl, sizeof(enc_scl)) == 0); + + msgb_free(msg); +} + int main(int argc, char **argv) { printf("Testing generation of GSM0808 messages\n"); @@ -327,6 +447,10 @@ test_prepend_dtap(); test_enc_dec_aoip_trasp_addr_v4(); test_enc_dec_aoip_trasp_addr_v6(); + test_gsm0808_enc_dec_speech_codec(); + test_gsm0808_enc_dec_speech_codec_ext(); + test_gsm0808_enc_dec_speech_codec_ext_with_cfg(); + test_gsm0808_enc_dec_speech_codec_list(); printf("Done\n"); return EXIT_SUCCESS; -- To view, visit https://gerrit.osmocom.org/2177 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I0e1e2edf47adaa45b22d4b0bcae3640dba7ca200 Gerrit-PatchSet: 3 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Apr 4 12:40:59 2017 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Tue, 4 Apr 2017 12:40:59 +0000 Subject: [PATCH] libosmocore[master]: gsm0808: Add AoIP specific elements to gsm0808_create_... fu... In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2178 to look at the new patch set (#3). gsm0808: Add AoIP specific elements to gsm0808_create_... functions the classic A implementation in libosmocore lacks support for AoIP message elements. This patch adds support for AoIP by adding a set of new gsm0808_create_..., which support the missing AoIP message elements Change-Id: I77f866abec1822d19871052f3c647ad782785b34 --- M include/osmocom/gsm/gsm0808.h M src/gsm/gsm0808.c M src/gsm/libosmogsm.map M tests/gsm0808/gsm0808_test.c M tests/gsm0808/gsm0808_test.ok 5 files changed, 225 insertions(+), 18 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/78/2178/3 diff --git a/include/osmocom/gsm/gsm0808.h b/include/osmocom/gsm/gsm0808.h index a7e102c..fd0d5ee 100644 --- a/include/osmocom/gsm/gsm0808.h +++ b/include/osmocom/gsm/gsm0808.h @@ -20,10 +20,16 @@ #pragma once #include "tlv.h" +#include +#include struct msgb; -struct msgb *gsm0808_create_layer3(struct msgb *msg, uint16_t netcode, uint16_t countrycode, int lac, uint16_t ci); +struct msgb *gsm0808_create_layer3(struct msgb *msg_l3, uint16_t nc, + uint16_t cc, int lac, uint16_t _ci); +struct msgb *gsm0808_create_layer3_aoip(struct msgb *msg_l3, uint16_t nc, + uint16_t cc, int lac, uint16_t _ci, + struct gsm0808_speech_codec_list *scl); struct msgb *gsm0808_create_reset(void); struct msgb *gsm0808_create_reset_ack(void); struct msgb *gsm0808_create_clear_command(uint8_t reason); @@ -33,9 +39,25 @@ struct msgb *gsm0808_create_classmark_update(const uint8_t *cm2, uint8_t cm2_len, const uint8_t *cm3, uint8_t cm3_len); struct msgb *gsm0808_create_sapi_reject(uint8_t link_id); +struct msgb *gsm0808_create_assignment_completed_aoip(uint8_t rr_cause, + uint8_t chosen_channel, + uint8_t encr_alg_id, + uint8_t speech_mode, + struct sockaddr_storage + *ss, struct + gsm0808_speech_codec *sc, + struct + gsm0808_speech_codec_list + *scl); struct msgb *gsm0808_create_assignment_completed(uint8_t rr_cause, - uint8_t chosen_channel, uint8_t encr_alg_id, + uint8_t chosen_channel, + uint8_t encr_alg_id, uint8_t speech_mode); +struct msgb *gsm0808_create_assignment_failure_aoip(uint8_t cause, + uint8_t *rr_cause, + struct + gsm0808_speech_codec_list + *scl); struct msgb *gsm0808_create_assignment_failure(uint8_t cause, uint8_t *rr_cause); struct msgb *gsm0808_create_clear_rqst(uint8_t cause); diff --git a/src/gsm/gsm0808.c b/src/gsm/gsm0808.c index de80006..0dc7b8e 100644 --- a/src/gsm/gsm0808.c +++ b/src/gsm/gsm0808.c @@ -19,6 +19,7 @@ */ #include +#include #include #include @@ -27,17 +28,19 @@ #define BSSMAP_MSG_SIZE 512 #define BSSMAP_MSG_HEADROOM 128 -struct msgb *gsm0808_create_layer3(struct msgb *msg_l3, uint16_t nc, uint16_t cc, int lac, uint16_t _ci) +struct msgb *gsm0808_create_layer3_aoip(struct msgb *msg_l3, uint16_t nc, + uint16_t cc, int lac, uint16_t _ci, + struct gsm0808_speech_codec_list *scl) { - struct msgb* msg; + struct msgb *msg; struct { uint8_t ident; struct gsm48_loc_area_id lai; uint16_t ci; } __attribute__ ((packed)) lai_ci; - msg = msgb_alloc_headroom(BSSMAP_MSG_SIZE, BSSMAP_MSG_HEADROOM, - "bssmap cmpl l3"); + msg = msgb_alloc_headroom(BSSMAP_MSG_SIZE, BSSMAP_MSG_HEADROOM, + "bssmap cmpl l3"); if (!msg) return NULL; @@ -49,16 +52,27 @@ gsm48_generate_lai(&lai_ci.lai, cc, nc, lac); lai_ci.ci = htons(_ci); msgb_tlv_put(msg, GSM0808_IE_CELL_IDENTIFIER, sizeof(lai_ci), - (uint8_t *) &lai_ci); + (uint8_t *) & lai_ci); /* copy the layer3 data */ msgb_tlv_put(msg, GSM0808_IE_LAYER_3_INFORMATION, msgb_l3len(msg_l3), msg_l3->l3h); + /* AoIP: add Codec List (BSS Supported) 3.2.2.103 */ + if (scl) + gsm0808_enc_speech_codec_list(msg, scl); + /* push the bssmap header */ - msg->l3h = msgb_tv_push(msg, BSSAP_MSG_BSS_MANAGEMENT, msgb_length(msg)); + msg->l3h = + msgb_tv_push(msg, BSSAP_MSG_BSS_MANAGEMENT, msgb_length(msg)); return msg; +} + +struct msgb *gsm0808_create_layer3(struct msgb *msg_l3, uint16_t nc, + uint16_t cc, int lac, uint16_t _ci) +{ + return gsm0808_create_layer3_aoip(msg_l3, nc, cc, lac, _ci, NULL); } struct msgb *gsm0808_create_reset(void) @@ -191,12 +205,20 @@ return msg; } -struct msgb *gsm0808_create_assignment_completed(uint8_t rr_cause, - uint8_t chosen_channel, uint8_t encr_alg_id, - uint8_t speech_mode) +struct msgb *gsm0808_create_assignment_completed_aoip(uint8_t rr_cause, + uint8_t chosen_channel, + uint8_t encr_alg_id, + uint8_t speech_mode, + struct sockaddr_storage + *ss, struct + gsm0808_speech_codec *sc, + struct + gsm0808_speech_codec_list + *scl) { - struct msgb *msg = msgb_alloc_headroom(BSSMAP_MSG_SIZE, BSSMAP_MSG_HEADROOM, - "bssmap: ass compl"); + struct msgb *msg = + msgb_alloc_headroom(BSSMAP_MSG_SIZE, BSSMAP_MSG_HEADROOM, + "bssmap: ass compl"); if (!msg) return NULL; @@ -218,17 +240,47 @@ if (speech_mode != 0) msgb_tv_put(msg, GSM0808_IE_SPEECH_VERSION, speech_mode); + /* AoIP: AoIP Transport Layer Address (BSS) 3.2.2.102 */ + if (ss) + gsm0808_enc_aoip_trasp_addr(msg, ss); + + /* AoIP: Speech Codec (Chosen) 3.2.2.104 */ + if (sc) + gsm0808_enc_speech_codec(msg, sc); + + /* AoIP: add Codec List (BSS Supported) 3.2.2.103 */ + if (scl) + gsm0808_enc_speech_codec_list(msg, scl); + /* write LSA identifier 3.2.2.15 */ - msg->l3h = msgb_tv_push(msg, BSSAP_MSG_BSS_MANAGEMENT, msgb_length(msg)); + msg->l3h = + msgb_tv_push(msg, BSSAP_MSG_BSS_MANAGEMENT, msgb_length(msg)); return msg; } -struct msgb *gsm0808_create_assignment_failure(uint8_t cause, uint8_t *rr_cause) +struct msgb *gsm0808_create_assignment_completed(uint8_t rr_cause, + uint8_t chosen_channel, + uint8_t encr_alg_id, + uint8_t speech_mode) { - struct msgb *msg = msgb_alloc_headroom(BSSMAP_MSG_SIZE, BSSMAP_MSG_HEADROOM, - "bssmap: ass fail"); + return gsm0808_create_assignment_completed_aoip(rr_cause, + chosen_channel, + encr_alg_id, + speech_mode, + NULL, NULL, NULL); +} + +struct msgb *gsm0808_create_assignment_failure_aoip(uint8_t cause, + uint8_t *rr_cause, + struct + gsm0808_speech_codec_list + *scl) +{ + struct msgb *msg = + msgb_alloc_headroom(BSSMAP_MSG_SIZE, BSSMAP_MSG_HEADROOM, + "bssmap: ass fail"); if (!msg) return NULL; @@ -242,12 +294,23 @@ /* Circuit pool 3.22.45 */ /* Circuit pool list 3.2.2.46 */ + /* AoIP: add Codec List (BSS Supported) 3.2.2.103 */ + if (scl) + gsm0808_enc_speech_codec_list(msg, scl); + /* update the size */ - msg->l3h = msgb_tv_push(msg, BSSAP_MSG_BSS_MANAGEMENT, msgb_length(msg)); + msg->l3h = + msgb_tv_push(msg, BSSAP_MSG_BSS_MANAGEMENT, msgb_length(msg)); return msg; } +struct msgb *gsm0808_create_assignment_failure(uint8_t cause, + uint8_t *rr_cause) +{ + return gsm0808_create_assignment_failure_aoip(cause, rr_cause, NULL); +} + struct msgb *gsm0808_create_clear_rqst(uint8_t cause) { struct msgb *msg; diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map index c89cbe4..3c23ed8 100644 --- a/src/gsm/libosmogsm.map +++ b/src/gsm/libosmogsm.map @@ -125,7 +125,9 @@ gsm0808_bssap_name; gsm0808_bssmap_name; gsm0808_create_assignment_completed; +gsm0808_create_assignment_completed_aoip; gsm0808_create_assignment_failure; +gsm0808_create_assignment_failure_aoip; gsm0808_create_cipher_complete; gsm0808_create_cipher_reject; gsm0808_create_classmark_update; @@ -134,6 +136,7 @@ gsm0808_create_clear_rqst; gsm0808_create_dtap; gsm0808_create_layer3; +gsm0808_create_layer3_aoip; gsm0808_create_reset; gsm0808_create_sapi_reject; gsm0808_prepend_dtap_header; diff --git a/tests/gsm0808/gsm0808_test.c b/tests/gsm0808/gsm0808_test.c index b22de9b..a3b0cc9 100644 --- a/tests/gsm0808/gsm0808_test.c +++ b/tests/gsm0808/gsm0808_test.c @@ -41,6 +41,29 @@ abort(); \ } +/* Setup a fake codec list for testing */ +static void setup_codec_list(struct gsm0808_speech_codec_list *scl) +{ + memset(scl, 0, sizeof(*scl)); + + scl->codec[0].pi = true; + scl->codec[0].tf = true; + scl->codec[0].type = 0xab; + scl->codec[0].type_extended = true; + scl->codec[0].cfg_present = true; + scl->codec[0].cfg = 0xcdef; + + scl->codec[1].fi = true; + scl->codec[1].pt = true; + scl->codec[1].type = 0x05; + + scl->codec[2].fi = true; + scl->codec[2].tf = true; + scl->codec[2].type = 0xf2; + scl->codec[2].type_extended = true; + + scl->len = 3; +} static void test_create_layer3(void) { @@ -56,6 +79,34 @@ msg = gsm0808_create_layer3(in_msg, 0x1122, 0x2244, 0x3366, 0x4488); VERIFY(msg, res, ARRAY_SIZE(res)); + msgb_free(msg); + msgb_free(in_msg); +} + +static void test_create_layer3_aoip() +{ + static const uint8_t res[] = { + 0x00, 0x17, 0x57, 0x05, 0x08, 0x00, 0x77, 0x62, + 0x83, 0x33, 0x66, 0x44, 0x88, 0x17, 0x01, 0x23, + GSM0808_IE_SPEECH_CODEC_LIST, 0x07, 0x5f, 0xab, 0xcd, 0xef, + 0xa5, 0x9f, 0xf2 + }; + + struct msgb *msg, *in_msg; + struct gsm0808_speech_codec_list sc_list; + printf("Testing creating Layer3 (AoIP)\n"); + + setup_codec_list(&sc_list); + + in_msg = msgb_alloc_headroom(512, 128, "foo"); + in_msg->l3h = in_msg->data; + msgb_v_put(in_msg, 0x23); + + msg = + gsm0808_create_layer3_aoip(in_msg, 0x1122, 0x2244, 0x3366, 0x4488, + &sc_list); + VERIFY(msg, res, ARRAY_SIZE(res)); + msgb_free(msg); msgb_free(in_msg); } @@ -189,6 +240,43 @@ msgb_free(msg); } +static void test_create_ass_compl_aoip() +{ + struct sockaddr_storage ss; + struct sockaddr_in sin; + struct gsm0808_speech_codec sc; + struct gsm0808_speech_codec_list sc_list; + static const uint8_t res[] = + { 0x00, 0x1d, 0x02, 0x15, 0x23, 0x21, 0x42, 0x2c, 0x11, 0x40, 0x22, + GSM0808_IE_AOIP_TRASP_ADDR, 0x06, 0xc0, 0xa8, 0x64, 0x17, 0x04, + 0xd2, GSM0808_IE_SPEECH_CODEC, 0x01, 0x9a, + GSM0808_IE_SPEECH_CODEC_LIST, 0x07, 0x5f, 0xab, 0xcd, 0xef, 0xa5, + 0x9f, 0xf2 }; + struct msgb *msg; + + memset(&sin, 0, sizeof(sin)); + sin.sin_family = AF_INET; + sin.sin_port = htons(1234); + inet_aton("192.168.100.23", &sin.sin_addr); + + memset(&ss, 0, sizeof(ss)); + memcpy(&ss, &sin, sizeof(sin)); + + memset(&sc, 0, sizeof(sc)); + sc.fi = true; + sc.tf = true; + sc.type = 0x0a; + + setup_codec_list(&sc_list); + + printf("Testing creating Assignment Complete (AoIP)\n"); + msg = + gsm0808_create_assignment_completed_aoip(0x23, 0x42, 0x11, 0x22, + &ss, &sc, &sc_list); + VERIFY(msg, res, ARRAY_SIZE(res)); + msgb_free(msg); +} + static void test_create_ass_fail() { static const uint8_t res1[] = { 0x00, 0x04, 0x03, 0x04, 0x01, 0x23 }; @@ -203,6 +291,31 @@ msgb_free(msg); msg = gsm0808_create_assignment_failure(0x23, &rr_res); + VERIFY(msg, res2, ARRAY_SIZE(res2)); + msgb_free(msg); +} + +static void test_create_ass_fail_aoip() +{ + static const uint8_t res1[] = + { 0x00, 0x0d, 0x03, 0x04, 0x01, 0x23, GSM0808_IE_SPEECH_CODEC_LIST, + 0x07, 0x5f, 0xab, 0xcd, 0xef, 0xa5, 0x9f, 0xf2 }; + static const uint8_t res2[] = + { 0x00, 0x0f, 0x03, 0x04, 0x01, 0x23, 0x15, 0x02, + GSM0808_IE_SPEECH_CODEC_LIST, 0x07, 0x5f, 0xab, + 0xcd, 0xef, 0xa5, 0x9f, 0xf2 }; + uint8_t rr_res = 2; + struct msgb *msg; + struct gsm0808_speech_codec_list sc_list; + + setup_codec_list(&sc_list); + + printf("Testing creating Assignment Failure (AoIP)\n"); + msg = gsm0808_create_assignment_failure_aoip(0x23, NULL, &sc_list); + VERIFY(msg, res1, ARRAY_SIZE(res1)); + msgb_free(msg); + + msg = gsm0808_create_assignment_failure_aoip(0x23, &rr_res, &sc_list); VERIFY(msg, res2, ARRAY_SIZE(res2)); msgb_free(msg); } @@ -433,6 +546,7 @@ { printf("Testing generation of GSM0808 messages\n"); test_create_layer3(); + test_create_layer3_aoip(); test_create_reset(); test_create_clear_command(); test_create_clear_complete(); @@ -441,7 +555,9 @@ test_create_cm_u(); test_create_sapi_reject(); test_create_ass_compl(); + test_create_ass_compl_aoip(); test_create_ass_fail(); + test_create_ass_fail_aoip(); test_create_clear_rqst(); test_create_dtap(); test_prepend_dtap(); diff --git a/tests/gsm0808/gsm0808_test.ok b/tests/gsm0808/gsm0808_test.ok index eb43126..f406551 100644 --- a/tests/gsm0808/gsm0808_test.ok +++ b/tests/gsm0808/gsm0808_test.ok @@ -1,5 +1,6 @@ Testing generation of GSM0808 messages Testing creating Layer3 +Testing creating Layer3 (AoIP) Testing creating Reset Testing creating Clear Command Testing creating Clear Complete @@ -8,7 +9,9 @@ Testing creating CM U Testing creating SAPI Reject Testing creating Assignment Complete +Testing creating Assignment Complete (AoIP) Testing creating Assignment Failure +Testing creating Assignment Failure (AoIP) Testing creating Clear Request Testing creating DTAP Testing prepend DTAP -- To view, visit https://gerrit.osmocom.org/2178 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I77f866abec1822d19871052f3c647ad782785b34 Gerrit-PatchSet: 3 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Apr 4 12:40:59 2017 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Tue, 4 Apr 2017 12:40:59 +0000 Subject: [PATCH] libosmocore[master]: gsm0808: Add utils for Channel Type In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2179 to look at the new patch set (#3). gsm0808: Add utils for Channel Type The planned support for true A over IP requires the encoding of the a Channel Type element (see also ASSIGNMENT REQUEST). This commt adds encoding/decoding functionality and tests for the element mentioned above, however, it is not yet actively used. Change-Id: Id0e2164d84b8cbcc6fe6a090fc7f40a1251421d7 --- M include/osmocom/gsm/gsm0808_utils.h M include/osmocom/gsm/protocol/gsm_08_08.h M src/gsm/gsm0808_utils.c M src/gsm/libosmogsm.map M tests/gsm0808/gsm0808_test.c 5 files changed, 123 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/79/2179/3 diff --git a/include/osmocom/gsm/gsm0808_utils.h b/include/osmocom/gsm/gsm0808_utils.h index cc500b6..3f29276 100644 --- a/include/osmocom/gsm/gsm0808_utils.h +++ b/include/osmocom/gsm/gsm0808_utils.h @@ -46,3 +46,11 @@ /* Decode Speech Codec list */ int gsm0808_dec_speech_codec_list(struct gsm0808_speech_codec_list *scl, const uint8_t *elem, uint8_t len); + +/* Encode Channel Type element */ +uint8_t gsm0808_enc_channel_type(struct msgb *msg, + struct gsm0808_channel_type *ct); + +/* Decode Channel Type element */ +int gsm0808_dec_channel_type(struct gsm0808_channel_type *ct, + const uint8_t *elem, uint8_t len); diff --git a/include/osmocom/gsm/protocol/gsm_08_08.h b/include/osmocom/gsm/protocol/gsm_08_08.h index 3e5514d..e2355f6 100644 --- a/include/osmocom/gsm/protocol/gsm_08_08.h +++ b/include/osmocom/gsm/protocol/gsm_08_08.h @@ -438,3 +438,12 @@ struct gsm0808_speech_codec codec[SPEECH_CODEC_MAXLEN]; uint8_t len; }; + +/* 3GPP TS 48.008 3.2.2.11 Channel Type */ +#define CH_TYPE_PERM_SPCH_MAXLEN 9 +struct gsm0808_channel_type { + uint8_t ch_indctr; + uint8_t ch_rate_type; + uint8_t perm_spch[CH_TYPE_PERM_SPCH_MAXLEN]; + unsigned int perm_spch_len; +}; diff --git a/src/gsm/gsm0808_utils.c b/src/gsm/gsm0808_utils.c index 6a83cd4..c48acc0 100644 --- a/src/gsm/gsm0808_utils.c +++ b/src/gsm/gsm0808_utils.c @@ -31,6 +31,8 @@ #define IP_V6_ADDR_LEN 16 #define IP_PORT_LEN 2 +#define CHANNEL_TYPE_ELEMENT_MAXLEN 11 +#define CHANNEL_TYPE_ELEMENT_MINLEN 3 /* Encode AoIP transport address element */ uint8_t gsm0808_enc_aoip_trasp_addr(struct msgb *msg, @@ -306,3 +308,74 @@ return (int)(elem - old_elem); } + +/* Encode Channel Type element */ +uint8_t gsm0808_enc_channel_type(struct msgb *msg, + struct gsm0808_channel_type *ct) +{ + unsigned int i; + uint8_t byte; + uint8_t *old_tail; + uint8_t *tlv_len; + + OSMO_ASSERT(msg); + OSMO_ASSERT(ct); + OSMO_ASSERT(ct->perm_spch_len <= CHANNEL_TYPE_ELEMENT_MAXLEN - 2); + + /* FIXME: Implement encoding support for Data + * and Speech + CTM Text Telephony */ + if ((ct->ch_indctr & 0x0f) != GSM0808_CHAN_SPEECH + && (ct->ch_indctr & 0x0f) != GSM0808_CHAN_SIGN) + OSMO_ASSERT(false); + + msgb_put_u8(msg, GSM0808_IE_CHANNEL_TYPE); + tlv_len = msgb_put(msg, 1); + old_tail = msg->tail; + + msgb_put_u8(msg, ct->ch_indctr & 0x0f); + msgb_put_u8(msg, ct->ch_rate_type); + + for (i = 0; i < ct->perm_spch_len; i++) { + byte = ct->perm_spch[i]; + + if (i < ct->perm_spch_len - 1) + byte |= 0x80; + msgb_put_u8(msg, byte); + } + + *tlv_len = (uint8_t) (msg->tail - old_tail); + return *tlv_len + 2; +} + +/* Decode Channel Type element */ +int gsm0808_dec_channel_type(struct gsm0808_channel_type *ct, + const uint8_t *elem, uint8_t len) +{ + unsigned int i; + uint8_t byte; + const uint8_t *old_elem = elem; + + OSMO_ASSERT(ct); + if (!elem) + return -EINVAL; + if (len <= 0) + return -EINVAL; + + memset(ct, 0, sizeof(*ct)); + + ct->ch_indctr = (*elem) & 0x0f; + elem++; + ct->ch_rate_type = (*elem) & 0x0f; + elem++; + + for (i = 0; i < ARRAY_SIZE(ct->perm_spch); i++) { + byte = *elem; + elem++; + ct->perm_spch[i] = byte & 0x7f; + if ((byte & 0x80) == 0x00) + break; + } + ct->perm_spch_len = i + 1; + + return (int)(elem - old_elem); +} diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map index 3c23ed8..60cc742 100644 --- a/src/gsm/libosmogsm.map +++ b/src/gsm/libosmogsm.map @@ -146,6 +146,8 @@ gsm0808_dec_speech_codec; gsm0808_enc_speech_codec_list; gsm0808_dec_speech_codec_list; +gsm0808_enc_channel_type; +gsm0808_dec_channel_type; gsm0858_rsl_ul_meas_enc; diff --git a/tests/gsm0808/gsm0808_test.c b/tests/gsm0808/gsm0808_test.c index a3b0cc9..29adc15 100644 --- a/tests/gsm0808/gsm0808_test.c +++ b/tests/gsm0808/gsm0808_test.c @@ -542,6 +542,36 @@ msgb_free(msg); } +static void test_gsm0808_enc_dec_channel_type() +{ + struct gsm0808_channel_type enc_ct; + struct gsm0808_channel_type dec_ct; + struct msgb *msg; + uint8_t ct_enc_expected[] = { GSM0808_IE_CHANNEL_TYPE, + 0x04, 0x01, 0x0b, 0xa1, 0x25 + }; + uint8_t rc_enc; + int rc_dec; + + memset(&enc_ct, 0, sizeof(enc_ct)); + enc_ct.ch_indctr = GSM0808_CHAN_SPEECH; + enc_ct.ch_rate_type = GSM0808_SPEECH_HALF_PREF; + enc_ct.perm_spch[0] = GSM0808_PERM_FR3; + enc_ct.perm_spch[1] = GSM0808_PERM_HR3; + enc_ct.perm_spch_len = 2; + + msg = msgb_alloc(1024, "output buffer"); + rc_enc = gsm0808_enc_channel_type(msg, &enc_ct); + OSMO_ASSERT(rc_enc == 6); + OSMO_ASSERT(memcmp(ct_enc_expected, msg->data, msg->len) == 0); + + rc_dec = gsm0808_dec_channel_type(&dec_ct, msg->data + 2, msg->len - 2); + OSMO_ASSERT(rc_dec == 4); + OSMO_ASSERT(memcmp(&enc_ct, &dec_ct, sizeof(enc_ct)) == 0); + + msgb_free(msg); +} + int main(int argc, char **argv) { printf("Testing generation of GSM0808 messages\n"); @@ -567,6 +597,7 @@ test_gsm0808_enc_dec_speech_codec_ext(); test_gsm0808_enc_dec_speech_codec_ext_with_cfg(); test_gsm0808_enc_dec_speech_codec_list(); + test_gsm0808_enc_dec_channel_type(); printf("Done\n"); return EXIT_SUCCESS; -- To view, visit https://gerrit.osmocom.org/2179 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Id0e2164d84b8cbcc6fe6a090fc7f40a1251421d7 Gerrit-PatchSet: 3 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Apr 4 12:40:59 2017 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Tue, 4 Apr 2017 12:40:59 +0000 Subject: [PATCH] libosmocore[master]: gsm0808: Add utils for Encryption Information In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2180 to look at the new patch set (#3). gsm0808: Add utils for Encryption Information The planned support for true A over IP requires the encoding of the an Encryption Information element (see also BSS_MAP_MSG_CIPHER_MODE_CMD). This commt adds encoding/decoding functionality and tests for the element mentioned above, however, it is not yet actively used. Change-Id: I8262050a9d9fd3f17462cfbb046c6e034dccc6fb --- M include/osmocom/gsm/gsm0808_utils.h M include/osmocom/gsm/protocol/gsm_08_08.h M src/gsm/gsm0808_utils.c M src/gsm/libosmogsm.map M tests/gsm0808/gsm0808_test.c 5 files changed, 131 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/80/2180/3 diff --git a/include/osmocom/gsm/gsm0808_utils.h b/include/osmocom/gsm/gsm0808_utils.h index 3f29276..edaa915 100644 --- a/include/osmocom/gsm/gsm0808_utils.h +++ b/include/osmocom/gsm/gsm0808_utils.h @@ -54,3 +54,11 @@ /* Decode Channel Type element */ int gsm0808_dec_channel_type(struct gsm0808_channel_type *ct, const uint8_t *elem, uint8_t len); + +/* Encode Encryption Information element */ +uint8_t gsm0808_enc_encrypt_info(struct msgb *msg, + struct gsm0808_encrypt_info *ei); + +/* Decode Encryption Information element */ +int gsm0808_dec_encrypt_info(struct gsm0808_encrypt_info *ei, + const uint8_t *elem, uint8_t len); diff --git a/include/osmocom/gsm/protocol/gsm_08_08.h b/include/osmocom/gsm/protocol/gsm_08_08.h index e2355f6..3939aed 100644 --- a/include/osmocom/gsm/protocol/gsm_08_08.h +++ b/include/osmocom/gsm/protocol/gsm_08_08.h @@ -447,3 +447,13 @@ uint8_t perm_spch[CH_TYPE_PERM_SPCH_MAXLEN]; unsigned int perm_spch_len; }; + +/* 3GPP TS 48.008 3.2.2.10 Encryption Information */ +#define ENCRY_INFO_KEY_MAXLEN 252 +#define ENCRY_INFO_PERM_ALGO_MAXLEN 8 +struct gsm0808_encrypt_info { + uint8_t perm_algo[ENCRY_INFO_PERM_ALGO_MAXLEN]; + unsigned int perm_algo_len; + uint8_t key[ENCRY_INFO_KEY_MAXLEN]; + unsigned int key_len; +}; diff --git a/src/gsm/gsm0808_utils.c b/src/gsm/gsm0808_utils.c index c48acc0..690ca2e 100644 --- a/src/gsm/gsm0808_utils.c +++ b/src/gsm/gsm0808_utils.c @@ -33,6 +33,7 @@ #define CHANNEL_TYPE_ELEMENT_MAXLEN 11 #define CHANNEL_TYPE_ELEMENT_MINLEN 3 +#define ENCRYPT_INFO_ELEMENT_MINLEN 1 /* Encode AoIP transport address element */ uint8_t gsm0808_enc_aoip_trasp_addr(struct msgb *msg, @@ -379,3 +380,73 @@ return (int)(elem - old_elem); } + +/* Encode Encryption Information element */ +uint8_t gsm0808_enc_encrypt_info(struct msgb *msg, + struct gsm0808_encrypt_info *ei) +{ + unsigned int i; + uint8_t perm_algo = 0; + uint8_t *ptr; + uint8_t *old_tail; + uint8_t *tlv_len; + + OSMO_ASSERT(msg); + OSMO_ASSERT(ei); + OSMO_ASSERT(ei->key_len <= ARRAY_SIZE(ei->key)); + OSMO_ASSERT(ei->perm_algo_len <= ENCRY_INFO_PERM_ALGO_MAXLEN); + + msgb_put_u8(msg, GSM0808_IE_ENCRYPTION_INFORMATION); + tlv_len = msgb_put(msg, 1); + old_tail = msg->tail; + + for (i = 0; i < ei->perm_algo_len; i++) { + /* Note: gsm_08_08.h defines the permitted algorithms + * as an enum which ranges from 0x01 to 0x08 */ + OSMO_ASSERT(ei->perm_algo[i] != 0); + OSMO_ASSERT(ei->perm_algo[i] <= ENCRY_INFO_PERM_ALGO_MAXLEN); + perm_algo |= (1 << (ei->perm_algo[i] - 1)); + } + + msgb_put_u8(msg, perm_algo); + ptr = msgb_put(msg, ei->key_len); + memcpy(ptr, ei->key, ei->key_len); + + *tlv_len = (uint8_t) (msg->tail - old_tail); + return *tlv_len + 2; +} + +/* Decode Encryption Information element */ +int gsm0808_dec_encrypt_info(struct gsm0808_encrypt_info *ei, + const uint8_t *elem, uint8_t len) +{ + uint8_t perm_algo; + unsigned int i; + unsigned int perm_algo_len = 0; + const uint8_t *old_elem = elem; + + OSMO_ASSERT(ei); + if (!elem) + return -EINVAL; + if (len <= 0) + return -EINVAL; + + memset(ei, 0, sizeof(*ei)); + + perm_algo = *elem; + elem++; + + for (i = 0; i < ENCRY_INFO_PERM_ALGO_MAXLEN; i++) { + if (perm_algo & (1 << i)) { + ei->perm_algo[perm_algo_len] = i + 1; + perm_algo_len++; + } + } + ei->perm_algo_len = perm_algo_len; + + ei->key_len = len - 1; + memcpy(ei->key, elem, ei->key_len); + elem+=ei->key_len; + + return (int)(elem - old_elem); +} diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map index 60cc742..e64fdd9 100644 --- a/src/gsm/libosmogsm.map +++ b/src/gsm/libosmogsm.map @@ -148,6 +148,8 @@ gsm0808_dec_speech_codec_list; gsm0808_enc_channel_type; gsm0808_dec_channel_type; +gsm0808_enc_encrypt_info; +gsm0808_dec_encrypt_info; gsm0858_rsl_ul_meas_enc; diff --git a/tests/gsm0808/gsm0808_test.c b/tests/gsm0808/gsm0808_test.c index 29adc15..67a790b 100644 --- a/tests/gsm0808/gsm0808_test.c +++ b/tests/gsm0808/gsm0808_test.c @@ -572,6 +572,45 @@ msgb_free(msg); } +static void test_gsm0808_enc_dec_encrypt_info() +{ + struct gsm0808_encrypt_info enc_ei; + struct gsm0808_encrypt_info dec_ei; + struct msgb *msg; + uint8_t ei_enc_expected[] = + { GSM0808_IE_ENCRYPTION_INFORMATION, 0x09, 0x03, 0xaa, 0xbb, + 0xcc, 0xdd, 0xee, 0xff, 0x23, 0x42 + }; + uint8_t rc_enc; + int rc_dec; + + memset(&enc_ei, 0, sizeof(enc_ei)); + enc_ei.perm_algo[0] = GSM0808_ALG_ID_A5_0; + enc_ei.perm_algo[1] = GSM0808_ALG_ID_A5_1; + enc_ei.perm_algo_len = 2; + enc_ei.key[0] = 0xaa; + enc_ei.key[1] = 0xbb; + enc_ei.key[2] = 0xcc; + enc_ei.key[3] = 0xdd; + enc_ei.key[4] = 0xee; + enc_ei.key[5] = 0xff; + enc_ei.key[6] = 0x23; + enc_ei.key[7] = 0x42; + enc_ei.key_len = 8; + + msg = msgb_alloc(1024, "output buffer"); + rc_enc = gsm0808_enc_encrypt_info(msg, &enc_ei); + OSMO_ASSERT(rc_enc == 11); + OSMO_ASSERT(memcmp(ei_enc_expected, msg->data, msg->len) == 0); + + rc_dec = gsm0808_dec_encrypt_info(&dec_ei, msg->data + 2, msg->len - 2); + OSMO_ASSERT(rc_dec == 9); + + OSMO_ASSERT(memcmp(&enc_ei, &dec_ei, sizeof(enc_ei)) == 0); + + msgb_free(msg); +} + int main(int argc, char **argv) { printf("Testing generation of GSM0808 messages\n"); @@ -598,6 +637,7 @@ test_gsm0808_enc_dec_speech_codec_ext_with_cfg(); test_gsm0808_enc_dec_speech_codec_list(); test_gsm0808_enc_dec_channel_type(); + test_gsm0808_enc_dec_encrypt_info(); printf("Done\n"); return EXIT_SUCCESS; -- To view, visit https://gerrit.osmocom.org/2180 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I8262050a9d9fd3f17462cfbb046c6e034dccc6fb Gerrit-PatchSet: 3 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Apr 4 12:40:59 2017 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Tue, 4 Apr 2017 12:40:59 +0000 Subject: [PATCH] libosmocore[master]: gsm0808: Add utils for Cell Identifier List In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2181 to look at the new patch set (#3). gsm0808: Add utils for Cell Identifier List The planned support for true A over IP requires the encoding of the a Cell Identifier List element (see also BSS_MAP_MSG_PAGING). This commt adds encoding/decoding functionality and tests for the element mentioned above, however, it is not yet actively used. Change-Id: I625245dd1dd396fc2bc189e8cd2c444a33042528 --- M include/osmocom/gsm/gsm0808_utils.h M include/osmocom/gsm/protocol/gsm_08_08.h M src/gsm/gsm0808_utils.c M src/gsm/libosmogsm.map M tests/gsm0808/gsm0808_test.c 5 files changed, 181 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/81/2181/3 diff --git a/include/osmocom/gsm/gsm0808_utils.h b/include/osmocom/gsm/gsm0808_utils.h index edaa915..e335aa4 100644 --- a/include/osmocom/gsm/gsm0808_utils.h +++ b/include/osmocom/gsm/gsm0808_utils.h @@ -62,3 +62,11 @@ /* Decode Encryption Information element */ int gsm0808_dec_encrypt_info(struct gsm0808_encrypt_info *ei, const uint8_t *elem, uint8_t len); + +/* Encode Cell Identifier List element */ +uint8_t gsm0808_enc_cell_id_list(struct msgb *msg, + struct gsm0808_cell_id_list *cil); + +/* Decode Cell Identifier List element */ +int gsm0808_dec_cell_id_list(struct gsm0808_cell_id_list *cil, + const uint8_t *elem, uint8_t len); diff --git a/include/osmocom/gsm/protocol/gsm_08_08.h b/include/osmocom/gsm/protocol/gsm_08_08.h index 3939aed..e5e7e1e 100644 --- a/include/osmocom/gsm/protocol/gsm_08_08.h +++ b/include/osmocom/gsm/protocol/gsm_08_08.h @@ -457,3 +457,11 @@ uint8_t key[ENCRY_INFO_KEY_MAXLEN]; unsigned int key_len; }; + +/* 3GPP TS 48.008 3.2.2.27 Cell Identifier List */ +#define CELL_ID_LIST_LAC_MAXLEN 127 +struct gsm0808_cell_id_list { + uint8_t id_discr; + uint16_t id_list_lac[CELL_ID_LIST_LAC_MAXLEN]; + unsigned int id_list_len; +}; diff --git a/src/gsm/gsm0808_utils.c b/src/gsm/gsm0808_utils.c index 690ca2e..0ad0268 100644 --- a/src/gsm/gsm0808_utils.c +++ b/src/gsm/gsm0808_utils.c @@ -450,3 +450,81 @@ return (int)(elem - old_elem); } + +/* Encode Cell Identifier List element */ +uint8_t gsm0808_enc_cell_id_list(struct msgb *msg, + struct gsm0808_cell_id_list *cil) +{ + uint8_t *old_tail; + uint8_t *tlv_len; + unsigned int i; + + OSMO_ASSERT(msg); + OSMO_ASSERT(cil); + + msgb_put_u8(msg, GSM0808_IE_CELL_IDENTIFIER_LIST); + tlv_len = msgb_put(msg, 1); + old_tail = msg->tail; + + msgb_put_u8(msg, cil->id_discr & 0x0f); + + switch (cil->id_discr) { + case CELL_IDENT_LAC: + OSMO_ASSERT(cil->id_list_len <= CELL_ID_LIST_LAC_MAXLEN) + for (i=0;iid_list_len;i++) { + msgb_put_u16(msg, cil->id_list_lac[i]); + } + break; + case CELL_IDENT_BSS: + /* Does not have any list items */ + break; + default: + /* FIXME: Implement support for all identifier list elements */ + OSMO_ASSERT(false); + } + + *tlv_len = (uint8_t) (msg->tail - old_tail); + return *tlv_len + 2; +} + +/* Decode Cell Identifier List element */ +int gsm0808_dec_cell_id_list(struct gsm0808_cell_id_list *cil, + const uint8_t *elem, uint8_t len) +{ + uint8_t id_discr; + const uint8_t *old_elem = elem; + unsigned int item_count = 0; + + OSMO_ASSERT(cil); + if (!elem) + return -EINVAL; + if (len <= 0) + return -EINVAL; + + memset(cil, 0, sizeof(*cil)); + + id_discr = *elem & 0x0f; + elem++; + len--; + + cil->id_discr = id_discr; + + switch (id_discr) { + case CELL_IDENT_LAC: + while (len >= 2) { + cil->id_list_lac[item_count] = osmo_load16be(elem); + elem += 2; + item_count++; + len -= 2; + } + case CELL_IDENT_BSS: + /* Does not have any list items */ + break; + default: + /* FIXME: Implement support for all identifier list elements */ + return -EINVAL; + } + + cil->id_list_len = item_count; + return (int)(elem - old_elem); +} diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map index e64fdd9..ac8d467 100644 --- a/src/gsm/libosmogsm.map +++ b/src/gsm/libosmogsm.map @@ -150,6 +150,8 @@ gsm0808_dec_channel_type; gsm0808_enc_encrypt_info; gsm0808_dec_encrypt_info; +gsm0808_enc_cell_id_list; +gsm0808_dec_cell_id_list; gsm0858_rsl_ul_meas_enc; diff --git a/tests/gsm0808/gsm0808_test.c b/tests/gsm0808/gsm0808_test.c index 67a790b..ab555d2 100644 --- a/tests/gsm0808/gsm0808_test.c +++ b/tests/gsm0808/gsm0808_test.c @@ -611,6 +611,88 @@ msgb_free(msg); } +static void test_gsm0808_enc_dec_cell_id_list_lac() +{ + struct gsm0808_cell_id_list enc_cil; + struct gsm0808_cell_id_list dec_cil; + struct msgb *msg; + uint8_t rc_enc; + int rc_dec; + + memset(&enc_cil, 0, sizeof(enc_cil)); + enc_cil.id_discr = CELL_IDENT_LAC; + enc_cil.id_list_lac[0] = 0x0124; + enc_cil.id_list_lac[1] = 0xABCD; + enc_cil.id_list_lac[2] = 0x5678; + enc_cil.id_list_len = 3; + + msg = msgb_alloc(1024, "output buffer"); + rc_enc = gsm0808_enc_cell_id_list(msg, &enc_cil); + OSMO_ASSERT(rc_enc == 9); + + rc_dec = gsm0808_dec_cell_id_list(&dec_cil, msg->data + 2, + msg->len - 2); + OSMO_ASSERT(rc_dec == 7); + + OSMO_ASSERT(memcmp(&enc_cil, &dec_cil, sizeof(enc_cil)) == 0); + + msgb_free(msg); +} + +static void test_gsm0808_enc_dec_cell_id_list_single_lac() +{ + struct gsm0808_cell_id_list enc_cil; + struct gsm0808_cell_id_list dec_cil; + struct msgb *msg; + uint8_t cil_enc_expected[] = { GSM0808_IE_CELL_IDENTIFIER_LIST, 0x03, + 0x05, 0x23, 0x42 + }; + uint8_t rc_enc; + int rc_dec; + + memset(&enc_cil, 0, sizeof(enc_cil)); + enc_cil.id_discr = CELL_IDENT_LAC; + enc_cil.id_list_lac[0] = 0x2342; + enc_cil.id_list_len = 1; + + msg = msgb_alloc(1024, "output buffer"); + rc_enc = gsm0808_enc_cell_id_list(msg, &enc_cil); + OSMO_ASSERT(rc_enc == 5); + OSMO_ASSERT(memcmp(cil_enc_expected, msg->data, msg->len) == 0); + + rc_dec = gsm0808_dec_cell_id_list(&dec_cil, msg->data + 2, + msg->len - 2); + OSMO_ASSERT(rc_dec == 3); + + OSMO_ASSERT(memcmp(&enc_cil, &dec_cil, sizeof(enc_cil)) == 0); + + msgb_free(msg); +} + +static void test_gsm0808_enc_dec_cell_id_list_bss() +{ + struct gsm0808_cell_id_list enc_cil; + struct gsm0808_cell_id_list dec_cil; + struct msgb *msg; + uint8_t rc_enc; + int rc_dec; + + memset(&enc_cil, 0, sizeof(enc_cil)); + enc_cil.id_discr = CELL_IDENT_LAC; + + msg = msgb_alloc(1024, "output buffer"); + rc_enc = gsm0808_enc_cell_id_list(msg, &enc_cil); + OSMO_ASSERT(rc_enc == 3); + + rc_dec = gsm0808_dec_cell_id_list(&dec_cil, msg->data + 2, + msg->len - 2); + OSMO_ASSERT(rc_dec == 1); + + OSMO_ASSERT(memcmp(&enc_cil, &dec_cil, sizeof(enc_cil)) == 0); + + msgb_free(msg); +} + int main(int argc, char **argv) { printf("Testing generation of GSM0808 messages\n"); @@ -638,6 +720,9 @@ test_gsm0808_enc_dec_speech_codec_list(); test_gsm0808_enc_dec_channel_type(); test_gsm0808_enc_dec_encrypt_info(); + test_gsm0808_enc_dec_cell_id_list_lac(); + test_gsm0808_enc_dec_cell_id_list_single_lac(); + test_gsm0808_enc_dec_cell_id_list_bss(); printf("Done\n"); return EXIT_SUCCESS; -- To view, visit https://gerrit.osmocom.org/2181 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I625245dd1dd396fc2bc189e8cd2c444a33042528 Gerrit-PatchSet: 3 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Apr 4 12:40:59 2017 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Tue, 4 Apr 2017 12:40:59 +0000 Subject: [PATCH] libosmocore[master]: gsm0808: Add create functions for CIPHER MODE COMMAND In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2182 to look at the new patch set (#3). gsm0808: Add create functions for CIPHER MODE COMMAND gsm0808.h/c lacks functionality to generate CIPHER MODE COMMAND messages. These messages are required if the code is used in an MSC implementation. This commit adds a gsm0808_create_cipher() function, that generates an A/AoiP CIPHER MODE COMMAND message. Change-Id: I8eb1c357860c3e740b0f5d17e1c256bc87920958 --- M include/osmocom/gsm/gsm0808.h M src/gsm/gsm0808.c M src/gsm/libosmogsm.map M tests/gsm0808/gsm0808_test.c M tests/gsm0808/gsm0808_test.ok 5 files changed, 78 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/82/2182/3 diff --git a/include/osmocom/gsm/gsm0808.h b/include/osmocom/gsm/gsm0808.h index fd0d5ee..7e7cd46 100644 --- a/include/osmocom/gsm/gsm0808.h +++ b/include/osmocom/gsm/gsm0808.h @@ -34,6 +34,8 @@ struct msgb *gsm0808_create_reset_ack(void); struct msgb *gsm0808_create_clear_command(uint8_t reason); struct msgb *gsm0808_create_clear_complete(void); +struct msgb *gsm0808_create_cipher(struct gsm0808_encrypt_info *ei, + uint8_t *cipher_response_mode); struct msgb *gsm0808_create_cipher_complete(struct msgb *layer3, uint8_t alg_id); struct msgb *gsm0808_create_cipher_reject(uint8_t cause); struct msgb *gsm0808_create_classmark_update(const uint8_t *cm2, uint8_t cm2_len, diff --git a/src/gsm/gsm0808.c b/src/gsm/gsm0808.c index 0dc7b8e..b71a0a1 100644 --- a/src/gsm/gsm0808.c +++ b/src/gsm/gsm0808.c @@ -131,6 +131,39 @@ return msg; } +struct msgb *gsm0808_create_cipher(struct gsm0808_encrypt_info *ei, + uint8_t *cipher_response_mode) +{ + /* See also: 3GPP TS 48.008 3.2.1.30 CIPHER MODE COMMAND */ + struct msgb *msg; + + /* Mandatory emelent! */ + OSMO_ASSERT(ei); + + msg = + msgb_alloc_headroom(BSSMAP_MSG_SIZE, BSSMAP_MSG_HEADROOM, + "cipher-mode-command"); + if (!msg) + return NULL; + + /* Message Type 3.2.2.1 */ + msgb_v_put(msg, BSS_MAP_MSG_CIPHER_MODE_CMD); + + /* Encryption Information 3.2.2.10 */ + gsm0808_enc_encrypt_info(msg, ei); + + /* Cipher Response Mode 3.2.2.34 */ + if (cipher_response_mode) + msgb_tv_put(msg, GSM0808_IE_CIPHER_RESPONSE_MODE, + *cipher_response_mode); + + /* pre-pend the header */ + msg->l3h = + msgb_tv_push(msg, BSSAP_MSG_BSS_MANAGEMENT, msgb_length(msg)); + + return msg; +} + struct msgb *gsm0808_create_cipher_complete(struct msgb *layer3, uint8_t alg_id) { struct msgb *msg = msgb_alloc_headroom(BSSMAP_MSG_SIZE, BSSMAP_MSG_HEADROOM, diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map index ac8d467..2826cd8 100644 --- a/src/gsm/libosmogsm.map +++ b/src/gsm/libosmogsm.map @@ -128,6 +128,7 @@ gsm0808_create_assignment_completed_aoip; gsm0808_create_assignment_failure; gsm0808_create_assignment_failure_aoip; +gsm0808_create_cipher; gsm0808_create_cipher_complete; gsm0808_create_cipher_reject; gsm0808_create_classmark_update; diff --git a/tests/gsm0808/gsm0808_test.c b/tests/gsm0808/gsm0808_test.c index ab555d2..bf979bb 100644 --- a/tests/gsm0808/gsm0808_test.c +++ b/tests/gsm0808/gsm0808_test.c @@ -144,6 +144,46 @@ msgb_free(msg); } +static void test_create_cipher() +{ + static const uint8_t res[] = + { 0x00, 0x0c, 0x53, 0x0a, 0x09, 0x03, 0xaa, + 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x23, 0x42 }; + static const uint8_t res2[] = + { 0x00, 0x0e, 0x53, 0x0a, 0x09, 0x03, 0xaa, + 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x23, 0x42, + GSM0808_IE_CIPHER_RESPONSE_MODE, 0x01 }; + struct msgb *msg; + struct gsm0808_encrypt_info ei; + uint8_t include_imeisv; + + memset(&ei, 0, sizeof(ei)); + ei.perm_algo[0] = GSM0808_ALG_ID_A5_0; + ei.perm_algo[1] = GSM0808_ALG_ID_A5_1; + ei.perm_algo_len = 2; + ei.key[0] = 0xaa; + ei.key[1] = 0xbb; + ei.key[2] = 0xcc; + ei.key[3] = 0xdd; + ei.key[4] = 0xee; + ei.key[5] = 0xff; + ei.key[6] = 0x23; + ei.key[7] = 0x42; + ei.key_len = 8; + include_imeisv = 1; + + printf("Testing creating Chipher Mode Command\n"); + msg = gsm0808_create_cipher(&ei, NULL); + OSMO_ASSERT(msg); + VERIFY(msg, res, ARRAY_SIZE(res)); + msgb_free(msg); + + msg = gsm0808_create_cipher(&ei, &include_imeisv); + OSMO_ASSERT(msg); + VERIFY(msg, res2, ARRAY_SIZE(res2)); + msgb_free(msg); +} + static void test_create_cipher_complete() { static const uint8_t res1[] = { @@ -701,6 +741,7 @@ test_create_reset(); test_create_clear_command(); test_create_clear_complete(); + test_create_cipher(); test_create_cipher_complete(); test_create_cipher_reject(); test_create_cm_u(); diff --git a/tests/gsm0808/gsm0808_test.ok b/tests/gsm0808/gsm0808_test.ok index f406551..8e2087d 100644 --- a/tests/gsm0808/gsm0808_test.ok +++ b/tests/gsm0808/gsm0808_test.ok @@ -4,6 +4,7 @@ Testing creating Reset Testing creating Clear Command Testing creating Clear Complete +Testing creating Chipher Mode Command Testing creating Cipher Complete Testing creating Cipher Reject Testing creating CM U -- To view, visit https://gerrit.osmocom.org/2182 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I8eb1c357860c3e740b0f5d17e1c256bc87920958 Gerrit-PatchSet: 3 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Apr 4 12:40:59 2017 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Tue, 4 Apr 2017 12:40:59 +0000 Subject: [PATCH] libosmocore[master]: gsm0808: Add create functions for BSS_MAP_MSG_PAGING In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2183 to look at the new patch set (#3). gsm0808: Add create functions for BSS_MAP_MSG_PAGING gsm0808.h/c lacks functionality to generate BSS_MAP_MSG_PAGING messages. These messages are required if the code is used in an MSC implementation. This commit adds a gsm0808_create_paging() function, that generates an A/AoiP BSS_MAP_MSG_PAGING message. Change-Id: I9afecf0109305ca5153bf081bb29cd94071dd2b7 --- M include/osmocom/gsm/gsm0808.h M src/gsm/gsm0808.c M src/gsm/libosmogsm.map M tests/gsm0808/gsm0808_test.c M tests/gsm0808/gsm0808_test.ok 5 files changed, 108 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/83/2183/3 diff --git a/include/osmocom/gsm/gsm0808.h b/include/osmocom/gsm/gsm0808.h index 7e7cd46..db9a505 100644 --- a/include/osmocom/gsm/gsm0808.h +++ b/include/osmocom/gsm/gsm0808.h @@ -62,6 +62,9 @@ *scl); struct msgb *gsm0808_create_assignment_failure(uint8_t cause, uint8_t *rr_cause); struct msgb *gsm0808_create_clear_rqst(uint8_t cause); +struct msgb *gsm0808_create_paging(char *imsi, uint32_t *tmsi, + struct gsm0808_cell_id_list *cil, + uint8_t *chan_needed); struct msgb *gsm0808_create_dtap(struct msgb *msg, uint8_t link_id); void gsm0808_prepend_dtap_header(struct msgb *msg, uint8_t link_id); diff --git a/src/gsm/gsm0808.c b/src/gsm/gsm0808.c index b71a0a1..daed85c 100644 --- a/src/gsm/gsm0808.c +++ b/src/gsm/gsm0808.c @@ -360,6 +360,67 @@ return msg; } +struct msgb *gsm0808_create_paging(char *imsi, uint32_t *tmsi, + struct gsm0808_cell_id_list *cil, + uint8_t *chan_needed) +{ + struct msgb *msg; + struct msgb *cil_encoded; + uint8_t mid_buf[GSM48_MI_SIZE + 2]; + int mid_len; + uint32_t tmsi_sw; + + /* Mandatory emelents! */ + OSMO_ASSERT(imsi); + OSMO_ASSERT(cil); + + /* Malformed IMSI */ + OSMO_ASSERT(strlen(imsi) <= GSM48_MI_SIZE); + + msg = + msgb_alloc_headroom(BSSMAP_MSG_SIZE, BSSMAP_MSG_HEADROOM, "paging"); + if (!msg) + return NULL; + + /* Message Type 3.2.2.1 */ + msgb_v_put(msg, BSS_MAP_MSG_PAGING); + + /* IMSI 3.2.2.6 */ + mid_len = gsm48_generate_mid_from_imsi(mid_buf, imsi); + msgb_tlv_put(msg, GSM0808_IE_IMSI, mid_len - 2, mid_buf + 2); + + /* TMSI 3.2.2.7 */ + if (tmsi) { + tmsi_sw = htonl(*tmsi); + msgb_tlv_put(msg, GSM0808_IE_TMSI, sizeof(*tmsi), + (uint8_t *) & tmsi_sw); + } + + /* Cell Identifier List 3.2.2.27 */ + if (cil) { + cil_encoded = gsm0808_enc_cell_id_list(cil); + if (!cil_encoded) { + msgb_free(msg); + return NULL; + } + msgb_tlv_put(msg, GSM0808_IE_CELL_IDENTIFIER_LIST, + cil_encoded->len, cil_encoded->data); + msgb_free(cil_encoded); + } + + /* Channel Needed 3.2.2.36 */ + if (chan_needed) { + msgb_tv_put(msg, GSM0808_IE_CHANNEL_NEEDED, + (*chan_needed) & 0x03); + } + + /* pre-pend the header */ + msg->l3h = + msgb_tv_push(msg, BSSAP_MSG_BSS_MANAGEMENT, msgb_length(msg)); + + return msg; +} + void gsm0808_prepend_dtap_header(struct msgb *msg, uint8_t link_id) { uint8_t *hh = msgb_push(msg, 3); diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map index 2826cd8..fb06bff 100644 --- a/src/gsm/libosmogsm.map +++ b/src/gsm/libosmogsm.map @@ -135,6 +135,7 @@ gsm0808_create_clear_command; gsm0808_create_clear_complete; gsm0808_create_clear_rqst; +gsm0808_create_paging; gsm0808_create_dtap; gsm0808_create_layer3; gsm0808_create_layer3_aoip; diff --git a/tests/gsm0808/gsm0808_test.c b/tests/gsm0808/gsm0808_test.c index bf979bb..02de5e1 100644 --- a/tests/gsm0808/gsm0808_test.c +++ b/tests/gsm0808/gsm0808_test.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -368,6 +369,46 @@ printf("Testing creating Clear Request\n"); msg = gsm0808_create_clear_rqst(0x23); VERIFY(msg, res, ARRAY_SIZE(res)); + msgb_free(msg); +} + +static void test_create_paging() +{ + static const uint8_t res[] = + { 0x00, 0x10, 0x52, 0x08, 0x08, 0x09, 0x10, 0x10, 0x00, 0x00, 0x00, + 0x21, 0x43, 0x1a, 0x03, 0x05, 0x23, 0x42 }; + static const uint8_t res2[] = + { 0x00, 0x16, 0x52, 0x08, 0x08, 0x09, 0x10, 0x10, 0x00, 0x00, 0x00, + 0x21, 0x43, GSM0808_IE_TMSI, 0x04, 0x12, 0x34, 0x56, 0x78, 0x1a, + 0x03, 0x05, 0x23, 0x42 }; + static const uint8_t res3[] = + { 0x00, 0x18, 0x52, 0x08, 0x08, 0x09, 0x10, 0x10, 0x00, 0x00, 0x00, + 0x21, 0x43, GSM0808_IE_TMSI, 0x04, 0x12, 0x34, 0x56, 0x78, 0x1a, + 0x03, 0x05, 0x23, 0x42, GSM0808_IE_CHANNEL_NEEDED, + RSL_CHANNEED_TCH_ForH }; + + struct msgb *msg; + struct gsm0808_cell_id_list cil; + uint32_t tmsi = 0x12345678; + uint8_t chan_needed = RSL_CHANNEED_TCH_ForH; + + char imsi[] = "001010000001234"; + + cil.id_discr = CELL_IDENT_LAC; + cil.id_list_lac[0] = 0x2342; + cil.id_list_len = 1; + + printf("Testing creating Paging Request\n"); + msg = gsm0808_create_paging(imsi, NULL, &cil, NULL); + VERIFY(msg, res, ARRAY_SIZE(res)); + msgb_free(msg); + + msg = gsm0808_create_paging(imsi, &tmsi, &cil, NULL); + VERIFY(msg, res2, ARRAY_SIZE(res2)); + msgb_free(msg); + + msg = gsm0808_create_paging(imsi, &tmsi, &cil, &chan_needed); + VERIFY(msg, res3, ARRAY_SIZE(res3)); msgb_free(msg); } @@ -751,6 +792,7 @@ test_create_ass_fail(); test_create_ass_fail_aoip(); test_create_clear_rqst(); + test_create_paging(); test_create_dtap(); test_prepend_dtap(); test_enc_dec_aoip_trasp_addr_v4(); diff --git a/tests/gsm0808/gsm0808_test.ok b/tests/gsm0808/gsm0808_test.ok index 8e2087d..6170a7a 100644 --- a/tests/gsm0808/gsm0808_test.ok +++ b/tests/gsm0808/gsm0808_test.ok @@ -14,6 +14,7 @@ Testing creating Assignment Failure Testing creating Assignment Failure (AoIP) Testing creating Clear Request +Testing creating Paging Request Testing creating DTAP Testing prepend DTAP Done -- To view, visit https://gerrit.osmocom.org/2183 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I9afecf0109305ca5153bf081bb29cd94071dd2b7 Gerrit-PatchSet: 3 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Apr 4 12:40:59 2017 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Tue, 4 Apr 2017 12:40:59 +0000 Subject: [PATCH] libosmocore[master]: gsm0808: Add create functions for BSS_MAP_MSG_ASSIGMENT_RQST In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2184 to look at the new patch set (#3). gsm0808: Add create functions for BSS_MAP_MSG_ASSIGMENT_RQST gsm0808.h/c lacks functionality to generate BSS_MAP_MSG_ASSIGMENT_RQST messages. These messages are required if the code is used in an MSC implementation. This commit adds a gsm0808_create_assignment() function, that generates an A/AoiP BSS_MAP_MSG_PAGING message. Change-Id: I4d1d455a1e1cf95407e23ded7b7defbcf2dd6ff0 --- M include/osmocom/gsm/gsm0808.h M src/gsm/gsm0808.c M src/gsm/libosmogsm.map M tests/gsm0808/gsm0808_test.c M tests/gsm0808/gsm0808_test.ok 5 files changed, 115 insertions(+), 11 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/84/2184/3 diff --git a/include/osmocom/gsm/gsm0808.h b/include/osmocom/gsm/gsm0808.h index db9a505..031215e 100644 --- a/include/osmocom/gsm/gsm0808.h +++ b/include/osmocom/gsm/gsm0808.h @@ -41,6 +41,11 @@ struct msgb *gsm0808_create_classmark_update(const uint8_t *cm2, uint8_t cm2_len, const uint8_t *cm3, uint8_t cm3_len); struct msgb *gsm0808_create_sapi_reject(uint8_t link_id); +struct msgb *gsm0808_create_assignment(struct gsm0808_channel_type *ct, + uint16_t * cic, + struct sockaddr_storage *ss, + struct gsm0808_speech_codec_list *scl, + uint32_t * ci); struct msgb *gsm0808_create_assignment_completed_aoip(uint8_t rr_cause, uint8_t chosen_channel, uint8_t encr_alg_id, diff --git a/src/gsm/gsm0808.c b/src/gsm/gsm0808.c index daed85c..fd0bf2e 100644 --- a/src/gsm/gsm0808.c +++ b/src/gsm/gsm0808.c @@ -238,6 +238,62 @@ return msg; } +struct msgb *gsm0808_create_assignment(struct gsm0808_channel_type *ct, + uint16_t *cic, + struct sockaddr_storage *ss, + struct gsm0808_speech_codec_list *scl, + uint32_t *ci) +{ + /* See also: 3GPP TS 48.008 3.2.1.1 ASSIGNMENT REQUEST */ + struct msgb *msg; + uint16_t cic_sw; + uint32_t ci_sw; + + /* Mandatory emelent! */ + OSMO_ASSERT(ct); + + msg = + msgb_alloc_headroom(BSSMAP_MSG_SIZE, BSSMAP_MSG_HEADROOM, + "bssmap: ass req"); + if (!msg) + return NULL; + + /* Message Type 3.2.2.1 */ + msgb_v_put(msg, BSS_MAP_MSG_ASSIGMENT_RQST); + + /* Channel Type 3.2.2.11 */ + gsm0808_enc_channel_type(msg, ct); + + /* Circuit Identity Code 3.2.2.2 */ + if (cic) { + cic_sw = htons(*cic); + msgb_tv_fixed_put(msg, GSM0808_IE_CIRCUIT_IDENTITY_CODE, + sizeof(cic_sw), (uint8_t *) & cic_sw); + } + + /* AoIP: AoIP Transport Layer Address (MGW) 3.2.2.102 */ + if (ss) { + gsm0808_enc_aoip_trasp_addr(msg, ss); + } + + /* AoIP: Codec List (MSC Preferred) 3.2.2.103 */ + if (scl) + gsm0808_enc_speech_codec_list(msg, scl); + + /* AoIP: Call Identifier 3.2.2.105 */ + if (ci) { + ci_sw = htonl(*ci); + msgb_tv_fixed_put(msg, GSM0808_IE_CALL_ID, sizeof(ci_sw), + (uint8_t *) & ci_sw); + } + + /* push the bssmap header */ + msg->l3h = + msgb_tv_push(msg, BSSAP_MSG_BSS_MANAGEMENT, msgb_length(msg)); + + return msg; +} + struct msgb *gsm0808_create_assignment_completed_aoip(uint8_t rr_cause, uint8_t chosen_channel, uint8_t encr_alg_id, @@ -365,7 +421,6 @@ uint8_t *chan_needed) { struct msgb *msg; - struct msgb *cil_encoded; uint8_t mid_buf[GSM48_MI_SIZE + 2]; int mid_len; uint32_t tmsi_sw; @@ -397,16 +452,8 @@ } /* Cell Identifier List 3.2.2.27 */ - if (cil) { - cil_encoded = gsm0808_enc_cell_id_list(cil); - if (!cil_encoded) { - msgb_free(msg); - return NULL; - } - msgb_tlv_put(msg, GSM0808_IE_CELL_IDENTIFIER_LIST, - cil_encoded->len, cil_encoded->data); - msgb_free(cil_encoded); - } + if (cil) + gsm0808_enc_cell_id_list(msg, cil); /* Channel Needed 3.2.2.36 */ if (chan_needed) { diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map index fb06bff..fcd13d1 100644 --- a/src/gsm/libosmogsm.map +++ b/src/gsm/libosmogsm.map @@ -124,6 +124,7 @@ gsm0808_att_tlvdef; gsm0808_bssap_name; gsm0808_bssmap_name; +gsm0808_create_assignment; gsm0808_create_assignment_completed; gsm0808_create_assignment_completed_aoip; gsm0808_create_assignment_failure; diff --git a/tests/gsm0808/gsm0808_test.c b/tests/gsm0808/gsm0808_test.c index 02de5e1..521ae24 100644 --- a/tests/gsm0808/gsm0808_test.c +++ b/tests/gsm0808/gsm0808_test.c @@ -262,6 +262,55 @@ msgb_free(msg); } +static void test_create_ass() +{ + static const uint8_t res1[] = + { 0x00, 0x0a, 0x01, 0x0b, 0x04, 0x01, 0x0b, 0xa1, 0x25, 0x01, 0x00, + 0x04 }; + static const uint8_t res2[] = + { 0x00, 0x20, 0x01, 0x0b, 0x04, 0x01, 0x0b, 0xa1, 0x25, 0x01, 0x00, + 0x04, GSM0808_IE_AOIP_TRASP_ADDR, 0x06, 0xc0, 0xa8, 0x64, 0x17, + 0x04, 0xd2, GSM0808_IE_SPEECH_CODEC_LIST, 0x07, 0x5f, 0xab, 0xcd, + 0xef, 0xa5, 0x9f, 0xf2, GSM0808_IE_CALL_ID, 0xaa, 0xbb, 0xcc, + 0xdd }; + + struct msgb *msg; + struct gsm0808_channel_type ct; + uint16_t cic = 0004; + struct sockaddr_storage ss; + struct sockaddr_in sin; + struct gsm0808_speech_codec_list sc_list; + uint32_t call_id = 0xAABBCCDD; + + memset(&ct, 0, sizeof(ct)); + ct.ch_indctr = GSM0808_CHAN_SPEECH; + ct.ch_rate_type = GSM0808_SPEECH_HALF_PREF; + ct.perm_spch[0] = GSM0808_PERM_FR3; + ct.perm_spch[1] = GSM0808_PERM_HR3; + ct.perm_spch_len = 2; + + memset(&sin, 0, sizeof(sin)); + sin.sin_family = AF_INET; + sin.sin_port = htons(1234); + inet_aton("192.168.100.23", &sin.sin_addr); + + memset(&ss, 0, sizeof(ss)); + memcpy(&ss, &sin, sizeof(sin)); + + setup_codec_list(&sc_list); + + printf("Testing creating Assignment Request\n"); + msg = gsm0808_create_assignment(&ct, &cic, NULL, NULL, NULL); + OSMO_ASSERT(msg); + VERIFY(msg, res1, ARRAY_SIZE(res1)); + msgb_free(msg); + + msg = gsm0808_create_assignment(&ct, &cic, &ss, &sc_list, &call_id); + OSMO_ASSERT(msg); + VERIFY(msg, res2, ARRAY_SIZE(res2)); + msgb_free(msg); +} + static void test_create_ass_compl() { static const uint8_t res1[] = { @@ -787,6 +836,7 @@ test_create_cipher_reject(); test_create_cm_u(); test_create_sapi_reject(); + test_create_ass(); test_create_ass_compl(); test_create_ass_compl_aoip(); test_create_ass_fail(); diff --git a/tests/gsm0808/gsm0808_test.ok b/tests/gsm0808/gsm0808_test.ok index 6170a7a..52af134 100644 --- a/tests/gsm0808/gsm0808_test.ok +++ b/tests/gsm0808/gsm0808_test.ok @@ -9,6 +9,7 @@ Testing creating Cipher Reject Testing creating CM U Testing creating SAPI Reject +Testing creating Assignment Request Testing creating Assignment Complete Testing creating Assignment Complete (AoIP) Testing creating Assignment Failure -- To view, visit https://gerrit.osmocom.org/2184 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I4d1d455a1e1cf95407e23ded7b7defbcf2dd6ff0 Gerrit-PatchSet: 3 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Apr 4 12:43:17 2017 From: gerrit-no-reply at lists.osmocom.org (Pau Espin Pedrol) Date: Tue, 4 Apr 2017 12:43:17 +0000 Subject: libosmo-abis[master]: Fix HAVE_ORTP_LOG_DOMAIN detection on FreeBSD In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+1 -- To view, visit https://gerrit.osmocom.org/2222 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I0c95e37cc449297389bf31dd9d5dcaa922d75d0c Gerrit-PatchSet: 2 Gerrit-Project: libosmo-abis Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Pau Espin Pedrol Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Apr 4 12:51:12 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 4 Apr 2017 12:51:12 +0000 Subject: libosmocore[master]: gsm0808: Add utils for Speech Codec List and Speech Codec In-Reply-To: References: Message-ID: Patch Set 3: Code-Review+1 (3 comments) with const, it would be perfect :) https://gerrit.osmocom.org/#/c/2177/3/include/osmocom/gsm/gsm0808_utils.h File include/osmocom/gsm/gsm0808_utils.h: Line 28: struct sockaddr_storage *ss); const Line 36: struct gsm0808_speech_codec *sc); for encoding functions, we generally use "const *" input to indicate that this is read-only input data. Line 44: struct gsm0808_speech_codec_list *scl); const -- To view, visit https://gerrit.osmocom.org/2177 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I0e1e2edf47adaa45b22d4b0bcae3640dba7ca200 Gerrit-PatchSet: 3 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Tue Apr 4 12:53:07 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 4 Apr 2017 12:53:07 +0000 Subject: libosmocore[master]: gsm0808: Add utils for AoIP Transport Layer Address In-Reply-To: References: Message-ID: Patch Set 3: Code-Review+1 (1 comment) https://gerrit.osmocom.org/#/c/2176/3/include/osmocom/gsm/gsm0808_utils.h File include/osmocom/gsm/gsm0808_utils.h: Line 25: uint8_t gsm0808_enc_aoip_trasp_addr(struct msgb *msg, in terms of the naming, I'm still wondering. msgb_put_gsm0808_aoip_transp_addr() would e more expressive, but it's even longer... so let's just go ahead with current naming -- To view, visit https://gerrit.osmocom.org/2176 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I57933b0a06a3f54ec2a41e6ecb6ced9fbbc89332 Gerrit-PatchSet: 3 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Tue Apr 4 13:38:18 2017 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Tue, 4 Apr 2017 13:38:18 +0000 Subject: [PATCH] libosmocore[master]: gsm0808: Add create functions for BSS_MAP_MSG_PAGING In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2183 to look at the new patch set (#4). gsm0808: Add create functions for BSS_MAP_MSG_PAGING gsm0808.h/c lacks functionality to generate BSS_MAP_MSG_PAGING messages. These messages are required if the code is used in an MSC implementation. This commit adds a gsm0808_create_paging() function, that generates an A/AoiP BSS_MAP_MSG_PAGING message. Change-Id: I9afecf0109305ca5153bf081bb29cd94071dd2b7 --- M include/osmocom/gsm/gsm0808.h M src/gsm/gsm0808.c M src/gsm/libosmogsm.map M tests/gsm0808/gsm0808_test.c M tests/gsm0808/gsm0808_test.ok 5 files changed, 99 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/83/2183/4 diff --git a/include/osmocom/gsm/gsm0808.h b/include/osmocom/gsm/gsm0808.h index 7e7cd46..db9a505 100644 --- a/include/osmocom/gsm/gsm0808.h +++ b/include/osmocom/gsm/gsm0808.h @@ -62,6 +62,9 @@ *scl); struct msgb *gsm0808_create_assignment_failure(uint8_t cause, uint8_t *rr_cause); struct msgb *gsm0808_create_clear_rqst(uint8_t cause); +struct msgb *gsm0808_create_paging(char *imsi, uint32_t *tmsi, + struct gsm0808_cell_id_list *cil, + uint8_t *chan_needed); struct msgb *gsm0808_create_dtap(struct msgb *msg, uint8_t link_id); void gsm0808_prepend_dtap_header(struct msgb *msg, uint8_t link_id); diff --git a/src/gsm/gsm0808.c b/src/gsm/gsm0808.c index b71a0a1..01d54ef 100644 --- a/src/gsm/gsm0808.c +++ b/src/gsm/gsm0808.c @@ -360,6 +360,58 @@ return msg; } +struct msgb *gsm0808_create_paging(char *imsi, uint32_t *tmsi, + struct gsm0808_cell_id_list *cil, + uint8_t *chan_needed) +{ + struct msgb *msg; + uint8_t mid_buf[GSM48_MI_SIZE + 2]; + int mid_len; + uint32_t tmsi_sw; + + /* Mandatory emelents! */ + OSMO_ASSERT(imsi); + OSMO_ASSERT(cil); + + /* Malformed IMSI */ + OSMO_ASSERT(strlen(imsi) <= GSM48_MI_SIZE); + + msg = + msgb_alloc_headroom(BSSMAP_MSG_SIZE, BSSMAP_MSG_HEADROOM, "paging"); + if (!msg) + return NULL; + + /* Message Type 3.2.2.1 */ + msgb_v_put(msg, BSS_MAP_MSG_PAGING); + + /* IMSI 3.2.2.6 */ + mid_len = gsm48_generate_mid_from_imsi(mid_buf, imsi); + msgb_tlv_put(msg, GSM0808_IE_IMSI, mid_len - 2, mid_buf + 2); + + /* TMSI 3.2.2.7 */ + if (tmsi) { + tmsi_sw = htonl(*tmsi); + msgb_tlv_put(msg, GSM0808_IE_TMSI, sizeof(*tmsi), + (uint8_t *) & tmsi_sw); + } + + /* Cell Identifier List 3.2.2.27 */ + if (cil) + gsm0808_enc_cell_id_list(msg, cil); + + /* Channel Needed 3.2.2.36 */ + if (chan_needed) { + msgb_tv_put(msg, GSM0808_IE_CHANNEL_NEEDED, + (*chan_needed) & 0x03); + } + + /* pre-pend the header */ + msg->l3h = + msgb_tv_push(msg, BSSAP_MSG_BSS_MANAGEMENT, msgb_length(msg)); + + return msg; +} + void gsm0808_prepend_dtap_header(struct msgb *msg, uint8_t link_id) { uint8_t *hh = msgb_push(msg, 3); diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map index 2826cd8..fb06bff 100644 --- a/src/gsm/libosmogsm.map +++ b/src/gsm/libosmogsm.map @@ -135,6 +135,7 @@ gsm0808_create_clear_command; gsm0808_create_clear_complete; gsm0808_create_clear_rqst; +gsm0808_create_paging; gsm0808_create_dtap; gsm0808_create_layer3; gsm0808_create_layer3_aoip; diff --git a/tests/gsm0808/gsm0808_test.c b/tests/gsm0808/gsm0808_test.c index bf979bb..02de5e1 100644 --- a/tests/gsm0808/gsm0808_test.c +++ b/tests/gsm0808/gsm0808_test.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -368,6 +369,46 @@ printf("Testing creating Clear Request\n"); msg = gsm0808_create_clear_rqst(0x23); VERIFY(msg, res, ARRAY_SIZE(res)); + msgb_free(msg); +} + +static void test_create_paging() +{ + static const uint8_t res[] = + { 0x00, 0x10, 0x52, 0x08, 0x08, 0x09, 0x10, 0x10, 0x00, 0x00, 0x00, + 0x21, 0x43, 0x1a, 0x03, 0x05, 0x23, 0x42 }; + static const uint8_t res2[] = + { 0x00, 0x16, 0x52, 0x08, 0x08, 0x09, 0x10, 0x10, 0x00, 0x00, 0x00, + 0x21, 0x43, GSM0808_IE_TMSI, 0x04, 0x12, 0x34, 0x56, 0x78, 0x1a, + 0x03, 0x05, 0x23, 0x42 }; + static const uint8_t res3[] = + { 0x00, 0x18, 0x52, 0x08, 0x08, 0x09, 0x10, 0x10, 0x00, 0x00, 0x00, + 0x21, 0x43, GSM0808_IE_TMSI, 0x04, 0x12, 0x34, 0x56, 0x78, 0x1a, + 0x03, 0x05, 0x23, 0x42, GSM0808_IE_CHANNEL_NEEDED, + RSL_CHANNEED_TCH_ForH }; + + struct msgb *msg; + struct gsm0808_cell_id_list cil; + uint32_t tmsi = 0x12345678; + uint8_t chan_needed = RSL_CHANNEED_TCH_ForH; + + char imsi[] = "001010000001234"; + + cil.id_discr = CELL_IDENT_LAC; + cil.id_list_lac[0] = 0x2342; + cil.id_list_len = 1; + + printf("Testing creating Paging Request\n"); + msg = gsm0808_create_paging(imsi, NULL, &cil, NULL); + VERIFY(msg, res, ARRAY_SIZE(res)); + msgb_free(msg); + + msg = gsm0808_create_paging(imsi, &tmsi, &cil, NULL); + VERIFY(msg, res2, ARRAY_SIZE(res2)); + msgb_free(msg); + + msg = gsm0808_create_paging(imsi, &tmsi, &cil, &chan_needed); + VERIFY(msg, res3, ARRAY_SIZE(res3)); msgb_free(msg); } @@ -751,6 +792,7 @@ test_create_ass_fail(); test_create_ass_fail_aoip(); test_create_clear_rqst(); + test_create_paging(); test_create_dtap(); test_prepend_dtap(); test_enc_dec_aoip_trasp_addr_v4(); diff --git a/tests/gsm0808/gsm0808_test.ok b/tests/gsm0808/gsm0808_test.ok index 8e2087d..6170a7a 100644 --- a/tests/gsm0808/gsm0808_test.ok +++ b/tests/gsm0808/gsm0808_test.ok @@ -14,6 +14,7 @@ Testing creating Assignment Failure Testing creating Assignment Failure (AoIP) Testing creating Clear Request +Testing creating Paging Request Testing creating DTAP Testing prepend DTAP Done -- To view, visit https://gerrit.osmocom.org/2183 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I9afecf0109305ca5153bf081bb29cd94071dd2b7 Gerrit-PatchSet: 4 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Apr 4 13:38:18 2017 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Tue, 4 Apr 2017 13:38:18 +0000 Subject: [PATCH] libosmocore[master]: gsm0808: Add create functions for BSS_MAP_MSG_ASSIGMENT_RQST In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2184 to look at the new patch set (#4). gsm0808: Add create functions for BSS_MAP_MSG_ASSIGMENT_RQST gsm0808.h/c lacks functionality to generate BSS_MAP_MSG_ASSIGMENT_RQST messages. These messages are required if the code is used in an MSC implementation. This commit adds a gsm0808_create_assignment() function, that generates an A/AoiP BSS_MAP_MSG_PAGING message. Change-Id: I4d1d455a1e1cf95407e23ded7b7defbcf2dd6ff0 --- M include/osmocom/gsm/gsm0808.h M src/gsm/gsm0808.c M src/gsm/libosmogsm.map M tests/gsm0808/gsm0808_test.c M tests/gsm0808/gsm0808_test.ok 5 files changed, 113 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/84/2184/4 diff --git a/include/osmocom/gsm/gsm0808.h b/include/osmocom/gsm/gsm0808.h index db9a505..031215e 100644 --- a/include/osmocom/gsm/gsm0808.h +++ b/include/osmocom/gsm/gsm0808.h @@ -41,6 +41,11 @@ struct msgb *gsm0808_create_classmark_update(const uint8_t *cm2, uint8_t cm2_len, const uint8_t *cm3, uint8_t cm3_len); struct msgb *gsm0808_create_sapi_reject(uint8_t link_id); +struct msgb *gsm0808_create_assignment(struct gsm0808_channel_type *ct, + uint16_t * cic, + struct sockaddr_storage *ss, + struct gsm0808_speech_codec_list *scl, + uint32_t * ci); struct msgb *gsm0808_create_assignment_completed_aoip(uint8_t rr_cause, uint8_t chosen_channel, uint8_t encr_alg_id, diff --git a/src/gsm/gsm0808.c b/src/gsm/gsm0808.c index 01d54ef..fd0bf2e 100644 --- a/src/gsm/gsm0808.c +++ b/src/gsm/gsm0808.c @@ -238,6 +238,62 @@ return msg; } +struct msgb *gsm0808_create_assignment(struct gsm0808_channel_type *ct, + uint16_t *cic, + struct sockaddr_storage *ss, + struct gsm0808_speech_codec_list *scl, + uint32_t *ci) +{ + /* See also: 3GPP TS 48.008 3.2.1.1 ASSIGNMENT REQUEST */ + struct msgb *msg; + uint16_t cic_sw; + uint32_t ci_sw; + + /* Mandatory emelent! */ + OSMO_ASSERT(ct); + + msg = + msgb_alloc_headroom(BSSMAP_MSG_SIZE, BSSMAP_MSG_HEADROOM, + "bssmap: ass req"); + if (!msg) + return NULL; + + /* Message Type 3.2.2.1 */ + msgb_v_put(msg, BSS_MAP_MSG_ASSIGMENT_RQST); + + /* Channel Type 3.2.2.11 */ + gsm0808_enc_channel_type(msg, ct); + + /* Circuit Identity Code 3.2.2.2 */ + if (cic) { + cic_sw = htons(*cic); + msgb_tv_fixed_put(msg, GSM0808_IE_CIRCUIT_IDENTITY_CODE, + sizeof(cic_sw), (uint8_t *) & cic_sw); + } + + /* AoIP: AoIP Transport Layer Address (MGW) 3.2.2.102 */ + if (ss) { + gsm0808_enc_aoip_trasp_addr(msg, ss); + } + + /* AoIP: Codec List (MSC Preferred) 3.2.2.103 */ + if (scl) + gsm0808_enc_speech_codec_list(msg, scl); + + /* AoIP: Call Identifier 3.2.2.105 */ + if (ci) { + ci_sw = htonl(*ci); + msgb_tv_fixed_put(msg, GSM0808_IE_CALL_ID, sizeof(ci_sw), + (uint8_t *) & ci_sw); + } + + /* push the bssmap header */ + msg->l3h = + msgb_tv_push(msg, BSSAP_MSG_BSS_MANAGEMENT, msgb_length(msg)); + + return msg; +} + struct msgb *gsm0808_create_assignment_completed_aoip(uint8_t rr_cause, uint8_t chosen_channel, uint8_t encr_alg_id, diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map index fb06bff..fcd13d1 100644 --- a/src/gsm/libosmogsm.map +++ b/src/gsm/libosmogsm.map @@ -124,6 +124,7 @@ gsm0808_att_tlvdef; gsm0808_bssap_name; gsm0808_bssmap_name; +gsm0808_create_assignment; gsm0808_create_assignment_completed; gsm0808_create_assignment_completed_aoip; gsm0808_create_assignment_failure; diff --git a/tests/gsm0808/gsm0808_test.c b/tests/gsm0808/gsm0808_test.c index 02de5e1..521ae24 100644 --- a/tests/gsm0808/gsm0808_test.c +++ b/tests/gsm0808/gsm0808_test.c @@ -262,6 +262,55 @@ msgb_free(msg); } +static void test_create_ass() +{ + static const uint8_t res1[] = + { 0x00, 0x0a, 0x01, 0x0b, 0x04, 0x01, 0x0b, 0xa1, 0x25, 0x01, 0x00, + 0x04 }; + static const uint8_t res2[] = + { 0x00, 0x20, 0x01, 0x0b, 0x04, 0x01, 0x0b, 0xa1, 0x25, 0x01, 0x00, + 0x04, GSM0808_IE_AOIP_TRASP_ADDR, 0x06, 0xc0, 0xa8, 0x64, 0x17, + 0x04, 0xd2, GSM0808_IE_SPEECH_CODEC_LIST, 0x07, 0x5f, 0xab, 0xcd, + 0xef, 0xa5, 0x9f, 0xf2, GSM0808_IE_CALL_ID, 0xaa, 0xbb, 0xcc, + 0xdd }; + + struct msgb *msg; + struct gsm0808_channel_type ct; + uint16_t cic = 0004; + struct sockaddr_storage ss; + struct sockaddr_in sin; + struct gsm0808_speech_codec_list sc_list; + uint32_t call_id = 0xAABBCCDD; + + memset(&ct, 0, sizeof(ct)); + ct.ch_indctr = GSM0808_CHAN_SPEECH; + ct.ch_rate_type = GSM0808_SPEECH_HALF_PREF; + ct.perm_spch[0] = GSM0808_PERM_FR3; + ct.perm_spch[1] = GSM0808_PERM_HR3; + ct.perm_spch_len = 2; + + memset(&sin, 0, sizeof(sin)); + sin.sin_family = AF_INET; + sin.sin_port = htons(1234); + inet_aton("192.168.100.23", &sin.sin_addr); + + memset(&ss, 0, sizeof(ss)); + memcpy(&ss, &sin, sizeof(sin)); + + setup_codec_list(&sc_list); + + printf("Testing creating Assignment Request\n"); + msg = gsm0808_create_assignment(&ct, &cic, NULL, NULL, NULL); + OSMO_ASSERT(msg); + VERIFY(msg, res1, ARRAY_SIZE(res1)); + msgb_free(msg); + + msg = gsm0808_create_assignment(&ct, &cic, &ss, &sc_list, &call_id); + OSMO_ASSERT(msg); + VERIFY(msg, res2, ARRAY_SIZE(res2)); + msgb_free(msg); +} + static void test_create_ass_compl() { static const uint8_t res1[] = { @@ -787,6 +836,7 @@ test_create_cipher_reject(); test_create_cm_u(); test_create_sapi_reject(); + test_create_ass(); test_create_ass_compl(); test_create_ass_compl_aoip(); test_create_ass_fail(); diff --git a/tests/gsm0808/gsm0808_test.ok b/tests/gsm0808/gsm0808_test.ok index 6170a7a..52af134 100644 --- a/tests/gsm0808/gsm0808_test.ok +++ b/tests/gsm0808/gsm0808_test.ok @@ -9,6 +9,7 @@ Testing creating Cipher Reject Testing creating CM U Testing creating SAPI Reject +Testing creating Assignment Request Testing creating Assignment Complete Testing creating Assignment Complete (AoIP) Testing creating Assignment Failure -- To view, visit https://gerrit.osmocom.org/2184 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I4d1d455a1e1cf95407e23ded7b7defbcf2dd6ff0 Gerrit-PatchSet: 4 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Apr 4 13:39:47 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 4 Apr 2017 13:39:47 +0000 Subject: libosmocore[master]: gsm0808: Add AoIP specific elements to gsm0808_create_... fu... In-Reply-To: References: Message-ID: Patch Set 3: Code-Review+1 (2 comments) https://gerrit.osmocom.org/#/c/2178/3/src/gsm/gsm0808.c File src/gsm/gsm0808.c: Line 55: (uint8_t *) & lai_ci); we normally don't mix cosmetic and non-cosmetic changes in a single patch. This one has already three cosmetic changes. Line 208: struct msgb *gsm0808_create_assignment_completed_aoip(uint8_t rr_cause, as we're changing the signature anyway, we might as well shorten the naming. "gsm0808_create_ass_compl" or if you like to prevent the "ass" use "assgn" -- To view, visit https://gerrit.osmocom.org/2178 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I77f866abec1822d19871052f3c647ad782785b34 Gerrit-PatchSet: 3 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Tue Apr 4 13:39:55 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 4 Apr 2017 13:39:55 +0000 Subject: libosmo-abis[master]: Fix HAVE_ORTP_LOG_DOMAIN detection on FreeBSD In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2222 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I0c95e37cc449297389bf31dd9d5dcaa922d75d0c Gerrit-PatchSet: 2 Gerrit-Project: libosmo-abis Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Pau Espin Pedrol Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Apr 4 13:39:57 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 4 Apr 2017 13:39:57 +0000 Subject: [MERGED] libosmo-abis[master]: Fix HAVE_ORTP_LOG_DOMAIN detection on FreeBSD In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: Fix HAVE_ORTP_LOG_DOMAIN detection on FreeBSD ...................................................................... Fix HAVE_ORTP_LOG_DOMAIN detection on FreeBSD We need to use the include path[s] resolved by pkg-config for ortp before trying to compile our test program. Without this patch, compilation will fail e.g. on FreeBSD 11. Change-Id: I0c95e37cc449297389bf31dd9d5dcaa922d75d0c --- M configure.ac 1 file changed, 3 insertions(+), 0 deletions(-) Approvals: Pau Espin Pedrol: Looks good to me, but someone else must approve Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/configure.ac b/configure.ac index 43266be..9b2f189 100644 --- a/configure.ac +++ b/configure.ac @@ -59,6 +59,8 @@ CPPFLAGS+=" -fsanitize=address -fsanitize=undefined" fi +_cflags_save=$CFLAGS +CFLAGS="$CFLAGS $ORTP_CFLAGS" AC_COMPILE_IFELSE( [AC_LANG_PROGRAM( [[#include ]], @@ -68,6 +70,7 @@ [ortp_set_log_level_mask requires domain parameter])], [AC_DEFINE([HAVE_ORTP_LOG_DOMAIN], [0], [ortp_set_log_level_mask has no domain parameter])]) +CFLAGS=$_cflags_save AC_OUTPUT( libosmoabis.pc -- To view, visit https://gerrit.osmocom.org/2222 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I0c95e37cc449297389bf31dd9d5dcaa922d75d0c Gerrit-PatchSet: 2 Gerrit-Project: libosmo-abis Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Pau Espin Pedrol From gerrit-no-reply at lists.osmocom.org Tue Apr 4 13:46:31 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 4 Apr 2017 13:46:31 +0000 Subject: [PATCH] libosmo-sccp[master]: sua: Make use of xua_msg_dialect In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2210 to look at the new patch set (#3). sua: Make use of xua_msg_dialect We fill in the data structures of a xua_msg_dialect and make use of it for generic mandatory IE checking and messageheader printing. Change-Id: I966103f30b9be247ba6905ba8e06b87654d9981a --- M src/sua.c 1 file changed, 162 insertions(+), 112 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/10/2210/3 diff --git a/src/sua.c b/src/sua.c index 145bf1a..659104c 100644 --- a/src/sua.c +++ b/src/sua.c @@ -37,6 +37,8 @@ #include #include +#include "xua_internal.h" + #define SUA_MSGB_SIZE 1500 /* Appendix C.4 of Q.714 (all in milliseconds) */ @@ -48,6 +50,161 @@ #define INT_TIMER ( 1 * 60 * 100) #define GUARD_TIMER (23 * 60 * 100) #define RESET_TIMER ( 10 * 100) + +/*********************************************************************** + * Protocol Definition (string tables, mandatory IE checking) + ***********************************************************************/ + +static const struct value_string sua_iei_names[] = { + { SUA_IEI_ROUTE_CTX, "Routing Context" }, + { SUA_IEI_CORR_ID, "Correlation Id" }, + { SUA_IEI_REG_RESULT, "Registration Result" }, + { SUA_IEI_DEREG_RESULT, "De-Registration Result" }, + + { SUA_IEI_S7_HOP_CTR, "SS7 Hop Counter" }, + { SUA_IEI_SRC_ADDR, "Source Address" }, + { SUA_IEI_DEST_ADDR, "Destination Address" }, + { SUA_IEI_SRC_REF, "Source Reference" }, + { SUA_IEI_DEST_REF, "Destination Reference" }, + { SUA_IEI_CAUSE, "Cause" }, + { SUA_IEI_SEQ_NR, "Sequence Number" }, + { SUA_IEI_RX_SEQ_NR, "Receive Sequence Number" }, + { SUA_IEI_ASP_CAPA, "ASP Capability" }, + { SUA_IEI_CREDIT, "Credit" }, + { SUA_IEI_DATA, "Data" }, + { SUA_IEI_USER_CAUSE, "User/Cause" }, + { SUA_IEI_NET_APPEARANCE, "Network Appearance" }, + { SUA_IEI_ROUTING_KEY, "Routing Key" }, + { SUA_IEI_DRN, "DRN Label" }, + { SUA_IEI_TID, "TID Label" }, + { SUA_IEI_SMI, "SMI" }, + { SUA_IEI_IMPORTANCE, "Importance" }, + { SUA_IEI_MSG_PRIO, "Message Priority" }, + { SUA_IEI_PROTO_CLASS, "Protocol Class" }, + { SUA_IEI_SEQ_CTRL, "Sequence Control" }, + { SUA_IEI_SEGMENTATION, "Segmentation" }, + { SUA_IEI_CONG_LEVEL, "Congestion Level" }, + + { SUA_IEI_GT, "Global Title" }, + { SUA_IEI_PC, "Point Code" }, + { SUA_IEI_SSN, "Sub-System Number" }, + { SUA_IEI_IPv4, "IPv4 Address" }, + { SUA_IEI_HOST, "Host Name" }, + { SUA_IEI_IPv6, "IPv6 Address" }, + { 0, NULL } +}; + +#define MAND_IES(msgt, ies) [msgt] = (ies) + +static const uint16_t cldt_mand_ies[] = { + SUA_IEI_ROUTE_CTX, SUA_IEI_PROTO_CLASS, SUA_IEI_SRC_ADDR, + SUA_IEI_DEST_ADDR, SUA_IEI_SEQ_CTRL, SUA_IEI_DATA, 0 +}; +static const uint16_t cldr_mand_ies[] = { + SUA_IEI_ROUTE_CTX, SUA_IEI_CAUSE, SUA_IEI_SRC_ADDR, + SUA_IEI_DEST_ADDR, 0 +}; +static const struct value_string sua_cl_msgt_names[] = { + { SUA_CL_CLDT, "CLDT" }, + { SUA_CL_CLDR, "CLDR" }, + { 0, NULL } +}; +static const struct xua_msg_class msg_class_cl = { + .name = "CL", + .msgt_names = sua_cl_msgt_names, + .iei_names = sua_iei_names, + .mand_ies = { + MAND_IES(SUA_CL_CLDT, cldt_mand_ies), + MAND_IES(SUA_CL_CLDR, cldr_mand_ies), + }, +}; + +static const uint16_t codt_mand_ies[] = { + SUA_IEI_ROUTE_CTX, SUA_IEI_DEST_REF, SUA_IEI_DATA, 0 +}; +static const uint16_t coda_mand_ies[] = { + SUA_IEI_ROUTE_CTX, SUA_IEI_DEST_REF, 0 +}; +static const uint16_t core_mand_ies[] = { + SUA_IEI_ROUTE_CTX, SUA_IEI_PROTO_CLASS, SUA_IEI_SRC_REF, + SUA_IEI_DEST_ADDR, SUA_IEI_SEQ_CTRL, 0 +}; +static const uint16_t coak_mand_ies[] = { + SUA_IEI_ROUTE_CTX, SUA_IEI_PROTO_CLASS, SUA_IEI_DEST_REF, + SUA_IEI_SRC_REF, SUA_IEI_SEQ_CTRL, 0 +}; +static const uint16_t coref_mand_ies[] = { + SUA_IEI_ROUTE_CTX, SUA_IEI_DEST_REF, SUA_IEI_CAUSE, 0 +}; +static const uint16_t relre_mand_ies[] = { + SUA_IEI_ROUTE_CTX, SUA_IEI_DEST_REF, SUA_IEI_SRC_REF, + SUA_IEI_CAUSE, 0 +}; +static const uint16_t relco_mand_ies[] = { + SUA_IEI_ROUTE_CTX, SUA_IEI_DEST_REF, SUA_IEI_SRC_REF, 0 +}; +static const uint16_t resre_mand_ies[] = { + SUA_IEI_ROUTE_CTX, SUA_IEI_DEST_REF, SUA_IEI_SRC_REF, + SUA_IEI_CAUSE, 0 +}; +static const uint16_t resco_mand_ies[] = { + SUA_IEI_ROUTE_CTX, SUA_IEI_DEST_REF, SUA_IEI_SRC_REF, 0 +}; +static const uint16_t coerr_mand_ies[] = { + SUA_IEI_ROUTE_CTX, SUA_IEI_DEST_REF, SUA_IEI_CAUSE, 0 +}; +static const uint16_t coit_mand_ies[] = { + SUA_IEI_ROUTE_CTX, SUA_IEI_PROTO_CLASS, SUA_IEI_SRC_REF, + SUA_IEI_DEST_REF, 0 +}; +static const struct value_string sua_co_msgt_names[] = { + { SUA_CO_CODT, "CODT" }, + { SUA_CO_CODA, "CODA" }, + { SUA_CO_CORE, "CORE" }, + { SUA_CO_COAK, "COAK" }, + { SUA_CO_COREF, "COREF" }, + { SUA_CO_RELRE, "RELRE" }, + { SUA_CO_RELCO, "RELCO" }, + { SUA_CO_RESRE, "RESRE" }, + { SUA_CO_RESCO, "RESCO" }, + { SUA_CO_COERR, "COERR" }, + { SUA_CO_COIT, "COIT" }, + { 0, NULL } +}; +static const struct xua_msg_class msg_class_co = { + .name = "CO", + .msgt_names = sua_co_msgt_names, + .iei_names = sua_iei_names, + .mand_ies = { + MAND_IES(SUA_CO_CODT, codt_mand_ies), + MAND_IES(SUA_CO_CODA, coda_mand_ies), + MAND_IES(SUA_CO_CORE, core_mand_ies), + MAND_IES(SUA_CO_COAK, coak_mand_ies), + MAND_IES(SUA_CO_COREF, coref_mand_ies), + MAND_IES(SUA_CO_RELRE, relre_mand_ies), + MAND_IES(SUA_CO_RELCO, relco_mand_ies), + MAND_IES(SUA_CO_RESRE, resre_mand_ies), + MAND_IES(SUA_CO_RESCO, resco_mand_ies), + MAND_IES(SUA_CO_COERR, coerr_mand_ies), + MAND_IES(SUA_CO_COIT, coit_mand_ies), + }, +}; + +const struct xua_dialect xua_dialect_sua = { + .name = "SUA", + .ppid = SUA_PPID, + .port = SUA_PORT, + .class = { + [SUA_MSGC_MGMT] = &m3ua_msg_class_mgmt, + [SUA_MSGC_SNM] = &m3ua_msg_class_snm, + [SUA_MSGC_ASPSM] = &m3ua_msg_class_aspsm, + [SUA_MSGC_ASPTM] = &m3ua_msg_class_asptm, + [SUA_MSGC_CL] = &msg_class_cl, + [SUA_MSGC_CO] = &msg_class_co, + [SUA_MSGC_RKM] = &m3ua_msg_class_rkm, + }, +}; + static int DSUA = -1; @@ -531,110 +688,6 @@ return rc; } - -/*********************************************************************** - * Mandatory IE checking - ***********************************************************************/ - -#define MAND_IES(msgt, ies) [msgt] = (ies) - -static const uint16_t cldt_mand_ies[] = { - SUA_IEI_ROUTE_CTX, SUA_IEI_PROTO_CLASS, SUA_IEI_SRC_ADDR, - SUA_IEI_DEST_ADDR, SUA_IEI_SEQ_CTRL, SUA_IEI_DATA, 0 -}; - -static const uint16_t cldr_mand_ies[] = { - SUA_IEI_ROUTE_CTX, SUA_IEI_CAUSE, SUA_IEI_SRC_ADDR, - SUA_IEI_DEST_ADDR, 0 -}; - -static const uint16_t codt_mand_ies[] = { - SUA_IEI_ROUTE_CTX, SUA_IEI_DEST_REF, SUA_IEI_DATA, 0 -}; - -static const uint16_t coda_mand_ies[] = { - SUA_IEI_ROUTE_CTX, SUA_IEI_DEST_REF, 0 -}; - -static const uint16_t core_mand_ies[] = { - SUA_IEI_ROUTE_CTX, SUA_IEI_PROTO_CLASS, SUA_IEI_SRC_REF, - SUA_IEI_DEST_ADDR, SUA_IEI_SEQ_CTRL, 0 -}; - -static const uint16_t coak_mand_ies[] = { - SUA_IEI_ROUTE_CTX, SUA_IEI_PROTO_CLASS, SUA_IEI_DEST_REF, - SUA_IEI_SRC_REF, SUA_IEI_SEQ_CTRL, 0 -}; - -static const uint16_t coref_mand_ies[] = { - SUA_IEI_ROUTE_CTX, SUA_IEI_DEST_REF, SUA_IEI_CAUSE, 0 -}; - -static const uint16_t relre_mand_ies[] = { - SUA_IEI_ROUTE_CTX, SUA_IEI_DEST_REF, SUA_IEI_SRC_REF, - SUA_IEI_CAUSE, 0 -}; - -static const uint16_t relco_mand_ies[] = { - SUA_IEI_ROUTE_CTX, SUA_IEI_DEST_REF, SUA_IEI_SRC_REF, 0 -}; - -static const uint16_t resre_mand_ies[] = { - SUA_IEI_ROUTE_CTX, SUA_IEI_DEST_REF, SUA_IEI_SRC_REF, - SUA_IEI_CAUSE, 0 -}; - -static const uint16_t resco_mand_ies[] = { - SUA_IEI_ROUTE_CTX, SUA_IEI_DEST_REF, SUA_IEI_SRC_REF, 0 -}; - -static const uint16_t coerr_mand_ies[] = { - SUA_IEI_ROUTE_CTX, SUA_IEI_DEST_REF, SUA_IEI_CAUSE, 0 -}; - -static const uint16_t coit_mand_ies[] = { - SUA_IEI_ROUTE_CTX, SUA_IEI_PROTO_CLASS, SUA_IEI_SRC_REF, - SUA_IEI_DEST_REF, 0 -}; - -static const uint16_t *mand_ies_cl[256] = { - MAND_IES(SUA_CL_CLDT, cldt_mand_ies), - MAND_IES(SUA_CL_CLDR, cldr_mand_ies), -}; - -static const uint16_t *mand_ies_co[256] = { - MAND_IES(SUA_CO_CODT, codt_mand_ies), - MAND_IES(SUA_CO_CODA, coda_mand_ies), - MAND_IES(SUA_CO_CORE, core_mand_ies), - MAND_IES(SUA_CO_COAK, coak_mand_ies), - MAND_IES(SUA_CO_COREF, coref_mand_ies), - MAND_IES(SUA_CO_RELRE, relre_mand_ies), - MAND_IES(SUA_CO_RELCO, relco_mand_ies), - MAND_IES(SUA_CO_RESRE, resre_mand_ies), - MAND_IES(SUA_CO_RESCO, resco_mand_ies), - MAND_IES(SUA_CO_COERR, coerr_mand_ies), - MAND_IES(SUA_CO_COIT, coit_mand_ies), -}; - -static int check_all_mand_ies(const uint16_t **mand_ies, struct xua_msg *xua) -{ - uint8_t msg_type = xua->hdr.msg_type; - const uint16_t *ies = mand_ies[msg_type]; - uint16_t ie; - - for (ie = *ies; ie; ie = *ies++) { - if (!xua_msg_find_tag(xua, ie)) { - LOGP(DSUA, LOGL_ERROR, "SUA Message %u:%u should " - "contain IE 0x%04x, but doesn't\n", - xua->hdr.msg_class, msg_type, ie); - return 0; - } - } - - return 1; -} - - /*********************************************************************** * Receiving SUA messsages from SCTP ***********************************************************************/ @@ -772,9 +825,6 @@ struct xua_msg *xua, struct msgb *msg) { int rc = -1; - - if (!check_all_mand_ies(mand_ies_cl, xua)) - return -1; switch (xua->hdr.msg_type) { case SUA_CL_CLDT: @@ -1094,9 +1144,6 @@ { int rc = -1; - if (!check_all_mand_ies(mand_ies_co, xua)) - return -1; - switch (xua->hdr.msg_type) { case SUA_CO_CORE: rc = sua_rx_core(link, xua); @@ -1142,8 +1189,11 @@ return -EIO; } - LOGP(DSUA, LOGL_DEBUG, "Received SUA Message (%u:%u)\n", - xua->hdr.msg_class, xua->hdr.msg_type); + LOGP(DSUA, LOGL_DEBUG, "Received SUA Message (%s)\n", + xua_hdr_dump(xua, &xua_dialect_sua)); + + if (!xua_dialect_check_all_mand_ies(&xua_dialect_sua, xua)) + return -1; switch (xua->hdr.msg_class) { case SUA_MSGC_CL: -- To view, visit https://gerrit.osmocom.org/2210 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I966103f30b9be247ba6905ba8e06b87654d9981a Gerrit-PatchSet: 3 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Apr 4 13:46:31 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 4 Apr 2017 13:46:31 +0000 Subject: [PATCH] libosmo-sccp[master]: sua: Extend address parsing with GT, RI and IPv4 support In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2211 to look at the new patch set (#3). sua: Extend address parsing with GT, RI and IPv4 support Change-Id: I186df77cbdbedfe1a60b855be3626b6766f4681c --- M src/sua.c 1 file changed, 104 insertions(+), 26 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/11/2211/3 diff --git a/src/sua.c b/src/sua.c index 659104c..de4a4e8 100644 --- a/src/sua.c +++ b/src/sua.c @@ -692,11 +692,51 @@ * Receiving SUA messsages from SCTP ***********************************************************************/ -static int sua_parse_addr(struct osmo_sccp_addr *out, - struct xua_msg *xua, - uint16_t iei) +/*! \brief Decode SUA Global Title according to RFC3868 3.10.2.3 + * \param[out] gt User-allocated structure for decoded output + * \param[in] data binary-encoded data + * \param[in] datalen length of \ref data in octets + */ +int sua_parse_gt(struct osmo_sccp_gt *gt, const uint8_t *data, unsigned int datalen) { - const struct xua_msg_part *param = xua_msg_find_tag(xua, iei); + uint8_t num_digits; + char *out_digits; + unsigned int i; + + /* 8 byte header at minimum, plus digits */ + if (datalen < 8) + return -EINVAL; + + /* parse header */ + gt->gti = data[3]; + num_digits = data[4]; + gt->tt = data[5]; + gt->npi = data[6]; + gt->nai = data[7]; + + /* parse digits */ + out_digits = gt->digits; + for (i = 0; i < datalen-8; i++) { + uint8_t byte = data[8+i]; + *out_digits++ = osmo_bcd2char(byte & 0x0F); + if (out_digits - gt->digits >= num_digits) + break; + *out_digits++ = osmo_bcd2char(byte >> 4); + if (out_digits - gt->digits >= num_digits) + break; + } + *out_digits++ = '\0'; + + return 0; +} + +/*! \brief parse SCCP address from given xUA message part + * \param[out] out caller-allocated decoded SCCP address struct + * \param[in] param xUA message part containing address + \returns 0 on success; negative on error */ +int sua_addr_parse_part(struct osmo_sccp_addr *out, + const struct xua_msg_part *param) +{ const struct xua_parameter_hdr *par; uint16_t ri; uint16_t ai; @@ -704,16 +744,15 @@ uint16_t par_tag, par_len, par_datalen; uint32_t *p32; - if (!param) - return -ENODEV; + memset(out, 0, sizeof(*out)); - LOGP(DSUA, LOGL_DEBUG, "sua_parse_addr(IEI=%d) (%d) %s\n", - iei, param->len, + LOGP(DSUA, LOGL_DEBUG, "%s(IEI=0x%04x) (%d) %s\n", __func__, + param->tag, param->len, osmo_hexdump(param->dat, param->len)); if (param->len < 4) { - LOGP(DSUA, LOGL_ERROR, "SUA IEI %d: invalid address length: %d\n", - iei, param->len); + LOGP(DSUA, LOGL_ERROR, "SUA IEI 0x%04x: invalid address length: %d\n", + param->tag, param->len); return -EINVAL; } @@ -723,16 +762,29 @@ ai = ntohs(*(uint16_t*) ¶m->dat[pos]); pos += 2; - if (ri != SUA_RI_SSN_PC) { - LOGP(DSUA, LOGL_ERROR, "SUA IEI %d: Routing Indicator not supported yet: %d\n", - iei, ri); + switch (ri) { + case SUA_RI_GT: + out->ri = OSMO_SCCP_RI_GT; + break; + case SUA_RI_SSN_PC: + out->ri = OSMO_SCCP_RI_SSN_PC; + break; + case SUA_RI_SSN_IP: + out->ri = OSMO_SCCP_RI_SSN_IP; + break; + case SUA_RI_HOST: + default: + LOGP(DSUA, LOGL_ERROR, "SUA IEI 0x%04x: Routing Indicator not supported yet: %d\n", + param->tag, ri); return -ENOTSUP; } if (ai != 7) { - LOGP(DSUA, LOGL_ERROR, "SUA IEI %d: Address Indicator not supported yet: %x\n", - iei, ai); +#if 0 + LOGP(DSUA, LOGL_ERROR, "SUA IEI 0x%04x: Address Indicator not supported yet: %x\n", + param->tag, ai); return -ENOTSUP; +#endif } /* @@ -749,8 +801,8 @@ par_len = ntohs(par->len); par_datalen = par_len - sizeof(*par); - LOGP(DSUA, LOGL_DEBUG, "SUA IEI %hu pos %hu/%hu: subpart tag %hu, len %hu\n", - iei, pos, param->len, par->tag, par->len); + LOGP(DSUA, LOGL_DEBUG, "SUA IEI 0x%04x pos %hu/%hu: subpart tag 0x%04x, len %hu\n", + param->tag, pos, param->len, par_tag, par_len); switch (par_tag) { case SUA_IEI_PC: @@ -768,12 +820,22 @@ out->presence |= OSMO_SCCP_ADDR_T_SSN; break; case SUA_IEI_GT: - /* TODO */ + if (par_datalen < 8) + goto subpar_fail; + sua_parse_gt(&out->gt, par->data, par_datalen); out->presence |= OSMO_SCCP_ADDR_T_GT; break; + case SUA_IEI_IPv4: + if (par_datalen != 4) + goto subpar_fail; + p32 = (uint32_t*)par->data; + /* no endian conversion, both network order */ + out->ip.v4.s_addr = *p32; + out->presence |= OSMO_SCCP_ADDR_T_IPv4; + break; default: - LOGP(DSUA, LOGL_ERROR, "SUA IEI %d: Unknown subpart tag %hd\n", - iei, par_tag); + LOGP(DSUA, LOGL_ERROR, "SUA IEI 0x%04x: Unknown subpart tag %hd\n", + param->tag, par_tag); goto subpar_fail; } @@ -783,9 +845,25 @@ return 0; subpar_fail: - LOGP(DSUA, LOGL_ERROR, "Failed to parse subparts of address IEI=%d\n", - iei); + LOGP(DSUA, LOGL_ERROR, "Failed to parse subparts of address IEI=0x%04x\n", + param->tag); return -EINVAL; +} + +/*! \brief parse SCCP address from given xUA message IE + * \param[out] out caller-allocated decoded SCCP address struct + * \param[in] xua xUA message + * \param[in] iei Information Element Identifier inside \ref xua + \returns 0 on success; negative on error */ +int sua_addr_parse(struct osmo_sccp_addr *out, struct xua_msg *xua, uint16_t iei) +{ + const struct xua_msg_part *param = xua_msg_find_tag(xua, iei); + if (!param) { + memset(out, 0, sizeof(*out)); + return -ENODEV; + } + + return sua_addr_parse_part(out, param); } static int sua_rx_cldt(struct osmo_sccp_link *link, struct xua_msg *xua) @@ -802,8 +880,8 @@ osmo_prim_init(&prim->oph, SCCP_SAP_USER, OSMO_SCU_PRIM_N_UNITDATA, PRIM_OP_INDICATION, upmsg); - sua_parse_addr(¶m->called_addr, xua, SUA_IEI_DEST_ADDR); - sua_parse_addr(¶m->calling_addr, xua, SUA_IEI_SRC_ADDR); + sua_addr_parse(¶m->called_addr, xua, SUA_IEI_DEST_ADDR); + sua_addr_parse(¶m->calling_addr, xua, SUA_IEI_SRC_ADDR); param->in_sequence_control = xua_msg_get_u32(xua, SUA_IEI_SEQ_CTRL); protocol_class = xua_msg_get_u32(xua, SUA_IEI_PROTO_CLASS); param->return_option = protocol_class & 0x80; @@ -849,8 +927,8 @@ /* fill conn */ conn = conn_create(link); - sua_parse_addr(&conn->called_addr, xua, SUA_IEI_DEST_ADDR); - sua_parse_addr(&conn->calling_addr, xua, SUA_IEI_SRC_ADDR); + sua_addr_parse(&conn->called_addr, xua, SUA_IEI_DEST_ADDR); + sua_addr_parse(&conn->calling_addr, xua, SUA_IEI_SRC_ADDR); conn->remote_ref = xua_msg_get_u32(xua, SUA_IEI_SRC_REF); /* fill primitive */ -- To view, visit https://gerrit.osmocom.org/2211 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I186df77cbdbedfe1a60b855be3626b6766f4681c Gerrit-PatchSet: 3 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Apr 4 13:46:31 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 4 Apr 2017 13:46:31 +0000 Subject: [PATCH] libosmo-sccp[master]: SUA: Port to new osmo_ss7 and SCCP code In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2218 to look at the new patch set (#4). SUA: Port to new osmo_ss7 and SCCP code If we use the infrastructure provided by osmo_ss7 on the lower layer and the SCCP SCRC, SCLC and SCOC code on the upper side, not much of the original sua.c code remains. It looks much like the M3UA code now. Change-Id: I193b74f58aa70c443ae17e78b5604246d6bc3f71 --- M include/osmocom/sigtran/Makefile.am M include/osmocom/sigtran/sccp_helpers.h D include/osmocom/sigtran/sua.h M src/osmo_ss7.c M src/sccp_helpers.c M src/sccp_scrc.c M src/sua.c M src/xua_internal.h 8 files changed, 364 insertions(+), 1,296 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/18/2218/4 diff --git a/include/osmocom/sigtran/Makefile.am b/include/osmocom/sigtran/Makefile.am index ca7a304..0aa90cb 100644 --- a/include/osmocom/sigtran/Makefile.am +++ b/include/osmocom/sigtran/Makefile.am @@ -1,5 +1,5 @@ sigtran_HEADERS = xua_types.h xua_msg.h m2ua_types.h sccp_sap.h \ - sua.h sigtran_sap.h sccp_helpers.h mtp_sap.h osmo_ss7.h + sigtran_sap.h sccp_helpers.h mtp_sap.h osmo_ss7.h sigtrandir = $(includedir)/osmocom/sigtran diff --git a/include/osmocom/sigtran/sccp_helpers.h b/include/osmocom/sigtran/sccp_helpers.h index 968c500..bbd0364 100644 --- a/include/osmocom/sigtran/sccp_helpers.h +++ b/include/osmocom/sigtran/sccp_helpers.h @@ -1,15 +1,17 @@ #pragma once + #include #include #include -#include -int osmo_sccp_tx_unitdata(struct osmo_sccp_link *link, +void osmo_sccp_make_addr_pc_ssn(struct osmo_sccp_addr *addr, uint32_t pc, uint32_t ssn); + +int osmo_sccp_tx_unitdata(struct osmo_sccp_user *scu, const struct osmo_sccp_addr *calling_addr, const struct osmo_sccp_addr *called_addr, - uint8_t *data, unsigned int len); + const uint8_t *data, unsigned int len); -int osmo_sccp_tx_unitdata_msg(struct osmo_sccp_link *link, +int osmo_sccp_tx_unitdata_msg(struct osmo_sccp_user *scu, const struct osmo_sccp_addr *calling_addr, const struct osmo_sccp_addr *called_addr, struct msgb *msg); @@ -17,26 +19,38 @@ void osmo_sccp_make_addr_pc_ssn(struct osmo_sccp_addr *addr, uint32_t pc, uint32_t ssn); -int osmo_sccp_tx_unitdata_ranap(struct osmo_sccp_link *link, +int osmo_sccp_tx_unitdata_ranap(struct osmo_sccp_user *scu, uint32_t src_point_code, uint32_t dst_point_code, - uint8_t *data, unsigned int len); + const uint8_t *data, unsigned int len); -int osmo_sccp_tx_conn_req(struct osmo_sccp_link *link, uint32_t conn_id, +int osmo_sccp_tx_conn_req(struct osmo_sccp_user *scu, uint32_t conn_id, const struct osmo_sccp_addr *calling_addr, const struct osmo_sccp_addr *called_addr, - uint8_t *data, unsigned int len); + const uint8_t *data, unsigned int len); -int osmo_sccp_tx_conn_req_msg(struct osmo_sccp_link *link, uint32_t conn_id, +int osmo_sccp_tx_conn_req_msg(struct osmo_sccp_user *scu, uint32_t conn_id, const struct osmo_sccp_addr *calling_addr, const struct osmo_sccp_addr *called_addr, struct msgb *msg); -int osmo_sccp_tx_data(struct osmo_sccp_link *link, uint32_t conn_id, - uint8_t *data, unsigned int len); +int osmo_sccp_tx_data(struct osmo_sccp_user *scu, uint32_t conn_id, + const uint8_t *data, unsigned int len); -int osmo_sccp_tx_data_msg(struct osmo_sccp_link *link, uint32_t conn_id, +int osmo_sccp_tx_data_msg(struct osmo_sccp_user *scu, uint32_t conn_id, struct msgb *msg); +int osmo_sccp_tx_disconn(struct osmo_sccp_user *scu, uint32_t conn_id, + const struct osmo_sccp_addr *resp_addr, + uint32_t cause); + +int osmo_sccp_tx_conn_resp_msg(struct osmo_sccp_user *scu, uint32_t conn_id, + const struct osmo_sccp_addr *resp_addr, + struct msgb *msg); + +int osmo_sccp_tx_conn_resp(struct osmo_sccp_user *scu, uint32_t conn_id, + const struct osmo_sccp_addr *resp_addr, + const uint8_t *data, unsigned int len); + char *osmo_sccp_gt_dump(const struct osmo_sccp_gt *gt); char *osmo_sccp_addr_dump(const struct osmo_sccp_addr *addr); diff --git a/include/osmocom/sigtran/sua.h b/include/osmocom/sigtran/sua.h deleted file mode 100644 index 766b488..0000000 --- a/include/osmocom/sigtran/sua.h +++ /dev/null @@ -1,23 +0,0 @@ -#pragma once - -#include -#include - -struct osmo_sccp_user; -struct osmo_sccp_link; - -void osmo_sua_set_log_area(int area); - -struct osmo_sccp_user *osmo_sua_user_create(void *ctx, osmo_prim_cb prim_cb, - void *priv); -void osmo_sua_user_destroy(struct osmo_sccp_user *user); - -int osmo_sua_server_listen(struct osmo_sccp_user *user, const char *hostname, uint16_t port); - -int osmo_sua_client_connect(struct osmo_sccp_user *user, const char *hostname, uint16_t port); -struct osmo_sccp_link *osmo_sua_client_get_link(struct osmo_sccp_user *user); - -/* user hands us a SCCP-USER SAP primitive down into the stack */ -int osmo_sua_user_link_down(struct osmo_sccp_link *link, struct osmo_prim_hdr *oph); - -void *osmo_sccp_link_get_user_priv(struct osmo_sccp_link *slink); diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index 6d0b446..ab0636c 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -1197,7 +1197,9 @@ msgb_sctp_stream(msg) = ntohl(sinfo.sinfo_stream); msg->dst = asp; - if (ppid == M3UA_PPID && asp->cfg.proto == OSMO_SS7_ASP_PROT_M3UA) + if (ppid == SUA_PPID && asp->cfg.proto == OSMO_SS7_ASP_PROT_SUA) + rc = sua_rx_msg(asp, msg); + else if (ppid == M3UA_PPID && asp->cfg.proto == OSMO_SS7_ASP_PROT_M3UA) rc = m3ua_rx_msg(asp, msg); else { LOGPASP(asp, DLSS7, LOGL_NOTICE, "SCTP chunk for unknown PPID %u " @@ -1280,7 +1282,9 @@ msgb_sctp_stream(msg) = ntohl(sinfo.sinfo_stream); msg->dst = asp; - if (ppid == M3UA_PPID && asp->cfg.proto == OSMO_SS7_ASP_PROT_M3UA) + if (ppid == SUA_PPID && asp->cfg.proto == OSMO_SS7_ASP_PROT_SUA) + rc = sua_rx_msg(asp, msg); + else if (ppid == M3UA_PPID && asp->cfg.proto == OSMO_SS7_ASP_PROT_M3UA) rc = m3ua_rx_msg(asp, msg); else { LOGPASP(asp, DLSS7, LOGL_NOTICE, "SCTP chunk for unknown PPID %u " diff --git a/src/sccp_helpers.c b/src/sccp_helpers.c index 6264424..c588607 100644 --- a/src/sccp_helpers.c +++ b/src/sccp_helpers.c @@ -1,6 +1,6 @@ /* SCCP User SAP helper functions */ -/* (C) 2015 by Harald Welte +/* (C) 2015-2017 by Harald Welte * (C) 2016 by sysmocom s.m.f.c. GmbH * All Rights Reserved * @@ -27,8 +27,14 @@ #include #include -#include #include + +#include "sccp_internal.h" + +static struct msgb *scu_msgb_alloc(const char *name) +{ + return sccp_msgb_alloc("SCU"); +} void osmo_sccp_make_addr_pc_ssn(struct osmo_sccp_addr *addr, uint32_t pc, uint32_t ssn) { @@ -37,12 +43,12 @@ addr->pc = pc; } -int osmo_sccp_tx_unitdata(struct osmo_sccp_link *link, +int osmo_sccp_tx_unitdata(struct osmo_sccp_user *scu, const struct osmo_sccp_addr *calling_addr, const struct osmo_sccp_addr *called_addr, - uint8_t *data, unsigned int len) + const uint8_t *data, unsigned int len) { - struct msgb *msg = msgb_alloc(1024, "sccp_tx_unitdata"); + struct msgb *msg = scu_msgb_alloc(__func__); struct osmo_scu_prim *prim; struct osmo_scu_unitdata_param *param; @@ -55,13 +61,13 @@ msg->l2h = msgb_put(msg, len); memcpy(msg->l2h, data, len); - return osmo_sua_user_link_down(link, &prim->oph); + return osmo_sccp_user_sap_down(scu, &prim->oph); } -int osmo_sccp_tx_unitdata_ranap(struct osmo_sccp_link *link, +int osmo_sccp_tx_unitdata_ranap(struct osmo_sccp_user *scu, uint32_t src_point_code, uint32_t dst_point_code, - uint8_t *data, unsigned int len) + const uint8_t *data, unsigned int len) { struct osmo_sccp_addr calling_addr; struct osmo_sccp_addr called_addr; @@ -69,67 +75,70 @@ OSMO_SCCP_SSN_RANAP); osmo_sccp_make_addr_pc_ssn(&called_addr, dst_point_code, OSMO_SCCP_SSN_RANAP); - return osmo_sccp_tx_unitdata(link, &calling_addr, &called_addr, + return osmo_sccp_tx_unitdata(scu, &calling_addr, &called_addr, data, len); } -int osmo_sccp_tx_unitdata_msg(struct osmo_sccp_link *link, +int osmo_sccp_tx_unitdata_msg(struct osmo_sccp_user *scu, const struct osmo_sccp_addr *calling_addr, const struct osmo_sccp_addr *called_addr, struct msgb *msg) { int rc; - rc = osmo_sccp_tx_unitdata(link, calling_addr, called_addr, + rc = osmo_sccp_tx_unitdata(scu, calling_addr, called_addr, msg->data, msgb_length(msg)); msgb_free(msg); return rc; } -int osmo_sccp_tx_conn_req(struct osmo_sccp_link *link, uint32_t conn_id, +int osmo_sccp_tx_conn_req(struct osmo_sccp_user *scu, uint32_t conn_id, const struct osmo_sccp_addr *calling_addr, const struct osmo_sccp_addr *called_addr, - uint8_t *data, unsigned int len) + const uint8_t *data, unsigned int len) { - struct msgb *msg = msgb_alloc(1024, "sccp_tx_conn_req"); + struct msgb *msg = scu_msgb_alloc(__func__); struct osmo_scu_prim *prim; + struct osmo_scu_connect_param *param; prim = (struct osmo_scu_prim *) msgb_put(msg, sizeof(*prim)); osmo_prim_init(&prim->oph, SCCP_SAP_USER, OSMO_SCU_PRIM_N_CONNECT, PRIM_OP_REQUEST, msg); - osmo_sccp_make_addr_pc_ssn(&prim->u.connect.calling_addr, 1, - OSMO_SCCP_SSN_RANAP); - prim->u.connect.sccp_class = 2; - prim->u.connect.conn_id = conn_id; + param = &prim->u.connect; + if (calling_addr) + memcpy(¶m->calling_addr, calling_addr, sizeof(*calling_addr)); + memcpy(¶m->called_addr, called_addr, sizeof(*called_addr)); + param->sccp_class = 2; + param->conn_id = conn_id; if (data && len) { msg->l2h = msgb_put(msg, len); memcpy(msg->l2h, data, len); } - return osmo_sua_user_link_down(link, &prim->oph); + return osmo_sccp_user_sap_down(scu, &prim->oph); } -int osmo_sccp_tx_conn_req_msg(struct osmo_sccp_link *link, uint32_t conn_id, +int osmo_sccp_tx_conn_req_msg(struct osmo_sccp_user *scu, uint32_t conn_id, const struct osmo_sccp_addr *calling_addr, const struct osmo_sccp_addr *called_addr, struct msgb *msg) { int rc; - rc = osmo_sccp_tx_conn_req(link, conn_id, calling_addr, called_addr, + rc = osmo_sccp_tx_conn_req(scu, conn_id, calling_addr, called_addr, msg->data, msgb_length(msg)); msgb_free(msg); return rc; } -int osmo_sccp_tx_data(struct osmo_sccp_link *link, uint32_t conn_id, - uint8_t *data, unsigned int len) +int osmo_sccp_tx_data(struct osmo_sccp_user *scu, uint32_t conn_id, + const uint8_t *data, unsigned int len) { - struct msgb *msg = msgb_alloc(1024, "sccp_tx_data"); + struct msgb *msg = scu_msgb_alloc(__func__); struct osmo_scu_prim *prim; prim = (struct osmo_scu_prim *) msgb_put(msg, sizeof(*prim)); @@ -141,20 +150,79 @@ msg->l2h = msgb_put(msg, len); memcpy(msg->l2h, data, len); - return osmo_sua_user_link_down(link, &prim->oph); + return osmo_sccp_user_sap_down(scu, &prim->oph); } -int osmo_sccp_tx_data_msg(struct osmo_sccp_link *link, uint32_t conn_id, +int osmo_sccp_tx_data_msg(struct osmo_sccp_user *scu, uint32_t conn_id, struct msgb *msg) { int rc; - rc = osmo_sccp_tx_data(link, conn_id, msg->data, msgb_length(msg)); + rc = osmo_sccp_tx_data(scu, conn_id, msg->data, msgb_length(msg)); msgb_free(msg); return rc; } +/* N-DISCONNECT.req */ +int osmo_sccp_tx_disconn(struct osmo_sccp_user *scu, uint32_t conn_id, + const struct osmo_sccp_addr *resp_addr, + uint32_t cause) +{ + struct msgb *msg = scu_msgb_alloc(__func__); + struct osmo_scu_prim *prim; + struct osmo_scu_disconn_param *param; + + prim = (struct osmo_scu_prim *) msgb_put(msg, sizeof(*prim)); + osmo_prim_init(&prim->oph, SCCP_SAP_USER, + OSMO_SCU_PRIM_N_DISCONNECT, + PRIM_OP_REQUEST, msg); + param = &prim->u.disconnect; + memset(param, 0, sizeof(*param)); + param->originator = OSMO_SCCP_ORIG_NS_USER; + if (resp_addr) + memcpy(¶m->responding_addr, resp_addr, sizeof(*resp_addr)); + param->conn_id = conn_id; + param->cause = cause; + + return osmo_sccp_user_sap_down(scu, &prim->oph); +} + +/* N-CONNECT.resp */ +int osmo_sccp_tx_conn_resp_msg(struct osmo_sccp_user *scu, uint32_t conn_id, + const struct osmo_sccp_addr *resp_addr, + struct msgb *msg) +{ + struct osmo_scu_prim *prim; + struct osmo_scu_connect_param *param; + + msg->l2h = msg->data; + + prim = (struct osmo_scu_prim *) msgb_push(msg, sizeof(*prim)); + osmo_prim_init(&prim->oph, SCCP_SAP_USER, + OSMO_SCU_PRIM_N_CONNECT, + PRIM_OP_RESPONSE, msg); + param = &prim->u.connect; + param->conn_id = conn_id; + memcpy(¶m->responding_addr, resp_addr, sizeof(*resp_addr)); + param->sccp_class = 2; + + return osmo_sccp_user_sap_down(scu, &prim->oph); +} + +int osmo_sccp_tx_conn_resp(struct osmo_sccp_user *scu, uint32_t conn_id, + const struct osmo_sccp_addr *resp_addr, + const uint8_t *data, unsigned int len) +{ + struct msgb *msg = scu_msgb_alloc(__func__); + + if (data && len) { + msg->l2h = msgb_put(msg, len); + memcpy(msg->l2h, data, len); + } + return osmo_sccp_tx_conn_resp_msg(scu, conn_id, resp_addr, msg); +} + static void append_to_buf(char *buf, bool *comma, const char *fmt, ...) { va_list ap; diff --git a/src/sccp_scrc.c b/src/sccp_scrc.c index 9bccc0a..0ab25cb 100644 --- a/src/sccp_scrc.c +++ b/src/sccp_scrc.c @@ -139,6 +139,8 @@ if (rt->dest.as) { struct osmo_ss7_as *as = rt->dest.as; switch (as->cfg.proto) { + case OSMO_SS7_ASP_PROT_SUA: + return sua_tx_xua_as(as, xua); case OSMO_SS7_ASP_PROT_M3UA: return sua2sccp_tx_m3ua(inst, xua); default: diff --git a/src/sua.c b/src/sua.c index b8bb2f5..836e02e 100644 --- a/src/sua.c +++ b/src/sua.c @@ -29,17 +29,20 @@ #include #include #include +#include #include #include #include +#include #include -#include +#include +#include +#include "xua_asp_fsm.h" #include "xua_internal.h" - -#define SUA_MSGB_SIZE 1500 +#include "sccp_internal.h" /* Appendix C.4 of Q.714 (all in milliseconds) */ #define CONNECTION_TIMER ( 1 * 60 * 100) @@ -205,6 +208,7 @@ .name = "SUA", .ppid = SUA_PPID, .port = SUA_PORT, + .log_subsys = DLSUA, .class = { [SUA_MSGC_MGMT] = &m3ua_msg_class_mgmt, [SUA_MSGC_SNM] = &m3ua_msg_class_snm, @@ -216,480 +220,81 @@ }, }; - -static int DSUA = -1; - -struct osmo_sccp_user { - /* global list of SUA users? */ - struct llist_head list; - /* set if we are a server */ - struct osmo_stream_srv_link *server; - struct osmo_stream_cli *client; - struct llist_head links; - /* user call-back function in case of incoming primitives */ - osmo_prim_cb prim_cb; - void *priv; -}; - -struct osmo_sccp_link { - /* list of SUA links per sua_user */ - struct llist_head list; - /* sua user to which we belong */ - struct osmo_sccp_user *user; - /* local list of (SCCP) connections in this link */ - struct llist_head connections; - /* next connection local reference */ - uint32_t next_id; - int is_server; - void *data; -}; - -enum sua_connection_state { - S_IDLE, - S_CONN_PEND_IN, - S_CONN_PEND_OUT, - S_ACTIVE, - S_DISCONN_PEND, - S_RESET_IN, - S_RESET_OUT, - S_BOTHWAY_RESET, - S_WAIT_CONN_CONF, -}; - -static const struct value_string conn_state_names[] = { - { S_IDLE, "IDLE" }, - { S_CONN_PEND_IN, "CONN_PEND_IN" }, - { S_CONN_PEND_OUT, "CONN_PEND_OUT" }, - { S_ACTIVE, "ACTIVE" }, - { S_DISCONN_PEND, "DISCONN_PEND" }, - { S_RESET_IN, "RESET_IN" }, - { S_RESET_OUT, "RESET_OUT" }, - { S_BOTHWAY_RESET, "BOTHWAY_RESET" }, - { S_WAIT_CONN_CONF, "WAIT_CONN_CONF" }, - { 0, NULL } -}; - -struct sua_connection { - struct llist_head list; - struct osmo_sccp_link *link; - struct osmo_sccp_addr calling_addr; - struct osmo_sccp_addr called_addr; - uint32_t conn_id; - uint32_t remote_ref; - enum sua_connection_state state; - struct osmo_timer_list timer; - /* inactivity timers */ - struct osmo_timer_list tias; - struct osmo_timer_list tiar; -}; - - /*********************************************************************** - * SUA Link and Connection handling + * ERROR generation ***********************************************************************/ -static struct osmo_sccp_link *sua_link_new(struct osmo_sccp_user *user, int is_server) +static struct xua_msg *sua_gen_error(uint32_t err_code) { - struct osmo_sccp_link *link; + struct xua_msg *xua = xua_msg_alloc(); - link = talloc_zero(user, struct osmo_sccp_link); - if (!link) - return NULL; + xua->hdr = XUA_HDR(SUA_MSGC_MGMT, SUA_MGMT_ERR); + xua->hdr.version = SUA_VERSION; + xua_msg_add_u32(xua, SUA_IEI_ERR_CODE, err_code); - link->user = user; - link->is_server = is_server; - INIT_LLIST_HEAD(&link->connections); - - llist_add_tail(&link->list, &user->links); - - return link; + return xua; } -static void conn_destroy(struct sua_connection *conn); - -static void sua_link_destroy(struct osmo_sccp_link *link) +static struct xua_msg *sua_gen_error_msg(uint32_t err_code, struct msgb *msg) { - struct sua_connection *conn; + struct xua_msg *xua = sua_gen_error(err_code); + unsigned int len_max_40 = msgb_length(msg); - llist_for_each_entry(conn, &link->connections, list) - conn_destroy(conn); + if (len_max_40 > 40) + len_max_40 = 40; - llist_del(&link->list); + xua_msg_add_data(xua, SUA_IEI_DIAG_INFO, len_max_40, msgb_data(msg)); - /* FIXME: do we need to cleanup the sccp link? */ - - talloc_free(link); + return xua; } -static int sua_link_send(struct osmo_sccp_link *link, struct msgb *msg) +/*********************************************************************** + * Transmitting SUA messsages to SCTP + ***********************************************************************/ + +static int sua_tx_xua_asp(struct osmo_ss7_asp *asp, struct xua_msg *xua) { + struct msgb *msg = xua_to_msg(SUA_VERSION, xua); + + OSMO_ASSERT(asp->cfg.proto == OSMO_SS7_ASP_PROT_SUA); + + xua_msg_free(xua); + + if (!msg) { + LOGPASP(asp, DLSUA, LOGL_ERROR, "Error encoding SUA Msg\n"); + return -1; + } + msgb_sctp_ppid(msg) = SUA_PPID; - - DEBUGP(DSUA, "sua_link_send(%s)\n", osmo_hexdump(msg->data, msgb_length(msg))); - - if (link->is_server) - osmo_stream_srv_send(link->data, msg); - else - osmo_stream_cli_send(link->data, msg); - - return 0; + return osmo_ss7_asp_send(asp, msg); } -static struct sua_connection *conn_find_by_id(struct osmo_sccp_link *link, uint32_t id) +/*! \brief Send a given xUA message via a given SUA Application Server + * \param[in] as Application Server through which to send \ref xua + * \param[in] xua xUA message to be sent + * \return 0 on success; negative on error */ +int sua_tx_xua_as(struct osmo_ss7_as *as, struct xua_msg *xua) { - struct sua_connection *conn; + struct osmo_ss7_asp *asp; + unsigned int i; - llist_for_each_entry(conn, &link->connections, list) { - if (conn->conn_id == id) - return conn; + OSMO_ASSERT(as->cfg.proto == OSMO_SS7_ASP_PROT_SUA); + + /* FIXME: Select ASP within AS depending on traffic mode */ + for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) { + asp = as->cfg.asps[i]; + if (!asp) + continue; + if (asp) + break; } - return NULL; -} - -static void tx_inact_tmr_cb(void *data) -{ - struct sua_connection *conn = data; - struct xua_msg *xua = xua_msg_alloc(); - struct msgb *outmsg; - - /* encode + send the CLDT */ - xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_COIT); - xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, 0); /* FIXME */ - xua_msg_add_u32(xua, SUA_IEI_PROTO_CLASS, 2); - xua_msg_add_u32(xua, SUA_IEI_SRC_REF, conn->conn_id); - xua_msg_add_u32(xua, SUA_IEI_DEST_REF, conn->remote_ref); - /* optional: sequence number; credit (both class 3 only) */ - - outmsg = xua_to_msg(1, xua); - xua_msg_free(xua); - - sua_link_send(conn->link, outmsg); -} - -static void rx_inact_tmr_cb(void *data) -{ - struct sua_connection *conn = data; - - /* FIXME: release connection */ - /* Send N-DISCONNECT.ind to local user */ - /* Send RLSD to peer */ - /* enter disconnect pending state with release timer pending */ -} - - -static struct sua_connection *conn_create_id(struct osmo_sccp_link *link, uint32_t conn_id) -{ - struct sua_connection *conn = talloc_zero(link, struct sua_connection); - - conn->conn_id = conn_id; - conn->link = link; - conn->state = S_IDLE; - - llist_add_tail(&conn->list, &link->connections); - - conn->tias.cb = tx_inact_tmr_cb; - conn->tias.data = conn; - conn->tiar.cb = rx_inact_tmr_cb; - conn->tiar.data = conn; - - return conn; -} - -static struct sua_connection *conn_create(struct osmo_sccp_link *link) -{ - uint32_t conn_id; - - do { - conn_id = link->next_id++; - } while (conn_find_by_id(link, conn_id)); - - return conn_create_id(link, conn_id); -} - -static void conn_destroy(struct sua_connection *conn) -{ - /* FIXME: do some cleanup; inform user? */ - osmo_timer_del(&conn->tias); - osmo_timer_del(&conn->tiar); - llist_del(&conn->list); - talloc_free(conn); -} - -static void conn_state_set(struct sua_connection *conn, - enum sua_connection_state state) -{ - DEBUGP(DSUA, "(%u) state chg %s->", conn->conn_id, - get_value_string(conn_state_names, conn->state)); - DEBUGPC(DSUA, "%s\n", - get_value_string(conn_state_names, state)); - conn->state = state; -} - -static void conn_restart_tx_inact_timer(struct sua_connection *conn) -{ - osmo_timer_schedule(&conn->tias, TX_INACT_TIMER / 100, - (TX_INACT_TIMER % 100) * 10); -} - -static void conn_restart_rx_inact_timer(struct sua_connection *conn) -{ - osmo_timer_schedule(&conn->tiar, RX_INACT_TIMER / 100, - (RX_INACT_TIMER % 100) * 10); -} - -static void conn_start_inact_timers(struct sua_connection *conn) -{ - conn_restart_tx_inact_timer(conn); - conn_restart_rx_inact_timer(conn); -} - -/*********************************************************************** - * Handling of messages from the User SAP - ***********************************************************************/ - -/* user program sends us a N-CONNNECT.req to initiate a new connection */ -static int sua_connect_req(struct osmo_sccp_link *link, struct osmo_scu_prim *prim) -{ - struct osmo_scu_connect_param *par = &prim->u.connect; - struct xua_msg *xua = xua_msg_alloc(); - struct sua_connection *conn; - struct msgb *outmsg; - - if (par->sccp_class != 2) { - LOGP(DSUA, LOGL_ERROR, "N-CONNECT.req for unsupported " - "SCCP class %u\n", par->sccp_class); - /* FIXME: Send primitive to user */ - return -EINVAL; - } - - conn = conn_create_id(link, par->conn_id); - if (!conn) { - /* FIXME: Send primitive to user */ - return -EINVAL; - } - - memcpy(&conn->called_addr, &par->called_addr, - sizeof(conn->called_addr)); - memcpy(&conn->calling_addr, &par->calling_addr, - sizeof(conn->calling_addr)); - - /* encode + send the CLDT */ - xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_CORE); - xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, 0); /* FIXME */ - xua_msg_add_u32(xua, SUA_IEI_PROTO_CLASS, par->sccp_class); - xua_msg_add_u32(xua, SUA_IEI_SRC_REF, conn->conn_id); - xua_msg_add_sccp_addr(xua, SUA_IEI_DEST_ADDR, &par->called_addr); - xua_msg_add_u32(xua, SUA_IEI_SEQ_CTRL, 0); /* FIXME */ - /* sequence number */ - if (par->calling_addr.presence) - xua_msg_add_sccp_addr(xua, SUA_IEI_SRC_ADDR, &par->calling_addr); - /* optional: hop count; importance; priority; credit */ - if (msgb_l2(prim->oph.msg)) - xua_msg_add_data(xua, SUA_IEI_DATA, msgb_l2len(prim->oph.msg), - msgb_l2(prim->oph.msg)); - - outmsg = xua_to_msg(1, xua); - xua_msg_free(xua); - - /* FIXME: Start CONNECTION_TIMER */ - conn_state_set(conn, S_CONN_PEND_OUT); - - return sua_link_send(link, outmsg); -} - -/* user program sends us a N-CONNNECT.resp, presumably against a - * N-CONNECT.ind */ -static int sua_connect_resp(struct osmo_sccp_link *link, struct osmo_scu_prim *prim) -{ - struct osmo_scu_connect_param *par = &prim->u.connect; - struct xua_msg *xua = xua_msg_alloc(); - struct sua_connection *conn; - struct msgb *outmsg; - - /* check if we already know a connection for this conn_id */ - conn = conn_find_by_id(link, par->conn_id); - if (!conn) { - LOGP(DSUA, LOGL_ERROR, "N-CONNECT.resp for unknown " - "connection ID %u\n", par->conn_id); - /* FIXME: Send primitive to user */ + if (!asp) { + LOGP(DLSUA, LOGL_ERROR, "No ASP in AS, dropping message\n"); + xua_msg_free(xua); return -ENODEV; } - if (conn->state != S_CONN_PEND_IN) { - LOGP(DSUA, LOGL_ERROR, "N-CONNECT.resp in wrong state %s\n", - get_value_string(conn_state_names, conn->state)); - /* FIXME: Send primitive to user */ - return -EINVAL; - } - - /* encode + send the COAK message */ - xua = xua_msg_alloc(); - xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_COAK); - xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, 0); /* FIXME */ - xua_msg_add_u32(xua, SUA_IEI_PROTO_CLASS, par->sccp_class); - xua_msg_add_u32(xua, SUA_IEI_DEST_REF, conn->remote_ref); - xua_msg_add_u32(xua, SUA_IEI_SRC_REF, conn->conn_id); - xua_msg_add_u32(xua, SUA_IEI_SEQ_CTRL, 0); /* FIXME */ - /* sequence number */ - if (par->calling_addr.presence) - xua_msg_add_sccp_addr(xua, SUA_IEI_SRC_ADDR, &par->calling_addr); - /* optional: hop count; importance; priority */ - /* FIXME: destination address will be present in case the CORE - * message conveys the source address parameter */ - if (par->called_addr.presence) - xua_msg_add_sccp_addr(xua, SUA_IEI_DEST_ADDR, &par->called_addr); - if (msgb_l2(prim->oph.msg)) - xua_msg_add_data(xua, SUA_IEI_DATA, msgb_l2len(prim->oph.msg), - msgb_l2(prim->oph.msg)); - - outmsg = xua_to_msg(1, xua); - xua_msg_free(xua); - - conn_state_set(conn, S_ACTIVE); - conn_start_inact_timers(conn); - - return sua_link_send(link, outmsg); -} - -/* user wants to send connection-oriented data */ -static int sua_data_req(struct osmo_sccp_link *link, struct osmo_scu_prim *prim) -{ - struct osmo_scu_data_param *par = &prim->u.data; - struct xua_msg *xua; - struct sua_connection *conn; - struct msgb *outmsg; - - /* check if we know about this conncetion, and obtain reference */ - conn = conn_find_by_id(link, par->conn_id); - if (!conn) { - LOGP(DSUA, LOGL_ERROR, "N-DATA.req for unknown " - "connection ID %u\n", par->conn_id); - /* FIXME: Send primitive to user */ - return -ENODEV; - } - - if (conn->state != S_ACTIVE) { - LOGP(DSUA, LOGL_ERROR, "N-DATA.req in wrong state %s\n", - get_value_string(conn_state_names, conn->state)); - /* FIXME: Send primitive to user */ - return -EINVAL; - } - - conn_restart_tx_inact_timer(conn); - - /* encode + send the CODT message */ - xua = xua_msg_alloc(); - xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_CODT); - xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, 0); /* FIXME */ - /* Sequence number only in expedited data */ - xua_msg_add_u32(xua, SUA_IEI_DEST_REF, conn->remote_ref); - /* optional: priority; correlation id */ - xua_msg_add_data(xua, SUA_IEI_DATA, msgb_l2len(prim->oph.msg), - msgb_l2(prim->oph.msg)); - - outmsg = xua_to_msg(1, xua); - xua_msg_free(xua); - - return sua_link_send(link, outmsg); -} - -/* user wants to disconnect a connection */ -static int sua_disconnect_req(struct osmo_sccp_link *link, struct osmo_scu_prim *prim) -{ - struct osmo_scu_disconn_param *par = &prim->u.disconnect; - struct xua_msg *xua; - struct sua_connection *conn; - struct msgb *outmsg; - - /* resolve reference of connection */ - conn = conn_find_by_id(link, par->conn_id); - if (!conn) { - LOGP(DSUA, LOGL_ERROR, "N-DISCONNECT.req for unknown " - "connection ID %u\n", par->conn_id); - /* FIXME: Send primitive to user */ - return -ENODEV; - } - - /* encode + send the RELRE */ - xua = xua_msg_alloc(); - xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_RELRE); - xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, 0); /* FIXME */ - xua_msg_add_u32(xua, SUA_IEI_DEST_REF, conn->remote_ref); - xua_msg_add_u32(xua, SUA_IEI_SRC_REF, conn->conn_id); - xua_msg_add_u32(xua, SUA_IEI_CAUSE, par->cause); - /* optional: importance */ - if (msgb_l2(prim->oph.msg)) - xua_msg_add_data(xua, SUA_IEI_DATA, msgb_l2len(prim->oph.msg), - msgb_l2(prim->oph.msg)); - - outmsg = xua_to_msg(1, xua); - xua_msg_free(xua); - - conn_state_set(conn, S_DISCONN_PEND); - conn_destroy(conn); - - LOGP(DSUA, LOGL_NOTICE, "About to send the SUA RELRE\n"); - return sua_link_send(link, outmsg); -} - -/* user wants to send connectionless data */ -static int sua_unitdata_req(struct osmo_sccp_link *link, struct osmo_scu_prim *prim) -{ - struct osmo_scu_unitdata_param *par = &prim->u.unitdata; - struct xua_msg *xua = xua_msg_alloc(); - struct msgb *outmsg; - - /* encode + send the CLDT */ - xua->hdr = XUA_HDR(SUA_MSGC_CL, SUA_CL_CLDT); - xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, 0); /* FIXME */ - xua_msg_add_u32(xua, SUA_IEI_PROTO_CLASS, 0); - xua_msg_add_sccp_addr(xua, SUA_IEI_SRC_ADDR, &par->calling_addr); - xua_msg_add_sccp_addr(xua, SUA_IEI_DEST_ADDR, &par->called_addr); - xua_msg_add_u32(xua, SUA_IEI_SEQ_CTRL, par->in_sequence_control); - /* optional: importance, ... correlation id? */ - xua_msg_add_data(xua, SUA_IEI_DATA, msgb_l2len(prim->oph.msg), - msgb_l2(prim->oph.msg)); - - outmsg = xua_to_msg(1, xua); - xua_msg_free(xua); - - return sua_link_send(link, outmsg); -} - -/* user hands us a SCCP-USER SAP primitive down into the stack */ -int osmo_sua_user_link_down(struct osmo_sccp_link *link, struct osmo_prim_hdr *oph) -{ - struct osmo_scu_prim *prim = (struct osmo_scu_prim *) oph; - struct msgb *msg = prim->oph.msg; - int rc = 0; - - LOGP(DSUA, LOGL_DEBUG, "Received SCCP User Primitive (%s)\n", - osmo_scu_prim_name(&prim->oph)); - - switch (OSMO_PRIM_HDR(&prim->oph)) { - case OSMO_PRIM(OSMO_SCU_PRIM_N_CONNECT, PRIM_OP_REQUEST): - rc = sua_connect_req(link, prim); - break; - case OSMO_PRIM(OSMO_SCU_PRIM_N_CONNECT, PRIM_OP_RESPONSE): - rc = sua_connect_resp(link, prim); - break; - case OSMO_PRIM(OSMO_SCU_PRIM_N_DATA, PRIM_OP_REQUEST): - rc = sua_data_req(link, prim); - break; - case OSMO_PRIM(OSMO_SCU_PRIM_N_DISCONNECT, PRIM_OP_REQUEST): - rc = sua_disconnect_req(link, prim); - break; - case OSMO_PRIM(OSMO_SCU_PRIM_N_UNITDATA, PRIM_OP_REQUEST): - rc = sua_unitdata_req(link, prim); - break; - default: - rc = -1; - } - - if (rc != 1) - msgb_free(msg); - - return rc; + return sua_tx_xua_asp(asp, xua); } /*********************************************************************** @@ -750,12 +355,12 @@ memset(out, 0, sizeof(*out)); - LOGP(DSUA, LOGL_DEBUG, "%s(IEI=0x%04x) (%d) %s\n", __func__, + LOGP(DLSUA, LOGL_DEBUG, "%s(IEI=0x%04x) (%d) %s\n", __func__, param->tag, param->len, osmo_hexdump(param->dat, param->len)); if (param->len < 4) { - LOGP(DSUA, LOGL_ERROR, "SUA IEI 0x%04x: invalid address length: %d\n", + LOGP(DLSUA, LOGL_ERROR, "SUA IEI 0x%04x: invalid address length: %d\n", param->tag, param->len); return -EINVAL; } @@ -778,14 +383,14 @@ break; case SUA_RI_HOST: default: - LOGP(DSUA, LOGL_ERROR, "SUA IEI 0x%04x: Routing Indicator not supported yet: %d\n", + LOGP(DLSUA, LOGL_ERROR, "SUA IEI 0x%04x: Routing Indicator not supported yet: %d\n", param->tag, ri); return -ENOTSUP; } if (ai != 7) { #if 0 - LOGP(DSUA, LOGL_ERROR, "SUA IEI 0x%04x: Address Indicator not supported yet: %x\n", + LOGP(DLSUA, LOGL_ERROR, "SUA IEI 0x%04x: Address Indicator not supported yet: %x\n", param->tag, ai); return -ENOTSUP; #endif @@ -805,7 +410,7 @@ par_len = ntohs(par->len); par_datalen = par_len - sizeof(*par); - LOGP(DSUA, LOGL_DEBUG, "SUA IEI 0x%04x pos %hu/%hu: subpart tag 0x%04x, len %hu\n", + LOGP(DLSUA, LOGL_DEBUG, "SUA IEI 0x%04x pos %hu/%hu: subpart tag 0x%04x, len %hu\n", param->tag, pos, param->len, par_tag, par_len); switch (par_tag) { @@ -838,7 +443,7 @@ out->presence |= OSMO_SCCP_ADDR_T_IPv4; break; default: - LOGP(DSUA, LOGL_ERROR, "SUA IEI 0x%04x: Unknown subpart tag %hd\n", + LOGP(DLSUA, LOGL_ERROR, "SUA IEI 0x%04x: Unknown subpart tag %hd\n", param->tag, par_tag); goto subpar_fail; } @@ -849,7 +454,7 @@ return 0; subpar_fail: - LOGP(DSUA, LOGL_ERROR, "Failed to parse subparts of address IEI=0x%04x\n", + LOGP(DLSUA, LOGL_ERROR, "Failed to parse subparts of address IEI=0x%04x\n", param->tag); return -EINVAL; } @@ -870,809 +475,205 @@ return sua_addr_parse_part(out, param); } -static int sua_rx_cldt(struct osmo_sccp_link *link, struct xua_msg *xua) +/* connectionless messages received from socket */ +static int sua_rx_cl(struct osmo_ss7_asp *asp, struct xua_msg *xua) { - struct osmo_scu_prim *prim; - struct osmo_scu_unitdata_param *param; - struct xua_msg_part *data_ie = xua_msg_find_tag(xua, SUA_IEI_DATA); - struct msgb *upmsg = sccp_msgb_alloc(__func__); - uint32_t protocol_class; + struct osmo_sccp_instance *inst = asp->inst->sccp; - /* fill primitive */ - prim = (struct osmo_scu_prim *) msgb_put(upmsg, sizeof(*prim)); - param = &prim->u.unitdata; - osmo_prim_init(&prim->oph, SCCP_SAP_USER, - OSMO_SCU_PRIM_N_UNITDATA, - PRIM_OP_INDICATION, upmsg); - sua_addr_parse(¶m->called_addr, xua, SUA_IEI_DEST_ADDR); - sua_addr_parse(¶m->calling_addr, xua, SUA_IEI_SRC_ADDR); - param->in_sequence_control = xua_msg_get_u32(xua, SUA_IEI_SEQ_CTRL); - protocol_class = xua_msg_get_u32(xua, SUA_IEI_PROTO_CLASS); - param->return_option = protocol_class & 0x80; - param->importance = xua_msg_get_u32(xua, SUA_IEI_IMPORTANCE); - - /* copy data */ - upmsg->l2h = msgb_put(upmsg, data_ie->len); - memcpy(upmsg->l2h, data_ie->dat, data_ie->len); - - /* send to user SAP */ - link->user->prim_cb(&prim->oph, link); - - return 0; + /* We feed into SCRC, which then hands the message into + * either SCLC or SCOC, or forwards it to MTP */ + return scrc_rx_mtp_xfer_ind_xua(inst, xua); } - - -/* connectioness messages received from socket */ -static int sua_rx_cl(struct osmo_sccp_link *link, - struct xua_msg *xua, struct msgb *msg) -{ - int rc = -1; - - switch (xua->hdr.msg_type) { - case SUA_CL_CLDT: - rc = sua_rx_cldt(link, xua); - break; - case SUA_CL_CLDR: - default: - break; - } - - return rc; -} - -/* RFC 3868 3.3.3 / SCCP CR (Connection Request) */ -static int sua_rx_core(struct osmo_sccp_link *link, struct xua_msg *xua) -{ - struct osmo_scu_prim *prim; - struct osmo_scu_connect_param *param; - struct xua_msg_part *data_ie = xua_msg_find_tag(xua, SUA_IEI_DATA); - struct msgb *upmsg; - struct sua_connection *conn; - - /* fill conn */ - conn = conn_create(link); - sua_addr_parse(&conn->called_addr, xua, SUA_IEI_DEST_ADDR); - sua_addr_parse(&conn->calling_addr, xua, SUA_IEI_SRC_ADDR); - conn->remote_ref = xua_msg_get_u32(xua, SUA_IEI_SRC_REF); - - /* fill primitive */ - upmsg = sccp_msgb_alloc(__func__); - prim = (struct osmo_scu_prim *) msgb_put(upmsg, sizeof(*prim)); - param = &prim->u.connect; - osmo_prim_init(&prim->oph, SCCP_SAP_USER, - OSMO_SCU_PRIM_N_CONNECT, - PRIM_OP_INDICATION, upmsg); - param->conn_id = conn->conn_id; - memcpy(¶m->called_addr, &conn->called_addr, - sizeof(param->called_addr)); - memcpy(¶m->calling_addr, &conn->calling_addr, - sizeof(param->calling_addr)); - //param->in_sequence_control; - param->sccp_class = xua_msg_get_u32(xua, SUA_IEI_PROTO_CLASS) & 3; - param->importance = xua_msg_get_u32(xua, SUA_IEI_IMPORTANCE); - - if (data_ie) { - /* copy data */ - upmsg->l2h = msgb_put(upmsg, data_ie->len); - memcpy(upmsg->l2h, data_ie->dat, data_ie->len); - } - - conn_state_set(conn, S_CONN_PEND_IN); - - /* send to user SAP */ - link->user->prim_cb(&prim->oph, link); - - return 0; -} - -/* RFC 3868 3.3.4 / SCCP CC (Connection Confirm) */ -static int sua_rx_coak(struct osmo_sccp_link *link, struct xua_msg *xua) -{ - struct osmo_scu_prim *prim; - struct sua_connection *conn; - struct osmo_scu_connect_param *param; - struct xua_msg_part *data_ie = xua_msg_find_tag(xua, SUA_IEI_DATA); - struct msgb *upmsg; - uint32_t conn_id = xua_msg_get_u32(xua, SUA_IEI_DEST_REF); - - /* resolve conn */ - conn = conn_find_by_id(link, conn_id); - if (!conn) { - LOGP(DSUA, LOGL_ERROR, "COAK for unknown reference %u\n", - conn_id); - /* FIXME: send error reply down the sua link? */ - return -1; - } - conn_restart_rx_inact_timer(conn); - - if (conn->state != S_CONN_PEND_OUT) { - LOGP(DSUA, LOGL_ERROR, "COAK in wrong state %s\n", - get_value_string(conn_state_names, conn->state)); - /* FIXME: send error reply down the sua link? */ - return -EINVAL; - } - - /* track remote reference */ - conn->remote_ref = xua_msg_get_u32(xua, SUA_IEI_SRC_REF); - - /* fill primitive */ - upmsg = sccp_msgb_alloc(__func__); - prim = (struct osmo_scu_prim *) msgb_put(upmsg, sizeof(*prim)); - param = &prim->u.connect; - osmo_prim_init(&prim->oph, SCCP_SAP_USER, - OSMO_SCU_PRIM_N_CONNECT, - PRIM_OP_CONFIRM, upmsg); - param->conn_id = conn->conn_id; - memcpy(¶m->called_addr, &conn->called_addr, - sizeof(param->called_addr)); - memcpy(¶m->calling_addr, &conn->calling_addr, - sizeof(param->calling_addr)); - //param->in_sequence_control; - param->sccp_class = xua_msg_get_u32(xua, SUA_IEI_PROTO_CLASS) & 3; - param->importance = xua_msg_get_u32(xua, SUA_IEI_IMPORTANCE); - - if (data_ie) { - /* copy data */ - upmsg->l2h = msgb_put(upmsg, data_ie->len); - memcpy(upmsg->l2h, data_ie->dat, data_ie->len); - } - - conn_state_set(conn, S_ACTIVE); - conn_start_inact_timers(conn); - - /* send to user SAP */ - link->user->prim_cb(&prim->oph, link); - - return 0; -} - -/* RFC 3868 3.3.5 / SCCP CREF (Connection Refused) */ -static int sua_rx_coref(struct osmo_sccp_link *link, struct xua_msg *xua) -{ - struct osmo_scu_prim *prim; - struct sua_connection *conn; - struct osmo_scu_disconn_param *param; - struct xua_msg_part *data_ie = xua_msg_find_tag(xua, SUA_IEI_DATA); - struct msgb *upmsg; - uint32_t conn_id = xua_msg_get_u32(xua, SUA_IEI_DEST_REF); - uint32_t cause; - - /* resolve conn */ - conn = conn_find_by_id(link, conn_id); - if (!conn) { - LOGP(DSUA, LOGL_ERROR, "COREF for unknown reference %u\n", - conn_id); - /* FIXME: send error reply down the sua link? */ - return -1; - } - conn_restart_rx_inact_timer(conn); - - /* fill primitive */ - upmsg = sccp_msgb_alloc(__func__); - prim = (struct osmo_scu_prim *) msgb_put(upmsg, sizeof(*prim)); - param = &prim->u.disconnect; - osmo_prim_init(&prim->oph, SCCP_SAP_USER, - OSMO_SCU_PRIM_N_DISCONNECT, - PRIM_OP_INDICATION, upmsg); - param->conn_id = conn_id; - param->responding_addr = conn->called_addr; - param->originator = OSMO_SCCP_ORIG_UNDEFINED; - //param->in_sequence_control; - /* TODO evaluate cause: - * cause = xua_msg_get_u32(xua, SUA_IEI_CAUSE); */ - /* optional: src addr */ - /* optional: dest addr */ - param->importance = xua_msg_get_u32(xua, SUA_IEI_IMPORTANCE); - if (data_ie) { - /* copy data */ - upmsg->l2h = msgb_put(upmsg, data_ie->len); - memcpy(upmsg->l2h, data_ie->dat, data_ie->len); - } - - /* send to user SAP */ - link->user->prim_cb(&prim->oph, link); - - conn_state_set(conn, S_IDLE); - conn_destroy(conn); - - return 0; -} - -/* RFC 3868 3.3.6 / SCCP RLSD (Released) */ -static int sua_rx_relre(struct osmo_sccp_link *link, struct xua_msg *xua) -{ - struct osmo_scu_prim *prim; - struct sua_connection *conn; - struct osmo_scu_disconn_param *param; - struct xua_msg_part *data_ie = xua_msg_find_tag(xua, SUA_IEI_DATA); - struct msgb *upmsg; - uint32_t conn_id = xua_msg_get_u32(xua, SUA_IEI_DEST_REF); - uint32_t cause; - - /* resolve conn */ - conn = conn_find_by_id(link, conn_id); - if (!conn) { - LOGP(DSUA, LOGL_ERROR, "RELRE for unknown reference %u\n", - conn_id); - /* FIXME: send error reply down the sua link? */ - return -1; - } - - /* fill primitive */ - upmsg = sccp_msgb_alloc(__func__); - prim = (struct osmo_scu_prim *) msgb_put(upmsg, sizeof(*prim)); - param = &prim->u.disconnect; - osmo_prim_init(&prim->oph, SCCP_SAP_USER, - OSMO_SCU_PRIM_N_DISCONNECT, - PRIM_OP_INDICATION, upmsg); /* what primitive? */ - - param->conn_id = conn_id; - /* source reference */ - cause = xua_msg_get_u32(xua, SUA_IEI_CAUSE); - param->importance = xua_msg_get_u32(xua, SUA_IEI_IMPORTANCE); - if (data_ie) { - /* copy data */ - upmsg->l2h = msgb_put(upmsg, data_ie->len); - memcpy(upmsg->l2h, data_ie->dat, data_ie->len); - } - - param->responding_addr = conn->called_addr; - param->originator = OSMO_SCCP_ORIG_UNDEFINED; - - /* send to user SAP */ - link->user->prim_cb(&prim->oph, link); - - conn_state_set(conn, S_IDLE); - conn_destroy(conn); - - return 0; -} - -/* RFC 3868 3.3.7 / SCCP RLC (Release Complete)*/ -static int sua_rx_relco(struct osmo_sccp_link *link, struct xua_msg *xua) -{ - struct osmo_scu_prim *prim; - struct sua_connection *conn; - struct osmo_scu_disconn_param *param; - struct msgb *upmsg; - uint32_t conn_id = xua_msg_get_u32(xua, SUA_IEI_DEST_REF); - - /* resolve conn */ - conn = conn_find_by_id(link, conn_id); - if (!conn) { - LOGP(DSUA, LOGL_ERROR, "RELCO for unknown reference %u\n", - conn_id); - /* FIXME: send error reply down the sua link? */ - return -1; - } - conn_restart_rx_inact_timer(conn); - - /* fill primitive */ - upmsg = sccp_msgb_alloc(__func__); - prim = (struct osmo_scu_prim *) msgb_put(upmsg, sizeof(*prim)); - param = &prim->u.disconnect; - osmo_prim_init(&prim->oph, SCCP_SAP_USER, - OSMO_SCU_PRIM_N_DISCONNECT, - PRIM_OP_CONFIRM, upmsg); /* what primitive? */ - - param->conn_id = conn_id; - /* source reference */ - param->importance = xua_msg_get_u32(xua, SUA_IEI_IMPORTANCE); - - param->responding_addr = conn->called_addr; - param->originator = OSMO_SCCP_ORIG_UNDEFINED; - - /* send to user SAP */ - link->user->prim_cb(&prim->oph, link); - - conn_destroy(conn); - - return 0; - -} - -/* RFC3868 3.3.1 / SCCP DT1 (Data Form 1) */ -static int sua_rx_codt(struct osmo_sccp_link *link, struct xua_msg *xua) -{ - struct osmo_scu_prim *prim; - struct sua_connection *conn; - struct osmo_scu_data_param *param; - struct xua_msg_part *data_ie = xua_msg_find_tag(xua, SUA_IEI_DATA); - struct msgb *upmsg; - uint32_t conn_id = xua_msg_get_u32(xua, SUA_IEI_DEST_REF); - - /* resolve conn */ - conn = conn_find_by_id(link, conn_id); - if (!conn) { - LOGP(DSUA, LOGL_ERROR, "DT1 for unknown reference %u\n", - conn_id); - /* FIXME: send error reply down the sua link? */ - return -1; - } - - if (conn->state != S_ACTIVE) { - LOGP(DSUA, LOGL_ERROR, "DT1 in invalid state %s\n", - get_value_string(conn_state_names, conn->state)); - /* FIXME: send error reply down the sua link? */ - return -1; - } - - conn_restart_rx_inact_timer(conn); - - /* fill primitive */ - upmsg = sccp_msgb_alloc(__func__); - prim = (struct osmo_scu_prim *) msgb_put(upmsg, sizeof(*prim)); - param = &prim->u.data; - osmo_prim_init(&prim->oph, SCCP_SAP_USER, - OSMO_SCU_PRIM_N_DATA, - PRIM_OP_INDICATION, upmsg); - param->conn_id = conn_id; - param->importance = xua_msg_get_u32(xua, SUA_IEI_IMPORTANCE); - - /* copy data */ - upmsg->l2h = msgb_put(upmsg, data_ie->len); - memcpy(upmsg->l2h, data_ie->dat, data_ie->len); - - /* send to user SAP */ - link->user->prim_cb(&prim->oph, link); - - return 0; -} - /* connection-oriented messages received from socket */ -static int sua_rx_co(struct osmo_sccp_link *link, - struct xua_msg *xua, struct msgb *msg) +static int sua_rx_co(struct osmo_ss7_asp *asp, struct xua_msg *xua) { - int rc = -1; + struct osmo_sccp_instance *inst = asp->inst->sccp; - switch (xua->hdr.msg_type) { - case SUA_CO_CORE: - rc = sua_rx_core(link, xua); - break; - case SUA_CO_COAK: - rc = sua_rx_coak(link, xua); - break; - case SUA_CO_COREF: - rc = sua_rx_coref(link, xua); - break; - case SUA_CO_RELRE: - rc = sua_rx_relre(link, xua); - break; - case SUA_CO_RELCO: - rc = sua_rx_relco(link, xua); - break; - case SUA_CO_CODT: - rc = sua_rx_codt(link, xua); - break; - case SUA_CO_RESCO: - case SUA_CO_RESRE: - case SUA_CO_CODA: - case SUA_CO_COERR: - case SUA_CO_COIT: - /* FIXME */ - default: - break; - } - - return rc; + /* We feed into SCRC, which then hands the message into + * either SCLC or SCOC, or forwards it to MTP */ + return scrc_rx_mtp_xfer_ind_xua(inst, xua); } -/* process SUA message received from socket */ -static int sua_rx_msg(struct osmo_sccp_link *link, struct msgb *msg) +static int sua_rx_mgmt_err(struct osmo_ss7_asp *asp, struct xua_msg *xua) { - struct xua_msg *xua; - int rc = -1; + uint32_t err_code = xua_msg_get_u32(xua, SUA_IEI_ERR_CODE); - xua = xua_from_msg(1, msgb_length(msg), msg->data); - if (!xua) { - LOGP(DSUA, LOGL_ERROR, "Unable to parse incoming " - "SUA message\n"); + LOGPASP(asp, DLSUA, LOGL_ERROR, "Received MGMT_ERR '%s': %s\n", + get_value_string(m3ua_err_names, err_code), + xua_msg_dump(xua, &xua_dialect_sua)); + + /* NEVER return != 0 here, as we cannot respont to an ERR + * message with another ERR! */ + return 0; +} + +static int sua_rx_mgmt_ntfy(struct osmo_ss7_asp *asp, struct xua_msg *xua) +{ + struct m3ua_notify_params ntfy; + const char *type_name, *info_name; + + m3ua_decode_notify(&ntfy, asp, xua); + + type_name = get_value_string(m3ua_ntfy_type_names, ntfy.status_type); + + switch (ntfy.status_type) { + case M3UA_NOTIFY_T_STATCHG: + info_name = get_value_string(m3ua_ntfy_stchg_names, + ntfy.status_info); + break; + case M3UA_NOTIFY_T_OTHER: + info_name = get_value_string(m3ua_ntfy_other_names, + ntfy.status_info); + break; + default: + info_name = "NULL"; + break; + } + LOGPASP(asp, DLSUA, LOGL_NOTICE, "Received NOTIFY Type %s:%s (%s)\n", + type_name, info_name, + ntfy.info_string ? ntfy.info_string : ""); + + if (ntfy.info_string) + talloc_free(ntfy.info_string); + + /* TODO: should we report this soemwhere? */ + return 0; +} + +static int sua_rx_mgmt(struct osmo_ss7_asp *asp, struct xua_msg *xua) +{ + switch (xua->hdr.msg_type) { + case SUA_MGMT_ERR: + return sua_rx_mgmt_err(asp, xua); + case SUA_MGMT_NTFY: + return sua_rx_mgmt_ntfy(asp, xua); + default: + return SUA_ERR_UNSUPP_MSG_TYPE; + } +} + +/* map from SUA ASPSM/ASPTM to xua_asp_fsm event */ +static const struct xua_msg_event_map sua_aspxm_map[] = { + { SUA_MSGC_ASPSM, SUA_ASPSM_UP, XUA_ASP_E_ASPSM_ASPUP }, + { SUA_MSGC_ASPSM, SUA_ASPSM_DOWN, XUA_ASP_E_ASPSM_ASPDN }, + { SUA_MSGC_ASPSM, SUA_ASPSM_BEAT, XUA_ASP_E_ASPSM_BEAT }, + { SUA_MSGC_ASPSM, SUA_ASPSM_UP_ACK, XUA_ASP_E_ASPSM_ASPUP_ACK }, + { SUA_MSGC_ASPSM, SUA_ASPSM_DOWN_ACK, XUA_ASP_E_ASPSM_ASPDN_ACK }, + { SUA_MSGC_ASPSM, SUA_ASPSM_BEAT_ACK, XUA_ASP_E_ASPSM_BEAT_ACK }, + { SUA_MSGC_ASPTM, SUA_ASPTM_ACTIVE, XUA_ASP_E_ASPTM_ASPAC }, + { SUA_MSGC_ASPTM, SUA_ASPTM_INACTIVE, XUA_ASP_E_ASPTM_ASPIA }, + { SUA_MSGC_ASPTM, SUA_ASPTM_ACTIVE_ACK, XUA_ASP_E_ASPTM_ASPAC_ACK }, + { SUA_MSGC_ASPTM, SUA_ASPTM_INACTIVE_ACK, XUA_ASP_E_ASPTM_ASPIA_ACK }, +}; + +static int sua_rx_asp(struct osmo_ss7_asp *asp, struct xua_msg *xua) +{ + int event; + + /* map from the SUA message class and message type to the XUA + * ASP FSM event number */ + event = xua_msg_event_map(xua, sua_aspxm_map, + ARRAY_SIZE(sua_aspxm_map)); + if (event < 0) + return SUA_ERR_UNSUPP_MSG_TYPE; + + /* deliver that event to the ASP FSM */ + osmo_fsm_inst_dispatch(asp->fi, event, xua); + + return 0; +} + +/*! \brief process SUA message received from socket + * \param[in] asp Application Server Process receiving \ref msg + * \param[in] msg received message buffer + * \returns 0 on success; negative on error */ +int sua_rx_msg(struct osmo_ss7_asp *asp, struct msgb *msg) +{ + struct xua_msg *xua = NULL, *err = NULL; + int rc = 0; + + OSMO_ASSERT(asp->cfg.proto == OSMO_SS7_ASP_PROT_SUA); + + /* caller owns msg memory, we shall neither free it here nor + * keep references beyon the execution of this function and its + * callees. */ + + if (!asp->inst->sccp) { + LOGP(DLSUA, LOGL_ERROR, "%s(asp->inst->sccp=NULL)\n", __func__); return -EIO; } - LOGP(DSUA, LOGL_DEBUG, "Received SUA Message (%s)\n", + xua = xua_from_msg(1, msgb_length(msg), msg->data); + if (!xua) { + struct xua_common_hdr *hdr = (struct xua_common_hdr *) msg->data; + + LOGPASP(asp, DLSUA, LOGL_ERROR, "Unable to parse incoming " + "SUA message\n"); + + if (hdr->version != SUA_VERSION) + err = sua_gen_error_msg(SUA_ERR_INVALID_VERSION, msg); + else + err = sua_gen_error_msg(SUA_ERR_PARAM_FIELD_ERR, msg); + goto out; + } + +#if 0 + xua->mtp.opc = ; + xua->mtp.dpc = ; +#endif + xua->mtp.sio = MTP_SI_SCCP; + + LOGPASP(asp, DLSUA, LOGL_DEBUG, "Received SUA Message (%s)\n", xua_hdr_dump(xua, &xua_dialect_sua)); - if (!xua_dialect_check_all_mand_ies(&xua_dialect_sua, xua)) - return -1; + if (!xua_dialect_check_all_mand_ies(&xua_dialect_sua, xua)) { + /* FIXME: Return error? */ + err = sua_gen_error_msg(SUA_ERR_MISSING_PARAM, msg); + goto out; + } + + /* TODO: check for SCTP Strema ID */ + /* TODO: check if any AS configured in ASP */ + /* TODO: check for valid routing context */ switch (xua->hdr.msg_class) { case SUA_MSGC_CL: - rc = sua_rx_cl(link, xua, msg); + rc = sua_rx_cl(asp, xua); break; case SUA_MSGC_CO: - rc = sua_rx_co(link, xua, msg); + rc = sua_rx_co(asp, xua); break; - case SUA_MSGC_MGMT: - case SUA_MSGC_SNM: case SUA_MSGC_ASPSM: case SUA_MSGC_ASPTM: + rc = sua_rx_asp(asp, xua); + break; + case SUA_MSGC_MGMT: + rc = sua_rx_mgmt(asp, xua); + break; + case SUA_MSGC_SNM: case SUA_MSGC_RKM: /* FIXME */ + LOGPASP(asp, DLSUA, LOGL_NOTICE, "Received unsupported SUA " + "Message Class %u\n", xua->hdr.msg_class); + err = sua_gen_error_msg(SUA_ERR_UNSUPP_MSG_CLASS, msg); + break; default: + LOGPASP(asp, DLSUA, LOGL_NOTICE, "Received unknown SUA " + "Message Class %u\n", xua->hdr.msg_class); + err = sua_gen_error_msg(SUA_ERR_UNSUPP_MSG_CLASS, msg); break; } + + if (rc > 0) + err = sua_gen_error_msg(rc, msg); + +out: + if (err) + sua_tx_xua_asp(asp, err); xua_msg_free(xua); return rc; } -/*********************************************************************** - * libosmonetif integration - ***********************************************************************/ - -#include -#include - -static const struct value_string sctp_assoc_chg_vals[] = { - { SCTP_COMM_UP, "COMM_UP" }, - { SCTP_COMM_LOST, "COMM_LOST" }, - { SCTP_RESTART, "RESTART" }, - { SCTP_SHUTDOWN_COMP, "SHUTDOWN_COMP" }, - { SCTP_CANT_STR_ASSOC, "CANT_STR_ASSOC" }, - { 0, NULL } -}; - -static const struct value_string sctp_sn_type_vals[] = { - { SCTP_ASSOC_CHANGE, "ASSOC_CHANGE" }, - { SCTP_PEER_ADDR_CHANGE, "PEER_ADDR_CHANGE" }, - { SCTP_SHUTDOWN_EVENT, "SHUTDOWN_EVENT" }, - { SCTP_SEND_FAILED, "SEND_FAILED" }, - { SCTP_REMOTE_ERROR, "REMOTE_ERROR" }, - { SCTP_PARTIAL_DELIVERY_EVENT, "PARTIAL_DELIVERY_EVENT" }, - { SCTP_ADAPTATION_INDICATION, "ADAPTATION_INDICATION" }, -#ifdef SCTP_AUTHENTICATION_INDICATION - { SCTP_AUTHENTICATION_INDICATION, "UTHENTICATION_INDICATION" }, -#endif -#ifdef SCTP_SENDER_DRY_EVENT - { SCTP_SENDER_DRY_EVENT, "SENDER_DRY_EVENT" }, -#endif - { 0, NULL } -}; - -static int get_logevel_by_sn_type(int sn_type) -{ - switch (sn_type) { - case SCTP_ADAPTATION_INDICATION: - case SCTP_PEER_ADDR_CHANGE: -#ifdef SCTP_AUTHENTICATION_INDICATION - case SCTP_AUTHENTICATION_INDICATION: -#endif -#ifdef SCTP_SENDER_DRY_EVENT - case SCTP_SENDER_DRY_EVENT: -#endif - return LOGL_INFO; - case SCTP_ASSOC_CHANGE: - return LOGL_NOTICE; - case SCTP_SHUTDOWN_EVENT: - case SCTP_PARTIAL_DELIVERY_EVENT: - return LOGL_NOTICE; - case SCTP_SEND_FAILED: - case SCTP_REMOTE_ERROR: - return LOGL_ERROR; - default: - return LOGL_NOTICE; - } -} - -static void log_sctp_notification(int fd, const char *pfx, - union sctp_notification *notif) -{ - int log_level; - char *conn_id = osmo_sock_get_name(NULL, fd); - - LOGP(DSUA, LOGL_INFO, "%s %s SCTP NOTIFICATION %u flags=0x%0x\n", - conn_id, pfx, notif->sn_header.sn_type, - notif->sn_header.sn_flags); - - log_level = get_logevel_by_sn_type(notif->sn_header.sn_type); - - switch (notif->sn_header.sn_type) { - case SCTP_ASSOC_CHANGE: - LOGP(DSUA, log_level, "%s %s SCTP_ASSOC_CHANGE: %s\n", - conn_id, pfx, get_value_string(sctp_assoc_chg_vals, - notif->sn_assoc_change.sac_state)); - break; - default: - LOGP(DSUA, log_level, "%s %s %s\n", - conn_id, pfx, get_value_string(sctp_sn_type_vals, - notif->sn_header.sn_type)); - break; - } - - talloc_free(conn_id); -} - -/* netif code tells us we can read something from the socket */ -static int sua_srv_conn_cb(struct osmo_stream_srv *conn) -{ - struct osmo_fd *ofd = osmo_stream_srv_get_ofd(conn); - struct osmo_sccp_link *link = osmo_stream_srv_get_data(conn); - struct msgb *msg = msgb_alloc(SUA_MSGB_SIZE, "SUA Server Rx"); - struct sctp_sndrcvinfo sinfo; - unsigned int ppid; - int flags = 0; - int rc; - - if (!msg) - return -ENOMEM; - - /* read SUA message from socket and process it */ - rc = sctp_recvmsg(ofd->fd, msgb_data(msg), msgb_tailroom(msg), - NULL, NULL, &sinfo, &flags); - LOGP(DSUA, LOGL_DEBUG, "sua_srv_conn_cb(): sctp_recvmsg() returned %d\n", - rc); - if (rc < 0) { - close(ofd->fd); - osmo_fd_unregister(ofd); - ofd->fd = -1; - return rc; - } else if (rc == 0) { - close(ofd->fd); - osmo_fd_unregister(ofd); - ofd->fd = -1; - } else { - msgb_put(msg, rc); - } - - if (flags & MSG_NOTIFICATION) { - union sctp_notification *notif = (union sctp_notification *) msgb_data(msg); - - log_sctp_notification(ofd->fd, "SUA SRV", notif); - - switch (notif->sn_header.sn_type) { - case SCTP_SHUTDOWN_EVENT: - close(ofd->fd); - osmo_fd_unregister(ofd); - ofd->fd = -1; - break; - default: - break; - } - msgb_free(msg); - return 0; - } - - ppid = ntohl(sinfo.sinfo_ppid); - msgb_sctp_ppid(msg) = ppid; - msgb_sctp_stream(msg) = ntohl(sinfo.sinfo_stream); - msg->dst = link; - - switch (ppid) { - case SUA_PPID: - rc = sua_rx_msg(link, msg); - break; - default: - LOGP(DSUA, LOGL_NOTICE, "SCTP chunk for unknown PPID %u " - "received\n", ppid); - rc = 0; - break; - } - - msgb_free(msg); - return rc; -} - -static int sua_srv_conn_closed_cb(struct osmo_stream_srv *srv) -{ - struct osmo_sccp_link *sual = osmo_stream_srv_get_data(srv); - struct sua_connection *conn; - - LOGP(DSUA, LOGL_INFO, "SCTP connection closed\n"); - - /* remove from per-user list of sua links */ - llist_del(&sual->list); - - llist_for_each_entry(conn, &sual->connections, list) { - /* FIXME: send RELEASE request */ - } - talloc_free(sual); - osmo_stream_srv_set_data(srv, NULL); - - return 0; -} - -static int sua_accept_cb(struct osmo_stream_srv_link *link, int fd) -{ - struct osmo_sccp_user *user = osmo_stream_srv_link_get_data(link); - struct osmo_stream_srv *srv; - struct osmo_sccp_link *sual; - - LOGP(DSUA, LOGL_INFO, "New SCTP connection accepted\n"); - - srv = osmo_stream_srv_create(user, link, fd, - sua_srv_conn_cb, - sua_srv_conn_closed_cb, NULL); - if (!srv) { - close(fd); - return -1; - } - - /* create new SUA link and connect both data structures */ - sual = sua_link_new(user, 1); - if (!sual) { - osmo_stream_srv_destroy(srv); - return -1; - } - sual->data = srv; - osmo_stream_srv_set_data(srv, sual); - - return 0; -} - -int osmo_sua_server_listen(struct osmo_sccp_user *user, const char *hostname, uint16_t port) -{ - int rc; - - if (user->server) - osmo_stream_srv_link_close(user->server); - else { - user->server = osmo_stream_srv_link_create(user); - osmo_stream_srv_link_set_data(user->server, user); - osmo_stream_srv_link_set_accept_cb(user->server, sua_accept_cb); - } - - osmo_stream_srv_link_set_addr(user->server, hostname); - osmo_stream_srv_link_set_port(user->server, port); - osmo_stream_srv_link_set_proto(user->server, IPPROTO_SCTP); - - rc = osmo_stream_srv_link_open(user->server); - if (rc < 0) { - osmo_stream_srv_link_destroy(user->server); - user->server = NULL; - return rc; - } - - return 0; -} - -/* netif code tells us we can read something from the socket */ -static int sua_cli_read_cb(struct osmo_stream_cli *conn) -{ - struct osmo_fd *ofd = osmo_stream_cli_get_ofd(conn); - struct osmo_sccp_link *link = osmo_stream_cli_get_data(conn); - struct msgb *msg = msgb_alloc(SUA_MSGB_SIZE, "SUA Client Rx"); - struct sctp_sndrcvinfo sinfo; - unsigned int ppid; - int flags = 0; - int rc; - - LOGP(DSUA, LOGL_DEBUG, "sua_cli_read_cb() rx\n"); - - if (!msg) - return -ENOMEM; - - /* read SUA message from socket and process it */ - rc = sctp_recvmsg(ofd->fd, msgb_data(msg), msgb_tailroom(msg), - NULL, NULL, &sinfo, &flags); - if (rc < 0) { - close(ofd->fd); - osmo_fd_unregister(ofd); - ofd->fd = -1; - return rc; - } else if (rc == 0) { - close(ofd->fd); - osmo_fd_unregister(ofd); - ofd->fd = -1; - } else { - msgb_put(msg, rc); - } - - if (flags & MSG_NOTIFICATION) { - union sctp_notification *notif = (union sctp_notification *) msgb_data(msg); - - log_sctp_notification(ofd->fd, "SUA CLNT", notif); - - switch (notif->sn_header.sn_type) { - case SCTP_SHUTDOWN_EVENT: - close(ofd->fd); - osmo_fd_unregister(ofd); - ofd->fd = -1; - break; - default: - break; - } - msgb_free(msg); - return 0; - } - - ppid = ntohl(sinfo.sinfo_ppid); - msgb_sctp_ppid(msg) = ppid; - msgb_sctp_stream(msg) = ntohl(sinfo.sinfo_stream); - msg->dst = link; - - switch (ppid) { - case SUA_PPID: - rc = sua_rx_msg(link, msg); - break; - default: - LOGP(DSUA, LOGL_NOTICE, "SCTP chunk for unknown PPID %u " - "received\n", ppid); - rc = 0; - break; - } - - msgb_free(msg); - return rc; -} - -int osmo_sua_client_connect(struct osmo_sccp_user *user, const char *hostname, uint16_t port) -{ - struct osmo_stream_cli *cli; - struct osmo_sccp_link *sual; - int rc; - - cli = osmo_stream_cli_create(user); - if (!cli) - return -1; - osmo_stream_cli_set_addr(cli, hostname); - osmo_stream_cli_set_port(cli, port); - osmo_stream_cli_set_proto(cli, IPPROTO_SCTP); - osmo_stream_cli_set_reconnect_timeout(cli, 5); - osmo_stream_cli_set_read_cb(cli, sua_cli_read_cb); - - /* create SUA link and associate it with stream_cli */ - sual = sua_link_new(user, 0); - if (!sual) { - osmo_stream_cli_destroy(cli); - return -1; - } - sual->data = cli; - osmo_stream_cli_set_data(cli, sual); - - rc = osmo_stream_cli_open2(cli, 1); - if (rc < 0) { - sua_link_destroy(sual); - osmo_stream_cli_destroy(cli); - return rc; - } - user->client = cli; - - return 0; -} - -struct osmo_sccp_link *osmo_sua_client_get_link(struct osmo_sccp_user *user) -{ - return osmo_stream_cli_get_data(user->client); -} - -static LLIST_HEAD(sua_users); - -struct osmo_sccp_user *osmo_sua_user_create(void *ctx, osmo_prim_cb prim_cb, - void *priv) -{ - struct osmo_sccp_user *user = talloc_zero(ctx, struct osmo_sccp_user); - - user->prim_cb = prim_cb; - user->priv = priv; - INIT_LLIST_HEAD(&user->links); - - llist_add_tail(&user->list, &sua_users); - - return user; -} - -void *osmo_sccp_link_get_user_priv(struct osmo_sccp_link *slink) -{ - return slink->user->priv; -} - -void osmo_sua_user_destroy(struct osmo_sccp_user *user) -{ - struct osmo_sccp_link *link; - - llist_del(&user->list); - - llist_for_each_entry(link, &user->links, list) - sua_link_destroy(link); - - talloc_free(user); -} - -void osmo_sua_set_log_area(int area) -{ - xua_set_log_area(area); - DSUA = area; -} diff --git a/src/xua_internal.h b/src/xua_internal.h index 66b5a26..c6f79b7 100644 --- a/src/xua_internal.h +++ b/src/xua_internal.h @@ -15,6 +15,8 @@ struct xua_msg *osmo_sccp_to_xua(struct msgb *msg); struct msgb *osmo_sua_to_sccp(struct xua_msg *xua); +int sua_rx_msg(struct osmo_ss7_asp *asp, struct msgb *msg); + int sua_tx_xua_as(struct osmo_ss7_as *as, struct xua_msg *xua); struct osmo_mtp_prim *m3ua_to_xfer_ind(struct xua_msg *xua); -- To view, visit https://gerrit.osmocom.org/2218 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I193b74f58aa70c443ae17e78b5604246d6bc3f71 Gerrit-PatchSet: 4 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Apr 4 13:46:31 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 4 Apr 2017 13:46:31 +0000 Subject: [PATCH] libosmo-sccp[master]: Add example program how to use M3UA+SCCP client and server In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2219 to look at the new patch set (#4). Add example program how to use M3UA+SCCP client and server This is an example tool that can be run either as server (SG) or as client (ASP) with a SCCP+M3UA stacking, and communicate via connectionless and connection-oriented primitives over it Change-Id: Id698ce2da5726e304dfa1773b794671dc80d853c --- M .gitignore M Makefile.am M configure.ac A examples/Makefile.am A examples/internal.h A examples/m3ua_example.c A examples/sccp_test_server.c A examples/sccp_test_vty.c 8 files changed, 392 insertions(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/19/2219/4 diff --git a/.gitignore b/.gitignore index 9d1435f..83f1333 100644 --- a/.gitignore +++ b/.gitignore @@ -60,6 +60,7 @@ tests/testsuite tests/testsuite.log +examples/m3ua_example *.pc config.* diff --git a/Makefile.am b/Makefile.am index b1eff56..dd73ec2 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,7 +1,7 @@ AUTOMAKE_OPTIONS = foreign dist-bzip2 1.6 AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -SUBDIRS = include src tests +SUBDIRS = include src tests examples pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = libosmo-sccp.pc libosmo-mtp.pc libosmo-sigtran.pc libosmo-xua.pc diff --git a/configure.ac b/configure.ac index 3644d22..6dc0ebd 100644 --- a/configure.ac +++ b/configure.ac @@ -27,6 +27,7 @@ PKG_PROG_PKG_CONFIG([0.20]) PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 0.3.0) +PKG_CHECK_MODULES(LIBOSMOVTY, libosmovty >= 0.3.0) PKG_CHECK_MODULES(LIBOSMONETIF, libosmo-netif >= 0.0.6) old_LIBS=$LIBS @@ -68,5 +69,6 @@ tests/m2ua/Makefile tests/xua/Makefile tests/ss7/Makefile + examples/Makefile Makefile) diff --git a/examples/Makefile.am b/examples/Makefile.am new file mode 100644 index 0000000..6418aca --- /dev/null +++ b/examples/Makefile.am @@ -0,0 +1,11 @@ +AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include +AM_CFLAGS=-Wall -g $(LIBOSMOCORE_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(LIBOSMONETIF_CFLAGS) $(COVERAGE_FLAGS) +AM_LDFLAGS=$(COVERAGE_LDFLAGS) + +noinst_HEADERS = internal.h + +noinst_PROGRAMS = m3ua_example + +m3ua_example_SOURCES = m3ua_example.c sccp_test_server.c sccp_test_vty.c +m3ua_example_LDADD = $(top_builddir)/src/libosmo-sigtran.la \ + $(LIBOSMOCORE_LIBS) $(LIBOSMOVTY_LIBS) diff --git a/examples/internal.h b/examples/internal.h new file mode 100644 index 0000000..70b9058 --- /dev/null +++ b/examples/internal.h @@ -0,0 +1,12 @@ +#pragma once + +#define SSN_TEST_UNUSED 200 +#define SSN_TEST_REFUSE 201 +#define SSN_TEST_ECHO 202 +#define SSN_TEST_CALLBACK 203 + +struct osmo_sccp_user; + +int sccp_test_user_vty_install(struct osmo_sccp_instance *inst, int ssn); + +int sccp_test_server_init(struct osmo_sccp_instance *sccp); diff --git a/examples/m3ua_example.c b/examples/m3ua_example.c new file mode 100644 index 0000000..d7b1fc2 --- /dev/null +++ b/examples/m3ua_example.c @@ -0,0 +1,98 @@ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "internal.h" + +static struct osmo_sccp_instance *sua_server_helper(void) +{ + struct osmo_sccp_instance *sccp; + + sccp = osmo_sccp_simple_server(NULL, 1, OSMO_SS7_ASP_PROT_M3UA, + -1, "127.0.0.2"); + + osmo_sccp_simple_server_add_clnt(sccp, OSMO_SS7_ASP_PROT_M3UA, + "23", 23, -1, 0, NULL); + + return sccp; +} + +/*********************************************************************** + * Initialization + ***********************************************************************/ + +static const struct log_info_cat log_info_cat[] = { +}; + +static const struct log_info log_info = { + .cat = log_info_cat, + .num_cat = ARRAY_SIZE(log_info_cat), +}; + +static void init_logging(void) +{ + const int log_cats[] = { DLSS7, DLSUA, DLM3UA, DLSCCP, DLINP }; + unsigned int i; + + osmo_init_logging(&log_info); + + for (i = 0; i < ARRAY_SIZE(log_cats); i++) + log_set_category_filter(osmo_stderr_target, log_cats[i], 1, LOGL_DEBUG); +} + +static struct vty_app_info vty_info = { + .name = "sccp-test", + .version = 0, +}; + +int main(int argc, char **argv) +{ + struct osmo_sccp_instance *sccp; + bool client; + int rc; + + init_logging(); + osmo_ss7_init(); + osmo_fsm_log_addr(false); + vty_init(&vty_info); + + if (argc <= 1) + client = true; + else + client = false; + + rc = telnet_init_dynif(NULL, NULL, vty_get_bind_addr(), 2324+client); + if (rc < 0) { + perror("Erro binding VTY port\n"); + exit(1); + } + + + if (client) { + sccp = osmo_sccp_simple_client(NULL, "client", 23, OSMO_SS7_ASP_PROT_M3UA, 0, M3UA_PORT, "127.0.0.2"); + sccp_test_user_vty_install(sccp, OSMO_SCCP_SSN_BSC_BSSAP); + } else { + sccp = sua_server_helper(); + sccp_test_server_init(sccp); + } + + while (1) { + osmo_select_main(0); + } +} diff --git a/examples/sccp_test_server.c b/examples/sccp_test_server.c new file mode 100644 index 0000000..c3c658f --- /dev/null +++ b/examples/sccp_test_server.c @@ -0,0 +1,115 @@ + +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include "internal.h" + +unsigned int conn_id; + +/* a simple SCCP User which refuses all connections and discards all + * unitdata */ +static int refuser_prim_cb(struct osmo_prim_hdr *oph, void *_scu) +{ + struct osmo_sccp_user *scu = _scu; + struct osmo_scu_prim *scu_prim = (struct osmo_scu_prim *) oph; + + switch (OSMO_PRIM_HDR(&scu_prim->oph)) { + case OSMO_PRIM(OSMO_SCU_PRIM_N_CONNECT, PRIM_OP_INDICATION): + printf("%s: refusing N-CONNECT.ind (local_ref=%u)\n", + __func__, scu_prim->u.connect.conn_id); + osmo_sccp_tx_disconn(scu, scu_prim->u.connect.conn_id, + &scu_prim->u.connect.called_addr, + 23); + break; + default: + printf("%s: Unknown primitive %u:%u\n", __func__, + oph->primitive, oph->operation); + break; + } + return 0; +} + +/* a simple SCCP User which accepts all connections and echos back all + * DATA + UNITDATA */ +static int echo_prim_cb(struct osmo_prim_hdr *oph, void *_scu) +{ + struct osmo_sccp_user *scu = _scu; + struct osmo_scu_prim *scu_prim = (struct osmo_scu_prim *) oph; + const uint8_t *data = msgb_l2(oph->msg); + unsigned int data_len = msgb_l2len(oph->msg); + + switch (OSMO_PRIM_HDR(&scu_prim->oph)) { + case OSMO_PRIM(OSMO_SCU_PRIM_N_CONNECT, PRIM_OP_INDICATION): + printf("%s: Accepting N-CONNECT.ind (local_ref=%u)\n", + __func__, scu_prim->u.connect.conn_id); + osmo_sccp_tx_conn_resp(scu, scu_prim->u.connect.conn_id, + &scu_prim->u.connect.called_addr, + data, data_len); + break; + case OSMO_PRIM(OSMO_SCU_PRIM_N_DATA, PRIM_OP_INDICATION): + printf("%s: Echoing N-DATA.ind (local_ref=%u)\n", + __func__, scu_prim->u.data.conn_id); + osmo_sccp_tx_data(scu, scu_prim->u.data.conn_id, + data, data_len); + break; + case OSMO_PRIM(OSMO_SCU_PRIM_N_UNITDATA, PRIM_OP_INDICATION): + printf("%s: Echoing N-UNITDATA.ind\n", __func__); + osmo_sccp_tx_unitdata(scu, &scu_prim->u.unitdata.called_addr, + &scu_prim->u.unitdata.calling_addr, + data, data_len); + break; + default: + printf("%s: Unknown primitive %u:%u\n", __func__, + oph->primitive, oph->operation); + break; + } + return 0; +} + +/* a simple SCCP User which receives UNITDATA messages and connects back + * to whoever sents UNITDATA and then echo's back all DATA */ +static int callback_prim_cb(struct osmo_prim_hdr *oph, void *_scu) +{ + struct osmo_sccp_user *scu = _scu; + struct osmo_scu_prim *scu_prim = (struct osmo_scu_prim *) oph; + const uint8_t *data = msgb_l2(oph->msg); + unsigned int data_len = msgb_l2len(oph->msg); + + switch (OSMO_PRIM_HDR(&scu_prim->oph)) { + case OSMO_PRIM(OSMO_SCU_PRIM_N_UNITDATA, PRIM_OP_INDICATION): + printf("%s: N-UNITDATA.ind: Connectiong back to sender\n", __func__); + osmo_sccp_tx_conn_req(scu, conn_id++, + &scu_prim->u.unitdata.called_addr, + &scu_prim->u.unitdata.calling_addr, + data, data_len); + break; + case OSMO_PRIM(OSMO_SCU_PRIM_N_DATA, PRIM_OP_INDICATION): + printf("%s: Echoing N-DATA.ind (local_ref=%u)\n", + __func__, scu_prim->u.data.conn_id); + osmo_sccp_tx_data(scu, scu_prim->u.data.conn_id, + data, data_len); + break; + default: + printf("%s: Unknown primitive %u:%u\n", __func__, + oph->primitive, oph->operation); + break; + } + return 0; +} + +int sccp_test_server_init(struct osmo_sccp_instance *sccp) +{ + osmo_sccp_user_bind(sccp, "refuser", &refuser_prim_cb, SSN_TEST_REFUSE); + osmo_sccp_user_bind(sccp, "echo", &echo_prim_cb, SSN_TEST_ECHO); + osmo_sccp_user_bind(sccp, "callback", &callback_prim_cb, SSN_TEST_CALLBACK); + + return 0; +} diff --git a/examples/sccp_test_vty.c b/examples/sccp_test_vty.c new file mode 100644 index 0000000..1134d57 --- /dev/null +++ b/examples/sccp_test_vty.c @@ -0,0 +1,152 @@ + +#include + +#include +#include + +#include +#include + +#include "internal.h" + +#define SCU_NODE 23 + +static struct osmo_sccp_user *g_scu; + +static struct osmo_sccp_addr g_calling_addr = { + .presence = OSMO_SCCP_ADDR_T_SSN | OSMO_SCCP_ADDR_T_PC, + .ri = OSMO_SCCP_RI_SSN_PC, + .pc = 23, +}; + +static struct osmo_sccp_addr g_called_addr = { + .presence = OSMO_SCCP_ADDR_T_SSN | OSMO_SCCP_ADDR_T_PC, + .ssn = 1, + .ri = OSMO_SCCP_RI_SSN_PC, + .pc = 1, +}; + +DEFUN(scu_called_ssn, scu_called_ssn_cmd, + "called-addr-ssn <0-255>", + "Set SSN of SCCP CalledAddress\n" + "SSN of SCCP CalledAddress\n") +{ + g_called_addr.ssn = atoi(argv[0]); + return CMD_SUCCESS; +} + +DEFUN(scu_conn_req, scu_conn_req_cmd, + "connect-req <0-16777216> [DATA]", + "N-CONNECT.req\n" + "Connection ID\n") +{ + struct osmo_sccp_user *scu = vty->index; + int conn_id = atoi(argv[0]); + const char *data = argv[1]; + + osmo_sccp_tx_conn_req(scu, conn_id, &g_calling_addr, &g_called_addr, + (const uint8_t *)data, data ? strlen(data)+1 : 0); + return CMD_SUCCESS; +} + +DEFUN(scu_conn_resp, scu_conn_resp_cmd, + "connect-resp <0-16777216> [DATA]", + "N-CONNET.resp\n" + "Connection ID\n") +{ + struct osmo_sccp_user *scu = vty->index; + int conn_id = atoi(argv[0]); + const char *data = argv[1]; + + osmo_sccp_tx_conn_resp(scu, conn_id, NULL, + (const uint8_t *)data, data ? strlen(data)+1 : 0); + return CMD_SUCCESS; +} + +DEFUN(scu_data_req, scu_data_req_cmd, + "data-req <0-16777216> DATA", + "N-DATA.req\n" + "Connection ID\n") +{ + struct osmo_sccp_user *scu = vty->index; + int conn_id = atoi(argv[0]); + const char *data = argv[1]; + + osmo_sccp_tx_data(scu, conn_id, (const uint8_t *)data, strlen(data)+1); + return CMD_SUCCESS; +} + +DEFUN(scu_unitdata_req, scu_unitdata_req_cmd, + "unitdata-req DATA", + "N-UNITDATA.req\n") +{ + struct osmo_sccp_user *scu = vty->index; + const char *data = argv[0]; + + osmo_sccp_tx_unitdata(scu, &g_calling_addr, &g_called_addr, + (const uint8_t *)data, strlen(data)+1); + return CMD_SUCCESS; +} + +DEFUN(scu_disc_req, scu_disc_req_cmd, + "disconnect-req <0-16777216>", + "N-DISCONNT.req\n" + "Connection ID\n") +{ + struct osmo_sccp_user *scu = vty->index; + int conn_id = atoi(argv[0]); + + osmo_sccp_tx_disconn(scu, conn_id, NULL, 42); + return CMD_SUCCESS; +} + +static struct cmd_node scu_node = { + SCU_NODE, + "%s(sccp-user)# ", + 1, +}; + +DEFUN(scu, scu_cmd, + "sccp-user", + "Enter SCCP User Node\n") +{ + vty->node = SCU_NODE; + vty->index = g_scu; + return CMD_SUCCESS; +} + +static int testclnt_prim_cb(struct osmo_prim_hdr *oph, void *_scu) +{ + struct osmo_sccp_user *scu = _scu; + struct osmo_scu_prim *scu_prim = (struct osmo_scu_prim *) oph; + + switch (OSMO_PRIM_HDR(&scu_prim->oph)) { + case OSMO_PRIM(OSMO_SCU_PRIM_N_CONNECT, PRIM_OP_INDICATION): + default: + break; + } + return 0; +} + + +int sccp_test_user_vty_install(struct osmo_sccp_instance *inst, int ssn) +{ + g_scu = osmo_sccp_user_bind(inst, "test_client_vty", testclnt_prim_cb, ssn); + if (!g_scu) + return -1; + + g_calling_addr.ssn = ssn; + + install_node(&scu_node, NULL); + vty_install_default(SCU_NODE); + install_element(SCU_NODE, &scu_called_ssn_cmd); + install_element(SCU_NODE, &scu_conn_req_cmd); + install_element(SCU_NODE, &scu_conn_resp_cmd); + install_element(SCU_NODE, &scu_data_req_cmd); + install_element(SCU_NODE, &scu_unitdata_req_cmd); + install_element(SCU_NODE, &scu_disc_req_cmd); + + install_element(ENABLE_NODE, &scu_cmd); + + return 0; +} -- To view, visit https://gerrit.osmocom.org/2219 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Id698ce2da5726e304dfa1773b794671dc80d853c Gerrit-PatchSet: 4 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Apr 4 13:46:31 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 4 Apr 2017 13:46:31 +0000 Subject: [PATCH] libosmo-sccp[master]: xua: Remove library-internal DXUA log subsystem In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2220 to look at the new patch set (#4). xua: Remove library-internal DXUA log subsystem We don't really need those thre log messages, and we can thus do away with the library-internal log-subsystem of DXUA. The rest of libosmo-sigtran uses the new globa DL... subsystems anyway Change-Id: Iea0d3db34a3674a9c6422b174a879bfdaa25786f --- M include/osmocom/sigtran/xua_msg.h M src/xua_msg.c 2 files changed, 2 insertions(+), 18 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/20/2220/4 diff --git a/include/osmocom/sigtran/xua_msg.h b/include/osmocom/sigtran/xua_msg.h index 320da6a..e0e1bcf 100644 --- a/include/osmocom/sigtran/xua_msg.h +++ b/include/osmocom/sigtran/xua_msg.h @@ -69,8 +69,6 @@ extern const struct xua_dialect xua_dialect_sua; extern const struct xua_dialect xua_dialect_m3ua; -extern int DXUA; - struct xua_msg *xua_msg_alloc(void); void xua_msg_free(struct xua_msg *msg); @@ -83,8 +81,6 @@ struct xua_msg *xua_from_msg(const int version, uint16_t len, uint8_t *data); struct msgb *xua_to_msg(const int version, struct xua_msg *msg); - -void xua_set_log_area(int log_area); int msgb_t16l16vp_put(struct msgb *msg, uint16_t tag, uint16_t len, const uint8_t *data); int msgb_t16l16vp_put_u32(struct msgb *msg, uint16_t tag, uint32_t val); diff --git a/src/xua_msg.c b/src/xua_msg.c index 27279ce..cb487c8 100644 --- a/src/xua_msg.c +++ b/src/xua_msg.c @@ -32,17 +32,14 @@ #include static void *tall_xua; -int DXUA = -1; struct xua_msg *xua_msg_alloc(void) { struct xua_msg *msg; msg = talloc_zero(tall_xua, struct xua_msg); - if (!msg) { - LOGP(DXUA, LOGL_ERROR, "Failed to allocate.\n"); + if (!msg) return NULL; - } INIT_LLIST_HEAD(&msg->headers); return msg; @@ -162,7 +159,6 @@ return msg; fail: - LOGP(DXUA, LOGL_ERROR, "Failed to parse.\n"); xua_msg_free(msg); return NULL; } @@ -175,10 +171,8 @@ uint8_t rest; msg = msgb_alloc_headroom(2048, 512, "xua msg"); - if (!msg) { - LOGP(DXUA, LOGL_ERROR, "Failed to allocate.\n"); + if (!msg) return NULL; - } msg->l2h = msgb_put(msg, sizeof(*hdr)); hdr = (struct xua_common_hdr *) msg->l2h; @@ -208,12 +202,6 @@ hdr->msg_length = htonl(msgb_l2len(msg)); return msg; } - -void xua_set_log_area(int log_area) -{ - DXUA = log_area; -} - /*********************************************************************** * Message encoding helper functions -- To view, visit https://gerrit.osmocom.org/2220 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Iea0d3db34a3674a9c6422b174a879bfdaa25786f Gerrit-PatchSet: 4 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Apr 4 13:47:13 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 4 Apr 2017 13:47:13 +0000 Subject: libosmo-sccp[master]: sua: Make use of xua_msg_dialect In-Reply-To: References: Message-ID: Patch Set 3: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2210 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I966103f30b9be247ba6905ba8e06b87654d9981a Gerrit-PatchSet: 3 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Apr 4 13:47:27 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 4 Apr 2017 13:47:27 +0000 Subject: libosmo-sccp[master]: sua: Extend address parsing with GT, RI and IPv4 support In-Reply-To: References: Message-ID: Patch Set 3: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2211 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I186df77cbdbedfe1a60b855be3626b6766f4681c Gerrit-PatchSet: 3 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Apr 4 14:13:53 2017 From: gerrit-no-reply at lists.osmocom.org (Pau Espin Pedrol) Date: Tue, 4 Apr 2017 14:13:53 +0000 Subject: [PATCH] osmo-gsm-manuals[master]: gb.adoc: Add info to NS-over-UDP example Message-ID: Review at https://gerrit.osmocom.org/2223 gb.adoc: Add info to NS-over-UDP example Change-Id: I5b6d2fb284336614da28e0d1b01c7e8c26725f81 --- M common/chapters/gb.adoc 1 file changed, 3 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-gsm-manuals refs/changes/23/2223/1 diff --git a/common/chapters/gb.adoc b/common/chapters/gb.adoc index 199ef2c..6a6f65c 100644 --- a/common/chapters/gb.adoc +++ b/common/chapters/gb.adoc @@ -20,6 +20,9 @@ OsmoSGSN(config-ns)# encapsulation udp local-ip 127.0.0.1 <1> OsmoSGSN(config-ns)# encapsulation udp local-port 23000 <2> ---- +The example above configures a libosmogb based application to listen for +incoming connections from PCUs on the specified address and port. + <1> Set the local side IP address for NS-over-UDP <2> Set the local side UDP port number for NS-over-UDP. 23000 is the default -- To view, visit https://gerrit.osmocom.org/2223 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I5b6d2fb284336614da28e0d1b01c7e8c26725f81 Gerrit-PatchSet: 1 Gerrit-Project: osmo-gsm-manuals Gerrit-Branch: master Gerrit-Owner: Pau Espin Pedrol From gerrit-no-reply at lists.osmocom.org Tue Apr 4 14:14:20 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Tue, 4 Apr 2017 14:14:20 +0000 Subject: [PATCH] libosmocore[master]: Add SW Description (de)marshalling In-Reply-To: References: Message-ID: Hello Neels Hofmeyr, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2165 to look at the new patch set (#8). Add SW Description (de)marshalling * data structure representing 3GPP TS 52.021 ?9.4.62 SW Description * function to serialize it into msgb * function to deserialize it from buffer * function to estimate buffer size * test harness There are several similar functions to deal with SW Description in OpenBSC, there's also need to use similar functionality in OsmoBTS. Hence it's better to put the code into common library with proper tests and documentation. Change-Id: Ib63b6b5e83b8914864fc7edd789f8958cdc993cd Related: OS#1614 --- M include/osmocom/gsm/protocol/gsm_12_21.h M src/gsm/abis_nm.c M src/gsm/libosmogsm.map M tests/Makefile.am M tests/lapd/lapd_test.c M tests/lapd/lapd_test.ok 6 files changed, 254 insertions(+), 2 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/65/2165/8 diff --git a/include/osmocom/gsm/protocol/gsm_12_21.h b/include/osmocom/gsm/protocol/gsm_12_21.h index c88f0b1..aa74382 100644 --- a/include/osmocom/gsm/protocol/gsm_12_21.h +++ b/include/osmocom/gsm/protocol/gsm_12_21.h @@ -29,6 +29,7 @@ /*! \file gsm_12_21.h */ #include +#include #include /*! \brief generic header in front of every OML message according to TS 08.59 */ @@ -791,6 +792,23 @@ IPAC_BINF_CELL_ALLOC = (1 << 2), }; +/*! \brief 3GPP TS 52.021 ?9.4.62 SW Description */ +struct abis_nm_sw_descr { + uint8_t file_id[UINT8_MAX]; + uint8_t file_id_len; + + uint8_t file_version[UINT8_MAX]; + uint8_t file_version_len; +}; + +uint16_t abis_nm_sw_descr_len(const struct abis_nm_sw_descr *sw, + bool put_sw_descr); +uint16_t abis_nm_put_sw_descr(struct msgb *msg, const struct abis_nm_sw_descr *sw, + bool put_sw_descr); +uint32_t abis_nm_get_sw_descr_len(const uint8_t * buf, size_t len); +int abis_nm_get_sw_descr_one(struct abis_nm_sw_descr *sw, const uint8_t * buf, + size_t len); + struct msgb *abis_nm_fail_evt_rep(enum abis_nm_event_type t, enum abis_nm_severity s, enum abis_nm_pcause_type ct, diff --git a/src/gsm/abis_nm.c b/src/gsm/abis_nm.c index 934d7ce..a3153a8 100644 --- a/src/gsm/abis_nm.c +++ b/src/gsm/abis_nm.c @@ -751,6 +751,117 @@ return nmsg; } +/*! \brief Compute length of given 3GPP TS 52.021 ?9.4.62 SW Description. + * \param[in] sw SW Description struct + * \param[in] put_sw_descr boolean, whether to put NM_ATT_SW_DESCR IE or not + * \returns length of buffer space necessary to store sw + */ +uint16_t abis_nm_sw_descr_len(const struct abis_nm_sw_descr *sw, + bool put_sw_descr) +{ + /* +3: type is 1-byte, length is 2-byte */ + return (put_sw_descr ? 1 : 0) + (sw->file_id_len + 3) + + (sw->file_version_len + 3); +} + +/*! \brief Put given 3GPP TS 52.021 ?9.4.62 SW Description into msgb. + * \param[out] msg message buffer + * \param[in] sw SW Description struct + * \param[in] put_sw_descr boolean, whether to put NM_ATT_SW_DESCR IE or not + * \param[in] simulate boolean, whether to actually modify msg or not + * \returns length of buffer space necessary to store sw + */ +uint16_t abis_nm_put_sw_descr(struct msgb *msg, const struct abis_nm_sw_descr *sw, + bool put_sw_descr) +{ + if (put_sw_descr) + msgb_v_put(msg, NM_ATT_SW_DESCR); + msgb_tl16v_put(msg, NM_ATT_FILE_ID, sw->file_id_len, sw->file_id); + msgb_tl16v_put(msg, NM_ATT_FILE_VERSION, sw->file_version_len, + sw->file_version); + + return abis_nm_sw_descr_len(sw, put_sw_descr); +} + +/*! \brief Get length of first 3GPP TS 52.021 ?9.4.62 SW Description from buffer. + * \param[in] buf buffer, may contain several SW Descriptions + * \param[in] len buffer length + * \returns length if parsing succeeded, 0 otherwise + */ +uint32_t abis_nm_get_sw_descr_len(const uint8_t *buf, size_t len) +{ + uint16_t sw = 2; /* 1-byte SW tag + 1-byte FILE_* tag */ + + if (buf[0] != NM_ATT_SW_DESCR) + sw = 1; /* 1-byte FILE_* tag */ + + if (buf[sw - 1] != NM_ATT_FILE_ID && buf[sw - 1] != NM_ATT_FILE_VERSION) + return 0; + + /* + length of 1st FILE_* element + 1-byte tag + 2-byte length field of + 1st FILE_* element */ + sw += (osmo_load16be(buf + sw) + 3); + + /* + length of 2nd FILE_* element */ + sw += osmo_load16be(buf + sw); + + return sw + 2; /* + 2-byte length field of 2nd FILE_* element */ +} + +/*! \brief Parse single 3GPP TS 52.021 ?9.4.62 SW Description from buffer. + * \param[out] sw SW Description struct + * \param[in] buf buffer + * \param[in] len buffer length + * \returns 0 if parsing succeeded, negative error code otherwise + */ +int abis_nm_get_sw_descr_one(struct abis_nm_sw_descr *sw, const uint8_t *buf, + size_t length) +{ + int rc; + size_t len = abis_nm_get_sw_descr_len(buf, length); + static struct tlv_parsed tp; + const struct tlv_definition sw_tlvdef = { + .def = { + [NM_ATT_SW_DESCR] = { TLV_TYPE_TV }, + [NM_ATT_FILE_ID] = { TLV_TYPE_TL16V }, + [NM_ATT_FILE_VERSION] = { TLV_TYPE_TL16V }, + }, + }; + + /* current implementation of TLV parser fails on multilpe SW Descr: + we will only parse the first one */ + if (!len) + return -EINVAL; + + /* Note: the return value is ignored here because SW Description tag + itself is considered optional. */ + tlv_parse(&tp, &sw_tlvdef, buf, len, 0, 0); + + /* Parsing SW Description is tricky for current implementation of TLV + parser which fails to properly handle TV when V has following + structure: | TL16V | TL16V |. Hence, the need for 2nd call: */ + rc = tlv_parse(&tp, &sw_tlvdef, buf + TLVP_LEN(&tp, NM_ATT_SW_DESCR), + len - TLVP_LEN(&tp, NM_ATT_SW_DESCR), 0, 0); + + if (rc < 0) + return rc; + + if (!TLVP_PRESENT(&tp, NM_ATT_FILE_ID)) + return -EBADF; + + if (!TLVP_PRESENT(&tp, NM_ATT_FILE_VERSION)) + return -EBADMSG; + + sw->file_id_len = TLVP_LEN(&tp, NM_ATT_FILE_ID); + sw->file_version_len = TLVP_LEN(&tp, NM_ATT_FILE_VERSION); + + memcpy(sw->file_id, TLVP_VAL(&tp, NM_ATT_FILE_ID), sw->file_id_len); + memcpy(sw->file_version, TLVP_VAL(&tp, NM_ATT_FILE_VERSION), + sw->file_version_len); + + return 0; +} + /*! \brief Obtain OML Channel Combination for phnsical channel config */ int abis_nm_chcomb4pchan(enum gsm_phys_chan_config pchan) { diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map index 5649e71..e6d4a15 100644 --- a/src/gsm/libosmogsm.map +++ b/src/gsm/libosmogsm.map @@ -31,6 +31,10 @@ abis_nm_pcause_type_names; abis_nm_msgtype_names; abis_nm_att_names; +abis_nm_sw_descr_len; +abis_nm_put_sw_descr; +abis_nm_get_sw_descr_one; +abis_nm_get_sw_descr_len; osmo_sitype_strs; osmo_c4; diff --git a/tests/Makefile.am b/tests/Makefile.am index 352b5a7..16b45ea 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -74,7 +74,7 @@ lapd_lapd_test_LDADD = $(top_builddir)/src/libosmocore.la $(top_builddir)/src/gsm/libosmogsm.la msgb_msgb_test_SOURCES = msgb/msgb_test.c -msgb_msgb_test_LDADD = $(top_builddir)/src/libosmocore.la +msgb_msgb_test_LDADD = $(top_builddir)/src/libosmocore.la $(top_builddir)/src/gsm/libosmogsm.la msgfile_msgfile_test_SOURCES = msgfile/msgfile_test.c msgfile_msgfile_test_LDADD = $(top_builddir)/src/libosmocore.la diff --git a/tests/lapd/lapd_test.c b/tests/lapd/lapd_test.c index e322314..79a5323 100644 --- a/tests/lapd/lapd_test.c +++ b/tests/lapd/lapd_test.c @@ -25,9 +25,10 @@ #include #include #include +#include #include - +#include #include #define CHECK_RC(rc) \ @@ -752,6 +753,94 @@ lapdm_channel_exit(&bts_to_ms_channel); } +static inline void print_chk(const char *what, uint8_t len1, uint8_t len2, + const uint8_t *x1, const uint8_t *x2) +{ + int cmp = memcmp(x1, x2, len2); + printf("\tFILE %s [%u == %u -> %d, %s] %d => %s\n", what, len1, len2, + len1 == len2, len1 != len2 ? "fail" : "ok", + cmp, cmp != 0 ? "FAIL" : "OK"); +} + +static inline void chk_descr(struct msgb *msg, struct abis_nm_sw_descr *put, + const char *descr, bool header) +{ + int res; + struct abis_nm_sw_descr sw = { 0 }; + uint16_t len = abis_nm_put_sw_descr(msg, put, header); + + printf("msgb[%u] :: {msgb->len} %u == %u {len} - %s]:\n\t" + "SW DESCR (%s)\n\t" + "length: {extracted} %u = %u {expected} - %s, failsafe - %s\n", + msg->data_len, msg->len, len, len != msg->len ? "fail" : "ok", + descr, abis_nm_get_sw_descr_len(msgb_data(msg), msg->len), + msg->len, + abis_nm_get_sw_descr_len(msgb_data(msg), msg->len) != msg->len ? "FAIL" : "OK", + len > put->file_version_len + put->file_id_len ? "OK" : "FAIL"); + + res = abis_nm_get_sw_descr_one(&sw, msgb_data(msg), msg->len); + if (res < 0) + printf("\tSW DESCR (%s) parsing error code %d!\n", descr, -res); + else { + print_chk("ID", sw.file_id_len, put->file_id_len, sw.file_id, + put->file_id); + print_chk("VERSION", sw.file_version_len, + put->file_version_len, sw.file_version, + put->file_version); + } +} + +static inline void chk_raw(const char *what, const uint8_t *data, uint16_t len) +{ + struct abis_nm_sw_descr sw = { 0 }; + int res = abis_nm_get_sw_descr_one(&sw, data, len); + uint16_t xlen = abis_nm_get_sw_descr_len(data, len); + + printf("parsing chained %s <1st: %d, total: %d>\n\tSW Descr (%s)\n", + osmo_hexdump(data, len), xlen, len, what); + + if (res < 0) + printf("\tFAIL: %d\n", -res); + else { + printf("\tFILE ID: [%d] %s => OK\n", sw.file_id_len, + osmo_hexdump(sw.file_id, sw.file_id_len)); + printf("\tFILE VERSION: [%d] %s => OK\n", sw.file_version_len, + osmo_hexdump(sw.file_version, sw.file_version_len)); + } + + if (len != xlen) + chk_raw(" 2nd", data + xlen, len - xlen); +} + +static void test_sw_descr() +{ + const char *f_id = "TEST.L0L", *f_ver = "0.1.666~deadbeeffacefeed-dirty"; + uint8_t lf_id = strlen(f_id), lf_ver = strlen(f_ver); + uint8_t chain[] = { 0x42, 0x12, 0x00, 0x03, 0x01, 0x02, 0x03, 0x13, 0x00, 0x03, 0x03, 0x04, 0x05, 0x42, 0x12, 0x00, 0x03, 0x09, 0x07, 0x05, 0x13, 0x00, 0x03, 0x06, 0x07, 0x08 }; + struct msgb *msg = msgb_alloc_headroom(4096, 128, "sw"); + struct abis_nm_sw_descr sw_put = { + .file_id_len = lf_id, + .file_version_len = lf_ver, + }; + + printf("\nI test SW Description (de)serialization:\n"); + + memcpy(sw_put.file_id, f_id, lf_id); + memcpy(sw_put.file_version, f_ver, lf_ver); + + /* check that parsing |SW|ID|VER| works: */ + chk_descr(msg, &sw_put, "with header", true); + msgb_reset(msg); + /* check that parsing |ID|VER| works: */ + chk_descr(msg, &sw_put, "without header", false); + /* check that parsing |ID|VER|SW|ID|VER| fails - notice the lack of + msgb_reset() to create bogus msgb data: */ + chk_descr(msg, &sw_put, "expected failure", true); + /* check multiple, chained SW-descr: */ + chk_raw("half", chain, sizeof(chain) / 2); + chk_raw("full", chain, sizeof(chain)); +} + int main(int argc, char **argv) { osmo_init_logging(&info); @@ -765,6 +854,7 @@ test_lapdm_contention_resolution(); test_lapdm_establishment(); test_lapdm_desync(); + test_sw_descr(); printf("Success.\n"); diff --git a/tests/lapd/lapd_test.ok b/tests/lapd/lapd_test.ok index e188e27..682b397 100644 --- a/tests/lapd/lapd_test.ok +++ b/tests/lapd/lapd_test.ok @@ -96,4 +96,33 @@ Took message from DCCH queue: L2 header size 23, L3 size 0, SAP 0x1000000, 0/0, Link 0x03 Message: [L2]> 0d 21 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b + +I test SW Description (de)serialization: +msgb[4096] :: {msgb->len} 45 == 45 {len} - ok]: + SW DESCR (with header) + length: {extracted} 45 = 45 {expected} - OK, failsafe - OK + FILE ID [8 == 8 -> 1, ok] 0 => OK + FILE VERSION [30 == 30 -> 1, ok] 0 => OK +msgb[4096] :: {msgb->len} 44 == 44 {len} - ok]: + SW DESCR (without header) + length: {extracted} 44 = 44 {expected} - OK, failsafe - OK + FILE ID [8 == 8 -> 1, ok] 0 => OK + FILE VERSION [30 == 30 -> 1, ok] 0 => OK +msgb[4096] :: {msgb->len} 89 == 45 {len} - fail]: + SW DESCR (expected failure) + length: {extracted} 44 = 89 {expected} - FAIL, failsafe - OK + FILE ID [8 == 8 -> 1, ok] 0 => OK + FILE VERSION [30 == 30 -> 1, ok] 0 => OK +parsing chained 42 12 00 03 01 02 03 13 00 03 03 04 05 <1st: 13, total: 13> + SW Descr (half) + FILE ID: [3] 01 02 03 => OK + FILE VERSION: [3] 03 04 05 => OK +parsing chained 42 12 00 03 01 02 03 13 00 03 03 04 05 42 12 00 03 09 07 05 13 00 03 06 07 08 <1st: 13, total: 26> + SW Descr (full) + FILE ID: [3] 01 02 03 => OK + FILE VERSION: [3] 03 04 05 => OK +parsing chained 42 12 00 03 09 07 05 13 00 03 06 07 08 <1st: 13, total: 13> + SW Descr ( 2nd) + FILE ID: [3] 09 07 05 => OK + FILE VERSION: [3] 06 07 08 => OK Success. -- To view, visit https://gerrit.osmocom.org/2165 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ib63b6b5e83b8914864fc7edd789f8958cdc993cd Gerrit-PatchSet: 8 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Tue Apr 4 14:38:36 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Tue, 4 Apr 2017 14:38:36 +0000 Subject: [PATCH] libosmocore[master]: Add SW Description (de)marshalling In-Reply-To: References: Message-ID: Hello Neels Hofmeyr, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2165 to look at the new patch set (#9). Add SW Description (de)marshalling * data structure representing 3GPP TS 52.021 ?9.4.62 SW Description * function to serialize it into msgb * function to deserialize it from buffer * function to estimate buffer size * test harness There are several similar functions to deal with SW Description in OpenBSC, there's also need to use similar functionality in OsmoBTS. Hence it's better to put the code into common library with proper tests and documentation. Change-Id: Ib63b6b5e83b8914864fc7edd789f8958cdc993cd Related: OS#1614 --- M include/osmocom/gsm/protocol/gsm_12_21.h M src/gsm/abis_nm.c M src/gsm/libosmogsm.map M tests/Makefile.am M tests/lapd/lapd_test.c M tests/lapd/lapd_test.ok 6 files changed, 258 insertions(+), 2 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/65/2165/9 diff --git a/include/osmocom/gsm/protocol/gsm_12_21.h b/include/osmocom/gsm/protocol/gsm_12_21.h index c88f0b1..aa74382 100644 --- a/include/osmocom/gsm/protocol/gsm_12_21.h +++ b/include/osmocom/gsm/protocol/gsm_12_21.h @@ -29,6 +29,7 @@ /*! \file gsm_12_21.h */ #include +#include #include /*! \brief generic header in front of every OML message according to TS 08.59 */ @@ -791,6 +792,23 @@ IPAC_BINF_CELL_ALLOC = (1 << 2), }; +/*! \brief 3GPP TS 52.021 ?9.4.62 SW Description */ +struct abis_nm_sw_descr { + uint8_t file_id[UINT8_MAX]; + uint8_t file_id_len; + + uint8_t file_version[UINT8_MAX]; + uint8_t file_version_len; +}; + +uint16_t abis_nm_sw_descr_len(const struct abis_nm_sw_descr *sw, + bool put_sw_descr); +uint16_t abis_nm_put_sw_descr(struct msgb *msg, const struct abis_nm_sw_descr *sw, + bool put_sw_descr); +uint32_t abis_nm_get_sw_descr_len(const uint8_t * buf, size_t len); +int abis_nm_get_sw_descr_one(struct abis_nm_sw_descr *sw, const uint8_t * buf, + size_t len); + struct msgb *abis_nm_fail_evt_rep(enum abis_nm_event_type t, enum abis_nm_severity s, enum abis_nm_pcause_type ct, diff --git a/src/gsm/abis_nm.c b/src/gsm/abis_nm.c index 934d7ce..98708a4 100644 --- a/src/gsm/abis_nm.c +++ b/src/gsm/abis_nm.c @@ -751,6 +751,121 @@ return nmsg; } +/*! \brief Compute length of given 3GPP TS 52.021 ?9.4.62 SW Description. + * \param[in] sw SW Description struct + * \param[in] put_sw_descr boolean, whether to put NM_ATT_SW_DESCR IE or not + * \returns length of buffer space necessary to store sw + */ +uint16_t abis_nm_sw_descr_len(const struct abis_nm_sw_descr *sw, + bool put_sw_descr) +{ + /* +3: type is 1-byte, length is 2-byte */ + return (put_sw_descr ? 1 : 0) + (sw->file_id_len + 3) + + (sw->file_version_len + 3); +} + +/*! \brief Put given 3GPP TS 52.021 ?9.4.62 SW Description into msgb. + * \param[out] msg message buffer + * \param[in] sw SW Description struct + * \param[in] put_sw_descr boolean, whether to put NM_ATT_SW_DESCR IE or not + * \param[in] simulate boolean, whether to actually modify msg or not + * \returns length of buffer space necessary to store sw + */ +uint16_t abis_nm_put_sw_descr(struct msgb *msg, const struct abis_nm_sw_descr *sw, + bool put_sw_descr) +{ + if (put_sw_descr) + msgb_v_put(msg, NM_ATT_SW_DESCR); + msgb_tl16v_put(msg, NM_ATT_FILE_ID, sw->file_id_len, sw->file_id); + msgb_tl16v_put(msg, NM_ATT_FILE_VERSION, sw->file_version_len, + sw->file_version); + + return abis_nm_sw_descr_len(sw, put_sw_descr); +} + +/*! \brief Get length of first 3GPP TS 52.021 ?9.4.62 SW Description from buffer. + * \param[in] buf buffer, may contain several SW Descriptions + * \param[in] len buffer length + * \returns length if parsing succeeded, 0 otherwise + */ +uint32_t abis_nm_get_sw_descr_len(const uint8_t *buf, size_t len) +{ + uint16_t sw = 2; /* 1-byte SW tag + 1-byte FILE_* tag */ + + if (buf[0] != NM_ATT_SW_DESCR) + sw = 1; /* 1-byte FILE_* tag */ + + if (buf[sw - 1] != NM_ATT_FILE_ID && buf[sw - 1] != NM_ATT_FILE_VERSION) + return 0; + + /* + length of 1st FILE_* element + 1-byte tag + 2-byte length field of + 1st FILE_* element */ + sw += (osmo_load16be(buf + sw) + 3); + + /* + length of 2nd FILE_* element */ + sw += osmo_load16be(buf + sw); + + return sw + 2; /* + 2-byte length field of 2nd FILE_* element */ +} + +/*! \brief Parse single 3GPP TS 52.021 ?9.4.62 SW Description from buffer. + * \param[out] sw SW Description struct + * \param[in] buf buffer + * \param[in] len buffer length + * \returns 0 if parsing succeeded, negative error code otherwise + */ +int abis_nm_get_sw_descr_one(struct abis_nm_sw_descr *sw, const uint8_t *buf, + size_t length) +{ + int rc; + uint32_t len = abis_nm_get_sw_descr_len(buf, length); + static struct tlv_parsed tp; + const struct tlv_definition sw_tlvdef = { + .def = { + [NM_ATT_SW_DESCR] = { TLV_TYPE_TV }, + [NM_ATT_FILE_ID] = { TLV_TYPE_TL16V }, + [NM_ATT_FILE_VERSION] = { TLV_TYPE_TL16V }, + }, + }; + + /* Basic sanity check */ + if (len > length) + return -EFBIG; + + /* Note: current implementation of TLV parser fails on multilpe SW Descr: + we will only parse the first one */ + if (!len) + return -EINVAL; + + /* Note: the return value is ignored here because SW Description tag + itself is considered optional. */ + tlv_parse(&tp, &sw_tlvdef, buf, len, 0, 0); + + /* Parsing SW Description is tricky for current implementation of TLV + parser which fails to properly handle TV when V has following + structure: | TL16V | TL16V |. Hence, the need for 2nd call: */ + rc = tlv_parse(&tp, &sw_tlvdef, buf + TLVP_LEN(&tp, NM_ATT_SW_DESCR), + len - TLVP_LEN(&tp, NM_ATT_SW_DESCR), 0, 0); + + if (rc < 0) + return rc; + + if (!TLVP_PRESENT(&tp, NM_ATT_FILE_ID)) + return -EBADF; + + if (!TLVP_PRESENT(&tp, NM_ATT_FILE_VERSION)) + return -EBADMSG; + + sw->file_id_len = TLVP_LEN(&tp, NM_ATT_FILE_ID); + sw->file_version_len = TLVP_LEN(&tp, NM_ATT_FILE_VERSION); + + memcpy(sw->file_id, TLVP_VAL(&tp, NM_ATT_FILE_ID), sw->file_id_len); + memcpy(sw->file_version, TLVP_VAL(&tp, NM_ATT_FILE_VERSION), + sw->file_version_len); + + return 0; +} + /*! \brief Obtain OML Channel Combination for phnsical channel config */ int abis_nm_chcomb4pchan(enum gsm_phys_chan_config pchan) { diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map index 5649e71..e6d4a15 100644 --- a/src/gsm/libosmogsm.map +++ b/src/gsm/libosmogsm.map @@ -31,6 +31,10 @@ abis_nm_pcause_type_names; abis_nm_msgtype_names; abis_nm_att_names; +abis_nm_sw_descr_len; +abis_nm_put_sw_descr; +abis_nm_get_sw_descr_one; +abis_nm_get_sw_descr_len; osmo_sitype_strs; osmo_c4; diff --git a/tests/Makefile.am b/tests/Makefile.am index 352b5a7..16b45ea 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -74,7 +74,7 @@ lapd_lapd_test_LDADD = $(top_builddir)/src/libosmocore.la $(top_builddir)/src/gsm/libosmogsm.la msgb_msgb_test_SOURCES = msgb/msgb_test.c -msgb_msgb_test_LDADD = $(top_builddir)/src/libosmocore.la +msgb_msgb_test_LDADD = $(top_builddir)/src/libosmocore.la $(top_builddir)/src/gsm/libosmogsm.la msgfile_msgfile_test_SOURCES = msgfile/msgfile_test.c msgfile_msgfile_test_LDADD = $(top_builddir)/src/libosmocore.la diff --git a/tests/lapd/lapd_test.c b/tests/lapd/lapd_test.c index e322314..79a5323 100644 --- a/tests/lapd/lapd_test.c +++ b/tests/lapd/lapd_test.c @@ -25,9 +25,10 @@ #include #include #include +#include #include - +#include #include #define CHECK_RC(rc) \ @@ -752,6 +753,94 @@ lapdm_channel_exit(&bts_to_ms_channel); } +static inline void print_chk(const char *what, uint8_t len1, uint8_t len2, + const uint8_t *x1, const uint8_t *x2) +{ + int cmp = memcmp(x1, x2, len2); + printf("\tFILE %s [%u == %u -> %d, %s] %d => %s\n", what, len1, len2, + len1 == len2, len1 != len2 ? "fail" : "ok", + cmp, cmp != 0 ? "FAIL" : "OK"); +} + +static inline void chk_descr(struct msgb *msg, struct abis_nm_sw_descr *put, + const char *descr, bool header) +{ + int res; + struct abis_nm_sw_descr sw = { 0 }; + uint16_t len = abis_nm_put_sw_descr(msg, put, header); + + printf("msgb[%u] :: {msgb->len} %u == %u {len} - %s]:\n\t" + "SW DESCR (%s)\n\t" + "length: {extracted} %u = %u {expected} - %s, failsafe - %s\n", + msg->data_len, msg->len, len, len != msg->len ? "fail" : "ok", + descr, abis_nm_get_sw_descr_len(msgb_data(msg), msg->len), + msg->len, + abis_nm_get_sw_descr_len(msgb_data(msg), msg->len) != msg->len ? "FAIL" : "OK", + len > put->file_version_len + put->file_id_len ? "OK" : "FAIL"); + + res = abis_nm_get_sw_descr_one(&sw, msgb_data(msg), msg->len); + if (res < 0) + printf("\tSW DESCR (%s) parsing error code %d!\n", descr, -res); + else { + print_chk("ID", sw.file_id_len, put->file_id_len, sw.file_id, + put->file_id); + print_chk("VERSION", sw.file_version_len, + put->file_version_len, sw.file_version, + put->file_version); + } +} + +static inline void chk_raw(const char *what, const uint8_t *data, uint16_t len) +{ + struct abis_nm_sw_descr sw = { 0 }; + int res = abis_nm_get_sw_descr_one(&sw, data, len); + uint16_t xlen = abis_nm_get_sw_descr_len(data, len); + + printf("parsing chained %s <1st: %d, total: %d>\n\tSW Descr (%s)\n", + osmo_hexdump(data, len), xlen, len, what); + + if (res < 0) + printf("\tFAIL: %d\n", -res); + else { + printf("\tFILE ID: [%d] %s => OK\n", sw.file_id_len, + osmo_hexdump(sw.file_id, sw.file_id_len)); + printf("\tFILE VERSION: [%d] %s => OK\n", sw.file_version_len, + osmo_hexdump(sw.file_version, sw.file_version_len)); + } + + if (len != xlen) + chk_raw(" 2nd", data + xlen, len - xlen); +} + +static void test_sw_descr() +{ + const char *f_id = "TEST.L0L", *f_ver = "0.1.666~deadbeeffacefeed-dirty"; + uint8_t lf_id = strlen(f_id), lf_ver = strlen(f_ver); + uint8_t chain[] = { 0x42, 0x12, 0x00, 0x03, 0x01, 0x02, 0x03, 0x13, 0x00, 0x03, 0x03, 0x04, 0x05, 0x42, 0x12, 0x00, 0x03, 0x09, 0x07, 0x05, 0x13, 0x00, 0x03, 0x06, 0x07, 0x08 }; + struct msgb *msg = msgb_alloc_headroom(4096, 128, "sw"); + struct abis_nm_sw_descr sw_put = { + .file_id_len = lf_id, + .file_version_len = lf_ver, + }; + + printf("\nI test SW Description (de)serialization:\n"); + + memcpy(sw_put.file_id, f_id, lf_id); + memcpy(sw_put.file_version, f_ver, lf_ver); + + /* check that parsing |SW|ID|VER| works: */ + chk_descr(msg, &sw_put, "with header", true); + msgb_reset(msg); + /* check that parsing |ID|VER| works: */ + chk_descr(msg, &sw_put, "without header", false); + /* check that parsing |ID|VER|SW|ID|VER| fails - notice the lack of + msgb_reset() to create bogus msgb data: */ + chk_descr(msg, &sw_put, "expected failure", true); + /* check multiple, chained SW-descr: */ + chk_raw("half", chain, sizeof(chain) / 2); + chk_raw("full", chain, sizeof(chain)); +} + int main(int argc, char **argv) { osmo_init_logging(&info); @@ -765,6 +854,7 @@ test_lapdm_contention_resolution(); test_lapdm_establishment(); test_lapdm_desync(); + test_sw_descr(); printf("Success.\n"); diff --git a/tests/lapd/lapd_test.ok b/tests/lapd/lapd_test.ok index e188e27..682b397 100644 --- a/tests/lapd/lapd_test.ok +++ b/tests/lapd/lapd_test.ok @@ -96,4 +96,33 @@ Took message from DCCH queue: L2 header size 23, L3 size 0, SAP 0x1000000, 0/0, Link 0x03 Message: [L2]> 0d 21 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b + +I test SW Description (de)serialization: +msgb[4096] :: {msgb->len} 45 == 45 {len} - ok]: + SW DESCR (with header) + length: {extracted} 45 = 45 {expected} - OK, failsafe - OK + FILE ID [8 == 8 -> 1, ok] 0 => OK + FILE VERSION [30 == 30 -> 1, ok] 0 => OK +msgb[4096] :: {msgb->len} 44 == 44 {len} - ok]: + SW DESCR (without header) + length: {extracted} 44 = 44 {expected} - OK, failsafe - OK + FILE ID [8 == 8 -> 1, ok] 0 => OK + FILE VERSION [30 == 30 -> 1, ok] 0 => OK +msgb[4096] :: {msgb->len} 89 == 45 {len} - fail]: + SW DESCR (expected failure) + length: {extracted} 44 = 89 {expected} - FAIL, failsafe - OK + FILE ID [8 == 8 -> 1, ok] 0 => OK + FILE VERSION [30 == 30 -> 1, ok] 0 => OK +parsing chained 42 12 00 03 01 02 03 13 00 03 03 04 05 <1st: 13, total: 13> + SW Descr (half) + FILE ID: [3] 01 02 03 => OK + FILE VERSION: [3] 03 04 05 => OK +parsing chained 42 12 00 03 01 02 03 13 00 03 03 04 05 42 12 00 03 09 07 05 13 00 03 06 07 08 <1st: 13, total: 26> + SW Descr (full) + FILE ID: [3] 01 02 03 => OK + FILE VERSION: [3] 03 04 05 => OK +parsing chained 42 12 00 03 09 07 05 13 00 03 06 07 08 <1st: 13, total: 13> + SW Descr ( 2nd) + FILE ID: [3] 09 07 05 => OK + FILE VERSION: [3] 06 07 08 => OK Success. -- To view, visit https://gerrit.osmocom.org/2165 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ib63b6b5e83b8914864fc7edd789f8958cdc993cd Gerrit-PatchSet: 9 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Tue Apr 4 14:51:52 2017 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Tue, 4 Apr 2017 14:51:52 +0000 Subject: [PATCH] libosmocore[master]: gsm0808: Add utils for AoIP Transport Layer Address In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2176 to look at the new patch set (#4). gsm0808: Add utils for AoIP Transport Layer Address The planned support for true A over IP requires the encoding and decoding of a so called "AoIP Transport Layer Address" element. This commt adds parsing functionality and tests for the element mentioned above, however, it is not yet actively used. Change-Id: I57933b0a06a3f54ec2a41e6ecb6ced9fbbc89332 --- M include/Makefile.am A include/osmocom/gsm/gsm0808_utils.h M src/gsm/Makefile.am A src/gsm/gsm0808_utils.c M src/gsm/libosmogsm.map M tests/gsm0808/gsm0808_test.c 6 files changed, 220 insertions(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/76/2176/4 diff --git a/include/Makefile.am b/include/Makefile.am index e2a1b12..0383d7a 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -77,6 +77,7 @@ osmocom/coding/gsm0503_interleaving.h \ osmocom/coding/gsm0503_coding.h \ osmocom/gsm/gsm0808.h \ + osmocom/gsm/gsm0808_utils.h \ osmocom/gsm/gsm23003.h \ osmocom/gsm/gsm48.h \ osmocom/gsm/gsm48_ie.h \ diff --git a/include/osmocom/gsm/gsm0808_utils.h b/include/osmocom/gsm/gsm0808_utils.h new file mode 100644 index 0000000..5fc1c88 --- /dev/null +++ b/include/osmocom/gsm/gsm0808_utils.h @@ -0,0 +1,30 @@ +/* (C) 2016 by Sysmocom s.f.m.c. GmbH + * All Rights Reserved + * + * Author: Philipp Maier + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#include + +/* Encode AoIP transport address element */ +uint8_t gsm0808_enc_aoip_trasp_addr(struct msgb *msg, + const struct sockaddr_storage *ss); + +/* Decode AoIP transport address element */ +int gsm0808_dec_aoip_trasp_addr(struct sockaddr_storage *ss, + const uint8_t *elem, uint8_t len); diff --git a/src/gsm/Makefile.am b/src/gsm/Makefile.am index 3a4a0cd..e64c9e7 100644 --- a/src/gsm/Makefile.am +++ b/src/gsm/Makefile.am @@ -25,7 +25,7 @@ auth_milenage.c milenage/aes-encblock.c gea.c \ milenage/aes-internal.c milenage/aes-internal-enc.c \ milenage/milenage.c gan.c ipa.c gsm0341.c apn.c \ - gsup.c gprs_gea.c gsm0503_conv.c oap.c + gsup.c gprs_gea.c gsm0503_conv.c oap.c gsm0808_utils.c libgsmint_la_LDFLAGS = -no-undefined libgsmint_la_LIBADD = $(top_builddir)/src/libosmocore.la diff --git a/src/gsm/gsm0808_utils.c b/src/gsm/gsm0808_utils.c new file mode 100644 index 0000000..df24e2b --- /dev/null +++ b/src/gsm/gsm0808_utils.c @@ -0,0 +1,122 @@ +/* (C) 2016 by Sysmocom s.f.m.c. GmbH + * All Rights Reserved + * + * Author: Philipp Maier + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define IP_V4_ADDR_LEN 4 +#define IP_V6_ADDR_LEN 16 +#define IP_PORT_LEN 2 + +/* Encode AoIP transport address element */ +uint8_t gsm0808_enc_aoip_trasp_addr(struct msgb *msg, + const struct sockaddr_storage *ss) +{ + /* See also 3GPP TS 48.008 3.2.2.102 AoIP Transport Layer Address */ + struct sockaddr_in *sin; + struct sockaddr_in6 *sin6; + uint16_t port = 0; + uint8_t *ptr; + uint8_t *old_tail; + uint8_t *tlv_len; + + OSMO_ASSERT(msg); + OSMO_ASSERT(ss); + OSMO_ASSERT(ss->ss_family == AF_INET || ss->ss_family == AF_INET6); + + msgb_put_u8(msg, GSM0808_IE_AOIP_TRASP_ADDR); + tlv_len = msgb_put(msg,1); + old_tail = msg->tail; + + switch (ss->ss_family) { + case AF_INET: + sin = (struct sockaddr_in *)ss; + port = ntohs(sin->sin_port); + ptr = msgb_put(msg, IP_V4_ADDR_LEN); + memcpy(ptr, &sin->sin_addr.s_addr, IP_V4_ADDR_LEN); + break; + case AF_INET6: + sin6 = (struct sockaddr_in6 *)ss; + port = ntohs(sin6->sin6_port); + ptr = msgb_put(msg, IP_V6_ADDR_LEN); + memcpy(ptr, sin6->sin6_addr.s6_addr, IP_V6_ADDR_LEN); + break; + } + + msgb_put_u16(msg, port); + + *tlv_len = (uint8_t) (msg->tail - old_tail); + return *tlv_len + 2; +} + +/* Decode AoIP transport address element */ +int gsm0808_dec_aoip_trasp_addr(struct sockaddr_storage *ss, + const uint8_t *elem, uint8_t len) +{ + /* See also 3GPP TS 48.008 3.2.2.102 AoIP Transport Layer Address */ + struct sockaddr_in sin; + struct sockaddr_in6 sin6; + const uint8_t *old_elem = elem; + + OSMO_ASSERT(ss); + if (!elem) + return -EINVAL; + if (len <= 0) + return -EINVAL; + + memset(ss, 0, sizeof(*ss)); + + switch (len) { + case IP_V4_ADDR_LEN + IP_PORT_LEN: + memset(&sin, 0, sizeof(sin)); + sin.sin_family = AF_INET; + + memcpy(&sin.sin_addr.s_addr, elem, IP_V4_ADDR_LEN); + elem += IP_V4_ADDR_LEN; + sin.sin_port = osmo_load16le(elem); + elem += IP_PORT_LEN; + + memcpy(ss, &sin, sizeof(sin)); + break; + case IP_V6_ADDR_LEN + IP_PORT_LEN: + memset(&sin6, 0, sizeof(sin6)); + sin6.sin6_family = AF_INET6; + + memcpy(sin6.sin6_addr.s6_addr, elem, IP_V6_ADDR_LEN); + elem += IP_V6_ADDR_LEN; + sin6.sin6_port = osmo_load16le(elem); + elem += IP_PORT_LEN; + + memcpy(ss, &sin6, sizeof(sin6)); + break; + default: + /* Malformed element! */ + return -EINVAL; + break; + } + + return (int)(elem - old_elem); +} diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map index 5649e71..3ad847d 100644 --- a/src/gsm/libosmogsm.map +++ b/src/gsm/libosmogsm.map @@ -137,6 +137,8 @@ gsm0808_create_reset; gsm0808_create_sapi_reject; gsm0808_prepend_dtap_header; +gsm0808_enc_aoip_trasp_addr; +gsm0808_dec_aoip_trasp_addr; gsm0858_rsl_ul_meas_enc; diff --git a/tests/gsm0808/gsm0808_test.c b/tests/gsm0808/gsm0808_test.c index 98502b7..26bd1d6 100644 --- a/tests/gsm0808/gsm0808_test.c +++ b/tests/gsm0808/gsm0808_test.c @@ -19,9 +19,14 @@ */ #include +#include +#include #include #include +#include +#include +#include #define VERIFY(msg, data, len) \ if (msgb_l3len(msg) != len) { \ @@ -247,6 +252,63 @@ msgb_free(in_msg); } +static void test_enc_dec_aoip_trasp_addr_v4() +{ + struct sockaddr_storage enc_addr; + struct sockaddr_storage dec_addr; + struct sockaddr_in enc_addr_in; + struct msgb *msg; + uint8_t rc_enc; + int rc_dec; + + memset(&enc_addr_in, 0, sizeof(enc_addr_in)); + enc_addr_in.sin_family = AF_INET; + enc_addr_in.sin_port = htons(1234); + inet_aton("255.0.255.255", &enc_addr_in.sin_addr); + + memset(&enc_addr, 0, sizeof(enc_addr)); + memcpy(&enc_addr, &enc_addr_in, sizeof(enc_addr_in)); + + msg = msgb_alloc(1024, "output buffer"); + rc_enc = gsm0808_enc_aoip_trasp_addr(msg, &enc_addr); + OSMO_ASSERT(rc_enc == 8); + rc_dec = + gsm0808_dec_aoip_trasp_addr(&dec_addr, msg->data + 2, msg->len - 2); + OSMO_ASSERT(rc_dec == 6); + OSMO_ASSERT(memcmp(&enc_addr, &dec_addr, sizeof(enc_addr)) == 0); + + msgb_free(msg); +} + +static void test_enc_dec_aoip_trasp_addr_v6() +{ + struct sockaddr_storage enc_addr; + struct sockaddr_storage dec_addr; + struct sockaddr_in6 enc_addr_in; + struct msgb *msg; + uint8_t rc_enc; + int rc_dec; + + memset(&enc_addr_in, 0, sizeof(enc_addr_in)); + enc_addr_in.sin6_family = AF_INET6; + enc_addr_in.sin6_port = htons(4567); + inet_pton(AF_INET6, "2001:0db8:85a3:08d3:1319:8a2e:0370:7344", + &enc_addr_in.sin6_addr); + + memset(&enc_addr, 0, sizeof(enc_addr)); + memcpy(&enc_addr, &enc_addr_in, sizeof(enc_addr_in)); + + msg = msgb_alloc(1024, "output buffer"); + rc_enc = gsm0808_enc_aoip_trasp_addr(msg, &enc_addr); + OSMO_ASSERT(rc_enc == 20); + rc_dec = + gsm0808_dec_aoip_trasp_addr(&dec_addr, msg->data + 2, msg->len - 2); + OSMO_ASSERT(rc_dec == 18); + OSMO_ASSERT(memcmp(&enc_addr, &dec_addr, sizeof(enc_addr)) == 0); + + msgb_free(msg); +} + int main(int argc, char **argv) { printf("Testing generation of GSM0808 messages\n"); @@ -263,6 +325,8 @@ test_create_clear_rqst(); test_create_dtap(); test_prepend_dtap(); + test_enc_dec_aoip_trasp_addr_v4(); + test_enc_dec_aoip_trasp_addr_v6(); printf("Done\n"); return EXIT_SUCCESS; -- To view, visit https://gerrit.osmocom.org/2176 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I57933b0a06a3f54ec2a41e6ecb6ced9fbbc89332 Gerrit-PatchSet: 4 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Apr 4 14:51:52 2017 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Tue, 4 Apr 2017 14:51:52 +0000 Subject: [PATCH] libosmocore[master]: gsm0808: Add utils for Speech Codec List and Speech Codec In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2177 to look at the new patch set (#4). gsm0808: Add utils for Speech Codec List and Speech Codec The planned support for true A over IP requires the encoding and decoding of a so called "Speech Codec Element" element. This commt adds parsing functionality and tests for the element mentioned above, however, it is not yet actively used. Change-Id: I0e1e2edf47adaa45b22d4b0bcae3640dba7ca200 --- M include/osmocom/gsm/gsm0808_utils.h M include/osmocom/gsm/protocol/gsm_08_08.h M src/gsm/gsm0808_utils.c M src/gsm/libosmogsm.map M tests/gsm0808/gsm0808_test.c 5 files changed, 355 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/77/2177/4 diff --git a/include/osmocom/gsm/gsm0808_utils.h b/include/osmocom/gsm/gsm0808_utils.h index 5fc1c88..b5ddbdb 100644 --- a/include/osmocom/gsm/gsm0808_utils.h +++ b/include/osmocom/gsm/gsm0808_utils.h @@ -21,6 +21,8 @@ #include +#include + /* Encode AoIP transport address element */ uint8_t gsm0808_enc_aoip_trasp_addr(struct msgb *msg, const struct sockaddr_storage *ss); @@ -28,3 +30,20 @@ /* Decode AoIP transport address element */ int gsm0808_dec_aoip_trasp_addr(struct sockaddr_storage *ss, const uint8_t *elem, uint8_t len); + +/* Encode Speech Codec element */ +uint8_t gsm0808_enc_speech_codec(struct msgb *msg, + const struct gsm0808_speech_codec *sc); + +/* Decode Speech Codec element */ +int gsm0808_dec_speech_codec(struct gsm0808_speech_codec *sc, + const uint8_t *elem, uint8_t len); + +/* Encode Speech Codec list */ +uint8_t gsm0808_enc_speech_codec_list(struct msgb *msg, + const struct gsm0808_speech_codec_list + *scl); + +/* Decode Speech Codec list */ +int gsm0808_dec_speech_codec_list(struct gsm0808_speech_codec_list *scl, + const uint8_t *elem, uint8_t len); diff --git a/include/osmocom/gsm/protocol/gsm_08_08.h b/include/osmocom/gsm/protocol/gsm_08_08.h index 6fb4e9e..3e5514d 100644 --- a/include/osmocom/gsm/protocol/gsm_08_08.h +++ b/include/osmocom/gsm/protocol/gsm_08_08.h @@ -3,6 +3,9 @@ #pragma once #include +#include +#include +#include /* * this is from GSM 03.03 CGI but is copied in GSM 08.08 @@ -416,3 +419,22 @@ GSM0808_PAGINF_FOR_SMS = 0x01, GSM0808_PAGINF_FOR_USSD = 0x02, }; + +/* 3GPP TS 48.008 3.2.2.104 Speech Codec */ +struct gsm0808_speech_codec { + bool fi; + bool pi; + bool pt; + bool tf; + uint8_t type; + uint16_t cfg; + bool type_extended; + bool cfg_present; +}; + +/* 3GPP TS 48.008 3.2.2.103 Speech Codec List */ +#define SPEECH_CODEC_MAXLEN 255 +struct gsm0808_speech_codec_list { + struct gsm0808_speech_codec codec[SPEECH_CODEC_MAXLEN]; + uint8_t len; +}; diff --git a/src/gsm/gsm0808_utils.c b/src/gsm/gsm0808_utils.c index df24e2b..eef6146 100644 --- a/src/gsm/gsm0808_utils.c +++ b/src/gsm/gsm0808_utils.c @@ -31,6 +31,7 @@ #define IP_V6_ADDR_LEN 16 #define IP_PORT_LEN 2 + /* Encode AoIP transport address element */ uint8_t gsm0808_enc_aoip_trasp_addr(struct msgb *msg, const struct sockaddr_storage *ss) @@ -120,3 +121,188 @@ return (int)(elem - old_elem); } + +/* Helper function for gsm0808_enc_speech_codec() + * and gsm0808_enc_speech_codec_list() */ +static uint8_t enc_speech_codec(struct msgb *msg, + const struct gsm0808_speech_codec *sc) +{ + /* See also 3GPP TS 48.008 3.2.2.103 Speech Codec List */ + uint8_t header = 0; + uint8_t *old_tail; + + old_tail = msg->tail; + + if (sc->fi) + header |= (1 << 7); + if (sc->pi) + header |= (1 << 6); + if (sc->pt) + header |= (1 << 5); + if (sc->tf) + header |= (1 << 4); + if (sc->type_extended) { + header |= 0x0f; + msgb_put_u8(msg, header); + } else { + OSMO_ASSERT(sc->type < 0x0f); + header |= sc->type; + msgb_put_u8(msg, header); + return (uint8_t) (msg->tail - old_tail); + } + + msgb_put_u8(msg, sc->type); + + if (sc->cfg_present) + msgb_put_u16(msg, sc->cfg); + + return (uint8_t) (msg->tail - old_tail); +} + +/* Encode Speech Codec element */ +uint8_t gsm0808_enc_speech_codec(struct msgb *msg, + const struct gsm0808_speech_codec *sc) +{ + uint8_t *old_tail; + uint8_t *tlv_len; + + OSMO_ASSERT(msg); + OSMO_ASSERT(sc); + + msgb_put_u8(msg, GSM0808_IE_SPEECH_CODEC); + tlv_len = msgb_put(msg, 1); + old_tail = msg->tail; + + enc_speech_codec(msg, sc); + + *tlv_len = (uint8_t) (msg->tail - old_tail); + return *tlv_len + 2; +} + +/* Decode Speech Codec element */ +int gsm0808_dec_speech_codec(struct gsm0808_speech_codec *sc, + const uint8_t *elem, uint8_t len) +{ + /* See also 3GPP TS 48.008 3.2.2.103 Speech Codec List */ + uint8_t header; + const uint8_t *old_elem = elem; + + OSMO_ASSERT(sc); + if (!elem) + return -EINVAL; + if (len <= 0) + return -EINVAL; + + memset(sc, 0, sizeof(*sc)); + + header = *elem; + + /* Malformed elements */ + if ((header & 0x0F) == 0x0F && len < 2) + return -EINVAL; + else if ((header & 0x0F) != 0x0F && len < 1) + return -EINVAL; + + elem++; + len--; + + if (header & (1 << 7)) + sc->fi = true; + if (header & (1 << 6)) + sc->pi = true; + if (header & (1 << 5)) + sc->pt = true; + if (header & (1 << 4)) + sc->tf = true; + + if ((header & 0x0F) != 0x0F) { + sc->type = (header & 0x0F); + return (int)(elem - old_elem); + } + + sc->type = *elem; + elem++; + len--; + + sc->type_extended = true; + + if (len < 2) + return (int)(elem - old_elem); + + sc->cfg = osmo_load16be(elem); + elem += 2; + sc->cfg_present = true; + + return (int)(elem - old_elem); +} + +/* Encode Speech Codec list */ +uint8_t gsm0808_enc_speech_codec_list(struct msgb *msg, + const struct gsm0808_speech_codec_list *scl) +{ + uint8_t *old_tail; + uint8_t *tlv_len; + unsigned int i; + uint8_t rc; + unsigned int bytes_used = 0; + + OSMO_ASSERT(msg); + OSMO_ASSERT(scl); + + /* Empty list */ + OSMO_ASSERT(scl->len >= 1); + + msgb_put_u8(msg, GSM0808_IE_SPEECH_CODEC_LIST); + tlv_len = msgb_put(msg, 1); + old_tail = msg->tail; + + for (i = 0; i < scl->len; i++) { + rc = enc_speech_codec(msg, &scl->codec[i]); + OSMO_ASSERT(rc >= 1); + bytes_used += rc; + OSMO_ASSERT(bytes_used <= 255); + } + + *tlv_len = (uint8_t) (msg->tail - old_tail); + return *tlv_len + 2; +} + +/* Decode Speech Codec list */ +int gsm0808_dec_speech_codec_list(struct gsm0808_speech_codec_list *scl, + const uint8_t *elem, uint8_t len) +{ + const uint8_t *old_elem = elem; + unsigned int i; + int rc; + uint8_t decoded = 0; + + OSMO_ASSERT(scl); + if (!elem) + return -EINVAL; + if (len <= 0) + return -EINVAL; + + memset(scl, 0, sizeof(*scl)); + + for (i = 0; i < ARRAY_SIZE(scl->codec); i++) { + if (len <= 0) + break; + + rc = gsm0808_dec_speech_codec(&scl->codec[i], elem, len); + if (rc < 1) + return -EINVAL; + + elem+=rc; + len -= rc; + decoded++; + } + + scl->len = decoded; + + /* Empty list */ + if (decoded < 1) { + return -EINVAL; + } + + return (int)(elem - old_elem); +} diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map index 3ad847d..c89cbe4 100644 --- a/src/gsm/libosmogsm.map +++ b/src/gsm/libosmogsm.map @@ -139,6 +139,10 @@ gsm0808_prepend_dtap_header; gsm0808_enc_aoip_trasp_addr; gsm0808_dec_aoip_trasp_addr; +gsm0808_enc_speech_codec; +gsm0808_dec_speech_codec; +gsm0808_enc_speech_codec_list; +gsm0808_dec_speech_codec_list; gsm0858_rsl_ul_meas_enc; diff --git a/tests/gsm0808/gsm0808_test.c b/tests/gsm0808/gsm0808_test.c index 26bd1d6..b22de9b 100644 --- a/tests/gsm0808/gsm0808_test.c +++ b/tests/gsm0808/gsm0808_test.c @@ -309,6 +309,126 @@ msgb_free(msg); } +static void test_gsm0808_enc_dec_speech_codec() +{ + struct gsm0808_speech_codec enc_sc; + struct gsm0808_speech_codec dec_sc; + struct msgb *msg; + uint8_t rc_enc; + int rc_dec; + + memset(&enc_sc, 0, sizeof(enc_sc)); + enc_sc.fi = true; + enc_sc.pt = true; + enc_sc.type = 0x05; + + msg = msgb_alloc(1024, "output buffer"); + rc_enc = gsm0808_enc_speech_codec(msg, &enc_sc); + OSMO_ASSERT(rc_enc == 3); + + rc_dec = gsm0808_dec_speech_codec(&dec_sc, msg->data + 2, msg->len - 2); + OSMO_ASSERT(rc_dec == 1); + + OSMO_ASSERT(memcmp(&enc_sc, &dec_sc, sizeof(enc_sc)) == 0); + + msgb_free(msg); +} + + +static void test_gsm0808_enc_dec_speech_codec_ext_with_cfg() +{ + struct gsm0808_speech_codec enc_sc; + struct gsm0808_speech_codec dec_sc; + struct msgb *msg; + uint8_t rc_enc; + int rc_dec; + + enc_sc.pi = true; + enc_sc.tf = true; + enc_sc.type = 0xab; + enc_sc.type_extended = true; + enc_sc.cfg_present = true; + enc_sc.cfg = 0xcdef; + + msg = msgb_alloc(1024, "output buffer"); + rc_enc = gsm0808_enc_speech_codec(msg, &enc_sc); + OSMO_ASSERT(rc_enc == 6); + + rc_dec = gsm0808_dec_speech_codec(&dec_sc, msg->data + 2, msg->len - 2); + OSMO_ASSERT(rc_dec == 4); + + OSMO_ASSERT(memcmp(&enc_sc, &dec_sc, sizeof(enc_sc)) == 0); + + msgb_free(msg); +} + +static void test_gsm0808_enc_dec_speech_codec_ext() +{ + struct gsm0808_speech_codec enc_sc; + struct gsm0808_speech_codec dec_sc; + struct msgb *msg; + uint8_t rc_enc; + int rc_dec; + + enc_sc.fi = true; + enc_sc.tf = true; + enc_sc.type = 0xf2; + enc_sc.type_extended = true; + enc_sc.cfg_present = false; + enc_sc.cfg = 0x0000; + + msg = msgb_alloc(1024, "output buffer"); + rc_enc = gsm0808_enc_speech_codec(msg, &enc_sc); + OSMO_ASSERT(rc_enc == 4); + + rc_dec = gsm0808_dec_speech_codec(&dec_sc, msg->data + 2, msg->len - 2); + OSMO_ASSERT(rc_dec == 2); + + OSMO_ASSERT(memcmp(&enc_sc, &dec_sc, sizeof(enc_sc)) == 0); + + msgb_free(msg); +} + +static void test_gsm0808_enc_dec_speech_codec_list() +{ + struct gsm0808_speech_codec_list enc_scl; + struct gsm0808_speech_codec_list dec_scl; + struct msgb *msg; + uint8_t rc_enc; + int rc_dec; + + memset(&enc_scl, 0, sizeof(enc_scl)); + + enc_scl.codec[0].pi = true; + enc_scl.codec[0].tf = true; + enc_scl.codec[0].type = 0xab; + enc_scl.codec[0].type_extended = true; + enc_scl.codec[0].cfg_present = true; + enc_scl.codec[0].cfg = 0xcdef; + + enc_scl.codec[1].fi = true; + enc_scl.codec[1].pt = true; + enc_scl.codec[1].type = 0x05; + + enc_scl.codec[2].fi = true; + enc_scl.codec[2].tf = true; + enc_scl.codec[2].type = 0xf2; + enc_scl.codec[2].type_extended = true; + + enc_scl.len = 3; + + msg = msgb_alloc(1024, "output buffer"); + rc_enc = gsm0808_enc_speech_codec_list(msg, &enc_scl); + OSMO_ASSERT(rc_enc == 9); + + rc_dec = gsm0808_dec_speech_codec_list(&dec_scl, msg->data + 2, msg->len - 2); + OSMO_ASSERT(rc_dec == 7); + + OSMO_ASSERT(memcmp(&enc_scl, &dec_scl, sizeof(enc_scl)) == 0); + + msgb_free(msg); +} + int main(int argc, char **argv) { printf("Testing generation of GSM0808 messages\n"); @@ -327,6 +447,10 @@ test_prepend_dtap(); test_enc_dec_aoip_trasp_addr_v4(); test_enc_dec_aoip_trasp_addr_v6(); + test_gsm0808_enc_dec_speech_codec(); + test_gsm0808_enc_dec_speech_codec_ext(); + test_gsm0808_enc_dec_speech_codec_ext_with_cfg(); + test_gsm0808_enc_dec_speech_codec_list(); printf("Done\n"); return EXIT_SUCCESS; -- To view, visit https://gerrit.osmocom.org/2177 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I0e1e2edf47adaa45b22d4b0bcae3640dba7ca200 Gerrit-PatchSet: 4 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Apr 4 14:51:52 2017 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Tue, 4 Apr 2017 14:51:52 +0000 Subject: [PATCH] libosmocore[master]: gsm0808: Add AoIP specific elements to gsm0808_create_... fu... In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2178 to look at the new patch set (#4). gsm0808: Add AoIP specific elements to gsm0808_create_... functions the classic A implementation in libosmocore lacks support for AoIP message elements. This patch adds support for AoIP by adding a set of new gsm0808_create_..., which support the missing AoIP message elements Change-Id: I77f866abec1822d19871052f3c647ad782785b34 --- M include/osmocom/gsm/gsm0808.h M src/gsm/gsm0808.c M src/gsm/libosmogsm.map M tests/gsm0808/gsm0808_test.c M tests/gsm0808/gsm0808_test.ok 5 files changed, 189 insertions(+), 7 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/78/2178/4 diff --git a/include/osmocom/gsm/gsm0808.h b/include/osmocom/gsm/gsm0808.h index a7e102c..15e5607 100644 --- a/include/osmocom/gsm/gsm0808.h +++ b/include/osmocom/gsm/gsm0808.h @@ -20,10 +20,16 @@ #pragma once #include "tlv.h" +#include +#include struct msgb; -struct msgb *gsm0808_create_layer3(struct msgb *msg, uint16_t netcode, uint16_t countrycode, int lac, uint16_t ci); +struct msgb *gsm0808_create_layer3(struct msgb *msg_l3, uint16_t nc, + uint16_t cc, int lac, uint16_t _ci); +struct msgb *gsm0808_create_layer3_aoip(struct msgb *msg_l3, uint16_t nc, + uint16_t cc, int lac, uint16_t _ci, + struct gsm0808_speech_codec_list *scl); struct msgb *gsm0808_create_reset(void); struct msgb *gsm0808_create_reset_ack(void); struct msgb *gsm0808_create_clear_command(uint8_t reason); @@ -33,9 +39,17 @@ struct msgb *gsm0808_create_classmark_update(const uint8_t *cm2, uint8_t cm2_len, const uint8_t *cm3, uint8_t cm3_len); struct msgb *gsm0808_create_sapi_reject(uint8_t link_id); +struct msgb *gsm0808_create_ass_compl(uint8_t rr_cause, uint8_t chosen_channel, + uint8_t encr_alg_id, uint8_t speech_mode, + struct sockaddr_storage *ss, + struct gsm0808_speech_codec *sc, + struct gsm0808_speech_codec_list *scl); struct msgb *gsm0808_create_assignment_completed(uint8_t rr_cause, - uint8_t chosen_channel, uint8_t encr_alg_id, + uint8_t chosen_channel, + uint8_t encr_alg_id, uint8_t speech_mode); +struct msgb *gsm0808_create_ass_fail(uint8_t cause, uint8_t *rr_cause, + struct gsm0808_speech_codec_list *scl); struct msgb *gsm0808_create_assignment_failure(uint8_t cause, uint8_t *rr_cause); struct msgb *gsm0808_create_clear_rqst(uint8_t cause); diff --git a/src/gsm/gsm0808.c b/src/gsm/gsm0808.c index de80006..38d0474 100644 --- a/src/gsm/gsm0808.c +++ b/src/gsm/gsm0808.c @@ -19,6 +19,7 @@ */ #include +#include #include #include @@ -27,7 +28,9 @@ #define BSSMAP_MSG_SIZE 512 #define BSSMAP_MSG_HEADROOM 128 -struct msgb *gsm0808_create_layer3(struct msgb *msg_l3, uint16_t nc, uint16_t cc, int lac, uint16_t _ci) +struct msgb *gsm0808_create_layer3_aoip(struct msgb *msg_l3, uint16_t nc, + uint16_t cc, int lac, uint16_t _ci, + struct gsm0808_speech_codec_list *scl) { struct msgb* msg; struct { @@ -55,10 +58,20 @@ msgb_tlv_put(msg, GSM0808_IE_LAYER_3_INFORMATION, msgb_l3len(msg_l3), msg_l3->l3h); + /* AoIP: add Codec List (BSS Supported) 3.2.2.103 */ + if (scl) + gsm0808_enc_speech_codec_list(msg, scl); + /* push the bssmap header */ msg->l3h = msgb_tv_push(msg, BSSAP_MSG_BSS_MANAGEMENT, msgb_length(msg)); return msg; +} + +struct msgb *gsm0808_create_layer3(struct msgb *msg_l3, uint16_t nc, + uint16_t cc, int lac, uint16_t _ci) +{ + return gsm0808_create_layer3_aoip(msg_l3, nc, cc, lac, _ci, NULL); } struct msgb *gsm0808_create_reset(void) @@ -191,9 +204,11 @@ return msg; } -struct msgb *gsm0808_create_assignment_completed(uint8_t rr_cause, - uint8_t chosen_channel, uint8_t encr_alg_id, - uint8_t speech_mode) +struct msgb *gsm0808_create_ass_compl(uint8_t rr_cause, uint8_t chosen_channel, + uint8_t encr_alg_id, uint8_t speech_mode, + struct sockaddr_storage *ss, + struct gsm0808_speech_codec *sc, + struct gsm0808_speech_codec_list *scl) { struct msgb *msg = msgb_alloc_headroom(BSSMAP_MSG_SIZE, BSSMAP_MSG_HEADROOM, "bssmap: ass compl"); @@ -218,6 +233,18 @@ if (speech_mode != 0) msgb_tv_put(msg, GSM0808_IE_SPEECH_VERSION, speech_mode); + /* AoIP: AoIP Transport Layer Address (BSS) 3.2.2.102 */ + if (ss) + gsm0808_enc_aoip_trasp_addr(msg, ss); + + /* AoIP: Speech Codec (Chosen) 3.2.2.104 */ + if (sc) + gsm0808_enc_speech_codec(msg, sc); + + /* AoIP: add Codec List (BSS Supported) 3.2.2.103 */ + if (scl) + gsm0808_enc_speech_codec_list(msg, scl); + /* write LSA identifier 3.2.2.15 */ msg->l3h = msgb_tv_push(msg, BSSAP_MSG_BSS_MANAGEMENT, msgb_length(msg)); @@ -225,7 +252,17 @@ return msg; } -struct msgb *gsm0808_create_assignment_failure(uint8_t cause, uint8_t *rr_cause) +struct msgb *gsm0808_create_assignment_completed(uint8_t rr_cause, + uint8_t chosen_channel, + uint8_t encr_alg_id, + uint8_t speech_mode) +{ + return gsm0808_create_ass_compl(rr_cause, chosen_channel, encr_alg_id, + speech_mode, NULL, NULL, NULL); +} + +struct msgb *gsm0808_create_ass_fail(uint8_t cause, uint8_t *rr_cause, + struct gsm0808_speech_codec_list *scl) { struct msgb *msg = msgb_alloc_headroom(BSSMAP_MSG_SIZE, BSSMAP_MSG_HEADROOM, "bssmap: ass fail"); @@ -242,12 +279,22 @@ /* Circuit pool 3.22.45 */ /* Circuit pool list 3.2.2.46 */ + /* AoIP: add Codec List (BSS Supported) 3.2.2.103 */ + if (scl) + gsm0808_enc_speech_codec_list(msg, scl); + /* update the size */ msg->l3h = msgb_tv_push(msg, BSSAP_MSG_BSS_MANAGEMENT, msgb_length(msg)); return msg; } +struct msgb *gsm0808_create_assignment_failure(uint8_t cause, + uint8_t *rr_cause) +{ + return gsm0808_create_ass_fail(cause, rr_cause, NULL); +} + struct msgb *gsm0808_create_clear_rqst(uint8_t cause) { struct msgb *msg; diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map index c89cbe4..518a5aa 100644 --- a/src/gsm/libosmogsm.map +++ b/src/gsm/libosmogsm.map @@ -125,7 +125,9 @@ gsm0808_bssap_name; gsm0808_bssmap_name; gsm0808_create_assignment_completed; +gsm0808_create_ass_compl; gsm0808_create_assignment_failure; +gsm0808_create_ass_fail; gsm0808_create_cipher_complete; gsm0808_create_cipher_reject; gsm0808_create_classmark_update; @@ -134,6 +136,7 @@ gsm0808_create_clear_rqst; gsm0808_create_dtap; gsm0808_create_layer3; +gsm0808_create_layer3_aoip; gsm0808_create_reset; gsm0808_create_sapi_reject; gsm0808_prepend_dtap_header; diff --git a/tests/gsm0808/gsm0808_test.c b/tests/gsm0808/gsm0808_test.c index b22de9b..4a4a108 100644 --- a/tests/gsm0808/gsm0808_test.c +++ b/tests/gsm0808/gsm0808_test.c @@ -41,6 +41,29 @@ abort(); \ } +/* Setup a fake codec list for testing */ +static void setup_codec_list(struct gsm0808_speech_codec_list *scl) +{ + memset(scl, 0, sizeof(*scl)); + + scl->codec[0].pi = true; + scl->codec[0].tf = true; + scl->codec[0].type = 0xab; + scl->codec[0].type_extended = true; + scl->codec[0].cfg_present = true; + scl->codec[0].cfg = 0xcdef; + + scl->codec[1].fi = true; + scl->codec[1].pt = true; + scl->codec[1].type = 0x05; + + scl->codec[2].fi = true; + scl->codec[2].tf = true; + scl->codec[2].type = 0xf2; + scl->codec[2].type_extended = true; + + scl->len = 3; +} static void test_create_layer3(void) { @@ -56,6 +79,34 @@ msg = gsm0808_create_layer3(in_msg, 0x1122, 0x2244, 0x3366, 0x4488); VERIFY(msg, res, ARRAY_SIZE(res)); + msgb_free(msg); + msgb_free(in_msg); +} + +static void test_create_layer3_aoip() +{ + static const uint8_t res[] = { + 0x00, 0x17, 0x57, 0x05, 0x08, 0x00, 0x77, 0x62, + 0x83, 0x33, 0x66, 0x44, 0x88, 0x17, 0x01, 0x23, + GSM0808_IE_SPEECH_CODEC_LIST, 0x07, 0x5f, 0xab, 0xcd, 0xef, + 0xa5, 0x9f, 0xf2 + }; + + struct msgb *msg, *in_msg; + struct gsm0808_speech_codec_list sc_list; + printf("Testing creating Layer3 (AoIP)\n"); + + setup_codec_list(&sc_list); + + in_msg = msgb_alloc_headroom(512, 128, "foo"); + in_msg->l3h = in_msg->data; + msgb_v_put(in_msg, 0x23); + + msg = + gsm0808_create_layer3_aoip(in_msg, 0x1122, 0x2244, 0x3366, 0x4488, + &sc_list); + VERIFY(msg, res, ARRAY_SIZE(res)); + msgb_free(msg); msgb_free(in_msg); } @@ -189,6 +240,42 @@ msgb_free(msg); } +static void test_create_ass_compl_aoip() +{ + struct sockaddr_storage ss; + struct sockaddr_in sin; + struct gsm0808_speech_codec sc; + struct gsm0808_speech_codec_list sc_list; + static const uint8_t res[] = + { 0x00, 0x1d, 0x02, 0x15, 0x23, 0x21, 0x42, 0x2c, 0x11, 0x40, 0x22, + GSM0808_IE_AOIP_TRASP_ADDR, 0x06, 0xc0, 0xa8, 0x64, 0x17, 0x04, + 0xd2, GSM0808_IE_SPEECH_CODEC, 0x01, 0x9a, + GSM0808_IE_SPEECH_CODEC_LIST, 0x07, 0x5f, 0xab, 0xcd, 0xef, 0xa5, + 0x9f, 0xf2 }; + struct msgb *msg; + + memset(&sin, 0, sizeof(sin)); + sin.sin_family = AF_INET; + sin.sin_port = htons(1234); + inet_aton("192.168.100.23", &sin.sin_addr); + + memset(&ss, 0, sizeof(ss)); + memcpy(&ss, &sin, sizeof(sin)); + + memset(&sc, 0, sizeof(sc)); + sc.fi = true; + sc.tf = true; + sc.type = 0x0a; + + setup_codec_list(&sc_list); + + printf("Testing creating Assignment Complete (AoIP)\n"); + msg = gsm0808_create_ass_compl(0x23, 0x42, 0x11, 0x22, + &ss, &sc, &sc_list); + VERIFY(msg, res, ARRAY_SIZE(res)); + msgb_free(msg); +} + static void test_create_ass_fail() { static const uint8_t res1[] = { 0x00, 0x04, 0x03, 0x04, 0x01, 0x23 }; @@ -203,6 +290,31 @@ msgb_free(msg); msg = gsm0808_create_assignment_failure(0x23, &rr_res); + VERIFY(msg, res2, ARRAY_SIZE(res2)); + msgb_free(msg); +} + +static void test_create_ass_fail_aoip() +{ + static const uint8_t res1[] = + { 0x00, 0x0d, 0x03, 0x04, 0x01, 0x23, GSM0808_IE_SPEECH_CODEC_LIST, + 0x07, 0x5f, 0xab, 0xcd, 0xef, 0xa5, 0x9f, 0xf2 }; + static const uint8_t res2[] = + { 0x00, 0x0f, 0x03, 0x04, 0x01, 0x23, 0x15, 0x02, + GSM0808_IE_SPEECH_CODEC_LIST, 0x07, 0x5f, 0xab, + 0xcd, 0xef, 0xa5, 0x9f, 0xf2 }; + uint8_t rr_res = 2; + struct msgb *msg; + struct gsm0808_speech_codec_list sc_list; + + setup_codec_list(&sc_list); + + printf("Testing creating Assignment Failure (AoIP)\n"); + msg = gsm0808_create_ass_fail(0x23, NULL, &sc_list); + VERIFY(msg, res1, ARRAY_SIZE(res1)); + msgb_free(msg); + + msg = gsm0808_create_ass_fail(0x23, &rr_res, &sc_list); VERIFY(msg, res2, ARRAY_SIZE(res2)); msgb_free(msg); } @@ -433,6 +545,7 @@ { printf("Testing generation of GSM0808 messages\n"); test_create_layer3(); + test_create_layer3_aoip(); test_create_reset(); test_create_clear_command(); test_create_clear_complete(); @@ -441,7 +554,9 @@ test_create_cm_u(); test_create_sapi_reject(); test_create_ass_compl(); + test_create_ass_compl_aoip(); test_create_ass_fail(); + test_create_ass_fail_aoip(); test_create_clear_rqst(); test_create_dtap(); test_prepend_dtap(); diff --git a/tests/gsm0808/gsm0808_test.ok b/tests/gsm0808/gsm0808_test.ok index eb43126..f406551 100644 --- a/tests/gsm0808/gsm0808_test.ok +++ b/tests/gsm0808/gsm0808_test.ok @@ -1,5 +1,6 @@ Testing generation of GSM0808 messages Testing creating Layer3 +Testing creating Layer3 (AoIP) Testing creating Reset Testing creating Clear Command Testing creating Clear Complete @@ -8,7 +9,9 @@ Testing creating CM U Testing creating SAPI Reject Testing creating Assignment Complete +Testing creating Assignment Complete (AoIP) Testing creating Assignment Failure +Testing creating Assignment Failure (AoIP) Testing creating Clear Request Testing creating DTAP Testing prepend DTAP -- To view, visit https://gerrit.osmocom.org/2178 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I77f866abec1822d19871052f3c647ad782785b34 Gerrit-PatchSet: 4 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Apr 4 14:51:52 2017 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Tue, 4 Apr 2017 14:51:52 +0000 Subject: [PATCH] libosmocore[master]: gsm0808: Add utils for Channel Type In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2179 to look at the new patch set (#4). gsm0808: Add utils for Channel Type The planned support for true A over IP requires the encoding of the a Channel Type element (see also ASSIGNMENT REQUEST). This commt adds encoding/decoding functionality and tests for the element mentioned above, however, it is not yet actively used. Change-Id: Id0e2164d84b8cbcc6fe6a090fc7f40a1251421d7 --- M include/osmocom/gsm/gsm0808_utils.h M include/osmocom/gsm/protocol/gsm_08_08.h M src/gsm/gsm0808_utils.c M src/gsm/libosmogsm.map M tests/gsm0808/gsm0808_test.c 5 files changed, 123 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/79/2179/4 diff --git a/include/osmocom/gsm/gsm0808_utils.h b/include/osmocom/gsm/gsm0808_utils.h index b5ddbdb..48e737d 100644 --- a/include/osmocom/gsm/gsm0808_utils.h +++ b/include/osmocom/gsm/gsm0808_utils.h @@ -47,3 +47,11 @@ /* Decode Speech Codec list */ int gsm0808_dec_speech_codec_list(struct gsm0808_speech_codec_list *scl, const uint8_t *elem, uint8_t len); + +/* Encode Channel Type element */ +uint8_t gsm0808_enc_channel_type(struct msgb *msg, + const struct gsm0808_channel_type *ct); + +/* Decode Channel Type element */ +int gsm0808_dec_channel_type(struct gsm0808_channel_type *ct, + const uint8_t *elem, uint8_t len); diff --git a/include/osmocom/gsm/protocol/gsm_08_08.h b/include/osmocom/gsm/protocol/gsm_08_08.h index 3e5514d..e2355f6 100644 --- a/include/osmocom/gsm/protocol/gsm_08_08.h +++ b/include/osmocom/gsm/protocol/gsm_08_08.h @@ -438,3 +438,12 @@ struct gsm0808_speech_codec codec[SPEECH_CODEC_MAXLEN]; uint8_t len; }; + +/* 3GPP TS 48.008 3.2.2.11 Channel Type */ +#define CH_TYPE_PERM_SPCH_MAXLEN 9 +struct gsm0808_channel_type { + uint8_t ch_indctr; + uint8_t ch_rate_type; + uint8_t perm_spch[CH_TYPE_PERM_SPCH_MAXLEN]; + unsigned int perm_spch_len; +}; diff --git a/src/gsm/gsm0808_utils.c b/src/gsm/gsm0808_utils.c index eef6146..ef0f943 100644 --- a/src/gsm/gsm0808_utils.c +++ b/src/gsm/gsm0808_utils.c @@ -31,6 +31,8 @@ #define IP_V6_ADDR_LEN 16 #define IP_PORT_LEN 2 +#define CHANNEL_TYPE_ELEMENT_MAXLEN 11 +#define CHANNEL_TYPE_ELEMENT_MINLEN 3 /* Encode AoIP transport address element */ uint8_t gsm0808_enc_aoip_trasp_addr(struct msgb *msg, @@ -306,3 +308,74 @@ return (int)(elem - old_elem); } + +/* Encode Channel Type element */ +uint8_t gsm0808_enc_channel_type(struct msgb *msg, + const struct gsm0808_channel_type *ct) +{ + unsigned int i; + uint8_t byte; + uint8_t *old_tail; + uint8_t *tlv_len; + + OSMO_ASSERT(msg); + OSMO_ASSERT(ct); + OSMO_ASSERT(ct->perm_spch_len <= CHANNEL_TYPE_ELEMENT_MAXLEN - 2); + + /* FIXME: Implement encoding support for Data + * and Speech + CTM Text Telephony */ + if ((ct->ch_indctr & 0x0f) != GSM0808_CHAN_SPEECH + && (ct->ch_indctr & 0x0f) != GSM0808_CHAN_SIGN) + OSMO_ASSERT(false); + + msgb_put_u8(msg, GSM0808_IE_CHANNEL_TYPE); + tlv_len = msgb_put(msg, 1); + old_tail = msg->tail; + + msgb_put_u8(msg, ct->ch_indctr & 0x0f); + msgb_put_u8(msg, ct->ch_rate_type); + + for (i = 0; i < ct->perm_spch_len; i++) { + byte = ct->perm_spch[i]; + + if (i < ct->perm_spch_len - 1) + byte |= 0x80; + msgb_put_u8(msg, byte); + } + + *tlv_len = (uint8_t) (msg->tail - old_tail); + return *tlv_len + 2; +} + +/* Decode Channel Type element */ +int gsm0808_dec_channel_type(struct gsm0808_channel_type *ct, + const uint8_t *elem, uint8_t len) +{ + unsigned int i; + uint8_t byte; + const uint8_t *old_elem = elem; + + OSMO_ASSERT(ct); + if (!elem) + return -EINVAL; + if (len <= 0) + return -EINVAL; + + memset(ct, 0, sizeof(*ct)); + + ct->ch_indctr = (*elem) & 0x0f; + elem++; + ct->ch_rate_type = (*elem) & 0x0f; + elem++; + + for (i = 0; i < ARRAY_SIZE(ct->perm_spch); i++) { + byte = *elem; + elem++; + ct->perm_spch[i] = byte & 0x7f; + if ((byte & 0x80) == 0x00) + break; + } + ct->perm_spch_len = i + 1; + + return (int)(elem - old_elem); +} diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map index 518a5aa..2ba0c42 100644 --- a/src/gsm/libosmogsm.map +++ b/src/gsm/libosmogsm.map @@ -146,6 +146,8 @@ gsm0808_dec_speech_codec; gsm0808_enc_speech_codec_list; gsm0808_dec_speech_codec_list; +gsm0808_enc_channel_type; +gsm0808_dec_channel_type; gsm0858_rsl_ul_meas_enc; diff --git a/tests/gsm0808/gsm0808_test.c b/tests/gsm0808/gsm0808_test.c index 4a4a108..0dd9e84 100644 --- a/tests/gsm0808/gsm0808_test.c +++ b/tests/gsm0808/gsm0808_test.c @@ -541,6 +541,36 @@ msgb_free(msg); } +static void test_gsm0808_enc_dec_channel_type() +{ + struct gsm0808_channel_type enc_ct; + struct gsm0808_channel_type dec_ct; + struct msgb *msg; + uint8_t ct_enc_expected[] = { GSM0808_IE_CHANNEL_TYPE, + 0x04, 0x01, 0x0b, 0xa1, 0x25 + }; + uint8_t rc_enc; + int rc_dec; + + memset(&enc_ct, 0, sizeof(enc_ct)); + enc_ct.ch_indctr = GSM0808_CHAN_SPEECH; + enc_ct.ch_rate_type = GSM0808_SPEECH_HALF_PREF; + enc_ct.perm_spch[0] = GSM0808_PERM_FR3; + enc_ct.perm_spch[1] = GSM0808_PERM_HR3; + enc_ct.perm_spch_len = 2; + + msg = msgb_alloc(1024, "output buffer"); + rc_enc = gsm0808_enc_channel_type(msg, &enc_ct); + OSMO_ASSERT(rc_enc == 6); + OSMO_ASSERT(memcmp(ct_enc_expected, msg->data, msg->len) == 0); + + rc_dec = gsm0808_dec_channel_type(&dec_ct, msg->data + 2, msg->len - 2); + OSMO_ASSERT(rc_dec == 4); + OSMO_ASSERT(memcmp(&enc_ct, &dec_ct, sizeof(enc_ct)) == 0); + + msgb_free(msg); +} + int main(int argc, char **argv) { printf("Testing generation of GSM0808 messages\n"); @@ -566,6 +596,7 @@ test_gsm0808_enc_dec_speech_codec_ext(); test_gsm0808_enc_dec_speech_codec_ext_with_cfg(); test_gsm0808_enc_dec_speech_codec_list(); + test_gsm0808_enc_dec_channel_type(); printf("Done\n"); return EXIT_SUCCESS; -- To view, visit https://gerrit.osmocom.org/2179 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Id0e2164d84b8cbcc6fe6a090fc7f40a1251421d7 Gerrit-PatchSet: 4 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Apr 4 14:51:52 2017 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Tue, 4 Apr 2017 14:51:52 +0000 Subject: [PATCH] libosmocore[master]: gsm0808: Add utils for Encryption Information In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2180 to look at the new patch set (#4). gsm0808: Add utils for Encryption Information The planned support for true A over IP requires the encoding of the an Encryption Information element (see also BSS_MAP_MSG_CIPHER_MODE_CMD). This commt adds encoding/decoding functionality and tests for the element mentioned above, however, it is not yet actively used. Change-Id: I8262050a9d9fd3f17462cfbb046c6e034dccc6fb --- M include/osmocom/gsm/gsm0808_utils.h M include/osmocom/gsm/protocol/gsm_08_08.h M src/gsm/gsm0808_utils.c M src/gsm/libosmogsm.map M tests/gsm0808/gsm0808_test.c 5 files changed, 131 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/80/2180/4 diff --git a/include/osmocom/gsm/gsm0808_utils.h b/include/osmocom/gsm/gsm0808_utils.h index 48e737d..5bd27c7 100644 --- a/include/osmocom/gsm/gsm0808_utils.h +++ b/include/osmocom/gsm/gsm0808_utils.h @@ -55,3 +55,11 @@ /* Decode Channel Type element */ int gsm0808_dec_channel_type(struct gsm0808_channel_type *ct, const uint8_t *elem, uint8_t len); + +/* Encode Encryption Information element */ +uint8_t gsm0808_enc_encrypt_info(struct msgb *msg, + const struct gsm0808_encrypt_info *ei); + +/* Decode Encryption Information element */ +int gsm0808_dec_encrypt_info(struct gsm0808_encrypt_info *ei, + const uint8_t *elem, uint8_t len); diff --git a/include/osmocom/gsm/protocol/gsm_08_08.h b/include/osmocom/gsm/protocol/gsm_08_08.h index e2355f6..3939aed 100644 --- a/include/osmocom/gsm/protocol/gsm_08_08.h +++ b/include/osmocom/gsm/protocol/gsm_08_08.h @@ -447,3 +447,13 @@ uint8_t perm_spch[CH_TYPE_PERM_SPCH_MAXLEN]; unsigned int perm_spch_len; }; + +/* 3GPP TS 48.008 3.2.2.10 Encryption Information */ +#define ENCRY_INFO_KEY_MAXLEN 252 +#define ENCRY_INFO_PERM_ALGO_MAXLEN 8 +struct gsm0808_encrypt_info { + uint8_t perm_algo[ENCRY_INFO_PERM_ALGO_MAXLEN]; + unsigned int perm_algo_len; + uint8_t key[ENCRY_INFO_KEY_MAXLEN]; + unsigned int key_len; +}; diff --git a/src/gsm/gsm0808_utils.c b/src/gsm/gsm0808_utils.c index ef0f943..1915605 100644 --- a/src/gsm/gsm0808_utils.c +++ b/src/gsm/gsm0808_utils.c @@ -33,6 +33,7 @@ #define CHANNEL_TYPE_ELEMENT_MAXLEN 11 #define CHANNEL_TYPE_ELEMENT_MINLEN 3 +#define ENCRYPT_INFO_ELEMENT_MINLEN 1 /* Encode AoIP transport address element */ uint8_t gsm0808_enc_aoip_trasp_addr(struct msgb *msg, @@ -379,3 +380,73 @@ return (int)(elem - old_elem); } + +/* Encode Encryption Information element */ +uint8_t gsm0808_enc_encrypt_info(struct msgb *msg, + const struct gsm0808_encrypt_info *ei) +{ + unsigned int i; + uint8_t perm_algo = 0; + uint8_t *ptr; + uint8_t *old_tail; + uint8_t *tlv_len; + + OSMO_ASSERT(msg); + OSMO_ASSERT(ei); + OSMO_ASSERT(ei->key_len <= ARRAY_SIZE(ei->key)); + OSMO_ASSERT(ei->perm_algo_len <= ENCRY_INFO_PERM_ALGO_MAXLEN); + + msgb_put_u8(msg, GSM0808_IE_ENCRYPTION_INFORMATION); + tlv_len = msgb_put(msg, 1); + old_tail = msg->tail; + + for (i = 0; i < ei->perm_algo_len; i++) { + /* Note: gsm_08_08.h defines the permitted algorithms + * as an enum which ranges from 0x01 to 0x08 */ + OSMO_ASSERT(ei->perm_algo[i] != 0); + OSMO_ASSERT(ei->perm_algo[i] <= ENCRY_INFO_PERM_ALGO_MAXLEN); + perm_algo |= (1 << (ei->perm_algo[i] - 1)); + } + + msgb_put_u8(msg, perm_algo); + ptr = msgb_put(msg, ei->key_len); + memcpy(ptr, ei->key, ei->key_len); + + *tlv_len = (uint8_t) (msg->tail - old_tail); + return *tlv_len + 2; +} + +/* Decode Encryption Information element */ +int gsm0808_dec_encrypt_info(struct gsm0808_encrypt_info *ei, + const uint8_t *elem, uint8_t len) +{ + uint8_t perm_algo; + unsigned int i; + unsigned int perm_algo_len = 0; + const uint8_t *old_elem = elem; + + OSMO_ASSERT(ei); + if (!elem) + return -EINVAL; + if (len <= 0) + return -EINVAL; + + memset(ei, 0, sizeof(*ei)); + + perm_algo = *elem; + elem++; + + for (i = 0; i < ENCRY_INFO_PERM_ALGO_MAXLEN; i++) { + if (perm_algo & (1 << i)) { + ei->perm_algo[perm_algo_len] = i + 1; + perm_algo_len++; + } + } + ei->perm_algo_len = perm_algo_len; + + ei->key_len = len - 1; + memcpy(ei->key, elem, ei->key_len); + elem+=ei->key_len; + + return (int)(elem - old_elem); +} diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map index 2ba0c42..323ad5a 100644 --- a/src/gsm/libosmogsm.map +++ b/src/gsm/libosmogsm.map @@ -148,6 +148,8 @@ gsm0808_dec_speech_codec_list; gsm0808_enc_channel_type; gsm0808_dec_channel_type; +gsm0808_enc_encrypt_info; +gsm0808_dec_encrypt_info; gsm0858_rsl_ul_meas_enc; diff --git a/tests/gsm0808/gsm0808_test.c b/tests/gsm0808/gsm0808_test.c index 0dd9e84..5fe9c87 100644 --- a/tests/gsm0808/gsm0808_test.c +++ b/tests/gsm0808/gsm0808_test.c @@ -571,6 +571,45 @@ msgb_free(msg); } +static void test_gsm0808_enc_dec_encrypt_info() +{ + struct gsm0808_encrypt_info enc_ei; + struct gsm0808_encrypt_info dec_ei; + struct msgb *msg; + uint8_t ei_enc_expected[] = + { GSM0808_IE_ENCRYPTION_INFORMATION, 0x09, 0x03, 0xaa, 0xbb, + 0xcc, 0xdd, 0xee, 0xff, 0x23, 0x42 + }; + uint8_t rc_enc; + int rc_dec; + + memset(&enc_ei, 0, sizeof(enc_ei)); + enc_ei.perm_algo[0] = GSM0808_ALG_ID_A5_0; + enc_ei.perm_algo[1] = GSM0808_ALG_ID_A5_1; + enc_ei.perm_algo_len = 2; + enc_ei.key[0] = 0xaa; + enc_ei.key[1] = 0xbb; + enc_ei.key[2] = 0xcc; + enc_ei.key[3] = 0xdd; + enc_ei.key[4] = 0xee; + enc_ei.key[5] = 0xff; + enc_ei.key[6] = 0x23; + enc_ei.key[7] = 0x42; + enc_ei.key_len = 8; + + msg = msgb_alloc(1024, "output buffer"); + rc_enc = gsm0808_enc_encrypt_info(msg, &enc_ei); + OSMO_ASSERT(rc_enc == 11); + OSMO_ASSERT(memcmp(ei_enc_expected, msg->data, msg->len) == 0); + + rc_dec = gsm0808_dec_encrypt_info(&dec_ei, msg->data + 2, msg->len - 2); + OSMO_ASSERT(rc_dec == 9); + + OSMO_ASSERT(memcmp(&enc_ei, &dec_ei, sizeof(enc_ei)) == 0); + + msgb_free(msg); +} + int main(int argc, char **argv) { printf("Testing generation of GSM0808 messages\n"); @@ -597,6 +636,7 @@ test_gsm0808_enc_dec_speech_codec_ext_with_cfg(); test_gsm0808_enc_dec_speech_codec_list(); test_gsm0808_enc_dec_channel_type(); + test_gsm0808_enc_dec_encrypt_info(); printf("Done\n"); return EXIT_SUCCESS; -- To view, visit https://gerrit.osmocom.org/2180 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I8262050a9d9fd3f17462cfbb046c6e034dccc6fb Gerrit-PatchSet: 4 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Apr 4 14:51:52 2017 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Tue, 4 Apr 2017 14:51:52 +0000 Subject: [PATCH] libosmocore[master]: gsm0808: Add utils for Cell Identifier List In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2181 to look at the new patch set (#4). gsm0808: Add utils for Cell Identifier List The planned support for true A over IP requires the encoding of the a Cell Identifier List element (see also BSS_MAP_MSG_PAGING). This commt adds encoding/decoding functionality and tests for the element mentioned above, however, it is not yet actively used. Change-Id: I625245dd1dd396fc2bc189e8cd2c444a33042528 --- M include/osmocom/gsm/gsm0808_utils.h M include/osmocom/gsm/protocol/gsm_08_08.h M src/gsm/gsm0808_utils.c M src/gsm/libosmogsm.map M tests/gsm0808/gsm0808_test.c 5 files changed, 181 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/81/2181/4 diff --git a/include/osmocom/gsm/gsm0808_utils.h b/include/osmocom/gsm/gsm0808_utils.h index 5bd27c7..e6e55a7 100644 --- a/include/osmocom/gsm/gsm0808_utils.h +++ b/include/osmocom/gsm/gsm0808_utils.h @@ -63,3 +63,11 @@ /* Decode Encryption Information element */ int gsm0808_dec_encrypt_info(struct gsm0808_encrypt_info *ei, const uint8_t *elem, uint8_t len); + +/* Encode Cell Identifier List element */ +uint8_t gsm0808_enc_cell_id_list(struct msgb *msg, + const struct gsm0808_cell_id_list *cil); + +/* Decode Cell Identifier List element */ +int gsm0808_dec_cell_id_list(struct gsm0808_cell_id_list *cil, + const uint8_t *elem, uint8_t len); diff --git a/include/osmocom/gsm/protocol/gsm_08_08.h b/include/osmocom/gsm/protocol/gsm_08_08.h index 3939aed..e5e7e1e 100644 --- a/include/osmocom/gsm/protocol/gsm_08_08.h +++ b/include/osmocom/gsm/protocol/gsm_08_08.h @@ -457,3 +457,11 @@ uint8_t key[ENCRY_INFO_KEY_MAXLEN]; unsigned int key_len; }; + +/* 3GPP TS 48.008 3.2.2.27 Cell Identifier List */ +#define CELL_ID_LIST_LAC_MAXLEN 127 +struct gsm0808_cell_id_list { + uint8_t id_discr; + uint16_t id_list_lac[CELL_ID_LIST_LAC_MAXLEN]; + unsigned int id_list_len; +}; diff --git a/src/gsm/gsm0808_utils.c b/src/gsm/gsm0808_utils.c index 1915605..054372a 100644 --- a/src/gsm/gsm0808_utils.c +++ b/src/gsm/gsm0808_utils.c @@ -450,3 +450,81 @@ return (int)(elem - old_elem); } + +/* Encode Cell Identifier List element */ +uint8_t gsm0808_enc_cell_id_list(struct msgb *msg, + const struct gsm0808_cell_id_list *cil) +{ + uint8_t *old_tail; + uint8_t *tlv_len; + unsigned int i; + + OSMO_ASSERT(msg); + OSMO_ASSERT(cil); + + msgb_put_u8(msg, GSM0808_IE_CELL_IDENTIFIER_LIST); + tlv_len = msgb_put(msg, 1); + old_tail = msg->tail; + + msgb_put_u8(msg, cil->id_discr & 0x0f); + + switch (cil->id_discr) { + case CELL_IDENT_LAC: + OSMO_ASSERT(cil->id_list_len <= CELL_ID_LIST_LAC_MAXLEN) + for (i=0;iid_list_len;i++) { + msgb_put_u16(msg, cil->id_list_lac[i]); + } + break; + case CELL_IDENT_BSS: + /* Does not have any list items */ + break; + default: + /* FIXME: Implement support for all identifier list elements */ + OSMO_ASSERT(false); + } + + *tlv_len = (uint8_t) (msg->tail - old_tail); + return *tlv_len + 2; +} + +/* Decode Cell Identifier List element */ +int gsm0808_dec_cell_id_list(struct gsm0808_cell_id_list *cil, + const uint8_t *elem, uint8_t len) +{ + uint8_t id_discr; + const uint8_t *old_elem = elem; + unsigned int item_count = 0; + + OSMO_ASSERT(cil); + if (!elem) + return -EINVAL; + if (len <= 0) + return -EINVAL; + + memset(cil, 0, sizeof(*cil)); + + id_discr = *elem & 0x0f; + elem++; + len--; + + cil->id_discr = id_discr; + + switch (id_discr) { + case CELL_IDENT_LAC: + while (len >= 2) { + cil->id_list_lac[item_count] = osmo_load16be(elem); + elem += 2; + item_count++; + len -= 2; + } + case CELL_IDENT_BSS: + /* Does not have any list items */ + break; + default: + /* FIXME: Implement support for all identifier list elements */ + return -EINVAL; + } + + cil->id_list_len = item_count; + return (int)(elem - old_elem); +} diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map index 323ad5a..cf0a7fe 100644 --- a/src/gsm/libosmogsm.map +++ b/src/gsm/libosmogsm.map @@ -150,6 +150,8 @@ gsm0808_dec_channel_type; gsm0808_enc_encrypt_info; gsm0808_dec_encrypt_info; +gsm0808_enc_cell_id_list; +gsm0808_dec_cell_id_list; gsm0858_rsl_ul_meas_enc; diff --git a/tests/gsm0808/gsm0808_test.c b/tests/gsm0808/gsm0808_test.c index 5fe9c87..af457b4 100644 --- a/tests/gsm0808/gsm0808_test.c +++ b/tests/gsm0808/gsm0808_test.c @@ -610,6 +610,88 @@ msgb_free(msg); } +static void test_gsm0808_enc_dec_cell_id_list_lac() +{ + struct gsm0808_cell_id_list enc_cil; + struct gsm0808_cell_id_list dec_cil; + struct msgb *msg; + uint8_t rc_enc; + int rc_dec; + + memset(&enc_cil, 0, sizeof(enc_cil)); + enc_cil.id_discr = CELL_IDENT_LAC; + enc_cil.id_list_lac[0] = 0x0124; + enc_cil.id_list_lac[1] = 0xABCD; + enc_cil.id_list_lac[2] = 0x5678; + enc_cil.id_list_len = 3; + + msg = msgb_alloc(1024, "output buffer"); + rc_enc = gsm0808_enc_cell_id_list(msg, &enc_cil); + OSMO_ASSERT(rc_enc == 9); + + rc_dec = gsm0808_dec_cell_id_list(&dec_cil, msg->data + 2, + msg->len - 2); + OSMO_ASSERT(rc_dec == 7); + + OSMO_ASSERT(memcmp(&enc_cil, &dec_cil, sizeof(enc_cil)) == 0); + + msgb_free(msg); +} + +static void test_gsm0808_enc_dec_cell_id_list_single_lac() +{ + struct gsm0808_cell_id_list enc_cil; + struct gsm0808_cell_id_list dec_cil; + struct msgb *msg; + uint8_t cil_enc_expected[] = { GSM0808_IE_CELL_IDENTIFIER_LIST, 0x03, + 0x05, 0x23, 0x42 + }; + uint8_t rc_enc; + int rc_dec; + + memset(&enc_cil, 0, sizeof(enc_cil)); + enc_cil.id_discr = CELL_IDENT_LAC; + enc_cil.id_list_lac[0] = 0x2342; + enc_cil.id_list_len = 1; + + msg = msgb_alloc(1024, "output buffer"); + rc_enc = gsm0808_enc_cell_id_list(msg, &enc_cil); + OSMO_ASSERT(rc_enc == 5); + OSMO_ASSERT(memcmp(cil_enc_expected, msg->data, msg->len) == 0); + + rc_dec = gsm0808_dec_cell_id_list(&dec_cil, msg->data + 2, + msg->len - 2); + OSMO_ASSERT(rc_dec == 3); + + OSMO_ASSERT(memcmp(&enc_cil, &dec_cil, sizeof(enc_cil)) == 0); + + msgb_free(msg); +} + +static void test_gsm0808_enc_dec_cell_id_list_bss() +{ + struct gsm0808_cell_id_list enc_cil; + struct gsm0808_cell_id_list dec_cil; + struct msgb *msg; + uint8_t rc_enc; + int rc_dec; + + memset(&enc_cil, 0, sizeof(enc_cil)); + enc_cil.id_discr = CELL_IDENT_LAC; + + msg = msgb_alloc(1024, "output buffer"); + rc_enc = gsm0808_enc_cell_id_list(msg, &enc_cil); + OSMO_ASSERT(rc_enc == 3); + + rc_dec = gsm0808_dec_cell_id_list(&dec_cil, msg->data + 2, + msg->len - 2); + OSMO_ASSERT(rc_dec == 1); + + OSMO_ASSERT(memcmp(&enc_cil, &dec_cil, sizeof(enc_cil)) == 0); + + msgb_free(msg); +} + int main(int argc, char **argv) { printf("Testing generation of GSM0808 messages\n"); @@ -637,6 +719,9 @@ test_gsm0808_enc_dec_speech_codec_list(); test_gsm0808_enc_dec_channel_type(); test_gsm0808_enc_dec_encrypt_info(); + test_gsm0808_enc_dec_cell_id_list_lac(); + test_gsm0808_enc_dec_cell_id_list_single_lac(); + test_gsm0808_enc_dec_cell_id_list_bss(); printf("Done\n"); return EXIT_SUCCESS; -- To view, visit https://gerrit.osmocom.org/2181 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I625245dd1dd396fc2bc189e8cd2c444a33042528 Gerrit-PatchSet: 4 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Apr 4 14:51:52 2017 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Tue, 4 Apr 2017 14:51:52 +0000 Subject: [PATCH] libosmocore[master]: gsm0808: Add create functions for CIPHER MODE COMMAND In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2182 to look at the new patch set (#4). gsm0808: Add create functions for CIPHER MODE COMMAND gsm0808.h/c lacks functionality to generate CIPHER MODE COMMAND messages. These messages are required if the code is used in an MSC implementation. This commit adds a gsm0808_create_cipher() function, that generates an A/AoiP CIPHER MODE COMMAND message. Change-Id: I8eb1c357860c3e740b0f5d17e1c256bc87920958 --- M include/osmocom/gsm/gsm0808.h M src/gsm/gsm0808.c M src/gsm/libosmogsm.map M tests/gsm0808/gsm0808_test.c M tests/gsm0808/gsm0808_test.ok 5 files changed, 78 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/82/2182/4 diff --git a/include/osmocom/gsm/gsm0808.h b/include/osmocom/gsm/gsm0808.h index 15e5607..53e673c 100644 --- a/include/osmocom/gsm/gsm0808.h +++ b/include/osmocom/gsm/gsm0808.h @@ -34,6 +34,8 @@ struct msgb *gsm0808_create_reset_ack(void); struct msgb *gsm0808_create_clear_command(uint8_t reason); struct msgb *gsm0808_create_clear_complete(void); +struct msgb *gsm0808_create_cipher(struct gsm0808_encrypt_info *ei, + uint8_t *cipher_response_mode); struct msgb *gsm0808_create_cipher_complete(struct msgb *layer3, uint8_t alg_id); struct msgb *gsm0808_create_cipher_reject(uint8_t cause); struct msgb *gsm0808_create_classmark_update(const uint8_t *cm2, uint8_t cm2_len, diff --git a/src/gsm/gsm0808.c b/src/gsm/gsm0808.c index 38d0474..add7fcb 100644 --- a/src/gsm/gsm0808.c +++ b/src/gsm/gsm0808.c @@ -130,6 +130,39 @@ return msg; } +struct msgb *gsm0808_create_cipher(struct gsm0808_encrypt_info *ei, + uint8_t *cipher_response_mode) +{ + /* See also: 3GPP TS 48.008 3.2.1.30 CIPHER MODE COMMAND */ + struct msgb *msg; + + /* Mandatory emelent! */ + OSMO_ASSERT(ei); + + msg = + msgb_alloc_headroom(BSSMAP_MSG_SIZE, BSSMAP_MSG_HEADROOM, + "cipher-mode-command"); + if (!msg) + return NULL; + + /* Message Type 3.2.2.1 */ + msgb_v_put(msg, BSS_MAP_MSG_CIPHER_MODE_CMD); + + /* Encryption Information 3.2.2.10 */ + gsm0808_enc_encrypt_info(msg, ei); + + /* Cipher Response Mode 3.2.2.34 */ + if (cipher_response_mode) + msgb_tv_put(msg, GSM0808_IE_CIPHER_RESPONSE_MODE, + *cipher_response_mode); + + /* pre-pend the header */ + msg->l3h = + msgb_tv_push(msg, BSSAP_MSG_BSS_MANAGEMENT, msgb_length(msg)); + + return msg; +} + struct msgb *gsm0808_create_cipher_complete(struct msgb *layer3, uint8_t alg_id) { struct msgb *msg = msgb_alloc_headroom(BSSMAP_MSG_SIZE, BSSMAP_MSG_HEADROOM, diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map index cf0a7fe..786bf08 100644 --- a/src/gsm/libosmogsm.map +++ b/src/gsm/libosmogsm.map @@ -128,6 +128,7 @@ gsm0808_create_ass_compl; gsm0808_create_assignment_failure; gsm0808_create_ass_fail; +gsm0808_create_cipher; gsm0808_create_cipher_complete; gsm0808_create_cipher_reject; gsm0808_create_classmark_update; diff --git a/tests/gsm0808/gsm0808_test.c b/tests/gsm0808/gsm0808_test.c index af457b4..f33e0bd 100644 --- a/tests/gsm0808/gsm0808_test.c +++ b/tests/gsm0808/gsm0808_test.c @@ -144,6 +144,46 @@ msgb_free(msg); } +static void test_create_cipher() +{ + static const uint8_t res[] = + { 0x00, 0x0c, 0x53, 0x0a, 0x09, 0x03, 0xaa, + 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x23, 0x42 }; + static const uint8_t res2[] = + { 0x00, 0x0e, 0x53, 0x0a, 0x09, 0x03, 0xaa, + 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x23, 0x42, + GSM0808_IE_CIPHER_RESPONSE_MODE, 0x01 }; + struct msgb *msg; + struct gsm0808_encrypt_info ei; + uint8_t include_imeisv; + + memset(&ei, 0, sizeof(ei)); + ei.perm_algo[0] = GSM0808_ALG_ID_A5_0; + ei.perm_algo[1] = GSM0808_ALG_ID_A5_1; + ei.perm_algo_len = 2; + ei.key[0] = 0xaa; + ei.key[1] = 0xbb; + ei.key[2] = 0xcc; + ei.key[3] = 0xdd; + ei.key[4] = 0xee; + ei.key[5] = 0xff; + ei.key[6] = 0x23; + ei.key[7] = 0x42; + ei.key_len = 8; + include_imeisv = 1; + + printf("Testing creating Chipher Mode Command\n"); + msg = gsm0808_create_cipher(&ei, NULL); + OSMO_ASSERT(msg); + VERIFY(msg, res, ARRAY_SIZE(res)); + msgb_free(msg); + + msg = gsm0808_create_cipher(&ei, &include_imeisv); + OSMO_ASSERT(msg); + VERIFY(msg, res2, ARRAY_SIZE(res2)); + msgb_free(msg); +} + static void test_create_cipher_complete() { static const uint8_t res1[] = { @@ -700,6 +740,7 @@ test_create_reset(); test_create_clear_command(); test_create_clear_complete(); + test_create_cipher(); test_create_cipher_complete(); test_create_cipher_reject(); test_create_cm_u(); diff --git a/tests/gsm0808/gsm0808_test.ok b/tests/gsm0808/gsm0808_test.ok index f406551..8e2087d 100644 --- a/tests/gsm0808/gsm0808_test.ok +++ b/tests/gsm0808/gsm0808_test.ok @@ -4,6 +4,7 @@ Testing creating Reset Testing creating Clear Command Testing creating Clear Complete +Testing creating Chipher Mode Command Testing creating Cipher Complete Testing creating Cipher Reject Testing creating CM U -- To view, visit https://gerrit.osmocom.org/2182 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I8eb1c357860c3e740b0f5d17e1c256bc87920958 Gerrit-PatchSet: 4 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Apr 4 14:51:52 2017 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Tue, 4 Apr 2017 14:51:52 +0000 Subject: [PATCH] libosmocore[master]: gsm0808: Add create functions for BSS_MAP_MSG_ASSIGMENT_RQST In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2184 to look at the new patch set (#5). gsm0808: Add create functions for BSS_MAP_MSG_ASSIGMENT_RQST gsm0808.h/c lacks functionality to generate BSS_MAP_MSG_ASSIGMENT_RQST messages. These messages are required if the code is used in an MSC implementation. This commit adds a gsm0808_create_assignment() function, that generates an A/AoiP BSS_MAP_MSG_PAGING message. Change-Id: I4d1d455a1e1cf95407e23ded7b7defbcf2dd6ff0 --- M include/osmocom/gsm/gsm0808.h M src/gsm/gsm0808.c M src/gsm/libosmogsm.map M tests/gsm0808/gsm0808_test.c M tests/gsm0808/gsm0808_test.ok 5 files changed, 113 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/84/2184/5 diff --git a/include/osmocom/gsm/gsm0808.h b/include/osmocom/gsm/gsm0808.h index d4d5395..c60650b 100644 --- a/include/osmocom/gsm/gsm0808.h +++ b/include/osmocom/gsm/gsm0808.h @@ -41,6 +41,11 @@ struct msgb *gsm0808_create_classmark_update(const uint8_t *cm2, uint8_t cm2_len, const uint8_t *cm3, uint8_t cm3_len); struct msgb *gsm0808_create_sapi_reject(uint8_t link_id); +struct msgb *gsm0808_create_assignment(struct gsm0808_channel_type *ct, + uint16_t * cic, + struct sockaddr_storage *ss, + struct gsm0808_speech_codec_list *scl, + uint32_t * ci); struct msgb *gsm0808_create_ass_compl(uint8_t rr_cause, uint8_t chosen_channel, uint8_t encr_alg_id, uint8_t speech_mode, struct sockaddr_storage *ss, diff --git a/src/gsm/gsm0808.c b/src/gsm/gsm0808.c index ab41215..42eaa7a 100644 --- a/src/gsm/gsm0808.c +++ b/src/gsm/gsm0808.c @@ -237,6 +237,62 @@ return msg; } +struct msgb *gsm0808_create_assignment(struct gsm0808_channel_type *ct, + uint16_t *cic, + struct sockaddr_storage *ss, + struct gsm0808_speech_codec_list *scl, + uint32_t *ci) +{ + /* See also: 3GPP TS 48.008 3.2.1.1 ASSIGNMENT REQUEST */ + struct msgb *msg; + uint16_t cic_sw; + uint32_t ci_sw; + + /* Mandatory emelent! */ + OSMO_ASSERT(ct); + + msg = + msgb_alloc_headroom(BSSMAP_MSG_SIZE, BSSMAP_MSG_HEADROOM, + "bssmap: ass req"); + if (!msg) + return NULL; + + /* Message Type 3.2.2.1 */ + msgb_v_put(msg, BSS_MAP_MSG_ASSIGMENT_RQST); + + /* Channel Type 3.2.2.11 */ + gsm0808_enc_channel_type(msg, ct); + + /* Circuit Identity Code 3.2.2.2 */ + if (cic) { + cic_sw = htons(*cic); + msgb_tv_fixed_put(msg, GSM0808_IE_CIRCUIT_IDENTITY_CODE, + sizeof(cic_sw), (uint8_t *) & cic_sw); + } + + /* AoIP: AoIP Transport Layer Address (MGW) 3.2.2.102 */ + if (ss) { + gsm0808_enc_aoip_trasp_addr(msg, ss); + } + + /* AoIP: Codec List (MSC Preferred) 3.2.2.103 */ + if (scl) + gsm0808_enc_speech_codec_list(msg, scl); + + /* AoIP: Call Identifier 3.2.2.105 */ + if (ci) { + ci_sw = htonl(*ci); + msgb_tv_fixed_put(msg, GSM0808_IE_CALL_ID, sizeof(ci_sw), + (uint8_t *) & ci_sw); + } + + /* push the bssmap header */ + msg->l3h = + msgb_tv_push(msg, BSSAP_MSG_BSS_MANAGEMENT, msgb_length(msg)); + + return msg; +} + struct msgb *gsm0808_create_ass_compl(uint8_t rr_cause, uint8_t chosen_channel, uint8_t encr_alg_id, uint8_t speech_mode, struct sockaddr_storage *ss, diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map index ec23418..8445f16 100644 --- a/src/gsm/libosmogsm.map +++ b/src/gsm/libosmogsm.map @@ -124,6 +124,7 @@ gsm0808_att_tlvdef; gsm0808_bssap_name; gsm0808_bssmap_name; +gsm0808_create_assignment; gsm0808_create_assignment_completed; gsm0808_create_ass_compl; gsm0808_create_assignment_failure; diff --git a/tests/gsm0808/gsm0808_test.c b/tests/gsm0808/gsm0808_test.c index b0dad7d..e8181c4 100644 --- a/tests/gsm0808/gsm0808_test.c +++ b/tests/gsm0808/gsm0808_test.c @@ -262,6 +262,55 @@ msgb_free(msg); } +static void test_create_ass() +{ + static const uint8_t res1[] = + { 0x00, 0x0a, 0x01, 0x0b, 0x04, 0x01, 0x0b, 0xa1, 0x25, 0x01, 0x00, + 0x04 }; + static const uint8_t res2[] = + { 0x00, 0x20, 0x01, 0x0b, 0x04, 0x01, 0x0b, 0xa1, 0x25, 0x01, 0x00, + 0x04, GSM0808_IE_AOIP_TRASP_ADDR, 0x06, 0xc0, 0xa8, 0x64, 0x17, + 0x04, 0xd2, GSM0808_IE_SPEECH_CODEC_LIST, 0x07, 0x5f, 0xab, 0xcd, + 0xef, 0xa5, 0x9f, 0xf2, GSM0808_IE_CALL_ID, 0xaa, 0xbb, 0xcc, + 0xdd }; + + struct msgb *msg; + struct gsm0808_channel_type ct; + uint16_t cic = 0004; + struct sockaddr_storage ss; + struct sockaddr_in sin; + struct gsm0808_speech_codec_list sc_list; + uint32_t call_id = 0xAABBCCDD; + + memset(&ct, 0, sizeof(ct)); + ct.ch_indctr = GSM0808_CHAN_SPEECH; + ct.ch_rate_type = GSM0808_SPEECH_HALF_PREF; + ct.perm_spch[0] = GSM0808_PERM_FR3; + ct.perm_spch[1] = GSM0808_PERM_HR3; + ct.perm_spch_len = 2; + + memset(&sin, 0, sizeof(sin)); + sin.sin_family = AF_INET; + sin.sin_port = htons(1234); + inet_aton("192.168.100.23", &sin.sin_addr); + + memset(&ss, 0, sizeof(ss)); + memcpy(&ss, &sin, sizeof(sin)); + + setup_codec_list(&sc_list); + + printf("Testing creating Assignment Request\n"); + msg = gsm0808_create_assignment(&ct, &cic, NULL, NULL, NULL); + OSMO_ASSERT(msg); + VERIFY(msg, res1, ARRAY_SIZE(res1)); + msgb_free(msg); + + msg = gsm0808_create_assignment(&ct, &cic, &ss, &sc_list, &call_id); + OSMO_ASSERT(msg); + VERIFY(msg, res2, ARRAY_SIZE(res2)); + msgb_free(msg); +} + static void test_create_ass_compl() { static const uint8_t res1[] = { @@ -786,6 +835,7 @@ test_create_cipher_reject(); test_create_cm_u(); test_create_sapi_reject(); + test_create_ass(); test_create_ass_compl(); test_create_ass_compl_aoip(); test_create_ass_fail(); diff --git a/tests/gsm0808/gsm0808_test.ok b/tests/gsm0808/gsm0808_test.ok index 6170a7a..52af134 100644 --- a/tests/gsm0808/gsm0808_test.ok +++ b/tests/gsm0808/gsm0808_test.ok @@ -9,6 +9,7 @@ Testing creating Cipher Reject Testing creating CM U Testing creating SAPI Reject +Testing creating Assignment Request Testing creating Assignment Complete Testing creating Assignment Complete (AoIP) Testing creating Assignment Failure -- To view, visit https://gerrit.osmocom.org/2184 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I4d1d455a1e1cf95407e23ded7b7defbcf2dd6ff0 Gerrit-PatchSet: 5 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Apr 4 14:58:57 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Tue, 4 Apr 2017 14:58:57 +0000 Subject: [PATCH] openbsc[master]: Use libosmocore for SW Description parsing In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2166 to look at the new patch set (#4). Use libosmocore for SW Description parsing Requires libosmocore with Ib63b6b5e83b8914864fc7edd789f8958cdc993cd. Change-Id: Ib94db414e94a2a1f234ac6f1cb346dca1c7a8be3 --- M openbsc/include/openbsc/abis_nm.h M openbsc/src/ipaccess/ipaccess-config.c M openbsc/src/libbsc/abis_nm.c M openbsc/tests/abis/abis_test.c M openbsc/tests/abis/abis_test.ok 5 files changed, 74 insertions(+), 124 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/66/2166/4 diff --git a/openbsc/include/openbsc/abis_nm.h b/openbsc/include/openbsc/abis_nm.h index 2465452..9dcb91f 100644 --- a/openbsc/include/openbsc/abis_nm.h +++ b/openbsc/include/openbsc/abis_nm.h @@ -68,18 +68,6 @@ int (*sw_act_req)(struct msgb *); }; -struct abis_nm_sw_descr { - /* where does it start? how long is it? */ - const uint8_t *start; - size_t len; - - /* the parsed data */ - const uint8_t *file_id; - uint16_t file_id_len; - const uint8_t *file_ver; - uint16_t file_ver_len; -}; - extern int abis_nm_rcvmsg(struct msgb *msg); int abis_nm_tlv_parse(struct tlv_parsed *tp, struct gsm_bts *bts, const uint8_t *buf, int len); @@ -182,7 +170,7 @@ void abis_nm_queue_send_next(struct gsm_bts *bts); /* for bs11_config. */ int abis_nm_parse_sw_config(const uint8_t *data, const size_t len, - struct abis_nm_sw_descr *res, const int res_len); + struct abis_nm_sw_descr *res, const int res_len); int abis_nm_select_newest_sw(const struct abis_nm_sw_descr *sw, const size_t len); /* Helper functions for updating attributes */ diff --git a/openbsc/src/ipaccess/ipaccess-config.c b/openbsc/src/ipaccess/ipaccess-config.c index 0c3f888..ca5f195 100644 --- a/openbsc/src/ipaccess/ipaccess-config.c +++ b/openbsc/src/ipaccess/ipaccess-config.c @@ -52,6 +52,7 @@ #include #include #include +#include struct gsm_network *bsc_gsmnet; @@ -70,17 +71,9 @@ static int found_trx = 0; static int loop_tests = 0; -struct sw_load { - uint8_t file_id[255]; - uint8_t file_id_len; - - uint8_t file_version[255]; - uint8_t file_version_len; -}; - static void *tall_ctx_config = NULL; -static struct sw_load *sw_load1 = NULL; -static struct sw_load *sw_load2 = NULL; +static struct abis_nm_sw_descr *sw_load1 = NULL; +static struct abis_nm_sw_descr *sw_load2 = NULL; /* static uint8_t prim_oml_attr[] = { 0x95, 0x00, 7, 0x88, 192, 168, 100, 11, 0x00, 0x00 }; @@ -344,19 +337,11 @@ msg->l3h = &msg->l2h[3]; /* activate software */ - if (sw_load1) { - msgb_v_put(msg, NM_ATT_SW_DESCR); - msgb_tl16v_put(msg, NM_ATT_FILE_ID, sw_load1->file_id_len, sw_load1->file_id); - msgb_tl16v_put(msg, NM_ATT_FILE_VERSION, sw_load1->file_version_len, - sw_load1->file_version); - } + if (sw_load1) + abis_nm_put_sw_descr(msg, sw_load1, true); - if (sw_load2) { - msgb_v_put(msg, NM_ATT_SW_DESCR); - msgb_tl16v_put(msg, NM_ATT_FILE_ID, sw_load2->file_id_len, sw_load2->file_id); - msgb_tl16v_put(msg, NM_ATT_FILE_VERSION, sw_load2->file_version_len, - sw_load2->file_version); - } + if (sw_load2) + abis_nm_put_sw_descr(msg, sw_load2, true); /* fill in the data */ msg->l2h[0] = NM_ATT_IPACC_CUR_SW_CFG; @@ -618,11 +603,11 @@ return 0; } -static struct sw_load *create_swload(struct sdp_header *header) +static struct abis_nm_sw_descr *create_swload(struct sdp_header *header) { - struct sw_load *load; + struct abis_nm_sw_descr *load; - load = talloc_zero(tall_ctx_config, struct sw_load); + load = talloc_zero(tall_ctx_config, struct abis_nm_sw_descr); strncpy((char *)load->file_id, header->firmware_info.sw_part, 20); load->file_id_len = strlen(header->firmware_info.sw_part) + 1; diff --git a/openbsc/src/libbsc/abis_nm.c b/openbsc/src/libbsc/abis_nm.c index 33a23a2..fb9c123 100644 --- a/openbsc/src/libbsc/abis_nm.c +++ b/openbsc/src/libbsc/abis_nm.c @@ -413,93 +413,50 @@ /* Activate the specified software into the BTS */ static int ipacc_sw_activate(struct gsm_bts *bts, uint8_t obj_class, uint8_t i0, uint8_t i1, - uint8_t i2, const uint8_t *sw_desc, uint8_t swdesc_len) + uint8_t i2, const struct abis_nm_sw_descr *sw_desc) { struct abis_om_hdr *oh; struct msgb *msg = nm_msgb_alloc(); - uint8_t len = swdesc_len; - uint8_t *trailer; + uint16_t len = abis_nm_sw_descr_len(sw_desc, true); oh = (struct abis_om_hdr *) msgb_put(msg, ABIS_OM_FOM_HDR_SIZE); fill_om_fom_hdr(oh, len, NM_MT_ACTIVATE_SW, obj_class, i0, i1, i2); - - trailer = msgb_put(msg, swdesc_len); - memcpy(trailer, sw_desc, swdesc_len); + abis_nm_put_sw_descr(msg, sw_desc, true); return abis_nm_sendmsg(bts, msg); } int abis_nm_parse_sw_config(const uint8_t *sw_descr, const size_t sw_descr_len, - struct abis_nm_sw_descr *desc, const int res_len) + struct abis_nm_sw_descr *desc, const int res_len) { - static const struct tlv_definition sw_descr_def = { - .def = { - [NM_ATT_FILE_ID] = { TLV_TYPE_TL16V, }, - [NM_ATT_FILE_VERSION] = { TLV_TYPE_TL16V, }, - }, - }; + int desc_pos, rc; + uint16_t i = 0; - size_t pos = 0; - int desc_pos = 0; - - for (pos = 0; pos < sw_descr_len && desc_pos < res_len; ++desc_pos) { - uint8_t tag; - uint16_t tag_len; - const uint8_t *val; - int len; - + for (desc_pos = 0; desc_pos < res_len; ++desc_pos) { memset(&desc[desc_pos], 0, sizeof(desc[desc_pos])); - desc[desc_pos].start = &sw_descr[pos]; + rc = abis_nm_get_sw_descr_one(&desc[desc_pos], sw_descr + i, + sw_descr_len - i); + i += abis_nm_get_sw_descr_len(sw_descr + i, sw_descr_len - i); + if (rc < 0) + return -EINVAL; - /* Classic TLV parsing doesn't work well with SW_DESCR because of it's - * nested nature and the fact you have to assume it contains only two sub - * tags NM_ATT_FILE_VERSION & NM_ATT_FILE_ID to parse it */ - if (sw_descr[pos] != NM_ATT_SW_DESCR) { - LOGP(DNM, LOGL_ERROR, - "SW_DESCR attribute identifier not found!\n"); - return -1; - } - - pos += 1; - len = tlv_parse_one(&tag, &tag_len, &val, - &sw_descr_def, &sw_descr[pos], sw_descr_len - pos); - if (len < 0 || (tag != NM_ATT_FILE_ID)) { - LOGP(DNM, LOGL_ERROR, - "FILE_ID attribute identifier not found!\n"); - return -2; - } - desc[desc_pos].file_id = val; - desc[desc_pos].file_id_len = tag_len; - pos += len; - - - len = tlv_parse_one(&tag, &tag_len, &val, - &sw_descr_def, &sw_descr[pos], sw_descr_len - pos); - if (len < 0 || (tag != NM_ATT_FILE_VERSION)) { - LOGP(DNM, LOGL_ERROR, - "FILE_VERSION attribute identifier not found!\n"); - return -3; - } - desc[desc_pos].file_ver = val; - desc[desc_pos].file_ver_len = tag_len; - pos += len; - - /* final size */ - desc[desc_pos].len = &sw_descr[pos] - desc[desc_pos].start; + if (i >= sw_descr_len) + return desc_pos + 1; } return desc_pos; } int abis_nm_select_newest_sw(const struct abis_nm_sw_descr *sw_descr, - const size_t size) + const size_t size) { int res = 0; int i; for (i = 1; i < size; ++i) { - if (memcmp(sw_descr[res].file_ver, sw_descr[i].file_ver, - OSMO_MIN(sw_descr[i].file_ver_len, sw_descr[res].file_ver_len)) < 0) { + if (memcmp(sw_descr[res].file_version, sw_descr[i].file_version, + OSMO_MIN(sw_descr[i].file_version_len, + sw_descr[res].file_version_len)) < 0) { res = i; } } @@ -560,7 +517,7 @@ foh->obj_inst.bts_nr, foh->obj_inst.trx_nr, foh->obj_inst.ts_nr, - sw_descr[ret].start, sw_descr[ret].len); + &sw_descr[ret]); } /* Receive a CHANGE_ADM_STATE_ACK, parse the TLV and update local state */ diff --git a/openbsc/tests/abis/abis_test.c b/openbsc/tests/abis/abis_test.c index 496267f..4043e3c 100644 --- a/openbsc/tests/abis/abis_test.c +++ b/openbsc/tests/abis/abis_test.c @@ -22,6 +22,7 @@ #include #include +#include #include #include @@ -51,23 +52,27 @@ static void test_simple_sw_config(void) { struct abis_nm_sw_descr descr[1]; + uint16_t len; int rc; rc = abis_nm_parse_sw_config(simple_config, ARRAY_SIZE(simple_config), &descr[0], ARRAY_SIZE(descr)); if (rc != 1) { - printf("FAILED to parse the File Id/File version\n"); + printf("%s(): FAILED to parse the File Id/File version: %d\n", + __func__, rc); abort(); } - if (descr[0].len != 13) { - printf("WRONG SIZE: %zu\n", descr[0].len); + len = abis_nm_sw_descr_len(&descr[0], true); + if (len != 13) { + printf("WRONG SIZE: %u\n", len); abort(); } - printf("Start: %td len: %zu\n", descr[0].start - simple_config, descr[0].len); + printf("len: %u\n", len); printf("file_id: %s\n", osmo_hexdump(descr[0].file_id, descr[0].file_id_len)); - printf("file_ver: %s\n", osmo_hexdump(descr[0].file_ver, descr[0].file_ver_len)); + printf("file_ver: %s\n", osmo_hexdump(descr[0].file_version, descr[0].file_version_len)); + printf("%s(): OK\n", __func__); } static void test_simple_sw_short(void) @@ -84,58 +89,68 @@ abort(); } } + printf("%s(): OK\n", __func__); } static void test_dual_sw_config(void) { struct abis_nm_sw_descr descr[2]; + uint16_t len0, len1; int rc; rc = abis_nm_parse_sw_config(dual_config, ARRAY_SIZE(dual_config), &descr[0], ARRAY_SIZE(descr)); if (rc != 2) { - printf("FAILED to parse the File Id/File version\n"); + printf("%s(): FAILED to parse the File Id/File version: %d (%d,%d)\n", + __func__, -rc, EBADF, EBADMSG); abort(); } - if (descr[0].len != 13) { - printf("WRONG SIZE0: %zu\n", descr[0].len); + len0 = abis_nm_sw_descr_len(&descr[0], true); + if (len0 != 13) { + printf("WRONG SIZE0: %u\n", len0); abort(); } - if (descr[1].len != 13) { - printf("WRONG SIZE1: %zu\n", descr[1].len); + len1 = abis_nm_sw_descr_len(&descr[1], true); + if (len1 != 13) { + printf("WRONG SIZE1: %u\n", len1); abort(); } - printf("Start: %td len: %zu\n", descr[0].start - dual_config, descr[0].len); + printf("len: %u\n", len0); printf("file_id: %s\n", osmo_hexdump(descr[0].file_id, descr[0].file_id_len)); - printf("file_ver: %s\n", osmo_hexdump(descr[0].file_ver, descr[0].file_ver_len)); + printf("file_ver: %s\n", osmo_hexdump(descr[0].file_version, descr[0].file_version_len)); - printf("Start: %td len: %zu\n", descr[1].start - dual_config, descr[1].len); + printf("len: %u\n", len1); printf("file_id: %s\n", osmo_hexdump(descr[1].file_id, descr[1].file_id_len)); - printf("file_ver: %s\n", osmo_hexdump(descr[1].file_ver, descr[1].file_ver_len)); + printf("file_ver: %s\n", osmo_hexdump(descr[1].file_version, descr[1].file_version_len)); + printf("%s(): OK\n", __func__); } static void test_sw_selection(void) { struct abis_nm_sw_descr descr[8], tmp; + uint16_t len0, len1; int rc, pos; rc = abis_nm_parse_sw_config(load_config, ARRAY_SIZE(load_config), &descr[0], ARRAY_SIZE(descr)); if (rc != 2) { - printf("FAILED to parse the File Id/File version\n"); + printf("%s(): FAILED to parse the File Id/File version: %d\n", + __func__, rc); abort(); } - printf("Start: %td len: %zu\n", descr[0].start - load_config, descr[0].len); + len0 = abis_nm_sw_descr_len(&descr[0], true); + printf("len: %u\n", len0); printf("file_id: %s\n", osmo_hexdump(descr[0].file_id, descr[0].file_id_len)); - printf("file_ver: %s\n", osmo_hexdump(descr[0].file_ver, descr[0].file_ver_len)); + printf("file_ver: %s\n", osmo_hexdump(descr[0].file_version, descr[0].file_version_len)); - printf("Start: %td len: %zu\n", descr[1].start - load_config, descr[1].len); + len1 = abis_nm_sw_descr_len(&descr[1], true); + printf("len: %u\n", len1); printf("file_id: %s\n", osmo_hexdump(descr[1].file_id, descr[1].file_id_len)); - printf("file_ver: %s\n", osmo_hexdump(descr[1].file_ver, descr[1].file_ver_len)); + printf("file_ver: %s\n", osmo_hexdump(descr[1].file_version, descr[1].file_version_len)); /* start */ pos = abis_nm_select_newest_sw(descr, rc); @@ -155,6 +170,7 @@ abort(); } printf("SELECTED: %d\n", pos); + printf("%s(): OK\n", __func__); } int main(int argc, char **argv) diff --git a/openbsc/tests/abis/abis_test.ok b/openbsc/tests/abis/abis_test.ok index 2f99f9d..7733429 100644 --- a/openbsc/tests/abis/abis_test.ok +++ b/openbsc/tests/abis/abis_test.ok @@ -1,17 +1,21 @@ -Start: 0 len: 13 +len: 13 file_id: 01 02 03 file_ver: 03 04 05 -Start: 0 len: 13 +test_simple_sw_config(): OK +test_simple_sw_short(): OK +len: 13 file_id: 01 02 03 file_ver: 03 04 05 -Start: 13 len: 13 +len: 13 file_id: 09 07 05 file_ver: 06 07 08 -Start: 0 len: 26 +test_dual_sw_config(): OK +len: 26 file_id: 31 36 38 64 34 37 32 00 file_ver: 76 32 30 30 62 31 34 33 64 30 00 -Start: 26 len: 26 +len: 26 file_id: 31 36 38 64 34 37 32 00 file_ver: 76 32 30 30 62 31 34 33 64 31 00 SELECTED: 1 SELECTED: 0 +test_sw_selection(): OK -- To view, visit https://gerrit.osmocom.org/2166 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ib94db414e94a2a1f234ac6f1cb346dca1c7a8be3 Gerrit-PatchSet: 4 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Apr 4 15:39:36 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Tue, 4 Apr 2017 15:39:36 +0000 Subject: [PATCH] libosmocore[master]: Add SW Description (de)marshalling In-Reply-To: References: Message-ID: Hello Neels Hofmeyr, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2165 to look at the new patch set (#10). Add SW Description (de)marshalling * data structure representing 3GPP TS 52.021 ?9.4.62 SW Description * function to serialize it into msgb * function to deserialize it from buffer * functions to extract/estimate buffer size for SW Description * test harness There are several similar functions to deal with SW Description in OpenBSC, there's also need to use similar functionality in OsmoBTS. Hence it's better to put the code into common library with proper tests and documentation. Change-Id: Ib63b6b5e83b8914864fc7edd789f8958cdc993cd Related: OS#1614 --- M include/osmocom/gsm/protocol/gsm_12_21.h M src/gsm/abis_nm.c M src/gsm/libosmogsm.map M tests/Makefile.am M tests/lapd/lapd_test.c M tests/lapd/lapd_test.ok 6 files changed, 285 insertions(+), 2 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/65/2165/10 diff --git a/include/osmocom/gsm/protocol/gsm_12_21.h b/include/osmocom/gsm/protocol/gsm_12_21.h index c88f0b1..427f472 100644 --- a/include/osmocom/gsm/protocol/gsm_12_21.h +++ b/include/osmocom/gsm/protocol/gsm_12_21.h @@ -29,6 +29,7 @@ /*! \file gsm_12_21.h */ #include +#include #include /*! \brief generic header in front of every OML message according to TS 08.59 */ @@ -791,6 +792,23 @@ IPAC_BINF_CELL_ALLOC = (1 << 2), }; +/*! \brief 3GPP TS 52.021 ?9.4.62 SW Description */ +struct abis_nm_sw_descr { + uint8_t file_id[UINT8_MAX]; + uint8_t file_id_len; + + uint8_t file_version[UINT8_MAX]; + uint8_t file_version_len; +}; + +uint16_t abis_nm_sw_descr_len(const struct abis_nm_sw_descr *sw, + bool put_sw_descr); +uint16_t abis_nm_put_sw_descr(struct msgb *msg, const struct abis_nm_sw_descr *sw, + bool put_sw_descr); +uint32_t abis_nm_get_sw_descr_len(const uint8_t * buf, size_t len); +int abis_nm_get_sw_conf(struct abis_nm_sw_descr *sw, uint16_t sw_len, + const uint8_t * buf, size_t buf_len); + struct msgb *abis_nm_fail_evt_rep(enum abis_nm_event_type t, enum abis_nm_severity s, enum abis_nm_pcause_type ct, diff --git a/src/gsm/abis_nm.c b/src/gsm/abis_nm.c index 934d7ce..e87188a 100644 --- a/src/gsm/abis_nm.c +++ b/src/gsm/abis_nm.c @@ -751,6 +751,148 @@ return nmsg; } +/*! \brief Compute length of given 3GPP TS 52.021 ?9.4.62 SW Description. + * \param[in] sw SW Description struct + * \param[in] put_sw_descr boolean, whether to put NM_ATT_SW_DESCR IE or not + * \returns length of buffer space necessary to store sw + */ +uint16_t abis_nm_sw_descr_len(const struct abis_nm_sw_descr *sw, + bool put_sw_descr) +{ + /* +3: type is 1-byte, length is 2-byte */ + return (put_sw_descr ? 1 : 0) + (sw->file_id_len + 3) + + (sw->file_version_len + 3); +} + +/*! \brief Put given 3GPP TS 52.021 ?9.4.62 SW Description into msgb. + * \param[out] msg message buffer + * \param[in] sw SW Description struct + * \param[in] put_sw_descr boolean, whether to put NM_ATT_SW_DESCR IE or not + * \param[in] simulate boolean, whether to actually modify msg or not + * \returns length of buffer space necessary to store sw + */ +uint16_t abis_nm_put_sw_descr(struct msgb *msg, const struct abis_nm_sw_descr *sw, + bool put_sw_descr) +{ + if (put_sw_descr) + msgb_v_put(msg, NM_ATT_SW_DESCR); + msgb_tl16v_put(msg, NM_ATT_FILE_ID, sw->file_id_len, sw->file_id); + msgb_tl16v_put(msg, NM_ATT_FILE_VERSION, sw->file_version_len, + sw->file_version); + + return abis_nm_sw_descr_len(sw, put_sw_descr); +} + +/*! \brief Get length of first 3GPP TS 52.021 ?9.4.62 SW Description from buffer. + * \param[in] buf buffer, may contain several SW Descriptions + * \param[in] len buffer length + * \returns length if parsing succeeded, 0 otherwise + */ +uint32_t abis_nm_get_sw_descr_len(const uint8_t *buf, size_t len) +{ + uint16_t sw = 2; /* 1-byte SW tag + 1-byte FILE_* tag */ + + if (buf[0] != NM_ATT_SW_DESCR) + sw = 1; /* 1-byte FILE_* tag */ + + if (buf[sw - 1] != NM_ATT_FILE_ID && buf[sw - 1] != NM_ATT_FILE_VERSION) + return 0; + + /* + length of 1st FILE_* element + 1-byte tag + 2-byte length field of + 1st FILE_* element */ + sw += (osmo_load16be(buf + sw) + 3); + + /* + length of 2nd FILE_* element */ + sw += osmo_load16be(buf + sw); + + return sw + 2; /* + 2-byte length field of 2nd FILE_* element */ +} + +/*! \brief Parse single 3GPP TS 52.021 ?9.4.62 SW Description from buffer. + * \param[out] sw SW Description struct + * \param[in] buf buffer + * \param[in] len buffer length + * \returns 0 if parsing succeeded, negative error code otherwise + */ +static inline int abis_nm_get_sw_descr(struct abis_nm_sw_descr *sw, + const uint8_t *buf, size_t length) +{ + int rc; + uint32_t len = abis_nm_get_sw_descr_len(buf, length); + static struct tlv_parsed tp; + const struct tlv_definition sw_tlvdef = { + .def = { + [NM_ATT_SW_DESCR] = { TLV_TYPE_TV }, + [NM_ATT_FILE_ID] = { TLV_TYPE_TL16V }, + [NM_ATT_FILE_VERSION] = { TLV_TYPE_TL16V }, + }, + }; + + /* Basic sanity check */ + if (len > length) + return -EFBIG; + + /* Note: current implementation of TLV parser fails on multilpe SW Descr: + we will only parse the first one */ + if (!len) + return -EINVAL; + + /* Note: the return value is ignored here because SW Description tag + itself is considered optional. */ + tlv_parse(&tp, &sw_tlvdef, buf, len, 0, 0); + + /* Parsing SW Description is tricky for current implementation of TLV + parser which fails to properly handle TV when V has following + structure: | TL16V | TL16V |. Hence, the need for 2nd call: */ + rc = tlv_parse(&tp, &sw_tlvdef, buf + TLVP_LEN(&tp, NM_ATT_SW_DESCR), + len - TLVP_LEN(&tp, NM_ATT_SW_DESCR), 0, 0); + + if (rc < 0) + return rc; + + if (!TLVP_PRESENT(&tp, NM_ATT_FILE_ID)) + return -EBADF; + + if (!TLVP_PRESENT(&tp, NM_ATT_FILE_VERSION)) + return -EBADMSG; + + sw->file_id_len = TLVP_LEN(&tp, NM_ATT_FILE_ID); + sw->file_version_len = TLVP_LEN(&tp, NM_ATT_FILE_VERSION); + + memcpy(sw->file_id, TLVP_VAL(&tp, NM_ATT_FILE_ID), sw->file_id_len); + memcpy(sw->file_version, TLVP_VAL(&tp, NM_ATT_FILE_VERSION), + sw->file_version_len); + + return 0; +} + +/*! \brief Parse 3GPP TS 52.021 ?9.4.61 SW Configuration from buffer. + * \param[out] sw SW Description struct array + * \param[in] sw_len Expected number of SW Description entries + * \param[in] buf buffer + * \param[in] buf_len buffer length + * \returns 0 if parsing succeeded, negative error code otherwise + */ +int abis_nm_get_sw_conf(struct abis_nm_sw_descr *sw, uint16_t sw_len, + const uint8_t * buf, size_t buf_len) +{ + int rc; + uint16_t len = 0, i; + for (i = 0; i < sw_len; i++) { + memset(&sw[i], 0, sizeof(sw[i])); + rc = abis_nm_get_sw_descr(&sw[i], buf + len, buf_len - len); + if (rc < 0) + return rc; + + len += abis_nm_get_sw_descr_len(buf + len, buf_len - len); + + if (len >= buf_len) + return i + 1; + } + + return i; +} + /*! \brief Obtain OML Channel Combination for phnsical channel config */ int abis_nm_chcomb4pchan(enum gsm_phys_chan_config pchan) { diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map index 5649e71..f9c75c3 100644 --- a/src/gsm/libosmogsm.map +++ b/src/gsm/libosmogsm.map @@ -31,6 +31,10 @@ abis_nm_pcause_type_names; abis_nm_msgtype_names; abis_nm_att_names; +abis_nm_sw_descr_len; +abis_nm_put_sw_descr; +abis_nm_get_sw_conf; +abis_nm_get_sw_descr_len; osmo_sitype_strs; osmo_c4; diff --git a/tests/Makefile.am b/tests/Makefile.am index 352b5a7..16b45ea 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -74,7 +74,7 @@ lapd_lapd_test_LDADD = $(top_builddir)/src/libosmocore.la $(top_builddir)/src/gsm/libosmogsm.la msgb_msgb_test_SOURCES = msgb/msgb_test.c -msgb_msgb_test_LDADD = $(top_builddir)/src/libosmocore.la +msgb_msgb_test_LDADD = $(top_builddir)/src/libosmocore.la $(top_builddir)/src/gsm/libosmogsm.la msgfile_msgfile_test_SOURCES = msgfile/msgfile_test.c msgfile_msgfile_test_LDADD = $(top_builddir)/src/libosmocore.la diff --git a/tests/lapd/lapd_test.c b/tests/lapd/lapd_test.c index e322314..d49f818 100644 --- a/tests/lapd/lapd_test.c +++ b/tests/lapd/lapd_test.c @@ -25,9 +25,10 @@ #include #include #include +#include #include - +#include #include #define CHECK_RC(rc) \ @@ -752,6 +753,94 @@ lapdm_channel_exit(&bts_to_ms_channel); } +static inline void print_chk(const char *what, uint8_t len1, uint8_t len2, + const uint8_t *x1, const uint8_t *x2) +{ + int cmp = memcmp(x1, x2, len2); + printf("\tFILE %s [%u == %u -> %d, %s] %d => %s\n", what, len1, len2, + len1 == len2, len1 != len2 ? "fail" : "ok", + cmp, cmp != 0 ? "FAIL" : "OK"); +} + +static inline void chk_descr(struct msgb *msg, struct abis_nm_sw_descr *put, + const char *descr, bool header) +{ + int res; + struct abis_nm_sw_descr sw = { 0 }; + uint16_t len = abis_nm_put_sw_descr(msg, put, header); + + printf("msgb[%u] :: {msgb->len} %u == %u {len} - %s]:\n\t" + "SW DESCR (%s)\n\t" + "length: {extracted} %u = %u {expected} - %s, failsafe - %s\n", + msg->data_len, msg->len, len, len != msg->len ? "fail" : "ok", + descr, abis_nm_get_sw_descr_len(msgb_data(msg), msg->len), + msg->len, + abis_nm_get_sw_descr_len(msgb_data(msg), msg->len) != msg->len ? "FAIL" : "OK", + len > put->file_version_len + put->file_id_len ? "OK" : "FAIL"); + + res = abis_nm_get_sw_conf(&sw, 1, msgb_data(msg), msg->len); + if (res < 0) + printf("\tSW DESCR (%s) parsing error code %d!\n", descr, -res); + else { + print_chk("ID", sw.file_id_len, put->file_id_len, sw.file_id, + put->file_id); + print_chk("VERSION", sw.file_version_len, + put->file_version_len, sw.file_version, + put->file_version); + } +} + +static inline void chk_raw(const char *what, const uint8_t *data, uint16_t len) +{ + struct abis_nm_sw_descr sw = { 0 }; + int res = abis_nm_get_sw_conf(&sw, 1, data, len); + uint16_t xlen = abis_nm_get_sw_descr_len(data, len); + + printf("parsing chained %s <1st: %d, total: %d>\n\tSW Descr (%s)\n", + osmo_hexdump(data, len), xlen, len, what); + + if (res < 0) + printf("\tFAIL: %d\n", -res); + else { + printf("\tFILE ID: [%d] %s => OK\n", sw.file_id_len, + osmo_hexdump(sw.file_id, sw.file_id_len)); + printf("\tFILE VERSION: [%d] %s => OK\n", sw.file_version_len, + osmo_hexdump(sw.file_version, sw.file_version_len)); + } + + if (len != xlen) + chk_raw(" 2nd", data + xlen, len - xlen); +} + +static void test_sw_descr() +{ + const char *f_id = "TEST.L0L", *f_ver = "0.1.666~deadbeeffacefeed-dirty"; + uint8_t lf_id = strlen(f_id), lf_ver = strlen(f_ver); + uint8_t chain[] = { 0x42, 0x12, 0x00, 0x03, 0x01, 0x02, 0x03, 0x13, 0x00, 0x03, 0x03, 0x04, 0x05, 0x42, 0x12, 0x00, 0x03, 0x09, 0x07, 0x05, 0x13, 0x00, 0x03, 0x06, 0x07, 0x08 }; + struct msgb *msg = msgb_alloc_headroom(4096, 128, "sw"); + struct abis_nm_sw_descr sw_put = { + .file_id_len = lf_id, + .file_version_len = lf_ver, + }; + + printf("\nI test SW Description (de)serialization:\n"); + + memcpy(sw_put.file_id, f_id, lf_id); + memcpy(sw_put.file_version, f_ver, lf_ver); + + /* check that parsing |SW|ID|VER| works: */ + chk_descr(msg, &sw_put, "with header", true); + msgb_reset(msg); + /* check that parsing |ID|VER| works: */ + chk_descr(msg, &sw_put, "without header", false); + /* check that parsing |ID|VER|SW|ID|VER| fails - notice the lack of + msgb_reset() to create bogus msgb data: */ + chk_descr(msg, &sw_put, "expected failure", true); + /* check multiple, chained SW-descr: */ + chk_raw("half", chain, sizeof(chain) / 2); + chk_raw("full", chain, sizeof(chain)); +} + int main(int argc, char **argv) { osmo_init_logging(&info); @@ -765,6 +854,7 @@ test_lapdm_contention_resolution(); test_lapdm_establishment(); test_lapdm_desync(); + test_sw_descr(); printf("Success.\n"); diff --git a/tests/lapd/lapd_test.ok b/tests/lapd/lapd_test.ok index e188e27..682b397 100644 --- a/tests/lapd/lapd_test.ok +++ b/tests/lapd/lapd_test.ok @@ -96,4 +96,33 @@ Took message from DCCH queue: L2 header size 23, L3 size 0, SAP 0x1000000, 0/0, Link 0x03 Message: [L2]> 0d 21 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b + +I test SW Description (de)serialization: +msgb[4096] :: {msgb->len} 45 == 45 {len} - ok]: + SW DESCR (with header) + length: {extracted} 45 = 45 {expected} - OK, failsafe - OK + FILE ID [8 == 8 -> 1, ok] 0 => OK + FILE VERSION [30 == 30 -> 1, ok] 0 => OK +msgb[4096] :: {msgb->len} 44 == 44 {len} - ok]: + SW DESCR (without header) + length: {extracted} 44 = 44 {expected} - OK, failsafe - OK + FILE ID [8 == 8 -> 1, ok] 0 => OK + FILE VERSION [30 == 30 -> 1, ok] 0 => OK +msgb[4096] :: {msgb->len} 89 == 45 {len} - fail]: + SW DESCR (expected failure) + length: {extracted} 44 = 89 {expected} - FAIL, failsafe - OK + FILE ID [8 == 8 -> 1, ok] 0 => OK + FILE VERSION [30 == 30 -> 1, ok] 0 => OK +parsing chained 42 12 00 03 01 02 03 13 00 03 03 04 05 <1st: 13, total: 13> + SW Descr (half) + FILE ID: [3] 01 02 03 => OK + FILE VERSION: [3] 03 04 05 => OK +parsing chained 42 12 00 03 01 02 03 13 00 03 03 04 05 42 12 00 03 09 07 05 13 00 03 06 07 08 <1st: 13, total: 26> + SW Descr (full) + FILE ID: [3] 01 02 03 => OK + FILE VERSION: [3] 03 04 05 => OK +parsing chained 42 12 00 03 09 07 05 13 00 03 06 07 08 <1st: 13, total: 13> + SW Descr ( 2nd) + FILE ID: [3] 09 07 05 => OK + FILE VERSION: [3] 06 07 08 => OK Success. -- To view, visit https://gerrit.osmocom.org/2165 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ib63b6b5e83b8914864fc7edd789f8958cdc993cd Gerrit-PatchSet: 10 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Tue Apr 4 15:42:35 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Tue, 4 Apr 2017 15:42:35 +0000 Subject: osmo-gsm-manuals[master]: gb.adoc: Add info to NS-over-UDP example In-Reply-To: References: Message-ID: Patch Set 1: (1 comment) https://gerrit.osmocom.org/#/c/2223/1/common/chapters/gb.adoc File common/chapters/gb.adoc: Line 24: incoming connections from PCUs on the specified address and port. I doubt that we really support multiple PCUs ATM so I think it's better to use singular in here. -- To view, visit https://gerrit.osmocom.org/2223 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I5b6d2fb284336614da28e0d1b01c7e8c26725f81 Gerrit-PatchSet: 1 Gerrit-Project: osmo-gsm-manuals Gerrit-Branch: master Gerrit-Owner: Pau Espin Pedrol Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Tue Apr 4 16:27:19 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Tue, 4 Apr 2017 16:27:19 +0000 Subject: [PATCH] libosmocore[master]: Add SW Description (de)marshalling In-Reply-To: References: Message-ID: Hello Neels Hofmeyr, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2165 to look at the new patch set (#11). Add SW Description (de)marshalling * data structure representing 3GPP TS 52.021 ?9.4.62 SW Description * function to serialize it into msgb * function to deserialize it from buffer * functions to extract/estimate buffer size for SW Description * test harness (partially taken from OpenBSC) There are several similar functions to deal with SW Description in OpenBSC, there's also need to use similar functionality in OsmoBTS. Hence it's better to put the code into common library with proper tests and documentation. Change-Id: Ib63b6b5e83b8914864fc7edd789f8958cdc993cd Related: OS#1614 --- M .gitignore M include/osmocom/gsm/protocol/gsm_12_21.h M src/gsm/abis_nm.c M src/gsm/libosmogsm.map M tests/Makefile.am A tests/abis/abis_test.c A tests/abis/abis_test.ok M tests/testsuite.at 8 files changed, 436 insertions(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/65/2165/11 diff --git a/.gitignore b/.gitignore index ecbcedd..4c6a78f 100644 --- a/.gitignore +++ b/.gitignore @@ -60,6 +60,7 @@ tests/testsuite tests/testsuite.dir/ tests/testsuite.log +tests/abis/abis_test tests/ctrl/ctrl_test tests/utils/utils_test tests/stats/stats_test diff --git a/include/osmocom/gsm/protocol/gsm_12_21.h b/include/osmocom/gsm/protocol/gsm_12_21.h index c88f0b1..09d8432 100644 --- a/include/osmocom/gsm/protocol/gsm_12_21.h +++ b/include/osmocom/gsm/protocol/gsm_12_21.h @@ -29,6 +29,7 @@ /*! \file gsm_12_21.h */ #include +#include #include /*! \brief generic header in front of every OML message according to TS 08.59 */ @@ -791,6 +792,22 @@ IPAC_BINF_CELL_ALLOC = (1 << 2), }; +/*! \brief 3GPP TS 52.021 ?9.4.62 SW Description */ +struct abis_nm_sw_descr { + uint8_t file_id[UINT8_MAX]; + uint8_t file_id_len; + + uint8_t file_version[UINT8_MAX]; + uint8_t file_version_len; +}; + +uint16_t abis_nm_sw_descr_len(const struct abis_nm_sw_descr *sw, + bool put_sw_descr); +uint16_t abis_nm_put_sw_descr(struct msgb *msg, const struct abis_nm_sw_descr *sw, + bool put_sw_descr); +uint32_t abis_nm_get_sw_descr_len(const uint8_t * buf, size_t len); +int abis_nm_get_sw_conf(const uint8_t * buf, size_t buf_len, + struct abis_nm_sw_descr *sw, uint16_t sw_len); struct msgb *abis_nm_fail_evt_rep(enum abis_nm_event_type t, enum abis_nm_severity s, enum abis_nm_pcause_type ct, diff --git a/src/gsm/abis_nm.c b/src/gsm/abis_nm.c index 934d7ce..4acd322 100644 --- a/src/gsm/abis_nm.c +++ b/src/gsm/abis_nm.c @@ -751,6 +751,148 @@ return nmsg; } +/*! \brief Compute length of given 3GPP TS 52.021 ?9.4.62 SW Description. + * \param[in] sw SW Description struct + * \param[in] put_sw_descr boolean, whether to put NM_ATT_SW_DESCR IE or not + * \returns length of buffer space necessary to store sw + */ +uint16_t abis_nm_sw_descr_len(const struct abis_nm_sw_descr *sw, + bool put_sw_descr) +{ + /* +3: type is 1-byte, length is 2-byte */ + return (put_sw_descr ? 1 : 0) + (sw->file_id_len + 3) + + (sw->file_version_len + 3); +} + +/*! \brief Put given 3GPP TS 52.021 ?9.4.62 SW Description into msgb. + * \param[out] msg message buffer + * \param[in] sw SW Description struct + * \param[in] put_sw_descr boolean, whether to put NM_ATT_SW_DESCR IE or not + * \param[in] simulate boolean, whether to actually modify msg or not + * \returns length of buffer space necessary to store sw + */ +uint16_t abis_nm_put_sw_descr(struct msgb *msg, const struct abis_nm_sw_descr *sw, + bool put_sw_descr) +{ + if (put_sw_descr) + msgb_v_put(msg, NM_ATT_SW_DESCR); + msgb_tl16v_put(msg, NM_ATT_FILE_ID, sw->file_id_len, sw->file_id); + msgb_tl16v_put(msg, NM_ATT_FILE_VERSION, sw->file_version_len, + sw->file_version); + + return abis_nm_sw_descr_len(sw, put_sw_descr); +} + +/*! \brief Get length of first 3GPP TS 52.021 ?9.4.62 SW Description from buffer. + * \param[in] buf buffer, may contain several SW Descriptions + * \param[in] len buffer length + * \returns length if parsing succeeded, 0 otherwise + */ +uint32_t abis_nm_get_sw_descr_len(const uint8_t *buf, size_t len) +{ + uint16_t sw = 2; /* 1-byte SW tag + 1-byte FILE_* tag */ + + if (buf[0] != NM_ATT_SW_DESCR) + sw = 1; /* 1-byte FILE_* tag */ + + if (buf[sw - 1] != NM_ATT_FILE_ID && buf[sw - 1] != NM_ATT_FILE_VERSION) + return 0; + + /* + length of 1st FILE_* element + 1-byte tag + 2-byte length field of + 1st FILE_* element */ + sw += (osmo_load16be(buf + sw) + 3); + + /* + length of 2nd FILE_* element */ + sw += osmo_load16be(buf + sw); + + return sw + 2; /* + 2-byte length field of 2nd FILE_* element */ +} + +/*! \brief Parse single 3GPP TS 52.021 ?9.4.62 SW Description from buffer. + * \param[out] sw SW Description struct + * \param[in] buf buffer + * \param[in] len buffer length + * \returns 0 if parsing succeeded, negative error code otherwise + */ +static inline int abis_nm_get_sw_descr(struct abis_nm_sw_descr *sw, + const uint8_t *buf, size_t length) +{ + int rc; + uint32_t len = abis_nm_get_sw_descr_len(buf, length); + static struct tlv_parsed tp; + const struct tlv_definition sw_tlvdef = { + .def = { + [NM_ATT_SW_DESCR] = { TLV_TYPE_TV }, + [NM_ATT_FILE_ID] = { TLV_TYPE_TL16V }, + [NM_ATT_FILE_VERSION] = { TLV_TYPE_TL16V }, + }, + }; + + /* Basic sanity check */ + if (len > length) + return -EFBIG; + + /* Note: current implementation of TLV parser fails on multilpe SW Descr: + we will only parse the first one */ + if (!len) + return -EINVAL; + + /* Note: the return value is ignored here because SW Description tag + itself is considered optional. */ + tlv_parse(&tp, &sw_tlvdef, buf, len, 0, 0); + + /* Parsing SW Description is tricky for current implementation of TLV + parser which fails to properly handle TV when V has following + structure: | TL16V | TL16V |. Hence, the need for 2nd call: */ + rc = tlv_parse(&tp, &sw_tlvdef, buf + TLVP_LEN(&tp, NM_ATT_SW_DESCR), + len - TLVP_LEN(&tp, NM_ATT_SW_DESCR), 0, 0); + + if (rc < 0) + return rc; + + if (!TLVP_PRESENT(&tp, NM_ATT_FILE_ID)) + return -EBADF; + + if (!TLVP_PRESENT(&tp, NM_ATT_FILE_VERSION)) + return -EBADMSG; + + sw->file_id_len = TLVP_LEN(&tp, NM_ATT_FILE_ID); + sw->file_version_len = TLVP_LEN(&tp, NM_ATT_FILE_VERSION); + + memcpy(sw->file_id, TLVP_VAL(&tp, NM_ATT_FILE_ID), sw->file_id_len); + memcpy(sw->file_version, TLVP_VAL(&tp, NM_ATT_FILE_VERSION), + sw->file_version_len); + + return 0; +} + +/*! \brief Parse 3GPP TS 52.021 ?9.4.61 SW Configuration from buffer. + * \param[in] buf buffer + * \param[in] buf_len buffer length + * \param[out] sw SW Description struct array + * \param[in] sw_len Expected number of SW Description entries + * \returns 0 if parsing succeeded, negative error code otherwise + */ +int abis_nm_get_sw_conf(const uint8_t * buf, size_t buf_len, + struct abis_nm_sw_descr *sw, uint16_t sw_len) +{ + int rc; + uint16_t len = 0, i; + for (i = 0; i < sw_len; i++) { + memset(&sw[i], 0, sizeof(sw[i])); + rc = abis_nm_get_sw_descr(&sw[i], buf + len, buf_len - len); + if (rc < 0) + return rc; + + len += abis_nm_get_sw_descr_len(buf + len, buf_len - len); + + if (len >= buf_len) + return i + 1; + } + + return i; +} + /*! \brief Obtain OML Channel Combination for phnsical channel config */ int abis_nm_chcomb4pchan(enum gsm_phys_chan_config pchan) { diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map index 5649e71..f9c75c3 100644 --- a/src/gsm/libosmogsm.map +++ b/src/gsm/libosmogsm.map @@ -31,6 +31,10 @@ abis_nm_pcause_type_names; abis_nm_msgtype_names; abis_nm_att_names; +abis_nm_sw_descr_len; +abis_nm_put_sw_descr; +abis_nm_get_sw_conf; +abis_nm_get_sw_descr_len; osmo_sitype_strs; osmo_c4; diff --git a/tests/Makefile.am b/tests/Makefile.am index 352b5a7..a50e6b2 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -15,7 +15,7 @@ bitvec/bitvec_test msgb/msgb_test bits/bitcomp_test \ tlv/tlv_test gsup/gsup_test oap/oap_test fsm/fsm_test \ write_queue/wqueue_test socket/socket_test \ - coding/coding_test + coding/coding_test abis/abis_test if ENABLE_MSGFILE check_PROGRAMS += msgfile/msgfile_test @@ -43,6 +43,9 @@ auth_milenage_test_SOURCES = auth/milenage_test.c auth_milenage_test_LDADD = $(top_builddir)/src/libosmocore.la $(top_builddir)/src/gsm/libosmogsm.la +abis_abis_test_SOURCES = abis/abis_test.c +abis_abis_test_LDADD = $(top_builddir)/src/libosmocore.la $(top_builddir)/src/gsm/libosmogsm.la + ctrl_ctrl_test_SOURCES = ctrl/ctrl_test.c ctrl_ctrl_test_LDADD = $(top_builddir)/src/libosmocore.la $(top_builddir)/src/ctrl/libosmoctrl.la diff --git a/tests/abis/abis_test.c b/tests/abis/abis_test.c new file mode 100644 index 0000000..beb50f2 --- /dev/null +++ b/tests/abis/abis_test.c @@ -0,0 +1,221 @@ +/* + * (C) 2012 by Holger Hans Peter Freyther + * (C) 2017 by sysmocom s.m.f.c. GmbH + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +static struct log_info info = {}; + +static const uint8_t simple_config[] = { 66, 18, 0, 3, 1, 2, 3, 19, 0, 3, 3, 4, 5 }; + +static const uint8_t dual_config[] = { + 66, 18, 0, 3, 1, 2, 3, 19, 0, 3, 3, 4, 5, + 66, 18, 0, 3, 9, 7, 5, 19, 0, 3, 6, 7, 8, +}; + +static void test_simple_sw_config(void) +{ + struct abis_nm_sw_descr descr[1]; + uint16_t len; + int rc; + + rc = abis_nm_get_sw_conf(simple_config, ARRAY_SIZE(simple_config), + &descr[0], ARRAY_SIZE(descr)); + if (rc != 1) { + printf("%s(): FAILED to parse the File Id/File version: %d\n", + __func__, rc); + abort(); + } + + len = abis_nm_sw_descr_len(&descr[0], true); + if (len != 13) { + printf("WRONG SIZE: %u\n", len); + abort(); + } + + printf("len: %u\n", len); + printf("file_id: %s\n", osmo_hexdump(descr[0].file_id, descr[0].file_id_len)); + printf("file_ver: %s\n", osmo_hexdump(descr[0].file_version, descr[0].file_version_len)); + printf("%s(): OK\n", __func__); +} + +static void test_simple_sw_short(void) +{ + struct abis_nm_sw_descr descr[1]; + int i; + + for (i = 1; i < ARRAY_SIZE(simple_config); ++i) { + int rc = abis_nm_get_sw_conf(simple_config, + ARRAY_SIZE(simple_config) - i, &descr[0], + ARRAY_SIZE(descr)); + if (rc >= 1) { + printf("SHOULD not have parsed: %d\n", rc); + abort(); + } + } + printf("%s(): OK\n", __func__); +} + +static void test_dual_sw_config(void) +{ + struct abis_nm_sw_descr descr[2]; + uint16_t len0, len1; + int rc; + + rc = abis_nm_get_sw_conf(dual_config, ARRAY_SIZE(dual_config), + &descr[0], ARRAY_SIZE(descr)); + if (rc != 2) { + printf("%s(): FAILED to parse the File Id/File version: %d (%d,%d)\n", + __func__, -rc, EBADF, EBADMSG); + abort(); + } + + len0 = abis_nm_sw_descr_len(&descr[0], true); + if (len0 != 13) { + printf("WRONG SIZE0: %u\n", len0); + abort(); + } + + len1 = abis_nm_sw_descr_len(&descr[1], true); + if (len1 != 13) { + printf("WRONG SIZE1: %u\n", len1); + abort(); + } + + printf("len: %u\n", len0); + printf("file_id: %s\n", osmo_hexdump(descr[0].file_id, descr[0].file_id_len)); + printf("file_ver: %s\n", osmo_hexdump(descr[0].file_version, descr[0].file_version_len)); + + printf("len: %u\n", len1); + printf("file_id: %s\n", osmo_hexdump(descr[1].file_id, descr[1].file_id_len)); + printf("file_ver: %s\n", osmo_hexdump(descr[1].file_version, descr[1].file_version_len)); + printf("%s(): OK\n", __func__); +} + +static inline void print_chk(const char *what, uint8_t len1, uint8_t len2, + const uint8_t *x1, const uint8_t *x2) +{ + int cmp = memcmp(x1, x2, len2); + printf("\tFILE %s [%u == %u -> %d, %s] %d => %s\n", what, len1, len2, + len1 == len2, len1 != len2 ? "fail" : "ok", + cmp, cmp != 0 ? "FAIL" : "OK"); +} + +static inline void chk_descr(struct msgb *msg, struct abis_nm_sw_descr *put, + const char *descr, bool header) +{ + int res; + struct abis_nm_sw_descr sw = { 0 }; + uint16_t len = abis_nm_put_sw_descr(msg, put, header); + + printf("msgb[%u] :: {msgb->len} %u == %u {len} - %s]:\n\t" + "SW DESCR (%s)\n\t" + "length: {extracted} %u = %u {expected} - %s, failsafe - %s\n", + msg->data_len, msg->len, len, len != msg->len ? "fail" : "ok", + descr, abis_nm_get_sw_descr_len(msgb_data(msg), msg->len), + msg->len, + abis_nm_get_sw_descr_len(msgb_data(msg), msg->len) != msg->len ? "FAIL" : "OK", + len > put->file_version_len + put->file_id_len ? "OK" : "FAIL"); + + res = abis_nm_get_sw_conf(msgb_data(msg), msg->len, &sw, 1); + if (res < 0) + printf("\tSW DESCR (%s) parsing error code %d!\n", descr, -res); + else { + print_chk("ID", sw.file_id_len, put->file_id_len, sw.file_id, + put->file_id); + print_chk("VERSION", sw.file_version_len, + put->file_version_len, sw.file_version, + put->file_version); + } +} + +static inline void chk_raw(const char *what, const uint8_t *data, uint16_t len) +{ + struct abis_nm_sw_descr sw = { 0 }; + int res = abis_nm_get_sw_conf(data, len, &sw, 1); + uint16_t xlen = abis_nm_get_sw_descr_len(data, len); + + printf("parsing chained %s <1st: %d, total: %d>\n\tSW Descr (%s)\n", + osmo_hexdump(data, len), xlen, len, what); + + if (res < 0) + printf("\tFAIL: %d\n", -res); + else { + printf("\tFILE ID: [%d] %s => OK\n", sw.file_id_len, + osmo_hexdump(sw.file_id, sw.file_id_len)); + printf("\tFILE VERSION: [%d] %s => OK\n", sw.file_version_len, + osmo_hexdump(sw.file_version, sw.file_version_len)); + } + + if (len != xlen) + chk_raw(" 2nd", data + xlen, len - xlen); +} + +static void test_sw_descr() +{ + const char *f_id = "TEST.L0L", *f_ver = "0.1.666~deadbeeffacefeed-dirty"; + uint8_t lf_id = strlen(f_id), lf_ver = strlen(f_ver); + uint8_t chain[] = { 0x42, 0x12, 0x00, 0x03, 0x01, 0x02, 0x03, 0x13, 0x00, 0x03, 0x03, 0x04, 0x05, 0x42, 0x12, 0x00, 0x03, 0x09, 0x07, 0x05, 0x13, 0x00, 0x03, 0x06, 0x07, 0x08 }; + struct msgb *msg = msgb_alloc_headroom(4096, 128, "sw"); + struct abis_nm_sw_descr sw_put = { + .file_id_len = lf_id, + .file_version_len = lf_ver, + }; + + printf("Testing SW Description (de)serialization...\n"); + + memcpy(sw_put.file_id, f_id, lf_id); + memcpy(sw_put.file_version, f_ver, lf_ver); + + /* check that parsing |SW|ID|VER| works: */ + chk_descr(msg, &sw_put, "with header", true); + msgb_reset(msg); + /* check that parsing |ID|VER| works: */ + chk_descr(msg, &sw_put, "without header", false); + /* check that parsing |ID|VER|SW|ID|VER| fails - notice the lack of + msgb_reset() to create bogus msgb data: */ + chk_descr(msg, &sw_put, "expected failure", true); + /* check multiple, chained SW-descr: */ + chk_raw("half", chain, sizeof(chain) / 2); + chk_raw("full", chain, sizeof(chain)); +} + +int main(int argc, char **argv) +{ + osmo_init_logging(&info); + + test_sw_descr(); + test_simple_sw_config(); + test_simple_sw_short(); + test_dual_sw_config(); + + printf("OK.\n"); + + return 0; +} diff --git a/tests/abis/abis_test.ok b/tests/abis/abis_test.ok new file mode 100644 index 0000000..e6b626b --- /dev/null +++ b/tests/abis/abis_test.ok @@ -0,0 +1,41 @@ +Testing SW Description (de)serialization... +msgb[4096] :: {msgb->len} 45 == 45 {len} - ok]: + SW DESCR (with header) + length: {extracted} 45 = 45 {expected} - OK, failsafe - OK + FILE ID [8 == 8 -> 1, ok] 0 => OK + FILE VERSION [30 == 30 -> 1, ok] 0 => OK +msgb[4096] :: {msgb->len} 44 == 44 {len} - ok]: + SW DESCR (without header) + length: {extracted} 44 = 44 {expected} - OK, failsafe - OK + FILE ID [8 == 8 -> 1, ok] 0 => OK + FILE VERSION [30 == 30 -> 1, ok] 0 => OK +msgb[4096] :: {msgb->len} 89 == 45 {len} - fail]: + SW DESCR (expected failure) + length: {extracted} 44 = 89 {expected} - FAIL, failsafe - OK + FILE ID [8 == 8 -> 1, ok] 0 => OK + FILE VERSION [30 == 30 -> 1, ok] 0 => OK +parsing chained 42 12 00 03 01 02 03 13 00 03 03 04 05 <1st: 13, total: 13> + SW Descr (half) + FILE ID: [3] 01 02 03 => OK + FILE VERSION: [3] 03 04 05 => OK +parsing chained 42 12 00 03 01 02 03 13 00 03 03 04 05 42 12 00 03 09 07 05 13 00 03 06 07 08 <1st: 13, total: 26> + SW Descr (full) + FILE ID: [3] 01 02 03 => OK + FILE VERSION: [3] 03 04 05 => OK +parsing chained 42 12 00 03 09 07 05 13 00 03 06 07 08 <1st: 13, total: 13> + SW Descr ( 2nd) + FILE ID: [3] 09 07 05 => OK + FILE VERSION: [3] 06 07 08 => OK +len: 13 +file_id: 01 02 03 +file_ver: 03 04 05 +test_simple_sw_config(): OK +test_simple_sw_short(): OK +len: 13 +file_id: 01 02 03 +file_ver: 03 04 05 +len: 13 +file_id: 09 07 05 +file_ver: 06 07 08 +test_dual_sw_config(): OK +OK. diff --git a/tests/testsuite.at b/tests/testsuite.at index 64df724..7ee0164 100644 --- a/tests/testsuite.at +++ b/tests/testsuite.at @@ -9,6 +9,12 @@ AT_CHECK([$abs_top_builddir/tests/a5/a5_test], [0], [expout]) AT_CLEANUP +AT_SETUP([abis]) +AT_KEYWORDS([abis]) +cat $abs_srcdir/abis/abis_test.ok > expout +AT_CHECK([$abs_top_builddir/tests/abis/abis_test], [0], [expout], [ignore]) +AT_CLEANUP + AT_SETUP([ctrl]) AT_KEYWORDS([ctrl]) cat $abs_srcdir/ctrl/ctrl_test.ok > expout -- To view, visit https://gerrit.osmocom.org/2165 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ib63b6b5e83b8914864fc7edd789f8958cdc993cd Gerrit-PatchSet: 11 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Tue Apr 4 16:33:50 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Tue, 4 Apr 2017 16:33:50 +0000 Subject: [PATCH] libosmocore[master]: Add SW Description (de)marshalling In-Reply-To: References: Message-ID: Hello Neels Hofmeyr, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2165 to look at the new patch set (#12). Add SW Description (de)marshalling * data structure representing 3GPP TS 52.021 ?9.4.62 SW Description * function to serialize it into msgb * function to deserialize it from buffer * functions to extract/estimate buffer size for SW Description * test harness (partially taken from OpenBSC) There are several similar functions to deal with SW Description in OpenBSC, there's also need to use similar functionality in OsmoBTS. Hence it's better to put the code into common library with proper tests and documentation. Change-Id: Ib63b6b5e83b8914864fc7edd789f8958cdc993cd Related: OS#1614 --- M .gitignore M include/osmocom/gsm/protocol/gsm_12_21.h M src/gsm/abis_nm.c M src/gsm/libosmogsm.map M tests/Makefile.am A tests/abis/abis_test.c A tests/abis/abis_test.ok M tests/testsuite.at 8 files changed, 437 insertions(+), 2 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/65/2165/12 diff --git a/.gitignore b/.gitignore index ecbcedd..4c6a78f 100644 --- a/.gitignore +++ b/.gitignore @@ -60,6 +60,7 @@ tests/testsuite tests/testsuite.dir/ tests/testsuite.log +tests/abis/abis_test tests/ctrl/ctrl_test tests/utils/utils_test tests/stats/stats_test diff --git a/include/osmocom/gsm/protocol/gsm_12_21.h b/include/osmocom/gsm/protocol/gsm_12_21.h index c88f0b1..09d8432 100644 --- a/include/osmocom/gsm/protocol/gsm_12_21.h +++ b/include/osmocom/gsm/protocol/gsm_12_21.h @@ -29,6 +29,7 @@ /*! \file gsm_12_21.h */ #include +#include #include /*! \brief generic header in front of every OML message according to TS 08.59 */ @@ -791,6 +792,22 @@ IPAC_BINF_CELL_ALLOC = (1 << 2), }; +/*! \brief 3GPP TS 52.021 ?9.4.62 SW Description */ +struct abis_nm_sw_descr { + uint8_t file_id[UINT8_MAX]; + uint8_t file_id_len; + + uint8_t file_version[UINT8_MAX]; + uint8_t file_version_len; +}; + +uint16_t abis_nm_sw_descr_len(const struct abis_nm_sw_descr *sw, + bool put_sw_descr); +uint16_t abis_nm_put_sw_descr(struct msgb *msg, const struct abis_nm_sw_descr *sw, + bool put_sw_descr); +uint32_t abis_nm_get_sw_descr_len(const uint8_t * buf, size_t len); +int abis_nm_get_sw_conf(const uint8_t * buf, size_t buf_len, + struct abis_nm_sw_descr *sw, uint16_t sw_len); struct msgb *abis_nm_fail_evt_rep(enum abis_nm_event_type t, enum abis_nm_severity s, enum abis_nm_pcause_type ct, diff --git a/src/gsm/abis_nm.c b/src/gsm/abis_nm.c index 934d7ce..4acd322 100644 --- a/src/gsm/abis_nm.c +++ b/src/gsm/abis_nm.c @@ -751,6 +751,148 @@ return nmsg; } +/*! \brief Compute length of given 3GPP TS 52.021 ?9.4.62 SW Description. + * \param[in] sw SW Description struct + * \param[in] put_sw_descr boolean, whether to put NM_ATT_SW_DESCR IE or not + * \returns length of buffer space necessary to store sw + */ +uint16_t abis_nm_sw_descr_len(const struct abis_nm_sw_descr *sw, + bool put_sw_descr) +{ + /* +3: type is 1-byte, length is 2-byte */ + return (put_sw_descr ? 1 : 0) + (sw->file_id_len + 3) + + (sw->file_version_len + 3); +} + +/*! \brief Put given 3GPP TS 52.021 ?9.4.62 SW Description into msgb. + * \param[out] msg message buffer + * \param[in] sw SW Description struct + * \param[in] put_sw_descr boolean, whether to put NM_ATT_SW_DESCR IE or not + * \param[in] simulate boolean, whether to actually modify msg or not + * \returns length of buffer space necessary to store sw + */ +uint16_t abis_nm_put_sw_descr(struct msgb *msg, const struct abis_nm_sw_descr *sw, + bool put_sw_descr) +{ + if (put_sw_descr) + msgb_v_put(msg, NM_ATT_SW_DESCR); + msgb_tl16v_put(msg, NM_ATT_FILE_ID, sw->file_id_len, sw->file_id); + msgb_tl16v_put(msg, NM_ATT_FILE_VERSION, sw->file_version_len, + sw->file_version); + + return abis_nm_sw_descr_len(sw, put_sw_descr); +} + +/*! \brief Get length of first 3GPP TS 52.021 ?9.4.62 SW Description from buffer. + * \param[in] buf buffer, may contain several SW Descriptions + * \param[in] len buffer length + * \returns length if parsing succeeded, 0 otherwise + */ +uint32_t abis_nm_get_sw_descr_len(const uint8_t *buf, size_t len) +{ + uint16_t sw = 2; /* 1-byte SW tag + 1-byte FILE_* tag */ + + if (buf[0] != NM_ATT_SW_DESCR) + sw = 1; /* 1-byte FILE_* tag */ + + if (buf[sw - 1] != NM_ATT_FILE_ID && buf[sw - 1] != NM_ATT_FILE_VERSION) + return 0; + + /* + length of 1st FILE_* element + 1-byte tag + 2-byte length field of + 1st FILE_* element */ + sw += (osmo_load16be(buf + sw) + 3); + + /* + length of 2nd FILE_* element */ + sw += osmo_load16be(buf + sw); + + return sw + 2; /* + 2-byte length field of 2nd FILE_* element */ +} + +/*! \brief Parse single 3GPP TS 52.021 ?9.4.62 SW Description from buffer. + * \param[out] sw SW Description struct + * \param[in] buf buffer + * \param[in] len buffer length + * \returns 0 if parsing succeeded, negative error code otherwise + */ +static inline int abis_nm_get_sw_descr(struct abis_nm_sw_descr *sw, + const uint8_t *buf, size_t length) +{ + int rc; + uint32_t len = abis_nm_get_sw_descr_len(buf, length); + static struct tlv_parsed tp; + const struct tlv_definition sw_tlvdef = { + .def = { + [NM_ATT_SW_DESCR] = { TLV_TYPE_TV }, + [NM_ATT_FILE_ID] = { TLV_TYPE_TL16V }, + [NM_ATT_FILE_VERSION] = { TLV_TYPE_TL16V }, + }, + }; + + /* Basic sanity check */ + if (len > length) + return -EFBIG; + + /* Note: current implementation of TLV parser fails on multilpe SW Descr: + we will only parse the first one */ + if (!len) + return -EINVAL; + + /* Note: the return value is ignored here because SW Description tag + itself is considered optional. */ + tlv_parse(&tp, &sw_tlvdef, buf, len, 0, 0); + + /* Parsing SW Description is tricky for current implementation of TLV + parser which fails to properly handle TV when V has following + structure: | TL16V | TL16V |. Hence, the need for 2nd call: */ + rc = tlv_parse(&tp, &sw_tlvdef, buf + TLVP_LEN(&tp, NM_ATT_SW_DESCR), + len - TLVP_LEN(&tp, NM_ATT_SW_DESCR), 0, 0); + + if (rc < 0) + return rc; + + if (!TLVP_PRESENT(&tp, NM_ATT_FILE_ID)) + return -EBADF; + + if (!TLVP_PRESENT(&tp, NM_ATT_FILE_VERSION)) + return -EBADMSG; + + sw->file_id_len = TLVP_LEN(&tp, NM_ATT_FILE_ID); + sw->file_version_len = TLVP_LEN(&tp, NM_ATT_FILE_VERSION); + + memcpy(sw->file_id, TLVP_VAL(&tp, NM_ATT_FILE_ID), sw->file_id_len); + memcpy(sw->file_version, TLVP_VAL(&tp, NM_ATT_FILE_VERSION), + sw->file_version_len); + + return 0; +} + +/*! \brief Parse 3GPP TS 52.021 ?9.4.61 SW Configuration from buffer. + * \param[in] buf buffer + * \param[in] buf_len buffer length + * \param[out] sw SW Description struct array + * \param[in] sw_len Expected number of SW Description entries + * \returns 0 if parsing succeeded, negative error code otherwise + */ +int abis_nm_get_sw_conf(const uint8_t * buf, size_t buf_len, + struct abis_nm_sw_descr *sw, uint16_t sw_len) +{ + int rc; + uint16_t len = 0, i; + for (i = 0; i < sw_len; i++) { + memset(&sw[i], 0, sizeof(sw[i])); + rc = abis_nm_get_sw_descr(&sw[i], buf + len, buf_len - len); + if (rc < 0) + return rc; + + len += abis_nm_get_sw_descr_len(buf + len, buf_len - len); + + if (len >= buf_len) + return i + 1; + } + + return i; +} + /*! \brief Obtain OML Channel Combination for phnsical channel config */ int abis_nm_chcomb4pchan(enum gsm_phys_chan_config pchan) { diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map index 5649e71..f9c75c3 100644 --- a/src/gsm/libosmogsm.map +++ b/src/gsm/libosmogsm.map @@ -31,6 +31,10 @@ abis_nm_pcause_type_names; abis_nm_msgtype_names; abis_nm_att_names; +abis_nm_sw_descr_len; +abis_nm_put_sw_descr; +abis_nm_get_sw_conf; +abis_nm_get_sw_descr_len; osmo_sitype_strs; osmo_c4; diff --git a/tests/Makefile.am b/tests/Makefile.am index 352b5a7..c726277 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -15,7 +15,7 @@ bitvec/bitvec_test msgb/msgb_test bits/bitcomp_test \ tlv/tlv_test gsup/gsup_test oap/oap_test fsm/fsm_test \ write_queue/wqueue_test socket/socket_test \ - coding/coding_test + coding/coding_test abis/abis_test if ENABLE_MSGFILE check_PROGRAMS += msgfile/msgfile_test @@ -42,6 +42,9 @@ auth_milenage_test_SOURCES = auth/milenage_test.c auth_milenage_test_LDADD = $(top_builddir)/src/libosmocore.la $(top_builddir)/src/gsm/libosmogsm.la + +abis_abis_test_SOURCES = abis/abis_test.c +abis_abis_test_LDADD = $(top_builddir)/src/libosmocore.la $(top_builddir)/src/gsm/libosmogsm.la ctrl_ctrl_test_SOURCES = ctrl/ctrl_test.c ctrl_ctrl_test_LDADD = $(top_builddir)/src/libosmocore.la $(top_builddir)/src/ctrl/libosmoctrl.la @@ -188,7 +191,7 @@ vty/vty_test.ok comp128/comp128_test.ok \ utils/utils_test.ok stats/stats_test.ok \ bitvec/bitvec_test.ok msgb/msgb_test.ok bits/bitcomp_test.ok \ - sim/sim_test.ok tlv/tlv_test.ok \ + sim/sim_test.ok tlv/tlv_test.ok abis/abis_test.ok \ gsup/gsup_test.ok gsup/gsup_test.err \ oap/oap_test.ok fsm/fsm_test.ok fsm/fsm_test.err \ write_queue/wqueue_test.ok socket/socket_test.ok \ diff --git a/tests/abis/abis_test.c b/tests/abis/abis_test.c new file mode 100644 index 0000000..beb50f2 --- /dev/null +++ b/tests/abis/abis_test.c @@ -0,0 +1,221 @@ +/* + * (C) 2012 by Holger Hans Peter Freyther + * (C) 2017 by sysmocom s.m.f.c. GmbH + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +static struct log_info info = {}; + +static const uint8_t simple_config[] = { 66, 18, 0, 3, 1, 2, 3, 19, 0, 3, 3, 4, 5 }; + +static const uint8_t dual_config[] = { + 66, 18, 0, 3, 1, 2, 3, 19, 0, 3, 3, 4, 5, + 66, 18, 0, 3, 9, 7, 5, 19, 0, 3, 6, 7, 8, +}; + +static void test_simple_sw_config(void) +{ + struct abis_nm_sw_descr descr[1]; + uint16_t len; + int rc; + + rc = abis_nm_get_sw_conf(simple_config, ARRAY_SIZE(simple_config), + &descr[0], ARRAY_SIZE(descr)); + if (rc != 1) { + printf("%s(): FAILED to parse the File Id/File version: %d\n", + __func__, rc); + abort(); + } + + len = abis_nm_sw_descr_len(&descr[0], true); + if (len != 13) { + printf("WRONG SIZE: %u\n", len); + abort(); + } + + printf("len: %u\n", len); + printf("file_id: %s\n", osmo_hexdump(descr[0].file_id, descr[0].file_id_len)); + printf("file_ver: %s\n", osmo_hexdump(descr[0].file_version, descr[0].file_version_len)); + printf("%s(): OK\n", __func__); +} + +static void test_simple_sw_short(void) +{ + struct abis_nm_sw_descr descr[1]; + int i; + + for (i = 1; i < ARRAY_SIZE(simple_config); ++i) { + int rc = abis_nm_get_sw_conf(simple_config, + ARRAY_SIZE(simple_config) - i, &descr[0], + ARRAY_SIZE(descr)); + if (rc >= 1) { + printf("SHOULD not have parsed: %d\n", rc); + abort(); + } + } + printf("%s(): OK\n", __func__); +} + +static void test_dual_sw_config(void) +{ + struct abis_nm_sw_descr descr[2]; + uint16_t len0, len1; + int rc; + + rc = abis_nm_get_sw_conf(dual_config, ARRAY_SIZE(dual_config), + &descr[0], ARRAY_SIZE(descr)); + if (rc != 2) { + printf("%s(): FAILED to parse the File Id/File version: %d (%d,%d)\n", + __func__, -rc, EBADF, EBADMSG); + abort(); + } + + len0 = abis_nm_sw_descr_len(&descr[0], true); + if (len0 != 13) { + printf("WRONG SIZE0: %u\n", len0); + abort(); + } + + len1 = abis_nm_sw_descr_len(&descr[1], true); + if (len1 != 13) { + printf("WRONG SIZE1: %u\n", len1); + abort(); + } + + printf("len: %u\n", len0); + printf("file_id: %s\n", osmo_hexdump(descr[0].file_id, descr[0].file_id_len)); + printf("file_ver: %s\n", osmo_hexdump(descr[0].file_version, descr[0].file_version_len)); + + printf("len: %u\n", len1); + printf("file_id: %s\n", osmo_hexdump(descr[1].file_id, descr[1].file_id_len)); + printf("file_ver: %s\n", osmo_hexdump(descr[1].file_version, descr[1].file_version_len)); + printf("%s(): OK\n", __func__); +} + +static inline void print_chk(const char *what, uint8_t len1, uint8_t len2, + const uint8_t *x1, const uint8_t *x2) +{ + int cmp = memcmp(x1, x2, len2); + printf("\tFILE %s [%u == %u -> %d, %s] %d => %s\n", what, len1, len2, + len1 == len2, len1 != len2 ? "fail" : "ok", + cmp, cmp != 0 ? "FAIL" : "OK"); +} + +static inline void chk_descr(struct msgb *msg, struct abis_nm_sw_descr *put, + const char *descr, bool header) +{ + int res; + struct abis_nm_sw_descr sw = { 0 }; + uint16_t len = abis_nm_put_sw_descr(msg, put, header); + + printf("msgb[%u] :: {msgb->len} %u == %u {len} - %s]:\n\t" + "SW DESCR (%s)\n\t" + "length: {extracted} %u = %u {expected} - %s, failsafe - %s\n", + msg->data_len, msg->len, len, len != msg->len ? "fail" : "ok", + descr, abis_nm_get_sw_descr_len(msgb_data(msg), msg->len), + msg->len, + abis_nm_get_sw_descr_len(msgb_data(msg), msg->len) != msg->len ? "FAIL" : "OK", + len > put->file_version_len + put->file_id_len ? "OK" : "FAIL"); + + res = abis_nm_get_sw_conf(msgb_data(msg), msg->len, &sw, 1); + if (res < 0) + printf("\tSW DESCR (%s) parsing error code %d!\n", descr, -res); + else { + print_chk("ID", sw.file_id_len, put->file_id_len, sw.file_id, + put->file_id); + print_chk("VERSION", sw.file_version_len, + put->file_version_len, sw.file_version, + put->file_version); + } +} + +static inline void chk_raw(const char *what, const uint8_t *data, uint16_t len) +{ + struct abis_nm_sw_descr sw = { 0 }; + int res = abis_nm_get_sw_conf(data, len, &sw, 1); + uint16_t xlen = abis_nm_get_sw_descr_len(data, len); + + printf("parsing chained %s <1st: %d, total: %d>\n\tSW Descr (%s)\n", + osmo_hexdump(data, len), xlen, len, what); + + if (res < 0) + printf("\tFAIL: %d\n", -res); + else { + printf("\tFILE ID: [%d] %s => OK\n", sw.file_id_len, + osmo_hexdump(sw.file_id, sw.file_id_len)); + printf("\tFILE VERSION: [%d] %s => OK\n", sw.file_version_len, + osmo_hexdump(sw.file_version, sw.file_version_len)); + } + + if (len != xlen) + chk_raw(" 2nd", data + xlen, len - xlen); +} + +static void test_sw_descr() +{ + const char *f_id = "TEST.L0L", *f_ver = "0.1.666~deadbeeffacefeed-dirty"; + uint8_t lf_id = strlen(f_id), lf_ver = strlen(f_ver); + uint8_t chain[] = { 0x42, 0x12, 0x00, 0x03, 0x01, 0x02, 0x03, 0x13, 0x00, 0x03, 0x03, 0x04, 0x05, 0x42, 0x12, 0x00, 0x03, 0x09, 0x07, 0x05, 0x13, 0x00, 0x03, 0x06, 0x07, 0x08 }; + struct msgb *msg = msgb_alloc_headroom(4096, 128, "sw"); + struct abis_nm_sw_descr sw_put = { + .file_id_len = lf_id, + .file_version_len = lf_ver, + }; + + printf("Testing SW Description (de)serialization...\n"); + + memcpy(sw_put.file_id, f_id, lf_id); + memcpy(sw_put.file_version, f_ver, lf_ver); + + /* check that parsing |SW|ID|VER| works: */ + chk_descr(msg, &sw_put, "with header", true); + msgb_reset(msg); + /* check that parsing |ID|VER| works: */ + chk_descr(msg, &sw_put, "without header", false); + /* check that parsing |ID|VER|SW|ID|VER| fails - notice the lack of + msgb_reset() to create bogus msgb data: */ + chk_descr(msg, &sw_put, "expected failure", true); + /* check multiple, chained SW-descr: */ + chk_raw("half", chain, sizeof(chain) / 2); + chk_raw("full", chain, sizeof(chain)); +} + +int main(int argc, char **argv) +{ + osmo_init_logging(&info); + + test_sw_descr(); + test_simple_sw_config(); + test_simple_sw_short(); + test_dual_sw_config(); + + printf("OK.\n"); + + return 0; +} diff --git a/tests/abis/abis_test.ok b/tests/abis/abis_test.ok new file mode 100644 index 0000000..e6b626b --- /dev/null +++ b/tests/abis/abis_test.ok @@ -0,0 +1,41 @@ +Testing SW Description (de)serialization... +msgb[4096] :: {msgb->len} 45 == 45 {len} - ok]: + SW DESCR (with header) + length: {extracted} 45 = 45 {expected} - OK, failsafe - OK + FILE ID [8 == 8 -> 1, ok] 0 => OK + FILE VERSION [30 == 30 -> 1, ok] 0 => OK +msgb[4096] :: {msgb->len} 44 == 44 {len} - ok]: + SW DESCR (without header) + length: {extracted} 44 = 44 {expected} - OK, failsafe - OK + FILE ID [8 == 8 -> 1, ok] 0 => OK + FILE VERSION [30 == 30 -> 1, ok] 0 => OK +msgb[4096] :: {msgb->len} 89 == 45 {len} - fail]: + SW DESCR (expected failure) + length: {extracted} 44 = 89 {expected} - FAIL, failsafe - OK + FILE ID [8 == 8 -> 1, ok] 0 => OK + FILE VERSION [30 == 30 -> 1, ok] 0 => OK +parsing chained 42 12 00 03 01 02 03 13 00 03 03 04 05 <1st: 13, total: 13> + SW Descr (half) + FILE ID: [3] 01 02 03 => OK + FILE VERSION: [3] 03 04 05 => OK +parsing chained 42 12 00 03 01 02 03 13 00 03 03 04 05 42 12 00 03 09 07 05 13 00 03 06 07 08 <1st: 13, total: 26> + SW Descr (full) + FILE ID: [3] 01 02 03 => OK + FILE VERSION: [3] 03 04 05 => OK +parsing chained 42 12 00 03 09 07 05 13 00 03 06 07 08 <1st: 13, total: 13> + SW Descr ( 2nd) + FILE ID: [3] 09 07 05 => OK + FILE VERSION: [3] 06 07 08 => OK +len: 13 +file_id: 01 02 03 +file_ver: 03 04 05 +test_simple_sw_config(): OK +test_simple_sw_short(): OK +len: 13 +file_id: 01 02 03 +file_ver: 03 04 05 +len: 13 +file_id: 09 07 05 +file_ver: 06 07 08 +test_dual_sw_config(): OK +OK. diff --git a/tests/testsuite.at b/tests/testsuite.at index 64df724..7ee0164 100644 --- a/tests/testsuite.at +++ b/tests/testsuite.at @@ -9,6 +9,12 @@ AT_CHECK([$abs_top_builddir/tests/a5/a5_test], [0], [expout]) AT_CLEANUP +AT_SETUP([abis]) +AT_KEYWORDS([abis]) +cat $abs_srcdir/abis/abis_test.ok > expout +AT_CHECK([$abs_top_builddir/tests/abis/abis_test], [0], [expout], [ignore]) +AT_CLEANUP + AT_SETUP([ctrl]) AT_KEYWORDS([ctrl]) cat $abs_srcdir/ctrl/ctrl_test.ok > expout -- To view, visit https://gerrit.osmocom.org/2165 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ib63b6b5e83b8914864fc7edd789f8958cdc993cd Gerrit-PatchSet: 12 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Tue Apr 4 16:34:45 2017 From: gerrit-no-reply at lists.osmocom.org (Pau Espin Pedrol) Date: Tue, 4 Apr 2017 16:34:45 +0000 Subject: [PATCH] osmo-pcu[master]: Name systemd service after the software Message-ID: Review at https://gerrit.osmocom.org/2224 Name systemd service after the software Binary name was changed from sysmopcu to osmo-pcu but the service file remained with the old name, which is confusing for newcomers. Added an alias to the service file for users used to the old naming. Change-Id: Ia7fa4a1868ee04ee043efd61aa55ee0c4001f12b --- R contrib/osmo-pcu.service 1 file changed, 1 insertion(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-pcu refs/changes/24/2224/1 diff --git a/contrib/sysmopcu.service b/contrib/osmo-pcu.service similarity index 92% rename from contrib/sysmopcu.service rename to contrib/osmo-pcu.service index 3e3ff07..3066a66 100644 --- a/contrib/sysmopcu.service +++ b/contrib/osmo-pcu.service @@ -14,3 +14,4 @@ [Install] WantedBy=multi-user.target +Alias=sysmopcu.service -- To view, visit https://gerrit.osmocom.org/2224 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ia7fa4a1868ee04ee043efd61aa55ee0c4001f12b Gerrit-PatchSet: 1 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: Pau Espin Pedrol From gerrit-no-reply at lists.osmocom.org Tue Apr 4 16:35:14 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Tue, 4 Apr 2017 16:35:14 +0000 Subject: [PATCH] openbsc[master]: Use libosmocore for SW Description parsing In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2166 to look at the new patch set (#5). Use libosmocore for SW Description parsing Requires libosmocore with Ib63b6b5e83b8914864fc7edd789f8958cdc993cd. Change-Id: Ib94db414e94a2a1f234ac6f1cb346dca1c7a8be3 --- M openbsc/include/openbsc/abis_nm.h M openbsc/src/ipaccess/ipaccess-config.c M openbsc/src/libbsc/abis_nm.c M openbsc/tests/abis/abis_test.c M openbsc/tests/abis/abis_test.ok 5 files changed, 36 insertions(+), 213 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/66/2166/5 diff --git a/openbsc/include/openbsc/abis_nm.h b/openbsc/include/openbsc/abis_nm.h index 2465452..09e0b23 100644 --- a/openbsc/include/openbsc/abis_nm.h +++ b/openbsc/include/openbsc/abis_nm.h @@ -68,18 +68,6 @@ int (*sw_act_req)(struct msgb *); }; -struct abis_nm_sw_descr { - /* where does it start? how long is it? */ - const uint8_t *start; - size_t len; - - /* the parsed data */ - const uint8_t *file_id; - uint16_t file_id_len; - const uint8_t *file_ver; - uint16_t file_ver_len; -}; - extern int abis_nm_rcvmsg(struct msgb *msg); int abis_nm_tlv_parse(struct tlv_parsed *tp, struct gsm_bts *bts, const uint8_t *buf, int len); @@ -181,8 +169,6 @@ void abis_nm_queue_send_next(struct gsm_bts *bts); /* for bs11_config. */ -int abis_nm_parse_sw_config(const uint8_t *data, const size_t len, - struct abis_nm_sw_descr *res, const int res_len); int abis_nm_select_newest_sw(const struct abis_nm_sw_descr *sw, const size_t len); /* Helper functions for updating attributes */ diff --git a/openbsc/src/ipaccess/ipaccess-config.c b/openbsc/src/ipaccess/ipaccess-config.c index 0c3f888..ca5f195 100644 --- a/openbsc/src/ipaccess/ipaccess-config.c +++ b/openbsc/src/ipaccess/ipaccess-config.c @@ -52,6 +52,7 @@ #include #include #include +#include struct gsm_network *bsc_gsmnet; @@ -70,17 +71,9 @@ static int found_trx = 0; static int loop_tests = 0; -struct sw_load { - uint8_t file_id[255]; - uint8_t file_id_len; - - uint8_t file_version[255]; - uint8_t file_version_len; -}; - static void *tall_ctx_config = NULL; -static struct sw_load *sw_load1 = NULL; -static struct sw_load *sw_load2 = NULL; +static struct abis_nm_sw_descr *sw_load1 = NULL; +static struct abis_nm_sw_descr *sw_load2 = NULL; /* static uint8_t prim_oml_attr[] = { 0x95, 0x00, 7, 0x88, 192, 168, 100, 11, 0x00, 0x00 }; @@ -344,19 +337,11 @@ msg->l3h = &msg->l2h[3]; /* activate software */ - if (sw_load1) { - msgb_v_put(msg, NM_ATT_SW_DESCR); - msgb_tl16v_put(msg, NM_ATT_FILE_ID, sw_load1->file_id_len, sw_load1->file_id); - msgb_tl16v_put(msg, NM_ATT_FILE_VERSION, sw_load1->file_version_len, - sw_load1->file_version); - } + if (sw_load1) + abis_nm_put_sw_descr(msg, sw_load1, true); - if (sw_load2) { - msgb_v_put(msg, NM_ATT_SW_DESCR); - msgb_tl16v_put(msg, NM_ATT_FILE_ID, sw_load2->file_id_len, sw_load2->file_id); - msgb_tl16v_put(msg, NM_ATT_FILE_VERSION, sw_load2->file_version_len, - sw_load2->file_version); - } + if (sw_load2) + abis_nm_put_sw_descr(msg, sw_load2, true); /* fill in the data */ msg->l2h[0] = NM_ATT_IPACC_CUR_SW_CFG; @@ -618,11 +603,11 @@ return 0; } -static struct sw_load *create_swload(struct sdp_header *header) +static struct abis_nm_sw_descr *create_swload(struct sdp_header *header) { - struct sw_load *load; + struct abis_nm_sw_descr *load; - load = talloc_zero(tall_ctx_config, struct sw_load); + load = talloc_zero(tall_ctx_config, struct abis_nm_sw_descr); strncpy((char *)load->file_id, header->firmware_info.sw_part, 20); load->file_id_len = strlen(header->firmware_info.sw_part) + 1; diff --git a/openbsc/src/libbsc/abis_nm.c b/openbsc/src/libbsc/abis_nm.c index 33a23a2..cd848b0 100644 --- a/openbsc/src/libbsc/abis_nm.c +++ b/openbsc/src/libbsc/abis_nm.c @@ -413,93 +413,29 @@ /* Activate the specified software into the BTS */ static int ipacc_sw_activate(struct gsm_bts *bts, uint8_t obj_class, uint8_t i0, uint8_t i1, - uint8_t i2, const uint8_t *sw_desc, uint8_t swdesc_len) + uint8_t i2, const struct abis_nm_sw_descr *sw_desc) { struct abis_om_hdr *oh; struct msgb *msg = nm_msgb_alloc(); - uint8_t len = swdesc_len; - uint8_t *trailer; + uint16_t len = abis_nm_sw_descr_len(sw_desc, true); oh = (struct abis_om_hdr *) msgb_put(msg, ABIS_OM_FOM_HDR_SIZE); fill_om_fom_hdr(oh, len, NM_MT_ACTIVATE_SW, obj_class, i0, i1, i2); - - trailer = msgb_put(msg, swdesc_len); - memcpy(trailer, sw_desc, swdesc_len); + abis_nm_put_sw_descr(msg, sw_desc, true); return abis_nm_sendmsg(bts, msg); } -int abis_nm_parse_sw_config(const uint8_t *sw_descr, const size_t sw_descr_len, - struct abis_nm_sw_descr *desc, const int res_len) -{ - static const struct tlv_definition sw_descr_def = { - .def = { - [NM_ATT_FILE_ID] = { TLV_TYPE_TL16V, }, - [NM_ATT_FILE_VERSION] = { TLV_TYPE_TL16V, }, - }, - }; - - size_t pos = 0; - int desc_pos = 0; - - for (pos = 0; pos < sw_descr_len && desc_pos < res_len; ++desc_pos) { - uint8_t tag; - uint16_t tag_len; - const uint8_t *val; - int len; - - memset(&desc[desc_pos], 0, sizeof(desc[desc_pos])); - desc[desc_pos].start = &sw_descr[pos]; - - /* Classic TLV parsing doesn't work well with SW_DESCR because of it's - * nested nature and the fact you have to assume it contains only two sub - * tags NM_ATT_FILE_VERSION & NM_ATT_FILE_ID to parse it */ - if (sw_descr[pos] != NM_ATT_SW_DESCR) { - LOGP(DNM, LOGL_ERROR, - "SW_DESCR attribute identifier not found!\n"); - return -1; - } - - pos += 1; - len = tlv_parse_one(&tag, &tag_len, &val, - &sw_descr_def, &sw_descr[pos], sw_descr_len - pos); - if (len < 0 || (tag != NM_ATT_FILE_ID)) { - LOGP(DNM, LOGL_ERROR, - "FILE_ID attribute identifier not found!\n"); - return -2; - } - desc[desc_pos].file_id = val; - desc[desc_pos].file_id_len = tag_len; - pos += len; - - - len = tlv_parse_one(&tag, &tag_len, &val, - &sw_descr_def, &sw_descr[pos], sw_descr_len - pos); - if (len < 0 || (tag != NM_ATT_FILE_VERSION)) { - LOGP(DNM, LOGL_ERROR, - "FILE_VERSION attribute identifier not found!\n"); - return -3; - } - desc[desc_pos].file_ver = val; - desc[desc_pos].file_ver_len = tag_len; - pos += len; - - /* final size */ - desc[desc_pos].len = &sw_descr[pos] - desc[desc_pos].start; - } - - return desc_pos; -} - int abis_nm_select_newest_sw(const struct abis_nm_sw_descr *sw_descr, - const size_t size) + const size_t size) { int res = 0; int i; for (i = 1; i < size; ++i) { - if (memcmp(sw_descr[res].file_ver, sw_descr[i].file_ver, - OSMO_MIN(sw_descr[i].file_ver_len, sw_descr[res].file_ver_len)) < 0) { + if (memcmp(sw_descr[res].file_version, sw_descr[i].file_version, + OSMO_MIN(sw_descr[i].file_version_len, + sw_descr[res].file_version_len)) < 0) { res = i; } } @@ -546,8 +482,8 @@ } /* Parse up to two sw descriptions from the data */ - len = abis_nm_parse_sw_config(sw_config, sw_config_len, - &sw_descr[0], ARRAY_SIZE(sw_descr)); + len = abis_nm_get_sw_conf(sw_config, sw_config_len, &sw_descr[0], + ARRAY_SIZE(sw_descr)); if (len <= 0) { LOGP(DNM, LOGL_ERROR, "Failed to parse SW Config.\n"); return -EINVAL; @@ -560,7 +496,7 @@ foh->obj_inst.bts_nr, foh->obj_inst.trx_nr, foh->obj_inst.ts_nr, - sw_descr[ret].start, sw_descr[ret].len); + &sw_descr[ret]); } /* Receive a CHANGE_ADM_STATE_ACK, parse the TLV and update local state */ diff --git a/openbsc/tests/abis/abis_test.c b/openbsc/tests/abis/abis_test.c index 496267f..e288e30 100644 --- a/openbsc/tests/abis/abis_test.c +++ b/openbsc/tests/abis/abis_test.c @@ -22,21 +22,11 @@ #include #include +#include #include #include #include - -static const uint8_t simple_config[] = { - /*0, 13, */ - 66, 18, 0, 3, 1, 2, 3, 19, 0, 3, 3, 4, 5, -}; - -static const uint8_t dual_config[] = { - /*0, 26, */ - 66, 18, 0, 3, 1, 2, 3, 19, 0, 3, 3, 4, 5, - 66, 18, 0, 3, 9, 7, 5, 19, 0, 3, 6, 7, 8, -}; static const uint8_t load_config[] = { 0x42, 0x12, 0x00, 0x08, 0x31, 0x36, 0x38, 0x64, @@ -48,94 +38,29 @@ 0x33, 0x64, 0x31, 0x00 }; -static void test_simple_sw_config(void) -{ - struct abis_nm_sw_descr descr[1]; - int rc; - - rc = abis_nm_parse_sw_config(simple_config, ARRAY_SIZE(simple_config), - &descr[0], ARRAY_SIZE(descr)); - if (rc != 1) { - printf("FAILED to parse the File Id/File version\n"); - abort(); - } - - if (descr[0].len != 13) { - printf("WRONG SIZE: %zu\n", descr[0].len); - abort(); - } - - printf("Start: %td len: %zu\n", descr[0].start - simple_config, descr[0].len); - printf("file_id: %s\n", osmo_hexdump(descr[0].file_id, descr[0].file_id_len)); - printf("file_ver: %s\n", osmo_hexdump(descr[0].file_ver, descr[0].file_ver_len)); -} - -static void test_simple_sw_short(void) -{ - struct abis_nm_sw_descr descr[1]; - int i; - - for (i = 1; i < ARRAY_SIZE(simple_config); ++i) { - int rc = abis_nm_parse_sw_config(simple_config, - ARRAY_SIZE(simple_config) - i, &descr[0], - ARRAY_SIZE(descr)); - if (rc >= 1) { - printf("SHOULD not have parsed: %d\n", rc); - abort(); - } - } -} - -static void test_dual_sw_config(void) -{ - struct abis_nm_sw_descr descr[2]; - int rc; - - rc = abis_nm_parse_sw_config(dual_config, ARRAY_SIZE(dual_config), - &descr[0], ARRAY_SIZE(descr)); - if (rc != 2) { - printf("FAILED to parse the File Id/File version\n"); - abort(); - } - - if (descr[0].len != 13) { - printf("WRONG SIZE0: %zu\n", descr[0].len); - abort(); - } - - if (descr[1].len != 13) { - printf("WRONG SIZE1: %zu\n", descr[1].len); - abort(); - } - - printf("Start: %td len: %zu\n", descr[0].start - dual_config, descr[0].len); - printf("file_id: %s\n", osmo_hexdump(descr[0].file_id, descr[0].file_id_len)); - printf("file_ver: %s\n", osmo_hexdump(descr[0].file_ver, descr[0].file_ver_len)); - - printf("Start: %td len: %zu\n", descr[1].start - dual_config, descr[1].len); - printf("file_id: %s\n", osmo_hexdump(descr[1].file_id, descr[1].file_id_len)); - printf("file_ver: %s\n", osmo_hexdump(descr[1].file_ver, descr[1].file_ver_len)); -} - static void test_sw_selection(void) { struct abis_nm_sw_descr descr[8], tmp; + uint16_t len0, len1; int rc, pos; - rc = abis_nm_parse_sw_config(load_config, ARRAY_SIZE(load_config), + rc = abis_nm_get_sw_conf(load_config, ARRAY_SIZE(load_config), &descr[0], ARRAY_SIZE(descr)); if (rc != 2) { - printf("FAILED to parse the File Id/File version\n"); + printf("%s(): FAILED to parse the File Id/File version: %d\n", + __func__, rc); abort(); } - printf("Start: %td len: %zu\n", descr[0].start - load_config, descr[0].len); + len0 = abis_nm_sw_descr_len(&descr[0], true); + printf("len: %u\n", len0); printf("file_id: %s\n", osmo_hexdump(descr[0].file_id, descr[0].file_id_len)); - printf("file_ver: %s\n", osmo_hexdump(descr[0].file_ver, descr[0].file_ver_len)); + printf("file_ver: %s\n", osmo_hexdump(descr[0].file_version, descr[0].file_version_len)); - printf("Start: %td len: %zu\n", descr[1].start - load_config, descr[1].len); + len1 = abis_nm_sw_descr_len(&descr[1], true); + printf("len: %u\n", len1); printf("file_id: %s\n", osmo_hexdump(descr[1].file_id, descr[1].file_id_len)); - printf("file_ver: %s\n", osmo_hexdump(descr[1].file_ver, descr[1].file_ver_len)); + printf("file_ver: %s\n", osmo_hexdump(descr[1].file_version, descr[1].file_version_len)); /* start */ pos = abis_nm_select_newest_sw(descr, rc); @@ -155,14 +80,13 @@ abort(); } printf("SELECTED: %d\n", pos); + printf("%s(): OK\n", __func__); } int main(int argc, char **argv) { osmo_init_logging(&log_info); - test_simple_sw_config(); - test_simple_sw_short(); - test_dual_sw_config(); + test_sw_selection(); return EXIT_SUCCESS; diff --git a/openbsc/tests/abis/abis_test.ok b/openbsc/tests/abis/abis_test.ok index 2f99f9d..8418cad 100644 --- a/openbsc/tests/abis/abis_test.ok +++ b/openbsc/tests/abis/abis_test.ok @@ -1,17 +1,9 @@ -Start: 0 len: 13 -file_id: 01 02 03 -file_ver: 03 04 05 -Start: 0 len: 13 -file_id: 01 02 03 -file_ver: 03 04 05 -Start: 13 len: 13 -file_id: 09 07 05 -file_ver: 06 07 08 -Start: 0 len: 26 +len: 26 file_id: 31 36 38 64 34 37 32 00 file_ver: 76 32 30 30 62 31 34 33 64 30 00 -Start: 26 len: 26 +len: 26 file_id: 31 36 38 64 34 37 32 00 file_ver: 76 32 30 30 62 31 34 33 64 31 00 SELECTED: 1 SELECTED: 0 +test_sw_selection(): OK -- To view, visit https://gerrit.osmocom.org/2166 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ib94db414e94a2a1f234ac6f1cb346dca1c7a8be3 Gerrit-PatchSet: 5 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Apr 4 16:35:29 2017 From: gerrit-no-reply at lists.osmocom.org (Pau Espin Pedrol) Date: Tue, 4 Apr 2017 16:35:29 +0000 Subject: [PATCH] osmo-bts[master]: Name systemd service after the software Message-ID: Review at https://gerrit.osmocom.org/2225 Name systemd service after the software Binary name was changed from sysmopcu to osmo-pcu but the service file remained with the old name, which is confusing for newcomers. Added an alias to the service file for users used to the old naming. Change-Id: Ie336292c275e7415a1deedab7c3b44966aacc3bf --- M Makefile.am R contrib/osmo-bts.service M src/osmo-bts-sysmo/misc/sysmobts_mgr_temp.c M src/osmo-bts-sysmo/misc/sysmobts_mgr_vty.c 4 files changed, 8 insertions(+), 7 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/25/2225/1 diff --git a/Makefile.am b/Makefile.am index 9a5e26f..b83189c 100644 --- a/Makefile.am +++ b/Makefile.am @@ -5,7 +5,7 @@ # package the contrib and doc EXTRA_DIST = \ - contrib/dump_docs.py contrib/screenrc-l1fwd contrib/sysmobts.service \ + contrib/dump_docs.py contrib/screenrc-l1fwd contrib/osmo-bts.service \ contrib/l1fwd.init contrib/screenrc-sysmobts contrib/respawn.sh \ contrib/sysmobts.init contrib/sysmobts-calib/Makefile \ contrib/sysmobts-calib/sysmobts-calib.c \ diff --git a/contrib/sysmobts.service b/contrib/osmo-bts.service similarity index 96% rename from contrib/sysmobts.service rename to contrib/osmo-bts.service index e07a3db..bbb2bef 100644 --- a/contrib/sysmobts.service +++ b/contrib/osmo-bts.service @@ -17,3 +17,4 @@ [Install] WantedBy=multi-user.target +Alias=sysmobts.service diff --git a/src/osmo-bts-sysmo/misc/sysmobts_mgr_temp.c b/src/osmo-bts-sysmo/misc/sysmobts_mgr_temp.c index f01fd14..81e41f0 100644 --- a/src/osmo-bts-sysmo/misc/sysmobts_mgr_temp.c +++ b/src/osmo-bts-sysmo/misc/sysmobts_mgr_temp.c @@ -116,7 +116,7 @@ * and used SIGCHLD/waitpid to pick up the dead processes * without invoking shell. */ - system("/bin/systemctl start sysmobts.service"); + system("/bin/systemctl start osmo-bts.service"); } } @@ -157,7 +157,7 @@ * and used SIGCHLD/waitpid to pick up the dead processes * without invoking shell. */ - system("/bin/systemctl stop sysmobts.service"); + system("/bin/systemctl stop osmo-bts.service"); } } diff --git a/src/osmo-bts-sysmo/misc/sysmobts_mgr_vty.c b/src/osmo-bts-sysmo/misc/sysmobts_mgr_vty.c index 3020d90..85270de 100644 --- a/src/osmo-bts-sysmo/misc/sysmobts_mgr_vty.c +++ b/src/osmo-bts-sysmo/misc/sysmobts_mgr_vty.c @@ -284,7 +284,7 @@ DEFUN(cfg_action_bts_srv_on, cfg_action_bts_srv_on_cmd, "bts-service-on", - "Start the systemd sysmobts.service\n") + "Start the systemd osmo-bts.service\n") { int *action = vty->index; *action |= TEMP_ACT_NORM_BTS_SRV_ON; @@ -293,7 +293,7 @@ DEFUN(cfg_no_action_bts_srv_on, cfg_no_action_bts_srv_on_cmd, "no bts-service-on", - NO_STR "Start the systemd sysmobts.service\n") + NO_STR "Start the systemd osmo-bts.service\n") { int *action = vty->index; *action &= ~TEMP_ACT_NORM_BTS_SRV_ON; @@ -338,7 +338,7 @@ DEFUN(cfg_action_bts_srv_off, cfg_action_bts_srv_off_cmd, "bts-service-off", - "Stop the systemd sysmobts.service\n") + "Stop the systemd osmo-bts.service\n") { int *action = vty->index; *action |= TEMP_ACT_BTS_SRV_OFF; @@ -347,7 +347,7 @@ DEFUN(cfg_no_action_bts_srv_off, cfg_no_action_bts_srv_off_cmd, "no bts-service-off", - NO_STR "Stop the systemd sysmobts.service\n") + NO_STR "Stop the systemd osmo-bts.service\n") { int *action = vty->index; *action &= ~TEMP_ACT_BTS_SRV_OFF; -- To view, visit https://gerrit.osmocom.org/2225 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ie336292c275e7415a1deedab7c3b44966aacc3bf Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Pau Espin Pedrol From gerrit-no-reply at lists.osmocom.org Tue Apr 4 16:49:29 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Tue, 4 Apr 2017 16:49:29 +0000 Subject: [PATCH] openbsc[master]: python: fix Null logger Message-ID: Review at https://gerrit.osmocom.org/2226 python: fix Null logger Change-Id: Ie120273eabbc670e9f19ba365508688a810a2773 Related: SYS#3028 --- M openbsc/contrib/twisted_ipa.py 1 file changed, 2 insertions(+), 2 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/26/2226/1 diff --git a/openbsc/contrib/twisted_ipa.py b/openbsc/contrib/twisted_ipa.py index c143852..5b48ed5 100755 --- a/openbsc/contrib/twisted_ipa.py +++ b/openbsc/contrib/twisted_ipa.py @@ -318,8 +318,8 @@ self.log = log else: self.log = logging.getLogger('IPAFactory') - log.setLevel(logging.CRITICAL) - log.addHandler(logging.NullHandler) + self.log.setLevel(logging.CRITICAL) + self.log.addHandler(logging.NullHandler) def clientConnectionFailed(self, connector, reason): """ -- To view, visit https://gerrit.osmocom.org/2226 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ie120273eabbc670e9f19ba365508688a810a2773 Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Max From gerrit-no-reply at lists.osmocom.org Tue Apr 4 16:51:59 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Tue, 4 Apr 2017 16:51:59 +0000 Subject: [PATCH] openbsc[master]: python: fix Null logger In-Reply-To: References: Message-ID: python: fix Null logger Change-Id: Ie120273eabbc670e9f19ba365508688a810a2773 Related: SYS#3028 --- M openbsc/contrib/twisted_ipa.py 1 file changed, 3 insertions(+), 3 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/26/2226/2 diff --git a/openbsc/contrib/twisted_ipa.py b/openbsc/contrib/twisted_ipa.py index c143852..e6d7b1a 100755 --- a/openbsc/contrib/twisted_ipa.py +++ b/openbsc/contrib/twisted_ipa.py @@ -22,7 +22,7 @@ */ """ -__version__ = "0.5" # bump this on every non-trivial change +__version__ = "0.6" # bump this on every non-trivial change from ipa import Ctrl, IPA from twisted.internet.protocol import ReconnectingClientFactory @@ -318,8 +318,8 @@ self.log = log else: self.log = logging.getLogger('IPAFactory') - log.setLevel(logging.CRITICAL) - log.addHandler(logging.NullHandler) + self.log.setLevel(logging.CRITICAL) + self.log.addHandler(logging.NullHandler) def clientConnectionFailed(self, connector, reason): """ -- To view, visit https://gerrit.osmocom.org/2226 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ie120273eabbc670e9f19ba365508688a810a2773 Gerrit-PatchSet: 2 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Apr 4 17:03:52 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Tue, 4 Apr 2017 17:03:52 +0000 Subject: [PATCH] openbsc[master]: gsm_bts: add version and variant details In-Reply-To: References: Message-ID: Hello Neels Hofmeyr, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2161 to look at the new patch set (#6). gsm_bts: add version and variant details * add version string to gsm_bts * add PCU version string to gsm_bts * rename GSM_BTS_TYPE_OSMO_SYSMO -> GSM_BTS_OSMOBTS to avoid confusion between BTS model and variant * add variant enum to gsm_bts_model using enum with variants for each hw vendor of OsmoBTS * show connected PCU version (if available) in vty via 'show bts' This will come in handy when logging details regarding particular BTS reported via OML, see: Related: OS#1614 Change-Id: I6710d53115f34634a7b70969cc05fd5c72ff8ab2 --- M openbsc/include/openbsc/gsm_data.h M openbsc/include/openbsc/gsm_data_shared.h M openbsc/src/libbsc/abis_nm.c M openbsc/src/libbsc/bsc_vty.c M openbsc/src/libbsc/bts_sysmobts.c M openbsc/src/libbsc/e1_config.c M openbsc/src/libbsc/system_information.c M openbsc/src/libcommon/gsm_data.c M openbsc/src/libmsc/gsm_04_08.c 9 files changed, 38 insertions(+), 18 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/61/2161/6 diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h index e9ba173..02d621d 100644 --- a/openbsc/include/openbsc/gsm_data.h +++ b/openbsc/include/openbsc/gsm_data.h @@ -470,7 +470,7 @@ { switch (bts->type) { case GSM_BTS_TYPE_NANOBTS: - case GSM_BTS_TYPE_OSMO_SYSMO: + case GSM_BTS_TYPE_OSMOBTS: return 1; default: break; @@ -481,7 +481,7 @@ static inline int is_sysmobts_v2(struct gsm_bts *bts) { switch (bts->type) { - case GSM_BTS_TYPE_OSMO_SYSMO: + case GSM_BTS_TYPE_OSMOBTS: return 1; default: break; diff --git a/openbsc/include/openbsc/gsm_data_shared.h b/openbsc/include/openbsc/gsm_data_shared.h index 06fa8dd..242889a 100644 --- a/openbsc/include/openbsc/gsm_data_shared.h +++ b/openbsc/include/openbsc/gsm_data_shared.h @@ -64,6 +64,8 @@ #define HARDCODED_BTS1_TS 6 #define HARDCODED_BTS2_TS 11 +#define MAX_VERSION_LENGTH 64 + enum gsm_hooks { GSM_HOOK_NM_SWLOAD, GSM_HOOK_RR_PAGING, @@ -489,8 +491,17 @@ GSM_BTS_TYPE_NANOBTS, GSM_BTS_TYPE_RBS2000, GSM_BTS_TYPE_NOKIA_SITE, - GSM_BTS_TYPE_OSMO_SYSMO, + GSM_BTS_TYPE_OSMOBTS, _NUM_GSM_BTS_TYPE +}; + +enum gsm_bts_type_variant { + BTS_UNKNOWN, + BTS_OSMO_LITECELL15, + BTS_OSMO_OCTPHY, + BTS_OSMO_SYSMO, + BTS_OSMO_TRX, + _NUM_BTS_VARIANT }; struct vty; @@ -499,6 +510,7 @@ struct llist_head list; enum gsm_bts_type type; + enum gsm_bts_type_variant variant; const char *name; bool started; @@ -653,6 +665,11 @@ enum gsm_bts_type type; struct gsm_bts_model *model; enum gsm_band band; + char version[MAX_VERSION_LENGTH]; + + /* Connected PCU version (if any) */ + char pcu_version[MAX_VERSION_LENGTH]; + /* maximum Tx power that the MS is permitted to use in this cell */ int ms_max_power; diff --git a/openbsc/src/libbsc/abis_nm.c b/openbsc/src/libbsc/abis_nm.c index 8b0eec2..394c427 100644 --- a/openbsc/src/libbsc/abis_nm.c +++ b/openbsc/src/libbsc/abis_nm.c @@ -661,7 +661,7 @@ switch (bts_type) { case GSM_BTS_TYPE_NANOBTS: - case GSM_BTS_TYPE_OSMO_SYSMO: + case GSM_BTS_TYPE_OSMOBTS: rc = abis_nm_rx_ipacc(mb); abis_nm_queue_send_next(sign_link->trx->bts); break; @@ -1646,7 +1646,7 @@ } *reason = "Unknown combination"; return -EINVAL; - case GSM_BTS_TYPE_OSMO_SYSMO: + case GSM_BTS_TYPE_OSMOBTS: /* no known restrictions */ return 0; default: diff --git a/openbsc/src/libbsc/bsc_vty.c b/openbsc/src/libbsc/bsc_vty.c index b1747aa..21afd52 100644 --- a/openbsc/src/libbsc/bsc_vty.c +++ b/openbsc/src/libbsc/bsc_vty.c @@ -245,6 +245,9 @@ bts->num_trx, VTY_NEWLINE); vty_out(vty, "Description: %s%s", bts->description ? bts->description : "(null)", VTY_NEWLINE); + if (strnlen(bts->pcu_version, MAX_VERSION_LENGTH)) + vty_out(vty, "PCU version %s connected%s", bts->pcu_version, + VTY_NEWLINE); vty_out(vty, "MS Max power: %u dBm%s", bts->ms_max_power, VTY_NEWLINE); vty_out(vty, "Minimum Rx Level for Access: %i dBm%s", rxlev2dbm(bts->si_common.cell_sel_par.rxlev_acc_min), @@ -649,7 +652,7 @@ bts->early_classmark_allowed ? "allowed" : "forbidden", VTY_NEWLINE); switch (bts->type) { case GSM_BTS_TYPE_NANOBTS: - case GSM_BTS_TYPE_OSMO_SYSMO: + case GSM_BTS_TYPE_OSMOBTS: vty_out(vty, " ip.access unit_id %u %u%s", bts->ip_access.site_id, bts->ip_access.bts_id, VTY_NEWLINE); if (bts->ip_access.rsl_ip) { diff --git a/openbsc/src/libbsc/bts_sysmobts.c b/openbsc/src/libbsc/bts_sysmobts.c index e1bf661..e4b6cdc 100644 --- a/openbsc/src/libbsc/bts_sysmobts.c +++ b/openbsc/src/libbsc/bts_sysmobts.c @@ -46,7 +46,7 @@ { model_sysmobts = bts_model_nanobts; model_sysmobts.name = "sysmobts"; - model_sysmobts.type = GSM_BTS_TYPE_OSMO_SYSMO; + model_sysmobts.type = GSM_BTS_TYPE_OSMOBTS; model_sysmobts.features.data = &model_sysmobts._features_data[0]; model_sysmobts.features.data_len = diff --git a/openbsc/src/libbsc/e1_config.c b/openbsc/src/libbsc/e1_config.c index 8910d21..d57dec5 100644 --- a/openbsc/src/libbsc/e1_config.c +++ b/openbsc/src/libbsc/e1_config.c @@ -179,7 +179,7 @@ /* skip signal link initialization, this is done later for these BTS. */ if (bts->type == GSM_BTS_TYPE_NANOBTS || - bts->type == GSM_BTS_TYPE_OSMO_SYSMO) + bts->type == GSM_BTS_TYPE_OSMOBTS) return e1inp_line_update(line); /* OML link */ diff --git a/openbsc/src/libbsc/system_information.c b/openbsc/src/libbsc/system_information.c index a2dd827..2610331 100644 --- a/openbsc/src/libbsc/system_information.c +++ b/openbsc/src/libbsc/system_information.c @@ -830,7 +830,7 @@ /* ip.access nanoBTS needs l2_plen!! */ switch (bts->type) { case GSM_BTS_TYPE_NANOBTS: - case GSM_BTS_TYPE_OSMO_SYSMO: + case GSM_BTS_TYPE_OSMOBTS: *output++ = GSM48_LEN2PLEN(l2_plen); l2_plen++; break; @@ -865,7 +865,7 @@ /* ip.access nanoBTS needs l2_plen!! */ switch (bts->type) { case GSM_BTS_TYPE_NANOBTS: - case GSM_BTS_TYPE_OSMO_SYSMO: + case GSM_BTS_TYPE_OSMOBTS: *output++ = GSM48_LEN2PLEN(l2_plen); l2_plen++; break; @@ -909,7 +909,7 @@ /* ip.access nanoBTS needs l2_plen!! */ switch (bts->type) { case GSM_BTS_TYPE_NANOBTS: - case GSM_BTS_TYPE_OSMO_SYSMO: + case GSM_BTS_TYPE_OSMOBTS: *output++ = GSM48_LEN2PLEN(l2_plen); l2_plen++; break; @@ -946,7 +946,7 @@ /* ip.access nanoBTS needs l2_plen!! */ switch (bts->type) { case GSM_BTS_TYPE_NANOBTS: - case GSM_BTS_TYPE_OSMO_SYSMO: + case GSM_BTS_TYPE_OSMOBTS: *output++ = GSM48_LEN2PLEN(l2_plen); l2_plen++; break; diff --git a/openbsc/src/libcommon/gsm_data.c b/openbsc/src/libcommon/gsm_data.c index 3e12430..fd34793 100644 --- a/openbsc/src/libcommon/gsm_data.c +++ b/openbsc/src/libcommon/gsm_data.c @@ -96,7 +96,7 @@ { GSM_BTS_TYPE_NANOBTS, "nanobts" }, { GSM_BTS_TYPE_RBS2000, "rbs2000" }, { GSM_BTS_TYPE_NOKIA_SITE, "nokia_site" }, - { GSM_BTS_TYPE_OSMO_SYSMO, "sysmobts" }, + { GSM_BTS_TYPE_OSMOBTS, "sysmobts" }, { 0, NULL } }; @@ -106,7 +106,7 @@ { GSM_BTS_TYPE_NANOBTS, "ip.access nanoBTS or compatible" }, { GSM_BTS_TYPE_RBS2000, "Ericsson RBS2000 Series" }, { GSM_BTS_TYPE_NOKIA_SITE, "Nokia {Metro,Ultra,In}Site" }, - { GSM_BTS_TYPE_OSMO_SYSMO, "sysmocom sysmoBTS" }, + { GSM_BTS_TYPE_OSMOBTS, "sysmocom sysmoBTS" }, { 0, NULL } }; @@ -274,7 +274,7 @@ switch (bts->type) { case GSM_BTS_TYPE_NANOBTS: - case GSM_BTS_TYPE_OSMO_SYSMO: + case GSM_BTS_TYPE_OSMOBTS: /* Set the default OML Stream ID to 0xff */ bts->oml_tei = 0xff; bts->c0->nominal_power = 23; diff --git a/openbsc/src/libmsc/gsm_04_08.c b/openbsc/src/libmsc/gsm_04_08.c index c910d71..ee4e561 100644 --- a/openbsc/src/libmsc/gsm_04_08.c +++ b/openbsc/src/libmsc/gsm_04_08.c @@ -1944,7 +1944,7 @@ // todo: map between different bts types switch (bts->type) { case GSM_BTS_TYPE_NANOBTS: - case GSM_BTS_TYPE_OSMO_SYSMO: + case GSM_BTS_TYPE_OSMOBTS: if (!ipacc_rtp_direct) { if (!lchan->abis_ip.rtp_socket) { LOGP(DHO, LOGL_ERROR, "no RTP socket for " @@ -2035,7 +2035,7 @@ switch (bts->type) { case GSM_BTS_TYPE_NANOBTS: - case GSM_BTS_TYPE_OSMO_SYSMO: + case GSM_BTS_TYPE_OSMOBTS: if (ipacc_rtp_direct) { LOGP(DCC, LOGL_ERROR, "Error: RTP proxy is disabled\n"); return -EINVAL; @@ -3615,7 +3615,7 @@ bts = trans->conn->lchan->ts->trx->bts; switch (bts->type) { case GSM_BTS_TYPE_NANOBTS: - case GSM_BTS_TYPE_OSMO_SYSMO: + case GSM_BTS_TYPE_OSMOBTS: if (!trans->conn->lchan->abis_ip.rtp_socket) { DEBUGP(DMNCC, "TCH frame to lchan without RTP connection\n"); return 0; -- To view, visit https://gerrit.osmocom.org/2161 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I6710d53115f34634a7b70969cc05fd5c72ff8ab2 Gerrit-PatchSet: 6 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Tue Apr 4 17:08:54 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Tue, 4 Apr 2017 17:08:54 +0000 Subject: osmo-bts[master]: Name systemd service after the software In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+1 -- To view, visit https://gerrit.osmocom.org/2225 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ie336292c275e7415a1deedab7c3b44966aacc3bf Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Pau Espin Pedrol Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Apr 4 17:09:28 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Tue, 4 Apr 2017 17:09:28 +0000 Subject: osmo-pcu[master]: Name systemd service after the software In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+1 -- To view, visit https://gerrit.osmocom.org/2224 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ia7fa4a1868ee04ee043efd61aa55ee0c4001f12b Gerrit-PatchSet: 1 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: Pau Espin Pedrol Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Apr 4 17:23:12 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Tue, 4 Apr 2017 17:23:12 +0000 Subject: [PATCH] openbsc[master]: abis: log known ACKs and unknown messages Message-ID: Review at https://gerrit.osmocom.org/2227 abis: log known ACKs and unknown messages Log expected ACK messages and unhandled messages to aid in troubleshooting. Change-Id: Id3afaaa76e24f63076ae0e6fd2322e4a7fa29b45 Related: OS#1614 --- M openbsc/src/libbsc/abis_nm.c 1 file changed, 13 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/27/2227/1 diff --git a/openbsc/src/libbsc/abis_nm.c b/openbsc/src/libbsc/abis_nm.c index 33a23a2..c8a53bf 100644 --- a/openbsc/src/libbsc/abis_nm.c +++ b/openbsc/src/libbsc/abis_nm.c @@ -694,6 +694,15 @@ case NM_MT_BS11_LMT_SESSION: ret = abis_nm_rx_lmt_event(mb); break; + case NM_MT_OPSTART_ACK: + DEBUGP(DNM, "Opstart acked\n"); + break; + case NM_MT_SET_CHAN_ATTR_ACK: + DEBUGP(DNM, "Set Channel Attributes acked\n"); + break; + case NM_MT_SET_RADIO_ATTR_ACK: + DEBUGP(DNM, "Set Radio Carrier Attributes acked\n"); + break; case NM_MT_CONN_MDROP_LINK_ACK: DEBUGP(DNM, "CONN MDROP LINK ACK\n"); break; @@ -705,6 +714,10 @@ break; case NM_MT_SET_BTS_ATTR_ACK: break; + default: + LOGP(DNM, LOGL_ERROR, "Unhandled message %s from BTS type %s\n", + get_value_string(abis_nm_msgtype_names, mt), + btstype2str(bts->type)); } abis_nm_queue_send_next(bts); -- To view, visit https://gerrit.osmocom.org/2227 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Id3afaaa76e24f63076ae0e6fd2322e4a7fa29b45 Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Max From gerrit-no-reply at lists.osmocom.org Tue Apr 4 20:04:58 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 4 Apr 2017 20:04:58 +0000 Subject: openbsc[master]: abis: log known ACKs and unknown messages In-Reply-To: References: Message-ID: Patch Set 1: Code-Review-1 (1 comment) https://gerrit.osmocom.org/#/c/2227/1/openbsc/src/libbsc/abis_nm.c File openbsc/src/libbsc/abis_nm.c: Line 698: DEBUGP(DNM, "Opstart acked\n"); opstart of whom? you should make an effort to print the BTS number [from oml header] as well as the string version of the MO. I'm quite sure we have functions that take care of this in other places already. -- To view, visit https://gerrit.osmocom.org/2227 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Id3afaaa76e24f63076ae0e6fd2322e4a7fa29b45 Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Tue Apr 4 20:06:27 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 4 Apr 2017 20:06:27 +0000 Subject: osmo-pcu[master]: Name systemd service after the software In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+1 I would +2 this, but we need to be careful to synchronize this with the changes for the OE nightly builds to avoid breakage -- To view, visit https://gerrit.osmocom.org/2224 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ia7fa4a1868ee04ee043efd61aa55ee0c4001f12b Gerrit-PatchSet: 1 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: Pau Espin Pedrol Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Apr 4 20:06:47 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 4 Apr 2017 20:06:47 +0000 Subject: openbsc[master]: python: fix Null logger In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2226 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ie120273eabbc670e9f19ba365508688a810a2773 Gerrit-PatchSet: 2 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Apr 4 20:07:58 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 4 Apr 2017 20:07:58 +0000 Subject: osmo-bts[master]: Name systemd service after the software In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+1 sames as for the other change, we must make sure that the nightly builds won't break, or if they break manually fix up and build them again. -- To view, visit https://gerrit.osmocom.org/2225 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ie336292c275e7415a1deedab7c3b44966aacc3bf Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Pau Espin Pedrol Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Apr 4 20:09:50 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 4 Apr 2017 20:09:50 +0000 Subject: osmo-gsm-manuals[master]: gb.adoc: Add info to NS-over-UDP example In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 (1 comment) https://gerrit.osmocom.org/#/c/2223/1/common/chapters/gb.adoc File common/chapters/gb.adoc: Line 24: incoming connections from PCUs on the specified address and port. > I doubt that we really support multiple PCUs ATM so I think it's better to of course we support connections form multiple PCUs. That's what osmo-gbproxy does since 2010 or so. Also, the SGSN of course can deal with multiple PCUs connected to it - both with the libosmogb code mentioned above. -- To view, visit https://gerrit.osmocom.org/2223 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I5b6d2fb284336614da28e0d1b01c7e8c26725f81 Gerrit-PatchSet: 1 Gerrit-Project: osmo-gsm-manuals Gerrit-Branch: master Gerrit-Owner: Pau Espin Pedrol Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Tue Apr 4 20:11:27 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 4 Apr 2017 20:11:27 +0000 Subject: libosmocore[master]: gsm0808: Add utils for AoIP Transport Layer Address In-Reply-To: References: Message-ID: Patch Set 4: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2176 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I57933b0a06a3f54ec2a41e6ecb6ced9fbbc89332 Gerrit-PatchSet: 4 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Apr 4 20:12:15 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 4 Apr 2017 20:12:15 +0000 Subject: libosmocore[master]: gsm0808: Add utils for Speech Codec List and Speech Codec In-Reply-To: References: Message-ID: Patch Set 4: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2177 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I0e1e2edf47adaa45b22d4b0bcae3640dba7ca200 Gerrit-PatchSet: 4 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Apr 4 20:12:50 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 4 Apr 2017 20:12:50 +0000 Subject: libosmocore[master]: gsm0808: Add AoIP specific elements to gsm0808_create_... fu... In-Reply-To: References: Message-ID: Patch Set 4: Code-Review+1 i think we still have the 'const' here. -- To view, visit https://gerrit.osmocom.org/2178 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I77f866abec1822d19871052f3c647ad782785b34 Gerrit-PatchSet: 4 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Apr 4 20:13:21 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 4 Apr 2017 20:13:21 +0000 Subject: libosmocore[master]: gsm0808: Add utils for Channel Type In-Reply-To: References: Message-ID: Patch Set 4: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2179 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Id0e2164d84b8cbcc6fe6a090fc7f40a1251421d7 Gerrit-PatchSet: 4 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Apr 4 20:13:41 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 4 Apr 2017 20:13:41 +0000 Subject: libosmocore[master]: gsm0808: Add utils for Encryption Information In-Reply-To: References: Message-ID: Patch Set 4: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2180 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I8262050a9d9fd3f17462cfbb046c6e034dccc6fb Gerrit-PatchSet: 4 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Apr 4 20:13:52 2017 From: gerrit-no-reply at lists.osmocom.org (Holger Freyther) Date: Tue, 4 Apr 2017 20:13:52 +0000 Subject: libosmocore[master]: compiler warnings: take care of compiler warning "unused-res... In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2045 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ia2caadbed2a24f84d1d55a47236b398b74224e82 Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Thorsten Alteholz Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Apr 4 20:14:05 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 4 Apr 2017 20:14:05 +0000 Subject: libosmocore[master]: gsm0808: Add utils for Cell Identifier List In-Reply-To: References: Message-ID: Patch Set 4: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2181 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I625245dd1dd396fc2bc189e8cd2c444a33042528 Gerrit-PatchSet: 4 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Apr 4 20:14:12 2017 From: gerrit-no-reply at lists.osmocom.org (Holger Freyther) Date: Tue, 4 Apr 2017 20:14:12 +0000 Subject: libosmocore[master]: select: Find the highest fd when filling the fd_sets In-Reply-To: References: Message-ID: Patch Set 3: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/1986 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I1a6d7271273ec08bb511c21b936891bc508843e4 Gerrit-PatchSet: 3 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Holger Freyther Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Apr 4 20:14:33 2017 From: gerrit-no-reply at lists.osmocom.org (Holger Freyther) Date: Tue, 4 Apr 2017 20:14:33 +0000 Subject: [MERGED] libosmocore[master]: select: Find the highest fd when filling the fd_sets In-Reply-To: References: Message-ID: Holger Freyther has submitted this change and it was merged. Change subject: select: Find the highest fd when filling the fd_sets ...................................................................... select: Find the highest fd when filling the fd_sets Instead of returning maxfd, which is the highest fd ever seen, take the highest we have seen on this iteration. This makes a tiny difference for the osmo-sip-connector and its event loop integration. select.c ignores the return value of this function right now. This was seen while debugging the eventloop integration of the osmo-sip-connector before and after a VTY connection. The fds being polled didn't go down. Change-Id: I1a6d7271273ec08bb511c21b936891bc508843e4 --- M src/select.c 1 file changed, 12 insertions(+), 1 deletion(-) Approvals: Max: Looks good to me, but someone else must approve Jenkins Builder: Verified Holger Freyther: Looks good to me, approved diff --git a/src/select.c b/src/select.c index ab0734e..8ed7f1b 100644 --- a/src/select.c +++ b/src/select.c @@ -117,10 +117,18 @@ llist_del(&fd->list); } +/*! \brief Populate the fd_sets and return the highest fd number + * \param[in] _rset The readfds to populate + * \param[in] _wset The wrtiefds to populate + * \param[in] _eset The errorfds to populate + * + * \returns The highest file descriptor seen or 0 on an empty list + */ inline int osmo_fd_fill_fds(void *_rset, void *_wset, void *_eset) { fd_set *readset = _rset, *writeset = _wset, *exceptset = _eset; struct osmo_fd *ufd; + int highfd = 0; llist_for_each_entry(ufd, &osmo_fds, list) { if (ufd->when & BSC_FD_READ) @@ -131,9 +139,12 @@ if (ufd->when & BSC_FD_EXCEPT) FD_SET(ufd->fd, exceptset); + + if (ufd->fd > highfd) + highfd = ufd->fd; } - return maxfd; + return highfd; } inline int osmo_fd_disp_fds(void *_rset, void *_wset, void *_eset) -- To view, visit https://gerrit.osmocom.org/1986 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I1a6d7271273ec08bb511c21b936891bc508843e4 Gerrit-PatchSet: 4 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Holger Freyther Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max From gerrit-no-reply at lists.osmocom.org Tue Apr 4 20:14:47 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 4 Apr 2017 20:14:47 +0000 Subject: libosmocore[master]: gsm0808: Add create functions for CIPHER MODE COMMAND In-Reply-To: References: Message-ID: Patch Set 4: Code-Review+1 (1 comment) https://gerrit.osmocom.org/#/c/2182/4/include/osmocom/gsm/gsm0808.h File include/osmocom/gsm/gsm0808.h: Line 38: uint8_t *cipher_response_mode); const? -- To view, visit https://gerrit.osmocom.org/2182 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I8eb1c357860c3e740b0f5d17e1c256bc87920958 Gerrit-PatchSet: 4 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Tue Apr 4 20:15:09 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 4 Apr 2017 20:15:09 +0000 Subject: libosmocore[master]: gsm0808: Add create functions for BSS_MAP_MSG_PAGING In-Reply-To: References: Message-ID: Patch Set 5: Code-Review+1 (1 comment) https://gerrit.osmocom.org/#/c/2183/5/include/osmocom/gsm/gsm0808.h File include/osmocom/gsm/gsm0808.h: Line 57: struct msgb *gsm0808_create_paging(char *imsi, uint32_t *tmsi, const for all pointers? -- To view, visit https://gerrit.osmocom.org/2183 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I9afecf0109305ca5153bf081bb29cd94071dd2b7 Gerrit-PatchSet: 5 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Tue Apr 4 20:15:42 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 4 Apr 2017 20:15:42 +0000 Subject: libosmocore[master]: gsm0808: Add create functions for BSS_MAP_MSG_ASSIGMENT_RQST In-Reply-To: References: Message-ID: Patch Set 5: Code-Review+1 (1 comment) https://gerrit.osmocom.org/#/c/2184/5/include/osmocom/gsm/gsm0808.h File include/osmocom/gsm/gsm0808.h: Line 44: struct msgb *gsm0808_create_assignment(struct gsm0808_channel_type *ct, again const? -- To view, visit https://gerrit.osmocom.org/2184 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I4d1d455a1e1cf95407e23ded7b7defbcf2dd6ff0 Gerrit-PatchSet: 5 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Tue Apr 4 21:55:30 2017 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Tue, 4 Apr 2017 21:55:30 +0000 Subject: osmo-bts[master]: Name systemd service after the software In-Reply-To: References: Message-ID: Patch Set 1: Code-Review-1 The binary is called 'osmo-bts-sysmo', so let's have the service named 'osmo-bts-sysmo.service', right?? -- To view, visit https://gerrit.osmocom.org/2225 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ie336292c275e7415a1deedab7c3b44966aacc3bf Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Pau Espin Pedrol Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Wed Apr 5 08:16:26 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Wed, 5 Apr 2017 08:16:26 +0000 Subject: [MERGED] openbsc[master]: python: fix Null logger In-Reply-To: References: Message-ID: Max has submitted this change and it was merged. Change subject: python: fix Null logger ...................................................................... python: fix Null logger Change-Id: Ie120273eabbc670e9f19ba365508688a810a2773 Related: SYS#3028 --- M openbsc/contrib/twisted_ipa.py 1 file changed, 3 insertions(+), 3 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/openbsc/contrib/twisted_ipa.py b/openbsc/contrib/twisted_ipa.py index c143852..e6d7b1a 100755 --- a/openbsc/contrib/twisted_ipa.py +++ b/openbsc/contrib/twisted_ipa.py @@ -22,7 +22,7 @@ */ """ -__version__ = "0.5" # bump this on every non-trivial change +__version__ = "0.6" # bump this on every non-trivial change from ipa import Ctrl, IPA from twisted.internet.protocol import ReconnectingClientFactory @@ -318,8 +318,8 @@ self.log = log else: self.log = logging.getLogger('IPAFactory') - log.setLevel(logging.CRITICAL) - log.addHandler(logging.NullHandler) + self.log.setLevel(logging.CRITICAL) + self.log.addHandler(logging.NullHandler) def clientConnectionFailed(self, connector, reason): """ -- To view, visit https://gerrit.osmocom.org/2226 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ie120273eabbc670e9f19ba365508688a810a2773 Gerrit-PatchSet: 3 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max From gerrit-no-reply at lists.osmocom.org Wed Apr 5 09:25:40 2017 From: gerrit-no-reply at lists.osmocom.org (Pau Espin Pedrol) Date: Wed, 5 Apr 2017 09:25:40 +0000 Subject: [PATCH] osmo-iuh[master]: asn1tostruct.py: specify python version in shebang Message-ID: Review at https://gerrit.osmocom.org/2228 asn1tostruct.py: specify python version in shebang The script is expected to be run using python 2.x, but nowadays some distros are already using python 3 as default, which will fail to run this script. This change fixes compilation in my Archlinux box. Change-Id: I6eb95351538a64f2b23d638824972818591b1b66 --- M asn1/utils/asn1tostruct.py 1 file changed, 1 insertion(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/osmo-iuh refs/changes/28/2228/1 diff --git a/asn1/utils/asn1tostruct.py b/asn1/utils/asn1tostruct.py index 1a2d95f..8364c27 100755 --- a/asn1/utils/asn1tostruct.py +++ b/asn1/utils/asn1tostruct.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python2 import re, os, sys, string import datetime -- To view, visit https://gerrit.osmocom.org/2228 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I6eb95351538a64f2b23d638824972818591b1b66 Gerrit-PatchSet: 1 Gerrit-Project: osmo-iuh Gerrit-Branch: master Gerrit-Owner: Pau Espin Pedrol From gerrit-no-reply at lists.osmocom.org Wed Apr 5 09:32:57 2017 From: gerrit-no-reply at lists.osmocom.org (daniel) Date: Wed, 5 Apr 2017 09:32:57 +0000 Subject: [MERGED] osmo-gsm-manuals[master]: gb.adoc: Add info to NS-over-UDP example In-Reply-To: References: Message-ID: daniel has submitted this change and it was merged. Change subject: gb.adoc: Add info to NS-over-UDP example ...................................................................... gb.adoc: Add info to NS-over-UDP example Change-Id: I5b6d2fb284336614da28e0d1b01c7e8c26725f81 --- M common/chapters/gb.adoc 1 file changed, 3 insertions(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/common/chapters/gb.adoc b/common/chapters/gb.adoc index 199ef2c..6a6f65c 100644 --- a/common/chapters/gb.adoc +++ b/common/chapters/gb.adoc @@ -20,6 +20,9 @@ OsmoSGSN(config-ns)# encapsulation udp local-ip 127.0.0.1 <1> OsmoSGSN(config-ns)# encapsulation udp local-port 23000 <2> ---- +The example above configures a libosmogb based application to listen for +incoming connections from PCUs on the specified address and port. + <1> Set the local side IP address for NS-over-UDP <2> Set the local side UDP port number for NS-over-UDP. 23000 is the default -- To view, visit https://gerrit.osmocom.org/2223 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I5b6d2fb284336614da28e0d1b01c7e8c26725f81 Gerrit-PatchSet: 1 Gerrit-Project: osmo-gsm-manuals Gerrit-Branch: master Gerrit-Owner: Pau Espin Pedrol Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: daniel From gerrit-no-reply at lists.osmocom.org Wed Apr 5 09:46:10 2017 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Wed, 5 Apr 2017 09:46:10 +0000 Subject: [PATCH] libosmocore[master]: gsm0808: Add AoIP specific elements to gsm0808_create_... fu... In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2178 to look at the new patch set (#5). gsm0808: Add AoIP specific elements to gsm0808_create_... functions the classic A implementation in libosmocore lacks support for AoIP message elements. This patch adds support for AoIP by adding a set of new gsm0808_create_..., which support the missing AoIP message elements Change-Id: I77f866abec1822d19871052f3c647ad782785b34 --- M include/osmocom/gsm/gsm0808.h M src/gsm/gsm0808.c M src/gsm/libosmogsm.map M tests/gsm0808/gsm0808_test.c M tests/gsm0808/gsm0808_test.ok 5 files changed, 195 insertions(+), 7 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/78/2178/5 diff --git a/include/osmocom/gsm/gsm0808.h b/include/osmocom/gsm/gsm0808.h index a7e102c..fd73376 100644 --- a/include/osmocom/gsm/gsm0808.h +++ b/include/osmocom/gsm/gsm0808.h @@ -20,10 +20,17 @@ #pragma once #include "tlv.h" +#include +#include struct msgb; -struct msgb *gsm0808_create_layer3(struct msgb *msg, uint16_t netcode, uint16_t countrycode, int lac, uint16_t ci); +struct msgb *gsm0808_create_layer3(struct msgb *msg_l3, uint16_t nc, + uint16_t cc, int lac, uint16_t _ci); +struct msgb *gsm0808_create_layer3_aoip(const struct msgb *msg_l3, uint16_t nc, + uint16_t cc, int lac, uint16_t _ci, + const struct gsm0808_speech_codec_list + *scl); struct msgb *gsm0808_create_reset(void); struct msgb *gsm0808_create_reset_ack(void); struct msgb *gsm0808_create_clear_command(uint8_t reason); @@ -33,9 +40,19 @@ struct msgb *gsm0808_create_classmark_update(const uint8_t *cm2, uint8_t cm2_len, const uint8_t *cm3, uint8_t cm3_len); struct msgb *gsm0808_create_sapi_reject(uint8_t link_id); +struct msgb *gsm0808_create_ass_compl(uint8_t rr_cause, uint8_t chosen_channel, + uint8_t encr_alg_id, uint8_t speech_mode, + const struct sockaddr_storage *ss, + const struct gsm0808_speech_codec *sc, + const struct gsm0808_speech_codec_list + *scl); struct msgb *gsm0808_create_assignment_completed(uint8_t rr_cause, - uint8_t chosen_channel, uint8_t encr_alg_id, + uint8_t chosen_channel, + uint8_t encr_alg_id, uint8_t speech_mode); +struct msgb *gsm0808_create_ass_fail(uint8_t cause, const uint8_t *rr_cause, + const struct gsm0808_speech_codec_list + *scl); struct msgb *gsm0808_create_assignment_failure(uint8_t cause, uint8_t *rr_cause); struct msgb *gsm0808_create_clear_rqst(uint8_t cause); diff --git a/src/gsm/gsm0808.c b/src/gsm/gsm0808.c index de80006..b8ab79b 100644 --- a/src/gsm/gsm0808.c +++ b/src/gsm/gsm0808.c @@ -19,6 +19,7 @@ */ #include +#include #include #include @@ -27,7 +28,10 @@ #define BSSMAP_MSG_SIZE 512 #define BSSMAP_MSG_HEADROOM 128 -struct msgb *gsm0808_create_layer3(struct msgb *msg_l3, uint16_t nc, uint16_t cc, int lac, uint16_t _ci) +struct msgb *gsm0808_create_layer3_aoip(const struct msgb *msg_l3, uint16_t nc, + uint16_t cc, int lac, uint16_t _ci, + const struct gsm0808_speech_codec_list + *scl) { struct msgb* msg; struct { @@ -55,10 +59,20 @@ msgb_tlv_put(msg, GSM0808_IE_LAYER_3_INFORMATION, msgb_l3len(msg_l3), msg_l3->l3h); + /* AoIP: add Codec List (BSS Supported) 3.2.2.103 */ + if (scl) + gsm0808_enc_speech_codec_list(msg, scl); + /* push the bssmap header */ msg->l3h = msgb_tv_push(msg, BSSAP_MSG_BSS_MANAGEMENT, msgb_length(msg)); return msg; +} + +struct msgb *gsm0808_create_layer3(struct msgb *msg_l3, uint16_t nc, + uint16_t cc, int lac, uint16_t _ci) +{ + return gsm0808_create_layer3_aoip(msg_l3, nc, cc, lac, _ci, NULL); } struct msgb *gsm0808_create_reset(void) @@ -191,9 +205,12 @@ return msg; } -struct msgb *gsm0808_create_assignment_completed(uint8_t rr_cause, - uint8_t chosen_channel, uint8_t encr_alg_id, - uint8_t speech_mode) +struct msgb *gsm0808_create_ass_compl(uint8_t rr_cause, uint8_t chosen_channel, + uint8_t encr_alg_id, uint8_t speech_mode, + const struct sockaddr_storage *ss, + const struct gsm0808_speech_codec *sc, + const struct gsm0808_speech_codec_list + *scl) { struct msgb *msg = msgb_alloc_headroom(BSSMAP_MSG_SIZE, BSSMAP_MSG_HEADROOM, "bssmap: ass compl"); @@ -218,6 +235,18 @@ if (speech_mode != 0) msgb_tv_put(msg, GSM0808_IE_SPEECH_VERSION, speech_mode); + /* AoIP: AoIP Transport Layer Address (BSS) 3.2.2.102 */ + if (ss) + gsm0808_enc_aoip_trasp_addr(msg, ss); + + /* AoIP: Speech Codec (Chosen) 3.2.2.104 */ + if (sc) + gsm0808_enc_speech_codec(msg, sc); + + /* AoIP: add Codec List (BSS Supported) 3.2.2.103 */ + if (scl) + gsm0808_enc_speech_codec_list(msg, scl); + /* write LSA identifier 3.2.2.15 */ msg->l3h = msgb_tv_push(msg, BSSAP_MSG_BSS_MANAGEMENT, msgb_length(msg)); @@ -225,7 +254,18 @@ return msg; } -struct msgb *gsm0808_create_assignment_failure(uint8_t cause, uint8_t *rr_cause) +struct msgb *gsm0808_create_assignment_completed(uint8_t rr_cause, + uint8_t chosen_channel, + uint8_t encr_alg_id, + uint8_t speech_mode) +{ + return gsm0808_create_ass_compl(rr_cause, chosen_channel, encr_alg_id, + speech_mode, NULL, NULL, NULL); +} + +struct msgb *gsm0808_create_ass_fail(uint8_t cause, const uint8_t *rr_cause, + const struct gsm0808_speech_codec_list + *scl) { struct msgb *msg = msgb_alloc_headroom(BSSMAP_MSG_SIZE, BSSMAP_MSG_HEADROOM, "bssmap: ass fail"); @@ -242,12 +282,22 @@ /* Circuit pool 3.22.45 */ /* Circuit pool list 3.2.2.46 */ + /* AoIP: add Codec List (BSS Supported) 3.2.2.103 */ + if (scl) + gsm0808_enc_speech_codec_list(msg, scl); + /* update the size */ msg->l3h = msgb_tv_push(msg, BSSAP_MSG_BSS_MANAGEMENT, msgb_length(msg)); return msg; } +struct msgb *gsm0808_create_assignment_failure(uint8_t cause, + uint8_t *rr_cause) +{ + return gsm0808_create_ass_fail(cause, rr_cause, NULL); +} + struct msgb *gsm0808_create_clear_rqst(uint8_t cause) { struct msgb *msg; diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map index c89cbe4..518a5aa 100644 --- a/src/gsm/libosmogsm.map +++ b/src/gsm/libosmogsm.map @@ -125,7 +125,9 @@ gsm0808_bssap_name; gsm0808_bssmap_name; gsm0808_create_assignment_completed; +gsm0808_create_ass_compl; gsm0808_create_assignment_failure; +gsm0808_create_ass_fail; gsm0808_create_cipher_complete; gsm0808_create_cipher_reject; gsm0808_create_classmark_update; @@ -134,6 +136,7 @@ gsm0808_create_clear_rqst; gsm0808_create_dtap; gsm0808_create_layer3; +gsm0808_create_layer3_aoip; gsm0808_create_reset; gsm0808_create_sapi_reject; gsm0808_prepend_dtap_header; diff --git a/tests/gsm0808/gsm0808_test.c b/tests/gsm0808/gsm0808_test.c index b22de9b..4a4a108 100644 --- a/tests/gsm0808/gsm0808_test.c +++ b/tests/gsm0808/gsm0808_test.c @@ -41,6 +41,29 @@ abort(); \ } +/* Setup a fake codec list for testing */ +static void setup_codec_list(struct gsm0808_speech_codec_list *scl) +{ + memset(scl, 0, sizeof(*scl)); + + scl->codec[0].pi = true; + scl->codec[0].tf = true; + scl->codec[0].type = 0xab; + scl->codec[0].type_extended = true; + scl->codec[0].cfg_present = true; + scl->codec[0].cfg = 0xcdef; + + scl->codec[1].fi = true; + scl->codec[1].pt = true; + scl->codec[1].type = 0x05; + + scl->codec[2].fi = true; + scl->codec[2].tf = true; + scl->codec[2].type = 0xf2; + scl->codec[2].type_extended = true; + + scl->len = 3; +} static void test_create_layer3(void) { @@ -56,6 +79,34 @@ msg = gsm0808_create_layer3(in_msg, 0x1122, 0x2244, 0x3366, 0x4488); VERIFY(msg, res, ARRAY_SIZE(res)); + msgb_free(msg); + msgb_free(in_msg); +} + +static void test_create_layer3_aoip() +{ + static const uint8_t res[] = { + 0x00, 0x17, 0x57, 0x05, 0x08, 0x00, 0x77, 0x62, + 0x83, 0x33, 0x66, 0x44, 0x88, 0x17, 0x01, 0x23, + GSM0808_IE_SPEECH_CODEC_LIST, 0x07, 0x5f, 0xab, 0xcd, 0xef, + 0xa5, 0x9f, 0xf2 + }; + + struct msgb *msg, *in_msg; + struct gsm0808_speech_codec_list sc_list; + printf("Testing creating Layer3 (AoIP)\n"); + + setup_codec_list(&sc_list); + + in_msg = msgb_alloc_headroom(512, 128, "foo"); + in_msg->l3h = in_msg->data; + msgb_v_put(in_msg, 0x23); + + msg = + gsm0808_create_layer3_aoip(in_msg, 0x1122, 0x2244, 0x3366, 0x4488, + &sc_list); + VERIFY(msg, res, ARRAY_SIZE(res)); + msgb_free(msg); msgb_free(in_msg); } @@ -189,6 +240,42 @@ msgb_free(msg); } +static void test_create_ass_compl_aoip() +{ + struct sockaddr_storage ss; + struct sockaddr_in sin; + struct gsm0808_speech_codec sc; + struct gsm0808_speech_codec_list sc_list; + static const uint8_t res[] = + { 0x00, 0x1d, 0x02, 0x15, 0x23, 0x21, 0x42, 0x2c, 0x11, 0x40, 0x22, + GSM0808_IE_AOIP_TRASP_ADDR, 0x06, 0xc0, 0xa8, 0x64, 0x17, 0x04, + 0xd2, GSM0808_IE_SPEECH_CODEC, 0x01, 0x9a, + GSM0808_IE_SPEECH_CODEC_LIST, 0x07, 0x5f, 0xab, 0xcd, 0xef, 0xa5, + 0x9f, 0xf2 }; + struct msgb *msg; + + memset(&sin, 0, sizeof(sin)); + sin.sin_family = AF_INET; + sin.sin_port = htons(1234); + inet_aton("192.168.100.23", &sin.sin_addr); + + memset(&ss, 0, sizeof(ss)); + memcpy(&ss, &sin, sizeof(sin)); + + memset(&sc, 0, sizeof(sc)); + sc.fi = true; + sc.tf = true; + sc.type = 0x0a; + + setup_codec_list(&sc_list); + + printf("Testing creating Assignment Complete (AoIP)\n"); + msg = gsm0808_create_ass_compl(0x23, 0x42, 0x11, 0x22, + &ss, &sc, &sc_list); + VERIFY(msg, res, ARRAY_SIZE(res)); + msgb_free(msg); +} + static void test_create_ass_fail() { static const uint8_t res1[] = { 0x00, 0x04, 0x03, 0x04, 0x01, 0x23 }; @@ -203,6 +290,31 @@ msgb_free(msg); msg = gsm0808_create_assignment_failure(0x23, &rr_res); + VERIFY(msg, res2, ARRAY_SIZE(res2)); + msgb_free(msg); +} + +static void test_create_ass_fail_aoip() +{ + static const uint8_t res1[] = + { 0x00, 0x0d, 0x03, 0x04, 0x01, 0x23, GSM0808_IE_SPEECH_CODEC_LIST, + 0x07, 0x5f, 0xab, 0xcd, 0xef, 0xa5, 0x9f, 0xf2 }; + static const uint8_t res2[] = + { 0x00, 0x0f, 0x03, 0x04, 0x01, 0x23, 0x15, 0x02, + GSM0808_IE_SPEECH_CODEC_LIST, 0x07, 0x5f, 0xab, + 0xcd, 0xef, 0xa5, 0x9f, 0xf2 }; + uint8_t rr_res = 2; + struct msgb *msg; + struct gsm0808_speech_codec_list sc_list; + + setup_codec_list(&sc_list); + + printf("Testing creating Assignment Failure (AoIP)\n"); + msg = gsm0808_create_ass_fail(0x23, NULL, &sc_list); + VERIFY(msg, res1, ARRAY_SIZE(res1)); + msgb_free(msg); + + msg = gsm0808_create_ass_fail(0x23, &rr_res, &sc_list); VERIFY(msg, res2, ARRAY_SIZE(res2)); msgb_free(msg); } @@ -433,6 +545,7 @@ { printf("Testing generation of GSM0808 messages\n"); test_create_layer3(); + test_create_layer3_aoip(); test_create_reset(); test_create_clear_command(); test_create_clear_complete(); @@ -441,7 +554,9 @@ test_create_cm_u(); test_create_sapi_reject(); test_create_ass_compl(); + test_create_ass_compl_aoip(); test_create_ass_fail(); + test_create_ass_fail_aoip(); test_create_clear_rqst(); test_create_dtap(); test_prepend_dtap(); diff --git a/tests/gsm0808/gsm0808_test.ok b/tests/gsm0808/gsm0808_test.ok index eb43126..f406551 100644 --- a/tests/gsm0808/gsm0808_test.ok +++ b/tests/gsm0808/gsm0808_test.ok @@ -1,5 +1,6 @@ Testing generation of GSM0808 messages Testing creating Layer3 +Testing creating Layer3 (AoIP) Testing creating Reset Testing creating Clear Command Testing creating Clear Complete @@ -8,7 +9,9 @@ Testing creating CM U Testing creating SAPI Reject Testing creating Assignment Complete +Testing creating Assignment Complete (AoIP) Testing creating Assignment Failure +Testing creating Assignment Failure (AoIP) Testing creating Clear Request Testing creating DTAP Testing prepend DTAP -- To view, visit https://gerrit.osmocom.org/2178 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I77f866abec1822d19871052f3c647ad782785b34 Gerrit-PatchSet: 5 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Wed Apr 5 09:46:10 2017 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Wed, 5 Apr 2017 09:46:10 +0000 Subject: [PATCH] libosmocore[master]: gsm0808: Add create functions for CIPHER MODE COMMAND In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2182 to look at the new patch set (#5). gsm0808: Add create functions for CIPHER MODE COMMAND gsm0808.h/c lacks functionality to generate CIPHER MODE COMMAND messages. These messages are required if the code is used in an MSC implementation. This commit adds a gsm0808_create_cipher() function, that generates an A/AoiP CIPHER MODE COMMAND message. Change-Id: I8eb1c357860c3e740b0f5d17e1c256bc87920958 --- M include/osmocom/gsm/gsm0808.h M src/gsm/gsm0808.c M src/gsm/libosmogsm.map M tests/gsm0808/gsm0808_test.c M tests/gsm0808/gsm0808_test.ok 5 files changed, 78 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/82/2182/5 diff --git a/include/osmocom/gsm/gsm0808.h b/include/osmocom/gsm/gsm0808.h index fd73376..9738a55 100644 --- a/include/osmocom/gsm/gsm0808.h +++ b/include/osmocom/gsm/gsm0808.h @@ -35,6 +35,8 @@ struct msgb *gsm0808_create_reset_ack(void); struct msgb *gsm0808_create_clear_command(uint8_t reason); struct msgb *gsm0808_create_clear_complete(void); +struct msgb *gsm0808_create_cipher(const struct gsm0808_encrypt_info *ei, + const uint8_t *cipher_response_mode); struct msgb *gsm0808_create_cipher_complete(struct msgb *layer3, uint8_t alg_id); struct msgb *gsm0808_create_cipher_reject(uint8_t cause); struct msgb *gsm0808_create_classmark_update(const uint8_t *cm2, uint8_t cm2_len, diff --git a/src/gsm/gsm0808.c b/src/gsm/gsm0808.c index b8ab79b..c952a9f 100644 --- a/src/gsm/gsm0808.c +++ b/src/gsm/gsm0808.c @@ -131,6 +131,39 @@ return msg; } +struct msgb *gsm0808_create_cipher(const struct gsm0808_encrypt_info *ei, + const uint8_t *cipher_response_mode) +{ + /* See also: 3GPP TS 48.008 3.2.1.30 CIPHER MODE COMMAND */ + struct msgb *msg; + + /* Mandatory emelent! */ + OSMO_ASSERT(ei); + + msg = + msgb_alloc_headroom(BSSMAP_MSG_SIZE, BSSMAP_MSG_HEADROOM, + "cipher-mode-command"); + if (!msg) + return NULL; + + /* Message Type 3.2.2.1 */ + msgb_v_put(msg, BSS_MAP_MSG_CIPHER_MODE_CMD); + + /* Encryption Information 3.2.2.10 */ + gsm0808_enc_encrypt_info(msg, ei); + + /* Cipher Response Mode 3.2.2.34 */ + if (cipher_response_mode) + msgb_tv_put(msg, GSM0808_IE_CIPHER_RESPONSE_MODE, + *cipher_response_mode); + + /* pre-pend the header */ + msg->l3h = + msgb_tv_push(msg, BSSAP_MSG_BSS_MANAGEMENT, msgb_length(msg)); + + return msg; +} + struct msgb *gsm0808_create_cipher_complete(struct msgb *layer3, uint8_t alg_id) { struct msgb *msg = msgb_alloc_headroom(BSSMAP_MSG_SIZE, BSSMAP_MSG_HEADROOM, diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map index cf0a7fe..786bf08 100644 --- a/src/gsm/libosmogsm.map +++ b/src/gsm/libosmogsm.map @@ -128,6 +128,7 @@ gsm0808_create_ass_compl; gsm0808_create_assignment_failure; gsm0808_create_ass_fail; +gsm0808_create_cipher; gsm0808_create_cipher_complete; gsm0808_create_cipher_reject; gsm0808_create_classmark_update; diff --git a/tests/gsm0808/gsm0808_test.c b/tests/gsm0808/gsm0808_test.c index af457b4..f33e0bd 100644 --- a/tests/gsm0808/gsm0808_test.c +++ b/tests/gsm0808/gsm0808_test.c @@ -144,6 +144,46 @@ msgb_free(msg); } +static void test_create_cipher() +{ + static const uint8_t res[] = + { 0x00, 0x0c, 0x53, 0x0a, 0x09, 0x03, 0xaa, + 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x23, 0x42 }; + static const uint8_t res2[] = + { 0x00, 0x0e, 0x53, 0x0a, 0x09, 0x03, 0xaa, + 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x23, 0x42, + GSM0808_IE_CIPHER_RESPONSE_MODE, 0x01 }; + struct msgb *msg; + struct gsm0808_encrypt_info ei; + uint8_t include_imeisv; + + memset(&ei, 0, sizeof(ei)); + ei.perm_algo[0] = GSM0808_ALG_ID_A5_0; + ei.perm_algo[1] = GSM0808_ALG_ID_A5_1; + ei.perm_algo_len = 2; + ei.key[0] = 0xaa; + ei.key[1] = 0xbb; + ei.key[2] = 0xcc; + ei.key[3] = 0xdd; + ei.key[4] = 0xee; + ei.key[5] = 0xff; + ei.key[6] = 0x23; + ei.key[7] = 0x42; + ei.key_len = 8; + include_imeisv = 1; + + printf("Testing creating Chipher Mode Command\n"); + msg = gsm0808_create_cipher(&ei, NULL); + OSMO_ASSERT(msg); + VERIFY(msg, res, ARRAY_SIZE(res)); + msgb_free(msg); + + msg = gsm0808_create_cipher(&ei, &include_imeisv); + OSMO_ASSERT(msg); + VERIFY(msg, res2, ARRAY_SIZE(res2)); + msgb_free(msg); +} + static void test_create_cipher_complete() { static const uint8_t res1[] = { @@ -700,6 +740,7 @@ test_create_reset(); test_create_clear_command(); test_create_clear_complete(); + test_create_cipher(); test_create_cipher_complete(); test_create_cipher_reject(); test_create_cm_u(); diff --git a/tests/gsm0808/gsm0808_test.ok b/tests/gsm0808/gsm0808_test.ok index f406551..8e2087d 100644 --- a/tests/gsm0808/gsm0808_test.ok +++ b/tests/gsm0808/gsm0808_test.ok @@ -4,6 +4,7 @@ Testing creating Reset Testing creating Clear Command Testing creating Clear Complete +Testing creating Chipher Mode Command Testing creating Cipher Complete Testing creating Cipher Reject Testing creating CM U -- To view, visit https://gerrit.osmocom.org/2182 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I8eb1c357860c3e740b0f5d17e1c256bc87920958 Gerrit-PatchSet: 5 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Wed Apr 5 09:46:10 2017 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Wed, 5 Apr 2017 09:46:10 +0000 Subject: [PATCH] libosmocore[master]: gsm0808: Add create functions for BSS_MAP_MSG_PAGING In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2183 to look at the new patch set (#6). gsm0808: Add create functions for BSS_MAP_MSG_PAGING gsm0808.h/c lacks functionality to generate BSS_MAP_MSG_PAGING messages. These messages are required if the code is used in an MSC implementation. This commit adds a gsm0808_create_paging() function, that generates an A/AoiP BSS_MAP_MSG_PAGING message. Change-Id: I9afecf0109305ca5153bf081bb29cd94071dd2b7 --- M include/osmocom/gsm/gsm0808.h M src/gsm/gsm0808.c M src/gsm/libosmogsm.map M tests/gsm0808/gsm0808_test.c M tests/gsm0808/gsm0808_test.ok 5 files changed, 99 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/83/2183/6 diff --git a/include/osmocom/gsm/gsm0808.h b/include/osmocom/gsm/gsm0808.h index 9738a55..990fd74 100644 --- a/include/osmocom/gsm/gsm0808.h +++ b/include/osmocom/gsm/gsm0808.h @@ -57,6 +57,9 @@ *scl); struct msgb *gsm0808_create_assignment_failure(uint8_t cause, uint8_t *rr_cause); struct msgb *gsm0808_create_clear_rqst(uint8_t cause); +struct msgb *gsm0808_create_paging(const char *imsi, const uint32_t *tmsi, + const struct gsm0808_cell_id_list *cil, + const uint8_t *chan_needed); struct msgb *gsm0808_create_dtap(struct msgb *msg, uint8_t link_id); void gsm0808_prepend_dtap_header(struct msgb *msg, uint8_t link_id); diff --git a/src/gsm/gsm0808.c b/src/gsm/gsm0808.c index c952a9f..2721a1b 100644 --- a/src/gsm/gsm0808.c +++ b/src/gsm/gsm0808.c @@ -347,6 +347,58 @@ return msg; } +struct msgb *gsm0808_create_paging(const char *imsi, const uint32_t *tmsi, + const struct gsm0808_cell_id_list *cil, + const uint8_t *chan_needed) +{ + struct msgb *msg; + uint8_t mid_buf[GSM48_MI_SIZE + 2]; + int mid_len; + uint32_t tmsi_sw; + + /* Mandatory emelents! */ + OSMO_ASSERT(imsi); + OSMO_ASSERT(cil); + + /* Malformed IMSI */ + OSMO_ASSERT(strlen(imsi) <= GSM48_MI_SIZE); + + msg = + msgb_alloc_headroom(BSSMAP_MSG_SIZE, BSSMAP_MSG_HEADROOM, "paging"); + if (!msg) + return NULL; + + /* Message Type 3.2.2.1 */ + msgb_v_put(msg, BSS_MAP_MSG_PAGING); + + /* IMSI 3.2.2.6 */ + mid_len = gsm48_generate_mid_from_imsi(mid_buf, imsi); + msgb_tlv_put(msg, GSM0808_IE_IMSI, mid_len - 2, mid_buf + 2); + + /* TMSI 3.2.2.7 */ + if (tmsi) { + tmsi_sw = htonl(*tmsi); + msgb_tlv_put(msg, GSM0808_IE_TMSI, sizeof(*tmsi), + (uint8_t *) & tmsi_sw); + } + + /* Cell Identifier List 3.2.2.27 */ + if (cil) + gsm0808_enc_cell_id_list(msg, cil); + + /* Channel Needed 3.2.2.36 */ + if (chan_needed) { + msgb_tv_put(msg, GSM0808_IE_CHANNEL_NEEDED, + (*chan_needed) & 0x03); + } + + /* pre-pend the header */ + msg->l3h = + msgb_tv_push(msg, BSSAP_MSG_BSS_MANAGEMENT, msgb_length(msg)); + + return msg; +} + void gsm0808_prepend_dtap_header(struct msgb *msg, uint8_t link_id) { uint8_t *hh = msgb_push(msg, 3); diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map index 786bf08..ec23418 100644 --- a/src/gsm/libosmogsm.map +++ b/src/gsm/libosmogsm.map @@ -135,6 +135,7 @@ gsm0808_create_clear_command; gsm0808_create_clear_complete; gsm0808_create_clear_rqst; +gsm0808_create_paging; gsm0808_create_dtap; gsm0808_create_layer3; gsm0808_create_layer3_aoip; diff --git a/tests/gsm0808/gsm0808_test.c b/tests/gsm0808/gsm0808_test.c index f33e0bd..b0dad7d 100644 --- a/tests/gsm0808/gsm0808_test.c +++ b/tests/gsm0808/gsm0808_test.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -367,6 +368,46 @@ printf("Testing creating Clear Request\n"); msg = gsm0808_create_clear_rqst(0x23); VERIFY(msg, res, ARRAY_SIZE(res)); + msgb_free(msg); +} + +static void test_create_paging() +{ + static const uint8_t res[] = + { 0x00, 0x10, 0x52, 0x08, 0x08, 0x09, 0x10, 0x10, 0x00, 0x00, 0x00, + 0x21, 0x43, 0x1a, 0x03, 0x05, 0x23, 0x42 }; + static const uint8_t res2[] = + { 0x00, 0x16, 0x52, 0x08, 0x08, 0x09, 0x10, 0x10, 0x00, 0x00, 0x00, + 0x21, 0x43, GSM0808_IE_TMSI, 0x04, 0x12, 0x34, 0x56, 0x78, 0x1a, + 0x03, 0x05, 0x23, 0x42 }; + static const uint8_t res3[] = + { 0x00, 0x18, 0x52, 0x08, 0x08, 0x09, 0x10, 0x10, 0x00, 0x00, 0x00, + 0x21, 0x43, GSM0808_IE_TMSI, 0x04, 0x12, 0x34, 0x56, 0x78, 0x1a, + 0x03, 0x05, 0x23, 0x42, GSM0808_IE_CHANNEL_NEEDED, + RSL_CHANNEED_TCH_ForH }; + + struct msgb *msg; + struct gsm0808_cell_id_list cil; + uint32_t tmsi = 0x12345678; + uint8_t chan_needed = RSL_CHANNEED_TCH_ForH; + + char imsi[] = "001010000001234"; + + cil.id_discr = CELL_IDENT_LAC; + cil.id_list_lac[0] = 0x2342; + cil.id_list_len = 1; + + printf("Testing creating Paging Request\n"); + msg = gsm0808_create_paging(imsi, NULL, &cil, NULL); + VERIFY(msg, res, ARRAY_SIZE(res)); + msgb_free(msg); + + msg = gsm0808_create_paging(imsi, &tmsi, &cil, NULL); + VERIFY(msg, res2, ARRAY_SIZE(res2)); + msgb_free(msg); + + msg = gsm0808_create_paging(imsi, &tmsi, &cil, &chan_needed); + VERIFY(msg, res3, ARRAY_SIZE(res3)); msgb_free(msg); } @@ -750,6 +791,7 @@ test_create_ass_fail(); test_create_ass_fail_aoip(); test_create_clear_rqst(); + test_create_paging(); test_create_dtap(); test_prepend_dtap(); test_enc_dec_aoip_trasp_addr_v4(); diff --git a/tests/gsm0808/gsm0808_test.ok b/tests/gsm0808/gsm0808_test.ok index 8e2087d..6170a7a 100644 --- a/tests/gsm0808/gsm0808_test.ok +++ b/tests/gsm0808/gsm0808_test.ok @@ -14,6 +14,7 @@ Testing creating Assignment Failure Testing creating Assignment Failure (AoIP) Testing creating Clear Request +Testing creating Paging Request Testing creating DTAP Testing prepend DTAP Done -- To view, visit https://gerrit.osmocom.org/2183 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I9afecf0109305ca5153bf081bb29cd94071dd2b7 Gerrit-PatchSet: 6 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Wed Apr 5 09:46:10 2017 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Wed, 5 Apr 2017 09:46:10 +0000 Subject: [PATCH] libosmocore[master]: gsm0808: Add create functions for BSS_MAP_MSG_ASSIGMENT_RQST In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2184 to look at the new patch set (#6). gsm0808: Add create functions for BSS_MAP_MSG_ASSIGMENT_RQST gsm0808.h/c lacks functionality to generate BSS_MAP_MSG_ASSIGMENT_RQST messages. These messages are required if the code is used in an MSC implementation. This commit adds a gsm0808_create_assignment() function, that generates an A/AoiP BSS_MAP_MSG_PAGING message. Change-Id: I4d1d455a1e1cf95407e23ded7b7defbcf2dd6ff0 --- M include/osmocom/gsm/gsm0808.h M src/gsm/gsm0808.c M src/gsm/libosmogsm.map M tests/gsm0808/gsm0808_test.c M tests/gsm0808/gsm0808_test.ok 5 files changed, 113 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/84/2184/6 diff --git a/include/osmocom/gsm/gsm0808.h b/include/osmocom/gsm/gsm0808.h index 990fd74..a9f610a 100644 --- a/include/osmocom/gsm/gsm0808.h +++ b/include/osmocom/gsm/gsm0808.h @@ -42,6 +42,11 @@ struct msgb *gsm0808_create_classmark_update(const uint8_t *cm2, uint8_t cm2_len, const uint8_t *cm3, uint8_t cm3_len); struct msgb *gsm0808_create_sapi_reject(uint8_t link_id); +struct msgb *gsm0808_create_ass(const struct gsm0808_channel_type *ct, + const uint16_t *cic, + const struct sockaddr_storage *ss, + const struct gsm0808_speech_codec_list *scl, + const uint32_t *ci); struct msgb *gsm0808_create_ass_compl(uint8_t rr_cause, uint8_t chosen_channel, uint8_t encr_alg_id, uint8_t speech_mode, const struct sockaddr_storage *ss, diff --git a/src/gsm/gsm0808.c b/src/gsm/gsm0808.c index 2721a1b..be58939 100644 --- a/src/gsm/gsm0808.c +++ b/src/gsm/gsm0808.c @@ -238,6 +238,62 @@ return msg; } +struct msgb *gsm0808_create_ass(const struct gsm0808_channel_type *ct, + const uint16_t *cic, + const struct sockaddr_storage *ss, + const struct gsm0808_speech_codec_list *scl, + const uint32_t *ci) +{ + /* See also: 3GPP TS 48.008 3.2.1.1 ASSIGNMENT REQUEST */ + struct msgb *msg; + uint16_t cic_sw; + uint32_t ci_sw; + + /* Mandatory emelent! */ + OSMO_ASSERT(ct); + + msg = + msgb_alloc_headroom(BSSMAP_MSG_SIZE, BSSMAP_MSG_HEADROOM, + "bssmap: ass req"); + if (!msg) + return NULL; + + /* Message Type 3.2.2.1 */ + msgb_v_put(msg, BSS_MAP_MSG_ASSIGMENT_RQST); + + /* Channel Type 3.2.2.11 */ + gsm0808_enc_channel_type(msg, ct); + + /* Circuit Identity Code 3.2.2.2 */ + if (cic) { + cic_sw = htons(*cic); + msgb_tv_fixed_put(msg, GSM0808_IE_CIRCUIT_IDENTITY_CODE, + sizeof(cic_sw), (uint8_t *) & cic_sw); + } + + /* AoIP: AoIP Transport Layer Address (MGW) 3.2.2.102 */ + if (ss) { + gsm0808_enc_aoip_trasp_addr(msg, ss); + } + + /* AoIP: Codec List (MSC Preferred) 3.2.2.103 */ + if (scl) + gsm0808_enc_speech_codec_list(msg, scl); + + /* AoIP: Call Identifier 3.2.2.105 */ + if (ci) { + ci_sw = htonl(*ci); + msgb_tv_fixed_put(msg, GSM0808_IE_CALL_ID, sizeof(ci_sw), + (uint8_t *) & ci_sw); + } + + /* push the bssmap header */ + msg->l3h = + msgb_tv_push(msg, BSSAP_MSG_BSS_MANAGEMENT, msgb_length(msg)); + + return msg; +} + struct msgb *gsm0808_create_ass_compl(uint8_t rr_cause, uint8_t chosen_channel, uint8_t encr_alg_id, uint8_t speech_mode, const struct sockaddr_storage *ss, diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map index ec23418..a4e6083 100644 --- a/src/gsm/libosmogsm.map +++ b/src/gsm/libosmogsm.map @@ -124,6 +124,7 @@ gsm0808_att_tlvdef; gsm0808_bssap_name; gsm0808_bssmap_name; +gsm0808_create_ass; gsm0808_create_assignment_completed; gsm0808_create_ass_compl; gsm0808_create_assignment_failure; diff --git a/tests/gsm0808/gsm0808_test.c b/tests/gsm0808/gsm0808_test.c index b0dad7d..a0ff6d5 100644 --- a/tests/gsm0808/gsm0808_test.c +++ b/tests/gsm0808/gsm0808_test.c @@ -262,6 +262,55 @@ msgb_free(msg); } +static void test_create_ass() +{ + static const uint8_t res1[] = + { 0x00, 0x0a, 0x01, 0x0b, 0x04, 0x01, 0x0b, 0xa1, 0x25, 0x01, 0x00, + 0x04 }; + static const uint8_t res2[] = + { 0x00, 0x20, 0x01, 0x0b, 0x04, 0x01, 0x0b, 0xa1, 0x25, 0x01, 0x00, + 0x04, GSM0808_IE_AOIP_TRASP_ADDR, 0x06, 0xc0, 0xa8, 0x64, 0x17, + 0x04, 0xd2, GSM0808_IE_SPEECH_CODEC_LIST, 0x07, 0x5f, 0xab, 0xcd, + 0xef, 0xa5, 0x9f, 0xf2, GSM0808_IE_CALL_ID, 0xaa, 0xbb, 0xcc, + 0xdd }; + + struct msgb *msg; + struct gsm0808_channel_type ct; + uint16_t cic = 0004; + struct sockaddr_storage ss; + struct sockaddr_in sin; + struct gsm0808_speech_codec_list sc_list; + uint32_t call_id = 0xAABBCCDD; + + memset(&ct, 0, sizeof(ct)); + ct.ch_indctr = GSM0808_CHAN_SPEECH; + ct.ch_rate_type = GSM0808_SPEECH_HALF_PREF; + ct.perm_spch[0] = GSM0808_PERM_FR3; + ct.perm_spch[1] = GSM0808_PERM_HR3; + ct.perm_spch_len = 2; + + memset(&sin, 0, sizeof(sin)); + sin.sin_family = AF_INET; + sin.sin_port = htons(1234); + inet_aton("192.168.100.23", &sin.sin_addr); + + memset(&ss, 0, sizeof(ss)); + memcpy(&ss, &sin, sizeof(sin)); + + setup_codec_list(&sc_list); + + printf("Testing creating Assignment Request\n"); + msg = gsm0808_create_ass(&ct, &cic, NULL, NULL, NULL); + OSMO_ASSERT(msg); + VERIFY(msg, res1, ARRAY_SIZE(res1)); + msgb_free(msg); + + msg = gsm0808_create_ass(&ct, &cic, &ss, &sc_list, &call_id); + OSMO_ASSERT(msg); + VERIFY(msg, res2, ARRAY_SIZE(res2)); + msgb_free(msg); +} + static void test_create_ass_compl() { static const uint8_t res1[] = { @@ -786,6 +835,7 @@ test_create_cipher_reject(); test_create_cm_u(); test_create_sapi_reject(); + test_create_ass(); test_create_ass_compl(); test_create_ass_compl_aoip(); test_create_ass_fail(); diff --git a/tests/gsm0808/gsm0808_test.ok b/tests/gsm0808/gsm0808_test.ok index 6170a7a..52af134 100644 --- a/tests/gsm0808/gsm0808_test.ok +++ b/tests/gsm0808/gsm0808_test.ok @@ -9,6 +9,7 @@ Testing creating Cipher Reject Testing creating CM U Testing creating SAPI Reject +Testing creating Assignment Request Testing creating Assignment Complete Testing creating Assignment Complete (AoIP) Testing creating Assignment Failure -- To view, visit https://gerrit.osmocom.org/2184 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I4d1d455a1e1cf95407e23ded7b7defbcf2dd6ff0 Gerrit-PatchSet: 6 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Wed Apr 5 09:52:00 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Wed, 5 Apr 2017 09:52:00 +0000 Subject: [PATCH] openbsc[master]: abis: log known ACKs and unknown messages In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2227 to look at the new patch set (#2). abis: log known ACKs and unknown messages Log expected ACK messages and unhandled messages to aid in troubleshooting. Change-Id: Id3afaaa76e24f63076ae0e6fd2322e4a7fa29b45 Related: OS#1614 --- M openbsc/src/libbsc/abis_nm.c 1 file changed, 22 insertions(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/27/2227/2 diff --git a/openbsc/src/libbsc/abis_nm.c b/openbsc/src/libbsc/abis_nm.c index 33a23a2..ff0a70b 100644 --- a/openbsc/src/libbsc/abis_nm.c +++ b/openbsc/src/libbsc/abis_nm.c @@ -694,8 +694,25 @@ case NM_MT_BS11_LMT_SESSION: ret = abis_nm_rx_lmt_event(mb); break; + case NM_MT_OPSTART_ACK: + abis_nm_debugp_foh(DNM, foh); + DEBUGP(DNM, "Opstart acked by BTS %u type %s\n", bts->nr, + btstype2str(bts->type)); + break; + case NM_MT_SET_CHAN_ATTR_ACK: + abis_nm_debugp_foh(DNM, foh); + DEBUGP(DNM, "Set Channel Attributes acked by BTS %u type %s\n", + bts->nr, btstype2str(bts->type)); + break; + case NM_MT_SET_RADIO_ATTR_ACK: + abis_nm_debugp_foh(DNM, foh); + DEBUGP(DNM, "Set Radio Carrier Attributes acked by BTS %u type %s\n", + bts->nr, btstype2str(bts->type)); + break; case NM_MT_CONN_MDROP_LINK_ACK: - DEBUGP(DNM, "CONN MDROP LINK ACK\n"); + abis_nm_debugp_foh(DNM, foh); + DEBUGP(DNM, "CONN MDROP LINK acked by BTS %u type %s\n", + bts->nr, btstype2str(bts->type)); break; case NM_MT_IPACC_RESTART_ACK: osmo_signal_dispatch(SS_NM, S_NM_IPACC_RESTART_ACK, NULL); @@ -705,6 +722,10 @@ break; case NM_MT_SET_BTS_ATTR_ACK: break; + default: + LOGP(DNM, LOGL_ERROR, "Unhandled message %s from BTS type %s\n", + get_value_string(abis_nm_msgtype_names, mt), + btstype2str(bts->type)); } abis_nm_queue_send_next(bts); -- To view, visit https://gerrit.osmocom.org/2227 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Id3afaaa76e24f63076ae0e6fd2322e4a7fa29b45 Gerrit-PatchSet: 2 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Wed Apr 5 10:10:20 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Wed, 5 Apr 2017 10:10:20 +0000 Subject: osmo-bts[master]: Name systemd service after the software In-Reply-To: References: Message-ID: Patch Set 1: I wonder if it's worth it to merge common parts with debian/osmo-bts-trx.service? -- To view, visit https://gerrit.osmocom.org/2225 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ie336292c275e7415a1deedab7c3b44966aacc3bf Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Pau Espin Pedrol Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Wed Apr 5 10:40:15 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Wed, 5 Apr 2017 10:40:15 +0000 Subject: libosmocore[master]: gsm0808: Add create functions for BSS_MAP_MSG_ASSIGMENT_RQST In-Reply-To: References: Message-ID: Patch Set 6: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2184 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I4d1d455a1e1cf95407e23ded7b7defbcf2dd6ff0 Gerrit-PatchSet: 6 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Wed Apr 5 10:41:24 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Wed, 5 Apr 2017 10:41:24 +0000 Subject: libosmocore[master]: gsm0808: Add create functions for BSS_MAP_MSG_PAGING In-Reply-To: References: Message-ID: Patch Set 6: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2183 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I9afecf0109305ca5153bf081bb29cd94071dd2b7 Gerrit-PatchSet: 6 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Wed Apr 5 10:41:42 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Wed, 5 Apr 2017 10:41:42 +0000 Subject: libosmo-sccp[master]: Add new 'osmo_ss7' SS7 core code with M3UA, ASP/AS FSM, ... In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2209 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I375eb80f01acc013094851d91d1d3333ebc12bc7 Gerrit-PatchSet: 2 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Wed Apr 5 10:44:13 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Wed, 5 Apr 2017 10:44:13 +0000 Subject: openbsc[master]: abis: log known ACKs and unknown messages In-Reply-To: References: Message-ID: Patch Set 2: Code-Review-2 (1 comment) https://gerrit.osmocom.org/#/c/2227/2/openbsc/src/libbsc/abis_nm.c File openbsc/src/libbsc/abis_nm.c: Line 700: btstype2str(bts->type)); The BTS type is not useful here (it is static configuratoin for one given BTS number). The MO class + instance is the important information. Was it TS0 on TRX1 that sent us th emessage? Opstart messages are not sent "by a bts" but by one specific managed objcet identified by the MO header. -- To view, visit https://gerrit.osmocom.org/2227 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Id3afaaa76e24f63076ae0e6fd2322e4a7fa29b45 Gerrit-PatchSet: 2 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Wed Apr 5 11:01:42 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Wed, 5 Apr 2017 11:01:42 +0000 Subject: [PATCH] openbsc[master]: abis: log known ACKs and unknown messages In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2227 to look at the new patch set (#3). abis: log known ACKs and unknown messages Log expected ACK messages and unhandled messages to aid in troubleshooting. Change-Id: Id3afaaa76e24f63076ae0e6fd2322e4a7fa29b45 Related: OS#1614 --- M openbsc/src/libbsc/abis_nm.c 1 file changed, 17 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/27/2227/3 diff --git a/openbsc/src/libbsc/abis_nm.c b/openbsc/src/libbsc/abis_nm.c index 33a23a2..20e8e60 100644 --- a/openbsc/src/libbsc/abis_nm.c +++ b/openbsc/src/libbsc/abis_nm.c @@ -694,7 +694,20 @@ case NM_MT_BS11_LMT_SESSION: ret = abis_nm_rx_lmt_event(mb); break; + case NM_MT_OPSTART_ACK: + abis_nm_debugp_foh(DNM, foh); + DEBUGP(DNM, "Opstart ACK\n"); + break; + case NM_MT_SET_CHAN_ATTR_ACK: + abis_nm_debugp_foh(DNM, foh); + DEBUGP(DNM, "Set Channel Attributes ACK\n"); + break; + case NM_MT_SET_RADIO_ATTR_ACK: + abis_nm_debugp_foh(DNM, foh); + DEBUGP(DNM, "Set Radio Carrier Attributes ACK\n"); + break; case NM_MT_CONN_MDROP_LINK_ACK: + abis_nm_debugp_foh(DNM, foh); DEBUGP(DNM, "CONN MDROP LINK ACK\n"); break; case NM_MT_IPACC_RESTART_ACK: @@ -705,6 +718,10 @@ break; case NM_MT_SET_BTS_ATTR_ACK: break; + default: + abis_nm_debugp_foh(DNM, foh); + LOGP(DNM, LOGL_ERROR, "Unhandled message %s\n", + get_value_string(abis_nm_msgtype_names, mt)); } abis_nm_queue_send_next(bts); -- To view, visit https://gerrit.osmocom.org/2227 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Id3afaaa76e24f63076ae0e6fd2322e4a7fa29b45 Gerrit-PatchSet: 3 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Wed Apr 5 11:47:11 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Wed, 5 Apr 2017 11:47:11 +0000 Subject: [PATCH] openbsc[master]: abis: log known ACKs and unknown messages In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2227 to look at the new patch set (#4). abis: log known ACKs and unknown messages Log expected ACK messages and unhandled messages to aid in troubleshooting. Change-Id: Id3afaaa76e24f63076ae0e6fd2322e4a7fa29b45 Related: OS#1614 --- M openbsc/src/libbsc/abis_nm.c 1 file changed, 18 insertions(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/27/2227/4 diff --git a/openbsc/src/libbsc/abis_nm.c b/openbsc/src/libbsc/abis_nm.c index 33a23a2..651ca02 100644 --- a/openbsc/src/libbsc/abis_nm.c +++ b/openbsc/src/libbsc/abis_nm.c @@ -694,8 +694,21 @@ case NM_MT_BS11_LMT_SESSION: ret = abis_nm_rx_lmt_event(mb); break; + case NM_MT_OPSTART_ACK: + abis_nm_debugp_foh(DNM, foh); + DEBUGPC(DNM, "Opstart ACK\n"); + break; + case NM_MT_SET_CHAN_ATTR_ACK: + abis_nm_debugp_foh(DNM, foh); + DEBUGPC(DNM, "Set Channel Attributes ACK\n"); + break; + case NM_MT_SET_RADIO_ATTR_ACK: + abis_nm_debugp_foh(DNM, foh); + DEBUGPC(DNM, "Set Radio Carrier Attributes ACK\n"); + break; case NM_MT_CONN_MDROP_LINK_ACK: - DEBUGP(DNM, "CONN MDROP LINK ACK\n"); + abis_nm_debugp_foh(DNM, foh); + DEBUGPC(DNM, "CONN MDROP LINK ACK\n"); break; case NM_MT_IPACC_RESTART_ACK: osmo_signal_dispatch(SS_NM, S_NM_IPACC_RESTART_ACK, NULL); @@ -705,6 +718,10 @@ break; case NM_MT_SET_BTS_ATTR_ACK: break; + default: + abis_nm_debugp_foh(DNM, foh); + LOGPC(DNM, LOGL_ERROR, "Unhandled message %s\n", + get_value_string(abis_nm_msgtype_names, mt)); } abis_nm_queue_send_next(bts); -- To view, visit https://gerrit.osmocom.org/2227 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Id3afaaa76e24f63076ae0e6fd2322e4a7fa29b45 Gerrit-PatchSet: 4 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Wed Apr 5 12:13:13 2017 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Wed, 5 Apr 2017 12:13:13 +0000 Subject: osmo-iuh[master]: asn1tostruct.py: specify python version in shebang In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2228 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I6eb95351538a64f2b23d638824972818591b1b66 Gerrit-PatchSet: 1 Gerrit-Project: osmo-iuh Gerrit-Branch: master Gerrit-Owner: Pau Espin Pedrol Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Wed Apr 5 12:13:16 2017 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Wed, 5 Apr 2017 12:13:16 +0000 Subject: [MERGED] osmo-iuh[master]: asn1tostruct.py: specify python version in shebang In-Reply-To: References: Message-ID: Neels Hofmeyr has submitted this change and it was merged. Change subject: asn1tostruct.py: specify python version in shebang ...................................................................... asn1tostruct.py: specify python version in shebang The script is expected to be run using python 2.x, but nowadays some distros are already using python 3 as default, which will fail to run this script. This change fixes compilation in my Archlinux box. Change-Id: I6eb95351538a64f2b23d638824972818591b1b66 --- M asn1/utils/asn1tostruct.py 1 file changed, 1 insertion(+), 1 deletion(-) Approvals: Neels Hofmeyr: Looks good to me, approved Jenkins Builder: Verified diff --git a/asn1/utils/asn1tostruct.py b/asn1/utils/asn1tostruct.py index 1a2d95f..8364c27 100755 --- a/asn1/utils/asn1tostruct.py +++ b/asn1/utils/asn1tostruct.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python2 import re, os, sys, string import datetime -- To view, visit https://gerrit.osmocom.org/2228 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I6eb95351538a64f2b23d638824972818591b1b66 Gerrit-PatchSet: 1 Gerrit-Project: osmo-iuh Gerrit-Branch: master Gerrit-Owner: Pau Espin Pedrol Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Wed Apr 5 15:58:57 2017 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Wed, 5 Apr 2017 15:58:57 +0000 Subject: [PATCH] libosmocore[master]: gsm0808: make gsm0808_create_reset_ack() accessible Message-ID: Review at https://gerrit.osmocom.org/2229 gsm0808: make gsm0808_create_reset_ack() accessible The create function to generate the RESET ACKNOWLEDGE message is not accessible from outside, as it does not appear in limosmogsm.map. It also has not testcase. This commit adds gsm0808_create_reset_ack() to the map file and also adds a testcase. Change-Id: I82d3411484f82b4a9205d407fa0442244678f183 --- M src/gsm/libosmogsm.map M tests/gsm0808/gsm0808_test.c M tests/gsm0808/gsm0808_test.ok 3 files changed, 15 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/29/2229/1 diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map index a4e6083..c825dd5 100644 --- a/src/gsm/libosmogsm.map +++ b/src/gsm/libosmogsm.map @@ -141,6 +141,7 @@ gsm0808_create_layer3; gsm0808_create_layer3_aoip; gsm0808_create_reset; +gsm0808_create_reset_ack; gsm0808_create_sapi_reject; gsm0808_prepend_dtap_header; gsm0808_enc_aoip_trasp_addr; diff --git a/tests/gsm0808/gsm0808_test.c b/tests/gsm0808/gsm0808_test.c index a0ff6d5..8304052 100644 --- a/tests/gsm0808/gsm0808_test.c +++ b/tests/gsm0808/gsm0808_test.c @@ -123,6 +123,18 @@ msgb_free(msg); } +static void test_create_reset_ack() +{ + static const uint8_t res[] = { 0x00, 0x01, 0x31 }; + struct msgb *msg; + + printf("Testing creating Reset Ack\n"); + msg = gsm0808_create_reset_ack(); + VERIFY(msg, res, ARRAY_SIZE(res)); + msgb_free(msg); +} + + static void test_create_clear_command() { static const uint8_t res[] = { 0x20, 0x04, 0x01, 0x23 }; @@ -828,6 +840,7 @@ test_create_layer3(); test_create_layer3_aoip(); test_create_reset(); + test_create_reset_ack(); test_create_clear_command(); test_create_clear_complete(); test_create_cipher(); diff --git a/tests/gsm0808/gsm0808_test.ok b/tests/gsm0808/gsm0808_test.ok index 52af134..e101d65 100644 --- a/tests/gsm0808/gsm0808_test.ok +++ b/tests/gsm0808/gsm0808_test.ok @@ -2,6 +2,7 @@ Testing creating Layer3 Testing creating Layer3 (AoIP) Testing creating Reset +Testing creating Reset Ack Testing creating Clear Command Testing creating Clear Complete Testing creating Chipher Mode Command -- To view, visit https://gerrit.osmocom.org/2229 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I82d3411484f82b4a9205d407fa0442244678f183 Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: dexter From gerrit-no-reply at lists.osmocom.org Wed Apr 5 21:20:04 2017 From: gerrit-no-reply at lists.osmocom.org (Tom Tsou) Date: Wed, 5 Apr 2017 21:20:04 +0000 Subject: osmo-trx[master]: Configuration: Fix const and signedness compile warnings In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2221 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I701559814b2aee6f84f10e612f128da40f6a51c1 Gerrit-PatchSet: 1 Gerrit-Project: osmo-trx Gerrit-Branch: master Gerrit-Owner: Tom Tsou Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Tom Tsou Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Wed Apr 5 22:26:26 2017 From: gerrit-no-reply at lists.osmocom.org (Pau Espin Pedrol) Date: Wed, 5 Apr 2017 22:26:26 +0000 Subject: [PATCH] osmo-bts[master]: Name systemd service after the software In-Reply-To: References: Message-ID: Hello Max, Neels Hofmeyr, Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2225 to look at the new patch set (#2). Name systemd service after the software Binary name was changed from sysmobts to osmo-bts but the service file remained with the old name, which is confusing for newcomers. Added an alias to the service file for users used to the old naming. Change-Id: Ie336292c275e7415a1deedab7c3b44966aacc3bf --- M Makefile.am R contrib/osmo-bts-sysmo.service M src/osmo-bts-sysmo/misc/sysmobts_mgr_temp.c M src/osmo-bts-sysmo/misc/sysmobts_mgr_vty.c 4 files changed, 8 insertions(+), 7 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/25/2225/2 diff --git a/Makefile.am b/Makefile.am index 9a5e26f..5598c4a 100644 --- a/Makefile.am +++ b/Makefile.am @@ -5,7 +5,7 @@ # package the contrib and doc EXTRA_DIST = \ - contrib/dump_docs.py contrib/screenrc-l1fwd contrib/sysmobts.service \ + contrib/dump_docs.py contrib/screenrc-l1fwd contrib/osmo-bts-sysmo.service \ contrib/l1fwd.init contrib/screenrc-sysmobts contrib/respawn.sh \ contrib/sysmobts.init contrib/sysmobts-calib/Makefile \ contrib/sysmobts-calib/sysmobts-calib.c \ diff --git a/contrib/sysmobts.service b/contrib/osmo-bts-sysmo.service similarity index 96% rename from contrib/sysmobts.service rename to contrib/osmo-bts-sysmo.service index e07a3db..bbb2bef 100644 --- a/contrib/sysmobts.service +++ b/contrib/osmo-bts-sysmo.service @@ -17,3 +17,4 @@ [Install] WantedBy=multi-user.target +Alias=sysmobts.service diff --git a/src/osmo-bts-sysmo/misc/sysmobts_mgr_temp.c b/src/osmo-bts-sysmo/misc/sysmobts_mgr_temp.c index f01fd14..bdb8000 100644 --- a/src/osmo-bts-sysmo/misc/sysmobts_mgr_temp.c +++ b/src/osmo-bts-sysmo/misc/sysmobts_mgr_temp.c @@ -116,7 +116,7 @@ * and used SIGCHLD/waitpid to pick up the dead processes * without invoking shell. */ - system("/bin/systemctl start sysmobts.service"); + system("/bin/systemctl start osmo-bts-sysmo.service"); } } @@ -157,7 +157,7 @@ * and used SIGCHLD/waitpid to pick up the dead processes * without invoking shell. */ - system("/bin/systemctl stop sysmobts.service"); + system("/bin/systemctl stop osmo-bts-sysmo.service"); } } diff --git a/src/osmo-bts-sysmo/misc/sysmobts_mgr_vty.c b/src/osmo-bts-sysmo/misc/sysmobts_mgr_vty.c index 3020d90..b49f282 100644 --- a/src/osmo-bts-sysmo/misc/sysmobts_mgr_vty.c +++ b/src/osmo-bts-sysmo/misc/sysmobts_mgr_vty.c @@ -284,7 +284,7 @@ DEFUN(cfg_action_bts_srv_on, cfg_action_bts_srv_on_cmd, "bts-service-on", - "Start the systemd sysmobts.service\n") + "Start the systemd osmo-bts-sysmo.service\n") { int *action = vty->index; *action |= TEMP_ACT_NORM_BTS_SRV_ON; @@ -293,7 +293,7 @@ DEFUN(cfg_no_action_bts_srv_on, cfg_no_action_bts_srv_on_cmd, "no bts-service-on", - NO_STR "Start the systemd sysmobts.service\n") + NO_STR "Start the systemd osmo-bts-sysmo.service\n") { int *action = vty->index; *action &= ~TEMP_ACT_NORM_BTS_SRV_ON; @@ -338,7 +338,7 @@ DEFUN(cfg_action_bts_srv_off, cfg_action_bts_srv_off_cmd, "bts-service-off", - "Stop the systemd sysmobts.service\n") + "Stop the systemd osmo-bts-sysmo.service\n") { int *action = vty->index; *action |= TEMP_ACT_BTS_SRV_OFF; @@ -347,7 +347,7 @@ DEFUN(cfg_no_action_bts_srv_off, cfg_no_action_bts_srv_off_cmd, "no bts-service-off", - NO_STR "Stop the systemd sysmobts.service\n") + NO_STR "Stop the systemd osmo-bts-sysmo.service\n") { int *action = vty->index; *action &= ~TEMP_ACT_BTS_SRV_OFF; -- To view, visit https://gerrit.osmocom.org/2225 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ie336292c275e7415a1deedab7c3b44966aacc3bf Gerrit-PatchSet: 2 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Pau Espin Pedrol Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Wed Apr 5 22:37:10 2017 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Wed, 5 Apr 2017 22:37:10 +0000 Subject: [PATCH] pysim[master]: fixup Message-ID: Review at https://gerrit.osmocom.org/2230 fixup Change-Id: I32a81a2f1bc0c8f4b4eb41c45c3000f60b2902c3 --- M pySim/commands.py 1 file changed, 2 insertions(+), 2 deletions(-) git pull ssh://gerrit.osmocom.org:29418/pysim refs/changes/30/2230/1 diff --git a/pySim/commands.py b/pySim/commands.py index d8bd8f2..777dd24 100644 --- a/pySim/commands.py +++ b/pySim/commands.py @@ -29,7 +29,7 @@ def __init__(self, transport): self._tp = transport; self._cla_byte = "a0" - self._sel_ctrl = "0000" + self.sel_ctrl = "0000" @property def cla_byte(self): @@ -48,7 +48,7 @@ def select_file(self, dir_list): rv = [] for i in dir_list: - data, sw = self._tp.send_apdu_checksw(self.cla_byte + "a4" + self._sel_ctrl + "02" + i) + data, sw = self._tp.send_apdu_checksw(self.cla_byte + "a4" + self.sel_ctrl + "02" + i) rv.append(data) return rv -- To view, visit https://gerrit.osmocom.org/2230 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I32a81a2f1bc0c8f4b4eb41c45c3000f60b2902c3 Gerrit-PatchSet: 1 Gerrit-Project: pysim Gerrit-Branch: master Gerrit-Owner: dexter From gerrit-no-reply at lists.osmocom.org Wed Apr 5 22:38:51 2017 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Wed, 5 Apr 2017 22:38:51 +0000 Subject: [ABANDON] pysim[master]: fixup In-Reply-To: References: Message-ID: dexter has abandoned this change. Change subject: fixup ...................................................................... Abandoned -- To view, visit https://gerrit.osmocom.org/2230 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: abandon Gerrit-Change-Id: I32a81a2f1bc0c8f4b4eb41c45c3000f60b2902c3 Gerrit-PatchSet: 1 Gerrit-Project: pysim Gerrit-Branch: master Gerrit-Owner: dexter From gerrit-no-reply at lists.osmocom.org Wed Apr 5 22:38:59 2017 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Wed, 5 Apr 2017 22:38:59 +0000 Subject: [PATCH] pysim[master]: Fix select control parameter In-Reply-To: References: Message-ID: Hello Neels Hofmeyr, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2174 to look at the new patch set (#2). Fix select control parameter sysmo-usim-sjs1 requires P2 to be set to 0x0C (request FCI) when using the USIM application commands. The FCI is not used by pysim anyway and might even cause problems with other cards. This commit adds a pair of get/set methods to the SimCardCommands class in order to set a default for the selection control parameters (P1, P2). (Similar to the set/get methods for the class byte) The SysmoUSIMSJS1 class now calls the setter method for the selection control parameters inside of its constructuor and sets the selection control parameter default to "000C". This way we can be sure that we only change the behaviour for sysmo-usim-sjs1 and do not break support for any other cards. Change-Id: I1993a267c952bf37d5de1cb4e1107f445614c17b --- M pySim/cards.py M pySim/commands.py 2 files changed, 9 insertions(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/pysim refs/changes/74/2174/2 diff --git a/pySim/cards.py b/pySim/cards.py index 23352a7..fafc55f 100644 --- a/pySim/cards.py +++ b/pySim/cards.py @@ -425,6 +425,7 @@ def __init__(self, ssc): super(SysmoUSIMSJS1, self).__init__(ssc) self._scc.cla_byte = "00" + self._scc.sel_ctrl = "000C" @classmethod def autodetect(kls, scc): diff --git a/pySim/commands.py b/pySim/commands.py index b7fb77f..777dd24 100644 --- a/pySim/commands.py +++ b/pySim/commands.py @@ -29,6 +29,7 @@ def __init__(self, transport): self._tp = transport; self._cla_byte = "a0" + self.sel_ctrl = "0000" @property def cla_byte(self): @@ -37,11 +38,17 @@ def cla_byte(self, value): self._cla_byte = value + @property + def sel_ctrl(self): + return self._sel_ctrl + @sel_ctrl.setter + def sel_ctrl(self, value): + self._sel_ctrl = value def select_file(self, dir_list): rv = [] for i in dir_list: - data, sw = self._tp.send_apdu_checksw(self.cla_byte + "a4000002" + i) + data, sw = self._tp.send_apdu_checksw(self.cla_byte + "a4" + self.sel_ctrl + "02" + i) rv.append(data) return rv -- To view, visit https://gerrit.osmocom.org/2174 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I1993a267c952bf37d5de1cb4e1107f445614c17b Gerrit-PatchSet: 2 Gerrit-Project: pysim Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Wed Apr 5 22:38:59 2017 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Wed, 5 Apr 2017 22:38:59 +0000 Subject: [PATCH] pysim[master]: fix writing of ICCID for sysmo-usim-sjs1 In-Reply-To: References: Message-ID: Hello Neels Hofmeyr, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2175 to look at the new patch set (#3). fix writing of ICCID for sysmo-usim-sjs1 The programming procedure for sysmo-usim-sjs1 lacks writing the ICCID. This commit adds the missing call to update_binary() Change-Id: Ief85aa07c562d8d7b2a6dec302d2f485d0b1e577 --- M pySim/cards.py 1 file changed, 7 insertions(+), 7 deletions(-) git pull ssh://gerrit.osmocom.org:29418/pysim refs/changes/75/2175/3 diff --git a/pySim/cards.py b/pySim/cards.py index fafc55f..925c5e6 100644 --- a/pySim/cards.py +++ b/pySim/cards.py @@ -434,19 +434,19 @@ def program(self, p): + # authenticate as ADM using default key (written on the card..) + if not p['pin_adm']: + raise ValueError("Please provide a PIN-ADM as there is no default one") + self._scc.verify_chv(0x0A, h2b(p['pin_adm'])) # select MF r = self._scc.select_file(['3f00']) + # write EF.ICCID + data, sw = self._scc.update_binary('2fe2', enc_iccid(p['iccid'])) + # select DF_GSM r = self._scc.select_file(['7f20']) - - # authenticate as ADM using default key (written on the card..) - if not p['pin_adm']: - raise ValueError("Please provide a PIN-ADM as there is no default one") - - self._scc.verify_chv(0x0A, h2b(p['pin_adm'])) - # set Ki in proprietary file data, sw = self._scc.update_binary('00FF', p['ki']) -- To view, visit https://gerrit.osmocom.org/2175 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ief85aa07c562d8d7b2a6dec302d2f485d0b1e577 Gerrit-PatchSet: 3 Gerrit-Project: pysim Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Thu Apr 6 07:54:11 2017 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Thu, 6 Apr 2017 07:54:11 +0000 Subject: pysim[master]: Fix select control parameter In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+1 Verified+1 (2 comments) > Uploaded patch set 2. https://gerrit.osmocom.org/#/c/2174/1/pySim/cards.py File pySim/cards.py: Line 428: self._scc.sel_ctrl = "000C" > why are the get_ / set_ methods added when no-one is actually using them? E I have implemented the methods in order to be some sort of complete. There is also a get/set for cla_byte, ans from what I can see it is also not used. Maybe remove both? https://gerrit.osmocom.org/#/c/2174/1/pySim/commands.py File pySim/commands.py: Line 51: data, sw = self._tp.send_apdu_checksw(self.cla_byte + "a4" + self.sel_ctrl + "02" + i) > this also doesn't use sel_ctrl() Done -- To view, visit https://gerrit.osmocom.org/2174 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I1993a267c952bf37d5de1cb4e1107f445614c17b Gerrit-PatchSet: 2 Gerrit-Project: pysim Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: dexter Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Thu Apr 6 07:54:19 2017 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Thu, 6 Apr 2017 07:54:19 +0000 Subject: pysim[master]: Fix select control parameter In-Reply-To: References: Message-ID: Patch Set 2: > (2 comments) > > > Uploaded patch set 2. -- To view, visit https://gerrit.osmocom.org/2174 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I1993a267c952bf37d5de1cb4e1107f445614c17b Gerrit-PatchSet: 2 Gerrit-Project: pysim Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: dexter Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Apr 6 07:54:33 2017 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Thu, 6 Apr 2017 07:54:33 +0000 Subject: pysim[master]: Fix select control parameter In-Reply-To: References: Message-ID: Patch Set 2: > (2 comments) > > > Uploaded patch set 2. -- To view, visit https://gerrit.osmocom.org/2174 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I1993a267c952bf37d5de1cb4e1107f445614c17b Gerrit-PatchSet: 2 Gerrit-Project: pysim Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: dexter Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Apr 6 07:55:34 2017 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Thu, 6 Apr 2017 07:55:34 +0000 Subject: pysim[master]: fix writing of ICCID for sysmo-usim-sjs1 In-Reply-To: References: Message-ID: Patch Set 3: Code-Review+1 Verified+1 > Uploaded patch set 3: Patch Set 2 was rebased. -- To view, visit https://gerrit.osmocom.org/2175 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ief85aa07c562d8d7b2a6dec302d2f485d0b1e577 Gerrit-PatchSet: 3 Gerrit-Project: pysim Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: dexter Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Apr 6 11:55:58 2017 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 6 Apr 2017 11:55:58 +0000 Subject: pysim[master]: Fix select control parameter In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 (1 comment) https://gerrit.osmocom.org/#/c/2174/2/pySim/commands.py File pySim/commands.py: Line 32: self.sel_ctrl = "0000" this underscore would have been fine in the sense of initializing the internal _sel_ctrl value. But if it works like this then I'm fine. -- To view, visit https://gerrit.osmocom.org/2174 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I1993a267c952bf37d5de1cb4e1107f445614c17b Gerrit-PatchSet: 2 Gerrit-Project: pysim Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: dexter Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Thu Apr 6 11:56:13 2017 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 6 Apr 2017 11:56:13 +0000 Subject: pysim[master]: fix writing of ICCID for sysmo-usim-sjs1 In-Reply-To: References: Message-ID: Patch Set 3: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2175 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ief85aa07c562d8d7b2a6dec302d2f485d0b1e577 Gerrit-PatchSet: 3 Gerrit-Project: pysim Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: dexter Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Apr 6 11:56:16 2017 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 6 Apr 2017 11:56:16 +0000 Subject: [MERGED] pysim[master]: fix writing of ICCID for sysmo-usim-sjs1 In-Reply-To: References: Message-ID: Neels Hofmeyr has submitted this change and it was merged. Change subject: fix writing of ICCID for sysmo-usim-sjs1 ...................................................................... fix writing of ICCID for sysmo-usim-sjs1 The programming procedure for sysmo-usim-sjs1 lacks writing the ICCID. This commit adds the missing call to update_binary() Change-Id: Ief85aa07c562d8d7b2a6dec302d2f485d0b1e577 --- M pySim/cards.py 1 file changed, 7 insertions(+), 7 deletions(-) Approvals: dexter: Looks good to me, but someone else must approve; Verified Neels Hofmeyr: Looks good to me, approved diff --git a/pySim/cards.py b/pySim/cards.py index fafc55f..925c5e6 100644 --- a/pySim/cards.py +++ b/pySim/cards.py @@ -434,19 +434,19 @@ def program(self, p): + # authenticate as ADM using default key (written on the card..) + if not p['pin_adm']: + raise ValueError("Please provide a PIN-ADM as there is no default one") + self._scc.verify_chv(0x0A, h2b(p['pin_adm'])) # select MF r = self._scc.select_file(['3f00']) + # write EF.ICCID + data, sw = self._scc.update_binary('2fe2', enc_iccid(p['iccid'])) + # select DF_GSM r = self._scc.select_file(['7f20']) - - # authenticate as ADM using default key (written on the card..) - if not p['pin_adm']: - raise ValueError("Please provide a PIN-ADM as there is no default one") - - self._scc.verify_chv(0x0A, h2b(p['pin_adm'])) - # set Ki in proprietary file data, sw = self._scc.update_binary('00FF', p['ki']) -- To view, visit https://gerrit.osmocom.org/2175 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ief85aa07c562d8d7b2a6dec302d2f485d0b1e577 Gerrit-PatchSet: 3 Gerrit-Project: pysim Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: dexter From gerrit-no-reply at lists.osmocom.org Thu Apr 6 11:56:16 2017 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 6 Apr 2017 11:56:16 +0000 Subject: [MERGED] pysim[master]: Fix select control parameter In-Reply-To: References: Message-ID: Neels Hofmeyr has submitted this change and it was merged. Change subject: Fix select control parameter ...................................................................... Fix select control parameter sysmo-usim-sjs1 requires P2 to be set to 0x0C (request FCI) when using the USIM application commands. The FCI is not used by pysim anyway and might even cause problems with other cards. This commit adds a pair of get/set methods to the SimCardCommands class in order to set a default for the selection control parameters (P1, P2). (Similar to the set/get methods for the class byte) The SysmoUSIMSJS1 class now calls the setter method for the selection control parameters inside of its constructuor and sets the selection control parameter default to "000C". This way we can be sure that we only change the behaviour for sysmo-usim-sjs1 and do not break support for any other cards. Change-Id: I1993a267c952bf37d5de1cb4e1107f445614c17b --- M pySim/cards.py M pySim/commands.py 2 files changed, 9 insertions(+), 1 deletion(-) Approvals: dexter: Looks good to me, but someone else must approve; Verified Neels Hofmeyr: Looks good to me, approved diff --git a/pySim/cards.py b/pySim/cards.py index 23352a7..fafc55f 100644 --- a/pySim/cards.py +++ b/pySim/cards.py @@ -425,6 +425,7 @@ def __init__(self, ssc): super(SysmoUSIMSJS1, self).__init__(ssc) self._scc.cla_byte = "00" + self._scc.sel_ctrl = "000C" @classmethod def autodetect(kls, scc): diff --git a/pySim/commands.py b/pySim/commands.py index b7fb77f..777dd24 100644 --- a/pySim/commands.py +++ b/pySim/commands.py @@ -29,6 +29,7 @@ def __init__(self, transport): self._tp = transport; self._cla_byte = "a0" + self.sel_ctrl = "0000" @property def cla_byte(self): @@ -37,11 +38,17 @@ def cla_byte(self, value): self._cla_byte = value + @property + def sel_ctrl(self): + return self._sel_ctrl + @sel_ctrl.setter + def sel_ctrl(self, value): + self._sel_ctrl = value def select_file(self, dir_list): rv = [] for i in dir_list: - data, sw = self._tp.send_apdu_checksw(self.cla_byte + "a4000002" + i) + data, sw = self._tp.send_apdu_checksw(self.cla_byte + "a4" + self.sel_ctrl + "02" + i) rv.append(data) return rv -- To view, visit https://gerrit.osmocom.org/2174 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I1993a267c952bf37d5de1cb4e1107f445614c17b Gerrit-PatchSet: 2 Gerrit-Project: pysim Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: dexter From gerrit-no-reply at lists.osmocom.org Thu Apr 6 12:33:06 2017 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 6 Apr 2017 12:33:06 +0000 Subject: osmo-bts[master]: Name systemd service after the software In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 I'm giving +2, but emphasizing Harald's remark: when submitting, stay alert for packaging failures from jenkins. (probably the sysmocom internal jenkins as well as the public jenkins.osmocom.org). Anyway, I think the only way to resolve this is to submit and clean up later in case of fallout. -- To view, visit https://gerrit.osmocom.org/2225 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ie336292c275e7415a1deedab7c3b44966aacc3bf Gerrit-PatchSet: 2 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Pau Espin Pedrol Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Apr 6 12:41:29 2017 From: gerrit-no-reply at lists.osmocom.org (Pau Espin Pedrol) Date: Thu, 6 Apr 2017 12:41:29 +0000 Subject: osmo-bts[master]: Name systemd service after the software In-Reply-To: References: Message-ID: Patch Set 2: Fixes needed for meta-sysmocom-bsp are available in this branch (untested as I don't have the env setup here). Anyway, it seems osmo-bts_git.bb and osmo-pcu_git.bb recipes seem to pull from a specific git revision,so I guess the build should not break until those revisions are updated manually. I could not find anything to be changed in meta-telephony. If some other repo need to be upgraded please inform me. -- To view, visit https://gerrit.osmocom.org/2225 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ie336292c275e7415a1deedab7c3b44966aacc3bf Gerrit-PatchSet: 2 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Pau Espin Pedrol Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: Pau Espin Pedrol Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Apr 6 12:47:14 2017 From: gerrit-no-reply at lists.osmocom.org (Pau Espin Pedrol) Date: Thu, 6 Apr 2017 12:47:14 +0000 Subject: osmo-bts[master]: Name systemd service after the software In-Reply-To: References: Message-ID: Patch Set 2: Sorry I actually forgot to add the branch name in my previous e-mail: http://git.sysmocom.de/poky/meta-sysmocom-bsp/log/?h=sysmo2osmo -- To view, visit https://gerrit.osmocom.org/2225 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ie336292c275e7415a1deedab7c3b44966aacc3bf Gerrit-PatchSet: 2 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Pau Espin Pedrol Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: Pau Espin Pedrol Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Apr 6 16:41:29 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 6 Apr 2017 16:41:29 +0000 Subject: [PATCH] osmo-bts[master]: sysmobts: Don't start with 0dBm TRX output power before ramping Message-ID: Review at https://gerrit.osmocom.org/2231 sysmobts: Don't start with 0dBm TRX output power before ramping In case a system has a high-gain external PA (like a 40dB PA) connected externally, we cannot simply switch the transceiver to 0 dBm in trx_init() only to then start the ramping at much lower levels once the PHJ completes in trx_init_compl_cb(). The result would be a short 0 + 40 dBm spike followed by later ramping. We want to avoid that spike, particularly its associated inrush current, so let's bring up the board with smething very conservative like -50 dBm, and then ramp from there. Change-Id: I0ad91fce64f65e0213c9fcfde3390ace519055db Fixes: SYS#3259 --- M include/osmo-bts/tx_power.h M src/common/bts.c M src/common/tx_power.c M src/osmo-bts-sysmo/oml.c M tests/tx_power/tx_power_test.c 5 files changed, 30 insertions(+), 3 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/31/2231/1 diff --git a/include/osmo-bts/tx_power.h b/include/osmo-bts/tx_power.h index 8d099bc..21887c7 100644 --- a/include/osmo-bts/tx_power.h +++ b/include/osmo-bts/tx_power.h @@ -74,3 +74,5 @@ int power_ramp_start(struct gsm_bts_trx *trx, int p_total_tgt_mdBm, int bypass); void power_trx_change_compl(struct gsm_bts_trx *trx, int p_trxout_cur_mdBm); + +int power_ramp_initial_power_mdBm(struct gsm_bts_trx *trx); diff --git a/src/common/bts.c b/src/common/bts.c index 9915e1c..540caaa 100644 --- a/src/common/bts.c +++ b/src/common/bts.c @@ -153,7 +153,7 @@ } } /* Default values for the power adjustments */ - tpp->ramp.max_initial_pout_mdBm = to_mdB(23); + tpp->ramp.max_initial_pout_mdBm = to_mdB(0); tpp->ramp.step_size_mdB = to_mdB(2); tpp->ramp.step_interval_sec = 1; } diff --git a/src/common/tx_power.c b/src/common/tx_power.c index c517918..3dfe1f7 100644 --- a/src/common/tx_power.c +++ b/src/common/tx_power.c @@ -289,3 +289,18 @@ return 0; } + +/* determine the initial transceiver output power at start-up time */ +int power_ramp_initial_power_mdBm(struct gsm_bts_trx *trx) +{ + struct trx_power_params *tpp = &trx->power_params; + int pout_mdBm; + + /* this is the maximum initial output on the antenna connector + * towards the antenna */ + pout_mdBm = tpp->ramp.max_initial_pout_mdBm; + + /* use this as input to compute transceiver board power + * (reflecting gains in internal/external amplifiers */ + return get_p_trxout_eff_mdBm(trx, pout_mdBm); +} diff --git a/src/osmo-bts-sysmo/oml.c b/src/osmo-bts-sysmo/oml.c index 01752d1..776a50c 100644 --- a/src/osmo-bts-sysmo/oml.c +++ b/src/osmo-bts-sysmo/oml.c @@ -389,6 +389,7 @@ GsmL1_MphInitReq_t *mi_req; GsmL1_DeviceParam_t *dev_par; int femto_band; + int initial_mdBm = power_ramp_initial_power_mdBm(trx); if (!gsm_abis_mo_check_attr(&trx->mo, trx_rqd_attr, ARRAY_SIZE(trx_rqd_attr))) { @@ -416,11 +417,12 @@ dev_par->fRxPowerLevel = trx_ms_pwr_ctrl_is_osmo(trx) ? 0.0 : btsb->ul_power_target; - dev_par->fTxPowerLevel = 0.0; + dev_par->fTxPowerLevel = ((float) initial_mdBm) / 1000; LOGP(DL1C, LOGL_NOTICE, "Init TRX (ARFCN %u, TSC %u, RxPower % 2f dBm, " "TxPower % 2.2f dBm\n", dev_par->u16Arfcn, dev_par->u8NbTsc, dev_par->fRxPowerLevel, dev_par->fTxPowerLevel); - + trx->power_params.p_total_cur_mdBm = trx->power_params.ramp.max_initial_pout_mdBm; + /* send MPH-INIT-REQ, wait for MPH-INIT-CNF */ return l1if_gsm_req_compl(fl1h, msg, trx_init_compl_cb, NULL); } diff --git a/tests/tx_power/tx_power_test.c b/tests/tx_power/tx_power_test.c index d657362..fb23409 100644 --- a/tests/tx_power/tx_power_test.c +++ b/tests/tx_power/tx_power_test.c @@ -44,6 +44,7 @@ .nominal_gain_mdB = 0, }, .ramp = { + .max_initial_pout_mdBm = to_mdB(23), .step_size_mdB = to_mdB(2), .step_interval_sec = 1, }, @@ -62,6 +63,7 @@ .nominal_gain_mdB = 0, }, .ramp = { + .max_initial_pout_mdBm = to_mdB(0), .step_size_mdB = to_mdB(2), .step_interval_sec = 1, }, @@ -80,6 +82,7 @@ .nominal_gain_mdB = 0, }, .ramp = { + .max_initial_pout_mdBm = to_mdB(0), .step_size_mdB = to_mdB(2), .step_interval_sec = 1, }, @@ -98,6 +101,7 @@ .nominal_gain_mdB = 0, }, .ramp = { + .max_initial_pout_mdBm = to_mdB(0), .step_size_mdB = to_mdB(2), .step_interval_sec = 1, }, @@ -108,6 +112,7 @@ printf("Testing tx_power calculation for sysmoBTS 1002\n"); trx->power_params = tpp_1002; trx->max_power_red = 0; + OSMO_ASSERT(power_ramp_initial_power_mdBm(trx) == to_mdB(23)); OSMO_ASSERT(get_p_max_out_mdBm(trx) == to_mdB(23)); /* at max_power_red = 0, we expect full 23dBm */ OSMO_ASSERT(get_p_nominal_mdBm(trx) == to_mdB(23)); @@ -125,6 +130,7 @@ printf("Testing tx_power calculation for sysmoBTS 1020\n"); trx->power_params = tpp_1020; trx->max_power_red = 0; + OSMO_ASSERT(power_ramp_initial_power_mdBm(trx) == to_mdB(-10)); OSMO_ASSERT(get_p_max_out_mdBm(trx) == to_mdB(33)); /* at max_power_red = 0, we expect full 33dBm */ OSMO_ASSERT(get_p_nominal_mdBm(trx) == to_mdB(33)); @@ -143,6 +149,7 @@ printf("Testing tx_power calculation for sysmoBTS 1100\n"); trx->power_params = tpp_1100; trx->max_power_red = 0; + OSMO_ASSERT(power_ramp_initial_power_mdBm(trx) == to_mdB(-17)); OSMO_ASSERT(get_p_max_out_mdBm(trx) == to_mdB(40)); /* at max_power_red = 0, we expect full 33dBm */ OSMO_ASSERT(get_p_nominal_mdBm(trx) == to_mdB(40)); @@ -160,6 +167,7 @@ printf("Testing tx_power calculation for sysmoBTS 2050\n"); trx->power_params = tpp_2050; trx->max_power_red = 0; + OSMO_ASSERT(power_ramp_initial_power_mdBm(trx) == to_mdB(0)); OSMO_ASSERT(get_p_max_out_mdBm(trx) == to_mdB(37)); /* at max_power_red = 0, we expect full 37dBm */ OSMO_ASSERT(get_p_nominal_mdBm(trx) == to_mdB(37)); -- To view, visit https://gerrit.osmocom.org/2231 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I0ad91fce64f65e0213c9fcfde3390ace519055db Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Thu Apr 6 16:53:47 2017 From: gerrit-no-reply at lists.osmocom.org (Pau Espin Pedrol) Date: Thu, 6 Apr 2017 16:53:47 +0000 Subject: [PATCH] osmo-iuh[master]: hnbgw: Fix crash if cnlink fails to connect Message-ID: Review at https://gerrit.osmocom.org/2232 hnbgw: Fix crash if cnlink fails to connect Return NULL in the error code path, otherwise an uninitialized pointer is returned and later accessed when a UE tries to register using the cnlink. Change-Id: I4f3e2e0680de3216e2e569958bd64f70dc30c2a3 --- M src/hnbgw_cn.c 1 file changed, 1 insertion(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-iuh refs/changes/32/2232/1 diff --git a/src/hnbgw_cn.c b/src/hnbgw_cn.c index 0e993e2..4e5b2e0 100644 --- a/src/hnbgw_cn.c +++ b/src/hnbgw_cn.c @@ -409,4 +409,5 @@ osmo_sua_user_destroy(cnlink->sua_user); out_free: talloc_free(cnlink); + return NULL; } -- To view, visit https://gerrit.osmocom.org/2232 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I4f3e2e0680de3216e2e569958bd64f70dc30c2a3 Gerrit-PatchSet: 1 Gerrit-Project: osmo-iuh Gerrit-Branch: master Gerrit-Owner: Pau Espin Pedrol From gerrit-no-reply at lists.osmocom.org Fri Apr 7 08:07:11 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 7 Apr 2017 08:07:11 +0000 Subject: osmo-iuh[master]: hnbgw: Fix crash if cnlink fails to connect In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2232 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I4f3e2e0680de3216e2e569958bd64f70dc30c2a3 Gerrit-PatchSet: 1 Gerrit-Project: osmo-iuh Gerrit-Branch: master Gerrit-Owner: Pau Espin Pedrol Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Apr 7 10:20:06 2017 From: gerrit-no-reply at lists.osmocom.org (Pau Espin Pedrol) Date: Fri, 7 Apr 2017 10:20:06 +0000 Subject: [MERGED] osmo-iuh[master]: hnbgw: Fix crash if cnlink fails to connect In-Reply-To: References: Message-ID: Pau Espin Pedrol has submitted this change and it was merged. Change subject: hnbgw: Fix crash if cnlink fails to connect ...................................................................... hnbgw: Fix crash if cnlink fails to connect Return NULL in the error code path, otherwise an uninitialized pointer is returned and later accessed when a UE tries to register using the cnlink. Change-Id: I4f3e2e0680de3216e2e569958bd64f70dc30c2a3 --- M src/hnbgw_cn.c 1 file changed, 1 insertion(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/hnbgw_cn.c b/src/hnbgw_cn.c index 0e993e2..4e5b2e0 100644 --- a/src/hnbgw_cn.c +++ b/src/hnbgw_cn.c @@ -409,4 +409,5 @@ osmo_sua_user_destroy(cnlink->sua_user); out_free: talloc_free(cnlink); + return NULL; } -- To view, visit https://gerrit.osmocom.org/2232 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I4f3e2e0680de3216e2e569958bd64f70dc30c2a3 Gerrit-PatchSet: 1 Gerrit-Project: osmo-iuh Gerrit-Branch: master Gerrit-Owner: Pau Espin Pedrol Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Pau Espin Pedrol From gerrit-no-reply at lists.osmocom.org Fri Apr 7 11:21:11 2017 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 7 Apr 2017 11:21:11 +0000 Subject: [PATCH] osmo-gsm-manuals[master]: add INSTALL.txt with a list of dependencies Message-ID: Review at https://gerrit.osmocom.org/2233 add INSTALL.txt with a list of dependencies Change-Id: I0e472381270c4c4783394ef8969bc8cb6005dcfe --- A INSTALL.txt 1 file changed, 14 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-gsm-manuals refs/changes/33/2233/1 diff --git a/INSTALL.txt b/INSTALL.txt new file mode 100644 index 0000000..6f19720 --- /dev/null +++ b/INSTALL.txt @@ -0,0 +1,14 @@ +Dependencies needed, by example of a debian system: + +apt-get install \ + make \ + asciidoc \ + xsltproc \ + dblatex \ + mscgen \ + graphviz + +Build PDFs, run: + make +or for a parallel build using more CPU cores: + make -j 5 -- To view, visit https://gerrit.osmocom.org/2233 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I0e472381270c4c4783394ef8969bc8cb6005dcfe Gerrit-PatchSet: 1 Gerrit-Project: osmo-gsm-manuals Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Fri Apr 7 18:47:22 2017 From: gerrit-no-reply at lists.osmocom.org (Vadim Yanitskiy) Date: Fri, 7 Apr 2017 18:47:22 +0000 Subject: libosmocore[master]: core/conv: implement optimized Viterbi decoder In-Reply-To: References: Message-ID: Patch Set 5: Verified-1 Just rebased the change to the current master. I don't know why, but with this decoder the coding_test fails. -- To view, visit https://gerrit.osmocom.org/1337 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I74d355274b4176a7d924f91ef3c96912ce338fb2 Gerrit-PatchSet: 5 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Vadim Yanitskiy Gerrit-Reviewer: Alexander Chemeris Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Tom Tsou Gerrit-Reviewer: Vadim Yanitskiy Gerrit-Reviewer: tnt Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sat Apr 8 03:05:32 2017 From: gerrit-no-reply at lists.osmocom.org (Tom Tsou) Date: Sat, 8 Apr 2017 03:05:32 +0000 Subject: libosmocore[master]: core/conv: implement optimized Viterbi decoder In-Reply-To: References: Message-ID: Patch Set 5: > Just rebased the change to the current master. I don't know why, > but with this decoder the coding_test fails. The build failure can be fixed with the below change. In terms of decoder 'correctness' there is nothing wrong. The Viterbi ACS (add-compare-select) is based on a min() or max() function that becomes ambiguous under equivalency. The difference is whether one guesses 1 or 0 when path metrics are equal - statistically the outcomes are the same. The test case adds zeros to otherwise signed bits, which makes the code differences apparent. diff --git a/src/viterbi_gen.c b/src/viterbi_gen.c index 219b25b..7972c39 100644 --- a/src/viterbi_gen.c +++ b/src/viterbi_gen.c @@ -44,7 +44,7 @@ static void acs_butterfly(int state, int num_states, sum2 = state0 - metric; sum3 = state1 + metric; - if (sum0 > sum1) { + if (sum0 >= sum1) { *new_sum = sum0; *path = -1; } else { @@ -52,7 +52,7 @@ static void acs_butterfly(int state, int num_states, *path = 0; } - if (sum2 > sum3) { + if (sum2 >= sum3) { *(new_sum + num_states / 2) = sum2; *(path + num_states / 2) = -1; } else { -- Alternatively, matching in the other direction also brings both implementation outputs together. Neither selection is technically right or wrong. diff --git a/src/conv.c b/src/conv.c index 79b3a7c..8f007a4 100644 --- a/src/conv.c +++ b/src/conv.c @@ -405,7 +405,7 @@ osmo_conv_decode_scan(struct osmo_conv_decoder *decoder, } /* Is it survivor ? */ - if (ae_next[state] > nae) { + if (ae_next[state] >= nae) { ae_next[state] = nae; state_history[(n_states * i) + state] = s; } -- -- To view, visit https://gerrit.osmocom.org/1337 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I74d355274b4176a7d924f91ef3c96912ce338fb2 Gerrit-PatchSet: 5 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Vadim Yanitskiy Gerrit-Reviewer: Alexander Chemeris Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Tom Tsou Gerrit-Reviewer: Vadim Yanitskiy Gerrit-Reviewer: tnt Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sat Apr 8 03:40:12 2017 From: gerrit-no-reply at lists.osmocom.org (Tom Tsou) Date: Sat, 8 Apr 2017 03:40:12 +0000 Subject: libosmocore[master]: core/conv: implement optimized Viterbi decoder In-Reply-To: References: Message-ID: Patch Set 5: (2 comments) https://gerrit.osmocom.org/#/c/1337/5/src/viterbi.c File src/viterbi.c: PS5, Line 541: _cnt Can get rid of this variable. diff --git a/src/viterbi.c b/src/viterbi.c index 9422575..06aae85 100644 --- a/src/viterbi.c +++ b/src/viterbi.c @@ -538,12 +538,12 @@ static int depuncture(const int8_t *in, const int *punc, int8_t *out, int len) * accumulated path metric sums and path selections are stored. Normalize on * the interval specified by the decoder. */ -static void _conv_decode(struct vdecoder *dec, const int8_t *seq, int _cnt) +static void _conv_decode(struct vdecoder *dec, const int8_t *seq) { - int i, len = dec->len; + int i; struct vtrellis *trellis = dec->trellis; - for (i = 0; i < len; i++) { + for (i = 0; i < dec->len; i++) { dec->metric_func(&seq[dec->n * i], trellis->outputs, trellis->sums, @@ -571,10 +571,10 @@ static int conv_decode(struct vdecoder *dec, const int8_t *seq, } /* Propagate through the trellis with interval normalization */ - _conv_decode(dec, seq, cnt); + _conv_decode(dec, seq); if (term == CONV_TERM_TAIL_BITING) - _conv_decode(dec, seq, cnt); + _conv_decode(dec, seq); return traceback(dec, out, term, len); } https://gerrit.osmocom.org/#/c/1337/5/src/viterbi_gen.c File src/viterbi_gen.c: PS5, Line 47: Change > to >= in order to match existing implementation behavior. diff --git a/src/viterbi_gen.c b/src/viterbi_gen.c index 219b25b..7972c39 100644 --- a/src/viterbi_gen.c +++ b/src/viterbi_gen.c @@ -44,7 +44,7 @@ static void acs_butterfly(int state, int num_states, sum2 = state0 - metric; sum3 = state1 + metric; - if (sum0 > sum1) { + if (sum0 >= sum1) { *new_sum = sum0; *path = -1; } else { @@ -52,7 +52,7 @@ static void acs_butterfly(int state, int num_states, *path = 0; } - if (sum2 > sum3) { + if (sum2 >= sum3) { *(new_sum + num_states / 2) = sum2; *(path + num_states / 2) = -1; } else { -- To view, visit https://gerrit.osmocom.org/1337 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I74d355274b4176a7d924f91ef3c96912ce338fb2 Gerrit-PatchSet: 5 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Vadim Yanitskiy Gerrit-Reviewer: Alexander Chemeris Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Tom Tsou Gerrit-Reviewer: Vadim Yanitskiy Gerrit-Reviewer: tnt Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Sat Apr 8 06:15:23 2017 From: gerrit-no-reply at lists.osmocom.org (Vadim Yanitskiy) Date: Sat, 8 Apr 2017 06:15:23 +0000 Subject: [PATCH] libosmocore[master]: core/conv: implement optimized Viterbi decoder In-Reply-To: References: Message-ID: Hello tnt, Alexander Chemeris, Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/1337 to look at the new patch set (#6). core/conv: implement optimized Viterbi decoder Add a separate, faster convolution decoding implementation for rates up to N=4 and constraint lengths of K=5 and K=7, which covers the most GSM code uses. The decoding algorithm exploits the symmetric structure of the Viterbi add-compare-select (ACS) operation - commonly known as the ACS butterfly. This shift-register optimization can be found in the well-known text by Dave Forney. Forney, G.D., "The Viterbi Algorithm," Proc. of the IEEE, March 1973. Implementation is non-architecture specific and improves performance on x86 as well as ARM processors. Existing API is unchanged with optimized code being called internally for supported codes. The original code was relicensed under GPLv2-or-later with permission of copyright holder - Tom Tsou. Change-Id: I74d355274b4176a7d924f91ef3c96912ce338fb2 --- M src/Makefile.am M src/conv.c A src/viterbi.c A src/viterbi_gen.c 4 files changed, 806 insertions(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/37/1337/6 diff --git a/src/Makefile.am b/src/Makefile.am index 0cf2665..6948e1a 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -16,7 +16,8 @@ gsmtap_util.c crc16.c panic.c backtrace.c \ conv.c application.c rbtree.c strrb.c \ loggingrb.c crc8gen.c crc16gen.c crc32gen.c crc64gen.c \ - macaddr.c stat_item.c stats.c stats_statsd.c prim.c + macaddr.c stat_item.c stats.c stats_statsd.c prim.c \ + viterbi.c viterbi_gen.c BUILT_SOURCES = crc8gen.c crc16gen.c crc32gen.c crc64gen.c diff --git a/src/conv.c b/src/conv.c index f13deef..79b3a7c 100644 --- a/src/conv.c +++ b/src/conv.c @@ -238,6 +238,11 @@ #define MAX_AE 0x00ffffff +/* Forward declaration for accerlated decoding with certain codes */ +int +osmo_conv_decode_acc(const struct osmo_conv_code *code, + const sbit_t *input, ubit_t *output); + void osmo_conv_decode_init(struct osmo_conv_decoder *decoder, const struct osmo_conv_code *code, int len, int start_state) @@ -606,6 +611,10 @@ struct osmo_conv_decoder decoder; int rv, l; + /* Use accelerated implementation for supported codes */ + if ((code->N <= 4) && ((code->K == 5) || (code->K == 7))) + return osmo_conv_decode_acc(code, input, output); + osmo_conv_decode_init(&decoder, code, 0, 0); if (code->term == CONV_TERM_TAIL_BITING) { diff --git a/src/viterbi.c b/src/viterbi.c new file mode 100644 index 0000000..ea4fb21 --- /dev/null +++ b/src/viterbi.c @@ -0,0 +1,602 @@ +/* + * Viterbi decoder + * + * Copyright (C) 2013, 2014 Thomas Tsou + * + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include +#include +#include + +#include +#include "config.h" + +#define BIT2NRZ(REG,N) (((REG >> N) & 0x01) * 2 - 1) * -1 +#define NUM_STATES(K) (K == 7 ? 64 : 16) +#define SSE_ALIGN 16 + +/* Forward Metric Units */ +void osmo_conv_gen_metrics_k5_n2(const int8_t *seq, const int16_t *out, + int16_t *sums, int16_t *paths, int norm); +void osmo_conv_gen_metrics_k5_n3(const int8_t *seq, const int16_t *out, + int16_t *sums, int16_t *paths, int norm); +void osmo_conv_gen_metrics_k5_n4(const int8_t *seq, const int16_t *out, + int16_t *sums, int16_t *paths, int norm); +void osmo_conv_gen_metrics_k7_n2(const int8_t *seq, const int16_t *out, + int16_t *sums, int16_t *paths, int norm); +void osmo_conv_gen_metrics_k7_n3(const int8_t *seq, const int16_t *out, + int16_t *sums, int16_t *paths, int norm); +void osmo_conv_gen_metrics_k7_n4(const int8_t *seq, const int16_t *out, + int16_t *sums, int16_t *paths, int norm); + +/* Trellis State + * state - Internal lshift register value + * prev - Register values of previous 0 and 1 states + */ +struct vstate { + unsigned state; + unsigned prev[2]; +}; + +/* Trellis Object + * num_states - Number of states in the trellis + * sums - Accumulated path metrics + * outputs - Trellis output values + * vals - Input value that led to each state + */ +struct vtrellis { + int num_states; + int16_t *sums; + int16_t *outputs; + uint8_t *vals; +}; + +/* Viterbi Decoder + * n - Code order + * k - Constraint length + * len - Horizontal length of trellis + * recursive - Set to '1' if the code is recursive + * intrvl - Normalization interval + * trellis - Trellis object + * punc - Puncturing sequence + * paths - Trellis paths + */ +struct vdecoder { + int n; + int k; + int len; + int recursive; + int intrvl; + struct vtrellis *trellis; + int *punc; + int16_t **paths; + + void (*metric_func)(const int8_t *, const int16_t *, + int16_t *, int16_t *, int); +}; + +/* Aligned Memory Allocator + * SSE requires 16-byte memory alignment. We store relevant trellis values + * (accumulated sums, outputs, and path decisions) as 16 bit signed integers + * so the allocated memory is casted as such. + */ +static int16_t *vdec_malloc(size_t n) +{ +#ifdef HAVE_SSE3 + return (int16_t *) memalign(SSE_ALIGN, sizeof(int16_t) * n); +#else + return (int16_t *) malloc(sizeof(int16_t) * n); +#endif +} + +/* Accessor calls */ +static inline int conv_code_recursive(const struct osmo_conv_code *code) +{ + return code->next_term_output ? 1 : 0; +} + +/* Left shift and mask for finding the previous state */ +static unsigned vstate_lshift(unsigned reg, int k, int val) +{ + unsigned mask; + + if (k == 5) + mask = 0x0e; + else if (k == 7) + mask = 0x3e; + else + mask = 0; + + return ((reg << 1) & mask) | val; +} + +/* Bit endian manipulators */ +static inline unsigned bitswap2(unsigned v) +{ + return ((v & 0x02) >> 1) | ((v & 0x01) << 1); +} + +static inline unsigned bitswap3(unsigned v) +{ + return ((v & 0x04) >> 2) | ((v & 0x02) >> 0) | + ((v & 0x01) << 2); +} + +static inline unsigned bitswap4(unsigned v) +{ + return ((v & 0x08) >> 3) | ((v & 0x04) >> 1) | + ((v & 0x02) << 1) | ((v & 0x01) << 3); +} + +static inline unsigned bitswap5(unsigned v) +{ + return ((v & 0x10) >> 4) | ((v & 0x08) >> 2) | ((v & 0x04) >> 0) | + ((v & 0x02) << 2) | ((v & 0x01) << 4); +} + +static inline unsigned bitswap6(unsigned v) +{ + return ((v & 0x20) >> 5) | ((v & 0x10) >> 3) | ((v & 0x08) >> 1) | + ((v & 0x04) << 1) | ((v & 0x02) << 3) | ((v & 0x01) << 5); +} + +static unsigned bitswap(unsigned v, unsigned n) +{ + switch (n) { + case 1: + return v; + case 2: + return bitswap2(v); + case 3: + return bitswap3(v); + case 4: + return bitswap4(v); + case 5: + return bitswap5(v); + case 6: + return bitswap6(v); + default: + return 0; + } +} + +/* Generate non-recursive state output from generator state table + * Note that the shift register moves right (i.e. the most recent bit is + * shifted into the register at k-1 bit of the register), which is typical + * textbook representation. The API transition table expects the most recent + * bit in the low order bit, or left shift. A bitswap operation is required + * to accommodate the difference. + */ +static unsigned gen_output(struct vstate *state, int val, + const struct osmo_conv_code *code) +{ + unsigned out, prev; + + prev = bitswap(state->prev[0], code->K - 1); + out = code->next_output[prev][val]; + out = bitswap(out, code->N); + + return out; +} + +/* Populate non-recursive trellis state + * For a given state defined by the k-1 length shift register, find the + * value of the input bit that drove the trellis to that state. Also + * generate the N outputs of the generator polynomial at that state. + */ +static int gen_state_info(uint8_t *val, unsigned reg, + int16_t *output, const struct osmo_conv_code *code) +{ + int i; + unsigned out; + struct vstate state; + + /* Previous '0' state */ + state.state = reg; + state.prev[0] = vstate_lshift(reg, code->K, 0); + state.prev[1] = vstate_lshift(reg, code->K, 1); + + *val = (reg >> (code->K - 2)) & 0x01; + + /* Transition output */ + out = gen_output(&state, *val, code); + + /* Unpack to NRZ */ + for (i = 0; i < code->N; i++) + output[i] = BIT2NRZ(out, i); + + return 0; +} + +/* Generate recursive state output from generator state table */ +static unsigned gen_recursive_output(struct vstate *state, + uint8_t *val, unsigned reg, + const struct osmo_conv_code *code, int pos) +{ + int val0, val1; + unsigned out, prev; + + /* Previous '0' state */ + prev = vstate_lshift(reg, code->K, 0); + prev = bitswap(prev, code->K - 1); + + /* Input value */ + val0 = (reg >> (code->K - 2)) & 0x01; + val1 = (code->next_term_output[prev] >> pos) & 0x01; + *val = val0 == val1 ? 0 : 1; + + /* Wrapper for osmocom state access */ + prev = bitswap(state->prev[0], code->K - 1); + + /* Compute the transition output */ + out = code->next_output[prev][*val]; + out = bitswap(out, code->N); + + return out; +} + +/* Populate recursive trellis state + * The bit position of the systematic bit is not explicitly marked by the + * API, so it must be extracted from the generator table. Otherwise, + * populate the trellis similar to the non-recursive version. + * Non-systematic recursive codes are not supported. + */ +static int gen_recursive_state_info(uint8_t *val, + unsigned reg, int16_t *output, const struct osmo_conv_code *code) +{ + int i, j, pos = -1; + int ns = NUM_STATES(code->K); + unsigned out; + struct vstate state; + + /* Previous '0' and '1' states */ + state.state = reg; + state.prev[0] = vstate_lshift(reg, code->K, 0); + state.prev[1] = vstate_lshift(reg, code->K, 1); + + /* Find recursive bit location */ + for (i = 0; i < code->N; i++) { + for (j = 0; j < ns; j++) { + if ((code->next_output[j][0] >> i) & 0x01) + break; + } + + if (j == ns) { + pos = i; + break; + } + } + + /* Non-systematic recursive code not supported */ + if (pos < 0) + return -EPROTO; + + /* Transition output */ + out = gen_recursive_output(&state, val, reg, code, pos); + + /* Unpack to NRZ */ + for (i = 0; i < code->N; i++) + output[i] = BIT2NRZ(out, i); + + return 0; +} + +/* Release the trellis */ +static void free_trellis(struct vtrellis *trellis) +{ + if (!trellis) + return; + + free(trellis->vals); + free(trellis->outputs); + free(trellis->sums); + free(trellis); +} + +/* Allocate and initialize the trellis object + * Initialization consists of generating the outputs and output value of a + * given state. Due to trellis symmetry and anti-symmetry, only one of the + * transition paths is utilized by the butterfly operation in the forward + * recursion, so only one set of N outputs is required per state variable. + */ +static struct vtrellis *generate_trellis(const struct osmo_conv_code *code) +{ + int i, rc = -1; + struct vtrellis *trellis; + int16_t *outputs; + + int ns = NUM_STATES(code->K); + int recursive = conv_code_recursive(code); + int olen = (code->N == 2) ? 2 : 4; + + trellis = (struct vtrellis *) calloc(1, sizeof(struct vtrellis)); + trellis->num_states = ns; + trellis->sums = vdec_malloc(ns); + trellis->outputs = vdec_malloc(ns * olen); + trellis->vals = (uint8_t *) malloc(ns * sizeof(uint8_t)); + + if (!trellis->sums || !trellis->outputs) + goto fail; + + /* Populate the trellis state objects */ + for (i = 0; i < ns; i++) { + outputs = &trellis->outputs[olen * i]; + if (recursive) { + rc = gen_recursive_state_info(&trellis->vals[i], + i, outputs, code); + } else { + rc = gen_state_info(&trellis->vals[i], + i, outputs, code); + } + } + + if (rc < 0) + goto fail; + + return trellis; + +fail: + free_trellis(trellis); + return NULL; +} + +/* Reset decoder + * Set accumulated path metrics to zero. For termination other than + * tail-biting, initialize the zero state as the encoder starting state. + * Initialize with the maximum accumulated sum at length equal to the + * constraint length. + */ +static void reset_decoder(struct vdecoder *dec, int term) +{ + int ns = dec->trellis->num_states; + + memset(dec->trellis->sums, 0, sizeof(int16_t) * ns); + + if (term != CONV_TERM_TAIL_BITING) + dec->trellis->sums[0] = INT8_MAX * dec->n * dec->k; +} + +static void _traceback(struct vdecoder *dec, + unsigned state, uint8_t *out, int len) +{ + int i; + unsigned path; + + for (i = len - 1; i >= 0; i--) { + path = dec->paths[i][state] + 1; + out[i] = dec->trellis->vals[state]; + state = vstate_lshift(state, dec->k, path); + } +} + +static void _traceback_rec(struct vdecoder *dec, + unsigned state, uint8_t *out, int len) +{ + int i; + unsigned path; + + for (i = len - 1; i >= 0; i--) { + path = dec->paths[i][state] + 1; + out[i] = path ^ dec->trellis->vals[state]; + state = vstate_lshift(state, dec->k, path); + } +} + +/* Traceback and generate decoded output + * Find the largest accumulated path metric at the final state except for + * the zero terminated case, where we assume the final state is always zero. + */ +static int traceback(struct vdecoder *dec, uint8_t *out, int term, int len) +{ + int i, sum, max = -1; + unsigned path, state = 0; + + if (term != CONV_TERM_FLUSH) { + for (i = 0; i < dec->trellis->num_states; i++) { + sum = dec->trellis->sums[i]; + if (sum > max) { + max = sum; + state = i; + } + } + + if (max < 0) + return -EPROTO; + } + + for (i = dec->len - 1; i >= len; i--) { + path = dec->paths[i][state] + 1; + state = vstate_lshift(state, dec->k, path); + } + + if (dec->recursive) + _traceback_rec(dec, state, out, len); + else + _traceback(dec, state, out, len); + + return 0; +} + +/* Release decoder object */ +static void free_vdec(struct vdecoder *dec) +{ + if (!dec) + return; + + free(dec->paths[0]); + free(dec->paths); + free_trellis(dec->trellis); + free(dec); +} + +/* Allocate decoder object + * Subtract the constraint length K on the normalization interval to + * accommodate the initialization path metric at state zero. + */ +static struct vdecoder *alloc_vdec(const struct osmo_conv_code *code) +{ + int i, ns; + struct vdecoder *dec; + + ns = NUM_STATES(code->K); + + dec = (struct vdecoder *) calloc(1, sizeof(struct vdecoder)); + dec->n = code->N; + dec->k = code->K; + dec->recursive = conv_code_recursive(code); + dec->intrvl = INT16_MAX / (dec->n * INT8_MAX) - dec->k; + + if (dec->k == 5) { + switch (dec->n) { + case 2: + dec->metric_func = osmo_conv_gen_metrics_k5_n2; + break; + case 3: + dec->metric_func = osmo_conv_gen_metrics_k5_n3; + break; + case 4: + dec->metric_func = osmo_conv_gen_metrics_k5_n4; + break; + default: + goto fail; + } + } else if (dec->k == 7) { + switch (dec->n) { + case 2: + dec->metric_func = osmo_conv_gen_metrics_k7_n2; + break; + case 3: + dec->metric_func = osmo_conv_gen_metrics_k7_n3; + break; + case 4: + dec->metric_func = osmo_conv_gen_metrics_k7_n4; + break; + default: + goto fail; + } + } else { + goto fail; + } + + if (code->term == CONV_TERM_FLUSH) + dec->len = code->len + code->K - 1; + else + dec->len = code->len; + + dec->trellis = generate_trellis(code); + if (!dec->trellis) + goto fail; + + dec->paths = (int16_t **) malloc(sizeof(int16_t *) * dec->len); + dec->paths[0] = vdec_malloc(ns * dec->len); + for (i = 1; i < dec->len; i++) + dec->paths[i] = &dec->paths[0][i * ns]; + + return dec; + +fail: + free_vdec(dec); + return NULL; +} + +/* Depuncture sequence with nagative value terminated puncturing matrix */ +static int depuncture(const int8_t *in, const int *punc, int8_t *out, int len) +{ + int i, n = 0, m = 0; + + for (i = 0; i < len; i++) { + if (i == punc[n]) { + out[i] = 0; + n++; + continue; + } + + out[i] = in[m++]; + } + + return 0; +} + +/* Forward trellis recursion + * Generate branch metrics and path metrics with a combined function. Only + * accumulated path metric sums and path selections are stored. Normalize on + * the interval specified by the decoder. + */ +static void forward_traverse(struct vdecoder *dec, const int8_t *seq) +{ + struct vtrellis *trellis = dec->trellis; + int i; + + for (i = 0; i < dec->len; i++) { + dec->metric_func(&seq[dec->n * i], + trellis->outputs, + trellis->sums, + dec->paths[i], + !(i % dec->intrvl)); + } +} + +/* Convolutional decode with a decoder object + * Initial puncturing run if necessary followed by the forward recursion. + * For tail-biting perform a second pass before running the backward + * traceback operation. + */ +static int conv_decode(struct vdecoder *dec, const int8_t *seq, + const int *punc, uint8_t *out, int len, int term) +{ + int8_t depunc[dec->len * dec->n]; + + reset_decoder(dec, term); + + if (punc) { + depuncture(seq, punc, depunc, dec->len * dec->n); + seq = depunc; + } + + /* Propagate through the trellis with interval normalization */ + forward_traverse(dec, seq); + + if (term == CONV_TERM_TAIL_BITING) + forward_traverse(dec, seq); + + return traceback(dec, out, term, len); +} + +/* All-in-one Viterbi decoding */ +int osmo_conv_decode_acc(const struct osmo_conv_code *code, + const sbit_t *input, ubit_t *output) +{ + int rc; + struct vdecoder *vdec; + + if ((code->N < 2) || (code->N > 4) || (code->len < 1) || + ((code->K != 5) && (code->K != 7))) + return -EINVAL; + + vdec = alloc_vdec(code); + if (!vdec) + return -EFAULT; + + rc = conv_decode(vdec, input, code->puncture, + output, code->len, code->term); + + free_vdec(vdec); + + return rc; +} diff --git a/src/viterbi_gen.c b/src/viterbi_gen.c new file mode 100644 index 0000000..7972c39 --- /dev/null +++ b/src/viterbi_gen.c @@ -0,0 +1,193 @@ +/* + * Viterbi decoder + * + * Copyright (C) 2013, 2014 Thomas Tsou + * + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include +#include + +/* Add-Compare-Select (ACS-Butterfly) + * Compute 4 accumulated path metrics and 4 path selections. Note that path + * selections are store as -1 and 0 rather than 0 and 1. This is to match + * the output format of the SSE packed compare instruction 'pmaxuw'. + */ + +static void acs_butterfly(int state, int num_states, + int16_t metric, int16_t *sum, + int16_t *new_sum, int16_t *path) +{ + int state0, state1; + int sum0, sum1, sum2, sum3; + + state0 = *(sum + (2 * state + 0)); + state1 = *(sum + (2 * state + 1)); + + sum0 = state0 + metric; + sum1 = state1 - metric; + sum2 = state0 - metric; + sum3 = state1 + metric; + + if (sum0 >= sum1) { + *new_sum = sum0; + *path = -1; + } else { + *new_sum = sum1; + *path = 0; + } + + if (sum2 >= sum3) { + *(new_sum + num_states / 2) = sum2; + *(path + num_states / 2) = -1; + } else { + *(new_sum + num_states / 2) = sum3; + *(path + num_states / 2) = 0; + } +} + +/* Branch metrics unit N=2 */ +static void gen_branch_metrics_n2(int num_states, const int8_t *seq, + const int16_t *out, int16_t *metrics) +{ + int i; + + for (i = 0; i < num_states / 2; i++) { + metrics[i] = seq[0] * out[2 * i + 0] + + seq[1] * out[2 * i + 1]; + } +} + +/* Branch metrics unit N=3 */ +static void gen_branch_metrics_n3(int num_states, const int8_t *seq, + const int16_t *out, int16_t *metrics) +{ + int i; + + for (i = 0; i < num_states / 2; i++) { + metrics[i] = seq[0] * out[4 * i + 0] + + seq[1] * out[4 * i + 1] + + seq[2] * out[4 * i + 2]; + } +} + +/* Branch metrics unit N=4 */ +static void gen_branch_metrics_n4(int num_states, const int8_t *seq, + const int16_t *out, int16_t *metrics) +{ + int i; + + for (i = 0; i < num_states / 2; i++) { + metrics[i] = seq[0] * out[4 * i + 0] + + seq[1] * out[4 * i + 1] + + seq[2] * out[4 * i + 2] + + seq[3] * out[4 * i + 3]; + } +} + +/* Path metric unit */ +static void gen_path_metrics(int num_states, int16_t *sums, + int16_t *metrics, int16_t *paths, int norm) +{ + int i; + int16_t min; + int16_t new_sums[num_states]; + + for (i = 0; i < num_states / 2; i++) + acs_butterfly(i, num_states, metrics[i], + sums, &new_sums[i], &paths[i]); + + if (norm) { + min = new_sums[0]; + + for (i = 1; i < num_states; i++) + if (new_sums[i] < min) + min = new_sums[i]; + + for (i = 0; i < num_states; i++) + new_sums[i] -= min; + } + + memcpy(sums, new_sums, num_states * sizeof(int16_t)); +} + +/* 16-state branch-path metrics units (K=5) */ +__attribute__ ((visibility("hidden"))) +void osmo_conv_gen_metrics_k5_n2(const int8_t *seq, const int16_t *out, + int16_t *sums, int16_t *paths, int norm) +{ + int16_t metrics[8]; + + gen_branch_metrics_n2(16, seq, out, metrics); + gen_path_metrics(16, sums, metrics, paths, norm); +} + +__attribute__ ((visibility("hidden"))) +void osmo_conv_gen_metrics_k5_n3(const int8_t *seq, const int16_t *out, + int16_t *sums, int16_t *paths, int norm) +{ + int16_t metrics[8]; + + gen_branch_metrics_n3(16, seq, out, metrics); + gen_path_metrics(16, sums, metrics, paths, norm); + +} + +__attribute__ ((visibility("hidden"))) +void osmo_conv_gen_metrics_k5_n4(const int8_t *seq, const int16_t *out, + int16_t *sums, int16_t *paths, int norm) +{ + int16_t metrics[8]; + + gen_branch_metrics_n4(16, seq, out, metrics); + gen_path_metrics(16, sums, metrics, paths, norm); + +} + +/* 64-state branch-path metrics units (K=7) */ +__attribute__ ((visibility("hidden"))) +void osmo_conv_gen_metrics_k7_n2(const int8_t *seq, const int16_t *out, + int16_t *sums, int16_t *paths, int norm) +{ + int16_t metrics[32]; + + gen_branch_metrics_n2(64, seq, out, metrics); + gen_path_metrics(64, sums, metrics, paths, norm); + +} + +__attribute__ ((visibility("hidden"))) +void osmo_conv_gen_metrics_k7_n3(const int8_t *seq, const int16_t *out, + int16_t *sums, int16_t *paths, int norm) +{ + int16_t metrics[32]; + + gen_branch_metrics_n3(64, seq, out, metrics); + gen_path_metrics(64, sums, metrics, paths, norm); + +} + +__attribute__ ((visibility("hidden"))) +void osmo_conv_gen_metrics_k7_n4(const int8_t *seq, const int16_t *out, + int16_t *sums, int16_t *paths, int norm) +{ + int16_t metrics[32]; + + gen_branch_metrics_n4(64, seq, out, metrics); + gen_path_metrics(64, sums, metrics, paths, norm); +} -- To view, visit https://gerrit.osmocom.org/1337 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I74d355274b4176a7d924f91ef3c96912ce338fb2 Gerrit-PatchSet: 6 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Vadim Yanitskiy Gerrit-Reviewer: Alexander Chemeris Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Tom Tsou Gerrit-Reviewer: Vadim Yanitskiy Gerrit-Reviewer: tnt From gerrit-no-reply at lists.osmocom.org Sat Apr 8 06:37:44 2017 From: gerrit-no-reply at lists.osmocom.org (tnt) Date: Sat, 8 Apr 2017 06:37:44 +0000 Subject: libosmocore[master]: core/conv: implement optimized Viterbi decoder In-Reply-To: References: Message-ID: Patch Set 6: Code-Review+1 All the points I raised originally have been addressed AFAICT, looks good to me -- To view, visit https://gerrit.osmocom.org/1337 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I74d355274b4176a7d924f91ef3c96912ce338fb2 Gerrit-PatchSet: 6 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Vadim Yanitskiy Gerrit-Reviewer: Alexander Chemeris Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Tom Tsou Gerrit-Reviewer: Vadim Yanitskiy Gerrit-Reviewer: tnt Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sat Apr 8 07:17:35 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 8 Apr 2017 07:17:35 +0000 Subject: [PATCH] libosmo-sccp[master]: sccp: add osmo_sccp_user_get_priv() API function Message-ID: Review at https://gerrit.osmocom.org/2234 sccp: add osmo_sccp_user_get_priv() API function As 'struct osmo_sccp_user' is private, we need this accessor function for the SCCP User so it can resolve the 'priv' that was passed in when binding the SCCP user to a given SSN. Change-Id: Ia68a36dc18a7d754d63ae29c86d68e495b5c4134 --- M include/osmocom/sigtran/sccp_sap.h M src/sccp_user.c 2 files changed, 6 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/34/2234/1 diff --git a/include/osmocom/sigtran/sccp_sap.h b/include/osmocom/sigtran/sccp_sap.h index c1464f0..a35af56 100644 --- a/include/osmocom/sigtran/sccp_sap.h +++ b/include/osmocom/sigtran/sccp_sap.h @@ -232,6 +232,7 @@ void osmo_sccp_instance_destroy(struct osmo_sccp_instance *inst); void osmo_sccp_user_unbind(struct osmo_sccp_user *scu); +void *osmo_sccp_user_get_priv(struct osmo_sccp_user *scu); struct osmo_sccp_user * osmo_sccp_user_bind_pc(struct osmo_sccp_instance *inst, const char *name, diff --git a/src/sccp_user.c b/src/sccp_user.c index df02486..5c8d026 100644 --- a/src/sccp_user.c +++ b/src/sccp_user.c @@ -130,6 +130,11 @@ talloc_free(scu); } +void *osmo_sccp_user_get_priv(struct osmo_sccp_user *scu) +{ + return scu->priv; +} + /*! \brief Send a SCCP User SAP Primitive up to the User * \param[in] scu SCCP User to whom to send the primitive * \param[in] prim Primitive to send to the user -- To view, visit https://gerrit.osmocom.org/2234 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ia68a36dc18a7d754d63ae29c86d68e495b5c4134 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Sat Apr 8 07:17:35 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 8 Apr 2017 07:17:35 +0000 Subject: [PATCH] libosmo-sccp[master]: osmo_ss7: make OVERRIDE the default traffic mode type (0) Message-ID: Review at https://gerrit.osmocom.org/2235 osmo_ss7: make OVERRIDE the default traffic mode type (0) Change-Id: Ie83fa0a403dcfc582d6bb59ec08d6a719d2f6398 --- M include/osmocom/sigtran/osmo_ss7.h 1 file changed, 1 insertion(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/35/2235/1 diff --git a/include/osmocom/sigtran/osmo_ss7.h b/include/osmocom/sigtran/osmo_ss7.h index 5bbcd65..7918a51 100644 --- a/include/osmocom/sigtran/osmo_ss7.h +++ b/include/osmocom/sigtran/osmo_ss7.h @@ -229,10 +229,10 @@ }; enum osmo_ss7_as_traffic_mode { + OSMO_SS7_AS_TMOD_OVERRIDE = 0, /* default */ OSMO_SS7_AS_TMOD_BCAST, OSMO_SS7_AS_TMOD_LOADSHARE, OSMO_SS7_AS_TMOD_ROUNDROBIN, - OSMO_SS7_AS_TMOD_OVERRIDE, _NUM_OSMO_SS7_ASP_TMOD }; -- To view, visit https://gerrit.osmocom.org/2235 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ie83fa0a403dcfc582d6bb59ec08d6a719d2f6398 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Sat Apr 8 07:17:36 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 8 Apr 2017 07:17:36 +0000 Subject: [PATCH] libosmo-sccp[master]: add converter functions between osmo_ss7 and m3ua traffic mo... Message-ID: Review at https://gerrit.osmocom.org/2236 add converter functions between osmo_ss7 and m3ua traffic mode types Change-Id: I6cc9530d7d2812cbc8feb6e9db51902865ebfe83 --- M include/osmocom/sigtran/osmo_ss7.h M include/osmocom/sigtran/protocol/m3ua.h M src/osmo_ss7.c 3 files changed, 36 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/36/2236/1 diff --git a/include/osmocom/sigtran/osmo_ss7.h b/include/osmocom/sigtran/osmo_ss7.h index 7918a51..d765ae0 100644 --- a/include/osmocom/sigtran/osmo_ss7.h +++ b/include/osmocom/sigtran/osmo_ss7.h @@ -406,3 +406,6 @@ const char *name, uint32_t pc, int local_port, int remote_port, const char *remote_ip); + +enum osmo_ss7_as_traffic_mode osmo_ss7_tmode_from_xua(uint32_t in); +int osmo_ss7_tmode_to_xua(enum osmo_ss7_as_traffic_mode tmod); diff --git a/include/osmocom/sigtran/protocol/m3ua.h b/include/osmocom/sigtran/protocol/m3ua.h index d4dc1fe..c10808c 100644 --- a/include/osmocom/sigtran/protocol/m3ua.h +++ b/include/osmocom/sigtran/protocol/m3ua.h @@ -145,3 +145,9 @@ M3UA_ERR_INVAL_ROUT_CTX = 0x19, M3UA_ERR_NO_CONFGD_AS_FOR_ASP = 0x1a, }; + +enum m3ua_traffic_mode { + M3UA_TMOD_OVERRIDE = 1, + M3UA_TMOD_LOADSHARE = 2, + M3UA_TMOD_BCAST = 3, +}; diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index ab0636c..2dbb94d 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -1494,3 +1494,30 @@ ss7_initialized = true; return 0; } + +int osmo_ss7_tmode_to_xua(enum osmo_ss7_as_traffic_mode tmod) +{ + switch (tmod) { + case OSMO_SS7_AS_TMOD_OVERRIDE: + return M3UA_TMOD_OVERRIDE; + case OSMO_SS7_AS_TMOD_LOADSHARE: + return M3UA_TMOD_LOADSHARE; + case OSMO_SS7_AS_TMOD_BCAST: + return M3UA_TMOD_BCAST; + default: + return -1; + } +} + +enum osmo_ss7_as_traffic_mode osmo_ss7_tmode_from_xua(uint32_t in) +{ + switch (in) { + case M3UA_TMOD_OVERRIDE: + default: + return OSMO_SS7_AS_TMOD_OVERRIDE; + case M3UA_TMOD_LOADSHARE: + return OSMO_SS7_AS_TMOD_LOADSHARE; + case M3UA_TMOD_BCAST: + return OSMO_SS7_AS_TMOD_BCAST; + } +} -- To view, visit https://gerrit.osmocom.org/2236 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I6cc9530d7d2812cbc8feb6e9db51902865ebfe83 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Sat Apr 8 07:17:36 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 8 Apr 2017 07:17:36 +0000 Subject: [PATCH] libosmo-sccp[master]: m3ua: Include RC IE of AS in Tx; validate RC IE on Rx Message-ID: Review at https://gerrit.osmocom.org/2237 m3ua: Include RC IE of AS in Tx; validate RC IE on Rx Change-Id: I7db36a23185f82d8d68e318afe89ec5127c40333 --- M src/m3ua.c 1 file changed, 26 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/37/2237/1 diff --git a/src/m3ua.c b/src/m3ua.c index 8ec82c5..7437b6e 100644 --- a/src/m3ua.c +++ b/src/m3ua.c @@ -448,6 +448,10 @@ OSMO_ASSERT(as->cfg.proto == OSMO_SS7_ASP_PROT_M3UA); + /* Add RC for this AS */ + if (as->cfg.routing_key.context) + xua_msg_add_u32(xua, M3UA_IEI_ROUTE_CTX, as->cfg.routing_key.context); + for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) { asp = as->cfg.asps[i]; if (!asp) @@ -488,7 +492,24 @@ static int m3ua_rx_xfer(struct osmo_ss7_asp *asp, struct xua_msg *xua) { + uint32_t rctx = xua_msg_get_u32(xua, M3UA_IEI_ROUTE_CTX); struct m3ua_data_hdr *dh; + struct xua_msg *err = NULL; + struct osmo_ss7_as *as; + + /* Use routing context IE to look up the AS for which the + * message was received. */ + as = osmo_ss7_as_find_by_rctx(asp->inst, rctx); + if (!as) { + err = m3ua_gen_error(M3UA_ERR_INVAL_ROUT_CTX); + goto out_err; + } + /* Verify that this ASP ix part of the AS. */ + if (!osmo_ss7_as_has_asp(as, asp)) { + err = m3ua_gen_error(M3UA_ERR_NO_CONFGD_AS_FOR_ASP); + goto out_err; + } + /* FIXME: check for AS state == ACTIVE */ /* store the MTP-level information in the xua_msg for use by * higher layer protocols */ @@ -497,6 +518,11 @@ m3ua_dh_to_xfer_param(&xua->mtp, dh); return m3ua_hmdc_rx_from_l2(asp->inst, xua); +out_err: + if (err) + m3ua_tx_xua_asp(asp, err); + + return -1; } static int m3ua_rx_mgmt_err(struct osmo_ss7_asp *asp, struct xua_msg *xua) -- To view, visit https://gerrit.osmocom.org/2237 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I7db36a23185f82d8d68e318afe89ec5127c40333 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Sat Apr 8 07:17:36 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 8 Apr 2017 07:17:36 +0000 Subject: [PATCH] libosmo-sccp[master]: xua_asp_fsm: Always return BEAT-ACK for BEAT, including BEAT... Message-ID: Review at https://gerrit.osmocom.org/2238 xua_asp_fsm: Always return BEAT-ACK for BEAT, including BEAT DATA IE The RFCs say we *must* always respond to the optional heartbeat message, and we must return a verbatim copy of the heartbeat data IE. Change-Id: I836e0940a8dbb0f55ddf132202a5f0d51473b82d --- M src/xua_asp_fsm.c 1 file changed, 22 insertions(+), 11 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/38/2238/1 diff --git a/src/xua_asp_fsm.c b/src/xua_asp_fsm.c index 80faeb2..a8ef01a 100644 --- a/src/xua_asp_fsm.c +++ b/src/xua_asp_fsm.c @@ -128,7 +128,7 @@ } /* ask the xUA implementation to transmit a specific message */ -static int peer_send(struct osmo_fsm_inst *fi, int out_event) +static int peer_send(struct osmo_fsm_inst *fi, int out_event, struct xua_msg *in) { struct xua_asp_fsm_priv *xafp = fi->priv; struct osmo_ss7_asp *asp = xafp->asp; @@ -217,7 +217,7 @@ osmo_fsm_event_name(fi->fsm, xafp->t_ack.out_event)); /* Re-transmit message */ - peer_send(fi, xafp->t_ack.out_event); + peer_send(fi, xafp->t_ack.out_event, NULL); /* Re-start the timer */ osmo_timer_schedule(&xafp->t_ack.timer, XUA_T_ACK_SEC, 0); @@ -229,7 +229,7 @@ struct xua_asp_fsm_priv *xafp = fi->priv; int rc; - rc = peer_send(fi, out_event); + rc = peer_send(fi, out_event, NULL); if (rc < 0) return rc; @@ -328,7 +328,7 @@ asp->asp_id_present = true; } /* send ACK */ - peer_send(fi, XUA_ASP_E_ASPSM_ASPUP_ACK); + peer_send(fi, XUA_ASP_E_ASPSM_ASPUP_ACK, NULL); /* transition state and inform layer manager */ osmo_fsm_inst_state_chg(fi, XUA_ASP_S_INACTIVE, 0, 0); send_xlm_prim_simple(fi, OSMO_XLM_PRIM_M_ASP_UP, @@ -340,7 +340,7 @@ /* The SGP MUST send an ASP Down Ack message in response * to a received ASP Down message from the ASP even if * the ASP is already marked as ASP-DOWN at the SGP. */ - peer_send(fi, XUA_ASP_E_ASPSM_ASPDN_ACK); + peer_send(fi, XUA_ASP_E_ASPSM_ASPDN_ACK, NULL); break; } } @@ -401,7 +401,7 @@ /* only in role SG */ ENSURE_SG_OR_IPSP(fi, event); /* send ACK */ - peer_send(fi, XUA_ASP_E_ASPTM_ASPAC_ACK); + peer_send(fi, XUA_ASP_E_ASPTM_ASPAC_ACK, NULL); /* transition state and inform layer manager */ osmo_fsm_inst_state_chg(fi, XUA_ASP_S_ACTIVE, 0, 0); send_xlm_prim_simple(fi, OSMO_XLM_PRIM_M_ASP_ACTIVE, @@ -411,7 +411,7 @@ /* only in role SG */ ENSURE_SG_OR_IPSP(fi, event); /* send ACK */ - peer_send(fi, XUA_ASP_E_ASPSM_ASPDN_ACK); + peer_send(fi, XUA_ASP_E_ASPSM_ASPDN_ACK, NULL); /* transition state and inform layer manager */ osmo_fsm_inst_state_chg(fi, XUA_ASP_S_DOWN, 0, 0); send_xlm_prim_simple(fi, OSMO_XLM_PRIM_M_ASP_DOWN, @@ -424,7 +424,7 @@ * remote ASP is already in the ASP-INACTIVE state, an * ASP Up Ack message is returned and no further action * is taken. */ - peer_send(fi, XUA_ASP_E_ASPSM_ASPUP_ACK); + peer_send(fi, XUA_ASP_E_ASPSM_ASPUP_ACK, NULL); break; } } @@ -470,7 +470,7 @@ /* only in role SG */ ENSURE_SG_OR_IPSP(fi, event); /* send ACK */ - peer_send(fi, XUA_ASP_E_ASPTM_ASPIA_ACK); + peer_send(fi, XUA_ASP_E_ASPTM_ASPIA_ACK, NULL); /* transition state and inform layer manager */ osmo_fsm_inst_state_chg(fi, XUA_ASP_S_INACTIVE, 0, 0); send_xlm_prim_simple(fi, OSMO_XLM_PRIM_M_ASP_INACTIVE, @@ -480,7 +480,7 @@ /* only in role SG */ ENSURE_SG_OR_IPSP(fi, event); /* send ACK */ - peer_send(fi, XUA_ASP_E_ASPSM_ASPDN_ACK); + peer_send(fi, XUA_ASP_E_ASPSM_ASPDN_ACK, NULL); /* transition state and inform layer manager */ osmo_fsm_inst_state_chg(fi, XUA_ASP_S_DOWN, 0, 0); send_xlm_prim_simple(fi, OSMO_XLM_PRIM_M_ASP_DOWN, @@ -508,12 +508,21 @@ static void xua_asp_allstate(struct osmo_fsm_inst *fi, uint32_t event, void *data) { + struct xua_msg *xua; + switch (event) { case XUA_ASP_E_SCTP_COMM_DOWN_IND: case XUA_ASP_E_SCTP_RESTART_IND: osmo_fsm_inst_state_chg(fi, XUA_ASP_S_DOWN, 0, 0); send_xlm_prim_simple(fi, OSMO_XLM_PRIM_M_ASP_DOWN, PRIM_OP_INDICATION); + break; + case XUA_ASP_E_ASPSM_BEAT: + xua = data; + peer_send(fi, XUA_ASP_E_ASPSM_BEAT_ACK, xua); + break; + case XUA_ASP_E_ASPSM_BEAT_ACK: + /* FIXME: stop timer, if any */ break; default: break; @@ -577,7 +586,9 @@ .log_subsys = DLSS7, .event_names = xua_asp_event_names, .allstate_event_mask = S(XUA_ASP_E_SCTP_COMM_DOWN_IND) | - S(XUA_ASP_E_SCTP_RESTART_IND), + S(XUA_ASP_E_SCTP_RESTART_IND) | + S(XUA_ASP_E_ASPSM_BEAT) | + S(XUA_ASP_E_ASPSM_BEAT_ACK), .allstate_action = xua_asp_allstate, }; -- To view, visit https://gerrit.osmocom.org/2238 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I836e0940a8dbb0f55ddf132202a5f0d51473b82d Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Sat Apr 8 07:17:36 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 8 Apr 2017 07:17:36 +0000 Subject: [PATCH] libosmo-sccp[master]: xua_as_fsm: Include routing context (if configured) in NTFY ... Message-ID: Review at https://gerrit.osmocom.org/2239 xua_as_fsm: Include routing context (if configured) in NTFY message Change-Id: I15e8bf5cee194f9924d0eab9cff0e7c25daa6dde --- M src/xua_as_fsm.c 1 file changed, 9 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/39/2239/1 diff --git a/src/xua_as_fsm.c b/src/xua_as_fsm.c index 887a9ec..d73f793 100644 --- a/src/xua_as_fsm.c +++ b/src/xua_as_fsm.c @@ -149,6 +149,7 @@ static void xua_as_fsm_onenter(struct osmo_fsm_inst *fi, uint32_t old_state) { struct xua_as_fsm_priv *xafp = (struct xua_as_fsm_priv *) fi->priv; + struct osmo_ss7_as *as = xafp->as; struct m3ua_notify_params npar = { .status_type = M3UA_NOTIFY_T_STATCHG, }; @@ -167,6 +168,14 @@ return; } + /* Add the routing context, if it is configured */ + if (as->cfg.routing_key.context) { + npar.presence |= NOTIFY_PAR_P_ROUTE_CTX; + npar.route_ctx = as->cfg.routing_key.context; + } + + /* TODO: ASP-Id of ASP triggering this state change */ + asp_notify_all_as(xafp->as, &npar); }; -- To view, visit https://gerrit.osmocom.org/2239 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I15e8bf5cee194f9924d0eab9cff0e7c25daa6dde Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Sat Apr 8 07:17:37 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 8 Apr 2017 07:17:37 +0000 Subject: [PATCH] libosmo-sccp[master]: xua_cli_conn_cb: Print flags as hex, not decimal. Message-ID: Review at https://gerrit.osmocom.org/2240 xua_cli_conn_cb: Print flags as hex, not decimal. Change-Id: Idcf861cfdc6c14d7d3bafbf2e243da5db6e2f3e6 --- M src/osmo_ss7.c 1 file changed, 1 insertion(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/40/2240/1 diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index 2dbb94d..df85ea8 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -1246,7 +1246,7 @@ /* read xUA message from socket and process it */ rc = sctp_recvmsg(ofd->fd, msgb_data(msg), msgb_tailroom(msg), NULL, NULL, &sinfo, &flags); - LOGPASP(asp, DLSS7, LOGL_DEBUG, "%s(): sctp_recvmsg() returned %d (flags=%d)\n", + LOGPASP(asp, DLSS7, LOGL_DEBUG, "%s(): sctp_recvmsg() returned %d (flags=0x%x)\n", __func__, rc, flags); if (rc < 0) { osmo_stream_cli_reconnect(conn); -- To view, visit https://gerrit.osmocom.org/2240 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Idcf861cfdc6c14d7d3bafbf2e243da5db6e2f3e6 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Sat Apr 8 07:17:37 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 8 Apr 2017 07:17:37 +0000 Subject: [PATCH] libosmo-sccp[master]: xua_srv_conn_cb(): Print sctp_recvmsg flags (line in xua_cli... Message-ID: Review at https://gerrit.osmocom.org/2241 xua_srv_conn_cb(): Print sctp_recvmsg flags (line in xua_cli_conn_cb()) Change-Id: I91920c6ad665abc791a1dbf386d52cf0aece9133 --- M src/osmo_ss7.c 1 file changed, 2 insertions(+), 2 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/41/2241/1 diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index df85ea8..8ec099a 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -1163,8 +1163,8 @@ /* read xUA message from socket and process it */ rc = sctp_recvmsg(ofd->fd, msgb_data(msg), msgb_tailroom(msg), NULL, NULL, &sinfo, &flags); - LOGPASP(asp, DLSS7, LOGL_DEBUG, "%s(): sctp_recvmsg() returned %d\n", - __func__, rc); + LOGPASP(asp, DLSS7, LOGL_DEBUG, "%s(): sctp_recvmsg() returned %d (flags=0x%x)\n", + __func__, rc, flags); if (rc < 0) { osmo_stream_srv_destroy(conn); goto out; -- To view, visit https://gerrit.osmocom.org/2241 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I91920c6ad665abc791a1dbf386d52cf0aece9133 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Sat Apr 8 07:17:37 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 8 Apr 2017 07:17:37 +0000 Subject: [PATCH] libosmo-sccp[master]: sigtran: fix various memory leaks (msgb and xua_msg) Message-ID: Review at https://gerrit.osmocom.org/2242 sigtran: fix various memory leaks (msgb and xua_msg) Change-Id: I708505d129da5824c69b31a13a9c93201929bada --- M examples/sccp_test_server.c M examples/sccp_test_vty.c M src/osmo_ss7_hmrt.c M src/sccp_scrc.c M src/sccp_user.c 5 files changed, 56 insertions(+), 18 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/42/2242/1 diff --git a/examples/sccp_test_server.c b/examples/sccp_test_server.c index c3c658f..71bed96 100644 --- a/examples/sccp_test_server.c +++ b/examples/sccp_test_server.c @@ -34,6 +34,7 @@ oph->primitive, oph->operation); break; } + msgb_free(oph->msg); return 0; } @@ -71,6 +72,7 @@ oph->primitive, oph->operation); break; } + msgb_free(oph->msg); return 0; } @@ -102,6 +104,7 @@ oph->primitive, oph->operation); break; } + msgb_free(oph->msg); return 0; } diff --git a/examples/sccp_test_vty.c b/examples/sccp_test_vty.c index 1134d57..ddfbb27 100644 --- a/examples/sccp_test_vty.c +++ b/examples/sccp_test_vty.c @@ -125,6 +125,7 @@ default: break; } + msgb_free(oph->msg); return 0; } diff --git a/src/osmo_ss7_hmrt.c b/src/osmo_ss7_hmrt.c index bc2b8e5..7269f93 100644 --- a/src/osmo_ss7_hmrt.c +++ b/src/osmo_ss7_hmrt.c @@ -108,6 +108,7 @@ default: LOGP(DLSS7, LOGL_ERROR, "Unknown M3UA XFER Message " "Type %u\n", xua->hdr.msg_type); + xua_msg_free(xua); return -1; } break; @@ -119,6 +120,7 @@ /* Discard Message */ LOGP(DLSS7, LOGL_ERROR, "Unknown M3UA Message Class %u\n", xua->hdr.msg_class); + xua_msg_free(xua); return -1; } @@ -130,6 +132,7 @@ LOGP(DLSS7, LOGL_NOTICE, "No MTP-User for SI %u\n", service_ind); /* Discard Message */ /* FIXME: User Part Unavailable HMDT -> HMRT */ + xua_msg_free(xua); return -1; } } @@ -174,6 +177,7 @@ /* Message Received for inaccesible SP HMRT ->RTPC */ /* Discard Message */ } + xua_msg_free(xua); return -1; } @@ -195,6 +199,7 @@ struct osmo_mtp_prim *omp) { struct xua_msg *xua; + int rc; OSMO_ASSERT(omp->oph.sap == MTP_SAP_USER); @@ -210,10 +215,13 @@ * is a very useful feature (aka "loopback device" in * IPv4). So we call m3ua_hmdc_rx_from_l2() just like * the MTP-TRANSFER had been received from L2. */ - return m3ua_hmdc_rx_from_l2(inst, xua); + rc = m3ua_hmdc_rx_from_l2(inst, xua); default: LOGP(DLSS7, LOGL_ERROR, "Ignoring unknown primitive %u:%u\n", omp->oph.primitive, omp->oph.operation); - return -1; + rc = -1; } + + msgb_free(omp->oph.msg); + return rc; } diff --git a/src/sccp_scrc.c b/src/sccp_scrc.c index 0ab25cb..88aed59 100644 --- a/src/sccp_scrc.c +++ b/src/sccp_scrc.c @@ -374,20 +374,29 @@ struct xua_msg *xua) { struct osmo_sccp_addr called; + int rc; LOGP(DLSS7, LOGL_DEBUG, "%s: %s\n", __func__, xua_msg_dump(xua, &xua_dialect_sua)); sua_addr_parse(&called, xua, SUA_IEI_DEST_ADDR); /* Is this a CR message ? */ - if (xua->hdr.msg_type != SUA_CO_CORE) - return scrc_node_2(inst, xua, &called); + if (xua->hdr.msg_type != SUA_CO_CORE) { + rc = scrc_node_2(inst, xua, &called); + goto out; + } /* TOOD: Coupling performed (not supported) */ - if (0) - return scrc_node_2(inst, xua, &called); + if (0) { + rc = scrc_node_2(inst, xua, &called); + goto out; + } - return scrc_local_out_common(inst, xua, &called); + rc = scrc_local_out_common(inst, xua, &called); + +out: + xua_msg_free(xua); + return rc; } /* Connectionless Message SCLC -> SCRC */ @@ -395,6 +404,7 @@ struct xua_msg *xua) { struct osmo_sccp_addr called; + int rc; LOGP(DLSS7, LOGL_DEBUG, "%s: %s\n", __func__, xua_msg_dump(xua, &xua_dialect_sua)); @@ -403,16 +413,23 @@ /* Message Type */ if (xua->hdr.msg_type == SUA_CL_CLDR) { /* UDTS, XUDTS or LUDTS */ - if (called.ri != OSMO_SCCP_RI_GT) - return scrc_node_7(inst, xua, &called); + if (called.ri != OSMO_SCCP_RI_GT) { + rc = scrc_node_7(inst, xua, &called); + goto out; + } /* Fall-through */ } else { if (0 /* TODO: translation already performed */) { /* Node 12 (Sheet 5) */ - return scrc_node_12(inst, xua, &called); + rc = scrc_node_12(inst, xua, &called); + goto out; } } - return scrc_local_out_common(inst, xua, &called); + + rc = scrc_local_out_common(inst, xua, &called); +out: + xua_msg_free(xua); + return rc; } /* Figure C.1/Q.714 Sheet 1 of 12, after we converted the @@ -423,6 +440,7 @@ struct osmo_sccp_addr called; uint32_t proto_class; struct xua_msg_part *hop_ctr_part; + int rc; LOGP(DLSS7, LOGL_DEBUG, "%s: %s\n", __func__, xua_msg_dump(xua, &xua_dialect_sua)); /* TODO: SCCP or nodal congestion? */ @@ -432,7 +450,8 @@ /* Node 1 (Sheet 3) */ /* deliver to SCOC */ sccp_scoc_rx_from_scrc(inst, xua); - return 0; + rc = 0; + goto out; } /* We only treat connectionless and CR below */ @@ -441,7 +460,8 @@ /* Route on GT? */ if (called.ri != OSMO_SCCP_RI_GT) { /* Node 6 (Sheet 3) */ - return scrc_node_6(inst, xua, &called); + rc = scrc_node_6(inst, xua, &called); + goto out; } /* Message with hop-counter? */ hop_ctr_part = xua_msg_find_tag(xua, SUA_IEI_S7_HOP_CTR); @@ -450,8 +470,8 @@ if (hop_counter <= 1) { /* Error: hop-counter violation */ /* node 4 */ - return scrc_node_4(inst, xua, - SCCP_RETURN_CAUSE_HOP_COUNTER_VIOLATION); + rc = scrc_node_4(inst, xua, SCCP_RETURN_CAUSE_HOP_COUNTER_VIOLATION); + goto out; } /* Decrement hop-counter */ hop_counter--; @@ -471,5 +491,8 @@ default: break; } - return scrc_translate_node_9(inst, xua, &called); + rc = scrc_translate_node_9(inst, xua, &called); +out: + xua_msg_free(xua); + return rc; } diff --git a/src/sccp_user.c b/src/sccp_user.c index 5c8d026..825d545 100644 --- a/src/sccp_user.c +++ b/src/sccp_user.c @@ -152,6 +152,7 @@ struct osmo_sccp_instance *inst = ctx; struct osmo_mtp_prim *omp = (struct osmo_mtp_prim *)oph; struct xua_msg *xua; + int rc; OSMO_ASSERT(oph->sap == MTP_SAP_USER); @@ -161,12 +162,14 @@ xua = osmo_sccp_to_xua(oph->msg); xua->mtp = omp->u.transfer; /* hand this primitive into SCCP via the SCRC code */ - return scrc_rx_mtp_xfer_ind_xua(inst, xua); + rc = scrc_rx_mtp_xfer_ind_xua(inst, xua); default: LOGP(DLSCCP, LOGL_ERROR, "Unknown primitive %u:%u receivd\n", oph->primitive, oph->operation); - return -1; + rc = -1; } + msgb_free(oph->msg); + return rc; } static LLIST_HEAD(sccp_instances); -- To view, visit https://gerrit.osmocom.org/2242 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I708505d129da5824c69b31a13a9c93201929bada Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Sat Apr 8 07:17:38 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 8 Apr 2017 07:17:38 +0000 Subject: [PATCH] libosmo-sccp[master]: Add osmo_sccp_get_ss7() accessor function Message-ID: Review at https://gerrit.osmocom.org/2243 Add osmo_sccp_get_ss7() accessor function as 'struct osmo_sccp_instance' is opaque to the user application, it is useful to have an accessor function that resolves the ss7 instance used by the SCCP instance. Change-Id: I8057a6d69584239b9781c5cece42066293ea1dd6 --- M include/osmocom/sigtran/sccp_sap.h M src/sccp_user.c 2 files changed, 6 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/43/2243/1 diff --git a/include/osmocom/sigtran/sccp_sap.h b/include/osmocom/sigtran/sccp_sap.h index a35af56..03891e7 100644 --- a/include/osmocom/sigtran/sccp_sap.h +++ b/include/osmocom/sigtran/sccp_sap.h @@ -230,6 +230,7 @@ struct osmo_sccp_instance * osmo_sccp_instance_create(struct osmo_ss7_instance *ss7, void *priv); void osmo_sccp_instance_destroy(struct osmo_sccp_instance *inst); +struct osmo_ss7_instance *osmo_sccp_get_ss7(struct osmo_sccp_instance *sccp); void osmo_sccp_user_unbind(struct osmo_sccp_user *scu); void *osmo_sccp_user_get_priv(struct osmo_sccp_user *scu); diff --git a/src/sccp_user.c b/src/sccp_user.c index 825d545..73b6a60 100644 --- a/src/sccp_user.c +++ b/src/sccp_user.c @@ -383,3 +383,8 @@ return NULL; } + +struct osmo_ss7_instance *osmo_sccp_get_ss7(struct osmo_sccp_instance *sccp) +{ + return sccp->ss7; +} -- To view, visit https://gerrit.osmocom.org/2243 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I8057a6d69584239b9781c5cece42066293ea1dd6 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Sat Apr 8 07:17:38 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 8 Apr 2017 07:17:38 +0000 Subject: [PATCH] libosmo-sccp[master]: m3ua_example: Add talloc reporting Message-ID: Review at https://gerrit.osmocom.org/2244 m3ua_example: Add talloc reporting This can be used to check for memory leaks while running the example code. Change-Id: I87caa76a2be3c92c93e419242595107d744bad97 --- M examples/m3ua_example.c 1 file changed, 26 insertions(+), 5 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/44/2244/1 diff --git a/examples/m3ua_example.c b/examples/m3ua_example.c index d7b1fc2..07de7f3 100644 --- a/examples/m3ua_example.c +++ b/examples/m3ua_example.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #include @@ -20,6 +21,8 @@ #include "internal.h" +static struct osmo_sccp_instance *g_sccp; + static struct osmo_sccp_instance *sua_server_helper(void) { struct osmo_sccp_instance *sccp; @@ -36,6 +39,20 @@ /*********************************************************************** * Initialization ***********************************************************************/ + +static void signal_handler(int signal) +{ + fprintf(stdout, "signal %d received\n", signal); + + switch (signal) { + case SIGUSR1: + talloc_report_full(osmo_sccp_get_ss7(g_sccp), stderr); + break; + case SIGUSR2: + talloc_report_full(NULL, stderr); + break; + } +} static const struct log_info_cat log_info_cat[] = { }; @@ -63,9 +80,13 @@ int main(int argc, char **argv) { - struct osmo_sccp_instance *sccp; bool client; int rc; + + talloc_enable_leak_report_full(); + + signal(SIGUSR1, &signal_handler); + signal(SIGUSR2, &signal_handler); init_logging(); osmo_ss7_init(); @@ -85,11 +106,11 @@ if (client) { - sccp = osmo_sccp_simple_client(NULL, "client", 23, OSMO_SS7_ASP_PROT_M3UA, 0, M3UA_PORT, "127.0.0.2"); - sccp_test_user_vty_install(sccp, OSMO_SCCP_SSN_BSC_BSSAP); + g_sccp = osmo_sccp_simple_client(NULL, "client", 23, OSMO_SS7_ASP_PROT_M3UA, 0, M3UA_PORT, "127.0.0.2"); + sccp_test_user_vty_install(g_sccp, OSMO_SCCP_SSN_BSC_BSSAP); } else { - sccp = sua_server_helper(); - sccp_test_server_init(sccp); + g_sccp = sua_server_helper(); + sccp_test_server_init(g_sccp); } while (1) { -- To view, visit https://gerrit.osmocom.org/2244 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I87caa76a2be3c92c93e419242595107d744bad97 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Sat Apr 8 07:17:38 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 8 Apr 2017 07:17:38 +0000 Subject: [PATCH] libosmo-sccp[master]: osmo_ss7: Fix segfault when routing MTP-TRANSFER.req to ASP ... Message-ID: Review at https://gerrit.osmocom.org/2245 osmo_ss7: Fix segfault when routing MTP-TRANSFER.req to ASP without sctp connection Change-Id: I142a11b09672864b54b927b8334b1975c8cd6022 --- M src/osmo_ss7.c 1 file changed, 13 insertions(+), 2 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/45/2245/1 diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index 8ec099a..f7f2519 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -1376,10 +1376,21 @@ OSMO_ASSERT(0); } - if (asp->cfg.is_server) + if (asp->cfg.is_server) { + if (!asp->server) { + LOGPASP(asp, DLSS7, LOGL_ERROR, "Cannot transmit, no asp->server\n"); + /* FIXME: what to do here? delete the route? send DUNA? */ + return -EIO; + } osmo_stream_srv_send(asp->server, msg); - else + } else { + if (!asp->client) { + LOGPASP(asp, DLSS7, LOGL_ERROR, "Cannot transmit, no asp->client\n"); + /* FIXME: what to do here? delete the route? send DUNA? */ + return -EIO; + } osmo_stream_cli_send(asp->client, msg); + } return 0; } -- To view, visit https://gerrit.osmocom.org/2245 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I142a11b09672864b54b927b8334b1975c8cd6022 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Sat Apr 8 07:34:24 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 8 Apr 2017 07:34:24 +0000 Subject: [PATCH] libosmocore[master]: add VTY port number for osmo-stp Message-ID: Review at https://gerrit.osmocom.org/2246 add VTY port number for osmo-stp Change-Id: I978e1b73aa8097a7db6318d78f9f93457e6ce2af --- M include/osmocom/vty/ports.h 1 file changed, 1 insertion(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/46/2246/1 diff --git a/include/osmocom/vty/ports.h b/include/osmocom/vty/ports.h index 887e4df..a6043b3 100644 --- a/include/osmocom/vty/ports.h +++ b/include/osmocom/vty/ports.h @@ -9,6 +9,7 @@ */ /* 4238 used by osmo-bts control interface */ +#define OSMO_VTY_PORT_STP 4239 #define OSMO_VTY_PORT_PCU 4240 /* also: osmo_pcap_client */ #define OSMO_VTY_PORT_BTS 4241 /* also: osmo_pcap_server */ #define OSMO_VTY_PORT_NITB_BSC 4242 -- To view, visit https://gerrit.osmocom.org/2246 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I978e1b73aa8097a7db6318d78f9f93457e6ce2af Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Sat Apr 8 07:35:25 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 8 Apr 2017 07:35:25 +0000 Subject: [PATCH] osmo-gsm-manuals[master]: port_numbers.adoc: Add VTY port number for STP Message-ID: Review at https://gerrit.osmocom.org/2247 port_numbers.adoc: Add VTY port number for STP Change-Id: If812e0d6818ed704f0b75a9bc3e07dddfba37081 --- M common/chapters/port_numbers.adoc 1 file changed, 1 insertion(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-gsm-manuals refs/changes/47/2247/1 diff --git a/common/chapters/port_numbers.adoc b/common/chapters/port_numbers.adoc index 4475b0f..d5cba8f 100644 --- a/common/chapters/port_numbers.adoc +++ b/common/chapters/port_numbers.adoc @@ -14,6 +14,7 @@ |TCP|2775|SMPP (SMS interface for external programs)|osmo-nitb |TCP|3002|A-bis/IP OML|osmo-bts, osmo-bsc, osmo-nitb |TCP|3003|A-bis/IP RSL|osmo-bts, osmo-bsc, osmo-nitb +|TCP|4239|telnet (VTY)|osmo-stp |TCP|4240|telnet (VTY)|osmo-pcu |TCP|4241|telnet (VTY)|osmo-bts |TCP|4242|telnet (VTY)|osmo-nitb, osmo-bsc, cellmgr-ng -- To view, visit https://gerrit.osmocom.org/2247 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: If812e0d6818ed704f0b75a9bc3e07dddfba37081 Gerrit-PatchSet: 1 Gerrit-Project: osmo-gsm-manuals Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Sat Apr 8 07:36:09 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 8 Apr 2017 07:36:09 +0000 Subject: libosmo-sccp[master]: sccp: add osmo_sccp_user_get_priv() API function In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2234 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ia68a36dc18a7d754d63ae29c86d68e495b5c4134 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sat Apr 8 07:36:15 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 8 Apr 2017 07:36:15 +0000 Subject: libosmo-sccp[master]: osmo_ss7: make OVERRIDE the default traffic mode type (0) In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2235 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ie83fa0a403dcfc582d6bb59ec08d6a719d2f6398 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sat Apr 8 07:36:26 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 8 Apr 2017 07:36:26 +0000 Subject: libosmo-sccp[master]: add converter functions between osmo_ss7 and m3ua traffic mo... In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2236 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I6cc9530d7d2812cbc8feb6e9db51902865ebfe83 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sat Apr 8 07:37:16 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 8 Apr 2017 07:37:16 +0000 Subject: libosmo-sccp[master]: xua_asp_fsm: Always return BEAT-ACK for BEAT, including BEAT... In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2238 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I836e0940a8dbb0f55ddf132202a5f0d51473b82d Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sat Apr 8 07:37:38 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 8 Apr 2017 07:37:38 +0000 Subject: libosmo-sccp[master]: xua_as_fsm: Include routing context (if configured) in NTFY ... In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2239 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I15e8bf5cee194f9924d0eab9cff0e7c25daa6dde Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sat Apr 8 07:37:47 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 8 Apr 2017 07:37:47 +0000 Subject: libosmo-sccp[master]: xua_cli_conn_cb: Print flags as hex, not decimal. In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2240 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Idcf861cfdc6c14d7d3bafbf2e243da5db6e2f3e6 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sat Apr 8 07:37:57 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 8 Apr 2017 07:37:57 +0000 Subject: libosmo-sccp[master]: xua_srv_conn_cb(): Print sctp_recvmsg flags (line in xua_cli... In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2241 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I91920c6ad665abc791a1dbf386d52cf0aece9133 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sat Apr 8 07:38:00 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 8 Apr 2017 07:38:00 +0000 Subject: libosmo-sccp[master]: sigtran: fix various memory leaks (msgb and xua_msg) In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2242 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I708505d129da5824c69b31a13a9c93201929bada Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sat Apr 8 07:38:04 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 8 Apr 2017 07:38:04 +0000 Subject: libosmo-sccp[master]: Add osmo_sccp_get_ss7() accessor function In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2243 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I8057a6d69584239b9781c5cece42066293ea1dd6 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sat Apr 8 07:38:07 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 8 Apr 2017 07:38:07 +0000 Subject: libosmo-sccp[master]: m3ua_example: Add talloc reporting In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2244 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I87caa76a2be3c92c93e419242595107d744bad97 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sat Apr 8 07:38:10 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 8 Apr 2017 07:38:10 +0000 Subject: libosmo-sccp[master]: osmo_ss7: Fix segfault when routing MTP-TRANSFER.req to ASP ... In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2245 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I142a11b09672864b54b927b8334b1975c8cd6022 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sat Apr 8 07:38:17 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 8 Apr 2017 07:38:17 +0000 Subject: osmo-gsm-manuals[master]: port_numbers.adoc: Add VTY port number for STP In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2247 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: If812e0d6818ed704f0b75a9bc3e07dddfba37081 Gerrit-PatchSet: 1 Gerrit-Project: osmo-gsm-manuals Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sat Apr 8 07:38:25 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 8 Apr 2017 07:38:25 +0000 Subject: [MERGED] osmo-gsm-manuals[master]: port_numbers.adoc: Add VTY port number for STP In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: port_numbers.adoc: Add VTY port number for STP ...................................................................... port_numbers.adoc: Add VTY port number for STP Change-Id: If812e0d6818ed704f0b75a9bc3e07dddfba37081 --- M common/chapters/port_numbers.adoc 1 file changed, 1 insertion(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/common/chapters/port_numbers.adoc b/common/chapters/port_numbers.adoc index 4475b0f..d5cba8f 100644 --- a/common/chapters/port_numbers.adoc +++ b/common/chapters/port_numbers.adoc @@ -14,6 +14,7 @@ |TCP|2775|SMPP (SMS interface for external programs)|osmo-nitb |TCP|3002|A-bis/IP OML|osmo-bts, osmo-bsc, osmo-nitb |TCP|3003|A-bis/IP RSL|osmo-bts, osmo-bsc, osmo-nitb +|TCP|4239|telnet (VTY)|osmo-stp |TCP|4240|telnet (VTY)|osmo-pcu |TCP|4241|telnet (VTY)|osmo-bts |TCP|4242|telnet (VTY)|osmo-nitb, osmo-bsc, cellmgr-ng -- To view, visit https://gerrit.osmocom.org/2247 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: If812e0d6818ed704f0b75a9bc3e07dddfba37081 Gerrit-PatchSet: 1 Gerrit-Project: osmo-gsm-manuals Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sat Apr 8 07:38:31 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 8 Apr 2017 07:38:31 +0000 Subject: libosmocore[master]: add VTY port number for osmo-stp In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2246 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I978e1b73aa8097a7db6318d78f9f93457e6ce2af Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sat Apr 8 07:38:38 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 8 Apr 2017 07:38:38 +0000 Subject: [MERGED] libosmocore[master]: add VTY port number for osmo-stp In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: add VTY port number for osmo-stp ...................................................................... add VTY port number for osmo-stp Change-Id: I978e1b73aa8097a7db6318d78f9f93457e6ce2af --- M include/osmocom/vty/ports.h 1 file changed, 1 insertion(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/include/osmocom/vty/ports.h b/include/osmocom/vty/ports.h index 887e4df..a6043b3 100644 --- a/include/osmocom/vty/ports.h +++ b/include/osmocom/vty/ports.h @@ -9,6 +9,7 @@ */ /* 4238 used by osmo-bts control interface */ +#define OSMO_VTY_PORT_STP 4239 #define OSMO_VTY_PORT_PCU 4240 /* also: osmo_pcap_client */ #define OSMO_VTY_PORT_BTS 4241 /* also: osmo_pcap_server */ #define OSMO_VTY_PORT_NITB_BSC 4242 -- To view, visit https://gerrit.osmocom.org/2246 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I978e1b73aa8097a7db6318d78f9f93457e6ce2af Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sat Apr 8 07:41:00 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 8 Apr 2017 07:41:00 +0000 Subject: libosmocore[master]: core/conv: implement optimized Viterbi decoder In-Reply-To: References: Message-ID: Patch Set 6: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/1337 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I74d355274b4176a7d924f91ef3c96912ce338fb2 Gerrit-PatchSet: 6 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Vadim Yanitskiy Gerrit-Reviewer: Alexander Chemeris Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Tom Tsou Gerrit-Reviewer: Vadim Yanitskiy Gerrit-Reviewer: tnt Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sat Apr 8 07:41:27 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 8 Apr 2017 07:41:27 +0000 Subject: libosmocore[master]: core/conv: implement optimized Viterbi decoder In-Reply-To: References: Message-ID: Patch Set 6: gave my +2, but leaving the final word to ttsou on this. @ttsou: If you're fine with v6 of this patch, please merge. -- To view, visit https://gerrit.osmocom.org/1337 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I74d355274b4176a7d924f91ef3c96912ce338fb2 Gerrit-PatchSet: 6 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Vadim Yanitskiy Gerrit-Reviewer: Alexander Chemeris Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Tom Tsou Gerrit-Reviewer: Vadim Yanitskiy Gerrit-Reviewer: tnt Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sat Apr 8 07:41:41 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 8 Apr 2017 07:41:41 +0000 Subject: osmo-gsm-manuals[master]: add INSTALL.txt with a list of dependencies In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2233 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I0e472381270c4c4783394ef8969bc8cb6005dcfe Gerrit-PatchSet: 1 Gerrit-Project: osmo-gsm-manuals Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sat Apr 8 07:41:42 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 8 Apr 2017 07:41:42 +0000 Subject: [MERGED] osmo-gsm-manuals[master]: add INSTALL.txt with a list of dependencies In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: add INSTALL.txt with a list of dependencies ...................................................................... add INSTALL.txt with a list of dependencies Change-Id: I0e472381270c4c4783394ef8969bc8cb6005dcfe --- A INSTALL.txt 1 file changed, 14 insertions(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/INSTALL.txt b/INSTALL.txt new file mode 100644 index 0000000..6f19720 --- /dev/null +++ b/INSTALL.txt @@ -0,0 +1,14 @@ +Dependencies needed, by example of a debian system: + +apt-get install \ + make \ + asciidoc \ + xsltproc \ + dblatex \ + mscgen \ + graphviz + +Build PDFs, run: + make +or for a parallel build using more CPU cores: + make -j 5 -- To view, visit https://gerrit.osmocom.org/2233 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I0e472381270c4c4783394ef8969bc8cb6005dcfe Gerrit-PatchSet: 2 Gerrit-Project: osmo-gsm-manuals Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sat Apr 8 07:42:15 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 8 Apr 2017 07:42:15 +0000 Subject: osmo-bts[master]: sysmobts: Don't start with 0dBm TRX output power before ramping In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2231 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I0ad91fce64f65e0213c9fcfde3390ace519055db Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sat Apr 8 07:42:26 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 8 Apr 2017 07:42:26 +0000 Subject: [MERGED] osmo-bts[master]: sysmobts: Don't start with 0dBm TRX output power before ramping In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: sysmobts: Don't start with 0dBm TRX output power before ramping ...................................................................... sysmobts: Don't start with 0dBm TRX output power before ramping In case a system has a high-gain external PA (like a 40dB PA) connected externally, we cannot simply switch the transceiver to 0 dBm in trx_init() only to then start the ramping at much lower levels once the PHJ completes in trx_init_compl_cb(). The result would be a short 0 + 40 dBm spike followed by later ramping. We want to avoid that spike, particularly its associated inrush current, so let's bring up the board with smething very conservative like -50 dBm, and then ramp from there. Change-Id: I0ad91fce64f65e0213c9fcfde3390ace519055db Fixes: SYS#3259 --- M include/osmo-bts/tx_power.h M src/common/bts.c M src/common/tx_power.c M src/osmo-bts-sysmo/oml.c M tests/tx_power/tx_power_test.c 5 files changed, 30 insertions(+), 3 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/include/osmo-bts/tx_power.h b/include/osmo-bts/tx_power.h index 8d099bc..21887c7 100644 --- a/include/osmo-bts/tx_power.h +++ b/include/osmo-bts/tx_power.h @@ -74,3 +74,5 @@ int power_ramp_start(struct gsm_bts_trx *trx, int p_total_tgt_mdBm, int bypass); void power_trx_change_compl(struct gsm_bts_trx *trx, int p_trxout_cur_mdBm); + +int power_ramp_initial_power_mdBm(struct gsm_bts_trx *trx); diff --git a/src/common/bts.c b/src/common/bts.c index 9915e1c..540caaa 100644 --- a/src/common/bts.c +++ b/src/common/bts.c @@ -153,7 +153,7 @@ } } /* Default values for the power adjustments */ - tpp->ramp.max_initial_pout_mdBm = to_mdB(23); + tpp->ramp.max_initial_pout_mdBm = to_mdB(0); tpp->ramp.step_size_mdB = to_mdB(2); tpp->ramp.step_interval_sec = 1; } diff --git a/src/common/tx_power.c b/src/common/tx_power.c index c517918..3dfe1f7 100644 --- a/src/common/tx_power.c +++ b/src/common/tx_power.c @@ -289,3 +289,18 @@ return 0; } + +/* determine the initial transceiver output power at start-up time */ +int power_ramp_initial_power_mdBm(struct gsm_bts_trx *trx) +{ + struct trx_power_params *tpp = &trx->power_params; + int pout_mdBm; + + /* this is the maximum initial output on the antenna connector + * towards the antenna */ + pout_mdBm = tpp->ramp.max_initial_pout_mdBm; + + /* use this as input to compute transceiver board power + * (reflecting gains in internal/external amplifiers */ + return get_p_trxout_eff_mdBm(trx, pout_mdBm); +} diff --git a/src/osmo-bts-sysmo/oml.c b/src/osmo-bts-sysmo/oml.c index 01752d1..776a50c 100644 --- a/src/osmo-bts-sysmo/oml.c +++ b/src/osmo-bts-sysmo/oml.c @@ -389,6 +389,7 @@ GsmL1_MphInitReq_t *mi_req; GsmL1_DeviceParam_t *dev_par; int femto_band; + int initial_mdBm = power_ramp_initial_power_mdBm(trx); if (!gsm_abis_mo_check_attr(&trx->mo, trx_rqd_attr, ARRAY_SIZE(trx_rqd_attr))) { @@ -416,11 +417,12 @@ dev_par->fRxPowerLevel = trx_ms_pwr_ctrl_is_osmo(trx) ? 0.0 : btsb->ul_power_target; - dev_par->fTxPowerLevel = 0.0; + dev_par->fTxPowerLevel = ((float) initial_mdBm) / 1000; LOGP(DL1C, LOGL_NOTICE, "Init TRX (ARFCN %u, TSC %u, RxPower % 2f dBm, " "TxPower % 2.2f dBm\n", dev_par->u16Arfcn, dev_par->u8NbTsc, dev_par->fRxPowerLevel, dev_par->fTxPowerLevel); - + trx->power_params.p_total_cur_mdBm = trx->power_params.ramp.max_initial_pout_mdBm; + /* send MPH-INIT-REQ, wait for MPH-INIT-CNF */ return l1if_gsm_req_compl(fl1h, msg, trx_init_compl_cb, NULL); } diff --git a/tests/tx_power/tx_power_test.c b/tests/tx_power/tx_power_test.c index d657362..fb23409 100644 --- a/tests/tx_power/tx_power_test.c +++ b/tests/tx_power/tx_power_test.c @@ -44,6 +44,7 @@ .nominal_gain_mdB = 0, }, .ramp = { + .max_initial_pout_mdBm = to_mdB(23), .step_size_mdB = to_mdB(2), .step_interval_sec = 1, }, @@ -62,6 +63,7 @@ .nominal_gain_mdB = 0, }, .ramp = { + .max_initial_pout_mdBm = to_mdB(0), .step_size_mdB = to_mdB(2), .step_interval_sec = 1, }, @@ -80,6 +82,7 @@ .nominal_gain_mdB = 0, }, .ramp = { + .max_initial_pout_mdBm = to_mdB(0), .step_size_mdB = to_mdB(2), .step_interval_sec = 1, }, @@ -98,6 +101,7 @@ .nominal_gain_mdB = 0, }, .ramp = { + .max_initial_pout_mdBm = to_mdB(0), .step_size_mdB = to_mdB(2), .step_interval_sec = 1, }, @@ -108,6 +112,7 @@ printf("Testing tx_power calculation for sysmoBTS 1002\n"); trx->power_params = tpp_1002; trx->max_power_red = 0; + OSMO_ASSERT(power_ramp_initial_power_mdBm(trx) == to_mdB(23)); OSMO_ASSERT(get_p_max_out_mdBm(trx) == to_mdB(23)); /* at max_power_red = 0, we expect full 23dBm */ OSMO_ASSERT(get_p_nominal_mdBm(trx) == to_mdB(23)); @@ -125,6 +130,7 @@ printf("Testing tx_power calculation for sysmoBTS 1020\n"); trx->power_params = tpp_1020; trx->max_power_red = 0; + OSMO_ASSERT(power_ramp_initial_power_mdBm(trx) == to_mdB(-10)); OSMO_ASSERT(get_p_max_out_mdBm(trx) == to_mdB(33)); /* at max_power_red = 0, we expect full 33dBm */ OSMO_ASSERT(get_p_nominal_mdBm(trx) == to_mdB(33)); @@ -143,6 +149,7 @@ printf("Testing tx_power calculation for sysmoBTS 1100\n"); trx->power_params = tpp_1100; trx->max_power_red = 0; + OSMO_ASSERT(power_ramp_initial_power_mdBm(trx) == to_mdB(-17)); OSMO_ASSERT(get_p_max_out_mdBm(trx) == to_mdB(40)); /* at max_power_red = 0, we expect full 33dBm */ OSMO_ASSERT(get_p_nominal_mdBm(trx) == to_mdB(40)); @@ -160,6 +167,7 @@ printf("Testing tx_power calculation for sysmoBTS 2050\n"); trx->power_params = tpp_2050; trx->max_power_red = 0; + OSMO_ASSERT(power_ramp_initial_power_mdBm(trx) == to_mdB(0)); OSMO_ASSERT(get_p_max_out_mdBm(trx) == to_mdB(37)); /* at max_power_red = 0, we expect full 37dBm */ OSMO_ASSERT(get_p_nominal_mdBm(trx) == to_mdB(37)); -- To view, visit https://gerrit.osmocom.org/2231 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I0ad91fce64f65e0213c9fcfde3390ace519055db Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sat Apr 8 07:43:52 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 8 Apr 2017 07:43:52 +0000 Subject: libosmocore[master]: gsm0808: Add AoIP specific elements to gsm0808_create_... fu... In-Reply-To: References: Message-ID: Patch Set 5: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2178 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I77f866abec1822d19871052f3c647ad782785b34 Gerrit-PatchSet: 5 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sat Apr 8 07:44:17 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 8 Apr 2017 07:44:17 +0000 Subject: libosmocore[master]: gsm0808: Add create functions for CIPHER MODE COMMAND In-Reply-To: References: Message-ID: Patch Set 5: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2182 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I8eb1c357860c3e740b0f5d17e1c256bc87920958 Gerrit-PatchSet: 5 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sat Apr 8 07:44:43 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 8 Apr 2017 07:44:43 +0000 Subject: libosmocore[master]: gsm0808: make gsm0808_create_reset_ack() accessible In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2229 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I82d3411484f82b4a9205d407fa0442244678f183 Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sat Apr 8 07:44:47 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 8 Apr 2017 07:44:47 +0000 Subject: [MERGED] libosmocore[master]: gsm0808: make gsm0808_create_reset_ack() accessible In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: gsm0808: make gsm0808_create_reset_ack() accessible ...................................................................... gsm0808: make gsm0808_create_reset_ack() accessible The create function to generate the RESET ACKNOWLEDGE message is not accessible from outside, as it does not appear in limosmogsm.map. It also has not testcase. This commit adds gsm0808_create_reset_ack() to the map file and also adds a testcase. Change-Id: I82d3411484f82b4a9205d407fa0442244678f183 --- M src/gsm/libosmogsm.map M tests/gsm0808/gsm0808_test.c M tests/gsm0808/gsm0808_test.ok 3 files changed, 15 insertions(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map index a4e6083..c825dd5 100644 --- a/src/gsm/libosmogsm.map +++ b/src/gsm/libosmogsm.map @@ -141,6 +141,7 @@ gsm0808_create_layer3; gsm0808_create_layer3_aoip; gsm0808_create_reset; +gsm0808_create_reset_ack; gsm0808_create_sapi_reject; gsm0808_prepend_dtap_header; gsm0808_enc_aoip_trasp_addr; diff --git a/tests/gsm0808/gsm0808_test.c b/tests/gsm0808/gsm0808_test.c index a0ff6d5..8304052 100644 --- a/tests/gsm0808/gsm0808_test.c +++ b/tests/gsm0808/gsm0808_test.c @@ -123,6 +123,18 @@ msgb_free(msg); } +static void test_create_reset_ack() +{ + static const uint8_t res[] = { 0x00, 0x01, 0x31 }; + struct msgb *msg; + + printf("Testing creating Reset Ack\n"); + msg = gsm0808_create_reset_ack(); + VERIFY(msg, res, ARRAY_SIZE(res)); + msgb_free(msg); +} + + static void test_create_clear_command() { static const uint8_t res[] = { 0x20, 0x04, 0x01, 0x23 }; @@ -828,6 +840,7 @@ test_create_layer3(); test_create_layer3_aoip(); test_create_reset(); + test_create_reset_ack(); test_create_clear_command(); test_create_clear_complete(); test_create_cipher(); diff --git a/tests/gsm0808/gsm0808_test.ok b/tests/gsm0808/gsm0808_test.ok index 52af134..e101d65 100644 --- a/tests/gsm0808/gsm0808_test.ok +++ b/tests/gsm0808/gsm0808_test.ok @@ -2,6 +2,7 @@ Testing creating Layer3 Testing creating Layer3 (AoIP) Testing creating Reset +Testing creating Reset Ack Testing creating Clear Command Testing creating Clear Complete Testing creating Chipher Mode Command -- To view, visit https://gerrit.osmocom.org/2229 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I82d3411484f82b4a9205d407fa0442244678f183 Gerrit-PatchSet: 2 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sat Apr 8 07:44:47 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 8 Apr 2017 07:44:47 +0000 Subject: [MERGED] libosmocore[master]: gsm0808: Add create functions for CIPHER MODE COMMAND In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: gsm0808: Add create functions for CIPHER MODE COMMAND ...................................................................... gsm0808: Add create functions for CIPHER MODE COMMAND gsm0808.h/c lacks functionality to generate CIPHER MODE COMMAND messages. These messages are required if the code is used in an MSC implementation. This commit adds a gsm0808_create_cipher() function, that generates an A/AoiP CIPHER MODE COMMAND message. Change-Id: I8eb1c357860c3e740b0f5d17e1c256bc87920958 --- M include/osmocom/gsm/gsm0808.h M src/gsm/gsm0808.c M src/gsm/libosmogsm.map M tests/gsm0808/gsm0808_test.c M tests/gsm0808/gsm0808_test.ok 5 files changed, 78 insertions(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/include/osmocom/gsm/gsm0808.h b/include/osmocom/gsm/gsm0808.h index fd73376..9738a55 100644 --- a/include/osmocom/gsm/gsm0808.h +++ b/include/osmocom/gsm/gsm0808.h @@ -35,6 +35,8 @@ struct msgb *gsm0808_create_reset_ack(void); struct msgb *gsm0808_create_clear_command(uint8_t reason); struct msgb *gsm0808_create_clear_complete(void); +struct msgb *gsm0808_create_cipher(const struct gsm0808_encrypt_info *ei, + const uint8_t *cipher_response_mode); struct msgb *gsm0808_create_cipher_complete(struct msgb *layer3, uint8_t alg_id); struct msgb *gsm0808_create_cipher_reject(uint8_t cause); struct msgb *gsm0808_create_classmark_update(const uint8_t *cm2, uint8_t cm2_len, diff --git a/src/gsm/gsm0808.c b/src/gsm/gsm0808.c index b8ab79b..c952a9f 100644 --- a/src/gsm/gsm0808.c +++ b/src/gsm/gsm0808.c @@ -131,6 +131,39 @@ return msg; } +struct msgb *gsm0808_create_cipher(const struct gsm0808_encrypt_info *ei, + const uint8_t *cipher_response_mode) +{ + /* See also: 3GPP TS 48.008 3.2.1.30 CIPHER MODE COMMAND */ + struct msgb *msg; + + /* Mandatory emelent! */ + OSMO_ASSERT(ei); + + msg = + msgb_alloc_headroom(BSSMAP_MSG_SIZE, BSSMAP_MSG_HEADROOM, + "cipher-mode-command"); + if (!msg) + return NULL; + + /* Message Type 3.2.2.1 */ + msgb_v_put(msg, BSS_MAP_MSG_CIPHER_MODE_CMD); + + /* Encryption Information 3.2.2.10 */ + gsm0808_enc_encrypt_info(msg, ei); + + /* Cipher Response Mode 3.2.2.34 */ + if (cipher_response_mode) + msgb_tv_put(msg, GSM0808_IE_CIPHER_RESPONSE_MODE, + *cipher_response_mode); + + /* pre-pend the header */ + msg->l3h = + msgb_tv_push(msg, BSSAP_MSG_BSS_MANAGEMENT, msgb_length(msg)); + + return msg; +} + struct msgb *gsm0808_create_cipher_complete(struct msgb *layer3, uint8_t alg_id) { struct msgb *msg = msgb_alloc_headroom(BSSMAP_MSG_SIZE, BSSMAP_MSG_HEADROOM, diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map index cf0a7fe..786bf08 100644 --- a/src/gsm/libosmogsm.map +++ b/src/gsm/libosmogsm.map @@ -128,6 +128,7 @@ gsm0808_create_ass_compl; gsm0808_create_assignment_failure; gsm0808_create_ass_fail; +gsm0808_create_cipher; gsm0808_create_cipher_complete; gsm0808_create_cipher_reject; gsm0808_create_classmark_update; diff --git a/tests/gsm0808/gsm0808_test.c b/tests/gsm0808/gsm0808_test.c index af457b4..f33e0bd 100644 --- a/tests/gsm0808/gsm0808_test.c +++ b/tests/gsm0808/gsm0808_test.c @@ -144,6 +144,46 @@ msgb_free(msg); } +static void test_create_cipher() +{ + static const uint8_t res[] = + { 0x00, 0x0c, 0x53, 0x0a, 0x09, 0x03, 0xaa, + 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x23, 0x42 }; + static const uint8_t res2[] = + { 0x00, 0x0e, 0x53, 0x0a, 0x09, 0x03, 0xaa, + 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x23, 0x42, + GSM0808_IE_CIPHER_RESPONSE_MODE, 0x01 }; + struct msgb *msg; + struct gsm0808_encrypt_info ei; + uint8_t include_imeisv; + + memset(&ei, 0, sizeof(ei)); + ei.perm_algo[0] = GSM0808_ALG_ID_A5_0; + ei.perm_algo[1] = GSM0808_ALG_ID_A5_1; + ei.perm_algo_len = 2; + ei.key[0] = 0xaa; + ei.key[1] = 0xbb; + ei.key[2] = 0xcc; + ei.key[3] = 0xdd; + ei.key[4] = 0xee; + ei.key[5] = 0xff; + ei.key[6] = 0x23; + ei.key[7] = 0x42; + ei.key_len = 8; + include_imeisv = 1; + + printf("Testing creating Chipher Mode Command\n"); + msg = gsm0808_create_cipher(&ei, NULL); + OSMO_ASSERT(msg); + VERIFY(msg, res, ARRAY_SIZE(res)); + msgb_free(msg); + + msg = gsm0808_create_cipher(&ei, &include_imeisv); + OSMO_ASSERT(msg); + VERIFY(msg, res2, ARRAY_SIZE(res2)); + msgb_free(msg); +} + static void test_create_cipher_complete() { static const uint8_t res1[] = { @@ -700,6 +740,7 @@ test_create_reset(); test_create_clear_command(); test_create_clear_complete(); + test_create_cipher(); test_create_cipher_complete(); test_create_cipher_reject(); test_create_cm_u(); diff --git a/tests/gsm0808/gsm0808_test.ok b/tests/gsm0808/gsm0808_test.ok index f406551..8e2087d 100644 --- a/tests/gsm0808/gsm0808_test.ok +++ b/tests/gsm0808/gsm0808_test.ok @@ -4,6 +4,7 @@ Testing creating Reset Testing creating Clear Command Testing creating Clear Complete +Testing creating Chipher Mode Command Testing creating Cipher Complete Testing creating Cipher Reject Testing creating CM U -- To view, visit https://gerrit.osmocom.org/2182 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I8eb1c357860c3e740b0f5d17e1c256bc87920958 Gerrit-PatchSet: 6 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sat Apr 8 07:44:48 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 8 Apr 2017 07:44:48 +0000 Subject: [MERGED] libosmocore[master]: gsm0808: Add AoIP specific elements to gsm0808_create_... fu... In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: gsm0808: Add AoIP specific elements to gsm0808_create_... functions ...................................................................... gsm0808: Add AoIP specific elements to gsm0808_create_... functions the classic A implementation in libosmocore lacks support for AoIP message elements. This patch adds support for AoIP by adding a set of new gsm0808_create_..., which support the missing AoIP message elements Change-Id: I77f866abec1822d19871052f3c647ad782785b34 --- M include/osmocom/gsm/gsm0808.h M src/gsm/gsm0808.c M src/gsm/libosmogsm.map M tests/gsm0808/gsm0808_test.c M tests/gsm0808/gsm0808_test.ok 5 files changed, 195 insertions(+), 7 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/include/osmocom/gsm/gsm0808.h b/include/osmocom/gsm/gsm0808.h index a7e102c..fd73376 100644 --- a/include/osmocom/gsm/gsm0808.h +++ b/include/osmocom/gsm/gsm0808.h @@ -20,10 +20,17 @@ #pragma once #include "tlv.h" +#include +#include struct msgb; -struct msgb *gsm0808_create_layer3(struct msgb *msg, uint16_t netcode, uint16_t countrycode, int lac, uint16_t ci); +struct msgb *gsm0808_create_layer3(struct msgb *msg_l3, uint16_t nc, + uint16_t cc, int lac, uint16_t _ci); +struct msgb *gsm0808_create_layer3_aoip(const struct msgb *msg_l3, uint16_t nc, + uint16_t cc, int lac, uint16_t _ci, + const struct gsm0808_speech_codec_list + *scl); struct msgb *gsm0808_create_reset(void); struct msgb *gsm0808_create_reset_ack(void); struct msgb *gsm0808_create_clear_command(uint8_t reason); @@ -33,9 +40,19 @@ struct msgb *gsm0808_create_classmark_update(const uint8_t *cm2, uint8_t cm2_len, const uint8_t *cm3, uint8_t cm3_len); struct msgb *gsm0808_create_sapi_reject(uint8_t link_id); +struct msgb *gsm0808_create_ass_compl(uint8_t rr_cause, uint8_t chosen_channel, + uint8_t encr_alg_id, uint8_t speech_mode, + const struct sockaddr_storage *ss, + const struct gsm0808_speech_codec *sc, + const struct gsm0808_speech_codec_list + *scl); struct msgb *gsm0808_create_assignment_completed(uint8_t rr_cause, - uint8_t chosen_channel, uint8_t encr_alg_id, + uint8_t chosen_channel, + uint8_t encr_alg_id, uint8_t speech_mode); +struct msgb *gsm0808_create_ass_fail(uint8_t cause, const uint8_t *rr_cause, + const struct gsm0808_speech_codec_list + *scl); struct msgb *gsm0808_create_assignment_failure(uint8_t cause, uint8_t *rr_cause); struct msgb *gsm0808_create_clear_rqst(uint8_t cause); diff --git a/src/gsm/gsm0808.c b/src/gsm/gsm0808.c index de80006..b8ab79b 100644 --- a/src/gsm/gsm0808.c +++ b/src/gsm/gsm0808.c @@ -19,6 +19,7 @@ */ #include +#include #include #include @@ -27,7 +28,10 @@ #define BSSMAP_MSG_SIZE 512 #define BSSMAP_MSG_HEADROOM 128 -struct msgb *gsm0808_create_layer3(struct msgb *msg_l3, uint16_t nc, uint16_t cc, int lac, uint16_t _ci) +struct msgb *gsm0808_create_layer3_aoip(const struct msgb *msg_l3, uint16_t nc, + uint16_t cc, int lac, uint16_t _ci, + const struct gsm0808_speech_codec_list + *scl) { struct msgb* msg; struct { @@ -55,10 +59,20 @@ msgb_tlv_put(msg, GSM0808_IE_LAYER_3_INFORMATION, msgb_l3len(msg_l3), msg_l3->l3h); + /* AoIP: add Codec List (BSS Supported) 3.2.2.103 */ + if (scl) + gsm0808_enc_speech_codec_list(msg, scl); + /* push the bssmap header */ msg->l3h = msgb_tv_push(msg, BSSAP_MSG_BSS_MANAGEMENT, msgb_length(msg)); return msg; +} + +struct msgb *gsm0808_create_layer3(struct msgb *msg_l3, uint16_t nc, + uint16_t cc, int lac, uint16_t _ci) +{ + return gsm0808_create_layer3_aoip(msg_l3, nc, cc, lac, _ci, NULL); } struct msgb *gsm0808_create_reset(void) @@ -191,9 +205,12 @@ return msg; } -struct msgb *gsm0808_create_assignment_completed(uint8_t rr_cause, - uint8_t chosen_channel, uint8_t encr_alg_id, - uint8_t speech_mode) +struct msgb *gsm0808_create_ass_compl(uint8_t rr_cause, uint8_t chosen_channel, + uint8_t encr_alg_id, uint8_t speech_mode, + const struct sockaddr_storage *ss, + const struct gsm0808_speech_codec *sc, + const struct gsm0808_speech_codec_list + *scl) { struct msgb *msg = msgb_alloc_headroom(BSSMAP_MSG_SIZE, BSSMAP_MSG_HEADROOM, "bssmap: ass compl"); @@ -218,6 +235,18 @@ if (speech_mode != 0) msgb_tv_put(msg, GSM0808_IE_SPEECH_VERSION, speech_mode); + /* AoIP: AoIP Transport Layer Address (BSS) 3.2.2.102 */ + if (ss) + gsm0808_enc_aoip_trasp_addr(msg, ss); + + /* AoIP: Speech Codec (Chosen) 3.2.2.104 */ + if (sc) + gsm0808_enc_speech_codec(msg, sc); + + /* AoIP: add Codec List (BSS Supported) 3.2.2.103 */ + if (scl) + gsm0808_enc_speech_codec_list(msg, scl); + /* write LSA identifier 3.2.2.15 */ msg->l3h = msgb_tv_push(msg, BSSAP_MSG_BSS_MANAGEMENT, msgb_length(msg)); @@ -225,7 +254,18 @@ return msg; } -struct msgb *gsm0808_create_assignment_failure(uint8_t cause, uint8_t *rr_cause) +struct msgb *gsm0808_create_assignment_completed(uint8_t rr_cause, + uint8_t chosen_channel, + uint8_t encr_alg_id, + uint8_t speech_mode) +{ + return gsm0808_create_ass_compl(rr_cause, chosen_channel, encr_alg_id, + speech_mode, NULL, NULL, NULL); +} + +struct msgb *gsm0808_create_ass_fail(uint8_t cause, const uint8_t *rr_cause, + const struct gsm0808_speech_codec_list + *scl) { struct msgb *msg = msgb_alloc_headroom(BSSMAP_MSG_SIZE, BSSMAP_MSG_HEADROOM, "bssmap: ass fail"); @@ -242,12 +282,22 @@ /* Circuit pool 3.22.45 */ /* Circuit pool list 3.2.2.46 */ + /* AoIP: add Codec List (BSS Supported) 3.2.2.103 */ + if (scl) + gsm0808_enc_speech_codec_list(msg, scl); + /* update the size */ msg->l3h = msgb_tv_push(msg, BSSAP_MSG_BSS_MANAGEMENT, msgb_length(msg)); return msg; } +struct msgb *gsm0808_create_assignment_failure(uint8_t cause, + uint8_t *rr_cause) +{ + return gsm0808_create_ass_fail(cause, rr_cause, NULL); +} + struct msgb *gsm0808_create_clear_rqst(uint8_t cause) { struct msgb *msg; diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map index c89cbe4..518a5aa 100644 --- a/src/gsm/libosmogsm.map +++ b/src/gsm/libosmogsm.map @@ -125,7 +125,9 @@ gsm0808_bssap_name; gsm0808_bssmap_name; gsm0808_create_assignment_completed; +gsm0808_create_ass_compl; gsm0808_create_assignment_failure; +gsm0808_create_ass_fail; gsm0808_create_cipher_complete; gsm0808_create_cipher_reject; gsm0808_create_classmark_update; @@ -134,6 +136,7 @@ gsm0808_create_clear_rqst; gsm0808_create_dtap; gsm0808_create_layer3; +gsm0808_create_layer3_aoip; gsm0808_create_reset; gsm0808_create_sapi_reject; gsm0808_prepend_dtap_header; diff --git a/tests/gsm0808/gsm0808_test.c b/tests/gsm0808/gsm0808_test.c index b22de9b..4a4a108 100644 --- a/tests/gsm0808/gsm0808_test.c +++ b/tests/gsm0808/gsm0808_test.c @@ -41,6 +41,29 @@ abort(); \ } +/* Setup a fake codec list for testing */ +static void setup_codec_list(struct gsm0808_speech_codec_list *scl) +{ + memset(scl, 0, sizeof(*scl)); + + scl->codec[0].pi = true; + scl->codec[0].tf = true; + scl->codec[0].type = 0xab; + scl->codec[0].type_extended = true; + scl->codec[0].cfg_present = true; + scl->codec[0].cfg = 0xcdef; + + scl->codec[1].fi = true; + scl->codec[1].pt = true; + scl->codec[1].type = 0x05; + + scl->codec[2].fi = true; + scl->codec[2].tf = true; + scl->codec[2].type = 0xf2; + scl->codec[2].type_extended = true; + + scl->len = 3; +} static void test_create_layer3(void) { @@ -56,6 +79,34 @@ msg = gsm0808_create_layer3(in_msg, 0x1122, 0x2244, 0x3366, 0x4488); VERIFY(msg, res, ARRAY_SIZE(res)); + msgb_free(msg); + msgb_free(in_msg); +} + +static void test_create_layer3_aoip() +{ + static const uint8_t res[] = { + 0x00, 0x17, 0x57, 0x05, 0x08, 0x00, 0x77, 0x62, + 0x83, 0x33, 0x66, 0x44, 0x88, 0x17, 0x01, 0x23, + GSM0808_IE_SPEECH_CODEC_LIST, 0x07, 0x5f, 0xab, 0xcd, 0xef, + 0xa5, 0x9f, 0xf2 + }; + + struct msgb *msg, *in_msg; + struct gsm0808_speech_codec_list sc_list; + printf("Testing creating Layer3 (AoIP)\n"); + + setup_codec_list(&sc_list); + + in_msg = msgb_alloc_headroom(512, 128, "foo"); + in_msg->l3h = in_msg->data; + msgb_v_put(in_msg, 0x23); + + msg = + gsm0808_create_layer3_aoip(in_msg, 0x1122, 0x2244, 0x3366, 0x4488, + &sc_list); + VERIFY(msg, res, ARRAY_SIZE(res)); + msgb_free(msg); msgb_free(in_msg); } @@ -189,6 +240,42 @@ msgb_free(msg); } +static void test_create_ass_compl_aoip() +{ + struct sockaddr_storage ss; + struct sockaddr_in sin; + struct gsm0808_speech_codec sc; + struct gsm0808_speech_codec_list sc_list; + static const uint8_t res[] = + { 0x00, 0x1d, 0x02, 0x15, 0x23, 0x21, 0x42, 0x2c, 0x11, 0x40, 0x22, + GSM0808_IE_AOIP_TRASP_ADDR, 0x06, 0xc0, 0xa8, 0x64, 0x17, 0x04, + 0xd2, GSM0808_IE_SPEECH_CODEC, 0x01, 0x9a, + GSM0808_IE_SPEECH_CODEC_LIST, 0x07, 0x5f, 0xab, 0xcd, 0xef, 0xa5, + 0x9f, 0xf2 }; + struct msgb *msg; + + memset(&sin, 0, sizeof(sin)); + sin.sin_family = AF_INET; + sin.sin_port = htons(1234); + inet_aton("192.168.100.23", &sin.sin_addr); + + memset(&ss, 0, sizeof(ss)); + memcpy(&ss, &sin, sizeof(sin)); + + memset(&sc, 0, sizeof(sc)); + sc.fi = true; + sc.tf = true; + sc.type = 0x0a; + + setup_codec_list(&sc_list); + + printf("Testing creating Assignment Complete (AoIP)\n"); + msg = gsm0808_create_ass_compl(0x23, 0x42, 0x11, 0x22, + &ss, &sc, &sc_list); + VERIFY(msg, res, ARRAY_SIZE(res)); + msgb_free(msg); +} + static void test_create_ass_fail() { static const uint8_t res1[] = { 0x00, 0x04, 0x03, 0x04, 0x01, 0x23 }; @@ -203,6 +290,31 @@ msgb_free(msg); msg = gsm0808_create_assignment_failure(0x23, &rr_res); + VERIFY(msg, res2, ARRAY_SIZE(res2)); + msgb_free(msg); +} + +static void test_create_ass_fail_aoip() +{ + static const uint8_t res1[] = + { 0x00, 0x0d, 0x03, 0x04, 0x01, 0x23, GSM0808_IE_SPEECH_CODEC_LIST, + 0x07, 0x5f, 0xab, 0xcd, 0xef, 0xa5, 0x9f, 0xf2 }; + static const uint8_t res2[] = + { 0x00, 0x0f, 0x03, 0x04, 0x01, 0x23, 0x15, 0x02, + GSM0808_IE_SPEECH_CODEC_LIST, 0x07, 0x5f, 0xab, + 0xcd, 0xef, 0xa5, 0x9f, 0xf2 }; + uint8_t rr_res = 2; + struct msgb *msg; + struct gsm0808_speech_codec_list sc_list; + + setup_codec_list(&sc_list); + + printf("Testing creating Assignment Failure (AoIP)\n"); + msg = gsm0808_create_ass_fail(0x23, NULL, &sc_list); + VERIFY(msg, res1, ARRAY_SIZE(res1)); + msgb_free(msg); + + msg = gsm0808_create_ass_fail(0x23, &rr_res, &sc_list); VERIFY(msg, res2, ARRAY_SIZE(res2)); msgb_free(msg); } @@ -433,6 +545,7 @@ { printf("Testing generation of GSM0808 messages\n"); test_create_layer3(); + test_create_layer3_aoip(); test_create_reset(); test_create_clear_command(); test_create_clear_complete(); @@ -441,7 +554,9 @@ test_create_cm_u(); test_create_sapi_reject(); test_create_ass_compl(); + test_create_ass_compl_aoip(); test_create_ass_fail(); + test_create_ass_fail_aoip(); test_create_clear_rqst(); test_create_dtap(); test_prepend_dtap(); diff --git a/tests/gsm0808/gsm0808_test.ok b/tests/gsm0808/gsm0808_test.ok index eb43126..f406551 100644 --- a/tests/gsm0808/gsm0808_test.ok +++ b/tests/gsm0808/gsm0808_test.ok @@ -1,5 +1,6 @@ Testing generation of GSM0808 messages Testing creating Layer3 +Testing creating Layer3 (AoIP) Testing creating Reset Testing creating Clear Command Testing creating Clear Complete @@ -8,7 +9,9 @@ Testing creating CM U Testing creating SAPI Reject Testing creating Assignment Complete +Testing creating Assignment Complete (AoIP) Testing creating Assignment Failure +Testing creating Assignment Failure (AoIP) Testing creating Clear Request Testing creating DTAP Testing prepend DTAP -- To view, visit https://gerrit.osmocom.org/2178 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I77f866abec1822d19871052f3c647ad782785b34 Gerrit-PatchSet: 6 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sat Apr 8 07:44:48 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 8 Apr 2017 07:44:48 +0000 Subject: [MERGED] libosmocore[master]: gsm0808: Add create functions for BSS_MAP_MSG_PAGING In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: gsm0808: Add create functions for BSS_MAP_MSG_PAGING ...................................................................... gsm0808: Add create functions for BSS_MAP_MSG_PAGING gsm0808.h/c lacks functionality to generate BSS_MAP_MSG_PAGING messages. These messages are required if the code is used in an MSC implementation. This commit adds a gsm0808_create_paging() function, that generates an A/AoiP BSS_MAP_MSG_PAGING message. Change-Id: I9afecf0109305ca5153bf081bb29cd94071dd2b7 --- M include/osmocom/gsm/gsm0808.h M src/gsm/gsm0808.c M src/gsm/libosmogsm.map M tests/gsm0808/gsm0808_test.c M tests/gsm0808/gsm0808_test.ok 5 files changed, 99 insertions(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/include/osmocom/gsm/gsm0808.h b/include/osmocom/gsm/gsm0808.h index 9738a55..990fd74 100644 --- a/include/osmocom/gsm/gsm0808.h +++ b/include/osmocom/gsm/gsm0808.h @@ -57,6 +57,9 @@ *scl); struct msgb *gsm0808_create_assignment_failure(uint8_t cause, uint8_t *rr_cause); struct msgb *gsm0808_create_clear_rqst(uint8_t cause); +struct msgb *gsm0808_create_paging(const char *imsi, const uint32_t *tmsi, + const struct gsm0808_cell_id_list *cil, + const uint8_t *chan_needed); struct msgb *gsm0808_create_dtap(struct msgb *msg, uint8_t link_id); void gsm0808_prepend_dtap_header(struct msgb *msg, uint8_t link_id); diff --git a/src/gsm/gsm0808.c b/src/gsm/gsm0808.c index c952a9f..2721a1b 100644 --- a/src/gsm/gsm0808.c +++ b/src/gsm/gsm0808.c @@ -347,6 +347,58 @@ return msg; } +struct msgb *gsm0808_create_paging(const char *imsi, const uint32_t *tmsi, + const struct gsm0808_cell_id_list *cil, + const uint8_t *chan_needed) +{ + struct msgb *msg; + uint8_t mid_buf[GSM48_MI_SIZE + 2]; + int mid_len; + uint32_t tmsi_sw; + + /* Mandatory emelents! */ + OSMO_ASSERT(imsi); + OSMO_ASSERT(cil); + + /* Malformed IMSI */ + OSMO_ASSERT(strlen(imsi) <= GSM48_MI_SIZE); + + msg = + msgb_alloc_headroom(BSSMAP_MSG_SIZE, BSSMAP_MSG_HEADROOM, "paging"); + if (!msg) + return NULL; + + /* Message Type 3.2.2.1 */ + msgb_v_put(msg, BSS_MAP_MSG_PAGING); + + /* IMSI 3.2.2.6 */ + mid_len = gsm48_generate_mid_from_imsi(mid_buf, imsi); + msgb_tlv_put(msg, GSM0808_IE_IMSI, mid_len - 2, mid_buf + 2); + + /* TMSI 3.2.2.7 */ + if (tmsi) { + tmsi_sw = htonl(*tmsi); + msgb_tlv_put(msg, GSM0808_IE_TMSI, sizeof(*tmsi), + (uint8_t *) & tmsi_sw); + } + + /* Cell Identifier List 3.2.2.27 */ + if (cil) + gsm0808_enc_cell_id_list(msg, cil); + + /* Channel Needed 3.2.2.36 */ + if (chan_needed) { + msgb_tv_put(msg, GSM0808_IE_CHANNEL_NEEDED, + (*chan_needed) & 0x03); + } + + /* pre-pend the header */ + msg->l3h = + msgb_tv_push(msg, BSSAP_MSG_BSS_MANAGEMENT, msgb_length(msg)); + + return msg; +} + void gsm0808_prepend_dtap_header(struct msgb *msg, uint8_t link_id) { uint8_t *hh = msgb_push(msg, 3); diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map index 786bf08..ec23418 100644 --- a/src/gsm/libosmogsm.map +++ b/src/gsm/libosmogsm.map @@ -135,6 +135,7 @@ gsm0808_create_clear_command; gsm0808_create_clear_complete; gsm0808_create_clear_rqst; +gsm0808_create_paging; gsm0808_create_dtap; gsm0808_create_layer3; gsm0808_create_layer3_aoip; diff --git a/tests/gsm0808/gsm0808_test.c b/tests/gsm0808/gsm0808_test.c index f33e0bd..b0dad7d 100644 --- a/tests/gsm0808/gsm0808_test.c +++ b/tests/gsm0808/gsm0808_test.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -367,6 +368,46 @@ printf("Testing creating Clear Request\n"); msg = gsm0808_create_clear_rqst(0x23); VERIFY(msg, res, ARRAY_SIZE(res)); + msgb_free(msg); +} + +static void test_create_paging() +{ + static const uint8_t res[] = + { 0x00, 0x10, 0x52, 0x08, 0x08, 0x09, 0x10, 0x10, 0x00, 0x00, 0x00, + 0x21, 0x43, 0x1a, 0x03, 0x05, 0x23, 0x42 }; + static const uint8_t res2[] = + { 0x00, 0x16, 0x52, 0x08, 0x08, 0x09, 0x10, 0x10, 0x00, 0x00, 0x00, + 0x21, 0x43, GSM0808_IE_TMSI, 0x04, 0x12, 0x34, 0x56, 0x78, 0x1a, + 0x03, 0x05, 0x23, 0x42 }; + static const uint8_t res3[] = + { 0x00, 0x18, 0x52, 0x08, 0x08, 0x09, 0x10, 0x10, 0x00, 0x00, 0x00, + 0x21, 0x43, GSM0808_IE_TMSI, 0x04, 0x12, 0x34, 0x56, 0x78, 0x1a, + 0x03, 0x05, 0x23, 0x42, GSM0808_IE_CHANNEL_NEEDED, + RSL_CHANNEED_TCH_ForH }; + + struct msgb *msg; + struct gsm0808_cell_id_list cil; + uint32_t tmsi = 0x12345678; + uint8_t chan_needed = RSL_CHANNEED_TCH_ForH; + + char imsi[] = "001010000001234"; + + cil.id_discr = CELL_IDENT_LAC; + cil.id_list_lac[0] = 0x2342; + cil.id_list_len = 1; + + printf("Testing creating Paging Request\n"); + msg = gsm0808_create_paging(imsi, NULL, &cil, NULL); + VERIFY(msg, res, ARRAY_SIZE(res)); + msgb_free(msg); + + msg = gsm0808_create_paging(imsi, &tmsi, &cil, NULL); + VERIFY(msg, res2, ARRAY_SIZE(res2)); + msgb_free(msg); + + msg = gsm0808_create_paging(imsi, &tmsi, &cil, &chan_needed); + VERIFY(msg, res3, ARRAY_SIZE(res3)); msgb_free(msg); } @@ -750,6 +791,7 @@ test_create_ass_fail(); test_create_ass_fail_aoip(); test_create_clear_rqst(); + test_create_paging(); test_create_dtap(); test_prepend_dtap(); test_enc_dec_aoip_trasp_addr_v4(); diff --git a/tests/gsm0808/gsm0808_test.ok b/tests/gsm0808/gsm0808_test.ok index 8e2087d..6170a7a 100644 --- a/tests/gsm0808/gsm0808_test.ok +++ b/tests/gsm0808/gsm0808_test.ok @@ -14,6 +14,7 @@ Testing creating Assignment Failure Testing creating Assignment Failure (AoIP) Testing creating Clear Request +Testing creating Paging Request Testing creating DTAP Testing prepend DTAP Done -- To view, visit https://gerrit.osmocom.org/2183 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I9afecf0109305ca5153bf081bb29cd94071dd2b7 Gerrit-PatchSet: 7 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sat Apr 8 07:44:49 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 8 Apr 2017 07:44:49 +0000 Subject: [MERGED] libosmocore[master]: gsm0808: Add create functions for BSS_MAP_MSG_ASSIGMENT_RQST In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: gsm0808: Add create functions for BSS_MAP_MSG_ASSIGMENT_RQST ...................................................................... gsm0808: Add create functions for BSS_MAP_MSG_ASSIGMENT_RQST gsm0808.h/c lacks functionality to generate BSS_MAP_MSG_ASSIGMENT_RQST messages. These messages are required if the code is used in an MSC implementation. This commit adds a gsm0808_create_assignment() function, that generates an A/AoiP BSS_MAP_MSG_PAGING message. Change-Id: I4d1d455a1e1cf95407e23ded7b7defbcf2dd6ff0 --- M include/osmocom/gsm/gsm0808.h M src/gsm/gsm0808.c M src/gsm/libosmogsm.map M tests/gsm0808/gsm0808_test.c M tests/gsm0808/gsm0808_test.ok 5 files changed, 113 insertions(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/include/osmocom/gsm/gsm0808.h b/include/osmocom/gsm/gsm0808.h index 990fd74..a9f610a 100644 --- a/include/osmocom/gsm/gsm0808.h +++ b/include/osmocom/gsm/gsm0808.h @@ -42,6 +42,11 @@ struct msgb *gsm0808_create_classmark_update(const uint8_t *cm2, uint8_t cm2_len, const uint8_t *cm3, uint8_t cm3_len); struct msgb *gsm0808_create_sapi_reject(uint8_t link_id); +struct msgb *gsm0808_create_ass(const struct gsm0808_channel_type *ct, + const uint16_t *cic, + const struct sockaddr_storage *ss, + const struct gsm0808_speech_codec_list *scl, + const uint32_t *ci); struct msgb *gsm0808_create_ass_compl(uint8_t rr_cause, uint8_t chosen_channel, uint8_t encr_alg_id, uint8_t speech_mode, const struct sockaddr_storage *ss, diff --git a/src/gsm/gsm0808.c b/src/gsm/gsm0808.c index 2721a1b..be58939 100644 --- a/src/gsm/gsm0808.c +++ b/src/gsm/gsm0808.c @@ -238,6 +238,62 @@ return msg; } +struct msgb *gsm0808_create_ass(const struct gsm0808_channel_type *ct, + const uint16_t *cic, + const struct sockaddr_storage *ss, + const struct gsm0808_speech_codec_list *scl, + const uint32_t *ci) +{ + /* See also: 3GPP TS 48.008 3.2.1.1 ASSIGNMENT REQUEST */ + struct msgb *msg; + uint16_t cic_sw; + uint32_t ci_sw; + + /* Mandatory emelent! */ + OSMO_ASSERT(ct); + + msg = + msgb_alloc_headroom(BSSMAP_MSG_SIZE, BSSMAP_MSG_HEADROOM, + "bssmap: ass req"); + if (!msg) + return NULL; + + /* Message Type 3.2.2.1 */ + msgb_v_put(msg, BSS_MAP_MSG_ASSIGMENT_RQST); + + /* Channel Type 3.2.2.11 */ + gsm0808_enc_channel_type(msg, ct); + + /* Circuit Identity Code 3.2.2.2 */ + if (cic) { + cic_sw = htons(*cic); + msgb_tv_fixed_put(msg, GSM0808_IE_CIRCUIT_IDENTITY_CODE, + sizeof(cic_sw), (uint8_t *) & cic_sw); + } + + /* AoIP: AoIP Transport Layer Address (MGW) 3.2.2.102 */ + if (ss) { + gsm0808_enc_aoip_trasp_addr(msg, ss); + } + + /* AoIP: Codec List (MSC Preferred) 3.2.2.103 */ + if (scl) + gsm0808_enc_speech_codec_list(msg, scl); + + /* AoIP: Call Identifier 3.2.2.105 */ + if (ci) { + ci_sw = htonl(*ci); + msgb_tv_fixed_put(msg, GSM0808_IE_CALL_ID, sizeof(ci_sw), + (uint8_t *) & ci_sw); + } + + /* push the bssmap header */ + msg->l3h = + msgb_tv_push(msg, BSSAP_MSG_BSS_MANAGEMENT, msgb_length(msg)); + + return msg; +} + struct msgb *gsm0808_create_ass_compl(uint8_t rr_cause, uint8_t chosen_channel, uint8_t encr_alg_id, uint8_t speech_mode, const struct sockaddr_storage *ss, diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map index ec23418..a4e6083 100644 --- a/src/gsm/libosmogsm.map +++ b/src/gsm/libosmogsm.map @@ -124,6 +124,7 @@ gsm0808_att_tlvdef; gsm0808_bssap_name; gsm0808_bssmap_name; +gsm0808_create_ass; gsm0808_create_assignment_completed; gsm0808_create_ass_compl; gsm0808_create_assignment_failure; diff --git a/tests/gsm0808/gsm0808_test.c b/tests/gsm0808/gsm0808_test.c index b0dad7d..a0ff6d5 100644 --- a/tests/gsm0808/gsm0808_test.c +++ b/tests/gsm0808/gsm0808_test.c @@ -262,6 +262,55 @@ msgb_free(msg); } +static void test_create_ass() +{ + static const uint8_t res1[] = + { 0x00, 0x0a, 0x01, 0x0b, 0x04, 0x01, 0x0b, 0xa1, 0x25, 0x01, 0x00, + 0x04 }; + static const uint8_t res2[] = + { 0x00, 0x20, 0x01, 0x0b, 0x04, 0x01, 0x0b, 0xa1, 0x25, 0x01, 0x00, + 0x04, GSM0808_IE_AOIP_TRASP_ADDR, 0x06, 0xc0, 0xa8, 0x64, 0x17, + 0x04, 0xd2, GSM0808_IE_SPEECH_CODEC_LIST, 0x07, 0x5f, 0xab, 0xcd, + 0xef, 0xa5, 0x9f, 0xf2, GSM0808_IE_CALL_ID, 0xaa, 0xbb, 0xcc, + 0xdd }; + + struct msgb *msg; + struct gsm0808_channel_type ct; + uint16_t cic = 0004; + struct sockaddr_storage ss; + struct sockaddr_in sin; + struct gsm0808_speech_codec_list sc_list; + uint32_t call_id = 0xAABBCCDD; + + memset(&ct, 0, sizeof(ct)); + ct.ch_indctr = GSM0808_CHAN_SPEECH; + ct.ch_rate_type = GSM0808_SPEECH_HALF_PREF; + ct.perm_spch[0] = GSM0808_PERM_FR3; + ct.perm_spch[1] = GSM0808_PERM_HR3; + ct.perm_spch_len = 2; + + memset(&sin, 0, sizeof(sin)); + sin.sin_family = AF_INET; + sin.sin_port = htons(1234); + inet_aton("192.168.100.23", &sin.sin_addr); + + memset(&ss, 0, sizeof(ss)); + memcpy(&ss, &sin, sizeof(sin)); + + setup_codec_list(&sc_list); + + printf("Testing creating Assignment Request\n"); + msg = gsm0808_create_ass(&ct, &cic, NULL, NULL, NULL); + OSMO_ASSERT(msg); + VERIFY(msg, res1, ARRAY_SIZE(res1)); + msgb_free(msg); + + msg = gsm0808_create_ass(&ct, &cic, &ss, &sc_list, &call_id); + OSMO_ASSERT(msg); + VERIFY(msg, res2, ARRAY_SIZE(res2)); + msgb_free(msg); +} + static void test_create_ass_compl() { static const uint8_t res1[] = { @@ -786,6 +835,7 @@ test_create_cipher_reject(); test_create_cm_u(); test_create_sapi_reject(); + test_create_ass(); test_create_ass_compl(); test_create_ass_compl_aoip(); test_create_ass_fail(); diff --git a/tests/gsm0808/gsm0808_test.ok b/tests/gsm0808/gsm0808_test.ok index 6170a7a..52af134 100644 --- a/tests/gsm0808/gsm0808_test.ok +++ b/tests/gsm0808/gsm0808_test.ok @@ -9,6 +9,7 @@ Testing creating Cipher Reject Testing creating CM U Testing creating SAPI Reject +Testing creating Assignment Request Testing creating Assignment Complete Testing creating Assignment Complete (AoIP) Testing creating Assignment Failure -- To view, visit https://gerrit.osmocom.org/2184 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I4d1d455a1e1cf95407e23ded7b7defbcf2dd6ff0 Gerrit-PatchSet: 7 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sat Apr 8 07:44:49 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 8 Apr 2017 07:44:49 +0000 Subject: [MERGED] libosmocore[master]: gsm0808: Add utils for Cell Identifier List In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: gsm0808: Add utils for Cell Identifier List ...................................................................... gsm0808: Add utils for Cell Identifier List The planned support for true A over IP requires the encoding of the a Cell Identifier List element (see also BSS_MAP_MSG_PAGING). This commt adds encoding/decoding functionality and tests for the element mentioned above, however, it is not yet actively used. Change-Id: I625245dd1dd396fc2bc189e8cd2c444a33042528 --- M include/osmocom/gsm/gsm0808_utils.h M include/osmocom/gsm/protocol/gsm_08_08.h M src/gsm/gsm0808_utils.c M src/gsm/libosmogsm.map M tests/gsm0808/gsm0808_test.c 5 files changed, 181 insertions(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/include/osmocom/gsm/gsm0808_utils.h b/include/osmocom/gsm/gsm0808_utils.h index 5bd27c7..e6e55a7 100644 --- a/include/osmocom/gsm/gsm0808_utils.h +++ b/include/osmocom/gsm/gsm0808_utils.h @@ -63,3 +63,11 @@ /* Decode Encryption Information element */ int gsm0808_dec_encrypt_info(struct gsm0808_encrypt_info *ei, const uint8_t *elem, uint8_t len); + +/* Encode Cell Identifier List element */ +uint8_t gsm0808_enc_cell_id_list(struct msgb *msg, + const struct gsm0808_cell_id_list *cil); + +/* Decode Cell Identifier List element */ +int gsm0808_dec_cell_id_list(struct gsm0808_cell_id_list *cil, + const uint8_t *elem, uint8_t len); diff --git a/include/osmocom/gsm/protocol/gsm_08_08.h b/include/osmocom/gsm/protocol/gsm_08_08.h index 3939aed..e5e7e1e 100644 --- a/include/osmocom/gsm/protocol/gsm_08_08.h +++ b/include/osmocom/gsm/protocol/gsm_08_08.h @@ -457,3 +457,11 @@ uint8_t key[ENCRY_INFO_KEY_MAXLEN]; unsigned int key_len; }; + +/* 3GPP TS 48.008 3.2.2.27 Cell Identifier List */ +#define CELL_ID_LIST_LAC_MAXLEN 127 +struct gsm0808_cell_id_list { + uint8_t id_discr; + uint16_t id_list_lac[CELL_ID_LIST_LAC_MAXLEN]; + unsigned int id_list_len; +}; diff --git a/src/gsm/gsm0808_utils.c b/src/gsm/gsm0808_utils.c index 1915605..054372a 100644 --- a/src/gsm/gsm0808_utils.c +++ b/src/gsm/gsm0808_utils.c @@ -450,3 +450,81 @@ return (int)(elem - old_elem); } + +/* Encode Cell Identifier List element */ +uint8_t gsm0808_enc_cell_id_list(struct msgb *msg, + const struct gsm0808_cell_id_list *cil) +{ + uint8_t *old_tail; + uint8_t *tlv_len; + unsigned int i; + + OSMO_ASSERT(msg); + OSMO_ASSERT(cil); + + msgb_put_u8(msg, GSM0808_IE_CELL_IDENTIFIER_LIST); + tlv_len = msgb_put(msg, 1); + old_tail = msg->tail; + + msgb_put_u8(msg, cil->id_discr & 0x0f); + + switch (cil->id_discr) { + case CELL_IDENT_LAC: + OSMO_ASSERT(cil->id_list_len <= CELL_ID_LIST_LAC_MAXLEN) + for (i=0;iid_list_len;i++) { + msgb_put_u16(msg, cil->id_list_lac[i]); + } + break; + case CELL_IDENT_BSS: + /* Does not have any list items */ + break; + default: + /* FIXME: Implement support for all identifier list elements */ + OSMO_ASSERT(false); + } + + *tlv_len = (uint8_t) (msg->tail - old_tail); + return *tlv_len + 2; +} + +/* Decode Cell Identifier List element */ +int gsm0808_dec_cell_id_list(struct gsm0808_cell_id_list *cil, + const uint8_t *elem, uint8_t len) +{ + uint8_t id_discr; + const uint8_t *old_elem = elem; + unsigned int item_count = 0; + + OSMO_ASSERT(cil); + if (!elem) + return -EINVAL; + if (len <= 0) + return -EINVAL; + + memset(cil, 0, sizeof(*cil)); + + id_discr = *elem & 0x0f; + elem++; + len--; + + cil->id_discr = id_discr; + + switch (id_discr) { + case CELL_IDENT_LAC: + while (len >= 2) { + cil->id_list_lac[item_count] = osmo_load16be(elem); + elem += 2; + item_count++; + len -= 2; + } + case CELL_IDENT_BSS: + /* Does not have any list items */ + break; + default: + /* FIXME: Implement support for all identifier list elements */ + return -EINVAL; + } + + cil->id_list_len = item_count; + return (int)(elem - old_elem); +} diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map index 323ad5a..cf0a7fe 100644 --- a/src/gsm/libosmogsm.map +++ b/src/gsm/libosmogsm.map @@ -150,6 +150,8 @@ gsm0808_dec_channel_type; gsm0808_enc_encrypt_info; gsm0808_dec_encrypt_info; +gsm0808_enc_cell_id_list; +gsm0808_dec_cell_id_list; gsm0858_rsl_ul_meas_enc; diff --git a/tests/gsm0808/gsm0808_test.c b/tests/gsm0808/gsm0808_test.c index 5fe9c87..af457b4 100644 --- a/tests/gsm0808/gsm0808_test.c +++ b/tests/gsm0808/gsm0808_test.c @@ -610,6 +610,88 @@ msgb_free(msg); } +static void test_gsm0808_enc_dec_cell_id_list_lac() +{ + struct gsm0808_cell_id_list enc_cil; + struct gsm0808_cell_id_list dec_cil; + struct msgb *msg; + uint8_t rc_enc; + int rc_dec; + + memset(&enc_cil, 0, sizeof(enc_cil)); + enc_cil.id_discr = CELL_IDENT_LAC; + enc_cil.id_list_lac[0] = 0x0124; + enc_cil.id_list_lac[1] = 0xABCD; + enc_cil.id_list_lac[2] = 0x5678; + enc_cil.id_list_len = 3; + + msg = msgb_alloc(1024, "output buffer"); + rc_enc = gsm0808_enc_cell_id_list(msg, &enc_cil); + OSMO_ASSERT(rc_enc == 9); + + rc_dec = gsm0808_dec_cell_id_list(&dec_cil, msg->data + 2, + msg->len - 2); + OSMO_ASSERT(rc_dec == 7); + + OSMO_ASSERT(memcmp(&enc_cil, &dec_cil, sizeof(enc_cil)) == 0); + + msgb_free(msg); +} + +static void test_gsm0808_enc_dec_cell_id_list_single_lac() +{ + struct gsm0808_cell_id_list enc_cil; + struct gsm0808_cell_id_list dec_cil; + struct msgb *msg; + uint8_t cil_enc_expected[] = { GSM0808_IE_CELL_IDENTIFIER_LIST, 0x03, + 0x05, 0x23, 0x42 + }; + uint8_t rc_enc; + int rc_dec; + + memset(&enc_cil, 0, sizeof(enc_cil)); + enc_cil.id_discr = CELL_IDENT_LAC; + enc_cil.id_list_lac[0] = 0x2342; + enc_cil.id_list_len = 1; + + msg = msgb_alloc(1024, "output buffer"); + rc_enc = gsm0808_enc_cell_id_list(msg, &enc_cil); + OSMO_ASSERT(rc_enc == 5); + OSMO_ASSERT(memcmp(cil_enc_expected, msg->data, msg->len) == 0); + + rc_dec = gsm0808_dec_cell_id_list(&dec_cil, msg->data + 2, + msg->len - 2); + OSMO_ASSERT(rc_dec == 3); + + OSMO_ASSERT(memcmp(&enc_cil, &dec_cil, sizeof(enc_cil)) == 0); + + msgb_free(msg); +} + +static void test_gsm0808_enc_dec_cell_id_list_bss() +{ + struct gsm0808_cell_id_list enc_cil; + struct gsm0808_cell_id_list dec_cil; + struct msgb *msg; + uint8_t rc_enc; + int rc_dec; + + memset(&enc_cil, 0, sizeof(enc_cil)); + enc_cil.id_discr = CELL_IDENT_LAC; + + msg = msgb_alloc(1024, "output buffer"); + rc_enc = gsm0808_enc_cell_id_list(msg, &enc_cil); + OSMO_ASSERT(rc_enc == 3); + + rc_dec = gsm0808_dec_cell_id_list(&dec_cil, msg->data + 2, + msg->len - 2); + OSMO_ASSERT(rc_dec == 1); + + OSMO_ASSERT(memcmp(&enc_cil, &dec_cil, sizeof(enc_cil)) == 0); + + msgb_free(msg); +} + int main(int argc, char **argv) { printf("Testing generation of GSM0808 messages\n"); @@ -637,6 +719,9 @@ test_gsm0808_enc_dec_speech_codec_list(); test_gsm0808_enc_dec_channel_type(); test_gsm0808_enc_dec_encrypt_info(); + test_gsm0808_enc_dec_cell_id_list_lac(); + test_gsm0808_enc_dec_cell_id_list_single_lac(); + test_gsm0808_enc_dec_cell_id_list_bss(); printf("Done\n"); return EXIT_SUCCESS; -- To view, visit https://gerrit.osmocom.org/2181 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I625245dd1dd396fc2bc189e8cd2c444a33042528 Gerrit-PatchSet: 6 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sat Apr 8 07:44:49 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 8 Apr 2017 07:44:49 +0000 Subject: [MERGED] libosmocore[master]: gsm0808: Add utils for Encryption Information In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: gsm0808: Add utils for Encryption Information ...................................................................... gsm0808: Add utils for Encryption Information The planned support for true A over IP requires the encoding of the an Encryption Information element (see also BSS_MAP_MSG_CIPHER_MODE_CMD). This commt adds encoding/decoding functionality and tests for the element mentioned above, however, it is not yet actively used. Change-Id: I8262050a9d9fd3f17462cfbb046c6e034dccc6fb --- M include/osmocom/gsm/gsm0808_utils.h M include/osmocom/gsm/protocol/gsm_08_08.h M src/gsm/gsm0808_utils.c M src/gsm/libosmogsm.map M tests/gsm0808/gsm0808_test.c 5 files changed, 131 insertions(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/include/osmocom/gsm/gsm0808_utils.h b/include/osmocom/gsm/gsm0808_utils.h index 48e737d..5bd27c7 100644 --- a/include/osmocom/gsm/gsm0808_utils.h +++ b/include/osmocom/gsm/gsm0808_utils.h @@ -55,3 +55,11 @@ /* Decode Channel Type element */ int gsm0808_dec_channel_type(struct gsm0808_channel_type *ct, const uint8_t *elem, uint8_t len); + +/* Encode Encryption Information element */ +uint8_t gsm0808_enc_encrypt_info(struct msgb *msg, + const struct gsm0808_encrypt_info *ei); + +/* Decode Encryption Information element */ +int gsm0808_dec_encrypt_info(struct gsm0808_encrypt_info *ei, + const uint8_t *elem, uint8_t len); diff --git a/include/osmocom/gsm/protocol/gsm_08_08.h b/include/osmocom/gsm/protocol/gsm_08_08.h index e2355f6..3939aed 100644 --- a/include/osmocom/gsm/protocol/gsm_08_08.h +++ b/include/osmocom/gsm/protocol/gsm_08_08.h @@ -447,3 +447,13 @@ uint8_t perm_spch[CH_TYPE_PERM_SPCH_MAXLEN]; unsigned int perm_spch_len; }; + +/* 3GPP TS 48.008 3.2.2.10 Encryption Information */ +#define ENCRY_INFO_KEY_MAXLEN 252 +#define ENCRY_INFO_PERM_ALGO_MAXLEN 8 +struct gsm0808_encrypt_info { + uint8_t perm_algo[ENCRY_INFO_PERM_ALGO_MAXLEN]; + unsigned int perm_algo_len; + uint8_t key[ENCRY_INFO_KEY_MAXLEN]; + unsigned int key_len; +}; diff --git a/src/gsm/gsm0808_utils.c b/src/gsm/gsm0808_utils.c index ef0f943..1915605 100644 --- a/src/gsm/gsm0808_utils.c +++ b/src/gsm/gsm0808_utils.c @@ -33,6 +33,7 @@ #define CHANNEL_TYPE_ELEMENT_MAXLEN 11 #define CHANNEL_TYPE_ELEMENT_MINLEN 3 +#define ENCRYPT_INFO_ELEMENT_MINLEN 1 /* Encode AoIP transport address element */ uint8_t gsm0808_enc_aoip_trasp_addr(struct msgb *msg, @@ -379,3 +380,73 @@ return (int)(elem - old_elem); } + +/* Encode Encryption Information element */ +uint8_t gsm0808_enc_encrypt_info(struct msgb *msg, + const struct gsm0808_encrypt_info *ei) +{ + unsigned int i; + uint8_t perm_algo = 0; + uint8_t *ptr; + uint8_t *old_tail; + uint8_t *tlv_len; + + OSMO_ASSERT(msg); + OSMO_ASSERT(ei); + OSMO_ASSERT(ei->key_len <= ARRAY_SIZE(ei->key)); + OSMO_ASSERT(ei->perm_algo_len <= ENCRY_INFO_PERM_ALGO_MAXLEN); + + msgb_put_u8(msg, GSM0808_IE_ENCRYPTION_INFORMATION); + tlv_len = msgb_put(msg, 1); + old_tail = msg->tail; + + for (i = 0; i < ei->perm_algo_len; i++) { + /* Note: gsm_08_08.h defines the permitted algorithms + * as an enum which ranges from 0x01 to 0x08 */ + OSMO_ASSERT(ei->perm_algo[i] != 0); + OSMO_ASSERT(ei->perm_algo[i] <= ENCRY_INFO_PERM_ALGO_MAXLEN); + perm_algo |= (1 << (ei->perm_algo[i] - 1)); + } + + msgb_put_u8(msg, perm_algo); + ptr = msgb_put(msg, ei->key_len); + memcpy(ptr, ei->key, ei->key_len); + + *tlv_len = (uint8_t) (msg->tail - old_tail); + return *tlv_len + 2; +} + +/* Decode Encryption Information element */ +int gsm0808_dec_encrypt_info(struct gsm0808_encrypt_info *ei, + const uint8_t *elem, uint8_t len) +{ + uint8_t perm_algo; + unsigned int i; + unsigned int perm_algo_len = 0; + const uint8_t *old_elem = elem; + + OSMO_ASSERT(ei); + if (!elem) + return -EINVAL; + if (len <= 0) + return -EINVAL; + + memset(ei, 0, sizeof(*ei)); + + perm_algo = *elem; + elem++; + + for (i = 0; i < ENCRY_INFO_PERM_ALGO_MAXLEN; i++) { + if (perm_algo & (1 << i)) { + ei->perm_algo[perm_algo_len] = i + 1; + perm_algo_len++; + } + } + ei->perm_algo_len = perm_algo_len; + + ei->key_len = len - 1; + memcpy(ei->key, elem, ei->key_len); + elem+=ei->key_len; + + return (int)(elem - old_elem); +} diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map index 2ba0c42..323ad5a 100644 --- a/src/gsm/libosmogsm.map +++ b/src/gsm/libosmogsm.map @@ -148,6 +148,8 @@ gsm0808_dec_speech_codec_list; gsm0808_enc_channel_type; gsm0808_dec_channel_type; +gsm0808_enc_encrypt_info; +gsm0808_dec_encrypt_info; gsm0858_rsl_ul_meas_enc; diff --git a/tests/gsm0808/gsm0808_test.c b/tests/gsm0808/gsm0808_test.c index 0dd9e84..5fe9c87 100644 --- a/tests/gsm0808/gsm0808_test.c +++ b/tests/gsm0808/gsm0808_test.c @@ -571,6 +571,45 @@ msgb_free(msg); } +static void test_gsm0808_enc_dec_encrypt_info() +{ + struct gsm0808_encrypt_info enc_ei; + struct gsm0808_encrypt_info dec_ei; + struct msgb *msg; + uint8_t ei_enc_expected[] = + { GSM0808_IE_ENCRYPTION_INFORMATION, 0x09, 0x03, 0xaa, 0xbb, + 0xcc, 0xdd, 0xee, 0xff, 0x23, 0x42 + }; + uint8_t rc_enc; + int rc_dec; + + memset(&enc_ei, 0, sizeof(enc_ei)); + enc_ei.perm_algo[0] = GSM0808_ALG_ID_A5_0; + enc_ei.perm_algo[1] = GSM0808_ALG_ID_A5_1; + enc_ei.perm_algo_len = 2; + enc_ei.key[0] = 0xaa; + enc_ei.key[1] = 0xbb; + enc_ei.key[2] = 0xcc; + enc_ei.key[3] = 0xdd; + enc_ei.key[4] = 0xee; + enc_ei.key[5] = 0xff; + enc_ei.key[6] = 0x23; + enc_ei.key[7] = 0x42; + enc_ei.key_len = 8; + + msg = msgb_alloc(1024, "output buffer"); + rc_enc = gsm0808_enc_encrypt_info(msg, &enc_ei); + OSMO_ASSERT(rc_enc == 11); + OSMO_ASSERT(memcmp(ei_enc_expected, msg->data, msg->len) == 0); + + rc_dec = gsm0808_dec_encrypt_info(&dec_ei, msg->data + 2, msg->len - 2); + OSMO_ASSERT(rc_dec == 9); + + OSMO_ASSERT(memcmp(&enc_ei, &dec_ei, sizeof(enc_ei)) == 0); + + msgb_free(msg); +} + int main(int argc, char **argv) { printf("Testing generation of GSM0808 messages\n"); @@ -597,6 +636,7 @@ test_gsm0808_enc_dec_speech_codec_ext_with_cfg(); test_gsm0808_enc_dec_speech_codec_list(); test_gsm0808_enc_dec_channel_type(); + test_gsm0808_enc_dec_encrypt_info(); printf("Done\n"); return EXIT_SUCCESS; -- To view, visit https://gerrit.osmocom.org/2180 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I8262050a9d9fd3f17462cfbb046c6e034dccc6fb Gerrit-PatchSet: 6 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sat Apr 8 07:44:50 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 8 Apr 2017 07:44:50 +0000 Subject: [MERGED] libosmocore[master]: gsm0808: Add utils for Channel Type In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: gsm0808: Add utils for Channel Type ...................................................................... gsm0808: Add utils for Channel Type The planned support for true A over IP requires the encoding of the a Channel Type element (see also ASSIGNMENT REQUEST). This commt adds encoding/decoding functionality and tests for the element mentioned above, however, it is not yet actively used. Change-Id: Id0e2164d84b8cbcc6fe6a090fc7f40a1251421d7 --- M include/osmocom/gsm/gsm0808_utils.h M include/osmocom/gsm/protocol/gsm_08_08.h M src/gsm/gsm0808_utils.c M src/gsm/libosmogsm.map M tests/gsm0808/gsm0808_test.c 5 files changed, 123 insertions(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/include/osmocom/gsm/gsm0808_utils.h b/include/osmocom/gsm/gsm0808_utils.h index b5ddbdb..48e737d 100644 --- a/include/osmocom/gsm/gsm0808_utils.h +++ b/include/osmocom/gsm/gsm0808_utils.h @@ -47,3 +47,11 @@ /* Decode Speech Codec list */ int gsm0808_dec_speech_codec_list(struct gsm0808_speech_codec_list *scl, const uint8_t *elem, uint8_t len); + +/* Encode Channel Type element */ +uint8_t gsm0808_enc_channel_type(struct msgb *msg, + const struct gsm0808_channel_type *ct); + +/* Decode Channel Type element */ +int gsm0808_dec_channel_type(struct gsm0808_channel_type *ct, + const uint8_t *elem, uint8_t len); diff --git a/include/osmocom/gsm/protocol/gsm_08_08.h b/include/osmocom/gsm/protocol/gsm_08_08.h index 3e5514d..e2355f6 100644 --- a/include/osmocom/gsm/protocol/gsm_08_08.h +++ b/include/osmocom/gsm/protocol/gsm_08_08.h @@ -438,3 +438,12 @@ struct gsm0808_speech_codec codec[SPEECH_CODEC_MAXLEN]; uint8_t len; }; + +/* 3GPP TS 48.008 3.2.2.11 Channel Type */ +#define CH_TYPE_PERM_SPCH_MAXLEN 9 +struct gsm0808_channel_type { + uint8_t ch_indctr; + uint8_t ch_rate_type; + uint8_t perm_spch[CH_TYPE_PERM_SPCH_MAXLEN]; + unsigned int perm_spch_len; +}; diff --git a/src/gsm/gsm0808_utils.c b/src/gsm/gsm0808_utils.c index eef6146..ef0f943 100644 --- a/src/gsm/gsm0808_utils.c +++ b/src/gsm/gsm0808_utils.c @@ -31,6 +31,8 @@ #define IP_V6_ADDR_LEN 16 #define IP_PORT_LEN 2 +#define CHANNEL_TYPE_ELEMENT_MAXLEN 11 +#define CHANNEL_TYPE_ELEMENT_MINLEN 3 /* Encode AoIP transport address element */ uint8_t gsm0808_enc_aoip_trasp_addr(struct msgb *msg, @@ -306,3 +308,74 @@ return (int)(elem - old_elem); } + +/* Encode Channel Type element */ +uint8_t gsm0808_enc_channel_type(struct msgb *msg, + const struct gsm0808_channel_type *ct) +{ + unsigned int i; + uint8_t byte; + uint8_t *old_tail; + uint8_t *tlv_len; + + OSMO_ASSERT(msg); + OSMO_ASSERT(ct); + OSMO_ASSERT(ct->perm_spch_len <= CHANNEL_TYPE_ELEMENT_MAXLEN - 2); + + /* FIXME: Implement encoding support for Data + * and Speech + CTM Text Telephony */ + if ((ct->ch_indctr & 0x0f) != GSM0808_CHAN_SPEECH + && (ct->ch_indctr & 0x0f) != GSM0808_CHAN_SIGN) + OSMO_ASSERT(false); + + msgb_put_u8(msg, GSM0808_IE_CHANNEL_TYPE); + tlv_len = msgb_put(msg, 1); + old_tail = msg->tail; + + msgb_put_u8(msg, ct->ch_indctr & 0x0f); + msgb_put_u8(msg, ct->ch_rate_type); + + for (i = 0; i < ct->perm_spch_len; i++) { + byte = ct->perm_spch[i]; + + if (i < ct->perm_spch_len - 1) + byte |= 0x80; + msgb_put_u8(msg, byte); + } + + *tlv_len = (uint8_t) (msg->tail - old_tail); + return *tlv_len + 2; +} + +/* Decode Channel Type element */ +int gsm0808_dec_channel_type(struct gsm0808_channel_type *ct, + const uint8_t *elem, uint8_t len) +{ + unsigned int i; + uint8_t byte; + const uint8_t *old_elem = elem; + + OSMO_ASSERT(ct); + if (!elem) + return -EINVAL; + if (len <= 0) + return -EINVAL; + + memset(ct, 0, sizeof(*ct)); + + ct->ch_indctr = (*elem) & 0x0f; + elem++; + ct->ch_rate_type = (*elem) & 0x0f; + elem++; + + for (i = 0; i < ARRAY_SIZE(ct->perm_spch); i++) { + byte = *elem; + elem++; + ct->perm_spch[i] = byte & 0x7f; + if ((byte & 0x80) == 0x00) + break; + } + ct->perm_spch_len = i + 1; + + return (int)(elem - old_elem); +} diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map index 518a5aa..2ba0c42 100644 --- a/src/gsm/libosmogsm.map +++ b/src/gsm/libosmogsm.map @@ -146,6 +146,8 @@ gsm0808_dec_speech_codec; gsm0808_enc_speech_codec_list; gsm0808_dec_speech_codec_list; +gsm0808_enc_channel_type; +gsm0808_dec_channel_type; gsm0858_rsl_ul_meas_enc; diff --git a/tests/gsm0808/gsm0808_test.c b/tests/gsm0808/gsm0808_test.c index 4a4a108..0dd9e84 100644 --- a/tests/gsm0808/gsm0808_test.c +++ b/tests/gsm0808/gsm0808_test.c @@ -541,6 +541,36 @@ msgb_free(msg); } +static void test_gsm0808_enc_dec_channel_type() +{ + struct gsm0808_channel_type enc_ct; + struct gsm0808_channel_type dec_ct; + struct msgb *msg; + uint8_t ct_enc_expected[] = { GSM0808_IE_CHANNEL_TYPE, + 0x04, 0x01, 0x0b, 0xa1, 0x25 + }; + uint8_t rc_enc; + int rc_dec; + + memset(&enc_ct, 0, sizeof(enc_ct)); + enc_ct.ch_indctr = GSM0808_CHAN_SPEECH; + enc_ct.ch_rate_type = GSM0808_SPEECH_HALF_PREF; + enc_ct.perm_spch[0] = GSM0808_PERM_FR3; + enc_ct.perm_spch[1] = GSM0808_PERM_HR3; + enc_ct.perm_spch_len = 2; + + msg = msgb_alloc(1024, "output buffer"); + rc_enc = gsm0808_enc_channel_type(msg, &enc_ct); + OSMO_ASSERT(rc_enc == 6); + OSMO_ASSERT(memcmp(ct_enc_expected, msg->data, msg->len) == 0); + + rc_dec = gsm0808_dec_channel_type(&dec_ct, msg->data + 2, msg->len - 2); + OSMO_ASSERT(rc_dec == 4); + OSMO_ASSERT(memcmp(&enc_ct, &dec_ct, sizeof(enc_ct)) == 0); + + msgb_free(msg); +} + int main(int argc, char **argv) { printf("Testing generation of GSM0808 messages\n"); @@ -566,6 +596,7 @@ test_gsm0808_enc_dec_speech_codec_ext(); test_gsm0808_enc_dec_speech_codec_ext_with_cfg(); test_gsm0808_enc_dec_speech_codec_list(); + test_gsm0808_enc_dec_channel_type(); printf("Done\n"); return EXIT_SUCCESS; -- To view, visit https://gerrit.osmocom.org/2179 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Id0e2164d84b8cbcc6fe6a090fc7f40a1251421d7 Gerrit-PatchSet: 6 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sat Apr 8 07:44:50 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 8 Apr 2017 07:44:50 +0000 Subject: [MERGED] libosmocore[master]: gsm0808: Add utils for Speech Codec List and Speech Codec In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: gsm0808: Add utils for Speech Codec List and Speech Codec ...................................................................... gsm0808: Add utils for Speech Codec List and Speech Codec The planned support for true A over IP requires the encoding and decoding of a so called "Speech Codec Element" element. This commt adds parsing functionality and tests for the element mentioned above, however, it is not yet actively used. Change-Id: I0e1e2edf47adaa45b22d4b0bcae3640dba7ca200 --- M include/osmocom/gsm/gsm0808_utils.h M include/osmocom/gsm/protocol/gsm_08_08.h M src/gsm/gsm0808_utils.c M src/gsm/libosmogsm.map M tests/gsm0808/gsm0808_test.c 5 files changed, 355 insertions(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/include/osmocom/gsm/gsm0808_utils.h b/include/osmocom/gsm/gsm0808_utils.h index 5fc1c88..b5ddbdb 100644 --- a/include/osmocom/gsm/gsm0808_utils.h +++ b/include/osmocom/gsm/gsm0808_utils.h @@ -21,6 +21,8 @@ #include +#include + /* Encode AoIP transport address element */ uint8_t gsm0808_enc_aoip_trasp_addr(struct msgb *msg, const struct sockaddr_storage *ss); @@ -28,3 +30,20 @@ /* Decode AoIP transport address element */ int gsm0808_dec_aoip_trasp_addr(struct sockaddr_storage *ss, const uint8_t *elem, uint8_t len); + +/* Encode Speech Codec element */ +uint8_t gsm0808_enc_speech_codec(struct msgb *msg, + const struct gsm0808_speech_codec *sc); + +/* Decode Speech Codec element */ +int gsm0808_dec_speech_codec(struct gsm0808_speech_codec *sc, + const uint8_t *elem, uint8_t len); + +/* Encode Speech Codec list */ +uint8_t gsm0808_enc_speech_codec_list(struct msgb *msg, + const struct gsm0808_speech_codec_list + *scl); + +/* Decode Speech Codec list */ +int gsm0808_dec_speech_codec_list(struct gsm0808_speech_codec_list *scl, + const uint8_t *elem, uint8_t len); diff --git a/include/osmocom/gsm/protocol/gsm_08_08.h b/include/osmocom/gsm/protocol/gsm_08_08.h index 6fb4e9e..3e5514d 100644 --- a/include/osmocom/gsm/protocol/gsm_08_08.h +++ b/include/osmocom/gsm/protocol/gsm_08_08.h @@ -3,6 +3,9 @@ #pragma once #include +#include +#include +#include /* * this is from GSM 03.03 CGI but is copied in GSM 08.08 @@ -416,3 +419,22 @@ GSM0808_PAGINF_FOR_SMS = 0x01, GSM0808_PAGINF_FOR_USSD = 0x02, }; + +/* 3GPP TS 48.008 3.2.2.104 Speech Codec */ +struct gsm0808_speech_codec { + bool fi; + bool pi; + bool pt; + bool tf; + uint8_t type; + uint16_t cfg; + bool type_extended; + bool cfg_present; +}; + +/* 3GPP TS 48.008 3.2.2.103 Speech Codec List */ +#define SPEECH_CODEC_MAXLEN 255 +struct gsm0808_speech_codec_list { + struct gsm0808_speech_codec codec[SPEECH_CODEC_MAXLEN]; + uint8_t len; +}; diff --git a/src/gsm/gsm0808_utils.c b/src/gsm/gsm0808_utils.c index df24e2b..eef6146 100644 --- a/src/gsm/gsm0808_utils.c +++ b/src/gsm/gsm0808_utils.c @@ -31,6 +31,7 @@ #define IP_V6_ADDR_LEN 16 #define IP_PORT_LEN 2 + /* Encode AoIP transport address element */ uint8_t gsm0808_enc_aoip_trasp_addr(struct msgb *msg, const struct sockaddr_storage *ss) @@ -120,3 +121,188 @@ return (int)(elem - old_elem); } + +/* Helper function for gsm0808_enc_speech_codec() + * and gsm0808_enc_speech_codec_list() */ +static uint8_t enc_speech_codec(struct msgb *msg, + const struct gsm0808_speech_codec *sc) +{ + /* See also 3GPP TS 48.008 3.2.2.103 Speech Codec List */ + uint8_t header = 0; + uint8_t *old_tail; + + old_tail = msg->tail; + + if (sc->fi) + header |= (1 << 7); + if (sc->pi) + header |= (1 << 6); + if (sc->pt) + header |= (1 << 5); + if (sc->tf) + header |= (1 << 4); + if (sc->type_extended) { + header |= 0x0f; + msgb_put_u8(msg, header); + } else { + OSMO_ASSERT(sc->type < 0x0f); + header |= sc->type; + msgb_put_u8(msg, header); + return (uint8_t) (msg->tail - old_tail); + } + + msgb_put_u8(msg, sc->type); + + if (sc->cfg_present) + msgb_put_u16(msg, sc->cfg); + + return (uint8_t) (msg->tail - old_tail); +} + +/* Encode Speech Codec element */ +uint8_t gsm0808_enc_speech_codec(struct msgb *msg, + const struct gsm0808_speech_codec *sc) +{ + uint8_t *old_tail; + uint8_t *tlv_len; + + OSMO_ASSERT(msg); + OSMO_ASSERT(sc); + + msgb_put_u8(msg, GSM0808_IE_SPEECH_CODEC); + tlv_len = msgb_put(msg, 1); + old_tail = msg->tail; + + enc_speech_codec(msg, sc); + + *tlv_len = (uint8_t) (msg->tail - old_tail); + return *tlv_len + 2; +} + +/* Decode Speech Codec element */ +int gsm0808_dec_speech_codec(struct gsm0808_speech_codec *sc, + const uint8_t *elem, uint8_t len) +{ + /* See also 3GPP TS 48.008 3.2.2.103 Speech Codec List */ + uint8_t header; + const uint8_t *old_elem = elem; + + OSMO_ASSERT(sc); + if (!elem) + return -EINVAL; + if (len <= 0) + return -EINVAL; + + memset(sc, 0, sizeof(*sc)); + + header = *elem; + + /* Malformed elements */ + if ((header & 0x0F) == 0x0F && len < 2) + return -EINVAL; + else if ((header & 0x0F) != 0x0F && len < 1) + return -EINVAL; + + elem++; + len--; + + if (header & (1 << 7)) + sc->fi = true; + if (header & (1 << 6)) + sc->pi = true; + if (header & (1 << 5)) + sc->pt = true; + if (header & (1 << 4)) + sc->tf = true; + + if ((header & 0x0F) != 0x0F) { + sc->type = (header & 0x0F); + return (int)(elem - old_elem); + } + + sc->type = *elem; + elem++; + len--; + + sc->type_extended = true; + + if (len < 2) + return (int)(elem - old_elem); + + sc->cfg = osmo_load16be(elem); + elem += 2; + sc->cfg_present = true; + + return (int)(elem - old_elem); +} + +/* Encode Speech Codec list */ +uint8_t gsm0808_enc_speech_codec_list(struct msgb *msg, + const struct gsm0808_speech_codec_list *scl) +{ + uint8_t *old_tail; + uint8_t *tlv_len; + unsigned int i; + uint8_t rc; + unsigned int bytes_used = 0; + + OSMO_ASSERT(msg); + OSMO_ASSERT(scl); + + /* Empty list */ + OSMO_ASSERT(scl->len >= 1); + + msgb_put_u8(msg, GSM0808_IE_SPEECH_CODEC_LIST); + tlv_len = msgb_put(msg, 1); + old_tail = msg->tail; + + for (i = 0; i < scl->len; i++) { + rc = enc_speech_codec(msg, &scl->codec[i]); + OSMO_ASSERT(rc >= 1); + bytes_used += rc; + OSMO_ASSERT(bytes_used <= 255); + } + + *tlv_len = (uint8_t) (msg->tail - old_tail); + return *tlv_len + 2; +} + +/* Decode Speech Codec list */ +int gsm0808_dec_speech_codec_list(struct gsm0808_speech_codec_list *scl, + const uint8_t *elem, uint8_t len) +{ + const uint8_t *old_elem = elem; + unsigned int i; + int rc; + uint8_t decoded = 0; + + OSMO_ASSERT(scl); + if (!elem) + return -EINVAL; + if (len <= 0) + return -EINVAL; + + memset(scl, 0, sizeof(*scl)); + + for (i = 0; i < ARRAY_SIZE(scl->codec); i++) { + if (len <= 0) + break; + + rc = gsm0808_dec_speech_codec(&scl->codec[i], elem, len); + if (rc < 1) + return -EINVAL; + + elem+=rc; + len -= rc; + decoded++; + } + + scl->len = decoded; + + /* Empty list */ + if (decoded < 1) { + return -EINVAL; + } + + return (int)(elem - old_elem); +} diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map index 3ad847d..c89cbe4 100644 --- a/src/gsm/libosmogsm.map +++ b/src/gsm/libosmogsm.map @@ -139,6 +139,10 @@ gsm0808_prepend_dtap_header; gsm0808_enc_aoip_trasp_addr; gsm0808_dec_aoip_trasp_addr; +gsm0808_enc_speech_codec; +gsm0808_dec_speech_codec; +gsm0808_enc_speech_codec_list; +gsm0808_dec_speech_codec_list; gsm0858_rsl_ul_meas_enc; diff --git a/tests/gsm0808/gsm0808_test.c b/tests/gsm0808/gsm0808_test.c index 26bd1d6..b22de9b 100644 --- a/tests/gsm0808/gsm0808_test.c +++ b/tests/gsm0808/gsm0808_test.c @@ -309,6 +309,126 @@ msgb_free(msg); } +static void test_gsm0808_enc_dec_speech_codec() +{ + struct gsm0808_speech_codec enc_sc; + struct gsm0808_speech_codec dec_sc; + struct msgb *msg; + uint8_t rc_enc; + int rc_dec; + + memset(&enc_sc, 0, sizeof(enc_sc)); + enc_sc.fi = true; + enc_sc.pt = true; + enc_sc.type = 0x05; + + msg = msgb_alloc(1024, "output buffer"); + rc_enc = gsm0808_enc_speech_codec(msg, &enc_sc); + OSMO_ASSERT(rc_enc == 3); + + rc_dec = gsm0808_dec_speech_codec(&dec_sc, msg->data + 2, msg->len - 2); + OSMO_ASSERT(rc_dec == 1); + + OSMO_ASSERT(memcmp(&enc_sc, &dec_sc, sizeof(enc_sc)) == 0); + + msgb_free(msg); +} + + +static void test_gsm0808_enc_dec_speech_codec_ext_with_cfg() +{ + struct gsm0808_speech_codec enc_sc; + struct gsm0808_speech_codec dec_sc; + struct msgb *msg; + uint8_t rc_enc; + int rc_dec; + + enc_sc.pi = true; + enc_sc.tf = true; + enc_sc.type = 0xab; + enc_sc.type_extended = true; + enc_sc.cfg_present = true; + enc_sc.cfg = 0xcdef; + + msg = msgb_alloc(1024, "output buffer"); + rc_enc = gsm0808_enc_speech_codec(msg, &enc_sc); + OSMO_ASSERT(rc_enc == 6); + + rc_dec = gsm0808_dec_speech_codec(&dec_sc, msg->data + 2, msg->len - 2); + OSMO_ASSERT(rc_dec == 4); + + OSMO_ASSERT(memcmp(&enc_sc, &dec_sc, sizeof(enc_sc)) == 0); + + msgb_free(msg); +} + +static void test_gsm0808_enc_dec_speech_codec_ext() +{ + struct gsm0808_speech_codec enc_sc; + struct gsm0808_speech_codec dec_sc; + struct msgb *msg; + uint8_t rc_enc; + int rc_dec; + + enc_sc.fi = true; + enc_sc.tf = true; + enc_sc.type = 0xf2; + enc_sc.type_extended = true; + enc_sc.cfg_present = false; + enc_sc.cfg = 0x0000; + + msg = msgb_alloc(1024, "output buffer"); + rc_enc = gsm0808_enc_speech_codec(msg, &enc_sc); + OSMO_ASSERT(rc_enc == 4); + + rc_dec = gsm0808_dec_speech_codec(&dec_sc, msg->data + 2, msg->len - 2); + OSMO_ASSERT(rc_dec == 2); + + OSMO_ASSERT(memcmp(&enc_sc, &dec_sc, sizeof(enc_sc)) == 0); + + msgb_free(msg); +} + +static void test_gsm0808_enc_dec_speech_codec_list() +{ + struct gsm0808_speech_codec_list enc_scl; + struct gsm0808_speech_codec_list dec_scl; + struct msgb *msg; + uint8_t rc_enc; + int rc_dec; + + memset(&enc_scl, 0, sizeof(enc_scl)); + + enc_scl.codec[0].pi = true; + enc_scl.codec[0].tf = true; + enc_scl.codec[0].type = 0xab; + enc_scl.codec[0].type_extended = true; + enc_scl.codec[0].cfg_present = true; + enc_scl.codec[0].cfg = 0xcdef; + + enc_scl.codec[1].fi = true; + enc_scl.codec[1].pt = true; + enc_scl.codec[1].type = 0x05; + + enc_scl.codec[2].fi = true; + enc_scl.codec[2].tf = true; + enc_scl.codec[2].type = 0xf2; + enc_scl.codec[2].type_extended = true; + + enc_scl.len = 3; + + msg = msgb_alloc(1024, "output buffer"); + rc_enc = gsm0808_enc_speech_codec_list(msg, &enc_scl); + OSMO_ASSERT(rc_enc == 9); + + rc_dec = gsm0808_dec_speech_codec_list(&dec_scl, msg->data + 2, msg->len - 2); + OSMO_ASSERT(rc_dec == 7); + + OSMO_ASSERT(memcmp(&enc_scl, &dec_scl, sizeof(enc_scl)) == 0); + + msgb_free(msg); +} + int main(int argc, char **argv) { printf("Testing generation of GSM0808 messages\n"); @@ -327,6 +447,10 @@ test_prepend_dtap(); test_enc_dec_aoip_trasp_addr_v4(); test_enc_dec_aoip_trasp_addr_v6(); + test_gsm0808_enc_dec_speech_codec(); + test_gsm0808_enc_dec_speech_codec_ext(); + test_gsm0808_enc_dec_speech_codec_ext_with_cfg(); + test_gsm0808_enc_dec_speech_codec_list(); printf("Done\n"); return EXIT_SUCCESS; -- To view, visit https://gerrit.osmocom.org/2177 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I0e1e2edf47adaa45b22d4b0bcae3640dba7ca200 Gerrit-PatchSet: 5 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sat Apr 8 07:44:51 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 8 Apr 2017 07:44:51 +0000 Subject: [MERGED] libosmocore[master]: gsm0808: Add utils for AoIP Transport Layer Address In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: gsm0808: Add utils for AoIP Transport Layer Address ...................................................................... gsm0808: Add utils for AoIP Transport Layer Address The planned support for true A over IP requires the encoding and decoding of a so called "AoIP Transport Layer Address" element. This commt adds parsing functionality and tests for the element mentioned above, however, it is not yet actively used. Change-Id: I57933b0a06a3f54ec2a41e6ecb6ced9fbbc89332 --- M include/Makefile.am A include/osmocom/gsm/gsm0808_utils.h M src/gsm/Makefile.am A src/gsm/gsm0808_utils.c M src/gsm/libosmogsm.map M tests/gsm0808/gsm0808_test.c 6 files changed, 220 insertions(+), 1 deletion(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/include/Makefile.am b/include/Makefile.am index e2a1b12..0383d7a 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -77,6 +77,7 @@ osmocom/coding/gsm0503_interleaving.h \ osmocom/coding/gsm0503_coding.h \ osmocom/gsm/gsm0808.h \ + osmocom/gsm/gsm0808_utils.h \ osmocom/gsm/gsm23003.h \ osmocom/gsm/gsm48.h \ osmocom/gsm/gsm48_ie.h \ diff --git a/include/osmocom/gsm/gsm0808_utils.h b/include/osmocom/gsm/gsm0808_utils.h new file mode 100644 index 0000000..5fc1c88 --- /dev/null +++ b/include/osmocom/gsm/gsm0808_utils.h @@ -0,0 +1,30 @@ +/* (C) 2016 by Sysmocom s.f.m.c. GmbH + * All Rights Reserved + * + * Author: Philipp Maier + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#include + +/* Encode AoIP transport address element */ +uint8_t gsm0808_enc_aoip_trasp_addr(struct msgb *msg, + const struct sockaddr_storage *ss); + +/* Decode AoIP transport address element */ +int gsm0808_dec_aoip_trasp_addr(struct sockaddr_storage *ss, + const uint8_t *elem, uint8_t len); diff --git a/src/gsm/Makefile.am b/src/gsm/Makefile.am index 3a4a0cd..e64c9e7 100644 --- a/src/gsm/Makefile.am +++ b/src/gsm/Makefile.am @@ -25,7 +25,7 @@ auth_milenage.c milenage/aes-encblock.c gea.c \ milenage/aes-internal.c milenage/aes-internal-enc.c \ milenage/milenage.c gan.c ipa.c gsm0341.c apn.c \ - gsup.c gprs_gea.c gsm0503_conv.c oap.c + gsup.c gprs_gea.c gsm0503_conv.c oap.c gsm0808_utils.c libgsmint_la_LDFLAGS = -no-undefined libgsmint_la_LIBADD = $(top_builddir)/src/libosmocore.la diff --git a/src/gsm/gsm0808_utils.c b/src/gsm/gsm0808_utils.c new file mode 100644 index 0000000..df24e2b --- /dev/null +++ b/src/gsm/gsm0808_utils.c @@ -0,0 +1,122 @@ +/* (C) 2016 by Sysmocom s.f.m.c. GmbH + * All Rights Reserved + * + * Author: Philipp Maier + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define IP_V4_ADDR_LEN 4 +#define IP_V6_ADDR_LEN 16 +#define IP_PORT_LEN 2 + +/* Encode AoIP transport address element */ +uint8_t gsm0808_enc_aoip_trasp_addr(struct msgb *msg, + const struct sockaddr_storage *ss) +{ + /* See also 3GPP TS 48.008 3.2.2.102 AoIP Transport Layer Address */ + struct sockaddr_in *sin; + struct sockaddr_in6 *sin6; + uint16_t port = 0; + uint8_t *ptr; + uint8_t *old_tail; + uint8_t *tlv_len; + + OSMO_ASSERT(msg); + OSMO_ASSERT(ss); + OSMO_ASSERT(ss->ss_family == AF_INET || ss->ss_family == AF_INET6); + + msgb_put_u8(msg, GSM0808_IE_AOIP_TRASP_ADDR); + tlv_len = msgb_put(msg,1); + old_tail = msg->tail; + + switch (ss->ss_family) { + case AF_INET: + sin = (struct sockaddr_in *)ss; + port = ntohs(sin->sin_port); + ptr = msgb_put(msg, IP_V4_ADDR_LEN); + memcpy(ptr, &sin->sin_addr.s_addr, IP_V4_ADDR_LEN); + break; + case AF_INET6: + sin6 = (struct sockaddr_in6 *)ss; + port = ntohs(sin6->sin6_port); + ptr = msgb_put(msg, IP_V6_ADDR_LEN); + memcpy(ptr, sin6->sin6_addr.s6_addr, IP_V6_ADDR_LEN); + break; + } + + msgb_put_u16(msg, port); + + *tlv_len = (uint8_t) (msg->tail - old_tail); + return *tlv_len + 2; +} + +/* Decode AoIP transport address element */ +int gsm0808_dec_aoip_trasp_addr(struct sockaddr_storage *ss, + const uint8_t *elem, uint8_t len) +{ + /* See also 3GPP TS 48.008 3.2.2.102 AoIP Transport Layer Address */ + struct sockaddr_in sin; + struct sockaddr_in6 sin6; + const uint8_t *old_elem = elem; + + OSMO_ASSERT(ss); + if (!elem) + return -EINVAL; + if (len <= 0) + return -EINVAL; + + memset(ss, 0, sizeof(*ss)); + + switch (len) { + case IP_V4_ADDR_LEN + IP_PORT_LEN: + memset(&sin, 0, sizeof(sin)); + sin.sin_family = AF_INET; + + memcpy(&sin.sin_addr.s_addr, elem, IP_V4_ADDR_LEN); + elem += IP_V4_ADDR_LEN; + sin.sin_port = osmo_load16le(elem); + elem += IP_PORT_LEN; + + memcpy(ss, &sin, sizeof(sin)); + break; + case IP_V6_ADDR_LEN + IP_PORT_LEN: + memset(&sin6, 0, sizeof(sin6)); + sin6.sin6_family = AF_INET6; + + memcpy(sin6.sin6_addr.s6_addr, elem, IP_V6_ADDR_LEN); + elem += IP_V6_ADDR_LEN; + sin6.sin6_port = osmo_load16le(elem); + elem += IP_PORT_LEN; + + memcpy(ss, &sin6, sizeof(sin6)); + break; + default: + /* Malformed element! */ + return -EINVAL; + break; + } + + return (int)(elem - old_elem); +} diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map index 5649e71..3ad847d 100644 --- a/src/gsm/libosmogsm.map +++ b/src/gsm/libosmogsm.map @@ -137,6 +137,8 @@ gsm0808_create_reset; gsm0808_create_sapi_reject; gsm0808_prepend_dtap_header; +gsm0808_enc_aoip_trasp_addr; +gsm0808_dec_aoip_trasp_addr; gsm0858_rsl_ul_meas_enc; diff --git a/tests/gsm0808/gsm0808_test.c b/tests/gsm0808/gsm0808_test.c index 98502b7..26bd1d6 100644 --- a/tests/gsm0808/gsm0808_test.c +++ b/tests/gsm0808/gsm0808_test.c @@ -19,9 +19,14 @@ */ #include +#include +#include #include #include +#include +#include +#include #define VERIFY(msg, data, len) \ if (msgb_l3len(msg) != len) { \ @@ -247,6 +252,63 @@ msgb_free(in_msg); } +static void test_enc_dec_aoip_trasp_addr_v4() +{ + struct sockaddr_storage enc_addr; + struct sockaddr_storage dec_addr; + struct sockaddr_in enc_addr_in; + struct msgb *msg; + uint8_t rc_enc; + int rc_dec; + + memset(&enc_addr_in, 0, sizeof(enc_addr_in)); + enc_addr_in.sin_family = AF_INET; + enc_addr_in.sin_port = htons(1234); + inet_aton("255.0.255.255", &enc_addr_in.sin_addr); + + memset(&enc_addr, 0, sizeof(enc_addr)); + memcpy(&enc_addr, &enc_addr_in, sizeof(enc_addr_in)); + + msg = msgb_alloc(1024, "output buffer"); + rc_enc = gsm0808_enc_aoip_trasp_addr(msg, &enc_addr); + OSMO_ASSERT(rc_enc == 8); + rc_dec = + gsm0808_dec_aoip_trasp_addr(&dec_addr, msg->data + 2, msg->len - 2); + OSMO_ASSERT(rc_dec == 6); + OSMO_ASSERT(memcmp(&enc_addr, &dec_addr, sizeof(enc_addr)) == 0); + + msgb_free(msg); +} + +static void test_enc_dec_aoip_trasp_addr_v6() +{ + struct sockaddr_storage enc_addr; + struct sockaddr_storage dec_addr; + struct sockaddr_in6 enc_addr_in; + struct msgb *msg; + uint8_t rc_enc; + int rc_dec; + + memset(&enc_addr_in, 0, sizeof(enc_addr_in)); + enc_addr_in.sin6_family = AF_INET6; + enc_addr_in.sin6_port = htons(4567); + inet_pton(AF_INET6, "2001:0db8:85a3:08d3:1319:8a2e:0370:7344", + &enc_addr_in.sin6_addr); + + memset(&enc_addr, 0, sizeof(enc_addr)); + memcpy(&enc_addr, &enc_addr_in, sizeof(enc_addr_in)); + + msg = msgb_alloc(1024, "output buffer"); + rc_enc = gsm0808_enc_aoip_trasp_addr(msg, &enc_addr); + OSMO_ASSERT(rc_enc == 20); + rc_dec = + gsm0808_dec_aoip_trasp_addr(&dec_addr, msg->data + 2, msg->len - 2); + OSMO_ASSERT(rc_dec == 18); + OSMO_ASSERT(memcmp(&enc_addr, &dec_addr, sizeof(enc_addr)) == 0); + + msgb_free(msg); +} + int main(int argc, char **argv) { printf("Testing generation of GSM0808 messages\n"); @@ -263,6 +325,8 @@ test_create_clear_rqst(); test_create_dtap(); test_prepend_dtap(); + test_enc_dec_aoip_trasp_addr_v4(); + test_enc_dec_aoip_trasp_addr_v6(); printf("Done\n"); return EXIT_SUCCESS; -- To view, visit https://gerrit.osmocom.org/2176 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I57933b0a06a3f54ec2a41e6ecb6ced9fbbc89332 Gerrit-PatchSet: 5 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sat Apr 8 07:45:14 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 8 Apr 2017 07:45:14 +0000 Subject: [MERGED] libosmocore[master]: compiler warnings: take care of compiler warning "unused-res... In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: compiler warnings: take care of compiler warning "unused-result" ...................................................................... compiler warnings: take care of compiler warning "unused-result" Though it makes no sense to handle the return code of freopen() here, the compiler complains about it. The #pragma statements take care of that. Change-Id: Ia2caadbed2a24f84d1d55a47236b398b74224e82 --- M src/application.c 1 file changed, 7 insertions(+), 0 deletions(-) Approvals: Jenkins Builder: Verified Holger Freyther: Looks good to me, approved diff --git a/src/application.c b/src/application.c index 4112e75..6a18d0e 100644 --- a/src/application.c +++ b/src/application.c @@ -156,9 +156,16 @@ /* Redirect stdio to /dev/null */ /* since C89/C99 says stderr is a macro, we can safely do this! */ #ifdef stderr +/* + * it does not make sense to check the return code here, so we just + * ignore the compiler warning from gcc + */ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-result" freopen("/dev/null", "r", stdin); freopen("/dev/null", "w", stdout); freopen("/dev/null", "w", stderr); +#pragma GCC diagnostic pop #endif return 0; -- To view, visit https://gerrit.osmocom.org/2045 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ia2caadbed2a24f84d1d55a47236b398b74224e82 Gerrit-PatchSet: 2 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Thorsten Alteholz Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sat Apr 8 07:45:51 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 8 Apr 2017 07:45:51 +0000 Subject: openbsc[master]: abis: log known ACKs and unknown messages In-Reply-To: References: Message-ID: Patch Set 4: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2227 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Id3afaaa76e24f63076ae0e6fd2322e4a7fa29b45 Gerrit-PatchSet: 4 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sat Apr 8 07:46:09 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 8 Apr 2017 07:46:09 +0000 Subject: [MERGED] openbsc[master]: abis: log known ACKs and unknown messages In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: abis: log known ACKs and unknown messages ...................................................................... abis: log known ACKs and unknown messages Log expected ACK messages and unhandled messages to aid in troubleshooting. Change-Id: Id3afaaa76e24f63076ae0e6fd2322e4a7fa29b45 Related: OS#1614 --- M openbsc/src/libbsc/abis_nm.c 1 file changed, 18 insertions(+), 1 deletion(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/openbsc/src/libbsc/abis_nm.c b/openbsc/src/libbsc/abis_nm.c index 33a23a2..651ca02 100644 --- a/openbsc/src/libbsc/abis_nm.c +++ b/openbsc/src/libbsc/abis_nm.c @@ -694,8 +694,21 @@ case NM_MT_BS11_LMT_SESSION: ret = abis_nm_rx_lmt_event(mb); break; + case NM_MT_OPSTART_ACK: + abis_nm_debugp_foh(DNM, foh); + DEBUGPC(DNM, "Opstart ACK\n"); + break; + case NM_MT_SET_CHAN_ATTR_ACK: + abis_nm_debugp_foh(DNM, foh); + DEBUGPC(DNM, "Set Channel Attributes ACK\n"); + break; + case NM_MT_SET_RADIO_ATTR_ACK: + abis_nm_debugp_foh(DNM, foh); + DEBUGPC(DNM, "Set Radio Carrier Attributes ACK\n"); + break; case NM_MT_CONN_MDROP_LINK_ACK: - DEBUGP(DNM, "CONN MDROP LINK ACK\n"); + abis_nm_debugp_foh(DNM, foh); + DEBUGPC(DNM, "CONN MDROP LINK ACK\n"); break; case NM_MT_IPACC_RESTART_ACK: osmo_signal_dispatch(SS_NM, S_NM_IPACC_RESTART_ACK, NULL); @@ -705,6 +718,10 @@ break; case NM_MT_SET_BTS_ATTR_ACK: break; + default: + abis_nm_debugp_foh(DNM, foh); + LOGPC(DNM, LOGL_ERROR, "Unhandled message %s\n", + get_value_string(abis_nm_msgtype_names, mt)); } abis_nm_queue_send_next(bts); -- To view, visit https://gerrit.osmocom.org/2227 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Id3afaaa76e24f63076ae0e6fd2322e4a7fa29b45 Gerrit-PatchSet: 5 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sat Apr 8 07:47:12 2017 From: gerrit-no-reply at lists.osmocom.org (Vadim Yanitskiy) Date: Sat, 8 Apr 2017 07:47:12 +0000 Subject: libosmocore[master]: core/conv: implement optimized Viterbi decoder In-Reply-To: References: Message-ID: Patch Set 6: Thanks everyone for review! I'll be happy to see this one merged. There are also some patches, written by Tom and related to Viterbi, so I'll take care of them. -- To view, visit https://gerrit.osmocom.org/1337 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I74d355274b4176a7d924f91ef3c96912ce338fb2 Gerrit-PatchSet: 6 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Vadim Yanitskiy Gerrit-Reviewer: Alexander Chemeris Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Tom Tsou Gerrit-Reviewer: Vadim Yanitskiy Gerrit-Reviewer: tnt Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sat Apr 8 18:13:31 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 8 Apr 2017 18:13:31 +0000 Subject: [PATCH] libosmo-netif[master]: Add minimal doxygen documentation for stream + datagram modules Message-ID: Review at https://gerrit.osmocom.org/2248 Add minimal doxygen documentation for stream + datagram modules We should have doxygen documentation for all libosmo-* APIs. libosmo-netif is currently devoid of any API docs. Let's start with the stream and datagram socket related functions. Change-Id: I589a5e60d9df2b8a65fbaf68f80e3ae0039d8c2a --- M .gitignore A Doxyfile.in M Makefile.am M configure.ac M include/osmocom/netif/stream.h M src/datagram.c M src/stream.c 7 files changed, 2,018 insertions(+), 4 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-netif refs/changes/48/2248/1 diff --git a/.gitignore b/.gitignore index aa38852..2d582bd 100644 --- a/.gitignore +++ b/.gitignore @@ -49,3 +49,5 @@ examples/rtp-udp-test-server examples/stream-client examples/stream-server + +Doxyfile diff --git a/Doxyfile.in b/Doxyfile.in new file mode 100644 index 0000000..3843f79 --- /dev/null +++ b/Doxyfile.in @@ -0,0 +1,1716 @@ +# Doxyfile 1.7.4 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project. +# +# All text after a hash (#) is considered a comment and will be ignored. +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" "). + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See +# http://www.gnu.org/software/libiconv for the list of possible encodings. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = libosmo-netif + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = @VERSION@ + +# Using the PROJECT_BRIEF tag one can provide an optional one line description +# for a project that appears at the top of each page and should give viewer +# a quick idea about the purpose of the project. Keep the description short. + +PROJECT_BRIEF = "Osmocom network interface library" + +# With the PROJECT_LOGO tag one can specify an logo or icon that is +# included in the documentation. The maximum height of the logo should not +# exceed 55 pixels and the maximum width should not exceed 200 pixels. +# Doxygen will copy the logo to the output directory. + +PROJECT_LOGO = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = doc + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, +# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, +# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English +# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, +# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, +# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = YES + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful if your file system +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like regular Qt-style comments +# (thus requiring an explicit @brief command for a brief description.) + +JAVADOC_AUTOBRIEF = NO + +# If the QT_AUTOBRIEF tag is set to YES then Doxygen will +# interpret the first line (until the first dot) of a Qt-style +# comment as the brief description. If set to NO, the comments +# will behave just like regular Qt-style comments (thus requiring +# an explicit \brief command for a brief description.) + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 8 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = YES + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for +# Java. For instance, namespaces will be presented as packages, qualified +# scopes will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources only. Doxygen will then generate output that is more tailored for +# Fortran. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for +# VHDL. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Doxygen selects the parser to use depending on the extension of the files it +# parses. With this tag you can assign which parser to use for a given extension. +# Doxygen has a built-in mapping, but you can override or extend it using this +# tag. The format is ext=language, where ext is a file extension, and language +# is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C, +# C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make +# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C +# (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions +# you also need to set FILE_PATTERNS otherwise the files are not read by doxygen. + +EXTENSION_MAPPING = + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also makes the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. +# Doxygen will parse them like normal C++ but will assume all classes use public +# instead of private inheritance when no explicit protection keyword is present. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate getter +# and setter methods for a property. Setting this option to YES (the default) +# will make doxygen replace the get and set methods by a property in the +# documentation. This will only work if the methods are indeed getting or +# setting a simple type. If this is not the case, or you want to show the +# methods anyway, you should set this option to NO. + +IDL_PROPERTY_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and +# unions are shown inside the group in which they are included (e.g. using +# @ingroup) instead of on a separate page (for HTML and Man pages) or +# section (for LaTeX and RTF). + +INLINE_GROUPED_CLASSES = NO + +# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum +# is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically +# be useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. + +TYPEDEF_HIDES_STRUCT = NO + +# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to +# determine which symbols to keep in memory and which to flush to disk. +# When the cache is full, less often used symbols will be written to disk. +# For small to medium size projects (<1000 input files) the default value is +# probably good enough. For larger projects a too small cache size can cause +# doxygen to be busy swapping symbols to and from disk most of the time +# causing a significant performance penalty. +# If the system has enough physical memory increasing the cache will improve the +# performance by keeping more symbols in memory. Note that the value works on +# a logarithmic scale so increasing the size by one will roughly double the +# memory usage. The cache size is given by this formula: +# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, +# corresponding to a cache size of 2^16 = 65536 symbols + +SYMBOL_CACHE_SIZE = 0 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = NO + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = YES + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base +# name of the file that contains the anonymous namespace. By default +# anonymous namespaces are hidden. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen +# will list include files with double quotes in the documentation +# rather than with sharp brackets. + +FORCE_LOCAL_INCLUDES = NO + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen +# will sort the (brief and detailed) documentation of class members so that +# constructors and destructors are listed first. If set to NO (the default) +# the constructors will appear in the respective orders defined by +# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. +# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO +# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. + +SORT_MEMBERS_CTORS_1ST = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the +# hierarchy of group names into alphabetical order. If set to NO (the default) +# the group names will appear in their defined order. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to +# do proper type resolution of all parameters of a function it will reject a +# match between the prototype and the implementation of a member function even +# if there is only one candidate or it is obvious which candidate to choose +# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen +# will still accept a match between prototype and implementation in such cases. + +STRICT_PROTO_MATCHING = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or macro consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and macros in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# If the sources in your project are distributed over multiple directories +# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy +# in the documentation. The default is NO. + +SHOW_DIRECTORIES = NO + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. +# This will remove the Files entry from the Quick Index and from the +# Folder Tree View (if specified). The default is YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the +# Namespaces page. +# This will remove the Namespaces entry from the Quick Index +# and from the Folder Tree View (if specified). The default is YES. + +SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the program writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed +# by doxygen. The layout file controls the global structure of the generated +# output files in an output format independent way. The create the layout file +# that represents doxygen's defaults, run doxygen with the -l option. +# You can optionally specify a file name after the option, if omitted +# DoxygenLayout.xml will be used as the name of the layout file. + +LAYOUT_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# The WARN_NO_PARAMDOC option can be enabled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = @srcdir@/include/osmocom/netif @srcdir@/src + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is +# also the default input encoding. Doxygen uses libiconv (or the iconv built +# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for +# the list of possible encodings. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh +# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py +# *.f90 *.f *.for *.vhd *.vhdl + +FILE_PATTERNS = + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = NO + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or +# directories that are symbolic links (a Unix file system feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +# IMAGE_PATH = images/ + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. +# If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. +# Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. +# The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty or if +# non of the patterns match the file name, INPUT_FILTER is applied. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file +# pattern. A pattern will override the setting for FILTER_PATTERN (if any) +# and it is also possible to disable source filtering for a specific pattern +# using *.ext= (so without naming a filter). This option only has effect when +# FILTER_SOURCE_FILES is enabled. + +FILTER_SOURCE_PATTERNS = + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = YES + +# If the REFERENCES_RELATION tag is set to YES +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = YES + +# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) +# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from +# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will +# link to the source code. +# Otherwise they will link to the documentation. + +REFERENCES_LINK_SOURCE = YES + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = NO + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. Note that when using a custom header you are responsible +# for the proper inclusion of any scripts and style sheets that doxygen +# needs, which is dependent on the configuration options used. +# It is adviced to generate a default header using "doxygen -w html +# header.html footer.html stylesheet.css YourConfigFile" and then modify +# that header. Note that the header is subject to change so you typically +# have to redo this when upgrading to a newer version of doxygen or when changing the value of configuration settings such as GENERATE_TREEVIEW! + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# stylesheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = + +# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the HTML output directory. Note +# that these files will be copied to the base HTML output directory. Use the +# $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these +# files. In the HTML_STYLESHEET file, use the file name only. Also note that +# the files will be copied as-is; there are no commands or markers available. + +HTML_EXTRA_FILES = + +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. +# Doxygen will adjust the colors in the stylesheet and background images +# according to this color. Hue is specified as an angle on a colorwheel, +# see http://en.wikipedia.org/wiki/Hue for more information. +# For instance the value 0 represents red, 60 is yellow, 120 is green, +# 180 is cyan, 240 is blue, 300 purple, and 360 is red again. +# The allowed range is 0 to 359. + +HTML_COLORSTYLE_HUE = 220 + +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of +# the colors in the HTML output. For a value of 0 the output will use +# grayscales only. A value of 255 will produce the most vivid colors. + +HTML_COLORSTYLE_SAT = 100 + +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to +# the luminance component of the colors in the HTML output. Values below +# 100 gradually make the output lighter, whereas values above 100 make +# the output darker. The value divided by 100 is the actual gamma applied, +# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, +# and 100 does not change the gamma. + +HTML_COLORSTYLE_GAMMA = 80 + +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting +# this to NO can help when comparing the output of multiple runs. + +HTML_TIMESTAMP = YES + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. For this to work a browser that supports +# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox +# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). + +HTML_DYNAMIC_SECTIONS = NO + +# If the GENERATE_DOCSET tag is set to YES, additional index files +# will be generated that can be used as input for Apple's Xcode 3 +# integrated development environment, introduced with OSX 10.5 (Leopard). +# To create a documentation set, doxygen will generate a Makefile in the +# HTML output directory. Running make will produce the docset in that +# directory and running "make install" will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find +# it at startup. +# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html +# for more information. + +GENERATE_DOCSET = NO + +# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the +# feed. A documentation feed provides an umbrella under which multiple +# documentation sets from a single provider (such as a company or product suite) +# can be grouped. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that +# should uniquely identify the documentation set bundle. This should be a +# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen +# will append .docset to the name. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify +# the documentation publisher. This should be a reverse domain-name style +# string, e.g. com.mycompany.MyDocSet.documentation. + +DOCSET_PUBLISHER_ID = org.doxygen.Publisher + +# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. + +DOCSET_PUBLISHER_NAME = Publisher + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING +# is used to encode HtmlHelp index (hhk), content (hhc) and project file +# content. + +CHM_INDEX_ENCODING = + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated +# that can be used as input for Qt's qhelpgenerator to generate a +# Qt Compressed Help (.qch) of the generated HTML documentation. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can +# be used to specify the file name of the resulting .qch file. +# The path specified is relative to the HTML output folder. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#namespace + +QHP_NAMESPACE = org.doxygen.Project + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#virtual-folders + +QHP_VIRTUAL_FOLDER = doc + +# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to +# add. For more information please see +# http://doc.trolltech.com/qthelpproject.html#custom-filters + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see +# +# Qt Help Project / Custom Filters. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this +# project's +# filter section matches. +# +# Qt Help Project / Filter Attributes. + +QHP_SECT_FILTER_ATTRS = + +# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can +# be used to specify the location of Qt's qhelpgenerator. +# If non-empty doxygen will try to run qhelpgenerator on the generated +# .qhp file. + +QHG_LOCATION = + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files +# will be generated, which together with the HTML files, form an Eclipse help +# plugin. To install this plugin and make it available under the help contents +# menu in Eclipse, the contents of the directory containing the HTML and XML +# files needs to be copied into the plugins directory of eclipse. The name of +# the directory within the plugins directory should be the same as +# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before +# the help appears. + +GENERATE_ECLIPSEHELP = NO + +# A unique identifier for the eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have +# this name. + +ECLIPSE_DOC_ID = org.doxygen.Project + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values +# (range [0,1..20]) that doxygen will group on one line in the generated HTML +# documentation. Note that a value of 0 will completely suppress the enum +# values from appearing in the overview section. + +ENUM_VALUES_PER_LINE = 4 + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. +# If the tag value is set to YES, a side panel will be generated +# containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). +# Windows users are probably better off using the HTML help feature. + +GENERATE_TREEVIEW = YES + +# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, +# and Class Hierarchy pages using a tree view instead of an ordered list. + +USE_INLINE_TREES = NO + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open +# links to external symbols imported via tag files in a separate window. + +EXT_LINKS_IN_WINDOW = NO + +# Use this tag to change the font size of Latex formulas included +# as images in the HTML documentation. The default is 10. Note that +# when you change the font size after a successful doxygen run you need +# to manually remove any form_*.png images from the HTML output directory +# to force them to be regenerated. + +FORMULA_FONTSIZE = 10 + +# Use the FORMULA_TRANPARENT tag to determine whether or not the images +# generated for formulas are transparent PNGs. Transparent PNGs are +# not supported properly for IE 6.0, but are supported on all modern browsers. +# Note that when changing this option you need to delete any form_*.png files +# in the HTML output before the changes have effect. + +FORMULA_TRANSPARENT = YES + +# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax +# (see http://www.mathjax.org) which uses client side Javascript for the +# rendering instead of using prerendered bitmaps. Use this if you do not +# have LaTeX installed or if you want to formulas look prettier in the HTML +# output. When enabled you also need to install MathJax separately and +# configure the path to it using the MATHJAX_RELPATH option. + +USE_MATHJAX = NO + +# When MathJax is enabled you need to specify the location relative to the +# HTML output directory using the MATHJAX_RELPATH option. The destination +# directory should contain the MathJax.js script. For instance, if the mathjax +# directory is located at the same level as the HTML output directory, then +# MATHJAX_RELPATH should be ../mathjax. The default value points to the +# mathjax.org site, so you can quickly see the result without installing +# MathJax, but it is strongly recommended to install a local copy of MathJax +# before deployment. + +MATHJAX_RELPATH = http://www.mathjax.org/mathjax + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box +# for the HTML output. The underlying search engine uses javascript +# and DHTML and should work on any modern browser. Note that when using +# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets +# (GENERATE_DOCSET) there is already a search function so this one should +# typically be disabled. For large projects the javascript based search engine +# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. + +SEARCHENGINE = YES + +# When the SERVER_BASED_SEARCH tag is enabled the search engine will be +# implemented using a PHP enabled web server instead of at the web client +# using Javascript. Doxygen will generate the search PHP script and index +# file to put on the web server. The advantage of the server +# based approach is that it scales better to large projects and allows +# full text search. The disadvantages are that it is more difficult to setup +# and does not have live searching capabilities. + +SERVER_BASED_SEARCH = NO + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = YES + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. +# Note that when enabling USE_PDFLATEX this option is only used for +# generating bitmaps for formulas in the HTML output, but not in the +# Makefile that is written to the output directory. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4wide + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for +# the generated latex document. The footer should contain everything after +# the last chapter. If it is left blank doxygen will generate a +# standard footer. Notice: only use this tag if you know what you are doing! + +LATEX_FOOTER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = NO + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = NO + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +# If LATEX_SOURCE_CODE is set to YES then doxygen will include +# source code with syntax highlighting in the LaTeX output. +# Note that which sources are shown also depends on other settings +# such as SOURCE_BROWSER. + +LATEX_SOURCE_CODE = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. +# This is useful +# if you want to understand what is going on. +# On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_DEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# pointed to by INCLUDE_PATH will be searched when a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition that +# overrules the definition found in the source code. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all references to function-like macros +# that are alone on a line, have an all uppercase name, and do not end with a +# semicolon, because these will confuse the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen +# is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = doc/libosmo-netif.tag + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option also works with HAVE_DOT disabled, but it is recommended to +# install and use dot, since it yields more powerful graphs. + +CLASS_DIAGRAMS = YES + +# You can define message sequence charts within doxygen comments using the \msc +# command. Doxygen will then run the mscgen tool (see +# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the +# documentation. The MSCGEN_PATH tag allows you to specify the directory where +# the mscgen tool resides. If left empty the tool is assumed to be found in the +# default search path. + +MSCGEN_PATH = + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = NO + +# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is +# allowed to run in parallel. When set to 0 (the default) doxygen will +# base this on the number of processors available in the system. You can set it +# explicitly to a value larger than 0 to get control over the balance +# between CPU load and processing speed. + +DOT_NUM_THREADS = 0 + +# By default doxygen will write a font called Helvetica to the output +# directory and reference it in all dot files that doxygen generates. +# When you want a differently looking font you can specify the font name +# using DOT_FONTNAME. You need to make sure dot is able to find the font, +# which can be done by putting it in a standard location or by setting the +# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory +# containing the font. + +DOT_FONTNAME = Helvetica + +# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. +# The default size is 10pt. + +DOT_FONTSIZE = 10 + +# By default doxygen will tell dot to use the output directory to look for the +# FreeSans.ttf font (which doxygen will put there itself). If you specify a +# different font using DOT_FONTNAME you can set the path where dot +# can find it using this tag. + +DOT_FONTPATH = + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT options are set to YES then +# doxygen will generate a call dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable call graphs +# for selected functions only using the \callgraph command. + +CALL_GRAPH = NO + +# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then +# doxygen will generate a caller dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable caller +# graphs for selected functions only using the \callergraph command. + +CALLER_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will generate a graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are svg, png, jpg, or gif. +# If left blank png will be used. + +DOT_IMAGE_FORMAT = png + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = /usr/bin/dot + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The MSCFILE_DIRS tag can be used to specify one or more directories that +# contain msc files that are included in the documentation (see the +# \mscfile command). + +MSCFILE_DIRS = + +# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of +# nodes that will be shown in the graph. If the number of nodes in a graph +# becomes larger than this value, doxygen will truncate the graph, which is +# visualized by representing a node as a red box. Note that doxygen if the +# number of direct children of the root node in a graph is already larger than +# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note +# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. + +DOT_GRAPH_MAX_NODES = 50 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that the size of a graph can be further restricted by +# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, because dot on Windows does not +# seem to support this out of the box. Warning: Depending on the platform used, +# enabling this option may lead to badly anti-aliased labels on the edges of +# a graph (i.e. they become hard to read). + +DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = NO + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES diff --git a/Makefile.am b/Makefile.am index a78c523..9b1c0f1 100644 --- a/Makefile.am +++ b/Makefile.am @@ -13,3 +13,28 @@ echo $(VERSION) > $@-t && mv $@-t $@ dist-hook: echo $(VERSION) > $(distdir)/.tarball-version + + +if HAVE_DOXYGEN + +html_DATA = $(top_builddir)/doc/html.tar + +$(html_DATA): $(top_builddir)/doc/html/index.html + cd $(top_builddir)/doc && tar cf html.tar html + +$(top_builddir)/doc/html/index.html: $(SOURCES) Doxyfile + @rm -rf doc + mkdir -p doc + $(DOXYGEN) Doxyfile + +install-data-hook: + cd $(DESTDIR)$(htmldir) && tar xf html.tar && rm -f html.tar + +uninstall-hook: + rm -rf $(DESTDIR)$(htmldir) + +DX_CLEAN = doc/html/search/* doc/{html,latex}/* doc/html.tar doc/doxygen_sqlite3.db doc/*.tag + +endif + +MOSTLYCLEANFILES = $(DX_CLEAN) diff --git a/configure.ac b/configure.ac index 3994aff..8cd2238 100644 --- a/configure.ac +++ b/configure.ac @@ -63,6 +63,9 @@ AC_CHECK_HEADERS(dahdi/user.h,,AC_MSG_WARN(DAHDI input driver will not be built)) +AC_PATH_PROG(DOXYGEN,doxygen,false) +AM_CONDITIONAL(HAVE_DOXYGEN, test $DOXYGEN != false) + AC_OUTPUT( libosmo-netif.pc include/Makefile @@ -75,4 +78,5 @@ examples/Makefile examples/channel/Makefile tests/Makefile + Doxyfile Makefile) diff --git a/include/osmocom/netif/stream.h b/include/osmocom/netif/stream.h index 819f1ce..254b4c5 100644 --- a/include/osmocom/netif/stream.h +++ b/include/osmocom/netif/stream.h @@ -1,9 +1,16 @@ #ifndef _OSMO_STREAM_H_ #define _OSMO_STREAM_H_ +/*! \addtogroup stream + * @{ + */ + +/*! \brief Access the SCTP PPID from the msgb control buffer */ #define msgb_sctp_ppid(msg) (msg)->cb[3] +/*! \brief Access the SCTP Stream ID from the msgb control buffer */ #define msgb_sctp_stream(msg) (msg)->cb[4] +/*! \brief Osmocom Stream Server Link: A server socket listening/accepting */ struct osmo_stream_srv_link; struct osmo_stream_srv_link *osmo_stream_srv_link_create(void *ctx); @@ -20,6 +27,8 @@ int osmo_stream_srv_link_open(struct osmo_stream_srv_link *link); void osmo_stream_srv_link_close(struct osmo_stream_srv_link *link); +/*! \brief Osmocom Stream Server: Single connection accept()ed via \ref + * osmo_stream_srv_link */ struct osmo_stream_srv; struct osmo_stream_srv *osmo_stream_srv_create(void *ctx, struct osmo_stream_srv_link *link, int fd, int (*cb)(struct osmo_stream_srv *conn), int (*closed_cb)(struct osmo_stream_srv *conn), void *data); @@ -33,6 +42,7 @@ void osmo_stream_srv_send(struct osmo_stream_srv *conn, struct msgb *msg); int osmo_stream_srv_recv(struct osmo_stream_srv *conn, struct msgb *msg); +/*! \brief Osmocom Stream Client: Single client connection */ struct osmo_stream_cli; void osmo_stream_cli_set_addr(struct osmo_stream_cli *cli, const char *addr); @@ -56,4 +66,6 @@ void osmo_stream_cli_send(struct osmo_stream_cli *cli, struct msgb *msg); int osmo_stream_cli_recv(struct osmo_stream_cli *conn, struct msgb *msg); +/*! @} */ + #endif diff --git a/src/datagram.c b/src/datagram.c index c01ed9e..6316552 100644 --- a/src/datagram.c +++ b/src/datagram.c @@ -20,6 +20,15 @@ #include +/*! \addtogroup datagram Osmocom Datagram Socket + * @{ + */ + +/*! \file datagram.c + * \brief Osmocom datagram socket helpers + */ + + /* * Client side. */ @@ -36,6 +45,10 @@ unsigned int flags; }; +/*! \brief Close an Osmocom Datagram Transmitter + * \param[in] conn Osmocom Datagram Transmitter to be closed + * We unregister the socket fd from the osmocom select() loop + * abstraction and close the socket */ void osmo_dgram_tx_close(struct osmo_dgram_tx *conn) { osmo_fd_unregister(&conn->ofd); @@ -78,6 +91,11 @@ return 0; } +/*! \brief Create an Osmocom datagram transmitter + * \param[in] ctx talloc context from which to allocate memory + * This function allocates a new \ref osmo_dgram_tx and initializes + * it with default values + * \returns Osmocom Datagram Transmitter; NULL on error */ struct osmo_dgram_tx *osmo_dgram_tx_create(void *crx) { struct osmo_dgram_tx *conn; @@ -96,6 +114,10 @@ return conn; } + +/*! \brief Set the remote address to which we transmit + * \param[in] conn Datagram Transmitter to modify + * \param[in] addr Remote IP address */ void osmo_dgram_tx_set_addr(struct osmo_dgram_tx *conn, const char *addr) @@ -107,6 +129,9 @@ conn->flags |= OSMO_DGRAM_CLI_F_RECONF; } +/*! \brief Set the remote port to which we transmit + * \param[in] conn Datagram Transmitter to modify + * \param[in] port Remote Port Number */ void osmo_dgram_tx_set_port(struct osmo_dgram_tx *conn, uint16_t port) @@ -115,17 +140,25 @@ conn->flags |= OSMO_DGRAM_CLI_F_RECONF; } +/*! \brief Set application private data of the datagram transmitter + * \param[in] conn Datagram Transmitter to modify + * \param[in] data User-specific data (available in call-back functions) */ void osmo_dgram_tx_set_data(struct osmo_dgram_tx *conn, void *data) { conn->data = data; } +/*! \brief Destroy a Osmocom datagram transmitter + * \param[in] conn Datagram Transmitter to destroy */ void osmo_dgram_tx_destroy(struct osmo_dgram_tx *conn) { talloc_free(conn); } +/*! \brief Open connection of an Osmocom datagram transmitter + * \param[in] conn Stream Client to connect + * \returns 0 on success; negative in case of error */ int osmo_dgram_tx_open(struct osmo_dgram_tx *conn) { int ret; @@ -150,6 +183,9 @@ return 0; } +/*! \brief Enqueue data to be sent via an Osmocom datagram transmitter + * \param[in] conn Datagram Transmitter through which we want to send + * \param[in] msg Message buffer to enqueue in transmit queue */ void osmo_dgram_tx_send(struct osmo_dgram_tx *conn, struct msgb *msg) { @@ -172,6 +208,10 @@ unsigned int flags; }; +/*! \brief Receive data via Osmocom datagram receiver + * \param[in] conn Datagram Receiver from which to receive + * \param msg pre-allocate message buffer to which received data is appended + * \returns number of bytes read, negative on error. */ int osmo_dgram_rx_recv(struct osmo_dgram_rx *conn, struct msgb *msg) { @@ -206,6 +246,11 @@ return 0; } +/*! \brief Create an Osmocom datagram receiver + * \param[in] ctx talloc context from which to allocate memory + * This function allocates a new \ref osmo_dgram_rx and initializes + * it with default values + * \returns Datagram Receiver; NULL on error */ struct osmo_dgram_rx *osmo_dgram_rx_create(void *crx) { struct osmo_dgram_rx *conn; @@ -222,6 +267,9 @@ return conn; } +/*! \brief Set the local address to which we bind + * \param[in] conn Datagram Receiver to modify + * \param[in] addr Local IP address */ void osmo_dgram_rx_set_addr(struct osmo_dgram_rx *conn, const char *addr) { @@ -232,6 +280,9 @@ conn->flags |= OSMO_DGRAM_RX_F_RECONF; } +/*! \brief Set the local port to which we bind + * \param[in] conn Datagram Receiver to modify + * \param[in] port Local port number */ void osmo_dgram_rx_set_port(struct osmo_dgram_rx *conn, uint16_t port) { @@ -239,17 +290,26 @@ conn->flags |= OSMO_DGRAM_RX_F_RECONF; } +/*! \brief Set the read() call-back of the datagram receiver + * \param[in] conn Datagram Receiver to modify + * \param[in] read_cb Call-back function executed after read() */ void osmo_dgram_rx_set_read_cb(struct osmo_dgram_rx *conn, int (*read_cb)(struct osmo_dgram_rx *conn)) { conn->cb = read_cb; } +/*! \brief Destroy the datagram receiver. Releases Memory. + * Caller must make sure to osmo_dgram_rx_close() before calling + * \param[in] conn Datagram Receiver */ void osmo_dgram_rx_destroy(struct osmo_dgram_rx *conn) { talloc_free(conn); } +/*! \brief Open the datagram receiver. This actually initializes the + * underlying socket and binds it to the configured ip/port + * \param[in] conn Datagram Receiver to open */ int osmo_dgram_rx_open(struct osmo_dgram_rx *conn) { int ret; @@ -273,6 +333,10 @@ return 0; } + +/*! \brief Close the datagram receiver and unregister from select loop + * Does not destroy the datagram receiver, merely closes it! + * \param[in] conn Stream Server Link to close */ void osmo_dgram_rx_close(struct osmo_dgram_rx *conn) { osmo_fd_unregister(&conn->ofd); @@ -301,6 +365,13 @@ return 0; } + +/*! \brief Create an Osmocom datagram transceiver (bidirectional) + * \param[in] ctx talloc context from which to allocate memory + * This function allocates a new \ref osmo_dgram and initializes + * it with default values. Internally, the Transceiver is based on a + * tuple of transmitter (\ref osmo_dgram_tx) and receiver (\ref osmo_dgram_rx) + * \returns Osmocom Datagram Transceiver; NULL on error */ struct osmo_dgram *osmo_dgram_create(void *crx) { struct osmo_dgram *conn; @@ -325,52 +396,78 @@ return conn; } +/*! \brief Destroy a Osmocom datagram transceiver + * \param[in] conn Datagram Transceiver to destroy */ void osmo_dgram_destroy(struct osmo_dgram *conn) { osmo_dgram_rx_destroy(conn->rx); osmo_dgram_tx_destroy(conn->tx); } +/*! \brief Set the local address to which we bind + * \param[in] conn Datagram Transceiver to modify + * \param[in] addr Local IP address */ void osmo_dgram_set_local_addr(struct osmo_dgram *conn, const char *addr) { osmo_dgram_rx_set_addr(conn->rx, addr); } +/*! \brief Set the remote address to which we transmit/connect + * \param[in] conn Datagram Transceiver to modify + * \param[in] addr Remote IP address */ void osmo_dgram_set_remote_addr(struct osmo_dgram *conn, const char *addr) { osmo_dgram_tx_set_addr(conn->tx, addr); } +/*! \brief Set the local port to which we bind + * \param[in] conn Datagram Transceiver to modify + * \param[in] port Local Port Number */ void osmo_dgram_set_local_port(struct osmo_dgram *conn, uint16_t port) { osmo_dgram_rx_set_port(conn->rx, port); } +/*! \brief Set the remote port to which we transmit + * \param[in] conn Datagram Transceiver to modify + * \param[in] port Remote Port Number */ void osmo_dgram_set_remote_port(struct osmo_dgram *conn, uint16_t port) { osmo_dgram_tx_set_port(conn->tx, port); } +/*! \brief Set the read() call-back of the datagram receiver + * \param[in] conn Datagram Receiver to modify + * \param[in] read_cb Call-back function executed after read() */ void osmo_dgram_set_read_cb(struct osmo_dgram *conn, int (*read_cb)(struct osmo_dgram *conn)) { conn->read_cb = read_cb; } +/*! \brief Set application private data of the datagram transmitter + * \param[in] conn Datagram Transmitter to modify + * \param[in] data User-specific data (available in call-back functions) */ void osmo_dgram_set_data(struct osmo_dgram *conn, void *data) { conn->data = data; } +/*! \brief Get application private data of the datagram transceiver + * \param[in] conn Datagram Transceiver + * \returns Application private data, as set by \ref osmo_dgram_set_data() */ void *osmo_dgram_get_data(struct osmo_dgram *conn) { return conn->data; } +/*! \brief Open the datagram transceiver. This actually initializes the + * underlying sockets and binds/connects them to the configured ips/ports + * \param[in] conn Datagram Transceiver to open */ int osmo_dgram_open(struct osmo_dgram *conn) { int ret; @@ -387,18 +484,31 @@ return ret; } +/*! \brief Close an Osmocom Datagram Transceiver + * \param[in] conn Osmocom Datagram Transceiver to be closed + * We unregister the socket fds from the osmocom select() loop + * and close them. */ void osmo_dgram_close(struct osmo_dgram *conn) { osmo_dgram_rx_close(conn->rx); osmo_dgram_tx_close(conn->tx); } +/*! \brief Enqueue data to be sent via an Osmocom datagram transceiver + * \param[in] conn Datagram Transceiver through which we want to send + * \param[in] msg Message buffer to enqueue in transmit queue */ void osmo_dgram_send(struct osmo_dgram *conn, struct msgb *msg) { osmo_dgram_tx_send(conn->tx, msg); } +/*! \brief Receive data via Osmocom datagram transceiver + * \param[in] conn Datagram Transceiver from which to receive + * \param msg pre-allocate message buffer to which received data is appended + * \returns number of bytes read, negative on error. */ int osmo_dgram_recv(struct osmo_dgram *conn, struct msgb *msg) { return osmo_dgram_rx_recv(conn->rx, msg); } + +/*! @} */ diff --git a/src/stream.c b/src/stream.c index 6b8bc95..e71e420 100644 --- a/src/stream.c +++ b/src/stream.c @@ -26,6 +26,14 @@ #include #endif +/*! \addtogroup stream Osmocom Stream Socket + * @{ + */ + +/*! \file stream.c + * \brief Osmocom stream socket helpers + */ + /* * Platforms that don't have MSG_NOSIGNAL (which disables SIGPIPE) * usually have SO_NOSIGPIPE (set via setsockopt). @@ -74,6 +82,7 @@ enum osmo_stream_cli_state state; const char *addr; uint16_t port; + uint16_t local_port; uint16_t proto; int (*connect_cb)(struct osmo_stream_cli *srv); int (*read_cb)(struct osmo_stream_cli *srv); @@ -85,6 +94,9 @@ void osmo_stream_cli_close(struct osmo_stream_cli *cli); +/*! \brief Re-connect an Osmocom Stream Client + * If re-connection is enabled for this client, we close any existing + * connection (if any) and schedule a re-connect timer */ void osmo_stream_cli_reconnect(struct osmo_stream_cli *cli) { if (cli->reconnect_timeout < 0) { @@ -99,6 +111,10 @@ cli->state = STREAM_CLI_STATE_CONNECTING; } +/*! \brief Close an Osmocom Stream Client + * \param[in] cli Osmocom Stream Client to be closed + * We unregister the socket fd from the osmocom select() loop + * abstraction and close the socket */ void osmo_stream_cli_close(struct osmo_stream_cli *cli) { if (cli->ofd.fd == -1) @@ -212,6 +228,10 @@ static void cli_timer_cb(void *data); +/*! \brief Create an Osmocom stream client + * \param[in] ctx talloc context from which to allocate memory + * This function allocates a new \ref osmo_stream_cli and initializes + * it with default values (5s reconnect timer, TCP protocol) */ struct osmo_stream_cli *osmo_stream_cli_create(void *ctx) { struct osmo_stream_cli *cli; @@ -235,6 +255,10 @@ return cli; } +/*! \brief Set the remote address to which we connect + * \param[in] cli Stream Client to modify + * \param[in] addr Remote IP address + */ void osmo_stream_cli_set_addr(struct osmo_stream_cli *cli, const char *addr) { @@ -242,6 +266,10 @@ cli->flags |= OSMO_STREAM_CLI_F_RECONF; } +/*! \brief Set the remote port number to which we connect + * \param[in] cli Stream Client to modify + * \param[in] port Remote port number + */ void osmo_stream_cli_set_port(struct osmo_stream_cli *cli, uint16_t port) { @@ -249,6 +277,21 @@ cli->flags |= OSMO_STREAM_CLI_F_RECONF; } +/*! \brief Set the local port number for the socket + * \param[in] cli Stream Client to modify + * \param[in] port Local port number + */ +void +osmo_stream_cli_set_local_port(struct osmo_stream_cli *cli, uint16_t port) +{ + cli->local_port = port; + cli->flags |= OSMO_STREAM_CLI_F_RECONF; +} + +/*! \brief Set the protocol for the stream client socket + * \param[in] cli Stream Client to modify + * \param[in] proto Protocol (like IPPROTO_TCP (default), IPPROTO_SCTP, ...) + */ void osmo_stream_cli_set_proto(struct osmo_stream_cli *cli, uint16_t proto) { @@ -256,29 +299,44 @@ cli->flags |= OSMO_STREAM_CLI_F_RECONF; } +/*! \brief Set the reconnect time of the stream client socket + * \param[in] cli Stream Client to modify + * \param[in] timeout Re-connect timeout in seconds */ void osmo_stream_cli_set_reconnect_timeout(struct osmo_stream_cli *cli, int timeout) { cli->reconnect_timeout = timeout; } +/*! \brief Set application private data of the stream client socket + * \param[in] cli Stream Client to modify + * \param[in] data User-specific data (available in call-back functions) */ void osmo_stream_cli_set_data(struct osmo_stream_cli *cli, void *data) { cli->data = data; } +/*! \brief Get application private data of the stream client socket + * \param[in] cli Stream Client to modif + * \returns Application private data, as set by \ref osmo_stream_cli_set_data() */ void *osmo_stream_cli_get_data(struct osmo_stream_cli *cli) { return cli->data; } +/*! \brief Get Osmocom File Descriptor of the stream client socket + * \param[in] cli Stream Client to modif + * \returns Pointer to \ref osmo_fd */ struct osmo_fd * osmo_stream_cli_get_ofd(struct osmo_stream_cli *cli) { return &cli->ofd; } +/*! \brief Set the call-back function called on connect of the stream client socket + * \param[in] cli Stream Client to modif + * \param[in] connect_cb Call-back function to be called upon connect */ void osmo_stream_cli_set_connect_cb(struct osmo_stream_cli *cli, int (*connect_cb)(struct osmo_stream_cli *cli)) @@ -286,6 +344,9 @@ cli->connect_cb = connect_cb; } +/*! \brief Set the call-back function called to read from the stream client socket + * \param[in] cli Stream Client to modif + * \param[in] read_cb Call-back function to be called when we want to read */ void osmo_stream_cli_set_read_cb(struct osmo_stream_cli *cli, int (*read_cb)(struct osmo_stream_cli *cli)) @@ -293,12 +354,18 @@ cli->read_cb = read_cb; } +/*! \brief Destroy a Osmocom stream client + * \param[in] cli Stream Client to destroy */ void osmo_stream_cli_destroy(struct osmo_stream_cli *cli) { osmo_timer_del(&cli->timer); talloc_free(cli); } +/*! \brief Open connection of an Osmocom stream client + * \param[in] cli Stream Client to connect + * \param[in] reconect 1 if we should not automatically reconnect + */ int osmo_stream_cli_open2(struct osmo_stream_cli *cli, int reconnect) { int ret; @@ -327,6 +394,8 @@ } +/*! \brief Open connection of an Osmocom stream client + * \param[in] cli Stream Client to connect */ int osmo_stream_cli_open(struct osmo_stream_cli *cli) { return osmo_stream_cli_open2(cli, 0); @@ -348,12 +417,19 @@ } } +/*! \brief Enqueue data to be sent via an Osmocom stream client + * \param[in] cli Stream Client through which we want to send + * \param[in] msg Message buffer to enqueue in transmit queue */ void osmo_stream_cli_send(struct osmo_stream_cli *cli, struct msgb *msg) { msgb_enqueue(&cli->tx_queue, msg); cli->ofd.when |= BSC_FD_WRITE; } +/*! \brief Receive data via an Osmocom stream client + * \param[in] cli Stream Client through which we want to send + * \param msg pre-allocate message buffer to which received data is appended + * \returns number of bytes read; <=0 in case of error */ int osmo_stream_cli_recv(struct osmo_stream_cli *cli, struct msgb *msg) { int ret; @@ -417,6 +493,12 @@ return 0; } +/*! \brief Create an Osmocom Stream Server Link + * A Stream Server Link is the listen()+accept() "parent" to individual + * Stream Servers + * \param[in] ctx talloc allocation context + * \returns Stream Server Link with default values (TCP) + */ struct osmo_stream_srv_link *osmo_stream_srv_link_create(void *ctx) { struct osmo_stream_srv_link *link; @@ -434,6 +516,10 @@ return link; } +/*! \brief Set the local address to which we bind + * \param[in] link Stream Server Link to modify + * \param[in] addr Local IP address + */ void osmo_stream_srv_link_set_addr(struct osmo_stream_srv_link *link, const char *addr) { @@ -441,6 +527,10 @@ link->flags |= OSMO_STREAM_SRV_F_RECONF; } +/*! \brief Set the local port number to which we bind + * \param[in] link Stream Server Link to modify + * \param[in] port Local port number + */ void osmo_stream_srv_link_set_port(struct osmo_stream_srv_link *link, uint16_t port) { @@ -448,6 +538,10 @@ link->flags |= OSMO_STREAM_SRV_F_RECONF; } +/*! \brief Set the protocol for the stream server link + * \param[in] link Stream Server Link to modify + * \param[in] proto Protocol (like IPPROTO_TCP (default), IPPROTO_SCTP, ...) + */ void osmo_stream_srv_link_set_proto(struct osmo_stream_srv_link *link, uint16_t proto) @@ -456,6 +550,9 @@ link->flags |= OSMO_STREAM_SRV_F_RECONF; } +/*! \brief Set application private data of the stream server link + * \param[in] link Stream Server Link to modify + * \param[in] data User-specific data (available in call-back functions) */ void osmo_stream_srv_link_set_data(struct osmo_stream_srv_link *link, void *data) @@ -463,17 +560,26 @@ link->data = data; } +/*! \brief Get application private data of the stream server link + * \param[in] link Stream Server Link to modify + * \returns Application private data, as set by \ref osmo_stream_cli_set_data() */ void *osmo_stream_srv_link_get_data(struct osmo_stream_srv_link *link) { return link->data; } +/*! \brief Get Osmocom File Descriptor of the stream server link + * \param[in] link Stream Server Link + * \returns Pointer to \ref osmo_fd */ struct osmo_fd * osmo_stream_srv_link_get_ofd(struct osmo_stream_srv_link *link) { return &link->ofd; } +/*! \brief Set the accept() call-back of the stream server link + * \param[in] link Stream Server Link + * \param[in] accept_cb Call-back function executed upon accept() */ void osmo_stream_srv_link_set_accept_cb(struct osmo_stream_srv_link *link, int (*accept_cb)(struct osmo_stream_srv_link *link, int fd)) @@ -481,11 +587,17 @@ link->accept_cb = accept_cb; } +/*! \brief Destroy the stream server link. Releases Memory. + * Caller must make sure to osmo_stream_srv_link_close() before calling + * \param[in] link Stream Server Link */ void osmo_stream_srv_link_destroy(struct osmo_stream_srv_link *link) { talloc_free(link); } +/*! \brief Open the stream server link. This actually initializes the + * underlying socket and binds it to the configured ip/port + * \param[in] link Stream Server Link to open */ int osmo_stream_srv_link_open(struct osmo_stream_srv_link *link) { int ret; @@ -509,6 +621,9 @@ return 0; } +/*! \brief Close the stream server link and unregister from select loop + * Does not destroy the server link, merely closes it! + * \param[in] link Stream Server Link to close */ void osmo_stream_srv_link_close(struct osmo_stream_srv_link *link) { if (link->ofd.fd == -1) @@ -590,6 +705,10 @@ return 0; } +/*! \brief Create a Stream Server inside the specified link + * \param[in] ctx talloc allocation context from which to allocate + * \param[in] link Stream Server Link to which we belong + * \returns Stream Server in case of success; NULL on error */ struct osmo_stream_srv * osmo_stream_srv_create(void *ctx, struct osmo_stream_srv_link *link, int fd, @@ -622,6 +741,9 @@ return conn; } +/*! \brief Set application private data of the stream server + * \param[in] conn Stream Server to modify + * \param[in] data User-specific data (available in call-back functions) */ void osmo_stream_srv_set_data(struct osmo_stream_srv *conn, void *data) @@ -629,22 +751,35 @@ conn->data = data; } -void *osmo_stream_srv_get_data(struct osmo_stream_srv *link) +/*! \brief Get application private data of the stream server + * \param[in] conn Stream Server + * \returns Application private data, as set by \ref osmo_stream_srv_set_data() */ +void *osmo_stream_srv_get_data(struct osmo_stream_srv *conn) { - return link->data; + return conn->data; } +/*! \brief Get Osmocom File Descriptor of the stream server + * \param[in] conn Stream Server + * \returns Pointer to \ref osmo_fd */ struct osmo_fd * -osmo_stream_srv_get_ofd(struct osmo_stream_srv *link) +osmo_stream_srv_get_ofd(struct osmo_stream_srv *conn) { - return &link->ofd; + return &conn->ofd; } +/*! \brief Get the master (Link) from a Stream Server + * \param[in] conn Stream Server of which we want to know the Link + * \returns Link through which the given Stream Server is established */ struct osmo_stream_srv_link *osmo_stream_srv_get_master(struct osmo_stream_srv *conn) { return conn->srv; } +/*! \brief Destroy given Stream Server + * This function closes the Stream Server socket, unregisters from + * select loop and de-allocates associated memory. + * \param[in] conn Stream Server to be destroyed */ void osmo_stream_srv_destroy(struct osmo_stream_srv *conn) { close(conn->ofd.fd); @@ -654,12 +789,20 @@ talloc_free(conn); } +/*! \brief Enqueue data to be sent via an Osmocom stream server + * \param[in] conn Stream Server through which we want to send + * \param[in] msg Message buffer to enqueue in transmit queue */ void osmo_stream_srv_send(struct osmo_stream_srv *conn, struct msgb *msg) { msgb_enqueue(&conn->tx_queue, msg); conn->ofd.when |= BSC_FD_WRITE; } +/*! \brief Receive data via Osmocom stream server + * \param[in] conn Stream Server from which to receive + * \param msg pre-allocate message buffer to which received data is appended + * \returns number of bytes read, negative on error. + */ int osmo_stream_srv_recv(struct osmo_stream_srv *conn, struct msgb *msg) { #ifdef HAVE_LIBSCTP @@ -735,3 +878,5 @@ LOGP(DLINP, LOGL_DEBUG, "received %d bytes from client\n", ret); return ret; } + +/*! @} */ -- To view, visit https://gerrit.osmocom.org/2248 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I589a5e60d9df2b8a65fbaf68f80e3ae0039d8c2a Gerrit-PatchSet: 1 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Sat Apr 8 18:13:31 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 8 Apr 2017 18:13:31 +0000 Subject: [PATCH] libosmo-netif[master]: doc: Add Doxygen group for OSMUX related functions Message-ID: Review at https://gerrit.osmocom.org/2249 doc: Add Doxygen group for OSMUX related functions Change-Id: I87e08bd84236ae5d5c057bca96d122e568a6b52a --- M include/osmocom/netif/osmux.h M src/osmux.c 2 files changed, 21 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-netif refs/changes/49/2249/1 diff --git a/include/osmocom/netif/osmux.h b/include/osmocom/netif/osmux.h index 83bb2e1..1d93aa0 100644 --- a/include/osmocom/netif/osmux.h +++ b/include/osmocom/netif/osmux.h @@ -3,6 +3,14 @@ #include +/*! \addtogroup osmux + * @{ + */ + +/*! \file osmux.h + * Osmocom multiplex protocol helpers + */ + /* OSmux header: * * ft (3 bits): 0=signalling, 1=voice, 2=dummy @@ -95,4 +103,6 @@ void osmux_tx_sched(struct llist_head *list, void (*tx_cb)(struct msgb *msg, void *data), void *data); +/*! @} */ + #endif diff --git a/src/osmux.c b/src/osmux.c index 913d68f..5655269 100644 --- a/src/osmux.c +++ b/src/osmux.c @@ -23,6 +23,15 @@ #include +/*! \addtogroup osmux Osmocom Multiplex Protocol + * @{ + */ + +/*! \file osmux.c + * \brief Osmocom multiplex protocol helpers + */ + + /* This allows you to debug timing reconstruction in the output path */ #if 0 #define DEBUG_TIMING 0 @@ -921,3 +930,5 @@ return offset; } + +/*! @} */ -- To view, visit https://gerrit.osmocom.org/2249 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I87e08bd84236ae5d5c057bca96d122e568a6b52a Gerrit-PatchSet: 1 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Sat Apr 8 19:26:43 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 8 Apr 2017 19:26:43 +0000 Subject: [PATCH] libosmocore[master]: Add osmo_sock_init2() function, allowing both BIND *and* CON... Message-ID: Review at https://gerrit.osmocom.org/2250 Add osmo_sock_init2() function, allowing both BIND *and* CONNECT The old osmo_sock_init() function allows only either a bind (for a server socket), or a connect (for a client socket), but not both together. So there's no way to have a client socket that is bound to a specific local IP and/or port, which is needed for some use cases. Change-Id: Idab124bcca47872f55311a82d6818aed590965e6 --- M include/osmocom/core/socket.h M src/socket.c M tests/socket/socket_test.c M tests/socket/socket_test.err M tests/socket/socket_test.ok 5 files changed, 243 insertions(+), 33 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/50/2250/1 diff --git a/include/osmocom/core/socket.h b/include/osmocom/core/socket.h index 4f00e30..e19e8f2 100644 --- a/include/osmocom/core/socket.h +++ b/include/osmocom/core/socket.h @@ -24,6 +24,10 @@ int osmo_sock_init(uint16_t family, uint16_t type, uint8_t proto, const char *host, uint16_t port, unsigned int flags); +int osmo_sock_init2(uint16_t family, uint16_t type, uint8_t proto, + const char *local_host, uint16_t local_port, + const char *remote_host, uint16_t remote_port, unsigned int flags); + int osmo_sock_init_ofd(struct osmo_fd *ofd, int family, int type, int proto, const char *host, uint16_t port, unsigned int flags); diff --git a/src/socket.c b/src/socket.c index 2c1b547..ad0f69b 100644 --- a/src/socket.c +++ b/src/socket.c @@ -51,6 +51,188 @@ #include #include +static struct addrinfo *addrinfo_helper(uint16_t family, uint16_t type, uint8_t proto, + const char *host, uint16_t port, bool passive) +{ + struct addrinfo hints, *result; + char portbuf[16]; + int rc; + + snprintf(portbuf, sizeof(portbuf), "%u", port); + memset(&hints, 0, sizeof(struct addrinfo)); + hints.ai_family = family; + if (type == SOCK_RAW) { + /* Workaround for glibc, that returns EAI_SERVICE (-8) if + * SOCK_RAW and IPPROTO_GRE is used. + */ + hints.ai_socktype = SOCK_DGRAM; + hints.ai_protocol = IPPROTO_UDP; + } else { + hints.ai_socktype = type; + hints.ai_protocol = proto; + } + + if (passive) + hints.ai_flags |= AI_PASSIVE; + + rc = getaddrinfo(host, portbuf, &hints, &result); + if (rc != 0) { + LOGP(DLGLOBAL, LOGL_ERROR, "getaddrinfo returned NULL: %s:%u: %s\n", + host, port, strerror(errno)); + return NULL; + } + + return result; +} + +static int socket_helper(const struct addrinfo *rp, unsigned int flags) +{ + int sfd, on = 1; + + sfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); + if (sfd == -1) + return sfd; + if (flags & OSMO_SOCK_F_NONBLOCK) { + if (ioctl(sfd, FIONBIO, (unsigned char *)&on) < 0) { + LOGP(DLGLOBAL, LOGL_ERROR, + "cannot set this socket unblocking: %s\n", + strerror(errno)); + close(sfd); + sfd = -EINVAL; + } + } + return sfd; +} + + +/*! \brief Initialize a socket (including bind and/or connect) + * \param[in] family Address Family like AF_INET, AF_INET6, AF_UNSPEC + * \param[in] type Socket type like SOCK_DGRAM, SOCK_STREAM + * \param[in] proto Protocol like IPPROTO_TCP, IPPROTO_UDP + * \param[in] local_host local host name or IP address in string form + * \param[in] local_port local port number in host byte order + * \param[in] remote_host remote host name or IP address in string form + * \param[in] remote_port remote port number in host byte order + * \param[in] flags flags like \ref OSMO_SOCK_F_CONNECT + * \returns socket file descriptor on success; negative on error + * + * This function creates a new socket of the designated \a family, \a + * type and \a proto and optionally binds it to the \a local_host and \a + * local_port as well as optionally connects it to the \a remote_host + * and \q remote_port, depending on the value * of \a flags parameter. + * + * As opposed to \ref osmo_sock_init(), this function allows to combine + * the \ref OSMO_SOCK_F_BIND and \ref OSMO_SOCK_F_CONNECT flags. This + * is useful if you want to connect to a remote host/port, but still + * want to bind that socket to either a specific local alias IP and/or a + * specific local source port. + * + * You must specify either \ref OSMO_SOCK_F_BIND, or \ref + * OSMO_SOCK_F_CONNECT, or both. + * + * If \ref OSMO_SOCK_F_NONBLOCK is specified, the socket will be set to + * non-blocking mode. + */ +int osmo_sock_init2(uint16_t family, uint16_t type, uint8_t proto, + const char *local_host, uint16_t local_port, + const char *remote_host, uint16_t remote_port, unsigned int flags) +{ + struct addrinfo *result, *rp; + int sfd = -1, rc, on = 1; + + if ((flags & (OSMO_SOCK_F_BIND | OSMO_SOCK_F_CONNECT)) == 0) { + LOGP(DLGLOBAL, LOGL_ERROR, "invalid: you have to specify either " + "BIND or CONNECT flags\n"); + return -EINVAL; + } + + /* figure out local side of socket */ + if (flags & OSMO_SOCK_F_BIND) { + result = addrinfo_helper(family, type, proto, local_host, local_port, true); + if (!result) + return -EINVAL; + + for (rp = result; rp != NULL; rp = rp->ai_next) { + /* Workaround for glibc again */ + if (type == SOCK_RAW) { + rp->ai_socktype = SOCK_RAW; + rp->ai_protocol = proto; + } + + sfd = socket_helper(rp, flags); + if (sfd < 0) + continue; + + rc = setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, + &on, sizeof(on)); + if (rc < 0) { + LOGP(DLGLOBAL, LOGL_ERROR, + "cannot setsockopt socket:" + " %s:%u: %s\n", + local_host, local_port, strerror(errno)); + break; + } + if (bind(sfd, rp->ai_addr, rp->ai_addrlen) != -1) + break; + close(sfd); + } + freeaddrinfo(result); + if (rp == NULL) { + LOGP(DLGLOBAL, LOGL_ERROR, "unable to bind socket: %s:%u: %s\n", + local_host, local_port, strerror(errno)); + return -ENODEV; + } + } + + /* figure out remote side of socket */ + if (flags & OSMO_SOCK_F_CONNECT) { + result = addrinfo_helper(family, type, proto, remote_host, remote_port, false); + if (!result) { + close(sfd); + return -EINVAL; + } + + for (rp = result; rp != NULL; rp = rp->ai_next) { + /* Workaround for glibc again */ + if (type == SOCK_RAW) { + rp->ai_socktype = SOCK_RAW; + rp->ai_protocol = proto; + } + + if (!sfd) { + sfd = socket_helper(rp, flags); + if (sfd < 0) + continue; + } + + rc = connect(sfd, rp->ai_addr, rp->ai_addrlen); + if (rc != -1 || (rc == -1 && errno == EINPROGRESS)) + break; + + close(sfd); + sfd = -1; + } + freeaddrinfo(result); + if (rp == NULL) { + LOGP(DLGLOBAL, LOGL_ERROR, "unable to connect socket: %s:%u: %s\n", + remote_host, remote_port, strerror(errno)); + return -ENODEV; + } + } + + /* Make sure to call 'listen' on a bound, connection-oriented sock */ + if ((flags & (OSMO_SOCK_F_BIND|OSMO_SOCK_F_CONNECT)) == OSMO_SOCK_F_BIND) { + switch (type) { + case SOCK_STREAM: + case SOCK_SEQPACKET: + listen(sfd, 10); + break; + } + } + return sfd; +} + + /*! \brief Initialize a socket (including bind/connect) * \param[in] family Address Family like AF_INET, AF_INET6, AF_UNSPEC * \param[in] type Socket type like SOCK_DGRAM, SOCK_STREAM @@ -67,9 +249,8 @@ int osmo_sock_init(uint16_t family, uint16_t type, uint8_t proto, const char *host, uint16_t port, unsigned int flags) { - struct addrinfo hints, *result, *rp; + struct addrinfo *result, *rp; int sfd, rc, on = 1; - char portbuf[16]; if ((flags & (OSMO_SOCK_F_BIND | OSMO_SOCK_F_CONNECT)) == (OSMO_SOCK_F_BIND | OSMO_SOCK_F_CONNECT)) { @@ -78,25 +259,8 @@ return -EINVAL; } - sprintf(portbuf, "%u", port); - memset(&hints, 0, sizeof(struct addrinfo)); - hints.ai_family = family; - if (type == SOCK_RAW) { - /* Workaround for glibc, that returns EAI_SERVICE (-8) if - * SOCK_RAW and IPPROTO_GRE is used. - */ - hints.ai_socktype = SOCK_DGRAM; - hints.ai_protocol = IPPROTO_UDP; - } else { - hints.ai_socktype = type; - hints.ai_protocol = proto; - } - - if (flags & OSMO_SOCK_F_BIND) - hints.ai_flags |= AI_PASSIVE; - - rc = getaddrinfo(host, portbuf, &hints, &result); - if (rc != 0) { + result = addrinfo_helper(family, type, proto, host, port, flags & OSMO_SOCK_F_BIND); + if (!result) { LOGP(DLGLOBAL, LOGL_ERROR, "getaddrinfo returned NULL: %s:%u: %s\n", host, port, strerror(errno)); return -EINVAL; @@ -109,20 +273,10 @@ rp->ai_protocol = proto; } - sfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); + sfd = socket_helper(rp, flags); if (sfd == -1) continue; - if (flags & OSMO_SOCK_F_NONBLOCK) { - if (ioctl(sfd, FIONBIO, (unsigned char *)&on) < 0) { - LOGP(DLGLOBAL, LOGL_ERROR, - "cannot set this socket unblocking:" - " %s:%u: %s\n", - host, port, strerror(errno)); - close(sfd); - freeaddrinfo(result); - return -EINVAL; - } - } + if (flags & OSMO_SOCK_F_CONNECT) { rc = connect(sfd, rp->ai_addr, rp->ai_addrlen); if (rc != -1 || (rc == -1 && errno == EINPROGRESS)) diff --git a/tests/socket/socket_test.c b/tests/socket/socket_test.c index 5b6abc4..57425ef 100644 --- a/tests/socket/socket_test.c +++ b/tests/socket/socket_test.c @@ -73,6 +73,52 @@ return 0; } +static int test_sockinit2(void) +{ + int fd, rc; + char *name; + + printf("Checking osmo_sock_init2() with bind to a random local UDP port\n"); + fd = osmo_sock_init2(AF_INET, SOCK_DGRAM, IPPROTO_UDP, + "0.0.0.0", 0, NULL, 0, OSMO_SOCK_F_BIND); + OSMO_ASSERT(fd >= 0); + name = osmo_sock_get_name(NULL, fd); + /* expect it to be not connected. We cannot match on INADDR_ANY, + * as apparently that won't work on FreeBSD if there's only one + * address (e.g. 127.0.0.1) assigned to the entire system, like + * the Osmocom FreeBSD build slaves */ + OSMO_ASSERT(!strncmp(name, "(NULL<->", 7)); + talloc_free(name); + /* expect it to be blocking */ + rc = fcntl(fd, F_GETFL); + OSMO_ASSERT(!(rc & O_NONBLOCK)); + close(fd); + + printf("Checking osmo_sock_init2() for OSMO_SOCK_F_NONBLOCK\n"); + fd = osmo_sock_init2(AF_INET, SOCK_DGRAM, IPPROTO_UDP, + "0.0.0.0", 0, NULL, 0, OSMO_SOCK_F_BIND|OSMO_SOCK_F_NONBLOCK); + OSMO_ASSERT(fd >= 0); + /* expect it to be blocking */ + rc = fcntl(fd, F_GETFL); + OSMO_ASSERT(rc & O_NONBLOCK); + close(fd); + + printf("Checking osmo_sock_init2() for invalid flags\n"); + fd = osmo_sock_init2(AF_INET, SOCK_DGRAM, IPPROTO_UDP, "0.0.0.0", 0, NULL, 0, 0); + OSMO_ASSERT(fd < 0); + + printf("Checking osmo_sock_init2() for combined BIND + CONNECT\n"); + fd = osmo_sock_init2(AF_INET, SOCK_DGRAM, IPPROTO_UDP, "127.0.0.1", 0, "127.0.0.1", 53, + OSMO_SOCK_F_BIND|OSMO_SOCK_F_CONNECT); + OSMO_ASSERT(fd >= 0); + name = osmo_sock_get_name(NULL, fd); + OSMO_ASSERT(!strncmp(name, "(127.0.0.1:53<->127.0.0.1", 25)); + talloc_free(name); + + return 0; +} + + const struct log_info_cat default_categories[] = { }; @@ -88,6 +134,7 @@ log_set_print_filename(osmo_stderr_target, 0); test_sockinit(); + test_sockinit2(); return EXIT_SUCCESS; } diff --git a/tests/socket/socket_test.err b/tests/socket/socket_test.err index 5367239..ed6e186 100644 --- a/tests/socket/socket_test.err +++ b/tests/socket/socket_test.err @@ -1 +1,2 @@ invalid: both bind and connect flags set: 0.0.0.0:0 +invalid: you have to specify either BIND or CONNECT flags diff --git a/tests/socket/socket_test.ok b/tests/socket/socket_test.ok index d6ec40e..4b24fbc 100644 --- a/tests/socket/socket_test.ok +++ b/tests/socket/socket_test.ok @@ -1,3 +1,7 @@ Checking osmo_sock_init() with bind to a random local UDP port Checking for OSMO_SOCK_F_NONBLOCK Checking for invalid flags +Checking osmo_sock_init2() with bind to a random local UDP port +Checking osmo_sock_init2() for OSMO_SOCK_F_NONBLOCK +Checking osmo_sock_init2() for invalid flags +Checking osmo_sock_init2() for combined BIND + CONNECT -- To view, visit https://gerrit.osmocom.org/2250 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Idab124bcca47872f55311a82d6818aed590965e6 Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Sat Apr 8 19:54:05 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 8 Apr 2017 19:54:05 +0000 Subject: libosmocore[master]: Add osmo_sock_init2() function, allowing both BIND *and* CON... In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+1 "make check" passes fine on my local FreeBSD 10.3 and FreeBSD 11 VMs. I'm not quite sure what local configuration of the buildhost might make socket_test fail? Holger? -- To view, visit https://gerrit.osmocom.org/2250 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Idab124bcca47872f55311a82d6818aed590965e6 Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sat Apr 8 19:55:01 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 8 Apr 2017 19:55:01 +0000 Subject: libosmo-netif[master]: doc: Add Doxygen group for OSMUX related functions In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2249 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I87e08bd84236ae5d5c057bca96d122e568a6b52a Gerrit-PatchSet: 1 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sat Apr 8 19:55:03 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 8 Apr 2017 19:55:03 +0000 Subject: libosmo-netif[master]: Add minimal doxygen documentation for stream + datagram modules In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2248 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I589a5e60d9df2b8a65fbaf68f80e3ae0039d8c2a Gerrit-PatchSet: 1 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sat Apr 8 19:55:06 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 8 Apr 2017 19:55:06 +0000 Subject: [MERGED] libosmo-netif[master]: Add minimal doxygen documentation for stream + datagram modules In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: Add minimal doxygen documentation for stream + datagram modules ...................................................................... Add minimal doxygen documentation for stream + datagram modules We should have doxygen documentation for all libosmo-* APIs. libosmo-netif is currently devoid of any API docs. Let's start with the stream and datagram socket related functions. Change-Id: I589a5e60d9df2b8a65fbaf68f80e3ae0039d8c2a --- M .gitignore A Doxyfile.in M Makefile.am M configure.ac M include/osmocom/netif/stream.h M src/datagram.c M src/stream.c 7 files changed, 2,018 insertions(+), 4 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/.gitignore b/.gitignore index aa38852..2d582bd 100644 --- a/.gitignore +++ b/.gitignore @@ -49,3 +49,5 @@ examples/rtp-udp-test-server examples/stream-client examples/stream-server + +Doxyfile diff --git a/Doxyfile.in b/Doxyfile.in new file mode 100644 index 0000000..3843f79 --- /dev/null +++ b/Doxyfile.in @@ -0,0 +1,1716 @@ +# Doxyfile 1.7.4 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project. +# +# All text after a hash (#) is considered a comment and will be ignored. +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" "). + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See +# http://www.gnu.org/software/libiconv for the list of possible encodings. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = libosmo-netif + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = @VERSION@ + +# Using the PROJECT_BRIEF tag one can provide an optional one line description +# for a project that appears at the top of each page and should give viewer +# a quick idea about the purpose of the project. Keep the description short. + +PROJECT_BRIEF = "Osmocom network interface library" + +# With the PROJECT_LOGO tag one can specify an logo or icon that is +# included in the documentation. The maximum height of the logo should not +# exceed 55 pixels and the maximum width should not exceed 200 pixels. +# Doxygen will copy the logo to the output directory. + +PROJECT_LOGO = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = doc + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, +# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, +# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English +# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, +# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, +# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = YES + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful if your file system +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like regular Qt-style comments +# (thus requiring an explicit @brief command for a brief description.) + +JAVADOC_AUTOBRIEF = NO + +# If the QT_AUTOBRIEF tag is set to YES then Doxygen will +# interpret the first line (until the first dot) of a Qt-style +# comment as the brief description. If set to NO, the comments +# will behave just like regular Qt-style comments (thus requiring +# an explicit \brief command for a brief description.) + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 8 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = YES + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for +# Java. For instance, namespaces will be presented as packages, qualified +# scopes will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources only. Doxygen will then generate output that is more tailored for +# Fortran. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for +# VHDL. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Doxygen selects the parser to use depending on the extension of the files it +# parses. With this tag you can assign which parser to use for a given extension. +# Doxygen has a built-in mapping, but you can override or extend it using this +# tag. The format is ext=language, where ext is a file extension, and language +# is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C, +# C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make +# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C +# (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions +# you also need to set FILE_PATTERNS otherwise the files are not read by doxygen. + +EXTENSION_MAPPING = + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also makes the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. +# Doxygen will parse them like normal C++ but will assume all classes use public +# instead of private inheritance when no explicit protection keyword is present. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate getter +# and setter methods for a property. Setting this option to YES (the default) +# will make doxygen replace the get and set methods by a property in the +# documentation. This will only work if the methods are indeed getting or +# setting a simple type. If this is not the case, or you want to show the +# methods anyway, you should set this option to NO. + +IDL_PROPERTY_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and +# unions are shown inside the group in which they are included (e.g. using +# @ingroup) instead of on a separate page (for HTML and Man pages) or +# section (for LaTeX and RTF). + +INLINE_GROUPED_CLASSES = NO + +# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum +# is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically +# be useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. + +TYPEDEF_HIDES_STRUCT = NO + +# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to +# determine which symbols to keep in memory and which to flush to disk. +# When the cache is full, less often used symbols will be written to disk. +# For small to medium size projects (<1000 input files) the default value is +# probably good enough. For larger projects a too small cache size can cause +# doxygen to be busy swapping symbols to and from disk most of the time +# causing a significant performance penalty. +# If the system has enough physical memory increasing the cache will improve the +# performance by keeping more symbols in memory. Note that the value works on +# a logarithmic scale so increasing the size by one will roughly double the +# memory usage. The cache size is given by this formula: +# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, +# corresponding to a cache size of 2^16 = 65536 symbols + +SYMBOL_CACHE_SIZE = 0 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = NO + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = YES + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base +# name of the file that contains the anonymous namespace. By default +# anonymous namespaces are hidden. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen +# will list include files with double quotes in the documentation +# rather than with sharp brackets. + +FORCE_LOCAL_INCLUDES = NO + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen +# will sort the (brief and detailed) documentation of class members so that +# constructors and destructors are listed first. If set to NO (the default) +# the constructors will appear in the respective orders defined by +# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. +# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO +# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. + +SORT_MEMBERS_CTORS_1ST = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the +# hierarchy of group names into alphabetical order. If set to NO (the default) +# the group names will appear in their defined order. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to +# do proper type resolution of all parameters of a function it will reject a +# match between the prototype and the implementation of a member function even +# if there is only one candidate or it is obvious which candidate to choose +# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen +# will still accept a match between prototype and implementation in such cases. + +STRICT_PROTO_MATCHING = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or macro consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and macros in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# If the sources in your project are distributed over multiple directories +# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy +# in the documentation. The default is NO. + +SHOW_DIRECTORIES = NO + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. +# This will remove the Files entry from the Quick Index and from the +# Folder Tree View (if specified). The default is YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the +# Namespaces page. +# This will remove the Namespaces entry from the Quick Index +# and from the Folder Tree View (if specified). The default is YES. + +SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the program writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed +# by doxygen. The layout file controls the global structure of the generated +# output files in an output format independent way. The create the layout file +# that represents doxygen's defaults, run doxygen with the -l option. +# You can optionally specify a file name after the option, if omitted +# DoxygenLayout.xml will be used as the name of the layout file. + +LAYOUT_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# The WARN_NO_PARAMDOC option can be enabled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = @srcdir@/include/osmocom/netif @srcdir@/src + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is +# also the default input encoding. Doxygen uses libiconv (or the iconv built +# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for +# the list of possible encodings. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh +# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py +# *.f90 *.f *.for *.vhd *.vhdl + +FILE_PATTERNS = + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = NO + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or +# directories that are symbolic links (a Unix file system feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +# IMAGE_PATH = images/ + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. +# If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. +# Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. +# The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty or if +# non of the patterns match the file name, INPUT_FILTER is applied. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file +# pattern. A pattern will override the setting for FILTER_PATTERN (if any) +# and it is also possible to disable source filtering for a specific pattern +# using *.ext= (so without naming a filter). This option only has effect when +# FILTER_SOURCE_FILES is enabled. + +FILTER_SOURCE_PATTERNS = + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = YES + +# If the REFERENCES_RELATION tag is set to YES +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = YES + +# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) +# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from +# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will +# link to the source code. +# Otherwise they will link to the documentation. + +REFERENCES_LINK_SOURCE = YES + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = NO + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. Note that when using a custom header you are responsible +# for the proper inclusion of any scripts and style sheets that doxygen +# needs, which is dependent on the configuration options used. +# It is adviced to generate a default header using "doxygen -w html +# header.html footer.html stylesheet.css YourConfigFile" and then modify +# that header. Note that the header is subject to change so you typically +# have to redo this when upgrading to a newer version of doxygen or when changing the value of configuration settings such as GENERATE_TREEVIEW! + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# stylesheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = + +# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the HTML output directory. Note +# that these files will be copied to the base HTML output directory. Use the +# $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these +# files. In the HTML_STYLESHEET file, use the file name only. Also note that +# the files will be copied as-is; there are no commands or markers available. + +HTML_EXTRA_FILES = + +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. +# Doxygen will adjust the colors in the stylesheet and background images +# according to this color. Hue is specified as an angle on a colorwheel, +# see http://en.wikipedia.org/wiki/Hue for more information. +# For instance the value 0 represents red, 60 is yellow, 120 is green, +# 180 is cyan, 240 is blue, 300 purple, and 360 is red again. +# The allowed range is 0 to 359. + +HTML_COLORSTYLE_HUE = 220 + +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of +# the colors in the HTML output. For a value of 0 the output will use +# grayscales only. A value of 255 will produce the most vivid colors. + +HTML_COLORSTYLE_SAT = 100 + +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to +# the luminance component of the colors in the HTML output. Values below +# 100 gradually make the output lighter, whereas values above 100 make +# the output darker. The value divided by 100 is the actual gamma applied, +# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, +# and 100 does not change the gamma. + +HTML_COLORSTYLE_GAMMA = 80 + +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting +# this to NO can help when comparing the output of multiple runs. + +HTML_TIMESTAMP = YES + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. For this to work a browser that supports +# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox +# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). + +HTML_DYNAMIC_SECTIONS = NO + +# If the GENERATE_DOCSET tag is set to YES, additional index files +# will be generated that can be used as input for Apple's Xcode 3 +# integrated development environment, introduced with OSX 10.5 (Leopard). +# To create a documentation set, doxygen will generate a Makefile in the +# HTML output directory. Running make will produce the docset in that +# directory and running "make install" will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find +# it at startup. +# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html +# for more information. + +GENERATE_DOCSET = NO + +# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the +# feed. A documentation feed provides an umbrella under which multiple +# documentation sets from a single provider (such as a company or product suite) +# can be grouped. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that +# should uniquely identify the documentation set bundle. This should be a +# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen +# will append .docset to the name. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify +# the documentation publisher. This should be a reverse domain-name style +# string, e.g. com.mycompany.MyDocSet.documentation. + +DOCSET_PUBLISHER_ID = org.doxygen.Publisher + +# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. + +DOCSET_PUBLISHER_NAME = Publisher + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING +# is used to encode HtmlHelp index (hhk), content (hhc) and project file +# content. + +CHM_INDEX_ENCODING = + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated +# that can be used as input for Qt's qhelpgenerator to generate a +# Qt Compressed Help (.qch) of the generated HTML documentation. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can +# be used to specify the file name of the resulting .qch file. +# The path specified is relative to the HTML output folder. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#namespace + +QHP_NAMESPACE = org.doxygen.Project + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#virtual-folders + +QHP_VIRTUAL_FOLDER = doc + +# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to +# add. For more information please see +# http://doc.trolltech.com/qthelpproject.html#custom-filters + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see +# +# Qt Help Project / Custom Filters. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this +# project's +# filter section matches. +# +# Qt Help Project / Filter Attributes. + +QHP_SECT_FILTER_ATTRS = + +# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can +# be used to specify the location of Qt's qhelpgenerator. +# If non-empty doxygen will try to run qhelpgenerator on the generated +# .qhp file. + +QHG_LOCATION = + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files +# will be generated, which together with the HTML files, form an Eclipse help +# plugin. To install this plugin and make it available under the help contents +# menu in Eclipse, the contents of the directory containing the HTML and XML +# files needs to be copied into the plugins directory of eclipse. The name of +# the directory within the plugins directory should be the same as +# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before +# the help appears. + +GENERATE_ECLIPSEHELP = NO + +# A unique identifier for the eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have +# this name. + +ECLIPSE_DOC_ID = org.doxygen.Project + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values +# (range [0,1..20]) that doxygen will group on one line in the generated HTML +# documentation. Note that a value of 0 will completely suppress the enum +# values from appearing in the overview section. + +ENUM_VALUES_PER_LINE = 4 + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. +# If the tag value is set to YES, a side panel will be generated +# containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). +# Windows users are probably better off using the HTML help feature. + +GENERATE_TREEVIEW = YES + +# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, +# and Class Hierarchy pages using a tree view instead of an ordered list. + +USE_INLINE_TREES = NO + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open +# links to external symbols imported via tag files in a separate window. + +EXT_LINKS_IN_WINDOW = NO + +# Use this tag to change the font size of Latex formulas included +# as images in the HTML documentation. The default is 10. Note that +# when you change the font size after a successful doxygen run you need +# to manually remove any form_*.png images from the HTML output directory +# to force them to be regenerated. + +FORMULA_FONTSIZE = 10 + +# Use the FORMULA_TRANPARENT tag to determine whether or not the images +# generated for formulas are transparent PNGs. Transparent PNGs are +# not supported properly for IE 6.0, but are supported on all modern browsers. +# Note that when changing this option you need to delete any form_*.png files +# in the HTML output before the changes have effect. + +FORMULA_TRANSPARENT = YES + +# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax +# (see http://www.mathjax.org) which uses client side Javascript for the +# rendering instead of using prerendered bitmaps. Use this if you do not +# have LaTeX installed or if you want to formulas look prettier in the HTML +# output. When enabled you also need to install MathJax separately and +# configure the path to it using the MATHJAX_RELPATH option. + +USE_MATHJAX = NO + +# When MathJax is enabled you need to specify the location relative to the +# HTML output directory using the MATHJAX_RELPATH option. The destination +# directory should contain the MathJax.js script. For instance, if the mathjax +# directory is located at the same level as the HTML output directory, then +# MATHJAX_RELPATH should be ../mathjax. The default value points to the +# mathjax.org site, so you can quickly see the result without installing +# MathJax, but it is strongly recommended to install a local copy of MathJax +# before deployment. + +MATHJAX_RELPATH = http://www.mathjax.org/mathjax + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box +# for the HTML output. The underlying search engine uses javascript +# and DHTML and should work on any modern browser. Note that when using +# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets +# (GENERATE_DOCSET) there is already a search function so this one should +# typically be disabled. For large projects the javascript based search engine +# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. + +SEARCHENGINE = YES + +# When the SERVER_BASED_SEARCH tag is enabled the search engine will be +# implemented using a PHP enabled web server instead of at the web client +# using Javascript. Doxygen will generate the search PHP script and index +# file to put on the web server. The advantage of the server +# based approach is that it scales better to large projects and allows +# full text search. The disadvantages are that it is more difficult to setup +# and does not have live searching capabilities. + +SERVER_BASED_SEARCH = NO + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = YES + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. +# Note that when enabling USE_PDFLATEX this option is only used for +# generating bitmaps for formulas in the HTML output, but not in the +# Makefile that is written to the output directory. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4wide + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for +# the generated latex document. The footer should contain everything after +# the last chapter. If it is left blank doxygen will generate a +# standard footer. Notice: only use this tag if you know what you are doing! + +LATEX_FOOTER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = NO + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = NO + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +# If LATEX_SOURCE_CODE is set to YES then doxygen will include +# source code with syntax highlighting in the LaTeX output. +# Note that which sources are shown also depends on other settings +# such as SOURCE_BROWSER. + +LATEX_SOURCE_CODE = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. +# This is useful +# if you want to understand what is going on. +# On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_DEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# pointed to by INCLUDE_PATH will be searched when a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition that +# overrules the definition found in the source code. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all references to function-like macros +# that are alone on a line, have an all uppercase name, and do not end with a +# semicolon, because these will confuse the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen +# is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = doc/libosmo-netif.tag + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option also works with HAVE_DOT disabled, but it is recommended to +# install and use dot, since it yields more powerful graphs. + +CLASS_DIAGRAMS = YES + +# You can define message sequence charts within doxygen comments using the \msc +# command. Doxygen will then run the mscgen tool (see +# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the +# documentation. The MSCGEN_PATH tag allows you to specify the directory where +# the mscgen tool resides. If left empty the tool is assumed to be found in the +# default search path. + +MSCGEN_PATH = + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = NO + +# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is +# allowed to run in parallel. When set to 0 (the default) doxygen will +# base this on the number of processors available in the system. You can set it +# explicitly to a value larger than 0 to get control over the balance +# between CPU load and processing speed. + +DOT_NUM_THREADS = 0 + +# By default doxygen will write a font called Helvetica to the output +# directory and reference it in all dot files that doxygen generates. +# When you want a differently looking font you can specify the font name +# using DOT_FONTNAME. You need to make sure dot is able to find the font, +# which can be done by putting it in a standard location or by setting the +# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory +# containing the font. + +DOT_FONTNAME = Helvetica + +# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. +# The default size is 10pt. + +DOT_FONTSIZE = 10 + +# By default doxygen will tell dot to use the output directory to look for the +# FreeSans.ttf font (which doxygen will put there itself). If you specify a +# different font using DOT_FONTNAME you can set the path where dot +# can find it using this tag. + +DOT_FONTPATH = + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT options are set to YES then +# doxygen will generate a call dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable call graphs +# for selected functions only using the \callgraph command. + +CALL_GRAPH = NO + +# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then +# doxygen will generate a caller dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable caller +# graphs for selected functions only using the \callergraph command. + +CALLER_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will generate a graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are svg, png, jpg, or gif. +# If left blank png will be used. + +DOT_IMAGE_FORMAT = png + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = /usr/bin/dot + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The MSCFILE_DIRS tag can be used to specify one or more directories that +# contain msc files that are included in the documentation (see the +# \mscfile command). + +MSCFILE_DIRS = + +# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of +# nodes that will be shown in the graph. If the number of nodes in a graph +# becomes larger than this value, doxygen will truncate the graph, which is +# visualized by representing a node as a red box. Note that doxygen if the +# number of direct children of the root node in a graph is already larger than +# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note +# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. + +DOT_GRAPH_MAX_NODES = 50 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that the size of a graph can be further restricted by +# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, because dot on Windows does not +# seem to support this out of the box. Warning: Depending on the platform used, +# enabling this option may lead to badly anti-aliased labels on the edges of +# a graph (i.e. they become hard to read). + +DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = NO + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES diff --git a/Makefile.am b/Makefile.am index a78c523..9b1c0f1 100644 --- a/Makefile.am +++ b/Makefile.am @@ -13,3 +13,28 @@ echo $(VERSION) > $@-t && mv $@-t $@ dist-hook: echo $(VERSION) > $(distdir)/.tarball-version + + +if HAVE_DOXYGEN + +html_DATA = $(top_builddir)/doc/html.tar + +$(html_DATA): $(top_builddir)/doc/html/index.html + cd $(top_builddir)/doc && tar cf html.tar html + +$(top_builddir)/doc/html/index.html: $(SOURCES) Doxyfile + @rm -rf doc + mkdir -p doc + $(DOXYGEN) Doxyfile + +install-data-hook: + cd $(DESTDIR)$(htmldir) && tar xf html.tar && rm -f html.tar + +uninstall-hook: + rm -rf $(DESTDIR)$(htmldir) + +DX_CLEAN = doc/html/search/* doc/{html,latex}/* doc/html.tar doc/doxygen_sqlite3.db doc/*.tag + +endif + +MOSTLYCLEANFILES = $(DX_CLEAN) diff --git a/configure.ac b/configure.ac index 3994aff..8cd2238 100644 --- a/configure.ac +++ b/configure.ac @@ -63,6 +63,9 @@ AC_CHECK_HEADERS(dahdi/user.h,,AC_MSG_WARN(DAHDI input driver will not be built)) +AC_PATH_PROG(DOXYGEN,doxygen,false) +AM_CONDITIONAL(HAVE_DOXYGEN, test $DOXYGEN != false) + AC_OUTPUT( libosmo-netif.pc include/Makefile @@ -75,4 +78,5 @@ examples/Makefile examples/channel/Makefile tests/Makefile + Doxyfile Makefile) diff --git a/include/osmocom/netif/stream.h b/include/osmocom/netif/stream.h index 819f1ce..254b4c5 100644 --- a/include/osmocom/netif/stream.h +++ b/include/osmocom/netif/stream.h @@ -1,9 +1,16 @@ #ifndef _OSMO_STREAM_H_ #define _OSMO_STREAM_H_ +/*! \addtogroup stream + * @{ + */ + +/*! \brief Access the SCTP PPID from the msgb control buffer */ #define msgb_sctp_ppid(msg) (msg)->cb[3] +/*! \brief Access the SCTP Stream ID from the msgb control buffer */ #define msgb_sctp_stream(msg) (msg)->cb[4] +/*! \brief Osmocom Stream Server Link: A server socket listening/accepting */ struct osmo_stream_srv_link; struct osmo_stream_srv_link *osmo_stream_srv_link_create(void *ctx); @@ -20,6 +27,8 @@ int osmo_stream_srv_link_open(struct osmo_stream_srv_link *link); void osmo_stream_srv_link_close(struct osmo_stream_srv_link *link); +/*! \brief Osmocom Stream Server: Single connection accept()ed via \ref + * osmo_stream_srv_link */ struct osmo_stream_srv; struct osmo_stream_srv *osmo_stream_srv_create(void *ctx, struct osmo_stream_srv_link *link, int fd, int (*cb)(struct osmo_stream_srv *conn), int (*closed_cb)(struct osmo_stream_srv *conn), void *data); @@ -33,6 +42,7 @@ void osmo_stream_srv_send(struct osmo_stream_srv *conn, struct msgb *msg); int osmo_stream_srv_recv(struct osmo_stream_srv *conn, struct msgb *msg); +/*! \brief Osmocom Stream Client: Single client connection */ struct osmo_stream_cli; void osmo_stream_cli_set_addr(struct osmo_stream_cli *cli, const char *addr); @@ -56,4 +66,6 @@ void osmo_stream_cli_send(struct osmo_stream_cli *cli, struct msgb *msg); int osmo_stream_cli_recv(struct osmo_stream_cli *conn, struct msgb *msg); +/*! @} */ + #endif diff --git a/src/datagram.c b/src/datagram.c index c01ed9e..6316552 100644 --- a/src/datagram.c +++ b/src/datagram.c @@ -20,6 +20,15 @@ #include +/*! \addtogroup datagram Osmocom Datagram Socket + * @{ + */ + +/*! \file datagram.c + * \brief Osmocom datagram socket helpers + */ + + /* * Client side. */ @@ -36,6 +45,10 @@ unsigned int flags; }; +/*! \brief Close an Osmocom Datagram Transmitter + * \param[in] conn Osmocom Datagram Transmitter to be closed + * We unregister the socket fd from the osmocom select() loop + * abstraction and close the socket */ void osmo_dgram_tx_close(struct osmo_dgram_tx *conn) { osmo_fd_unregister(&conn->ofd); @@ -78,6 +91,11 @@ return 0; } +/*! \brief Create an Osmocom datagram transmitter + * \param[in] ctx talloc context from which to allocate memory + * This function allocates a new \ref osmo_dgram_tx and initializes + * it with default values + * \returns Osmocom Datagram Transmitter; NULL on error */ struct osmo_dgram_tx *osmo_dgram_tx_create(void *crx) { struct osmo_dgram_tx *conn; @@ -96,6 +114,10 @@ return conn; } + +/*! \brief Set the remote address to which we transmit + * \param[in] conn Datagram Transmitter to modify + * \param[in] addr Remote IP address */ void osmo_dgram_tx_set_addr(struct osmo_dgram_tx *conn, const char *addr) @@ -107,6 +129,9 @@ conn->flags |= OSMO_DGRAM_CLI_F_RECONF; } +/*! \brief Set the remote port to which we transmit + * \param[in] conn Datagram Transmitter to modify + * \param[in] port Remote Port Number */ void osmo_dgram_tx_set_port(struct osmo_dgram_tx *conn, uint16_t port) @@ -115,17 +140,25 @@ conn->flags |= OSMO_DGRAM_CLI_F_RECONF; } +/*! \brief Set application private data of the datagram transmitter + * \param[in] conn Datagram Transmitter to modify + * \param[in] data User-specific data (available in call-back functions) */ void osmo_dgram_tx_set_data(struct osmo_dgram_tx *conn, void *data) { conn->data = data; } +/*! \brief Destroy a Osmocom datagram transmitter + * \param[in] conn Datagram Transmitter to destroy */ void osmo_dgram_tx_destroy(struct osmo_dgram_tx *conn) { talloc_free(conn); } +/*! \brief Open connection of an Osmocom datagram transmitter + * \param[in] conn Stream Client to connect + * \returns 0 on success; negative in case of error */ int osmo_dgram_tx_open(struct osmo_dgram_tx *conn) { int ret; @@ -150,6 +183,9 @@ return 0; } +/*! \brief Enqueue data to be sent via an Osmocom datagram transmitter + * \param[in] conn Datagram Transmitter through which we want to send + * \param[in] msg Message buffer to enqueue in transmit queue */ void osmo_dgram_tx_send(struct osmo_dgram_tx *conn, struct msgb *msg) { @@ -172,6 +208,10 @@ unsigned int flags; }; +/*! \brief Receive data via Osmocom datagram receiver + * \param[in] conn Datagram Receiver from which to receive + * \param msg pre-allocate message buffer to which received data is appended + * \returns number of bytes read, negative on error. */ int osmo_dgram_rx_recv(struct osmo_dgram_rx *conn, struct msgb *msg) { @@ -206,6 +246,11 @@ return 0; } +/*! \brief Create an Osmocom datagram receiver + * \param[in] ctx talloc context from which to allocate memory + * This function allocates a new \ref osmo_dgram_rx and initializes + * it with default values + * \returns Datagram Receiver; NULL on error */ struct osmo_dgram_rx *osmo_dgram_rx_create(void *crx) { struct osmo_dgram_rx *conn; @@ -222,6 +267,9 @@ return conn; } +/*! \brief Set the local address to which we bind + * \param[in] conn Datagram Receiver to modify + * \param[in] addr Local IP address */ void osmo_dgram_rx_set_addr(struct osmo_dgram_rx *conn, const char *addr) { @@ -232,6 +280,9 @@ conn->flags |= OSMO_DGRAM_RX_F_RECONF; } +/*! \brief Set the local port to which we bind + * \param[in] conn Datagram Receiver to modify + * \param[in] port Local port number */ void osmo_dgram_rx_set_port(struct osmo_dgram_rx *conn, uint16_t port) { @@ -239,17 +290,26 @@ conn->flags |= OSMO_DGRAM_RX_F_RECONF; } +/*! \brief Set the read() call-back of the datagram receiver + * \param[in] conn Datagram Receiver to modify + * \param[in] read_cb Call-back function executed after read() */ void osmo_dgram_rx_set_read_cb(struct osmo_dgram_rx *conn, int (*read_cb)(struct osmo_dgram_rx *conn)) { conn->cb = read_cb; } +/*! \brief Destroy the datagram receiver. Releases Memory. + * Caller must make sure to osmo_dgram_rx_close() before calling + * \param[in] conn Datagram Receiver */ void osmo_dgram_rx_destroy(struct osmo_dgram_rx *conn) { talloc_free(conn); } +/*! \brief Open the datagram receiver. This actually initializes the + * underlying socket and binds it to the configured ip/port + * \param[in] conn Datagram Receiver to open */ int osmo_dgram_rx_open(struct osmo_dgram_rx *conn) { int ret; @@ -273,6 +333,10 @@ return 0; } + +/*! \brief Close the datagram receiver and unregister from select loop + * Does not destroy the datagram receiver, merely closes it! + * \param[in] conn Stream Server Link to close */ void osmo_dgram_rx_close(struct osmo_dgram_rx *conn) { osmo_fd_unregister(&conn->ofd); @@ -301,6 +365,13 @@ return 0; } + +/*! \brief Create an Osmocom datagram transceiver (bidirectional) + * \param[in] ctx talloc context from which to allocate memory + * This function allocates a new \ref osmo_dgram and initializes + * it with default values. Internally, the Transceiver is based on a + * tuple of transmitter (\ref osmo_dgram_tx) and receiver (\ref osmo_dgram_rx) + * \returns Osmocom Datagram Transceiver; NULL on error */ struct osmo_dgram *osmo_dgram_create(void *crx) { struct osmo_dgram *conn; @@ -325,52 +396,78 @@ return conn; } +/*! \brief Destroy a Osmocom datagram transceiver + * \param[in] conn Datagram Transceiver to destroy */ void osmo_dgram_destroy(struct osmo_dgram *conn) { osmo_dgram_rx_destroy(conn->rx); osmo_dgram_tx_destroy(conn->tx); } +/*! \brief Set the local address to which we bind + * \param[in] conn Datagram Transceiver to modify + * \param[in] addr Local IP address */ void osmo_dgram_set_local_addr(struct osmo_dgram *conn, const char *addr) { osmo_dgram_rx_set_addr(conn->rx, addr); } +/*! \brief Set the remote address to which we transmit/connect + * \param[in] conn Datagram Transceiver to modify + * \param[in] addr Remote IP address */ void osmo_dgram_set_remote_addr(struct osmo_dgram *conn, const char *addr) { osmo_dgram_tx_set_addr(conn->tx, addr); } +/*! \brief Set the local port to which we bind + * \param[in] conn Datagram Transceiver to modify + * \param[in] port Local Port Number */ void osmo_dgram_set_local_port(struct osmo_dgram *conn, uint16_t port) { osmo_dgram_rx_set_port(conn->rx, port); } +/*! \brief Set the remote port to which we transmit + * \param[in] conn Datagram Transceiver to modify + * \param[in] port Remote Port Number */ void osmo_dgram_set_remote_port(struct osmo_dgram *conn, uint16_t port) { osmo_dgram_tx_set_port(conn->tx, port); } +/*! \brief Set the read() call-back of the datagram receiver + * \param[in] conn Datagram Receiver to modify + * \param[in] read_cb Call-back function executed after read() */ void osmo_dgram_set_read_cb(struct osmo_dgram *conn, int (*read_cb)(struct osmo_dgram *conn)) { conn->read_cb = read_cb; } +/*! \brief Set application private data of the datagram transmitter + * \param[in] conn Datagram Transmitter to modify + * \param[in] data User-specific data (available in call-back functions) */ void osmo_dgram_set_data(struct osmo_dgram *conn, void *data) { conn->data = data; } +/*! \brief Get application private data of the datagram transceiver + * \param[in] conn Datagram Transceiver + * \returns Application private data, as set by \ref osmo_dgram_set_data() */ void *osmo_dgram_get_data(struct osmo_dgram *conn) { return conn->data; } +/*! \brief Open the datagram transceiver. This actually initializes the + * underlying sockets and binds/connects them to the configured ips/ports + * \param[in] conn Datagram Transceiver to open */ int osmo_dgram_open(struct osmo_dgram *conn) { int ret; @@ -387,18 +484,31 @@ return ret; } +/*! \brief Close an Osmocom Datagram Transceiver + * \param[in] conn Osmocom Datagram Transceiver to be closed + * We unregister the socket fds from the osmocom select() loop + * and close them. */ void osmo_dgram_close(struct osmo_dgram *conn) { osmo_dgram_rx_close(conn->rx); osmo_dgram_tx_close(conn->tx); } +/*! \brief Enqueue data to be sent via an Osmocom datagram transceiver + * \param[in] conn Datagram Transceiver through which we want to send + * \param[in] msg Message buffer to enqueue in transmit queue */ void osmo_dgram_send(struct osmo_dgram *conn, struct msgb *msg) { osmo_dgram_tx_send(conn->tx, msg); } +/*! \brief Receive data via Osmocom datagram transceiver + * \param[in] conn Datagram Transceiver from which to receive + * \param msg pre-allocate message buffer to which received data is appended + * \returns number of bytes read, negative on error. */ int osmo_dgram_recv(struct osmo_dgram *conn, struct msgb *msg) { return osmo_dgram_rx_recv(conn->rx, msg); } + +/*! @} */ diff --git a/src/stream.c b/src/stream.c index 6b8bc95..e71e420 100644 --- a/src/stream.c +++ b/src/stream.c @@ -26,6 +26,14 @@ #include #endif +/*! \addtogroup stream Osmocom Stream Socket + * @{ + */ + +/*! \file stream.c + * \brief Osmocom stream socket helpers + */ + /* * Platforms that don't have MSG_NOSIGNAL (which disables SIGPIPE) * usually have SO_NOSIGPIPE (set via setsockopt). @@ -74,6 +82,7 @@ enum osmo_stream_cli_state state; const char *addr; uint16_t port; + uint16_t local_port; uint16_t proto; int (*connect_cb)(struct osmo_stream_cli *srv); int (*read_cb)(struct osmo_stream_cli *srv); @@ -85,6 +94,9 @@ void osmo_stream_cli_close(struct osmo_stream_cli *cli); +/*! \brief Re-connect an Osmocom Stream Client + * If re-connection is enabled for this client, we close any existing + * connection (if any) and schedule a re-connect timer */ void osmo_stream_cli_reconnect(struct osmo_stream_cli *cli) { if (cli->reconnect_timeout < 0) { @@ -99,6 +111,10 @@ cli->state = STREAM_CLI_STATE_CONNECTING; } +/*! \brief Close an Osmocom Stream Client + * \param[in] cli Osmocom Stream Client to be closed + * We unregister the socket fd from the osmocom select() loop + * abstraction and close the socket */ void osmo_stream_cli_close(struct osmo_stream_cli *cli) { if (cli->ofd.fd == -1) @@ -212,6 +228,10 @@ static void cli_timer_cb(void *data); +/*! \brief Create an Osmocom stream client + * \param[in] ctx talloc context from which to allocate memory + * This function allocates a new \ref osmo_stream_cli and initializes + * it with default values (5s reconnect timer, TCP protocol) */ struct osmo_stream_cli *osmo_stream_cli_create(void *ctx) { struct osmo_stream_cli *cli; @@ -235,6 +255,10 @@ return cli; } +/*! \brief Set the remote address to which we connect + * \param[in] cli Stream Client to modify + * \param[in] addr Remote IP address + */ void osmo_stream_cli_set_addr(struct osmo_stream_cli *cli, const char *addr) { @@ -242,6 +266,10 @@ cli->flags |= OSMO_STREAM_CLI_F_RECONF; } +/*! \brief Set the remote port number to which we connect + * \param[in] cli Stream Client to modify + * \param[in] port Remote port number + */ void osmo_stream_cli_set_port(struct osmo_stream_cli *cli, uint16_t port) { @@ -249,6 +277,21 @@ cli->flags |= OSMO_STREAM_CLI_F_RECONF; } +/*! \brief Set the local port number for the socket + * \param[in] cli Stream Client to modify + * \param[in] port Local port number + */ +void +osmo_stream_cli_set_local_port(struct osmo_stream_cli *cli, uint16_t port) +{ + cli->local_port = port; + cli->flags |= OSMO_STREAM_CLI_F_RECONF; +} + +/*! \brief Set the protocol for the stream client socket + * \param[in] cli Stream Client to modify + * \param[in] proto Protocol (like IPPROTO_TCP (default), IPPROTO_SCTP, ...) + */ void osmo_stream_cli_set_proto(struct osmo_stream_cli *cli, uint16_t proto) { @@ -256,29 +299,44 @@ cli->flags |= OSMO_STREAM_CLI_F_RECONF; } +/*! \brief Set the reconnect time of the stream client socket + * \param[in] cli Stream Client to modify + * \param[in] timeout Re-connect timeout in seconds */ void osmo_stream_cli_set_reconnect_timeout(struct osmo_stream_cli *cli, int timeout) { cli->reconnect_timeout = timeout; } +/*! \brief Set application private data of the stream client socket + * \param[in] cli Stream Client to modify + * \param[in] data User-specific data (available in call-back functions) */ void osmo_stream_cli_set_data(struct osmo_stream_cli *cli, void *data) { cli->data = data; } +/*! \brief Get application private data of the stream client socket + * \param[in] cli Stream Client to modif + * \returns Application private data, as set by \ref osmo_stream_cli_set_data() */ void *osmo_stream_cli_get_data(struct osmo_stream_cli *cli) { return cli->data; } +/*! \brief Get Osmocom File Descriptor of the stream client socket + * \param[in] cli Stream Client to modif + * \returns Pointer to \ref osmo_fd */ struct osmo_fd * osmo_stream_cli_get_ofd(struct osmo_stream_cli *cli) { return &cli->ofd; } +/*! \brief Set the call-back function called on connect of the stream client socket + * \param[in] cli Stream Client to modif + * \param[in] connect_cb Call-back function to be called upon connect */ void osmo_stream_cli_set_connect_cb(struct osmo_stream_cli *cli, int (*connect_cb)(struct osmo_stream_cli *cli)) @@ -286,6 +344,9 @@ cli->connect_cb = connect_cb; } +/*! \brief Set the call-back function called to read from the stream client socket + * \param[in] cli Stream Client to modif + * \param[in] read_cb Call-back function to be called when we want to read */ void osmo_stream_cli_set_read_cb(struct osmo_stream_cli *cli, int (*read_cb)(struct osmo_stream_cli *cli)) @@ -293,12 +354,18 @@ cli->read_cb = read_cb; } +/*! \brief Destroy a Osmocom stream client + * \param[in] cli Stream Client to destroy */ void osmo_stream_cli_destroy(struct osmo_stream_cli *cli) { osmo_timer_del(&cli->timer); talloc_free(cli); } +/*! \brief Open connection of an Osmocom stream client + * \param[in] cli Stream Client to connect + * \param[in] reconect 1 if we should not automatically reconnect + */ int osmo_stream_cli_open2(struct osmo_stream_cli *cli, int reconnect) { int ret; @@ -327,6 +394,8 @@ } +/*! \brief Open connection of an Osmocom stream client + * \param[in] cli Stream Client to connect */ int osmo_stream_cli_open(struct osmo_stream_cli *cli) { return osmo_stream_cli_open2(cli, 0); @@ -348,12 +417,19 @@ } } +/*! \brief Enqueue data to be sent via an Osmocom stream client + * \param[in] cli Stream Client through which we want to send + * \param[in] msg Message buffer to enqueue in transmit queue */ void osmo_stream_cli_send(struct osmo_stream_cli *cli, struct msgb *msg) { msgb_enqueue(&cli->tx_queue, msg); cli->ofd.when |= BSC_FD_WRITE; } +/*! \brief Receive data via an Osmocom stream client + * \param[in] cli Stream Client through which we want to send + * \param msg pre-allocate message buffer to which received data is appended + * \returns number of bytes read; <=0 in case of error */ int osmo_stream_cli_recv(struct osmo_stream_cli *cli, struct msgb *msg) { int ret; @@ -417,6 +493,12 @@ return 0; } +/*! \brief Create an Osmocom Stream Server Link + * A Stream Server Link is the listen()+accept() "parent" to individual + * Stream Servers + * \param[in] ctx talloc allocation context + * \returns Stream Server Link with default values (TCP) + */ struct osmo_stream_srv_link *osmo_stream_srv_link_create(void *ctx) { struct osmo_stream_srv_link *link; @@ -434,6 +516,10 @@ return link; } +/*! \brief Set the local address to which we bind + * \param[in] link Stream Server Link to modify + * \param[in] addr Local IP address + */ void osmo_stream_srv_link_set_addr(struct osmo_stream_srv_link *link, const char *addr) { @@ -441,6 +527,10 @@ link->flags |= OSMO_STREAM_SRV_F_RECONF; } +/*! \brief Set the local port number to which we bind + * \param[in] link Stream Server Link to modify + * \param[in] port Local port number + */ void osmo_stream_srv_link_set_port(struct osmo_stream_srv_link *link, uint16_t port) { @@ -448,6 +538,10 @@ link->flags |= OSMO_STREAM_SRV_F_RECONF; } +/*! \brief Set the protocol for the stream server link + * \param[in] link Stream Server Link to modify + * \param[in] proto Protocol (like IPPROTO_TCP (default), IPPROTO_SCTP, ...) + */ void osmo_stream_srv_link_set_proto(struct osmo_stream_srv_link *link, uint16_t proto) @@ -456,6 +550,9 @@ link->flags |= OSMO_STREAM_SRV_F_RECONF; } +/*! \brief Set application private data of the stream server link + * \param[in] link Stream Server Link to modify + * \param[in] data User-specific data (available in call-back functions) */ void osmo_stream_srv_link_set_data(struct osmo_stream_srv_link *link, void *data) @@ -463,17 +560,26 @@ link->data = data; } +/*! \brief Get application private data of the stream server link + * \param[in] link Stream Server Link to modify + * \returns Application private data, as set by \ref osmo_stream_cli_set_data() */ void *osmo_stream_srv_link_get_data(struct osmo_stream_srv_link *link) { return link->data; } +/*! \brief Get Osmocom File Descriptor of the stream server link + * \param[in] link Stream Server Link + * \returns Pointer to \ref osmo_fd */ struct osmo_fd * osmo_stream_srv_link_get_ofd(struct osmo_stream_srv_link *link) { return &link->ofd; } +/*! \brief Set the accept() call-back of the stream server link + * \param[in] link Stream Server Link + * \param[in] accept_cb Call-back function executed upon accept() */ void osmo_stream_srv_link_set_accept_cb(struct osmo_stream_srv_link *link, int (*accept_cb)(struct osmo_stream_srv_link *link, int fd)) @@ -481,11 +587,17 @@ link->accept_cb = accept_cb; } +/*! \brief Destroy the stream server link. Releases Memory. + * Caller must make sure to osmo_stream_srv_link_close() before calling + * \param[in] link Stream Server Link */ void osmo_stream_srv_link_destroy(struct osmo_stream_srv_link *link) { talloc_free(link); } +/*! \brief Open the stream server link. This actually initializes the + * underlying socket and binds it to the configured ip/port + * \param[in] link Stream Server Link to open */ int osmo_stream_srv_link_open(struct osmo_stream_srv_link *link) { int ret; @@ -509,6 +621,9 @@ return 0; } +/*! \brief Close the stream server link and unregister from select loop + * Does not destroy the server link, merely closes it! + * \param[in] link Stream Server Link to close */ void osmo_stream_srv_link_close(struct osmo_stream_srv_link *link) { if (link->ofd.fd == -1) @@ -590,6 +705,10 @@ return 0; } +/*! \brief Create a Stream Server inside the specified link + * \param[in] ctx talloc allocation context from which to allocate + * \param[in] link Stream Server Link to which we belong + * \returns Stream Server in case of success; NULL on error */ struct osmo_stream_srv * osmo_stream_srv_create(void *ctx, struct osmo_stream_srv_link *link, int fd, @@ -622,6 +741,9 @@ return conn; } +/*! \brief Set application private data of the stream server + * \param[in] conn Stream Server to modify + * \param[in] data User-specific data (available in call-back functions) */ void osmo_stream_srv_set_data(struct osmo_stream_srv *conn, void *data) @@ -629,22 +751,35 @@ conn->data = data; } -void *osmo_stream_srv_get_data(struct osmo_stream_srv *link) +/*! \brief Get application private data of the stream server + * \param[in] conn Stream Server + * \returns Application private data, as set by \ref osmo_stream_srv_set_data() */ +void *osmo_stream_srv_get_data(struct osmo_stream_srv *conn) { - return link->data; + return conn->data; } +/*! \brief Get Osmocom File Descriptor of the stream server + * \param[in] conn Stream Server + * \returns Pointer to \ref osmo_fd */ struct osmo_fd * -osmo_stream_srv_get_ofd(struct osmo_stream_srv *link) +osmo_stream_srv_get_ofd(struct osmo_stream_srv *conn) { - return &link->ofd; + return &conn->ofd; } +/*! \brief Get the master (Link) from a Stream Server + * \param[in] conn Stream Server of which we want to know the Link + * \returns Link through which the given Stream Server is established */ struct osmo_stream_srv_link *osmo_stream_srv_get_master(struct osmo_stream_srv *conn) { return conn->srv; } +/*! \brief Destroy given Stream Server + * This function closes the Stream Server socket, unregisters from + * select loop and de-allocates associated memory. + * \param[in] conn Stream Server to be destroyed */ void osmo_stream_srv_destroy(struct osmo_stream_srv *conn) { close(conn->ofd.fd); @@ -654,12 +789,20 @@ talloc_free(conn); } +/*! \brief Enqueue data to be sent via an Osmocom stream server + * \param[in] conn Stream Server through which we want to send + * \param[in] msg Message buffer to enqueue in transmit queue */ void osmo_stream_srv_send(struct osmo_stream_srv *conn, struct msgb *msg) { msgb_enqueue(&conn->tx_queue, msg); conn->ofd.when |= BSC_FD_WRITE; } +/*! \brief Receive data via Osmocom stream server + * \param[in] conn Stream Server from which to receive + * \param msg pre-allocate message buffer to which received data is appended + * \returns number of bytes read, negative on error. + */ int osmo_stream_srv_recv(struct osmo_stream_srv *conn, struct msgb *msg) { #ifdef HAVE_LIBSCTP @@ -735,3 +878,5 @@ LOGP(DLINP, LOGL_DEBUG, "received %d bytes from client\n", ret); return ret; } + +/*! @} */ -- To view, visit https://gerrit.osmocom.org/2248 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I589a5e60d9df2b8a65fbaf68f80e3ae0039d8c2a Gerrit-PatchSet: 1 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sat Apr 8 19:55:07 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 8 Apr 2017 19:55:07 +0000 Subject: [MERGED] libosmo-netif[master]: doc: Add Doxygen group for OSMUX related functions In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: doc: Add Doxygen group for OSMUX related functions ...................................................................... doc: Add Doxygen group for OSMUX related functions Change-Id: I87e08bd84236ae5d5c057bca96d122e568a6b52a --- M include/osmocom/netif/osmux.h M src/osmux.c 2 files changed, 21 insertions(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/include/osmocom/netif/osmux.h b/include/osmocom/netif/osmux.h index 83bb2e1..1d93aa0 100644 --- a/include/osmocom/netif/osmux.h +++ b/include/osmocom/netif/osmux.h @@ -3,6 +3,14 @@ #include +/*! \addtogroup osmux + * @{ + */ + +/*! \file osmux.h + * Osmocom multiplex protocol helpers + */ + /* OSmux header: * * ft (3 bits): 0=signalling, 1=voice, 2=dummy @@ -95,4 +103,6 @@ void osmux_tx_sched(struct llist_head *list, void (*tx_cb)(struct msgb *msg, void *data), void *data); +/*! @} */ + #endif diff --git a/src/osmux.c b/src/osmux.c index 913d68f..5655269 100644 --- a/src/osmux.c +++ b/src/osmux.c @@ -23,6 +23,15 @@ #include +/*! \addtogroup osmux Osmocom Multiplex Protocol + * @{ + */ + +/*! \file osmux.c + * \brief Osmocom multiplex protocol helpers + */ + + /* This allows you to debug timing reconstruction in the output path */ #if 0 #define DEBUG_TIMING 0 @@ -921,3 +930,5 @@ return offset; } + +/*! @} */ -- To view, visit https://gerrit.osmocom.org/2249 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I87e08bd84236ae5d5c057bca96d122e568a6b52a Gerrit-PatchSet: 1 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sat Apr 8 20:20:47 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 8 Apr 2017 20:20:47 +0000 Subject: [PATCH] libosmo-netif[master]: stream+datagram: Allow local bind + connect for client sockets Message-ID: Review at https://gerrit.osmocom.org/2251 stream+datagram: Allow local bind + connect for client sockets This uses the new osmo_sock_init2() features introduced in libosmocore Change-Id Idab124bcca47872f55311a82d6818aed590965e6 to bind *and* connect a given socket during creation. Change-Id: I013f4cc10b26d332d52d231f252bb0f03df8c54b --- M include/osmocom/netif/datagram.h M include/osmocom/netif/stream.h M src/datagram.c M src/stream.c 4 files changed, 48 insertions(+), 7 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-netif refs/changes/51/2251/1 diff --git a/include/osmocom/netif/datagram.h b/include/osmocom/netif/datagram.h index 33d3d30..b7ecfe3 100644 --- a/include/osmocom/netif/datagram.h +++ b/include/osmocom/netif/datagram.h @@ -8,6 +8,8 @@ void osmo_dgram_tx_set_addr(struct osmo_dgram_tx *conn, const char *addr); void osmo_dgram_tx_set_port(struct osmo_dgram_tx *conn, uint16_t port); +void osmo_dgram_tx_set_local_addr(struct osmo_dgram_tx *conn, const char *addr); +void osmo_dgram_tx_set_local_port(struct osmo_dgram_tx *conn, uint16_t port); void osmo_dgram_tx_set_data(struct osmo_dgram_tx *conn, void *data); int osmo_dgram_tx_open(struct osmo_dgram_tx *conn); diff --git a/include/osmocom/netif/stream.h b/include/osmocom/netif/stream.h index 254b4c5..63eccf8 100644 --- a/include/osmocom/netif/stream.h +++ b/include/osmocom/netif/stream.h @@ -48,6 +48,8 @@ void osmo_stream_cli_set_addr(struct osmo_stream_cli *cli, const char *addr); void osmo_stream_cli_set_port(struct osmo_stream_cli *cli, uint16_t port); void osmo_stream_cli_set_proto(struct osmo_stream_cli *cli, uint16_t proto); +void osmo_stream_cli_set_local_addr(struct osmo_stream_cli *cli, const char *addr); +void osmo_stream_cli_set_local_port(struct osmo_stream_cli *cli, uint16_t port); void osmo_stream_cli_set_data(struct osmo_stream_cli *cli, void *data); void osmo_stream_cli_set_reconnect_timeout(struct osmo_stream_cli *cli, int timeout); void *osmo_stream_cli_get_data(struct osmo_stream_cli *cli); diff --git a/src/datagram.c b/src/datagram.c index 6316552..cb2a64f 100644 --- a/src/datagram.c +++ b/src/datagram.c @@ -12,6 +12,7 @@ #include #include +#include #include #include #include @@ -40,6 +41,8 @@ struct llist_head tx_queue; const char *addr; uint16_t port; + char *local_addr; + uint16_t local_port; int (*write_cb)(struct osmo_dgram_tx *conn); void *data; unsigned int flags; @@ -140,6 +143,26 @@ conn->flags |= OSMO_DGRAM_CLI_F_RECONF; } +/*! \brief Set the local address from which we transmit + * \param[in] conn Datagram Transmitter to modify + * \param[in] addr Local IP address */ +void +osmo_dgram_tx_set_local_addr(struct osmo_dgram_tx *conn, const char *addr) +{ + osmo_talloc_replace_string(conn, &conn->local_addr, addr); + conn->flags |= OSMO_DGRAM_CLI_F_RECONF; +} + +/*! \brief Set the local port from which we transmit + * \param[in] conn Datagram Transmitter to modify + * \param[in] port Local Port Number */ +void +osmo_dgram_tx_set_local_port(struct osmo_dgram_tx *conn, uint16_t port) +{ + conn->local_port = port; + conn->flags |= OSMO_DGRAM_CLI_F_RECONF; +} + /*! \brief Set application private data of the datagram transmitter * \param[in] conn Datagram Transmitter to modify * \param[in] data User-specific data (available in call-back functions) */ @@ -169,9 +192,9 @@ conn->flags &= ~OSMO_DGRAM_CLI_F_RECONF; - ret = osmo_sock_init(AF_INET, SOCK_DGRAM, IPPROTO_UDP, - conn->addr, conn->port, - OSMO_SOCK_F_CONNECT|OSMO_SOCK_F_NONBLOCK); + ret = osmo_sock_init2(AF_INET, SOCK_DGRAM, IPPROTO_UDP, + conn->local_addr, conn->local_port, conn->addr, conn->port, + OSMO_SOCK_F_BIND|OSMO_SOCK_F_CONNECT|OSMO_SOCK_F_NONBLOCK); if (ret < 0) return ret; diff --git a/src/stream.c b/src/stream.c index e71e420..52521d7 100644 --- a/src/stream.c +++ b/src/stream.c @@ -12,6 +12,7 @@ #include #include +#include #include #include #include @@ -82,6 +83,7 @@ enum osmo_stream_cli_state state; const char *addr; uint16_t port; + char *local_addr; uint16_t local_port; uint16_t proto; int (*connect_cb)(struct osmo_stream_cli *srv); @@ -277,7 +279,7 @@ cli->flags |= OSMO_STREAM_CLI_F_RECONF; } -/*! \brief Set the local port number for the socket +/*! \brief Set the local port number for the socket (to be bound to) * \param[in] cli Stream Client to modify * \param[in] port Local port number */ @@ -285,6 +287,17 @@ osmo_stream_cli_set_local_port(struct osmo_stream_cli *cli, uint16_t port) { cli->local_port = port; + cli->flags |= OSMO_STREAM_CLI_F_RECONF; +} + +/*! \brief Set the local address for the socket (to be bound to) + * \param[in] cli Stream Client to modify + * \param[in] port Local host name + */ +void +osmo_stream_cli_set_local_addr(struct osmo_stream_cli *cli, const char *addr) +{ + osmo_talloc_replace_string(cli, &cli->local_addr, addr); cli->flags |= OSMO_STREAM_CLI_F_RECONF; } @@ -376,9 +389,10 @@ cli->flags &= ~OSMO_STREAM_CLI_F_RECONF; - ret = osmo_sock_init(AF_INET, SOCK_STREAM, cli->proto, - cli->addr, cli->port, - OSMO_SOCK_F_CONNECT); + ret = osmo_sock_init2(AF_INET, SOCK_STREAM, cli->proto, + cli->local_addr, cli->local_port, + cli->addr, cli->port, + OSMO_SOCK_F_CONNECT|OSMO_SOCK_F_BIND); if (ret < 0) { if (reconnect && errno == ECONNREFUSED) osmo_stream_cli_reconnect(cli); -- To view, visit https://gerrit.osmocom.org/2251 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I013f4cc10b26d332d52d231f252bb0f03df8c54b Gerrit-PatchSet: 1 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Sat Apr 8 20:20:48 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 8 Apr 2017 20:20:48 +0000 Subject: [PATCH] libosmo-netif[master]: stream/datagram: Consistently use osmo_talloc_replace_string() Message-ID: Review at https://gerrit.osmocom.org/2252 stream/datagram: Consistently use osmo_talloc_replace_string() during osmo_*_set_addr(), we must make sure to talloc_free() any old address before copying in the new address. Not all functions did this, and those that did implemented it manually. Let's use osmo_talloc_replace_string() which is exactly intended for this case. Change-Id: Ie1b140a160c66e8b62c745174865d5ba525cb2c2 --- M src/datagram.c M src/stream.c 2 files changed, 8 insertions(+), 14 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-netif refs/changes/52/2252/1 diff --git a/src/datagram.c b/src/datagram.c index cb2a64f..13f1b5c 100644 --- a/src/datagram.c +++ b/src/datagram.c @@ -39,7 +39,7 @@ struct osmo_dgram_tx { struct osmo_fd ofd; struct llist_head tx_queue; - const char *addr; + char *addr; uint16_t port; char *local_addr; uint16_t local_port; @@ -125,10 +125,7 @@ osmo_dgram_tx_set_addr(struct osmo_dgram_tx *conn, const char *addr) { - if (conn->addr != NULL) - talloc_free((void *)conn->addr); - - conn->addr = talloc_strdup(conn, addr); + osmo_talloc_replace_string(conn, &conn->addr, addr); conn->flags |= OSMO_DGRAM_CLI_F_RECONF; } @@ -224,7 +221,7 @@ struct osmo_dgram_rx { struct osmo_fd ofd; - const char *addr; + char *addr; uint16_t port; int (*cb)(struct osmo_dgram_rx *conn); void *data; @@ -296,10 +293,7 @@ void osmo_dgram_rx_set_addr(struct osmo_dgram_rx *conn, const char *addr) { - if (conn->addr != NULL) - talloc_free((void *)conn->addr); - - conn->addr = talloc_strdup(conn, addr); + osmo_talloc_replace_string(conn, &conn->addr, addr); conn->flags |= OSMO_DGRAM_RX_F_RECONF; } diff --git a/src/stream.c b/src/stream.c index 52521d7..7bac1cc 100644 --- a/src/stream.c +++ b/src/stream.c @@ -81,7 +81,7 @@ struct llist_head tx_queue; struct osmo_timer_list timer; enum osmo_stream_cli_state state; - const char *addr; + char *addr; uint16_t port; char *local_addr; uint16_t local_port; @@ -264,7 +264,7 @@ void osmo_stream_cli_set_addr(struct osmo_stream_cli *cli, const char *addr) { - cli->addr = talloc_strdup(cli, addr); + osmo_talloc_replace_string(cli, &cli->addr, addr); cli->flags |= OSMO_STREAM_CLI_F_RECONF; } @@ -474,7 +474,7 @@ struct osmo_stream_srv_link { struct osmo_fd ofd; - const char *addr; + char *addr; uint16_t port; uint16_t proto; int (*accept_cb)(struct osmo_stream_srv_link *srv, int fd); @@ -537,7 +537,7 @@ void osmo_stream_srv_link_set_addr(struct osmo_stream_srv_link *link, const char *addr) { - link->addr = talloc_strdup(link, addr); + osmo_talloc_replace_string(link, &link->addr, addr); link->flags |= OSMO_STREAM_SRV_F_RECONF; } -- To view, visit https://gerrit.osmocom.org/2252 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ie1b140a160c66e8b62c745174865d5ba525cb2c2 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Sat Apr 8 20:20:48 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 8 Apr 2017 20:20:48 +0000 Subject: [PATCH] libosmo-netif[master]: stream/datagram: Ensure reliable close/destroy Message-ID: Review at https://gerrit.osmocom.org/2253 stream/datagram: Ensure reliable close/destroy * when using osmo_*_destroy(), always call *_close() internally to make sure we don't free memory holding references to sockets that are still open * when closing the socket, always make sure to set the fd to -1 in all cases, to avoid attempts to avoid later close() on a new file using the same fd number as the socket closed previously. Change-Id: I29c37da6e8f5be8ab030e68952a8f92add146821 --- M src/datagram.c M src/stream.c 2 files changed, 16 insertions(+), 4 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-netif refs/changes/53/2253/1 diff --git a/src/datagram.c b/src/datagram.c index 13f1b5c..d98221f 100644 --- a/src/datagram.c +++ b/src/datagram.c @@ -54,8 +54,11 @@ * abstraction and close the socket */ void osmo_dgram_tx_close(struct osmo_dgram_tx *conn) { + if (conn->ofd.fd == -1) + return; osmo_fd_unregister(&conn->ofd); close(conn->ofd.fd); + conn->ofd.fd = -1; } static int osmo_dgram_tx_write(struct osmo_dgram_tx *conn) @@ -173,6 +176,7 @@ * \param[in] conn Datagram Transmitter to destroy */ void osmo_dgram_tx_destroy(struct osmo_dgram_tx *conn) { + osmo_dgram_tx_close(conn); talloc_free(conn); } @@ -198,6 +202,7 @@ conn->ofd.fd = ret; if (osmo_fd_register(&conn->ofd) < 0) { close(ret); + conn->ofd.fd = -1; return -EIO; } return 0; @@ -317,10 +322,10 @@ } /*! \brief Destroy the datagram receiver. Releases Memory. - * Caller must make sure to osmo_dgram_rx_close() before calling * \param[in] conn Datagram Receiver */ void osmo_dgram_rx_destroy(struct osmo_dgram_rx *conn) { + osmo_dgram_rx_close(conn); talloc_free(conn); } @@ -345,6 +350,7 @@ conn->ofd.fd = ret; if (osmo_fd_register(&conn->ofd) < 0) { close(ret); + conn->ofd.fd = -1; return -EIO; } return 0; @@ -356,8 +362,11 @@ * \param[in] conn Stream Server Link to close */ void osmo_dgram_rx_close(struct osmo_dgram_rx *conn) { + if (conn->ofd.fd == -1) + return; osmo_fd_unregister(&conn->ofd); close(conn->ofd.fd); + conn->ofd.fd = -1; } /* diff --git a/src/stream.c b/src/stream.c index 7bac1cc..f899a41 100644 --- a/src/stream.c +++ b/src/stream.c @@ -367,10 +367,11 @@ cli->read_cb = read_cb; } -/*! \brief Destroy a Osmocom stream client +/*! \brief Destroy a Osmocom stream client (includes close) * \param[in] cli Stream Client to destroy */ void osmo_stream_cli_destroy(struct osmo_stream_cli *cli) { + osmo_stream_cli_close(cli); osmo_timer_del(&cli->timer); talloc_free(cli); } @@ -402,6 +403,7 @@ cli->ofd.fd = ret; if (osmo_fd_register(&cli->ofd) < 0) { close(ret); + cli->ofd.fd = -1; return -EIO; } return 0; @@ -601,11 +603,11 @@ link->accept_cb = accept_cb; } -/*! \brief Destroy the stream server link. Releases Memory. - * Caller must make sure to osmo_stream_srv_link_close() before calling +/*! \brief Destroy the stream server link. Closes + Releases Memory. * \param[in] link Stream Server Link */ void osmo_stream_srv_link_destroy(struct osmo_stream_srv_link *link) { + osmo_stream_srv_link_close(link); talloc_free(link); } @@ -630,6 +632,7 @@ link->ofd.fd = ret; if (osmo_fd_register(&link->ofd) < 0) { close(ret); + link->ofd.fd = -1; return -EIO; } return 0; -- To view, visit https://gerrit.osmocom.org/2253 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I29c37da6e8f5be8ab030e68952a8f92add146821 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Sun Apr 9 14:44:12 2017 From: gerrit-no-reply at lists.osmocom.org (Holger Freyther) Date: Sun, 9 Apr 2017 14:44:12 +0000 Subject: libosmocore[master]: Add osmo_sock_init2() function, allowing both BIND *and* CON... In-Reply-To: References: Message-ID: Patch Set 1: I think it might be related to jails again? That 127.0.0.1 is remapped to another IPv4 address on the loopback? The "network namespaces" ("VIMAGE") don't seem be ready in FreeBSD yet. You had a similar issue for another network test. Do you remember or should I search for it? -- To view, visit https://gerrit.osmocom.org/2250 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Idab124bcca47872f55311a82d6818aed590965e6 Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sun Apr 9 16:56:58 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 16:56:58 +0000 Subject: [PATCH] libosmo-sccp[master]: sigtran: fix various memory leaks (msgb and xua_msg) In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2242 to look at the new patch set (#2). sigtran: fix various memory leaks (msgb and xua_msg) The general rule for 'struct xua_msg' is now that it is free'd by the function that also allocates it in the first place. Any downstream consumer of the xua_msg may interpret it, but not hold any references or free() it. Change-Id: I708505d129da5824c69b31a13a9c93201929bada --- M examples/sccp_test_server.c M examples/sccp_test_vty.c M src/m3ua.c M src/osmo_ss7_hmrt.c M src/sccp_sclc.c M src/sccp_scoc.c M src/sccp_scrc.c M src/sccp_user.c M src/sua.c 9 files changed, 33 insertions(+), 17 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/42/2242/2 diff --git a/examples/sccp_test_server.c b/examples/sccp_test_server.c index c3c658f..71bed96 100644 --- a/examples/sccp_test_server.c +++ b/examples/sccp_test_server.c @@ -34,6 +34,7 @@ oph->primitive, oph->operation); break; } + msgb_free(oph->msg); return 0; } @@ -71,6 +72,7 @@ oph->primitive, oph->operation); break; } + msgb_free(oph->msg); return 0; } @@ -102,6 +104,7 @@ oph->primitive, oph->operation); break; } + msgb_free(oph->msg); return 0; } diff --git a/examples/sccp_test_vty.c b/examples/sccp_test_vty.c index 1134d57..ddfbb27 100644 --- a/examples/sccp_test_vty.c +++ b/examples/sccp_test_vty.c @@ -125,6 +125,7 @@ default: break; } + msgb_free(oph->msg); return 0; } diff --git a/src/m3ua.c b/src/m3ua.c index 7437b6e..4f20c6e 100644 --- a/src/m3ua.c +++ b/src/m3ua.c @@ -420,13 +420,12 @@ * Transmitting M3UA messsages to SCTP ***********************************************************************/ +/* transmit given xua_msg via given ASP. callee takes xua ownership */ static int m3ua_tx_xua_asp(struct osmo_ss7_asp *asp, struct xua_msg *xua) { struct msgb *msg = xua_to_msg(M3UA_VERSION, xua); OSMO_ASSERT(asp->cfg.proto == OSMO_SS7_ASP_PROT_M3UA); - - xua_msg_free(xua); if (!msg) { LOGP(DLM3UA, LOGL_ERROR, "Error encoding M3UA Msg\n"); @@ -461,7 +460,6 @@ } if (!asp) { LOGP(DLM3UA, LOGL_ERROR, "No ASP entroy in AS, dropping message\n"); - xua_msg_free(xua); return -ENODEV; } diff --git a/src/osmo_ss7_hmrt.c b/src/osmo_ss7_hmrt.c index bc2b8e5..105a542 100644 --- a/src/osmo_ss7_hmrt.c +++ b/src/osmo_ss7_hmrt.c @@ -195,6 +195,7 @@ struct osmo_mtp_prim *omp) { struct xua_msg *xua; + int rc; OSMO_ASSERT(omp->oph.sap == MTP_SAP_USER); @@ -210,10 +211,15 @@ * is a very useful feature (aka "loopback device" in * IPv4). So we call m3ua_hmdc_rx_from_l2() just like * the MTP-TRANSFER had been received from L2. */ - return m3ua_hmdc_rx_from_l2(inst, xua); + rc = m3ua_hmdc_rx_from_l2(inst, xua); + xua_msg_free(xua); + break; default: LOGP(DLSS7, LOGL_ERROR, "Ignoring unknown primitive %u:%u\n", omp->oph.primitive, omp->oph.operation); - return -1; + rc = -1; } + + msgb_free(omp->oph.msg); + return rc; } diff --git a/src/sccp_sclc.c b/src/sccp_sclc.c index dae2c36..7cdfac5 100644 --- a/src/sccp_sclc.c +++ b/src/sccp_sclc.c @@ -102,12 +102,15 @@ struct osmo_scu_prim *prim, int msg_type) { struct xua_msg *xua; + int rc; xua = xua_gen_msg_cl(event, prim, msg_type); if (!xua) return -1; - return sccp_scrc_rx_sclc_msg(scu->inst, xua); + rc = sccp_scrc_rx_sclc_msg(scu->inst, xua); + xua_msg_free(xua); + return rc; } /*! \brief Main entrance function for primitives from SCCP User @@ -327,8 +330,8 @@ /* local originator: send N-NOTICE to user */ /* TODO: N-NOTICE.ind SCLC -> SCU */ sclc_rx_cldr(inst, xua_out); - xua_msg_free(xua_out); } + xua_msg_free(xua_out); break; case SUA_CL_CLDR: /* do nothing */ diff --git a/src/sccp_scoc.c b/src/sccp_scoc.c index cb592e6..b7ae38a 100644 --- a/src/sccp_scoc.c +++ b/src/sccp_scoc.c @@ -489,7 +489,9 @@ /* amend this with point code information; The SUA RELRE * includes neither called nor calling party address! */ xua->mtp.dpc = conn->remote_pc; - return sccp_scrc_rx_scoc_conn_msg(conn->inst, xua); + sccp_scrc_rx_scoc_conn_msg(conn->inst, xua); + xua_msg_free(xua); + return 0; } /* generate a 'struct xua_msg' of requested type from connection + @@ -623,7 +625,9 @@ /* amend this with point code information; Many CO msgs * includes neither called nor calling party address! */ xua->mtp.dpc = conn->remote_pc; - return sccp_scrc_rx_scoc_conn_msg(conn->inst, xua); + sccp_scrc_rx_scoc_conn_msg(conn->inst, xua); + xua_msg_free(xua); + return 0; } /* allocate a SCU primitive to be sent to the user */ diff --git a/src/sccp_scrc.c b/src/sccp_scrc.c index 0ab25cb..f9df075 100644 --- a/src/sccp_scrc.c +++ b/src/sccp_scrc.c @@ -384,8 +384,9 @@ return scrc_node_2(inst, xua, &called); /* TOOD: Coupling performed (not supported) */ - if (0) + if (0) { return scrc_node_2(inst, xua, &called); + } return scrc_local_out_common(inst, xua, &called); } @@ -412,6 +413,7 @@ return scrc_node_12(inst, xua, &called); } } + return scrc_local_out_common(inst, xua, &called); } @@ -450,8 +452,7 @@ if (hop_counter <= 1) { /* Error: hop-counter violation */ /* node 4 */ - return scrc_node_4(inst, xua, - SCCP_RETURN_CAUSE_HOP_COUNTER_VIOLATION); + return scrc_node_4(inst, xua, SCCP_RETURN_CAUSE_HOP_COUNTER_VIOLATION); } /* Decrement hop-counter */ hop_counter--; diff --git a/src/sccp_user.c b/src/sccp_user.c index bc03f4e..297d939 100644 --- a/src/sccp_user.c +++ b/src/sccp_user.c @@ -157,6 +157,7 @@ struct osmo_sccp_instance *inst = ctx; struct osmo_mtp_prim *omp = (struct osmo_mtp_prim *)oph; struct xua_msg *xua; + int rc; OSMO_ASSERT(oph->sap == MTP_SAP_USER); @@ -166,12 +167,14 @@ xua = osmo_sccp_to_xua(oph->msg); xua->mtp = omp->u.transfer; /* hand this primitive into SCCP via the SCRC code */ - return scrc_rx_mtp_xfer_ind_xua(inst, xua); + rc = scrc_rx_mtp_xfer_ind_xua(inst, xua); default: LOGP(DLSCCP, LOGL_ERROR, "Unknown primitive %u:%u receivd\n", oph->primitive, oph->operation); - return -1; + rc = -1; } + msgb_free(oph->msg); + return rc; } static LLIST_HEAD(sccp_instances); diff --git a/src/sua.c b/src/sua.c index 836e02e..d9e303b 100644 --- a/src/sua.c +++ b/src/sua.c @@ -258,8 +258,6 @@ OSMO_ASSERT(asp->cfg.proto == OSMO_SS7_ASP_PROT_SUA); - xua_msg_free(xua); - if (!msg) { LOGPASP(asp, DLSUA, LOGL_ERROR, "Error encoding SUA Msg\n"); return -1; @@ -290,7 +288,6 @@ } if (!asp) { LOGP(DLSUA, LOGL_ERROR, "No ASP in AS, dropping message\n"); - xua_msg_free(xua); return -ENODEV; } -- To view, visit https://gerrit.osmocom.org/2242 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I708505d129da5824c69b31a13a9c93201929bada Gerrit-PatchSet: 2 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sun Apr 9 16:56:58 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 16:56:58 +0000 Subject: [PATCH] libosmo-sccp[master]: sccp: add osmo_sccp_user_{get, set}_priv() API function In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2234 to look at the new patch set (#2). sccp: add osmo_sccp_user_{get,set}_priv() API function As 'struct osmo_sccp_user' is private, we need this accessor functions for the SCCP User so it can set and get the 'priv' data. Change-Id: Ia68a36dc18a7d754d63ae29c86d68e495b5c4134 --- M include/osmocom/sigtran/sccp_sap.h M src/sccp_user.c 2 files changed, 12 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/34/2234/2 diff --git a/include/osmocom/sigtran/sccp_sap.h b/include/osmocom/sigtran/sccp_sap.h index c1464f0..a86f86a 100644 --- a/include/osmocom/sigtran/sccp_sap.h +++ b/include/osmocom/sigtran/sccp_sap.h @@ -232,6 +232,8 @@ void osmo_sccp_instance_destroy(struct osmo_sccp_instance *inst); void osmo_sccp_user_unbind(struct osmo_sccp_user *scu); +void osmo_sccp_user_set_priv(struct osmo_sccp_user *scu, void *priv); +void *osmo_sccp_user_get_priv(struct osmo_sccp_user *scu); struct osmo_sccp_user * osmo_sccp_user_bind_pc(struct osmo_sccp_instance *inst, const char *name, diff --git a/src/sccp_user.c b/src/sccp_user.c index df02486..bc03f4e 100644 --- a/src/sccp_user.c +++ b/src/sccp_user.c @@ -130,6 +130,16 @@ talloc_free(scu); } +void osmo_sccp_user_set_priv(struct osmo_sccp_user *scu, void *priv) +{ + scu->priv = priv; +} + +void *osmo_sccp_user_get_priv(struct osmo_sccp_user *scu) +{ + return scu->priv; +} + /*! \brief Send a SCCP User SAP Primitive up to the User * \param[in] scu SCCP User to whom to send the primitive * \param[in] prim Primitive to send to the user -- To view, visit https://gerrit.osmocom.org/2234 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ia68a36dc18a7d754d63ae29c86d68e495b5c4134 Gerrit-PatchSet: 2 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sun Apr 9 16:56:58 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 16:56:58 +0000 Subject: [PATCH] libosmo-sccp[master]: xua_asp_fsm: Always return BEAT-ACK for BEAT, including BEAT... In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2238 to look at the new patch set (#2). xua_asp_fsm: Always return BEAT-ACK for BEAT, including BEAT DATA IE The RFCs say we *must* always respond to the optional heartbeat message, and we must return a verbatim copy of the heartbeat data IE. This was discovered (and fix validated) using m3ua-sgp-asptm-v-011 of Michael Tuexen's m3ua-testtool. Change-Id: I836e0940a8dbb0f55ddf132202a5f0d51473b82d --- M src/xua_asp_fsm.c 1 file changed, 23 insertions(+), 11 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/38/2238/2 diff --git a/src/xua_asp_fsm.c b/src/xua_asp_fsm.c index 80faeb2..aafc09f 100644 --- a/src/xua_asp_fsm.c +++ b/src/xua_asp_fsm.c @@ -128,7 +128,7 @@ } /* ask the xUA implementation to transmit a specific message */ -static int peer_send(struct osmo_fsm_inst *fi, int out_event) +static int peer_send(struct osmo_fsm_inst *fi, int out_event, struct xua_msg *in) { struct xua_asp_fsm_priv *xafp = fi->priv; struct osmo_ss7_asp *asp = xafp->asp; @@ -168,6 +168,7 @@ /* RFC3868 Ch. 3.5.6 */ xua->hdr = XUA_HDR(SUA_MSGC_ASPSM, SUA_ASPSM_BEAT_ACK); /* Optional: Heartbeat Data */ + xua_msg_copy_part(xua, M3UA_IEI_HEARDBT_DATA, in, M3UA_IEI_HEARDBT_DATA); break; case XUA_ASP_E_ASPTM_ASPAC: /* RFC3868 Ch. 3.6.1 */ @@ -217,7 +218,7 @@ osmo_fsm_event_name(fi->fsm, xafp->t_ack.out_event)); /* Re-transmit message */ - peer_send(fi, xafp->t_ack.out_event); + peer_send(fi, xafp->t_ack.out_event, NULL); /* Re-start the timer */ osmo_timer_schedule(&xafp->t_ack.timer, XUA_T_ACK_SEC, 0); @@ -229,7 +230,7 @@ struct xua_asp_fsm_priv *xafp = fi->priv; int rc; - rc = peer_send(fi, out_event); + rc = peer_send(fi, out_event, NULL); if (rc < 0) return rc; @@ -328,7 +329,7 @@ asp->asp_id_present = true; } /* send ACK */ - peer_send(fi, XUA_ASP_E_ASPSM_ASPUP_ACK); + peer_send(fi, XUA_ASP_E_ASPSM_ASPUP_ACK, NULL); /* transition state and inform layer manager */ osmo_fsm_inst_state_chg(fi, XUA_ASP_S_INACTIVE, 0, 0); send_xlm_prim_simple(fi, OSMO_XLM_PRIM_M_ASP_UP, @@ -340,7 +341,7 @@ /* The SGP MUST send an ASP Down Ack message in response * to a received ASP Down message from the ASP even if * the ASP is already marked as ASP-DOWN at the SGP. */ - peer_send(fi, XUA_ASP_E_ASPSM_ASPDN_ACK); + peer_send(fi, XUA_ASP_E_ASPSM_ASPDN_ACK, NULL); break; } } @@ -401,7 +402,7 @@ /* only in role SG */ ENSURE_SG_OR_IPSP(fi, event); /* send ACK */ - peer_send(fi, XUA_ASP_E_ASPTM_ASPAC_ACK); + peer_send(fi, XUA_ASP_E_ASPTM_ASPAC_ACK, NULL); /* transition state and inform layer manager */ osmo_fsm_inst_state_chg(fi, XUA_ASP_S_ACTIVE, 0, 0); send_xlm_prim_simple(fi, OSMO_XLM_PRIM_M_ASP_ACTIVE, @@ -411,7 +412,7 @@ /* only in role SG */ ENSURE_SG_OR_IPSP(fi, event); /* send ACK */ - peer_send(fi, XUA_ASP_E_ASPSM_ASPDN_ACK); + peer_send(fi, XUA_ASP_E_ASPSM_ASPDN_ACK, NULL); /* transition state and inform layer manager */ osmo_fsm_inst_state_chg(fi, XUA_ASP_S_DOWN, 0, 0); send_xlm_prim_simple(fi, OSMO_XLM_PRIM_M_ASP_DOWN, @@ -424,7 +425,7 @@ * remote ASP is already in the ASP-INACTIVE state, an * ASP Up Ack message is returned and no further action * is taken. */ - peer_send(fi, XUA_ASP_E_ASPSM_ASPUP_ACK); + peer_send(fi, XUA_ASP_E_ASPSM_ASPUP_ACK, NULL); break; } } @@ -470,7 +471,7 @@ /* only in role SG */ ENSURE_SG_OR_IPSP(fi, event); /* send ACK */ - peer_send(fi, XUA_ASP_E_ASPTM_ASPIA_ACK); + peer_send(fi, XUA_ASP_E_ASPTM_ASPIA_ACK, NULL); /* transition state and inform layer manager */ osmo_fsm_inst_state_chg(fi, XUA_ASP_S_INACTIVE, 0, 0); send_xlm_prim_simple(fi, OSMO_XLM_PRIM_M_ASP_INACTIVE, @@ -480,7 +481,7 @@ /* only in role SG */ ENSURE_SG_OR_IPSP(fi, event); /* send ACK */ - peer_send(fi, XUA_ASP_E_ASPSM_ASPDN_ACK); + peer_send(fi, XUA_ASP_E_ASPSM_ASPDN_ACK, NULL); /* transition state and inform layer manager */ osmo_fsm_inst_state_chg(fi, XUA_ASP_S_DOWN, 0, 0); send_xlm_prim_simple(fi, OSMO_XLM_PRIM_M_ASP_DOWN, @@ -508,12 +509,21 @@ static void xua_asp_allstate(struct osmo_fsm_inst *fi, uint32_t event, void *data) { + struct xua_msg *xua; + switch (event) { case XUA_ASP_E_SCTP_COMM_DOWN_IND: case XUA_ASP_E_SCTP_RESTART_IND: osmo_fsm_inst_state_chg(fi, XUA_ASP_S_DOWN, 0, 0); send_xlm_prim_simple(fi, OSMO_XLM_PRIM_M_ASP_DOWN, PRIM_OP_INDICATION); + break; + case XUA_ASP_E_ASPSM_BEAT: + xua = data; + peer_send(fi, XUA_ASP_E_ASPSM_BEAT_ACK, xua); + break; + case XUA_ASP_E_ASPSM_BEAT_ACK: + /* FIXME: stop timer, if any */ break; default: break; @@ -577,7 +587,9 @@ .log_subsys = DLSS7, .event_names = xua_asp_event_names, .allstate_event_mask = S(XUA_ASP_E_SCTP_COMM_DOWN_IND) | - S(XUA_ASP_E_SCTP_RESTART_IND), + S(XUA_ASP_E_SCTP_RESTART_IND) | + S(XUA_ASP_E_ASPSM_BEAT) | + S(XUA_ASP_E_ASPSM_BEAT_ACK), .allstate_action = xua_asp_allstate, }; -- To view, visit https://gerrit.osmocom.org/2238 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I836e0940a8dbb0f55ddf132202a5f0d51473b82d Gerrit-PatchSet: 2 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sun Apr 9 16:57:00 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 16:57:00 +0000 Subject: [PATCH] libosmo-sccp[master]: Allow clients to specify local IP/port Message-ID: Review at https://gerrit.osmocom.org/2254 Allow clients to specify local IP/port Change-Id: Ief7ce8181442fd0f51c34cf598269ed3a6beacea --- M examples/m3ua_example.c M include/osmocom/sigtran/osmo_ss7.h M src/osmo_ss7.c M src/sccp_user.c 4 files changed, 9 insertions(+), 5 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/54/2254/1 diff --git a/examples/m3ua_example.c b/examples/m3ua_example.c index 07de7f3..d1247f5 100644 --- a/examples/m3ua_example.c +++ b/examples/m3ua_example.c @@ -106,7 +106,7 @@ if (client) { - g_sccp = osmo_sccp_simple_client(NULL, "client", 23, OSMO_SS7_ASP_PROT_M3UA, 0, M3UA_PORT, "127.0.0.2"); + g_sccp = osmo_sccp_simple_client(NULL, "client", 23, OSMO_SS7_ASP_PROT_M3UA, 0, NULL, M3UA_PORT, "127.0.0.2"); sccp_test_user_vty_install(g_sccp, OSMO_SCCP_SSN_BSC_BSSAP); } else { g_sccp = sua_server_helper(); diff --git a/include/osmocom/sigtran/osmo_ss7.h b/include/osmocom/sigtran/osmo_ss7.h index d765ae0..b8fab99 100644 --- a/include/osmocom/sigtran/osmo_ss7.h +++ b/include/osmocom/sigtran/osmo_ss7.h @@ -390,10 +390,11 @@ void osmo_ss7_xua_server_destroy(struct osmo_xua_server *xs); + struct osmo_sccp_instance * osmo_sccp_simple_client(void *ctx, const char *name, uint32_t pc, - enum osmo_ss7_asp_protocol prot, - int local_port, int remote_port, const char *remote_ip); + enum osmo_ss7_asp_protocol prot, int local_port, + const char *local_ip, int remote_port, const char *remote_ip); struct osmo_sccp_instance * osmo_sccp_simple_server(void *ctx, uint32_t pc, diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index f7f2519..d569475 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -1031,6 +1031,8 @@ } osmo_stream_cli_set_addr(asp->client, asp->cfg.remote.host); osmo_stream_cli_set_port(asp->client, asp->cfg.remote.port); + osmo_stream_cli_set_local_addr(asp->client, asp->cfg.local.host); + osmo_stream_cli_set_local_port(asp->client, asp->cfg.local.port); osmo_stream_cli_set_proto(asp->client, IPPROTO_SCTP); osmo_stream_cli_set_reconnect_timeout(asp->client, 5); osmo_stream_cli_set_connect_cb(asp->client, xua_cli_connect_cb); diff --git a/src/sccp_user.c b/src/sccp_user.c index 9ed57d4..57c0038 100644 --- a/src/sccp_user.c +++ b/src/sccp_user.c @@ -230,8 +230,8 @@ struct osmo_sccp_instance * osmo_sccp_simple_client(void *ctx, const char *name, uint32_t pc, - enum osmo_ss7_asp_protocol prot, - int local_port, int remote_port, const char *remote_ip) + enum osmo_ss7_asp_protocol prot, int local_port, + const char *local_ip, int remote_port, const char *remote_ip) { struct osmo_ss7_instance *ss7; struct osmo_ss7_as *as; @@ -269,6 +269,7 @@ prot); if (!asp) goto out_rt; + asp->cfg.local.host = talloc_strdup(asp, local_ip); asp->cfg.remote.host = talloc_strdup(asp, remote_ip); osmo_ss7_as_add_asp(as, asp_name); talloc_free(asp_name); -- To view, visit https://gerrit.osmocom.org/2254 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ief7ce8181442fd0f51c34cf598269ed3a6beacea Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Sun Apr 9 16:57:00 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 16:57:00 +0000 Subject: [PATCH] libosmo-sccp[master]: sccp_scoc: Move osmo_prim_event_map to libosmocore Message-ID: Review at https://gerrit.osmocom.org/2255 sccp_scoc: Move osmo_prim_event_map to libosmocore Change-Id: Ic1f22ae2e8d786bfe4bbb84e8eb9f8ae4d93d899 --- M src/sccp_scoc.c 1 file changed, 0 insertions(+), 30 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/55/2255/1 diff --git a/src/sccp_scoc.c b/src/sccp_scoc.c index b7ae38a..2585c9f 100644 --- a/src/sccp_scoc.c +++ b/src/sccp_scoc.c @@ -211,36 +211,6 @@ }; -/*! \brief magic value to be used as final record of \ref - * osmo_prim_event_map */ -#define OSMO_NO_EVENT 0xFFFFFFFF - -/*! \brief single entry in a SAP/PRIM/OP -> EVENT map */ -struct osmo_prim_event_map { - unsigned int sap; /*!< SAP to match */ - unsigned int primitive; /*!< primtiive to match */ - enum osmo_prim_operation operation; /*!< operation to match */ - uint32_t event; /*!< event as result if above match */ -}; - -/*! \brief resolve the (fsm) event for a given primitive using a map - * \param[in] oph primitive header used as key for match - * \param[in] maps list of mappings from primitive to event - * \returns event determined by map; \ref OSMO_NO_EVENT if no match */ -uint32_t osmo_event_for_prim(const struct osmo_prim_hdr *oph, - const struct osmo_prim_event_map *maps) -{ - const struct osmo_prim_event_map *map; - - for (map = maps; map->event != OSMO_NO_EVENT; map++) { - if (map->sap == oph->sap && - map->primitive == oph->primitive && - map->operation == oph->operation) - return map->event; - } - return OSMO_NO_EVENT; -} - /* map from SCU-primitives to SCOC FSM events */ static const struct osmo_prim_event_map scu_scoc_event_map[] = { { SCCP_SAP_USER, OSMO_SCU_PRIM_N_CONNECT, PRIM_OP_REQUEST, -- To view, visit https://gerrit.osmocom.org/2255 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ic1f22ae2e8d786bfe4bbb84e8eb9f8ae4d93d899 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Sun Apr 9 16:57:00 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 16:57:00 +0000 Subject: [PATCH] libosmo-sccp[master]: protocol/m3ua.h: Add definition for RKM reg/dereg result codes Message-ID: Review at https://gerrit.osmocom.org/2256 protocol/m3ua.h: Add definition for RKM reg/dereg result codes Change-Id: I16db7847e20501b89cc487029b29c8796b10bb84 --- M include/osmocom/sigtran/protocol/m3ua.h 1 file changed, 26 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/56/2256/1 diff --git a/include/osmocom/sigtran/protocol/m3ua.h b/include/osmocom/sigtran/protocol/m3ua.h index c10808c..7b8eadc 100644 --- a/include/osmocom/sigtran/protocol/m3ua.h +++ b/include/osmocom/sigtran/protocol/m3ua.h @@ -116,6 +116,32 @@ #define M3UA_NOTIFY_I_OT_ALT_ASP_ACT 2 #define M3UA_NOTIFY_I_OT_ASP_FAILURE 3 +/* 3.6.2 Registration Status */ +enum m3ua_rkm_reg_status { + M3UA_RKM_REG_SUCCESS = 0, + M3UA_RKM_REG_ERR_UNKNOWN = 1, + M3UA_RKM_REG_ERR_INVAL_DPC = 2, + M3UA_RKM_REG_ERR_INVAL_NET_APPEAR = 3, + M3UA_RKM_REG_ERR_INVAL_RKEY = 4, + M3UA_RKM_REG_ERR_PERM_DENIED = 5, + M3UA_RKM_REG_ERR_CANT_SUPP_UNQ_RT = 6, + M3UA_RKM_REG_ERR_RKEY_NOT_PROVD = 7, + M3UA_RKM_REG_ERR_INSUFF_RESRC = 8, + M3UA_RKM_REG_ERR_UNSUPP_RK_PARAM = 9, + M3UA_RKM_REG_ERR_UNSUPP_TRAF_MODE = 10, + M3UA_RKM_REG_ERR_RKEY_CHG_REFUSED = 11, + M3UA_RKM_REG_ERR_RKEY_ALRDY_REGD = 12, +}; + +enum m3ua_rkm_dereg_satus { + M3UA_RKM_DEREG_SUCCESS = 0, + M3UA_RKM_DEREG_ERR_UNKNOWN = 1, + M3UA_RKM_DEREG_ERR_INVAL_RCTX = 2, + M3UA_RKM_DEREG_ERR_PERM_DENIED = 3, + M3UA_RKM_DEREG_ERR_NOT_REGD = 4, + M3UA_RKM_DEREG_ERR_ASP_ACTIVE = 5, +}; + /* 3.8.1 Error */ enum m3ua_error_code { M3UA_ERR_INVALID_VERSION = 0x01, -- To view, visit https://gerrit.osmocom.org/2256 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I16db7847e20501b89cc487029b29c8796b10bb84 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Sun Apr 9 16:57:01 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 16:57:01 +0000 Subject: [PATCH] libosmo-sccp[master]: xua_msg: Add xua_from_nested() helper function for nested IEs Message-ID: Review at https://gerrit.osmocom.org/2257 xua_msg: Add xua_from_nested() helper function for nested IEs Change-Id: If664ac20f43eb5c8e11bca6e61eb372e25613789 --- M include/osmocom/sigtran/xua_msg.h M src/xua_msg.c 2 files changed, 7 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/57/2257/1 diff --git a/include/osmocom/sigtran/xua_msg.h b/include/osmocom/sigtran/xua_msg.h index e0e1bcf..423adbc 100644 --- a/include/osmocom/sigtran/xua_msg.h +++ b/include/osmocom/sigtran/xua_msg.h @@ -82,6 +82,8 @@ struct xua_msg *xua_from_msg(const int version, uint16_t len, uint8_t *data); struct msgb *xua_to_msg(const int version, struct xua_msg *msg); +struct xua_msg *xua_from_nested(struct xua_msg_part *outer); + int msgb_t16l16vp_put(struct msgb *msg, uint16_t tag, uint16_t len, const uint8_t *data); int msgb_t16l16vp_put_u32(struct msgb *msg, uint16_t tag, uint32_t val); int xua_msg_add_u32(struct xua_msg *xua, uint16_t iei, uint32_t val); diff --git a/src/xua_msg.c b/src/xua_msg.c index cb487c8..a5b7560 100644 --- a/src/xua_msg.c +++ b/src/xua_msg.c @@ -163,6 +163,11 @@ return NULL; } +struct xua_msg *xua_from_nested(struct xua_msg_part *outer) +{ + return xua_from_msg(0, outer->len, outer->dat); +} + struct msgb *xua_to_msg(const int version, struct xua_msg *xua) { struct xua_msg_part *part; -- To view, visit https://gerrit.osmocom.org/2257 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: If664ac20f43eb5c8e11bca6e61eb372e25613789 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Sun Apr 9 16:57:01 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 16:57:01 +0000 Subject: [PATCH] libosmo-sccp[master]: Add osmo_ss7_find_free_rctx() function to get unused rctx Message-ID: Review at https://gerrit.osmocom.org/2258 Add osmo_ss7_find_free_rctx() function to get unused rctx Change-Id: I0186e25a1b3a325c6b0e3f50ef1590c4de6dbef6 --- M include/osmocom/sigtran/osmo_ss7.h M src/osmo_ss7.c 2 files changed, 12 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/58/2258/1 diff --git a/include/osmocom/sigtran/osmo_ss7.h b/include/osmocom/sigtran/osmo_ss7.h index b8fab99..527efb8 100644 --- a/include/osmocom/sigtran/osmo_ss7.h +++ b/include/osmocom/sigtran/osmo_ss7.h @@ -15,6 +15,7 @@ struct osmo_mtp_prim; int osmo_ss7_init(void); +int osmo_ss7_find_free_rctx(struct osmo_ss7_instance *inst); bool osmo_ss7_pc_is_local(struct osmo_ss7_instance *inst, uint32_t pc); int osmo_ss7_pointcode_parse(struct osmo_ss7_instance *inst, const char *str); diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index d569475..5790356 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -53,6 +53,7 @@ static LLIST_HEAD(ss7_instances); static LLIST_HEAD(ss7_xua_servers); +static int32_t next_rctx = 1; struct value_string osmo_ss7_as_traffic_mode_vals[] = { { OSMO_SS7_AS_TMOD_BCAST, "broadcast" }, @@ -72,6 +73,16 @@ #define LOGSS7(inst, level, fmt, args ...) \ LOGP(DLSS7, level, "%u: " fmt, (inst)->cfg.id, ## args) +int osmo_ss7_find_free_rctx(struct osmo_ss7_instance *inst) +{ + int32_t rctx; + + for (rctx = next_rctx; rctx; rctx = ++next_rctx) { + if (!osmo_ss7_as_find_by_rctx(inst, next_rctx)) + return rctx; + } + return -1; +} /*********************************************************************** * SS7 Point Code Parsing / Printing -- To view, visit https://gerrit.osmocom.org/2258 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I0186e25a1b3a325c6b0e3f50ef1590c4de6dbef6 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Sun Apr 9 16:57:01 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 16:57:01 +0000 Subject: [PATCH] libosmo-sccp[master]: osmo_ss7: Add support for dynamic ASP registration Message-ID: Review at https://gerrit.osmocom.org/2259 osmo_ss7: Add support for dynamic ASP registration if osmo_xua_server.cfg.accept_dyn_reg is set, then ASPs are permitted to connect without having a pre-configured matching ASP definition in the vty. This helps particularly in cases where RKM is used for dynamica registration of a RC (and hence AS). Change-Id: Ie48898202acbdbfe144fdd5851dfedbb554b11aa --- M include/osmocom/sigtran/osmo_ss7.h M src/osmo_ss7.c 2 files changed, 25 insertions(+), 8 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/59/2259/1 diff --git a/include/osmocom/sigtran/osmo_ss7.h b/include/osmocom/sigtran/osmo_ss7.h index 527efb8..21c3768 100644 --- a/include/osmocom/sigtran/osmo_ss7.h +++ b/include/osmocom/sigtran/osmo_ss7.h @@ -373,6 +373,7 @@ struct osmo_stream_srv_link *server; struct { + bool accept_dyn_reg; struct osmo_ss7_asp_peer local; enum osmo_ss7_asp_protocol proto; } cfg; diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index 5790356..185d6b4 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -1347,15 +1347,31 @@ } asp = osmo_ss7_asp_find_by_socket_addr(fd); - if (!asp) { - LOGP(DLSS7, LOGL_NOTICE, "%s: SCTP connection without matching " - "ASP definition, terminating\n", sock_name); - osmo_stream_srv_destroy(srv); - talloc_free(sock_name); - return -1; + if (asp) { + LOGP(DLSS7, LOGL_INFO, "%s: matched connection to ASP %s\n", + sock_name, asp->cfg.name); + } else { + if (!oxs->cfg.accept_dyn_reg) { + LOGP(DLSS7, LOGL_NOTICE, "%s: SCTP connection without matching " + "ASP definition and no dynamic registration enabled, terminating\n", + sock_name); + } else { + char namebuf[32]; + static uint32_t dyn_asp_num = 0; + snprintf(namebuf, sizeof(namebuf), "asp-dyn-%u", dyn_asp_num++); + asp = osmo_ss7_asp_find_or_create(oxs->inst, NULL, 0, 0, + OSMO_SS7_ASP_PROT_M3UA); + if (asp) + LOGP(DLSS7, LOGL_INFO, "%s: created dynamicASP %s\n", + sock_name, asp->cfg.name); + } + if (!asp) { + osmo_stream_srv_destroy(srv); + talloc_free(sock_name); + return -1; + } } - LOGP(DLSS7, LOGL_INFO, "%s: matched connection to ASP %s\n", - sock_name, asp->cfg.name); + /* update the ASP reference back to the server over which the * connection came in */ asp->server = srv; -- To view, visit https://gerrit.osmocom.org/2259 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ie48898202acbdbfe144fdd5851dfedbb554b11aa Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Sun Apr 9 16:57:01 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 16:57:01 +0000 Subject: [PATCH] libosmo-sccp[master]: Add M3UA RKM (routing key management) support, SGW side only Message-ID: Review at https://gerrit.osmocom.org/2260 Add M3UA RKM (routing key management) support, SGW side only Change-Id: I9b1cf438a42519c0fe2f555c1672fafa499122a1 --- M src/Makefile.am M src/m3ua.c M src/xua_internal.h A src/xua_rkm.c 4 files changed, 289 insertions(+), 2 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/60/2260/1 diff --git a/src/Makefile.am b/src/Makefile.am index a4cfeeb..7867282 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -28,7 +28,7 @@ libosmo_sigtran_la_SOURCES = sccp_sap.c sua.c m3ua.c xua_msg.c sccp_helpers.c \ sccp2sua.c sccp_scrc.c sccp_sclc.c sccp_scoc.c \ - sccp_user.c \ + sccp_user.c xua_rkm.c \ osmo_ss7.c osmo_ss7_hmrt.c xua_asp_fsm.c xua_as_fsm.c libosmo_sigtran_la_LDFLAGS = -version-info $(LIBVERSION) -no-undefined -export-symbols-regex '^osmo_' libosmo_sigtran_la_LIBADD = $(LIBOSMOCORE_LIBS) $(LIBOSMONETIF_LIBS) $(LIBSCTP_LIBS) diff --git a/src/m3ua.c b/src/m3ua.c index 4f20c6e..5708985 100644 --- a/src/m3ua.c +++ b/src/m3ua.c @@ -666,8 +666,10 @@ case M3UA_MSGC_MGMT: rc = m3ua_rx_mgmt(asp, xua); break; - case M3UA_MSGC_SNM: case M3UA_MSGC_RKM: + rc = m3ua_rx_rkm(asp, xua); + break; + case M3UA_MSGC_SNM: /* FIXME */ LOGPASP(asp, DLM3UA, LOGL_NOTICE, "Received unsupported M3UA " "Message Class %u\n", xua->hdr.msg_class); diff --git a/src/xua_internal.h b/src/xua_internal.h index c6f79b7..24fcb1c 100644 --- a/src/xua_internal.h +++ b/src/xua_internal.h @@ -58,3 +58,4 @@ struct xua_msg *m3ua_encode_notify(const struct m3ua_notify_params *npar); int m3ua_decode_notify(struct m3ua_notify_params *npar, void *ctx, const struct xua_msg *xua); +int m3ua_rx_rkm(struct osmo_ss7_asp *asp, struct xua_msg *xua); diff --git a/src/xua_rkm.c b/src/xua_rkm.c new file mode 100644 index 0000000..5215af1 --- /dev/null +++ b/src/xua_rkm.c @@ -0,0 +1,284 @@ +/* xUA Routing Key Management (RKM) as per RFC 4666 */ +/* (C) 2017 by Harald Welte + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include + +#include +#include + +#include +#include +#include + +#include "xua_internal.h" + +/* push a M3UA header to the front of the given message */ +static void msgb_push_m3ua_hdr(struct msgb *msg, uint8_t msg_class, uint8_t msg_type) +{ + struct xua_common_hdr *hdr; + + msg->l2h = msgb_push(msg, sizeof(*msg)); + hdr = (struct xua_common_hdr *) msg->l2h; + + hdr->version = M3UA_VERSION; + hdr->spare = 0; + hdr->msg_class = msg_class; + hdr->msg_type = msg_type; + hdr->msg_length = htonl(msgb_l2len(msg)); +} + +/* append a single registration result to given msgb */ +static int msgb_append_reg_res(struct msgb *msg, uint32_t local_rk_id, + uint32_t status, uint32_t rctx) +{ + uint8_t *old_tail = msg->tail; + + /* One individual Registration Result according to Chapter 3.6.2 */ + msgb_put_u16(msg, M3UA_IEI_REG_RESULT); /* outer IEI */ + msgb_put_u16(msg, 24 + 4); /* outer length */ + /* nested IEIs */ + msgb_t16l16vp_put_u32(msg, M3UA_IEI_LOC_RKEY_ID, local_rk_id); + msgb_t16l16vp_put_u32(msg, M3UA_IEI_REG_STATUS, status); + msgb_t16l16vp_put_u32(msg, M3UA_IEI_ROUTE_CTX, rctx); + + return msg->tail - old_tail; +} + +/* append a single de-registration result to given msgb */ +static int msgb_append_dereg_res(struct msgb *msg, + uint32_t status, uint32_t rctx) +{ + uint8_t *old_tail = msg->tail; + + /* One individual De-Registration Result according to Chapter 3.6.4 */ + msgb_put_u16(msg, M3UA_IEI_DEREG_RESULT); /* outer IEI */ + msgb_put_u16(msg, 16 + 4); /* outer length */ + /* nested IEIs */ + msgb_t16l16vp_put_u32(msg, M3UA_IEI_ROUTE_CTX, rctx); + msgb_t16l16vp_put_u32(msg, M3UA_IEI_DEREG_STATUS, status); + + return msg->tail - old_tail; +} + +/* handle a single registration request IE (nested IEs in 'innner' */ +static int handle_rkey_reg(struct osmo_ss7_asp *asp, struct xua_msg *inner, + struct msgb *resp) +{ + uint32_t rk_id, rctx, _tmode, dpc; + enum osmo_ss7_as_traffic_mode tmode; + struct osmo_ss7_as *as; + struct osmo_ss7_route *rt; + char namebuf[32]; + + /* mandatory local routing key ID */ + rk_id = xua_msg_get_u32(inner, M3UA_IEI_LOC_RKEY_ID); + /* ASP may already include a routing context value here */ + rctx = xua_msg_get_u32(inner, M3UA_IEI_ROUTE_CTX); + + /* traffic mode type (0 = undefined) */ + _tmode = xua_msg_get_u32(inner, M3UA_IEI_TRAF_MODE_TYP); + tmode = osmo_ss7_tmode_from_xua(_tmode); + + /* destination point code (mandatory) */ + dpc = xua_msg_get_u32(inner, M3UA_IEI_DEST_PC); + + /* We don't support routing keys with the following criteria, so + * we have to reject those */ + /* TODO: network appearance (optional) */ + /* TODO: service indicators (optional) */ + /* TODO: originating point code list (optional) */ + if (xua_msg_find_tag(inner, M3UA_IEI_NET_APPEAR) || + xua_msg_find_tag(inner, M3UA_IEI_SVC_IND) || + xua_msg_find_tag(inner, M3UA_IEI_ORIG_PC)) { + LOGPASP(asp, DLSS7, LOGL_NOTICE, "Unsupported Routing Key\n"); + msgb_append_reg_res(resp, rk_id, M3UA_RKM_REG_ERR_UNSUPP_RK_PARAM, 0); + return -1; + } + + /* if the ASP did not include a routing context number, allocate + * one locally (will be part of response) */ + if (!rctx) + rctx = osmo_ss7_find_free_rctx(asp->inst); + + LOGPASP(asp, DLSS7, LOGL_INFO, "Registering routing key %u for DPC %s\n", + rctx, osmo_ss7_pointcode_print(asp->inst, dpc)); + + /* check if there is already an AS for this routing key */ + if (osmo_ss7_as_find_by_rctx(asp->inst, rctx)) { + LOGPASP(asp, DLSS7, LOGL_NOTICE, "RCTX %u already in use\n", rctx); + msgb_append_reg_res(resp, rk_id, M3UA_RKM_REG_ERR_RKEY_ALRDY_REGD, 0); + return -1; + } + + /* Create an AS for this routing key */ + snprintf(namebuf, sizeof(namebuf), "as-rkm-%u", rctx); + as = osmo_ss7_as_find_or_create(asp->inst, namebuf, OSMO_SS7_ASP_PROT_M3UA); + if (!as) { + msgb_append_reg_res(resp, rk_id, M3UA_RKM_REG_ERR_INSUFF_RESRC, 0); + return -1; + } + + as->cfg.description = talloc_strdup(as, "Auto-generated by RKM"); + as->cfg.mode = tmode; + /* fill routing key */ + as->cfg.routing_key.context = rctx; + as->cfg.routing_key.pc = dpc; + + /* add route for that routing key */ + rt = osmo_ss7_route_create(as->inst->rtable_system, dpc, 0xFFFFFF, namebuf); + if (!rt) { + osmo_ss7_as_destroy(as); + msgb_append_reg_res(resp, rk_id, M3UA_RKM_REG_ERR_CANT_SUPP_UNQ_RT, 0); + return -1; + } + + /* Success: Add just-create AS to connected ASP + report success */ + osmo_ss7_as_add_asp(as, asp->cfg.name); + msgb_append_reg_res(resp, rk_id, M3UA_RKM_REG_SUCCESS, rctx); + return 0; +} + +/* receive a deregistration requuest (SG role) */ +static int m3ua_rx_rkm_reg_req(struct osmo_ss7_asp *asp, struct xua_msg *xua) +{ + struct xua_msg_part *part; + struct msgb *resp = m3ua_msgb_alloc(__func__); + + /* iterate over all routing key IEs in message */ + llist_for_each_entry(part, &xua->headers, entry) { + struct xua_msg *inner; + + if (part->tag != M3UA_IEI_ROUT_KEY) + continue; + + inner = xua_from_nested(part); + if (!inner) { + LOGPASP(asp, DLSS7, LOGL_NOTICE, "Unable to parse " + "nested IE for Routing Key\n"); + continue; + } + /* handle single registration and append result to + * 'resp' */ + handle_rkey_reg(asp, inner, resp); + } + msgb_push_m3ua_hdr(resp, M3UA_MSGC_RKM, M3UA_RKM_REG_RSP); + + return 0; +} + +/* receive a deregistration requuest (SG role) */ +static int handle_rkey_dereg(struct osmo_ss7_asp *asp, uint32_t rctx, + struct msgb *resp) +{ + struct osmo_ss7_instance *inst = asp->inst; + struct osmo_ss7_as *as; + struct osmo_ss7_route *rt; + + as = osmo_ss7_as_find_by_rctx(inst, rctx); + if (!as) { + msgb_append_dereg_res(resp, M3UA_RKM_DEREG_ERR_INVAL_RCTX, 0); + return -1; + } + + /* Reject if ASP is not even part of AS */ + if (!osmo_ss7_as_has_asp(as, asp)) { + msgb_append_dereg_res(resp, M3UA_RKM_DEREG_ERR_INVAL_RCTX, 0); + return -1; + } + + /* FIXME Reject if any ASP stillactively using this RCTX */ + + rt = osmo_ss7_route_find_dpc(inst->rtable_system, as->cfg.routing_key.pc); + if (!rt) { + msgb_append_dereg_res(resp, M3UA_RKM_DEREG_ERR_UNKNOWN, 0); + return -1; + } + + LOGPASP(asp, DLSS7, LOGL_INFO, "De-Registering rctx %u for DPC %s\n", + rctx, osmo_ss7_pointcode_print(inst, as->cfg.routing_key.pc)); + + /* remove route + AS definition */ + osmo_ss7_route_destroy(rt); + osmo_ss7_as_destroy(as); + /* report success */ + msgb_append_dereg_res(resp, M3UA_RKM_DEREG_SUCCESS, rctx); + + return 0; +} + +static int m3ua_rx_rkm_dereg_req(struct osmo_ss7_asp *asp, struct xua_msg *xua) +{ + struct xua_msg_part *part = xua_msg_find_tag(xua, M3UA_IEI_ROUTE_CTX); + struct msgb *resp = m3ua_msgb_alloc(__func__); + uint32_t *rctx; + + if (!part) + return -1; + + for (rctx = (uint32_t *)part->dat; (uint8_t *)rctx < part->dat + part->len; rctx++) + handle_rkey_dereg(asp, ntohl(*rctx), resp); + + msgb_push_m3ua_hdr(resp, M3UA_MSGC_RKM, M3UA_RKM_DEREG_RSP); + + return 0; +} + +/* receive a registration response (ASP role) */ +static int m3ua_rx_rkm_reg_rsp(struct osmo_ss7_asp *asp, struct xua_msg *xua) +{ + /* TODO */ +} + +/* receive a deregistration response (ASP role) */ +static int m3ua_rx_rkm_dereg_rsp(struct osmo_ss7_asp *asp, struct xua_msg *xua) +{ + /* TODO */ +} + +/* process an incoming RKM message in xua format */ +int m3ua_rx_rkm(struct osmo_ss7_asp *asp, struct xua_msg *xua) +{ + int rc; + + switch (xua->hdr.msg_type) { + /* SG Side */ + case M3UA_RKM_REG_REQ: + /* TOOD: ensure we are role SG */ + rc = m3ua_rx_rkm_reg_req(asp, xua); + break; + case M3UA_RKM_DEREG_REQ: + /* TOOD: ensure we are role SG */ + rc = m3ua_rx_rkm_dereg_req(asp, xua); + break; + /* ASP Side */ + case M3UA_RKM_REG_RSP: + /* TOOD: ensure we are role ASP */ + rc = m3ua_rx_rkm_reg_rsp(asp, xua); + break; + case M3UA_RKM_DEREG_RSP: + /* TOOD: ensure we are role ASP */ + rc = m3ua_rx_rkm_dereg_rsp(asp, xua); + break; + default: + LOGPASP(asp, DLSS7, LOGL_ERROR, "Received unknown RKM msg_type %u\n", + xua->hdr.msg_type); + rc = -1; + break; + } + return rc; +} -- To view, visit https://gerrit.osmocom.org/2260 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I9b1cf438a42519c0fe2f555c1672fafa499122a1 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Sun Apr 9 16:57:01 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 16:57:01 +0000 Subject: [PATCH] libosmo-sccp[master]: xua: move notfiy parameters from xua_internal to sigtran_sap... Message-ID: Review at https://gerrit.osmocom.org/2261 xua: move notfiy parameters from xua_internal to sigtran_sap and rename them Change-Id: I295b9d6755a4bb52a817d2791a302bdd9fc775dd --- M include/osmocom/sigtran/sigtran_sap.h M src/m3ua.c M src/sua.c M src/xua_as_fsm.c M src/xua_asp_fsm.c M src/xua_internal.h 6 files changed, 55 insertions(+), 44 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/61/2261/1 diff --git a/include/osmocom/sigtran/sigtran_sap.h b/include/osmocom/sigtran/sigtran_sap.h index d29c37d..d18aa3d 100644 --- a/include/osmocom/sigtran/sigtran_sap.h +++ b/include/osmocom/sigtran/sigtran_sap.h @@ -1,6 +1,7 @@ #pragma once #include + enum osmo_sigtran_sap { SCCP_SAP_USER = _SAP_SS7_BASE, /* xUA Layer Manager */ @@ -29,10 +30,27 @@ OSMO_XLM_PRIM_M_RK_DEREG, }; +#define NOTIFY_PAR_P_ASP_ID (1 << 0) +#define NOTIFY_PAR_P_ROUTE_CTX (1 << 1) + +struct osmo_xlm_prim_notify { + uint32_t presence; + uint16_t status_type; + uint16_t status_info; + uint32_t asp_id; + uint32_t route_ctx; + char *info_string; +}; + +struct osmo_xlm_prim_error { + uint32_t code; +}; struct osmo_xlm_prim { struct osmo_prim_hdr oph; union { + struct osmo_xlm_prim_notify notify; + struct osmo_xlm_prim_error error; } u; }; diff --git a/src/m3ua.c b/src/m3ua.c index 5708985..96991a7 100644 --- a/src/m3ua.c +++ b/src/m3ua.c @@ -350,7 +350,7 @@ ***********************************************************************/ /* RFC4666 Ch. 3.8.2. Notify */ -struct xua_msg *m3ua_encode_notify(const struct m3ua_notify_params *npar) +struct xua_msg *m3ua_encode_notify(const struct osmo_xlm_prim_notify *npar) { struct xua_msg *xua = xua_msg_alloc(); uint32_t status; @@ -379,7 +379,7 @@ } /* RFC4666 Ch. 3.8.2. Notify */ -int m3ua_decode_notify(struct m3ua_notify_params *npar, void *ctx, +int m3ua_decode_notify(struct osmo_xlm_prim_notify *npar, void *ctx, const struct xua_msg *xua) { struct xua_msg_part *info_ie, *aspid_ie, *status_ie, *rctx_ie; @@ -538,7 +538,7 @@ static int m3ua_rx_mgmt_ntfy(struct osmo_ss7_asp *asp, struct xua_msg *xua) { - struct m3ua_notify_params ntfy; + struct osmo_xlm_prim_notify ntfy; const char *type_name, *info_name; m3ua_decode_notify(&ntfy, asp, xua); diff --git a/src/sua.c b/src/sua.c index d9e303b..0f19bea 100644 --- a/src/sua.c +++ b/src/sua.c @@ -507,7 +507,7 @@ static int sua_rx_mgmt_ntfy(struct osmo_ss7_asp *asp, struct xua_msg *xua) { - struct m3ua_notify_params ntfy; + struct osmo_xlm_prim_notify ntfy; const char *type_name, *info_name; m3ua_decode_notify(&ntfy, asp, xua); diff --git a/src/xua_as_fsm.c b/src/xua_as_fsm.c index d73f793..740070b 100644 --- a/src/xua_as_fsm.c +++ b/src/xua_as_fsm.c @@ -25,7 +25,7 @@ #include "xua_as_fsm.h" #include "xua_internal.h" -static struct msgb *encode_notify(const struct m3ua_notify_params *npar) +static struct msgb *encode_notify(const struct osmo_xlm_prim_notify *npar) { struct xua_msg *xua = m3ua_encode_notify(npar); struct msgb *msg = xua_to_msg(M3UA_VERSION, xua); @@ -33,7 +33,7 @@ return msg; } -static int asp_notify_all_as(struct osmo_ss7_as *as, struct m3ua_notify_params *npar) +static int asp_notify_all_as(struct osmo_ss7_as *as, struct osmo_xlm_prim_notify *npar) { struct msgb *msg; unsigned int i, sent = 0; @@ -150,7 +150,7 @@ { struct xua_as_fsm_priv *xafp = (struct xua_as_fsm_priv *) fi->priv; struct osmo_ss7_as *as = xafp->as; - struct m3ua_notify_params npar = { + struct osmo_xlm_prim_notify npar = { .status_type = M3UA_NOTIFY_T_STATCHG, }; diff --git a/src/xua_asp_fsm.c b/src/xua_asp_fsm.c index aafc09f..d38a18a 100644 --- a/src/xua_asp_fsm.c +++ b/src/xua_asp_fsm.c @@ -89,42 +89,42 @@ } t_ack; }; -static struct msgb *xlm_msgb_alloc(void) +struct osmo_xlm_prim *xua_xlm_prim_alloc(enum osmo_xlm_prim_type prim_type, + enum osmo_prim_operation op) { - return msgb_alloc_headroom(2048+128, 128, "xua_asp-xlm msgb"); + struct osmo_xlm_prim *prim; + struct msgb *msg = msgb_alloc_headroom(2048+128, 128, "xua_asp-xlm msgb"); + if (!msg) + return NULL; + + prim = (struct osmo_xlm_prim *) msgb_put(msg, sizeof(*prim)); + osmo_prim_init(&prim->oph, XUA_SAP_LM, prim_type, op, msg); + + return prim; } /* Send a XUA LM Primitive to the XUA Layer Manager (LM) */ -static int send_xlm_prim(struct osmo_fsm_inst *fi, - enum osmo_xlm_prim_type prim_type, - enum osmo_prim_operation op, - const uint8_t *data, unsigned int data_len) +void xua_asp_send_xlm_prim(struct osmo_ss7_asp *asp, struct osmo_xlm_prim *prim) { - struct xua_asp_fsm_priv *xafp = fi->priv; - struct msgb *xlmsg; - struct osmo_xlm_prim *prim; + struct xua_asp_fsm_priv *xafp = asp->fi->priv; struct xua_layer_manager *lm = xafp->lm; - if (!lm || !lm->prim_cb) - return 0; + if (lm && lm->prim_cb) + lm->prim_cb(&prim->oph, xafp->asp); - xlmsg = xlm_msgb_alloc(); - if (!xlmsg) - return -ENOMEM; - prim = (struct osmo_xlm_prim *) msgb_put(xlmsg, sizeof(*prim)); - osmo_prim_init(&prim->oph, XUA_SAP_LM, prim_type, op, xlmsg); - - lm->prim_cb(&prim->oph, xafp->asp); - - return 0; + msgb_free(prim->oph.msg); } /* wrapper around send_xlm_prim for primitives without data */ -static int send_xlm_prim_simple(struct osmo_fsm_inst *fi, - enum osmo_xlm_prim_type prim, +static void send_xlm_prim_simple(struct osmo_fsm_inst *fi, + enum osmo_xlm_prim_type prim_type, enum osmo_prim_operation op) { - return send_xlm_prim(fi, prim, op, NULL, 0); + struct osmo_xlm_prim *prim = xua_xlm_prim_alloc(prim_type, op); + struct xua_asp_fsm_priv *xafp = fi->priv; + if (!prim) + return; + xua_asp_send_xlm_prim(xafp->asp, prim); } /* ask the xUA implementation to transmit a specific message */ diff --git a/src/xua_internal.h b/src/xua_internal.h index 24fcb1c..6a3f723 100644 --- a/src/xua_internal.h +++ b/src/xua_internal.h @@ -43,19 +43,12 @@ extern const struct value_string m3ua_ntfy_stchg_names[]; extern const struct value_string m3ua_ntfy_other_names[]; -#define NOTIFY_PAR_P_ASP_ID (1 << 0) -#define NOTIFY_PAR_P_ROUTE_CTX (1 << 1) - -struct m3ua_notify_params { - uint32_t presence; - uint16_t status_type; - uint16_t status_info; - uint32_t asp_id; - uint32_t route_ctx; - char *info_string; -}; - -struct xua_msg *m3ua_encode_notify(const struct m3ua_notify_params *npar); -int m3ua_decode_notify(struct m3ua_notify_params *npar, void *ctx, +struct xua_msg *m3ua_encode_notify(const struct osmo_xlm_prim_notify *npar); +int m3ua_decode_notify(struct osmo_xlm_prim_notify *npar, void *ctx, const struct xua_msg *xua); int m3ua_rx_rkm(struct osmo_ss7_asp *asp, struct xua_msg *xua); + +struct osmo_xlm_prim *xua_xlm_prim_alloc(enum osmo_xlm_prim_type prim_type, + enum osmo_prim_operation op); + +void xua_asp_send_xlm_prim(struct osmo_ss7_asp *asp, struct osmo_xlm_prim *prim); -- To view, visit https://gerrit.osmocom.org/2261 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I295b9d6755a4bb52a817d2791a302bdd9fc775dd Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Sun Apr 9 16:57:02 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 16:57:02 +0000 Subject: [PATCH] libosmo-sccp[master]: xua: report N-ERROR and N-NOTIFY primitives to layer manager Message-ID: Review at https://gerrit.osmocom.org/2262 xua: report N-ERROR and N-NOTIFY primitives to layer manager Change-Id: I5c2060f0397d2bf510b085a5bb07e7ab176f2742 --- M src/m3ua.c 1 file changed, 12 insertions(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/62/2262/1 diff --git a/src/m3ua.c b/src/m3ua.c index 96991a7..25fb3aa 100644 --- a/src/m3ua.c +++ b/src/m3ua.c @@ -526,10 +526,16 @@ static int m3ua_rx_mgmt_err(struct osmo_ss7_asp *asp, struct xua_msg *xua) { uint32_t err_code = xua_msg_get_u32(xua, M3UA_IEI_ERR_CODE); + struct osmo_xlm_prim *prim; LOGPASP(asp, DLM3UA, LOGL_ERROR, "Received MGMT_ERR '%s': %s\n", get_value_string(m3ua_err_names, err_code), xua_msg_dump(xua, &xua_dialect_m3ua)); + + /* report this to layer manager */ + prim = xua_xlm_prim_alloc(OSMO_XLM_PRIM_M_ERROR, PRIM_OP_INDICATION); + prim->u.error.code = err_code; + xua_asp_send_xlm_prim(asp, prim); /* NEVER return != 0 here, as we cannot respont to an ERR * message with another ERR! */ @@ -540,6 +546,7 @@ { struct osmo_xlm_prim_notify ntfy; const char *type_name, *info_name; + struct osmo_xlm_prim *prim; m3ua_decode_notify(&ntfy, asp, xua); @@ -562,10 +569,14 @@ type_name, info_name, ntfy.info_string ? ntfy.info_string : ""); + /* report this to layer manager */ + prim = xua_xlm_prim_alloc(OSMO_XLM_PRIM_M_NOTIFY, PRIM_OP_INDICATION); + prim->u.notify = ntfy; + xua_asp_send_xlm_prim(asp,prim); + if (ntfy.info_string) talloc_free(ntfy.info_string); - /* TODO: should we report this soemwhere? */ return 0; } -- To view, visit https://gerrit.osmocom.org/2262 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I5c2060f0397d2bf510b085a5bb07e7ab176f2742 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Sun Apr 9 16:57:02 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 16:57:02 +0000 Subject: [PATCH] libosmo-sccp[master]: move layer_manager from xua_asp_fsm priv to osmo_ss7_asp Message-ID: Review at https://gerrit.osmocom.org/2263 move layer_manager from xua_asp_fsm priv to osmo_ss7_asp ... this way it is publicly accessible/reachable Change-Id: I00ec1689bfb068b9067d893fdba14d12d59f73f0 --- M include/osmocom/sigtran/osmo_ss7.h M src/xua_asp_fsm.c 2 files changed, 10 insertions(+), 9 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/63/2263/1 diff --git a/include/osmocom/sigtran/osmo_ss7.h b/include/osmocom/sigtran/osmo_ss7.h index 21c3768..6e35ee6 100644 --- a/include/osmocom/sigtran/osmo_ss7.h +++ b/include/osmocom/sigtran/osmo_ss7.h @@ -13,6 +13,7 @@ struct osmo_ss7_user; struct osmo_sccp_instance; struct osmo_mtp_prim; +struct osmo_xua_layer_manager; int osmo_ss7_init(void); int osmo_ss7_find_free_rctx(struct osmo_ss7_instance *inst); @@ -336,6 +337,9 @@ uint32_t asp_id; bool asp_id_present; + /* Layer Manager to which we talk */ + struct osmo_xua_layer_manager *lm; + struct { char *name; char *description; @@ -366,6 +370,10 @@ * xUA Servers ***********************************************************************/ +struct osmo_xua_layer_manager { + osmo_prim_cb prim_cb; +}; + struct osmo_xua_server { struct llist_head list; struct osmo_ss7_instance *inst; diff --git a/src/xua_asp_fsm.c b/src/xua_asp_fsm.c index d38a18a..e16e26a 100644 --- a/src/xua_asp_fsm.c +++ b/src/xua_asp_fsm.c @@ -67,18 +67,12 @@ { 0, NULL } }; -struct xua_layer_manager { - osmo_prim_cb prim_cb; -}; - /* private data structure for each FSM instance */ struct xua_asp_fsm_priv { /* pointer back to ASP to which we belong */ struct osmo_ss7_asp *asp; /* Role (ASP/SG/IPSP) */ enum xua_asp_role role; - /* Layer Manager to which we talk */ - struct xua_layer_manager *lm; /* routing context[s]: list of 32bit integers */ /* ACTIVE: traffic mode type, tid label, drn label ? */ @@ -106,11 +100,10 @@ /* Send a XUA LM Primitive to the XUA Layer Manager (LM) */ void xua_asp_send_xlm_prim(struct osmo_ss7_asp *asp, struct osmo_xlm_prim *prim) { - struct xua_asp_fsm_priv *xafp = asp->fi->priv; - struct xua_layer_manager *lm = xafp->lm; + struct osmo_xua_layer_manager *lm = asp->lm; if (lm && lm->prim_cb) - lm->prim_cb(&prim->oph, xafp->asp); + lm->prim_cb(&prim->oph, asp); msgb_free(prim->oph.msg); } -- To view, visit https://gerrit.osmocom.org/2263 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I00ec1689bfb068b9067d893fdba14d12d59f73f0 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Sun Apr 9 16:57:02 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 16:57:02 +0000 Subject: [PATCH] libosmo-sccp[master]: send M-SCTP_ESTABLISH.ind to Layer Manager Message-ID: Review at https://gerrit.osmocom.org/2264 send M-SCTP_ESTABLISH.ind to Layer Manager Change-Id: I2904f8ebd97036690ba8a9525b31354c0252123b --- M src/osmo_ss7.c M src/xua_asp_fsm.c M src/xua_internal.h 3 files changed, 25 insertions(+), 6 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/64/2264/1 diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index 185d6b4..a798d25 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -1236,9 +1236,14 @@ LOGPASP(asp, DLSS7, LOGL_INFO, "Client connected %s\n", asp->sock_name); - /* Notify the ASP FSM that the connection has just been - * established */ - osmo_fsm_inst_dispatch(asp->fi, XUA_ASP_E_M_ASP_UP_REQ, NULL); + if (asp->lm && asp->lm->prim_cb) { + /* Notify layer manager that a connection has been + * established */ + xua_asp_send_xlm_prim_simple(asp, OSMO_XLM_PRIM_M_SCTP_ESTABLISH, PRIM_OP_INDICATION); + } else { + /* directly as the ASP FSM to start by sending an ASP-UP ... */ + osmo_fsm_inst_dispatch(asp->fi, XUA_ASP_E_M_ASP_UP_REQ, NULL); + } return 0; } @@ -1383,6 +1388,9 @@ * data */ osmo_stream_srv_set_data(srv, asp); + /* send M-SCTP_ESTABLISH.ind to Layer Manager */ + xua_asp_send_xlm_prim_simple(asp, OSMO_XLM_PRIM_M_SCTP_ESTABLISH, PRIM_OP_INDICATION); + return 0; } diff --git a/src/xua_asp_fsm.c b/src/xua_asp_fsm.c index e16e26a..1570bc9 100644 --- a/src/xua_asp_fsm.c +++ b/src/xua_asp_fsm.c @@ -109,15 +109,23 @@ } /* wrapper around send_xlm_prim for primitives without data */ -static void send_xlm_prim_simple(struct osmo_fsm_inst *fi, +void xua_asp_send_xlm_prim_simple(struct osmo_ss7_asp *asp, enum osmo_xlm_prim_type prim_type, enum osmo_prim_operation op) { struct osmo_xlm_prim *prim = xua_xlm_prim_alloc(prim_type, op); - struct xua_asp_fsm_priv *xafp = fi->priv; if (!prim) return; - xua_asp_send_xlm_prim(xafp->asp, prim); + xua_asp_send_xlm_prim(asp, prim); +} + +static void send_xlm_prim_simple(struct osmo_fsm_inst *fi, + enum osmo_xlm_prim_type prim_type, + enum osmo_prim_operation op) +{ + struct xua_asp_fsm_priv *xafp = fi->priv; + struct osmo_ss7_asp *asp = xafp->asp; + xua_asp_send_xlm_prim_simple(asp, prim_type, op); } /* ask the xUA implementation to transmit a specific message */ diff --git a/src/xua_internal.h b/src/xua_internal.h index 6a3f723..3921309 100644 --- a/src/xua_internal.h +++ b/src/xua_internal.h @@ -52,3 +52,6 @@ enum osmo_prim_operation op); void xua_asp_send_xlm_prim(struct osmo_ss7_asp *asp, struct osmo_xlm_prim *prim); +void xua_asp_send_xlm_prim_simple(struct osmo_ss7_asp *asp, + enum osmo_xlm_prim_type prim_type, + enum osmo_prim_operation op); -- To view, visit https://gerrit.osmocom.org/2264 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I2904f8ebd97036690ba8a9525b31354c0252123b Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Sun Apr 9 16:57:02 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 16:57:02 +0000 Subject: [PATCH] libosmo-sccp[master]: osmo_ss7: default point-code format for parsing/printing wit... Message-ID: Review at https://gerrit.osmocom.org/2265 osmo_ss7: default point-code format for parsing/printing without ss7_instance osmo_ss7_pointcode_print() osmo_ss7_pointcode_parse() etc. now support passing a NULL ss7-instance which will lead to application of the default ITU 3.8.3 point code format. Change-Id: Ifb739e92e31eaaa0343dc57c9af8c9164d00175f --- M include/osmocom/sigtran/osmo_ss7.h M src/osmo_ss7.c 2 files changed, 43 insertions(+), 37 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/65/2265/1 diff --git a/include/osmocom/sigtran/osmo_ss7.h b/include/osmocom/sigtran/osmo_ss7.h index 6e35ee6..cbc6a02 100644 --- a/include/osmocom/sigtran/osmo_ss7.h +++ b/include/osmocom/sigtran/osmo_ss7.h @@ -51,6 +51,11 @@ * SS7 Instances ***********************************************************************/ +struct osmo_ss7_pc_fmt { + char delimiter; + uint8_t component_len[3]; +}; + struct osmo_ss7_instance { /*! member of global list of instances */ struct llist_head list; @@ -78,10 +83,7 @@ /* secondary PCs */ /* capability PCs */ uint8_t network_indicator; - struct { - char delimiter; - uint8_t component_len[3]; - } pc_fmt; + struct osmo_ss7_pc_fmt pc_fmt; } cfg; }; diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index a798d25..fb1cbc4 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -71,7 +71,7 @@ }; #define LOGSS7(inst, level, fmt, args ...) \ - LOGP(DLSS7, level, "%u: " fmt, (inst)->cfg.id, ## args) + LOGP(DLSS7, level, "%u: " fmt, inst ? (inst)->cfg.id : 0, ## args) int osmo_ss7_find_free_rctx(struct osmo_ss7_instance *inst) { @@ -87,6 +87,11 @@ /*********************************************************************** * SS7 Point Code Parsing / Printing ***********************************************************************/ + +static const struct osmo_ss7_pc_fmt default_pc_fmt = { + .delimiter = '.', + .component_len = { 3, 8, 3}, +}; /* like strcat() but appends a single character */ static int strnappendchar(char *str, char c, size_t n) @@ -104,7 +109,7 @@ /* generate a format string for formatting a point code. The result can * e.g. be used with sscanf() or sprintf() */ -static const char *gen_pc_fmtstr(struct osmo_ss7_instance *inst, +static const char *gen_pc_fmtstr(const struct osmo_ss7_pc_fmt *pc_fmt, unsigned int *num_comp_exp) { static char buf[MAX_PC_STR_LEN]; @@ -114,15 +119,15 @@ strcat(buf, "%u"); num_comp++; - if (inst->cfg.pc_fmt.component_len[1] == 0) + if (pc_fmt->component_len[1] == 0) goto out; - strnappendchar(buf, inst->cfg.pc_fmt.delimiter, sizeof(buf)); + strnappendchar(buf, pc_fmt->delimiter, sizeof(buf)); strcat(buf, "%u"); num_comp++; - if (inst->cfg.pc_fmt.component_len[2] == 0) + if (pc_fmt->component_len[2] == 0) goto out; - strnappendchar(buf, inst->cfg.pc_fmt.delimiter, sizeof(buf)); + strnappendchar(buf, pc_fmt->delimiter, sizeof(buf)); strcat(buf, "%u"); num_comp++; out: @@ -133,38 +138,35 @@ /* get number of components we expect for a point code, depending on the * configuration of this ss7_instance */ -static unsigned int num_pc_comp_exp(struct osmo_ss7_instance *inst) +static unsigned int num_pc_comp_exp(const struct osmo_ss7_pc_fmt *pc_fmt) { unsigned int num_comp_exp = 1; - if (inst->cfg.pc_fmt.component_len[1]) + if (pc_fmt->component_len[1]) num_comp_exp++; - if (inst->cfg.pc_fmt.component_len[2]) + if (pc_fmt->component_len[2]) num_comp_exp++; return num_comp_exp; } /* get the total width (in bits) of the point-codes in this ss7_instance */ -static unsigned int get_pc_width(struct osmo_ss7_instance *inst) +static unsigned int get_pc_width(const struct osmo_ss7_pc_fmt *pc_fmt) { - return inst->cfg.pc_fmt.component_len[0] + - inst->cfg.pc_fmt.component_len[1] + - inst->cfg.pc_fmt.component_len[2]; + return pc_fmt->component_len[0] + pc_fmt->component_len[1] + pc_fmt->component_len[2]; } /* get the number of bits we must shift the given component of a point * code in this ss7_instance */ -static unsigned int get_pc_comp_shift(struct osmo_ss7_instance *inst, +static unsigned int get_pc_comp_shift(const struct osmo_ss7_pc_fmt *pc_fmt, unsigned int comp_num) { - uint32_t pc_width = get_pc_width(inst); + uint32_t pc_width = get_pc_width(pc_fmt); switch (comp_num) { case 0: - return pc_width - inst->cfg.pc_fmt.component_len[0]; + return pc_width - pc_fmt->component_len[0]; case 1: - return pc_width - inst->cfg.pc_fmt.component_len[0] - - inst->cfg.pc_fmt.component_len[1]; + return pc_width - pc_fmt->component_len[0] - pc_fmt->component_len[1]; case 2: return 0; default: @@ -172,11 +174,11 @@ } } -static uint32_t pc_comp_shift_and_mask(struct osmo_ss7_instance *inst, +static uint32_t pc_comp_shift_and_mask(const struct osmo_ss7_pc_fmt *pc_fmt, unsigned int comp_num, uint32_t pc) { - unsigned int shift = get_pc_comp_shift(inst, comp_num); - uint32_t mask = (1 << inst->cfg.pc_fmt.component_len[comp_num]) - 1; + unsigned int shift = get_pc_comp_shift(pc_fmt, comp_num); + uint32_t mask = (1 << pc_fmt->component_len[comp_num]) - 1; return (pc >> shift) & mask; } @@ -186,8 +188,9 @@ int osmo_ss7_pointcode_parse(struct osmo_ss7_instance *inst, const char *str) { unsigned int component[3]; - unsigned int num_comp_exp = num_pc_comp_exp(inst); - const char *fmtstr = gen_pc_fmtstr(inst, &num_comp_exp); + const struct osmo_ss7_pc_fmt *pc_fmt = inst ? &inst->cfg.pc_fmt : &default_pc_fmt; + unsigned int num_comp_exp = num_pc_comp_exp(pc_fmt); + const char *fmtstr = gen_pc_fmtstr(pc_fmt, &num_comp_exp); int i, rc; rc = sscanf(str, fmtstr, &component[0], &component[1], &component[2]); @@ -198,16 +201,16 @@ /* check none of the component values exceeds what can be * represented within its bit-width */ for (i = 0; i < num_comp_exp; i++) { - if (component[i] >= (1 << inst->cfg.pc_fmt.component_len[i])) + if (component[i] >= (1 << pc_fmt->component_len[i])) goto err; } /* shift them all together */ - rc = (component[0] << get_pc_comp_shift(inst, 0)); + rc = (component[0] << get_pc_comp_shift(pc_fmt, 0)); if (num_comp_exp > 1) - rc |= (component[1] << get_pc_comp_shift(inst, 1)); + rc |= (component[1] << get_pc_comp_shift(pc_fmt, 1)); if (num_comp_exp > 2) - rc |= (component[2] << get_pc_comp_shift(inst, 2)); + rc |= (component[2] << get_pc_comp_shift(pc_fmt, 2)); return rc; @@ -221,21 +224,22 @@ const char *osmo_ss7_pointcode_print(struct osmo_ss7_instance *inst, uint32_t pc) { static char buf[MAX_PC_STR_LEN]; - unsigned int num_comp_exp = num_pc_comp_exp(inst); - const char *fmtstr = gen_pc_fmtstr(inst, &num_comp_exp); + const struct osmo_ss7_pc_fmt *pc_fmt = inst ? &inst->cfg.pc_fmt : &default_pc_fmt; + unsigned int num_comp_exp = num_pc_comp_exp(pc_fmt); + const char *fmtstr = gen_pc_fmtstr(pc_fmt, &num_comp_exp); OSMO_ASSERT(fmtstr); snprintf(buf, sizeof(buf), fmtstr, - pc_comp_shift_and_mask(inst, 0, pc), - pc_comp_shift_and_mask(inst, 1, pc), - pc_comp_shift_and_mask(inst, 2, pc)); + pc_comp_shift_and_mask(pc_fmt, 0, pc), + pc_comp_shift_and_mask(pc_fmt, 1, pc), + pc_comp_shift_and_mask(pc_fmt, 2, pc)); return buf; } int osmo_ss7_pointcode_parse_mask_or_len(struct osmo_ss7_instance *inst, const char *in) { - unsigned int width = get_pc_width(inst); + unsigned int width = get_pc_width(inst ? &inst->cfg.pc_fmt : &default_pc_fmt); if (in[0] == '/') { /* parse mask by length */ -- To view, visit https://gerrit.osmocom.org/2265 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ifb739e92e31eaaa0343dc57c9af8c9164d00175f Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Sun Apr 9 16:57:03 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 16:57:03 +0000 Subject: [PATCH] libosmo-sccp[master]: m3ua: Remove inbound routing context before routing Message-ID: Review at https://gerrit.osmocom.org/2266 m3ua: Remove inbound routing context before routing After verifying the routing context of an incoming M3UA message, remove the routing context before passing into MTP routing. In the forwarding case, we might want to set a new routing context on the outbound link, and we don't want the routing context IE to show up twice. Change-Id: I7a534cb1da275369c70766c059aaae8157ce6833 --- M src/m3ua.c 1 file changed, 4 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/66/2266/1 diff --git a/src/m3ua.c b/src/m3ua.c index 25fb3aa..7ae6dcf 100644 --- a/src/m3ua.c +++ b/src/m3ua.c @@ -515,6 +515,10 @@ OSMO_ASSERT(dh); m3ua_dh_to_xfer_param(&xua->mtp, dh); + /* remove ROUTE_CTX as in the routing case we want to add a new + * routing context on the outbound side */ + xua_msg_free_tag(xua, M3UA_IEI_ROUTE_CTX); + return m3ua_hmdc_rx_from_l2(asp->inst, xua); out_err: if (err) -- To view, visit https://gerrit.osmocom.org/2266 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I7a534cb1da275369c70766c059aaae8157ce6833 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Sun Apr 9 16:57:03 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 16:57:03 +0000 Subject: [PATCH] libosmo-sccp[master]: osmo_ss7: Fix msgb memory leaks in error paths (asp not conn... Message-ID: Review at https://gerrit.osmocom.org/2267 osmo_ss7: Fix msgb memory leaks in error paths (asp not connected) Change-Id: I031d90348ea243ac5dbdde14365528f3ec8e3709 --- M src/osmo_ss7.c 1 file changed, 2 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/67/2267/1 diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index fb1cbc4..103c05b 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -1421,6 +1421,7 @@ if (!asp->server) { LOGPASP(asp, DLSS7, LOGL_ERROR, "Cannot transmit, no asp->server\n"); /* FIXME: what to do here? delete the route? send DUNA? */ + msgb_free(msg); return -EIO; } osmo_stream_srv_send(asp->server, msg); @@ -1428,6 +1429,7 @@ if (!asp->client) { LOGPASP(asp, DLSS7, LOGL_ERROR, "Cannot transmit, no asp->client\n"); /* FIXME: what to do here? delete the route? send DUNA? */ + msgb_free(msg); return -EIO; } osmo_stream_cli_send(asp->client, msg); -- To view, visit https://gerrit.osmocom.org/2267 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I031d90348ea243ac5dbdde14365528f3ec8e3709 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Sun Apr 9 16:57:03 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 16:57:03 +0000 Subject: [PATCH] libosmo-sccp[master]: osmo_sccp_make_addr_pc_ssn(): Set routing indicator Message-ID: Review at https://gerrit.osmocom.org/2268 osmo_sccp_make_addr_pc_ssn(): Set routing indicator When we crate a sccp address with PC+SSN, we should also set the routing indicator accordingly (OSMO_SCCP_RI_SSN_PC). Change-Id: Ie179df7158624520e90093da063c57f1e3efa0bd --- M src/sccp_helpers.c 1 file changed, 1 insertion(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/68/2268/1 diff --git a/src/sccp_helpers.c b/src/sccp_helpers.c index c588607..76a7c1c 100644 --- a/src/sccp_helpers.c +++ b/src/sccp_helpers.c @@ -39,6 +39,7 @@ void osmo_sccp_make_addr_pc_ssn(struct osmo_sccp_addr *addr, uint32_t pc, uint32_t ssn) { addr->presence = OSMO_SCCP_ADDR_T_SSN | OSMO_SCCP_ADDR_T_PC; + addr->ri = OSMO_SCCP_RI_SSN_PC; addr->ssn = ssn; addr->pc = pc; } -- To view, visit https://gerrit.osmocom.org/2268 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ie179df7158624520e90093da063c57f1e3efa0bd Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Sun Apr 9 16:57:03 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 16:57:03 +0000 Subject: [PATCH] libosmo-sccp[master]: M3UA: Respond with "Unexpected Message" if ASPTM is received... Message-ID: Review at https://gerrit.osmocom.org/2269 M3UA: Respond with "Unexpected Message" if ASPTM is received too soon This was discovered (and fix validated) using m3ua-sgp-aspsm-i-003 of Michale Tuexen's m3ua-testtool. Change-Id: I8b63e7b5e39a7ef8dd66bf014110a04f5f3dc2a2 --- M src/m3ua.c 1 file changed, 2 insertions(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/69/2269/1 diff --git a/src/m3ua.c b/src/m3ua.c index 7ae6dcf..7291d0d 100644 --- a/src/m3ua.c +++ b/src/m3ua.c @@ -623,7 +623,8 @@ return M3UA_ERR_UNSUPP_MSG_TYPE; /* deliver that event to the ASP FSM */ - osmo_fsm_inst_dispatch(asp->fi, event, xua); + if (osmo_fsm_inst_dispatch(asp->fi, event, xua) < 0) + return M3UA_ERR_UNEXPECTED_MSG; return 0; } -- To view, visit https://gerrit.osmocom.org/2269 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I8b63e7b5e39a7ef8dd66bf014110a04f5f3dc2a2 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Sun Apr 9 16:57:04 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 16:57:04 +0000 Subject: [PATCH] libosmo-sccp[master]: M3UA: Make sure to reject unsupported traffic mode types Message-ID: Review at https://gerrit.osmocom.org/2270 M3UA: Make sure to reject unsupported traffic mode types This was discovered (and fix validated) using m3ua-sgp-asptm-i-004 of Michael Tuexen's m3ua-testtool. Change-Id: I76c01189b75ff3084cd4d3944314ec9b9f811dbf --- M src/xua_asp_fsm.c 1 file changed, 32 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/70/2270/1 diff --git a/src/xua_asp_fsm.c b/src/xua_asp_fsm.c index 1570bc9..87f8927 100644 --- a/src/xua_asp_fsm.c +++ b/src/xua_asp_fsm.c @@ -210,6 +210,25 @@ return osmo_ss7_asp_send(asp, msg); } +static int peer_send_error(struct osmo_fsm_inst *fi, uint32_t err_code) +{ + struct xua_asp_fsm_priv *xafp = fi->priv; + struct osmo_ss7_asp *asp = xafp->asp; + struct xua_msg *xua = xua_msg_alloc(); + struct msgb *msg; + + xua->hdr = XUA_HDR(SUA_MSGC_MGMT, SUA_MGMT_ERR); + xua->hdr.version = SUA_VERSION; + xua_msg_add_u32(xua, SUA_IEI_ERR_CODE, err_code); + + msg = xua_to_msg(SUA_VERSION, xua); + xua_msg_free(xua); + if (!msg) + return -1; + + return osmo_ss7_asp_send(asp, msg); +} + static void xua_t_ack_cb(void *data) { struct osmo_fsm_inst *fi = data; @@ -373,6 +392,9 @@ static void xua_asp_fsm_inactive(struct osmo_fsm_inst *fi, uint32_t event, void *data) { + struct xua_msg *xua_in; + uint32_t traf_mode; + check_stop_t_ack(fi, event); switch (event) { case XUA_ASP_E_M_ASP_ACTIVE_REQ: @@ -400,8 +422,18 @@ PRIM_OP_CONFIRM); break; case XUA_ASP_E_ASPTM_ASPAC: + xua_in = data; /* only in role SG */ ENSURE_SG_OR_IPSP(fi, event); + if (xua_msg_find_tag(xua_in, M3UA_IEI_TRAF_MODE_TYP)) { + traf_mode = xua_msg_get_u32(xua_in, M3UA_IEI_TRAF_MODE_TYP); + if (traf_mode != M3UA_TMOD_OVERRIDE && + traf_mode != M3UA_TMOD_LOADSHARE && + traf_mode != M3UA_TMOD_BCAST) { + peer_send_error(fi, M3UA_ERR_UNSUPP_TRAF_MOD_TYP); + break; + } + } /* send ACK */ peer_send(fi, XUA_ASP_E_ASPTM_ASPAC_ACK, NULL); /* transition state and inform layer manager */ -- To view, visit https://gerrit.osmocom.org/2270 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I76c01189b75ff3084cd4d3944314ec9b9f811dbf Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Sun Apr 9 16:57:04 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 16:57:04 +0000 Subject: [PATCH] libosmo-sccp[master]: M3UA: Send "Unexpected Message" when receiving ASP_UP-ACK in... Message-ID: Review at https://gerrit.osmocom.org/2271 M3UA: Send "Unexpected Message" when receiving ASP_UP-ACK in ACTIVE Change-Id: Ibcda68b7acb02bf1580a832baff06ff21cbac713 --- M src/xua_asp_fsm.c 1 file changed, 1 insertion(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/71/2271/1 diff --git a/src/xua_asp_fsm.c b/src/xua_asp_fsm.c index 87f8927..0996db0 100644 --- a/src/xua_asp_fsm.c +++ b/src/xua_asp_fsm.c @@ -527,10 +527,10 @@ * an Error message ("Unexpected Message), and the * remote ASP state is changed to ASP-INACTIVE in all * relevant Application Servers */ - /* FIXME: Send ERROR message */ osmo_fsm_inst_state_chg(fi, XUA_ASP_S_INACTIVE, 0, 0); send_xlm_prim_simple(fi, OSMO_XLM_PRIM_M_ASP_INACTIVE, PRIM_OP_INDICATION); + peer_send_error(fi, M3UA_ERR_UNEXPECTED_MSG); break; } } -- To view, visit https://gerrit.osmocom.org/2271 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ibcda68b7acb02bf1580a832baff06ff21cbac713 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Sun Apr 9 16:57:04 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 16:57:04 +0000 Subject: [PATCH] libosmo-sccp[master]: M3UA: Send opportunistic ASPACT-ACK to ASPACT-REQ in ACTIVE ... Message-ID: Review at https://gerrit.osmocom.org/2272 M3UA: Send opportunistic ASPACT-ACK to ASPACT-REQ in ACTIVE state This was discovered (and fix validated) using m3ua-sgp-asptm-o-001 of Michael Tuexen's m3ua-testtool. Change-Id: I6d254f7a33856e036329aa717a9c03efb1f1289d --- M src/xua_asp_fsm.c 1 file changed, 7 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/72/2272/1 diff --git a/src/xua_asp_fsm.c b/src/xua_asp_fsm.c index 0996db0..2e80506 100644 --- a/src/xua_asp_fsm.c +++ b/src/xua_asp_fsm.c @@ -532,6 +532,12 @@ PRIM_OP_INDICATION); peer_send_error(fi, M3UA_ERR_UNEXPECTED_MSG); break; + case XUA_ASP_E_ASPTM_ASPAC: + /* only in role SG */ + ENSURE_SG_OR_IPSP(fi, event); + /* send ACK */ + peer_send(fi, XUA_ASP_E_ASPTM_ASPAC_ACK, NULL); + break; } } @@ -601,6 +607,7 @@ S(XUA_ASP_E_ASPSM_ASPUP) | S(XUA_ASP_E_ASPTM_ASPIA) | S(XUA_ASP_E_ASPTM_ASPIA_ACK) | + S(XUA_ASP_E_ASPTM_ASPAC) | S(XUA_ASP_E_M_ASP_DOWN_REQ) | S(XUA_ASP_E_M_ASP_INACTIVE_REQ), .out_state_mask = S(XUA_ASP_S_INACTIVE) | -- To view, visit https://gerrit.osmocom.org/2272 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I6d254f7a33856e036329aa717a9c03efb1f1289d Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Sun Apr 9 16:57:05 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 16:57:05 +0000 Subject: [PATCH] libosmo-sccp[master]: M3UA: Handle opportunistic ASPIA in INACTIVE state Message-ID: Review at https://gerrit.osmocom.org/2273 M3UA: Handle opportunistic ASPIA in INACTIVE state This was discovered (and fix validated) using m3ua-sgp-asptm-o-003 of Michale Tuexen's m3ua-testtool. Change-Id: If231072655170fe52dae738882dd63b1d0a60cf9 --- M src/xua_asp_fsm.c 1 file changed, 6 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/73/2273/1 diff --git a/src/xua_asp_fsm.c b/src/xua_asp_fsm.c index 2e80506..9c4a8ca 100644 --- a/src/xua_asp_fsm.c +++ b/src/xua_asp_fsm.c @@ -460,6 +460,11 @@ * is taken. */ peer_send(fi, XUA_ASP_E_ASPSM_ASPUP_ACK, NULL); break; + case XUA_ASP_E_ASPTM_ASPIA: + /* only in role SG */ + ENSURE_SG_OR_IPSP(fi, event); + peer_send(fi, XUA_ASP_E_ASPTM_ASPIA_ACK, NULL); + break; } } @@ -592,6 +597,7 @@ S(XUA_ASP_E_M_ASP_DOWN_REQ) | S(XUA_ASP_E_ASPTM_ASPAC) | S(XUA_ASP_E_ASPTM_ASPAC_ACK) | + S(XUA_ASP_E_ASPTM_ASPIA) | S(XUA_ASP_E_ASPSM_ASPDN) | S(XUA_ASP_E_ASPSM_ASPDN_ACK) | S(XUA_ASP_E_ASPSM_ASPUP), -- To view, visit https://gerrit.osmocom.org/2273 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: If231072655170fe52dae738882dd63b1d0a60cf9 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Sun Apr 9 16:57:06 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 16:57:06 +0000 Subject: [PATCH] libosmo-sccp[master]: M3UA: Properly reject invalid/unknown routing context Message-ID: Review at https://gerrit.osmocom.org/2274 M3UA: Properly reject invalid/unknown routing context This was discovered (and fix validated) using m3ua-sgp-asptm-i-005 of Michael Tuexne's m3ua-testtool. Change-Id: I217ae287e22371e36dda0f87a7737b62fb1bf2d6 --- M src/xua_asp_fsm.c 1 file changed, 9 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/74/2274/1 diff --git a/src/xua_asp_fsm.c b/src/xua_asp_fsm.c index 9c4a8ca..2830334 100644 --- a/src/xua_asp_fsm.c +++ b/src/xua_asp_fsm.c @@ -392,6 +392,8 @@ static void xua_asp_fsm_inactive(struct osmo_fsm_inst *fi, uint32_t event, void *data) { + struct xua_asp_fsm_priv *xafp = fi->priv; + struct osmo_ss7_asp *asp = xafp->asp; struct xua_msg *xua_in; uint32_t traf_mode; @@ -434,6 +436,13 @@ break; } } + if (xua_msg_find_tag(xua_in, M3UA_IEI_ROUTE_CTX)) { + uint32_t rctx = xua_msg_get_u32(xua_in, M3UA_IEI_ROUTE_CTX); + if (!osmo_ss7_as_find_by_rctx(asp->inst, rctx)) { + peer_send_error(fi, M3UA_ERR_INVAL_ROUT_CTX); + break; + } + } /* send ACK */ peer_send(fi, XUA_ASP_E_ASPTM_ASPAC_ACK, NULL); /* transition state and inform layer manager */ -- To view, visit https://gerrit.osmocom.org/2274 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I217ae287e22371e36dda0f87a7737b62fb1bf2d6 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Sun Apr 9 17:25:57 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 17:25:57 +0000 Subject: libosmo-sccp[master]: xua_asp_fsm: Always return BEAT-ACK for BEAT, including BEAT... In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2238 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I836e0940a8dbb0f55ddf132202a5f0d51473b82d Gerrit-PatchSet: 2 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sun Apr 9 17:26:22 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 17:26:22 +0000 Subject: libosmo-sccp[master]: m3ua: Include RC IE of AS in Tx; validate RC IE on Rx In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2237 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I7db36a23185f82d8d68e318afe89ec5127c40333 Gerrit-PatchSet: 2 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sun Apr 9 17:26:46 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 17:26:46 +0000 Subject: libosmo-sccp[master]: M3UA: Properly reject invalid/unknown routing context In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2274 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I217ae287e22371e36dda0f87a7737b62fb1bf2d6 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sun Apr 9 17:27:32 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 17:27:32 +0000 Subject: libosmo-sccp[master]: sigtran: fix various memory leaks (msgb and xua_msg) In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2242 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I708505d129da5824c69b31a13a9c93201929bada Gerrit-PatchSet: 2 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sun Apr 9 17:27:42 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 17:27:42 +0000 Subject: libosmo-sccp[master]: sccp: add osmo_sccp_user_{get, set}_priv() API function In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2234 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ia68a36dc18a7d754d63ae29c86d68e495b5c4134 Gerrit-PatchSet: 2 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sun Apr 9 17:48:40 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 17:48:40 +0000 Subject: [PATCH] libosmo-sccp[master]: M3UA: Ensure XFER messages are not sent on stream 0 Message-ID: Review at https://gerrit.osmocom.org/2275 M3UA: Ensure XFER messages are not sent on stream 0 According to the RFC, Stream ID 0 MUST not be used for XFER/DATA messages. This was discovered (and fix validated) using m3ua-sgp-mtr-v-003-alternate of Michale Tuexen's m3ua-testtool. Change-Id: I80b941426b5106e091bd1becff0ae97958aff97c --- M src/m3ua.c 1 file changed, 9 insertions(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/75/2275/1 diff --git a/src/m3ua.c b/src/m3ua.c index 7291d0d..ee96c6e 100644 --- a/src/m3ua.c +++ b/src/m3ua.c @@ -432,6 +432,10 @@ return -1; } + if (xua->hdr.msg_class == M3UA_MSGC_XFER) + msgb_sctp_stream(msg) = 1; + else + msgb_sctp_stream(msg) = 0; msgb_sctp_ppid(msg) = M3UA_PPID; return osmo_ss7_asp_send(asp, msg); } @@ -666,12 +670,16 @@ goto out; } - /* TODO: check for SCTP Strema ID */ /* TODO: check if any AS configured in ASP */ /* TODO: check for valid routing context */ switch (xua->hdr.msg_class) { case M3UA_MSGC_XFER: + /* The DATA message MUST NOT be sent on stream 0. */ + if (msgb_sctp_stream(msg) == 0) { + rc = M3UA_ERR_INVAL_STREAM_ID; + break; + } rc = m3ua_rx_xfer(asp, xua); break; case M3UA_MSGC_ASPSM: -- To view, visit https://gerrit.osmocom.org/2275 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I80b941426b5106e091bd1becff0ae97958aff97c Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Sun Apr 9 17:48:41 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 17:48:41 +0000 Subject: [PATCH] libosmo-sccp[master]: M3UA: Reject Message Class XFER / Type != DATA Message-ID: Review at https://gerrit.osmocom.org/2276 M3UA: Reject Message Class XFER / Type != DATA This was discovered (and fix validated) using m3ua-sgp-mtr-i-003 of Michael Tuexen's m3ua-testtol. Change-Id: I7498f606b031f5a6dfb538d9900c744da6aed36f --- M src/m3ua.c 1 file changed, 3 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/76/2276/1 diff --git a/src/m3ua.c b/src/m3ua.c index ee96c6e..83c8320 100644 --- a/src/m3ua.c +++ b/src/m3ua.c @@ -499,6 +499,9 @@ struct xua_msg *err = NULL; struct osmo_ss7_as *as; + if (xua->hdr.msg_type != M3UA_XFER_DATA) + return M3UA_ERR_UNSUPP_MSG_TYPE; + /* Use routing context IE to look up the AS for which the * message was received. */ as = osmo_ss7_as_find_by_rctx(asp->inst, rctx); -- To view, visit https://gerrit.osmocom.org/2276 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I7498f606b031f5a6dfb538d9900c744da6aed36f Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Sun Apr 9 17:48:41 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 17:48:41 +0000 Subject: [PATCH] libosmo-sccp[master]: m3ua: cosmetic clanup. We can simply return the M3UA errror... Message-ID: Review at https://gerrit.osmocom.org/2277 m3ua: cosmetic clanup. We can simply return the M3UA errror code Change-Id: I6ed04a4f78e618938484aeab62dbcfb3f310998d --- M src/m3ua.c 1 file changed, 6 insertions(+), 15 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/77/2277/1 diff --git a/src/m3ua.c b/src/m3ua.c index 83c8320..a6ac677 100644 --- a/src/m3ua.c +++ b/src/m3ua.c @@ -496,7 +496,6 @@ { uint32_t rctx = xua_msg_get_u32(xua, M3UA_IEI_ROUTE_CTX); struct m3ua_data_hdr *dh; - struct xua_msg *err = NULL; struct osmo_ss7_as *as; if (xua->hdr.msg_type != M3UA_XFER_DATA) @@ -505,15 +504,13 @@ /* Use routing context IE to look up the AS for which the * message was received. */ as = osmo_ss7_as_find_by_rctx(asp->inst, rctx); - if (!as) { - err = m3ua_gen_error(M3UA_ERR_INVAL_ROUT_CTX); - goto out_err; - } + if (!as) + return M3UA_ERR_INVAL_ROUT_CTX; + /* Verify that this ASP ix part of the AS. */ - if (!osmo_ss7_as_has_asp(as, asp)) { - err = m3ua_gen_error(M3UA_ERR_NO_CONFGD_AS_FOR_ASP); - goto out_err; - } + if (!osmo_ss7_as_has_asp(as, asp)) + return M3UA_ERR_NO_CONFGD_AS_FOR_ASP; + /* FIXME: check for AS state == ACTIVE */ /* store the MTP-level information in the xua_msg for use by @@ -527,11 +524,6 @@ xua_msg_free_tag(xua, M3UA_IEI_ROUTE_CTX); return m3ua_hmdc_rx_from_l2(asp->inst, xua); -out_err: - if (err) - m3ua_tx_xua_asp(asp, err); - - return -1; } static int m3ua_rx_mgmt_err(struct osmo_ss7_asp *asp, struct xua_msg *xua) @@ -688,7 +680,6 @@ case M3UA_MSGC_ASPSM: case M3UA_MSGC_ASPTM: rc = m3ua_rx_asp(asp, xua); - break; break; case M3UA_MSGC_MGMT: rc = m3ua_rx_mgmt(asp, xua); -- To view, visit https://gerrit.osmocom.org/2277 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I6ed04a4f78e618938484aeab62dbcfb3f310998d Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Sun Apr 9 17:53:20 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 17:53:20 +0000 Subject: [PATCH] libosmocore[master]: Add struct osmo_prim_event_map and osmo_event_for_prim() Message-ID: Review at https://gerrit.osmocom.org/2278 Add struct osmo_prim_event_map and osmo_event_for_prim() This can be used to map from an osmo_prim to an osmo_fsm event. Change-Id: I52350f4ebe97811b2a692e5a69a2cd39a853583c --- M include/osmocom/core/prim.h M src/prim.c 2 files changed, 32 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/78/2278/1 diff --git a/include/osmocom/core/prim.h b/include/osmocom/core/prim.h index 99a71d5..f04e15e 100644 --- a/include/osmocom/core/prim.h +++ b/include/osmocom/core/prim.h @@ -57,4 +57,18 @@ /*! \brief primitive handler callback type */ typedef int (*osmo_prim_cb)(struct osmo_prim_hdr *oph, void *ctx); +/*! \brief magic value to be used as final record of \ref + * osmo_prim_event_map */ +#define OSMO_NO_EVENT 0xFFFFFFFF + +/*! \brief single entry in a SAP/PRIM/OP -> EVENT map */ +struct osmo_prim_event_map { + unsigned int sap; /*!< SAP to match */ + unsigned int primitive; /*!< primtiive to match */ + enum osmo_prim_operation operation; /*!< operation to match */ + uint32_t event; /*!< event as result if above match */ +}; + +uint32_t osmo_event_for_prim(const struct osmo_prim_hdr *oph, + const struct osmo_prim_event_map *maps); /*! @} */ diff --git a/src/prim.c b/src/prim.c index 3f41c41..5851f6f 100644 --- a/src/prim.c +++ b/src/prim.c @@ -10,3 +10,21 @@ { PRIM_OP_CONFIRM, "confirm" }, { 0, NULL } }; + +/*! \brief resolve the (fsm) event for a given primitive using a map + * \param[in] oph primitive header used as key for match + * \param[in] maps list of mappings from primitive to event + * \returns event determined by map; \ref OSMO_NO_EVENT if no match */ +uint32_t osmo_event_for_prim(const struct osmo_prim_hdr *oph, + const struct osmo_prim_event_map *maps) +{ + const struct osmo_prim_event_map *map; + + for (map = maps; map->event != OSMO_NO_EVENT; map++) { + if (map->sap == oph->sap && + map->primitive == oph->primitive && + map->operation == oph->operation) + return map->event; + } + return OSMO_NO_EVENT; +} -- To view, visit https://gerrit.osmocom.org/2278 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I52350f4ebe97811b2a692e5a69a2cd39a853583c Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Sun Apr 9 17:59:04 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 17:59:04 +0000 Subject: libosmocore[master]: Add struct osmo_prim_event_map and osmo_event_for_prim() In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2278 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I52350f4ebe97811b2a692e5a69a2cd39a853583c Gerrit-PatchSet: 2 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sun Apr 9 17:59:06 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 17:59:06 +0000 Subject: [MERGED] libosmocore[master]: Add struct osmo_prim_event_map and osmo_event_for_prim() In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: Add struct osmo_prim_event_map and osmo_event_for_prim() ...................................................................... Add struct osmo_prim_event_map and osmo_event_for_prim() This can be used to map from an osmo_prim to an osmo_fsm event. Change-Id: I52350f4ebe97811b2a692e5a69a2cd39a853583c --- M include/osmocom/core/prim.h M src/prim.c 2 files changed, 32 insertions(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/include/osmocom/core/prim.h b/include/osmocom/core/prim.h index 99a71d5..f04e15e 100644 --- a/include/osmocom/core/prim.h +++ b/include/osmocom/core/prim.h @@ -57,4 +57,18 @@ /*! \brief primitive handler callback type */ typedef int (*osmo_prim_cb)(struct osmo_prim_hdr *oph, void *ctx); +/*! \brief magic value to be used as final record of \ref + * osmo_prim_event_map */ +#define OSMO_NO_EVENT 0xFFFFFFFF + +/*! \brief single entry in a SAP/PRIM/OP -> EVENT map */ +struct osmo_prim_event_map { + unsigned int sap; /*!< SAP to match */ + unsigned int primitive; /*!< primtiive to match */ + enum osmo_prim_operation operation; /*!< operation to match */ + uint32_t event; /*!< event as result if above match */ +}; + +uint32_t osmo_event_for_prim(const struct osmo_prim_hdr *oph, + const struct osmo_prim_event_map *maps); /*! @} */ diff --git a/src/prim.c b/src/prim.c index 3f41c41..5851f6f 100644 --- a/src/prim.c +++ b/src/prim.c @@ -10,3 +10,21 @@ { PRIM_OP_CONFIRM, "confirm" }, { 0, NULL } }; + +/*! \brief resolve the (fsm) event for a given primitive using a map + * \param[in] oph primitive header used as key for match + * \param[in] maps list of mappings from primitive to event + * \returns event determined by map; \ref OSMO_NO_EVENT if no match */ +uint32_t osmo_event_for_prim(const struct osmo_prim_hdr *oph, + const struct osmo_prim_event_map *maps) +{ + const struct osmo_prim_event_map *map; + + for (map = maps; map->event != OSMO_NO_EVENT; map++) { + if (map->sap == oph->sap && + map->primitive == oph->primitive && + map->operation == oph->operation) + return map->event; + } + return OSMO_NO_EVENT; +} -- To view, visit https://gerrit.osmocom.org/2278 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I52350f4ebe97811b2a692e5a69a2cd39a853583c Gerrit-PatchSet: 2 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sun Apr 9 18:25:31 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 18:25:31 +0000 Subject: libosmo-sccp[master]: Allow clients to specify local IP/port In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2254 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ief7ce8181442fd0f51c34cf598269ed3a6beacea Gerrit-PatchSet: 2 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sun Apr 9 18:25:44 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 18:25:44 +0000 Subject: libosmo-sccp[master]: sccp_scoc: Move osmo_prim_event_map to libosmocore In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2255 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ic1f22ae2e8d786bfe4bbb84e8eb9f8ae4d93d899 Gerrit-PatchSet: 2 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sun Apr 9 18:25:55 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 18:25:55 +0000 Subject: libosmo-sccp[master]: protocol/m3ua.h: Add definition for RKM reg/dereg result codes In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2256 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I16db7847e20501b89cc487029b29c8796b10bb84 Gerrit-PatchSet: 2 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sun Apr 9 18:26:19 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 18:26:19 +0000 Subject: libosmo-sccp[master]: Add osmo_ss7_find_free_rctx() function to get unused rctx In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2258 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I0186e25a1b3a325c6b0e3f50ef1590c4de6dbef6 Gerrit-PatchSet: 2 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sun Apr 9 18:26:38 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 18:26:38 +0000 Subject: libosmo-sccp[master]: osmo_ss7: Add support for dynamic ASP registration In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2259 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ie48898202acbdbfe144fdd5851dfedbb554b11aa Gerrit-PatchSet: 2 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sun Apr 9 18:27:28 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 18:27:28 +0000 Subject: libosmo-sccp[master]: xua: move notfiy parameters from xua_internal to sigtran_sap... In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2261 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I295b9d6755a4bb52a817d2791a302bdd9fc775dd Gerrit-PatchSet: 2 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sun Apr 9 18:27:34 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 18:27:34 +0000 Subject: libosmo-sccp[master]: xua: report N-ERROR and N-NOTIFY primitives to layer manager In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2262 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I5c2060f0397d2bf510b085a5bb07e7ab176f2742 Gerrit-PatchSet: 2 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sun Apr 9 18:27:49 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 18:27:49 +0000 Subject: libosmo-sccp[master]: move layer_manager from xua_asp_fsm priv to osmo_ss7_asp In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2263 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I00ec1689bfb068b9067d893fdba14d12d59f73f0 Gerrit-PatchSet: 2 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sun Apr 9 18:27:52 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 18:27:52 +0000 Subject: libosmo-sccp[master]: send M-SCTP_ESTABLISH.ind to Layer Manager In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2264 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I2904f8ebd97036690ba8a9525b31354c0252123b Gerrit-PatchSet: 2 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sun Apr 9 18:29:47 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 18:29:47 +0000 Subject: [PATCH] libosmo-sccp[master]: xua_msg: Add xua_from_nested() helper function for nested IEs Message-ID: Review at https://gerrit.osmocom.org/2279 xua_msg: Add xua_from_nested() helper function for nested IEs ... and add a test case to ensure it continues to work. Change-Id: Iee434886598b528d23ddce0490dcc782e0f5d6ae --- M include/osmocom/sigtran/xua_msg.h M src/xua_msg.c M tests/xua/xua_test.c M tests/xua/xua_test.ok 4 files changed, 86 insertions(+), 21 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/79/2279/1 diff --git a/include/osmocom/sigtran/xua_msg.h b/include/osmocom/sigtran/xua_msg.h index e0e1bcf..423adbc 100644 --- a/include/osmocom/sigtran/xua_msg.h +++ b/include/osmocom/sigtran/xua_msg.h @@ -82,6 +82,8 @@ struct xua_msg *xua_from_msg(const int version, uint16_t len, uint8_t *data); struct msgb *xua_to_msg(const int version, struct xua_msg *msg); +struct xua_msg *xua_from_nested(struct xua_msg_part *outer); + int msgb_t16l16vp_put(struct msgb *msg, uint16_t tag, uint16_t len, const uint8_t *data); int msgb_t16l16vp_put_u32(struct msgb *msg, uint16_t tag, uint32_t val); int xua_msg_add_u32(struct xua_msg *xua, uint16_t iei, uint32_t val); diff --git a/src/xua_msg.c b/src/xua_msg.c index cb487c8..05430a4 100644 --- a/src/xua_msg.c +++ b/src/xua_msg.c @@ -112,12 +112,39 @@ return xua_msg_add_data(xua_out, tag_out, part->len, part->dat); } -struct xua_msg *xua_from_msg(const int version, uint16_t len, uint8_t *data) +static int xua_from_msg_common(struct xua_msg *msg, const uint8_t *data, uint16_t pos, uint16_t len) { struct xua_parameter_hdr *par; + uint16_t par_len, padding; + int rc; + + while (pos + sizeof(*par) < len) { + par = (struct xua_parameter_hdr *) &data[pos]; + par_len = ntohs(par->len); + + if (pos + par_len > len || par_len < 4) + return -1; + + rc = xua_msg_add_data(msg, ntohs(par->tag), + par_len - 4, par->data); + if (rc != 0) + return -1; + + pos += par_len; + + /* move over the padding */ + padding = (4 - (par_len % 4)) & 0x3; + pos += padding; + } + + return 0; +} + +struct xua_msg *xua_from_msg(const int version, uint16_t len, uint8_t *data) +{ struct xua_common_hdr *hdr; struct xua_msg *msg; - uint16_t pos, par_len, padding; + uint16_t pos; int rc; msg = xua_msg_alloc(); @@ -136,31 +163,33 @@ msg->hdr = *hdr; pos = sizeof(*hdr); - while (pos + sizeof(*par) < len) { - par = (struct xua_parameter_hdr *) &data[pos]; - par_len = ntohs(par->len); + rc = xua_from_msg_common(msg, data, pos, len); + if (rc < 0) + goto fail; - if (pos + par_len > len || par_len < 4) - goto fail; - - rc = xua_msg_add_data(msg, ntohs(par->tag), - par_len - 4, par->data); - if (rc != 0) - goto fail; - - pos += par_len; - - /* move over the padding */ - padding = (4 - (par_len % 4)) & 0x3; - pos += padding; - } - - /* TODO: parse */ return msg; fail: xua_msg_free(msg); return NULL; + +} + +struct xua_msg *xua_from_nested(struct xua_msg_part *outer) +{ + struct xua_msg *msg = xua_msg_alloc(); + int rc; + + if (!msg) + return NULL; + + rc = xua_from_msg_common(msg, outer->dat, 0, outer->len); + if (rc < 0) { + xua_msg_free(msg); + return NULL; + } + + return msg; } struct msgb *xua_to_msg(const int version, struct xua_msg *xua) diff --git a/tests/xua/xua_test.c b/tests/xua/xua_test.c index 74d91c4..d1aa564 100644 --- a/tests/xua/xua_test.c +++ b/tests/xua/xua_test.c @@ -1,4 +1,5 @@ /* (C) 2011 by Holger Hans Peter Freyther + * (C) 2017 by Harald Welte * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by @@ -21,6 +22,7 @@ #include #include +#include #include #include @@ -355,6 +357,35 @@ } } +/* M3UA message with RKM-REG contents */ +static const uint8_t rkm_reg[] = { + 0x01, 0x00, 0x09, 0x01, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x04, 0x00, 0x0e, 0x4d, 0x33, 0x55, 0x41, + 0x20, 0x72, 0x6f, 0x63, 0x6b, 0x73, 0x00, 0x00, 0x02, 0x07, 0x00, 0x14, 0x02, 0x0a, 0x00, 0x08, + 0x00, 0x00, 0x00, 0x01, 0x02, 0x0b, 0x00, 0x08, 0x00, 0x00, 0x00, 0x17, +}; + +static void test_rkm(void) +{ + struct xua_msg *xua, *nested; + struct xua_msg_part *rkey; + + printf("Parsing M3UA Message\n"); + xua = xua_from_msg(M3UA_VERSION, sizeof(rkm_reg), (uint8_t *)rkm_reg); + OSMO_ASSERT(xua); + OSMO_ASSERT(xua->hdr.msg_class == M3UA_MSGC_RKM); + OSMO_ASSERT(xua->hdr.msg_type == M3UA_RKM_REG_REQ); + OSMO_ASSERT(xua_msg_find_tag(xua, M3UA_IEI_INFO_STRING)); + rkey = xua_msg_find_tag(xua, M3UA_IEI_ROUT_KEY); + OSMO_ASSERT(rkey); + OSMO_ASSERT(rkey->len == 16); + + printf("Parsing Nested M3UA Routing Key IE\n"); + nested = xua_from_nested(rkey); + OSMO_ASSERT(nested); + OSMO_ASSERT(xua_msg_get_u32(nested, M3UA_IEI_LOC_RKEY_ID) == 1); + OSMO_ASSERT(xua_msg_get_u32(nested, M3UA_IEI_DEST_PC) == 23); +} + static const struct log_info_cat default_categories[] = { [0] = { @@ -380,6 +411,7 @@ test_sccp_addr_parser(); test_helpers(); test_sccp2sua(); + test_rkm(); printf("All tests passed.\n"); return 0; diff --git a/tests/xua/xua_test.ok b/tests/xua/xua_test.ok index a9fba1d..2184902 100644 --- a/tests/xua/xua_test.ok +++ b/tests/xua/xua_test.ok @@ -128,4 +128,6 @@ PART(T=Data,L=154,D=6581974804260001984904510103df6c8188a181850201440201073080a780a08004012b30803012830110840107850791445776671697860120300682011884010400000000a306040142840105a306040151840105a306040131840105a309040112840105820102a309040111840105810101a306040114840100a30b0401418401043003830110a30b040141840104300382011800000000) Re-Encoding decoded SUA to SCCP SCCP Output: 09 81 03 0d 18 0a 12 07 00 12 04 53 84 09 00 17 0b 12 06 00 12 04 44 87 20 00 20 65 9a 65 81 97 48 04 26 00 01 98 49 04 51 01 03 df 6c 81 88 a1 81 85 02 01 44 02 01 07 30 80 a7 80 a0 80 04 01 2b 30 80 30 12 83 01 10 84 01 07 85 07 91 44 57 76 67 16 97 86 01 20 30 06 82 01 18 84 01 04 00 00 00 00 a3 06 04 01 42 84 01 05 a3 06 04 01 51 84 01 05 a3 06 04 01 31 84 01 05 a3 09 04 01 12 84 01 05 82 01 02 a3 09 04 01 11 84 01 05 81 01 01 a3 06 04 01 14 84 01 00 a3 0b 04 01 41 84 01 04 30 03 83 01 10 a3 0b 04 01 41 84 01 04 30 03 82 01 18 00 00 00 00 +Parsing M3UA Message +Parsing Nested M3UA Routing Key IE All tests passed. -- To view, visit https://gerrit.osmocom.org/2279 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Iee434886598b528d23ddce0490dcc782e0f5d6ae Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Sun Apr 9 18:31:29 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 18:31:29 +0000 Subject: [ABANDON] libosmo-sccp[master]: xua_msg: Add xua_from_nested() helper function for nested IEs In-Reply-To: References: Message-ID: Harald Welte has abandoned this change. Change subject: xua_msg: Add xua_from_nested() helper function for nested IEs ...................................................................... Abandoned replaced by Iee434886598b528d23ddce0490dcc782e0f5d6ae -- To view, visit https://gerrit.osmocom.org/2257 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: abandon Gerrit-Change-Id: If664ac20f43eb5c8e11bca6e61eb372e25613789 Gerrit-PatchSet: 2 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:22:37 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:22:37 +0000 Subject: libosmo-sccp[master]: osmo_ss7: default point-code format for parsing/printing wit... In-Reply-To: References: Message-ID: Patch Set 3: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2265 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ifb739e92e31eaaa0343dc57c9af8c9164d00175f Gerrit-PatchSet: 3 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:23:13 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:23:13 +0000 Subject: libosmo-sccp[master]: m3ua: Remove inbound routing context before routing In-Reply-To: References: Message-ID: Patch Set 3: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2266 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I7a534cb1da275369c70766c059aaae8157ce6833 Gerrit-PatchSet: 3 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:23:18 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:23:18 +0000 Subject: libosmo-sccp[master]: osmo_ss7: Fix msgb memory leaks in error paths (asp not conn... In-Reply-To: References: Message-ID: Patch Set 3: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2267 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I031d90348ea243ac5dbdde14365528f3ec8e3709 Gerrit-PatchSet: 3 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:23:20 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:23:20 +0000 Subject: libosmo-sccp[master]: osmo_sccp_make_addr_pc_ssn(): Set routing indicator In-Reply-To: References: Message-ID: Patch Set 3: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2268 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ie179df7158624520e90093da063c57f1e3efa0bd Gerrit-PatchSet: 3 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:23:22 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:23:22 +0000 Subject: libosmo-sccp[master]: M3UA: Respond with "Unexpected Message" if ASPTM is received... In-Reply-To: References: Message-ID: Patch Set 3: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2269 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I8b63e7b5e39a7ef8dd66bf014110a04f5f3dc2a2 Gerrit-PatchSet: 3 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:23:37 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:23:37 +0000 Subject: libosmo-sccp[master]: M3UA: Make sure to reject unsupported traffic mode types In-Reply-To: References: Message-ID: Patch Set 3: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2270 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I76c01189b75ff3084cd4d3944314ec9b9f811dbf Gerrit-PatchSet: 3 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:23:55 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:23:55 +0000 Subject: libosmo-sccp[master]: M3UA: Send "Unexpected Message" when receiving ASP_UP-ACK in... In-Reply-To: References: Message-ID: Patch Set 3: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2271 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ibcda68b7acb02bf1580a832baff06ff21cbac713 Gerrit-PatchSet: 3 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:24:05 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:24:05 +0000 Subject: libosmo-sccp[master]: M3UA: Send opportunistic ASPACT-ACK to ASPACT-REQ in ACTIVE ... In-Reply-To: References: Message-ID: Patch Set 3: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2272 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I6d254f7a33856e036329aa717a9c03efb1f1289d Gerrit-PatchSet: 3 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:24:15 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:24:15 +0000 Subject: libosmo-sccp[master]: M3UA: Handle opportunistic ASPIA in INACTIVE state In-Reply-To: References: Message-ID: Patch Set 3: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2273 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: If231072655170fe52dae738882dd63b1d0a60cf9 Gerrit-PatchSet: 3 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:24:43 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:24:43 +0000 Subject: libosmo-sccp[master]: M3UA: Reject Message Class XFER / Type != DATA In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2276 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I7498f606b031f5a6dfb538d9900c744da6aed36f Gerrit-PatchSet: 2 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:24:55 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:24:55 +0000 Subject: libosmo-sccp[master]: m3ua: cosmetic clanup. We can simply return the M3UA errror... In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2277 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I6ed04a4f78e618938484aeab62dbcfb3f310998d Gerrit-PatchSet: 2 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:25:05 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:25:05 +0000 Subject: libosmo-sccp[master]: xua_msg: Add xua_from_nested() helper function for nested IEs In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2279 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Iee434886598b528d23ddce0490dcc782e0f5d6ae Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:25:13 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:25:13 +0000 Subject: libosmo-sccp[master]: Add M3UA RKM (routing key management) support, SGW side only In-Reply-To: References: Message-ID: Patch Set 3: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2260 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I9b1cf438a42519c0fe2f555c1672fafa499122a1 Gerrit-PatchSet: 3 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:25:50 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:25:50 +0000 Subject: libosmo-sccp[master]: M3UA: Ensure XFER messages are not sent on stream 0 In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2275 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I80b941426b5106e091bd1becff0ae97958aff97c Gerrit-PatchSet: 2 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:28:45 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:28:45 +0000 Subject: [PATCH] libosmo-sccp[master]: Add M3UA RKM (routing key management) support, SGW side only In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2260 to look at the new patch set (#4). Add M3UA RKM (routing key management) support, SGW side only Change-Id: I9b1cf438a42519c0fe2f555c1672fafa499122a1 --- M src/Makefile.am M src/m3ua.c M src/xua_internal.h A src/xua_rkm.c 4 files changed, 301 insertions(+), 2 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/60/2260/4 diff --git a/src/Makefile.am b/src/Makefile.am index a4cfeeb..7867282 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -28,7 +28,7 @@ libosmo_sigtran_la_SOURCES = sccp_sap.c sua.c m3ua.c xua_msg.c sccp_helpers.c \ sccp2sua.c sccp_scrc.c sccp_sclc.c sccp_scoc.c \ - sccp_user.c \ + sccp_user.c xua_rkm.c \ osmo_ss7.c osmo_ss7_hmrt.c xua_asp_fsm.c xua_as_fsm.c libosmo_sigtran_la_LDFLAGS = -version-info $(LIBVERSION) -no-undefined -export-symbols-regex '^osmo_' libosmo_sigtran_la_LIBADD = $(LIBOSMOCORE_LIBS) $(LIBOSMONETIF_LIBS) $(LIBSCTP_LIBS) diff --git a/src/m3ua.c b/src/m3ua.c index 4f20c6e..5708985 100644 --- a/src/m3ua.c +++ b/src/m3ua.c @@ -666,8 +666,10 @@ case M3UA_MSGC_MGMT: rc = m3ua_rx_mgmt(asp, xua); break; - case M3UA_MSGC_SNM: case M3UA_MSGC_RKM: + rc = m3ua_rx_rkm(asp, xua); + break; + case M3UA_MSGC_SNM: /* FIXME */ LOGPASP(asp, DLM3UA, LOGL_NOTICE, "Received unsupported M3UA " "Message Class %u\n", xua->hdr.msg_class); diff --git a/src/xua_internal.h b/src/xua_internal.h index c6f79b7..24fcb1c 100644 --- a/src/xua_internal.h +++ b/src/xua_internal.h @@ -58,3 +58,4 @@ struct xua_msg *m3ua_encode_notify(const struct m3ua_notify_params *npar); int m3ua_decode_notify(struct m3ua_notify_params *npar, void *ctx, const struct xua_msg *xua); +int m3ua_rx_rkm(struct osmo_ss7_asp *asp, struct xua_msg *xua); diff --git a/src/xua_rkm.c b/src/xua_rkm.c new file mode 100644 index 0000000..12d59c7 --- /dev/null +++ b/src/xua_rkm.c @@ -0,0 +1,296 @@ +/* xUA Routing Key Management (RKM) as per RFC 4666 */ +/* (C) 2017 by Harald Welte + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include + +#include +#include + +#include +#include +#include + +#include "xua_internal.h" + +/* push a M3UA header to the front of the given message */ +static void msgb_push_m3ua_hdr(struct msgb *msg, uint8_t msg_class, uint8_t msg_type) +{ + struct xua_common_hdr *hdr; + + msg->l2h = msgb_push(msg, sizeof(*hdr)); + hdr = (struct xua_common_hdr *) msg->l2h; + + hdr->version = M3UA_VERSION; + hdr->spare = 0; + hdr->msg_class = msg_class; + hdr->msg_type = msg_type; + hdr->msg_length = htonl(msgb_l2len(msg)); +} + +/* append a single registration result to given msgb */ +static int msgb_append_reg_res(struct msgb *msg, uint32_t local_rk_id, + uint32_t status, uint32_t rctx) +{ + uint8_t *old_tail = msg->tail; + + /* One individual Registration Result according to Chapter 3.6.2 */ + msgb_put_u16(msg, M3UA_IEI_REG_RESULT); /* outer IEI */ + msgb_put_u16(msg, 24 + 4); /* outer length */ + /* nested IEIs */ + msgb_t16l16vp_put_u32(msg, M3UA_IEI_LOC_RKEY_ID, local_rk_id); + msgb_t16l16vp_put_u32(msg, M3UA_IEI_REG_STATUS, status); + msgb_t16l16vp_put_u32(msg, M3UA_IEI_ROUTE_CTX, rctx); + + return msg->tail - old_tail; +} + +/* append a single de-registration result to given msgb */ +static int msgb_append_dereg_res(struct msgb *msg, + uint32_t status, uint32_t rctx) +{ + uint8_t *old_tail = msg->tail; + + /* One individual De-Registration Result according to Chapter 3.6.4 */ + msgb_put_u16(msg, M3UA_IEI_DEREG_RESULT); /* outer IEI */ + msgb_put_u16(msg, 16 + 4); /* outer length */ + /* nested IEIs */ + msgb_t16l16vp_put_u32(msg, M3UA_IEI_ROUTE_CTX, rctx); + msgb_t16l16vp_put_u32(msg, M3UA_IEI_DEREG_STATUS, status); + + return msg->tail - old_tail; +} + +/* handle a single registration request IE (nested IEs in 'innner' */ +static int handle_rkey_reg(struct osmo_ss7_asp *asp, struct xua_msg *inner, + struct msgb *resp) +{ + uint32_t rk_id, rctx, _tmode, dpc; + enum osmo_ss7_as_traffic_mode tmode; + struct osmo_ss7_as *as; + struct osmo_ss7_route *rt; + char namebuf[32]; + + /* mandatory local routing key ID */ + rk_id = xua_msg_get_u32(inner, M3UA_IEI_LOC_RKEY_ID); + /* ASP may already include a routing context value here */ + rctx = xua_msg_get_u32(inner, M3UA_IEI_ROUTE_CTX); + + /* traffic mode type (0 = undefined) */ + _tmode = xua_msg_get_u32(inner, M3UA_IEI_TRAF_MODE_TYP); + if (xua_msg_find_tag(inner, M3UA_IEI_TRAF_MODE_TYP) && _tmode != M3UA_TMOD_OVERRIDE && + _tmode != M3UA_TMOD_LOADSHARE && _tmode != M3UA_TMOD_BCAST) { + LOGPASP(asp, DLSS7, LOGL_NOTICE, "RKM: Invalid Traffic Mode %u\n", _tmode); + msgb_append_reg_res(resp, rk_id, M3UA_RKM_REG_ERR_UNSUPP_TRAF_MODE, 0); + return -1; + } + + tmode = osmo_ss7_tmode_from_xua(_tmode); + + /* destination point code (mandatory) */ + dpc = xua_msg_get_u32(inner, M3UA_IEI_DEST_PC); + + /* We don't support routing keys with the following criteria, so + * we have to reject those */ + /* TODO: network appearance (optional) */ + /* TODO: service indicators (optional) */ + /* TODO: originating point code list (optional) */ + if (xua_msg_find_tag(inner, M3UA_IEI_NET_APPEAR) || + xua_msg_find_tag(inner, M3UA_IEI_SVC_IND) || + xua_msg_find_tag(inner, M3UA_IEI_ORIG_PC)) { + LOGPASP(asp, DLSS7, LOGL_NOTICE, "RKM: Unsupported Routing Key\n"); + msgb_append_reg_res(resp, rk_id, M3UA_RKM_REG_ERR_UNSUPP_RK_PARAM, 0); + return -1; + } + + /* if the ASP did not include a routing context number, allocate + * one locally (will be part of response) */ + if (!rctx) + rctx = osmo_ss7_find_free_rctx(asp->inst); + + LOGPASP(asp, DLSS7, LOGL_INFO, "RKM: Registering routing key %u for DPC %s\n", + rctx, osmo_ss7_pointcode_print(asp->inst, dpc)); + + /* check if there is already an AS for this routing key */ + if (osmo_ss7_as_find_by_rctx(asp->inst, rctx)) { + LOGPASP(asp, DLSS7, LOGL_NOTICE, "RKM: RCTX %u already in use\n", rctx); + msgb_append_reg_res(resp, rk_id, M3UA_RKM_REG_ERR_RKEY_ALRDY_REGD, 0); + return -1; + } + + /* Create an AS for this routing key */ + snprintf(namebuf, sizeof(namebuf), "as-rkm-%u", rctx); + as = osmo_ss7_as_find_or_create(asp->inst, namebuf, OSMO_SS7_ASP_PROT_M3UA); + if (!as) { + LOGPASP(asp, DLSS7, LOGL_ERROR, "RKM: Cannot create AS %s\n", namebuf); + msgb_append_reg_res(resp, rk_id, M3UA_RKM_REG_ERR_INSUFF_RESRC, 0); + return -1; + } + + as->cfg.description = talloc_strdup(as, "Auto-generated by RKM"); + as->cfg.mode = tmode; + /* fill routing key */ + as->cfg.routing_key.context = rctx; + as->cfg.routing_key.pc = dpc; + + /* add route for that routing key */ + rt = osmo_ss7_route_create(as->inst->rtable_system, dpc, 0xFFFFFF, namebuf); + if (!rt) { + LOGPASP(asp, DLSS7, LOGL_ERROR, "RKM: Cannot insert route for DPC %s / as %s\n", + osmo_ss7_pointcode_print(asp->inst, dpc), namebuf); + osmo_ss7_as_destroy(as); + msgb_append_reg_res(resp, rk_id, M3UA_RKM_REG_ERR_CANT_SUPP_UNQ_RT, 0); + return -1; + } + + /* Success: Add just-create AS to connected ASP + report success */ + osmo_ss7_as_add_asp(as, asp->cfg.name); + msgb_append_reg_res(resp, rk_id, M3UA_RKM_REG_SUCCESS, rctx); + return 0; +} + +/* receive a registration requuest (SG role) */ +static int m3ua_rx_rkm_reg_req(struct osmo_ss7_asp *asp, struct xua_msg *xua) +{ + struct xua_msg_part *part; + struct msgb *resp = m3ua_msgb_alloc(__func__); + + /* iterate over all routing key IEs in message */ + llist_for_each_entry(part, &xua->headers, entry) { + struct xua_msg *inner; + + if (part->tag != M3UA_IEI_ROUT_KEY) + continue; + + inner = xua_from_nested(part); + if (!inner) { + LOGPASP(asp, DLSS7, LOGL_NOTICE, "RKM: Unable to parse " + "nested IE for Routing Key\n"); + continue; + } + /* handle single registration and append result to + * 'resp' */ + handle_rkey_reg(asp, inner, resp); + } + msgb_push_m3ua_hdr(resp, M3UA_MSGC_RKM, M3UA_RKM_REG_RSP); + osmo_ss7_asp_send(asp, resp); + + return 0; +} + +/* receive a deregistration requuest (SG role) */ +static int handle_rkey_dereg(struct osmo_ss7_asp *asp, uint32_t rctx, + struct msgb *resp) +{ + struct osmo_ss7_instance *inst = asp->inst; + struct osmo_ss7_as *as; + struct osmo_ss7_route *rt; + + as = osmo_ss7_as_find_by_rctx(inst, rctx); + if (!as) { + msgb_append_dereg_res(resp, M3UA_RKM_DEREG_ERR_INVAL_RCTX, 0); + return -1; + } + + /* Reject if ASP is not even part of AS */ + if (!osmo_ss7_as_has_asp(as, asp)) { + msgb_append_dereg_res(resp, M3UA_RKM_DEREG_ERR_INVAL_RCTX, 0); + return -1; + } + + /* FIXME Reject if any ASP stillactively using this RCTX */ + + rt = osmo_ss7_route_find_dpc(inst->rtable_system, as->cfg.routing_key.pc); + if (!rt) { + msgb_append_dereg_res(resp, M3UA_RKM_DEREG_ERR_UNKNOWN, 0); + return -1; + } + + LOGPASP(asp, DLSS7, LOGL_INFO, "RKM: De-Registering rctx %u for DPC %s\n", + rctx, osmo_ss7_pointcode_print(inst, as->cfg.routing_key.pc)); + + /* remove route + AS definition */ + osmo_ss7_route_destroy(rt); + osmo_ss7_as_destroy(as); + /* report success */ + msgb_append_dereg_res(resp, M3UA_RKM_DEREG_SUCCESS, rctx); + + return 0; +} + +static int m3ua_rx_rkm_dereg_req(struct osmo_ss7_asp *asp, struct xua_msg *xua) +{ + struct xua_msg_part *part = xua_msg_find_tag(xua, M3UA_IEI_ROUTE_CTX); + struct msgb *resp = m3ua_msgb_alloc(__func__); + uint32_t *rctx; + + if (!part) + return -1; + + for (rctx = (uint32_t *)part->dat; (uint8_t *)rctx < part->dat + part->len; rctx++) + handle_rkey_dereg(asp, ntohl(*rctx), resp); + + msgb_push_m3ua_hdr(resp, M3UA_MSGC_RKM, M3UA_RKM_DEREG_RSP); + osmo_ss7_asp_send(asp, resp); + + return 0; +} + +/* receive a registration response (ASP role) */ +static int m3ua_rx_rkm_reg_rsp(struct osmo_ss7_asp *asp, struct xua_msg *xua) +{ + /* TODO */ +} + +/* receive a deregistration response (ASP role) */ +static int m3ua_rx_rkm_dereg_rsp(struct osmo_ss7_asp *asp, struct xua_msg *xua) +{ + /* TODO */ +} + +/* process an incoming RKM message in xua format */ +int m3ua_rx_rkm(struct osmo_ss7_asp *asp, struct xua_msg *xua) +{ + int rc; + + switch (xua->hdr.msg_type) { + /* SG Side */ + case M3UA_RKM_REG_REQ: + /* TOOD: ensure we are role SG */ + rc = m3ua_rx_rkm_reg_req(asp, xua); + break; + case M3UA_RKM_DEREG_REQ: + /* TOOD: ensure we are role SG */ + rc = m3ua_rx_rkm_dereg_req(asp, xua); + break; + /* ASP Side */ + case M3UA_RKM_REG_RSP: + /* TOOD: ensure we are role ASP */ + rc = m3ua_rx_rkm_reg_rsp(asp, xua); + break; + case M3UA_RKM_DEREG_RSP: + /* TOOD: ensure we are role ASP */ + rc = m3ua_rx_rkm_dereg_rsp(asp, xua); + break; + default: + LOGPASP(asp, DLSS7, LOGL_ERROR, "Received unknown RKM msg_type %u\n", + xua->hdr.msg_type); + rc = -1; + break; + } + return rc; +} -- To view, visit https://gerrit.osmocom.org/2260 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I9b1cf438a42519c0fe2f555c1672fafa499122a1 Gerrit-PatchSet: 4 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:28:47 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:28:47 +0000 Subject: [PATCH] libosmo-sccp[master]: M3UA: RKM DEREG-REQ should contain routing context, not rout... Message-ID: Review at https://gerrit.osmocom.org/2280 M3UA: RKM DEREG-REQ should contain routing context, not routing key The mandatory IE checking is requiring the wrong IE Change-Id: I73ecd163e2143341687ee4bca15a0bc69719c594 --- M src/m3ua.c 1 file changed, 1 insertion(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/80/2280/1 diff --git a/src/m3ua.c b/src/m3ua.c index 5708985..031e5cd 100644 --- a/src/m3ua.c +++ b/src/m3ua.c @@ -241,7 +241,7 @@ M3UA_IEI_REG_RESULT, 0 }; static const uint16_t dereg_req_ies[] = { - M3UA_IEI_ROUT_KEY, 0 + M3UA_IEI_ROUTE_CTX, 0 }; static const uint16_t dereg_rsp_ies[] = { M3UA_IEI_DEREG_RESULT, 0 -- To view, visit https://gerrit.osmocom.org/2280 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I73ecd163e2143341687ee4bca15a0bc69719c594 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:28:47 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:28:47 +0000 Subject: [PATCH] libosmo-sccp[master]: WIP: osmo-stp executable Message-ID: Review at https://gerrit.osmocom.org/2281 WIP: osmo-stp executable Change-Id: If32227b8d3127c6178e4ee45527ce65f69bc7b1e --- M .gitignore M Makefile.am M configure.ac M include/osmocom/sigtran/osmo_ss7.h M src/osmo_ss7.c A stp/Makefile.am A stp/internal.h R stp/osmo_ss7_vty.c A stp/stp_main.c 9 files changed, 334 insertions(+), 60 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/81/2281/1 diff --git a/.gitignore b/.gitignore index 83f1333..c38bac1 100644 --- a/.gitignore +++ b/.gitignore @@ -62,6 +62,8 @@ examples/m3ua_example +stp/osmo-stp + *.pc config.* diff --git a/Makefile.am b/Makefile.am index dd73ec2..ededdac 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,7 +1,7 @@ AUTOMAKE_OPTIONS = foreign dist-bzip2 1.6 AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -SUBDIRS = include src tests examples +SUBDIRS = include src tests examples stp pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = libosmo-sccp.pc libosmo-mtp.pc libosmo-sigtran.pc libosmo-xua.pc diff --git a/configure.ac b/configure.ac index 6dc0ebd..82c7ee8 100644 --- a/configure.ac +++ b/configure.ac @@ -70,5 +70,6 @@ tests/xua/Makefile tests/ss7/Makefile examples/Makefile + stp/Makefile Makefile) diff --git a/include/osmocom/sigtran/osmo_ss7.h b/include/osmocom/sigtran/osmo_ss7.h index cbc6a02..2d5eba9 100644 --- a/include/osmocom/sigtran/osmo_ss7.h +++ b/include/osmocom/sigtran/osmo_ss7.h @@ -9,6 +9,8 @@ #include #include +extern struct llist_head osmo_ss7_xua_servers; + struct osmo_ss7_instance; struct osmo_ss7_user; struct osmo_sccp_instance; diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index 103c05b..e55d55c 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -28,6 +28,7 @@ #include #include +#include #include #include @@ -52,7 +53,7 @@ static bool ss7_initialized = false; static LLIST_HEAD(ss7_instances); -static LLIST_HEAD(ss7_xua_servers); +LLIST_HEAD(osmo_ss7_xua_servers); static int32_t next_rctx = 1; struct value_string osmo_ss7_as_traffic_mode_vals[] = { @@ -1449,7 +1450,7 @@ struct osmo_xua_server *xs; OSMO_ASSERT(ss7_initialized); - llist_for_each_entry(xs, &ss7_xua_servers, list) { + llist_for_each_entry(xs, &osmo_ss7_xua_servers, list) { if (proto == xs->cfg.proto && local_port == xs->cfg.local.port) return xs; @@ -1498,7 +1499,7 @@ } oxs->inst = inst; - llist_add_tail(&oxs->list, &ss7_xua_servers); + llist_add_tail(&oxs->list, &osmo_ss7_xua_servers); return oxs; } diff --git a/stp/Makefile.am b/stp/Makefile.am new file mode 100644 index 0000000..3cc9112 --- /dev/null +++ b/stp/Makefile.am @@ -0,0 +1,9 @@ +AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include +AM_CFLAGS=-Wall -g $(LIBOSMOCORE_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(LIBOSMONETIF_CFLAGS) $(COVERAGE_FLAGS) +AM_LDFLAGS=$(COVERAGE_LDFLAGS) + +noinst_PROGRAMS = osmo-stp + +osmo_stp_SOURCES = stp_main.c osmo_ss7_vty.c +osmo_stp_LDADD = $(top_builddir)/src/libosmo-sigtran.la \ + $(LIBOSMOCORE_LIBS) $(LIBOSMOVTY_LIBS) diff --git a/stp/internal.h b/stp/internal.h new file mode 100644 index 0000000..0a434cc --- /dev/null +++ b/stp/internal.h @@ -0,0 +1,18 @@ +#pragma once + +#include + +enum stp_vty_node { + L_CS7_AS_NODE = _LAST_OSMOVTY_NODE + 1, + L_CS7_ASP_NODE, + L_CS7_SUA_NODE, + L_CS7_M3UA_NODE, + L_CS7_RTABLE_NODE, +}; + +int osmo_ss7_vty_init(void); +int osmo_ss7_vty_go_parent(struct vty *vty); +int osmo_ss7_is_config_node(struct vty *vty, int node); + +extern struct osmo_ss7_instance *g_s7i; + diff --git a/src/osmo_ss7_vty.c b/stp/osmo_ss7_vty.c similarity index 74% rename from src/osmo_ss7_vty.c rename to stp/osmo_ss7_vty.c index 80cd4d0..7863e8a 100644 --- a/src/osmo_ss7_vty.c +++ b/stp/osmo_ss7_vty.c @@ -33,6 +33,9 @@ #include #include +#include + +#include "internal.h" #define CS7_STR "ITU-T Signaling System 7\n" #define PC_STR "Point Code\n" @@ -58,7 +61,7 @@ "Reserved Network\n" "Spare Network\n") { - struct osmo_ss7_instance *inst = FIXME; + struct osmo_ss7_instance *inst = g_s7i; int ni = get_string_value(ss7_network_indicator_vals, argv[0]); inst->cfg.network_indicator = ni; @@ -67,13 +70,13 @@ /* TODO: cs7 point-code format */ DEFUN(cs7_pc_format, cs7_pc_format_cmd, - "cs7 point-code format <1-24> [<1-23> [<1-22>]]", + "cs7 point-code format <1-24> [<1-23>] [<1-22>]", CS7_STR PC_STR "Configure Point Code Format\n" "Length of first PC component\n" "Length of second PC component\n" "Length of third PC component\n") { - struct osmo_ss7_instance *inst = FIXME; + struct osmo_ss7_instance *inst = g_s7i; int argind = 0; inst->cfg.pc_fmt.component_len[0] = atoi(argv[argind++]); @@ -96,7 +99,7 @@ CS7_STR PC_STR "Configure Point Code Format\n" "Default Point Code Format (3.8.3)\n") { - struct osmo_ss7_instance *inst = FIXME; + struct osmo_ss7_instance *inst = g_s7i; inst->cfg.pc_fmt.component_len[0] = 3; inst->cfg.pc_fmt.component_len[1] = 8; inst->cfg.pc_fmt.component_len[2] = 3; @@ -111,7 +114,7 @@ "Use dot as delimiter\n" "User dash as delimiter\n") { - struct osmo_ss7_instance *inst = FIXME; + struct osmo_ss7_instance *inst = g_s7i; if (!strcmp(argv[0], "dash")) inst->cfg.pc_fmt.delimiter = '-'; @@ -126,7 +129,7 @@ CS7_STR "Configure the local Point Code\n" "Point Code\n") { - struct osmo_ss7_instance *inst = FIXME; + struct osmo_ss7_instance *inst = g_s7i; uint32_t pc = osmo_ss7_pointcode_parse(inst, argv[0]); inst->cfg.primary_pc = pc; @@ -135,6 +138,40 @@ /* TODO: cs7 secondary-pc */ /* TODO: cs7 capability-pc */ + +static void write_one_ss7_inst(struct vty *vty, struct osmo_ss7_instance *inst) +{ + if (inst->cfg.network_indicator) + vty_out(vty, "cs7 network-indicator %s%s", + get_value_string(ss7_network_indicator_vals, + inst->cfg.network_indicator), + VTY_NEWLINE); + + if (inst->cfg.pc_fmt.component_len[0] != 3 || + inst->cfg.pc_fmt.component_len[1] != 8 || + inst->cfg.pc_fmt.component_len[2] != 3) { + vty_out(vty, "cs7 point-code format %u", + inst->cfg.pc_fmt.component_len[0]); + if (inst->cfg.pc_fmt.component_len[1]) + vty_out(vty, " %u", inst->cfg.pc_fmt.component_len[1]); + if (inst->cfg.pc_fmt.component_len[2]) + vty_out(vty, " %u", inst->cfg.pc_fmt.component_len[2]); + vty_out(vty, "%s", VTY_NEWLINE); + } + + if (inst->cfg.pc_fmt.delimiter != '.') + vty_out(vty, "cs7 point-code delimiter dash%s", VTY_NEWLINE); + + if (inst->cfg.primary_pc) + vty_out(vty, "cs7 point-code %s%s", + osmo_ss7_pointcode_print(inst, inst->cfg.primary_pc), + VTY_NEWLINE); +} + +static void config_write_cs7(struct vty *vty) +{ + write_one_ss7_inst(vty, g_s7i); +} /*********************************************************************** * Routing Table Configuration @@ -151,7 +188,7 @@ CS7_STR "Specify the name of the route table\n" "Name of the route table\n") { - struct osmo_ss7_instance *inst = FIXME; + struct osmo_ss7_instance *inst = g_s7i; struct osmo_ss7_route_table *rtable; rtable = inst->rtable_system; @@ -163,7 +200,7 @@ } DEFUN(cs7_rt_upd, cs7_rt_upd_cmd, - "update route POINT_CODE [MASK | LENGTH] linkset LS_NAME [priority PRIO] [qos-class (CLASS | default", + "update route POINT_CODE MASK linkset LS_NAME [priority PRIO] [qos-class (CLASS|default)]", "Update the Route\n" "Update the Route\n" "Destination Point Code\n" @@ -185,8 +222,10 @@ unsigned int argind; rt = osmo_ss7_route_create(rtable, dpc, mask, ls_name); - if (!rt) + if (!rt) { + vty_out(vty, "cannot create route%s", VTY_NEWLINE); return CMD_WARNING; + } argind = 3; if (argc > argind && !strcmp(argv[argind], "priority")) { @@ -203,7 +242,7 @@ } DEFUN(cs7_rt_rem, cs7_rt_rem_cmd, - "remove route POINT_CODE [MASK | LENGTH]", + "remove route POINT_CODE MASK", "Remove a Route\n" "Remove a Route\n" "Destination Point Code\n" @@ -216,19 +255,22 @@ uint32_t mask = osmo_ss7_pointcode_parse_mask_or_len(rtable->inst, argv[1]); rt = osmo_ss7_route_find_dpc_mask(rtable, dpc, mask); - if (!rt) + if (!rt) { + vty_out(vty, "cannot find route to be deleted%s", VTY_NEWLINE); return CMD_WARNING; + } osmo_ss7_route_destroy(rt); return CMD_SUCCESS; } -static int config_write_rtable(struct vty *vty) +static void write_one_rtable(struct vty *vty, struct osmo_ss7_route_table *rtable) { - struct osmo_ss7_route_table *rtable = vty->index; struct osmo_ss7_route *rt; vty_out(vty, "cs7 route-table %s%s", rtable->cfg.name, VTY_NEWLINE); + if (rtable->cfg.description) + vty_out(vty, " description %s%s", rtable->cfg.description, VTY_NEWLINE); llist_for_each_entry(rt, &rtable->routes, list) { vty_out(vty, " update route %s %s linkset %s", osmo_ss7_pointcode_print(rtable->inst, rt->cfg.pc), @@ -240,6 +282,16 @@ vty_out(vty, " qos-class %u", rt->cfg.qos_class); vty_out(vty, "%s", VTY_NEWLINE); } +} + +static int config_write_rtable(struct vty *vty) +{ + struct osmo_ss7_instance *inst = g_s7i; + struct osmo_ss7_route_table *rtable; + + llist_for_each_entry(rtable, &inst->rtable_list, list) + write_one_rtable(vty, rtable); + return 0; } @@ -259,7 +311,7 @@ "Configure/Enable SUA\n" "SCTP Port number for SUA\n") { - struct osmo_ss7_instance *inst = FIXME; + struct osmo_ss7_instance *inst = g_s7i; struct osmo_xua_server *xs; uint16_t port = atoi(argv[0]); @@ -291,12 +343,22 @@ return get_string_value(osmo_ss7_asp_protocol_vals, protocol); } +static void write_one_sua(struct vty *vty, struct osmo_xua_server *xs) +{ + vty_out(vty, "cs7 %s %u%s", + get_value_string(osmo_ss7_asp_protocol_vals, xs->cfg.proto), + xs->cfg.local.port, VTY_NEWLINE); + vty_out(vty, " local-ip %s%s", xs->cfg.local.host, VTY_NEWLINE); +} + + static int config_write_sua(struct vty *vty) { - struct osmo_xua_server *xs = vty->index; + struct osmo_xua_server *xs; - vty_out(vty, "cs7 sua %u%s", xs->cfg.local.port, VTY_NEWLINE); - vty_out(vty, " local-ip %s%s", xs->cfg.local.host, VTY_NEWLINE); + llist_for_each_entry(xs, &osmo_ss7_xua_servers, list) + write_one_sua(vty, xs); + return 0; } @@ -316,7 +378,7 @@ "Configure/Enable M3UA\n" "SCTP Port number for M3UA\n") { - struct osmo_ss7_instance *inst = FIXME; + struct osmo_ss7_instance *inst = g_s7i; struct osmo_xua_server *xs; uint16_t port = atoi(argv[0]); @@ -345,10 +407,7 @@ static int config_write_m3ua(struct vty *vty) { - struct osmo_xua_server *xs = vty->index; - - vty_out(vty, "cs7 m3ua %u%s", xs->cfg.local.port, VTY_NEWLINE); - vty_out(vty, " local-ip %s%s", xs->cfg.local.host, VTY_NEWLINE); + /* see config_write_sua */ return 0; } @@ -363,7 +422,7 @@ }; DEFUN(cs7_asp, cs7_asp_cmd, - "cs7 asp NAME <0-65535> <0-65535> [m3ua | sua]", + "cs7 asp NAME <0-65535> <0-65535> (m3ua|sua)", CS7_STR "Configure Application Server Process\n" "Name of ASP\n" @@ -372,19 +431,24 @@ "M3UA Protocol\n" "SUA Protocol\n") { - struct osmo_ss7_instance *inst = FIXME; + struct osmo_ss7_instance *inst = g_s7i; const char *name = argv[0]; uint16_t remote_port = atoi(argv[1]); uint16_t local_port = atoi(argv[2]); enum osmo_ss7_asp_protocol protocol = parse_asp_proto(argv[3]); struct osmo_ss7_asp *asp; - if (protocol == OSMO_SS7_ASP_PROT_NONE) + if (protocol == OSMO_SS7_ASP_PROT_NONE) { + vty_out(vty, "invalid protocol '%s'%s", argv[3], VTY_NEWLINE); return CMD_WARNING; + } asp = osmo_ss7_asp_find_or_create(inst, name, remote_port, local_port, protocol); - if (!asp) + if (!asp) { + vty_out(vty, "cannot create ASP '%s'%s", name, VTY_NEWLINE); return CMD_WARNING; + } + asp->cfg.is_server = true; vty->node = L_CS7_ASP_NODE; vty->index = asp; @@ -394,7 +458,7 @@ DEFUN(asp_remote_ip, asp_remote_ip_cmd, "remote-ip A.B.C.D", - "Specity Remote IP Address of ASP\n" + "Specify Remote IP Address of ASP\n" "Remote IP Address of ASP\n") { struct osmo_ss7_asp *asp = vty->index; @@ -404,7 +468,7 @@ DEFUN(asp_qos_clas, asp_qos_class_cmd, "qos-class <0-255>", - "Specity QoS Class of ASP\n" + "Specify QoS Class of ASP\n" "QoS Class of ASP\n") { struct osmo_ss7_asp *asp = vty->index; @@ -417,7 +481,7 @@ "Allows a SCTP Association with ASP, but doesn't let it become active\n") { struct osmo_ss7_asp *asp = vty->index; - vty_out(vty, "Not supported yet\n"); + vty_out(vty, "Not supported yet%s", VTY_NEWLINE); return CMD_WARNING; } @@ -426,22 +490,33 @@ "Terminates SCTP association; New associations will be rejected\n") { struct osmo_ss7_asp *asp = vty->index; - vty_out(vty, "Not supported yet\n"); + vty_out(vty, "Not supported yet%s", VTY_NEWLINE); return CMD_WARNING; +} + +static void write_one_asp(struct vty *vty, struct osmo_ss7_asp *asp) +{ + vty_out(vty, "cs7 asp %s %u %u %s%s", + asp->cfg.name, asp->cfg.remote.port, asp->cfg.local.port, + osmo_ss7_asp_protocol_name(asp->cfg.proto), VTY_NEWLINE); + if (asp->cfg.description) + vty_out(vty, " description %s%s", asp->cfg.description, VTY_NEWLINE); + vty_out(vty, " remote-ip %s%s", asp->cfg.remote.host, VTY_NEWLINE); + if (asp->cfg.qos_class) + vty_out(vty, " qos-class %u%s", asp->cfg.qos_class, VTY_NEWLINE); } static int config_write_asp(struct vty *vty) { - struct osmo_ss7_asp *asp = vty->index; + struct osmo_ss7_instance *inst = g_s7i; + struct osmo_ss7_asp *asp; - vty_out(vty, "cs7 asp %s %u %u %s%s", - asp->cfg.name, asp->cfg.remote.port, asp->cfg.local.port, - osmo_ss7_asp_protocol_name(asp->cfg.proto), VTY_NEWLINE); - vty_out(vty, " remote-ip %s%s", asp->cfg.remote.host, VTY_NEWLINE); - if (asp->cfg.qos_class) - vty_out(vty, " qos-class %u%s", asp->cfg.qos_class, VTY_NEWLINE); + llist_for_each_entry(asp, &inst->asp_list, list) + write_one_asp(vty, asp); + return 0; } + /*********************************************************************** * Application Server @@ -454,21 +529,29 @@ }; DEFUN(cs7_as, cs7_as_cmd, - "cs7 as NAME [m3ua | sua]", + "cs7 as NAME (m3ua|sua)", CS7_STR "Configure an Application Server\n" "Name of the Application Server\n" "M3UA Application Server\n" "SUA Application Server\n") { + struct osmo_ss7_instance *inst = g_s7i; struct osmo_ss7_as *as; const char *name = argv[0]; enum osmo_ss7_asp_protocol protocol = parse_asp_proto(argv[1]); - if (protocol == OSMO_SS7_ASP_PROT_NONE) + if (protocol == OSMO_SS7_ASP_PROT_NONE) { + vty_out(vty, "invalid protocol '%s'%s", argv[3], VTY_NEWLINE); return CMD_WARNING; + } - /* FIXME */ + as = osmo_ss7_as_find_or_create(inst, name, protocol); + if (!as) { + vty_out(vty, "cannot create AS '%s'%s", name, VTY_NEWLINE); + return CMD_WARNING; + } + as->cfg.name = talloc_strdup(as, name); vty->node = L_CS7_AS_NODE; @@ -486,8 +569,10 @@ { struct osmo_ss7_as *as = vty->index; - if (osmo_ss7_as_add_asp(as, argv[0])) + if (osmo_ss7_as_add_asp(as, argv[0])) { + vty_out(vty, "cannot find ASP '%s'%s", argv[0], VTY_NEWLINE); return CMD_WARNING; + } return CMD_SUCCESS; } @@ -499,8 +584,10 @@ { struct osmo_ss7_as *as = vty->index; - if (osmo_ss7_as_del_asp(as, argv[0])) + if (osmo_ss7_as_del_asp(as, argv[0])) { + vty_out(vty, "cannot find ASP '%s'%s", argv[0], VTY_NEWLINE); return CMD_WARNING; + } return CMD_SUCCESS; } @@ -516,7 +603,7 @@ struct osmo_ss7_as *as = vty->index; as->cfg.mode = get_string_value(osmo_ss7_as_traffic_mode_vals, argv[0]); - return CMD_WARNING; + return CMD_SUCCESS; } DEFUN(as_recov_tout, as_recov_tout_cmd, @@ -554,7 +641,7 @@ }; DEFUN(as_rout_key, as_rout_key_cmd, - "routing-key RCONTEXT DPC [si {aal2 | bicc | b-isup | h248 | isup | sat-isup | sccp | tup }] [ssn SSN]}", + "routing-key RCONTEXT DPC [si (aal2|bicc|b-isup|h248|isup|sat-isup|sccp|tup)] [ssn SSN]}", "Define a routing key\n" "Routing context number\n" "Destination Point Code\n" @@ -571,25 +658,21 @@ "Sub-System Number to match on\n") { struct osmo_ss7_as *as = vty->index; - uint32_t key = atoi(argv[0]); - struct osmo_ss7_routing_key *rkey; + struct osmo_ss7_routing_key *rkey = &as->cfg.routing_key; int argind; - rkey = osmo_ss7_rkey_find_or_create(as, key); - if (!rkey) - return CMD_WARNING; - + rkey->context = atoi(argv[0]); rkey->pc = osmo_ss7_pointcode_parse(as->inst, argv[1]); argind = 2; - if (!strcmp(argv[argind], "si")) { + if (argind < argc && !strcmp(argv[argind], "si")) { const char *si_str; argind++; si_str = argv[argind++]; /* parse numeric SI from string */ rkey->si = get_string_value(mtp_si_vals, si_str); } - if (!strcmp(argv[argind], "ssn")) { + if (argind < argc && !strcmp(argv[argind], "ssn")) { argind++; rkey->ssn = atoi(argv[argind]); } @@ -597,14 +680,15 @@ return CMD_SUCCESS; } -static int config_write_as(struct vty *vty) +static void write_one_as(struct vty *vty, struct osmo_ss7_as *as) { - struct osmo_ss7_as *as = vty->index; struct osmo_ss7_routing_key *rkey; unsigned int i; vty_out(vty, "cs7 as %s %s%s", as->cfg.name, osmo_ss7_asp_protocol_name(as->cfg.proto), VTY_NEWLINE); + if (as->cfg.description) + vty_out(vty, " description %s%s", as->cfg.description, VTY_NEWLINE); for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) { struct osmo_ss7_asp *asp = as->cfg.asps[i]; if (!asp) @@ -618,7 +702,8 @@ vty_out(vty, " recovery-timeout %u%s", as->cfg.recovery_timeout_msec, VTY_NEWLINE); } - vty_out(vty, " qos-class %u%s", as->cfg.qos_class, VTY_NEWLINE); + if (as->cfg.qos_class) + vty_out(vty, " qos-class %u%s", as->cfg.qos_class, VTY_NEWLINE); rkey = &as->cfg.routing_key; vty_out(vty, " routing-key %u %s", rkey->context, osmo_ss7_pointcode_print(as->inst, rkey->pc)); @@ -628,8 +713,61 @@ if (rkey->ssn) vty_out(vty, " ssn %u", rkey->ssn); vty_out(vty, "%s", VTY_NEWLINE); +} + +static int config_write_as(struct vty *vty) +{ + struct osmo_ss7_instance *inst = g_s7i; + struct osmo_ss7_as *as; + + /* HACK to call this here, as we cannot install additional + * 'save' code into the root CONFIG_NODE ... */ + config_write_cs7(vty); + + /* HACK to call this here, but we must make sure that the ASP + * are all configured before we reference them from the AS, and + * VTY code always stores the nodes in alphabetical order */ + + config_write_asp(vty); + + llist_for_each_entry(as, &inst->as_list, list) + write_one_as(vty, as); return 0; +} + +int osmo_ss7_vty_go_parent(struct vty *vty) +{ + struct osmo_ss7_asp *asp; + + switch (vty->node) { + case L_CS7_ASP_NODE: + asp = vty->index; + osmo_ss7_asp_restart(asp); + vty->node = CONFIG_NODE; + break; + case L_CS7_RTABLE_NODE: + case L_CS7_SUA_NODE: + case L_CS7_M3UA_NODE: + case L_CS7_AS_NODE: + default: + vty->node = CONFIG_NODE; + break; + } +} + +int osmo_ss7_is_config_node(struct vty *vty, int node) +{ + switch (node) { + case L_CS7_ASP_NODE: + case L_CS7_RTABLE_NODE: + case L_CS7_SUA_NODE: + case L_CS7_M3UA_NODE: + case L_CS7_AS_NODE: + return 1; + default: + return 0; + } } int osmo_ss7_vty_init(void) @@ -657,7 +795,7 @@ install_element(CONFIG_NODE, &cs7_m3ua_cmd); install_element(L_CS7_M3UA_NODE, &m3ua_local_ip_cmd); - install_node(&asp_node, config_write_asp); + install_node(&asp_node, NULL); vty_install_default(L_CS7_ASP_NODE); install_element(CONFIG_NODE, &cs7_asp_cmd); install_element(L_CS7_ASP_NODE, &cfg_description_cmd); diff --git a/stp/stp_main.c b/stp/stp_main.c new file mode 100644 index 0000000..e70ff14 --- /dev/null +++ b/stp/stp_main.c @@ -0,0 +1,103 @@ +/* Osmocom STP (Signal Transfer Point) */ + +/* (C) 2015-2017 by Harald Welte + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "internal.h" + +struct osmo_ss7_instance *g_s7i; + +static const struct log_info_cat log_info_cat[] = { +}; + +static const struct log_info log_info = { + .cat = log_info_cat, + .num_cat = ARRAY_SIZE(log_info_cat), +}; + +/* Hack to enable debug logging for all relevant (used?) subsystems */ +static void init_logging(void) +{ + const int log_cats[] = { DLSS7, DLSUA, DLM3UA, DLSCCP, DLINP }; + unsigned int i; + + osmo_init_logging(&log_info); + + for (i = 0; i < ARRAY_SIZE(log_cats); i++) + log_set_category_filter(osmo_stderr_target, log_cats[i], 1, LOGL_DEBUG); +} + +static struct vty_app_info vty_info = { + .name = "osmo-stp", + .version = PACKAGE_VERSION, + .go_parent_cb = osmo_ss7_vty_go_parent, + .is_config_node = osmo_ss7_is_config_node, +}; + +int main(int argc, char **argv) +{ + struct osmo_sccp_instance *sccp; + char *config_file = "osmo-stp.cfg"; + bool client; + int rc; + + init_logging(); + osmo_ss7_init(); + osmo_fsm_log_addr(false); + vty_init(&vty_info); + osmo_ss7_vty_init(); + + g_s7i = osmo_ss7_instance_find_or_create(NULL, 0); + + rc = vty_read_config_file(config_file, NULL); + if (rc < 0) { + fprintf(stderr, "Failed to parse the config file '%s'\n", + config_file); + exit(1); + } + + rc = telnet_init_dynif(NULL, NULL, vty_get_bind_addr(), OSMO_VTY_PORT_STP); + if (rc < 0) { + perror("Erro binding VTY port\n"); + exit(1); + } + + while (1) { + osmo_select_main(0); + } +} -- To view, visit https://gerrit.osmocom.org/2281 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: If32227b8d3127c6178e4ee45527ce65f69bc7b1e Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:28:48 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:28:48 +0000 Subject: [PATCH] libosmo-sccp[master]: WIP: Add IPA/SCCPlite stacking Message-ID: Review at https://gerrit.osmocom.org/2282 WIP: Add IPA/SCCPlite stacking Change-Id: I9098574cddeba10fcf8f1b6c196a7069a6805c56 --- M include/osmocom/sigtran/osmo_ss7.h M src/osmo_ss7.c M src/sccp_scrc.c 3 files changed, 134 insertions(+), 9 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/82/2282/1 diff --git a/include/osmocom/sigtran/osmo_ss7.h b/include/osmocom/sigtran/osmo_ss7.h index 2d5eba9..e33a9ad 100644 --- a/include/osmocom/sigtran/osmo_ss7.h +++ b/include/osmocom/sigtran/osmo_ss7.h @@ -254,6 +254,7 @@ OSMO_SS7_ASP_PROT_NONE, OSMO_SS7_ASP_PROT_SUA, OSMO_SS7_ASP_PROT_M3UA, + OSMO_SS7_ASP_PROT_IPA, _NUM_OSMO_SS7_ASP_PROT }; diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index e55d55c..f9770c7 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -41,6 +41,7 @@ #include #include +#include #include "sccp_internal.h" #include "xua_internal.h" @@ -68,11 +69,24 @@ { OSMO_SS7_ASP_PROT_NONE, "none" }, { OSMO_SS7_ASP_PROT_SUA, "sua" }, { OSMO_SS7_ASP_PROT_M3UA, "m3ua" }, + { OSMO_SS7_ASP_PROT_IPA, "ipa" }, { 0, NULL } }; #define LOGSS7(inst, level, fmt, args ...) \ LOGP(DLSS7, level, "%u: " fmt, inst ? (inst)->cfg.id : 0, ## args) + +static int asp_proto_to_ip_proto(enum osmo_ss7_asp_protocol proto) +{ + switch (proto) { + case OSMO_SS7_ASP_PROT_IPA: + return IPPROTO_TCP; + case OSMO_SS7_ASP_PROT_SUA: + case OSMO_SS7_ASP_PROT_M3UA: + default: + return IPPROTO_SCTP; + } +} int osmo_ss7_find_free_rctx(struct osmo_ss7_instance *inst) { @@ -786,7 +800,8 @@ as->cfg.proto = proto; as->cfg.mode = OSMO_SS7_AS_TMOD_LOADSHARE; as->cfg.recovery_timeout_msec = 2000; - as->fi = xua_as_fsm_start(as, LOGL_DEBUG); + if (proto != OSMO_SS7_ASP_PROT_IPA) + as->fi = xua_as_fsm_start(as, LOGL_DEBUG); llist_add_tail(&as->list, &inst->as_list); } @@ -1020,6 +1035,7 @@ } static int xua_cli_read_cb(struct osmo_stream_cli *conn); +static int ipa_cli_read_cb(struct osmo_stream_cli *conn); static int xua_cli_connect_cb(struct osmo_stream_cli *cli); int osmo_ss7_asp_restart(struct osmo_ss7_asp *asp) @@ -1049,10 +1065,13 @@ osmo_stream_cli_set_port(asp->client, asp->cfg.remote.port); osmo_stream_cli_set_local_addr(asp->client, asp->cfg.local.host); osmo_stream_cli_set_local_port(asp->client, asp->cfg.local.port); - osmo_stream_cli_set_proto(asp->client, IPPROTO_SCTP); + osmo_stream_cli_set_proto(asp->client, asp_proto_to_ip_proto(asp->cfg.proto)); osmo_stream_cli_set_reconnect_timeout(asp->client, 5); osmo_stream_cli_set_connect_cb(asp->client, xua_cli_connect_cb); - osmo_stream_cli_set_read_cb(asp->client, xua_cli_read_cb); + if (asp->cfg.proto == OSMO_SS7_ASP_PROT_IPA) + osmo_stream_cli_set_read_cb(asp->client, ipa_cli_read_cb); + else + osmo_stream_cli_set_read_cb(asp->client, xua_cli_read_cb); osmo_stream_cli_set_data(asp->client, asp); rc = osmo_stream_cli_open2(asp->client, 1); if (rc < 0) { @@ -1079,7 +1098,8 @@ /* (re)start the ASP FSM */ if (asp->fi) osmo_fsm_inst_term(asp->fi, OSMO_FSM_TERM_REQUEST, NULL); - asp->fi = xua_asp_fsm_start(asp, role, LOGL_DEBUG); + if (asp->cfg.proto != OSMO_SS7_ASP_PROT_IPA) + asp->fi = xua_asp_fsm_start(asp, role, LOGL_DEBUG); return 0; } @@ -1162,6 +1182,64 @@ notif->sn_header.sn_type)); break; } +} + +static int ipa_rx_msg(struct osmo_ss7_asp *asp, struct msgb *msg) +{ + struct osmo_mtp_prim *omp; + + /* FIXME: pull the IPA header */ + + /* Generate an MTP-TRANSFER.ind and hand it into the MTP core + * so it can dispatch it to SCCP */ + omp = (struct osmo_mtp_prim *) msgb_push(msg, sizeof(*omp)); + osmo_prim_init(&omp->oph, MTP_SAP_USER, + OSMO_MTP_PRIM_TRANSFER, PRIM_OP_INDICATION, msg); + omp->u.transfer.opc = 0; + omp->u.transfer.dpc = 0; + omp->u.transfer.sio = MTP_SI_SCCP; + omp->u.transfer.sls = 0; + + return osmo_ss7_mtp_to_user(asp->inst, omp); +} + +/* netif code tells us we can read something from the socket */ +static int ipa_srv_conn_cb(struct osmo_stream_srv *conn) +{ + struct osmo_fd *ofd = osmo_stream_srv_get_ofd(conn); + struct osmo_ss7_asp *asp = osmo_stream_srv_get_data(conn); + struct msgb *msg = msgb_alloc(ASP_MSGB_SIZE, "xUA Server Rx"); + int rc; + + if (!msg) + return -ENOMEM; + + /* read xUA message from socket and process it */ + rc = osmo_stream_srv_recv(conn, msg); + LOGPASP(asp, DLSS7, LOGL_DEBUG, "%s(): recvmsg() returned %d\n", + __func__, rc); + if (rc < 0) { + osmo_stream_srv_destroy(conn); + goto out; + } else if (rc == 0) { + osmo_stream_srv_destroy(conn); + goto out; + } + if (osmo_ipa_process_msg(msg) < 0) { + LOGPASP(asp, DLSS7, LOGL_ERROR, "Bad IPA message\n"); + osmo_stream_srv_destroy(conn); + goto out; + } + msg->dst = asp; + + /* Handle IPA PING, PONG and ID_ACK messages */ + if (osmo_ipa_rcvmsg_base(msg, ofd, 1)) + return 0; + + rc = ipa_rx_msg(asp, msg); +out: + msgb_free(msg); + return rc; } /* netif code tells us we can read something from the socket */ @@ -1251,6 +1329,40 @@ } return 0; +} + +/* read call-back for IPA/SCCPlite socket */ +static int ipa_cli_read_cb(struct osmo_stream_cli *conn) +{ + struct osmo_fd *ofd = osmo_stream_cli_get_ofd(conn); + struct osmo_ss7_asp *asp = osmo_stream_cli_get_data(conn); + struct msgb *msg = msgb_alloc(ASP_MSGB_SIZE, "IPA Client Rx"); + int rc; + + if (!msg) + return -ENOMEM; + + rc = osmo_stream_cli_recv(conn, msg); + if (rc <= 0) { + LOGPASP(asp, DLSS7, LOGL_ERROR, "Cannot receive message\n"); + osmo_stream_cli_reconnect(conn); + goto out; + } + if (osmo_ipa_process_msg(msg) < 0) { + LOGPASP(asp, DLSS7, LOGL_ERROR, "Bad IPA message\n"); + osmo_stream_cli_reconnect(conn); + goto out; + } + + /* Handle IPA PING, PONG and ID_ACK messages */ + if (osmo_ipa_rcvmsg_base(msg, ofd, 0)) + return 0; + + msg->dst = asp; + rc = ipa_rx_msg(asp, msg); +out: + msgb_free(msg); + return rc; } static int xua_cli_read_cb(struct osmo_stream_cli *conn) @@ -1345,9 +1457,15 @@ LOGP(DLSS7, LOGL_INFO, "%s: New SCTP connection accepted\n", sock_name); - srv = osmo_stream_srv_create(oxs, link, fd, - xua_srv_conn_cb, - xua_srv_conn_closed_cb, NULL); + if (oxs->cfg.proto == OSMO_SS7_ASP_PROT_IPA) { + srv = osmo_stream_srv_create(oxs, link, fd, + ipa_srv_conn_cb, + xua_srv_conn_closed_cb, NULL); + } else { + srv = osmo_stream_srv_create(oxs, link, fd, + xua_srv_conn_cb, + xua_srv_conn_closed_cb, NULL); + } if (!srv) { LOGP(DLSS7, LOGL_ERROR, "%s: Unable to create stream server " "for SCTP connection\n", sock_name); @@ -1413,6 +1531,10 @@ break; case OSMO_SS7_ASP_PROT_M3UA: msgb_sctp_ppid(msg) = M3UA_PPID; + break; + case OSMO_SS7_ASP_PROT_IPA: + /* do we really want to do this here? */ + osmo_ipa_msg_push_header(msg, FIXME); break; default: OSMO_ASSERT(0); @@ -1489,7 +1611,7 @@ osmo_stream_srv_link_set_addr(oxs->server, oxs->cfg.local.host); osmo_stream_srv_link_set_port(oxs->server, oxs->cfg.local.port); - osmo_stream_srv_link_set_proto(oxs->server, IPPROTO_SCTP); + osmo_stream_srv_link_set_proto(oxs->server, asp_proto_to_ip_proto(proto)); rc = osmo_stream_srv_link_open(oxs->server); if (rc < 0) { diff --git a/src/sccp_scrc.c b/src/sccp_scrc.c index f9df075..80c8126 100644 --- a/src/sccp_scrc.c +++ b/src/sccp_scrc.c @@ -142,6 +142,7 @@ case OSMO_SS7_ASP_PROT_SUA: return sua_tx_xua_as(as, xua); case OSMO_SS7_ASP_PROT_M3UA: + case OSMO_SS7_ASP_PROT_IPA: return sua2sccp_tx_m3ua(inst, xua); default: LOGP(DLSCCP, LOGL_ERROR, "MTP-TRANSFER.req for " @@ -295,7 +296,8 @@ const struct osmo_sccp_addr *called) { struct osmo_sccp_user *scu; - + /* it is not really clear that called->pc will be set to + * anything here, in the case of a SSN-only CalledAddr */ scu = sccp_user_find(inst, called->ssn, called->pc); /* Is subsystem equipped? */ -- To view, visit https://gerrit.osmocom.org/2282 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I9098574cddeba10fcf8f1b6c196a7069a6805c56 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:28:48 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:28:48 +0000 Subject: [PATCH] libosmo-sccp[master]: WIP: default layer manager using RKM to register PC with SG Message-ID: Review at https://gerrit.osmocom.org/2283 WIP: default layer manager using RKM to register PC with SG Change-Id: I78d4623dd213b5c59007a026a6cc3cfe5c04af50 --- M include/osmocom/sigtran/osmo_ss7.h M include/osmocom/sigtran/sigtran_sap.h M src/Makefile.am M src/sccp_sap.c A src/xua_default_lm_fsm.c M src/xua_rkm.c 6 files changed, 399 insertions(+), 7 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/83/2283/1 diff --git a/include/osmocom/sigtran/osmo_ss7.h b/include/osmocom/sigtran/osmo_ss7.h index e33a9ad..7ddebae 100644 --- a/include/osmocom/sigtran/osmo_ss7.h +++ b/include/osmocom/sigtran/osmo_ss7.h @@ -343,7 +343,8 @@ bool asp_id_present; /* Layer Manager to which we talk */ - struct osmo_xua_layer_manager *lm; + const struct osmo_xua_layer_manager *lm; + void *lm_priv; struct { char *name; diff --git a/include/osmocom/sigtran/sigtran_sap.h b/include/osmocom/sigtran/sigtran_sap.h index d18aa3d..419498e 100644 --- a/include/osmocom/sigtran/sigtran_sap.h +++ b/include/osmocom/sigtran/sigtran_sap.h @@ -1,6 +1,8 @@ #pragma once #include +#include + enum osmo_sigtran_sap { SCCP_SAP_USER = _SAP_SS7_BASE, @@ -46,14 +48,31 @@ uint32_t code; }; +struct osmo_xlm_prim_rk_reg { + /* local routing key ID */ + uint32_t l_rk_id; + /* routing key */ + struct osmo_ss7_routing_key key; + enum osmo_ss7_as_traffic_mode traf_mode; +}; + +struct osmo_xlm_prim_rk_dereg { + uint32_t route_ctx; +}; + struct osmo_xlm_prim { struct osmo_prim_hdr oph; union { struct osmo_xlm_prim_notify notify; struct osmo_xlm_prim_error error; + struct osmo_xlm_prim_rk_reg rk_reg; + struct osmo_xlm_prim_rk_dereg rk_dereg; } u; }; #define msgb_xlm_prim(msg) ((struct osmo_xlm_prim *)(msg)->l1h) char *osmo_xlm_prim_name(struct osmo_prim_hdr *oph); + +/* XUA LM-SAP towards stack */ +int osmo_xlm_sap_down(struct osmo_ss7_asp *asp, struct osmo_prim_hdr *oph); diff --git a/src/Makefile.am b/src/Makefile.am index 7867282..f9b87b0 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -28,7 +28,7 @@ libosmo_sigtran_la_SOURCES = sccp_sap.c sua.c m3ua.c xua_msg.c sccp_helpers.c \ sccp2sua.c sccp_scrc.c sccp_sclc.c sccp_scoc.c \ - sccp_user.c xua_rkm.c \ + sccp_user.c xua_rkm.c xua_default_lm_fsm.c \ osmo_ss7.c osmo_ss7_hmrt.c xua_asp_fsm.c xua_as_fsm.c libosmo_sigtran_la_LDFLAGS = -version-info $(LIBVERSION) -no-undefined -export-symbols-regex '^osmo_' libosmo_sigtran_la_LIBADD = $(LIBOSMOCORE_LIBS) $(LIBOSMONETIF_LIBS) $(LIBSCTP_LIBS) diff --git a/src/sccp_sap.c b/src/sccp_sap.c index 2211f71..d4580ae 100644 --- a/src/sccp_sap.c +++ b/src/sccp_sap.c @@ -45,11 +45,43 @@ { const char *name = get_value_string(osmo_scu_prim_names, oph->primitive); - prim_name_buf[0] = '\0'; - strncpy(prim_name_buf, name, sizeof(prim_name_buf)-1); - prim_name_buf[sizeof(prim_name_buf)-1] = '\0'; - name = get_value_string(osmo_prim_op_names, oph->operation); - strncat(prim_name_buf, name, sizeof(prim_name_buf)-strlen(prim_name_buf)-2); + snprintf(prim_name_buf, sizeof(prim_name_buf), "%s.%s", name, + get_value_string(osmo_prim_op_names, oph->operation)); + + return prim_name_buf; +} + + +#include + +const struct value_string osmo_xlm_prim_names[] = { + { OSMO_XLM_PRIM_M_SCTP_ESTABLISH, "M-SCTP_ESTABLISH" }, + { OSMO_XLM_PRIM_M_SCTP_RELEASE, "M-SCTP_RELEASE" }, + { OSMO_XLM_PRIM_M_SCTP_RESTART, "M-SCTP_RESTART" }, + { OSMO_XLM_PRIM_M_SCTP_STATUS, "M-SCTP_STATUS" }, + { OSMO_XLM_PRIM_M_ASP_STATUS, "M-ASP_STATUS" }, + { OSMO_XLM_PRIM_M_AS_STATUS, "M-AS_STATUS" }, + { OSMO_XLM_PRIM_M_NOTIFY, "M-NOTIFY" }, + { OSMO_XLM_PRIM_M_ERROR, "M-ERROR" }, + { OSMO_XLM_PRIM_M_ASP_UP, "M-ASP_UP" }, + { OSMO_XLM_PRIM_M_ASP_DOWN, "M-ASP_DOWN" }, + { OSMO_XLM_PRIM_M_ASP_ACTIVE, "M-ASP_ACTIVE" }, + { OSMO_XLM_PRIM_M_ASP_INACTIVE, "M-ASP_INACTIVE" }, + { OSMO_XLM_PRIM_M_AS_ACTIVE, "M-AS_ACTIVE" }, + { OSMO_XLM_PRIM_M_AS_INACTIVE, "M-AS_INACTIVE" }, + { OSMO_XLM_PRIM_M_AS_DOWN, "M-AS_DOWN" }, + /* optional as per spec, not implemented yet */ + { OSMO_XLM_PRIM_M_RK_REG, "M-RK_REG" }, + { OSMO_XLM_PRIM_M_RK_DEREG, "M-RK_DEREG" }, + { 0, NULL }, +}; + +char *osmo_xlm_prim_name(struct osmo_prim_hdr *oph) +{ + const char *name = get_value_string(osmo_xlm_prim_names, oph->primitive); + + snprintf(prim_name_buf, sizeof(prim_name_buf), "%s.%s", name, + get_value_string(osmo_prim_op_names, oph->operation)); return prim_name_buf; } diff --git a/src/xua_default_lm_fsm.c b/src/xua_default_lm_fsm.c new file mode 100644 index 0000000..9606841 --- /dev/null +++ b/src/xua_default_lm_fsm.c @@ -0,0 +1,282 @@ +/* Default XUA Layer Manager */ +/* (C) 2017 by Harald Welte + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/* The idea of this default Layer Manager is as follows: + * - we wait until a SCTP connection is established + * - we issue the ASP-UP request and wait for the ASP being in UP state + * - we wait if we receive a M-NOTIFY indication about any AS in this ASP + * - if that's not received, we use RKM to register a routing context + * for our locally configured ASP + */ + +#include + +#include +#include + +#include "xua_internal.h" +#include "xua_asp_fsm.h" + +#define S(x) (1 << (x)) + +enum lm_state { + /* idle state, SCTP not connected */ + S_IDLE, + /* we're waiting for the ASP-UP to be confirmed */ + S_WAIT_ASP_UP, + /* we are waiting for any NOTIFY about an AS in this ASP */ + S_WAIT_NOTIFY, + /* we've sent a RK REG REQ and wait for the result */ + S_RKM_REG, + /* all systems up, we're communicating */ + S_ACTIVE, +}; + +enum lm_event { + LM_E_SCTP_EST_IND, + LM_E_ASP_UP_IND, + LM_E_NOTIFY_IND, + LM_E_AS_INACTIVE_IND, + LM_E_AS_ACTIVE_IND, + LM_E_AS_STATUS_IND, + LM_E_RKM_REG_CONF, + LM_E_SCTP_DISC_IND, +}; + +static const struct value_string lm_event_names[] = { + { LM_E_SCTP_EST_IND, "SCTP-ESTABLISH.ind" }, + { LM_E_ASP_UP_IND, "ASP-UP.ind" }, + { LM_E_NOTIFY_IND, "NOTIFY.ind" }, + { LM_E_AS_INACTIVE_IND, "AS-INACTIVE.ind" }, + { LM_E_AS_ACTIVE_IND, "AS-ACTIVE.ind" }, + { LM_E_AS_STATUS_IND, "AS-STATUS.ind" }, + { LM_E_RKM_REG_CONF, "RKM_REG.conf" }, + { LM_E_SCTP_DISC_IND, "SCTP-RELEASE.ind" }, + { 0, NULL } +}; + +enum lm_timer { + T_WAIT_ASP_UP, + T_WAIT_NOTIFY, + T_WAIT_NOTIFY_RKM, + T_WAIT_RK_REG_RESP, +}; + +struct lm_fsm_priv { + struct osmo_ss7_asp *asp; +}; + +static void lm_idle(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct lm_fsm_priv *lmp = fi->priv; + + switch (event) { + case LM_E_SCTP_EST_IND: + /* Try to transition to ASP-UP */ + osmo_fsm_inst_state_chg(fi, S_WAIT_ASP_UP, 20, T_WAIT_ASP_UP); + osmo_fsm_inst_dispatch(lmp->asp->fi, XUA_ASP_E_M_ASP_UP_REQ, NULL); + break; + } +} + +static void lm_wait_asp_up(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + switch (event) { + case LM_E_ASP_UP_IND: + /* ASP is sup, wait for some time if any NOTIFY + * indications about AS in this ASP are received */ + osmo_fsm_inst_state_chg(fi, S_WAIT_NOTIFY, 2, T_WAIT_NOTIFY); + break; + } +} + + +static int lm_timer_cb(struct osmo_fsm_inst *fi) +{ + struct lm_fsm_priv *lmp = fi->priv; + struct osmo_xlm_prim *prim; + + switch (fi->T) { + case T_WAIT_ASP_UP: + /* we have been waiting for the ASP to come up, but it + * failed to do so */ + /* FIXME: kill SCTP connection and re-try? */ + break; + case T_WAIT_NOTIFY: + /* No AS has reported via NOTIFY that is was + * (statically) configured at the SG for this ASP, so + * let's dynamically register */ + osmo_fsm_inst_state_chg(fi, S_RKM_REG, 10, T_WAIT_RK_REG_RESP); + prim = xua_xlm_prim_alloc(OSMO_XLM_PRIM_M_RK_REG, PRIM_OP_REQUEST); + osmo_xlm_sap_down(lmp->asp, &prim->oph); + break; + case T_WAIT_NOTIFY_RKM: + /* No AS has reported via NOTIFY even after dynamic RKM + * configuration */ + /* FIXME: disconnect/reconnect SCTP? */ + break; + case T_WAIT_RK_REG_RESP: + /* timeout of registration of routing key */ + /* FIXME: disconnect/reconect SCTP? */ + break; + } + return 0; +} + +static void lm_wait_notify(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct lm_fsm_priv *lmp = fi->priv; + + switch (event) { + case LM_E_AS_INACTIVE_IND: + /* we now know that an AS is associated with this ASP at + * the SG, and that this AS is currently inactive */ + /* request the ASP to go into active state (which + * hopefully will bring the AS to active, too) */ + osmo_fsm_inst_state_chg(fi, S_ACTIVE, 0, 0); + osmo_fsm_inst_dispatch(lmp->asp->fi, XUA_ASP_E_M_ASP_ACTIVE_REQ, NULL); + break; + } +}; + +static void lm_rkm_reg(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + switch (event) { + case LM_E_RKM_REG_CONF: + /* RKM registration was successful, we can transition to + * WAIT_NOTIFY state and assume that an + * NOTIFY/AS-INACTIVE arrives within 20 seconds */ + osmo_fsm_inst_state_chg(fi, S_WAIT_NOTIFY, 20, T_WAIT_NOTIFY_RKM); + break; + } +} + +static void lm_active(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct lm_fsm_priv *lmp = fi->priv; + + switch (event) { + case LM_E_AS_INACTIVE_IND: + /* request the ASP to go into active state */ + osmo_fsm_inst_dispatch(lmp->asp->fi, XUA_ASP_E_M_ASP_ACTIVE_REQ, NULL); + break; + } +} + +static void lm_allstate(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + switch (event) { + case LM_E_SCTP_DISC_IND: + /* FIXME: disconnect/reconnect SCTP? */ + break; + } +} + +static const struct osmo_fsm_state lm_states[] = { + [S_IDLE] = { + .in_event_mask = S(LM_E_SCTP_EST_IND), + .out_state_mask = S(S_WAIT_NOTIFY), + .name = "IDLE", + .action = lm_idle, + }, + [S_WAIT_ASP_UP] = { + .in_event_mask = S(LM_E_ASP_UP_IND), + .out_state_mask = S(S_WAIT_NOTIFY), + .name = "WAIT_ASP_UP", + .action = lm_wait_asp_up, + }, + [S_WAIT_NOTIFY] = { + .in_event_mask = S(LM_E_AS_INACTIVE_IND) | S(LM_E_NOTIFY_IND), + .out_state_mask = S(S_RKM_REG) | S(S_ACTIVE), + .name = "WAIT_NOTIFY", + .action = lm_wait_notify, + }, + [S_RKM_REG] = { + .in_event_mask = S(LM_E_RKM_REG_CONF), + .out_state_mask = S(S_WAIT_NOTIFY), + .name = "RKM_REG", + .action = lm_rkm_reg, + }, + [S_ACTIVE] = { + .in_event_mask = S(LM_E_AS_INACTIVE_IND), + .name = "ACTIVE", + .action = lm_active, + }, +}; + +/* Map from incoming XLM SAP primitives towards FSM events */ +static const struct osmo_prim_event_map lm_event_map[] = { + { XUA_SAP_LM, OSMO_XLM_PRIM_M_SCTP_ESTABLISH, PRIM_OP_INDICATION, LM_E_SCTP_EST_IND }, + { XUA_SAP_LM, OSMO_XLM_PRIM_M_SCTP_RELEASE, PRIM_OP_INDICATION, LM_E_SCTP_DISC_IND }, + { XUA_SAP_LM, OSMO_XLM_PRIM_M_AS_STATUS, PRIM_OP_INDICATION, LM_E_AS_STATUS_IND }, + { XUA_SAP_LM, OSMO_XLM_PRIM_M_NOTIFY, PRIM_OP_INDICATION, LM_E_NOTIFY_IND }, + { XUA_SAP_LM, OSMO_XLM_PRIM_M_AS_INACTIVE, PRIM_OP_INDICATION, LM_E_AS_INACTIVE_IND }, + { XUA_SAP_LM, OSMO_XLM_PRIM_M_AS_ACTIVE, PRIM_OP_INDICATION, LM_E_AS_ACTIVE_IND }, + { XUA_SAP_LM, OSMO_XLM_PRIM_M_RK_REG, PRIM_OP_CONFIRM, LM_E_RKM_REG_CONF }, + { 0, 0, OSMO_NO_EVENT }, +}; + + +struct osmo_fsm default_lm_fsm = { + .name = "XUA default LM", + .states = lm_states, + .num_states = ARRAY_SIZE(lm_states), + .timer_cb = lm_timer_cb, + .event_names = lm_event_names, + .allstate_event_mask = S(LM_E_SCTP_DISC_IND), + .allstate_action = lm_allstate, +}; + + +/* layer manager primitive call-back function, registered osmo_ss7 */ +static int default_lm_prim_cb(struct osmo_prim_hdr *oph, void *_asp) +{ + struct osmo_ss7_asp *asp = _asp; + struct osmo_fsm_inst *fi = asp->lm_priv; + uint32_t event = osmo_event_for_prim(oph, lm_event_map); + + osmo_fsm_inst_dispatch(fi, event, oph); + + return 0; +} + +static const struct osmo_xua_layer_manager default_layer_manager = { + .prim_cb = default_lm_prim_cb, +}; + +int xua_asp_use_default_lm(struct osmo_ss7_asp *asp, int log_level) +{ + struct lm_fsm_priv *lmp; + struct osmo_fsm_inst *fi; + + fi = osmo_fsm_inst_alloc(&default_lm_fsm, asp, NULL, log_level, asp->cfg.name); + + lmp = talloc_zero(fi, struct lm_fsm_priv); + if (!lmp) { + osmo_fsm_inst_term(fi, OSMO_FSM_TERM_ERROR, NULL); + return -ENOMEM; + } + lmp->asp = asp; + fi->priv = lmp; + + asp->lm = &default_layer_manager; + asp->lm_priv = fi; + + return 0; +} + diff --git a/src/xua_rkm.c b/src/xua_rkm.c index 12d59c7..d906db4 100644 --- a/src/xua_rkm.c +++ b/src/xua_rkm.c @@ -75,6 +75,41 @@ return msg->tail - old_tail; } +static void xua_rkm_send_reg_req(struct osmo_ss7_asp *asp, uint32_t l_rk_id, + const struct osmo_ss7_routing_key *rkey, + enum osmo_ss7_as_traffic_mode traf_mode) +{ + struct msgb *msg = m3ua_msgb_alloc(__func__); + int tmod = osmo_ss7_tmode_to_xua(traf_mode); + + /* One individual Registration Request according to Chapter 3.6.1 */ + msgb_put_u16(msg, M3UA_IEI_ROUT_KEY); /* outer IEI */ + msgb_put_u16(msg, 32 + 4); /* outer length */ + /* nested IEIs */ + msgb_t16l16vp_put_u32(msg, M3UA_IEI_LOC_RKEY_ID, l_rk_id); + msgb_t16l16vp_put_u32(msg, M3UA_IEI_ROUTE_CTX, rkey->context); + msgb_t16l16vp_put_u32(msg, M3UA_IEI_TRAF_MODE_TYP, tmod); + msgb_t16l16vp_put_u32(msg, M3UA_IEI_DEST_PC, rkey->pc); + + msgb_push_m3ua_hdr(msg, M3UA_MSGC_RKM, M3UA_RKM_REG_REQ); + + osmo_ss7_asp_send(asp, msg); +} + +static void xua_rkm_send_dereg_req(struct osmo_ss7_asp *asp, uint32_t route_ctx) +{ + struct msgb *msg = m3ua_msgb_alloc(__func__); + + /* One individual De-Registration Request according to Chapter 3.6.3 */ + msgb_t16l16vp_put_u32(msg, M3UA_IEI_ROUTE_CTX, route_ctx); + + msgb_push_m3ua_hdr(msg, M3UA_MSGC_RKM, M3UA_RKM_DEREG_REQ); + + osmo_ss7_asp_send(asp, msg); +} + + + /* handle a single registration request IE (nested IEs in 'innner' */ static int handle_rkey_reg(struct osmo_ss7_asp *asp, struct xua_msg *inner, struct msgb *resp) @@ -294,3 +329,26 @@ } return rc; } + +int osmo_xlm_sap_down(struct osmo_ss7_asp *asp, struct osmo_prim_hdr *oph) +{ + struct osmo_xlm_prim *prim = (struct osmo_xlm_prim *) oph; + + LOGPASP(asp, DLSS7, LOGL_DEBUG, "Received XUA Layer Manager Primitive: %s)\n", + osmo_xlm_prim_name(&prim->oph)); + + switch (OSMO_PRIM_HDR(&prim->oph)) { + case OSMO_PRIM(OSMO_XLM_PRIM_M_RK_REG, PRIM_OP_REQUEST): + xua_rkm_send_reg_req(asp, prim->u.rk_reg.l_rk_id, &prim->u.rk_reg.key, + prim->u.rk_reg.traf_mode); + break; + case OSMO_PRIM(OSMO_XLM_PRIM_M_RK_DEREG, PRIM_OP_REQUEST): + xua_rkm_send_dereg_req(asp, prim->u.rk_dereg.route_ctx); + break; + default: + LOGPASP(asp, DLSS7, LOGL_ERROR, "Unknown XUA Layer Manager Primitive: %s\n", + osmo_xlm_prim_name(&prim->oph)); + } + + return 0; +} -- To view, visit https://gerrit.osmocom.org/2283 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I78d4623dd213b5c59007a026a6cc3cfe5c04af50 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:29:20 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:29:20 +0000 Subject: [ABANDON] libosmo-sccp[master]: WIP: default layer manager using RKM to register PC with SG In-Reply-To: References: Message-ID: Harald Welte has abandoned this change. Change subject: WIP: default layer manager using RKM to register PC with SG ...................................................................... Abandoned -- To view, visit https://gerrit.osmocom.org/2283 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: abandon Gerrit-Change-Id: I78d4623dd213b5c59007a026a6cc3cfe5c04af50 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:29:27 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:29:27 +0000 Subject: [ABANDON] libosmo-sccp[master]: WIP: Add IPA/SCCPlite stacking In-Reply-To: References: Message-ID: Harald Welte has abandoned this change. Change subject: WIP: Add IPA/SCCPlite stacking ...................................................................... Abandoned -- To view, visit https://gerrit.osmocom.org/2282 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: abandon Gerrit-Change-Id: I9098574cddeba10fcf8f1b6c196a7069a6805c56 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:29:32 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:29:32 +0000 Subject: [ABANDON] libosmo-sccp[master]: WIP: osmo-stp executable In-Reply-To: References: Message-ID: Harald Welte has abandoned this change. Change subject: WIP: osmo-stp executable ...................................................................... Abandoned -- To view, visit https://gerrit.osmocom.org/2281 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: abandon Gerrit-Change-Id: If32227b8d3127c6178e4ee45527ce65f69bc7b1e Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:29:42 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:29:42 +0000 Subject: libosmo-sccp[master]: WIP: osmo-stp executable In-Reply-To: References: Message-ID: Harald Welte has restored this change. Change subject: WIP: osmo-stp executable ...................................................................... Restored -- To view, visit https://gerrit.osmocom.org/2281 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: restore Gerrit-Change-Id: If32227b8d3127c6178e4ee45527ce65f69bc7b1e Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:29:46 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:29:46 +0000 Subject: libosmo-sccp[master]: WIP: osmo-stp executable In-Reply-To: References: Message-ID: Patch Set 1: Code-Review-1 -- To view, visit https://gerrit.osmocom.org/2281 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: If32227b8d3127c6178e4ee45527ce65f69bc7b1e Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:31:09 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:31:09 +0000 Subject: [PATCH] libosmo-sccp[master]: Replace unused m3ua_types.h with protocol/m3ua.h In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2191 to look at the new patch set (#2). Replace unused m3ua_types.h with protocol/m3ua.h This is more in line with what we do for SUA in protocol/sua.h. Change-Id: I4a32cb698d28b4ccff9280b8512557ab5a353fe3 --- M include/osmocom/sigtran/Makefile.am D include/osmocom/sigtran/m3ua_types.h A include/osmocom/sigtran/protocol/m3ua.h 3 files changed, 149 insertions(+), 130 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/91/2191/2 diff --git a/include/osmocom/sigtran/Makefile.am b/include/osmocom/sigtran/Makefile.am index e168256..ca7de0f 100644 --- a/include/osmocom/sigtran/Makefile.am +++ b/include/osmocom/sigtran/Makefile.am @@ -1,7 +1,7 @@ -sigtran_HEADERS = m3ua_types.h xua_types.h xua_msg.h m2ua_types.h sccp_sap.h \ +sigtran_HEADERS = xua_types.h xua_msg.h m2ua_types.h sccp_sap.h \ sua.h sigtran_sap.h sccp_helpers.h sigtrandir = $(includedir)/osmocom/sigtran -sigtran_prot_HEADERS = protocol/sua.h +sigtran_prot_HEADERS = protocol/sua.h protocol/m3ua.h sigtran_protdir = $(includedir)/osmocom/sigtran/protocol diff --git a/include/osmocom/sigtran/m3ua_types.h b/include/osmocom/sigtran/m3ua_types.h deleted file mode 100644 index c8e62b4..0000000 --- a/include/osmocom/sigtran/m3ua_types.h +++ /dev/null @@ -1,128 +0,0 @@ -#pragma once - -/** - * Types found in the M3UA RFC 4666 - */ - -#include - - -#define M3UA_VERSION 1 - -enum { - M3UA_CLS_MGMT, /* Management (MGMT) Message [IUA/M2UA/M3UA/SUA] */ - M3UA_CLS_TRANS, /* Transfer Messages [M3UA] */ - M3UA_CLS_SSNM, /* SS7 Signalling Network Management (SSNM) Messages [M3UA/SUA] */ - M3UA_CLS_ASPSM, /* ASP State Maintenance (ASPSM) Messages [IUA/M2UA/M3UA/SUA] */ - M3UA_CLS_ASPTM, /* ASP Traffic Maintenance (ASPTM) Messages [IUA/M2UA/M3UA/SUA] */ - M3UA_CLS_RESERVED1, /* Reserved for Other SIGTRAN Adaptation Layers */ - M3UA_CLS_RESERVED2, /* Reserved for Other SIGTRAN Adaptation Layers */ - M3UA_CLS_RESERVED3, /* Reserved for Other SIGTRAN Adaptation Layers */ - M3UA_CLS_RESERVED4, /* Reserved for Other SIGTRAN Adaptation Layers */ - M3UA_CLS_RKM, /* Routing Key Management (RKM) Messages (M3UA) */ -}; - -/** - * Management (MGMT) messages - */ -enum { - M3UA_MGMT_ERROR, /* Error (ERR) */ - M3UA_MGMT_NTFY, /* Notify (NTFY) */ -}; - -/** - * Transfer Messages - */ -enum { - M3UA_TRANS_RESERVED, /* Reserved */ - M3UA_TRANS_DATA, /* Payload Data (DATA) */ -}; - -/** - * SS7 Signalling Network Management (SSNM) Messages - */ -enum { - M3UA_SSNM_RESERVED, /* Reserved */ - M3UA_SSNM_DUNA, /* Destination Unavailable (DUNA) */ - M3UA_SSNM_DAVA, /* Destination Available (DAVA) */ - M3UA_SSNM_DAUD, /* Destination State Audit (DAUD) */ - M3UA_SSNM_SCON, /* Signalling Congestion (SCON) */ - M3UA_SSNM_DUPU, /* Destination User Part Unavailable (DUPU) */ - M3UA_SSNM_DRST, /* Destination Restricted (DRST) */ -}; - -/** - * Application Server Process State Maintaenance (ASPSM) messages - */ -enum { - M3UA_ASPSM_RESERVED, /* Reserved */ - M3UA_ASPSM_UP, /* ASP Up (UP) */ - M3UA_ASPSM_DOWN, /* ASP Down (DOWN) */ - M3UA_ASPSM_BEAT, /* Heartbeat (BEAT) */ - M3UA_ASPSM_UP_ACK, /* ASP Up Ack (UP ACK) */ - M3UA_ASPSM_DOWN_ACK, /* ASP Down Ack (DOWN ACK) */ - M3UA_ASPSM_BEAT_ACK, /* Heartbeat Ack (BEAT ACK) */ -}; - -/** - * Application Server Process Traffic Maintaenance (ASPTM) messages. - */ -enum { - M3UA_ASPTM_RESERVED, /* Reserved */ - M3UA_ASPTM_ACTIV, /* ASP Active (ACTIVE) */ - M3UA_ASPTM_INACTIV, /* ASP Inactive (INACTIVE) */ - M3UA_ASPTM_ACTIV_ACK, /* ASP Active Ack (ACTIVE ACK) */ - M3UA_ASPTM_INACTIV_ACK, /* ASP Inactive Ack (INACTIVE ACK) */ -}; - -/** - * Routing Key Management (RKM) Messages - */ -enum { - M3UA_RKM_RESERVED, /* Reserved */ - M3UA_RKM_REG_REQ, /* Registration Request (REG REQ) */ - M3UA_RKM_REG_RSP, /* Registration Response (REG RSP) */ - M3UA_RKM_DEREG_REQ, /* Deregistration Request (DEREG REQ) */ - M3UA_RKM_DEREG_RSP, /* Deregistration Response (DEREG RSP) */ -}; - -/** - * Tag Values for M3UA - */ -enum { - M3UA_TAG_NET_APPEAR = 0x0200, /* Network Appearance */ - M3UA_TAG_RESERVED1, /* Reserved */ - M3UA_TAG_RESERVED2, /* Reserved */ - M3UA_TAG_RESERVED3, /* Reserved */ - M3UA_TAG_USER_CAUSE, /* User/Cause */ - M3UA_TAG_CONGEST_IND, /* Congestion Indications */ - M3UA_TAG_CONCERN_DEST, /* Concerned Destination */ - M3UA_TAG_ROUTING_KEY, /* Routing Key */ - M3UA_TAG_REG_RESULT, /* Registration Result */ - M3UA_TAG_DEREG_RESULT, /* Deregistration Result */ - M3UA_TAG_LOCAL_ROUT_KEY_IDENT, /* Local Routing Key Identifier */ - M3UA_TAG_DEST_PC, /* Destination Point Code */ - M3UA_TAG_SERV_IND, /* Service Indicators */ - M3UA_TAG_RESERVED4, /* Reserved */ - M3UA_TAG_ORIG_PC_LIST, /* Originating Point Code List */ - M3UA_TAG_RESERVED5, /* Reserved */ - M3UA_TAG_PROTO_DATA, /* Protocol Data */ - M3UA_TAG_RESERVED6, /* Reserved */ - M3UA_TAG_REG_STATUS, /* Registration Status */ - M3UA_TAG_DEREG_STATUS, /* Deregistration Status */ -}; - - -/** - * Protocol data for transport messages. This is - * replacing the MTP L3 header - */ -struct m3ua_protocol_data { - uint32_t opc; - uint32_t dpc; - uint8_t si; - uint8_t ni; - uint8_t mp; - uint8_t sls; - uint8_t data[0]; -} __attribute__((packed)); diff --git a/include/osmocom/sigtran/protocol/m3ua.h b/include/osmocom/sigtran/protocol/m3ua.h new file mode 100644 index 0000000..d4dc1fe --- /dev/null +++ b/include/osmocom/sigtran/protocol/m3ua.h @@ -0,0 +1,147 @@ +/* RFC 4666 M3UA SCCP User Adaption */ + +/* (C) 2017 by Harald Welte + * + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once +#include + +#define M3UA_VERSION 1 +#define M3UA_PPID 3 +#define M3UA_PORT 2905 + +/* 3.1.2 Message Classes */ +#define M3UA_MSGC_MGMT 0 +#define M3UA_MSGC_XFER 1 +#define M3UA_MSGC_SNM 2 +#define M3UA_MSGC_ASPSM 3 +#define M3UA_MSGC_ASPTM 4 +#define M3UA_MSGC_RKM 9 + +/* 3.1.3 Message Types */ +#define M3UA_MGMT_ERR 0 +#define M3UA_MGMT_NTFY 1 + +#define M3UA_XFER_DATA 1 + +#define M3UA_SNM_DUNA 1 +#define M3UA_SNM_DAVA 2 +#define M3UA_SNM_DAUD 3 +#define M3UA_SNM_SCON 4 +#define M3UA_SNM_DUPU 5 +#define M3UA_SNM_DRST 6 + +#define M3UA_ASPSM_UP 1 +#define M3UA_ASPSM_DOWN 2 +#define M3UA_ASPSM_BEAT 3 +#define M3UA_ASPSM_UP_ACK 4 +#define M3UA_ASPSM_DOWN_ACK 5 +#define M3UA_ASPSM_BEAT_ACK 6 + +#define M3UA_ASPTM_ACTIVE 1 +#define M3UA_ASPTM_INACTIVE 2 +#define M3UA_ASPTM_ACTIVE_ACK 3 +#define M3UA_ASPTM_INACTIVE_ACK 4 + +#define M3UA_RKM_REG_REQ 1 +#define M3UA_RKM_REG_RSP 2 +#define M3UA_RKM_DEREG_REQ 3 +#define M3UA_RKM_DEREG_RSP 4 + +#define M3UA_IEI_INFO_STRING 0x0004 +#define M3UA_IEI_ROUTE_CTX 0x0006 +#define M3UA_IEI_DIAG_INFO 0x0007 +#define M3UA_IEI_HEARDBT_DATA 0x0009 +#define M3UA_IEI_TRAF_MODE_TYP 0x000b +#define M3UA_IEI_ERR_CODE 0x000c +#define M3UA_IEI_STATUS 0x000d +#define M3UA_IEI_ASP_ID 0x0011 +#define M3UA_IEI_AFFECTED_PC 0x0012 +#define M3UA_IEI_CORR_ID 0x0013 + +/* 3.2 M3UA specific parameters */ + +#define M3UA_IEI_NET_APPEAR 0x0200 +#define M3UA_IEI_USER_CAUSE 0x0204 +#define M3UA_IEI_CONG_IND 0x0205 +#define M3UA_IEI_CONC_DEST 0x0206 +#define M3UA_IEI_ROUT_KEY 0x0207 +#define M3UA_IEI_REG_RESULT 0x0208 +#define M3UA_IEI_DEREG_RESULT 0x0209 +#define M3UA_IEI_LOC_RKEY_ID 0x020a +#define M3UA_IEI_DEST_PC 0x020b +#define M3UA_IEI_SVC_IND 0x020c +#define M3UA_IEI_ORIG_PC 0x020e +#define M3UA_IEI_PROT_DATA 0x0210 +#define M3UA_IEI_REG_STATUS 0x0212 +#define M3UA_IEI_DEREG_STATUS 0x0213 + +/* 3.3.1 Payload Data Message */ +struct m3ua_data_hdr { + uint32_t opc; /* Originating Point Code */ + uint32_t dpc; /* Destination Point Code */ + uint8_t si; /* Service Indicator */ + uint8_t ni; /* Network Indicator */ + uint8_t mp; /* Message Priority */ + uint8_t sls; /* Signalling Link Selection */ +} __attribute__ ((packed)); + +/* 3.8.2 Notify */ + +#define M3UA_NOTIFY(type, info) ((info) << 16 | (type)) +#define M3UA_NOTIFY_T_STATCHG 1 +#define M3UA_NOTIFY_T_OTHER 2 + +#define M3UA_NOTIFY_I_RESERVED 1 +#define M3UA_NOTIFY_I_AS_INACT 2 +#define M3UA_NOTIFY_I_AS_ACT 3 +#define M3UA_NOTIFY_I_AS_PEND 4 + +#define M3UA_NOTIFY_I_OT_INS_RES 1 +#define M3UA_NOTIFY_I_OT_ALT_ASP_ACT 2 +#define M3UA_NOTIFY_I_OT_ASP_FAILURE 3 + +/* 3.8.1 Error */ +enum m3ua_error_code { + M3UA_ERR_INVALID_VERSION = 0x01, + /* not used in M3UA */ + M3UA_ERR_UNSUPP_MSG_CLASS = 0x03, + M3UA_ERR_UNSUPP_MSG_TYPE = 0x04, + M3UA_ERR_UNSUPP_TRAF_MOD_TYP = 0x05, + M3UA_ERR_UNEXPECTED_MSG = 0x06, + M3UA_ERR_PROTOCOL_ERR = 0x07, + /* not used in M3UA */ + M3UA_ERR_INVAL_STREAM_ID = 0x09, + /* not used in M3UA */ + /* not used in M3UA */ + /* not used in M3UA */ + M3UA_ERR_REFUSED_MGMT_BLOCKING = 0x0d, + M3UA_ERR_ASP_ID_REQD = 0x0e, + M3UA_ERR_INVAL_ASP_ID = 0x0f, + /* not used in M3UA */ + M3UA_ERR_INVAL_PARAM_VAL = 0x11, + M3UA_ERR_PARAM_FIELD_ERR = 0x12, + M3UA_ERR_UNEXP_PARAM = 0x13, + M3UA_ERR_DEST_STATUS_UNKN = 0x14, + M3UA_ERR_INVAL_NET_APPEAR = 0x15, + M3UA_ERR_MISSING_PARAM = 0x16, + /* not used in M3UA */ + /* not used in M3UA */ + M3UA_ERR_INVAL_ROUT_CTX = 0x19, + M3UA_ERR_NO_CONFGD_AS_FOR_ASP = 0x1a, +}; -- To view, visit https://gerrit.osmocom.org/2191 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I4a32cb698d28b4ccff9280b8512557ab5a353fe3 Gerrit-PatchSet: 2 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:31:09 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:31:09 +0000 Subject: [PATCH] libosmo-sccp[master]: sua.h: Define more IEIs; base definitions on m3ua.h In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2192 to look at the new patch set (#2). sua.h: Define more IEIs; base definitions on m3ua.h A lot of IEIs are identical between the different xUA dialects, so let's base the SUA definitions on the m3ua definitions. Change-Id: I64c7166cf0b5c8a927ab7e14955100f8d13fe16a --- M include/osmocom/sigtran/protocol/sua.h 1 file changed, 13 insertions(+), 2 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/92/2192/2 diff --git a/include/osmocom/sigtran/protocol/sua.h b/include/osmocom/sigtran/protocol/sua.h index d191368..0ae4131 100644 --- a/include/osmocom/sigtran/protocol/sua.h +++ b/include/osmocom/sigtran/protocol/sua.h @@ -21,6 +21,9 @@ #pragma once #include +#include + +#define SUA_VERSION 1 #define SUA_PPID 4 #define SUA_PORT 14001 @@ -76,8 +79,16 @@ #define SUA_CO_COERR 10 #define SUA_CO_COIT 11 /* Connection Oriented Inactiviy Test */ -#define SUA_IEI_ROUTE_CTX 0x0006 -#define SUA_IEI_CORR_ID 0x0013 +#define SUA_IEI_INFO_STRING M3UA_IEI_INFO_STRING +#define SUA_IEI_ROUTE_CTX M3UA_IEI_ROUTE_CTX +#define SUA_IEI_DIAG_INFO M3UA_IEI_DIAG_INFO +#define SUA_IEI_HEARTBT_DATA M3UA_IEI_HEARDBT_DATA +#define SUA_IEI_TRAF_MODE_TYP M3UA_IEI_TRAF_MODE_TYP +#define SUA_IEI_ERR_CODE M3UA_IEI_ERR_CODE +#define SUA_IEI_STATUS M3UA_IEI_STATUS +#define SUA_IEI_ASP_ID M3UA_IEI_ASP_ID +#define SUA_IEI_AFFECTED_PC M3UA_IEI_AFFECTED_PC +#define SUA_IEI_CORR_ID M3UA_IEI_CORR_ID #define SUA_IEI_REG_RESULT 0x0014 #define SUA_IEI_DEREG_RESULT 0x0015 -- To view, visit https://gerrit.osmocom.org/2192 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I64c7166cf0b5c8a927ab7e14955100f8d13fe16a Gerrit-PatchSet: 2 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:31:09 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:31:09 +0000 Subject: [PATCH] libosmo-sccp[master]: sua.h: Add #define for the varius SUA protocol errors In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2193 to look at the new patch set (#2). sua.h: Add #define for the varius SUA protocol errors again using m3ua.h definitions as base whenever applicable. Change-Id: Iec2563cb158b1c18064671564a7502b5c4d82517 --- M include/osmocom/sigtran/protocol/sua.h 1 file changed, 22 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/93/2193/2 diff --git a/include/osmocom/sigtran/protocol/sua.h b/include/osmocom/sigtran/protocol/sua.h index 0ae4131..de67041 100644 --- a/include/osmocom/sigtran/protocol/sua.h +++ b/include/osmocom/sigtran/protocol/sua.h @@ -136,3 +136,25 @@ #define SUA_CAUSE_T_RELEASE 0x0300 #define SUA_CAUSE_T_RESET 0x0400 #define SUA_CAUSE_T_ERROR 0x0500 + +/* 3.9.12 Error: Identical to M3UA, extended by two at the bottom */ +#define SUA_ERR_INVALID_VERSION M3UA_ERR_INVALID_VERSION +#define SUA_ERR_UNSUPP_MSG_CLASS M3UA_ERR_UNSUPP_MSG_CLASS +#define SUA_ERR_UNSUPP_MSG_TYPE M3UA_ERR_UNSUPP_MSG_TYPE +#define SUA_ERR_UNSUPP_TRAF_MOD_TYP M3UA_ERR_UNSUPP_TRAF_MOD_TYP +#define SUA_ERR_UNEXPECTED_MSG M3UA_ERR_UNEXPECTED_MSG +#define SUA_ERR_PROTOCOL_ERR M3UA_ERR_PROTOCOL_ERR +#define SUA_ERR_INVAL_STREAM_ID M3UA_ERR_INVAL_STREAM_ID +#define SUA_ERR_REFUSED_MGMT_BLOCKING M3UA_ERR_REFUSED_MGMT_BLOCKING +#define SUA_ERR_ASP_ID_REQD M3UA_ERR_ASP_ID_REQD +#define SUA_ERR_INVAL_ASP_ID M3UA_ERR_INVAL_ASP_ID +#define SUA_ERR_INVAL_PARAM_VAL M3UA_ERR_INVAL_PARAM_VAL +#define SUA_ERR_PARAM_FIELD_ERR M3UA_ERR_PARAM_FIELD_ERR +#define SUA_ERR_UNEXP_PARAM M3UA_ERR_UNEXP_PARAM +#define SUA_ERR_DEST_STATUS_UNKN M3UA_ERR_DEST_STATUS_UNKN +#define SUA_ERR_INVAL_NET_APPEAR M3UA_ERR_INVAL_NET_APPEAR +#define SUA_ERR_MISSING_PARAM M3UA_ERR_MISSING_PARAM +#define SUA_ERR_INVAL_ROUT_CTX M3UA_ERR_INVAL_ROUT_CTX +#define SUA_ERR_NO_CONFGD_AS_FOR_ASP M3UA_ERR_NO_CONFGD_AS_FOR_ASP +#define SUA_ERR_SUBSYS_STATUS_UNKN 0x1b +#define SUA_ERR_INVAL_LOADSH_LEVEL 0x1c -- To view, visit https://gerrit.osmocom.org/2193 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Iec2563cb158b1c18064671564a7502b5c4d82517 Gerrit-PatchSet: 2 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:31:09 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:31:09 +0000 Subject: [PATCH] libosmo-sccp[master]: gitignore: add 'tags' files as created by 'make ctags' In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2194 to look at the new patch set (#2). gitignore: add 'tags' files as created by 'make ctags' Change-Id: I9e4ec0e07b996092a1f4e6a01911dc0041111498 --- M .gitignore 1 file changed, 2 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/94/2194/2 diff --git a/.gitignore b/.gitignore index 168690a..abb2458 100644 --- a/.gitignore +++ b/.gitignore @@ -70,3 +70,5 @@ *.pc config.* + +tags -- To view, visit https://gerrit.osmocom.org/2194 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I9e4ec0e07b996092a1f4e6a01911dc0041111498 Gerrit-PatchSet: 2 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:31:09 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:31:09 +0000 Subject: [PATCH] libosmo-sccp[master]: gitignore: use one wildcard line for all test executables In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2195 to look at the new patch set (#2). gitignore: use one wildcard line for all test executables Change-Id: I53ce43fa8e09646dec56c6cc32b09c4618e9b5a5 --- M .gitignore 1 file changed, 1 insertion(+), 8 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/95/2195/2 diff --git a/.gitignore b/.gitignore index abb2458..9d1435f 100644 --- a/.gitignore +++ b/.gitignore @@ -53,14 +53,7 @@ tests/channel/channel_test tests/db/db_test tests/debug/debug_test -tests/gsm0408/gsm0408_test -tests/m2ua/m2ua_test -tests/mtp/mtp_parse_test -tests/sccp/sccp_test -tests/sms/sms_test -tests/timer/timer_test -tests/sigtran/sua_server_test -tests/sigtran/sua_client_test +tests/*/*_test tests/atconfig tests/package.m4 -- To view, visit https://gerrit.osmocom.org/2195 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I53ce43fa8e09646dec56c6cc32b09c4618e9b5a5 Gerrit-PatchSet: 2 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:31:09 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:31:09 +0000 Subject: [PATCH] libosmo-sccp[master]: xua_msg: Add xua_msg_free_tag() and xua_msg_copy_part() In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2196 to look at the new patch set (#3). xua_msg: Add xua_msg_free_tag() and xua_msg_copy_part() ... also, mark input to xua_msg_find_tag as 'const' pointer. Change-Id: I083634db9c3606bcff87700f253054a38a20816d --- M include/osmocom/sigtran/xua_msg.h M src/xua_msg.c 2 files changed, 31 insertions(+), 2 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/96/2196/3 diff --git a/include/osmocom/sigtran/xua_msg.h b/include/osmocom/sigtran/xua_msg.h index 2a6e3ae..23f92c5 100644 --- a/include/osmocom/sigtran/xua_msg.h +++ b/include/osmocom/sigtran/xua_msg.h @@ -50,7 +50,10 @@ int xua_msg_add_data(struct xua_msg *msg, uint16_t tag, uint16_t len, uint8_t *dat); -struct xua_msg_part *xua_msg_find_tag(struct xua_msg *msg, uint16_t tag); +struct xua_msg_part *xua_msg_find_tag(const struct xua_msg *msg, uint16_t tag); +int xua_msg_free_tag(struct xua_msg *xua, uint16_t tag); +int xua_msg_copy_part(struct xua_msg *xua_out, uint16_t tag_out, + const struct xua_msg *xua_in, uint16_t tag_in); struct xua_msg *xua_from_msg(const int version, uint16_t len, uint8_t *data); struct msgb *xua_to_msg(const int version, struct xua_msg *msg); diff --git a/src/xua_msg.c b/src/xua_msg.c index 4a3e013..71511a9 100644 --- a/src/xua_msg.c +++ b/src/xua_msg.c @@ -77,7 +77,7 @@ return 0; } -struct xua_msg_part *xua_msg_find_tag(struct xua_msg *xua, uint16_t tag) +struct xua_msg_part *xua_msg_find_tag(const struct xua_msg *xua, uint16_t tag) { struct xua_msg_part *part; @@ -88,6 +88,32 @@ return NULL; } +int xua_msg_free_tag(struct xua_msg *xua, uint16_t tag) +{ + struct xua_msg_part *part; + + llist_for_each_entry(part, &xua->headers, entry) { + if (part->tag == tag) { + llist_del(&part->entry); + talloc_free(part); + return 1; + } + } + return 0; +} + +int xua_msg_copy_part(struct xua_msg *xua_out, uint16_t tag_out, + const struct xua_msg *xua_in, uint16_t tag_in) +{ + const struct xua_msg_part *part; + + part = xua_msg_find_tag(xua_in, tag_in); + if (!part) + return -1; + + return xua_msg_add_data(xua_out, tag_out, part->len, part->dat); +} + struct xua_msg *xua_from_msg(const int version, uint16_t len, uint8_t *data) { struct xua_parameter_hdr *par; -- To view, visit https://gerrit.osmocom.org/2196 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I083634db9c3606bcff87700f253054a38a20816d Gerrit-PatchSet: 3 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:31:09 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:31:09 +0000 Subject: [PATCH] libosmo-sccp[master]: xua_msg: Add concept of xua_msg_class and xua_msg_dialect In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2197 to look at the new patch set (#3). xua_msg: Add concept of xua_msg_class and xua_msg_dialect A xua_msg_class repreents one xUA message class (like M3UA XFER or SUA CL). A dialect is then something like SUA or M3UA, each consisting of as many as 256 message classes. Each class contains value_strings of the individual messages, as well as constraint information on mandatory IEs for each message. Change-Id: Ib538aca295b7b50132bc814b2d7b56cbe5d65bfc --- M include/osmocom/sigtran/xua_msg.h M src/xua_msg.c 2 files changed, 130 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/97/2197/3 diff --git a/include/osmocom/sigtran/xua_msg.h b/include/osmocom/sigtran/xua_msg.h index 23f92c5..6e98409 100644 --- a/include/osmocom/sigtran/xua_msg.h +++ b/include/osmocom/sigtran/xua_msg.h @@ -42,6 +42,23 @@ /* TODO: keep small data in the struct for perf reasons */ }; +struct xua_msg_class { + const char *name; + const struct value_string *msgt_names; + const struct value_string *iei_names; + const uint16_t *mand_ies[256]; +}; + +struct xua_dialect { + const char *name; + uint16_t port; + uint16_t ppid; + int log_subsys; + const struct xua_msg_class *class[256]; +}; + +extern const struct xua_dialect xua_dialect_sua; +extern const struct xua_dialect xua_dialect_m3ua; extern int DXUA; @@ -66,3 +83,10 @@ uint32_t xua_msg_part_get_u32(struct xua_msg_part *part); uint32_t xua_msg_get_u32(struct xua_msg *xua, uint16_t iei); int xua_msg_add_sccp_addr(struct xua_msg *xua, uint16_t iei, const struct osmo_sccp_addr *addr); + +const char *xua_class_msg_name(const struct xua_msg_class *xmc, uint16_t msg_type); +const char *xua_class_iei_name(const struct xua_msg_class *xmc, uint16_t iei); +char *xua_hdr_dump(struct xua_msg *xua, const struct xua_dialect *dialect); +char *xua_msg_dump(struct xua_msg *xua, const struct xua_dialect *dialect); +int xua_dialect_check_all_mand_ies(const struct xua_dialect *dialect, struct xua_msg *xua); + diff --git a/src/xua_msg.c b/src/xua_msg.c index 71511a9..1084622 100644 --- a/src/xua_msg.c +++ b/src/xua_msg.c @@ -301,3 +301,109 @@ return rc; } + +const char *xua_class_msg_name(const struct xua_msg_class *xmc, uint16_t msg_type) +{ + static char class_buf[64]; + + if (xmc && xmc->msgt_names) + return get_value_string(xmc->msgt_names, msg_type); + else { + snprintf(class_buf, sizeof(class_buf), "Unknown 0x%04x", msg_type); + return class_buf; + } +} + +const char *xua_class_iei_name(const struct xua_msg_class *xmc, uint16_t iei) +{ + static char iei_buf[64]; + + if (xmc && xmc->iei_names) + return get_value_string(xmc->iei_names, iei); + else { + snprintf(iei_buf, sizeof(iei_buf), "Unknown 0x%04x", iei); + return iei_buf; + } +} + +char *xua_hdr_dump(struct xua_msg *xua, const struct xua_dialect *dialect) +{ + const struct xua_msg_class *xmc = NULL; + static char buf[128]; + + if (dialect) + xmc = dialect->class[xua->hdr.msg_class]; + if (!xmc) + snprintf(buf, sizeof(buf), "%u:%u", xua->hdr.msg_class, xua->hdr.msg_type); + else + snprintf(buf, sizeof(buf), "%s:%s", xmc->name, + xua_class_msg_name(xmc, xua->hdr.msg_type)); + return buf; +} + +int xua_dialect_check_all_mand_ies(const struct xua_dialect *dialect, struct xua_msg *xua) +{ + uint8_t msg_class = xua->hdr.msg_class; + uint8_t msg_type = xua->hdr.msg_type; + const struct xua_msg_class *xmc = dialect->class[msg_class]; + const uint16_t *ies; + uint16_t ie; + + /* unknown class? */ + if (!xmc) + return 1; + + ies = xmc->mand_ies[msg_type]; + /* no mandatory IEs? */ + if (!ies) + return 1; + + for (ie = *ies; ie; ie = *ies++) { + if (!xua_msg_find_tag(xua, ie)) { + LOGP(dialect->log_subsys, LOGL_ERROR, + "%s Message %s:%s should " + "contain IE %s, but doesn't\n", + dialect->name, xmc->name, + xua_class_msg_name(xmc, msg_type), + xua_class_iei_name(xmc, ie)); + return 0; + } + } + + return 1; +} + +static void append_to_buf(char *buf, bool *comma, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + if (!comma || *comma == true) { + strcat(buf, ","); + } else if (comma) + *comma = true; + vsprintf(buf+strlen(buf), fmt, ap); + va_end(ap); +} + +char *xua_msg_dump(struct xua_msg *xua, const struct xua_dialect *dialect) +{ + static char buf[1024]; + struct xua_msg_part *part; + const struct xua_msg_class *xmc = NULL; + + if (dialect) + xmc = dialect->class[xua->hdr.msg_class]; + + buf[0] = '\0'; + + append_to_buf(buf, NULL, "HDR=(%s,V=%u,LEN=%u)", + xua_hdr_dump(xua, dialect), + xua->hdr.version, xua->hdr.msg_length); + buf[0] = ' '; + llist_for_each_entry(part, &xua->headers, entry) + append_to_buf(buf, NULL, "\n\tPART(T=%s,L=%u,D=%s)", + xua_class_iei_name(xmc, part->tag), part->len, + osmo_hexdump_nospc(part->dat, part->len)); + return buf; +} -- To view, visit https://gerrit.osmocom.org/2197 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ib538aca295b7b50132bc814b2d7b56cbe5d65bfc Gerrit-PatchSet: 3 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:31:09 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:31:09 +0000 Subject: [PATCH] libosmo-sccp[master]: sccp_sap: Use zero-terminated string for GT digits in osmo_s... In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2198 to look at the new patch set (#3). sccp_sap: Use zero-terminated string for GT digits in osmo_sccp_addr This is more natural to most application code, so simply go for ASCII string with NUL-termination rather than an array with explicit length. Change-Id: I6312208cdfa83184be41157a473c96e9120c63db --- M include/osmocom/sigtran/sccp_sap.h 1 file changed, 1 insertion(+), 2 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/98/2198/3 diff --git a/include/osmocom/sigtran/sccp_sap.h b/include/osmocom/sigtran/sccp_sap.h index 0aa565a..e58e670 100644 --- a/include/osmocom/sigtran/sccp_sap.h +++ b/include/osmocom/sigtran/sccp_sap.h @@ -127,11 +127,10 @@ struct osmo_sccp_gt { uint8_t gti; - uint8_t nr_digits; uint8_t tt; uint32_t npi; uint32_t nai; - uint8_t digits[32]; + char digits[32]; }; struct osmo_sccp_addr { -- To view, visit https://gerrit.osmocom.org/2198 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I6312208cdfa83184be41157a473c96e9120c63db Gerrit-PatchSet: 3 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:31:09 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:31:09 +0000 Subject: [PATCH] libosmo-sccp[master]: sccp_sap: Add routing indication (RI) to osmo_sccp_addr In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2199 to look at the new patch set (#3). sccp_sap: Add routing indication (RI) to osmo_sccp_addr Change-Id: I4dd23150f4c588b6430c22fc0cb66635994ceea9 --- M include/osmocom/sigtran/sccp_sap.h 1 file changed, 1 insertion(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/99/2199/3 diff --git a/include/osmocom/sigtran/sccp_sap.h b/include/osmocom/sigtran/sccp_sap.h index e58e670..ec021c7 100644 --- a/include/osmocom/sigtran/sccp_sap.h +++ b/include/osmocom/sigtran/sccp_sap.h @@ -135,6 +135,7 @@ struct osmo_sccp_addr { uint32_t presence; + enum osmo_sccp_routing_ind ri; struct osmo_sccp_gt gt; uint32_t pc; uint32_t ssn; -- To view, visit https://gerrit.osmocom.org/2199 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I4dd23150f4c588b6430c22fc0cb66635994ceea9 Gerrit-PatchSet: 3 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:31:09 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:31:09 +0000 Subject: [PATCH] libosmo-sccp[master]: sccp_sap: Add support for N-NOTICE.indication In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2200 to look at the new patch set (#3). sccp_sap: Add support for N-NOTICE.indication Change-Id: I6656889b4333e9909cf1c60c24dfc754281547b4 --- M include/osmocom/sigtran/sccp_sap.h 1 file changed, 10 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/00/2200/3 diff --git a/include/osmocom/sigtran/sccp_sap.h b/include/osmocom/sigtran/sccp_sap.h index ec021c7..139567e 100644 --- a/include/osmocom/sigtran/sccp_sap.h +++ b/include/osmocom/sigtran/sccp_sap.h @@ -198,6 +198,15 @@ /* user data */ }; +/* OSMO_SCU_PRIM_N_NOTICE */ +struct osmo_scu_notice_param { + struct osmo_sccp_addr called_addr; + struct osmo_sccp_addr calling_addr; + uint32_t cause; + uint32_t importance; + /* user data */ +}; + struct osmo_scu_prim { struct osmo_prim_hdr oph; union { @@ -206,6 +215,7 @@ struct osmo_scu_disconn_param disconnect; struct osmo_scu_reset_param reset; struct osmo_scu_unitdata_param unitdata; + struct osmo_scu_notice_param notice; } u; }; -- To view, visit https://gerrit.osmocom.org/2200 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I6656889b4333e9909cf1c60c24dfc754281547b4 Gerrit-PatchSet: 3 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:31:09 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:31:09 +0000 Subject: [PATCH] libosmo-sccp[master]: xua_msg: Add support for encoding Global Title in osmo_sccp_... In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2201 to look at the new patch set (#3). xua_msg: Add support for encoding Global Title in osmo_sccp_addr Change-Id: I4668fd0fba2e1be1ec37e75eeee85ed476320d14 --- M include/osmocom/sigtran/xua_msg.h M src/xua_msg.c 2 files changed, 64 insertions(+), 3 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/01/2201/3 diff --git a/include/osmocom/sigtran/xua_msg.h b/include/osmocom/sigtran/xua_msg.h index 6e98409..18b9e49 100644 --- a/include/osmocom/sigtran/xua_msg.h +++ b/include/osmocom/sigtran/xua_msg.h @@ -25,6 +25,7 @@ struct msgb; struct osmo_sccp_addr; +struct osmo_sccp_gt; struct xua_msg { struct xua_common_hdr hdr; @@ -82,6 +83,7 @@ int xua_msg_add_u32(struct xua_msg *xua, uint16_t iei, uint32_t val); uint32_t xua_msg_part_get_u32(struct xua_msg_part *part); uint32_t xua_msg_get_u32(struct xua_msg *xua, uint16_t iei); +void xua_part_add_gt(struct msgb *msg, const struct osmo_sccp_gt *gt); int xua_msg_add_sccp_addr(struct xua_msg *xua, uint16_t iei, const struct osmo_sccp_addr *addr); const char *xua_class_msg_name(const struct xua_msg_class *xmc, uint16_t msg_type); diff --git a/src/xua_msg.c b/src/xua_msg.c index 1084622..0a31a96 100644 --- a/src/xua_msg.c +++ b/src/xua_msg.c @@ -1,5 +1,6 @@ /* Routines for generating and parsing messages */ /* (C) 2011 by Holger Hans Peter Freyther + * (C) 2016-2017 by Harald Welte * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by @@ -271,19 +272,77 @@ return xua_msg_part_get_u32(part); } +void xua_part_add_gt(struct msgb *msg, const struct osmo_sccp_gt *gt) +{ + uint16_t *len_ptr; + unsigned int num_digits = strlen(gt->digits); + unsigned int num_digit_bytes; + unsigned int i, j; + + /* Tag + Length */ + msgb_put_u16(msg, SUA_IEI_GT); + len_ptr = (uint16_t *) msgb_put(msg, sizeof(uint16_t)); + + /* first dword: padding + GT */ + msgb_put_u32(msg, gt->gti); + + /* second header dword */ + msgb_put_u8(msg, strlen(gt->digits)); + msgb_put_u8(msg, gt->tt); + msgb_put_u8(msg, gt->npi); + msgb_put_u8(msg, gt->nai); + + /* actual digits */ + num_digit_bytes = num_digits / 2; + if (num_digits & 1) + num_digit_bytes++; + for (i = 0, j = 0; i < num_digit_bytes; i++) { + uint8_t byte; + byte = osmo_char2bcd(gt->digits[j++]); + if (j < num_digits) { + byte |= osmo_char2bcd(gt->digits[j++]) << 4; + } + msgb_put_u8(msg, byte); + } + /* pad to 32bit */ + if (num_digit_bytes % 4) + msgb_put(msg, 4 - (num_digit_bytes % 4)); + *len_ptr = htons(msg->tail - (uint8_t *)len_ptr + 2); +} + int xua_msg_add_sccp_addr(struct xua_msg *xua, uint16_t iei, const struct osmo_sccp_addr *addr) { struct msgb *tmp = msgb_alloc(128, "SCCP Address"); + uint16_t addr_ind = 0; int rc; if (!tmp) return -ENOMEM; - msgb_put_u16(tmp, SUA_RI_SSN_PC); /* route on SSN + PC */ - msgb_put_u16(tmp, 7); /* always put all addresses on SCCP side */ + switch (addr->ri) { + case OSMO_SCCP_RI_GT: + msgb_put_u16(tmp, SUA_RI_GT); + break; + case OSMO_SCCP_RI_SSN_PC: + msgb_put_u16(tmp, SUA_RI_SSN_PC); + break; + case OSMO_SCCP_RI_SSN_IP: + msgb_put_u16(tmp, SUA_RI_SSN_IP); + break; + default: + return -EINVAL; + } + if (addr->presence & OSMO_SCCP_ADDR_T_SSN) + addr_ind |= 0x0001; + if (addr->presence & OSMO_SCCP_ADDR_T_PC) + addr_ind |= 0x0002; + if (addr->presence & OSMO_SCCP_ADDR_T_GT) + addr_ind |= 0x0004; + + msgb_put_u16(tmp, addr_ind); if (addr->presence & OSMO_SCCP_ADDR_T_GT) { - /* FIXME */ + xua_part_add_gt(tmp, &addr->gt); } if (addr->presence & OSMO_SCCP_ADDR_T_PC) { msgb_t16l16vp_put_u32(tmp, SUA_IEI_PC, addr->pc); -- To view, visit https://gerrit.osmocom.org/2201 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I4668fd0fba2e1be1ec37e75eeee85ed476320d14 Gerrit-PatchSet: 3 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:31:09 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:31:09 +0000 Subject: [PATCH] libosmo-sccp[master]: xua_msg: Add support for encoding IPv4 addr in osmo_sccp_addr In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2202 to look at the new patch set (#3). xua_msg: Add support for encoding IPv4 addr in osmo_sccp_addr Change-Id: I956f069ce4cea78cb0db0470265ca8365093c0e5 --- M src/xua_msg.c 1 file changed, 1 insertion(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/02/2202/3 diff --git a/src/xua_msg.c b/src/xua_msg.c index 0a31a96..a7f2e52 100644 --- a/src/xua_msg.c +++ b/src/xua_msg.c @@ -351,7 +351,7 @@ msgb_t16l16vp_put_u32(tmp, SUA_IEI_SSN, addr->ssn); } if (addr->presence & OSMO_SCCP_ADDR_T_IPv4) { - /* FIXME: IPv4 address */ + msgb_t16l16vp_put_u32(tmp, SUA_IEI_IPv4, ntohl(addr->ip.v4.s_addr)); } else if (addr->presence & OSMO_SCCP_ADDR_T_IPv6) { /* FIXME: IPv6 address */ } -- To view, visit https://gerrit.osmocom.org/2202 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I956f069ce4cea78cb0db0470265ca8365093c0e5 Gerrit-PatchSet: 3 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:31:09 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:31:09 +0000 Subject: [PATCH] libosmo-sccp[master]: Add mtp_sap.h file with definitions for MTP-USER SAP In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2203 to look at the new patch set (#3). Add mtp_sap.h file with definitions for MTP-USER SAP The ITU-T Q.70x series describe a MTP-USER SAP, which we define here for use with osmocom primitives. Change-Id: Id1f8892e5dee877e2ffbeb3925753ab3da5a9420 --- M include/osmocom/sigtran/Makefile.am A include/osmocom/sigtran/mtp_sap.h 2 files changed, 69 insertions(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/03/2203/3 diff --git a/include/osmocom/sigtran/Makefile.am b/include/osmocom/sigtran/Makefile.am index ca7de0f..2f2912f 100644 --- a/include/osmocom/sigtran/Makefile.am +++ b/include/osmocom/sigtran/Makefile.am @@ -1,5 +1,5 @@ sigtran_HEADERS = xua_types.h xua_msg.h m2ua_types.h sccp_sap.h \ - sua.h sigtran_sap.h sccp_helpers.h + sua.h sigtran_sap.h sccp_helpers.h mtp_sap.h sigtrandir = $(includedir)/osmocom/sigtran diff --git a/include/osmocom/sigtran/mtp_sap.h b/include/osmocom/sigtran/mtp_sap.h new file mode 100644 index 0000000..120ae91 --- /dev/null +++ b/include/osmocom/sigtran/mtp_sap.h @@ -0,0 +1,68 @@ +#pragma once + +/* MTP User SAP description in accordance with ITU Q.701 */ + +/* (C) 2017 by Harald Welte + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include +#include +#include + +enum osmo_mtp_prim_type { + OSMO_MTP_PRIM_TRANSFER, + OSMO_MTP_PRIM_PAUSE, + OSMO_MTP_PRIM_RESUME, + OSMO_MTP_PRIM_STATUS, +}; + +#define MTP_SIO(service, net_ind) (((net_ind & 0xF) << 4) | (service & 0xF)) + +struct osmo_mtp_transfer_param { + uint32_t opc; + uint32_t dpc; + uint8_t sls; + uint8_t sio; +}; + +struct osmo_mtp_pause_param { + uint32_t affected_dpc; +}; + +struct osmo_mtp_resume_param { + uint32_t affected_dpc; +}; + +struct osmo_mtp_status_param { + uint32_t affected_dpc; + uint32_t cause; +}; + +struct osmo_mtp_prim { + struct osmo_prim_hdr oph; + union { + struct osmo_mtp_transfer_param transfer; + struct osmo_mtp_pause_param pause; + struct osmo_mtp_resume_param resume; + struct osmo_mtp_status_param status; + } u; +}; + +#define msgb_mtp_prim(msg) ((struct osmo_mtp_prim *)(msg)->l1h) + +char *osmo_mtp_prim_name(struct osmo_prim_hdr *oph); -- To view, visit https://gerrit.osmocom.org/2203 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Id1f8892e5dee877e2ffbeb3925753ab3da5a9420 Gerrit-PatchSet: 3 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:31:09 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:31:09 +0000 Subject: [PATCH] libosmo-sccp[master]: xua_msg: Add MTP routing label to 'struct xua_msg' In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2204 to look at the new patch set (#3). xua_msg: Add MTP routing label to 'struct xua_msg' Higher-layer protocols (particularly SCCP) require knowledge on the MTP-level routing label of a message. Let's add this to the common header of 'struct xua_msg' to communicate it across layer boundaries. Change-Id: I31a6388ac999e02ad779619adb54bbf4040672c9 --- M include/osmocom/sigtran/xua_msg.h 1 file changed, 2 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/04/2204/3 diff --git a/include/osmocom/sigtran/xua_msg.h b/include/osmocom/sigtran/xua_msg.h index 18b9e49..33eb1b0 100644 --- a/include/osmocom/sigtran/xua_msg.h +++ b/include/osmocom/sigtran/xua_msg.h @@ -20,6 +20,7 @@ #include "xua_types.h" #include +#include #define XUA_HDR(class, type) ((struct xua_common_hdr) { .spare = 0, .msg_class = (class), .msg_type = (type) }) @@ -29,6 +30,7 @@ struct xua_msg { struct xua_common_hdr hdr; + struct osmo_mtp_transfer_param mtp; struct llist_head headers; }; -- To view, visit https://gerrit.osmocom.org/2204 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I31a6388ac999e02ad779619adb54bbf4040672c9 Gerrit-PatchSet: 3 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:31:09 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:31:09 +0000 Subject: [PATCH] libosmo-sccp[master]: License headers: Should always have been GPLv2-or-later In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2205 to look at the new patch set (#3). License headers: Should always have been GPLv2-or-later libosmo-sigtran is GPLv2-or-later, there were some files that accidentially had an AGPLv3 license header, which was a copy+paste mistake at that time. Change-Id: I67dfd0ae6157afafd3873a3baaa4c6107c04ddfd --- M debian/copyright M include/osmocom/sigtran/protocol/sua.h M include/osmocom/sigtran/sccp_sap.h M include/osmocom/sigtran/xua_msg.h M src/sccp_helpers.c M src/sua.c M src/xua_msg.c 7 files changed, 25 insertions(+), 27 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/05/2205/3 diff --git a/debian/copyright b/debian/copyright index 78c9f12..436675c 100644 --- a/debian/copyright +++ b/debian/copyright @@ -8,9 +8,7 @@ 2010 Harald Welte License: GPL-2+ -Files: include/sigtran/xua_msg.h - src/xua_msg.c - tests/m2ua/m2ua_test.c +Files: tests/m2ua/m2ua_test.c Copyright: 2011 Holger Hans Peter Freyther License: AGPL-3+ diff --git a/include/osmocom/sigtran/protocol/sua.h b/include/osmocom/sigtran/protocol/sua.h index de67041..70c16ba 100644 --- a/include/osmocom/sigtran/protocol/sua.h +++ b/include/osmocom/sigtran/protocol/sua.h @@ -5,8 +5,8 @@ * All Rights Reserved * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation; either version 3 of the + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, @@ -14,7 +14,7 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU Affero General Public License + * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ diff --git a/include/osmocom/sigtran/sccp_sap.h b/include/osmocom/sigtran/sccp_sap.h index 139567e..0cc1531 100644 --- a/include/osmocom/sigtran/sccp_sap.h +++ b/include/osmocom/sigtran/sccp_sap.h @@ -2,20 +2,20 @@ /* SCCP User SAP description */ -/* (C) 2015 by Harald Welte +/* (C) 2015-2017 by Harald Welte * All Rights Reserved * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation; either version 3 of the License, or + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. + * GNU General Public License for more details. * - * You should have received a copy of the GNU Affero General Public License + * You should have received a copy of the GNU General Public License * along with this program. If not, see . * */ diff --git a/include/osmocom/sigtran/xua_msg.h b/include/osmocom/sigtran/xua_msg.h index 33eb1b0..60dd693 100644 --- a/include/osmocom/sigtran/xua_msg.h +++ b/include/osmocom/sigtran/xua_msg.h @@ -2,16 +2,16 @@ /* (C) 2011 by Holger Hans Peter Freyther * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation; either version 3 of the License, or + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. + * GNU General Public License for more details. * - * You should have received a copy of the GNU Affero General Public License + * You should have received a copy of the GNU General Public License * along with this program. If not, see . * */ diff --git a/src/sccp_helpers.c b/src/sccp_helpers.c index 1fc257c..6264424 100644 --- a/src/sccp_helpers.c +++ b/src/sccp_helpers.c @@ -5,16 +5,16 @@ * All Rights Reserved * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation; either version 3 of the License, or + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. + * GNU General Public License for more details. * - * You should have received a copy of the GNU Affero General Public License + * You should have received a copy of the GNU General Public License * along with this program. If not, see . * */ diff --git a/src/sua.c b/src/sua.c index cdc2cf0..145bf1a 100644 --- a/src/sua.c +++ b/src/sua.c @@ -4,16 +4,16 @@ * All Rights Reserved * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation; either version 3 of the License, or + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. + * GNU General Public License for more details. * - * You should have received a copy of the GNU Affero General Public License + * You should have received a copy of the GNU General Public License * along with this program. If not, see . * */ diff --git a/src/xua_msg.c b/src/xua_msg.c index a7f2e52..e094cb6 100644 --- a/src/xua_msg.c +++ b/src/xua_msg.c @@ -3,16 +3,16 @@ * (C) 2016-2017 by Harald Welte * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation; either version 3 of the License, or + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. + * GNU General Public License for more details. * - * You should have received a copy of the GNU Affero General Public License + * You should have received a copy of the GNU General Public License * along with this program. If not, see . * */ -- To view, visit https://gerrit.osmocom.org/2205 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I67dfd0ae6157afafd3873a3baaa4c6107c04ddfd Gerrit-PatchSet: 3 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:31:09 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:31:09 +0000 Subject: [PATCH] libosmo-sccp[master]: xua_msg: Add support for msg_event_maps In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2208 to look at the new patch set (#2). xua_msg: Add support for msg_event_maps msg_event_maps facilitate the mapping from a xUA message (class + type) to an integer event. This is useful when passing xUA messages to a osmo_fsm. Change-Id: Iee1c7fc2bf64219ebb71a0dbe6fd210749332413 --- M include/osmocom/sigtran/xua_msg.h M src/xua_msg.c 2 files changed, 30 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/08/2208/2 diff --git a/include/osmocom/sigtran/xua_msg.h b/include/osmocom/sigtran/xua_msg.h index 60dd693..320da6a 100644 --- a/include/osmocom/sigtran/xua_msg.h +++ b/include/osmocom/sigtran/xua_msg.h @@ -60,6 +60,12 @@ const struct xua_msg_class *class[256]; }; +struct xua_msg_event_map { + uint8_t msg_class; + uint8_t msg_type; + int event; +}; + extern const struct xua_dialect xua_dialect_sua; extern const struct xua_dialect xua_dialect_m3ua; @@ -94,3 +100,6 @@ char *xua_msg_dump(struct xua_msg *xua, const struct xua_dialect *dialect); int xua_dialect_check_all_mand_ies(const struct xua_dialect *dialect, struct xua_msg *xua); +int xua_msg_event_map(const struct xua_msg *xua, + const struct xua_msg_event_map *maps, + unsigned int num_maps); diff --git a/src/xua_msg.c b/src/xua_msg.c index e094cb6..27279ce 100644 --- a/src/xua_msg.c +++ b/src/xua_msg.c @@ -361,6 +361,27 @@ return rc; } +/*! \brief Map from a xua_msg (class+type) to an event + * \param[in] xua xUA message which is to be mapped + * \param[in] maps Table containing msg type+class -> event maps + * \[aram[in] num_maps number of entries in \ref maps + * \returns event >= 0; negative on error (no map found) */ +int xua_msg_event_map(const struct xua_msg *xua, + const struct xua_msg_event_map *maps, + unsigned int num_maps) +{ + int i; + + for (i= 0; i < num_maps; i++) { + const struct xua_msg_event_map *map = &maps[i]; + if (xua->hdr.msg_class == map->msg_class && + xua->hdr.msg_type == map->msg_type) { + return map->event; + } + } + return -1; +} + const char *xua_class_msg_name(const struct xua_msg_class *xmc, uint16_t msg_type) { static char class_buf[64]; -- To view, visit https://gerrit.osmocom.org/2208 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Iee1c7fc2bf64219ebb71a0dbe6fd210749332413 Gerrit-PatchSet: 2 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:31:09 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:31:09 +0000 Subject: [PATCH] libosmo-sccp[master]: Add new 'osmo_ss7' SS7 core code with M3UA, ASP/AS FSM, ... In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2209 to look at the new patch set (#3). Add new 'osmo_ss7' SS7 core code with M3UA, ASP/AS FSM, ... This is what aims to be a rather complete/proper implementation of the SIGTRAN + SS7 protocol suite. It has proper abstraction between the layers with primitives, finite state machines for things like the AS and ASP state machines, support for point code routing, etc. What's not implemented at this point: * re-integration of pre-existing SUA (pending) * actual MTP2 and physical E1/T1 link support * different trafic modes like broadcast/fail-over/load-balance Change-Id: I375eb80f01acc013094851d91d1d3333ebc12bc7 --- M configure.ac M include/osmocom/sigtran/Makefile.am A include/osmocom/sigtran/osmo_ss7.h A include/osmocom/sigtran/protocol/mtp.h M include/osmocom/sigtran/sigtran_sap.h M src/Makefile.am A src/m3ua.c A src/osmo_ss7.c A src/osmo_ss7_hmrt.c A src/osmo_ss7_vty.c A src/xua_as_fsm.c A src/xua_as_fsm.h A src/xua_asp_fsm.c A src/xua_asp_fsm.h A src/xua_internal.h M tests/Makefile.am A tests/ss7/Makefile.am A tests/ss7/ss7_test.c A tests/ss7/ss7_test.err A tests/ss7/ss7_test.ok M tests/testsuite.at 21 files changed, 4,991 insertions(+), 4 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/09/2209/3 diff --git a/configure.ac b/configure.ac index 4c3c937..116e168 100644 --- a/configure.ac +++ b/configure.ac @@ -29,6 +29,17 @@ PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 0.3.0) PKG_CHECK_MODULES(LIBOSMONETIF, libosmo-netif >= 0.0.6) +old_LIBS=$LIBS +AC_SEARCH_LIBS([sctp_send], [sctp], [ + AC_DEFINE(HAVE_LIBSCTP, 1, [Define 1 to enable SCTP support]) + AC_SUBST(HAVE_LIBSCTP, [1]) + if test -n "$ac_lib"; then + AC_SUBST(LIBSCTP_LIBS, [-l$ac_lib]) + fi + ], [ + AC_MSG_ERROR([sctp_send not found in searched libs])]) +LIBS=$old_LIBS + # The following test is taken from WebKit's webkit.m4 saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -fvisibility=hidden " @@ -56,5 +67,6 @@ tests/mtp/Makefile tests/m2ua/Makefile tests/sigtran/Makefile + tests/ss7/Makefile Makefile) diff --git a/include/osmocom/sigtran/Makefile.am b/include/osmocom/sigtran/Makefile.am index 2f2912f..ca7a304 100644 --- a/include/osmocom/sigtran/Makefile.am +++ b/include/osmocom/sigtran/Makefile.am @@ -1,7 +1,7 @@ sigtran_HEADERS = xua_types.h xua_msg.h m2ua_types.h sccp_sap.h \ - sua.h sigtran_sap.h sccp_helpers.h mtp_sap.h + sua.h sigtran_sap.h sccp_helpers.h mtp_sap.h osmo_ss7.h sigtrandir = $(includedir)/osmocom/sigtran -sigtran_prot_HEADERS = protocol/sua.h protocol/m3ua.h +sigtran_prot_HEADERS = protocol/sua.h protocol/m3ua.h protocol/mtp.h sigtran_protdir = $(includedir)/osmocom/sigtran/protocol diff --git a/include/osmocom/sigtran/osmo_ss7.h b/include/osmocom/sigtran/osmo_ss7.h new file mode 100644 index 0000000..5bbcd65 --- /dev/null +++ b/include/osmocom/sigtran/osmo_ss7.h @@ -0,0 +1,408 @@ +#pragma once + +#include +#include + +#include +#include +#include +#include +#include + +struct osmo_ss7_instance; +struct osmo_ss7_user; +struct osmo_sccp_instance; +struct osmo_mtp_prim; + +int osmo_ss7_init(void); + +bool osmo_ss7_pc_is_local(struct osmo_ss7_instance *inst, uint32_t pc); +int osmo_ss7_pointcode_parse(struct osmo_ss7_instance *inst, const char *str); +int osmo_ss7_pointcode_parse_mask_or_len(struct osmo_ss7_instance *inst, const char *in); +const char *osmo_ss7_pointcode_print(struct osmo_ss7_instance *inst, uint32_t pc); + +/*********************************************************************** + * SS7 Routing Tables + ***********************************************************************/ + +struct osmo_ss7_route_table { + /*! member in list of routing tables */ + struct llist_head list; + /*! \ref osmo_ss7_instance to which we belong */ + struct osmo_ss7_instance *inst; + /*! list of \ref osmo_ss7_route */ + struct llist_head routes; + + struct { + char *name; + char *description; + } cfg; +}; + +struct osmo_ss7_route_table * +osmo_ss7_route_table_find(struct osmo_ss7_instance *inst, const char *name); +struct osmo_ss7_route_table * +osmo_ss7_route_table_find_or_create(struct osmo_ss7_instance *inst, const char *name); +void osmo_ss7_route_table_destroy(struct osmo_ss7_route_table *rtbl); + +/*********************************************************************** + * SS7 Instances + ***********************************************************************/ + +struct osmo_ss7_instance { + /*! member of global list of instances */ + struct llist_head list; + /*! list of \ref osmo_ss7_linkset */ + struct llist_head linksets; + /*! list of \ref osmo_ss7_as */ + struct llist_head as_list; + /*! list of \ref osmo_ss7_asp */ + struct llist_head asp_list; + /*! list of \ref osmo_ss7_route_table */ + struct llist_head rtable_list; + /* array for faster lookup of user (indexed by service + * indicator) */ + const struct osmo_ss7_user *user[16]; + + struct osmo_ss7_route_table *rtable_system; + + struct osmo_sccp_instance *sccp; + + struct { + uint32_t id; + char *name; + char *description; + uint32_t primary_pc; + /* secondary PCs */ + /* capability PCs */ + uint8_t network_indicator; + struct { + char delimiter; + uint8_t component_len[3]; + } pc_fmt; + } cfg; +}; + +struct osmo_ss7_instance *osmo_ss7_instance_find(uint32_t id); +struct osmo_ss7_instance * +osmo_ss7_instance_find_or_create(void *ctx, uint32_t id); +void osmo_ss7_instance_destroy(struct osmo_ss7_instance *inst); +int osmo_ss7_instance_set_pc_fmt(struct osmo_ss7_instance *inst, + uint8_t c0, uint8_t c1, uint8_t c2); + +/*********************************************************************** + * MTP Users (Users of MTP, such as SCCP or ISUP) + ***********************************************************************/ + +struct osmo_ss7_user { + /* pointer back to SS7 instance */ + struct osmo_ss7_instance *inst; + /* name of the user */ + const char *name; + /* primitive call-back for incoming MTP primitives */ + osmo_prim_cb prim_cb; + /* private data */ + void *priv; +}; + +int osmo_ss7_user_register(struct osmo_ss7_instance *inst, uint8_t service_ind, + struct osmo_ss7_user *user); + +int osmo_ss7_user_unregister(struct osmo_ss7_instance *inst, uint8_t service_ind, + struct osmo_ss7_user *user); + +int osmo_ss7_mtp_to_user(struct osmo_ss7_instance *inst, struct osmo_mtp_prim *omp); + +/* SS7 User wants to issue MTP-TRANSFER.req */ +int osmo_ss7_user_mtp_xfer_req(struct osmo_ss7_instance *inst, + struct osmo_mtp_prim *omp); + +/*********************************************************************** + * SS7 Links + ***********************************************************************/ + +enum osmo_ss7_link_adm_state { + OSMO_SS7_LS_SHUTDOWN, + OSMO_SS7_LS_INHIBITED, + OSMO_SS7_LS_ENABLED, + _NUM_OSMO_SS7_LS +}; + +struct osmo_ss7_linkset; +struct osmo_ss7_link; + +struct osmo_ss7_link { + /*! \ref osmo_ss7_linkset to which we belong */ + struct osmo_ss7_linkset *linkset; + struct { + char *name; + char *description; + uint32_t id; + + enum osmo_ss7_link_adm_state adm_state; + } cfg; +}; + +void osmo_ss7_link_destroy(struct osmo_ss7_link *link); +struct osmo_ss7_link * +osmo_ss7_link_find_or_create(struct osmo_ss7_linkset *lset, uint32_t id); + +/*********************************************************************** + * SS7 Linksets + ***********************************************************************/ + +struct osmo_ss7_linkset { + struct llist_head list; + /*! \ref osmo_ss7_instance to which we belong */ + struct osmo_ss7_instance *inst; + /*! array of \ref osmo_ss7_link */ + struct osmo_ss7_link *links[16]; + + struct { + char *name; + char *description; + uint32_t adjacent_pc; + uint32_t local_pc; + } cfg; +}; + +void osmo_ss7_linkset_destroy(struct osmo_ss7_linkset *lset); +struct osmo_ss7_linkset * +osmo_ss7_linkset_find_by_name(struct osmo_ss7_instance *inst, const char *name); +struct osmo_ss7_linkset * +osmo_ss7_linkset_find_or_create(struct osmo_ss7_instance *inst, const char *name, uint32_t pc); + + +/*********************************************************************** + * SS7 Routes + ***********************************************************************/ + +struct osmo_ss7_route { + /*! member in \ref osmo_ss7_route_table.routes */ + struct llist_head list; + /*! \ref osmo_ss7_route_table to which we belong */ + struct osmo_ss7_route_table *rtable; + + struct { + /*! pointer to linkset (destination) of route */ + struct osmo_ss7_linkset *linkset; + /*! pointer to Application Server */ + struct osmo_ss7_as *as; + } dest; + + struct { + /* FIXME: presence? */ + uint32_t pc; + uint32_t mask; + /*! human-specified linkset name */ + char *linkset_name; + /*! lower priority is higher */ + uint32_t priority; + uint8_t qos_class; + } cfg; +}; + +struct osmo_ss7_route * +osmo_ss7_route_find_dpc(struct osmo_ss7_route_table *rtbl, uint32_t dpc); +struct osmo_ss7_route * +osmo_ss7_route_find_dpc_mask(struct osmo_ss7_route_table *rtbl, uint32_t dpc, + uint32_t mask); +struct osmo_ss7_route * +osmo_ss7_route_lookup(struct osmo_ss7_instance *inst, uint32_t dpc); +struct osmo_ss7_route * +osmo_ss7_route_create(struct osmo_ss7_route_table *rtbl, uint32_t dpc, + uint32_t mask, const char *linkset_name); +void osmo_ss7_route_destroy(struct osmo_ss7_route *rt); + + +/*********************************************************************** + * SS7 Application Servers + ***********************************************************************/ + +struct osmo_ss7_routing_key { + uint32_t context; + + uint32_t pc; + uint8_t si; + uint32_t ssn; + /* FIXME: more complex routing keys */ +}; + +enum osmo_ss7_as_traffic_mode { + OSMO_SS7_AS_TMOD_BCAST, + OSMO_SS7_AS_TMOD_LOADSHARE, + OSMO_SS7_AS_TMOD_ROUNDROBIN, + OSMO_SS7_AS_TMOD_OVERRIDE, + _NUM_OSMO_SS7_ASP_TMOD +}; + +extern struct value_string osmo_ss7_as_traffic_mode_vals[]; + +static inline const char * +osmo_ss7_as_traffic_mode_name(enum osmo_ss7_as_traffic_mode mode) +{ + return get_value_string(osmo_ss7_as_traffic_mode_vals, mode); +} + +enum osmo_ss7_asp_protocol { + OSMO_SS7_ASP_PROT_NONE, + OSMO_SS7_ASP_PROT_SUA, + OSMO_SS7_ASP_PROT_M3UA, + _NUM_OSMO_SS7_ASP_PROT +}; + +extern struct value_string osmo_ss7_asp_protocol_vals[]; + +static inline const char * +osmo_ss7_asp_protocol_name(enum osmo_ss7_asp_protocol mode) +{ + return get_value_string(osmo_ss7_asp_protocol_vals, mode); +} + +int osmo_ss7_asp_protocol_port(enum osmo_ss7_asp_protocol prot); + +struct osmo_ss7_as { + /*! entry in 'ref osmo_ss7_instance.as_list */ + struct llist_head list; + struct osmo_ss7_instance *inst; + + /*! AS FSM */ + struct osmo_fsm_inst *fi; + + struct { + char *name; + char *description; + enum osmo_ss7_asp_protocol proto; + struct osmo_ss7_routing_key routing_key; + enum osmo_ss7_as_traffic_mode mode; + uint32_t recovery_timeout_msec; + uint8_t qos_class; + + struct osmo_ss7_asp *asps[16]; + } cfg; +}; + +struct osmo_ss7_as * +osmo_ss7_as_find_by_name(struct osmo_ss7_instance *inst, const char *name); +struct osmo_ss7_as * +osmo_ss7_as_find_by_rctx(struct osmo_ss7_instance *inst, uint32_t rctx); +struct osmo_ss7_as * +osmo_ss7_as_find_or_create(struct osmo_ss7_instance *inst, const char *name, + enum osmo_ss7_asp_protocol proto); +int osmo_ss7_as_add_asp(struct osmo_ss7_as *as, const char *asp_name); +int osmo_ss7_as_del_asp(struct osmo_ss7_as *as, const char *asp_name); +void osmo_ss7_as_destroy(struct osmo_ss7_as *as); +bool osmo_ss7_as_has_asp(struct osmo_ss7_as *as, + struct osmo_ss7_asp *asp); + + +/*********************************************************************** + * SS7 Application Server Processes + ***********************************************************************/ + +struct osmo_ss7_asp_peer { + char *host; + uint16_t port; +}; + +enum osmo_ss7_asp_admin_state { + /*! no SCTP association with peer */ + OSMO_SS7_ASP_ADM_S_SHUTDOWN, + /*! SCP association, but reject ASP-ACTIVE */ + OSMO_SS7_ASP_ADM_S_BLOCKED, + /*! in normal operation */ + OSMO_SS7_ASP_ADM_S_ENABLED, +}; + +struct osmo_ss7_asp { + /*! entry in \ref osmo_ss7_instance.asp_list */ + struct llist_head list; + struct osmo_ss7_instance *inst; + + /*! ASP FSM */ + struct osmo_fsm_inst *fi; + + /*! \ref osmo_xua_server over which we were established */ + struct osmo_xua_server *xua_server; + + /*! osmo_stream / libosmo-netif handles */ + struct osmo_stream_cli *client; + struct osmo_stream_srv *server; + /*! pre-formatted human readable local/remote socket name */ + char *sock_name; + + /* ASP Identifier for ASP-UP + NTFY */ + uint32_t asp_id; + bool asp_id_present; + + struct { + char *name; + char *description; + enum osmo_ss7_asp_protocol proto; + enum osmo_ss7_asp_admin_state adm_state; + bool is_server; + + struct osmo_ss7_asp_peer local; + struct osmo_ss7_asp_peer remote; + uint8_t qos_class; + } cfg; +}; + +struct osmo_ss7_asp * +osmo_ss7_asp_find_by_name(struct osmo_ss7_instance *inst, const char *name); +struct osmo_ss7_asp * +osmo_ss7_asp_find_or_create(struct osmo_ss7_instance *inst, const char *name, + uint16_t remote_port, uint16_t local_port, + enum osmo_ss7_asp_protocol proto); +void osmo_ss7_asp_destroy(struct osmo_ss7_asp *asp); +int osmo_ss7_asp_send(struct osmo_ss7_asp *asp, struct msgb *msg); +int osmo_ss7_asp_restart(struct osmo_ss7_asp *asp); + +#define LOGPASP(asp, subsys, level, fmt, args ...) \ + LOGP(subsys, level, "asp-%s: " fmt, (asp)->cfg.name, ## args) + +/*********************************************************************** + * xUA Servers + ***********************************************************************/ + +struct osmo_xua_server { + struct llist_head list; + struct osmo_ss7_instance *inst; + + struct osmo_stream_srv_link *server; + + struct { + struct osmo_ss7_asp_peer local; + enum osmo_ss7_asp_protocol proto; + } cfg; +}; + +struct osmo_xua_server * +osmo_ss7_xua_server_find(struct osmo_ss7_instance *inst, enum osmo_ss7_asp_protocol proto, + uint16_t local_port); + +struct osmo_xua_server * +osmo_ss7_xua_server_create(struct osmo_ss7_instance *inst, enum osmo_ss7_asp_protocol proto, + uint16_t local_port, const char *local_host); + +int +osmo_ss7_xua_server_set_local_host(struct osmo_xua_server *xs, const char *local_host); + +void osmo_ss7_xua_server_destroy(struct osmo_xua_server *xs); + +struct osmo_sccp_instance * +osmo_sccp_simple_client(void *ctx, const char *name, uint32_t pc, + enum osmo_ss7_asp_protocol prot, + int local_port, int remote_port, const char *remote_ip); + +struct osmo_sccp_instance * +osmo_sccp_simple_server(void *ctx, uint32_t pc, + enum osmo_ss7_asp_protocol prot, int local_port, + const char *local_ip); + +struct osmo_sccp_instance * +osmo_sccp_simple_server_add_clnt(struct osmo_sccp_instance *inst, + enum osmo_ss7_asp_protocol prot, + const char *name, uint32_t pc, + int local_port, int remote_port, + const char *remote_ip); diff --git a/include/osmocom/sigtran/protocol/mtp.h b/include/osmocom/sigtran/protocol/mtp.h new file mode 100644 index 0000000..8b990c0 --- /dev/null +++ b/include/osmocom/sigtran/protocol/mtp.h @@ -0,0 +1,24 @@ +#pragma once + +#include + +/* Chapter 15.17.4 of Q.704 + RFC4666 3.4.5. */ +/* Section 5.1 of ETSI EG 201 693: MTP SI code allocations (for NI= 00) */ +enum mtp_si_ni00 { + MTP_SI_SNM = 0, + MTP_SI_STM = 1, + MTP_SI_SCCP = 3, + MTP_SI_TUP = 4, + MTP_SI_ISUP = 5, + MTP_SI_DUP = 6, /* call related */ + MTP_SI_DUP_FAC = 7, /* facility related */ + MTP_SI_TESTING = 8, + MTP_SI_B_ISUP = 9, + MTP_SI_SAT_ISUP = 10, + MTP_SI_SPEECH = 11, /* speech processing element */ + MTP_SI_AAL2_SIG = 12, + MTP_SI_BICC = 13, + MTP_SI_GCP = 14, +}; + +extern const struct value_string mtp_si_vals[]; diff --git a/include/osmocom/sigtran/sigtran_sap.h b/include/osmocom/sigtran/sigtran_sap.h index 544fc44..d29c37d 100644 --- a/include/osmocom/sigtran/sigtran_sap.h +++ b/include/osmocom/sigtran/sigtran_sap.h @@ -3,4 +3,39 @@ enum osmo_sigtran_sap { SCCP_SAP_USER = _SAP_SS7_BASE, + /* xUA Layer Manager */ + XUA_SAP_LM, + MTP_SAP_USER, }; + +enum osmo_xlm_prim_type { + OSMO_XLM_PRIM_M_SCTP_ESTABLISH, + OSMO_XLM_PRIM_M_SCTP_RELEASE, + OSMO_XLM_PRIM_M_SCTP_RESTART, + OSMO_XLM_PRIM_M_SCTP_STATUS, + OSMO_XLM_PRIM_M_ASP_STATUS, + OSMO_XLM_PRIM_M_AS_STATUS, + OSMO_XLM_PRIM_M_NOTIFY, + OSMO_XLM_PRIM_M_ERROR, + OSMO_XLM_PRIM_M_ASP_UP, + OSMO_XLM_PRIM_M_ASP_DOWN, + OSMO_XLM_PRIM_M_ASP_ACTIVE, + OSMO_XLM_PRIM_M_ASP_INACTIVE, + OSMO_XLM_PRIM_M_AS_ACTIVE, + OSMO_XLM_PRIM_M_AS_INACTIVE, + OSMO_XLM_PRIM_M_AS_DOWN, + /* optional as per spec, not implemented yet */ + OSMO_XLM_PRIM_M_RK_REG, + OSMO_XLM_PRIM_M_RK_DEREG, +}; + + +struct osmo_xlm_prim { + struct osmo_prim_hdr oph; + union { + } u; +}; + +#define msgb_xlm_prim(msg) ((struct osmo_xlm_prim *)(msg)->l1h) + +char *osmo_xlm_prim_name(struct osmo_prim_hdr *oph); diff --git a/src/Makefile.am b/src/Makefile.am index 26482a0..f7f4ccc 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,6 +1,8 @@ AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir) AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMONETIF_CFLAGS) +noinst_HEADERS = xua_asp_fsm.h xua_as_fsm.h xua_internal.h + # Legacy static libs sccpdir = $(libdir) @@ -24,6 +26,7 @@ # documentation before making any modification LIBVERSION=0:0:0 -libosmo_sigtran_la_SOURCES = sccp_sap.c sua.c xua_msg.c sccp_helpers.c +libosmo_sigtran_la_SOURCES = sccp_sap.c sua.c m3ua.c xua_msg.c sccp_helpers.c \ + osmo_ss7.c osmo_ss7_hmrt.c xua_asp_fsm.c xua_as_fsm.c libosmo_sigtran_la_LDFLAGS = -version-info $(LIBVERSION) -no-undefined -export-symbols-regex '^osmo_' libosmo_sigtran_la_LIBADD = $(LIBOSMOCORE_LIBS) $(LIBOSMONETIF_LIBS) $(LIBSCTP_LIBS) diff --git a/src/m3ua.c b/src/m3ua.c new file mode 100644 index 0000000..8ec82c5 --- /dev/null +++ b/src/m3ua.c @@ -0,0 +1,669 @@ +/* Minimal implementation of RFC 4666 - MTP3 User Adaptation Layer */ + +/* (C) 2015-2017 by Harald Welte + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include "xua_asp_fsm.h" +#include "xua_internal.h" + +#define M3UA_MSGB_SIZE 1500 + +/*********************************************************************** + * Protocol Definition (string tables, mandatory IE checking) + ***********************************************************************/ + +/* Section 3.8.1 */ +const struct value_string m3ua_err_names[] = { + { M3UA_ERR_INVALID_VERSION, "Invalid Version" }, + { M3UA_ERR_UNSUPP_MSG_CLASS, "Unsupported Message Class" }, + { M3UA_ERR_UNSUPP_MSG_TYPE, "Unsupported Message Type" }, + { M3UA_ERR_UNSUPP_TRAF_MOD_TYP, "Unsupported Traffic Mode Type" }, + { M3UA_ERR_UNEXPECTED_MSG, "Unexpected Message" }, + { M3UA_ERR_PROTOCOL_ERR, "Protocol Error" }, + { M3UA_ERR_INVAL_STREAM_ID, "Invalid Stream Identifier" }, + { M3UA_ERR_REFUSED_MGMT_BLOCKING, "Refused - Management Blocking" }, + { M3UA_ERR_ASP_ID_REQD, "ASP Identifier Required" }, + { M3UA_ERR_INVAL_ASP_ID, "Invalid ASP Identifier" }, + { M3UA_ERR_INVAL_PARAM_VAL, "Invalid Parameter Value" }, + { M3UA_ERR_PARAM_FIELD_ERR, "Parameter Field Error" }, + { M3UA_ERR_UNEXP_PARAM, "Unexpected Parameter" }, + { M3UA_ERR_DEST_STATUS_UNKN, "Destination Status Unknown" }, + { M3UA_ERR_INVAL_NET_APPEAR, "Invalid Network Appearance" }, + { M3UA_ERR_MISSING_PARAM, "Missing Parameter" }, + { M3UA_ERR_INVAL_ROUT_CTX, "Invalid Routing Context" }, + { M3UA_ERR_NO_CONFGD_AS_FOR_ASP,"No Configured AS for ASP" }, + { SUA_ERR_SUBSYS_STATUS_UNKN, "Subsystem Status Unknown" }, + { SUA_ERR_INVAL_LOADSH_LEVEL, "Invalid loadsharing level" }, + { 0, NULL } +}; + +const struct value_string m3ua_ntfy_type_names[] = { + { M3UA_NOTIFY_T_STATCHG, "State Change" }, + { M3UA_NOTIFY_T_OTHER, "Other" }, + { 0, NULL } +}; + +const struct value_string m3ua_ntfy_stchg_names[] = { + { M3UA_NOTIFY_I_RESERVED, "Reserved" }, + { M3UA_NOTIFY_I_AS_INACT, "AS Inactive" }, + { M3UA_NOTIFY_I_AS_ACT, "AS Active" }, + { M3UA_NOTIFY_I_AS_PEND, "AS Pending" }, + { 0, NULL } +}; + +const struct value_string m3ua_ntfy_other_names[] = { + { M3UA_NOTIFY_I_OT_INS_RES, "Insufficient ASP Resouces active in AS" }, + { M3UA_NOTIFY_I_OT_ALT_ASP_ACT, "Alternative ASP Active" }, + { M3UA_NOTIFY_I_OT_ASP_FAILURE, "ASP Failure" }, + { 0, NULL } +}; + +static const struct value_string m3ua_iei_names[] = { + { M3UA_IEI_INFO_STRING, "INFO String" }, + { M3UA_IEI_ROUTE_CTX, "Routing Context" }, + { M3UA_IEI_DIAG_INFO, "Diagnostic Info" }, + { M3UA_IEI_HEARDBT_DATA, "Heartbeat Data" }, + { M3UA_IEI_TRAF_MODE_TYP, "Traffic Mode Type" }, + { M3UA_IEI_ERR_CODE, "Error Code" }, + { M3UA_IEI_STATUS, "Status" }, + { M3UA_IEI_ASP_ID, "ASP Identifier" }, + { M3UA_IEI_AFFECTED_PC, "Affected Point Code" }, + { M3UA_IEI_CORR_ID, "Correlation Id" }, + + { M3UA_IEI_NET_APPEAR, "Network Appearance" }, + { M3UA_IEI_USER_CAUSE, "User/Cause" }, + { M3UA_IEI_CONG_IND, "Congestion Indication" }, + { M3UA_IEI_CONC_DEST, "Concerned Destination" }, + { M3UA_IEI_ROUT_KEY, "Routing Key" }, + { M3UA_IEI_REG_RESULT, "Registration Result" }, + { M3UA_IEI_DEREG_RESULT, "De-Registration Result" }, + { M3UA_IEI_LOC_RKEY_ID, "Local Routing-Key Identifier" }, + { M3UA_IEI_DEST_PC, "Destination Point Code" }, + { M3UA_IEI_SVC_IND, "Service Indicators" }, + { M3UA_IEI_ORIG_PC, "Originating Point Code List" }, + { M3UA_IEI_PROT_DATA, "Protocol Data" }, + { M3UA_IEI_REG_STATUS, "Registration Status" }, + { M3UA_IEI_DEREG_STATUS, "De-Registration Status" }, + { 0, NULL } +}; + +#define MAND_IES(msgt, ies) [msgt] = (ies) + +/* XFER */ +static const uint16_t data_mand_ies[] = { + M3UA_IEI_PROT_DATA, 0 +}; +static const struct value_string m3ua_xfer_msgt_names[] = { + { M3UA_XFER_DATA, "DATA" }, + { 0, NULL } +}; +static const struct xua_msg_class msg_class_xfer = { + .name = "XFER", + .msgt_names = m3ua_xfer_msgt_names, + .mand_ies = { + MAND_IES(M3UA_XFER_DATA, data_mand_ies), + }, +}; + +/* SNM */ +static const uint16_t duna_mand_ies[] = { + M3UA_IEI_AFFECTED_PC, 0 +}; +static const uint16_t dava_mand_ies[] = { + M3UA_IEI_AFFECTED_PC, 0 +}; +static const uint16_t daud_mand_ies[] = { + M3UA_IEI_AFFECTED_PC, 0 +}; +static const uint16_t scon_mand_ies[] = { + M3UA_IEI_AFFECTED_PC, 0 +}; +static const uint16_t dupu_mand_ies[] = { + M3UA_IEI_AFFECTED_PC, M3UA_IEI_USER_CAUSE, 0 +}; +static const uint16_t drst_mand_ies[] = { + M3UA_IEI_AFFECTED_PC, 0 +}; +static const struct value_string m3ua_snm_msgt_names[] = { + { M3UA_SNM_DUNA, "DUNA" }, + { M3UA_SNM_DAVA, "DAVA" }, + { M3UA_SNM_DAUD, "DAUD" }, + { M3UA_SNM_SCON, "SCON" }, + { M3UA_SNM_DUPU, "DUPU" }, + { M3UA_SNM_DRST, "DRST" }, + { 0, NULL } +}; +const struct xua_msg_class m3ua_msg_class_snm = { + .name = "SNM", + .msgt_names = m3ua_snm_msgt_names, + .mand_ies = { + MAND_IES(M3UA_SNM_DUNA, duna_mand_ies), + MAND_IES(M3UA_SNM_DAVA, dava_mand_ies), + MAND_IES(M3UA_SNM_DAUD, daud_mand_ies), + MAND_IES(M3UA_SNM_SCON, scon_mand_ies), + MAND_IES(M3UA_SNM_DUPU, dupu_mand_ies), + MAND_IES(M3UA_SNM_DRST, drst_mand_ies), + }, +}; + +/* ASPSM */ +static const struct value_string m3ua_aspsm_msgt_names[] = { + { M3UA_ASPSM_UP, "UP" }, + { M3UA_ASPSM_DOWN, "DOWN" }, + { M3UA_ASPSM_BEAT, "BEAT" }, + { M3UA_ASPSM_UP_ACK, "UP-ACK" }, + { M3UA_ASPSM_DOWN_ACK, "DOWN-ACK" }, + { M3UA_ASPSM_BEAT_ACK, "BEAT-ACK" }, + { 0, NULL } +}; +const struct xua_msg_class m3ua_msg_class_aspsm = { + .name = "ASPSM", + .msgt_names = m3ua_aspsm_msgt_names, +}; + +/* ASPTM */ +const struct value_string m3ua_asptm_msgt_names[] = { + { M3UA_ASPTM_ACTIVE, "ACTIVE" }, + { M3UA_ASPTM_INACTIVE, "INACTIVE" }, + { M3UA_ASPTM_ACTIVE_ACK,"ACTIVE-ACK" }, + { M3UA_ASPTM_INACTIVE_ACK, "INACTIVE-ACK" }, + { 0, NULL } +}; +const struct xua_msg_class m3ua_msg_class_asptm = { + .name = "ASPTM", + .msgt_names = m3ua_asptm_msgt_names, + .iei_names = m3ua_iei_names, +}; + +/* MGMT */ +static const uint16_t err_req_ies[] = { + M3UA_IEI_ERR_CODE, 0 +}; +static const uint16_t ntfy_req_ies[] = { + M3UA_IEI_STATUS, 0 +}; +static const struct value_string m3ua_mgmt_msgt_names[] = { + { M3UA_MGMT_ERR, "ERROR" }, + { M3UA_MGMT_NTFY, "NOTIFY" }, + { 0, NULL } +}; +const struct xua_msg_class m3ua_msg_class_mgmt = { + .name = "MGMT", + .msgt_names = m3ua_mgmt_msgt_names, + .iei_names = m3ua_iei_names, + .mand_ies = { + MAND_IES(M3UA_MGMT_ERR, err_req_ies), + MAND_IES(M3UA_MGMT_NTFY, ntfy_req_ies), + }, +}; + +/* RKM */ +static const uint16_t reg_req_ies[] = { + M3UA_IEI_ROUT_KEY, 0 +}; +static const uint16_t reg_rsp_ies[] = { + M3UA_IEI_REG_RESULT, 0 +}; +static const uint16_t dereg_req_ies[] = { + M3UA_IEI_ROUT_KEY, 0 +}; +static const uint16_t dereg_rsp_ies[] = { + M3UA_IEI_DEREG_RESULT, 0 +}; +static const struct value_string m3ua_rkm_msgt_names[] = { + { M3UA_RKM_REG_REQ, "REG-REQ" }, + { M3UA_RKM_REG_RSP, "REG-RESP" }, + { M3UA_RKM_DEREG_REQ, "DEREG-REQ" }, + { M3UA_RKM_DEREG_RSP, "DEREG-RESP" }, + { 0, NULL } +}; +const struct xua_msg_class m3ua_msg_class_rkm = { + .name = "RKM", + .msgt_names = m3ua_rkm_msgt_names, + .iei_names = m3ua_iei_names, + .mand_ies = { + MAND_IES(M3UA_RKM_REG_REQ, reg_req_ies), + MAND_IES(M3UA_RKM_REG_RSP, reg_rsp_ies), + MAND_IES(M3UA_RKM_DEREG_REQ, dereg_req_ies), + MAND_IES(M3UA_RKM_DEREG_RSP, dereg_rsp_ies), + }, +}; + +/* M3UA dialect of XUA, MGMT,XFER,SNM,ASPSM,ASPTM,RKM */ +const struct xua_dialect xua_dialect_m3ua = { + .name = "M3UA", + .ppid = M3UA_PPID, + .port = M3UA_PORT, + .log_subsys = DLM3UA, + .class = { + [M3UA_MSGC_MGMT] = &m3ua_msg_class_mgmt, + [M3UA_MSGC_XFER] = &msg_class_xfer, + [M3UA_MSGC_SNM] = &m3ua_msg_class_snm, + [M3UA_MSGC_ASPSM] = &m3ua_msg_class_aspsm, + [M3UA_MSGC_ASPTM] = &m3ua_msg_class_asptm, + [M3UA_MSGC_RKM] = &m3ua_msg_class_rkm, + }, +}; + +/* convert osmo_mtp_transfer_param to m3ua_data_hdr */ +void mtp_xfer_param_to_m3ua_dh(struct m3ua_data_hdr *mdh, + const struct osmo_mtp_transfer_param *param) +{ + mdh->opc = htonl(param->opc); + mdh->dpc = htonl(param->dpc); + mdh->si = param->sio & 0xF; + mdh->ni = (param->sio >> 6) & 0x3; + mdh->mp = (param->sio >> 4) & 0x3; + mdh->sls = param->sls; +} + +/* convert m3ua_data_hdr to osmo_mtp_transfer_param */ +void m3ua_dh_to_xfer_param(struct osmo_mtp_transfer_param *param, + const struct m3ua_data_hdr *mdh) +{ + param->opc = ntohl(mdh->opc); + param->dpc = ntohl(mdh->dpc); + param->sls = mdh->sls; + /* re-construct SIO */ + param->sio = (mdh->si & 0xF) | + (mdh->mp & 0x3 << 4) | + (mdh->ni & 0x3 << 6); +} + +#define M3UA_MSG_SIZE 2048 +#define M3UA_MSG_HEADROOM 512 + +struct msgb *m3ua_msgb_alloc(const char *name) +{ + if (!name) + name = "M3UA"; + return msgb_alloc_headroom(M3UA_MSG_SIZE+M3UA_MSG_HEADROOM, + M3UA_MSG_HEADROOM, name); +} + +/*********************************************************************** + * ERROR generation + ***********************************************************************/ + +static struct xua_msg *m3ua_gen_error(uint32_t err_code) +{ + struct xua_msg *xua = xua_msg_alloc(); + + xua->hdr = XUA_HDR(M3UA_MSGC_MGMT, M3UA_MGMT_ERR); + xua->hdr.version = M3UA_VERSION; + xua_msg_add_u32(xua, M3UA_IEI_ERR_CODE, err_code); + + return xua; +} + +static struct xua_msg *m3ua_gen_error_msg(uint32_t err_code, struct msgb *msg) +{ + struct xua_msg *xua = m3ua_gen_error(err_code); + unsigned int len_max_40 = msgb_length(msg); + + if (len_max_40 > 40) + len_max_40 = 40; + + xua_msg_add_data(xua, M3UA_IEI_DIAG_INFO, len_max_40, msgb_data(msg)); + + return xua; +} + +/*********************************************************************** + * NOTIFY generation + ***********************************************************************/ + +/* RFC4666 Ch. 3.8.2. Notify */ +struct xua_msg *m3ua_encode_notify(const struct m3ua_notify_params *npar) +{ + struct xua_msg *xua = xua_msg_alloc(); + uint32_t status; + + xua->hdr = XUA_HDR(M3UA_MSGC_MGMT, M3UA_MGMT_NTFY); + + status = M3UA_NOTIFY(htons(npar->status_type), htons(npar->status_info)); + /* cannot use xua_msg_add_u32() as it does endian conversion */ + xua_msg_add_data(xua, M3UA_IEI_STATUS, sizeof(status), (uint8_t *) &status); + + /* Conditional: ASP Identifier */ + if (npar->presence & NOTIFY_PAR_P_ASP_ID) + xua_msg_add_u32(xua, M3UA_IEI_ASP_ID, npar->asp_id); + + /* Optional Routing Context */ + if (npar->presence & NOTIFY_PAR_P_ROUTE_CTX) + xua_msg_add_u32(xua, M3UA_IEI_ROUTE_CTX, npar->route_ctx); + + /* Optional: Info String */ + if (npar->info_string) + xua_msg_add_data(xua, M3UA_IEI_INFO_STRING, + strlen(npar->info_string)+1, + (uint8_t *) npar->info_string); + + return xua; +} + +/* RFC4666 Ch. 3.8.2. Notify */ +int m3ua_decode_notify(struct m3ua_notify_params *npar, void *ctx, + const struct xua_msg *xua) +{ + struct xua_msg_part *info_ie, *aspid_ie, *status_ie, *rctx_ie; + uint32_t status; + + /* cannot use xua_msg_get_u32() as it does endian conversion */ + status_ie = xua_msg_find_tag(xua, M3UA_IEI_STATUS); + status = *(uint32_t *) status_ie->dat; + + aspid_ie = xua_msg_find_tag(xua, M3UA_IEI_ASP_ID); + rctx_ie = xua_msg_find_tag(xua, M3UA_IEI_ROUTE_CTX); + info_ie = xua_msg_find_tag(xua, M3UA_IEI_INFO_STRING); + + npar->presence = 0; + npar->status_type = ntohs(status & 0xffff); + npar->status_info = ntohs(status >> 16); + + if (aspid_ie) { + npar->asp_id = xua_msg_part_get_u32(aspid_ie); + npar->presence |= NOTIFY_PAR_P_ASP_ID; + } + + if (rctx_ie) { + npar->route_ctx = xua_msg_part_get_u32(rctx_ie); + npar->presence |= NOTIFY_PAR_P_ROUTE_CTX; + } + + if (info_ie) { + npar->info_string = talloc_size(ctx, info_ie->len); + memcpy(npar->info_string, info_ie->dat, info_ie->len); + } else + npar->info_string = NULL; + + return 0; +} + +/*********************************************************************** + * Transmitting M3UA messsages to SCTP + ***********************************************************************/ + +static int m3ua_tx_xua_asp(struct osmo_ss7_asp *asp, struct xua_msg *xua) +{ + struct msgb *msg = xua_to_msg(M3UA_VERSION, xua); + + OSMO_ASSERT(asp->cfg.proto == OSMO_SS7_ASP_PROT_M3UA); + + xua_msg_free(xua); + + if (!msg) { + LOGP(DLM3UA, LOGL_ERROR, "Error encoding M3UA Msg\n"); + return -1; + } + + msgb_sctp_ppid(msg) = M3UA_PPID; + return osmo_ss7_asp_send(asp, msg); +} + +/*! \brief Send a given xUA message via a given M3UA Application Server + * \param[in] as Application Server through which to send \ref xua + * \param[in] xua xUA message to be sent + * \return 0 on success; negative on error */ +int m3ua_tx_xua_as(struct osmo_ss7_as *as, struct xua_msg *xua) +{ + struct osmo_ss7_asp *asp; + unsigned int i; + + OSMO_ASSERT(as->cfg.proto == OSMO_SS7_ASP_PROT_M3UA); + + for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) { + asp = as->cfg.asps[i]; + if (!asp) + continue; + if (asp) + break; + } + if (!asp) { + LOGP(DLM3UA, LOGL_ERROR, "No ASP entroy in AS, dropping message\n"); + xua_msg_free(xua); + return -ENODEV; + } + + return m3ua_tx_xua_asp(asp, xua); +} + +/*********************************************************************** + * Receiving M3UA messsages from SCTP + ***********************************************************************/ + +/* obtain the destination point code from a M3UA message in XUA fmt * */ +struct m3ua_data_hdr *data_hdr_from_m3ua(struct xua_msg *xua) +{ + struct xua_msg_part *data_ie; + struct m3ua_data_hdr *data_hdr; + + if (xua->hdr.msg_class != M3UA_MSGC_XFER || + xua->hdr.msg_type != M3UA_XFER_DATA) + return NULL; + + data_ie = xua_msg_find_tag(xua, M3UA_IEI_PROT_DATA); + if (!data_ie) + return NULL; + data_hdr = (struct m3ua_data_hdr *) data_ie->dat; + + return data_hdr; +} + +static int m3ua_rx_xfer(struct osmo_ss7_asp *asp, struct xua_msg *xua) +{ + struct m3ua_data_hdr *dh; + + /* store the MTP-level information in the xua_msg for use by + * higher layer protocols */ + dh = data_hdr_from_m3ua(xua); + OSMO_ASSERT(dh); + m3ua_dh_to_xfer_param(&xua->mtp, dh); + + return m3ua_hmdc_rx_from_l2(asp->inst, xua); +} + +static int m3ua_rx_mgmt_err(struct osmo_ss7_asp *asp, struct xua_msg *xua) +{ + uint32_t err_code = xua_msg_get_u32(xua, M3UA_IEI_ERR_CODE); + + LOGPASP(asp, DLM3UA, LOGL_ERROR, "Received MGMT_ERR '%s': %s\n", + get_value_string(m3ua_err_names, err_code), + xua_msg_dump(xua, &xua_dialect_m3ua)); + + /* NEVER return != 0 here, as we cannot respont to an ERR + * message with another ERR! */ + return 0; +} + +static int m3ua_rx_mgmt_ntfy(struct osmo_ss7_asp *asp, struct xua_msg *xua) +{ + struct m3ua_notify_params ntfy; + const char *type_name, *info_name; + + m3ua_decode_notify(&ntfy, asp, xua); + + type_name = get_value_string(m3ua_ntfy_type_names, ntfy.status_type); + + switch (ntfy.status_type) { + case M3UA_NOTIFY_T_STATCHG: + info_name = get_value_string(m3ua_ntfy_stchg_names, + ntfy.status_info); + break; + case M3UA_NOTIFY_T_OTHER: + info_name = get_value_string(m3ua_ntfy_other_names, + ntfy.status_info); + break; + default: + info_name = "NULL"; + break; + } + LOGPASP(asp, DLM3UA, LOGL_NOTICE, "Received NOTIFY Type %s:%s (%s)\n", + type_name, info_name, + ntfy.info_string ? ntfy.info_string : ""); + + if (ntfy.info_string) + talloc_free(ntfy.info_string); + + /* TODO: should we report this soemwhere? */ + return 0; +} + +static int m3ua_rx_mgmt(struct osmo_ss7_asp *asp, struct xua_msg *xua) +{ + switch (xua->hdr.msg_type) { + case M3UA_MGMT_ERR: + return m3ua_rx_mgmt_err(asp, xua); + case M3UA_MGMT_NTFY: + return m3ua_rx_mgmt_ntfy(asp, xua); + default: + return M3UA_ERR_UNSUPP_MSG_TYPE; + } +} + +/* map from M3UA ASPSM/ASPTM to xua_asp_fsm event */ +static const struct xua_msg_event_map m3ua_aspxm_map[] = { + { M3UA_MSGC_ASPSM, M3UA_ASPSM_UP, XUA_ASP_E_ASPSM_ASPUP }, + { M3UA_MSGC_ASPSM, M3UA_ASPSM_DOWN, XUA_ASP_E_ASPSM_ASPDN }, + { M3UA_MSGC_ASPSM, M3UA_ASPSM_BEAT, XUA_ASP_E_ASPSM_BEAT }, + { M3UA_MSGC_ASPSM, M3UA_ASPSM_UP_ACK, XUA_ASP_E_ASPSM_ASPUP_ACK }, + { M3UA_MSGC_ASPSM, M3UA_ASPSM_DOWN_ACK, XUA_ASP_E_ASPSM_ASPDN_ACK }, + { M3UA_MSGC_ASPSM, M3UA_ASPSM_BEAT_ACK, XUA_ASP_E_ASPSM_BEAT_ACK }, + { M3UA_MSGC_ASPTM, M3UA_ASPTM_ACTIVE, XUA_ASP_E_ASPTM_ASPAC }, + { M3UA_MSGC_ASPTM, M3UA_ASPTM_INACTIVE, XUA_ASP_E_ASPTM_ASPIA }, + { M3UA_MSGC_ASPTM, M3UA_ASPTM_ACTIVE_ACK, XUA_ASP_E_ASPTM_ASPAC_ACK }, + { M3UA_MSGC_ASPTM, M3UA_ASPTM_INACTIVE_ACK, XUA_ASP_E_ASPTM_ASPIA_ACK }, +}; + + +static int m3ua_rx_asp(struct osmo_ss7_asp *asp, struct xua_msg *xua) +{ + int event; + + /* map from the M3UA message class and message type to the XUA + * ASP FSM event number */ + event = xua_msg_event_map(xua, m3ua_aspxm_map, + ARRAY_SIZE(m3ua_aspxm_map)); + if (event < 0) + return M3UA_ERR_UNSUPP_MSG_TYPE; + + /* deliver that event to the ASP FSM */ + osmo_fsm_inst_dispatch(asp->fi, event, xua); + + return 0; +} + +/*! \brief process M3UA message received from socket + * \param[in] asp Application Server Process receiving \ref msg + * \param[in] msg received message buffer + * \returns 0 on success; negative on error */ +int m3ua_rx_msg(struct osmo_ss7_asp *asp, struct msgb *msg) +{ + struct xua_msg *xua = NULL, *err = NULL; + int rc = 0; + + OSMO_ASSERT(asp->cfg.proto == OSMO_SS7_ASP_PROT_M3UA); + + /* caller owns msg memory, we shall neither free it here nor + * keep references beyond the executin of this function and its + * callees */ + + xua = xua_from_msg(M3UA_VERSION, msgb_length(msg), msgb_data(msg)); + if (!xua) { + struct xua_common_hdr *hdr = (struct xua_common_hdr *) msg->data; + + LOGPASP(asp, DLM3UA, LOGL_ERROR, "Unable to parse incoming " + "M3UA message\n"); + + if (hdr->version != M3UA_VERSION) + err = m3ua_gen_error_msg(M3UA_ERR_INVALID_VERSION, msg); + else + err = m3ua_gen_error_msg(M3UA_ERR_PARAM_FIELD_ERR, msg); + goto out; + } + + LOGPASP(asp, DLM3UA, LOGL_DEBUG, "Received M3UA Message (%s)\n", + xua_hdr_dump(xua, &xua_dialect_m3ua)); + + if (!xua_dialect_check_all_mand_ies(&xua_dialect_m3ua, xua)) { + err = m3ua_gen_error_msg(M3UA_ERR_MISSING_PARAM, msg); + goto out; + } + + /* TODO: check for SCTP Strema ID */ + /* TODO: check if any AS configured in ASP */ + /* TODO: check for valid routing context */ + + switch (xua->hdr.msg_class) { + case M3UA_MSGC_XFER: + rc = m3ua_rx_xfer(asp, xua); + break; + case M3UA_MSGC_ASPSM: + case M3UA_MSGC_ASPTM: + rc = m3ua_rx_asp(asp, xua); + break; + break; + case M3UA_MSGC_MGMT: + rc = m3ua_rx_mgmt(asp, xua); + break; + case M3UA_MSGC_SNM: + case M3UA_MSGC_RKM: + /* FIXME */ + LOGPASP(asp, DLM3UA, LOGL_NOTICE, "Received unsupported M3UA " + "Message Class %u\n", xua->hdr.msg_class); + err = m3ua_gen_error_msg(M3UA_ERR_UNSUPP_MSG_CLASS, msg); + break; + default: + LOGPASP(asp, DLM3UA, LOGL_NOTICE, "Received unknown M3UA " + "Message Class %u\n", xua->hdr.msg_class); + err = m3ua_gen_error_msg(M3UA_ERR_UNSUPP_MSG_CLASS, msg); + break; + } + + if (rc > 0) + err = m3ua_gen_error_msg(rc, msg); + +out: + if (err) + m3ua_tx_xua_asp(asp, err); + + xua_msg_free(xua); + + return rc; +} diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c new file mode 100644 index 0000000..74c54bb --- /dev/null +++ b/src/osmo_ss7.c @@ -0,0 +1,1490 @@ +/* Core SS7 Instance/Linkset/Link/AS/ASP Handling */ + +/* (C) 2015-2017 by Harald Welte + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "xua_internal.h" +#include "xua_asp_fsm.h" +#include "xua_as_fsm.h" + +#define ASP_MSGB_SIZE 1500 +#define MAX_PC_STR_LEN 32 + +static bool ss7_initialized = false; + +static LLIST_HEAD(ss7_instances); +static LLIST_HEAD(ss7_xua_servers); + +struct value_string osmo_ss7_as_traffic_mode_vals[] = { + { OSMO_SS7_AS_TMOD_BCAST, "broadcast" }, + { OSMO_SS7_AS_TMOD_LOADSHARE, "loadshare" }, + { OSMO_SS7_AS_TMOD_ROUNDROBIN, "round-robin" }, + { OSMO_SS7_AS_TMOD_OVERRIDE, "override" }, + { 0, NULL } +}; + +struct value_string osmo_ss7_asp_protocol_vals[] = { + { OSMO_SS7_ASP_PROT_NONE, "none" }, + { OSMO_SS7_ASP_PROT_SUA, "sua" }, + { OSMO_SS7_ASP_PROT_M3UA, "m3ua" }, + { 0, NULL } +}; + +#define LOGSS7(inst, level, fmt, args ...) \ + LOGP(DLSS7, level, "%u: " fmt, (inst)->cfg.id, ## args) + + +/*********************************************************************** + * SS7 Point Code Parsing / Printing + ***********************************************************************/ + +/* like strcat() but appends a single character */ +static int strnappendchar(char *str, char c, size_t n) +{ + unsigned int curlen = strlen(str); + + if (n < curlen + 2) + return -1; + + str[curlen] = c; + str[curlen+1] = '\0'; + + return curlen+1; +} + +/* generate a format string for formatting a point code. The result can + * e.g. be used with sscanf() or sprintf() */ +static const char *gen_pc_fmtstr(struct osmo_ss7_instance *inst, + unsigned int *num_comp_exp) +{ + static char buf[MAX_PC_STR_LEN]; + unsigned int num_comp = 0; + + buf[0] = '\0'; + strcat(buf, "%u"); + num_comp++; + + if (inst->cfg.pc_fmt.component_len[1] == 0) + goto out; + strnappendchar(buf, inst->cfg.pc_fmt.delimiter, sizeof(buf)); + strcat(buf, "%u"); + num_comp++; + + if (inst->cfg.pc_fmt.component_len[2] == 0) + goto out; + strnappendchar(buf, inst->cfg.pc_fmt.delimiter, sizeof(buf)); + strcat(buf, "%u"); + num_comp++; +out: + if (num_comp_exp) + *num_comp_exp = num_comp; + return buf; +} + +/* get number of components we expect for a point code, depending on the + * configuration of this ss7_instance */ +static unsigned int num_pc_comp_exp(struct osmo_ss7_instance *inst) +{ + unsigned int num_comp_exp = 1; + + if (inst->cfg.pc_fmt.component_len[1]) + num_comp_exp++; + if (inst->cfg.pc_fmt.component_len[2]) + num_comp_exp++; + + return num_comp_exp; +} + +/* get the total width (in bits) of the point-codes in this ss7_instance */ +static unsigned int get_pc_width(struct osmo_ss7_instance *inst) +{ + return inst->cfg.pc_fmt.component_len[0] + + inst->cfg.pc_fmt.component_len[1] + + inst->cfg.pc_fmt.component_len[2]; +} + +/* get the number of bits we must shift the given component of a point + * code in this ss7_instance */ +static unsigned int get_pc_comp_shift(struct osmo_ss7_instance *inst, + unsigned int comp_num) +{ + uint32_t pc_width = get_pc_width(inst); + switch (comp_num) { + case 0: + return pc_width - inst->cfg.pc_fmt.component_len[0]; + case 1: + return pc_width - inst->cfg.pc_fmt.component_len[0] - + inst->cfg.pc_fmt.component_len[1]; + case 2: + return 0; + default: + return -EINVAL; + } +} + +static uint32_t pc_comp_shift_and_mask(struct osmo_ss7_instance *inst, + unsigned int comp_num, uint32_t pc) +{ + unsigned int shift = get_pc_comp_shift(inst, comp_num); + uint32_t mask = (1 << inst->cfg.pc_fmt.component_len[comp_num]) - 1; + + return (pc >> shift) & mask; +} + +/* parse a point code according to the structure configured for this + * ss7_instance */ +int osmo_ss7_pointcode_parse(struct osmo_ss7_instance *inst, const char *str) +{ + unsigned int component[3]; + unsigned int num_comp_exp = num_pc_comp_exp(inst); + const char *fmtstr = gen_pc_fmtstr(inst, &num_comp_exp); + int i, rc; + + rc = sscanf(str, fmtstr, &component[0], &component[1], &component[2]); + /* ensure all components were parsed */ + if (rc != num_comp_exp) + goto err; + + /* check none of the component values exceeds what can be + * represented within its bit-width */ + for (i = 0; i < num_comp_exp; i++) { + if (component[i] >= (1 << inst->cfg.pc_fmt.component_len[i])) + goto err; + } + + /* shift them all together */ + rc = (component[0] << get_pc_comp_shift(inst, 0)); + if (num_comp_exp > 1) + rc |= (component[1] << get_pc_comp_shift(inst, 1)); + if (num_comp_exp > 2) + rc |= (component[2] << get_pc_comp_shift(inst, 2)); + + return rc; + +err: + LOGSS7(inst, LOGL_NOTICE, "Error parsing Pointcode '%s'\n", str); + return -EINVAL; +} + +/* print a pointcode according to the structure configured for this + * ss7_instance */ +const char *osmo_ss7_pointcode_print(struct osmo_ss7_instance *inst, uint32_t pc) +{ + static char buf[MAX_PC_STR_LEN]; + unsigned int num_comp_exp = num_pc_comp_exp(inst); + const char *fmtstr = gen_pc_fmtstr(inst, &num_comp_exp); + + OSMO_ASSERT(fmtstr); + snprintf(buf, sizeof(buf), fmtstr, + pc_comp_shift_and_mask(inst, 0, pc), + pc_comp_shift_and_mask(inst, 1, pc), + pc_comp_shift_and_mask(inst, 2, pc)); + + return buf; +} + +int osmo_ss7_pointcode_parse_mask_or_len(struct osmo_ss7_instance *inst, const char *in) +{ + unsigned int width = get_pc_width(inst); + + if (in[0] == '/') { + /* parse mask by length */ + int masklen = atoi(in+1); + if (masklen < 0 || masklen > 32) + return -EINVAL; + if (masklen == 0) + return 0; + return (0xFFFFFFFF << (width - masklen)) & ((1 << width)-1); + } else { + /* parse mask as point code */ + return osmo_ss7_pointcode_parse(inst, in); + } +} + +static const uint16_t prot2port[] = { + [OSMO_SS7_ASP_PROT_NONE] = 0, + [OSMO_SS7_ASP_PROT_SUA] = SUA_PORT, + [OSMO_SS7_ASP_PROT_M3UA] = M3UA_PORT, +}; + +int osmo_ss7_asp_protocol_port(enum osmo_ss7_asp_protocol prot) +{ + if (prot >= ARRAY_SIZE(prot2port)) + return -EINVAL; + else + return prot2port[prot]; +} + +/*********************************************************************** + * SS7 Instance + ***********************************************************************/ + +/*! \brief Find a SS7 Instance with given ID + * \param[in] id ID for which to search + * \returns \ref osmo_ss7_instance on success; NULL on error */ +struct osmo_ss7_instance * +osmo_ss7_instance_find(uint32_t id) +{ + OSMO_ASSERT(ss7_initialized); + + struct osmo_ss7_instance *inst; + llist_for_each_entry(inst, &ss7_instances, list) { + if (inst->cfg.id == id) + return inst; + } + return NULL; +} + +/*! \brief Find or create a SS7 Instance + * \param[in] ctx talloc allocation context to use for allocations + * \param[in] id ID of SS7 Instance + * \returns \ref osmo_ss7_instance on success; NULL on error */ +struct osmo_ss7_instance * +osmo_ss7_instance_find_or_create(void *ctx, uint32_t id) +{ + struct osmo_ss7_instance *inst; + + OSMO_ASSERT(ss7_initialized); + + inst = osmo_ss7_instance_find(id); + if (!inst) + inst = talloc_zero(ctx, struct osmo_ss7_instance); + if (!inst) + return NULL; + + inst->cfg.id = id; + LOGSS7(inst, LOGL_INFO, "Creating SS7 Instance\n"); + + INIT_LLIST_HEAD(&inst->linksets); + INIT_LLIST_HEAD(&inst->as_list); + INIT_LLIST_HEAD(&inst->asp_list); + INIT_LLIST_HEAD(&inst->rtable_list); + inst->rtable_system = osmo_ss7_route_table_find_or_create(inst, "system"); + + /* default point code structure + formatting */ + inst->cfg.pc_fmt.delimiter = '.'; + inst->cfg.pc_fmt.component_len[0] = 3; + inst->cfg.pc_fmt.component_len[1] = 8; + inst->cfg.pc_fmt.component_len[2] = 3; + + llist_add(&inst->list, &ss7_instances); + + return inst; +} + +/*! \brief Destroy a SS7 Instance + * \param[in] inst SS7 Instance to be destroyed */ +void osmo_ss7_instance_destroy(struct osmo_ss7_instance *inst) +{ + struct osmo_ss7_linkset *lset; + struct osmo_ss7_as *as; + struct osmo_ss7_asp *asp; + + OSMO_ASSERT(ss7_initialized); + LOGSS7(inst, LOGL_INFO, "Destroying SS7 Instance\n"); + + llist_for_each_entry(asp, &inst->asp_list, list) + osmo_ss7_asp_destroy(asp); + + llist_for_each_entry(as, &inst->as_list, list) + osmo_ss7_as_destroy(as); + + llist_for_each_entry(lset, &inst->linksets, list) + osmo_ss7_linkset_destroy(lset); + + llist_del(&inst->list); + talloc_free(inst); +} + +/*! \brief Set the point code format used in given SS7 instance */ +int osmo_ss7_instance_set_pc_fmt(struct osmo_ss7_instance *inst, + uint8_t c0, uint8_t c1, uint8_t c2) +{ + if (c0+c1+c2 > 32) + return -EINVAL; + + if (c0+c1+c2 > 14) + LOGSS7(inst, LOGL_NOTICE, "Point Code Format %u-%u-%u " + "is longer than 14 bits, odd?\n", c0, c1, c2); + + inst->cfg.pc_fmt.component_len[0] = c0; + inst->cfg.pc_fmt.component_len[1] = c1; + inst->cfg.pc_fmt.component_len[2] = c2; + + return 0; +} + +/*********************************************************************** + * MTP Users (Users of MTP, such as SCCP or ISUP) + ***********************************************************************/ + +/*! \brief Register a MTP user for a given service indicator + * \param[in] inst SS7 instance for which we register the user + * \param[in] service_ind Service (ISUP, SCCP, ...) + * \param[in] user SS7 user (including primitive call-back) + * \returns 0 on success; negative on error */ +int osmo_ss7_user_register(struct osmo_ss7_instance *inst, uint8_t service_ind, + struct osmo_ss7_user *user) +{ + if (service_ind >= ARRAY_SIZE(inst->user)) + return -EINVAL; + + if (inst->user[service_ind]) + return -EBUSY; + + DEBUGP(DLSS7, "registering user=%s for SI %u with priv %p\n", + user->name, service_ind, user->priv); + + user->inst = inst; + inst->user[service_ind] = user; + + return 0; +} + +/*! \brief Unregister a MTP user for a given service indicator + * \param[in] inst SS7 instance for which we register the user + * \param[in] service_ind Service (ISUP, SCCP, ...) + * \param[in] user (optional) SS7 user. If present, we will not + * unregister other users + * \returns 0 on success; negative on error */ +int osmo_ss7_user_unregister(struct osmo_ss7_instance *inst, uint8_t service_ind, + struct osmo_ss7_user *user) +{ + if (service_ind >= ARRAY_SIZE(inst->user)) + return -EINVAL; + + if (!inst->user[service_ind]) + return -ENODEV; + + if (user && (inst->user[service_ind] != user)) + return -EINVAL; + + user->inst = NULL; + inst->user[service_ind] = NULL; + + return 0; +} + +/* deliver to a local MTP user */ +int osmo_ss7_mtp_to_user(struct osmo_ss7_instance *inst, struct osmo_mtp_prim *omp) +{ + uint32_t service_ind; + const struct osmo_ss7_user *osu; + + if (omp->oph.sap != MTP_SAP_USER || + omp->oph.primitive != OSMO_MTP_PRIM_TRANSFER || + omp->oph.operation != PRIM_OP_INDICATION) { + LOGP(DLSS7, LOGL_ERROR, "Unsupported Primitive\n"); + return -EINVAL; + } + + service_ind = omp->u.transfer.sio & 0xF; + osu = inst->user[service_ind]; + + if (!osu) { + LOGP(DLSS7, LOGL_NOTICE, "No MTP-User for SI %u\n", service_ind); + return -ENODEV; + } + + DEBUGP(DLSS7, "delivering MTP-TRANSFER.ind to user %s, priv=%p\n", + osu->name, osu->priv); + return osu->prim_cb(&omp->oph, (void *) osu->priv); +} + +/*********************************************************************** + * SS7 Linkset + ***********************************************************************/ + +/*! \brief Destroy a SS7 Linkset + * \param[in] lset Linkset to be destroyed */ +void osmo_ss7_linkset_destroy(struct osmo_ss7_linkset *lset) +{ + unsigned int i; + + OSMO_ASSERT(ss7_initialized); + LOGSS7(lset->inst, LOGL_INFO, "Destroying Linkset %s\n", + lset->cfg.name); + + for (i = 0; i < ARRAY_SIZE(lset->links); i++) { + struct osmo_ss7_link *link = lset->links[i]; + if (!link) + continue; + osmo_ss7_link_destroy(link); + } + llist_del(&lset->list); + talloc_free(lset); +} + +/*! \brief Find SS7 Linkset by given name + * \param[in] inst SS7 Instance in which to look + * \param[in] name Name of SS7 Linkset + * \returns pointer to linkset on success; NULL on error */ +struct osmo_ss7_linkset * +osmo_ss7_linkset_find_by_name(struct osmo_ss7_instance *inst, const char *name) +{ + struct osmo_ss7_linkset *lset; + OSMO_ASSERT(ss7_initialized); + llist_for_each_entry(lset, &inst->linksets, list) { + if (!strcmp(name, lset->cfg.name)) + return lset; + } + return NULL; +} + +/*! \brief Find or allocate SS7 Linkset + * \param[in] inst SS7 Instance in which we operate + * \param[in] name Name of SS7 Linkset + * \param[in] pc Adjacent Pointcode + * \returns pointer to Linkset on success; NULL on error */ +struct osmo_ss7_linkset * +osmo_ss7_linkset_find_or_create(struct osmo_ss7_instance *inst, const char *name, uint32_t pc) +{ + struct osmo_ss7_linkset *lset; + + OSMO_ASSERT(ss7_initialized); + lset = osmo_ss7_linkset_find_by_name(inst, name); + if (lset && lset->cfg.adjacent_pc != pc) + return NULL; + + if (!lset) { + LOGSS7(inst, LOGL_INFO, "Creating Linkset %s\n", name); + lset = talloc_zero(inst, struct osmo_ss7_linkset); + lset->inst = inst; + lset->cfg.adjacent_pc = pc; + lset->cfg.name = talloc_strdup(lset, name); + llist_add_tail(&lset->list, &inst->linksets); + } + + return lset; +} + +/*********************************************************************** + * SS7 Link + ***********************************************************************/ + +/*! \brief Destryo SS7 Link + * \param[in] link SS7 Link to be destroyed */ +void osmo_ss7_link_destroy(struct osmo_ss7_link *link) +{ + struct osmo_ss7_linkset *lset = link->linkset; + + OSMO_ASSERT(ss7_initialized); + LOGSS7(lset->inst, LOGL_INFO, "Destroying Link %s:%u\n", + lset->cfg.name, link->cfg.id); + /* FIXME: do cleanup */ + lset->links[link->cfg.id] = NULL; + talloc_free(link); +} + +/*! \brief Find or create SS7 Link with given ID in given Linkset + * \param[in] lset SS7 Linkset on which we operate + * \param[in] id Link number within Linkset + * \returns pointer to SS7 Link on success; NULL on error */ +struct osmo_ss7_link * +osmo_ss7_link_find_or_create(struct osmo_ss7_linkset *lset, uint32_t id) +{ + struct osmo_ss7_link *link; + + OSMO_ASSERT(ss7_initialized); + if (id >= ARRAY_SIZE(lset->links)) + return NULL; + + if (lset->links[id]) { + link = lset->links[id]; + } else { + LOGSS7(lset->inst, LOGL_INFO, "Creating Link %s:%u\n", + lset->cfg.name, id); + link = talloc_zero(lset, struct osmo_ss7_link); + if (!link) + return NULL; + link->linkset = lset; + lset->links[id] = link; + link->cfg.id = id; + } + + return link; +} + + +/*********************************************************************** + * SS7 Route Tables + ***********************************************************************/ + +struct osmo_ss7_route_table * +osmo_ss7_route_table_find(struct osmo_ss7_instance *inst, const char *name) +{ + struct osmo_ss7_route_table *rtbl; + OSMO_ASSERT(ss7_initialized); + llist_for_each_entry(rtbl, &inst->rtable_list, list) { + if (!strcmp(rtbl->cfg.name, name)) + return rtbl; + } + return NULL; +} + +struct osmo_ss7_route_table * +osmo_ss7_route_table_find_or_create(struct osmo_ss7_instance *inst, const char *name) +{ + struct osmo_ss7_route_table *rtbl; + + OSMO_ASSERT(ss7_initialized); + rtbl = osmo_ss7_route_table_find(inst, name); + if (!rtbl) { + LOGSS7(inst, LOGL_INFO, "Creating Route Table %s\n", name); + rtbl = talloc_zero(inst, struct osmo_ss7_route_table); + rtbl->inst = inst; + rtbl->cfg.name = talloc_strdup(rtbl, name); + INIT_LLIST_HEAD(&rtbl->routes); + llist_add_tail(&rtbl->list, &inst->rtable_list); + } + return rtbl; +} + +void osmo_ss7_route_table_destroy(struct osmo_ss7_route_table *rtbl) +{ + llist_del(&rtbl->list); + /* routes are allocated as children of route table, will be + * automatically freed() */ + talloc_free(rtbl); +} + +/*********************************************************************** + * SS7 Routes + ***********************************************************************/ + +/*! \brief Find a SS7 route for given destination point code in given table */ +struct osmo_ss7_route * +osmo_ss7_route_find_dpc(struct osmo_ss7_route_table *rtbl, uint32_t dpc) +{ + struct osmo_ss7_route *rt; + + OSMO_ASSERT(ss7_initialized); + /* we assume the routes are sorted by mask length, i.e. more + * specific routes first, and less specific routes with shorter + * mask later */ + llist_for_each_entry(rt, &rtbl->routes, list) { + if ((dpc & rt->cfg.mask) == rt->cfg.pc) + return rt; + } + return NULL; +} + +/*! \brief Find a SS7 route for given destination point code + mask in given table */ +struct osmo_ss7_route * +osmo_ss7_route_find_dpc_mask(struct osmo_ss7_route_table *rtbl, uint32_t dpc, + uint32_t mask) +{ + struct osmo_ss7_route *rt; + + OSMO_ASSERT(ss7_initialized); + /* we assume the routes are sorted by mask length, i.e. more + * specific routes first, and less specific routes with shorter + * mask later */ + llist_for_each_entry(rt, &rtbl->routes, list) { + if (dpc == rt->cfg.pc && mask == rt->cfg.mask) + return rt; + } + return NULL; +} + +/*! \brief Find a SS7 route for given destination point code in given SS7 */ +struct osmo_ss7_route * +osmo_ss7_route_lookup(struct osmo_ss7_instance *inst, uint32_t dpc) +{ + OSMO_ASSERT(ss7_initialized); + return osmo_ss7_route_find_dpc(inst->rtable_system, dpc); +} + +/* insert the route in the ordered list of routes. The list is sorted by + * mask length, so that the more specific (longer mask) routes are + * first, while the less specific routes with shorter masks are last. + * Hence, the first matching route in a linear iteration is the most + * specific match. */ +static void route_insert_sorted(struct osmo_ss7_route_table *rtbl, + struct osmo_ss7_route *cmp) +{ + struct osmo_ss7_route *rt; + + llist_for_each_entry(rt, &rtbl->routes, list) { + if (rt->cfg.mask < cmp->cfg.mask) { + /* insert before the current entry */ + llist_add(&cmp->list, rt->list.prev); + return; + } + } + /* not added, i.e. no smaller mask length found: we are the + * smallest mask and thus should go last */ + llist_add_tail(&cmp->list, &rtbl->routes); +} + +/*! \brief Create a new route in the given routing table + * \param[in] rtbl Routing Table in which the route is to be created + * \param[in] pc Point Code of the destination of the route + * \param[in] mask Mask of the destination Point Code \ref pc + * \param[in] linkset_name string name of the linkset to be used + * \returns caller-allocated + initialized route, NULL on error + */ +struct osmo_ss7_route * +osmo_ss7_route_create(struct osmo_ss7_route_table *rtbl, uint32_t pc, + uint32_t mask, const char *linkset_name) +{ + struct osmo_ss7_route *rt; + struct osmo_ss7_linkset *lset; + struct osmo_ss7_as *as; + + OSMO_ASSERT(ss7_initialized); + lset = osmo_ss7_linkset_find_by_name(rtbl->inst, linkset_name); + if (!lset) { + as = osmo_ss7_as_find_by_name(rtbl->inst, linkset_name); + if (!as) + return NULL; + } + + rt = talloc_zero(rtbl, struct osmo_ss7_route); + if (!rt) + return NULL; + + rt->cfg.pc = pc; + rt->cfg.mask = mask; + rt->cfg.linkset_name = talloc_strdup(rt, linkset_name); + if (lset) + rt->dest.linkset = lset; + else + rt->dest.as = as; + rt->rtable = rtbl; + + route_insert_sorted(rtbl, rt); + + return rt; +} + +/*! \brief Destroy a given SS7 route */ +void osmo_ss7_route_destroy(struct osmo_ss7_route *rt) +{ + OSMO_ASSERT(ss7_initialized); + llist_del(&rt->list); + talloc_free(rt); +} + +/*********************************************************************** + * SS7 Application Server + ***********************************************************************/ + +/*! \brief Find Application Server by given name + * \param[in] inst SS7 Instance on which we operate + * \param[in] name Name of AS + * \returns pointer to Application Server on success; NULL otherwise */ +struct osmo_ss7_as * +osmo_ss7_as_find_by_name(struct osmo_ss7_instance *inst, const char *name) +{ + struct osmo_ss7_as *as; + + OSMO_ASSERT(ss7_initialized); + llist_for_each_entry(as, &inst->as_list, list) { + if (!strcmp(name, as->cfg.name)) + return as; + } + return NULL; +} + +/*! \brief Find Application Server by given routing context + * \param[in] inst SS7 Instance on which we operate + * \param[in] rctx Routing Context + * \returns pointer to Application Server on success; NULL otherwise */ +struct osmo_ss7_as * +osmo_ss7_as_find_by_rctx(struct osmo_ss7_instance *inst, uint32_t rctx) +{ + struct osmo_ss7_as *as; + + OSMO_ASSERT(ss7_initialized); + llist_for_each_entry(as, &inst->as_list, list) { + if (as->cfg.routing_key.context == rctx) + return as; + } + return NULL; +} + +/*! \brief Find or Create Application Server + * \param[in] inst SS7 Instance on which we operate + * \param[in] name Name of Application Server + * \param[in] proto Protocol of Application Server + * \returns pointer to Application Server on suuccess; NULL otherwise */ +struct osmo_ss7_as * +osmo_ss7_as_find_or_create(struct osmo_ss7_instance *inst, const char *name, + enum osmo_ss7_asp_protocol proto) +{ + struct osmo_ss7_as *as; + + OSMO_ASSERT(ss7_initialized); + as = osmo_ss7_as_find_by_name(inst, name); + + if (as && as->cfg.proto != proto) + return NULL; + + if (!as) { + LOGSS7(inst, LOGL_INFO, "Creating AS %s\n", name); + as = talloc_zero(inst, struct osmo_ss7_as); + if (!as) + return NULL; + as->inst = inst; + as->cfg.name = talloc_strdup(as, name); + as->cfg.proto = proto; + as->cfg.mode = OSMO_SS7_AS_TMOD_LOADSHARE; + as->cfg.recovery_timeout_msec = 2000; + as->fi = xua_as_fsm_start(as, LOGL_DEBUG); + llist_add_tail(&as->list, &inst->as_list); + } + + return as; +} + +/*! \brief Add given ASP to given AS + * \param[in] as Application Server to which \ref asp is added + * \param[in] asp Application Server Process to be added to \ref as + * \returns 0 on success; negative in case of error */ +int osmo_ss7_as_add_asp(struct osmo_ss7_as *as, const char *asp_name) +{ + struct osmo_ss7_asp *asp; + unsigned int i; + + OSMO_ASSERT(ss7_initialized); + asp = osmo_ss7_asp_find_by_name(as->inst, asp_name); + if (!asp) + return -ENODEV; + + LOGSS7(as->inst, LOGL_INFO, "Adding ASP %s to AS %s\n", + asp->cfg.name, as->cfg.name); + + if (osmo_ss7_as_has_asp(as, asp)) + return 0; + + for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) { + if (!as->cfg.asps[i]) { + as->cfg.asps[i] = asp; + return 0; + } + } + + return -ENOSPC; +} + +/*! \brief Delete given ASP from given AS + * \param[in] as Application Server from which \ref asp is deleted + * \param[in] asp Application Server Process to delete from \ref as + * \returns 0 on success; negative in case of error */ +int osmo_ss7_as_del_asp(struct osmo_ss7_as *as, const char *asp_name) +{ + struct osmo_ss7_asp *asp; + unsigned int i; + + OSMO_ASSERT(ss7_initialized); + asp = osmo_ss7_asp_find_by_name(as->inst, asp_name); + if (!asp) + return -ENODEV; + + LOGSS7(as->inst, LOGL_INFO, "Removing ASP %s from AS %s\n", + asp->cfg.name, as->cfg.name); + + for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) { + if (as->cfg.asps[i] == asp) { + as->cfg.asps[i] = NULL; + return 0; + } + } + + return -EINVAL; +} + +/*! \brief Destroy given Application Server + * \param[in] as Application Server to destroy */ +void osmo_ss7_as_destroy(struct osmo_ss7_as *as) +{ + OSMO_ASSERT(ss7_initialized); + LOGSS7(as->inst, LOGL_INFO, "Destroying AS %s\n", as->cfg.name); + + if (as->fi) + osmo_fsm_inst_term(as->fi, OSMO_FSM_TERM_REQUEST, NULL); + + as->inst = NULL; + llist_del(&as->list); + talloc_free(as); +} + +/*! \brief Determine if given AS contains ASP + * \param[in] as Application Server in which to look for \ref asp + * \param[in] asp Application Server Process to look for in \ref as + * \returns true in case \ref asp is part of \ref as; false otherwise */ +bool osmo_ss7_as_has_asp(struct osmo_ss7_as *as, + struct osmo_ss7_asp *asp) +{ + unsigned int i; + + OSMO_ASSERT(ss7_initialized); + for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) { + if (as->cfg.asps[i] == asp) + return true; + } + return false; +} + +/*********************************************************************** + * SS7 Application Server Process + ***********************************************************************/ + +struct osmo_ss7_asp * +osmo_ss7_asp_find_by_name(struct osmo_ss7_instance *inst, const char *name) +{ + struct osmo_ss7_asp *asp; + + OSMO_ASSERT(ss7_initialized); + llist_for_each_entry(asp, &inst->asp_list, list) { + if (!strcmp(name, asp->cfg.name)) + return asp; + } + return NULL; +} + +static uint16_t get_in_port(struct sockaddr *sa) +{ + switch (sa->sa_family) { + case AF_INET: + return (((struct sockaddr_in*)sa)->sin_port); + case AF_INET6: + return (((struct sockaddr_in6*)sa)->sin6_port); + default: + return 0; + } +} + +/*! \brief Find an ASP definition matching the local+remote IP/PORT of given fd + * \param[in] fd socket descriptor of given socket + * \returns SS7 ASP in case a matching one is found; NULL otherwise */ +static struct osmo_ss7_asp * +osmo_ss7_asp_find_by_socket_addr(int fd) +{ + struct osmo_ss7_instance *inst; + struct sockaddr sa_l, sa_r; + socklen_t sa_len_l = sizeof(sa_l); + socklen_t sa_len_r = sizeof(sa_r); + char hostbuf_l[64], hostbuf_r[64]; + uint16_t local_port, remote_port; + int rc; + + OSMO_ASSERT(ss7_initialized); + /* convert local and remote IP to string */ + rc = getsockname(fd, &sa_l, &sa_len_l); + if (rc < 0) + return NULL; + rc = getnameinfo(&sa_l, sa_len_l, hostbuf_l, sizeof(hostbuf_l), + NULL, 0, NI_NUMERICHOST); + if (rc < 0) + return NULL; + local_port = ntohs(get_in_port(&sa_l)); + + rc = getpeername(fd, &sa_r, &sa_len_r); + if (rc < 0) + return NULL; + rc = getnameinfo(&sa_r, sa_len_r, hostbuf_r, sizeof(hostbuf_r), + NULL, 0, NI_NUMERICHOST); + if (rc < 0) + return NULL; + remote_port = ntohs(get_in_port(&sa_r)); + + /* check all instances for any ASP definition matching the + * address combination of local/remote ip/port */ + llist_for_each_entry(inst, &ss7_instances, list) { + struct osmo_ss7_asp *asp; + llist_for_each_entry(asp, &inst->asp_list, list) { + if (asp->cfg.local.port == local_port && + (!asp->cfg.remote.port ||asp->cfg.remote.port == remote_port) && + (!asp->cfg.local.host || !strcmp(asp->cfg.local.host, hostbuf_l)) && + (!asp->cfg.remote.host || !strcmp(asp->cfg.remote.host, hostbuf_r))) + return asp; + } + } + + return NULL; +} + +struct osmo_ss7_asp * +osmo_ss7_asp_find_or_create(struct osmo_ss7_instance *inst, const char *name, + uint16_t remote_port, uint16_t local_port, + enum osmo_ss7_asp_protocol proto) +{ + struct osmo_ss7_asp *asp; + + OSMO_ASSERT(ss7_initialized); + asp = osmo_ss7_asp_find_by_name(inst, name); + + if (asp && (asp->cfg.remote.port != remote_port || + asp->cfg.local.port != local_port || + asp->cfg.proto != proto)) + return NULL; + + if (!asp) { + /* FIXME: check if local port has SCTP? */ + asp = talloc_zero(inst, struct osmo_ss7_asp); + asp->inst = inst; + asp->cfg.remote.port = remote_port; + asp->cfg.local.port = local_port; + asp->cfg.proto = proto; + asp->cfg.name = talloc_strdup(asp, name); + llist_add_tail(&asp->list, &inst->asp_list); + } + return asp; +} + +void osmo_ss7_asp_destroy(struct osmo_ss7_asp *asp) +{ + struct osmo_ss7_as *as; + + OSMO_ASSERT(ss7_initialized); + LOGSS7(asp->inst, LOGL_INFO, "Destroying ASP %s\n", asp->cfg.name); + + if (asp->server) + osmo_stream_srv_destroy(asp->server); + if (asp->client) + osmo_stream_cli_destroy(asp->client); + if (asp->fi) + osmo_fsm_inst_term(asp->fi, OSMO_FSM_TERM_REQUEST, NULL); + + /* unlink from all ASs we are part of */ + llist_for_each_entry(as, &asp->inst->as_list, list) { + unsigned int i; + for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) { + if (as->cfg.asps[i] == asp) { + as->cfg.asps[i] = NULL; + } + } + } + /* unlink from ss7_instance */ + asp->inst = NULL; + llist_del(&asp->list); + /* release memory */ + talloc_free(asp); +} + +static int xua_cli_read_cb(struct osmo_stream_cli *conn); +static int xua_cli_connect_cb(struct osmo_stream_cli *cli); + +int osmo_ss7_asp_restart(struct osmo_ss7_asp *asp) +{ + int rc; + enum xua_asp_role role; + + OSMO_ASSERT(ss7_initialized); + LOGSS7(asp->inst, LOGL_INFO, "Restarting ASP %s\n", asp->cfg.name); + + if (!asp->cfg.is_server) { + /* We are in client mode now */ + if (asp->server) { + /* if we previously were in server mode, + * destroy it */ + osmo_stream_srv_destroy(asp->server); + asp->server = NULL; + } + if (!asp->client) + asp->client = osmo_stream_cli_create(asp); + if (!asp->client) { + LOGSS7(asp->inst, LOGL_ERROR, "Unable to create stream" + " client for ASP %s\n", asp->cfg.name); + return -1; + } + osmo_stream_cli_set_addr(asp->client, asp->cfg.remote.host); + osmo_stream_cli_set_port(asp->client, asp->cfg.remote.port); + osmo_stream_cli_set_proto(asp->client, IPPROTO_SCTP); + osmo_stream_cli_set_reconnect_timeout(asp->client, 5); + osmo_stream_cli_set_connect_cb(asp->client, xua_cli_connect_cb); + osmo_stream_cli_set_read_cb(asp->client, xua_cli_read_cb); + osmo_stream_cli_set_data(asp->client, asp); + rc = osmo_stream_cli_open2(asp->client, 1); + if (rc < 0) { + LOGSS7(asp->inst, LOGL_ERROR, "Unable to open stream" + " client for ASP %s\n", asp->cfg.name); + } + /* TODO: make this configurable and not implicit */ + role = XUA_ASPFSM_ROLE_ASP; + } else { + /* We are in server mode now */ + if (asp->client) { + /* if we previously were in client mode, + * destroy it */ + osmo_stream_cli_destroy(asp->client); + asp->client = NULL; + } + /* FIXME: ensure we have a SCTP server */ + LOGSS7(asp->inst, LOGL_NOTICE, "ASP Restart for server " + "not implemented yet!\n"); + /* TODO: make this configurable and not implicit */ + role = XUA_ASPFSM_ROLE_SG; + } + + /* (re)start the ASP FSM */ + if (asp->fi) + osmo_fsm_inst_term(asp->fi, OSMO_FSM_TERM_REQUEST, NULL); + asp->fi = xua_asp_fsm_start(asp, role, LOGL_DEBUG); + + return 0; +} + +/*********************************************************************** + * libosmo-netif integration for SCTP stream server/client + ***********************************************************************/ + +static const struct value_string sctp_assoc_chg_vals[] = { + { SCTP_COMM_UP, "COMM_UP" }, + { SCTP_COMM_LOST, "COMM_LOST" }, + { SCTP_RESTART, "RESTART" }, + { SCTP_SHUTDOWN_COMP, "SHUTDOWN_COMP" }, + { SCTP_CANT_STR_ASSOC, "CANT_STR_ASSOC" }, + { 0, NULL } +}; + +static const struct value_string sctp_sn_type_vals[] = { + { SCTP_ASSOC_CHANGE, "ASSOC_CHANGE" }, + { SCTP_PEER_ADDR_CHANGE, "PEER_ADDR_CHANGE" }, + { SCTP_SHUTDOWN_EVENT, "SHUTDOWN_EVENT" }, + { SCTP_SEND_FAILED, "SEND_FAILED" }, + { SCTP_REMOTE_ERROR, "REMOTE_ERROR" }, + { SCTP_PARTIAL_DELIVERY_EVENT, "PARTIAL_DELIVERY_EVENT" }, + { SCTP_ADAPTATION_INDICATION, "ADAPTATION_INDICATION" }, +#ifdef SCTP_AUTHENTICATION_INDICATION + { SCTP_AUTHENTICATION_INDICATION, "UTHENTICATION_INDICATION" }, +#endif +#ifdef SCTP_SENDER_DRY_EVENT + { SCTP_SENDER_DRY_EVENT, "SENDER_DRY_EVENT" }, +#endif + { 0, NULL } +}; + +static int get_logevel_by_sn_type(int sn_type) +{ + switch (sn_type) { + case SCTP_ADAPTATION_INDICATION: + case SCTP_PEER_ADDR_CHANGE: +#ifdef SCTP_AUTHENTICATION_INDICATION + case SCTP_AUTHENTICATION_INDICATION: +#endif +#ifdef SCTP_SENDER_DRY_EVENT + case SCTP_SENDER_DRY_EVENT: +#endif + return LOGL_INFO; + case SCTP_ASSOC_CHANGE: + return LOGL_NOTICE; + case SCTP_SHUTDOWN_EVENT: + case SCTP_PARTIAL_DELIVERY_EVENT: + return LOGL_NOTICE; + case SCTP_SEND_FAILED: + case SCTP_REMOTE_ERROR: + return LOGL_ERROR; + default: + return LOGL_NOTICE; + } +} + +static void log_sctp_notification(struct osmo_ss7_asp *asp, const char *pfx, + union sctp_notification *notif) +{ + int log_level; + + LOGPASP(asp, DLSS7, LOGL_INFO, "%s SCTP NOTIFICATION %u flags=0x%0x\n", + pfx, notif->sn_header.sn_type, + notif->sn_header.sn_flags); + + log_level = get_logevel_by_sn_type(notif->sn_header.sn_type); + + switch (notif->sn_header.sn_type) { + case SCTP_ASSOC_CHANGE: + LOGPASP(asp, DLSS7, log_level, "%s SCTP_ASSOC_CHANGE: %s\n", + pfx, get_value_string(sctp_assoc_chg_vals, + notif->sn_assoc_change.sac_state)); + break; + default: + LOGPASP(asp, DLSS7, log_level, "%s %s\n", + pfx, get_value_string(sctp_sn_type_vals, + notif->sn_header.sn_type)); + break; + } +} + +/* netif code tells us we can read something from the socket */ +static int xua_srv_conn_cb(struct osmo_stream_srv *conn) +{ + struct osmo_fd *ofd = osmo_stream_srv_get_ofd(conn); + struct osmo_ss7_asp *asp = osmo_stream_srv_get_data(conn); + struct msgb *msg = msgb_alloc(ASP_MSGB_SIZE, "xUA Server Rx"); + struct sctp_sndrcvinfo sinfo; + unsigned int ppid; + int flags = 0; + int rc; + + if (!msg) + return -ENOMEM; + + /* read xUA message from socket and process it */ + rc = sctp_recvmsg(ofd->fd, msgb_data(msg), msgb_tailroom(msg), + NULL, NULL, &sinfo, &flags); + LOGPASP(asp, DLSS7, LOGL_DEBUG, "%s(): sctp_recvmsg() returned %d\n", + __func__, rc); + if (rc < 0) { + osmo_stream_srv_destroy(conn); + goto out; + } else if (rc == 0) { + osmo_stream_srv_destroy(conn); + goto out; + } else { + msgb_put(msg, rc); + } + + if (flags & MSG_NOTIFICATION) { + union sctp_notification *notif = (union sctp_notification *) msgb_data(msg); + + log_sctp_notification(asp, "xUA SRV", notif); + + switch (notif->sn_header.sn_type) { + case SCTP_SHUTDOWN_EVENT: + osmo_stream_srv_destroy(conn); + osmo_fsm_inst_dispatch(asp->fi, XUA_ASP_E_SCTP_COMM_DOWN_IND, asp); + break; + default: + break; + } + rc = 0; + goto out; + } + + ppid = ntohl(sinfo.sinfo_ppid); + msgb_sctp_ppid(msg) = ppid; + msgb_sctp_stream(msg) = ntohl(sinfo.sinfo_stream); + msg->dst = asp; + + if (ppid == M3UA_PPID && asp->cfg.proto == OSMO_SS7_ASP_PROT_M3UA) + rc = m3ua_rx_msg(asp, msg); + else { + LOGPASP(asp, DLSS7, LOGL_NOTICE, "SCTP chunk for unknown PPID %u " + "received\n", ppid); + rc = 0; + } + +out: + msgb_free(msg); + return rc; +} + +/* client has established SCTP connection to server */ +static int xua_cli_connect_cb(struct osmo_stream_cli *cli) +{ + struct osmo_fd *ofd = osmo_stream_cli_get_ofd(cli); + struct osmo_ss7_asp *asp = osmo_stream_cli_get_data(cli); + + /* update the socket name */ + osmo_talloc_replace_string(asp, &asp->sock_name, osmo_sock_get_name(asp, ofd->fd)); + + LOGPASP(asp, DLSS7, LOGL_INFO, "Client connected %s\n", asp->sock_name); + + /* Notify the ASP FSM that the connection has just been + * established */ + osmo_fsm_inst_dispatch(asp->fi, XUA_ASP_E_M_ASP_UP_REQ, NULL); + + return 0; +} + +static int xua_cli_read_cb(struct osmo_stream_cli *conn) +{ + struct osmo_fd *ofd = osmo_stream_cli_get_ofd(conn); + struct osmo_ss7_asp *asp = osmo_stream_cli_get_data(conn); + struct msgb *msg = msgb_alloc(ASP_MSGB_SIZE, "xUA Client Rx"); + struct sctp_sndrcvinfo sinfo; + unsigned int ppid; + int flags = 0; + int rc; + + if (!msg) + return -ENOMEM; + + /* read xUA message from socket and process it */ + rc = sctp_recvmsg(ofd->fd, msgb_data(msg), msgb_tailroom(msg), + NULL, NULL, &sinfo, &flags); + LOGPASP(asp, DLSS7, LOGL_DEBUG, "%s(): sctp_recvmsg() returned %d (flags=%d)\n", + __func__, rc, flags); + if (rc < 0) { + osmo_stream_cli_reconnect(conn); + goto out; + } else if (rc == 0) { + osmo_stream_cli_reconnect(conn); + } else { + msgb_put(msg, rc); + } + + if (flags & MSG_NOTIFICATION) { + union sctp_notification *notif = (union sctp_notification *) msgb_data(msg); + + log_sctp_notification(asp, "xUA CLNT", notif); + + switch (notif->sn_header.sn_type) { + case SCTP_SHUTDOWN_EVENT: + osmo_fsm_inst_dispatch(asp->fi, XUA_ASP_E_SCTP_COMM_DOWN_IND, asp); + osmo_stream_cli_reconnect(conn); + break; + default: + break; + } + rc = 0; + goto out; + } + + if (rc == 0) + goto out; + + ppid = ntohl(sinfo.sinfo_ppid); + msgb_sctp_ppid(msg) = ppid; + msgb_sctp_stream(msg) = ntohl(sinfo.sinfo_stream); + msg->dst = asp; + + if (ppid == M3UA_PPID && asp->cfg.proto == OSMO_SS7_ASP_PROT_M3UA) + rc = m3ua_rx_msg(asp, msg); + else { + LOGPASP(asp, DLSS7, LOGL_NOTICE, "SCTP chunk for unknown PPID %u " + "received\n", ppid); + rc = 0; + } + +out: + msgb_free(msg); + return rc; +} + +static int xua_srv_conn_closed_cb(struct osmo_stream_srv *srv) +{ + struct osmo_ss7_asp *asp = osmo_stream_srv_get_data(srv); + + LOGP(DLSS7, LOGL_INFO, "%s: SCTP connection closed\n", + asp ? asp->cfg.name : "?"); + + /* FIXME: somehow notify ASP FSM and everyone else */ + + return 0; +} + + +/* server has accept()ed a new SCTP association, let's find the ASP for + * it (if any) */ +static int xua_accept_cb(struct osmo_stream_srv_link *link, int fd) +{ + struct osmo_xua_server *oxs = osmo_stream_srv_link_get_data(link); + struct osmo_stream_srv *srv; + struct osmo_ss7_asp *asp; + char *sock_name = osmo_sock_get_name(link, fd); + + LOGP(DLSS7, LOGL_INFO, "%s: New SCTP connection accepted\n", + sock_name); + + srv = osmo_stream_srv_create(oxs, link, fd, + xua_srv_conn_cb, + xua_srv_conn_closed_cb, NULL); + if (!srv) { + LOGP(DLSS7, LOGL_ERROR, "%s: Unable to create stream server " + "for SCTP connection\n", sock_name); + close(fd); + talloc_free(sock_name); + return -1; + } + + asp = osmo_ss7_asp_find_by_socket_addr(fd); + if (!asp) { + LOGP(DLSS7, LOGL_NOTICE, "%s: SCTP connection without matching " + "ASP definition, terminating\n", sock_name); + osmo_stream_srv_destroy(srv); + talloc_free(sock_name); + return -1; + } + LOGP(DLSS7, LOGL_INFO, "%s: matched connection to ASP %s\n", + sock_name, asp->cfg.name); + /* update the ASP reference back to the server over which the + * connection came in */ + asp->server = srv; + /* update the ASP socket name */ + if (asp->sock_name) + talloc_free(asp->sock_name); + asp->sock_name = talloc_reparent(link, asp, sock_name); + /* make sure the conn_cb() is called with the asp as private + * data */ + osmo_stream_srv_set_data(srv, asp); + + return 0; +} + +/*! \brief send a fully encoded msgb via a given ASP + * \param[in] asp Application Server Process through which to send + * \param[in] msg message buffer to transmit. Ownership transferred. + * \returns 0 on success; negative in case of error */ +int osmo_ss7_asp_send(struct osmo_ss7_asp *asp, struct msgb *msg) +{ + OSMO_ASSERT(ss7_initialized); + + switch (asp->cfg.proto) { + case OSMO_SS7_ASP_PROT_SUA: + msgb_sctp_ppid(msg) = SUA_PPID; + break; + case OSMO_SS7_ASP_PROT_M3UA: + msgb_sctp_ppid(msg) = M3UA_PPID; + break; + default: + OSMO_ASSERT(0); + } + + if (asp->cfg.is_server) + osmo_stream_srv_send(asp->server, msg); + else + osmo_stream_cli_send(asp->client, msg); + + return 0; +} + +/*********************************************************************** + * SS7 xUA Server + ***********************************************************************/ + +struct osmo_xua_server * +osmo_ss7_xua_server_find(struct osmo_ss7_instance *inst, enum osmo_ss7_asp_protocol proto, + uint16_t local_port) +{ + struct osmo_xua_server *xs; + + OSMO_ASSERT(ss7_initialized); + llist_for_each_entry(xs, &ss7_xua_servers, list) { + if (proto == xs->cfg.proto && + local_port == xs->cfg.local.port) + return xs; + } + return NULL; +} + +/*! \brief create a new xUA server listening to given ip/port + * \param[in] ctx talloc allocation context + * \param[in] proto protocol (xUA variant) to use + * \param[in] local_port local SCTP port to bind/listen to + * \param[in] local_host local IP address to bind/listen to (optional) + * \returns callee-allocated \ref osmo_xua_server in case of success + */ +struct osmo_xua_server * +osmo_ss7_xua_server_create(struct osmo_ss7_instance *inst, enum osmo_ss7_asp_protocol proto, + uint16_t local_port, const char *local_host) +{ + struct osmo_xua_server *oxs = talloc_zero(inst, struct osmo_xua_server); + int rc; + + OSMO_ASSERT(ss7_initialized); + if (!oxs) + return NULL; + + LOGP(DLSS7, LOGL_INFO, "Creating XUA Server %s:%u\n", + local_host, local_port); + + oxs->cfg.proto = proto; + oxs->cfg.local.port = local_port; + oxs->cfg.local.host = talloc_strdup(oxs, local_host); + + oxs->server = osmo_stream_srv_link_create(oxs); + osmo_stream_srv_link_set_data(oxs->server, oxs); + osmo_stream_srv_link_set_accept_cb(oxs->server, xua_accept_cb); + + osmo_stream_srv_link_set_addr(oxs->server, oxs->cfg.local.host); + osmo_stream_srv_link_set_port(oxs->server, oxs->cfg.local.port); + osmo_stream_srv_link_set_proto(oxs->server, IPPROTO_SCTP); + + rc = osmo_stream_srv_link_open(oxs->server); + if (rc < 0) { + osmo_stream_srv_link_destroy(oxs->server); + oxs->server = NULL; + talloc_free(oxs); + } + + oxs->inst = inst; + llist_add_tail(&oxs->list, &ss7_xua_servers); + + return oxs; +} + +int +osmo_ss7_xua_server_set_local_host(struct osmo_xua_server *xs, const char *local_host) +{ + OSMO_ASSERT(ss7_initialized); + if (xs->cfg.local.host) + talloc_free(xs->cfg.local.host); + xs->cfg.local.host = talloc_strdup(xs, local_host); + + osmo_stream_srv_link_set_addr(xs->server, xs->cfg.local.host); + + return 0; +} + +void osmo_ss7_xua_server_destroy(struct osmo_xua_server *xs) +{ + if (xs->server) { + osmo_stream_srv_link_close(xs->server); + osmo_stream_srv_link_destroy(xs->server); + } + /* FIXME: add asp_list to xua_server so we can iterate it here + * and close all connections established in relation with this + * server */ + llist_del(&xs->list); + talloc_free(xs); +} + +bool osmo_ss7_pc_is_local(struct osmo_ss7_instance *inst, uint32_t pc) +{ + OSMO_ASSERT(ss7_initialized); + if (pc == inst->cfg.primary_pc) + return true; + /* FIXME: Secondary and Capability Point Codes */ + return false; +} + +int osmo_ss7_init(void) +{ + if (ss7_initialized) + return 1; + osmo_fsm_register(&xua_as_fsm); + osmo_fsm_register(&xua_asp_fsm); + ss7_initialized = true; + return 0; +} diff --git a/src/osmo_ss7_hmrt.c b/src/osmo_ss7_hmrt.c new file mode 100644 index 0000000..bc2b8e5 --- /dev/null +++ b/src/osmo_ss7_hmrt.c @@ -0,0 +1,219 @@ +/*********************************************************************** + * MTP Level 3 - Signalling message handling (SMH) Figure 23/Q.704 + ***********************************************************************/ + +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include "xua_internal.h" + +/* convert from M3UA message to MTP-TRANSFER.ind osmo_mtp_prim */ +struct osmo_mtp_prim *m3ua_to_xfer_ind(struct xua_msg *xua) +{ + struct osmo_mtp_prim *prim; + struct osmo_mtp_transfer_param *param; + struct xua_msg_part *data_ie = xua_msg_find_tag(xua, M3UA_IEI_PROT_DATA); + struct m3ua_data_hdr *data_hdr; + struct msgb *upmsg = m3ua_msgb_alloc("M3UA MTP-TRANSFER.ind"); + + if (data_ie->len < sizeof(*data_hdr)) { + /* FIXME: ERROR message */ + msgb_free(upmsg); + return NULL; + } + data_hdr = (struct m3ua_data_hdr *) data_ie->dat; + + /* fill primitive */ + prim = (struct osmo_mtp_prim *) msgb_put(upmsg, sizeof(*prim)); + param = &prim->u.transfer; + osmo_prim_init(&prim->oph, MTP_SAP_USER, + OSMO_MTP_PRIM_TRANSFER, + PRIM_OP_INDICATION, upmsg); + + m3ua_dh_to_xfer_param(param, data_hdr); + /* copy data */ + upmsg->l2h = msgb_put(upmsg, data_ie->len - sizeof(*data_hdr)); + memcpy(upmsg->l2h, data_ie->dat+sizeof(*data_hdr), data_ie->len - sizeof(*data_hdr)); + + return prim; +} + +/* convert from MTP-TRANSFER.req to osmo_mtp_prim */ +static struct xua_msg *mtp_prim_to_m3ua(struct osmo_mtp_prim *prim) +{ + struct msgb *msg = prim->oph.msg; + struct xua_msg *xua = xua_msg_alloc(); + struct osmo_mtp_transfer_param *param = &prim->u.transfer; + struct xua_msg_part *data_part; + struct m3ua_data_hdr data_hdr; + + mtp_xfer_param_to_m3ua_dh(&data_hdr, param); + + xua->hdr = XUA_HDR(M3UA_MSGC_XFER, M3UA_XFER_DATA); + /* Network Appearance: Optional */ + /* Routing Context: Conditional */ + /* Protocol Data: Mandatory */ + data_part = talloc_zero(xua, struct xua_msg_part); + data_part->tag = M3UA_IEI_PROT_DATA; + data_part->len = sizeof(data_hdr) + msgb_l2len(msg); + data_part->dat = talloc_size(data_part, data_part->len); + memcpy(data_part->dat, &data_hdr, sizeof(data_hdr)); + memcpy(data_part->dat+sizeof(data_hdr), msgb_l2(msg), msgb_l2len(msg)); + llist_add_tail(&data_part->entry, &xua->headers); + /* Correlation Id: Optional */ + + return xua; +} + +/* delivery given XUA message to given SS7 user */ +static int deliver_to_mtp_user(const struct osmo_ss7_user *osu, + struct xua_msg *xua) +{ + struct osmo_mtp_prim *prim; + + /* Create MTP-TRANSFER.ind and feed to user */ + prim = m3ua_to_xfer_ind(xua); + prim->u.transfer = xua->mtp; + if (!prim) + return -1; + + return osu->prim_cb(&prim->oph, (void *) osu->priv); +} + +/* HMDC -> HMDT: Message for distribution; Figure 25/Q.704 */ +/* This means it is a message we received from remote/L2, and it is to + * be routed to a local user part */ +static int hmdt_message_for_distribution(struct osmo_ss7_instance *inst, struct xua_msg *xua) +{ + struct m3ua_data_hdr *mdh; + const struct osmo_ss7_user *osu; + uint32_t service_ind; + + switch (xua->hdr.msg_class) { + case M3UA_MSGC_XFER: + switch (xua->hdr.msg_type) { + case M3UA_XFER_DATA: + mdh = data_hdr_from_m3ua(xua); + service_ind = mdh->si & 0xf; + break; + default: + LOGP(DLSS7, LOGL_ERROR, "Unknown M3UA XFER Message " + "Type %u\n", xua->hdr.msg_type); + return -1; + } + break; + case M3UA_MSGC_SNM: + /* FIXME */ + /* FIXME: SI = Signalling Network Management -> SRM/SLM/STM */ + /* FIXME: SI = Signalling Network Testing and Maintenance -> SLTC */ + default: + /* Discard Message */ + LOGP(DLSS7, LOGL_ERROR, "Unknown M3UA Message Class %u\n", + xua->hdr.msg_class); + return -1; + } + + /* Check for local SSN registered for this DPC/SSN */ + osu = inst->user[service_ind]; + if (osu) { + return deliver_to_mtp_user(osu, xua); + } else { + LOGP(DLSS7, LOGL_NOTICE, "No MTP-User for SI %u\n", service_ind); + /* Discard Message */ + /* FIXME: User Part Unavailable HMDT -> HMRT */ + return -1; + } +} + +/* HMDC->HMRT Msg For Routing; Figure 26/Q.704 */ +/* local message was receive d from L4, SRM, SLM, STM or SLTC, or + * remote message received from L2 and HMDC determined msg for routing */ +static int hmrt_message_for_routing(struct osmo_ss7_instance *inst, + struct xua_msg *xua) +{ + uint32_t dpc = xua->mtp.dpc; + struct osmo_ss7_route *rt; + + /* find route for DPC */ + /* FIXME: unify with gen_mtp_transfer_req_xua() */ + rt = osmo_ss7_route_lookup(inst, dpc); + if (rt) { + /* FIXME: DPC SP restart? */ + /* FIXME: DPC Congested? */ + /* FIXME: Select link based on SLS */ + /* FIXME: Transmit over respective Link */ + if (rt->dest.as) { + struct osmo_ss7_as *as = rt->dest.as; + switch (as->cfg.proto) { + case OSMO_SS7_ASP_PROT_M3UA: + return m3ua_tx_xua_as(as,xua); + default: + LOGP(DLSS7, LOGL_ERROR, "MTP message " + "for ASP of unknown protocol%u\n", + as->cfg.proto); + break; + } + } else if (rt->dest.linkset) { + LOGP(DLSS7, LOGL_ERROR, "MTP-TRANSFER.req for linkset" + "%s unsupported\n",rt->dest.linkset->cfg.name); + } else + OSMO_ASSERT(0); + } else { + LOGP(DLSS7, LOGL_ERROR, "MTP-TRANSFER.req for DPC %u: " + "no route!\n", dpc); + /* DPC unknown HMRT -> MGMT */ + /* Message Received for inaccesible SP HMRT ->RTPC */ + /* Discard Message */ + } + return -1; +} + +/* HMDC: Received Message L2 -> L3; Figure 24/Q.704 */ +/* This means a message was received from L2 and we have to decide if it + * is for the local stack (HMDT) or for routng (HMRT) */ +int m3ua_hmdc_rx_from_l2(struct osmo_ss7_instance *inst, struct xua_msg *xua) +{ + uint32_t dpc = xua->mtp.dpc; + if (osmo_ss7_pc_is_local(inst, dpc)) { + return hmdt_message_for_distribution(inst, xua); + } else { + return hmrt_message_for_routing(inst, xua); + } +} + +/* MTP-User requests to send a MTP-TRANSFER.req via the stack */ +int osmo_ss7_user_mtp_xfer_req(struct osmo_ss7_instance *inst, + struct osmo_mtp_prim *omp) +{ + struct xua_msg *xua; + + OSMO_ASSERT(omp->oph.sap == MTP_SAP_USER); + + switch (OSMO_PRIM_HDR(&omp->oph)) { + case OSMO_PRIM(OSMO_MTP_PRIM_TRANSFER, PRIM_OP_REQUEST): + xua = mtp_prim_to_m3ua(omp); + xua->mtp = omp->u.transfer; + /* normally we would call hmrt_message_for_routing() + * here, if we were to follow the state diagrams of the + * ITU-T Q.70x specifications. However, what if a local + * MTP user sends a MTP-TRANSFER.req to a local SSN? + * This wouldn't work as per the spec, but I believe it + * is a very useful feature (aka "loopback device" in + * IPv4). So we call m3ua_hmdc_rx_from_l2() just like + * the MTP-TRANSFER had been received from L2. */ + return m3ua_hmdc_rx_from_l2(inst, xua); + default: + LOGP(DLSS7, LOGL_ERROR, "Ignoring unknown primitive %u:%u\n", + omp->oph.primitive, omp->oph.operation); + return -1; + } +} diff --git a/src/osmo_ss7_vty.c b/src/osmo_ss7_vty.c new file mode 100644 index 0000000..80cd4d0 --- /dev/null +++ b/src/osmo_ss7_vty.c @@ -0,0 +1,681 @@ +/* Core SS7 Instance/Linkset/Link/AS/ASP VTY Interface */ + +/* (C) 2015-2017 by Harald Welte + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include + +#define CS7_STR "ITU-T Signaling System 7\n" +#define PC_STR "Point Code\n" + +/*********************************************************************** + * Core CS7 Configuration + ***********************************************************************/ + +static const struct value_string ss7_network_indicator_vals[] = { + { 0, "international" }, + { 1, "spare" }, + { 2, "national" }, + { 3, "reserved" }, + { 0, NULL } +}; + +/* cs7 network-indicator */ +DEFUN(cs7_net_ind, cs7_net_ind_cmd, + "cs7 network-indicator (international | national | reserved | spare)", + CS7_STR "Configure the Network Indicator\n" + "International Network\n" + "National Network\n" + "Reserved Network\n" + "Spare Network\n") +{ + struct osmo_ss7_instance *inst = FIXME; + int ni = get_string_value(ss7_network_indicator_vals, argv[0]); + + inst->cfg.network_indicator = ni; + return CMD_SUCCESS; +} + +/* TODO: cs7 point-code format */ +DEFUN(cs7_pc_format, cs7_pc_format_cmd, + "cs7 point-code format <1-24> [<1-23> [<1-22>]]", + CS7_STR PC_STR "Configure Point Code Format\n" + "Length of first PC component\n" + "Length of second PC component\n" + "Length of third PC component\n") +{ + struct osmo_ss7_instance *inst = FIXME; + int argind = 0; + + inst->cfg.pc_fmt.component_len[0] = atoi(argv[argind++]); + + if (argc >= 2) + inst->cfg.pc_fmt.component_len[1] = atoi(argv[argind++]); + else + inst->cfg.pc_fmt.component_len[1] = 0; + + if (argc >= 3) + inst->cfg.pc_fmt.component_len[2] = atoi(argv[argind++]); + else + inst->cfg.pc_fmt.component_len[2] = 0; + + return CMD_SUCCESS; +} + +DEFUN(cs7_pc_format_def, cs7_pc_format_def_cmd, + "cs7 point-code format default", + CS7_STR PC_STR "Configure Point Code Format\n" + "Default Point Code Format (3.8.3)\n") +{ + struct osmo_ss7_instance *inst = FIXME; + inst->cfg.pc_fmt.component_len[0] = 3; + inst->cfg.pc_fmt.component_len[1] = 8; + inst->cfg.pc_fmt.component_len[2] = 3; + return CMD_SUCCESS; +} + + +/* cs7 point-code delimiter */ +DEFUN(cs7_pc_delimiter, cs7_pc_delimiter_cmd, + "cs7 point-code delimiter (default|dash)", + CS7_STR PC_STR "Configure Point Code Delimiter\n" + "Use dot as delimiter\n" + "User dash as delimiter\n") +{ + struct osmo_ss7_instance *inst = FIXME; + + if (!strcmp(argv[0], "dash")) + inst->cfg.pc_fmt.delimiter = '-'; + else + inst->cfg.pc_fmt.delimiter = '.'; + + return CMD_SUCCESS; +} + +DEFUN(cs7_point_code, cs7_point_code_cmd, + "cs7 point-code POINT_CODE", + CS7_STR "Configure the local Point Code\n" + "Point Code\n") +{ + struct osmo_ss7_instance *inst = FIXME; + uint32_t pc = osmo_ss7_pointcode_parse(inst, argv[0]); + + inst->cfg.primary_pc = pc; + return CMD_SUCCESS; +} +/* TODO: cs7 secondary-pc */ +/* TODO: cs7 capability-pc */ + + +/*********************************************************************** + * Routing Table Configuration + ***********************************************************************/ + +static struct cmd_node rtable_node = { + L_CS7_RTABLE_NODE, + "%s(config-cs7-rt)# ", + 1, +}; + +DEFUN(cs7_route_table, cs7_route_table_cmd, + "cs7 route-table system", + CS7_STR "Specify the name of the route table\n" + "Name of the route table\n") +{ + struct osmo_ss7_instance *inst = FIXME; + struct osmo_ss7_route_table *rtable; + + rtable = inst->rtable_system; + vty->node = L_CS7_RTABLE_NODE; + vty->index = rtable; + vty->index_sub = &rtable->cfg.description; + + return CMD_SUCCESS; +} + +DEFUN(cs7_rt_upd, cs7_rt_upd_cmd, + "update route POINT_CODE [MASK | LENGTH] linkset LS_NAME [priority PRIO] [qos-class (CLASS | default", + "Update the Route\n" + "Update the Route\n" + "Destination Point Code\n" + "Point Code Mask\n" + "Point Code Length\n" + "Specify Destination Linkset\n" + "Linkset Name\n" + "Specity Priority\n" + "Priority\n" + "Specify QoS Class\n" + "QoS Class\n" + "Default QoS Class\n") +{ + struct osmo_ss7_route_table *rtable = vty->index; + struct osmo_ss7_route *rt; + uint32_t dpc = osmo_ss7_pointcode_parse(rtable->inst, argv[0]); + uint32_t mask = osmo_ss7_pointcode_parse_mask_or_len(rtable->inst, argv[1]); + const char *ls_name = argv[2]; + unsigned int argind; + + rt = osmo_ss7_route_create(rtable, dpc, mask, ls_name); + if (!rt) + return CMD_WARNING; + + argind = 3; + if (argc > argind && !strcmp(argv[argind], "priority")) { + argind++; + rt->cfg.priority = atoi(argv[argind++]); + } + + if (argc > argind && !strcmp(argv[argind], "qos-class")) { + argind++; + rt->cfg.qos_class = atoi(argv[argind++]); + } + + return CMD_SUCCESS; +} + +DEFUN(cs7_rt_rem, cs7_rt_rem_cmd, + "remove route POINT_CODE [MASK | LENGTH]", + "Remove a Route\n" + "Remove a Route\n" + "Destination Point Code\n" + "Point Code Mask\n" + "Point Code Length\n") +{ + struct osmo_ss7_route_table *rtable = vty->index; + struct osmo_ss7_route *rt; + uint32_t dpc = osmo_ss7_pointcode_parse(rtable->inst, argv[0]); + uint32_t mask = osmo_ss7_pointcode_parse_mask_or_len(rtable->inst, argv[1]); + + rt = osmo_ss7_route_find_dpc_mask(rtable, dpc, mask); + if (!rt) + return CMD_WARNING; + + osmo_ss7_route_destroy(rt); + return CMD_SUCCESS; +} + +static int config_write_rtable(struct vty *vty) +{ + struct osmo_ss7_route_table *rtable = vty->index; + struct osmo_ss7_route *rt; + + vty_out(vty, "cs7 route-table %s%s", rtable->cfg.name, VTY_NEWLINE); + llist_for_each_entry(rt, &rtable->routes, list) { + vty_out(vty, " update route %s %s linkset %s", + osmo_ss7_pointcode_print(rtable->inst, rt->cfg.pc), + osmo_ss7_pointcode_print(rtable->inst, rt->cfg.mask), + rt->cfg.linkset_name); + if (rt->cfg.priority) + vty_out(vty, " priority %u", rt->cfg.priority); + if (rt->cfg.qos_class) + vty_out(vty, " qos-class %u", rt->cfg.qos_class); + vty_out(vty, "%s", VTY_NEWLINE); + } + return 0; +} + +/*********************************************************************** + * SUA Configuration + ***********************************************************************/ + +static struct cmd_node sua_node = { + L_CS7_SUA_NODE, + "%s(config-cs7-sua)# ", + 1, +}; + +DEFUN(cs7_sua, cs7_sua_cmd, + "cs7 sua <0-65534>", + CS7_STR + "Configure/Enable SUA\n" + "SCTP Port number for SUA\n") +{ + struct osmo_ss7_instance *inst = FIXME; + struct osmo_xua_server *xs; + uint16_t port = atoi(argv[0]); + + xs = osmo_ss7_xua_server_find(inst, OSMO_SS7_ASP_PROT_SUA, port); + if (!xs) { + xs = osmo_ss7_xua_server_create(inst, OSMO_SS7_ASP_PROT_SUA, port, NULL); + if (!xs) + return CMD_SUCCESS; + } + + vty->node = L_CS7_SUA_NODE; + vty->index = xs; + return CMD_SUCCESS; +} + +DEFUN(sua_local_ip, sua_local_ip_cmd, + "local-ip A.B.C.D", + "Configure the Local IP Address for SUA\n" + "IP Address to use for SUA\n") +{ + struct osmo_xua_server *xs = vty->index; + + osmo_ss7_xua_server_set_local_host(xs, argv[0]); + return CMD_SUCCESS; +} + +enum osmo_ss7_asp_protocol parse_asp_proto(const char *protocol) +{ + return get_string_value(osmo_ss7_asp_protocol_vals, protocol); +} + +static int config_write_sua(struct vty *vty) +{ + struct osmo_xua_server *xs = vty->index; + + vty_out(vty, "cs7 sua %u%s", xs->cfg.local.port, VTY_NEWLINE); + vty_out(vty, " local-ip %s%s", xs->cfg.local.host, VTY_NEWLINE); + return 0; +} + +/*********************************************************************** + * M3UA Configuration + ***********************************************************************/ + +static struct cmd_node m3ua_node = { + L_CS7_M3UA_NODE, + "%s(config-cs7-m3ua)# ", + 1, +}; + +DEFUN(cs7_m3ua, cs7_m3ua_cmd, + "cs7 m3ua <0-65534>", + CS7_STR + "Configure/Enable M3UA\n" + "SCTP Port number for M3UA\n") +{ + struct osmo_ss7_instance *inst = FIXME; + struct osmo_xua_server *xs; + uint16_t port = atoi(argv[0]); + + xs = osmo_ss7_xua_server_find(inst, OSMO_SS7_ASP_PROT_M3UA, port); + if (!xs) { + xs = osmo_ss7_xua_server_create(inst, OSMO_SS7_ASP_PROT_M3UA, port, NULL); + if (!xs) + return CMD_SUCCESS; + } + + vty->node = L_CS7_M3UA_NODE; + vty->index = xs; + return CMD_SUCCESS; +} + +DEFUN(m3ua_local_ip, m3ua_local_ip_cmd, + "local-ip A.B.C.D", + "Configure the Local IP Address for M3UA\n" + "IP Address to use for M3UA\n") +{ + struct osmo_xua_server *xs = vty->index; + + osmo_ss7_xua_server_set_local_host(xs, argv[0]); + return CMD_SUCCESS; +} + +static int config_write_m3ua(struct vty *vty) +{ + struct osmo_xua_server *xs = vty->index; + + vty_out(vty, "cs7 m3ua %u%s", xs->cfg.local.port, VTY_NEWLINE); + vty_out(vty, " local-ip %s%s", xs->cfg.local.host, VTY_NEWLINE); + return 0; +} + +/*********************************************************************** + * Application Server Process + ***********************************************************************/ + +static struct cmd_node asp_node = { + L_CS7_ASP_NODE, + "%s(config-cs7-asp)# ", + 1, +}; + +DEFUN(cs7_asp, cs7_asp_cmd, + "cs7 asp NAME <0-65535> <0-65535> [m3ua | sua]", + CS7_STR + "Configure Application Server Process\n" + "Name of ASP\n" + "Remote SCTP port number\n" + "Local SCTP port number\n" + "M3UA Protocol\n" + "SUA Protocol\n") +{ + struct osmo_ss7_instance *inst = FIXME; + const char *name = argv[0]; + uint16_t remote_port = atoi(argv[1]); + uint16_t local_port = atoi(argv[2]); + enum osmo_ss7_asp_protocol protocol = parse_asp_proto(argv[3]); + struct osmo_ss7_asp *asp; + + if (protocol == OSMO_SS7_ASP_PROT_NONE) + return CMD_WARNING; + + asp = osmo_ss7_asp_find_or_create(inst, name, remote_port, local_port, protocol); + if (!asp) + return CMD_WARNING; + + vty->node = L_CS7_ASP_NODE; + vty->index = asp; + vty->index_sub = &asp->cfg.description; + return CMD_SUCCESS; +} + +DEFUN(asp_remote_ip, asp_remote_ip_cmd, + "remote-ip A.B.C.D", + "Specity Remote IP Address of ASP\n" + "Remote IP Address of ASP\n") +{ + struct osmo_ss7_asp *asp = vty->index; + osmo_talloc_replace_string(asp, &asp->cfg.remote.host, argv[0]); + return CMD_SUCCESS; +} + +DEFUN(asp_qos_clas, asp_qos_class_cmd, + "qos-class <0-255>", + "Specity QoS Class of ASP\n" + "QoS Class of ASP\n") +{ + struct osmo_ss7_asp *asp = vty->index; + asp->cfg.qos_class = atoi(argv[0]); + return CMD_SUCCESS; +} + +DEFUN(asp_block, asp_block_cmd, + "block", + "Allows a SCTP Association with ASP, but doesn't let it become active\n") +{ + struct osmo_ss7_asp *asp = vty->index; + vty_out(vty, "Not supported yet\n"); + return CMD_WARNING; +} + +DEFUN(asp_shutdown, asp_shutdown_cmd, + "shutdown", + "Terminates SCTP association; New associations will be rejected\n") +{ + struct osmo_ss7_asp *asp = vty->index; + vty_out(vty, "Not supported yet\n"); + return CMD_WARNING; +} + +static int config_write_asp(struct vty *vty) +{ + struct osmo_ss7_asp *asp = vty->index; + + vty_out(vty, "cs7 asp %s %u %u %s%s", + asp->cfg.name, asp->cfg.remote.port, asp->cfg.local.port, + osmo_ss7_asp_protocol_name(asp->cfg.proto), VTY_NEWLINE); + vty_out(vty, " remote-ip %s%s", asp->cfg.remote.host, VTY_NEWLINE); + if (asp->cfg.qos_class) + vty_out(vty, " qos-class %u%s", asp->cfg.qos_class, VTY_NEWLINE); + return 0; +} + +/*********************************************************************** + * Application Server + ***********************************************************************/ + +static struct cmd_node as_node = { + L_CS7_AS_NODE, + "%s(config-cs7-as)# ", + 1, +}; + +DEFUN(cs7_as, cs7_as_cmd, + "cs7 as NAME [m3ua | sua]", + CS7_STR + "Configure an Application Server\n" + "Name of the Application Server\n" + "M3UA Application Server\n" + "SUA Application Server\n") +{ + struct osmo_ss7_as *as; + const char *name = argv[0]; + enum osmo_ss7_asp_protocol protocol = parse_asp_proto(argv[1]); + + if (protocol == OSMO_SS7_ASP_PROT_NONE) + return CMD_WARNING; + + /* FIXME */ + as->cfg.name = talloc_strdup(as, name); + + vty->node = L_CS7_AS_NODE; + vty->index = as; + vty->index_sub = &as->cfg.description; + + return CMD_SUCCESS; +} + +/* TODO: routing-key */ +DEFUN(as_asp, as_asp_cmd, + "asp NAME", + "Specify that a given ASP is part of this AS\n" + "Name of ASP to be added to AS\n") +{ + struct osmo_ss7_as *as = vty->index; + + if (osmo_ss7_as_add_asp(as, argv[0])) + return CMD_WARNING; + + return CMD_SUCCESS; +} + +DEFUN(as_no_asp, as_no_asp_cmd, + "no asp NAME", + NO_STR "Specify ASP to be removed from this AS\n" + "Name of ASP to be removed\n") +{ + struct osmo_ss7_as *as = vty->index; + + if (osmo_ss7_as_del_asp(as, argv[0])) + return CMD_WARNING; + + return CMD_SUCCESS; +} + +DEFUN(as_traf_mode, as_traf_mode_cmd, + "traffic-mode (broadcast | loadshare | roundrobin | override)", + "Specifies traffic mode of operation of the ASP within the AS\n" + "Broadcast to all ASP within AS\n" + "Share Load among all ASP within AS\n" + "Round-Robin between all ASP within AS\n" + "Override\n") +{ + struct osmo_ss7_as *as = vty->index; + + as->cfg.mode = get_string_value(osmo_ss7_as_traffic_mode_vals, argv[0]); + return CMD_WARNING; +} + +DEFUN(as_recov_tout, as_recov_tout_cmd, + "recovery-timeout <1-2000>", + "Specifies the recovery timeout value in milliseconds\n" + "Recovery Timeout in Milliseconds\n") +{ + struct osmo_ss7_as *as = vty->index; + as->cfg.recovery_timeout_msec = atoi(argv[0]); + return CMD_SUCCESS; +} + +DEFUN(as_qos_clas, as_qos_class_cmd, + "qos-class <0-255>", + "Specity QoS Class of AS\n" + "QoS Class of AS\n") +{ + struct osmo_ss7_as *as = vty->index; + as->cfg.qos_class = atoi(argv[0]); + return CMD_SUCCESS; +} + +const struct value_string mtp_si_vals[] = { + { MTP_SI_SCCP, "sccp" }, + { MTP_SI_TUP, "tup" }, + { MTP_SI_ISUP, "isup" }, + { MTP_SI_DUP, "dup" }, + { MTP_SI_TESTING, "testing" }, + { MTP_SI_B_ISUP, "b-isup" }, + { MTP_SI_SAT_ISUP, "sat-isup" }, + { MTP_SI_AAL2_SIG, "aal2" }, + { MTP_SI_BICC, "bicc" }, + { MTP_SI_GCP, "h248" }, + { 0, NULL } +}; + +DEFUN(as_rout_key, as_rout_key_cmd, + "routing-key RCONTEXT DPC [si {aal2 | bicc | b-isup | h248 | isup | sat-isup | sccp | tup }] [ssn SSN]}", + "Define a routing key\n" + "Routing context number\n" + "Destination Point Code\n" + "Optional Match on Service Indicator\n" + "ATM Adaption Layer 2\n" + "Bearer Independent Call Control\n" + "Broadband ISDN User Part\n" + "H.248\n" + "ISDN User Part\n" + "Sattelite ISDN User Part\n" + "Signalling Connection Control Part\n" + "Telephony User Part\n" + "Optional Match on Sub-System Number\n" + "Sub-System Number to match on\n") +{ + struct osmo_ss7_as *as = vty->index; + uint32_t key = atoi(argv[0]); + struct osmo_ss7_routing_key *rkey; + int argind; + + rkey = osmo_ss7_rkey_find_or_create(as, key); + if (!rkey) + return CMD_WARNING; + + rkey->pc = osmo_ss7_pointcode_parse(as->inst, argv[1]); + argind = 2; + + if (!strcmp(argv[argind], "si")) { + const char *si_str; + argind++; + si_str = argv[argind++]; + /* parse numeric SI from string */ + rkey->si = get_string_value(mtp_si_vals, si_str); + } + if (!strcmp(argv[argind], "ssn")) { + argind++; + rkey->ssn = atoi(argv[argind]); + } + + return CMD_SUCCESS; +} + +static int config_write_as(struct vty *vty) +{ + struct osmo_ss7_as *as = vty->index; + struct osmo_ss7_routing_key *rkey; + unsigned int i; + + vty_out(vty, "cs7 as %s %s%s", as->cfg.name, + osmo_ss7_asp_protocol_name(as->cfg.proto), VTY_NEWLINE); + for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) { + struct osmo_ss7_asp *asp = as->cfg.asps[i]; + if (!asp) + continue; + vty_out(vty, " asp %s%s", asp->cfg.name, VTY_NEWLINE); + } + if (as->cfg.mode != OSMO_SS7_AS_TMOD_LOADSHARE) + vty_out(vty, " traffic-mode %s%s", + osmo_ss7_as_traffic_mode_name(as->cfg.mode), VTY_NEWLINE); + if (as->cfg.recovery_timeout_msec != 2000) { + vty_out(vty, " recovery-timeout %u%s", + as->cfg.recovery_timeout_msec, VTY_NEWLINE); + } + vty_out(vty, " qos-class %u%s", as->cfg.qos_class, VTY_NEWLINE); + rkey = &as->cfg.routing_key; + vty_out(vty, " routing-key %u %s", rkey->context, + osmo_ss7_pointcode_print(as->inst, rkey->pc)); + if (rkey->si) + vty_out(vty, " si %s", + get_value_string(mtp_si_vals, rkey->si)); + if (rkey->ssn) + vty_out(vty, " ssn %u", rkey->ssn); + vty_out(vty, "%s", VTY_NEWLINE); + + return 0; +} + +int osmo_ss7_vty_init(void) +{ + install_element(CONFIG_NODE, &cs7_net_ind_cmd); + install_element(CONFIG_NODE, &cs7_point_code_cmd); + install_element(CONFIG_NODE, &cs7_pc_format_cmd); + install_element(CONFIG_NODE, &cs7_pc_format_def_cmd); + install_element(CONFIG_NODE, &cs7_pc_delimiter_cmd); + + install_node(&rtable_node, config_write_rtable); + vty_install_default(L_CS7_RTABLE_NODE); + install_element(CONFIG_NODE, &cs7_route_table_cmd); + install_element(L_CS7_RTABLE_NODE, &cfg_description_cmd); + install_element(L_CS7_RTABLE_NODE, &cs7_rt_upd_cmd); + install_element(L_CS7_RTABLE_NODE, &cs7_rt_rem_cmd); + + install_node(&sua_node, config_write_sua); + vty_install_default(L_CS7_SUA_NODE); + install_element(CONFIG_NODE, &cs7_sua_cmd); + install_element(L_CS7_SUA_NODE, &sua_local_ip_cmd); + + install_node(&m3ua_node, config_write_m3ua); + vty_install_default(L_CS7_M3UA_NODE); + install_element(CONFIG_NODE, &cs7_m3ua_cmd); + install_element(L_CS7_M3UA_NODE, &m3ua_local_ip_cmd); + + install_node(&asp_node, config_write_asp); + vty_install_default(L_CS7_ASP_NODE); + install_element(CONFIG_NODE, &cs7_asp_cmd); + install_element(L_CS7_ASP_NODE, &cfg_description_cmd); + install_element(L_CS7_ASP_NODE, &asp_remote_ip_cmd); + install_element(L_CS7_ASP_NODE, &asp_qos_class_cmd); + install_element(L_CS7_ASP_NODE, &asp_block_cmd); + install_element(L_CS7_ASP_NODE, &asp_shutdown_cmd); + + install_node(&as_node, config_write_as); + vty_install_default(L_CS7_AS_NODE); + install_element(CONFIG_NODE, &cs7_as_cmd); + install_element(L_CS7_AS_NODE, &cfg_description_cmd); + install_element(L_CS7_AS_NODE, &as_asp_cmd); + install_element(L_CS7_AS_NODE, &as_no_asp_cmd); + install_element(L_CS7_AS_NODE, &as_traf_mode_cmd); + install_element(L_CS7_AS_NODE, &as_recov_tout_cmd); + install_element(L_CS7_AS_NODE, &as_qos_class_cmd); + install_element(L_CS7_AS_NODE, &as_rout_key_cmd); + + return 0; +} diff --git a/src/xua_as_fsm.c b/src/xua_as_fsm.c new file mode 100644 index 0000000..887a9ec --- /dev/null +++ b/src/xua_as_fsm.c @@ -0,0 +1,308 @@ +/* SCCP M3UA / SUA AS osmo_fsm according to RFC3868 4.3.1 / RFC4666 4.3.2 */ +/* (C) Copyright 2017 by Harald Welte + * + * All Rights reserved. + * + * Based on Erlang implementation xua_as_fsm.erl in osmo-ss7.git + */ + +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "xua_asp_fsm.h" +#include "xua_as_fsm.h" +#include "xua_internal.h" + +static struct msgb *encode_notify(const struct m3ua_notify_params *npar) +{ + struct xua_msg *xua = m3ua_encode_notify(npar); + struct msgb *msg = xua_to_msg(M3UA_VERSION, xua); + xua_msg_free(xua); + return msg; +} + +static int asp_notify_all_as(struct osmo_ss7_as *as, struct m3ua_notify_params *npar) +{ + struct msgb *msg; + unsigned int i, sent = 0; + + /* iterate over all non-DOWN ASPs and send them the message */ + for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) { + struct osmo_ss7_asp *asp = as->cfg.asps[i]; + + if (!asp) + continue; + + if (!asp->fi || asp->fi->state == XUA_ASP_S_DOWN) + continue; + + /* Optional: ASP Identifier (if sent in ASP-UP) */ + if (asp->asp_id_present) { + npar->presence |= NOTIFY_PAR_P_ASP_ID; + npar->asp_id = asp->asp_id; + } else + npar->presence &= ~NOTIFY_PAR_P_ASP_ID; + + /* TODO: Optional Routing Context */ + + msg = encode_notify(npar); + osmo_ss7_asp_send(asp, msg); + sent++; + } + + return sent; +} + + +/*********************************************************************** + * Actual FSM + ***********************************************************************/ + +#define S(x) (1 << (x)) + +enum xua_as_state { + XUA_AS_S_DOWN, + XUA_AS_S_INACTIVE, + XUA_AS_S_ACTIVE, + XUA_AS_S_PENDING, +}; + +static const struct value_string xua_as_event_names[] = { + { XUA_ASPAS_ASP_INACTIVE_IND, "ASPAS-ASP_INACTIVE.ind" }, + { XUA_ASPAS_ASP_DOWN_IND, "ASPAS-ASP_DOWN.ind" }, + { XUA_ASPAS_ASP_ACTIVE_IND, "ASPAS-ASP_ACTIVE.ind" }, + { 0, NULL } +}; + +struct xua_as_fsm_priv { + struct osmo_ss7_as *as; +}; + +/* is any other ASP in this AS in state != DOWN? */ +static bool check_any_other_asp_not_down(struct osmo_ss7_as *as, struct osmo_ss7_asp *asp_cmp) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) { + struct osmo_ss7_asp *asp = as->cfg.asps[i]; + if (!asp) + continue; + + if (asp_cmp == asp) + continue; + + if (asp->fi && asp->fi->state != XUA_ASP_S_DOWN) + return true; + } + + return false; +} + +/* is any other ASP in this AS in state ACTIVE? */ +static bool check_any_other_asp_in_active(struct osmo_ss7_as *as, struct osmo_ss7_asp *asp_cmp) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) { + struct osmo_ss7_asp *asp = as->cfg.asps[i]; + if (!asp) + continue; + + if (asp_cmp == asp) + continue; + + if (asp->fi && asp->fi->state == XUA_ASP_S_ACTIVE) + return true; + } + + return false; +} + + +static void xua_as_fsm_down(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + switch (event) { + case XUA_ASPAS_ASP_INACTIVE_IND: + /* one ASP transitions into ASP-INACTIVE */ + osmo_fsm_inst_state_chg(fi, XUA_AS_S_INACTIVE, 0, 0); + break; + case XUA_ASPAS_ASP_DOWN_IND: + /* ignore */ + break; + } +} + +/* onenter call-back responsible of transmitting NTFY to all ASPs in + * case of AS state changes */ +static void xua_as_fsm_onenter(struct osmo_fsm_inst *fi, uint32_t old_state) +{ + struct xua_as_fsm_priv *xafp = (struct xua_as_fsm_priv *) fi->priv; + struct m3ua_notify_params npar = { + .status_type = M3UA_NOTIFY_T_STATCHG, + }; + + switch (fi->state) { + case XUA_AS_S_INACTIVE: + npar.status_info = M3UA_NOTIFY_I_AS_INACT; + break; + case XUA_AS_S_ACTIVE: + npar.status_info = M3UA_NOTIFY_I_AS_ACT; + break; + case XUA_AS_S_PENDING: + npar.status_info = M3UA_NOTIFY_I_AS_PEND; + break; + default: + return; + } + + asp_notify_all_as(xafp->as, &npar); +}; + +static void xua_as_fsm_inactive(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct xua_as_fsm_priv *xafp = (struct xua_as_fsm_priv *) fi->priv; + struct osmo_ss7_asp *asp = data; + + switch (event) { + case XUA_ASPAS_ASP_DOWN_IND: + /* one ASP transitions into ASP-DOWN */ + if (check_any_other_asp_not_down(xafp->as, asp)) { + /* ignore, we stay AS_INACTIVE */ + } else + osmo_fsm_inst_state_chg(fi, XUA_AS_S_DOWN, 0, 0); + break; + case XUA_ASPAS_ASP_ACTIVE_IND: + /* one ASP transitions into ASP-ACTIVE */ + osmo_fsm_inst_state_chg(fi, XUA_AS_S_ACTIVE, 0, 0); + break; + case XUA_ASPAS_ASP_INACTIVE_IND: + /* ignore */ + break; + } +} + +static void xua_as_fsm_active(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct xua_as_fsm_priv *xafp = (struct xua_as_fsm_priv *) fi->priv; + struct osmo_ss7_asp *asp = data; + + switch (event) { + case XUA_ASPAS_ASP_DOWN_IND: + case XUA_ASPAS_ASP_INACTIVE_IND: + if (check_any_other_asp_in_active(xafp->as, asp)) { + /* ignore, we stay AS_ACTIVE */ + } else { + osmo_fsm_inst_state_chg(fi, XUA_AS_S_PENDING, 0, 0); + /* FIXME: Start T(r) */ + /* FIXME: Queue all signalling messages until + * recovery or T(r) expiry */ + } + break; + case XUA_ASPAS_ASP_ACTIVE_IND: + /* ignore */ + break; + } +} + +static void xua_as_fsm_pending(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + switch (event) { + case XUA_ASPAS_ASP_ACTIVE_IND: + /* one ASP transitions into ASP-ACTIVE */ + osmo_fsm_inst_state_chg(fi, XUA_AS_S_ACTIVE, 0, 0); + break; + case XUA_ASPAS_ASP_INACTIVE_IND: + /* ignore */ + break; + case XUA_ASPAS_ASP_DOWN_IND: + /* ignore */ + break; + } +} + +static const struct osmo_fsm_state xua_as_fsm_states[] = { + [XUA_AS_S_DOWN] = { + .in_event_mask = S(XUA_ASPAS_ASP_INACTIVE_IND) | + S(XUA_ASPAS_ASP_DOWN_IND), + .out_state_mask = S(XUA_AS_S_DOWN) | + S(XUA_AS_S_INACTIVE), + .name = "AS_DOWN", + .action = xua_as_fsm_down, + }, + [XUA_AS_S_INACTIVE] = { + .in_event_mask = S(XUA_ASPAS_ASP_DOWN_IND) | + S(XUA_ASPAS_ASP_ACTIVE_IND) | + S(XUA_ASPAS_ASP_INACTIVE_IND), + .out_state_mask = S(XUA_AS_S_DOWN) | + S(XUA_AS_S_INACTIVE) | + S(XUA_AS_S_ACTIVE), + .name = "AS_INACTIVE", + .action = xua_as_fsm_inactive, + .onenter = xua_as_fsm_onenter, + }, + [XUA_AS_S_ACTIVE] = { + .in_event_mask = S(XUA_ASPAS_ASP_DOWN_IND) | + S(XUA_ASPAS_ASP_INACTIVE_IND) | + S(XUA_ASPAS_ASP_ACTIVE_IND), + .out_state_mask = S(XUA_AS_S_ACTIVE) | + S(XUA_AS_S_PENDING), + .name = "AS_ACTIVE", + .action = xua_as_fsm_active, + .onenter = xua_as_fsm_onenter, + }, + [XUA_AS_S_PENDING] = { + .in_event_mask = S(XUA_ASPAS_ASP_INACTIVE_IND) | + S(XUA_ASPAS_ASP_DOWN_IND) | + S(XUA_ASPAS_ASP_ACTIVE_IND), + .out_state_mask = S(XUA_AS_S_DOWN) | + S(XUA_AS_S_INACTIVE) | + S(XUA_AS_S_ACTIVE) | + S(XUA_AS_S_PENDING), + .name = "AS_PENDING", + .action = xua_as_fsm_pending, + .onenter = xua_as_fsm_onenter, + }, +}; + +struct osmo_fsm xua_as_fsm = { + .name = "XUA_AS", + .states = xua_as_fsm_states, + .num_states = ARRAY_SIZE(xua_as_fsm_states), + .log_subsys = DLSS7, + .event_names = xua_as_event_names, +}; + +/*! \brief Start an AS FSM for a given Application Server + * \param[in] as Application Server for which to start the AS FSM + * \param[in] log_level Logging level for logging of this FSM + * \returns FSM instance in case of success; NULL in case of error */ +struct osmo_fsm_inst *xua_as_fsm_start(struct osmo_ss7_as *as, int log_level) +{ + struct osmo_fsm_inst *fi; + struct xua_as_fsm_priv *xafp; + + fi = osmo_fsm_inst_alloc(&xua_as_fsm, as, NULL, log_level, as->cfg.name); + + xafp = talloc_zero(fi, struct xua_as_fsm_priv); + if (!xafp) { + osmo_fsm_inst_term(fi, OSMO_FSM_TERM_ERROR, NULL); + return NULL; + } + xafp->as = as; + + fi->priv = xafp; + + return fi; +} diff --git a/src/xua_as_fsm.h b/src/xua_as_fsm.h new file mode 100644 index 0000000..3b8e5b7 --- /dev/null +++ b/src/xua_as_fsm.h @@ -0,0 +1,13 @@ +#pragma once + +struct osmo_ss7_as; + +enum xua_as_event { + XUA_ASPAS_ASP_INACTIVE_IND, + XUA_ASPAS_ASP_DOWN_IND, + XUA_ASPAS_ASP_ACTIVE_IND, +}; + +extern struct osmo_fsm xua_as_fsm; + +struct osmo_fsm_inst *xua_as_fsm_start(struct osmo_ss7_as *as, int log_level); diff --git a/src/xua_asp_fsm.c b/src/xua_asp_fsm.c new file mode 100644 index 0000000..80faeb2 --- /dev/null +++ b/src/xua_asp_fsm.c @@ -0,0 +1,610 @@ +/* SCCP M3UA / SUA ASP osmo_fsm according to RFC3868 4.3.1 */ +/* (C) Copyright 2017 by Harald Welte + * + * All Rights reserved. + * + * Based on my earlier Erlang implementation xua_asp_fsm.erl in + * osmo-ss7.git + */ + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "xua_asp_fsm.h" +#include "xua_as_fsm.h" + +#define S(x) (1 << (x)) + +/* The general idea is: + * * translate incoming SUA/M3UA msg_class/msg_type to xua_asp_event + * * propagate state transitions to XUA_AS_FSM via _onenter functiosn + * * notify the Layer Management of any relevant changes + * * + */ + +/* According to RFC3868 Section 8 */ +#define XUA_T_A_SEC 2 +#define XUA_T_R_SEC 2 +#define XUA_T_ACK_SEC 2 +#define XUA_T_BEAT_SEC 30 +#define SUA_T_IAS_SEC (7*60) /* SUA only */ +#define SUA_T_IAR_SEC (15*60) /* SUA only */ + +static const struct value_string xua_asp_role_names[] = { + { XUA_ASPFSM_ROLE_ASP, "ASP" }, + { XUA_ASPFSM_ROLE_SG, "SG" }, + { XUA_ASPFSM_ROLE_IPSP, "IPSP" }, + { 0, NULL } +}; + +static const struct value_string xua_asp_event_names[] = { + { XUA_ASP_E_M_ASP_UP_REQ, "M-ASP_UP.req" }, + { XUA_ASP_E_M_ASP_ACTIVE_REQ, "M-ASP_ACTIVE.req" }, + { XUA_ASP_E_M_ASP_DOWN_REQ, "M-ASP_DOWN.req" }, + { XUA_ASP_E_M_ASP_INACTIVE_REQ, "M-ASP_INACTIVE.req" }, + + { XUA_ASP_E_SCTP_COMM_DOWN_IND, "SCTP-COMM_DOWN.ind" }, + { XUA_ASP_E_SCTP_RESTART_IND, "SCTP-RESTART.ind" }, + + { XUA_ASP_E_ASPSM_ASPUP, "ASPSM-ASP_UP" }, + { XUA_ASP_E_ASPSM_ASPUP_ACK, "ASPSM-ASP_UP_ACK" }, + { XUA_ASP_E_ASPTM_ASPAC, "ASPTM-ASP_AC" }, + { XUA_ASP_E_ASPTM_ASPAC_ACK, "ASPTM-ASP_AC_ACK" }, + { XUA_ASP_E_ASPSM_ASPDN, "ASPSM-ASP_DN" }, + { XUA_ASP_E_ASPSM_ASPDN_ACK, "ASPSM-ASP_DN_ACK" }, + { XUA_ASP_E_ASPTM_ASPIA, "ASPTM-ASP_IA" }, + { XUA_ASP_E_ASPTM_ASPIA_ACK, "ASPTM_ASP_IA_ACK" }, + { 0, NULL } +}; + +struct xua_layer_manager { + osmo_prim_cb prim_cb; +}; + +/* private data structure for each FSM instance */ +struct xua_asp_fsm_priv { + /* pointer back to ASP to which we belong */ + struct osmo_ss7_asp *asp; + /* Role (ASP/SG/IPSP) */ + enum xua_asp_role role; + /* Layer Manager to which we talk */ + struct xua_layer_manager *lm; + + /* routing context[s]: list of 32bit integers */ + /* ACTIVE: traffic mode type, tid label, drn label ? */ + + struct { + struct osmo_timer_list timer; + int out_event; + } t_ack; +}; + +static struct msgb *xlm_msgb_alloc(void) +{ + return msgb_alloc_headroom(2048+128, 128, "xua_asp-xlm msgb"); +} + +/* Send a XUA LM Primitive to the XUA Layer Manager (LM) */ +static int send_xlm_prim(struct osmo_fsm_inst *fi, + enum osmo_xlm_prim_type prim_type, + enum osmo_prim_operation op, + const uint8_t *data, unsigned int data_len) +{ + struct xua_asp_fsm_priv *xafp = fi->priv; + struct msgb *xlmsg; + struct osmo_xlm_prim *prim; + struct xua_layer_manager *lm = xafp->lm; + + if (!lm || !lm->prim_cb) + return 0; + + xlmsg = xlm_msgb_alloc(); + if (!xlmsg) + return -ENOMEM; + prim = (struct osmo_xlm_prim *) msgb_put(xlmsg, sizeof(*prim)); + osmo_prim_init(&prim->oph, XUA_SAP_LM, prim_type, op, xlmsg); + + lm->prim_cb(&prim->oph, xafp->asp); + + return 0; +} + +/* wrapper around send_xlm_prim for primitives without data */ +static int send_xlm_prim_simple(struct osmo_fsm_inst *fi, + enum osmo_xlm_prim_type prim, + enum osmo_prim_operation op) +{ + return send_xlm_prim(fi, prim, op, NULL, 0); +} + +/* ask the xUA implementation to transmit a specific message */ +static int peer_send(struct osmo_fsm_inst *fi, int out_event) +{ + struct xua_asp_fsm_priv *xafp = fi->priv; + struct osmo_ss7_asp *asp = xafp->asp; + struct xua_msg *xua = xua_msg_alloc(); + struct msgb *msg; + + switch (out_event) { + case XUA_ASP_E_ASPSM_ASPUP: + /* RFC 3868 Ch. 3.5.1 */ + xua->hdr = XUA_HDR(SUA_MSGC_ASPSM, SUA_ASPSM_UP); + /* Optional: ASP ID */ + if (asp->asp_id_present) + xua_msg_add_u32(xua, SUA_IEI_ASP_ID, asp->asp_id); + /* Optional: Info String */ + break; + case XUA_ASP_E_ASPSM_ASPUP_ACK: + /* RFC3868 Ch. 3.5.2 */ + xua->hdr = XUA_HDR(SUA_MSGC_ASPSM, SUA_ASPSM_UP_ACK); + /* Optional: Info String */ + break; + case XUA_ASP_E_ASPSM_ASPDN: + /* RFC3868 Ch. 3.5.3 */ + xua->hdr = XUA_HDR(SUA_MSGC_ASPSM, SUA_ASPSM_DOWN); + /* Optional: Info String */ + break; + case XUA_ASP_E_ASPSM_ASPDN_ACK: + /* RFC3868 Ch. 3.5.4 */ + xua->hdr = XUA_HDR(SUA_MSGC_ASPSM, SUA_ASPSM_DOWN_ACK); + /* Optional: Info String */ + break; + case XUA_ASP_E_ASPSM_BEAT: + /* RFC3868 Ch. 3.5.5 */ + xua->hdr = XUA_HDR(SUA_MSGC_ASPSM, SUA_ASPSM_BEAT); + /* Optional: Heartbeat Data */ + break; + case XUA_ASP_E_ASPSM_BEAT_ACK: + /* RFC3868 Ch. 3.5.6 */ + xua->hdr = XUA_HDR(SUA_MSGC_ASPSM, SUA_ASPSM_BEAT_ACK); + /* Optional: Heartbeat Data */ + break; + case XUA_ASP_E_ASPTM_ASPAC: + /* RFC3868 Ch. 3.6.1 */ + xua->hdr = XUA_HDR(SUA_MSGC_ASPTM, SUA_ASPTM_ACTIVE); + /* Optional: Traffic Mode Type */ + /* Optional: Routing Context */ + /* Optional: TID Label */ + /* Optional: DRN Label */ + /* Optional: Info String */ + break; + case XUA_ASP_E_ASPTM_ASPAC_ACK: + /* RFC3868 Ch. 3.6.2 */ + xua->hdr = XUA_HDR(SUA_MSGC_ASPTM, SUA_ASPTM_ACTIVE_ACK); + /* Optional: Traffic Mode Type */ + /* Mandatory: Routing Context */ + //FIXME xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, + /* Optional: Info String */ + break; + case XUA_ASP_E_ASPTM_ASPIA: + /* RFC3868 Ch. 3.6.3 */ + xua->hdr = XUA_HDR(SUA_MSGC_ASPTM, SUA_ASPTM_INACTIVE); + /* Optional: Routing Context */ + /* Optional: Info String */ + break; + case XUA_ASP_E_ASPTM_ASPIA_ACK: + /* RFC3868 Ch. 3.6.4 */ + xua->hdr = XUA_HDR(SUA_MSGC_ASPTM, SUA_ASPTM_INACTIVE_ACK); + /* Optional: Routing Context */ + /* Optional: Info String */ + break; + } + + msg = xua_to_msg(SUA_VERSION, xua); + xua_msg_free(xua); + if (!msg) + return -1; + + return osmo_ss7_asp_send(asp, msg); +} + +static void xua_t_ack_cb(void *data) +{ + struct osmo_fsm_inst *fi = data; + struct xua_asp_fsm_priv *xafp = fi->priv; + + LOGPFSML(fi, LOGL_INFO, "T(ack) callback: re-transmitting event %s\n", + osmo_fsm_event_name(fi->fsm, xafp->t_ack.out_event)); + + /* Re-transmit message */ + peer_send(fi, xafp->t_ack.out_event); + + /* Re-start the timer */ + osmo_timer_schedule(&xafp->t_ack.timer, XUA_T_ACK_SEC, 0); +} + +static int peer_send_and_start_t_ack(struct osmo_fsm_inst *fi, + int out_event) +{ + struct xua_asp_fsm_priv *xafp = fi->priv; + int rc; + + rc = peer_send(fi, out_event); + if (rc < 0) + return rc; + + xafp->t_ack.out_event = out_event; + xafp->t_ack.timer.cb = xua_t_ack_cb, + xafp->t_ack.timer.data = fi; + + osmo_timer_schedule(&xafp->t_ack.timer, XUA_T_ACK_SEC, 0); + + return rc; +} + +static const uint32_t evt_ack_map[_NUM_XUA_ASP_E] = { + [XUA_ASP_E_ASPSM_ASPUP] = XUA_ASP_E_ASPSM_ASPUP_ACK, + [XUA_ASP_E_ASPTM_ASPAC] = XUA_ASP_E_ASPTM_ASPAC_ACK, + [XUA_ASP_E_ASPSM_ASPDN] = XUA_ASP_E_ASPSM_ASPDN_ACK, + [XUA_ASP_E_ASPTM_ASPIA] = XUA_ASP_E_ASPTM_ASPIA_ACK, + [XUA_ASP_E_ASPSM_BEAT] = XUA_ASP_E_ASPSM_BEAT_ACK, +}; + + +/* check if expected message was received + stop t_ack */ +static void check_stop_t_ack(struct osmo_fsm_inst *fi, uint32_t event) +{ + struct xua_asp_fsm_priv *xafp = fi->priv; + int exp_ack; + + if (event >= ARRAY_SIZE(evt_ack_map)) + return; + + exp_ack = evt_ack_map[xafp->t_ack.out_event]; + if (exp_ack && event == exp_ack) { + LOGPFSML(fi, LOGL_DEBUG, "T(ack) stopped\n"); + osmo_timer_del(&xafp->t_ack.timer); + } +} + +#define ENSURE_ASP_OR_IPSP(fi, event) \ + do { \ + struct xua_asp_fsm_priv *_xafp = fi->priv; \ + if (_xafp->role != XUA_ASPFSM_ROLE_ASP && \ + _xafp->role != XUA_ASPFSM_ROLE_IPSP) { \ + LOGPFSML(fi, LOGL_ERROR, "event %s not permitted " \ + "in role %s\n", \ + osmo_fsm_event_name(fi->fsm, event), \ + get_value_string(xua_asp_role_names, _xafp->role));\ + return; \ + } \ + } while(0) + +#define ENSURE_SG_OR_IPSP(fi, event) \ + do { \ + struct xua_asp_fsm_priv *_xafp = fi->priv; \ + if (_xafp->role != XUA_ASPFSM_ROLE_SG && \ + _xafp->role != XUA_ASPFSM_ROLE_IPSP) { \ + LOGPFSML(fi, LOGL_ERROR, "event %s not permitted " \ + "in role %s\n", \ + osmo_fsm_event_name(fi->fsm, event), \ + get_value_string(xua_asp_role_names, _xafp->role));\ + return; \ + } \ + } while(0) + +static void xua_asp_fsm_down(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct xua_asp_fsm_priv *xafp = fi->priv; + struct osmo_ss7_asp *asp = xafp->asp; + struct xua_msg_part *asp_id_ie; + + check_stop_t_ack(fi, event); + + switch (event) { + case XUA_ASP_E_M_ASP_UP_REQ: + /* only if role ASP */ + ENSURE_ASP_OR_IPSP(fi, event); + /* Send M3UA_MSGT_ASPSM_ASPUP and start t_ack */ + peer_send_and_start_t_ack(fi, XUA_ASP_E_ASPSM_ASPUP); + break; + case XUA_ASP_E_ASPSM_ASPUP_ACK: + /* only if role ASP */ + ENSURE_ASP_OR_IPSP(fi, event); + osmo_fsm_inst_state_chg(fi, XUA_ASP_S_INACTIVE, 0, 0); + /* inform layer manager */ + send_xlm_prim_simple(fi, OSMO_XLM_PRIM_M_ASP_UP, + PRIM_OP_CONFIRM); + /* FIXME: This hack should be in layer manager? */ + osmo_fsm_inst_dispatch(fi, XUA_ASP_E_M_ASP_ACTIVE_REQ, NULL); + break; + case XUA_ASP_E_ASPSM_ASPUP: + /* only if role SG */ + ENSURE_SG_OR_IPSP(fi, event); + asp_id_ie = xua_msg_find_tag(data, SUA_IEI_ASP_ID); + /* Optional ASP Identifier: Store for NTFY */ + if (asp_id_ie) { + asp->asp_id = xua_msg_part_get_u32(asp_id_ie); + asp->asp_id_present = true; + } + /* send ACK */ + peer_send(fi, XUA_ASP_E_ASPSM_ASPUP_ACK); + /* transition state and inform layer manager */ + osmo_fsm_inst_state_chg(fi, XUA_ASP_S_INACTIVE, 0, 0); + send_xlm_prim_simple(fi, OSMO_XLM_PRIM_M_ASP_UP, + PRIM_OP_INDICATION); + break; + case XUA_ASP_E_ASPSM_ASPDN: + /* only if role SG */ + ENSURE_SG_OR_IPSP(fi, event); + /* The SGP MUST send an ASP Down Ack message in response + * to a received ASP Down message from the ASP even if + * the ASP is already marked as ASP-DOWN at the SGP. */ + peer_send(fi, XUA_ASP_E_ASPSM_ASPDN_ACK); + break; + } +} + +/* Helper function to dispatch an ASP->AS event to all AS of which this + * ASP is a memmber. Ignores routing contexts for now. */ +static void dispatch_to_all_as(struct osmo_fsm_inst *fi, uint32_t event) +{ + struct xua_asp_fsm_priv *xafp = fi->priv; + struct osmo_ss7_asp *asp = xafp->asp; + struct osmo_ss7_instance *inst = asp->inst; + struct osmo_ss7_as *as; + + if (xafp->role != XUA_ASPFSM_ROLE_SG) + return; + + llist_for_each_entry(as, &inst->as_list, list) { + if (!osmo_ss7_as_has_asp(as, asp)) + continue; + osmo_fsm_inst_dispatch(as->fi, event, asp); + } +} + +static void xua_asp_fsm_down_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state) +{ + dispatch_to_all_as(fi, XUA_ASPAS_ASP_DOWN_IND); +} + +static void xua_asp_fsm_inactive(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + check_stop_t_ack(fi, event); + switch (event) { + case XUA_ASP_E_M_ASP_ACTIVE_REQ: + /* send M3UA_MSGT_ASPTM_ASPAC and start t_ack */ + peer_send_and_start_t_ack(fi, XUA_ASP_E_ASPTM_ASPAC); + break; + case XUA_ASP_E_M_ASP_DOWN_REQ: + /* send M3UA_MSGT_ASPSM_ASPDN and start t_ack */ + peer_send_and_start_t_ack(fi, XUA_ASP_E_ASPSM_ASPDN); + break; + case XUA_ASP_E_ASPTM_ASPAC_ACK: + /* only in role ASP */ + ENSURE_ASP_OR_IPSP(fi, event); + /* transition state and inform layer manager */ + osmo_fsm_inst_state_chg(fi, XUA_ASP_S_ACTIVE, 0, 0); + send_xlm_prim_simple(fi, OSMO_XLM_PRIM_M_ASP_ACTIVE, + PRIM_OP_CONFIRM); + break; + case XUA_ASP_E_ASPSM_ASPDN_ACK: + /* only in role ASP */ + ENSURE_ASP_OR_IPSP(fi, event); + /* transition state and inform layer manager */ + osmo_fsm_inst_state_chg(fi, XUA_ASP_S_DOWN, 0, 0); + send_xlm_prim_simple(fi, OSMO_XLM_PRIM_M_ASP_DOWN, + PRIM_OP_CONFIRM); + break; + case XUA_ASP_E_ASPTM_ASPAC: + /* only in role SG */ + ENSURE_SG_OR_IPSP(fi, event); + /* send ACK */ + peer_send(fi, XUA_ASP_E_ASPTM_ASPAC_ACK); + /* transition state and inform layer manager */ + osmo_fsm_inst_state_chg(fi, XUA_ASP_S_ACTIVE, 0, 0); + send_xlm_prim_simple(fi, OSMO_XLM_PRIM_M_ASP_ACTIVE, + PRIM_OP_INDICATION); + break; + case XUA_ASP_E_ASPSM_ASPDN: + /* only in role SG */ + ENSURE_SG_OR_IPSP(fi, event); + /* send ACK */ + peer_send(fi, XUA_ASP_E_ASPSM_ASPDN_ACK); + /* transition state and inform layer manager */ + osmo_fsm_inst_state_chg(fi, XUA_ASP_S_DOWN, 0, 0); + send_xlm_prim_simple(fi, OSMO_XLM_PRIM_M_ASP_DOWN, + PRIM_OP_INDICATION); + break; + case XUA_ASP_E_ASPSM_ASPUP: + /* only if role SG */ + ENSURE_SG_OR_IPSP(fi, event); + /* If an ASP Up message is received and internally the + * remote ASP is already in the ASP-INACTIVE state, an + * ASP Up Ack message is returned and no further action + * is taken. */ + peer_send(fi, XUA_ASP_E_ASPSM_ASPUP_ACK); + break; + } +} + +static void xua_asp_fsm_inactive_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state) +{ + dispatch_to_all_as(fi, XUA_ASPAS_ASP_INACTIVE_IND); +} + +static void xua_asp_fsm_active(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + check_stop_t_ack(fi, event); + switch (event) { + case XUA_ASP_E_ASPSM_ASPDN_ACK: + /* only in role ASP */ + ENSURE_ASP_OR_IPSP(fi, event); + osmo_fsm_inst_state_chg(fi, XUA_ASP_S_DOWN, 0, 0); + /* inform layer manager */ + send_xlm_prim_simple(fi, OSMO_XLM_PRIM_M_ASP_DOWN, + PRIM_OP_CONFIRM); + break; + case XUA_ASP_E_ASPTM_ASPIA_ACK: + /* only in role ASP */ + ENSURE_ASP_OR_IPSP(fi, event); + osmo_fsm_inst_state_chg(fi, XUA_ASP_S_INACTIVE, 0, 0); + /* inform layer manager */ + send_xlm_prim_simple(fi, OSMO_XLM_PRIM_M_ASP_INACTIVE, + PRIM_OP_CONFIRM); + break; + case XUA_ASP_E_M_ASP_DOWN_REQ: + /* only in role ASP */ + ENSURE_ASP_OR_IPSP(fi, event); + /* send M3UA_MSGT_ASPSM_ASPDN and star t_ack */ + peer_send_and_start_t_ack(fi, XUA_ASP_E_ASPSM_ASPDN); + break; + case XUA_ASP_E_M_ASP_INACTIVE_REQ: + /* only in role ASP */ + ENSURE_ASP_OR_IPSP(fi, event); + /* send M3UA_MSGT_ASPTM_ASPIA and star t_ack */ + peer_send_and_start_t_ack(fi, XUA_ASP_E_ASPTM_ASPIA); + break; + case XUA_ASP_E_ASPTM_ASPIA: + /* only in role SG */ + ENSURE_SG_OR_IPSP(fi, event); + /* send ACK */ + peer_send(fi, XUA_ASP_E_ASPTM_ASPIA_ACK); + /* transition state and inform layer manager */ + osmo_fsm_inst_state_chg(fi, XUA_ASP_S_INACTIVE, 0, 0); + send_xlm_prim_simple(fi, OSMO_XLM_PRIM_M_ASP_INACTIVE, + PRIM_OP_INDICATION); + break; + case XUA_ASP_E_ASPSM_ASPDN: + /* only in role SG */ + ENSURE_SG_OR_IPSP(fi, event); + /* send ACK */ + peer_send(fi, XUA_ASP_E_ASPSM_ASPDN_ACK); + /* transition state and inform layer manager */ + osmo_fsm_inst_state_chg(fi, XUA_ASP_S_DOWN, 0, 0); + send_xlm_prim_simple(fi, OSMO_XLM_PRIM_M_ASP_DOWN, + PRIM_OP_INDICATION); + break; + case XUA_ASP_E_ASPSM_ASPUP: + /* only if role SG */ + ENSURE_SG_OR_IPSP(fi, event); + /* an ASP Up Ack message is returned, as well as + * an Error message ("Unexpected Message), and the + * remote ASP state is changed to ASP-INACTIVE in all + * relevant Application Servers */ + /* FIXME: Send ERROR message */ + osmo_fsm_inst_state_chg(fi, XUA_ASP_S_INACTIVE, 0, 0); + send_xlm_prim_simple(fi, OSMO_XLM_PRIM_M_ASP_INACTIVE, + PRIM_OP_INDICATION); + break; + } +} + +static void xua_asp_fsm_active_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state) +{ + dispatch_to_all_as(fi, XUA_ASPAS_ASP_ACTIVE_IND); +} + +static void xua_asp_allstate(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + switch (event) { + case XUA_ASP_E_SCTP_COMM_DOWN_IND: + case XUA_ASP_E_SCTP_RESTART_IND: + osmo_fsm_inst_state_chg(fi, XUA_ASP_S_DOWN, 0, 0); + send_xlm_prim_simple(fi, OSMO_XLM_PRIM_M_ASP_DOWN, + PRIM_OP_INDICATION); + break; + default: + break; + } +} + +static int xua_asp_fsm_timer_cb(struct osmo_fsm_inst *fi) +{ + /* We don't use the fsm timer, so any calls to this are an error */ + OSMO_ASSERT(0); + return 0; +} + +static const struct osmo_fsm_state xua_asp_states[] = { + [XUA_ASP_S_DOWN] = { + .in_event_mask = S(XUA_ASP_E_M_ASP_UP_REQ) | + S(XUA_ASP_E_ASPSM_ASPUP) | + S(XUA_ASP_E_ASPSM_ASPUP_ACK) | + S(XUA_ASP_E_ASPSM_ASPDN), + .out_state_mask = S(XUA_ASP_S_INACTIVE), + .name = "ASP_DOWN", + .action = xua_asp_fsm_down, + .onenter = xua_asp_fsm_down_onenter, + }, + [XUA_ASP_S_INACTIVE] = { + .in_event_mask = S(XUA_ASP_E_M_ASP_ACTIVE_REQ) | + S(XUA_ASP_E_M_ASP_DOWN_REQ) | + S(XUA_ASP_E_ASPTM_ASPAC) | + S(XUA_ASP_E_ASPTM_ASPAC_ACK) | + S(XUA_ASP_E_ASPSM_ASPDN) | + S(XUA_ASP_E_ASPSM_ASPDN_ACK) | + S(XUA_ASP_E_ASPSM_ASPUP), + .out_state_mask = S(XUA_ASP_S_DOWN) | + S(XUA_ASP_S_ACTIVE), + .name = "ASP_INACTIVE", + .action = xua_asp_fsm_inactive, + .onenter = xua_asp_fsm_inactive_onenter, + }, + [XUA_ASP_S_ACTIVE] = { + .in_event_mask = S(XUA_ASP_E_ASPSM_ASPDN) | + S(XUA_ASP_E_ASPSM_ASPDN_ACK) | + S(XUA_ASP_E_ASPSM_ASPUP) | + S(XUA_ASP_E_ASPTM_ASPIA) | + S(XUA_ASP_E_ASPTM_ASPIA_ACK) | + S(XUA_ASP_E_M_ASP_DOWN_REQ) | + S(XUA_ASP_E_M_ASP_INACTIVE_REQ), + .out_state_mask = S(XUA_ASP_S_INACTIVE) | + S(XUA_ASP_S_DOWN), + .name = "ASP_ACTIVE", + .action = xua_asp_fsm_active, + .onenter = xua_asp_fsm_active_onenter, + }, +}; + + +struct osmo_fsm xua_asp_fsm = { + .name = "XUA_ASP", + .states = xua_asp_states, + .num_states = ARRAY_SIZE(xua_asp_states), + .timer_cb = xua_asp_fsm_timer_cb, + .log_subsys = DLSS7, + .event_names = xua_asp_event_names, + .allstate_event_mask = S(XUA_ASP_E_SCTP_COMM_DOWN_IND) | + S(XUA_ASP_E_SCTP_RESTART_IND), + .allstate_action = xua_asp_allstate, +}; + + +/*! \brief Start a new ASP finite stae machine for given ASP + * \param[in] asp Application Server Process for which to start FSM + * \param[in] role Role (ASP, SG, IPSP) of this FSM + * \param[in] log_level Logging Level for ASP FSM logging + * \returns FSM instance on success; NULL on error */ +struct osmo_fsm_inst *xua_asp_fsm_start(struct osmo_ss7_asp *asp, + enum xua_asp_role role, int log_level) +{ + struct osmo_fsm_inst *fi; + struct xua_asp_fsm_priv *xafp; + + /* allocate as child of AS? */ + fi = osmo_fsm_inst_alloc(&xua_asp_fsm, asp, NULL, log_level, asp->cfg.name); + + xafp = talloc_zero(fi, struct xua_asp_fsm_priv); + if (!xafp) { + osmo_fsm_inst_term(fi, OSMO_FSM_TERM_ERROR, NULL); + return NULL; + } + xafp->role = role; + xafp->asp = asp; + + fi->priv = xafp; + + return fi; +} diff --git a/src/xua_asp_fsm.h b/src/xua_asp_fsm.h new file mode 100644 index 0000000..ea62484 --- /dev/null +++ b/src/xua_asp_fsm.h @@ -0,0 +1,42 @@ +#pragma once + +enum xua_asp_state { + XUA_ASP_S_DOWN, + XUA_ASP_S_INACTIVE, + XUA_ASP_S_ACTIVE, +}; + +enum xua_asp_event { + XUA_ASP_E_M_ASP_UP_REQ, + XUA_ASP_E_M_ASP_ACTIVE_REQ, + XUA_ASP_E_M_ASP_DOWN_REQ, + XUA_ASP_E_M_ASP_INACTIVE_REQ, + + XUA_ASP_E_SCTP_COMM_DOWN_IND, + XUA_ASP_E_SCTP_RESTART_IND, + + XUA_ASP_E_ASPSM_ASPUP, + XUA_ASP_E_ASPSM_ASPUP_ACK, + XUA_ASP_E_ASPTM_ASPAC, + XUA_ASP_E_ASPTM_ASPAC_ACK, + XUA_ASP_E_ASPSM_ASPDN, + XUA_ASP_E_ASPSM_ASPDN_ACK, + XUA_ASP_E_ASPTM_ASPIA, + XUA_ASP_E_ASPTM_ASPIA_ACK, + + XUA_ASP_E_ASPSM_BEAT, + XUA_ASP_E_ASPSM_BEAT_ACK, + + _NUM_XUA_ASP_E +}; + +enum xua_asp_role { + XUA_ASPFSM_ROLE_ASP, + XUA_ASPFSM_ROLE_SG, + XUA_ASPFSM_ROLE_IPSP, +}; + +extern struct osmo_fsm xua_asp_fsm; + +struct osmo_fsm_inst *xua_asp_fsm_start(struct osmo_ss7_asp *asp, + enum xua_asp_role role, int log_level); diff --git a/src/xua_internal.h b/src/xua_internal.h new file mode 100644 index 0000000..66b5a26 --- /dev/null +++ b/src/xua_internal.h @@ -0,0 +1,58 @@ +#pragma once + +#include +#include + +struct osmo_sccp_addr; +struct m3ua_data_hdr; + +int sua_addr_parse_part(struct osmo_sccp_addr *out, + const struct xua_msg_part *param); +int sua_addr_parse(struct osmo_sccp_addr *out, struct xua_msg *xua, uint16_t iei); + +int sua_parse_gt(struct osmo_sccp_gt *gt, const uint8_t *data, unsigned int datalen); + +struct xua_msg *osmo_sccp_to_xua(struct msgb *msg); +struct msgb *osmo_sua_to_sccp(struct xua_msg *xua); + +int sua_tx_xua_as(struct osmo_ss7_as *as, struct xua_msg *xua); + +struct osmo_mtp_prim *m3ua_to_xfer_ind(struct xua_msg *xua); +int m3ua_hmdc_rx_from_l2(struct osmo_ss7_instance *inst, struct xua_msg *xua); +int m3ua_tx_xua_as(struct osmo_ss7_as *as, struct xua_msg *xua); +int m3ua_rx_msg(struct osmo_ss7_asp *asp, struct msgb *msg); + +struct msgb *m3ua_msgb_alloc(const char *name); +struct m3ua_data_hdr *data_hdr_from_m3ua(struct xua_msg *xua); +void m3ua_dh_to_xfer_param(struct osmo_mtp_transfer_param *param, + const struct m3ua_data_hdr *mdh); +void mtp_xfer_param_to_m3ua_dh(struct m3ua_data_hdr *mdh, + const struct osmo_mtp_transfer_param *param); + + +extern const struct xua_msg_class m3ua_msg_class_mgmt; +extern const struct xua_msg_class m3ua_msg_class_snm; +extern const struct xua_msg_class m3ua_msg_class_rkm; +extern const struct xua_msg_class m3ua_msg_class_aspsm; +extern const struct xua_msg_class m3ua_msg_class_asptm; + +extern const struct value_string m3ua_err_names[]; +extern const struct value_string m3ua_ntfy_type_names[]; +extern const struct value_string m3ua_ntfy_stchg_names[]; +extern const struct value_string m3ua_ntfy_other_names[]; + +#define NOTIFY_PAR_P_ASP_ID (1 << 0) +#define NOTIFY_PAR_P_ROUTE_CTX (1 << 1) + +struct m3ua_notify_params { + uint32_t presence; + uint16_t status_type; + uint16_t status_info; + uint32_t asp_id; + uint32_t route_ctx; + char *info_string; +}; + +struct xua_msg *m3ua_encode_notify(const struct m3ua_notify_params *npar); +int m3ua_decode_notify(struct m3ua_notify_params *npar, void *ctx, + const struct xua_msg *xua); diff --git a/tests/Makefile.am b/tests/Makefile.am index 6e9b807..9c251fe 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,4 +1,4 @@ -SUBDIRS = sccp mtp m2ua sigtran +SUBDIRS = sccp mtp m2ua sigtran ss7 # The `:;' works around a Bash 3.2 bug when the output is not writeable. $(srcdir)/package.m4: $(top_srcdir)/configure.ac diff --git a/tests/ss7/Makefile.am b/tests/ss7/Makefile.am new file mode 100644 index 0000000..bc81915 --- /dev/null +++ b/tests/ss7/Makefile.am @@ -0,0 +1,12 @@ +AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -Wall +AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) + +AM_LDFLAGS = -static +LDADD = $(top_builddir)/src/libosmo-sigtran.la \ + $(LIBOSMOCORE_LIBS) $(LIBOSMONETIF_LIBS) $(LIBSCTP_LIBS) + +EXTRA_DIST = ss7_test.ok ss7_test.err + +noinst_PROGRAMS = ss7_test + +ss7_test_SOURCES = ss7_test.c diff --git a/tests/ss7/ss7_test.c b/tests/ss7/ss7_test.c new file mode 100644 index 0000000..24eabc9 --- /dev/null +++ b/tests/ss7/ss7_test.c @@ -0,0 +1,321 @@ +#include "../src/xua_internal.h" +#include "../src/xua_asp_fsm.h" + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +static struct osmo_ss7_instance *s7i; + +static void test_pc_transcode(uint32_t pc) +{ + const char *pc_str = osmo_ss7_pointcode_print(s7i, pc); + uint32_t pc_reenc = osmo_ss7_pointcode_parse(s7i, pc_str); + + printf("%s(%u) -> %s -> %u\n", __func__, pc, pc_str, pc_reenc); + OSMO_ASSERT(pc == pc_reenc); +} + +static void test_pc_defaults(void) +{ + /* ensure the default point code format settings apply */ + OSMO_ASSERT(s7i->cfg.pc_fmt.component_len[0] == 3); + OSMO_ASSERT(s7i->cfg.pc_fmt.component_len[1] == 8); + OSMO_ASSERT(s7i->cfg.pc_fmt.component_len[2] == 3); + OSMO_ASSERT(s7i->cfg.pc_fmt.delimiter = '.'); +} + +static void parse_print_mask(const char *in) +{ + uint32_t mask = osmo_ss7_pointcode_parse_mask_or_len(s7i, in); + const char *pc_str = osmo_ss7_pointcode_print(s7i, mask); + printf("mask %s => %u (0x%x) %s\n", in, mask, mask, pc_str); +} + +static void test_pc_parser_itu(void) +{ + /* ITU Style */ + printf("Testing ITU-style point code format\n"); + osmo_ss7_instance_set_pc_fmt(s7i, 3, 8, 3); + test_pc_transcode(0); + test_pc_transcode(1); + test_pc_transcode(1 << 3); + test_pc_transcode(1 << (3+8)); + test_pc_transcode(7 << (3+8)); + test_pc_transcode(100); + test_pc_transcode(2342); + test_pc_transcode((1 << 14)-1); + + parse_print_mask("/1"); + parse_print_mask("7.0.0"); + parse_print_mask("/14"); +} + +static void test_pc_parser_ansi(void) +{ + /* ANSI Style */ + printf("Testing ANSI-style point code format\n"); + osmo_ss7_instance_set_pc_fmt(s7i, 8, 8, 8); + s7i->cfg.pc_fmt.delimiter = '-'; + test_pc_transcode(0); + test_pc_transcode(1); + test_pc_transcode(1 << 8); + test_pc_transcode(1 << 16); + test_pc_transcode(1 << (3+8)); + test_pc_transcode((1 << 24)-1); + test_pc_transcode(100); + test_pc_transcode(2342); + + parse_print_mask("/1"); + parse_print_mask("/16"); + parse_print_mask("/24"); + + /* re-set to default (ITU) */ + osmo_ss7_instance_set_pc_fmt(s7i, 3, 8, 3); + s7i->cfg.pc_fmt.delimiter = '.'; +} + +static int test_user_prim_cb(struct osmo_prim_hdr *oph, void *priv) +{ + OSMO_ASSERT(priv == (void *) 0x1234); + + return 23; +} + +static void test_user(void) +{ + struct osmo_ss7_user user, user2; + struct osmo_mtp_prim omp = { + .oph = { + .sap = MTP_SAP_USER, + .primitive = OSMO_MTP_PRIM_TRANSFER, + .operation = PRIM_OP_INDICATION, + }, + .u.transfer = { + .sio = 1, + }, + }; + + printf("Testing SS7 user\n"); + + user.name = "testuser"; + user.priv = (void *) 0x1234; + user.prim_cb = test_user_prim_cb; + + /* registration */ + OSMO_ASSERT(osmo_ss7_user_register(s7i, 1, &user) == 0); + OSMO_ASSERT(osmo_ss7_user_register(s7i, 1, NULL) == -EBUSY); + OSMO_ASSERT(osmo_ss7_user_register(s7i, 255, NULL) == -EINVAL); + + /* primitive delivery */ + OSMO_ASSERT(osmo_ss7_mtp_to_user(s7i, &omp) == 23); + + /* cleanup */ + OSMO_ASSERT(osmo_ss7_user_unregister(s7i, 255, NULL) == -EINVAL); + OSMO_ASSERT(osmo_ss7_user_unregister(s7i, 10, NULL) == -ENODEV); + OSMO_ASSERT(osmo_ss7_user_unregister(s7i, 1, &user2) == -EINVAL); + OSMO_ASSERT(osmo_ss7_user_unregister(s7i, 1, &user) == 0); + + /* primitive delivery should fail now */ + OSMO_ASSERT(osmo_ss7_mtp_to_user(s7i, &omp) == -ENODEV); + + /* wrong primitive delivery should also fail */ + omp.oph.primitive = OSMO_MTP_PRIM_PAUSE; + OSMO_ASSERT(osmo_ss7_mtp_to_user(s7i, &omp) == -EINVAL); +} + +static void test_route(void) +{ + struct osmo_ss7_route_table *rtbl; + struct osmo_ss7_linkset *lset_a, *lset_b; + struct osmo_ss7_route *rt, *rt12, *rtdef; + + printf("Testing SS7 routing\n"); + + /* creation / destruction */ + OSMO_ASSERT(osmo_ss7_route_table_find(s7i, "foobar") == NULL); + rtbl = osmo_ss7_route_table_find_or_create(s7i, "foobar"); + OSMO_ASSERT(rtbl); + OSMO_ASSERT(osmo_ss7_route_table_find_or_create(s7i, "foobar") == rtbl); + osmo_ss7_route_table_destroy(rtbl); + OSMO_ASSERT(osmo_ss7_route_table_find(s7i, "foobar") == NULL); + + /* we now work with system route table */ + rtbl = osmo_ss7_route_table_find(s7i, "system"); + OSMO_ASSERT(rtbl && rtbl == s7i->rtable_system); + + lset_a = osmo_ss7_linkset_find_or_create(s7i, "a", 100); + OSMO_ASSERT(lset_a); + lset_b = osmo_ss7_linkset_find_or_create(s7i, "b", 200); + OSMO_ASSERT(lset_b); + + /* route with full mask */ + OSMO_ASSERT(osmo_ss7_route_find_dpc(rtbl, 12) == NULL); + rt = osmo_ss7_route_create(rtbl, 12, 0xffff, "a"); + OSMO_ASSERT(rt); + OSMO_ASSERT(osmo_ss7_route_find_dpc(rtbl, 12) == rt); + osmo_ss7_route_destroy(rt); + + /* route with partial mask */ + rt = osmo_ss7_route_create(rtbl, 8, 0xfff8, "a"); + OSMO_ASSERT(osmo_ss7_route_find_dpc(rtbl, 8) == rt); + OSMO_ASSERT(osmo_ss7_route_find_dpc(rtbl, 9) == rt); + OSMO_ASSERT(osmo_ss7_route_find_dpc(rtbl, 12) == rt); + OSMO_ASSERT(osmo_ss7_route_find_dpc(rtbl, 15) == rt); + OSMO_ASSERT(osmo_ss7_route_find_dpc(rtbl, 16) == NULL); + /* insert more specific route for 12, must have higher priority + * than existing one */ + rt12 = osmo_ss7_route_create(rtbl, 12, 0xffff, "b"); + OSMO_ASSERT(osmo_ss7_route_find_dpc(rtbl, 12) == rt12); + OSMO_ASSERT(osmo_ss7_route_find_dpc(rtbl, 15) == rt); + OSMO_ASSERT(osmo_ss7_route_find_dpc(rtbl, 16) == NULL); + /* add a default route, which should have lowest precedence */ + rtdef = osmo_ss7_route_create(rtbl, 0, 0, "a"); + OSMO_ASSERT(osmo_ss7_route_find_dpc(rtbl, 12) == rt12); + OSMO_ASSERT(osmo_ss7_route_find_dpc(rtbl, 15) == rt); + OSMO_ASSERT(osmo_ss7_route_find_dpc(rtbl, 16) == rtdef); + + osmo_ss7_route_destroy(rtdef); + osmo_ss7_route_destroy(rt12); + osmo_ss7_route_destroy(rt); + + osmo_ss7_linkset_destroy(lset_a); + osmo_ss7_linkset_destroy(lset_b); +} + +static void test_linkset(void) +{ + struct osmo_ss7_linkset *lset_a, *lset_b; + struct osmo_ss7_link *l_a1, *l_a2; + + printf("Testing SS7 linkset/link\n"); + + OSMO_ASSERT(osmo_ss7_linkset_find_by_name(s7i, "a") == NULL); + OSMO_ASSERT(osmo_ss7_linkset_find_by_name(s7i, "b") == NULL); + + lset_a = osmo_ss7_linkset_find_or_create(s7i, "a", 100); + OSMO_ASSERT(lset_a); + OSMO_ASSERT(osmo_ss7_linkset_find_by_name(s7i, "a") == lset_a); + + lset_b = osmo_ss7_linkset_find_or_create(s7i, "b", 200); + OSMO_ASSERT(lset_b); + OSMO_ASSERT(osmo_ss7_linkset_find_by_name(s7i, "b") == lset_b); + + l_a1 = osmo_ss7_link_find_or_create(lset_a, 1); + OSMO_ASSERT(l_a1); + l_a2 = osmo_ss7_link_find_or_create(lset_a, 2); + OSMO_ASSERT(l_a2); + + /* ID too high */ + OSMO_ASSERT(osmo_ss7_link_find_or_create(lset_a, 1000) == NULL); + /* already exists */ + OSMO_ASSERT(osmo_ss7_link_find_or_create(lset_a, 1) == l_a1); + + osmo_ss7_link_destroy(l_a1); + osmo_ss7_link_destroy(l_a2); + + osmo_ss7_linkset_destroy(lset_a); + osmo_ss7_linkset_destroy(lset_b); +} + +static void test_as(void) +{ + struct osmo_ss7_as *as; + struct osmo_ss7_asp *asp; + + OSMO_ASSERT(osmo_ss7_as_find_by_name(s7i, "as1") == NULL); + as = osmo_ss7_as_find_or_create(s7i, "as1", OSMO_SS7_ASP_PROT_M3UA); + OSMO_ASSERT(osmo_ss7_as_find_by_name(s7i, "as1") == as); + OSMO_ASSERT(osmo_ss7_as_find_by_rctx(s7i, 2342) == NULL); + as->cfg.routing_key.context = 2342; + OSMO_ASSERT(osmo_ss7_as_find_by_rctx(s7i, 2342) == as); + OSMO_ASSERT(osmo_ss7_as_add_asp(as, "asp1") == -ENODEV); + + asp = osmo_ss7_asp_find_or_create(s7i, "asp1", 0, M3UA_PORT, OSMO_SS7_ASP_PROT_M3UA); + OSMO_ASSERT(asp); + + OSMO_ASSERT(osmo_ss7_as_has_asp(as, asp) == false); + OSMO_ASSERT(osmo_ss7_as_add_asp(as, "asp1") == 0); + + osmo_ss7_asp_restart(asp); + + /* ask FSM to send ASP-UP.req */ + osmo_fsm_inst_dispatch(asp->fi, XUA_ASP_E_M_ASP_UP_REQ, NULL); + osmo_fsm_inst_dispatch(asp->fi, XUA_ASP_E_ASPSM_ASPUP_ACK, NULL); + osmo_fsm_inst_dispatch(asp->fi, XUA_ASP_E_ASPTM_ASPAC_ACK, NULL); + + OSMO_ASSERT(osmo_ss7_as_del_asp(as, "asp1") == 0); + OSMO_ASSERT(osmo_ss7_as_del_asp(as, "asp2") == -ENODEV); + OSMO_ASSERT(osmo_ss7_as_del_asp(as, "asp1") == -EINVAL); + + osmo_ss7_asp_destroy(asp); + osmo_ss7_as_destroy(as); + OSMO_ASSERT(osmo_ss7_as_find_by_name(s7i, "as1") == NULL); +} + +/*********************************************************************** + * Initialization + ***********************************************************************/ + +static const struct log_info_cat log_info_cat[] = { +}; + +static const struct log_info log_info = { + .cat = log_info_cat, + .num_cat = ARRAY_SIZE(log_info_cat), +}; + +static void init_logging(void) +{ + const int log_cats[] = { DLSS7, DLSUA, DLM3UA, DLSCCP, DLINP }; + unsigned int i; + + osmo_init_logging(&log_info); + + log_set_print_filename(osmo_stderr_target, 0); + + for (i = 0; i < ARRAY_SIZE(log_cats); i++) + log_set_category_filter(osmo_stderr_target, log_cats[i], 1, LOGL_DEBUG); +} + +int main(int argc, char **argv) +{ + init_logging(); + osmo_fsm_log_addr(false); + + /* init */ + osmo_ss7_init(); + s7i = osmo_ss7_instance_find_or_create(NULL, 0); + OSMO_ASSERT(osmo_ss7_instance_find(0) == s7i); + OSMO_ASSERT(osmo_ss7_instance_find(23) == NULL); + + /* test osmo_ss7_pc_is_local() */ + s7i->cfg.primary_pc = 55; + OSMO_ASSERT(osmo_ss7_pc_is_local(s7i, 55) == true); + OSMO_ASSERT(osmo_ss7_pc_is_local(s7i, 23) == false); + + /* further tests */ + test_pc_defaults(); + test_pc_parser_itu(); + test_pc_parser_ansi(); + test_user(); + test_route(); + test_linkset(); + test_as(); + + /* destroy */ + osmo_ss7_instance_destroy(s7i); + OSMO_ASSERT(osmo_ss7_instance_find(0) == NULL); + + exit(0); +} diff --git a/tests/ss7/ss7_test.err b/tests/ss7/ss7_test.err new file mode 100644 index 0000000..8823d1c --- /dev/null +++ b/tests/ss7/ss7_test.err @@ -0,0 +1,49 @@ +0: Creating SS7 Instance +0: Creating Route Table system +0: Point Code Format 8-8-8 is longer than 14 bits, odd? +registering user=testuser for SI 1 with priv 0x1234 +delivering MTP-TRANSFER.ind to user testuser, priv=0x1234 +No MTP-User for SI 1 +Unsupported Primitive +0: Creating Route Table foobar +0: Creating Linkset a +0: Creating Linkset b +0: Destroying Linkset a +0: Destroying Linkset b +0: Creating Linkset a +0: Creating Linkset b +0: Creating Link a:1 +0: Creating Link a:2 +0: Destroying Link a:1 +0: Destroying Link a:2 +0: Destroying Linkset a +0: Destroying Linkset b +0: Creating AS as1 +XUA_AS(as1){AS_DOWN}: Allocated +0: Adding ASP asp1 to AS as1 +0: Restarting ASP asp1 +unable to connect/bind socket: (null):0: Connection refused +connection closed +retrying in 5 seconds... +0: Unable to open stream client for ASP asp1 +XUA_ASP(asp1){ASP_DOWN}: Allocated +XUA_ASP(asp1){ASP_DOWN}: Received Event M-ASP_UP.req +XUA_ASP(asp1){ASP_DOWN}: Received Event ASPSM-ASP_UP_ACK +XUA_ASP(asp1){ASP_DOWN}: T(ack) stopped +XUA_ASP(asp1){ASP_DOWN}: state_chg to ASP_INACTIVE +XUA_ASP(asp1){ASP_INACTIVE}: Received Event M-ASP_ACTIVE.req +XUA_ASP(asp1){ASP_INACTIVE}: Received Event ASPTM-ASP_AC_ACK +XUA_ASP(asp1){ASP_INACTIVE}: T(ack) stopped +XUA_ASP(asp1){ASP_INACTIVE}: state_chg to ASP_ACTIVE +0: Removing ASP asp1 from AS as1 +0: Removing ASP asp1 from AS as1 +0: Destroying ASP asp1 +XUA_ASP(asp1){ASP_ACTIVE}: Terminating (cause = OSMO_FSM_TERM_REQUEST) +XUA_ASP(asp1){ASP_ACTIVE}: Freeing instance +XUA_ASP(asp1){ASP_ACTIVE}: Deallocated +0: Destroying AS as1 +XUA_AS(as1){AS_DOWN}: Terminating (cause = OSMO_FSM_TERM_REQUEST) +XUA_AS(as1){AS_DOWN}: Freeing instance +XUA_AS(as1){AS_DOWN}: Deallocated +0: Destroying SS7 Instance + \ No newline at end of file diff --git a/tests/ss7/ss7_test.ok b/tests/ss7/ss7_test.ok new file mode 100644 index 0000000..8aea63d --- /dev/null +++ b/tests/ss7/ss7_test.ok @@ -0,0 +1,27 @@ +Testing ITU-style point code format +test_pc_transcode(0) -> 0.0.0 -> 0 +test_pc_transcode(1) -> 0.0.1 -> 1 +test_pc_transcode(8) -> 0.1.0 -> 8 +test_pc_transcode(2048) -> 1.0.0 -> 2048 +test_pc_transcode(14336) -> 7.0.0 -> 14336 +test_pc_transcode(100) -> 0.12.4 -> 100 +test_pc_transcode(2342) -> 1.36.6 -> 2342 +test_pc_transcode(16383) -> 7.255.7 -> 16383 +mask /1 => 8192 (0x2000) 4.0.0 +mask 7.0.0 => 14336 (0x3800) 7.0.0 +mask /14 => 16383 (0x3fff) 7.255.7 +Testing ANSI-style point code format +test_pc_transcode(0) -> 0-0-0 -> 0 +test_pc_transcode(1) -> 0-0-1 -> 1 +test_pc_transcode(256) -> 0-1-0 -> 256 +test_pc_transcode(65536) -> 1-0-0 -> 65536 +test_pc_transcode(2048) -> 0-8-0 -> 2048 +test_pc_transcode(16777215) -> 255-255-255 -> 16777215 +test_pc_transcode(100) -> 0-0-100 -> 100 +test_pc_transcode(2342) -> 0-9-38 -> 2342 +mask /1 => 8388608 (0x800000) 128-0-0 +mask /16 => 16776960 (0xffff00) 255-255-0 +mask /24 => 16777215 (0xffffff) 255-255-255 +Testing SS7 user +Testing SS7 routing +Testing SS7 linkset/link diff --git a/tests/testsuite.at b/tests/testsuite.at index 8907ffa..171f488 100644 --- a/tests/testsuite.at +++ b/tests/testsuite.at @@ -18,3 +18,9 @@ cat $abs_srcdir/sccp/sccp_test.ok > expout AT_CHECK([$abs_top_builddir/tests/sccp/sccp_test], [], [expout], [ignore]) AT_CLEANUP + +AT_SETUP([ss7]) +AT_KEYWORDS([ss7]) +cat $abs_srcdir/ss7/ss7_test.ok > expout +AT_CHECK([$abs_top_builddir/tests/ss7/ss7_test], [], [expout], [ignore]) +AT_CLEANUP -- To view, visit https://gerrit.osmocom.org/2209 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I375eb80f01acc013094851d91d1d3333ebc12bc7 Gerrit-PatchSet: 3 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:31:09 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:31:09 +0000 Subject: [PATCH] libosmo-sccp[master]: sua: Make use of xua_msg_dialect In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2210 to look at the new patch set (#4). sua: Make use of xua_msg_dialect We fill in the data structures of a xua_msg_dialect and make use of it for generic mandatory IE checking and messageheader printing. Change-Id: I966103f30b9be247ba6905ba8e06b87654d9981a --- M src/sua.c 1 file changed, 162 insertions(+), 112 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/10/2210/4 diff --git a/src/sua.c b/src/sua.c index 145bf1a..659104c 100644 --- a/src/sua.c +++ b/src/sua.c @@ -37,6 +37,8 @@ #include #include +#include "xua_internal.h" + #define SUA_MSGB_SIZE 1500 /* Appendix C.4 of Q.714 (all in milliseconds) */ @@ -48,6 +50,161 @@ #define INT_TIMER ( 1 * 60 * 100) #define GUARD_TIMER (23 * 60 * 100) #define RESET_TIMER ( 10 * 100) + +/*********************************************************************** + * Protocol Definition (string tables, mandatory IE checking) + ***********************************************************************/ + +static const struct value_string sua_iei_names[] = { + { SUA_IEI_ROUTE_CTX, "Routing Context" }, + { SUA_IEI_CORR_ID, "Correlation Id" }, + { SUA_IEI_REG_RESULT, "Registration Result" }, + { SUA_IEI_DEREG_RESULT, "De-Registration Result" }, + + { SUA_IEI_S7_HOP_CTR, "SS7 Hop Counter" }, + { SUA_IEI_SRC_ADDR, "Source Address" }, + { SUA_IEI_DEST_ADDR, "Destination Address" }, + { SUA_IEI_SRC_REF, "Source Reference" }, + { SUA_IEI_DEST_REF, "Destination Reference" }, + { SUA_IEI_CAUSE, "Cause" }, + { SUA_IEI_SEQ_NR, "Sequence Number" }, + { SUA_IEI_RX_SEQ_NR, "Receive Sequence Number" }, + { SUA_IEI_ASP_CAPA, "ASP Capability" }, + { SUA_IEI_CREDIT, "Credit" }, + { SUA_IEI_DATA, "Data" }, + { SUA_IEI_USER_CAUSE, "User/Cause" }, + { SUA_IEI_NET_APPEARANCE, "Network Appearance" }, + { SUA_IEI_ROUTING_KEY, "Routing Key" }, + { SUA_IEI_DRN, "DRN Label" }, + { SUA_IEI_TID, "TID Label" }, + { SUA_IEI_SMI, "SMI" }, + { SUA_IEI_IMPORTANCE, "Importance" }, + { SUA_IEI_MSG_PRIO, "Message Priority" }, + { SUA_IEI_PROTO_CLASS, "Protocol Class" }, + { SUA_IEI_SEQ_CTRL, "Sequence Control" }, + { SUA_IEI_SEGMENTATION, "Segmentation" }, + { SUA_IEI_CONG_LEVEL, "Congestion Level" }, + + { SUA_IEI_GT, "Global Title" }, + { SUA_IEI_PC, "Point Code" }, + { SUA_IEI_SSN, "Sub-System Number" }, + { SUA_IEI_IPv4, "IPv4 Address" }, + { SUA_IEI_HOST, "Host Name" }, + { SUA_IEI_IPv6, "IPv6 Address" }, + { 0, NULL } +}; + +#define MAND_IES(msgt, ies) [msgt] = (ies) + +static const uint16_t cldt_mand_ies[] = { + SUA_IEI_ROUTE_CTX, SUA_IEI_PROTO_CLASS, SUA_IEI_SRC_ADDR, + SUA_IEI_DEST_ADDR, SUA_IEI_SEQ_CTRL, SUA_IEI_DATA, 0 +}; +static const uint16_t cldr_mand_ies[] = { + SUA_IEI_ROUTE_CTX, SUA_IEI_CAUSE, SUA_IEI_SRC_ADDR, + SUA_IEI_DEST_ADDR, 0 +}; +static const struct value_string sua_cl_msgt_names[] = { + { SUA_CL_CLDT, "CLDT" }, + { SUA_CL_CLDR, "CLDR" }, + { 0, NULL } +}; +static const struct xua_msg_class msg_class_cl = { + .name = "CL", + .msgt_names = sua_cl_msgt_names, + .iei_names = sua_iei_names, + .mand_ies = { + MAND_IES(SUA_CL_CLDT, cldt_mand_ies), + MAND_IES(SUA_CL_CLDR, cldr_mand_ies), + }, +}; + +static const uint16_t codt_mand_ies[] = { + SUA_IEI_ROUTE_CTX, SUA_IEI_DEST_REF, SUA_IEI_DATA, 0 +}; +static const uint16_t coda_mand_ies[] = { + SUA_IEI_ROUTE_CTX, SUA_IEI_DEST_REF, 0 +}; +static const uint16_t core_mand_ies[] = { + SUA_IEI_ROUTE_CTX, SUA_IEI_PROTO_CLASS, SUA_IEI_SRC_REF, + SUA_IEI_DEST_ADDR, SUA_IEI_SEQ_CTRL, 0 +}; +static const uint16_t coak_mand_ies[] = { + SUA_IEI_ROUTE_CTX, SUA_IEI_PROTO_CLASS, SUA_IEI_DEST_REF, + SUA_IEI_SRC_REF, SUA_IEI_SEQ_CTRL, 0 +}; +static const uint16_t coref_mand_ies[] = { + SUA_IEI_ROUTE_CTX, SUA_IEI_DEST_REF, SUA_IEI_CAUSE, 0 +}; +static const uint16_t relre_mand_ies[] = { + SUA_IEI_ROUTE_CTX, SUA_IEI_DEST_REF, SUA_IEI_SRC_REF, + SUA_IEI_CAUSE, 0 +}; +static const uint16_t relco_mand_ies[] = { + SUA_IEI_ROUTE_CTX, SUA_IEI_DEST_REF, SUA_IEI_SRC_REF, 0 +}; +static const uint16_t resre_mand_ies[] = { + SUA_IEI_ROUTE_CTX, SUA_IEI_DEST_REF, SUA_IEI_SRC_REF, + SUA_IEI_CAUSE, 0 +}; +static const uint16_t resco_mand_ies[] = { + SUA_IEI_ROUTE_CTX, SUA_IEI_DEST_REF, SUA_IEI_SRC_REF, 0 +}; +static const uint16_t coerr_mand_ies[] = { + SUA_IEI_ROUTE_CTX, SUA_IEI_DEST_REF, SUA_IEI_CAUSE, 0 +}; +static const uint16_t coit_mand_ies[] = { + SUA_IEI_ROUTE_CTX, SUA_IEI_PROTO_CLASS, SUA_IEI_SRC_REF, + SUA_IEI_DEST_REF, 0 +}; +static const struct value_string sua_co_msgt_names[] = { + { SUA_CO_CODT, "CODT" }, + { SUA_CO_CODA, "CODA" }, + { SUA_CO_CORE, "CORE" }, + { SUA_CO_COAK, "COAK" }, + { SUA_CO_COREF, "COREF" }, + { SUA_CO_RELRE, "RELRE" }, + { SUA_CO_RELCO, "RELCO" }, + { SUA_CO_RESRE, "RESRE" }, + { SUA_CO_RESCO, "RESCO" }, + { SUA_CO_COERR, "COERR" }, + { SUA_CO_COIT, "COIT" }, + { 0, NULL } +}; +static const struct xua_msg_class msg_class_co = { + .name = "CO", + .msgt_names = sua_co_msgt_names, + .iei_names = sua_iei_names, + .mand_ies = { + MAND_IES(SUA_CO_CODT, codt_mand_ies), + MAND_IES(SUA_CO_CODA, coda_mand_ies), + MAND_IES(SUA_CO_CORE, core_mand_ies), + MAND_IES(SUA_CO_COAK, coak_mand_ies), + MAND_IES(SUA_CO_COREF, coref_mand_ies), + MAND_IES(SUA_CO_RELRE, relre_mand_ies), + MAND_IES(SUA_CO_RELCO, relco_mand_ies), + MAND_IES(SUA_CO_RESRE, resre_mand_ies), + MAND_IES(SUA_CO_RESCO, resco_mand_ies), + MAND_IES(SUA_CO_COERR, coerr_mand_ies), + MAND_IES(SUA_CO_COIT, coit_mand_ies), + }, +}; + +const struct xua_dialect xua_dialect_sua = { + .name = "SUA", + .ppid = SUA_PPID, + .port = SUA_PORT, + .class = { + [SUA_MSGC_MGMT] = &m3ua_msg_class_mgmt, + [SUA_MSGC_SNM] = &m3ua_msg_class_snm, + [SUA_MSGC_ASPSM] = &m3ua_msg_class_aspsm, + [SUA_MSGC_ASPTM] = &m3ua_msg_class_asptm, + [SUA_MSGC_CL] = &msg_class_cl, + [SUA_MSGC_CO] = &msg_class_co, + [SUA_MSGC_RKM] = &m3ua_msg_class_rkm, + }, +}; + static int DSUA = -1; @@ -531,110 +688,6 @@ return rc; } - -/*********************************************************************** - * Mandatory IE checking - ***********************************************************************/ - -#define MAND_IES(msgt, ies) [msgt] = (ies) - -static const uint16_t cldt_mand_ies[] = { - SUA_IEI_ROUTE_CTX, SUA_IEI_PROTO_CLASS, SUA_IEI_SRC_ADDR, - SUA_IEI_DEST_ADDR, SUA_IEI_SEQ_CTRL, SUA_IEI_DATA, 0 -}; - -static const uint16_t cldr_mand_ies[] = { - SUA_IEI_ROUTE_CTX, SUA_IEI_CAUSE, SUA_IEI_SRC_ADDR, - SUA_IEI_DEST_ADDR, 0 -}; - -static const uint16_t codt_mand_ies[] = { - SUA_IEI_ROUTE_CTX, SUA_IEI_DEST_REF, SUA_IEI_DATA, 0 -}; - -static const uint16_t coda_mand_ies[] = { - SUA_IEI_ROUTE_CTX, SUA_IEI_DEST_REF, 0 -}; - -static const uint16_t core_mand_ies[] = { - SUA_IEI_ROUTE_CTX, SUA_IEI_PROTO_CLASS, SUA_IEI_SRC_REF, - SUA_IEI_DEST_ADDR, SUA_IEI_SEQ_CTRL, 0 -}; - -static const uint16_t coak_mand_ies[] = { - SUA_IEI_ROUTE_CTX, SUA_IEI_PROTO_CLASS, SUA_IEI_DEST_REF, - SUA_IEI_SRC_REF, SUA_IEI_SEQ_CTRL, 0 -}; - -static const uint16_t coref_mand_ies[] = { - SUA_IEI_ROUTE_CTX, SUA_IEI_DEST_REF, SUA_IEI_CAUSE, 0 -}; - -static const uint16_t relre_mand_ies[] = { - SUA_IEI_ROUTE_CTX, SUA_IEI_DEST_REF, SUA_IEI_SRC_REF, - SUA_IEI_CAUSE, 0 -}; - -static const uint16_t relco_mand_ies[] = { - SUA_IEI_ROUTE_CTX, SUA_IEI_DEST_REF, SUA_IEI_SRC_REF, 0 -}; - -static const uint16_t resre_mand_ies[] = { - SUA_IEI_ROUTE_CTX, SUA_IEI_DEST_REF, SUA_IEI_SRC_REF, - SUA_IEI_CAUSE, 0 -}; - -static const uint16_t resco_mand_ies[] = { - SUA_IEI_ROUTE_CTX, SUA_IEI_DEST_REF, SUA_IEI_SRC_REF, 0 -}; - -static const uint16_t coerr_mand_ies[] = { - SUA_IEI_ROUTE_CTX, SUA_IEI_DEST_REF, SUA_IEI_CAUSE, 0 -}; - -static const uint16_t coit_mand_ies[] = { - SUA_IEI_ROUTE_CTX, SUA_IEI_PROTO_CLASS, SUA_IEI_SRC_REF, - SUA_IEI_DEST_REF, 0 -}; - -static const uint16_t *mand_ies_cl[256] = { - MAND_IES(SUA_CL_CLDT, cldt_mand_ies), - MAND_IES(SUA_CL_CLDR, cldr_mand_ies), -}; - -static const uint16_t *mand_ies_co[256] = { - MAND_IES(SUA_CO_CODT, codt_mand_ies), - MAND_IES(SUA_CO_CODA, coda_mand_ies), - MAND_IES(SUA_CO_CORE, core_mand_ies), - MAND_IES(SUA_CO_COAK, coak_mand_ies), - MAND_IES(SUA_CO_COREF, coref_mand_ies), - MAND_IES(SUA_CO_RELRE, relre_mand_ies), - MAND_IES(SUA_CO_RELCO, relco_mand_ies), - MAND_IES(SUA_CO_RESRE, resre_mand_ies), - MAND_IES(SUA_CO_RESCO, resco_mand_ies), - MAND_IES(SUA_CO_COERR, coerr_mand_ies), - MAND_IES(SUA_CO_COIT, coit_mand_ies), -}; - -static int check_all_mand_ies(const uint16_t **mand_ies, struct xua_msg *xua) -{ - uint8_t msg_type = xua->hdr.msg_type; - const uint16_t *ies = mand_ies[msg_type]; - uint16_t ie; - - for (ie = *ies; ie; ie = *ies++) { - if (!xua_msg_find_tag(xua, ie)) { - LOGP(DSUA, LOGL_ERROR, "SUA Message %u:%u should " - "contain IE 0x%04x, but doesn't\n", - xua->hdr.msg_class, msg_type, ie); - return 0; - } - } - - return 1; -} - - /*********************************************************************** * Receiving SUA messsages from SCTP ***********************************************************************/ @@ -772,9 +825,6 @@ struct xua_msg *xua, struct msgb *msg) { int rc = -1; - - if (!check_all_mand_ies(mand_ies_cl, xua)) - return -1; switch (xua->hdr.msg_type) { case SUA_CL_CLDT: @@ -1094,9 +1144,6 @@ { int rc = -1; - if (!check_all_mand_ies(mand_ies_co, xua)) - return -1; - switch (xua->hdr.msg_type) { case SUA_CO_CORE: rc = sua_rx_core(link, xua); @@ -1142,8 +1189,11 @@ return -EIO; } - LOGP(DSUA, LOGL_DEBUG, "Received SUA Message (%u:%u)\n", - xua->hdr.msg_class, xua->hdr.msg_type); + LOGP(DSUA, LOGL_DEBUG, "Received SUA Message (%s)\n", + xua_hdr_dump(xua, &xua_dialect_sua)); + + if (!xua_dialect_check_all_mand_ies(&xua_dialect_sua, xua)) + return -1; switch (xua->hdr.msg_class) { case SUA_MSGC_CL: -- To view, visit https://gerrit.osmocom.org/2210 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I966103f30b9be247ba6905ba8e06b87654d9981a Gerrit-PatchSet: 4 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:31:09 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:31:09 +0000 Subject: [PATCH] libosmo-sccp[master]: sua: Extend address parsing with GT, RI and IPv4 support In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2211 to look at the new patch set (#4). sua: Extend address parsing with GT, RI and IPv4 support Change-Id: I186df77cbdbedfe1a60b855be3626b6766f4681c --- M src/sua.c 1 file changed, 104 insertions(+), 26 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/11/2211/4 diff --git a/src/sua.c b/src/sua.c index 659104c..de4a4e8 100644 --- a/src/sua.c +++ b/src/sua.c @@ -692,11 +692,51 @@ * Receiving SUA messsages from SCTP ***********************************************************************/ -static int sua_parse_addr(struct osmo_sccp_addr *out, - struct xua_msg *xua, - uint16_t iei) +/*! \brief Decode SUA Global Title according to RFC3868 3.10.2.3 + * \param[out] gt User-allocated structure for decoded output + * \param[in] data binary-encoded data + * \param[in] datalen length of \ref data in octets + */ +int sua_parse_gt(struct osmo_sccp_gt *gt, const uint8_t *data, unsigned int datalen) { - const struct xua_msg_part *param = xua_msg_find_tag(xua, iei); + uint8_t num_digits; + char *out_digits; + unsigned int i; + + /* 8 byte header at minimum, plus digits */ + if (datalen < 8) + return -EINVAL; + + /* parse header */ + gt->gti = data[3]; + num_digits = data[4]; + gt->tt = data[5]; + gt->npi = data[6]; + gt->nai = data[7]; + + /* parse digits */ + out_digits = gt->digits; + for (i = 0; i < datalen-8; i++) { + uint8_t byte = data[8+i]; + *out_digits++ = osmo_bcd2char(byte & 0x0F); + if (out_digits - gt->digits >= num_digits) + break; + *out_digits++ = osmo_bcd2char(byte >> 4); + if (out_digits - gt->digits >= num_digits) + break; + } + *out_digits++ = '\0'; + + return 0; +} + +/*! \brief parse SCCP address from given xUA message part + * \param[out] out caller-allocated decoded SCCP address struct + * \param[in] param xUA message part containing address + \returns 0 on success; negative on error */ +int sua_addr_parse_part(struct osmo_sccp_addr *out, + const struct xua_msg_part *param) +{ const struct xua_parameter_hdr *par; uint16_t ri; uint16_t ai; @@ -704,16 +744,15 @@ uint16_t par_tag, par_len, par_datalen; uint32_t *p32; - if (!param) - return -ENODEV; + memset(out, 0, sizeof(*out)); - LOGP(DSUA, LOGL_DEBUG, "sua_parse_addr(IEI=%d) (%d) %s\n", - iei, param->len, + LOGP(DSUA, LOGL_DEBUG, "%s(IEI=0x%04x) (%d) %s\n", __func__, + param->tag, param->len, osmo_hexdump(param->dat, param->len)); if (param->len < 4) { - LOGP(DSUA, LOGL_ERROR, "SUA IEI %d: invalid address length: %d\n", - iei, param->len); + LOGP(DSUA, LOGL_ERROR, "SUA IEI 0x%04x: invalid address length: %d\n", + param->tag, param->len); return -EINVAL; } @@ -723,16 +762,29 @@ ai = ntohs(*(uint16_t*) ¶m->dat[pos]); pos += 2; - if (ri != SUA_RI_SSN_PC) { - LOGP(DSUA, LOGL_ERROR, "SUA IEI %d: Routing Indicator not supported yet: %d\n", - iei, ri); + switch (ri) { + case SUA_RI_GT: + out->ri = OSMO_SCCP_RI_GT; + break; + case SUA_RI_SSN_PC: + out->ri = OSMO_SCCP_RI_SSN_PC; + break; + case SUA_RI_SSN_IP: + out->ri = OSMO_SCCP_RI_SSN_IP; + break; + case SUA_RI_HOST: + default: + LOGP(DSUA, LOGL_ERROR, "SUA IEI 0x%04x: Routing Indicator not supported yet: %d\n", + param->tag, ri); return -ENOTSUP; } if (ai != 7) { - LOGP(DSUA, LOGL_ERROR, "SUA IEI %d: Address Indicator not supported yet: %x\n", - iei, ai); +#if 0 + LOGP(DSUA, LOGL_ERROR, "SUA IEI 0x%04x: Address Indicator not supported yet: %x\n", + param->tag, ai); return -ENOTSUP; +#endif } /* @@ -749,8 +801,8 @@ par_len = ntohs(par->len); par_datalen = par_len - sizeof(*par); - LOGP(DSUA, LOGL_DEBUG, "SUA IEI %hu pos %hu/%hu: subpart tag %hu, len %hu\n", - iei, pos, param->len, par->tag, par->len); + LOGP(DSUA, LOGL_DEBUG, "SUA IEI 0x%04x pos %hu/%hu: subpart tag 0x%04x, len %hu\n", + param->tag, pos, param->len, par_tag, par_len); switch (par_tag) { case SUA_IEI_PC: @@ -768,12 +820,22 @@ out->presence |= OSMO_SCCP_ADDR_T_SSN; break; case SUA_IEI_GT: - /* TODO */ + if (par_datalen < 8) + goto subpar_fail; + sua_parse_gt(&out->gt, par->data, par_datalen); out->presence |= OSMO_SCCP_ADDR_T_GT; break; + case SUA_IEI_IPv4: + if (par_datalen != 4) + goto subpar_fail; + p32 = (uint32_t*)par->data; + /* no endian conversion, both network order */ + out->ip.v4.s_addr = *p32; + out->presence |= OSMO_SCCP_ADDR_T_IPv4; + break; default: - LOGP(DSUA, LOGL_ERROR, "SUA IEI %d: Unknown subpart tag %hd\n", - iei, par_tag); + LOGP(DSUA, LOGL_ERROR, "SUA IEI 0x%04x: Unknown subpart tag %hd\n", + param->tag, par_tag); goto subpar_fail; } @@ -783,9 +845,25 @@ return 0; subpar_fail: - LOGP(DSUA, LOGL_ERROR, "Failed to parse subparts of address IEI=%d\n", - iei); + LOGP(DSUA, LOGL_ERROR, "Failed to parse subparts of address IEI=0x%04x\n", + param->tag); return -EINVAL; +} + +/*! \brief parse SCCP address from given xUA message IE + * \param[out] out caller-allocated decoded SCCP address struct + * \param[in] xua xUA message + * \param[in] iei Information Element Identifier inside \ref xua + \returns 0 on success; negative on error */ +int sua_addr_parse(struct osmo_sccp_addr *out, struct xua_msg *xua, uint16_t iei) +{ + const struct xua_msg_part *param = xua_msg_find_tag(xua, iei); + if (!param) { + memset(out, 0, sizeof(*out)); + return -ENODEV; + } + + return sua_addr_parse_part(out, param); } static int sua_rx_cldt(struct osmo_sccp_link *link, struct xua_msg *xua) @@ -802,8 +880,8 @@ osmo_prim_init(&prim->oph, SCCP_SAP_USER, OSMO_SCU_PRIM_N_UNITDATA, PRIM_OP_INDICATION, upmsg); - sua_parse_addr(¶m->called_addr, xua, SUA_IEI_DEST_ADDR); - sua_parse_addr(¶m->calling_addr, xua, SUA_IEI_SRC_ADDR); + sua_addr_parse(¶m->called_addr, xua, SUA_IEI_DEST_ADDR); + sua_addr_parse(¶m->calling_addr, xua, SUA_IEI_SRC_ADDR); param->in_sequence_control = xua_msg_get_u32(xua, SUA_IEI_SEQ_CTRL); protocol_class = xua_msg_get_u32(xua, SUA_IEI_PROTO_CLASS); param->return_option = protocol_class & 0x80; @@ -849,8 +927,8 @@ /* fill conn */ conn = conn_create(link); - sua_parse_addr(&conn->called_addr, xua, SUA_IEI_DEST_ADDR); - sua_parse_addr(&conn->calling_addr, xua, SUA_IEI_SRC_ADDR); + sua_addr_parse(&conn->called_addr, xua, SUA_IEI_DEST_ADDR); + sua_addr_parse(&conn->calling_addr, xua, SUA_IEI_SRC_ADDR); conn->remote_ref = xua_msg_get_u32(xua, SUA_IEI_SRC_REF); /* fill primitive */ -- To view, visit https://gerrit.osmocom.org/2211 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I186df77cbdbedfe1a60b855be3626b6766f4681c Gerrit-PatchSet: 4 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:31:09 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:31:09 +0000 Subject: [PATCH] libosmo-sccp[master]: sua.c: Replace sua_msgb_alloc() with new sccp_msgb_alloc() In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2212 to look at the new patch set (#4). sua.c: Replace sua_msgb_alloc() with new sccp_msgb_alloc() Change-Id: I7067a85dcc5dda66f4b17b0fe08da8cb3efe79ef --- M src/Makefile.am A src/sccp_internal.h M src/sua.c 3 files changed, 24 insertions(+), 15 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/12/2212/4 diff --git a/src/Makefile.am b/src/Makefile.am index f7f4ccc..ec3fe99 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,7 +1,7 @@ AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir) AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMONETIF_CFLAGS) -noinst_HEADERS = xua_asp_fsm.h xua_as_fsm.h xua_internal.h +noinst_HEADERS = sccp_internal.h xua_asp_fsm.h xua_as_fsm.h xua_internal.h # Legacy static libs diff --git a/src/sccp_internal.h b/src/sccp_internal.h new file mode 100644 index 0000000..7287a82 --- /dev/null +++ b/src/sccp_internal.h @@ -0,0 +1,5 @@ +#pragma once + +#include + +struct msgb *sccp_msgb_alloc(const char *name); diff --git a/src/sua.c b/src/sua.c index de4a4e8..b8bb2f5 100644 --- a/src/sua.c +++ b/src/sua.c @@ -51,6 +51,17 @@ #define GUARD_TIMER (23 * 60 * 100) #define RESET_TIMER ( 10 * 100) +#define SCCP_MSG_SIZE 2048 +#define SCCP_MSG_HEADROOM 512 + +struct msgb *sccp_msgb_alloc(const char *name) +{ + if (!name) + name = "SCCP"; + return msgb_alloc_headroom(SCCP_MSG_SIZE+SCCP_MSG_HEADROOM, + SCCP_MSG_HEADROOM, name); +} + /*********************************************************************** * Protocol Definition (string tables, mandatory IE checking) ***********************************************************************/ @@ -431,13 +442,6 @@ conn_restart_tx_inact_timer(conn); conn_restart_rx_inact_timer(conn); } - - -static struct msgb *sua_msgb_alloc(void) -{ - return msgb_alloc(SUA_MSGB_SIZE, "SUA Primitive"); -} - /*********************************************************************** * Handling of messages from the User SAP @@ -871,7 +875,7 @@ struct osmo_scu_prim *prim; struct osmo_scu_unitdata_param *param; struct xua_msg_part *data_ie = xua_msg_find_tag(xua, SUA_IEI_DATA); - struct msgb *upmsg = sua_msgb_alloc(); + struct msgb *upmsg = sccp_msgb_alloc(__func__); uint32_t protocol_class; /* fill primitive */ @@ -932,7 +936,7 @@ conn->remote_ref = xua_msg_get_u32(xua, SUA_IEI_SRC_REF); /* fill primitive */ - upmsg = sua_msgb_alloc(); + upmsg = sccp_msgb_alloc(__func__); prim = (struct osmo_scu_prim *) msgb_put(upmsg, sizeof(*prim)); param = &prim->u.connect; osmo_prim_init(&prim->oph, SCCP_SAP_USER, @@ -992,7 +996,7 @@ conn->remote_ref = xua_msg_get_u32(xua, SUA_IEI_SRC_REF); /* fill primitive */ - upmsg = sua_msgb_alloc(); + upmsg = sccp_msgb_alloc(__func__); prim = (struct osmo_scu_prim *) msgb_put(upmsg, sizeof(*prim)); param = &prim->u.connect; osmo_prim_init(&prim->oph, SCCP_SAP_USER, @@ -1044,7 +1048,7 @@ conn_restart_rx_inact_timer(conn); /* fill primitive */ - upmsg = sua_msgb_alloc(); + upmsg = sccp_msgb_alloc(__func__); prim = (struct osmo_scu_prim *) msgb_put(upmsg, sizeof(*prim)); param = &prim->u.disconnect; osmo_prim_init(&prim->oph, SCCP_SAP_USER, @@ -1095,7 +1099,7 @@ } /* fill primitive */ - upmsg = sua_msgb_alloc(); + upmsg = sccp_msgb_alloc(__func__); prim = (struct osmo_scu_prim *) msgb_put(upmsg, sizeof(*prim)); param = &prim->u.disconnect; osmo_prim_init(&prim->oph, SCCP_SAP_USER, @@ -1144,7 +1148,7 @@ conn_restart_rx_inact_timer(conn); /* fill primitive */ - upmsg = sua_msgb_alloc(); + upmsg = sccp_msgb_alloc(__func__); prim = (struct osmo_scu_prim *) msgb_put(upmsg, sizeof(*prim)); param = &prim->u.disconnect; osmo_prim_init(&prim->oph, SCCP_SAP_USER, @@ -1196,7 +1200,7 @@ conn_restart_rx_inact_timer(conn); /* fill primitive */ - upmsg = sua_msgb_alloc(); + upmsg = sccp_msgb_alloc(__func__); prim = (struct osmo_scu_prim *) msgb_put(upmsg, sizeof(*prim)); param = &prim->u.data; osmo_prim_init(&prim->oph, SCCP_SAP_USER, -- To view, visit https://gerrit.osmocom.org/2212 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I7067a85dcc5dda66f4b17b0fe08da8cb3efe79ef Gerrit-PatchSet: 4 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:31:09 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:31:09 +0000 Subject: [PATCH] libosmo-sccp[master]: Add SCCP <-> SUA message transcoding routines In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2213 to look at the new patch set (#4). Add SCCP <-> SUA message transcoding routines Change-Id: I8151a9b08a0b0ca97b9c73105ad4548512ce3be8 --- M src/Makefile.am A src/sccp2sua.c 2 files changed, 1,266 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/13/2213/4 diff --git a/src/Makefile.am b/src/Makefile.am index ec3fe99..4455127 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -27,6 +27,7 @@ LIBVERSION=0:0:0 libosmo_sigtran_la_SOURCES = sccp_sap.c sua.c m3ua.c xua_msg.c sccp_helpers.c \ + sccp2sua.c \ osmo_ss7.c osmo_ss7_hmrt.c xua_asp_fsm.c xua_as_fsm.c libosmo_sigtran_la_LDFLAGS = -version-info $(LIBVERSION) -no-undefined -export-symbols-regex '^osmo_' libosmo_sigtran_la_LIBADD = $(LIBOSMOCORE_LIBS) $(LIBOSMONETIF_LIBS) $(LIBSCTP_LIBS) diff --git a/src/sccp2sua.c b/src/sccp2sua.c new file mode 100644 index 0000000..070a8cb --- /dev/null +++ b/src/sccp2sua.c @@ -0,0 +1,1265 @@ +/* SCCP <-> SUA transcoding routines */ + +/* (C) 2017 by Harald Welte + * All Rights Reserved + * + * based on my 2011 Erlang implementation osmo_ss7/src/sua_sccp_conv.erl + * + * References: ITU-T Q.713 and IETF RFC 3868 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "xua_internal.h" +#include "sccp_internal.h" + +/* libosmocore candidates */ + +static void msgb_put_u24be(struct msgb *msg, uint32_t val) +{ + msgb_put_u8(msg, (val >> 16) & 0xff); + msgb_put_u8(msg, (val >> 8) & 0xff); + msgb_put_u8(msg, val & 0xff); +} + +static void msgb_put_u16le(struct msgb *msg, uint16_t val) +{ + msgb_put_u8(msg, val & 0xff); + msgb_put_u8(msg, (val >> 8) & 0xff); +} + +/*! \brief load a 24bit value as big-endian */ +static uint32_t load_24be(const void *ptr) +{ + const uint8_t *data = ptr; + return (data[0] << 16) | (data[1] << 8) | data[2]; +} + + + +/*! \brief Parse ISUP style address of BCD digets + * \param[out] out_digits user-allocated buffer for ASCII digits + * \param[in] in BCD-encoded digits + * \param[in] in_num_bytes Size of \ref in in bytes + * \param[in] odd Odd (true) or even (false) number of digits + * \returns number of digits generated + * */ +int osmo_isup_party_parse(char *out_digits, const uint8_t *in, + unsigned int in_num_bytes, bool odd) +{ + char *out = out_digits; + unsigned int i; + + for (i = 0; i < in_num_bytes; i++) { + *out_digits++ = osmo_bcd2char(in[i] & 0x0F); + if (i+1 == in_num_bytes && odd) + break; + *out_digits++ = osmo_bcd2char(in[i] >> 4); + } + *out_digits = '\0'; + return (out_digits - out); +} + +/*! \brief Encode an ISUP style address of BCD digits + * \param[out] msg Message to which the encoded address is appended + * \param[in] in_digits NUL-terminated ASCII string of digits + * \returns number of octets used for encoding \ref in_digits */ +int osmo_isup_party_encode(struct msgb *msg, const char *in_digits) +{ + unsigned int num_digits = strlen(in_digits); + unsigned int i, num_octets = num_digits/2; + const char *cur_digit = in_digits; + uint8_t *cur; + + if (num_digits & 1) + num_octets++; + + cur = msgb_put(msg, num_octets); + + for (i = 0; i < num_octets; i++) { + cur[i] = osmo_char2bcd(*cur_digit++); + if (cur_digit - in_digits < num_digits) + cur[i] |= osmo_char2bcd(*cur_digit++) << 4; + } + return num_octets; +} + +/*! \brief Parse wire-encoded SCCP address into omso_sccp_addr + * \param[out] out user-allocated output data structure + * \param[in] addr wire-encoded SCCP address + * \param[in] addrlen Size of \ref addr in bytes + * \returns 0 in case of success, negative on error + * According to Q.713/3.4 and RFC3868/3.10.2 */ +int osmo_sccp_addr_parse(struct osmo_sccp_addr *out, + const uint8_t *addr, unsigned int addrlen) +{ + struct sccp_called_party_address *sca; + uint8_t *cur; + uint8_t encoding; + bool odd; + int rc; + + memset(out, 0, sizeof(*out)); + + sca = (struct sccp_called_party_address *) addr; + cur = sca->data; + + if (sca->routing_indicator) + out->ri = OSMO_SCCP_RI_SSN_PC; + else + out->ri = OSMO_SCCP_RI_GT; + + if (sca->point_code_indicator) { + out->presence |= OSMO_SCCP_ADDR_T_PC; + out->pc = ((cur[1] << 8) & 0x3f) | cur[0]; + cur += 2; + } + + if (sca->ssn_indicator) { + out->presence |= OSMO_SCCP_ADDR_T_SSN; + out->ssn = *cur; + cur += 1; + } + + switch (sca->global_title_indicator) { + case SCCP_TITLE_IND_NONE: + out->gt.gti = OSMO_SCCP_GTI_NO_GT; + return 0; + case SCCP_TITLE_IND_NATURE_ONLY: + out->presence |= OSMO_SCCP_ADDR_T_GT; + out->gt.gti = OSMO_SCCP_GTI_NAI_ONLY; + out->gt.nai = *cur & 0x7f; + if (*cur++ & 0x80) + odd = true; + else + odd = false; + break; + case SCCP_TITLE_IND_TRANSLATION_ONLY: + out->presence |= OSMO_SCCP_ADDR_T_GT; + out->gt.gti = OSMO_SCCP_GTI_TT_ONLY; + out->gt.tt = *cur++; + /* abort, for national use only */ + return -EINVAL; + case SCCP_TITLE_IND_TRANS_NUM_ENC: + out->presence |= OSMO_SCCP_ADDR_T_GT; + out->gt.gti = OSMO_SCCP_GTI_TT_NPL_ENC; + out->gt.tt = *cur++; + out->gt.npi = *cur >> 4; + switch (*cur++ & 0xF) { + case 1: + odd = true; + break; + case 2: + odd = false; + break; + default: + return -1; + } + break; + case SCCP_TITLE_IND_TRANS_NUM_ENC_NATURE: + out->presence |= OSMO_SCCP_ADDR_T_GT; + out->gt.gti = OSMO_SCCP_GTI_TT_NPL_ENC_NAI; + out->gt.tt = *cur++; + out->gt.npi = *cur >> 4; + encoding = *cur++ & 0xF; + switch (encoding) { + case 1: + odd = true; + break; + case 2: + odd = false; + break; + default: + LOGP(DLSUA, LOGL_ERROR, "Unknown GT encoding 0x%x\n", + encoding); + return -EINVAL; + } + out->gt.nai = *cur++ & 0x7f; + break; + default: + LOGP(DLSUA, LOGL_ERROR, "Unknown GTI %u in SCCP message\n", + sca->global_title_indicator); + return -EINVAL; + } + rc = osmo_isup_party_parse(out->gt.digits, cur, (addr+addrlen-cur), odd); + if (rc < 0) + return rc; + + return 0; +} + +/*! \brief encode a SCCP address from parsed format to wire format + * \param[out] msg message buffer to which address is to be appended + * \param[in] in data structure describing SCCP address + * \returns number of bytes written to \ref msg */ +int osmo_sccp_addr_encode(struct msgb *msg, const struct osmo_sccp_addr *in) +{ + struct sccp_called_party_address *sca; + bool odd; + + sca = (struct sccp_called_party_address *) msgb_put(msg, sizeof(*sca)); + switch (in->ri) { + case OSMO_SCCP_RI_SSN_PC: + sca->routing_indicator = 1; + break; + case OSMO_SCCP_RI_GT: + sca->routing_indicator = 0; + break; + default: + LOGP(DLSUA, LOGL_ERROR, "Unknown CCP Routing Indicator %u" + "requested\n", in->ri); + return -EINVAL; + } + + if (in->presence & OSMO_SCCP_ADDR_T_PC) { + sca->point_code_indicator = 1; + msgb_put_u16le(msg, in->pc & 0x3ff); + } + + if (in->presence & OSMO_SCCP_ADDR_T_SSN) { + sca->ssn_indicator = 1; + msgb_put_u8(msg, in->ssn); + } + + if (!(in->presence & OSMO_SCCP_ADDR_T_GT)) { + sca->global_title_indicator = SCCP_TITLE_IND_NONE; + goto out; + } + + odd = strlen(in->gt.digits) & 1; + switch (in->gt.gti) { + case OSMO_SCCP_GTI_NO_GT: + sca->global_title_indicator = SCCP_TITLE_IND_NONE; + goto out; + case OSMO_SCCP_GTI_NAI_ONLY: + sca->global_title_indicator = SCCP_TITLE_IND_NATURE_ONLY; + msgb_put_u8(msg, (odd << 7) | (in->gt.nai & 0x7f)); + break; + case OSMO_SCCP_GTI_TT_ONLY: + sca->global_title_indicator = SCCP_TITLE_IND_TRANSLATION_ONLY; + msgb_put_u8(msg, in->gt.tt); + /* abort, for national use only */ + LOGP(DLSUA, LOGL_ERROR, "Unsupported Translation Type %u" + "requested\n", in->gt.gti); + return -EINVAL; + case OSMO_SCCP_GTI_TT_NPL_ENC: + sca->global_title_indicator = SCCP_TITLE_IND_TRANS_NUM_ENC; + msgb_put_u8(msg, in->gt.tt); + msgb_put_u8(msg, (in->gt.npi << 4) | (odd ? 1 : 2)); + break; + case OSMO_SCCP_GTI_TT_NPL_ENC_NAI: + sca->global_title_indicator = SCCP_TITLE_IND_TRANS_NUM_ENC_NATURE; + msgb_put_u8(msg, in->gt.tt); + msgb_put_u8(msg, (in->gt.npi << 4) | (odd ? 1 : 2)); + msgb_put_u8(msg, in->gt.nai & 0x7f); + break; + } + osmo_isup_party_encode(msg, in->gt.digits); + +out: + /* return number of bytes written */ + return msg->tail - (uint8_t *)sca; +} + +/*! \brief convert SCCP address to SUA address + * \param xua user-provided xUA message to which address shall be added + * \param[in] iei SUA Information Element Identifier for address + * \param[in] addr SCCP wire format binary address + * \param[in] addrlen Size of \ref addr in bytes + * \returns 0 in case of success; negative on error */ +static int sccp_addr_to_sua(struct xua_msg *xua, uint16_t iei, const uint8_t *addr, + unsigned int addrlen) +{ + struct osmo_sccp_addr osa; + int rc; + + /* First decode the address from SCCP wire format to + * osmo_sccp_addr */ + rc = osmo_sccp_addr_parse(&osa, addr, addrlen); + if (rc < 0) + return rc; + + LOGP(DLSUA, LOGL_DEBUG, "Parsed Addr: %s\n", osmo_sccp_addr_dump(&osa)); + + /* Then re-encode it as SUA address */ + return xua_msg_add_sccp_addr(xua, iei, &osa); +} + +/*! \brief convenience wrapper around sccp_addr_to_sua() for variable mandatory addresses */ +static int sccp_addr_to_sua_ptr(struct xua_msg *xua, uint16_t iei, struct msgb *msg, uint8_t *ptr_addr) +{ + uint8_t *addr = ptr_addr + *ptr_addr + 1; + unsigned int addrlen = *(ptr_addr + *ptr_addr); + + return sccp_addr_to_sua(xua, iei, addr, addrlen); +} + +/*! \brief convert SUA address to SCCP address + * \param msg user-provided message buffer to which address shall be * appended + * \param[in] part SUA wire format binary address + * \returns 0 in case of success; negative on error */ +static int sua_addr_to_sccp(struct msgb *msg, struct xua_msg_part *part) +{ + struct osmo_sccp_addr osa; + int rc; + + /* First decode the address from SUA wire format to + * osmo_sccp_addr */ + rc = sua_addr_parse_part(&osa, part); + if (rc < 0) + return rc; + + /* Then re-encode it as SCCP address */ + return osmo_sccp_addr_encode(msg, &osa); +} + +/*! \brief Add a "SCCP Variable Mandatory Part" (Address format) to the given msgb + * \param msg Message buffer to which part shall be added + * \param[out] var_ptr pointer to relative pointer in SCCP header + * \param[in] xua xUA message from which to use address + * \param[in] iei xUA information element identifier of address */ +static int sccp_add_var_addr(struct msgb *msg, uint8_t *var_ptr, struct xua_msg *xua, uint16_t iei) +{ + struct xua_msg_part *part = xua_msg_find_tag(xua, iei); + uint8_t *lenbyte; + int rc; + if (!part) { + LOGP(DLSUA, LOGL_ERROR, "Cannot find IEI %u in SUA message\n", iei); + return -ENODEV; + } + + /* first allocate one byte for the length */ + lenbyte = msgb_put(msg, 1); + /* update the relative pointer to the length byte */ + *var_ptr = lenbyte - var_ptr; + + /* then append the encoded SCCP address */ + rc = sua_addr_to_sccp(msg, part); + if (rc < 0) + return rc; + + /* store the encoded length of the address */ + *lenbyte = rc; + + return rc; +} + +/*! \brief Add a "SCCP Variable Mandatory Part" to the given msgb + * \param msg Message buffer to which part shall be added + * \param[out] var_ptr pointer to relative pointer in SCCP header + * \param[in] xua xUA message from which to use source data + * \param[in] iei xUA information element identifier of source data */ +static int sccp_add_variable_part(struct msgb *msg, uint8_t *var_ptr, struct xua_msg *xua, uint16_t iei) +{ + struct xua_msg_part *part = xua_msg_find_tag(xua, iei); + uint8_t *lenbyte; + uint8_t *cur; + if (!part) { + LOGP(DLSUA, LOGL_ERROR, "Cannot find IEI %u in SUA message\n", iei); + return -ENODEV; + } + + /* first allocate one byte for the length */ + lenbyte = msgb_put(msg, 1); + /* update the relative pointer to the length byte */ + *var_ptr = lenbyte - var_ptr; + + /* then append the encoded SCCP address */ + cur = msgb_put(msg, part->len); + memcpy(cur, part->dat, part->len); + + /* store the encoded length of the address */ + *lenbyte = part->len; + + return part->len; +} + + +/*! \brief validate that SCCP part with pointer + length doesn't exceed msg tail + * \param[in] msg Message containing SCCP address + * \param[in] ptr_addr pointer to byte with relative SCCP pointer + * \returns true if OK; false if message inconsistent */ +static bool sccp_ptr_part_consistent(struct msgb *msg, uint8_t *ptr_addr) +{ + uint8_t *ptr; + + /* check the address of the relative pointer is within msg */ + if (ptr_addr < msg->data || ptr_addr > msg->tail) { + LOGP(DLSUA, LOGL_ERROR, "ptr_addr outside msg boundary\n"); + return false; + } + + ptr = ptr_addr + *ptr_addr; + if (ptr > msg->tail) { + LOGP(DLSUA, LOGL_ERROR, "ptr points outside msg boundary\n"); + return false; + } + + /* at destination of relative pointer is the length */ + if (ptr + 1 + *ptr > msg->tail) { + LOGP(DLSUA, LOGL_ERROR, "ptr + len points outside msg boundary\n"); + return false; + } + return true; +} + +/*! \brief convenience wrapper around xua_msg_add_data() for variable mandatory data */ +static int sccp_data_to_sua_ptr(struct xua_msg *xua, uint16_t iei, struct msgb *msg, uint8_t *ptr_addr) +{ + uint8_t *addr = ptr_addr + *ptr_addr + 1; + unsigned int addrlen = *(ptr_addr + *ptr_addr); + + return xua_msg_add_data(xua, iei, addrlen, addr); +} + +/*! \brief Convert a given SCCP option to SUA and add it to given xua_msg + * \param xua caller-provided xUA message to which option is to be added + * \param[in] sccp_opt_type SCCP option type (PNC) + * \param[in] opt_len size of \ref opt in bytes + * \param[in] opt pointer to wire-format encoded SCCP option data + * \returns 0 in case of success; negative on error */ +static int xua_msg_add_sccp_opt(struct xua_msg *xua, uint8_t sccp_opt_type, + uint16_t opt_len, uint8_t *opt) +{ + switch (sccp_opt_type) { + case SCCP_PNC_DESTINATION_LOCAL_REFERENCE: + if (opt_len != 3) + return -EINVAL; + xua_msg_add_u32(xua, SUA_IEI_DEST_REF, load_24be(opt)); + break; + case SCCP_PNC_SOURCE_LOCAL_REFERENCE: + if (opt_len != 3) + return -EINVAL; + xua_msg_add_u32(xua, SUA_IEI_SRC_REF, load_24be(opt)); + break; + case SCCP_PNC_CALLED_PARTY_ADDRESS: + if (opt_len < 3) + return -EINVAL; + sccp_addr_to_sua(xua, SUA_IEI_DEST_ADDR, opt, opt_len); + break; + case SCCP_PNC_CALLING_PARTY_ADDRESS: + if (opt_len < 3) + return -EINVAL; + sccp_addr_to_sua(xua, SUA_IEI_SRC_ADDR, opt, opt_len); + break; + case SCCP_PNC_PROTOCOL_CLASS: + if (opt_len < 1) + return -EINVAL; + xua_msg_add_u32(xua, SUA_IEI_PROTO_CLASS, *opt); + break; + case SCCP_PNC_CREDIT: + if (opt_len != 1) + return -EINVAL; + xua_msg_add_u32(xua, SUA_IEI_IMPORTANCE, *opt & 0x7); + break; + case SCCP_PNC_RELEASE_CAUSE: + if (opt_len != 1) + return -EINVAL; + xua_msg_add_u32(xua, SUA_IEI_CAUSE, SUA_CAUSE_T_RELEASE | *opt); + break; + case SCCP_PNC_RETURN_CAUSE: + if (opt_len != 1) + return -EINVAL; + xua_msg_add_u32(xua, SUA_IEI_CAUSE, SUA_CAUSE_T_RETURN | *opt); + break; + case SCCP_PNC_RESET_CAUSE: + if (opt_len != 1) + return -EINVAL; + xua_msg_add_u32(xua, SUA_IEI_CAUSE, SUA_CAUSE_T_RESET | *opt); + break; + case SCCP_PNC_ERROR_CAUSE: + if (opt_len != 1) + return -EINVAL; + xua_msg_add_u32(xua, SUA_IEI_CAUSE, SUA_CAUSE_T_ERROR | *opt); + break; + case SCCP_PNC_REFUSAL_CAUSE: + if (opt_len != 1) + return -EINVAL; + xua_msg_add_u32(xua, SUA_IEI_CAUSE, SUA_CAUSE_T_REFUSAL | *opt); + break; + case SCCP_PNC_DATA: + xua_msg_add_data(xua, SUA_IEI_DATA, opt_len, opt); + break; + case SCCP_PNC_HOP_COUNTER: + if (opt_len != 1) + return -EINVAL; + xua_msg_add_u32(xua, SUA_IEI_S7_HOP_CTR, *opt); + break; + case SCCP_PNC_IMPORTANCE: + if (opt_len != 1) + return -EINVAL; + xua_msg_add_u32(xua, SUA_IEI_IMPORTANCE, *opt & 0x7); + break; + case SCCP_PNC_LONG_DATA: + xua_msg_add_data(xua, SUA_IEI_DATA, opt_len, opt); + break; + case SCCP_PNC_SEGMENTATION: + case SCCP_PNC_SEGMENTING: + case SCCP_PNC_RECEIVE_SEQ_NUMBER: + /* only in class 3 */ + case SCCP_PNC_SEQUENCING: + /* only in class 3 */ + default: + LOGP(DLSUA, LOGL_ERROR, "Unsupported SCCP option type %u\n", + sccp_opt_type); + return -1; + } + return 0; +} + +/*! \brief append a SCCP option header to the given message + * \param msg Message to which header is to be appended + * \param[in] pnc PNC of the option header + * \param[in] len length of the option, excluding the header */ +static void msgb_put_sccp_opt_hdr(struct msgb *msg, uint8_t pnc, uint8_t len) +{ + msgb_put_u8(msg, pnc); + msgb_put_u8(msg, len); +} + +/*! \brief append a SCCP option to the given message + * \param msg Message to which option is to be appended + * \param[in] pnc PNC of the option header + * \param[in] len length of the option, excluding the header + * \param[in] data actual data to be appended */ +static void msgb_put_sccp_opt(struct msgb *msg, uint8_t pnc, uint8_t len, const uint8_t *data) +{ + uint8_t *cur; + + msgb_put_sccp_opt_hdr(msg, pnc, len); + cur = msgb_put(msg, len); + memcpy(cur, data, len); +} + +/*! \brief Convert a given SUA option/IE to SCCP and add it to given * msgb + * \param msg caller-provided message buffer to which option is to be appended + * \param[in] opt xUA option/IE (messge part) to be converted+added + * \returns 0 in case of success; negative on error */ +static int sccp_msg_add_sua_opt(struct msgb *msg, struct xua_msg_part *opt) +{ + uint32_t tmp32; + uint8_t pnc, *lenptr; + int rc; + + switch (opt->tag) { + case SUA_IEI_DEST_REF: + msgb_put_sccp_opt_hdr(msg, SCCP_PNC_DESTINATION_LOCAL_REFERENCE, 3); + msgb_put_u24be(msg, xua_msg_part_get_u32(opt)); + break; + case SUA_IEI_SRC_REF: + msgb_put_sccp_opt_hdr(msg, SCCP_PNC_SOURCE_LOCAL_REFERENCE, 3); + msgb_put_u24be(msg, xua_msg_part_get_u32(opt)); + break; + case SUA_IEI_DEST_ADDR: + msgb_put_u8(msg, SCCP_PNC_CALLED_PARTY_ADDRESS); + lenptr = msgb_put(msg, 1); + rc = sua_addr_to_sccp(msg, opt); + if (rc < 0) + return rc; + *lenptr = rc; + break; + case SUA_IEI_SRC_ADDR: + msgb_put_u8(msg, SCCP_PNC_CALLING_PARTY_ADDRESS); + lenptr = msgb_put(msg, 1); + rc = sua_addr_to_sccp(msg, opt); + if (rc < 0) + return rc; + *lenptr = rc; + break; + case SUA_IEI_PROTO_CLASS: + msgb_put_sccp_opt_hdr(msg, SCCP_PNC_PROTOCOL_CLASS, 1); + msgb_put_u8(msg, xua_msg_part_get_u32(opt)); + break; + case SUA_IEI_CREDIT: + msgb_put_sccp_opt_hdr(msg, SCCP_PNC_CREDIT, 1); + msgb_put_u8(msg, xua_msg_part_get_u32(opt) & 0x7); + break; + case SUA_IEI_CAUSE: + tmp32 = xua_msg_part_get_u32(opt); + switch (tmp32 & SUA_CAUSE_T_MASK) { + case SUA_CAUSE_T_RETURN: + pnc = SCCP_PNC_RETURN_CAUSE; + break; + case SUA_CAUSE_T_REFUSAL: + pnc = SCCP_PNC_REFUSAL_CAUSE; + break; + case SUA_CAUSE_T_RELEASE: + pnc = SCCP_PNC_RELEASE_CAUSE; + break; + case SUA_CAUSE_T_RESET: + pnc = SCCP_PNC_RESET_CAUSE; + break; + case SUA_CAUSE_T_ERROR: + pnc = SCCP_PNC_ERROR_CAUSE; + break; + default: + LOGP(DLSUA, LOGL_ERROR, "Unknown SUA Cause Class 0x%04x\n", tmp32); + return -EINVAL; + } + msgb_put_sccp_opt_hdr(msg, pnc, 1); + msgb_put_u8(msg, tmp32 & 0xff); + break; + case SUA_IEI_DATA: + msgb_put_sccp_opt(msg, SCCP_PNC_DATA, opt->len, opt->dat); + break; + case SUA_IEI_S7_HOP_CTR: + msgb_put_sccp_opt_hdr(msg, SCCP_PNC_HOP_COUNTER, 1); + msgb_put_u8(msg, xua_msg_part_get_u32(opt)); + break; + case SUA_IEI_IMPORTANCE: + msgb_put_sccp_opt_hdr(msg, SCCP_PNC_IMPORTANCE, 1); + msgb_put_u8(msg, xua_msg_part_get_u32(opt) & 0x7); + break; + case SUA_IEI_ROUTE_CTX: + break; + case SUA_IEI_SEQ_CTRL: + /* TODO */ + break; + default: + LOGP(DLSUA, LOGL_ERROR, "Unknown SUA IEI 0x%04x\n", opt->tag); + return -1; + } + return 0; +} + +/*! \brief convert SCCP optional part to list of SUA options + * \param[in] msg Message buffer holding SCCP message + * \param[in] ptr_opt address of relative pointer to optional part + * \param xua caller-provided xUA message to which options are added + * \returns \ref xua in case of success, NULL on error (xua not freed!) */ +static struct xua_msg *sccp_to_xua_opt(struct msgb *msg, uint8_t *ptr_opt, struct xua_msg *xua) +{ + uint8_t *opt_start, *oneopt; + + /* some bounds checking */ + if (ptr_opt < msg->data || ptr_opt > msg->tail) + return NULL; + opt_start = ptr_opt + *ptr_opt; + if (opt_start > msg->tail) + return NULL; + + oneopt = opt_start; + + while (oneopt < msg->tail) { + uint8_t opt_type = oneopt[0]; + + if (opt_type == SCCP_PNC_END_OF_OPTIONAL) + return xua; + + if (opt_type == SCCP_PNC_LONG_DATA) { + uint16_t opt_len16; + /* two byte length field */ + if (oneopt + 2 > msg->tail) + return NULL; + opt_len16 = oneopt[1] << 8 | oneopt[2]; + if (oneopt + 3 + opt_len16 > msg->tail) + return NULL; + xua_msg_add_sccp_opt(xua, opt_type, opt_len16, oneopt+3); + oneopt += 3 + opt_len16; + } else { + uint8_t opt_len; + /* one byte length field */ + if (oneopt + 1 > msg->tail) + return NULL; + + opt_len = oneopt[1]; + if (oneopt + 2 + opt_len > msg->tail) + return NULL; + xua_msg_add_sccp_opt(xua, opt_type, opt_len, oneopt+2); + oneopt += 2 + opt_len; + } + } + return NULL; +} + +#define MAX_IES 6 +#define NUM_SCCP_MSGT (SCCP_MSG_TYPE_LUDTS+1) + +/* This table indicates which information elements are mandatory and not + * optional in SCCP, per message type */ +static const uint16_t sccp_mandatory[NUM_SCCP_MSGT][MAX_IES] = { + /* Table 3/Q.713 */ + [SCCP_MSG_TYPE_CR] = { + SUA_IEI_SRC_REF, SUA_IEI_PROTO_CLASS, SUA_IEI_DEST_ADDR , 0 + }, + /* Table 4/Q.713 */ + [SCCP_MSG_TYPE_CC] = { + SUA_IEI_DEST_REF, SUA_IEI_SRC_REF, SUA_IEI_PROTO_CLASS, 0 + }, + /* Table 5/Q.713 */ + [SCCP_MSG_TYPE_CREF] = { + SUA_IEI_DEST_REF, SUA_IEI_CAUSE, 0 + }, + /* Table 6/Q.713 */ + [SCCP_MSG_TYPE_RLSD] = { + SUA_IEI_DEST_REF, SUA_IEI_SRC_REF, SUA_IEI_CAUSE, 0 + }, + /* Table 7/Q.713 */ + [SCCP_MSG_TYPE_RLC] = { + SUA_IEI_DEST_REF, SUA_IEI_SRC_REF, 0 + }, + /* Table 8/Q.713 */ + [SCCP_MSG_TYPE_DT1] = { + SUA_IEI_DEST_REF, SUA_IEI_SEGMENTATION, 0 + }, + /* Table 9/Q.713 */ + [SCCP_MSG_TYPE_DT2] = { + SUA_IEI_DEST_REF, SUA_IEI_SEGMENTATION, 0 + }, + /* Table 10/Q.713 */ + [SCCP_MSG_TYPE_AK] = { + SUA_IEI_DEST_REF, SUA_IEI_RX_SEQ_NR, 0 + }, + /* Table 11/Q.713 */ + [SCCP_MSG_TYPE_UDT] = { + SUA_IEI_PROTO_CLASS, SUA_IEI_DEST_ADDR, + SUA_IEI_SRC_ADDR, SUA_IEI_DATA, 0 + }, + /* Table 12/Q.713 */ + [SCCP_MSG_TYPE_UDTS] = { + SUA_IEI_CAUSE, SUA_IEI_DEST_ADDR, SUA_IEI_SRC_ADDR, SUA_IEI_DATA, 0 + }, + /* Table 13/Q.713 */ + [SCCP_MSG_TYPE_ED] = { + SUA_IEI_DEST_REF, 0 + }, + /* Table 14/Q.713 */ + [SCCP_MSG_TYPE_EA] = { + SUA_IEI_DEST_REF, 0 + }, + /* Table 15/Q.713 */ + [SCCP_MSG_TYPE_RSR] = { + SUA_IEI_DEST_REF, SUA_IEI_SRC_REF, SUA_IEI_CAUSE, 0 + }, + /* Table 16/Q.713 */ + [SCCP_MSG_TYPE_RSC] = { + SUA_IEI_DEST_REF, SUA_IEI_SRC_REF, 0 + }, + /* Table 17/Q.713 */ + [SCCP_MSG_TYPE_ERR] = { + SUA_IEI_DEST_REF, SUA_IEI_CAUSE, 0 + }, + /* Table 18/Q.713 */ + [SCCP_MSG_TYPE_IT] = { + SUA_IEI_DEST_REF, SUA_IEI_SRC_REF, SUA_IEI_PROTO_CLASS, + SUA_IEI_SEGMENTATION, SUA_IEI_CREDIT, 0 + }, + /* Table 19/Q.713 */ + [SCCP_MSG_TYPE_XUDT] = { + SUA_IEI_PROTO_CLASS, SUA_IEI_S7_HOP_CTR, + SUA_IEI_DEST_ADDR, SUA_IEI_SRC_ADDR, SUA_IEI_DATA, 0 + }, + /* Table 20/Q.713 */ + [SCCP_MSG_TYPE_XUDTS] = { + SUA_IEI_CAUSE, SUA_IEI_S7_HOP_CTR, SUA_IEI_DEST_ADDR, + SUA_IEI_SRC_ADDR, SUA_IEI_DATA, 0 + }, + /* Table 21/Q.713 */ + [SCCP_MSG_TYPE_LUDT] = { + SUA_IEI_PROTO_CLASS, SUA_IEI_S7_HOP_CTR, + SUA_IEI_DEST_ADDR, SUA_IEI_SRC_ADDR, SUA_IEI_DATA, 0 + }, + /* Table 22/Q.713 */ + [SCCP_MSG_TYPE_LUDTS] = { + SUA_IEI_CAUSE, SUA_IEI_S7_HOP_CTR, SUA_IEI_DEST_ADDR, + SUA_IEI_SRC_ADDR, SUA_IEI_DATA, 0 + }, +}; + +static bool sccp_is_mandatory(enum sccp_message_types type, const struct xua_msg_part *part) +{ + unsigned int i; + + if (type > ARRAY_SIZE(sccp_mandatory)) + return false; + + for (i = 0; i < MAX_IES; i++) { + uint16_t val = sccp_mandatory[type][i]; + if (val == 0) { + /* end of list, don't iterate further */ + return false; + } + if (val == part->tag) { + /* found in list, it's mandatory */ + return true; + } + } + /* not mandatory */ + return false; +} + +static int xua_ies_to_sccp_opts(struct msgb *msg, uint8_t *ptr_opt, + enum sccp_message_types type, struct xua_msg *xua) +{ + struct xua_msg_part *part; + + /* store relative pointer to start of optional part */ + *ptr_opt = msg->tail - ptr_opt; + + llist_for_each_entry(part, &xua->headers, entry) { + /* make sure we don't add a SCCP option for information + * that is already present in mandatory fixed or + * mandatory variable parts of the header */ + if (!sccp_is_mandatory(type, part)) + sccp_msg_add_sua_opt(msg, part); + } + msgb_put_u8(msg, SCCP_PNC_END_OF_OPTIONAL); + + return 0; +} + +/* store a 'local reference' as big-eidian 24bit value at local_ref */ +static void store_local_ref(struct sccp_source_reference *local_ref, struct xua_msg *xua, uint16_t iei) +{ + uint32_t tmp32 = xua_msg_get_u32(xua, iei); + local_ref->octet1 = (tmp32 >> 16) & 0xff; + local_ref->octet2 = (tmp32 >> 8) & 0xff; + local_ref->octet3 = tmp32 & 0xff; +} + +static struct xua_msg *sccp_to_xua_cr(struct msgb *msg, struct xua_msg *xua) +{ + struct sccp_connection_request *req = (struct sccp_connection_request *)msg->l2h; + + /* Fixed Part */ + xua_msg_add_u32(xua, SUA_IEI_PROTO_CLASS, req->proto_class); + xua_msg_add_u32(xua, SUA_IEI_SRC_REF, load_24be(&req->source_local_reference)); + /* Variable Part */ + if (!sccp_ptr_part_consistent(msg, &req->variable_called)) + return NULL; + sccp_addr_to_sua_ptr(xua, SUA_IEI_DEST_ADDR, msg, &req->variable_called); + /* Optional Part */ + return sccp_to_xua_opt(msg, &req->optional_start, xua); +} + +static int sua_to_sccp_cr(struct msgb *msg, struct xua_msg *xua) +{ + struct sccp_connection_request *req; + req = (struct sccp_connection_request *) msgb_put(msg, sizeof(*req)); + + /* Fixed Part */ + req->type = SCCP_MSG_TYPE_CR; + req->proto_class = xua_msg_get_u32(xua, SUA_IEI_PROTO_CLASS); + store_local_ref(&req->source_local_reference, xua, SUA_IEI_SRC_REF); + /* Variable Part */ + sccp_add_var_addr(msg, &req->variable_called, xua, SUA_IEI_DEST_ADDR); + + /* Optional Part */ + return xua_ies_to_sccp_opts(msg, &req->optional_start, req->type, xua); +} + +static struct xua_msg *sccp_to_xua_cc(struct msgb *msg, struct xua_msg *xua) +{ + struct sccp_connection_confirm *cnf = (struct sccp_connection_confirm *)msg->l2h; + + /* Fixed Part */ + xua_msg_add_u32(xua, SUA_IEI_PROTO_CLASS, cnf->proto_class); + xua_msg_add_u32(xua, SUA_IEI_DEST_REF, load_24be(&cnf->destination_local_reference)); + xua_msg_add_u32(xua, SUA_IEI_SRC_REF, load_24be(&cnf->source_local_reference)); + /* Optional Part */ + return sccp_to_xua_opt(msg, &cnf->optional_start, xua); +} + +static int sua_to_sccp_cc(struct msgb *msg, struct xua_msg *xua) +{ + struct sccp_connection_confirm *cnf; + cnf = (struct sccp_connection_confirm *) msgb_put(msg, sizeof(*cnf)); + + /* Fixed Part */ + cnf->type = SCCP_MSG_TYPE_CC; + cnf->proto_class = xua_msg_get_u32(xua, SUA_IEI_PROTO_CLASS); + store_local_ref(&cnf->destination_local_reference, xua, SUA_IEI_DEST_REF); + store_local_ref(&cnf->source_local_reference, xua, SUA_IEI_SRC_REF); + /* Optional Part */ + return xua_ies_to_sccp_opts(msg, &cnf->optional_start, cnf->type, xua); +} + +static struct xua_msg *sccp_to_xua_cref(struct msgb *msg, struct xua_msg *xua) +{ + struct sccp_connection_refused *ref = (struct sccp_connection_refused *)msg->l2h; + + /* Fixed Part */ + xua_msg_add_u32(xua, SUA_IEI_DEST_REF, load_24be(&ref->destination_local_reference)); + xua_msg_add_u32(xua, SUA_IEI_CAUSE, SUA_CAUSE_T_REFUSAL | ref->cause); + /* Optional Part */ + return sccp_to_xua_opt(msg, &ref->optional_start, xua); +} + +static int sua_to_sccp_cref(struct msgb *msg, struct xua_msg *xua) +{ + struct sccp_connection_refused *ref; + ref = (struct sccp_connection_refused *) msgb_put(msg, sizeof(*ref)); + + /* Fixed Part */ + ref->type = SCCP_MSG_TYPE_CREF; + store_local_ref(&ref->destination_local_reference, xua, SUA_IEI_DEST_REF); + ref->cause = xua_msg_get_u32(xua, SUA_IEI_CAUSE) & 0xff; + /* Optional Part */ + return xua_ies_to_sccp_opts(msg, &ref->optional_start, ref->type, xua); +} + +static struct xua_msg *sccp_to_xua_rlsd(struct msgb *msg, struct xua_msg *xua) +{ + struct sccp_connection_released *rlsd = (struct sccp_connection_released *)msg->l2h; + + /* Fixed Part */ + xua_msg_add_u32(xua, SUA_IEI_DEST_REF, load_24be(&rlsd->destination_local_reference)); + xua_msg_add_u32(xua, SUA_IEI_SRC_REF, load_24be(&rlsd->source_local_reference)); + xua_msg_add_u32(xua, SUA_IEI_CAUSE, SUA_CAUSE_T_RELEASE | rlsd->release_cause); + /* Optional Part */ + return sccp_to_xua_opt(msg, &rlsd->optional_start, xua); +} + +static int sua_to_sccp_rlsd(struct msgb *msg, struct xua_msg *xua) +{ + struct sccp_connection_released *rlsd; + rlsd =(struct sccp_connection_released *) msgb_put(msg, sizeof(*rlsd)); + + /* Fixed Part */ + rlsd->type = SCCP_MSG_TYPE_RLSD; + store_local_ref(&rlsd->destination_local_reference, xua, SUA_IEI_DEST_REF); + store_local_ref(&rlsd->source_local_reference, xua, SUA_IEI_SRC_REF); + rlsd->release_cause = xua_msg_get_u32(xua, SUA_IEI_CAUSE) & 0xff; + + /* Optional Part */ + return xua_ies_to_sccp_opts(msg, &rlsd->optional_start, rlsd->type, xua); +} + +static struct xua_msg *sccp_to_xua_rlc(struct msgb *msg, struct xua_msg *xua) +{ + struct sccp_connection_release_complete *rlc; + rlc = (struct sccp_connection_release_complete *) msg->l2h; + + /* Fixed Part */ + xua_msg_add_u32(xua, SUA_IEI_DEST_REF, load_24be(&rlc->destination_local_reference)); + xua_msg_add_u32(xua, SUA_IEI_SRC_REF, load_24be(&rlc->source_local_reference)); + return xua; +} + +static int sua_to_sccp_rlc(struct msgb *msg, struct xua_msg *xua) +{ + struct sccp_connection_release_complete *rlc; + rlc = (struct sccp_connection_release_complete *) msgb_put(msg, sizeof(*rlc)); + + /* Fixed Part */ + rlc->type = SCCP_MSG_TYPE_RLC; + store_local_ref(&rlc->destination_local_reference, xua, SUA_IEI_DEST_REF); + store_local_ref(&rlc->source_local_reference, xua, SUA_IEI_SRC_REF); + return 0; +} + +static struct xua_msg *sccp_to_xua_dt1(struct msgb *msg, struct xua_msg *xua) +{ + struct sccp_data_form1 *dt1 = (struct sccp_data_form1 *) msg->l2h; + + /* Fixed Part */ + xua_msg_add_u32(xua, SUA_IEI_DEST_REF, load_24be(&dt1->destination_local_reference)); + xua_msg_add_u32(xua, SUA_IEI_SEGMENTATION, dt1->segmenting); + /* Variable Part */ + if (!sccp_ptr_part_consistent(msg, &dt1->variable_start)) + return NULL; + sccp_data_to_sua_ptr(xua, SUA_IEI_DATA, msg, &dt1->variable_start); + return xua; +} + +static int sua_to_sccp_dt1(struct msgb *msg, struct xua_msg *xua) +{ + struct sccp_data_form1 *dt1; + dt1 = (struct sccp_data_form1 *) msgb_put(msg, sizeof(*dt1)); + + /* Fixed Part */ + dt1->type = SCCP_MSG_TYPE_DT1; + store_local_ref(&dt1->destination_local_reference, xua, SUA_IEI_DEST_REF); + dt1->segmenting = xua_msg_get_u32(xua, SUA_IEI_SEGMENTATION); + /* Variable Part */ + sccp_add_variable_part(msg, &dt1->variable_start, xua, SUA_IEI_DATA); + return 0; +} + +static struct xua_msg *sccp_to_xua_udt(struct msgb *msg, struct xua_msg *xua) +{ + struct sccp_data_unitdata *udt = (struct sccp_data_unitdata *)msg->l2h; + + /* Fixed Part */ + xua_msg_add_u32(xua, SUA_IEI_PROTO_CLASS, udt->proto_class); + /* Variable Part */ + if (!sccp_ptr_part_consistent(msg, &udt->variable_called)) + return NULL; + sccp_addr_to_sua_ptr(xua, SUA_IEI_DEST_ADDR, msg, &udt->variable_called); + if (!sccp_ptr_part_consistent(msg, &udt->variable_calling)) + return NULL; + sccp_addr_to_sua_ptr(xua, SUA_IEI_SRC_ADDR, msg, &udt->variable_calling); + if (!sccp_ptr_part_consistent(msg, &udt->variable_data)) + return NULL; + sccp_data_to_sua_ptr(xua, SUA_IEI_DATA, msg, &udt->variable_data); + return xua; + +} + +static int sua_to_sccp_udt(struct msgb *msg, struct xua_msg *xua) +{ + struct sccp_data_unitdata *udt; + udt = (struct sccp_data_unitdata *) msgb_put(msg, sizeof(*udt)); + + /* Fixed Part */ + udt->type = SCCP_MSG_TYPE_UDT; + udt->proto_class = xua_msg_get_u32(xua, SUA_IEI_PROTO_CLASS); + /* Variable Part */ + sccp_add_var_addr(msg, &udt->variable_called, xua, SUA_IEI_DEST_ADDR); + sccp_add_var_addr(msg, &udt->variable_calling, xua, SUA_IEI_SRC_ADDR); + sccp_add_variable_part(msg, &udt->variable_data, xua, SUA_IEI_DATA); + return 0; +} + +static struct xua_msg *sccp_to_xua_udts(struct msgb *msg, struct xua_msg *xua) +{ + struct sccp_data_unitdata_service *udts; + udts =(struct sccp_data_unitdata_service *)msg->l2h; + + /* Fixed Part */ + xua_msg_add_u32(xua, SUA_IEI_CAUSE, SUA_CAUSE_T_RETURN | udts->return_cause); + /* Variable Part */ + if (!sccp_ptr_part_consistent(msg, &udts->variable_called)) + return NULL; + sccp_addr_to_sua_ptr(xua, SUA_IEI_DEST_ADDR, msg, &udts->variable_called); + if (!sccp_ptr_part_consistent(msg, &udts->variable_calling)) + return NULL; + sccp_addr_to_sua_ptr(xua, SUA_IEI_SRC_ADDR, msg, &udts->variable_calling); + if (!sccp_ptr_part_consistent(msg, &udts->variable_data)) + return NULL; + sccp_data_to_sua_ptr(xua, SUA_IEI_DATA, msg, &udts->variable_data); + return xua; + +} + +static int sua_to_sccp_udts(struct msgb *msg, struct xua_msg *xua) +{ + struct sccp_data_unitdata_service *udts; + udts = (struct sccp_data_unitdata_service *) msgb_put(msg, sizeof(*udts)); + + /* Fixed Part */ + udts->type = SCCP_MSG_TYPE_UDTS; + udts->return_cause = xua_msg_get_u32(xua, SUA_IEI_CAUSE) & 0xff; + /* Variable Part */ + sccp_add_var_addr(msg, &udts->variable_called, xua, SUA_IEI_DEST_ADDR); + sccp_add_var_addr(msg, &udts->variable_calling, xua, SUA_IEI_SRC_ADDR); + sccp_add_variable_part(msg, &udts->variable_data, xua, SUA_IEI_DATA); + return 0; +} + +static struct xua_msg *sccp_to_xua_it(struct msgb *msg, struct xua_msg *xua) +{ + struct sccp_data_it *it = (struct sccp_data_it *)msg->l2h; + + /* Fixed Part */ + xua_msg_add_u32(xua, SUA_IEI_PROTO_CLASS, it->proto_class); + xua_msg_add_u32(xua, SUA_IEI_SRC_REF, load_24be(&it->source_local_reference)); + xua_msg_add_u32(xua, SUA_IEI_DEST_REF, load_24be(&it->destination_local_reference)); + if ((it->proto_class & 0xF) == 3) { + //xua_msg_add_u32(xua, SUA_IEI_SEQUENCING, it->sequencing); + xua_msg_add_u32(xua, SUA_IEI_CREDIT, it->credit); + } + return xua; +} + +static int sua_to_sccp_it(struct msgb *msg, struct xua_msg *xua) +{ + struct sccp_data_it *it; + it = (struct sccp_data_it *) msgb_put(msg, sizeof(*it)); + + /* Fixed Part */ + it->type = SCCP_MSG_TYPE_IT; + it->proto_class = xua_msg_get_u32(xua, SUA_IEI_PROTO_CLASS); + store_local_ref(&it->destination_local_reference, xua, SUA_IEI_DEST_REF); + store_local_ref(&it->source_local_reference, xua, SUA_IEI_SRC_REF); + if ((it->proto_class & 0xF) == 3) { + //it->sequencing + it->credit = xua_msg_get_u32(xua, SUA_IEI_CREDIT); + } + + return 0; +} + +static struct xua_msg *sccp_to_xua_err(struct msgb *msg, struct xua_msg *xua) +{ + struct sccp_proto_err *err = (struct sccp_proto_err *)msg->l2h; + + /* Fixed Part */ + xua_msg_add_u32(xua, SUA_IEI_DEST_REF, load_24be(&err->destination_local_reference)); + xua_msg_add_u32(xua, SUA_IEI_CAUSE, SUA_CAUSE_T_ERROR | err->error_cause); + return xua; +} + +static int sua_to_sccp_err(struct msgb *msg, struct xua_msg *xua) +{ + struct sccp_proto_err *err; + err = (struct sccp_proto_err *) msgb_put(msg, sizeof(*err)); + + /* Fixed Part */ + err->type = SCCP_MSG_TYPE_ERR; + store_local_ref(&err->destination_local_reference, xua, SUA_IEI_DEST_REF); + err->error_cause = xua_msg_get_u32(xua, SUA_IEI_CAUSE) & 0xff; + return 0; +} + +/*! \brief convert SCCP message to a SUA message + * \param[in] msg message buffer holding SCCP message at l2h + * \returns callee-allocated xUA message on success; NULL on error */ +struct xua_msg *osmo_sccp_to_xua(struct msgb *msg) +{ + struct xua_msg *xua; + + if (msgb_l2len(msg) < 1) { + LOGP(DLSUA, LOGL_ERROR, "Short SCCP Message, cannot transcode\n"); + return NULL; + } + + xua = xua_msg_alloc(); + if (!xua) + return NULL; + + switch (msg->l2h[0]) { + case SCCP_MSG_TYPE_CR: + xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_CORE); + return sccp_to_xua_cr(msg, xua); + case SCCP_MSG_TYPE_CC: + xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_COAK); + return sccp_to_xua_cc(msg, xua); + case SCCP_MSG_TYPE_CREF: + xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_COREF); + return sccp_to_xua_cref(msg, xua); + case SCCP_MSG_TYPE_RLSD: + xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_RELRE); + return sccp_to_xua_rlsd(msg, xua); + case SCCP_MSG_TYPE_RLC: + xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_RELCO); + return sccp_to_xua_rlc(msg, xua); + case SCCP_MSG_TYPE_DT1: + xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_CODT); + return sccp_to_xua_dt1(msg, xua); + case SCCP_MSG_TYPE_UDT: + xua->hdr = XUA_HDR(SUA_MSGC_CL, SUA_CL_CLDT); + return sccp_to_xua_udt(msg, xua); + case SCCP_MSG_TYPE_UDTS: + xua->hdr = XUA_HDR(SUA_MSGC_CL, SUA_CL_CLDR); + return sccp_to_xua_udts(msg, xua); + case SCCP_MSG_TYPE_IT: + xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_COIT); + return sccp_to_xua_it(msg, xua); + case SCCP_MSG_TYPE_ERR: + xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_COERR); + return sccp_to_xua_err(msg, xua); + /* Unsupported Message Types */ + case SCCP_MSG_TYPE_DT2: + case SCCP_MSG_TYPE_AK: + case SCCP_MSG_TYPE_ED: + case SCCP_MSG_TYPE_EA: + case SCCP_MSG_TYPE_RSR: + case SCCP_MSG_TYPE_RSC: + case SCCP_MSG_TYPE_XUDT: + case SCCP_MSG_TYPE_XUDTS: + case SCCP_MSG_TYPE_LUDT: + case SCCP_MSG_TYPE_LUDTS: + default: + LOGP(DLSUA, LOGL_ERROR, "Unsupported SCCP message type %u\n", + msg->l2h[0]); + xua_msg_free(xua); + return NULL; + } + + return NULL; +} + +/*! \brief convert parsed SUA message to SCCP message + * \param[in] xua parsed SUA message to be converted + * \returns callee-allocated msgb containing encoded SCCP message */ +struct msgb *osmo_sua_to_sccp(struct xua_msg *xua) +{ + struct msgb *msg = sccp_msgb_alloc("SCCP from SUA"); + int rc; + + switch (xua->hdr.msg_class) { + case SUA_MSGC_CL: + switch (xua->hdr.msg_type) { + case SUA_CL_CLDT: + rc = sua_to_sccp_udt(msg, xua); + break; + case SUA_CL_CLDR: + rc = sua_to_sccp_udts(msg, xua); + break; + default: + LOGP(DLSUA, LOGL_ERROR, "Unsupported SUA message %s\n", + xua_hdr_dump(xua, &xua_dialect_sua)); + goto out_err; + } + break; + case SUA_MSGC_CO: + switch (xua->hdr.msg_type) { + case SUA_CO_CORE: + rc = sua_to_sccp_cr(msg, xua); + break; + case SUA_CO_COAK: + rc = sua_to_sccp_cc(msg, xua); + break; + case SUA_CO_COREF: + rc = sua_to_sccp_cref(msg, xua); + break; + case SUA_CO_RELRE: + rc = sua_to_sccp_rlsd(msg, xua); + break; + case SUA_CO_RELCO: + rc = sua_to_sccp_rlc(msg, xua); + break; + case SUA_CO_CODT: + rc = sua_to_sccp_dt1(msg, xua); + break; + case SUA_CO_COIT: + rc = sua_to_sccp_it(msg, xua); + break; + case SUA_CO_COERR: + rc = sua_to_sccp_err(msg, xua); + break; + default: + LOGP(DLSUA, LOGL_ERROR, "Unsupported SUA message %s\n", + xua_hdr_dump(xua, &xua_dialect_sua)); + goto out_err; + } + break; + default: + LOGP(DLSUA, LOGL_ERROR, "Unsupported SUA message class %s\n", + xua_hdr_dump(xua, &xua_dialect_sua)); + goto out_err; + } + + if (rc < 0) + goto out_err; + + return msg; + +out_err: + msgb_free(msg); + return NULL; +} -- To view, visit https://gerrit.osmocom.org/2213 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I8151a9b08a0b0ca97b9c73105ad4548512ce3be8 Gerrit-PatchSet: 4 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:31:09 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:31:09 +0000 Subject: [PATCH] libosmo-sccp[master]: Add tests for xUA code + SCCP/SUA transcoding In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2214 to look at the new patch set (#4). Add tests for xUA code + SCCP/SUA transcoding Change-Id: I7ce038d72dca18fb83d5a12519c9a48267e52ab8 --- M configure.ac M tests/Makefile.am M tests/testsuite.at A tests/xua/Makefile.am A tests/xua/sccp_test_data.c A tests/xua/sccp_test_data.h A tests/xua/xua_test.c A tests/xua/xua_test.ok 8 files changed, 654 insertions(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/14/2214/4 diff --git a/configure.ac b/configure.ac index 116e168..ed3e25a 100644 --- a/configure.ac +++ b/configure.ac @@ -67,6 +67,7 @@ tests/mtp/Makefile tests/m2ua/Makefile tests/sigtran/Makefile + tests/xua/Makefile tests/ss7/Makefile Makefile) diff --git a/tests/Makefile.am b/tests/Makefile.am index 9c251fe..6d3c96f 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,4 +1,4 @@ -SUBDIRS = sccp mtp m2ua sigtran ss7 +SUBDIRS = xua sccp mtp m2ua sigtran ss7 # The `:;' works around a Bash 3.2 bug when the output is not writeable. $(srcdir)/package.m4: $(top_srcdir)/configure.ac diff --git a/tests/testsuite.at b/tests/testsuite.at index 171f488..b810bdf 100644 --- a/tests/testsuite.at +++ b/tests/testsuite.at @@ -19,6 +19,12 @@ AT_CHECK([$abs_top_builddir/tests/sccp/sccp_test], [], [expout], [ignore]) AT_CLEANUP +AT_SETUP([xua]) +AT_KEYWORDS([xua]) +cat $abs_srcdir/xua/xua_test.ok > expout +AT_CHECK([$abs_top_builddir/tests/xua/xua_test], [], [expout], [ignore]) +AT_CLEANUP + AT_SETUP([ss7]) AT_KEYWORDS([ss7]) cat $abs_srcdir/ss7/ss7_test.ok > expout diff --git a/tests/xua/Makefile.am b/tests/xua/Makefile.am new file mode 100644 index 0000000..8a75e6c --- /dev/null +++ b/tests/xua/Makefile.am @@ -0,0 +1,13 @@ +AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -Wall +AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) + +AM_LDFLAGS = -static +LDADD = $(top_builddir)/src/libosmo-sigtran.la \ + $(LIBOSMOCORE_LIBS) $(LIBOSMONETIF_LIBS) $(LIBSCTP_LIBS) + +EXTRA_DIST = xua_test.ok + +noinst_HEADERS = sccp_test_data.h +noinst_PROGRAMS = xua_test + +xua_test_SOURCES = xua_test.c sccp_test_data.c diff --git a/tests/xua/sccp_test_data.c b/tests/xua/sccp_test_data.c new file mode 100644 index 0000000..c7c8f27 --- /dev/null +++ b/tests/xua/sccp_test_data.c @@ -0,0 +1,102 @@ +#include + +/* BSC -> MSC */ +const uint8_t bssmap_reset[18] = { + 0x09, 0x00, 0x03, 0x05, 0x07, 0x02, 0x42, 0xfe, + 0x02, 0x42, 0xfe, 0x06, 0x00, 0x04, 0x30, 0x04, + 0x01, 0x20, +}; + +/* MSC -> BSC reset ack */ +const uint8_t bssmap_reset_ack[19] = { + 0x09, 0x00, 0x03, 0x07, 0x0b, 0x04, 0x43, 0x01, + 0x00, 0xfe, 0x04, 0x43, 0x5c, 0x00, 0xfe, 0x03, + 0x00, 0x01, 0x31, +}; + +/* MSC -> BSC paging, connection less */ +const uint8_t bssmap_paging[32] = { + 0x09, 0x00, 0x03, 0x07, 0x0b, 0x04, 0x43, 0x01, + 0x00, 0xfe, 0x04, 0x43, 0x5c, 0x00, 0xfe, 0x10, + 0x00, 0x0e, 0x52, 0x08, 0x08, 0x29, 0x47, 0x10, + 0x02, 0x01, 0x31, 0x97, 0x61, 0x1a, 0x01, 0x06, +}; + +/* MSC -> BSC paging, UDT without PC */ +const uint8_t bssmap_udt[28] = { + 0x09, 0x00, 0x03, 0x05, 0x07, 0x02, 0x42, 0xfe, + 0x02, 0x42, 0xfe, 0x10, 0x00, 0x0e, 0x52, 0x08, + 0x08, 0x29, 0x47, 0x10, 0x02, 0x01, 0x31, 0x97, + 0x61, 0x1a, 0x01, 0x06, +}; + +/* BSC -> MSC connection open */ +const uint8_t bssmap_cr[44] = { + 0x01, 0x01, 0x02, 0x03, 0x02, 0x02, 0x04, 0x02, + 0x42, 0xfe, 0x0f, 0x1f, 0x00, 0x1d, 0x57, 0x05, + 0x08, 0x00, 0x72, 0xf4, 0x80, 0x20, 0x12, 0xc3, + 0x50, 0x17, 0x10, 0x05, 0x24, 0x11, 0x03, 0x33, + 0x19, 0xa2, 0x08, 0x29, 0x47, 0x10, 0x02, 0x01, + 0x31, 0x97, 0x61, 0x00 +}; + +/* MSC -> BSC connection confirm */ +const uint8_t bssmap_cc[10] = { + 0x02, 0x01, 0x02, 0x03, 0x00, 0x00, 0x03, 0x02, 0x01, 0x00, +}; + +/* MSC -> BSC DTAP + * + * we fake a bit and make it BSC -> MSC... so the + * payload does not make any sense.. + */ +const uint8_t bssmap_dtap[22] = { + 0x06, 0x00, 0x00, 0x03, 0x00, 0x01, 0x0f, 0x01, 0x00, 0x0c, + 0x03, 0x05, 0x5c, 0x08, 0x11, 0x81, 0x33, 0x66, 0x02, 0x13, + 0x45, 0xf4, +}; + +/* MSC -> BSC clear command */ +const uint8_t bssmap_clear[13] = { + 0x06, 0x00, 0x00, 0x03, 0x00, 0x01, 0x06, 0x00, 0x04, 0x20, + 0x04, 0x01, 0x09, +}; + +/* MSC -> BSC released */ +const uint8_t bssmap_released[14] = { + 0x04, 0x00, 0x00, 0x03, 0x01, 0x02, 0x03, 0x00, 0x01, 0x0f, + 0x02, 0x23, 0x42, 0x00, +}; + +/* BSC -> MSC released */ +const uint8_t bssmap_release_complete[7] = { + 0x05, 0x01, 0x02, 0x03, 0x00, 0x00, 0x03 +}; + +/* message with a SCCP global title */ +const uint8_t tcap_global_title[183] = { + 0x09, + 0x81, 0x03, 0x0d, 0x18, 0x0a, 0x12, 0x07, 0x00, + 0x12, 0x04, 0x53, 0x84, 0x09, 0x00, 0x17, 0x0b, + 0x12, 0x06, 0x00, 0x12, 0x04, 0x44, 0x87, 0x20, + 0x00, 0x20, 0x65, 0x9a, 0x65, 0x81, 0x97, 0x48, + 0x04, 0x26, 0x00, 0x01, 0x98, 0x49, 0x04, 0x51, + 0x01, 0x03, 0xdf, 0x6c, 0x81, 0x88, 0xa1, 0x81, + 0x85, 0x02, 0x01, 0x44, 0x02, 0x01, 0x07, 0x30, + 0x80, 0xa7, 0x80, 0xa0, 0x80, 0x04, 0x01, 0x2b, + 0x30, 0x80, 0x30, 0x12, 0x83, 0x01, 0x10, 0x84, + 0x01, 0x07, 0x85, 0x07, 0x91, 0x44, 0x57, 0x76, + 0x67, 0x16, 0x97, 0x86, 0x01, 0x20, 0x30, 0x06, + 0x82, 0x01, 0x18, 0x84, 0x01, 0x04, 0x00, 0x00, + 0x00, 0x00, 0xa3, 0x06, 0x04, 0x01, 0x42, 0x84, + 0x01, 0x05, 0xa3, 0x06, 0x04, 0x01, 0x51, 0x84, + 0x01, 0x05, 0xa3, 0x06, 0x04, 0x01, 0x31, 0x84, + 0x01, 0x05, 0xa3, 0x09, 0x04, 0x01, 0x12, 0x84, + 0x01, 0x05, 0x82, 0x01, 0x02, 0xa3, 0x09, 0x04, + 0x01, 0x11, 0x84, 0x01, 0x05, 0x81, 0x01, 0x01, + 0xa3, 0x06, 0x04, 0x01, 0x14, 0x84, 0x01, 0x00, + 0xa3, 0x0b, 0x04, 0x01, 0x41, 0x84, 0x01, 0x04, + 0x30, 0x03, 0x83, 0x01, 0x10, 0xa3, 0x0b, 0x04, + 0x01, 0x41, 0x84, 0x01, 0x04, 0x30, 0x03, 0x82, + 0x01, 0x18, 0x00, 0x00, 0x00, 0x00 +}; diff --git a/tests/xua/sccp_test_data.h b/tests/xua/sccp_test_data.h new file mode 100644 index 0000000..3d70549 --- /dev/null +++ b/tests/xua/sccp_test_data.h @@ -0,0 +1,14 @@ +#pragma once +#include + +extern const uint8_t bssmap_reset[18]; +extern const uint8_t bssmap_reset_ack[19]; +extern const uint8_t bssmap_paging[32]; +extern const uint8_t bssmap_udt[28]; +extern const uint8_t bssmap_cr[44]; +extern const uint8_t bssmap_cc[10]; +extern const uint8_t bssmap_dtap[22]; +extern const uint8_t bssmap_clear[13]; +extern const uint8_t bssmap_released[14]; +extern const uint8_t bssmap_release_complete[7]; +extern const uint8_t tcap_global_title[183]; diff --git a/tests/xua/xua_test.c b/tests/xua/xua_test.c new file mode 100644 index 0000000..74d91c4 --- /dev/null +++ b/tests/xua/xua_test.c @@ -0,0 +1,386 @@ +/* (C) 2011 by Holger Hans Peter Freyther + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +#include "sccp_test_data.h" + +#include "../src/xua_internal.h" + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +static void test_isup_parse(void) +{ + const uint8_t party0[] = { 0x10, 0x32, 0x54, 0x76 }; + char digits[23] = ""; + int rc; + + rc = osmo_isup_party_parse(digits, party0, ARRAY_SIZE(party0), false); + printf("digits='%s' (%d)\n", digits, rc); + OSMO_ASSERT(rc == 8); + OSMO_ASSERT(!strcmp(digits, "01234567")); + + rc = osmo_isup_party_parse(digits, party0, ARRAY_SIZE(party0), true); + printf("digits='%s' (%d)\n", digits, rc); + OSMO_ASSERT(rc == 7); + OSMO_ASSERT(!strcmp(digits, "0123456")); +} + +/* SCCP Address Parsing */ + +static struct sccp_addr_testcase { + struct osmo_sccp_addr expected; + uint8_t *bin; + unsigned int bin_len; +}; + +static uint8_t addr_bin0[] = { 0x92, 0x06, 0x00, 0x12, 0x04, 0x19, 0x99, 0x96, 0x76, 0x39, 0x98 }; +static uint8_t addr_bin1[] = { 0x12, 0x08, 0x00, 0x12, 0x04, 0x19, 0x89, 0x96, 0x92, 0x99, 0x29 }; +static uint8_t addr_bin2[] = { 0x42, 0xfe }; + +static const struct sccp_addr_testcase sccp_addr_testcases[] = { + { + .expected = { + .presence = OSMO_SCCP_ADDR_T_GT | OSMO_SCCP_ADDR_T_SSN, + .ri = OSMO_SCCP_RI_GT, + .gt = { + .gti = OSMO_SCCP_GTI_TT_NPL_ENC_NAI, + .tt = 0, + .npi = OSMO_SCCP_NPI_E164_ISDN, + .nai = OSMO_SCCP_NAI_INTL, + .digits = "919969679389", + }, + .ssn = 6, + }, + .bin = addr_bin0, + .bin_len = ARRAY_SIZE(addr_bin0), + }, { + .expected = { + .presence = OSMO_SCCP_ADDR_T_GT | OSMO_SCCP_ADDR_T_SSN, + .ri = OSMO_SCCP_RI_GT, + .gt = { + .gti = OSMO_SCCP_GTI_TT_NPL_ENC_NAI, + .tt = 0, + .npi = OSMO_SCCP_NPI_E164_ISDN, + .nai = OSMO_SCCP_NAI_INTL, + .digits = "919869299992", + }, + .ssn = 8, + }, + .bin = addr_bin1, + .bin_len = ARRAY_SIZE(addr_bin1), + }, { + .expected = { + .presence = OSMO_SCCP_ADDR_T_SSN, + .ri = OSMO_SCCP_RI_SSN_PC, + .ssn = 254, + }, + .bin = addr_bin2, + .bin_len = ARRAY_SIZE(addr_bin2), + + }, +}; + +static int test_sccp_addr_parse(const struct osmo_sccp_addr *cmp, + const uint8_t *in, unsigned int in_len) +{ + struct osmo_sccp_addr osa; + int rc; + + memset(&osa, 0, sizeof(osa)); + rc = osmo_sccp_addr_parse(&osa, in, in_len); + if (rc < 0) + return rc; + + printf("expected: %s\n", osmo_sccp_addr_dump(cmp)); + printf("parsed: %s\n", osmo_sccp_addr_dump(&osa)); + + if (memcmp(&osa, cmp, sizeof(osa))) { + fprintf(stderr, "expected: %s\n", osmo_hexdump_nospc((uint8_t *)cmp, sizeof(*cmp))); + fprintf(stderr, "parsed: %s\n", osmo_hexdump_nospc((uint8_t *)&osa, sizeof(osa))); + } + + return 0; +} + +static void test_sccp_addr_parser(void) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(sccp_addr_testcases); i++) { + const struct sccp_addr_testcase *tcase = &sccp_addr_testcases[i]; + printf("sccp_addr_parse test case %u\n", i); + test_sccp_addr_parse(&tcase->expected, tcase->bin, tcase->bin_len); + } +} + +/* sccp_addr_testcases[0].expected.gt transcoded into a SUA Global Title IE */ +static const uint8_t expected_sua_gt[] = { + 0x80, 0x01, 0x00, 0x14, 0x00, 0x00, 0x00, 0x04, + 0x0c, 0x00, 0x01, 0x04, 0x19, 0x99, 0x96, 0x76, + 0x39, 0x98, 0x00, 0x00 +}; + +static void test_helpers(void) +{ + struct msgb *msg = msgb_alloc(1024, "foo"); + const struct osmo_sccp_gt *gt_in = &sccp_addr_testcases[0].expected.gt; + struct osmo_sccp_gt gt_out; + + printf("Testing Decoded GT -> SUA encoding\n"); + printf("IN: %s\n", osmo_sccp_gt_dump(gt_in)); + + /* encode sccp_addr to SUA GT */ + xua_part_add_gt(msg, gt_in); + OSMO_ASSERT(msgb_length(msg) == sizeof(expected_sua_gt)); + OSMO_ASSERT(!memcmp(msg->data, expected_sua_gt, sizeof(expected_sua_gt))); + + /* pull the tag+length value */ + msgb_pull(msg, 4); + + /* parse + compare */ + sua_parse_gt(>_out, msgb_data(msg), msgb_length(msg)); + printf("OUT:%s\n", osmo_sccp_gt_dump(>_out)); + OSMO_ASSERT(!memcmp(gt_in, >_out, sizeof(gt_out))); + + msgb_free(msg); +} + +/* SCCP Message Transcoding */ + +struct sccp2sua_testcase { + const char *name; + struct { + const uint8_t *bin; + unsigned int length; + } sccp; + struct { + struct xua_common_hdr hdr; + const struct xua_msg_part parts[32]; + } sua; +}; + +#define PANDSIZ(x) { x, ARRAY_SIZE(x) } +#define PARTU32(x, data) { .tag = x, .len = 4, .dat = (uint8_t *) data } +#define PARTARR(x, data) { .tag = x, .len = ARRAY_SIZE(data), .dat = (uint8_t *) data } + +const uint32_t sua_proto_class0 = 0; +const uint32_t sua_proto_class2 = 2; +const uint32_t sua_loc_ref_bsc = 0x10203; +const uint32_t sua_loc_ref_msc = 0x00003; +const uint32_t sua_cause0 = 0x00003; +const uint8_t sua_addr_ssn_bssmap[] = { 0x00, 0x02, 0x00, 0x07, 0x80, 0x03, 0x00, 0x08, 0x00, 0x00, 0x00, 0xfe }; +const uint8_t sua_addr_ssn_bssmap_pc1[] = { 0x00, 0x01, 0x00, 0x07, 0x80, 0x02, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x80, 0x03, 0x00, 0x08, 0x00, 0x00, 0x00, 0xfe }; +const uint8_t sua_addr_ssn_bssmap_pc92[] = { 0x00, 0x01, 0x00, 0x07, 0x80, 0x02, 0x00, 0x08, 0x00, 0x00, 0x00, 0x5c, 0x80, 0x03, 0x00, 0x08, 0x00, 0x00, 0x00, 0xfe }; + +static const struct sccp2sua_testcase sccp2sua_testcases[] = { + { + .name = "BSSMAP-RESET", + .sccp = PANDSIZ(bssmap_reset), + .sua = { + .hdr = XUA_HDR(SUA_MSGC_CL, SUA_CL_CLDT), + .parts = { + PARTU32(SUA_IEI_PROTO_CLASS, &sua_proto_class0), + PARTARR(SUA_IEI_DEST_ADDR, &sua_addr_ssn_bssmap), + PARTARR(SUA_IEI_SRC_ADDR, &sua_addr_ssn_bssmap), + }, + }, + }, { + .name = "BSSMAP-RESET-ACK", + .sccp = PANDSIZ(bssmap_reset_ack), + .sua = { + .hdr = XUA_HDR(SUA_MSGC_CL, SUA_CL_CLDT), + .parts = { + PARTU32(SUA_IEI_PROTO_CLASS, &sua_proto_class0), + PARTARR(SUA_IEI_DEST_ADDR, &sua_addr_ssn_bssmap_pc1), + PARTARR(SUA_IEI_SRC_ADDR, &sua_addr_ssn_bssmap_pc92), + }, + }, + }, { + .name = "BSSMAP-PAGING", + .sccp = PANDSIZ(bssmap_paging), + .sua = { + .hdr = XUA_HDR(SUA_MSGC_CL, SUA_CL_CLDT), + .parts = { + PARTU32(SUA_IEI_PROTO_CLASS, &sua_proto_class0), + PARTARR(SUA_IEI_DEST_ADDR, &sua_addr_ssn_bssmap_pc1), + PARTARR(SUA_IEI_SRC_ADDR, &sua_addr_ssn_bssmap_pc92), + }, + }, + }, { + .name = "BSSMAP-UDT", + .sccp = PANDSIZ(bssmap_udt), + .sua = { + .hdr = XUA_HDR(SUA_MSGC_CL, SUA_CL_CLDT), + .parts = { + PARTU32(SUA_IEI_PROTO_CLASS, &sua_proto_class0), + PARTARR(SUA_IEI_DEST_ADDR, &sua_addr_ssn_bssmap), + PARTARR(SUA_IEI_SRC_ADDR, &sua_addr_ssn_bssmap), + }, + }, + }, { + .name = "BSSMAP-CR", + .sccp = PANDSIZ(bssmap_cr), + .sua = { + .hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_CORE), + .parts = { + PARTU32(SUA_IEI_PROTO_CLASS, &sua_proto_class2), + PARTU32(SUA_IEI_SRC_REF, &sua_loc_ref_bsc), + PARTARR(SUA_IEI_DEST_ADDR, &sua_addr_ssn_bssmap), + }, + }, + }, { + .name = "BSSMAP-CC", + .sccp = PANDSIZ(bssmap_cc), + .sua = { + .hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_COAK), + .parts = { + PARTU32(SUA_IEI_PROTO_CLASS, &sua_proto_class2), + PARTU32(SUA_IEI_SRC_REF, &sua_loc_ref_msc), + PARTARR(SUA_IEI_DEST_ADDR, &sua_loc_ref_bsc), + }, + }, + }, { + .name = "BSSMAP-DTAP", + .sccp = PANDSIZ(bssmap_dtap), + .sua = { + .hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_CODT), + .parts = { + PARTU32(SUA_IEI_SRC_REF, &sua_loc_ref_msc), + }, + }, + }, { + .name = "BSSMAP-CLEAR", + .sccp = PANDSIZ(bssmap_clear), + .sua = { + .hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_CODT), + .parts = { + PARTU32(SUA_IEI_SRC_REF, &sua_loc_ref_msc), + }, + }, + }, { + .name = "BSSMAP-RELEASED", + .sccp = PANDSIZ(bssmap_released), + .sua = { + .hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_RELRE), + .parts = { + PARTU32(SUA_IEI_DEST_REF, &sua_loc_ref_msc), + PARTU32(SUA_IEI_SRC_REF, &sua_loc_ref_bsc), + PARTU32(SUA_IEI_CAUSE, &sua_cause0), + }, + }, + }, { + .name = "BSSMAP-RELEASE_COMPLETE", + .sccp = PANDSIZ(bssmap_release_complete), + .sua = { + .hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_RELCO), + .parts = { + PARTU32(SUA_IEI_DEST_REF, &sua_loc_ref_bsc), + PARTU32(SUA_IEI_SRC_REF, &sua_loc_ref_msc), + }, + }, + }, { + .name = "TCAP", + .sccp = PANDSIZ(tcap_global_title), + .sua = { + .hdr = XUA_HDR(SUA_MSGC_CL, SUA_CL_CLDT), + .parts = { + }, + }, + }, +}; + +static void test_sccp2sua_case(const struct sccp2sua_testcase *tcase) +{ + struct xua_msg *xua; + struct msgb *msg = msgb_alloc(300, "SCCP2SUA Test Input"); + struct msgb *msg2; + + printf("\n=> %s\n", tcase->name); + msg->l2h = msgb_put(msg, tcase->sccp.length); + memcpy(msg->l2h, tcase->sccp.bin, tcase->sccp.length); + printf("SCCP Input: %s\n", msgb_hexdump(msg)); + printf("Transcoding message SCCP -> XUA\n"); + xua = osmo_sccp_to_xua(msg); + OSMO_ASSERT(xua); + + printf("Decoded SUA: "); + printf("%s\n", xua_msg_dump(xua, &xua_dialect_sua)); + + printf("Re-Encoding decoded SUA to SCCP\n"); + msg2 = osmo_sua_to_sccp(xua); + OSMO_ASSERT(msg2); + /* Re-encode xUA to SCCP */ + printf("SCCP Output: %s\n", msgb_hexdump(msg2)); + + if (msgb_length(msg) != msgb_length(msg2) || + memcmp(msgb_data(msg), msgb_data(msg2), msgb_length(msg))) + printf("Input != re-encoded output!\n"); + + /* free related data */ + msgb_free(msg); + msgb_free(msg2); + xua_msg_free(xua); +} + +static void test_sccp2sua(void) +{ + unsigned int i; + for (i = 0; i < ARRAY_SIZE(sccp2sua_testcases); i++) { + test_sccp2sua_case(&sccp2sua_testcases[i]); + } +} + + +static const struct log_info_cat default_categories[] = { + [0] = { + .name = "DSCCP", + .description = "DSCP", + .enabled = 1, .loglevel = LOGL_DEBUG, + }, +}; + +static const struct log_info log_info = { + .cat = default_categories, + .num_cat = ARRAY_SIZE(default_categories), +}; + +int main(int argc, char **argv) +{ + struct log_target *stderr_target; + log_init(&log_info, NULL); + stderr_target = log_target_create_stderr(); + log_add_target(stderr_target); + + test_isup_parse(); + test_sccp_addr_parser(); + test_helpers(); + test_sccp2sua(); + + printf("All tests passed.\n"); + return 0; +} diff --git a/tests/xua/xua_test.ok b/tests/xua/xua_test.ok new file mode 100644 index 0000000..a9fba1d --- /dev/null +++ b/tests/xua/xua_test.ok @@ -0,0 +1,131 @@ +digits='01234567' (8) +digits='0123456' (7) +sccp_addr_parse test case 0 +expected: RI=7,SSN=6,GTI=4,GT=(TT=0,NPL=1,NAI=4,DIG=919969679389) +parsed: RI=7,SSN=6,GTI=4,GT=(TT=0,NPL=1,NAI=4,DIG=919969679389) +sccp_addr_parse test case 1 +expected: RI=7,SSN=8,GTI=4,GT=(TT=0,NPL=1,NAI=4,DIG=919869299992) +parsed: RI=7,SSN=8,GTI=4,GT=(TT=0,NPL=1,NAI=4,DIG=919869299992) +sccp_addr_parse test case 2 +expected: RI=7,SSN=254,GTI=0 +parsed: RI=7,SSN=254,GTI=0 +Testing Decoded GT -> SUA encoding +IN: TT=0,NPL=1,NAI=4,DIG=919969679389 +OUT:TT=0,NPL=1,NAI=4,DIG=919969679389 + +=> BSSMAP-RESET +SCCP Input: [L2]> 09 00 03 05 07 02 42 fe 02 42 fe 06 00 04 30 04 01 20 +Transcoding message SCCP -> XUA +Decoded SUA: HDR=(CL:CLDT,V=0,LEN=0), + PART(T=Protocol Class,L=4,D=00000000), + PART(T=Destination Address,L=12,D=0002000180030008000000fe), + PART(T=Source Address,L=12,D=0002000180030008000000fe), + PART(T=Data,L=6,D=000430040120) +Re-Encoding decoded SUA to SCCP +SCCP Output: 09 00 03 05 07 02 42 fe 02 42 fe 06 00 04 30 04 01 20 + +=> BSSMAP-RESET-ACK +SCCP Input: [L2]> 09 00 03 07 0b 04 43 01 00 fe 04 43 5c 00 fe 03 00 01 31 +Transcoding message SCCP -> XUA +Decoded SUA: HDR=(CL:CLDT,V=0,LEN=0), + PART(T=Protocol Class,L=4,D=00000000), + PART(T=Destination Address,L=20,D=00020003800200080000000180030008000000fe), + PART(T=Source Address,L=20,D=00020003800200080000005c80030008000000fe), + PART(T=Data,L=3,D=000131) +Re-Encoding decoded SUA to SCCP +SCCP Output: 09 00 03 07 0b 04 43 01 00 fe 04 43 5c 00 fe 03 00 01 31 + +=> BSSMAP-PAGING +SCCP Input: [L2]> 09 00 03 07 0b 04 43 01 00 fe 04 43 5c 00 fe 10 00 0e 52 08 08 29 47 10 02 01 31 97 61 1a 01 06 +Transcoding message SCCP -> XUA +Decoded SUA: HDR=(CL:CLDT,V=0,LEN=0), + PART(T=Protocol Class,L=4,D=00000000), + PART(T=Destination Address,L=20,D=00020003800200080000000180030008000000fe), + PART(T=Source Address,L=20,D=00020003800200080000005c80030008000000fe), + PART(T=Data,L=16,D=000e52080829471002013197611a0106) +Re-Encoding decoded SUA to SCCP +SCCP Output: 09 00 03 07 0b 04 43 01 00 fe 04 43 5c 00 fe 10 00 0e 52 08 08 29 47 10 02 01 31 97 61 1a 01 06 + +=> BSSMAP-UDT +SCCP Input: [L2]> 09 00 03 05 07 02 42 fe 02 42 fe 10 00 0e 52 08 08 29 47 10 02 01 31 97 61 1a 01 06 +Transcoding message SCCP -> XUA +Decoded SUA: HDR=(CL:CLDT,V=0,LEN=0), + PART(T=Protocol Class,L=4,D=00000000), + PART(T=Destination Address,L=12,D=0002000180030008000000fe), + PART(T=Source Address,L=12,D=0002000180030008000000fe), + PART(T=Data,L=16,D=000e52080829471002013197611a0106) +Re-Encoding decoded SUA to SCCP +SCCP Output: 09 00 03 05 07 02 42 fe 02 42 fe 10 00 0e 52 08 08 29 47 10 02 01 31 97 61 1a 01 06 + +=> BSSMAP-CR +SCCP Input: [L2]> 01 01 02 03 02 02 04 02 42 fe 0f 1f 00 1d 57 05 08 00 72 f4 80 20 12 c3 50 17 10 05 24 11 03 33 19 a2 08 29 47 10 02 01 31 97 61 00 +Transcoding message SCCP -> XUA +Decoded SUA: HDR=(CO:CORE,V=0,LEN=0), + PART(T=Protocol Class,L=4,D=00000002), + PART(T=Source Reference,L=4,D=00010203), + PART(T=Destination Address,L=12,D=0002000180030008000000fe), + PART(T=Data,L=31,D=001d5705080072f4802012c3501710052411033319a2082947100201319761) +Re-Encoding decoded SUA to SCCP +SCCP Output: 01 01 02 03 02 02 04 02 42 fe 0f 1f 00 1d 57 05 08 00 72 f4 80 20 12 c3 50 17 10 05 24 11 03 33 19 a2 08 29 47 10 02 01 31 97 61 00 + +=> BSSMAP-CC +SCCP Input: [L2]> 02 01 02 03 00 00 03 02 01 00 +Transcoding message SCCP -> XUA +Decoded SUA: HDR=(CO:COAK,V=0,LEN=0), + PART(T=Protocol Class,L=4,D=00000002), + PART(T=Destination Reference,L=4,D=00010203), + PART(T=Source Reference,L=4,D=00000003) +Re-Encoding decoded SUA to SCCP +SCCP Output: 02 01 02 03 00 00 03 02 01 00 + +=> BSSMAP-DTAP +SCCP Input: [L2]> 06 00 00 03 00 01 0f 01 00 0c 03 05 5c 08 11 81 33 66 02 13 45 f4 +Transcoding message SCCP -> XUA +Decoded SUA: HDR=(CO:CODT,V=0,LEN=0), + PART(T=Destination Reference,L=4,D=00000003), + PART(T=Segmentation,L=4,D=00000000), + PART(T=Data,L=15,D=01000c03055c0811813366021345f4) +Re-Encoding decoded SUA to SCCP +SCCP Output: 06 00 00 03 00 01 0f 01 00 0c 03 05 5c 08 11 81 33 66 02 13 45 f4 + +=> BSSMAP-CLEAR +SCCP Input: [L2]> 06 00 00 03 00 01 06 00 04 20 04 01 09 +Transcoding message SCCP -> XUA +Decoded SUA: HDR=(CO:CODT,V=0,LEN=0), + PART(T=Destination Reference,L=4,D=00000003), + PART(T=Segmentation,L=4,D=00000000), + PART(T=Data,L=6,D=000420040109) +Re-Encoding decoded SUA to SCCP +SCCP Output: 06 00 00 03 00 01 06 00 04 20 04 01 09 + +=> BSSMAP-RELEASED +SCCP Input: [L2]> 04 00 00 03 01 02 03 00 01 0f 02 23 42 00 +Transcoding message SCCP -> XUA +Decoded SUA: HDR=(CO:RELRE,V=0,LEN=0), + PART(T=Destination Reference,L=4,D=00000003), + PART(T=Source Reference,L=4,D=00010203), + PART(T=Cause,L=4,D=00000300), + PART(T=Data,L=2,D=2342) +Re-Encoding decoded SUA to SCCP +SCCP Output: 04 00 00 03 01 02 03 00 01 0f 02 23 42 00 + +=> BSSMAP-RELEASE_COMPLETE +SCCP Input: [L2]> 05 01 02 03 00 00 03 +Transcoding message SCCP -> XUA +Decoded SUA: HDR=(CO:RELCO,V=0,LEN=0), + PART(T=Destination Reference,L=4,D=00010203), + PART(T=Source Reference,L=4,D=00000003) +Re-Encoding decoded SUA to SCCP +SCCP Output: 05 01 02 03 00 00 03 + +=> TCAP +SCCP Input: [L2]> 09 81 03 0d 18 0a 12 07 00 12 04 53 84 09 00 17 0b 12 06 00 12 04 44 87 20 00 20 65 9a 65 81 97 48 04 26 00 01 98 49 04 51 01 03 df 6c 81 88 a1 81 85 02 01 44 02 01 07 30 80 a7 80 a0 80 04 01 2b 30 80 30 12 83 01 10 84 01 07 85 07 91 44 57 76 67 16 97 86 01 20 30 06 82 01 18 84 01 04 00 00 00 00 a3 06 04 01 42 84 01 05 a3 06 04 01 51 84 01 05 a3 06 04 01 31 84 01 05 a3 09 04 01 12 84 01 05 82 01 02 a3 09 04 01 11 84 01 05 81 01 01 a3 06 04 01 14 84 01 00 a3 0b 04 01 41 84 01 04 30 03 83 01 10 a3 0b 04 01 41 84 01 04 30 03 82 01 18 00 00 00 00 +Transcoding message SCCP -> XUA +Decoded SUA: HDR=(CL:CLDT,V=0,LEN=0), + PART(T=Protocol Class,L=4,D=00000081), + PART(T=Destination Address,L=32,D=0001000580010014000000040a00010453840900170000008003000800000007), + PART(T=Source Address,L=32,D=0001000580010014000000040c00010444872000206500008003000800000006), + PART(T=Data,L=154,D=6581974804260001984904510103df6c8188a181850201440201073080a780a08004012b30803012830110840107850791445776671697860120300682011884010400000000a306040142840105a306040151840105a306040131840105a309040112840105820102a309040111840105810101a306040114840100a30b0401418401043003830110a30b040141840104300382011800000000) +Re-Encoding decoded SUA to SCCP +SCCP Output: 09 81 03 0d 18 0a 12 07 00 12 04 53 84 09 00 17 0b 12 06 00 12 04 44 87 20 00 20 65 9a 65 81 97 48 04 26 00 01 98 49 04 51 01 03 df 6c 81 88 a1 81 85 02 01 44 02 01 07 30 80 a7 80 a0 80 04 01 2b 30 80 30 12 83 01 10 84 01 07 85 07 91 44 57 76 67 16 97 86 01 20 30 06 82 01 18 84 01 04 00 00 00 00 a3 06 04 01 42 84 01 05 a3 06 04 01 51 84 01 05 a3 06 04 01 31 84 01 05 a3 09 04 01 12 84 01 05 82 01 02 a3 09 04 01 11 84 01 05 81 01 01 a3 06 04 01 14 84 01 00 a3 0b 04 01 41 84 01 04 30 03 83 01 10 a3 0b 04 01 41 84 01 04 30 03 82 01 18 00 00 00 00 +All tests passed. -- To view, visit https://gerrit.osmocom.org/2214 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I7ce038d72dca18fb83d5a12519c9a48267e52ab8 Gerrit-PatchSet: 4 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:31:09 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:31:09 +0000 Subject: [PATCH] libosmo-sccp[master]: Add new SCCP implementation In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2215 to look at the new patch set (#5). Add new SCCP implementation This is an implementation of SCCP as specified in ITO-T Q.71x, particularly the SCRC (routing), SCLC (Connectionless) and SCOC (Connection Oriented) portions. the elaborate state machines of SCOC are implemented using osmo_fsm, with one state machine for each connection. Interfaces to the top (user application) are the SCCP-USER-SAP and on the bottom (network) side the MTP-USER-SAP as provided by osmo_ss7. Contrary to a straight-forward implementation, the code internally always uses a SUA representation of all messages (in struct xua_msg). This enables us to have one common implementation of all related state machines and use them for both SUA and SCCP. If used with real SCCP wire format, all messages are translated from SCCP to SUA on ingress and translated from SUA to SCCP on egress. As SUA is a super-set of SCCP, this can be done "lossless". Change-Id: I916e895d9a4914b05483fe12ab5251f206d10dee --- M include/osmocom/sigtran/sccp_sap.h M src/Makefile.am M src/osmo_ss7.c M src/sccp_internal.h A src/sccp_sclc.c A src/sccp_scoc.c A src/sccp_scrc.c A src/sccp_user.c 8 files changed, 2,968 insertions(+), 2 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/15/2215/5 diff --git a/include/osmocom/sigtran/sccp_sap.h b/include/osmocom/sigtran/sccp_sap.h index 0cc1531..c1464f0 100644 --- a/include/osmocom/sigtran/sccp_sap.h +++ b/include/osmocom/sigtran/sccp_sap.h @@ -222,3 +222,23 @@ #define msgb_scu_prim(msg) ((struct osmo_scu_prim *)(msg)->l1h) char *osmo_scu_prim_name(struct osmo_prim_hdr *oph); + +struct osmo_ss7_instance; +struct osmo_sccp_instance; +struct osmo_sccp_user; + +struct osmo_sccp_instance * +osmo_sccp_instance_create(struct osmo_ss7_instance *ss7, void *priv); +void osmo_sccp_instance_destroy(struct osmo_sccp_instance *inst); + +void osmo_sccp_user_unbind(struct osmo_sccp_user *scu); + +struct osmo_sccp_user * +osmo_sccp_user_bind_pc(struct osmo_sccp_instance *inst, const char *name, + osmo_prim_cb prim_cb, uint16_t ssn, uint32_t pc); + +struct osmo_sccp_user * +osmo_sccp_user_bind(struct osmo_sccp_instance *inst, const char *name, + osmo_prim_cb prim_cb, uint16_t ssn); + +int osmo_sccp_user_sap_down(struct osmo_sccp_user *scu, struct osmo_prim_hdr *oph); diff --git a/src/Makefile.am b/src/Makefile.am index 4455127..a4cfeeb 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -27,7 +27,8 @@ LIBVERSION=0:0:0 libosmo_sigtran_la_SOURCES = sccp_sap.c sua.c m3ua.c xua_msg.c sccp_helpers.c \ - sccp2sua.c \ + sccp2sua.c sccp_scrc.c sccp_sclc.c sccp_scoc.c \ + sccp_user.c \ osmo_ss7.c osmo_ss7_hmrt.c xua_asp_fsm.c xua_as_fsm.c libosmo_sigtran_la_LDFLAGS = -version-info $(LIBVERSION) -no-undefined -export-symbols-regex '^osmo_' libosmo_sigtran_la_LIBADD = $(LIBOSMOCORE_LIBS) $(LIBOSMONETIF_LIBS) $(LIBSCTP_LIBS) diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index 74c54bb..6d0b446 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -41,6 +41,7 @@ #include +#include "sccp_internal.h" #include "xua_internal.h" #include "xua_asp_fsm.h" #include "xua_as_fsm.h" @@ -1483,6 +1484,7 @@ { if (ss7_initialized) return 1; + osmo_fsm_register(&sccp_scoc_fsm); osmo_fsm_register(&xua_as_fsm); osmo_fsm_register(&xua_asp_fsm); ss7_initialized = true; diff --git a/src/sccp_internal.h b/src/sccp_internal.h index 7287a82..c35ef4b 100644 --- a/src/sccp_internal.h +++ b/src/sccp_internal.h @@ -1,5 +1,89 @@ #pragma once -#include +#include +#include +#include +#include + +/* an instance of the SCCP stack */ +struct osmo_sccp_instance { + /* entry in global list of ss7 instances */ + struct llist_head list; + /* list of 'struct sccp_connection' in this instance */ + struct llist_head connections; + /* list of SCCP users in this instance */ + struct llist_head users; + /* routing context to be used in all outbound messages */ + uint32_t route_ctx; + /* next local reference to allocate */ + uint32_t next_id; + struct osmo_ss7_instance *ss7; + void *priv; + + struct osmo_ss7_user ss7_user; +}; + +struct osmo_sccp_user { + /*! \brief entry in list of sccp users of \ref osmo_sccp_instance */ + struct llist_head list; + /*! \brief pointer back to SCCP instance */ + struct osmo_sccp_instance *inst; + /*! \brief human-readable name of this user */ + char *name; + + /*! \brief SSN and/or point code to which we are bound */ + uint16_t ssn; + uint32_t pc; + bool pc_valid; + + /* set if we are a server */ + struct llist_head links; + + /* user call-back function in case of incoming primitives */ + osmo_prim_cb prim_cb; + void *priv; + + /* Application Server FSM Instance */ + struct osmo_fsm_inst *as_fi; +}; + +extern int DSCCP; + +struct xua_msg; + +struct osmo_sccp_user * +sccp_user_find(struct osmo_sccp_instance *inst, uint16_t ssn, uint32_t pc); + +/* Message from SCOC -> SCRC */ +int sccp_scrc_rx_scoc_conn_msg(struct osmo_sccp_instance *inst, + struct xua_msg *xua); + +/* Message from SCLC -> SCRC */ +int sccp_scrc_rx_sclc_msg(struct osmo_sccp_instance *inst, struct xua_msg *xua); + +/* Message from MTP (SUA) -> SCRC */ +int scrc_rx_mtp_xfer_ind_xua(struct osmo_sccp_instance *inst, + struct xua_msg *xua); + +/* Message from SCRC -> SCOC */ +void sccp_scoc_rx_from_scrc(struct osmo_sccp_instance *inst, + struct xua_msg *xua); +void sccp_scoc_rx_scrc_rout_fail(struct osmo_sccp_instance *inst, + struct xua_msg *xua, uint32_t cause); + +void sccp_scoc_flush_connections(struct osmo_sccp_instance *inst); + +/* Message from SCRC -> SCLC */ +int sccp_sclc_rx_from_scrc(struct osmo_sccp_instance *inst, + struct xua_msg *xua); +void sccp_sclc_rx_scrc_rout_fail(struct osmo_sccp_instance *inst, + struct xua_msg *xua, uint32_t cause); + +int sccp_user_prim_up(struct osmo_sccp_user *scut, struct osmo_scu_prim *prim); + +/* SCU -> SCLC */ +int sccp_sclc_user_sap_down(struct osmo_sccp_user *scu, struct osmo_prim_hdr *oph); struct msgb *sccp_msgb_alloc(const char *name); + +struct osmo_fsm sccp_scoc_fsm; diff --git a/src/sccp_sclc.c b/src/sccp_sclc.c new file mode 100644 index 0000000..dae2c36 --- /dev/null +++ b/src/sccp_sclc.c @@ -0,0 +1,337 @@ +/* SCCP Connectionless Control (SCLC) according to ITU-T Q.713/Q.714 */ + +/* (C) 2015-2017 by Harald Welte + * All Rights reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/* This code is a bit of a hybrid between the ITU-T Q.71x specifications + * for SCCP (particularly its connection-oriented part), and the IETF + * RFC 3868 (SUA). The idea here is to have one shared code base of the + * state machines for SCCP Connection Oriented, and use those both from + * SCCP and SUA. + * + * To do so, all SCCP messages are translated to SUA messages in the + * input side, and all generated SUA messages are translated to SCCP on + * the output side. + * + * The Choice of going for SUA messages as the "native" format was based + * on their easier parseability, and the fact that there are features in + * SUA which classic SCCP cannot handle (like IP addresses in GT). + * However, all SCCP features can be expressed in SUA. + * + * The code only supports Class 2. No support for Class 3 is intended, + * but patches are of course alwys welcome. + * + * Missing other features: + * * Segmentation/Reassembly support + * * T(guard) after (re)start + * * freezing of local references + * * parsing/encoding of IPv4/IPv6 addresses + * * use of multiple Routing Contexts in SUA case + */ + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "xua_internal.h" +#include "sccp_internal.h" + +/* generate a 'struct xua_msg' of requested type from primitive data */ +static struct xua_msg *xua_gen_msg_cl(uint32_t event, + struct osmo_scu_prim *prim, int msg_type) +{ + struct xua_msg *xua = xua_msg_alloc(); + struct osmo_scu_unitdata_param *udpar = &prim->u.unitdata; + + if (!xua) + return NULL; + + switch (msg_type) { + case SUA_CL_CLDT: + xua->hdr = XUA_HDR(SUA_MSGC_CL, SUA_CL_CLDT); + xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, 0); /* FIXME */ + xua_msg_add_u32(xua, SUA_IEI_PROTO_CLASS, 0); + xua_msg_add_sccp_addr(xua, SUA_IEI_SRC_ADDR, &udpar->calling_addr); + xua_msg_add_sccp_addr(xua, SUA_IEI_DEST_ADDR, &udpar->called_addr); + xua_msg_add_u32(xua, SUA_IEI_SEQ_CTRL, udpar->in_sequence_control); + /* optional: importance, ... correlation id? */ + if (!prim) + goto prim_needed; + xua_msg_add_data(xua, SUA_IEI_DATA, msgb_l2len(prim->oph.msg), + msgb_l2(prim->oph.msg)); + break; + default: + LOGP(DLSCCP, LOGL_ERROR, "Unknown msg_type %u\n", msg_type); + xua_msg_free(xua); + return NULL; + } + return xua; + +prim_needed: + xua_msg_free(xua); + LOGP(DLSCCP, LOGL_ERROR, "%s must be called with valid 'prim' " + "pointer for msg_type=%u\n", __func__, msg_type); + return NULL; +} + +/* generate xua_msg, encode it and send it to SCRC */ +static int xua_gen_encode_and_send(struct osmo_sccp_user *scu, uint32_t event, + struct osmo_scu_prim *prim, int msg_type) +{ + struct xua_msg *xua; + + xua = xua_gen_msg_cl(event, prim, msg_type); + if (!xua) + return -1; + + return sccp_scrc_rx_sclc_msg(scu->inst, xua); +} + +/*! \brief Main entrance function for primitives from SCCP User + * \param[in] scu SCCP User who is sending the primitive + * \param[on] oph Osmocom primitive header of the primitive + * \returns 0 on success; negtive in case of error */ +int sccp_sclc_user_sap_down(struct osmo_sccp_user *scu, struct osmo_prim_hdr *oph) +{ + struct osmo_scu_prim *prim = (struct osmo_scu_prim *) oph; + struct msgb *msg = prim->oph.msg; + int rc = 0; + + /* we get called from osmo_sccp_user_sap_down() which already + * has debug-logged the primitive */ + + switch (OSMO_PRIM_HDR(&prim->oph)) { + case OSMO_PRIM(OSMO_SCU_PRIM_N_UNITDATA, PRIM_OP_REQUEST): + /* Connectionless by-passes this altogether */ + rc = xua_gen_encode_and_send(scu, -1, prim, SUA_CL_CLDT); + goto out; + default: + LOGP(DLSCCP, LOGL_ERROR, "Received unknown SCCP User " + "primitive %s from user\n", + osmo_scu_prim_name(&prim->oph)); + rc = -1; + goto out; + } + +out: + /* the SAP is supposed to consume the primitive/msgb */ + msgb_free(msg); + + return rc; +} + +/* Process an incoming CLDT message (from a remote peer) */ +static int sclc_rx_cldt(struct osmo_sccp_instance *inst, struct xua_msg *xua) +{ + struct osmo_scu_prim *prim; + struct osmo_scu_unitdata_param *param; + struct xua_msg_part *data_ie = xua_msg_find_tag(xua, SUA_IEI_DATA); + struct msgb *upmsg = sccp_msgb_alloc(__func__); + struct osmo_sccp_user *scu; + uint32_t protocol_class; + + /* fill primitive */ + prim = (struct osmo_scu_prim *) msgb_put(upmsg, sizeof(*prim)); + param = &prim->u.unitdata; + osmo_prim_init(&prim->oph, SCCP_SAP_USER, + OSMO_SCU_PRIM_N_UNITDATA, + PRIM_OP_INDICATION, upmsg); + sua_addr_parse(¶m->called_addr, xua, SUA_IEI_DEST_ADDR); + sua_addr_parse(¶m->calling_addr, xua, SUA_IEI_SRC_ADDR); + param->in_sequence_control = xua_msg_get_u32(xua, SUA_IEI_SEQ_CTRL); + protocol_class = xua_msg_get_u32(xua, SUA_IEI_PROTO_CLASS); + param->return_option = protocol_class & 0x80; + param->importance = xua_msg_get_u32(xua, SUA_IEI_IMPORTANCE); + + scu = sccp_user_find(inst, param->called_addr.ssn, + param->called_addr.pc); + + if (!scu) { + /* FIXME: Send destination unreachable? */ + LOGP(DLSUA, LOGL_NOTICE, "Received SUA message for unequipped SSN %u\n", + param->called_addr.ssn); + msgb_free(upmsg); + return 0; + } + + /* copy data */ + upmsg->l2h = msgb_put(upmsg, data_ie->len); + memcpy(upmsg->l2h, data_ie->dat, data_ie->len); + + /* send to user SAP */ + sccp_user_prim_up(scu, prim); + + /* xua_msg is free'd by our caller */ + return 0; +} + +static int sclc_rx_cldr(struct osmo_sccp_instance *inst, struct xua_msg *xua) +{ + struct osmo_scu_prim *prim; + struct osmo_scu_notice_param *param; + struct xua_msg_part *data_ie = xua_msg_find_tag(xua, SUA_IEI_DATA); + struct msgb *upmsg = sccp_msgb_alloc(__func__); + struct osmo_sccp_user *scu; + + /* fill primitive */ + prim = (struct osmo_scu_prim *) msgb_put(upmsg, sizeof(*prim)); + param = &prim->u.notice; + osmo_prim_init(&prim->oph, SCCP_SAP_USER, + OSMO_SCU_PRIM_N_NOTICE, + PRIM_OP_INDICATION, upmsg); + + sua_addr_parse(¶m->called_addr, xua, SUA_IEI_DEST_ADDR); + sua_addr_parse(¶m->calling_addr, xua, SUA_IEI_SRC_ADDR); + param->importance = xua_msg_get_u32(xua, SUA_IEI_IMPORTANCE); + param->cause = xua_msg_get_u32(xua, SUA_IEI_CAUSE); + + scu = sccp_user_find(inst, param->called_addr.ssn, + param->called_addr.pc); + if (!scu) { + /* FIXME: Send destination unreachable? */ + LOGP(DLSUA, LOGL_NOTICE, "Received CLDR for unequipped SSN %u\n", + param->called_addr.ssn); + msgb_free(upmsg); + return 0; + } + + /* copy data */ + upmsg->l2h = msgb_put(upmsg, data_ie->len); + memcpy(upmsg->l2h, data_ie->dat, data_ie->len); + + /* send to user SAP */ + sccp_user_prim_up(scu, prim); + + /* xua_msg is free'd by our caller */ + return 0; +} + +/*! \brief SCRC -> SCLC (connectionless message) + * \param[in] inst SCCP Instance in which we operate + * \param[in] xua SUA connectionless message + * \returns 0 on success; negative on error */ +int sccp_sclc_rx_from_scrc(struct osmo_sccp_instance *inst, + struct xua_msg *xua) +{ + int rc = -1; + + OSMO_ASSERT(xua->hdr.msg_class == SUA_MSGC_CL); + + switch (xua->hdr.msg_type) { + case SUA_CL_CLDT: + rc = sclc_rx_cldt(inst, xua); + break; + case SUA_CL_CLDR: + rc = sclc_rx_cldr(inst, xua); + break; + default: + LOGP(DLSUA, LOGL_NOTICE, "Received unknown/unsupported " + "message %s\n", xua_hdr_dump(xua, &xua_dialect_sua)); + break; + } + + return rc; +} + +/* generate a return/refusal message (SUA CLDR == SCCP UDTS) based on + * the incoming message. We need to flip all identities between sender + * and receiver */ +static struct xua_msg *gen_ret_msg(struct osmo_sccp_instance *inst, + const struct xua_msg *xua_in, + uint32_t ret_cause) +{ + struct xua_msg *xua_out = xua_msg_alloc(); + struct osmo_sccp_addr called; + + xua_out->hdr = XUA_HDR(SUA_MSGC_CL, SUA_CL_CLDR); + xua_msg_add_u32(xua_out, SUA_IEI_ROUTE_CTX, inst->route_ctx); + xua_msg_add_u32(xua_out, SUA_IEI_CAUSE, + SUA_CAUSE_T_RETURN | ret_cause); + /* Swap Calling and Called Party */ + xua_msg_copy_part(xua_out, SUA_IEI_SRC_ADDR, xua_in, SUA_IEI_DEST_ADDR); + xua_msg_copy_part(xua_out, SUA_IEI_DEST_ADDR, xua_in, SUA_IEI_SRC_ADDR); + /* TODO: Optional: Hop Count */ + /* Optional: Importance */ + xua_msg_copy_part(xua_out, SUA_IEI_IMPORTANCE, + xua_in, SUA_IEI_IMPORTANCE); + /* Optional: Message Priority */ + xua_msg_copy_part(xua_out, SUA_IEI_MSG_PRIO, xua_in, SUA_IEI_MSG_PRIO); + /* Optional: Correlation ID */ + xua_msg_copy_part(xua_out, SUA_IEI_CORR_ID, xua_in, SUA_IEI_CORR_ID); + /* Optional: Segmentation */ + xua_msg_copy_part(xua_out, SUA_IEI_SEGMENTATION, + xua_in, SUA_IEI_SEGMENTATION); + /* Optional: Data */ + xua_msg_copy_part(xua_out, SUA_IEI_DATA, xua_in, SUA_IEI_DATA); + + sua_addr_parse(&called, xua_out, SUA_IEI_DEST_ADDR); + /* Route on PC + SSN ? */ + if (called.ri == OSMO_SCCP_RI_SSN_PC) { + /* if no PC, copy OPC into called addr */ + if (!(called.presence & OSMO_SCCP_ADDR_T_PC)) { + struct osmo_sccp_addr calling; + sua_addr_parse(&calling, xua_out, SUA_IEI_SRC_ADDR); + called.presence |= OSMO_SCCP_ADDR_T_PC; + called.pc = calling.pc; + /* Re-encode / replace called address */ + xua_msg_free_tag(xua_out, SUA_IEI_DEST_ADDR); + xua_msg_add_sccp_addr(xua_out, SUA_IEI_DEST_ADDR, + &called); + } + } + return xua_out; +} + +/*! \brief SCRC -> SCLC (Routing Failure + * \param[in] inst SCCP Instance in which we operate + * \param[in] xua_in Message that failed to be routed + * \param[in] cause SCCP Return Cause */ +void sccp_sclc_rx_scrc_rout_fail(struct osmo_sccp_instance *inst, + struct xua_msg *xua_in, uint32_t cause) +{ + struct xua_msg *xua_out; + + /* Figure C.12/Q.714 (Sheet 8) Node 9 */ + switch (xua_in->hdr.msg_type) { + case SUA_CL_CLDT: + xua_out = gen_ret_msg(inst, xua_in, cause); + /* TODO: Message Return Option? */ + if (!osmo_ss7_pc_is_local(inst->ss7, xua_in->mtp.opc)) { + /* non-local originator: send UDTS */ + /* TODO: Assign SLS */ + sccp_scrc_rx_sclc_msg(inst, xua_out); + } else { + /* local originator: send N-NOTICE to user */ + /* TODO: N-NOTICE.ind SCLC -> SCU */ + sclc_rx_cldr(inst, xua_out); + xua_msg_free(xua_out); + } + break; + case SUA_CL_CLDR: + /* do nothing */ + break; + } +} diff --git a/src/sccp_scoc.c b/src/sccp_scoc.c new file mode 100644 index 0000000..cb592e6 --- /dev/null +++ b/src/sccp_scoc.c @@ -0,0 +1,1672 @@ +/* SCCP Connection Oriented (SCOC) according to ITU-T Q.713/Q.714 */ + +/* (C) 2015-2017 by Harald Welte + * All Rights reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/* This code is a bit of a hybrid between the ITU-T Q.71x specifications + * for SCCP (particularly its connection-oriented part), and the IETF + * RFC 3868 (SUA). The idea here is to have one shared code base of the + * state machines for SCCP Connection Oriented, and use those both from + * SCCP and SUA. + * + * To do so, all SCCP messages are translated to SUA messages in the + * input side, and all generated SUA messages are translated to SCCP on + * the output side. + * + * The Choice of going for SUA messages as the "native" format was based + * on their easier parseability, and the fact that there are features in + * SUA which classic SCCP cannot handle (like IP addresses in GT). + * However, all SCCP features can be expressed in SUA. + * + * The code only supports Class 2. No support for Class 3 is intended, + * but patches are of course alwys welcome. + * + * Missing other features: + * * Segmentation/Reassembly support + * * T(guard) after (re)start + * * freezing of local references + * * parsing/encoding of IPv4/IPv6 addresses + * * use of multiple Routing Contexts in SUA case + */ + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "xua_internal.h" +#include "sccp_internal.h" + +#define S(x) (1 << (x)) +#define SCU_MSGB_SIZE 1024 + +/* Appendix C.4 of Q.714 (all in milliseconds) */ +#define CONNECTION_TIMER ( 1 * 60 * 100) +#define TX_INACT_TIMER ( 7 * 60 * 100) /* RFC 3868 Ch. 8. */ +#define RX_INACT_TIMER (15 * 60 * 100) /* RFC 3868 Ch. 8. */ +#define RELEASE_TIMER ( 10 * 100) +#define RELEASE_REP_TIMER ( 10 * 100) +#define INT_TIMER ( 1 * 60 * 100) +#define GUARD_TIMER (23 * 60 * 100) +#define RESET_TIMER ( 10 * 100) + +/* convert from single value in milliseconds to comma-separated + * "seconds, microseconds" format we use in osmocom/core/timers.h */ +#define MSEC_TO_S_US(x) (x/100), ((x%100)*10) + +/*********************************************************************** + * SCCP connection table + ***********************************************************************/ + +/* a logical connection within the SCCP instance */ +struct sccp_connection { + /* part of osmo_sccp_instance.list */ + struct llist_head list; + /* which instance are we part of? */ + struct osmo_sccp_instance *inst; + /* which user owns us? */ + struct osmo_sccp_user *user; + + /* remote point code */ + uint32_t remote_pc; + + /* local/remote addresses and identiies */ + struct osmo_sccp_addr calling_addr; + struct osmo_sccp_addr called_addr; + uint32_t conn_id; + uint32_t remote_ref; + + uint32_t importance; + uint32_t sccp_class; + uint32_t release_cause; /* WAIT_CONN_CONF */ + + /* Osmo FSM Instance of sccp_scoc_fsm */ + struct osmo_fsm_inst *fi; + + /* Connect timer */ + struct osmo_timer_list t_conn; + + /* inactivity timers */ + struct osmo_timer_list t_ias; + struct osmo_timer_list t_iar; + + /* release timers */ + struct osmo_timer_list t_rel; + struct osmo_timer_list t_int; + struct osmo_timer_list t_rep_rel; +}; + +/*********************************************************************** + * various helper functions + ***********************************************************************/ + +enum sccp_connection_state { + S_IDLE, + S_CONN_PEND_IN, + S_CONN_PEND_OUT, + S_ACTIVE, + S_DISCONN_PEND, + S_RESET_IN, + S_RESET_OUT, + S_BOTHWAY_RESET, + S_WAIT_CONN_CONF, +}; + +/* Events that this FSM can process */ +enum sccp_scoc_event { + /* Primitives from SCCP-User */ + SCOC_E_SCU_N_CONN_REQ, + SCOC_E_SCU_N_CONN_RESP, + SCOC_E_SCU_N_DISC_REQ, + SCOC_E_SCU_N_DATA_REQ, + SCOC_E_SCU_N_EXP_DATA_REQ, + + /* Events from RCOC (Routing for Connection Oriented) */ + SCOC_E_RCOC_CONN_IND, + SCOC_E_RCOC_ROUT_FAIL_IND, + SCOC_E_RCOC_RLSD_IND, + SCOC_E_RCOC_REL_COMPL_IND, + SCOC_E_RCOC_CREF_IND, + SCOC_E_RCOC_CC_IND, + SCOC_E_RCOC_DT1_IND, + SCOC_E_RCOC_DT2_IND, + SCOC_E_RCOC_IT_IND, + SCOC_E_RCOC_OTHER_NPDU, + SCOC_E_RCOC_ERROR_IND, + + /* Timer Events */ + SCOC_E_T_IAR_EXP, + SCOC_E_T_IAS_EXP, + + SCOC_E_CONN_TMR_EXP, + + SCOC_E_T_REL_EXP, + SCOC_E_T_INT_EXP, + SCOC_E_T_REP_REL_EXP, +}; + +static const struct value_string scoc_event_names[] = { + /* Primitives from SCCP-User */ + { SCOC_E_SCU_N_CONN_REQ, "N-CONNECT.req" }, + { SCOC_E_SCU_N_CONN_RESP, "N-CONNECT.resp" }, + { SCOC_E_SCU_N_DISC_REQ, "N-DISCONNECT.req" }, + { SCOC_E_SCU_N_DATA_REQ, "N-DATA.req" }, + { SCOC_E_SCU_N_EXP_DATA_REQ, "N-EXPEDITED_DATA.req" }, + + /* Events from RCOC (Routing for Connection Oriented) */ + { SCOC_E_RCOC_CONN_IND, "RCOC-CONNECT.ind" }, + { SCOC_E_RCOC_ROUT_FAIL_IND, "RCOC-ROUT_FAIL.ind" }, + { SCOC_E_RCOC_RLSD_IND, "RCOC-RELEASED.ind" }, + { SCOC_E_RCOC_REL_COMPL_IND, "RCOC-RELEASE_COMPLETE.ind" }, + { SCOC_E_RCOC_CREF_IND, "RCOC-CONNECT_REFUSED.ind" }, + { SCOC_E_RCOC_CC_IND, "RCOC-CONNECT_CONFIRM.ind" }, + { SCOC_E_RCOC_DT1_IND, "RCOC-DT1.ind" }, + { SCOC_E_RCOC_DT2_IND, "RCOC-DT2.ind" }, + { SCOC_E_RCOC_IT_IND, "RCOC-IT.ind" }, + { SCOC_E_RCOC_OTHER_NPDU, "RCOC-OTHER_NPDU.ind" }, + { SCOC_E_RCOC_ERROR_IND, "RCOC-ERROR.ind" }, + + { SCOC_E_T_IAR_EXP, "T(iar)_expired" }, + { SCOC_E_T_IAS_EXP, "T(ias)_expired" }, + { SCOC_E_CONN_TMR_EXP, "T(conn)_expired" }, + { SCOC_E_T_REL_EXP, "T(rel)_expired" }, + { SCOC_E_T_INT_EXP, "T(int)_expired" }, + { SCOC_E_T_REP_REL_EXP, "T(rep_rel)_expired" }, + + { 0, NULL } +}; + +/* how to map a SCCP CO message to an event */ +static const struct xua_msg_event_map sua_scoc_event_map[] = { + { SUA_MSGC_CO, SUA_CO_CORE, SCOC_E_RCOC_CONN_IND }, + { SUA_MSGC_CO, SUA_CO_RELRE, SCOC_E_RCOC_RLSD_IND }, + { SUA_MSGC_CO, SUA_CO_RELCO, SCOC_E_RCOC_REL_COMPL_IND }, + { SUA_MSGC_CO, SUA_CO_COREF, SCOC_E_RCOC_CREF_IND }, + { SUA_MSGC_CO, SUA_CO_COAK, SCOC_E_RCOC_CC_IND }, + { SUA_MSGC_CO, SUA_CO_CODT, SCOC_E_RCOC_DT1_IND }, + { SUA_MSGC_CO, SUA_CO_COIT, SCOC_E_RCOC_IT_IND }, + { SUA_MSGC_CO, SUA_CO_COERR, SCOC_E_RCOC_ERROR_IND }, +}; + + +/*! \brief magic value to be used as final record of \ref + * osmo_prim_event_map */ +#define OSMO_NO_EVENT 0xFFFFFFFF + +/*! \brief single entry in a SAP/PRIM/OP -> EVENT map */ +struct osmo_prim_event_map { + unsigned int sap; /*!< SAP to match */ + unsigned int primitive; /*!< primtiive to match */ + enum osmo_prim_operation operation; /*!< operation to match */ + uint32_t event; /*!< event as result if above match */ +}; + +/*! \brief resolve the (fsm) event for a given primitive using a map + * \param[in] oph primitive header used as key for match + * \param[in] maps list of mappings from primitive to event + * \returns event determined by map; \ref OSMO_NO_EVENT if no match */ +uint32_t osmo_event_for_prim(const struct osmo_prim_hdr *oph, + const struct osmo_prim_event_map *maps) +{ + const struct osmo_prim_event_map *map; + + for (map = maps; map->event != OSMO_NO_EVENT; map++) { + if (map->sap == oph->sap && + map->primitive == oph->primitive && + map->operation == oph->operation) + return map->event; + } + return OSMO_NO_EVENT; +} + +/* map from SCU-primitives to SCOC FSM events */ +static const struct osmo_prim_event_map scu_scoc_event_map[] = { + { SCCP_SAP_USER, OSMO_SCU_PRIM_N_CONNECT, PRIM_OP_REQUEST, + SCOC_E_SCU_N_CONN_REQ }, + { SCCP_SAP_USER, OSMO_SCU_PRIM_N_CONNECT, PRIM_OP_RESPONSE, + SCOC_E_SCU_N_CONN_RESP }, + { SCCP_SAP_USER, OSMO_SCU_PRIM_N_DATA, PRIM_OP_REQUEST, + SCOC_E_SCU_N_DATA_REQ }, + { SCCP_SAP_USER, OSMO_SCU_PRIM_N_DISCONNECT, PRIM_OP_REQUEST, + SCOC_E_SCU_N_DISC_REQ }, + { SCCP_SAP_USER, OSMO_SCU_PRIM_N_EXPEDITED_DATA, PRIM_OP_REQUEST, + SCOC_E_SCU_N_EXP_DATA_REQ }, + { 0, 0, 0, OSMO_NO_EVENT } +}; + +/*********************************************************************** + * Timer Handling + ***********************************************************************/ + +/* T(ias) has expired, send a COIT message to the peer */ +static void tx_inact_tmr_cb(void *data) +{ + struct sccp_connection *conn = data; + osmo_fsm_inst_dispatch(conn->fi, SCOC_E_T_IAS_EXP, NULL); +} + +/* T(iar) has expired, notify the FSM about it */ +static void rx_inact_tmr_cb(void *data) +{ + struct sccp_connection *conn = data; + osmo_fsm_inst_dispatch(conn->fi, SCOC_E_T_IAR_EXP, NULL); +} + +/* T(rel) has expired, notify the FSM about it */ +static void rel_tmr_cb(void *data) +{ + struct sccp_connection *conn = data; + osmo_fsm_inst_dispatch(conn->fi, SCOC_E_T_REL_EXP, NULL); +} + +/* T(int) has expired, notify the FSM about it */ +static void int_tmr_cb(void *data) +{ + struct sccp_connection *conn = data; + osmo_fsm_inst_dispatch(conn->fi, SCOC_E_T_INT_EXP, NULL); +} + +/* T(repeat_rel) has expired, notify the FSM about it */ +static void rep_rel_tmr_cb(void *data) +{ + struct sccp_connection *conn = data; + osmo_fsm_inst_dispatch(conn->fi, SCOC_E_T_REP_REL_EXP, NULL); +} + +/* T(conn) has expired, notify the FSM about it */ +static void conn_tmr_cb(void *data) +{ + struct sccp_connection *conn = data; + osmo_fsm_inst_dispatch(conn->fi, SCOC_E_CONN_TMR_EXP, NULL); +} + +/* Re-start the Tx inactivity timer */ +static void conn_restart_tx_inact_timer(struct sccp_connection *conn) +{ + osmo_timer_schedule(&conn->t_ias, MSEC_TO_S_US(TX_INACT_TIMER)); +} + +/* Re-start the Rx inactivity timer */ +static void conn_restart_rx_inact_timer(struct sccp_connection *conn) +{ + osmo_timer_schedule(&conn->t_iar, MSEC_TO_S_US(RX_INACT_TIMER)); +} + +/* Re-start both Rx and Tx inactivity timers */ +static void conn_start_inact_timers(struct sccp_connection *conn) +{ + conn_restart_tx_inact_timer(conn); + conn_restart_rx_inact_timer(conn); +} + +/* Stop both Rx and Tx inactivity timers */ +static void conn_stop_inact_timers(struct sccp_connection *conn) +{ + osmo_timer_del(&conn->t_ias); + osmo_timer_del(&conn->t_iar); +} + +/* Start release timer T(rel) */ +static void conn_start_rel_timer(struct sccp_connection *conn) +{ + osmo_timer_schedule(&conn->t_rel, MSEC_TO_S_US(RELEASE_TIMER)); +} + +/* Start repeat release timer T(rep_rel) */ +static void conn_start_rep_rel_timer(struct sccp_connection *conn) +{ + osmo_timer_schedule(&conn->t_rep_rel, MSEC_TO_S_US(RELEASE_REP_TIMER)); +} + +/* Start interval timer T(int) */ +static void conn_start_int_timer(struct sccp_connection *conn) +{ + osmo_timer_schedule(&conn->t_int, MSEC_TO_S_US(INT_TIMER)); +} + +/* Stop all release related timers: T(rel), T(int) and T(rep_rel) */ +static void conn_stop_release_timers(struct sccp_connection *conn) +{ + osmo_timer_del(&conn->t_rel); + osmo_timer_del(&conn->t_int); + osmo_timer_del(&conn->t_rep_rel); +} + +/* Start connect timer T(conn) */ +static void conn_start_connect_timer(struct sccp_connection *conn) +{ + osmo_timer_schedule(&conn->t_conn, MSEC_TO_S_US(CONNECTION_TIMER)); +} + +/* Stop connect timer T(conn) */ +static void conn_stop_connect_timer(struct sccp_connection *conn) +{ + osmo_timer_del(&conn->t_conn); +} + + +/*********************************************************************** + * SUA Instance and Connection handling + ***********************************************************************/ + +static void conn_destroy(struct sccp_connection *conn); + +static struct sccp_connection *conn_find_by_id(struct osmo_sccp_instance *inst, uint32_t id) +{ + struct sccp_connection *conn; + + llist_for_each_entry(conn, &inst->connections, list) { + if (conn->conn_id == id) + return conn; + } + return NULL; +} + +#define INIT_TIMER(x, fn, priv) do { (x)->cb = fn; (x)->data = priv; } while (0) + +/* allocate + init a SCCP Connection with given ID (local reference) */ +static struct sccp_connection *conn_create_id(struct osmo_sccp_instance *inst, + uint32_t conn_id) +{ + struct sccp_connection *conn = talloc_zero(inst, struct sccp_connection); + char name[16]; + + conn->conn_id = conn_id; + conn->inst = inst; + + llist_add_tail(&conn->list, &inst->connections); + + INIT_TIMER(&conn->t_conn, conn_tmr_cb, conn); + INIT_TIMER(&conn->t_ias, tx_inact_tmr_cb, conn); + INIT_TIMER(&conn->t_iar, rx_inact_tmr_cb, conn); + INIT_TIMER(&conn->t_rel, rel_tmr_cb, conn); + INIT_TIMER(&conn->t_int, int_tmr_cb, conn); + INIT_TIMER(&conn->t_rep_rel, rep_rel_tmr_cb, conn); + + /* this might change at runtime, as it is not a constant :/ */ + sccp_scoc_fsm.log_subsys = DLSCCP; + + /* we simply use the local reference as FSM instance name */ + snprintf(name, sizeof(name), "%u", conn->conn_id); + conn->fi = osmo_fsm_inst_alloc(&sccp_scoc_fsm, conn, conn, + LOGL_DEBUG, name); + if (!conn->fi) { + llist_del(&conn->list); + talloc_free(conn); + return NULL; + } + + return conn; +} + +/* Search for next free connection ID (local reference) and allocate conn */ +static struct sccp_connection *conn_create(struct osmo_sccp_instance *inst) +{ + uint32_t conn_id; + + do { + conn_id = inst->next_id++; + } while (conn_find_by_id(inst, conn_id)); + + return conn_create_id(inst, conn_id); +} + +/* destroy a SCCP connection state, releasing all timers, terminating + * FSM and releasing associated memory */ +static void conn_destroy(struct sccp_connection *conn) +{ + conn_stop_connect_timer(conn); + conn_stop_inact_timers(conn); + conn_stop_release_timers(conn); + llist_del(&conn->list); + + osmo_fsm_inst_term(conn->fi, OSMO_FSM_TERM_REQUEST, NULL); + + talloc_free(conn); +} + +/* allocate a message buffer for an SCCP User Primitive */ +static struct msgb *scu_msgb_alloc(void) +{ + return msgb_alloc(SCU_MSGB_SIZE, "SCCP User Primitive"); +} + +/* generate a RELRE (release request) xua_msg for given conn */ +static struct xua_msg *xua_gen_relre(struct sccp_connection *conn, + uint32_t cause, + struct osmo_scu_prim *prim) +{ + struct xua_msg *xua = xua_msg_alloc(); + + if (!xua) + return NULL; + + xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_RELRE); + xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, conn->inst->route_ctx); + xua_msg_add_u32(xua, SUA_IEI_DEST_REF, conn->remote_ref); + xua_msg_add_u32(xua, SUA_IEI_SRC_REF, conn->conn_id); + xua_msg_add_u32(xua, SUA_IEI_CAUSE, SUA_CAUSE_T_RELEASE | cause); + /* optional: importance */ + if (prim && msgb_l2(prim->oph.msg)) + xua_msg_add_data(xua, SUA_IEI_DATA, msgb_l2len(prim->oph.msg), + msgb_l2(prim->oph.msg)); + + return xua; +} + +/* generate xua_msg, encode it and send it to SCRC */ +static int xua_gen_relre_and_send(struct sccp_connection *conn, uint32_t cause, + struct osmo_scu_prim *prim) +{ + struct xua_msg *xua; + + xua = xua_gen_relre(conn, cause, prim); + if (!xua) + return -1; + + /* amend this with point code information; The SUA RELRE + * includes neither called nor calling party address! */ + xua->mtp.dpc = conn->remote_pc; + return sccp_scrc_rx_scoc_conn_msg(conn->inst, xua); +} + +/* generate a 'struct xua_msg' of requested type from connection + + * primitive data */ +static struct xua_msg *xua_gen_msg_co(struct sccp_connection *conn, uint32_t event, + struct osmo_scu_prim *prim, int msg_type) +{ + struct xua_msg *xua = xua_msg_alloc(); + + if (!xua) + return NULL; + + switch (msg_type) { + case SUA_CO_CORE: /* Connect Request == SCCP CR */ + xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_CORE); + xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, conn->inst->route_ctx); + xua_msg_add_u32(xua, SUA_IEI_PROTO_CLASS, conn->sccp_class); + xua_msg_add_u32(xua, SUA_IEI_SRC_REF, conn->conn_id); + xua_msg_add_sccp_addr(xua, SUA_IEI_DEST_ADDR, &conn->called_addr); + xua_msg_add_u32(xua, SUA_IEI_SEQ_CTRL, 0); /* TODO */ + /* optional: sequence number (class 3 only) */ + if (conn->calling_addr.presence) + xua_msg_add_sccp_addr(xua, SUA_IEI_SRC_ADDR, &conn->calling_addr); + /* optional: hop count; importance; priority; credit */ + if (prim && msgb_l2(prim->oph.msg)) + xua_msg_add_data(xua, SUA_IEI_DATA, msgb_l2len(prim->oph.msg), + msgb_l2(prim->oph.msg)); + break; + case SUA_CO_COAK: /* Connect Acknowledge == SCCP CC */ + xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_COAK); + xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, conn->inst->route_ctx); + xua_msg_add_u32(xua, SUA_IEI_PROTO_CLASS, conn->sccp_class); + xua_msg_add_u32(xua, SUA_IEI_DEST_REF, conn->remote_ref); + xua_msg_add_u32(xua, SUA_IEI_SRC_REF, conn->conn_id); + xua_msg_add_u32(xua, SUA_IEI_SEQ_CTRL, 0); /* TODO */ + /* optional: sequence number (class 3 only) */ + if (conn->called_addr.presence) + xua_msg_add_sccp_addr(xua, SUA_IEI_SRC_ADDR, &conn->called_addr); + /* optional: hop count; importance; priority */ + /* FIXME: destination address will [only] be present in + * case the CORE message conveys the source address + * parameter */ + if (conn->calling_addr.presence) + xua_msg_add_sccp_addr(xua, SUA_IEI_DEST_ADDR, &conn->calling_addr); + if (prim && msgb_l2(prim->oph.msg)) + xua_msg_add_data(xua, SUA_IEI_DATA, msgb_l2len(prim->oph.msg), + msgb_l2(prim->oph.msg)); + break; + case SUA_CO_RELRE: /* Release Request == SCCP REL */ + if (!prim) + goto prim_needed; + xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_RELRE); + xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, conn->inst->route_ctx); + xua_msg_add_u32(xua, SUA_IEI_DEST_REF, conn->remote_ref); + xua_msg_add_u32(xua, SUA_IEI_SRC_REF, conn->conn_id); + xua_msg_add_u32(xua, SUA_IEI_CAUSE, SUA_CAUSE_T_RELEASE | prim->u.disconnect.cause); + /* optional: importance */ + if (msgb_l2(prim->oph.msg)) + xua_msg_add_data(xua, SUA_IEI_DATA, msgb_l2len(prim->oph.msg), + msgb_l2(prim->oph.msg)); + break; + case SUA_CO_RELCO: /* Release Confirm == SCCP RLSD */ + xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_RELCO); + xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, conn->inst->route_ctx); + xua_msg_add_u32(xua, SUA_IEI_DEST_REF, conn->remote_ref); + xua_msg_add_u32(xua, SUA_IEI_SRC_REF, conn->conn_id); + /* optional: importance */ + break; + case SUA_CO_CODT: /* Connection Oriented Data Transfer == SCCP DT1 */ + if (!prim) + goto prim_needed; + xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_CODT); + xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, conn->inst->route_ctx); + /* Sequence number only in expedited data */ + xua_msg_add_u32(xua, SUA_IEI_DEST_REF, conn->remote_ref); + /* optional: priority; correlation id */ + xua_msg_add_data(xua, SUA_IEI_DATA, msgb_l2len(prim->oph.msg), + msgb_l2(prim->oph.msg)); + break; + case SUA_CO_COIT: /* Connection Oriented Interval Timer == SCCP IT */ + xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_COIT); + xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, conn->inst->route_ctx); + xua_msg_add_u32(xua, SUA_IEI_PROTO_CLASS, conn->sccp_class); + xua_msg_add_u32(xua, SUA_IEI_SRC_REF, conn->conn_id); + xua_msg_add_u32(xua, SUA_IEI_DEST_REF, conn->remote_ref); + /* optional: sequence number; credit (both class 3 only) */ + break; + case SUA_CO_COREF: /* Connect Refuse == SCCP CREF */ + xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_COREF); + xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, conn->inst->route_ctx); + xua_msg_add_u32(xua, SUA_IEI_DEST_REF, conn->remote_ref); + //xua_msg_add_u32(xua, SUA_IEI_CAUSE, SUA_CAUSE_T_REFUSAL | prim->u.disconnect.cause); + xua_msg_add_u32(xua, SUA_IEI_CAUSE, SUA_CAUSE_T_REFUSAL | SCCP_REFUSAL_UNEQUIPPED_USER); + /* optional: source addr */ + if (conn->called_addr.presence) + xua_msg_add_sccp_addr(xua, SUA_IEI_SRC_ADDR, &conn->called_addr); + /* conditional: dest addr */ + if (conn->calling_addr.presence) + xua_msg_add_sccp_addr(xua, SUA_IEI_DEST_ADDR, &conn->calling_addr); + /* optional: importance */ + /* optional: data */ + if (prim && msgb_l2(prim->oph.msg)) + xua_msg_add_data(xua, SUA_IEI_DATA, msgb_l2len(prim->oph.msg), + msgb_l2(prim->oph.msg)); + break; + /* FIXME */ + default: + LOGP(DLSCCP, LOGL_ERROR, "Don't know how to encode msg_type %u\n", msg_type); + xua_msg_free(xua); + return NULL; + } + return xua; + +prim_needed: + xua_msg_free(xua); + LOGP(DLSCCP, LOGL_ERROR, "%s must be called with valid 'prim' " + "pointer for msg_type=%u\n", __func__, msg_type); + return NULL; +} + +/* generate xua_msg, encode it and send it to SCRC */ +static int xua_gen_encode_and_send(struct sccp_connection *conn, uint32_t event, + struct osmo_scu_prim *prim, int msg_type) +{ + struct xua_msg *xua; + + xua = xua_gen_msg_co(conn, event, prim, msg_type); + if (!xua) + return -1; + + /* amend this with point code information; Many CO msgs + * includes neither called nor calling party address! */ + xua->mtp.dpc = conn->remote_pc; + return sccp_scrc_rx_scoc_conn_msg(conn->inst, xua); +} + +/* allocate a SCU primitive to be sent to the user */ +static struct osmo_scu_prim *scu_prim_alloc(unsigned int primitive, enum osmo_prim_operation operation) +{ + struct msgb *upmsg = scu_msgb_alloc(); + struct osmo_scu_prim *prim; + + prim = (struct osmo_scu_prim *) msgb_put(upmsg, sizeof(*prim)); + osmo_prim_init(&prim->oph, SCCP_SAP_USER, + primitive, operation, upmsg); + return prim; +} + +/* high-level function to generate a SCCP User primitive of requested + * type based on the connection and currently processed XUA message */ +static void scu_gen_encode_and_send(struct sccp_connection *conn, uint32_t event, + struct xua_msg *xua, unsigned int primitive, + enum osmo_prim_operation operation) +{ + struct osmo_scu_prim *scu_prim; + struct osmo_scu_disconn_param *udisp; + struct osmo_scu_connect_param *uconp; + struct osmo_scu_data_param *udatp; + struct xua_msg_part *data_ie; + + scu_prim = scu_prim_alloc(primitive, operation); + + switch (OSMO_PRIM_HDR(&scu_prim->oph)) { + case OSMO_PRIM(OSMO_SCU_PRIM_N_DISCONNECT, PRIM_OP_INDICATION): + udisp = &scu_prim->u.disconnect; + udisp->conn_id = conn->conn_id; + udisp->responding_addr = conn->called_addr; + udisp->originator = OSMO_SCCP_ORIG_UNDEFINED; + //udisp->in_sequence_control; + if (xua) { + udisp->cause = xua_msg_get_u32(xua, SUA_IEI_CAUSE); + if (xua_msg_find_tag(xua, SUA_IEI_SRC_ADDR)) + sua_addr_parse(&udisp->responding_addr, xua, SUA_IEI_SRC_ADDR); + data_ie = xua_msg_find_tag(xua, SUA_IEI_DATA); + udisp->importance = xua_msg_get_u32(xua, SUA_IEI_IMPORTANCE); + if (data_ie) { + struct msgb *upmsg = scu_prim->oph.msg; + upmsg->l2h = msgb_put(upmsg, data_ie->len); + memcpy(upmsg->l2h, data_ie->dat, data_ie->len); + } + } + break; + case OSMO_PRIM(OSMO_SCU_PRIM_N_CONNECT, PRIM_OP_INDICATION): + uconp = &scu_prim->u.connect; + uconp->conn_id = conn->conn_id; + uconp->called_addr = conn->called_addr; + uconp->calling_addr = conn->calling_addr; + uconp->sccp_class = conn->sccp_class; + uconp->importance = conn->importance; + data_ie = xua_msg_find_tag(xua, SUA_IEI_DATA); + if (xua) { + if (data_ie) { + struct msgb *upmsg = scu_prim->oph.msg; + upmsg->l2h = msgb_put(upmsg, data_ie->len); + memcpy(upmsg->l2h, data_ie->dat, data_ie->len); + } + } + break; + case OSMO_PRIM(OSMO_SCU_PRIM_N_CONNECT, PRIM_OP_CONFIRM): + uconp = &scu_prim->u.connect; + uconp->conn_id = conn->conn_id; + uconp->called_addr = conn->called_addr; + uconp->calling_addr = conn->calling_addr; + //scu_prim->u.connect.in_sequence_control + uconp->sccp_class = xua_msg_get_u32(xua, SUA_IEI_PROTO_CLASS) & 3; + uconp->importance = xua_msg_get_u32(xua, SUA_IEI_IMPORTANCE); + data_ie = xua_msg_find_tag(xua, SUA_IEI_DATA); + if (data_ie) { + struct msgb *upmsg = scu_prim->oph.msg; + upmsg->l2h = msgb_put(upmsg, data_ie->len); + memcpy(upmsg->l2h, data_ie->dat, data_ie->len); + } + break; + case OSMO_PRIM(OSMO_SCU_PRIM_N_DATA, PRIM_OP_INDICATION): + udatp = &scu_prim->u.data; + udatp->conn_id = conn->conn_id; + udatp->importance = conn->importance; + data_ie = xua_msg_find_tag(xua, SUA_IEI_DATA); + if (data_ie) { + struct msgb *upmsg = scu_prim->oph.msg; + upmsg->l2h = msgb_put(upmsg, data_ie->len); + memcpy(upmsg->l2h, data_ie->dat, data_ie->len); + } + break; + default: + LOGPFSML(conn->fi, LOGL_ERROR, "Unsupported primitive %u:%u\n", + scu_prim->oph.primitive, scu_prim->oph.operation); + talloc_free(scu_prim->oph.msg); + return; + } + + sccp_user_prim_up(conn->user, scu_prim); +} + + +/*********************************************************************** + * Actual SCCP Connection Oriented Control (SCOC) Finite Stte Machine + ***********************************************************************/ + +/* Figure C.2/Q.714 (sheet 1 of 7) and C.3/Q.714 (sheet 1 of 6) */ +static void scoc_fsm_idle(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct sccp_connection *conn = fi->priv; + struct osmo_scu_prim *prim = NULL; + struct osmo_scu_connect_param *uconp; + struct xua_msg *xua = NULL; + + switch (event) { + case SCOC_E_SCU_N_CONN_REQ: + prim = data; + uconp = &prim->u.connect; + /* copy relevant parameters from prim to conn */ + conn->called_addr = uconp->called_addr; + conn->calling_addr = uconp->calling_addr; + conn->sccp_class = uconp->sccp_class; + /* generate + send CR PDU to SCRC */ + xua_gen_encode_and_send(conn, event, prim, SUA_CO_CORE); + /* start connection timer */ + conn_start_connect_timer(conn); + osmo_fsm_inst_state_chg(fi, S_CONN_PEND_OUT, 0, 0); + break; +#if 0 + case SCOC_E_SCU_N_TYPE1_REQ: + /* ?!? */ + break; +#endif + case SCOC_E_RCOC_RLSD_IND: + /* send release complete to SCRC */ + xua_gen_encode_and_send(conn, event, NULL, SUA_CO_RELCO); + break; + case SCOC_E_RCOC_REL_COMPL_IND: + /* do nothing */ + break; + case SCOC_E_RCOC_OTHER_NPDU: +#if 0 + if (src_ref) { + /* FIXME: send ERROR to SCRC */ + } +#endif + break; + /* destination node / incoming connection */ + /* Figure C.3 / Q.714 (sheet 1 of 6) */ + case SCOC_E_RCOC_CONN_IND: + xua = data; + /* copy relevant parameters from xua to conn */ + sua_addr_parse(&conn->calling_addr, xua, SUA_IEI_SRC_ADDR); + sua_addr_parse(&conn->called_addr, xua, SUA_IEI_DEST_ADDR); + conn->remote_ref = xua_msg_get_u32(xua, SUA_IEI_SRC_REF); + conn->sccp_class = xua_msg_get_u32(xua, SUA_IEI_PROTO_CLASS) & 3; + conn->importance = xua_msg_get_u32(xua, SUA_IEI_IMPORTANCE); + /* 3.1.6.1 The originating node of the CR message + * (identified by the OPC in the calling party address + * or by default by the OPC in the MTP label, [and the + * MTP-SAP instance]) is associated with the incoming + * connection section. */ + if (conn->calling_addr.presence & OSMO_SCCP_ADDR_T_PC) + conn->remote_pc = conn->calling_addr.pc; + else { + /* Hack to get the MTP label here ?!? */ + conn->remote_pc = xua->mtp.opc; + } + + osmo_fsm_inst_state_chg(fi, S_CONN_PEND_IN, 0, 0); + /* N-CONNECT.ind to User */ + scu_gen_encode_and_send(conn, event, xua, OSMO_SCU_PRIM_N_CONNECT, + PRIM_OP_INDICATION); + break; + } +} + +static void scoc_fsm_idle_onenter(struct osmo_fsm_inst *fi, uint32_t old_state) +{ + conn_destroy(fi->priv); +} + +/* Figure C.3 / Q.714 (sheet 2 of 6) */ +static void scoc_fsm_conn_pend_in(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct sccp_connection *conn = fi->priv; + struct osmo_scu_prim *prim = NULL; + + switch (event) { + case SCOC_E_SCU_N_CONN_RESP: + prim = data; + /* FIXME: assign local reference (only now?) */ + /* FIXME: assign sls, protocol class and credit */ + xua_gen_encode_and_send(conn, event, prim, SUA_CO_COAK); + /* start inactivity timers */ + conn_start_inact_timers(conn); + osmo_fsm_inst_state_chg(fi, S_ACTIVE, 0, 0); + break; + case SCOC_E_SCU_N_DISC_REQ: + prim = data; + /* release resources: implicit */ + xua_gen_encode_and_send(conn, event, prim, SUA_CO_COREF); + osmo_fsm_inst_state_chg(fi, S_IDLE, 0, 0); + break; + } +} + +/* Figure C.2/Q.714 (sheet 2 of 7) */ +static void scoc_fsm_conn_pend_out(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct sccp_connection *conn = fi->priv; + struct osmo_scu_prim *prim = NULL; + struct xua_msg *xua = NULL; + + switch (event) { + case SCOC_E_SCU_N_DISC_REQ: + prim = data; + conn->release_cause = prim->u.disconnect.cause; + osmo_fsm_inst_state_chg(fi, S_WAIT_CONN_CONF, 0, 0); + /* keep conn timer running(!) */ + break; + case SCOC_E_CONN_TMR_EXP: + /* N-DISCONNECT.ind to user */ + scu_gen_encode_and_send(conn, event, xua, OSMO_SCU_PRIM_N_DISCONNECT, + PRIM_OP_INDICATION); + /* below implicitly releases resources + local ref */ + osmo_fsm_inst_state_chg(fi, S_IDLE, 0, 0); + break; + case SCOC_E_RCOC_ROUT_FAIL_IND: + case SCOC_E_RCOC_CREF_IND: + xua = data; + /* stop conn timer */ + conn_stop_connect_timer(conn); + /* release local res + ref (implicit by going to idle) */ + /* N-DISCONNECT.ind to user */ + scu_gen_encode_and_send(conn, event, xua, OSMO_SCU_PRIM_N_DISCONNECT, + PRIM_OP_INDICATION); + /* below implicitly releases resources + local ref */ + osmo_fsm_inst_state_chg(fi, S_IDLE, 0, 0); + break; + case SCOC_E_RCOC_RLSD_IND: + xua = data; + /* RLC to SCRC */ + xua_gen_encode_and_send(conn, event, NULL, SUA_CO_RELCO); + /* stop conn timer */ + conn_stop_connect_timer(conn); + /* release local res + ref (implicit) */ + /* N-DISCONNECT.ind to user */ + scu_gen_encode_and_send(conn, event, xua, OSMO_SCU_PRIM_N_DISCONNECT, + PRIM_OP_INDICATION); + osmo_fsm_inst_state_chg(fi, S_IDLE, 0, 0); + break; + case SCOC_E_RCOC_OTHER_NPDU: + xua = data; + conn_start_connect_timer(conn); + /* release local res + ref (implicit) */ + /* N-DISCONNECT.ind to user */ + scu_gen_encode_and_send(conn, event, xua, OSMO_SCU_PRIM_N_DISCONNECT, + PRIM_OP_INDICATION); + osmo_fsm_inst_state_chg(fi, S_IDLE, 0, 0); + break; + case SCOC_E_RCOC_CC_IND: + xua = data; + /* stop conn timer */ + conn_stop_connect_timer(conn); + /* start inactivity timers */ + conn_start_inact_timers(conn); + /* TODO: assign PCU and credit */ + /* associate remote ref to conn */ + conn->remote_ref = xua_msg_get_u32(xua, SUA_IEI_SRC_REF); + /* 3.1.4.2 The node sending the CC message (identified + * by the parameter OPC contained in the + * MTP-TRANSFER.indication primitive which conveyed the + * CC message [plus the MTP-SAP instance]) is associated + * with the connection section. */ + conn->remote_pc = xua->mtp.opc; + + osmo_fsm_inst_state_chg(fi, S_ACTIVE, 0, 0); + /* N-CONNECT.conf to user */ + scu_gen_encode_and_send(conn, event, xua, OSMO_SCU_PRIM_N_CONNECT, + PRIM_OP_CONFIRM); + break; + } +} + +/* Figure C.2/Q.714 (sheet 3 of 7) */ +static void scoc_fsm_wait_conn_conf(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct sccp_connection *conn = fi->priv; + struct xua_msg *xua = NULL; + + switch (event) { + case SCOC_E_RCOC_RLSD_IND: + xua = data; + /* release complete to SCRC */ + xua_gen_encode_and_send(conn, event, NULL, SUA_CO_RELCO); + /* stop conn timer */ + conn_stop_connect_timer(conn); + /* release local res + ref (implicit) */ + osmo_fsm_inst_state_chg(fi, S_IDLE, 0, 0); + break; + case SCOC_E_RCOC_CC_IND: + xua = data; + /* stop conn timer */ + conn_stop_connect_timer(conn); + /* associate rem ref to conn */ + conn->remote_ref = xua_msg_get_u32(xua, SUA_IEI_SRC_REF); + /* released to SCRC */ + xua_gen_relre_and_send(conn, conn->release_cause, NULL); + /* start rel timer */ + conn_start_rel_timer(conn); + osmo_fsm_inst_state_chg(fi, S_DISCONN_PEND, 0, 0); + break; + case SCOC_E_RCOC_OTHER_NPDU: + case SCOC_E_RCOC_CREF_IND: + case SCOC_E_RCOC_ROUT_FAIL_IND: + xua = data; + /* stop conn timer */ + conn_stop_connect_timer(conn); + /* release local res + ref */ + osmo_fsm_inst_state_chg(fi, S_IDLE, 0, 0); + break; + case SCOC_E_CONN_TMR_EXP: + /* release local res + ref */ + osmo_fsm_inst_state_chg(fi, S_IDLE, 0, 0); + break; + } +} + +/* C.2/Q.714 (sheet 4+5 of 7) and C.3/Q714 (sheet 3+4 of 6) */ +static void scoc_fsm_active(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct xua_msg *xua = data; + struct sccp_connection *conn = fi->priv; + struct osmo_scu_prim *prim = NULL; + + switch (event) { + /* TODO: internal disco */ + /* send N-DISCONNECT.ind to user */ + scu_gen_encode_and_send(conn, event, xua, OSMO_SCU_PRIM_N_DISCONNECT, + PRIM_OP_INDICATION); + /* fall-through */ + case SCOC_E_SCU_N_DISC_REQ: + prim = data; + /* stop inact timers */ + conn_stop_inact_timers(conn); + /* send RLSD to SCRC */ + xua_gen_encode_and_send(conn, event, prim, SUA_CO_RELRE); + /* start rel timer */ + conn_start_rel_timer(conn); + osmo_fsm_inst_state_chg(fi, S_DISCONN_PEND, 0, 0); + break; + case SCOC_E_RCOC_CREF_IND: + case SCOC_E_RCOC_CC_IND: + case SCOC_E_RCOC_REL_COMPL_IND: + /* do nothing */ + break; + case SCOC_E_RCOC_RLSD_IND: + /* send N-DISCONNECT.ind to user */ + scu_gen_encode_and_send(conn, event, xua, OSMO_SCU_PRIM_N_DISCONNECT, + PRIM_OP_INDICATION); + /* release res + local ref (implicit) */ + /* stop inact timers */ + conn_stop_inact_timers(conn); + /* RLC to SCRC */ + xua_gen_encode_and_send(conn, event, NULL, SUA_CO_RELCO); + osmo_fsm_inst_state_chg(fi, S_IDLE, 0, 0); + break; + case SCOC_E_RCOC_ERROR_IND: + xua = data; + /* FIXME: check for cause service_class_mismatch */ + /* release res + local ref (implicit) */ + /* send N-DISCONNECT.ind to user */ + scu_gen_encode_and_send(conn, event, xua, OSMO_SCU_PRIM_N_DISCONNECT, + PRIM_OP_INDICATION); + /* stop inact timers */ + conn_stop_inact_timers(conn); + osmo_fsm_inst_state_chg(fi, S_IDLE, 0, 0); + break; + case SCOC_E_T_IAR_EXP: + /* Send N-DISCONNECT.ind to local user */ + scu_gen_encode_and_send(conn, event, NULL, OSMO_SCU_PRIM_N_DISCONNECT, + PRIM_OP_INDICATION); + /* Send RLSD to peer */ + xua_gen_relre_and_send(conn, SCCP_RELEASE_CAUSE_EXPIRATION_INACTIVE, NULL); + conn_start_rel_timer(conn); + osmo_fsm_inst_state_chg(fi, S_DISCONN_PEND, 0, 0); + break; + case SCOC_E_RCOC_ROUT_FAIL_IND: + /* send N-DISCONNECT.ind to user */ + scu_gen_encode_and_send(conn, event, NULL, OSMO_SCU_PRIM_N_DISCONNECT, + PRIM_OP_INDICATION); + /* stop inact timers */ + conn_stop_inact_timers(conn); + /* start release timer */ + conn_start_rel_timer(conn); + osmo_fsm_inst_state_chg(fi, S_DISCONN_PEND, 0, 0); + break; + /* Figure C.4/Q.714 */ + case SCOC_E_SCU_N_DATA_REQ: + case SCOC_E_SCU_N_EXP_DATA_REQ: + prim = data; + xua_gen_encode_and_send(conn, event, prim, SUA_CO_CODT); + conn_restart_tx_inact_timer(conn); + break; + case SCOC_E_RCOC_DT1_IND: + /* restart receive inactivity timer */ + conn_restart_rx_inact_timer(conn); + /* TODO: M-bit */ + scu_gen_encode_and_send(conn, event, xua, OSMO_SCU_PRIM_N_DATA, + PRIM_OP_INDICATION); + break; + /* Figure C.4/Q.714 (sheet 4 of 4) */ + case SCOC_E_RCOC_IT_IND: + xua = data; + /* check if remote reference is what we expect */ + /* check class is what we expect */ + if (xua_msg_get_u32(xua, SUA_IEI_SRC_REF) != conn->remote_ref || + xua_msg_get_u32(xua, SUA_IEI_PROTO_CLASS) != conn->sccp_class) { + /* Release connection */ + /* send N-DISCONNECT.ind to user */ + scu_gen_encode_and_send(conn, event, NULL, + OSMO_SCU_PRIM_N_DISCONNECT, + PRIM_OP_INDICATION); + /* Stop inactivity Timers */ + conn_stop_inact_timers(conn); + /* Send RLSD to SCRC */ + xua_gen_relre_and_send(conn, SCCP_RELEASE_CAUSE_INCONSISTENT_CONN_DATA, NULL); + /* Start release timer */ + conn_start_rel_timer(conn); + osmo_fsm_inst_state_chg(fi, S_DISCONN_PEND, 0, 0); + } + conn_restart_rx_inact_timer(conn); + break; + case SCOC_E_T_IAS_EXP: + /* Send IT to peer */ + xua_gen_encode_and_send(conn, event, NULL, SUA_CO_COIT); + conn_restart_tx_inact_timer(conn); + break; + } +} + +/* C.2/Q.714 (sheet 6+7 of 7) and C.3/Q.714 (sheet 5+6 of 6) */ +static void scoc_fsm_disconn_pend(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct sccp_connection *conn = fi->priv; + + switch (event) { + case SCOC_E_RCOC_REL_COMPL_IND: + case SCOC_E_RCOC_RLSD_IND: + /* release res + local ref (implicit) */ + /* freeze local ref */ + /* stop release + interval timers */ + conn_stop_release_timers(conn); + osmo_fsm_inst_state_chg(fi, S_IDLE, 0, 0); + break; + case SCOC_E_RCOC_ROUT_FAIL_IND: + case SCOC_E_RCOC_OTHER_NPDU: + /* do nothing */ + break; + case SCOC_E_T_REL_EXP: /* release timer exp */ + /* send RLSD */ + xua_gen_relre_and_send(conn, SCCP_RELEASE_CAUSE_UNQUALIFIED, NULL); + /* start interval timer */ + conn_start_int_timer(conn); + /* start repeat release timer */ + conn_start_rep_rel_timer(conn); + break; + case SCOC_E_T_INT_EXP: /* interval timer exp */ + /* TODO: Inform maintenance */ + /* stop release and interval timers */ + conn_stop_release_timers(conn); + osmo_fsm_inst_state_chg(fi, S_IDLE, 0, 0); + break; + case SCOC_E_T_REP_REL_EXP: /* repeat release timer exp */ + /* send RLSD */ + xua_gen_relre_and_send(conn, SCCP_RELEASE_CAUSE_UNQUALIFIED, NULL); + /* re-start repeat release timer */ + conn_start_rep_rel_timer(conn); + break; + } +} + +static const struct osmo_fsm_state sccp_scoc_states[] = { + [S_IDLE] = { + .name = "IDLE", + .action = scoc_fsm_idle, + .onenter= scoc_fsm_idle_onenter, + .in_event_mask = S(SCOC_E_SCU_N_CONN_REQ) | + //S(SCOC_E_SCU_N_TYPE1_REQ) | + S(SCOC_E_RCOC_CONN_IND) | + S(SCOC_E_RCOC_RLSD_IND) | + S(SCOC_E_RCOC_REL_COMPL_IND) | + S(SCOC_E_RCOC_OTHER_NPDU), + .out_state_mask = S(S_CONN_PEND_OUT) | + S(S_CONN_PEND_IN), + }, + [S_CONN_PEND_IN] = { + .name = "CONN_PEND_IN", + .action = scoc_fsm_conn_pend_in, + .in_event_mask = S(SCOC_E_SCU_N_CONN_RESP) | + S(SCOC_E_SCU_N_DISC_REQ), + .out_state_mask = S(S_IDLE) | + S(S_ACTIVE), + }, + [S_CONN_PEND_OUT] = { + .name = "CONN_PEND_OUT", + .action = scoc_fsm_conn_pend_out, + .in_event_mask = S(SCOC_E_SCU_N_DISC_REQ) | + S(SCOC_E_CONN_TMR_EXP) | + S(SCOC_E_RCOC_ROUT_FAIL_IND) | + S(SCOC_E_RCOC_RLSD_IND) | + S(SCOC_E_RCOC_OTHER_NPDU) | + S(SCOC_E_RCOC_CREF_IND) | + S(SCOC_E_RCOC_CC_IND), + .out_state_mask = S(S_IDLE) | + S(S_ACTIVE) | + S(S_WAIT_CONN_CONF), + }, + [S_ACTIVE] = { + .name = "ACTIVE", + .action = scoc_fsm_active, + .in_event_mask = S(SCOC_E_SCU_N_DISC_REQ) | + /* internal disconnect */ + S(SCOC_E_RCOC_CREF_IND) | + S(SCOC_E_RCOC_REL_COMPL_IND) | + S(SCOC_E_RCOC_RLSD_IND) | + S(SCOC_E_RCOC_ERROR_IND) | + S(SCOC_E_T_IAR_EXP) | + S(SCOC_E_T_IAS_EXP) | + S(SCOC_E_RCOC_ROUT_FAIL_IND) | + S(SCOC_E_SCU_N_DATA_REQ) | + S(SCOC_E_SCU_N_EXP_DATA_REQ) | + S(SCOC_E_RCOC_DT1_IND) | + S(SCOC_E_RCOC_IT_IND), + .out_state_mask = S(S_IDLE) | + S(S_DISCONN_PEND), + }, + [S_DISCONN_PEND] = { + .name = "DISCONN_PEND", + .action = scoc_fsm_disconn_pend, + .in_event_mask = S(SCOC_E_RCOC_REL_COMPL_IND) | + S(SCOC_E_RCOC_RLSD_IND) | + S(SCOC_E_RCOC_ROUT_FAIL_IND) | + S(SCOC_E_RCOC_OTHER_NPDU) | + S(SCOC_E_T_REL_EXP) | + S(SCOC_E_T_INT_EXP) | + S(SCOC_E_T_REP_REL_EXP), + .out_state_mask = S(S_IDLE), + }, + [S_RESET_IN] = { + .name = "RESET_IN", + }, + [S_RESET_OUT] = { + .name = "RESET_OUT", + }, + [S_BOTHWAY_RESET] = { + .name = "BOTHWAY_RESET", + }, + [S_WAIT_CONN_CONF] = { + .name = "WAIT_CONN_CONF", + .action = scoc_fsm_wait_conn_conf, + .in_event_mask = S(SCOC_E_RCOC_RLSD_IND) | + S(SCOC_E_RCOC_CC_IND) | + S(SCOC_E_RCOC_OTHER_NPDU) | + S(SCOC_E_CONN_TMR_EXP) | + S(SCOC_E_RCOC_CREF_IND) | + S(SCOC_E_RCOC_ROUT_FAIL_IND), + }, +}; + +struct osmo_fsm sccp_scoc_fsm = { + .name = "SCCP-SCOC", + .states = sccp_scoc_states, + .num_states = ARRAY_SIZE(sccp_scoc_states), + /* ".log_subsys = DLSCCP" doesn't work as DLSCCP is not a constant */ + .event_names = scoc_event_names, +}; + +/* map from SCCP return cause to SCCP Refusal cause */ +static const uint8_t cause_map_cref[] = { + [SCCP_RETURN_CAUSE_SUBSYSTEM_CONGESTION] = + SCCP_REFUSAL_SUBSYTEM_CONGESTION, + [SCCP_RETURN_CAUSE_SUBSYSTEM_FAILURE] = + SCCP_REFUSAL_SUBSYSTEM_FAILURE, + [SCCP_RETURN_CAUSE_UNEQUIPPED_USER] = + SCCP_REFUSAL_UNEQUIPPED_USER, + [SCCP_RETURN_CAUSE_UNQUALIFIED] = + SCCP_REFUSAL_UNQUALIFIED, + [SCCP_RETURN_CAUSE_SCCP_FAILURE] = + SCCP_REFUSAL_SCCP_FAILURE, + [SCCP_RETURN_CAUSE_HOP_COUNTER_VIOLATION] = + SCCP_REFUSAL_HOP_COUNTER_VIOLATION, +}; + +static uint8_t get_cref_cause_for_ret(uint8_t ret_cause) +{ + if (ret_cause < ARRAY_SIZE(cause_map_cref)) + return cause_map_cref[ret_cause]; + else + return SCCP_REFUSAL_UNQUALIFIED; +} + +/* Generate a COREF message purely based on an incoming SUA message, + * without the use of any local connection state */ +static struct xua_msg *gen_coref_without_conn(struct osmo_sccp_instance *inst, + struct xua_msg *xua_in, + uint32_t ref_cause) +{ + struct xua_msg *xua; + + xua = xua_msg_alloc(); + xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_COREF); + xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, inst->route_ctx); + + xua_msg_copy_part(xua, SUA_IEI_DEST_REF, xua_in, SUA_IEI_SRC_REF); + xua_msg_add_u32(xua, SUA_IEI_CAUSE, SUA_CAUSE_T_REFUSAL | ref_cause); + /* optional: source addr */ + xua_msg_copy_part(xua, SUA_IEI_SRC_ADDR, xua_in, SUA_IEI_DEST_ADDR); + /* conditional: dest addr */ + xua_msg_copy_part(xua, SUA_IEI_DEST_ADDR, xua_in, SUA_IEI_SRC_ADDR); + /* optional: importance */ + xua_msg_copy_part(xua, SUA_IEI_IMPORTANCE, xua_in, SUA_IEI_IMPORTANCE); + /* optional: data */ + xua_msg_copy_part(xua, SUA_IEI_DATA, xua_in, SUA_IEI_DATA); + + return xua; +} + +/*! \brief SCOC: Receive SCRC Routing Failure + * \param[in] inst SCCP Instance on which we operate + * \param[in] xua SUA message that was failed to route + * \param[in] return_cause Reason (cause) for routing failure */ +void sccp_scoc_rx_scrc_rout_fail(struct osmo_sccp_instance *inst, + struct xua_msg *xua, uint32_t return_cause) +{ + uint32_t conn_id; + struct sccp_connection *conn; + + /* try to dispatch to connection FSM (if any) */ + conn_id = xua_msg_get_u32(xua, SUA_IEI_DEST_REF); + conn = conn_find_by_id(inst, conn_id); + if (conn) { + osmo_fsm_inst_dispatch(conn->fi, + SCOC_E_RCOC_ROUT_FAIL_IND, xua); + } else { + /* generate + send CREF directly */ + struct xua_msg *cref; + uint8_t cref_cause = get_cref_cause_for_ret(return_cause); + cref = gen_coref_without_conn(inst, xua, cref_cause); + sccp_scrc_rx_scoc_conn_msg(inst, cref); + xua_msg_free(cref); + } +} + +/* Find a SCCP user for given SUA message (based on SUA_IEI_DEST_ADDR */ +static struct osmo_sccp_user *sccp_find_user(struct osmo_sccp_instance *inst, + struct xua_msg *xua) +{ + int rc; + struct osmo_sccp_addr called_addr; + + rc = sua_addr_parse(&called_addr, xua, SUA_IEI_DEST_ADDR); + if (rc < 0) { + LOGP(DLSCCP, LOGL_ERROR, "Cannot find SCCP User for XUA " + "Message %s without valid DEST_ADDR\n", + xua_hdr_dump(xua, &xua_dialect_sua)); + return NULL; + } + + if (!(called_addr.presence & OSMO_SCCP_ADDR_T_SSN)) { + LOGP(DLSCCP, LOGL_ERROR, "Cannot resolve SCCP User for " + "XUA Message %s without SSN in CalledAddr\n", + xua_hdr_dump(xua, &xua_dialect_sua)); + return NULL; + } + + return sccp_user_find(inst, called_addr.ssn, called_addr.pc); +} + +/* Generate a COERR based in input arguments */ +static struct xua_msg *gen_coerr(uint32_t route_ctx, uint32_t dest_ref, + uint32_t err_cause) +{ + struct xua_msg *xua = xua_msg_alloc(); + + xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_COERR); + xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, route_ctx); + xua_msg_add_u32(xua, SUA_IEI_DEST_REF, dest_ref); + xua_msg_add_u32(xua, SUA_IEI_CAUSE, SUA_CAUSE_T_ERROR | err_cause); + + return xua; +} + +/* generate COERR from incoming XUA and send it */ +static void tx_coerr_from_xua(struct osmo_sccp_instance *inst, + struct xua_msg *in, uint32_t err_cause) +{ + struct xua_msg *xua; + uint32_t route_ctx, dest_ref; + + route_ctx = xua_msg_get_u32(in, SUA_IEI_ROUTE_CTX); + /* get *source* reference and use as destination ref */ + dest_ref = xua_msg_get_u32(in, SUA_IEI_SRC_REF); + + xua = gen_coerr(route_ctx, dest_ref, err_cause); + /* copy over the MTP parameters */ + xua->mtp.dpc = in->mtp.opc; + xua->mtp.opc = in->mtp.dpc; + xua->mtp.sio = in->mtp.sio; + + /* sent to SCRC for transmission */ + sccp_scrc_rx_scoc_conn_msg(inst, xua); + xua_msg_free(xua); +} + +/* Generate a RELCO based in input arguments */ +static struct xua_msg *gen_relco(uint32_t route_ctx, uint32_t dest_ref, + uint32_t src_ref) +{ + struct xua_msg *xua = xua_msg_alloc(); + + xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_RELCO); + xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, route_ctx); + xua_msg_add_u32(xua, SUA_IEI_DEST_REF, dest_ref); + xua_msg_add_u32(xua, SUA_IEI_SRC_REF, src_ref); + + return xua; +} + +/* generate RELCO from incoming XUA and send it */ +static void tx_relco_from_xua(struct osmo_sccp_instance *inst, + struct xua_msg *in) +{ + struct xua_msg *xua; + uint32_t route_ctx, dest_ref, src_ref; + + route_ctx = xua_msg_get_u32(in, SUA_IEI_ROUTE_CTX); + /* get *source* reference and use as destination ref */ + dest_ref = xua_msg_get_u32(in, SUA_IEI_SRC_REF); + /* get *dest* reference and use as source ref */ + src_ref = xua_msg_get_u32(in, SUA_IEI_DEST_REF); + + xua = gen_relco(route_ctx, dest_ref, src_ref); + /* copy over the MTP parameters */ + xua->mtp.dpc = in->mtp.opc; + xua->mtp.opc = in->mtp.dpc; + xua->mtp.sio = in->mtp.sio; + + /* send to SCRC for transmission */ + sccp_scrc_rx_scoc_conn_msg(inst, xua); + xua_msg_free(xua); +} + +/* Generate a RLSD based in input arguments */ +static struct xua_msg *gen_rlsd(uint32_t route_ctx, uint32_t dest_ref, + uint32_t src_ref) +{ + struct xua_msg *xua = xua_msg_alloc(); + + xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_RELRE); + xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, route_ctx); + xua_msg_add_u32(xua, SUA_IEI_DEST_REF, dest_ref); + xua_msg_add_u32(xua, SUA_IEI_SRC_REF, src_ref); + + return xua; +} + +/* Generate a RLSD to both the remote side and the local conn */ +static void tx_rlsd_from_xua_twoway(struct sccp_connection *conn, + struct xua_msg *in) +{ + struct xua_msg *xua; + uint32_t route_ctx, dest_ref, src_ref; + + route_ctx = xua_msg_get_u32(in, SUA_IEI_ROUTE_CTX); + /* get *source* reference and use as destination ref */ + dest_ref = xua_msg_get_u32(in, SUA_IEI_SRC_REF); + /* get *source* reference and use as destination ref */ + src_ref = xua_msg_get_u32(in, SUA_IEI_DEST_REF); + + /* Generate RLSD towards remote peer */ + xua = gen_rlsd(route_ctx, dest_ref, src_ref); + /* copy over the MTP parameters */ + xua->mtp.dpc = in->mtp.opc; + xua->mtp.opc = in->mtp.dpc; + xua->mtp.sio = in->mtp.sio; + /* send to SCRC for transmission */ + sccp_scrc_rx_scoc_conn_msg(conn->inst, xua); + xua_msg_free(xua); + + /* Generate RLSD towards local peer */ + xua = gen_rlsd(conn->inst->route_ctx, conn->conn_id, conn->remote_ref); + xua->mtp.dpc = in->mtp.dpc; + xua->mtp.opc = conn->remote_pc; + xua->mtp.sio = in->mtp.sio; + osmo_fsm_inst_dispatch(conn->fi, SCOC_E_RCOC_RLSD_IND, xua); + xua_msg_free(xua); +} + +/* process received message for unasigned local reference */ +static void sccp_scoc_rx_unass_local_ref(struct osmo_sccp_instance *inst, + struct xua_msg *xua) +{ + /* we have received a message with unassigned destination local + * reference and thus apply the action indicated in Table + * B.2/Q.714 */ + switch (xua->hdr.msg_type) { + case SUA_CO_COAK: /* CC */ + case SUA_CO_COIT: /* IT */ + case SUA_CO_RESRE: /* RSR */ + case SUA_CO_RESCO: /* RSC */ + /* Send COERR */ + tx_coerr_from_xua(inst, xua, SCCP_ERROR_LRN_MISMATCH_UNASSIGNED); + break; + case SUA_CO_COREF: /* CREF */ + case SUA_CO_RELCO: /* RLC */ + case SUA_CO_CODT: /* DT1 */ + case SUA_CO_CODA: /* AK */ + case SUA_CO_COERR: /* ERR */ + /* DISCARD */ + break; + case SUA_CO_RELRE: /* RLSD */ + /* Send RLC */ + tx_relco_from_xua(inst, xua); + break; + default: + LOGP(DLSCCP, LOGL_NOTICE, "Unhandled %s\n", + xua_hdr_dump(xua, &xua_dialect_sua)); + break; + } +} + +/* process received message for invalid source local reference */ +static void sccp_scoc_rx_inval_src_ref(struct sccp_connection *conn, + struct xua_msg *xua) +{ + /* we have received a message with invalid source local + * reference and thus apply the action indicated in Table + * B.2/Q.714 */ + switch (xua->hdr.msg_type) { + case SUA_CO_RELRE: /* RLSD */ + case SUA_CO_RESRE: /* RSR */ + case SUA_CO_RESCO: /* RSC */ + /* Send ERR */ + tx_coerr_from_xua(conn->inst, xua, SCCP_ERROR_LRN_MISMATCH_INCONSISTENT); + break; + case SUA_CO_COIT: /* IT */ + /* FIXME: RLSD to both sides */ + tx_rlsd_from_xua_twoway(conn, xua); + break; + case SUA_CO_RELCO: /* RLC */ + /* DISCARD */ + break; + default: + LOGP(DLSCCP, LOGL_NOTICE, "Unhandled %s\n", + xua_hdr_dump(xua, &xua_dialect_sua)); + break; + } +} + +/* process received message for invalid origin point code */ +static void sccp_scoc_rx_inval_opc(struct osmo_sccp_instance *inst, + struct xua_msg *xua) +{ + /* we have received a message with invalid origin PC and thus + * apply the action indiacted in Table B.2/Q.714 */ + switch (xua->hdr.msg_type) { + case SUA_CO_RELRE: /* RLSD */ + case SUA_CO_RESRE: /* RSR */ + case SUA_CO_RESCO: /* RSC */ + /* Send ERR */ + tx_coerr_from_xua(inst, xua, SCCP_ERROR_POINT_CODE_MISMATCH); + break; + case SUA_CO_RELCO: /* RLC */ + case SUA_CO_CODT: /* DT1 */ + case SUA_CO_CODA: /* AK */ + case SUA_CO_COERR: /* ERR */ + /* DISCARD */ + break; + default: + LOGP(DLSCCP, LOGL_NOTICE, "Unhandled %s\n", + xua_hdr_dump(xua, &xua_dialect_sua)); + break; + } +} + +/*! \brief Main entrance function for primitives from the SCRC (Routing Control) + * \param[in] inst SCCP Instance in which we operate + * \param[in] xua SUA message in xua_msg format */ +void sccp_scoc_rx_from_scrc(struct osmo_sccp_instance *inst, + struct xua_msg *xua) +{ + struct sccp_connection *conn; + struct osmo_sccp_user *scu; + uint32_t src_loc_ref; + int event; + + /* we basically try to convert the SUA message into an event, + * and then dispatch the event to the connection-specific FSM. + * If it is a CORE (Connect REquest), we create the connection + * (and imlpicitly its FSM) first */ + + if (xua->hdr.msg_type == SUA_CO_CORE) { + scu = sccp_find_user(inst, xua); + if (!scu) { + /* this shouldn't happen, as the caller should + * have already verified that a local user is + * equipped for this SSN */ + LOGP(DLSCCP, LOGL_ERROR, "Cannot find user for " + "CORE ?!?\n"); + return; + } + /* Allocate new connection */ + conn = conn_create(inst); + conn->user = scu; + } else { + uint32_t conn_id; + /* Resolve existing connection */ + conn_id = xua_msg_get_u32(xua, SUA_IEI_DEST_REF); + conn = conn_find_by_id(inst, conn_id); + if (!conn) { + LOGP(DLSCCP, LOGL_NOTICE, "Cannot find connection for " + "local reference %u\n", conn_id); + sccp_scoc_rx_unass_local_ref(inst, xua); + return; + } + } + OSMO_ASSERT(conn); + OSMO_ASSERT(conn->fi); + + DEBUGP(DLSCCP, "Received %s for local reference %u\n", + xua_hdr_dump(xua, &xua_dialect_sua), conn->conn_id); + + if (xua->hdr.msg_type != SUA_CO_CORE && + xua->hdr.msg_type != SUA_CO_COAK && + xua->hdr.msg_type != SUA_CO_COREF) { + if (xua_msg_find_tag(xua, SUA_IEI_SRC_REF)) { + /* Check if received source local reference != + * the one we saved in local state */ + src_loc_ref = xua_msg_get_u32(xua, SUA_IEI_SRC_REF); + if (src_loc_ref != conn->remote_ref) { + sccp_scoc_rx_inval_src_ref(conn, xua); + return; + } + } + + /* Check if received OPC != the remote_pc we stored locally */ + if (xua->mtp.opc != conn->remote_pc) { + sccp_scoc_rx_inval_opc(inst, xua); + return; + } + } + + /* Map from XUA message to event */ + event = xua_msg_event_map(xua, sua_scoc_event_map, ARRAY_SIZE(sua_scoc_event_map)); + if (event < 0) { + LOGP(DLSCCP, LOGL_ERROR, "Cannot map SCRC msg %s to event\n", + xua_hdr_dump(xua, &xua_dialect_sua)); + /* Table B.1/Q714 states DISCARD for any message with + * unknown type */ + return; + } + + /* Dispatch event to existing connection */ + osmo_fsm_inst_dispatch(conn->fi, event, xua); +} + +/* get the Connection ID of the given SCU primitive */ +static uint32_t scu_prim_conn_id(const struct osmo_scu_prim *prim) +{ + switch (prim->oph.primitive) { + case OSMO_SCU_PRIM_N_CONNECT: + return prim->u.connect.conn_id; + case OSMO_SCU_PRIM_N_DATA: + return prim->u.data.conn_id; + case OSMO_SCU_PRIM_N_DISCONNECT: + return prim->u.disconnect.conn_id; + case OSMO_SCU_PRIM_N_RESET: + return prim->u.reset.conn_id; + default: + return 0; + } +} + +/*! \brief Main entrance function for primitives from SCCP User + * \param[in] scu SCCP User sending us the primitive + * \param[in] oph Osmocom primitive sent by the user + * \returns 0 on success; negative on error */ +int osmo_sccp_user_sap_down(struct osmo_sccp_user *scu, struct osmo_prim_hdr *oph) +{ + struct osmo_scu_prim *prim = (struct osmo_scu_prim *) oph; + struct osmo_sccp_instance *inst = scu->inst; + struct msgb *msg = prim->oph.msg; + struct sccp_connection *conn; + int rc = 0; + int event; + + LOGP(DLSCCP, LOGL_DEBUG, "Received SCCP User Primitive %s)\n", + osmo_scu_prim_name(&prim->oph)); + + switch (OSMO_PRIM_HDR(&prim->oph)) { + case OSMO_PRIM(OSMO_SCU_PRIM_N_UNITDATA, PRIM_OP_REQUEST): + /* other CL primitives? */ + /* Connectionless by-passes this altogether */ + return sccp_sclc_user_sap_down(scu, oph); + case OSMO_PRIM(OSMO_SCU_PRIM_N_CONNECT, PRIM_OP_REQUEST): + /* Allocate new connection structure */ + conn = conn_create_id(inst, prim->u.connect.conn_id); + if (!conn) { + /* FIXME: inform user */ + goto out; + } + conn->user = scu; + break; + case OSMO_PRIM(OSMO_SCU_PRIM_N_CONNECT, PRIM_OP_RESPONSE): + case OSMO_PRIM(OSMO_SCU_PRIM_N_DATA, PRIM_OP_REQUEST): + case OSMO_PRIM(OSMO_SCU_PRIM_N_DISCONNECT, PRIM_OP_REQUEST): + case OSMO_PRIM(OSMO_SCU_PRIM_N_RESET, PRIM_OP_REQUEST): + /* Resolve existing connection structure */ + conn = conn_find_by_id(inst, scu_prim_conn_id(prim)); + if (!conn) { + /* FIXME: inform user */ + goto out; + } + break; + } + + /* Map from primitive to event */ + event = osmo_event_for_prim(oph, scu_scoc_event_map); + + /* Dispatch event into connection */ + rc = osmo_fsm_inst_dispatch(conn->fi, event, prim); +out: + /* the SAP is supposed to consume the primitive/msgb */ + msgb_free(msg); + + return rc; +} + +void sccp_scoc_flush_connections(struct osmo_sccp_instance *inst) +{ + struct sccp_connection *conn, *conn2; + + llist_for_each_entry_safe(conn, conn2, &inst->connections, list) + conn_destroy(conn); +} diff --git a/src/sccp_scrc.c b/src/sccp_scrc.c new file mode 100644 index 0000000..9bccc0a --- /dev/null +++ b/src/sccp_scrc.c @@ -0,0 +1,473 @@ +/* SCCP Routing Control (SCRC) according to ITU-T Q.714 */ + +/* (C) 2015-2017 by Harald Welte + * All Rights reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include "sccp_internal.h" +#include "xua_internal.h" + +/*********************************************************************** + * Helper Functions + ***********************************************************************/ + +static bool sua_is_connectionless(struct xua_msg *xua) +{ + if (xua->hdr.msg_class == SUA_MSGC_CL) + return true; + else + return false; +} + +static bool sua_is_cr(struct xua_msg *xua) +{ + if (xua->hdr.msg_class == SUA_MSGC_CO && + xua->hdr.msg_type == SUA_CO_CORE) + return true; + + return false; +} + +static bool dpc_accessible(struct osmo_sccp_instance *inst, uint32_t pc) +{ + /* TODO: implement this! */ + return true; +} + +static bool sccp_available(struct osmo_sccp_instance *inst, + const struct osmo_sccp_addr *addr) +{ + /* TODO: implement this! */ + return true; +} + +static int sua2sccp_tx_m3ua(struct osmo_sccp_instance *inst, + struct xua_msg *sua) +{ + struct msgb *msg; + struct osmo_mtp_prim *omp; + struct osmo_mtp_transfer_param *param; + struct osmo_ss7_instance *s7i = inst->ss7; + uint32_t remote_pc = sua->mtp.dpc; + + /* 1) encode the SUA in xua_msg to SCCP message */ + msg = osmo_sua_to_sccp(sua); + if (!msg) { + LOGP(DLSCCP, LOGL_ERROR, "Cannot encode SUA to SCCP\n"); + return -1; + } + + /* 2) wrap into MTP-TRANSFER.req primtiive */ + msg->l2h = msg->data; + omp = (struct osmo_mtp_prim *) msgb_push(msg, sizeof(*omp)); + osmo_prim_init(&omp->oph, MTP_SAP_USER, + OSMO_MTP_PRIM_TRANSFER, PRIM_OP_REQUEST, msg); + param = &omp->u.transfer; + if (sua->mtp.opc) + param->opc = sua->mtp.opc; + else + param->opc = s7i->cfg.primary_pc; + param->dpc = remote_pc; + param->sls = sua->mtp.sls; + param->sio = MTP_SIO(MTP_SI_SCCP, s7i->cfg.network_indicator); + + /* 3) send via MTP-SAP (osmo_ss7_instance) */ + return osmo_ss7_user_mtp_xfer_req(s7i, omp); +} + +/* Gererate MTP-TRANSFER.req from xUA message */ +static int gen_mtp_transfer_req_xua(struct osmo_sccp_instance *inst, + struct xua_msg *xua, + const struct osmo_sccp_addr *called) +{ + struct osmo_ss7_route *rt; + + /* this is a bit fishy due to the different requirements of + * classic SSCP/MTP compared to various SIGTRAN stackings. + * Normally, we would expect a fully encoded SCCP message here, + * but then if the route points to a SUA link, we actually need + * the SUA version of the message. + * + * We need to differentiate the following cases: + * a) SUA: encode XUA to SUA and send via ASP + * b) M3UA: encode XUA to SCCP, create MTP-TRANSFER.req + * primitive and send it via ASP + * c) M2UA/M2PA or CS7: encode XUA, create MTP-TRANSFER.req + * primitive and send it via link + */ + + if (called->presence & OSMO_SCCP_ADDR_T_PC) + xua->mtp.dpc = called->pc; + if (!xua->mtp.dpc) { + LOGP(DLSCCP, LOGL_ERROR, "MTP-TRANSFER.req from SCCP " + "without DPC?!?\n"); + return -1; + } + + rt = osmo_ss7_route_lookup(inst->ss7, xua->mtp.dpc); + if (!rt) { + LOGP(DLSCCP, LOGL_ERROR, "MTP-TRANSFER.req from SCCP for " + "DPC %u: no route!\n", xua->mtp.dpc); + return -1; + } + + if (rt->dest.as) { + struct osmo_ss7_as *as = rt->dest.as; + switch (as->cfg.proto) { + case OSMO_SS7_ASP_PROT_M3UA: + return sua2sccp_tx_m3ua(inst, xua); + default: + LOGP(DLSCCP, LOGL_ERROR, "MTP-TRANSFER.req for " + "unknown protocol %u\n", as->cfg.proto); + break; + } + } else if (rt->dest.linkset) { + LOGP(DLSCCP, LOGL_ERROR, "MTP-TRANSFER.req from SCCP for " + "linkset %s unsupported\n", rt->dest.linkset->cfg.name); + } else { + OSMO_ASSERT(0); + } + return -1; +} + +/*********************************************************************** + * Global Title Translation + ***********************************************************************/ + +static int translate(struct osmo_sccp_instance *inst, + const struct osmo_sccp_addr *called, + struct osmo_sccp_addr *translated) +{ + /* TODO: implement this! */ + *translated = *called; + return 0; +} + + +/*********************************************************************** + * Individual SCRC Nodes + ***********************************************************************/ + +static int scrc_local_out_common(struct osmo_sccp_instance *inst, + struct xua_msg *xua, + const struct osmo_sccp_addr *called); + +static int scrc_node_12(struct osmo_sccp_instance *inst, struct xua_msg *xua, + const struct osmo_sccp_addr *called) +{ + /* TODO: Determine restriction */ + /* TODO: Treat Calling Party Addr */ + /* TODO: Hop counter */ + /* MTP-TRANSFER.req to MTP */ + return gen_mtp_transfer_req_xua(inst, xua, called); +} + +static int scrc_node_2(struct osmo_sccp_instance *inst, struct xua_msg *xua, + const struct osmo_sccp_addr *called) +{ + /* Node 2 on Sheet 5, only CO */ + /* Is DPC accessible? */ + if (!dpc_accessible(inst, called->pc)) { + /* Error: MTP Failure */ + /* Routing Failure SCRC -> SCOC */ + sccp_scoc_rx_scrc_rout_fail(inst, xua, + SCCP_RETURN_CAUSE_MTP_FAILURE); + return 0; + } + /* Is SCCP available? */ + if (!sccp_available(inst, called)) { + /* Error: SCCP Failure */ + /* Routing Failure SCRC -> SCOC */ + sccp_scoc_rx_scrc_rout_fail(inst, xua, + SCCP_RETURN_CAUSE_SCCP_FAILURE); + return 0; + } + return scrc_node_12(inst, xua, called); +} + +static int scrc_node_7(struct osmo_sccp_instance *inst, + struct xua_msg *xua, + const struct osmo_sccp_addr *called) +{ + /* Connection Oriented? */ + if (sua_is_connectionless(xua)) { + /* TODO: Perform Capability Test */ + /* TODO: Canges Needed? */ + if (0) { + /* Changes Needed -> SCLC */ + return 0; + } + } else { + /* TODO: Coupling Required? */ + if (0) { + /* Node 13 (Sheet 5) */ + } + } + return scrc_node_12(inst, xua, called); +} + +/* Node 4 (Sheet 3) */ +static int scrc_node_4(struct osmo_sccp_instance *inst, + struct xua_msg *xua, uint32_t return_cause) +{ + /* TODO: Routing Failure SCRC -> OMAP */ + if (sua_is_connectionless(xua)) { + /* Routing Failure SCRC -> SCLC */ + sccp_sclc_rx_scrc_rout_fail(inst, xua, return_cause); + } else { + /* Routing Failure SCRC -> SCOC */ + sccp_scoc_rx_scrc_rout_fail(inst, xua, return_cause); + } + return 0; +} + +static int scrc_translate_node_9(struct osmo_sccp_instance *inst, + struct xua_msg *xua, + const struct osmo_sccp_addr *called) +{ + struct osmo_sccp_addr translated; + int rc; + + /* Translate */ + rc = translate(inst, called, &translated); + /* Node 9 (Sheet 3) */ + if (rc < 0) { + /* Node 4 (Sheet 3) */ + return scrc_node_4(inst, xua, + SCCP_RETURN_CAUSE_NO_TRANSLATION); + } + /* Route on SSN? */ + if (translated.ri != OSMO_SCCP_RI_SSN_PC && + translated.ri != OSMO_SCCP_RI_SSN_IP) { + /* TODO: GT Routing */ + /* Node 7 (Sheet 5) */ + return scrc_node_7(inst, xua, called); + } + + /* Check DPC resultant from GT translation */ + if (osmo_ss7_pc_is_local(inst->ss7, translated.pc)) { + if (sua_is_connectionless(xua)) { + /* CL_MSG -> SCLC */ + sccp_sclc_rx_from_scrc(inst, xua); + } else { + /* Node 1 (Sheet 3) */ + /* CO_MSG -> SCOC */ + sccp_scoc_rx_from_scrc(inst, xua); + } + return 0; + } else { + /* Availability already checked */ + /* Node 7 (Sheet 5) */ + return scrc_node_7(inst, xua, called); + } +} + +/* Node 6 (Sheet 3) */ +static int scrc_node_6(struct osmo_sccp_instance *inst, + struct xua_msg *xua, + const struct osmo_sccp_addr *called) +{ + struct osmo_sccp_user *scu; + + scu = sccp_user_find(inst, called->ssn, called->pc); + + /* Is subsystem equipped? */ + if (!scu) { + /* Error: unequipped user */ + return scrc_node_4(inst, xua, + SCCP_RETURN_CAUSE_UNEQUIPPED_USER); + } + /* Is subsystem available? */ + if (0 /* !subsys_available(scu) */) { + /* Error: subsystem failure */ + /* TODO: SCRC -> SSPC */ + if (sua_is_connectionless(xua)) { + /* Routing Failure SCRC -> SCLC */ + sccp_sclc_rx_scrc_rout_fail(inst, xua, + SCCP_RETURN_CAUSE_SUBSYSTEM_FAILURE); + } else { + /* Routing Failure SCRC -> SCOC */ + sccp_scoc_rx_scrc_rout_fail(inst, xua, + SCCP_RETURN_CAUSE_SUBSYSTEM_FAILURE); + } + return 0; + } + if (sua_is_connectionless(xua)) { + /* CL_MSG -> SCLC */ + sccp_sclc_rx_from_scrc(inst, xua); + } else { + /* Node 1 (Sheet 3) */ + /* CO_MSG -> SCOC */ + sccp_scoc_rx_from_scrc(inst, xua); + } + return 0; +} + +static int scrc_local_out_common(struct osmo_sccp_instance *inst, + struct xua_msg *xua, + const struct osmo_sccp_addr *called) +{ + struct osmo_ss7_instance *s7i = inst->ss7; + + /* Called address includes DPC? */ + if (called->presence & OSMO_SCCP_ADDR_T_PC) { + if (!osmo_ss7_pc_is_local(s7i, called->pc)) { + /* Node 7 of sheet 5 */ + /* Coupling required: no */ + return scrc_node_12(inst, xua, called); + } + /* Called address includes SSN? */ + if (called->presence & OSMO_SCCP_ADDR_T_SSN) { + if (translate && + (called->presence & OSMO_SCCP_ADDR_T_GT)) + return scrc_translate_node_9(inst, xua, called); + else + return scrc_node_6(inst, xua, called); + } + } + /* No SSN in CalledAddr or no DPC included */ + if (!(called->presence & OSMO_SCCP_ADDR_T_GT)) { + /* Error reason: Unqualified */ + /* TODO: Routing Failure SCRC -> OMAP */ + /* Node 4 (Sheet 3) */ + return scrc_node_4(inst, xua, + SCCP_RETURN_CAUSE_UNQUALIFIED); + } else + return scrc_translate_node_9(inst, xua, called); +} + +/*********************************************************************** + * Entrance points from MTP, SCLC, SCOC, ... + ***********************************************************************/ + +/* Figure C.1/Q.714 - SCCP Routing control procedures (SCRC) */ + +/* Connection oriented message SCOC -> SCRC */ +int sccp_scrc_rx_scoc_conn_msg(struct osmo_sccp_instance *inst, + struct xua_msg *xua) +{ + struct osmo_sccp_addr called; + + LOGP(DLSS7, LOGL_DEBUG, "%s: %s\n", __func__, xua_msg_dump(xua, &xua_dialect_sua)); + + sua_addr_parse(&called, xua, SUA_IEI_DEST_ADDR); + + /* Is this a CR message ? */ + if (xua->hdr.msg_type != SUA_CO_CORE) + return scrc_node_2(inst, xua, &called); + + /* TOOD: Coupling performed (not supported) */ + if (0) + return scrc_node_2(inst, xua, &called); + + return scrc_local_out_common(inst, xua, &called); +} + +/* Connectionless Message SCLC -> SCRC */ +int sccp_scrc_rx_sclc_msg(struct osmo_sccp_instance *inst, + struct xua_msg *xua) +{ + struct osmo_sccp_addr called; + + LOGP(DLSS7, LOGL_DEBUG, "%s: %s\n", __func__, xua_msg_dump(xua, &xua_dialect_sua)); + + sua_addr_parse(&called, xua, SUA_IEI_DEST_ADDR); + + /* Message Type */ + if (xua->hdr.msg_type == SUA_CL_CLDR) { + /* UDTS, XUDTS or LUDTS */ + if (called.ri != OSMO_SCCP_RI_GT) + return scrc_node_7(inst, xua, &called); + /* Fall-through */ + } else { + if (0 /* TODO: translation already performed */) { + /* Node 12 (Sheet 5) */ + return scrc_node_12(inst, xua, &called); + } + } + return scrc_local_out_common(inst, xua, &called); +} + +/* Figure C.1/Q.714 Sheet 1 of 12, after we converted the + * MTP-TRANSFER.ind to SUA */ +int scrc_rx_mtp_xfer_ind_xua(struct osmo_sccp_instance *inst, + struct xua_msg *xua) +{ + struct osmo_sccp_addr called; + uint32_t proto_class; + struct xua_msg_part *hop_ctr_part; + + LOGP(DLSS7, LOGL_DEBUG, "%s: %s\n", __func__, xua_msg_dump(xua, &xua_dialect_sua)); + /* TODO: SCCP or nodal congestion? */ + + /* CR or CL message? */ + if (!sua_is_connectionless(xua) && !sua_is_cr(xua)) { + /* Node 1 (Sheet 3) */ + /* deliver to SCOC */ + sccp_scoc_rx_from_scrc(inst, xua); + return 0; + } + /* We only treat connectionless and CR below */ + + sua_addr_parse(&called, xua, SUA_IEI_DEST_ADDR); + + /* Route on GT? */ + if (called.ri != OSMO_SCCP_RI_GT) { + /* Node 6 (Sheet 3) */ + return scrc_node_6(inst, xua, &called); + } + /* Message with hop-counter? */ + hop_ctr_part = xua_msg_find_tag(xua, SUA_IEI_S7_HOP_CTR); + if (hop_ctr_part) { + uint32_t hop_counter = xua_msg_part_get_u32(hop_ctr_part); + if (hop_counter <= 1) { + /* Error: hop-counter violation */ + /* node 4 */ + return scrc_node_4(inst, xua, + SCCP_RETURN_CAUSE_HOP_COUNTER_VIOLATION); + } + /* Decrement hop-counter */ + hop_counter--; + *(uint32_t *)hop_ctr_part->dat = htonl(hop_counter); + } + + /* node 3 (Sheet 2) */ + /* Protocol class 0? */ + proto_class = xua_msg_get_u32(xua, SUA_IEI_PROTO_CLASS); + switch (proto_class) { + case 0: + /* TODO: Assign SLS */ + break; + case 1: + /* TODO: Map incoming SLS to outgoing SLS */ + break; + default: + break; + } + return scrc_translate_node_9(inst, xua, &called); +} diff --git a/src/sccp_user.c b/src/sccp_user.c new file mode 100644 index 0000000..df02486 --- /dev/null +++ b/src/sccp_user.c @@ -0,0 +1,377 @@ +/* SCCP User related routines */ + +/* (C) 2017 by Harald Welte + * All Rights Reserved + * + * based on my 2011 Erlang implementation osmo_ss7/src/sua_sccp_conv.erl + * + * References: ITU-T Q.713 and IETF RFC 3868 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include + +#include +#include + +#include +#include +#include +#include + +#include "sccp_internal.h" +#include "xua_internal.h" + +/*! \brief Find a SCCP User registered for given PC+SSN or SSN only + * \param[in] inst SCCP Instance in which to search + * \param[in] ssn Sub-System Number to search for + * \param[in] pc Point Code to search for + * \returns Matching SCCP User; NULL if none found */ +struct osmo_sccp_user * +sccp_user_find(struct osmo_sccp_instance *inst, uint16_t ssn, uint32_t pc) +{ + struct osmo_sccp_user *scu; + + /* First try to find match for PC + SSN */ + llist_for_each_entry(scu, &inst->users, list) { + if (scu->pc_valid && scu->pc == pc && scu->ssn == ssn) + return scu; + } + + /* Then try to match on SSN only */ + llist_for_each_entry(scu, &inst->users, list) { + if (!scu->pc_valid && scu->ssn == ssn) + return scu; + } + + return NULL; +} + +/*! \brief Bind a SCCP User to a given Point Code + * \param[in] inst SCCP Instance + * \param[in] name human-readable name + * \param[in] ssn Sub-System Number to bind to + * \param[in] pc Point Code to bind to (if any) + * \param[in] pc_valid Whether or not \ref pc is valid/used + * \returns Callee-allocated SCCP User on success; negative otherwise */ +static struct osmo_sccp_user * +sccp_user_bind_pc(struct osmo_sccp_instance *inst, const char *name, + osmo_prim_cb prim_cb, uint16_t ssn, uint32_t pc, bool pc_valid) +{ + struct osmo_sccp_user *scu; + if (!pc_valid) + pc = 0; + + if (sccp_user_find(inst, ssn, pc)) + return NULL; + + LOGP(DLSCCP, LOGL_INFO, "Binding user '%s' to SSN=%u PC=%u (pc_valid=%u)\n", + name, ssn, pc, pc_valid); + + scu = talloc_zero(inst, struct osmo_sccp_user); + scu->name = talloc_strdup(scu, name); + scu->inst = inst; + scu->prim_cb = prim_cb; + scu->ssn = ssn; + scu->pc = pc; + scu->pc_valid = pc_valid; + llist_add_tail(&scu->list, &inst->users); + + return scu; +} + +/*! \brief Bind a given SCCP User to a given SSN+PC + * \param[in] inst SCCP Instance + * \param[in] name human-readable name + * \param[in] ssn Sub-System Number to bind to + * \param[in] pc Point Code to bind to (if any) + * \returns Callee-allocated SCCP User on success; negative otherwise */ +struct osmo_sccp_user * +osmo_sccp_user_bind_pc(struct osmo_sccp_instance *inst, const char *name, + osmo_prim_cb prim_cb, uint16_t ssn, uint32_t pc) +{ + return sccp_user_bind_pc(inst, name, prim_cb, ssn, pc, true); +} + +/*! \brief Bind a given SCCP User to a given SSN (at any PC) + * \param[in] inst SCCP Instance + * \param[in] name human-readable name + * \param[in] ssn Sub-System Number to bind to + * \returns Callee-allocated SCCP User on success; negative otherwise */ +struct osmo_sccp_user * +osmo_sccp_user_bind(struct osmo_sccp_instance *inst, const char *name, + osmo_prim_cb prim_cb, uint16_t ssn) +{ + return sccp_user_bind_pc(inst, name, prim_cb, ssn, 0, false); +} + +/*! \brief Unbind a given SCCP user + * \param[in] scu SCCP User which is to be un-bound. Will be destroyed + * at the time this function returns. */ +void osmo_sccp_user_unbind(struct osmo_sccp_user *scu) +{ + LOGP(DLSCCP, LOGL_INFO, "Unbinding user '%s' from SSN=%u PC=%u " + "(pc_valid=%u)\n", scu->name, scu->ssn, scu->pc, + scu->pc_valid); + /* FIXME: free/release all connections held by this user? */ + llist_del(&scu->list); + talloc_free(scu); +} + +/*! \brief Send a SCCP User SAP Primitive up to the User + * \param[in] scu SCCP User to whom to send the primitive + * \param[in] prim Primitive to send to the user + * \returns return value of the SCCP User's prim_cb() function */ +int sccp_user_prim_up(struct osmo_sccp_user *scu, struct osmo_scu_prim *prim) +{ + LOGP(DLSCCP, LOGL_DEBUG, "Delivering %s to SCCP User '%s'\n", + osmo_scu_prim_name(&prim->oph), scu->name); + return scu->prim_cb(&prim->oph, scu); +} + +/* prim_cb handed to MTP code for incoming MTP-TRANSFER.ind */ +static int mtp_user_prim_cb(struct osmo_prim_hdr *oph, void *ctx) +{ + struct osmo_sccp_instance *inst = ctx; + struct osmo_mtp_prim *omp = (struct osmo_mtp_prim *)oph; + struct xua_msg *xua; + + OSMO_ASSERT(oph->sap == MTP_SAP_USER); + + switch OSMO_PRIM(oph->primitive, oph->operation) { + case OSMO_PRIM(OSMO_MTP_PRIM_TRANSFER, PRIM_OP_INDICATION): + /* Convert from SCCP to SUA in xua_msg format */ + xua = osmo_sccp_to_xua(oph->msg); + xua->mtp = omp->u.transfer; + /* hand this primitive into SCCP via the SCRC code */ + return scrc_rx_mtp_xfer_ind_xua(inst, xua); + default: + LOGP(DLSCCP, LOGL_ERROR, "Unknown primitive %u:%u receivd\n", + oph->primitive, oph->operation); + return -1; + } +} + +static LLIST_HEAD(sccp_instances); + +/*! \brief create a SCCP Instance and register it as user with SS7 inst + * \param[in] ss7 SS7 instance to which this SCCP instance belongs + * \param[in] priv private data to be stored within SCCP instance + * \returns callee-allocated SCCP instance on success; NULL on error */ +struct osmo_sccp_instance * +osmo_sccp_instance_create(struct osmo_ss7_instance *ss7, void *priv) +{ + struct osmo_sccp_instance *inst; + + inst = talloc_zero(ss7, struct osmo_sccp_instance); + if (!inst) + return NULL; + + inst->ss7 = ss7; + inst->priv = priv; + INIT_LLIST_HEAD(&inst->connections); + INIT_LLIST_HEAD(&inst->users); + + inst->ss7_user.inst = ss7; + inst->ss7_user.name = "SCCP"; + inst->ss7_user.prim_cb = mtp_user_prim_cb; + inst->ss7_user.priv = inst; + + osmo_ss7_user_register(ss7, MTP_SI_SCCP, &inst->ss7_user); + + llist_add_tail(&inst->list, &sccp_instances); + + return inst; +} + +void osmo_sccp_instance_destroy(struct osmo_sccp_instance *inst) +{ + struct osmo_sccp_user *scu, *scu2; + + inst->ss7->sccp = NULL; + osmo_ss7_user_unregister(inst->ss7, MTP_SI_SCCP, &inst->ss7_user); + + llist_for_each_entry_safe(scu, scu2, &inst->users, list) { + osmo_sccp_user_unbind(scu); + } + sccp_scoc_flush_connections(inst); + llist_del(&inst->list); + talloc_free(inst); +} + +/*********************************************************************** + * Convenience function for CLIENT + ***********************************************************************/ + +struct osmo_sccp_instance * +osmo_sccp_simple_client(void *ctx, const char *name, uint32_t pc, + enum osmo_ss7_asp_protocol prot, + int local_port, int remote_port, const char *remote_ip) +{ + struct osmo_ss7_instance *ss7; + struct osmo_ss7_as *as; + struct osmo_ss7_route *rt; + struct osmo_ss7_asp *asp; + char *as_name, *asp_name; + + if (!remote_port || remote_port < 0) + remote_port = osmo_ss7_asp_protocol_port(prot); + if (local_port < 0) + local_port = osmo_ss7_asp_protocol_port(prot); + + /* allocate + initialize SS7 instance */ + ss7 = osmo_ss7_instance_find_or_create(ctx, 1); + if (!ss7) + return NULL; + ss7->cfg.primary_pc = pc; + + as_name = talloc_asprintf(ctx, "as-clnt-%s", name); + asp_name = talloc_asprintf(ctx, "asp-clnt-%s", name); + + /* application server */ + as = osmo_ss7_as_find_or_create(ss7, as_name, prot); + if (!as) + goto out_strings; + + /* install default route */ + rt = osmo_ss7_route_create(ss7->rtable_system, 0, 0, as_name); + if (!rt) + goto out_as; + talloc_free(as_name); + + /* application server process */ + asp = osmo_ss7_asp_find_or_create(ss7, asp_name, remote_port, local_port, + prot); + if (!asp) + goto out_rt; + asp->cfg.remote.host = talloc_strdup(asp, remote_ip); + osmo_ss7_as_add_asp(as, asp_name); + talloc_free(asp_name); + osmo_ss7_asp_restart(asp); + + /* Allocate SCCP stack + SCCP user */ + ss7->sccp = osmo_sccp_instance_create(ss7, NULL); + if (!ss7->sccp) + goto out_asp; + + return ss7->sccp; + +out_asp: + osmo_ss7_asp_destroy(asp); +out_rt: + osmo_ss7_route_destroy(rt); +out_as: + osmo_ss7_as_destroy(as); +out_strings: + talloc_free(as_name); + talloc_free(asp_name); + osmo_ss7_instance_destroy(ss7); + + return NULL; +} + +/*********************************************************************** + * Convenience function for SERVER + ***********************************************************************/ + +struct osmo_sccp_instance * +osmo_sccp_simple_server(void *ctx, uint32_t pc, + enum osmo_ss7_asp_protocol prot, int local_port, + const char *local_ip) +{ + struct osmo_ss7_instance *ss7; + struct osmo_xua_server *xs; + + if (local_port < 0) + local_port = osmo_ss7_asp_protocol_port(prot); + + /* allocate + initialize SS7 instance */ + ss7 = osmo_ss7_instance_find_or_create(ctx, 1); + if (!ss7) + return NULL; + ss7->cfg.primary_pc = pc; + + xs = osmo_ss7_xua_server_create(ss7, prot, local_port, local_ip); + if (!xs) + goto out_ss7; + + /* Allocate SCCP stack */ + ss7->sccp = osmo_sccp_instance_create(ss7, NULL); + if (!ss7->sccp) + goto out_xs; + + return ss7->sccp; + +out_xs: + osmo_ss7_xua_server_destroy(xs); +out_ss7: + osmo_ss7_instance_destroy(ss7); + + return NULL; +} + +struct osmo_sccp_instance * +osmo_sccp_simple_server_add_clnt(struct osmo_sccp_instance *inst, + enum osmo_ss7_asp_protocol prot, + const char *name, uint32_t pc, + int local_port, int remote_port, + const char *remote_ip) +{ + struct osmo_ss7_instance *ss7 = inst->ss7; + struct osmo_ss7_as *as; + struct osmo_ss7_route *rt; + struct osmo_ss7_asp *asp; + char *as_name, *asp_name; + + if (local_port < 0) + local_port = osmo_ss7_asp_protocol_port(prot); + + if (remote_port < 0) + remote_port = osmo_ss7_asp_protocol_port(prot); + + as_name = talloc_asprintf(ss7, "as-srv-%s", name); + asp_name = talloc_asprintf(ss7, "asp-srv-%s", name); + + /* application server */ + as = osmo_ss7_as_find_or_create(ss7, as_name, prot); + if (!as) + goto out_strings; + talloc_free(as_name); + + /* route only selected PC to the client */ + rt = osmo_ss7_route_create(ss7->rtable_system, pc, 0xffff, as_name); + if (!rt) + goto out_as; + + asp = osmo_ss7_asp_find_or_create(ss7, asp_name, remote_port, local_port, prot); + if (!asp) + goto out_rt; + asp->cfg.is_server = true; + osmo_ss7_as_add_asp(as, asp_name); + talloc_free(asp_name); + osmo_ss7_asp_restart(asp); + + return ss7->sccp; + +out_rt: + osmo_ss7_route_destroy(rt); +out_as: + osmo_ss7_as_destroy(as); +out_strings: + talloc_free(as_name); + talloc_free(asp_name); + + return NULL; +} -- To view, visit https://gerrit.osmocom.org/2215 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I916e895d9a4914b05483fe12ab5251f206d10dee Gerrit-PatchSet: 5 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:31:09 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:31:09 +0000 Subject: [PATCH] libosmo-sccp[master]: remove tests/sigtran: it's not a test case In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2216 to look at the new patch set (#5). remove tests/sigtran: it's not a test case in tests/* we have unit tests that are run as part of the autotest suite during 'make check'. The code in tests/sigtran is an example, but not a test. As the API is changing anyway, let's remove it for now and re-introduce actual tests and examples after the changes in API required by the upcoming new SCCP core. Change-Id: Ie471a197856c875eb4987bf9858d757312de24fb --- M configure.ac M tests/Makefile.am D tests/sigtran/Makefile.am D tests/sigtran/sua_client_test.c D tests/sigtran/sua_server_test.c D tests/sigtran/sua_test_common.c D tests/sigtran/sua_test_common.h 7 files changed, 1 insertion(+), 266 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/16/2216/5 diff --git a/configure.ac b/configure.ac index ed3e25a..3644d22 100644 --- a/configure.ac +++ b/configure.ac @@ -66,7 +66,6 @@ tests/sccp/Makefile tests/mtp/Makefile tests/m2ua/Makefile - tests/sigtran/Makefile tests/xua/Makefile tests/ss7/Makefile Makefile) diff --git a/tests/Makefile.am b/tests/Makefile.am index 6d3c96f..70e8a00 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,4 +1,4 @@ -SUBDIRS = xua sccp mtp m2ua sigtran ss7 +SUBDIRS = xua sccp mtp m2ua ss7 # The `:;' works around a Bash 3.2 bug when the output is not writeable. $(srcdir)/package.m4: $(top_srcdir)/configure.ac diff --git a/tests/sigtran/Makefile.am b/tests/sigtran/Makefile.am deleted file mode 100644 index 91c0960..0000000 --- a/tests/sigtran/Makefile.am +++ /dev/null @@ -1,11 +0,0 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir) -AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) - -noinst_HEADERS = sua_test_common.h -noinst_PROGRAMS = sua_server_test sua_client_test - -sua_server_test_SOURCES = sua_server_test.c sua_test_common.c -sua_server_test_LDADD = $(top_builddir)/src/libosmo-sigtran.la $(LIBOSMOCORE_LIBS) $(TALLOC_LIBS) - -sua_client_test_SOURCES = sua_client_test.c sua_test_common.c -sua_client_test_LDADD = $(top_builddir)/src/libosmo-sigtran.la $(LIBOSMOCORE_LIBS) $(TALLOC_LIBS) diff --git a/tests/sigtran/sua_client_test.c b/tests/sigtran/sua_client_test.c deleted file mode 100644 index 3cbd937..0000000 --- a/tests/sigtran/sua_client_test.c +++ /dev/null @@ -1,56 +0,0 @@ -#include "sua_test_common.h" - -struct osmo_sccp_user *g_user; -struct osmo_sccp_link *g_link; - -static int sccp_sap_up(struct osmo_prim_hdr *oph, void *link) -{ - struct osmo_scu_prim *prim = (struct osmo_scu_prim *) oph; - struct osmo_prim_hdr *resp = NULL; - uint8_t payload[] = { 0xa1, 0xa2, 0xa3 }; - - printf("sccp_sap_up(%s)\n", osmo_scu_prim_name(oph)); - - switch (OSMO_PRIM_HDR(oph)) { - case OSMO_PRIM(OSMO_SCU_PRIM_N_CONNECT, PRIM_OP_CONFIRM): - printf("N-CONNECT.ind(%u), issuing DATA.req\n", - prim->u.connect.conn_id); - resp = make_dt1_req(prim->u.connect.conn_id, payload, sizeof(payload)); - break; - } - - if (resp) - osmo_sua_user_link_down(link, resp); - - msgb_free(oph->msg); - return 0; -} - - -int main(int argc, char **argv) -{ - void *ctx = talloc_named_const(NULL, 1, "root"); - int rc; - - osmo_sua_set_log_area(DSUA); - - osmo_init_logging(&test_log_info); - - g_user = osmo_sua_user_create(ctx, sccp_sap_up, NULL); - - rc = osmo_sua_client_connect(g_user, "127.0.0.1", 2342); - if (rc < 0) { - exit(1); - } - - g_link = osmo_sua_client_get_link(g_user); - - int i = 8000; - - while (1) { - if (i < 8010) - tx_conn_req(g_link, i++); - //tx_unitdata(g_link); - osmo_select_main(0); - } -} diff --git a/tests/sigtran/sua_server_test.c b/tests/sigtran/sua_server_test.c deleted file mode 100644 index 97b2baf..0000000 --- a/tests/sigtran/sua_server_test.c +++ /dev/null @@ -1,78 +0,0 @@ -#include "sua_test_common.h" - -struct osmo_prim_hdr *make_conn_resp(struct osmo_scu_connect_param *param) -{ - struct msgb *msg = msgb_alloc(1024, "conn_resp"); - struct osmo_scu_prim *prim; - - prim = (struct osmo_scu_prim *) msgb_put(msg, sizeof(*prim)); - osmo_prim_init(&prim->oph, SCCP_SAP_USER, - OSMO_SCU_PRIM_N_CONNECT, - PRIM_OP_RESPONSE, msg); - memcpy(&prim->u.connect, param, sizeof(prim->u.connect)); - return &prim->oph; -} - -static int sccp_sap_up(struct osmo_prim_hdr *oph, void *link) -{ - struct osmo_scu_prim *prim = (struct osmo_scu_prim *) oph; - struct osmo_prim_hdr *resp = NULL; - const uint8_t payload[] = { 0xb1, 0xb2, 0xb3 }; - - printf("sccp_sap_up(%s)\n", osmo_scu_prim_name(oph)); - - switch (OSMO_PRIM_HDR(oph)) { - case OSMO_PRIM(OSMO_SCU_PRIM_N_CONNECT, PRIM_OP_CONFIRM): - /* confirmation of outbound connection */ - break; - case OSMO_PRIM(OSMO_SCU_PRIM_N_CONNECT, PRIM_OP_INDICATION): - /* indication of new inbound connection request*/ - printf("N-CONNECT.ind(X->%u)\n", prim->u.connect.conn_id); - resp = make_conn_resp(&prim->u.connect); - break; - case OSMO_PRIM(OSMO_SCU_PRIM_N_DISCONNECT, PRIM_OP_INDICATION): - /* indication of disconnect */ - printf("N-DISCONNECT.ind(%u)\n", prim->u.disconnect.conn_id); - break; - case OSMO_PRIM(OSMO_SCU_PRIM_N_DATA, PRIM_OP_INDICATION): - /* connection-oriented data received */ - printf("N-DATA.ind(%u, %s)\n", prim->u.data.conn_id, - osmo_hexdump(msgb_l2(oph->msg), msgb_l2len(oph->msg))); - resp = make_dt1_req(prim->u.data.conn_id, payload, sizeof(payload)); - break; - case OSMO_PRIM(OSMO_SCU_PRIM_N_UNITDATA, PRIM_OP_INDICATION): - /* connection-oriented data received */ - printf("N-UNITDATA.ind(%s)\n", - osmo_hexdump(msgb_l2(oph->msg), msgb_l2len(oph->msg))); - tx_unitdata(link); - break; - } - - if (resp) - osmo_sua_user_link_down(link, resp); - - msgb_free(oph->msg); - return 0; -} - -int main(int argc, char **argv) -{ - struct osmo_sccp_user *user; - void *ctx = talloc_named_const(NULL, 1, "root"); - int rc; - - osmo_sua_set_log_area(DSUA); - - osmo_init_logging(&test_log_info); - - user = osmo_sua_user_create(ctx, sccp_sap_up, NULL); - - rc = osmo_sua_server_listen(user, "127.0.0.1", 2342); - if (rc < 0) { - exit(1); - } - - while (1) { - osmo_select_main(0); - } -} diff --git a/tests/sigtran/sua_test_common.c b/tests/sigtran/sua_test_common.c deleted file mode 100644 index db1f5f3..0000000 --- a/tests/sigtran/sua_test_common.c +++ /dev/null @@ -1,87 +0,0 @@ -#include "sua_test_common.h" - -static const struct log_info_cat log_cat[] = { - [DMAIN] = { - .name = "DMAIN", .loglevel = LOGL_DEBUG, .enabled = 1, - .color = "", - .description = "Main program", - }, - [DSUA] = { - .name = "DSUA", .loglevel = LOGL_DEBUG, .enabled = 1, - .color = "", - .description = "SCCP User Adaption", - }, -}; - -const struct log_info test_log_info = { - .cat = log_cat, - .num_cat = ARRAY_SIZE(log_cat), -}; - -int tx_unitdata(struct osmo_sccp_link *link) -{ - struct msgb *msg = msgb_alloc(1024, "tx_unitdata"); - struct osmo_scu_prim *prim; - struct osmo_scu_unitdata_param *param; - uint8_t *cur; - - prim = (struct osmo_scu_prim *) msgb_put(msg, sizeof(*prim)); - param = &prim->u.unitdata; - param->calling_addr.presence = OSMO_SCCP_ADDR_T_SSN; - param->called_addr.presence = OSMO_SCCP_ADDR_T_SSN; - osmo_prim_init(&prim->oph, SCCP_SAP_USER, OSMO_SCU_PRIM_N_UNITDATA, PRIM_OP_REQUEST, msg); - - cur = msg->l2h = msgb_put(msg, 3); - cur[0] = 1; cur[1] = 2; cur[2] = 3; - - return osmo_sua_user_link_down(link, &prim->oph); -} - -static void sccp_make_addr_pc_ssn(struct osmo_sccp_addr *addr, uint32_t pc, uint32_t ssn) -{ - addr->presence = OSMO_SCCP_ADDR_T_SSN | OSMO_SCCP_ADDR_T_PC; - addr->ssn = ssn; - addr->pc = pc; -} - -struct osmo_prim_hdr *make_conn_req(uint32_t conn_id) -{ - struct msgb *msg = msgb_alloc(1024, "conn_req"); - struct osmo_scu_prim *prim; - - prim = (struct osmo_scu_prim *) msgb_put(msg, sizeof(*prim)); - osmo_prim_init(&prim->oph, SCCP_SAP_USER, - OSMO_SCU_PRIM_N_CONNECT, - PRIM_OP_REQUEST, msg); - /* Set SSN for calling and called addr */ - sccp_make_addr_pc_ssn(&prim->u.connect.called_addr, 2, OSMO_SCCP_SSN_RANAP); - sccp_make_addr_pc_ssn(&prim->u.connect.calling_addr, 1, OSMO_SCCP_SSN_RANAP); - prim->u.connect.sccp_class = 2; - prim->u.connect.conn_id = conn_id; - - return &prim->oph; -} - -int tx_conn_req(struct osmo_sccp_link *link, uint32_t conn_id) -{ - struct osmo_prim_hdr *prim = make_conn_req(conn_id); - return osmo_sua_user_link_down(link, prim); -} - -struct osmo_prim_hdr * -make_dt1_req(uint32_t conn_id, const uint8_t *data, unsigned int len) -{ - struct msgb *msg = msgb_alloc(1024, "dt1"); - struct osmo_scu_prim *prim; - - prim = (struct osmo_scu_prim *) msgb_put(msg, sizeof(*prim)); - osmo_prim_init(&prim->oph, SCCP_SAP_USER, - OSMO_SCU_PRIM_N_DATA, - PRIM_OP_REQUEST, msg); - prim->u.data.conn_id = conn_id; - - msg->l2h = msgb_put(msg, len); - memcpy(msg->l2h, data, len); - - return &prim->oph; -} diff --git a/tests/sigtran/sua_test_common.h b/tests/sigtran/sua_test_common.h deleted file mode 100644 index b1883cd..0000000 --- a/tests/sigtran/sua_test_common.h +++ /dev/null @@ -1,32 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include - - -enum log_cat { - DMAIN, - DSUA, - DXUA, -}; - -extern const struct log_info test_log_info; - -int tx_unitdata(struct osmo_sccp_link *link); -int tx_conn_req(struct osmo_sccp_link *link, uint32_t conn_id); - -struct osmo_prim_hdr *make_conn_req(uint32_t conn_id); -struct osmo_prim_hdr *make_dt1_req(uint32_t conn_id, const uint8_t *data, unsigned int len); -- To view, visit https://gerrit.osmocom.org/2216 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ie471a197856c875eb4987bf9858d757312de24fb Gerrit-PatchSet: 5 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:31:09 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:31:09 +0000 Subject: [PATCH] libosmo-sccp[master]: sccp_sap license header was missing In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2217 to look at the new patch set (#5). sccp_sap license header was missing Change-Id: I442634ca74d9c4cd386726a9d6b933a12f45afc5 --- M src/sccp_sap.c 1 file changed, 19 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/17/2217/5 diff --git a/src/sccp_sap.c b/src/sccp_sap.c index 51598b0..2211f71 100644 --- a/src/sccp_sap.c +++ b/src/sccp_sap.c @@ -1,3 +1,22 @@ +/* SCCP User SAP related routines */ + +/* (C) 2017 by Harald Welte + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + #include #include #include -- To view, visit https://gerrit.osmocom.org/2217 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I442634ca74d9c4cd386726a9d6b933a12f45afc5 Gerrit-PatchSet: 5 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:31:09 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:31:09 +0000 Subject: [PATCH] libosmo-sccp[master]: SUA: Port to new osmo_ss7 and SCCP code In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2218 to look at the new patch set (#5). SUA: Port to new osmo_ss7 and SCCP code If we use the infrastructure provided by osmo_ss7 on the lower layer and the SCCP SCRC, SCLC and SCOC code on the upper side, not much of the original sua.c code remains. It looks much like the M3UA code now. Change-Id: I193b74f58aa70c443ae17e78b5604246d6bc3f71 --- M include/osmocom/sigtran/Makefile.am M include/osmocom/sigtran/sccp_helpers.h D include/osmocom/sigtran/sua.h M src/osmo_ss7.c M src/sccp_helpers.c M src/sccp_scrc.c M src/sua.c M src/xua_internal.h 8 files changed, 364 insertions(+), 1,296 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/18/2218/5 diff --git a/include/osmocom/sigtran/Makefile.am b/include/osmocom/sigtran/Makefile.am index ca7a304..0aa90cb 100644 --- a/include/osmocom/sigtran/Makefile.am +++ b/include/osmocom/sigtran/Makefile.am @@ -1,5 +1,5 @@ sigtran_HEADERS = xua_types.h xua_msg.h m2ua_types.h sccp_sap.h \ - sua.h sigtran_sap.h sccp_helpers.h mtp_sap.h osmo_ss7.h + sigtran_sap.h sccp_helpers.h mtp_sap.h osmo_ss7.h sigtrandir = $(includedir)/osmocom/sigtran diff --git a/include/osmocom/sigtran/sccp_helpers.h b/include/osmocom/sigtran/sccp_helpers.h index 968c500..bbd0364 100644 --- a/include/osmocom/sigtran/sccp_helpers.h +++ b/include/osmocom/sigtran/sccp_helpers.h @@ -1,15 +1,17 @@ #pragma once + #include #include #include -#include -int osmo_sccp_tx_unitdata(struct osmo_sccp_link *link, +void osmo_sccp_make_addr_pc_ssn(struct osmo_sccp_addr *addr, uint32_t pc, uint32_t ssn); + +int osmo_sccp_tx_unitdata(struct osmo_sccp_user *scu, const struct osmo_sccp_addr *calling_addr, const struct osmo_sccp_addr *called_addr, - uint8_t *data, unsigned int len); + const uint8_t *data, unsigned int len); -int osmo_sccp_tx_unitdata_msg(struct osmo_sccp_link *link, +int osmo_sccp_tx_unitdata_msg(struct osmo_sccp_user *scu, const struct osmo_sccp_addr *calling_addr, const struct osmo_sccp_addr *called_addr, struct msgb *msg); @@ -17,26 +19,38 @@ void osmo_sccp_make_addr_pc_ssn(struct osmo_sccp_addr *addr, uint32_t pc, uint32_t ssn); -int osmo_sccp_tx_unitdata_ranap(struct osmo_sccp_link *link, +int osmo_sccp_tx_unitdata_ranap(struct osmo_sccp_user *scu, uint32_t src_point_code, uint32_t dst_point_code, - uint8_t *data, unsigned int len); + const uint8_t *data, unsigned int len); -int osmo_sccp_tx_conn_req(struct osmo_sccp_link *link, uint32_t conn_id, +int osmo_sccp_tx_conn_req(struct osmo_sccp_user *scu, uint32_t conn_id, const struct osmo_sccp_addr *calling_addr, const struct osmo_sccp_addr *called_addr, - uint8_t *data, unsigned int len); + const uint8_t *data, unsigned int len); -int osmo_sccp_tx_conn_req_msg(struct osmo_sccp_link *link, uint32_t conn_id, +int osmo_sccp_tx_conn_req_msg(struct osmo_sccp_user *scu, uint32_t conn_id, const struct osmo_sccp_addr *calling_addr, const struct osmo_sccp_addr *called_addr, struct msgb *msg); -int osmo_sccp_tx_data(struct osmo_sccp_link *link, uint32_t conn_id, - uint8_t *data, unsigned int len); +int osmo_sccp_tx_data(struct osmo_sccp_user *scu, uint32_t conn_id, + const uint8_t *data, unsigned int len); -int osmo_sccp_tx_data_msg(struct osmo_sccp_link *link, uint32_t conn_id, +int osmo_sccp_tx_data_msg(struct osmo_sccp_user *scu, uint32_t conn_id, struct msgb *msg); +int osmo_sccp_tx_disconn(struct osmo_sccp_user *scu, uint32_t conn_id, + const struct osmo_sccp_addr *resp_addr, + uint32_t cause); + +int osmo_sccp_tx_conn_resp_msg(struct osmo_sccp_user *scu, uint32_t conn_id, + const struct osmo_sccp_addr *resp_addr, + struct msgb *msg); + +int osmo_sccp_tx_conn_resp(struct osmo_sccp_user *scu, uint32_t conn_id, + const struct osmo_sccp_addr *resp_addr, + const uint8_t *data, unsigned int len); + char *osmo_sccp_gt_dump(const struct osmo_sccp_gt *gt); char *osmo_sccp_addr_dump(const struct osmo_sccp_addr *addr); diff --git a/include/osmocom/sigtran/sua.h b/include/osmocom/sigtran/sua.h deleted file mode 100644 index 766b488..0000000 --- a/include/osmocom/sigtran/sua.h +++ /dev/null @@ -1,23 +0,0 @@ -#pragma once - -#include -#include - -struct osmo_sccp_user; -struct osmo_sccp_link; - -void osmo_sua_set_log_area(int area); - -struct osmo_sccp_user *osmo_sua_user_create(void *ctx, osmo_prim_cb prim_cb, - void *priv); -void osmo_sua_user_destroy(struct osmo_sccp_user *user); - -int osmo_sua_server_listen(struct osmo_sccp_user *user, const char *hostname, uint16_t port); - -int osmo_sua_client_connect(struct osmo_sccp_user *user, const char *hostname, uint16_t port); -struct osmo_sccp_link *osmo_sua_client_get_link(struct osmo_sccp_user *user); - -/* user hands us a SCCP-USER SAP primitive down into the stack */ -int osmo_sua_user_link_down(struct osmo_sccp_link *link, struct osmo_prim_hdr *oph); - -void *osmo_sccp_link_get_user_priv(struct osmo_sccp_link *slink); diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index 6d0b446..ab0636c 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -1197,7 +1197,9 @@ msgb_sctp_stream(msg) = ntohl(sinfo.sinfo_stream); msg->dst = asp; - if (ppid == M3UA_PPID && asp->cfg.proto == OSMO_SS7_ASP_PROT_M3UA) + if (ppid == SUA_PPID && asp->cfg.proto == OSMO_SS7_ASP_PROT_SUA) + rc = sua_rx_msg(asp, msg); + else if (ppid == M3UA_PPID && asp->cfg.proto == OSMO_SS7_ASP_PROT_M3UA) rc = m3ua_rx_msg(asp, msg); else { LOGPASP(asp, DLSS7, LOGL_NOTICE, "SCTP chunk for unknown PPID %u " @@ -1280,7 +1282,9 @@ msgb_sctp_stream(msg) = ntohl(sinfo.sinfo_stream); msg->dst = asp; - if (ppid == M3UA_PPID && asp->cfg.proto == OSMO_SS7_ASP_PROT_M3UA) + if (ppid == SUA_PPID && asp->cfg.proto == OSMO_SS7_ASP_PROT_SUA) + rc = sua_rx_msg(asp, msg); + else if (ppid == M3UA_PPID && asp->cfg.proto == OSMO_SS7_ASP_PROT_M3UA) rc = m3ua_rx_msg(asp, msg); else { LOGPASP(asp, DLSS7, LOGL_NOTICE, "SCTP chunk for unknown PPID %u " diff --git a/src/sccp_helpers.c b/src/sccp_helpers.c index 6264424..c588607 100644 --- a/src/sccp_helpers.c +++ b/src/sccp_helpers.c @@ -1,6 +1,6 @@ /* SCCP User SAP helper functions */ -/* (C) 2015 by Harald Welte +/* (C) 2015-2017 by Harald Welte * (C) 2016 by sysmocom s.m.f.c. GmbH * All Rights Reserved * @@ -27,8 +27,14 @@ #include #include -#include #include + +#include "sccp_internal.h" + +static struct msgb *scu_msgb_alloc(const char *name) +{ + return sccp_msgb_alloc("SCU"); +} void osmo_sccp_make_addr_pc_ssn(struct osmo_sccp_addr *addr, uint32_t pc, uint32_t ssn) { @@ -37,12 +43,12 @@ addr->pc = pc; } -int osmo_sccp_tx_unitdata(struct osmo_sccp_link *link, +int osmo_sccp_tx_unitdata(struct osmo_sccp_user *scu, const struct osmo_sccp_addr *calling_addr, const struct osmo_sccp_addr *called_addr, - uint8_t *data, unsigned int len) + const uint8_t *data, unsigned int len) { - struct msgb *msg = msgb_alloc(1024, "sccp_tx_unitdata"); + struct msgb *msg = scu_msgb_alloc(__func__); struct osmo_scu_prim *prim; struct osmo_scu_unitdata_param *param; @@ -55,13 +61,13 @@ msg->l2h = msgb_put(msg, len); memcpy(msg->l2h, data, len); - return osmo_sua_user_link_down(link, &prim->oph); + return osmo_sccp_user_sap_down(scu, &prim->oph); } -int osmo_sccp_tx_unitdata_ranap(struct osmo_sccp_link *link, +int osmo_sccp_tx_unitdata_ranap(struct osmo_sccp_user *scu, uint32_t src_point_code, uint32_t dst_point_code, - uint8_t *data, unsigned int len) + const uint8_t *data, unsigned int len) { struct osmo_sccp_addr calling_addr; struct osmo_sccp_addr called_addr; @@ -69,67 +75,70 @@ OSMO_SCCP_SSN_RANAP); osmo_sccp_make_addr_pc_ssn(&called_addr, dst_point_code, OSMO_SCCP_SSN_RANAP); - return osmo_sccp_tx_unitdata(link, &calling_addr, &called_addr, + return osmo_sccp_tx_unitdata(scu, &calling_addr, &called_addr, data, len); } -int osmo_sccp_tx_unitdata_msg(struct osmo_sccp_link *link, +int osmo_sccp_tx_unitdata_msg(struct osmo_sccp_user *scu, const struct osmo_sccp_addr *calling_addr, const struct osmo_sccp_addr *called_addr, struct msgb *msg) { int rc; - rc = osmo_sccp_tx_unitdata(link, calling_addr, called_addr, + rc = osmo_sccp_tx_unitdata(scu, calling_addr, called_addr, msg->data, msgb_length(msg)); msgb_free(msg); return rc; } -int osmo_sccp_tx_conn_req(struct osmo_sccp_link *link, uint32_t conn_id, +int osmo_sccp_tx_conn_req(struct osmo_sccp_user *scu, uint32_t conn_id, const struct osmo_sccp_addr *calling_addr, const struct osmo_sccp_addr *called_addr, - uint8_t *data, unsigned int len) + const uint8_t *data, unsigned int len) { - struct msgb *msg = msgb_alloc(1024, "sccp_tx_conn_req"); + struct msgb *msg = scu_msgb_alloc(__func__); struct osmo_scu_prim *prim; + struct osmo_scu_connect_param *param; prim = (struct osmo_scu_prim *) msgb_put(msg, sizeof(*prim)); osmo_prim_init(&prim->oph, SCCP_SAP_USER, OSMO_SCU_PRIM_N_CONNECT, PRIM_OP_REQUEST, msg); - osmo_sccp_make_addr_pc_ssn(&prim->u.connect.calling_addr, 1, - OSMO_SCCP_SSN_RANAP); - prim->u.connect.sccp_class = 2; - prim->u.connect.conn_id = conn_id; + param = &prim->u.connect; + if (calling_addr) + memcpy(¶m->calling_addr, calling_addr, sizeof(*calling_addr)); + memcpy(¶m->called_addr, called_addr, sizeof(*called_addr)); + param->sccp_class = 2; + param->conn_id = conn_id; if (data && len) { msg->l2h = msgb_put(msg, len); memcpy(msg->l2h, data, len); } - return osmo_sua_user_link_down(link, &prim->oph); + return osmo_sccp_user_sap_down(scu, &prim->oph); } -int osmo_sccp_tx_conn_req_msg(struct osmo_sccp_link *link, uint32_t conn_id, +int osmo_sccp_tx_conn_req_msg(struct osmo_sccp_user *scu, uint32_t conn_id, const struct osmo_sccp_addr *calling_addr, const struct osmo_sccp_addr *called_addr, struct msgb *msg) { int rc; - rc = osmo_sccp_tx_conn_req(link, conn_id, calling_addr, called_addr, + rc = osmo_sccp_tx_conn_req(scu, conn_id, calling_addr, called_addr, msg->data, msgb_length(msg)); msgb_free(msg); return rc; } -int osmo_sccp_tx_data(struct osmo_sccp_link *link, uint32_t conn_id, - uint8_t *data, unsigned int len) +int osmo_sccp_tx_data(struct osmo_sccp_user *scu, uint32_t conn_id, + const uint8_t *data, unsigned int len) { - struct msgb *msg = msgb_alloc(1024, "sccp_tx_data"); + struct msgb *msg = scu_msgb_alloc(__func__); struct osmo_scu_prim *prim; prim = (struct osmo_scu_prim *) msgb_put(msg, sizeof(*prim)); @@ -141,20 +150,79 @@ msg->l2h = msgb_put(msg, len); memcpy(msg->l2h, data, len); - return osmo_sua_user_link_down(link, &prim->oph); + return osmo_sccp_user_sap_down(scu, &prim->oph); } -int osmo_sccp_tx_data_msg(struct osmo_sccp_link *link, uint32_t conn_id, +int osmo_sccp_tx_data_msg(struct osmo_sccp_user *scu, uint32_t conn_id, struct msgb *msg) { int rc; - rc = osmo_sccp_tx_data(link, conn_id, msg->data, msgb_length(msg)); + rc = osmo_sccp_tx_data(scu, conn_id, msg->data, msgb_length(msg)); msgb_free(msg); return rc; } +/* N-DISCONNECT.req */ +int osmo_sccp_tx_disconn(struct osmo_sccp_user *scu, uint32_t conn_id, + const struct osmo_sccp_addr *resp_addr, + uint32_t cause) +{ + struct msgb *msg = scu_msgb_alloc(__func__); + struct osmo_scu_prim *prim; + struct osmo_scu_disconn_param *param; + + prim = (struct osmo_scu_prim *) msgb_put(msg, sizeof(*prim)); + osmo_prim_init(&prim->oph, SCCP_SAP_USER, + OSMO_SCU_PRIM_N_DISCONNECT, + PRIM_OP_REQUEST, msg); + param = &prim->u.disconnect; + memset(param, 0, sizeof(*param)); + param->originator = OSMO_SCCP_ORIG_NS_USER; + if (resp_addr) + memcpy(¶m->responding_addr, resp_addr, sizeof(*resp_addr)); + param->conn_id = conn_id; + param->cause = cause; + + return osmo_sccp_user_sap_down(scu, &prim->oph); +} + +/* N-CONNECT.resp */ +int osmo_sccp_tx_conn_resp_msg(struct osmo_sccp_user *scu, uint32_t conn_id, + const struct osmo_sccp_addr *resp_addr, + struct msgb *msg) +{ + struct osmo_scu_prim *prim; + struct osmo_scu_connect_param *param; + + msg->l2h = msg->data; + + prim = (struct osmo_scu_prim *) msgb_push(msg, sizeof(*prim)); + osmo_prim_init(&prim->oph, SCCP_SAP_USER, + OSMO_SCU_PRIM_N_CONNECT, + PRIM_OP_RESPONSE, msg); + param = &prim->u.connect; + param->conn_id = conn_id; + memcpy(¶m->responding_addr, resp_addr, sizeof(*resp_addr)); + param->sccp_class = 2; + + return osmo_sccp_user_sap_down(scu, &prim->oph); +} + +int osmo_sccp_tx_conn_resp(struct osmo_sccp_user *scu, uint32_t conn_id, + const struct osmo_sccp_addr *resp_addr, + const uint8_t *data, unsigned int len) +{ + struct msgb *msg = scu_msgb_alloc(__func__); + + if (data && len) { + msg->l2h = msgb_put(msg, len); + memcpy(msg->l2h, data, len); + } + return osmo_sccp_tx_conn_resp_msg(scu, conn_id, resp_addr, msg); +} + static void append_to_buf(char *buf, bool *comma, const char *fmt, ...) { va_list ap; diff --git a/src/sccp_scrc.c b/src/sccp_scrc.c index 9bccc0a..0ab25cb 100644 --- a/src/sccp_scrc.c +++ b/src/sccp_scrc.c @@ -139,6 +139,8 @@ if (rt->dest.as) { struct osmo_ss7_as *as = rt->dest.as; switch (as->cfg.proto) { + case OSMO_SS7_ASP_PROT_SUA: + return sua_tx_xua_as(as, xua); case OSMO_SS7_ASP_PROT_M3UA: return sua2sccp_tx_m3ua(inst, xua); default: diff --git a/src/sua.c b/src/sua.c index b8bb2f5..836e02e 100644 --- a/src/sua.c +++ b/src/sua.c @@ -29,17 +29,20 @@ #include #include #include +#include #include #include #include +#include #include -#include +#include +#include +#include "xua_asp_fsm.h" #include "xua_internal.h" - -#define SUA_MSGB_SIZE 1500 +#include "sccp_internal.h" /* Appendix C.4 of Q.714 (all in milliseconds) */ #define CONNECTION_TIMER ( 1 * 60 * 100) @@ -205,6 +208,7 @@ .name = "SUA", .ppid = SUA_PPID, .port = SUA_PORT, + .log_subsys = DLSUA, .class = { [SUA_MSGC_MGMT] = &m3ua_msg_class_mgmt, [SUA_MSGC_SNM] = &m3ua_msg_class_snm, @@ -216,480 +220,81 @@ }, }; - -static int DSUA = -1; - -struct osmo_sccp_user { - /* global list of SUA users? */ - struct llist_head list; - /* set if we are a server */ - struct osmo_stream_srv_link *server; - struct osmo_stream_cli *client; - struct llist_head links; - /* user call-back function in case of incoming primitives */ - osmo_prim_cb prim_cb; - void *priv; -}; - -struct osmo_sccp_link { - /* list of SUA links per sua_user */ - struct llist_head list; - /* sua user to which we belong */ - struct osmo_sccp_user *user; - /* local list of (SCCP) connections in this link */ - struct llist_head connections; - /* next connection local reference */ - uint32_t next_id; - int is_server; - void *data; -}; - -enum sua_connection_state { - S_IDLE, - S_CONN_PEND_IN, - S_CONN_PEND_OUT, - S_ACTIVE, - S_DISCONN_PEND, - S_RESET_IN, - S_RESET_OUT, - S_BOTHWAY_RESET, - S_WAIT_CONN_CONF, -}; - -static const struct value_string conn_state_names[] = { - { S_IDLE, "IDLE" }, - { S_CONN_PEND_IN, "CONN_PEND_IN" }, - { S_CONN_PEND_OUT, "CONN_PEND_OUT" }, - { S_ACTIVE, "ACTIVE" }, - { S_DISCONN_PEND, "DISCONN_PEND" }, - { S_RESET_IN, "RESET_IN" }, - { S_RESET_OUT, "RESET_OUT" }, - { S_BOTHWAY_RESET, "BOTHWAY_RESET" }, - { S_WAIT_CONN_CONF, "WAIT_CONN_CONF" }, - { 0, NULL } -}; - -struct sua_connection { - struct llist_head list; - struct osmo_sccp_link *link; - struct osmo_sccp_addr calling_addr; - struct osmo_sccp_addr called_addr; - uint32_t conn_id; - uint32_t remote_ref; - enum sua_connection_state state; - struct osmo_timer_list timer; - /* inactivity timers */ - struct osmo_timer_list tias; - struct osmo_timer_list tiar; -}; - - /*********************************************************************** - * SUA Link and Connection handling + * ERROR generation ***********************************************************************/ -static struct osmo_sccp_link *sua_link_new(struct osmo_sccp_user *user, int is_server) +static struct xua_msg *sua_gen_error(uint32_t err_code) { - struct osmo_sccp_link *link; + struct xua_msg *xua = xua_msg_alloc(); - link = talloc_zero(user, struct osmo_sccp_link); - if (!link) - return NULL; + xua->hdr = XUA_HDR(SUA_MSGC_MGMT, SUA_MGMT_ERR); + xua->hdr.version = SUA_VERSION; + xua_msg_add_u32(xua, SUA_IEI_ERR_CODE, err_code); - link->user = user; - link->is_server = is_server; - INIT_LLIST_HEAD(&link->connections); - - llist_add_tail(&link->list, &user->links); - - return link; + return xua; } -static void conn_destroy(struct sua_connection *conn); - -static void sua_link_destroy(struct osmo_sccp_link *link) +static struct xua_msg *sua_gen_error_msg(uint32_t err_code, struct msgb *msg) { - struct sua_connection *conn; + struct xua_msg *xua = sua_gen_error(err_code); + unsigned int len_max_40 = msgb_length(msg); - llist_for_each_entry(conn, &link->connections, list) - conn_destroy(conn); + if (len_max_40 > 40) + len_max_40 = 40; - llist_del(&link->list); + xua_msg_add_data(xua, SUA_IEI_DIAG_INFO, len_max_40, msgb_data(msg)); - /* FIXME: do we need to cleanup the sccp link? */ - - talloc_free(link); + return xua; } -static int sua_link_send(struct osmo_sccp_link *link, struct msgb *msg) +/*********************************************************************** + * Transmitting SUA messsages to SCTP + ***********************************************************************/ + +static int sua_tx_xua_asp(struct osmo_ss7_asp *asp, struct xua_msg *xua) { + struct msgb *msg = xua_to_msg(SUA_VERSION, xua); + + OSMO_ASSERT(asp->cfg.proto == OSMO_SS7_ASP_PROT_SUA); + + xua_msg_free(xua); + + if (!msg) { + LOGPASP(asp, DLSUA, LOGL_ERROR, "Error encoding SUA Msg\n"); + return -1; + } + msgb_sctp_ppid(msg) = SUA_PPID; - - DEBUGP(DSUA, "sua_link_send(%s)\n", osmo_hexdump(msg->data, msgb_length(msg))); - - if (link->is_server) - osmo_stream_srv_send(link->data, msg); - else - osmo_stream_cli_send(link->data, msg); - - return 0; + return osmo_ss7_asp_send(asp, msg); } -static struct sua_connection *conn_find_by_id(struct osmo_sccp_link *link, uint32_t id) +/*! \brief Send a given xUA message via a given SUA Application Server + * \param[in] as Application Server through which to send \ref xua + * \param[in] xua xUA message to be sent + * \return 0 on success; negative on error */ +int sua_tx_xua_as(struct osmo_ss7_as *as, struct xua_msg *xua) { - struct sua_connection *conn; + struct osmo_ss7_asp *asp; + unsigned int i; - llist_for_each_entry(conn, &link->connections, list) { - if (conn->conn_id == id) - return conn; + OSMO_ASSERT(as->cfg.proto == OSMO_SS7_ASP_PROT_SUA); + + /* FIXME: Select ASP within AS depending on traffic mode */ + for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) { + asp = as->cfg.asps[i]; + if (!asp) + continue; + if (asp) + break; } - return NULL; -} - -static void tx_inact_tmr_cb(void *data) -{ - struct sua_connection *conn = data; - struct xua_msg *xua = xua_msg_alloc(); - struct msgb *outmsg; - - /* encode + send the CLDT */ - xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_COIT); - xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, 0); /* FIXME */ - xua_msg_add_u32(xua, SUA_IEI_PROTO_CLASS, 2); - xua_msg_add_u32(xua, SUA_IEI_SRC_REF, conn->conn_id); - xua_msg_add_u32(xua, SUA_IEI_DEST_REF, conn->remote_ref); - /* optional: sequence number; credit (both class 3 only) */ - - outmsg = xua_to_msg(1, xua); - xua_msg_free(xua); - - sua_link_send(conn->link, outmsg); -} - -static void rx_inact_tmr_cb(void *data) -{ - struct sua_connection *conn = data; - - /* FIXME: release connection */ - /* Send N-DISCONNECT.ind to local user */ - /* Send RLSD to peer */ - /* enter disconnect pending state with release timer pending */ -} - - -static struct sua_connection *conn_create_id(struct osmo_sccp_link *link, uint32_t conn_id) -{ - struct sua_connection *conn = talloc_zero(link, struct sua_connection); - - conn->conn_id = conn_id; - conn->link = link; - conn->state = S_IDLE; - - llist_add_tail(&conn->list, &link->connections); - - conn->tias.cb = tx_inact_tmr_cb; - conn->tias.data = conn; - conn->tiar.cb = rx_inact_tmr_cb; - conn->tiar.data = conn; - - return conn; -} - -static struct sua_connection *conn_create(struct osmo_sccp_link *link) -{ - uint32_t conn_id; - - do { - conn_id = link->next_id++; - } while (conn_find_by_id(link, conn_id)); - - return conn_create_id(link, conn_id); -} - -static void conn_destroy(struct sua_connection *conn) -{ - /* FIXME: do some cleanup; inform user? */ - osmo_timer_del(&conn->tias); - osmo_timer_del(&conn->tiar); - llist_del(&conn->list); - talloc_free(conn); -} - -static void conn_state_set(struct sua_connection *conn, - enum sua_connection_state state) -{ - DEBUGP(DSUA, "(%u) state chg %s->", conn->conn_id, - get_value_string(conn_state_names, conn->state)); - DEBUGPC(DSUA, "%s\n", - get_value_string(conn_state_names, state)); - conn->state = state; -} - -static void conn_restart_tx_inact_timer(struct sua_connection *conn) -{ - osmo_timer_schedule(&conn->tias, TX_INACT_TIMER / 100, - (TX_INACT_TIMER % 100) * 10); -} - -static void conn_restart_rx_inact_timer(struct sua_connection *conn) -{ - osmo_timer_schedule(&conn->tiar, RX_INACT_TIMER / 100, - (RX_INACT_TIMER % 100) * 10); -} - -static void conn_start_inact_timers(struct sua_connection *conn) -{ - conn_restart_tx_inact_timer(conn); - conn_restart_rx_inact_timer(conn); -} - -/*********************************************************************** - * Handling of messages from the User SAP - ***********************************************************************/ - -/* user program sends us a N-CONNNECT.req to initiate a new connection */ -static int sua_connect_req(struct osmo_sccp_link *link, struct osmo_scu_prim *prim) -{ - struct osmo_scu_connect_param *par = &prim->u.connect; - struct xua_msg *xua = xua_msg_alloc(); - struct sua_connection *conn; - struct msgb *outmsg; - - if (par->sccp_class != 2) { - LOGP(DSUA, LOGL_ERROR, "N-CONNECT.req for unsupported " - "SCCP class %u\n", par->sccp_class); - /* FIXME: Send primitive to user */ - return -EINVAL; - } - - conn = conn_create_id(link, par->conn_id); - if (!conn) { - /* FIXME: Send primitive to user */ - return -EINVAL; - } - - memcpy(&conn->called_addr, &par->called_addr, - sizeof(conn->called_addr)); - memcpy(&conn->calling_addr, &par->calling_addr, - sizeof(conn->calling_addr)); - - /* encode + send the CLDT */ - xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_CORE); - xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, 0); /* FIXME */ - xua_msg_add_u32(xua, SUA_IEI_PROTO_CLASS, par->sccp_class); - xua_msg_add_u32(xua, SUA_IEI_SRC_REF, conn->conn_id); - xua_msg_add_sccp_addr(xua, SUA_IEI_DEST_ADDR, &par->called_addr); - xua_msg_add_u32(xua, SUA_IEI_SEQ_CTRL, 0); /* FIXME */ - /* sequence number */ - if (par->calling_addr.presence) - xua_msg_add_sccp_addr(xua, SUA_IEI_SRC_ADDR, &par->calling_addr); - /* optional: hop count; importance; priority; credit */ - if (msgb_l2(prim->oph.msg)) - xua_msg_add_data(xua, SUA_IEI_DATA, msgb_l2len(prim->oph.msg), - msgb_l2(prim->oph.msg)); - - outmsg = xua_to_msg(1, xua); - xua_msg_free(xua); - - /* FIXME: Start CONNECTION_TIMER */ - conn_state_set(conn, S_CONN_PEND_OUT); - - return sua_link_send(link, outmsg); -} - -/* user program sends us a N-CONNNECT.resp, presumably against a - * N-CONNECT.ind */ -static int sua_connect_resp(struct osmo_sccp_link *link, struct osmo_scu_prim *prim) -{ - struct osmo_scu_connect_param *par = &prim->u.connect; - struct xua_msg *xua = xua_msg_alloc(); - struct sua_connection *conn; - struct msgb *outmsg; - - /* check if we already know a connection for this conn_id */ - conn = conn_find_by_id(link, par->conn_id); - if (!conn) { - LOGP(DSUA, LOGL_ERROR, "N-CONNECT.resp for unknown " - "connection ID %u\n", par->conn_id); - /* FIXME: Send primitive to user */ + if (!asp) { + LOGP(DLSUA, LOGL_ERROR, "No ASP in AS, dropping message\n"); + xua_msg_free(xua); return -ENODEV; } - if (conn->state != S_CONN_PEND_IN) { - LOGP(DSUA, LOGL_ERROR, "N-CONNECT.resp in wrong state %s\n", - get_value_string(conn_state_names, conn->state)); - /* FIXME: Send primitive to user */ - return -EINVAL; - } - - /* encode + send the COAK message */ - xua = xua_msg_alloc(); - xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_COAK); - xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, 0); /* FIXME */ - xua_msg_add_u32(xua, SUA_IEI_PROTO_CLASS, par->sccp_class); - xua_msg_add_u32(xua, SUA_IEI_DEST_REF, conn->remote_ref); - xua_msg_add_u32(xua, SUA_IEI_SRC_REF, conn->conn_id); - xua_msg_add_u32(xua, SUA_IEI_SEQ_CTRL, 0); /* FIXME */ - /* sequence number */ - if (par->calling_addr.presence) - xua_msg_add_sccp_addr(xua, SUA_IEI_SRC_ADDR, &par->calling_addr); - /* optional: hop count; importance; priority */ - /* FIXME: destination address will be present in case the CORE - * message conveys the source address parameter */ - if (par->called_addr.presence) - xua_msg_add_sccp_addr(xua, SUA_IEI_DEST_ADDR, &par->called_addr); - if (msgb_l2(prim->oph.msg)) - xua_msg_add_data(xua, SUA_IEI_DATA, msgb_l2len(prim->oph.msg), - msgb_l2(prim->oph.msg)); - - outmsg = xua_to_msg(1, xua); - xua_msg_free(xua); - - conn_state_set(conn, S_ACTIVE); - conn_start_inact_timers(conn); - - return sua_link_send(link, outmsg); -} - -/* user wants to send connection-oriented data */ -static int sua_data_req(struct osmo_sccp_link *link, struct osmo_scu_prim *prim) -{ - struct osmo_scu_data_param *par = &prim->u.data; - struct xua_msg *xua; - struct sua_connection *conn; - struct msgb *outmsg; - - /* check if we know about this conncetion, and obtain reference */ - conn = conn_find_by_id(link, par->conn_id); - if (!conn) { - LOGP(DSUA, LOGL_ERROR, "N-DATA.req for unknown " - "connection ID %u\n", par->conn_id); - /* FIXME: Send primitive to user */ - return -ENODEV; - } - - if (conn->state != S_ACTIVE) { - LOGP(DSUA, LOGL_ERROR, "N-DATA.req in wrong state %s\n", - get_value_string(conn_state_names, conn->state)); - /* FIXME: Send primitive to user */ - return -EINVAL; - } - - conn_restart_tx_inact_timer(conn); - - /* encode + send the CODT message */ - xua = xua_msg_alloc(); - xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_CODT); - xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, 0); /* FIXME */ - /* Sequence number only in expedited data */ - xua_msg_add_u32(xua, SUA_IEI_DEST_REF, conn->remote_ref); - /* optional: priority; correlation id */ - xua_msg_add_data(xua, SUA_IEI_DATA, msgb_l2len(prim->oph.msg), - msgb_l2(prim->oph.msg)); - - outmsg = xua_to_msg(1, xua); - xua_msg_free(xua); - - return sua_link_send(link, outmsg); -} - -/* user wants to disconnect a connection */ -static int sua_disconnect_req(struct osmo_sccp_link *link, struct osmo_scu_prim *prim) -{ - struct osmo_scu_disconn_param *par = &prim->u.disconnect; - struct xua_msg *xua; - struct sua_connection *conn; - struct msgb *outmsg; - - /* resolve reference of connection */ - conn = conn_find_by_id(link, par->conn_id); - if (!conn) { - LOGP(DSUA, LOGL_ERROR, "N-DISCONNECT.req for unknown " - "connection ID %u\n", par->conn_id); - /* FIXME: Send primitive to user */ - return -ENODEV; - } - - /* encode + send the RELRE */ - xua = xua_msg_alloc(); - xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_RELRE); - xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, 0); /* FIXME */ - xua_msg_add_u32(xua, SUA_IEI_DEST_REF, conn->remote_ref); - xua_msg_add_u32(xua, SUA_IEI_SRC_REF, conn->conn_id); - xua_msg_add_u32(xua, SUA_IEI_CAUSE, par->cause); - /* optional: importance */ - if (msgb_l2(prim->oph.msg)) - xua_msg_add_data(xua, SUA_IEI_DATA, msgb_l2len(prim->oph.msg), - msgb_l2(prim->oph.msg)); - - outmsg = xua_to_msg(1, xua); - xua_msg_free(xua); - - conn_state_set(conn, S_DISCONN_PEND); - conn_destroy(conn); - - LOGP(DSUA, LOGL_NOTICE, "About to send the SUA RELRE\n"); - return sua_link_send(link, outmsg); -} - -/* user wants to send connectionless data */ -static int sua_unitdata_req(struct osmo_sccp_link *link, struct osmo_scu_prim *prim) -{ - struct osmo_scu_unitdata_param *par = &prim->u.unitdata; - struct xua_msg *xua = xua_msg_alloc(); - struct msgb *outmsg; - - /* encode + send the CLDT */ - xua->hdr = XUA_HDR(SUA_MSGC_CL, SUA_CL_CLDT); - xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, 0); /* FIXME */ - xua_msg_add_u32(xua, SUA_IEI_PROTO_CLASS, 0); - xua_msg_add_sccp_addr(xua, SUA_IEI_SRC_ADDR, &par->calling_addr); - xua_msg_add_sccp_addr(xua, SUA_IEI_DEST_ADDR, &par->called_addr); - xua_msg_add_u32(xua, SUA_IEI_SEQ_CTRL, par->in_sequence_control); - /* optional: importance, ... correlation id? */ - xua_msg_add_data(xua, SUA_IEI_DATA, msgb_l2len(prim->oph.msg), - msgb_l2(prim->oph.msg)); - - outmsg = xua_to_msg(1, xua); - xua_msg_free(xua); - - return sua_link_send(link, outmsg); -} - -/* user hands us a SCCP-USER SAP primitive down into the stack */ -int osmo_sua_user_link_down(struct osmo_sccp_link *link, struct osmo_prim_hdr *oph) -{ - struct osmo_scu_prim *prim = (struct osmo_scu_prim *) oph; - struct msgb *msg = prim->oph.msg; - int rc = 0; - - LOGP(DSUA, LOGL_DEBUG, "Received SCCP User Primitive (%s)\n", - osmo_scu_prim_name(&prim->oph)); - - switch (OSMO_PRIM_HDR(&prim->oph)) { - case OSMO_PRIM(OSMO_SCU_PRIM_N_CONNECT, PRIM_OP_REQUEST): - rc = sua_connect_req(link, prim); - break; - case OSMO_PRIM(OSMO_SCU_PRIM_N_CONNECT, PRIM_OP_RESPONSE): - rc = sua_connect_resp(link, prim); - break; - case OSMO_PRIM(OSMO_SCU_PRIM_N_DATA, PRIM_OP_REQUEST): - rc = sua_data_req(link, prim); - break; - case OSMO_PRIM(OSMO_SCU_PRIM_N_DISCONNECT, PRIM_OP_REQUEST): - rc = sua_disconnect_req(link, prim); - break; - case OSMO_PRIM(OSMO_SCU_PRIM_N_UNITDATA, PRIM_OP_REQUEST): - rc = sua_unitdata_req(link, prim); - break; - default: - rc = -1; - } - - if (rc != 1) - msgb_free(msg); - - return rc; + return sua_tx_xua_asp(asp, xua); } /*********************************************************************** @@ -750,12 +355,12 @@ memset(out, 0, sizeof(*out)); - LOGP(DSUA, LOGL_DEBUG, "%s(IEI=0x%04x) (%d) %s\n", __func__, + LOGP(DLSUA, LOGL_DEBUG, "%s(IEI=0x%04x) (%d) %s\n", __func__, param->tag, param->len, osmo_hexdump(param->dat, param->len)); if (param->len < 4) { - LOGP(DSUA, LOGL_ERROR, "SUA IEI 0x%04x: invalid address length: %d\n", + LOGP(DLSUA, LOGL_ERROR, "SUA IEI 0x%04x: invalid address length: %d\n", param->tag, param->len); return -EINVAL; } @@ -778,14 +383,14 @@ break; case SUA_RI_HOST: default: - LOGP(DSUA, LOGL_ERROR, "SUA IEI 0x%04x: Routing Indicator not supported yet: %d\n", + LOGP(DLSUA, LOGL_ERROR, "SUA IEI 0x%04x: Routing Indicator not supported yet: %d\n", param->tag, ri); return -ENOTSUP; } if (ai != 7) { #if 0 - LOGP(DSUA, LOGL_ERROR, "SUA IEI 0x%04x: Address Indicator not supported yet: %x\n", + LOGP(DLSUA, LOGL_ERROR, "SUA IEI 0x%04x: Address Indicator not supported yet: %x\n", param->tag, ai); return -ENOTSUP; #endif @@ -805,7 +410,7 @@ par_len = ntohs(par->len); par_datalen = par_len - sizeof(*par); - LOGP(DSUA, LOGL_DEBUG, "SUA IEI 0x%04x pos %hu/%hu: subpart tag 0x%04x, len %hu\n", + LOGP(DLSUA, LOGL_DEBUG, "SUA IEI 0x%04x pos %hu/%hu: subpart tag 0x%04x, len %hu\n", param->tag, pos, param->len, par_tag, par_len); switch (par_tag) { @@ -838,7 +443,7 @@ out->presence |= OSMO_SCCP_ADDR_T_IPv4; break; default: - LOGP(DSUA, LOGL_ERROR, "SUA IEI 0x%04x: Unknown subpart tag %hd\n", + LOGP(DLSUA, LOGL_ERROR, "SUA IEI 0x%04x: Unknown subpart tag %hd\n", param->tag, par_tag); goto subpar_fail; } @@ -849,7 +454,7 @@ return 0; subpar_fail: - LOGP(DSUA, LOGL_ERROR, "Failed to parse subparts of address IEI=0x%04x\n", + LOGP(DLSUA, LOGL_ERROR, "Failed to parse subparts of address IEI=0x%04x\n", param->tag); return -EINVAL; } @@ -870,809 +475,205 @@ return sua_addr_parse_part(out, param); } -static int sua_rx_cldt(struct osmo_sccp_link *link, struct xua_msg *xua) +/* connectionless messages received from socket */ +static int sua_rx_cl(struct osmo_ss7_asp *asp, struct xua_msg *xua) { - struct osmo_scu_prim *prim; - struct osmo_scu_unitdata_param *param; - struct xua_msg_part *data_ie = xua_msg_find_tag(xua, SUA_IEI_DATA); - struct msgb *upmsg = sccp_msgb_alloc(__func__); - uint32_t protocol_class; + struct osmo_sccp_instance *inst = asp->inst->sccp; - /* fill primitive */ - prim = (struct osmo_scu_prim *) msgb_put(upmsg, sizeof(*prim)); - param = &prim->u.unitdata; - osmo_prim_init(&prim->oph, SCCP_SAP_USER, - OSMO_SCU_PRIM_N_UNITDATA, - PRIM_OP_INDICATION, upmsg); - sua_addr_parse(¶m->called_addr, xua, SUA_IEI_DEST_ADDR); - sua_addr_parse(¶m->calling_addr, xua, SUA_IEI_SRC_ADDR); - param->in_sequence_control = xua_msg_get_u32(xua, SUA_IEI_SEQ_CTRL); - protocol_class = xua_msg_get_u32(xua, SUA_IEI_PROTO_CLASS); - param->return_option = protocol_class & 0x80; - param->importance = xua_msg_get_u32(xua, SUA_IEI_IMPORTANCE); - - /* copy data */ - upmsg->l2h = msgb_put(upmsg, data_ie->len); - memcpy(upmsg->l2h, data_ie->dat, data_ie->len); - - /* send to user SAP */ - link->user->prim_cb(&prim->oph, link); - - return 0; + /* We feed into SCRC, which then hands the message into + * either SCLC or SCOC, or forwards it to MTP */ + return scrc_rx_mtp_xfer_ind_xua(inst, xua); } - - -/* connectioness messages received from socket */ -static int sua_rx_cl(struct osmo_sccp_link *link, - struct xua_msg *xua, struct msgb *msg) -{ - int rc = -1; - - switch (xua->hdr.msg_type) { - case SUA_CL_CLDT: - rc = sua_rx_cldt(link, xua); - break; - case SUA_CL_CLDR: - default: - break; - } - - return rc; -} - -/* RFC 3868 3.3.3 / SCCP CR (Connection Request) */ -static int sua_rx_core(struct osmo_sccp_link *link, struct xua_msg *xua) -{ - struct osmo_scu_prim *prim; - struct osmo_scu_connect_param *param; - struct xua_msg_part *data_ie = xua_msg_find_tag(xua, SUA_IEI_DATA); - struct msgb *upmsg; - struct sua_connection *conn; - - /* fill conn */ - conn = conn_create(link); - sua_addr_parse(&conn->called_addr, xua, SUA_IEI_DEST_ADDR); - sua_addr_parse(&conn->calling_addr, xua, SUA_IEI_SRC_ADDR); - conn->remote_ref = xua_msg_get_u32(xua, SUA_IEI_SRC_REF); - - /* fill primitive */ - upmsg = sccp_msgb_alloc(__func__); - prim = (struct osmo_scu_prim *) msgb_put(upmsg, sizeof(*prim)); - param = &prim->u.connect; - osmo_prim_init(&prim->oph, SCCP_SAP_USER, - OSMO_SCU_PRIM_N_CONNECT, - PRIM_OP_INDICATION, upmsg); - param->conn_id = conn->conn_id; - memcpy(¶m->called_addr, &conn->called_addr, - sizeof(param->called_addr)); - memcpy(¶m->calling_addr, &conn->calling_addr, - sizeof(param->calling_addr)); - //param->in_sequence_control; - param->sccp_class = xua_msg_get_u32(xua, SUA_IEI_PROTO_CLASS) & 3; - param->importance = xua_msg_get_u32(xua, SUA_IEI_IMPORTANCE); - - if (data_ie) { - /* copy data */ - upmsg->l2h = msgb_put(upmsg, data_ie->len); - memcpy(upmsg->l2h, data_ie->dat, data_ie->len); - } - - conn_state_set(conn, S_CONN_PEND_IN); - - /* send to user SAP */ - link->user->prim_cb(&prim->oph, link); - - return 0; -} - -/* RFC 3868 3.3.4 / SCCP CC (Connection Confirm) */ -static int sua_rx_coak(struct osmo_sccp_link *link, struct xua_msg *xua) -{ - struct osmo_scu_prim *prim; - struct sua_connection *conn; - struct osmo_scu_connect_param *param; - struct xua_msg_part *data_ie = xua_msg_find_tag(xua, SUA_IEI_DATA); - struct msgb *upmsg; - uint32_t conn_id = xua_msg_get_u32(xua, SUA_IEI_DEST_REF); - - /* resolve conn */ - conn = conn_find_by_id(link, conn_id); - if (!conn) { - LOGP(DSUA, LOGL_ERROR, "COAK for unknown reference %u\n", - conn_id); - /* FIXME: send error reply down the sua link? */ - return -1; - } - conn_restart_rx_inact_timer(conn); - - if (conn->state != S_CONN_PEND_OUT) { - LOGP(DSUA, LOGL_ERROR, "COAK in wrong state %s\n", - get_value_string(conn_state_names, conn->state)); - /* FIXME: send error reply down the sua link? */ - return -EINVAL; - } - - /* track remote reference */ - conn->remote_ref = xua_msg_get_u32(xua, SUA_IEI_SRC_REF); - - /* fill primitive */ - upmsg = sccp_msgb_alloc(__func__); - prim = (struct osmo_scu_prim *) msgb_put(upmsg, sizeof(*prim)); - param = &prim->u.connect; - osmo_prim_init(&prim->oph, SCCP_SAP_USER, - OSMO_SCU_PRIM_N_CONNECT, - PRIM_OP_CONFIRM, upmsg); - param->conn_id = conn->conn_id; - memcpy(¶m->called_addr, &conn->called_addr, - sizeof(param->called_addr)); - memcpy(¶m->calling_addr, &conn->calling_addr, - sizeof(param->calling_addr)); - //param->in_sequence_control; - param->sccp_class = xua_msg_get_u32(xua, SUA_IEI_PROTO_CLASS) & 3; - param->importance = xua_msg_get_u32(xua, SUA_IEI_IMPORTANCE); - - if (data_ie) { - /* copy data */ - upmsg->l2h = msgb_put(upmsg, data_ie->len); - memcpy(upmsg->l2h, data_ie->dat, data_ie->len); - } - - conn_state_set(conn, S_ACTIVE); - conn_start_inact_timers(conn); - - /* send to user SAP */ - link->user->prim_cb(&prim->oph, link); - - return 0; -} - -/* RFC 3868 3.3.5 / SCCP CREF (Connection Refused) */ -static int sua_rx_coref(struct osmo_sccp_link *link, struct xua_msg *xua) -{ - struct osmo_scu_prim *prim; - struct sua_connection *conn; - struct osmo_scu_disconn_param *param; - struct xua_msg_part *data_ie = xua_msg_find_tag(xua, SUA_IEI_DATA); - struct msgb *upmsg; - uint32_t conn_id = xua_msg_get_u32(xua, SUA_IEI_DEST_REF); - uint32_t cause; - - /* resolve conn */ - conn = conn_find_by_id(link, conn_id); - if (!conn) { - LOGP(DSUA, LOGL_ERROR, "COREF for unknown reference %u\n", - conn_id); - /* FIXME: send error reply down the sua link? */ - return -1; - } - conn_restart_rx_inact_timer(conn); - - /* fill primitive */ - upmsg = sccp_msgb_alloc(__func__); - prim = (struct osmo_scu_prim *) msgb_put(upmsg, sizeof(*prim)); - param = &prim->u.disconnect; - osmo_prim_init(&prim->oph, SCCP_SAP_USER, - OSMO_SCU_PRIM_N_DISCONNECT, - PRIM_OP_INDICATION, upmsg); - param->conn_id = conn_id; - param->responding_addr = conn->called_addr; - param->originator = OSMO_SCCP_ORIG_UNDEFINED; - //param->in_sequence_control; - /* TODO evaluate cause: - * cause = xua_msg_get_u32(xua, SUA_IEI_CAUSE); */ - /* optional: src addr */ - /* optional: dest addr */ - param->importance = xua_msg_get_u32(xua, SUA_IEI_IMPORTANCE); - if (data_ie) { - /* copy data */ - upmsg->l2h = msgb_put(upmsg, data_ie->len); - memcpy(upmsg->l2h, data_ie->dat, data_ie->len); - } - - /* send to user SAP */ - link->user->prim_cb(&prim->oph, link); - - conn_state_set(conn, S_IDLE); - conn_destroy(conn); - - return 0; -} - -/* RFC 3868 3.3.6 / SCCP RLSD (Released) */ -static int sua_rx_relre(struct osmo_sccp_link *link, struct xua_msg *xua) -{ - struct osmo_scu_prim *prim; - struct sua_connection *conn; - struct osmo_scu_disconn_param *param; - struct xua_msg_part *data_ie = xua_msg_find_tag(xua, SUA_IEI_DATA); - struct msgb *upmsg; - uint32_t conn_id = xua_msg_get_u32(xua, SUA_IEI_DEST_REF); - uint32_t cause; - - /* resolve conn */ - conn = conn_find_by_id(link, conn_id); - if (!conn) { - LOGP(DSUA, LOGL_ERROR, "RELRE for unknown reference %u\n", - conn_id); - /* FIXME: send error reply down the sua link? */ - return -1; - } - - /* fill primitive */ - upmsg = sccp_msgb_alloc(__func__); - prim = (struct osmo_scu_prim *) msgb_put(upmsg, sizeof(*prim)); - param = &prim->u.disconnect; - osmo_prim_init(&prim->oph, SCCP_SAP_USER, - OSMO_SCU_PRIM_N_DISCONNECT, - PRIM_OP_INDICATION, upmsg); /* what primitive? */ - - param->conn_id = conn_id; - /* source reference */ - cause = xua_msg_get_u32(xua, SUA_IEI_CAUSE); - param->importance = xua_msg_get_u32(xua, SUA_IEI_IMPORTANCE); - if (data_ie) { - /* copy data */ - upmsg->l2h = msgb_put(upmsg, data_ie->len); - memcpy(upmsg->l2h, data_ie->dat, data_ie->len); - } - - param->responding_addr = conn->called_addr; - param->originator = OSMO_SCCP_ORIG_UNDEFINED; - - /* send to user SAP */ - link->user->prim_cb(&prim->oph, link); - - conn_state_set(conn, S_IDLE); - conn_destroy(conn); - - return 0; -} - -/* RFC 3868 3.3.7 / SCCP RLC (Release Complete)*/ -static int sua_rx_relco(struct osmo_sccp_link *link, struct xua_msg *xua) -{ - struct osmo_scu_prim *prim; - struct sua_connection *conn; - struct osmo_scu_disconn_param *param; - struct msgb *upmsg; - uint32_t conn_id = xua_msg_get_u32(xua, SUA_IEI_DEST_REF); - - /* resolve conn */ - conn = conn_find_by_id(link, conn_id); - if (!conn) { - LOGP(DSUA, LOGL_ERROR, "RELCO for unknown reference %u\n", - conn_id); - /* FIXME: send error reply down the sua link? */ - return -1; - } - conn_restart_rx_inact_timer(conn); - - /* fill primitive */ - upmsg = sccp_msgb_alloc(__func__); - prim = (struct osmo_scu_prim *) msgb_put(upmsg, sizeof(*prim)); - param = &prim->u.disconnect; - osmo_prim_init(&prim->oph, SCCP_SAP_USER, - OSMO_SCU_PRIM_N_DISCONNECT, - PRIM_OP_CONFIRM, upmsg); /* what primitive? */ - - param->conn_id = conn_id; - /* source reference */ - param->importance = xua_msg_get_u32(xua, SUA_IEI_IMPORTANCE); - - param->responding_addr = conn->called_addr; - param->originator = OSMO_SCCP_ORIG_UNDEFINED; - - /* send to user SAP */ - link->user->prim_cb(&prim->oph, link); - - conn_destroy(conn); - - return 0; - -} - -/* RFC3868 3.3.1 / SCCP DT1 (Data Form 1) */ -static int sua_rx_codt(struct osmo_sccp_link *link, struct xua_msg *xua) -{ - struct osmo_scu_prim *prim; - struct sua_connection *conn; - struct osmo_scu_data_param *param; - struct xua_msg_part *data_ie = xua_msg_find_tag(xua, SUA_IEI_DATA); - struct msgb *upmsg; - uint32_t conn_id = xua_msg_get_u32(xua, SUA_IEI_DEST_REF); - - /* resolve conn */ - conn = conn_find_by_id(link, conn_id); - if (!conn) { - LOGP(DSUA, LOGL_ERROR, "DT1 for unknown reference %u\n", - conn_id); - /* FIXME: send error reply down the sua link? */ - return -1; - } - - if (conn->state != S_ACTIVE) { - LOGP(DSUA, LOGL_ERROR, "DT1 in invalid state %s\n", - get_value_string(conn_state_names, conn->state)); - /* FIXME: send error reply down the sua link? */ - return -1; - } - - conn_restart_rx_inact_timer(conn); - - /* fill primitive */ - upmsg = sccp_msgb_alloc(__func__); - prim = (struct osmo_scu_prim *) msgb_put(upmsg, sizeof(*prim)); - param = &prim->u.data; - osmo_prim_init(&prim->oph, SCCP_SAP_USER, - OSMO_SCU_PRIM_N_DATA, - PRIM_OP_INDICATION, upmsg); - param->conn_id = conn_id; - param->importance = xua_msg_get_u32(xua, SUA_IEI_IMPORTANCE); - - /* copy data */ - upmsg->l2h = msgb_put(upmsg, data_ie->len); - memcpy(upmsg->l2h, data_ie->dat, data_ie->len); - - /* send to user SAP */ - link->user->prim_cb(&prim->oph, link); - - return 0; -} - /* connection-oriented messages received from socket */ -static int sua_rx_co(struct osmo_sccp_link *link, - struct xua_msg *xua, struct msgb *msg) +static int sua_rx_co(struct osmo_ss7_asp *asp, struct xua_msg *xua) { - int rc = -1; + struct osmo_sccp_instance *inst = asp->inst->sccp; - switch (xua->hdr.msg_type) { - case SUA_CO_CORE: - rc = sua_rx_core(link, xua); - break; - case SUA_CO_COAK: - rc = sua_rx_coak(link, xua); - break; - case SUA_CO_COREF: - rc = sua_rx_coref(link, xua); - break; - case SUA_CO_RELRE: - rc = sua_rx_relre(link, xua); - break; - case SUA_CO_RELCO: - rc = sua_rx_relco(link, xua); - break; - case SUA_CO_CODT: - rc = sua_rx_codt(link, xua); - break; - case SUA_CO_RESCO: - case SUA_CO_RESRE: - case SUA_CO_CODA: - case SUA_CO_COERR: - case SUA_CO_COIT: - /* FIXME */ - default: - break; - } - - return rc; + /* We feed into SCRC, which then hands the message into + * either SCLC or SCOC, or forwards it to MTP */ + return scrc_rx_mtp_xfer_ind_xua(inst, xua); } -/* process SUA message received from socket */ -static int sua_rx_msg(struct osmo_sccp_link *link, struct msgb *msg) +static int sua_rx_mgmt_err(struct osmo_ss7_asp *asp, struct xua_msg *xua) { - struct xua_msg *xua; - int rc = -1; + uint32_t err_code = xua_msg_get_u32(xua, SUA_IEI_ERR_CODE); - xua = xua_from_msg(1, msgb_length(msg), msg->data); - if (!xua) { - LOGP(DSUA, LOGL_ERROR, "Unable to parse incoming " - "SUA message\n"); + LOGPASP(asp, DLSUA, LOGL_ERROR, "Received MGMT_ERR '%s': %s\n", + get_value_string(m3ua_err_names, err_code), + xua_msg_dump(xua, &xua_dialect_sua)); + + /* NEVER return != 0 here, as we cannot respont to an ERR + * message with another ERR! */ + return 0; +} + +static int sua_rx_mgmt_ntfy(struct osmo_ss7_asp *asp, struct xua_msg *xua) +{ + struct m3ua_notify_params ntfy; + const char *type_name, *info_name; + + m3ua_decode_notify(&ntfy, asp, xua); + + type_name = get_value_string(m3ua_ntfy_type_names, ntfy.status_type); + + switch (ntfy.status_type) { + case M3UA_NOTIFY_T_STATCHG: + info_name = get_value_string(m3ua_ntfy_stchg_names, + ntfy.status_info); + break; + case M3UA_NOTIFY_T_OTHER: + info_name = get_value_string(m3ua_ntfy_other_names, + ntfy.status_info); + break; + default: + info_name = "NULL"; + break; + } + LOGPASP(asp, DLSUA, LOGL_NOTICE, "Received NOTIFY Type %s:%s (%s)\n", + type_name, info_name, + ntfy.info_string ? ntfy.info_string : ""); + + if (ntfy.info_string) + talloc_free(ntfy.info_string); + + /* TODO: should we report this soemwhere? */ + return 0; +} + +static int sua_rx_mgmt(struct osmo_ss7_asp *asp, struct xua_msg *xua) +{ + switch (xua->hdr.msg_type) { + case SUA_MGMT_ERR: + return sua_rx_mgmt_err(asp, xua); + case SUA_MGMT_NTFY: + return sua_rx_mgmt_ntfy(asp, xua); + default: + return SUA_ERR_UNSUPP_MSG_TYPE; + } +} + +/* map from SUA ASPSM/ASPTM to xua_asp_fsm event */ +static const struct xua_msg_event_map sua_aspxm_map[] = { + { SUA_MSGC_ASPSM, SUA_ASPSM_UP, XUA_ASP_E_ASPSM_ASPUP }, + { SUA_MSGC_ASPSM, SUA_ASPSM_DOWN, XUA_ASP_E_ASPSM_ASPDN }, + { SUA_MSGC_ASPSM, SUA_ASPSM_BEAT, XUA_ASP_E_ASPSM_BEAT }, + { SUA_MSGC_ASPSM, SUA_ASPSM_UP_ACK, XUA_ASP_E_ASPSM_ASPUP_ACK }, + { SUA_MSGC_ASPSM, SUA_ASPSM_DOWN_ACK, XUA_ASP_E_ASPSM_ASPDN_ACK }, + { SUA_MSGC_ASPSM, SUA_ASPSM_BEAT_ACK, XUA_ASP_E_ASPSM_BEAT_ACK }, + { SUA_MSGC_ASPTM, SUA_ASPTM_ACTIVE, XUA_ASP_E_ASPTM_ASPAC }, + { SUA_MSGC_ASPTM, SUA_ASPTM_INACTIVE, XUA_ASP_E_ASPTM_ASPIA }, + { SUA_MSGC_ASPTM, SUA_ASPTM_ACTIVE_ACK, XUA_ASP_E_ASPTM_ASPAC_ACK }, + { SUA_MSGC_ASPTM, SUA_ASPTM_INACTIVE_ACK, XUA_ASP_E_ASPTM_ASPIA_ACK }, +}; + +static int sua_rx_asp(struct osmo_ss7_asp *asp, struct xua_msg *xua) +{ + int event; + + /* map from the SUA message class and message type to the XUA + * ASP FSM event number */ + event = xua_msg_event_map(xua, sua_aspxm_map, + ARRAY_SIZE(sua_aspxm_map)); + if (event < 0) + return SUA_ERR_UNSUPP_MSG_TYPE; + + /* deliver that event to the ASP FSM */ + osmo_fsm_inst_dispatch(asp->fi, event, xua); + + return 0; +} + +/*! \brief process SUA message received from socket + * \param[in] asp Application Server Process receiving \ref msg + * \param[in] msg received message buffer + * \returns 0 on success; negative on error */ +int sua_rx_msg(struct osmo_ss7_asp *asp, struct msgb *msg) +{ + struct xua_msg *xua = NULL, *err = NULL; + int rc = 0; + + OSMO_ASSERT(asp->cfg.proto == OSMO_SS7_ASP_PROT_SUA); + + /* caller owns msg memory, we shall neither free it here nor + * keep references beyon the execution of this function and its + * callees. */ + + if (!asp->inst->sccp) { + LOGP(DLSUA, LOGL_ERROR, "%s(asp->inst->sccp=NULL)\n", __func__); return -EIO; } - LOGP(DSUA, LOGL_DEBUG, "Received SUA Message (%s)\n", + xua = xua_from_msg(1, msgb_length(msg), msg->data); + if (!xua) { + struct xua_common_hdr *hdr = (struct xua_common_hdr *) msg->data; + + LOGPASP(asp, DLSUA, LOGL_ERROR, "Unable to parse incoming " + "SUA message\n"); + + if (hdr->version != SUA_VERSION) + err = sua_gen_error_msg(SUA_ERR_INVALID_VERSION, msg); + else + err = sua_gen_error_msg(SUA_ERR_PARAM_FIELD_ERR, msg); + goto out; + } + +#if 0 + xua->mtp.opc = ; + xua->mtp.dpc = ; +#endif + xua->mtp.sio = MTP_SI_SCCP; + + LOGPASP(asp, DLSUA, LOGL_DEBUG, "Received SUA Message (%s)\n", xua_hdr_dump(xua, &xua_dialect_sua)); - if (!xua_dialect_check_all_mand_ies(&xua_dialect_sua, xua)) - return -1; + if (!xua_dialect_check_all_mand_ies(&xua_dialect_sua, xua)) { + /* FIXME: Return error? */ + err = sua_gen_error_msg(SUA_ERR_MISSING_PARAM, msg); + goto out; + } + + /* TODO: check for SCTP Strema ID */ + /* TODO: check if any AS configured in ASP */ + /* TODO: check for valid routing context */ switch (xua->hdr.msg_class) { case SUA_MSGC_CL: - rc = sua_rx_cl(link, xua, msg); + rc = sua_rx_cl(asp, xua); break; case SUA_MSGC_CO: - rc = sua_rx_co(link, xua, msg); + rc = sua_rx_co(asp, xua); break; - case SUA_MSGC_MGMT: - case SUA_MSGC_SNM: case SUA_MSGC_ASPSM: case SUA_MSGC_ASPTM: + rc = sua_rx_asp(asp, xua); + break; + case SUA_MSGC_MGMT: + rc = sua_rx_mgmt(asp, xua); + break; + case SUA_MSGC_SNM: case SUA_MSGC_RKM: /* FIXME */ + LOGPASP(asp, DLSUA, LOGL_NOTICE, "Received unsupported SUA " + "Message Class %u\n", xua->hdr.msg_class); + err = sua_gen_error_msg(SUA_ERR_UNSUPP_MSG_CLASS, msg); + break; default: + LOGPASP(asp, DLSUA, LOGL_NOTICE, "Received unknown SUA " + "Message Class %u\n", xua->hdr.msg_class); + err = sua_gen_error_msg(SUA_ERR_UNSUPP_MSG_CLASS, msg); break; } + + if (rc > 0) + err = sua_gen_error_msg(rc, msg); + +out: + if (err) + sua_tx_xua_asp(asp, err); xua_msg_free(xua); return rc; } -/*********************************************************************** - * libosmonetif integration - ***********************************************************************/ - -#include -#include - -static const struct value_string sctp_assoc_chg_vals[] = { - { SCTP_COMM_UP, "COMM_UP" }, - { SCTP_COMM_LOST, "COMM_LOST" }, - { SCTP_RESTART, "RESTART" }, - { SCTP_SHUTDOWN_COMP, "SHUTDOWN_COMP" }, - { SCTP_CANT_STR_ASSOC, "CANT_STR_ASSOC" }, - { 0, NULL } -}; - -static const struct value_string sctp_sn_type_vals[] = { - { SCTP_ASSOC_CHANGE, "ASSOC_CHANGE" }, - { SCTP_PEER_ADDR_CHANGE, "PEER_ADDR_CHANGE" }, - { SCTP_SHUTDOWN_EVENT, "SHUTDOWN_EVENT" }, - { SCTP_SEND_FAILED, "SEND_FAILED" }, - { SCTP_REMOTE_ERROR, "REMOTE_ERROR" }, - { SCTP_PARTIAL_DELIVERY_EVENT, "PARTIAL_DELIVERY_EVENT" }, - { SCTP_ADAPTATION_INDICATION, "ADAPTATION_INDICATION" }, -#ifdef SCTP_AUTHENTICATION_INDICATION - { SCTP_AUTHENTICATION_INDICATION, "UTHENTICATION_INDICATION" }, -#endif -#ifdef SCTP_SENDER_DRY_EVENT - { SCTP_SENDER_DRY_EVENT, "SENDER_DRY_EVENT" }, -#endif - { 0, NULL } -}; - -static int get_logevel_by_sn_type(int sn_type) -{ - switch (sn_type) { - case SCTP_ADAPTATION_INDICATION: - case SCTP_PEER_ADDR_CHANGE: -#ifdef SCTP_AUTHENTICATION_INDICATION - case SCTP_AUTHENTICATION_INDICATION: -#endif -#ifdef SCTP_SENDER_DRY_EVENT - case SCTP_SENDER_DRY_EVENT: -#endif - return LOGL_INFO; - case SCTP_ASSOC_CHANGE: - return LOGL_NOTICE; - case SCTP_SHUTDOWN_EVENT: - case SCTP_PARTIAL_DELIVERY_EVENT: - return LOGL_NOTICE; - case SCTP_SEND_FAILED: - case SCTP_REMOTE_ERROR: - return LOGL_ERROR; - default: - return LOGL_NOTICE; - } -} - -static void log_sctp_notification(int fd, const char *pfx, - union sctp_notification *notif) -{ - int log_level; - char *conn_id = osmo_sock_get_name(NULL, fd); - - LOGP(DSUA, LOGL_INFO, "%s %s SCTP NOTIFICATION %u flags=0x%0x\n", - conn_id, pfx, notif->sn_header.sn_type, - notif->sn_header.sn_flags); - - log_level = get_logevel_by_sn_type(notif->sn_header.sn_type); - - switch (notif->sn_header.sn_type) { - case SCTP_ASSOC_CHANGE: - LOGP(DSUA, log_level, "%s %s SCTP_ASSOC_CHANGE: %s\n", - conn_id, pfx, get_value_string(sctp_assoc_chg_vals, - notif->sn_assoc_change.sac_state)); - break; - default: - LOGP(DSUA, log_level, "%s %s %s\n", - conn_id, pfx, get_value_string(sctp_sn_type_vals, - notif->sn_header.sn_type)); - break; - } - - talloc_free(conn_id); -} - -/* netif code tells us we can read something from the socket */ -static int sua_srv_conn_cb(struct osmo_stream_srv *conn) -{ - struct osmo_fd *ofd = osmo_stream_srv_get_ofd(conn); - struct osmo_sccp_link *link = osmo_stream_srv_get_data(conn); - struct msgb *msg = msgb_alloc(SUA_MSGB_SIZE, "SUA Server Rx"); - struct sctp_sndrcvinfo sinfo; - unsigned int ppid; - int flags = 0; - int rc; - - if (!msg) - return -ENOMEM; - - /* read SUA message from socket and process it */ - rc = sctp_recvmsg(ofd->fd, msgb_data(msg), msgb_tailroom(msg), - NULL, NULL, &sinfo, &flags); - LOGP(DSUA, LOGL_DEBUG, "sua_srv_conn_cb(): sctp_recvmsg() returned %d\n", - rc); - if (rc < 0) { - close(ofd->fd); - osmo_fd_unregister(ofd); - ofd->fd = -1; - return rc; - } else if (rc == 0) { - close(ofd->fd); - osmo_fd_unregister(ofd); - ofd->fd = -1; - } else { - msgb_put(msg, rc); - } - - if (flags & MSG_NOTIFICATION) { - union sctp_notification *notif = (union sctp_notification *) msgb_data(msg); - - log_sctp_notification(ofd->fd, "SUA SRV", notif); - - switch (notif->sn_header.sn_type) { - case SCTP_SHUTDOWN_EVENT: - close(ofd->fd); - osmo_fd_unregister(ofd); - ofd->fd = -1; - break; - default: - break; - } - msgb_free(msg); - return 0; - } - - ppid = ntohl(sinfo.sinfo_ppid); - msgb_sctp_ppid(msg) = ppid; - msgb_sctp_stream(msg) = ntohl(sinfo.sinfo_stream); - msg->dst = link; - - switch (ppid) { - case SUA_PPID: - rc = sua_rx_msg(link, msg); - break; - default: - LOGP(DSUA, LOGL_NOTICE, "SCTP chunk for unknown PPID %u " - "received\n", ppid); - rc = 0; - break; - } - - msgb_free(msg); - return rc; -} - -static int sua_srv_conn_closed_cb(struct osmo_stream_srv *srv) -{ - struct osmo_sccp_link *sual = osmo_stream_srv_get_data(srv); - struct sua_connection *conn; - - LOGP(DSUA, LOGL_INFO, "SCTP connection closed\n"); - - /* remove from per-user list of sua links */ - llist_del(&sual->list); - - llist_for_each_entry(conn, &sual->connections, list) { - /* FIXME: send RELEASE request */ - } - talloc_free(sual); - osmo_stream_srv_set_data(srv, NULL); - - return 0; -} - -static int sua_accept_cb(struct osmo_stream_srv_link *link, int fd) -{ - struct osmo_sccp_user *user = osmo_stream_srv_link_get_data(link); - struct osmo_stream_srv *srv; - struct osmo_sccp_link *sual; - - LOGP(DSUA, LOGL_INFO, "New SCTP connection accepted\n"); - - srv = osmo_stream_srv_create(user, link, fd, - sua_srv_conn_cb, - sua_srv_conn_closed_cb, NULL); - if (!srv) { - close(fd); - return -1; - } - - /* create new SUA link and connect both data structures */ - sual = sua_link_new(user, 1); - if (!sual) { - osmo_stream_srv_destroy(srv); - return -1; - } - sual->data = srv; - osmo_stream_srv_set_data(srv, sual); - - return 0; -} - -int osmo_sua_server_listen(struct osmo_sccp_user *user, const char *hostname, uint16_t port) -{ - int rc; - - if (user->server) - osmo_stream_srv_link_close(user->server); - else { - user->server = osmo_stream_srv_link_create(user); - osmo_stream_srv_link_set_data(user->server, user); - osmo_stream_srv_link_set_accept_cb(user->server, sua_accept_cb); - } - - osmo_stream_srv_link_set_addr(user->server, hostname); - osmo_stream_srv_link_set_port(user->server, port); - osmo_stream_srv_link_set_proto(user->server, IPPROTO_SCTP); - - rc = osmo_stream_srv_link_open(user->server); - if (rc < 0) { - osmo_stream_srv_link_destroy(user->server); - user->server = NULL; - return rc; - } - - return 0; -} - -/* netif code tells us we can read something from the socket */ -static int sua_cli_read_cb(struct osmo_stream_cli *conn) -{ - struct osmo_fd *ofd = osmo_stream_cli_get_ofd(conn); - struct osmo_sccp_link *link = osmo_stream_cli_get_data(conn); - struct msgb *msg = msgb_alloc(SUA_MSGB_SIZE, "SUA Client Rx"); - struct sctp_sndrcvinfo sinfo; - unsigned int ppid; - int flags = 0; - int rc; - - LOGP(DSUA, LOGL_DEBUG, "sua_cli_read_cb() rx\n"); - - if (!msg) - return -ENOMEM; - - /* read SUA message from socket and process it */ - rc = sctp_recvmsg(ofd->fd, msgb_data(msg), msgb_tailroom(msg), - NULL, NULL, &sinfo, &flags); - if (rc < 0) { - close(ofd->fd); - osmo_fd_unregister(ofd); - ofd->fd = -1; - return rc; - } else if (rc == 0) { - close(ofd->fd); - osmo_fd_unregister(ofd); - ofd->fd = -1; - } else { - msgb_put(msg, rc); - } - - if (flags & MSG_NOTIFICATION) { - union sctp_notification *notif = (union sctp_notification *) msgb_data(msg); - - log_sctp_notification(ofd->fd, "SUA CLNT", notif); - - switch (notif->sn_header.sn_type) { - case SCTP_SHUTDOWN_EVENT: - close(ofd->fd); - osmo_fd_unregister(ofd); - ofd->fd = -1; - break; - default: - break; - } - msgb_free(msg); - return 0; - } - - ppid = ntohl(sinfo.sinfo_ppid); - msgb_sctp_ppid(msg) = ppid; - msgb_sctp_stream(msg) = ntohl(sinfo.sinfo_stream); - msg->dst = link; - - switch (ppid) { - case SUA_PPID: - rc = sua_rx_msg(link, msg); - break; - default: - LOGP(DSUA, LOGL_NOTICE, "SCTP chunk for unknown PPID %u " - "received\n", ppid); - rc = 0; - break; - } - - msgb_free(msg); - return rc; -} - -int osmo_sua_client_connect(struct osmo_sccp_user *user, const char *hostname, uint16_t port) -{ - struct osmo_stream_cli *cli; - struct osmo_sccp_link *sual; - int rc; - - cli = osmo_stream_cli_create(user); - if (!cli) - return -1; - osmo_stream_cli_set_addr(cli, hostname); - osmo_stream_cli_set_port(cli, port); - osmo_stream_cli_set_proto(cli, IPPROTO_SCTP); - osmo_stream_cli_set_reconnect_timeout(cli, 5); - osmo_stream_cli_set_read_cb(cli, sua_cli_read_cb); - - /* create SUA link and associate it with stream_cli */ - sual = sua_link_new(user, 0); - if (!sual) { - osmo_stream_cli_destroy(cli); - return -1; - } - sual->data = cli; - osmo_stream_cli_set_data(cli, sual); - - rc = osmo_stream_cli_open2(cli, 1); - if (rc < 0) { - sua_link_destroy(sual); - osmo_stream_cli_destroy(cli); - return rc; - } - user->client = cli; - - return 0; -} - -struct osmo_sccp_link *osmo_sua_client_get_link(struct osmo_sccp_user *user) -{ - return osmo_stream_cli_get_data(user->client); -} - -static LLIST_HEAD(sua_users); - -struct osmo_sccp_user *osmo_sua_user_create(void *ctx, osmo_prim_cb prim_cb, - void *priv) -{ - struct osmo_sccp_user *user = talloc_zero(ctx, struct osmo_sccp_user); - - user->prim_cb = prim_cb; - user->priv = priv; - INIT_LLIST_HEAD(&user->links); - - llist_add_tail(&user->list, &sua_users); - - return user; -} - -void *osmo_sccp_link_get_user_priv(struct osmo_sccp_link *slink) -{ - return slink->user->priv; -} - -void osmo_sua_user_destroy(struct osmo_sccp_user *user) -{ - struct osmo_sccp_link *link; - - llist_del(&user->list); - - llist_for_each_entry(link, &user->links, list) - sua_link_destroy(link); - - talloc_free(user); -} - -void osmo_sua_set_log_area(int area) -{ - xua_set_log_area(area); - DSUA = area; -} diff --git a/src/xua_internal.h b/src/xua_internal.h index 66b5a26..c6f79b7 100644 --- a/src/xua_internal.h +++ b/src/xua_internal.h @@ -15,6 +15,8 @@ struct xua_msg *osmo_sccp_to_xua(struct msgb *msg); struct msgb *osmo_sua_to_sccp(struct xua_msg *xua); +int sua_rx_msg(struct osmo_ss7_asp *asp, struct msgb *msg); + int sua_tx_xua_as(struct osmo_ss7_as *as, struct xua_msg *xua); struct osmo_mtp_prim *m3ua_to_xfer_ind(struct xua_msg *xua); -- To view, visit https://gerrit.osmocom.org/2218 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I193b74f58aa70c443ae17e78b5604246d6bc3f71 Gerrit-PatchSet: 5 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:31:09 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:31:09 +0000 Subject: [PATCH] libosmo-sccp[master]: Add example program how to use M3UA+SCCP client and server In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2219 to look at the new patch set (#5). Add example program how to use M3UA+SCCP client and server This is an example tool that can be run either as server (SG) or as client (ASP) with a SCCP+M3UA stacking, and communicate via connectionless and connection-oriented primitives over it Change-Id: Id698ce2da5726e304dfa1773b794671dc80d853c --- M .gitignore M Makefile.am M configure.ac A examples/Makefile.am A examples/internal.h A examples/m3ua_example.c A examples/sccp_test_server.c A examples/sccp_test_vty.c 8 files changed, 392 insertions(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/19/2219/5 diff --git a/.gitignore b/.gitignore index 9d1435f..83f1333 100644 --- a/.gitignore +++ b/.gitignore @@ -60,6 +60,7 @@ tests/testsuite tests/testsuite.log +examples/m3ua_example *.pc config.* diff --git a/Makefile.am b/Makefile.am index b1eff56..dd73ec2 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,7 +1,7 @@ AUTOMAKE_OPTIONS = foreign dist-bzip2 1.6 AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -SUBDIRS = include src tests +SUBDIRS = include src tests examples pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = libosmo-sccp.pc libosmo-mtp.pc libosmo-sigtran.pc libosmo-xua.pc diff --git a/configure.ac b/configure.ac index 3644d22..6dc0ebd 100644 --- a/configure.ac +++ b/configure.ac @@ -27,6 +27,7 @@ PKG_PROG_PKG_CONFIG([0.20]) PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 0.3.0) +PKG_CHECK_MODULES(LIBOSMOVTY, libosmovty >= 0.3.0) PKG_CHECK_MODULES(LIBOSMONETIF, libosmo-netif >= 0.0.6) old_LIBS=$LIBS @@ -68,5 +69,6 @@ tests/m2ua/Makefile tests/xua/Makefile tests/ss7/Makefile + examples/Makefile Makefile) diff --git a/examples/Makefile.am b/examples/Makefile.am new file mode 100644 index 0000000..6418aca --- /dev/null +++ b/examples/Makefile.am @@ -0,0 +1,11 @@ +AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include +AM_CFLAGS=-Wall -g $(LIBOSMOCORE_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(LIBOSMONETIF_CFLAGS) $(COVERAGE_FLAGS) +AM_LDFLAGS=$(COVERAGE_LDFLAGS) + +noinst_HEADERS = internal.h + +noinst_PROGRAMS = m3ua_example + +m3ua_example_SOURCES = m3ua_example.c sccp_test_server.c sccp_test_vty.c +m3ua_example_LDADD = $(top_builddir)/src/libosmo-sigtran.la \ + $(LIBOSMOCORE_LIBS) $(LIBOSMOVTY_LIBS) diff --git a/examples/internal.h b/examples/internal.h new file mode 100644 index 0000000..70b9058 --- /dev/null +++ b/examples/internal.h @@ -0,0 +1,12 @@ +#pragma once + +#define SSN_TEST_UNUSED 200 +#define SSN_TEST_REFUSE 201 +#define SSN_TEST_ECHO 202 +#define SSN_TEST_CALLBACK 203 + +struct osmo_sccp_user; + +int sccp_test_user_vty_install(struct osmo_sccp_instance *inst, int ssn); + +int sccp_test_server_init(struct osmo_sccp_instance *sccp); diff --git a/examples/m3ua_example.c b/examples/m3ua_example.c new file mode 100644 index 0000000..d7b1fc2 --- /dev/null +++ b/examples/m3ua_example.c @@ -0,0 +1,98 @@ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "internal.h" + +static struct osmo_sccp_instance *sua_server_helper(void) +{ + struct osmo_sccp_instance *sccp; + + sccp = osmo_sccp_simple_server(NULL, 1, OSMO_SS7_ASP_PROT_M3UA, + -1, "127.0.0.2"); + + osmo_sccp_simple_server_add_clnt(sccp, OSMO_SS7_ASP_PROT_M3UA, + "23", 23, -1, 0, NULL); + + return sccp; +} + +/*********************************************************************** + * Initialization + ***********************************************************************/ + +static const struct log_info_cat log_info_cat[] = { +}; + +static const struct log_info log_info = { + .cat = log_info_cat, + .num_cat = ARRAY_SIZE(log_info_cat), +}; + +static void init_logging(void) +{ + const int log_cats[] = { DLSS7, DLSUA, DLM3UA, DLSCCP, DLINP }; + unsigned int i; + + osmo_init_logging(&log_info); + + for (i = 0; i < ARRAY_SIZE(log_cats); i++) + log_set_category_filter(osmo_stderr_target, log_cats[i], 1, LOGL_DEBUG); +} + +static struct vty_app_info vty_info = { + .name = "sccp-test", + .version = 0, +}; + +int main(int argc, char **argv) +{ + struct osmo_sccp_instance *sccp; + bool client; + int rc; + + init_logging(); + osmo_ss7_init(); + osmo_fsm_log_addr(false); + vty_init(&vty_info); + + if (argc <= 1) + client = true; + else + client = false; + + rc = telnet_init_dynif(NULL, NULL, vty_get_bind_addr(), 2324+client); + if (rc < 0) { + perror("Erro binding VTY port\n"); + exit(1); + } + + + if (client) { + sccp = osmo_sccp_simple_client(NULL, "client", 23, OSMO_SS7_ASP_PROT_M3UA, 0, M3UA_PORT, "127.0.0.2"); + sccp_test_user_vty_install(sccp, OSMO_SCCP_SSN_BSC_BSSAP); + } else { + sccp = sua_server_helper(); + sccp_test_server_init(sccp); + } + + while (1) { + osmo_select_main(0); + } +} diff --git a/examples/sccp_test_server.c b/examples/sccp_test_server.c new file mode 100644 index 0000000..c3c658f --- /dev/null +++ b/examples/sccp_test_server.c @@ -0,0 +1,115 @@ + +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include "internal.h" + +unsigned int conn_id; + +/* a simple SCCP User which refuses all connections and discards all + * unitdata */ +static int refuser_prim_cb(struct osmo_prim_hdr *oph, void *_scu) +{ + struct osmo_sccp_user *scu = _scu; + struct osmo_scu_prim *scu_prim = (struct osmo_scu_prim *) oph; + + switch (OSMO_PRIM_HDR(&scu_prim->oph)) { + case OSMO_PRIM(OSMO_SCU_PRIM_N_CONNECT, PRIM_OP_INDICATION): + printf("%s: refusing N-CONNECT.ind (local_ref=%u)\n", + __func__, scu_prim->u.connect.conn_id); + osmo_sccp_tx_disconn(scu, scu_prim->u.connect.conn_id, + &scu_prim->u.connect.called_addr, + 23); + break; + default: + printf("%s: Unknown primitive %u:%u\n", __func__, + oph->primitive, oph->operation); + break; + } + return 0; +} + +/* a simple SCCP User which accepts all connections and echos back all + * DATA + UNITDATA */ +static int echo_prim_cb(struct osmo_prim_hdr *oph, void *_scu) +{ + struct osmo_sccp_user *scu = _scu; + struct osmo_scu_prim *scu_prim = (struct osmo_scu_prim *) oph; + const uint8_t *data = msgb_l2(oph->msg); + unsigned int data_len = msgb_l2len(oph->msg); + + switch (OSMO_PRIM_HDR(&scu_prim->oph)) { + case OSMO_PRIM(OSMO_SCU_PRIM_N_CONNECT, PRIM_OP_INDICATION): + printf("%s: Accepting N-CONNECT.ind (local_ref=%u)\n", + __func__, scu_prim->u.connect.conn_id); + osmo_sccp_tx_conn_resp(scu, scu_prim->u.connect.conn_id, + &scu_prim->u.connect.called_addr, + data, data_len); + break; + case OSMO_PRIM(OSMO_SCU_PRIM_N_DATA, PRIM_OP_INDICATION): + printf("%s: Echoing N-DATA.ind (local_ref=%u)\n", + __func__, scu_prim->u.data.conn_id); + osmo_sccp_tx_data(scu, scu_prim->u.data.conn_id, + data, data_len); + break; + case OSMO_PRIM(OSMO_SCU_PRIM_N_UNITDATA, PRIM_OP_INDICATION): + printf("%s: Echoing N-UNITDATA.ind\n", __func__); + osmo_sccp_tx_unitdata(scu, &scu_prim->u.unitdata.called_addr, + &scu_prim->u.unitdata.calling_addr, + data, data_len); + break; + default: + printf("%s: Unknown primitive %u:%u\n", __func__, + oph->primitive, oph->operation); + break; + } + return 0; +} + +/* a simple SCCP User which receives UNITDATA messages and connects back + * to whoever sents UNITDATA and then echo's back all DATA */ +static int callback_prim_cb(struct osmo_prim_hdr *oph, void *_scu) +{ + struct osmo_sccp_user *scu = _scu; + struct osmo_scu_prim *scu_prim = (struct osmo_scu_prim *) oph; + const uint8_t *data = msgb_l2(oph->msg); + unsigned int data_len = msgb_l2len(oph->msg); + + switch (OSMO_PRIM_HDR(&scu_prim->oph)) { + case OSMO_PRIM(OSMO_SCU_PRIM_N_UNITDATA, PRIM_OP_INDICATION): + printf("%s: N-UNITDATA.ind: Connectiong back to sender\n", __func__); + osmo_sccp_tx_conn_req(scu, conn_id++, + &scu_prim->u.unitdata.called_addr, + &scu_prim->u.unitdata.calling_addr, + data, data_len); + break; + case OSMO_PRIM(OSMO_SCU_PRIM_N_DATA, PRIM_OP_INDICATION): + printf("%s: Echoing N-DATA.ind (local_ref=%u)\n", + __func__, scu_prim->u.data.conn_id); + osmo_sccp_tx_data(scu, scu_prim->u.data.conn_id, + data, data_len); + break; + default: + printf("%s: Unknown primitive %u:%u\n", __func__, + oph->primitive, oph->operation); + break; + } + return 0; +} + +int sccp_test_server_init(struct osmo_sccp_instance *sccp) +{ + osmo_sccp_user_bind(sccp, "refuser", &refuser_prim_cb, SSN_TEST_REFUSE); + osmo_sccp_user_bind(sccp, "echo", &echo_prim_cb, SSN_TEST_ECHO); + osmo_sccp_user_bind(sccp, "callback", &callback_prim_cb, SSN_TEST_CALLBACK); + + return 0; +} diff --git a/examples/sccp_test_vty.c b/examples/sccp_test_vty.c new file mode 100644 index 0000000..1134d57 --- /dev/null +++ b/examples/sccp_test_vty.c @@ -0,0 +1,152 @@ + +#include + +#include +#include + +#include +#include + +#include "internal.h" + +#define SCU_NODE 23 + +static struct osmo_sccp_user *g_scu; + +static struct osmo_sccp_addr g_calling_addr = { + .presence = OSMO_SCCP_ADDR_T_SSN | OSMO_SCCP_ADDR_T_PC, + .ri = OSMO_SCCP_RI_SSN_PC, + .pc = 23, +}; + +static struct osmo_sccp_addr g_called_addr = { + .presence = OSMO_SCCP_ADDR_T_SSN | OSMO_SCCP_ADDR_T_PC, + .ssn = 1, + .ri = OSMO_SCCP_RI_SSN_PC, + .pc = 1, +}; + +DEFUN(scu_called_ssn, scu_called_ssn_cmd, + "called-addr-ssn <0-255>", + "Set SSN of SCCP CalledAddress\n" + "SSN of SCCP CalledAddress\n") +{ + g_called_addr.ssn = atoi(argv[0]); + return CMD_SUCCESS; +} + +DEFUN(scu_conn_req, scu_conn_req_cmd, + "connect-req <0-16777216> [DATA]", + "N-CONNECT.req\n" + "Connection ID\n") +{ + struct osmo_sccp_user *scu = vty->index; + int conn_id = atoi(argv[0]); + const char *data = argv[1]; + + osmo_sccp_tx_conn_req(scu, conn_id, &g_calling_addr, &g_called_addr, + (const uint8_t *)data, data ? strlen(data)+1 : 0); + return CMD_SUCCESS; +} + +DEFUN(scu_conn_resp, scu_conn_resp_cmd, + "connect-resp <0-16777216> [DATA]", + "N-CONNET.resp\n" + "Connection ID\n") +{ + struct osmo_sccp_user *scu = vty->index; + int conn_id = atoi(argv[0]); + const char *data = argv[1]; + + osmo_sccp_tx_conn_resp(scu, conn_id, NULL, + (const uint8_t *)data, data ? strlen(data)+1 : 0); + return CMD_SUCCESS; +} + +DEFUN(scu_data_req, scu_data_req_cmd, + "data-req <0-16777216> DATA", + "N-DATA.req\n" + "Connection ID\n") +{ + struct osmo_sccp_user *scu = vty->index; + int conn_id = atoi(argv[0]); + const char *data = argv[1]; + + osmo_sccp_tx_data(scu, conn_id, (const uint8_t *)data, strlen(data)+1); + return CMD_SUCCESS; +} + +DEFUN(scu_unitdata_req, scu_unitdata_req_cmd, + "unitdata-req DATA", + "N-UNITDATA.req\n") +{ + struct osmo_sccp_user *scu = vty->index; + const char *data = argv[0]; + + osmo_sccp_tx_unitdata(scu, &g_calling_addr, &g_called_addr, + (const uint8_t *)data, strlen(data)+1); + return CMD_SUCCESS; +} + +DEFUN(scu_disc_req, scu_disc_req_cmd, + "disconnect-req <0-16777216>", + "N-DISCONNT.req\n" + "Connection ID\n") +{ + struct osmo_sccp_user *scu = vty->index; + int conn_id = atoi(argv[0]); + + osmo_sccp_tx_disconn(scu, conn_id, NULL, 42); + return CMD_SUCCESS; +} + +static struct cmd_node scu_node = { + SCU_NODE, + "%s(sccp-user)# ", + 1, +}; + +DEFUN(scu, scu_cmd, + "sccp-user", + "Enter SCCP User Node\n") +{ + vty->node = SCU_NODE; + vty->index = g_scu; + return CMD_SUCCESS; +} + +static int testclnt_prim_cb(struct osmo_prim_hdr *oph, void *_scu) +{ + struct osmo_sccp_user *scu = _scu; + struct osmo_scu_prim *scu_prim = (struct osmo_scu_prim *) oph; + + switch (OSMO_PRIM_HDR(&scu_prim->oph)) { + case OSMO_PRIM(OSMO_SCU_PRIM_N_CONNECT, PRIM_OP_INDICATION): + default: + break; + } + return 0; +} + + +int sccp_test_user_vty_install(struct osmo_sccp_instance *inst, int ssn) +{ + g_scu = osmo_sccp_user_bind(inst, "test_client_vty", testclnt_prim_cb, ssn); + if (!g_scu) + return -1; + + g_calling_addr.ssn = ssn; + + install_node(&scu_node, NULL); + vty_install_default(SCU_NODE); + install_element(SCU_NODE, &scu_called_ssn_cmd); + install_element(SCU_NODE, &scu_conn_req_cmd); + install_element(SCU_NODE, &scu_conn_resp_cmd); + install_element(SCU_NODE, &scu_data_req_cmd); + install_element(SCU_NODE, &scu_unitdata_req_cmd); + install_element(SCU_NODE, &scu_disc_req_cmd); + + install_element(ENABLE_NODE, &scu_cmd); + + return 0; +} -- To view, visit https://gerrit.osmocom.org/2219 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Id698ce2da5726e304dfa1773b794671dc80d853c Gerrit-PatchSet: 5 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:31:09 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:31:09 +0000 Subject: [PATCH] libosmo-sccp[master]: xua: Remove library-internal DXUA log subsystem In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2220 to look at the new patch set (#5). xua: Remove library-internal DXUA log subsystem We don't really need those thre log messages, and we can thus do away with the library-internal log-subsystem of DXUA. The rest of libosmo-sigtran uses the new globa DL... subsystems anyway Change-Id: Iea0d3db34a3674a9c6422b174a879bfdaa25786f --- M include/osmocom/sigtran/xua_msg.h M src/xua_msg.c 2 files changed, 2 insertions(+), 18 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/20/2220/5 diff --git a/include/osmocom/sigtran/xua_msg.h b/include/osmocom/sigtran/xua_msg.h index 320da6a..e0e1bcf 100644 --- a/include/osmocom/sigtran/xua_msg.h +++ b/include/osmocom/sigtran/xua_msg.h @@ -69,8 +69,6 @@ extern const struct xua_dialect xua_dialect_sua; extern const struct xua_dialect xua_dialect_m3ua; -extern int DXUA; - struct xua_msg *xua_msg_alloc(void); void xua_msg_free(struct xua_msg *msg); @@ -83,8 +81,6 @@ struct xua_msg *xua_from_msg(const int version, uint16_t len, uint8_t *data); struct msgb *xua_to_msg(const int version, struct xua_msg *msg); - -void xua_set_log_area(int log_area); int msgb_t16l16vp_put(struct msgb *msg, uint16_t tag, uint16_t len, const uint8_t *data); int msgb_t16l16vp_put_u32(struct msgb *msg, uint16_t tag, uint32_t val); diff --git a/src/xua_msg.c b/src/xua_msg.c index 27279ce..cb487c8 100644 --- a/src/xua_msg.c +++ b/src/xua_msg.c @@ -32,17 +32,14 @@ #include static void *tall_xua; -int DXUA = -1; struct xua_msg *xua_msg_alloc(void) { struct xua_msg *msg; msg = talloc_zero(tall_xua, struct xua_msg); - if (!msg) { - LOGP(DXUA, LOGL_ERROR, "Failed to allocate.\n"); + if (!msg) return NULL; - } INIT_LLIST_HEAD(&msg->headers); return msg; @@ -162,7 +159,6 @@ return msg; fail: - LOGP(DXUA, LOGL_ERROR, "Failed to parse.\n"); xua_msg_free(msg); return NULL; } @@ -175,10 +171,8 @@ uint8_t rest; msg = msgb_alloc_headroom(2048, 512, "xua msg"); - if (!msg) { - LOGP(DXUA, LOGL_ERROR, "Failed to allocate.\n"); + if (!msg) return NULL; - } msg->l2h = msgb_put(msg, sizeof(*hdr)); hdr = (struct xua_common_hdr *) msg->l2h; @@ -208,12 +202,6 @@ hdr->msg_length = htonl(msgb_l2len(msg)); return msg; } - -void xua_set_log_area(int log_area) -{ - DXUA = log_area; -} - /*********************************************************************** * Message encoding helper functions -- To view, visit https://gerrit.osmocom.org/2220 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Iea0d3db34a3674a9c6422b174a879bfdaa25786f Gerrit-PatchSet: 5 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:31:09 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:31:09 +0000 Subject: [PATCH] libosmo-sccp[master]: sccp: add osmo_sccp_user_{get, set}_priv() API function In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2234 to look at the new patch set (#3). sccp: add osmo_sccp_user_{get,set}_priv() API function As 'struct osmo_sccp_user' is private, we need this accessor functions for the SCCP User so it can set and get the 'priv' data. Change-Id: Ia68a36dc18a7d754d63ae29c86d68e495b5c4134 --- M include/osmocom/sigtran/sccp_sap.h M src/sccp_user.c 2 files changed, 12 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/34/2234/3 diff --git a/include/osmocom/sigtran/sccp_sap.h b/include/osmocom/sigtran/sccp_sap.h index c1464f0..a86f86a 100644 --- a/include/osmocom/sigtran/sccp_sap.h +++ b/include/osmocom/sigtran/sccp_sap.h @@ -232,6 +232,8 @@ void osmo_sccp_instance_destroy(struct osmo_sccp_instance *inst); void osmo_sccp_user_unbind(struct osmo_sccp_user *scu); +void osmo_sccp_user_set_priv(struct osmo_sccp_user *scu, void *priv); +void *osmo_sccp_user_get_priv(struct osmo_sccp_user *scu); struct osmo_sccp_user * osmo_sccp_user_bind_pc(struct osmo_sccp_instance *inst, const char *name, diff --git a/src/sccp_user.c b/src/sccp_user.c index df02486..bc03f4e 100644 --- a/src/sccp_user.c +++ b/src/sccp_user.c @@ -130,6 +130,16 @@ talloc_free(scu); } +void osmo_sccp_user_set_priv(struct osmo_sccp_user *scu, void *priv) +{ + scu->priv = priv; +} + +void *osmo_sccp_user_get_priv(struct osmo_sccp_user *scu) +{ + return scu->priv; +} + /*! \brief Send a SCCP User SAP Primitive up to the User * \param[in] scu SCCP User to whom to send the primitive * \param[in] prim Primitive to send to the user -- To view, visit https://gerrit.osmocom.org/2234 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ia68a36dc18a7d754d63ae29c86d68e495b5c4134 Gerrit-PatchSet: 3 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:31:09 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:31:09 +0000 Subject: [PATCH] libosmo-sccp[master]: osmo_ss7: make OVERRIDE the default traffic mode type (0) In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2235 to look at the new patch set (#3). osmo_ss7: make OVERRIDE the default traffic mode type (0) Change-Id: Ie83fa0a403dcfc582d6bb59ec08d6a719d2f6398 --- M include/osmocom/sigtran/osmo_ss7.h 1 file changed, 1 insertion(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/35/2235/3 diff --git a/include/osmocom/sigtran/osmo_ss7.h b/include/osmocom/sigtran/osmo_ss7.h index 5bbcd65..7918a51 100644 --- a/include/osmocom/sigtran/osmo_ss7.h +++ b/include/osmocom/sigtran/osmo_ss7.h @@ -229,10 +229,10 @@ }; enum osmo_ss7_as_traffic_mode { + OSMO_SS7_AS_TMOD_OVERRIDE = 0, /* default */ OSMO_SS7_AS_TMOD_BCAST, OSMO_SS7_AS_TMOD_LOADSHARE, OSMO_SS7_AS_TMOD_ROUNDROBIN, - OSMO_SS7_AS_TMOD_OVERRIDE, _NUM_OSMO_SS7_ASP_TMOD }; -- To view, visit https://gerrit.osmocom.org/2235 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ie83fa0a403dcfc582d6bb59ec08d6a719d2f6398 Gerrit-PatchSet: 3 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:31:09 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:31:09 +0000 Subject: [PATCH] libosmo-sccp[master]: add converter functions between osmo_ss7 and m3ua traffic mo... In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2236 to look at the new patch set (#3). add converter functions between osmo_ss7 and m3ua traffic mode types Change-Id: I6cc9530d7d2812cbc8feb6e9db51902865ebfe83 --- M include/osmocom/sigtran/osmo_ss7.h M include/osmocom/sigtran/protocol/m3ua.h M src/osmo_ss7.c 3 files changed, 36 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/36/2236/3 diff --git a/include/osmocom/sigtran/osmo_ss7.h b/include/osmocom/sigtran/osmo_ss7.h index 7918a51..d765ae0 100644 --- a/include/osmocom/sigtran/osmo_ss7.h +++ b/include/osmocom/sigtran/osmo_ss7.h @@ -406,3 +406,6 @@ const char *name, uint32_t pc, int local_port, int remote_port, const char *remote_ip); + +enum osmo_ss7_as_traffic_mode osmo_ss7_tmode_from_xua(uint32_t in); +int osmo_ss7_tmode_to_xua(enum osmo_ss7_as_traffic_mode tmod); diff --git a/include/osmocom/sigtran/protocol/m3ua.h b/include/osmocom/sigtran/protocol/m3ua.h index d4dc1fe..c10808c 100644 --- a/include/osmocom/sigtran/protocol/m3ua.h +++ b/include/osmocom/sigtran/protocol/m3ua.h @@ -145,3 +145,9 @@ M3UA_ERR_INVAL_ROUT_CTX = 0x19, M3UA_ERR_NO_CONFGD_AS_FOR_ASP = 0x1a, }; + +enum m3ua_traffic_mode { + M3UA_TMOD_OVERRIDE = 1, + M3UA_TMOD_LOADSHARE = 2, + M3UA_TMOD_BCAST = 3, +}; diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index ab0636c..2dbb94d 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -1494,3 +1494,30 @@ ss7_initialized = true; return 0; } + +int osmo_ss7_tmode_to_xua(enum osmo_ss7_as_traffic_mode tmod) +{ + switch (tmod) { + case OSMO_SS7_AS_TMOD_OVERRIDE: + return M3UA_TMOD_OVERRIDE; + case OSMO_SS7_AS_TMOD_LOADSHARE: + return M3UA_TMOD_LOADSHARE; + case OSMO_SS7_AS_TMOD_BCAST: + return M3UA_TMOD_BCAST; + default: + return -1; + } +} + +enum osmo_ss7_as_traffic_mode osmo_ss7_tmode_from_xua(uint32_t in) +{ + switch (in) { + case M3UA_TMOD_OVERRIDE: + default: + return OSMO_SS7_AS_TMOD_OVERRIDE; + case M3UA_TMOD_LOADSHARE: + return OSMO_SS7_AS_TMOD_LOADSHARE; + case M3UA_TMOD_BCAST: + return OSMO_SS7_AS_TMOD_BCAST; + } +} -- To view, visit https://gerrit.osmocom.org/2236 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I6cc9530d7d2812cbc8feb6e9db51902865ebfe83 Gerrit-PatchSet: 3 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:31:09 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:31:09 +0000 Subject: [PATCH] libosmo-sccp[master]: m3ua: Include RC IE of AS in Tx; validate RC IE on Rx In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2237 to look at the new patch set (#3). m3ua: Include RC IE of AS in Tx; validate RC IE on Rx Change-Id: I7db36a23185f82d8d68e318afe89ec5127c40333 --- M src/m3ua.c 1 file changed, 26 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/37/2237/3 diff --git a/src/m3ua.c b/src/m3ua.c index 8ec82c5..7437b6e 100644 --- a/src/m3ua.c +++ b/src/m3ua.c @@ -448,6 +448,10 @@ OSMO_ASSERT(as->cfg.proto == OSMO_SS7_ASP_PROT_M3UA); + /* Add RC for this AS */ + if (as->cfg.routing_key.context) + xua_msg_add_u32(xua, M3UA_IEI_ROUTE_CTX, as->cfg.routing_key.context); + for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) { asp = as->cfg.asps[i]; if (!asp) @@ -488,7 +492,24 @@ static int m3ua_rx_xfer(struct osmo_ss7_asp *asp, struct xua_msg *xua) { + uint32_t rctx = xua_msg_get_u32(xua, M3UA_IEI_ROUTE_CTX); struct m3ua_data_hdr *dh; + struct xua_msg *err = NULL; + struct osmo_ss7_as *as; + + /* Use routing context IE to look up the AS for which the + * message was received. */ + as = osmo_ss7_as_find_by_rctx(asp->inst, rctx); + if (!as) { + err = m3ua_gen_error(M3UA_ERR_INVAL_ROUT_CTX); + goto out_err; + } + /* Verify that this ASP ix part of the AS. */ + if (!osmo_ss7_as_has_asp(as, asp)) { + err = m3ua_gen_error(M3UA_ERR_NO_CONFGD_AS_FOR_ASP); + goto out_err; + } + /* FIXME: check for AS state == ACTIVE */ /* store the MTP-level information in the xua_msg for use by * higher layer protocols */ @@ -497,6 +518,11 @@ m3ua_dh_to_xfer_param(&xua->mtp, dh); return m3ua_hmdc_rx_from_l2(asp->inst, xua); +out_err: + if (err) + m3ua_tx_xua_asp(asp, err); + + return -1; } static int m3ua_rx_mgmt_err(struct osmo_ss7_asp *asp, struct xua_msg *xua) -- To view, visit https://gerrit.osmocom.org/2237 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I7db36a23185f82d8d68e318afe89ec5127c40333 Gerrit-PatchSet: 3 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:31:09 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:31:09 +0000 Subject: [PATCH] libosmo-sccp[master]: xua_asp_fsm: Always return BEAT-ACK for BEAT, including BEAT... In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2238 to look at the new patch set (#3). xua_asp_fsm: Always return BEAT-ACK for BEAT, including BEAT DATA IE The RFCs say we *must* always respond to the optional heartbeat message, and we must return a verbatim copy of the heartbeat data IE. This was discovered (and fix validated) using m3ua-sgp-asptm-v-011 of Michael Tuexen's m3ua-testtool. Change-Id: I836e0940a8dbb0f55ddf132202a5f0d51473b82d --- M src/xua_asp_fsm.c 1 file changed, 23 insertions(+), 11 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/38/2238/3 diff --git a/src/xua_asp_fsm.c b/src/xua_asp_fsm.c index 80faeb2..aafc09f 100644 --- a/src/xua_asp_fsm.c +++ b/src/xua_asp_fsm.c @@ -128,7 +128,7 @@ } /* ask the xUA implementation to transmit a specific message */ -static int peer_send(struct osmo_fsm_inst *fi, int out_event) +static int peer_send(struct osmo_fsm_inst *fi, int out_event, struct xua_msg *in) { struct xua_asp_fsm_priv *xafp = fi->priv; struct osmo_ss7_asp *asp = xafp->asp; @@ -168,6 +168,7 @@ /* RFC3868 Ch. 3.5.6 */ xua->hdr = XUA_HDR(SUA_MSGC_ASPSM, SUA_ASPSM_BEAT_ACK); /* Optional: Heartbeat Data */ + xua_msg_copy_part(xua, M3UA_IEI_HEARDBT_DATA, in, M3UA_IEI_HEARDBT_DATA); break; case XUA_ASP_E_ASPTM_ASPAC: /* RFC3868 Ch. 3.6.1 */ @@ -217,7 +218,7 @@ osmo_fsm_event_name(fi->fsm, xafp->t_ack.out_event)); /* Re-transmit message */ - peer_send(fi, xafp->t_ack.out_event); + peer_send(fi, xafp->t_ack.out_event, NULL); /* Re-start the timer */ osmo_timer_schedule(&xafp->t_ack.timer, XUA_T_ACK_SEC, 0); @@ -229,7 +230,7 @@ struct xua_asp_fsm_priv *xafp = fi->priv; int rc; - rc = peer_send(fi, out_event); + rc = peer_send(fi, out_event, NULL); if (rc < 0) return rc; @@ -328,7 +329,7 @@ asp->asp_id_present = true; } /* send ACK */ - peer_send(fi, XUA_ASP_E_ASPSM_ASPUP_ACK); + peer_send(fi, XUA_ASP_E_ASPSM_ASPUP_ACK, NULL); /* transition state and inform layer manager */ osmo_fsm_inst_state_chg(fi, XUA_ASP_S_INACTIVE, 0, 0); send_xlm_prim_simple(fi, OSMO_XLM_PRIM_M_ASP_UP, @@ -340,7 +341,7 @@ /* The SGP MUST send an ASP Down Ack message in response * to a received ASP Down message from the ASP even if * the ASP is already marked as ASP-DOWN at the SGP. */ - peer_send(fi, XUA_ASP_E_ASPSM_ASPDN_ACK); + peer_send(fi, XUA_ASP_E_ASPSM_ASPDN_ACK, NULL); break; } } @@ -401,7 +402,7 @@ /* only in role SG */ ENSURE_SG_OR_IPSP(fi, event); /* send ACK */ - peer_send(fi, XUA_ASP_E_ASPTM_ASPAC_ACK); + peer_send(fi, XUA_ASP_E_ASPTM_ASPAC_ACK, NULL); /* transition state and inform layer manager */ osmo_fsm_inst_state_chg(fi, XUA_ASP_S_ACTIVE, 0, 0); send_xlm_prim_simple(fi, OSMO_XLM_PRIM_M_ASP_ACTIVE, @@ -411,7 +412,7 @@ /* only in role SG */ ENSURE_SG_OR_IPSP(fi, event); /* send ACK */ - peer_send(fi, XUA_ASP_E_ASPSM_ASPDN_ACK); + peer_send(fi, XUA_ASP_E_ASPSM_ASPDN_ACK, NULL); /* transition state and inform layer manager */ osmo_fsm_inst_state_chg(fi, XUA_ASP_S_DOWN, 0, 0); send_xlm_prim_simple(fi, OSMO_XLM_PRIM_M_ASP_DOWN, @@ -424,7 +425,7 @@ * remote ASP is already in the ASP-INACTIVE state, an * ASP Up Ack message is returned and no further action * is taken. */ - peer_send(fi, XUA_ASP_E_ASPSM_ASPUP_ACK); + peer_send(fi, XUA_ASP_E_ASPSM_ASPUP_ACK, NULL); break; } } @@ -470,7 +471,7 @@ /* only in role SG */ ENSURE_SG_OR_IPSP(fi, event); /* send ACK */ - peer_send(fi, XUA_ASP_E_ASPTM_ASPIA_ACK); + peer_send(fi, XUA_ASP_E_ASPTM_ASPIA_ACK, NULL); /* transition state and inform layer manager */ osmo_fsm_inst_state_chg(fi, XUA_ASP_S_INACTIVE, 0, 0); send_xlm_prim_simple(fi, OSMO_XLM_PRIM_M_ASP_INACTIVE, @@ -480,7 +481,7 @@ /* only in role SG */ ENSURE_SG_OR_IPSP(fi, event); /* send ACK */ - peer_send(fi, XUA_ASP_E_ASPSM_ASPDN_ACK); + peer_send(fi, XUA_ASP_E_ASPSM_ASPDN_ACK, NULL); /* transition state and inform layer manager */ osmo_fsm_inst_state_chg(fi, XUA_ASP_S_DOWN, 0, 0); send_xlm_prim_simple(fi, OSMO_XLM_PRIM_M_ASP_DOWN, @@ -508,12 +509,21 @@ static void xua_asp_allstate(struct osmo_fsm_inst *fi, uint32_t event, void *data) { + struct xua_msg *xua; + switch (event) { case XUA_ASP_E_SCTP_COMM_DOWN_IND: case XUA_ASP_E_SCTP_RESTART_IND: osmo_fsm_inst_state_chg(fi, XUA_ASP_S_DOWN, 0, 0); send_xlm_prim_simple(fi, OSMO_XLM_PRIM_M_ASP_DOWN, PRIM_OP_INDICATION); + break; + case XUA_ASP_E_ASPSM_BEAT: + xua = data; + peer_send(fi, XUA_ASP_E_ASPSM_BEAT_ACK, xua); + break; + case XUA_ASP_E_ASPSM_BEAT_ACK: + /* FIXME: stop timer, if any */ break; default: break; @@ -577,7 +587,9 @@ .log_subsys = DLSS7, .event_names = xua_asp_event_names, .allstate_event_mask = S(XUA_ASP_E_SCTP_COMM_DOWN_IND) | - S(XUA_ASP_E_SCTP_RESTART_IND), + S(XUA_ASP_E_SCTP_RESTART_IND) | + S(XUA_ASP_E_ASPSM_BEAT) | + S(XUA_ASP_E_ASPSM_BEAT_ACK), .allstate_action = xua_asp_allstate, }; -- To view, visit https://gerrit.osmocom.org/2238 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I836e0940a8dbb0f55ddf132202a5f0d51473b82d Gerrit-PatchSet: 3 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:31:09 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:31:09 +0000 Subject: [PATCH] libosmo-sccp[master]: xua_as_fsm: Include routing context (if configured) in NTFY ... In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2239 to look at the new patch set (#3). xua_as_fsm: Include routing context (if configured) in NTFY message Change-Id: I15e8bf5cee194f9924d0eab9cff0e7c25daa6dde --- M src/xua_as_fsm.c 1 file changed, 9 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/39/2239/3 diff --git a/src/xua_as_fsm.c b/src/xua_as_fsm.c index 887a9ec..d73f793 100644 --- a/src/xua_as_fsm.c +++ b/src/xua_as_fsm.c @@ -149,6 +149,7 @@ static void xua_as_fsm_onenter(struct osmo_fsm_inst *fi, uint32_t old_state) { struct xua_as_fsm_priv *xafp = (struct xua_as_fsm_priv *) fi->priv; + struct osmo_ss7_as *as = xafp->as; struct m3ua_notify_params npar = { .status_type = M3UA_NOTIFY_T_STATCHG, }; @@ -167,6 +168,14 @@ return; } + /* Add the routing context, if it is configured */ + if (as->cfg.routing_key.context) { + npar.presence |= NOTIFY_PAR_P_ROUTE_CTX; + npar.route_ctx = as->cfg.routing_key.context; + } + + /* TODO: ASP-Id of ASP triggering this state change */ + asp_notify_all_as(xafp->as, &npar); }; -- To view, visit https://gerrit.osmocom.org/2239 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I15e8bf5cee194f9924d0eab9cff0e7c25daa6dde Gerrit-PatchSet: 3 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:31:09 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:31:09 +0000 Subject: [PATCH] libosmo-sccp[master]: xua_cli_conn_cb: Print flags as hex, not decimal. In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2240 to look at the new patch set (#3). xua_cli_conn_cb: Print flags as hex, not decimal. Change-Id: Idcf861cfdc6c14d7d3bafbf2e243da5db6e2f3e6 --- M src/osmo_ss7.c 1 file changed, 1 insertion(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/40/2240/3 diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index 2dbb94d..df85ea8 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -1246,7 +1246,7 @@ /* read xUA message from socket and process it */ rc = sctp_recvmsg(ofd->fd, msgb_data(msg), msgb_tailroom(msg), NULL, NULL, &sinfo, &flags); - LOGPASP(asp, DLSS7, LOGL_DEBUG, "%s(): sctp_recvmsg() returned %d (flags=%d)\n", + LOGPASP(asp, DLSS7, LOGL_DEBUG, "%s(): sctp_recvmsg() returned %d (flags=0x%x)\n", __func__, rc, flags); if (rc < 0) { osmo_stream_cli_reconnect(conn); -- To view, visit https://gerrit.osmocom.org/2240 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Idcf861cfdc6c14d7d3bafbf2e243da5db6e2f3e6 Gerrit-PatchSet: 3 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:31:09 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:31:09 +0000 Subject: [PATCH] libosmo-sccp[master]: xua_srv_conn_cb(): Print sctp_recvmsg flags (line in xua_cli... In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2241 to look at the new patch set (#3). xua_srv_conn_cb(): Print sctp_recvmsg flags (line in xua_cli_conn_cb()) Change-Id: I91920c6ad665abc791a1dbf386d52cf0aece9133 --- M src/osmo_ss7.c 1 file changed, 2 insertions(+), 2 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/41/2241/3 diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index df85ea8..8ec099a 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -1163,8 +1163,8 @@ /* read xUA message from socket and process it */ rc = sctp_recvmsg(ofd->fd, msgb_data(msg), msgb_tailroom(msg), NULL, NULL, &sinfo, &flags); - LOGPASP(asp, DLSS7, LOGL_DEBUG, "%s(): sctp_recvmsg() returned %d\n", - __func__, rc); + LOGPASP(asp, DLSS7, LOGL_DEBUG, "%s(): sctp_recvmsg() returned %d (flags=0x%x)\n", + __func__, rc, flags); if (rc < 0) { osmo_stream_srv_destroy(conn); goto out; -- To view, visit https://gerrit.osmocom.org/2241 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I91920c6ad665abc791a1dbf386d52cf0aece9133 Gerrit-PatchSet: 3 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:31:09 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:31:09 +0000 Subject: [PATCH] libosmo-sccp[master]: sigtran: fix various memory leaks (msgb and xua_msg) In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2242 to look at the new patch set (#3). sigtran: fix various memory leaks (msgb and xua_msg) The general rule for 'struct xua_msg' is now that it is free'd by the function that also allocates it in the first place. Any downstream consumer of the xua_msg may interpret it, but not hold any references or free() it. Change-Id: I708505d129da5824c69b31a13a9c93201929bada --- M examples/sccp_test_server.c M examples/sccp_test_vty.c M src/m3ua.c M src/osmo_ss7_hmrt.c M src/sccp_sclc.c M src/sccp_scoc.c M src/sccp_scrc.c M src/sccp_user.c M src/sua.c 9 files changed, 33 insertions(+), 17 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/42/2242/3 diff --git a/examples/sccp_test_server.c b/examples/sccp_test_server.c index c3c658f..71bed96 100644 --- a/examples/sccp_test_server.c +++ b/examples/sccp_test_server.c @@ -34,6 +34,7 @@ oph->primitive, oph->operation); break; } + msgb_free(oph->msg); return 0; } @@ -71,6 +72,7 @@ oph->primitive, oph->operation); break; } + msgb_free(oph->msg); return 0; } @@ -102,6 +104,7 @@ oph->primitive, oph->operation); break; } + msgb_free(oph->msg); return 0; } diff --git a/examples/sccp_test_vty.c b/examples/sccp_test_vty.c index 1134d57..ddfbb27 100644 --- a/examples/sccp_test_vty.c +++ b/examples/sccp_test_vty.c @@ -125,6 +125,7 @@ default: break; } + msgb_free(oph->msg); return 0; } diff --git a/src/m3ua.c b/src/m3ua.c index 7437b6e..4f20c6e 100644 --- a/src/m3ua.c +++ b/src/m3ua.c @@ -420,13 +420,12 @@ * Transmitting M3UA messsages to SCTP ***********************************************************************/ +/* transmit given xua_msg via given ASP. callee takes xua ownership */ static int m3ua_tx_xua_asp(struct osmo_ss7_asp *asp, struct xua_msg *xua) { struct msgb *msg = xua_to_msg(M3UA_VERSION, xua); OSMO_ASSERT(asp->cfg.proto == OSMO_SS7_ASP_PROT_M3UA); - - xua_msg_free(xua); if (!msg) { LOGP(DLM3UA, LOGL_ERROR, "Error encoding M3UA Msg\n"); @@ -461,7 +460,6 @@ } if (!asp) { LOGP(DLM3UA, LOGL_ERROR, "No ASP entroy in AS, dropping message\n"); - xua_msg_free(xua); return -ENODEV; } diff --git a/src/osmo_ss7_hmrt.c b/src/osmo_ss7_hmrt.c index bc2b8e5..105a542 100644 --- a/src/osmo_ss7_hmrt.c +++ b/src/osmo_ss7_hmrt.c @@ -195,6 +195,7 @@ struct osmo_mtp_prim *omp) { struct xua_msg *xua; + int rc; OSMO_ASSERT(omp->oph.sap == MTP_SAP_USER); @@ -210,10 +211,15 @@ * is a very useful feature (aka "loopback device" in * IPv4). So we call m3ua_hmdc_rx_from_l2() just like * the MTP-TRANSFER had been received from L2. */ - return m3ua_hmdc_rx_from_l2(inst, xua); + rc = m3ua_hmdc_rx_from_l2(inst, xua); + xua_msg_free(xua); + break; default: LOGP(DLSS7, LOGL_ERROR, "Ignoring unknown primitive %u:%u\n", omp->oph.primitive, omp->oph.operation); - return -1; + rc = -1; } + + msgb_free(omp->oph.msg); + return rc; } diff --git a/src/sccp_sclc.c b/src/sccp_sclc.c index dae2c36..7cdfac5 100644 --- a/src/sccp_sclc.c +++ b/src/sccp_sclc.c @@ -102,12 +102,15 @@ struct osmo_scu_prim *prim, int msg_type) { struct xua_msg *xua; + int rc; xua = xua_gen_msg_cl(event, prim, msg_type); if (!xua) return -1; - return sccp_scrc_rx_sclc_msg(scu->inst, xua); + rc = sccp_scrc_rx_sclc_msg(scu->inst, xua); + xua_msg_free(xua); + return rc; } /*! \brief Main entrance function for primitives from SCCP User @@ -327,8 +330,8 @@ /* local originator: send N-NOTICE to user */ /* TODO: N-NOTICE.ind SCLC -> SCU */ sclc_rx_cldr(inst, xua_out); - xua_msg_free(xua_out); } + xua_msg_free(xua_out); break; case SUA_CL_CLDR: /* do nothing */ diff --git a/src/sccp_scoc.c b/src/sccp_scoc.c index cb592e6..b7ae38a 100644 --- a/src/sccp_scoc.c +++ b/src/sccp_scoc.c @@ -489,7 +489,9 @@ /* amend this with point code information; The SUA RELRE * includes neither called nor calling party address! */ xua->mtp.dpc = conn->remote_pc; - return sccp_scrc_rx_scoc_conn_msg(conn->inst, xua); + sccp_scrc_rx_scoc_conn_msg(conn->inst, xua); + xua_msg_free(xua); + return 0; } /* generate a 'struct xua_msg' of requested type from connection + @@ -623,7 +625,9 @@ /* amend this with point code information; Many CO msgs * includes neither called nor calling party address! */ xua->mtp.dpc = conn->remote_pc; - return sccp_scrc_rx_scoc_conn_msg(conn->inst, xua); + sccp_scrc_rx_scoc_conn_msg(conn->inst, xua); + xua_msg_free(xua); + return 0; } /* allocate a SCU primitive to be sent to the user */ diff --git a/src/sccp_scrc.c b/src/sccp_scrc.c index 0ab25cb..f9df075 100644 --- a/src/sccp_scrc.c +++ b/src/sccp_scrc.c @@ -384,8 +384,9 @@ return scrc_node_2(inst, xua, &called); /* TOOD: Coupling performed (not supported) */ - if (0) + if (0) { return scrc_node_2(inst, xua, &called); + } return scrc_local_out_common(inst, xua, &called); } @@ -412,6 +413,7 @@ return scrc_node_12(inst, xua, &called); } } + return scrc_local_out_common(inst, xua, &called); } @@ -450,8 +452,7 @@ if (hop_counter <= 1) { /* Error: hop-counter violation */ /* node 4 */ - return scrc_node_4(inst, xua, - SCCP_RETURN_CAUSE_HOP_COUNTER_VIOLATION); + return scrc_node_4(inst, xua, SCCP_RETURN_CAUSE_HOP_COUNTER_VIOLATION); } /* Decrement hop-counter */ hop_counter--; diff --git a/src/sccp_user.c b/src/sccp_user.c index bc03f4e..297d939 100644 --- a/src/sccp_user.c +++ b/src/sccp_user.c @@ -157,6 +157,7 @@ struct osmo_sccp_instance *inst = ctx; struct osmo_mtp_prim *omp = (struct osmo_mtp_prim *)oph; struct xua_msg *xua; + int rc; OSMO_ASSERT(oph->sap == MTP_SAP_USER); @@ -166,12 +167,14 @@ xua = osmo_sccp_to_xua(oph->msg); xua->mtp = omp->u.transfer; /* hand this primitive into SCCP via the SCRC code */ - return scrc_rx_mtp_xfer_ind_xua(inst, xua); + rc = scrc_rx_mtp_xfer_ind_xua(inst, xua); default: LOGP(DLSCCP, LOGL_ERROR, "Unknown primitive %u:%u receivd\n", oph->primitive, oph->operation); - return -1; + rc = -1; } + msgb_free(oph->msg); + return rc; } static LLIST_HEAD(sccp_instances); diff --git a/src/sua.c b/src/sua.c index 836e02e..d9e303b 100644 --- a/src/sua.c +++ b/src/sua.c @@ -258,8 +258,6 @@ OSMO_ASSERT(asp->cfg.proto == OSMO_SS7_ASP_PROT_SUA); - xua_msg_free(xua); - if (!msg) { LOGPASP(asp, DLSUA, LOGL_ERROR, "Error encoding SUA Msg\n"); return -1; @@ -290,7 +288,6 @@ } if (!asp) { LOGP(DLSUA, LOGL_ERROR, "No ASP in AS, dropping message\n"); - xua_msg_free(xua); return -ENODEV; } -- To view, visit https://gerrit.osmocom.org/2242 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I708505d129da5824c69b31a13a9c93201929bada Gerrit-PatchSet: 3 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:31:09 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:31:09 +0000 Subject: [PATCH] libosmo-sccp[master]: Add osmo_sccp_get_ss7() accessor function In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2243 to look at the new patch set (#3). Add osmo_sccp_get_ss7() accessor function as 'struct osmo_sccp_instance' is opaque to the user application, it is useful to have an accessor function that resolves the ss7 instance used by the SCCP instance. Change-Id: I8057a6d69584239b9781c5cece42066293ea1dd6 --- M include/osmocom/sigtran/sccp_sap.h M src/sccp_user.c 2 files changed, 6 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/43/2243/3 diff --git a/include/osmocom/sigtran/sccp_sap.h b/include/osmocom/sigtran/sccp_sap.h index a86f86a..fd25752 100644 --- a/include/osmocom/sigtran/sccp_sap.h +++ b/include/osmocom/sigtran/sccp_sap.h @@ -230,6 +230,7 @@ struct osmo_sccp_instance * osmo_sccp_instance_create(struct osmo_ss7_instance *ss7, void *priv); void osmo_sccp_instance_destroy(struct osmo_sccp_instance *inst); +struct osmo_ss7_instance *osmo_sccp_get_ss7(struct osmo_sccp_instance *sccp); void osmo_sccp_user_unbind(struct osmo_sccp_user *scu); void osmo_sccp_user_set_priv(struct osmo_sccp_user *scu, void *priv); diff --git a/src/sccp_user.c b/src/sccp_user.c index 297d939..9ed57d4 100644 --- a/src/sccp_user.c +++ b/src/sccp_user.c @@ -388,3 +388,8 @@ return NULL; } + +struct osmo_ss7_instance *osmo_sccp_get_ss7(struct osmo_sccp_instance *sccp) +{ + return sccp->ss7; +} -- To view, visit https://gerrit.osmocom.org/2243 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I8057a6d69584239b9781c5cece42066293ea1dd6 Gerrit-PatchSet: 3 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:31:09 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:31:09 +0000 Subject: [PATCH] libosmo-sccp[master]: m3ua_example: Add talloc reporting In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2244 to look at the new patch set (#3). m3ua_example: Add talloc reporting This can be used to check for memory leaks while running the example code. Change-Id: I87caa76a2be3c92c93e419242595107d744bad97 --- M examples/m3ua_example.c 1 file changed, 26 insertions(+), 5 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/44/2244/3 diff --git a/examples/m3ua_example.c b/examples/m3ua_example.c index d7b1fc2..07de7f3 100644 --- a/examples/m3ua_example.c +++ b/examples/m3ua_example.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #include @@ -20,6 +21,8 @@ #include "internal.h" +static struct osmo_sccp_instance *g_sccp; + static struct osmo_sccp_instance *sua_server_helper(void) { struct osmo_sccp_instance *sccp; @@ -36,6 +39,20 @@ /*********************************************************************** * Initialization ***********************************************************************/ + +static void signal_handler(int signal) +{ + fprintf(stdout, "signal %d received\n", signal); + + switch (signal) { + case SIGUSR1: + talloc_report_full(osmo_sccp_get_ss7(g_sccp), stderr); + break; + case SIGUSR2: + talloc_report_full(NULL, stderr); + break; + } +} static const struct log_info_cat log_info_cat[] = { }; @@ -63,9 +80,13 @@ int main(int argc, char **argv) { - struct osmo_sccp_instance *sccp; bool client; int rc; + + talloc_enable_leak_report_full(); + + signal(SIGUSR1, &signal_handler); + signal(SIGUSR2, &signal_handler); init_logging(); osmo_ss7_init(); @@ -85,11 +106,11 @@ if (client) { - sccp = osmo_sccp_simple_client(NULL, "client", 23, OSMO_SS7_ASP_PROT_M3UA, 0, M3UA_PORT, "127.0.0.2"); - sccp_test_user_vty_install(sccp, OSMO_SCCP_SSN_BSC_BSSAP); + g_sccp = osmo_sccp_simple_client(NULL, "client", 23, OSMO_SS7_ASP_PROT_M3UA, 0, M3UA_PORT, "127.0.0.2"); + sccp_test_user_vty_install(g_sccp, OSMO_SCCP_SSN_BSC_BSSAP); } else { - sccp = sua_server_helper(); - sccp_test_server_init(sccp); + g_sccp = sua_server_helper(); + sccp_test_server_init(g_sccp); } while (1) { -- To view, visit https://gerrit.osmocom.org/2244 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I87caa76a2be3c92c93e419242595107d744bad97 Gerrit-PatchSet: 3 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:31:09 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:31:09 +0000 Subject: [PATCH] libosmo-sccp[master]: osmo_ss7: Fix segfault when routing MTP-TRANSFER.req to ASP ... In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2245 to look at the new patch set (#3). osmo_ss7: Fix segfault when routing MTP-TRANSFER.req to ASP without sctp connection Change-Id: I142a11b09672864b54b927b8334b1975c8cd6022 --- M src/osmo_ss7.c 1 file changed, 13 insertions(+), 2 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/45/2245/3 diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index 8ec099a..f7f2519 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -1376,10 +1376,21 @@ OSMO_ASSERT(0); } - if (asp->cfg.is_server) + if (asp->cfg.is_server) { + if (!asp->server) { + LOGPASP(asp, DLSS7, LOGL_ERROR, "Cannot transmit, no asp->server\n"); + /* FIXME: what to do here? delete the route? send DUNA? */ + return -EIO; + } osmo_stream_srv_send(asp->server, msg); - else + } else { + if (!asp->client) { + LOGPASP(asp, DLSS7, LOGL_ERROR, "Cannot transmit, no asp->client\n"); + /* FIXME: what to do here? delete the route? send DUNA? */ + return -EIO; + } osmo_stream_cli_send(asp->client, msg); + } return 0; } -- To view, visit https://gerrit.osmocom.org/2245 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I142a11b09672864b54b927b8334b1975c8cd6022 Gerrit-PatchSet: 3 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:31:09 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:31:09 +0000 Subject: [PATCH] libosmo-sccp[master]: Allow clients to specify local IP/port In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2254 to look at the new patch set (#4). Allow clients to specify local IP/port Change-Id: Ief7ce8181442fd0f51c34cf598269ed3a6beacea --- M examples/m3ua_example.c M include/osmocom/sigtran/osmo_ss7.h M src/osmo_ss7.c M src/sccp_user.c 4 files changed, 9 insertions(+), 5 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/54/2254/4 diff --git a/examples/m3ua_example.c b/examples/m3ua_example.c index 07de7f3..d1247f5 100644 --- a/examples/m3ua_example.c +++ b/examples/m3ua_example.c @@ -106,7 +106,7 @@ if (client) { - g_sccp = osmo_sccp_simple_client(NULL, "client", 23, OSMO_SS7_ASP_PROT_M3UA, 0, M3UA_PORT, "127.0.0.2"); + g_sccp = osmo_sccp_simple_client(NULL, "client", 23, OSMO_SS7_ASP_PROT_M3UA, 0, NULL, M3UA_PORT, "127.0.0.2"); sccp_test_user_vty_install(g_sccp, OSMO_SCCP_SSN_BSC_BSSAP); } else { g_sccp = sua_server_helper(); diff --git a/include/osmocom/sigtran/osmo_ss7.h b/include/osmocom/sigtran/osmo_ss7.h index ebb7cb3..cbc6a02 100644 --- a/include/osmocom/sigtran/osmo_ss7.h +++ b/include/osmocom/sigtran/osmo_ss7.h @@ -402,10 +402,11 @@ void osmo_ss7_xua_server_destroy(struct osmo_xua_server *xs); + struct osmo_sccp_instance * osmo_sccp_simple_client(void *ctx, const char *name, uint32_t pc, - enum osmo_ss7_asp_protocol prot, - int local_port, int remote_port, const char *remote_ip); + enum osmo_ss7_asp_protocol prot, int local_port, + const char *local_ip, int remote_port, const char *remote_ip); struct osmo_sccp_instance * osmo_sccp_simple_server(void *ctx, uint32_t pc, diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index 9c886c4..103c05b 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -1046,6 +1046,8 @@ } osmo_stream_cli_set_addr(asp->client, asp->cfg.remote.host); osmo_stream_cli_set_port(asp->client, asp->cfg.remote.port); + osmo_stream_cli_set_local_addr(asp->client, asp->cfg.local.host); + osmo_stream_cli_set_local_port(asp->client, asp->cfg.local.port); osmo_stream_cli_set_proto(asp->client, IPPROTO_SCTP); osmo_stream_cli_set_reconnect_timeout(asp->client, 5); osmo_stream_cli_set_connect_cb(asp->client, xua_cli_connect_cb); diff --git a/src/sccp_user.c b/src/sccp_user.c index 9ed57d4..57c0038 100644 --- a/src/sccp_user.c +++ b/src/sccp_user.c @@ -230,8 +230,8 @@ struct osmo_sccp_instance * osmo_sccp_simple_client(void *ctx, const char *name, uint32_t pc, - enum osmo_ss7_asp_protocol prot, - int local_port, int remote_port, const char *remote_ip) + enum osmo_ss7_asp_protocol prot, int local_port, + const char *local_ip, int remote_port, const char *remote_ip) { struct osmo_ss7_instance *ss7; struct osmo_ss7_as *as; @@ -269,6 +269,7 @@ prot); if (!asp) goto out_rt; + asp->cfg.local.host = talloc_strdup(asp, local_ip); asp->cfg.remote.host = talloc_strdup(asp, remote_ip); osmo_ss7_as_add_asp(as, asp_name); talloc_free(asp_name); -- To view, visit https://gerrit.osmocom.org/2254 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ief7ce8181442fd0f51c34cf598269ed3a6beacea Gerrit-PatchSet: 4 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:31:09 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:31:09 +0000 Subject: [PATCH] libosmo-sccp[master]: sccp_scoc: Move osmo_prim_event_map to libosmocore In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2255 to look at the new patch set (#3). sccp_scoc: Move osmo_prim_event_map to libosmocore Change-Id: Ic1f22ae2e8d786bfe4bbb84e8eb9f8ae4d93d899 --- M src/sccp_scoc.c 1 file changed, 0 insertions(+), 30 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/55/2255/3 diff --git a/src/sccp_scoc.c b/src/sccp_scoc.c index b7ae38a..2585c9f 100644 --- a/src/sccp_scoc.c +++ b/src/sccp_scoc.c @@ -211,36 +211,6 @@ }; -/*! \brief magic value to be used as final record of \ref - * osmo_prim_event_map */ -#define OSMO_NO_EVENT 0xFFFFFFFF - -/*! \brief single entry in a SAP/PRIM/OP -> EVENT map */ -struct osmo_prim_event_map { - unsigned int sap; /*!< SAP to match */ - unsigned int primitive; /*!< primtiive to match */ - enum osmo_prim_operation operation; /*!< operation to match */ - uint32_t event; /*!< event as result if above match */ -}; - -/*! \brief resolve the (fsm) event for a given primitive using a map - * \param[in] oph primitive header used as key for match - * \param[in] maps list of mappings from primitive to event - * \returns event determined by map; \ref OSMO_NO_EVENT if no match */ -uint32_t osmo_event_for_prim(const struct osmo_prim_hdr *oph, - const struct osmo_prim_event_map *maps) -{ - const struct osmo_prim_event_map *map; - - for (map = maps; map->event != OSMO_NO_EVENT; map++) { - if (map->sap == oph->sap && - map->primitive == oph->primitive && - map->operation == oph->operation) - return map->event; - } - return OSMO_NO_EVENT; -} - /* map from SCU-primitives to SCOC FSM events */ static const struct osmo_prim_event_map scu_scoc_event_map[] = { { SCCP_SAP_USER, OSMO_SCU_PRIM_N_CONNECT, PRIM_OP_REQUEST, -- To view, visit https://gerrit.osmocom.org/2255 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ic1f22ae2e8d786bfe4bbb84e8eb9f8ae4d93d899 Gerrit-PatchSet: 3 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:31:09 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:31:09 +0000 Subject: [PATCH] libosmo-sccp[master]: protocol/m3ua.h: Add definition for RKM reg/dereg result codes In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2256 to look at the new patch set (#3). protocol/m3ua.h: Add definition for RKM reg/dereg result codes Change-Id: I16db7847e20501b89cc487029b29c8796b10bb84 --- M include/osmocom/sigtran/protocol/m3ua.h 1 file changed, 26 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/56/2256/3 diff --git a/include/osmocom/sigtran/protocol/m3ua.h b/include/osmocom/sigtran/protocol/m3ua.h index c10808c..7b8eadc 100644 --- a/include/osmocom/sigtran/protocol/m3ua.h +++ b/include/osmocom/sigtran/protocol/m3ua.h @@ -116,6 +116,32 @@ #define M3UA_NOTIFY_I_OT_ALT_ASP_ACT 2 #define M3UA_NOTIFY_I_OT_ASP_FAILURE 3 +/* 3.6.2 Registration Status */ +enum m3ua_rkm_reg_status { + M3UA_RKM_REG_SUCCESS = 0, + M3UA_RKM_REG_ERR_UNKNOWN = 1, + M3UA_RKM_REG_ERR_INVAL_DPC = 2, + M3UA_RKM_REG_ERR_INVAL_NET_APPEAR = 3, + M3UA_RKM_REG_ERR_INVAL_RKEY = 4, + M3UA_RKM_REG_ERR_PERM_DENIED = 5, + M3UA_RKM_REG_ERR_CANT_SUPP_UNQ_RT = 6, + M3UA_RKM_REG_ERR_RKEY_NOT_PROVD = 7, + M3UA_RKM_REG_ERR_INSUFF_RESRC = 8, + M3UA_RKM_REG_ERR_UNSUPP_RK_PARAM = 9, + M3UA_RKM_REG_ERR_UNSUPP_TRAF_MODE = 10, + M3UA_RKM_REG_ERR_RKEY_CHG_REFUSED = 11, + M3UA_RKM_REG_ERR_RKEY_ALRDY_REGD = 12, +}; + +enum m3ua_rkm_dereg_satus { + M3UA_RKM_DEREG_SUCCESS = 0, + M3UA_RKM_DEREG_ERR_UNKNOWN = 1, + M3UA_RKM_DEREG_ERR_INVAL_RCTX = 2, + M3UA_RKM_DEREG_ERR_PERM_DENIED = 3, + M3UA_RKM_DEREG_ERR_NOT_REGD = 4, + M3UA_RKM_DEREG_ERR_ASP_ACTIVE = 5, +}; + /* 3.8.1 Error */ enum m3ua_error_code { M3UA_ERR_INVALID_VERSION = 0x01, -- To view, visit https://gerrit.osmocom.org/2256 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I16db7847e20501b89cc487029b29c8796b10bb84 Gerrit-PatchSet: 3 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:31:09 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:31:09 +0000 Subject: [PATCH] libosmo-sccp[master]: Add osmo_ss7_find_free_rctx() function to get unused rctx In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2258 to look at the new patch set (#4). Add osmo_ss7_find_free_rctx() function to get unused rctx Change-Id: I0186e25a1b3a325c6b0e3f50ef1590c4de6dbef6 --- M include/osmocom/sigtran/osmo_ss7.h M src/osmo_ss7.c 2 files changed, 12 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/58/2258/4 diff --git a/include/osmocom/sigtran/osmo_ss7.h b/include/osmocom/sigtran/osmo_ss7.h index d765ae0..4eece3e 100644 --- a/include/osmocom/sigtran/osmo_ss7.h +++ b/include/osmocom/sigtran/osmo_ss7.h @@ -15,6 +15,7 @@ struct osmo_mtp_prim; int osmo_ss7_init(void); +int osmo_ss7_find_free_rctx(struct osmo_ss7_instance *inst); bool osmo_ss7_pc_is_local(struct osmo_ss7_instance *inst, uint32_t pc); int osmo_ss7_pointcode_parse(struct osmo_ss7_instance *inst, const char *str); diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index f7f2519..7909bfd 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -53,6 +53,7 @@ static LLIST_HEAD(ss7_instances); static LLIST_HEAD(ss7_xua_servers); +static int32_t next_rctx = 1; struct value_string osmo_ss7_as_traffic_mode_vals[] = { { OSMO_SS7_AS_TMOD_BCAST, "broadcast" }, @@ -72,6 +73,16 @@ #define LOGSS7(inst, level, fmt, args ...) \ LOGP(DLSS7, level, "%u: " fmt, (inst)->cfg.id, ## args) +int osmo_ss7_find_free_rctx(struct osmo_ss7_instance *inst) +{ + int32_t rctx; + + for (rctx = next_rctx; rctx; rctx = ++next_rctx) { + if (!osmo_ss7_as_find_by_rctx(inst, next_rctx)) + return rctx; + } + return -1; +} /*********************************************************************** * SS7 Point Code Parsing / Printing -- To view, visit https://gerrit.osmocom.org/2258 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I0186e25a1b3a325c6b0e3f50ef1590c4de6dbef6 Gerrit-PatchSet: 4 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:31:09 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:31:09 +0000 Subject: [PATCH] libosmo-sccp[master]: osmo_ss7: Add support for dynamic ASP registration In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2259 to look at the new patch set (#4). osmo_ss7: Add support for dynamic ASP registration if osmo_xua_server.cfg.accept_dyn_reg is set, then ASPs are permitted to connect without having a pre-configured matching ASP definition in the vty. This helps particularly in cases where RKM is used for dynamica registration of a RC (and hence AS). Change-Id: Ie48898202acbdbfe144fdd5851dfedbb554b11aa --- M include/osmocom/sigtran/osmo_ss7.h M src/osmo_ss7.c 2 files changed, 25 insertions(+), 8 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/59/2259/4 diff --git a/include/osmocom/sigtran/osmo_ss7.h b/include/osmocom/sigtran/osmo_ss7.h index 4eece3e..df85012 100644 --- a/include/osmocom/sigtran/osmo_ss7.h +++ b/include/osmocom/sigtran/osmo_ss7.h @@ -373,6 +373,7 @@ struct osmo_stream_srv_link *server; struct { + bool accept_dyn_reg; struct osmo_ss7_asp_peer local; enum osmo_ss7_asp_protocol proto; } cfg; diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index 7909bfd..4d3ced1 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -1345,15 +1345,31 @@ } asp = osmo_ss7_asp_find_by_socket_addr(fd); - if (!asp) { - LOGP(DLSS7, LOGL_NOTICE, "%s: SCTP connection without matching " - "ASP definition, terminating\n", sock_name); - osmo_stream_srv_destroy(srv); - talloc_free(sock_name); - return -1; + if (asp) { + LOGP(DLSS7, LOGL_INFO, "%s: matched connection to ASP %s\n", + sock_name, asp->cfg.name); + } else { + if (!oxs->cfg.accept_dyn_reg) { + LOGP(DLSS7, LOGL_NOTICE, "%s: SCTP connection without matching " + "ASP definition and no dynamic registration enabled, terminating\n", + sock_name); + } else { + char namebuf[32]; + static uint32_t dyn_asp_num = 0; + snprintf(namebuf, sizeof(namebuf), "asp-dyn-%u", dyn_asp_num++); + asp = osmo_ss7_asp_find_or_create(oxs->inst, NULL, 0, 0, + OSMO_SS7_ASP_PROT_M3UA); + if (asp) + LOGP(DLSS7, LOGL_INFO, "%s: created dynamicASP %s\n", + sock_name, asp->cfg.name); + } + if (!asp) { + osmo_stream_srv_destroy(srv); + talloc_free(sock_name); + return -1; + } } - LOGP(DLSS7, LOGL_INFO, "%s: matched connection to ASP %s\n", - sock_name, asp->cfg.name); + /* update the ASP reference back to the server over which the * connection came in */ asp->server = srv; -- To view, visit https://gerrit.osmocom.org/2259 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ie48898202acbdbfe144fdd5851dfedbb554b11aa Gerrit-PatchSet: 4 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:31:09 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:31:09 +0000 Subject: [PATCH] libosmo-sccp[master]: Add M3UA RKM (routing key management) support, SGW side only In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2260 to look at the new patch set (#5). Add M3UA RKM (routing key management) support, SGW side only Change-Id: I9b1cf438a42519c0fe2f555c1672fafa499122a1 --- M src/Makefile.am M src/m3ua.c M src/xua_internal.h A src/xua_rkm.c 4 files changed, 301 insertions(+), 2 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/60/2260/5 diff --git a/src/Makefile.am b/src/Makefile.am index a4cfeeb..7867282 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -28,7 +28,7 @@ libosmo_sigtran_la_SOURCES = sccp_sap.c sua.c m3ua.c xua_msg.c sccp_helpers.c \ sccp2sua.c sccp_scrc.c sccp_sclc.c sccp_scoc.c \ - sccp_user.c \ + sccp_user.c xua_rkm.c \ osmo_ss7.c osmo_ss7_hmrt.c xua_asp_fsm.c xua_as_fsm.c libosmo_sigtran_la_LDFLAGS = -version-info $(LIBVERSION) -no-undefined -export-symbols-regex '^osmo_' libosmo_sigtran_la_LIBADD = $(LIBOSMOCORE_LIBS) $(LIBOSMONETIF_LIBS) $(LIBSCTP_LIBS) diff --git a/src/m3ua.c b/src/m3ua.c index 4f20c6e..5708985 100644 --- a/src/m3ua.c +++ b/src/m3ua.c @@ -666,8 +666,10 @@ case M3UA_MSGC_MGMT: rc = m3ua_rx_mgmt(asp, xua); break; - case M3UA_MSGC_SNM: case M3UA_MSGC_RKM: + rc = m3ua_rx_rkm(asp, xua); + break; + case M3UA_MSGC_SNM: /* FIXME */ LOGPASP(asp, DLM3UA, LOGL_NOTICE, "Received unsupported M3UA " "Message Class %u\n", xua->hdr.msg_class); diff --git a/src/xua_internal.h b/src/xua_internal.h index c6f79b7..24fcb1c 100644 --- a/src/xua_internal.h +++ b/src/xua_internal.h @@ -58,3 +58,4 @@ struct xua_msg *m3ua_encode_notify(const struct m3ua_notify_params *npar); int m3ua_decode_notify(struct m3ua_notify_params *npar, void *ctx, const struct xua_msg *xua); +int m3ua_rx_rkm(struct osmo_ss7_asp *asp, struct xua_msg *xua); diff --git a/src/xua_rkm.c b/src/xua_rkm.c new file mode 100644 index 0000000..12d59c7 --- /dev/null +++ b/src/xua_rkm.c @@ -0,0 +1,296 @@ +/* xUA Routing Key Management (RKM) as per RFC 4666 */ +/* (C) 2017 by Harald Welte + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include + +#include +#include + +#include +#include +#include + +#include "xua_internal.h" + +/* push a M3UA header to the front of the given message */ +static void msgb_push_m3ua_hdr(struct msgb *msg, uint8_t msg_class, uint8_t msg_type) +{ + struct xua_common_hdr *hdr; + + msg->l2h = msgb_push(msg, sizeof(*hdr)); + hdr = (struct xua_common_hdr *) msg->l2h; + + hdr->version = M3UA_VERSION; + hdr->spare = 0; + hdr->msg_class = msg_class; + hdr->msg_type = msg_type; + hdr->msg_length = htonl(msgb_l2len(msg)); +} + +/* append a single registration result to given msgb */ +static int msgb_append_reg_res(struct msgb *msg, uint32_t local_rk_id, + uint32_t status, uint32_t rctx) +{ + uint8_t *old_tail = msg->tail; + + /* One individual Registration Result according to Chapter 3.6.2 */ + msgb_put_u16(msg, M3UA_IEI_REG_RESULT); /* outer IEI */ + msgb_put_u16(msg, 24 + 4); /* outer length */ + /* nested IEIs */ + msgb_t16l16vp_put_u32(msg, M3UA_IEI_LOC_RKEY_ID, local_rk_id); + msgb_t16l16vp_put_u32(msg, M3UA_IEI_REG_STATUS, status); + msgb_t16l16vp_put_u32(msg, M3UA_IEI_ROUTE_CTX, rctx); + + return msg->tail - old_tail; +} + +/* append a single de-registration result to given msgb */ +static int msgb_append_dereg_res(struct msgb *msg, + uint32_t status, uint32_t rctx) +{ + uint8_t *old_tail = msg->tail; + + /* One individual De-Registration Result according to Chapter 3.6.4 */ + msgb_put_u16(msg, M3UA_IEI_DEREG_RESULT); /* outer IEI */ + msgb_put_u16(msg, 16 + 4); /* outer length */ + /* nested IEIs */ + msgb_t16l16vp_put_u32(msg, M3UA_IEI_ROUTE_CTX, rctx); + msgb_t16l16vp_put_u32(msg, M3UA_IEI_DEREG_STATUS, status); + + return msg->tail - old_tail; +} + +/* handle a single registration request IE (nested IEs in 'innner' */ +static int handle_rkey_reg(struct osmo_ss7_asp *asp, struct xua_msg *inner, + struct msgb *resp) +{ + uint32_t rk_id, rctx, _tmode, dpc; + enum osmo_ss7_as_traffic_mode tmode; + struct osmo_ss7_as *as; + struct osmo_ss7_route *rt; + char namebuf[32]; + + /* mandatory local routing key ID */ + rk_id = xua_msg_get_u32(inner, M3UA_IEI_LOC_RKEY_ID); + /* ASP may already include a routing context value here */ + rctx = xua_msg_get_u32(inner, M3UA_IEI_ROUTE_CTX); + + /* traffic mode type (0 = undefined) */ + _tmode = xua_msg_get_u32(inner, M3UA_IEI_TRAF_MODE_TYP); + if (xua_msg_find_tag(inner, M3UA_IEI_TRAF_MODE_TYP) && _tmode != M3UA_TMOD_OVERRIDE && + _tmode != M3UA_TMOD_LOADSHARE && _tmode != M3UA_TMOD_BCAST) { + LOGPASP(asp, DLSS7, LOGL_NOTICE, "RKM: Invalid Traffic Mode %u\n", _tmode); + msgb_append_reg_res(resp, rk_id, M3UA_RKM_REG_ERR_UNSUPP_TRAF_MODE, 0); + return -1; + } + + tmode = osmo_ss7_tmode_from_xua(_tmode); + + /* destination point code (mandatory) */ + dpc = xua_msg_get_u32(inner, M3UA_IEI_DEST_PC); + + /* We don't support routing keys with the following criteria, so + * we have to reject those */ + /* TODO: network appearance (optional) */ + /* TODO: service indicators (optional) */ + /* TODO: originating point code list (optional) */ + if (xua_msg_find_tag(inner, M3UA_IEI_NET_APPEAR) || + xua_msg_find_tag(inner, M3UA_IEI_SVC_IND) || + xua_msg_find_tag(inner, M3UA_IEI_ORIG_PC)) { + LOGPASP(asp, DLSS7, LOGL_NOTICE, "RKM: Unsupported Routing Key\n"); + msgb_append_reg_res(resp, rk_id, M3UA_RKM_REG_ERR_UNSUPP_RK_PARAM, 0); + return -1; + } + + /* if the ASP did not include a routing context number, allocate + * one locally (will be part of response) */ + if (!rctx) + rctx = osmo_ss7_find_free_rctx(asp->inst); + + LOGPASP(asp, DLSS7, LOGL_INFO, "RKM: Registering routing key %u for DPC %s\n", + rctx, osmo_ss7_pointcode_print(asp->inst, dpc)); + + /* check if there is already an AS for this routing key */ + if (osmo_ss7_as_find_by_rctx(asp->inst, rctx)) { + LOGPASP(asp, DLSS7, LOGL_NOTICE, "RKM: RCTX %u already in use\n", rctx); + msgb_append_reg_res(resp, rk_id, M3UA_RKM_REG_ERR_RKEY_ALRDY_REGD, 0); + return -1; + } + + /* Create an AS for this routing key */ + snprintf(namebuf, sizeof(namebuf), "as-rkm-%u", rctx); + as = osmo_ss7_as_find_or_create(asp->inst, namebuf, OSMO_SS7_ASP_PROT_M3UA); + if (!as) { + LOGPASP(asp, DLSS7, LOGL_ERROR, "RKM: Cannot create AS %s\n", namebuf); + msgb_append_reg_res(resp, rk_id, M3UA_RKM_REG_ERR_INSUFF_RESRC, 0); + return -1; + } + + as->cfg.description = talloc_strdup(as, "Auto-generated by RKM"); + as->cfg.mode = tmode; + /* fill routing key */ + as->cfg.routing_key.context = rctx; + as->cfg.routing_key.pc = dpc; + + /* add route for that routing key */ + rt = osmo_ss7_route_create(as->inst->rtable_system, dpc, 0xFFFFFF, namebuf); + if (!rt) { + LOGPASP(asp, DLSS7, LOGL_ERROR, "RKM: Cannot insert route for DPC %s / as %s\n", + osmo_ss7_pointcode_print(asp->inst, dpc), namebuf); + osmo_ss7_as_destroy(as); + msgb_append_reg_res(resp, rk_id, M3UA_RKM_REG_ERR_CANT_SUPP_UNQ_RT, 0); + return -1; + } + + /* Success: Add just-create AS to connected ASP + report success */ + osmo_ss7_as_add_asp(as, asp->cfg.name); + msgb_append_reg_res(resp, rk_id, M3UA_RKM_REG_SUCCESS, rctx); + return 0; +} + +/* receive a registration requuest (SG role) */ +static int m3ua_rx_rkm_reg_req(struct osmo_ss7_asp *asp, struct xua_msg *xua) +{ + struct xua_msg_part *part; + struct msgb *resp = m3ua_msgb_alloc(__func__); + + /* iterate over all routing key IEs in message */ + llist_for_each_entry(part, &xua->headers, entry) { + struct xua_msg *inner; + + if (part->tag != M3UA_IEI_ROUT_KEY) + continue; + + inner = xua_from_nested(part); + if (!inner) { + LOGPASP(asp, DLSS7, LOGL_NOTICE, "RKM: Unable to parse " + "nested IE for Routing Key\n"); + continue; + } + /* handle single registration and append result to + * 'resp' */ + handle_rkey_reg(asp, inner, resp); + } + msgb_push_m3ua_hdr(resp, M3UA_MSGC_RKM, M3UA_RKM_REG_RSP); + osmo_ss7_asp_send(asp, resp); + + return 0; +} + +/* receive a deregistration requuest (SG role) */ +static int handle_rkey_dereg(struct osmo_ss7_asp *asp, uint32_t rctx, + struct msgb *resp) +{ + struct osmo_ss7_instance *inst = asp->inst; + struct osmo_ss7_as *as; + struct osmo_ss7_route *rt; + + as = osmo_ss7_as_find_by_rctx(inst, rctx); + if (!as) { + msgb_append_dereg_res(resp, M3UA_RKM_DEREG_ERR_INVAL_RCTX, 0); + return -1; + } + + /* Reject if ASP is not even part of AS */ + if (!osmo_ss7_as_has_asp(as, asp)) { + msgb_append_dereg_res(resp, M3UA_RKM_DEREG_ERR_INVAL_RCTX, 0); + return -1; + } + + /* FIXME Reject if any ASP stillactively using this RCTX */ + + rt = osmo_ss7_route_find_dpc(inst->rtable_system, as->cfg.routing_key.pc); + if (!rt) { + msgb_append_dereg_res(resp, M3UA_RKM_DEREG_ERR_UNKNOWN, 0); + return -1; + } + + LOGPASP(asp, DLSS7, LOGL_INFO, "RKM: De-Registering rctx %u for DPC %s\n", + rctx, osmo_ss7_pointcode_print(inst, as->cfg.routing_key.pc)); + + /* remove route + AS definition */ + osmo_ss7_route_destroy(rt); + osmo_ss7_as_destroy(as); + /* report success */ + msgb_append_dereg_res(resp, M3UA_RKM_DEREG_SUCCESS, rctx); + + return 0; +} + +static int m3ua_rx_rkm_dereg_req(struct osmo_ss7_asp *asp, struct xua_msg *xua) +{ + struct xua_msg_part *part = xua_msg_find_tag(xua, M3UA_IEI_ROUTE_CTX); + struct msgb *resp = m3ua_msgb_alloc(__func__); + uint32_t *rctx; + + if (!part) + return -1; + + for (rctx = (uint32_t *)part->dat; (uint8_t *)rctx < part->dat + part->len; rctx++) + handle_rkey_dereg(asp, ntohl(*rctx), resp); + + msgb_push_m3ua_hdr(resp, M3UA_MSGC_RKM, M3UA_RKM_DEREG_RSP); + osmo_ss7_asp_send(asp, resp); + + return 0; +} + +/* receive a registration response (ASP role) */ +static int m3ua_rx_rkm_reg_rsp(struct osmo_ss7_asp *asp, struct xua_msg *xua) +{ + /* TODO */ +} + +/* receive a deregistration response (ASP role) */ +static int m3ua_rx_rkm_dereg_rsp(struct osmo_ss7_asp *asp, struct xua_msg *xua) +{ + /* TODO */ +} + +/* process an incoming RKM message in xua format */ +int m3ua_rx_rkm(struct osmo_ss7_asp *asp, struct xua_msg *xua) +{ + int rc; + + switch (xua->hdr.msg_type) { + /* SG Side */ + case M3UA_RKM_REG_REQ: + /* TOOD: ensure we are role SG */ + rc = m3ua_rx_rkm_reg_req(asp, xua); + break; + case M3UA_RKM_DEREG_REQ: + /* TOOD: ensure we are role SG */ + rc = m3ua_rx_rkm_dereg_req(asp, xua); + break; + /* ASP Side */ + case M3UA_RKM_REG_RSP: + /* TOOD: ensure we are role ASP */ + rc = m3ua_rx_rkm_reg_rsp(asp, xua); + break; + case M3UA_RKM_DEREG_RSP: + /* TOOD: ensure we are role ASP */ + rc = m3ua_rx_rkm_dereg_rsp(asp, xua); + break; + default: + LOGPASP(asp, DLSS7, LOGL_ERROR, "Received unknown RKM msg_type %u\n", + xua->hdr.msg_type); + rc = -1; + break; + } + return rc; +} -- To view, visit https://gerrit.osmocom.org/2260 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I9b1cf438a42519c0fe2f555c1672fafa499122a1 Gerrit-PatchSet: 5 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:31:09 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:31:09 +0000 Subject: [PATCH] libosmo-sccp[master]: xua: move notfiy parameters from xua_internal to sigtran_sap... In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2261 to look at the new patch set (#5). xua: move notfiy parameters from xua_internal to sigtran_sap and rename them Change-Id: I295b9d6755a4bb52a817d2791a302bdd9fc775dd --- M include/osmocom/sigtran/sigtran_sap.h M src/m3ua.c M src/sua.c M src/xua_as_fsm.c M src/xua_asp_fsm.c M src/xua_internal.h 6 files changed, 55 insertions(+), 44 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/61/2261/5 diff --git a/include/osmocom/sigtran/sigtran_sap.h b/include/osmocom/sigtran/sigtran_sap.h index d29c37d..d18aa3d 100644 --- a/include/osmocom/sigtran/sigtran_sap.h +++ b/include/osmocom/sigtran/sigtran_sap.h @@ -1,6 +1,7 @@ #pragma once #include + enum osmo_sigtran_sap { SCCP_SAP_USER = _SAP_SS7_BASE, /* xUA Layer Manager */ @@ -29,10 +30,27 @@ OSMO_XLM_PRIM_M_RK_DEREG, }; +#define NOTIFY_PAR_P_ASP_ID (1 << 0) +#define NOTIFY_PAR_P_ROUTE_CTX (1 << 1) + +struct osmo_xlm_prim_notify { + uint32_t presence; + uint16_t status_type; + uint16_t status_info; + uint32_t asp_id; + uint32_t route_ctx; + char *info_string; +}; + +struct osmo_xlm_prim_error { + uint32_t code; +}; struct osmo_xlm_prim { struct osmo_prim_hdr oph; union { + struct osmo_xlm_prim_notify notify; + struct osmo_xlm_prim_error error; } u; }; diff --git a/src/m3ua.c b/src/m3ua.c index 031e5cd..0ec4529 100644 --- a/src/m3ua.c +++ b/src/m3ua.c @@ -350,7 +350,7 @@ ***********************************************************************/ /* RFC4666 Ch. 3.8.2. Notify */ -struct xua_msg *m3ua_encode_notify(const struct m3ua_notify_params *npar) +struct xua_msg *m3ua_encode_notify(const struct osmo_xlm_prim_notify *npar) { struct xua_msg *xua = xua_msg_alloc(); uint32_t status; @@ -379,7 +379,7 @@ } /* RFC4666 Ch. 3.8.2. Notify */ -int m3ua_decode_notify(struct m3ua_notify_params *npar, void *ctx, +int m3ua_decode_notify(struct osmo_xlm_prim_notify *npar, void *ctx, const struct xua_msg *xua) { struct xua_msg_part *info_ie, *aspid_ie, *status_ie, *rctx_ie; @@ -538,7 +538,7 @@ static int m3ua_rx_mgmt_ntfy(struct osmo_ss7_asp *asp, struct xua_msg *xua) { - struct m3ua_notify_params ntfy; + struct osmo_xlm_prim_notify ntfy; const char *type_name, *info_name; m3ua_decode_notify(&ntfy, asp, xua); diff --git a/src/sua.c b/src/sua.c index d9e303b..0f19bea 100644 --- a/src/sua.c +++ b/src/sua.c @@ -507,7 +507,7 @@ static int sua_rx_mgmt_ntfy(struct osmo_ss7_asp *asp, struct xua_msg *xua) { - struct m3ua_notify_params ntfy; + struct osmo_xlm_prim_notify ntfy; const char *type_name, *info_name; m3ua_decode_notify(&ntfy, asp, xua); diff --git a/src/xua_as_fsm.c b/src/xua_as_fsm.c index d73f793..740070b 100644 --- a/src/xua_as_fsm.c +++ b/src/xua_as_fsm.c @@ -25,7 +25,7 @@ #include "xua_as_fsm.h" #include "xua_internal.h" -static struct msgb *encode_notify(const struct m3ua_notify_params *npar) +static struct msgb *encode_notify(const struct osmo_xlm_prim_notify *npar) { struct xua_msg *xua = m3ua_encode_notify(npar); struct msgb *msg = xua_to_msg(M3UA_VERSION, xua); @@ -33,7 +33,7 @@ return msg; } -static int asp_notify_all_as(struct osmo_ss7_as *as, struct m3ua_notify_params *npar) +static int asp_notify_all_as(struct osmo_ss7_as *as, struct osmo_xlm_prim_notify *npar) { struct msgb *msg; unsigned int i, sent = 0; @@ -150,7 +150,7 @@ { struct xua_as_fsm_priv *xafp = (struct xua_as_fsm_priv *) fi->priv; struct osmo_ss7_as *as = xafp->as; - struct m3ua_notify_params npar = { + struct osmo_xlm_prim_notify npar = { .status_type = M3UA_NOTIFY_T_STATCHG, }; diff --git a/src/xua_asp_fsm.c b/src/xua_asp_fsm.c index aafc09f..d38a18a 100644 --- a/src/xua_asp_fsm.c +++ b/src/xua_asp_fsm.c @@ -89,42 +89,42 @@ } t_ack; }; -static struct msgb *xlm_msgb_alloc(void) +struct osmo_xlm_prim *xua_xlm_prim_alloc(enum osmo_xlm_prim_type prim_type, + enum osmo_prim_operation op) { - return msgb_alloc_headroom(2048+128, 128, "xua_asp-xlm msgb"); + struct osmo_xlm_prim *prim; + struct msgb *msg = msgb_alloc_headroom(2048+128, 128, "xua_asp-xlm msgb"); + if (!msg) + return NULL; + + prim = (struct osmo_xlm_prim *) msgb_put(msg, sizeof(*prim)); + osmo_prim_init(&prim->oph, XUA_SAP_LM, prim_type, op, msg); + + return prim; } /* Send a XUA LM Primitive to the XUA Layer Manager (LM) */ -static int send_xlm_prim(struct osmo_fsm_inst *fi, - enum osmo_xlm_prim_type prim_type, - enum osmo_prim_operation op, - const uint8_t *data, unsigned int data_len) +void xua_asp_send_xlm_prim(struct osmo_ss7_asp *asp, struct osmo_xlm_prim *prim) { - struct xua_asp_fsm_priv *xafp = fi->priv; - struct msgb *xlmsg; - struct osmo_xlm_prim *prim; + struct xua_asp_fsm_priv *xafp = asp->fi->priv; struct xua_layer_manager *lm = xafp->lm; - if (!lm || !lm->prim_cb) - return 0; + if (lm && lm->prim_cb) + lm->prim_cb(&prim->oph, xafp->asp); - xlmsg = xlm_msgb_alloc(); - if (!xlmsg) - return -ENOMEM; - prim = (struct osmo_xlm_prim *) msgb_put(xlmsg, sizeof(*prim)); - osmo_prim_init(&prim->oph, XUA_SAP_LM, prim_type, op, xlmsg); - - lm->prim_cb(&prim->oph, xafp->asp); - - return 0; + msgb_free(prim->oph.msg); } /* wrapper around send_xlm_prim for primitives without data */ -static int send_xlm_prim_simple(struct osmo_fsm_inst *fi, - enum osmo_xlm_prim_type prim, +static void send_xlm_prim_simple(struct osmo_fsm_inst *fi, + enum osmo_xlm_prim_type prim_type, enum osmo_prim_operation op) { - return send_xlm_prim(fi, prim, op, NULL, 0); + struct osmo_xlm_prim *prim = xua_xlm_prim_alloc(prim_type, op); + struct xua_asp_fsm_priv *xafp = fi->priv; + if (!prim) + return; + xua_asp_send_xlm_prim(xafp->asp, prim); } /* ask the xUA implementation to transmit a specific message */ diff --git a/src/xua_internal.h b/src/xua_internal.h index 24fcb1c..6a3f723 100644 --- a/src/xua_internal.h +++ b/src/xua_internal.h @@ -43,19 +43,12 @@ extern const struct value_string m3ua_ntfy_stchg_names[]; extern const struct value_string m3ua_ntfy_other_names[]; -#define NOTIFY_PAR_P_ASP_ID (1 << 0) -#define NOTIFY_PAR_P_ROUTE_CTX (1 << 1) - -struct m3ua_notify_params { - uint32_t presence; - uint16_t status_type; - uint16_t status_info; - uint32_t asp_id; - uint32_t route_ctx; - char *info_string; -}; - -struct xua_msg *m3ua_encode_notify(const struct m3ua_notify_params *npar); -int m3ua_decode_notify(struct m3ua_notify_params *npar, void *ctx, +struct xua_msg *m3ua_encode_notify(const struct osmo_xlm_prim_notify *npar); +int m3ua_decode_notify(struct osmo_xlm_prim_notify *npar, void *ctx, const struct xua_msg *xua); int m3ua_rx_rkm(struct osmo_ss7_asp *asp, struct xua_msg *xua); + +struct osmo_xlm_prim *xua_xlm_prim_alloc(enum osmo_xlm_prim_type prim_type, + enum osmo_prim_operation op); + +void xua_asp_send_xlm_prim(struct osmo_ss7_asp *asp, struct osmo_xlm_prim *prim); -- To view, visit https://gerrit.osmocom.org/2261 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I295b9d6755a4bb52a817d2791a302bdd9fc775dd Gerrit-PatchSet: 5 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:31:09 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:31:09 +0000 Subject: [PATCH] libosmo-sccp[master]: xua: report N-ERROR and N-NOTIFY primitives to layer manager In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2262 to look at the new patch set (#5). xua: report N-ERROR and N-NOTIFY primitives to layer manager Change-Id: I5c2060f0397d2bf510b085a5bb07e7ab176f2742 --- M src/m3ua.c 1 file changed, 12 insertions(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/62/2262/5 diff --git a/src/m3ua.c b/src/m3ua.c index 0ec4529..1868388 100644 --- a/src/m3ua.c +++ b/src/m3ua.c @@ -526,10 +526,16 @@ static int m3ua_rx_mgmt_err(struct osmo_ss7_asp *asp, struct xua_msg *xua) { uint32_t err_code = xua_msg_get_u32(xua, M3UA_IEI_ERR_CODE); + struct osmo_xlm_prim *prim; LOGPASP(asp, DLM3UA, LOGL_ERROR, "Received MGMT_ERR '%s': %s\n", get_value_string(m3ua_err_names, err_code), xua_msg_dump(xua, &xua_dialect_m3ua)); + + /* report this to layer manager */ + prim = xua_xlm_prim_alloc(OSMO_XLM_PRIM_M_ERROR, PRIM_OP_INDICATION); + prim->u.error.code = err_code; + xua_asp_send_xlm_prim(asp, prim); /* NEVER return != 0 here, as we cannot respont to an ERR * message with another ERR! */ @@ -540,6 +546,7 @@ { struct osmo_xlm_prim_notify ntfy; const char *type_name, *info_name; + struct osmo_xlm_prim *prim; m3ua_decode_notify(&ntfy, asp, xua); @@ -562,10 +569,14 @@ type_name, info_name, ntfy.info_string ? ntfy.info_string : ""); + /* report this to layer manager */ + prim = xua_xlm_prim_alloc(OSMO_XLM_PRIM_M_NOTIFY, PRIM_OP_INDICATION); + prim->u.notify = ntfy; + xua_asp_send_xlm_prim(asp,prim); + if (ntfy.info_string) talloc_free(ntfy.info_string); - /* TODO: should we report this soemwhere? */ return 0; } -- To view, visit https://gerrit.osmocom.org/2262 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I5c2060f0397d2bf510b085a5bb07e7ab176f2742 Gerrit-PatchSet: 5 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:31:09 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:31:09 +0000 Subject: [PATCH] libosmo-sccp[master]: move layer_manager from xua_asp_fsm priv to osmo_ss7_asp In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2263 to look at the new patch set (#5). move layer_manager from xua_asp_fsm priv to osmo_ss7_asp ... this way it is publicly accessible/reachable Change-Id: I00ec1689bfb068b9067d893fdba14d12d59f73f0 --- M include/osmocom/sigtran/osmo_ss7.h M src/xua_asp_fsm.c 2 files changed, 10 insertions(+), 9 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/63/2263/5 diff --git a/include/osmocom/sigtran/osmo_ss7.h b/include/osmocom/sigtran/osmo_ss7.h index df85012..56a3ea4 100644 --- a/include/osmocom/sigtran/osmo_ss7.h +++ b/include/osmocom/sigtran/osmo_ss7.h @@ -13,6 +13,7 @@ struct osmo_ss7_user; struct osmo_sccp_instance; struct osmo_mtp_prim; +struct osmo_xua_layer_manager; int osmo_ss7_init(void); int osmo_ss7_find_free_rctx(struct osmo_ss7_instance *inst); @@ -336,6 +337,9 @@ uint32_t asp_id; bool asp_id_present; + /* Layer Manager to which we talk */ + struct osmo_xua_layer_manager *lm; + struct { char *name; char *description; @@ -366,6 +370,10 @@ * xUA Servers ***********************************************************************/ +struct osmo_xua_layer_manager { + osmo_prim_cb prim_cb; +}; + struct osmo_xua_server { struct llist_head list; struct osmo_ss7_instance *inst; diff --git a/src/xua_asp_fsm.c b/src/xua_asp_fsm.c index d38a18a..e16e26a 100644 --- a/src/xua_asp_fsm.c +++ b/src/xua_asp_fsm.c @@ -67,18 +67,12 @@ { 0, NULL } }; -struct xua_layer_manager { - osmo_prim_cb prim_cb; -}; - /* private data structure for each FSM instance */ struct xua_asp_fsm_priv { /* pointer back to ASP to which we belong */ struct osmo_ss7_asp *asp; /* Role (ASP/SG/IPSP) */ enum xua_asp_role role; - /* Layer Manager to which we talk */ - struct xua_layer_manager *lm; /* routing context[s]: list of 32bit integers */ /* ACTIVE: traffic mode type, tid label, drn label ? */ @@ -106,11 +100,10 @@ /* Send a XUA LM Primitive to the XUA Layer Manager (LM) */ void xua_asp_send_xlm_prim(struct osmo_ss7_asp *asp, struct osmo_xlm_prim *prim) { - struct xua_asp_fsm_priv *xafp = asp->fi->priv; - struct xua_layer_manager *lm = xafp->lm; + struct osmo_xua_layer_manager *lm = asp->lm; if (lm && lm->prim_cb) - lm->prim_cb(&prim->oph, xafp->asp); + lm->prim_cb(&prim->oph, asp); msgb_free(prim->oph.msg); } -- To view, visit https://gerrit.osmocom.org/2263 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I00ec1689bfb068b9067d893fdba14d12d59f73f0 Gerrit-PatchSet: 5 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:31:09 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:31:09 +0000 Subject: [PATCH] libosmo-sccp[master]: send M-SCTP_ESTABLISH.ind to Layer Manager In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2264 to look at the new patch set (#5). send M-SCTP_ESTABLISH.ind to Layer Manager Change-Id: I2904f8ebd97036690ba8a9525b31354c0252123b --- M src/osmo_ss7.c M src/xua_asp_fsm.c M src/xua_internal.h 3 files changed, 25 insertions(+), 6 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/64/2264/5 diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index 4d3ced1..d657b81 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -1234,9 +1234,14 @@ LOGPASP(asp, DLSS7, LOGL_INFO, "Client connected %s\n", asp->sock_name); - /* Notify the ASP FSM that the connection has just been - * established */ - osmo_fsm_inst_dispatch(asp->fi, XUA_ASP_E_M_ASP_UP_REQ, NULL); + if (asp->lm && asp->lm->prim_cb) { + /* Notify layer manager that a connection has been + * established */ + xua_asp_send_xlm_prim_simple(asp, OSMO_XLM_PRIM_M_SCTP_ESTABLISH, PRIM_OP_INDICATION); + } else { + /* directly as the ASP FSM to start by sending an ASP-UP ... */ + osmo_fsm_inst_dispatch(asp->fi, XUA_ASP_E_M_ASP_UP_REQ, NULL); + } return 0; } @@ -1381,6 +1386,9 @@ * data */ osmo_stream_srv_set_data(srv, asp); + /* send M-SCTP_ESTABLISH.ind to Layer Manager */ + xua_asp_send_xlm_prim_simple(asp, OSMO_XLM_PRIM_M_SCTP_ESTABLISH, PRIM_OP_INDICATION); + return 0; } diff --git a/src/xua_asp_fsm.c b/src/xua_asp_fsm.c index e16e26a..1570bc9 100644 --- a/src/xua_asp_fsm.c +++ b/src/xua_asp_fsm.c @@ -109,15 +109,23 @@ } /* wrapper around send_xlm_prim for primitives without data */ -static void send_xlm_prim_simple(struct osmo_fsm_inst *fi, +void xua_asp_send_xlm_prim_simple(struct osmo_ss7_asp *asp, enum osmo_xlm_prim_type prim_type, enum osmo_prim_operation op) { struct osmo_xlm_prim *prim = xua_xlm_prim_alloc(prim_type, op); - struct xua_asp_fsm_priv *xafp = fi->priv; if (!prim) return; - xua_asp_send_xlm_prim(xafp->asp, prim); + xua_asp_send_xlm_prim(asp, prim); +} + +static void send_xlm_prim_simple(struct osmo_fsm_inst *fi, + enum osmo_xlm_prim_type prim_type, + enum osmo_prim_operation op) +{ + struct xua_asp_fsm_priv *xafp = fi->priv; + struct osmo_ss7_asp *asp = xafp->asp; + xua_asp_send_xlm_prim_simple(asp, prim_type, op); } /* ask the xUA implementation to transmit a specific message */ diff --git a/src/xua_internal.h b/src/xua_internal.h index 6a3f723..3921309 100644 --- a/src/xua_internal.h +++ b/src/xua_internal.h @@ -52,3 +52,6 @@ enum osmo_prim_operation op); void xua_asp_send_xlm_prim(struct osmo_ss7_asp *asp, struct osmo_xlm_prim *prim); +void xua_asp_send_xlm_prim_simple(struct osmo_ss7_asp *asp, + enum osmo_xlm_prim_type prim_type, + enum osmo_prim_operation op); -- To view, visit https://gerrit.osmocom.org/2264 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I2904f8ebd97036690ba8a9525b31354c0252123b Gerrit-PatchSet: 5 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:31:09 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:31:09 +0000 Subject: [PATCH] libosmo-sccp[master]: osmo_ss7: default point-code format for parsing/printing wit... In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2265 to look at the new patch set (#5). osmo_ss7: default point-code format for parsing/printing without ss7_instance osmo_ss7_pointcode_print() osmo_ss7_pointcode_parse() etc. now support passing a NULL ss7-instance which will lead to application of the default ITU 3.8.3 point code format. Change-Id: Ifb739e92e31eaaa0343dc57c9af8c9164d00175f --- M include/osmocom/sigtran/osmo_ss7.h M src/osmo_ss7.c 2 files changed, 43 insertions(+), 37 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/65/2265/5 diff --git a/include/osmocom/sigtran/osmo_ss7.h b/include/osmocom/sigtran/osmo_ss7.h index 56a3ea4..ebb7cb3 100644 --- a/include/osmocom/sigtran/osmo_ss7.h +++ b/include/osmocom/sigtran/osmo_ss7.h @@ -51,6 +51,11 @@ * SS7 Instances ***********************************************************************/ +struct osmo_ss7_pc_fmt { + char delimiter; + uint8_t component_len[3]; +}; + struct osmo_ss7_instance { /*! member of global list of instances */ struct llist_head list; @@ -78,10 +83,7 @@ /* secondary PCs */ /* capability PCs */ uint8_t network_indicator; - struct { - char delimiter; - uint8_t component_len[3]; - } pc_fmt; + struct osmo_ss7_pc_fmt pc_fmt; } cfg; }; diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index d657b81..d3b71e7 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -71,7 +71,7 @@ }; #define LOGSS7(inst, level, fmt, args ...) \ - LOGP(DLSS7, level, "%u: " fmt, (inst)->cfg.id, ## args) + LOGP(DLSS7, level, "%u: " fmt, inst ? (inst)->cfg.id : 0, ## args) int osmo_ss7_find_free_rctx(struct osmo_ss7_instance *inst) { @@ -87,6 +87,11 @@ /*********************************************************************** * SS7 Point Code Parsing / Printing ***********************************************************************/ + +static const struct osmo_ss7_pc_fmt default_pc_fmt = { + .delimiter = '.', + .component_len = { 3, 8, 3}, +}; /* like strcat() but appends a single character */ static int strnappendchar(char *str, char c, size_t n) @@ -104,7 +109,7 @@ /* generate a format string for formatting a point code. The result can * e.g. be used with sscanf() or sprintf() */ -static const char *gen_pc_fmtstr(struct osmo_ss7_instance *inst, +static const char *gen_pc_fmtstr(const struct osmo_ss7_pc_fmt *pc_fmt, unsigned int *num_comp_exp) { static char buf[MAX_PC_STR_LEN]; @@ -114,15 +119,15 @@ strcat(buf, "%u"); num_comp++; - if (inst->cfg.pc_fmt.component_len[1] == 0) + if (pc_fmt->component_len[1] == 0) goto out; - strnappendchar(buf, inst->cfg.pc_fmt.delimiter, sizeof(buf)); + strnappendchar(buf, pc_fmt->delimiter, sizeof(buf)); strcat(buf, "%u"); num_comp++; - if (inst->cfg.pc_fmt.component_len[2] == 0) + if (pc_fmt->component_len[2] == 0) goto out; - strnappendchar(buf, inst->cfg.pc_fmt.delimiter, sizeof(buf)); + strnappendchar(buf, pc_fmt->delimiter, sizeof(buf)); strcat(buf, "%u"); num_comp++; out: @@ -133,38 +138,35 @@ /* get number of components we expect for a point code, depending on the * configuration of this ss7_instance */ -static unsigned int num_pc_comp_exp(struct osmo_ss7_instance *inst) +static unsigned int num_pc_comp_exp(const struct osmo_ss7_pc_fmt *pc_fmt) { unsigned int num_comp_exp = 1; - if (inst->cfg.pc_fmt.component_len[1]) + if (pc_fmt->component_len[1]) num_comp_exp++; - if (inst->cfg.pc_fmt.component_len[2]) + if (pc_fmt->component_len[2]) num_comp_exp++; return num_comp_exp; } /* get the total width (in bits) of the point-codes in this ss7_instance */ -static unsigned int get_pc_width(struct osmo_ss7_instance *inst) +static unsigned int get_pc_width(const struct osmo_ss7_pc_fmt *pc_fmt) { - return inst->cfg.pc_fmt.component_len[0] + - inst->cfg.pc_fmt.component_len[1] + - inst->cfg.pc_fmt.component_len[2]; + return pc_fmt->component_len[0] + pc_fmt->component_len[1] + pc_fmt->component_len[2]; } /* get the number of bits we must shift the given component of a point * code in this ss7_instance */ -static unsigned int get_pc_comp_shift(struct osmo_ss7_instance *inst, +static unsigned int get_pc_comp_shift(const struct osmo_ss7_pc_fmt *pc_fmt, unsigned int comp_num) { - uint32_t pc_width = get_pc_width(inst); + uint32_t pc_width = get_pc_width(pc_fmt); switch (comp_num) { case 0: - return pc_width - inst->cfg.pc_fmt.component_len[0]; + return pc_width - pc_fmt->component_len[0]; case 1: - return pc_width - inst->cfg.pc_fmt.component_len[0] - - inst->cfg.pc_fmt.component_len[1]; + return pc_width - pc_fmt->component_len[0] - pc_fmt->component_len[1]; case 2: return 0; default: @@ -172,11 +174,11 @@ } } -static uint32_t pc_comp_shift_and_mask(struct osmo_ss7_instance *inst, +static uint32_t pc_comp_shift_and_mask(const struct osmo_ss7_pc_fmt *pc_fmt, unsigned int comp_num, uint32_t pc) { - unsigned int shift = get_pc_comp_shift(inst, comp_num); - uint32_t mask = (1 << inst->cfg.pc_fmt.component_len[comp_num]) - 1; + unsigned int shift = get_pc_comp_shift(pc_fmt, comp_num); + uint32_t mask = (1 << pc_fmt->component_len[comp_num]) - 1; return (pc >> shift) & mask; } @@ -186,8 +188,9 @@ int osmo_ss7_pointcode_parse(struct osmo_ss7_instance *inst, const char *str) { unsigned int component[3]; - unsigned int num_comp_exp = num_pc_comp_exp(inst); - const char *fmtstr = gen_pc_fmtstr(inst, &num_comp_exp); + const struct osmo_ss7_pc_fmt *pc_fmt = inst ? &inst->cfg.pc_fmt : &default_pc_fmt; + unsigned int num_comp_exp = num_pc_comp_exp(pc_fmt); + const char *fmtstr = gen_pc_fmtstr(pc_fmt, &num_comp_exp); int i, rc; rc = sscanf(str, fmtstr, &component[0], &component[1], &component[2]); @@ -198,16 +201,16 @@ /* check none of the component values exceeds what can be * represented within its bit-width */ for (i = 0; i < num_comp_exp; i++) { - if (component[i] >= (1 << inst->cfg.pc_fmt.component_len[i])) + if (component[i] >= (1 << pc_fmt->component_len[i])) goto err; } /* shift them all together */ - rc = (component[0] << get_pc_comp_shift(inst, 0)); + rc = (component[0] << get_pc_comp_shift(pc_fmt, 0)); if (num_comp_exp > 1) - rc |= (component[1] << get_pc_comp_shift(inst, 1)); + rc |= (component[1] << get_pc_comp_shift(pc_fmt, 1)); if (num_comp_exp > 2) - rc |= (component[2] << get_pc_comp_shift(inst, 2)); + rc |= (component[2] << get_pc_comp_shift(pc_fmt, 2)); return rc; @@ -221,21 +224,22 @@ const char *osmo_ss7_pointcode_print(struct osmo_ss7_instance *inst, uint32_t pc) { static char buf[MAX_PC_STR_LEN]; - unsigned int num_comp_exp = num_pc_comp_exp(inst); - const char *fmtstr = gen_pc_fmtstr(inst, &num_comp_exp); + const struct osmo_ss7_pc_fmt *pc_fmt = inst ? &inst->cfg.pc_fmt : &default_pc_fmt; + unsigned int num_comp_exp = num_pc_comp_exp(pc_fmt); + const char *fmtstr = gen_pc_fmtstr(pc_fmt, &num_comp_exp); OSMO_ASSERT(fmtstr); snprintf(buf, sizeof(buf), fmtstr, - pc_comp_shift_and_mask(inst, 0, pc), - pc_comp_shift_and_mask(inst, 1, pc), - pc_comp_shift_and_mask(inst, 2, pc)); + pc_comp_shift_and_mask(pc_fmt, 0, pc), + pc_comp_shift_and_mask(pc_fmt, 1, pc), + pc_comp_shift_and_mask(pc_fmt, 2, pc)); return buf; } int osmo_ss7_pointcode_parse_mask_or_len(struct osmo_ss7_instance *inst, const char *in) { - unsigned int width = get_pc_width(inst); + unsigned int width = get_pc_width(inst ? &inst->cfg.pc_fmt : &default_pc_fmt); if (in[0] == '/') { /* parse mask by length */ -- To view, visit https://gerrit.osmocom.org/2265 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ifb739e92e31eaaa0343dc57c9af8c9164d00175f Gerrit-PatchSet: 5 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:31:09 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:31:09 +0000 Subject: [PATCH] libosmo-sccp[master]: m3ua: Remove inbound routing context before routing In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2266 to look at the new patch set (#5). m3ua: Remove inbound routing context before routing After verifying the routing context of an incoming M3UA message, remove the routing context before passing into MTP routing. In the forwarding case, we might want to set a new routing context on the outbound link, and we don't want the routing context IE to show up twice. Change-Id: I7a534cb1da275369c70766c059aaae8157ce6833 --- M src/m3ua.c 1 file changed, 4 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/66/2266/5 diff --git a/src/m3ua.c b/src/m3ua.c index 1868388..92470d7 100644 --- a/src/m3ua.c +++ b/src/m3ua.c @@ -515,6 +515,10 @@ OSMO_ASSERT(dh); m3ua_dh_to_xfer_param(&xua->mtp, dh); + /* remove ROUTE_CTX as in the routing case we want to add a new + * routing context on the outbound side */ + xua_msg_free_tag(xua, M3UA_IEI_ROUTE_CTX); + return m3ua_hmdc_rx_from_l2(asp->inst, xua); out_err: if (err) -- To view, visit https://gerrit.osmocom.org/2266 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I7a534cb1da275369c70766c059aaae8157ce6833 Gerrit-PatchSet: 5 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:31:09 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:31:09 +0000 Subject: [PATCH] libosmo-sccp[master]: osmo_ss7: Fix msgb memory leaks in error paths (asp not conn... In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2267 to look at the new patch set (#5). osmo_ss7: Fix msgb memory leaks in error paths (asp not connected) Change-Id: I031d90348ea243ac5dbdde14365528f3ec8e3709 --- M src/osmo_ss7.c 1 file changed, 2 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/67/2267/5 diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index d3b71e7..9c886c4 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -1419,6 +1419,7 @@ if (!asp->server) { LOGPASP(asp, DLSS7, LOGL_ERROR, "Cannot transmit, no asp->server\n"); /* FIXME: what to do here? delete the route? send DUNA? */ + msgb_free(msg); return -EIO; } osmo_stream_srv_send(asp->server, msg); @@ -1426,6 +1427,7 @@ if (!asp->client) { LOGPASP(asp, DLSS7, LOGL_ERROR, "Cannot transmit, no asp->client\n"); /* FIXME: what to do here? delete the route? send DUNA? */ + msgb_free(msg); return -EIO; } osmo_stream_cli_send(asp->client, msg); -- To view, visit https://gerrit.osmocom.org/2267 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I031d90348ea243ac5dbdde14365528f3ec8e3709 Gerrit-PatchSet: 5 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:31:09 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:31:09 +0000 Subject: [PATCH] libosmo-sccp[master]: osmo_sccp_make_addr_pc_ssn(): Set routing indicator In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2268 to look at the new patch set (#5). osmo_sccp_make_addr_pc_ssn(): Set routing indicator When we crate a sccp address with PC+SSN, we should also set the routing indicator accordingly (OSMO_SCCP_RI_SSN_PC). Change-Id: Ie179df7158624520e90093da063c57f1e3efa0bd --- M src/sccp_helpers.c 1 file changed, 1 insertion(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/68/2268/5 diff --git a/src/sccp_helpers.c b/src/sccp_helpers.c index c588607..76a7c1c 100644 --- a/src/sccp_helpers.c +++ b/src/sccp_helpers.c @@ -39,6 +39,7 @@ void osmo_sccp_make_addr_pc_ssn(struct osmo_sccp_addr *addr, uint32_t pc, uint32_t ssn) { addr->presence = OSMO_SCCP_ADDR_T_SSN | OSMO_SCCP_ADDR_T_PC; + addr->ri = OSMO_SCCP_RI_SSN_PC; addr->ssn = ssn; addr->pc = pc; } -- To view, visit https://gerrit.osmocom.org/2268 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ie179df7158624520e90093da063c57f1e3efa0bd Gerrit-PatchSet: 5 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:31:09 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:31:09 +0000 Subject: [PATCH] libosmo-sccp[master]: M3UA: Respond with "Unexpected Message" if ASPTM is received... In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2269 to look at the new patch set (#5). M3UA: Respond with "Unexpected Message" if ASPTM is received too soon This was discovered (and fix validated) using m3ua-sgp-aspsm-i-003 of Michale Tuexen's m3ua-testtool. Change-Id: I8b63e7b5e39a7ef8dd66bf014110a04f5f3dc2a2 --- M src/m3ua.c 1 file changed, 2 insertions(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/69/2269/5 diff --git a/src/m3ua.c b/src/m3ua.c index 92470d7..14df269 100644 --- a/src/m3ua.c +++ b/src/m3ua.c @@ -623,7 +623,8 @@ return M3UA_ERR_UNSUPP_MSG_TYPE; /* deliver that event to the ASP FSM */ - osmo_fsm_inst_dispatch(asp->fi, event, xua); + if (osmo_fsm_inst_dispatch(asp->fi, event, xua) < 0) + return M3UA_ERR_UNEXPECTED_MSG; return 0; } -- To view, visit https://gerrit.osmocom.org/2269 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I8b63e7b5e39a7ef8dd66bf014110a04f5f3dc2a2 Gerrit-PatchSet: 5 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:31:09 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:31:09 +0000 Subject: [PATCH] libosmo-sccp[master]: M3UA: Make sure to reject unsupported traffic mode types In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2270 to look at the new patch set (#5). M3UA: Make sure to reject unsupported traffic mode types This was discovered (and fix validated) using m3ua-sgp-asptm-i-004 of Michael Tuexen's m3ua-testtool. Change-Id: I76c01189b75ff3084cd4d3944314ec9b9f811dbf --- M src/xua_asp_fsm.c 1 file changed, 32 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/70/2270/5 diff --git a/src/xua_asp_fsm.c b/src/xua_asp_fsm.c index 1570bc9..87f8927 100644 --- a/src/xua_asp_fsm.c +++ b/src/xua_asp_fsm.c @@ -210,6 +210,25 @@ return osmo_ss7_asp_send(asp, msg); } +static int peer_send_error(struct osmo_fsm_inst *fi, uint32_t err_code) +{ + struct xua_asp_fsm_priv *xafp = fi->priv; + struct osmo_ss7_asp *asp = xafp->asp; + struct xua_msg *xua = xua_msg_alloc(); + struct msgb *msg; + + xua->hdr = XUA_HDR(SUA_MSGC_MGMT, SUA_MGMT_ERR); + xua->hdr.version = SUA_VERSION; + xua_msg_add_u32(xua, SUA_IEI_ERR_CODE, err_code); + + msg = xua_to_msg(SUA_VERSION, xua); + xua_msg_free(xua); + if (!msg) + return -1; + + return osmo_ss7_asp_send(asp, msg); +} + static void xua_t_ack_cb(void *data) { struct osmo_fsm_inst *fi = data; @@ -373,6 +392,9 @@ static void xua_asp_fsm_inactive(struct osmo_fsm_inst *fi, uint32_t event, void *data) { + struct xua_msg *xua_in; + uint32_t traf_mode; + check_stop_t_ack(fi, event); switch (event) { case XUA_ASP_E_M_ASP_ACTIVE_REQ: @@ -400,8 +422,18 @@ PRIM_OP_CONFIRM); break; case XUA_ASP_E_ASPTM_ASPAC: + xua_in = data; /* only in role SG */ ENSURE_SG_OR_IPSP(fi, event); + if (xua_msg_find_tag(xua_in, M3UA_IEI_TRAF_MODE_TYP)) { + traf_mode = xua_msg_get_u32(xua_in, M3UA_IEI_TRAF_MODE_TYP); + if (traf_mode != M3UA_TMOD_OVERRIDE && + traf_mode != M3UA_TMOD_LOADSHARE && + traf_mode != M3UA_TMOD_BCAST) { + peer_send_error(fi, M3UA_ERR_UNSUPP_TRAF_MOD_TYP); + break; + } + } /* send ACK */ peer_send(fi, XUA_ASP_E_ASPTM_ASPAC_ACK, NULL); /* transition state and inform layer manager */ -- To view, visit https://gerrit.osmocom.org/2270 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I76c01189b75ff3084cd4d3944314ec9b9f811dbf Gerrit-PatchSet: 5 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:31:09 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:31:09 +0000 Subject: [PATCH] libosmo-sccp[master]: M3UA: Send "Unexpected Message" when receiving ASP_UP-ACK in... In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2271 to look at the new patch set (#5). M3UA: Send "Unexpected Message" when receiving ASP_UP-ACK in ACTIVE Change-Id: Ibcda68b7acb02bf1580a832baff06ff21cbac713 --- M src/xua_asp_fsm.c 1 file changed, 1 insertion(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/71/2271/5 diff --git a/src/xua_asp_fsm.c b/src/xua_asp_fsm.c index 87f8927..0996db0 100644 --- a/src/xua_asp_fsm.c +++ b/src/xua_asp_fsm.c @@ -527,10 +527,10 @@ * an Error message ("Unexpected Message), and the * remote ASP state is changed to ASP-INACTIVE in all * relevant Application Servers */ - /* FIXME: Send ERROR message */ osmo_fsm_inst_state_chg(fi, XUA_ASP_S_INACTIVE, 0, 0); send_xlm_prim_simple(fi, OSMO_XLM_PRIM_M_ASP_INACTIVE, PRIM_OP_INDICATION); + peer_send_error(fi, M3UA_ERR_UNEXPECTED_MSG); break; } } -- To view, visit https://gerrit.osmocom.org/2271 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ibcda68b7acb02bf1580a832baff06ff21cbac713 Gerrit-PatchSet: 5 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:31:09 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:31:09 +0000 Subject: [PATCH] libosmo-sccp[master]: M3UA: Send opportunistic ASPACT-ACK to ASPACT-REQ in ACTIVE ... In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2272 to look at the new patch set (#5). M3UA: Send opportunistic ASPACT-ACK to ASPACT-REQ in ACTIVE state This was discovered (and fix validated) using m3ua-sgp-asptm-o-001 of Michael Tuexen's m3ua-testtool. Change-Id: I6d254f7a33856e036329aa717a9c03efb1f1289d --- M src/xua_asp_fsm.c 1 file changed, 7 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/72/2272/5 diff --git a/src/xua_asp_fsm.c b/src/xua_asp_fsm.c index 0996db0..2e80506 100644 --- a/src/xua_asp_fsm.c +++ b/src/xua_asp_fsm.c @@ -532,6 +532,12 @@ PRIM_OP_INDICATION); peer_send_error(fi, M3UA_ERR_UNEXPECTED_MSG); break; + case XUA_ASP_E_ASPTM_ASPAC: + /* only in role SG */ + ENSURE_SG_OR_IPSP(fi, event); + /* send ACK */ + peer_send(fi, XUA_ASP_E_ASPTM_ASPAC_ACK, NULL); + break; } } @@ -601,6 +607,7 @@ S(XUA_ASP_E_ASPSM_ASPUP) | S(XUA_ASP_E_ASPTM_ASPIA) | S(XUA_ASP_E_ASPTM_ASPIA_ACK) | + S(XUA_ASP_E_ASPTM_ASPAC) | S(XUA_ASP_E_M_ASP_DOWN_REQ) | S(XUA_ASP_E_M_ASP_INACTIVE_REQ), .out_state_mask = S(XUA_ASP_S_INACTIVE) | -- To view, visit https://gerrit.osmocom.org/2272 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I6d254f7a33856e036329aa717a9c03efb1f1289d Gerrit-PatchSet: 5 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:31:09 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:31:09 +0000 Subject: [PATCH] libosmo-sccp[master]: M3UA: Handle opportunistic ASPIA in INACTIVE state In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2273 to look at the new patch set (#5). M3UA: Handle opportunistic ASPIA in INACTIVE state This was discovered (and fix validated) using m3ua-sgp-asptm-o-003 of Michale Tuexen's m3ua-testtool. Change-Id: If231072655170fe52dae738882dd63b1d0a60cf9 --- M src/xua_asp_fsm.c 1 file changed, 6 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/73/2273/5 diff --git a/src/xua_asp_fsm.c b/src/xua_asp_fsm.c index 2e80506..9c4a8ca 100644 --- a/src/xua_asp_fsm.c +++ b/src/xua_asp_fsm.c @@ -460,6 +460,11 @@ * is taken. */ peer_send(fi, XUA_ASP_E_ASPSM_ASPUP_ACK, NULL); break; + case XUA_ASP_E_ASPTM_ASPIA: + /* only in role SG */ + ENSURE_SG_OR_IPSP(fi, event); + peer_send(fi, XUA_ASP_E_ASPTM_ASPIA_ACK, NULL); + break; } } @@ -592,6 +597,7 @@ S(XUA_ASP_E_M_ASP_DOWN_REQ) | S(XUA_ASP_E_ASPTM_ASPAC) | S(XUA_ASP_E_ASPTM_ASPAC_ACK) | + S(XUA_ASP_E_ASPTM_ASPIA) | S(XUA_ASP_E_ASPSM_ASPDN) | S(XUA_ASP_E_ASPSM_ASPDN_ACK) | S(XUA_ASP_E_ASPSM_ASPUP), -- To view, visit https://gerrit.osmocom.org/2273 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: If231072655170fe52dae738882dd63b1d0a60cf9 Gerrit-PatchSet: 5 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:31:09 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:31:09 +0000 Subject: [PATCH] libosmo-sccp[master]: M3UA: Properly reject invalid/unknown routing context In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2274 to look at the new patch set (#5). M3UA: Properly reject invalid/unknown routing context This was discovered (and fix validated) using m3ua-sgp-asptm-i-005 of Michael Tuexne's m3ua-testtool. Change-Id: I217ae287e22371e36dda0f87a7737b62fb1bf2d6 --- M src/xua_asp_fsm.c 1 file changed, 9 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/74/2274/5 diff --git a/src/xua_asp_fsm.c b/src/xua_asp_fsm.c index 9c4a8ca..2830334 100644 --- a/src/xua_asp_fsm.c +++ b/src/xua_asp_fsm.c @@ -392,6 +392,8 @@ static void xua_asp_fsm_inactive(struct osmo_fsm_inst *fi, uint32_t event, void *data) { + struct xua_asp_fsm_priv *xafp = fi->priv; + struct osmo_ss7_asp *asp = xafp->asp; struct xua_msg *xua_in; uint32_t traf_mode; @@ -434,6 +436,13 @@ break; } } + if (xua_msg_find_tag(xua_in, M3UA_IEI_ROUTE_CTX)) { + uint32_t rctx = xua_msg_get_u32(xua_in, M3UA_IEI_ROUTE_CTX); + if (!osmo_ss7_as_find_by_rctx(asp->inst, rctx)) { + peer_send_error(fi, M3UA_ERR_INVAL_ROUT_CTX); + break; + } + } /* send ACK */ peer_send(fi, XUA_ASP_E_ASPTM_ASPAC_ACK, NULL); /* transition state and inform layer manager */ -- To view, visit https://gerrit.osmocom.org/2274 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I217ae287e22371e36dda0f87a7737b62fb1bf2d6 Gerrit-PatchSet: 5 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:31:09 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:31:09 +0000 Subject: [PATCH] libosmo-sccp[master]: M3UA: Ensure XFER messages are not sent on stream 0 In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2275 to look at the new patch set (#4). M3UA: Ensure XFER messages are not sent on stream 0 According to the RFC, Stream ID 0 MUST not be used for XFER/DATA messages. This was discovered (and fix validated) using m3ua-sgp-mtr-v-003-alternate of Michale Tuexen's m3ua-testtool. Change-Id: I80b941426b5106e091bd1becff0ae97958aff97c --- M src/m3ua.c 1 file changed, 9 insertions(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/75/2275/4 diff --git a/src/m3ua.c b/src/m3ua.c index 14df269..c29ed00 100644 --- a/src/m3ua.c +++ b/src/m3ua.c @@ -432,6 +432,10 @@ return -1; } + if (xua->hdr.msg_class == M3UA_MSGC_XFER) + msgb_sctp_stream(msg) = 1; + else + msgb_sctp_stream(msg) = 0; msgb_sctp_ppid(msg) = M3UA_PPID; return osmo_ss7_asp_send(asp, msg); } @@ -666,12 +670,16 @@ goto out; } - /* TODO: check for SCTP Strema ID */ /* TODO: check if any AS configured in ASP */ /* TODO: check for valid routing context */ switch (xua->hdr.msg_class) { case M3UA_MSGC_XFER: + /* The DATA message MUST NOT be sent on stream 0. */ + if (msgb_sctp_stream(msg) == 0) { + rc = M3UA_ERR_INVAL_STREAM_ID; + break; + } rc = m3ua_rx_xfer(asp, xua); break; case M3UA_MSGC_ASPSM: -- To view, visit https://gerrit.osmocom.org/2275 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I80b941426b5106e091bd1becff0ae97958aff97c Gerrit-PatchSet: 4 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:31:09 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:31:09 +0000 Subject: [PATCH] libosmo-sccp[master]: M3UA: Reject Message Class XFER / Type != DATA In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2276 to look at the new patch set (#4). M3UA: Reject Message Class XFER / Type != DATA This was discovered (and fix validated) using m3ua-sgp-mtr-i-003 of Michael Tuexen's m3ua-testtol. Change-Id: I7498f606b031f5a6dfb538d9900c744da6aed36f --- M src/m3ua.c 1 file changed, 3 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/76/2276/4 diff --git a/src/m3ua.c b/src/m3ua.c index c29ed00..9a56ff9 100644 --- a/src/m3ua.c +++ b/src/m3ua.c @@ -499,6 +499,9 @@ struct xua_msg *err = NULL; struct osmo_ss7_as *as; + if (xua->hdr.msg_type != M3UA_XFER_DATA) + return M3UA_ERR_UNSUPP_MSG_TYPE; + /* Use routing context IE to look up the AS for which the * message was received. */ as = osmo_ss7_as_find_by_rctx(asp->inst, rctx); -- To view, visit https://gerrit.osmocom.org/2276 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I7498f606b031f5a6dfb538d9900c744da6aed36f Gerrit-PatchSet: 4 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:31:09 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:31:09 +0000 Subject: [PATCH] libosmo-sccp[master]: m3ua: cosmetic clanup. We can simply return the M3UA errror... In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2277 to look at the new patch set (#4). m3ua: cosmetic clanup. We can simply return the M3UA errror code Change-Id: I6ed04a4f78e618938484aeab62dbcfb3f310998d --- M src/m3ua.c 1 file changed, 6 insertions(+), 15 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/77/2277/4 diff --git a/src/m3ua.c b/src/m3ua.c index 9a56ff9..7dc2afb 100644 --- a/src/m3ua.c +++ b/src/m3ua.c @@ -496,7 +496,6 @@ { uint32_t rctx = xua_msg_get_u32(xua, M3UA_IEI_ROUTE_CTX); struct m3ua_data_hdr *dh; - struct xua_msg *err = NULL; struct osmo_ss7_as *as; if (xua->hdr.msg_type != M3UA_XFER_DATA) @@ -505,15 +504,13 @@ /* Use routing context IE to look up the AS for which the * message was received. */ as = osmo_ss7_as_find_by_rctx(asp->inst, rctx); - if (!as) { - err = m3ua_gen_error(M3UA_ERR_INVAL_ROUT_CTX); - goto out_err; - } + if (!as) + return M3UA_ERR_INVAL_ROUT_CTX; + /* Verify that this ASP ix part of the AS. */ - if (!osmo_ss7_as_has_asp(as, asp)) { - err = m3ua_gen_error(M3UA_ERR_NO_CONFGD_AS_FOR_ASP); - goto out_err; - } + if (!osmo_ss7_as_has_asp(as, asp)) + return M3UA_ERR_NO_CONFGD_AS_FOR_ASP; + /* FIXME: check for AS state == ACTIVE */ /* store the MTP-level information in the xua_msg for use by @@ -527,11 +524,6 @@ xua_msg_free_tag(xua, M3UA_IEI_ROUTE_CTX); return m3ua_hmdc_rx_from_l2(asp->inst, xua); -out_err: - if (err) - m3ua_tx_xua_asp(asp, err); - - return -1; } static int m3ua_rx_mgmt_err(struct osmo_ss7_asp *asp, struct xua_msg *xua) @@ -688,7 +680,6 @@ case M3UA_MSGC_ASPSM: case M3UA_MSGC_ASPTM: rc = m3ua_rx_asp(asp, xua); - break; break; case M3UA_MSGC_MGMT: rc = m3ua_rx_mgmt(asp, xua); -- To view, visit https://gerrit.osmocom.org/2277 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I6ed04a4f78e618938484aeab62dbcfb3f310998d Gerrit-PatchSet: 4 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:31:09 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:31:09 +0000 Subject: [PATCH] libosmo-sccp[master]: xua_msg: Add xua_from_nested() helper function for nested IEs In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2279 to look at the new patch set (#2). xua_msg: Add xua_from_nested() helper function for nested IEs ... and add a test case to ensure it continues to work. Change-Id: Iee434886598b528d23ddce0490dcc782e0f5d6ae --- M include/osmocom/sigtran/xua_msg.h M src/xua_msg.c M tests/xua/xua_test.c M tests/xua/xua_test.ok 4 files changed, 86 insertions(+), 21 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/79/2279/2 diff --git a/include/osmocom/sigtran/xua_msg.h b/include/osmocom/sigtran/xua_msg.h index e0e1bcf..423adbc 100644 --- a/include/osmocom/sigtran/xua_msg.h +++ b/include/osmocom/sigtran/xua_msg.h @@ -82,6 +82,8 @@ struct xua_msg *xua_from_msg(const int version, uint16_t len, uint8_t *data); struct msgb *xua_to_msg(const int version, struct xua_msg *msg); +struct xua_msg *xua_from_nested(struct xua_msg_part *outer); + int msgb_t16l16vp_put(struct msgb *msg, uint16_t tag, uint16_t len, const uint8_t *data); int msgb_t16l16vp_put_u32(struct msgb *msg, uint16_t tag, uint32_t val); int xua_msg_add_u32(struct xua_msg *xua, uint16_t iei, uint32_t val); diff --git a/src/xua_msg.c b/src/xua_msg.c index cb487c8..05430a4 100644 --- a/src/xua_msg.c +++ b/src/xua_msg.c @@ -112,12 +112,39 @@ return xua_msg_add_data(xua_out, tag_out, part->len, part->dat); } -struct xua_msg *xua_from_msg(const int version, uint16_t len, uint8_t *data) +static int xua_from_msg_common(struct xua_msg *msg, const uint8_t *data, uint16_t pos, uint16_t len) { struct xua_parameter_hdr *par; + uint16_t par_len, padding; + int rc; + + while (pos + sizeof(*par) < len) { + par = (struct xua_parameter_hdr *) &data[pos]; + par_len = ntohs(par->len); + + if (pos + par_len > len || par_len < 4) + return -1; + + rc = xua_msg_add_data(msg, ntohs(par->tag), + par_len - 4, par->data); + if (rc != 0) + return -1; + + pos += par_len; + + /* move over the padding */ + padding = (4 - (par_len % 4)) & 0x3; + pos += padding; + } + + return 0; +} + +struct xua_msg *xua_from_msg(const int version, uint16_t len, uint8_t *data) +{ struct xua_common_hdr *hdr; struct xua_msg *msg; - uint16_t pos, par_len, padding; + uint16_t pos; int rc; msg = xua_msg_alloc(); @@ -136,31 +163,33 @@ msg->hdr = *hdr; pos = sizeof(*hdr); - while (pos + sizeof(*par) < len) { - par = (struct xua_parameter_hdr *) &data[pos]; - par_len = ntohs(par->len); + rc = xua_from_msg_common(msg, data, pos, len); + if (rc < 0) + goto fail; - if (pos + par_len > len || par_len < 4) - goto fail; - - rc = xua_msg_add_data(msg, ntohs(par->tag), - par_len - 4, par->data); - if (rc != 0) - goto fail; - - pos += par_len; - - /* move over the padding */ - padding = (4 - (par_len % 4)) & 0x3; - pos += padding; - } - - /* TODO: parse */ return msg; fail: xua_msg_free(msg); return NULL; + +} + +struct xua_msg *xua_from_nested(struct xua_msg_part *outer) +{ + struct xua_msg *msg = xua_msg_alloc(); + int rc; + + if (!msg) + return NULL; + + rc = xua_from_msg_common(msg, outer->dat, 0, outer->len); + if (rc < 0) { + xua_msg_free(msg); + return NULL; + } + + return msg; } struct msgb *xua_to_msg(const int version, struct xua_msg *xua) diff --git a/tests/xua/xua_test.c b/tests/xua/xua_test.c index 74d91c4..d1aa564 100644 --- a/tests/xua/xua_test.c +++ b/tests/xua/xua_test.c @@ -1,4 +1,5 @@ /* (C) 2011 by Holger Hans Peter Freyther + * (C) 2017 by Harald Welte * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by @@ -21,6 +22,7 @@ #include #include +#include #include #include @@ -355,6 +357,35 @@ } } +/* M3UA message with RKM-REG contents */ +static const uint8_t rkm_reg[] = { + 0x01, 0x00, 0x09, 0x01, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x04, 0x00, 0x0e, 0x4d, 0x33, 0x55, 0x41, + 0x20, 0x72, 0x6f, 0x63, 0x6b, 0x73, 0x00, 0x00, 0x02, 0x07, 0x00, 0x14, 0x02, 0x0a, 0x00, 0x08, + 0x00, 0x00, 0x00, 0x01, 0x02, 0x0b, 0x00, 0x08, 0x00, 0x00, 0x00, 0x17, +}; + +static void test_rkm(void) +{ + struct xua_msg *xua, *nested; + struct xua_msg_part *rkey; + + printf("Parsing M3UA Message\n"); + xua = xua_from_msg(M3UA_VERSION, sizeof(rkm_reg), (uint8_t *)rkm_reg); + OSMO_ASSERT(xua); + OSMO_ASSERT(xua->hdr.msg_class == M3UA_MSGC_RKM); + OSMO_ASSERT(xua->hdr.msg_type == M3UA_RKM_REG_REQ); + OSMO_ASSERT(xua_msg_find_tag(xua, M3UA_IEI_INFO_STRING)); + rkey = xua_msg_find_tag(xua, M3UA_IEI_ROUT_KEY); + OSMO_ASSERT(rkey); + OSMO_ASSERT(rkey->len == 16); + + printf("Parsing Nested M3UA Routing Key IE\n"); + nested = xua_from_nested(rkey); + OSMO_ASSERT(nested); + OSMO_ASSERT(xua_msg_get_u32(nested, M3UA_IEI_LOC_RKEY_ID) == 1); + OSMO_ASSERT(xua_msg_get_u32(nested, M3UA_IEI_DEST_PC) == 23); +} + static const struct log_info_cat default_categories[] = { [0] = { @@ -380,6 +411,7 @@ test_sccp_addr_parser(); test_helpers(); test_sccp2sua(); + test_rkm(); printf("All tests passed.\n"); return 0; diff --git a/tests/xua/xua_test.ok b/tests/xua/xua_test.ok index a9fba1d..2184902 100644 --- a/tests/xua/xua_test.ok +++ b/tests/xua/xua_test.ok @@ -128,4 +128,6 @@ PART(T=Data,L=154,D=6581974804260001984904510103df6c8188a181850201440201073080a780a08004012b30803012830110840107850791445776671697860120300682011884010400000000a306040142840105a306040151840105a306040131840105a309040112840105820102a309040111840105810101a306040114840100a30b0401418401043003830110a30b040141840104300382011800000000) Re-Encoding decoded SUA to SCCP SCCP Output: 09 81 03 0d 18 0a 12 07 00 12 04 53 84 09 00 17 0b 12 06 00 12 04 44 87 20 00 20 65 9a 65 81 97 48 04 26 00 01 98 49 04 51 01 03 df 6c 81 88 a1 81 85 02 01 44 02 01 07 30 80 a7 80 a0 80 04 01 2b 30 80 30 12 83 01 10 84 01 07 85 07 91 44 57 76 67 16 97 86 01 20 30 06 82 01 18 84 01 04 00 00 00 00 a3 06 04 01 42 84 01 05 a3 06 04 01 51 84 01 05 a3 06 04 01 31 84 01 05 a3 09 04 01 12 84 01 05 82 01 02 a3 09 04 01 11 84 01 05 81 01 01 a3 06 04 01 14 84 01 00 a3 0b 04 01 41 84 01 04 30 03 83 01 10 a3 0b 04 01 41 84 01 04 30 03 82 01 18 00 00 00 00 +Parsing M3UA Message +Parsing Nested M3UA Routing Key IE All tests passed. -- To view, visit https://gerrit.osmocom.org/2279 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Iee434886598b528d23ddce0490dcc782e0f5d6ae Gerrit-PatchSet: 2 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:31:09 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:31:09 +0000 Subject: [PATCH] libosmo-sccp[master]: M3UA: RKM DEREG-REQ should contain routing context, not rout... In-Reply-To: References: Message-ID: M3UA: RKM DEREG-REQ should contain routing context, not routing key The mandatory IE checking is requiring the wrong IE Change-Id: I73ecd163e2143341687ee4bca15a0bc69719c594 --- M src/m3ua.c 1 file changed, 1 insertion(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/80/2280/2 diff --git a/src/m3ua.c b/src/m3ua.c index 5708985..031e5cd 100644 --- a/src/m3ua.c +++ b/src/m3ua.c @@ -241,7 +241,7 @@ M3UA_IEI_REG_RESULT, 0 }; static const uint16_t dereg_req_ies[] = { - M3UA_IEI_ROUT_KEY, 0 + M3UA_IEI_ROUTE_CTX, 0 }; static const uint16_t dereg_rsp_ies[] = { M3UA_IEI_DEREG_RESULT, 0 -- To view, visit https://gerrit.osmocom.org/2280 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I73ecd163e2143341687ee4bca15a0bc69719c594 Gerrit-PatchSet: 2 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:31:55 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:31:55 +0000 Subject: libosmo-sccp[master]: Replace unused m3ua_types.h with protocol/m3ua.h In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2191 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I4a32cb698d28b4ccff9280b8512557ab5a353fe3 Gerrit-PatchSet: 2 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:34:27 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:34:27 +0000 Subject: libosmo-sccp[master]: Add M3UA RKM (routing key management) support, SGW side only In-Reply-To: References: Message-ID: Patch Set 5: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2260 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I9b1cf438a42519c0fe2f555c1672fafa499122a1 Gerrit-PatchSet: 5 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:40:07 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:40:07 +0000 Subject: libosmo-sccp[master]: M3UA: RKM DEREG-REQ should contain routing context, not rout... In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2280 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I73ecd163e2143341687ee4bca15a0bc69719c594 Gerrit-PatchSet: 2 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:42:58 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:42:58 +0000 Subject: libosmocore[master]: Add osmo_sock_init2() function, allowing both BIND *and* CON... In-Reply-To: References: Message-ID: Patch Set 1: > I think it might be related to jails again? That 127.0.0.1 is > remapped to another IPv4 address on the loopback? The "network > namespaces" ("VIMAGE") don't seem be ready in FreeBSD yet. > > You had a similar issue for another network test. Do you remember > or should I search for it? I made that test at the time very unspecific, i.e. pass with a less strict check, which is of course less than desirable. I'll probably simply go ahead and #ifdef the curent test out on FreeBSD. -- To view, visit https://gerrit.osmocom.org/2250 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Idab124bcca47872f55311a82d6818aed590965e6 Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:46:32 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:46:32 +0000 Subject: [PATCH] libosmocore[master]: Add osmo_sock_init2() function, allowing both BIND *and* CON... In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2250 to look at the new patch set (#2). Add osmo_sock_init2() function, allowing both BIND *and* CONNECT The old osmo_sock_init() function allows only either a bind (for a server socket), or a connect (for a client socket), but not both together. So there's no way to have a client socket that is bound to a specific local IP and/or port, which is needed for some use cases. Change-Id: Idab124bcca47872f55311a82d6818aed590965e6 --- M include/osmocom/core/socket.h M src/socket.c M tests/socket/socket_test.c M tests/socket/socket_test.err M tests/socket/socket_test.ok 5 files changed, 248 insertions(+), 33 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/50/2250/2 diff --git a/include/osmocom/core/socket.h b/include/osmocom/core/socket.h index 4f00e30..e19e8f2 100644 --- a/include/osmocom/core/socket.h +++ b/include/osmocom/core/socket.h @@ -24,6 +24,10 @@ int osmo_sock_init(uint16_t family, uint16_t type, uint8_t proto, const char *host, uint16_t port, unsigned int flags); +int osmo_sock_init2(uint16_t family, uint16_t type, uint8_t proto, + const char *local_host, uint16_t local_port, + const char *remote_host, uint16_t remote_port, unsigned int flags); + int osmo_sock_init_ofd(struct osmo_fd *ofd, int family, int type, int proto, const char *host, uint16_t port, unsigned int flags); diff --git a/src/socket.c b/src/socket.c index 2c1b547..ad0f69b 100644 --- a/src/socket.c +++ b/src/socket.c @@ -51,6 +51,188 @@ #include #include +static struct addrinfo *addrinfo_helper(uint16_t family, uint16_t type, uint8_t proto, + const char *host, uint16_t port, bool passive) +{ + struct addrinfo hints, *result; + char portbuf[16]; + int rc; + + snprintf(portbuf, sizeof(portbuf), "%u", port); + memset(&hints, 0, sizeof(struct addrinfo)); + hints.ai_family = family; + if (type == SOCK_RAW) { + /* Workaround for glibc, that returns EAI_SERVICE (-8) if + * SOCK_RAW and IPPROTO_GRE is used. + */ + hints.ai_socktype = SOCK_DGRAM; + hints.ai_protocol = IPPROTO_UDP; + } else { + hints.ai_socktype = type; + hints.ai_protocol = proto; + } + + if (passive) + hints.ai_flags |= AI_PASSIVE; + + rc = getaddrinfo(host, portbuf, &hints, &result); + if (rc != 0) { + LOGP(DLGLOBAL, LOGL_ERROR, "getaddrinfo returned NULL: %s:%u: %s\n", + host, port, strerror(errno)); + return NULL; + } + + return result; +} + +static int socket_helper(const struct addrinfo *rp, unsigned int flags) +{ + int sfd, on = 1; + + sfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); + if (sfd == -1) + return sfd; + if (flags & OSMO_SOCK_F_NONBLOCK) { + if (ioctl(sfd, FIONBIO, (unsigned char *)&on) < 0) { + LOGP(DLGLOBAL, LOGL_ERROR, + "cannot set this socket unblocking: %s\n", + strerror(errno)); + close(sfd); + sfd = -EINVAL; + } + } + return sfd; +} + + +/*! \brief Initialize a socket (including bind and/or connect) + * \param[in] family Address Family like AF_INET, AF_INET6, AF_UNSPEC + * \param[in] type Socket type like SOCK_DGRAM, SOCK_STREAM + * \param[in] proto Protocol like IPPROTO_TCP, IPPROTO_UDP + * \param[in] local_host local host name or IP address in string form + * \param[in] local_port local port number in host byte order + * \param[in] remote_host remote host name or IP address in string form + * \param[in] remote_port remote port number in host byte order + * \param[in] flags flags like \ref OSMO_SOCK_F_CONNECT + * \returns socket file descriptor on success; negative on error + * + * This function creates a new socket of the designated \a family, \a + * type and \a proto and optionally binds it to the \a local_host and \a + * local_port as well as optionally connects it to the \a remote_host + * and \q remote_port, depending on the value * of \a flags parameter. + * + * As opposed to \ref osmo_sock_init(), this function allows to combine + * the \ref OSMO_SOCK_F_BIND and \ref OSMO_SOCK_F_CONNECT flags. This + * is useful if you want to connect to a remote host/port, but still + * want to bind that socket to either a specific local alias IP and/or a + * specific local source port. + * + * You must specify either \ref OSMO_SOCK_F_BIND, or \ref + * OSMO_SOCK_F_CONNECT, or both. + * + * If \ref OSMO_SOCK_F_NONBLOCK is specified, the socket will be set to + * non-blocking mode. + */ +int osmo_sock_init2(uint16_t family, uint16_t type, uint8_t proto, + const char *local_host, uint16_t local_port, + const char *remote_host, uint16_t remote_port, unsigned int flags) +{ + struct addrinfo *result, *rp; + int sfd = -1, rc, on = 1; + + if ((flags & (OSMO_SOCK_F_BIND | OSMO_SOCK_F_CONNECT)) == 0) { + LOGP(DLGLOBAL, LOGL_ERROR, "invalid: you have to specify either " + "BIND or CONNECT flags\n"); + return -EINVAL; + } + + /* figure out local side of socket */ + if (flags & OSMO_SOCK_F_BIND) { + result = addrinfo_helper(family, type, proto, local_host, local_port, true); + if (!result) + return -EINVAL; + + for (rp = result; rp != NULL; rp = rp->ai_next) { + /* Workaround for glibc again */ + if (type == SOCK_RAW) { + rp->ai_socktype = SOCK_RAW; + rp->ai_protocol = proto; + } + + sfd = socket_helper(rp, flags); + if (sfd < 0) + continue; + + rc = setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, + &on, sizeof(on)); + if (rc < 0) { + LOGP(DLGLOBAL, LOGL_ERROR, + "cannot setsockopt socket:" + " %s:%u: %s\n", + local_host, local_port, strerror(errno)); + break; + } + if (bind(sfd, rp->ai_addr, rp->ai_addrlen) != -1) + break; + close(sfd); + } + freeaddrinfo(result); + if (rp == NULL) { + LOGP(DLGLOBAL, LOGL_ERROR, "unable to bind socket: %s:%u: %s\n", + local_host, local_port, strerror(errno)); + return -ENODEV; + } + } + + /* figure out remote side of socket */ + if (flags & OSMO_SOCK_F_CONNECT) { + result = addrinfo_helper(family, type, proto, remote_host, remote_port, false); + if (!result) { + close(sfd); + return -EINVAL; + } + + for (rp = result; rp != NULL; rp = rp->ai_next) { + /* Workaround for glibc again */ + if (type == SOCK_RAW) { + rp->ai_socktype = SOCK_RAW; + rp->ai_protocol = proto; + } + + if (!sfd) { + sfd = socket_helper(rp, flags); + if (sfd < 0) + continue; + } + + rc = connect(sfd, rp->ai_addr, rp->ai_addrlen); + if (rc != -1 || (rc == -1 && errno == EINPROGRESS)) + break; + + close(sfd); + sfd = -1; + } + freeaddrinfo(result); + if (rp == NULL) { + LOGP(DLGLOBAL, LOGL_ERROR, "unable to connect socket: %s:%u: %s\n", + remote_host, remote_port, strerror(errno)); + return -ENODEV; + } + } + + /* Make sure to call 'listen' on a bound, connection-oriented sock */ + if ((flags & (OSMO_SOCK_F_BIND|OSMO_SOCK_F_CONNECT)) == OSMO_SOCK_F_BIND) { + switch (type) { + case SOCK_STREAM: + case SOCK_SEQPACKET: + listen(sfd, 10); + break; + } + } + return sfd; +} + + /*! \brief Initialize a socket (including bind/connect) * \param[in] family Address Family like AF_INET, AF_INET6, AF_UNSPEC * \param[in] type Socket type like SOCK_DGRAM, SOCK_STREAM @@ -67,9 +249,8 @@ int osmo_sock_init(uint16_t family, uint16_t type, uint8_t proto, const char *host, uint16_t port, unsigned int flags) { - struct addrinfo hints, *result, *rp; + struct addrinfo *result, *rp; int sfd, rc, on = 1; - char portbuf[16]; if ((flags & (OSMO_SOCK_F_BIND | OSMO_SOCK_F_CONNECT)) == (OSMO_SOCK_F_BIND | OSMO_SOCK_F_CONNECT)) { @@ -78,25 +259,8 @@ return -EINVAL; } - sprintf(portbuf, "%u", port); - memset(&hints, 0, sizeof(struct addrinfo)); - hints.ai_family = family; - if (type == SOCK_RAW) { - /* Workaround for glibc, that returns EAI_SERVICE (-8) if - * SOCK_RAW and IPPROTO_GRE is used. - */ - hints.ai_socktype = SOCK_DGRAM; - hints.ai_protocol = IPPROTO_UDP; - } else { - hints.ai_socktype = type; - hints.ai_protocol = proto; - } - - if (flags & OSMO_SOCK_F_BIND) - hints.ai_flags |= AI_PASSIVE; - - rc = getaddrinfo(host, portbuf, &hints, &result); - if (rc != 0) { + result = addrinfo_helper(family, type, proto, host, port, flags & OSMO_SOCK_F_BIND); + if (!result) { LOGP(DLGLOBAL, LOGL_ERROR, "getaddrinfo returned NULL: %s:%u: %s\n", host, port, strerror(errno)); return -EINVAL; @@ -109,20 +273,10 @@ rp->ai_protocol = proto; } - sfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); + sfd = socket_helper(rp, flags); if (sfd == -1) continue; - if (flags & OSMO_SOCK_F_NONBLOCK) { - if (ioctl(sfd, FIONBIO, (unsigned char *)&on) < 0) { - LOGP(DLGLOBAL, LOGL_ERROR, - "cannot set this socket unblocking:" - " %s:%u: %s\n", - host, port, strerror(errno)); - close(sfd); - freeaddrinfo(result); - return -EINVAL; - } - } + if (flags & OSMO_SOCK_F_CONNECT) { rc = connect(sfd, rp->ai_addr, rp->ai_addrlen); if (rc != -1 || (rc == -1 && errno == EINPROGRESS)) diff --git a/tests/socket/socket_test.c b/tests/socket/socket_test.c index 5b6abc4..b56d50c 100644 --- a/tests/socket/socket_test.c +++ b/tests/socket/socket_test.c @@ -73,6 +73,57 @@ return 0; } +static int test_sockinit2(void) +{ + int fd, rc; + char *name; + + printf("Checking osmo_sock_init2() with bind to a random local UDP port\n"); + fd = osmo_sock_init2(AF_INET, SOCK_DGRAM, IPPROTO_UDP, + "0.0.0.0", 0, NULL, 0, OSMO_SOCK_F_BIND); + OSMO_ASSERT(fd >= 0); + name = osmo_sock_get_name(NULL, fd); + /* expect it to be not connected. We cannot match on INADDR_ANY, + * as apparently that won't work on FreeBSD if there's only one + * address (e.g. 127.0.0.1) assigned to the entire system, like + * the Osmocom FreeBSD build slaves */ + OSMO_ASSERT(!strncmp(name, "(NULL<->", 7)); + talloc_free(name); + /* expect it to be blocking */ + rc = fcntl(fd, F_GETFL); + OSMO_ASSERT(!(rc & O_NONBLOCK)); + close(fd); + + printf("Checking osmo_sock_init2() for OSMO_SOCK_F_NONBLOCK\n"); + fd = osmo_sock_init2(AF_INET, SOCK_DGRAM, IPPROTO_UDP, + "0.0.0.0", 0, NULL, 0, OSMO_SOCK_F_BIND|OSMO_SOCK_F_NONBLOCK); + OSMO_ASSERT(fd >= 0); + /* expect it to be blocking */ + rc = fcntl(fd, F_GETFL); + OSMO_ASSERT(rc & O_NONBLOCK); + close(fd); + + printf("Checking osmo_sock_init2() for invalid flags\n"); + fd = osmo_sock_init2(AF_INET, SOCK_DGRAM, IPPROTO_UDP, "0.0.0.0", 0, NULL, 0, 0); + OSMO_ASSERT(fd < 0); + + printf("Checking osmo_sock_init2() for combined BIND + CONNECT\n"); + fd = osmo_sock_init2(AF_INET, SOCK_DGRAM, IPPROTO_UDP, "127.0.0.1", 0, "127.0.0.1", 53, + OSMO_SOCK_F_BIND|OSMO_SOCK_F_CONNECT); + OSMO_ASSERT(fd >= 0); + name = osmo_sock_get_name(NULL, fd); +#ifndef __FreeBSD__ + /* For some reason, on the jenkins.osmocom.org build slave with + * FreeBSD 10 inside a jail, it fails. Works fine on laforge's + * FreeBSD 10 or 11 VM at home */ + OSMO_ASSERT(!strncmp(name, "(127.0.0.1:53<->127.0.0.1", 25)); +#endif + talloc_free(name); + + return 0; +} + + const struct log_info_cat default_categories[] = { }; @@ -88,6 +139,7 @@ log_set_print_filename(osmo_stderr_target, 0); test_sockinit(); + test_sockinit2(); return EXIT_SUCCESS; } diff --git a/tests/socket/socket_test.err b/tests/socket/socket_test.err index 5367239..ed6e186 100644 --- a/tests/socket/socket_test.err +++ b/tests/socket/socket_test.err @@ -1 +1,2 @@ invalid: both bind and connect flags set: 0.0.0.0:0 +invalid: you have to specify either BIND or CONNECT flags diff --git a/tests/socket/socket_test.ok b/tests/socket/socket_test.ok index d6ec40e..4b24fbc 100644 --- a/tests/socket/socket_test.ok +++ b/tests/socket/socket_test.ok @@ -1,3 +1,7 @@ Checking osmo_sock_init() with bind to a random local UDP port Checking for OSMO_SOCK_F_NONBLOCK Checking for invalid flags +Checking osmo_sock_init2() with bind to a random local UDP port +Checking osmo_sock_init2() for OSMO_SOCK_F_NONBLOCK +Checking osmo_sock_init2() for invalid flags +Checking osmo_sock_init2() for combined BIND + CONNECT -- To view, visit https://gerrit.osmocom.org/2250 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Idab124bcca47872f55311a82d6818aed590965e6 Gerrit-PatchSet: 2 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:57:07 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:57:07 +0000 Subject: libosmocore[master]: Add osmo_sock_init2() function, allowing both BIND *and* CON... In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2250 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Idab124bcca47872f55311a82d6818aed590965e6 Gerrit-PatchSet: 2 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sun Apr 9 19:57:09 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 9 Apr 2017 19:57:09 +0000 Subject: [MERGED] libosmocore[master]: Add osmo_sock_init2() function, allowing both BIND *and* CON... In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: Add osmo_sock_init2() function, allowing both BIND *and* CONNECT ...................................................................... Add osmo_sock_init2() function, allowing both BIND *and* CONNECT The old osmo_sock_init() function allows only either a bind (for a server socket), or a connect (for a client socket), but not both together. So there's no way to have a client socket that is bound to a specific local IP and/or port, which is needed for some use cases. Change-Id: Idab124bcca47872f55311a82d6818aed590965e6 --- M include/osmocom/core/socket.h M src/socket.c M tests/socket/socket_test.c M tests/socket/socket_test.err M tests/socket/socket_test.ok 5 files changed, 248 insertions(+), 33 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/include/osmocom/core/socket.h b/include/osmocom/core/socket.h index 4f00e30..e19e8f2 100644 --- a/include/osmocom/core/socket.h +++ b/include/osmocom/core/socket.h @@ -24,6 +24,10 @@ int osmo_sock_init(uint16_t family, uint16_t type, uint8_t proto, const char *host, uint16_t port, unsigned int flags); +int osmo_sock_init2(uint16_t family, uint16_t type, uint8_t proto, + const char *local_host, uint16_t local_port, + const char *remote_host, uint16_t remote_port, unsigned int flags); + int osmo_sock_init_ofd(struct osmo_fd *ofd, int family, int type, int proto, const char *host, uint16_t port, unsigned int flags); diff --git a/src/socket.c b/src/socket.c index 2c1b547..ad0f69b 100644 --- a/src/socket.c +++ b/src/socket.c @@ -51,6 +51,188 @@ #include #include +static struct addrinfo *addrinfo_helper(uint16_t family, uint16_t type, uint8_t proto, + const char *host, uint16_t port, bool passive) +{ + struct addrinfo hints, *result; + char portbuf[16]; + int rc; + + snprintf(portbuf, sizeof(portbuf), "%u", port); + memset(&hints, 0, sizeof(struct addrinfo)); + hints.ai_family = family; + if (type == SOCK_RAW) { + /* Workaround for glibc, that returns EAI_SERVICE (-8) if + * SOCK_RAW and IPPROTO_GRE is used. + */ + hints.ai_socktype = SOCK_DGRAM; + hints.ai_protocol = IPPROTO_UDP; + } else { + hints.ai_socktype = type; + hints.ai_protocol = proto; + } + + if (passive) + hints.ai_flags |= AI_PASSIVE; + + rc = getaddrinfo(host, portbuf, &hints, &result); + if (rc != 0) { + LOGP(DLGLOBAL, LOGL_ERROR, "getaddrinfo returned NULL: %s:%u: %s\n", + host, port, strerror(errno)); + return NULL; + } + + return result; +} + +static int socket_helper(const struct addrinfo *rp, unsigned int flags) +{ + int sfd, on = 1; + + sfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); + if (sfd == -1) + return sfd; + if (flags & OSMO_SOCK_F_NONBLOCK) { + if (ioctl(sfd, FIONBIO, (unsigned char *)&on) < 0) { + LOGP(DLGLOBAL, LOGL_ERROR, + "cannot set this socket unblocking: %s\n", + strerror(errno)); + close(sfd); + sfd = -EINVAL; + } + } + return sfd; +} + + +/*! \brief Initialize a socket (including bind and/or connect) + * \param[in] family Address Family like AF_INET, AF_INET6, AF_UNSPEC + * \param[in] type Socket type like SOCK_DGRAM, SOCK_STREAM + * \param[in] proto Protocol like IPPROTO_TCP, IPPROTO_UDP + * \param[in] local_host local host name or IP address in string form + * \param[in] local_port local port number in host byte order + * \param[in] remote_host remote host name or IP address in string form + * \param[in] remote_port remote port number in host byte order + * \param[in] flags flags like \ref OSMO_SOCK_F_CONNECT + * \returns socket file descriptor on success; negative on error + * + * This function creates a new socket of the designated \a family, \a + * type and \a proto and optionally binds it to the \a local_host and \a + * local_port as well as optionally connects it to the \a remote_host + * and \q remote_port, depending on the value * of \a flags parameter. + * + * As opposed to \ref osmo_sock_init(), this function allows to combine + * the \ref OSMO_SOCK_F_BIND and \ref OSMO_SOCK_F_CONNECT flags. This + * is useful if you want to connect to a remote host/port, but still + * want to bind that socket to either a specific local alias IP and/or a + * specific local source port. + * + * You must specify either \ref OSMO_SOCK_F_BIND, or \ref + * OSMO_SOCK_F_CONNECT, or both. + * + * If \ref OSMO_SOCK_F_NONBLOCK is specified, the socket will be set to + * non-blocking mode. + */ +int osmo_sock_init2(uint16_t family, uint16_t type, uint8_t proto, + const char *local_host, uint16_t local_port, + const char *remote_host, uint16_t remote_port, unsigned int flags) +{ + struct addrinfo *result, *rp; + int sfd = -1, rc, on = 1; + + if ((flags & (OSMO_SOCK_F_BIND | OSMO_SOCK_F_CONNECT)) == 0) { + LOGP(DLGLOBAL, LOGL_ERROR, "invalid: you have to specify either " + "BIND or CONNECT flags\n"); + return -EINVAL; + } + + /* figure out local side of socket */ + if (flags & OSMO_SOCK_F_BIND) { + result = addrinfo_helper(family, type, proto, local_host, local_port, true); + if (!result) + return -EINVAL; + + for (rp = result; rp != NULL; rp = rp->ai_next) { + /* Workaround for glibc again */ + if (type == SOCK_RAW) { + rp->ai_socktype = SOCK_RAW; + rp->ai_protocol = proto; + } + + sfd = socket_helper(rp, flags); + if (sfd < 0) + continue; + + rc = setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, + &on, sizeof(on)); + if (rc < 0) { + LOGP(DLGLOBAL, LOGL_ERROR, + "cannot setsockopt socket:" + " %s:%u: %s\n", + local_host, local_port, strerror(errno)); + break; + } + if (bind(sfd, rp->ai_addr, rp->ai_addrlen) != -1) + break; + close(sfd); + } + freeaddrinfo(result); + if (rp == NULL) { + LOGP(DLGLOBAL, LOGL_ERROR, "unable to bind socket: %s:%u: %s\n", + local_host, local_port, strerror(errno)); + return -ENODEV; + } + } + + /* figure out remote side of socket */ + if (flags & OSMO_SOCK_F_CONNECT) { + result = addrinfo_helper(family, type, proto, remote_host, remote_port, false); + if (!result) { + close(sfd); + return -EINVAL; + } + + for (rp = result; rp != NULL; rp = rp->ai_next) { + /* Workaround for glibc again */ + if (type == SOCK_RAW) { + rp->ai_socktype = SOCK_RAW; + rp->ai_protocol = proto; + } + + if (!sfd) { + sfd = socket_helper(rp, flags); + if (sfd < 0) + continue; + } + + rc = connect(sfd, rp->ai_addr, rp->ai_addrlen); + if (rc != -1 || (rc == -1 && errno == EINPROGRESS)) + break; + + close(sfd); + sfd = -1; + } + freeaddrinfo(result); + if (rp == NULL) { + LOGP(DLGLOBAL, LOGL_ERROR, "unable to connect socket: %s:%u: %s\n", + remote_host, remote_port, strerror(errno)); + return -ENODEV; + } + } + + /* Make sure to call 'listen' on a bound, connection-oriented sock */ + if ((flags & (OSMO_SOCK_F_BIND|OSMO_SOCK_F_CONNECT)) == OSMO_SOCK_F_BIND) { + switch (type) { + case SOCK_STREAM: + case SOCK_SEQPACKET: + listen(sfd, 10); + break; + } + } + return sfd; +} + + /*! \brief Initialize a socket (including bind/connect) * \param[in] family Address Family like AF_INET, AF_INET6, AF_UNSPEC * \param[in] type Socket type like SOCK_DGRAM, SOCK_STREAM @@ -67,9 +249,8 @@ int osmo_sock_init(uint16_t family, uint16_t type, uint8_t proto, const char *host, uint16_t port, unsigned int flags) { - struct addrinfo hints, *result, *rp; + struct addrinfo *result, *rp; int sfd, rc, on = 1; - char portbuf[16]; if ((flags & (OSMO_SOCK_F_BIND | OSMO_SOCK_F_CONNECT)) == (OSMO_SOCK_F_BIND | OSMO_SOCK_F_CONNECT)) { @@ -78,25 +259,8 @@ return -EINVAL; } - sprintf(portbuf, "%u", port); - memset(&hints, 0, sizeof(struct addrinfo)); - hints.ai_family = family; - if (type == SOCK_RAW) { - /* Workaround for glibc, that returns EAI_SERVICE (-8) if - * SOCK_RAW and IPPROTO_GRE is used. - */ - hints.ai_socktype = SOCK_DGRAM; - hints.ai_protocol = IPPROTO_UDP; - } else { - hints.ai_socktype = type; - hints.ai_protocol = proto; - } - - if (flags & OSMO_SOCK_F_BIND) - hints.ai_flags |= AI_PASSIVE; - - rc = getaddrinfo(host, portbuf, &hints, &result); - if (rc != 0) { + result = addrinfo_helper(family, type, proto, host, port, flags & OSMO_SOCK_F_BIND); + if (!result) { LOGP(DLGLOBAL, LOGL_ERROR, "getaddrinfo returned NULL: %s:%u: %s\n", host, port, strerror(errno)); return -EINVAL; @@ -109,20 +273,10 @@ rp->ai_protocol = proto; } - sfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); + sfd = socket_helper(rp, flags); if (sfd == -1) continue; - if (flags & OSMO_SOCK_F_NONBLOCK) { - if (ioctl(sfd, FIONBIO, (unsigned char *)&on) < 0) { - LOGP(DLGLOBAL, LOGL_ERROR, - "cannot set this socket unblocking:" - " %s:%u: %s\n", - host, port, strerror(errno)); - close(sfd); - freeaddrinfo(result); - return -EINVAL; - } - } + if (flags & OSMO_SOCK_F_CONNECT) { rc = connect(sfd, rp->ai_addr, rp->ai_addrlen); if (rc != -1 || (rc == -1 && errno == EINPROGRESS)) diff --git a/tests/socket/socket_test.c b/tests/socket/socket_test.c index 5b6abc4..b56d50c 100644 --- a/tests/socket/socket_test.c +++ b/tests/socket/socket_test.c @@ -73,6 +73,57 @@ return 0; } +static int test_sockinit2(void) +{ + int fd, rc; + char *name; + + printf("Checking osmo_sock_init2() with bind to a random local UDP port\n"); + fd = osmo_sock_init2(AF_INET, SOCK_DGRAM, IPPROTO_UDP, + "0.0.0.0", 0, NULL, 0, OSMO_SOCK_F_BIND); + OSMO_ASSERT(fd >= 0); + name = osmo_sock_get_name(NULL, fd); + /* expect it to be not connected. We cannot match on INADDR_ANY, + * as apparently that won't work on FreeBSD if there's only one + * address (e.g. 127.0.0.1) assigned to the entire system, like + * the Osmocom FreeBSD build slaves */ + OSMO_ASSERT(!strncmp(name, "(NULL<->", 7)); + talloc_free(name); + /* expect it to be blocking */ + rc = fcntl(fd, F_GETFL); + OSMO_ASSERT(!(rc & O_NONBLOCK)); + close(fd); + + printf("Checking osmo_sock_init2() for OSMO_SOCK_F_NONBLOCK\n"); + fd = osmo_sock_init2(AF_INET, SOCK_DGRAM, IPPROTO_UDP, + "0.0.0.0", 0, NULL, 0, OSMO_SOCK_F_BIND|OSMO_SOCK_F_NONBLOCK); + OSMO_ASSERT(fd >= 0); + /* expect it to be blocking */ + rc = fcntl(fd, F_GETFL); + OSMO_ASSERT(rc & O_NONBLOCK); + close(fd); + + printf("Checking osmo_sock_init2() for invalid flags\n"); + fd = osmo_sock_init2(AF_INET, SOCK_DGRAM, IPPROTO_UDP, "0.0.0.0", 0, NULL, 0, 0); + OSMO_ASSERT(fd < 0); + + printf("Checking osmo_sock_init2() for combined BIND + CONNECT\n"); + fd = osmo_sock_init2(AF_INET, SOCK_DGRAM, IPPROTO_UDP, "127.0.0.1", 0, "127.0.0.1", 53, + OSMO_SOCK_F_BIND|OSMO_SOCK_F_CONNECT); + OSMO_ASSERT(fd >= 0); + name = osmo_sock_get_name(NULL, fd); +#ifndef __FreeBSD__ + /* For some reason, on the jenkins.osmocom.org build slave with + * FreeBSD 10 inside a jail, it fails. Works fine on laforge's + * FreeBSD 10 or 11 VM at home */ + OSMO_ASSERT(!strncmp(name, "(127.0.0.1:53<->127.0.0.1", 25)); +#endif + talloc_free(name); + + return 0; +} + + const struct log_info_cat default_categories[] = { }; @@ -88,6 +139,7 @@ log_set_print_filename(osmo_stderr_target, 0); test_sockinit(); + test_sockinit2(); return EXIT_SUCCESS; } diff --git a/tests/socket/socket_test.err b/tests/socket/socket_test.err index 5367239..ed6e186 100644 --- a/tests/socket/socket_test.err +++ b/tests/socket/socket_test.err @@ -1 +1,2 @@ invalid: both bind and connect flags set: 0.0.0.0:0 +invalid: you have to specify either BIND or CONNECT flags diff --git a/tests/socket/socket_test.ok b/tests/socket/socket_test.ok index d6ec40e..4b24fbc 100644 --- a/tests/socket/socket_test.ok +++ b/tests/socket/socket_test.ok @@ -1,3 +1,7 @@ Checking osmo_sock_init() with bind to a random local UDP port Checking for OSMO_SOCK_F_NONBLOCK Checking for invalid flags +Checking osmo_sock_init2() with bind to a random local UDP port +Checking osmo_sock_init2() for OSMO_SOCK_F_NONBLOCK +Checking osmo_sock_init2() for invalid flags +Checking osmo_sock_init2() for combined BIND + CONNECT -- To view, visit https://gerrit.osmocom.org/2250 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Idab124bcca47872f55311a82d6818aed590965e6 Gerrit-PatchSet: 2 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Apr 10 06:47:17 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 06:47:17 +0000 Subject: libosmo-netif[master]: stream+datagram: Allow local bind + connect for client sockets In-Reply-To: References: Message-ID: Patch Set 3: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2251 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I013f4cc10b26d332d52d231f252bb0f03df8c54b Gerrit-PatchSet: 3 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Mon Apr 10 06:47:19 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 06:47:19 +0000 Subject: [MERGED] libosmo-netif[master]: stream+datagram: Allow local bind + connect for client sockets In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: stream+datagram: Allow local bind + connect for client sockets ...................................................................... stream+datagram: Allow local bind + connect for client sockets This uses the new osmo_sock_init2() features introduced in libosmocore Change-Id Idab124bcca47872f55311a82d6818aed590965e6 to bind *and* connect a given socket during creation. Change-Id: I013f4cc10b26d332d52d231f252bb0f03df8c54b --- M include/osmocom/netif/datagram.h M include/osmocom/netif/stream.h M src/datagram.c M src/stream.c 4 files changed, 48 insertions(+), 7 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/include/osmocom/netif/datagram.h b/include/osmocom/netif/datagram.h index 33d3d30..b7ecfe3 100644 --- a/include/osmocom/netif/datagram.h +++ b/include/osmocom/netif/datagram.h @@ -8,6 +8,8 @@ void osmo_dgram_tx_set_addr(struct osmo_dgram_tx *conn, const char *addr); void osmo_dgram_tx_set_port(struct osmo_dgram_tx *conn, uint16_t port); +void osmo_dgram_tx_set_local_addr(struct osmo_dgram_tx *conn, const char *addr); +void osmo_dgram_tx_set_local_port(struct osmo_dgram_tx *conn, uint16_t port); void osmo_dgram_tx_set_data(struct osmo_dgram_tx *conn, void *data); int osmo_dgram_tx_open(struct osmo_dgram_tx *conn); diff --git a/include/osmocom/netif/stream.h b/include/osmocom/netif/stream.h index 254b4c5..63eccf8 100644 --- a/include/osmocom/netif/stream.h +++ b/include/osmocom/netif/stream.h @@ -48,6 +48,8 @@ void osmo_stream_cli_set_addr(struct osmo_stream_cli *cli, const char *addr); void osmo_stream_cli_set_port(struct osmo_stream_cli *cli, uint16_t port); void osmo_stream_cli_set_proto(struct osmo_stream_cli *cli, uint16_t proto); +void osmo_stream_cli_set_local_addr(struct osmo_stream_cli *cli, const char *addr); +void osmo_stream_cli_set_local_port(struct osmo_stream_cli *cli, uint16_t port); void osmo_stream_cli_set_data(struct osmo_stream_cli *cli, void *data); void osmo_stream_cli_set_reconnect_timeout(struct osmo_stream_cli *cli, int timeout); void *osmo_stream_cli_get_data(struct osmo_stream_cli *cli); diff --git a/src/datagram.c b/src/datagram.c index 6316552..cb2a64f 100644 --- a/src/datagram.c +++ b/src/datagram.c @@ -12,6 +12,7 @@ #include #include +#include #include #include #include @@ -40,6 +41,8 @@ struct llist_head tx_queue; const char *addr; uint16_t port; + char *local_addr; + uint16_t local_port; int (*write_cb)(struct osmo_dgram_tx *conn); void *data; unsigned int flags; @@ -140,6 +143,26 @@ conn->flags |= OSMO_DGRAM_CLI_F_RECONF; } +/*! \brief Set the local address from which we transmit + * \param[in] conn Datagram Transmitter to modify + * \param[in] addr Local IP address */ +void +osmo_dgram_tx_set_local_addr(struct osmo_dgram_tx *conn, const char *addr) +{ + osmo_talloc_replace_string(conn, &conn->local_addr, addr); + conn->flags |= OSMO_DGRAM_CLI_F_RECONF; +} + +/*! \brief Set the local port from which we transmit + * \param[in] conn Datagram Transmitter to modify + * \param[in] port Local Port Number */ +void +osmo_dgram_tx_set_local_port(struct osmo_dgram_tx *conn, uint16_t port) +{ + conn->local_port = port; + conn->flags |= OSMO_DGRAM_CLI_F_RECONF; +} + /*! \brief Set application private data of the datagram transmitter * \param[in] conn Datagram Transmitter to modify * \param[in] data User-specific data (available in call-back functions) */ @@ -169,9 +192,9 @@ conn->flags &= ~OSMO_DGRAM_CLI_F_RECONF; - ret = osmo_sock_init(AF_INET, SOCK_DGRAM, IPPROTO_UDP, - conn->addr, conn->port, - OSMO_SOCK_F_CONNECT|OSMO_SOCK_F_NONBLOCK); + ret = osmo_sock_init2(AF_INET, SOCK_DGRAM, IPPROTO_UDP, + conn->local_addr, conn->local_port, conn->addr, conn->port, + OSMO_SOCK_F_BIND|OSMO_SOCK_F_CONNECT|OSMO_SOCK_F_NONBLOCK); if (ret < 0) return ret; diff --git a/src/stream.c b/src/stream.c index e71e420..52521d7 100644 --- a/src/stream.c +++ b/src/stream.c @@ -12,6 +12,7 @@ #include #include +#include #include #include #include @@ -82,6 +83,7 @@ enum osmo_stream_cli_state state; const char *addr; uint16_t port; + char *local_addr; uint16_t local_port; uint16_t proto; int (*connect_cb)(struct osmo_stream_cli *srv); @@ -277,7 +279,7 @@ cli->flags |= OSMO_STREAM_CLI_F_RECONF; } -/*! \brief Set the local port number for the socket +/*! \brief Set the local port number for the socket (to be bound to) * \param[in] cli Stream Client to modify * \param[in] port Local port number */ @@ -285,6 +287,17 @@ osmo_stream_cli_set_local_port(struct osmo_stream_cli *cli, uint16_t port) { cli->local_port = port; + cli->flags |= OSMO_STREAM_CLI_F_RECONF; +} + +/*! \brief Set the local address for the socket (to be bound to) + * \param[in] cli Stream Client to modify + * \param[in] port Local host name + */ +void +osmo_stream_cli_set_local_addr(struct osmo_stream_cli *cli, const char *addr) +{ + osmo_talloc_replace_string(cli, &cli->local_addr, addr); cli->flags |= OSMO_STREAM_CLI_F_RECONF; } @@ -376,9 +389,10 @@ cli->flags &= ~OSMO_STREAM_CLI_F_RECONF; - ret = osmo_sock_init(AF_INET, SOCK_STREAM, cli->proto, - cli->addr, cli->port, - OSMO_SOCK_F_CONNECT); + ret = osmo_sock_init2(AF_INET, SOCK_STREAM, cli->proto, + cli->local_addr, cli->local_port, + cli->addr, cli->port, + OSMO_SOCK_F_CONNECT|OSMO_SOCK_F_BIND); if (ret < 0) { if (reconnect && errno == ECONNREFUSED) osmo_stream_cli_reconnect(cli); -- To view, visit https://gerrit.osmocom.org/2251 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I013f4cc10b26d332d52d231f252bb0f03df8c54b Gerrit-PatchSet: 3 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Apr 10 06:52:08 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 06:52:08 +0000 Subject: libosmo-netif[master]: stream/datagram: Consistently use osmo_talloc_replace_string() In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2252 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ie1b140a160c66e8b62c745174865d5ba525cb2c2 Gerrit-PatchSet: 2 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Mon Apr 10 06:52:11 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 06:52:11 +0000 Subject: [MERGED] libosmo-netif[master]: stream/datagram: Consistently use osmo_talloc_replace_string() In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: stream/datagram: Consistently use osmo_talloc_replace_string() ...................................................................... stream/datagram: Consistently use osmo_talloc_replace_string() during osmo_*_set_addr(), we must make sure to talloc_free() any old address before copying in the new address. Not all functions did this, and those that did implemented it manually. Let's use osmo_talloc_replace_string() which is exactly intended for this case. Change-Id: Ie1b140a160c66e8b62c745174865d5ba525cb2c2 --- M src/datagram.c M src/stream.c 2 files changed, 8 insertions(+), 14 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/datagram.c b/src/datagram.c index cb2a64f..13f1b5c 100644 --- a/src/datagram.c +++ b/src/datagram.c @@ -39,7 +39,7 @@ struct osmo_dgram_tx { struct osmo_fd ofd; struct llist_head tx_queue; - const char *addr; + char *addr; uint16_t port; char *local_addr; uint16_t local_port; @@ -125,10 +125,7 @@ osmo_dgram_tx_set_addr(struct osmo_dgram_tx *conn, const char *addr) { - if (conn->addr != NULL) - talloc_free((void *)conn->addr); - - conn->addr = talloc_strdup(conn, addr); + osmo_talloc_replace_string(conn, &conn->addr, addr); conn->flags |= OSMO_DGRAM_CLI_F_RECONF; } @@ -224,7 +221,7 @@ struct osmo_dgram_rx { struct osmo_fd ofd; - const char *addr; + char *addr; uint16_t port; int (*cb)(struct osmo_dgram_rx *conn); void *data; @@ -296,10 +293,7 @@ void osmo_dgram_rx_set_addr(struct osmo_dgram_rx *conn, const char *addr) { - if (conn->addr != NULL) - talloc_free((void *)conn->addr); - - conn->addr = talloc_strdup(conn, addr); + osmo_talloc_replace_string(conn, &conn->addr, addr); conn->flags |= OSMO_DGRAM_RX_F_RECONF; } diff --git a/src/stream.c b/src/stream.c index 52521d7..7bac1cc 100644 --- a/src/stream.c +++ b/src/stream.c @@ -81,7 +81,7 @@ struct llist_head tx_queue; struct osmo_timer_list timer; enum osmo_stream_cli_state state; - const char *addr; + char *addr; uint16_t port; char *local_addr; uint16_t local_port; @@ -264,7 +264,7 @@ void osmo_stream_cli_set_addr(struct osmo_stream_cli *cli, const char *addr) { - cli->addr = talloc_strdup(cli, addr); + osmo_talloc_replace_string(cli, &cli->addr, addr); cli->flags |= OSMO_STREAM_CLI_F_RECONF; } @@ -474,7 +474,7 @@ struct osmo_stream_srv_link { struct osmo_fd ofd; - const char *addr; + char *addr; uint16_t port; uint16_t proto; int (*accept_cb)(struct osmo_stream_srv_link *srv, int fd); @@ -537,7 +537,7 @@ void osmo_stream_srv_link_set_addr(struct osmo_stream_srv_link *link, const char *addr) { - link->addr = talloc_strdup(link, addr); + osmo_talloc_replace_string(link, &link->addr, addr); link->flags |= OSMO_STREAM_SRV_F_RECONF; } -- To view, visit https://gerrit.osmocom.org/2252 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ie1b140a160c66e8b62c745174865d5ba525cb2c2 Gerrit-PatchSet: 2 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Apr 10 06:54:32 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 06:54:32 +0000 Subject: [MERGED] osmo-trx[master]: Configuration: Fix const and signedness compile warnings In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: Configuration: Fix const and signedness compile warnings ...................................................................... Configuration: Fix const and signedness compile warnings Change-Id: I701559814b2aee6f84f10e612f128da40f6a51c1 --- M CommonLibs/Configuration.cpp M CommonLibs/ConfigurationTest.cpp 2 files changed, 2 insertions(+), 2 deletions(-) Approvals: Tom Tsou: Looks good to me, approved Jenkins Builder: Verified diff --git a/CommonLibs/Configuration.cpp b/CommonLibs/Configuration.cpp index bfff893..7ca193b 100644 --- a/CommonLibs/Configuration.cpp +++ b/CommonLibs/Configuration.cpp @@ -56,7 +56,7 @@ static std::string replaceAll(const std::string input, const std::string search, const std::string replace) { std::string output = input; - int index = 0; + size_t index = 0; while (true) { index = output.find(search, index); diff --git a/CommonLibs/ConfigurationTest.cpp b/CommonLibs/ConfigurationTest.cpp index 2fd43e9..7042228 100644 --- a/CommonLibs/ConfigurationTest.cpp +++ b/CommonLibs/ConfigurationTest.cpp @@ -47,7 +47,7 @@ gConfig.setUpdateHook(purgeConfig); - char *keys[5] = {"key1", "key2", "key3", "key4", "key5"}; + const char *keys[5] = {"key1", "key2", "key3", "key4", "key5"}; for (int i=0; i<5; i++) { gConfig.set(keys[i],i); -- To view, visit https://gerrit.osmocom.org/2221 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I701559814b2aee6f84f10e612f128da40f6a51c1 Gerrit-PatchSet: 1 Gerrit-Project: osmo-trx Gerrit-Branch: master Gerrit-Owner: Tom Tsou Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Tom Tsou From gerrit-no-reply at lists.osmocom.org Mon Apr 10 06:54:40 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 06:54:40 +0000 Subject: [MERGED] osmo-trx[master]: config: Remove OpenBTS style sqlite configuration In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: config: Remove OpenBTS style sqlite configuration ...................................................................... config: Remove OpenBTS style sqlite configuration OpenBTS relies on reading in configuration values from the OpenBTS.config sqlite3 database. This configuration method is not maintained and not recommended for Osmocom or OpenBTS use. Command line setup is the recommended approach. Note that when the osmo-trx logging mechanism is replaced, the sqlite dependency will be removed. Change-Id: I95d7b771fde976818bee76f89163e72c3a44ecdd --- M Transceiver52M/osmo-trx.cpp 1 file changed, 4 insertions(+), 80 deletions(-) Approvals: Tom Tsou: Looks good to me, approved Max: Looks good to me, but someone else must approve Harald Welte: Looks good to me, but someone else must approve Jenkins Builder: Verified diff --git a/Transceiver52M/osmo-trx.cpp b/Transceiver52M/osmo-trx.cpp index b36c081..b07ffe8 100644 --- a/Transceiver52M/osmo-trx.cpp +++ b/Transceiver52M/osmo-trx.cpp @@ -49,16 +49,9 @@ */ #define DEFAULT_RX_SPS 1 -/* Default configuration parameters - * Note that these values are only used if the particular key does not - * exist in the configuration database. IP port and address values will - * typically be overwritten by the OpenBTS.db values. Other values will - * not be in the database by default. - */ +/* Default configuration parameters */ #define DEFAULT_TRX_PORT 5700 #define DEFAULT_TRX_IP "127.0.0.1" -#define DEFAULT_EXTREF false -#define DEFAULT_DIVERSITY false #define DEFAULT_CHANS 1 struct trx_config { @@ -86,40 +79,6 @@ volatile bool gshutdown = false; -/* Run sanity check on configuration table - * The global table constructor cannot provide notification in the - * event of failure. Make sure that we can access the database, - * write to it, and that it contains the bare minimum required keys. - */ -bool testConfig() -{ - int val = 9999; - std::string test = "asldfkjsaldkf"; - const char *key = "Log.Level"; - - /* Attempt to query */ - try { - gConfig.getStr(key); - } catch (...) { - std::cerr << std::endl; - std::cerr << "Config: Failed query required key " << key - << std::endl; - return false; - } - - /* Attempt to set a test value in the global config */ - if (!gConfig.set(test, val)) { - std::cerr << std::endl; - std::cerr << "Config: Failed to set test key" << std::endl; - return false; - } else { - gConfig.remove(test); - } - - return true; -} - - /* Setup configuration values * Don't query the existence of the Log.Level because it's a * mandatory value. That is, if it doesn't exist, the configuration @@ -130,43 +89,6 @@ bool trx_setup_config(struct trx_config *config) { std::string refstr, fillstr, divstr, mcstr, edgestr; - - if (!testConfig()) - return false; - - if (config->log_level == "") - config->log_level = gConfig.getStr("Log.Level"); - - if (!config->port) { - if (gConfig.defines("TRX.Port")) - config->port = gConfig.getNum("TRX.Port"); - else - config->port = DEFAULT_TRX_PORT; - } - - if (config->addr == "") { - if (gConfig.defines("TRX.IP")) - config->addr = gConfig.getStr("TRX.IP"); - else - config->addr = DEFAULT_TRX_IP; - } - - if (!config->extref) { - if (gConfig.defines("TRX.Reference")) - config->extref = gConfig.getNum("TRX.Reference"); - else - config->extref = DEFAULT_EXTREF; - } - - if (!config->diversity) { - if (gConfig.defines("TRX.Diversity")) - config->diversity = gConfig.getNum("TRX.Diversity"); - else - config->diversity = DEFAULT_DIVERSITY; - } - - if (!config->chans) - config->chans = DEFAULT_CHANS; if (config->mcbts && config->chans > 5) { std::cout << "Unsupported number of channels" << std::endl; @@ -350,7 +272,9 @@ { int option; - config->port = 0; + config->log_level = "NOTICE"; + config->addr = DEFAULT_TRX_IP; + config->port = DEFAULT_TRX_PORT; config->tx_sps = DEFAULT_TX_SPS; config->rx_sps = DEFAULT_RX_SPS; config->chans = DEFAULT_CHANS; -- To view, visit https://gerrit.osmocom.org/2185 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I95d7b771fde976818bee76f89163e72c3a44ecdd Gerrit-PatchSet: 4 Gerrit-Project: osmo-trx Gerrit-Branch: master Gerrit-Owner: Tom Tsou Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Tom Tsou From gerrit-no-reply at lists.osmocom.org Mon Apr 10 06:58:29 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 06:58:29 +0000 Subject: openbsc[master]: gsm_bts: add version and variant details In-Reply-To: References: Message-ID: Patch Set 6: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2161 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I6710d53115f34634a7b70969cc05fd5c72ff8ab2 Gerrit-PatchSet: 6 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Mon Apr 10 06:58:44 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 06:58:44 +0000 Subject: [MERGED] openbsc[master]: gsm_bts: add version and variant details In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: gsm_bts: add version and variant details ...................................................................... gsm_bts: add version and variant details * add version string to gsm_bts * add PCU version string to gsm_bts * rename GSM_BTS_TYPE_OSMO_SYSMO -> GSM_BTS_OSMOBTS to avoid confusion between BTS model and variant * add variant enum to gsm_bts_model using enum with variants for each hw vendor of OsmoBTS * show connected PCU version (if available) in vty via 'show bts' This will come in handy when logging details regarding particular BTS reported via OML, see: Related: OS#1614 Change-Id: I6710d53115f34634a7b70969cc05fd5c72ff8ab2 --- M openbsc/include/openbsc/gsm_data.h M openbsc/include/openbsc/gsm_data_shared.h M openbsc/src/libbsc/abis_nm.c M openbsc/src/libbsc/bsc_vty.c M openbsc/src/libbsc/bts_sysmobts.c M openbsc/src/libbsc/e1_config.c M openbsc/src/libbsc/system_information.c M openbsc/src/libcommon/gsm_data.c M openbsc/src/libmsc/gsm_04_08.c 9 files changed, 38 insertions(+), 18 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h index 08e07d8..1d90eee 100644 --- a/openbsc/include/openbsc/gsm_data.h +++ b/openbsc/include/openbsc/gsm_data.h @@ -469,7 +469,7 @@ { switch (bts->type) { case GSM_BTS_TYPE_NANOBTS: - case GSM_BTS_TYPE_OSMO_SYSMO: + case GSM_BTS_TYPE_OSMOBTS: return 1; default: break; @@ -480,7 +480,7 @@ static inline int is_sysmobts_v2(struct gsm_bts *bts) { switch (bts->type) { - case GSM_BTS_TYPE_OSMO_SYSMO: + case GSM_BTS_TYPE_OSMOBTS: return 1; default: break; diff --git a/openbsc/include/openbsc/gsm_data_shared.h b/openbsc/include/openbsc/gsm_data_shared.h index 06fa8dd..242889a 100644 --- a/openbsc/include/openbsc/gsm_data_shared.h +++ b/openbsc/include/openbsc/gsm_data_shared.h @@ -64,6 +64,8 @@ #define HARDCODED_BTS1_TS 6 #define HARDCODED_BTS2_TS 11 +#define MAX_VERSION_LENGTH 64 + enum gsm_hooks { GSM_HOOK_NM_SWLOAD, GSM_HOOK_RR_PAGING, @@ -489,8 +491,17 @@ GSM_BTS_TYPE_NANOBTS, GSM_BTS_TYPE_RBS2000, GSM_BTS_TYPE_NOKIA_SITE, - GSM_BTS_TYPE_OSMO_SYSMO, + GSM_BTS_TYPE_OSMOBTS, _NUM_GSM_BTS_TYPE +}; + +enum gsm_bts_type_variant { + BTS_UNKNOWN, + BTS_OSMO_LITECELL15, + BTS_OSMO_OCTPHY, + BTS_OSMO_SYSMO, + BTS_OSMO_TRX, + _NUM_BTS_VARIANT }; struct vty; @@ -499,6 +510,7 @@ struct llist_head list; enum gsm_bts_type type; + enum gsm_bts_type_variant variant; const char *name; bool started; @@ -653,6 +665,11 @@ enum gsm_bts_type type; struct gsm_bts_model *model; enum gsm_band band; + char version[MAX_VERSION_LENGTH]; + + /* Connected PCU version (if any) */ + char pcu_version[MAX_VERSION_LENGTH]; + /* maximum Tx power that the MS is permitted to use in this cell */ int ms_max_power; diff --git a/openbsc/src/libbsc/abis_nm.c b/openbsc/src/libbsc/abis_nm.c index 651ca02..56b6fcf 100644 --- a/openbsc/src/libbsc/abis_nm.c +++ b/openbsc/src/libbsc/abis_nm.c @@ -738,7 +738,7 @@ switch (bts_type) { case GSM_BTS_TYPE_NANOBTS: - case GSM_BTS_TYPE_OSMO_SYSMO: + case GSM_BTS_TYPE_OSMOBTS: rc = abis_nm_rx_ipacc(mb); abis_nm_queue_send_next(sign_link->trx->bts); break; @@ -1723,7 +1723,7 @@ } *reason = "Unknown combination"; return -EINVAL; - case GSM_BTS_TYPE_OSMO_SYSMO: + case GSM_BTS_TYPE_OSMOBTS: /* no known restrictions */ return 0; default: diff --git a/openbsc/src/libbsc/bsc_vty.c b/openbsc/src/libbsc/bsc_vty.c index 66b30cd..c1882fc 100644 --- a/openbsc/src/libbsc/bsc_vty.c +++ b/openbsc/src/libbsc/bsc_vty.c @@ -245,6 +245,9 @@ bts->num_trx, VTY_NEWLINE); vty_out(vty, "Description: %s%s", bts->description ? bts->description : "(null)", VTY_NEWLINE); + if (strnlen(bts->pcu_version, MAX_VERSION_LENGTH)) + vty_out(vty, "PCU version %s connected%s", bts->pcu_version, + VTY_NEWLINE); vty_out(vty, "MS Max power: %u dBm%s", bts->ms_max_power, VTY_NEWLINE); vty_out(vty, "Minimum Rx Level for Access: %i dBm%s", rxlev2dbm(bts->si_common.cell_sel_par.rxlev_acc_min), @@ -649,7 +652,7 @@ bts->early_classmark_allowed ? "allowed" : "forbidden", VTY_NEWLINE); switch (bts->type) { case GSM_BTS_TYPE_NANOBTS: - case GSM_BTS_TYPE_OSMO_SYSMO: + case GSM_BTS_TYPE_OSMOBTS: vty_out(vty, " ip.access unit_id %u %u%s", bts->ip_access.site_id, bts->ip_access.bts_id, VTY_NEWLINE); if (bts->ip_access.rsl_ip) { diff --git a/openbsc/src/libbsc/bts_sysmobts.c b/openbsc/src/libbsc/bts_sysmobts.c index e1bf661..e4b6cdc 100644 --- a/openbsc/src/libbsc/bts_sysmobts.c +++ b/openbsc/src/libbsc/bts_sysmobts.c @@ -46,7 +46,7 @@ { model_sysmobts = bts_model_nanobts; model_sysmobts.name = "sysmobts"; - model_sysmobts.type = GSM_BTS_TYPE_OSMO_SYSMO; + model_sysmobts.type = GSM_BTS_TYPE_OSMOBTS; model_sysmobts.features.data = &model_sysmobts._features_data[0]; model_sysmobts.features.data_len = diff --git a/openbsc/src/libbsc/e1_config.c b/openbsc/src/libbsc/e1_config.c index 8910d21..d57dec5 100644 --- a/openbsc/src/libbsc/e1_config.c +++ b/openbsc/src/libbsc/e1_config.c @@ -179,7 +179,7 @@ /* skip signal link initialization, this is done later for these BTS. */ if (bts->type == GSM_BTS_TYPE_NANOBTS || - bts->type == GSM_BTS_TYPE_OSMO_SYSMO) + bts->type == GSM_BTS_TYPE_OSMOBTS) return e1inp_line_update(line); /* OML link */ diff --git a/openbsc/src/libbsc/system_information.c b/openbsc/src/libbsc/system_information.c index a2dd827..2610331 100644 --- a/openbsc/src/libbsc/system_information.c +++ b/openbsc/src/libbsc/system_information.c @@ -830,7 +830,7 @@ /* ip.access nanoBTS needs l2_plen!! */ switch (bts->type) { case GSM_BTS_TYPE_NANOBTS: - case GSM_BTS_TYPE_OSMO_SYSMO: + case GSM_BTS_TYPE_OSMOBTS: *output++ = GSM48_LEN2PLEN(l2_plen); l2_plen++; break; @@ -865,7 +865,7 @@ /* ip.access nanoBTS needs l2_plen!! */ switch (bts->type) { case GSM_BTS_TYPE_NANOBTS: - case GSM_BTS_TYPE_OSMO_SYSMO: + case GSM_BTS_TYPE_OSMOBTS: *output++ = GSM48_LEN2PLEN(l2_plen); l2_plen++; break; @@ -909,7 +909,7 @@ /* ip.access nanoBTS needs l2_plen!! */ switch (bts->type) { case GSM_BTS_TYPE_NANOBTS: - case GSM_BTS_TYPE_OSMO_SYSMO: + case GSM_BTS_TYPE_OSMOBTS: *output++ = GSM48_LEN2PLEN(l2_plen); l2_plen++; break; @@ -946,7 +946,7 @@ /* ip.access nanoBTS needs l2_plen!! */ switch (bts->type) { case GSM_BTS_TYPE_NANOBTS: - case GSM_BTS_TYPE_OSMO_SYSMO: + case GSM_BTS_TYPE_OSMOBTS: *output++ = GSM48_LEN2PLEN(l2_plen); l2_plen++; break; diff --git a/openbsc/src/libcommon/gsm_data.c b/openbsc/src/libcommon/gsm_data.c index 3e12430..fd34793 100644 --- a/openbsc/src/libcommon/gsm_data.c +++ b/openbsc/src/libcommon/gsm_data.c @@ -96,7 +96,7 @@ { GSM_BTS_TYPE_NANOBTS, "nanobts" }, { GSM_BTS_TYPE_RBS2000, "rbs2000" }, { GSM_BTS_TYPE_NOKIA_SITE, "nokia_site" }, - { GSM_BTS_TYPE_OSMO_SYSMO, "sysmobts" }, + { GSM_BTS_TYPE_OSMOBTS, "sysmobts" }, { 0, NULL } }; @@ -106,7 +106,7 @@ { GSM_BTS_TYPE_NANOBTS, "ip.access nanoBTS or compatible" }, { GSM_BTS_TYPE_RBS2000, "Ericsson RBS2000 Series" }, { GSM_BTS_TYPE_NOKIA_SITE, "Nokia {Metro,Ultra,In}Site" }, - { GSM_BTS_TYPE_OSMO_SYSMO, "sysmocom sysmoBTS" }, + { GSM_BTS_TYPE_OSMOBTS, "sysmocom sysmoBTS" }, { 0, NULL } }; @@ -274,7 +274,7 @@ switch (bts->type) { case GSM_BTS_TYPE_NANOBTS: - case GSM_BTS_TYPE_OSMO_SYSMO: + case GSM_BTS_TYPE_OSMOBTS: /* Set the default OML Stream ID to 0xff */ bts->oml_tei = 0xff; bts->c0->nominal_power = 23; diff --git a/openbsc/src/libmsc/gsm_04_08.c b/openbsc/src/libmsc/gsm_04_08.c index 31392f3..376106f 100644 --- a/openbsc/src/libmsc/gsm_04_08.c +++ b/openbsc/src/libmsc/gsm_04_08.c @@ -1962,7 +1962,7 @@ // todo: map between different bts types switch (bts->type) { case GSM_BTS_TYPE_NANOBTS: - case GSM_BTS_TYPE_OSMO_SYSMO: + case GSM_BTS_TYPE_OSMOBTS: if (!ipacc_rtp_direct) { if (!lchan->abis_ip.rtp_socket) { LOGP(DHO, LOGL_ERROR, "no RTP socket for " @@ -2053,7 +2053,7 @@ switch (bts->type) { case GSM_BTS_TYPE_NANOBTS: - case GSM_BTS_TYPE_OSMO_SYSMO: + case GSM_BTS_TYPE_OSMOBTS: if (ipacc_rtp_direct) { LOGP(DCC, LOGL_ERROR, "Error: RTP proxy is disabled\n"); return -EINVAL; @@ -3633,7 +3633,7 @@ bts = trans->conn->lchan->ts->trx->bts; switch (bts->type) { case GSM_BTS_TYPE_NANOBTS: - case GSM_BTS_TYPE_OSMO_SYSMO: + case GSM_BTS_TYPE_OSMOBTS: if (!trans->conn->lchan->abis_ip.rtp_socket) { DEBUGP(DMNCC, "TCH frame to lchan without RTP connection\n"); return 0; -- To view, visit https://gerrit.osmocom.org/2161 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I6710d53115f34634a7b70969cc05fd5c72ff8ab2 Gerrit-PatchSet: 7 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Mon Apr 10 07:32:07 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 07:32:07 +0000 Subject: libosmo-netif[master]: stream/datagram: Ensure reliable close/destroy In-Reply-To: References: Message-ID: Patch Set 3: Code-Review+2 once again I'm at a loss. This patch passes "make check" without any problem on my FreeBSD 10 VM. -- To view, visit https://gerrit.osmocom.org/2253 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I29c37da6e8f5be8ab030e68952a8f92add146821 Gerrit-PatchSet: 3 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Mon Apr 10 08:24:48 2017 From: gerrit-no-reply at lists.osmocom.org (Holger Freyther) Date: Mon, 10 Apr 2017 08:24:48 +0000 Subject: libosmo-netif[master]: stream/datagram: Ensure reliable close/destroy In-Reply-To: References: Message-ID: Patch Set 3: > once again I'm at a loss. This patch passes "make check" without > any problem on my FreeBSD 10 VM. Apparently something (the VM? FreeBSD?) stalled for 10s leading to the sigalarm handler being called. I re-triggered the build.. and it didn't run into a timeout. -- To view, visit https://gerrit.osmocom.org/2253 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I29c37da6e8f5be8ab030e68952a8f92add146821 Gerrit-PatchSet: 3 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Mon Apr 10 08:36:55 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 08:36:55 +0000 Subject: [MERGED] libosmo-netif[master]: stream/datagram: Ensure reliable close/destroy In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: stream/datagram: Ensure reliable close/destroy ...................................................................... stream/datagram: Ensure reliable close/destroy * when using osmo_*_destroy(), always call *_close() internally to make sure we don't free memory holding references to sockets that are still open * when closing the socket, always make sure to set the fd to -1 in all cases, to avoid attempts to avoid later close() on a new file using the same fd number as the socket closed previously. Change-Id: I29c37da6e8f5be8ab030e68952a8f92add146821 --- M src/datagram.c M src/stream.c 2 files changed, 16 insertions(+), 4 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/datagram.c b/src/datagram.c index 13f1b5c..d98221f 100644 --- a/src/datagram.c +++ b/src/datagram.c @@ -54,8 +54,11 @@ * abstraction and close the socket */ void osmo_dgram_tx_close(struct osmo_dgram_tx *conn) { + if (conn->ofd.fd == -1) + return; osmo_fd_unregister(&conn->ofd); close(conn->ofd.fd); + conn->ofd.fd = -1; } static int osmo_dgram_tx_write(struct osmo_dgram_tx *conn) @@ -173,6 +176,7 @@ * \param[in] conn Datagram Transmitter to destroy */ void osmo_dgram_tx_destroy(struct osmo_dgram_tx *conn) { + osmo_dgram_tx_close(conn); talloc_free(conn); } @@ -198,6 +202,7 @@ conn->ofd.fd = ret; if (osmo_fd_register(&conn->ofd) < 0) { close(ret); + conn->ofd.fd = -1; return -EIO; } return 0; @@ -317,10 +322,10 @@ } /*! \brief Destroy the datagram receiver. Releases Memory. - * Caller must make sure to osmo_dgram_rx_close() before calling * \param[in] conn Datagram Receiver */ void osmo_dgram_rx_destroy(struct osmo_dgram_rx *conn) { + osmo_dgram_rx_close(conn); talloc_free(conn); } @@ -345,6 +350,7 @@ conn->ofd.fd = ret; if (osmo_fd_register(&conn->ofd) < 0) { close(ret); + conn->ofd.fd = -1; return -EIO; } return 0; @@ -356,8 +362,11 @@ * \param[in] conn Stream Server Link to close */ void osmo_dgram_rx_close(struct osmo_dgram_rx *conn) { + if (conn->ofd.fd == -1) + return; osmo_fd_unregister(&conn->ofd); close(conn->ofd.fd); + conn->ofd.fd = -1; } /* diff --git a/src/stream.c b/src/stream.c index 7bac1cc..f899a41 100644 --- a/src/stream.c +++ b/src/stream.c @@ -367,10 +367,11 @@ cli->read_cb = read_cb; } -/*! \brief Destroy a Osmocom stream client +/*! \brief Destroy a Osmocom stream client (includes close) * \param[in] cli Stream Client to destroy */ void osmo_stream_cli_destroy(struct osmo_stream_cli *cli) { + osmo_stream_cli_close(cli); osmo_timer_del(&cli->timer); talloc_free(cli); } @@ -402,6 +403,7 @@ cli->ofd.fd = ret; if (osmo_fd_register(&cli->ofd) < 0) { close(ret); + cli->ofd.fd = -1; return -EIO; } return 0; @@ -601,11 +603,11 @@ link->accept_cb = accept_cb; } -/*! \brief Destroy the stream server link. Releases Memory. - * Caller must make sure to osmo_stream_srv_link_close() before calling +/*! \brief Destroy the stream server link. Closes + Releases Memory. * \param[in] link Stream Server Link */ void osmo_stream_srv_link_destroy(struct osmo_stream_srv_link *link) { + osmo_stream_srv_link_close(link); talloc_free(link); } @@ -630,6 +632,7 @@ link->ofd.fd = ret; if (osmo_fd_register(&link->ofd) < 0) { close(ret); + link->ofd.fd = -1; return -EIO; } return 0; -- To view, visit https://gerrit.osmocom.org/2253 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I29c37da6e8f5be8ab030e68952a8f92add146821 Gerrit-PatchSet: 3 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Apr 10 08:39:42 2017 From: gerrit-no-reply at lists.osmocom.org (Holger Freyther) Date: Mon, 10 Apr 2017 08:39:42 +0000 Subject: libosmo-netif[master]: stream/datagram: Ensure reliable close/destroy In-Reply-To: References: Message-ID: Patch Set 3: (1 comment) https://gerrit.osmocom.org/#/c/2253/3/src/datagram.c File src/datagram.c: PS3, Line 196: osmo_sock_init2 This will not always set conn->ofd to -1. There are error paths before creating a socket. -- To view, visit https://gerrit.osmocom.org/2253 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I29c37da6e8f5be8ab030e68952a8f92add146821 Gerrit-PatchSet: 3 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Mon Apr 10 08:41:35 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 08:41:35 +0000 Subject: [PATCH] libosmo-sccp[master]: Replace unused m3ua_types.h with protocol/m3ua.h In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2191 to look at the new patch set (#3). Replace unused m3ua_types.h with protocol/m3ua.h This is more in line with what we do for SUA in protocol/sua.h Change-Id: I4a32cb698d28b4ccff9280b8512557ab5a353fe3 --- M include/osmocom/sigtran/Makefile.am D include/osmocom/sigtran/m3ua_types.h A include/osmocom/sigtran/protocol/m3ua.h 3 files changed, 149 insertions(+), 130 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/91/2191/3 diff --git a/include/osmocom/sigtran/Makefile.am b/include/osmocom/sigtran/Makefile.am index e168256..ca7de0f 100644 --- a/include/osmocom/sigtran/Makefile.am +++ b/include/osmocom/sigtran/Makefile.am @@ -1,7 +1,7 @@ -sigtran_HEADERS = m3ua_types.h xua_types.h xua_msg.h m2ua_types.h sccp_sap.h \ +sigtran_HEADERS = xua_types.h xua_msg.h m2ua_types.h sccp_sap.h \ sua.h sigtran_sap.h sccp_helpers.h sigtrandir = $(includedir)/osmocom/sigtran -sigtran_prot_HEADERS = protocol/sua.h +sigtran_prot_HEADERS = protocol/sua.h protocol/m3ua.h sigtran_protdir = $(includedir)/osmocom/sigtran/protocol diff --git a/include/osmocom/sigtran/m3ua_types.h b/include/osmocom/sigtran/m3ua_types.h deleted file mode 100644 index c8e62b4..0000000 --- a/include/osmocom/sigtran/m3ua_types.h +++ /dev/null @@ -1,128 +0,0 @@ -#pragma once - -/** - * Types found in the M3UA RFC 4666 - */ - -#include - - -#define M3UA_VERSION 1 - -enum { - M3UA_CLS_MGMT, /* Management (MGMT) Message [IUA/M2UA/M3UA/SUA] */ - M3UA_CLS_TRANS, /* Transfer Messages [M3UA] */ - M3UA_CLS_SSNM, /* SS7 Signalling Network Management (SSNM) Messages [M3UA/SUA] */ - M3UA_CLS_ASPSM, /* ASP State Maintenance (ASPSM) Messages [IUA/M2UA/M3UA/SUA] */ - M3UA_CLS_ASPTM, /* ASP Traffic Maintenance (ASPTM) Messages [IUA/M2UA/M3UA/SUA] */ - M3UA_CLS_RESERVED1, /* Reserved for Other SIGTRAN Adaptation Layers */ - M3UA_CLS_RESERVED2, /* Reserved for Other SIGTRAN Adaptation Layers */ - M3UA_CLS_RESERVED3, /* Reserved for Other SIGTRAN Adaptation Layers */ - M3UA_CLS_RESERVED4, /* Reserved for Other SIGTRAN Adaptation Layers */ - M3UA_CLS_RKM, /* Routing Key Management (RKM) Messages (M3UA) */ -}; - -/** - * Management (MGMT) messages - */ -enum { - M3UA_MGMT_ERROR, /* Error (ERR) */ - M3UA_MGMT_NTFY, /* Notify (NTFY) */ -}; - -/** - * Transfer Messages - */ -enum { - M3UA_TRANS_RESERVED, /* Reserved */ - M3UA_TRANS_DATA, /* Payload Data (DATA) */ -}; - -/** - * SS7 Signalling Network Management (SSNM) Messages - */ -enum { - M3UA_SSNM_RESERVED, /* Reserved */ - M3UA_SSNM_DUNA, /* Destination Unavailable (DUNA) */ - M3UA_SSNM_DAVA, /* Destination Available (DAVA) */ - M3UA_SSNM_DAUD, /* Destination State Audit (DAUD) */ - M3UA_SSNM_SCON, /* Signalling Congestion (SCON) */ - M3UA_SSNM_DUPU, /* Destination User Part Unavailable (DUPU) */ - M3UA_SSNM_DRST, /* Destination Restricted (DRST) */ -}; - -/** - * Application Server Process State Maintaenance (ASPSM) messages - */ -enum { - M3UA_ASPSM_RESERVED, /* Reserved */ - M3UA_ASPSM_UP, /* ASP Up (UP) */ - M3UA_ASPSM_DOWN, /* ASP Down (DOWN) */ - M3UA_ASPSM_BEAT, /* Heartbeat (BEAT) */ - M3UA_ASPSM_UP_ACK, /* ASP Up Ack (UP ACK) */ - M3UA_ASPSM_DOWN_ACK, /* ASP Down Ack (DOWN ACK) */ - M3UA_ASPSM_BEAT_ACK, /* Heartbeat Ack (BEAT ACK) */ -}; - -/** - * Application Server Process Traffic Maintaenance (ASPTM) messages. - */ -enum { - M3UA_ASPTM_RESERVED, /* Reserved */ - M3UA_ASPTM_ACTIV, /* ASP Active (ACTIVE) */ - M3UA_ASPTM_INACTIV, /* ASP Inactive (INACTIVE) */ - M3UA_ASPTM_ACTIV_ACK, /* ASP Active Ack (ACTIVE ACK) */ - M3UA_ASPTM_INACTIV_ACK, /* ASP Inactive Ack (INACTIVE ACK) */ -}; - -/** - * Routing Key Management (RKM) Messages - */ -enum { - M3UA_RKM_RESERVED, /* Reserved */ - M3UA_RKM_REG_REQ, /* Registration Request (REG REQ) */ - M3UA_RKM_REG_RSP, /* Registration Response (REG RSP) */ - M3UA_RKM_DEREG_REQ, /* Deregistration Request (DEREG REQ) */ - M3UA_RKM_DEREG_RSP, /* Deregistration Response (DEREG RSP) */ -}; - -/** - * Tag Values for M3UA - */ -enum { - M3UA_TAG_NET_APPEAR = 0x0200, /* Network Appearance */ - M3UA_TAG_RESERVED1, /* Reserved */ - M3UA_TAG_RESERVED2, /* Reserved */ - M3UA_TAG_RESERVED3, /* Reserved */ - M3UA_TAG_USER_CAUSE, /* User/Cause */ - M3UA_TAG_CONGEST_IND, /* Congestion Indications */ - M3UA_TAG_CONCERN_DEST, /* Concerned Destination */ - M3UA_TAG_ROUTING_KEY, /* Routing Key */ - M3UA_TAG_REG_RESULT, /* Registration Result */ - M3UA_TAG_DEREG_RESULT, /* Deregistration Result */ - M3UA_TAG_LOCAL_ROUT_KEY_IDENT, /* Local Routing Key Identifier */ - M3UA_TAG_DEST_PC, /* Destination Point Code */ - M3UA_TAG_SERV_IND, /* Service Indicators */ - M3UA_TAG_RESERVED4, /* Reserved */ - M3UA_TAG_ORIG_PC_LIST, /* Originating Point Code List */ - M3UA_TAG_RESERVED5, /* Reserved */ - M3UA_TAG_PROTO_DATA, /* Protocol Data */ - M3UA_TAG_RESERVED6, /* Reserved */ - M3UA_TAG_REG_STATUS, /* Registration Status */ - M3UA_TAG_DEREG_STATUS, /* Deregistration Status */ -}; - - -/** - * Protocol data for transport messages. This is - * replacing the MTP L3 header - */ -struct m3ua_protocol_data { - uint32_t opc; - uint32_t dpc; - uint8_t si; - uint8_t ni; - uint8_t mp; - uint8_t sls; - uint8_t data[0]; -} __attribute__((packed)); diff --git a/include/osmocom/sigtran/protocol/m3ua.h b/include/osmocom/sigtran/protocol/m3ua.h new file mode 100644 index 0000000..43d18c5 --- /dev/null +++ b/include/osmocom/sigtran/protocol/m3ua.h @@ -0,0 +1,147 @@ +/* RFC 4666 M3UA SCCP User Adaption */ + +/* (C) 2017 by Harald Welte + * + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once +#include + +#define M3UA_VERSION 1 +#define M3UA_PPID 3 +#define M3UA_PORT 2905 + +/* 3.1.2 Message Classes */ +#define M3UA_MSGC_MGMT 0 +#define M3UA_MSGC_XFER 1 +#define M3UA_MSGC_SNM 2 +#define M3UA_MSGC_ASPSM 3 +#define M3UA_MSGC_ASPTM 4 +#define M3UA_MSGC_RKM 9 + +/* 3.1.3 Message Types */ +#define M3UA_MGMT_ERR 0 +#define M3UA_MGMT_NTFY 1 + +#define M3UA_XFER_DATA 1 + +#define M3UA_SNM_DUNA 1 +#define M3UA_SNM_DAVA 2 +#define M3UA_SNM_DAUD 3 +#define M3UA_SNM_SCON 4 +#define M3UA_SNM_DUPU 5 +#define M3UA_SNM_DRST 6 + +#define M3UA_ASPSM_UP 1 +#define M3UA_ASPSM_DOWN 2 +#define M3UA_ASPSM_BEAT 3 +#define M3UA_ASPSM_UP_ACK 4 +#define M3UA_ASPSM_DOWN_ACK 5 +#define M3UA_ASPSM_BEAT_ACK 6 + +#define M3UA_ASPTM_ACTIVE 1 +#define M3UA_ASPTM_INACTIVE 2 +#define M3UA_ASPTM_ACTIVE_ACK 3 +#define M3UA_ASPTM_INACTIVE_ACK 4 + +#define M3UA_RKM_REG_REQ 1 +#define M3UA_RKM_REG_RSP 2 +#define M3UA_RKM_DEREG_REQ 3 +#define M3UA_RKM_DEREG_RSP 4 + +#define M3UA_IEI_INFO_STRING 0x0004 +#define M3UA_IEI_ROUTE_CTX 0x0006 +#define M3UA_IEI_DIAG_INFO 0x0007 +#define M3UA_IEI_HEARDBT_DATA 0x0009 +#define M3UA_IEI_TRAF_MODE_TYP 0x000b +#define M3UA_IEI_ERR_CODE 0x000c +#define M3UA_IEI_STATUS 0x000d +#define M3UA_IEI_ASP_ID 0x0011 +#define M3UA_IEI_AFFECTED_PC 0x0012 +#define M3UA_IEI_CORR_ID 0x0013 + +/* 3.2 M3UA specific parameters */ + +#define M3UA_IEI_NET_APPEAR 0x0200 +#define M3UA_IEI_USER_CAUSE 0x0204 +#define M3UA_IEI_CONG_IND 0x0205 +#define M3UA_IEI_CONC_DEST 0x0206 +#define M3UA_IEI_ROUT_KEY 0x0207 +#define M3UA_IEI_REG_RESULT 0x0208 +#define M3UA_IEI_DEREG_RESULT 0x0209 +#define M3UA_IEI_LOC_RKEY_ID 0x020a +#define M3UA_IEI_DEST_PC 0x020b +#define M3UA_IEI_SVC_IND 0x020c +#define M3UA_IEI_ORIG_PC 0x020e +#define M3UA_IEI_PROT_DATA 0x0210 +#define M3UA_IEI_REG_STATUS 0x0212 +#define M3UA_IEI_DEREG_STATUS 0x0213 + +/* 3.3.1 Payload Data Message */ +struct m3ua_data_hdr { + uint32_t opc; /* Originating Point Code */ + uint32_t dpc; /* Destination Point Code */ + uint8_t si; /* Service Indicator */ + uint8_t ni; /* Network Indicator */ + uint8_t mp; /* Message Priority */ + uint8_t sls; /* Signalling Link Selection */ +} __attribute__ ((packed)); + +/* 3.8.2 Notify */ + +#define M3UA_NOTIFY(type, info) ((info) << 16 | (type)) +#define M3UA_NOTIFY_T_STATCHG 1 +#define M3UA_NOTIFY_T_OTHER 2 + +#define M3UA_NOTIFY_I_RESERVED 1 +#define M3UA_NOTIFY_I_AS_INACT 2 +#define M3UA_NOTIFY_I_AS_ACT 3 +#define M3UA_NOTIFY_I_AS_PEND 4 + +#define M3UA_NOTIFY_I_OT_INS_RES 1 +#define M3UA_NOTIFY_I_OT_ALT_ASP_ACT 2 +#define M3UA_NOTIFY_I_OT_ASP_FAILURE 3 + +/* 3.8.1 Error */ +enum m3ua_error_code { + M3UA_ERR_INVALID_VERSION = 0x01, + /* not used in M3UA */ + M3UA_ERR_UNSUPP_MSG_CLASS = 0x03, + M3UA_ERR_UNSUPP_MSG_TYPE = 0x04, + M3UA_ERR_UNSUPP_TRAF_MOD_TYP = 0x05, + M3UA_ERR_UNEXPECTED_MSG = 0x06, + M3UA_ERR_PROTOCOL_ERR = 0x07, + /* not used in M3UA */ + M3UA_ERR_INVAL_STREAM_ID = 0x09, + /* not used in M3UA */ + /* not used in M3UA */ + /* not used in M3UA */ + M3UA_ERR_REFUSED_MGMT_BLOCKING = 0x0d, + M3UA_ERR_ASP_ID_REQD = 0x0e, + M3UA_ERR_INVAL_ASP_ID = 0x0f, + /* not used in M3UA */ + M3UA_ERR_INVAL_PARAM_VAL = 0x11, + M3UA_ERR_PARAM_FIELD_ERR = 0x12, + M3UA_ERR_UNEXP_PARAM = 0x13, + M3UA_ERR_DEST_STATUS_UNKN = 0x14, + M3UA_ERR_INVAL_NET_APPEAR = 0x15, + M3UA_ERR_MISSING_PARAM = 0x16, + /* not used in M3UA */ + /* not used in M3UA */ + M3UA_ERR_INVAL_ROUT_CTX = 0x19, + M3UA_ERR_NO_CONFGD_AS_FOR_ASP = 0x1a, +}; -- To view, visit https://gerrit.osmocom.org/2191 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I4a32cb698d28b4ccff9280b8512557ab5a353fe3 Gerrit-PatchSet: 3 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Apr 10 08:46:43 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 08:46:43 +0000 Subject: libosmo-sccp[master]: Replace unused m3ua_types.h with protocol/m3ua.h In-Reply-To: References: Message-ID: Patch Set 3: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2191 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I4a32cb698d28b4ccff9280b8512557ab5a353fe3 Gerrit-PatchSet: 3 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Mon Apr 10 08:46:45 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 08:46:45 +0000 Subject: [MERGED] libosmo-sccp[master]: Replace unused m3ua_types.h with protocol/m3ua.h In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: Replace unused m3ua_types.h with protocol/m3ua.h ...................................................................... Replace unused m3ua_types.h with protocol/m3ua.h This is more in line with what we do for SUA in protocol/sua.h Change-Id: I4a32cb698d28b4ccff9280b8512557ab5a353fe3 --- M include/osmocom/sigtran/Makefile.am D include/osmocom/sigtran/m3ua_types.h A include/osmocom/sigtran/protocol/m3ua.h 3 files changed, 149 insertions(+), 130 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/include/osmocom/sigtran/Makefile.am b/include/osmocom/sigtran/Makefile.am index e168256..ca7de0f 100644 --- a/include/osmocom/sigtran/Makefile.am +++ b/include/osmocom/sigtran/Makefile.am @@ -1,7 +1,7 @@ -sigtran_HEADERS = m3ua_types.h xua_types.h xua_msg.h m2ua_types.h sccp_sap.h \ +sigtran_HEADERS = xua_types.h xua_msg.h m2ua_types.h sccp_sap.h \ sua.h sigtran_sap.h sccp_helpers.h sigtrandir = $(includedir)/osmocom/sigtran -sigtran_prot_HEADERS = protocol/sua.h +sigtran_prot_HEADERS = protocol/sua.h protocol/m3ua.h sigtran_protdir = $(includedir)/osmocom/sigtran/protocol diff --git a/include/osmocom/sigtran/m3ua_types.h b/include/osmocom/sigtran/m3ua_types.h deleted file mode 100644 index c8e62b4..0000000 --- a/include/osmocom/sigtran/m3ua_types.h +++ /dev/null @@ -1,128 +0,0 @@ -#pragma once - -/** - * Types found in the M3UA RFC 4666 - */ - -#include - - -#define M3UA_VERSION 1 - -enum { - M3UA_CLS_MGMT, /* Management (MGMT) Message [IUA/M2UA/M3UA/SUA] */ - M3UA_CLS_TRANS, /* Transfer Messages [M3UA] */ - M3UA_CLS_SSNM, /* SS7 Signalling Network Management (SSNM) Messages [M3UA/SUA] */ - M3UA_CLS_ASPSM, /* ASP State Maintenance (ASPSM) Messages [IUA/M2UA/M3UA/SUA] */ - M3UA_CLS_ASPTM, /* ASP Traffic Maintenance (ASPTM) Messages [IUA/M2UA/M3UA/SUA] */ - M3UA_CLS_RESERVED1, /* Reserved for Other SIGTRAN Adaptation Layers */ - M3UA_CLS_RESERVED2, /* Reserved for Other SIGTRAN Adaptation Layers */ - M3UA_CLS_RESERVED3, /* Reserved for Other SIGTRAN Adaptation Layers */ - M3UA_CLS_RESERVED4, /* Reserved for Other SIGTRAN Adaptation Layers */ - M3UA_CLS_RKM, /* Routing Key Management (RKM) Messages (M3UA) */ -}; - -/** - * Management (MGMT) messages - */ -enum { - M3UA_MGMT_ERROR, /* Error (ERR) */ - M3UA_MGMT_NTFY, /* Notify (NTFY) */ -}; - -/** - * Transfer Messages - */ -enum { - M3UA_TRANS_RESERVED, /* Reserved */ - M3UA_TRANS_DATA, /* Payload Data (DATA) */ -}; - -/** - * SS7 Signalling Network Management (SSNM) Messages - */ -enum { - M3UA_SSNM_RESERVED, /* Reserved */ - M3UA_SSNM_DUNA, /* Destination Unavailable (DUNA) */ - M3UA_SSNM_DAVA, /* Destination Available (DAVA) */ - M3UA_SSNM_DAUD, /* Destination State Audit (DAUD) */ - M3UA_SSNM_SCON, /* Signalling Congestion (SCON) */ - M3UA_SSNM_DUPU, /* Destination User Part Unavailable (DUPU) */ - M3UA_SSNM_DRST, /* Destination Restricted (DRST) */ -}; - -/** - * Application Server Process State Maintaenance (ASPSM) messages - */ -enum { - M3UA_ASPSM_RESERVED, /* Reserved */ - M3UA_ASPSM_UP, /* ASP Up (UP) */ - M3UA_ASPSM_DOWN, /* ASP Down (DOWN) */ - M3UA_ASPSM_BEAT, /* Heartbeat (BEAT) */ - M3UA_ASPSM_UP_ACK, /* ASP Up Ack (UP ACK) */ - M3UA_ASPSM_DOWN_ACK, /* ASP Down Ack (DOWN ACK) */ - M3UA_ASPSM_BEAT_ACK, /* Heartbeat Ack (BEAT ACK) */ -}; - -/** - * Application Server Process Traffic Maintaenance (ASPTM) messages. - */ -enum { - M3UA_ASPTM_RESERVED, /* Reserved */ - M3UA_ASPTM_ACTIV, /* ASP Active (ACTIVE) */ - M3UA_ASPTM_INACTIV, /* ASP Inactive (INACTIVE) */ - M3UA_ASPTM_ACTIV_ACK, /* ASP Active Ack (ACTIVE ACK) */ - M3UA_ASPTM_INACTIV_ACK, /* ASP Inactive Ack (INACTIVE ACK) */ -}; - -/** - * Routing Key Management (RKM) Messages - */ -enum { - M3UA_RKM_RESERVED, /* Reserved */ - M3UA_RKM_REG_REQ, /* Registration Request (REG REQ) */ - M3UA_RKM_REG_RSP, /* Registration Response (REG RSP) */ - M3UA_RKM_DEREG_REQ, /* Deregistration Request (DEREG REQ) */ - M3UA_RKM_DEREG_RSP, /* Deregistration Response (DEREG RSP) */ -}; - -/** - * Tag Values for M3UA - */ -enum { - M3UA_TAG_NET_APPEAR = 0x0200, /* Network Appearance */ - M3UA_TAG_RESERVED1, /* Reserved */ - M3UA_TAG_RESERVED2, /* Reserved */ - M3UA_TAG_RESERVED3, /* Reserved */ - M3UA_TAG_USER_CAUSE, /* User/Cause */ - M3UA_TAG_CONGEST_IND, /* Congestion Indications */ - M3UA_TAG_CONCERN_DEST, /* Concerned Destination */ - M3UA_TAG_ROUTING_KEY, /* Routing Key */ - M3UA_TAG_REG_RESULT, /* Registration Result */ - M3UA_TAG_DEREG_RESULT, /* Deregistration Result */ - M3UA_TAG_LOCAL_ROUT_KEY_IDENT, /* Local Routing Key Identifier */ - M3UA_TAG_DEST_PC, /* Destination Point Code */ - M3UA_TAG_SERV_IND, /* Service Indicators */ - M3UA_TAG_RESERVED4, /* Reserved */ - M3UA_TAG_ORIG_PC_LIST, /* Originating Point Code List */ - M3UA_TAG_RESERVED5, /* Reserved */ - M3UA_TAG_PROTO_DATA, /* Protocol Data */ - M3UA_TAG_RESERVED6, /* Reserved */ - M3UA_TAG_REG_STATUS, /* Registration Status */ - M3UA_TAG_DEREG_STATUS, /* Deregistration Status */ -}; - - -/** - * Protocol data for transport messages. This is - * replacing the MTP L3 header - */ -struct m3ua_protocol_data { - uint32_t opc; - uint32_t dpc; - uint8_t si; - uint8_t ni; - uint8_t mp; - uint8_t sls; - uint8_t data[0]; -} __attribute__((packed)); diff --git a/include/osmocom/sigtran/protocol/m3ua.h b/include/osmocom/sigtran/protocol/m3ua.h new file mode 100644 index 0000000..43d18c5 --- /dev/null +++ b/include/osmocom/sigtran/protocol/m3ua.h @@ -0,0 +1,147 @@ +/* RFC 4666 M3UA SCCP User Adaption */ + +/* (C) 2017 by Harald Welte + * + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once +#include + +#define M3UA_VERSION 1 +#define M3UA_PPID 3 +#define M3UA_PORT 2905 + +/* 3.1.2 Message Classes */ +#define M3UA_MSGC_MGMT 0 +#define M3UA_MSGC_XFER 1 +#define M3UA_MSGC_SNM 2 +#define M3UA_MSGC_ASPSM 3 +#define M3UA_MSGC_ASPTM 4 +#define M3UA_MSGC_RKM 9 + +/* 3.1.3 Message Types */ +#define M3UA_MGMT_ERR 0 +#define M3UA_MGMT_NTFY 1 + +#define M3UA_XFER_DATA 1 + +#define M3UA_SNM_DUNA 1 +#define M3UA_SNM_DAVA 2 +#define M3UA_SNM_DAUD 3 +#define M3UA_SNM_SCON 4 +#define M3UA_SNM_DUPU 5 +#define M3UA_SNM_DRST 6 + +#define M3UA_ASPSM_UP 1 +#define M3UA_ASPSM_DOWN 2 +#define M3UA_ASPSM_BEAT 3 +#define M3UA_ASPSM_UP_ACK 4 +#define M3UA_ASPSM_DOWN_ACK 5 +#define M3UA_ASPSM_BEAT_ACK 6 + +#define M3UA_ASPTM_ACTIVE 1 +#define M3UA_ASPTM_INACTIVE 2 +#define M3UA_ASPTM_ACTIVE_ACK 3 +#define M3UA_ASPTM_INACTIVE_ACK 4 + +#define M3UA_RKM_REG_REQ 1 +#define M3UA_RKM_REG_RSP 2 +#define M3UA_RKM_DEREG_REQ 3 +#define M3UA_RKM_DEREG_RSP 4 + +#define M3UA_IEI_INFO_STRING 0x0004 +#define M3UA_IEI_ROUTE_CTX 0x0006 +#define M3UA_IEI_DIAG_INFO 0x0007 +#define M3UA_IEI_HEARDBT_DATA 0x0009 +#define M3UA_IEI_TRAF_MODE_TYP 0x000b +#define M3UA_IEI_ERR_CODE 0x000c +#define M3UA_IEI_STATUS 0x000d +#define M3UA_IEI_ASP_ID 0x0011 +#define M3UA_IEI_AFFECTED_PC 0x0012 +#define M3UA_IEI_CORR_ID 0x0013 + +/* 3.2 M3UA specific parameters */ + +#define M3UA_IEI_NET_APPEAR 0x0200 +#define M3UA_IEI_USER_CAUSE 0x0204 +#define M3UA_IEI_CONG_IND 0x0205 +#define M3UA_IEI_CONC_DEST 0x0206 +#define M3UA_IEI_ROUT_KEY 0x0207 +#define M3UA_IEI_REG_RESULT 0x0208 +#define M3UA_IEI_DEREG_RESULT 0x0209 +#define M3UA_IEI_LOC_RKEY_ID 0x020a +#define M3UA_IEI_DEST_PC 0x020b +#define M3UA_IEI_SVC_IND 0x020c +#define M3UA_IEI_ORIG_PC 0x020e +#define M3UA_IEI_PROT_DATA 0x0210 +#define M3UA_IEI_REG_STATUS 0x0212 +#define M3UA_IEI_DEREG_STATUS 0x0213 + +/* 3.3.1 Payload Data Message */ +struct m3ua_data_hdr { + uint32_t opc; /* Originating Point Code */ + uint32_t dpc; /* Destination Point Code */ + uint8_t si; /* Service Indicator */ + uint8_t ni; /* Network Indicator */ + uint8_t mp; /* Message Priority */ + uint8_t sls; /* Signalling Link Selection */ +} __attribute__ ((packed)); + +/* 3.8.2 Notify */ + +#define M3UA_NOTIFY(type, info) ((info) << 16 | (type)) +#define M3UA_NOTIFY_T_STATCHG 1 +#define M3UA_NOTIFY_T_OTHER 2 + +#define M3UA_NOTIFY_I_RESERVED 1 +#define M3UA_NOTIFY_I_AS_INACT 2 +#define M3UA_NOTIFY_I_AS_ACT 3 +#define M3UA_NOTIFY_I_AS_PEND 4 + +#define M3UA_NOTIFY_I_OT_INS_RES 1 +#define M3UA_NOTIFY_I_OT_ALT_ASP_ACT 2 +#define M3UA_NOTIFY_I_OT_ASP_FAILURE 3 + +/* 3.8.1 Error */ +enum m3ua_error_code { + M3UA_ERR_INVALID_VERSION = 0x01, + /* not used in M3UA */ + M3UA_ERR_UNSUPP_MSG_CLASS = 0x03, + M3UA_ERR_UNSUPP_MSG_TYPE = 0x04, + M3UA_ERR_UNSUPP_TRAF_MOD_TYP = 0x05, + M3UA_ERR_UNEXPECTED_MSG = 0x06, + M3UA_ERR_PROTOCOL_ERR = 0x07, + /* not used in M3UA */ + M3UA_ERR_INVAL_STREAM_ID = 0x09, + /* not used in M3UA */ + /* not used in M3UA */ + /* not used in M3UA */ + M3UA_ERR_REFUSED_MGMT_BLOCKING = 0x0d, + M3UA_ERR_ASP_ID_REQD = 0x0e, + M3UA_ERR_INVAL_ASP_ID = 0x0f, + /* not used in M3UA */ + M3UA_ERR_INVAL_PARAM_VAL = 0x11, + M3UA_ERR_PARAM_FIELD_ERR = 0x12, + M3UA_ERR_UNEXP_PARAM = 0x13, + M3UA_ERR_DEST_STATUS_UNKN = 0x14, + M3UA_ERR_INVAL_NET_APPEAR = 0x15, + M3UA_ERR_MISSING_PARAM = 0x16, + /* not used in M3UA */ + /* not used in M3UA */ + M3UA_ERR_INVAL_ROUT_CTX = 0x19, + M3UA_ERR_NO_CONFGD_AS_FOR_ASP = 0x1a, +}; -- To view, visit https://gerrit.osmocom.org/2191 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I4a32cb698d28b4ccff9280b8512557ab5a353fe3 Gerrit-PatchSet: 3 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Apr 10 08:49:29 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 08:49:29 +0000 Subject: libosmo-netif[master]: stream/datagram: Ensure reliable close/destroy In-Reply-To: References: Message-ID: Patch Set 3: (1 comment) https://gerrit.osmocom.org/#/c/2253/3/src/datagram.c File src/datagram.c: PS3, Line 196: osmo_sock_init2 > This will not always set conn->ofd to -1. There are error paths before crea Thanks for your review! Howeveer, if it was >= 0 a few lines above, we would have called osmo_dgram_tx_close() which would have set it to -1. Or did I misinterpret your comment? -- To view, visit https://gerrit.osmocom.org/2253 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I29c37da6e8f5be8ab030e68952a8f92add146821 Gerrit-PatchSet: 3 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Mon Apr 10 08:51:31 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 08:51:31 +0000 Subject: libosmo-netif[master]: stream/datagram: Ensure reliable close/destroy In-Reply-To: References: Message-ID: Patch Set 3: > > once again I'm at a loss. This patch passes "make check" without > > any problem on my FreeBSD 10 VM. > > Apparently something (the VM? FreeBSD?) stalled for 10s leading to > the sigalarm handler being called. I re-triggered the build.. and > it didn't run into a timeout. FYI: I started the build job twice (today at 08:48 and at 08:53), and it failed twice before your re-try at 10:20 when it worked again. -- To view, visit https://gerrit.osmocom.org/2253 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I29c37da6e8f5be8ab030e68952a8f92add146821 Gerrit-PatchSet: 3 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Mon Apr 10 08:58:23 2017 From: gerrit-no-reply at lists.osmocom.org (Holger Freyther) Date: Mon, 10 Apr 2017 08:58:23 +0000 Subject: libosmo-netif[master]: stream/datagram: Ensure reliable close/destroy In-Reply-To: References: Message-ID: Patch Set 3: (1 comment) https://gerrit.osmocom.org/#/c/2253/3/src/datagram.c File src/datagram.c: PS3, Line 196: osmo_sock_init2 > Thanks for your review! Howeveer, if it was >= 0 a few lines above, we wou To be honest I have to see how it is used. So just by reviewing this file I see.. osmo_dgram_create() conn->tx->flags = BOGUS; (or dns failure?) osmo_dgram_open() osmo_dgram_tx_open() ret = -int if (ret < 0) return ret; conn->fd == 0 after that. So the OSMO_DGRAM_CLI_F_RECONF case would not be hit? For sure it is a corner case and would require the bind/resolving to fail or passing wrong flags. -- To view, visit https://gerrit.osmocom.org/2253 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I29c37da6e8f5be8ab030e68952a8f92add146821 Gerrit-PatchSet: 3 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Mon Apr 10 09:15:21 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 09:15:21 +0000 Subject: [MERGED] libosmo-sccp[master]: sccp_sap: Add support for N-NOTICE.indication In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: sccp_sap: Add support for N-NOTICE.indication ...................................................................... sccp_sap: Add support for N-NOTICE.indication Change-Id: I6656889b4333e9909cf1c60c24dfc754281547b4 --- M include/osmocom/sigtran/sccp_sap.h 1 file changed, 10 insertions(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/include/osmocom/sigtran/sccp_sap.h b/include/osmocom/sigtran/sccp_sap.h index ec021c7..139567e 100644 --- a/include/osmocom/sigtran/sccp_sap.h +++ b/include/osmocom/sigtran/sccp_sap.h @@ -198,6 +198,15 @@ /* user data */ }; +/* OSMO_SCU_PRIM_N_NOTICE */ +struct osmo_scu_notice_param { + struct osmo_sccp_addr called_addr; + struct osmo_sccp_addr calling_addr; + uint32_t cause; + uint32_t importance; + /* user data */ +}; + struct osmo_scu_prim { struct osmo_prim_hdr oph; union { @@ -206,6 +215,7 @@ struct osmo_scu_disconn_param disconnect; struct osmo_scu_reset_param reset; struct osmo_scu_unitdata_param unitdata; + struct osmo_scu_notice_param notice; } u; }; -- To view, visit https://gerrit.osmocom.org/2200 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I6656889b4333e9909cf1c60c24dfc754281547b4 Gerrit-PatchSet: 4 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Apr 10 09:15:22 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 09:15:22 +0000 Subject: [MERGED] libosmo-sccp[master]: sccp_sap: Add routing indication (RI) to osmo_sccp_addr In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: sccp_sap: Add routing indication (RI) to osmo_sccp_addr ...................................................................... sccp_sap: Add routing indication (RI) to osmo_sccp_addr Change-Id: I4dd23150f4c588b6430c22fc0cb66635994ceea9 --- M include/osmocom/sigtran/sccp_sap.h 1 file changed, 1 insertion(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/include/osmocom/sigtran/sccp_sap.h b/include/osmocom/sigtran/sccp_sap.h index e58e670..ec021c7 100644 --- a/include/osmocom/sigtran/sccp_sap.h +++ b/include/osmocom/sigtran/sccp_sap.h @@ -135,6 +135,7 @@ struct osmo_sccp_addr { uint32_t presence; + enum osmo_sccp_routing_ind ri; struct osmo_sccp_gt gt; uint32_t pc; uint32_t ssn; -- To view, visit https://gerrit.osmocom.org/2199 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I4dd23150f4c588b6430c22fc0cb66635994ceea9 Gerrit-PatchSet: 4 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Apr 10 09:15:22 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 09:15:22 +0000 Subject: [MERGED] libosmo-sccp[master]: sccp_sap: Use zero-terminated string for GT digits in osmo_s... In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: sccp_sap: Use zero-terminated string for GT digits in osmo_sccp_addr ...................................................................... sccp_sap: Use zero-terminated string for GT digits in osmo_sccp_addr This is more natural to most application code, so simply go for ASCII string with NUL-termination rather than an array with explicit length. Change-Id: I6312208cdfa83184be41157a473c96e9120c63db --- M include/osmocom/sigtran/sccp_sap.h 1 file changed, 1 insertion(+), 2 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/include/osmocom/sigtran/sccp_sap.h b/include/osmocom/sigtran/sccp_sap.h index 0aa565a..e58e670 100644 --- a/include/osmocom/sigtran/sccp_sap.h +++ b/include/osmocom/sigtran/sccp_sap.h @@ -127,11 +127,10 @@ struct osmo_sccp_gt { uint8_t gti; - uint8_t nr_digits; uint8_t tt; uint32_t npi; uint32_t nai; - uint8_t digits[32]; + char digits[32]; }; struct osmo_sccp_addr { -- To view, visit https://gerrit.osmocom.org/2198 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I6312208cdfa83184be41157a473c96e9120c63db Gerrit-PatchSet: 4 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Apr 10 09:15:22 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 09:15:22 +0000 Subject: [MERGED] libosmo-sccp[master]: xua_msg: Add concept of xua_msg_class and xua_msg_dialect In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: xua_msg: Add concept of xua_msg_class and xua_msg_dialect ...................................................................... xua_msg: Add concept of xua_msg_class and xua_msg_dialect A xua_msg_class repreents one xUA message class (like M3UA XFER or SUA CL). A dialect is then something like SUA or M3UA, each consisting of as many as 256 message classes. Each class contains value_strings of the individual messages, as well as constraint information on mandatory IEs for each message. Change-Id: Ib538aca295b7b50132bc814b2d7b56cbe5d65bfc --- M include/osmocom/sigtran/xua_msg.h M src/xua_msg.c 2 files changed, 130 insertions(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/include/osmocom/sigtran/xua_msg.h b/include/osmocom/sigtran/xua_msg.h index 23f92c5..6e98409 100644 --- a/include/osmocom/sigtran/xua_msg.h +++ b/include/osmocom/sigtran/xua_msg.h @@ -42,6 +42,23 @@ /* TODO: keep small data in the struct for perf reasons */ }; +struct xua_msg_class { + const char *name; + const struct value_string *msgt_names; + const struct value_string *iei_names; + const uint16_t *mand_ies[256]; +}; + +struct xua_dialect { + const char *name; + uint16_t port; + uint16_t ppid; + int log_subsys; + const struct xua_msg_class *class[256]; +}; + +extern const struct xua_dialect xua_dialect_sua; +extern const struct xua_dialect xua_dialect_m3ua; extern int DXUA; @@ -66,3 +83,10 @@ uint32_t xua_msg_part_get_u32(struct xua_msg_part *part); uint32_t xua_msg_get_u32(struct xua_msg *xua, uint16_t iei); int xua_msg_add_sccp_addr(struct xua_msg *xua, uint16_t iei, const struct osmo_sccp_addr *addr); + +const char *xua_class_msg_name(const struct xua_msg_class *xmc, uint16_t msg_type); +const char *xua_class_iei_name(const struct xua_msg_class *xmc, uint16_t iei); +char *xua_hdr_dump(struct xua_msg *xua, const struct xua_dialect *dialect); +char *xua_msg_dump(struct xua_msg *xua, const struct xua_dialect *dialect); +int xua_dialect_check_all_mand_ies(const struct xua_dialect *dialect, struct xua_msg *xua); + diff --git a/src/xua_msg.c b/src/xua_msg.c index 71511a9..1084622 100644 --- a/src/xua_msg.c +++ b/src/xua_msg.c @@ -301,3 +301,109 @@ return rc; } + +const char *xua_class_msg_name(const struct xua_msg_class *xmc, uint16_t msg_type) +{ + static char class_buf[64]; + + if (xmc && xmc->msgt_names) + return get_value_string(xmc->msgt_names, msg_type); + else { + snprintf(class_buf, sizeof(class_buf), "Unknown 0x%04x", msg_type); + return class_buf; + } +} + +const char *xua_class_iei_name(const struct xua_msg_class *xmc, uint16_t iei) +{ + static char iei_buf[64]; + + if (xmc && xmc->iei_names) + return get_value_string(xmc->iei_names, iei); + else { + snprintf(iei_buf, sizeof(iei_buf), "Unknown 0x%04x", iei); + return iei_buf; + } +} + +char *xua_hdr_dump(struct xua_msg *xua, const struct xua_dialect *dialect) +{ + const struct xua_msg_class *xmc = NULL; + static char buf[128]; + + if (dialect) + xmc = dialect->class[xua->hdr.msg_class]; + if (!xmc) + snprintf(buf, sizeof(buf), "%u:%u", xua->hdr.msg_class, xua->hdr.msg_type); + else + snprintf(buf, sizeof(buf), "%s:%s", xmc->name, + xua_class_msg_name(xmc, xua->hdr.msg_type)); + return buf; +} + +int xua_dialect_check_all_mand_ies(const struct xua_dialect *dialect, struct xua_msg *xua) +{ + uint8_t msg_class = xua->hdr.msg_class; + uint8_t msg_type = xua->hdr.msg_type; + const struct xua_msg_class *xmc = dialect->class[msg_class]; + const uint16_t *ies; + uint16_t ie; + + /* unknown class? */ + if (!xmc) + return 1; + + ies = xmc->mand_ies[msg_type]; + /* no mandatory IEs? */ + if (!ies) + return 1; + + for (ie = *ies; ie; ie = *ies++) { + if (!xua_msg_find_tag(xua, ie)) { + LOGP(dialect->log_subsys, LOGL_ERROR, + "%s Message %s:%s should " + "contain IE %s, but doesn't\n", + dialect->name, xmc->name, + xua_class_msg_name(xmc, msg_type), + xua_class_iei_name(xmc, ie)); + return 0; + } + } + + return 1; +} + +static void append_to_buf(char *buf, bool *comma, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + if (!comma || *comma == true) { + strcat(buf, ","); + } else if (comma) + *comma = true; + vsprintf(buf+strlen(buf), fmt, ap); + va_end(ap); +} + +char *xua_msg_dump(struct xua_msg *xua, const struct xua_dialect *dialect) +{ + static char buf[1024]; + struct xua_msg_part *part; + const struct xua_msg_class *xmc = NULL; + + if (dialect) + xmc = dialect->class[xua->hdr.msg_class]; + + buf[0] = '\0'; + + append_to_buf(buf, NULL, "HDR=(%s,V=%u,LEN=%u)", + xua_hdr_dump(xua, dialect), + xua->hdr.version, xua->hdr.msg_length); + buf[0] = ' '; + llist_for_each_entry(part, &xua->headers, entry) + append_to_buf(buf, NULL, "\n\tPART(T=%s,L=%u,D=%s)", + xua_class_iei_name(xmc, part->tag), part->len, + osmo_hexdump_nospc(part->dat, part->len)); + return buf; +} -- To view, visit https://gerrit.osmocom.org/2197 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ib538aca295b7b50132bc814b2d7b56cbe5d65bfc Gerrit-PatchSet: 4 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Apr 10 09:15:22 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 09:15:22 +0000 Subject: [MERGED] libosmo-sccp[master]: gitignore: add 'tags' files as created by 'make ctags' In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: gitignore: add 'tags' files as created by 'make ctags' ...................................................................... gitignore: add 'tags' files as created by 'make ctags' Change-Id: I9e4ec0e07b996092a1f4e6a01911dc0041111498 --- M .gitignore 1 file changed, 2 insertions(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/.gitignore b/.gitignore index 168690a..abb2458 100644 --- a/.gitignore +++ b/.gitignore @@ -70,3 +70,5 @@ *.pc config.* + +tags -- To view, visit https://gerrit.osmocom.org/2194 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I9e4ec0e07b996092a1f4e6a01911dc0041111498 Gerrit-PatchSet: 3 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Apr 10 09:15:23 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 09:15:23 +0000 Subject: [MERGED] libosmo-sccp[master]: gitignore: use one wildcard line for all test executables In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: gitignore: use one wildcard line for all test executables ...................................................................... gitignore: use one wildcard line for all test executables Change-Id: I53ce43fa8e09646dec56c6cc32b09c4618e9b5a5 --- M .gitignore 1 file changed, 1 insertion(+), 8 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/.gitignore b/.gitignore index abb2458..9d1435f 100644 --- a/.gitignore +++ b/.gitignore @@ -53,14 +53,7 @@ tests/channel/channel_test tests/db/db_test tests/debug/debug_test -tests/gsm0408/gsm0408_test -tests/m2ua/m2ua_test -tests/mtp/mtp_parse_test -tests/sccp/sccp_test -tests/sms/sms_test -tests/timer/timer_test -tests/sigtran/sua_server_test -tests/sigtran/sua_client_test +tests/*/*_test tests/atconfig tests/package.m4 -- To view, visit https://gerrit.osmocom.org/2195 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I53ce43fa8e09646dec56c6cc32b09c4618e9b5a5 Gerrit-PatchSet: 3 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Apr 10 09:15:23 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 09:15:23 +0000 Subject: [MERGED] libosmo-sccp[master]: xua_msg: Add xua_msg_free_tag() and xua_msg_copy_part() In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: xua_msg: Add xua_msg_free_tag() and xua_msg_copy_part() ...................................................................... xua_msg: Add xua_msg_free_tag() and xua_msg_copy_part() ... also, mark input to xua_msg_find_tag as 'const' pointer. Change-Id: I083634db9c3606bcff87700f253054a38a20816d --- M include/osmocom/sigtran/xua_msg.h M src/xua_msg.c 2 files changed, 31 insertions(+), 2 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/include/osmocom/sigtran/xua_msg.h b/include/osmocom/sigtran/xua_msg.h index 2a6e3ae..23f92c5 100644 --- a/include/osmocom/sigtran/xua_msg.h +++ b/include/osmocom/sigtran/xua_msg.h @@ -50,7 +50,10 @@ int xua_msg_add_data(struct xua_msg *msg, uint16_t tag, uint16_t len, uint8_t *dat); -struct xua_msg_part *xua_msg_find_tag(struct xua_msg *msg, uint16_t tag); +struct xua_msg_part *xua_msg_find_tag(const struct xua_msg *msg, uint16_t tag); +int xua_msg_free_tag(struct xua_msg *xua, uint16_t tag); +int xua_msg_copy_part(struct xua_msg *xua_out, uint16_t tag_out, + const struct xua_msg *xua_in, uint16_t tag_in); struct xua_msg *xua_from_msg(const int version, uint16_t len, uint8_t *data); struct msgb *xua_to_msg(const int version, struct xua_msg *msg); diff --git a/src/xua_msg.c b/src/xua_msg.c index 4a3e013..71511a9 100644 --- a/src/xua_msg.c +++ b/src/xua_msg.c @@ -77,7 +77,7 @@ return 0; } -struct xua_msg_part *xua_msg_find_tag(struct xua_msg *xua, uint16_t tag) +struct xua_msg_part *xua_msg_find_tag(const struct xua_msg *xua, uint16_t tag) { struct xua_msg_part *part; @@ -88,6 +88,32 @@ return NULL; } +int xua_msg_free_tag(struct xua_msg *xua, uint16_t tag) +{ + struct xua_msg_part *part; + + llist_for_each_entry(part, &xua->headers, entry) { + if (part->tag == tag) { + llist_del(&part->entry); + talloc_free(part); + return 1; + } + } + return 0; +} + +int xua_msg_copy_part(struct xua_msg *xua_out, uint16_t tag_out, + const struct xua_msg *xua_in, uint16_t tag_in) +{ + const struct xua_msg_part *part; + + part = xua_msg_find_tag(xua_in, tag_in); + if (!part) + return -1; + + return xua_msg_add_data(xua_out, tag_out, part->len, part->dat); +} + struct xua_msg *xua_from_msg(const int version, uint16_t len, uint8_t *data) { struct xua_parameter_hdr *par; -- To view, visit https://gerrit.osmocom.org/2196 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I083634db9c3606bcff87700f253054a38a20816d Gerrit-PatchSet: 4 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Apr 10 09:15:23 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 09:15:23 +0000 Subject: [MERGED] libosmo-sccp[master]: sua.h: Add #define for the varius SUA protocol errors In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: sua.h: Add #define for the varius SUA protocol errors ...................................................................... sua.h: Add #define for the varius SUA protocol errors again using m3ua.h definitions as base whenever applicable. Change-Id: Iec2563cb158b1c18064671564a7502b5c4d82517 --- M include/osmocom/sigtran/protocol/sua.h 1 file changed, 22 insertions(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/include/osmocom/sigtran/protocol/sua.h b/include/osmocom/sigtran/protocol/sua.h index 0ae4131..de67041 100644 --- a/include/osmocom/sigtran/protocol/sua.h +++ b/include/osmocom/sigtran/protocol/sua.h @@ -136,3 +136,25 @@ #define SUA_CAUSE_T_RELEASE 0x0300 #define SUA_CAUSE_T_RESET 0x0400 #define SUA_CAUSE_T_ERROR 0x0500 + +/* 3.9.12 Error: Identical to M3UA, extended by two at the bottom */ +#define SUA_ERR_INVALID_VERSION M3UA_ERR_INVALID_VERSION +#define SUA_ERR_UNSUPP_MSG_CLASS M3UA_ERR_UNSUPP_MSG_CLASS +#define SUA_ERR_UNSUPP_MSG_TYPE M3UA_ERR_UNSUPP_MSG_TYPE +#define SUA_ERR_UNSUPP_TRAF_MOD_TYP M3UA_ERR_UNSUPP_TRAF_MOD_TYP +#define SUA_ERR_UNEXPECTED_MSG M3UA_ERR_UNEXPECTED_MSG +#define SUA_ERR_PROTOCOL_ERR M3UA_ERR_PROTOCOL_ERR +#define SUA_ERR_INVAL_STREAM_ID M3UA_ERR_INVAL_STREAM_ID +#define SUA_ERR_REFUSED_MGMT_BLOCKING M3UA_ERR_REFUSED_MGMT_BLOCKING +#define SUA_ERR_ASP_ID_REQD M3UA_ERR_ASP_ID_REQD +#define SUA_ERR_INVAL_ASP_ID M3UA_ERR_INVAL_ASP_ID +#define SUA_ERR_INVAL_PARAM_VAL M3UA_ERR_INVAL_PARAM_VAL +#define SUA_ERR_PARAM_FIELD_ERR M3UA_ERR_PARAM_FIELD_ERR +#define SUA_ERR_UNEXP_PARAM M3UA_ERR_UNEXP_PARAM +#define SUA_ERR_DEST_STATUS_UNKN M3UA_ERR_DEST_STATUS_UNKN +#define SUA_ERR_INVAL_NET_APPEAR M3UA_ERR_INVAL_NET_APPEAR +#define SUA_ERR_MISSING_PARAM M3UA_ERR_MISSING_PARAM +#define SUA_ERR_INVAL_ROUT_CTX M3UA_ERR_INVAL_ROUT_CTX +#define SUA_ERR_NO_CONFGD_AS_FOR_ASP M3UA_ERR_NO_CONFGD_AS_FOR_ASP +#define SUA_ERR_SUBSYS_STATUS_UNKN 0x1b +#define SUA_ERR_INVAL_LOADSH_LEVEL 0x1c -- To view, visit https://gerrit.osmocom.org/2193 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Iec2563cb158b1c18064671564a7502b5c4d82517 Gerrit-PatchSet: 3 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Apr 10 09:15:23 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 09:15:23 +0000 Subject: [MERGED] libosmo-sccp[master]: sua.h: Define more IEIs; base definitions on m3ua.h In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: sua.h: Define more IEIs; base definitions on m3ua.h ...................................................................... sua.h: Define more IEIs; base definitions on m3ua.h A lot of IEIs are identical between the different xUA dialects, so let's base the SUA definitions on the m3ua definitions. Change-Id: I64c7166cf0b5c8a927ab7e14955100f8d13fe16a --- M include/osmocom/sigtran/protocol/sua.h 1 file changed, 13 insertions(+), 2 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/include/osmocom/sigtran/protocol/sua.h b/include/osmocom/sigtran/protocol/sua.h index d191368..0ae4131 100644 --- a/include/osmocom/sigtran/protocol/sua.h +++ b/include/osmocom/sigtran/protocol/sua.h @@ -21,6 +21,9 @@ #pragma once #include +#include + +#define SUA_VERSION 1 #define SUA_PPID 4 #define SUA_PORT 14001 @@ -76,8 +79,16 @@ #define SUA_CO_COERR 10 #define SUA_CO_COIT 11 /* Connection Oriented Inactiviy Test */ -#define SUA_IEI_ROUTE_CTX 0x0006 -#define SUA_IEI_CORR_ID 0x0013 +#define SUA_IEI_INFO_STRING M3UA_IEI_INFO_STRING +#define SUA_IEI_ROUTE_CTX M3UA_IEI_ROUTE_CTX +#define SUA_IEI_DIAG_INFO M3UA_IEI_DIAG_INFO +#define SUA_IEI_HEARTBT_DATA M3UA_IEI_HEARDBT_DATA +#define SUA_IEI_TRAF_MODE_TYP M3UA_IEI_TRAF_MODE_TYP +#define SUA_IEI_ERR_CODE M3UA_IEI_ERR_CODE +#define SUA_IEI_STATUS M3UA_IEI_STATUS +#define SUA_IEI_ASP_ID M3UA_IEI_ASP_ID +#define SUA_IEI_AFFECTED_PC M3UA_IEI_AFFECTED_PC +#define SUA_IEI_CORR_ID M3UA_IEI_CORR_ID #define SUA_IEI_REG_RESULT 0x0014 #define SUA_IEI_DEREG_RESULT 0x0015 -- To view, visit https://gerrit.osmocom.org/2192 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I64c7166cf0b5c8a927ab7e14955100f8d13fe16a Gerrit-PatchSet: 3 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Apr 10 09:27:26 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 09:27:26 +0000 Subject: [MERGED] libosmo-sccp[master]: sua: Make use of xua_msg_dialect In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: sua: Make use of xua_msg_dialect ...................................................................... sua: Make use of xua_msg_dialect We fill in the data structures of a xua_msg_dialect and make use of it for generic mandatory IE checking and messageheader printing. Change-Id: I966103f30b9be247ba6905ba8e06b87654d9981a --- M src/sua.c 1 file changed, 162 insertions(+), 112 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/sua.c b/src/sua.c index 145bf1a..659104c 100644 --- a/src/sua.c +++ b/src/sua.c @@ -37,6 +37,8 @@ #include #include +#include "xua_internal.h" + #define SUA_MSGB_SIZE 1500 /* Appendix C.4 of Q.714 (all in milliseconds) */ @@ -48,6 +50,161 @@ #define INT_TIMER ( 1 * 60 * 100) #define GUARD_TIMER (23 * 60 * 100) #define RESET_TIMER ( 10 * 100) + +/*********************************************************************** + * Protocol Definition (string tables, mandatory IE checking) + ***********************************************************************/ + +static const struct value_string sua_iei_names[] = { + { SUA_IEI_ROUTE_CTX, "Routing Context" }, + { SUA_IEI_CORR_ID, "Correlation Id" }, + { SUA_IEI_REG_RESULT, "Registration Result" }, + { SUA_IEI_DEREG_RESULT, "De-Registration Result" }, + + { SUA_IEI_S7_HOP_CTR, "SS7 Hop Counter" }, + { SUA_IEI_SRC_ADDR, "Source Address" }, + { SUA_IEI_DEST_ADDR, "Destination Address" }, + { SUA_IEI_SRC_REF, "Source Reference" }, + { SUA_IEI_DEST_REF, "Destination Reference" }, + { SUA_IEI_CAUSE, "Cause" }, + { SUA_IEI_SEQ_NR, "Sequence Number" }, + { SUA_IEI_RX_SEQ_NR, "Receive Sequence Number" }, + { SUA_IEI_ASP_CAPA, "ASP Capability" }, + { SUA_IEI_CREDIT, "Credit" }, + { SUA_IEI_DATA, "Data" }, + { SUA_IEI_USER_CAUSE, "User/Cause" }, + { SUA_IEI_NET_APPEARANCE, "Network Appearance" }, + { SUA_IEI_ROUTING_KEY, "Routing Key" }, + { SUA_IEI_DRN, "DRN Label" }, + { SUA_IEI_TID, "TID Label" }, + { SUA_IEI_SMI, "SMI" }, + { SUA_IEI_IMPORTANCE, "Importance" }, + { SUA_IEI_MSG_PRIO, "Message Priority" }, + { SUA_IEI_PROTO_CLASS, "Protocol Class" }, + { SUA_IEI_SEQ_CTRL, "Sequence Control" }, + { SUA_IEI_SEGMENTATION, "Segmentation" }, + { SUA_IEI_CONG_LEVEL, "Congestion Level" }, + + { SUA_IEI_GT, "Global Title" }, + { SUA_IEI_PC, "Point Code" }, + { SUA_IEI_SSN, "Sub-System Number" }, + { SUA_IEI_IPv4, "IPv4 Address" }, + { SUA_IEI_HOST, "Host Name" }, + { SUA_IEI_IPv6, "IPv6 Address" }, + { 0, NULL } +}; + +#define MAND_IES(msgt, ies) [msgt] = (ies) + +static const uint16_t cldt_mand_ies[] = { + SUA_IEI_ROUTE_CTX, SUA_IEI_PROTO_CLASS, SUA_IEI_SRC_ADDR, + SUA_IEI_DEST_ADDR, SUA_IEI_SEQ_CTRL, SUA_IEI_DATA, 0 +}; +static const uint16_t cldr_mand_ies[] = { + SUA_IEI_ROUTE_CTX, SUA_IEI_CAUSE, SUA_IEI_SRC_ADDR, + SUA_IEI_DEST_ADDR, 0 +}; +static const struct value_string sua_cl_msgt_names[] = { + { SUA_CL_CLDT, "CLDT" }, + { SUA_CL_CLDR, "CLDR" }, + { 0, NULL } +}; +static const struct xua_msg_class msg_class_cl = { + .name = "CL", + .msgt_names = sua_cl_msgt_names, + .iei_names = sua_iei_names, + .mand_ies = { + MAND_IES(SUA_CL_CLDT, cldt_mand_ies), + MAND_IES(SUA_CL_CLDR, cldr_mand_ies), + }, +}; + +static const uint16_t codt_mand_ies[] = { + SUA_IEI_ROUTE_CTX, SUA_IEI_DEST_REF, SUA_IEI_DATA, 0 +}; +static const uint16_t coda_mand_ies[] = { + SUA_IEI_ROUTE_CTX, SUA_IEI_DEST_REF, 0 +}; +static const uint16_t core_mand_ies[] = { + SUA_IEI_ROUTE_CTX, SUA_IEI_PROTO_CLASS, SUA_IEI_SRC_REF, + SUA_IEI_DEST_ADDR, SUA_IEI_SEQ_CTRL, 0 +}; +static const uint16_t coak_mand_ies[] = { + SUA_IEI_ROUTE_CTX, SUA_IEI_PROTO_CLASS, SUA_IEI_DEST_REF, + SUA_IEI_SRC_REF, SUA_IEI_SEQ_CTRL, 0 +}; +static const uint16_t coref_mand_ies[] = { + SUA_IEI_ROUTE_CTX, SUA_IEI_DEST_REF, SUA_IEI_CAUSE, 0 +}; +static const uint16_t relre_mand_ies[] = { + SUA_IEI_ROUTE_CTX, SUA_IEI_DEST_REF, SUA_IEI_SRC_REF, + SUA_IEI_CAUSE, 0 +}; +static const uint16_t relco_mand_ies[] = { + SUA_IEI_ROUTE_CTX, SUA_IEI_DEST_REF, SUA_IEI_SRC_REF, 0 +}; +static const uint16_t resre_mand_ies[] = { + SUA_IEI_ROUTE_CTX, SUA_IEI_DEST_REF, SUA_IEI_SRC_REF, + SUA_IEI_CAUSE, 0 +}; +static const uint16_t resco_mand_ies[] = { + SUA_IEI_ROUTE_CTX, SUA_IEI_DEST_REF, SUA_IEI_SRC_REF, 0 +}; +static const uint16_t coerr_mand_ies[] = { + SUA_IEI_ROUTE_CTX, SUA_IEI_DEST_REF, SUA_IEI_CAUSE, 0 +}; +static const uint16_t coit_mand_ies[] = { + SUA_IEI_ROUTE_CTX, SUA_IEI_PROTO_CLASS, SUA_IEI_SRC_REF, + SUA_IEI_DEST_REF, 0 +}; +static const struct value_string sua_co_msgt_names[] = { + { SUA_CO_CODT, "CODT" }, + { SUA_CO_CODA, "CODA" }, + { SUA_CO_CORE, "CORE" }, + { SUA_CO_COAK, "COAK" }, + { SUA_CO_COREF, "COREF" }, + { SUA_CO_RELRE, "RELRE" }, + { SUA_CO_RELCO, "RELCO" }, + { SUA_CO_RESRE, "RESRE" }, + { SUA_CO_RESCO, "RESCO" }, + { SUA_CO_COERR, "COERR" }, + { SUA_CO_COIT, "COIT" }, + { 0, NULL } +}; +static const struct xua_msg_class msg_class_co = { + .name = "CO", + .msgt_names = sua_co_msgt_names, + .iei_names = sua_iei_names, + .mand_ies = { + MAND_IES(SUA_CO_CODT, codt_mand_ies), + MAND_IES(SUA_CO_CODA, coda_mand_ies), + MAND_IES(SUA_CO_CORE, core_mand_ies), + MAND_IES(SUA_CO_COAK, coak_mand_ies), + MAND_IES(SUA_CO_COREF, coref_mand_ies), + MAND_IES(SUA_CO_RELRE, relre_mand_ies), + MAND_IES(SUA_CO_RELCO, relco_mand_ies), + MAND_IES(SUA_CO_RESRE, resre_mand_ies), + MAND_IES(SUA_CO_RESCO, resco_mand_ies), + MAND_IES(SUA_CO_COERR, coerr_mand_ies), + MAND_IES(SUA_CO_COIT, coit_mand_ies), + }, +}; + +const struct xua_dialect xua_dialect_sua = { + .name = "SUA", + .ppid = SUA_PPID, + .port = SUA_PORT, + .class = { + [SUA_MSGC_MGMT] = &m3ua_msg_class_mgmt, + [SUA_MSGC_SNM] = &m3ua_msg_class_snm, + [SUA_MSGC_ASPSM] = &m3ua_msg_class_aspsm, + [SUA_MSGC_ASPTM] = &m3ua_msg_class_asptm, + [SUA_MSGC_CL] = &msg_class_cl, + [SUA_MSGC_CO] = &msg_class_co, + [SUA_MSGC_RKM] = &m3ua_msg_class_rkm, + }, +}; + static int DSUA = -1; @@ -531,110 +688,6 @@ return rc; } - -/*********************************************************************** - * Mandatory IE checking - ***********************************************************************/ - -#define MAND_IES(msgt, ies) [msgt] = (ies) - -static const uint16_t cldt_mand_ies[] = { - SUA_IEI_ROUTE_CTX, SUA_IEI_PROTO_CLASS, SUA_IEI_SRC_ADDR, - SUA_IEI_DEST_ADDR, SUA_IEI_SEQ_CTRL, SUA_IEI_DATA, 0 -}; - -static const uint16_t cldr_mand_ies[] = { - SUA_IEI_ROUTE_CTX, SUA_IEI_CAUSE, SUA_IEI_SRC_ADDR, - SUA_IEI_DEST_ADDR, 0 -}; - -static const uint16_t codt_mand_ies[] = { - SUA_IEI_ROUTE_CTX, SUA_IEI_DEST_REF, SUA_IEI_DATA, 0 -}; - -static const uint16_t coda_mand_ies[] = { - SUA_IEI_ROUTE_CTX, SUA_IEI_DEST_REF, 0 -}; - -static const uint16_t core_mand_ies[] = { - SUA_IEI_ROUTE_CTX, SUA_IEI_PROTO_CLASS, SUA_IEI_SRC_REF, - SUA_IEI_DEST_ADDR, SUA_IEI_SEQ_CTRL, 0 -}; - -static const uint16_t coak_mand_ies[] = { - SUA_IEI_ROUTE_CTX, SUA_IEI_PROTO_CLASS, SUA_IEI_DEST_REF, - SUA_IEI_SRC_REF, SUA_IEI_SEQ_CTRL, 0 -}; - -static const uint16_t coref_mand_ies[] = { - SUA_IEI_ROUTE_CTX, SUA_IEI_DEST_REF, SUA_IEI_CAUSE, 0 -}; - -static const uint16_t relre_mand_ies[] = { - SUA_IEI_ROUTE_CTX, SUA_IEI_DEST_REF, SUA_IEI_SRC_REF, - SUA_IEI_CAUSE, 0 -}; - -static const uint16_t relco_mand_ies[] = { - SUA_IEI_ROUTE_CTX, SUA_IEI_DEST_REF, SUA_IEI_SRC_REF, 0 -}; - -static const uint16_t resre_mand_ies[] = { - SUA_IEI_ROUTE_CTX, SUA_IEI_DEST_REF, SUA_IEI_SRC_REF, - SUA_IEI_CAUSE, 0 -}; - -static const uint16_t resco_mand_ies[] = { - SUA_IEI_ROUTE_CTX, SUA_IEI_DEST_REF, SUA_IEI_SRC_REF, 0 -}; - -static const uint16_t coerr_mand_ies[] = { - SUA_IEI_ROUTE_CTX, SUA_IEI_DEST_REF, SUA_IEI_CAUSE, 0 -}; - -static const uint16_t coit_mand_ies[] = { - SUA_IEI_ROUTE_CTX, SUA_IEI_PROTO_CLASS, SUA_IEI_SRC_REF, - SUA_IEI_DEST_REF, 0 -}; - -static const uint16_t *mand_ies_cl[256] = { - MAND_IES(SUA_CL_CLDT, cldt_mand_ies), - MAND_IES(SUA_CL_CLDR, cldr_mand_ies), -}; - -static const uint16_t *mand_ies_co[256] = { - MAND_IES(SUA_CO_CODT, codt_mand_ies), - MAND_IES(SUA_CO_CODA, coda_mand_ies), - MAND_IES(SUA_CO_CORE, core_mand_ies), - MAND_IES(SUA_CO_COAK, coak_mand_ies), - MAND_IES(SUA_CO_COREF, coref_mand_ies), - MAND_IES(SUA_CO_RELRE, relre_mand_ies), - MAND_IES(SUA_CO_RELCO, relco_mand_ies), - MAND_IES(SUA_CO_RESRE, resre_mand_ies), - MAND_IES(SUA_CO_RESCO, resco_mand_ies), - MAND_IES(SUA_CO_COERR, coerr_mand_ies), - MAND_IES(SUA_CO_COIT, coit_mand_ies), -}; - -static int check_all_mand_ies(const uint16_t **mand_ies, struct xua_msg *xua) -{ - uint8_t msg_type = xua->hdr.msg_type; - const uint16_t *ies = mand_ies[msg_type]; - uint16_t ie; - - for (ie = *ies; ie; ie = *ies++) { - if (!xua_msg_find_tag(xua, ie)) { - LOGP(DSUA, LOGL_ERROR, "SUA Message %u:%u should " - "contain IE 0x%04x, but doesn't\n", - xua->hdr.msg_class, msg_type, ie); - return 0; - } - } - - return 1; -} - - /*********************************************************************** * Receiving SUA messsages from SCTP ***********************************************************************/ @@ -772,9 +825,6 @@ struct xua_msg *xua, struct msgb *msg) { int rc = -1; - - if (!check_all_mand_ies(mand_ies_cl, xua)) - return -1; switch (xua->hdr.msg_type) { case SUA_CL_CLDT: @@ -1094,9 +1144,6 @@ { int rc = -1; - if (!check_all_mand_ies(mand_ies_co, xua)) - return -1; - switch (xua->hdr.msg_type) { case SUA_CO_CORE: rc = sua_rx_core(link, xua); @@ -1142,8 +1189,11 @@ return -EIO; } - LOGP(DSUA, LOGL_DEBUG, "Received SUA Message (%u:%u)\n", - xua->hdr.msg_class, xua->hdr.msg_type); + LOGP(DSUA, LOGL_DEBUG, "Received SUA Message (%s)\n", + xua_hdr_dump(xua, &xua_dialect_sua)); + + if (!xua_dialect_check_all_mand_ies(&xua_dialect_sua, xua)) + return -1; switch (xua->hdr.msg_class) { case SUA_MSGC_CL: -- To view, visit https://gerrit.osmocom.org/2210 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I966103f30b9be247ba6905ba8e06b87654d9981a Gerrit-PatchSet: 5 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Apr 10 09:27:26 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 09:27:26 +0000 Subject: [MERGED] libosmo-sccp[master]: xua_msg: Add support for msg_event_maps In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: xua_msg: Add support for msg_event_maps ...................................................................... xua_msg: Add support for msg_event_maps msg_event_maps facilitate the mapping from a xUA message (class + type) to an integer event. This is useful when passing xUA messages to a osmo_fsm. Change-Id: Iee1c7fc2bf64219ebb71a0dbe6fd210749332413 --- M include/osmocom/sigtran/xua_msg.h M src/xua_msg.c 2 files changed, 30 insertions(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/include/osmocom/sigtran/xua_msg.h b/include/osmocom/sigtran/xua_msg.h index 60dd693..320da6a 100644 --- a/include/osmocom/sigtran/xua_msg.h +++ b/include/osmocom/sigtran/xua_msg.h @@ -60,6 +60,12 @@ const struct xua_msg_class *class[256]; }; +struct xua_msg_event_map { + uint8_t msg_class; + uint8_t msg_type; + int event; +}; + extern const struct xua_dialect xua_dialect_sua; extern const struct xua_dialect xua_dialect_m3ua; @@ -94,3 +100,6 @@ char *xua_msg_dump(struct xua_msg *xua, const struct xua_dialect *dialect); int xua_dialect_check_all_mand_ies(const struct xua_dialect *dialect, struct xua_msg *xua); +int xua_msg_event_map(const struct xua_msg *xua, + const struct xua_msg_event_map *maps, + unsigned int num_maps); diff --git a/src/xua_msg.c b/src/xua_msg.c index e094cb6..27279ce 100644 --- a/src/xua_msg.c +++ b/src/xua_msg.c @@ -361,6 +361,27 @@ return rc; } +/*! \brief Map from a xua_msg (class+type) to an event + * \param[in] xua xUA message which is to be mapped + * \param[in] maps Table containing msg type+class -> event maps + * \[aram[in] num_maps number of entries in \ref maps + * \returns event >= 0; negative on error (no map found) */ +int xua_msg_event_map(const struct xua_msg *xua, + const struct xua_msg_event_map *maps, + unsigned int num_maps) +{ + int i; + + for (i= 0; i < num_maps; i++) { + const struct xua_msg_event_map *map = &maps[i]; + if (xua->hdr.msg_class == map->msg_class && + xua->hdr.msg_type == map->msg_type) { + return map->event; + } + } + return -1; +} + const char *xua_class_msg_name(const struct xua_msg_class *xmc, uint16_t msg_type) { static char class_buf[64]; -- To view, visit https://gerrit.osmocom.org/2208 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Iee1c7fc2bf64219ebb71a0dbe6fd210749332413 Gerrit-PatchSet: 3 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Apr 10 09:27:27 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 09:27:27 +0000 Subject: [MERGED] libosmo-sccp[master]: Add new 'osmo_ss7' SS7 core code with M3UA, ASP/AS FSM, ... In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: Add new 'osmo_ss7' SS7 core code with M3UA, ASP/AS FSM, ... ...................................................................... Add new 'osmo_ss7' SS7 core code with M3UA, ASP/AS FSM, ... This is what aims to be a rather complete/proper implementation of the SIGTRAN + SS7 protocol suite. It has proper abstraction between the layers with primitives, finite state machines for things like the AS and ASP state machines, support for point code routing, etc. What's not implemented at this point: * re-integration of pre-existing SUA (pending) * actual MTP2 and physical E1/T1 link support * different trafic modes like broadcast/fail-over/load-balance Change-Id: I375eb80f01acc013094851d91d1d3333ebc12bc7 --- M configure.ac M include/osmocom/sigtran/Makefile.am A include/osmocom/sigtran/osmo_ss7.h A include/osmocom/sigtran/protocol/mtp.h M include/osmocom/sigtran/sigtran_sap.h M src/Makefile.am A src/m3ua.c A src/osmo_ss7.c A src/osmo_ss7_hmrt.c A src/osmo_ss7_vty.c A src/xua_as_fsm.c A src/xua_as_fsm.h A src/xua_asp_fsm.c A src/xua_asp_fsm.h A src/xua_internal.h M tests/Makefile.am A tests/ss7/Makefile.am A tests/ss7/ss7_test.c A tests/ss7/ss7_test.err A tests/ss7/ss7_test.ok M tests/testsuite.at 21 files changed, 4,991 insertions(+), 4 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/configure.ac b/configure.ac index 4c3c937..116e168 100644 --- a/configure.ac +++ b/configure.ac @@ -29,6 +29,17 @@ PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 0.3.0) PKG_CHECK_MODULES(LIBOSMONETIF, libosmo-netif >= 0.0.6) +old_LIBS=$LIBS +AC_SEARCH_LIBS([sctp_send], [sctp], [ + AC_DEFINE(HAVE_LIBSCTP, 1, [Define 1 to enable SCTP support]) + AC_SUBST(HAVE_LIBSCTP, [1]) + if test -n "$ac_lib"; then + AC_SUBST(LIBSCTP_LIBS, [-l$ac_lib]) + fi + ], [ + AC_MSG_ERROR([sctp_send not found in searched libs])]) +LIBS=$old_LIBS + # The following test is taken from WebKit's webkit.m4 saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -fvisibility=hidden " @@ -56,5 +67,6 @@ tests/mtp/Makefile tests/m2ua/Makefile tests/sigtran/Makefile + tests/ss7/Makefile Makefile) diff --git a/include/osmocom/sigtran/Makefile.am b/include/osmocom/sigtran/Makefile.am index 2f2912f..ca7a304 100644 --- a/include/osmocom/sigtran/Makefile.am +++ b/include/osmocom/sigtran/Makefile.am @@ -1,7 +1,7 @@ sigtran_HEADERS = xua_types.h xua_msg.h m2ua_types.h sccp_sap.h \ - sua.h sigtran_sap.h sccp_helpers.h mtp_sap.h + sua.h sigtran_sap.h sccp_helpers.h mtp_sap.h osmo_ss7.h sigtrandir = $(includedir)/osmocom/sigtran -sigtran_prot_HEADERS = protocol/sua.h protocol/m3ua.h +sigtran_prot_HEADERS = protocol/sua.h protocol/m3ua.h protocol/mtp.h sigtran_protdir = $(includedir)/osmocom/sigtran/protocol diff --git a/include/osmocom/sigtran/osmo_ss7.h b/include/osmocom/sigtran/osmo_ss7.h new file mode 100644 index 0000000..5bbcd65 --- /dev/null +++ b/include/osmocom/sigtran/osmo_ss7.h @@ -0,0 +1,408 @@ +#pragma once + +#include +#include + +#include +#include +#include +#include +#include + +struct osmo_ss7_instance; +struct osmo_ss7_user; +struct osmo_sccp_instance; +struct osmo_mtp_prim; + +int osmo_ss7_init(void); + +bool osmo_ss7_pc_is_local(struct osmo_ss7_instance *inst, uint32_t pc); +int osmo_ss7_pointcode_parse(struct osmo_ss7_instance *inst, const char *str); +int osmo_ss7_pointcode_parse_mask_or_len(struct osmo_ss7_instance *inst, const char *in); +const char *osmo_ss7_pointcode_print(struct osmo_ss7_instance *inst, uint32_t pc); + +/*********************************************************************** + * SS7 Routing Tables + ***********************************************************************/ + +struct osmo_ss7_route_table { + /*! member in list of routing tables */ + struct llist_head list; + /*! \ref osmo_ss7_instance to which we belong */ + struct osmo_ss7_instance *inst; + /*! list of \ref osmo_ss7_route */ + struct llist_head routes; + + struct { + char *name; + char *description; + } cfg; +}; + +struct osmo_ss7_route_table * +osmo_ss7_route_table_find(struct osmo_ss7_instance *inst, const char *name); +struct osmo_ss7_route_table * +osmo_ss7_route_table_find_or_create(struct osmo_ss7_instance *inst, const char *name); +void osmo_ss7_route_table_destroy(struct osmo_ss7_route_table *rtbl); + +/*********************************************************************** + * SS7 Instances + ***********************************************************************/ + +struct osmo_ss7_instance { + /*! member of global list of instances */ + struct llist_head list; + /*! list of \ref osmo_ss7_linkset */ + struct llist_head linksets; + /*! list of \ref osmo_ss7_as */ + struct llist_head as_list; + /*! list of \ref osmo_ss7_asp */ + struct llist_head asp_list; + /*! list of \ref osmo_ss7_route_table */ + struct llist_head rtable_list; + /* array for faster lookup of user (indexed by service + * indicator) */ + const struct osmo_ss7_user *user[16]; + + struct osmo_ss7_route_table *rtable_system; + + struct osmo_sccp_instance *sccp; + + struct { + uint32_t id; + char *name; + char *description; + uint32_t primary_pc; + /* secondary PCs */ + /* capability PCs */ + uint8_t network_indicator; + struct { + char delimiter; + uint8_t component_len[3]; + } pc_fmt; + } cfg; +}; + +struct osmo_ss7_instance *osmo_ss7_instance_find(uint32_t id); +struct osmo_ss7_instance * +osmo_ss7_instance_find_or_create(void *ctx, uint32_t id); +void osmo_ss7_instance_destroy(struct osmo_ss7_instance *inst); +int osmo_ss7_instance_set_pc_fmt(struct osmo_ss7_instance *inst, + uint8_t c0, uint8_t c1, uint8_t c2); + +/*********************************************************************** + * MTP Users (Users of MTP, such as SCCP or ISUP) + ***********************************************************************/ + +struct osmo_ss7_user { + /* pointer back to SS7 instance */ + struct osmo_ss7_instance *inst; + /* name of the user */ + const char *name; + /* primitive call-back for incoming MTP primitives */ + osmo_prim_cb prim_cb; + /* private data */ + void *priv; +}; + +int osmo_ss7_user_register(struct osmo_ss7_instance *inst, uint8_t service_ind, + struct osmo_ss7_user *user); + +int osmo_ss7_user_unregister(struct osmo_ss7_instance *inst, uint8_t service_ind, + struct osmo_ss7_user *user); + +int osmo_ss7_mtp_to_user(struct osmo_ss7_instance *inst, struct osmo_mtp_prim *omp); + +/* SS7 User wants to issue MTP-TRANSFER.req */ +int osmo_ss7_user_mtp_xfer_req(struct osmo_ss7_instance *inst, + struct osmo_mtp_prim *omp); + +/*********************************************************************** + * SS7 Links + ***********************************************************************/ + +enum osmo_ss7_link_adm_state { + OSMO_SS7_LS_SHUTDOWN, + OSMO_SS7_LS_INHIBITED, + OSMO_SS7_LS_ENABLED, + _NUM_OSMO_SS7_LS +}; + +struct osmo_ss7_linkset; +struct osmo_ss7_link; + +struct osmo_ss7_link { + /*! \ref osmo_ss7_linkset to which we belong */ + struct osmo_ss7_linkset *linkset; + struct { + char *name; + char *description; + uint32_t id; + + enum osmo_ss7_link_adm_state adm_state; + } cfg; +}; + +void osmo_ss7_link_destroy(struct osmo_ss7_link *link); +struct osmo_ss7_link * +osmo_ss7_link_find_or_create(struct osmo_ss7_linkset *lset, uint32_t id); + +/*********************************************************************** + * SS7 Linksets + ***********************************************************************/ + +struct osmo_ss7_linkset { + struct llist_head list; + /*! \ref osmo_ss7_instance to which we belong */ + struct osmo_ss7_instance *inst; + /*! array of \ref osmo_ss7_link */ + struct osmo_ss7_link *links[16]; + + struct { + char *name; + char *description; + uint32_t adjacent_pc; + uint32_t local_pc; + } cfg; +}; + +void osmo_ss7_linkset_destroy(struct osmo_ss7_linkset *lset); +struct osmo_ss7_linkset * +osmo_ss7_linkset_find_by_name(struct osmo_ss7_instance *inst, const char *name); +struct osmo_ss7_linkset * +osmo_ss7_linkset_find_or_create(struct osmo_ss7_instance *inst, const char *name, uint32_t pc); + + +/*********************************************************************** + * SS7 Routes + ***********************************************************************/ + +struct osmo_ss7_route { + /*! member in \ref osmo_ss7_route_table.routes */ + struct llist_head list; + /*! \ref osmo_ss7_route_table to which we belong */ + struct osmo_ss7_route_table *rtable; + + struct { + /*! pointer to linkset (destination) of route */ + struct osmo_ss7_linkset *linkset; + /*! pointer to Application Server */ + struct osmo_ss7_as *as; + } dest; + + struct { + /* FIXME: presence? */ + uint32_t pc; + uint32_t mask; + /*! human-specified linkset name */ + char *linkset_name; + /*! lower priority is higher */ + uint32_t priority; + uint8_t qos_class; + } cfg; +}; + +struct osmo_ss7_route * +osmo_ss7_route_find_dpc(struct osmo_ss7_route_table *rtbl, uint32_t dpc); +struct osmo_ss7_route * +osmo_ss7_route_find_dpc_mask(struct osmo_ss7_route_table *rtbl, uint32_t dpc, + uint32_t mask); +struct osmo_ss7_route * +osmo_ss7_route_lookup(struct osmo_ss7_instance *inst, uint32_t dpc); +struct osmo_ss7_route * +osmo_ss7_route_create(struct osmo_ss7_route_table *rtbl, uint32_t dpc, + uint32_t mask, const char *linkset_name); +void osmo_ss7_route_destroy(struct osmo_ss7_route *rt); + + +/*********************************************************************** + * SS7 Application Servers + ***********************************************************************/ + +struct osmo_ss7_routing_key { + uint32_t context; + + uint32_t pc; + uint8_t si; + uint32_t ssn; + /* FIXME: more complex routing keys */ +}; + +enum osmo_ss7_as_traffic_mode { + OSMO_SS7_AS_TMOD_BCAST, + OSMO_SS7_AS_TMOD_LOADSHARE, + OSMO_SS7_AS_TMOD_ROUNDROBIN, + OSMO_SS7_AS_TMOD_OVERRIDE, + _NUM_OSMO_SS7_ASP_TMOD +}; + +extern struct value_string osmo_ss7_as_traffic_mode_vals[]; + +static inline const char * +osmo_ss7_as_traffic_mode_name(enum osmo_ss7_as_traffic_mode mode) +{ + return get_value_string(osmo_ss7_as_traffic_mode_vals, mode); +} + +enum osmo_ss7_asp_protocol { + OSMO_SS7_ASP_PROT_NONE, + OSMO_SS7_ASP_PROT_SUA, + OSMO_SS7_ASP_PROT_M3UA, + _NUM_OSMO_SS7_ASP_PROT +}; + +extern struct value_string osmo_ss7_asp_protocol_vals[]; + +static inline const char * +osmo_ss7_asp_protocol_name(enum osmo_ss7_asp_protocol mode) +{ + return get_value_string(osmo_ss7_asp_protocol_vals, mode); +} + +int osmo_ss7_asp_protocol_port(enum osmo_ss7_asp_protocol prot); + +struct osmo_ss7_as { + /*! entry in 'ref osmo_ss7_instance.as_list */ + struct llist_head list; + struct osmo_ss7_instance *inst; + + /*! AS FSM */ + struct osmo_fsm_inst *fi; + + struct { + char *name; + char *description; + enum osmo_ss7_asp_protocol proto; + struct osmo_ss7_routing_key routing_key; + enum osmo_ss7_as_traffic_mode mode; + uint32_t recovery_timeout_msec; + uint8_t qos_class; + + struct osmo_ss7_asp *asps[16]; + } cfg; +}; + +struct osmo_ss7_as * +osmo_ss7_as_find_by_name(struct osmo_ss7_instance *inst, const char *name); +struct osmo_ss7_as * +osmo_ss7_as_find_by_rctx(struct osmo_ss7_instance *inst, uint32_t rctx); +struct osmo_ss7_as * +osmo_ss7_as_find_or_create(struct osmo_ss7_instance *inst, const char *name, + enum osmo_ss7_asp_protocol proto); +int osmo_ss7_as_add_asp(struct osmo_ss7_as *as, const char *asp_name); +int osmo_ss7_as_del_asp(struct osmo_ss7_as *as, const char *asp_name); +void osmo_ss7_as_destroy(struct osmo_ss7_as *as); +bool osmo_ss7_as_has_asp(struct osmo_ss7_as *as, + struct osmo_ss7_asp *asp); + + +/*********************************************************************** + * SS7 Application Server Processes + ***********************************************************************/ + +struct osmo_ss7_asp_peer { + char *host; + uint16_t port; +}; + +enum osmo_ss7_asp_admin_state { + /*! no SCTP association with peer */ + OSMO_SS7_ASP_ADM_S_SHUTDOWN, + /*! SCP association, but reject ASP-ACTIVE */ + OSMO_SS7_ASP_ADM_S_BLOCKED, + /*! in normal operation */ + OSMO_SS7_ASP_ADM_S_ENABLED, +}; + +struct osmo_ss7_asp { + /*! entry in \ref osmo_ss7_instance.asp_list */ + struct llist_head list; + struct osmo_ss7_instance *inst; + + /*! ASP FSM */ + struct osmo_fsm_inst *fi; + + /*! \ref osmo_xua_server over which we were established */ + struct osmo_xua_server *xua_server; + + /*! osmo_stream / libosmo-netif handles */ + struct osmo_stream_cli *client; + struct osmo_stream_srv *server; + /*! pre-formatted human readable local/remote socket name */ + char *sock_name; + + /* ASP Identifier for ASP-UP + NTFY */ + uint32_t asp_id; + bool asp_id_present; + + struct { + char *name; + char *description; + enum osmo_ss7_asp_protocol proto; + enum osmo_ss7_asp_admin_state adm_state; + bool is_server; + + struct osmo_ss7_asp_peer local; + struct osmo_ss7_asp_peer remote; + uint8_t qos_class; + } cfg; +}; + +struct osmo_ss7_asp * +osmo_ss7_asp_find_by_name(struct osmo_ss7_instance *inst, const char *name); +struct osmo_ss7_asp * +osmo_ss7_asp_find_or_create(struct osmo_ss7_instance *inst, const char *name, + uint16_t remote_port, uint16_t local_port, + enum osmo_ss7_asp_protocol proto); +void osmo_ss7_asp_destroy(struct osmo_ss7_asp *asp); +int osmo_ss7_asp_send(struct osmo_ss7_asp *asp, struct msgb *msg); +int osmo_ss7_asp_restart(struct osmo_ss7_asp *asp); + +#define LOGPASP(asp, subsys, level, fmt, args ...) \ + LOGP(subsys, level, "asp-%s: " fmt, (asp)->cfg.name, ## args) + +/*********************************************************************** + * xUA Servers + ***********************************************************************/ + +struct osmo_xua_server { + struct llist_head list; + struct osmo_ss7_instance *inst; + + struct osmo_stream_srv_link *server; + + struct { + struct osmo_ss7_asp_peer local; + enum osmo_ss7_asp_protocol proto; + } cfg; +}; + +struct osmo_xua_server * +osmo_ss7_xua_server_find(struct osmo_ss7_instance *inst, enum osmo_ss7_asp_protocol proto, + uint16_t local_port); + +struct osmo_xua_server * +osmo_ss7_xua_server_create(struct osmo_ss7_instance *inst, enum osmo_ss7_asp_protocol proto, + uint16_t local_port, const char *local_host); + +int +osmo_ss7_xua_server_set_local_host(struct osmo_xua_server *xs, const char *local_host); + +void osmo_ss7_xua_server_destroy(struct osmo_xua_server *xs); + +struct osmo_sccp_instance * +osmo_sccp_simple_client(void *ctx, const char *name, uint32_t pc, + enum osmo_ss7_asp_protocol prot, + int local_port, int remote_port, const char *remote_ip); + +struct osmo_sccp_instance * +osmo_sccp_simple_server(void *ctx, uint32_t pc, + enum osmo_ss7_asp_protocol prot, int local_port, + const char *local_ip); + +struct osmo_sccp_instance * +osmo_sccp_simple_server_add_clnt(struct osmo_sccp_instance *inst, + enum osmo_ss7_asp_protocol prot, + const char *name, uint32_t pc, + int local_port, int remote_port, + const char *remote_ip); diff --git a/include/osmocom/sigtran/protocol/mtp.h b/include/osmocom/sigtran/protocol/mtp.h new file mode 100644 index 0000000..8b990c0 --- /dev/null +++ b/include/osmocom/sigtran/protocol/mtp.h @@ -0,0 +1,24 @@ +#pragma once + +#include + +/* Chapter 15.17.4 of Q.704 + RFC4666 3.4.5. */ +/* Section 5.1 of ETSI EG 201 693: MTP SI code allocations (for NI= 00) */ +enum mtp_si_ni00 { + MTP_SI_SNM = 0, + MTP_SI_STM = 1, + MTP_SI_SCCP = 3, + MTP_SI_TUP = 4, + MTP_SI_ISUP = 5, + MTP_SI_DUP = 6, /* call related */ + MTP_SI_DUP_FAC = 7, /* facility related */ + MTP_SI_TESTING = 8, + MTP_SI_B_ISUP = 9, + MTP_SI_SAT_ISUP = 10, + MTP_SI_SPEECH = 11, /* speech processing element */ + MTP_SI_AAL2_SIG = 12, + MTP_SI_BICC = 13, + MTP_SI_GCP = 14, +}; + +extern const struct value_string mtp_si_vals[]; diff --git a/include/osmocom/sigtran/sigtran_sap.h b/include/osmocom/sigtran/sigtran_sap.h index 544fc44..d29c37d 100644 --- a/include/osmocom/sigtran/sigtran_sap.h +++ b/include/osmocom/sigtran/sigtran_sap.h @@ -3,4 +3,39 @@ enum osmo_sigtran_sap { SCCP_SAP_USER = _SAP_SS7_BASE, + /* xUA Layer Manager */ + XUA_SAP_LM, + MTP_SAP_USER, }; + +enum osmo_xlm_prim_type { + OSMO_XLM_PRIM_M_SCTP_ESTABLISH, + OSMO_XLM_PRIM_M_SCTP_RELEASE, + OSMO_XLM_PRIM_M_SCTP_RESTART, + OSMO_XLM_PRIM_M_SCTP_STATUS, + OSMO_XLM_PRIM_M_ASP_STATUS, + OSMO_XLM_PRIM_M_AS_STATUS, + OSMO_XLM_PRIM_M_NOTIFY, + OSMO_XLM_PRIM_M_ERROR, + OSMO_XLM_PRIM_M_ASP_UP, + OSMO_XLM_PRIM_M_ASP_DOWN, + OSMO_XLM_PRIM_M_ASP_ACTIVE, + OSMO_XLM_PRIM_M_ASP_INACTIVE, + OSMO_XLM_PRIM_M_AS_ACTIVE, + OSMO_XLM_PRIM_M_AS_INACTIVE, + OSMO_XLM_PRIM_M_AS_DOWN, + /* optional as per spec, not implemented yet */ + OSMO_XLM_PRIM_M_RK_REG, + OSMO_XLM_PRIM_M_RK_DEREG, +}; + + +struct osmo_xlm_prim { + struct osmo_prim_hdr oph; + union { + } u; +}; + +#define msgb_xlm_prim(msg) ((struct osmo_xlm_prim *)(msg)->l1h) + +char *osmo_xlm_prim_name(struct osmo_prim_hdr *oph); diff --git a/src/Makefile.am b/src/Makefile.am index 26482a0..f7f4ccc 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,6 +1,8 @@ AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir) AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMONETIF_CFLAGS) +noinst_HEADERS = xua_asp_fsm.h xua_as_fsm.h xua_internal.h + # Legacy static libs sccpdir = $(libdir) @@ -24,6 +26,7 @@ # documentation before making any modification LIBVERSION=0:0:0 -libosmo_sigtran_la_SOURCES = sccp_sap.c sua.c xua_msg.c sccp_helpers.c +libosmo_sigtran_la_SOURCES = sccp_sap.c sua.c m3ua.c xua_msg.c sccp_helpers.c \ + osmo_ss7.c osmo_ss7_hmrt.c xua_asp_fsm.c xua_as_fsm.c libosmo_sigtran_la_LDFLAGS = -version-info $(LIBVERSION) -no-undefined -export-symbols-regex '^osmo_' libosmo_sigtran_la_LIBADD = $(LIBOSMOCORE_LIBS) $(LIBOSMONETIF_LIBS) $(LIBSCTP_LIBS) diff --git a/src/m3ua.c b/src/m3ua.c new file mode 100644 index 0000000..8ec82c5 --- /dev/null +++ b/src/m3ua.c @@ -0,0 +1,669 @@ +/* Minimal implementation of RFC 4666 - MTP3 User Adaptation Layer */ + +/* (C) 2015-2017 by Harald Welte + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include "xua_asp_fsm.h" +#include "xua_internal.h" + +#define M3UA_MSGB_SIZE 1500 + +/*********************************************************************** + * Protocol Definition (string tables, mandatory IE checking) + ***********************************************************************/ + +/* Section 3.8.1 */ +const struct value_string m3ua_err_names[] = { + { M3UA_ERR_INVALID_VERSION, "Invalid Version" }, + { M3UA_ERR_UNSUPP_MSG_CLASS, "Unsupported Message Class" }, + { M3UA_ERR_UNSUPP_MSG_TYPE, "Unsupported Message Type" }, + { M3UA_ERR_UNSUPP_TRAF_MOD_TYP, "Unsupported Traffic Mode Type" }, + { M3UA_ERR_UNEXPECTED_MSG, "Unexpected Message" }, + { M3UA_ERR_PROTOCOL_ERR, "Protocol Error" }, + { M3UA_ERR_INVAL_STREAM_ID, "Invalid Stream Identifier" }, + { M3UA_ERR_REFUSED_MGMT_BLOCKING, "Refused - Management Blocking" }, + { M3UA_ERR_ASP_ID_REQD, "ASP Identifier Required" }, + { M3UA_ERR_INVAL_ASP_ID, "Invalid ASP Identifier" }, + { M3UA_ERR_INVAL_PARAM_VAL, "Invalid Parameter Value" }, + { M3UA_ERR_PARAM_FIELD_ERR, "Parameter Field Error" }, + { M3UA_ERR_UNEXP_PARAM, "Unexpected Parameter" }, + { M3UA_ERR_DEST_STATUS_UNKN, "Destination Status Unknown" }, + { M3UA_ERR_INVAL_NET_APPEAR, "Invalid Network Appearance" }, + { M3UA_ERR_MISSING_PARAM, "Missing Parameter" }, + { M3UA_ERR_INVAL_ROUT_CTX, "Invalid Routing Context" }, + { M3UA_ERR_NO_CONFGD_AS_FOR_ASP,"No Configured AS for ASP" }, + { SUA_ERR_SUBSYS_STATUS_UNKN, "Subsystem Status Unknown" }, + { SUA_ERR_INVAL_LOADSH_LEVEL, "Invalid loadsharing level" }, + { 0, NULL } +}; + +const struct value_string m3ua_ntfy_type_names[] = { + { M3UA_NOTIFY_T_STATCHG, "State Change" }, + { M3UA_NOTIFY_T_OTHER, "Other" }, + { 0, NULL } +}; + +const struct value_string m3ua_ntfy_stchg_names[] = { + { M3UA_NOTIFY_I_RESERVED, "Reserved" }, + { M3UA_NOTIFY_I_AS_INACT, "AS Inactive" }, + { M3UA_NOTIFY_I_AS_ACT, "AS Active" }, + { M3UA_NOTIFY_I_AS_PEND, "AS Pending" }, + { 0, NULL } +}; + +const struct value_string m3ua_ntfy_other_names[] = { + { M3UA_NOTIFY_I_OT_INS_RES, "Insufficient ASP Resouces active in AS" }, + { M3UA_NOTIFY_I_OT_ALT_ASP_ACT, "Alternative ASP Active" }, + { M3UA_NOTIFY_I_OT_ASP_FAILURE, "ASP Failure" }, + { 0, NULL } +}; + +static const struct value_string m3ua_iei_names[] = { + { M3UA_IEI_INFO_STRING, "INFO String" }, + { M3UA_IEI_ROUTE_CTX, "Routing Context" }, + { M3UA_IEI_DIAG_INFO, "Diagnostic Info" }, + { M3UA_IEI_HEARDBT_DATA, "Heartbeat Data" }, + { M3UA_IEI_TRAF_MODE_TYP, "Traffic Mode Type" }, + { M3UA_IEI_ERR_CODE, "Error Code" }, + { M3UA_IEI_STATUS, "Status" }, + { M3UA_IEI_ASP_ID, "ASP Identifier" }, + { M3UA_IEI_AFFECTED_PC, "Affected Point Code" }, + { M3UA_IEI_CORR_ID, "Correlation Id" }, + + { M3UA_IEI_NET_APPEAR, "Network Appearance" }, + { M3UA_IEI_USER_CAUSE, "User/Cause" }, + { M3UA_IEI_CONG_IND, "Congestion Indication" }, + { M3UA_IEI_CONC_DEST, "Concerned Destination" }, + { M3UA_IEI_ROUT_KEY, "Routing Key" }, + { M3UA_IEI_REG_RESULT, "Registration Result" }, + { M3UA_IEI_DEREG_RESULT, "De-Registration Result" }, + { M3UA_IEI_LOC_RKEY_ID, "Local Routing-Key Identifier" }, + { M3UA_IEI_DEST_PC, "Destination Point Code" }, + { M3UA_IEI_SVC_IND, "Service Indicators" }, + { M3UA_IEI_ORIG_PC, "Originating Point Code List" }, + { M3UA_IEI_PROT_DATA, "Protocol Data" }, + { M3UA_IEI_REG_STATUS, "Registration Status" }, + { M3UA_IEI_DEREG_STATUS, "De-Registration Status" }, + { 0, NULL } +}; + +#define MAND_IES(msgt, ies) [msgt] = (ies) + +/* XFER */ +static const uint16_t data_mand_ies[] = { + M3UA_IEI_PROT_DATA, 0 +}; +static const struct value_string m3ua_xfer_msgt_names[] = { + { M3UA_XFER_DATA, "DATA" }, + { 0, NULL } +}; +static const struct xua_msg_class msg_class_xfer = { + .name = "XFER", + .msgt_names = m3ua_xfer_msgt_names, + .mand_ies = { + MAND_IES(M3UA_XFER_DATA, data_mand_ies), + }, +}; + +/* SNM */ +static const uint16_t duna_mand_ies[] = { + M3UA_IEI_AFFECTED_PC, 0 +}; +static const uint16_t dava_mand_ies[] = { + M3UA_IEI_AFFECTED_PC, 0 +}; +static const uint16_t daud_mand_ies[] = { + M3UA_IEI_AFFECTED_PC, 0 +}; +static const uint16_t scon_mand_ies[] = { + M3UA_IEI_AFFECTED_PC, 0 +}; +static const uint16_t dupu_mand_ies[] = { + M3UA_IEI_AFFECTED_PC, M3UA_IEI_USER_CAUSE, 0 +}; +static const uint16_t drst_mand_ies[] = { + M3UA_IEI_AFFECTED_PC, 0 +}; +static const struct value_string m3ua_snm_msgt_names[] = { + { M3UA_SNM_DUNA, "DUNA" }, + { M3UA_SNM_DAVA, "DAVA" }, + { M3UA_SNM_DAUD, "DAUD" }, + { M3UA_SNM_SCON, "SCON" }, + { M3UA_SNM_DUPU, "DUPU" }, + { M3UA_SNM_DRST, "DRST" }, + { 0, NULL } +}; +const struct xua_msg_class m3ua_msg_class_snm = { + .name = "SNM", + .msgt_names = m3ua_snm_msgt_names, + .mand_ies = { + MAND_IES(M3UA_SNM_DUNA, duna_mand_ies), + MAND_IES(M3UA_SNM_DAVA, dava_mand_ies), + MAND_IES(M3UA_SNM_DAUD, daud_mand_ies), + MAND_IES(M3UA_SNM_SCON, scon_mand_ies), + MAND_IES(M3UA_SNM_DUPU, dupu_mand_ies), + MAND_IES(M3UA_SNM_DRST, drst_mand_ies), + }, +}; + +/* ASPSM */ +static const struct value_string m3ua_aspsm_msgt_names[] = { + { M3UA_ASPSM_UP, "UP" }, + { M3UA_ASPSM_DOWN, "DOWN" }, + { M3UA_ASPSM_BEAT, "BEAT" }, + { M3UA_ASPSM_UP_ACK, "UP-ACK" }, + { M3UA_ASPSM_DOWN_ACK, "DOWN-ACK" }, + { M3UA_ASPSM_BEAT_ACK, "BEAT-ACK" }, + { 0, NULL } +}; +const struct xua_msg_class m3ua_msg_class_aspsm = { + .name = "ASPSM", + .msgt_names = m3ua_aspsm_msgt_names, +}; + +/* ASPTM */ +const struct value_string m3ua_asptm_msgt_names[] = { + { M3UA_ASPTM_ACTIVE, "ACTIVE" }, + { M3UA_ASPTM_INACTIVE, "INACTIVE" }, + { M3UA_ASPTM_ACTIVE_ACK,"ACTIVE-ACK" }, + { M3UA_ASPTM_INACTIVE_ACK, "INACTIVE-ACK" }, + { 0, NULL } +}; +const struct xua_msg_class m3ua_msg_class_asptm = { + .name = "ASPTM", + .msgt_names = m3ua_asptm_msgt_names, + .iei_names = m3ua_iei_names, +}; + +/* MGMT */ +static const uint16_t err_req_ies[] = { + M3UA_IEI_ERR_CODE, 0 +}; +static const uint16_t ntfy_req_ies[] = { + M3UA_IEI_STATUS, 0 +}; +static const struct value_string m3ua_mgmt_msgt_names[] = { + { M3UA_MGMT_ERR, "ERROR" }, + { M3UA_MGMT_NTFY, "NOTIFY" }, + { 0, NULL } +}; +const struct xua_msg_class m3ua_msg_class_mgmt = { + .name = "MGMT", + .msgt_names = m3ua_mgmt_msgt_names, + .iei_names = m3ua_iei_names, + .mand_ies = { + MAND_IES(M3UA_MGMT_ERR, err_req_ies), + MAND_IES(M3UA_MGMT_NTFY, ntfy_req_ies), + }, +}; + +/* RKM */ +static const uint16_t reg_req_ies[] = { + M3UA_IEI_ROUT_KEY, 0 +}; +static const uint16_t reg_rsp_ies[] = { + M3UA_IEI_REG_RESULT, 0 +}; +static const uint16_t dereg_req_ies[] = { + M3UA_IEI_ROUT_KEY, 0 +}; +static const uint16_t dereg_rsp_ies[] = { + M3UA_IEI_DEREG_RESULT, 0 +}; +static const struct value_string m3ua_rkm_msgt_names[] = { + { M3UA_RKM_REG_REQ, "REG-REQ" }, + { M3UA_RKM_REG_RSP, "REG-RESP" }, + { M3UA_RKM_DEREG_REQ, "DEREG-REQ" }, + { M3UA_RKM_DEREG_RSP, "DEREG-RESP" }, + { 0, NULL } +}; +const struct xua_msg_class m3ua_msg_class_rkm = { + .name = "RKM", + .msgt_names = m3ua_rkm_msgt_names, + .iei_names = m3ua_iei_names, + .mand_ies = { + MAND_IES(M3UA_RKM_REG_REQ, reg_req_ies), + MAND_IES(M3UA_RKM_REG_RSP, reg_rsp_ies), + MAND_IES(M3UA_RKM_DEREG_REQ, dereg_req_ies), + MAND_IES(M3UA_RKM_DEREG_RSP, dereg_rsp_ies), + }, +}; + +/* M3UA dialect of XUA, MGMT,XFER,SNM,ASPSM,ASPTM,RKM */ +const struct xua_dialect xua_dialect_m3ua = { + .name = "M3UA", + .ppid = M3UA_PPID, + .port = M3UA_PORT, + .log_subsys = DLM3UA, + .class = { + [M3UA_MSGC_MGMT] = &m3ua_msg_class_mgmt, + [M3UA_MSGC_XFER] = &msg_class_xfer, + [M3UA_MSGC_SNM] = &m3ua_msg_class_snm, + [M3UA_MSGC_ASPSM] = &m3ua_msg_class_aspsm, + [M3UA_MSGC_ASPTM] = &m3ua_msg_class_asptm, + [M3UA_MSGC_RKM] = &m3ua_msg_class_rkm, + }, +}; + +/* convert osmo_mtp_transfer_param to m3ua_data_hdr */ +void mtp_xfer_param_to_m3ua_dh(struct m3ua_data_hdr *mdh, + const struct osmo_mtp_transfer_param *param) +{ + mdh->opc = htonl(param->opc); + mdh->dpc = htonl(param->dpc); + mdh->si = param->sio & 0xF; + mdh->ni = (param->sio >> 6) & 0x3; + mdh->mp = (param->sio >> 4) & 0x3; + mdh->sls = param->sls; +} + +/* convert m3ua_data_hdr to osmo_mtp_transfer_param */ +void m3ua_dh_to_xfer_param(struct osmo_mtp_transfer_param *param, + const struct m3ua_data_hdr *mdh) +{ + param->opc = ntohl(mdh->opc); + param->dpc = ntohl(mdh->dpc); + param->sls = mdh->sls; + /* re-construct SIO */ + param->sio = (mdh->si & 0xF) | + (mdh->mp & 0x3 << 4) | + (mdh->ni & 0x3 << 6); +} + +#define M3UA_MSG_SIZE 2048 +#define M3UA_MSG_HEADROOM 512 + +struct msgb *m3ua_msgb_alloc(const char *name) +{ + if (!name) + name = "M3UA"; + return msgb_alloc_headroom(M3UA_MSG_SIZE+M3UA_MSG_HEADROOM, + M3UA_MSG_HEADROOM, name); +} + +/*********************************************************************** + * ERROR generation + ***********************************************************************/ + +static struct xua_msg *m3ua_gen_error(uint32_t err_code) +{ + struct xua_msg *xua = xua_msg_alloc(); + + xua->hdr = XUA_HDR(M3UA_MSGC_MGMT, M3UA_MGMT_ERR); + xua->hdr.version = M3UA_VERSION; + xua_msg_add_u32(xua, M3UA_IEI_ERR_CODE, err_code); + + return xua; +} + +static struct xua_msg *m3ua_gen_error_msg(uint32_t err_code, struct msgb *msg) +{ + struct xua_msg *xua = m3ua_gen_error(err_code); + unsigned int len_max_40 = msgb_length(msg); + + if (len_max_40 > 40) + len_max_40 = 40; + + xua_msg_add_data(xua, M3UA_IEI_DIAG_INFO, len_max_40, msgb_data(msg)); + + return xua; +} + +/*********************************************************************** + * NOTIFY generation + ***********************************************************************/ + +/* RFC4666 Ch. 3.8.2. Notify */ +struct xua_msg *m3ua_encode_notify(const struct m3ua_notify_params *npar) +{ + struct xua_msg *xua = xua_msg_alloc(); + uint32_t status; + + xua->hdr = XUA_HDR(M3UA_MSGC_MGMT, M3UA_MGMT_NTFY); + + status = M3UA_NOTIFY(htons(npar->status_type), htons(npar->status_info)); + /* cannot use xua_msg_add_u32() as it does endian conversion */ + xua_msg_add_data(xua, M3UA_IEI_STATUS, sizeof(status), (uint8_t *) &status); + + /* Conditional: ASP Identifier */ + if (npar->presence & NOTIFY_PAR_P_ASP_ID) + xua_msg_add_u32(xua, M3UA_IEI_ASP_ID, npar->asp_id); + + /* Optional Routing Context */ + if (npar->presence & NOTIFY_PAR_P_ROUTE_CTX) + xua_msg_add_u32(xua, M3UA_IEI_ROUTE_CTX, npar->route_ctx); + + /* Optional: Info String */ + if (npar->info_string) + xua_msg_add_data(xua, M3UA_IEI_INFO_STRING, + strlen(npar->info_string)+1, + (uint8_t *) npar->info_string); + + return xua; +} + +/* RFC4666 Ch. 3.8.2. Notify */ +int m3ua_decode_notify(struct m3ua_notify_params *npar, void *ctx, + const struct xua_msg *xua) +{ + struct xua_msg_part *info_ie, *aspid_ie, *status_ie, *rctx_ie; + uint32_t status; + + /* cannot use xua_msg_get_u32() as it does endian conversion */ + status_ie = xua_msg_find_tag(xua, M3UA_IEI_STATUS); + status = *(uint32_t *) status_ie->dat; + + aspid_ie = xua_msg_find_tag(xua, M3UA_IEI_ASP_ID); + rctx_ie = xua_msg_find_tag(xua, M3UA_IEI_ROUTE_CTX); + info_ie = xua_msg_find_tag(xua, M3UA_IEI_INFO_STRING); + + npar->presence = 0; + npar->status_type = ntohs(status & 0xffff); + npar->status_info = ntohs(status >> 16); + + if (aspid_ie) { + npar->asp_id = xua_msg_part_get_u32(aspid_ie); + npar->presence |= NOTIFY_PAR_P_ASP_ID; + } + + if (rctx_ie) { + npar->route_ctx = xua_msg_part_get_u32(rctx_ie); + npar->presence |= NOTIFY_PAR_P_ROUTE_CTX; + } + + if (info_ie) { + npar->info_string = talloc_size(ctx, info_ie->len); + memcpy(npar->info_string, info_ie->dat, info_ie->len); + } else + npar->info_string = NULL; + + return 0; +} + +/*********************************************************************** + * Transmitting M3UA messsages to SCTP + ***********************************************************************/ + +static int m3ua_tx_xua_asp(struct osmo_ss7_asp *asp, struct xua_msg *xua) +{ + struct msgb *msg = xua_to_msg(M3UA_VERSION, xua); + + OSMO_ASSERT(asp->cfg.proto == OSMO_SS7_ASP_PROT_M3UA); + + xua_msg_free(xua); + + if (!msg) { + LOGP(DLM3UA, LOGL_ERROR, "Error encoding M3UA Msg\n"); + return -1; + } + + msgb_sctp_ppid(msg) = M3UA_PPID; + return osmo_ss7_asp_send(asp, msg); +} + +/*! \brief Send a given xUA message via a given M3UA Application Server + * \param[in] as Application Server through which to send \ref xua + * \param[in] xua xUA message to be sent + * \return 0 on success; negative on error */ +int m3ua_tx_xua_as(struct osmo_ss7_as *as, struct xua_msg *xua) +{ + struct osmo_ss7_asp *asp; + unsigned int i; + + OSMO_ASSERT(as->cfg.proto == OSMO_SS7_ASP_PROT_M3UA); + + for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) { + asp = as->cfg.asps[i]; + if (!asp) + continue; + if (asp) + break; + } + if (!asp) { + LOGP(DLM3UA, LOGL_ERROR, "No ASP entroy in AS, dropping message\n"); + xua_msg_free(xua); + return -ENODEV; + } + + return m3ua_tx_xua_asp(asp, xua); +} + +/*********************************************************************** + * Receiving M3UA messsages from SCTP + ***********************************************************************/ + +/* obtain the destination point code from a M3UA message in XUA fmt * */ +struct m3ua_data_hdr *data_hdr_from_m3ua(struct xua_msg *xua) +{ + struct xua_msg_part *data_ie; + struct m3ua_data_hdr *data_hdr; + + if (xua->hdr.msg_class != M3UA_MSGC_XFER || + xua->hdr.msg_type != M3UA_XFER_DATA) + return NULL; + + data_ie = xua_msg_find_tag(xua, M3UA_IEI_PROT_DATA); + if (!data_ie) + return NULL; + data_hdr = (struct m3ua_data_hdr *) data_ie->dat; + + return data_hdr; +} + +static int m3ua_rx_xfer(struct osmo_ss7_asp *asp, struct xua_msg *xua) +{ + struct m3ua_data_hdr *dh; + + /* store the MTP-level information in the xua_msg for use by + * higher layer protocols */ + dh = data_hdr_from_m3ua(xua); + OSMO_ASSERT(dh); + m3ua_dh_to_xfer_param(&xua->mtp, dh); + + return m3ua_hmdc_rx_from_l2(asp->inst, xua); +} + +static int m3ua_rx_mgmt_err(struct osmo_ss7_asp *asp, struct xua_msg *xua) +{ + uint32_t err_code = xua_msg_get_u32(xua, M3UA_IEI_ERR_CODE); + + LOGPASP(asp, DLM3UA, LOGL_ERROR, "Received MGMT_ERR '%s': %s\n", + get_value_string(m3ua_err_names, err_code), + xua_msg_dump(xua, &xua_dialect_m3ua)); + + /* NEVER return != 0 here, as we cannot respont to an ERR + * message with another ERR! */ + return 0; +} + +static int m3ua_rx_mgmt_ntfy(struct osmo_ss7_asp *asp, struct xua_msg *xua) +{ + struct m3ua_notify_params ntfy; + const char *type_name, *info_name; + + m3ua_decode_notify(&ntfy, asp, xua); + + type_name = get_value_string(m3ua_ntfy_type_names, ntfy.status_type); + + switch (ntfy.status_type) { + case M3UA_NOTIFY_T_STATCHG: + info_name = get_value_string(m3ua_ntfy_stchg_names, + ntfy.status_info); + break; + case M3UA_NOTIFY_T_OTHER: + info_name = get_value_string(m3ua_ntfy_other_names, + ntfy.status_info); + break; + default: + info_name = "NULL"; + break; + } + LOGPASP(asp, DLM3UA, LOGL_NOTICE, "Received NOTIFY Type %s:%s (%s)\n", + type_name, info_name, + ntfy.info_string ? ntfy.info_string : ""); + + if (ntfy.info_string) + talloc_free(ntfy.info_string); + + /* TODO: should we report this soemwhere? */ + return 0; +} + +static int m3ua_rx_mgmt(struct osmo_ss7_asp *asp, struct xua_msg *xua) +{ + switch (xua->hdr.msg_type) { + case M3UA_MGMT_ERR: + return m3ua_rx_mgmt_err(asp, xua); + case M3UA_MGMT_NTFY: + return m3ua_rx_mgmt_ntfy(asp, xua); + default: + return M3UA_ERR_UNSUPP_MSG_TYPE; + } +} + +/* map from M3UA ASPSM/ASPTM to xua_asp_fsm event */ +static const struct xua_msg_event_map m3ua_aspxm_map[] = { + { M3UA_MSGC_ASPSM, M3UA_ASPSM_UP, XUA_ASP_E_ASPSM_ASPUP }, + { M3UA_MSGC_ASPSM, M3UA_ASPSM_DOWN, XUA_ASP_E_ASPSM_ASPDN }, + { M3UA_MSGC_ASPSM, M3UA_ASPSM_BEAT, XUA_ASP_E_ASPSM_BEAT }, + { M3UA_MSGC_ASPSM, M3UA_ASPSM_UP_ACK, XUA_ASP_E_ASPSM_ASPUP_ACK }, + { M3UA_MSGC_ASPSM, M3UA_ASPSM_DOWN_ACK, XUA_ASP_E_ASPSM_ASPDN_ACK }, + { M3UA_MSGC_ASPSM, M3UA_ASPSM_BEAT_ACK, XUA_ASP_E_ASPSM_BEAT_ACK }, + { M3UA_MSGC_ASPTM, M3UA_ASPTM_ACTIVE, XUA_ASP_E_ASPTM_ASPAC }, + { M3UA_MSGC_ASPTM, M3UA_ASPTM_INACTIVE, XUA_ASP_E_ASPTM_ASPIA }, + { M3UA_MSGC_ASPTM, M3UA_ASPTM_ACTIVE_ACK, XUA_ASP_E_ASPTM_ASPAC_ACK }, + { M3UA_MSGC_ASPTM, M3UA_ASPTM_INACTIVE_ACK, XUA_ASP_E_ASPTM_ASPIA_ACK }, +}; + + +static int m3ua_rx_asp(struct osmo_ss7_asp *asp, struct xua_msg *xua) +{ + int event; + + /* map from the M3UA message class and message type to the XUA + * ASP FSM event number */ + event = xua_msg_event_map(xua, m3ua_aspxm_map, + ARRAY_SIZE(m3ua_aspxm_map)); + if (event < 0) + return M3UA_ERR_UNSUPP_MSG_TYPE; + + /* deliver that event to the ASP FSM */ + osmo_fsm_inst_dispatch(asp->fi, event, xua); + + return 0; +} + +/*! \brief process M3UA message received from socket + * \param[in] asp Application Server Process receiving \ref msg + * \param[in] msg received message buffer + * \returns 0 on success; negative on error */ +int m3ua_rx_msg(struct osmo_ss7_asp *asp, struct msgb *msg) +{ + struct xua_msg *xua = NULL, *err = NULL; + int rc = 0; + + OSMO_ASSERT(asp->cfg.proto == OSMO_SS7_ASP_PROT_M3UA); + + /* caller owns msg memory, we shall neither free it here nor + * keep references beyond the executin of this function and its + * callees */ + + xua = xua_from_msg(M3UA_VERSION, msgb_length(msg), msgb_data(msg)); + if (!xua) { + struct xua_common_hdr *hdr = (struct xua_common_hdr *) msg->data; + + LOGPASP(asp, DLM3UA, LOGL_ERROR, "Unable to parse incoming " + "M3UA message\n"); + + if (hdr->version != M3UA_VERSION) + err = m3ua_gen_error_msg(M3UA_ERR_INVALID_VERSION, msg); + else + err = m3ua_gen_error_msg(M3UA_ERR_PARAM_FIELD_ERR, msg); + goto out; + } + + LOGPASP(asp, DLM3UA, LOGL_DEBUG, "Received M3UA Message (%s)\n", + xua_hdr_dump(xua, &xua_dialect_m3ua)); + + if (!xua_dialect_check_all_mand_ies(&xua_dialect_m3ua, xua)) { + err = m3ua_gen_error_msg(M3UA_ERR_MISSING_PARAM, msg); + goto out; + } + + /* TODO: check for SCTP Strema ID */ + /* TODO: check if any AS configured in ASP */ + /* TODO: check for valid routing context */ + + switch (xua->hdr.msg_class) { + case M3UA_MSGC_XFER: + rc = m3ua_rx_xfer(asp, xua); + break; + case M3UA_MSGC_ASPSM: + case M3UA_MSGC_ASPTM: + rc = m3ua_rx_asp(asp, xua); + break; + break; + case M3UA_MSGC_MGMT: + rc = m3ua_rx_mgmt(asp, xua); + break; + case M3UA_MSGC_SNM: + case M3UA_MSGC_RKM: + /* FIXME */ + LOGPASP(asp, DLM3UA, LOGL_NOTICE, "Received unsupported M3UA " + "Message Class %u\n", xua->hdr.msg_class); + err = m3ua_gen_error_msg(M3UA_ERR_UNSUPP_MSG_CLASS, msg); + break; + default: + LOGPASP(asp, DLM3UA, LOGL_NOTICE, "Received unknown M3UA " + "Message Class %u\n", xua->hdr.msg_class); + err = m3ua_gen_error_msg(M3UA_ERR_UNSUPP_MSG_CLASS, msg); + break; + } + + if (rc > 0) + err = m3ua_gen_error_msg(rc, msg); + +out: + if (err) + m3ua_tx_xua_asp(asp, err); + + xua_msg_free(xua); + + return rc; +} diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c new file mode 100644 index 0000000..74c54bb --- /dev/null +++ b/src/osmo_ss7.c @@ -0,0 +1,1490 @@ +/* Core SS7 Instance/Linkset/Link/AS/ASP Handling */ + +/* (C) 2015-2017 by Harald Welte + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "xua_internal.h" +#include "xua_asp_fsm.h" +#include "xua_as_fsm.h" + +#define ASP_MSGB_SIZE 1500 +#define MAX_PC_STR_LEN 32 + +static bool ss7_initialized = false; + +static LLIST_HEAD(ss7_instances); +static LLIST_HEAD(ss7_xua_servers); + +struct value_string osmo_ss7_as_traffic_mode_vals[] = { + { OSMO_SS7_AS_TMOD_BCAST, "broadcast" }, + { OSMO_SS7_AS_TMOD_LOADSHARE, "loadshare" }, + { OSMO_SS7_AS_TMOD_ROUNDROBIN, "round-robin" }, + { OSMO_SS7_AS_TMOD_OVERRIDE, "override" }, + { 0, NULL } +}; + +struct value_string osmo_ss7_asp_protocol_vals[] = { + { OSMO_SS7_ASP_PROT_NONE, "none" }, + { OSMO_SS7_ASP_PROT_SUA, "sua" }, + { OSMO_SS7_ASP_PROT_M3UA, "m3ua" }, + { 0, NULL } +}; + +#define LOGSS7(inst, level, fmt, args ...) \ + LOGP(DLSS7, level, "%u: " fmt, (inst)->cfg.id, ## args) + + +/*********************************************************************** + * SS7 Point Code Parsing / Printing + ***********************************************************************/ + +/* like strcat() but appends a single character */ +static int strnappendchar(char *str, char c, size_t n) +{ + unsigned int curlen = strlen(str); + + if (n < curlen + 2) + return -1; + + str[curlen] = c; + str[curlen+1] = '\0'; + + return curlen+1; +} + +/* generate a format string for formatting a point code. The result can + * e.g. be used with sscanf() or sprintf() */ +static const char *gen_pc_fmtstr(struct osmo_ss7_instance *inst, + unsigned int *num_comp_exp) +{ + static char buf[MAX_PC_STR_LEN]; + unsigned int num_comp = 0; + + buf[0] = '\0'; + strcat(buf, "%u"); + num_comp++; + + if (inst->cfg.pc_fmt.component_len[1] == 0) + goto out; + strnappendchar(buf, inst->cfg.pc_fmt.delimiter, sizeof(buf)); + strcat(buf, "%u"); + num_comp++; + + if (inst->cfg.pc_fmt.component_len[2] == 0) + goto out; + strnappendchar(buf, inst->cfg.pc_fmt.delimiter, sizeof(buf)); + strcat(buf, "%u"); + num_comp++; +out: + if (num_comp_exp) + *num_comp_exp = num_comp; + return buf; +} + +/* get number of components we expect for a point code, depending on the + * configuration of this ss7_instance */ +static unsigned int num_pc_comp_exp(struct osmo_ss7_instance *inst) +{ + unsigned int num_comp_exp = 1; + + if (inst->cfg.pc_fmt.component_len[1]) + num_comp_exp++; + if (inst->cfg.pc_fmt.component_len[2]) + num_comp_exp++; + + return num_comp_exp; +} + +/* get the total width (in bits) of the point-codes in this ss7_instance */ +static unsigned int get_pc_width(struct osmo_ss7_instance *inst) +{ + return inst->cfg.pc_fmt.component_len[0] + + inst->cfg.pc_fmt.component_len[1] + + inst->cfg.pc_fmt.component_len[2]; +} + +/* get the number of bits we must shift the given component of a point + * code in this ss7_instance */ +static unsigned int get_pc_comp_shift(struct osmo_ss7_instance *inst, + unsigned int comp_num) +{ + uint32_t pc_width = get_pc_width(inst); + switch (comp_num) { + case 0: + return pc_width - inst->cfg.pc_fmt.component_len[0]; + case 1: + return pc_width - inst->cfg.pc_fmt.component_len[0] - + inst->cfg.pc_fmt.component_len[1]; + case 2: + return 0; + default: + return -EINVAL; + } +} + +static uint32_t pc_comp_shift_and_mask(struct osmo_ss7_instance *inst, + unsigned int comp_num, uint32_t pc) +{ + unsigned int shift = get_pc_comp_shift(inst, comp_num); + uint32_t mask = (1 << inst->cfg.pc_fmt.component_len[comp_num]) - 1; + + return (pc >> shift) & mask; +} + +/* parse a point code according to the structure configured for this + * ss7_instance */ +int osmo_ss7_pointcode_parse(struct osmo_ss7_instance *inst, const char *str) +{ + unsigned int component[3]; + unsigned int num_comp_exp = num_pc_comp_exp(inst); + const char *fmtstr = gen_pc_fmtstr(inst, &num_comp_exp); + int i, rc; + + rc = sscanf(str, fmtstr, &component[0], &component[1], &component[2]); + /* ensure all components were parsed */ + if (rc != num_comp_exp) + goto err; + + /* check none of the component values exceeds what can be + * represented within its bit-width */ + for (i = 0; i < num_comp_exp; i++) { + if (component[i] >= (1 << inst->cfg.pc_fmt.component_len[i])) + goto err; + } + + /* shift them all together */ + rc = (component[0] << get_pc_comp_shift(inst, 0)); + if (num_comp_exp > 1) + rc |= (component[1] << get_pc_comp_shift(inst, 1)); + if (num_comp_exp > 2) + rc |= (component[2] << get_pc_comp_shift(inst, 2)); + + return rc; + +err: + LOGSS7(inst, LOGL_NOTICE, "Error parsing Pointcode '%s'\n", str); + return -EINVAL; +} + +/* print a pointcode according to the structure configured for this + * ss7_instance */ +const char *osmo_ss7_pointcode_print(struct osmo_ss7_instance *inst, uint32_t pc) +{ + static char buf[MAX_PC_STR_LEN]; + unsigned int num_comp_exp = num_pc_comp_exp(inst); + const char *fmtstr = gen_pc_fmtstr(inst, &num_comp_exp); + + OSMO_ASSERT(fmtstr); + snprintf(buf, sizeof(buf), fmtstr, + pc_comp_shift_and_mask(inst, 0, pc), + pc_comp_shift_and_mask(inst, 1, pc), + pc_comp_shift_and_mask(inst, 2, pc)); + + return buf; +} + +int osmo_ss7_pointcode_parse_mask_or_len(struct osmo_ss7_instance *inst, const char *in) +{ + unsigned int width = get_pc_width(inst); + + if (in[0] == '/') { + /* parse mask by length */ + int masklen = atoi(in+1); + if (masklen < 0 || masklen > 32) + return -EINVAL; + if (masklen == 0) + return 0; + return (0xFFFFFFFF << (width - masklen)) & ((1 << width)-1); + } else { + /* parse mask as point code */ + return osmo_ss7_pointcode_parse(inst, in); + } +} + +static const uint16_t prot2port[] = { + [OSMO_SS7_ASP_PROT_NONE] = 0, + [OSMO_SS7_ASP_PROT_SUA] = SUA_PORT, + [OSMO_SS7_ASP_PROT_M3UA] = M3UA_PORT, +}; + +int osmo_ss7_asp_protocol_port(enum osmo_ss7_asp_protocol prot) +{ + if (prot >= ARRAY_SIZE(prot2port)) + return -EINVAL; + else + return prot2port[prot]; +} + +/*********************************************************************** + * SS7 Instance + ***********************************************************************/ + +/*! \brief Find a SS7 Instance with given ID + * \param[in] id ID for which to search + * \returns \ref osmo_ss7_instance on success; NULL on error */ +struct osmo_ss7_instance * +osmo_ss7_instance_find(uint32_t id) +{ + OSMO_ASSERT(ss7_initialized); + + struct osmo_ss7_instance *inst; + llist_for_each_entry(inst, &ss7_instances, list) { + if (inst->cfg.id == id) + return inst; + } + return NULL; +} + +/*! \brief Find or create a SS7 Instance + * \param[in] ctx talloc allocation context to use for allocations + * \param[in] id ID of SS7 Instance + * \returns \ref osmo_ss7_instance on success; NULL on error */ +struct osmo_ss7_instance * +osmo_ss7_instance_find_or_create(void *ctx, uint32_t id) +{ + struct osmo_ss7_instance *inst; + + OSMO_ASSERT(ss7_initialized); + + inst = osmo_ss7_instance_find(id); + if (!inst) + inst = talloc_zero(ctx, struct osmo_ss7_instance); + if (!inst) + return NULL; + + inst->cfg.id = id; + LOGSS7(inst, LOGL_INFO, "Creating SS7 Instance\n"); + + INIT_LLIST_HEAD(&inst->linksets); + INIT_LLIST_HEAD(&inst->as_list); + INIT_LLIST_HEAD(&inst->asp_list); + INIT_LLIST_HEAD(&inst->rtable_list); + inst->rtable_system = osmo_ss7_route_table_find_or_create(inst, "system"); + + /* default point code structure + formatting */ + inst->cfg.pc_fmt.delimiter = '.'; + inst->cfg.pc_fmt.component_len[0] = 3; + inst->cfg.pc_fmt.component_len[1] = 8; + inst->cfg.pc_fmt.component_len[2] = 3; + + llist_add(&inst->list, &ss7_instances); + + return inst; +} + +/*! \brief Destroy a SS7 Instance + * \param[in] inst SS7 Instance to be destroyed */ +void osmo_ss7_instance_destroy(struct osmo_ss7_instance *inst) +{ + struct osmo_ss7_linkset *lset; + struct osmo_ss7_as *as; + struct osmo_ss7_asp *asp; + + OSMO_ASSERT(ss7_initialized); + LOGSS7(inst, LOGL_INFO, "Destroying SS7 Instance\n"); + + llist_for_each_entry(asp, &inst->asp_list, list) + osmo_ss7_asp_destroy(asp); + + llist_for_each_entry(as, &inst->as_list, list) + osmo_ss7_as_destroy(as); + + llist_for_each_entry(lset, &inst->linksets, list) + osmo_ss7_linkset_destroy(lset); + + llist_del(&inst->list); + talloc_free(inst); +} + +/*! \brief Set the point code format used in given SS7 instance */ +int osmo_ss7_instance_set_pc_fmt(struct osmo_ss7_instance *inst, + uint8_t c0, uint8_t c1, uint8_t c2) +{ + if (c0+c1+c2 > 32) + return -EINVAL; + + if (c0+c1+c2 > 14) + LOGSS7(inst, LOGL_NOTICE, "Point Code Format %u-%u-%u " + "is longer than 14 bits, odd?\n", c0, c1, c2); + + inst->cfg.pc_fmt.component_len[0] = c0; + inst->cfg.pc_fmt.component_len[1] = c1; + inst->cfg.pc_fmt.component_len[2] = c2; + + return 0; +} + +/*********************************************************************** + * MTP Users (Users of MTP, such as SCCP or ISUP) + ***********************************************************************/ + +/*! \brief Register a MTP user for a given service indicator + * \param[in] inst SS7 instance for which we register the user + * \param[in] service_ind Service (ISUP, SCCP, ...) + * \param[in] user SS7 user (including primitive call-back) + * \returns 0 on success; negative on error */ +int osmo_ss7_user_register(struct osmo_ss7_instance *inst, uint8_t service_ind, + struct osmo_ss7_user *user) +{ + if (service_ind >= ARRAY_SIZE(inst->user)) + return -EINVAL; + + if (inst->user[service_ind]) + return -EBUSY; + + DEBUGP(DLSS7, "registering user=%s for SI %u with priv %p\n", + user->name, service_ind, user->priv); + + user->inst = inst; + inst->user[service_ind] = user; + + return 0; +} + +/*! \brief Unregister a MTP user for a given service indicator + * \param[in] inst SS7 instance for which we register the user + * \param[in] service_ind Service (ISUP, SCCP, ...) + * \param[in] user (optional) SS7 user. If present, we will not + * unregister other users + * \returns 0 on success; negative on error */ +int osmo_ss7_user_unregister(struct osmo_ss7_instance *inst, uint8_t service_ind, + struct osmo_ss7_user *user) +{ + if (service_ind >= ARRAY_SIZE(inst->user)) + return -EINVAL; + + if (!inst->user[service_ind]) + return -ENODEV; + + if (user && (inst->user[service_ind] != user)) + return -EINVAL; + + user->inst = NULL; + inst->user[service_ind] = NULL; + + return 0; +} + +/* deliver to a local MTP user */ +int osmo_ss7_mtp_to_user(struct osmo_ss7_instance *inst, struct osmo_mtp_prim *omp) +{ + uint32_t service_ind; + const struct osmo_ss7_user *osu; + + if (omp->oph.sap != MTP_SAP_USER || + omp->oph.primitive != OSMO_MTP_PRIM_TRANSFER || + omp->oph.operation != PRIM_OP_INDICATION) { + LOGP(DLSS7, LOGL_ERROR, "Unsupported Primitive\n"); + return -EINVAL; + } + + service_ind = omp->u.transfer.sio & 0xF; + osu = inst->user[service_ind]; + + if (!osu) { + LOGP(DLSS7, LOGL_NOTICE, "No MTP-User for SI %u\n", service_ind); + return -ENODEV; + } + + DEBUGP(DLSS7, "delivering MTP-TRANSFER.ind to user %s, priv=%p\n", + osu->name, osu->priv); + return osu->prim_cb(&omp->oph, (void *) osu->priv); +} + +/*********************************************************************** + * SS7 Linkset + ***********************************************************************/ + +/*! \brief Destroy a SS7 Linkset + * \param[in] lset Linkset to be destroyed */ +void osmo_ss7_linkset_destroy(struct osmo_ss7_linkset *lset) +{ + unsigned int i; + + OSMO_ASSERT(ss7_initialized); + LOGSS7(lset->inst, LOGL_INFO, "Destroying Linkset %s\n", + lset->cfg.name); + + for (i = 0; i < ARRAY_SIZE(lset->links); i++) { + struct osmo_ss7_link *link = lset->links[i]; + if (!link) + continue; + osmo_ss7_link_destroy(link); + } + llist_del(&lset->list); + talloc_free(lset); +} + +/*! \brief Find SS7 Linkset by given name + * \param[in] inst SS7 Instance in which to look + * \param[in] name Name of SS7 Linkset + * \returns pointer to linkset on success; NULL on error */ +struct osmo_ss7_linkset * +osmo_ss7_linkset_find_by_name(struct osmo_ss7_instance *inst, const char *name) +{ + struct osmo_ss7_linkset *lset; + OSMO_ASSERT(ss7_initialized); + llist_for_each_entry(lset, &inst->linksets, list) { + if (!strcmp(name, lset->cfg.name)) + return lset; + } + return NULL; +} + +/*! \brief Find or allocate SS7 Linkset + * \param[in] inst SS7 Instance in which we operate + * \param[in] name Name of SS7 Linkset + * \param[in] pc Adjacent Pointcode + * \returns pointer to Linkset on success; NULL on error */ +struct osmo_ss7_linkset * +osmo_ss7_linkset_find_or_create(struct osmo_ss7_instance *inst, const char *name, uint32_t pc) +{ + struct osmo_ss7_linkset *lset; + + OSMO_ASSERT(ss7_initialized); + lset = osmo_ss7_linkset_find_by_name(inst, name); + if (lset && lset->cfg.adjacent_pc != pc) + return NULL; + + if (!lset) { + LOGSS7(inst, LOGL_INFO, "Creating Linkset %s\n", name); + lset = talloc_zero(inst, struct osmo_ss7_linkset); + lset->inst = inst; + lset->cfg.adjacent_pc = pc; + lset->cfg.name = talloc_strdup(lset, name); + llist_add_tail(&lset->list, &inst->linksets); + } + + return lset; +} + +/*********************************************************************** + * SS7 Link + ***********************************************************************/ + +/*! \brief Destryo SS7 Link + * \param[in] link SS7 Link to be destroyed */ +void osmo_ss7_link_destroy(struct osmo_ss7_link *link) +{ + struct osmo_ss7_linkset *lset = link->linkset; + + OSMO_ASSERT(ss7_initialized); + LOGSS7(lset->inst, LOGL_INFO, "Destroying Link %s:%u\n", + lset->cfg.name, link->cfg.id); + /* FIXME: do cleanup */ + lset->links[link->cfg.id] = NULL; + talloc_free(link); +} + +/*! \brief Find or create SS7 Link with given ID in given Linkset + * \param[in] lset SS7 Linkset on which we operate + * \param[in] id Link number within Linkset + * \returns pointer to SS7 Link on success; NULL on error */ +struct osmo_ss7_link * +osmo_ss7_link_find_or_create(struct osmo_ss7_linkset *lset, uint32_t id) +{ + struct osmo_ss7_link *link; + + OSMO_ASSERT(ss7_initialized); + if (id >= ARRAY_SIZE(lset->links)) + return NULL; + + if (lset->links[id]) { + link = lset->links[id]; + } else { + LOGSS7(lset->inst, LOGL_INFO, "Creating Link %s:%u\n", + lset->cfg.name, id); + link = talloc_zero(lset, struct osmo_ss7_link); + if (!link) + return NULL; + link->linkset = lset; + lset->links[id] = link; + link->cfg.id = id; + } + + return link; +} + + +/*********************************************************************** + * SS7 Route Tables + ***********************************************************************/ + +struct osmo_ss7_route_table * +osmo_ss7_route_table_find(struct osmo_ss7_instance *inst, const char *name) +{ + struct osmo_ss7_route_table *rtbl; + OSMO_ASSERT(ss7_initialized); + llist_for_each_entry(rtbl, &inst->rtable_list, list) { + if (!strcmp(rtbl->cfg.name, name)) + return rtbl; + } + return NULL; +} + +struct osmo_ss7_route_table * +osmo_ss7_route_table_find_or_create(struct osmo_ss7_instance *inst, const char *name) +{ + struct osmo_ss7_route_table *rtbl; + + OSMO_ASSERT(ss7_initialized); + rtbl = osmo_ss7_route_table_find(inst, name); + if (!rtbl) { + LOGSS7(inst, LOGL_INFO, "Creating Route Table %s\n", name); + rtbl = talloc_zero(inst, struct osmo_ss7_route_table); + rtbl->inst = inst; + rtbl->cfg.name = talloc_strdup(rtbl, name); + INIT_LLIST_HEAD(&rtbl->routes); + llist_add_tail(&rtbl->list, &inst->rtable_list); + } + return rtbl; +} + +void osmo_ss7_route_table_destroy(struct osmo_ss7_route_table *rtbl) +{ + llist_del(&rtbl->list); + /* routes are allocated as children of route table, will be + * automatically freed() */ + talloc_free(rtbl); +} + +/*********************************************************************** + * SS7 Routes + ***********************************************************************/ + +/*! \brief Find a SS7 route for given destination point code in given table */ +struct osmo_ss7_route * +osmo_ss7_route_find_dpc(struct osmo_ss7_route_table *rtbl, uint32_t dpc) +{ + struct osmo_ss7_route *rt; + + OSMO_ASSERT(ss7_initialized); + /* we assume the routes are sorted by mask length, i.e. more + * specific routes first, and less specific routes with shorter + * mask later */ + llist_for_each_entry(rt, &rtbl->routes, list) { + if ((dpc & rt->cfg.mask) == rt->cfg.pc) + return rt; + } + return NULL; +} + +/*! \brief Find a SS7 route for given destination point code + mask in given table */ +struct osmo_ss7_route * +osmo_ss7_route_find_dpc_mask(struct osmo_ss7_route_table *rtbl, uint32_t dpc, + uint32_t mask) +{ + struct osmo_ss7_route *rt; + + OSMO_ASSERT(ss7_initialized); + /* we assume the routes are sorted by mask length, i.e. more + * specific routes first, and less specific routes with shorter + * mask later */ + llist_for_each_entry(rt, &rtbl->routes, list) { + if (dpc == rt->cfg.pc && mask == rt->cfg.mask) + return rt; + } + return NULL; +} + +/*! \brief Find a SS7 route for given destination point code in given SS7 */ +struct osmo_ss7_route * +osmo_ss7_route_lookup(struct osmo_ss7_instance *inst, uint32_t dpc) +{ + OSMO_ASSERT(ss7_initialized); + return osmo_ss7_route_find_dpc(inst->rtable_system, dpc); +} + +/* insert the route in the ordered list of routes. The list is sorted by + * mask length, so that the more specific (longer mask) routes are + * first, while the less specific routes with shorter masks are last. + * Hence, the first matching route in a linear iteration is the most + * specific match. */ +static void route_insert_sorted(struct osmo_ss7_route_table *rtbl, + struct osmo_ss7_route *cmp) +{ + struct osmo_ss7_route *rt; + + llist_for_each_entry(rt, &rtbl->routes, list) { + if (rt->cfg.mask < cmp->cfg.mask) { + /* insert before the current entry */ + llist_add(&cmp->list, rt->list.prev); + return; + } + } + /* not added, i.e. no smaller mask length found: we are the + * smallest mask and thus should go last */ + llist_add_tail(&cmp->list, &rtbl->routes); +} + +/*! \brief Create a new route in the given routing table + * \param[in] rtbl Routing Table in which the route is to be created + * \param[in] pc Point Code of the destination of the route + * \param[in] mask Mask of the destination Point Code \ref pc + * \param[in] linkset_name string name of the linkset to be used + * \returns caller-allocated + initialized route, NULL on error + */ +struct osmo_ss7_route * +osmo_ss7_route_create(struct osmo_ss7_route_table *rtbl, uint32_t pc, + uint32_t mask, const char *linkset_name) +{ + struct osmo_ss7_route *rt; + struct osmo_ss7_linkset *lset; + struct osmo_ss7_as *as; + + OSMO_ASSERT(ss7_initialized); + lset = osmo_ss7_linkset_find_by_name(rtbl->inst, linkset_name); + if (!lset) { + as = osmo_ss7_as_find_by_name(rtbl->inst, linkset_name); + if (!as) + return NULL; + } + + rt = talloc_zero(rtbl, struct osmo_ss7_route); + if (!rt) + return NULL; + + rt->cfg.pc = pc; + rt->cfg.mask = mask; + rt->cfg.linkset_name = talloc_strdup(rt, linkset_name); + if (lset) + rt->dest.linkset = lset; + else + rt->dest.as = as; + rt->rtable = rtbl; + + route_insert_sorted(rtbl, rt); + + return rt; +} + +/*! \brief Destroy a given SS7 route */ +void osmo_ss7_route_destroy(struct osmo_ss7_route *rt) +{ + OSMO_ASSERT(ss7_initialized); + llist_del(&rt->list); + talloc_free(rt); +} + +/*********************************************************************** + * SS7 Application Server + ***********************************************************************/ + +/*! \brief Find Application Server by given name + * \param[in] inst SS7 Instance on which we operate + * \param[in] name Name of AS + * \returns pointer to Application Server on success; NULL otherwise */ +struct osmo_ss7_as * +osmo_ss7_as_find_by_name(struct osmo_ss7_instance *inst, const char *name) +{ + struct osmo_ss7_as *as; + + OSMO_ASSERT(ss7_initialized); + llist_for_each_entry(as, &inst->as_list, list) { + if (!strcmp(name, as->cfg.name)) + return as; + } + return NULL; +} + +/*! \brief Find Application Server by given routing context + * \param[in] inst SS7 Instance on which we operate + * \param[in] rctx Routing Context + * \returns pointer to Application Server on success; NULL otherwise */ +struct osmo_ss7_as * +osmo_ss7_as_find_by_rctx(struct osmo_ss7_instance *inst, uint32_t rctx) +{ + struct osmo_ss7_as *as; + + OSMO_ASSERT(ss7_initialized); + llist_for_each_entry(as, &inst->as_list, list) { + if (as->cfg.routing_key.context == rctx) + return as; + } + return NULL; +} + +/*! \brief Find or Create Application Server + * \param[in] inst SS7 Instance on which we operate + * \param[in] name Name of Application Server + * \param[in] proto Protocol of Application Server + * \returns pointer to Application Server on suuccess; NULL otherwise */ +struct osmo_ss7_as * +osmo_ss7_as_find_or_create(struct osmo_ss7_instance *inst, const char *name, + enum osmo_ss7_asp_protocol proto) +{ + struct osmo_ss7_as *as; + + OSMO_ASSERT(ss7_initialized); + as = osmo_ss7_as_find_by_name(inst, name); + + if (as && as->cfg.proto != proto) + return NULL; + + if (!as) { + LOGSS7(inst, LOGL_INFO, "Creating AS %s\n", name); + as = talloc_zero(inst, struct osmo_ss7_as); + if (!as) + return NULL; + as->inst = inst; + as->cfg.name = talloc_strdup(as, name); + as->cfg.proto = proto; + as->cfg.mode = OSMO_SS7_AS_TMOD_LOADSHARE; + as->cfg.recovery_timeout_msec = 2000; + as->fi = xua_as_fsm_start(as, LOGL_DEBUG); + llist_add_tail(&as->list, &inst->as_list); + } + + return as; +} + +/*! \brief Add given ASP to given AS + * \param[in] as Application Server to which \ref asp is added + * \param[in] asp Application Server Process to be added to \ref as + * \returns 0 on success; negative in case of error */ +int osmo_ss7_as_add_asp(struct osmo_ss7_as *as, const char *asp_name) +{ + struct osmo_ss7_asp *asp; + unsigned int i; + + OSMO_ASSERT(ss7_initialized); + asp = osmo_ss7_asp_find_by_name(as->inst, asp_name); + if (!asp) + return -ENODEV; + + LOGSS7(as->inst, LOGL_INFO, "Adding ASP %s to AS %s\n", + asp->cfg.name, as->cfg.name); + + if (osmo_ss7_as_has_asp(as, asp)) + return 0; + + for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) { + if (!as->cfg.asps[i]) { + as->cfg.asps[i] = asp; + return 0; + } + } + + return -ENOSPC; +} + +/*! \brief Delete given ASP from given AS + * \param[in] as Application Server from which \ref asp is deleted + * \param[in] asp Application Server Process to delete from \ref as + * \returns 0 on success; negative in case of error */ +int osmo_ss7_as_del_asp(struct osmo_ss7_as *as, const char *asp_name) +{ + struct osmo_ss7_asp *asp; + unsigned int i; + + OSMO_ASSERT(ss7_initialized); + asp = osmo_ss7_asp_find_by_name(as->inst, asp_name); + if (!asp) + return -ENODEV; + + LOGSS7(as->inst, LOGL_INFO, "Removing ASP %s from AS %s\n", + asp->cfg.name, as->cfg.name); + + for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) { + if (as->cfg.asps[i] == asp) { + as->cfg.asps[i] = NULL; + return 0; + } + } + + return -EINVAL; +} + +/*! \brief Destroy given Application Server + * \param[in] as Application Server to destroy */ +void osmo_ss7_as_destroy(struct osmo_ss7_as *as) +{ + OSMO_ASSERT(ss7_initialized); + LOGSS7(as->inst, LOGL_INFO, "Destroying AS %s\n", as->cfg.name); + + if (as->fi) + osmo_fsm_inst_term(as->fi, OSMO_FSM_TERM_REQUEST, NULL); + + as->inst = NULL; + llist_del(&as->list); + talloc_free(as); +} + +/*! \brief Determine if given AS contains ASP + * \param[in] as Application Server in which to look for \ref asp + * \param[in] asp Application Server Process to look for in \ref as + * \returns true in case \ref asp is part of \ref as; false otherwise */ +bool osmo_ss7_as_has_asp(struct osmo_ss7_as *as, + struct osmo_ss7_asp *asp) +{ + unsigned int i; + + OSMO_ASSERT(ss7_initialized); + for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) { + if (as->cfg.asps[i] == asp) + return true; + } + return false; +} + +/*********************************************************************** + * SS7 Application Server Process + ***********************************************************************/ + +struct osmo_ss7_asp * +osmo_ss7_asp_find_by_name(struct osmo_ss7_instance *inst, const char *name) +{ + struct osmo_ss7_asp *asp; + + OSMO_ASSERT(ss7_initialized); + llist_for_each_entry(asp, &inst->asp_list, list) { + if (!strcmp(name, asp->cfg.name)) + return asp; + } + return NULL; +} + +static uint16_t get_in_port(struct sockaddr *sa) +{ + switch (sa->sa_family) { + case AF_INET: + return (((struct sockaddr_in*)sa)->sin_port); + case AF_INET6: + return (((struct sockaddr_in6*)sa)->sin6_port); + default: + return 0; + } +} + +/*! \brief Find an ASP definition matching the local+remote IP/PORT of given fd + * \param[in] fd socket descriptor of given socket + * \returns SS7 ASP in case a matching one is found; NULL otherwise */ +static struct osmo_ss7_asp * +osmo_ss7_asp_find_by_socket_addr(int fd) +{ + struct osmo_ss7_instance *inst; + struct sockaddr sa_l, sa_r; + socklen_t sa_len_l = sizeof(sa_l); + socklen_t sa_len_r = sizeof(sa_r); + char hostbuf_l[64], hostbuf_r[64]; + uint16_t local_port, remote_port; + int rc; + + OSMO_ASSERT(ss7_initialized); + /* convert local and remote IP to string */ + rc = getsockname(fd, &sa_l, &sa_len_l); + if (rc < 0) + return NULL; + rc = getnameinfo(&sa_l, sa_len_l, hostbuf_l, sizeof(hostbuf_l), + NULL, 0, NI_NUMERICHOST); + if (rc < 0) + return NULL; + local_port = ntohs(get_in_port(&sa_l)); + + rc = getpeername(fd, &sa_r, &sa_len_r); + if (rc < 0) + return NULL; + rc = getnameinfo(&sa_r, sa_len_r, hostbuf_r, sizeof(hostbuf_r), + NULL, 0, NI_NUMERICHOST); + if (rc < 0) + return NULL; + remote_port = ntohs(get_in_port(&sa_r)); + + /* check all instances for any ASP definition matching the + * address combination of local/remote ip/port */ + llist_for_each_entry(inst, &ss7_instances, list) { + struct osmo_ss7_asp *asp; + llist_for_each_entry(asp, &inst->asp_list, list) { + if (asp->cfg.local.port == local_port && + (!asp->cfg.remote.port ||asp->cfg.remote.port == remote_port) && + (!asp->cfg.local.host || !strcmp(asp->cfg.local.host, hostbuf_l)) && + (!asp->cfg.remote.host || !strcmp(asp->cfg.remote.host, hostbuf_r))) + return asp; + } + } + + return NULL; +} + +struct osmo_ss7_asp * +osmo_ss7_asp_find_or_create(struct osmo_ss7_instance *inst, const char *name, + uint16_t remote_port, uint16_t local_port, + enum osmo_ss7_asp_protocol proto) +{ + struct osmo_ss7_asp *asp; + + OSMO_ASSERT(ss7_initialized); + asp = osmo_ss7_asp_find_by_name(inst, name); + + if (asp && (asp->cfg.remote.port != remote_port || + asp->cfg.local.port != local_port || + asp->cfg.proto != proto)) + return NULL; + + if (!asp) { + /* FIXME: check if local port has SCTP? */ + asp = talloc_zero(inst, struct osmo_ss7_asp); + asp->inst = inst; + asp->cfg.remote.port = remote_port; + asp->cfg.local.port = local_port; + asp->cfg.proto = proto; + asp->cfg.name = talloc_strdup(asp, name); + llist_add_tail(&asp->list, &inst->asp_list); + } + return asp; +} + +void osmo_ss7_asp_destroy(struct osmo_ss7_asp *asp) +{ + struct osmo_ss7_as *as; + + OSMO_ASSERT(ss7_initialized); + LOGSS7(asp->inst, LOGL_INFO, "Destroying ASP %s\n", asp->cfg.name); + + if (asp->server) + osmo_stream_srv_destroy(asp->server); + if (asp->client) + osmo_stream_cli_destroy(asp->client); + if (asp->fi) + osmo_fsm_inst_term(asp->fi, OSMO_FSM_TERM_REQUEST, NULL); + + /* unlink from all ASs we are part of */ + llist_for_each_entry(as, &asp->inst->as_list, list) { + unsigned int i; + for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) { + if (as->cfg.asps[i] == asp) { + as->cfg.asps[i] = NULL; + } + } + } + /* unlink from ss7_instance */ + asp->inst = NULL; + llist_del(&asp->list); + /* release memory */ + talloc_free(asp); +} + +static int xua_cli_read_cb(struct osmo_stream_cli *conn); +static int xua_cli_connect_cb(struct osmo_stream_cli *cli); + +int osmo_ss7_asp_restart(struct osmo_ss7_asp *asp) +{ + int rc; + enum xua_asp_role role; + + OSMO_ASSERT(ss7_initialized); + LOGSS7(asp->inst, LOGL_INFO, "Restarting ASP %s\n", asp->cfg.name); + + if (!asp->cfg.is_server) { + /* We are in client mode now */ + if (asp->server) { + /* if we previously were in server mode, + * destroy it */ + osmo_stream_srv_destroy(asp->server); + asp->server = NULL; + } + if (!asp->client) + asp->client = osmo_stream_cli_create(asp); + if (!asp->client) { + LOGSS7(asp->inst, LOGL_ERROR, "Unable to create stream" + " client for ASP %s\n", asp->cfg.name); + return -1; + } + osmo_stream_cli_set_addr(asp->client, asp->cfg.remote.host); + osmo_stream_cli_set_port(asp->client, asp->cfg.remote.port); + osmo_stream_cli_set_proto(asp->client, IPPROTO_SCTP); + osmo_stream_cli_set_reconnect_timeout(asp->client, 5); + osmo_stream_cli_set_connect_cb(asp->client, xua_cli_connect_cb); + osmo_stream_cli_set_read_cb(asp->client, xua_cli_read_cb); + osmo_stream_cli_set_data(asp->client, asp); + rc = osmo_stream_cli_open2(asp->client, 1); + if (rc < 0) { + LOGSS7(asp->inst, LOGL_ERROR, "Unable to open stream" + " client for ASP %s\n", asp->cfg.name); + } + /* TODO: make this configurable and not implicit */ + role = XUA_ASPFSM_ROLE_ASP; + } else { + /* We are in server mode now */ + if (asp->client) { + /* if we previously were in client mode, + * destroy it */ + osmo_stream_cli_destroy(asp->client); + asp->client = NULL; + } + /* FIXME: ensure we have a SCTP server */ + LOGSS7(asp->inst, LOGL_NOTICE, "ASP Restart for server " + "not implemented yet!\n"); + /* TODO: make this configurable and not implicit */ + role = XUA_ASPFSM_ROLE_SG; + } + + /* (re)start the ASP FSM */ + if (asp->fi) + osmo_fsm_inst_term(asp->fi, OSMO_FSM_TERM_REQUEST, NULL); + asp->fi = xua_asp_fsm_start(asp, role, LOGL_DEBUG); + + return 0; +} + +/*********************************************************************** + * libosmo-netif integration for SCTP stream server/client + ***********************************************************************/ + +static const struct value_string sctp_assoc_chg_vals[] = { + { SCTP_COMM_UP, "COMM_UP" }, + { SCTP_COMM_LOST, "COMM_LOST" }, + { SCTP_RESTART, "RESTART" }, + { SCTP_SHUTDOWN_COMP, "SHUTDOWN_COMP" }, + { SCTP_CANT_STR_ASSOC, "CANT_STR_ASSOC" }, + { 0, NULL } +}; + +static const struct value_string sctp_sn_type_vals[] = { + { SCTP_ASSOC_CHANGE, "ASSOC_CHANGE" }, + { SCTP_PEER_ADDR_CHANGE, "PEER_ADDR_CHANGE" }, + { SCTP_SHUTDOWN_EVENT, "SHUTDOWN_EVENT" }, + { SCTP_SEND_FAILED, "SEND_FAILED" }, + { SCTP_REMOTE_ERROR, "REMOTE_ERROR" }, + { SCTP_PARTIAL_DELIVERY_EVENT, "PARTIAL_DELIVERY_EVENT" }, + { SCTP_ADAPTATION_INDICATION, "ADAPTATION_INDICATION" }, +#ifdef SCTP_AUTHENTICATION_INDICATION + { SCTP_AUTHENTICATION_INDICATION, "UTHENTICATION_INDICATION" }, +#endif +#ifdef SCTP_SENDER_DRY_EVENT + { SCTP_SENDER_DRY_EVENT, "SENDER_DRY_EVENT" }, +#endif + { 0, NULL } +}; + +static int get_logevel_by_sn_type(int sn_type) +{ + switch (sn_type) { + case SCTP_ADAPTATION_INDICATION: + case SCTP_PEER_ADDR_CHANGE: +#ifdef SCTP_AUTHENTICATION_INDICATION + case SCTP_AUTHENTICATION_INDICATION: +#endif +#ifdef SCTP_SENDER_DRY_EVENT + case SCTP_SENDER_DRY_EVENT: +#endif + return LOGL_INFO; + case SCTP_ASSOC_CHANGE: + return LOGL_NOTICE; + case SCTP_SHUTDOWN_EVENT: + case SCTP_PARTIAL_DELIVERY_EVENT: + return LOGL_NOTICE; + case SCTP_SEND_FAILED: + case SCTP_REMOTE_ERROR: + return LOGL_ERROR; + default: + return LOGL_NOTICE; + } +} + +static void log_sctp_notification(struct osmo_ss7_asp *asp, const char *pfx, + union sctp_notification *notif) +{ + int log_level; + + LOGPASP(asp, DLSS7, LOGL_INFO, "%s SCTP NOTIFICATION %u flags=0x%0x\n", + pfx, notif->sn_header.sn_type, + notif->sn_header.sn_flags); + + log_level = get_logevel_by_sn_type(notif->sn_header.sn_type); + + switch (notif->sn_header.sn_type) { + case SCTP_ASSOC_CHANGE: + LOGPASP(asp, DLSS7, log_level, "%s SCTP_ASSOC_CHANGE: %s\n", + pfx, get_value_string(sctp_assoc_chg_vals, + notif->sn_assoc_change.sac_state)); + break; + default: + LOGPASP(asp, DLSS7, log_level, "%s %s\n", + pfx, get_value_string(sctp_sn_type_vals, + notif->sn_header.sn_type)); + break; + } +} + +/* netif code tells us we can read something from the socket */ +static int xua_srv_conn_cb(struct osmo_stream_srv *conn) +{ + struct osmo_fd *ofd = osmo_stream_srv_get_ofd(conn); + struct osmo_ss7_asp *asp = osmo_stream_srv_get_data(conn); + struct msgb *msg = msgb_alloc(ASP_MSGB_SIZE, "xUA Server Rx"); + struct sctp_sndrcvinfo sinfo; + unsigned int ppid; + int flags = 0; + int rc; + + if (!msg) + return -ENOMEM; + + /* read xUA message from socket and process it */ + rc = sctp_recvmsg(ofd->fd, msgb_data(msg), msgb_tailroom(msg), + NULL, NULL, &sinfo, &flags); + LOGPASP(asp, DLSS7, LOGL_DEBUG, "%s(): sctp_recvmsg() returned %d\n", + __func__, rc); + if (rc < 0) { + osmo_stream_srv_destroy(conn); + goto out; + } else if (rc == 0) { + osmo_stream_srv_destroy(conn); + goto out; + } else { + msgb_put(msg, rc); + } + + if (flags & MSG_NOTIFICATION) { + union sctp_notification *notif = (union sctp_notification *) msgb_data(msg); + + log_sctp_notification(asp, "xUA SRV", notif); + + switch (notif->sn_header.sn_type) { + case SCTP_SHUTDOWN_EVENT: + osmo_stream_srv_destroy(conn); + osmo_fsm_inst_dispatch(asp->fi, XUA_ASP_E_SCTP_COMM_DOWN_IND, asp); + break; + default: + break; + } + rc = 0; + goto out; + } + + ppid = ntohl(sinfo.sinfo_ppid); + msgb_sctp_ppid(msg) = ppid; + msgb_sctp_stream(msg) = ntohl(sinfo.sinfo_stream); + msg->dst = asp; + + if (ppid == M3UA_PPID && asp->cfg.proto == OSMO_SS7_ASP_PROT_M3UA) + rc = m3ua_rx_msg(asp, msg); + else { + LOGPASP(asp, DLSS7, LOGL_NOTICE, "SCTP chunk for unknown PPID %u " + "received\n", ppid); + rc = 0; + } + +out: + msgb_free(msg); + return rc; +} + +/* client has established SCTP connection to server */ +static int xua_cli_connect_cb(struct osmo_stream_cli *cli) +{ + struct osmo_fd *ofd = osmo_stream_cli_get_ofd(cli); + struct osmo_ss7_asp *asp = osmo_stream_cli_get_data(cli); + + /* update the socket name */ + osmo_talloc_replace_string(asp, &asp->sock_name, osmo_sock_get_name(asp, ofd->fd)); + + LOGPASP(asp, DLSS7, LOGL_INFO, "Client connected %s\n", asp->sock_name); + + /* Notify the ASP FSM that the connection has just been + * established */ + osmo_fsm_inst_dispatch(asp->fi, XUA_ASP_E_M_ASP_UP_REQ, NULL); + + return 0; +} + +static int xua_cli_read_cb(struct osmo_stream_cli *conn) +{ + struct osmo_fd *ofd = osmo_stream_cli_get_ofd(conn); + struct osmo_ss7_asp *asp = osmo_stream_cli_get_data(conn); + struct msgb *msg = msgb_alloc(ASP_MSGB_SIZE, "xUA Client Rx"); + struct sctp_sndrcvinfo sinfo; + unsigned int ppid; + int flags = 0; + int rc; + + if (!msg) + return -ENOMEM; + + /* read xUA message from socket and process it */ + rc = sctp_recvmsg(ofd->fd, msgb_data(msg), msgb_tailroom(msg), + NULL, NULL, &sinfo, &flags); + LOGPASP(asp, DLSS7, LOGL_DEBUG, "%s(): sctp_recvmsg() returned %d (flags=%d)\n", + __func__, rc, flags); + if (rc < 0) { + osmo_stream_cli_reconnect(conn); + goto out; + } else if (rc == 0) { + osmo_stream_cli_reconnect(conn); + } else { + msgb_put(msg, rc); + } + + if (flags & MSG_NOTIFICATION) { + union sctp_notification *notif = (union sctp_notification *) msgb_data(msg); + + log_sctp_notification(asp, "xUA CLNT", notif); + + switch (notif->sn_header.sn_type) { + case SCTP_SHUTDOWN_EVENT: + osmo_fsm_inst_dispatch(asp->fi, XUA_ASP_E_SCTP_COMM_DOWN_IND, asp); + osmo_stream_cli_reconnect(conn); + break; + default: + break; + } + rc = 0; + goto out; + } + + if (rc == 0) + goto out; + + ppid = ntohl(sinfo.sinfo_ppid); + msgb_sctp_ppid(msg) = ppid; + msgb_sctp_stream(msg) = ntohl(sinfo.sinfo_stream); + msg->dst = asp; + + if (ppid == M3UA_PPID && asp->cfg.proto == OSMO_SS7_ASP_PROT_M3UA) + rc = m3ua_rx_msg(asp, msg); + else { + LOGPASP(asp, DLSS7, LOGL_NOTICE, "SCTP chunk for unknown PPID %u " + "received\n", ppid); + rc = 0; + } + +out: + msgb_free(msg); + return rc; +} + +static int xua_srv_conn_closed_cb(struct osmo_stream_srv *srv) +{ + struct osmo_ss7_asp *asp = osmo_stream_srv_get_data(srv); + + LOGP(DLSS7, LOGL_INFO, "%s: SCTP connection closed\n", + asp ? asp->cfg.name : "?"); + + /* FIXME: somehow notify ASP FSM and everyone else */ + + return 0; +} + + +/* server has accept()ed a new SCTP association, let's find the ASP for + * it (if any) */ +static int xua_accept_cb(struct osmo_stream_srv_link *link, int fd) +{ + struct osmo_xua_server *oxs = osmo_stream_srv_link_get_data(link); + struct osmo_stream_srv *srv; + struct osmo_ss7_asp *asp; + char *sock_name = osmo_sock_get_name(link, fd); + + LOGP(DLSS7, LOGL_INFO, "%s: New SCTP connection accepted\n", + sock_name); + + srv = osmo_stream_srv_create(oxs, link, fd, + xua_srv_conn_cb, + xua_srv_conn_closed_cb, NULL); + if (!srv) { + LOGP(DLSS7, LOGL_ERROR, "%s: Unable to create stream server " + "for SCTP connection\n", sock_name); + close(fd); + talloc_free(sock_name); + return -1; + } + + asp = osmo_ss7_asp_find_by_socket_addr(fd); + if (!asp) { + LOGP(DLSS7, LOGL_NOTICE, "%s: SCTP connection without matching " + "ASP definition, terminating\n", sock_name); + osmo_stream_srv_destroy(srv); + talloc_free(sock_name); + return -1; + } + LOGP(DLSS7, LOGL_INFO, "%s: matched connection to ASP %s\n", + sock_name, asp->cfg.name); + /* update the ASP reference back to the server over which the + * connection came in */ + asp->server = srv; + /* update the ASP socket name */ + if (asp->sock_name) + talloc_free(asp->sock_name); + asp->sock_name = talloc_reparent(link, asp, sock_name); + /* make sure the conn_cb() is called with the asp as private + * data */ + osmo_stream_srv_set_data(srv, asp); + + return 0; +} + +/*! \brief send a fully encoded msgb via a given ASP + * \param[in] asp Application Server Process through which to send + * \param[in] msg message buffer to transmit. Ownership transferred. + * \returns 0 on success; negative in case of error */ +int osmo_ss7_asp_send(struct osmo_ss7_asp *asp, struct msgb *msg) +{ + OSMO_ASSERT(ss7_initialized); + + switch (asp->cfg.proto) { + case OSMO_SS7_ASP_PROT_SUA: + msgb_sctp_ppid(msg) = SUA_PPID; + break; + case OSMO_SS7_ASP_PROT_M3UA: + msgb_sctp_ppid(msg) = M3UA_PPID; + break; + default: + OSMO_ASSERT(0); + } + + if (asp->cfg.is_server) + osmo_stream_srv_send(asp->server, msg); + else + osmo_stream_cli_send(asp->client, msg); + + return 0; +} + +/*********************************************************************** + * SS7 xUA Server + ***********************************************************************/ + +struct osmo_xua_server * +osmo_ss7_xua_server_find(struct osmo_ss7_instance *inst, enum osmo_ss7_asp_protocol proto, + uint16_t local_port) +{ + struct osmo_xua_server *xs; + + OSMO_ASSERT(ss7_initialized); + llist_for_each_entry(xs, &ss7_xua_servers, list) { + if (proto == xs->cfg.proto && + local_port == xs->cfg.local.port) + return xs; + } + return NULL; +} + +/*! \brief create a new xUA server listening to given ip/port + * \param[in] ctx talloc allocation context + * \param[in] proto protocol (xUA variant) to use + * \param[in] local_port local SCTP port to bind/listen to + * \param[in] local_host local IP address to bind/listen to (optional) + * \returns callee-allocated \ref osmo_xua_server in case of success + */ +struct osmo_xua_server * +osmo_ss7_xua_server_create(struct osmo_ss7_instance *inst, enum osmo_ss7_asp_protocol proto, + uint16_t local_port, const char *local_host) +{ + struct osmo_xua_server *oxs = talloc_zero(inst, struct osmo_xua_server); + int rc; + + OSMO_ASSERT(ss7_initialized); + if (!oxs) + return NULL; + + LOGP(DLSS7, LOGL_INFO, "Creating XUA Server %s:%u\n", + local_host, local_port); + + oxs->cfg.proto = proto; + oxs->cfg.local.port = local_port; + oxs->cfg.local.host = talloc_strdup(oxs, local_host); + + oxs->server = osmo_stream_srv_link_create(oxs); + osmo_stream_srv_link_set_data(oxs->server, oxs); + osmo_stream_srv_link_set_accept_cb(oxs->server, xua_accept_cb); + + osmo_stream_srv_link_set_addr(oxs->server, oxs->cfg.local.host); + osmo_stream_srv_link_set_port(oxs->server, oxs->cfg.local.port); + osmo_stream_srv_link_set_proto(oxs->server, IPPROTO_SCTP); + + rc = osmo_stream_srv_link_open(oxs->server); + if (rc < 0) { + osmo_stream_srv_link_destroy(oxs->server); + oxs->server = NULL; + talloc_free(oxs); + } + + oxs->inst = inst; + llist_add_tail(&oxs->list, &ss7_xua_servers); + + return oxs; +} + +int +osmo_ss7_xua_server_set_local_host(struct osmo_xua_server *xs, const char *local_host) +{ + OSMO_ASSERT(ss7_initialized); + if (xs->cfg.local.host) + talloc_free(xs->cfg.local.host); + xs->cfg.local.host = talloc_strdup(xs, local_host); + + osmo_stream_srv_link_set_addr(xs->server, xs->cfg.local.host); + + return 0; +} + +void osmo_ss7_xua_server_destroy(struct osmo_xua_server *xs) +{ + if (xs->server) { + osmo_stream_srv_link_close(xs->server); + osmo_stream_srv_link_destroy(xs->server); + } + /* FIXME: add asp_list to xua_server so we can iterate it here + * and close all connections established in relation with this + * server */ + llist_del(&xs->list); + talloc_free(xs); +} + +bool osmo_ss7_pc_is_local(struct osmo_ss7_instance *inst, uint32_t pc) +{ + OSMO_ASSERT(ss7_initialized); + if (pc == inst->cfg.primary_pc) + return true; + /* FIXME: Secondary and Capability Point Codes */ + return false; +} + +int osmo_ss7_init(void) +{ + if (ss7_initialized) + return 1; + osmo_fsm_register(&xua_as_fsm); + osmo_fsm_register(&xua_asp_fsm); + ss7_initialized = true; + return 0; +} diff --git a/src/osmo_ss7_hmrt.c b/src/osmo_ss7_hmrt.c new file mode 100644 index 0000000..bc2b8e5 --- /dev/null +++ b/src/osmo_ss7_hmrt.c @@ -0,0 +1,219 @@ +/*********************************************************************** + * MTP Level 3 - Signalling message handling (SMH) Figure 23/Q.704 + ***********************************************************************/ + +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include "xua_internal.h" + +/* convert from M3UA message to MTP-TRANSFER.ind osmo_mtp_prim */ +struct osmo_mtp_prim *m3ua_to_xfer_ind(struct xua_msg *xua) +{ + struct osmo_mtp_prim *prim; + struct osmo_mtp_transfer_param *param; + struct xua_msg_part *data_ie = xua_msg_find_tag(xua, M3UA_IEI_PROT_DATA); + struct m3ua_data_hdr *data_hdr; + struct msgb *upmsg = m3ua_msgb_alloc("M3UA MTP-TRANSFER.ind"); + + if (data_ie->len < sizeof(*data_hdr)) { + /* FIXME: ERROR message */ + msgb_free(upmsg); + return NULL; + } + data_hdr = (struct m3ua_data_hdr *) data_ie->dat; + + /* fill primitive */ + prim = (struct osmo_mtp_prim *) msgb_put(upmsg, sizeof(*prim)); + param = &prim->u.transfer; + osmo_prim_init(&prim->oph, MTP_SAP_USER, + OSMO_MTP_PRIM_TRANSFER, + PRIM_OP_INDICATION, upmsg); + + m3ua_dh_to_xfer_param(param, data_hdr); + /* copy data */ + upmsg->l2h = msgb_put(upmsg, data_ie->len - sizeof(*data_hdr)); + memcpy(upmsg->l2h, data_ie->dat+sizeof(*data_hdr), data_ie->len - sizeof(*data_hdr)); + + return prim; +} + +/* convert from MTP-TRANSFER.req to osmo_mtp_prim */ +static struct xua_msg *mtp_prim_to_m3ua(struct osmo_mtp_prim *prim) +{ + struct msgb *msg = prim->oph.msg; + struct xua_msg *xua = xua_msg_alloc(); + struct osmo_mtp_transfer_param *param = &prim->u.transfer; + struct xua_msg_part *data_part; + struct m3ua_data_hdr data_hdr; + + mtp_xfer_param_to_m3ua_dh(&data_hdr, param); + + xua->hdr = XUA_HDR(M3UA_MSGC_XFER, M3UA_XFER_DATA); + /* Network Appearance: Optional */ + /* Routing Context: Conditional */ + /* Protocol Data: Mandatory */ + data_part = talloc_zero(xua, struct xua_msg_part); + data_part->tag = M3UA_IEI_PROT_DATA; + data_part->len = sizeof(data_hdr) + msgb_l2len(msg); + data_part->dat = talloc_size(data_part, data_part->len); + memcpy(data_part->dat, &data_hdr, sizeof(data_hdr)); + memcpy(data_part->dat+sizeof(data_hdr), msgb_l2(msg), msgb_l2len(msg)); + llist_add_tail(&data_part->entry, &xua->headers); + /* Correlation Id: Optional */ + + return xua; +} + +/* delivery given XUA message to given SS7 user */ +static int deliver_to_mtp_user(const struct osmo_ss7_user *osu, + struct xua_msg *xua) +{ + struct osmo_mtp_prim *prim; + + /* Create MTP-TRANSFER.ind and feed to user */ + prim = m3ua_to_xfer_ind(xua); + prim->u.transfer = xua->mtp; + if (!prim) + return -1; + + return osu->prim_cb(&prim->oph, (void *) osu->priv); +} + +/* HMDC -> HMDT: Message for distribution; Figure 25/Q.704 */ +/* This means it is a message we received from remote/L2, and it is to + * be routed to a local user part */ +static int hmdt_message_for_distribution(struct osmo_ss7_instance *inst, struct xua_msg *xua) +{ + struct m3ua_data_hdr *mdh; + const struct osmo_ss7_user *osu; + uint32_t service_ind; + + switch (xua->hdr.msg_class) { + case M3UA_MSGC_XFER: + switch (xua->hdr.msg_type) { + case M3UA_XFER_DATA: + mdh = data_hdr_from_m3ua(xua); + service_ind = mdh->si & 0xf; + break; + default: + LOGP(DLSS7, LOGL_ERROR, "Unknown M3UA XFER Message " + "Type %u\n", xua->hdr.msg_type); + return -1; + } + break; + case M3UA_MSGC_SNM: + /* FIXME */ + /* FIXME: SI = Signalling Network Management -> SRM/SLM/STM */ + /* FIXME: SI = Signalling Network Testing and Maintenance -> SLTC */ + default: + /* Discard Message */ + LOGP(DLSS7, LOGL_ERROR, "Unknown M3UA Message Class %u\n", + xua->hdr.msg_class); + return -1; + } + + /* Check for local SSN registered for this DPC/SSN */ + osu = inst->user[service_ind]; + if (osu) { + return deliver_to_mtp_user(osu, xua); + } else { + LOGP(DLSS7, LOGL_NOTICE, "No MTP-User for SI %u\n", service_ind); + /* Discard Message */ + /* FIXME: User Part Unavailable HMDT -> HMRT */ + return -1; + } +} + +/* HMDC->HMRT Msg For Routing; Figure 26/Q.704 */ +/* local message was receive d from L4, SRM, SLM, STM or SLTC, or + * remote message received from L2 and HMDC determined msg for routing */ +static int hmrt_message_for_routing(struct osmo_ss7_instance *inst, + struct xua_msg *xua) +{ + uint32_t dpc = xua->mtp.dpc; + struct osmo_ss7_route *rt; + + /* find route for DPC */ + /* FIXME: unify with gen_mtp_transfer_req_xua() */ + rt = osmo_ss7_route_lookup(inst, dpc); + if (rt) { + /* FIXME: DPC SP restart? */ + /* FIXME: DPC Congested? */ + /* FIXME: Select link based on SLS */ + /* FIXME: Transmit over respective Link */ + if (rt->dest.as) { + struct osmo_ss7_as *as = rt->dest.as; + switch (as->cfg.proto) { + case OSMO_SS7_ASP_PROT_M3UA: + return m3ua_tx_xua_as(as,xua); + default: + LOGP(DLSS7, LOGL_ERROR, "MTP message " + "for ASP of unknown protocol%u\n", + as->cfg.proto); + break; + } + } else if (rt->dest.linkset) { + LOGP(DLSS7, LOGL_ERROR, "MTP-TRANSFER.req for linkset" + "%s unsupported\n",rt->dest.linkset->cfg.name); + } else + OSMO_ASSERT(0); + } else { + LOGP(DLSS7, LOGL_ERROR, "MTP-TRANSFER.req for DPC %u: " + "no route!\n", dpc); + /* DPC unknown HMRT -> MGMT */ + /* Message Received for inaccesible SP HMRT ->RTPC */ + /* Discard Message */ + } + return -1; +} + +/* HMDC: Received Message L2 -> L3; Figure 24/Q.704 */ +/* This means a message was received from L2 and we have to decide if it + * is for the local stack (HMDT) or for routng (HMRT) */ +int m3ua_hmdc_rx_from_l2(struct osmo_ss7_instance *inst, struct xua_msg *xua) +{ + uint32_t dpc = xua->mtp.dpc; + if (osmo_ss7_pc_is_local(inst, dpc)) { + return hmdt_message_for_distribution(inst, xua); + } else { + return hmrt_message_for_routing(inst, xua); + } +} + +/* MTP-User requests to send a MTP-TRANSFER.req via the stack */ +int osmo_ss7_user_mtp_xfer_req(struct osmo_ss7_instance *inst, + struct osmo_mtp_prim *omp) +{ + struct xua_msg *xua; + + OSMO_ASSERT(omp->oph.sap == MTP_SAP_USER); + + switch (OSMO_PRIM_HDR(&omp->oph)) { + case OSMO_PRIM(OSMO_MTP_PRIM_TRANSFER, PRIM_OP_REQUEST): + xua = mtp_prim_to_m3ua(omp); + xua->mtp = omp->u.transfer; + /* normally we would call hmrt_message_for_routing() + * here, if we were to follow the state diagrams of the + * ITU-T Q.70x specifications. However, what if a local + * MTP user sends a MTP-TRANSFER.req to a local SSN? + * This wouldn't work as per the spec, but I believe it + * is a very useful feature (aka "loopback device" in + * IPv4). So we call m3ua_hmdc_rx_from_l2() just like + * the MTP-TRANSFER had been received from L2. */ + return m3ua_hmdc_rx_from_l2(inst, xua); + default: + LOGP(DLSS7, LOGL_ERROR, "Ignoring unknown primitive %u:%u\n", + omp->oph.primitive, omp->oph.operation); + return -1; + } +} diff --git a/src/osmo_ss7_vty.c b/src/osmo_ss7_vty.c new file mode 100644 index 0000000..80cd4d0 --- /dev/null +++ b/src/osmo_ss7_vty.c @@ -0,0 +1,681 @@ +/* Core SS7 Instance/Linkset/Link/AS/ASP VTY Interface */ + +/* (C) 2015-2017 by Harald Welte + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include + +#define CS7_STR "ITU-T Signaling System 7\n" +#define PC_STR "Point Code\n" + +/*********************************************************************** + * Core CS7 Configuration + ***********************************************************************/ + +static const struct value_string ss7_network_indicator_vals[] = { + { 0, "international" }, + { 1, "spare" }, + { 2, "national" }, + { 3, "reserved" }, + { 0, NULL } +}; + +/* cs7 network-indicator */ +DEFUN(cs7_net_ind, cs7_net_ind_cmd, + "cs7 network-indicator (international | national | reserved | spare)", + CS7_STR "Configure the Network Indicator\n" + "International Network\n" + "National Network\n" + "Reserved Network\n" + "Spare Network\n") +{ + struct osmo_ss7_instance *inst = FIXME; + int ni = get_string_value(ss7_network_indicator_vals, argv[0]); + + inst->cfg.network_indicator = ni; + return CMD_SUCCESS; +} + +/* TODO: cs7 point-code format */ +DEFUN(cs7_pc_format, cs7_pc_format_cmd, + "cs7 point-code format <1-24> [<1-23> [<1-22>]]", + CS7_STR PC_STR "Configure Point Code Format\n" + "Length of first PC component\n" + "Length of second PC component\n" + "Length of third PC component\n") +{ + struct osmo_ss7_instance *inst = FIXME; + int argind = 0; + + inst->cfg.pc_fmt.component_len[0] = atoi(argv[argind++]); + + if (argc >= 2) + inst->cfg.pc_fmt.component_len[1] = atoi(argv[argind++]); + else + inst->cfg.pc_fmt.component_len[1] = 0; + + if (argc >= 3) + inst->cfg.pc_fmt.component_len[2] = atoi(argv[argind++]); + else + inst->cfg.pc_fmt.component_len[2] = 0; + + return CMD_SUCCESS; +} + +DEFUN(cs7_pc_format_def, cs7_pc_format_def_cmd, + "cs7 point-code format default", + CS7_STR PC_STR "Configure Point Code Format\n" + "Default Point Code Format (3.8.3)\n") +{ + struct osmo_ss7_instance *inst = FIXME; + inst->cfg.pc_fmt.component_len[0] = 3; + inst->cfg.pc_fmt.component_len[1] = 8; + inst->cfg.pc_fmt.component_len[2] = 3; + return CMD_SUCCESS; +} + + +/* cs7 point-code delimiter */ +DEFUN(cs7_pc_delimiter, cs7_pc_delimiter_cmd, + "cs7 point-code delimiter (default|dash)", + CS7_STR PC_STR "Configure Point Code Delimiter\n" + "Use dot as delimiter\n" + "User dash as delimiter\n") +{ + struct osmo_ss7_instance *inst = FIXME; + + if (!strcmp(argv[0], "dash")) + inst->cfg.pc_fmt.delimiter = '-'; + else + inst->cfg.pc_fmt.delimiter = '.'; + + return CMD_SUCCESS; +} + +DEFUN(cs7_point_code, cs7_point_code_cmd, + "cs7 point-code POINT_CODE", + CS7_STR "Configure the local Point Code\n" + "Point Code\n") +{ + struct osmo_ss7_instance *inst = FIXME; + uint32_t pc = osmo_ss7_pointcode_parse(inst, argv[0]); + + inst->cfg.primary_pc = pc; + return CMD_SUCCESS; +} +/* TODO: cs7 secondary-pc */ +/* TODO: cs7 capability-pc */ + + +/*********************************************************************** + * Routing Table Configuration + ***********************************************************************/ + +static struct cmd_node rtable_node = { + L_CS7_RTABLE_NODE, + "%s(config-cs7-rt)# ", + 1, +}; + +DEFUN(cs7_route_table, cs7_route_table_cmd, + "cs7 route-table system", + CS7_STR "Specify the name of the route table\n" + "Name of the route table\n") +{ + struct osmo_ss7_instance *inst = FIXME; + struct osmo_ss7_route_table *rtable; + + rtable = inst->rtable_system; + vty->node = L_CS7_RTABLE_NODE; + vty->index = rtable; + vty->index_sub = &rtable->cfg.description; + + return CMD_SUCCESS; +} + +DEFUN(cs7_rt_upd, cs7_rt_upd_cmd, + "update route POINT_CODE [MASK | LENGTH] linkset LS_NAME [priority PRIO] [qos-class (CLASS | default", + "Update the Route\n" + "Update the Route\n" + "Destination Point Code\n" + "Point Code Mask\n" + "Point Code Length\n" + "Specify Destination Linkset\n" + "Linkset Name\n" + "Specity Priority\n" + "Priority\n" + "Specify QoS Class\n" + "QoS Class\n" + "Default QoS Class\n") +{ + struct osmo_ss7_route_table *rtable = vty->index; + struct osmo_ss7_route *rt; + uint32_t dpc = osmo_ss7_pointcode_parse(rtable->inst, argv[0]); + uint32_t mask = osmo_ss7_pointcode_parse_mask_or_len(rtable->inst, argv[1]); + const char *ls_name = argv[2]; + unsigned int argind; + + rt = osmo_ss7_route_create(rtable, dpc, mask, ls_name); + if (!rt) + return CMD_WARNING; + + argind = 3; + if (argc > argind && !strcmp(argv[argind], "priority")) { + argind++; + rt->cfg.priority = atoi(argv[argind++]); + } + + if (argc > argind && !strcmp(argv[argind], "qos-class")) { + argind++; + rt->cfg.qos_class = atoi(argv[argind++]); + } + + return CMD_SUCCESS; +} + +DEFUN(cs7_rt_rem, cs7_rt_rem_cmd, + "remove route POINT_CODE [MASK | LENGTH]", + "Remove a Route\n" + "Remove a Route\n" + "Destination Point Code\n" + "Point Code Mask\n" + "Point Code Length\n") +{ + struct osmo_ss7_route_table *rtable = vty->index; + struct osmo_ss7_route *rt; + uint32_t dpc = osmo_ss7_pointcode_parse(rtable->inst, argv[0]); + uint32_t mask = osmo_ss7_pointcode_parse_mask_or_len(rtable->inst, argv[1]); + + rt = osmo_ss7_route_find_dpc_mask(rtable, dpc, mask); + if (!rt) + return CMD_WARNING; + + osmo_ss7_route_destroy(rt); + return CMD_SUCCESS; +} + +static int config_write_rtable(struct vty *vty) +{ + struct osmo_ss7_route_table *rtable = vty->index; + struct osmo_ss7_route *rt; + + vty_out(vty, "cs7 route-table %s%s", rtable->cfg.name, VTY_NEWLINE); + llist_for_each_entry(rt, &rtable->routes, list) { + vty_out(vty, " update route %s %s linkset %s", + osmo_ss7_pointcode_print(rtable->inst, rt->cfg.pc), + osmo_ss7_pointcode_print(rtable->inst, rt->cfg.mask), + rt->cfg.linkset_name); + if (rt->cfg.priority) + vty_out(vty, " priority %u", rt->cfg.priority); + if (rt->cfg.qos_class) + vty_out(vty, " qos-class %u", rt->cfg.qos_class); + vty_out(vty, "%s", VTY_NEWLINE); + } + return 0; +} + +/*********************************************************************** + * SUA Configuration + ***********************************************************************/ + +static struct cmd_node sua_node = { + L_CS7_SUA_NODE, + "%s(config-cs7-sua)# ", + 1, +}; + +DEFUN(cs7_sua, cs7_sua_cmd, + "cs7 sua <0-65534>", + CS7_STR + "Configure/Enable SUA\n" + "SCTP Port number for SUA\n") +{ + struct osmo_ss7_instance *inst = FIXME; + struct osmo_xua_server *xs; + uint16_t port = atoi(argv[0]); + + xs = osmo_ss7_xua_server_find(inst, OSMO_SS7_ASP_PROT_SUA, port); + if (!xs) { + xs = osmo_ss7_xua_server_create(inst, OSMO_SS7_ASP_PROT_SUA, port, NULL); + if (!xs) + return CMD_SUCCESS; + } + + vty->node = L_CS7_SUA_NODE; + vty->index = xs; + return CMD_SUCCESS; +} + +DEFUN(sua_local_ip, sua_local_ip_cmd, + "local-ip A.B.C.D", + "Configure the Local IP Address for SUA\n" + "IP Address to use for SUA\n") +{ + struct osmo_xua_server *xs = vty->index; + + osmo_ss7_xua_server_set_local_host(xs, argv[0]); + return CMD_SUCCESS; +} + +enum osmo_ss7_asp_protocol parse_asp_proto(const char *protocol) +{ + return get_string_value(osmo_ss7_asp_protocol_vals, protocol); +} + +static int config_write_sua(struct vty *vty) +{ + struct osmo_xua_server *xs = vty->index; + + vty_out(vty, "cs7 sua %u%s", xs->cfg.local.port, VTY_NEWLINE); + vty_out(vty, " local-ip %s%s", xs->cfg.local.host, VTY_NEWLINE); + return 0; +} + +/*********************************************************************** + * M3UA Configuration + ***********************************************************************/ + +static struct cmd_node m3ua_node = { + L_CS7_M3UA_NODE, + "%s(config-cs7-m3ua)# ", + 1, +}; + +DEFUN(cs7_m3ua, cs7_m3ua_cmd, + "cs7 m3ua <0-65534>", + CS7_STR + "Configure/Enable M3UA\n" + "SCTP Port number for M3UA\n") +{ + struct osmo_ss7_instance *inst = FIXME; + struct osmo_xua_server *xs; + uint16_t port = atoi(argv[0]); + + xs = osmo_ss7_xua_server_find(inst, OSMO_SS7_ASP_PROT_M3UA, port); + if (!xs) { + xs = osmo_ss7_xua_server_create(inst, OSMO_SS7_ASP_PROT_M3UA, port, NULL); + if (!xs) + return CMD_SUCCESS; + } + + vty->node = L_CS7_M3UA_NODE; + vty->index = xs; + return CMD_SUCCESS; +} + +DEFUN(m3ua_local_ip, m3ua_local_ip_cmd, + "local-ip A.B.C.D", + "Configure the Local IP Address for M3UA\n" + "IP Address to use for M3UA\n") +{ + struct osmo_xua_server *xs = vty->index; + + osmo_ss7_xua_server_set_local_host(xs, argv[0]); + return CMD_SUCCESS; +} + +static int config_write_m3ua(struct vty *vty) +{ + struct osmo_xua_server *xs = vty->index; + + vty_out(vty, "cs7 m3ua %u%s", xs->cfg.local.port, VTY_NEWLINE); + vty_out(vty, " local-ip %s%s", xs->cfg.local.host, VTY_NEWLINE); + return 0; +} + +/*********************************************************************** + * Application Server Process + ***********************************************************************/ + +static struct cmd_node asp_node = { + L_CS7_ASP_NODE, + "%s(config-cs7-asp)# ", + 1, +}; + +DEFUN(cs7_asp, cs7_asp_cmd, + "cs7 asp NAME <0-65535> <0-65535> [m3ua | sua]", + CS7_STR + "Configure Application Server Process\n" + "Name of ASP\n" + "Remote SCTP port number\n" + "Local SCTP port number\n" + "M3UA Protocol\n" + "SUA Protocol\n") +{ + struct osmo_ss7_instance *inst = FIXME; + const char *name = argv[0]; + uint16_t remote_port = atoi(argv[1]); + uint16_t local_port = atoi(argv[2]); + enum osmo_ss7_asp_protocol protocol = parse_asp_proto(argv[3]); + struct osmo_ss7_asp *asp; + + if (protocol == OSMO_SS7_ASP_PROT_NONE) + return CMD_WARNING; + + asp = osmo_ss7_asp_find_or_create(inst, name, remote_port, local_port, protocol); + if (!asp) + return CMD_WARNING; + + vty->node = L_CS7_ASP_NODE; + vty->index = asp; + vty->index_sub = &asp->cfg.description; + return CMD_SUCCESS; +} + +DEFUN(asp_remote_ip, asp_remote_ip_cmd, + "remote-ip A.B.C.D", + "Specity Remote IP Address of ASP\n" + "Remote IP Address of ASP\n") +{ + struct osmo_ss7_asp *asp = vty->index; + osmo_talloc_replace_string(asp, &asp->cfg.remote.host, argv[0]); + return CMD_SUCCESS; +} + +DEFUN(asp_qos_clas, asp_qos_class_cmd, + "qos-class <0-255>", + "Specity QoS Class of ASP\n" + "QoS Class of ASP\n") +{ + struct osmo_ss7_asp *asp = vty->index; + asp->cfg.qos_class = atoi(argv[0]); + return CMD_SUCCESS; +} + +DEFUN(asp_block, asp_block_cmd, + "block", + "Allows a SCTP Association with ASP, but doesn't let it become active\n") +{ + struct osmo_ss7_asp *asp = vty->index; + vty_out(vty, "Not supported yet\n"); + return CMD_WARNING; +} + +DEFUN(asp_shutdown, asp_shutdown_cmd, + "shutdown", + "Terminates SCTP association; New associations will be rejected\n") +{ + struct osmo_ss7_asp *asp = vty->index; + vty_out(vty, "Not supported yet\n"); + return CMD_WARNING; +} + +static int config_write_asp(struct vty *vty) +{ + struct osmo_ss7_asp *asp = vty->index; + + vty_out(vty, "cs7 asp %s %u %u %s%s", + asp->cfg.name, asp->cfg.remote.port, asp->cfg.local.port, + osmo_ss7_asp_protocol_name(asp->cfg.proto), VTY_NEWLINE); + vty_out(vty, " remote-ip %s%s", asp->cfg.remote.host, VTY_NEWLINE); + if (asp->cfg.qos_class) + vty_out(vty, " qos-class %u%s", asp->cfg.qos_class, VTY_NEWLINE); + return 0; +} + +/*********************************************************************** + * Application Server + ***********************************************************************/ + +static struct cmd_node as_node = { + L_CS7_AS_NODE, + "%s(config-cs7-as)# ", + 1, +}; + +DEFUN(cs7_as, cs7_as_cmd, + "cs7 as NAME [m3ua | sua]", + CS7_STR + "Configure an Application Server\n" + "Name of the Application Server\n" + "M3UA Application Server\n" + "SUA Application Server\n") +{ + struct osmo_ss7_as *as; + const char *name = argv[0]; + enum osmo_ss7_asp_protocol protocol = parse_asp_proto(argv[1]); + + if (protocol == OSMO_SS7_ASP_PROT_NONE) + return CMD_WARNING; + + /* FIXME */ + as->cfg.name = talloc_strdup(as, name); + + vty->node = L_CS7_AS_NODE; + vty->index = as; + vty->index_sub = &as->cfg.description; + + return CMD_SUCCESS; +} + +/* TODO: routing-key */ +DEFUN(as_asp, as_asp_cmd, + "asp NAME", + "Specify that a given ASP is part of this AS\n" + "Name of ASP to be added to AS\n") +{ + struct osmo_ss7_as *as = vty->index; + + if (osmo_ss7_as_add_asp(as, argv[0])) + return CMD_WARNING; + + return CMD_SUCCESS; +} + +DEFUN(as_no_asp, as_no_asp_cmd, + "no asp NAME", + NO_STR "Specify ASP to be removed from this AS\n" + "Name of ASP to be removed\n") +{ + struct osmo_ss7_as *as = vty->index; + + if (osmo_ss7_as_del_asp(as, argv[0])) + return CMD_WARNING; + + return CMD_SUCCESS; +} + +DEFUN(as_traf_mode, as_traf_mode_cmd, + "traffic-mode (broadcast | loadshare | roundrobin | override)", + "Specifies traffic mode of operation of the ASP within the AS\n" + "Broadcast to all ASP within AS\n" + "Share Load among all ASP within AS\n" + "Round-Robin between all ASP within AS\n" + "Override\n") +{ + struct osmo_ss7_as *as = vty->index; + + as->cfg.mode = get_string_value(osmo_ss7_as_traffic_mode_vals, argv[0]); + return CMD_WARNING; +} + +DEFUN(as_recov_tout, as_recov_tout_cmd, + "recovery-timeout <1-2000>", + "Specifies the recovery timeout value in milliseconds\n" + "Recovery Timeout in Milliseconds\n") +{ + struct osmo_ss7_as *as = vty->index; + as->cfg.recovery_timeout_msec = atoi(argv[0]); + return CMD_SUCCESS; +} + +DEFUN(as_qos_clas, as_qos_class_cmd, + "qos-class <0-255>", + "Specity QoS Class of AS\n" + "QoS Class of AS\n") +{ + struct osmo_ss7_as *as = vty->index; + as->cfg.qos_class = atoi(argv[0]); + return CMD_SUCCESS; +} + +const struct value_string mtp_si_vals[] = { + { MTP_SI_SCCP, "sccp" }, + { MTP_SI_TUP, "tup" }, + { MTP_SI_ISUP, "isup" }, + { MTP_SI_DUP, "dup" }, + { MTP_SI_TESTING, "testing" }, + { MTP_SI_B_ISUP, "b-isup" }, + { MTP_SI_SAT_ISUP, "sat-isup" }, + { MTP_SI_AAL2_SIG, "aal2" }, + { MTP_SI_BICC, "bicc" }, + { MTP_SI_GCP, "h248" }, + { 0, NULL } +}; + +DEFUN(as_rout_key, as_rout_key_cmd, + "routing-key RCONTEXT DPC [si {aal2 | bicc | b-isup | h248 | isup | sat-isup | sccp | tup }] [ssn SSN]}", + "Define a routing key\n" + "Routing context number\n" + "Destination Point Code\n" + "Optional Match on Service Indicator\n" + "ATM Adaption Layer 2\n" + "Bearer Independent Call Control\n" + "Broadband ISDN User Part\n" + "H.248\n" + "ISDN User Part\n" + "Sattelite ISDN User Part\n" + "Signalling Connection Control Part\n" + "Telephony User Part\n" + "Optional Match on Sub-System Number\n" + "Sub-System Number to match on\n") +{ + struct osmo_ss7_as *as = vty->index; + uint32_t key = atoi(argv[0]); + struct osmo_ss7_routing_key *rkey; + int argind; + + rkey = osmo_ss7_rkey_find_or_create(as, key); + if (!rkey) + return CMD_WARNING; + + rkey->pc = osmo_ss7_pointcode_parse(as->inst, argv[1]); + argind = 2; + + if (!strcmp(argv[argind], "si")) { + const char *si_str; + argind++; + si_str = argv[argind++]; + /* parse numeric SI from string */ + rkey->si = get_string_value(mtp_si_vals, si_str); + } + if (!strcmp(argv[argind], "ssn")) { + argind++; + rkey->ssn = atoi(argv[argind]); + } + + return CMD_SUCCESS; +} + +static int config_write_as(struct vty *vty) +{ + struct osmo_ss7_as *as = vty->index; + struct osmo_ss7_routing_key *rkey; + unsigned int i; + + vty_out(vty, "cs7 as %s %s%s", as->cfg.name, + osmo_ss7_asp_protocol_name(as->cfg.proto), VTY_NEWLINE); + for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) { + struct osmo_ss7_asp *asp = as->cfg.asps[i]; + if (!asp) + continue; + vty_out(vty, " asp %s%s", asp->cfg.name, VTY_NEWLINE); + } + if (as->cfg.mode != OSMO_SS7_AS_TMOD_LOADSHARE) + vty_out(vty, " traffic-mode %s%s", + osmo_ss7_as_traffic_mode_name(as->cfg.mode), VTY_NEWLINE); + if (as->cfg.recovery_timeout_msec != 2000) { + vty_out(vty, " recovery-timeout %u%s", + as->cfg.recovery_timeout_msec, VTY_NEWLINE); + } + vty_out(vty, " qos-class %u%s", as->cfg.qos_class, VTY_NEWLINE); + rkey = &as->cfg.routing_key; + vty_out(vty, " routing-key %u %s", rkey->context, + osmo_ss7_pointcode_print(as->inst, rkey->pc)); + if (rkey->si) + vty_out(vty, " si %s", + get_value_string(mtp_si_vals, rkey->si)); + if (rkey->ssn) + vty_out(vty, " ssn %u", rkey->ssn); + vty_out(vty, "%s", VTY_NEWLINE); + + return 0; +} + +int osmo_ss7_vty_init(void) +{ + install_element(CONFIG_NODE, &cs7_net_ind_cmd); + install_element(CONFIG_NODE, &cs7_point_code_cmd); + install_element(CONFIG_NODE, &cs7_pc_format_cmd); + install_element(CONFIG_NODE, &cs7_pc_format_def_cmd); + install_element(CONFIG_NODE, &cs7_pc_delimiter_cmd); + + install_node(&rtable_node, config_write_rtable); + vty_install_default(L_CS7_RTABLE_NODE); + install_element(CONFIG_NODE, &cs7_route_table_cmd); + install_element(L_CS7_RTABLE_NODE, &cfg_description_cmd); + install_element(L_CS7_RTABLE_NODE, &cs7_rt_upd_cmd); + install_element(L_CS7_RTABLE_NODE, &cs7_rt_rem_cmd); + + install_node(&sua_node, config_write_sua); + vty_install_default(L_CS7_SUA_NODE); + install_element(CONFIG_NODE, &cs7_sua_cmd); + install_element(L_CS7_SUA_NODE, &sua_local_ip_cmd); + + install_node(&m3ua_node, config_write_m3ua); + vty_install_default(L_CS7_M3UA_NODE); + install_element(CONFIG_NODE, &cs7_m3ua_cmd); + install_element(L_CS7_M3UA_NODE, &m3ua_local_ip_cmd); + + install_node(&asp_node, config_write_asp); + vty_install_default(L_CS7_ASP_NODE); + install_element(CONFIG_NODE, &cs7_asp_cmd); + install_element(L_CS7_ASP_NODE, &cfg_description_cmd); + install_element(L_CS7_ASP_NODE, &asp_remote_ip_cmd); + install_element(L_CS7_ASP_NODE, &asp_qos_class_cmd); + install_element(L_CS7_ASP_NODE, &asp_block_cmd); + install_element(L_CS7_ASP_NODE, &asp_shutdown_cmd); + + install_node(&as_node, config_write_as); + vty_install_default(L_CS7_AS_NODE); + install_element(CONFIG_NODE, &cs7_as_cmd); + install_element(L_CS7_AS_NODE, &cfg_description_cmd); + install_element(L_CS7_AS_NODE, &as_asp_cmd); + install_element(L_CS7_AS_NODE, &as_no_asp_cmd); + install_element(L_CS7_AS_NODE, &as_traf_mode_cmd); + install_element(L_CS7_AS_NODE, &as_recov_tout_cmd); + install_element(L_CS7_AS_NODE, &as_qos_class_cmd); + install_element(L_CS7_AS_NODE, &as_rout_key_cmd); + + return 0; +} diff --git a/src/xua_as_fsm.c b/src/xua_as_fsm.c new file mode 100644 index 0000000..887a9ec --- /dev/null +++ b/src/xua_as_fsm.c @@ -0,0 +1,308 @@ +/* SCCP M3UA / SUA AS osmo_fsm according to RFC3868 4.3.1 / RFC4666 4.3.2 */ +/* (C) Copyright 2017 by Harald Welte + * + * All Rights reserved. + * + * Based on Erlang implementation xua_as_fsm.erl in osmo-ss7.git + */ + +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "xua_asp_fsm.h" +#include "xua_as_fsm.h" +#include "xua_internal.h" + +static struct msgb *encode_notify(const struct m3ua_notify_params *npar) +{ + struct xua_msg *xua = m3ua_encode_notify(npar); + struct msgb *msg = xua_to_msg(M3UA_VERSION, xua); + xua_msg_free(xua); + return msg; +} + +static int asp_notify_all_as(struct osmo_ss7_as *as, struct m3ua_notify_params *npar) +{ + struct msgb *msg; + unsigned int i, sent = 0; + + /* iterate over all non-DOWN ASPs and send them the message */ + for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) { + struct osmo_ss7_asp *asp = as->cfg.asps[i]; + + if (!asp) + continue; + + if (!asp->fi || asp->fi->state == XUA_ASP_S_DOWN) + continue; + + /* Optional: ASP Identifier (if sent in ASP-UP) */ + if (asp->asp_id_present) { + npar->presence |= NOTIFY_PAR_P_ASP_ID; + npar->asp_id = asp->asp_id; + } else + npar->presence &= ~NOTIFY_PAR_P_ASP_ID; + + /* TODO: Optional Routing Context */ + + msg = encode_notify(npar); + osmo_ss7_asp_send(asp, msg); + sent++; + } + + return sent; +} + + +/*********************************************************************** + * Actual FSM + ***********************************************************************/ + +#define S(x) (1 << (x)) + +enum xua_as_state { + XUA_AS_S_DOWN, + XUA_AS_S_INACTIVE, + XUA_AS_S_ACTIVE, + XUA_AS_S_PENDING, +}; + +static const struct value_string xua_as_event_names[] = { + { XUA_ASPAS_ASP_INACTIVE_IND, "ASPAS-ASP_INACTIVE.ind" }, + { XUA_ASPAS_ASP_DOWN_IND, "ASPAS-ASP_DOWN.ind" }, + { XUA_ASPAS_ASP_ACTIVE_IND, "ASPAS-ASP_ACTIVE.ind" }, + { 0, NULL } +}; + +struct xua_as_fsm_priv { + struct osmo_ss7_as *as; +}; + +/* is any other ASP in this AS in state != DOWN? */ +static bool check_any_other_asp_not_down(struct osmo_ss7_as *as, struct osmo_ss7_asp *asp_cmp) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) { + struct osmo_ss7_asp *asp = as->cfg.asps[i]; + if (!asp) + continue; + + if (asp_cmp == asp) + continue; + + if (asp->fi && asp->fi->state != XUA_ASP_S_DOWN) + return true; + } + + return false; +} + +/* is any other ASP in this AS in state ACTIVE? */ +static bool check_any_other_asp_in_active(struct osmo_ss7_as *as, struct osmo_ss7_asp *asp_cmp) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) { + struct osmo_ss7_asp *asp = as->cfg.asps[i]; + if (!asp) + continue; + + if (asp_cmp == asp) + continue; + + if (asp->fi && asp->fi->state == XUA_ASP_S_ACTIVE) + return true; + } + + return false; +} + + +static void xua_as_fsm_down(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + switch (event) { + case XUA_ASPAS_ASP_INACTIVE_IND: + /* one ASP transitions into ASP-INACTIVE */ + osmo_fsm_inst_state_chg(fi, XUA_AS_S_INACTIVE, 0, 0); + break; + case XUA_ASPAS_ASP_DOWN_IND: + /* ignore */ + break; + } +} + +/* onenter call-back responsible of transmitting NTFY to all ASPs in + * case of AS state changes */ +static void xua_as_fsm_onenter(struct osmo_fsm_inst *fi, uint32_t old_state) +{ + struct xua_as_fsm_priv *xafp = (struct xua_as_fsm_priv *) fi->priv; + struct m3ua_notify_params npar = { + .status_type = M3UA_NOTIFY_T_STATCHG, + }; + + switch (fi->state) { + case XUA_AS_S_INACTIVE: + npar.status_info = M3UA_NOTIFY_I_AS_INACT; + break; + case XUA_AS_S_ACTIVE: + npar.status_info = M3UA_NOTIFY_I_AS_ACT; + break; + case XUA_AS_S_PENDING: + npar.status_info = M3UA_NOTIFY_I_AS_PEND; + break; + default: + return; + } + + asp_notify_all_as(xafp->as, &npar); +}; + +static void xua_as_fsm_inactive(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct xua_as_fsm_priv *xafp = (struct xua_as_fsm_priv *) fi->priv; + struct osmo_ss7_asp *asp = data; + + switch (event) { + case XUA_ASPAS_ASP_DOWN_IND: + /* one ASP transitions into ASP-DOWN */ + if (check_any_other_asp_not_down(xafp->as, asp)) { + /* ignore, we stay AS_INACTIVE */ + } else + osmo_fsm_inst_state_chg(fi, XUA_AS_S_DOWN, 0, 0); + break; + case XUA_ASPAS_ASP_ACTIVE_IND: + /* one ASP transitions into ASP-ACTIVE */ + osmo_fsm_inst_state_chg(fi, XUA_AS_S_ACTIVE, 0, 0); + break; + case XUA_ASPAS_ASP_INACTIVE_IND: + /* ignore */ + break; + } +} + +static void xua_as_fsm_active(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct xua_as_fsm_priv *xafp = (struct xua_as_fsm_priv *) fi->priv; + struct osmo_ss7_asp *asp = data; + + switch (event) { + case XUA_ASPAS_ASP_DOWN_IND: + case XUA_ASPAS_ASP_INACTIVE_IND: + if (check_any_other_asp_in_active(xafp->as, asp)) { + /* ignore, we stay AS_ACTIVE */ + } else { + osmo_fsm_inst_state_chg(fi, XUA_AS_S_PENDING, 0, 0); + /* FIXME: Start T(r) */ + /* FIXME: Queue all signalling messages until + * recovery or T(r) expiry */ + } + break; + case XUA_ASPAS_ASP_ACTIVE_IND: + /* ignore */ + break; + } +} + +static void xua_as_fsm_pending(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + switch (event) { + case XUA_ASPAS_ASP_ACTIVE_IND: + /* one ASP transitions into ASP-ACTIVE */ + osmo_fsm_inst_state_chg(fi, XUA_AS_S_ACTIVE, 0, 0); + break; + case XUA_ASPAS_ASP_INACTIVE_IND: + /* ignore */ + break; + case XUA_ASPAS_ASP_DOWN_IND: + /* ignore */ + break; + } +} + +static const struct osmo_fsm_state xua_as_fsm_states[] = { + [XUA_AS_S_DOWN] = { + .in_event_mask = S(XUA_ASPAS_ASP_INACTIVE_IND) | + S(XUA_ASPAS_ASP_DOWN_IND), + .out_state_mask = S(XUA_AS_S_DOWN) | + S(XUA_AS_S_INACTIVE), + .name = "AS_DOWN", + .action = xua_as_fsm_down, + }, + [XUA_AS_S_INACTIVE] = { + .in_event_mask = S(XUA_ASPAS_ASP_DOWN_IND) | + S(XUA_ASPAS_ASP_ACTIVE_IND) | + S(XUA_ASPAS_ASP_INACTIVE_IND), + .out_state_mask = S(XUA_AS_S_DOWN) | + S(XUA_AS_S_INACTIVE) | + S(XUA_AS_S_ACTIVE), + .name = "AS_INACTIVE", + .action = xua_as_fsm_inactive, + .onenter = xua_as_fsm_onenter, + }, + [XUA_AS_S_ACTIVE] = { + .in_event_mask = S(XUA_ASPAS_ASP_DOWN_IND) | + S(XUA_ASPAS_ASP_INACTIVE_IND) | + S(XUA_ASPAS_ASP_ACTIVE_IND), + .out_state_mask = S(XUA_AS_S_ACTIVE) | + S(XUA_AS_S_PENDING), + .name = "AS_ACTIVE", + .action = xua_as_fsm_active, + .onenter = xua_as_fsm_onenter, + }, + [XUA_AS_S_PENDING] = { + .in_event_mask = S(XUA_ASPAS_ASP_INACTIVE_IND) | + S(XUA_ASPAS_ASP_DOWN_IND) | + S(XUA_ASPAS_ASP_ACTIVE_IND), + .out_state_mask = S(XUA_AS_S_DOWN) | + S(XUA_AS_S_INACTIVE) | + S(XUA_AS_S_ACTIVE) | + S(XUA_AS_S_PENDING), + .name = "AS_PENDING", + .action = xua_as_fsm_pending, + .onenter = xua_as_fsm_onenter, + }, +}; + +struct osmo_fsm xua_as_fsm = { + .name = "XUA_AS", + .states = xua_as_fsm_states, + .num_states = ARRAY_SIZE(xua_as_fsm_states), + .log_subsys = DLSS7, + .event_names = xua_as_event_names, +}; + +/*! \brief Start an AS FSM for a given Application Server + * \param[in] as Application Server for which to start the AS FSM + * \param[in] log_level Logging level for logging of this FSM + * \returns FSM instance in case of success; NULL in case of error */ +struct osmo_fsm_inst *xua_as_fsm_start(struct osmo_ss7_as *as, int log_level) +{ + struct osmo_fsm_inst *fi; + struct xua_as_fsm_priv *xafp; + + fi = osmo_fsm_inst_alloc(&xua_as_fsm, as, NULL, log_level, as->cfg.name); + + xafp = talloc_zero(fi, struct xua_as_fsm_priv); + if (!xafp) { + osmo_fsm_inst_term(fi, OSMO_FSM_TERM_ERROR, NULL); + return NULL; + } + xafp->as = as; + + fi->priv = xafp; + + return fi; +} diff --git a/src/xua_as_fsm.h b/src/xua_as_fsm.h new file mode 100644 index 0000000..3b8e5b7 --- /dev/null +++ b/src/xua_as_fsm.h @@ -0,0 +1,13 @@ +#pragma once + +struct osmo_ss7_as; + +enum xua_as_event { + XUA_ASPAS_ASP_INACTIVE_IND, + XUA_ASPAS_ASP_DOWN_IND, + XUA_ASPAS_ASP_ACTIVE_IND, +}; + +extern struct osmo_fsm xua_as_fsm; + +struct osmo_fsm_inst *xua_as_fsm_start(struct osmo_ss7_as *as, int log_level); diff --git a/src/xua_asp_fsm.c b/src/xua_asp_fsm.c new file mode 100644 index 0000000..80faeb2 --- /dev/null +++ b/src/xua_asp_fsm.c @@ -0,0 +1,610 @@ +/* SCCP M3UA / SUA ASP osmo_fsm according to RFC3868 4.3.1 */ +/* (C) Copyright 2017 by Harald Welte + * + * All Rights reserved. + * + * Based on my earlier Erlang implementation xua_asp_fsm.erl in + * osmo-ss7.git + */ + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "xua_asp_fsm.h" +#include "xua_as_fsm.h" + +#define S(x) (1 << (x)) + +/* The general idea is: + * * translate incoming SUA/M3UA msg_class/msg_type to xua_asp_event + * * propagate state transitions to XUA_AS_FSM via _onenter functiosn + * * notify the Layer Management of any relevant changes + * * + */ + +/* According to RFC3868 Section 8 */ +#define XUA_T_A_SEC 2 +#define XUA_T_R_SEC 2 +#define XUA_T_ACK_SEC 2 +#define XUA_T_BEAT_SEC 30 +#define SUA_T_IAS_SEC (7*60) /* SUA only */ +#define SUA_T_IAR_SEC (15*60) /* SUA only */ + +static const struct value_string xua_asp_role_names[] = { + { XUA_ASPFSM_ROLE_ASP, "ASP" }, + { XUA_ASPFSM_ROLE_SG, "SG" }, + { XUA_ASPFSM_ROLE_IPSP, "IPSP" }, + { 0, NULL } +}; + +static const struct value_string xua_asp_event_names[] = { + { XUA_ASP_E_M_ASP_UP_REQ, "M-ASP_UP.req" }, + { XUA_ASP_E_M_ASP_ACTIVE_REQ, "M-ASP_ACTIVE.req" }, + { XUA_ASP_E_M_ASP_DOWN_REQ, "M-ASP_DOWN.req" }, + { XUA_ASP_E_M_ASP_INACTIVE_REQ, "M-ASP_INACTIVE.req" }, + + { XUA_ASP_E_SCTP_COMM_DOWN_IND, "SCTP-COMM_DOWN.ind" }, + { XUA_ASP_E_SCTP_RESTART_IND, "SCTP-RESTART.ind" }, + + { XUA_ASP_E_ASPSM_ASPUP, "ASPSM-ASP_UP" }, + { XUA_ASP_E_ASPSM_ASPUP_ACK, "ASPSM-ASP_UP_ACK" }, + { XUA_ASP_E_ASPTM_ASPAC, "ASPTM-ASP_AC" }, + { XUA_ASP_E_ASPTM_ASPAC_ACK, "ASPTM-ASP_AC_ACK" }, + { XUA_ASP_E_ASPSM_ASPDN, "ASPSM-ASP_DN" }, + { XUA_ASP_E_ASPSM_ASPDN_ACK, "ASPSM-ASP_DN_ACK" }, + { XUA_ASP_E_ASPTM_ASPIA, "ASPTM-ASP_IA" }, + { XUA_ASP_E_ASPTM_ASPIA_ACK, "ASPTM_ASP_IA_ACK" }, + { 0, NULL } +}; + +struct xua_layer_manager { + osmo_prim_cb prim_cb; +}; + +/* private data structure for each FSM instance */ +struct xua_asp_fsm_priv { + /* pointer back to ASP to which we belong */ + struct osmo_ss7_asp *asp; + /* Role (ASP/SG/IPSP) */ + enum xua_asp_role role; + /* Layer Manager to which we talk */ + struct xua_layer_manager *lm; + + /* routing context[s]: list of 32bit integers */ + /* ACTIVE: traffic mode type, tid label, drn label ? */ + + struct { + struct osmo_timer_list timer; + int out_event; + } t_ack; +}; + +static struct msgb *xlm_msgb_alloc(void) +{ + return msgb_alloc_headroom(2048+128, 128, "xua_asp-xlm msgb"); +} + +/* Send a XUA LM Primitive to the XUA Layer Manager (LM) */ +static int send_xlm_prim(struct osmo_fsm_inst *fi, + enum osmo_xlm_prim_type prim_type, + enum osmo_prim_operation op, + const uint8_t *data, unsigned int data_len) +{ + struct xua_asp_fsm_priv *xafp = fi->priv; + struct msgb *xlmsg; + struct osmo_xlm_prim *prim; + struct xua_layer_manager *lm = xafp->lm; + + if (!lm || !lm->prim_cb) + return 0; + + xlmsg = xlm_msgb_alloc(); + if (!xlmsg) + return -ENOMEM; + prim = (struct osmo_xlm_prim *) msgb_put(xlmsg, sizeof(*prim)); + osmo_prim_init(&prim->oph, XUA_SAP_LM, prim_type, op, xlmsg); + + lm->prim_cb(&prim->oph, xafp->asp); + + return 0; +} + +/* wrapper around send_xlm_prim for primitives without data */ +static int send_xlm_prim_simple(struct osmo_fsm_inst *fi, + enum osmo_xlm_prim_type prim, + enum osmo_prim_operation op) +{ + return send_xlm_prim(fi, prim, op, NULL, 0); +} + +/* ask the xUA implementation to transmit a specific message */ +static int peer_send(struct osmo_fsm_inst *fi, int out_event) +{ + struct xua_asp_fsm_priv *xafp = fi->priv; + struct osmo_ss7_asp *asp = xafp->asp; + struct xua_msg *xua = xua_msg_alloc(); + struct msgb *msg; + + switch (out_event) { + case XUA_ASP_E_ASPSM_ASPUP: + /* RFC 3868 Ch. 3.5.1 */ + xua->hdr = XUA_HDR(SUA_MSGC_ASPSM, SUA_ASPSM_UP); + /* Optional: ASP ID */ + if (asp->asp_id_present) + xua_msg_add_u32(xua, SUA_IEI_ASP_ID, asp->asp_id); + /* Optional: Info String */ + break; + case XUA_ASP_E_ASPSM_ASPUP_ACK: + /* RFC3868 Ch. 3.5.2 */ + xua->hdr = XUA_HDR(SUA_MSGC_ASPSM, SUA_ASPSM_UP_ACK); + /* Optional: Info String */ + break; + case XUA_ASP_E_ASPSM_ASPDN: + /* RFC3868 Ch. 3.5.3 */ + xua->hdr = XUA_HDR(SUA_MSGC_ASPSM, SUA_ASPSM_DOWN); + /* Optional: Info String */ + break; + case XUA_ASP_E_ASPSM_ASPDN_ACK: + /* RFC3868 Ch. 3.5.4 */ + xua->hdr = XUA_HDR(SUA_MSGC_ASPSM, SUA_ASPSM_DOWN_ACK); + /* Optional: Info String */ + break; + case XUA_ASP_E_ASPSM_BEAT: + /* RFC3868 Ch. 3.5.5 */ + xua->hdr = XUA_HDR(SUA_MSGC_ASPSM, SUA_ASPSM_BEAT); + /* Optional: Heartbeat Data */ + break; + case XUA_ASP_E_ASPSM_BEAT_ACK: + /* RFC3868 Ch. 3.5.6 */ + xua->hdr = XUA_HDR(SUA_MSGC_ASPSM, SUA_ASPSM_BEAT_ACK); + /* Optional: Heartbeat Data */ + break; + case XUA_ASP_E_ASPTM_ASPAC: + /* RFC3868 Ch. 3.6.1 */ + xua->hdr = XUA_HDR(SUA_MSGC_ASPTM, SUA_ASPTM_ACTIVE); + /* Optional: Traffic Mode Type */ + /* Optional: Routing Context */ + /* Optional: TID Label */ + /* Optional: DRN Label */ + /* Optional: Info String */ + break; + case XUA_ASP_E_ASPTM_ASPAC_ACK: + /* RFC3868 Ch. 3.6.2 */ + xua->hdr = XUA_HDR(SUA_MSGC_ASPTM, SUA_ASPTM_ACTIVE_ACK); + /* Optional: Traffic Mode Type */ + /* Mandatory: Routing Context */ + //FIXME xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, + /* Optional: Info String */ + break; + case XUA_ASP_E_ASPTM_ASPIA: + /* RFC3868 Ch. 3.6.3 */ + xua->hdr = XUA_HDR(SUA_MSGC_ASPTM, SUA_ASPTM_INACTIVE); + /* Optional: Routing Context */ + /* Optional: Info String */ + break; + case XUA_ASP_E_ASPTM_ASPIA_ACK: + /* RFC3868 Ch. 3.6.4 */ + xua->hdr = XUA_HDR(SUA_MSGC_ASPTM, SUA_ASPTM_INACTIVE_ACK); + /* Optional: Routing Context */ + /* Optional: Info String */ + break; + } + + msg = xua_to_msg(SUA_VERSION, xua); + xua_msg_free(xua); + if (!msg) + return -1; + + return osmo_ss7_asp_send(asp, msg); +} + +static void xua_t_ack_cb(void *data) +{ + struct osmo_fsm_inst *fi = data; + struct xua_asp_fsm_priv *xafp = fi->priv; + + LOGPFSML(fi, LOGL_INFO, "T(ack) callback: re-transmitting event %s\n", + osmo_fsm_event_name(fi->fsm, xafp->t_ack.out_event)); + + /* Re-transmit message */ + peer_send(fi, xafp->t_ack.out_event); + + /* Re-start the timer */ + osmo_timer_schedule(&xafp->t_ack.timer, XUA_T_ACK_SEC, 0); +} + +static int peer_send_and_start_t_ack(struct osmo_fsm_inst *fi, + int out_event) +{ + struct xua_asp_fsm_priv *xafp = fi->priv; + int rc; + + rc = peer_send(fi, out_event); + if (rc < 0) + return rc; + + xafp->t_ack.out_event = out_event; + xafp->t_ack.timer.cb = xua_t_ack_cb, + xafp->t_ack.timer.data = fi; + + osmo_timer_schedule(&xafp->t_ack.timer, XUA_T_ACK_SEC, 0); + + return rc; +} + +static const uint32_t evt_ack_map[_NUM_XUA_ASP_E] = { + [XUA_ASP_E_ASPSM_ASPUP] = XUA_ASP_E_ASPSM_ASPUP_ACK, + [XUA_ASP_E_ASPTM_ASPAC] = XUA_ASP_E_ASPTM_ASPAC_ACK, + [XUA_ASP_E_ASPSM_ASPDN] = XUA_ASP_E_ASPSM_ASPDN_ACK, + [XUA_ASP_E_ASPTM_ASPIA] = XUA_ASP_E_ASPTM_ASPIA_ACK, + [XUA_ASP_E_ASPSM_BEAT] = XUA_ASP_E_ASPSM_BEAT_ACK, +}; + + +/* check if expected message was received + stop t_ack */ +static void check_stop_t_ack(struct osmo_fsm_inst *fi, uint32_t event) +{ + struct xua_asp_fsm_priv *xafp = fi->priv; + int exp_ack; + + if (event >= ARRAY_SIZE(evt_ack_map)) + return; + + exp_ack = evt_ack_map[xafp->t_ack.out_event]; + if (exp_ack && event == exp_ack) { + LOGPFSML(fi, LOGL_DEBUG, "T(ack) stopped\n"); + osmo_timer_del(&xafp->t_ack.timer); + } +} + +#define ENSURE_ASP_OR_IPSP(fi, event) \ + do { \ + struct xua_asp_fsm_priv *_xafp = fi->priv; \ + if (_xafp->role != XUA_ASPFSM_ROLE_ASP && \ + _xafp->role != XUA_ASPFSM_ROLE_IPSP) { \ + LOGPFSML(fi, LOGL_ERROR, "event %s not permitted " \ + "in role %s\n", \ + osmo_fsm_event_name(fi->fsm, event), \ + get_value_string(xua_asp_role_names, _xafp->role));\ + return; \ + } \ + } while(0) + +#define ENSURE_SG_OR_IPSP(fi, event) \ + do { \ + struct xua_asp_fsm_priv *_xafp = fi->priv; \ + if (_xafp->role != XUA_ASPFSM_ROLE_SG && \ + _xafp->role != XUA_ASPFSM_ROLE_IPSP) { \ + LOGPFSML(fi, LOGL_ERROR, "event %s not permitted " \ + "in role %s\n", \ + osmo_fsm_event_name(fi->fsm, event), \ + get_value_string(xua_asp_role_names, _xafp->role));\ + return; \ + } \ + } while(0) + +static void xua_asp_fsm_down(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct xua_asp_fsm_priv *xafp = fi->priv; + struct osmo_ss7_asp *asp = xafp->asp; + struct xua_msg_part *asp_id_ie; + + check_stop_t_ack(fi, event); + + switch (event) { + case XUA_ASP_E_M_ASP_UP_REQ: + /* only if role ASP */ + ENSURE_ASP_OR_IPSP(fi, event); + /* Send M3UA_MSGT_ASPSM_ASPUP and start t_ack */ + peer_send_and_start_t_ack(fi, XUA_ASP_E_ASPSM_ASPUP); + break; + case XUA_ASP_E_ASPSM_ASPUP_ACK: + /* only if role ASP */ + ENSURE_ASP_OR_IPSP(fi, event); + osmo_fsm_inst_state_chg(fi, XUA_ASP_S_INACTIVE, 0, 0); + /* inform layer manager */ + send_xlm_prim_simple(fi, OSMO_XLM_PRIM_M_ASP_UP, + PRIM_OP_CONFIRM); + /* FIXME: This hack should be in layer manager? */ + osmo_fsm_inst_dispatch(fi, XUA_ASP_E_M_ASP_ACTIVE_REQ, NULL); + break; + case XUA_ASP_E_ASPSM_ASPUP: + /* only if role SG */ + ENSURE_SG_OR_IPSP(fi, event); + asp_id_ie = xua_msg_find_tag(data, SUA_IEI_ASP_ID); + /* Optional ASP Identifier: Store for NTFY */ + if (asp_id_ie) { + asp->asp_id = xua_msg_part_get_u32(asp_id_ie); + asp->asp_id_present = true; + } + /* send ACK */ + peer_send(fi, XUA_ASP_E_ASPSM_ASPUP_ACK); + /* transition state and inform layer manager */ + osmo_fsm_inst_state_chg(fi, XUA_ASP_S_INACTIVE, 0, 0); + send_xlm_prim_simple(fi, OSMO_XLM_PRIM_M_ASP_UP, + PRIM_OP_INDICATION); + break; + case XUA_ASP_E_ASPSM_ASPDN: + /* only if role SG */ + ENSURE_SG_OR_IPSP(fi, event); + /* The SGP MUST send an ASP Down Ack message in response + * to a received ASP Down message from the ASP even if + * the ASP is already marked as ASP-DOWN at the SGP. */ + peer_send(fi, XUA_ASP_E_ASPSM_ASPDN_ACK); + break; + } +} + +/* Helper function to dispatch an ASP->AS event to all AS of which this + * ASP is a memmber. Ignores routing contexts for now. */ +static void dispatch_to_all_as(struct osmo_fsm_inst *fi, uint32_t event) +{ + struct xua_asp_fsm_priv *xafp = fi->priv; + struct osmo_ss7_asp *asp = xafp->asp; + struct osmo_ss7_instance *inst = asp->inst; + struct osmo_ss7_as *as; + + if (xafp->role != XUA_ASPFSM_ROLE_SG) + return; + + llist_for_each_entry(as, &inst->as_list, list) { + if (!osmo_ss7_as_has_asp(as, asp)) + continue; + osmo_fsm_inst_dispatch(as->fi, event, asp); + } +} + +static void xua_asp_fsm_down_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state) +{ + dispatch_to_all_as(fi, XUA_ASPAS_ASP_DOWN_IND); +} + +static void xua_asp_fsm_inactive(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + check_stop_t_ack(fi, event); + switch (event) { + case XUA_ASP_E_M_ASP_ACTIVE_REQ: + /* send M3UA_MSGT_ASPTM_ASPAC and start t_ack */ + peer_send_and_start_t_ack(fi, XUA_ASP_E_ASPTM_ASPAC); + break; + case XUA_ASP_E_M_ASP_DOWN_REQ: + /* send M3UA_MSGT_ASPSM_ASPDN and start t_ack */ + peer_send_and_start_t_ack(fi, XUA_ASP_E_ASPSM_ASPDN); + break; + case XUA_ASP_E_ASPTM_ASPAC_ACK: + /* only in role ASP */ + ENSURE_ASP_OR_IPSP(fi, event); + /* transition state and inform layer manager */ + osmo_fsm_inst_state_chg(fi, XUA_ASP_S_ACTIVE, 0, 0); + send_xlm_prim_simple(fi, OSMO_XLM_PRIM_M_ASP_ACTIVE, + PRIM_OP_CONFIRM); + break; + case XUA_ASP_E_ASPSM_ASPDN_ACK: + /* only in role ASP */ + ENSURE_ASP_OR_IPSP(fi, event); + /* transition state and inform layer manager */ + osmo_fsm_inst_state_chg(fi, XUA_ASP_S_DOWN, 0, 0); + send_xlm_prim_simple(fi, OSMO_XLM_PRIM_M_ASP_DOWN, + PRIM_OP_CONFIRM); + break; + case XUA_ASP_E_ASPTM_ASPAC: + /* only in role SG */ + ENSURE_SG_OR_IPSP(fi, event); + /* send ACK */ + peer_send(fi, XUA_ASP_E_ASPTM_ASPAC_ACK); + /* transition state and inform layer manager */ + osmo_fsm_inst_state_chg(fi, XUA_ASP_S_ACTIVE, 0, 0); + send_xlm_prim_simple(fi, OSMO_XLM_PRIM_M_ASP_ACTIVE, + PRIM_OP_INDICATION); + break; + case XUA_ASP_E_ASPSM_ASPDN: + /* only in role SG */ + ENSURE_SG_OR_IPSP(fi, event); + /* send ACK */ + peer_send(fi, XUA_ASP_E_ASPSM_ASPDN_ACK); + /* transition state and inform layer manager */ + osmo_fsm_inst_state_chg(fi, XUA_ASP_S_DOWN, 0, 0); + send_xlm_prim_simple(fi, OSMO_XLM_PRIM_M_ASP_DOWN, + PRIM_OP_INDICATION); + break; + case XUA_ASP_E_ASPSM_ASPUP: + /* only if role SG */ + ENSURE_SG_OR_IPSP(fi, event); + /* If an ASP Up message is received and internally the + * remote ASP is already in the ASP-INACTIVE state, an + * ASP Up Ack message is returned and no further action + * is taken. */ + peer_send(fi, XUA_ASP_E_ASPSM_ASPUP_ACK); + break; + } +} + +static void xua_asp_fsm_inactive_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state) +{ + dispatch_to_all_as(fi, XUA_ASPAS_ASP_INACTIVE_IND); +} + +static void xua_asp_fsm_active(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + check_stop_t_ack(fi, event); + switch (event) { + case XUA_ASP_E_ASPSM_ASPDN_ACK: + /* only in role ASP */ + ENSURE_ASP_OR_IPSP(fi, event); + osmo_fsm_inst_state_chg(fi, XUA_ASP_S_DOWN, 0, 0); + /* inform layer manager */ + send_xlm_prim_simple(fi, OSMO_XLM_PRIM_M_ASP_DOWN, + PRIM_OP_CONFIRM); + break; + case XUA_ASP_E_ASPTM_ASPIA_ACK: + /* only in role ASP */ + ENSURE_ASP_OR_IPSP(fi, event); + osmo_fsm_inst_state_chg(fi, XUA_ASP_S_INACTIVE, 0, 0); + /* inform layer manager */ + send_xlm_prim_simple(fi, OSMO_XLM_PRIM_M_ASP_INACTIVE, + PRIM_OP_CONFIRM); + break; + case XUA_ASP_E_M_ASP_DOWN_REQ: + /* only in role ASP */ + ENSURE_ASP_OR_IPSP(fi, event); + /* send M3UA_MSGT_ASPSM_ASPDN and star t_ack */ + peer_send_and_start_t_ack(fi, XUA_ASP_E_ASPSM_ASPDN); + break; + case XUA_ASP_E_M_ASP_INACTIVE_REQ: + /* only in role ASP */ + ENSURE_ASP_OR_IPSP(fi, event); + /* send M3UA_MSGT_ASPTM_ASPIA and star t_ack */ + peer_send_and_start_t_ack(fi, XUA_ASP_E_ASPTM_ASPIA); + break; + case XUA_ASP_E_ASPTM_ASPIA: + /* only in role SG */ + ENSURE_SG_OR_IPSP(fi, event); + /* send ACK */ + peer_send(fi, XUA_ASP_E_ASPTM_ASPIA_ACK); + /* transition state and inform layer manager */ + osmo_fsm_inst_state_chg(fi, XUA_ASP_S_INACTIVE, 0, 0); + send_xlm_prim_simple(fi, OSMO_XLM_PRIM_M_ASP_INACTIVE, + PRIM_OP_INDICATION); + break; + case XUA_ASP_E_ASPSM_ASPDN: + /* only in role SG */ + ENSURE_SG_OR_IPSP(fi, event); + /* send ACK */ + peer_send(fi, XUA_ASP_E_ASPSM_ASPDN_ACK); + /* transition state and inform layer manager */ + osmo_fsm_inst_state_chg(fi, XUA_ASP_S_DOWN, 0, 0); + send_xlm_prim_simple(fi, OSMO_XLM_PRIM_M_ASP_DOWN, + PRIM_OP_INDICATION); + break; + case XUA_ASP_E_ASPSM_ASPUP: + /* only if role SG */ + ENSURE_SG_OR_IPSP(fi, event); + /* an ASP Up Ack message is returned, as well as + * an Error message ("Unexpected Message), and the + * remote ASP state is changed to ASP-INACTIVE in all + * relevant Application Servers */ + /* FIXME: Send ERROR message */ + osmo_fsm_inst_state_chg(fi, XUA_ASP_S_INACTIVE, 0, 0); + send_xlm_prim_simple(fi, OSMO_XLM_PRIM_M_ASP_INACTIVE, + PRIM_OP_INDICATION); + break; + } +} + +static void xua_asp_fsm_active_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state) +{ + dispatch_to_all_as(fi, XUA_ASPAS_ASP_ACTIVE_IND); +} + +static void xua_asp_allstate(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + switch (event) { + case XUA_ASP_E_SCTP_COMM_DOWN_IND: + case XUA_ASP_E_SCTP_RESTART_IND: + osmo_fsm_inst_state_chg(fi, XUA_ASP_S_DOWN, 0, 0); + send_xlm_prim_simple(fi, OSMO_XLM_PRIM_M_ASP_DOWN, + PRIM_OP_INDICATION); + break; + default: + break; + } +} + +static int xua_asp_fsm_timer_cb(struct osmo_fsm_inst *fi) +{ + /* We don't use the fsm timer, so any calls to this are an error */ + OSMO_ASSERT(0); + return 0; +} + +static const struct osmo_fsm_state xua_asp_states[] = { + [XUA_ASP_S_DOWN] = { + .in_event_mask = S(XUA_ASP_E_M_ASP_UP_REQ) | + S(XUA_ASP_E_ASPSM_ASPUP) | + S(XUA_ASP_E_ASPSM_ASPUP_ACK) | + S(XUA_ASP_E_ASPSM_ASPDN), + .out_state_mask = S(XUA_ASP_S_INACTIVE), + .name = "ASP_DOWN", + .action = xua_asp_fsm_down, + .onenter = xua_asp_fsm_down_onenter, + }, + [XUA_ASP_S_INACTIVE] = { + .in_event_mask = S(XUA_ASP_E_M_ASP_ACTIVE_REQ) | + S(XUA_ASP_E_M_ASP_DOWN_REQ) | + S(XUA_ASP_E_ASPTM_ASPAC) | + S(XUA_ASP_E_ASPTM_ASPAC_ACK) | + S(XUA_ASP_E_ASPSM_ASPDN) | + S(XUA_ASP_E_ASPSM_ASPDN_ACK) | + S(XUA_ASP_E_ASPSM_ASPUP), + .out_state_mask = S(XUA_ASP_S_DOWN) | + S(XUA_ASP_S_ACTIVE), + .name = "ASP_INACTIVE", + .action = xua_asp_fsm_inactive, + .onenter = xua_asp_fsm_inactive_onenter, + }, + [XUA_ASP_S_ACTIVE] = { + .in_event_mask = S(XUA_ASP_E_ASPSM_ASPDN) | + S(XUA_ASP_E_ASPSM_ASPDN_ACK) | + S(XUA_ASP_E_ASPSM_ASPUP) | + S(XUA_ASP_E_ASPTM_ASPIA) | + S(XUA_ASP_E_ASPTM_ASPIA_ACK) | + S(XUA_ASP_E_M_ASP_DOWN_REQ) | + S(XUA_ASP_E_M_ASP_INACTIVE_REQ), + .out_state_mask = S(XUA_ASP_S_INACTIVE) | + S(XUA_ASP_S_DOWN), + .name = "ASP_ACTIVE", + .action = xua_asp_fsm_active, + .onenter = xua_asp_fsm_active_onenter, + }, +}; + + +struct osmo_fsm xua_asp_fsm = { + .name = "XUA_ASP", + .states = xua_asp_states, + .num_states = ARRAY_SIZE(xua_asp_states), + .timer_cb = xua_asp_fsm_timer_cb, + .log_subsys = DLSS7, + .event_names = xua_asp_event_names, + .allstate_event_mask = S(XUA_ASP_E_SCTP_COMM_DOWN_IND) | + S(XUA_ASP_E_SCTP_RESTART_IND), + .allstate_action = xua_asp_allstate, +}; + + +/*! \brief Start a new ASP finite stae machine for given ASP + * \param[in] asp Application Server Process for which to start FSM + * \param[in] role Role (ASP, SG, IPSP) of this FSM + * \param[in] log_level Logging Level for ASP FSM logging + * \returns FSM instance on success; NULL on error */ +struct osmo_fsm_inst *xua_asp_fsm_start(struct osmo_ss7_asp *asp, + enum xua_asp_role role, int log_level) +{ + struct osmo_fsm_inst *fi; + struct xua_asp_fsm_priv *xafp; + + /* allocate as child of AS? */ + fi = osmo_fsm_inst_alloc(&xua_asp_fsm, asp, NULL, log_level, asp->cfg.name); + + xafp = talloc_zero(fi, struct xua_asp_fsm_priv); + if (!xafp) { + osmo_fsm_inst_term(fi, OSMO_FSM_TERM_ERROR, NULL); + return NULL; + } + xafp->role = role; + xafp->asp = asp; + + fi->priv = xafp; + + return fi; +} diff --git a/src/xua_asp_fsm.h b/src/xua_asp_fsm.h new file mode 100644 index 0000000..ea62484 --- /dev/null +++ b/src/xua_asp_fsm.h @@ -0,0 +1,42 @@ +#pragma once + +enum xua_asp_state { + XUA_ASP_S_DOWN, + XUA_ASP_S_INACTIVE, + XUA_ASP_S_ACTIVE, +}; + +enum xua_asp_event { + XUA_ASP_E_M_ASP_UP_REQ, + XUA_ASP_E_M_ASP_ACTIVE_REQ, + XUA_ASP_E_M_ASP_DOWN_REQ, + XUA_ASP_E_M_ASP_INACTIVE_REQ, + + XUA_ASP_E_SCTP_COMM_DOWN_IND, + XUA_ASP_E_SCTP_RESTART_IND, + + XUA_ASP_E_ASPSM_ASPUP, + XUA_ASP_E_ASPSM_ASPUP_ACK, + XUA_ASP_E_ASPTM_ASPAC, + XUA_ASP_E_ASPTM_ASPAC_ACK, + XUA_ASP_E_ASPSM_ASPDN, + XUA_ASP_E_ASPSM_ASPDN_ACK, + XUA_ASP_E_ASPTM_ASPIA, + XUA_ASP_E_ASPTM_ASPIA_ACK, + + XUA_ASP_E_ASPSM_BEAT, + XUA_ASP_E_ASPSM_BEAT_ACK, + + _NUM_XUA_ASP_E +}; + +enum xua_asp_role { + XUA_ASPFSM_ROLE_ASP, + XUA_ASPFSM_ROLE_SG, + XUA_ASPFSM_ROLE_IPSP, +}; + +extern struct osmo_fsm xua_asp_fsm; + +struct osmo_fsm_inst *xua_asp_fsm_start(struct osmo_ss7_asp *asp, + enum xua_asp_role role, int log_level); diff --git a/src/xua_internal.h b/src/xua_internal.h new file mode 100644 index 0000000..66b5a26 --- /dev/null +++ b/src/xua_internal.h @@ -0,0 +1,58 @@ +#pragma once + +#include +#include + +struct osmo_sccp_addr; +struct m3ua_data_hdr; + +int sua_addr_parse_part(struct osmo_sccp_addr *out, + const struct xua_msg_part *param); +int sua_addr_parse(struct osmo_sccp_addr *out, struct xua_msg *xua, uint16_t iei); + +int sua_parse_gt(struct osmo_sccp_gt *gt, const uint8_t *data, unsigned int datalen); + +struct xua_msg *osmo_sccp_to_xua(struct msgb *msg); +struct msgb *osmo_sua_to_sccp(struct xua_msg *xua); + +int sua_tx_xua_as(struct osmo_ss7_as *as, struct xua_msg *xua); + +struct osmo_mtp_prim *m3ua_to_xfer_ind(struct xua_msg *xua); +int m3ua_hmdc_rx_from_l2(struct osmo_ss7_instance *inst, struct xua_msg *xua); +int m3ua_tx_xua_as(struct osmo_ss7_as *as, struct xua_msg *xua); +int m3ua_rx_msg(struct osmo_ss7_asp *asp, struct msgb *msg); + +struct msgb *m3ua_msgb_alloc(const char *name); +struct m3ua_data_hdr *data_hdr_from_m3ua(struct xua_msg *xua); +void m3ua_dh_to_xfer_param(struct osmo_mtp_transfer_param *param, + const struct m3ua_data_hdr *mdh); +void mtp_xfer_param_to_m3ua_dh(struct m3ua_data_hdr *mdh, + const struct osmo_mtp_transfer_param *param); + + +extern const struct xua_msg_class m3ua_msg_class_mgmt; +extern const struct xua_msg_class m3ua_msg_class_snm; +extern const struct xua_msg_class m3ua_msg_class_rkm; +extern const struct xua_msg_class m3ua_msg_class_aspsm; +extern const struct xua_msg_class m3ua_msg_class_asptm; + +extern const struct value_string m3ua_err_names[]; +extern const struct value_string m3ua_ntfy_type_names[]; +extern const struct value_string m3ua_ntfy_stchg_names[]; +extern const struct value_string m3ua_ntfy_other_names[]; + +#define NOTIFY_PAR_P_ASP_ID (1 << 0) +#define NOTIFY_PAR_P_ROUTE_CTX (1 << 1) + +struct m3ua_notify_params { + uint32_t presence; + uint16_t status_type; + uint16_t status_info; + uint32_t asp_id; + uint32_t route_ctx; + char *info_string; +}; + +struct xua_msg *m3ua_encode_notify(const struct m3ua_notify_params *npar); +int m3ua_decode_notify(struct m3ua_notify_params *npar, void *ctx, + const struct xua_msg *xua); diff --git a/tests/Makefile.am b/tests/Makefile.am index 6e9b807..9c251fe 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,4 +1,4 @@ -SUBDIRS = sccp mtp m2ua sigtran +SUBDIRS = sccp mtp m2ua sigtran ss7 # The `:;' works around a Bash 3.2 bug when the output is not writeable. $(srcdir)/package.m4: $(top_srcdir)/configure.ac diff --git a/tests/ss7/Makefile.am b/tests/ss7/Makefile.am new file mode 100644 index 0000000..bc81915 --- /dev/null +++ b/tests/ss7/Makefile.am @@ -0,0 +1,12 @@ +AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -Wall +AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) + +AM_LDFLAGS = -static +LDADD = $(top_builddir)/src/libosmo-sigtran.la \ + $(LIBOSMOCORE_LIBS) $(LIBOSMONETIF_LIBS) $(LIBSCTP_LIBS) + +EXTRA_DIST = ss7_test.ok ss7_test.err + +noinst_PROGRAMS = ss7_test + +ss7_test_SOURCES = ss7_test.c diff --git a/tests/ss7/ss7_test.c b/tests/ss7/ss7_test.c new file mode 100644 index 0000000..24eabc9 --- /dev/null +++ b/tests/ss7/ss7_test.c @@ -0,0 +1,321 @@ +#include "../src/xua_internal.h" +#include "../src/xua_asp_fsm.h" + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +static struct osmo_ss7_instance *s7i; + +static void test_pc_transcode(uint32_t pc) +{ + const char *pc_str = osmo_ss7_pointcode_print(s7i, pc); + uint32_t pc_reenc = osmo_ss7_pointcode_parse(s7i, pc_str); + + printf("%s(%u) -> %s -> %u\n", __func__, pc, pc_str, pc_reenc); + OSMO_ASSERT(pc == pc_reenc); +} + +static void test_pc_defaults(void) +{ + /* ensure the default point code format settings apply */ + OSMO_ASSERT(s7i->cfg.pc_fmt.component_len[0] == 3); + OSMO_ASSERT(s7i->cfg.pc_fmt.component_len[1] == 8); + OSMO_ASSERT(s7i->cfg.pc_fmt.component_len[2] == 3); + OSMO_ASSERT(s7i->cfg.pc_fmt.delimiter = '.'); +} + +static void parse_print_mask(const char *in) +{ + uint32_t mask = osmo_ss7_pointcode_parse_mask_or_len(s7i, in); + const char *pc_str = osmo_ss7_pointcode_print(s7i, mask); + printf("mask %s => %u (0x%x) %s\n", in, mask, mask, pc_str); +} + +static void test_pc_parser_itu(void) +{ + /* ITU Style */ + printf("Testing ITU-style point code format\n"); + osmo_ss7_instance_set_pc_fmt(s7i, 3, 8, 3); + test_pc_transcode(0); + test_pc_transcode(1); + test_pc_transcode(1 << 3); + test_pc_transcode(1 << (3+8)); + test_pc_transcode(7 << (3+8)); + test_pc_transcode(100); + test_pc_transcode(2342); + test_pc_transcode((1 << 14)-1); + + parse_print_mask("/1"); + parse_print_mask("7.0.0"); + parse_print_mask("/14"); +} + +static void test_pc_parser_ansi(void) +{ + /* ANSI Style */ + printf("Testing ANSI-style point code format\n"); + osmo_ss7_instance_set_pc_fmt(s7i, 8, 8, 8); + s7i->cfg.pc_fmt.delimiter = '-'; + test_pc_transcode(0); + test_pc_transcode(1); + test_pc_transcode(1 << 8); + test_pc_transcode(1 << 16); + test_pc_transcode(1 << (3+8)); + test_pc_transcode((1 << 24)-1); + test_pc_transcode(100); + test_pc_transcode(2342); + + parse_print_mask("/1"); + parse_print_mask("/16"); + parse_print_mask("/24"); + + /* re-set to default (ITU) */ + osmo_ss7_instance_set_pc_fmt(s7i, 3, 8, 3); + s7i->cfg.pc_fmt.delimiter = '.'; +} + +static int test_user_prim_cb(struct osmo_prim_hdr *oph, void *priv) +{ + OSMO_ASSERT(priv == (void *) 0x1234); + + return 23; +} + +static void test_user(void) +{ + struct osmo_ss7_user user, user2; + struct osmo_mtp_prim omp = { + .oph = { + .sap = MTP_SAP_USER, + .primitive = OSMO_MTP_PRIM_TRANSFER, + .operation = PRIM_OP_INDICATION, + }, + .u.transfer = { + .sio = 1, + }, + }; + + printf("Testing SS7 user\n"); + + user.name = "testuser"; + user.priv = (void *) 0x1234; + user.prim_cb = test_user_prim_cb; + + /* registration */ + OSMO_ASSERT(osmo_ss7_user_register(s7i, 1, &user) == 0); + OSMO_ASSERT(osmo_ss7_user_register(s7i, 1, NULL) == -EBUSY); + OSMO_ASSERT(osmo_ss7_user_register(s7i, 255, NULL) == -EINVAL); + + /* primitive delivery */ + OSMO_ASSERT(osmo_ss7_mtp_to_user(s7i, &omp) == 23); + + /* cleanup */ + OSMO_ASSERT(osmo_ss7_user_unregister(s7i, 255, NULL) == -EINVAL); + OSMO_ASSERT(osmo_ss7_user_unregister(s7i, 10, NULL) == -ENODEV); + OSMO_ASSERT(osmo_ss7_user_unregister(s7i, 1, &user2) == -EINVAL); + OSMO_ASSERT(osmo_ss7_user_unregister(s7i, 1, &user) == 0); + + /* primitive delivery should fail now */ + OSMO_ASSERT(osmo_ss7_mtp_to_user(s7i, &omp) == -ENODEV); + + /* wrong primitive delivery should also fail */ + omp.oph.primitive = OSMO_MTP_PRIM_PAUSE; + OSMO_ASSERT(osmo_ss7_mtp_to_user(s7i, &omp) == -EINVAL); +} + +static void test_route(void) +{ + struct osmo_ss7_route_table *rtbl; + struct osmo_ss7_linkset *lset_a, *lset_b; + struct osmo_ss7_route *rt, *rt12, *rtdef; + + printf("Testing SS7 routing\n"); + + /* creation / destruction */ + OSMO_ASSERT(osmo_ss7_route_table_find(s7i, "foobar") == NULL); + rtbl = osmo_ss7_route_table_find_or_create(s7i, "foobar"); + OSMO_ASSERT(rtbl); + OSMO_ASSERT(osmo_ss7_route_table_find_or_create(s7i, "foobar") == rtbl); + osmo_ss7_route_table_destroy(rtbl); + OSMO_ASSERT(osmo_ss7_route_table_find(s7i, "foobar") == NULL); + + /* we now work with system route table */ + rtbl = osmo_ss7_route_table_find(s7i, "system"); + OSMO_ASSERT(rtbl && rtbl == s7i->rtable_system); + + lset_a = osmo_ss7_linkset_find_or_create(s7i, "a", 100); + OSMO_ASSERT(lset_a); + lset_b = osmo_ss7_linkset_find_or_create(s7i, "b", 200); + OSMO_ASSERT(lset_b); + + /* route with full mask */ + OSMO_ASSERT(osmo_ss7_route_find_dpc(rtbl, 12) == NULL); + rt = osmo_ss7_route_create(rtbl, 12, 0xffff, "a"); + OSMO_ASSERT(rt); + OSMO_ASSERT(osmo_ss7_route_find_dpc(rtbl, 12) == rt); + osmo_ss7_route_destroy(rt); + + /* route with partial mask */ + rt = osmo_ss7_route_create(rtbl, 8, 0xfff8, "a"); + OSMO_ASSERT(osmo_ss7_route_find_dpc(rtbl, 8) == rt); + OSMO_ASSERT(osmo_ss7_route_find_dpc(rtbl, 9) == rt); + OSMO_ASSERT(osmo_ss7_route_find_dpc(rtbl, 12) == rt); + OSMO_ASSERT(osmo_ss7_route_find_dpc(rtbl, 15) == rt); + OSMO_ASSERT(osmo_ss7_route_find_dpc(rtbl, 16) == NULL); + /* insert more specific route for 12, must have higher priority + * than existing one */ + rt12 = osmo_ss7_route_create(rtbl, 12, 0xffff, "b"); + OSMO_ASSERT(osmo_ss7_route_find_dpc(rtbl, 12) == rt12); + OSMO_ASSERT(osmo_ss7_route_find_dpc(rtbl, 15) == rt); + OSMO_ASSERT(osmo_ss7_route_find_dpc(rtbl, 16) == NULL); + /* add a default route, which should have lowest precedence */ + rtdef = osmo_ss7_route_create(rtbl, 0, 0, "a"); + OSMO_ASSERT(osmo_ss7_route_find_dpc(rtbl, 12) == rt12); + OSMO_ASSERT(osmo_ss7_route_find_dpc(rtbl, 15) == rt); + OSMO_ASSERT(osmo_ss7_route_find_dpc(rtbl, 16) == rtdef); + + osmo_ss7_route_destroy(rtdef); + osmo_ss7_route_destroy(rt12); + osmo_ss7_route_destroy(rt); + + osmo_ss7_linkset_destroy(lset_a); + osmo_ss7_linkset_destroy(lset_b); +} + +static void test_linkset(void) +{ + struct osmo_ss7_linkset *lset_a, *lset_b; + struct osmo_ss7_link *l_a1, *l_a2; + + printf("Testing SS7 linkset/link\n"); + + OSMO_ASSERT(osmo_ss7_linkset_find_by_name(s7i, "a") == NULL); + OSMO_ASSERT(osmo_ss7_linkset_find_by_name(s7i, "b") == NULL); + + lset_a = osmo_ss7_linkset_find_or_create(s7i, "a", 100); + OSMO_ASSERT(lset_a); + OSMO_ASSERT(osmo_ss7_linkset_find_by_name(s7i, "a") == lset_a); + + lset_b = osmo_ss7_linkset_find_or_create(s7i, "b", 200); + OSMO_ASSERT(lset_b); + OSMO_ASSERT(osmo_ss7_linkset_find_by_name(s7i, "b") == lset_b); + + l_a1 = osmo_ss7_link_find_or_create(lset_a, 1); + OSMO_ASSERT(l_a1); + l_a2 = osmo_ss7_link_find_or_create(lset_a, 2); + OSMO_ASSERT(l_a2); + + /* ID too high */ + OSMO_ASSERT(osmo_ss7_link_find_or_create(lset_a, 1000) == NULL); + /* already exists */ + OSMO_ASSERT(osmo_ss7_link_find_or_create(lset_a, 1) == l_a1); + + osmo_ss7_link_destroy(l_a1); + osmo_ss7_link_destroy(l_a2); + + osmo_ss7_linkset_destroy(lset_a); + osmo_ss7_linkset_destroy(lset_b); +} + +static void test_as(void) +{ + struct osmo_ss7_as *as; + struct osmo_ss7_asp *asp; + + OSMO_ASSERT(osmo_ss7_as_find_by_name(s7i, "as1") == NULL); + as = osmo_ss7_as_find_or_create(s7i, "as1", OSMO_SS7_ASP_PROT_M3UA); + OSMO_ASSERT(osmo_ss7_as_find_by_name(s7i, "as1") == as); + OSMO_ASSERT(osmo_ss7_as_find_by_rctx(s7i, 2342) == NULL); + as->cfg.routing_key.context = 2342; + OSMO_ASSERT(osmo_ss7_as_find_by_rctx(s7i, 2342) == as); + OSMO_ASSERT(osmo_ss7_as_add_asp(as, "asp1") == -ENODEV); + + asp = osmo_ss7_asp_find_or_create(s7i, "asp1", 0, M3UA_PORT, OSMO_SS7_ASP_PROT_M3UA); + OSMO_ASSERT(asp); + + OSMO_ASSERT(osmo_ss7_as_has_asp(as, asp) == false); + OSMO_ASSERT(osmo_ss7_as_add_asp(as, "asp1") == 0); + + osmo_ss7_asp_restart(asp); + + /* ask FSM to send ASP-UP.req */ + osmo_fsm_inst_dispatch(asp->fi, XUA_ASP_E_M_ASP_UP_REQ, NULL); + osmo_fsm_inst_dispatch(asp->fi, XUA_ASP_E_ASPSM_ASPUP_ACK, NULL); + osmo_fsm_inst_dispatch(asp->fi, XUA_ASP_E_ASPTM_ASPAC_ACK, NULL); + + OSMO_ASSERT(osmo_ss7_as_del_asp(as, "asp1") == 0); + OSMO_ASSERT(osmo_ss7_as_del_asp(as, "asp2") == -ENODEV); + OSMO_ASSERT(osmo_ss7_as_del_asp(as, "asp1") == -EINVAL); + + osmo_ss7_asp_destroy(asp); + osmo_ss7_as_destroy(as); + OSMO_ASSERT(osmo_ss7_as_find_by_name(s7i, "as1") == NULL); +} + +/*********************************************************************** + * Initialization + ***********************************************************************/ + +static const struct log_info_cat log_info_cat[] = { +}; + +static const struct log_info log_info = { + .cat = log_info_cat, + .num_cat = ARRAY_SIZE(log_info_cat), +}; + +static void init_logging(void) +{ + const int log_cats[] = { DLSS7, DLSUA, DLM3UA, DLSCCP, DLINP }; + unsigned int i; + + osmo_init_logging(&log_info); + + log_set_print_filename(osmo_stderr_target, 0); + + for (i = 0; i < ARRAY_SIZE(log_cats); i++) + log_set_category_filter(osmo_stderr_target, log_cats[i], 1, LOGL_DEBUG); +} + +int main(int argc, char **argv) +{ + init_logging(); + osmo_fsm_log_addr(false); + + /* init */ + osmo_ss7_init(); + s7i = osmo_ss7_instance_find_or_create(NULL, 0); + OSMO_ASSERT(osmo_ss7_instance_find(0) == s7i); + OSMO_ASSERT(osmo_ss7_instance_find(23) == NULL); + + /* test osmo_ss7_pc_is_local() */ + s7i->cfg.primary_pc = 55; + OSMO_ASSERT(osmo_ss7_pc_is_local(s7i, 55) == true); + OSMO_ASSERT(osmo_ss7_pc_is_local(s7i, 23) == false); + + /* further tests */ + test_pc_defaults(); + test_pc_parser_itu(); + test_pc_parser_ansi(); + test_user(); + test_route(); + test_linkset(); + test_as(); + + /* destroy */ + osmo_ss7_instance_destroy(s7i); + OSMO_ASSERT(osmo_ss7_instance_find(0) == NULL); + + exit(0); +} diff --git a/tests/ss7/ss7_test.err b/tests/ss7/ss7_test.err new file mode 100644 index 0000000..8823d1c --- /dev/null +++ b/tests/ss7/ss7_test.err @@ -0,0 +1,49 @@ +0: Creating SS7 Instance +0: Creating Route Table system +0: Point Code Format 8-8-8 is longer than 14 bits, odd? +registering user=testuser for SI 1 with priv 0x1234 +delivering MTP-TRANSFER.ind to user testuser, priv=0x1234 +No MTP-User for SI 1 +Unsupported Primitive +0: Creating Route Table foobar +0: Creating Linkset a +0: Creating Linkset b +0: Destroying Linkset a +0: Destroying Linkset b +0: Creating Linkset a +0: Creating Linkset b +0: Creating Link a:1 +0: Creating Link a:2 +0: Destroying Link a:1 +0: Destroying Link a:2 +0: Destroying Linkset a +0: Destroying Linkset b +0: Creating AS as1 +XUA_AS(as1){AS_DOWN}: Allocated +0: Adding ASP asp1 to AS as1 +0: Restarting ASP asp1 +unable to connect/bind socket: (null):0: Connection refused +connection closed +retrying in 5 seconds... +0: Unable to open stream client for ASP asp1 +XUA_ASP(asp1){ASP_DOWN}: Allocated +XUA_ASP(asp1){ASP_DOWN}: Received Event M-ASP_UP.req +XUA_ASP(asp1){ASP_DOWN}: Received Event ASPSM-ASP_UP_ACK +XUA_ASP(asp1){ASP_DOWN}: T(ack) stopped +XUA_ASP(asp1){ASP_DOWN}: state_chg to ASP_INACTIVE +XUA_ASP(asp1){ASP_INACTIVE}: Received Event M-ASP_ACTIVE.req +XUA_ASP(asp1){ASP_INACTIVE}: Received Event ASPTM-ASP_AC_ACK +XUA_ASP(asp1){ASP_INACTIVE}: T(ack) stopped +XUA_ASP(asp1){ASP_INACTIVE}: state_chg to ASP_ACTIVE +0: Removing ASP asp1 from AS as1 +0: Removing ASP asp1 from AS as1 +0: Destroying ASP asp1 +XUA_ASP(asp1){ASP_ACTIVE}: Terminating (cause = OSMO_FSM_TERM_REQUEST) +XUA_ASP(asp1){ASP_ACTIVE}: Freeing instance +XUA_ASP(asp1){ASP_ACTIVE}: Deallocated +0: Destroying AS as1 +XUA_AS(as1){AS_DOWN}: Terminating (cause = OSMO_FSM_TERM_REQUEST) +XUA_AS(as1){AS_DOWN}: Freeing instance +XUA_AS(as1){AS_DOWN}: Deallocated +0: Destroying SS7 Instance + \ No newline at end of file diff --git a/tests/ss7/ss7_test.ok b/tests/ss7/ss7_test.ok new file mode 100644 index 0000000..8aea63d --- /dev/null +++ b/tests/ss7/ss7_test.ok @@ -0,0 +1,27 @@ +Testing ITU-style point code format +test_pc_transcode(0) -> 0.0.0 -> 0 +test_pc_transcode(1) -> 0.0.1 -> 1 +test_pc_transcode(8) -> 0.1.0 -> 8 +test_pc_transcode(2048) -> 1.0.0 -> 2048 +test_pc_transcode(14336) -> 7.0.0 -> 14336 +test_pc_transcode(100) -> 0.12.4 -> 100 +test_pc_transcode(2342) -> 1.36.6 -> 2342 +test_pc_transcode(16383) -> 7.255.7 -> 16383 +mask /1 => 8192 (0x2000) 4.0.0 +mask 7.0.0 => 14336 (0x3800) 7.0.0 +mask /14 => 16383 (0x3fff) 7.255.7 +Testing ANSI-style point code format +test_pc_transcode(0) -> 0-0-0 -> 0 +test_pc_transcode(1) -> 0-0-1 -> 1 +test_pc_transcode(256) -> 0-1-0 -> 256 +test_pc_transcode(65536) -> 1-0-0 -> 65536 +test_pc_transcode(2048) -> 0-8-0 -> 2048 +test_pc_transcode(16777215) -> 255-255-255 -> 16777215 +test_pc_transcode(100) -> 0-0-100 -> 100 +test_pc_transcode(2342) -> 0-9-38 -> 2342 +mask /1 => 8388608 (0x800000) 128-0-0 +mask /16 => 16776960 (0xffff00) 255-255-0 +mask /24 => 16777215 (0xffffff) 255-255-255 +Testing SS7 user +Testing SS7 routing +Testing SS7 linkset/link diff --git a/tests/testsuite.at b/tests/testsuite.at index 8907ffa..171f488 100644 --- a/tests/testsuite.at +++ b/tests/testsuite.at @@ -18,3 +18,9 @@ cat $abs_srcdir/sccp/sccp_test.ok > expout AT_CHECK([$abs_top_builddir/tests/sccp/sccp_test], [], [expout], [ignore]) AT_CLEANUP + +AT_SETUP([ss7]) +AT_KEYWORDS([ss7]) +cat $abs_srcdir/ss7/ss7_test.ok > expout +AT_CHECK([$abs_top_builddir/tests/ss7/ss7_test], [], [expout], [ignore]) +AT_CLEANUP -- To view, visit https://gerrit.osmocom.org/2209 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I375eb80f01acc013094851d91d1d3333ebc12bc7 Gerrit-PatchSet: 4 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Apr 10 09:27:27 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 09:27:27 +0000 Subject: [MERGED] libosmo-sccp[master]: License headers: Should always have been GPLv2-or-later In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: License headers: Should always have been GPLv2-or-later ...................................................................... License headers: Should always have been GPLv2-or-later libosmo-sigtran is GPLv2-or-later, there were some files that accidentially had an AGPLv3 license header, which was a copy+paste mistake at that time. Change-Id: I67dfd0ae6157afafd3873a3baaa4c6107c04ddfd --- M debian/copyright M include/osmocom/sigtran/protocol/sua.h M include/osmocom/sigtran/sccp_sap.h M include/osmocom/sigtran/xua_msg.h M src/sccp_helpers.c M src/sua.c M src/xua_msg.c 7 files changed, 25 insertions(+), 27 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/debian/copyright b/debian/copyright index 78c9f12..436675c 100644 --- a/debian/copyright +++ b/debian/copyright @@ -8,9 +8,7 @@ 2010 Harald Welte License: GPL-2+ -Files: include/sigtran/xua_msg.h - src/xua_msg.c - tests/m2ua/m2ua_test.c +Files: tests/m2ua/m2ua_test.c Copyright: 2011 Holger Hans Peter Freyther License: AGPL-3+ diff --git a/include/osmocom/sigtran/protocol/sua.h b/include/osmocom/sigtran/protocol/sua.h index de67041..70c16ba 100644 --- a/include/osmocom/sigtran/protocol/sua.h +++ b/include/osmocom/sigtran/protocol/sua.h @@ -5,8 +5,8 @@ * All Rights Reserved * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation; either version 3 of the + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, @@ -14,7 +14,7 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU Affero General Public License + * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ diff --git a/include/osmocom/sigtran/sccp_sap.h b/include/osmocom/sigtran/sccp_sap.h index 139567e..0cc1531 100644 --- a/include/osmocom/sigtran/sccp_sap.h +++ b/include/osmocom/sigtran/sccp_sap.h @@ -2,20 +2,20 @@ /* SCCP User SAP description */ -/* (C) 2015 by Harald Welte +/* (C) 2015-2017 by Harald Welte * All Rights Reserved * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation; either version 3 of the License, or + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. + * GNU General Public License for more details. * - * You should have received a copy of the GNU Affero General Public License + * You should have received a copy of the GNU General Public License * along with this program. If not, see . * */ diff --git a/include/osmocom/sigtran/xua_msg.h b/include/osmocom/sigtran/xua_msg.h index 33eb1b0..60dd693 100644 --- a/include/osmocom/sigtran/xua_msg.h +++ b/include/osmocom/sigtran/xua_msg.h @@ -2,16 +2,16 @@ /* (C) 2011 by Holger Hans Peter Freyther * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation; either version 3 of the License, or + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. + * GNU General Public License for more details. * - * You should have received a copy of the GNU Affero General Public License + * You should have received a copy of the GNU General Public License * along with this program. If not, see . * */ diff --git a/src/sccp_helpers.c b/src/sccp_helpers.c index 1fc257c..6264424 100644 --- a/src/sccp_helpers.c +++ b/src/sccp_helpers.c @@ -5,16 +5,16 @@ * All Rights Reserved * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation; either version 3 of the License, or + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. + * GNU General Public License for more details. * - * You should have received a copy of the GNU Affero General Public License + * You should have received a copy of the GNU General Public License * along with this program. If not, see . * */ diff --git a/src/sua.c b/src/sua.c index cdc2cf0..145bf1a 100644 --- a/src/sua.c +++ b/src/sua.c @@ -4,16 +4,16 @@ * All Rights Reserved * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation; either version 3 of the License, or + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. + * GNU General Public License for more details. * - * You should have received a copy of the GNU Affero General Public License + * You should have received a copy of the GNU General Public License * along with this program. If not, see . * */ diff --git a/src/xua_msg.c b/src/xua_msg.c index a7f2e52..e094cb6 100644 --- a/src/xua_msg.c +++ b/src/xua_msg.c @@ -3,16 +3,16 @@ * (C) 2016-2017 by Harald Welte * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation; either version 3 of the License, or + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. + * GNU General Public License for more details. * - * You should have received a copy of the GNU Affero General Public License + * You should have received a copy of the GNU General Public License * along with this program. If not, see . * */ -- To view, visit https://gerrit.osmocom.org/2205 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I67dfd0ae6157afafd3873a3baaa4c6107c04ddfd Gerrit-PatchSet: 4 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Apr 10 09:27:28 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 09:27:28 +0000 Subject: [MERGED] libosmo-sccp[master]: xua_msg: Add MTP routing label to 'struct xua_msg' In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: xua_msg: Add MTP routing label to 'struct xua_msg' ...................................................................... xua_msg: Add MTP routing label to 'struct xua_msg' Higher-layer protocols (particularly SCCP) require knowledge on the MTP-level routing label of a message. Let's add this to the common header of 'struct xua_msg' to communicate it across layer boundaries. Change-Id: I31a6388ac999e02ad779619adb54bbf4040672c9 --- M include/osmocom/sigtran/xua_msg.h 1 file changed, 2 insertions(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/include/osmocom/sigtran/xua_msg.h b/include/osmocom/sigtran/xua_msg.h index 18b9e49..33eb1b0 100644 --- a/include/osmocom/sigtran/xua_msg.h +++ b/include/osmocom/sigtran/xua_msg.h @@ -20,6 +20,7 @@ #include "xua_types.h" #include +#include #define XUA_HDR(class, type) ((struct xua_common_hdr) { .spare = 0, .msg_class = (class), .msg_type = (type) }) @@ -29,6 +30,7 @@ struct xua_msg { struct xua_common_hdr hdr; + struct osmo_mtp_transfer_param mtp; struct llist_head headers; }; -- To view, visit https://gerrit.osmocom.org/2204 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I31a6388ac999e02ad779619adb54bbf4040672c9 Gerrit-PatchSet: 4 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Apr 10 09:27:28 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 09:27:28 +0000 Subject: [MERGED] libosmo-sccp[master]: Add mtp_sap.h file with definitions for MTP-USER SAP In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: Add mtp_sap.h file with definitions for MTP-USER SAP ...................................................................... Add mtp_sap.h file with definitions for MTP-USER SAP The ITU-T Q.70x series describe a MTP-USER SAP, which we define here for use with osmocom primitives. Change-Id: Id1f8892e5dee877e2ffbeb3925753ab3da5a9420 --- M include/osmocom/sigtran/Makefile.am A include/osmocom/sigtran/mtp_sap.h 2 files changed, 69 insertions(+), 1 deletion(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/include/osmocom/sigtran/Makefile.am b/include/osmocom/sigtran/Makefile.am index ca7de0f..2f2912f 100644 --- a/include/osmocom/sigtran/Makefile.am +++ b/include/osmocom/sigtran/Makefile.am @@ -1,5 +1,5 @@ sigtran_HEADERS = xua_types.h xua_msg.h m2ua_types.h sccp_sap.h \ - sua.h sigtran_sap.h sccp_helpers.h + sua.h sigtran_sap.h sccp_helpers.h mtp_sap.h sigtrandir = $(includedir)/osmocom/sigtran diff --git a/include/osmocom/sigtran/mtp_sap.h b/include/osmocom/sigtran/mtp_sap.h new file mode 100644 index 0000000..120ae91 --- /dev/null +++ b/include/osmocom/sigtran/mtp_sap.h @@ -0,0 +1,68 @@ +#pragma once + +/* MTP User SAP description in accordance with ITU Q.701 */ + +/* (C) 2017 by Harald Welte + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include +#include +#include + +enum osmo_mtp_prim_type { + OSMO_MTP_PRIM_TRANSFER, + OSMO_MTP_PRIM_PAUSE, + OSMO_MTP_PRIM_RESUME, + OSMO_MTP_PRIM_STATUS, +}; + +#define MTP_SIO(service, net_ind) (((net_ind & 0xF) << 4) | (service & 0xF)) + +struct osmo_mtp_transfer_param { + uint32_t opc; + uint32_t dpc; + uint8_t sls; + uint8_t sio; +}; + +struct osmo_mtp_pause_param { + uint32_t affected_dpc; +}; + +struct osmo_mtp_resume_param { + uint32_t affected_dpc; +}; + +struct osmo_mtp_status_param { + uint32_t affected_dpc; + uint32_t cause; +}; + +struct osmo_mtp_prim { + struct osmo_prim_hdr oph; + union { + struct osmo_mtp_transfer_param transfer; + struct osmo_mtp_pause_param pause; + struct osmo_mtp_resume_param resume; + struct osmo_mtp_status_param status; + } u; +}; + +#define msgb_mtp_prim(msg) ((struct osmo_mtp_prim *)(msg)->l1h) + +char *osmo_mtp_prim_name(struct osmo_prim_hdr *oph); -- To view, visit https://gerrit.osmocom.org/2203 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Id1f8892e5dee877e2ffbeb3925753ab3da5a9420 Gerrit-PatchSet: 4 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Apr 10 09:27:28 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 09:27:28 +0000 Subject: [MERGED] libosmo-sccp[master]: xua_msg: Add support for encoding Global Title in osmo_sccp_... In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: xua_msg: Add support for encoding Global Title in osmo_sccp_addr ...................................................................... xua_msg: Add support for encoding Global Title in osmo_sccp_addr Change-Id: I4668fd0fba2e1be1ec37e75eeee85ed476320d14 --- M include/osmocom/sigtran/xua_msg.h M src/xua_msg.c 2 files changed, 64 insertions(+), 3 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/include/osmocom/sigtran/xua_msg.h b/include/osmocom/sigtran/xua_msg.h index 6e98409..18b9e49 100644 --- a/include/osmocom/sigtran/xua_msg.h +++ b/include/osmocom/sigtran/xua_msg.h @@ -25,6 +25,7 @@ struct msgb; struct osmo_sccp_addr; +struct osmo_sccp_gt; struct xua_msg { struct xua_common_hdr hdr; @@ -82,6 +83,7 @@ int xua_msg_add_u32(struct xua_msg *xua, uint16_t iei, uint32_t val); uint32_t xua_msg_part_get_u32(struct xua_msg_part *part); uint32_t xua_msg_get_u32(struct xua_msg *xua, uint16_t iei); +void xua_part_add_gt(struct msgb *msg, const struct osmo_sccp_gt *gt); int xua_msg_add_sccp_addr(struct xua_msg *xua, uint16_t iei, const struct osmo_sccp_addr *addr); const char *xua_class_msg_name(const struct xua_msg_class *xmc, uint16_t msg_type); diff --git a/src/xua_msg.c b/src/xua_msg.c index 1084622..0a31a96 100644 --- a/src/xua_msg.c +++ b/src/xua_msg.c @@ -1,5 +1,6 @@ /* Routines for generating and parsing messages */ /* (C) 2011 by Holger Hans Peter Freyther + * (C) 2016-2017 by Harald Welte * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by @@ -271,19 +272,77 @@ return xua_msg_part_get_u32(part); } +void xua_part_add_gt(struct msgb *msg, const struct osmo_sccp_gt *gt) +{ + uint16_t *len_ptr; + unsigned int num_digits = strlen(gt->digits); + unsigned int num_digit_bytes; + unsigned int i, j; + + /* Tag + Length */ + msgb_put_u16(msg, SUA_IEI_GT); + len_ptr = (uint16_t *) msgb_put(msg, sizeof(uint16_t)); + + /* first dword: padding + GT */ + msgb_put_u32(msg, gt->gti); + + /* second header dword */ + msgb_put_u8(msg, strlen(gt->digits)); + msgb_put_u8(msg, gt->tt); + msgb_put_u8(msg, gt->npi); + msgb_put_u8(msg, gt->nai); + + /* actual digits */ + num_digit_bytes = num_digits / 2; + if (num_digits & 1) + num_digit_bytes++; + for (i = 0, j = 0; i < num_digit_bytes; i++) { + uint8_t byte; + byte = osmo_char2bcd(gt->digits[j++]); + if (j < num_digits) { + byte |= osmo_char2bcd(gt->digits[j++]) << 4; + } + msgb_put_u8(msg, byte); + } + /* pad to 32bit */ + if (num_digit_bytes % 4) + msgb_put(msg, 4 - (num_digit_bytes % 4)); + *len_ptr = htons(msg->tail - (uint8_t *)len_ptr + 2); +} + int xua_msg_add_sccp_addr(struct xua_msg *xua, uint16_t iei, const struct osmo_sccp_addr *addr) { struct msgb *tmp = msgb_alloc(128, "SCCP Address"); + uint16_t addr_ind = 0; int rc; if (!tmp) return -ENOMEM; - msgb_put_u16(tmp, SUA_RI_SSN_PC); /* route on SSN + PC */ - msgb_put_u16(tmp, 7); /* always put all addresses on SCCP side */ + switch (addr->ri) { + case OSMO_SCCP_RI_GT: + msgb_put_u16(tmp, SUA_RI_GT); + break; + case OSMO_SCCP_RI_SSN_PC: + msgb_put_u16(tmp, SUA_RI_SSN_PC); + break; + case OSMO_SCCP_RI_SSN_IP: + msgb_put_u16(tmp, SUA_RI_SSN_IP); + break; + default: + return -EINVAL; + } + if (addr->presence & OSMO_SCCP_ADDR_T_SSN) + addr_ind |= 0x0001; + if (addr->presence & OSMO_SCCP_ADDR_T_PC) + addr_ind |= 0x0002; + if (addr->presence & OSMO_SCCP_ADDR_T_GT) + addr_ind |= 0x0004; + + msgb_put_u16(tmp, addr_ind); if (addr->presence & OSMO_SCCP_ADDR_T_GT) { - /* FIXME */ + xua_part_add_gt(tmp, &addr->gt); } if (addr->presence & OSMO_SCCP_ADDR_T_PC) { msgb_t16l16vp_put_u32(tmp, SUA_IEI_PC, addr->pc); -- To view, visit https://gerrit.osmocom.org/2201 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I4668fd0fba2e1be1ec37e75eeee85ed476320d14 Gerrit-PatchSet: 4 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Apr 10 09:27:28 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 09:27:28 +0000 Subject: [MERGED] libosmo-sccp[master]: xua_msg: Add support for encoding IPv4 addr in osmo_sccp_addr In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: xua_msg: Add support for encoding IPv4 addr in osmo_sccp_addr ...................................................................... xua_msg: Add support for encoding IPv4 addr in osmo_sccp_addr Change-Id: I956f069ce4cea78cb0db0470265ca8365093c0e5 --- M src/xua_msg.c 1 file changed, 1 insertion(+), 1 deletion(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/xua_msg.c b/src/xua_msg.c index 0a31a96..a7f2e52 100644 --- a/src/xua_msg.c +++ b/src/xua_msg.c @@ -351,7 +351,7 @@ msgb_t16l16vp_put_u32(tmp, SUA_IEI_SSN, addr->ssn); } if (addr->presence & OSMO_SCCP_ADDR_T_IPv4) { - /* FIXME: IPv4 address */ + msgb_t16l16vp_put_u32(tmp, SUA_IEI_IPv4, ntohl(addr->ip.v4.s_addr)); } else if (addr->presence & OSMO_SCCP_ADDR_T_IPv6) { /* FIXME: IPv6 address */ } -- To view, visit https://gerrit.osmocom.org/2202 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I956f069ce4cea78cb0db0470265ca8365093c0e5 Gerrit-PatchSet: 4 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Apr 10 09:51:59 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 09:51:59 +0000 Subject: [PATCH] libosmo-sccp[master]: sua: Extend address parsing with GT, RI and IPv4 support In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2211 to look at the new patch set (#6). sua: Extend address parsing with GT, RI and IPv4 support Change-Id: I186df77cbdbedfe1a60b855be3626b6766f4681c --- M src/sua.c 1 file changed, 104 insertions(+), 26 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/11/2211/6 diff --git a/src/sua.c b/src/sua.c index 659104c..0be5467 100644 --- a/src/sua.c +++ b/src/sua.c @@ -692,11 +692,51 @@ * Receiving SUA messsages from SCTP ***********************************************************************/ -static int sua_parse_addr(struct osmo_sccp_addr *out, - struct xua_msg *xua, - uint16_t iei) +/*! \brief Decode SUA Global Title according to RFC3868 Section 3.10.2.3 + * \param[out] gt User-allocated structure for decoded output + * \param[in] data binary-encoded data + * \param[in] datalen length of \ref data in octets + */ +int sua_parse_gt(struct osmo_sccp_gt *gt, const uint8_t *data, unsigned int datalen) { - const struct xua_msg_part *param = xua_msg_find_tag(xua, iei); + uint8_t num_digits; + char *out_digits; + unsigned int i; + + /* 8 byte header at minimum, plus digits */ + if (datalen < 8) + return -EINVAL; + + /* parse header */ + gt->gti = data[3]; + num_digits = data[4]; + gt->tt = data[5]; + gt->npi = data[6]; + gt->nai = data[7]; + + /* parse digits */ + out_digits = gt->digits; + for (i = 0; i < datalen-8; i++) { + uint8_t byte = data[8+i]; + *out_digits++ = osmo_bcd2char(byte & 0x0F); + if (out_digits - gt->digits >= num_digits) + break; + *out_digits++ = osmo_bcd2char(byte >> 4); + if (out_digits - gt->digits >= num_digits) + break; + } + *out_digits++ = '\0'; + + return 0; +} + +/*! \brief parse SCCP address from given xUA message part + * \param[out] out caller-allocated decoded SCCP address struct + * \param[in] param xUA message part containing address + \returns 0 on success; negative on error */ +int sua_addr_parse_part(struct osmo_sccp_addr *out, + const struct xua_msg_part *param) +{ const struct xua_parameter_hdr *par; uint16_t ri; uint16_t ai; @@ -704,16 +744,15 @@ uint16_t par_tag, par_len, par_datalen; uint32_t *p32; - if (!param) - return -ENODEV; + memset(out, 0, sizeof(*out)); - LOGP(DSUA, LOGL_DEBUG, "sua_parse_addr(IEI=%d) (%d) %s\n", - iei, param->len, + LOGP(DSUA, LOGL_DEBUG, "%s(IEI=0x%04x) (%d) %s\n", __func__, + param->tag, param->len, osmo_hexdump(param->dat, param->len)); if (param->len < 4) { - LOGP(DSUA, LOGL_ERROR, "SUA IEI %d: invalid address length: %d\n", - iei, param->len); + LOGP(DSUA, LOGL_ERROR, "SUA IEI 0x%04x: invalid address length: %d\n", + param->tag, param->len); return -EINVAL; } @@ -723,16 +762,29 @@ ai = ntohs(*(uint16_t*) ¶m->dat[pos]); pos += 2; - if (ri != SUA_RI_SSN_PC) { - LOGP(DSUA, LOGL_ERROR, "SUA IEI %d: Routing Indicator not supported yet: %d\n", - iei, ri); + switch (ri) { + case SUA_RI_GT: + out->ri = OSMO_SCCP_RI_GT; + break; + case SUA_RI_SSN_PC: + out->ri = OSMO_SCCP_RI_SSN_PC; + break; + case SUA_RI_SSN_IP: + out->ri = OSMO_SCCP_RI_SSN_IP; + break; + case SUA_RI_HOST: + default: + LOGP(DSUA, LOGL_ERROR, "SUA IEI 0x%04x: Routing Indicator not supported yet: %d\n", + param->tag, ri); return -ENOTSUP; } if (ai != 7) { - LOGP(DSUA, LOGL_ERROR, "SUA IEI %d: Address Indicator not supported yet: %x\n", - iei, ai); +#if 0 + LOGP(DSUA, LOGL_ERROR, "SUA IEI 0x%04x: Address Indicator not supported yet: %x\n", + param->tag, ai); return -ENOTSUP; +#endif } /* @@ -749,8 +801,8 @@ par_len = ntohs(par->len); par_datalen = par_len - sizeof(*par); - LOGP(DSUA, LOGL_DEBUG, "SUA IEI %hu pos %hu/%hu: subpart tag %hu, len %hu\n", - iei, pos, param->len, par->tag, par->len); + LOGP(DSUA, LOGL_DEBUG, "SUA IEI 0x%04x pos %hu/%hu: subpart tag 0x%04x, len %hu\n", + param->tag, pos, param->len, par_tag, par_len); switch (par_tag) { case SUA_IEI_PC: @@ -768,12 +820,22 @@ out->presence |= OSMO_SCCP_ADDR_T_SSN; break; case SUA_IEI_GT: - /* TODO */ + if (par_datalen < 8) + goto subpar_fail; + sua_parse_gt(&out->gt, par->data, par_datalen); out->presence |= OSMO_SCCP_ADDR_T_GT; break; + case SUA_IEI_IPv4: + if (par_datalen != 4) + goto subpar_fail; + p32 = (uint32_t*)par->data; + /* no endian conversion, both network order */ + out->ip.v4.s_addr = *p32; + out->presence |= OSMO_SCCP_ADDR_T_IPv4; + break; default: - LOGP(DSUA, LOGL_ERROR, "SUA IEI %d: Unknown subpart tag %hd\n", - iei, par_tag); + LOGP(DSUA, LOGL_ERROR, "SUA IEI 0x%04x: Unknown subpart tag %hd\n", + param->tag, par_tag); goto subpar_fail; } @@ -783,9 +845,25 @@ return 0; subpar_fail: - LOGP(DSUA, LOGL_ERROR, "Failed to parse subparts of address IEI=%d\n", - iei); + LOGP(DSUA, LOGL_ERROR, "Failed to parse subparts of address IEI=0x%04x\n", + param->tag); return -EINVAL; +} + +/*! \brief parse SCCP address from given xUA message IE + * \param[out] out caller-allocated decoded SCCP address struct + * \param[in] xua xUA message + * \param[in] iei Information Element Identifier inside \ref xua + \returns 0 on success; negative on error */ +int sua_addr_parse(struct osmo_sccp_addr *out, struct xua_msg *xua, uint16_t iei) +{ + const struct xua_msg_part *param = xua_msg_find_tag(xua, iei); + if (!param) { + memset(out, 0, sizeof(*out)); + return -ENODEV; + } + + return sua_addr_parse_part(out, param); } static int sua_rx_cldt(struct osmo_sccp_link *link, struct xua_msg *xua) @@ -802,8 +880,8 @@ osmo_prim_init(&prim->oph, SCCP_SAP_USER, OSMO_SCU_PRIM_N_UNITDATA, PRIM_OP_INDICATION, upmsg); - sua_parse_addr(¶m->called_addr, xua, SUA_IEI_DEST_ADDR); - sua_parse_addr(¶m->calling_addr, xua, SUA_IEI_SRC_ADDR); + sua_addr_parse(¶m->called_addr, xua, SUA_IEI_DEST_ADDR); + sua_addr_parse(¶m->calling_addr, xua, SUA_IEI_SRC_ADDR); param->in_sequence_control = xua_msg_get_u32(xua, SUA_IEI_SEQ_CTRL); protocol_class = xua_msg_get_u32(xua, SUA_IEI_PROTO_CLASS); param->return_option = protocol_class & 0x80; @@ -849,8 +927,8 @@ /* fill conn */ conn = conn_create(link); - sua_parse_addr(&conn->called_addr, xua, SUA_IEI_DEST_ADDR); - sua_parse_addr(&conn->calling_addr, xua, SUA_IEI_SRC_ADDR); + sua_addr_parse(&conn->called_addr, xua, SUA_IEI_DEST_ADDR); + sua_addr_parse(&conn->calling_addr, xua, SUA_IEI_SRC_ADDR); conn->remote_ref = xua_msg_get_u32(xua, SUA_IEI_SRC_REF); /* fill primitive */ -- To view, visit https://gerrit.osmocom.org/2211 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I186df77cbdbedfe1a60b855be3626b6766f4681c Gerrit-PatchSet: 6 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Apr 10 09:51:59 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 09:51:59 +0000 Subject: [PATCH] libosmo-sccp[master]: Add new SCCP implementation In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2215 to look at the new patch set (#7). Add new SCCP implementation This is an implementation of SCCP as specified in ITO-T Q.71x, particularly the SCRC (routing), SCLC (Connectionless) and SCOC (Connection Oriented) portions. the elaborate state machines of SCOC are implemented using osmo_fsm, with one state machine for each connection. Interfaces to the top (user application) are the SCCP-USER-SAP and on the bottom (network) side the MTP-USER-SAP as provided by osmo_ss7. Contrary to a straight-forward implementation, the code internally always uses a SUA representation of all messages (in struct xua_msg). This enables us to have one common implementation of all related state machines and use them for both SUA and SCCP. If used with real SCCP wire format, all messages are translated from SCCP to SUA on ingress and translated from SUA to SCCP on egress. As SUA is a super-set of SCCP, this can be done "lossless". Change-Id: I916e895d9a4914b05483fe12ab5251f206d10dee --- M include/osmocom/sigtran/sccp_sap.h M src/Makefile.am M src/osmo_ss7.c M src/sccp_internal.h A src/sccp_sclc.c A src/sccp_scoc.c A src/sccp_scrc.c A src/sccp_user.c 8 files changed, 2,938 insertions(+), 2 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/15/2215/7 diff --git a/include/osmocom/sigtran/sccp_sap.h b/include/osmocom/sigtran/sccp_sap.h index 0cc1531..c1464f0 100644 --- a/include/osmocom/sigtran/sccp_sap.h +++ b/include/osmocom/sigtran/sccp_sap.h @@ -222,3 +222,23 @@ #define msgb_scu_prim(msg) ((struct osmo_scu_prim *)(msg)->l1h) char *osmo_scu_prim_name(struct osmo_prim_hdr *oph); + +struct osmo_ss7_instance; +struct osmo_sccp_instance; +struct osmo_sccp_user; + +struct osmo_sccp_instance * +osmo_sccp_instance_create(struct osmo_ss7_instance *ss7, void *priv); +void osmo_sccp_instance_destroy(struct osmo_sccp_instance *inst); + +void osmo_sccp_user_unbind(struct osmo_sccp_user *scu); + +struct osmo_sccp_user * +osmo_sccp_user_bind_pc(struct osmo_sccp_instance *inst, const char *name, + osmo_prim_cb prim_cb, uint16_t ssn, uint32_t pc); + +struct osmo_sccp_user * +osmo_sccp_user_bind(struct osmo_sccp_instance *inst, const char *name, + osmo_prim_cb prim_cb, uint16_t ssn); + +int osmo_sccp_user_sap_down(struct osmo_sccp_user *scu, struct osmo_prim_hdr *oph); diff --git a/src/Makefile.am b/src/Makefile.am index 4455127..a4cfeeb 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -27,7 +27,8 @@ LIBVERSION=0:0:0 libosmo_sigtran_la_SOURCES = sccp_sap.c sua.c m3ua.c xua_msg.c sccp_helpers.c \ - sccp2sua.c \ + sccp2sua.c sccp_scrc.c sccp_sclc.c sccp_scoc.c \ + sccp_user.c \ osmo_ss7.c osmo_ss7_hmrt.c xua_asp_fsm.c xua_as_fsm.c libosmo_sigtran_la_LDFLAGS = -version-info $(LIBVERSION) -no-undefined -export-symbols-regex '^osmo_' libosmo_sigtran_la_LIBADD = $(LIBOSMOCORE_LIBS) $(LIBOSMONETIF_LIBS) $(LIBSCTP_LIBS) diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index 74c54bb..6d0b446 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -41,6 +41,7 @@ #include +#include "sccp_internal.h" #include "xua_internal.h" #include "xua_asp_fsm.h" #include "xua_as_fsm.h" @@ -1483,6 +1484,7 @@ { if (ss7_initialized) return 1; + osmo_fsm_register(&sccp_scoc_fsm); osmo_fsm_register(&xua_as_fsm); osmo_fsm_register(&xua_asp_fsm); ss7_initialized = true; diff --git a/src/sccp_internal.h b/src/sccp_internal.h index 7287a82..c35ef4b 100644 --- a/src/sccp_internal.h +++ b/src/sccp_internal.h @@ -1,5 +1,89 @@ #pragma once -#include +#include +#include +#include +#include + +/* an instance of the SCCP stack */ +struct osmo_sccp_instance { + /* entry in global list of ss7 instances */ + struct llist_head list; + /* list of 'struct sccp_connection' in this instance */ + struct llist_head connections; + /* list of SCCP users in this instance */ + struct llist_head users; + /* routing context to be used in all outbound messages */ + uint32_t route_ctx; + /* next local reference to allocate */ + uint32_t next_id; + struct osmo_ss7_instance *ss7; + void *priv; + + struct osmo_ss7_user ss7_user; +}; + +struct osmo_sccp_user { + /*! \brief entry in list of sccp users of \ref osmo_sccp_instance */ + struct llist_head list; + /*! \brief pointer back to SCCP instance */ + struct osmo_sccp_instance *inst; + /*! \brief human-readable name of this user */ + char *name; + + /*! \brief SSN and/or point code to which we are bound */ + uint16_t ssn; + uint32_t pc; + bool pc_valid; + + /* set if we are a server */ + struct llist_head links; + + /* user call-back function in case of incoming primitives */ + osmo_prim_cb prim_cb; + void *priv; + + /* Application Server FSM Instance */ + struct osmo_fsm_inst *as_fi; +}; + +extern int DSCCP; + +struct xua_msg; + +struct osmo_sccp_user * +sccp_user_find(struct osmo_sccp_instance *inst, uint16_t ssn, uint32_t pc); + +/* Message from SCOC -> SCRC */ +int sccp_scrc_rx_scoc_conn_msg(struct osmo_sccp_instance *inst, + struct xua_msg *xua); + +/* Message from SCLC -> SCRC */ +int sccp_scrc_rx_sclc_msg(struct osmo_sccp_instance *inst, struct xua_msg *xua); + +/* Message from MTP (SUA) -> SCRC */ +int scrc_rx_mtp_xfer_ind_xua(struct osmo_sccp_instance *inst, + struct xua_msg *xua); + +/* Message from SCRC -> SCOC */ +void sccp_scoc_rx_from_scrc(struct osmo_sccp_instance *inst, + struct xua_msg *xua); +void sccp_scoc_rx_scrc_rout_fail(struct osmo_sccp_instance *inst, + struct xua_msg *xua, uint32_t cause); + +void sccp_scoc_flush_connections(struct osmo_sccp_instance *inst); + +/* Message from SCRC -> SCLC */ +int sccp_sclc_rx_from_scrc(struct osmo_sccp_instance *inst, + struct xua_msg *xua); +void sccp_sclc_rx_scrc_rout_fail(struct osmo_sccp_instance *inst, + struct xua_msg *xua, uint32_t cause); + +int sccp_user_prim_up(struct osmo_sccp_user *scut, struct osmo_scu_prim *prim); + +/* SCU -> SCLC */ +int sccp_sclc_user_sap_down(struct osmo_sccp_user *scu, struct osmo_prim_hdr *oph); struct msgb *sccp_msgb_alloc(const char *name); + +struct osmo_fsm sccp_scoc_fsm; diff --git a/src/sccp_sclc.c b/src/sccp_sclc.c new file mode 100644 index 0000000..dae2c36 --- /dev/null +++ b/src/sccp_sclc.c @@ -0,0 +1,337 @@ +/* SCCP Connectionless Control (SCLC) according to ITU-T Q.713/Q.714 */ + +/* (C) 2015-2017 by Harald Welte + * All Rights reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/* This code is a bit of a hybrid between the ITU-T Q.71x specifications + * for SCCP (particularly its connection-oriented part), and the IETF + * RFC 3868 (SUA). The idea here is to have one shared code base of the + * state machines for SCCP Connection Oriented, and use those both from + * SCCP and SUA. + * + * To do so, all SCCP messages are translated to SUA messages in the + * input side, and all generated SUA messages are translated to SCCP on + * the output side. + * + * The Choice of going for SUA messages as the "native" format was based + * on their easier parseability, and the fact that there are features in + * SUA which classic SCCP cannot handle (like IP addresses in GT). + * However, all SCCP features can be expressed in SUA. + * + * The code only supports Class 2. No support for Class 3 is intended, + * but patches are of course alwys welcome. + * + * Missing other features: + * * Segmentation/Reassembly support + * * T(guard) after (re)start + * * freezing of local references + * * parsing/encoding of IPv4/IPv6 addresses + * * use of multiple Routing Contexts in SUA case + */ + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "xua_internal.h" +#include "sccp_internal.h" + +/* generate a 'struct xua_msg' of requested type from primitive data */ +static struct xua_msg *xua_gen_msg_cl(uint32_t event, + struct osmo_scu_prim *prim, int msg_type) +{ + struct xua_msg *xua = xua_msg_alloc(); + struct osmo_scu_unitdata_param *udpar = &prim->u.unitdata; + + if (!xua) + return NULL; + + switch (msg_type) { + case SUA_CL_CLDT: + xua->hdr = XUA_HDR(SUA_MSGC_CL, SUA_CL_CLDT); + xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, 0); /* FIXME */ + xua_msg_add_u32(xua, SUA_IEI_PROTO_CLASS, 0); + xua_msg_add_sccp_addr(xua, SUA_IEI_SRC_ADDR, &udpar->calling_addr); + xua_msg_add_sccp_addr(xua, SUA_IEI_DEST_ADDR, &udpar->called_addr); + xua_msg_add_u32(xua, SUA_IEI_SEQ_CTRL, udpar->in_sequence_control); + /* optional: importance, ... correlation id? */ + if (!prim) + goto prim_needed; + xua_msg_add_data(xua, SUA_IEI_DATA, msgb_l2len(prim->oph.msg), + msgb_l2(prim->oph.msg)); + break; + default: + LOGP(DLSCCP, LOGL_ERROR, "Unknown msg_type %u\n", msg_type); + xua_msg_free(xua); + return NULL; + } + return xua; + +prim_needed: + xua_msg_free(xua); + LOGP(DLSCCP, LOGL_ERROR, "%s must be called with valid 'prim' " + "pointer for msg_type=%u\n", __func__, msg_type); + return NULL; +} + +/* generate xua_msg, encode it and send it to SCRC */ +static int xua_gen_encode_and_send(struct osmo_sccp_user *scu, uint32_t event, + struct osmo_scu_prim *prim, int msg_type) +{ + struct xua_msg *xua; + + xua = xua_gen_msg_cl(event, prim, msg_type); + if (!xua) + return -1; + + return sccp_scrc_rx_sclc_msg(scu->inst, xua); +} + +/*! \brief Main entrance function for primitives from SCCP User + * \param[in] scu SCCP User who is sending the primitive + * \param[on] oph Osmocom primitive header of the primitive + * \returns 0 on success; negtive in case of error */ +int sccp_sclc_user_sap_down(struct osmo_sccp_user *scu, struct osmo_prim_hdr *oph) +{ + struct osmo_scu_prim *prim = (struct osmo_scu_prim *) oph; + struct msgb *msg = prim->oph.msg; + int rc = 0; + + /* we get called from osmo_sccp_user_sap_down() which already + * has debug-logged the primitive */ + + switch (OSMO_PRIM_HDR(&prim->oph)) { + case OSMO_PRIM(OSMO_SCU_PRIM_N_UNITDATA, PRIM_OP_REQUEST): + /* Connectionless by-passes this altogether */ + rc = xua_gen_encode_and_send(scu, -1, prim, SUA_CL_CLDT); + goto out; + default: + LOGP(DLSCCP, LOGL_ERROR, "Received unknown SCCP User " + "primitive %s from user\n", + osmo_scu_prim_name(&prim->oph)); + rc = -1; + goto out; + } + +out: + /* the SAP is supposed to consume the primitive/msgb */ + msgb_free(msg); + + return rc; +} + +/* Process an incoming CLDT message (from a remote peer) */ +static int sclc_rx_cldt(struct osmo_sccp_instance *inst, struct xua_msg *xua) +{ + struct osmo_scu_prim *prim; + struct osmo_scu_unitdata_param *param; + struct xua_msg_part *data_ie = xua_msg_find_tag(xua, SUA_IEI_DATA); + struct msgb *upmsg = sccp_msgb_alloc(__func__); + struct osmo_sccp_user *scu; + uint32_t protocol_class; + + /* fill primitive */ + prim = (struct osmo_scu_prim *) msgb_put(upmsg, sizeof(*prim)); + param = &prim->u.unitdata; + osmo_prim_init(&prim->oph, SCCP_SAP_USER, + OSMO_SCU_PRIM_N_UNITDATA, + PRIM_OP_INDICATION, upmsg); + sua_addr_parse(¶m->called_addr, xua, SUA_IEI_DEST_ADDR); + sua_addr_parse(¶m->calling_addr, xua, SUA_IEI_SRC_ADDR); + param->in_sequence_control = xua_msg_get_u32(xua, SUA_IEI_SEQ_CTRL); + protocol_class = xua_msg_get_u32(xua, SUA_IEI_PROTO_CLASS); + param->return_option = protocol_class & 0x80; + param->importance = xua_msg_get_u32(xua, SUA_IEI_IMPORTANCE); + + scu = sccp_user_find(inst, param->called_addr.ssn, + param->called_addr.pc); + + if (!scu) { + /* FIXME: Send destination unreachable? */ + LOGP(DLSUA, LOGL_NOTICE, "Received SUA message for unequipped SSN %u\n", + param->called_addr.ssn); + msgb_free(upmsg); + return 0; + } + + /* copy data */ + upmsg->l2h = msgb_put(upmsg, data_ie->len); + memcpy(upmsg->l2h, data_ie->dat, data_ie->len); + + /* send to user SAP */ + sccp_user_prim_up(scu, prim); + + /* xua_msg is free'd by our caller */ + return 0; +} + +static int sclc_rx_cldr(struct osmo_sccp_instance *inst, struct xua_msg *xua) +{ + struct osmo_scu_prim *prim; + struct osmo_scu_notice_param *param; + struct xua_msg_part *data_ie = xua_msg_find_tag(xua, SUA_IEI_DATA); + struct msgb *upmsg = sccp_msgb_alloc(__func__); + struct osmo_sccp_user *scu; + + /* fill primitive */ + prim = (struct osmo_scu_prim *) msgb_put(upmsg, sizeof(*prim)); + param = &prim->u.notice; + osmo_prim_init(&prim->oph, SCCP_SAP_USER, + OSMO_SCU_PRIM_N_NOTICE, + PRIM_OP_INDICATION, upmsg); + + sua_addr_parse(¶m->called_addr, xua, SUA_IEI_DEST_ADDR); + sua_addr_parse(¶m->calling_addr, xua, SUA_IEI_SRC_ADDR); + param->importance = xua_msg_get_u32(xua, SUA_IEI_IMPORTANCE); + param->cause = xua_msg_get_u32(xua, SUA_IEI_CAUSE); + + scu = sccp_user_find(inst, param->called_addr.ssn, + param->called_addr.pc); + if (!scu) { + /* FIXME: Send destination unreachable? */ + LOGP(DLSUA, LOGL_NOTICE, "Received CLDR for unequipped SSN %u\n", + param->called_addr.ssn); + msgb_free(upmsg); + return 0; + } + + /* copy data */ + upmsg->l2h = msgb_put(upmsg, data_ie->len); + memcpy(upmsg->l2h, data_ie->dat, data_ie->len); + + /* send to user SAP */ + sccp_user_prim_up(scu, prim); + + /* xua_msg is free'd by our caller */ + return 0; +} + +/*! \brief SCRC -> SCLC (connectionless message) + * \param[in] inst SCCP Instance in which we operate + * \param[in] xua SUA connectionless message + * \returns 0 on success; negative on error */ +int sccp_sclc_rx_from_scrc(struct osmo_sccp_instance *inst, + struct xua_msg *xua) +{ + int rc = -1; + + OSMO_ASSERT(xua->hdr.msg_class == SUA_MSGC_CL); + + switch (xua->hdr.msg_type) { + case SUA_CL_CLDT: + rc = sclc_rx_cldt(inst, xua); + break; + case SUA_CL_CLDR: + rc = sclc_rx_cldr(inst, xua); + break; + default: + LOGP(DLSUA, LOGL_NOTICE, "Received unknown/unsupported " + "message %s\n", xua_hdr_dump(xua, &xua_dialect_sua)); + break; + } + + return rc; +} + +/* generate a return/refusal message (SUA CLDR == SCCP UDTS) based on + * the incoming message. We need to flip all identities between sender + * and receiver */ +static struct xua_msg *gen_ret_msg(struct osmo_sccp_instance *inst, + const struct xua_msg *xua_in, + uint32_t ret_cause) +{ + struct xua_msg *xua_out = xua_msg_alloc(); + struct osmo_sccp_addr called; + + xua_out->hdr = XUA_HDR(SUA_MSGC_CL, SUA_CL_CLDR); + xua_msg_add_u32(xua_out, SUA_IEI_ROUTE_CTX, inst->route_ctx); + xua_msg_add_u32(xua_out, SUA_IEI_CAUSE, + SUA_CAUSE_T_RETURN | ret_cause); + /* Swap Calling and Called Party */ + xua_msg_copy_part(xua_out, SUA_IEI_SRC_ADDR, xua_in, SUA_IEI_DEST_ADDR); + xua_msg_copy_part(xua_out, SUA_IEI_DEST_ADDR, xua_in, SUA_IEI_SRC_ADDR); + /* TODO: Optional: Hop Count */ + /* Optional: Importance */ + xua_msg_copy_part(xua_out, SUA_IEI_IMPORTANCE, + xua_in, SUA_IEI_IMPORTANCE); + /* Optional: Message Priority */ + xua_msg_copy_part(xua_out, SUA_IEI_MSG_PRIO, xua_in, SUA_IEI_MSG_PRIO); + /* Optional: Correlation ID */ + xua_msg_copy_part(xua_out, SUA_IEI_CORR_ID, xua_in, SUA_IEI_CORR_ID); + /* Optional: Segmentation */ + xua_msg_copy_part(xua_out, SUA_IEI_SEGMENTATION, + xua_in, SUA_IEI_SEGMENTATION); + /* Optional: Data */ + xua_msg_copy_part(xua_out, SUA_IEI_DATA, xua_in, SUA_IEI_DATA); + + sua_addr_parse(&called, xua_out, SUA_IEI_DEST_ADDR); + /* Route on PC + SSN ? */ + if (called.ri == OSMO_SCCP_RI_SSN_PC) { + /* if no PC, copy OPC into called addr */ + if (!(called.presence & OSMO_SCCP_ADDR_T_PC)) { + struct osmo_sccp_addr calling; + sua_addr_parse(&calling, xua_out, SUA_IEI_SRC_ADDR); + called.presence |= OSMO_SCCP_ADDR_T_PC; + called.pc = calling.pc; + /* Re-encode / replace called address */ + xua_msg_free_tag(xua_out, SUA_IEI_DEST_ADDR); + xua_msg_add_sccp_addr(xua_out, SUA_IEI_DEST_ADDR, + &called); + } + } + return xua_out; +} + +/*! \brief SCRC -> SCLC (Routing Failure + * \param[in] inst SCCP Instance in which we operate + * \param[in] xua_in Message that failed to be routed + * \param[in] cause SCCP Return Cause */ +void sccp_sclc_rx_scrc_rout_fail(struct osmo_sccp_instance *inst, + struct xua_msg *xua_in, uint32_t cause) +{ + struct xua_msg *xua_out; + + /* Figure C.12/Q.714 (Sheet 8) Node 9 */ + switch (xua_in->hdr.msg_type) { + case SUA_CL_CLDT: + xua_out = gen_ret_msg(inst, xua_in, cause); + /* TODO: Message Return Option? */ + if (!osmo_ss7_pc_is_local(inst->ss7, xua_in->mtp.opc)) { + /* non-local originator: send UDTS */ + /* TODO: Assign SLS */ + sccp_scrc_rx_sclc_msg(inst, xua_out); + } else { + /* local originator: send N-NOTICE to user */ + /* TODO: N-NOTICE.ind SCLC -> SCU */ + sclc_rx_cldr(inst, xua_out); + xua_msg_free(xua_out); + } + break; + case SUA_CL_CLDR: + /* do nothing */ + break; + } +} diff --git a/src/sccp_scoc.c b/src/sccp_scoc.c new file mode 100644 index 0000000..f881872 --- /dev/null +++ b/src/sccp_scoc.c @@ -0,0 +1,1642 @@ +/* SCCP Connection Oriented (SCOC) according to ITU-T Q.713/Q.714 */ + +/* (C) 2015-2017 by Harald Welte + * All Rights reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/* This code is a bit of a hybrid between the ITU-T Q.71x specifications + * for SCCP (particularly its connection-oriented part), and the IETF + * RFC 3868 (SUA). The idea here is to have one shared code base of the + * state machines for SCCP Connection Oriented, and use those both from + * SCCP and SUA. + * + * To do so, all SCCP messages are translated to SUA messages in the + * input side, and all generated SUA messages are translated to SCCP on + * the output side. + * + * The Choice of going for SUA messages as the "native" format was based + * on their easier parseability, and the fact that there are features in + * SUA which classic SCCP cannot handle (like IP addresses in GT). + * However, all SCCP features can be expressed in SUA. + * + * The code only supports Class 2. No support for Class 3 is intended, + * but patches are of course alwys welcome. + * + * Missing other features: + * * Segmentation/Reassembly support + * * T(guard) after (re)start + * * freezing of local references + * * parsing/encoding of IPv4/IPv6 addresses + * * use of multiple Routing Contexts in SUA case + */ + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "xua_internal.h" +#include "sccp_internal.h" + +#define S(x) (1 << (x)) +#define SCU_MSGB_SIZE 1024 + +/* Appendix C.4 of Q.714 (all in milliseconds) */ +#define CONNECTION_TIMER ( 1 * 60 * 100) +#define TX_INACT_TIMER ( 7 * 60 * 100) /* RFC 3868 Ch. 8. */ +#define RX_INACT_TIMER (15 * 60 * 100) /* RFC 3868 Ch. 8. */ +#define RELEASE_TIMER ( 10 * 100) +#define RELEASE_REP_TIMER ( 10 * 100) +#define INT_TIMER ( 1 * 60 * 100) +#define GUARD_TIMER (23 * 60 * 100) +#define RESET_TIMER ( 10 * 100) + +/* convert from single value in milliseconds to comma-separated + * "seconds, microseconds" format we use in osmocom/core/timers.h */ +#define MSEC_TO_S_US(x) (x/100), ((x%100)*10) + +/*********************************************************************** + * SCCP connection table + ***********************************************************************/ + +/* a logical connection within the SCCP instance */ +struct sccp_connection { + /* part of osmo_sccp_instance.list */ + struct llist_head list; + /* which instance are we part of? */ + struct osmo_sccp_instance *inst; + /* which user owns us? */ + struct osmo_sccp_user *user; + + /* remote point code */ + uint32_t remote_pc; + + /* local/remote addresses and identiies */ + struct osmo_sccp_addr calling_addr; + struct osmo_sccp_addr called_addr; + uint32_t conn_id; + uint32_t remote_ref; + + uint32_t importance; + uint32_t sccp_class; + uint32_t release_cause; /* WAIT_CONN_CONF */ + + /* Osmo FSM Instance of sccp_scoc_fsm */ + struct osmo_fsm_inst *fi; + + /* Connect timer */ + struct osmo_timer_list t_conn; + + /* inactivity timers */ + struct osmo_timer_list t_ias; + struct osmo_timer_list t_iar; + + /* release timers */ + struct osmo_timer_list t_rel; + struct osmo_timer_list t_int; + struct osmo_timer_list t_rep_rel; +}; + +/*********************************************************************** + * various helper functions + ***********************************************************************/ + +enum sccp_connection_state { + S_IDLE, + S_CONN_PEND_IN, + S_CONN_PEND_OUT, + S_ACTIVE, + S_DISCONN_PEND, + S_RESET_IN, + S_RESET_OUT, + S_BOTHWAY_RESET, + S_WAIT_CONN_CONF, +}; + +/* Events that this FSM can process */ +enum sccp_scoc_event { + /* Primitives from SCCP-User */ + SCOC_E_SCU_N_CONN_REQ, + SCOC_E_SCU_N_CONN_RESP, + SCOC_E_SCU_N_DISC_REQ, + SCOC_E_SCU_N_DATA_REQ, + SCOC_E_SCU_N_EXP_DATA_REQ, + + /* Events from RCOC (Routing for Connection Oriented) */ + SCOC_E_RCOC_CONN_IND, + SCOC_E_RCOC_ROUT_FAIL_IND, + SCOC_E_RCOC_RLSD_IND, + SCOC_E_RCOC_REL_COMPL_IND, + SCOC_E_RCOC_CREF_IND, + SCOC_E_RCOC_CC_IND, + SCOC_E_RCOC_DT1_IND, + SCOC_E_RCOC_DT2_IND, + SCOC_E_RCOC_IT_IND, + SCOC_E_RCOC_OTHER_NPDU, + SCOC_E_RCOC_ERROR_IND, + + /* Timer Events */ + SCOC_E_T_IAR_EXP, + SCOC_E_T_IAS_EXP, + + SCOC_E_CONN_TMR_EXP, + + SCOC_E_T_REL_EXP, + SCOC_E_T_INT_EXP, + SCOC_E_T_REP_REL_EXP, +}; + +static const struct value_string scoc_event_names[] = { + /* Primitives from SCCP-User */ + { SCOC_E_SCU_N_CONN_REQ, "N-CONNECT.req" }, + { SCOC_E_SCU_N_CONN_RESP, "N-CONNECT.resp" }, + { SCOC_E_SCU_N_DISC_REQ, "N-DISCONNECT.req" }, + { SCOC_E_SCU_N_DATA_REQ, "N-DATA.req" }, + { SCOC_E_SCU_N_EXP_DATA_REQ, "N-EXPEDITED_DATA.req" }, + + /* Events from RCOC (Routing for Connection Oriented) */ + { SCOC_E_RCOC_CONN_IND, "RCOC-CONNECT.ind" }, + { SCOC_E_RCOC_ROUT_FAIL_IND, "RCOC-ROUT_FAIL.ind" }, + { SCOC_E_RCOC_RLSD_IND, "RCOC-RELEASED.ind" }, + { SCOC_E_RCOC_REL_COMPL_IND, "RCOC-RELEASE_COMPLETE.ind" }, + { SCOC_E_RCOC_CREF_IND, "RCOC-CONNECT_REFUSED.ind" }, + { SCOC_E_RCOC_CC_IND, "RCOC-CONNECT_CONFIRM.ind" }, + { SCOC_E_RCOC_DT1_IND, "RCOC-DT1.ind" }, + { SCOC_E_RCOC_DT2_IND, "RCOC-DT2.ind" }, + { SCOC_E_RCOC_IT_IND, "RCOC-IT.ind" }, + { SCOC_E_RCOC_OTHER_NPDU, "RCOC-OTHER_NPDU.ind" }, + { SCOC_E_RCOC_ERROR_IND, "RCOC-ERROR.ind" }, + + { SCOC_E_T_IAR_EXP, "T(iar)_expired" }, + { SCOC_E_T_IAS_EXP, "T(ias)_expired" }, + { SCOC_E_CONN_TMR_EXP, "T(conn)_expired" }, + { SCOC_E_T_REL_EXP, "T(rel)_expired" }, + { SCOC_E_T_INT_EXP, "T(int)_expired" }, + { SCOC_E_T_REP_REL_EXP, "T(rep_rel)_expired" }, + + { 0, NULL } +}; + +/* how to map a SCCP CO message to an event */ +static const struct xua_msg_event_map sua_scoc_event_map[] = { + { SUA_MSGC_CO, SUA_CO_CORE, SCOC_E_RCOC_CONN_IND }, + { SUA_MSGC_CO, SUA_CO_RELRE, SCOC_E_RCOC_RLSD_IND }, + { SUA_MSGC_CO, SUA_CO_RELCO, SCOC_E_RCOC_REL_COMPL_IND }, + { SUA_MSGC_CO, SUA_CO_COREF, SCOC_E_RCOC_CREF_IND }, + { SUA_MSGC_CO, SUA_CO_COAK, SCOC_E_RCOC_CC_IND }, + { SUA_MSGC_CO, SUA_CO_CODT, SCOC_E_RCOC_DT1_IND }, + { SUA_MSGC_CO, SUA_CO_COIT, SCOC_E_RCOC_IT_IND }, + { SUA_MSGC_CO, SUA_CO_COERR, SCOC_E_RCOC_ERROR_IND }, +}; + + +/* map from SCU-primitives to SCOC FSM events */ +static const struct osmo_prim_event_map scu_scoc_event_map[] = { + { SCCP_SAP_USER, OSMO_SCU_PRIM_N_CONNECT, PRIM_OP_REQUEST, + SCOC_E_SCU_N_CONN_REQ }, + { SCCP_SAP_USER, OSMO_SCU_PRIM_N_CONNECT, PRIM_OP_RESPONSE, + SCOC_E_SCU_N_CONN_RESP }, + { SCCP_SAP_USER, OSMO_SCU_PRIM_N_DATA, PRIM_OP_REQUEST, + SCOC_E_SCU_N_DATA_REQ }, + { SCCP_SAP_USER, OSMO_SCU_PRIM_N_DISCONNECT, PRIM_OP_REQUEST, + SCOC_E_SCU_N_DISC_REQ }, + { SCCP_SAP_USER, OSMO_SCU_PRIM_N_EXPEDITED_DATA, PRIM_OP_REQUEST, + SCOC_E_SCU_N_EXP_DATA_REQ }, + { 0, 0, 0, OSMO_NO_EVENT } +}; + +/*********************************************************************** + * Timer Handling + ***********************************************************************/ + +/* T(ias) has expired, send a COIT message to the peer */ +static void tx_inact_tmr_cb(void *data) +{ + struct sccp_connection *conn = data; + osmo_fsm_inst_dispatch(conn->fi, SCOC_E_T_IAS_EXP, NULL); +} + +/* T(iar) has expired, notify the FSM about it */ +static void rx_inact_tmr_cb(void *data) +{ + struct sccp_connection *conn = data; + osmo_fsm_inst_dispatch(conn->fi, SCOC_E_T_IAR_EXP, NULL); +} + +/* T(rel) has expired, notify the FSM about it */ +static void rel_tmr_cb(void *data) +{ + struct sccp_connection *conn = data; + osmo_fsm_inst_dispatch(conn->fi, SCOC_E_T_REL_EXP, NULL); +} + +/* T(int) has expired, notify the FSM about it */ +static void int_tmr_cb(void *data) +{ + struct sccp_connection *conn = data; + osmo_fsm_inst_dispatch(conn->fi, SCOC_E_T_INT_EXP, NULL); +} + +/* T(repeat_rel) has expired, notify the FSM about it */ +static void rep_rel_tmr_cb(void *data) +{ + struct sccp_connection *conn = data; + osmo_fsm_inst_dispatch(conn->fi, SCOC_E_T_REP_REL_EXP, NULL); +} + +/* T(conn) has expired, notify the FSM about it */ +static void conn_tmr_cb(void *data) +{ + struct sccp_connection *conn = data; + osmo_fsm_inst_dispatch(conn->fi, SCOC_E_CONN_TMR_EXP, NULL); +} + +/* Re-start the Tx inactivity timer */ +static void conn_restart_tx_inact_timer(struct sccp_connection *conn) +{ + osmo_timer_schedule(&conn->t_ias, MSEC_TO_S_US(TX_INACT_TIMER)); +} + +/* Re-start the Rx inactivity timer */ +static void conn_restart_rx_inact_timer(struct sccp_connection *conn) +{ + osmo_timer_schedule(&conn->t_iar, MSEC_TO_S_US(RX_INACT_TIMER)); +} + +/* Re-start both Rx and Tx inactivity timers */ +static void conn_start_inact_timers(struct sccp_connection *conn) +{ + conn_restart_tx_inact_timer(conn); + conn_restart_rx_inact_timer(conn); +} + +/* Stop both Rx and Tx inactivity timers */ +static void conn_stop_inact_timers(struct sccp_connection *conn) +{ + osmo_timer_del(&conn->t_ias); + osmo_timer_del(&conn->t_iar); +} + +/* Start release timer T(rel) */ +static void conn_start_rel_timer(struct sccp_connection *conn) +{ + osmo_timer_schedule(&conn->t_rel, MSEC_TO_S_US(RELEASE_TIMER)); +} + +/* Start repeat release timer T(rep_rel) */ +static void conn_start_rep_rel_timer(struct sccp_connection *conn) +{ + osmo_timer_schedule(&conn->t_rep_rel, MSEC_TO_S_US(RELEASE_REP_TIMER)); +} + +/* Start interval timer T(int) */ +static void conn_start_int_timer(struct sccp_connection *conn) +{ + osmo_timer_schedule(&conn->t_int, MSEC_TO_S_US(INT_TIMER)); +} + +/* Stop all release related timers: T(rel), T(int) and T(rep_rel) */ +static void conn_stop_release_timers(struct sccp_connection *conn) +{ + osmo_timer_del(&conn->t_rel); + osmo_timer_del(&conn->t_int); + osmo_timer_del(&conn->t_rep_rel); +} + +/* Start connect timer T(conn) */ +static void conn_start_connect_timer(struct sccp_connection *conn) +{ + osmo_timer_schedule(&conn->t_conn, MSEC_TO_S_US(CONNECTION_TIMER)); +} + +/* Stop connect timer T(conn) */ +static void conn_stop_connect_timer(struct sccp_connection *conn) +{ + osmo_timer_del(&conn->t_conn); +} + + +/*********************************************************************** + * SUA Instance and Connection handling + ***********************************************************************/ + +static void conn_destroy(struct sccp_connection *conn); + +static struct sccp_connection *conn_find_by_id(struct osmo_sccp_instance *inst, uint32_t id) +{ + struct sccp_connection *conn; + + llist_for_each_entry(conn, &inst->connections, list) { + if (conn->conn_id == id) + return conn; + } + return NULL; +} + +#define INIT_TIMER(x, fn, priv) do { (x)->cb = fn; (x)->data = priv; } while (0) + +/* allocate + init a SCCP Connection with given ID (local reference) */ +static struct sccp_connection *conn_create_id(struct osmo_sccp_instance *inst, + uint32_t conn_id) +{ + struct sccp_connection *conn = talloc_zero(inst, struct sccp_connection); + char name[16]; + + conn->conn_id = conn_id; + conn->inst = inst; + + llist_add_tail(&conn->list, &inst->connections); + + INIT_TIMER(&conn->t_conn, conn_tmr_cb, conn); + INIT_TIMER(&conn->t_ias, tx_inact_tmr_cb, conn); + INIT_TIMER(&conn->t_iar, rx_inact_tmr_cb, conn); + INIT_TIMER(&conn->t_rel, rel_tmr_cb, conn); + INIT_TIMER(&conn->t_int, int_tmr_cb, conn); + INIT_TIMER(&conn->t_rep_rel, rep_rel_tmr_cb, conn); + + /* this might change at runtime, as it is not a constant :/ */ + sccp_scoc_fsm.log_subsys = DLSCCP; + + /* we simply use the local reference as FSM instance name */ + snprintf(name, sizeof(name), "%u", conn->conn_id); + conn->fi = osmo_fsm_inst_alloc(&sccp_scoc_fsm, conn, conn, + LOGL_DEBUG, name); + if (!conn->fi) { + llist_del(&conn->list); + talloc_free(conn); + return NULL; + } + + return conn; +} + +/* Search for next free connection ID (local reference) and allocate conn */ +static struct sccp_connection *conn_create(struct osmo_sccp_instance *inst) +{ + uint32_t conn_id; + + do { + conn_id = inst->next_id++; + } while (conn_find_by_id(inst, conn_id)); + + return conn_create_id(inst, conn_id); +} + +/* destroy a SCCP connection state, releasing all timers, terminating + * FSM and releasing associated memory */ +static void conn_destroy(struct sccp_connection *conn) +{ + conn_stop_connect_timer(conn); + conn_stop_inact_timers(conn); + conn_stop_release_timers(conn); + llist_del(&conn->list); + + osmo_fsm_inst_term(conn->fi, OSMO_FSM_TERM_REQUEST, NULL); + + talloc_free(conn); +} + +/* allocate a message buffer for an SCCP User Primitive */ +static struct msgb *scu_msgb_alloc(void) +{ + return msgb_alloc(SCU_MSGB_SIZE, "SCCP User Primitive"); +} + +/* generate a RELRE (release request) xua_msg for given conn */ +static struct xua_msg *xua_gen_relre(struct sccp_connection *conn, + uint32_t cause, + struct osmo_scu_prim *prim) +{ + struct xua_msg *xua = xua_msg_alloc(); + + if (!xua) + return NULL; + + xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_RELRE); + xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, conn->inst->route_ctx); + xua_msg_add_u32(xua, SUA_IEI_DEST_REF, conn->remote_ref); + xua_msg_add_u32(xua, SUA_IEI_SRC_REF, conn->conn_id); + xua_msg_add_u32(xua, SUA_IEI_CAUSE, SUA_CAUSE_T_RELEASE | cause); + /* optional: importance */ + if (prim && msgb_l2(prim->oph.msg)) + xua_msg_add_data(xua, SUA_IEI_DATA, msgb_l2len(prim->oph.msg), + msgb_l2(prim->oph.msg)); + + return xua; +} + +/* generate xua_msg, encode it and send it to SCRC */ +static int xua_gen_relre_and_send(struct sccp_connection *conn, uint32_t cause, + struct osmo_scu_prim *prim) +{ + struct xua_msg *xua; + + xua = xua_gen_relre(conn, cause, prim); + if (!xua) + return -1; + + /* amend this with point code information; The SUA RELRE + * includes neither called nor calling party address! */ + xua->mtp.dpc = conn->remote_pc; + return sccp_scrc_rx_scoc_conn_msg(conn->inst, xua); +} + +/* generate a 'struct xua_msg' of requested type from connection + + * primitive data */ +static struct xua_msg *xua_gen_msg_co(struct sccp_connection *conn, uint32_t event, + struct osmo_scu_prim *prim, int msg_type) +{ + struct xua_msg *xua = xua_msg_alloc(); + + if (!xua) + return NULL; + + switch (msg_type) { + case SUA_CO_CORE: /* Connect Request == SCCP CR */ + xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_CORE); + xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, conn->inst->route_ctx); + xua_msg_add_u32(xua, SUA_IEI_PROTO_CLASS, conn->sccp_class); + xua_msg_add_u32(xua, SUA_IEI_SRC_REF, conn->conn_id); + xua_msg_add_sccp_addr(xua, SUA_IEI_DEST_ADDR, &conn->called_addr); + xua_msg_add_u32(xua, SUA_IEI_SEQ_CTRL, 0); /* TODO */ + /* optional: sequence number (class 3 only) */ + if (conn->calling_addr.presence) + xua_msg_add_sccp_addr(xua, SUA_IEI_SRC_ADDR, &conn->calling_addr); + /* optional: hop count; importance; priority; credit */ + if (prim && msgb_l2(prim->oph.msg)) + xua_msg_add_data(xua, SUA_IEI_DATA, msgb_l2len(prim->oph.msg), + msgb_l2(prim->oph.msg)); + break; + case SUA_CO_COAK: /* Connect Acknowledge == SCCP CC */ + xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_COAK); + xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, conn->inst->route_ctx); + xua_msg_add_u32(xua, SUA_IEI_PROTO_CLASS, conn->sccp_class); + xua_msg_add_u32(xua, SUA_IEI_DEST_REF, conn->remote_ref); + xua_msg_add_u32(xua, SUA_IEI_SRC_REF, conn->conn_id); + xua_msg_add_u32(xua, SUA_IEI_SEQ_CTRL, 0); /* TODO */ + /* optional: sequence number (class 3 only) */ + if (conn->called_addr.presence) + xua_msg_add_sccp_addr(xua, SUA_IEI_SRC_ADDR, &conn->called_addr); + /* optional: hop count; importance; priority */ + /* FIXME: destination address will [only] be present in + * case the CORE message conveys the source address + * parameter */ + if (conn->calling_addr.presence) + xua_msg_add_sccp_addr(xua, SUA_IEI_DEST_ADDR, &conn->calling_addr); + if (prim && msgb_l2(prim->oph.msg)) + xua_msg_add_data(xua, SUA_IEI_DATA, msgb_l2len(prim->oph.msg), + msgb_l2(prim->oph.msg)); + break; + case SUA_CO_RELRE: /* Release Request == SCCP REL */ + if (!prim) + goto prim_needed; + xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_RELRE); + xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, conn->inst->route_ctx); + xua_msg_add_u32(xua, SUA_IEI_DEST_REF, conn->remote_ref); + xua_msg_add_u32(xua, SUA_IEI_SRC_REF, conn->conn_id); + xua_msg_add_u32(xua, SUA_IEI_CAUSE, SUA_CAUSE_T_RELEASE | prim->u.disconnect.cause); + /* optional: importance */ + if (msgb_l2(prim->oph.msg)) + xua_msg_add_data(xua, SUA_IEI_DATA, msgb_l2len(prim->oph.msg), + msgb_l2(prim->oph.msg)); + break; + case SUA_CO_RELCO: /* Release Confirm == SCCP RLSD */ + xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_RELCO); + xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, conn->inst->route_ctx); + xua_msg_add_u32(xua, SUA_IEI_DEST_REF, conn->remote_ref); + xua_msg_add_u32(xua, SUA_IEI_SRC_REF, conn->conn_id); + /* optional: importance */ + break; + case SUA_CO_CODT: /* Connection Oriented Data Transfer == SCCP DT1 */ + if (!prim) + goto prim_needed; + xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_CODT); + xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, conn->inst->route_ctx); + /* Sequence number only in expedited data */ + xua_msg_add_u32(xua, SUA_IEI_DEST_REF, conn->remote_ref); + /* optional: priority; correlation id */ + xua_msg_add_data(xua, SUA_IEI_DATA, msgb_l2len(prim->oph.msg), + msgb_l2(prim->oph.msg)); + break; + case SUA_CO_COIT: /* Connection Oriented Interval Timer == SCCP IT */ + xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_COIT); + xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, conn->inst->route_ctx); + xua_msg_add_u32(xua, SUA_IEI_PROTO_CLASS, conn->sccp_class); + xua_msg_add_u32(xua, SUA_IEI_SRC_REF, conn->conn_id); + xua_msg_add_u32(xua, SUA_IEI_DEST_REF, conn->remote_ref); + /* optional: sequence number; credit (both class 3 only) */ + break; + case SUA_CO_COREF: /* Connect Refuse == SCCP CREF */ + xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_COREF); + xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, conn->inst->route_ctx); + xua_msg_add_u32(xua, SUA_IEI_DEST_REF, conn->remote_ref); + //xua_msg_add_u32(xua, SUA_IEI_CAUSE, SUA_CAUSE_T_REFUSAL | prim->u.disconnect.cause); + xua_msg_add_u32(xua, SUA_IEI_CAUSE, SUA_CAUSE_T_REFUSAL | SCCP_REFUSAL_UNEQUIPPED_USER); + /* optional: source addr */ + if (conn->called_addr.presence) + xua_msg_add_sccp_addr(xua, SUA_IEI_SRC_ADDR, &conn->called_addr); + /* conditional: dest addr */ + if (conn->calling_addr.presence) + xua_msg_add_sccp_addr(xua, SUA_IEI_DEST_ADDR, &conn->calling_addr); + /* optional: importance */ + /* optional: data */ + if (prim && msgb_l2(prim->oph.msg)) + xua_msg_add_data(xua, SUA_IEI_DATA, msgb_l2len(prim->oph.msg), + msgb_l2(prim->oph.msg)); + break; + /* FIXME */ + default: + LOGP(DLSCCP, LOGL_ERROR, "Don't know how to encode msg_type %u\n", msg_type); + xua_msg_free(xua); + return NULL; + } + return xua; + +prim_needed: + xua_msg_free(xua); + LOGP(DLSCCP, LOGL_ERROR, "%s must be called with valid 'prim' " + "pointer for msg_type=%u\n", __func__, msg_type); + return NULL; +} + +/* generate xua_msg, encode it and send it to SCRC */ +static int xua_gen_encode_and_send(struct sccp_connection *conn, uint32_t event, + struct osmo_scu_prim *prim, int msg_type) +{ + struct xua_msg *xua; + + xua = xua_gen_msg_co(conn, event, prim, msg_type); + if (!xua) + return -1; + + /* amend this with point code information; Many CO msgs + * includes neither called nor calling party address! */ + xua->mtp.dpc = conn->remote_pc; + return sccp_scrc_rx_scoc_conn_msg(conn->inst, xua); +} + +/* allocate a SCU primitive to be sent to the user */ +static struct osmo_scu_prim *scu_prim_alloc(unsigned int primitive, enum osmo_prim_operation operation) +{ + struct msgb *upmsg = scu_msgb_alloc(); + struct osmo_scu_prim *prim; + + prim = (struct osmo_scu_prim *) msgb_put(upmsg, sizeof(*prim)); + osmo_prim_init(&prim->oph, SCCP_SAP_USER, + primitive, operation, upmsg); + return prim; +} + +/* high-level function to generate a SCCP User primitive of requested + * type based on the connection and currently processed XUA message */ +static void scu_gen_encode_and_send(struct sccp_connection *conn, uint32_t event, + struct xua_msg *xua, unsigned int primitive, + enum osmo_prim_operation operation) +{ + struct osmo_scu_prim *scu_prim; + struct osmo_scu_disconn_param *udisp; + struct osmo_scu_connect_param *uconp; + struct osmo_scu_data_param *udatp; + struct xua_msg_part *data_ie; + + scu_prim = scu_prim_alloc(primitive, operation); + + switch (OSMO_PRIM_HDR(&scu_prim->oph)) { + case OSMO_PRIM(OSMO_SCU_PRIM_N_DISCONNECT, PRIM_OP_INDICATION): + udisp = &scu_prim->u.disconnect; + udisp->conn_id = conn->conn_id; + udisp->responding_addr = conn->called_addr; + udisp->originator = OSMO_SCCP_ORIG_UNDEFINED; + //udisp->in_sequence_control; + if (xua) { + udisp->cause = xua_msg_get_u32(xua, SUA_IEI_CAUSE); + if (xua_msg_find_tag(xua, SUA_IEI_SRC_ADDR)) + sua_addr_parse(&udisp->responding_addr, xua, SUA_IEI_SRC_ADDR); + data_ie = xua_msg_find_tag(xua, SUA_IEI_DATA); + udisp->importance = xua_msg_get_u32(xua, SUA_IEI_IMPORTANCE); + if (data_ie) { + struct msgb *upmsg = scu_prim->oph.msg; + upmsg->l2h = msgb_put(upmsg, data_ie->len); + memcpy(upmsg->l2h, data_ie->dat, data_ie->len); + } + } + break; + case OSMO_PRIM(OSMO_SCU_PRIM_N_CONNECT, PRIM_OP_INDICATION): + uconp = &scu_prim->u.connect; + uconp->conn_id = conn->conn_id; + uconp->called_addr = conn->called_addr; + uconp->calling_addr = conn->calling_addr; + uconp->sccp_class = conn->sccp_class; + uconp->importance = conn->importance; + data_ie = xua_msg_find_tag(xua, SUA_IEI_DATA); + if (xua) { + if (data_ie) { + struct msgb *upmsg = scu_prim->oph.msg; + upmsg->l2h = msgb_put(upmsg, data_ie->len); + memcpy(upmsg->l2h, data_ie->dat, data_ie->len); + } + } + break; + case OSMO_PRIM(OSMO_SCU_PRIM_N_CONNECT, PRIM_OP_CONFIRM): + uconp = &scu_prim->u.connect; + uconp->conn_id = conn->conn_id; + uconp->called_addr = conn->called_addr; + uconp->calling_addr = conn->calling_addr; + //scu_prim->u.connect.in_sequence_control + uconp->sccp_class = xua_msg_get_u32(xua, SUA_IEI_PROTO_CLASS) & 3; + uconp->importance = xua_msg_get_u32(xua, SUA_IEI_IMPORTANCE); + data_ie = xua_msg_find_tag(xua, SUA_IEI_DATA); + if (data_ie) { + struct msgb *upmsg = scu_prim->oph.msg; + upmsg->l2h = msgb_put(upmsg, data_ie->len); + memcpy(upmsg->l2h, data_ie->dat, data_ie->len); + } + break; + case OSMO_PRIM(OSMO_SCU_PRIM_N_DATA, PRIM_OP_INDICATION): + udatp = &scu_prim->u.data; + udatp->conn_id = conn->conn_id; + udatp->importance = conn->importance; + data_ie = xua_msg_find_tag(xua, SUA_IEI_DATA); + if (data_ie) { + struct msgb *upmsg = scu_prim->oph.msg; + upmsg->l2h = msgb_put(upmsg, data_ie->len); + memcpy(upmsg->l2h, data_ie->dat, data_ie->len); + } + break; + default: + LOGPFSML(conn->fi, LOGL_ERROR, "Unsupported primitive %u:%u\n", + scu_prim->oph.primitive, scu_prim->oph.operation); + talloc_free(scu_prim->oph.msg); + return; + } + + sccp_user_prim_up(conn->user, scu_prim); +} + + +/*********************************************************************** + * Actual SCCP Connection Oriented Control (SCOC) Finite Stte Machine + ***********************************************************************/ + +/* Figure C.2/Q.714 (sheet 1 of 7) and C.3/Q.714 (sheet 1 of 6) */ +static void scoc_fsm_idle(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct sccp_connection *conn = fi->priv; + struct osmo_scu_prim *prim = NULL; + struct osmo_scu_connect_param *uconp; + struct xua_msg *xua = NULL; + + switch (event) { + case SCOC_E_SCU_N_CONN_REQ: + prim = data; + uconp = &prim->u.connect; + /* copy relevant parameters from prim to conn */ + conn->called_addr = uconp->called_addr; + conn->calling_addr = uconp->calling_addr; + conn->sccp_class = uconp->sccp_class; + /* generate + send CR PDU to SCRC */ + xua_gen_encode_and_send(conn, event, prim, SUA_CO_CORE); + /* start connection timer */ + conn_start_connect_timer(conn); + osmo_fsm_inst_state_chg(fi, S_CONN_PEND_OUT, 0, 0); + break; +#if 0 + case SCOC_E_SCU_N_TYPE1_REQ: + /* ?!? */ + break; +#endif + case SCOC_E_RCOC_RLSD_IND: + /* send release complete to SCRC */ + xua_gen_encode_and_send(conn, event, NULL, SUA_CO_RELCO); + break; + case SCOC_E_RCOC_REL_COMPL_IND: + /* do nothing */ + break; + case SCOC_E_RCOC_OTHER_NPDU: +#if 0 + if (src_ref) { + /* FIXME: send ERROR to SCRC */ + } +#endif + break; + /* destination node / incoming connection */ + /* Figure C.3 / Q.714 (sheet 1 of 6) */ + case SCOC_E_RCOC_CONN_IND: + xua = data; + /* copy relevant parameters from xua to conn */ + sua_addr_parse(&conn->calling_addr, xua, SUA_IEI_SRC_ADDR); + sua_addr_parse(&conn->called_addr, xua, SUA_IEI_DEST_ADDR); + conn->remote_ref = xua_msg_get_u32(xua, SUA_IEI_SRC_REF); + conn->sccp_class = xua_msg_get_u32(xua, SUA_IEI_PROTO_CLASS) & 3; + conn->importance = xua_msg_get_u32(xua, SUA_IEI_IMPORTANCE); + /* 3.1.6.1 The originating node of the CR message + * (identified by the OPC in the calling party address + * or by default by the OPC in the MTP label, [and the + * MTP-SAP instance]) is associated with the incoming + * connection section. */ + if (conn->calling_addr.presence & OSMO_SCCP_ADDR_T_PC) + conn->remote_pc = conn->calling_addr.pc; + else { + /* Hack to get the MTP label here ?!? */ + conn->remote_pc = xua->mtp.opc; + } + + osmo_fsm_inst_state_chg(fi, S_CONN_PEND_IN, 0, 0); + /* N-CONNECT.ind to User */ + scu_gen_encode_and_send(conn, event, xua, OSMO_SCU_PRIM_N_CONNECT, + PRIM_OP_INDICATION); + break; + } +} + +static void scoc_fsm_idle_onenter(struct osmo_fsm_inst *fi, uint32_t old_state) +{ + conn_destroy(fi->priv); +} + +/* Figure C.3 / Q.714 (sheet 2 of 6) */ +static void scoc_fsm_conn_pend_in(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct sccp_connection *conn = fi->priv; + struct osmo_scu_prim *prim = NULL; + + switch (event) { + case SCOC_E_SCU_N_CONN_RESP: + prim = data; + /* FIXME: assign local reference (only now?) */ + /* FIXME: assign sls, protocol class and credit */ + xua_gen_encode_and_send(conn, event, prim, SUA_CO_COAK); + /* start inactivity timers */ + conn_start_inact_timers(conn); + osmo_fsm_inst_state_chg(fi, S_ACTIVE, 0, 0); + break; + case SCOC_E_SCU_N_DISC_REQ: + prim = data; + /* release resources: implicit */ + xua_gen_encode_and_send(conn, event, prim, SUA_CO_COREF); + osmo_fsm_inst_state_chg(fi, S_IDLE, 0, 0); + break; + } +} + +/* Figure C.2/Q.714 (sheet 2 of 7) */ +static void scoc_fsm_conn_pend_out(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct sccp_connection *conn = fi->priv; + struct osmo_scu_prim *prim = NULL; + struct xua_msg *xua = NULL; + + switch (event) { + case SCOC_E_SCU_N_DISC_REQ: + prim = data; + conn->release_cause = prim->u.disconnect.cause; + osmo_fsm_inst_state_chg(fi, S_WAIT_CONN_CONF, 0, 0); + /* keep conn timer running(!) */ + break; + case SCOC_E_CONN_TMR_EXP: + /* N-DISCONNECT.ind to user */ + scu_gen_encode_and_send(conn, event, xua, OSMO_SCU_PRIM_N_DISCONNECT, + PRIM_OP_INDICATION); + /* below implicitly releases resources + local ref */ + osmo_fsm_inst_state_chg(fi, S_IDLE, 0, 0); + break; + case SCOC_E_RCOC_ROUT_FAIL_IND: + case SCOC_E_RCOC_CREF_IND: + xua = data; + /* stop conn timer */ + conn_stop_connect_timer(conn); + /* release local res + ref (implicit by going to idle) */ + /* N-DISCONNECT.ind to user */ + scu_gen_encode_and_send(conn, event, xua, OSMO_SCU_PRIM_N_DISCONNECT, + PRIM_OP_INDICATION); + /* below implicitly releases resources + local ref */ + osmo_fsm_inst_state_chg(fi, S_IDLE, 0, 0); + break; + case SCOC_E_RCOC_RLSD_IND: + xua = data; + /* RLC to SCRC */ + xua_gen_encode_and_send(conn, event, NULL, SUA_CO_RELCO); + /* stop conn timer */ + conn_stop_connect_timer(conn); + /* release local res + ref (implicit) */ + /* N-DISCONNECT.ind to user */ + scu_gen_encode_and_send(conn, event, xua, OSMO_SCU_PRIM_N_DISCONNECT, + PRIM_OP_INDICATION); + osmo_fsm_inst_state_chg(fi, S_IDLE, 0, 0); + break; + case SCOC_E_RCOC_OTHER_NPDU: + xua = data; + conn_start_connect_timer(conn); + /* release local res + ref (implicit) */ + /* N-DISCONNECT.ind to user */ + scu_gen_encode_and_send(conn, event, xua, OSMO_SCU_PRIM_N_DISCONNECT, + PRIM_OP_INDICATION); + osmo_fsm_inst_state_chg(fi, S_IDLE, 0, 0); + break; + case SCOC_E_RCOC_CC_IND: + xua = data; + /* stop conn timer */ + conn_stop_connect_timer(conn); + /* start inactivity timers */ + conn_start_inact_timers(conn); + /* TODO: assign PCU and credit */ + /* associate remote ref to conn */ + conn->remote_ref = xua_msg_get_u32(xua, SUA_IEI_SRC_REF); + /* 3.1.4.2 The node sending the CC message (identified + * by the parameter OPC contained in the + * MTP-TRANSFER.indication primitive which conveyed the + * CC message [plus the MTP-SAP instance]) is associated + * with the connection section. */ + conn->remote_pc = xua->mtp.opc; + + osmo_fsm_inst_state_chg(fi, S_ACTIVE, 0, 0); + /* N-CONNECT.conf to user */ + scu_gen_encode_and_send(conn, event, xua, OSMO_SCU_PRIM_N_CONNECT, + PRIM_OP_CONFIRM); + break; + } +} + +/* Figure C.2/Q.714 (sheet 3 of 7) */ +static void scoc_fsm_wait_conn_conf(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct sccp_connection *conn = fi->priv; + struct xua_msg *xua = NULL; + + switch (event) { + case SCOC_E_RCOC_RLSD_IND: + xua = data; + /* release complete to SCRC */ + xua_gen_encode_and_send(conn, event, NULL, SUA_CO_RELCO); + /* stop conn timer */ + conn_stop_connect_timer(conn); + /* release local res + ref (implicit) */ + osmo_fsm_inst_state_chg(fi, S_IDLE, 0, 0); + break; + case SCOC_E_RCOC_CC_IND: + xua = data; + /* stop conn timer */ + conn_stop_connect_timer(conn); + /* associate rem ref to conn */ + conn->remote_ref = xua_msg_get_u32(xua, SUA_IEI_SRC_REF); + /* released to SCRC */ + xua_gen_relre_and_send(conn, conn->release_cause, NULL); + /* start rel timer */ + conn_start_rel_timer(conn); + osmo_fsm_inst_state_chg(fi, S_DISCONN_PEND, 0, 0); + break; + case SCOC_E_RCOC_OTHER_NPDU: + case SCOC_E_RCOC_CREF_IND: + case SCOC_E_RCOC_ROUT_FAIL_IND: + xua = data; + /* stop conn timer */ + conn_stop_connect_timer(conn); + /* release local res + ref */ + osmo_fsm_inst_state_chg(fi, S_IDLE, 0, 0); + break; + case SCOC_E_CONN_TMR_EXP: + /* release local res + ref */ + osmo_fsm_inst_state_chg(fi, S_IDLE, 0, 0); + break; + } +} + +/* C.2/Q.714 (sheet 4+5 of 7) and C.3/Q714 (sheet 3+4 of 6) */ +static void scoc_fsm_active(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct xua_msg *xua = data; + struct sccp_connection *conn = fi->priv; + struct osmo_scu_prim *prim = NULL; + + switch (event) { + /* TODO: internal disco */ + /* send N-DISCONNECT.ind to user */ + scu_gen_encode_and_send(conn, event, xua, OSMO_SCU_PRIM_N_DISCONNECT, + PRIM_OP_INDICATION); + /* fall-through */ + case SCOC_E_SCU_N_DISC_REQ: + prim = data; + /* stop inact timers */ + conn_stop_inact_timers(conn); + /* send RLSD to SCRC */ + xua_gen_encode_and_send(conn, event, prim, SUA_CO_RELRE); + /* start rel timer */ + conn_start_rel_timer(conn); + osmo_fsm_inst_state_chg(fi, S_DISCONN_PEND, 0, 0); + break; + case SCOC_E_RCOC_CREF_IND: + case SCOC_E_RCOC_CC_IND: + case SCOC_E_RCOC_REL_COMPL_IND: + /* do nothing */ + break; + case SCOC_E_RCOC_RLSD_IND: + /* send N-DISCONNECT.ind to user */ + scu_gen_encode_and_send(conn, event, xua, OSMO_SCU_PRIM_N_DISCONNECT, + PRIM_OP_INDICATION); + /* release res + local ref (implicit) */ + /* stop inact timers */ + conn_stop_inact_timers(conn); + /* RLC to SCRC */ + xua_gen_encode_and_send(conn, event, NULL, SUA_CO_RELCO); + osmo_fsm_inst_state_chg(fi, S_IDLE, 0, 0); + break; + case SCOC_E_RCOC_ERROR_IND: + xua = data; + /* FIXME: check for cause service_class_mismatch */ + /* release res + local ref (implicit) */ + /* send N-DISCONNECT.ind to user */ + scu_gen_encode_and_send(conn, event, xua, OSMO_SCU_PRIM_N_DISCONNECT, + PRIM_OP_INDICATION); + /* stop inact timers */ + conn_stop_inact_timers(conn); + osmo_fsm_inst_state_chg(fi, S_IDLE, 0, 0); + break; + case SCOC_E_T_IAR_EXP: + /* Send N-DISCONNECT.ind to local user */ + scu_gen_encode_and_send(conn, event, NULL, OSMO_SCU_PRIM_N_DISCONNECT, + PRIM_OP_INDICATION); + /* Send RLSD to peer */ + xua_gen_relre_and_send(conn, SCCP_RELEASE_CAUSE_EXPIRATION_INACTIVE, NULL); + conn_start_rel_timer(conn); + osmo_fsm_inst_state_chg(fi, S_DISCONN_PEND, 0, 0); + break; + case SCOC_E_RCOC_ROUT_FAIL_IND: + /* send N-DISCONNECT.ind to user */ + scu_gen_encode_and_send(conn, event, NULL, OSMO_SCU_PRIM_N_DISCONNECT, + PRIM_OP_INDICATION); + /* stop inact timers */ + conn_stop_inact_timers(conn); + /* start release timer */ + conn_start_rel_timer(conn); + osmo_fsm_inst_state_chg(fi, S_DISCONN_PEND, 0, 0); + break; + /* Figure C.4/Q.714 */ + case SCOC_E_SCU_N_DATA_REQ: + case SCOC_E_SCU_N_EXP_DATA_REQ: + prim = data; + xua_gen_encode_and_send(conn, event, prim, SUA_CO_CODT); + conn_restart_tx_inact_timer(conn); + break; + case SCOC_E_RCOC_DT1_IND: + /* restart receive inactivity timer */ + conn_restart_rx_inact_timer(conn); + /* TODO: M-bit */ + scu_gen_encode_and_send(conn, event, xua, OSMO_SCU_PRIM_N_DATA, + PRIM_OP_INDICATION); + break; + /* Figure C.4/Q.714 (sheet 4 of 4) */ + case SCOC_E_RCOC_IT_IND: + xua = data; + /* check if remote reference is what we expect */ + /* check class is what we expect */ + if (xua_msg_get_u32(xua, SUA_IEI_SRC_REF) != conn->remote_ref || + xua_msg_get_u32(xua, SUA_IEI_PROTO_CLASS) != conn->sccp_class) { + /* Release connection */ + /* send N-DISCONNECT.ind to user */ + scu_gen_encode_and_send(conn, event, NULL, + OSMO_SCU_PRIM_N_DISCONNECT, + PRIM_OP_INDICATION); + /* Stop inactivity Timers */ + conn_stop_inact_timers(conn); + /* Send RLSD to SCRC */ + xua_gen_relre_and_send(conn, SCCP_RELEASE_CAUSE_INCONSISTENT_CONN_DATA, NULL); + /* Start release timer */ + conn_start_rel_timer(conn); + osmo_fsm_inst_state_chg(fi, S_DISCONN_PEND, 0, 0); + } + conn_restart_rx_inact_timer(conn); + break; + case SCOC_E_T_IAS_EXP: + /* Send IT to peer */ + xua_gen_encode_and_send(conn, event, NULL, SUA_CO_COIT); + conn_restart_tx_inact_timer(conn); + break; + } +} + +/* C.2/Q.714 (sheet 6+7 of 7) and C.3/Q.714 (sheet 5+6 of 6) */ +static void scoc_fsm_disconn_pend(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct sccp_connection *conn = fi->priv; + + switch (event) { + case SCOC_E_RCOC_REL_COMPL_IND: + case SCOC_E_RCOC_RLSD_IND: + /* release res + local ref (implicit) */ + /* freeze local ref */ + /* stop release + interval timers */ + conn_stop_release_timers(conn); + osmo_fsm_inst_state_chg(fi, S_IDLE, 0, 0); + break; + case SCOC_E_RCOC_ROUT_FAIL_IND: + case SCOC_E_RCOC_OTHER_NPDU: + /* do nothing */ + break; + case SCOC_E_T_REL_EXP: /* release timer exp */ + /* send RLSD */ + xua_gen_relre_and_send(conn, SCCP_RELEASE_CAUSE_UNQUALIFIED, NULL); + /* start interval timer */ + conn_start_int_timer(conn); + /* start repeat release timer */ + conn_start_rep_rel_timer(conn); + break; + case SCOC_E_T_INT_EXP: /* interval timer exp */ + /* TODO: Inform maintenance */ + /* stop release and interval timers */ + conn_stop_release_timers(conn); + osmo_fsm_inst_state_chg(fi, S_IDLE, 0, 0); + break; + case SCOC_E_T_REP_REL_EXP: /* repeat release timer exp */ + /* send RLSD */ + xua_gen_relre_and_send(conn, SCCP_RELEASE_CAUSE_UNQUALIFIED, NULL); + /* re-start repeat release timer */ + conn_start_rep_rel_timer(conn); + break; + } +} + +static const struct osmo_fsm_state sccp_scoc_states[] = { + [S_IDLE] = { + .name = "IDLE", + .action = scoc_fsm_idle, + .onenter= scoc_fsm_idle_onenter, + .in_event_mask = S(SCOC_E_SCU_N_CONN_REQ) | + //S(SCOC_E_SCU_N_TYPE1_REQ) | + S(SCOC_E_RCOC_CONN_IND) | + S(SCOC_E_RCOC_RLSD_IND) | + S(SCOC_E_RCOC_REL_COMPL_IND) | + S(SCOC_E_RCOC_OTHER_NPDU), + .out_state_mask = S(S_CONN_PEND_OUT) | + S(S_CONN_PEND_IN), + }, + [S_CONN_PEND_IN] = { + .name = "CONN_PEND_IN", + .action = scoc_fsm_conn_pend_in, + .in_event_mask = S(SCOC_E_SCU_N_CONN_RESP) | + S(SCOC_E_SCU_N_DISC_REQ), + .out_state_mask = S(S_IDLE) | + S(S_ACTIVE), + }, + [S_CONN_PEND_OUT] = { + .name = "CONN_PEND_OUT", + .action = scoc_fsm_conn_pend_out, + .in_event_mask = S(SCOC_E_SCU_N_DISC_REQ) | + S(SCOC_E_CONN_TMR_EXP) | + S(SCOC_E_RCOC_ROUT_FAIL_IND) | + S(SCOC_E_RCOC_RLSD_IND) | + S(SCOC_E_RCOC_OTHER_NPDU) | + S(SCOC_E_RCOC_CREF_IND) | + S(SCOC_E_RCOC_CC_IND), + .out_state_mask = S(S_IDLE) | + S(S_ACTIVE) | + S(S_WAIT_CONN_CONF), + }, + [S_ACTIVE] = { + .name = "ACTIVE", + .action = scoc_fsm_active, + .in_event_mask = S(SCOC_E_SCU_N_DISC_REQ) | + /* internal disconnect */ + S(SCOC_E_RCOC_CREF_IND) | + S(SCOC_E_RCOC_REL_COMPL_IND) | + S(SCOC_E_RCOC_RLSD_IND) | + S(SCOC_E_RCOC_ERROR_IND) | + S(SCOC_E_T_IAR_EXP) | + S(SCOC_E_T_IAS_EXP) | + S(SCOC_E_RCOC_ROUT_FAIL_IND) | + S(SCOC_E_SCU_N_DATA_REQ) | + S(SCOC_E_SCU_N_EXP_DATA_REQ) | + S(SCOC_E_RCOC_DT1_IND) | + S(SCOC_E_RCOC_IT_IND), + .out_state_mask = S(S_IDLE) | + S(S_DISCONN_PEND), + }, + [S_DISCONN_PEND] = { + .name = "DISCONN_PEND", + .action = scoc_fsm_disconn_pend, + .in_event_mask = S(SCOC_E_RCOC_REL_COMPL_IND) | + S(SCOC_E_RCOC_RLSD_IND) | + S(SCOC_E_RCOC_ROUT_FAIL_IND) | + S(SCOC_E_RCOC_OTHER_NPDU) | + S(SCOC_E_T_REL_EXP) | + S(SCOC_E_T_INT_EXP) | + S(SCOC_E_T_REP_REL_EXP), + .out_state_mask = S(S_IDLE), + }, + [S_RESET_IN] = { + .name = "RESET_IN", + }, + [S_RESET_OUT] = { + .name = "RESET_OUT", + }, + [S_BOTHWAY_RESET] = { + .name = "BOTHWAY_RESET", + }, + [S_WAIT_CONN_CONF] = { + .name = "WAIT_CONN_CONF", + .action = scoc_fsm_wait_conn_conf, + .in_event_mask = S(SCOC_E_RCOC_RLSD_IND) | + S(SCOC_E_RCOC_CC_IND) | + S(SCOC_E_RCOC_OTHER_NPDU) | + S(SCOC_E_CONN_TMR_EXP) | + S(SCOC_E_RCOC_CREF_IND) | + S(SCOC_E_RCOC_ROUT_FAIL_IND), + }, +}; + +struct osmo_fsm sccp_scoc_fsm = { + .name = "SCCP-SCOC", + .states = sccp_scoc_states, + .num_states = ARRAY_SIZE(sccp_scoc_states), + /* ".log_subsys = DLSCCP" doesn't work as DLSCCP is not a constant */ + .event_names = scoc_event_names, +}; + +/* map from SCCP return cause to SCCP Refusal cause */ +static const uint8_t cause_map_cref[] = { + [SCCP_RETURN_CAUSE_SUBSYSTEM_CONGESTION] = + SCCP_REFUSAL_SUBSYTEM_CONGESTION, + [SCCP_RETURN_CAUSE_SUBSYSTEM_FAILURE] = + SCCP_REFUSAL_SUBSYSTEM_FAILURE, + [SCCP_RETURN_CAUSE_UNEQUIPPED_USER] = + SCCP_REFUSAL_UNEQUIPPED_USER, + [SCCP_RETURN_CAUSE_UNQUALIFIED] = + SCCP_REFUSAL_UNQUALIFIED, + [SCCP_RETURN_CAUSE_SCCP_FAILURE] = + SCCP_REFUSAL_SCCP_FAILURE, + [SCCP_RETURN_CAUSE_HOP_COUNTER_VIOLATION] = + SCCP_REFUSAL_HOP_COUNTER_VIOLATION, +}; + +static uint8_t get_cref_cause_for_ret(uint8_t ret_cause) +{ + if (ret_cause < ARRAY_SIZE(cause_map_cref)) + return cause_map_cref[ret_cause]; + else + return SCCP_REFUSAL_UNQUALIFIED; +} + +/* Generate a COREF message purely based on an incoming SUA message, + * without the use of any local connection state */ +static struct xua_msg *gen_coref_without_conn(struct osmo_sccp_instance *inst, + struct xua_msg *xua_in, + uint32_t ref_cause) +{ + struct xua_msg *xua; + + xua = xua_msg_alloc(); + xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_COREF); + xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, inst->route_ctx); + + xua_msg_copy_part(xua, SUA_IEI_DEST_REF, xua_in, SUA_IEI_SRC_REF); + xua_msg_add_u32(xua, SUA_IEI_CAUSE, SUA_CAUSE_T_REFUSAL | ref_cause); + /* optional: source addr */ + xua_msg_copy_part(xua, SUA_IEI_SRC_ADDR, xua_in, SUA_IEI_DEST_ADDR); + /* conditional: dest addr */ + xua_msg_copy_part(xua, SUA_IEI_DEST_ADDR, xua_in, SUA_IEI_SRC_ADDR); + /* optional: importance */ + xua_msg_copy_part(xua, SUA_IEI_IMPORTANCE, xua_in, SUA_IEI_IMPORTANCE); + /* optional: data */ + xua_msg_copy_part(xua, SUA_IEI_DATA, xua_in, SUA_IEI_DATA); + + return xua; +} + +/*! \brief SCOC: Receive SCRC Routing Failure + * \param[in] inst SCCP Instance on which we operate + * \param[in] xua SUA message that was failed to route + * \param[in] return_cause Reason (cause) for routing failure */ +void sccp_scoc_rx_scrc_rout_fail(struct osmo_sccp_instance *inst, + struct xua_msg *xua, uint32_t return_cause) +{ + uint32_t conn_id; + struct sccp_connection *conn; + + /* try to dispatch to connection FSM (if any) */ + conn_id = xua_msg_get_u32(xua, SUA_IEI_DEST_REF); + conn = conn_find_by_id(inst, conn_id); + if (conn) { + osmo_fsm_inst_dispatch(conn->fi, + SCOC_E_RCOC_ROUT_FAIL_IND, xua); + } else { + /* generate + send CREF directly */ + struct xua_msg *cref; + uint8_t cref_cause = get_cref_cause_for_ret(return_cause); + cref = gen_coref_without_conn(inst, xua, cref_cause); + sccp_scrc_rx_scoc_conn_msg(inst, cref); + xua_msg_free(cref); + } +} + +/* Find a SCCP user for given SUA message (based on SUA_IEI_DEST_ADDR */ +static struct osmo_sccp_user *sccp_find_user(struct osmo_sccp_instance *inst, + struct xua_msg *xua) +{ + int rc; + struct osmo_sccp_addr called_addr; + + rc = sua_addr_parse(&called_addr, xua, SUA_IEI_DEST_ADDR); + if (rc < 0) { + LOGP(DLSCCP, LOGL_ERROR, "Cannot find SCCP User for XUA " + "Message %s without valid DEST_ADDR\n", + xua_hdr_dump(xua, &xua_dialect_sua)); + return NULL; + } + + if (!(called_addr.presence & OSMO_SCCP_ADDR_T_SSN)) { + LOGP(DLSCCP, LOGL_ERROR, "Cannot resolve SCCP User for " + "XUA Message %s without SSN in CalledAddr\n", + xua_hdr_dump(xua, &xua_dialect_sua)); + return NULL; + } + + return sccp_user_find(inst, called_addr.ssn, called_addr.pc); +} + +/* Generate a COERR based in input arguments */ +static struct xua_msg *gen_coerr(uint32_t route_ctx, uint32_t dest_ref, + uint32_t err_cause) +{ + struct xua_msg *xua = xua_msg_alloc(); + + xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_COERR); + xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, route_ctx); + xua_msg_add_u32(xua, SUA_IEI_DEST_REF, dest_ref); + xua_msg_add_u32(xua, SUA_IEI_CAUSE, SUA_CAUSE_T_ERROR | err_cause); + + return xua; +} + +/* generate COERR from incoming XUA and send it */ +static void tx_coerr_from_xua(struct osmo_sccp_instance *inst, + struct xua_msg *in, uint32_t err_cause) +{ + struct xua_msg *xua; + uint32_t route_ctx, dest_ref; + + route_ctx = xua_msg_get_u32(in, SUA_IEI_ROUTE_CTX); + /* get *source* reference and use as destination ref */ + dest_ref = xua_msg_get_u32(in, SUA_IEI_SRC_REF); + + xua = gen_coerr(route_ctx, dest_ref, err_cause); + /* copy over the MTP parameters */ + xua->mtp.dpc = in->mtp.opc; + xua->mtp.opc = in->mtp.dpc; + xua->mtp.sio = in->mtp.sio; + + /* sent to SCRC for transmission */ + sccp_scrc_rx_scoc_conn_msg(inst, xua); + xua_msg_free(xua); +} + +/* Generate a RELCO based in input arguments */ +static struct xua_msg *gen_relco(uint32_t route_ctx, uint32_t dest_ref, + uint32_t src_ref) +{ + struct xua_msg *xua = xua_msg_alloc(); + + xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_RELCO); + xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, route_ctx); + xua_msg_add_u32(xua, SUA_IEI_DEST_REF, dest_ref); + xua_msg_add_u32(xua, SUA_IEI_SRC_REF, src_ref); + + return xua; +} + +/* generate RELCO from incoming XUA and send it */ +static void tx_relco_from_xua(struct osmo_sccp_instance *inst, + struct xua_msg *in) +{ + struct xua_msg *xua; + uint32_t route_ctx, dest_ref, src_ref; + + route_ctx = xua_msg_get_u32(in, SUA_IEI_ROUTE_CTX); + /* get *source* reference and use as destination ref */ + dest_ref = xua_msg_get_u32(in, SUA_IEI_SRC_REF); + /* get *dest* reference and use as source ref */ + src_ref = xua_msg_get_u32(in, SUA_IEI_DEST_REF); + + xua = gen_relco(route_ctx, dest_ref, src_ref); + /* copy over the MTP parameters */ + xua->mtp.dpc = in->mtp.opc; + xua->mtp.opc = in->mtp.dpc; + xua->mtp.sio = in->mtp.sio; + + /* send to SCRC for transmission */ + sccp_scrc_rx_scoc_conn_msg(inst, xua); + xua_msg_free(xua); +} + +/* Generate a RLSD based in input arguments */ +static struct xua_msg *gen_rlsd(uint32_t route_ctx, uint32_t dest_ref, + uint32_t src_ref) +{ + struct xua_msg *xua = xua_msg_alloc(); + + xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_RELRE); + xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, route_ctx); + xua_msg_add_u32(xua, SUA_IEI_DEST_REF, dest_ref); + xua_msg_add_u32(xua, SUA_IEI_SRC_REF, src_ref); + + return xua; +} + +/* Generate a RLSD to both the remote side and the local conn */ +static void tx_rlsd_from_xua_twoway(struct sccp_connection *conn, + struct xua_msg *in) +{ + struct xua_msg *xua; + uint32_t route_ctx, dest_ref, src_ref; + + route_ctx = xua_msg_get_u32(in, SUA_IEI_ROUTE_CTX); + /* get *source* reference and use as destination ref */ + dest_ref = xua_msg_get_u32(in, SUA_IEI_SRC_REF); + /* get *source* reference and use as destination ref */ + src_ref = xua_msg_get_u32(in, SUA_IEI_DEST_REF); + + /* Generate RLSD towards remote peer */ + xua = gen_rlsd(route_ctx, dest_ref, src_ref); + /* copy over the MTP parameters */ + xua->mtp.dpc = in->mtp.opc; + xua->mtp.opc = in->mtp.dpc; + xua->mtp.sio = in->mtp.sio; + /* send to SCRC for transmission */ + sccp_scrc_rx_scoc_conn_msg(conn->inst, xua); + xua_msg_free(xua); + + /* Generate RLSD towards local peer */ + xua = gen_rlsd(conn->inst->route_ctx, conn->conn_id, conn->remote_ref); + xua->mtp.dpc = in->mtp.dpc; + xua->mtp.opc = conn->remote_pc; + xua->mtp.sio = in->mtp.sio; + osmo_fsm_inst_dispatch(conn->fi, SCOC_E_RCOC_RLSD_IND, xua); + xua_msg_free(xua); +} + +/* process received message for unasigned local reference */ +static void sccp_scoc_rx_unass_local_ref(struct osmo_sccp_instance *inst, + struct xua_msg *xua) +{ + /* we have received a message with unassigned destination local + * reference and thus apply the action indicated in Table + * B.2/Q.714 */ + switch (xua->hdr.msg_type) { + case SUA_CO_COAK: /* CC */ + case SUA_CO_COIT: /* IT */ + case SUA_CO_RESRE: /* RSR */ + case SUA_CO_RESCO: /* RSC */ + /* Send COERR */ + tx_coerr_from_xua(inst, xua, SCCP_ERROR_LRN_MISMATCH_UNASSIGNED); + break; + case SUA_CO_COREF: /* CREF */ + case SUA_CO_RELCO: /* RLC */ + case SUA_CO_CODT: /* DT1 */ + case SUA_CO_CODA: /* AK */ + case SUA_CO_COERR: /* ERR */ + /* DISCARD */ + break; + case SUA_CO_RELRE: /* RLSD */ + /* Send RLC */ + tx_relco_from_xua(inst, xua); + break; + default: + LOGP(DLSCCP, LOGL_NOTICE, "Unhandled %s\n", + xua_hdr_dump(xua, &xua_dialect_sua)); + break; + } +} + +/* process received message for invalid source local reference */ +static void sccp_scoc_rx_inval_src_ref(struct sccp_connection *conn, + struct xua_msg *xua) +{ + /* we have received a message with invalid source local + * reference and thus apply the action indicated in Table + * B.2/Q.714 */ + switch (xua->hdr.msg_type) { + case SUA_CO_RELRE: /* RLSD */ + case SUA_CO_RESRE: /* RSR */ + case SUA_CO_RESCO: /* RSC */ + /* Send ERR */ + tx_coerr_from_xua(conn->inst, xua, SCCP_ERROR_LRN_MISMATCH_INCONSISTENT); + break; + case SUA_CO_COIT: /* IT */ + /* FIXME: RLSD to both sides */ + tx_rlsd_from_xua_twoway(conn, xua); + break; + case SUA_CO_RELCO: /* RLC */ + /* DISCARD */ + break; + default: + LOGP(DLSCCP, LOGL_NOTICE, "Unhandled %s\n", + xua_hdr_dump(xua, &xua_dialect_sua)); + break; + } +} + +/* process received message for invalid origin point code */ +static void sccp_scoc_rx_inval_opc(struct osmo_sccp_instance *inst, + struct xua_msg *xua) +{ + /* we have received a message with invalid origin PC and thus + * apply the action indiacted in Table B.2/Q.714 */ + switch (xua->hdr.msg_type) { + case SUA_CO_RELRE: /* RLSD */ + case SUA_CO_RESRE: /* RSR */ + case SUA_CO_RESCO: /* RSC */ + /* Send ERR */ + tx_coerr_from_xua(inst, xua, SCCP_ERROR_POINT_CODE_MISMATCH); + break; + case SUA_CO_RELCO: /* RLC */ + case SUA_CO_CODT: /* DT1 */ + case SUA_CO_CODA: /* AK */ + case SUA_CO_COERR: /* ERR */ + /* DISCARD */ + break; + default: + LOGP(DLSCCP, LOGL_NOTICE, "Unhandled %s\n", + xua_hdr_dump(xua, &xua_dialect_sua)); + break; + } +} + +/*! \brief Main entrance function for primitives from the SCRC (Routing Control) + * \param[in] inst SCCP Instance in which we operate + * \param[in] xua SUA message in xua_msg format */ +void sccp_scoc_rx_from_scrc(struct osmo_sccp_instance *inst, + struct xua_msg *xua) +{ + struct sccp_connection *conn; + struct osmo_sccp_user *scu; + uint32_t src_loc_ref; + int event; + + /* we basically try to convert the SUA message into an event, + * and then dispatch the event to the connection-specific FSM. + * If it is a CORE (Connect REquest), we create the connection + * (and imlpicitly its FSM) first */ + + if (xua->hdr.msg_type == SUA_CO_CORE) { + scu = sccp_find_user(inst, xua); + if (!scu) { + /* this shouldn't happen, as the caller should + * have already verified that a local user is + * equipped for this SSN */ + LOGP(DLSCCP, LOGL_ERROR, "Cannot find user for " + "CORE ?!?\n"); + return; + } + /* Allocate new connection */ + conn = conn_create(inst); + conn->user = scu; + } else { + uint32_t conn_id; + /* Resolve existing connection */ + conn_id = xua_msg_get_u32(xua, SUA_IEI_DEST_REF); + conn = conn_find_by_id(inst, conn_id); + if (!conn) { + LOGP(DLSCCP, LOGL_NOTICE, "Cannot find connection for " + "local reference %u\n", conn_id); + sccp_scoc_rx_unass_local_ref(inst, xua); + return; + } + } + OSMO_ASSERT(conn); + OSMO_ASSERT(conn->fi); + + DEBUGP(DLSCCP, "Received %s for local reference %u\n", + xua_hdr_dump(xua, &xua_dialect_sua), conn->conn_id); + + if (xua->hdr.msg_type != SUA_CO_CORE && + xua->hdr.msg_type != SUA_CO_COAK && + xua->hdr.msg_type != SUA_CO_COREF) { + if (xua_msg_find_tag(xua, SUA_IEI_SRC_REF)) { + /* Check if received source local reference != + * the one we saved in local state */ + src_loc_ref = xua_msg_get_u32(xua, SUA_IEI_SRC_REF); + if (src_loc_ref != conn->remote_ref) { + sccp_scoc_rx_inval_src_ref(conn, xua); + return; + } + } + + /* Check if received OPC != the remote_pc we stored locally */ + if (xua->mtp.opc != conn->remote_pc) { + sccp_scoc_rx_inval_opc(inst, xua); + return; + } + } + + /* Map from XUA message to event */ + event = xua_msg_event_map(xua, sua_scoc_event_map, ARRAY_SIZE(sua_scoc_event_map)); + if (event < 0) { + LOGP(DLSCCP, LOGL_ERROR, "Cannot map SCRC msg %s to event\n", + xua_hdr_dump(xua, &xua_dialect_sua)); + /* Table B.1/Q714 states DISCARD for any message with + * unknown type */ + return; + } + + /* Dispatch event to existing connection */ + osmo_fsm_inst_dispatch(conn->fi, event, xua); +} + +/* get the Connection ID of the given SCU primitive */ +static uint32_t scu_prim_conn_id(const struct osmo_scu_prim *prim) +{ + switch (prim->oph.primitive) { + case OSMO_SCU_PRIM_N_CONNECT: + return prim->u.connect.conn_id; + case OSMO_SCU_PRIM_N_DATA: + return prim->u.data.conn_id; + case OSMO_SCU_PRIM_N_DISCONNECT: + return prim->u.disconnect.conn_id; + case OSMO_SCU_PRIM_N_RESET: + return prim->u.reset.conn_id; + default: + return 0; + } +} + +/*! \brief Main entrance function for primitives from SCCP User + * \param[in] scu SCCP User sending us the primitive + * \param[in] oph Osmocom primitive sent by the user + * \returns 0 on success; negative on error */ +int osmo_sccp_user_sap_down(struct osmo_sccp_user *scu, struct osmo_prim_hdr *oph) +{ + struct osmo_scu_prim *prim = (struct osmo_scu_prim *) oph; + struct osmo_sccp_instance *inst = scu->inst; + struct msgb *msg = prim->oph.msg; + struct sccp_connection *conn; + int rc = 0; + int event; + + LOGP(DLSCCP, LOGL_DEBUG, "Received SCCP User Primitive %s)\n", + osmo_scu_prim_name(&prim->oph)); + + switch (OSMO_PRIM_HDR(&prim->oph)) { + case OSMO_PRIM(OSMO_SCU_PRIM_N_UNITDATA, PRIM_OP_REQUEST): + /* other CL primitives? */ + /* Connectionless by-passes this altogether */ + return sccp_sclc_user_sap_down(scu, oph); + case OSMO_PRIM(OSMO_SCU_PRIM_N_CONNECT, PRIM_OP_REQUEST): + /* Allocate new connection structure */ + conn = conn_create_id(inst, prim->u.connect.conn_id); + if (!conn) { + /* FIXME: inform user */ + goto out; + } + conn->user = scu; + break; + case OSMO_PRIM(OSMO_SCU_PRIM_N_CONNECT, PRIM_OP_RESPONSE): + case OSMO_PRIM(OSMO_SCU_PRIM_N_DATA, PRIM_OP_REQUEST): + case OSMO_PRIM(OSMO_SCU_PRIM_N_DISCONNECT, PRIM_OP_REQUEST): + case OSMO_PRIM(OSMO_SCU_PRIM_N_RESET, PRIM_OP_REQUEST): + /* Resolve existing connection structure */ + conn = conn_find_by_id(inst, scu_prim_conn_id(prim)); + if (!conn) { + /* FIXME: inform user */ + goto out; + } + break; + } + + /* Map from primitive to event */ + event = osmo_event_for_prim(oph, scu_scoc_event_map); + + /* Dispatch event into connection */ + rc = osmo_fsm_inst_dispatch(conn->fi, event, prim); +out: + /* the SAP is supposed to consume the primitive/msgb */ + msgb_free(msg); + + return rc; +} + +void sccp_scoc_flush_connections(struct osmo_sccp_instance *inst) +{ + struct sccp_connection *conn, *conn2; + + llist_for_each_entry_safe(conn, conn2, &inst->connections, list) + conn_destroy(conn); +} diff --git a/src/sccp_scrc.c b/src/sccp_scrc.c new file mode 100644 index 0000000..9bccc0a --- /dev/null +++ b/src/sccp_scrc.c @@ -0,0 +1,473 @@ +/* SCCP Routing Control (SCRC) according to ITU-T Q.714 */ + +/* (C) 2015-2017 by Harald Welte + * All Rights reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include "sccp_internal.h" +#include "xua_internal.h" + +/*********************************************************************** + * Helper Functions + ***********************************************************************/ + +static bool sua_is_connectionless(struct xua_msg *xua) +{ + if (xua->hdr.msg_class == SUA_MSGC_CL) + return true; + else + return false; +} + +static bool sua_is_cr(struct xua_msg *xua) +{ + if (xua->hdr.msg_class == SUA_MSGC_CO && + xua->hdr.msg_type == SUA_CO_CORE) + return true; + + return false; +} + +static bool dpc_accessible(struct osmo_sccp_instance *inst, uint32_t pc) +{ + /* TODO: implement this! */ + return true; +} + +static bool sccp_available(struct osmo_sccp_instance *inst, + const struct osmo_sccp_addr *addr) +{ + /* TODO: implement this! */ + return true; +} + +static int sua2sccp_tx_m3ua(struct osmo_sccp_instance *inst, + struct xua_msg *sua) +{ + struct msgb *msg; + struct osmo_mtp_prim *omp; + struct osmo_mtp_transfer_param *param; + struct osmo_ss7_instance *s7i = inst->ss7; + uint32_t remote_pc = sua->mtp.dpc; + + /* 1) encode the SUA in xua_msg to SCCP message */ + msg = osmo_sua_to_sccp(sua); + if (!msg) { + LOGP(DLSCCP, LOGL_ERROR, "Cannot encode SUA to SCCP\n"); + return -1; + } + + /* 2) wrap into MTP-TRANSFER.req primtiive */ + msg->l2h = msg->data; + omp = (struct osmo_mtp_prim *) msgb_push(msg, sizeof(*omp)); + osmo_prim_init(&omp->oph, MTP_SAP_USER, + OSMO_MTP_PRIM_TRANSFER, PRIM_OP_REQUEST, msg); + param = &omp->u.transfer; + if (sua->mtp.opc) + param->opc = sua->mtp.opc; + else + param->opc = s7i->cfg.primary_pc; + param->dpc = remote_pc; + param->sls = sua->mtp.sls; + param->sio = MTP_SIO(MTP_SI_SCCP, s7i->cfg.network_indicator); + + /* 3) send via MTP-SAP (osmo_ss7_instance) */ + return osmo_ss7_user_mtp_xfer_req(s7i, omp); +} + +/* Gererate MTP-TRANSFER.req from xUA message */ +static int gen_mtp_transfer_req_xua(struct osmo_sccp_instance *inst, + struct xua_msg *xua, + const struct osmo_sccp_addr *called) +{ + struct osmo_ss7_route *rt; + + /* this is a bit fishy due to the different requirements of + * classic SSCP/MTP compared to various SIGTRAN stackings. + * Normally, we would expect a fully encoded SCCP message here, + * but then if the route points to a SUA link, we actually need + * the SUA version of the message. + * + * We need to differentiate the following cases: + * a) SUA: encode XUA to SUA and send via ASP + * b) M3UA: encode XUA to SCCP, create MTP-TRANSFER.req + * primitive and send it via ASP + * c) M2UA/M2PA or CS7: encode XUA, create MTP-TRANSFER.req + * primitive and send it via link + */ + + if (called->presence & OSMO_SCCP_ADDR_T_PC) + xua->mtp.dpc = called->pc; + if (!xua->mtp.dpc) { + LOGP(DLSCCP, LOGL_ERROR, "MTP-TRANSFER.req from SCCP " + "without DPC?!?\n"); + return -1; + } + + rt = osmo_ss7_route_lookup(inst->ss7, xua->mtp.dpc); + if (!rt) { + LOGP(DLSCCP, LOGL_ERROR, "MTP-TRANSFER.req from SCCP for " + "DPC %u: no route!\n", xua->mtp.dpc); + return -1; + } + + if (rt->dest.as) { + struct osmo_ss7_as *as = rt->dest.as; + switch (as->cfg.proto) { + case OSMO_SS7_ASP_PROT_M3UA: + return sua2sccp_tx_m3ua(inst, xua); + default: + LOGP(DLSCCP, LOGL_ERROR, "MTP-TRANSFER.req for " + "unknown protocol %u\n", as->cfg.proto); + break; + } + } else if (rt->dest.linkset) { + LOGP(DLSCCP, LOGL_ERROR, "MTP-TRANSFER.req from SCCP for " + "linkset %s unsupported\n", rt->dest.linkset->cfg.name); + } else { + OSMO_ASSERT(0); + } + return -1; +} + +/*********************************************************************** + * Global Title Translation + ***********************************************************************/ + +static int translate(struct osmo_sccp_instance *inst, + const struct osmo_sccp_addr *called, + struct osmo_sccp_addr *translated) +{ + /* TODO: implement this! */ + *translated = *called; + return 0; +} + + +/*********************************************************************** + * Individual SCRC Nodes + ***********************************************************************/ + +static int scrc_local_out_common(struct osmo_sccp_instance *inst, + struct xua_msg *xua, + const struct osmo_sccp_addr *called); + +static int scrc_node_12(struct osmo_sccp_instance *inst, struct xua_msg *xua, + const struct osmo_sccp_addr *called) +{ + /* TODO: Determine restriction */ + /* TODO: Treat Calling Party Addr */ + /* TODO: Hop counter */ + /* MTP-TRANSFER.req to MTP */ + return gen_mtp_transfer_req_xua(inst, xua, called); +} + +static int scrc_node_2(struct osmo_sccp_instance *inst, struct xua_msg *xua, + const struct osmo_sccp_addr *called) +{ + /* Node 2 on Sheet 5, only CO */ + /* Is DPC accessible? */ + if (!dpc_accessible(inst, called->pc)) { + /* Error: MTP Failure */ + /* Routing Failure SCRC -> SCOC */ + sccp_scoc_rx_scrc_rout_fail(inst, xua, + SCCP_RETURN_CAUSE_MTP_FAILURE); + return 0; + } + /* Is SCCP available? */ + if (!sccp_available(inst, called)) { + /* Error: SCCP Failure */ + /* Routing Failure SCRC -> SCOC */ + sccp_scoc_rx_scrc_rout_fail(inst, xua, + SCCP_RETURN_CAUSE_SCCP_FAILURE); + return 0; + } + return scrc_node_12(inst, xua, called); +} + +static int scrc_node_7(struct osmo_sccp_instance *inst, + struct xua_msg *xua, + const struct osmo_sccp_addr *called) +{ + /* Connection Oriented? */ + if (sua_is_connectionless(xua)) { + /* TODO: Perform Capability Test */ + /* TODO: Canges Needed? */ + if (0) { + /* Changes Needed -> SCLC */ + return 0; + } + } else { + /* TODO: Coupling Required? */ + if (0) { + /* Node 13 (Sheet 5) */ + } + } + return scrc_node_12(inst, xua, called); +} + +/* Node 4 (Sheet 3) */ +static int scrc_node_4(struct osmo_sccp_instance *inst, + struct xua_msg *xua, uint32_t return_cause) +{ + /* TODO: Routing Failure SCRC -> OMAP */ + if (sua_is_connectionless(xua)) { + /* Routing Failure SCRC -> SCLC */ + sccp_sclc_rx_scrc_rout_fail(inst, xua, return_cause); + } else { + /* Routing Failure SCRC -> SCOC */ + sccp_scoc_rx_scrc_rout_fail(inst, xua, return_cause); + } + return 0; +} + +static int scrc_translate_node_9(struct osmo_sccp_instance *inst, + struct xua_msg *xua, + const struct osmo_sccp_addr *called) +{ + struct osmo_sccp_addr translated; + int rc; + + /* Translate */ + rc = translate(inst, called, &translated); + /* Node 9 (Sheet 3) */ + if (rc < 0) { + /* Node 4 (Sheet 3) */ + return scrc_node_4(inst, xua, + SCCP_RETURN_CAUSE_NO_TRANSLATION); + } + /* Route on SSN? */ + if (translated.ri != OSMO_SCCP_RI_SSN_PC && + translated.ri != OSMO_SCCP_RI_SSN_IP) { + /* TODO: GT Routing */ + /* Node 7 (Sheet 5) */ + return scrc_node_7(inst, xua, called); + } + + /* Check DPC resultant from GT translation */ + if (osmo_ss7_pc_is_local(inst->ss7, translated.pc)) { + if (sua_is_connectionless(xua)) { + /* CL_MSG -> SCLC */ + sccp_sclc_rx_from_scrc(inst, xua); + } else { + /* Node 1 (Sheet 3) */ + /* CO_MSG -> SCOC */ + sccp_scoc_rx_from_scrc(inst, xua); + } + return 0; + } else { + /* Availability already checked */ + /* Node 7 (Sheet 5) */ + return scrc_node_7(inst, xua, called); + } +} + +/* Node 6 (Sheet 3) */ +static int scrc_node_6(struct osmo_sccp_instance *inst, + struct xua_msg *xua, + const struct osmo_sccp_addr *called) +{ + struct osmo_sccp_user *scu; + + scu = sccp_user_find(inst, called->ssn, called->pc); + + /* Is subsystem equipped? */ + if (!scu) { + /* Error: unequipped user */ + return scrc_node_4(inst, xua, + SCCP_RETURN_CAUSE_UNEQUIPPED_USER); + } + /* Is subsystem available? */ + if (0 /* !subsys_available(scu) */) { + /* Error: subsystem failure */ + /* TODO: SCRC -> SSPC */ + if (sua_is_connectionless(xua)) { + /* Routing Failure SCRC -> SCLC */ + sccp_sclc_rx_scrc_rout_fail(inst, xua, + SCCP_RETURN_CAUSE_SUBSYSTEM_FAILURE); + } else { + /* Routing Failure SCRC -> SCOC */ + sccp_scoc_rx_scrc_rout_fail(inst, xua, + SCCP_RETURN_CAUSE_SUBSYSTEM_FAILURE); + } + return 0; + } + if (sua_is_connectionless(xua)) { + /* CL_MSG -> SCLC */ + sccp_sclc_rx_from_scrc(inst, xua); + } else { + /* Node 1 (Sheet 3) */ + /* CO_MSG -> SCOC */ + sccp_scoc_rx_from_scrc(inst, xua); + } + return 0; +} + +static int scrc_local_out_common(struct osmo_sccp_instance *inst, + struct xua_msg *xua, + const struct osmo_sccp_addr *called) +{ + struct osmo_ss7_instance *s7i = inst->ss7; + + /* Called address includes DPC? */ + if (called->presence & OSMO_SCCP_ADDR_T_PC) { + if (!osmo_ss7_pc_is_local(s7i, called->pc)) { + /* Node 7 of sheet 5 */ + /* Coupling required: no */ + return scrc_node_12(inst, xua, called); + } + /* Called address includes SSN? */ + if (called->presence & OSMO_SCCP_ADDR_T_SSN) { + if (translate && + (called->presence & OSMO_SCCP_ADDR_T_GT)) + return scrc_translate_node_9(inst, xua, called); + else + return scrc_node_6(inst, xua, called); + } + } + /* No SSN in CalledAddr or no DPC included */ + if (!(called->presence & OSMO_SCCP_ADDR_T_GT)) { + /* Error reason: Unqualified */ + /* TODO: Routing Failure SCRC -> OMAP */ + /* Node 4 (Sheet 3) */ + return scrc_node_4(inst, xua, + SCCP_RETURN_CAUSE_UNQUALIFIED); + } else + return scrc_translate_node_9(inst, xua, called); +} + +/*********************************************************************** + * Entrance points from MTP, SCLC, SCOC, ... + ***********************************************************************/ + +/* Figure C.1/Q.714 - SCCP Routing control procedures (SCRC) */ + +/* Connection oriented message SCOC -> SCRC */ +int sccp_scrc_rx_scoc_conn_msg(struct osmo_sccp_instance *inst, + struct xua_msg *xua) +{ + struct osmo_sccp_addr called; + + LOGP(DLSS7, LOGL_DEBUG, "%s: %s\n", __func__, xua_msg_dump(xua, &xua_dialect_sua)); + + sua_addr_parse(&called, xua, SUA_IEI_DEST_ADDR); + + /* Is this a CR message ? */ + if (xua->hdr.msg_type != SUA_CO_CORE) + return scrc_node_2(inst, xua, &called); + + /* TOOD: Coupling performed (not supported) */ + if (0) + return scrc_node_2(inst, xua, &called); + + return scrc_local_out_common(inst, xua, &called); +} + +/* Connectionless Message SCLC -> SCRC */ +int sccp_scrc_rx_sclc_msg(struct osmo_sccp_instance *inst, + struct xua_msg *xua) +{ + struct osmo_sccp_addr called; + + LOGP(DLSS7, LOGL_DEBUG, "%s: %s\n", __func__, xua_msg_dump(xua, &xua_dialect_sua)); + + sua_addr_parse(&called, xua, SUA_IEI_DEST_ADDR); + + /* Message Type */ + if (xua->hdr.msg_type == SUA_CL_CLDR) { + /* UDTS, XUDTS or LUDTS */ + if (called.ri != OSMO_SCCP_RI_GT) + return scrc_node_7(inst, xua, &called); + /* Fall-through */ + } else { + if (0 /* TODO: translation already performed */) { + /* Node 12 (Sheet 5) */ + return scrc_node_12(inst, xua, &called); + } + } + return scrc_local_out_common(inst, xua, &called); +} + +/* Figure C.1/Q.714 Sheet 1 of 12, after we converted the + * MTP-TRANSFER.ind to SUA */ +int scrc_rx_mtp_xfer_ind_xua(struct osmo_sccp_instance *inst, + struct xua_msg *xua) +{ + struct osmo_sccp_addr called; + uint32_t proto_class; + struct xua_msg_part *hop_ctr_part; + + LOGP(DLSS7, LOGL_DEBUG, "%s: %s\n", __func__, xua_msg_dump(xua, &xua_dialect_sua)); + /* TODO: SCCP or nodal congestion? */ + + /* CR or CL message? */ + if (!sua_is_connectionless(xua) && !sua_is_cr(xua)) { + /* Node 1 (Sheet 3) */ + /* deliver to SCOC */ + sccp_scoc_rx_from_scrc(inst, xua); + return 0; + } + /* We only treat connectionless and CR below */ + + sua_addr_parse(&called, xua, SUA_IEI_DEST_ADDR); + + /* Route on GT? */ + if (called.ri != OSMO_SCCP_RI_GT) { + /* Node 6 (Sheet 3) */ + return scrc_node_6(inst, xua, &called); + } + /* Message with hop-counter? */ + hop_ctr_part = xua_msg_find_tag(xua, SUA_IEI_S7_HOP_CTR); + if (hop_ctr_part) { + uint32_t hop_counter = xua_msg_part_get_u32(hop_ctr_part); + if (hop_counter <= 1) { + /* Error: hop-counter violation */ + /* node 4 */ + return scrc_node_4(inst, xua, + SCCP_RETURN_CAUSE_HOP_COUNTER_VIOLATION); + } + /* Decrement hop-counter */ + hop_counter--; + *(uint32_t *)hop_ctr_part->dat = htonl(hop_counter); + } + + /* node 3 (Sheet 2) */ + /* Protocol class 0? */ + proto_class = xua_msg_get_u32(xua, SUA_IEI_PROTO_CLASS); + switch (proto_class) { + case 0: + /* TODO: Assign SLS */ + break; + case 1: + /* TODO: Map incoming SLS to outgoing SLS */ + break; + default: + break; + } + return scrc_translate_node_9(inst, xua, &called); +} diff --git a/src/sccp_user.c b/src/sccp_user.c new file mode 100644 index 0000000..df02486 --- /dev/null +++ b/src/sccp_user.c @@ -0,0 +1,377 @@ +/* SCCP User related routines */ + +/* (C) 2017 by Harald Welte + * All Rights Reserved + * + * based on my 2011 Erlang implementation osmo_ss7/src/sua_sccp_conv.erl + * + * References: ITU-T Q.713 and IETF RFC 3868 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include + +#include +#include + +#include +#include +#include +#include + +#include "sccp_internal.h" +#include "xua_internal.h" + +/*! \brief Find a SCCP User registered for given PC+SSN or SSN only + * \param[in] inst SCCP Instance in which to search + * \param[in] ssn Sub-System Number to search for + * \param[in] pc Point Code to search for + * \returns Matching SCCP User; NULL if none found */ +struct osmo_sccp_user * +sccp_user_find(struct osmo_sccp_instance *inst, uint16_t ssn, uint32_t pc) +{ + struct osmo_sccp_user *scu; + + /* First try to find match for PC + SSN */ + llist_for_each_entry(scu, &inst->users, list) { + if (scu->pc_valid && scu->pc == pc && scu->ssn == ssn) + return scu; + } + + /* Then try to match on SSN only */ + llist_for_each_entry(scu, &inst->users, list) { + if (!scu->pc_valid && scu->ssn == ssn) + return scu; + } + + return NULL; +} + +/*! \brief Bind a SCCP User to a given Point Code + * \param[in] inst SCCP Instance + * \param[in] name human-readable name + * \param[in] ssn Sub-System Number to bind to + * \param[in] pc Point Code to bind to (if any) + * \param[in] pc_valid Whether or not \ref pc is valid/used + * \returns Callee-allocated SCCP User on success; negative otherwise */ +static struct osmo_sccp_user * +sccp_user_bind_pc(struct osmo_sccp_instance *inst, const char *name, + osmo_prim_cb prim_cb, uint16_t ssn, uint32_t pc, bool pc_valid) +{ + struct osmo_sccp_user *scu; + if (!pc_valid) + pc = 0; + + if (sccp_user_find(inst, ssn, pc)) + return NULL; + + LOGP(DLSCCP, LOGL_INFO, "Binding user '%s' to SSN=%u PC=%u (pc_valid=%u)\n", + name, ssn, pc, pc_valid); + + scu = talloc_zero(inst, struct osmo_sccp_user); + scu->name = talloc_strdup(scu, name); + scu->inst = inst; + scu->prim_cb = prim_cb; + scu->ssn = ssn; + scu->pc = pc; + scu->pc_valid = pc_valid; + llist_add_tail(&scu->list, &inst->users); + + return scu; +} + +/*! \brief Bind a given SCCP User to a given SSN+PC + * \param[in] inst SCCP Instance + * \param[in] name human-readable name + * \param[in] ssn Sub-System Number to bind to + * \param[in] pc Point Code to bind to (if any) + * \returns Callee-allocated SCCP User on success; negative otherwise */ +struct osmo_sccp_user * +osmo_sccp_user_bind_pc(struct osmo_sccp_instance *inst, const char *name, + osmo_prim_cb prim_cb, uint16_t ssn, uint32_t pc) +{ + return sccp_user_bind_pc(inst, name, prim_cb, ssn, pc, true); +} + +/*! \brief Bind a given SCCP User to a given SSN (at any PC) + * \param[in] inst SCCP Instance + * \param[in] name human-readable name + * \param[in] ssn Sub-System Number to bind to + * \returns Callee-allocated SCCP User on success; negative otherwise */ +struct osmo_sccp_user * +osmo_sccp_user_bind(struct osmo_sccp_instance *inst, const char *name, + osmo_prim_cb prim_cb, uint16_t ssn) +{ + return sccp_user_bind_pc(inst, name, prim_cb, ssn, 0, false); +} + +/*! \brief Unbind a given SCCP user + * \param[in] scu SCCP User which is to be un-bound. Will be destroyed + * at the time this function returns. */ +void osmo_sccp_user_unbind(struct osmo_sccp_user *scu) +{ + LOGP(DLSCCP, LOGL_INFO, "Unbinding user '%s' from SSN=%u PC=%u " + "(pc_valid=%u)\n", scu->name, scu->ssn, scu->pc, + scu->pc_valid); + /* FIXME: free/release all connections held by this user? */ + llist_del(&scu->list); + talloc_free(scu); +} + +/*! \brief Send a SCCP User SAP Primitive up to the User + * \param[in] scu SCCP User to whom to send the primitive + * \param[in] prim Primitive to send to the user + * \returns return value of the SCCP User's prim_cb() function */ +int sccp_user_prim_up(struct osmo_sccp_user *scu, struct osmo_scu_prim *prim) +{ + LOGP(DLSCCP, LOGL_DEBUG, "Delivering %s to SCCP User '%s'\n", + osmo_scu_prim_name(&prim->oph), scu->name); + return scu->prim_cb(&prim->oph, scu); +} + +/* prim_cb handed to MTP code for incoming MTP-TRANSFER.ind */ +static int mtp_user_prim_cb(struct osmo_prim_hdr *oph, void *ctx) +{ + struct osmo_sccp_instance *inst = ctx; + struct osmo_mtp_prim *omp = (struct osmo_mtp_prim *)oph; + struct xua_msg *xua; + + OSMO_ASSERT(oph->sap == MTP_SAP_USER); + + switch OSMO_PRIM(oph->primitive, oph->operation) { + case OSMO_PRIM(OSMO_MTP_PRIM_TRANSFER, PRIM_OP_INDICATION): + /* Convert from SCCP to SUA in xua_msg format */ + xua = osmo_sccp_to_xua(oph->msg); + xua->mtp = omp->u.transfer; + /* hand this primitive into SCCP via the SCRC code */ + return scrc_rx_mtp_xfer_ind_xua(inst, xua); + default: + LOGP(DLSCCP, LOGL_ERROR, "Unknown primitive %u:%u receivd\n", + oph->primitive, oph->operation); + return -1; + } +} + +static LLIST_HEAD(sccp_instances); + +/*! \brief create a SCCP Instance and register it as user with SS7 inst + * \param[in] ss7 SS7 instance to which this SCCP instance belongs + * \param[in] priv private data to be stored within SCCP instance + * \returns callee-allocated SCCP instance on success; NULL on error */ +struct osmo_sccp_instance * +osmo_sccp_instance_create(struct osmo_ss7_instance *ss7, void *priv) +{ + struct osmo_sccp_instance *inst; + + inst = talloc_zero(ss7, struct osmo_sccp_instance); + if (!inst) + return NULL; + + inst->ss7 = ss7; + inst->priv = priv; + INIT_LLIST_HEAD(&inst->connections); + INIT_LLIST_HEAD(&inst->users); + + inst->ss7_user.inst = ss7; + inst->ss7_user.name = "SCCP"; + inst->ss7_user.prim_cb = mtp_user_prim_cb; + inst->ss7_user.priv = inst; + + osmo_ss7_user_register(ss7, MTP_SI_SCCP, &inst->ss7_user); + + llist_add_tail(&inst->list, &sccp_instances); + + return inst; +} + +void osmo_sccp_instance_destroy(struct osmo_sccp_instance *inst) +{ + struct osmo_sccp_user *scu, *scu2; + + inst->ss7->sccp = NULL; + osmo_ss7_user_unregister(inst->ss7, MTP_SI_SCCP, &inst->ss7_user); + + llist_for_each_entry_safe(scu, scu2, &inst->users, list) { + osmo_sccp_user_unbind(scu); + } + sccp_scoc_flush_connections(inst); + llist_del(&inst->list); + talloc_free(inst); +} + +/*********************************************************************** + * Convenience function for CLIENT + ***********************************************************************/ + +struct osmo_sccp_instance * +osmo_sccp_simple_client(void *ctx, const char *name, uint32_t pc, + enum osmo_ss7_asp_protocol prot, + int local_port, int remote_port, const char *remote_ip) +{ + struct osmo_ss7_instance *ss7; + struct osmo_ss7_as *as; + struct osmo_ss7_route *rt; + struct osmo_ss7_asp *asp; + char *as_name, *asp_name; + + if (!remote_port || remote_port < 0) + remote_port = osmo_ss7_asp_protocol_port(prot); + if (local_port < 0) + local_port = osmo_ss7_asp_protocol_port(prot); + + /* allocate + initialize SS7 instance */ + ss7 = osmo_ss7_instance_find_or_create(ctx, 1); + if (!ss7) + return NULL; + ss7->cfg.primary_pc = pc; + + as_name = talloc_asprintf(ctx, "as-clnt-%s", name); + asp_name = talloc_asprintf(ctx, "asp-clnt-%s", name); + + /* application server */ + as = osmo_ss7_as_find_or_create(ss7, as_name, prot); + if (!as) + goto out_strings; + + /* install default route */ + rt = osmo_ss7_route_create(ss7->rtable_system, 0, 0, as_name); + if (!rt) + goto out_as; + talloc_free(as_name); + + /* application server process */ + asp = osmo_ss7_asp_find_or_create(ss7, asp_name, remote_port, local_port, + prot); + if (!asp) + goto out_rt; + asp->cfg.remote.host = talloc_strdup(asp, remote_ip); + osmo_ss7_as_add_asp(as, asp_name); + talloc_free(asp_name); + osmo_ss7_asp_restart(asp); + + /* Allocate SCCP stack + SCCP user */ + ss7->sccp = osmo_sccp_instance_create(ss7, NULL); + if (!ss7->sccp) + goto out_asp; + + return ss7->sccp; + +out_asp: + osmo_ss7_asp_destroy(asp); +out_rt: + osmo_ss7_route_destroy(rt); +out_as: + osmo_ss7_as_destroy(as); +out_strings: + talloc_free(as_name); + talloc_free(asp_name); + osmo_ss7_instance_destroy(ss7); + + return NULL; +} + +/*********************************************************************** + * Convenience function for SERVER + ***********************************************************************/ + +struct osmo_sccp_instance * +osmo_sccp_simple_server(void *ctx, uint32_t pc, + enum osmo_ss7_asp_protocol prot, int local_port, + const char *local_ip) +{ + struct osmo_ss7_instance *ss7; + struct osmo_xua_server *xs; + + if (local_port < 0) + local_port = osmo_ss7_asp_protocol_port(prot); + + /* allocate + initialize SS7 instance */ + ss7 = osmo_ss7_instance_find_or_create(ctx, 1); + if (!ss7) + return NULL; + ss7->cfg.primary_pc = pc; + + xs = osmo_ss7_xua_server_create(ss7, prot, local_port, local_ip); + if (!xs) + goto out_ss7; + + /* Allocate SCCP stack */ + ss7->sccp = osmo_sccp_instance_create(ss7, NULL); + if (!ss7->sccp) + goto out_xs; + + return ss7->sccp; + +out_xs: + osmo_ss7_xua_server_destroy(xs); +out_ss7: + osmo_ss7_instance_destroy(ss7); + + return NULL; +} + +struct osmo_sccp_instance * +osmo_sccp_simple_server_add_clnt(struct osmo_sccp_instance *inst, + enum osmo_ss7_asp_protocol prot, + const char *name, uint32_t pc, + int local_port, int remote_port, + const char *remote_ip) +{ + struct osmo_ss7_instance *ss7 = inst->ss7; + struct osmo_ss7_as *as; + struct osmo_ss7_route *rt; + struct osmo_ss7_asp *asp; + char *as_name, *asp_name; + + if (local_port < 0) + local_port = osmo_ss7_asp_protocol_port(prot); + + if (remote_port < 0) + remote_port = osmo_ss7_asp_protocol_port(prot); + + as_name = talloc_asprintf(ss7, "as-srv-%s", name); + asp_name = talloc_asprintf(ss7, "asp-srv-%s", name); + + /* application server */ + as = osmo_ss7_as_find_or_create(ss7, as_name, prot); + if (!as) + goto out_strings; + talloc_free(as_name); + + /* route only selected PC to the client */ + rt = osmo_ss7_route_create(ss7->rtable_system, pc, 0xffff, as_name); + if (!rt) + goto out_as; + + asp = osmo_ss7_asp_find_or_create(ss7, asp_name, remote_port, local_port, prot); + if (!asp) + goto out_rt; + asp->cfg.is_server = true; + osmo_ss7_as_add_asp(as, asp_name); + talloc_free(asp_name); + osmo_ss7_asp_restart(asp); + + return ss7->sccp; + +out_rt: + osmo_ss7_route_destroy(rt); +out_as: + osmo_ss7_as_destroy(as); +out_strings: + talloc_free(as_name); + talloc_free(asp_name); + + return NULL; +} -- To view, visit https://gerrit.osmocom.org/2215 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I916e895d9a4914b05483fe12ab5251f206d10dee Gerrit-PatchSet: 7 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Apr 10 09:52:55 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 09:52:55 +0000 Subject: libosmo-sccp[master]: Add new SCCP implementation In-Reply-To: References: Message-ID: Patch Set 7: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2215 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I916e895d9a4914b05483fe12ab5251f206d10dee Gerrit-PatchSet: 7 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Mon Apr 10 09:53:36 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 09:53:36 +0000 Subject: libosmo-sccp[master]: sccp_scoc: Move osmo_prim_event_map to libosmocore In-Reply-To: References: Message-ID: Patch Set 4: -Code-Review -- To view, visit https://gerrit.osmocom.org/2255 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ic1f22ae2e8d786bfe4bbb84e8eb9f8ae4d93d899 Gerrit-PatchSet: 4 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Mon Apr 10 09:54:07 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 09:54:07 +0000 Subject: [ABANDON] libosmo-sccp[master]: sccp_scoc: Move osmo_prim_event_map to libosmocore In-Reply-To: References: Message-ID: Harald Welte has abandoned this change. Change subject: sccp_scoc: Move osmo_prim_event_map to libosmocore ...................................................................... Abandoned as the libosmcore change has already been merged to master, this change had to be merged into the main "new SCCP implementation' patch -- To view, visit https://gerrit.osmocom.org/2255 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: abandon Gerrit-Change-Id: Ic1f22ae2e8d786bfe4bbb84e8eb9f8ae4d93d899 Gerrit-PatchSet: 4 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Apr 10 09:54:53 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 09:54:53 +0000 Subject: libosmo-sccp[master]: sua: Extend address parsing with GT, RI and IPv4 support In-Reply-To: References: Message-ID: Patch Set 6: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2211 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I186df77cbdbedfe1a60b855be3626b6766f4681c Gerrit-PatchSet: 6 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Mon Apr 10 10:15:13 2017 From: gerrit-no-reply at lists.osmocom.org (Holger Freyther) Date: Mon, 10 Apr 2017 10:15:13 +0000 Subject: [PATCH] libosmo-netif[master]: api doc: Call the variable by the right ("crx") name Message-ID: Review at https://gerrit.osmocom.org/2284 api doc: Call the variable by the right ("crx") name While "ctx" would be consistent with the rest of libosmocore and other places, the "crx" occurs so frequently I don't think it is a typo. So change the API docs to "crx" and leave the code as is. Change-Id: I27ed1178fdbbcf3fc0e1070dc19b4ecf9a327a04 --- M src/datagram.c 1 file changed, 3 insertions(+), 3 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-netif refs/changes/84/2284/1 diff --git a/src/datagram.c b/src/datagram.c index d98221f..ab72f95 100644 --- a/src/datagram.c +++ b/src/datagram.c @@ -98,7 +98,7 @@ } /*! \brief Create an Osmocom datagram transmitter - * \param[in] ctx talloc context from which to allocate memory + * \param[in] crx talloc context from which to allocate memory * This function allocates a new \ref osmo_dgram_tx and initializes * it with default values * \returns Osmocom Datagram Transmitter; NULL on error */ @@ -272,7 +272,7 @@ } /*! \brief Create an Osmocom datagram receiver - * \param[in] ctx talloc context from which to allocate memory + * \param[in] crx talloc context from which to allocate memory * This function allocates a new \ref osmo_dgram_rx and initializes * it with default values * \returns Datagram Receiver; NULL on error */ @@ -393,7 +393,7 @@ /*! \brief Create an Osmocom datagram transceiver (bidirectional) - * \param[in] ctx talloc context from which to allocate memory + * \param[in] crx talloc context from which to allocate memory * This function allocates a new \ref osmo_dgram and initializes * it with default values. Internally, the Transceiver is based on a * tuple of transmitter (\ref osmo_dgram_tx) and receiver (\ref osmo_dgram_rx) -- To view, visit https://gerrit.osmocom.org/2284 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I27ed1178fdbbcf3fc0e1070dc19b4ecf9a327a04 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Holger Freyther From gerrit-no-reply at lists.osmocom.org Mon Apr 10 11:03:00 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 11:03:00 +0000 Subject: [MERGED] libosmo-sccp[master]: sccp_sap license header was missing In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: sccp_sap license header was missing ...................................................................... sccp_sap license header was missing Change-Id: I442634ca74d9c4cd386726a9d6b933a12f45afc5 --- M src/sccp_sap.c 1 file changed, 19 insertions(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/sccp_sap.c b/src/sccp_sap.c index 51598b0..2211f71 100644 --- a/src/sccp_sap.c +++ b/src/sccp_sap.c @@ -1,3 +1,22 @@ +/* SCCP User SAP related routines */ + +/* (C) 2017 by Harald Welte + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + #include #include #include -- To view, visit https://gerrit.osmocom.org/2217 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I442634ca74d9c4cd386726a9d6b933a12f45afc5 Gerrit-PatchSet: 7 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Apr 10 11:03:00 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 11:03:00 +0000 Subject: [MERGED] libosmo-sccp[master]: remove tests/sigtran: it's not a test case In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: remove tests/sigtran: it's not a test case ...................................................................... remove tests/sigtran: it's not a test case in tests/* we have unit tests that are run as part of the autotest suite during 'make check'. The code in tests/sigtran is an example, but not a test. As the API is changing anyway, let's remove it for now and re-introduce actual tests and examples after the changes in API required by the upcoming new SCCP core. Change-Id: Ie471a197856c875eb4987bf9858d757312de24fb --- M configure.ac M tests/Makefile.am D tests/sigtran/Makefile.am D tests/sigtran/sua_client_test.c D tests/sigtran/sua_server_test.c D tests/sigtran/sua_test_common.c D tests/sigtran/sua_test_common.h 7 files changed, 1 insertion(+), 266 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/configure.ac b/configure.ac index ed3e25a..3644d22 100644 --- a/configure.ac +++ b/configure.ac @@ -66,7 +66,6 @@ tests/sccp/Makefile tests/mtp/Makefile tests/m2ua/Makefile - tests/sigtran/Makefile tests/xua/Makefile tests/ss7/Makefile Makefile) diff --git a/tests/Makefile.am b/tests/Makefile.am index 6d3c96f..70e8a00 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,4 +1,4 @@ -SUBDIRS = xua sccp mtp m2ua sigtran ss7 +SUBDIRS = xua sccp mtp m2ua ss7 # The `:;' works around a Bash 3.2 bug when the output is not writeable. $(srcdir)/package.m4: $(top_srcdir)/configure.ac diff --git a/tests/sigtran/Makefile.am b/tests/sigtran/Makefile.am deleted file mode 100644 index 91c0960..0000000 --- a/tests/sigtran/Makefile.am +++ /dev/null @@ -1,11 +0,0 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir) -AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) - -noinst_HEADERS = sua_test_common.h -noinst_PROGRAMS = sua_server_test sua_client_test - -sua_server_test_SOURCES = sua_server_test.c sua_test_common.c -sua_server_test_LDADD = $(top_builddir)/src/libosmo-sigtran.la $(LIBOSMOCORE_LIBS) $(TALLOC_LIBS) - -sua_client_test_SOURCES = sua_client_test.c sua_test_common.c -sua_client_test_LDADD = $(top_builddir)/src/libosmo-sigtran.la $(LIBOSMOCORE_LIBS) $(TALLOC_LIBS) diff --git a/tests/sigtran/sua_client_test.c b/tests/sigtran/sua_client_test.c deleted file mode 100644 index 3cbd937..0000000 --- a/tests/sigtran/sua_client_test.c +++ /dev/null @@ -1,56 +0,0 @@ -#include "sua_test_common.h" - -struct osmo_sccp_user *g_user; -struct osmo_sccp_link *g_link; - -static int sccp_sap_up(struct osmo_prim_hdr *oph, void *link) -{ - struct osmo_scu_prim *prim = (struct osmo_scu_prim *) oph; - struct osmo_prim_hdr *resp = NULL; - uint8_t payload[] = { 0xa1, 0xa2, 0xa3 }; - - printf("sccp_sap_up(%s)\n", osmo_scu_prim_name(oph)); - - switch (OSMO_PRIM_HDR(oph)) { - case OSMO_PRIM(OSMO_SCU_PRIM_N_CONNECT, PRIM_OP_CONFIRM): - printf("N-CONNECT.ind(%u), issuing DATA.req\n", - prim->u.connect.conn_id); - resp = make_dt1_req(prim->u.connect.conn_id, payload, sizeof(payload)); - break; - } - - if (resp) - osmo_sua_user_link_down(link, resp); - - msgb_free(oph->msg); - return 0; -} - - -int main(int argc, char **argv) -{ - void *ctx = talloc_named_const(NULL, 1, "root"); - int rc; - - osmo_sua_set_log_area(DSUA); - - osmo_init_logging(&test_log_info); - - g_user = osmo_sua_user_create(ctx, sccp_sap_up, NULL); - - rc = osmo_sua_client_connect(g_user, "127.0.0.1", 2342); - if (rc < 0) { - exit(1); - } - - g_link = osmo_sua_client_get_link(g_user); - - int i = 8000; - - while (1) { - if (i < 8010) - tx_conn_req(g_link, i++); - //tx_unitdata(g_link); - osmo_select_main(0); - } -} diff --git a/tests/sigtran/sua_server_test.c b/tests/sigtran/sua_server_test.c deleted file mode 100644 index 97b2baf..0000000 --- a/tests/sigtran/sua_server_test.c +++ /dev/null @@ -1,78 +0,0 @@ -#include "sua_test_common.h" - -struct osmo_prim_hdr *make_conn_resp(struct osmo_scu_connect_param *param) -{ - struct msgb *msg = msgb_alloc(1024, "conn_resp"); - struct osmo_scu_prim *prim; - - prim = (struct osmo_scu_prim *) msgb_put(msg, sizeof(*prim)); - osmo_prim_init(&prim->oph, SCCP_SAP_USER, - OSMO_SCU_PRIM_N_CONNECT, - PRIM_OP_RESPONSE, msg); - memcpy(&prim->u.connect, param, sizeof(prim->u.connect)); - return &prim->oph; -} - -static int sccp_sap_up(struct osmo_prim_hdr *oph, void *link) -{ - struct osmo_scu_prim *prim = (struct osmo_scu_prim *) oph; - struct osmo_prim_hdr *resp = NULL; - const uint8_t payload[] = { 0xb1, 0xb2, 0xb3 }; - - printf("sccp_sap_up(%s)\n", osmo_scu_prim_name(oph)); - - switch (OSMO_PRIM_HDR(oph)) { - case OSMO_PRIM(OSMO_SCU_PRIM_N_CONNECT, PRIM_OP_CONFIRM): - /* confirmation of outbound connection */ - break; - case OSMO_PRIM(OSMO_SCU_PRIM_N_CONNECT, PRIM_OP_INDICATION): - /* indication of new inbound connection request*/ - printf("N-CONNECT.ind(X->%u)\n", prim->u.connect.conn_id); - resp = make_conn_resp(&prim->u.connect); - break; - case OSMO_PRIM(OSMO_SCU_PRIM_N_DISCONNECT, PRIM_OP_INDICATION): - /* indication of disconnect */ - printf("N-DISCONNECT.ind(%u)\n", prim->u.disconnect.conn_id); - break; - case OSMO_PRIM(OSMO_SCU_PRIM_N_DATA, PRIM_OP_INDICATION): - /* connection-oriented data received */ - printf("N-DATA.ind(%u, %s)\n", prim->u.data.conn_id, - osmo_hexdump(msgb_l2(oph->msg), msgb_l2len(oph->msg))); - resp = make_dt1_req(prim->u.data.conn_id, payload, sizeof(payload)); - break; - case OSMO_PRIM(OSMO_SCU_PRIM_N_UNITDATA, PRIM_OP_INDICATION): - /* connection-oriented data received */ - printf("N-UNITDATA.ind(%s)\n", - osmo_hexdump(msgb_l2(oph->msg), msgb_l2len(oph->msg))); - tx_unitdata(link); - break; - } - - if (resp) - osmo_sua_user_link_down(link, resp); - - msgb_free(oph->msg); - return 0; -} - -int main(int argc, char **argv) -{ - struct osmo_sccp_user *user; - void *ctx = talloc_named_const(NULL, 1, "root"); - int rc; - - osmo_sua_set_log_area(DSUA); - - osmo_init_logging(&test_log_info); - - user = osmo_sua_user_create(ctx, sccp_sap_up, NULL); - - rc = osmo_sua_server_listen(user, "127.0.0.1", 2342); - if (rc < 0) { - exit(1); - } - - while (1) { - osmo_select_main(0); - } -} diff --git a/tests/sigtran/sua_test_common.c b/tests/sigtran/sua_test_common.c deleted file mode 100644 index db1f5f3..0000000 --- a/tests/sigtran/sua_test_common.c +++ /dev/null @@ -1,87 +0,0 @@ -#include "sua_test_common.h" - -static const struct log_info_cat log_cat[] = { - [DMAIN] = { - .name = "DMAIN", .loglevel = LOGL_DEBUG, .enabled = 1, - .color = "", - .description = "Main program", - }, - [DSUA] = { - .name = "DSUA", .loglevel = LOGL_DEBUG, .enabled = 1, - .color = "", - .description = "SCCP User Adaption", - }, -}; - -const struct log_info test_log_info = { - .cat = log_cat, - .num_cat = ARRAY_SIZE(log_cat), -}; - -int tx_unitdata(struct osmo_sccp_link *link) -{ - struct msgb *msg = msgb_alloc(1024, "tx_unitdata"); - struct osmo_scu_prim *prim; - struct osmo_scu_unitdata_param *param; - uint8_t *cur; - - prim = (struct osmo_scu_prim *) msgb_put(msg, sizeof(*prim)); - param = &prim->u.unitdata; - param->calling_addr.presence = OSMO_SCCP_ADDR_T_SSN; - param->called_addr.presence = OSMO_SCCP_ADDR_T_SSN; - osmo_prim_init(&prim->oph, SCCP_SAP_USER, OSMO_SCU_PRIM_N_UNITDATA, PRIM_OP_REQUEST, msg); - - cur = msg->l2h = msgb_put(msg, 3); - cur[0] = 1; cur[1] = 2; cur[2] = 3; - - return osmo_sua_user_link_down(link, &prim->oph); -} - -static void sccp_make_addr_pc_ssn(struct osmo_sccp_addr *addr, uint32_t pc, uint32_t ssn) -{ - addr->presence = OSMO_SCCP_ADDR_T_SSN | OSMO_SCCP_ADDR_T_PC; - addr->ssn = ssn; - addr->pc = pc; -} - -struct osmo_prim_hdr *make_conn_req(uint32_t conn_id) -{ - struct msgb *msg = msgb_alloc(1024, "conn_req"); - struct osmo_scu_prim *prim; - - prim = (struct osmo_scu_prim *) msgb_put(msg, sizeof(*prim)); - osmo_prim_init(&prim->oph, SCCP_SAP_USER, - OSMO_SCU_PRIM_N_CONNECT, - PRIM_OP_REQUEST, msg); - /* Set SSN for calling and called addr */ - sccp_make_addr_pc_ssn(&prim->u.connect.called_addr, 2, OSMO_SCCP_SSN_RANAP); - sccp_make_addr_pc_ssn(&prim->u.connect.calling_addr, 1, OSMO_SCCP_SSN_RANAP); - prim->u.connect.sccp_class = 2; - prim->u.connect.conn_id = conn_id; - - return &prim->oph; -} - -int tx_conn_req(struct osmo_sccp_link *link, uint32_t conn_id) -{ - struct osmo_prim_hdr *prim = make_conn_req(conn_id); - return osmo_sua_user_link_down(link, prim); -} - -struct osmo_prim_hdr * -make_dt1_req(uint32_t conn_id, const uint8_t *data, unsigned int len) -{ - struct msgb *msg = msgb_alloc(1024, "dt1"); - struct osmo_scu_prim *prim; - - prim = (struct osmo_scu_prim *) msgb_put(msg, sizeof(*prim)); - osmo_prim_init(&prim->oph, SCCP_SAP_USER, - OSMO_SCU_PRIM_N_DATA, - PRIM_OP_REQUEST, msg); - prim->u.data.conn_id = conn_id; - - msg->l2h = msgb_put(msg, len); - memcpy(msg->l2h, data, len); - - return &prim->oph; -} diff --git a/tests/sigtran/sua_test_common.h b/tests/sigtran/sua_test_common.h deleted file mode 100644 index b1883cd..0000000 --- a/tests/sigtran/sua_test_common.h +++ /dev/null @@ -1,32 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include - - -enum log_cat { - DMAIN, - DSUA, - DXUA, -}; - -extern const struct log_info test_log_info; - -int tx_unitdata(struct osmo_sccp_link *link); -int tx_conn_req(struct osmo_sccp_link *link, uint32_t conn_id); - -struct osmo_prim_hdr *make_conn_req(uint32_t conn_id); -struct osmo_prim_hdr *make_dt1_req(uint32_t conn_id, const uint8_t *data, unsigned int len); -- To view, visit https://gerrit.osmocom.org/2216 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ie471a197856c875eb4987bf9858d757312de24fb Gerrit-PatchSet: 7 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Apr 10 11:03:00 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 11:03:00 +0000 Subject: [MERGED] libosmo-sccp[master]: Add new SCCP implementation In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: Add new SCCP implementation ...................................................................... Add new SCCP implementation This is an implementation of SCCP as specified in ITO-T Q.71x, particularly the SCRC (routing), SCLC (Connectionless) and SCOC (Connection Oriented) portions. the elaborate state machines of SCOC are implemented using osmo_fsm, with one state machine for each connection. Interfaces to the top (user application) are the SCCP-USER-SAP and on the bottom (network) side the MTP-USER-SAP as provided by osmo_ss7. Contrary to a straight-forward implementation, the code internally always uses a SUA representation of all messages (in struct xua_msg). This enables us to have one common implementation of all related state machines and use them for both SUA and SCCP. If used with real SCCP wire format, all messages are translated from SCCP to SUA on ingress and translated from SUA to SCCP on egress. As SUA is a super-set of SCCP, this can be done "lossless". Change-Id: I916e895d9a4914b05483fe12ab5251f206d10dee --- M include/osmocom/sigtran/sccp_sap.h M src/Makefile.am M src/osmo_ss7.c M src/sccp_internal.h A src/sccp_sclc.c A src/sccp_scoc.c A src/sccp_scrc.c A src/sccp_user.c 8 files changed, 2,938 insertions(+), 2 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/include/osmocom/sigtran/sccp_sap.h b/include/osmocom/sigtran/sccp_sap.h index 0cc1531..c1464f0 100644 --- a/include/osmocom/sigtran/sccp_sap.h +++ b/include/osmocom/sigtran/sccp_sap.h @@ -222,3 +222,23 @@ #define msgb_scu_prim(msg) ((struct osmo_scu_prim *)(msg)->l1h) char *osmo_scu_prim_name(struct osmo_prim_hdr *oph); + +struct osmo_ss7_instance; +struct osmo_sccp_instance; +struct osmo_sccp_user; + +struct osmo_sccp_instance * +osmo_sccp_instance_create(struct osmo_ss7_instance *ss7, void *priv); +void osmo_sccp_instance_destroy(struct osmo_sccp_instance *inst); + +void osmo_sccp_user_unbind(struct osmo_sccp_user *scu); + +struct osmo_sccp_user * +osmo_sccp_user_bind_pc(struct osmo_sccp_instance *inst, const char *name, + osmo_prim_cb prim_cb, uint16_t ssn, uint32_t pc); + +struct osmo_sccp_user * +osmo_sccp_user_bind(struct osmo_sccp_instance *inst, const char *name, + osmo_prim_cb prim_cb, uint16_t ssn); + +int osmo_sccp_user_sap_down(struct osmo_sccp_user *scu, struct osmo_prim_hdr *oph); diff --git a/src/Makefile.am b/src/Makefile.am index 4455127..a4cfeeb 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -27,7 +27,8 @@ LIBVERSION=0:0:0 libosmo_sigtran_la_SOURCES = sccp_sap.c sua.c m3ua.c xua_msg.c sccp_helpers.c \ - sccp2sua.c \ + sccp2sua.c sccp_scrc.c sccp_sclc.c sccp_scoc.c \ + sccp_user.c \ osmo_ss7.c osmo_ss7_hmrt.c xua_asp_fsm.c xua_as_fsm.c libosmo_sigtran_la_LDFLAGS = -version-info $(LIBVERSION) -no-undefined -export-symbols-regex '^osmo_' libosmo_sigtran_la_LIBADD = $(LIBOSMOCORE_LIBS) $(LIBOSMONETIF_LIBS) $(LIBSCTP_LIBS) diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index 74c54bb..6d0b446 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -41,6 +41,7 @@ #include +#include "sccp_internal.h" #include "xua_internal.h" #include "xua_asp_fsm.h" #include "xua_as_fsm.h" @@ -1483,6 +1484,7 @@ { if (ss7_initialized) return 1; + osmo_fsm_register(&sccp_scoc_fsm); osmo_fsm_register(&xua_as_fsm); osmo_fsm_register(&xua_asp_fsm); ss7_initialized = true; diff --git a/src/sccp_internal.h b/src/sccp_internal.h index 7287a82..c35ef4b 100644 --- a/src/sccp_internal.h +++ b/src/sccp_internal.h @@ -1,5 +1,89 @@ #pragma once -#include +#include +#include +#include +#include + +/* an instance of the SCCP stack */ +struct osmo_sccp_instance { + /* entry in global list of ss7 instances */ + struct llist_head list; + /* list of 'struct sccp_connection' in this instance */ + struct llist_head connections; + /* list of SCCP users in this instance */ + struct llist_head users; + /* routing context to be used in all outbound messages */ + uint32_t route_ctx; + /* next local reference to allocate */ + uint32_t next_id; + struct osmo_ss7_instance *ss7; + void *priv; + + struct osmo_ss7_user ss7_user; +}; + +struct osmo_sccp_user { + /*! \brief entry in list of sccp users of \ref osmo_sccp_instance */ + struct llist_head list; + /*! \brief pointer back to SCCP instance */ + struct osmo_sccp_instance *inst; + /*! \brief human-readable name of this user */ + char *name; + + /*! \brief SSN and/or point code to which we are bound */ + uint16_t ssn; + uint32_t pc; + bool pc_valid; + + /* set if we are a server */ + struct llist_head links; + + /* user call-back function in case of incoming primitives */ + osmo_prim_cb prim_cb; + void *priv; + + /* Application Server FSM Instance */ + struct osmo_fsm_inst *as_fi; +}; + +extern int DSCCP; + +struct xua_msg; + +struct osmo_sccp_user * +sccp_user_find(struct osmo_sccp_instance *inst, uint16_t ssn, uint32_t pc); + +/* Message from SCOC -> SCRC */ +int sccp_scrc_rx_scoc_conn_msg(struct osmo_sccp_instance *inst, + struct xua_msg *xua); + +/* Message from SCLC -> SCRC */ +int sccp_scrc_rx_sclc_msg(struct osmo_sccp_instance *inst, struct xua_msg *xua); + +/* Message from MTP (SUA) -> SCRC */ +int scrc_rx_mtp_xfer_ind_xua(struct osmo_sccp_instance *inst, + struct xua_msg *xua); + +/* Message from SCRC -> SCOC */ +void sccp_scoc_rx_from_scrc(struct osmo_sccp_instance *inst, + struct xua_msg *xua); +void sccp_scoc_rx_scrc_rout_fail(struct osmo_sccp_instance *inst, + struct xua_msg *xua, uint32_t cause); + +void sccp_scoc_flush_connections(struct osmo_sccp_instance *inst); + +/* Message from SCRC -> SCLC */ +int sccp_sclc_rx_from_scrc(struct osmo_sccp_instance *inst, + struct xua_msg *xua); +void sccp_sclc_rx_scrc_rout_fail(struct osmo_sccp_instance *inst, + struct xua_msg *xua, uint32_t cause); + +int sccp_user_prim_up(struct osmo_sccp_user *scut, struct osmo_scu_prim *prim); + +/* SCU -> SCLC */ +int sccp_sclc_user_sap_down(struct osmo_sccp_user *scu, struct osmo_prim_hdr *oph); struct msgb *sccp_msgb_alloc(const char *name); + +struct osmo_fsm sccp_scoc_fsm; diff --git a/src/sccp_sclc.c b/src/sccp_sclc.c new file mode 100644 index 0000000..dae2c36 --- /dev/null +++ b/src/sccp_sclc.c @@ -0,0 +1,337 @@ +/* SCCP Connectionless Control (SCLC) according to ITU-T Q.713/Q.714 */ + +/* (C) 2015-2017 by Harald Welte + * All Rights reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/* This code is a bit of a hybrid between the ITU-T Q.71x specifications + * for SCCP (particularly its connection-oriented part), and the IETF + * RFC 3868 (SUA). The idea here is to have one shared code base of the + * state machines for SCCP Connection Oriented, and use those both from + * SCCP and SUA. + * + * To do so, all SCCP messages are translated to SUA messages in the + * input side, and all generated SUA messages are translated to SCCP on + * the output side. + * + * The Choice of going for SUA messages as the "native" format was based + * on their easier parseability, and the fact that there are features in + * SUA which classic SCCP cannot handle (like IP addresses in GT). + * However, all SCCP features can be expressed in SUA. + * + * The code only supports Class 2. No support for Class 3 is intended, + * but patches are of course alwys welcome. + * + * Missing other features: + * * Segmentation/Reassembly support + * * T(guard) after (re)start + * * freezing of local references + * * parsing/encoding of IPv4/IPv6 addresses + * * use of multiple Routing Contexts in SUA case + */ + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "xua_internal.h" +#include "sccp_internal.h" + +/* generate a 'struct xua_msg' of requested type from primitive data */ +static struct xua_msg *xua_gen_msg_cl(uint32_t event, + struct osmo_scu_prim *prim, int msg_type) +{ + struct xua_msg *xua = xua_msg_alloc(); + struct osmo_scu_unitdata_param *udpar = &prim->u.unitdata; + + if (!xua) + return NULL; + + switch (msg_type) { + case SUA_CL_CLDT: + xua->hdr = XUA_HDR(SUA_MSGC_CL, SUA_CL_CLDT); + xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, 0); /* FIXME */ + xua_msg_add_u32(xua, SUA_IEI_PROTO_CLASS, 0); + xua_msg_add_sccp_addr(xua, SUA_IEI_SRC_ADDR, &udpar->calling_addr); + xua_msg_add_sccp_addr(xua, SUA_IEI_DEST_ADDR, &udpar->called_addr); + xua_msg_add_u32(xua, SUA_IEI_SEQ_CTRL, udpar->in_sequence_control); + /* optional: importance, ... correlation id? */ + if (!prim) + goto prim_needed; + xua_msg_add_data(xua, SUA_IEI_DATA, msgb_l2len(prim->oph.msg), + msgb_l2(prim->oph.msg)); + break; + default: + LOGP(DLSCCP, LOGL_ERROR, "Unknown msg_type %u\n", msg_type); + xua_msg_free(xua); + return NULL; + } + return xua; + +prim_needed: + xua_msg_free(xua); + LOGP(DLSCCP, LOGL_ERROR, "%s must be called with valid 'prim' " + "pointer for msg_type=%u\n", __func__, msg_type); + return NULL; +} + +/* generate xua_msg, encode it and send it to SCRC */ +static int xua_gen_encode_and_send(struct osmo_sccp_user *scu, uint32_t event, + struct osmo_scu_prim *prim, int msg_type) +{ + struct xua_msg *xua; + + xua = xua_gen_msg_cl(event, prim, msg_type); + if (!xua) + return -1; + + return sccp_scrc_rx_sclc_msg(scu->inst, xua); +} + +/*! \brief Main entrance function for primitives from SCCP User + * \param[in] scu SCCP User who is sending the primitive + * \param[on] oph Osmocom primitive header of the primitive + * \returns 0 on success; negtive in case of error */ +int sccp_sclc_user_sap_down(struct osmo_sccp_user *scu, struct osmo_prim_hdr *oph) +{ + struct osmo_scu_prim *prim = (struct osmo_scu_prim *) oph; + struct msgb *msg = prim->oph.msg; + int rc = 0; + + /* we get called from osmo_sccp_user_sap_down() which already + * has debug-logged the primitive */ + + switch (OSMO_PRIM_HDR(&prim->oph)) { + case OSMO_PRIM(OSMO_SCU_PRIM_N_UNITDATA, PRIM_OP_REQUEST): + /* Connectionless by-passes this altogether */ + rc = xua_gen_encode_and_send(scu, -1, prim, SUA_CL_CLDT); + goto out; + default: + LOGP(DLSCCP, LOGL_ERROR, "Received unknown SCCP User " + "primitive %s from user\n", + osmo_scu_prim_name(&prim->oph)); + rc = -1; + goto out; + } + +out: + /* the SAP is supposed to consume the primitive/msgb */ + msgb_free(msg); + + return rc; +} + +/* Process an incoming CLDT message (from a remote peer) */ +static int sclc_rx_cldt(struct osmo_sccp_instance *inst, struct xua_msg *xua) +{ + struct osmo_scu_prim *prim; + struct osmo_scu_unitdata_param *param; + struct xua_msg_part *data_ie = xua_msg_find_tag(xua, SUA_IEI_DATA); + struct msgb *upmsg = sccp_msgb_alloc(__func__); + struct osmo_sccp_user *scu; + uint32_t protocol_class; + + /* fill primitive */ + prim = (struct osmo_scu_prim *) msgb_put(upmsg, sizeof(*prim)); + param = &prim->u.unitdata; + osmo_prim_init(&prim->oph, SCCP_SAP_USER, + OSMO_SCU_PRIM_N_UNITDATA, + PRIM_OP_INDICATION, upmsg); + sua_addr_parse(¶m->called_addr, xua, SUA_IEI_DEST_ADDR); + sua_addr_parse(¶m->calling_addr, xua, SUA_IEI_SRC_ADDR); + param->in_sequence_control = xua_msg_get_u32(xua, SUA_IEI_SEQ_CTRL); + protocol_class = xua_msg_get_u32(xua, SUA_IEI_PROTO_CLASS); + param->return_option = protocol_class & 0x80; + param->importance = xua_msg_get_u32(xua, SUA_IEI_IMPORTANCE); + + scu = sccp_user_find(inst, param->called_addr.ssn, + param->called_addr.pc); + + if (!scu) { + /* FIXME: Send destination unreachable? */ + LOGP(DLSUA, LOGL_NOTICE, "Received SUA message for unequipped SSN %u\n", + param->called_addr.ssn); + msgb_free(upmsg); + return 0; + } + + /* copy data */ + upmsg->l2h = msgb_put(upmsg, data_ie->len); + memcpy(upmsg->l2h, data_ie->dat, data_ie->len); + + /* send to user SAP */ + sccp_user_prim_up(scu, prim); + + /* xua_msg is free'd by our caller */ + return 0; +} + +static int sclc_rx_cldr(struct osmo_sccp_instance *inst, struct xua_msg *xua) +{ + struct osmo_scu_prim *prim; + struct osmo_scu_notice_param *param; + struct xua_msg_part *data_ie = xua_msg_find_tag(xua, SUA_IEI_DATA); + struct msgb *upmsg = sccp_msgb_alloc(__func__); + struct osmo_sccp_user *scu; + + /* fill primitive */ + prim = (struct osmo_scu_prim *) msgb_put(upmsg, sizeof(*prim)); + param = &prim->u.notice; + osmo_prim_init(&prim->oph, SCCP_SAP_USER, + OSMO_SCU_PRIM_N_NOTICE, + PRIM_OP_INDICATION, upmsg); + + sua_addr_parse(¶m->called_addr, xua, SUA_IEI_DEST_ADDR); + sua_addr_parse(¶m->calling_addr, xua, SUA_IEI_SRC_ADDR); + param->importance = xua_msg_get_u32(xua, SUA_IEI_IMPORTANCE); + param->cause = xua_msg_get_u32(xua, SUA_IEI_CAUSE); + + scu = sccp_user_find(inst, param->called_addr.ssn, + param->called_addr.pc); + if (!scu) { + /* FIXME: Send destination unreachable? */ + LOGP(DLSUA, LOGL_NOTICE, "Received CLDR for unequipped SSN %u\n", + param->called_addr.ssn); + msgb_free(upmsg); + return 0; + } + + /* copy data */ + upmsg->l2h = msgb_put(upmsg, data_ie->len); + memcpy(upmsg->l2h, data_ie->dat, data_ie->len); + + /* send to user SAP */ + sccp_user_prim_up(scu, prim); + + /* xua_msg is free'd by our caller */ + return 0; +} + +/*! \brief SCRC -> SCLC (connectionless message) + * \param[in] inst SCCP Instance in which we operate + * \param[in] xua SUA connectionless message + * \returns 0 on success; negative on error */ +int sccp_sclc_rx_from_scrc(struct osmo_sccp_instance *inst, + struct xua_msg *xua) +{ + int rc = -1; + + OSMO_ASSERT(xua->hdr.msg_class == SUA_MSGC_CL); + + switch (xua->hdr.msg_type) { + case SUA_CL_CLDT: + rc = sclc_rx_cldt(inst, xua); + break; + case SUA_CL_CLDR: + rc = sclc_rx_cldr(inst, xua); + break; + default: + LOGP(DLSUA, LOGL_NOTICE, "Received unknown/unsupported " + "message %s\n", xua_hdr_dump(xua, &xua_dialect_sua)); + break; + } + + return rc; +} + +/* generate a return/refusal message (SUA CLDR == SCCP UDTS) based on + * the incoming message. We need to flip all identities between sender + * and receiver */ +static struct xua_msg *gen_ret_msg(struct osmo_sccp_instance *inst, + const struct xua_msg *xua_in, + uint32_t ret_cause) +{ + struct xua_msg *xua_out = xua_msg_alloc(); + struct osmo_sccp_addr called; + + xua_out->hdr = XUA_HDR(SUA_MSGC_CL, SUA_CL_CLDR); + xua_msg_add_u32(xua_out, SUA_IEI_ROUTE_CTX, inst->route_ctx); + xua_msg_add_u32(xua_out, SUA_IEI_CAUSE, + SUA_CAUSE_T_RETURN | ret_cause); + /* Swap Calling and Called Party */ + xua_msg_copy_part(xua_out, SUA_IEI_SRC_ADDR, xua_in, SUA_IEI_DEST_ADDR); + xua_msg_copy_part(xua_out, SUA_IEI_DEST_ADDR, xua_in, SUA_IEI_SRC_ADDR); + /* TODO: Optional: Hop Count */ + /* Optional: Importance */ + xua_msg_copy_part(xua_out, SUA_IEI_IMPORTANCE, + xua_in, SUA_IEI_IMPORTANCE); + /* Optional: Message Priority */ + xua_msg_copy_part(xua_out, SUA_IEI_MSG_PRIO, xua_in, SUA_IEI_MSG_PRIO); + /* Optional: Correlation ID */ + xua_msg_copy_part(xua_out, SUA_IEI_CORR_ID, xua_in, SUA_IEI_CORR_ID); + /* Optional: Segmentation */ + xua_msg_copy_part(xua_out, SUA_IEI_SEGMENTATION, + xua_in, SUA_IEI_SEGMENTATION); + /* Optional: Data */ + xua_msg_copy_part(xua_out, SUA_IEI_DATA, xua_in, SUA_IEI_DATA); + + sua_addr_parse(&called, xua_out, SUA_IEI_DEST_ADDR); + /* Route on PC + SSN ? */ + if (called.ri == OSMO_SCCP_RI_SSN_PC) { + /* if no PC, copy OPC into called addr */ + if (!(called.presence & OSMO_SCCP_ADDR_T_PC)) { + struct osmo_sccp_addr calling; + sua_addr_parse(&calling, xua_out, SUA_IEI_SRC_ADDR); + called.presence |= OSMO_SCCP_ADDR_T_PC; + called.pc = calling.pc; + /* Re-encode / replace called address */ + xua_msg_free_tag(xua_out, SUA_IEI_DEST_ADDR); + xua_msg_add_sccp_addr(xua_out, SUA_IEI_DEST_ADDR, + &called); + } + } + return xua_out; +} + +/*! \brief SCRC -> SCLC (Routing Failure + * \param[in] inst SCCP Instance in which we operate + * \param[in] xua_in Message that failed to be routed + * \param[in] cause SCCP Return Cause */ +void sccp_sclc_rx_scrc_rout_fail(struct osmo_sccp_instance *inst, + struct xua_msg *xua_in, uint32_t cause) +{ + struct xua_msg *xua_out; + + /* Figure C.12/Q.714 (Sheet 8) Node 9 */ + switch (xua_in->hdr.msg_type) { + case SUA_CL_CLDT: + xua_out = gen_ret_msg(inst, xua_in, cause); + /* TODO: Message Return Option? */ + if (!osmo_ss7_pc_is_local(inst->ss7, xua_in->mtp.opc)) { + /* non-local originator: send UDTS */ + /* TODO: Assign SLS */ + sccp_scrc_rx_sclc_msg(inst, xua_out); + } else { + /* local originator: send N-NOTICE to user */ + /* TODO: N-NOTICE.ind SCLC -> SCU */ + sclc_rx_cldr(inst, xua_out); + xua_msg_free(xua_out); + } + break; + case SUA_CL_CLDR: + /* do nothing */ + break; + } +} diff --git a/src/sccp_scoc.c b/src/sccp_scoc.c new file mode 100644 index 0000000..f881872 --- /dev/null +++ b/src/sccp_scoc.c @@ -0,0 +1,1642 @@ +/* SCCP Connection Oriented (SCOC) according to ITU-T Q.713/Q.714 */ + +/* (C) 2015-2017 by Harald Welte + * All Rights reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/* This code is a bit of a hybrid between the ITU-T Q.71x specifications + * for SCCP (particularly its connection-oriented part), and the IETF + * RFC 3868 (SUA). The idea here is to have one shared code base of the + * state machines for SCCP Connection Oriented, and use those both from + * SCCP and SUA. + * + * To do so, all SCCP messages are translated to SUA messages in the + * input side, and all generated SUA messages are translated to SCCP on + * the output side. + * + * The Choice of going for SUA messages as the "native" format was based + * on their easier parseability, and the fact that there are features in + * SUA which classic SCCP cannot handle (like IP addresses in GT). + * However, all SCCP features can be expressed in SUA. + * + * The code only supports Class 2. No support for Class 3 is intended, + * but patches are of course alwys welcome. + * + * Missing other features: + * * Segmentation/Reassembly support + * * T(guard) after (re)start + * * freezing of local references + * * parsing/encoding of IPv4/IPv6 addresses + * * use of multiple Routing Contexts in SUA case + */ + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "xua_internal.h" +#include "sccp_internal.h" + +#define S(x) (1 << (x)) +#define SCU_MSGB_SIZE 1024 + +/* Appendix C.4 of Q.714 (all in milliseconds) */ +#define CONNECTION_TIMER ( 1 * 60 * 100) +#define TX_INACT_TIMER ( 7 * 60 * 100) /* RFC 3868 Ch. 8. */ +#define RX_INACT_TIMER (15 * 60 * 100) /* RFC 3868 Ch. 8. */ +#define RELEASE_TIMER ( 10 * 100) +#define RELEASE_REP_TIMER ( 10 * 100) +#define INT_TIMER ( 1 * 60 * 100) +#define GUARD_TIMER (23 * 60 * 100) +#define RESET_TIMER ( 10 * 100) + +/* convert from single value in milliseconds to comma-separated + * "seconds, microseconds" format we use in osmocom/core/timers.h */ +#define MSEC_TO_S_US(x) (x/100), ((x%100)*10) + +/*********************************************************************** + * SCCP connection table + ***********************************************************************/ + +/* a logical connection within the SCCP instance */ +struct sccp_connection { + /* part of osmo_sccp_instance.list */ + struct llist_head list; + /* which instance are we part of? */ + struct osmo_sccp_instance *inst; + /* which user owns us? */ + struct osmo_sccp_user *user; + + /* remote point code */ + uint32_t remote_pc; + + /* local/remote addresses and identiies */ + struct osmo_sccp_addr calling_addr; + struct osmo_sccp_addr called_addr; + uint32_t conn_id; + uint32_t remote_ref; + + uint32_t importance; + uint32_t sccp_class; + uint32_t release_cause; /* WAIT_CONN_CONF */ + + /* Osmo FSM Instance of sccp_scoc_fsm */ + struct osmo_fsm_inst *fi; + + /* Connect timer */ + struct osmo_timer_list t_conn; + + /* inactivity timers */ + struct osmo_timer_list t_ias; + struct osmo_timer_list t_iar; + + /* release timers */ + struct osmo_timer_list t_rel; + struct osmo_timer_list t_int; + struct osmo_timer_list t_rep_rel; +}; + +/*********************************************************************** + * various helper functions + ***********************************************************************/ + +enum sccp_connection_state { + S_IDLE, + S_CONN_PEND_IN, + S_CONN_PEND_OUT, + S_ACTIVE, + S_DISCONN_PEND, + S_RESET_IN, + S_RESET_OUT, + S_BOTHWAY_RESET, + S_WAIT_CONN_CONF, +}; + +/* Events that this FSM can process */ +enum sccp_scoc_event { + /* Primitives from SCCP-User */ + SCOC_E_SCU_N_CONN_REQ, + SCOC_E_SCU_N_CONN_RESP, + SCOC_E_SCU_N_DISC_REQ, + SCOC_E_SCU_N_DATA_REQ, + SCOC_E_SCU_N_EXP_DATA_REQ, + + /* Events from RCOC (Routing for Connection Oriented) */ + SCOC_E_RCOC_CONN_IND, + SCOC_E_RCOC_ROUT_FAIL_IND, + SCOC_E_RCOC_RLSD_IND, + SCOC_E_RCOC_REL_COMPL_IND, + SCOC_E_RCOC_CREF_IND, + SCOC_E_RCOC_CC_IND, + SCOC_E_RCOC_DT1_IND, + SCOC_E_RCOC_DT2_IND, + SCOC_E_RCOC_IT_IND, + SCOC_E_RCOC_OTHER_NPDU, + SCOC_E_RCOC_ERROR_IND, + + /* Timer Events */ + SCOC_E_T_IAR_EXP, + SCOC_E_T_IAS_EXP, + + SCOC_E_CONN_TMR_EXP, + + SCOC_E_T_REL_EXP, + SCOC_E_T_INT_EXP, + SCOC_E_T_REP_REL_EXP, +}; + +static const struct value_string scoc_event_names[] = { + /* Primitives from SCCP-User */ + { SCOC_E_SCU_N_CONN_REQ, "N-CONNECT.req" }, + { SCOC_E_SCU_N_CONN_RESP, "N-CONNECT.resp" }, + { SCOC_E_SCU_N_DISC_REQ, "N-DISCONNECT.req" }, + { SCOC_E_SCU_N_DATA_REQ, "N-DATA.req" }, + { SCOC_E_SCU_N_EXP_DATA_REQ, "N-EXPEDITED_DATA.req" }, + + /* Events from RCOC (Routing for Connection Oriented) */ + { SCOC_E_RCOC_CONN_IND, "RCOC-CONNECT.ind" }, + { SCOC_E_RCOC_ROUT_FAIL_IND, "RCOC-ROUT_FAIL.ind" }, + { SCOC_E_RCOC_RLSD_IND, "RCOC-RELEASED.ind" }, + { SCOC_E_RCOC_REL_COMPL_IND, "RCOC-RELEASE_COMPLETE.ind" }, + { SCOC_E_RCOC_CREF_IND, "RCOC-CONNECT_REFUSED.ind" }, + { SCOC_E_RCOC_CC_IND, "RCOC-CONNECT_CONFIRM.ind" }, + { SCOC_E_RCOC_DT1_IND, "RCOC-DT1.ind" }, + { SCOC_E_RCOC_DT2_IND, "RCOC-DT2.ind" }, + { SCOC_E_RCOC_IT_IND, "RCOC-IT.ind" }, + { SCOC_E_RCOC_OTHER_NPDU, "RCOC-OTHER_NPDU.ind" }, + { SCOC_E_RCOC_ERROR_IND, "RCOC-ERROR.ind" }, + + { SCOC_E_T_IAR_EXP, "T(iar)_expired" }, + { SCOC_E_T_IAS_EXP, "T(ias)_expired" }, + { SCOC_E_CONN_TMR_EXP, "T(conn)_expired" }, + { SCOC_E_T_REL_EXP, "T(rel)_expired" }, + { SCOC_E_T_INT_EXP, "T(int)_expired" }, + { SCOC_E_T_REP_REL_EXP, "T(rep_rel)_expired" }, + + { 0, NULL } +}; + +/* how to map a SCCP CO message to an event */ +static const struct xua_msg_event_map sua_scoc_event_map[] = { + { SUA_MSGC_CO, SUA_CO_CORE, SCOC_E_RCOC_CONN_IND }, + { SUA_MSGC_CO, SUA_CO_RELRE, SCOC_E_RCOC_RLSD_IND }, + { SUA_MSGC_CO, SUA_CO_RELCO, SCOC_E_RCOC_REL_COMPL_IND }, + { SUA_MSGC_CO, SUA_CO_COREF, SCOC_E_RCOC_CREF_IND }, + { SUA_MSGC_CO, SUA_CO_COAK, SCOC_E_RCOC_CC_IND }, + { SUA_MSGC_CO, SUA_CO_CODT, SCOC_E_RCOC_DT1_IND }, + { SUA_MSGC_CO, SUA_CO_COIT, SCOC_E_RCOC_IT_IND }, + { SUA_MSGC_CO, SUA_CO_COERR, SCOC_E_RCOC_ERROR_IND }, +}; + + +/* map from SCU-primitives to SCOC FSM events */ +static const struct osmo_prim_event_map scu_scoc_event_map[] = { + { SCCP_SAP_USER, OSMO_SCU_PRIM_N_CONNECT, PRIM_OP_REQUEST, + SCOC_E_SCU_N_CONN_REQ }, + { SCCP_SAP_USER, OSMO_SCU_PRIM_N_CONNECT, PRIM_OP_RESPONSE, + SCOC_E_SCU_N_CONN_RESP }, + { SCCP_SAP_USER, OSMO_SCU_PRIM_N_DATA, PRIM_OP_REQUEST, + SCOC_E_SCU_N_DATA_REQ }, + { SCCP_SAP_USER, OSMO_SCU_PRIM_N_DISCONNECT, PRIM_OP_REQUEST, + SCOC_E_SCU_N_DISC_REQ }, + { SCCP_SAP_USER, OSMO_SCU_PRIM_N_EXPEDITED_DATA, PRIM_OP_REQUEST, + SCOC_E_SCU_N_EXP_DATA_REQ }, + { 0, 0, 0, OSMO_NO_EVENT } +}; + +/*********************************************************************** + * Timer Handling + ***********************************************************************/ + +/* T(ias) has expired, send a COIT message to the peer */ +static void tx_inact_tmr_cb(void *data) +{ + struct sccp_connection *conn = data; + osmo_fsm_inst_dispatch(conn->fi, SCOC_E_T_IAS_EXP, NULL); +} + +/* T(iar) has expired, notify the FSM about it */ +static void rx_inact_tmr_cb(void *data) +{ + struct sccp_connection *conn = data; + osmo_fsm_inst_dispatch(conn->fi, SCOC_E_T_IAR_EXP, NULL); +} + +/* T(rel) has expired, notify the FSM about it */ +static void rel_tmr_cb(void *data) +{ + struct sccp_connection *conn = data; + osmo_fsm_inst_dispatch(conn->fi, SCOC_E_T_REL_EXP, NULL); +} + +/* T(int) has expired, notify the FSM about it */ +static void int_tmr_cb(void *data) +{ + struct sccp_connection *conn = data; + osmo_fsm_inst_dispatch(conn->fi, SCOC_E_T_INT_EXP, NULL); +} + +/* T(repeat_rel) has expired, notify the FSM about it */ +static void rep_rel_tmr_cb(void *data) +{ + struct sccp_connection *conn = data; + osmo_fsm_inst_dispatch(conn->fi, SCOC_E_T_REP_REL_EXP, NULL); +} + +/* T(conn) has expired, notify the FSM about it */ +static void conn_tmr_cb(void *data) +{ + struct sccp_connection *conn = data; + osmo_fsm_inst_dispatch(conn->fi, SCOC_E_CONN_TMR_EXP, NULL); +} + +/* Re-start the Tx inactivity timer */ +static void conn_restart_tx_inact_timer(struct sccp_connection *conn) +{ + osmo_timer_schedule(&conn->t_ias, MSEC_TO_S_US(TX_INACT_TIMER)); +} + +/* Re-start the Rx inactivity timer */ +static void conn_restart_rx_inact_timer(struct sccp_connection *conn) +{ + osmo_timer_schedule(&conn->t_iar, MSEC_TO_S_US(RX_INACT_TIMER)); +} + +/* Re-start both Rx and Tx inactivity timers */ +static void conn_start_inact_timers(struct sccp_connection *conn) +{ + conn_restart_tx_inact_timer(conn); + conn_restart_rx_inact_timer(conn); +} + +/* Stop both Rx and Tx inactivity timers */ +static void conn_stop_inact_timers(struct sccp_connection *conn) +{ + osmo_timer_del(&conn->t_ias); + osmo_timer_del(&conn->t_iar); +} + +/* Start release timer T(rel) */ +static void conn_start_rel_timer(struct sccp_connection *conn) +{ + osmo_timer_schedule(&conn->t_rel, MSEC_TO_S_US(RELEASE_TIMER)); +} + +/* Start repeat release timer T(rep_rel) */ +static void conn_start_rep_rel_timer(struct sccp_connection *conn) +{ + osmo_timer_schedule(&conn->t_rep_rel, MSEC_TO_S_US(RELEASE_REP_TIMER)); +} + +/* Start interval timer T(int) */ +static void conn_start_int_timer(struct sccp_connection *conn) +{ + osmo_timer_schedule(&conn->t_int, MSEC_TO_S_US(INT_TIMER)); +} + +/* Stop all release related timers: T(rel), T(int) and T(rep_rel) */ +static void conn_stop_release_timers(struct sccp_connection *conn) +{ + osmo_timer_del(&conn->t_rel); + osmo_timer_del(&conn->t_int); + osmo_timer_del(&conn->t_rep_rel); +} + +/* Start connect timer T(conn) */ +static void conn_start_connect_timer(struct sccp_connection *conn) +{ + osmo_timer_schedule(&conn->t_conn, MSEC_TO_S_US(CONNECTION_TIMER)); +} + +/* Stop connect timer T(conn) */ +static void conn_stop_connect_timer(struct sccp_connection *conn) +{ + osmo_timer_del(&conn->t_conn); +} + + +/*********************************************************************** + * SUA Instance and Connection handling + ***********************************************************************/ + +static void conn_destroy(struct sccp_connection *conn); + +static struct sccp_connection *conn_find_by_id(struct osmo_sccp_instance *inst, uint32_t id) +{ + struct sccp_connection *conn; + + llist_for_each_entry(conn, &inst->connections, list) { + if (conn->conn_id == id) + return conn; + } + return NULL; +} + +#define INIT_TIMER(x, fn, priv) do { (x)->cb = fn; (x)->data = priv; } while (0) + +/* allocate + init a SCCP Connection with given ID (local reference) */ +static struct sccp_connection *conn_create_id(struct osmo_sccp_instance *inst, + uint32_t conn_id) +{ + struct sccp_connection *conn = talloc_zero(inst, struct sccp_connection); + char name[16]; + + conn->conn_id = conn_id; + conn->inst = inst; + + llist_add_tail(&conn->list, &inst->connections); + + INIT_TIMER(&conn->t_conn, conn_tmr_cb, conn); + INIT_TIMER(&conn->t_ias, tx_inact_tmr_cb, conn); + INIT_TIMER(&conn->t_iar, rx_inact_tmr_cb, conn); + INIT_TIMER(&conn->t_rel, rel_tmr_cb, conn); + INIT_TIMER(&conn->t_int, int_tmr_cb, conn); + INIT_TIMER(&conn->t_rep_rel, rep_rel_tmr_cb, conn); + + /* this might change at runtime, as it is not a constant :/ */ + sccp_scoc_fsm.log_subsys = DLSCCP; + + /* we simply use the local reference as FSM instance name */ + snprintf(name, sizeof(name), "%u", conn->conn_id); + conn->fi = osmo_fsm_inst_alloc(&sccp_scoc_fsm, conn, conn, + LOGL_DEBUG, name); + if (!conn->fi) { + llist_del(&conn->list); + talloc_free(conn); + return NULL; + } + + return conn; +} + +/* Search for next free connection ID (local reference) and allocate conn */ +static struct sccp_connection *conn_create(struct osmo_sccp_instance *inst) +{ + uint32_t conn_id; + + do { + conn_id = inst->next_id++; + } while (conn_find_by_id(inst, conn_id)); + + return conn_create_id(inst, conn_id); +} + +/* destroy a SCCP connection state, releasing all timers, terminating + * FSM and releasing associated memory */ +static void conn_destroy(struct sccp_connection *conn) +{ + conn_stop_connect_timer(conn); + conn_stop_inact_timers(conn); + conn_stop_release_timers(conn); + llist_del(&conn->list); + + osmo_fsm_inst_term(conn->fi, OSMO_FSM_TERM_REQUEST, NULL); + + talloc_free(conn); +} + +/* allocate a message buffer for an SCCP User Primitive */ +static struct msgb *scu_msgb_alloc(void) +{ + return msgb_alloc(SCU_MSGB_SIZE, "SCCP User Primitive"); +} + +/* generate a RELRE (release request) xua_msg for given conn */ +static struct xua_msg *xua_gen_relre(struct sccp_connection *conn, + uint32_t cause, + struct osmo_scu_prim *prim) +{ + struct xua_msg *xua = xua_msg_alloc(); + + if (!xua) + return NULL; + + xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_RELRE); + xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, conn->inst->route_ctx); + xua_msg_add_u32(xua, SUA_IEI_DEST_REF, conn->remote_ref); + xua_msg_add_u32(xua, SUA_IEI_SRC_REF, conn->conn_id); + xua_msg_add_u32(xua, SUA_IEI_CAUSE, SUA_CAUSE_T_RELEASE | cause); + /* optional: importance */ + if (prim && msgb_l2(prim->oph.msg)) + xua_msg_add_data(xua, SUA_IEI_DATA, msgb_l2len(prim->oph.msg), + msgb_l2(prim->oph.msg)); + + return xua; +} + +/* generate xua_msg, encode it and send it to SCRC */ +static int xua_gen_relre_and_send(struct sccp_connection *conn, uint32_t cause, + struct osmo_scu_prim *prim) +{ + struct xua_msg *xua; + + xua = xua_gen_relre(conn, cause, prim); + if (!xua) + return -1; + + /* amend this with point code information; The SUA RELRE + * includes neither called nor calling party address! */ + xua->mtp.dpc = conn->remote_pc; + return sccp_scrc_rx_scoc_conn_msg(conn->inst, xua); +} + +/* generate a 'struct xua_msg' of requested type from connection + + * primitive data */ +static struct xua_msg *xua_gen_msg_co(struct sccp_connection *conn, uint32_t event, + struct osmo_scu_prim *prim, int msg_type) +{ + struct xua_msg *xua = xua_msg_alloc(); + + if (!xua) + return NULL; + + switch (msg_type) { + case SUA_CO_CORE: /* Connect Request == SCCP CR */ + xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_CORE); + xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, conn->inst->route_ctx); + xua_msg_add_u32(xua, SUA_IEI_PROTO_CLASS, conn->sccp_class); + xua_msg_add_u32(xua, SUA_IEI_SRC_REF, conn->conn_id); + xua_msg_add_sccp_addr(xua, SUA_IEI_DEST_ADDR, &conn->called_addr); + xua_msg_add_u32(xua, SUA_IEI_SEQ_CTRL, 0); /* TODO */ + /* optional: sequence number (class 3 only) */ + if (conn->calling_addr.presence) + xua_msg_add_sccp_addr(xua, SUA_IEI_SRC_ADDR, &conn->calling_addr); + /* optional: hop count; importance; priority; credit */ + if (prim && msgb_l2(prim->oph.msg)) + xua_msg_add_data(xua, SUA_IEI_DATA, msgb_l2len(prim->oph.msg), + msgb_l2(prim->oph.msg)); + break; + case SUA_CO_COAK: /* Connect Acknowledge == SCCP CC */ + xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_COAK); + xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, conn->inst->route_ctx); + xua_msg_add_u32(xua, SUA_IEI_PROTO_CLASS, conn->sccp_class); + xua_msg_add_u32(xua, SUA_IEI_DEST_REF, conn->remote_ref); + xua_msg_add_u32(xua, SUA_IEI_SRC_REF, conn->conn_id); + xua_msg_add_u32(xua, SUA_IEI_SEQ_CTRL, 0); /* TODO */ + /* optional: sequence number (class 3 only) */ + if (conn->called_addr.presence) + xua_msg_add_sccp_addr(xua, SUA_IEI_SRC_ADDR, &conn->called_addr); + /* optional: hop count; importance; priority */ + /* FIXME: destination address will [only] be present in + * case the CORE message conveys the source address + * parameter */ + if (conn->calling_addr.presence) + xua_msg_add_sccp_addr(xua, SUA_IEI_DEST_ADDR, &conn->calling_addr); + if (prim && msgb_l2(prim->oph.msg)) + xua_msg_add_data(xua, SUA_IEI_DATA, msgb_l2len(prim->oph.msg), + msgb_l2(prim->oph.msg)); + break; + case SUA_CO_RELRE: /* Release Request == SCCP REL */ + if (!prim) + goto prim_needed; + xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_RELRE); + xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, conn->inst->route_ctx); + xua_msg_add_u32(xua, SUA_IEI_DEST_REF, conn->remote_ref); + xua_msg_add_u32(xua, SUA_IEI_SRC_REF, conn->conn_id); + xua_msg_add_u32(xua, SUA_IEI_CAUSE, SUA_CAUSE_T_RELEASE | prim->u.disconnect.cause); + /* optional: importance */ + if (msgb_l2(prim->oph.msg)) + xua_msg_add_data(xua, SUA_IEI_DATA, msgb_l2len(prim->oph.msg), + msgb_l2(prim->oph.msg)); + break; + case SUA_CO_RELCO: /* Release Confirm == SCCP RLSD */ + xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_RELCO); + xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, conn->inst->route_ctx); + xua_msg_add_u32(xua, SUA_IEI_DEST_REF, conn->remote_ref); + xua_msg_add_u32(xua, SUA_IEI_SRC_REF, conn->conn_id); + /* optional: importance */ + break; + case SUA_CO_CODT: /* Connection Oriented Data Transfer == SCCP DT1 */ + if (!prim) + goto prim_needed; + xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_CODT); + xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, conn->inst->route_ctx); + /* Sequence number only in expedited data */ + xua_msg_add_u32(xua, SUA_IEI_DEST_REF, conn->remote_ref); + /* optional: priority; correlation id */ + xua_msg_add_data(xua, SUA_IEI_DATA, msgb_l2len(prim->oph.msg), + msgb_l2(prim->oph.msg)); + break; + case SUA_CO_COIT: /* Connection Oriented Interval Timer == SCCP IT */ + xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_COIT); + xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, conn->inst->route_ctx); + xua_msg_add_u32(xua, SUA_IEI_PROTO_CLASS, conn->sccp_class); + xua_msg_add_u32(xua, SUA_IEI_SRC_REF, conn->conn_id); + xua_msg_add_u32(xua, SUA_IEI_DEST_REF, conn->remote_ref); + /* optional: sequence number; credit (both class 3 only) */ + break; + case SUA_CO_COREF: /* Connect Refuse == SCCP CREF */ + xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_COREF); + xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, conn->inst->route_ctx); + xua_msg_add_u32(xua, SUA_IEI_DEST_REF, conn->remote_ref); + //xua_msg_add_u32(xua, SUA_IEI_CAUSE, SUA_CAUSE_T_REFUSAL | prim->u.disconnect.cause); + xua_msg_add_u32(xua, SUA_IEI_CAUSE, SUA_CAUSE_T_REFUSAL | SCCP_REFUSAL_UNEQUIPPED_USER); + /* optional: source addr */ + if (conn->called_addr.presence) + xua_msg_add_sccp_addr(xua, SUA_IEI_SRC_ADDR, &conn->called_addr); + /* conditional: dest addr */ + if (conn->calling_addr.presence) + xua_msg_add_sccp_addr(xua, SUA_IEI_DEST_ADDR, &conn->calling_addr); + /* optional: importance */ + /* optional: data */ + if (prim && msgb_l2(prim->oph.msg)) + xua_msg_add_data(xua, SUA_IEI_DATA, msgb_l2len(prim->oph.msg), + msgb_l2(prim->oph.msg)); + break; + /* FIXME */ + default: + LOGP(DLSCCP, LOGL_ERROR, "Don't know how to encode msg_type %u\n", msg_type); + xua_msg_free(xua); + return NULL; + } + return xua; + +prim_needed: + xua_msg_free(xua); + LOGP(DLSCCP, LOGL_ERROR, "%s must be called with valid 'prim' " + "pointer for msg_type=%u\n", __func__, msg_type); + return NULL; +} + +/* generate xua_msg, encode it and send it to SCRC */ +static int xua_gen_encode_and_send(struct sccp_connection *conn, uint32_t event, + struct osmo_scu_prim *prim, int msg_type) +{ + struct xua_msg *xua; + + xua = xua_gen_msg_co(conn, event, prim, msg_type); + if (!xua) + return -1; + + /* amend this with point code information; Many CO msgs + * includes neither called nor calling party address! */ + xua->mtp.dpc = conn->remote_pc; + return sccp_scrc_rx_scoc_conn_msg(conn->inst, xua); +} + +/* allocate a SCU primitive to be sent to the user */ +static struct osmo_scu_prim *scu_prim_alloc(unsigned int primitive, enum osmo_prim_operation operation) +{ + struct msgb *upmsg = scu_msgb_alloc(); + struct osmo_scu_prim *prim; + + prim = (struct osmo_scu_prim *) msgb_put(upmsg, sizeof(*prim)); + osmo_prim_init(&prim->oph, SCCP_SAP_USER, + primitive, operation, upmsg); + return prim; +} + +/* high-level function to generate a SCCP User primitive of requested + * type based on the connection and currently processed XUA message */ +static void scu_gen_encode_and_send(struct sccp_connection *conn, uint32_t event, + struct xua_msg *xua, unsigned int primitive, + enum osmo_prim_operation operation) +{ + struct osmo_scu_prim *scu_prim; + struct osmo_scu_disconn_param *udisp; + struct osmo_scu_connect_param *uconp; + struct osmo_scu_data_param *udatp; + struct xua_msg_part *data_ie; + + scu_prim = scu_prim_alloc(primitive, operation); + + switch (OSMO_PRIM_HDR(&scu_prim->oph)) { + case OSMO_PRIM(OSMO_SCU_PRIM_N_DISCONNECT, PRIM_OP_INDICATION): + udisp = &scu_prim->u.disconnect; + udisp->conn_id = conn->conn_id; + udisp->responding_addr = conn->called_addr; + udisp->originator = OSMO_SCCP_ORIG_UNDEFINED; + //udisp->in_sequence_control; + if (xua) { + udisp->cause = xua_msg_get_u32(xua, SUA_IEI_CAUSE); + if (xua_msg_find_tag(xua, SUA_IEI_SRC_ADDR)) + sua_addr_parse(&udisp->responding_addr, xua, SUA_IEI_SRC_ADDR); + data_ie = xua_msg_find_tag(xua, SUA_IEI_DATA); + udisp->importance = xua_msg_get_u32(xua, SUA_IEI_IMPORTANCE); + if (data_ie) { + struct msgb *upmsg = scu_prim->oph.msg; + upmsg->l2h = msgb_put(upmsg, data_ie->len); + memcpy(upmsg->l2h, data_ie->dat, data_ie->len); + } + } + break; + case OSMO_PRIM(OSMO_SCU_PRIM_N_CONNECT, PRIM_OP_INDICATION): + uconp = &scu_prim->u.connect; + uconp->conn_id = conn->conn_id; + uconp->called_addr = conn->called_addr; + uconp->calling_addr = conn->calling_addr; + uconp->sccp_class = conn->sccp_class; + uconp->importance = conn->importance; + data_ie = xua_msg_find_tag(xua, SUA_IEI_DATA); + if (xua) { + if (data_ie) { + struct msgb *upmsg = scu_prim->oph.msg; + upmsg->l2h = msgb_put(upmsg, data_ie->len); + memcpy(upmsg->l2h, data_ie->dat, data_ie->len); + } + } + break; + case OSMO_PRIM(OSMO_SCU_PRIM_N_CONNECT, PRIM_OP_CONFIRM): + uconp = &scu_prim->u.connect; + uconp->conn_id = conn->conn_id; + uconp->called_addr = conn->called_addr; + uconp->calling_addr = conn->calling_addr; + //scu_prim->u.connect.in_sequence_control + uconp->sccp_class = xua_msg_get_u32(xua, SUA_IEI_PROTO_CLASS) & 3; + uconp->importance = xua_msg_get_u32(xua, SUA_IEI_IMPORTANCE); + data_ie = xua_msg_find_tag(xua, SUA_IEI_DATA); + if (data_ie) { + struct msgb *upmsg = scu_prim->oph.msg; + upmsg->l2h = msgb_put(upmsg, data_ie->len); + memcpy(upmsg->l2h, data_ie->dat, data_ie->len); + } + break; + case OSMO_PRIM(OSMO_SCU_PRIM_N_DATA, PRIM_OP_INDICATION): + udatp = &scu_prim->u.data; + udatp->conn_id = conn->conn_id; + udatp->importance = conn->importance; + data_ie = xua_msg_find_tag(xua, SUA_IEI_DATA); + if (data_ie) { + struct msgb *upmsg = scu_prim->oph.msg; + upmsg->l2h = msgb_put(upmsg, data_ie->len); + memcpy(upmsg->l2h, data_ie->dat, data_ie->len); + } + break; + default: + LOGPFSML(conn->fi, LOGL_ERROR, "Unsupported primitive %u:%u\n", + scu_prim->oph.primitive, scu_prim->oph.operation); + talloc_free(scu_prim->oph.msg); + return; + } + + sccp_user_prim_up(conn->user, scu_prim); +} + + +/*********************************************************************** + * Actual SCCP Connection Oriented Control (SCOC) Finite Stte Machine + ***********************************************************************/ + +/* Figure C.2/Q.714 (sheet 1 of 7) and C.3/Q.714 (sheet 1 of 6) */ +static void scoc_fsm_idle(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct sccp_connection *conn = fi->priv; + struct osmo_scu_prim *prim = NULL; + struct osmo_scu_connect_param *uconp; + struct xua_msg *xua = NULL; + + switch (event) { + case SCOC_E_SCU_N_CONN_REQ: + prim = data; + uconp = &prim->u.connect; + /* copy relevant parameters from prim to conn */ + conn->called_addr = uconp->called_addr; + conn->calling_addr = uconp->calling_addr; + conn->sccp_class = uconp->sccp_class; + /* generate + send CR PDU to SCRC */ + xua_gen_encode_and_send(conn, event, prim, SUA_CO_CORE); + /* start connection timer */ + conn_start_connect_timer(conn); + osmo_fsm_inst_state_chg(fi, S_CONN_PEND_OUT, 0, 0); + break; +#if 0 + case SCOC_E_SCU_N_TYPE1_REQ: + /* ?!? */ + break; +#endif + case SCOC_E_RCOC_RLSD_IND: + /* send release complete to SCRC */ + xua_gen_encode_and_send(conn, event, NULL, SUA_CO_RELCO); + break; + case SCOC_E_RCOC_REL_COMPL_IND: + /* do nothing */ + break; + case SCOC_E_RCOC_OTHER_NPDU: +#if 0 + if (src_ref) { + /* FIXME: send ERROR to SCRC */ + } +#endif + break; + /* destination node / incoming connection */ + /* Figure C.3 / Q.714 (sheet 1 of 6) */ + case SCOC_E_RCOC_CONN_IND: + xua = data; + /* copy relevant parameters from xua to conn */ + sua_addr_parse(&conn->calling_addr, xua, SUA_IEI_SRC_ADDR); + sua_addr_parse(&conn->called_addr, xua, SUA_IEI_DEST_ADDR); + conn->remote_ref = xua_msg_get_u32(xua, SUA_IEI_SRC_REF); + conn->sccp_class = xua_msg_get_u32(xua, SUA_IEI_PROTO_CLASS) & 3; + conn->importance = xua_msg_get_u32(xua, SUA_IEI_IMPORTANCE); + /* 3.1.6.1 The originating node of the CR message + * (identified by the OPC in the calling party address + * or by default by the OPC in the MTP label, [and the + * MTP-SAP instance]) is associated with the incoming + * connection section. */ + if (conn->calling_addr.presence & OSMO_SCCP_ADDR_T_PC) + conn->remote_pc = conn->calling_addr.pc; + else { + /* Hack to get the MTP label here ?!? */ + conn->remote_pc = xua->mtp.opc; + } + + osmo_fsm_inst_state_chg(fi, S_CONN_PEND_IN, 0, 0); + /* N-CONNECT.ind to User */ + scu_gen_encode_and_send(conn, event, xua, OSMO_SCU_PRIM_N_CONNECT, + PRIM_OP_INDICATION); + break; + } +} + +static void scoc_fsm_idle_onenter(struct osmo_fsm_inst *fi, uint32_t old_state) +{ + conn_destroy(fi->priv); +} + +/* Figure C.3 / Q.714 (sheet 2 of 6) */ +static void scoc_fsm_conn_pend_in(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct sccp_connection *conn = fi->priv; + struct osmo_scu_prim *prim = NULL; + + switch (event) { + case SCOC_E_SCU_N_CONN_RESP: + prim = data; + /* FIXME: assign local reference (only now?) */ + /* FIXME: assign sls, protocol class and credit */ + xua_gen_encode_and_send(conn, event, prim, SUA_CO_COAK); + /* start inactivity timers */ + conn_start_inact_timers(conn); + osmo_fsm_inst_state_chg(fi, S_ACTIVE, 0, 0); + break; + case SCOC_E_SCU_N_DISC_REQ: + prim = data; + /* release resources: implicit */ + xua_gen_encode_and_send(conn, event, prim, SUA_CO_COREF); + osmo_fsm_inst_state_chg(fi, S_IDLE, 0, 0); + break; + } +} + +/* Figure C.2/Q.714 (sheet 2 of 7) */ +static void scoc_fsm_conn_pend_out(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct sccp_connection *conn = fi->priv; + struct osmo_scu_prim *prim = NULL; + struct xua_msg *xua = NULL; + + switch (event) { + case SCOC_E_SCU_N_DISC_REQ: + prim = data; + conn->release_cause = prim->u.disconnect.cause; + osmo_fsm_inst_state_chg(fi, S_WAIT_CONN_CONF, 0, 0); + /* keep conn timer running(!) */ + break; + case SCOC_E_CONN_TMR_EXP: + /* N-DISCONNECT.ind to user */ + scu_gen_encode_and_send(conn, event, xua, OSMO_SCU_PRIM_N_DISCONNECT, + PRIM_OP_INDICATION); + /* below implicitly releases resources + local ref */ + osmo_fsm_inst_state_chg(fi, S_IDLE, 0, 0); + break; + case SCOC_E_RCOC_ROUT_FAIL_IND: + case SCOC_E_RCOC_CREF_IND: + xua = data; + /* stop conn timer */ + conn_stop_connect_timer(conn); + /* release local res + ref (implicit by going to idle) */ + /* N-DISCONNECT.ind to user */ + scu_gen_encode_and_send(conn, event, xua, OSMO_SCU_PRIM_N_DISCONNECT, + PRIM_OP_INDICATION); + /* below implicitly releases resources + local ref */ + osmo_fsm_inst_state_chg(fi, S_IDLE, 0, 0); + break; + case SCOC_E_RCOC_RLSD_IND: + xua = data; + /* RLC to SCRC */ + xua_gen_encode_and_send(conn, event, NULL, SUA_CO_RELCO); + /* stop conn timer */ + conn_stop_connect_timer(conn); + /* release local res + ref (implicit) */ + /* N-DISCONNECT.ind to user */ + scu_gen_encode_and_send(conn, event, xua, OSMO_SCU_PRIM_N_DISCONNECT, + PRIM_OP_INDICATION); + osmo_fsm_inst_state_chg(fi, S_IDLE, 0, 0); + break; + case SCOC_E_RCOC_OTHER_NPDU: + xua = data; + conn_start_connect_timer(conn); + /* release local res + ref (implicit) */ + /* N-DISCONNECT.ind to user */ + scu_gen_encode_and_send(conn, event, xua, OSMO_SCU_PRIM_N_DISCONNECT, + PRIM_OP_INDICATION); + osmo_fsm_inst_state_chg(fi, S_IDLE, 0, 0); + break; + case SCOC_E_RCOC_CC_IND: + xua = data; + /* stop conn timer */ + conn_stop_connect_timer(conn); + /* start inactivity timers */ + conn_start_inact_timers(conn); + /* TODO: assign PCU and credit */ + /* associate remote ref to conn */ + conn->remote_ref = xua_msg_get_u32(xua, SUA_IEI_SRC_REF); + /* 3.1.4.2 The node sending the CC message (identified + * by the parameter OPC contained in the + * MTP-TRANSFER.indication primitive which conveyed the + * CC message [plus the MTP-SAP instance]) is associated + * with the connection section. */ + conn->remote_pc = xua->mtp.opc; + + osmo_fsm_inst_state_chg(fi, S_ACTIVE, 0, 0); + /* N-CONNECT.conf to user */ + scu_gen_encode_and_send(conn, event, xua, OSMO_SCU_PRIM_N_CONNECT, + PRIM_OP_CONFIRM); + break; + } +} + +/* Figure C.2/Q.714 (sheet 3 of 7) */ +static void scoc_fsm_wait_conn_conf(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct sccp_connection *conn = fi->priv; + struct xua_msg *xua = NULL; + + switch (event) { + case SCOC_E_RCOC_RLSD_IND: + xua = data; + /* release complete to SCRC */ + xua_gen_encode_and_send(conn, event, NULL, SUA_CO_RELCO); + /* stop conn timer */ + conn_stop_connect_timer(conn); + /* release local res + ref (implicit) */ + osmo_fsm_inst_state_chg(fi, S_IDLE, 0, 0); + break; + case SCOC_E_RCOC_CC_IND: + xua = data; + /* stop conn timer */ + conn_stop_connect_timer(conn); + /* associate rem ref to conn */ + conn->remote_ref = xua_msg_get_u32(xua, SUA_IEI_SRC_REF); + /* released to SCRC */ + xua_gen_relre_and_send(conn, conn->release_cause, NULL); + /* start rel timer */ + conn_start_rel_timer(conn); + osmo_fsm_inst_state_chg(fi, S_DISCONN_PEND, 0, 0); + break; + case SCOC_E_RCOC_OTHER_NPDU: + case SCOC_E_RCOC_CREF_IND: + case SCOC_E_RCOC_ROUT_FAIL_IND: + xua = data; + /* stop conn timer */ + conn_stop_connect_timer(conn); + /* release local res + ref */ + osmo_fsm_inst_state_chg(fi, S_IDLE, 0, 0); + break; + case SCOC_E_CONN_TMR_EXP: + /* release local res + ref */ + osmo_fsm_inst_state_chg(fi, S_IDLE, 0, 0); + break; + } +} + +/* C.2/Q.714 (sheet 4+5 of 7) and C.3/Q714 (sheet 3+4 of 6) */ +static void scoc_fsm_active(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct xua_msg *xua = data; + struct sccp_connection *conn = fi->priv; + struct osmo_scu_prim *prim = NULL; + + switch (event) { + /* TODO: internal disco */ + /* send N-DISCONNECT.ind to user */ + scu_gen_encode_and_send(conn, event, xua, OSMO_SCU_PRIM_N_DISCONNECT, + PRIM_OP_INDICATION); + /* fall-through */ + case SCOC_E_SCU_N_DISC_REQ: + prim = data; + /* stop inact timers */ + conn_stop_inact_timers(conn); + /* send RLSD to SCRC */ + xua_gen_encode_and_send(conn, event, prim, SUA_CO_RELRE); + /* start rel timer */ + conn_start_rel_timer(conn); + osmo_fsm_inst_state_chg(fi, S_DISCONN_PEND, 0, 0); + break; + case SCOC_E_RCOC_CREF_IND: + case SCOC_E_RCOC_CC_IND: + case SCOC_E_RCOC_REL_COMPL_IND: + /* do nothing */ + break; + case SCOC_E_RCOC_RLSD_IND: + /* send N-DISCONNECT.ind to user */ + scu_gen_encode_and_send(conn, event, xua, OSMO_SCU_PRIM_N_DISCONNECT, + PRIM_OP_INDICATION); + /* release res + local ref (implicit) */ + /* stop inact timers */ + conn_stop_inact_timers(conn); + /* RLC to SCRC */ + xua_gen_encode_and_send(conn, event, NULL, SUA_CO_RELCO); + osmo_fsm_inst_state_chg(fi, S_IDLE, 0, 0); + break; + case SCOC_E_RCOC_ERROR_IND: + xua = data; + /* FIXME: check for cause service_class_mismatch */ + /* release res + local ref (implicit) */ + /* send N-DISCONNECT.ind to user */ + scu_gen_encode_and_send(conn, event, xua, OSMO_SCU_PRIM_N_DISCONNECT, + PRIM_OP_INDICATION); + /* stop inact timers */ + conn_stop_inact_timers(conn); + osmo_fsm_inst_state_chg(fi, S_IDLE, 0, 0); + break; + case SCOC_E_T_IAR_EXP: + /* Send N-DISCONNECT.ind to local user */ + scu_gen_encode_and_send(conn, event, NULL, OSMO_SCU_PRIM_N_DISCONNECT, + PRIM_OP_INDICATION); + /* Send RLSD to peer */ + xua_gen_relre_and_send(conn, SCCP_RELEASE_CAUSE_EXPIRATION_INACTIVE, NULL); + conn_start_rel_timer(conn); + osmo_fsm_inst_state_chg(fi, S_DISCONN_PEND, 0, 0); + break; + case SCOC_E_RCOC_ROUT_FAIL_IND: + /* send N-DISCONNECT.ind to user */ + scu_gen_encode_and_send(conn, event, NULL, OSMO_SCU_PRIM_N_DISCONNECT, + PRIM_OP_INDICATION); + /* stop inact timers */ + conn_stop_inact_timers(conn); + /* start release timer */ + conn_start_rel_timer(conn); + osmo_fsm_inst_state_chg(fi, S_DISCONN_PEND, 0, 0); + break; + /* Figure C.4/Q.714 */ + case SCOC_E_SCU_N_DATA_REQ: + case SCOC_E_SCU_N_EXP_DATA_REQ: + prim = data; + xua_gen_encode_and_send(conn, event, prim, SUA_CO_CODT); + conn_restart_tx_inact_timer(conn); + break; + case SCOC_E_RCOC_DT1_IND: + /* restart receive inactivity timer */ + conn_restart_rx_inact_timer(conn); + /* TODO: M-bit */ + scu_gen_encode_and_send(conn, event, xua, OSMO_SCU_PRIM_N_DATA, + PRIM_OP_INDICATION); + break; + /* Figure C.4/Q.714 (sheet 4 of 4) */ + case SCOC_E_RCOC_IT_IND: + xua = data; + /* check if remote reference is what we expect */ + /* check class is what we expect */ + if (xua_msg_get_u32(xua, SUA_IEI_SRC_REF) != conn->remote_ref || + xua_msg_get_u32(xua, SUA_IEI_PROTO_CLASS) != conn->sccp_class) { + /* Release connection */ + /* send N-DISCONNECT.ind to user */ + scu_gen_encode_and_send(conn, event, NULL, + OSMO_SCU_PRIM_N_DISCONNECT, + PRIM_OP_INDICATION); + /* Stop inactivity Timers */ + conn_stop_inact_timers(conn); + /* Send RLSD to SCRC */ + xua_gen_relre_and_send(conn, SCCP_RELEASE_CAUSE_INCONSISTENT_CONN_DATA, NULL); + /* Start release timer */ + conn_start_rel_timer(conn); + osmo_fsm_inst_state_chg(fi, S_DISCONN_PEND, 0, 0); + } + conn_restart_rx_inact_timer(conn); + break; + case SCOC_E_T_IAS_EXP: + /* Send IT to peer */ + xua_gen_encode_and_send(conn, event, NULL, SUA_CO_COIT); + conn_restart_tx_inact_timer(conn); + break; + } +} + +/* C.2/Q.714 (sheet 6+7 of 7) and C.3/Q.714 (sheet 5+6 of 6) */ +static void scoc_fsm_disconn_pend(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct sccp_connection *conn = fi->priv; + + switch (event) { + case SCOC_E_RCOC_REL_COMPL_IND: + case SCOC_E_RCOC_RLSD_IND: + /* release res + local ref (implicit) */ + /* freeze local ref */ + /* stop release + interval timers */ + conn_stop_release_timers(conn); + osmo_fsm_inst_state_chg(fi, S_IDLE, 0, 0); + break; + case SCOC_E_RCOC_ROUT_FAIL_IND: + case SCOC_E_RCOC_OTHER_NPDU: + /* do nothing */ + break; + case SCOC_E_T_REL_EXP: /* release timer exp */ + /* send RLSD */ + xua_gen_relre_and_send(conn, SCCP_RELEASE_CAUSE_UNQUALIFIED, NULL); + /* start interval timer */ + conn_start_int_timer(conn); + /* start repeat release timer */ + conn_start_rep_rel_timer(conn); + break; + case SCOC_E_T_INT_EXP: /* interval timer exp */ + /* TODO: Inform maintenance */ + /* stop release and interval timers */ + conn_stop_release_timers(conn); + osmo_fsm_inst_state_chg(fi, S_IDLE, 0, 0); + break; + case SCOC_E_T_REP_REL_EXP: /* repeat release timer exp */ + /* send RLSD */ + xua_gen_relre_and_send(conn, SCCP_RELEASE_CAUSE_UNQUALIFIED, NULL); + /* re-start repeat release timer */ + conn_start_rep_rel_timer(conn); + break; + } +} + +static const struct osmo_fsm_state sccp_scoc_states[] = { + [S_IDLE] = { + .name = "IDLE", + .action = scoc_fsm_idle, + .onenter= scoc_fsm_idle_onenter, + .in_event_mask = S(SCOC_E_SCU_N_CONN_REQ) | + //S(SCOC_E_SCU_N_TYPE1_REQ) | + S(SCOC_E_RCOC_CONN_IND) | + S(SCOC_E_RCOC_RLSD_IND) | + S(SCOC_E_RCOC_REL_COMPL_IND) | + S(SCOC_E_RCOC_OTHER_NPDU), + .out_state_mask = S(S_CONN_PEND_OUT) | + S(S_CONN_PEND_IN), + }, + [S_CONN_PEND_IN] = { + .name = "CONN_PEND_IN", + .action = scoc_fsm_conn_pend_in, + .in_event_mask = S(SCOC_E_SCU_N_CONN_RESP) | + S(SCOC_E_SCU_N_DISC_REQ), + .out_state_mask = S(S_IDLE) | + S(S_ACTIVE), + }, + [S_CONN_PEND_OUT] = { + .name = "CONN_PEND_OUT", + .action = scoc_fsm_conn_pend_out, + .in_event_mask = S(SCOC_E_SCU_N_DISC_REQ) | + S(SCOC_E_CONN_TMR_EXP) | + S(SCOC_E_RCOC_ROUT_FAIL_IND) | + S(SCOC_E_RCOC_RLSD_IND) | + S(SCOC_E_RCOC_OTHER_NPDU) | + S(SCOC_E_RCOC_CREF_IND) | + S(SCOC_E_RCOC_CC_IND), + .out_state_mask = S(S_IDLE) | + S(S_ACTIVE) | + S(S_WAIT_CONN_CONF), + }, + [S_ACTIVE] = { + .name = "ACTIVE", + .action = scoc_fsm_active, + .in_event_mask = S(SCOC_E_SCU_N_DISC_REQ) | + /* internal disconnect */ + S(SCOC_E_RCOC_CREF_IND) | + S(SCOC_E_RCOC_REL_COMPL_IND) | + S(SCOC_E_RCOC_RLSD_IND) | + S(SCOC_E_RCOC_ERROR_IND) | + S(SCOC_E_T_IAR_EXP) | + S(SCOC_E_T_IAS_EXP) | + S(SCOC_E_RCOC_ROUT_FAIL_IND) | + S(SCOC_E_SCU_N_DATA_REQ) | + S(SCOC_E_SCU_N_EXP_DATA_REQ) | + S(SCOC_E_RCOC_DT1_IND) | + S(SCOC_E_RCOC_IT_IND), + .out_state_mask = S(S_IDLE) | + S(S_DISCONN_PEND), + }, + [S_DISCONN_PEND] = { + .name = "DISCONN_PEND", + .action = scoc_fsm_disconn_pend, + .in_event_mask = S(SCOC_E_RCOC_REL_COMPL_IND) | + S(SCOC_E_RCOC_RLSD_IND) | + S(SCOC_E_RCOC_ROUT_FAIL_IND) | + S(SCOC_E_RCOC_OTHER_NPDU) | + S(SCOC_E_T_REL_EXP) | + S(SCOC_E_T_INT_EXP) | + S(SCOC_E_T_REP_REL_EXP), + .out_state_mask = S(S_IDLE), + }, + [S_RESET_IN] = { + .name = "RESET_IN", + }, + [S_RESET_OUT] = { + .name = "RESET_OUT", + }, + [S_BOTHWAY_RESET] = { + .name = "BOTHWAY_RESET", + }, + [S_WAIT_CONN_CONF] = { + .name = "WAIT_CONN_CONF", + .action = scoc_fsm_wait_conn_conf, + .in_event_mask = S(SCOC_E_RCOC_RLSD_IND) | + S(SCOC_E_RCOC_CC_IND) | + S(SCOC_E_RCOC_OTHER_NPDU) | + S(SCOC_E_CONN_TMR_EXP) | + S(SCOC_E_RCOC_CREF_IND) | + S(SCOC_E_RCOC_ROUT_FAIL_IND), + }, +}; + +struct osmo_fsm sccp_scoc_fsm = { + .name = "SCCP-SCOC", + .states = sccp_scoc_states, + .num_states = ARRAY_SIZE(sccp_scoc_states), + /* ".log_subsys = DLSCCP" doesn't work as DLSCCP is not a constant */ + .event_names = scoc_event_names, +}; + +/* map from SCCP return cause to SCCP Refusal cause */ +static const uint8_t cause_map_cref[] = { + [SCCP_RETURN_CAUSE_SUBSYSTEM_CONGESTION] = + SCCP_REFUSAL_SUBSYTEM_CONGESTION, + [SCCP_RETURN_CAUSE_SUBSYSTEM_FAILURE] = + SCCP_REFUSAL_SUBSYSTEM_FAILURE, + [SCCP_RETURN_CAUSE_UNEQUIPPED_USER] = + SCCP_REFUSAL_UNEQUIPPED_USER, + [SCCP_RETURN_CAUSE_UNQUALIFIED] = + SCCP_REFUSAL_UNQUALIFIED, + [SCCP_RETURN_CAUSE_SCCP_FAILURE] = + SCCP_REFUSAL_SCCP_FAILURE, + [SCCP_RETURN_CAUSE_HOP_COUNTER_VIOLATION] = + SCCP_REFUSAL_HOP_COUNTER_VIOLATION, +}; + +static uint8_t get_cref_cause_for_ret(uint8_t ret_cause) +{ + if (ret_cause < ARRAY_SIZE(cause_map_cref)) + return cause_map_cref[ret_cause]; + else + return SCCP_REFUSAL_UNQUALIFIED; +} + +/* Generate a COREF message purely based on an incoming SUA message, + * without the use of any local connection state */ +static struct xua_msg *gen_coref_without_conn(struct osmo_sccp_instance *inst, + struct xua_msg *xua_in, + uint32_t ref_cause) +{ + struct xua_msg *xua; + + xua = xua_msg_alloc(); + xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_COREF); + xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, inst->route_ctx); + + xua_msg_copy_part(xua, SUA_IEI_DEST_REF, xua_in, SUA_IEI_SRC_REF); + xua_msg_add_u32(xua, SUA_IEI_CAUSE, SUA_CAUSE_T_REFUSAL | ref_cause); + /* optional: source addr */ + xua_msg_copy_part(xua, SUA_IEI_SRC_ADDR, xua_in, SUA_IEI_DEST_ADDR); + /* conditional: dest addr */ + xua_msg_copy_part(xua, SUA_IEI_DEST_ADDR, xua_in, SUA_IEI_SRC_ADDR); + /* optional: importance */ + xua_msg_copy_part(xua, SUA_IEI_IMPORTANCE, xua_in, SUA_IEI_IMPORTANCE); + /* optional: data */ + xua_msg_copy_part(xua, SUA_IEI_DATA, xua_in, SUA_IEI_DATA); + + return xua; +} + +/*! \brief SCOC: Receive SCRC Routing Failure + * \param[in] inst SCCP Instance on which we operate + * \param[in] xua SUA message that was failed to route + * \param[in] return_cause Reason (cause) for routing failure */ +void sccp_scoc_rx_scrc_rout_fail(struct osmo_sccp_instance *inst, + struct xua_msg *xua, uint32_t return_cause) +{ + uint32_t conn_id; + struct sccp_connection *conn; + + /* try to dispatch to connection FSM (if any) */ + conn_id = xua_msg_get_u32(xua, SUA_IEI_DEST_REF); + conn = conn_find_by_id(inst, conn_id); + if (conn) { + osmo_fsm_inst_dispatch(conn->fi, + SCOC_E_RCOC_ROUT_FAIL_IND, xua); + } else { + /* generate + send CREF directly */ + struct xua_msg *cref; + uint8_t cref_cause = get_cref_cause_for_ret(return_cause); + cref = gen_coref_without_conn(inst, xua, cref_cause); + sccp_scrc_rx_scoc_conn_msg(inst, cref); + xua_msg_free(cref); + } +} + +/* Find a SCCP user for given SUA message (based on SUA_IEI_DEST_ADDR */ +static struct osmo_sccp_user *sccp_find_user(struct osmo_sccp_instance *inst, + struct xua_msg *xua) +{ + int rc; + struct osmo_sccp_addr called_addr; + + rc = sua_addr_parse(&called_addr, xua, SUA_IEI_DEST_ADDR); + if (rc < 0) { + LOGP(DLSCCP, LOGL_ERROR, "Cannot find SCCP User for XUA " + "Message %s without valid DEST_ADDR\n", + xua_hdr_dump(xua, &xua_dialect_sua)); + return NULL; + } + + if (!(called_addr.presence & OSMO_SCCP_ADDR_T_SSN)) { + LOGP(DLSCCP, LOGL_ERROR, "Cannot resolve SCCP User for " + "XUA Message %s without SSN in CalledAddr\n", + xua_hdr_dump(xua, &xua_dialect_sua)); + return NULL; + } + + return sccp_user_find(inst, called_addr.ssn, called_addr.pc); +} + +/* Generate a COERR based in input arguments */ +static struct xua_msg *gen_coerr(uint32_t route_ctx, uint32_t dest_ref, + uint32_t err_cause) +{ + struct xua_msg *xua = xua_msg_alloc(); + + xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_COERR); + xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, route_ctx); + xua_msg_add_u32(xua, SUA_IEI_DEST_REF, dest_ref); + xua_msg_add_u32(xua, SUA_IEI_CAUSE, SUA_CAUSE_T_ERROR | err_cause); + + return xua; +} + +/* generate COERR from incoming XUA and send it */ +static void tx_coerr_from_xua(struct osmo_sccp_instance *inst, + struct xua_msg *in, uint32_t err_cause) +{ + struct xua_msg *xua; + uint32_t route_ctx, dest_ref; + + route_ctx = xua_msg_get_u32(in, SUA_IEI_ROUTE_CTX); + /* get *source* reference and use as destination ref */ + dest_ref = xua_msg_get_u32(in, SUA_IEI_SRC_REF); + + xua = gen_coerr(route_ctx, dest_ref, err_cause); + /* copy over the MTP parameters */ + xua->mtp.dpc = in->mtp.opc; + xua->mtp.opc = in->mtp.dpc; + xua->mtp.sio = in->mtp.sio; + + /* sent to SCRC for transmission */ + sccp_scrc_rx_scoc_conn_msg(inst, xua); + xua_msg_free(xua); +} + +/* Generate a RELCO based in input arguments */ +static struct xua_msg *gen_relco(uint32_t route_ctx, uint32_t dest_ref, + uint32_t src_ref) +{ + struct xua_msg *xua = xua_msg_alloc(); + + xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_RELCO); + xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, route_ctx); + xua_msg_add_u32(xua, SUA_IEI_DEST_REF, dest_ref); + xua_msg_add_u32(xua, SUA_IEI_SRC_REF, src_ref); + + return xua; +} + +/* generate RELCO from incoming XUA and send it */ +static void tx_relco_from_xua(struct osmo_sccp_instance *inst, + struct xua_msg *in) +{ + struct xua_msg *xua; + uint32_t route_ctx, dest_ref, src_ref; + + route_ctx = xua_msg_get_u32(in, SUA_IEI_ROUTE_CTX); + /* get *source* reference and use as destination ref */ + dest_ref = xua_msg_get_u32(in, SUA_IEI_SRC_REF); + /* get *dest* reference and use as source ref */ + src_ref = xua_msg_get_u32(in, SUA_IEI_DEST_REF); + + xua = gen_relco(route_ctx, dest_ref, src_ref); + /* copy over the MTP parameters */ + xua->mtp.dpc = in->mtp.opc; + xua->mtp.opc = in->mtp.dpc; + xua->mtp.sio = in->mtp.sio; + + /* send to SCRC for transmission */ + sccp_scrc_rx_scoc_conn_msg(inst, xua); + xua_msg_free(xua); +} + +/* Generate a RLSD based in input arguments */ +static struct xua_msg *gen_rlsd(uint32_t route_ctx, uint32_t dest_ref, + uint32_t src_ref) +{ + struct xua_msg *xua = xua_msg_alloc(); + + xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_RELRE); + xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, route_ctx); + xua_msg_add_u32(xua, SUA_IEI_DEST_REF, dest_ref); + xua_msg_add_u32(xua, SUA_IEI_SRC_REF, src_ref); + + return xua; +} + +/* Generate a RLSD to both the remote side and the local conn */ +static void tx_rlsd_from_xua_twoway(struct sccp_connection *conn, + struct xua_msg *in) +{ + struct xua_msg *xua; + uint32_t route_ctx, dest_ref, src_ref; + + route_ctx = xua_msg_get_u32(in, SUA_IEI_ROUTE_CTX); + /* get *source* reference and use as destination ref */ + dest_ref = xua_msg_get_u32(in, SUA_IEI_SRC_REF); + /* get *source* reference and use as destination ref */ + src_ref = xua_msg_get_u32(in, SUA_IEI_DEST_REF); + + /* Generate RLSD towards remote peer */ + xua = gen_rlsd(route_ctx, dest_ref, src_ref); + /* copy over the MTP parameters */ + xua->mtp.dpc = in->mtp.opc; + xua->mtp.opc = in->mtp.dpc; + xua->mtp.sio = in->mtp.sio; + /* send to SCRC for transmission */ + sccp_scrc_rx_scoc_conn_msg(conn->inst, xua); + xua_msg_free(xua); + + /* Generate RLSD towards local peer */ + xua = gen_rlsd(conn->inst->route_ctx, conn->conn_id, conn->remote_ref); + xua->mtp.dpc = in->mtp.dpc; + xua->mtp.opc = conn->remote_pc; + xua->mtp.sio = in->mtp.sio; + osmo_fsm_inst_dispatch(conn->fi, SCOC_E_RCOC_RLSD_IND, xua); + xua_msg_free(xua); +} + +/* process received message for unasigned local reference */ +static void sccp_scoc_rx_unass_local_ref(struct osmo_sccp_instance *inst, + struct xua_msg *xua) +{ + /* we have received a message with unassigned destination local + * reference and thus apply the action indicated in Table + * B.2/Q.714 */ + switch (xua->hdr.msg_type) { + case SUA_CO_COAK: /* CC */ + case SUA_CO_COIT: /* IT */ + case SUA_CO_RESRE: /* RSR */ + case SUA_CO_RESCO: /* RSC */ + /* Send COERR */ + tx_coerr_from_xua(inst, xua, SCCP_ERROR_LRN_MISMATCH_UNASSIGNED); + break; + case SUA_CO_COREF: /* CREF */ + case SUA_CO_RELCO: /* RLC */ + case SUA_CO_CODT: /* DT1 */ + case SUA_CO_CODA: /* AK */ + case SUA_CO_COERR: /* ERR */ + /* DISCARD */ + break; + case SUA_CO_RELRE: /* RLSD */ + /* Send RLC */ + tx_relco_from_xua(inst, xua); + break; + default: + LOGP(DLSCCP, LOGL_NOTICE, "Unhandled %s\n", + xua_hdr_dump(xua, &xua_dialect_sua)); + break; + } +} + +/* process received message for invalid source local reference */ +static void sccp_scoc_rx_inval_src_ref(struct sccp_connection *conn, + struct xua_msg *xua) +{ + /* we have received a message with invalid source local + * reference and thus apply the action indicated in Table + * B.2/Q.714 */ + switch (xua->hdr.msg_type) { + case SUA_CO_RELRE: /* RLSD */ + case SUA_CO_RESRE: /* RSR */ + case SUA_CO_RESCO: /* RSC */ + /* Send ERR */ + tx_coerr_from_xua(conn->inst, xua, SCCP_ERROR_LRN_MISMATCH_INCONSISTENT); + break; + case SUA_CO_COIT: /* IT */ + /* FIXME: RLSD to both sides */ + tx_rlsd_from_xua_twoway(conn, xua); + break; + case SUA_CO_RELCO: /* RLC */ + /* DISCARD */ + break; + default: + LOGP(DLSCCP, LOGL_NOTICE, "Unhandled %s\n", + xua_hdr_dump(xua, &xua_dialect_sua)); + break; + } +} + +/* process received message for invalid origin point code */ +static void sccp_scoc_rx_inval_opc(struct osmo_sccp_instance *inst, + struct xua_msg *xua) +{ + /* we have received a message with invalid origin PC and thus + * apply the action indiacted in Table B.2/Q.714 */ + switch (xua->hdr.msg_type) { + case SUA_CO_RELRE: /* RLSD */ + case SUA_CO_RESRE: /* RSR */ + case SUA_CO_RESCO: /* RSC */ + /* Send ERR */ + tx_coerr_from_xua(inst, xua, SCCP_ERROR_POINT_CODE_MISMATCH); + break; + case SUA_CO_RELCO: /* RLC */ + case SUA_CO_CODT: /* DT1 */ + case SUA_CO_CODA: /* AK */ + case SUA_CO_COERR: /* ERR */ + /* DISCARD */ + break; + default: + LOGP(DLSCCP, LOGL_NOTICE, "Unhandled %s\n", + xua_hdr_dump(xua, &xua_dialect_sua)); + break; + } +} + +/*! \brief Main entrance function for primitives from the SCRC (Routing Control) + * \param[in] inst SCCP Instance in which we operate + * \param[in] xua SUA message in xua_msg format */ +void sccp_scoc_rx_from_scrc(struct osmo_sccp_instance *inst, + struct xua_msg *xua) +{ + struct sccp_connection *conn; + struct osmo_sccp_user *scu; + uint32_t src_loc_ref; + int event; + + /* we basically try to convert the SUA message into an event, + * and then dispatch the event to the connection-specific FSM. + * If it is a CORE (Connect REquest), we create the connection + * (and imlpicitly its FSM) first */ + + if (xua->hdr.msg_type == SUA_CO_CORE) { + scu = sccp_find_user(inst, xua); + if (!scu) { + /* this shouldn't happen, as the caller should + * have already verified that a local user is + * equipped for this SSN */ + LOGP(DLSCCP, LOGL_ERROR, "Cannot find user for " + "CORE ?!?\n"); + return; + } + /* Allocate new connection */ + conn = conn_create(inst); + conn->user = scu; + } else { + uint32_t conn_id; + /* Resolve existing connection */ + conn_id = xua_msg_get_u32(xua, SUA_IEI_DEST_REF); + conn = conn_find_by_id(inst, conn_id); + if (!conn) { + LOGP(DLSCCP, LOGL_NOTICE, "Cannot find connection for " + "local reference %u\n", conn_id); + sccp_scoc_rx_unass_local_ref(inst, xua); + return; + } + } + OSMO_ASSERT(conn); + OSMO_ASSERT(conn->fi); + + DEBUGP(DLSCCP, "Received %s for local reference %u\n", + xua_hdr_dump(xua, &xua_dialect_sua), conn->conn_id); + + if (xua->hdr.msg_type != SUA_CO_CORE && + xua->hdr.msg_type != SUA_CO_COAK && + xua->hdr.msg_type != SUA_CO_COREF) { + if (xua_msg_find_tag(xua, SUA_IEI_SRC_REF)) { + /* Check if received source local reference != + * the one we saved in local state */ + src_loc_ref = xua_msg_get_u32(xua, SUA_IEI_SRC_REF); + if (src_loc_ref != conn->remote_ref) { + sccp_scoc_rx_inval_src_ref(conn, xua); + return; + } + } + + /* Check if received OPC != the remote_pc we stored locally */ + if (xua->mtp.opc != conn->remote_pc) { + sccp_scoc_rx_inval_opc(inst, xua); + return; + } + } + + /* Map from XUA message to event */ + event = xua_msg_event_map(xua, sua_scoc_event_map, ARRAY_SIZE(sua_scoc_event_map)); + if (event < 0) { + LOGP(DLSCCP, LOGL_ERROR, "Cannot map SCRC msg %s to event\n", + xua_hdr_dump(xua, &xua_dialect_sua)); + /* Table B.1/Q714 states DISCARD for any message with + * unknown type */ + return; + } + + /* Dispatch event to existing connection */ + osmo_fsm_inst_dispatch(conn->fi, event, xua); +} + +/* get the Connection ID of the given SCU primitive */ +static uint32_t scu_prim_conn_id(const struct osmo_scu_prim *prim) +{ + switch (prim->oph.primitive) { + case OSMO_SCU_PRIM_N_CONNECT: + return prim->u.connect.conn_id; + case OSMO_SCU_PRIM_N_DATA: + return prim->u.data.conn_id; + case OSMO_SCU_PRIM_N_DISCONNECT: + return prim->u.disconnect.conn_id; + case OSMO_SCU_PRIM_N_RESET: + return prim->u.reset.conn_id; + default: + return 0; + } +} + +/*! \brief Main entrance function for primitives from SCCP User + * \param[in] scu SCCP User sending us the primitive + * \param[in] oph Osmocom primitive sent by the user + * \returns 0 on success; negative on error */ +int osmo_sccp_user_sap_down(struct osmo_sccp_user *scu, struct osmo_prim_hdr *oph) +{ + struct osmo_scu_prim *prim = (struct osmo_scu_prim *) oph; + struct osmo_sccp_instance *inst = scu->inst; + struct msgb *msg = prim->oph.msg; + struct sccp_connection *conn; + int rc = 0; + int event; + + LOGP(DLSCCP, LOGL_DEBUG, "Received SCCP User Primitive %s)\n", + osmo_scu_prim_name(&prim->oph)); + + switch (OSMO_PRIM_HDR(&prim->oph)) { + case OSMO_PRIM(OSMO_SCU_PRIM_N_UNITDATA, PRIM_OP_REQUEST): + /* other CL primitives? */ + /* Connectionless by-passes this altogether */ + return sccp_sclc_user_sap_down(scu, oph); + case OSMO_PRIM(OSMO_SCU_PRIM_N_CONNECT, PRIM_OP_REQUEST): + /* Allocate new connection structure */ + conn = conn_create_id(inst, prim->u.connect.conn_id); + if (!conn) { + /* FIXME: inform user */ + goto out; + } + conn->user = scu; + break; + case OSMO_PRIM(OSMO_SCU_PRIM_N_CONNECT, PRIM_OP_RESPONSE): + case OSMO_PRIM(OSMO_SCU_PRIM_N_DATA, PRIM_OP_REQUEST): + case OSMO_PRIM(OSMO_SCU_PRIM_N_DISCONNECT, PRIM_OP_REQUEST): + case OSMO_PRIM(OSMO_SCU_PRIM_N_RESET, PRIM_OP_REQUEST): + /* Resolve existing connection structure */ + conn = conn_find_by_id(inst, scu_prim_conn_id(prim)); + if (!conn) { + /* FIXME: inform user */ + goto out; + } + break; + } + + /* Map from primitive to event */ + event = osmo_event_for_prim(oph, scu_scoc_event_map); + + /* Dispatch event into connection */ + rc = osmo_fsm_inst_dispatch(conn->fi, event, prim); +out: + /* the SAP is supposed to consume the primitive/msgb */ + msgb_free(msg); + + return rc; +} + +void sccp_scoc_flush_connections(struct osmo_sccp_instance *inst) +{ + struct sccp_connection *conn, *conn2; + + llist_for_each_entry_safe(conn, conn2, &inst->connections, list) + conn_destroy(conn); +} diff --git a/src/sccp_scrc.c b/src/sccp_scrc.c new file mode 100644 index 0000000..9bccc0a --- /dev/null +++ b/src/sccp_scrc.c @@ -0,0 +1,473 @@ +/* SCCP Routing Control (SCRC) according to ITU-T Q.714 */ + +/* (C) 2015-2017 by Harald Welte + * All Rights reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include "sccp_internal.h" +#include "xua_internal.h" + +/*********************************************************************** + * Helper Functions + ***********************************************************************/ + +static bool sua_is_connectionless(struct xua_msg *xua) +{ + if (xua->hdr.msg_class == SUA_MSGC_CL) + return true; + else + return false; +} + +static bool sua_is_cr(struct xua_msg *xua) +{ + if (xua->hdr.msg_class == SUA_MSGC_CO && + xua->hdr.msg_type == SUA_CO_CORE) + return true; + + return false; +} + +static bool dpc_accessible(struct osmo_sccp_instance *inst, uint32_t pc) +{ + /* TODO: implement this! */ + return true; +} + +static bool sccp_available(struct osmo_sccp_instance *inst, + const struct osmo_sccp_addr *addr) +{ + /* TODO: implement this! */ + return true; +} + +static int sua2sccp_tx_m3ua(struct osmo_sccp_instance *inst, + struct xua_msg *sua) +{ + struct msgb *msg; + struct osmo_mtp_prim *omp; + struct osmo_mtp_transfer_param *param; + struct osmo_ss7_instance *s7i = inst->ss7; + uint32_t remote_pc = sua->mtp.dpc; + + /* 1) encode the SUA in xua_msg to SCCP message */ + msg = osmo_sua_to_sccp(sua); + if (!msg) { + LOGP(DLSCCP, LOGL_ERROR, "Cannot encode SUA to SCCP\n"); + return -1; + } + + /* 2) wrap into MTP-TRANSFER.req primtiive */ + msg->l2h = msg->data; + omp = (struct osmo_mtp_prim *) msgb_push(msg, sizeof(*omp)); + osmo_prim_init(&omp->oph, MTP_SAP_USER, + OSMO_MTP_PRIM_TRANSFER, PRIM_OP_REQUEST, msg); + param = &omp->u.transfer; + if (sua->mtp.opc) + param->opc = sua->mtp.opc; + else + param->opc = s7i->cfg.primary_pc; + param->dpc = remote_pc; + param->sls = sua->mtp.sls; + param->sio = MTP_SIO(MTP_SI_SCCP, s7i->cfg.network_indicator); + + /* 3) send via MTP-SAP (osmo_ss7_instance) */ + return osmo_ss7_user_mtp_xfer_req(s7i, omp); +} + +/* Gererate MTP-TRANSFER.req from xUA message */ +static int gen_mtp_transfer_req_xua(struct osmo_sccp_instance *inst, + struct xua_msg *xua, + const struct osmo_sccp_addr *called) +{ + struct osmo_ss7_route *rt; + + /* this is a bit fishy due to the different requirements of + * classic SSCP/MTP compared to various SIGTRAN stackings. + * Normally, we would expect a fully encoded SCCP message here, + * but then if the route points to a SUA link, we actually need + * the SUA version of the message. + * + * We need to differentiate the following cases: + * a) SUA: encode XUA to SUA and send via ASP + * b) M3UA: encode XUA to SCCP, create MTP-TRANSFER.req + * primitive and send it via ASP + * c) M2UA/M2PA or CS7: encode XUA, create MTP-TRANSFER.req + * primitive and send it via link + */ + + if (called->presence & OSMO_SCCP_ADDR_T_PC) + xua->mtp.dpc = called->pc; + if (!xua->mtp.dpc) { + LOGP(DLSCCP, LOGL_ERROR, "MTP-TRANSFER.req from SCCP " + "without DPC?!?\n"); + return -1; + } + + rt = osmo_ss7_route_lookup(inst->ss7, xua->mtp.dpc); + if (!rt) { + LOGP(DLSCCP, LOGL_ERROR, "MTP-TRANSFER.req from SCCP for " + "DPC %u: no route!\n", xua->mtp.dpc); + return -1; + } + + if (rt->dest.as) { + struct osmo_ss7_as *as = rt->dest.as; + switch (as->cfg.proto) { + case OSMO_SS7_ASP_PROT_M3UA: + return sua2sccp_tx_m3ua(inst, xua); + default: + LOGP(DLSCCP, LOGL_ERROR, "MTP-TRANSFER.req for " + "unknown protocol %u\n", as->cfg.proto); + break; + } + } else if (rt->dest.linkset) { + LOGP(DLSCCP, LOGL_ERROR, "MTP-TRANSFER.req from SCCP for " + "linkset %s unsupported\n", rt->dest.linkset->cfg.name); + } else { + OSMO_ASSERT(0); + } + return -1; +} + +/*********************************************************************** + * Global Title Translation + ***********************************************************************/ + +static int translate(struct osmo_sccp_instance *inst, + const struct osmo_sccp_addr *called, + struct osmo_sccp_addr *translated) +{ + /* TODO: implement this! */ + *translated = *called; + return 0; +} + + +/*********************************************************************** + * Individual SCRC Nodes + ***********************************************************************/ + +static int scrc_local_out_common(struct osmo_sccp_instance *inst, + struct xua_msg *xua, + const struct osmo_sccp_addr *called); + +static int scrc_node_12(struct osmo_sccp_instance *inst, struct xua_msg *xua, + const struct osmo_sccp_addr *called) +{ + /* TODO: Determine restriction */ + /* TODO: Treat Calling Party Addr */ + /* TODO: Hop counter */ + /* MTP-TRANSFER.req to MTP */ + return gen_mtp_transfer_req_xua(inst, xua, called); +} + +static int scrc_node_2(struct osmo_sccp_instance *inst, struct xua_msg *xua, + const struct osmo_sccp_addr *called) +{ + /* Node 2 on Sheet 5, only CO */ + /* Is DPC accessible? */ + if (!dpc_accessible(inst, called->pc)) { + /* Error: MTP Failure */ + /* Routing Failure SCRC -> SCOC */ + sccp_scoc_rx_scrc_rout_fail(inst, xua, + SCCP_RETURN_CAUSE_MTP_FAILURE); + return 0; + } + /* Is SCCP available? */ + if (!sccp_available(inst, called)) { + /* Error: SCCP Failure */ + /* Routing Failure SCRC -> SCOC */ + sccp_scoc_rx_scrc_rout_fail(inst, xua, + SCCP_RETURN_CAUSE_SCCP_FAILURE); + return 0; + } + return scrc_node_12(inst, xua, called); +} + +static int scrc_node_7(struct osmo_sccp_instance *inst, + struct xua_msg *xua, + const struct osmo_sccp_addr *called) +{ + /* Connection Oriented? */ + if (sua_is_connectionless(xua)) { + /* TODO: Perform Capability Test */ + /* TODO: Canges Needed? */ + if (0) { + /* Changes Needed -> SCLC */ + return 0; + } + } else { + /* TODO: Coupling Required? */ + if (0) { + /* Node 13 (Sheet 5) */ + } + } + return scrc_node_12(inst, xua, called); +} + +/* Node 4 (Sheet 3) */ +static int scrc_node_4(struct osmo_sccp_instance *inst, + struct xua_msg *xua, uint32_t return_cause) +{ + /* TODO: Routing Failure SCRC -> OMAP */ + if (sua_is_connectionless(xua)) { + /* Routing Failure SCRC -> SCLC */ + sccp_sclc_rx_scrc_rout_fail(inst, xua, return_cause); + } else { + /* Routing Failure SCRC -> SCOC */ + sccp_scoc_rx_scrc_rout_fail(inst, xua, return_cause); + } + return 0; +} + +static int scrc_translate_node_9(struct osmo_sccp_instance *inst, + struct xua_msg *xua, + const struct osmo_sccp_addr *called) +{ + struct osmo_sccp_addr translated; + int rc; + + /* Translate */ + rc = translate(inst, called, &translated); + /* Node 9 (Sheet 3) */ + if (rc < 0) { + /* Node 4 (Sheet 3) */ + return scrc_node_4(inst, xua, + SCCP_RETURN_CAUSE_NO_TRANSLATION); + } + /* Route on SSN? */ + if (translated.ri != OSMO_SCCP_RI_SSN_PC && + translated.ri != OSMO_SCCP_RI_SSN_IP) { + /* TODO: GT Routing */ + /* Node 7 (Sheet 5) */ + return scrc_node_7(inst, xua, called); + } + + /* Check DPC resultant from GT translation */ + if (osmo_ss7_pc_is_local(inst->ss7, translated.pc)) { + if (sua_is_connectionless(xua)) { + /* CL_MSG -> SCLC */ + sccp_sclc_rx_from_scrc(inst, xua); + } else { + /* Node 1 (Sheet 3) */ + /* CO_MSG -> SCOC */ + sccp_scoc_rx_from_scrc(inst, xua); + } + return 0; + } else { + /* Availability already checked */ + /* Node 7 (Sheet 5) */ + return scrc_node_7(inst, xua, called); + } +} + +/* Node 6 (Sheet 3) */ +static int scrc_node_6(struct osmo_sccp_instance *inst, + struct xua_msg *xua, + const struct osmo_sccp_addr *called) +{ + struct osmo_sccp_user *scu; + + scu = sccp_user_find(inst, called->ssn, called->pc); + + /* Is subsystem equipped? */ + if (!scu) { + /* Error: unequipped user */ + return scrc_node_4(inst, xua, + SCCP_RETURN_CAUSE_UNEQUIPPED_USER); + } + /* Is subsystem available? */ + if (0 /* !subsys_available(scu) */) { + /* Error: subsystem failure */ + /* TODO: SCRC -> SSPC */ + if (sua_is_connectionless(xua)) { + /* Routing Failure SCRC -> SCLC */ + sccp_sclc_rx_scrc_rout_fail(inst, xua, + SCCP_RETURN_CAUSE_SUBSYSTEM_FAILURE); + } else { + /* Routing Failure SCRC -> SCOC */ + sccp_scoc_rx_scrc_rout_fail(inst, xua, + SCCP_RETURN_CAUSE_SUBSYSTEM_FAILURE); + } + return 0; + } + if (sua_is_connectionless(xua)) { + /* CL_MSG -> SCLC */ + sccp_sclc_rx_from_scrc(inst, xua); + } else { + /* Node 1 (Sheet 3) */ + /* CO_MSG -> SCOC */ + sccp_scoc_rx_from_scrc(inst, xua); + } + return 0; +} + +static int scrc_local_out_common(struct osmo_sccp_instance *inst, + struct xua_msg *xua, + const struct osmo_sccp_addr *called) +{ + struct osmo_ss7_instance *s7i = inst->ss7; + + /* Called address includes DPC? */ + if (called->presence & OSMO_SCCP_ADDR_T_PC) { + if (!osmo_ss7_pc_is_local(s7i, called->pc)) { + /* Node 7 of sheet 5 */ + /* Coupling required: no */ + return scrc_node_12(inst, xua, called); + } + /* Called address includes SSN? */ + if (called->presence & OSMO_SCCP_ADDR_T_SSN) { + if (translate && + (called->presence & OSMO_SCCP_ADDR_T_GT)) + return scrc_translate_node_9(inst, xua, called); + else + return scrc_node_6(inst, xua, called); + } + } + /* No SSN in CalledAddr or no DPC included */ + if (!(called->presence & OSMO_SCCP_ADDR_T_GT)) { + /* Error reason: Unqualified */ + /* TODO: Routing Failure SCRC -> OMAP */ + /* Node 4 (Sheet 3) */ + return scrc_node_4(inst, xua, + SCCP_RETURN_CAUSE_UNQUALIFIED); + } else + return scrc_translate_node_9(inst, xua, called); +} + +/*********************************************************************** + * Entrance points from MTP, SCLC, SCOC, ... + ***********************************************************************/ + +/* Figure C.1/Q.714 - SCCP Routing control procedures (SCRC) */ + +/* Connection oriented message SCOC -> SCRC */ +int sccp_scrc_rx_scoc_conn_msg(struct osmo_sccp_instance *inst, + struct xua_msg *xua) +{ + struct osmo_sccp_addr called; + + LOGP(DLSS7, LOGL_DEBUG, "%s: %s\n", __func__, xua_msg_dump(xua, &xua_dialect_sua)); + + sua_addr_parse(&called, xua, SUA_IEI_DEST_ADDR); + + /* Is this a CR message ? */ + if (xua->hdr.msg_type != SUA_CO_CORE) + return scrc_node_2(inst, xua, &called); + + /* TOOD: Coupling performed (not supported) */ + if (0) + return scrc_node_2(inst, xua, &called); + + return scrc_local_out_common(inst, xua, &called); +} + +/* Connectionless Message SCLC -> SCRC */ +int sccp_scrc_rx_sclc_msg(struct osmo_sccp_instance *inst, + struct xua_msg *xua) +{ + struct osmo_sccp_addr called; + + LOGP(DLSS7, LOGL_DEBUG, "%s: %s\n", __func__, xua_msg_dump(xua, &xua_dialect_sua)); + + sua_addr_parse(&called, xua, SUA_IEI_DEST_ADDR); + + /* Message Type */ + if (xua->hdr.msg_type == SUA_CL_CLDR) { + /* UDTS, XUDTS or LUDTS */ + if (called.ri != OSMO_SCCP_RI_GT) + return scrc_node_7(inst, xua, &called); + /* Fall-through */ + } else { + if (0 /* TODO: translation already performed */) { + /* Node 12 (Sheet 5) */ + return scrc_node_12(inst, xua, &called); + } + } + return scrc_local_out_common(inst, xua, &called); +} + +/* Figure C.1/Q.714 Sheet 1 of 12, after we converted the + * MTP-TRANSFER.ind to SUA */ +int scrc_rx_mtp_xfer_ind_xua(struct osmo_sccp_instance *inst, + struct xua_msg *xua) +{ + struct osmo_sccp_addr called; + uint32_t proto_class; + struct xua_msg_part *hop_ctr_part; + + LOGP(DLSS7, LOGL_DEBUG, "%s: %s\n", __func__, xua_msg_dump(xua, &xua_dialect_sua)); + /* TODO: SCCP or nodal congestion? */ + + /* CR or CL message? */ + if (!sua_is_connectionless(xua) && !sua_is_cr(xua)) { + /* Node 1 (Sheet 3) */ + /* deliver to SCOC */ + sccp_scoc_rx_from_scrc(inst, xua); + return 0; + } + /* We only treat connectionless and CR below */ + + sua_addr_parse(&called, xua, SUA_IEI_DEST_ADDR); + + /* Route on GT? */ + if (called.ri != OSMO_SCCP_RI_GT) { + /* Node 6 (Sheet 3) */ + return scrc_node_6(inst, xua, &called); + } + /* Message with hop-counter? */ + hop_ctr_part = xua_msg_find_tag(xua, SUA_IEI_S7_HOP_CTR); + if (hop_ctr_part) { + uint32_t hop_counter = xua_msg_part_get_u32(hop_ctr_part); + if (hop_counter <= 1) { + /* Error: hop-counter violation */ + /* node 4 */ + return scrc_node_4(inst, xua, + SCCP_RETURN_CAUSE_HOP_COUNTER_VIOLATION); + } + /* Decrement hop-counter */ + hop_counter--; + *(uint32_t *)hop_ctr_part->dat = htonl(hop_counter); + } + + /* node 3 (Sheet 2) */ + /* Protocol class 0? */ + proto_class = xua_msg_get_u32(xua, SUA_IEI_PROTO_CLASS); + switch (proto_class) { + case 0: + /* TODO: Assign SLS */ + break; + case 1: + /* TODO: Map incoming SLS to outgoing SLS */ + break; + default: + break; + } + return scrc_translate_node_9(inst, xua, &called); +} diff --git a/src/sccp_user.c b/src/sccp_user.c new file mode 100644 index 0000000..df02486 --- /dev/null +++ b/src/sccp_user.c @@ -0,0 +1,377 @@ +/* SCCP User related routines */ + +/* (C) 2017 by Harald Welte + * All Rights Reserved + * + * based on my 2011 Erlang implementation osmo_ss7/src/sua_sccp_conv.erl + * + * References: ITU-T Q.713 and IETF RFC 3868 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include + +#include +#include + +#include +#include +#include +#include + +#include "sccp_internal.h" +#include "xua_internal.h" + +/*! \brief Find a SCCP User registered for given PC+SSN or SSN only + * \param[in] inst SCCP Instance in which to search + * \param[in] ssn Sub-System Number to search for + * \param[in] pc Point Code to search for + * \returns Matching SCCP User; NULL if none found */ +struct osmo_sccp_user * +sccp_user_find(struct osmo_sccp_instance *inst, uint16_t ssn, uint32_t pc) +{ + struct osmo_sccp_user *scu; + + /* First try to find match for PC + SSN */ + llist_for_each_entry(scu, &inst->users, list) { + if (scu->pc_valid && scu->pc == pc && scu->ssn == ssn) + return scu; + } + + /* Then try to match on SSN only */ + llist_for_each_entry(scu, &inst->users, list) { + if (!scu->pc_valid && scu->ssn == ssn) + return scu; + } + + return NULL; +} + +/*! \brief Bind a SCCP User to a given Point Code + * \param[in] inst SCCP Instance + * \param[in] name human-readable name + * \param[in] ssn Sub-System Number to bind to + * \param[in] pc Point Code to bind to (if any) + * \param[in] pc_valid Whether or not \ref pc is valid/used + * \returns Callee-allocated SCCP User on success; negative otherwise */ +static struct osmo_sccp_user * +sccp_user_bind_pc(struct osmo_sccp_instance *inst, const char *name, + osmo_prim_cb prim_cb, uint16_t ssn, uint32_t pc, bool pc_valid) +{ + struct osmo_sccp_user *scu; + if (!pc_valid) + pc = 0; + + if (sccp_user_find(inst, ssn, pc)) + return NULL; + + LOGP(DLSCCP, LOGL_INFO, "Binding user '%s' to SSN=%u PC=%u (pc_valid=%u)\n", + name, ssn, pc, pc_valid); + + scu = talloc_zero(inst, struct osmo_sccp_user); + scu->name = talloc_strdup(scu, name); + scu->inst = inst; + scu->prim_cb = prim_cb; + scu->ssn = ssn; + scu->pc = pc; + scu->pc_valid = pc_valid; + llist_add_tail(&scu->list, &inst->users); + + return scu; +} + +/*! \brief Bind a given SCCP User to a given SSN+PC + * \param[in] inst SCCP Instance + * \param[in] name human-readable name + * \param[in] ssn Sub-System Number to bind to + * \param[in] pc Point Code to bind to (if any) + * \returns Callee-allocated SCCP User on success; negative otherwise */ +struct osmo_sccp_user * +osmo_sccp_user_bind_pc(struct osmo_sccp_instance *inst, const char *name, + osmo_prim_cb prim_cb, uint16_t ssn, uint32_t pc) +{ + return sccp_user_bind_pc(inst, name, prim_cb, ssn, pc, true); +} + +/*! \brief Bind a given SCCP User to a given SSN (at any PC) + * \param[in] inst SCCP Instance + * \param[in] name human-readable name + * \param[in] ssn Sub-System Number to bind to + * \returns Callee-allocated SCCP User on success; negative otherwise */ +struct osmo_sccp_user * +osmo_sccp_user_bind(struct osmo_sccp_instance *inst, const char *name, + osmo_prim_cb prim_cb, uint16_t ssn) +{ + return sccp_user_bind_pc(inst, name, prim_cb, ssn, 0, false); +} + +/*! \brief Unbind a given SCCP user + * \param[in] scu SCCP User which is to be un-bound. Will be destroyed + * at the time this function returns. */ +void osmo_sccp_user_unbind(struct osmo_sccp_user *scu) +{ + LOGP(DLSCCP, LOGL_INFO, "Unbinding user '%s' from SSN=%u PC=%u " + "(pc_valid=%u)\n", scu->name, scu->ssn, scu->pc, + scu->pc_valid); + /* FIXME: free/release all connections held by this user? */ + llist_del(&scu->list); + talloc_free(scu); +} + +/*! \brief Send a SCCP User SAP Primitive up to the User + * \param[in] scu SCCP User to whom to send the primitive + * \param[in] prim Primitive to send to the user + * \returns return value of the SCCP User's prim_cb() function */ +int sccp_user_prim_up(struct osmo_sccp_user *scu, struct osmo_scu_prim *prim) +{ + LOGP(DLSCCP, LOGL_DEBUG, "Delivering %s to SCCP User '%s'\n", + osmo_scu_prim_name(&prim->oph), scu->name); + return scu->prim_cb(&prim->oph, scu); +} + +/* prim_cb handed to MTP code for incoming MTP-TRANSFER.ind */ +static int mtp_user_prim_cb(struct osmo_prim_hdr *oph, void *ctx) +{ + struct osmo_sccp_instance *inst = ctx; + struct osmo_mtp_prim *omp = (struct osmo_mtp_prim *)oph; + struct xua_msg *xua; + + OSMO_ASSERT(oph->sap == MTP_SAP_USER); + + switch OSMO_PRIM(oph->primitive, oph->operation) { + case OSMO_PRIM(OSMO_MTP_PRIM_TRANSFER, PRIM_OP_INDICATION): + /* Convert from SCCP to SUA in xua_msg format */ + xua = osmo_sccp_to_xua(oph->msg); + xua->mtp = omp->u.transfer; + /* hand this primitive into SCCP via the SCRC code */ + return scrc_rx_mtp_xfer_ind_xua(inst, xua); + default: + LOGP(DLSCCP, LOGL_ERROR, "Unknown primitive %u:%u receivd\n", + oph->primitive, oph->operation); + return -1; + } +} + +static LLIST_HEAD(sccp_instances); + +/*! \brief create a SCCP Instance and register it as user with SS7 inst + * \param[in] ss7 SS7 instance to which this SCCP instance belongs + * \param[in] priv private data to be stored within SCCP instance + * \returns callee-allocated SCCP instance on success; NULL on error */ +struct osmo_sccp_instance * +osmo_sccp_instance_create(struct osmo_ss7_instance *ss7, void *priv) +{ + struct osmo_sccp_instance *inst; + + inst = talloc_zero(ss7, struct osmo_sccp_instance); + if (!inst) + return NULL; + + inst->ss7 = ss7; + inst->priv = priv; + INIT_LLIST_HEAD(&inst->connections); + INIT_LLIST_HEAD(&inst->users); + + inst->ss7_user.inst = ss7; + inst->ss7_user.name = "SCCP"; + inst->ss7_user.prim_cb = mtp_user_prim_cb; + inst->ss7_user.priv = inst; + + osmo_ss7_user_register(ss7, MTP_SI_SCCP, &inst->ss7_user); + + llist_add_tail(&inst->list, &sccp_instances); + + return inst; +} + +void osmo_sccp_instance_destroy(struct osmo_sccp_instance *inst) +{ + struct osmo_sccp_user *scu, *scu2; + + inst->ss7->sccp = NULL; + osmo_ss7_user_unregister(inst->ss7, MTP_SI_SCCP, &inst->ss7_user); + + llist_for_each_entry_safe(scu, scu2, &inst->users, list) { + osmo_sccp_user_unbind(scu); + } + sccp_scoc_flush_connections(inst); + llist_del(&inst->list); + talloc_free(inst); +} + +/*********************************************************************** + * Convenience function for CLIENT + ***********************************************************************/ + +struct osmo_sccp_instance * +osmo_sccp_simple_client(void *ctx, const char *name, uint32_t pc, + enum osmo_ss7_asp_protocol prot, + int local_port, int remote_port, const char *remote_ip) +{ + struct osmo_ss7_instance *ss7; + struct osmo_ss7_as *as; + struct osmo_ss7_route *rt; + struct osmo_ss7_asp *asp; + char *as_name, *asp_name; + + if (!remote_port || remote_port < 0) + remote_port = osmo_ss7_asp_protocol_port(prot); + if (local_port < 0) + local_port = osmo_ss7_asp_protocol_port(prot); + + /* allocate + initialize SS7 instance */ + ss7 = osmo_ss7_instance_find_or_create(ctx, 1); + if (!ss7) + return NULL; + ss7->cfg.primary_pc = pc; + + as_name = talloc_asprintf(ctx, "as-clnt-%s", name); + asp_name = talloc_asprintf(ctx, "asp-clnt-%s", name); + + /* application server */ + as = osmo_ss7_as_find_or_create(ss7, as_name, prot); + if (!as) + goto out_strings; + + /* install default route */ + rt = osmo_ss7_route_create(ss7->rtable_system, 0, 0, as_name); + if (!rt) + goto out_as; + talloc_free(as_name); + + /* application server process */ + asp = osmo_ss7_asp_find_or_create(ss7, asp_name, remote_port, local_port, + prot); + if (!asp) + goto out_rt; + asp->cfg.remote.host = talloc_strdup(asp, remote_ip); + osmo_ss7_as_add_asp(as, asp_name); + talloc_free(asp_name); + osmo_ss7_asp_restart(asp); + + /* Allocate SCCP stack + SCCP user */ + ss7->sccp = osmo_sccp_instance_create(ss7, NULL); + if (!ss7->sccp) + goto out_asp; + + return ss7->sccp; + +out_asp: + osmo_ss7_asp_destroy(asp); +out_rt: + osmo_ss7_route_destroy(rt); +out_as: + osmo_ss7_as_destroy(as); +out_strings: + talloc_free(as_name); + talloc_free(asp_name); + osmo_ss7_instance_destroy(ss7); + + return NULL; +} + +/*********************************************************************** + * Convenience function for SERVER + ***********************************************************************/ + +struct osmo_sccp_instance * +osmo_sccp_simple_server(void *ctx, uint32_t pc, + enum osmo_ss7_asp_protocol prot, int local_port, + const char *local_ip) +{ + struct osmo_ss7_instance *ss7; + struct osmo_xua_server *xs; + + if (local_port < 0) + local_port = osmo_ss7_asp_protocol_port(prot); + + /* allocate + initialize SS7 instance */ + ss7 = osmo_ss7_instance_find_or_create(ctx, 1); + if (!ss7) + return NULL; + ss7->cfg.primary_pc = pc; + + xs = osmo_ss7_xua_server_create(ss7, prot, local_port, local_ip); + if (!xs) + goto out_ss7; + + /* Allocate SCCP stack */ + ss7->sccp = osmo_sccp_instance_create(ss7, NULL); + if (!ss7->sccp) + goto out_xs; + + return ss7->sccp; + +out_xs: + osmo_ss7_xua_server_destroy(xs); +out_ss7: + osmo_ss7_instance_destroy(ss7); + + return NULL; +} + +struct osmo_sccp_instance * +osmo_sccp_simple_server_add_clnt(struct osmo_sccp_instance *inst, + enum osmo_ss7_asp_protocol prot, + const char *name, uint32_t pc, + int local_port, int remote_port, + const char *remote_ip) +{ + struct osmo_ss7_instance *ss7 = inst->ss7; + struct osmo_ss7_as *as; + struct osmo_ss7_route *rt; + struct osmo_ss7_asp *asp; + char *as_name, *asp_name; + + if (local_port < 0) + local_port = osmo_ss7_asp_protocol_port(prot); + + if (remote_port < 0) + remote_port = osmo_ss7_asp_protocol_port(prot); + + as_name = talloc_asprintf(ss7, "as-srv-%s", name); + asp_name = talloc_asprintf(ss7, "asp-srv-%s", name); + + /* application server */ + as = osmo_ss7_as_find_or_create(ss7, as_name, prot); + if (!as) + goto out_strings; + talloc_free(as_name); + + /* route only selected PC to the client */ + rt = osmo_ss7_route_create(ss7->rtable_system, pc, 0xffff, as_name); + if (!rt) + goto out_as; + + asp = osmo_ss7_asp_find_or_create(ss7, asp_name, remote_port, local_port, prot); + if (!asp) + goto out_rt; + asp->cfg.is_server = true; + osmo_ss7_as_add_asp(as, asp_name); + talloc_free(asp_name); + osmo_ss7_asp_restart(asp); + + return ss7->sccp; + +out_rt: + osmo_ss7_route_destroy(rt); +out_as: + osmo_ss7_as_destroy(as); +out_strings: + talloc_free(as_name); + talloc_free(asp_name); + + return NULL; +} -- To view, visit https://gerrit.osmocom.org/2215 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I916e895d9a4914b05483fe12ab5251f206d10dee Gerrit-PatchSet: 7 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Apr 10 11:03:01 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 11:03:01 +0000 Subject: [MERGED] libosmo-sccp[master]: Add SCCP <-> SUA message transcoding routines In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: Add SCCP <-> SUA message transcoding routines ...................................................................... Add SCCP <-> SUA message transcoding routines Change-Id: I8151a9b08a0b0ca97b9c73105ad4548512ce3be8 --- M src/Makefile.am A src/sccp2sua.c 2 files changed, 1,266 insertions(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/Makefile.am b/src/Makefile.am index ec3fe99..4455127 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -27,6 +27,7 @@ LIBVERSION=0:0:0 libosmo_sigtran_la_SOURCES = sccp_sap.c sua.c m3ua.c xua_msg.c sccp_helpers.c \ + sccp2sua.c \ osmo_ss7.c osmo_ss7_hmrt.c xua_asp_fsm.c xua_as_fsm.c libosmo_sigtran_la_LDFLAGS = -version-info $(LIBVERSION) -no-undefined -export-symbols-regex '^osmo_' libosmo_sigtran_la_LIBADD = $(LIBOSMOCORE_LIBS) $(LIBOSMONETIF_LIBS) $(LIBSCTP_LIBS) diff --git a/src/sccp2sua.c b/src/sccp2sua.c new file mode 100644 index 0000000..070a8cb --- /dev/null +++ b/src/sccp2sua.c @@ -0,0 +1,1265 @@ +/* SCCP <-> SUA transcoding routines */ + +/* (C) 2017 by Harald Welte + * All Rights Reserved + * + * based on my 2011 Erlang implementation osmo_ss7/src/sua_sccp_conv.erl + * + * References: ITU-T Q.713 and IETF RFC 3868 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "xua_internal.h" +#include "sccp_internal.h" + +/* libosmocore candidates */ + +static void msgb_put_u24be(struct msgb *msg, uint32_t val) +{ + msgb_put_u8(msg, (val >> 16) & 0xff); + msgb_put_u8(msg, (val >> 8) & 0xff); + msgb_put_u8(msg, val & 0xff); +} + +static void msgb_put_u16le(struct msgb *msg, uint16_t val) +{ + msgb_put_u8(msg, val & 0xff); + msgb_put_u8(msg, (val >> 8) & 0xff); +} + +/*! \brief load a 24bit value as big-endian */ +static uint32_t load_24be(const void *ptr) +{ + const uint8_t *data = ptr; + return (data[0] << 16) | (data[1] << 8) | data[2]; +} + + + +/*! \brief Parse ISUP style address of BCD digets + * \param[out] out_digits user-allocated buffer for ASCII digits + * \param[in] in BCD-encoded digits + * \param[in] in_num_bytes Size of \ref in in bytes + * \param[in] odd Odd (true) or even (false) number of digits + * \returns number of digits generated + * */ +int osmo_isup_party_parse(char *out_digits, const uint8_t *in, + unsigned int in_num_bytes, bool odd) +{ + char *out = out_digits; + unsigned int i; + + for (i = 0; i < in_num_bytes; i++) { + *out_digits++ = osmo_bcd2char(in[i] & 0x0F); + if (i+1 == in_num_bytes && odd) + break; + *out_digits++ = osmo_bcd2char(in[i] >> 4); + } + *out_digits = '\0'; + return (out_digits - out); +} + +/*! \brief Encode an ISUP style address of BCD digits + * \param[out] msg Message to which the encoded address is appended + * \param[in] in_digits NUL-terminated ASCII string of digits + * \returns number of octets used for encoding \ref in_digits */ +int osmo_isup_party_encode(struct msgb *msg, const char *in_digits) +{ + unsigned int num_digits = strlen(in_digits); + unsigned int i, num_octets = num_digits/2; + const char *cur_digit = in_digits; + uint8_t *cur; + + if (num_digits & 1) + num_octets++; + + cur = msgb_put(msg, num_octets); + + for (i = 0; i < num_octets; i++) { + cur[i] = osmo_char2bcd(*cur_digit++); + if (cur_digit - in_digits < num_digits) + cur[i] |= osmo_char2bcd(*cur_digit++) << 4; + } + return num_octets; +} + +/*! \brief Parse wire-encoded SCCP address into omso_sccp_addr + * \param[out] out user-allocated output data structure + * \param[in] addr wire-encoded SCCP address + * \param[in] addrlen Size of \ref addr in bytes + * \returns 0 in case of success, negative on error + * According to Q.713/3.4 and RFC3868/3.10.2 */ +int osmo_sccp_addr_parse(struct osmo_sccp_addr *out, + const uint8_t *addr, unsigned int addrlen) +{ + struct sccp_called_party_address *sca; + uint8_t *cur; + uint8_t encoding; + bool odd; + int rc; + + memset(out, 0, sizeof(*out)); + + sca = (struct sccp_called_party_address *) addr; + cur = sca->data; + + if (sca->routing_indicator) + out->ri = OSMO_SCCP_RI_SSN_PC; + else + out->ri = OSMO_SCCP_RI_GT; + + if (sca->point_code_indicator) { + out->presence |= OSMO_SCCP_ADDR_T_PC; + out->pc = ((cur[1] << 8) & 0x3f) | cur[0]; + cur += 2; + } + + if (sca->ssn_indicator) { + out->presence |= OSMO_SCCP_ADDR_T_SSN; + out->ssn = *cur; + cur += 1; + } + + switch (sca->global_title_indicator) { + case SCCP_TITLE_IND_NONE: + out->gt.gti = OSMO_SCCP_GTI_NO_GT; + return 0; + case SCCP_TITLE_IND_NATURE_ONLY: + out->presence |= OSMO_SCCP_ADDR_T_GT; + out->gt.gti = OSMO_SCCP_GTI_NAI_ONLY; + out->gt.nai = *cur & 0x7f; + if (*cur++ & 0x80) + odd = true; + else + odd = false; + break; + case SCCP_TITLE_IND_TRANSLATION_ONLY: + out->presence |= OSMO_SCCP_ADDR_T_GT; + out->gt.gti = OSMO_SCCP_GTI_TT_ONLY; + out->gt.tt = *cur++; + /* abort, for national use only */ + return -EINVAL; + case SCCP_TITLE_IND_TRANS_NUM_ENC: + out->presence |= OSMO_SCCP_ADDR_T_GT; + out->gt.gti = OSMO_SCCP_GTI_TT_NPL_ENC; + out->gt.tt = *cur++; + out->gt.npi = *cur >> 4; + switch (*cur++ & 0xF) { + case 1: + odd = true; + break; + case 2: + odd = false; + break; + default: + return -1; + } + break; + case SCCP_TITLE_IND_TRANS_NUM_ENC_NATURE: + out->presence |= OSMO_SCCP_ADDR_T_GT; + out->gt.gti = OSMO_SCCP_GTI_TT_NPL_ENC_NAI; + out->gt.tt = *cur++; + out->gt.npi = *cur >> 4; + encoding = *cur++ & 0xF; + switch (encoding) { + case 1: + odd = true; + break; + case 2: + odd = false; + break; + default: + LOGP(DLSUA, LOGL_ERROR, "Unknown GT encoding 0x%x\n", + encoding); + return -EINVAL; + } + out->gt.nai = *cur++ & 0x7f; + break; + default: + LOGP(DLSUA, LOGL_ERROR, "Unknown GTI %u in SCCP message\n", + sca->global_title_indicator); + return -EINVAL; + } + rc = osmo_isup_party_parse(out->gt.digits, cur, (addr+addrlen-cur), odd); + if (rc < 0) + return rc; + + return 0; +} + +/*! \brief encode a SCCP address from parsed format to wire format + * \param[out] msg message buffer to which address is to be appended + * \param[in] in data structure describing SCCP address + * \returns number of bytes written to \ref msg */ +int osmo_sccp_addr_encode(struct msgb *msg, const struct osmo_sccp_addr *in) +{ + struct sccp_called_party_address *sca; + bool odd; + + sca = (struct sccp_called_party_address *) msgb_put(msg, sizeof(*sca)); + switch (in->ri) { + case OSMO_SCCP_RI_SSN_PC: + sca->routing_indicator = 1; + break; + case OSMO_SCCP_RI_GT: + sca->routing_indicator = 0; + break; + default: + LOGP(DLSUA, LOGL_ERROR, "Unknown CCP Routing Indicator %u" + "requested\n", in->ri); + return -EINVAL; + } + + if (in->presence & OSMO_SCCP_ADDR_T_PC) { + sca->point_code_indicator = 1; + msgb_put_u16le(msg, in->pc & 0x3ff); + } + + if (in->presence & OSMO_SCCP_ADDR_T_SSN) { + sca->ssn_indicator = 1; + msgb_put_u8(msg, in->ssn); + } + + if (!(in->presence & OSMO_SCCP_ADDR_T_GT)) { + sca->global_title_indicator = SCCP_TITLE_IND_NONE; + goto out; + } + + odd = strlen(in->gt.digits) & 1; + switch (in->gt.gti) { + case OSMO_SCCP_GTI_NO_GT: + sca->global_title_indicator = SCCP_TITLE_IND_NONE; + goto out; + case OSMO_SCCP_GTI_NAI_ONLY: + sca->global_title_indicator = SCCP_TITLE_IND_NATURE_ONLY; + msgb_put_u8(msg, (odd << 7) | (in->gt.nai & 0x7f)); + break; + case OSMO_SCCP_GTI_TT_ONLY: + sca->global_title_indicator = SCCP_TITLE_IND_TRANSLATION_ONLY; + msgb_put_u8(msg, in->gt.tt); + /* abort, for national use only */ + LOGP(DLSUA, LOGL_ERROR, "Unsupported Translation Type %u" + "requested\n", in->gt.gti); + return -EINVAL; + case OSMO_SCCP_GTI_TT_NPL_ENC: + sca->global_title_indicator = SCCP_TITLE_IND_TRANS_NUM_ENC; + msgb_put_u8(msg, in->gt.tt); + msgb_put_u8(msg, (in->gt.npi << 4) | (odd ? 1 : 2)); + break; + case OSMO_SCCP_GTI_TT_NPL_ENC_NAI: + sca->global_title_indicator = SCCP_TITLE_IND_TRANS_NUM_ENC_NATURE; + msgb_put_u8(msg, in->gt.tt); + msgb_put_u8(msg, (in->gt.npi << 4) | (odd ? 1 : 2)); + msgb_put_u8(msg, in->gt.nai & 0x7f); + break; + } + osmo_isup_party_encode(msg, in->gt.digits); + +out: + /* return number of bytes written */ + return msg->tail - (uint8_t *)sca; +} + +/*! \brief convert SCCP address to SUA address + * \param xua user-provided xUA message to which address shall be added + * \param[in] iei SUA Information Element Identifier for address + * \param[in] addr SCCP wire format binary address + * \param[in] addrlen Size of \ref addr in bytes + * \returns 0 in case of success; negative on error */ +static int sccp_addr_to_sua(struct xua_msg *xua, uint16_t iei, const uint8_t *addr, + unsigned int addrlen) +{ + struct osmo_sccp_addr osa; + int rc; + + /* First decode the address from SCCP wire format to + * osmo_sccp_addr */ + rc = osmo_sccp_addr_parse(&osa, addr, addrlen); + if (rc < 0) + return rc; + + LOGP(DLSUA, LOGL_DEBUG, "Parsed Addr: %s\n", osmo_sccp_addr_dump(&osa)); + + /* Then re-encode it as SUA address */ + return xua_msg_add_sccp_addr(xua, iei, &osa); +} + +/*! \brief convenience wrapper around sccp_addr_to_sua() for variable mandatory addresses */ +static int sccp_addr_to_sua_ptr(struct xua_msg *xua, uint16_t iei, struct msgb *msg, uint8_t *ptr_addr) +{ + uint8_t *addr = ptr_addr + *ptr_addr + 1; + unsigned int addrlen = *(ptr_addr + *ptr_addr); + + return sccp_addr_to_sua(xua, iei, addr, addrlen); +} + +/*! \brief convert SUA address to SCCP address + * \param msg user-provided message buffer to which address shall be * appended + * \param[in] part SUA wire format binary address + * \returns 0 in case of success; negative on error */ +static int sua_addr_to_sccp(struct msgb *msg, struct xua_msg_part *part) +{ + struct osmo_sccp_addr osa; + int rc; + + /* First decode the address from SUA wire format to + * osmo_sccp_addr */ + rc = sua_addr_parse_part(&osa, part); + if (rc < 0) + return rc; + + /* Then re-encode it as SCCP address */ + return osmo_sccp_addr_encode(msg, &osa); +} + +/*! \brief Add a "SCCP Variable Mandatory Part" (Address format) to the given msgb + * \param msg Message buffer to which part shall be added + * \param[out] var_ptr pointer to relative pointer in SCCP header + * \param[in] xua xUA message from which to use address + * \param[in] iei xUA information element identifier of address */ +static int sccp_add_var_addr(struct msgb *msg, uint8_t *var_ptr, struct xua_msg *xua, uint16_t iei) +{ + struct xua_msg_part *part = xua_msg_find_tag(xua, iei); + uint8_t *lenbyte; + int rc; + if (!part) { + LOGP(DLSUA, LOGL_ERROR, "Cannot find IEI %u in SUA message\n", iei); + return -ENODEV; + } + + /* first allocate one byte for the length */ + lenbyte = msgb_put(msg, 1); + /* update the relative pointer to the length byte */ + *var_ptr = lenbyte - var_ptr; + + /* then append the encoded SCCP address */ + rc = sua_addr_to_sccp(msg, part); + if (rc < 0) + return rc; + + /* store the encoded length of the address */ + *lenbyte = rc; + + return rc; +} + +/*! \brief Add a "SCCP Variable Mandatory Part" to the given msgb + * \param msg Message buffer to which part shall be added + * \param[out] var_ptr pointer to relative pointer in SCCP header + * \param[in] xua xUA message from which to use source data + * \param[in] iei xUA information element identifier of source data */ +static int sccp_add_variable_part(struct msgb *msg, uint8_t *var_ptr, struct xua_msg *xua, uint16_t iei) +{ + struct xua_msg_part *part = xua_msg_find_tag(xua, iei); + uint8_t *lenbyte; + uint8_t *cur; + if (!part) { + LOGP(DLSUA, LOGL_ERROR, "Cannot find IEI %u in SUA message\n", iei); + return -ENODEV; + } + + /* first allocate one byte for the length */ + lenbyte = msgb_put(msg, 1); + /* update the relative pointer to the length byte */ + *var_ptr = lenbyte - var_ptr; + + /* then append the encoded SCCP address */ + cur = msgb_put(msg, part->len); + memcpy(cur, part->dat, part->len); + + /* store the encoded length of the address */ + *lenbyte = part->len; + + return part->len; +} + + +/*! \brief validate that SCCP part with pointer + length doesn't exceed msg tail + * \param[in] msg Message containing SCCP address + * \param[in] ptr_addr pointer to byte with relative SCCP pointer + * \returns true if OK; false if message inconsistent */ +static bool sccp_ptr_part_consistent(struct msgb *msg, uint8_t *ptr_addr) +{ + uint8_t *ptr; + + /* check the address of the relative pointer is within msg */ + if (ptr_addr < msg->data || ptr_addr > msg->tail) { + LOGP(DLSUA, LOGL_ERROR, "ptr_addr outside msg boundary\n"); + return false; + } + + ptr = ptr_addr + *ptr_addr; + if (ptr > msg->tail) { + LOGP(DLSUA, LOGL_ERROR, "ptr points outside msg boundary\n"); + return false; + } + + /* at destination of relative pointer is the length */ + if (ptr + 1 + *ptr > msg->tail) { + LOGP(DLSUA, LOGL_ERROR, "ptr + len points outside msg boundary\n"); + return false; + } + return true; +} + +/*! \brief convenience wrapper around xua_msg_add_data() for variable mandatory data */ +static int sccp_data_to_sua_ptr(struct xua_msg *xua, uint16_t iei, struct msgb *msg, uint8_t *ptr_addr) +{ + uint8_t *addr = ptr_addr + *ptr_addr + 1; + unsigned int addrlen = *(ptr_addr + *ptr_addr); + + return xua_msg_add_data(xua, iei, addrlen, addr); +} + +/*! \brief Convert a given SCCP option to SUA and add it to given xua_msg + * \param xua caller-provided xUA message to which option is to be added + * \param[in] sccp_opt_type SCCP option type (PNC) + * \param[in] opt_len size of \ref opt in bytes + * \param[in] opt pointer to wire-format encoded SCCP option data + * \returns 0 in case of success; negative on error */ +static int xua_msg_add_sccp_opt(struct xua_msg *xua, uint8_t sccp_opt_type, + uint16_t opt_len, uint8_t *opt) +{ + switch (sccp_opt_type) { + case SCCP_PNC_DESTINATION_LOCAL_REFERENCE: + if (opt_len != 3) + return -EINVAL; + xua_msg_add_u32(xua, SUA_IEI_DEST_REF, load_24be(opt)); + break; + case SCCP_PNC_SOURCE_LOCAL_REFERENCE: + if (opt_len != 3) + return -EINVAL; + xua_msg_add_u32(xua, SUA_IEI_SRC_REF, load_24be(opt)); + break; + case SCCP_PNC_CALLED_PARTY_ADDRESS: + if (opt_len < 3) + return -EINVAL; + sccp_addr_to_sua(xua, SUA_IEI_DEST_ADDR, opt, opt_len); + break; + case SCCP_PNC_CALLING_PARTY_ADDRESS: + if (opt_len < 3) + return -EINVAL; + sccp_addr_to_sua(xua, SUA_IEI_SRC_ADDR, opt, opt_len); + break; + case SCCP_PNC_PROTOCOL_CLASS: + if (opt_len < 1) + return -EINVAL; + xua_msg_add_u32(xua, SUA_IEI_PROTO_CLASS, *opt); + break; + case SCCP_PNC_CREDIT: + if (opt_len != 1) + return -EINVAL; + xua_msg_add_u32(xua, SUA_IEI_IMPORTANCE, *opt & 0x7); + break; + case SCCP_PNC_RELEASE_CAUSE: + if (opt_len != 1) + return -EINVAL; + xua_msg_add_u32(xua, SUA_IEI_CAUSE, SUA_CAUSE_T_RELEASE | *opt); + break; + case SCCP_PNC_RETURN_CAUSE: + if (opt_len != 1) + return -EINVAL; + xua_msg_add_u32(xua, SUA_IEI_CAUSE, SUA_CAUSE_T_RETURN | *opt); + break; + case SCCP_PNC_RESET_CAUSE: + if (opt_len != 1) + return -EINVAL; + xua_msg_add_u32(xua, SUA_IEI_CAUSE, SUA_CAUSE_T_RESET | *opt); + break; + case SCCP_PNC_ERROR_CAUSE: + if (opt_len != 1) + return -EINVAL; + xua_msg_add_u32(xua, SUA_IEI_CAUSE, SUA_CAUSE_T_ERROR | *opt); + break; + case SCCP_PNC_REFUSAL_CAUSE: + if (opt_len != 1) + return -EINVAL; + xua_msg_add_u32(xua, SUA_IEI_CAUSE, SUA_CAUSE_T_REFUSAL | *opt); + break; + case SCCP_PNC_DATA: + xua_msg_add_data(xua, SUA_IEI_DATA, opt_len, opt); + break; + case SCCP_PNC_HOP_COUNTER: + if (opt_len != 1) + return -EINVAL; + xua_msg_add_u32(xua, SUA_IEI_S7_HOP_CTR, *opt); + break; + case SCCP_PNC_IMPORTANCE: + if (opt_len != 1) + return -EINVAL; + xua_msg_add_u32(xua, SUA_IEI_IMPORTANCE, *opt & 0x7); + break; + case SCCP_PNC_LONG_DATA: + xua_msg_add_data(xua, SUA_IEI_DATA, opt_len, opt); + break; + case SCCP_PNC_SEGMENTATION: + case SCCP_PNC_SEGMENTING: + case SCCP_PNC_RECEIVE_SEQ_NUMBER: + /* only in class 3 */ + case SCCP_PNC_SEQUENCING: + /* only in class 3 */ + default: + LOGP(DLSUA, LOGL_ERROR, "Unsupported SCCP option type %u\n", + sccp_opt_type); + return -1; + } + return 0; +} + +/*! \brief append a SCCP option header to the given message + * \param msg Message to which header is to be appended + * \param[in] pnc PNC of the option header + * \param[in] len length of the option, excluding the header */ +static void msgb_put_sccp_opt_hdr(struct msgb *msg, uint8_t pnc, uint8_t len) +{ + msgb_put_u8(msg, pnc); + msgb_put_u8(msg, len); +} + +/*! \brief append a SCCP option to the given message + * \param msg Message to which option is to be appended + * \param[in] pnc PNC of the option header + * \param[in] len length of the option, excluding the header + * \param[in] data actual data to be appended */ +static void msgb_put_sccp_opt(struct msgb *msg, uint8_t pnc, uint8_t len, const uint8_t *data) +{ + uint8_t *cur; + + msgb_put_sccp_opt_hdr(msg, pnc, len); + cur = msgb_put(msg, len); + memcpy(cur, data, len); +} + +/*! \brief Convert a given SUA option/IE to SCCP and add it to given * msgb + * \param msg caller-provided message buffer to which option is to be appended + * \param[in] opt xUA option/IE (messge part) to be converted+added + * \returns 0 in case of success; negative on error */ +static int sccp_msg_add_sua_opt(struct msgb *msg, struct xua_msg_part *opt) +{ + uint32_t tmp32; + uint8_t pnc, *lenptr; + int rc; + + switch (opt->tag) { + case SUA_IEI_DEST_REF: + msgb_put_sccp_opt_hdr(msg, SCCP_PNC_DESTINATION_LOCAL_REFERENCE, 3); + msgb_put_u24be(msg, xua_msg_part_get_u32(opt)); + break; + case SUA_IEI_SRC_REF: + msgb_put_sccp_opt_hdr(msg, SCCP_PNC_SOURCE_LOCAL_REFERENCE, 3); + msgb_put_u24be(msg, xua_msg_part_get_u32(opt)); + break; + case SUA_IEI_DEST_ADDR: + msgb_put_u8(msg, SCCP_PNC_CALLED_PARTY_ADDRESS); + lenptr = msgb_put(msg, 1); + rc = sua_addr_to_sccp(msg, opt); + if (rc < 0) + return rc; + *lenptr = rc; + break; + case SUA_IEI_SRC_ADDR: + msgb_put_u8(msg, SCCP_PNC_CALLING_PARTY_ADDRESS); + lenptr = msgb_put(msg, 1); + rc = sua_addr_to_sccp(msg, opt); + if (rc < 0) + return rc; + *lenptr = rc; + break; + case SUA_IEI_PROTO_CLASS: + msgb_put_sccp_opt_hdr(msg, SCCP_PNC_PROTOCOL_CLASS, 1); + msgb_put_u8(msg, xua_msg_part_get_u32(opt)); + break; + case SUA_IEI_CREDIT: + msgb_put_sccp_opt_hdr(msg, SCCP_PNC_CREDIT, 1); + msgb_put_u8(msg, xua_msg_part_get_u32(opt) & 0x7); + break; + case SUA_IEI_CAUSE: + tmp32 = xua_msg_part_get_u32(opt); + switch (tmp32 & SUA_CAUSE_T_MASK) { + case SUA_CAUSE_T_RETURN: + pnc = SCCP_PNC_RETURN_CAUSE; + break; + case SUA_CAUSE_T_REFUSAL: + pnc = SCCP_PNC_REFUSAL_CAUSE; + break; + case SUA_CAUSE_T_RELEASE: + pnc = SCCP_PNC_RELEASE_CAUSE; + break; + case SUA_CAUSE_T_RESET: + pnc = SCCP_PNC_RESET_CAUSE; + break; + case SUA_CAUSE_T_ERROR: + pnc = SCCP_PNC_ERROR_CAUSE; + break; + default: + LOGP(DLSUA, LOGL_ERROR, "Unknown SUA Cause Class 0x%04x\n", tmp32); + return -EINVAL; + } + msgb_put_sccp_opt_hdr(msg, pnc, 1); + msgb_put_u8(msg, tmp32 & 0xff); + break; + case SUA_IEI_DATA: + msgb_put_sccp_opt(msg, SCCP_PNC_DATA, opt->len, opt->dat); + break; + case SUA_IEI_S7_HOP_CTR: + msgb_put_sccp_opt_hdr(msg, SCCP_PNC_HOP_COUNTER, 1); + msgb_put_u8(msg, xua_msg_part_get_u32(opt)); + break; + case SUA_IEI_IMPORTANCE: + msgb_put_sccp_opt_hdr(msg, SCCP_PNC_IMPORTANCE, 1); + msgb_put_u8(msg, xua_msg_part_get_u32(opt) & 0x7); + break; + case SUA_IEI_ROUTE_CTX: + break; + case SUA_IEI_SEQ_CTRL: + /* TODO */ + break; + default: + LOGP(DLSUA, LOGL_ERROR, "Unknown SUA IEI 0x%04x\n", opt->tag); + return -1; + } + return 0; +} + +/*! \brief convert SCCP optional part to list of SUA options + * \param[in] msg Message buffer holding SCCP message + * \param[in] ptr_opt address of relative pointer to optional part + * \param xua caller-provided xUA message to which options are added + * \returns \ref xua in case of success, NULL on error (xua not freed!) */ +static struct xua_msg *sccp_to_xua_opt(struct msgb *msg, uint8_t *ptr_opt, struct xua_msg *xua) +{ + uint8_t *opt_start, *oneopt; + + /* some bounds checking */ + if (ptr_opt < msg->data || ptr_opt > msg->tail) + return NULL; + opt_start = ptr_opt + *ptr_opt; + if (opt_start > msg->tail) + return NULL; + + oneopt = opt_start; + + while (oneopt < msg->tail) { + uint8_t opt_type = oneopt[0]; + + if (opt_type == SCCP_PNC_END_OF_OPTIONAL) + return xua; + + if (opt_type == SCCP_PNC_LONG_DATA) { + uint16_t opt_len16; + /* two byte length field */ + if (oneopt + 2 > msg->tail) + return NULL; + opt_len16 = oneopt[1] << 8 | oneopt[2]; + if (oneopt + 3 + opt_len16 > msg->tail) + return NULL; + xua_msg_add_sccp_opt(xua, opt_type, opt_len16, oneopt+3); + oneopt += 3 + opt_len16; + } else { + uint8_t opt_len; + /* one byte length field */ + if (oneopt + 1 > msg->tail) + return NULL; + + opt_len = oneopt[1]; + if (oneopt + 2 + opt_len > msg->tail) + return NULL; + xua_msg_add_sccp_opt(xua, opt_type, opt_len, oneopt+2); + oneopt += 2 + opt_len; + } + } + return NULL; +} + +#define MAX_IES 6 +#define NUM_SCCP_MSGT (SCCP_MSG_TYPE_LUDTS+1) + +/* This table indicates which information elements are mandatory and not + * optional in SCCP, per message type */ +static const uint16_t sccp_mandatory[NUM_SCCP_MSGT][MAX_IES] = { + /* Table 3/Q.713 */ + [SCCP_MSG_TYPE_CR] = { + SUA_IEI_SRC_REF, SUA_IEI_PROTO_CLASS, SUA_IEI_DEST_ADDR , 0 + }, + /* Table 4/Q.713 */ + [SCCP_MSG_TYPE_CC] = { + SUA_IEI_DEST_REF, SUA_IEI_SRC_REF, SUA_IEI_PROTO_CLASS, 0 + }, + /* Table 5/Q.713 */ + [SCCP_MSG_TYPE_CREF] = { + SUA_IEI_DEST_REF, SUA_IEI_CAUSE, 0 + }, + /* Table 6/Q.713 */ + [SCCP_MSG_TYPE_RLSD] = { + SUA_IEI_DEST_REF, SUA_IEI_SRC_REF, SUA_IEI_CAUSE, 0 + }, + /* Table 7/Q.713 */ + [SCCP_MSG_TYPE_RLC] = { + SUA_IEI_DEST_REF, SUA_IEI_SRC_REF, 0 + }, + /* Table 8/Q.713 */ + [SCCP_MSG_TYPE_DT1] = { + SUA_IEI_DEST_REF, SUA_IEI_SEGMENTATION, 0 + }, + /* Table 9/Q.713 */ + [SCCP_MSG_TYPE_DT2] = { + SUA_IEI_DEST_REF, SUA_IEI_SEGMENTATION, 0 + }, + /* Table 10/Q.713 */ + [SCCP_MSG_TYPE_AK] = { + SUA_IEI_DEST_REF, SUA_IEI_RX_SEQ_NR, 0 + }, + /* Table 11/Q.713 */ + [SCCP_MSG_TYPE_UDT] = { + SUA_IEI_PROTO_CLASS, SUA_IEI_DEST_ADDR, + SUA_IEI_SRC_ADDR, SUA_IEI_DATA, 0 + }, + /* Table 12/Q.713 */ + [SCCP_MSG_TYPE_UDTS] = { + SUA_IEI_CAUSE, SUA_IEI_DEST_ADDR, SUA_IEI_SRC_ADDR, SUA_IEI_DATA, 0 + }, + /* Table 13/Q.713 */ + [SCCP_MSG_TYPE_ED] = { + SUA_IEI_DEST_REF, 0 + }, + /* Table 14/Q.713 */ + [SCCP_MSG_TYPE_EA] = { + SUA_IEI_DEST_REF, 0 + }, + /* Table 15/Q.713 */ + [SCCP_MSG_TYPE_RSR] = { + SUA_IEI_DEST_REF, SUA_IEI_SRC_REF, SUA_IEI_CAUSE, 0 + }, + /* Table 16/Q.713 */ + [SCCP_MSG_TYPE_RSC] = { + SUA_IEI_DEST_REF, SUA_IEI_SRC_REF, 0 + }, + /* Table 17/Q.713 */ + [SCCP_MSG_TYPE_ERR] = { + SUA_IEI_DEST_REF, SUA_IEI_CAUSE, 0 + }, + /* Table 18/Q.713 */ + [SCCP_MSG_TYPE_IT] = { + SUA_IEI_DEST_REF, SUA_IEI_SRC_REF, SUA_IEI_PROTO_CLASS, + SUA_IEI_SEGMENTATION, SUA_IEI_CREDIT, 0 + }, + /* Table 19/Q.713 */ + [SCCP_MSG_TYPE_XUDT] = { + SUA_IEI_PROTO_CLASS, SUA_IEI_S7_HOP_CTR, + SUA_IEI_DEST_ADDR, SUA_IEI_SRC_ADDR, SUA_IEI_DATA, 0 + }, + /* Table 20/Q.713 */ + [SCCP_MSG_TYPE_XUDTS] = { + SUA_IEI_CAUSE, SUA_IEI_S7_HOP_CTR, SUA_IEI_DEST_ADDR, + SUA_IEI_SRC_ADDR, SUA_IEI_DATA, 0 + }, + /* Table 21/Q.713 */ + [SCCP_MSG_TYPE_LUDT] = { + SUA_IEI_PROTO_CLASS, SUA_IEI_S7_HOP_CTR, + SUA_IEI_DEST_ADDR, SUA_IEI_SRC_ADDR, SUA_IEI_DATA, 0 + }, + /* Table 22/Q.713 */ + [SCCP_MSG_TYPE_LUDTS] = { + SUA_IEI_CAUSE, SUA_IEI_S7_HOP_CTR, SUA_IEI_DEST_ADDR, + SUA_IEI_SRC_ADDR, SUA_IEI_DATA, 0 + }, +}; + +static bool sccp_is_mandatory(enum sccp_message_types type, const struct xua_msg_part *part) +{ + unsigned int i; + + if (type > ARRAY_SIZE(sccp_mandatory)) + return false; + + for (i = 0; i < MAX_IES; i++) { + uint16_t val = sccp_mandatory[type][i]; + if (val == 0) { + /* end of list, don't iterate further */ + return false; + } + if (val == part->tag) { + /* found in list, it's mandatory */ + return true; + } + } + /* not mandatory */ + return false; +} + +static int xua_ies_to_sccp_opts(struct msgb *msg, uint8_t *ptr_opt, + enum sccp_message_types type, struct xua_msg *xua) +{ + struct xua_msg_part *part; + + /* store relative pointer to start of optional part */ + *ptr_opt = msg->tail - ptr_opt; + + llist_for_each_entry(part, &xua->headers, entry) { + /* make sure we don't add a SCCP option for information + * that is already present in mandatory fixed or + * mandatory variable parts of the header */ + if (!sccp_is_mandatory(type, part)) + sccp_msg_add_sua_opt(msg, part); + } + msgb_put_u8(msg, SCCP_PNC_END_OF_OPTIONAL); + + return 0; +} + +/* store a 'local reference' as big-eidian 24bit value at local_ref */ +static void store_local_ref(struct sccp_source_reference *local_ref, struct xua_msg *xua, uint16_t iei) +{ + uint32_t tmp32 = xua_msg_get_u32(xua, iei); + local_ref->octet1 = (tmp32 >> 16) & 0xff; + local_ref->octet2 = (tmp32 >> 8) & 0xff; + local_ref->octet3 = tmp32 & 0xff; +} + +static struct xua_msg *sccp_to_xua_cr(struct msgb *msg, struct xua_msg *xua) +{ + struct sccp_connection_request *req = (struct sccp_connection_request *)msg->l2h; + + /* Fixed Part */ + xua_msg_add_u32(xua, SUA_IEI_PROTO_CLASS, req->proto_class); + xua_msg_add_u32(xua, SUA_IEI_SRC_REF, load_24be(&req->source_local_reference)); + /* Variable Part */ + if (!sccp_ptr_part_consistent(msg, &req->variable_called)) + return NULL; + sccp_addr_to_sua_ptr(xua, SUA_IEI_DEST_ADDR, msg, &req->variable_called); + /* Optional Part */ + return sccp_to_xua_opt(msg, &req->optional_start, xua); +} + +static int sua_to_sccp_cr(struct msgb *msg, struct xua_msg *xua) +{ + struct sccp_connection_request *req; + req = (struct sccp_connection_request *) msgb_put(msg, sizeof(*req)); + + /* Fixed Part */ + req->type = SCCP_MSG_TYPE_CR; + req->proto_class = xua_msg_get_u32(xua, SUA_IEI_PROTO_CLASS); + store_local_ref(&req->source_local_reference, xua, SUA_IEI_SRC_REF); + /* Variable Part */ + sccp_add_var_addr(msg, &req->variable_called, xua, SUA_IEI_DEST_ADDR); + + /* Optional Part */ + return xua_ies_to_sccp_opts(msg, &req->optional_start, req->type, xua); +} + +static struct xua_msg *sccp_to_xua_cc(struct msgb *msg, struct xua_msg *xua) +{ + struct sccp_connection_confirm *cnf = (struct sccp_connection_confirm *)msg->l2h; + + /* Fixed Part */ + xua_msg_add_u32(xua, SUA_IEI_PROTO_CLASS, cnf->proto_class); + xua_msg_add_u32(xua, SUA_IEI_DEST_REF, load_24be(&cnf->destination_local_reference)); + xua_msg_add_u32(xua, SUA_IEI_SRC_REF, load_24be(&cnf->source_local_reference)); + /* Optional Part */ + return sccp_to_xua_opt(msg, &cnf->optional_start, xua); +} + +static int sua_to_sccp_cc(struct msgb *msg, struct xua_msg *xua) +{ + struct sccp_connection_confirm *cnf; + cnf = (struct sccp_connection_confirm *) msgb_put(msg, sizeof(*cnf)); + + /* Fixed Part */ + cnf->type = SCCP_MSG_TYPE_CC; + cnf->proto_class = xua_msg_get_u32(xua, SUA_IEI_PROTO_CLASS); + store_local_ref(&cnf->destination_local_reference, xua, SUA_IEI_DEST_REF); + store_local_ref(&cnf->source_local_reference, xua, SUA_IEI_SRC_REF); + /* Optional Part */ + return xua_ies_to_sccp_opts(msg, &cnf->optional_start, cnf->type, xua); +} + +static struct xua_msg *sccp_to_xua_cref(struct msgb *msg, struct xua_msg *xua) +{ + struct sccp_connection_refused *ref = (struct sccp_connection_refused *)msg->l2h; + + /* Fixed Part */ + xua_msg_add_u32(xua, SUA_IEI_DEST_REF, load_24be(&ref->destination_local_reference)); + xua_msg_add_u32(xua, SUA_IEI_CAUSE, SUA_CAUSE_T_REFUSAL | ref->cause); + /* Optional Part */ + return sccp_to_xua_opt(msg, &ref->optional_start, xua); +} + +static int sua_to_sccp_cref(struct msgb *msg, struct xua_msg *xua) +{ + struct sccp_connection_refused *ref; + ref = (struct sccp_connection_refused *) msgb_put(msg, sizeof(*ref)); + + /* Fixed Part */ + ref->type = SCCP_MSG_TYPE_CREF; + store_local_ref(&ref->destination_local_reference, xua, SUA_IEI_DEST_REF); + ref->cause = xua_msg_get_u32(xua, SUA_IEI_CAUSE) & 0xff; + /* Optional Part */ + return xua_ies_to_sccp_opts(msg, &ref->optional_start, ref->type, xua); +} + +static struct xua_msg *sccp_to_xua_rlsd(struct msgb *msg, struct xua_msg *xua) +{ + struct sccp_connection_released *rlsd = (struct sccp_connection_released *)msg->l2h; + + /* Fixed Part */ + xua_msg_add_u32(xua, SUA_IEI_DEST_REF, load_24be(&rlsd->destination_local_reference)); + xua_msg_add_u32(xua, SUA_IEI_SRC_REF, load_24be(&rlsd->source_local_reference)); + xua_msg_add_u32(xua, SUA_IEI_CAUSE, SUA_CAUSE_T_RELEASE | rlsd->release_cause); + /* Optional Part */ + return sccp_to_xua_opt(msg, &rlsd->optional_start, xua); +} + +static int sua_to_sccp_rlsd(struct msgb *msg, struct xua_msg *xua) +{ + struct sccp_connection_released *rlsd; + rlsd =(struct sccp_connection_released *) msgb_put(msg, sizeof(*rlsd)); + + /* Fixed Part */ + rlsd->type = SCCP_MSG_TYPE_RLSD; + store_local_ref(&rlsd->destination_local_reference, xua, SUA_IEI_DEST_REF); + store_local_ref(&rlsd->source_local_reference, xua, SUA_IEI_SRC_REF); + rlsd->release_cause = xua_msg_get_u32(xua, SUA_IEI_CAUSE) & 0xff; + + /* Optional Part */ + return xua_ies_to_sccp_opts(msg, &rlsd->optional_start, rlsd->type, xua); +} + +static struct xua_msg *sccp_to_xua_rlc(struct msgb *msg, struct xua_msg *xua) +{ + struct sccp_connection_release_complete *rlc; + rlc = (struct sccp_connection_release_complete *) msg->l2h; + + /* Fixed Part */ + xua_msg_add_u32(xua, SUA_IEI_DEST_REF, load_24be(&rlc->destination_local_reference)); + xua_msg_add_u32(xua, SUA_IEI_SRC_REF, load_24be(&rlc->source_local_reference)); + return xua; +} + +static int sua_to_sccp_rlc(struct msgb *msg, struct xua_msg *xua) +{ + struct sccp_connection_release_complete *rlc; + rlc = (struct sccp_connection_release_complete *) msgb_put(msg, sizeof(*rlc)); + + /* Fixed Part */ + rlc->type = SCCP_MSG_TYPE_RLC; + store_local_ref(&rlc->destination_local_reference, xua, SUA_IEI_DEST_REF); + store_local_ref(&rlc->source_local_reference, xua, SUA_IEI_SRC_REF); + return 0; +} + +static struct xua_msg *sccp_to_xua_dt1(struct msgb *msg, struct xua_msg *xua) +{ + struct sccp_data_form1 *dt1 = (struct sccp_data_form1 *) msg->l2h; + + /* Fixed Part */ + xua_msg_add_u32(xua, SUA_IEI_DEST_REF, load_24be(&dt1->destination_local_reference)); + xua_msg_add_u32(xua, SUA_IEI_SEGMENTATION, dt1->segmenting); + /* Variable Part */ + if (!sccp_ptr_part_consistent(msg, &dt1->variable_start)) + return NULL; + sccp_data_to_sua_ptr(xua, SUA_IEI_DATA, msg, &dt1->variable_start); + return xua; +} + +static int sua_to_sccp_dt1(struct msgb *msg, struct xua_msg *xua) +{ + struct sccp_data_form1 *dt1; + dt1 = (struct sccp_data_form1 *) msgb_put(msg, sizeof(*dt1)); + + /* Fixed Part */ + dt1->type = SCCP_MSG_TYPE_DT1; + store_local_ref(&dt1->destination_local_reference, xua, SUA_IEI_DEST_REF); + dt1->segmenting = xua_msg_get_u32(xua, SUA_IEI_SEGMENTATION); + /* Variable Part */ + sccp_add_variable_part(msg, &dt1->variable_start, xua, SUA_IEI_DATA); + return 0; +} + +static struct xua_msg *sccp_to_xua_udt(struct msgb *msg, struct xua_msg *xua) +{ + struct sccp_data_unitdata *udt = (struct sccp_data_unitdata *)msg->l2h; + + /* Fixed Part */ + xua_msg_add_u32(xua, SUA_IEI_PROTO_CLASS, udt->proto_class); + /* Variable Part */ + if (!sccp_ptr_part_consistent(msg, &udt->variable_called)) + return NULL; + sccp_addr_to_sua_ptr(xua, SUA_IEI_DEST_ADDR, msg, &udt->variable_called); + if (!sccp_ptr_part_consistent(msg, &udt->variable_calling)) + return NULL; + sccp_addr_to_sua_ptr(xua, SUA_IEI_SRC_ADDR, msg, &udt->variable_calling); + if (!sccp_ptr_part_consistent(msg, &udt->variable_data)) + return NULL; + sccp_data_to_sua_ptr(xua, SUA_IEI_DATA, msg, &udt->variable_data); + return xua; + +} + +static int sua_to_sccp_udt(struct msgb *msg, struct xua_msg *xua) +{ + struct sccp_data_unitdata *udt; + udt = (struct sccp_data_unitdata *) msgb_put(msg, sizeof(*udt)); + + /* Fixed Part */ + udt->type = SCCP_MSG_TYPE_UDT; + udt->proto_class = xua_msg_get_u32(xua, SUA_IEI_PROTO_CLASS); + /* Variable Part */ + sccp_add_var_addr(msg, &udt->variable_called, xua, SUA_IEI_DEST_ADDR); + sccp_add_var_addr(msg, &udt->variable_calling, xua, SUA_IEI_SRC_ADDR); + sccp_add_variable_part(msg, &udt->variable_data, xua, SUA_IEI_DATA); + return 0; +} + +static struct xua_msg *sccp_to_xua_udts(struct msgb *msg, struct xua_msg *xua) +{ + struct sccp_data_unitdata_service *udts; + udts =(struct sccp_data_unitdata_service *)msg->l2h; + + /* Fixed Part */ + xua_msg_add_u32(xua, SUA_IEI_CAUSE, SUA_CAUSE_T_RETURN | udts->return_cause); + /* Variable Part */ + if (!sccp_ptr_part_consistent(msg, &udts->variable_called)) + return NULL; + sccp_addr_to_sua_ptr(xua, SUA_IEI_DEST_ADDR, msg, &udts->variable_called); + if (!sccp_ptr_part_consistent(msg, &udts->variable_calling)) + return NULL; + sccp_addr_to_sua_ptr(xua, SUA_IEI_SRC_ADDR, msg, &udts->variable_calling); + if (!sccp_ptr_part_consistent(msg, &udts->variable_data)) + return NULL; + sccp_data_to_sua_ptr(xua, SUA_IEI_DATA, msg, &udts->variable_data); + return xua; + +} + +static int sua_to_sccp_udts(struct msgb *msg, struct xua_msg *xua) +{ + struct sccp_data_unitdata_service *udts; + udts = (struct sccp_data_unitdata_service *) msgb_put(msg, sizeof(*udts)); + + /* Fixed Part */ + udts->type = SCCP_MSG_TYPE_UDTS; + udts->return_cause = xua_msg_get_u32(xua, SUA_IEI_CAUSE) & 0xff; + /* Variable Part */ + sccp_add_var_addr(msg, &udts->variable_called, xua, SUA_IEI_DEST_ADDR); + sccp_add_var_addr(msg, &udts->variable_calling, xua, SUA_IEI_SRC_ADDR); + sccp_add_variable_part(msg, &udts->variable_data, xua, SUA_IEI_DATA); + return 0; +} + +static struct xua_msg *sccp_to_xua_it(struct msgb *msg, struct xua_msg *xua) +{ + struct sccp_data_it *it = (struct sccp_data_it *)msg->l2h; + + /* Fixed Part */ + xua_msg_add_u32(xua, SUA_IEI_PROTO_CLASS, it->proto_class); + xua_msg_add_u32(xua, SUA_IEI_SRC_REF, load_24be(&it->source_local_reference)); + xua_msg_add_u32(xua, SUA_IEI_DEST_REF, load_24be(&it->destination_local_reference)); + if ((it->proto_class & 0xF) == 3) { + //xua_msg_add_u32(xua, SUA_IEI_SEQUENCING, it->sequencing); + xua_msg_add_u32(xua, SUA_IEI_CREDIT, it->credit); + } + return xua; +} + +static int sua_to_sccp_it(struct msgb *msg, struct xua_msg *xua) +{ + struct sccp_data_it *it; + it = (struct sccp_data_it *) msgb_put(msg, sizeof(*it)); + + /* Fixed Part */ + it->type = SCCP_MSG_TYPE_IT; + it->proto_class = xua_msg_get_u32(xua, SUA_IEI_PROTO_CLASS); + store_local_ref(&it->destination_local_reference, xua, SUA_IEI_DEST_REF); + store_local_ref(&it->source_local_reference, xua, SUA_IEI_SRC_REF); + if ((it->proto_class & 0xF) == 3) { + //it->sequencing + it->credit = xua_msg_get_u32(xua, SUA_IEI_CREDIT); + } + + return 0; +} + +static struct xua_msg *sccp_to_xua_err(struct msgb *msg, struct xua_msg *xua) +{ + struct sccp_proto_err *err = (struct sccp_proto_err *)msg->l2h; + + /* Fixed Part */ + xua_msg_add_u32(xua, SUA_IEI_DEST_REF, load_24be(&err->destination_local_reference)); + xua_msg_add_u32(xua, SUA_IEI_CAUSE, SUA_CAUSE_T_ERROR | err->error_cause); + return xua; +} + +static int sua_to_sccp_err(struct msgb *msg, struct xua_msg *xua) +{ + struct sccp_proto_err *err; + err = (struct sccp_proto_err *) msgb_put(msg, sizeof(*err)); + + /* Fixed Part */ + err->type = SCCP_MSG_TYPE_ERR; + store_local_ref(&err->destination_local_reference, xua, SUA_IEI_DEST_REF); + err->error_cause = xua_msg_get_u32(xua, SUA_IEI_CAUSE) & 0xff; + return 0; +} + +/*! \brief convert SCCP message to a SUA message + * \param[in] msg message buffer holding SCCP message at l2h + * \returns callee-allocated xUA message on success; NULL on error */ +struct xua_msg *osmo_sccp_to_xua(struct msgb *msg) +{ + struct xua_msg *xua; + + if (msgb_l2len(msg) < 1) { + LOGP(DLSUA, LOGL_ERROR, "Short SCCP Message, cannot transcode\n"); + return NULL; + } + + xua = xua_msg_alloc(); + if (!xua) + return NULL; + + switch (msg->l2h[0]) { + case SCCP_MSG_TYPE_CR: + xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_CORE); + return sccp_to_xua_cr(msg, xua); + case SCCP_MSG_TYPE_CC: + xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_COAK); + return sccp_to_xua_cc(msg, xua); + case SCCP_MSG_TYPE_CREF: + xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_COREF); + return sccp_to_xua_cref(msg, xua); + case SCCP_MSG_TYPE_RLSD: + xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_RELRE); + return sccp_to_xua_rlsd(msg, xua); + case SCCP_MSG_TYPE_RLC: + xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_RELCO); + return sccp_to_xua_rlc(msg, xua); + case SCCP_MSG_TYPE_DT1: + xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_CODT); + return sccp_to_xua_dt1(msg, xua); + case SCCP_MSG_TYPE_UDT: + xua->hdr = XUA_HDR(SUA_MSGC_CL, SUA_CL_CLDT); + return sccp_to_xua_udt(msg, xua); + case SCCP_MSG_TYPE_UDTS: + xua->hdr = XUA_HDR(SUA_MSGC_CL, SUA_CL_CLDR); + return sccp_to_xua_udts(msg, xua); + case SCCP_MSG_TYPE_IT: + xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_COIT); + return sccp_to_xua_it(msg, xua); + case SCCP_MSG_TYPE_ERR: + xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_COERR); + return sccp_to_xua_err(msg, xua); + /* Unsupported Message Types */ + case SCCP_MSG_TYPE_DT2: + case SCCP_MSG_TYPE_AK: + case SCCP_MSG_TYPE_ED: + case SCCP_MSG_TYPE_EA: + case SCCP_MSG_TYPE_RSR: + case SCCP_MSG_TYPE_RSC: + case SCCP_MSG_TYPE_XUDT: + case SCCP_MSG_TYPE_XUDTS: + case SCCP_MSG_TYPE_LUDT: + case SCCP_MSG_TYPE_LUDTS: + default: + LOGP(DLSUA, LOGL_ERROR, "Unsupported SCCP message type %u\n", + msg->l2h[0]); + xua_msg_free(xua); + return NULL; + } + + return NULL; +} + +/*! \brief convert parsed SUA message to SCCP message + * \param[in] xua parsed SUA message to be converted + * \returns callee-allocated msgb containing encoded SCCP message */ +struct msgb *osmo_sua_to_sccp(struct xua_msg *xua) +{ + struct msgb *msg = sccp_msgb_alloc("SCCP from SUA"); + int rc; + + switch (xua->hdr.msg_class) { + case SUA_MSGC_CL: + switch (xua->hdr.msg_type) { + case SUA_CL_CLDT: + rc = sua_to_sccp_udt(msg, xua); + break; + case SUA_CL_CLDR: + rc = sua_to_sccp_udts(msg, xua); + break; + default: + LOGP(DLSUA, LOGL_ERROR, "Unsupported SUA message %s\n", + xua_hdr_dump(xua, &xua_dialect_sua)); + goto out_err; + } + break; + case SUA_MSGC_CO: + switch (xua->hdr.msg_type) { + case SUA_CO_CORE: + rc = sua_to_sccp_cr(msg, xua); + break; + case SUA_CO_COAK: + rc = sua_to_sccp_cc(msg, xua); + break; + case SUA_CO_COREF: + rc = sua_to_sccp_cref(msg, xua); + break; + case SUA_CO_RELRE: + rc = sua_to_sccp_rlsd(msg, xua); + break; + case SUA_CO_RELCO: + rc = sua_to_sccp_rlc(msg, xua); + break; + case SUA_CO_CODT: + rc = sua_to_sccp_dt1(msg, xua); + break; + case SUA_CO_COIT: + rc = sua_to_sccp_it(msg, xua); + break; + case SUA_CO_COERR: + rc = sua_to_sccp_err(msg, xua); + break; + default: + LOGP(DLSUA, LOGL_ERROR, "Unsupported SUA message %s\n", + xua_hdr_dump(xua, &xua_dialect_sua)); + goto out_err; + } + break; + default: + LOGP(DLSUA, LOGL_ERROR, "Unsupported SUA message class %s\n", + xua_hdr_dump(xua, &xua_dialect_sua)); + goto out_err; + } + + if (rc < 0) + goto out_err; + + return msg; + +out_err: + msgb_free(msg); + return NULL; +} -- To view, visit https://gerrit.osmocom.org/2213 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I8151a9b08a0b0ca97b9c73105ad4548512ce3be8 Gerrit-PatchSet: 6 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Apr 10 11:03:01 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 11:03:01 +0000 Subject: [MERGED] libosmo-sccp[master]: Add tests for xUA code + SCCP/SUA transcoding In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: Add tests for xUA code + SCCP/SUA transcoding ...................................................................... Add tests for xUA code + SCCP/SUA transcoding Change-Id: I7ce038d72dca18fb83d5a12519c9a48267e52ab8 --- M configure.ac M tests/Makefile.am M tests/testsuite.at A tests/xua/Makefile.am A tests/xua/sccp_test_data.c A tests/xua/sccp_test_data.h A tests/xua/xua_test.c A tests/xua/xua_test.ok 8 files changed, 654 insertions(+), 1 deletion(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/configure.ac b/configure.ac index 116e168..ed3e25a 100644 --- a/configure.ac +++ b/configure.ac @@ -67,6 +67,7 @@ tests/mtp/Makefile tests/m2ua/Makefile tests/sigtran/Makefile + tests/xua/Makefile tests/ss7/Makefile Makefile) diff --git a/tests/Makefile.am b/tests/Makefile.am index 9c251fe..6d3c96f 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,4 +1,4 @@ -SUBDIRS = sccp mtp m2ua sigtran ss7 +SUBDIRS = xua sccp mtp m2ua sigtran ss7 # The `:;' works around a Bash 3.2 bug when the output is not writeable. $(srcdir)/package.m4: $(top_srcdir)/configure.ac diff --git a/tests/testsuite.at b/tests/testsuite.at index 171f488..b810bdf 100644 --- a/tests/testsuite.at +++ b/tests/testsuite.at @@ -19,6 +19,12 @@ AT_CHECK([$abs_top_builddir/tests/sccp/sccp_test], [], [expout], [ignore]) AT_CLEANUP +AT_SETUP([xua]) +AT_KEYWORDS([xua]) +cat $abs_srcdir/xua/xua_test.ok > expout +AT_CHECK([$abs_top_builddir/tests/xua/xua_test], [], [expout], [ignore]) +AT_CLEANUP + AT_SETUP([ss7]) AT_KEYWORDS([ss7]) cat $abs_srcdir/ss7/ss7_test.ok > expout diff --git a/tests/xua/Makefile.am b/tests/xua/Makefile.am new file mode 100644 index 0000000..8a75e6c --- /dev/null +++ b/tests/xua/Makefile.am @@ -0,0 +1,13 @@ +AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -Wall +AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) + +AM_LDFLAGS = -static +LDADD = $(top_builddir)/src/libosmo-sigtran.la \ + $(LIBOSMOCORE_LIBS) $(LIBOSMONETIF_LIBS) $(LIBSCTP_LIBS) + +EXTRA_DIST = xua_test.ok + +noinst_HEADERS = sccp_test_data.h +noinst_PROGRAMS = xua_test + +xua_test_SOURCES = xua_test.c sccp_test_data.c diff --git a/tests/xua/sccp_test_data.c b/tests/xua/sccp_test_data.c new file mode 100644 index 0000000..c7c8f27 --- /dev/null +++ b/tests/xua/sccp_test_data.c @@ -0,0 +1,102 @@ +#include + +/* BSC -> MSC */ +const uint8_t bssmap_reset[18] = { + 0x09, 0x00, 0x03, 0x05, 0x07, 0x02, 0x42, 0xfe, + 0x02, 0x42, 0xfe, 0x06, 0x00, 0x04, 0x30, 0x04, + 0x01, 0x20, +}; + +/* MSC -> BSC reset ack */ +const uint8_t bssmap_reset_ack[19] = { + 0x09, 0x00, 0x03, 0x07, 0x0b, 0x04, 0x43, 0x01, + 0x00, 0xfe, 0x04, 0x43, 0x5c, 0x00, 0xfe, 0x03, + 0x00, 0x01, 0x31, +}; + +/* MSC -> BSC paging, connection less */ +const uint8_t bssmap_paging[32] = { + 0x09, 0x00, 0x03, 0x07, 0x0b, 0x04, 0x43, 0x01, + 0x00, 0xfe, 0x04, 0x43, 0x5c, 0x00, 0xfe, 0x10, + 0x00, 0x0e, 0x52, 0x08, 0x08, 0x29, 0x47, 0x10, + 0x02, 0x01, 0x31, 0x97, 0x61, 0x1a, 0x01, 0x06, +}; + +/* MSC -> BSC paging, UDT without PC */ +const uint8_t bssmap_udt[28] = { + 0x09, 0x00, 0x03, 0x05, 0x07, 0x02, 0x42, 0xfe, + 0x02, 0x42, 0xfe, 0x10, 0x00, 0x0e, 0x52, 0x08, + 0x08, 0x29, 0x47, 0x10, 0x02, 0x01, 0x31, 0x97, + 0x61, 0x1a, 0x01, 0x06, +}; + +/* BSC -> MSC connection open */ +const uint8_t bssmap_cr[44] = { + 0x01, 0x01, 0x02, 0x03, 0x02, 0x02, 0x04, 0x02, + 0x42, 0xfe, 0x0f, 0x1f, 0x00, 0x1d, 0x57, 0x05, + 0x08, 0x00, 0x72, 0xf4, 0x80, 0x20, 0x12, 0xc3, + 0x50, 0x17, 0x10, 0x05, 0x24, 0x11, 0x03, 0x33, + 0x19, 0xa2, 0x08, 0x29, 0x47, 0x10, 0x02, 0x01, + 0x31, 0x97, 0x61, 0x00 +}; + +/* MSC -> BSC connection confirm */ +const uint8_t bssmap_cc[10] = { + 0x02, 0x01, 0x02, 0x03, 0x00, 0x00, 0x03, 0x02, 0x01, 0x00, +}; + +/* MSC -> BSC DTAP + * + * we fake a bit and make it BSC -> MSC... so the + * payload does not make any sense.. + */ +const uint8_t bssmap_dtap[22] = { + 0x06, 0x00, 0x00, 0x03, 0x00, 0x01, 0x0f, 0x01, 0x00, 0x0c, + 0x03, 0x05, 0x5c, 0x08, 0x11, 0x81, 0x33, 0x66, 0x02, 0x13, + 0x45, 0xf4, +}; + +/* MSC -> BSC clear command */ +const uint8_t bssmap_clear[13] = { + 0x06, 0x00, 0x00, 0x03, 0x00, 0x01, 0x06, 0x00, 0x04, 0x20, + 0x04, 0x01, 0x09, +}; + +/* MSC -> BSC released */ +const uint8_t bssmap_released[14] = { + 0x04, 0x00, 0x00, 0x03, 0x01, 0x02, 0x03, 0x00, 0x01, 0x0f, + 0x02, 0x23, 0x42, 0x00, +}; + +/* BSC -> MSC released */ +const uint8_t bssmap_release_complete[7] = { + 0x05, 0x01, 0x02, 0x03, 0x00, 0x00, 0x03 +}; + +/* message with a SCCP global title */ +const uint8_t tcap_global_title[183] = { + 0x09, + 0x81, 0x03, 0x0d, 0x18, 0x0a, 0x12, 0x07, 0x00, + 0x12, 0x04, 0x53, 0x84, 0x09, 0x00, 0x17, 0x0b, + 0x12, 0x06, 0x00, 0x12, 0x04, 0x44, 0x87, 0x20, + 0x00, 0x20, 0x65, 0x9a, 0x65, 0x81, 0x97, 0x48, + 0x04, 0x26, 0x00, 0x01, 0x98, 0x49, 0x04, 0x51, + 0x01, 0x03, 0xdf, 0x6c, 0x81, 0x88, 0xa1, 0x81, + 0x85, 0x02, 0x01, 0x44, 0x02, 0x01, 0x07, 0x30, + 0x80, 0xa7, 0x80, 0xa0, 0x80, 0x04, 0x01, 0x2b, + 0x30, 0x80, 0x30, 0x12, 0x83, 0x01, 0x10, 0x84, + 0x01, 0x07, 0x85, 0x07, 0x91, 0x44, 0x57, 0x76, + 0x67, 0x16, 0x97, 0x86, 0x01, 0x20, 0x30, 0x06, + 0x82, 0x01, 0x18, 0x84, 0x01, 0x04, 0x00, 0x00, + 0x00, 0x00, 0xa3, 0x06, 0x04, 0x01, 0x42, 0x84, + 0x01, 0x05, 0xa3, 0x06, 0x04, 0x01, 0x51, 0x84, + 0x01, 0x05, 0xa3, 0x06, 0x04, 0x01, 0x31, 0x84, + 0x01, 0x05, 0xa3, 0x09, 0x04, 0x01, 0x12, 0x84, + 0x01, 0x05, 0x82, 0x01, 0x02, 0xa3, 0x09, 0x04, + 0x01, 0x11, 0x84, 0x01, 0x05, 0x81, 0x01, 0x01, + 0xa3, 0x06, 0x04, 0x01, 0x14, 0x84, 0x01, 0x00, + 0xa3, 0x0b, 0x04, 0x01, 0x41, 0x84, 0x01, 0x04, + 0x30, 0x03, 0x83, 0x01, 0x10, 0xa3, 0x0b, 0x04, + 0x01, 0x41, 0x84, 0x01, 0x04, 0x30, 0x03, 0x82, + 0x01, 0x18, 0x00, 0x00, 0x00, 0x00 +}; diff --git a/tests/xua/sccp_test_data.h b/tests/xua/sccp_test_data.h new file mode 100644 index 0000000..3d70549 --- /dev/null +++ b/tests/xua/sccp_test_data.h @@ -0,0 +1,14 @@ +#pragma once +#include + +extern const uint8_t bssmap_reset[18]; +extern const uint8_t bssmap_reset_ack[19]; +extern const uint8_t bssmap_paging[32]; +extern const uint8_t bssmap_udt[28]; +extern const uint8_t bssmap_cr[44]; +extern const uint8_t bssmap_cc[10]; +extern const uint8_t bssmap_dtap[22]; +extern const uint8_t bssmap_clear[13]; +extern const uint8_t bssmap_released[14]; +extern const uint8_t bssmap_release_complete[7]; +extern const uint8_t tcap_global_title[183]; diff --git a/tests/xua/xua_test.c b/tests/xua/xua_test.c new file mode 100644 index 0000000..74d91c4 --- /dev/null +++ b/tests/xua/xua_test.c @@ -0,0 +1,386 @@ +/* (C) 2011 by Holger Hans Peter Freyther + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +#include "sccp_test_data.h" + +#include "../src/xua_internal.h" + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +static void test_isup_parse(void) +{ + const uint8_t party0[] = { 0x10, 0x32, 0x54, 0x76 }; + char digits[23] = ""; + int rc; + + rc = osmo_isup_party_parse(digits, party0, ARRAY_SIZE(party0), false); + printf("digits='%s' (%d)\n", digits, rc); + OSMO_ASSERT(rc == 8); + OSMO_ASSERT(!strcmp(digits, "01234567")); + + rc = osmo_isup_party_parse(digits, party0, ARRAY_SIZE(party0), true); + printf("digits='%s' (%d)\n", digits, rc); + OSMO_ASSERT(rc == 7); + OSMO_ASSERT(!strcmp(digits, "0123456")); +} + +/* SCCP Address Parsing */ + +static struct sccp_addr_testcase { + struct osmo_sccp_addr expected; + uint8_t *bin; + unsigned int bin_len; +}; + +static uint8_t addr_bin0[] = { 0x92, 0x06, 0x00, 0x12, 0x04, 0x19, 0x99, 0x96, 0x76, 0x39, 0x98 }; +static uint8_t addr_bin1[] = { 0x12, 0x08, 0x00, 0x12, 0x04, 0x19, 0x89, 0x96, 0x92, 0x99, 0x29 }; +static uint8_t addr_bin2[] = { 0x42, 0xfe }; + +static const struct sccp_addr_testcase sccp_addr_testcases[] = { + { + .expected = { + .presence = OSMO_SCCP_ADDR_T_GT | OSMO_SCCP_ADDR_T_SSN, + .ri = OSMO_SCCP_RI_GT, + .gt = { + .gti = OSMO_SCCP_GTI_TT_NPL_ENC_NAI, + .tt = 0, + .npi = OSMO_SCCP_NPI_E164_ISDN, + .nai = OSMO_SCCP_NAI_INTL, + .digits = "919969679389", + }, + .ssn = 6, + }, + .bin = addr_bin0, + .bin_len = ARRAY_SIZE(addr_bin0), + }, { + .expected = { + .presence = OSMO_SCCP_ADDR_T_GT | OSMO_SCCP_ADDR_T_SSN, + .ri = OSMO_SCCP_RI_GT, + .gt = { + .gti = OSMO_SCCP_GTI_TT_NPL_ENC_NAI, + .tt = 0, + .npi = OSMO_SCCP_NPI_E164_ISDN, + .nai = OSMO_SCCP_NAI_INTL, + .digits = "919869299992", + }, + .ssn = 8, + }, + .bin = addr_bin1, + .bin_len = ARRAY_SIZE(addr_bin1), + }, { + .expected = { + .presence = OSMO_SCCP_ADDR_T_SSN, + .ri = OSMO_SCCP_RI_SSN_PC, + .ssn = 254, + }, + .bin = addr_bin2, + .bin_len = ARRAY_SIZE(addr_bin2), + + }, +}; + +static int test_sccp_addr_parse(const struct osmo_sccp_addr *cmp, + const uint8_t *in, unsigned int in_len) +{ + struct osmo_sccp_addr osa; + int rc; + + memset(&osa, 0, sizeof(osa)); + rc = osmo_sccp_addr_parse(&osa, in, in_len); + if (rc < 0) + return rc; + + printf("expected: %s\n", osmo_sccp_addr_dump(cmp)); + printf("parsed: %s\n", osmo_sccp_addr_dump(&osa)); + + if (memcmp(&osa, cmp, sizeof(osa))) { + fprintf(stderr, "expected: %s\n", osmo_hexdump_nospc((uint8_t *)cmp, sizeof(*cmp))); + fprintf(stderr, "parsed: %s\n", osmo_hexdump_nospc((uint8_t *)&osa, sizeof(osa))); + } + + return 0; +} + +static void test_sccp_addr_parser(void) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(sccp_addr_testcases); i++) { + const struct sccp_addr_testcase *tcase = &sccp_addr_testcases[i]; + printf("sccp_addr_parse test case %u\n", i); + test_sccp_addr_parse(&tcase->expected, tcase->bin, tcase->bin_len); + } +} + +/* sccp_addr_testcases[0].expected.gt transcoded into a SUA Global Title IE */ +static const uint8_t expected_sua_gt[] = { + 0x80, 0x01, 0x00, 0x14, 0x00, 0x00, 0x00, 0x04, + 0x0c, 0x00, 0x01, 0x04, 0x19, 0x99, 0x96, 0x76, + 0x39, 0x98, 0x00, 0x00 +}; + +static void test_helpers(void) +{ + struct msgb *msg = msgb_alloc(1024, "foo"); + const struct osmo_sccp_gt *gt_in = &sccp_addr_testcases[0].expected.gt; + struct osmo_sccp_gt gt_out; + + printf("Testing Decoded GT -> SUA encoding\n"); + printf("IN: %s\n", osmo_sccp_gt_dump(gt_in)); + + /* encode sccp_addr to SUA GT */ + xua_part_add_gt(msg, gt_in); + OSMO_ASSERT(msgb_length(msg) == sizeof(expected_sua_gt)); + OSMO_ASSERT(!memcmp(msg->data, expected_sua_gt, sizeof(expected_sua_gt))); + + /* pull the tag+length value */ + msgb_pull(msg, 4); + + /* parse + compare */ + sua_parse_gt(>_out, msgb_data(msg), msgb_length(msg)); + printf("OUT:%s\n", osmo_sccp_gt_dump(>_out)); + OSMO_ASSERT(!memcmp(gt_in, >_out, sizeof(gt_out))); + + msgb_free(msg); +} + +/* SCCP Message Transcoding */ + +struct sccp2sua_testcase { + const char *name; + struct { + const uint8_t *bin; + unsigned int length; + } sccp; + struct { + struct xua_common_hdr hdr; + const struct xua_msg_part parts[32]; + } sua; +}; + +#define PANDSIZ(x) { x, ARRAY_SIZE(x) } +#define PARTU32(x, data) { .tag = x, .len = 4, .dat = (uint8_t *) data } +#define PARTARR(x, data) { .tag = x, .len = ARRAY_SIZE(data), .dat = (uint8_t *) data } + +const uint32_t sua_proto_class0 = 0; +const uint32_t sua_proto_class2 = 2; +const uint32_t sua_loc_ref_bsc = 0x10203; +const uint32_t sua_loc_ref_msc = 0x00003; +const uint32_t sua_cause0 = 0x00003; +const uint8_t sua_addr_ssn_bssmap[] = { 0x00, 0x02, 0x00, 0x07, 0x80, 0x03, 0x00, 0x08, 0x00, 0x00, 0x00, 0xfe }; +const uint8_t sua_addr_ssn_bssmap_pc1[] = { 0x00, 0x01, 0x00, 0x07, 0x80, 0x02, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x80, 0x03, 0x00, 0x08, 0x00, 0x00, 0x00, 0xfe }; +const uint8_t sua_addr_ssn_bssmap_pc92[] = { 0x00, 0x01, 0x00, 0x07, 0x80, 0x02, 0x00, 0x08, 0x00, 0x00, 0x00, 0x5c, 0x80, 0x03, 0x00, 0x08, 0x00, 0x00, 0x00, 0xfe }; + +static const struct sccp2sua_testcase sccp2sua_testcases[] = { + { + .name = "BSSMAP-RESET", + .sccp = PANDSIZ(bssmap_reset), + .sua = { + .hdr = XUA_HDR(SUA_MSGC_CL, SUA_CL_CLDT), + .parts = { + PARTU32(SUA_IEI_PROTO_CLASS, &sua_proto_class0), + PARTARR(SUA_IEI_DEST_ADDR, &sua_addr_ssn_bssmap), + PARTARR(SUA_IEI_SRC_ADDR, &sua_addr_ssn_bssmap), + }, + }, + }, { + .name = "BSSMAP-RESET-ACK", + .sccp = PANDSIZ(bssmap_reset_ack), + .sua = { + .hdr = XUA_HDR(SUA_MSGC_CL, SUA_CL_CLDT), + .parts = { + PARTU32(SUA_IEI_PROTO_CLASS, &sua_proto_class0), + PARTARR(SUA_IEI_DEST_ADDR, &sua_addr_ssn_bssmap_pc1), + PARTARR(SUA_IEI_SRC_ADDR, &sua_addr_ssn_bssmap_pc92), + }, + }, + }, { + .name = "BSSMAP-PAGING", + .sccp = PANDSIZ(bssmap_paging), + .sua = { + .hdr = XUA_HDR(SUA_MSGC_CL, SUA_CL_CLDT), + .parts = { + PARTU32(SUA_IEI_PROTO_CLASS, &sua_proto_class0), + PARTARR(SUA_IEI_DEST_ADDR, &sua_addr_ssn_bssmap_pc1), + PARTARR(SUA_IEI_SRC_ADDR, &sua_addr_ssn_bssmap_pc92), + }, + }, + }, { + .name = "BSSMAP-UDT", + .sccp = PANDSIZ(bssmap_udt), + .sua = { + .hdr = XUA_HDR(SUA_MSGC_CL, SUA_CL_CLDT), + .parts = { + PARTU32(SUA_IEI_PROTO_CLASS, &sua_proto_class0), + PARTARR(SUA_IEI_DEST_ADDR, &sua_addr_ssn_bssmap), + PARTARR(SUA_IEI_SRC_ADDR, &sua_addr_ssn_bssmap), + }, + }, + }, { + .name = "BSSMAP-CR", + .sccp = PANDSIZ(bssmap_cr), + .sua = { + .hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_CORE), + .parts = { + PARTU32(SUA_IEI_PROTO_CLASS, &sua_proto_class2), + PARTU32(SUA_IEI_SRC_REF, &sua_loc_ref_bsc), + PARTARR(SUA_IEI_DEST_ADDR, &sua_addr_ssn_bssmap), + }, + }, + }, { + .name = "BSSMAP-CC", + .sccp = PANDSIZ(bssmap_cc), + .sua = { + .hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_COAK), + .parts = { + PARTU32(SUA_IEI_PROTO_CLASS, &sua_proto_class2), + PARTU32(SUA_IEI_SRC_REF, &sua_loc_ref_msc), + PARTARR(SUA_IEI_DEST_ADDR, &sua_loc_ref_bsc), + }, + }, + }, { + .name = "BSSMAP-DTAP", + .sccp = PANDSIZ(bssmap_dtap), + .sua = { + .hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_CODT), + .parts = { + PARTU32(SUA_IEI_SRC_REF, &sua_loc_ref_msc), + }, + }, + }, { + .name = "BSSMAP-CLEAR", + .sccp = PANDSIZ(bssmap_clear), + .sua = { + .hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_CODT), + .parts = { + PARTU32(SUA_IEI_SRC_REF, &sua_loc_ref_msc), + }, + }, + }, { + .name = "BSSMAP-RELEASED", + .sccp = PANDSIZ(bssmap_released), + .sua = { + .hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_RELRE), + .parts = { + PARTU32(SUA_IEI_DEST_REF, &sua_loc_ref_msc), + PARTU32(SUA_IEI_SRC_REF, &sua_loc_ref_bsc), + PARTU32(SUA_IEI_CAUSE, &sua_cause0), + }, + }, + }, { + .name = "BSSMAP-RELEASE_COMPLETE", + .sccp = PANDSIZ(bssmap_release_complete), + .sua = { + .hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_RELCO), + .parts = { + PARTU32(SUA_IEI_DEST_REF, &sua_loc_ref_bsc), + PARTU32(SUA_IEI_SRC_REF, &sua_loc_ref_msc), + }, + }, + }, { + .name = "TCAP", + .sccp = PANDSIZ(tcap_global_title), + .sua = { + .hdr = XUA_HDR(SUA_MSGC_CL, SUA_CL_CLDT), + .parts = { + }, + }, + }, +}; + +static void test_sccp2sua_case(const struct sccp2sua_testcase *tcase) +{ + struct xua_msg *xua; + struct msgb *msg = msgb_alloc(300, "SCCP2SUA Test Input"); + struct msgb *msg2; + + printf("\n=> %s\n", tcase->name); + msg->l2h = msgb_put(msg, tcase->sccp.length); + memcpy(msg->l2h, tcase->sccp.bin, tcase->sccp.length); + printf("SCCP Input: %s\n", msgb_hexdump(msg)); + printf("Transcoding message SCCP -> XUA\n"); + xua = osmo_sccp_to_xua(msg); + OSMO_ASSERT(xua); + + printf("Decoded SUA: "); + printf("%s\n", xua_msg_dump(xua, &xua_dialect_sua)); + + printf("Re-Encoding decoded SUA to SCCP\n"); + msg2 = osmo_sua_to_sccp(xua); + OSMO_ASSERT(msg2); + /* Re-encode xUA to SCCP */ + printf("SCCP Output: %s\n", msgb_hexdump(msg2)); + + if (msgb_length(msg) != msgb_length(msg2) || + memcmp(msgb_data(msg), msgb_data(msg2), msgb_length(msg))) + printf("Input != re-encoded output!\n"); + + /* free related data */ + msgb_free(msg); + msgb_free(msg2); + xua_msg_free(xua); +} + +static void test_sccp2sua(void) +{ + unsigned int i; + for (i = 0; i < ARRAY_SIZE(sccp2sua_testcases); i++) { + test_sccp2sua_case(&sccp2sua_testcases[i]); + } +} + + +static const struct log_info_cat default_categories[] = { + [0] = { + .name = "DSCCP", + .description = "DSCP", + .enabled = 1, .loglevel = LOGL_DEBUG, + }, +}; + +static const struct log_info log_info = { + .cat = default_categories, + .num_cat = ARRAY_SIZE(default_categories), +}; + +int main(int argc, char **argv) +{ + struct log_target *stderr_target; + log_init(&log_info, NULL); + stderr_target = log_target_create_stderr(); + log_add_target(stderr_target); + + test_isup_parse(); + test_sccp_addr_parser(); + test_helpers(); + test_sccp2sua(); + + printf("All tests passed.\n"); + return 0; +} diff --git a/tests/xua/xua_test.ok b/tests/xua/xua_test.ok new file mode 100644 index 0000000..a9fba1d --- /dev/null +++ b/tests/xua/xua_test.ok @@ -0,0 +1,131 @@ +digits='01234567' (8) +digits='0123456' (7) +sccp_addr_parse test case 0 +expected: RI=7,SSN=6,GTI=4,GT=(TT=0,NPL=1,NAI=4,DIG=919969679389) +parsed: RI=7,SSN=6,GTI=4,GT=(TT=0,NPL=1,NAI=4,DIG=919969679389) +sccp_addr_parse test case 1 +expected: RI=7,SSN=8,GTI=4,GT=(TT=0,NPL=1,NAI=4,DIG=919869299992) +parsed: RI=7,SSN=8,GTI=4,GT=(TT=0,NPL=1,NAI=4,DIG=919869299992) +sccp_addr_parse test case 2 +expected: RI=7,SSN=254,GTI=0 +parsed: RI=7,SSN=254,GTI=0 +Testing Decoded GT -> SUA encoding +IN: TT=0,NPL=1,NAI=4,DIG=919969679389 +OUT:TT=0,NPL=1,NAI=4,DIG=919969679389 + +=> BSSMAP-RESET +SCCP Input: [L2]> 09 00 03 05 07 02 42 fe 02 42 fe 06 00 04 30 04 01 20 +Transcoding message SCCP -> XUA +Decoded SUA: HDR=(CL:CLDT,V=0,LEN=0), + PART(T=Protocol Class,L=4,D=00000000), + PART(T=Destination Address,L=12,D=0002000180030008000000fe), + PART(T=Source Address,L=12,D=0002000180030008000000fe), + PART(T=Data,L=6,D=000430040120) +Re-Encoding decoded SUA to SCCP +SCCP Output: 09 00 03 05 07 02 42 fe 02 42 fe 06 00 04 30 04 01 20 + +=> BSSMAP-RESET-ACK +SCCP Input: [L2]> 09 00 03 07 0b 04 43 01 00 fe 04 43 5c 00 fe 03 00 01 31 +Transcoding message SCCP -> XUA +Decoded SUA: HDR=(CL:CLDT,V=0,LEN=0), + PART(T=Protocol Class,L=4,D=00000000), + PART(T=Destination Address,L=20,D=00020003800200080000000180030008000000fe), + PART(T=Source Address,L=20,D=00020003800200080000005c80030008000000fe), + PART(T=Data,L=3,D=000131) +Re-Encoding decoded SUA to SCCP +SCCP Output: 09 00 03 07 0b 04 43 01 00 fe 04 43 5c 00 fe 03 00 01 31 + +=> BSSMAP-PAGING +SCCP Input: [L2]> 09 00 03 07 0b 04 43 01 00 fe 04 43 5c 00 fe 10 00 0e 52 08 08 29 47 10 02 01 31 97 61 1a 01 06 +Transcoding message SCCP -> XUA +Decoded SUA: HDR=(CL:CLDT,V=0,LEN=0), + PART(T=Protocol Class,L=4,D=00000000), + PART(T=Destination Address,L=20,D=00020003800200080000000180030008000000fe), + PART(T=Source Address,L=20,D=00020003800200080000005c80030008000000fe), + PART(T=Data,L=16,D=000e52080829471002013197611a0106) +Re-Encoding decoded SUA to SCCP +SCCP Output: 09 00 03 07 0b 04 43 01 00 fe 04 43 5c 00 fe 10 00 0e 52 08 08 29 47 10 02 01 31 97 61 1a 01 06 + +=> BSSMAP-UDT +SCCP Input: [L2]> 09 00 03 05 07 02 42 fe 02 42 fe 10 00 0e 52 08 08 29 47 10 02 01 31 97 61 1a 01 06 +Transcoding message SCCP -> XUA +Decoded SUA: HDR=(CL:CLDT,V=0,LEN=0), + PART(T=Protocol Class,L=4,D=00000000), + PART(T=Destination Address,L=12,D=0002000180030008000000fe), + PART(T=Source Address,L=12,D=0002000180030008000000fe), + PART(T=Data,L=16,D=000e52080829471002013197611a0106) +Re-Encoding decoded SUA to SCCP +SCCP Output: 09 00 03 05 07 02 42 fe 02 42 fe 10 00 0e 52 08 08 29 47 10 02 01 31 97 61 1a 01 06 + +=> BSSMAP-CR +SCCP Input: [L2]> 01 01 02 03 02 02 04 02 42 fe 0f 1f 00 1d 57 05 08 00 72 f4 80 20 12 c3 50 17 10 05 24 11 03 33 19 a2 08 29 47 10 02 01 31 97 61 00 +Transcoding message SCCP -> XUA +Decoded SUA: HDR=(CO:CORE,V=0,LEN=0), + PART(T=Protocol Class,L=4,D=00000002), + PART(T=Source Reference,L=4,D=00010203), + PART(T=Destination Address,L=12,D=0002000180030008000000fe), + PART(T=Data,L=31,D=001d5705080072f4802012c3501710052411033319a2082947100201319761) +Re-Encoding decoded SUA to SCCP +SCCP Output: 01 01 02 03 02 02 04 02 42 fe 0f 1f 00 1d 57 05 08 00 72 f4 80 20 12 c3 50 17 10 05 24 11 03 33 19 a2 08 29 47 10 02 01 31 97 61 00 + +=> BSSMAP-CC +SCCP Input: [L2]> 02 01 02 03 00 00 03 02 01 00 +Transcoding message SCCP -> XUA +Decoded SUA: HDR=(CO:COAK,V=0,LEN=0), + PART(T=Protocol Class,L=4,D=00000002), + PART(T=Destination Reference,L=4,D=00010203), + PART(T=Source Reference,L=4,D=00000003) +Re-Encoding decoded SUA to SCCP +SCCP Output: 02 01 02 03 00 00 03 02 01 00 + +=> BSSMAP-DTAP +SCCP Input: [L2]> 06 00 00 03 00 01 0f 01 00 0c 03 05 5c 08 11 81 33 66 02 13 45 f4 +Transcoding message SCCP -> XUA +Decoded SUA: HDR=(CO:CODT,V=0,LEN=0), + PART(T=Destination Reference,L=4,D=00000003), + PART(T=Segmentation,L=4,D=00000000), + PART(T=Data,L=15,D=01000c03055c0811813366021345f4) +Re-Encoding decoded SUA to SCCP +SCCP Output: 06 00 00 03 00 01 0f 01 00 0c 03 05 5c 08 11 81 33 66 02 13 45 f4 + +=> BSSMAP-CLEAR +SCCP Input: [L2]> 06 00 00 03 00 01 06 00 04 20 04 01 09 +Transcoding message SCCP -> XUA +Decoded SUA: HDR=(CO:CODT,V=0,LEN=0), + PART(T=Destination Reference,L=4,D=00000003), + PART(T=Segmentation,L=4,D=00000000), + PART(T=Data,L=6,D=000420040109) +Re-Encoding decoded SUA to SCCP +SCCP Output: 06 00 00 03 00 01 06 00 04 20 04 01 09 + +=> BSSMAP-RELEASED +SCCP Input: [L2]> 04 00 00 03 01 02 03 00 01 0f 02 23 42 00 +Transcoding message SCCP -> XUA +Decoded SUA: HDR=(CO:RELRE,V=0,LEN=0), + PART(T=Destination Reference,L=4,D=00000003), + PART(T=Source Reference,L=4,D=00010203), + PART(T=Cause,L=4,D=00000300), + PART(T=Data,L=2,D=2342) +Re-Encoding decoded SUA to SCCP +SCCP Output: 04 00 00 03 01 02 03 00 01 0f 02 23 42 00 + +=> BSSMAP-RELEASE_COMPLETE +SCCP Input: [L2]> 05 01 02 03 00 00 03 +Transcoding message SCCP -> XUA +Decoded SUA: HDR=(CO:RELCO,V=0,LEN=0), + PART(T=Destination Reference,L=4,D=00010203), + PART(T=Source Reference,L=4,D=00000003) +Re-Encoding decoded SUA to SCCP +SCCP Output: 05 01 02 03 00 00 03 + +=> TCAP +SCCP Input: [L2]> 09 81 03 0d 18 0a 12 07 00 12 04 53 84 09 00 17 0b 12 06 00 12 04 44 87 20 00 20 65 9a 65 81 97 48 04 26 00 01 98 49 04 51 01 03 df 6c 81 88 a1 81 85 02 01 44 02 01 07 30 80 a7 80 a0 80 04 01 2b 30 80 30 12 83 01 10 84 01 07 85 07 91 44 57 76 67 16 97 86 01 20 30 06 82 01 18 84 01 04 00 00 00 00 a3 06 04 01 42 84 01 05 a3 06 04 01 51 84 01 05 a3 06 04 01 31 84 01 05 a3 09 04 01 12 84 01 05 82 01 02 a3 09 04 01 11 84 01 05 81 01 01 a3 06 04 01 14 84 01 00 a3 0b 04 01 41 84 01 04 30 03 83 01 10 a3 0b 04 01 41 84 01 04 30 03 82 01 18 00 00 00 00 +Transcoding message SCCP -> XUA +Decoded SUA: HDR=(CL:CLDT,V=0,LEN=0), + PART(T=Protocol Class,L=4,D=00000081), + PART(T=Destination Address,L=32,D=0001000580010014000000040a00010453840900170000008003000800000007), + PART(T=Source Address,L=32,D=0001000580010014000000040c00010444872000206500008003000800000006), + PART(T=Data,L=154,D=6581974804260001984904510103df6c8188a181850201440201073080a780a08004012b30803012830110840107850791445776671697860120300682011884010400000000a306040142840105a306040151840105a306040131840105a309040112840105820102a309040111840105810101a306040114840100a30b0401418401043003830110a30b040141840104300382011800000000) +Re-Encoding decoded SUA to SCCP +SCCP Output: 09 81 03 0d 18 0a 12 07 00 12 04 53 84 09 00 17 0b 12 06 00 12 04 44 87 20 00 20 65 9a 65 81 97 48 04 26 00 01 98 49 04 51 01 03 df 6c 81 88 a1 81 85 02 01 44 02 01 07 30 80 a7 80 a0 80 04 01 2b 30 80 30 12 83 01 10 84 01 07 85 07 91 44 57 76 67 16 97 86 01 20 30 06 82 01 18 84 01 04 00 00 00 00 a3 06 04 01 42 84 01 05 a3 06 04 01 51 84 01 05 a3 06 04 01 31 84 01 05 a3 09 04 01 12 84 01 05 82 01 02 a3 09 04 01 11 84 01 05 81 01 01 a3 06 04 01 14 84 01 00 a3 0b 04 01 41 84 01 04 30 03 83 01 10 a3 0b 04 01 41 84 01 04 30 03 82 01 18 00 00 00 00 +All tests passed. -- To view, visit https://gerrit.osmocom.org/2214 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I7ce038d72dca18fb83d5a12519c9a48267e52ab8 Gerrit-PatchSet: 6 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Apr 10 11:03:01 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 11:03:01 +0000 Subject: [MERGED] libosmo-sccp[master]: sua.c: Replace sua_msgb_alloc() with new sccp_msgb_alloc() In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: sua.c: Replace sua_msgb_alloc() with new sccp_msgb_alloc() ...................................................................... sua.c: Replace sua_msgb_alloc() with new sccp_msgb_alloc() Change-Id: I7067a85dcc5dda66f4b17b0fe08da8cb3efe79ef --- M src/Makefile.am A src/sccp_internal.h M src/sua.c 3 files changed, 24 insertions(+), 15 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/Makefile.am b/src/Makefile.am index f7f4ccc..ec3fe99 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,7 +1,7 @@ AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir) AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMONETIF_CFLAGS) -noinst_HEADERS = xua_asp_fsm.h xua_as_fsm.h xua_internal.h +noinst_HEADERS = sccp_internal.h xua_asp_fsm.h xua_as_fsm.h xua_internal.h # Legacy static libs diff --git a/src/sccp_internal.h b/src/sccp_internal.h new file mode 100644 index 0000000..7287a82 --- /dev/null +++ b/src/sccp_internal.h @@ -0,0 +1,5 @@ +#pragma once + +#include + +struct msgb *sccp_msgb_alloc(const char *name); diff --git a/src/sua.c b/src/sua.c index 0be5467..0f42d63 100644 --- a/src/sua.c +++ b/src/sua.c @@ -51,6 +51,17 @@ #define GUARD_TIMER (23 * 60 * 100) #define RESET_TIMER ( 10 * 100) +#define SCCP_MSG_SIZE 2048 +#define SCCP_MSG_HEADROOM 512 + +struct msgb *sccp_msgb_alloc(const char *name) +{ + if (!name) + name = "SCCP"; + return msgb_alloc_headroom(SCCP_MSG_SIZE+SCCP_MSG_HEADROOM, + SCCP_MSG_HEADROOM, name); +} + /*********************************************************************** * Protocol Definition (string tables, mandatory IE checking) ***********************************************************************/ @@ -431,13 +442,6 @@ conn_restart_tx_inact_timer(conn); conn_restart_rx_inact_timer(conn); } - - -static struct msgb *sua_msgb_alloc(void) -{ - return msgb_alloc(SUA_MSGB_SIZE, "SUA Primitive"); -} - /*********************************************************************** * Handling of messages from the User SAP @@ -871,7 +875,7 @@ struct osmo_scu_prim *prim; struct osmo_scu_unitdata_param *param; struct xua_msg_part *data_ie = xua_msg_find_tag(xua, SUA_IEI_DATA); - struct msgb *upmsg = sua_msgb_alloc(); + struct msgb *upmsg = sccp_msgb_alloc(__func__); uint32_t protocol_class; /* fill primitive */ @@ -932,7 +936,7 @@ conn->remote_ref = xua_msg_get_u32(xua, SUA_IEI_SRC_REF); /* fill primitive */ - upmsg = sua_msgb_alloc(); + upmsg = sccp_msgb_alloc(__func__); prim = (struct osmo_scu_prim *) msgb_put(upmsg, sizeof(*prim)); param = &prim->u.connect; osmo_prim_init(&prim->oph, SCCP_SAP_USER, @@ -992,7 +996,7 @@ conn->remote_ref = xua_msg_get_u32(xua, SUA_IEI_SRC_REF); /* fill primitive */ - upmsg = sua_msgb_alloc(); + upmsg = sccp_msgb_alloc(__func__); prim = (struct osmo_scu_prim *) msgb_put(upmsg, sizeof(*prim)); param = &prim->u.connect; osmo_prim_init(&prim->oph, SCCP_SAP_USER, @@ -1044,7 +1048,7 @@ conn_restart_rx_inact_timer(conn); /* fill primitive */ - upmsg = sua_msgb_alloc(); + upmsg = sccp_msgb_alloc(__func__); prim = (struct osmo_scu_prim *) msgb_put(upmsg, sizeof(*prim)); param = &prim->u.disconnect; osmo_prim_init(&prim->oph, SCCP_SAP_USER, @@ -1095,7 +1099,7 @@ } /* fill primitive */ - upmsg = sua_msgb_alloc(); + upmsg = sccp_msgb_alloc(__func__); prim = (struct osmo_scu_prim *) msgb_put(upmsg, sizeof(*prim)); param = &prim->u.disconnect; osmo_prim_init(&prim->oph, SCCP_SAP_USER, @@ -1144,7 +1148,7 @@ conn_restart_rx_inact_timer(conn); /* fill primitive */ - upmsg = sua_msgb_alloc(); + upmsg = sccp_msgb_alloc(__func__); prim = (struct osmo_scu_prim *) msgb_put(upmsg, sizeof(*prim)); param = &prim->u.disconnect; osmo_prim_init(&prim->oph, SCCP_SAP_USER, @@ -1196,7 +1200,7 @@ conn_restart_rx_inact_timer(conn); /* fill primitive */ - upmsg = sua_msgb_alloc(); + upmsg = sccp_msgb_alloc(__func__); prim = (struct osmo_scu_prim *) msgb_put(upmsg, sizeof(*prim)); param = &prim->u.data; osmo_prim_init(&prim->oph, SCCP_SAP_USER, -- To view, visit https://gerrit.osmocom.org/2212 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I7067a85dcc5dda66f4b17b0fe08da8cb3efe79ef Gerrit-PatchSet: 6 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Apr 10 11:03:02 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 11:03:02 +0000 Subject: [MERGED] libosmo-sccp[master]: sua: Extend address parsing with GT, RI and IPv4 support In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: sua: Extend address parsing with GT, RI and IPv4 support ...................................................................... sua: Extend address parsing with GT, RI and IPv4 support Change-Id: I186df77cbdbedfe1a60b855be3626b6766f4681c --- M src/sua.c 1 file changed, 104 insertions(+), 26 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/sua.c b/src/sua.c index 659104c..0be5467 100644 --- a/src/sua.c +++ b/src/sua.c @@ -692,11 +692,51 @@ * Receiving SUA messsages from SCTP ***********************************************************************/ -static int sua_parse_addr(struct osmo_sccp_addr *out, - struct xua_msg *xua, - uint16_t iei) +/*! \brief Decode SUA Global Title according to RFC3868 Section 3.10.2.3 + * \param[out] gt User-allocated structure for decoded output + * \param[in] data binary-encoded data + * \param[in] datalen length of \ref data in octets + */ +int sua_parse_gt(struct osmo_sccp_gt *gt, const uint8_t *data, unsigned int datalen) { - const struct xua_msg_part *param = xua_msg_find_tag(xua, iei); + uint8_t num_digits; + char *out_digits; + unsigned int i; + + /* 8 byte header at minimum, plus digits */ + if (datalen < 8) + return -EINVAL; + + /* parse header */ + gt->gti = data[3]; + num_digits = data[4]; + gt->tt = data[5]; + gt->npi = data[6]; + gt->nai = data[7]; + + /* parse digits */ + out_digits = gt->digits; + for (i = 0; i < datalen-8; i++) { + uint8_t byte = data[8+i]; + *out_digits++ = osmo_bcd2char(byte & 0x0F); + if (out_digits - gt->digits >= num_digits) + break; + *out_digits++ = osmo_bcd2char(byte >> 4); + if (out_digits - gt->digits >= num_digits) + break; + } + *out_digits++ = '\0'; + + return 0; +} + +/*! \brief parse SCCP address from given xUA message part + * \param[out] out caller-allocated decoded SCCP address struct + * \param[in] param xUA message part containing address + \returns 0 on success; negative on error */ +int sua_addr_parse_part(struct osmo_sccp_addr *out, + const struct xua_msg_part *param) +{ const struct xua_parameter_hdr *par; uint16_t ri; uint16_t ai; @@ -704,16 +744,15 @@ uint16_t par_tag, par_len, par_datalen; uint32_t *p32; - if (!param) - return -ENODEV; + memset(out, 0, sizeof(*out)); - LOGP(DSUA, LOGL_DEBUG, "sua_parse_addr(IEI=%d) (%d) %s\n", - iei, param->len, + LOGP(DSUA, LOGL_DEBUG, "%s(IEI=0x%04x) (%d) %s\n", __func__, + param->tag, param->len, osmo_hexdump(param->dat, param->len)); if (param->len < 4) { - LOGP(DSUA, LOGL_ERROR, "SUA IEI %d: invalid address length: %d\n", - iei, param->len); + LOGP(DSUA, LOGL_ERROR, "SUA IEI 0x%04x: invalid address length: %d\n", + param->tag, param->len); return -EINVAL; } @@ -723,16 +762,29 @@ ai = ntohs(*(uint16_t*) ¶m->dat[pos]); pos += 2; - if (ri != SUA_RI_SSN_PC) { - LOGP(DSUA, LOGL_ERROR, "SUA IEI %d: Routing Indicator not supported yet: %d\n", - iei, ri); + switch (ri) { + case SUA_RI_GT: + out->ri = OSMO_SCCP_RI_GT; + break; + case SUA_RI_SSN_PC: + out->ri = OSMO_SCCP_RI_SSN_PC; + break; + case SUA_RI_SSN_IP: + out->ri = OSMO_SCCP_RI_SSN_IP; + break; + case SUA_RI_HOST: + default: + LOGP(DSUA, LOGL_ERROR, "SUA IEI 0x%04x: Routing Indicator not supported yet: %d\n", + param->tag, ri); return -ENOTSUP; } if (ai != 7) { - LOGP(DSUA, LOGL_ERROR, "SUA IEI %d: Address Indicator not supported yet: %x\n", - iei, ai); +#if 0 + LOGP(DSUA, LOGL_ERROR, "SUA IEI 0x%04x: Address Indicator not supported yet: %x\n", + param->tag, ai); return -ENOTSUP; +#endif } /* @@ -749,8 +801,8 @@ par_len = ntohs(par->len); par_datalen = par_len - sizeof(*par); - LOGP(DSUA, LOGL_DEBUG, "SUA IEI %hu pos %hu/%hu: subpart tag %hu, len %hu\n", - iei, pos, param->len, par->tag, par->len); + LOGP(DSUA, LOGL_DEBUG, "SUA IEI 0x%04x pos %hu/%hu: subpart tag 0x%04x, len %hu\n", + param->tag, pos, param->len, par_tag, par_len); switch (par_tag) { case SUA_IEI_PC: @@ -768,12 +820,22 @@ out->presence |= OSMO_SCCP_ADDR_T_SSN; break; case SUA_IEI_GT: - /* TODO */ + if (par_datalen < 8) + goto subpar_fail; + sua_parse_gt(&out->gt, par->data, par_datalen); out->presence |= OSMO_SCCP_ADDR_T_GT; break; + case SUA_IEI_IPv4: + if (par_datalen != 4) + goto subpar_fail; + p32 = (uint32_t*)par->data; + /* no endian conversion, both network order */ + out->ip.v4.s_addr = *p32; + out->presence |= OSMO_SCCP_ADDR_T_IPv4; + break; default: - LOGP(DSUA, LOGL_ERROR, "SUA IEI %d: Unknown subpart tag %hd\n", - iei, par_tag); + LOGP(DSUA, LOGL_ERROR, "SUA IEI 0x%04x: Unknown subpart tag %hd\n", + param->tag, par_tag); goto subpar_fail; } @@ -783,9 +845,25 @@ return 0; subpar_fail: - LOGP(DSUA, LOGL_ERROR, "Failed to parse subparts of address IEI=%d\n", - iei); + LOGP(DSUA, LOGL_ERROR, "Failed to parse subparts of address IEI=0x%04x\n", + param->tag); return -EINVAL; +} + +/*! \brief parse SCCP address from given xUA message IE + * \param[out] out caller-allocated decoded SCCP address struct + * \param[in] xua xUA message + * \param[in] iei Information Element Identifier inside \ref xua + \returns 0 on success; negative on error */ +int sua_addr_parse(struct osmo_sccp_addr *out, struct xua_msg *xua, uint16_t iei) +{ + const struct xua_msg_part *param = xua_msg_find_tag(xua, iei); + if (!param) { + memset(out, 0, sizeof(*out)); + return -ENODEV; + } + + return sua_addr_parse_part(out, param); } static int sua_rx_cldt(struct osmo_sccp_link *link, struct xua_msg *xua) @@ -802,8 +880,8 @@ osmo_prim_init(&prim->oph, SCCP_SAP_USER, OSMO_SCU_PRIM_N_UNITDATA, PRIM_OP_INDICATION, upmsg); - sua_parse_addr(¶m->called_addr, xua, SUA_IEI_DEST_ADDR); - sua_parse_addr(¶m->calling_addr, xua, SUA_IEI_SRC_ADDR); + sua_addr_parse(¶m->called_addr, xua, SUA_IEI_DEST_ADDR); + sua_addr_parse(¶m->calling_addr, xua, SUA_IEI_SRC_ADDR); param->in_sequence_control = xua_msg_get_u32(xua, SUA_IEI_SEQ_CTRL); protocol_class = xua_msg_get_u32(xua, SUA_IEI_PROTO_CLASS); param->return_option = protocol_class & 0x80; @@ -849,8 +927,8 @@ /* fill conn */ conn = conn_create(link); - sua_parse_addr(&conn->called_addr, xua, SUA_IEI_DEST_ADDR); - sua_parse_addr(&conn->calling_addr, xua, SUA_IEI_SRC_ADDR); + sua_addr_parse(&conn->called_addr, xua, SUA_IEI_DEST_ADDR); + sua_addr_parse(&conn->calling_addr, xua, SUA_IEI_SRC_ADDR); conn->remote_ref = xua_msg_get_u32(xua, SUA_IEI_SRC_REF); /* fill primitive */ -- To view, visit https://gerrit.osmocom.org/2211 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I186df77cbdbedfe1a60b855be3626b6766f4681c Gerrit-PatchSet: 6 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Apr 10 11:03:29 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 11:03:29 +0000 Subject: [MERGED] libosmo-sccp[master]: SUA: Port to new osmo_ss7 and SCCP code In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: SUA: Port to new osmo_ss7 and SCCP code ...................................................................... SUA: Port to new osmo_ss7 and SCCP code If we use the infrastructure provided by osmo_ss7 on the lower layer and the SCCP SCRC, SCLC and SCOC code on the upper side, not much of the original sua.c code remains. It looks much like the M3UA code now. Change-Id: I193b74f58aa70c443ae17e78b5604246d6bc3f71 --- M include/osmocom/sigtran/Makefile.am M include/osmocom/sigtran/sccp_helpers.h D include/osmocom/sigtran/sua.h M src/osmo_ss7.c M src/sccp_helpers.c M src/sccp_scrc.c M src/sua.c M src/xua_internal.h 8 files changed, 364 insertions(+), 1,296 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/include/osmocom/sigtran/Makefile.am b/include/osmocom/sigtran/Makefile.am index ca7a304..0aa90cb 100644 --- a/include/osmocom/sigtran/Makefile.am +++ b/include/osmocom/sigtran/Makefile.am @@ -1,5 +1,5 @@ sigtran_HEADERS = xua_types.h xua_msg.h m2ua_types.h sccp_sap.h \ - sua.h sigtran_sap.h sccp_helpers.h mtp_sap.h osmo_ss7.h + sigtran_sap.h sccp_helpers.h mtp_sap.h osmo_ss7.h sigtrandir = $(includedir)/osmocom/sigtran diff --git a/include/osmocom/sigtran/sccp_helpers.h b/include/osmocom/sigtran/sccp_helpers.h index 968c500..bbd0364 100644 --- a/include/osmocom/sigtran/sccp_helpers.h +++ b/include/osmocom/sigtran/sccp_helpers.h @@ -1,15 +1,17 @@ #pragma once + #include #include #include -#include -int osmo_sccp_tx_unitdata(struct osmo_sccp_link *link, +void osmo_sccp_make_addr_pc_ssn(struct osmo_sccp_addr *addr, uint32_t pc, uint32_t ssn); + +int osmo_sccp_tx_unitdata(struct osmo_sccp_user *scu, const struct osmo_sccp_addr *calling_addr, const struct osmo_sccp_addr *called_addr, - uint8_t *data, unsigned int len); + const uint8_t *data, unsigned int len); -int osmo_sccp_tx_unitdata_msg(struct osmo_sccp_link *link, +int osmo_sccp_tx_unitdata_msg(struct osmo_sccp_user *scu, const struct osmo_sccp_addr *calling_addr, const struct osmo_sccp_addr *called_addr, struct msgb *msg); @@ -17,26 +19,38 @@ void osmo_sccp_make_addr_pc_ssn(struct osmo_sccp_addr *addr, uint32_t pc, uint32_t ssn); -int osmo_sccp_tx_unitdata_ranap(struct osmo_sccp_link *link, +int osmo_sccp_tx_unitdata_ranap(struct osmo_sccp_user *scu, uint32_t src_point_code, uint32_t dst_point_code, - uint8_t *data, unsigned int len); + const uint8_t *data, unsigned int len); -int osmo_sccp_tx_conn_req(struct osmo_sccp_link *link, uint32_t conn_id, +int osmo_sccp_tx_conn_req(struct osmo_sccp_user *scu, uint32_t conn_id, const struct osmo_sccp_addr *calling_addr, const struct osmo_sccp_addr *called_addr, - uint8_t *data, unsigned int len); + const uint8_t *data, unsigned int len); -int osmo_sccp_tx_conn_req_msg(struct osmo_sccp_link *link, uint32_t conn_id, +int osmo_sccp_tx_conn_req_msg(struct osmo_sccp_user *scu, uint32_t conn_id, const struct osmo_sccp_addr *calling_addr, const struct osmo_sccp_addr *called_addr, struct msgb *msg); -int osmo_sccp_tx_data(struct osmo_sccp_link *link, uint32_t conn_id, - uint8_t *data, unsigned int len); +int osmo_sccp_tx_data(struct osmo_sccp_user *scu, uint32_t conn_id, + const uint8_t *data, unsigned int len); -int osmo_sccp_tx_data_msg(struct osmo_sccp_link *link, uint32_t conn_id, +int osmo_sccp_tx_data_msg(struct osmo_sccp_user *scu, uint32_t conn_id, struct msgb *msg); +int osmo_sccp_tx_disconn(struct osmo_sccp_user *scu, uint32_t conn_id, + const struct osmo_sccp_addr *resp_addr, + uint32_t cause); + +int osmo_sccp_tx_conn_resp_msg(struct osmo_sccp_user *scu, uint32_t conn_id, + const struct osmo_sccp_addr *resp_addr, + struct msgb *msg); + +int osmo_sccp_tx_conn_resp(struct osmo_sccp_user *scu, uint32_t conn_id, + const struct osmo_sccp_addr *resp_addr, + const uint8_t *data, unsigned int len); + char *osmo_sccp_gt_dump(const struct osmo_sccp_gt *gt); char *osmo_sccp_addr_dump(const struct osmo_sccp_addr *addr); diff --git a/include/osmocom/sigtran/sua.h b/include/osmocom/sigtran/sua.h deleted file mode 100644 index 766b488..0000000 --- a/include/osmocom/sigtran/sua.h +++ /dev/null @@ -1,23 +0,0 @@ -#pragma once - -#include -#include - -struct osmo_sccp_user; -struct osmo_sccp_link; - -void osmo_sua_set_log_area(int area); - -struct osmo_sccp_user *osmo_sua_user_create(void *ctx, osmo_prim_cb prim_cb, - void *priv); -void osmo_sua_user_destroy(struct osmo_sccp_user *user); - -int osmo_sua_server_listen(struct osmo_sccp_user *user, const char *hostname, uint16_t port); - -int osmo_sua_client_connect(struct osmo_sccp_user *user, const char *hostname, uint16_t port); -struct osmo_sccp_link *osmo_sua_client_get_link(struct osmo_sccp_user *user); - -/* user hands us a SCCP-USER SAP primitive down into the stack */ -int osmo_sua_user_link_down(struct osmo_sccp_link *link, struct osmo_prim_hdr *oph); - -void *osmo_sccp_link_get_user_priv(struct osmo_sccp_link *slink); diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index 6d0b446..ab0636c 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -1197,7 +1197,9 @@ msgb_sctp_stream(msg) = ntohl(sinfo.sinfo_stream); msg->dst = asp; - if (ppid == M3UA_PPID && asp->cfg.proto == OSMO_SS7_ASP_PROT_M3UA) + if (ppid == SUA_PPID && asp->cfg.proto == OSMO_SS7_ASP_PROT_SUA) + rc = sua_rx_msg(asp, msg); + else if (ppid == M3UA_PPID && asp->cfg.proto == OSMO_SS7_ASP_PROT_M3UA) rc = m3ua_rx_msg(asp, msg); else { LOGPASP(asp, DLSS7, LOGL_NOTICE, "SCTP chunk for unknown PPID %u " @@ -1280,7 +1282,9 @@ msgb_sctp_stream(msg) = ntohl(sinfo.sinfo_stream); msg->dst = asp; - if (ppid == M3UA_PPID && asp->cfg.proto == OSMO_SS7_ASP_PROT_M3UA) + if (ppid == SUA_PPID && asp->cfg.proto == OSMO_SS7_ASP_PROT_SUA) + rc = sua_rx_msg(asp, msg); + else if (ppid == M3UA_PPID && asp->cfg.proto == OSMO_SS7_ASP_PROT_M3UA) rc = m3ua_rx_msg(asp, msg); else { LOGPASP(asp, DLSS7, LOGL_NOTICE, "SCTP chunk for unknown PPID %u " diff --git a/src/sccp_helpers.c b/src/sccp_helpers.c index 6264424..c588607 100644 --- a/src/sccp_helpers.c +++ b/src/sccp_helpers.c @@ -1,6 +1,6 @@ /* SCCP User SAP helper functions */ -/* (C) 2015 by Harald Welte +/* (C) 2015-2017 by Harald Welte * (C) 2016 by sysmocom s.m.f.c. GmbH * All Rights Reserved * @@ -27,8 +27,14 @@ #include #include -#include #include + +#include "sccp_internal.h" + +static struct msgb *scu_msgb_alloc(const char *name) +{ + return sccp_msgb_alloc("SCU"); +} void osmo_sccp_make_addr_pc_ssn(struct osmo_sccp_addr *addr, uint32_t pc, uint32_t ssn) { @@ -37,12 +43,12 @@ addr->pc = pc; } -int osmo_sccp_tx_unitdata(struct osmo_sccp_link *link, +int osmo_sccp_tx_unitdata(struct osmo_sccp_user *scu, const struct osmo_sccp_addr *calling_addr, const struct osmo_sccp_addr *called_addr, - uint8_t *data, unsigned int len) + const uint8_t *data, unsigned int len) { - struct msgb *msg = msgb_alloc(1024, "sccp_tx_unitdata"); + struct msgb *msg = scu_msgb_alloc(__func__); struct osmo_scu_prim *prim; struct osmo_scu_unitdata_param *param; @@ -55,13 +61,13 @@ msg->l2h = msgb_put(msg, len); memcpy(msg->l2h, data, len); - return osmo_sua_user_link_down(link, &prim->oph); + return osmo_sccp_user_sap_down(scu, &prim->oph); } -int osmo_sccp_tx_unitdata_ranap(struct osmo_sccp_link *link, +int osmo_sccp_tx_unitdata_ranap(struct osmo_sccp_user *scu, uint32_t src_point_code, uint32_t dst_point_code, - uint8_t *data, unsigned int len) + const uint8_t *data, unsigned int len) { struct osmo_sccp_addr calling_addr; struct osmo_sccp_addr called_addr; @@ -69,67 +75,70 @@ OSMO_SCCP_SSN_RANAP); osmo_sccp_make_addr_pc_ssn(&called_addr, dst_point_code, OSMO_SCCP_SSN_RANAP); - return osmo_sccp_tx_unitdata(link, &calling_addr, &called_addr, + return osmo_sccp_tx_unitdata(scu, &calling_addr, &called_addr, data, len); } -int osmo_sccp_tx_unitdata_msg(struct osmo_sccp_link *link, +int osmo_sccp_tx_unitdata_msg(struct osmo_sccp_user *scu, const struct osmo_sccp_addr *calling_addr, const struct osmo_sccp_addr *called_addr, struct msgb *msg) { int rc; - rc = osmo_sccp_tx_unitdata(link, calling_addr, called_addr, + rc = osmo_sccp_tx_unitdata(scu, calling_addr, called_addr, msg->data, msgb_length(msg)); msgb_free(msg); return rc; } -int osmo_sccp_tx_conn_req(struct osmo_sccp_link *link, uint32_t conn_id, +int osmo_sccp_tx_conn_req(struct osmo_sccp_user *scu, uint32_t conn_id, const struct osmo_sccp_addr *calling_addr, const struct osmo_sccp_addr *called_addr, - uint8_t *data, unsigned int len) + const uint8_t *data, unsigned int len) { - struct msgb *msg = msgb_alloc(1024, "sccp_tx_conn_req"); + struct msgb *msg = scu_msgb_alloc(__func__); struct osmo_scu_prim *prim; + struct osmo_scu_connect_param *param; prim = (struct osmo_scu_prim *) msgb_put(msg, sizeof(*prim)); osmo_prim_init(&prim->oph, SCCP_SAP_USER, OSMO_SCU_PRIM_N_CONNECT, PRIM_OP_REQUEST, msg); - osmo_sccp_make_addr_pc_ssn(&prim->u.connect.calling_addr, 1, - OSMO_SCCP_SSN_RANAP); - prim->u.connect.sccp_class = 2; - prim->u.connect.conn_id = conn_id; + param = &prim->u.connect; + if (calling_addr) + memcpy(¶m->calling_addr, calling_addr, sizeof(*calling_addr)); + memcpy(¶m->called_addr, called_addr, sizeof(*called_addr)); + param->sccp_class = 2; + param->conn_id = conn_id; if (data && len) { msg->l2h = msgb_put(msg, len); memcpy(msg->l2h, data, len); } - return osmo_sua_user_link_down(link, &prim->oph); + return osmo_sccp_user_sap_down(scu, &prim->oph); } -int osmo_sccp_tx_conn_req_msg(struct osmo_sccp_link *link, uint32_t conn_id, +int osmo_sccp_tx_conn_req_msg(struct osmo_sccp_user *scu, uint32_t conn_id, const struct osmo_sccp_addr *calling_addr, const struct osmo_sccp_addr *called_addr, struct msgb *msg) { int rc; - rc = osmo_sccp_tx_conn_req(link, conn_id, calling_addr, called_addr, + rc = osmo_sccp_tx_conn_req(scu, conn_id, calling_addr, called_addr, msg->data, msgb_length(msg)); msgb_free(msg); return rc; } -int osmo_sccp_tx_data(struct osmo_sccp_link *link, uint32_t conn_id, - uint8_t *data, unsigned int len) +int osmo_sccp_tx_data(struct osmo_sccp_user *scu, uint32_t conn_id, + const uint8_t *data, unsigned int len) { - struct msgb *msg = msgb_alloc(1024, "sccp_tx_data"); + struct msgb *msg = scu_msgb_alloc(__func__); struct osmo_scu_prim *prim; prim = (struct osmo_scu_prim *) msgb_put(msg, sizeof(*prim)); @@ -141,20 +150,79 @@ msg->l2h = msgb_put(msg, len); memcpy(msg->l2h, data, len); - return osmo_sua_user_link_down(link, &prim->oph); + return osmo_sccp_user_sap_down(scu, &prim->oph); } -int osmo_sccp_tx_data_msg(struct osmo_sccp_link *link, uint32_t conn_id, +int osmo_sccp_tx_data_msg(struct osmo_sccp_user *scu, uint32_t conn_id, struct msgb *msg) { int rc; - rc = osmo_sccp_tx_data(link, conn_id, msg->data, msgb_length(msg)); + rc = osmo_sccp_tx_data(scu, conn_id, msg->data, msgb_length(msg)); msgb_free(msg); return rc; } +/* N-DISCONNECT.req */ +int osmo_sccp_tx_disconn(struct osmo_sccp_user *scu, uint32_t conn_id, + const struct osmo_sccp_addr *resp_addr, + uint32_t cause) +{ + struct msgb *msg = scu_msgb_alloc(__func__); + struct osmo_scu_prim *prim; + struct osmo_scu_disconn_param *param; + + prim = (struct osmo_scu_prim *) msgb_put(msg, sizeof(*prim)); + osmo_prim_init(&prim->oph, SCCP_SAP_USER, + OSMO_SCU_PRIM_N_DISCONNECT, + PRIM_OP_REQUEST, msg); + param = &prim->u.disconnect; + memset(param, 0, sizeof(*param)); + param->originator = OSMO_SCCP_ORIG_NS_USER; + if (resp_addr) + memcpy(¶m->responding_addr, resp_addr, sizeof(*resp_addr)); + param->conn_id = conn_id; + param->cause = cause; + + return osmo_sccp_user_sap_down(scu, &prim->oph); +} + +/* N-CONNECT.resp */ +int osmo_sccp_tx_conn_resp_msg(struct osmo_sccp_user *scu, uint32_t conn_id, + const struct osmo_sccp_addr *resp_addr, + struct msgb *msg) +{ + struct osmo_scu_prim *prim; + struct osmo_scu_connect_param *param; + + msg->l2h = msg->data; + + prim = (struct osmo_scu_prim *) msgb_push(msg, sizeof(*prim)); + osmo_prim_init(&prim->oph, SCCP_SAP_USER, + OSMO_SCU_PRIM_N_CONNECT, + PRIM_OP_RESPONSE, msg); + param = &prim->u.connect; + param->conn_id = conn_id; + memcpy(¶m->responding_addr, resp_addr, sizeof(*resp_addr)); + param->sccp_class = 2; + + return osmo_sccp_user_sap_down(scu, &prim->oph); +} + +int osmo_sccp_tx_conn_resp(struct osmo_sccp_user *scu, uint32_t conn_id, + const struct osmo_sccp_addr *resp_addr, + const uint8_t *data, unsigned int len) +{ + struct msgb *msg = scu_msgb_alloc(__func__); + + if (data && len) { + msg->l2h = msgb_put(msg, len); + memcpy(msg->l2h, data, len); + } + return osmo_sccp_tx_conn_resp_msg(scu, conn_id, resp_addr, msg); +} + static void append_to_buf(char *buf, bool *comma, const char *fmt, ...) { va_list ap; diff --git a/src/sccp_scrc.c b/src/sccp_scrc.c index 9bccc0a..0ab25cb 100644 --- a/src/sccp_scrc.c +++ b/src/sccp_scrc.c @@ -139,6 +139,8 @@ if (rt->dest.as) { struct osmo_ss7_as *as = rt->dest.as; switch (as->cfg.proto) { + case OSMO_SS7_ASP_PROT_SUA: + return sua_tx_xua_as(as, xua); case OSMO_SS7_ASP_PROT_M3UA: return sua2sccp_tx_m3ua(inst, xua); default: diff --git a/src/sua.c b/src/sua.c index 0f42d63..b0d5f8a 100644 --- a/src/sua.c +++ b/src/sua.c @@ -29,17 +29,20 @@ #include #include #include +#include #include #include #include +#include #include -#include +#include +#include +#include "xua_asp_fsm.h" #include "xua_internal.h" - -#define SUA_MSGB_SIZE 1500 +#include "sccp_internal.h" /* Appendix C.4 of Q.714 (all in milliseconds) */ #define CONNECTION_TIMER ( 1 * 60 * 100) @@ -205,6 +208,7 @@ .name = "SUA", .ppid = SUA_PPID, .port = SUA_PORT, + .log_subsys = DLSUA, .class = { [SUA_MSGC_MGMT] = &m3ua_msg_class_mgmt, [SUA_MSGC_SNM] = &m3ua_msg_class_snm, @@ -216,480 +220,81 @@ }, }; - -static int DSUA = -1; - -struct osmo_sccp_user { - /* global list of SUA users? */ - struct llist_head list; - /* set if we are a server */ - struct osmo_stream_srv_link *server; - struct osmo_stream_cli *client; - struct llist_head links; - /* user call-back function in case of incoming primitives */ - osmo_prim_cb prim_cb; - void *priv; -}; - -struct osmo_sccp_link { - /* list of SUA links per sua_user */ - struct llist_head list; - /* sua user to which we belong */ - struct osmo_sccp_user *user; - /* local list of (SCCP) connections in this link */ - struct llist_head connections; - /* next connection local reference */ - uint32_t next_id; - int is_server; - void *data; -}; - -enum sua_connection_state { - S_IDLE, - S_CONN_PEND_IN, - S_CONN_PEND_OUT, - S_ACTIVE, - S_DISCONN_PEND, - S_RESET_IN, - S_RESET_OUT, - S_BOTHWAY_RESET, - S_WAIT_CONN_CONF, -}; - -static const struct value_string conn_state_names[] = { - { S_IDLE, "IDLE" }, - { S_CONN_PEND_IN, "CONN_PEND_IN" }, - { S_CONN_PEND_OUT, "CONN_PEND_OUT" }, - { S_ACTIVE, "ACTIVE" }, - { S_DISCONN_PEND, "DISCONN_PEND" }, - { S_RESET_IN, "RESET_IN" }, - { S_RESET_OUT, "RESET_OUT" }, - { S_BOTHWAY_RESET, "BOTHWAY_RESET" }, - { S_WAIT_CONN_CONF, "WAIT_CONN_CONF" }, - { 0, NULL } -}; - -struct sua_connection { - struct llist_head list; - struct osmo_sccp_link *link; - struct osmo_sccp_addr calling_addr; - struct osmo_sccp_addr called_addr; - uint32_t conn_id; - uint32_t remote_ref; - enum sua_connection_state state; - struct osmo_timer_list timer; - /* inactivity timers */ - struct osmo_timer_list tias; - struct osmo_timer_list tiar; -}; - - /*********************************************************************** - * SUA Link and Connection handling + * ERROR generation ***********************************************************************/ -static struct osmo_sccp_link *sua_link_new(struct osmo_sccp_user *user, int is_server) +static struct xua_msg *sua_gen_error(uint32_t err_code) { - struct osmo_sccp_link *link; + struct xua_msg *xua = xua_msg_alloc(); - link = talloc_zero(user, struct osmo_sccp_link); - if (!link) - return NULL; + xua->hdr = XUA_HDR(SUA_MSGC_MGMT, SUA_MGMT_ERR); + xua->hdr.version = SUA_VERSION; + xua_msg_add_u32(xua, SUA_IEI_ERR_CODE, err_code); - link->user = user; - link->is_server = is_server; - INIT_LLIST_HEAD(&link->connections); - - llist_add_tail(&link->list, &user->links); - - return link; + return xua; } -static void conn_destroy(struct sua_connection *conn); - -static void sua_link_destroy(struct osmo_sccp_link *link) +static struct xua_msg *sua_gen_error_msg(uint32_t err_code, struct msgb *msg) { - struct sua_connection *conn; + struct xua_msg *xua = sua_gen_error(err_code); + unsigned int len_max_40 = msgb_length(msg); - llist_for_each_entry(conn, &link->connections, list) - conn_destroy(conn); + if (len_max_40 > 40) + len_max_40 = 40; - llist_del(&link->list); + xua_msg_add_data(xua, SUA_IEI_DIAG_INFO, len_max_40, msgb_data(msg)); - /* FIXME: do we need to cleanup the sccp link? */ - - talloc_free(link); + return xua; } -static int sua_link_send(struct osmo_sccp_link *link, struct msgb *msg) +/*********************************************************************** + * Transmitting SUA messsages to SCTP + ***********************************************************************/ + +static int sua_tx_xua_asp(struct osmo_ss7_asp *asp, struct xua_msg *xua) { + struct msgb *msg = xua_to_msg(SUA_VERSION, xua); + + OSMO_ASSERT(asp->cfg.proto == OSMO_SS7_ASP_PROT_SUA); + + xua_msg_free(xua); + + if (!msg) { + LOGPASP(asp, DLSUA, LOGL_ERROR, "Error encoding SUA Msg\n"); + return -1; + } + msgb_sctp_ppid(msg) = SUA_PPID; - - DEBUGP(DSUA, "sua_link_send(%s)\n", osmo_hexdump(msg->data, msgb_length(msg))); - - if (link->is_server) - osmo_stream_srv_send(link->data, msg); - else - osmo_stream_cli_send(link->data, msg); - - return 0; + return osmo_ss7_asp_send(asp, msg); } -static struct sua_connection *conn_find_by_id(struct osmo_sccp_link *link, uint32_t id) +/*! \brief Send a given xUA message via a given SUA Application Server + * \param[in] as Application Server through which to send \ref xua + * \param[in] xua xUA message to be sent + * \return 0 on success; negative on error */ +int sua_tx_xua_as(struct osmo_ss7_as *as, struct xua_msg *xua) { - struct sua_connection *conn; + struct osmo_ss7_asp *asp; + unsigned int i; - llist_for_each_entry(conn, &link->connections, list) { - if (conn->conn_id == id) - return conn; + OSMO_ASSERT(as->cfg.proto == OSMO_SS7_ASP_PROT_SUA); + + /* FIXME: Select ASP within AS depending on traffic mode */ + for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) { + asp = as->cfg.asps[i]; + if (!asp) + continue; + if (asp) + break; } - return NULL; -} - -static void tx_inact_tmr_cb(void *data) -{ - struct sua_connection *conn = data; - struct xua_msg *xua = xua_msg_alloc(); - struct msgb *outmsg; - - /* encode + send the CLDT */ - xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_COIT); - xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, 0); /* FIXME */ - xua_msg_add_u32(xua, SUA_IEI_PROTO_CLASS, 2); - xua_msg_add_u32(xua, SUA_IEI_SRC_REF, conn->conn_id); - xua_msg_add_u32(xua, SUA_IEI_DEST_REF, conn->remote_ref); - /* optional: sequence number; credit (both class 3 only) */ - - outmsg = xua_to_msg(1, xua); - xua_msg_free(xua); - - sua_link_send(conn->link, outmsg); -} - -static void rx_inact_tmr_cb(void *data) -{ - struct sua_connection *conn = data; - - /* FIXME: release connection */ - /* Send N-DISCONNECT.ind to local user */ - /* Send RLSD to peer */ - /* enter disconnect pending state with release timer pending */ -} - - -static struct sua_connection *conn_create_id(struct osmo_sccp_link *link, uint32_t conn_id) -{ - struct sua_connection *conn = talloc_zero(link, struct sua_connection); - - conn->conn_id = conn_id; - conn->link = link; - conn->state = S_IDLE; - - llist_add_tail(&conn->list, &link->connections); - - conn->tias.cb = tx_inact_tmr_cb; - conn->tias.data = conn; - conn->tiar.cb = rx_inact_tmr_cb; - conn->tiar.data = conn; - - return conn; -} - -static struct sua_connection *conn_create(struct osmo_sccp_link *link) -{ - uint32_t conn_id; - - do { - conn_id = link->next_id++; - } while (conn_find_by_id(link, conn_id)); - - return conn_create_id(link, conn_id); -} - -static void conn_destroy(struct sua_connection *conn) -{ - /* FIXME: do some cleanup; inform user? */ - osmo_timer_del(&conn->tias); - osmo_timer_del(&conn->tiar); - llist_del(&conn->list); - talloc_free(conn); -} - -static void conn_state_set(struct sua_connection *conn, - enum sua_connection_state state) -{ - DEBUGP(DSUA, "(%u) state chg %s->", conn->conn_id, - get_value_string(conn_state_names, conn->state)); - DEBUGPC(DSUA, "%s\n", - get_value_string(conn_state_names, state)); - conn->state = state; -} - -static void conn_restart_tx_inact_timer(struct sua_connection *conn) -{ - osmo_timer_schedule(&conn->tias, TX_INACT_TIMER / 100, - (TX_INACT_TIMER % 100) * 10); -} - -static void conn_restart_rx_inact_timer(struct sua_connection *conn) -{ - osmo_timer_schedule(&conn->tiar, RX_INACT_TIMER / 100, - (RX_INACT_TIMER % 100) * 10); -} - -static void conn_start_inact_timers(struct sua_connection *conn) -{ - conn_restart_tx_inact_timer(conn); - conn_restart_rx_inact_timer(conn); -} - -/*********************************************************************** - * Handling of messages from the User SAP - ***********************************************************************/ - -/* user program sends us a N-CONNNECT.req to initiate a new connection */ -static int sua_connect_req(struct osmo_sccp_link *link, struct osmo_scu_prim *prim) -{ - struct osmo_scu_connect_param *par = &prim->u.connect; - struct xua_msg *xua = xua_msg_alloc(); - struct sua_connection *conn; - struct msgb *outmsg; - - if (par->sccp_class != 2) { - LOGP(DSUA, LOGL_ERROR, "N-CONNECT.req for unsupported " - "SCCP class %u\n", par->sccp_class); - /* FIXME: Send primitive to user */ - return -EINVAL; - } - - conn = conn_create_id(link, par->conn_id); - if (!conn) { - /* FIXME: Send primitive to user */ - return -EINVAL; - } - - memcpy(&conn->called_addr, &par->called_addr, - sizeof(conn->called_addr)); - memcpy(&conn->calling_addr, &par->calling_addr, - sizeof(conn->calling_addr)); - - /* encode + send the CLDT */ - xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_CORE); - xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, 0); /* FIXME */ - xua_msg_add_u32(xua, SUA_IEI_PROTO_CLASS, par->sccp_class); - xua_msg_add_u32(xua, SUA_IEI_SRC_REF, conn->conn_id); - xua_msg_add_sccp_addr(xua, SUA_IEI_DEST_ADDR, &par->called_addr); - xua_msg_add_u32(xua, SUA_IEI_SEQ_CTRL, 0); /* FIXME */ - /* sequence number */ - if (par->calling_addr.presence) - xua_msg_add_sccp_addr(xua, SUA_IEI_SRC_ADDR, &par->calling_addr); - /* optional: hop count; importance; priority; credit */ - if (msgb_l2(prim->oph.msg)) - xua_msg_add_data(xua, SUA_IEI_DATA, msgb_l2len(prim->oph.msg), - msgb_l2(prim->oph.msg)); - - outmsg = xua_to_msg(1, xua); - xua_msg_free(xua); - - /* FIXME: Start CONNECTION_TIMER */ - conn_state_set(conn, S_CONN_PEND_OUT); - - return sua_link_send(link, outmsg); -} - -/* user program sends us a N-CONNNECT.resp, presumably against a - * N-CONNECT.ind */ -static int sua_connect_resp(struct osmo_sccp_link *link, struct osmo_scu_prim *prim) -{ - struct osmo_scu_connect_param *par = &prim->u.connect; - struct xua_msg *xua = xua_msg_alloc(); - struct sua_connection *conn; - struct msgb *outmsg; - - /* check if we already know a connection for this conn_id */ - conn = conn_find_by_id(link, par->conn_id); - if (!conn) { - LOGP(DSUA, LOGL_ERROR, "N-CONNECT.resp for unknown " - "connection ID %u\n", par->conn_id); - /* FIXME: Send primitive to user */ + if (!asp) { + LOGP(DLSUA, LOGL_ERROR, "No ASP in AS, dropping message\n"); + xua_msg_free(xua); return -ENODEV; } - if (conn->state != S_CONN_PEND_IN) { - LOGP(DSUA, LOGL_ERROR, "N-CONNECT.resp in wrong state %s\n", - get_value_string(conn_state_names, conn->state)); - /* FIXME: Send primitive to user */ - return -EINVAL; - } - - /* encode + send the COAK message */ - xua = xua_msg_alloc(); - xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_COAK); - xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, 0); /* FIXME */ - xua_msg_add_u32(xua, SUA_IEI_PROTO_CLASS, par->sccp_class); - xua_msg_add_u32(xua, SUA_IEI_DEST_REF, conn->remote_ref); - xua_msg_add_u32(xua, SUA_IEI_SRC_REF, conn->conn_id); - xua_msg_add_u32(xua, SUA_IEI_SEQ_CTRL, 0); /* FIXME */ - /* sequence number */ - if (par->calling_addr.presence) - xua_msg_add_sccp_addr(xua, SUA_IEI_SRC_ADDR, &par->calling_addr); - /* optional: hop count; importance; priority */ - /* FIXME: destination address will be present in case the CORE - * message conveys the source address parameter */ - if (par->called_addr.presence) - xua_msg_add_sccp_addr(xua, SUA_IEI_DEST_ADDR, &par->called_addr); - if (msgb_l2(prim->oph.msg)) - xua_msg_add_data(xua, SUA_IEI_DATA, msgb_l2len(prim->oph.msg), - msgb_l2(prim->oph.msg)); - - outmsg = xua_to_msg(1, xua); - xua_msg_free(xua); - - conn_state_set(conn, S_ACTIVE); - conn_start_inact_timers(conn); - - return sua_link_send(link, outmsg); -} - -/* user wants to send connection-oriented data */ -static int sua_data_req(struct osmo_sccp_link *link, struct osmo_scu_prim *prim) -{ - struct osmo_scu_data_param *par = &prim->u.data; - struct xua_msg *xua; - struct sua_connection *conn; - struct msgb *outmsg; - - /* check if we know about this conncetion, and obtain reference */ - conn = conn_find_by_id(link, par->conn_id); - if (!conn) { - LOGP(DSUA, LOGL_ERROR, "N-DATA.req for unknown " - "connection ID %u\n", par->conn_id); - /* FIXME: Send primitive to user */ - return -ENODEV; - } - - if (conn->state != S_ACTIVE) { - LOGP(DSUA, LOGL_ERROR, "N-DATA.req in wrong state %s\n", - get_value_string(conn_state_names, conn->state)); - /* FIXME: Send primitive to user */ - return -EINVAL; - } - - conn_restart_tx_inact_timer(conn); - - /* encode + send the CODT message */ - xua = xua_msg_alloc(); - xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_CODT); - xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, 0); /* FIXME */ - /* Sequence number only in expedited data */ - xua_msg_add_u32(xua, SUA_IEI_DEST_REF, conn->remote_ref); - /* optional: priority; correlation id */ - xua_msg_add_data(xua, SUA_IEI_DATA, msgb_l2len(prim->oph.msg), - msgb_l2(prim->oph.msg)); - - outmsg = xua_to_msg(1, xua); - xua_msg_free(xua); - - return sua_link_send(link, outmsg); -} - -/* user wants to disconnect a connection */ -static int sua_disconnect_req(struct osmo_sccp_link *link, struct osmo_scu_prim *prim) -{ - struct osmo_scu_disconn_param *par = &prim->u.disconnect; - struct xua_msg *xua; - struct sua_connection *conn; - struct msgb *outmsg; - - /* resolve reference of connection */ - conn = conn_find_by_id(link, par->conn_id); - if (!conn) { - LOGP(DSUA, LOGL_ERROR, "N-DISCONNECT.req for unknown " - "connection ID %u\n", par->conn_id); - /* FIXME: Send primitive to user */ - return -ENODEV; - } - - /* encode + send the RELRE */ - xua = xua_msg_alloc(); - xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_RELRE); - xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, 0); /* FIXME */ - xua_msg_add_u32(xua, SUA_IEI_DEST_REF, conn->remote_ref); - xua_msg_add_u32(xua, SUA_IEI_SRC_REF, conn->conn_id); - xua_msg_add_u32(xua, SUA_IEI_CAUSE, par->cause); - /* optional: importance */ - if (msgb_l2(prim->oph.msg)) - xua_msg_add_data(xua, SUA_IEI_DATA, msgb_l2len(prim->oph.msg), - msgb_l2(prim->oph.msg)); - - outmsg = xua_to_msg(1, xua); - xua_msg_free(xua); - - conn_state_set(conn, S_DISCONN_PEND); - conn_destroy(conn); - - LOGP(DSUA, LOGL_NOTICE, "About to send the SUA RELRE\n"); - return sua_link_send(link, outmsg); -} - -/* user wants to send connectionless data */ -static int sua_unitdata_req(struct osmo_sccp_link *link, struct osmo_scu_prim *prim) -{ - struct osmo_scu_unitdata_param *par = &prim->u.unitdata; - struct xua_msg *xua = xua_msg_alloc(); - struct msgb *outmsg; - - /* encode + send the CLDT */ - xua->hdr = XUA_HDR(SUA_MSGC_CL, SUA_CL_CLDT); - xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, 0); /* FIXME */ - xua_msg_add_u32(xua, SUA_IEI_PROTO_CLASS, 0); - xua_msg_add_sccp_addr(xua, SUA_IEI_SRC_ADDR, &par->calling_addr); - xua_msg_add_sccp_addr(xua, SUA_IEI_DEST_ADDR, &par->called_addr); - xua_msg_add_u32(xua, SUA_IEI_SEQ_CTRL, par->in_sequence_control); - /* optional: importance, ... correlation id? */ - xua_msg_add_data(xua, SUA_IEI_DATA, msgb_l2len(prim->oph.msg), - msgb_l2(prim->oph.msg)); - - outmsg = xua_to_msg(1, xua); - xua_msg_free(xua); - - return sua_link_send(link, outmsg); -} - -/* user hands us a SCCP-USER SAP primitive down into the stack */ -int osmo_sua_user_link_down(struct osmo_sccp_link *link, struct osmo_prim_hdr *oph) -{ - struct osmo_scu_prim *prim = (struct osmo_scu_prim *) oph; - struct msgb *msg = prim->oph.msg; - int rc = 0; - - LOGP(DSUA, LOGL_DEBUG, "Received SCCP User Primitive (%s)\n", - osmo_scu_prim_name(&prim->oph)); - - switch (OSMO_PRIM_HDR(&prim->oph)) { - case OSMO_PRIM(OSMO_SCU_PRIM_N_CONNECT, PRIM_OP_REQUEST): - rc = sua_connect_req(link, prim); - break; - case OSMO_PRIM(OSMO_SCU_PRIM_N_CONNECT, PRIM_OP_RESPONSE): - rc = sua_connect_resp(link, prim); - break; - case OSMO_PRIM(OSMO_SCU_PRIM_N_DATA, PRIM_OP_REQUEST): - rc = sua_data_req(link, prim); - break; - case OSMO_PRIM(OSMO_SCU_PRIM_N_DISCONNECT, PRIM_OP_REQUEST): - rc = sua_disconnect_req(link, prim); - break; - case OSMO_PRIM(OSMO_SCU_PRIM_N_UNITDATA, PRIM_OP_REQUEST): - rc = sua_unitdata_req(link, prim); - break; - default: - rc = -1; - } - - if (rc != 1) - msgb_free(msg); - - return rc; + return sua_tx_xua_asp(asp, xua); } /*********************************************************************** @@ -750,12 +355,12 @@ memset(out, 0, sizeof(*out)); - LOGP(DSUA, LOGL_DEBUG, "%s(IEI=0x%04x) (%d) %s\n", __func__, + LOGP(DLSUA, LOGL_DEBUG, "%s(IEI=0x%04x) (%d) %s\n", __func__, param->tag, param->len, osmo_hexdump(param->dat, param->len)); if (param->len < 4) { - LOGP(DSUA, LOGL_ERROR, "SUA IEI 0x%04x: invalid address length: %d\n", + LOGP(DLSUA, LOGL_ERROR, "SUA IEI 0x%04x: invalid address length: %d\n", param->tag, param->len); return -EINVAL; } @@ -778,14 +383,14 @@ break; case SUA_RI_HOST: default: - LOGP(DSUA, LOGL_ERROR, "SUA IEI 0x%04x: Routing Indicator not supported yet: %d\n", + LOGP(DLSUA, LOGL_ERROR, "SUA IEI 0x%04x: Routing Indicator not supported yet: %d\n", param->tag, ri); return -ENOTSUP; } if (ai != 7) { #if 0 - LOGP(DSUA, LOGL_ERROR, "SUA IEI 0x%04x: Address Indicator not supported yet: %x\n", + LOGP(DLSUA, LOGL_ERROR, "SUA IEI 0x%04x: Address Indicator not supported yet: %x\n", param->tag, ai); return -ENOTSUP; #endif @@ -805,7 +410,7 @@ par_len = ntohs(par->len); par_datalen = par_len - sizeof(*par); - LOGP(DSUA, LOGL_DEBUG, "SUA IEI 0x%04x pos %hu/%hu: subpart tag 0x%04x, len %hu\n", + LOGP(DLSUA, LOGL_DEBUG, "SUA IEI 0x%04x pos %hu/%hu: subpart tag 0x%04x, len %hu\n", param->tag, pos, param->len, par_tag, par_len); switch (par_tag) { @@ -838,7 +443,7 @@ out->presence |= OSMO_SCCP_ADDR_T_IPv4; break; default: - LOGP(DSUA, LOGL_ERROR, "SUA IEI 0x%04x: Unknown subpart tag %hd\n", + LOGP(DLSUA, LOGL_ERROR, "SUA IEI 0x%04x: Unknown subpart tag %hd\n", param->tag, par_tag); goto subpar_fail; } @@ -849,7 +454,7 @@ return 0; subpar_fail: - LOGP(DSUA, LOGL_ERROR, "Failed to parse subparts of address IEI=0x%04x\n", + LOGP(DLSUA, LOGL_ERROR, "Failed to parse subparts of address IEI=0x%04x\n", param->tag); return -EINVAL; } @@ -870,809 +475,205 @@ return sua_addr_parse_part(out, param); } -static int sua_rx_cldt(struct osmo_sccp_link *link, struct xua_msg *xua) +/* connectionless messages received from socket */ +static int sua_rx_cl(struct osmo_ss7_asp *asp, struct xua_msg *xua) { - struct osmo_scu_prim *prim; - struct osmo_scu_unitdata_param *param; - struct xua_msg_part *data_ie = xua_msg_find_tag(xua, SUA_IEI_DATA); - struct msgb *upmsg = sccp_msgb_alloc(__func__); - uint32_t protocol_class; + struct osmo_sccp_instance *inst = asp->inst->sccp; - /* fill primitive */ - prim = (struct osmo_scu_prim *) msgb_put(upmsg, sizeof(*prim)); - param = &prim->u.unitdata; - osmo_prim_init(&prim->oph, SCCP_SAP_USER, - OSMO_SCU_PRIM_N_UNITDATA, - PRIM_OP_INDICATION, upmsg); - sua_addr_parse(¶m->called_addr, xua, SUA_IEI_DEST_ADDR); - sua_addr_parse(¶m->calling_addr, xua, SUA_IEI_SRC_ADDR); - param->in_sequence_control = xua_msg_get_u32(xua, SUA_IEI_SEQ_CTRL); - protocol_class = xua_msg_get_u32(xua, SUA_IEI_PROTO_CLASS); - param->return_option = protocol_class & 0x80; - param->importance = xua_msg_get_u32(xua, SUA_IEI_IMPORTANCE); - - /* copy data */ - upmsg->l2h = msgb_put(upmsg, data_ie->len); - memcpy(upmsg->l2h, data_ie->dat, data_ie->len); - - /* send to user SAP */ - link->user->prim_cb(&prim->oph, link); - - return 0; + /* We feed into SCRC, which then hands the message into + * either SCLC or SCOC, or forwards it to MTP */ + return scrc_rx_mtp_xfer_ind_xua(inst, xua); } - - -/* connectioness messages received from socket */ -static int sua_rx_cl(struct osmo_sccp_link *link, - struct xua_msg *xua, struct msgb *msg) -{ - int rc = -1; - - switch (xua->hdr.msg_type) { - case SUA_CL_CLDT: - rc = sua_rx_cldt(link, xua); - break; - case SUA_CL_CLDR: - default: - break; - } - - return rc; -} - -/* RFC 3868 3.3.3 / SCCP CR (Connection Request) */ -static int sua_rx_core(struct osmo_sccp_link *link, struct xua_msg *xua) -{ - struct osmo_scu_prim *prim; - struct osmo_scu_connect_param *param; - struct xua_msg_part *data_ie = xua_msg_find_tag(xua, SUA_IEI_DATA); - struct msgb *upmsg; - struct sua_connection *conn; - - /* fill conn */ - conn = conn_create(link); - sua_addr_parse(&conn->called_addr, xua, SUA_IEI_DEST_ADDR); - sua_addr_parse(&conn->calling_addr, xua, SUA_IEI_SRC_ADDR); - conn->remote_ref = xua_msg_get_u32(xua, SUA_IEI_SRC_REF); - - /* fill primitive */ - upmsg = sccp_msgb_alloc(__func__); - prim = (struct osmo_scu_prim *) msgb_put(upmsg, sizeof(*prim)); - param = &prim->u.connect; - osmo_prim_init(&prim->oph, SCCP_SAP_USER, - OSMO_SCU_PRIM_N_CONNECT, - PRIM_OP_INDICATION, upmsg); - param->conn_id = conn->conn_id; - memcpy(¶m->called_addr, &conn->called_addr, - sizeof(param->called_addr)); - memcpy(¶m->calling_addr, &conn->calling_addr, - sizeof(param->calling_addr)); - //param->in_sequence_control; - param->sccp_class = xua_msg_get_u32(xua, SUA_IEI_PROTO_CLASS) & 3; - param->importance = xua_msg_get_u32(xua, SUA_IEI_IMPORTANCE); - - if (data_ie) { - /* copy data */ - upmsg->l2h = msgb_put(upmsg, data_ie->len); - memcpy(upmsg->l2h, data_ie->dat, data_ie->len); - } - - conn_state_set(conn, S_CONN_PEND_IN); - - /* send to user SAP */ - link->user->prim_cb(&prim->oph, link); - - return 0; -} - -/* RFC 3868 3.3.4 / SCCP CC (Connection Confirm) */ -static int sua_rx_coak(struct osmo_sccp_link *link, struct xua_msg *xua) -{ - struct osmo_scu_prim *prim; - struct sua_connection *conn; - struct osmo_scu_connect_param *param; - struct xua_msg_part *data_ie = xua_msg_find_tag(xua, SUA_IEI_DATA); - struct msgb *upmsg; - uint32_t conn_id = xua_msg_get_u32(xua, SUA_IEI_DEST_REF); - - /* resolve conn */ - conn = conn_find_by_id(link, conn_id); - if (!conn) { - LOGP(DSUA, LOGL_ERROR, "COAK for unknown reference %u\n", - conn_id); - /* FIXME: send error reply down the sua link? */ - return -1; - } - conn_restart_rx_inact_timer(conn); - - if (conn->state != S_CONN_PEND_OUT) { - LOGP(DSUA, LOGL_ERROR, "COAK in wrong state %s\n", - get_value_string(conn_state_names, conn->state)); - /* FIXME: send error reply down the sua link? */ - return -EINVAL; - } - - /* track remote reference */ - conn->remote_ref = xua_msg_get_u32(xua, SUA_IEI_SRC_REF); - - /* fill primitive */ - upmsg = sccp_msgb_alloc(__func__); - prim = (struct osmo_scu_prim *) msgb_put(upmsg, sizeof(*prim)); - param = &prim->u.connect; - osmo_prim_init(&prim->oph, SCCP_SAP_USER, - OSMO_SCU_PRIM_N_CONNECT, - PRIM_OP_CONFIRM, upmsg); - param->conn_id = conn->conn_id; - memcpy(¶m->called_addr, &conn->called_addr, - sizeof(param->called_addr)); - memcpy(¶m->calling_addr, &conn->calling_addr, - sizeof(param->calling_addr)); - //param->in_sequence_control; - param->sccp_class = xua_msg_get_u32(xua, SUA_IEI_PROTO_CLASS) & 3; - param->importance = xua_msg_get_u32(xua, SUA_IEI_IMPORTANCE); - - if (data_ie) { - /* copy data */ - upmsg->l2h = msgb_put(upmsg, data_ie->len); - memcpy(upmsg->l2h, data_ie->dat, data_ie->len); - } - - conn_state_set(conn, S_ACTIVE); - conn_start_inact_timers(conn); - - /* send to user SAP */ - link->user->prim_cb(&prim->oph, link); - - return 0; -} - -/* RFC 3868 3.3.5 / SCCP CREF (Connection Refused) */ -static int sua_rx_coref(struct osmo_sccp_link *link, struct xua_msg *xua) -{ - struct osmo_scu_prim *prim; - struct sua_connection *conn; - struct osmo_scu_disconn_param *param; - struct xua_msg_part *data_ie = xua_msg_find_tag(xua, SUA_IEI_DATA); - struct msgb *upmsg; - uint32_t conn_id = xua_msg_get_u32(xua, SUA_IEI_DEST_REF); - uint32_t cause; - - /* resolve conn */ - conn = conn_find_by_id(link, conn_id); - if (!conn) { - LOGP(DSUA, LOGL_ERROR, "COREF for unknown reference %u\n", - conn_id); - /* FIXME: send error reply down the sua link? */ - return -1; - } - conn_restart_rx_inact_timer(conn); - - /* fill primitive */ - upmsg = sccp_msgb_alloc(__func__); - prim = (struct osmo_scu_prim *) msgb_put(upmsg, sizeof(*prim)); - param = &prim->u.disconnect; - osmo_prim_init(&prim->oph, SCCP_SAP_USER, - OSMO_SCU_PRIM_N_DISCONNECT, - PRIM_OP_INDICATION, upmsg); - param->conn_id = conn_id; - param->responding_addr = conn->called_addr; - param->originator = OSMO_SCCP_ORIG_UNDEFINED; - //param->in_sequence_control; - /* TODO evaluate cause: - * cause = xua_msg_get_u32(xua, SUA_IEI_CAUSE); */ - /* optional: src addr */ - /* optional: dest addr */ - param->importance = xua_msg_get_u32(xua, SUA_IEI_IMPORTANCE); - if (data_ie) { - /* copy data */ - upmsg->l2h = msgb_put(upmsg, data_ie->len); - memcpy(upmsg->l2h, data_ie->dat, data_ie->len); - } - - /* send to user SAP */ - link->user->prim_cb(&prim->oph, link); - - conn_state_set(conn, S_IDLE); - conn_destroy(conn); - - return 0; -} - -/* RFC 3868 3.3.6 / SCCP RLSD (Released) */ -static int sua_rx_relre(struct osmo_sccp_link *link, struct xua_msg *xua) -{ - struct osmo_scu_prim *prim; - struct sua_connection *conn; - struct osmo_scu_disconn_param *param; - struct xua_msg_part *data_ie = xua_msg_find_tag(xua, SUA_IEI_DATA); - struct msgb *upmsg; - uint32_t conn_id = xua_msg_get_u32(xua, SUA_IEI_DEST_REF); - uint32_t cause; - - /* resolve conn */ - conn = conn_find_by_id(link, conn_id); - if (!conn) { - LOGP(DSUA, LOGL_ERROR, "RELRE for unknown reference %u\n", - conn_id); - /* FIXME: send error reply down the sua link? */ - return -1; - } - - /* fill primitive */ - upmsg = sccp_msgb_alloc(__func__); - prim = (struct osmo_scu_prim *) msgb_put(upmsg, sizeof(*prim)); - param = &prim->u.disconnect; - osmo_prim_init(&prim->oph, SCCP_SAP_USER, - OSMO_SCU_PRIM_N_DISCONNECT, - PRIM_OP_INDICATION, upmsg); /* what primitive? */ - - param->conn_id = conn_id; - /* source reference */ - cause = xua_msg_get_u32(xua, SUA_IEI_CAUSE); - param->importance = xua_msg_get_u32(xua, SUA_IEI_IMPORTANCE); - if (data_ie) { - /* copy data */ - upmsg->l2h = msgb_put(upmsg, data_ie->len); - memcpy(upmsg->l2h, data_ie->dat, data_ie->len); - } - - param->responding_addr = conn->called_addr; - param->originator = OSMO_SCCP_ORIG_UNDEFINED; - - /* send to user SAP */ - link->user->prim_cb(&prim->oph, link); - - conn_state_set(conn, S_IDLE); - conn_destroy(conn); - - return 0; -} - -/* RFC 3868 3.3.7 / SCCP RLC (Release Complete)*/ -static int sua_rx_relco(struct osmo_sccp_link *link, struct xua_msg *xua) -{ - struct osmo_scu_prim *prim; - struct sua_connection *conn; - struct osmo_scu_disconn_param *param; - struct msgb *upmsg; - uint32_t conn_id = xua_msg_get_u32(xua, SUA_IEI_DEST_REF); - - /* resolve conn */ - conn = conn_find_by_id(link, conn_id); - if (!conn) { - LOGP(DSUA, LOGL_ERROR, "RELCO for unknown reference %u\n", - conn_id); - /* FIXME: send error reply down the sua link? */ - return -1; - } - conn_restart_rx_inact_timer(conn); - - /* fill primitive */ - upmsg = sccp_msgb_alloc(__func__); - prim = (struct osmo_scu_prim *) msgb_put(upmsg, sizeof(*prim)); - param = &prim->u.disconnect; - osmo_prim_init(&prim->oph, SCCP_SAP_USER, - OSMO_SCU_PRIM_N_DISCONNECT, - PRIM_OP_CONFIRM, upmsg); /* what primitive? */ - - param->conn_id = conn_id; - /* source reference */ - param->importance = xua_msg_get_u32(xua, SUA_IEI_IMPORTANCE); - - param->responding_addr = conn->called_addr; - param->originator = OSMO_SCCP_ORIG_UNDEFINED; - - /* send to user SAP */ - link->user->prim_cb(&prim->oph, link); - - conn_destroy(conn); - - return 0; - -} - -/* RFC3868 3.3.1 / SCCP DT1 (Data Form 1) */ -static int sua_rx_codt(struct osmo_sccp_link *link, struct xua_msg *xua) -{ - struct osmo_scu_prim *prim; - struct sua_connection *conn; - struct osmo_scu_data_param *param; - struct xua_msg_part *data_ie = xua_msg_find_tag(xua, SUA_IEI_DATA); - struct msgb *upmsg; - uint32_t conn_id = xua_msg_get_u32(xua, SUA_IEI_DEST_REF); - - /* resolve conn */ - conn = conn_find_by_id(link, conn_id); - if (!conn) { - LOGP(DSUA, LOGL_ERROR, "DT1 for unknown reference %u\n", - conn_id); - /* FIXME: send error reply down the sua link? */ - return -1; - } - - if (conn->state != S_ACTIVE) { - LOGP(DSUA, LOGL_ERROR, "DT1 in invalid state %s\n", - get_value_string(conn_state_names, conn->state)); - /* FIXME: send error reply down the sua link? */ - return -1; - } - - conn_restart_rx_inact_timer(conn); - - /* fill primitive */ - upmsg = sccp_msgb_alloc(__func__); - prim = (struct osmo_scu_prim *) msgb_put(upmsg, sizeof(*prim)); - param = &prim->u.data; - osmo_prim_init(&prim->oph, SCCP_SAP_USER, - OSMO_SCU_PRIM_N_DATA, - PRIM_OP_INDICATION, upmsg); - param->conn_id = conn_id; - param->importance = xua_msg_get_u32(xua, SUA_IEI_IMPORTANCE); - - /* copy data */ - upmsg->l2h = msgb_put(upmsg, data_ie->len); - memcpy(upmsg->l2h, data_ie->dat, data_ie->len); - - /* send to user SAP */ - link->user->prim_cb(&prim->oph, link); - - return 0; -} - /* connection-oriented messages received from socket */ -static int sua_rx_co(struct osmo_sccp_link *link, - struct xua_msg *xua, struct msgb *msg) +static int sua_rx_co(struct osmo_ss7_asp *asp, struct xua_msg *xua) { - int rc = -1; + struct osmo_sccp_instance *inst = asp->inst->sccp; - switch (xua->hdr.msg_type) { - case SUA_CO_CORE: - rc = sua_rx_core(link, xua); - break; - case SUA_CO_COAK: - rc = sua_rx_coak(link, xua); - break; - case SUA_CO_COREF: - rc = sua_rx_coref(link, xua); - break; - case SUA_CO_RELRE: - rc = sua_rx_relre(link, xua); - break; - case SUA_CO_RELCO: - rc = sua_rx_relco(link, xua); - break; - case SUA_CO_CODT: - rc = sua_rx_codt(link, xua); - break; - case SUA_CO_RESCO: - case SUA_CO_RESRE: - case SUA_CO_CODA: - case SUA_CO_COERR: - case SUA_CO_COIT: - /* FIXME */ - default: - break; - } - - return rc; + /* We feed into SCRC, which then hands the message into + * either SCLC or SCOC, or forwards it to MTP */ + return scrc_rx_mtp_xfer_ind_xua(inst, xua); } -/* process SUA message received from socket */ -static int sua_rx_msg(struct osmo_sccp_link *link, struct msgb *msg) +static int sua_rx_mgmt_err(struct osmo_ss7_asp *asp, struct xua_msg *xua) { - struct xua_msg *xua; - int rc = -1; + uint32_t err_code = xua_msg_get_u32(xua, SUA_IEI_ERR_CODE); - xua = xua_from_msg(1, msgb_length(msg), msg->data); - if (!xua) { - LOGP(DSUA, LOGL_ERROR, "Unable to parse incoming " - "SUA message\n"); + LOGPASP(asp, DLSUA, LOGL_ERROR, "Received MGMT_ERR '%s': %s\n", + get_value_string(m3ua_err_names, err_code), + xua_msg_dump(xua, &xua_dialect_sua)); + + /* NEVER return != 0 here, as we cannot respont to an ERR + * message with another ERR! */ + return 0; +} + +static int sua_rx_mgmt_ntfy(struct osmo_ss7_asp *asp, struct xua_msg *xua) +{ + struct m3ua_notify_params ntfy; + const char *type_name, *info_name; + + m3ua_decode_notify(&ntfy, asp, xua); + + type_name = get_value_string(m3ua_ntfy_type_names, ntfy.status_type); + + switch (ntfy.status_type) { + case M3UA_NOTIFY_T_STATCHG: + info_name = get_value_string(m3ua_ntfy_stchg_names, + ntfy.status_info); + break; + case M3UA_NOTIFY_T_OTHER: + info_name = get_value_string(m3ua_ntfy_other_names, + ntfy.status_info); + break; + default: + info_name = "NULL"; + break; + } + LOGPASP(asp, DLSUA, LOGL_NOTICE, "Received NOTIFY Type %s:%s (%s)\n", + type_name, info_name, + ntfy.info_string ? ntfy.info_string : ""); + + if (ntfy.info_string) + talloc_free(ntfy.info_string); + + /* TODO: should we report this soemwhere? */ + return 0; +} + +static int sua_rx_mgmt(struct osmo_ss7_asp *asp, struct xua_msg *xua) +{ + switch (xua->hdr.msg_type) { + case SUA_MGMT_ERR: + return sua_rx_mgmt_err(asp, xua); + case SUA_MGMT_NTFY: + return sua_rx_mgmt_ntfy(asp, xua); + default: + return SUA_ERR_UNSUPP_MSG_TYPE; + } +} + +/* map from SUA ASPSM/ASPTM to xua_asp_fsm event */ +static const struct xua_msg_event_map sua_aspxm_map[] = { + { SUA_MSGC_ASPSM, SUA_ASPSM_UP, XUA_ASP_E_ASPSM_ASPUP }, + { SUA_MSGC_ASPSM, SUA_ASPSM_DOWN, XUA_ASP_E_ASPSM_ASPDN }, + { SUA_MSGC_ASPSM, SUA_ASPSM_BEAT, XUA_ASP_E_ASPSM_BEAT }, + { SUA_MSGC_ASPSM, SUA_ASPSM_UP_ACK, XUA_ASP_E_ASPSM_ASPUP_ACK }, + { SUA_MSGC_ASPSM, SUA_ASPSM_DOWN_ACK, XUA_ASP_E_ASPSM_ASPDN_ACK }, + { SUA_MSGC_ASPSM, SUA_ASPSM_BEAT_ACK, XUA_ASP_E_ASPSM_BEAT_ACK }, + { SUA_MSGC_ASPTM, SUA_ASPTM_ACTIVE, XUA_ASP_E_ASPTM_ASPAC }, + { SUA_MSGC_ASPTM, SUA_ASPTM_INACTIVE, XUA_ASP_E_ASPTM_ASPIA }, + { SUA_MSGC_ASPTM, SUA_ASPTM_ACTIVE_ACK, XUA_ASP_E_ASPTM_ASPAC_ACK }, + { SUA_MSGC_ASPTM, SUA_ASPTM_INACTIVE_ACK, XUA_ASP_E_ASPTM_ASPIA_ACK }, +}; + +static int sua_rx_asp(struct osmo_ss7_asp *asp, struct xua_msg *xua) +{ + int event; + + /* map from the SUA message class and message type to the XUA + * ASP FSM event number */ + event = xua_msg_event_map(xua, sua_aspxm_map, + ARRAY_SIZE(sua_aspxm_map)); + if (event < 0) + return SUA_ERR_UNSUPP_MSG_TYPE; + + /* deliver that event to the ASP FSM */ + osmo_fsm_inst_dispatch(asp->fi, event, xua); + + return 0; +} + +/*! \brief process SUA message received from socket + * \param[in] asp Application Server Process receiving \ref msg + * \param[in] msg received message buffer + * \returns 0 on success; negative on error */ +int sua_rx_msg(struct osmo_ss7_asp *asp, struct msgb *msg) +{ + struct xua_msg *xua = NULL, *err = NULL; + int rc = 0; + + OSMO_ASSERT(asp->cfg.proto == OSMO_SS7_ASP_PROT_SUA); + + /* caller owns msg memory, we shall neither free it here nor + * keep references beyon the execution of this function and its + * callees. */ + + if (!asp->inst->sccp) { + LOGP(DLSUA, LOGL_ERROR, "%s(asp->inst->sccp=NULL)\n", __func__); return -EIO; } - LOGP(DSUA, LOGL_DEBUG, "Received SUA Message (%s)\n", + xua = xua_from_msg(1, msgb_length(msg), msg->data); + if (!xua) { + struct xua_common_hdr *hdr = (struct xua_common_hdr *) msg->data; + + LOGPASP(asp, DLSUA, LOGL_ERROR, "Unable to parse incoming " + "SUA message\n"); + + if (hdr->version != SUA_VERSION) + err = sua_gen_error_msg(SUA_ERR_INVALID_VERSION, msg); + else + err = sua_gen_error_msg(SUA_ERR_PARAM_FIELD_ERR, msg); + goto out; + } + +#if 0 + xua->mtp.opc = ; + xua->mtp.dpc = ; +#endif + xua->mtp.sio = MTP_SI_SCCP; + + LOGPASP(asp, DLSUA, LOGL_DEBUG, "Received SUA Message (%s)\n", xua_hdr_dump(xua, &xua_dialect_sua)); - if (!xua_dialect_check_all_mand_ies(&xua_dialect_sua, xua)) - return -1; + if (!xua_dialect_check_all_mand_ies(&xua_dialect_sua, xua)) { + /* FIXME: Return error? */ + err = sua_gen_error_msg(SUA_ERR_MISSING_PARAM, msg); + goto out; + } + + /* TODO: check for SCTP Strema ID */ + /* TODO: check if any AS configured in ASP */ + /* TODO: check for valid routing context */ switch (xua->hdr.msg_class) { case SUA_MSGC_CL: - rc = sua_rx_cl(link, xua, msg); + rc = sua_rx_cl(asp, xua); break; case SUA_MSGC_CO: - rc = sua_rx_co(link, xua, msg); + rc = sua_rx_co(asp, xua); break; - case SUA_MSGC_MGMT: - case SUA_MSGC_SNM: case SUA_MSGC_ASPSM: case SUA_MSGC_ASPTM: + rc = sua_rx_asp(asp, xua); + break; + case SUA_MSGC_MGMT: + rc = sua_rx_mgmt(asp, xua); + break; + case SUA_MSGC_SNM: case SUA_MSGC_RKM: /* FIXME */ + LOGPASP(asp, DLSUA, LOGL_NOTICE, "Received unsupported SUA " + "Message Class %u\n", xua->hdr.msg_class); + err = sua_gen_error_msg(SUA_ERR_UNSUPP_MSG_CLASS, msg); + break; default: + LOGPASP(asp, DLSUA, LOGL_NOTICE, "Received unknown SUA " + "Message Class %u\n", xua->hdr.msg_class); + err = sua_gen_error_msg(SUA_ERR_UNSUPP_MSG_CLASS, msg); break; } + + if (rc > 0) + err = sua_gen_error_msg(rc, msg); + +out: + if (err) + sua_tx_xua_asp(asp, err); xua_msg_free(xua); return rc; } -/*********************************************************************** - * libosmonetif integration - ***********************************************************************/ - -#include -#include - -static const struct value_string sctp_assoc_chg_vals[] = { - { SCTP_COMM_UP, "COMM_UP" }, - { SCTP_COMM_LOST, "COMM_LOST" }, - { SCTP_RESTART, "RESTART" }, - { SCTP_SHUTDOWN_COMP, "SHUTDOWN_COMP" }, - { SCTP_CANT_STR_ASSOC, "CANT_STR_ASSOC" }, - { 0, NULL } -}; - -static const struct value_string sctp_sn_type_vals[] = { - { SCTP_ASSOC_CHANGE, "ASSOC_CHANGE" }, - { SCTP_PEER_ADDR_CHANGE, "PEER_ADDR_CHANGE" }, - { SCTP_SHUTDOWN_EVENT, "SHUTDOWN_EVENT" }, - { SCTP_SEND_FAILED, "SEND_FAILED" }, - { SCTP_REMOTE_ERROR, "REMOTE_ERROR" }, - { SCTP_PARTIAL_DELIVERY_EVENT, "PARTIAL_DELIVERY_EVENT" }, - { SCTP_ADAPTATION_INDICATION, "ADAPTATION_INDICATION" }, -#ifdef SCTP_AUTHENTICATION_INDICATION - { SCTP_AUTHENTICATION_INDICATION, "UTHENTICATION_INDICATION" }, -#endif -#ifdef SCTP_SENDER_DRY_EVENT - { SCTP_SENDER_DRY_EVENT, "SENDER_DRY_EVENT" }, -#endif - { 0, NULL } -}; - -static int get_logevel_by_sn_type(int sn_type) -{ - switch (sn_type) { - case SCTP_ADAPTATION_INDICATION: - case SCTP_PEER_ADDR_CHANGE: -#ifdef SCTP_AUTHENTICATION_INDICATION - case SCTP_AUTHENTICATION_INDICATION: -#endif -#ifdef SCTP_SENDER_DRY_EVENT - case SCTP_SENDER_DRY_EVENT: -#endif - return LOGL_INFO; - case SCTP_ASSOC_CHANGE: - return LOGL_NOTICE; - case SCTP_SHUTDOWN_EVENT: - case SCTP_PARTIAL_DELIVERY_EVENT: - return LOGL_NOTICE; - case SCTP_SEND_FAILED: - case SCTP_REMOTE_ERROR: - return LOGL_ERROR; - default: - return LOGL_NOTICE; - } -} - -static void log_sctp_notification(int fd, const char *pfx, - union sctp_notification *notif) -{ - int log_level; - char *conn_id = osmo_sock_get_name(NULL, fd); - - LOGP(DSUA, LOGL_INFO, "%s %s SCTP NOTIFICATION %u flags=0x%0x\n", - conn_id, pfx, notif->sn_header.sn_type, - notif->sn_header.sn_flags); - - log_level = get_logevel_by_sn_type(notif->sn_header.sn_type); - - switch (notif->sn_header.sn_type) { - case SCTP_ASSOC_CHANGE: - LOGP(DSUA, log_level, "%s %s SCTP_ASSOC_CHANGE: %s\n", - conn_id, pfx, get_value_string(sctp_assoc_chg_vals, - notif->sn_assoc_change.sac_state)); - break; - default: - LOGP(DSUA, log_level, "%s %s %s\n", - conn_id, pfx, get_value_string(sctp_sn_type_vals, - notif->sn_header.sn_type)); - break; - } - - talloc_free(conn_id); -} - -/* netif code tells us we can read something from the socket */ -static int sua_srv_conn_cb(struct osmo_stream_srv *conn) -{ - struct osmo_fd *ofd = osmo_stream_srv_get_ofd(conn); - struct osmo_sccp_link *link = osmo_stream_srv_get_data(conn); - struct msgb *msg = msgb_alloc(SUA_MSGB_SIZE, "SUA Server Rx"); - struct sctp_sndrcvinfo sinfo; - unsigned int ppid; - int flags = 0; - int rc; - - if (!msg) - return -ENOMEM; - - /* read SUA message from socket and process it */ - rc = sctp_recvmsg(ofd->fd, msgb_data(msg), msgb_tailroom(msg), - NULL, NULL, &sinfo, &flags); - LOGP(DSUA, LOGL_DEBUG, "sua_srv_conn_cb(): sctp_recvmsg() returned %d\n", - rc); - if (rc < 0) { - close(ofd->fd); - osmo_fd_unregister(ofd); - ofd->fd = -1; - return rc; - } else if (rc == 0) { - close(ofd->fd); - osmo_fd_unregister(ofd); - ofd->fd = -1; - } else { - msgb_put(msg, rc); - } - - if (flags & MSG_NOTIFICATION) { - union sctp_notification *notif = (union sctp_notification *) msgb_data(msg); - - log_sctp_notification(ofd->fd, "SUA SRV", notif); - - switch (notif->sn_header.sn_type) { - case SCTP_SHUTDOWN_EVENT: - close(ofd->fd); - osmo_fd_unregister(ofd); - ofd->fd = -1; - break; - default: - break; - } - msgb_free(msg); - return 0; - } - - ppid = ntohl(sinfo.sinfo_ppid); - msgb_sctp_ppid(msg) = ppid; - msgb_sctp_stream(msg) = ntohl(sinfo.sinfo_stream); - msg->dst = link; - - switch (ppid) { - case SUA_PPID: - rc = sua_rx_msg(link, msg); - break; - default: - LOGP(DSUA, LOGL_NOTICE, "SCTP chunk for unknown PPID %u " - "received\n", ppid); - rc = 0; - break; - } - - msgb_free(msg); - return rc; -} - -static int sua_srv_conn_closed_cb(struct osmo_stream_srv *srv) -{ - struct osmo_sccp_link *sual = osmo_stream_srv_get_data(srv); - struct sua_connection *conn; - - LOGP(DSUA, LOGL_INFO, "SCTP connection closed\n"); - - /* remove from per-user list of sua links */ - llist_del(&sual->list); - - llist_for_each_entry(conn, &sual->connections, list) { - /* FIXME: send RELEASE request */ - } - talloc_free(sual); - osmo_stream_srv_set_data(srv, NULL); - - return 0; -} - -static int sua_accept_cb(struct osmo_stream_srv_link *link, int fd) -{ - struct osmo_sccp_user *user = osmo_stream_srv_link_get_data(link); - struct osmo_stream_srv *srv; - struct osmo_sccp_link *sual; - - LOGP(DSUA, LOGL_INFO, "New SCTP connection accepted\n"); - - srv = osmo_stream_srv_create(user, link, fd, - sua_srv_conn_cb, - sua_srv_conn_closed_cb, NULL); - if (!srv) { - close(fd); - return -1; - } - - /* create new SUA link and connect both data structures */ - sual = sua_link_new(user, 1); - if (!sual) { - osmo_stream_srv_destroy(srv); - return -1; - } - sual->data = srv; - osmo_stream_srv_set_data(srv, sual); - - return 0; -} - -int osmo_sua_server_listen(struct osmo_sccp_user *user, const char *hostname, uint16_t port) -{ - int rc; - - if (user->server) - osmo_stream_srv_link_close(user->server); - else { - user->server = osmo_stream_srv_link_create(user); - osmo_stream_srv_link_set_data(user->server, user); - osmo_stream_srv_link_set_accept_cb(user->server, sua_accept_cb); - } - - osmo_stream_srv_link_set_addr(user->server, hostname); - osmo_stream_srv_link_set_port(user->server, port); - osmo_stream_srv_link_set_proto(user->server, IPPROTO_SCTP); - - rc = osmo_stream_srv_link_open(user->server); - if (rc < 0) { - osmo_stream_srv_link_destroy(user->server); - user->server = NULL; - return rc; - } - - return 0; -} - -/* netif code tells us we can read something from the socket */ -static int sua_cli_read_cb(struct osmo_stream_cli *conn) -{ - struct osmo_fd *ofd = osmo_stream_cli_get_ofd(conn); - struct osmo_sccp_link *link = osmo_stream_cli_get_data(conn); - struct msgb *msg = msgb_alloc(SUA_MSGB_SIZE, "SUA Client Rx"); - struct sctp_sndrcvinfo sinfo; - unsigned int ppid; - int flags = 0; - int rc; - - LOGP(DSUA, LOGL_DEBUG, "sua_cli_read_cb() rx\n"); - - if (!msg) - return -ENOMEM; - - /* read SUA message from socket and process it */ - rc = sctp_recvmsg(ofd->fd, msgb_data(msg), msgb_tailroom(msg), - NULL, NULL, &sinfo, &flags); - if (rc < 0) { - close(ofd->fd); - osmo_fd_unregister(ofd); - ofd->fd = -1; - return rc; - } else if (rc == 0) { - close(ofd->fd); - osmo_fd_unregister(ofd); - ofd->fd = -1; - } else { - msgb_put(msg, rc); - } - - if (flags & MSG_NOTIFICATION) { - union sctp_notification *notif = (union sctp_notification *) msgb_data(msg); - - log_sctp_notification(ofd->fd, "SUA CLNT", notif); - - switch (notif->sn_header.sn_type) { - case SCTP_SHUTDOWN_EVENT: - close(ofd->fd); - osmo_fd_unregister(ofd); - ofd->fd = -1; - break; - default: - break; - } - msgb_free(msg); - return 0; - } - - ppid = ntohl(sinfo.sinfo_ppid); - msgb_sctp_ppid(msg) = ppid; - msgb_sctp_stream(msg) = ntohl(sinfo.sinfo_stream); - msg->dst = link; - - switch (ppid) { - case SUA_PPID: - rc = sua_rx_msg(link, msg); - break; - default: - LOGP(DSUA, LOGL_NOTICE, "SCTP chunk for unknown PPID %u " - "received\n", ppid); - rc = 0; - break; - } - - msgb_free(msg); - return rc; -} - -int osmo_sua_client_connect(struct osmo_sccp_user *user, const char *hostname, uint16_t port) -{ - struct osmo_stream_cli *cli; - struct osmo_sccp_link *sual; - int rc; - - cli = osmo_stream_cli_create(user); - if (!cli) - return -1; - osmo_stream_cli_set_addr(cli, hostname); - osmo_stream_cli_set_port(cli, port); - osmo_stream_cli_set_proto(cli, IPPROTO_SCTP); - osmo_stream_cli_set_reconnect_timeout(cli, 5); - osmo_stream_cli_set_read_cb(cli, sua_cli_read_cb); - - /* create SUA link and associate it with stream_cli */ - sual = sua_link_new(user, 0); - if (!sual) { - osmo_stream_cli_destroy(cli); - return -1; - } - sual->data = cli; - osmo_stream_cli_set_data(cli, sual); - - rc = osmo_stream_cli_open2(cli, 1); - if (rc < 0) { - sua_link_destroy(sual); - osmo_stream_cli_destroy(cli); - return rc; - } - user->client = cli; - - return 0; -} - -struct osmo_sccp_link *osmo_sua_client_get_link(struct osmo_sccp_user *user) -{ - return osmo_stream_cli_get_data(user->client); -} - -static LLIST_HEAD(sua_users); - -struct osmo_sccp_user *osmo_sua_user_create(void *ctx, osmo_prim_cb prim_cb, - void *priv) -{ - struct osmo_sccp_user *user = talloc_zero(ctx, struct osmo_sccp_user); - - user->prim_cb = prim_cb; - user->priv = priv; - INIT_LLIST_HEAD(&user->links); - - llist_add_tail(&user->list, &sua_users); - - return user; -} - -void *osmo_sccp_link_get_user_priv(struct osmo_sccp_link *slink) -{ - return slink->user->priv; -} - -void osmo_sua_user_destroy(struct osmo_sccp_user *user) -{ - struct osmo_sccp_link *link; - - llist_del(&user->list); - - llist_for_each_entry(link, &user->links, list) - sua_link_destroy(link); - - talloc_free(user); -} - -void osmo_sua_set_log_area(int area) -{ - xua_set_log_area(area); - DSUA = area; -} diff --git a/src/xua_internal.h b/src/xua_internal.h index 66b5a26..c6f79b7 100644 --- a/src/xua_internal.h +++ b/src/xua_internal.h @@ -15,6 +15,8 @@ struct xua_msg *osmo_sccp_to_xua(struct msgb *msg); struct msgb *osmo_sua_to_sccp(struct xua_msg *xua); +int sua_rx_msg(struct osmo_ss7_asp *asp, struct msgb *msg); + int sua_tx_xua_as(struct osmo_ss7_as *as, struct xua_msg *xua); struct osmo_mtp_prim *m3ua_to_xfer_ind(struct xua_msg *xua); -- To view, visit https://gerrit.osmocom.org/2218 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I193b74f58aa70c443ae17e78b5604246d6bc3f71 Gerrit-PatchSet: 7 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Apr 10 11:06:08 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 11:06:08 +0000 Subject: [MERGED] libosmo-sccp[master]: xua: Remove library-internal DXUA log subsystem In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: xua: Remove library-internal DXUA log subsystem ...................................................................... xua: Remove library-internal DXUA log subsystem We don't really need those thre log messages, and we can thus do away with the library-internal log-subsystem of DXUA. The rest of libosmo-sigtran uses the new globa DL... subsystems anyway Change-Id: Iea0d3db34a3674a9c6422b174a879bfdaa25786f --- M include/osmocom/sigtran/xua_msg.h M src/xua_msg.c 2 files changed, 2 insertions(+), 18 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/include/osmocom/sigtran/xua_msg.h b/include/osmocom/sigtran/xua_msg.h index 320da6a..e0e1bcf 100644 --- a/include/osmocom/sigtran/xua_msg.h +++ b/include/osmocom/sigtran/xua_msg.h @@ -69,8 +69,6 @@ extern const struct xua_dialect xua_dialect_sua; extern const struct xua_dialect xua_dialect_m3ua; -extern int DXUA; - struct xua_msg *xua_msg_alloc(void); void xua_msg_free(struct xua_msg *msg); @@ -83,8 +81,6 @@ struct xua_msg *xua_from_msg(const int version, uint16_t len, uint8_t *data); struct msgb *xua_to_msg(const int version, struct xua_msg *msg); - -void xua_set_log_area(int log_area); int msgb_t16l16vp_put(struct msgb *msg, uint16_t tag, uint16_t len, const uint8_t *data); int msgb_t16l16vp_put_u32(struct msgb *msg, uint16_t tag, uint32_t val); diff --git a/src/xua_msg.c b/src/xua_msg.c index 27279ce..cb487c8 100644 --- a/src/xua_msg.c +++ b/src/xua_msg.c @@ -32,17 +32,14 @@ #include static void *tall_xua; -int DXUA = -1; struct xua_msg *xua_msg_alloc(void) { struct xua_msg *msg; msg = talloc_zero(tall_xua, struct xua_msg); - if (!msg) { - LOGP(DXUA, LOGL_ERROR, "Failed to allocate.\n"); + if (!msg) return NULL; - } INIT_LLIST_HEAD(&msg->headers); return msg; @@ -162,7 +159,6 @@ return msg; fail: - LOGP(DXUA, LOGL_ERROR, "Failed to parse.\n"); xua_msg_free(msg); return NULL; } @@ -175,10 +171,8 @@ uint8_t rest; msg = msgb_alloc_headroom(2048, 512, "xua msg"); - if (!msg) { - LOGP(DXUA, LOGL_ERROR, "Failed to allocate.\n"); + if (!msg) return NULL; - } msg->l2h = msgb_put(msg, sizeof(*hdr)); hdr = (struct xua_common_hdr *) msg->l2h; @@ -208,12 +202,6 @@ hdr->msg_length = htonl(msgb_l2len(msg)); return msg; } - -void xua_set_log_area(int log_area) -{ - DXUA = log_area; -} - /*********************************************************************** * Message encoding helper functions -- To view, visit https://gerrit.osmocom.org/2220 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Iea0d3db34a3674a9c6422b174a879bfdaa25786f Gerrit-PatchSet: 7 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Apr 10 11:06:09 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 11:06:09 +0000 Subject: [MERGED] libosmo-sccp[master]: Add example program how to use M3UA+SCCP client and server In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: Add example program how to use M3UA+SCCP client and server ...................................................................... Add example program how to use M3UA+SCCP client and server This is an example tool that can be run either as server (SG) or as client (ASP) with a SCCP+M3UA stacking, and communicate via connectionless and connection-oriented primitives over it Change-Id: Id698ce2da5726e304dfa1773b794671dc80d853c --- M .gitignore M Makefile.am M configure.ac A examples/Makefile.am A examples/internal.h A examples/m3ua_example.c A examples/sccp_test_server.c A examples/sccp_test_vty.c 8 files changed, 392 insertions(+), 1 deletion(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/.gitignore b/.gitignore index 9d1435f..83f1333 100644 --- a/.gitignore +++ b/.gitignore @@ -60,6 +60,7 @@ tests/testsuite tests/testsuite.log +examples/m3ua_example *.pc config.* diff --git a/Makefile.am b/Makefile.am index b1eff56..dd73ec2 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,7 +1,7 @@ AUTOMAKE_OPTIONS = foreign dist-bzip2 1.6 AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -SUBDIRS = include src tests +SUBDIRS = include src tests examples pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = libosmo-sccp.pc libosmo-mtp.pc libosmo-sigtran.pc libosmo-xua.pc diff --git a/configure.ac b/configure.ac index 3644d22..6dc0ebd 100644 --- a/configure.ac +++ b/configure.ac @@ -27,6 +27,7 @@ PKG_PROG_PKG_CONFIG([0.20]) PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 0.3.0) +PKG_CHECK_MODULES(LIBOSMOVTY, libosmovty >= 0.3.0) PKG_CHECK_MODULES(LIBOSMONETIF, libosmo-netif >= 0.0.6) old_LIBS=$LIBS @@ -68,5 +69,6 @@ tests/m2ua/Makefile tests/xua/Makefile tests/ss7/Makefile + examples/Makefile Makefile) diff --git a/examples/Makefile.am b/examples/Makefile.am new file mode 100644 index 0000000..6418aca --- /dev/null +++ b/examples/Makefile.am @@ -0,0 +1,11 @@ +AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include +AM_CFLAGS=-Wall -g $(LIBOSMOCORE_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(LIBOSMONETIF_CFLAGS) $(COVERAGE_FLAGS) +AM_LDFLAGS=$(COVERAGE_LDFLAGS) + +noinst_HEADERS = internal.h + +noinst_PROGRAMS = m3ua_example + +m3ua_example_SOURCES = m3ua_example.c sccp_test_server.c sccp_test_vty.c +m3ua_example_LDADD = $(top_builddir)/src/libosmo-sigtran.la \ + $(LIBOSMOCORE_LIBS) $(LIBOSMOVTY_LIBS) diff --git a/examples/internal.h b/examples/internal.h new file mode 100644 index 0000000..70b9058 --- /dev/null +++ b/examples/internal.h @@ -0,0 +1,12 @@ +#pragma once + +#define SSN_TEST_UNUSED 200 +#define SSN_TEST_REFUSE 201 +#define SSN_TEST_ECHO 202 +#define SSN_TEST_CALLBACK 203 + +struct osmo_sccp_user; + +int sccp_test_user_vty_install(struct osmo_sccp_instance *inst, int ssn); + +int sccp_test_server_init(struct osmo_sccp_instance *sccp); diff --git a/examples/m3ua_example.c b/examples/m3ua_example.c new file mode 100644 index 0000000..d7b1fc2 --- /dev/null +++ b/examples/m3ua_example.c @@ -0,0 +1,98 @@ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "internal.h" + +static struct osmo_sccp_instance *sua_server_helper(void) +{ + struct osmo_sccp_instance *sccp; + + sccp = osmo_sccp_simple_server(NULL, 1, OSMO_SS7_ASP_PROT_M3UA, + -1, "127.0.0.2"); + + osmo_sccp_simple_server_add_clnt(sccp, OSMO_SS7_ASP_PROT_M3UA, + "23", 23, -1, 0, NULL); + + return sccp; +} + +/*********************************************************************** + * Initialization + ***********************************************************************/ + +static const struct log_info_cat log_info_cat[] = { +}; + +static const struct log_info log_info = { + .cat = log_info_cat, + .num_cat = ARRAY_SIZE(log_info_cat), +}; + +static void init_logging(void) +{ + const int log_cats[] = { DLSS7, DLSUA, DLM3UA, DLSCCP, DLINP }; + unsigned int i; + + osmo_init_logging(&log_info); + + for (i = 0; i < ARRAY_SIZE(log_cats); i++) + log_set_category_filter(osmo_stderr_target, log_cats[i], 1, LOGL_DEBUG); +} + +static struct vty_app_info vty_info = { + .name = "sccp-test", + .version = 0, +}; + +int main(int argc, char **argv) +{ + struct osmo_sccp_instance *sccp; + bool client; + int rc; + + init_logging(); + osmo_ss7_init(); + osmo_fsm_log_addr(false); + vty_init(&vty_info); + + if (argc <= 1) + client = true; + else + client = false; + + rc = telnet_init_dynif(NULL, NULL, vty_get_bind_addr(), 2324+client); + if (rc < 0) { + perror("Erro binding VTY port\n"); + exit(1); + } + + + if (client) { + sccp = osmo_sccp_simple_client(NULL, "client", 23, OSMO_SS7_ASP_PROT_M3UA, 0, M3UA_PORT, "127.0.0.2"); + sccp_test_user_vty_install(sccp, OSMO_SCCP_SSN_BSC_BSSAP); + } else { + sccp = sua_server_helper(); + sccp_test_server_init(sccp); + } + + while (1) { + osmo_select_main(0); + } +} diff --git a/examples/sccp_test_server.c b/examples/sccp_test_server.c new file mode 100644 index 0000000..c3c658f --- /dev/null +++ b/examples/sccp_test_server.c @@ -0,0 +1,115 @@ + +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include "internal.h" + +unsigned int conn_id; + +/* a simple SCCP User which refuses all connections and discards all + * unitdata */ +static int refuser_prim_cb(struct osmo_prim_hdr *oph, void *_scu) +{ + struct osmo_sccp_user *scu = _scu; + struct osmo_scu_prim *scu_prim = (struct osmo_scu_prim *) oph; + + switch (OSMO_PRIM_HDR(&scu_prim->oph)) { + case OSMO_PRIM(OSMO_SCU_PRIM_N_CONNECT, PRIM_OP_INDICATION): + printf("%s: refusing N-CONNECT.ind (local_ref=%u)\n", + __func__, scu_prim->u.connect.conn_id); + osmo_sccp_tx_disconn(scu, scu_prim->u.connect.conn_id, + &scu_prim->u.connect.called_addr, + 23); + break; + default: + printf("%s: Unknown primitive %u:%u\n", __func__, + oph->primitive, oph->operation); + break; + } + return 0; +} + +/* a simple SCCP User which accepts all connections and echos back all + * DATA + UNITDATA */ +static int echo_prim_cb(struct osmo_prim_hdr *oph, void *_scu) +{ + struct osmo_sccp_user *scu = _scu; + struct osmo_scu_prim *scu_prim = (struct osmo_scu_prim *) oph; + const uint8_t *data = msgb_l2(oph->msg); + unsigned int data_len = msgb_l2len(oph->msg); + + switch (OSMO_PRIM_HDR(&scu_prim->oph)) { + case OSMO_PRIM(OSMO_SCU_PRIM_N_CONNECT, PRIM_OP_INDICATION): + printf("%s: Accepting N-CONNECT.ind (local_ref=%u)\n", + __func__, scu_prim->u.connect.conn_id); + osmo_sccp_tx_conn_resp(scu, scu_prim->u.connect.conn_id, + &scu_prim->u.connect.called_addr, + data, data_len); + break; + case OSMO_PRIM(OSMO_SCU_PRIM_N_DATA, PRIM_OP_INDICATION): + printf("%s: Echoing N-DATA.ind (local_ref=%u)\n", + __func__, scu_prim->u.data.conn_id); + osmo_sccp_tx_data(scu, scu_prim->u.data.conn_id, + data, data_len); + break; + case OSMO_PRIM(OSMO_SCU_PRIM_N_UNITDATA, PRIM_OP_INDICATION): + printf("%s: Echoing N-UNITDATA.ind\n", __func__); + osmo_sccp_tx_unitdata(scu, &scu_prim->u.unitdata.called_addr, + &scu_prim->u.unitdata.calling_addr, + data, data_len); + break; + default: + printf("%s: Unknown primitive %u:%u\n", __func__, + oph->primitive, oph->operation); + break; + } + return 0; +} + +/* a simple SCCP User which receives UNITDATA messages and connects back + * to whoever sents UNITDATA and then echo's back all DATA */ +static int callback_prim_cb(struct osmo_prim_hdr *oph, void *_scu) +{ + struct osmo_sccp_user *scu = _scu; + struct osmo_scu_prim *scu_prim = (struct osmo_scu_prim *) oph; + const uint8_t *data = msgb_l2(oph->msg); + unsigned int data_len = msgb_l2len(oph->msg); + + switch (OSMO_PRIM_HDR(&scu_prim->oph)) { + case OSMO_PRIM(OSMO_SCU_PRIM_N_UNITDATA, PRIM_OP_INDICATION): + printf("%s: N-UNITDATA.ind: Connectiong back to sender\n", __func__); + osmo_sccp_tx_conn_req(scu, conn_id++, + &scu_prim->u.unitdata.called_addr, + &scu_prim->u.unitdata.calling_addr, + data, data_len); + break; + case OSMO_PRIM(OSMO_SCU_PRIM_N_DATA, PRIM_OP_INDICATION): + printf("%s: Echoing N-DATA.ind (local_ref=%u)\n", + __func__, scu_prim->u.data.conn_id); + osmo_sccp_tx_data(scu, scu_prim->u.data.conn_id, + data, data_len); + break; + default: + printf("%s: Unknown primitive %u:%u\n", __func__, + oph->primitive, oph->operation); + break; + } + return 0; +} + +int sccp_test_server_init(struct osmo_sccp_instance *sccp) +{ + osmo_sccp_user_bind(sccp, "refuser", &refuser_prim_cb, SSN_TEST_REFUSE); + osmo_sccp_user_bind(sccp, "echo", &echo_prim_cb, SSN_TEST_ECHO); + osmo_sccp_user_bind(sccp, "callback", &callback_prim_cb, SSN_TEST_CALLBACK); + + return 0; +} diff --git a/examples/sccp_test_vty.c b/examples/sccp_test_vty.c new file mode 100644 index 0000000..1134d57 --- /dev/null +++ b/examples/sccp_test_vty.c @@ -0,0 +1,152 @@ + +#include + +#include +#include + +#include +#include + +#include "internal.h" + +#define SCU_NODE 23 + +static struct osmo_sccp_user *g_scu; + +static struct osmo_sccp_addr g_calling_addr = { + .presence = OSMO_SCCP_ADDR_T_SSN | OSMO_SCCP_ADDR_T_PC, + .ri = OSMO_SCCP_RI_SSN_PC, + .pc = 23, +}; + +static struct osmo_sccp_addr g_called_addr = { + .presence = OSMO_SCCP_ADDR_T_SSN | OSMO_SCCP_ADDR_T_PC, + .ssn = 1, + .ri = OSMO_SCCP_RI_SSN_PC, + .pc = 1, +}; + +DEFUN(scu_called_ssn, scu_called_ssn_cmd, + "called-addr-ssn <0-255>", + "Set SSN of SCCP CalledAddress\n" + "SSN of SCCP CalledAddress\n") +{ + g_called_addr.ssn = atoi(argv[0]); + return CMD_SUCCESS; +} + +DEFUN(scu_conn_req, scu_conn_req_cmd, + "connect-req <0-16777216> [DATA]", + "N-CONNECT.req\n" + "Connection ID\n") +{ + struct osmo_sccp_user *scu = vty->index; + int conn_id = atoi(argv[0]); + const char *data = argv[1]; + + osmo_sccp_tx_conn_req(scu, conn_id, &g_calling_addr, &g_called_addr, + (const uint8_t *)data, data ? strlen(data)+1 : 0); + return CMD_SUCCESS; +} + +DEFUN(scu_conn_resp, scu_conn_resp_cmd, + "connect-resp <0-16777216> [DATA]", + "N-CONNET.resp\n" + "Connection ID\n") +{ + struct osmo_sccp_user *scu = vty->index; + int conn_id = atoi(argv[0]); + const char *data = argv[1]; + + osmo_sccp_tx_conn_resp(scu, conn_id, NULL, + (const uint8_t *)data, data ? strlen(data)+1 : 0); + return CMD_SUCCESS; +} + +DEFUN(scu_data_req, scu_data_req_cmd, + "data-req <0-16777216> DATA", + "N-DATA.req\n" + "Connection ID\n") +{ + struct osmo_sccp_user *scu = vty->index; + int conn_id = atoi(argv[0]); + const char *data = argv[1]; + + osmo_sccp_tx_data(scu, conn_id, (const uint8_t *)data, strlen(data)+1); + return CMD_SUCCESS; +} + +DEFUN(scu_unitdata_req, scu_unitdata_req_cmd, + "unitdata-req DATA", + "N-UNITDATA.req\n") +{ + struct osmo_sccp_user *scu = vty->index; + const char *data = argv[0]; + + osmo_sccp_tx_unitdata(scu, &g_calling_addr, &g_called_addr, + (const uint8_t *)data, strlen(data)+1); + return CMD_SUCCESS; +} + +DEFUN(scu_disc_req, scu_disc_req_cmd, + "disconnect-req <0-16777216>", + "N-DISCONNT.req\n" + "Connection ID\n") +{ + struct osmo_sccp_user *scu = vty->index; + int conn_id = atoi(argv[0]); + + osmo_sccp_tx_disconn(scu, conn_id, NULL, 42); + return CMD_SUCCESS; +} + +static struct cmd_node scu_node = { + SCU_NODE, + "%s(sccp-user)# ", + 1, +}; + +DEFUN(scu, scu_cmd, + "sccp-user", + "Enter SCCP User Node\n") +{ + vty->node = SCU_NODE; + vty->index = g_scu; + return CMD_SUCCESS; +} + +static int testclnt_prim_cb(struct osmo_prim_hdr *oph, void *_scu) +{ + struct osmo_sccp_user *scu = _scu; + struct osmo_scu_prim *scu_prim = (struct osmo_scu_prim *) oph; + + switch (OSMO_PRIM_HDR(&scu_prim->oph)) { + case OSMO_PRIM(OSMO_SCU_PRIM_N_CONNECT, PRIM_OP_INDICATION): + default: + break; + } + return 0; +} + + +int sccp_test_user_vty_install(struct osmo_sccp_instance *inst, int ssn) +{ + g_scu = osmo_sccp_user_bind(inst, "test_client_vty", testclnt_prim_cb, ssn); + if (!g_scu) + return -1; + + g_calling_addr.ssn = ssn; + + install_node(&scu_node, NULL); + vty_install_default(SCU_NODE); + install_element(SCU_NODE, &scu_called_ssn_cmd); + install_element(SCU_NODE, &scu_conn_req_cmd); + install_element(SCU_NODE, &scu_conn_resp_cmd); + install_element(SCU_NODE, &scu_data_req_cmd); + install_element(SCU_NODE, &scu_unitdata_req_cmd); + install_element(SCU_NODE, &scu_disc_req_cmd); + + install_element(ENABLE_NODE, &scu_cmd); + + return 0; +} -- To view, visit https://gerrit.osmocom.org/2219 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Id698ce2da5726e304dfa1773b794671dc80d853c Gerrit-PatchSet: 7 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Apr 10 11:26:52 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 11:26:52 +0000 Subject: [MERGED] libosmo-sccp[master]: xua_as_fsm: Include routing context (if configured) in NTFY ... In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: xua_as_fsm: Include routing context (if configured) in NTFY message ...................................................................... xua_as_fsm: Include routing context (if configured) in NTFY message Change-Id: I15e8bf5cee194f9924d0eab9cff0e7c25daa6dde --- M src/xua_as_fsm.c 1 file changed, 9 insertions(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/xua_as_fsm.c b/src/xua_as_fsm.c index 887a9ec..d73f793 100644 --- a/src/xua_as_fsm.c +++ b/src/xua_as_fsm.c @@ -149,6 +149,7 @@ static void xua_as_fsm_onenter(struct osmo_fsm_inst *fi, uint32_t old_state) { struct xua_as_fsm_priv *xafp = (struct xua_as_fsm_priv *) fi->priv; + struct osmo_ss7_as *as = xafp->as; struct m3ua_notify_params npar = { .status_type = M3UA_NOTIFY_T_STATCHG, }; @@ -167,6 +168,14 @@ return; } + /* Add the routing context, if it is configured */ + if (as->cfg.routing_key.context) { + npar.presence |= NOTIFY_PAR_P_ROUTE_CTX; + npar.route_ctx = as->cfg.routing_key.context; + } + + /* TODO: ASP-Id of ASP triggering this state change */ + asp_notify_all_as(xafp->as, &npar); }; -- To view, visit https://gerrit.osmocom.org/2239 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I15e8bf5cee194f9924d0eab9cff0e7c25daa6dde Gerrit-PatchSet: 5 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Apr 10 11:26:52 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 11:26:52 +0000 Subject: [MERGED] libosmo-sccp[master]: xua_asp_fsm: Always return BEAT-ACK for BEAT, including BEAT... In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: xua_asp_fsm: Always return BEAT-ACK for BEAT, including BEAT DATA IE ...................................................................... xua_asp_fsm: Always return BEAT-ACK for BEAT, including BEAT DATA IE The RFCs say we *must* always respond to the optional heartbeat message, and we must return a verbatim copy of the heartbeat data IE. This was discovered (and fix validated) using m3ua-sgp-asptm-v-011 of Michael Tuexen's m3ua-testtool. Change-Id: I836e0940a8dbb0f55ddf132202a5f0d51473b82d --- M src/xua_asp_fsm.c 1 file changed, 23 insertions(+), 11 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/xua_asp_fsm.c b/src/xua_asp_fsm.c index 80faeb2..aafc09f 100644 --- a/src/xua_asp_fsm.c +++ b/src/xua_asp_fsm.c @@ -128,7 +128,7 @@ } /* ask the xUA implementation to transmit a specific message */ -static int peer_send(struct osmo_fsm_inst *fi, int out_event) +static int peer_send(struct osmo_fsm_inst *fi, int out_event, struct xua_msg *in) { struct xua_asp_fsm_priv *xafp = fi->priv; struct osmo_ss7_asp *asp = xafp->asp; @@ -168,6 +168,7 @@ /* RFC3868 Ch. 3.5.6 */ xua->hdr = XUA_HDR(SUA_MSGC_ASPSM, SUA_ASPSM_BEAT_ACK); /* Optional: Heartbeat Data */ + xua_msg_copy_part(xua, M3UA_IEI_HEARDBT_DATA, in, M3UA_IEI_HEARDBT_DATA); break; case XUA_ASP_E_ASPTM_ASPAC: /* RFC3868 Ch. 3.6.1 */ @@ -217,7 +218,7 @@ osmo_fsm_event_name(fi->fsm, xafp->t_ack.out_event)); /* Re-transmit message */ - peer_send(fi, xafp->t_ack.out_event); + peer_send(fi, xafp->t_ack.out_event, NULL); /* Re-start the timer */ osmo_timer_schedule(&xafp->t_ack.timer, XUA_T_ACK_SEC, 0); @@ -229,7 +230,7 @@ struct xua_asp_fsm_priv *xafp = fi->priv; int rc; - rc = peer_send(fi, out_event); + rc = peer_send(fi, out_event, NULL); if (rc < 0) return rc; @@ -328,7 +329,7 @@ asp->asp_id_present = true; } /* send ACK */ - peer_send(fi, XUA_ASP_E_ASPSM_ASPUP_ACK); + peer_send(fi, XUA_ASP_E_ASPSM_ASPUP_ACK, NULL); /* transition state and inform layer manager */ osmo_fsm_inst_state_chg(fi, XUA_ASP_S_INACTIVE, 0, 0); send_xlm_prim_simple(fi, OSMO_XLM_PRIM_M_ASP_UP, @@ -340,7 +341,7 @@ /* The SGP MUST send an ASP Down Ack message in response * to a received ASP Down message from the ASP even if * the ASP is already marked as ASP-DOWN at the SGP. */ - peer_send(fi, XUA_ASP_E_ASPSM_ASPDN_ACK); + peer_send(fi, XUA_ASP_E_ASPSM_ASPDN_ACK, NULL); break; } } @@ -401,7 +402,7 @@ /* only in role SG */ ENSURE_SG_OR_IPSP(fi, event); /* send ACK */ - peer_send(fi, XUA_ASP_E_ASPTM_ASPAC_ACK); + peer_send(fi, XUA_ASP_E_ASPTM_ASPAC_ACK, NULL); /* transition state and inform layer manager */ osmo_fsm_inst_state_chg(fi, XUA_ASP_S_ACTIVE, 0, 0); send_xlm_prim_simple(fi, OSMO_XLM_PRIM_M_ASP_ACTIVE, @@ -411,7 +412,7 @@ /* only in role SG */ ENSURE_SG_OR_IPSP(fi, event); /* send ACK */ - peer_send(fi, XUA_ASP_E_ASPSM_ASPDN_ACK); + peer_send(fi, XUA_ASP_E_ASPSM_ASPDN_ACK, NULL); /* transition state and inform layer manager */ osmo_fsm_inst_state_chg(fi, XUA_ASP_S_DOWN, 0, 0); send_xlm_prim_simple(fi, OSMO_XLM_PRIM_M_ASP_DOWN, @@ -424,7 +425,7 @@ * remote ASP is already in the ASP-INACTIVE state, an * ASP Up Ack message is returned and no further action * is taken. */ - peer_send(fi, XUA_ASP_E_ASPSM_ASPUP_ACK); + peer_send(fi, XUA_ASP_E_ASPSM_ASPUP_ACK, NULL); break; } } @@ -470,7 +471,7 @@ /* only in role SG */ ENSURE_SG_OR_IPSP(fi, event); /* send ACK */ - peer_send(fi, XUA_ASP_E_ASPTM_ASPIA_ACK); + peer_send(fi, XUA_ASP_E_ASPTM_ASPIA_ACK, NULL); /* transition state and inform layer manager */ osmo_fsm_inst_state_chg(fi, XUA_ASP_S_INACTIVE, 0, 0); send_xlm_prim_simple(fi, OSMO_XLM_PRIM_M_ASP_INACTIVE, @@ -480,7 +481,7 @@ /* only in role SG */ ENSURE_SG_OR_IPSP(fi, event); /* send ACK */ - peer_send(fi, XUA_ASP_E_ASPSM_ASPDN_ACK); + peer_send(fi, XUA_ASP_E_ASPSM_ASPDN_ACK, NULL); /* transition state and inform layer manager */ osmo_fsm_inst_state_chg(fi, XUA_ASP_S_DOWN, 0, 0); send_xlm_prim_simple(fi, OSMO_XLM_PRIM_M_ASP_DOWN, @@ -508,12 +509,21 @@ static void xua_asp_allstate(struct osmo_fsm_inst *fi, uint32_t event, void *data) { + struct xua_msg *xua; + switch (event) { case XUA_ASP_E_SCTP_COMM_DOWN_IND: case XUA_ASP_E_SCTP_RESTART_IND: osmo_fsm_inst_state_chg(fi, XUA_ASP_S_DOWN, 0, 0); send_xlm_prim_simple(fi, OSMO_XLM_PRIM_M_ASP_DOWN, PRIM_OP_INDICATION); + break; + case XUA_ASP_E_ASPSM_BEAT: + xua = data; + peer_send(fi, XUA_ASP_E_ASPSM_BEAT_ACK, xua); + break; + case XUA_ASP_E_ASPSM_BEAT_ACK: + /* FIXME: stop timer, if any */ break; default: break; @@ -577,7 +587,9 @@ .log_subsys = DLSS7, .event_names = xua_asp_event_names, .allstate_event_mask = S(XUA_ASP_E_SCTP_COMM_DOWN_IND) | - S(XUA_ASP_E_SCTP_RESTART_IND), + S(XUA_ASP_E_SCTP_RESTART_IND) | + S(XUA_ASP_E_ASPSM_BEAT) | + S(XUA_ASP_E_ASPSM_BEAT_ACK), .allstate_action = xua_asp_allstate, }; -- To view, visit https://gerrit.osmocom.org/2238 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I836e0940a8dbb0f55ddf132202a5f0d51473b82d Gerrit-PatchSet: 5 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Apr 10 11:26:52 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 11:26:52 +0000 Subject: [MERGED] libosmo-sccp[master]: osmo_ss7: make OVERRIDE the default traffic mode type (0) In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: osmo_ss7: make OVERRIDE the default traffic mode type (0) ...................................................................... osmo_ss7: make OVERRIDE the default traffic mode type (0) Change-Id: Ie83fa0a403dcfc582d6bb59ec08d6a719d2f6398 --- M include/osmocom/sigtran/osmo_ss7.h 1 file changed, 1 insertion(+), 1 deletion(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/include/osmocom/sigtran/osmo_ss7.h b/include/osmocom/sigtran/osmo_ss7.h index 5bbcd65..7918a51 100644 --- a/include/osmocom/sigtran/osmo_ss7.h +++ b/include/osmocom/sigtran/osmo_ss7.h @@ -229,10 +229,10 @@ }; enum osmo_ss7_as_traffic_mode { + OSMO_SS7_AS_TMOD_OVERRIDE = 0, /* default */ OSMO_SS7_AS_TMOD_BCAST, OSMO_SS7_AS_TMOD_LOADSHARE, OSMO_SS7_AS_TMOD_ROUNDROBIN, - OSMO_SS7_AS_TMOD_OVERRIDE, _NUM_OSMO_SS7_ASP_TMOD }; -- To view, visit https://gerrit.osmocom.org/2235 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ie83fa0a403dcfc582d6bb59ec08d6a719d2f6398 Gerrit-PatchSet: 5 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Apr 10 11:26:53 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 11:26:53 +0000 Subject: [MERGED] libosmo-sccp[master]: add converter functions between osmo_ss7 and m3ua traffic mo... In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: add converter functions between osmo_ss7 and m3ua traffic mode types ...................................................................... add converter functions between osmo_ss7 and m3ua traffic mode types Change-Id: I6cc9530d7d2812cbc8feb6e9db51902865ebfe83 --- M include/osmocom/sigtran/osmo_ss7.h M include/osmocom/sigtran/protocol/m3ua.h M src/osmo_ss7.c 3 files changed, 36 insertions(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/include/osmocom/sigtran/osmo_ss7.h b/include/osmocom/sigtran/osmo_ss7.h index 7918a51..d765ae0 100644 --- a/include/osmocom/sigtran/osmo_ss7.h +++ b/include/osmocom/sigtran/osmo_ss7.h @@ -406,3 +406,6 @@ const char *name, uint32_t pc, int local_port, int remote_port, const char *remote_ip); + +enum osmo_ss7_as_traffic_mode osmo_ss7_tmode_from_xua(uint32_t in); +int osmo_ss7_tmode_to_xua(enum osmo_ss7_as_traffic_mode tmod); diff --git a/include/osmocom/sigtran/protocol/m3ua.h b/include/osmocom/sigtran/protocol/m3ua.h index 43d18c5..835e73e 100644 --- a/include/osmocom/sigtran/protocol/m3ua.h +++ b/include/osmocom/sigtran/protocol/m3ua.h @@ -145,3 +145,9 @@ M3UA_ERR_INVAL_ROUT_CTX = 0x19, M3UA_ERR_NO_CONFGD_AS_FOR_ASP = 0x1a, }; + +enum m3ua_traffic_mode { + M3UA_TMOD_OVERRIDE = 1, + M3UA_TMOD_LOADSHARE = 2, + M3UA_TMOD_BCAST = 3, +}; diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index ab0636c..2dbb94d 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -1494,3 +1494,30 @@ ss7_initialized = true; return 0; } + +int osmo_ss7_tmode_to_xua(enum osmo_ss7_as_traffic_mode tmod) +{ + switch (tmod) { + case OSMO_SS7_AS_TMOD_OVERRIDE: + return M3UA_TMOD_OVERRIDE; + case OSMO_SS7_AS_TMOD_LOADSHARE: + return M3UA_TMOD_LOADSHARE; + case OSMO_SS7_AS_TMOD_BCAST: + return M3UA_TMOD_BCAST; + default: + return -1; + } +} + +enum osmo_ss7_as_traffic_mode osmo_ss7_tmode_from_xua(uint32_t in) +{ + switch (in) { + case M3UA_TMOD_OVERRIDE: + default: + return OSMO_SS7_AS_TMOD_OVERRIDE; + case M3UA_TMOD_LOADSHARE: + return OSMO_SS7_AS_TMOD_LOADSHARE; + case M3UA_TMOD_BCAST: + return OSMO_SS7_AS_TMOD_BCAST; + } +} -- To view, visit https://gerrit.osmocom.org/2236 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I6cc9530d7d2812cbc8feb6e9db51902865ebfe83 Gerrit-PatchSet: 5 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Apr 10 11:26:53 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 11:26:53 +0000 Subject: [MERGED] libosmo-sccp[master]: m3ua: Include RC IE of AS in Tx; validate RC IE on Rx In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: m3ua: Include RC IE of AS in Tx; validate RC IE on Rx ...................................................................... m3ua: Include RC IE of AS in Tx; validate RC IE on Rx Change-Id: I7db36a23185f82d8d68e318afe89ec5127c40333 --- M src/m3ua.c 1 file changed, 26 insertions(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/m3ua.c b/src/m3ua.c index 8ec82c5..7437b6e 100644 --- a/src/m3ua.c +++ b/src/m3ua.c @@ -448,6 +448,10 @@ OSMO_ASSERT(as->cfg.proto == OSMO_SS7_ASP_PROT_M3UA); + /* Add RC for this AS */ + if (as->cfg.routing_key.context) + xua_msg_add_u32(xua, M3UA_IEI_ROUTE_CTX, as->cfg.routing_key.context); + for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) { asp = as->cfg.asps[i]; if (!asp) @@ -488,7 +492,24 @@ static int m3ua_rx_xfer(struct osmo_ss7_asp *asp, struct xua_msg *xua) { + uint32_t rctx = xua_msg_get_u32(xua, M3UA_IEI_ROUTE_CTX); struct m3ua_data_hdr *dh; + struct xua_msg *err = NULL; + struct osmo_ss7_as *as; + + /* Use routing context IE to look up the AS for which the + * message was received. */ + as = osmo_ss7_as_find_by_rctx(asp->inst, rctx); + if (!as) { + err = m3ua_gen_error(M3UA_ERR_INVAL_ROUT_CTX); + goto out_err; + } + /* Verify that this ASP ix part of the AS. */ + if (!osmo_ss7_as_has_asp(as, asp)) { + err = m3ua_gen_error(M3UA_ERR_NO_CONFGD_AS_FOR_ASP); + goto out_err; + } + /* FIXME: check for AS state == ACTIVE */ /* store the MTP-level information in the xua_msg for use by * higher layer protocols */ @@ -497,6 +518,11 @@ m3ua_dh_to_xfer_param(&xua->mtp, dh); return m3ua_hmdc_rx_from_l2(asp->inst, xua); +out_err: + if (err) + m3ua_tx_xua_asp(asp, err); + + return -1; } static int m3ua_rx_mgmt_err(struct osmo_ss7_asp *asp, struct xua_msg *xua) -- To view, visit https://gerrit.osmocom.org/2237 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I7db36a23185f82d8d68e318afe89ec5127c40333 Gerrit-PatchSet: 5 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Apr 10 11:26:53 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 11:26:53 +0000 Subject: [MERGED] libosmo-sccp[master]: sccp: add osmo_sccp_user_{get, set}_priv() API function In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: sccp: add osmo_sccp_user_{get,set}_priv() API function ...................................................................... sccp: add osmo_sccp_user_{get,set}_priv() API function As 'struct osmo_sccp_user' is private, we need this accessor functions for the SCCP User so it can set and get the 'priv' data. Change-Id: Ia68a36dc18a7d754d63ae29c86d68e495b5c4134 --- M include/osmocom/sigtran/sccp_sap.h M src/sccp_user.c 2 files changed, 12 insertions(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/include/osmocom/sigtran/sccp_sap.h b/include/osmocom/sigtran/sccp_sap.h index c1464f0..a86f86a 100644 --- a/include/osmocom/sigtran/sccp_sap.h +++ b/include/osmocom/sigtran/sccp_sap.h @@ -232,6 +232,8 @@ void osmo_sccp_instance_destroy(struct osmo_sccp_instance *inst); void osmo_sccp_user_unbind(struct osmo_sccp_user *scu); +void osmo_sccp_user_set_priv(struct osmo_sccp_user *scu, void *priv); +void *osmo_sccp_user_get_priv(struct osmo_sccp_user *scu); struct osmo_sccp_user * osmo_sccp_user_bind_pc(struct osmo_sccp_instance *inst, const char *name, diff --git a/src/sccp_user.c b/src/sccp_user.c index df02486..bc03f4e 100644 --- a/src/sccp_user.c +++ b/src/sccp_user.c @@ -130,6 +130,16 @@ talloc_free(scu); } +void osmo_sccp_user_set_priv(struct osmo_sccp_user *scu, void *priv) +{ + scu->priv = priv; +} + +void *osmo_sccp_user_get_priv(struct osmo_sccp_user *scu) +{ + return scu->priv; +} + /*! \brief Send a SCCP User SAP Primitive up to the User * \param[in] scu SCCP User to whom to send the primitive * \param[in] prim Primitive to send to the user -- To view, visit https://gerrit.osmocom.org/2234 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ia68a36dc18a7d754d63ae29c86d68e495b5c4134 Gerrit-PatchSet: 5 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Apr 10 11:26:54 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 11:26:54 +0000 Subject: [MERGED] libosmo-sccp[master]: M3UA: RKM DEREG-REQ should contain routing context, not rout... In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: M3UA: RKM DEREG-REQ should contain routing context, not routing key ...................................................................... M3UA: RKM DEREG-REQ should contain routing context, not routing key The mandatory IE checking is requiring the wrong IE Change-Id: I73ecd163e2143341687ee4bca15a0bc69719c594 --- M src/m3ua.c 1 file changed, 1 insertion(+), 1 deletion(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/m3ua.c b/src/m3ua.c index 5708985..031e5cd 100644 --- a/src/m3ua.c +++ b/src/m3ua.c @@ -241,7 +241,7 @@ M3UA_IEI_REG_RESULT, 0 }; static const uint16_t dereg_req_ies[] = { - M3UA_IEI_ROUT_KEY, 0 + M3UA_IEI_ROUTE_CTX, 0 }; static const uint16_t dereg_rsp_ies[] = { M3UA_IEI_DEREG_RESULT, 0 -- To view, visit https://gerrit.osmocom.org/2280 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I73ecd163e2143341687ee4bca15a0bc69719c594 Gerrit-PatchSet: 4 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Apr 10 11:26:54 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 11:26:54 +0000 Subject: [MERGED] libosmo-sccp[master]: xua_msg: Add xua_from_nested() helper function for nested IEs In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: xua_msg: Add xua_from_nested() helper function for nested IEs ...................................................................... xua_msg: Add xua_from_nested() helper function for nested IEs ... and add a test case to ensure it continues to work. Change-Id: Iee434886598b528d23ddce0490dcc782e0f5d6ae --- M include/osmocom/sigtran/xua_msg.h M src/xua_msg.c M tests/xua/xua_test.c M tests/xua/xua_test.ok 4 files changed, 86 insertions(+), 21 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/include/osmocom/sigtran/xua_msg.h b/include/osmocom/sigtran/xua_msg.h index e0e1bcf..423adbc 100644 --- a/include/osmocom/sigtran/xua_msg.h +++ b/include/osmocom/sigtran/xua_msg.h @@ -82,6 +82,8 @@ struct xua_msg *xua_from_msg(const int version, uint16_t len, uint8_t *data); struct msgb *xua_to_msg(const int version, struct xua_msg *msg); +struct xua_msg *xua_from_nested(struct xua_msg_part *outer); + int msgb_t16l16vp_put(struct msgb *msg, uint16_t tag, uint16_t len, const uint8_t *data); int msgb_t16l16vp_put_u32(struct msgb *msg, uint16_t tag, uint32_t val); int xua_msg_add_u32(struct xua_msg *xua, uint16_t iei, uint32_t val); diff --git a/src/xua_msg.c b/src/xua_msg.c index cb487c8..05430a4 100644 --- a/src/xua_msg.c +++ b/src/xua_msg.c @@ -112,12 +112,39 @@ return xua_msg_add_data(xua_out, tag_out, part->len, part->dat); } -struct xua_msg *xua_from_msg(const int version, uint16_t len, uint8_t *data) +static int xua_from_msg_common(struct xua_msg *msg, const uint8_t *data, uint16_t pos, uint16_t len) { struct xua_parameter_hdr *par; + uint16_t par_len, padding; + int rc; + + while (pos + sizeof(*par) < len) { + par = (struct xua_parameter_hdr *) &data[pos]; + par_len = ntohs(par->len); + + if (pos + par_len > len || par_len < 4) + return -1; + + rc = xua_msg_add_data(msg, ntohs(par->tag), + par_len - 4, par->data); + if (rc != 0) + return -1; + + pos += par_len; + + /* move over the padding */ + padding = (4 - (par_len % 4)) & 0x3; + pos += padding; + } + + return 0; +} + +struct xua_msg *xua_from_msg(const int version, uint16_t len, uint8_t *data) +{ struct xua_common_hdr *hdr; struct xua_msg *msg; - uint16_t pos, par_len, padding; + uint16_t pos; int rc; msg = xua_msg_alloc(); @@ -136,31 +163,33 @@ msg->hdr = *hdr; pos = sizeof(*hdr); - while (pos + sizeof(*par) < len) { - par = (struct xua_parameter_hdr *) &data[pos]; - par_len = ntohs(par->len); + rc = xua_from_msg_common(msg, data, pos, len); + if (rc < 0) + goto fail; - if (pos + par_len > len || par_len < 4) - goto fail; - - rc = xua_msg_add_data(msg, ntohs(par->tag), - par_len - 4, par->data); - if (rc != 0) - goto fail; - - pos += par_len; - - /* move over the padding */ - padding = (4 - (par_len % 4)) & 0x3; - pos += padding; - } - - /* TODO: parse */ return msg; fail: xua_msg_free(msg); return NULL; + +} + +struct xua_msg *xua_from_nested(struct xua_msg_part *outer) +{ + struct xua_msg *msg = xua_msg_alloc(); + int rc; + + if (!msg) + return NULL; + + rc = xua_from_msg_common(msg, outer->dat, 0, outer->len); + if (rc < 0) { + xua_msg_free(msg); + return NULL; + } + + return msg; } struct msgb *xua_to_msg(const int version, struct xua_msg *xua) diff --git a/tests/xua/xua_test.c b/tests/xua/xua_test.c index 74d91c4..d1aa564 100644 --- a/tests/xua/xua_test.c +++ b/tests/xua/xua_test.c @@ -1,4 +1,5 @@ /* (C) 2011 by Holger Hans Peter Freyther + * (C) 2017 by Harald Welte * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by @@ -21,6 +22,7 @@ #include #include +#include #include #include @@ -355,6 +357,35 @@ } } +/* M3UA message with RKM-REG contents */ +static const uint8_t rkm_reg[] = { + 0x01, 0x00, 0x09, 0x01, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x04, 0x00, 0x0e, 0x4d, 0x33, 0x55, 0x41, + 0x20, 0x72, 0x6f, 0x63, 0x6b, 0x73, 0x00, 0x00, 0x02, 0x07, 0x00, 0x14, 0x02, 0x0a, 0x00, 0x08, + 0x00, 0x00, 0x00, 0x01, 0x02, 0x0b, 0x00, 0x08, 0x00, 0x00, 0x00, 0x17, +}; + +static void test_rkm(void) +{ + struct xua_msg *xua, *nested; + struct xua_msg_part *rkey; + + printf("Parsing M3UA Message\n"); + xua = xua_from_msg(M3UA_VERSION, sizeof(rkm_reg), (uint8_t *)rkm_reg); + OSMO_ASSERT(xua); + OSMO_ASSERT(xua->hdr.msg_class == M3UA_MSGC_RKM); + OSMO_ASSERT(xua->hdr.msg_type == M3UA_RKM_REG_REQ); + OSMO_ASSERT(xua_msg_find_tag(xua, M3UA_IEI_INFO_STRING)); + rkey = xua_msg_find_tag(xua, M3UA_IEI_ROUT_KEY); + OSMO_ASSERT(rkey); + OSMO_ASSERT(rkey->len == 16); + + printf("Parsing Nested M3UA Routing Key IE\n"); + nested = xua_from_nested(rkey); + OSMO_ASSERT(nested); + OSMO_ASSERT(xua_msg_get_u32(nested, M3UA_IEI_LOC_RKEY_ID) == 1); + OSMO_ASSERT(xua_msg_get_u32(nested, M3UA_IEI_DEST_PC) == 23); +} + static const struct log_info_cat default_categories[] = { [0] = { @@ -380,6 +411,7 @@ test_sccp_addr_parser(); test_helpers(); test_sccp2sua(); + test_rkm(); printf("All tests passed.\n"); return 0; diff --git a/tests/xua/xua_test.ok b/tests/xua/xua_test.ok index a9fba1d..2184902 100644 --- a/tests/xua/xua_test.ok +++ b/tests/xua/xua_test.ok @@ -128,4 +128,6 @@ PART(T=Data,L=154,D=6581974804260001984904510103df6c8188a181850201440201073080a780a08004012b30803012830110840107850791445776671697860120300682011884010400000000a306040142840105a306040151840105a306040131840105a309040112840105820102a309040111840105810101a306040114840100a30b0401418401043003830110a30b040141840104300382011800000000) Re-Encoding decoded SUA to SCCP SCCP Output: 09 81 03 0d 18 0a 12 07 00 12 04 53 84 09 00 17 0b 12 06 00 12 04 44 87 20 00 20 65 9a 65 81 97 48 04 26 00 01 98 49 04 51 01 03 df 6c 81 88 a1 81 85 02 01 44 02 01 07 30 80 a7 80 a0 80 04 01 2b 30 80 30 12 83 01 10 84 01 07 85 07 91 44 57 76 67 16 97 86 01 20 30 06 82 01 18 84 01 04 00 00 00 00 a3 06 04 01 42 84 01 05 a3 06 04 01 51 84 01 05 a3 06 04 01 31 84 01 05 a3 09 04 01 12 84 01 05 82 01 02 a3 09 04 01 11 84 01 05 81 01 01 a3 06 04 01 14 84 01 00 a3 0b 04 01 41 84 01 04 30 03 83 01 10 a3 0b 04 01 41 84 01 04 30 03 82 01 18 00 00 00 00 +Parsing M3UA Message +Parsing Nested M3UA Routing Key IE All tests passed. -- To view, visit https://gerrit.osmocom.org/2279 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Iee434886598b528d23ddce0490dcc782e0f5d6ae Gerrit-PatchSet: 4 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Apr 10 11:26:54 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 11:26:54 +0000 Subject: [MERGED] libosmo-sccp[master]: m3ua: cosmetic clanup. We can simply return the M3UA errror... In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: m3ua: cosmetic clanup. We can simply return the M3UA errror code ...................................................................... m3ua: cosmetic clanup. We can simply return the M3UA errror code Change-Id: I6ed04a4f78e618938484aeab62dbcfb3f310998d --- M src/m3ua.c 1 file changed, 6 insertions(+), 15 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/m3ua.c b/src/m3ua.c index 9a56ff9..7dc2afb 100644 --- a/src/m3ua.c +++ b/src/m3ua.c @@ -496,7 +496,6 @@ { uint32_t rctx = xua_msg_get_u32(xua, M3UA_IEI_ROUTE_CTX); struct m3ua_data_hdr *dh; - struct xua_msg *err = NULL; struct osmo_ss7_as *as; if (xua->hdr.msg_type != M3UA_XFER_DATA) @@ -505,15 +504,13 @@ /* Use routing context IE to look up the AS for which the * message was received. */ as = osmo_ss7_as_find_by_rctx(asp->inst, rctx); - if (!as) { - err = m3ua_gen_error(M3UA_ERR_INVAL_ROUT_CTX); - goto out_err; - } + if (!as) + return M3UA_ERR_INVAL_ROUT_CTX; + /* Verify that this ASP ix part of the AS. */ - if (!osmo_ss7_as_has_asp(as, asp)) { - err = m3ua_gen_error(M3UA_ERR_NO_CONFGD_AS_FOR_ASP); - goto out_err; - } + if (!osmo_ss7_as_has_asp(as, asp)) + return M3UA_ERR_NO_CONFGD_AS_FOR_ASP; + /* FIXME: check for AS state == ACTIVE */ /* store the MTP-level information in the xua_msg for use by @@ -527,11 +524,6 @@ xua_msg_free_tag(xua, M3UA_IEI_ROUTE_CTX); return m3ua_hmdc_rx_from_l2(asp->inst, xua); -out_err: - if (err) - m3ua_tx_xua_asp(asp, err); - - return -1; } static int m3ua_rx_mgmt_err(struct osmo_ss7_asp *asp, struct xua_msg *xua) @@ -688,7 +680,6 @@ case M3UA_MSGC_ASPSM: case M3UA_MSGC_ASPTM: rc = m3ua_rx_asp(asp, xua); - break; break; case M3UA_MSGC_MGMT: rc = m3ua_rx_mgmt(asp, xua); -- To view, visit https://gerrit.osmocom.org/2277 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I6ed04a4f78e618938484aeab62dbcfb3f310998d Gerrit-PatchSet: 6 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Apr 10 11:26:55 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 11:26:55 +0000 Subject: [MERGED] libosmo-sccp[master]: M3UA: Reject Message Class XFER / Type != DATA In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: M3UA: Reject Message Class XFER / Type != DATA ...................................................................... M3UA: Reject Message Class XFER / Type != DATA This was discovered (and fix validated) using m3ua-sgp-mtr-i-003 of Michael Tuexen's m3ua-testtol. Change-Id: I7498f606b031f5a6dfb538d9900c744da6aed36f --- M src/m3ua.c 1 file changed, 3 insertions(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/m3ua.c b/src/m3ua.c index c29ed00..9a56ff9 100644 --- a/src/m3ua.c +++ b/src/m3ua.c @@ -499,6 +499,9 @@ struct xua_msg *err = NULL; struct osmo_ss7_as *as; + if (xua->hdr.msg_type != M3UA_XFER_DATA) + return M3UA_ERR_UNSUPP_MSG_TYPE; + /* Use routing context IE to look up the AS for which the * message was received. */ as = osmo_ss7_as_find_by_rctx(asp->inst, rctx); -- To view, visit https://gerrit.osmocom.org/2276 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I7498f606b031f5a6dfb538d9900c744da6aed36f Gerrit-PatchSet: 6 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Apr 10 11:26:55 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 11:26:55 +0000 Subject: [MERGED] libosmo-sccp[master]: M3UA: Ensure XFER messages are not sent on stream 0 In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: M3UA: Ensure XFER messages are not sent on stream 0 ...................................................................... M3UA: Ensure XFER messages are not sent on stream 0 According to the RFC, Stream ID 0 MUST not be used for XFER/DATA messages. This was discovered (and fix validated) using m3ua-sgp-mtr-v-003-alternate of Michale Tuexen's m3ua-testtool. Change-Id: I80b941426b5106e091bd1becff0ae97958aff97c --- M src/m3ua.c 1 file changed, 9 insertions(+), 1 deletion(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/m3ua.c b/src/m3ua.c index 14df269..c29ed00 100644 --- a/src/m3ua.c +++ b/src/m3ua.c @@ -432,6 +432,10 @@ return -1; } + if (xua->hdr.msg_class == M3UA_MSGC_XFER) + msgb_sctp_stream(msg) = 1; + else + msgb_sctp_stream(msg) = 0; msgb_sctp_ppid(msg) = M3UA_PPID; return osmo_ss7_asp_send(asp, msg); } @@ -666,12 +670,16 @@ goto out; } - /* TODO: check for SCTP Strema ID */ /* TODO: check if any AS configured in ASP */ /* TODO: check for valid routing context */ switch (xua->hdr.msg_class) { case M3UA_MSGC_XFER: + /* The DATA message MUST NOT be sent on stream 0. */ + if (msgb_sctp_stream(msg) == 0) { + rc = M3UA_ERR_INVAL_STREAM_ID; + break; + } rc = m3ua_rx_xfer(asp, xua); break; case M3UA_MSGC_ASPSM: -- To view, visit https://gerrit.osmocom.org/2275 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I80b941426b5106e091bd1becff0ae97958aff97c Gerrit-PatchSet: 6 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Apr 10 11:26:55 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 11:26:55 +0000 Subject: [MERGED] libosmo-sccp[master]: M3UA: Properly reject invalid/unknown routing context In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: M3UA: Properly reject invalid/unknown routing context ...................................................................... M3UA: Properly reject invalid/unknown routing context This was discovered (and fix validated) using m3ua-sgp-asptm-i-005 of Michael Tuexne's m3ua-testtool. Change-Id: I217ae287e22371e36dda0f87a7737b62fb1bf2d6 --- M src/xua_asp_fsm.c 1 file changed, 9 insertions(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/xua_asp_fsm.c b/src/xua_asp_fsm.c index 9c4a8ca..2830334 100644 --- a/src/xua_asp_fsm.c +++ b/src/xua_asp_fsm.c @@ -392,6 +392,8 @@ static void xua_asp_fsm_inactive(struct osmo_fsm_inst *fi, uint32_t event, void *data) { + struct xua_asp_fsm_priv *xafp = fi->priv; + struct osmo_ss7_asp *asp = xafp->asp; struct xua_msg *xua_in; uint32_t traf_mode; @@ -434,6 +436,13 @@ break; } } + if (xua_msg_find_tag(xua_in, M3UA_IEI_ROUTE_CTX)) { + uint32_t rctx = xua_msg_get_u32(xua_in, M3UA_IEI_ROUTE_CTX); + if (!osmo_ss7_as_find_by_rctx(asp->inst, rctx)) { + peer_send_error(fi, M3UA_ERR_INVAL_ROUT_CTX); + break; + } + } /* send ACK */ peer_send(fi, XUA_ASP_E_ASPTM_ASPAC_ACK, NULL); /* transition state and inform layer manager */ -- To view, visit https://gerrit.osmocom.org/2274 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I217ae287e22371e36dda0f87a7737b62fb1bf2d6 Gerrit-PatchSet: 7 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Apr 10 11:26:55 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 11:26:55 +0000 Subject: [MERGED] libosmo-sccp[master]: M3UA: Send opportunistic ASPACT-ACK to ASPACT-REQ in ACTIVE ... In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: M3UA: Send opportunistic ASPACT-ACK to ASPACT-REQ in ACTIVE state ...................................................................... M3UA: Send opportunistic ASPACT-ACK to ASPACT-REQ in ACTIVE state This was discovered (and fix validated) using m3ua-sgp-asptm-o-001 of Michael Tuexen's m3ua-testtool. Change-Id: I6d254f7a33856e036329aa717a9c03efb1f1289d --- M src/xua_asp_fsm.c 1 file changed, 7 insertions(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/xua_asp_fsm.c b/src/xua_asp_fsm.c index 0996db0..2e80506 100644 --- a/src/xua_asp_fsm.c +++ b/src/xua_asp_fsm.c @@ -532,6 +532,12 @@ PRIM_OP_INDICATION); peer_send_error(fi, M3UA_ERR_UNEXPECTED_MSG); break; + case XUA_ASP_E_ASPTM_ASPAC: + /* only in role SG */ + ENSURE_SG_OR_IPSP(fi, event); + /* send ACK */ + peer_send(fi, XUA_ASP_E_ASPTM_ASPAC_ACK, NULL); + break; } } @@ -601,6 +607,7 @@ S(XUA_ASP_E_ASPSM_ASPUP) | S(XUA_ASP_E_ASPTM_ASPIA) | S(XUA_ASP_E_ASPTM_ASPIA_ACK) | + S(XUA_ASP_E_ASPTM_ASPAC) | S(XUA_ASP_E_M_ASP_DOWN_REQ) | S(XUA_ASP_E_M_ASP_INACTIVE_REQ), .out_state_mask = S(XUA_ASP_S_INACTIVE) | -- To view, visit https://gerrit.osmocom.org/2272 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I6d254f7a33856e036329aa717a9c03efb1f1289d Gerrit-PatchSet: 7 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Apr 10 11:26:56 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 11:26:56 +0000 Subject: [MERGED] libosmo-sccp[master]: M3UA: Handle opportunistic ASPIA in INACTIVE state In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: M3UA: Handle opportunistic ASPIA in INACTIVE state ...................................................................... M3UA: Handle opportunistic ASPIA in INACTIVE state This was discovered (and fix validated) using m3ua-sgp-asptm-o-003 of Michale Tuexen's m3ua-testtool. Change-Id: If231072655170fe52dae738882dd63b1d0a60cf9 --- M src/xua_asp_fsm.c 1 file changed, 6 insertions(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/xua_asp_fsm.c b/src/xua_asp_fsm.c index 2e80506..9c4a8ca 100644 --- a/src/xua_asp_fsm.c +++ b/src/xua_asp_fsm.c @@ -460,6 +460,11 @@ * is taken. */ peer_send(fi, XUA_ASP_E_ASPSM_ASPUP_ACK, NULL); break; + case XUA_ASP_E_ASPTM_ASPIA: + /* only in role SG */ + ENSURE_SG_OR_IPSP(fi, event); + peer_send(fi, XUA_ASP_E_ASPTM_ASPIA_ACK, NULL); + break; } } @@ -592,6 +597,7 @@ S(XUA_ASP_E_M_ASP_DOWN_REQ) | S(XUA_ASP_E_ASPTM_ASPAC) | S(XUA_ASP_E_ASPTM_ASPAC_ACK) | + S(XUA_ASP_E_ASPTM_ASPIA) | S(XUA_ASP_E_ASPSM_ASPDN) | S(XUA_ASP_E_ASPSM_ASPDN_ACK) | S(XUA_ASP_E_ASPSM_ASPUP), -- To view, visit https://gerrit.osmocom.org/2273 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: If231072655170fe52dae738882dd63b1d0a60cf9 Gerrit-PatchSet: 7 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Apr 10 11:26:56 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 11:26:56 +0000 Subject: [MERGED] libosmo-sccp[master]: M3UA: Make sure to reject unsupported traffic mode types In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: M3UA: Make sure to reject unsupported traffic mode types ...................................................................... M3UA: Make sure to reject unsupported traffic mode types This was discovered (and fix validated) using m3ua-sgp-asptm-i-004 of Michael Tuexen's m3ua-testtool. Change-Id: I76c01189b75ff3084cd4d3944314ec9b9f811dbf --- M src/xua_asp_fsm.c 1 file changed, 32 insertions(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/xua_asp_fsm.c b/src/xua_asp_fsm.c index 1570bc9..87f8927 100644 --- a/src/xua_asp_fsm.c +++ b/src/xua_asp_fsm.c @@ -210,6 +210,25 @@ return osmo_ss7_asp_send(asp, msg); } +static int peer_send_error(struct osmo_fsm_inst *fi, uint32_t err_code) +{ + struct xua_asp_fsm_priv *xafp = fi->priv; + struct osmo_ss7_asp *asp = xafp->asp; + struct xua_msg *xua = xua_msg_alloc(); + struct msgb *msg; + + xua->hdr = XUA_HDR(SUA_MSGC_MGMT, SUA_MGMT_ERR); + xua->hdr.version = SUA_VERSION; + xua_msg_add_u32(xua, SUA_IEI_ERR_CODE, err_code); + + msg = xua_to_msg(SUA_VERSION, xua); + xua_msg_free(xua); + if (!msg) + return -1; + + return osmo_ss7_asp_send(asp, msg); +} + static void xua_t_ack_cb(void *data) { struct osmo_fsm_inst *fi = data; @@ -373,6 +392,9 @@ static void xua_asp_fsm_inactive(struct osmo_fsm_inst *fi, uint32_t event, void *data) { + struct xua_msg *xua_in; + uint32_t traf_mode; + check_stop_t_ack(fi, event); switch (event) { case XUA_ASP_E_M_ASP_ACTIVE_REQ: @@ -400,8 +422,18 @@ PRIM_OP_CONFIRM); break; case XUA_ASP_E_ASPTM_ASPAC: + xua_in = data; /* only in role SG */ ENSURE_SG_OR_IPSP(fi, event); + if (xua_msg_find_tag(xua_in, M3UA_IEI_TRAF_MODE_TYP)) { + traf_mode = xua_msg_get_u32(xua_in, M3UA_IEI_TRAF_MODE_TYP); + if (traf_mode != M3UA_TMOD_OVERRIDE && + traf_mode != M3UA_TMOD_LOADSHARE && + traf_mode != M3UA_TMOD_BCAST) { + peer_send_error(fi, M3UA_ERR_UNSUPP_TRAF_MOD_TYP); + break; + } + } /* send ACK */ peer_send(fi, XUA_ASP_E_ASPTM_ASPAC_ACK, NULL); /* transition state and inform layer manager */ -- To view, visit https://gerrit.osmocom.org/2270 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I76c01189b75ff3084cd4d3944314ec9b9f811dbf Gerrit-PatchSet: 7 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Apr 10 11:26:56 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 11:26:56 +0000 Subject: [MERGED] libosmo-sccp[master]: M3UA: Send "Unexpected Message" when receiving ASP_UP-ACK in... In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: M3UA: Send "Unexpected Message" when receiving ASP_UP-ACK in ACTIVE ...................................................................... M3UA: Send "Unexpected Message" when receiving ASP_UP-ACK in ACTIVE Change-Id: Ibcda68b7acb02bf1580a832baff06ff21cbac713 --- M src/xua_asp_fsm.c 1 file changed, 1 insertion(+), 1 deletion(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/xua_asp_fsm.c b/src/xua_asp_fsm.c index 87f8927..0996db0 100644 --- a/src/xua_asp_fsm.c +++ b/src/xua_asp_fsm.c @@ -527,10 +527,10 @@ * an Error message ("Unexpected Message), and the * remote ASP state is changed to ASP-INACTIVE in all * relevant Application Servers */ - /* FIXME: Send ERROR message */ osmo_fsm_inst_state_chg(fi, XUA_ASP_S_INACTIVE, 0, 0); send_xlm_prim_simple(fi, OSMO_XLM_PRIM_M_ASP_INACTIVE, PRIM_OP_INDICATION); + peer_send_error(fi, M3UA_ERR_UNEXPECTED_MSG); break; } } -- To view, visit https://gerrit.osmocom.org/2271 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ibcda68b7acb02bf1580a832baff06ff21cbac713 Gerrit-PatchSet: 7 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Apr 10 11:26:56 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 11:26:56 +0000 Subject: [MERGED] libosmo-sccp[master]: M3UA: Respond with "Unexpected Message" if ASPTM is received... In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: M3UA: Respond with "Unexpected Message" if ASPTM is received too soon ...................................................................... M3UA: Respond with "Unexpected Message" if ASPTM is received too soon This was discovered (and fix validated) using m3ua-sgp-aspsm-i-003 of Michale Tuexen's m3ua-testtool. Change-Id: I8b63e7b5e39a7ef8dd66bf014110a04f5f3dc2a2 --- M src/m3ua.c 1 file changed, 2 insertions(+), 1 deletion(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/m3ua.c b/src/m3ua.c index 92470d7..14df269 100644 --- a/src/m3ua.c +++ b/src/m3ua.c @@ -623,7 +623,8 @@ return M3UA_ERR_UNSUPP_MSG_TYPE; /* deliver that event to the ASP FSM */ - osmo_fsm_inst_dispatch(asp->fi, event, xua); + if (osmo_fsm_inst_dispatch(asp->fi, event, xua) < 0) + return M3UA_ERR_UNEXPECTED_MSG; return 0; } -- To view, visit https://gerrit.osmocom.org/2269 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I8b63e7b5e39a7ef8dd66bf014110a04f5f3dc2a2 Gerrit-PatchSet: 7 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Apr 10 11:26:57 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 11:26:57 +0000 Subject: [MERGED] libosmo-sccp[master]: osmo_sccp_make_addr_pc_ssn(): Set routing indicator In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: osmo_sccp_make_addr_pc_ssn(): Set routing indicator ...................................................................... osmo_sccp_make_addr_pc_ssn(): Set routing indicator When we crate a sccp address with PC+SSN, we should also set the routing indicator accordingly (OSMO_SCCP_RI_SSN_PC). Change-Id: Ie179df7158624520e90093da063c57f1e3efa0bd --- M src/sccp_helpers.c 1 file changed, 1 insertion(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/sccp_helpers.c b/src/sccp_helpers.c index c588607..76a7c1c 100644 --- a/src/sccp_helpers.c +++ b/src/sccp_helpers.c @@ -39,6 +39,7 @@ void osmo_sccp_make_addr_pc_ssn(struct osmo_sccp_addr *addr, uint32_t pc, uint32_t ssn) { addr->presence = OSMO_SCCP_ADDR_T_SSN | OSMO_SCCP_ADDR_T_PC; + addr->ri = OSMO_SCCP_RI_SSN_PC; addr->ssn = ssn; addr->pc = pc; } -- To view, visit https://gerrit.osmocom.org/2268 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ie179df7158624520e90093da063c57f1e3efa0bd Gerrit-PatchSet: 7 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Apr 10 11:26:57 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 11:26:57 +0000 Subject: [MERGED] libosmo-sccp[master]: osmo_ss7: Fix msgb memory leaks in error paths (asp not conn... In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: osmo_ss7: Fix msgb memory leaks in error paths (asp not connected) ...................................................................... osmo_ss7: Fix msgb memory leaks in error paths (asp not connected) Change-Id: I031d90348ea243ac5dbdde14365528f3ec8e3709 --- M src/osmo_ss7.c 1 file changed, 2 insertions(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index d3b71e7..9c886c4 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -1419,6 +1419,7 @@ if (!asp->server) { LOGPASP(asp, DLSS7, LOGL_ERROR, "Cannot transmit, no asp->server\n"); /* FIXME: what to do here? delete the route? send DUNA? */ + msgb_free(msg); return -EIO; } osmo_stream_srv_send(asp->server, msg); @@ -1426,6 +1427,7 @@ if (!asp->client) { LOGPASP(asp, DLSS7, LOGL_ERROR, "Cannot transmit, no asp->client\n"); /* FIXME: what to do here? delete the route? send DUNA? */ + msgb_free(msg); return -EIO; } osmo_stream_cli_send(asp->client, msg); -- To view, visit https://gerrit.osmocom.org/2267 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I031d90348ea243ac5dbdde14365528f3ec8e3709 Gerrit-PatchSet: 7 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Apr 10 11:26:57 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 11:26:57 +0000 Subject: [MERGED] libosmo-sccp[master]: osmo_ss7: default point-code format for parsing/printing wit... In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: osmo_ss7: default point-code format for parsing/printing without ss7_instance ...................................................................... osmo_ss7: default point-code format for parsing/printing without ss7_instance osmo_ss7_pointcode_print() osmo_ss7_pointcode_parse() etc. now support passing a NULL ss7-instance which will lead to application of the default ITU 3.8.3 point code format. Change-Id: Ifb739e92e31eaaa0343dc57c9af8c9164d00175f --- M include/osmocom/sigtran/osmo_ss7.h M src/osmo_ss7.c 2 files changed, 43 insertions(+), 37 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/include/osmocom/sigtran/osmo_ss7.h b/include/osmocom/sigtran/osmo_ss7.h index 56a3ea4..ebb7cb3 100644 --- a/include/osmocom/sigtran/osmo_ss7.h +++ b/include/osmocom/sigtran/osmo_ss7.h @@ -51,6 +51,11 @@ * SS7 Instances ***********************************************************************/ +struct osmo_ss7_pc_fmt { + char delimiter; + uint8_t component_len[3]; +}; + struct osmo_ss7_instance { /*! member of global list of instances */ struct llist_head list; @@ -78,10 +83,7 @@ /* secondary PCs */ /* capability PCs */ uint8_t network_indicator; - struct { - char delimiter; - uint8_t component_len[3]; - } pc_fmt; + struct osmo_ss7_pc_fmt pc_fmt; } cfg; }; diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index d657b81..d3b71e7 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -71,7 +71,7 @@ }; #define LOGSS7(inst, level, fmt, args ...) \ - LOGP(DLSS7, level, "%u: " fmt, (inst)->cfg.id, ## args) + LOGP(DLSS7, level, "%u: " fmt, inst ? (inst)->cfg.id : 0, ## args) int osmo_ss7_find_free_rctx(struct osmo_ss7_instance *inst) { @@ -87,6 +87,11 @@ /*********************************************************************** * SS7 Point Code Parsing / Printing ***********************************************************************/ + +static const struct osmo_ss7_pc_fmt default_pc_fmt = { + .delimiter = '.', + .component_len = { 3, 8, 3}, +}; /* like strcat() but appends a single character */ static int strnappendchar(char *str, char c, size_t n) @@ -104,7 +109,7 @@ /* generate a format string for formatting a point code. The result can * e.g. be used with sscanf() or sprintf() */ -static const char *gen_pc_fmtstr(struct osmo_ss7_instance *inst, +static const char *gen_pc_fmtstr(const struct osmo_ss7_pc_fmt *pc_fmt, unsigned int *num_comp_exp) { static char buf[MAX_PC_STR_LEN]; @@ -114,15 +119,15 @@ strcat(buf, "%u"); num_comp++; - if (inst->cfg.pc_fmt.component_len[1] == 0) + if (pc_fmt->component_len[1] == 0) goto out; - strnappendchar(buf, inst->cfg.pc_fmt.delimiter, sizeof(buf)); + strnappendchar(buf, pc_fmt->delimiter, sizeof(buf)); strcat(buf, "%u"); num_comp++; - if (inst->cfg.pc_fmt.component_len[2] == 0) + if (pc_fmt->component_len[2] == 0) goto out; - strnappendchar(buf, inst->cfg.pc_fmt.delimiter, sizeof(buf)); + strnappendchar(buf, pc_fmt->delimiter, sizeof(buf)); strcat(buf, "%u"); num_comp++; out: @@ -133,38 +138,35 @@ /* get number of components we expect for a point code, depending on the * configuration of this ss7_instance */ -static unsigned int num_pc_comp_exp(struct osmo_ss7_instance *inst) +static unsigned int num_pc_comp_exp(const struct osmo_ss7_pc_fmt *pc_fmt) { unsigned int num_comp_exp = 1; - if (inst->cfg.pc_fmt.component_len[1]) + if (pc_fmt->component_len[1]) num_comp_exp++; - if (inst->cfg.pc_fmt.component_len[2]) + if (pc_fmt->component_len[2]) num_comp_exp++; return num_comp_exp; } /* get the total width (in bits) of the point-codes in this ss7_instance */ -static unsigned int get_pc_width(struct osmo_ss7_instance *inst) +static unsigned int get_pc_width(const struct osmo_ss7_pc_fmt *pc_fmt) { - return inst->cfg.pc_fmt.component_len[0] + - inst->cfg.pc_fmt.component_len[1] + - inst->cfg.pc_fmt.component_len[2]; + return pc_fmt->component_len[0] + pc_fmt->component_len[1] + pc_fmt->component_len[2]; } /* get the number of bits we must shift the given component of a point * code in this ss7_instance */ -static unsigned int get_pc_comp_shift(struct osmo_ss7_instance *inst, +static unsigned int get_pc_comp_shift(const struct osmo_ss7_pc_fmt *pc_fmt, unsigned int comp_num) { - uint32_t pc_width = get_pc_width(inst); + uint32_t pc_width = get_pc_width(pc_fmt); switch (comp_num) { case 0: - return pc_width - inst->cfg.pc_fmt.component_len[0]; + return pc_width - pc_fmt->component_len[0]; case 1: - return pc_width - inst->cfg.pc_fmt.component_len[0] - - inst->cfg.pc_fmt.component_len[1]; + return pc_width - pc_fmt->component_len[0] - pc_fmt->component_len[1]; case 2: return 0; default: @@ -172,11 +174,11 @@ } } -static uint32_t pc_comp_shift_and_mask(struct osmo_ss7_instance *inst, +static uint32_t pc_comp_shift_and_mask(const struct osmo_ss7_pc_fmt *pc_fmt, unsigned int comp_num, uint32_t pc) { - unsigned int shift = get_pc_comp_shift(inst, comp_num); - uint32_t mask = (1 << inst->cfg.pc_fmt.component_len[comp_num]) - 1; + unsigned int shift = get_pc_comp_shift(pc_fmt, comp_num); + uint32_t mask = (1 << pc_fmt->component_len[comp_num]) - 1; return (pc >> shift) & mask; } @@ -186,8 +188,9 @@ int osmo_ss7_pointcode_parse(struct osmo_ss7_instance *inst, const char *str) { unsigned int component[3]; - unsigned int num_comp_exp = num_pc_comp_exp(inst); - const char *fmtstr = gen_pc_fmtstr(inst, &num_comp_exp); + const struct osmo_ss7_pc_fmt *pc_fmt = inst ? &inst->cfg.pc_fmt : &default_pc_fmt; + unsigned int num_comp_exp = num_pc_comp_exp(pc_fmt); + const char *fmtstr = gen_pc_fmtstr(pc_fmt, &num_comp_exp); int i, rc; rc = sscanf(str, fmtstr, &component[0], &component[1], &component[2]); @@ -198,16 +201,16 @@ /* check none of the component values exceeds what can be * represented within its bit-width */ for (i = 0; i < num_comp_exp; i++) { - if (component[i] >= (1 << inst->cfg.pc_fmt.component_len[i])) + if (component[i] >= (1 << pc_fmt->component_len[i])) goto err; } /* shift them all together */ - rc = (component[0] << get_pc_comp_shift(inst, 0)); + rc = (component[0] << get_pc_comp_shift(pc_fmt, 0)); if (num_comp_exp > 1) - rc |= (component[1] << get_pc_comp_shift(inst, 1)); + rc |= (component[1] << get_pc_comp_shift(pc_fmt, 1)); if (num_comp_exp > 2) - rc |= (component[2] << get_pc_comp_shift(inst, 2)); + rc |= (component[2] << get_pc_comp_shift(pc_fmt, 2)); return rc; @@ -221,21 +224,22 @@ const char *osmo_ss7_pointcode_print(struct osmo_ss7_instance *inst, uint32_t pc) { static char buf[MAX_PC_STR_LEN]; - unsigned int num_comp_exp = num_pc_comp_exp(inst); - const char *fmtstr = gen_pc_fmtstr(inst, &num_comp_exp); + const struct osmo_ss7_pc_fmt *pc_fmt = inst ? &inst->cfg.pc_fmt : &default_pc_fmt; + unsigned int num_comp_exp = num_pc_comp_exp(pc_fmt); + const char *fmtstr = gen_pc_fmtstr(pc_fmt, &num_comp_exp); OSMO_ASSERT(fmtstr); snprintf(buf, sizeof(buf), fmtstr, - pc_comp_shift_and_mask(inst, 0, pc), - pc_comp_shift_and_mask(inst, 1, pc), - pc_comp_shift_and_mask(inst, 2, pc)); + pc_comp_shift_and_mask(pc_fmt, 0, pc), + pc_comp_shift_and_mask(pc_fmt, 1, pc), + pc_comp_shift_and_mask(pc_fmt, 2, pc)); return buf; } int osmo_ss7_pointcode_parse_mask_or_len(struct osmo_ss7_instance *inst, const char *in) { - unsigned int width = get_pc_width(inst); + unsigned int width = get_pc_width(inst ? &inst->cfg.pc_fmt : &default_pc_fmt); if (in[0] == '/') { /* parse mask by length */ -- To view, visit https://gerrit.osmocom.org/2265 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ifb739e92e31eaaa0343dc57c9af8c9164d00175f Gerrit-PatchSet: 7 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Apr 10 11:26:57 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 11:26:57 +0000 Subject: [MERGED] libosmo-sccp[master]: m3ua: Remove inbound routing context before routing In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: m3ua: Remove inbound routing context before routing ...................................................................... m3ua: Remove inbound routing context before routing After verifying the routing context of an incoming M3UA message, remove the routing context before passing into MTP routing. In the forwarding case, we might want to set a new routing context on the outbound link, and we don't want the routing context IE to show up twice. Change-Id: I7a534cb1da275369c70766c059aaae8157ce6833 --- M src/m3ua.c 1 file changed, 4 insertions(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/m3ua.c b/src/m3ua.c index 1868388..92470d7 100644 --- a/src/m3ua.c +++ b/src/m3ua.c @@ -515,6 +515,10 @@ OSMO_ASSERT(dh); m3ua_dh_to_xfer_param(&xua->mtp, dh); + /* remove ROUTE_CTX as in the routing case we want to add a new + * routing context on the outbound side */ + xua_msg_free_tag(xua, M3UA_IEI_ROUTE_CTX); + return m3ua_hmdc_rx_from_l2(asp->inst, xua); out_err: if (err) -- To view, visit https://gerrit.osmocom.org/2266 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I7a534cb1da275369c70766c059aaae8157ce6833 Gerrit-PatchSet: 7 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Apr 10 11:26:58 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 11:26:58 +0000 Subject: [MERGED] libosmo-sccp[master]: send M-SCTP_ESTABLISH.ind to Layer Manager In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: send M-SCTP_ESTABLISH.ind to Layer Manager ...................................................................... send M-SCTP_ESTABLISH.ind to Layer Manager Change-Id: I2904f8ebd97036690ba8a9525b31354c0252123b --- M src/osmo_ss7.c M src/xua_asp_fsm.c M src/xua_internal.h 3 files changed, 25 insertions(+), 6 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index 4d3ced1..d657b81 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -1234,9 +1234,14 @@ LOGPASP(asp, DLSS7, LOGL_INFO, "Client connected %s\n", asp->sock_name); - /* Notify the ASP FSM that the connection has just been - * established */ - osmo_fsm_inst_dispatch(asp->fi, XUA_ASP_E_M_ASP_UP_REQ, NULL); + if (asp->lm && asp->lm->prim_cb) { + /* Notify layer manager that a connection has been + * established */ + xua_asp_send_xlm_prim_simple(asp, OSMO_XLM_PRIM_M_SCTP_ESTABLISH, PRIM_OP_INDICATION); + } else { + /* directly as the ASP FSM to start by sending an ASP-UP ... */ + osmo_fsm_inst_dispatch(asp->fi, XUA_ASP_E_M_ASP_UP_REQ, NULL); + } return 0; } @@ -1381,6 +1386,9 @@ * data */ osmo_stream_srv_set_data(srv, asp); + /* send M-SCTP_ESTABLISH.ind to Layer Manager */ + xua_asp_send_xlm_prim_simple(asp, OSMO_XLM_PRIM_M_SCTP_ESTABLISH, PRIM_OP_INDICATION); + return 0; } diff --git a/src/xua_asp_fsm.c b/src/xua_asp_fsm.c index e16e26a..1570bc9 100644 --- a/src/xua_asp_fsm.c +++ b/src/xua_asp_fsm.c @@ -109,15 +109,23 @@ } /* wrapper around send_xlm_prim for primitives without data */ -static void send_xlm_prim_simple(struct osmo_fsm_inst *fi, +void xua_asp_send_xlm_prim_simple(struct osmo_ss7_asp *asp, enum osmo_xlm_prim_type prim_type, enum osmo_prim_operation op) { struct osmo_xlm_prim *prim = xua_xlm_prim_alloc(prim_type, op); - struct xua_asp_fsm_priv *xafp = fi->priv; if (!prim) return; - xua_asp_send_xlm_prim(xafp->asp, prim); + xua_asp_send_xlm_prim(asp, prim); +} + +static void send_xlm_prim_simple(struct osmo_fsm_inst *fi, + enum osmo_xlm_prim_type prim_type, + enum osmo_prim_operation op) +{ + struct xua_asp_fsm_priv *xafp = fi->priv; + struct osmo_ss7_asp *asp = xafp->asp; + xua_asp_send_xlm_prim_simple(asp, prim_type, op); } /* ask the xUA implementation to transmit a specific message */ diff --git a/src/xua_internal.h b/src/xua_internal.h index 6a3f723..3921309 100644 --- a/src/xua_internal.h +++ b/src/xua_internal.h @@ -52,3 +52,6 @@ enum osmo_prim_operation op); void xua_asp_send_xlm_prim(struct osmo_ss7_asp *asp, struct osmo_xlm_prim *prim); +void xua_asp_send_xlm_prim_simple(struct osmo_ss7_asp *asp, + enum osmo_xlm_prim_type prim_type, + enum osmo_prim_operation op); -- To view, visit https://gerrit.osmocom.org/2264 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I2904f8ebd97036690ba8a9525b31354c0252123b Gerrit-PatchSet: 7 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Apr 10 11:26:58 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 11:26:58 +0000 Subject: [MERGED] libosmo-sccp[master]: xua: report N-ERROR and N-NOTIFY primitives to layer manager In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: xua: report N-ERROR and N-NOTIFY primitives to layer manager ...................................................................... xua: report N-ERROR and N-NOTIFY primitives to layer manager Change-Id: I5c2060f0397d2bf510b085a5bb07e7ab176f2742 --- M src/m3ua.c 1 file changed, 12 insertions(+), 1 deletion(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/m3ua.c b/src/m3ua.c index 0ec4529..1868388 100644 --- a/src/m3ua.c +++ b/src/m3ua.c @@ -526,10 +526,16 @@ static int m3ua_rx_mgmt_err(struct osmo_ss7_asp *asp, struct xua_msg *xua) { uint32_t err_code = xua_msg_get_u32(xua, M3UA_IEI_ERR_CODE); + struct osmo_xlm_prim *prim; LOGPASP(asp, DLM3UA, LOGL_ERROR, "Received MGMT_ERR '%s': %s\n", get_value_string(m3ua_err_names, err_code), xua_msg_dump(xua, &xua_dialect_m3ua)); + + /* report this to layer manager */ + prim = xua_xlm_prim_alloc(OSMO_XLM_PRIM_M_ERROR, PRIM_OP_INDICATION); + prim->u.error.code = err_code; + xua_asp_send_xlm_prim(asp, prim); /* NEVER return != 0 here, as we cannot respont to an ERR * message with another ERR! */ @@ -540,6 +546,7 @@ { struct osmo_xlm_prim_notify ntfy; const char *type_name, *info_name; + struct osmo_xlm_prim *prim; m3ua_decode_notify(&ntfy, asp, xua); @@ -562,10 +569,14 @@ type_name, info_name, ntfy.info_string ? ntfy.info_string : ""); + /* report this to layer manager */ + prim = xua_xlm_prim_alloc(OSMO_XLM_PRIM_M_NOTIFY, PRIM_OP_INDICATION); + prim->u.notify = ntfy; + xua_asp_send_xlm_prim(asp,prim); + if (ntfy.info_string) talloc_free(ntfy.info_string); - /* TODO: should we report this soemwhere? */ return 0; } -- To view, visit https://gerrit.osmocom.org/2262 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I5c2060f0397d2bf510b085a5bb07e7ab176f2742 Gerrit-PatchSet: 7 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Apr 10 11:26:58 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 11:26:58 +0000 Subject: [MERGED] libosmo-sccp[master]: xua: move notfiy parameters from xua_internal to sigtran_sap... In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: xua: move notfiy parameters from xua_internal to sigtran_sap and rename them ...................................................................... xua: move notfiy parameters from xua_internal to sigtran_sap and rename them Change-Id: I295b9d6755a4bb52a817d2791a302bdd9fc775dd --- M include/osmocom/sigtran/sigtran_sap.h M src/m3ua.c M src/sua.c M src/xua_as_fsm.c M src/xua_asp_fsm.c M src/xua_internal.h 6 files changed, 55 insertions(+), 44 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/include/osmocom/sigtran/sigtran_sap.h b/include/osmocom/sigtran/sigtran_sap.h index d29c37d..d18aa3d 100644 --- a/include/osmocom/sigtran/sigtran_sap.h +++ b/include/osmocom/sigtran/sigtran_sap.h @@ -1,6 +1,7 @@ #pragma once #include + enum osmo_sigtran_sap { SCCP_SAP_USER = _SAP_SS7_BASE, /* xUA Layer Manager */ @@ -29,10 +30,27 @@ OSMO_XLM_PRIM_M_RK_DEREG, }; +#define NOTIFY_PAR_P_ASP_ID (1 << 0) +#define NOTIFY_PAR_P_ROUTE_CTX (1 << 1) + +struct osmo_xlm_prim_notify { + uint32_t presence; + uint16_t status_type; + uint16_t status_info; + uint32_t asp_id; + uint32_t route_ctx; + char *info_string; +}; + +struct osmo_xlm_prim_error { + uint32_t code; +}; struct osmo_xlm_prim { struct osmo_prim_hdr oph; union { + struct osmo_xlm_prim_notify notify; + struct osmo_xlm_prim_error error; } u; }; diff --git a/src/m3ua.c b/src/m3ua.c index 031e5cd..0ec4529 100644 --- a/src/m3ua.c +++ b/src/m3ua.c @@ -350,7 +350,7 @@ ***********************************************************************/ /* RFC4666 Ch. 3.8.2. Notify */ -struct xua_msg *m3ua_encode_notify(const struct m3ua_notify_params *npar) +struct xua_msg *m3ua_encode_notify(const struct osmo_xlm_prim_notify *npar) { struct xua_msg *xua = xua_msg_alloc(); uint32_t status; @@ -379,7 +379,7 @@ } /* RFC4666 Ch. 3.8.2. Notify */ -int m3ua_decode_notify(struct m3ua_notify_params *npar, void *ctx, +int m3ua_decode_notify(struct osmo_xlm_prim_notify *npar, void *ctx, const struct xua_msg *xua) { struct xua_msg_part *info_ie, *aspid_ie, *status_ie, *rctx_ie; @@ -538,7 +538,7 @@ static int m3ua_rx_mgmt_ntfy(struct osmo_ss7_asp *asp, struct xua_msg *xua) { - struct m3ua_notify_params ntfy; + struct osmo_xlm_prim_notify ntfy; const char *type_name, *info_name; m3ua_decode_notify(&ntfy, asp, xua); diff --git a/src/sua.c b/src/sua.c index 2f8acf2..881191e 100644 --- a/src/sua.c +++ b/src/sua.c @@ -507,7 +507,7 @@ static int sua_rx_mgmt_ntfy(struct osmo_ss7_asp *asp, struct xua_msg *xua) { - struct m3ua_notify_params ntfy; + struct osmo_xlm_prim_notify ntfy; const char *type_name, *info_name; m3ua_decode_notify(&ntfy, asp, xua); diff --git a/src/xua_as_fsm.c b/src/xua_as_fsm.c index d73f793..740070b 100644 --- a/src/xua_as_fsm.c +++ b/src/xua_as_fsm.c @@ -25,7 +25,7 @@ #include "xua_as_fsm.h" #include "xua_internal.h" -static struct msgb *encode_notify(const struct m3ua_notify_params *npar) +static struct msgb *encode_notify(const struct osmo_xlm_prim_notify *npar) { struct xua_msg *xua = m3ua_encode_notify(npar); struct msgb *msg = xua_to_msg(M3UA_VERSION, xua); @@ -33,7 +33,7 @@ return msg; } -static int asp_notify_all_as(struct osmo_ss7_as *as, struct m3ua_notify_params *npar) +static int asp_notify_all_as(struct osmo_ss7_as *as, struct osmo_xlm_prim_notify *npar) { struct msgb *msg; unsigned int i, sent = 0; @@ -150,7 +150,7 @@ { struct xua_as_fsm_priv *xafp = (struct xua_as_fsm_priv *) fi->priv; struct osmo_ss7_as *as = xafp->as; - struct m3ua_notify_params npar = { + struct osmo_xlm_prim_notify npar = { .status_type = M3UA_NOTIFY_T_STATCHG, }; diff --git a/src/xua_asp_fsm.c b/src/xua_asp_fsm.c index aafc09f..d38a18a 100644 --- a/src/xua_asp_fsm.c +++ b/src/xua_asp_fsm.c @@ -89,42 +89,42 @@ } t_ack; }; -static struct msgb *xlm_msgb_alloc(void) +struct osmo_xlm_prim *xua_xlm_prim_alloc(enum osmo_xlm_prim_type prim_type, + enum osmo_prim_operation op) { - return msgb_alloc_headroom(2048+128, 128, "xua_asp-xlm msgb"); + struct osmo_xlm_prim *prim; + struct msgb *msg = msgb_alloc_headroom(2048+128, 128, "xua_asp-xlm msgb"); + if (!msg) + return NULL; + + prim = (struct osmo_xlm_prim *) msgb_put(msg, sizeof(*prim)); + osmo_prim_init(&prim->oph, XUA_SAP_LM, prim_type, op, msg); + + return prim; } /* Send a XUA LM Primitive to the XUA Layer Manager (LM) */ -static int send_xlm_prim(struct osmo_fsm_inst *fi, - enum osmo_xlm_prim_type prim_type, - enum osmo_prim_operation op, - const uint8_t *data, unsigned int data_len) +void xua_asp_send_xlm_prim(struct osmo_ss7_asp *asp, struct osmo_xlm_prim *prim) { - struct xua_asp_fsm_priv *xafp = fi->priv; - struct msgb *xlmsg; - struct osmo_xlm_prim *prim; + struct xua_asp_fsm_priv *xafp = asp->fi->priv; struct xua_layer_manager *lm = xafp->lm; - if (!lm || !lm->prim_cb) - return 0; + if (lm && lm->prim_cb) + lm->prim_cb(&prim->oph, xafp->asp); - xlmsg = xlm_msgb_alloc(); - if (!xlmsg) - return -ENOMEM; - prim = (struct osmo_xlm_prim *) msgb_put(xlmsg, sizeof(*prim)); - osmo_prim_init(&prim->oph, XUA_SAP_LM, prim_type, op, xlmsg); - - lm->prim_cb(&prim->oph, xafp->asp); - - return 0; + msgb_free(prim->oph.msg); } /* wrapper around send_xlm_prim for primitives without data */ -static int send_xlm_prim_simple(struct osmo_fsm_inst *fi, - enum osmo_xlm_prim_type prim, +static void send_xlm_prim_simple(struct osmo_fsm_inst *fi, + enum osmo_xlm_prim_type prim_type, enum osmo_prim_operation op) { - return send_xlm_prim(fi, prim, op, NULL, 0); + struct osmo_xlm_prim *prim = xua_xlm_prim_alloc(prim_type, op); + struct xua_asp_fsm_priv *xafp = fi->priv; + if (!prim) + return; + xua_asp_send_xlm_prim(xafp->asp, prim); } /* ask the xUA implementation to transmit a specific message */ diff --git a/src/xua_internal.h b/src/xua_internal.h index 24fcb1c..6a3f723 100644 --- a/src/xua_internal.h +++ b/src/xua_internal.h @@ -43,19 +43,12 @@ extern const struct value_string m3ua_ntfy_stchg_names[]; extern const struct value_string m3ua_ntfy_other_names[]; -#define NOTIFY_PAR_P_ASP_ID (1 << 0) -#define NOTIFY_PAR_P_ROUTE_CTX (1 << 1) - -struct m3ua_notify_params { - uint32_t presence; - uint16_t status_type; - uint16_t status_info; - uint32_t asp_id; - uint32_t route_ctx; - char *info_string; -}; - -struct xua_msg *m3ua_encode_notify(const struct m3ua_notify_params *npar); -int m3ua_decode_notify(struct m3ua_notify_params *npar, void *ctx, +struct xua_msg *m3ua_encode_notify(const struct osmo_xlm_prim_notify *npar); +int m3ua_decode_notify(struct osmo_xlm_prim_notify *npar, void *ctx, const struct xua_msg *xua); int m3ua_rx_rkm(struct osmo_ss7_asp *asp, struct xua_msg *xua); + +struct osmo_xlm_prim *xua_xlm_prim_alloc(enum osmo_xlm_prim_type prim_type, + enum osmo_prim_operation op); + +void xua_asp_send_xlm_prim(struct osmo_ss7_asp *asp, struct osmo_xlm_prim *prim); -- To view, visit https://gerrit.osmocom.org/2261 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I295b9d6755a4bb52a817d2791a302bdd9fc775dd Gerrit-PatchSet: 7 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Apr 10 11:26:58 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 11:26:58 +0000 Subject: [MERGED] libosmo-sccp[master]: move layer_manager from xua_asp_fsm priv to osmo_ss7_asp In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: move layer_manager from xua_asp_fsm priv to osmo_ss7_asp ...................................................................... move layer_manager from xua_asp_fsm priv to osmo_ss7_asp ... this way it is publicly accessible/reachable Change-Id: I00ec1689bfb068b9067d893fdba14d12d59f73f0 --- M include/osmocom/sigtran/osmo_ss7.h M src/xua_asp_fsm.c 2 files changed, 10 insertions(+), 9 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/include/osmocom/sigtran/osmo_ss7.h b/include/osmocom/sigtran/osmo_ss7.h index df85012..56a3ea4 100644 --- a/include/osmocom/sigtran/osmo_ss7.h +++ b/include/osmocom/sigtran/osmo_ss7.h @@ -13,6 +13,7 @@ struct osmo_ss7_user; struct osmo_sccp_instance; struct osmo_mtp_prim; +struct osmo_xua_layer_manager; int osmo_ss7_init(void); int osmo_ss7_find_free_rctx(struct osmo_ss7_instance *inst); @@ -336,6 +337,9 @@ uint32_t asp_id; bool asp_id_present; + /* Layer Manager to which we talk */ + struct osmo_xua_layer_manager *lm; + struct { char *name; char *description; @@ -366,6 +370,10 @@ * xUA Servers ***********************************************************************/ +struct osmo_xua_layer_manager { + osmo_prim_cb prim_cb; +}; + struct osmo_xua_server { struct llist_head list; struct osmo_ss7_instance *inst; diff --git a/src/xua_asp_fsm.c b/src/xua_asp_fsm.c index d38a18a..e16e26a 100644 --- a/src/xua_asp_fsm.c +++ b/src/xua_asp_fsm.c @@ -67,18 +67,12 @@ { 0, NULL } }; -struct xua_layer_manager { - osmo_prim_cb prim_cb; -}; - /* private data structure for each FSM instance */ struct xua_asp_fsm_priv { /* pointer back to ASP to which we belong */ struct osmo_ss7_asp *asp; /* Role (ASP/SG/IPSP) */ enum xua_asp_role role; - /* Layer Manager to which we talk */ - struct xua_layer_manager *lm; /* routing context[s]: list of 32bit integers */ /* ACTIVE: traffic mode type, tid label, drn label ? */ @@ -106,11 +100,10 @@ /* Send a XUA LM Primitive to the XUA Layer Manager (LM) */ void xua_asp_send_xlm_prim(struct osmo_ss7_asp *asp, struct osmo_xlm_prim *prim) { - struct xua_asp_fsm_priv *xafp = asp->fi->priv; - struct xua_layer_manager *lm = xafp->lm; + struct osmo_xua_layer_manager *lm = asp->lm; if (lm && lm->prim_cb) - lm->prim_cb(&prim->oph, xafp->asp); + lm->prim_cb(&prim->oph, asp); msgb_free(prim->oph.msg); } -- To view, visit https://gerrit.osmocom.org/2263 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I00ec1689bfb068b9067d893fdba14d12d59f73f0 Gerrit-PatchSet: 7 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Apr 10 11:26:59 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 11:26:59 +0000 Subject: [MERGED] libosmo-sccp[master]: Add M3UA RKM (routing key management) support, SGW side only In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: Add M3UA RKM (routing key management) support, SGW side only ...................................................................... Add M3UA RKM (routing key management) support, SGW side only Change-Id: I9b1cf438a42519c0fe2f555c1672fafa499122a1 --- M src/Makefile.am M src/m3ua.c M src/xua_internal.h A src/xua_rkm.c 4 files changed, 301 insertions(+), 2 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/Makefile.am b/src/Makefile.am index a4cfeeb..7867282 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -28,7 +28,7 @@ libosmo_sigtran_la_SOURCES = sccp_sap.c sua.c m3ua.c xua_msg.c sccp_helpers.c \ sccp2sua.c sccp_scrc.c sccp_sclc.c sccp_scoc.c \ - sccp_user.c \ + sccp_user.c xua_rkm.c \ osmo_ss7.c osmo_ss7_hmrt.c xua_asp_fsm.c xua_as_fsm.c libosmo_sigtran_la_LDFLAGS = -version-info $(LIBVERSION) -no-undefined -export-symbols-regex '^osmo_' libosmo_sigtran_la_LIBADD = $(LIBOSMOCORE_LIBS) $(LIBOSMONETIF_LIBS) $(LIBSCTP_LIBS) diff --git a/src/m3ua.c b/src/m3ua.c index 4f20c6e..5708985 100644 --- a/src/m3ua.c +++ b/src/m3ua.c @@ -666,8 +666,10 @@ case M3UA_MSGC_MGMT: rc = m3ua_rx_mgmt(asp, xua); break; - case M3UA_MSGC_SNM: case M3UA_MSGC_RKM: + rc = m3ua_rx_rkm(asp, xua); + break; + case M3UA_MSGC_SNM: /* FIXME */ LOGPASP(asp, DLM3UA, LOGL_NOTICE, "Received unsupported M3UA " "Message Class %u\n", xua->hdr.msg_class); diff --git a/src/xua_internal.h b/src/xua_internal.h index c6f79b7..24fcb1c 100644 --- a/src/xua_internal.h +++ b/src/xua_internal.h @@ -58,3 +58,4 @@ struct xua_msg *m3ua_encode_notify(const struct m3ua_notify_params *npar); int m3ua_decode_notify(struct m3ua_notify_params *npar, void *ctx, const struct xua_msg *xua); +int m3ua_rx_rkm(struct osmo_ss7_asp *asp, struct xua_msg *xua); diff --git a/src/xua_rkm.c b/src/xua_rkm.c new file mode 100644 index 0000000..12d59c7 --- /dev/null +++ b/src/xua_rkm.c @@ -0,0 +1,296 @@ +/* xUA Routing Key Management (RKM) as per RFC 4666 */ +/* (C) 2017 by Harald Welte + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include + +#include +#include + +#include +#include +#include + +#include "xua_internal.h" + +/* push a M3UA header to the front of the given message */ +static void msgb_push_m3ua_hdr(struct msgb *msg, uint8_t msg_class, uint8_t msg_type) +{ + struct xua_common_hdr *hdr; + + msg->l2h = msgb_push(msg, sizeof(*hdr)); + hdr = (struct xua_common_hdr *) msg->l2h; + + hdr->version = M3UA_VERSION; + hdr->spare = 0; + hdr->msg_class = msg_class; + hdr->msg_type = msg_type; + hdr->msg_length = htonl(msgb_l2len(msg)); +} + +/* append a single registration result to given msgb */ +static int msgb_append_reg_res(struct msgb *msg, uint32_t local_rk_id, + uint32_t status, uint32_t rctx) +{ + uint8_t *old_tail = msg->tail; + + /* One individual Registration Result according to Chapter 3.6.2 */ + msgb_put_u16(msg, M3UA_IEI_REG_RESULT); /* outer IEI */ + msgb_put_u16(msg, 24 + 4); /* outer length */ + /* nested IEIs */ + msgb_t16l16vp_put_u32(msg, M3UA_IEI_LOC_RKEY_ID, local_rk_id); + msgb_t16l16vp_put_u32(msg, M3UA_IEI_REG_STATUS, status); + msgb_t16l16vp_put_u32(msg, M3UA_IEI_ROUTE_CTX, rctx); + + return msg->tail - old_tail; +} + +/* append a single de-registration result to given msgb */ +static int msgb_append_dereg_res(struct msgb *msg, + uint32_t status, uint32_t rctx) +{ + uint8_t *old_tail = msg->tail; + + /* One individual De-Registration Result according to Chapter 3.6.4 */ + msgb_put_u16(msg, M3UA_IEI_DEREG_RESULT); /* outer IEI */ + msgb_put_u16(msg, 16 + 4); /* outer length */ + /* nested IEIs */ + msgb_t16l16vp_put_u32(msg, M3UA_IEI_ROUTE_CTX, rctx); + msgb_t16l16vp_put_u32(msg, M3UA_IEI_DEREG_STATUS, status); + + return msg->tail - old_tail; +} + +/* handle a single registration request IE (nested IEs in 'innner' */ +static int handle_rkey_reg(struct osmo_ss7_asp *asp, struct xua_msg *inner, + struct msgb *resp) +{ + uint32_t rk_id, rctx, _tmode, dpc; + enum osmo_ss7_as_traffic_mode tmode; + struct osmo_ss7_as *as; + struct osmo_ss7_route *rt; + char namebuf[32]; + + /* mandatory local routing key ID */ + rk_id = xua_msg_get_u32(inner, M3UA_IEI_LOC_RKEY_ID); + /* ASP may already include a routing context value here */ + rctx = xua_msg_get_u32(inner, M3UA_IEI_ROUTE_CTX); + + /* traffic mode type (0 = undefined) */ + _tmode = xua_msg_get_u32(inner, M3UA_IEI_TRAF_MODE_TYP); + if (xua_msg_find_tag(inner, M3UA_IEI_TRAF_MODE_TYP) && _tmode != M3UA_TMOD_OVERRIDE && + _tmode != M3UA_TMOD_LOADSHARE && _tmode != M3UA_TMOD_BCAST) { + LOGPASP(asp, DLSS7, LOGL_NOTICE, "RKM: Invalid Traffic Mode %u\n", _tmode); + msgb_append_reg_res(resp, rk_id, M3UA_RKM_REG_ERR_UNSUPP_TRAF_MODE, 0); + return -1; + } + + tmode = osmo_ss7_tmode_from_xua(_tmode); + + /* destination point code (mandatory) */ + dpc = xua_msg_get_u32(inner, M3UA_IEI_DEST_PC); + + /* We don't support routing keys with the following criteria, so + * we have to reject those */ + /* TODO: network appearance (optional) */ + /* TODO: service indicators (optional) */ + /* TODO: originating point code list (optional) */ + if (xua_msg_find_tag(inner, M3UA_IEI_NET_APPEAR) || + xua_msg_find_tag(inner, M3UA_IEI_SVC_IND) || + xua_msg_find_tag(inner, M3UA_IEI_ORIG_PC)) { + LOGPASP(asp, DLSS7, LOGL_NOTICE, "RKM: Unsupported Routing Key\n"); + msgb_append_reg_res(resp, rk_id, M3UA_RKM_REG_ERR_UNSUPP_RK_PARAM, 0); + return -1; + } + + /* if the ASP did not include a routing context number, allocate + * one locally (will be part of response) */ + if (!rctx) + rctx = osmo_ss7_find_free_rctx(asp->inst); + + LOGPASP(asp, DLSS7, LOGL_INFO, "RKM: Registering routing key %u for DPC %s\n", + rctx, osmo_ss7_pointcode_print(asp->inst, dpc)); + + /* check if there is already an AS for this routing key */ + if (osmo_ss7_as_find_by_rctx(asp->inst, rctx)) { + LOGPASP(asp, DLSS7, LOGL_NOTICE, "RKM: RCTX %u already in use\n", rctx); + msgb_append_reg_res(resp, rk_id, M3UA_RKM_REG_ERR_RKEY_ALRDY_REGD, 0); + return -1; + } + + /* Create an AS for this routing key */ + snprintf(namebuf, sizeof(namebuf), "as-rkm-%u", rctx); + as = osmo_ss7_as_find_or_create(asp->inst, namebuf, OSMO_SS7_ASP_PROT_M3UA); + if (!as) { + LOGPASP(asp, DLSS7, LOGL_ERROR, "RKM: Cannot create AS %s\n", namebuf); + msgb_append_reg_res(resp, rk_id, M3UA_RKM_REG_ERR_INSUFF_RESRC, 0); + return -1; + } + + as->cfg.description = talloc_strdup(as, "Auto-generated by RKM"); + as->cfg.mode = tmode; + /* fill routing key */ + as->cfg.routing_key.context = rctx; + as->cfg.routing_key.pc = dpc; + + /* add route for that routing key */ + rt = osmo_ss7_route_create(as->inst->rtable_system, dpc, 0xFFFFFF, namebuf); + if (!rt) { + LOGPASP(asp, DLSS7, LOGL_ERROR, "RKM: Cannot insert route for DPC %s / as %s\n", + osmo_ss7_pointcode_print(asp->inst, dpc), namebuf); + osmo_ss7_as_destroy(as); + msgb_append_reg_res(resp, rk_id, M3UA_RKM_REG_ERR_CANT_SUPP_UNQ_RT, 0); + return -1; + } + + /* Success: Add just-create AS to connected ASP + report success */ + osmo_ss7_as_add_asp(as, asp->cfg.name); + msgb_append_reg_res(resp, rk_id, M3UA_RKM_REG_SUCCESS, rctx); + return 0; +} + +/* receive a registration requuest (SG role) */ +static int m3ua_rx_rkm_reg_req(struct osmo_ss7_asp *asp, struct xua_msg *xua) +{ + struct xua_msg_part *part; + struct msgb *resp = m3ua_msgb_alloc(__func__); + + /* iterate over all routing key IEs in message */ + llist_for_each_entry(part, &xua->headers, entry) { + struct xua_msg *inner; + + if (part->tag != M3UA_IEI_ROUT_KEY) + continue; + + inner = xua_from_nested(part); + if (!inner) { + LOGPASP(asp, DLSS7, LOGL_NOTICE, "RKM: Unable to parse " + "nested IE for Routing Key\n"); + continue; + } + /* handle single registration and append result to + * 'resp' */ + handle_rkey_reg(asp, inner, resp); + } + msgb_push_m3ua_hdr(resp, M3UA_MSGC_RKM, M3UA_RKM_REG_RSP); + osmo_ss7_asp_send(asp, resp); + + return 0; +} + +/* receive a deregistration requuest (SG role) */ +static int handle_rkey_dereg(struct osmo_ss7_asp *asp, uint32_t rctx, + struct msgb *resp) +{ + struct osmo_ss7_instance *inst = asp->inst; + struct osmo_ss7_as *as; + struct osmo_ss7_route *rt; + + as = osmo_ss7_as_find_by_rctx(inst, rctx); + if (!as) { + msgb_append_dereg_res(resp, M3UA_RKM_DEREG_ERR_INVAL_RCTX, 0); + return -1; + } + + /* Reject if ASP is not even part of AS */ + if (!osmo_ss7_as_has_asp(as, asp)) { + msgb_append_dereg_res(resp, M3UA_RKM_DEREG_ERR_INVAL_RCTX, 0); + return -1; + } + + /* FIXME Reject if any ASP stillactively using this RCTX */ + + rt = osmo_ss7_route_find_dpc(inst->rtable_system, as->cfg.routing_key.pc); + if (!rt) { + msgb_append_dereg_res(resp, M3UA_RKM_DEREG_ERR_UNKNOWN, 0); + return -1; + } + + LOGPASP(asp, DLSS7, LOGL_INFO, "RKM: De-Registering rctx %u for DPC %s\n", + rctx, osmo_ss7_pointcode_print(inst, as->cfg.routing_key.pc)); + + /* remove route + AS definition */ + osmo_ss7_route_destroy(rt); + osmo_ss7_as_destroy(as); + /* report success */ + msgb_append_dereg_res(resp, M3UA_RKM_DEREG_SUCCESS, rctx); + + return 0; +} + +static int m3ua_rx_rkm_dereg_req(struct osmo_ss7_asp *asp, struct xua_msg *xua) +{ + struct xua_msg_part *part = xua_msg_find_tag(xua, M3UA_IEI_ROUTE_CTX); + struct msgb *resp = m3ua_msgb_alloc(__func__); + uint32_t *rctx; + + if (!part) + return -1; + + for (rctx = (uint32_t *)part->dat; (uint8_t *)rctx < part->dat + part->len; rctx++) + handle_rkey_dereg(asp, ntohl(*rctx), resp); + + msgb_push_m3ua_hdr(resp, M3UA_MSGC_RKM, M3UA_RKM_DEREG_RSP); + osmo_ss7_asp_send(asp, resp); + + return 0; +} + +/* receive a registration response (ASP role) */ +static int m3ua_rx_rkm_reg_rsp(struct osmo_ss7_asp *asp, struct xua_msg *xua) +{ + /* TODO */ +} + +/* receive a deregistration response (ASP role) */ +static int m3ua_rx_rkm_dereg_rsp(struct osmo_ss7_asp *asp, struct xua_msg *xua) +{ + /* TODO */ +} + +/* process an incoming RKM message in xua format */ +int m3ua_rx_rkm(struct osmo_ss7_asp *asp, struct xua_msg *xua) +{ + int rc; + + switch (xua->hdr.msg_type) { + /* SG Side */ + case M3UA_RKM_REG_REQ: + /* TOOD: ensure we are role SG */ + rc = m3ua_rx_rkm_reg_req(asp, xua); + break; + case M3UA_RKM_DEREG_REQ: + /* TOOD: ensure we are role SG */ + rc = m3ua_rx_rkm_dereg_req(asp, xua); + break; + /* ASP Side */ + case M3UA_RKM_REG_RSP: + /* TOOD: ensure we are role ASP */ + rc = m3ua_rx_rkm_reg_rsp(asp, xua); + break; + case M3UA_RKM_DEREG_RSP: + /* TOOD: ensure we are role ASP */ + rc = m3ua_rx_rkm_dereg_rsp(asp, xua); + break; + default: + LOGPASP(asp, DLSS7, LOGL_ERROR, "Received unknown RKM msg_type %u\n", + xua->hdr.msg_type); + rc = -1; + break; + } + return rc; +} -- To view, visit https://gerrit.osmocom.org/2260 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I9b1cf438a42519c0fe2f555c1672fafa499122a1 Gerrit-PatchSet: 7 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Apr 10 11:26:59 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 11:26:59 +0000 Subject: [MERGED] libosmo-sccp[master]: osmo_ss7: Add support for dynamic ASP registration In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: osmo_ss7: Add support for dynamic ASP registration ...................................................................... osmo_ss7: Add support for dynamic ASP registration if osmo_xua_server.cfg.accept_dyn_reg is set, then ASPs are permitted to connect without having a pre-configured matching ASP definition in the vty. This helps particularly in cases where RKM is used for dynamica registration of a RC (and hence AS). Change-Id: Ie48898202acbdbfe144fdd5851dfedbb554b11aa --- M include/osmocom/sigtran/osmo_ss7.h M src/osmo_ss7.c 2 files changed, 25 insertions(+), 8 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/include/osmocom/sigtran/osmo_ss7.h b/include/osmocom/sigtran/osmo_ss7.h index 4eece3e..df85012 100644 --- a/include/osmocom/sigtran/osmo_ss7.h +++ b/include/osmocom/sigtran/osmo_ss7.h @@ -373,6 +373,7 @@ struct osmo_stream_srv_link *server; struct { + bool accept_dyn_reg; struct osmo_ss7_asp_peer local; enum osmo_ss7_asp_protocol proto; } cfg; diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index 7909bfd..4d3ced1 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -1345,15 +1345,31 @@ } asp = osmo_ss7_asp_find_by_socket_addr(fd); - if (!asp) { - LOGP(DLSS7, LOGL_NOTICE, "%s: SCTP connection without matching " - "ASP definition, terminating\n", sock_name); - osmo_stream_srv_destroy(srv); - talloc_free(sock_name); - return -1; + if (asp) { + LOGP(DLSS7, LOGL_INFO, "%s: matched connection to ASP %s\n", + sock_name, asp->cfg.name); + } else { + if (!oxs->cfg.accept_dyn_reg) { + LOGP(DLSS7, LOGL_NOTICE, "%s: SCTP connection without matching " + "ASP definition and no dynamic registration enabled, terminating\n", + sock_name); + } else { + char namebuf[32]; + static uint32_t dyn_asp_num = 0; + snprintf(namebuf, sizeof(namebuf), "asp-dyn-%u", dyn_asp_num++); + asp = osmo_ss7_asp_find_or_create(oxs->inst, NULL, 0, 0, + OSMO_SS7_ASP_PROT_M3UA); + if (asp) + LOGP(DLSS7, LOGL_INFO, "%s: created dynamicASP %s\n", + sock_name, asp->cfg.name); + } + if (!asp) { + osmo_stream_srv_destroy(srv); + talloc_free(sock_name); + return -1; + } } - LOGP(DLSS7, LOGL_INFO, "%s: matched connection to ASP %s\n", - sock_name, asp->cfg.name); + /* update the ASP reference back to the server over which the * connection came in */ asp->server = srv; -- To view, visit https://gerrit.osmocom.org/2259 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ie48898202acbdbfe144fdd5851dfedbb554b11aa Gerrit-PatchSet: 6 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Apr 10 11:26:59 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 11:26:59 +0000 Subject: [MERGED] libosmo-sccp[master]: Add osmo_ss7_find_free_rctx() function to get unused rctx In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: Add osmo_ss7_find_free_rctx() function to get unused rctx ...................................................................... Add osmo_ss7_find_free_rctx() function to get unused rctx Change-Id: I0186e25a1b3a325c6b0e3f50ef1590c4de6dbef6 --- M include/osmocom/sigtran/osmo_ss7.h M src/osmo_ss7.c 2 files changed, 12 insertions(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/include/osmocom/sigtran/osmo_ss7.h b/include/osmocom/sigtran/osmo_ss7.h index d765ae0..4eece3e 100644 --- a/include/osmocom/sigtran/osmo_ss7.h +++ b/include/osmocom/sigtran/osmo_ss7.h @@ -15,6 +15,7 @@ struct osmo_mtp_prim; int osmo_ss7_init(void); +int osmo_ss7_find_free_rctx(struct osmo_ss7_instance *inst); bool osmo_ss7_pc_is_local(struct osmo_ss7_instance *inst, uint32_t pc); int osmo_ss7_pointcode_parse(struct osmo_ss7_instance *inst, const char *str); diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index f7f2519..7909bfd 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -53,6 +53,7 @@ static LLIST_HEAD(ss7_instances); static LLIST_HEAD(ss7_xua_servers); +static int32_t next_rctx = 1; struct value_string osmo_ss7_as_traffic_mode_vals[] = { { OSMO_SS7_AS_TMOD_BCAST, "broadcast" }, @@ -72,6 +73,16 @@ #define LOGSS7(inst, level, fmt, args ...) \ LOGP(DLSS7, level, "%u: " fmt, (inst)->cfg.id, ## args) +int osmo_ss7_find_free_rctx(struct osmo_ss7_instance *inst) +{ + int32_t rctx; + + for (rctx = next_rctx; rctx; rctx = ++next_rctx) { + if (!osmo_ss7_as_find_by_rctx(inst, next_rctx)) + return rctx; + } + return -1; +} /*********************************************************************** * SS7 Point Code Parsing / Printing -- To view, visit https://gerrit.osmocom.org/2258 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I0186e25a1b3a325c6b0e3f50ef1590c4de6dbef6 Gerrit-PatchSet: 6 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Apr 10 11:27:00 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 11:27:00 +0000 Subject: [MERGED] libosmo-sccp[master]: protocol/m3ua.h: Add definition for RKM reg/dereg result codes In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: protocol/m3ua.h: Add definition for RKM reg/dereg result codes ...................................................................... protocol/m3ua.h: Add definition for RKM reg/dereg result codes Change-Id: I16db7847e20501b89cc487029b29c8796b10bb84 --- M include/osmocom/sigtran/protocol/m3ua.h 1 file changed, 26 insertions(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/include/osmocom/sigtran/protocol/m3ua.h b/include/osmocom/sigtran/protocol/m3ua.h index 835e73e..ecbe37b 100644 --- a/include/osmocom/sigtran/protocol/m3ua.h +++ b/include/osmocom/sigtran/protocol/m3ua.h @@ -116,6 +116,32 @@ #define M3UA_NOTIFY_I_OT_ALT_ASP_ACT 2 #define M3UA_NOTIFY_I_OT_ASP_FAILURE 3 +/* 3.6.2 Registration Status */ +enum m3ua_rkm_reg_status { + M3UA_RKM_REG_SUCCESS = 0, + M3UA_RKM_REG_ERR_UNKNOWN = 1, + M3UA_RKM_REG_ERR_INVAL_DPC = 2, + M3UA_RKM_REG_ERR_INVAL_NET_APPEAR = 3, + M3UA_RKM_REG_ERR_INVAL_RKEY = 4, + M3UA_RKM_REG_ERR_PERM_DENIED = 5, + M3UA_RKM_REG_ERR_CANT_SUPP_UNQ_RT = 6, + M3UA_RKM_REG_ERR_RKEY_NOT_PROVD = 7, + M3UA_RKM_REG_ERR_INSUFF_RESRC = 8, + M3UA_RKM_REG_ERR_UNSUPP_RK_PARAM = 9, + M3UA_RKM_REG_ERR_UNSUPP_TRAF_MODE = 10, + M3UA_RKM_REG_ERR_RKEY_CHG_REFUSED = 11, + M3UA_RKM_REG_ERR_RKEY_ALRDY_REGD = 12, +}; + +enum m3ua_rkm_dereg_satus { + M3UA_RKM_DEREG_SUCCESS = 0, + M3UA_RKM_DEREG_ERR_UNKNOWN = 1, + M3UA_RKM_DEREG_ERR_INVAL_RCTX = 2, + M3UA_RKM_DEREG_ERR_PERM_DENIED = 3, + M3UA_RKM_DEREG_ERR_NOT_REGD = 4, + M3UA_RKM_DEREG_ERR_ASP_ACTIVE = 5, +}; + /* 3.8.1 Error */ enum m3ua_error_code { M3UA_ERR_INVALID_VERSION = 0x01, -- To view, visit https://gerrit.osmocom.org/2256 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I16db7847e20501b89cc487029b29c8796b10bb84 Gerrit-PatchSet: 5 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Apr 10 11:27:00 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 11:27:00 +0000 Subject: [MERGED] libosmo-sccp[master]: Allow clients to specify local IP/port In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: Allow clients to specify local IP/port ...................................................................... Allow clients to specify local IP/port Change-Id: Ief7ce8181442fd0f51c34cf598269ed3a6beacea --- M examples/m3ua_example.c M include/osmocom/sigtran/osmo_ss7.h M src/osmo_ss7.c M src/sccp_user.c 4 files changed, 9 insertions(+), 5 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/examples/m3ua_example.c b/examples/m3ua_example.c index 07de7f3..d1247f5 100644 --- a/examples/m3ua_example.c +++ b/examples/m3ua_example.c @@ -106,7 +106,7 @@ if (client) { - g_sccp = osmo_sccp_simple_client(NULL, "client", 23, OSMO_SS7_ASP_PROT_M3UA, 0, M3UA_PORT, "127.0.0.2"); + g_sccp = osmo_sccp_simple_client(NULL, "client", 23, OSMO_SS7_ASP_PROT_M3UA, 0, NULL, M3UA_PORT, "127.0.0.2"); sccp_test_user_vty_install(g_sccp, OSMO_SCCP_SSN_BSC_BSSAP); } else { g_sccp = sua_server_helper(); diff --git a/include/osmocom/sigtran/osmo_ss7.h b/include/osmocom/sigtran/osmo_ss7.h index ebb7cb3..cbc6a02 100644 --- a/include/osmocom/sigtran/osmo_ss7.h +++ b/include/osmocom/sigtran/osmo_ss7.h @@ -402,10 +402,11 @@ void osmo_ss7_xua_server_destroy(struct osmo_xua_server *xs); + struct osmo_sccp_instance * osmo_sccp_simple_client(void *ctx, const char *name, uint32_t pc, - enum osmo_ss7_asp_protocol prot, - int local_port, int remote_port, const char *remote_ip); + enum osmo_ss7_asp_protocol prot, int local_port, + const char *local_ip, int remote_port, const char *remote_ip); struct osmo_sccp_instance * osmo_sccp_simple_server(void *ctx, uint32_t pc, diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index 9c886c4..103c05b 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -1046,6 +1046,8 @@ } osmo_stream_cli_set_addr(asp->client, asp->cfg.remote.host); osmo_stream_cli_set_port(asp->client, asp->cfg.remote.port); + osmo_stream_cli_set_local_addr(asp->client, asp->cfg.local.host); + osmo_stream_cli_set_local_port(asp->client, asp->cfg.local.port); osmo_stream_cli_set_proto(asp->client, IPPROTO_SCTP); osmo_stream_cli_set_reconnect_timeout(asp->client, 5); osmo_stream_cli_set_connect_cb(asp->client, xua_cli_connect_cb); diff --git a/src/sccp_user.c b/src/sccp_user.c index 9ed57d4..57c0038 100644 --- a/src/sccp_user.c +++ b/src/sccp_user.c @@ -230,8 +230,8 @@ struct osmo_sccp_instance * osmo_sccp_simple_client(void *ctx, const char *name, uint32_t pc, - enum osmo_ss7_asp_protocol prot, - int local_port, int remote_port, const char *remote_ip) + enum osmo_ss7_asp_protocol prot, int local_port, + const char *local_ip, int remote_port, const char *remote_ip) { struct osmo_ss7_instance *ss7; struct osmo_ss7_as *as; @@ -269,6 +269,7 @@ prot); if (!asp) goto out_rt; + asp->cfg.local.host = talloc_strdup(asp, local_ip); asp->cfg.remote.host = talloc_strdup(asp, remote_ip); osmo_ss7_as_add_asp(as, asp_name); talloc_free(asp_name); -- To view, visit https://gerrit.osmocom.org/2254 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ief7ce8181442fd0f51c34cf598269ed3a6beacea Gerrit-PatchSet: 6 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Apr 10 11:27:00 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 11:27:00 +0000 Subject: [MERGED] libosmo-sccp[master]: osmo_ss7: Fix segfault when routing MTP-TRANSFER.req to ASP ... In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: osmo_ss7: Fix segfault when routing MTP-TRANSFER.req to ASP without sctp connection ...................................................................... osmo_ss7: Fix segfault when routing MTP-TRANSFER.req to ASP without sctp connection Change-Id: I142a11b09672864b54b927b8334b1975c8cd6022 --- M src/osmo_ss7.c 1 file changed, 13 insertions(+), 2 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index 8ec099a..f7f2519 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -1376,10 +1376,21 @@ OSMO_ASSERT(0); } - if (asp->cfg.is_server) + if (asp->cfg.is_server) { + if (!asp->server) { + LOGPASP(asp, DLSS7, LOGL_ERROR, "Cannot transmit, no asp->server\n"); + /* FIXME: what to do here? delete the route? send DUNA? */ + return -EIO; + } osmo_stream_srv_send(asp->server, msg); - else + } else { + if (!asp->client) { + LOGPASP(asp, DLSS7, LOGL_ERROR, "Cannot transmit, no asp->client\n"); + /* FIXME: what to do here? delete the route? send DUNA? */ + return -EIO; + } osmo_stream_cli_send(asp->client, msg); + } return 0; } -- To view, visit https://gerrit.osmocom.org/2245 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I142a11b09672864b54b927b8334b1975c8cd6022 Gerrit-PatchSet: 5 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Apr 10 11:27:00 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 11:27:00 +0000 Subject: [MERGED] libosmo-sccp[master]: m3ua_example: Add talloc reporting In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: m3ua_example: Add talloc reporting ...................................................................... m3ua_example: Add talloc reporting This can be used to check for memory leaks while running the example code. Change-Id: I87caa76a2be3c92c93e419242595107d744bad97 --- M examples/m3ua_example.c 1 file changed, 26 insertions(+), 5 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/examples/m3ua_example.c b/examples/m3ua_example.c index d7b1fc2..07de7f3 100644 --- a/examples/m3ua_example.c +++ b/examples/m3ua_example.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #include @@ -20,6 +21,8 @@ #include "internal.h" +static struct osmo_sccp_instance *g_sccp; + static struct osmo_sccp_instance *sua_server_helper(void) { struct osmo_sccp_instance *sccp; @@ -36,6 +39,20 @@ /*********************************************************************** * Initialization ***********************************************************************/ + +static void signal_handler(int signal) +{ + fprintf(stdout, "signal %d received\n", signal); + + switch (signal) { + case SIGUSR1: + talloc_report_full(osmo_sccp_get_ss7(g_sccp), stderr); + break; + case SIGUSR2: + talloc_report_full(NULL, stderr); + break; + } +} static const struct log_info_cat log_info_cat[] = { }; @@ -63,9 +80,13 @@ int main(int argc, char **argv) { - struct osmo_sccp_instance *sccp; bool client; int rc; + + talloc_enable_leak_report_full(); + + signal(SIGUSR1, &signal_handler); + signal(SIGUSR2, &signal_handler); init_logging(); osmo_ss7_init(); @@ -85,11 +106,11 @@ if (client) { - sccp = osmo_sccp_simple_client(NULL, "client", 23, OSMO_SS7_ASP_PROT_M3UA, 0, M3UA_PORT, "127.0.0.2"); - sccp_test_user_vty_install(sccp, OSMO_SCCP_SSN_BSC_BSSAP); + g_sccp = osmo_sccp_simple_client(NULL, "client", 23, OSMO_SS7_ASP_PROT_M3UA, 0, M3UA_PORT, "127.0.0.2"); + sccp_test_user_vty_install(g_sccp, OSMO_SCCP_SSN_BSC_BSSAP); } else { - sccp = sua_server_helper(); - sccp_test_server_init(sccp); + g_sccp = sua_server_helper(); + sccp_test_server_init(g_sccp); } while (1) { -- To view, visit https://gerrit.osmocom.org/2244 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I87caa76a2be3c92c93e419242595107d744bad97 Gerrit-PatchSet: 5 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Apr 10 11:27:01 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 11:27:01 +0000 Subject: [MERGED] libosmo-sccp[master]: xua_srv_conn_cb(): Print sctp_recvmsg flags (line in xua_cli... In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: xua_srv_conn_cb(): Print sctp_recvmsg flags (line in xua_cli_conn_cb()) ...................................................................... xua_srv_conn_cb(): Print sctp_recvmsg flags (line in xua_cli_conn_cb()) Change-Id: I91920c6ad665abc791a1dbf386d52cf0aece9133 --- M src/osmo_ss7.c 1 file changed, 2 insertions(+), 2 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index df85ea8..8ec099a 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -1163,8 +1163,8 @@ /* read xUA message from socket and process it */ rc = sctp_recvmsg(ofd->fd, msgb_data(msg), msgb_tailroom(msg), NULL, NULL, &sinfo, &flags); - LOGPASP(asp, DLSS7, LOGL_DEBUG, "%s(): sctp_recvmsg() returned %d\n", - __func__, rc); + LOGPASP(asp, DLSS7, LOGL_DEBUG, "%s(): sctp_recvmsg() returned %d (flags=0x%x)\n", + __func__, rc, flags); if (rc < 0) { osmo_stream_srv_destroy(conn); goto out; -- To view, visit https://gerrit.osmocom.org/2241 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I91920c6ad665abc791a1dbf386d52cf0aece9133 Gerrit-PatchSet: 5 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Apr 10 11:27:01 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 11:27:01 +0000 Subject: [MERGED] libosmo-sccp[master]: sigtran: fix various memory leaks (msgb and xua_msg) In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: sigtran: fix various memory leaks (msgb and xua_msg) ...................................................................... sigtran: fix various memory leaks (msgb and xua_msg) The general rule for 'struct xua_msg' is now that it is free'd by the function that also allocates it in the first place. Any downstream consumer of the xua_msg may interpret it, but not hold any references or free() it. Change-Id: I708505d129da5824c69b31a13a9c93201929bada --- M examples/sccp_test_server.c M examples/sccp_test_vty.c M src/m3ua.c M src/osmo_ss7_hmrt.c M src/sccp_sclc.c M src/sccp_scoc.c M src/sccp_scrc.c M src/sccp_user.c M src/sua.c 9 files changed, 33 insertions(+), 17 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/examples/sccp_test_server.c b/examples/sccp_test_server.c index c3c658f..71bed96 100644 --- a/examples/sccp_test_server.c +++ b/examples/sccp_test_server.c @@ -34,6 +34,7 @@ oph->primitive, oph->operation); break; } + msgb_free(oph->msg); return 0; } @@ -71,6 +72,7 @@ oph->primitive, oph->operation); break; } + msgb_free(oph->msg); return 0; } @@ -102,6 +104,7 @@ oph->primitive, oph->operation); break; } + msgb_free(oph->msg); return 0; } diff --git a/examples/sccp_test_vty.c b/examples/sccp_test_vty.c index 1134d57..ddfbb27 100644 --- a/examples/sccp_test_vty.c +++ b/examples/sccp_test_vty.c @@ -125,6 +125,7 @@ default: break; } + msgb_free(oph->msg); return 0; } diff --git a/src/m3ua.c b/src/m3ua.c index 7437b6e..4f20c6e 100644 --- a/src/m3ua.c +++ b/src/m3ua.c @@ -420,13 +420,12 @@ * Transmitting M3UA messsages to SCTP ***********************************************************************/ +/* transmit given xua_msg via given ASP. callee takes xua ownership */ static int m3ua_tx_xua_asp(struct osmo_ss7_asp *asp, struct xua_msg *xua) { struct msgb *msg = xua_to_msg(M3UA_VERSION, xua); OSMO_ASSERT(asp->cfg.proto == OSMO_SS7_ASP_PROT_M3UA); - - xua_msg_free(xua); if (!msg) { LOGP(DLM3UA, LOGL_ERROR, "Error encoding M3UA Msg\n"); @@ -461,7 +460,6 @@ } if (!asp) { LOGP(DLM3UA, LOGL_ERROR, "No ASP entroy in AS, dropping message\n"); - xua_msg_free(xua); return -ENODEV; } diff --git a/src/osmo_ss7_hmrt.c b/src/osmo_ss7_hmrt.c index bc2b8e5..105a542 100644 --- a/src/osmo_ss7_hmrt.c +++ b/src/osmo_ss7_hmrt.c @@ -195,6 +195,7 @@ struct osmo_mtp_prim *omp) { struct xua_msg *xua; + int rc; OSMO_ASSERT(omp->oph.sap == MTP_SAP_USER); @@ -210,10 +211,15 @@ * is a very useful feature (aka "loopback device" in * IPv4). So we call m3ua_hmdc_rx_from_l2() just like * the MTP-TRANSFER had been received from L2. */ - return m3ua_hmdc_rx_from_l2(inst, xua); + rc = m3ua_hmdc_rx_from_l2(inst, xua); + xua_msg_free(xua); + break; default: LOGP(DLSS7, LOGL_ERROR, "Ignoring unknown primitive %u:%u\n", omp->oph.primitive, omp->oph.operation); - return -1; + rc = -1; } + + msgb_free(omp->oph.msg); + return rc; } diff --git a/src/sccp_sclc.c b/src/sccp_sclc.c index dae2c36..7cdfac5 100644 --- a/src/sccp_sclc.c +++ b/src/sccp_sclc.c @@ -102,12 +102,15 @@ struct osmo_scu_prim *prim, int msg_type) { struct xua_msg *xua; + int rc; xua = xua_gen_msg_cl(event, prim, msg_type); if (!xua) return -1; - return sccp_scrc_rx_sclc_msg(scu->inst, xua); + rc = sccp_scrc_rx_sclc_msg(scu->inst, xua); + xua_msg_free(xua); + return rc; } /*! \brief Main entrance function for primitives from SCCP User @@ -327,8 +330,8 @@ /* local originator: send N-NOTICE to user */ /* TODO: N-NOTICE.ind SCLC -> SCU */ sclc_rx_cldr(inst, xua_out); - xua_msg_free(xua_out); } + xua_msg_free(xua_out); break; case SUA_CL_CLDR: /* do nothing */ diff --git a/src/sccp_scoc.c b/src/sccp_scoc.c index f881872..2585c9f 100644 --- a/src/sccp_scoc.c +++ b/src/sccp_scoc.c @@ -459,7 +459,9 @@ /* amend this with point code information; The SUA RELRE * includes neither called nor calling party address! */ xua->mtp.dpc = conn->remote_pc; - return sccp_scrc_rx_scoc_conn_msg(conn->inst, xua); + sccp_scrc_rx_scoc_conn_msg(conn->inst, xua); + xua_msg_free(xua); + return 0; } /* generate a 'struct xua_msg' of requested type from connection + @@ -593,7 +595,9 @@ /* amend this with point code information; Many CO msgs * includes neither called nor calling party address! */ xua->mtp.dpc = conn->remote_pc; - return sccp_scrc_rx_scoc_conn_msg(conn->inst, xua); + sccp_scrc_rx_scoc_conn_msg(conn->inst, xua); + xua_msg_free(xua); + return 0; } /* allocate a SCU primitive to be sent to the user */ diff --git a/src/sccp_scrc.c b/src/sccp_scrc.c index 0ab25cb..f9df075 100644 --- a/src/sccp_scrc.c +++ b/src/sccp_scrc.c @@ -384,8 +384,9 @@ return scrc_node_2(inst, xua, &called); /* TOOD: Coupling performed (not supported) */ - if (0) + if (0) { return scrc_node_2(inst, xua, &called); + } return scrc_local_out_common(inst, xua, &called); } @@ -412,6 +413,7 @@ return scrc_node_12(inst, xua, &called); } } + return scrc_local_out_common(inst, xua, &called); } @@ -450,8 +452,7 @@ if (hop_counter <= 1) { /* Error: hop-counter violation */ /* node 4 */ - return scrc_node_4(inst, xua, - SCCP_RETURN_CAUSE_HOP_COUNTER_VIOLATION); + return scrc_node_4(inst, xua, SCCP_RETURN_CAUSE_HOP_COUNTER_VIOLATION); } /* Decrement hop-counter */ hop_counter--; diff --git a/src/sccp_user.c b/src/sccp_user.c index bc03f4e..297d939 100644 --- a/src/sccp_user.c +++ b/src/sccp_user.c @@ -157,6 +157,7 @@ struct osmo_sccp_instance *inst = ctx; struct osmo_mtp_prim *omp = (struct osmo_mtp_prim *)oph; struct xua_msg *xua; + int rc; OSMO_ASSERT(oph->sap == MTP_SAP_USER); @@ -166,12 +167,14 @@ xua = osmo_sccp_to_xua(oph->msg); xua->mtp = omp->u.transfer; /* hand this primitive into SCCP via the SCRC code */ - return scrc_rx_mtp_xfer_ind_xua(inst, xua); + rc = scrc_rx_mtp_xfer_ind_xua(inst, xua); default: LOGP(DLSCCP, LOGL_ERROR, "Unknown primitive %u:%u receivd\n", oph->primitive, oph->operation); - return -1; + rc = -1; } + msgb_free(oph->msg); + return rc; } static LLIST_HEAD(sccp_instances); diff --git a/src/sua.c b/src/sua.c index b0d5f8a..2f8acf2 100644 --- a/src/sua.c +++ b/src/sua.c @@ -258,8 +258,6 @@ OSMO_ASSERT(asp->cfg.proto == OSMO_SS7_ASP_PROT_SUA); - xua_msg_free(xua); - if (!msg) { LOGPASP(asp, DLSUA, LOGL_ERROR, "Error encoding SUA Msg\n"); return -1; @@ -290,7 +288,6 @@ } if (!asp) { LOGP(DLSUA, LOGL_ERROR, "No ASP in AS, dropping message\n"); - xua_msg_free(xua); return -ENODEV; } -- To view, visit https://gerrit.osmocom.org/2242 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I708505d129da5824c69b31a13a9c93201929bada Gerrit-PatchSet: 5 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Apr 10 11:27:01 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 11:27:01 +0000 Subject: [MERGED] libosmo-sccp[master]: Add osmo_sccp_get_ss7() accessor function In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: Add osmo_sccp_get_ss7() accessor function ...................................................................... Add osmo_sccp_get_ss7() accessor function as 'struct osmo_sccp_instance' is opaque to the user application, it is useful to have an accessor function that resolves the ss7 instance used by the SCCP instance. Change-Id: I8057a6d69584239b9781c5cece42066293ea1dd6 --- M include/osmocom/sigtran/sccp_sap.h M src/sccp_user.c 2 files changed, 6 insertions(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/include/osmocom/sigtran/sccp_sap.h b/include/osmocom/sigtran/sccp_sap.h index a86f86a..fd25752 100644 --- a/include/osmocom/sigtran/sccp_sap.h +++ b/include/osmocom/sigtran/sccp_sap.h @@ -230,6 +230,7 @@ struct osmo_sccp_instance * osmo_sccp_instance_create(struct osmo_ss7_instance *ss7, void *priv); void osmo_sccp_instance_destroy(struct osmo_sccp_instance *inst); +struct osmo_ss7_instance *osmo_sccp_get_ss7(struct osmo_sccp_instance *sccp); void osmo_sccp_user_unbind(struct osmo_sccp_user *scu); void osmo_sccp_user_set_priv(struct osmo_sccp_user *scu, void *priv); diff --git a/src/sccp_user.c b/src/sccp_user.c index 297d939..9ed57d4 100644 --- a/src/sccp_user.c +++ b/src/sccp_user.c @@ -388,3 +388,8 @@ return NULL; } + +struct osmo_ss7_instance *osmo_sccp_get_ss7(struct osmo_sccp_instance *sccp) +{ + return sccp->ss7; +} -- To view, visit https://gerrit.osmocom.org/2243 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I8057a6d69584239b9781c5cece42066293ea1dd6 Gerrit-PatchSet: 5 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Apr 10 11:27:01 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 11:27:01 +0000 Subject: [MERGED] libosmo-sccp[master]: xua_cli_conn_cb: Print flags as hex, not decimal. In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: xua_cli_conn_cb: Print flags as hex, not decimal. ...................................................................... xua_cli_conn_cb: Print flags as hex, not decimal. Change-Id: Idcf861cfdc6c14d7d3bafbf2e243da5db6e2f3e6 --- M src/osmo_ss7.c 1 file changed, 1 insertion(+), 1 deletion(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index 2dbb94d..df85ea8 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -1246,7 +1246,7 @@ /* read xUA message from socket and process it */ rc = sctp_recvmsg(ofd->fd, msgb_data(msg), msgb_tailroom(msg), NULL, NULL, &sinfo, &flags); - LOGPASP(asp, DLSS7, LOGL_DEBUG, "%s(): sctp_recvmsg() returned %d (flags=%d)\n", + LOGPASP(asp, DLSS7, LOGL_DEBUG, "%s(): sctp_recvmsg() returned %d (flags=0x%x)\n", __func__, rc, flags); if (rc < 0) { osmo_stream_cli_reconnect(conn); -- To view, visit https://gerrit.osmocom.org/2240 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Idcf861cfdc6c14d7d3bafbf2e243da5db6e2f3e6 Gerrit-PatchSet: 5 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Apr 10 11:34:26 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 11:34:26 +0000 Subject: [PATCH] libosmo-sccp[master]: Add osmo-stp executable as new "Osmocom Signaling Transfer P... In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2281 to look at the new patch set (#2). Add osmo-stp executable as new "Osmocom Signaling Transfer Point" osmo-stp is able to define multiple M3UA and/or SUA application servers (AS) as well as application server processes (ASPs). Clients can then connect via M3UA or SUA, perform the respective ASPSM / ASPTM state changes and finally exchange MTP signaling such as ISUP or SCCP on top of it. Routing is currently only based on point codes (PC). Routing table is fully configurable with Destination PC and mask. Shortcomings: * xUA: only "override" traffic mode supported, no load-balance or broadcast * xUA: no SNM supported, i.e. DAVA/DUNA/... messages are neither parsed nor generated * SCCP: no Global Title based Routing (GTR) yet * SCCP: no Global Title Translatio (GTT) yet * no M2PA / M2UA sigtran dialects * no classic CS7 based signaling links(E1/T1 TDM) Change-Id: If32227b8d3127c6178e4ee45527ce65f69bc7b1e --- M .gitignore M Makefile.am M configure.ac M include/osmocom/sigtran/osmo_ss7.h M src/osmo_ss7.c A stp/Makefile.am A stp/internal.h R stp/osmo_ss7_vty.c A stp/stp_main.c 9 files changed, 413 insertions(+), 62 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/81/2281/2 diff --git a/.gitignore b/.gitignore index 83f1333..c38bac1 100644 --- a/.gitignore +++ b/.gitignore @@ -62,6 +62,8 @@ examples/m3ua_example +stp/osmo-stp + *.pc config.* diff --git a/Makefile.am b/Makefile.am index dd73ec2..ededdac 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,7 +1,7 @@ AUTOMAKE_OPTIONS = foreign dist-bzip2 1.6 AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -SUBDIRS = include src tests examples +SUBDIRS = include src tests examples stp pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = libosmo-sccp.pc libosmo-mtp.pc libosmo-sigtran.pc libosmo-xua.pc diff --git a/configure.ac b/configure.ac index 6dc0ebd..82c7ee8 100644 --- a/configure.ac +++ b/configure.ac @@ -70,5 +70,6 @@ tests/xua/Makefile tests/ss7/Makefile examples/Makefile + stp/Makefile Makefile) diff --git a/include/osmocom/sigtran/osmo_ss7.h b/include/osmocom/sigtran/osmo_ss7.h index cbc6a02..2d5eba9 100644 --- a/include/osmocom/sigtran/osmo_ss7.h +++ b/include/osmocom/sigtran/osmo_ss7.h @@ -9,6 +9,8 @@ #include #include +extern struct llist_head osmo_ss7_xua_servers; + struct osmo_ss7_instance; struct osmo_ss7_user; struct osmo_sccp_instance; diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index 103c05b..e55d55c 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -28,6 +28,7 @@ #include #include +#include #include #include @@ -52,7 +53,7 @@ static bool ss7_initialized = false; static LLIST_HEAD(ss7_instances); -static LLIST_HEAD(ss7_xua_servers); +LLIST_HEAD(osmo_ss7_xua_servers); static int32_t next_rctx = 1; struct value_string osmo_ss7_as_traffic_mode_vals[] = { @@ -1449,7 +1450,7 @@ struct osmo_xua_server *xs; OSMO_ASSERT(ss7_initialized); - llist_for_each_entry(xs, &ss7_xua_servers, list) { + llist_for_each_entry(xs, &osmo_ss7_xua_servers, list) { if (proto == xs->cfg.proto && local_port == xs->cfg.local.port) return xs; @@ -1498,7 +1499,7 @@ } oxs->inst = inst; - llist_add_tail(&oxs->list, &ss7_xua_servers); + llist_add_tail(&oxs->list, &osmo_ss7_xua_servers); return oxs; } diff --git a/stp/Makefile.am b/stp/Makefile.am new file mode 100644 index 0000000..81aa11c --- /dev/null +++ b/stp/Makefile.am @@ -0,0 +1,11 @@ +AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include +AM_CFLAGS=-Wall -g $(LIBOSMOCORE_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(LIBOSMONETIF_CFLAGS) $(COVERAGE_FLAGS) +AM_LDFLAGS=$(COVERAGE_LDFLAGS) + +EXTRA_DIST = internal.h + +bin_PROGRAMS = osmo-stp + +osmo_stp_SOURCES = stp_main.c osmo_ss7_vty.c +osmo_stp_LDADD = $(top_builddir)/src/libosmo-sigtran.la \ + $(LIBOSMOCORE_LIBS) $(LIBOSMOVTY_LIBS) diff --git a/stp/internal.h b/stp/internal.h new file mode 100644 index 0000000..0a434cc --- /dev/null +++ b/stp/internal.h @@ -0,0 +1,18 @@ +#pragma once + +#include + +enum stp_vty_node { + L_CS7_AS_NODE = _LAST_OSMOVTY_NODE + 1, + L_CS7_ASP_NODE, + L_CS7_SUA_NODE, + L_CS7_M3UA_NODE, + L_CS7_RTABLE_NODE, +}; + +int osmo_ss7_vty_init(void); +int osmo_ss7_vty_go_parent(struct vty *vty); +int osmo_ss7_is_config_node(struct vty *vty, int node); + +extern struct osmo_ss7_instance *g_s7i; + diff --git a/src/osmo_ss7_vty.c b/stp/osmo_ss7_vty.c similarity index 68% rename from src/osmo_ss7_vty.c rename to stp/osmo_ss7_vty.c index 80cd4d0..f8fb24b 100644 --- a/src/osmo_ss7_vty.c +++ b/stp/osmo_ss7_vty.c @@ -33,6 +33,9 @@ #include #include +#include + +#include "internal.h" #define CS7_STR "ITU-T Signaling System 7\n" #define PC_STR "Point Code\n" @@ -58,7 +61,7 @@ "Reserved Network\n" "Spare Network\n") { - struct osmo_ss7_instance *inst = FIXME; + struct osmo_ss7_instance *inst = g_s7i; int ni = get_string_value(ss7_network_indicator_vals, argv[0]); inst->cfg.network_indicator = ni; @@ -67,13 +70,13 @@ /* TODO: cs7 point-code format */ DEFUN(cs7_pc_format, cs7_pc_format_cmd, - "cs7 point-code format <1-24> [<1-23> [<1-22>]]", + "cs7 point-code format <1-24> [<1-23>] [<1-22>]", CS7_STR PC_STR "Configure Point Code Format\n" "Length of first PC component\n" "Length of second PC component\n" "Length of third PC component\n") { - struct osmo_ss7_instance *inst = FIXME; + struct osmo_ss7_instance *inst = g_s7i; int argind = 0; inst->cfg.pc_fmt.component_len[0] = atoi(argv[argind++]); @@ -96,7 +99,7 @@ CS7_STR PC_STR "Configure Point Code Format\n" "Default Point Code Format (3.8.3)\n") { - struct osmo_ss7_instance *inst = FIXME; + struct osmo_ss7_instance *inst = g_s7i; inst->cfg.pc_fmt.component_len[0] = 3; inst->cfg.pc_fmt.component_len[1] = 8; inst->cfg.pc_fmt.component_len[2] = 3; @@ -111,7 +114,7 @@ "Use dot as delimiter\n" "User dash as delimiter\n") { - struct osmo_ss7_instance *inst = FIXME; + struct osmo_ss7_instance *inst = g_s7i; if (!strcmp(argv[0], "dash")) inst->cfg.pc_fmt.delimiter = '-'; @@ -126,7 +129,7 @@ CS7_STR "Configure the local Point Code\n" "Point Code\n") { - struct osmo_ss7_instance *inst = FIXME; + struct osmo_ss7_instance *inst = g_s7i; uint32_t pc = osmo_ss7_pointcode_parse(inst, argv[0]); inst->cfg.primary_pc = pc; @@ -135,6 +138,40 @@ /* TODO: cs7 secondary-pc */ /* TODO: cs7 capability-pc */ + +static void write_one_ss7_inst(struct vty *vty, struct osmo_ss7_instance *inst) +{ + if (inst->cfg.network_indicator) + vty_out(vty, "cs7 network-indicator %s%s", + get_value_string(ss7_network_indicator_vals, + inst->cfg.network_indicator), + VTY_NEWLINE); + + if (inst->cfg.pc_fmt.component_len[0] != 3 || + inst->cfg.pc_fmt.component_len[1] != 8 || + inst->cfg.pc_fmt.component_len[2] != 3) { + vty_out(vty, "cs7 point-code format %u", + inst->cfg.pc_fmt.component_len[0]); + if (inst->cfg.pc_fmt.component_len[1]) + vty_out(vty, " %u", inst->cfg.pc_fmt.component_len[1]); + if (inst->cfg.pc_fmt.component_len[2]) + vty_out(vty, " %u", inst->cfg.pc_fmt.component_len[2]); + vty_out(vty, "%s", VTY_NEWLINE); + } + + if (inst->cfg.pc_fmt.delimiter != '.') + vty_out(vty, "cs7 point-code delimiter dash%s", VTY_NEWLINE); + + if (inst->cfg.primary_pc) + vty_out(vty, "cs7 point-code %s%s", + osmo_ss7_pointcode_print(inst, inst->cfg.primary_pc), + VTY_NEWLINE); +} + +static void config_write_cs7(struct vty *vty) +{ + write_one_ss7_inst(vty, g_s7i); +} /*********************************************************************** * Routing Table Configuration @@ -151,7 +188,7 @@ CS7_STR "Specify the name of the route table\n" "Name of the route table\n") { - struct osmo_ss7_instance *inst = FIXME; + struct osmo_ss7_instance *inst = g_s7i; struct osmo_ss7_route_table *rtable; rtable = inst->rtable_system; @@ -163,7 +200,7 @@ } DEFUN(cs7_rt_upd, cs7_rt_upd_cmd, - "update route POINT_CODE [MASK | LENGTH] linkset LS_NAME [priority PRIO] [qos-class (CLASS | default", + "update route POINT_CODE MASK linkset LS_NAME [priority PRIO] [qos-class (CLASS|default)]", "Update the Route\n" "Update the Route\n" "Destination Point Code\n" @@ -185,8 +222,10 @@ unsigned int argind; rt = osmo_ss7_route_create(rtable, dpc, mask, ls_name); - if (!rt) + if (!rt) { + vty_out(vty, "cannot create route%s", VTY_NEWLINE); return CMD_WARNING; + } argind = 3; if (argc > argind && !strcmp(argv[argind], "priority")) { @@ -203,7 +242,7 @@ } DEFUN(cs7_rt_rem, cs7_rt_rem_cmd, - "remove route POINT_CODE [MASK | LENGTH]", + "remove route POINT_CODE MASK", "Remove a Route\n" "Remove a Route\n" "Destination Point Code\n" @@ -216,19 +255,22 @@ uint32_t mask = osmo_ss7_pointcode_parse_mask_or_len(rtable->inst, argv[1]); rt = osmo_ss7_route_find_dpc_mask(rtable, dpc, mask); - if (!rt) + if (!rt) { + vty_out(vty, "cannot find route to be deleted%s", VTY_NEWLINE); return CMD_WARNING; + } osmo_ss7_route_destroy(rt); return CMD_SUCCESS; } -static int config_write_rtable(struct vty *vty) +static void write_one_rtable(struct vty *vty, struct osmo_ss7_route_table *rtable) { - struct osmo_ss7_route_table *rtable = vty->index; struct osmo_ss7_route *rt; vty_out(vty, "cs7 route-table %s%s", rtable->cfg.name, VTY_NEWLINE); + if (rtable->cfg.description) + vty_out(vty, " description %s%s", rtable->cfg.description, VTY_NEWLINE); llist_for_each_entry(rt, &rtable->routes, list) { vty_out(vty, " update route %s %s linkset %s", osmo_ss7_pointcode_print(rtable->inst, rt->cfg.pc), @@ -240,6 +282,16 @@ vty_out(vty, " qos-class %u", rt->cfg.qos_class); vty_out(vty, "%s", VTY_NEWLINE); } +} + +static int config_write_rtable(struct vty *vty) +{ + struct osmo_ss7_instance *inst = g_s7i; + struct osmo_ss7_route_table *rtable; + + llist_for_each_entry(rtable, &inst->rtable_list, list) + write_one_rtable(vty, rtable); + return 0; } @@ -259,7 +311,7 @@ "Configure/Enable SUA\n" "SCTP Port number for SUA\n") { - struct osmo_ss7_instance *inst = FIXME; + struct osmo_ss7_instance *inst = g_s7i; struct osmo_xua_server *xs; uint16_t port = atoi(argv[0]); @@ -272,6 +324,24 @@ vty->node = L_CS7_SUA_NODE; vty->index = xs; + return CMD_SUCCESS; +} + +DEFUN(no_cs7_sua, no_cs7_sua_cmd, + "no cs7 sua <0-65534>", + NO_STR CS7_STR "Disable SUA on given SCTP Port\n" + "SCTP Port number for SUA\n") +{ + struct osmo_ss7_instance *inst = g_s7i; + struct osmo_xua_server *xs; + uint16_t port = atoi(argv[0]); + + xs = osmo_ss7_xua_server_find(inst, OSMO_SS7_ASP_PROT_SUA, port); + if (!xs) { + vty_out(vty, "No SUA server for port %u found%s", port, VTY_NEWLINE); + return CMD_WARNING; + } + osmo_ss7_xua_server_destroy(xs); return CMD_SUCCESS; } @@ -291,12 +361,22 @@ return get_string_value(osmo_ss7_asp_protocol_vals, protocol); } +static void write_one_sua(struct vty *vty, struct osmo_xua_server *xs) +{ + vty_out(vty, "cs7 %s %u%s", + get_value_string(osmo_ss7_asp_protocol_vals, xs->cfg.proto), + xs->cfg.local.port, VTY_NEWLINE); + vty_out(vty, " local-ip %s%s", xs->cfg.local.host, VTY_NEWLINE); +} + + static int config_write_sua(struct vty *vty) { - struct osmo_xua_server *xs = vty->index; + struct osmo_xua_server *xs; - vty_out(vty, "cs7 sua %u%s", xs->cfg.local.port, VTY_NEWLINE); - vty_out(vty, " local-ip %s%s", xs->cfg.local.host, VTY_NEWLINE); + llist_for_each_entry(xs, &osmo_ss7_xua_servers, list) + write_one_sua(vty, xs); + return 0; } @@ -316,7 +396,7 @@ "Configure/Enable M3UA\n" "SCTP Port number for M3UA\n") { - struct osmo_ss7_instance *inst = FIXME; + struct osmo_ss7_instance *inst = g_s7i; struct osmo_xua_server *xs; uint16_t port = atoi(argv[0]); @@ -329,6 +409,24 @@ vty->node = L_CS7_M3UA_NODE; vty->index = xs; + return CMD_SUCCESS; +} + +DEFUN(no_cs7_m3ua, no_cs7_m3ua_cmd, + "no cs7 m3ua <0-65534>", + NO_STR CS7_STR "Disable M3UA on given SCTP Port\n" + "SCTP Port number for M3UA\n") +{ + struct osmo_ss7_instance *inst = g_s7i; + struct osmo_xua_server *xs; + uint16_t port = atoi(argv[0]); + + xs = osmo_ss7_xua_server_find(inst, OSMO_SS7_ASP_PROT_M3UA, port); + if (!xs) { + vty_out(vty, "No M3UA server for port %u found%s", port, VTY_NEWLINE); + return CMD_WARNING; + } + osmo_ss7_xua_server_destroy(xs); return CMD_SUCCESS; } @@ -345,10 +443,7 @@ static int config_write_m3ua(struct vty *vty) { - struct osmo_xua_server *xs = vty->index; - - vty_out(vty, "cs7 m3ua %u%s", xs->cfg.local.port, VTY_NEWLINE); - vty_out(vty, " local-ip %s%s", xs->cfg.local.host, VTY_NEWLINE); + /* see config_write_sua */ return 0; } @@ -363,7 +458,7 @@ }; DEFUN(cs7_asp, cs7_asp_cmd, - "cs7 asp NAME <0-65535> <0-65535> [m3ua | sua]", + "cs7 asp NAME <0-65535> <0-65535> (m3ua|sua)", CS7_STR "Configure Application Server Process\n" "Name of ASP\n" @@ -372,19 +467,24 @@ "M3UA Protocol\n" "SUA Protocol\n") { - struct osmo_ss7_instance *inst = FIXME; + struct osmo_ss7_instance *inst = g_s7i; const char *name = argv[0]; uint16_t remote_port = atoi(argv[1]); uint16_t local_port = atoi(argv[2]); enum osmo_ss7_asp_protocol protocol = parse_asp_proto(argv[3]); struct osmo_ss7_asp *asp; - if (protocol == OSMO_SS7_ASP_PROT_NONE) + if (protocol == OSMO_SS7_ASP_PROT_NONE) { + vty_out(vty, "invalid protocol '%s'%s", argv[3], VTY_NEWLINE); return CMD_WARNING; + } asp = osmo_ss7_asp_find_or_create(inst, name, remote_port, local_port, protocol); - if (!asp) + if (!asp) { + vty_out(vty, "cannot create ASP '%s'%s", name, VTY_NEWLINE); return CMD_WARNING; + } + asp->cfg.is_server = true; vty->node = L_CS7_ASP_NODE; vty->index = asp; @@ -392,9 +492,27 @@ return CMD_SUCCESS; } +DEFUN(no_cs7_asp, no_cs7_asp_cmd, + "no cs7 asp NAME", + NO_STR CS7_STR "Disable Application Server Process\n" + "Name of ASP\n") +{ + struct osmo_ss7_instance *inst = g_s7i; + const char *name = argv[0]; + struct osmo_ss7_asp *asp; + + asp = osmo_ss7_asp_find_by_name(inst, name); + if (!asp) { + vty_out(vty, "No ASP named '%s' found%s", name, VTY_NEWLINE); + return CMD_WARNING; + } + osmo_ss7_asp_destroy(asp); + return CMD_SUCCESS; +} + DEFUN(asp_remote_ip, asp_remote_ip_cmd, "remote-ip A.B.C.D", - "Specity Remote IP Address of ASP\n" + "Specify Remote IP Address of ASP\n" "Remote IP Address of ASP\n") { struct osmo_ss7_asp *asp = vty->index; @@ -404,7 +522,7 @@ DEFUN(asp_qos_clas, asp_qos_class_cmd, "qos-class <0-255>", - "Specity QoS Class of ASP\n" + "Specify QoS Class of ASP\n" "QoS Class of ASP\n") { struct osmo_ss7_asp *asp = vty->index; @@ -416,8 +534,8 @@ "block", "Allows a SCTP Association with ASP, but doesn't let it become active\n") { - struct osmo_ss7_asp *asp = vty->index; - vty_out(vty, "Not supported yet\n"); + /* TODO */ + vty_out(vty, "Not supported yet%s", VTY_NEWLINE); return CMD_WARNING; } @@ -425,23 +543,34 @@ "shutdown", "Terminates SCTP association; New associations will be rejected\n") { - struct osmo_ss7_asp *asp = vty->index; - vty_out(vty, "Not supported yet\n"); + /* TODO */ + vty_out(vty, "Not supported yet%s", VTY_NEWLINE); return CMD_WARNING; +} + +static void write_one_asp(struct vty *vty, struct osmo_ss7_asp *asp) +{ + vty_out(vty, "cs7 asp %s %u %u %s%s", + asp->cfg.name, asp->cfg.remote.port, asp->cfg.local.port, + osmo_ss7_asp_protocol_name(asp->cfg.proto), VTY_NEWLINE); + if (asp->cfg.description) + vty_out(vty, " description %s%s", asp->cfg.description, VTY_NEWLINE); + vty_out(vty, " remote-ip %s%s", asp->cfg.remote.host, VTY_NEWLINE); + if (asp->cfg.qos_class) + vty_out(vty, " qos-class %u%s", asp->cfg.qos_class, VTY_NEWLINE); } static int config_write_asp(struct vty *vty) { - struct osmo_ss7_asp *asp = vty->index; + struct osmo_ss7_instance *inst = g_s7i; + struct osmo_ss7_asp *asp; - vty_out(vty, "cs7 asp %s %u %u %s%s", - asp->cfg.name, asp->cfg.remote.port, asp->cfg.local.port, - osmo_ss7_asp_protocol_name(asp->cfg.proto), VTY_NEWLINE); - vty_out(vty, " remote-ip %s%s", asp->cfg.remote.host, VTY_NEWLINE); - if (asp->cfg.qos_class) - vty_out(vty, " qos-class %u%s", asp->cfg.qos_class, VTY_NEWLINE); + llist_for_each_entry(asp, &inst->asp_list, list) + write_one_asp(vty, asp); + return 0; } + /*********************************************************************** * Application Server @@ -454,27 +583,53 @@ }; DEFUN(cs7_as, cs7_as_cmd, - "cs7 as NAME [m3ua | sua]", + "cs7 as NAME (m3ua|sua)", CS7_STR "Configure an Application Server\n" "Name of the Application Server\n" "M3UA Application Server\n" "SUA Application Server\n") { + struct osmo_ss7_instance *inst = g_s7i; struct osmo_ss7_as *as; const char *name = argv[0]; enum osmo_ss7_asp_protocol protocol = parse_asp_proto(argv[1]); - if (protocol == OSMO_SS7_ASP_PROT_NONE) + if (protocol == OSMO_SS7_ASP_PROT_NONE) { + vty_out(vty, "invalid protocol '%s'%s", argv[3], VTY_NEWLINE); return CMD_WARNING; + } - /* FIXME */ + as = osmo_ss7_as_find_or_create(inst, name, protocol); + if (!as) { + vty_out(vty, "cannot create AS '%s'%s", name, VTY_NEWLINE); + return CMD_WARNING; + } + as->cfg.name = talloc_strdup(as, name); vty->node = L_CS7_AS_NODE; vty->index = as; vty->index_sub = &as->cfg.description; + return CMD_SUCCESS; +} + +DEFUN(no_cs7_as, no_cs7_as_cmd, + "no cs7 as NAME", + NO_STR CS7_STR "Disable Application Server\n" + "Name of AS\n") +{ + struct osmo_ss7_instance *inst = g_s7i; + const char *name = argv[0]; + struct osmo_ss7_as *as; + + as = osmo_ss7_as_find_by_name(inst, name); + if (!as) { + vty_out(vty, "No AS named '%s' found%s", name, VTY_NEWLINE); + return CMD_WARNING; + } + osmo_ss7_as_destroy(as); return CMD_SUCCESS; } @@ -486,8 +641,10 @@ { struct osmo_ss7_as *as = vty->index; - if (osmo_ss7_as_add_asp(as, argv[0])) + if (osmo_ss7_as_add_asp(as, argv[0])) { + vty_out(vty, "cannot find ASP '%s'%s", argv[0], VTY_NEWLINE); return CMD_WARNING; + } return CMD_SUCCESS; } @@ -499,8 +656,10 @@ { struct osmo_ss7_as *as = vty->index; - if (osmo_ss7_as_del_asp(as, argv[0])) + if (osmo_ss7_as_del_asp(as, argv[0])) { + vty_out(vty, "cannot find ASP '%s'%s", argv[0], VTY_NEWLINE); return CMD_WARNING; + } return CMD_SUCCESS; } @@ -516,7 +675,7 @@ struct osmo_ss7_as *as = vty->index; as->cfg.mode = get_string_value(osmo_ss7_as_traffic_mode_vals, argv[0]); - return CMD_WARNING; + return CMD_SUCCESS; } DEFUN(as_recov_tout, as_recov_tout_cmd, @@ -554,7 +713,7 @@ }; DEFUN(as_rout_key, as_rout_key_cmd, - "routing-key RCONTEXT DPC [si {aal2 | bicc | b-isup | h248 | isup | sat-isup | sccp | tup }] [ssn SSN]}", + "routing-key RCONTEXT DPC [si (aal2|bicc|b-isup|h248|isup|sat-isup|sccp|tup)] [ssn SSN]}", "Define a routing key\n" "Routing context number\n" "Destination Point Code\n" @@ -571,25 +730,21 @@ "Sub-System Number to match on\n") { struct osmo_ss7_as *as = vty->index; - uint32_t key = atoi(argv[0]); - struct osmo_ss7_routing_key *rkey; + struct osmo_ss7_routing_key *rkey = &as->cfg.routing_key; int argind; - rkey = osmo_ss7_rkey_find_or_create(as, key); - if (!rkey) - return CMD_WARNING; - + rkey->context = atoi(argv[0]); rkey->pc = osmo_ss7_pointcode_parse(as->inst, argv[1]); argind = 2; - if (!strcmp(argv[argind], "si")) { + if (argind < argc && !strcmp(argv[argind], "si")) { const char *si_str; argind++; si_str = argv[argind++]; /* parse numeric SI from string */ rkey->si = get_string_value(mtp_si_vals, si_str); } - if (!strcmp(argv[argind], "ssn")) { + if (argind < argc && !strcmp(argv[argind], "ssn")) { argind++; rkey->ssn = atoi(argv[argind]); } @@ -597,14 +752,15 @@ return CMD_SUCCESS; } -static int config_write_as(struct vty *vty) +static void write_one_as(struct vty *vty, struct osmo_ss7_as *as) { - struct osmo_ss7_as *as = vty->index; struct osmo_ss7_routing_key *rkey; unsigned int i; vty_out(vty, "cs7 as %s %s%s", as->cfg.name, osmo_ss7_asp_protocol_name(as->cfg.proto), VTY_NEWLINE); + if (as->cfg.description) + vty_out(vty, " description %s%s", as->cfg.description, VTY_NEWLINE); for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) { struct osmo_ss7_asp *asp = as->cfg.asps[i]; if (!asp) @@ -618,7 +774,8 @@ vty_out(vty, " recovery-timeout %u%s", as->cfg.recovery_timeout_msec, VTY_NEWLINE); } - vty_out(vty, " qos-class %u%s", as->cfg.qos_class, VTY_NEWLINE); + if (as->cfg.qos_class) + vty_out(vty, " qos-class %u%s", as->cfg.qos_class, VTY_NEWLINE); rkey = &as->cfg.routing_key; vty_out(vty, " routing-key %u %s", rkey->context, osmo_ss7_pointcode_print(as->inst, rkey->pc)); @@ -628,8 +785,62 @@ if (rkey->ssn) vty_out(vty, " ssn %u", rkey->ssn); vty_out(vty, "%s", VTY_NEWLINE); +} + +static int config_write_as(struct vty *vty) +{ + struct osmo_ss7_instance *inst = g_s7i; + struct osmo_ss7_as *as; + + /* HACK to call this here, as we cannot install additional + * 'save' code into the root CONFIG_NODE ... */ + config_write_cs7(vty); + + /* HACK to call this here, but we must make sure that the ASP + * are all configured before we reference them from the AS, and + * VTY code always stores the nodes in alphabetical order */ + + config_write_asp(vty); + + llist_for_each_entry(as, &inst->as_list, list) + write_one_as(vty, as); return 0; +} + +int osmo_ss7_vty_go_parent(struct vty *vty) +{ + struct osmo_ss7_asp *asp; + + switch (vty->node) { + case L_CS7_ASP_NODE: + asp = vty->index; + osmo_ss7_asp_restart(asp); + vty->node = CONFIG_NODE; + break; + case L_CS7_RTABLE_NODE: + case L_CS7_SUA_NODE: + case L_CS7_M3UA_NODE: + case L_CS7_AS_NODE: + default: + vty->node = CONFIG_NODE; + break; + } + return 0; +} + +int osmo_ss7_is_config_node(struct vty *vty, int node) +{ + switch (node) { + case L_CS7_ASP_NODE: + case L_CS7_RTABLE_NODE: + case L_CS7_SUA_NODE: + case L_CS7_M3UA_NODE: + case L_CS7_AS_NODE: + return 1; + default: + return 0; + } } int osmo_ss7_vty_init(void) @@ -650,16 +861,19 @@ install_node(&sua_node, config_write_sua); vty_install_default(L_CS7_SUA_NODE); install_element(CONFIG_NODE, &cs7_sua_cmd); + install_element(CONFIG_NODE, &no_cs7_sua_cmd); install_element(L_CS7_SUA_NODE, &sua_local_ip_cmd); install_node(&m3ua_node, config_write_m3ua); vty_install_default(L_CS7_M3UA_NODE); install_element(CONFIG_NODE, &cs7_m3ua_cmd); + install_element(CONFIG_NODE, &no_cs7_m3ua_cmd); install_element(L_CS7_M3UA_NODE, &m3ua_local_ip_cmd); - install_node(&asp_node, config_write_asp); + install_node(&asp_node, NULL); vty_install_default(L_CS7_ASP_NODE); install_element(CONFIG_NODE, &cs7_asp_cmd); + install_element(CONFIG_NODE, &no_cs7_asp_cmd); install_element(L_CS7_ASP_NODE, &cfg_description_cmd); install_element(L_CS7_ASP_NODE, &asp_remote_ip_cmd); install_element(L_CS7_ASP_NODE, &asp_qos_class_cmd); @@ -669,6 +883,7 @@ install_node(&as_node, config_write_as); vty_install_default(L_CS7_AS_NODE); install_element(CONFIG_NODE, &cs7_as_cmd); + install_element(CONFIG_NODE, &no_cs7_as_cmd); install_element(L_CS7_AS_NODE, &cfg_description_cmd); install_element(L_CS7_AS_NODE, &as_asp_cmd); install_element(L_CS7_AS_NODE, &as_no_asp_cmd); diff --git a/stp/stp_main.c b/stp/stp_main.c new file mode 100644 index 0000000..029c0b2 --- /dev/null +++ b/stp/stp_main.c @@ -0,0 +1,101 @@ +/* Osmocom STP (Signal Transfer Point) */ + +/* (C) 2015-2017 by Harald Welte + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "internal.h" + +struct osmo_ss7_instance *g_s7i; + +static const struct log_info_cat log_info_cat[] = { +}; + +static const struct log_info log_info = { + .cat = log_info_cat, + .num_cat = ARRAY_SIZE(log_info_cat), +}; + +/* Hack to enable debug logging for all relevant (used?) subsystems */ +static void init_logging(void) +{ + const int log_cats[] = { DLSS7, DLSUA, DLM3UA, DLSCCP, DLINP }; + unsigned int i; + + osmo_init_logging(&log_info); + + for (i = 0; i < ARRAY_SIZE(log_cats); i++) + log_set_category_filter(osmo_stderr_target, log_cats[i], 1, LOGL_DEBUG); +} + +static struct vty_app_info vty_info = { + .name = "osmo-stp", + .version = PACKAGE_VERSION, + .go_parent_cb = osmo_ss7_vty_go_parent, + .is_config_node = osmo_ss7_is_config_node, +}; + +int main(int argc, char **argv) +{ + char *config_file = "osmo-stp.cfg"; + int rc; + + init_logging(); + osmo_ss7_init(); + osmo_fsm_log_addr(false); + vty_init(&vty_info); + osmo_ss7_vty_init(); + + g_s7i = osmo_ss7_instance_find_or_create(NULL, 0); + + rc = vty_read_config_file(config_file, NULL); + if (rc < 0) { + fprintf(stderr, "Failed to parse the config file '%s'\n", + config_file); + exit(1); + } + + rc = telnet_init_dynif(NULL, NULL, vty_get_bind_addr(), OSMO_VTY_PORT_STP); + if (rc < 0) { + perror("Erro binding VTY port\n"); + exit(1); + } + + while (1) { + osmo_select_main(0); + } +} -- To view, visit https://gerrit.osmocom.org/2281 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: If32227b8d3127c6178e4ee45527ce65f69bc7b1e Gerrit-PatchSet: 2 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Apr 10 11:35:19 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 11:35:19 +0000 Subject: osmo-bts[master]: Handle TXT indication from OsmoPCU In-Reply-To: References: Message-ID: Patch Set 4: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2087 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I16e73198501487a5b1076bf83390b85538d5af73 Gerrit-PatchSet: 4 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Mon Apr 10 11:36:15 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Mon, 10 Apr 2017 11:36:15 +0000 Subject: [MERGED] osmo-bts[master]: Handle TXT indication from OsmoPCU In-Reply-To: References: Message-ID: Max has submitted this change and it was merged. Change subject: Handle TXT indication from OsmoPCU ...................................................................... Handle TXT indication from OsmoPCU * handle OML message * handle OsmoPCU version message * show stored PCU version in 'show bts ..' vty command Requires OpenBSc with I6710d53115f34634a7b70969cc05fd5c72ff8ab2. Change-Id: I16e73198501487a5b1076bf83390b85538d5af73 Related: OS#1614, 1615 --- M src/common/pcu_sock.c M src/common/vty.c 2 files changed, 28 insertions(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/common/pcu_sock.c b/src/common/pcu_sock.c index 85bc880..fa2c585 100644 --- a/src/common/pcu_sock.c +++ b/src/common/pcu_sock.c @@ -538,6 +538,28 @@ return rc; } +static int pcu_rx_txt_ind(struct gsm_bts *bts, + struct gsm_pcu_if_txt_ind *txt) +{ + switch (txt->type) { + case PCU_VERSION: + LOGP(DPCU, LOGL_INFO, "OsmoPCU version %s connected\n", + txt->text); + osmo_signal_dispatch(SS_FAIL, OSMO_EVT_PCU_VERS, txt->text); + osmo_strlcpy(bts->pcu_version, txt->text, MAX_VERSION_LENGTH); + break; + case PCU_OML_ALERT: + osmo_signal_dispatch(SS_FAIL, OSMO_EVT_EXT_ALARM, txt->text); + break; + default: + LOGP(DPCU, LOGL_ERROR, "Unknown TXT_IND type %u received\n", + txt->type); + return -EINVAL; + } + + return 0; +} + static int pcu_rx_act_req(struct gsm_bts *bts, struct gsm_pcu_if_act_req *act_req) { @@ -586,6 +608,9 @@ case PCU_IF_MSG_ACT_REQ: rc = pcu_rx_act_req(bts, &pcu_prim->u.act_req); break; + case PCU_IF_MSG_TXT_IND: + rc = pcu_rx_txt_ind(bts, &pcu_prim->u.txt_ind); + break; default: LOGP(DPCU, LOGL_ERROR, "Received unknwon PCU msg type %d\n", msg_type); diff --git a/src/common/vty.c b/src/common/vty.c index 3f736c9..a48f809 100644 --- a/src/common/vty.c +++ b/src/common/vty.c @@ -744,6 +744,9 @@ net_dump_nmstate(vty, &bts->mo.nm_state); vty_out(vty, " Site Mgr NM State: "); net_dump_nmstate(vty, &bts->site_mgr.mo.nm_state); + if (strnlen(bts->pcu_version, MAX_VERSION_LENGTH)) + vty_out(vty, " PCU version %s connected%s", + bts->pcu_version, VTY_NEWLINE); vty_out(vty, " Paging: Queue size %u, occupied %u, lifetime %us%s", paging_get_queue_max(btsb->paging_state), paging_queue_length(btsb->paging_state), paging_get_lifetime(btsb->paging_state), VTY_NEWLINE); -- To view, visit https://gerrit.osmocom.org/2087 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I16e73198501487a5b1076bf83390b85538d5af73 Gerrit-PatchSet: 4 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max From gerrit-no-reply at lists.osmocom.org Mon Apr 10 11:36:21 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 11:36:21 +0000 Subject: libosmo-sccp[master]: Add osmo-stp executable as new "Osmocom Signaling Transfer P... In-Reply-To: References: Message-ID: Patch Set 2: Code-Review-1 the debug logging hack should be removed, and the xua_servers public export needs to be revisited. -- To view, visit https://gerrit.osmocom.org/2281 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: If32227b8d3127c6178e4ee45527ce65f69bc7b1e Gerrit-PatchSet: 2 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Mon Apr 10 11:41:04 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 11:41:04 +0000 Subject: osmo-trx[master]: buildenv: Split up SSE3 and SSE4.1 code In-Reply-To: References: Message-ID: Patch Set 4: Code-Review+1 -- To view, visit https://gerrit.osmocom.org/2134 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I846e190e92f1258cd412d1b2d79b539e204e04b3 Gerrit-PatchSet: 4 Gerrit-Project: osmo-trx Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Mon Apr 10 11:44:14 2017 From: gerrit-no-reply at lists.osmocom.org (Pau Espin Pedrol) Date: Mon, 10 Apr 2017 11:44:14 +0000 Subject: [PATCH] openbsc[master]: nat: Use equal func in bsc_sccp Message-ID: Review at https://gerrit.osmocom.org/2285 nat: Use equal func in bsc_sccp It is defined in the file and used twice in there, so let's use it for all of them which makes code smaller and more clear. Change-Id: I9fac7cabedff74f8f6293ad8b54420229b80aa71 --- M openbsc/src/osmo-bsc_nat/bsc_sccp.c 1 file changed, 4 insertions(+), 6 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/85/2285/1 diff --git a/openbsc/src/osmo-bsc_nat/bsc_sccp.c b/openbsc/src/osmo-bsc_nat/bsc_sccp.c index 25c13d4..c6c265f 100644 --- a/openbsc/src/osmo-bsc_nat/bsc_sccp.c +++ b/openbsc/src/osmo-bsc_nat/bsc_sccp.c @@ -45,7 +45,7 @@ struct nat_sccp_connection *conn; llist_for_each_entry(conn, &nat->sccp_connections, list_entry) { - if (memcmp(ref, &conn->patched_ref, sizeof(*ref)) == 0) + if (equal(ref, &conn->patched_ref)) return -1; } @@ -91,7 +91,7 @@ llist_for_each_entry(conn, &bsc->nat->sccp_connections, list_entry) { if (conn->bsc != bsc) continue; - if (memcmp(&conn->real_ref, parsed->src_local_ref, sizeof(conn->real_ref)) != 0) + if (!equal(parsed->src_local_ref, &conn->real_ref)) continue; /* the BSC has reassigned the SRC ref and we failed to keep track */ @@ -159,9 +159,7 @@ struct nat_sccp_connection *conn; llist_for_each_entry(conn, &bsc->nat->sccp_connections, list_entry) { - if (memcmp(parsed->src_local_ref, - &conn->patched_ref, sizeof(conn->patched_ref)) == 0) { - + if (equal(parsed->src_local_ref, &conn->patched_ref)) { sccp_connection_destroy(conn); return; } @@ -241,7 +239,7 @@ struct nat_sccp_connection *conn; llist_for_each_entry(conn, &nat->sccp_connections, list_entry) { - if (memcmp(ref, &conn->real_ref, sizeof(*ref)) == 0) + if (equal(ref, &conn->real_ref)) return conn; } -- To view, visit https://gerrit.osmocom.org/2285 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I9fac7cabedff74f8f6293ad8b54420229b80aa71 Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Pau Espin Pedrol From gerrit-no-reply at lists.osmocom.org Mon Apr 10 12:06:06 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Mon, 10 Apr 2017 12:06:06 +0000 Subject: [PATCH] openbsc[master]: Move string - BTS type conversion to shared header Message-ID: Review at https://gerrit.osmocom.org/2286 Move string - BTS type conversion to shared header Move value_string definition and corresponding functions to shared header to make it re-usable by OsmoBTS. While at it - rename for consistency and make functions inline. Change-Id: Ida94725a6fce968443541e3526f48f13758031fd Related: OS#1614 --- M openbsc/include/openbsc/gsm_data_shared.h M openbsc/src/libbsc/bsc_vty.c M openbsc/src/libcommon/gsm_data.c 3 files changed, 21 insertions(+), 21 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/86/2286/1 diff --git a/openbsc/include/openbsc/gsm_data_shared.h b/openbsc/include/openbsc/gsm_data_shared.h index 242889a..ad5d05a 100644 --- a/openbsc/include/openbsc/gsm_data_shared.h +++ b/openbsc/include/openbsc/gsm_data_shared.h @@ -504,6 +504,26 @@ _NUM_BTS_VARIANT }; +static const struct value_string bts_type_names[_NUM_GSM_BTS_TYPE + 1] = { + { GSM_BTS_TYPE_UNKNOWN, "unknown" }, + { GSM_BTS_TYPE_BS11, "bs11" }, + { GSM_BTS_TYPE_NANOBTS, "nanobts" }, + { GSM_BTS_TYPE_RBS2000, "rbs2000" }, + { GSM_BTS_TYPE_NOKIA_SITE, "nokia_site" }, + { GSM_BTS_TYPE_OSMOBTS, "sysmobts" }, + { 0, NULL } +}; + +static inline enum gsm_bts_type str2btstype(const char *arg) +{ + return get_string_value(bts_type_names, arg); +} + +static inline const char *btstype2str(enum gsm_bts_type type) +{ + return get_value_string(bts_type_names, type); +} + struct vty; struct gsm_bts_model { diff --git a/openbsc/src/libbsc/bsc_vty.c b/openbsc/src/libbsc/bsc_vty.c index c1882fc..702af4a 100644 --- a/openbsc/src/libbsc/bsc_vty.c +++ b/openbsc/src/libbsc/bsc_vty.c @@ -1615,7 +1615,7 @@ struct gsm_bts *bts = vty->index; int rc; - rc = gsm_set_bts_type(bts, parse_btstype(argv[0])); + rc = gsm_set_bts_type(bts, str2btstype(argv[0])); if (rc < 0) return CMD_WARNING; diff --git a/openbsc/src/libcommon/gsm_data.c b/openbsc/src/libcommon/gsm_data.c index fd34793..8ec0be5 100644 --- a/openbsc/src/libcommon/gsm_data.c +++ b/openbsc/src/libcommon/gsm_data.c @@ -90,16 +90,6 @@ return NULL; } -const struct value_string bts_type_names[_NUM_GSM_BTS_TYPE+1] = { - { GSM_BTS_TYPE_UNKNOWN, "unknown" }, - { GSM_BTS_TYPE_BS11, "bs11" }, - { GSM_BTS_TYPE_NANOBTS, "nanobts" }, - { GSM_BTS_TYPE_RBS2000, "rbs2000" }, - { GSM_BTS_TYPE_NOKIA_SITE, "nokia_site" }, - { GSM_BTS_TYPE_OSMOBTS, "sysmobts" }, - { 0, NULL } -}; - const struct value_string bts_type_descs[_NUM_GSM_BTS_TYPE+1] = { { GSM_BTS_TYPE_UNKNOWN, "Unknown BTS Type" }, { GSM_BTS_TYPE_BS11, "Siemens BTS (BS-11 or compatible)" }, @@ -109,16 +99,6 @@ { GSM_BTS_TYPE_OSMOBTS, "sysmocom sysmoBTS" }, { 0, NULL } }; - -enum gsm_bts_type parse_btstype(const char *arg) -{ - return get_string_value(bts_type_names, arg); -} - -const char *btstype2str(enum gsm_bts_type type) -{ - return get_value_string(bts_type_names, type); -} struct gsm_bts_trx *gsm_bts_trx_by_nr(struct gsm_bts *bts, int nr) { -- To view, visit https://gerrit.osmocom.org/2286 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ida94725a6fce968443541e3526f48f13758031fd Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Max From gerrit-no-reply at lists.osmocom.org Mon Apr 10 12:23:55 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Mon, 10 Apr 2017 12:23:55 +0000 Subject: [PATCH] libosmocore[master]: Add SW Description (de)marshalling In-Reply-To: References: Message-ID: Hello Neels Hofmeyr, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2165 to look at the new patch set (#13). Add SW Description (de)marshalling * data structure representing 3GPP TS 52.021 ?9.4.62 SW Description * function to serialize it into msgb * function to deserialize it from buffer * functions to extract/estimate buffer size for SW Description * test harness (partially taken from OpenBSC) There are several similar functions to deal with SW Description in OpenBSC, there's also need to use similar functionality in OsmoBTS. Hence it's better to put the code into common library with proper tests and documentation. Change-Id: Ib63b6b5e83b8914864fc7edd789f8958cdc993cd Related: OS#1614 --- M .gitignore M include/osmocom/gsm/protocol/gsm_12_21.h M src/gsm/abis_nm.c M src/gsm/libosmogsm.map M tests/Makefile.am A tests/abis/abis_test.c A tests/abis/abis_test.ok M tests/testsuite.at 8 files changed, 416 insertions(+), 2 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/65/2165/13 diff --git a/.gitignore b/.gitignore index ecbcedd..4c6a78f 100644 --- a/.gitignore +++ b/.gitignore @@ -60,6 +60,7 @@ tests/testsuite tests/testsuite.dir/ tests/testsuite.log +tests/abis/abis_test tests/ctrl/ctrl_test tests/utils/utils_test tests/stats/stats_test diff --git a/include/osmocom/gsm/protocol/gsm_12_21.h b/include/osmocom/gsm/protocol/gsm_12_21.h index c88f0b1..aa36631 100644 --- a/include/osmocom/gsm/protocol/gsm_12_21.h +++ b/include/osmocom/gsm/protocol/gsm_12_21.h @@ -29,6 +29,7 @@ /*! \file gsm_12_21.h */ #include +#include #include /*! \brief generic header in front of every OML message according to TS 08.59 */ @@ -791,6 +792,20 @@ IPAC_BINF_CELL_ALLOC = (1 << 2), }; +/*! \brief 3GPP TS 52.021 ?9.4.62 SW Description */ +struct abis_nm_sw_desc { + uint8_t file_id[UINT8_MAX]; + uint8_t file_id_len; + + uint8_t file_version[UINT8_MAX]; + uint8_t file_version_len; +}; + +uint16_t abis_nm_sw_desc_len(const struct abis_nm_sw_desc *sw, bool put_sw_descr); +uint16_t abis_nm_put_sw_desc(struct msgb *msg, const struct abis_nm_sw_desc *sw, bool put_sw_descr); +uint32_t abis_nm_get_sw_desc_len(const uint8_t * buf, size_t len); +int abis_nm_get_sw_conf(const uint8_t * buf, size_t buf_len, struct abis_nm_sw_desc *sw, uint16_t sw_len); + struct msgb *abis_nm_fail_evt_rep(enum abis_nm_event_type t, enum abis_nm_severity s, enum abis_nm_pcause_type ct, diff --git a/src/gsm/abis_nm.c b/src/gsm/abis_nm.c index 934d7ce..58be5a7 100644 --- a/src/gsm/abis_nm.c +++ b/src/gsm/abis_nm.c @@ -751,6 +751,141 @@ return nmsg; } +/*! \brief Compute length of given 3GPP TS 52.021 ?9.4.62 SW Description. + * \param[in] sw SW Description struct + * \param[in] put_sw_descr boolean, whether to put NM_ATT_SW_DESCR IE or not + * \returns length of buffer space necessary to store sw + */ +uint16_t abis_nm_sw_desc_len(const struct abis_nm_sw_desc *sw, bool put_sw_desc) +{ + /* +3: type is 1-byte, length is 2-byte */ + return (put_sw_desc ? 1 : 0) + (sw->file_id_len + 3) + (sw->file_version_len + 3); +} + +/*! \brief Put given 3GPP TS 52.021 ?9.4.62 SW Description into msgb. + * \param[out] msg message buffer + * \param[in] sw SW Description struct + * \param[in] put_sw_descr boolean, whether to put NM_ATT_SW_DESCR IE or not + * \param[in] simulate boolean, whether to actually modify msg or not + * \returns length of buffer space necessary to store sw + */ +uint16_t abis_nm_put_sw_desc(struct msgb *msg, const struct abis_nm_sw_desc *sw, bool put_sw_desc) +{ + if (put_sw_desc) + msgb_v_put(msg, NM_ATT_SW_DESCR); + msgb_tl16v_put(msg, NM_ATT_FILE_ID, sw->file_id_len, sw->file_id); + msgb_tl16v_put(msg, NM_ATT_FILE_VERSION, sw->file_version_len, sw->file_version); + + return abis_nm_sw_desc_len(sw, put_sw_desc); +} + +/*! \brief Get length of first 3GPP TS 52.021 ?9.4.62 SW Description from buffer. + * \param[in] buf buffer, may contain several SW Descriptions + * \param[in] len buffer length + * \returns length if parsing succeeded, 0 otherwise + */ +uint32_t abis_nm_get_sw_desc_len(const uint8_t *buf, size_t len) +{ + uint16_t sw = 2; /* 1-byte SW tag + 1-byte FILE_* tag */ + + if (buf[0] != NM_ATT_SW_DESCR) + sw = 1; /* 1-byte FILE_* tag */ + + if (buf[sw - 1] != NM_ATT_FILE_ID && buf[sw - 1] != NM_ATT_FILE_VERSION) + return 0; + + /* + length of 1st FILE_* element + 1-byte tag + 2-byte length field of + 1st FILE_* element */ + sw += (osmo_load16be(buf + sw) + 3); + + /* + length of 2nd FILE_* element */ + sw += osmo_load16be(buf + sw); + + return sw + 2; /* + 2-byte length field of 2nd FILE_* element */ +} + +/*! \brief Parse single 3GPP TS 52.021 ?9.4.62 SW Description from buffer. + * \param[out] sw SW Description struct + * \param[in] buf buffer + * \param[in] len buffer length + * \returns 0 if parsing succeeded, negative error code otherwise + */ +static inline int abis_nm_get_sw_desc(struct abis_nm_sw_desc *sw, const uint8_t *buf, size_t length) +{ + int rc; + uint32_t len = abis_nm_get_sw_desc_len(buf, length); + static struct tlv_parsed tp; + const struct tlv_definition sw_tlvdef = { + .def = { + [NM_ATT_SW_DESCR] = { TLV_TYPE_TV }, + [NM_ATT_FILE_ID] = { TLV_TYPE_TL16V }, + [NM_ATT_FILE_VERSION] = { TLV_TYPE_TL16V }, + }, + }; + + /* Basic sanity check */ + if (len > length) + return -EFBIG; + + /* Note: current implementation of TLV parser fails on multilpe SW Descr: + we will only parse the first one */ + if (!len) + return -EINVAL; + + /* Note: the return value is ignored here because SW Description tag + itself is considered optional. */ + tlv_parse(&tp, &sw_tlvdef, buf, len, 0, 0); + + /* Parsing SW Description is tricky for current implementation of TLV + parser which fails to properly handle TV when V has following + structure: | TL16V | TL16V |. Hence, the need for 2nd call: */ + rc = tlv_parse(&tp, &sw_tlvdef, buf + TLVP_LEN(&tp, NM_ATT_SW_DESCR), len - TLVP_LEN(&tp, NM_ATT_SW_DESCR), + 0, 0); + + if (rc < 0) + return rc; + + if (!TLVP_PRESENT(&tp, NM_ATT_FILE_ID)) + return -EBADF; + + if (!TLVP_PRESENT(&tp, NM_ATT_FILE_VERSION)) + return -EBADMSG; + + sw->file_id_len = TLVP_LEN(&tp, NM_ATT_FILE_ID); + sw->file_version_len = TLVP_LEN(&tp, NM_ATT_FILE_VERSION); + + memcpy(sw->file_id, TLVP_VAL(&tp, NM_ATT_FILE_ID), sw->file_id_len); + memcpy(sw->file_version, TLVP_VAL(&tp, NM_ATT_FILE_VERSION), sw->file_version_len); + + return 0; +} + +/*! \brief Parse 3GPP TS 52.021 ?9.4.61 SW Configuration from buffer. + * \param[in] buf buffer + * \param[in] buf_len buffer length + * \param[out] sw SW Description struct array + * \param[in] sw_len Expected number of SW Description entries + * \returns 0 if parsing succeeded, negative error code otherwise + */ +int abis_nm_get_sw_conf(const uint8_t * buf, size_t buf_len, struct abis_nm_sw_desc *sw, uint16_t sw_len) +{ + int rc; + uint16_t len = 0, i; + for (i = 0; i < sw_len; i++) { + memset(&sw[i], 0, sizeof(sw[i])); + rc = abis_nm_get_sw_desc(&sw[i], buf + len, buf_len - len); + if (rc < 0) + return rc; + + len += abis_nm_get_sw_desc_len(buf + len, buf_len - len); + + if (len >= buf_len) + return i + 1; + } + + return i; +} + /*! \brief Obtain OML Channel Combination for phnsical channel config */ int abis_nm_chcomb4pchan(enum gsm_phys_chan_config pchan) { diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map index c825dd5..33806f9 100644 --- a/src/gsm/libosmogsm.map +++ b/src/gsm/libosmogsm.map @@ -31,6 +31,10 @@ abis_nm_pcause_type_names; abis_nm_msgtype_names; abis_nm_att_names; +abis_nm_sw_desc_len; +abis_nm_put_sw_desc; +abis_nm_get_sw_conf; +abis_nm_get_sw_desc_len; osmo_sitype_strs; osmo_c4; diff --git a/tests/Makefile.am b/tests/Makefile.am index 352b5a7..c726277 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -15,7 +15,7 @@ bitvec/bitvec_test msgb/msgb_test bits/bitcomp_test \ tlv/tlv_test gsup/gsup_test oap/oap_test fsm/fsm_test \ write_queue/wqueue_test socket/socket_test \ - coding/coding_test + coding/coding_test abis/abis_test if ENABLE_MSGFILE check_PROGRAMS += msgfile/msgfile_test @@ -42,6 +42,9 @@ auth_milenage_test_SOURCES = auth/milenage_test.c auth_milenage_test_LDADD = $(top_builddir)/src/libosmocore.la $(top_builddir)/src/gsm/libosmogsm.la + +abis_abis_test_SOURCES = abis/abis_test.c +abis_abis_test_LDADD = $(top_builddir)/src/libosmocore.la $(top_builddir)/src/gsm/libosmogsm.la ctrl_ctrl_test_SOURCES = ctrl/ctrl_test.c ctrl_ctrl_test_LDADD = $(top_builddir)/src/libosmocore.la $(top_builddir)/src/ctrl/libosmoctrl.la @@ -188,7 +191,7 @@ vty/vty_test.ok comp128/comp128_test.ok \ utils/utils_test.ok stats/stats_test.ok \ bitvec/bitvec_test.ok msgb/msgb_test.ok bits/bitcomp_test.ok \ - sim/sim_test.ok tlv/tlv_test.ok \ + sim/sim_test.ok tlv/tlv_test.ok abis/abis_test.ok \ gsup/gsup_test.ok gsup/gsup_test.err \ oap/oap_test.ok fsm/fsm_test.ok fsm/fsm_test.err \ write_queue/wqueue_test.ok socket/socket_test.ok \ diff --git a/tests/abis/abis_test.c b/tests/abis/abis_test.c new file mode 100644 index 0000000..a6fde2a --- /dev/null +++ b/tests/abis/abis_test.c @@ -0,0 +1,209 @@ +/* + * (C) 2012 by Holger Hans Peter Freyther + * (C) 2017 by sysmocom s.m.f.c. GmbH + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +static struct log_info info = {}; + +static const uint8_t simple_config[] = { 66, 18, 0, 3, 1, 2, 3, 19, 0, 3, 3, 4, 5 }; + +static const uint8_t dual_config[] = { + 66, 18, 0, 3, 1, 2, 3, 19, 0, 3, 3, 4, 5, + 66, 18, 0, 3, 9, 7, 5, 19, 0, 3, 6, 7, 8, +}; + +static void test_simple_sw_config(void) +{ + struct abis_nm_sw_desc desc[1]; + uint16_t len; + int rc; + + rc = abis_nm_get_sw_conf(simple_config, ARRAY_SIZE(simple_config), &desc[0], ARRAY_SIZE(desc)); + if (rc != 1) { + printf("%s(): FAILED to parse the File Id/File version: %d\n", __func__, rc); + abort(); + } + + len = abis_nm_sw_desc_len(&desc[0], true); + if (len != 13) { + printf("WRONG SIZE: %u\n", len); + abort(); + } + + printf("len: %u\n", len); + printf("file_id: %s\n", osmo_hexdump(desc[0].file_id, desc[0].file_id_len)); + printf("file_ver: %s\n", osmo_hexdump(desc[0].file_version, desc[0].file_version_len)); + printf("%s(): OK\n", __func__); +} + +static void test_simple_sw_short(void) +{ + struct abis_nm_sw_desc desc[1]; + int i; + + for (i = 1; i < ARRAY_SIZE(simple_config); ++i) { + int rc = abis_nm_get_sw_conf(simple_config, ARRAY_SIZE(simple_config) - i, &desc[0], ARRAY_SIZE(desc)); + if (rc >= 1) { + printf("SHOULD not have parsed: %d\n", rc); + abort(); + } + } + printf("%s(): OK\n", __func__); +} + +static void test_dual_sw_config(void) +{ + struct abis_nm_sw_desc desc[2]; + uint16_t len0, len1; + int rc; + + rc = abis_nm_get_sw_conf(dual_config, ARRAY_SIZE(dual_config), &desc[0], ARRAY_SIZE(desc)); + if (rc != 2) { + printf("%s(): FAILED to parse the File Id/File version: %d (%d,%d)\n", + __func__, -rc, EBADF, EBADMSG); + abort(); + } + + len0 = abis_nm_sw_desc_len(&desc[0], true); + if (len0 != 13) { + printf("WRONG SIZE0: %u\n", len0); + abort(); + } + + len1 = abis_nm_sw_desc_len(&desc[1], true); + if (len1 != 13) { + printf("WRONG SIZE1: %u\n", len1); + abort(); + } + + printf("len: %u\n", len0); + printf("file_id: %s\n", osmo_hexdump(desc[0].file_id, desc[0].file_id_len)); + printf("file_ver: %s\n", osmo_hexdump(desc[0].file_version, desc[0].file_version_len)); + + printf("len: %u\n", len1); + printf("file_id: %s\n", osmo_hexdump(desc[1].file_id, desc[1].file_id_len)); + printf("file_ver: %s\n", osmo_hexdump(desc[1].file_version, desc[1].file_version_len)); + printf("%s(): OK\n", __func__); +} + +static inline void print_chk(const char *what, uint8_t len1, uint8_t len2, const uint8_t *x1, const uint8_t *x2) +{ + int cmp = memcmp(x1, x2, len2); + printf("\tFILE %s [%u == %u -> %d, %s] %d => %s\n", what, len1, len2, len1 == len2, len1 != len2 ? "fail" : "ok", + cmp, cmp != 0 ? "FAIL" : "OK"); +} + +static inline void chk_descr(struct msgb *msg, struct abis_nm_sw_desc *put, const char *desc, bool header) +{ + int res; + struct abis_nm_sw_desc sw = { 0 }; + uint16_t len = abis_nm_put_sw_desc(msg, put, header); + + printf("msgb[%u] :: {msgb->len} %u == %u {len} - %s]:\n\tSW DESCR (%s)\n" + "\tlength: {extracted} %u = %u {expected} - %s, failsafe - %s\n", + msg->data_len, msg->len, len, len != msg->len ? "fail" : "ok", desc, + abis_nm_get_sw_desc_len(msgb_data(msg), msg->len), msg->len, + abis_nm_get_sw_desc_len(msgb_data(msg), msg->len) != msg->len ? "FAIL" : "OK", + len > put->file_version_len + put->file_id_len ? "OK" : "FAIL"); + + res = abis_nm_get_sw_conf(msgb_data(msg), msg->len, &sw, 1); + if (res < 0) + printf("\tSW DESCR (%s) parsing error code %d!\n", desc, -res); + else { + print_chk("ID", sw.file_id_len, put->file_id_len, sw.file_id, put->file_id); + print_chk("VERSION", sw.file_version_len, put->file_version_len, sw.file_version, put->file_version); + } +} + +static inline void chk_raw(const char *what, const uint8_t *data, uint16_t len) +{ + struct abis_nm_sw_desc sw = { 0 }; + int res = abis_nm_get_sw_conf(data, len, &sw, 1); + uint16_t xlen = abis_nm_get_sw_desc_len(data, len); + + printf("parsing chained %s <1st: %d, total: %d>\n\tSW Descr (%s)\n", osmo_hexdump(data, len), xlen, len, what); + + if (res < 0) + printf("\tFAIL: %d\n", -res); + else { + printf("\tFILE ID: [%d] %s => OK\n", sw.file_id_len, osmo_hexdump(sw.file_id, sw.file_id_len)); + printf("\tFILE VERSION: [%d] %s => OK\n", sw.file_version_len, + osmo_hexdump(sw.file_version, sw.file_version_len)); + } + + if (len != xlen) + chk_raw(" 2nd", data + xlen, len - xlen); +} + +static void test_sw_descr() +{ + const char *f_id = "TEST.L0L", *f_ver = "0.1.666~deadbeeffacefeed-dirty"; + uint8_t lf_id = strlen(f_id), lf_ver = strlen(f_ver); + uint8_t chain[] = { 0x42, 0x12, 0x00, 0x03, 0x01, 0x02, 0x03, 0x13, 0x00, 0x03, 0x03, 0x04, 0x05, 0x42, 0x12, + 0x00, 0x03, 0x09, 0x07, 0x05, 0x13, 0x00, 0x03, 0x06, 0x07, 0x08 }; + struct msgb *msg = msgb_alloc_headroom(4096, 128, "sw"); + struct abis_nm_sw_desc sw_put = { + .file_id_len = lf_id, + .file_version_len = lf_ver, + }; + + printf("Testing SW Description (de)serialization...\n"); + + memcpy(sw_put.file_id, f_id, lf_id); + memcpy(sw_put.file_version, f_ver, lf_ver); + + /* check that parsing |SW|ID|VER| works: */ + chk_descr(msg, &sw_put, "with header", true); + msgb_reset(msg); + + /* check that parsing |ID|VER| works: */ + chk_descr(msg, &sw_put, "without header", false); + + /* check that parsing |ID|VER|SW|ID|VER| fails - notice the lack of msgb_reset() to create bogus msgb data: */ + chk_descr(msg, &sw_put, "expected failure", true); + + /* check multiple, chained SW-descr: */ + chk_raw("half", chain, sizeof(chain) / 2); + chk_raw("full", chain, sizeof(chain)); +} + +int main(int argc, char **argv) +{ + osmo_init_logging(&info); + + test_sw_descr(); + test_simple_sw_config(); + test_simple_sw_short(); + test_dual_sw_config(); + + printf("OK.\n"); + + return 0; +} diff --git a/tests/abis/abis_test.ok b/tests/abis/abis_test.ok new file mode 100644 index 0000000..e6b626b --- /dev/null +++ b/tests/abis/abis_test.ok @@ -0,0 +1,41 @@ +Testing SW Description (de)serialization... +msgb[4096] :: {msgb->len} 45 == 45 {len} - ok]: + SW DESCR (with header) + length: {extracted} 45 = 45 {expected} - OK, failsafe - OK + FILE ID [8 == 8 -> 1, ok] 0 => OK + FILE VERSION [30 == 30 -> 1, ok] 0 => OK +msgb[4096] :: {msgb->len} 44 == 44 {len} - ok]: + SW DESCR (without header) + length: {extracted} 44 = 44 {expected} - OK, failsafe - OK + FILE ID [8 == 8 -> 1, ok] 0 => OK + FILE VERSION [30 == 30 -> 1, ok] 0 => OK +msgb[4096] :: {msgb->len} 89 == 45 {len} - fail]: + SW DESCR (expected failure) + length: {extracted} 44 = 89 {expected} - FAIL, failsafe - OK + FILE ID [8 == 8 -> 1, ok] 0 => OK + FILE VERSION [30 == 30 -> 1, ok] 0 => OK +parsing chained 42 12 00 03 01 02 03 13 00 03 03 04 05 <1st: 13, total: 13> + SW Descr (half) + FILE ID: [3] 01 02 03 => OK + FILE VERSION: [3] 03 04 05 => OK +parsing chained 42 12 00 03 01 02 03 13 00 03 03 04 05 42 12 00 03 09 07 05 13 00 03 06 07 08 <1st: 13, total: 26> + SW Descr (full) + FILE ID: [3] 01 02 03 => OK + FILE VERSION: [3] 03 04 05 => OK +parsing chained 42 12 00 03 09 07 05 13 00 03 06 07 08 <1st: 13, total: 13> + SW Descr ( 2nd) + FILE ID: [3] 09 07 05 => OK + FILE VERSION: [3] 06 07 08 => OK +len: 13 +file_id: 01 02 03 +file_ver: 03 04 05 +test_simple_sw_config(): OK +test_simple_sw_short(): OK +len: 13 +file_id: 01 02 03 +file_ver: 03 04 05 +len: 13 +file_id: 09 07 05 +file_ver: 06 07 08 +test_dual_sw_config(): OK +OK. diff --git a/tests/testsuite.at b/tests/testsuite.at index 64df724..7ee0164 100644 --- a/tests/testsuite.at +++ b/tests/testsuite.at @@ -9,6 +9,12 @@ AT_CHECK([$abs_top_builddir/tests/a5/a5_test], [0], [expout]) AT_CLEANUP +AT_SETUP([abis]) +AT_KEYWORDS([abis]) +cat $abs_srcdir/abis/abis_test.ok > expout +AT_CHECK([$abs_top_builddir/tests/abis/abis_test], [0], [expout], [ignore]) +AT_CLEANUP + AT_SETUP([ctrl]) AT_KEYWORDS([ctrl]) cat $abs_srcdir/ctrl/ctrl_test.ok > expout -- To view, visit https://gerrit.osmocom.org/2165 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ib63b6b5e83b8914864fc7edd789f8958cdc993cd Gerrit-PatchSet: 13 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Mon Apr 10 13:46:19 2017 From: gerrit-no-reply at lists.osmocom.org (Pau Espin Pedrol) Date: Mon, 10 Apr 2017 13:46:19 +0000 Subject: [PATCH] openbsc[master]: nat: Fix initial buffer size parameter for getline Message-ID: Review at https://gerrit.osmocom.org/2287 nat: Fix initial buffer size parameter for getline According to man, lineptr must be set to null AND n to 0. Change-Id: I36683884106b97ef697264716de13813c00da9bc --- M openbsc/src/osmo-bsc_nat/bsc_nat_rewrite_trie.c 1 file changed, 1 insertion(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/87/2287/1 diff --git a/openbsc/src/osmo-bsc_nat/bsc_nat_rewrite_trie.c b/openbsc/src/osmo-bsc_nat/bsc_nat_rewrite_trie.c index 9291c89..633fa87 100644 --- a/openbsc/src/osmo-bsc_nat/bsc_nat_rewrite_trie.c +++ b/openbsc/src/osmo-bsc_nat/bsc_nat_rewrite_trie.c @@ -169,7 +169,7 @@ { FILE *file; char *line = NULL; - size_t n = 2342; + size_t n = 0; struct nat_rewrite *res; file = fopen(filename, "r"); -- To view, visit https://gerrit.osmocom.org/2287 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I36683884106b97ef697264716de13813c00da9bc Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Pau Espin Pedrol From gerrit-no-reply at lists.osmocom.org Mon Apr 10 14:30:10 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Mon, 10 Apr 2017 14:30:10 +0000 Subject: [PATCH] openbsc[master]: Use libosmocore for SW Description parsing In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2166 to look at the new patch set (#7). Use libosmocore for SW Description parsing Requires libosmocore with Ib63b6b5e83b8914864fc7edd789f8958cdc993cd. Change-Id: Ib94db414e94a2a1f234ac6f1cb346dca1c7a8be3 --- M openbsc/include/openbsc/abis_nm.h M openbsc/src/ipaccess/ipaccess-config.c M openbsc/src/libbsc/abis_nm.c M openbsc/tests/abis/abis_test.c M openbsc/tests/abis/abis_test.ok 5 files changed, 40 insertions(+), 217 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/66/2166/7 diff --git a/openbsc/include/openbsc/abis_nm.h b/openbsc/include/openbsc/abis_nm.h index 2465452..0fe9d8e 100644 --- a/openbsc/include/openbsc/abis_nm.h +++ b/openbsc/include/openbsc/abis_nm.h @@ -68,18 +68,6 @@ int (*sw_act_req)(struct msgb *); }; -struct abis_nm_sw_descr { - /* where does it start? how long is it? */ - const uint8_t *start; - size_t len; - - /* the parsed data */ - const uint8_t *file_id; - uint16_t file_id_len; - const uint8_t *file_ver; - uint16_t file_ver_len; -}; - extern int abis_nm_rcvmsg(struct msgb *msg); int abis_nm_tlv_parse(struct tlv_parsed *tp, struct gsm_bts *bts, const uint8_t *buf, int len); @@ -181,9 +169,7 @@ void abis_nm_queue_send_next(struct gsm_bts *bts); /* for bs11_config. */ -int abis_nm_parse_sw_config(const uint8_t *data, const size_t len, - struct abis_nm_sw_descr *res, const int res_len); -int abis_nm_select_newest_sw(const struct abis_nm_sw_descr *sw, const size_t len); +int abis_nm_select_newest_sw(const struct abis_nm_sw_desc *sw, const size_t len); /* Helper functions for updating attributes */ int abis_nm_update_max_power_red(struct gsm_bts_trx *trx); diff --git a/openbsc/src/ipaccess/ipaccess-config.c b/openbsc/src/ipaccess/ipaccess-config.c index 0c3f888..8685a40 100644 --- a/openbsc/src/ipaccess/ipaccess-config.c +++ b/openbsc/src/ipaccess/ipaccess-config.c @@ -52,6 +52,7 @@ #include #include #include +#include struct gsm_network *bsc_gsmnet; @@ -70,17 +71,9 @@ static int found_trx = 0; static int loop_tests = 0; -struct sw_load { - uint8_t file_id[255]; - uint8_t file_id_len; - - uint8_t file_version[255]; - uint8_t file_version_len; -}; - static void *tall_ctx_config = NULL; -static struct sw_load *sw_load1 = NULL; -static struct sw_load *sw_load2 = NULL; +static struct abis_nm_sw_desc *sw_load1 = NULL; +static struct abis_nm_sw_desc *sw_load2 = NULL; /* static uint8_t prim_oml_attr[] = { 0x95, 0x00, 7, 0x88, 192, 168, 100, 11, 0x00, 0x00 }; @@ -344,19 +337,11 @@ msg->l3h = &msg->l2h[3]; /* activate software */ - if (sw_load1) { - msgb_v_put(msg, NM_ATT_SW_DESCR); - msgb_tl16v_put(msg, NM_ATT_FILE_ID, sw_load1->file_id_len, sw_load1->file_id); - msgb_tl16v_put(msg, NM_ATT_FILE_VERSION, sw_load1->file_version_len, - sw_load1->file_version); - } + if (sw_load1) + abis_nm_put_sw_desc(msg, sw_load1, true); - if (sw_load2) { - msgb_v_put(msg, NM_ATT_SW_DESCR); - msgb_tl16v_put(msg, NM_ATT_FILE_ID, sw_load2->file_id_len, sw_load2->file_id); - msgb_tl16v_put(msg, NM_ATT_FILE_VERSION, sw_load2->file_version_len, - sw_load2->file_version); - } + if (sw_load2) + abis_nm_put_sw_desc(msg, sw_load2, true); /* fill in the data */ msg->l2h[0] = NM_ATT_IPACC_CUR_SW_CFG; @@ -618,11 +603,11 @@ return 0; } -static struct sw_load *create_swload(struct sdp_header *header) +static struct abis_nm_sw_desc *create_swload(struct sdp_header *header) { - struct sw_load *load; + struct abis_nm_sw_desc *load; - load = talloc_zero(tall_ctx_config, struct sw_load); + load = talloc_zero(tall_ctx_config, struct abis_nm_sw_desc); strncpy((char *)load->file_id, header->firmware_info.sw_part, 20); load->file_id_len = strlen(header->firmware_info.sw_part) + 1; diff --git a/openbsc/src/libbsc/abis_nm.c b/openbsc/src/libbsc/abis_nm.c index 56b6fcf..67f28bf 100644 --- a/openbsc/src/libbsc/abis_nm.c +++ b/openbsc/src/libbsc/abis_nm.c @@ -413,93 +413,29 @@ /* Activate the specified software into the BTS */ static int ipacc_sw_activate(struct gsm_bts *bts, uint8_t obj_class, uint8_t i0, uint8_t i1, - uint8_t i2, const uint8_t *sw_desc, uint8_t swdesc_len) + uint8_t i2, const struct abis_nm_sw_desc *sw_desc) { struct abis_om_hdr *oh; struct msgb *msg = nm_msgb_alloc(); - uint8_t len = swdesc_len; - uint8_t *trailer; + uint16_t len = abis_nm_sw_desc_len(sw_desc, true); oh = (struct abis_om_hdr *) msgb_put(msg, ABIS_OM_FOM_HDR_SIZE); fill_om_fom_hdr(oh, len, NM_MT_ACTIVATE_SW, obj_class, i0, i1, i2); - - trailer = msgb_put(msg, swdesc_len); - memcpy(trailer, sw_desc, swdesc_len); + abis_nm_put_sw_desc(msg, sw_desc, true); return abis_nm_sendmsg(bts, msg); } -int abis_nm_parse_sw_config(const uint8_t *sw_descr, const size_t sw_descr_len, - struct abis_nm_sw_descr *desc, const int res_len) -{ - static const struct tlv_definition sw_descr_def = { - .def = { - [NM_ATT_FILE_ID] = { TLV_TYPE_TL16V, }, - [NM_ATT_FILE_VERSION] = { TLV_TYPE_TL16V, }, - }, - }; - - size_t pos = 0; - int desc_pos = 0; - - for (pos = 0; pos < sw_descr_len && desc_pos < res_len; ++desc_pos) { - uint8_t tag; - uint16_t tag_len; - const uint8_t *val; - int len; - - memset(&desc[desc_pos], 0, sizeof(desc[desc_pos])); - desc[desc_pos].start = &sw_descr[pos]; - - /* Classic TLV parsing doesn't work well with SW_DESCR because of it's - * nested nature and the fact you have to assume it contains only two sub - * tags NM_ATT_FILE_VERSION & NM_ATT_FILE_ID to parse it */ - if (sw_descr[pos] != NM_ATT_SW_DESCR) { - LOGP(DNM, LOGL_ERROR, - "SW_DESCR attribute identifier not found!\n"); - return -1; - } - - pos += 1; - len = tlv_parse_one(&tag, &tag_len, &val, - &sw_descr_def, &sw_descr[pos], sw_descr_len - pos); - if (len < 0 || (tag != NM_ATT_FILE_ID)) { - LOGP(DNM, LOGL_ERROR, - "FILE_ID attribute identifier not found!\n"); - return -2; - } - desc[desc_pos].file_id = val; - desc[desc_pos].file_id_len = tag_len; - pos += len; - - - len = tlv_parse_one(&tag, &tag_len, &val, - &sw_descr_def, &sw_descr[pos], sw_descr_len - pos); - if (len < 0 || (tag != NM_ATT_FILE_VERSION)) { - LOGP(DNM, LOGL_ERROR, - "FILE_VERSION attribute identifier not found!\n"); - return -3; - } - desc[desc_pos].file_ver = val; - desc[desc_pos].file_ver_len = tag_len; - pos += len; - - /* final size */ - desc[desc_pos].len = &sw_descr[pos] - desc[desc_pos].start; - } - - return desc_pos; -} - -int abis_nm_select_newest_sw(const struct abis_nm_sw_descr *sw_descr, - const size_t size) +int abis_nm_select_newest_sw(const struct abis_nm_sw_desc *sw_descr, + const size_t size) { int res = 0; int i; for (i = 1; i < size; ++i) { - if (memcmp(sw_descr[res].file_ver, sw_descr[i].file_ver, - OSMO_MIN(sw_descr[i].file_ver_len, sw_descr[res].file_ver_len)) < 0) { + if (memcmp(sw_descr[res].file_version, sw_descr[i].file_version, + OSMO_MIN(sw_descr[i].file_version_len, + sw_descr[res].file_version_len)) < 0) { res = i; } } @@ -515,7 +451,7 @@ struct tlv_parsed tp; const uint8_t *sw_config; int ret, sw_config_len, len; - struct abis_nm_sw_descr sw_descr[5]; + struct abis_nm_sw_desc sw_descr[5]; abis_nm_debugp_foh(DNM, foh); @@ -546,8 +482,8 @@ } /* Parse up to two sw descriptions from the data */ - len = abis_nm_parse_sw_config(sw_config, sw_config_len, - &sw_descr[0], ARRAY_SIZE(sw_descr)); + len = abis_nm_get_sw_conf(sw_config, sw_config_len, &sw_descr[0], + ARRAY_SIZE(sw_descr)); if (len <= 0) { LOGP(DNM, LOGL_ERROR, "Failed to parse SW Config.\n"); return -EINVAL; @@ -560,7 +496,7 @@ foh->obj_inst.bts_nr, foh->obj_inst.trx_nr, foh->obj_inst.ts_nr, - sw_descr[ret].start, sw_descr[ret].len); + &sw_descr[ret]); } /* Receive a CHANGE_ADM_STATE_ACK, parse the TLV and update local state */ diff --git a/openbsc/tests/abis/abis_test.c b/openbsc/tests/abis/abis_test.c index 496267f..591f835 100644 --- a/openbsc/tests/abis/abis_test.c +++ b/openbsc/tests/abis/abis_test.c @@ -22,21 +22,11 @@ #include #include +#include #include #include #include - -static const uint8_t simple_config[] = { - /*0, 13, */ - 66, 18, 0, 3, 1, 2, 3, 19, 0, 3, 3, 4, 5, -}; - -static const uint8_t dual_config[] = { - /*0, 26, */ - 66, 18, 0, 3, 1, 2, 3, 19, 0, 3, 3, 4, 5, - 66, 18, 0, 3, 9, 7, 5, 19, 0, 3, 6, 7, 8, -}; static const uint8_t load_config[] = { 0x42, 0x12, 0x00, 0x08, 0x31, 0x36, 0x38, 0x64, @@ -48,94 +38,29 @@ 0x33, 0x64, 0x31, 0x00 }; -static void test_simple_sw_config(void) -{ - struct abis_nm_sw_descr descr[1]; - int rc; - - rc = abis_nm_parse_sw_config(simple_config, ARRAY_SIZE(simple_config), - &descr[0], ARRAY_SIZE(descr)); - if (rc != 1) { - printf("FAILED to parse the File Id/File version\n"); - abort(); - } - - if (descr[0].len != 13) { - printf("WRONG SIZE: %zu\n", descr[0].len); - abort(); - } - - printf("Start: %td len: %zu\n", descr[0].start - simple_config, descr[0].len); - printf("file_id: %s\n", osmo_hexdump(descr[0].file_id, descr[0].file_id_len)); - printf("file_ver: %s\n", osmo_hexdump(descr[0].file_ver, descr[0].file_ver_len)); -} - -static void test_simple_sw_short(void) -{ - struct abis_nm_sw_descr descr[1]; - int i; - - for (i = 1; i < ARRAY_SIZE(simple_config); ++i) { - int rc = abis_nm_parse_sw_config(simple_config, - ARRAY_SIZE(simple_config) - i, &descr[0], - ARRAY_SIZE(descr)); - if (rc >= 1) { - printf("SHOULD not have parsed: %d\n", rc); - abort(); - } - } -} - -static void test_dual_sw_config(void) -{ - struct abis_nm_sw_descr descr[2]; - int rc; - - rc = abis_nm_parse_sw_config(dual_config, ARRAY_SIZE(dual_config), - &descr[0], ARRAY_SIZE(descr)); - if (rc != 2) { - printf("FAILED to parse the File Id/File version\n"); - abort(); - } - - if (descr[0].len != 13) { - printf("WRONG SIZE0: %zu\n", descr[0].len); - abort(); - } - - if (descr[1].len != 13) { - printf("WRONG SIZE1: %zu\n", descr[1].len); - abort(); - } - - printf("Start: %td len: %zu\n", descr[0].start - dual_config, descr[0].len); - printf("file_id: %s\n", osmo_hexdump(descr[0].file_id, descr[0].file_id_len)); - printf("file_ver: %s\n", osmo_hexdump(descr[0].file_ver, descr[0].file_ver_len)); - - printf("Start: %td len: %zu\n", descr[1].start - dual_config, descr[1].len); - printf("file_id: %s\n", osmo_hexdump(descr[1].file_id, descr[1].file_id_len)); - printf("file_ver: %s\n", osmo_hexdump(descr[1].file_ver, descr[1].file_ver_len)); -} - static void test_sw_selection(void) { - struct abis_nm_sw_descr descr[8], tmp; + struct abis_nm_sw_desc descr[8], tmp; + uint16_t len0, len1; int rc, pos; - rc = abis_nm_parse_sw_config(load_config, ARRAY_SIZE(load_config), + rc = abis_nm_get_sw_conf(load_config, ARRAY_SIZE(load_config), &descr[0], ARRAY_SIZE(descr)); if (rc != 2) { - printf("FAILED to parse the File Id/File version\n"); + printf("%s(): FAILED to parse the File Id/File version: %d\n", + __func__, rc); abort(); } - printf("Start: %td len: %zu\n", descr[0].start - load_config, descr[0].len); + len0 = abis_nm_sw_desc_len(&descr[0], true); + printf("len: %u\n", len0); printf("file_id: %s\n", osmo_hexdump(descr[0].file_id, descr[0].file_id_len)); - printf("file_ver: %s\n", osmo_hexdump(descr[0].file_ver, descr[0].file_ver_len)); + printf("file_ver: %s\n", osmo_hexdump(descr[0].file_version, descr[0].file_version_len)); - printf("Start: %td len: %zu\n", descr[1].start - load_config, descr[1].len); + len1 = abis_nm_sw_desc_len(&descr[1], true); + printf("len: %u\n", len1); printf("file_id: %s\n", osmo_hexdump(descr[1].file_id, descr[1].file_id_len)); - printf("file_ver: %s\n", osmo_hexdump(descr[1].file_ver, descr[1].file_ver_len)); + printf("file_ver: %s\n", osmo_hexdump(descr[1].file_version, descr[1].file_version_len)); /* start */ pos = abis_nm_select_newest_sw(descr, rc); @@ -155,14 +80,13 @@ abort(); } printf("SELECTED: %d\n", pos); + printf("%s(): OK\n", __func__); } int main(int argc, char **argv) { osmo_init_logging(&log_info); - test_simple_sw_config(); - test_simple_sw_short(); - test_dual_sw_config(); + test_sw_selection(); return EXIT_SUCCESS; diff --git a/openbsc/tests/abis/abis_test.ok b/openbsc/tests/abis/abis_test.ok index 2f99f9d..8418cad 100644 --- a/openbsc/tests/abis/abis_test.ok +++ b/openbsc/tests/abis/abis_test.ok @@ -1,17 +1,9 @@ -Start: 0 len: 13 -file_id: 01 02 03 -file_ver: 03 04 05 -Start: 0 len: 13 -file_id: 01 02 03 -file_ver: 03 04 05 -Start: 13 len: 13 -file_id: 09 07 05 -file_ver: 06 07 08 -Start: 0 len: 26 +len: 26 file_id: 31 36 38 64 34 37 32 00 file_ver: 76 32 30 30 62 31 34 33 64 30 00 -Start: 26 len: 26 +len: 26 file_id: 31 36 38 64 34 37 32 00 file_ver: 76 32 30 30 62 31 34 33 64 31 00 SELECTED: 1 SELECTED: 0 +test_sw_selection(): OK -- To view, visit https://gerrit.osmocom.org/2166 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ib94db414e94a2a1f234ac6f1cb346dca1c7a8be3 Gerrit-PatchSet: 7 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Apr 10 15:03:24 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Mon, 10 Apr 2017 15:03:24 +0000 Subject: [PATCH] osmo-bts[master]: Signal to BSC when PCU disconnects Message-ID: Review at https://gerrit.osmocom.org/2288 Signal to BSC when PCU disconnects Change-Id: I41a731bd719aee0bbb98d3236405fb3a7f3ddec0 Related: OS#1615 --- M src/common/pcu_sock.c 1 file changed, 1 insertion(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/88/2288/1 diff --git a/src/common/pcu_sock.c b/src/common/pcu_sock.c index fa2c585..daedb55 100644 --- a/src/common/pcu_sock.c +++ b/src/common/pcu_sock.c @@ -670,6 +670,7 @@ bts = llist_entry(state->net->bts_list.next, struct gsm_bts, list); LOGP(DPCU, LOGL_NOTICE, "PCU socket has LOST connection\n"); + osmo_signal_dispatch(SS_FAIL, OSMO_EVT_PCU_VERS, ""); close(bfd->fd); bfd->fd = -1; -- To view, visit https://gerrit.osmocom.org/2288 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I41a731bd719aee0bbb98d3236405fb3a7f3ddec0 Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max From gerrit-no-reply at lists.osmocom.org Mon Apr 10 15:06:53 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Mon, 10 Apr 2017 15:06:53 +0000 Subject: [PATCH] openbsc[master]: Save PCU version reported by BTS Message-ID: Review at https://gerrit.osmocom.org/2289 Save PCU version reported by BTS When BTS reports PCU disconnect - clear it. Change-Id: Idb32c73036413ee912f633604150ee17b611cfa7 Related: OS#1615 --- M openbsc/src/libbsc/abis_nm.c 1 file changed, 8 insertions(+), 8 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/89/2289/1 diff --git a/openbsc/src/libbsc/abis_nm.c b/openbsc/src/libbsc/abis_nm.c index 56b6fcf..85f6440 100644 --- a/openbsc/src/libbsc/abis_nm.c +++ b/openbsc/src/libbsc/abis_nm.c @@ -302,7 +302,7 @@ LOGPC(DNM, LOGL_ERROR, "\n"); } -static inline void handle_manufact_report(const struct gsm_bts *bts, +static inline void handle_manufact_report(struct gsm_bts *bts, const uint8_t *p_val, const char *type, const char *severity, const char *text) { @@ -310,23 +310,23 @@ switch (cause) { case OSMO_EVT_PCU_VERS: - if (text) + if (text) { LOGPC(DNM, LOGL_NOTICE, "BTS %u reported connected PCU version %s\n", bts->nr, text); - else + osmo_strlcpy(bts->pcu_version, text, MAX_VERSION_LENGTH); + } else { LOGPC(DNM, LOGL_ERROR, - "BTS %u sent %s without actual version string.\n", - bts->nr, - get_value_string(abis_mm_event_cause_names, - cause)); + "BTS %u reported PCU disconnection.\n", bts->nr); + bts->pcu_version[0] = '\0'; + } break; default: log_oml_fail_rep(bts, type, severity, p_val, text); }; } -static int rx_fail_evt_rep(struct msgb *mb, const struct gsm_bts *bts) +static int rx_fail_evt_rep(struct msgb *mb, struct gsm_bts *bts) { struct abis_om_hdr *oh = msgb_l2(mb); struct abis_om_fom_hdr *foh = msgb_l3(mb); -- To view, visit https://gerrit.osmocom.org/2289 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Idb32c73036413ee912f633604150ee17b611cfa7 Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Max From gerrit-no-reply at lists.osmocom.org Mon Apr 10 15:51:03 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 15:51:03 +0000 Subject: [PATCH] libosmo-netif[master]: stream.c: Fix endianness handling of PPID and STREAM_ID Message-ID: Review at https://gerrit.osmocom.org/2290 stream.c: Fix endianness handling of PPID and STREAM_ID In their infinite wisdom, the inventors of SCTP designed an API (the sockets API described in RFC6458), where some members are in host byte order (like the stream identifier), while other members are in network byte order (like the PPID). Let's handle this properly (we assumed both are network byte order), and also use 16-bit htons/ntohs fo the PPID, rather than htonl/ntohl. Change-Id: I777174ca2915c6de0063db41a745c71b4a09bbec --- M src/stream.c 1 file changed, 6 insertions(+), 6 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-netif refs/changes/90/2290/1 diff --git a/src/stream.c b/src/stream.c index f899a41..f5ead17 100644 --- a/src/stream.c +++ b/src/stream.c @@ -162,8 +162,8 @@ #ifdef HAVE_LIBSCTP case IPPROTO_SCTP: memset(&sinfo, 0, sizeof(sinfo)); - sinfo.sinfo_ppid = htonl(msgb_sctp_ppid(msg)); - sinfo.sinfo_stream = htonl(msgb_sctp_stream(msg)); + sinfo.sinfo_ppid = htons(msgb_sctp_ppid(msg)); + sinfo.sinfo_stream = msgb_sctp_stream(msg); ret = sctp_send(cli->ofd.fd, msg->data, msgb_length(msg), &sinfo, MSG_NOSIGNAL); break; @@ -692,8 +692,8 @@ #ifdef HAVE_LIBSCTP case IPPROTO_SCTP: memset(&sinfo, 0, sizeof(sinfo)); - sinfo.sinfo_ppid = htonl(msgb_sctp_ppid(msg)); - sinfo.sinfo_stream = htonl(msgb_sctp_stream(msg)); + sinfo.sinfo_ppid = htons(msgb_sctp_ppid(msg)); + sinfo.sinfo_stream = msgb_sctp_stream(msg); ret = sctp_send(conn->ofd.fd, msg->data, msgb_length(msg), &sinfo, MSG_NOSIGNAL); break; @@ -871,8 +871,8 @@ } return -EAGAIN; } - msgb_sctp_ppid(msg) = ntohl(sinfo.sinfo_ppid); - msgb_sctp_stream(msg) = ntohl(sinfo.sinfo_stream); + msgb_sctp_ppid(msg) = ntohs(sinfo.sinfo_ppid); + msgb_sctp_stream(msg) = sinfo.sinfo_stream; break; #endif case IPPROTO_TCP: -- To view, visit https://gerrit.osmocom.org/2290 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I777174ca2915c6de0063db41a745c71b4a09bbec Gerrit-PatchSet: 1 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Mon Apr 10 15:53:03 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 15:53:03 +0000 Subject: [PATCH] libosmo-sccp[master]: xUA: Fix endianness handling of PPID and STREAM_ID Message-ID: Review at https://gerrit.osmocom.org/2291 xUA: Fix endianness handling of PPID and STREAM_ID In their infinite wisdom, the inventors of SCTP designed an API (the sockets API described in RFC6458), where some members are in host byte order (like the stream identifier), while other members are in network byte order (like the PPID). Let's handle this properly (we assumed both are network byte order), and also use 16-bit htons/ntohs fo the PPID, rather than htonl/ntohl. Change-Id: I51c87314ef9ba6415e7e89980699ab07e787ed5d --- M src/osmo_ss7.c 1 file changed, 4 insertions(+), 4 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/91/2291/1 diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index 103c05b..aa331b9 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -1209,9 +1209,9 @@ goto out; } - ppid = ntohl(sinfo.sinfo_ppid); + ppid = ntohs(sinfo.sinfo_ppid); msgb_sctp_ppid(msg) = ppid; - msgb_sctp_stream(msg) = ntohl(sinfo.sinfo_stream); + msgb_sctp_stream(msg) = sinfo.sinfo_stream; msg->dst = asp; if (ppid == SUA_PPID && asp->cfg.proto == OSMO_SS7_ASP_PROT_SUA) @@ -1299,9 +1299,9 @@ if (rc == 0) goto out; - ppid = ntohl(sinfo.sinfo_ppid); + ppid = ntohs(sinfo.sinfo_ppid); msgb_sctp_ppid(msg) = ppid; - msgb_sctp_stream(msg) = ntohl(sinfo.sinfo_stream); + msgb_sctp_stream(msg) = sinfo.sinfo_stream; msg->dst = asp; if (ppid == SUA_PPID && asp->cfg.proto == OSMO_SS7_ASP_PROT_SUA) -- To view, visit https://gerrit.osmocom.org/2291 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I51c87314ef9ba6415e7e89980699ab07e787ed5d Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Mon Apr 10 15:53:04 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 15:53:04 +0000 Subject: [PATCH] libosmo-sccp[master]: (attempted) fix for SCCP CC without user data Message-ID: Review at https://gerrit.osmocom.org/2292 (attempted) fix for SCCP CC without user data Change-Id: If91edb526cbcd792ec5ebcb4518cf848feb69391 --- M src/sccp_scoc.c 1 file changed, 4 insertions(+), 4 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/92/2292/1 diff --git a/src/sccp_scoc.c b/src/sccp_scoc.c index 2585c9f..b05e071 100644 --- a/src/sccp_scoc.c +++ b/src/sccp_scoc.c @@ -486,7 +486,7 @@ if (conn->calling_addr.presence) xua_msg_add_sccp_addr(xua, SUA_IEI_SRC_ADDR, &conn->calling_addr); /* optional: hop count; importance; priority; credit */ - if (prim && msgb_l2(prim->oph.msg)) + if (prim && msgb_l2(prim->oph.msg) && msgb_l2len(prim->oph.msg)) xua_msg_add_data(xua, SUA_IEI_DATA, msgb_l2len(prim->oph.msg), msgb_l2(prim->oph.msg)); break; @@ -506,7 +506,7 @@ * parameter */ if (conn->calling_addr.presence) xua_msg_add_sccp_addr(xua, SUA_IEI_DEST_ADDR, &conn->calling_addr); - if (prim && msgb_l2(prim->oph.msg)) + if (prim && msgb_l2(prim->oph.msg) && msgb_l2len(prim->oph.msg)) xua_msg_add_data(xua, SUA_IEI_DATA, msgb_l2len(prim->oph.msg), msgb_l2(prim->oph.msg)); break; @@ -519,7 +519,7 @@ xua_msg_add_u32(xua, SUA_IEI_SRC_REF, conn->conn_id); xua_msg_add_u32(xua, SUA_IEI_CAUSE, SUA_CAUSE_T_RELEASE | prim->u.disconnect.cause); /* optional: importance */ - if (msgb_l2(prim->oph.msg)) + if (prim && msgb_l2(prim->oph.msg) && msgb_l2len(prim->oph.msg)) xua_msg_add_data(xua, SUA_IEI_DATA, msgb_l2len(prim->oph.msg), msgb_l2(prim->oph.msg)); break; @@ -563,7 +563,7 @@ xua_msg_add_sccp_addr(xua, SUA_IEI_DEST_ADDR, &conn->calling_addr); /* optional: importance */ /* optional: data */ - if (prim && msgb_l2(prim->oph.msg)) + if (prim && msgb_l2(prim->oph.msg) && msgb_l2len(prim->oph.msg)) xua_msg_add_data(xua, SUA_IEI_DATA, msgb_l2len(prim->oph.msg), msgb_l2(prim->oph.msg)); break; -- To view, visit https://gerrit.osmocom.org/2292 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: If91edb526cbcd792ec5ebcb4518cf848feb69391 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Mon Apr 10 15:54:05 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 15:54:05 +0000 Subject: libosmo-sccp[master]: xUA: Fix endianness handling of PPID and STREAM_ID In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2291 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I51c87314ef9ba6415e7e89980699ab07e787ed5d Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Mon Apr 10 15:54:19 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 15:54:19 +0000 Subject: libosmo-netif[master]: stream.c: Fix endianness handling of PPID and STREAM_ID In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2290 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I777174ca2915c6de0063db41a745c71b4a09bbec Gerrit-PatchSet: 1 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Mon Apr 10 15:54:24 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 15:54:24 +0000 Subject: [MERGED] libosmo-netif[master]: stream.c: Fix endianness handling of PPID and STREAM_ID In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: stream.c: Fix endianness handling of PPID and STREAM_ID ...................................................................... stream.c: Fix endianness handling of PPID and STREAM_ID In their infinite wisdom, the inventors of SCTP designed an API (the sockets API described in RFC6458), where some members are in host byte order (like the stream identifier), while other members are in network byte order (like the PPID). Let's handle this properly (we assumed both are network byte order), and also use 16-bit htons/ntohs fo the PPID, rather than htonl/ntohl. Change-Id: I777174ca2915c6de0063db41a745c71b4a09bbec --- M src/stream.c 1 file changed, 6 insertions(+), 6 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/stream.c b/src/stream.c index f899a41..f5ead17 100644 --- a/src/stream.c +++ b/src/stream.c @@ -162,8 +162,8 @@ #ifdef HAVE_LIBSCTP case IPPROTO_SCTP: memset(&sinfo, 0, sizeof(sinfo)); - sinfo.sinfo_ppid = htonl(msgb_sctp_ppid(msg)); - sinfo.sinfo_stream = htonl(msgb_sctp_stream(msg)); + sinfo.sinfo_ppid = htons(msgb_sctp_ppid(msg)); + sinfo.sinfo_stream = msgb_sctp_stream(msg); ret = sctp_send(cli->ofd.fd, msg->data, msgb_length(msg), &sinfo, MSG_NOSIGNAL); break; @@ -692,8 +692,8 @@ #ifdef HAVE_LIBSCTP case IPPROTO_SCTP: memset(&sinfo, 0, sizeof(sinfo)); - sinfo.sinfo_ppid = htonl(msgb_sctp_ppid(msg)); - sinfo.sinfo_stream = htonl(msgb_sctp_stream(msg)); + sinfo.sinfo_ppid = htons(msgb_sctp_ppid(msg)); + sinfo.sinfo_stream = msgb_sctp_stream(msg); ret = sctp_send(conn->ofd.fd, msg->data, msgb_length(msg), &sinfo, MSG_NOSIGNAL); break; @@ -871,8 +871,8 @@ } return -EAGAIN; } - msgb_sctp_ppid(msg) = ntohl(sinfo.sinfo_ppid); - msgb_sctp_stream(msg) = ntohl(sinfo.sinfo_stream); + msgb_sctp_ppid(msg) = ntohs(sinfo.sinfo_ppid); + msgb_sctp_stream(msg) = sinfo.sinfo_stream; break; #endif case IPPROTO_TCP: -- To view, visit https://gerrit.osmocom.org/2290 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I777174ca2915c6de0063db41a745c71b4a09bbec Gerrit-PatchSet: 1 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Apr 10 15:54:30 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 15:54:30 +0000 Subject: [MERGED] libosmo-sccp[master]: xUA: Fix endianness handling of PPID and STREAM_ID In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: xUA: Fix endianness handling of PPID and STREAM_ID ...................................................................... xUA: Fix endianness handling of PPID and STREAM_ID In their infinite wisdom, the inventors of SCTP designed an API (the sockets API described in RFC6458), where some members are in host byte order (like the stream identifier), while other members are in network byte order (like the PPID). Let's handle this properly (we assumed both are network byte order), and also use 16-bit htons/ntohs fo the PPID, rather than htonl/ntohl. Change-Id: I51c87314ef9ba6415e7e89980699ab07e787ed5d --- M src/osmo_ss7.c 1 file changed, 4 insertions(+), 4 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index 103c05b..aa331b9 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -1209,9 +1209,9 @@ goto out; } - ppid = ntohl(sinfo.sinfo_ppid); + ppid = ntohs(sinfo.sinfo_ppid); msgb_sctp_ppid(msg) = ppid; - msgb_sctp_stream(msg) = ntohl(sinfo.sinfo_stream); + msgb_sctp_stream(msg) = sinfo.sinfo_stream; msg->dst = asp; if (ppid == SUA_PPID && asp->cfg.proto == OSMO_SS7_ASP_PROT_SUA) @@ -1299,9 +1299,9 @@ if (rc == 0) goto out; - ppid = ntohl(sinfo.sinfo_ppid); + ppid = ntohs(sinfo.sinfo_ppid); msgb_sctp_ppid(msg) = ppid; - msgb_sctp_stream(msg) = ntohl(sinfo.sinfo_stream); + msgb_sctp_stream(msg) = sinfo.sinfo_stream; msg->dst = asp; if (ppid == SUA_PPID && asp->cfg.proto == OSMO_SS7_ASP_PROT_SUA) -- To view, visit https://gerrit.osmocom.org/2291 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I51c87314ef9ba6415e7e89980699ab07e787ed5d Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Apr 10 15:54:59 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 10 Apr 2017 15:54:59 +0000 Subject: libosmo-sccp[master]: (attempted) fix for SCCP CC without user data In-Reply-To: References: Message-ID: Patch Set 1: Code-Review-1 even if it fixes the issue, the commit message needs work -- To view, visit https://gerrit.osmocom.org/2292 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: If91edb526cbcd792ec5ebcb4518cf848feb69391 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Mon Apr 10 18:57:55 2017 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Mon, 10 Apr 2017 18:57:55 +0000 Subject: [PATCH] openbsc[master]: build: iu: use libosmo-sccp tag 'old_sua' Message-ID: Review at https://gerrit.osmocom.org/2293 build: iu: use libosmo-sccp tag 'old_sua' libosmo-sccp master is moving ahead, openbsc --enable-iu needs an older version. Change-Id: Id74a802fd2ca65f4b6c2079550fbb6b0af3e8340 --- M contrib/jenkins.sh 1 file changed, 5 insertions(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/93/2293/1 diff --git a/contrib/jenkins.sh b/contrib/jenkins.sh index 323ae04..0021947 100755 --- a/contrib/jenkins.sh +++ b/contrib/jenkins.sh @@ -17,9 +17,13 @@ export PKG_CONFIG_PATH="$inst/lib/pkgconfig:$PKG_CONFIG_PATH" export LD_LIBRARY_PATH="$inst/lib" +if [ "x$IU" = "x--enable-iu" ]; then + sccp_branch="old_sua" +fi + osmo-build-dep.sh libosmo-abis osmo-build-dep.sh libosmo-netif -osmo-build-dep.sh libosmo-sccp +osmo-build-dep.sh libosmo-sccp $sccp_branch PARALLEL_MAKE="" osmo-build-dep.sh libsmpp34 osmo-build-dep.sh openggsn -- To view, visit https://gerrit.osmocom.org/2293 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Id74a802fd2ca65f4b6c2079550fbb6b0af3e8340 Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From admin at opensuse.org Mon Apr 10 20:00:56 2017 From: admin at opensuse.org (OBS Notification) Date: Mon, 10 Apr 2017 20:00:56 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in Debian_8.0/x86_64 In-Reply-To: References: Message-ID: <58ebe4b155c4b_99c1156f8427445e@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/Debian_8.0/x86_64 Package network:osmocom:nightly/osmo-stp failed to build in Debian_8.0/x86_64 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 88s] CC vty_interface.o [ 89s] CC sctp_m3ua_client.o [ 89s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 89s] #include [ 89s] ^ [ 89s] compilation terminated. [ 89s] Makefile:475: recipe for target 'sctp_m3ua_client.o' failed [ 89s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 89s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 89s] Makefile:370: recipe for target 'all-recursive' failed [ 89s] make[2]: *** [all-recursive] Error 1 [ 89s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 89s] Makefile:310: recipe for target 'all' failed [ 89s] make[1]: *** [all] Error 2 [ 89s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 89s] dh_auto_build: make -j1 returned exit code 2 [ 89s] debian/rules:23: recipe for target 'build' failed [ 89s] make: *** [build] Error 2 [ 89s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 89s] [ 89s] lamb55 failed "build cellmgr-ng_1.4.7.20170410.dsc" at Mon Apr 10 20:00:47 UTC 2017. [ 89s] [ 89s] ### VM INTERACTION START ### [ 90s] Powering off. [ 90s] [ 75.918372] reboot: Power down [ 90s] ### VM INTERACTION END ### [ 90s] [ 90s] lamb55 failed "build cellmgr-ng_1.4.7.20170410.dsc" at Mon Apr 10 20:00:49 UTC 2017. [ 90s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Mon Apr 10 20:00:56 2017 From: admin at opensuse.org (OBS Notification) Date: Mon, 10 Apr 2017 20:00:56 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in xUbuntu_16.10/i586 In-Reply-To: References: Message-ID: <58ebe4b19cc9d_99c1156f842745b8@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/xUbuntu_16.10/i586 Package network:osmocom:nightly/osmo-stp failed to build in xUbuntu_16.10/i586 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 107s] ^~~~~~~ [ 107s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o vty_interface.o vty_interface.c [ 108s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o sctp_m3ua_client.o sctp_m3ua_client.c [ 108s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 108s] #include [ 108s] ^ [ 108s] compilation terminated. [ 108s] Makefile:485: recipe for target 'sctp_m3ua_client.o' failed [ 108s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 108s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 108s] Makefile:380: recipe for target 'all-recursive' failed [ 108s] make[2]: *** [all-recursive] Error 1 [ 108s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 108s] Makefile:321: recipe for target 'all' failed [ 108s] make[1]: *** [all] Error 2 [ 108s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 108s] dh_auto_build: make -j1 returned exit code 2 [ 108s] debian/rules:23: recipe for target 'build' failed [ 108s] make: *** [build] Error 2 [ 108s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 108s] [ 108s] cloud129 failed "build cellmgr-ng_1.4.7.20170410.dsc" at Mon Apr 10 20:00:50 UTC 2017. [ 108s] [ 108s] ### VM INTERACTION START ### [ 111s] [ 88.460516] reboot: Power down [ 113s] ### VM INTERACTION END ### [ 113s] [ 113s] cloud129 failed "build cellmgr-ng_1.4.7.20170410.dsc" at Mon Apr 10 20:00:55 UTC 2017. [ 113s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Mon Apr 10 20:02:22 2017 From: admin at opensuse.org (OBS Notification) Date: Mon, 10 Apr 2017 20:02:22 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in Debian_8.0/i586 In-Reply-To: References: Message-ID: <58ebe4edee8ed_98f1156f8425018a@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/Debian_8.0/i586 Package network:osmocom:nightly/osmo-stp failed to build in Debian_8.0/i586 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 90s] CC vty_interface.o [ 90s] CC sctp_m3ua_client.o [ 90s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 90s] #include [ 90s] ^ [ 90s] compilation terminated. [ 90s] Makefile:475: recipe for target 'sctp_m3ua_client.o' failed [ 90s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 90s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 90s] Makefile:370: recipe for target 'all-recursive' failed [ 90s] make[2]: *** [all-recursive] Error 1 [ 90s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 90s] Makefile:310: recipe for target 'all' failed [ 90s] make[1]: *** [all] Error 2 [ 90s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 90s] dh_auto_build: make -j1 returned exit code 2 [ 90s] debian/rules:23: recipe for target 'build' failed [ 90s] make: *** [build] Error 2 [ 90s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 90s] [ 90s] lamb25 failed "build cellmgr-ng_1.4.7.20170410.dsc" at Mon Apr 10 20:02:06 UTC 2017. [ 90s] [ 90s] ### VM INTERACTION START ### [ 92s] Powering off. [ 92s] [ 77.151022] reboot: Power down [ 92s] ### VM INTERACTION END ### [ 92s] [ 92s] lamb25 failed "build cellmgr-ng_1.4.7.20170410.dsc" at Mon Apr 10 20:02:08 UTC 2017. [ 92s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Mon Apr 10 20:02:22 2017 From: admin at opensuse.org (OBS Notification) Date: Mon, 10 Apr 2017 20:02:22 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in xUbuntu_16.04/x86_64 In-Reply-To: References: Message-ID: <58ebe4ee6b462_98f1156f842502d6@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/xUbuntu_16.04/x86_64 Package network:osmocom:nightly/osmo-stp failed to build in xUbuntu_16.04/x86_64 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 127s] sctp_m2ua.c:91:3: warning: #warning "Notify any other AS(P) for failover scenario" [-Wcpp] [ 127s] #warning "Notify any other AS(P) for failover scenario" [ 127s] ^ [ 127s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -c -o vty_interface.o vty_interface.c [ 128s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -c -o sctp_m3ua_client.o sctp_m3ua_client.c [ 128s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 128s] compilation terminated. [ 128s] Makefile:485: recipe for target 'sctp_m3ua_client.o' failed [ 128s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 128s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 128s] Makefile:380: recipe for target 'all-recursive' failed [ 128s] make[2]: *** [all-recursive] Error 1 [ 128s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 128s] Makefile:321: recipe for target 'all' failed [ 128s] make[1]: *** [all] Error 2 [ 128s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 128s] dh_auto_build: make -j1 returned exit code 2 [ 128s] debian/rules:23: recipe for target 'build' failed [ 128s] make: *** [build] Error 2 [ 128s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 128s] [ 128s] cloud122 failed "build cellmgr-ng_1.4.7.20170410.dsc" at Mon Apr 10 20:02:16 UTC 2017. [ 128s] [ 128s] ### VM INTERACTION START ### [ 131s] [ 106.433850] reboot: Power down [ 133s] ### VM INTERACTION END ### [ 133s] [ 133s] cloud122 failed "build cellmgr-ng_1.4.7.20170410.dsc" at Mon Apr 10 20:02:21 UTC 2017. [ 133s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Mon Apr 10 20:02:39 2017 From: admin at opensuse.org (OBS Notification) Date: Mon, 10 Apr 2017 20:02:39 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in xUbuntu_16.10/x86_64 In-Reply-To: References: Message-ID: <58ebe4eec263c_98f1156f842503ee@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/xUbuntu_16.10/x86_64 Package network:osmocom:nightly/osmo-stp failed to build in xUbuntu_16.10/x86_64 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 75s] ^~~~~~~ [ 75s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o vty_interface.o vty_interface.c [ 76s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o sctp_m3ua_client.o sctp_m3ua_client.c [ 76s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 76s] #include [ 76s] ^ [ 76s] compilation terminated. [ 76s] Makefile:485: recipe for target 'sctp_m3ua_client.o' failed [ 76s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 76s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 76s] Makefile:380: recipe for target 'all-recursive' failed [ 76s] make[2]: *** [all-recursive] Error 1 [ 76s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 76s] Makefile:321: recipe for target 'all' failed [ 76s] make[1]: *** [all] Error 2 [ 76s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 76s] dh_auto_build: make -j1 returned exit code 2 [ 76s] debian/rules:23: recipe for target 'build' failed [ 76s] make: *** [build] Error 2 [ 76s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 76s] [ 76s] lamb23 failed "build cellmgr-ng_1.4.7.20170410.dsc" at Mon Apr 10 20:02:24 UTC 2017. [ 76s] [ 76s] ### VM INTERACTION START ### [ 79s] [ 65.465808] reboot: Power down [ 79s] ### VM INTERACTION END ### [ 79s] [ 79s] lamb23 failed "build cellmgr-ng_1.4.7.20170410.dsc" at Mon Apr 10 20:02:27 UTC 2017. [ 79s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Mon Apr 10 20:02:56 2017 From: admin at opensuse.org (OBS Notification) Date: Mon, 10 Apr 2017 20:02:56 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in xUbuntu_16.04/i586 In-Reply-To: References: Message-ID: <58ebe50d3e273_9961156f8431396a@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/xUbuntu_16.04/i586 Package network:osmocom:nightly/osmo-stp failed to build in xUbuntu_16.04/i586 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 93s] sctp_m2ua.c:91:3: warning: #warning "Notify any other AS(P) for failover scenario" [-Wcpp] [ 93s] #warning "Notify any other AS(P) for failover scenario" [ 93s] ^ [ 93s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -c -o vty_interface.o vty_interface.c [ 94s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -c -o sctp_m3ua_client.o sctp_m3ua_client.c [ 94s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 94s] compilation terminated. [ 94s] Makefile:485: recipe for target 'sctp_m3ua_client.o' failed [ 94s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 94s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 94s] Makefile:380: recipe for target 'all-recursive' failed [ 94s] make[2]: *** [all-recursive] Error 1 [ 94s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 94s] Makefile:321: recipe for target 'all' failed [ 94s] make[1]: *** [all] Error 2 [ 94s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 94s] dh_auto_build: make -j1 returned exit code 2 [ 94s] debian/rules:23: recipe for target 'build' failed [ 94s] make: *** [build] Error 2 [ 94s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 94s] [ 94s] lamb74 failed "build cellmgr-ng_1.4.7.20170410.dsc" at Mon Apr 10 20:02:36 UTC 2017. [ 94s] [ 94s] ### VM INTERACTION START ### [ 97s] [ 83.368477] reboot: Power down [ 97s] ### VM INTERACTION END ### [ 97s] [ 97s] lamb74 failed "build cellmgr-ng_1.4.7.20170410.dsc" at Mon Apr 10 20:02:39 UTC 2017. [ 97s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From gerrit-no-reply at lists.osmocom.org Tue Apr 11 00:35:52 2017 From: gerrit-no-reply at lists.osmocom.org (Tom Tsou) Date: Tue, 11 Apr 2017 00:35:52 +0000 Subject: libosmocore[master]: core/conv: implement optimized Viterbi decoder In-Reply-To: References: Message-ID: Patch Set 6: Code-Review+1 Verified+1 -- To view, visit https://gerrit.osmocom.org/1337 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I74d355274b4176a7d924f91ef3c96912ce338fb2 Gerrit-PatchSet: 6 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Vadim Yanitskiy Gerrit-Reviewer: Alexander Chemeris Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Tom Tsou Gerrit-Reviewer: Vadim Yanitskiy Gerrit-Reviewer: tnt Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Apr 11 00:36:16 2017 From: gerrit-no-reply at lists.osmocom.org (Tom Tsou) Date: Tue, 11 Apr 2017 00:36:16 +0000 Subject: [MERGED] libosmocore[master]: core/conv: implement optimized Viterbi decoder In-Reply-To: References: Message-ID: Tom Tsou has submitted this change and it was merged. Change subject: core/conv: implement optimized Viterbi decoder ...................................................................... core/conv: implement optimized Viterbi decoder Add a separate, faster convolution decoding implementation for rates up to N=4 and constraint lengths of K=5 and K=7, which covers the most GSM code uses. The decoding algorithm exploits the symmetric structure of the Viterbi add-compare-select (ACS) operation - commonly known as the ACS butterfly. This shift-register optimization can be found in the well-known text by Dave Forney. Forney, G.D., "The Viterbi Algorithm," Proc. of the IEEE, March 1973. Implementation is non-architecture specific and improves performance on x86 as well as ARM processors. Existing API is unchanged with optimized code being called internally for supported codes. The original code was relicensed under GPLv2-or-later with permission of copyright holder - Tom Tsou. Change-Id: I74d355274b4176a7d924f91ef3c96912ce338fb2 --- M src/Makefile.am M src/conv.c A src/viterbi.c A src/viterbi_gen.c 4 files changed, 806 insertions(+), 1 deletion(-) Approvals: tnt: Looks good to me, but someone else must approve Tom Tsou: Looks good to me, but someone else must approve; Verified Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/Makefile.am b/src/Makefile.am index 0cf2665..6948e1a 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -16,7 +16,8 @@ gsmtap_util.c crc16.c panic.c backtrace.c \ conv.c application.c rbtree.c strrb.c \ loggingrb.c crc8gen.c crc16gen.c crc32gen.c crc64gen.c \ - macaddr.c stat_item.c stats.c stats_statsd.c prim.c + macaddr.c stat_item.c stats.c stats_statsd.c prim.c \ + viterbi.c viterbi_gen.c BUILT_SOURCES = crc8gen.c crc16gen.c crc32gen.c crc64gen.c diff --git a/src/conv.c b/src/conv.c index f13deef..79b3a7c 100644 --- a/src/conv.c +++ b/src/conv.c @@ -238,6 +238,11 @@ #define MAX_AE 0x00ffffff +/* Forward declaration for accerlated decoding with certain codes */ +int +osmo_conv_decode_acc(const struct osmo_conv_code *code, + const sbit_t *input, ubit_t *output); + void osmo_conv_decode_init(struct osmo_conv_decoder *decoder, const struct osmo_conv_code *code, int len, int start_state) @@ -606,6 +611,10 @@ struct osmo_conv_decoder decoder; int rv, l; + /* Use accelerated implementation for supported codes */ + if ((code->N <= 4) && ((code->K == 5) || (code->K == 7))) + return osmo_conv_decode_acc(code, input, output); + osmo_conv_decode_init(&decoder, code, 0, 0); if (code->term == CONV_TERM_TAIL_BITING) { diff --git a/src/viterbi.c b/src/viterbi.c new file mode 100644 index 0000000..ea4fb21 --- /dev/null +++ b/src/viterbi.c @@ -0,0 +1,602 @@ +/* + * Viterbi decoder + * + * Copyright (C) 2013, 2014 Thomas Tsou + * + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include +#include +#include + +#include +#include "config.h" + +#define BIT2NRZ(REG,N) (((REG >> N) & 0x01) * 2 - 1) * -1 +#define NUM_STATES(K) (K == 7 ? 64 : 16) +#define SSE_ALIGN 16 + +/* Forward Metric Units */ +void osmo_conv_gen_metrics_k5_n2(const int8_t *seq, const int16_t *out, + int16_t *sums, int16_t *paths, int norm); +void osmo_conv_gen_metrics_k5_n3(const int8_t *seq, const int16_t *out, + int16_t *sums, int16_t *paths, int norm); +void osmo_conv_gen_metrics_k5_n4(const int8_t *seq, const int16_t *out, + int16_t *sums, int16_t *paths, int norm); +void osmo_conv_gen_metrics_k7_n2(const int8_t *seq, const int16_t *out, + int16_t *sums, int16_t *paths, int norm); +void osmo_conv_gen_metrics_k7_n3(const int8_t *seq, const int16_t *out, + int16_t *sums, int16_t *paths, int norm); +void osmo_conv_gen_metrics_k7_n4(const int8_t *seq, const int16_t *out, + int16_t *sums, int16_t *paths, int norm); + +/* Trellis State + * state - Internal lshift register value + * prev - Register values of previous 0 and 1 states + */ +struct vstate { + unsigned state; + unsigned prev[2]; +}; + +/* Trellis Object + * num_states - Number of states in the trellis + * sums - Accumulated path metrics + * outputs - Trellis output values + * vals - Input value that led to each state + */ +struct vtrellis { + int num_states; + int16_t *sums; + int16_t *outputs; + uint8_t *vals; +}; + +/* Viterbi Decoder + * n - Code order + * k - Constraint length + * len - Horizontal length of trellis + * recursive - Set to '1' if the code is recursive + * intrvl - Normalization interval + * trellis - Trellis object + * punc - Puncturing sequence + * paths - Trellis paths + */ +struct vdecoder { + int n; + int k; + int len; + int recursive; + int intrvl; + struct vtrellis *trellis; + int *punc; + int16_t **paths; + + void (*metric_func)(const int8_t *, const int16_t *, + int16_t *, int16_t *, int); +}; + +/* Aligned Memory Allocator + * SSE requires 16-byte memory alignment. We store relevant trellis values + * (accumulated sums, outputs, and path decisions) as 16 bit signed integers + * so the allocated memory is casted as such. + */ +static int16_t *vdec_malloc(size_t n) +{ +#ifdef HAVE_SSE3 + return (int16_t *) memalign(SSE_ALIGN, sizeof(int16_t) * n); +#else + return (int16_t *) malloc(sizeof(int16_t) * n); +#endif +} + +/* Accessor calls */ +static inline int conv_code_recursive(const struct osmo_conv_code *code) +{ + return code->next_term_output ? 1 : 0; +} + +/* Left shift and mask for finding the previous state */ +static unsigned vstate_lshift(unsigned reg, int k, int val) +{ + unsigned mask; + + if (k == 5) + mask = 0x0e; + else if (k == 7) + mask = 0x3e; + else + mask = 0; + + return ((reg << 1) & mask) | val; +} + +/* Bit endian manipulators */ +static inline unsigned bitswap2(unsigned v) +{ + return ((v & 0x02) >> 1) | ((v & 0x01) << 1); +} + +static inline unsigned bitswap3(unsigned v) +{ + return ((v & 0x04) >> 2) | ((v & 0x02) >> 0) | + ((v & 0x01) << 2); +} + +static inline unsigned bitswap4(unsigned v) +{ + return ((v & 0x08) >> 3) | ((v & 0x04) >> 1) | + ((v & 0x02) << 1) | ((v & 0x01) << 3); +} + +static inline unsigned bitswap5(unsigned v) +{ + return ((v & 0x10) >> 4) | ((v & 0x08) >> 2) | ((v & 0x04) >> 0) | + ((v & 0x02) << 2) | ((v & 0x01) << 4); +} + +static inline unsigned bitswap6(unsigned v) +{ + return ((v & 0x20) >> 5) | ((v & 0x10) >> 3) | ((v & 0x08) >> 1) | + ((v & 0x04) << 1) | ((v & 0x02) << 3) | ((v & 0x01) << 5); +} + +static unsigned bitswap(unsigned v, unsigned n) +{ + switch (n) { + case 1: + return v; + case 2: + return bitswap2(v); + case 3: + return bitswap3(v); + case 4: + return bitswap4(v); + case 5: + return bitswap5(v); + case 6: + return bitswap6(v); + default: + return 0; + } +} + +/* Generate non-recursive state output from generator state table + * Note that the shift register moves right (i.e. the most recent bit is + * shifted into the register at k-1 bit of the register), which is typical + * textbook representation. The API transition table expects the most recent + * bit in the low order bit, or left shift. A bitswap operation is required + * to accommodate the difference. + */ +static unsigned gen_output(struct vstate *state, int val, + const struct osmo_conv_code *code) +{ + unsigned out, prev; + + prev = bitswap(state->prev[0], code->K - 1); + out = code->next_output[prev][val]; + out = bitswap(out, code->N); + + return out; +} + +/* Populate non-recursive trellis state + * For a given state defined by the k-1 length shift register, find the + * value of the input bit that drove the trellis to that state. Also + * generate the N outputs of the generator polynomial at that state. + */ +static int gen_state_info(uint8_t *val, unsigned reg, + int16_t *output, const struct osmo_conv_code *code) +{ + int i; + unsigned out; + struct vstate state; + + /* Previous '0' state */ + state.state = reg; + state.prev[0] = vstate_lshift(reg, code->K, 0); + state.prev[1] = vstate_lshift(reg, code->K, 1); + + *val = (reg >> (code->K - 2)) & 0x01; + + /* Transition output */ + out = gen_output(&state, *val, code); + + /* Unpack to NRZ */ + for (i = 0; i < code->N; i++) + output[i] = BIT2NRZ(out, i); + + return 0; +} + +/* Generate recursive state output from generator state table */ +static unsigned gen_recursive_output(struct vstate *state, + uint8_t *val, unsigned reg, + const struct osmo_conv_code *code, int pos) +{ + int val0, val1; + unsigned out, prev; + + /* Previous '0' state */ + prev = vstate_lshift(reg, code->K, 0); + prev = bitswap(prev, code->K - 1); + + /* Input value */ + val0 = (reg >> (code->K - 2)) & 0x01; + val1 = (code->next_term_output[prev] >> pos) & 0x01; + *val = val0 == val1 ? 0 : 1; + + /* Wrapper for osmocom state access */ + prev = bitswap(state->prev[0], code->K - 1); + + /* Compute the transition output */ + out = code->next_output[prev][*val]; + out = bitswap(out, code->N); + + return out; +} + +/* Populate recursive trellis state + * The bit position of the systematic bit is not explicitly marked by the + * API, so it must be extracted from the generator table. Otherwise, + * populate the trellis similar to the non-recursive version. + * Non-systematic recursive codes are not supported. + */ +static int gen_recursive_state_info(uint8_t *val, + unsigned reg, int16_t *output, const struct osmo_conv_code *code) +{ + int i, j, pos = -1; + int ns = NUM_STATES(code->K); + unsigned out; + struct vstate state; + + /* Previous '0' and '1' states */ + state.state = reg; + state.prev[0] = vstate_lshift(reg, code->K, 0); + state.prev[1] = vstate_lshift(reg, code->K, 1); + + /* Find recursive bit location */ + for (i = 0; i < code->N; i++) { + for (j = 0; j < ns; j++) { + if ((code->next_output[j][0] >> i) & 0x01) + break; + } + + if (j == ns) { + pos = i; + break; + } + } + + /* Non-systematic recursive code not supported */ + if (pos < 0) + return -EPROTO; + + /* Transition output */ + out = gen_recursive_output(&state, val, reg, code, pos); + + /* Unpack to NRZ */ + for (i = 0; i < code->N; i++) + output[i] = BIT2NRZ(out, i); + + return 0; +} + +/* Release the trellis */ +static void free_trellis(struct vtrellis *trellis) +{ + if (!trellis) + return; + + free(trellis->vals); + free(trellis->outputs); + free(trellis->sums); + free(trellis); +} + +/* Allocate and initialize the trellis object + * Initialization consists of generating the outputs and output value of a + * given state. Due to trellis symmetry and anti-symmetry, only one of the + * transition paths is utilized by the butterfly operation in the forward + * recursion, so only one set of N outputs is required per state variable. + */ +static struct vtrellis *generate_trellis(const struct osmo_conv_code *code) +{ + int i, rc = -1; + struct vtrellis *trellis; + int16_t *outputs; + + int ns = NUM_STATES(code->K); + int recursive = conv_code_recursive(code); + int olen = (code->N == 2) ? 2 : 4; + + trellis = (struct vtrellis *) calloc(1, sizeof(struct vtrellis)); + trellis->num_states = ns; + trellis->sums = vdec_malloc(ns); + trellis->outputs = vdec_malloc(ns * olen); + trellis->vals = (uint8_t *) malloc(ns * sizeof(uint8_t)); + + if (!trellis->sums || !trellis->outputs) + goto fail; + + /* Populate the trellis state objects */ + for (i = 0; i < ns; i++) { + outputs = &trellis->outputs[olen * i]; + if (recursive) { + rc = gen_recursive_state_info(&trellis->vals[i], + i, outputs, code); + } else { + rc = gen_state_info(&trellis->vals[i], + i, outputs, code); + } + } + + if (rc < 0) + goto fail; + + return trellis; + +fail: + free_trellis(trellis); + return NULL; +} + +/* Reset decoder + * Set accumulated path metrics to zero. For termination other than + * tail-biting, initialize the zero state as the encoder starting state. + * Initialize with the maximum accumulated sum at length equal to the + * constraint length. + */ +static void reset_decoder(struct vdecoder *dec, int term) +{ + int ns = dec->trellis->num_states; + + memset(dec->trellis->sums, 0, sizeof(int16_t) * ns); + + if (term != CONV_TERM_TAIL_BITING) + dec->trellis->sums[0] = INT8_MAX * dec->n * dec->k; +} + +static void _traceback(struct vdecoder *dec, + unsigned state, uint8_t *out, int len) +{ + int i; + unsigned path; + + for (i = len - 1; i >= 0; i--) { + path = dec->paths[i][state] + 1; + out[i] = dec->trellis->vals[state]; + state = vstate_lshift(state, dec->k, path); + } +} + +static void _traceback_rec(struct vdecoder *dec, + unsigned state, uint8_t *out, int len) +{ + int i; + unsigned path; + + for (i = len - 1; i >= 0; i--) { + path = dec->paths[i][state] + 1; + out[i] = path ^ dec->trellis->vals[state]; + state = vstate_lshift(state, dec->k, path); + } +} + +/* Traceback and generate decoded output + * Find the largest accumulated path metric at the final state except for + * the zero terminated case, where we assume the final state is always zero. + */ +static int traceback(struct vdecoder *dec, uint8_t *out, int term, int len) +{ + int i, sum, max = -1; + unsigned path, state = 0; + + if (term != CONV_TERM_FLUSH) { + for (i = 0; i < dec->trellis->num_states; i++) { + sum = dec->trellis->sums[i]; + if (sum > max) { + max = sum; + state = i; + } + } + + if (max < 0) + return -EPROTO; + } + + for (i = dec->len - 1; i >= len; i--) { + path = dec->paths[i][state] + 1; + state = vstate_lshift(state, dec->k, path); + } + + if (dec->recursive) + _traceback_rec(dec, state, out, len); + else + _traceback(dec, state, out, len); + + return 0; +} + +/* Release decoder object */ +static void free_vdec(struct vdecoder *dec) +{ + if (!dec) + return; + + free(dec->paths[0]); + free(dec->paths); + free_trellis(dec->trellis); + free(dec); +} + +/* Allocate decoder object + * Subtract the constraint length K on the normalization interval to + * accommodate the initialization path metric at state zero. + */ +static struct vdecoder *alloc_vdec(const struct osmo_conv_code *code) +{ + int i, ns; + struct vdecoder *dec; + + ns = NUM_STATES(code->K); + + dec = (struct vdecoder *) calloc(1, sizeof(struct vdecoder)); + dec->n = code->N; + dec->k = code->K; + dec->recursive = conv_code_recursive(code); + dec->intrvl = INT16_MAX / (dec->n * INT8_MAX) - dec->k; + + if (dec->k == 5) { + switch (dec->n) { + case 2: + dec->metric_func = osmo_conv_gen_metrics_k5_n2; + break; + case 3: + dec->metric_func = osmo_conv_gen_metrics_k5_n3; + break; + case 4: + dec->metric_func = osmo_conv_gen_metrics_k5_n4; + break; + default: + goto fail; + } + } else if (dec->k == 7) { + switch (dec->n) { + case 2: + dec->metric_func = osmo_conv_gen_metrics_k7_n2; + break; + case 3: + dec->metric_func = osmo_conv_gen_metrics_k7_n3; + break; + case 4: + dec->metric_func = osmo_conv_gen_metrics_k7_n4; + break; + default: + goto fail; + } + } else { + goto fail; + } + + if (code->term == CONV_TERM_FLUSH) + dec->len = code->len + code->K - 1; + else + dec->len = code->len; + + dec->trellis = generate_trellis(code); + if (!dec->trellis) + goto fail; + + dec->paths = (int16_t **) malloc(sizeof(int16_t *) * dec->len); + dec->paths[0] = vdec_malloc(ns * dec->len); + for (i = 1; i < dec->len; i++) + dec->paths[i] = &dec->paths[0][i * ns]; + + return dec; + +fail: + free_vdec(dec); + return NULL; +} + +/* Depuncture sequence with nagative value terminated puncturing matrix */ +static int depuncture(const int8_t *in, const int *punc, int8_t *out, int len) +{ + int i, n = 0, m = 0; + + for (i = 0; i < len; i++) { + if (i == punc[n]) { + out[i] = 0; + n++; + continue; + } + + out[i] = in[m++]; + } + + return 0; +} + +/* Forward trellis recursion + * Generate branch metrics and path metrics with a combined function. Only + * accumulated path metric sums and path selections are stored. Normalize on + * the interval specified by the decoder. + */ +static void forward_traverse(struct vdecoder *dec, const int8_t *seq) +{ + struct vtrellis *trellis = dec->trellis; + int i; + + for (i = 0; i < dec->len; i++) { + dec->metric_func(&seq[dec->n * i], + trellis->outputs, + trellis->sums, + dec->paths[i], + !(i % dec->intrvl)); + } +} + +/* Convolutional decode with a decoder object + * Initial puncturing run if necessary followed by the forward recursion. + * For tail-biting perform a second pass before running the backward + * traceback operation. + */ +static int conv_decode(struct vdecoder *dec, const int8_t *seq, + const int *punc, uint8_t *out, int len, int term) +{ + int8_t depunc[dec->len * dec->n]; + + reset_decoder(dec, term); + + if (punc) { + depuncture(seq, punc, depunc, dec->len * dec->n); + seq = depunc; + } + + /* Propagate through the trellis with interval normalization */ + forward_traverse(dec, seq); + + if (term == CONV_TERM_TAIL_BITING) + forward_traverse(dec, seq); + + return traceback(dec, out, term, len); +} + +/* All-in-one Viterbi decoding */ +int osmo_conv_decode_acc(const struct osmo_conv_code *code, + const sbit_t *input, ubit_t *output) +{ + int rc; + struct vdecoder *vdec; + + if ((code->N < 2) || (code->N > 4) || (code->len < 1) || + ((code->K != 5) && (code->K != 7))) + return -EINVAL; + + vdec = alloc_vdec(code); + if (!vdec) + return -EFAULT; + + rc = conv_decode(vdec, input, code->puncture, + output, code->len, code->term); + + free_vdec(vdec); + + return rc; +} diff --git a/src/viterbi_gen.c b/src/viterbi_gen.c new file mode 100644 index 0000000..7972c39 --- /dev/null +++ b/src/viterbi_gen.c @@ -0,0 +1,193 @@ +/* + * Viterbi decoder + * + * Copyright (C) 2013, 2014 Thomas Tsou + * + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include +#include + +/* Add-Compare-Select (ACS-Butterfly) + * Compute 4 accumulated path metrics and 4 path selections. Note that path + * selections are store as -1 and 0 rather than 0 and 1. This is to match + * the output format of the SSE packed compare instruction 'pmaxuw'. + */ + +static void acs_butterfly(int state, int num_states, + int16_t metric, int16_t *sum, + int16_t *new_sum, int16_t *path) +{ + int state0, state1; + int sum0, sum1, sum2, sum3; + + state0 = *(sum + (2 * state + 0)); + state1 = *(sum + (2 * state + 1)); + + sum0 = state0 + metric; + sum1 = state1 - metric; + sum2 = state0 - metric; + sum3 = state1 + metric; + + if (sum0 >= sum1) { + *new_sum = sum0; + *path = -1; + } else { + *new_sum = sum1; + *path = 0; + } + + if (sum2 >= sum3) { + *(new_sum + num_states / 2) = sum2; + *(path + num_states / 2) = -1; + } else { + *(new_sum + num_states / 2) = sum3; + *(path + num_states / 2) = 0; + } +} + +/* Branch metrics unit N=2 */ +static void gen_branch_metrics_n2(int num_states, const int8_t *seq, + const int16_t *out, int16_t *metrics) +{ + int i; + + for (i = 0; i < num_states / 2; i++) { + metrics[i] = seq[0] * out[2 * i + 0] + + seq[1] * out[2 * i + 1]; + } +} + +/* Branch metrics unit N=3 */ +static void gen_branch_metrics_n3(int num_states, const int8_t *seq, + const int16_t *out, int16_t *metrics) +{ + int i; + + for (i = 0; i < num_states / 2; i++) { + metrics[i] = seq[0] * out[4 * i + 0] + + seq[1] * out[4 * i + 1] + + seq[2] * out[4 * i + 2]; + } +} + +/* Branch metrics unit N=4 */ +static void gen_branch_metrics_n4(int num_states, const int8_t *seq, + const int16_t *out, int16_t *metrics) +{ + int i; + + for (i = 0; i < num_states / 2; i++) { + metrics[i] = seq[0] * out[4 * i + 0] + + seq[1] * out[4 * i + 1] + + seq[2] * out[4 * i + 2] + + seq[3] * out[4 * i + 3]; + } +} + +/* Path metric unit */ +static void gen_path_metrics(int num_states, int16_t *sums, + int16_t *metrics, int16_t *paths, int norm) +{ + int i; + int16_t min; + int16_t new_sums[num_states]; + + for (i = 0; i < num_states / 2; i++) + acs_butterfly(i, num_states, metrics[i], + sums, &new_sums[i], &paths[i]); + + if (norm) { + min = new_sums[0]; + + for (i = 1; i < num_states; i++) + if (new_sums[i] < min) + min = new_sums[i]; + + for (i = 0; i < num_states; i++) + new_sums[i] -= min; + } + + memcpy(sums, new_sums, num_states * sizeof(int16_t)); +} + +/* 16-state branch-path metrics units (K=5) */ +__attribute__ ((visibility("hidden"))) +void osmo_conv_gen_metrics_k5_n2(const int8_t *seq, const int16_t *out, + int16_t *sums, int16_t *paths, int norm) +{ + int16_t metrics[8]; + + gen_branch_metrics_n2(16, seq, out, metrics); + gen_path_metrics(16, sums, metrics, paths, norm); +} + +__attribute__ ((visibility("hidden"))) +void osmo_conv_gen_metrics_k5_n3(const int8_t *seq, const int16_t *out, + int16_t *sums, int16_t *paths, int norm) +{ + int16_t metrics[8]; + + gen_branch_metrics_n3(16, seq, out, metrics); + gen_path_metrics(16, sums, metrics, paths, norm); + +} + +__attribute__ ((visibility("hidden"))) +void osmo_conv_gen_metrics_k5_n4(const int8_t *seq, const int16_t *out, + int16_t *sums, int16_t *paths, int norm) +{ + int16_t metrics[8]; + + gen_branch_metrics_n4(16, seq, out, metrics); + gen_path_metrics(16, sums, metrics, paths, norm); + +} + +/* 64-state branch-path metrics units (K=7) */ +__attribute__ ((visibility("hidden"))) +void osmo_conv_gen_metrics_k7_n2(const int8_t *seq, const int16_t *out, + int16_t *sums, int16_t *paths, int norm) +{ + int16_t metrics[32]; + + gen_branch_metrics_n2(64, seq, out, metrics); + gen_path_metrics(64, sums, metrics, paths, norm); + +} + +__attribute__ ((visibility("hidden"))) +void osmo_conv_gen_metrics_k7_n3(const int8_t *seq, const int16_t *out, + int16_t *sums, int16_t *paths, int norm) +{ + int16_t metrics[32]; + + gen_branch_metrics_n3(64, seq, out, metrics); + gen_path_metrics(64, sums, metrics, paths, norm); + +} + +__attribute__ ((visibility("hidden"))) +void osmo_conv_gen_metrics_k7_n4(const int8_t *seq, const int16_t *out, + int16_t *sums, int16_t *paths, int norm) +{ + int16_t metrics[32]; + + gen_branch_metrics_n4(64, seq, out, metrics); + gen_path_metrics(64, sums, metrics, paths, norm); +} -- To view, visit https://gerrit.osmocom.org/1337 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I74d355274b4176a7d924f91ef3c96912ce338fb2 Gerrit-PatchSet: 7 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Vadim Yanitskiy Gerrit-Reviewer: Alexander Chemeris Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Tom Tsou Gerrit-Reviewer: Vadim Yanitskiy Gerrit-Reviewer: tnt From gerrit-no-reply at lists.osmocom.org Tue Apr 11 09:39:02 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Tue, 11 Apr 2017 09:39:02 +0000 Subject: [PATCH] osmo-bts[master]: Signal to BSC when PCU disconnects In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2288 to look at the new patch set (#2). Signal to BSC when PCU disconnects Change-Id: I41a731bd719aee0bbb98d3236405fb3a7f3ddec0 Related: OS#1615 --- M src/common/pcu_sock.c 1 file changed, 2 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/88/2288/2 diff --git a/src/common/pcu_sock.c b/src/common/pcu_sock.c index fa2c585..a498543 100644 --- a/src/common/pcu_sock.c +++ b/src/common/pcu_sock.c @@ -670,6 +670,8 @@ bts = llist_entry(state->net->bts_list.next, struct gsm_bts, list); LOGP(DPCU, LOGL_NOTICE, "PCU socket has LOST connection\n"); + osmo_signal_dispatch(SS_FAIL, OSMO_EVT_PCU_VERS, ""); + bts->pcu_version[0] = '\0'; close(bfd->fd); bfd->fd = -1; -- To view, visit https://gerrit.osmocom.org/2288 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I41a731bd719aee0bbb98d3236405fb3a7f3ddec0 Gerrit-PatchSet: 2 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Apr 11 09:41:06 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Tue, 11 Apr 2017 09:41:06 +0000 Subject: openbsc[master]: build: iu: use libosmo-sccp tag 'old_sua' In-Reply-To: References: Message-ID: Patch Set 1: In the description you mention tag, in the code - branch. So which is it? -- To view, visit https://gerrit.osmocom.org/2293 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Id74a802fd2ca65f4b6c2079550fbb6b0af3e8340 Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Apr 11 09:42:33 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Tue, 11 Apr 2017 09:42:33 +0000 Subject: openbsc[master]: nat: Use equal func in bsc_sccp In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+1 -- To view, visit https://gerrit.osmocom.org/2285 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I9fac7cabedff74f8f6293ad8b54420229b80aa71 Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Pau Espin Pedrol Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Apr 11 09:45:40 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Tue, 11 Apr 2017 09:45:40 +0000 Subject: libosmo-sccp[master]: Add osmo-stp executable as new "Osmocom Signaling Transfer P... In-Reply-To: References: Message-ID: Patch Set 2: I think we should add it to debian/ as well. -- To view, visit https://gerrit.osmocom.org/2281 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: If32227b8d3127c6178e4ee45527ce65f69bc7b1e Gerrit-PatchSet: 2 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Apr 11 14:41:55 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Tue, 11 Apr 2017 14:41:55 +0000 Subject: [PATCH] libosmocore[master]: Add SW Description (de)marshalling In-Reply-To: References: Message-ID: Hello Neels Hofmeyr, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2165 to look at the new patch set (#14). Add SW Description (de)marshalling * data structure representing 3GPP TS 52.021 ?9.4.62 SW Description * function to serialize it into msgb * function to deserialize it from buffer * functions to extract/estimate buffer size for SW Description * test harness (partially taken from OpenBSC) There are several similar functions to deal with SW Description in OpenBSC, there's also need to use similar functionality in OsmoBTS. Hence it's better to put the code into common library with proper tests and documentation. Change-Id: Ib63b6b5e83b8914864fc7edd789f8958cdc993cd Related: OS#1614 --- M .gitignore M include/osmocom/gsm/protocol/gsm_12_21.h M src/gsm/abis_nm.c M src/gsm/libosmogsm.map M tests/Makefile.am A tests/abis/abis_test.c A tests/abis/abis_test.ok M tests/testsuite.at 8 files changed, 437 insertions(+), 2 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/65/2165/14 diff --git a/.gitignore b/.gitignore index ecbcedd..4c6a78f 100644 --- a/.gitignore +++ b/.gitignore @@ -60,6 +60,7 @@ tests/testsuite tests/testsuite.dir/ tests/testsuite.log +tests/abis/abis_test tests/ctrl/ctrl_test tests/utils/utils_test tests/stats/stats_test diff --git a/include/osmocom/gsm/protocol/gsm_12_21.h b/include/osmocom/gsm/protocol/gsm_12_21.h index c88f0b1..b35da44 100644 --- a/include/osmocom/gsm/protocol/gsm_12_21.h +++ b/include/osmocom/gsm/protocol/gsm_12_21.h @@ -29,6 +29,7 @@ /*! \file gsm_12_21.h */ #include +#include #include /*! \brief generic header in front of every OML message according to TS 08.59 */ @@ -791,6 +792,21 @@ IPAC_BINF_CELL_ALLOC = (1 << 2), }; +/*! \brief 3GPP TS 52.021 ?9.4.62 SW Description */ +struct abis_nm_sw_desc { + uint8_t file_id[UINT8_MAX]; + uint8_t file_id_len; + + uint8_t file_version[UINT8_MAX]; + uint8_t file_version_len; +}; + +uint16_t abis_nm_sw_desc_len(const struct abis_nm_sw_desc *sw, bool put_sw_descr); +uint16_t abis_nm_put_sw_desc(struct msgb *msg, const struct abis_nm_sw_desc *sw, bool put_sw_descr); +uint16_t abis_nm_put_sw_file(struct msgb *msg, const char *id, const char *ver, bool put_sw_desc); +uint32_t abis_nm_get_sw_desc_len(const uint8_t * buf, size_t len); +int abis_nm_get_sw_conf(const uint8_t * buf, size_t buf_len, struct abis_nm_sw_desc *sw, uint16_t sw_len); + struct msgb *abis_nm_fail_evt_rep(enum abis_nm_event_type t, enum abis_nm_severity s, enum abis_nm_pcause_type ct, diff --git a/src/gsm/abis_nm.c b/src/gsm/abis_nm.c index 934d7ce..7553f84 100644 --- a/src/gsm/abis_nm.c +++ b/src/gsm/abis_nm.c @@ -751,6 +751,161 @@ return nmsg; } +/*! \brief Compute length of given 3GPP TS 52.021 ?9.4.62 SW Description. + * \param[in] sw SW Description struct + * \param[in] put_sw_descr boolean, whether to put NM_ATT_SW_DESCR IE or not + * \returns length of buffer space necessary to store sw + */ +uint16_t abis_nm_sw_desc_len(const struct abis_nm_sw_desc *sw, bool put_sw_desc) +{ + /* +3: type is 1-byte, length is 2-byte */ + return (put_sw_desc ? 1 : 0) + (sw->file_id_len + 3) + (sw->file_version_len + 3); +} + +/*! \brief Put given 3GPP TS 52.021 ?9.4.62 SW Description into msgb. + * \param[out] msg message buffer + * \param[in] sw SW Description struct + * \param[in] put_sw_descr boolean, whether to put NM_ATT_SW_DESCR IE or not + * \returns length of buffer space necessary to store sw + */ +uint16_t abis_nm_put_sw_desc(struct msgb *msg, const struct abis_nm_sw_desc *sw, bool put_sw_desc) +{ + if (put_sw_desc) + msgb_v_put(msg, NM_ATT_SW_DESCR); + + msgb_tl16v_put(msg, NM_ATT_FILE_ID, sw->file_id_len, sw->file_id); + msgb_tl16v_put(msg, NM_ATT_FILE_VERSION, sw->file_version_len, sw->file_version); + + return abis_nm_sw_desc_len(sw, put_sw_desc); +} + +/*! \brief Put given file ID/Version pair as 3GPP TS 52.021 ?9.4.62 SW Description into msgb. + * \param[out] msg message buffer + * \param[in] id File ID part of SW Description + * \param[in] id File Version part of SW Description + * \param[in] put_sw_descr boolean, whether to put NM_ATT_SW_DESCR IE or not + * \returns length of buffer space necessary to store sw + */ +uint16_t abis_nm_put_sw_file(struct msgb *msg, const char *id, const char *ver, bool put_sw_desc) +{ + struct abis_nm_sw_desc sw = { + .file_id_len = strlen(id), + .file_version_len = strlen(ver), + }; + + memcpy(sw.file_id, id, sw.file_id_len); + memcpy(sw.file_version, ver, sw.file_version_len); + + return abis_nm_put_sw_desc(msg, &sw, put_sw_desc); +} + +/*! \brief Get length of first 3GPP TS 52.021 ?9.4.62 SW Description from buffer. + * \param[in] buf buffer, may contain several SW Descriptions + * \param[in] len buffer length + * \returns length if parsing succeeded, 0 otherwise + */ +uint32_t abis_nm_get_sw_desc_len(const uint8_t *buf, size_t len) +{ + uint16_t sw = 2; /* 1-byte SW tag + 1-byte FILE_* tag */ + + if (buf[0] != NM_ATT_SW_DESCR) + sw = 1; /* 1-byte FILE_* tag */ + + if (buf[sw - 1] != NM_ATT_FILE_ID && buf[sw - 1] != NM_ATT_FILE_VERSION) + return 0; + + /* + length of 1st FILE_* element + 1-byte tag + 2-byte length field of + 1st FILE_* element */ + sw += (osmo_load16be(buf + sw) + 3); + + /* + length of 2nd FILE_* element */ + sw += osmo_load16be(buf + sw); + + return sw + 2; /* + 2-byte length field of 2nd FILE_* element */ +} + +/*! \brief Parse single 3GPP TS 52.021 ?9.4.62 SW Description from buffer. + * \param[out] sw SW Description struct + * \param[in] buf buffer + * \param[in] len buffer length + * \returns 0 if parsing succeeded, negative error code otherwise + */ +static inline int abis_nm_get_sw_desc(struct abis_nm_sw_desc *sw, const uint8_t *buf, size_t length) +{ + int rc; + uint32_t len = abis_nm_get_sw_desc_len(buf, length); + static struct tlv_parsed tp; + const struct tlv_definition sw_tlvdef = { + .def = { + [NM_ATT_SW_DESCR] = { TLV_TYPE_TV }, + [NM_ATT_FILE_ID] = { TLV_TYPE_TL16V }, + [NM_ATT_FILE_VERSION] = { TLV_TYPE_TL16V }, + }, + }; + + /* Basic sanity check */ + if (len > length) + return -EFBIG; + + /* Note: current implementation of TLV parser fails on multilpe SW Descr: + we will only parse the first one */ + if (!len) + return -EINVAL; + + /* Note: the return value is ignored here because SW Description tag + itself is considered optional. */ + tlv_parse(&tp, &sw_tlvdef, buf, len, 0, 0); + + /* Parsing SW Description is tricky for current implementation of TLV + parser which fails to properly handle TV when V has following + structure: | TL16V | TL16V |. Hence, the need for 2nd call: */ + rc = tlv_parse(&tp, &sw_tlvdef, buf + TLVP_LEN(&tp, NM_ATT_SW_DESCR), len - TLVP_LEN(&tp, NM_ATT_SW_DESCR), + 0, 0); + + if (rc < 0) + return rc; + + if (!TLVP_PRESENT(&tp, NM_ATT_FILE_ID)) + return -EBADF; + + if (!TLVP_PRESENT(&tp, NM_ATT_FILE_VERSION)) + return -EBADMSG; + + sw->file_id_len = TLVP_LEN(&tp, NM_ATT_FILE_ID); + sw->file_version_len = TLVP_LEN(&tp, NM_ATT_FILE_VERSION); + + memcpy(sw->file_id, TLVP_VAL(&tp, NM_ATT_FILE_ID), sw->file_id_len); + memcpy(sw->file_version, TLVP_VAL(&tp, NM_ATT_FILE_VERSION), sw->file_version_len); + + return 0; +} + +/*! \brief Parse 3GPP TS 52.021 ?9.4.61 SW Configuration from buffer. + * \param[in] buf buffer + * \param[in] buf_len buffer length + * \param[out] sw SW Description struct array + * \param[in] sw_len Expected number of SW Description entries + * \returns 0 if parsing succeeded, negative error code otherwise + */ +int abis_nm_get_sw_conf(const uint8_t * buf, size_t buf_len, struct abis_nm_sw_desc *sw, uint16_t sw_len) +{ + int rc; + uint16_t len = 0, i; + for (i = 0; i < sw_len; i++) { + memset(&sw[i], 0, sizeof(sw[i])); + rc = abis_nm_get_sw_desc(&sw[i], buf + len, buf_len - len); + if (rc < 0) + return rc; + + len += abis_nm_get_sw_desc_len(buf + len, buf_len - len); + + if (len >= buf_len) + return i + 1; + } + + return i; +} + /*! \brief Obtain OML Channel Combination for phnsical channel config */ int abis_nm_chcomb4pchan(enum gsm_phys_chan_config pchan) { diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map index c825dd5..1208b90 100644 --- a/src/gsm/libosmogsm.map +++ b/src/gsm/libosmogsm.map @@ -31,6 +31,11 @@ abis_nm_pcause_type_names; abis_nm_msgtype_names; abis_nm_att_names; +abis_nm_sw_desc_len; +abis_nm_put_sw_desc; +abis_nm_put_sw_file; +abis_nm_get_sw_conf; +abis_nm_get_sw_desc_len; osmo_sitype_strs; osmo_c4; diff --git a/tests/Makefile.am b/tests/Makefile.am index 352b5a7..c726277 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -15,7 +15,7 @@ bitvec/bitvec_test msgb/msgb_test bits/bitcomp_test \ tlv/tlv_test gsup/gsup_test oap/oap_test fsm/fsm_test \ write_queue/wqueue_test socket/socket_test \ - coding/coding_test + coding/coding_test abis/abis_test if ENABLE_MSGFILE check_PROGRAMS += msgfile/msgfile_test @@ -42,6 +42,9 @@ auth_milenage_test_SOURCES = auth/milenage_test.c auth_milenage_test_LDADD = $(top_builddir)/src/libosmocore.la $(top_builddir)/src/gsm/libosmogsm.la + +abis_abis_test_SOURCES = abis/abis_test.c +abis_abis_test_LDADD = $(top_builddir)/src/libosmocore.la $(top_builddir)/src/gsm/libosmogsm.la ctrl_ctrl_test_SOURCES = ctrl/ctrl_test.c ctrl_ctrl_test_LDADD = $(top_builddir)/src/libosmocore.la $(top_builddir)/src/ctrl/libosmoctrl.la @@ -188,7 +191,7 @@ vty/vty_test.ok comp128/comp128_test.ok \ utils/utils_test.ok stats/stats_test.ok \ bitvec/bitvec_test.ok msgb/msgb_test.ok bits/bitcomp_test.ok \ - sim/sim_test.ok tlv/tlv_test.ok \ + sim/sim_test.ok tlv/tlv_test.ok abis/abis_test.ok \ gsup/gsup_test.ok gsup/gsup_test.err \ oap/oap_test.ok fsm/fsm_test.ok fsm/fsm_test.err \ write_queue/wqueue_test.ok socket/socket_test.ok \ diff --git a/tests/abis/abis_test.c b/tests/abis/abis_test.c new file mode 100644 index 0000000..a303c91 --- /dev/null +++ b/tests/abis/abis_test.c @@ -0,0 +1,208 @@ +/* + * (C) 2012 by Holger Hans Peter Freyther + * (C) 2017 by sysmocom s.m.f.c. GmbH + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +static struct log_info info = {}; + +static const uint8_t simple_config[] = { 66, 18, 0, 3, 1, 2, 3, 19, 0, 3, 3, 4, 5 }; + +static const uint8_t dual_config[] = { + 66, 18, 0, 3, 1, 2, 3, 19, 0, 3, 3, 4, 5, + 66, 18, 0, 3, 9, 7, 5, 19, 0, 3, 6, 7, 8, +}; + +static void test_simple_sw_config(void) +{ + struct abis_nm_sw_desc desc[1]; + uint16_t len; + int rc; + + rc = abis_nm_get_sw_conf(simple_config, ARRAY_SIZE(simple_config), &desc[0], ARRAY_SIZE(desc)); + if (rc != 1) { + printf("%s(): FAILED to parse the File Id/File version: %d\n", __func__, rc); + abort(); + } + + len = abis_nm_sw_desc_len(&desc[0], true); + if (len != 13) { + printf("WRONG SIZE: %u\n", len); + abort(); + } + + printf("len: %u\n", len); + printf("file_id: %s\n", osmo_hexdump(desc[0].file_id, desc[0].file_id_len)); + printf("file_ver: %s\n", osmo_hexdump(desc[0].file_version, desc[0].file_version_len)); + printf("%s(): OK\n", __func__); +} + +static void test_simple_sw_short(void) +{ + struct abis_nm_sw_desc desc[1]; + int i; + + for (i = 1; i < ARRAY_SIZE(simple_config); ++i) { + int rc = abis_nm_get_sw_conf(simple_config, ARRAY_SIZE(simple_config) - i, &desc[0], ARRAY_SIZE(desc)); + if (rc >= 1) { + printf("SHOULD not have parsed: %d\n", rc); + abort(); + } + } + printf("%s(): OK\n", __func__); +} + +static void test_dual_sw_config(void) +{ + struct abis_nm_sw_desc desc[2]; + uint16_t len0, len1; + int rc; + + rc = abis_nm_get_sw_conf(dual_config, ARRAY_SIZE(dual_config), &desc[0], ARRAY_SIZE(desc)); + if (rc != 2) { + printf("%s(): FAILED to parse the File Id/File version: %d (%d,%d)\n", + __func__, -rc, EBADF, EBADMSG); + abort(); + } + + len0 = abis_nm_sw_desc_len(&desc[0], true); + if (len0 != 13) { + printf("WRONG SIZE0: %u\n", len0); + abort(); + } + + len1 = abis_nm_sw_desc_len(&desc[1], true); + if (len1 != 13) { + printf("WRONG SIZE1: %u\n", len1); + abort(); + } + + printf("len: %u\n", len0); + printf("file_id: %s\n", osmo_hexdump(desc[0].file_id, desc[0].file_id_len)); + printf("file_ver: %s\n", osmo_hexdump(desc[0].file_version, desc[0].file_version_len)); + + printf("len: %u\n", len1); + printf("file_id: %s\n", osmo_hexdump(desc[1].file_id, desc[1].file_id_len)); + printf("file_ver: %s\n", osmo_hexdump(desc[1].file_version, desc[1].file_version_len)); + printf("%s(): OK\n", __func__); +} + +static inline void print_chk(const char *what, uint8_t len1, uint8_t len2, const uint8_t *x1, const uint8_t *x2) +{ + int cmp = memcmp(x1, x2, len2); + printf("\tFILE %s [%u == %u -> %d, %s] %d => %s\n", what, len1, len2, len1 == len2, len1 != len2 ? "fail" : "ok", + cmp, cmp != 0 ? "FAIL" : "OK"); +} + +static inline void chk_raw(const char *what, const uint8_t *data, uint16_t len) +{ + struct abis_nm_sw_desc sw = { 0 }; + int res = abis_nm_get_sw_conf(data, len, &sw, 1); + uint16_t xlen = abis_nm_get_sw_desc_len(data, len); + + printf("parsing chained %s <1st: %d, total: %d>\n\tSW Descr (%s)\n", osmo_hexdump(data, len), xlen, len, what); + + if (res < 0) + printf("\tFAIL: %d\n", -res); + else { + printf("\tFILE ID: [%d] %s => OK\n", sw.file_id_len, osmo_hexdump(sw.file_id, sw.file_id_len)); + printf("\tFILE VERSION: [%d] %s => OK\n", sw.file_version_len, + osmo_hexdump(sw.file_version, sw.file_version_len)); + } + + if (len != xlen) + chk_raw(" 2nd", data + xlen, len - xlen); +} + +static inline void chk_descr(struct msgb *msg, const char *f_id, const char *f_ver, const char *desc, bool header) +{ + int res; + uint16_t len; + struct abis_nm_sw_desc sw = { 0 }, put = { + .file_id_len = strlen(f_id), + .file_version_len = strlen(f_ver), + }; + + memcpy(put.file_id, f_id, put.file_id_len); + memcpy(put.file_version, f_ver, put.file_version_len); + len = abis_nm_put_sw_file(msg, f_id, f_ver, header); + + printf("msgb[%u] :: {msgb->len} %u == %u {len} - %s]:\n\tSW DESCR (%s)\n" + "\tlength: {extracted} %u = %u {expected} - %s, failsafe - %s\n", + msg->data_len, msg->len, len, len != msg->len ? "fail" : "ok", desc, + abis_nm_get_sw_desc_len(msgb_data(msg), msg->len), msg->len, + abis_nm_get_sw_desc_len(msgb_data(msg), msg->len) != msg->len ? "FAIL" : "OK", + len > put.file_version_len + put.file_id_len ? "OK" : "FAIL"); + + res = abis_nm_get_sw_conf(msgb_data(msg), msg->len, &sw, 1); + if (res < 0) + printf("\tSW DESCR (%s) parsing error code %d!\n", desc, -res); + else { + print_chk("ID", sw.file_id_len, put.file_id_len, sw.file_id, put.file_id); + print_chk("VERSION", sw.file_version_len, put.file_version_len, sw.file_version, put.file_version); + } +} + +static void test_sw_descr() +{ + const char *f_id = "TEST.L0L", *f_ver = "0.1.666~deadbeeffacefeed-dirty"; + uint8_t chain[] = { 0x42, 0x12, 0x00, 0x03, 0x01, 0x02, 0x03, 0x13, 0x00, 0x03, 0x03, 0x04, 0x05, 0x42, 0x12, + 0x00, 0x03, 0x09, 0x07, 0x05, 0x13, 0x00, 0x03, 0x06, 0x07, 0x08 }; + struct msgb *msg = msgb_alloc_headroom(4096, 128, "sw"); + + printf("Testing SW Description (de)serialization...\n"); + + /* check that parsing |SW|ID|VER| works: */ + chk_descr(msg, f_id, f_ver, "with header", true); + msgb_reset(msg); + + /* check that parsing |ID|VER| works: */ + chk_descr(msg, f_id, f_ver, "without header", false); + + /* check that parsing |ID|VER|SW|ID|VER| fails - notice the lack of msgb_reset() to create bogus msgb data: */ + chk_descr(msg, f_id, f_ver, "expected failure", true); + + /* check multiple, chained SW-descr: */ + chk_raw("half", chain, sizeof(chain) / 2); + chk_raw("full", chain, sizeof(chain)); +} + +int main(int argc, char **argv) +{ + osmo_init_logging(&info); + + test_sw_descr(); + test_simple_sw_config(); + test_simple_sw_short(); + test_dual_sw_config(); + + printf("OK.\n"); + + return 0; +} diff --git a/tests/abis/abis_test.ok b/tests/abis/abis_test.ok new file mode 100644 index 0000000..e6b626b --- /dev/null +++ b/tests/abis/abis_test.ok @@ -0,0 +1,41 @@ +Testing SW Description (de)serialization... +msgb[4096] :: {msgb->len} 45 == 45 {len} - ok]: + SW DESCR (with header) + length: {extracted} 45 = 45 {expected} - OK, failsafe - OK + FILE ID [8 == 8 -> 1, ok] 0 => OK + FILE VERSION [30 == 30 -> 1, ok] 0 => OK +msgb[4096] :: {msgb->len} 44 == 44 {len} - ok]: + SW DESCR (without header) + length: {extracted} 44 = 44 {expected} - OK, failsafe - OK + FILE ID [8 == 8 -> 1, ok] 0 => OK + FILE VERSION [30 == 30 -> 1, ok] 0 => OK +msgb[4096] :: {msgb->len} 89 == 45 {len} - fail]: + SW DESCR (expected failure) + length: {extracted} 44 = 89 {expected} - FAIL, failsafe - OK + FILE ID [8 == 8 -> 1, ok] 0 => OK + FILE VERSION [30 == 30 -> 1, ok] 0 => OK +parsing chained 42 12 00 03 01 02 03 13 00 03 03 04 05 <1st: 13, total: 13> + SW Descr (half) + FILE ID: [3] 01 02 03 => OK + FILE VERSION: [3] 03 04 05 => OK +parsing chained 42 12 00 03 01 02 03 13 00 03 03 04 05 42 12 00 03 09 07 05 13 00 03 06 07 08 <1st: 13, total: 26> + SW Descr (full) + FILE ID: [3] 01 02 03 => OK + FILE VERSION: [3] 03 04 05 => OK +parsing chained 42 12 00 03 09 07 05 13 00 03 06 07 08 <1st: 13, total: 13> + SW Descr ( 2nd) + FILE ID: [3] 09 07 05 => OK + FILE VERSION: [3] 06 07 08 => OK +len: 13 +file_id: 01 02 03 +file_ver: 03 04 05 +test_simple_sw_config(): OK +test_simple_sw_short(): OK +len: 13 +file_id: 01 02 03 +file_ver: 03 04 05 +len: 13 +file_id: 09 07 05 +file_ver: 06 07 08 +test_dual_sw_config(): OK +OK. diff --git a/tests/testsuite.at b/tests/testsuite.at index 64df724..7ee0164 100644 --- a/tests/testsuite.at +++ b/tests/testsuite.at @@ -9,6 +9,12 @@ AT_CHECK([$abs_top_builddir/tests/a5/a5_test], [0], [expout]) AT_CLEANUP +AT_SETUP([abis]) +AT_KEYWORDS([abis]) +cat $abs_srcdir/abis/abis_test.ok > expout +AT_CHECK([$abs_top_builddir/tests/abis/abis_test], [0], [expout], [ignore]) +AT_CLEANUP + AT_SETUP([ctrl]) AT_KEYWORDS([ctrl]) cat $abs_srcdir/ctrl/ctrl_test.ok > expout -- To view, visit https://gerrit.osmocom.org/2165 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ib63b6b5e83b8914864fc7edd789f8958cdc993cd Gerrit-PatchSet: 14 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Tue Apr 11 15:22:48 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Tue, 11 Apr 2017 15:22:48 +0000 Subject: [PATCH] openbsc[master]: Move string - BTS type conversion to shared header In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2286 to look at the new patch set (#3). Move string - BTS type conversion to shared header Move value_string definition and corresponding functions to shared header to make it re-usable by OsmoBTS. While at it - rename for consistency. Change-Id: Ida94725a6fce968443541e3526f48f13758031fd Related: OS#1614 --- M openbsc/include/openbsc/gsm_data_shared.h M openbsc/src/libbsc/bsc_vty.c M openbsc/src/libcommon/gsm_data.c M openbsc/src/libcommon/gsm_data_shared.c 4 files changed, 23 insertions(+), 21 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/86/2286/3 diff --git a/openbsc/include/openbsc/gsm_data_shared.h b/openbsc/include/openbsc/gsm_data_shared.h index 242889a..f636b06 100644 --- a/openbsc/include/openbsc/gsm_data_shared.h +++ b/openbsc/include/openbsc/gsm_data_shared.h @@ -859,6 +859,8 @@ struct gsm_bts_trx *gsm_bts_trx_alloc(struct gsm_bts *bts); struct gsm_bts_trx *gsm_bts_trx_num(const struct gsm_bts *bts, int num); +enum gsm_bts_type str2btstype(const char *arg); +const char *btstype2str(enum gsm_bts_type type); const struct value_string gsm_pchant_names[13]; const struct value_string gsm_pchant_descs[13]; diff --git a/openbsc/src/libbsc/bsc_vty.c b/openbsc/src/libbsc/bsc_vty.c index c1882fc..702af4a 100644 --- a/openbsc/src/libbsc/bsc_vty.c +++ b/openbsc/src/libbsc/bsc_vty.c @@ -1615,7 +1615,7 @@ struct gsm_bts *bts = vty->index; int rc; - rc = gsm_set_bts_type(bts, parse_btstype(argv[0])); + rc = gsm_set_bts_type(bts, str2btstype(argv[0])); if (rc < 0) return CMD_WARNING; diff --git a/openbsc/src/libcommon/gsm_data.c b/openbsc/src/libcommon/gsm_data.c index fd34793..8ec0be5 100644 --- a/openbsc/src/libcommon/gsm_data.c +++ b/openbsc/src/libcommon/gsm_data.c @@ -90,16 +90,6 @@ return NULL; } -const struct value_string bts_type_names[_NUM_GSM_BTS_TYPE+1] = { - { GSM_BTS_TYPE_UNKNOWN, "unknown" }, - { GSM_BTS_TYPE_BS11, "bs11" }, - { GSM_BTS_TYPE_NANOBTS, "nanobts" }, - { GSM_BTS_TYPE_RBS2000, "rbs2000" }, - { GSM_BTS_TYPE_NOKIA_SITE, "nokia_site" }, - { GSM_BTS_TYPE_OSMOBTS, "sysmobts" }, - { 0, NULL } -}; - const struct value_string bts_type_descs[_NUM_GSM_BTS_TYPE+1] = { { GSM_BTS_TYPE_UNKNOWN, "Unknown BTS Type" }, { GSM_BTS_TYPE_BS11, "Siemens BTS (BS-11 or compatible)" }, @@ -109,16 +99,6 @@ { GSM_BTS_TYPE_OSMOBTS, "sysmocom sysmoBTS" }, { 0, NULL } }; - -enum gsm_bts_type parse_btstype(const char *arg) -{ - return get_string_value(bts_type_names, arg); -} - -const char *btstype2str(enum gsm_bts_type type) -{ - return get_value_string(bts_type_names, type); -} struct gsm_bts_trx *gsm_bts_trx_by_nr(struct gsm_bts *bts, int nr) { diff --git a/openbsc/src/libcommon/gsm_data_shared.c b/openbsc/src/libcommon/gsm_data_shared.c index 387af70..8bca933 100644 --- a/openbsc/src/libcommon/gsm_data_shared.c +++ b/openbsc/src/libcommon/gsm_data_shared.c @@ -51,6 +51,26 @@ gsm_abis_mo_reset(mo); } +const struct value_string bts_type_names[_NUM_GSM_BTS_TYPE + 1] = { + { GSM_BTS_TYPE_UNKNOWN, "unknown" }, + { GSM_BTS_TYPE_BS11, "bs11" }, + { GSM_BTS_TYPE_NANOBTS, "nanobts" }, + { GSM_BTS_TYPE_RBS2000, "rbs2000" }, + { GSM_BTS_TYPE_NOKIA_SITE, "nokia_site" }, + { GSM_BTS_TYPE_OSMOBTS, "sysmobts" }, + { 0, NULL } +}; + +enum gsm_bts_type str2btstype(const char *arg) +{ + return get_string_value(bts_type_names, arg); +} + +const char *btstype2str(enum gsm_bts_type type) +{ + return get_value_string(bts_type_names, type); +} + const struct value_string gsm_pchant_names[13] = { { GSM_PCHAN_NONE, "NONE" }, { GSM_PCHAN_CCCH, "CCCH" }, -- To view, visit https://gerrit.osmocom.org/2286 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ida94725a6fce968443541e3526f48f13758031fd Gerrit-PatchSet: 3 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Apr 11 16:30:07 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Tue, 11 Apr 2017 16:30:07 +0000 Subject: [PATCH] openbsc[master]: Move gsm_bts_type_variant to gsm_bts struct Message-ID: Review at https://gerrit.osmocom.org/2294 Move gsm_bts_type_variant to gsm_bts struct Previously it was in gsm_bts_model which is not initialized on BTS side. It's more convenient to have it in the struct which is available to both BSC and BTS. Change-Id: I54fde8c4ccd5d994af08074f5864446e79a93a25 Related: OS#1614 --- M openbsc/include/openbsc/gsm_data_shared.h 1 file changed, 1 insertion(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/94/2294/1 diff --git a/openbsc/include/openbsc/gsm_data_shared.h b/openbsc/include/openbsc/gsm_data_shared.h index 242889a..9c713fd 100644 --- a/openbsc/include/openbsc/gsm_data_shared.h +++ b/openbsc/include/openbsc/gsm_data_shared.h @@ -510,7 +510,6 @@ struct llist_head list; enum gsm_bts_type type; - enum gsm_bts_type_variant variant; const char *name; bool started; @@ -663,6 +662,7 @@ uint8_t bsic; /* type of BTS */ enum gsm_bts_type type; + enum gsm_bts_type_variant variant; struct gsm_bts_model *model; enum gsm_band band; char version[MAX_VERSION_LENGTH]; -- To view, visit https://gerrit.osmocom.org/2294 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I54fde8c4ccd5d994af08074f5864446e79a93a25 Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Max From gerrit-no-reply at lists.osmocom.org Tue Apr 11 16:33:48 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 11 Apr 2017 16:33:48 +0000 Subject: [PATCH] libosmo-netif[master]: Add void osmo_stream_{cli, srv_link}_set_nodelay() function Message-ID: Review at https://gerrit.osmocom.org/2295 Add void osmo_stream_{cli,srv_link}_set_nodelay() function Using this function, the user can configure if sockets related to the respective stream client or server should have the NODELAY socket option set in order to avoid Nagle algorithm or related algorithms that may introduce packet delay on the transmitter side. Change-Id: Ibeb9ba227bab18f7f4f16518c0022c4f003cc8e9 --- M include/osmocom/netif/stream.h M src/stream.c 2 files changed, 67 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-netif refs/changes/95/2295/1 diff --git a/include/osmocom/netif/stream.h b/include/osmocom/netif/stream.h index 63eccf8..7afb7af 100644 --- a/include/osmocom/netif/stream.h +++ b/include/osmocom/netif/stream.h @@ -16,6 +16,7 @@ struct osmo_stream_srv_link *osmo_stream_srv_link_create(void *ctx); void osmo_stream_srv_link_destroy(struct osmo_stream_srv_link *link); +void osmo_stream_srv_link_set_nodelay(struct osmo_stream_srv_link *link, bool nodelay); void osmo_stream_srv_link_set_addr(struct osmo_stream_srv_link *link, const char *addr); void osmo_stream_srv_link_set_port(struct osmo_stream_srv_link *link, uint16_t port); void osmo_stream_srv_link_set_proto(struct osmo_stream_srv_link *link, uint16_t proto); @@ -45,6 +46,7 @@ /*! \brief Osmocom Stream Client: Single client connection */ struct osmo_stream_cli; +void osmo_stream_cli_set_nodelay(struct osmo_stream_cli *cli, bool nodelay); void osmo_stream_cli_set_addr(struct osmo_stream_cli *cli, const char *addr); void osmo_stream_cli_set_port(struct osmo_stream_cli *cli, uint16_t port); void osmo_stream_cli_set_proto(struct osmo_stream_cli *cli, uint16_t proto); diff --git a/src/stream.c b/src/stream.c index f5ead17..76886f0 100644 --- a/src/stream.c +++ b/src/stream.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -75,6 +76,7 @@ }; #define OSMO_STREAM_CLI_F_RECONF (1 << 0) +#define OSMO_STREAM_CLI_F_NODELAY (1 << 1) struct osmo_stream_cli { struct osmo_fd ofd; @@ -400,6 +402,22 @@ return ret; } + if (cli->flags & OSMO_STREAM_CLI_F_NODELAY) { + int on = 1; + switch (cli->proto) { + case IPPROTO_TCP: + setsockopt(cli->ofd.fd, SOL_TCP, TCP_NODELAY, &on, sizeof(on)); + break; + case IPPROTO_SCTP: + setsockopt(cli->ofd.fd, SOL_SCTP, SCTP_NODELAY, &on, sizeof(on)); + break; + default: + LOGP(DLINP, LOGL_ERROR, "Unknown protocol %u, cannot set NODELAY\n", + cli->proto); + break; + } + } + cli->ofd.fd = ret; if (osmo_fd_register(&cli->ofd) < 0) { close(ret); @@ -409,6 +427,21 @@ return 0; } +/*! \brief Set the NODELAY socket option to avoid Nagle-like behavior + * Setting this to nodelay=true will automatically set the NODELAY + * socket option on any socket established via \ref osmo_stream_cli_open + * or any re-connect. You have to set this _before_ opening the + * socket. + * \param[in] cli Stream client whose sockets are to be configured + * \param[in] nodelay whether to set (true) NODELAY before connect() + */ +void osmo_stream_cli_set_nodelay(struct osmo_stream_cli *cli, bool nodelay) +{ + if (nodelay) + cli->flags |= OSMO_STREAM_CLI_F_NODELAY; + else + cli->flags &= ~OSMO_STREAM_CLI_F_NODELAY; +} /*! \brief Open connection of an Osmocom stream client * \param[in] cli Stream Client to connect */ @@ -473,6 +506,7 @@ */ #define OSMO_STREAM_SRV_F_RECONF (1 << 0) +#define OSMO_STREAM_SRV_F_NODELAY (1 << 1) struct osmo_stream_srv_link { struct osmo_fd ofd; @@ -503,6 +537,22 @@ if (link->proto == IPPROTO_SCTP) sctp_sock_activate_events(ret); + if (link->flags & OSMO_STREAM_SRV_F_NODELAY) { + int on = 1; + switch (link->proto) { + case IPPROTO_SCTP: + setsockopt(ret, SOL_SCTP, SCTP_NODELAY, &on, sizeof(on)); + break; + case IPPROTO_TCP: + setsockopt(ret, SOL_TCP, TCP_NODELAY, &on, sizeof(on)); + break; + default: + LOGP(DLINP, LOGL_ERROR, "Unknown protocol %u, cannot set NODELAY\n", + link->proto); + break; + } + } + if (link->accept_cb) link->accept_cb(link, ret); @@ -532,6 +582,21 @@ return link; } +/*! \brief Set the NODELAY socket option to avoid Nagle-like behavior + * Setting this to nodelay=true will automatically set the NODELAY + * socket option on any socket established via this server link, before + * calling the accept_cb() + * \param[in] link server link whose sockets are to be configured + * \param[in] nodelay whether to set (true) NODELAY after accept + */ +void osmo_stream_srv_link_set_nodelay(struct osmo_stream_srv_link *link, bool nodelay) +{ + if (nodelay) + link->flags |= OSMO_STREAM_SRV_F_NODELAY; + else + link->flags &= ~OSMO_STREAM_SRV_F_NODELAY; +} + /*! \brief Set the local address to which we bind * \param[in] link Stream Server Link to modify * \param[in] addr Local IP address -- To view, visit https://gerrit.osmocom.org/2295 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ibeb9ba227bab18f7f4f16518c0022c4f003cc8e9 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Tue Apr 11 16:34:02 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 11 Apr 2017 16:34:02 +0000 Subject: [PATCH] libosmo-netif[master]: Add osmo_stream_{cli, srv_link}_set_nodelay() function In-Reply-To: References: Message-ID: Add osmo_stream_{cli,srv_link}_set_nodelay() function Using this function, the user can configure if sockets related to the respective stream client or server should have the NODELAY socket option set in order to avoid Nagle algorithm or related algorithms that may introduce packet delay on the transmitter side. Change-Id: Ibeb9ba227bab18f7f4f16518c0022c4f003cc8e9 --- M include/osmocom/netif/stream.h M src/stream.c 2 files changed, 67 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-netif refs/changes/95/2295/2 diff --git a/include/osmocom/netif/stream.h b/include/osmocom/netif/stream.h index 63eccf8..7afb7af 100644 --- a/include/osmocom/netif/stream.h +++ b/include/osmocom/netif/stream.h @@ -16,6 +16,7 @@ struct osmo_stream_srv_link *osmo_stream_srv_link_create(void *ctx); void osmo_stream_srv_link_destroy(struct osmo_stream_srv_link *link); +void osmo_stream_srv_link_set_nodelay(struct osmo_stream_srv_link *link, bool nodelay); void osmo_stream_srv_link_set_addr(struct osmo_stream_srv_link *link, const char *addr); void osmo_stream_srv_link_set_port(struct osmo_stream_srv_link *link, uint16_t port); void osmo_stream_srv_link_set_proto(struct osmo_stream_srv_link *link, uint16_t proto); @@ -45,6 +46,7 @@ /*! \brief Osmocom Stream Client: Single client connection */ struct osmo_stream_cli; +void osmo_stream_cli_set_nodelay(struct osmo_stream_cli *cli, bool nodelay); void osmo_stream_cli_set_addr(struct osmo_stream_cli *cli, const char *addr); void osmo_stream_cli_set_port(struct osmo_stream_cli *cli, uint16_t port); void osmo_stream_cli_set_proto(struct osmo_stream_cli *cli, uint16_t proto); diff --git a/src/stream.c b/src/stream.c index f5ead17..76886f0 100644 --- a/src/stream.c +++ b/src/stream.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -75,6 +76,7 @@ }; #define OSMO_STREAM_CLI_F_RECONF (1 << 0) +#define OSMO_STREAM_CLI_F_NODELAY (1 << 1) struct osmo_stream_cli { struct osmo_fd ofd; @@ -400,6 +402,22 @@ return ret; } + if (cli->flags & OSMO_STREAM_CLI_F_NODELAY) { + int on = 1; + switch (cli->proto) { + case IPPROTO_TCP: + setsockopt(cli->ofd.fd, SOL_TCP, TCP_NODELAY, &on, sizeof(on)); + break; + case IPPROTO_SCTP: + setsockopt(cli->ofd.fd, SOL_SCTP, SCTP_NODELAY, &on, sizeof(on)); + break; + default: + LOGP(DLINP, LOGL_ERROR, "Unknown protocol %u, cannot set NODELAY\n", + cli->proto); + break; + } + } + cli->ofd.fd = ret; if (osmo_fd_register(&cli->ofd) < 0) { close(ret); @@ -409,6 +427,21 @@ return 0; } +/*! \brief Set the NODELAY socket option to avoid Nagle-like behavior + * Setting this to nodelay=true will automatically set the NODELAY + * socket option on any socket established via \ref osmo_stream_cli_open + * or any re-connect. You have to set this _before_ opening the + * socket. + * \param[in] cli Stream client whose sockets are to be configured + * \param[in] nodelay whether to set (true) NODELAY before connect() + */ +void osmo_stream_cli_set_nodelay(struct osmo_stream_cli *cli, bool nodelay) +{ + if (nodelay) + cli->flags |= OSMO_STREAM_CLI_F_NODELAY; + else + cli->flags &= ~OSMO_STREAM_CLI_F_NODELAY; +} /*! \brief Open connection of an Osmocom stream client * \param[in] cli Stream Client to connect */ @@ -473,6 +506,7 @@ */ #define OSMO_STREAM_SRV_F_RECONF (1 << 0) +#define OSMO_STREAM_SRV_F_NODELAY (1 << 1) struct osmo_stream_srv_link { struct osmo_fd ofd; @@ -503,6 +537,22 @@ if (link->proto == IPPROTO_SCTP) sctp_sock_activate_events(ret); + if (link->flags & OSMO_STREAM_SRV_F_NODELAY) { + int on = 1; + switch (link->proto) { + case IPPROTO_SCTP: + setsockopt(ret, SOL_SCTP, SCTP_NODELAY, &on, sizeof(on)); + break; + case IPPROTO_TCP: + setsockopt(ret, SOL_TCP, TCP_NODELAY, &on, sizeof(on)); + break; + default: + LOGP(DLINP, LOGL_ERROR, "Unknown protocol %u, cannot set NODELAY\n", + link->proto); + break; + } + } + if (link->accept_cb) link->accept_cb(link, ret); @@ -532,6 +582,21 @@ return link; } +/*! \brief Set the NODELAY socket option to avoid Nagle-like behavior + * Setting this to nodelay=true will automatically set the NODELAY + * socket option on any socket established via this server link, before + * calling the accept_cb() + * \param[in] link server link whose sockets are to be configured + * \param[in] nodelay whether to set (true) NODELAY after accept + */ +void osmo_stream_srv_link_set_nodelay(struct osmo_stream_srv_link *link, bool nodelay) +{ + if (nodelay) + link->flags |= OSMO_STREAM_SRV_F_NODELAY; + else + link->flags &= ~OSMO_STREAM_SRV_F_NODELAY; +} + /*! \brief Set the local address to which we bind * \param[in] link Stream Server Link to modify * \param[in] addr Local IP address -- To view, visit https://gerrit.osmocom.org/2295 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ibeb9ba227bab18f7f4f16518c0022c4f003cc8e9 Gerrit-PatchSet: 2 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Apr 11 16:51:58 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Tue, 11 Apr 2017 16:51:58 +0000 Subject: [PATCH] openbsc[master]: Make BTS type and variant convertors shareable In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2286 to look at the new patch set (#4). Make BTS type and variant convertors shareable * move value_string definition and corresponding functions for BTS type to shared header to make it re-usable by OsmoBTS * use consistent function naming * add similar functions for BTS variant Change-Id: Ida94725a6fce968443541e3526f48f13758031fd Related: OS#1614 --- M openbsc/include/openbsc/gsm_data_shared.h M openbsc/src/libbsc/bsc_vty.c M openbsc/src/libcommon/gsm_data.c M openbsc/src/libcommon/gsm_data_shared.c 4 files changed, 45 insertions(+), 21 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/86/2286/4 diff --git a/openbsc/include/openbsc/gsm_data_shared.h b/openbsc/include/openbsc/gsm_data_shared.h index 242889a..6e977dd 100644 --- a/openbsc/include/openbsc/gsm_data_shared.h +++ b/openbsc/include/openbsc/gsm_data_shared.h @@ -859,6 +859,11 @@ struct gsm_bts_trx *gsm_bts_trx_alloc(struct gsm_bts *bts); struct gsm_bts_trx *gsm_bts_trx_num(const struct gsm_bts *bts, int num); +enum gsm_bts_type str2btstype(const char *arg); +const char *btstype2str(enum gsm_bts_type type); + +enum gsm_bts_type str2btsvariant(const char *arg); +const char *btsvariant2str(enum gsm_bts_type_variant v); const struct value_string gsm_pchant_names[13]; const struct value_string gsm_pchant_descs[13]; diff --git a/openbsc/src/libbsc/bsc_vty.c b/openbsc/src/libbsc/bsc_vty.c index c1882fc..702af4a 100644 --- a/openbsc/src/libbsc/bsc_vty.c +++ b/openbsc/src/libbsc/bsc_vty.c @@ -1615,7 +1615,7 @@ struct gsm_bts *bts = vty->index; int rc; - rc = gsm_set_bts_type(bts, parse_btstype(argv[0])); + rc = gsm_set_bts_type(bts, str2btstype(argv[0])); if (rc < 0) return CMD_WARNING; diff --git a/openbsc/src/libcommon/gsm_data.c b/openbsc/src/libcommon/gsm_data.c index fd34793..8ec0be5 100644 --- a/openbsc/src/libcommon/gsm_data.c +++ b/openbsc/src/libcommon/gsm_data.c @@ -90,16 +90,6 @@ return NULL; } -const struct value_string bts_type_names[_NUM_GSM_BTS_TYPE+1] = { - { GSM_BTS_TYPE_UNKNOWN, "unknown" }, - { GSM_BTS_TYPE_BS11, "bs11" }, - { GSM_BTS_TYPE_NANOBTS, "nanobts" }, - { GSM_BTS_TYPE_RBS2000, "rbs2000" }, - { GSM_BTS_TYPE_NOKIA_SITE, "nokia_site" }, - { GSM_BTS_TYPE_OSMOBTS, "sysmobts" }, - { 0, NULL } -}; - const struct value_string bts_type_descs[_NUM_GSM_BTS_TYPE+1] = { { GSM_BTS_TYPE_UNKNOWN, "Unknown BTS Type" }, { GSM_BTS_TYPE_BS11, "Siemens BTS (BS-11 or compatible)" }, @@ -109,16 +99,6 @@ { GSM_BTS_TYPE_OSMOBTS, "sysmocom sysmoBTS" }, { 0, NULL } }; - -enum gsm_bts_type parse_btstype(const char *arg) -{ - return get_string_value(bts_type_names, arg); -} - -const char *btstype2str(enum gsm_bts_type type) -{ - return get_value_string(bts_type_names, type); -} struct gsm_bts_trx *gsm_bts_trx_by_nr(struct gsm_bts *bts, int nr) { diff --git a/openbsc/src/libcommon/gsm_data_shared.c b/openbsc/src/libcommon/gsm_data_shared.c index 387af70..870458b 100644 --- a/openbsc/src/libcommon/gsm_data_shared.c +++ b/openbsc/src/libcommon/gsm_data_shared.c @@ -51,6 +51,45 @@ gsm_abis_mo_reset(mo); } +const struct value_string bts_variant_names[_NUM_BTS_VARIANT + 1] = { + { BTS_UNKNOWN, "unknown" }, + { BTS_OSMO_LITECELL15, "Litecell15" }, + { BTS_OSMO_OCTPHY, "OctPHY" }, + { BTS_OSMO_SYSMO, "Sysmo" }, + { BTS_OSMO_TRX, "TRX" }, + { 0, NULL } +}; + +enum gsm_bts_type str2btsvariant(const char *arg) +{ + return get_string_value(bts_variant_names, arg); +} + +const char *btsvariant2str(enum gsm_bts_type_variant v) +{ + return get_value_string(bts_variant_names, v); +} + +const struct value_string bts_type_names[_NUM_GSM_BTS_TYPE + 1] = { + { GSM_BTS_TYPE_UNKNOWN, "unknown" }, + { GSM_BTS_TYPE_BS11, "bs11" }, + { GSM_BTS_TYPE_NANOBTS, "nanobts" }, + { GSM_BTS_TYPE_RBS2000, "rbs2000" }, + { GSM_BTS_TYPE_NOKIA_SITE, "nokia_site" }, + { GSM_BTS_TYPE_OSMOBTS, "sysmobts" }, + { 0, NULL } +}; + +enum gsm_bts_type str2btstype(const char *arg) +{ + return get_string_value(bts_type_names, arg); +} + +const char *btstype2str(enum gsm_bts_type type) +{ + return get_value_string(bts_type_names, type); +} + const struct value_string gsm_pchant_names[13] = { { GSM_PCHAN_NONE, "NONE" }, { GSM_PCHAN_CCCH, "CCCH" }, -- To view, visit https://gerrit.osmocom.org/2286 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ida94725a6fce968443541e3526f48f13758031fd Gerrit-PatchSet: 4 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Apr 11 16:56:05 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Tue, 11 Apr 2017 16:56:05 +0000 Subject: [PATCH] openbsc[master]: Add gsm_bts_type_variant to gsm_bts struct In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2294 to look at the new patch set (#2). Add gsm_bts_type_variant to gsm_bts struct Previously it was only in gsm_bts_model which is not initialized on BTS side. It's more convenient to have it in the struct which is available to BTS as well. Change-Id: I54fde8c4ccd5d994af08074f5864446e79a93a25 Related: OS#1614 --- M openbsc/include/openbsc/gsm_data_shared.h 1 file changed, 1 insertion(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/94/2294/2 diff --git a/openbsc/include/openbsc/gsm_data_shared.h b/openbsc/include/openbsc/gsm_data_shared.h index 242889a..00bc2f8 100644 --- a/openbsc/include/openbsc/gsm_data_shared.h +++ b/openbsc/include/openbsc/gsm_data_shared.h @@ -663,6 +663,7 @@ uint8_t bsic; /* type of BTS */ enum gsm_bts_type type; + enum gsm_bts_type_variant variant; struct gsm_bts_model *model; enum gsm_band band; char version[MAX_VERSION_LENGTH]; -- To view, visit https://gerrit.osmocom.org/2294 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I54fde8c4ccd5d994af08074f5864446e79a93a25 Gerrit-PatchSet: 2 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Apr 11 17:15:31 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 11 Apr 2017 17:15:31 +0000 Subject: [PATCH] libosmo-netif[master]: Add osmo_stream_{cli, srv_link}_set_nodelay() function In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2295 to look at the new patch set (#3). Add osmo_stream_{cli,srv_link}_set_nodelay() function Using this function, the user can configure if sockets related to the respective stream client or server should have the NODELAY socket option set in order to avoid Nagle algorithm or related algorithms that may introduce packet delay on the transmitter side. Change-Id: Ibeb9ba227bab18f7f4f16518c0022c4f003cc8e9 --- M include/osmocom/netif/stream.h M src/stream.c 2 files changed, 67 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-netif refs/changes/95/2295/3 diff --git a/include/osmocom/netif/stream.h b/include/osmocom/netif/stream.h index 63eccf8..7afb7af 100644 --- a/include/osmocom/netif/stream.h +++ b/include/osmocom/netif/stream.h @@ -16,6 +16,7 @@ struct osmo_stream_srv_link *osmo_stream_srv_link_create(void *ctx); void osmo_stream_srv_link_destroy(struct osmo_stream_srv_link *link); +void osmo_stream_srv_link_set_nodelay(struct osmo_stream_srv_link *link, bool nodelay); void osmo_stream_srv_link_set_addr(struct osmo_stream_srv_link *link, const char *addr); void osmo_stream_srv_link_set_port(struct osmo_stream_srv_link *link, uint16_t port); void osmo_stream_srv_link_set_proto(struct osmo_stream_srv_link *link, uint16_t proto); @@ -45,6 +46,7 @@ /*! \brief Osmocom Stream Client: Single client connection */ struct osmo_stream_cli; +void osmo_stream_cli_set_nodelay(struct osmo_stream_cli *cli, bool nodelay); void osmo_stream_cli_set_addr(struct osmo_stream_cli *cli, const char *addr); void osmo_stream_cli_set_port(struct osmo_stream_cli *cli, uint16_t port); void osmo_stream_cli_set_proto(struct osmo_stream_cli *cli, uint16_t proto); diff --git a/src/stream.c b/src/stream.c index f5ead17..9ab0ab3 100644 --- a/src/stream.c +++ b/src/stream.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -75,6 +76,7 @@ }; #define OSMO_STREAM_CLI_F_RECONF (1 << 0) +#define OSMO_STREAM_CLI_F_NODELAY (1 << 1) struct osmo_stream_cli { struct osmo_fd ofd; @@ -400,6 +402,22 @@ return ret; } + if (cli->flags & OSMO_STREAM_CLI_F_NODELAY) { + int on = 1; + switch (cli->proto) { + case IPPROTO_TCP: + setsockopt(cli->ofd.fd, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on)); + break; + case IPPROTO_SCTP: + setsockopt(cli->ofd.fd, IPPROTO_SCTP, SCTP_NODELAY, &on, sizeof(on)); + break; + default: + LOGP(DLINP, LOGL_ERROR, "Unknown protocol %u, cannot set NODELAY\n", + cli->proto); + break; + } + } + cli->ofd.fd = ret; if (osmo_fd_register(&cli->ofd) < 0) { close(ret); @@ -409,6 +427,21 @@ return 0; } +/*! \brief Set the NODELAY socket option to avoid Nagle-like behavior + * Setting this to nodelay=true will automatically set the NODELAY + * socket option on any socket established via \ref osmo_stream_cli_open + * or any re-connect. You have to set this _before_ opening the + * socket. + * \param[in] cli Stream client whose sockets are to be configured + * \param[in] nodelay whether to set (true) NODELAY before connect() + */ +void osmo_stream_cli_set_nodelay(struct osmo_stream_cli *cli, bool nodelay) +{ + if (nodelay) + cli->flags |= OSMO_STREAM_CLI_F_NODELAY; + else + cli->flags &= ~OSMO_STREAM_CLI_F_NODELAY; +} /*! \brief Open connection of an Osmocom stream client * \param[in] cli Stream Client to connect */ @@ -473,6 +506,7 @@ */ #define OSMO_STREAM_SRV_F_RECONF (1 << 0) +#define OSMO_STREAM_SRV_F_NODELAY (1 << 1) struct osmo_stream_srv_link { struct osmo_fd ofd; @@ -503,6 +537,22 @@ if (link->proto == IPPROTO_SCTP) sctp_sock_activate_events(ret); + if (link->flags & OSMO_STREAM_SRV_F_NODELAY) { + int on = 1; + switch (link->proto) { + case IPPROTO_SCTP: + setsockopt(ret, IPPROTO_SCTP, SCTP_NODELAY, &on, sizeof(on)); + break; + case IPPROTO_TCP: + setsockopt(ret, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on)); + break; + default: + LOGP(DLINP, LOGL_ERROR, "Unknown protocol %u, cannot set NODELAY\n", + link->proto); + break; + } + } + if (link->accept_cb) link->accept_cb(link, ret); @@ -532,6 +582,21 @@ return link; } +/*! \brief Set the NODELAY socket option to avoid Nagle-like behavior + * Setting this to nodelay=true will automatically set the NODELAY + * socket option on any socket established via this server link, before + * calling the accept_cb() + * \param[in] link server link whose sockets are to be configured + * \param[in] nodelay whether to set (true) NODELAY after accept + */ +void osmo_stream_srv_link_set_nodelay(struct osmo_stream_srv_link *link, bool nodelay) +{ + if (nodelay) + link->flags |= OSMO_STREAM_SRV_F_NODELAY; + else + link->flags &= ~OSMO_STREAM_SRV_F_NODELAY; +} + /*! \brief Set the local address to which we bind * \param[in] link Stream Server Link to modify * \param[in] addr Local IP address -- To view, visit https://gerrit.osmocom.org/2295 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ibeb9ba227bab18f7f4f16518c0022c4f003cc8e9 Gerrit-PatchSet: 3 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Apr 11 17:49:58 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 11 Apr 2017 17:49:58 +0000 Subject: libosmo-netif[master]: Add osmo_stream_{cli, srv_link}_set_nodelay() function In-Reply-To: References: Message-ID: Patch Set 3: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2295 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ibeb9ba227bab18f7f4f16518c0022c4f003cc8e9 Gerrit-PatchSet: 3 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Apr 11 17:54:15 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 11 Apr 2017 17:54:15 +0000 Subject: [PATCH] libosmo-netif[master]: Add osmo_stream_{cli, srv_link}_set_nodelay() function In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2295 to look at the new patch set (#4). Add osmo_stream_{cli,srv_link}_set_nodelay() function Using this function, the user can configure if sockets related to the respective stream client or server should have the NODELAY socket option set in order to avoid Nagle algorithm or related algorithms that may introduce packet delay on the transmitter side. Change-Id: Ibeb9ba227bab18f7f4f16518c0022c4f003cc8e9 --- M include/osmocom/netif/stream.h M src/stream.c 2 files changed, 62 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-netif refs/changes/95/2295/4 diff --git a/include/osmocom/netif/stream.h b/include/osmocom/netif/stream.h index 63eccf8..7afb7af 100644 --- a/include/osmocom/netif/stream.h +++ b/include/osmocom/netif/stream.h @@ -16,6 +16,7 @@ struct osmo_stream_srv_link *osmo_stream_srv_link_create(void *ctx); void osmo_stream_srv_link_destroy(struct osmo_stream_srv_link *link); +void osmo_stream_srv_link_set_nodelay(struct osmo_stream_srv_link *link, bool nodelay); void osmo_stream_srv_link_set_addr(struct osmo_stream_srv_link *link, const char *addr); void osmo_stream_srv_link_set_port(struct osmo_stream_srv_link *link, uint16_t port); void osmo_stream_srv_link_set_proto(struct osmo_stream_srv_link *link, uint16_t proto); @@ -45,6 +46,7 @@ /*! \brief Osmocom Stream Client: Single client connection */ struct osmo_stream_cli; +void osmo_stream_cli_set_nodelay(struct osmo_stream_cli *cli, bool nodelay); void osmo_stream_cli_set_addr(struct osmo_stream_cli *cli, const char *addr); void osmo_stream_cli_set_port(struct osmo_stream_cli *cli, uint16_t port); void osmo_stream_cli_set_proto(struct osmo_stream_cli *cli, uint16_t proto); diff --git a/src/stream.c b/src/stream.c index f5ead17..3bc36a3 100644 --- a/src/stream.c +++ b/src/stream.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -63,6 +64,27 @@ #endif } +static int setsockopt_nodelay(int fd, int proto, int on) +{ + int rc; + + switch (proto) { + case IPPROTO_SCTP: + rc = setsockopt(fd, IPPROTO_SCTP, SCTP_NODELAY, &on, sizeof(on)); + break; + case IPPROTO_TCP: + rc = setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on)); + break; + default: + rc = -1; + LOGP(DLINP, LOGL_ERROR, "Unknown protocol %u, cannot set NODELAY\n", + proto); + break; + } + return rc; +} + + /* * Client side. */ @@ -75,6 +97,7 @@ }; #define OSMO_STREAM_CLI_F_RECONF (1 << 0) +#define OSMO_STREAM_CLI_F_NODELAY (1 << 1) struct osmo_stream_cli { struct osmo_fd ofd; @@ -400,6 +423,9 @@ return ret; } + if (cli->flags & OSMO_STREAM_CLI_F_NODELAY) + setsockopt_nodelay(cli->ofd.fd, cli->proto, 1); + cli->ofd.fd = ret; if (osmo_fd_register(&cli->ofd) < 0) { close(ret); @@ -409,6 +435,21 @@ return 0; } +/*! \brief Set the NODELAY socket option to avoid Nagle-like behavior + * Setting this to nodelay=true will automatically set the NODELAY + * socket option on any socket established via \ref osmo_stream_cli_open + * or any re-connect. You have to set this _before_ opening the + * socket. + * \param[in] cli Stream client whose sockets are to be configured + * \param[in] nodelay whether to set (true) NODELAY before connect() + */ +void osmo_stream_cli_set_nodelay(struct osmo_stream_cli *cli, bool nodelay) +{ + if (nodelay) + cli->flags |= OSMO_STREAM_CLI_F_NODELAY; + else + cli->flags &= ~OSMO_STREAM_CLI_F_NODELAY; +} /*! \brief Open connection of an Osmocom stream client * \param[in] cli Stream Client to connect */ @@ -473,6 +514,7 @@ */ #define OSMO_STREAM_SRV_F_RECONF (1 << 0) +#define OSMO_STREAM_SRV_F_NODELAY (1 << 1) struct osmo_stream_srv_link { struct osmo_fd ofd; @@ -503,6 +545,9 @@ if (link->proto == IPPROTO_SCTP) sctp_sock_activate_events(ret); + if (link->flags & OSMO_STREAM_SRV_F_NODELAY) + setsockopt_nodelay(ret, link->proto, 1); + if (link->accept_cb) link->accept_cb(link, ret); @@ -532,6 +577,21 @@ return link; } +/*! \brief Set the NODELAY socket option to avoid Nagle-like behavior + * Setting this to nodelay=true will automatically set the NODELAY + * socket option on any socket established via this server link, before + * calling the accept_cb() + * \param[in] link server link whose sockets are to be configured + * \param[in] nodelay whether to set (true) NODELAY after accept + */ +void osmo_stream_srv_link_set_nodelay(struct osmo_stream_srv_link *link, bool nodelay) +{ + if (nodelay) + link->flags |= OSMO_STREAM_SRV_F_NODELAY; + else + link->flags &= ~OSMO_STREAM_SRV_F_NODELAY; +} + /*! \brief Set the local address to which we bind * \param[in] link Stream Server Link to modify * \param[in] addr Local IP address -- To view, visit https://gerrit.osmocom.org/2295 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ibeb9ba227bab18f7f4f16518c0022c4f003cc8e9 Gerrit-PatchSet: 4 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From admin at opensuse.org Tue Apr 11 20:02:49 2017 From: admin at opensuse.org (OBS Notification) Date: Tue, 11 Apr 2017 20:02:49 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in xUbuntu_16.04/i586 In-Reply-To: References: Message-ID: <58ed368168b54_c7610b4f7c3215f4@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/xUbuntu_16.04/i586 Package network:osmocom:nightly/osmo-stp failed to build in xUbuntu_16.04/i586 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 123s] sctp_m2ua.c:91:3: warning: #warning "Notify any other AS(P) for failover scenario" [-Wcpp] [ 123s] #warning "Notify any other AS(P) for failover scenario" [ 123s] ^ [ 124s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -c -o vty_interface.o vty_interface.c [ 124s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -c -o sctp_m3ua_client.o sctp_m3ua_client.c [ 124s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 124s] compilation terminated. [ 124s] Makefile:485: recipe for target 'sctp_m3ua_client.o' failed [ 124s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 124s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 124s] Makefile:380: recipe for target 'all-recursive' failed [ 124s] make[2]: *** [all-recursive] Error 1 [ 124s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 124s] Makefile:321: recipe for target 'all' failed [ 124s] make[1]: *** [all] Error 2 [ 124s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 124s] dh_auto_build: make -j1 returned exit code 2 [ 124s] debian/rules:23: recipe for target 'build' failed [ 124s] make: *** [build] Error 2 [ 124s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 124s] [ 124s] cloud115 failed "build cellmgr-ng_1.4.7.20170411.dsc" at Tue Apr 11 20:02:40 UTC 2017. [ 124s] [ 124s] ### VM INTERACTION START ### [ 128s] [ 103.850543] reboot: Power down [ 130s] ### VM INTERACTION END ### [ 130s] [ 130s] cloud115 failed "build cellmgr-ng_1.4.7.20170411.dsc" at Tue Apr 11 20:02:46 UTC 2017. [ 130s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Tue Apr 11 20:02:49 2017 From: admin at opensuse.org (OBS Notification) Date: Tue, 11 Apr 2017 20:02:49 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in xUbuntu_16.10/i586 In-Reply-To: References: Message-ID: <58ed368114587_c7610b4f7c3214f4@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/xUbuntu_16.10/i586 Package network:osmocom:nightly/osmo-stp failed to build in xUbuntu_16.10/i586 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 76s] ^~~~~~~ [ 77s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o vty_interface.o vty_interface.c [ 77s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o sctp_m3ua_client.o sctp_m3ua_client.c [ 78s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 78s] #include [ 78s] ^ [ 78s] compilation terminated. [ 78s] Makefile:485: recipe for target 'sctp_m3ua_client.o' failed [ 78s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 78s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 78s] Makefile:380: recipe for target 'all-recursive' failed [ 78s] make[2]: *** [all-recursive] Error 1 [ 78s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 78s] Makefile:321: recipe for target 'all' failed [ 78s] make[1]: *** [all] Error 2 [ 78s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 78s] dh_auto_build: make -j1 returned exit code 2 [ 78s] debian/rules:23: recipe for target 'build' failed [ 78s] make: *** [build] Error 2 [ 78s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 78s] [ 78s] lamb73 failed "build cellmgr-ng_1.4.7.20170411.dsc" at Tue Apr 11 20:02:39 UTC 2017. [ 78s] [ 78s] ### VM INTERACTION START ### [ 81s] [ 67.646117] reboot: Power down [ 81s] ### VM INTERACTION END ### [ 81s] [ 81s] lamb73 failed "build cellmgr-ng_1.4.7.20170411.dsc" at Tue Apr 11 20:02:43 UTC 2017. [ 81s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Tue Apr 11 20:04:49 2017 From: admin at opensuse.org (OBS Notification) Date: Tue, 11 Apr 2017 20:04:49 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in Debian_8.0/i586 In-Reply-To: References: Message-ID: <58ed36f6a6f57_98f1156f84337888@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/Debian_8.0/i586 Package network:osmocom:nightly/osmo-stp failed to build in Debian_8.0/i586 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 61s] CC vty_interface.o [ 61s] CC sctp_m3ua_client.o [ 61s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 61s] #include [ 61s] ^ [ 61s] compilation terminated. [ 61s] Makefile:475: recipe for target 'sctp_m3ua_client.o' failed [ 61s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 61s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 61s] Makefile:370: recipe for target 'all-recursive' failed [ 61s] make[2]: *** [all-recursive] Error 1 [ 61s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 61s] Makefile:310: recipe for target 'all' failed [ 61s] make[1]: *** [all] Error 2 [ 61s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 61s] dh_auto_build: make -j1 returned exit code 2 [ 61s] debian/rules:23: recipe for target 'build' failed [ 61s] make: *** [build] Error 2 [ 61s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 61s] [ 61s] build74 failed "build cellmgr-ng_1.4.7.20170411.dsc" at Tue Apr 11 20:04:30 UTC 2017. [ 61s] [ 61s] ### VM INTERACTION START ### [ 62s] Powering off. [ 62s] [ 51.302464] reboot: Power down [ 63s] ### VM INTERACTION END ### [ 63s] [ 63s] build74 failed "build cellmgr-ng_1.4.7.20170411.dsc" at Tue Apr 11 20:04:32 UTC 2017. [ 63s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Tue Apr 11 20:05:58 2017 From: admin at opensuse.org (OBS Notification) Date: Tue, 11 Apr 2017 20:05:58 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in Debian_8.0/x86_64 In-Reply-To: References: Message-ID: <58ed374f3a360_98f1156f84337977@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/Debian_8.0/x86_64 Package network:osmocom:nightly/osmo-stp failed to build in Debian_8.0/x86_64 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 173s] CC vty_interface.o [ 174s] CC sctp_m3ua_client.o [ 174s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 174s] #include [ 174s] ^ [ 174s] compilation terminated. [ 174s] Makefile:475: recipe for target 'sctp_m3ua_client.o' failed [ 174s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 174s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 174s] Makefile:370: recipe for target 'all-recursive' failed [ 174s] make[2]: *** [all-recursive] Error 1 [ 174s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 174s] Makefile:310: recipe for target 'all' failed [ 174s] make[1]: *** [all] Error 2 [ 174s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 174s] dh_auto_build: make -j1 returned exit code 2 [ 174s] debian/rules:23: recipe for target 'build' failed [ 174s] make: *** [build] Error 2 [ 174s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 174s] [ 174s] cloud107 failed "build cellmgr-ng_1.4.7.20170411.dsc" at Tue Apr 11 20:05:41 UTC 2017. [ 174s] [ 174s] ### VM INTERACTION START ### [ 175s] Powering off. [ 175s] [ 143.277517] reboot: Power down [ 177s] ### VM INTERACTION END ### [ 178s] [ 178s] cloud107 failed "build cellmgr-ng_1.4.7.20170411.dsc" at Tue Apr 11 20:05:46 UTC 2017. [ 178s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Tue Apr 11 20:06:15 2017 From: admin at opensuse.org (OBS Notification) Date: Tue, 11 Apr 2017 20:06:15 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in xUbuntu_16.10/x86_64 In-Reply-To: References: Message-ID: <58ed37502bbfb_98f1156f84338061@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/xUbuntu_16.10/x86_64 Package network:osmocom:nightly/osmo-stp failed to build in xUbuntu_16.10/x86_64 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 118s] ^~~~~~~ [ 118s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o vty_interface.o vty_interface.c [ 119s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o sctp_m3ua_client.o sctp_m3ua_client.c [ 119s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 119s] #include [ 119s] ^ [ 119s] compilation terminated. [ 119s] Makefile:485: recipe for target 'sctp_m3ua_client.o' failed [ 119s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 119s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 119s] Makefile:380: recipe for target 'all-recursive' failed [ 119s] make[2]: *** [all-recursive] Error 1 [ 119s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 119s] Makefile:321: recipe for target 'all' failed [ 119s] make[1]: *** [all] Error 2 [ 119s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 119s] dh_auto_build: make -j1 returned exit code 2 [ 119s] debian/rules:23: recipe for target 'build' failed [ 119s] make: *** [build] Error 2 [ 119s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 119s] [ 119s] lamb67 failed "build cellmgr-ng_1.4.7.20170411.dsc" at Tue Apr 11 20:05:54 UTC 2017. [ 119s] [ 119s] ### VM INTERACTION START ### [ 122s] [ 107.585490] reboot: Power down [ 122s] ### VM INTERACTION END ### [ 122s] [ 122s] lamb67 failed "build cellmgr-ng_1.4.7.20170411.dsc" at Tue Apr 11 20:05:58 UTC 2017. [ 122s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Tue Apr 11 20:06:49 2017 From: admin at opensuse.org (OBS Notification) Date: Tue, 11 Apr 2017 20:06:49 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in xUbuntu_16.04/x86_64 In-Reply-To: References: Message-ID: <58ed376b4a4fe_98f1156f84338133@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/xUbuntu_16.04/x86_64 Package network:osmocom:nightly/osmo-stp failed to build in xUbuntu_16.04/x86_64 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 132s] sctp_m2ua.c:91:3: warning: #warning "Notify any other AS(P) for failover scenario" [-Wcpp] [ 132s] #warning "Notify any other AS(P) for failover scenario" [ 132s] ^ [ 132s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -c -o vty_interface.o vty_interface.c [ 132s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -c -o sctp_m3ua_client.o sctp_m3ua_client.c [ 132s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 132s] compilation terminated. [ 132s] Makefile:485: recipe for target 'sctp_m3ua_client.o' failed [ 132s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 132s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 132s] Makefile:380: recipe for target 'all-recursive' failed [ 132s] make[2]: *** [all-recursive] Error 1 [ 132s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 132s] Makefile:321: recipe for target 'all' failed [ 132s] make[1]: *** [all] Error 2 [ 133s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 133s] dh_auto_build: make -j1 returned exit code 2 [ 133s] debian/rules:23: recipe for target 'build' failed [ 133s] make: *** [build] Error 2 [ 133s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 133s] [ 133s] cloud111 failed "build cellmgr-ng_1.4.7.20170411.dsc" at Tue Apr 11 20:06:43 UTC 2017. [ 133s] [ 133s] ### VM INTERACTION START ### [ 136s] [ 110.534099] reboot: Power down [ 137s] ### VM INTERACTION END ### [ 137s] [ 137s] cloud111 failed "build cellmgr-ng_1.4.7.20170411.dsc" at Tue Apr 11 20:06:48 UTC 2017. [ 137s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From gerrit-no-reply at lists.osmocom.org Tue Apr 11 20:15:20 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 11 Apr 2017 20:15:20 +0000 Subject: [PATCH] libosmo-sccp[master]: Fix for SCCP CC without user data In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2292 to look at the new patch set (#2). Fix for SCCP CC without user data When sending messages like CC (or SUA COAK) without user data, we must make sure to not include the optional data part - as opposed to including one with zero length. Change-Id: If91edb526cbcd792ec5ebcb4518cf848feb69391 --- M src/sccp_scoc.c 1 file changed, 4 insertions(+), 4 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/92/2292/2 diff --git a/src/sccp_scoc.c b/src/sccp_scoc.c index 2585c9f..b05e071 100644 --- a/src/sccp_scoc.c +++ b/src/sccp_scoc.c @@ -486,7 +486,7 @@ if (conn->calling_addr.presence) xua_msg_add_sccp_addr(xua, SUA_IEI_SRC_ADDR, &conn->calling_addr); /* optional: hop count; importance; priority; credit */ - if (prim && msgb_l2(prim->oph.msg)) + if (prim && msgb_l2(prim->oph.msg) && msgb_l2len(prim->oph.msg)) xua_msg_add_data(xua, SUA_IEI_DATA, msgb_l2len(prim->oph.msg), msgb_l2(prim->oph.msg)); break; @@ -506,7 +506,7 @@ * parameter */ if (conn->calling_addr.presence) xua_msg_add_sccp_addr(xua, SUA_IEI_DEST_ADDR, &conn->calling_addr); - if (prim && msgb_l2(prim->oph.msg)) + if (prim && msgb_l2(prim->oph.msg) && msgb_l2len(prim->oph.msg)) xua_msg_add_data(xua, SUA_IEI_DATA, msgb_l2len(prim->oph.msg), msgb_l2(prim->oph.msg)); break; @@ -519,7 +519,7 @@ xua_msg_add_u32(xua, SUA_IEI_SRC_REF, conn->conn_id); xua_msg_add_u32(xua, SUA_IEI_CAUSE, SUA_CAUSE_T_RELEASE | prim->u.disconnect.cause); /* optional: importance */ - if (msgb_l2(prim->oph.msg)) + if (prim && msgb_l2(prim->oph.msg) && msgb_l2len(prim->oph.msg)) xua_msg_add_data(xua, SUA_IEI_DATA, msgb_l2len(prim->oph.msg), msgb_l2(prim->oph.msg)); break; @@ -563,7 +563,7 @@ xua_msg_add_sccp_addr(xua, SUA_IEI_DEST_ADDR, &conn->calling_addr); /* optional: importance */ /* optional: data */ - if (prim && msgb_l2(prim->oph.msg)) + if (prim && msgb_l2(prim->oph.msg) && msgb_l2len(prim->oph.msg)) xua_msg_add_data(xua, SUA_IEI_DATA, msgb_l2len(prim->oph.msg), msgb_l2(prim->oph.msg)); break; -- To view, visit https://gerrit.osmocom.org/2292 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: If91edb526cbcd792ec5ebcb4518cf848feb69391 Gerrit-PatchSet: 2 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Apr 11 20:15:21 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 11 Apr 2017 20:15:21 +0000 Subject: [PATCH] libosmo-sccp[master]: SCCP SCOC: Ensure user primitive msgb->l2h always poinst to ... Message-ID: Review at https://gerrit.osmocom.org/2296 SCCP SCOC: Ensure user primitive msgb->l2h always poinst to tail In case there is no user data in a CONNECT.conf primitive (or other CO primitives), we must make sure that msgb->l2h = msgb->tail so that the SCCP User can use msgb_l2len(msg) == 0 as indicator to verify if user data is present or not. Change-Id: Ie512fe063391e3a634097f555b9b0089d2981de9 --- M src/sccp_scoc.c 1 file changed, 1 insertion(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/96/2296/1 diff --git a/src/sccp_scoc.c b/src/sccp_scoc.c index b05e071..4bf340d 100644 --- a/src/sccp_scoc.c +++ b/src/sccp_scoc.c @@ -609,6 +609,7 @@ prim = (struct osmo_scu_prim *) msgb_put(upmsg, sizeof(*prim)); osmo_prim_init(&prim->oph, SCCP_SAP_USER, primitive, operation, upmsg); + upmsg->l2h = upmsg->tail; return prim; } -- To view, visit https://gerrit.osmocom.org/2296 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ie512fe063391e3a634097f555b9b0089d2981de9 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Tue Apr 11 20:15:21 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 11 Apr 2017 20:15:21 +0000 Subject: [PATCH] libosmo-sccp[master]: SCRC: Print NOTICE log message if we attempt to use (missing... Message-ID: Review at https://gerrit.osmocom.org/2297 SCRC: Print NOTICE log message if we attempt to use (missing) GT routing Change-Id: I4dc954cc3f10860dea518f95e53f72c6a9a3de95 --- M src/sccp_scrc.c 1 file changed, 1 insertion(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/97/2297/1 diff --git a/src/sccp_scrc.c b/src/sccp_scrc.c index f9df075..4491ce6 100644 --- a/src/sccp_scrc.c +++ b/src/sccp_scrc.c @@ -267,6 +267,7 @@ if (translated.ri != OSMO_SCCP_RI_SSN_PC && translated.ri != OSMO_SCCP_RI_SSN_IP) { /* TODO: GT Routing */ + LOGP(DLSCCP, LOGL_NOTICE, "GT Routing not implemented yet\n"); /* Node 7 (Sheet 5) */ return scrc_node_7(inst, xua, called); } -- To view, visit https://gerrit.osmocom.org/2297 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I4dc954cc3f10860dea518f95e53f72c6a9a3de95 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Tue Apr 11 20:15:22 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 11 Apr 2017 20:15:22 +0000 Subject: [PATCH] libosmo-sccp[master]: xua: Add value_string for routing key [de]registration results Message-ID: Review at https://gerrit.osmocom.org/2298 xua: Add value_string for routing key [de]registration results Change-Id: If8f0a0ad0837810388cfe65a7b571b6ce4df33e3 --- M src/xua_internal.h M src/xua_rkm.c 2 files changed, 30 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/98/2298/1 diff --git a/src/xua_internal.h b/src/xua_internal.h index 3921309..171756b 100644 --- a/src/xua_internal.h +++ b/src/xua_internal.h @@ -55,3 +55,6 @@ void xua_asp_send_xlm_prim_simple(struct osmo_ss7_asp *asp, enum osmo_xlm_prim_type prim_type, enum osmo_prim_operation op); + +extern const struct value_string m3ua_rkm_reg_status_vals[]; +extern const struct value_string m3ua_rkm_dereg_status_vals[]; diff --git a/src/xua_rkm.c b/src/xua_rkm.c index 12d59c7..ad6c880 100644 --- a/src/xua_rkm.c +++ b/src/xua_rkm.c @@ -27,6 +27,33 @@ #include "xua_internal.h" +const struct value_string m3ua_rkm_reg_status_vals[] = { + { M3UA_RKM_REG_SUCCESS, "SUCCESS" }, + { M3UA_RKM_REG_ERR_UNKNOWN, "Unknown Error" }, + { M3UA_RKM_REG_ERR_INVAL_DPC, "Invalid Destination Pointcode" }, + { M3UA_RKM_REG_ERR_INVAL_NET_APPEAR, "Invalid Network Appearance" }, + { M3UA_RKM_REG_ERR_INVAL_RKEY, "Invalid Routing Key" }, + { M3UA_RKM_REG_ERR_PERM_DENIED, "Permission Denied" }, + { M3UA_RKM_REG_ERR_CANT_SUPP_UNQ_RT, "Cannot Support Unique Routing" }, + { M3UA_RKM_REG_ERR_RKEY_NOT_PROVD, "Routing Key Not Provided" }, + { M3UA_RKM_REG_ERR_INSUFF_RESRC, "Insufficient Resources" }, + { M3UA_RKM_REG_ERR_UNSUPP_RK_PARAM, "Unsupported Routing Key Parameter" }, + { M3UA_RKM_REG_ERR_UNSUPP_TRAF_MODE, "Unsupported Traffic Mode Type" }, + { M3UA_RKM_REG_ERR_RKEY_CHG_REFUSED, "Routing Key Change Refused" }, + { M3UA_RKM_REG_ERR_RKEY_ALRDY_REGD, "Routing Key Already Registered" }, + { 0, NULL } +}; + +const struct value_string m3ua_rkm_dereg_status_vals[] = { + { M3UA_RKM_DEREG_SUCCESS, "SUCCSS" }, + { M3UA_RKM_DEREG_ERR_UNKNOWN, "Unknown Error" }, + { M3UA_RKM_DEREG_ERR_INVAL_RCTX, "Invalid Routing Context" }, + { M3UA_RKM_DEREG_ERR_PERM_DENIED, "Permission Denied" }, + { M3UA_RKM_DEREG_ERR_NOT_REGD, "Error: Not Registered" }, + { M3UA_RKM_DEREG_ERR_ASP_ACTIVE, "Error: ASP Active" }, + { 0, NULL } +}; + /* push a M3UA header to the front of the given message */ static void msgb_push_m3ua_hdr(struct msgb *msg, uint8_t msg_class, uint8_t msg_type) { -- To view, visit https://gerrit.osmocom.org/2298 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: If8f0a0ad0837810388cfe65a7b571b6ce4df33e3 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Tue Apr 11 20:15:22 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 11 Apr 2017 20:15:22 +0000 Subject: [PATCH] libosmo-sccp[master]: osmo_ss7: Instruct libosmo-netif to use {TCP, SCTP}_NODELAY o... Message-ID: Review at https://gerrit.osmocom.org/2299 osmo_ss7: Instruct libosmo-netif to use {TCP,SCTP}_NODELAY on all sockets If we don't do this, we get some nasty packet delays, which are sufficient enough to trigger re-transmissions of an M3UA ASP-UP packet even over loopback/localhost on an otherwise unloaded system. Change-Id: I6aa4eb421ecb483d3da1b0ce3aa6511d161c3750 --- M src/osmo_ss7.c 1 file changed, 2 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/99/2299/1 diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index aa331b9..68315e7 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -1044,6 +1044,7 @@ " client for ASP %s\n", asp->cfg.name); return -1; } + osmo_stream_cli_set_nodelay(asp->client, true); osmo_stream_cli_set_addr(asp->client, asp->cfg.remote.host); osmo_stream_cli_set_port(asp->client, asp->cfg.remote.port); osmo_stream_cli_set_local_addr(asp->client, asp->cfg.local.host); @@ -1486,6 +1487,7 @@ osmo_stream_srv_link_set_data(oxs->server, oxs); osmo_stream_srv_link_set_accept_cb(oxs->server, xua_accept_cb); + osmo_stream_srv_link_set_nodelay(oxs->server, true); osmo_stream_srv_link_set_addr(oxs->server, oxs->cfg.local.host); osmo_stream_srv_link_set_port(oxs->server, oxs->cfg.local.port); osmo_stream_srv_link_set_proto(oxs->server, IPPROTO_SCTP); -- To view, visit https://gerrit.osmocom.org/2299 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I6aa4eb421ecb483d3da1b0ce3aa6511d161c3750 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Tue Apr 11 20:15:22 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 11 Apr 2017 20:15:22 +0000 Subject: [PATCH] libosmo-sccp[master]: osmo_ss7: Use proper string name for dynamically-created ASP Message-ID: Review at https://gerrit.osmocom.org/2300 osmo_ss7: Use proper string name for dynamically-created ASP Change-Id: Id346002c79ba2aba2183ebd46bead372a727316d --- M src/osmo_ss7.c 1 file changed, 1 insertion(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/00/2300/1 diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index 68315e7..9f01863 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -1369,7 +1369,7 @@ char namebuf[32]; static uint32_t dyn_asp_num = 0; snprintf(namebuf, sizeof(namebuf), "asp-dyn-%u", dyn_asp_num++); - asp = osmo_ss7_asp_find_or_create(oxs->inst, NULL, 0, 0, + asp = osmo_ss7_asp_find_or_create(oxs->inst, namebuf, 0, 0, OSMO_SS7_ASP_PROT_M3UA); if (asp) LOGP(DLSS7, LOGL_INFO, "%s: created dynamicASP %s\n", -- To view, visit https://gerrit.osmocom.org/2300 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Id346002c79ba2aba2183ebd46bead372a727316d Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Tue Apr 11 20:15:22 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 11 Apr 2017 20:15:22 +0000 Subject: [PATCH] libosmo-sccp[master]: osmo_ss7: Send M-SCTP_RELEASE.ind for close of xUA client or... Message-ID: Review at https://gerrit.osmocom.org/2301 osmo_ss7: Send M-SCTP_RELEASE.ind for close of xUA client or server socket Change-Id: I31e7de136545279a75a5faca0927d3dbf11ff46d --- M src/osmo_ss7.c 1 file changed, 22 insertions(+), 3 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/01/2301/1 diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index 9f01863..ff53317 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -1253,6 +1253,22 @@ return 0; } +static void xua_cli_close(struct osmo_stream_cli *cli) +{ + struct osmo_ss7_asp *asp = osmo_stream_cli_get_data(cli); + + osmo_stream_cli_close(cli); + + /* send M-SCTP_RELEASE.ind to Layer Manager */ + xua_asp_send_xlm_prim_simple(asp, OSMO_XLM_PRIM_M_SCTP_RELEASE, PRIM_OP_INDICATION); +} + +static void xua_cli_close_and_reconnect(struct osmo_stream_cli *cli) +{ + xua_cli_close(cli); + osmo_stream_cli_reconnect(cli); +} + static int xua_cli_read_cb(struct osmo_stream_cli *conn) { struct osmo_fd *ofd = osmo_stream_cli_get_ofd(conn); @@ -1272,10 +1288,10 @@ LOGPASP(asp, DLSS7, LOGL_DEBUG, "%s(): sctp_recvmsg() returned %d (flags=0x%x)\n", __func__, rc, flags); if (rc < 0) { - osmo_stream_cli_reconnect(conn); + xua_cli_close_and_reconnect(conn); goto out; } else if (rc == 0) { - osmo_stream_cli_reconnect(conn); + xua_cli_close_and_reconnect(conn); } else { msgb_put(msg, rc); } @@ -1288,7 +1304,7 @@ switch (notif->sn_header.sn_type) { case SCTP_SHUTDOWN_EVENT: osmo_fsm_inst_dispatch(asp->fi, XUA_ASP_E_SCTP_COMM_DOWN_IND, asp); - osmo_stream_cli_reconnect(conn); + xua_cli_close_and_reconnect(conn); break; default: break; @@ -1329,6 +1345,9 @@ /* FIXME: somehow notify ASP FSM and everyone else */ + /* send M-SCTP_RELEASE.ind to Layer Manager */ + xua_asp_send_xlm_prim_simple(asp, OSMO_XLM_PRIM_M_SCTP_RELEASE, PRIM_OP_INDICATION); + return 0; } -- To view, visit https://gerrit.osmocom.org/2301 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I31e7de136545279a75a5faca0927d3dbf11ff46d Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Tue Apr 11 20:15:23 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 11 Apr 2017 20:15:23 +0000 Subject: [PATCH] libosmo-sccp[master]: osmo_ss7: Generate M-SCTP_RESTART.ind towards Layer Manager Message-ID: Review at https://gerrit.osmocom.org/2302 osmo_ss7: Generate M-SCTP_RESTART.ind towards Layer Manager The M3UA RFC defines this primitive to the layer manager, but we so far didn't generate it. Let's inform the Layer Manager about such events, in case it wants to take appropriate action. Change-Id: I4e4e86f9b9d8ef4639c835878749ce8d8cc76f7c --- M src/osmo_ss7.c 1 file changed, 9 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/02/2302/1 diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index ff53317..79b0272 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -1203,6 +1203,11 @@ osmo_stream_srv_destroy(conn); osmo_fsm_inst_dispatch(asp->fi, XUA_ASP_E_SCTP_COMM_DOWN_IND, asp); break; + case SCTP_ASSOC_CHANGE: + if (notif->sn_assoc_change.sac_state == SCTP_RESTART) + xua_asp_send_xlm_prim_simple(asp, OSMO_XLM_PRIM_M_SCTP_RESTART, + PRIM_OP_INDICATION); + break; default: break; } @@ -1306,6 +1311,10 @@ osmo_fsm_inst_dispatch(asp->fi, XUA_ASP_E_SCTP_COMM_DOWN_IND, asp); xua_cli_close_and_reconnect(conn); break; + case SCTP_ASSOC_CHANGE: + if (notif->sn_assoc_change.sac_state == SCTP_RESTART) + xua_asp_send_xlm_prim_simple(asp, OSMO_XLM_PRIM_M_SCTP_RESTART, + PRIM_OP_INDICATION); default: break; } -- To view, visit https://gerrit.osmocom.org/2302 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I4e4e86f9b9d8ef4639c835878749ce8d8cc76f7c Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Tue Apr 11 20:15:23 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 11 Apr 2017 20:15:23 +0000 Subject: [PATCH] libosmo-sccp[master]: osmo_ss7: Fix memory leak with sock_name on clients at re-co... Message-ID: Review at https://gerrit.osmocom.org/2303 osmo_ss7: Fix memory leak with sock_name on clients at re-connect time We cannot use osmo_talloc_replace_string() together with osmo_sock_get_name(), as the latter already creates a dynamically allocated string, and the former will then make a copy of that allocation. Change-Id: I6798221ccb3c70186c1c51dd34b7823fefd6df58 --- M src/osmo_ss7.c 1 file changed, 4 insertions(+), 4 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/03/2303/1 diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index 79b0272..cf1948d 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -1242,7 +1242,9 @@ struct osmo_ss7_asp *asp = osmo_stream_cli_get_data(cli); /* update the socket name */ - osmo_talloc_replace_string(asp, &asp->sock_name, osmo_sock_get_name(asp, ofd->fd)); + if (asp->sock_name) + talloc_free(asp->sock_name); + asp->sock_name = osmo_sock_get_name(asp, ofd->fd); LOGPASP(asp, DLSS7, LOGL_INFO, "Client connected %s\n", asp->sock_name); @@ -1537,9 +1539,7 @@ osmo_ss7_xua_server_set_local_host(struct osmo_xua_server *xs, const char *local_host) { OSMO_ASSERT(ss7_initialized); - if (xs->cfg.local.host) - talloc_free(xs->cfg.local.host); - xs->cfg.local.host = talloc_strdup(xs, local_host); + osmo_talloc_replace_string(xs, &xs->cfg.local.host, local_host); osmo_stream_srv_link_set_addr(xs->server, xs->cfg.local.host); -- To view, visit https://gerrit.osmocom.org/2303 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I6798221ccb3c70186c1c51dd34b7823fefd6df58 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Tue Apr 11 20:15:23 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 11 Apr 2017 20:15:23 +0000 Subject: [PATCH] libosmo-sccp[master]: osmo_ss7: When destroying an AS or a linkset, delete all routes Message-ID: Review at https://gerrit.osmocom.org/2304 osmo_ss7: When destroying an AS or a linkset, delete all routes When we destroy a linkset, it make sense to remove all associated routes pointing to the linkset, as they would point to nowhere anyway. Change-Id: I393400bc758c28997e16bc78e3142719b6a61be8 --- M src/osmo_ss7.c 1 file changed, 15 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/04/2304/1 diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index cf1948d..e79d721 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -453,11 +453,18 @@ * \param[in] lset Linkset to be destroyed */ void osmo_ss7_linkset_destroy(struct osmo_ss7_linkset *lset) { + struct osmo_ss7_route *rt, *rt2; unsigned int i; OSMO_ASSERT(ss7_initialized); LOGSS7(lset->inst, LOGL_INFO, "Destroying Linkset %s\n", lset->cfg.name); + + /* find any routes pointing to this AS and remove them */ + llist_for_each_entry_safe(rt, rt2, &lset->inst->rtable_system->routes, list) { + if (rt->dest.linkset == lset) + osmo_ss7_route_destroy(rt); + } for (i = 0; i < ARRAY_SIZE(lset->links); i++) { struct osmo_ss7_link *link = lset->links[i]; @@ -853,12 +860,20 @@ * \param[in] as Application Server to destroy */ void osmo_ss7_as_destroy(struct osmo_ss7_as *as) { + struct osmo_ss7_route *rt, *rt2; + OSMO_ASSERT(ss7_initialized); LOGSS7(as->inst, LOGL_INFO, "Destroying AS %s\n", as->cfg.name); if (as->fi) osmo_fsm_inst_term(as->fi, OSMO_FSM_TERM_REQUEST, NULL); + /* find any routes pointing to this AS and remove them */ + llist_for_each_entry_safe(rt, rt2, &as->inst->rtable_system->routes, list) { + if (rt->dest.as == as) + osmo_ss7_route_destroy(rt); + } + as->inst = NULL; llist_del(&as->list); talloc_free(as); -- To view, visit https://gerrit.osmocom.org/2304 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I393400bc758c28997e16bc78e3142719b6a61be8 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Tue Apr 11 20:15:23 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 11 Apr 2017 20:15:23 +0000 Subject: [PATCH] libosmo-sccp[master]: osmo_ss7: Make sure to start server-side ASP FSM for dynamic... Message-ID: Review at https://gerrit.osmocom.org/2305 osmo_ss7: Make sure to start server-side ASP FSM for dynamically created ASPs Change-Id: I5dd079158a8c6b176a94dc251748924ef3e9c937 --- M src/osmo_ss7.c 1 file changed, 4 insertions(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/05/2305/1 diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index e79d721..b32f5d9 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -1416,9 +1416,12 @@ snprintf(namebuf, sizeof(namebuf), "asp-dyn-%u", dyn_asp_num++); asp = osmo_ss7_asp_find_or_create(oxs->inst, namebuf, 0, 0, OSMO_SS7_ASP_PROT_M3UA); - if (asp) + if (asp) { LOGP(DLSS7, LOGL_INFO, "%s: created dynamicASP %s\n", sock_name, asp->cfg.name); + asp->cfg.is_server = true; + osmo_ss7_asp_restart(asp); + } } if (!asp) { osmo_stream_srv_destroy(srv); -- To view, visit https://gerrit.osmocom.org/2305 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I5dd079158a8c6b176a94dc251748924ef3e9c937 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Tue Apr 11 20:15:24 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 11 Apr 2017 20:15:24 +0000 Subject: [PATCH] libosmo-sccp[master]: osmo_ss7: destroy any ASPs allocated dynamically at accept()... Message-ID: Review at https://gerrit.osmocom.org/2306 osmo_ss7: destroy any ASPs allocated dynamically at accept() time When we accept SCTP connections from clients for whose IP/port we have no matching local configurations, and it is permitted by local configuration, we dynamically allocate osmo_ss7_asp's in this case. Make sure to properly destroy them at the time the SCTP connection is lost. Change-Id: I07d69a0cd52a049a7a4bb0d996e95d39fee9a106 --- M include/osmocom/sigtran/osmo_ss7.h M src/osmo_ss7.c 2 files changed, 13 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/06/2306/1 diff --git a/include/osmocom/sigtran/osmo_ss7.h b/include/osmocom/sigtran/osmo_ss7.h index cbc6a02..bb151d1 100644 --- a/include/osmocom/sigtran/osmo_ss7.h +++ b/include/osmocom/sigtran/osmo_ss7.h @@ -342,6 +342,9 @@ /* Layer Manager to which we talk */ struct osmo_xua_layer_manager *lm; + /*! Were we dynamically allocated */ + bool dyn_allocated; + struct { char *name; char *description; diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index b32f5d9..78ff3ec 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -1374,6 +1374,15 @@ /* send M-SCTP_RELEASE.ind to Layer Manager */ xua_asp_send_xlm_prim_simple(asp, OSMO_XLM_PRIM_M_SCTP_RELEASE, PRIM_OP_INDICATION); + /* if we were dynamically allocated at accept_cb() time, let's + * self-destruct now. A new connection will re-create the ASP. */ + if (asp->dyn_allocated) { + /* avoid re-entrance via osmo_stream_srv_destroy() which + * called us */ + asp->server = NULL; + osmo_ss7_asp_destroy(asp); + } + return 0; } @@ -1420,6 +1429,7 @@ LOGP(DLSS7, LOGL_INFO, "%s: created dynamicASP %s\n", sock_name, asp->cfg.name); asp->cfg.is_server = true; + asp->dyn_allocated = true; osmo_ss7_asp_restart(asp); } } -- To view, visit https://gerrit.osmocom.org/2306 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I07d69a0cd52a049a7a4bb0d996e95d39fee9a106 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Tue Apr 11 20:15:24 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 11 Apr 2017 20:15:24 +0000 Subject: [PATCH] libosmo-sccp[master]: sccp_user: Make sure to create client-side AS with primary PC Message-ID: Review at https://gerrit.osmocom.org/2307 sccp_user: Make sure to create client-side AS with primary PC When we are on the ASP (client) side, we must initialize the routing key of the AS with the proper primary point code of the system. Only this way, the correct point code will be used during dynamic routing key registration via RKM. Change-Id: If586ac9f3449254973a19654dd13dce5793f285f --- M src/sccp_user.c 1 file changed, 2 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/07/2307/1 diff --git a/src/sccp_user.c b/src/sccp_user.c index 57c0038..01a0638 100644 --- a/src/sccp_user.c +++ b/src/sccp_user.c @@ -258,6 +258,8 @@ if (!as) goto out_strings; + as->cfg.routing_key.pc = pc; + /* install default route */ rt = osmo_ss7_route_create(ss7->rtable_system, 0, 0, as_name); if (!rt) -- To view, visit https://gerrit.osmocom.org/2307 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: If586ac9f3449254973a19654dd13dce5793f285f Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Tue Apr 11 20:15:24 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 11 Apr 2017 20:15:24 +0000 Subject: [PATCH] libosmo-sccp[master]: osmo_ss7: Allocate local routing key ID and use it as lookup... Message-ID: Review at https://gerrit.osmocom.org/2308 osmo_ss7: Allocate local routing key ID and use it as lookup key for AS In M3UA RKM we need a "Local Routing Key ID" which uniquely identifies a given routing key locally at the node. Allocate this value and store it in each osmo_ss7_as, as well as add a lookup function for it. Change-Id: I89a0abcf66228ce092126a497cc7971df3a6af71 --- M include/osmocom/sigtran/osmo_ss7.h M include/osmocom/sigtran/sigtran_sap.h M src/osmo_ss7.c 3 files changed, 45 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/08/2308/1 diff --git a/include/osmocom/sigtran/osmo_ss7.h b/include/osmocom/sigtran/osmo_ss7.h index bb151d1..5becc0e 100644 --- a/include/osmocom/sigtran/osmo_ss7.h +++ b/include/osmocom/sigtran/osmo_ss7.h @@ -225,6 +225,7 @@ struct osmo_ss7_routing_key { uint32_t context; + uint32_t l_rk_id; uint32_t pc; uint8_t si; @@ -291,6 +292,8 @@ struct osmo_ss7_as * osmo_ss7_as_find_by_rctx(struct osmo_ss7_instance *inst, uint32_t rctx); struct osmo_ss7_as * +osmo_ss7_as_find_by_l_rk_id(struct osmo_ss7_instance *inst, uint32_t l_rk_id); +struct osmo_ss7_as * osmo_ss7_as_find_or_create(struct osmo_ss7_instance *inst, const char *name, enum osmo_ss7_asp_protocol proto); int osmo_ss7_as_add_asp(struct osmo_ss7_as *as, const char *asp_name); diff --git a/include/osmocom/sigtran/sigtran_sap.h b/include/osmocom/sigtran/sigtran_sap.h index d18aa3d..80cfefc 100644 --- a/include/osmocom/sigtran/sigtran_sap.h +++ b/include/osmocom/sigtran/sigtran_sap.h @@ -1,5 +1,6 @@ #pragma once #include +#include enum osmo_sigtran_sap { @@ -46,6 +47,16 @@ uint32_t code; }; +struct osmo_xlm_prim_rk_reg { + /* routing key */ + struct osmo_ss7_routing_key key; + enum osmo_ss7_as_traffic_mode traf_mode; +}; + +struct osmo_xlm_prim_rk_dereg { + uint32_t route_ctx; +}; + struct osmo_xlm_prim { struct osmo_prim_hdr oph; union { diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index 78ff3ec..f935dd6 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -54,6 +54,7 @@ static LLIST_HEAD(ss7_instances); static LLIST_HEAD(ss7_xua_servers); static int32_t next_rctx = 1; +static int32_t next_l_rk_id = 1; struct value_string osmo_ss7_as_traffic_mode_vals[] = { { OSMO_SS7_AS_TMOD_BCAST, "broadcast" }, @@ -83,6 +84,18 @@ } return -1; } + +static uint32_t find_free_l_rk_id(struct osmo_ss7_instance *inst) +{ + uint32_t l_rk_id; + + for (l_rk_id = next_l_rk_id; next_l_rk_id; l_rk_id = ++next_l_rk_id) { + if (!osmo_ss7_as_find_by_l_rk_id(inst, next_l_rk_id)) + return l_rk_id; + } + return -1; +} + /*********************************************************************** * SS7 Point Code Parsing / Printing @@ -765,6 +778,23 @@ return NULL; } +/*! \brief Find Application Server by given local routing key ID + * \param[in] inst SS7 Instance on which we operate + * \param[in] l_rk_id Local Routing Key ID + * \returns pointer to Application Server on success; NULL otherwise */ +struct osmo_ss7_as * +osmo_ss7_as_find_by_l_rk_id(struct osmo_ss7_instance *inst, uint32_t l_rk_id) +{ + struct osmo_ss7_as *as; + + OSMO_ASSERT(ss7_initialized); + llist_for_each_entry(as, &inst->as_list, list) { + if (as->cfg.routing_key.l_rk_id == l_rk_id) + return as; + } + return NULL; +} + /*! \brief Find or Create Application Server * \param[in] inst SS7 Instance on which we operate * \param[in] name Name of Application Server @@ -792,6 +822,7 @@ as->cfg.proto = proto; as->cfg.mode = OSMO_SS7_AS_TMOD_LOADSHARE; as->cfg.recovery_timeout_msec = 2000; + as->cfg.routing_key.l_rk_id = find_free_l_rk_id(inst); as->fi = xua_as_fsm_start(as, LOGL_DEBUG); llist_add_tail(&as->list, &inst->as_list); } -- To view, visit https://gerrit.osmocom.org/2308 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I89a0abcf66228ce092126a497cc7971df3a6af71 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Tue Apr 11 20:46:17 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 11 Apr 2017 20:46:17 +0000 Subject: libosmo-netif[master]: Add osmo_stream_{cli, srv_link}_set_nodelay() function In-Reply-To: References: Message-ID: Patch Set 4: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2295 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ibeb9ba227bab18f7f4f16518c0022c4f003cc8e9 Gerrit-PatchSet: 4 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Apr 11 20:46:19 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 11 Apr 2017 20:46:19 +0000 Subject: [MERGED] libosmo-netif[master]: Add osmo_stream_{cli, srv_link}_set_nodelay() function In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: Add osmo_stream_{cli,srv_link}_set_nodelay() function ...................................................................... Add osmo_stream_{cli,srv_link}_set_nodelay() function Using this function, the user can configure if sockets related to the respective stream client or server should have the NODELAY socket option set in order to avoid Nagle algorithm or related algorithms that may introduce packet delay on the transmitter side. Change-Id: Ibeb9ba227bab18f7f4f16518c0022c4f003cc8e9 --- M include/osmocom/netif/stream.h M src/stream.c 2 files changed, 62 insertions(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/include/osmocom/netif/stream.h b/include/osmocom/netif/stream.h index 63eccf8..7afb7af 100644 --- a/include/osmocom/netif/stream.h +++ b/include/osmocom/netif/stream.h @@ -16,6 +16,7 @@ struct osmo_stream_srv_link *osmo_stream_srv_link_create(void *ctx); void osmo_stream_srv_link_destroy(struct osmo_stream_srv_link *link); +void osmo_stream_srv_link_set_nodelay(struct osmo_stream_srv_link *link, bool nodelay); void osmo_stream_srv_link_set_addr(struct osmo_stream_srv_link *link, const char *addr); void osmo_stream_srv_link_set_port(struct osmo_stream_srv_link *link, uint16_t port); void osmo_stream_srv_link_set_proto(struct osmo_stream_srv_link *link, uint16_t proto); @@ -45,6 +46,7 @@ /*! \brief Osmocom Stream Client: Single client connection */ struct osmo_stream_cli; +void osmo_stream_cli_set_nodelay(struct osmo_stream_cli *cli, bool nodelay); void osmo_stream_cli_set_addr(struct osmo_stream_cli *cli, const char *addr); void osmo_stream_cli_set_port(struct osmo_stream_cli *cli, uint16_t port); void osmo_stream_cli_set_proto(struct osmo_stream_cli *cli, uint16_t proto); diff --git a/src/stream.c b/src/stream.c index f5ead17..3bc36a3 100644 --- a/src/stream.c +++ b/src/stream.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -63,6 +64,27 @@ #endif } +static int setsockopt_nodelay(int fd, int proto, int on) +{ + int rc; + + switch (proto) { + case IPPROTO_SCTP: + rc = setsockopt(fd, IPPROTO_SCTP, SCTP_NODELAY, &on, sizeof(on)); + break; + case IPPROTO_TCP: + rc = setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on)); + break; + default: + rc = -1; + LOGP(DLINP, LOGL_ERROR, "Unknown protocol %u, cannot set NODELAY\n", + proto); + break; + } + return rc; +} + + /* * Client side. */ @@ -75,6 +97,7 @@ }; #define OSMO_STREAM_CLI_F_RECONF (1 << 0) +#define OSMO_STREAM_CLI_F_NODELAY (1 << 1) struct osmo_stream_cli { struct osmo_fd ofd; @@ -400,6 +423,9 @@ return ret; } + if (cli->flags & OSMO_STREAM_CLI_F_NODELAY) + setsockopt_nodelay(cli->ofd.fd, cli->proto, 1); + cli->ofd.fd = ret; if (osmo_fd_register(&cli->ofd) < 0) { close(ret); @@ -409,6 +435,21 @@ return 0; } +/*! \brief Set the NODELAY socket option to avoid Nagle-like behavior + * Setting this to nodelay=true will automatically set the NODELAY + * socket option on any socket established via \ref osmo_stream_cli_open + * or any re-connect. You have to set this _before_ opening the + * socket. + * \param[in] cli Stream client whose sockets are to be configured + * \param[in] nodelay whether to set (true) NODELAY before connect() + */ +void osmo_stream_cli_set_nodelay(struct osmo_stream_cli *cli, bool nodelay) +{ + if (nodelay) + cli->flags |= OSMO_STREAM_CLI_F_NODELAY; + else + cli->flags &= ~OSMO_STREAM_CLI_F_NODELAY; +} /*! \brief Open connection of an Osmocom stream client * \param[in] cli Stream Client to connect */ @@ -473,6 +514,7 @@ */ #define OSMO_STREAM_SRV_F_RECONF (1 << 0) +#define OSMO_STREAM_SRV_F_NODELAY (1 << 1) struct osmo_stream_srv_link { struct osmo_fd ofd; @@ -503,6 +545,9 @@ if (link->proto == IPPROTO_SCTP) sctp_sock_activate_events(ret); + if (link->flags & OSMO_STREAM_SRV_F_NODELAY) + setsockopt_nodelay(ret, link->proto, 1); + if (link->accept_cb) link->accept_cb(link, ret); @@ -532,6 +577,21 @@ return link; } +/*! \brief Set the NODELAY socket option to avoid Nagle-like behavior + * Setting this to nodelay=true will automatically set the NODELAY + * socket option on any socket established via this server link, before + * calling the accept_cb() + * \param[in] link server link whose sockets are to be configured + * \param[in] nodelay whether to set (true) NODELAY after accept + */ +void osmo_stream_srv_link_set_nodelay(struct osmo_stream_srv_link *link, bool nodelay) +{ + if (nodelay) + link->flags |= OSMO_STREAM_SRV_F_NODELAY; + else + link->flags &= ~OSMO_STREAM_SRV_F_NODELAY; +} + /*! \brief Set the local address to which we bind * \param[in] link Stream Server Link to modify * \param[in] addr Local IP address -- To view, visit https://gerrit.osmocom.org/2295 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ibeb9ba227bab18f7f4f16518c0022c4f003cc8e9 Gerrit-PatchSet: 4 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Apr 11 20:46:39 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 11 Apr 2017 20:46:39 +0000 Subject: libosmo-sccp[master]: Fix for SCCP CC without user data In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2292 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: If91edb526cbcd792ec5ebcb4518cf848feb69391 Gerrit-PatchSet: 2 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Apr 11 20:46:43 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 11 Apr 2017 20:46:43 +0000 Subject: libosmo-sccp[master]: SCCP SCOC: Ensure user primitive msgb->l2h always poinst to ... In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2296 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ie512fe063391e3a634097f555b9b0089d2981de9 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Apr 11 20:46:46 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 11 Apr 2017 20:46:46 +0000 Subject: libosmo-sccp[master]: SCRC: Print NOTICE log message if we attempt to use (missing... In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2297 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I4dc954cc3f10860dea518f95e53f72c6a9a3de95 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Apr 11 20:46:51 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 11 Apr 2017 20:46:51 +0000 Subject: libosmo-sccp[master]: xua: Add value_string for routing key [de]registration results In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2298 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: If8f0a0ad0837810388cfe65a7b571b6ce4df33e3 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Apr 11 20:47:07 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 11 Apr 2017 20:47:07 +0000 Subject: [MERGED] libosmo-sccp[master]: xua: Add value_string for routing key [de]registration results In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: xua: Add value_string for routing key [de]registration results ...................................................................... xua: Add value_string for routing key [de]registration results Change-Id: If8f0a0ad0837810388cfe65a7b571b6ce4df33e3 --- M src/xua_internal.h M src/xua_rkm.c 2 files changed, 30 insertions(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/xua_internal.h b/src/xua_internal.h index 3921309..171756b 100644 --- a/src/xua_internal.h +++ b/src/xua_internal.h @@ -55,3 +55,6 @@ void xua_asp_send_xlm_prim_simple(struct osmo_ss7_asp *asp, enum osmo_xlm_prim_type prim_type, enum osmo_prim_operation op); + +extern const struct value_string m3ua_rkm_reg_status_vals[]; +extern const struct value_string m3ua_rkm_dereg_status_vals[]; diff --git a/src/xua_rkm.c b/src/xua_rkm.c index 12d59c7..ad6c880 100644 --- a/src/xua_rkm.c +++ b/src/xua_rkm.c @@ -27,6 +27,33 @@ #include "xua_internal.h" +const struct value_string m3ua_rkm_reg_status_vals[] = { + { M3UA_RKM_REG_SUCCESS, "SUCCESS" }, + { M3UA_RKM_REG_ERR_UNKNOWN, "Unknown Error" }, + { M3UA_RKM_REG_ERR_INVAL_DPC, "Invalid Destination Pointcode" }, + { M3UA_RKM_REG_ERR_INVAL_NET_APPEAR, "Invalid Network Appearance" }, + { M3UA_RKM_REG_ERR_INVAL_RKEY, "Invalid Routing Key" }, + { M3UA_RKM_REG_ERR_PERM_DENIED, "Permission Denied" }, + { M3UA_RKM_REG_ERR_CANT_SUPP_UNQ_RT, "Cannot Support Unique Routing" }, + { M3UA_RKM_REG_ERR_RKEY_NOT_PROVD, "Routing Key Not Provided" }, + { M3UA_RKM_REG_ERR_INSUFF_RESRC, "Insufficient Resources" }, + { M3UA_RKM_REG_ERR_UNSUPP_RK_PARAM, "Unsupported Routing Key Parameter" }, + { M3UA_RKM_REG_ERR_UNSUPP_TRAF_MODE, "Unsupported Traffic Mode Type" }, + { M3UA_RKM_REG_ERR_RKEY_CHG_REFUSED, "Routing Key Change Refused" }, + { M3UA_RKM_REG_ERR_RKEY_ALRDY_REGD, "Routing Key Already Registered" }, + { 0, NULL } +}; + +const struct value_string m3ua_rkm_dereg_status_vals[] = { + { M3UA_RKM_DEREG_SUCCESS, "SUCCSS" }, + { M3UA_RKM_DEREG_ERR_UNKNOWN, "Unknown Error" }, + { M3UA_RKM_DEREG_ERR_INVAL_RCTX, "Invalid Routing Context" }, + { M3UA_RKM_DEREG_ERR_PERM_DENIED, "Permission Denied" }, + { M3UA_RKM_DEREG_ERR_NOT_REGD, "Error: Not Registered" }, + { M3UA_RKM_DEREG_ERR_ASP_ACTIVE, "Error: ASP Active" }, + { 0, NULL } +}; + /* push a M3UA header to the front of the given message */ static void msgb_push_m3ua_hdr(struct msgb *msg, uint8_t msg_class, uint8_t msg_type) { -- To view, visit https://gerrit.osmocom.org/2298 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: If8f0a0ad0837810388cfe65a7b571b6ce4df33e3 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Apr 11 20:47:07 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 11 Apr 2017 20:47:07 +0000 Subject: [MERGED] libosmo-sccp[master]: SCRC: Print NOTICE log message if we attempt to use (missing... In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: SCRC: Print NOTICE log message if we attempt to use (missing) GT routing ...................................................................... SCRC: Print NOTICE log message if we attempt to use (missing) GT routing Change-Id: I4dc954cc3f10860dea518f95e53f72c6a9a3de95 --- M src/sccp_scrc.c 1 file changed, 1 insertion(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/sccp_scrc.c b/src/sccp_scrc.c index f9df075..4491ce6 100644 --- a/src/sccp_scrc.c +++ b/src/sccp_scrc.c @@ -267,6 +267,7 @@ if (translated.ri != OSMO_SCCP_RI_SSN_PC && translated.ri != OSMO_SCCP_RI_SSN_IP) { /* TODO: GT Routing */ + LOGP(DLSCCP, LOGL_NOTICE, "GT Routing not implemented yet\n"); /* Node 7 (Sheet 5) */ return scrc_node_7(inst, xua, called); } -- To view, visit https://gerrit.osmocom.org/2297 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I4dc954cc3f10860dea518f95e53f72c6a9a3de95 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Apr 11 20:47:07 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 11 Apr 2017 20:47:07 +0000 Subject: [MERGED] libosmo-sccp[master]: SCCP SCOC: Ensure user primitive msgb->l2h always poinst to ... In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: SCCP SCOC: Ensure user primitive msgb->l2h always poinst to tail ...................................................................... SCCP SCOC: Ensure user primitive msgb->l2h always poinst to tail In case there is no user data in a CONNECT.conf primitive (or other CO primitives), we must make sure that msgb->l2h = msgb->tail so that the SCCP User can use msgb_l2len(msg) == 0 as indicator to verify if user data is present or not. Change-Id: Ie512fe063391e3a634097f555b9b0089d2981de9 --- M src/sccp_scoc.c 1 file changed, 1 insertion(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/sccp_scoc.c b/src/sccp_scoc.c index b05e071..4bf340d 100644 --- a/src/sccp_scoc.c +++ b/src/sccp_scoc.c @@ -609,6 +609,7 @@ prim = (struct osmo_scu_prim *) msgb_put(upmsg, sizeof(*prim)); osmo_prim_init(&prim->oph, SCCP_SAP_USER, primitive, operation, upmsg); + upmsg->l2h = upmsg->tail; return prim; } -- To view, visit https://gerrit.osmocom.org/2296 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ie512fe063391e3a634097f555b9b0089d2981de9 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Apr 11 20:47:08 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 11 Apr 2017 20:47:08 +0000 Subject: [MERGED] libosmo-sccp[master]: Fix for SCCP CC without user data In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: Fix for SCCP CC without user data ...................................................................... Fix for SCCP CC without user data When sending messages like CC (or SUA COAK) without user data, we must make sure to not include the optional data part - as opposed to including one with zero length. Change-Id: If91edb526cbcd792ec5ebcb4518cf848feb69391 --- M src/sccp_scoc.c 1 file changed, 4 insertions(+), 4 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/sccp_scoc.c b/src/sccp_scoc.c index 2585c9f..b05e071 100644 --- a/src/sccp_scoc.c +++ b/src/sccp_scoc.c @@ -486,7 +486,7 @@ if (conn->calling_addr.presence) xua_msg_add_sccp_addr(xua, SUA_IEI_SRC_ADDR, &conn->calling_addr); /* optional: hop count; importance; priority; credit */ - if (prim && msgb_l2(prim->oph.msg)) + if (prim && msgb_l2(prim->oph.msg) && msgb_l2len(prim->oph.msg)) xua_msg_add_data(xua, SUA_IEI_DATA, msgb_l2len(prim->oph.msg), msgb_l2(prim->oph.msg)); break; @@ -506,7 +506,7 @@ * parameter */ if (conn->calling_addr.presence) xua_msg_add_sccp_addr(xua, SUA_IEI_DEST_ADDR, &conn->calling_addr); - if (prim && msgb_l2(prim->oph.msg)) + if (prim && msgb_l2(prim->oph.msg) && msgb_l2len(prim->oph.msg)) xua_msg_add_data(xua, SUA_IEI_DATA, msgb_l2len(prim->oph.msg), msgb_l2(prim->oph.msg)); break; @@ -519,7 +519,7 @@ xua_msg_add_u32(xua, SUA_IEI_SRC_REF, conn->conn_id); xua_msg_add_u32(xua, SUA_IEI_CAUSE, SUA_CAUSE_T_RELEASE | prim->u.disconnect.cause); /* optional: importance */ - if (msgb_l2(prim->oph.msg)) + if (prim && msgb_l2(prim->oph.msg) && msgb_l2len(prim->oph.msg)) xua_msg_add_data(xua, SUA_IEI_DATA, msgb_l2len(prim->oph.msg), msgb_l2(prim->oph.msg)); break; @@ -563,7 +563,7 @@ xua_msg_add_sccp_addr(xua, SUA_IEI_DEST_ADDR, &conn->calling_addr); /* optional: importance */ /* optional: data */ - if (prim && msgb_l2(prim->oph.msg)) + if (prim && msgb_l2(prim->oph.msg) && msgb_l2len(prim->oph.msg)) xua_msg_add_data(xua, SUA_IEI_DATA, msgb_l2len(prim->oph.msg), msgb_l2(prim->oph.msg)); break; -- To view, visit https://gerrit.osmocom.org/2292 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: If91edb526cbcd792ec5ebcb4518cf848feb69391 Gerrit-PatchSet: 2 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Apr 11 20:48:39 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 11 Apr 2017 20:48:39 +0000 Subject: [PATCH] libosmo-sccp[master]: osmo_ss7: When destroying an AS or a linkset, delete all routes In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2304 to look at the new patch set (#2). osmo_ss7: When destroying an AS or a linkset, delete all routes When we destroy a linkset, it make sense to remove all associated routes pointing to the linkset, as they would point to nowhere anyway. Change-Id: I393400bc758c28997e16bc78e3142719b6a61be8 --- M src/osmo_ss7.c 1 file changed, 15 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/04/2304/2 diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index cf1948d..e79d721 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -453,11 +453,18 @@ * \param[in] lset Linkset to be destroyed */ void osmo_ss7_linkset_destroy(struct osmo_ss7_linkset *lset) { + struct osmo_ss7_route *rt, *rt2; unsigned int i; OSMO_ASSERT(ss7_initialized); LOGSS7(lset->inst, LOGL_INFO, "Destroying Linkset %s\n", lset->cfg.name); + + /* find any routes pointing to this AS and remove them */ + llist_for_each_entry_safe(rt, rt2, &lset->inst->rtable_system->routes, list) { + if (rt->dest.linkset == lset) + osmo_ss7_route_destroy(rt); + } for (i = 0; i < ARRAY_SIZE(lset->links); i++) { struct osmo_ss7_link *link = lset->links[i]; @@ -853,12 +860,20 @@ * \param[in] as Application Server to destroy */ void osmo_ss7_as_destroy(struct osmo_ss7_as *as) { + struct osmo_ss7_route *rt, *rt2; + OSMO_ASSERT(ss7_initialized); LOGSS7(as->inst, LOGL_INFO, "Destroying AS %s\n", as->cfg.name); if (as->fi) osmo_fsm_inst_term(as->fi, OSMO_FSM_TERM_REQUEST, NULL); + /* find any routes pointing to this AS and remove them */ + llist_for_each_entry_safe(rt, rt2, &as->inst->rtable_system->routes, list) { + if (rt->dest.as == as) + osmo_ss7_route_destroy(rt); + } + as->inst = NULL; llist_del(&as->list); talloc_free(as); -- To view, visit https://gerrit.osmocom.org/2304 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I393400bc758c28997e16bc78e3142719b6a61be8 Gerrit-PatchSet: 2 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Apr 11 20:48:39 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 11 Apr 2017 20:48:39 +0000 Subject: [PATCH] libosmo-sccp[master]: osmo_ss7: Make sure to start server-side ASP FSM for dynamic... In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2305 to look at the new patch set (#2). osmo_ss7: Make sure to start server-side ASP FSM for dynamically created ASPs Change-Id: I5dd079158a8c6b176a94dc251748924ef3e9c937 --- M src/osmo_ss7.c 1 file changed, 4 insertions(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/05/2305/2 diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index e79d721..b32f5d9 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -1416,9 +1416,12 @@ snprintf(namebuf, sizeof(namebuf), "asp-dyn-%u", dyn_asp_num++); asp = osmo_ss7_asp_find_or_create(oxs->inst, namebuf, 0, 0, OSMO_SS7_ASP_PROT_M3UA); - if (asp) + if (asp) { LOGP(DLSS7, LOGL_INFO, "%s: created dynamicASP %s\n", sock_name, asp->cfg.name); + asp->cfg.is_server = true; + osmo_ss7_asp_restart(asp); + } } if (!asp) { osmo_stream_srv_destroy(srv); -- To view, visit https://gerrit.osmocom.org/2305 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I5dd079158a8c6b176a94dc251748924ef3e9c937 Gerrit-PatchSet: 2 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Apr 11 20:48:39 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 11 Apr 2017 20:48:39 +0000 Subject: [PATCH] libosmo-sccp[master]: osmo_ss7: destroy any ASPs allocated dynamically at accept()... In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2306 to look at the new patch set (#2). osmo_ss7: destroy any ASPs allocated dynamically at accept() time When we accept SCTP connections from clients for whose IP/port we have no matching local configurations, and it is permitted by local configuration, we dynamically allocate osmo_ss7_asp's in this case. Make sure to properly destroy them at the time the SCTP connection is lost. Change-Id: I07d69a0cd52a049a7a4bb0d996e95d39fee9a106 --- M include/osmocom/sigtran/osmo_ss7.h M src/osmo_ss7.c 2 files changed, 13 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/06/2306/2 diff --git a/include/osmocom/sigtran/osmo_ss7.h b/include/osmocom/sigtran/osmo_ss7.h index cbc6a02..bb151d1 100644 --- a/include/osmocom/sigtran/osmo_ss7.h +++ b/include/osmocom/sigtran/osmo_ss7.h @@ -342,6 +342,9 @@ /* Layer Manager to which we talk */ struct osmo_xua_layer_manager *lm; + /*! Were we dynamically allocated */ + bool dyn_allocated; + struct { char *name; char *description; diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index b32f5d9..78ff3ec 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -1374,6 +1374,15 @@ /* send M-SCTP_RELEASE.ind to Layer Manager */ xua_asp_send_xlm_prim_simple(asp, OSMO_XLM_PRIM_M_SCTP_RELEASE, PRIM_OP_INDICATION); + /* if we were dynamically allocated at accept_cb() time, let's + * self-destruct now. A new connection will re-create the ASP. */ + if (asp->dyn_allocated) { + /* avoid re-entrance via osmo_stream_srv_destroy() which + * called us */ + asp->server = NULL; + osmo_ss7_asp_destroy(asp); + } + return 0; } @@ -1420,6 +1429,7 @@ LOGP(DLSS7, LOGL_INFO, "%s: created dynamicASP %s\n", sock_name, asp->cfg.name); asp->cfg.is_server = true; + asp->dyn_allocated = true; osmo_ss7_asp_restart(asp); } } -- To view, visit https://gerrit.osmocom.org/2306 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I07d69a0cd52a049a7a4bb0d996e95d39fee9a106 Gerrit-PatchSet: 2 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Apr 11 20:48:39 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 11 Apr 2017 20:48:39 +0000 Subject: [PATCH] libosmo-sccp[master]: sccp_user: Make sure to create client-side AS with primary PC In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2307 to look at the new patch set (#2). sccp_user: Make sure to create client-side AS with primary PC When we are on the ASP (client) side, we must initialize the routing key of the AS with the proper primary point code of the system. Only this way, the correct point code will be used during dynamic routing key registration via RKM. Change-Id: If586ac9f3449254973a19654dd13dce5793f285f --- M src/sccp_user.c 1 file changed, 2 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/07/2307/2 diff --git a/src/sccp_user.c b/src/sccp_user.c index 57c0038..01a0638 100644 --- a/src/sccp_user.c +++ b/src/sccp_user.c @@ -258,6 +258,8 @@ if (!as) goto out_strings; + as->cfg.routing_key.pc = pc; + /* install default route */ rt = osmo_ss7_route_create(ss7->rtable_system, 0, 0, as_name); if (!rt) -- To view, visit https://gerrit.osmocom.org/2307 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: If586ac9f3449254973a19654dd13dce5793f285f Gerrit-PatchSet: 2 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Apr 11 20:48:39 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 11 Apr 2017 20:48:39 +0000 Subject: [PATCH] libosmo-sccp[master]: osmo_ss7: Allocate local routing key ID and use it as lookup... In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2308 to look at the new patch set (#2). osmo_ss7: Allocate local routing key ID and use it as lookup key for AS In M3UA RKM we need a "Local Routing Key ID" which uniquely identifies a given routing key locally at the node. Allocate this value and store it in each osmo_ss7_as, as well as add a lookup function for it. Change-Id: I89a0abcf66228ce092126a497cc7971df3a6af71 --- M include/osmocom/sigtran/osmo_ss7.h M include/osmocom/sigtran/sigtran_sap.h M src/osmo_ss7.c 3 files changed, 45 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/08/2308/2 diff --git a/include/osmocom/sigtran/osmo_ss7.h b/include/osmocom/sigtran/osmo_ss7.h index bb151d1..5becc0e 100644 --- a/include/osmocom/sigtran/osmo_ss7.h +++ b/include/osmocom/sigtran/osmo_ss7.h @@ -225,6 +225,7 @@ struct osmo_ss7_routing_key { uint32_t context; + uint32_t l_rk_id; uint32_t pc; uint8_t si; @@ -291,6 +292,8 @@ struct osmo_ss7_as * osmo_ss7_as_find_by_rctx(struct osmo_ss7_instance *inst, uint32_t rctx); struct osmo_ss7_as * +osmo_ss7_as_find_by_l_rk_id(struct osmo_ss7_instance *inst, uint32_t l_rk_id); +struct osmo_ss7_as * osmo_ss7_as_find_or_create(struct osmo_ss7_instance *inst, const char *name, enum osmo_ss7_asp_protocol proto); int osmo_ss7_as_add_asp(struct osmo_ss7_as *as, const char *asp_name); diff --git a/include/osmocom/sigtran/sigtran_sap.h b/include/osmocom/sigtran/sigtran_sap.h index d18aa3d..80cfefc 100644 --- a/include/osmocom/sigtran/sigtran_sap.h +++ b/include/osmocom/sigtran/sigtran_sap.h @@ -1,5 +1,6 @@ #pragma once #include +#include enum osmo_sigtran_sap { @@ -46,6 +47,16 @@ uint32_t code; }; +struct osmo_xlm_prim_rk_reg { + /* routing key */ + struct osmo_ss7_routing_key key; + enum osmo_ss7_as_traffic_mode traf_mode; +}; + +struct osmo_xlm_prim_rk_dereg { + uint32_t route_ctx; +}; + struct osmo_xlm_prim { struct osmo_prim_hdr oph; union { diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index 78ff3ec..f935dd6 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -54,6 +54,7 @@ static LLIST_HEAD(ss7_instances); static LLIST_HEAD(ss7_xua_servers); static int32_t next_rctx = 1; +static int32_t next_l_rk_id = 1; struct value_string osmo_ss7_as_traffic_mode_vals[] = { { OSMO_SS7_AS_TMOD_BCAST, "broadcast" }, @@ -83,6 +84,18 @@ } return -1; } + +static uint32_t find_free_l_rk_id(struct osmo_ss7_instance *inst) +{ + uint32_t l_rk_id; + + for (l_rk_id = next_l_rk_id; next_l_rk_id; l_rk_id = ++next_l_rk_id) { + if (!osmo_ss7_as_find_by_l_rk_id(inst, next_l_rk_id)) + return l_rk_id; + } + return -1; +} + /*********************************************************************** * SS7 Point Code Parsing / Printing @@ -765,6 +778,23 @@ return NULL; } +/*! \brief Find Application Server by given local routing key ID + * \param[in] inst SS7 Instance on which we operate + * \param[in] l_rk_id Local Routing Key ID + * \returns pointer to Application Server on success; NULL otherwise */ +struct osmo_ss7_as * +osmo_ss7_as_find_by_l_rk_id(struct osmo_ss7_instance *inst, uint32_t l_rk_id) +{ + struct osmo_ss7_as *as; + + OSMO_ASSERT(ss7_initialized); + llist_for_each_entry(as, &inst->as_list, list) { + if (as->cfg.routing_key.l_rk_id == l_rk_id) + return as; + } + return NULL; +} + /*! \brief Find or Create Application Server * \param[in] inst SS7 Instance on which we operate * \param[in] name Name of Application Server @@ -792,6 +822,7 @@ as->cfg.proto = proto; as->cfg.mode = OSMO_SS7_AS_TMOD_LOADSHARE; as->cfg.recovery_timeout_msec = 2000; + as->cfg.routing_key.l_rk_id = find_free_l_rk_id(inst); as->fi = xua_as_fsm_start(as, LOGL_DEBUG); llist_add_tail(&as->list, &inst->as_list); } -- To view, visit https://gerrit.osmocom.org/2308 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I89a0abcf66228ce092126a497cc7971df3a6af71 Gerrit-PatchSet: 2 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Apr 11 20:48:39 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 11 Apr 2017 20:48:39 +0000 Subject: [PATCH] libosmo-sccp[master]: osmo_ss7: Send M-SCTP_RELEASE.ind for close of xUA client or... In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2301 to look at the new patch set (#2). osmo_ss7: Send M-SCTP_RELEASE.ind for close of xUA client or server socket Change-Id: I31e7de136545279a75a5faca0927d3dbf11ff46d --- M src/osmo_ss7.c 1 file changed, 22 insertions(+), 3 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/01/2301/2 diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index 9f01863..ff53317 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -1253,6 +1253,22 @@ return 0; } +static void xua_cli_close(struct osmo_stream_cli *cli) +{ + struct osmo_ss7_asp *asp = osmo_stream_cli_get_data(cli); + + osmo_stream_cli_close(cli); + + /* send M-SCTP_RELEASE.ind to Layer Manager */ + xua_asp_send_xlm_prim_simple(asp, OSMO_XLM_PRIM_M_SCTP_RELEASE, PRIM_OP_INDICATION); +} + +static void xua_cli_close_and_reconnect(struct osmo_stream_cli *cli) +{ + xua_cli_close(cli); + osmo_stream_cli_reconnect(cli); +} + static int xua_cli_read_cb(struct osmo_stream_cli *conn) { struct osmo_fd *ofd = osmo_stream_cli_get_ofd(conn); @@ -1272,10 +1288,10 @@ LOGPASP(asp, DLSS7, LOGL_DEBUG, "%s(): sctp_recvmsg() returned %d (flags=0x%x)\n", __func__, rc, flags); if (rc < 0) { - osmo_stream_cli_reconnect(conn); + xua_cli_close_and_reconnect(conn); goto out; } else if (rc == 0) { - osmo_stream_cli_reconnect(conn); + xua_cli_close_and_reconnect(conn); } else { msgb_put(msg, rc); } @@ -1288,7 +1304,7 @@ switch (notif->sn_header.sn_type) { case SCTP_SHUTDOWN_EVENT: osmo_fsm_inst_dispatch(asp->fi, XUA_ASP_E_SCTP_COMM_DOWN_IND, asp); - osmo_stream_cli_reconnect(conn); + xua_cli_close_and_reconnect(conn); break; default: break; @@ -1329,6 +1345,9 @@ /* FIXME: somehow notify ASP FSM and everyone else */ + /* send M-SCTP_RELEASE.ind to Layer Manager */ + xua_asp_send_xlm_prim_simple(asp, OSMO_XLM_PRIM_M_SCTP_RELEASE, PRIM_OP_INDICATION); + return 0; } -- To view, visit https://gerrit.osmocom.org/2301 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I31e7de136545279a75a5faca0927d3dbf11ff46d Gerrit-PatchSet: 2 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Apr 11 20:48:39 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 11 Apr 2017 20:48:39 +0000 Subject: [PATCH] libosmo-sccp[master]: osmo_ss7: Generate M-SCTP_RESTART.ind towards Layer Manager In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2302 to look at the new patch set (#2). osmo_ss7: Generate M-SCTP_RESTART.ind towards Layer Manager The M3UA RFC defines this primitive to the layer manager, but we so far didn't generate it. Let's inform the Layer Manager about such events, in case it wants to take appropriate action. Change-Id: I4e4e86f9b9d8ef4639c835878749ce8d8cc76f7c --- M src/osmo_ss7.c 1 file changed, 9 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/02/2302/2 diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index ff53317..79b0272 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -1203,6 +1203,11 @@ osmo_stream_srv_destroy(conn); osmo_fsm_inst_dispatch(asp->fi, XUA_ASP_E_SCTP_COMM_DOWN_IND, asp); break; + case SCTP_ASSOC_CHANGE: + if (notif->sn_assoc_change.sac_state == SCTP_RESTART) + xua_asp_send_xlm_prim_simple(asp, OSMO_XLM_PRIM_M_SCTP_RESTART, + PRIM_OP_INDICATION); + break; default: break; } @@ -1306,6 +1311,10 @@ osmo_fsm_inst_dispatch(asp->fi, XUA_ASP_E_SCTP_COMM_DOWN_IND, asp); xua_cli_close_and_reconnect(conn); break; + case SCTP_ASSOC_CHANGE: + if (notif->sn_assoc_change.sac_state == SCTP_RESTART) + xua_asp_send_xlm_prim_simple(asp, OSMO_XLM_PRIM_M_SCTP_RESTART, + PRIM_OP_INDICATION); default: break; } -- To view, visit https://gerrit.osmocom.org/2302 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I4e4e86f9b9d8ef4639c835878749ce8d8cc76f7c Gerrit-PatchSet: 2 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Apr 11 20:48:39 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 11 Apr 2017 20:48:39 +0000 Subject: [PATCH] libosmo-sccp[master]: osmo_ss7: Fix memory leak with sock_name on clients at re-co... In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2303 to look at the new patch set (#2). osmo_ss7: Fix memory leak with sock_name on clients at re-connect time We cannot use osmo_talloc_replace_string() together with osmo_sock_get_name(), as the latter already creates a dynamically allocated string, and the former will then make a copy of that allocation. Change-Id: I6798221ccb3c70186c1c51dd34b7823fefd6df58 --- M src/osmo_ss7.c 1 file changed, 4 insertions(+), 4 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/03/2303/2 diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index 79b0272..cf1948d 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -1242,7 +1242,9 @@ struct osmo_ss7_asp *asp = osmo_stream_cli_get_data(cli); /* update the socket name */ - osmo_talloc_replace_string(asp, &asp->sock_name, osmo_sock_get_name(asp, ofd->fd)); + if (asp->sock_name) + talloc_free(asp->sock_name); + asp->sock_name = osmo_sock_get_name(asp, ofd->fd); LOGPASP(asp, DLSS7, LOGL_INFO, "Client connected %s\n", asp->sock_name); @@ -1537,9 +1539,7 @@ osmo_ss7_xua_server_set_local_host(struct osmo_xua_server *xs, const char *local_host) { OSMO_ASSERT(ss7_initialized); - if (xs->cfg.local.host) - talloc_free(xs->cfg.local.host); - xs->cfg.local.host = talloc_strdup(xs, local_host); + osmo_talloc_replace_string(xs, &xs->cfg.local.host, local_host); osmo_stream_srv_link_set_addr(xs->server, xs->cfg.local.host); -- To view, visit https://gerrit.osmocom.org/2303 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I6798221ccb3c70186c1c51dd34b7823fefd6df58 Gerrit-PatchSet: 2 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Apr 11 20:49:21 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 11 Apr 2017 20:49:21 +0000 Subject: libosmo-sccp[master]: osmo_ss7: Use proper string name for dynamically-created ASP In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2300 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Id346002c79ba2aba2183ebd46bead372a727316d Gerrit-PatchSet: 2 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Apr 11 20:49:28 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 11 Apr 2017 20:49:28 +0000 Subject: libosmo-sccp[master]: osmo_ss7: Instruct libosmo-netif to use {TCP, SCTP}_NODELAY o... In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2299 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I6aa4eb421ecb483d3da1b0ce3aa6511d161c3750 Gerrit-PatchSet: 2 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Apr 11 20:49:46 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 11 Apr 2017 20:49:46 +0000 Subject: libosmo-sccp[master]: osmo_ss7: Send M-SCTP_RELEASE.ind for close of xUA client or... In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2301 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I31e7de136545279a75a5faca0927d3dbf11ff46d Gerrit-PatchSet: 2 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Apr 11 20:49:52 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 11 Apr 2017 20:49:52 +0000 Subject: libosmo-sccp[master]: osmo_ss7: Generate M-SCTP_RESTART.ind towards Layer Manager In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2302 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I4e4e86f9b9d8ef4639c835878749ce8d8cc76f7c Gerrit-PatchSet: 2 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Apr 11 20:49:58 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 11 Apr 2017 20:49:58 +0000 Subject: libosmo-sccp[master]: osmo_ss7: Fix memory leak with sock_name on clients at re-co... In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2303 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I6798221ccb3c70186c1c51dd34b7823fefd6df58 Gerrit-PatchSet: 2 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Apr 11 20:50:17 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 11 Apr 2017 20:50:17 +0000 Subject: libosmo-sccp[master]: osmo_ss7: When destroying an AS or a linkset, delete all routes In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2304 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I393400bc758c28997e16bc78e3142719b6a61be8 Gerrit-PatchSet: 2 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Apr 11 20:50:32 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 11 Apr 2017 20:50:32 +0000 Subject: libosmo-sccp[master]: osmo_ss7: Make sure to start server-side ASP FSM for dynamic... In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2305 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I5dd079158a8c6b176a94dc251748924ef3e9c937 Gerrit-PatchSet: 2 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Apr 11 20:50:46 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 11 Apr 2017 20:50:46 +0000 Subject: libosmo-sccp[master]: osmo_ss7: destroy any ASPs allocated dynamically at accept()... In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2306 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I07d69a0cd52a049a7a4bb0d996e95d39fee9a106 Gerrit-PatchSet: 2 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Apr 11 20:51:00 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 11 Apr 2017 20:51:00 +0000 Subject: libosmo-sccp[master]: sccp_user: Make sure to create client-side AS with primary PC In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2307 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: If586ac9f3449254973a19654dd13dce5793f285f Gerrit-PatchSet: 2 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Apr 11 20:51:19 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 11 Apr 2017 20:51:19 +0000 Subject: libosmo-sccp[master]: osmo_ss7: Allocate local routing key ID and use it as lookup... In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2308 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I89a0abcf66228ce092126a497cc7971df3a6af71 Gerrit-PatchSet: 2 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Apr 11 21:27:11 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 11 Apr 2017 21:27:11 +0000 Subject: [PATCH] libosmo-sccp[master]: osmo_ss7: Send M-SCTP_RELEASE.ind for close of xUA client or... In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2301 to look at the new patch set (#3). osmo_ss7: Send M-SCTP_RELEASE.ind for close of xUA client or server socket Change-Id: I31e7de136545279a75a5faca0927d3dbf11ff46d --- M src/osmo_ss7.c 1 file changed, 22 insertions(+), 3 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/01/2301/3 diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index aa331b9..b916094 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -1252,6 +1252,22 @@ return 0; } +static void xua_cli_close(struct osmo_stream_cli *cli) +{ + struct osmo_ss7_asp *asp = osmo_stream_cli_get_data(cli); + + osmo_stream_cli_close(cli); + + /* send M-SCTP_RELEASE.ind to XUA Layer Manager */ + xua_asp_send_xlm_prim_simple(asp, OSMO_XLM_PRIM_M_SCTP_RELEASE, PRIM_OP_INDICATION); +} + +static void xua_cli_close_and_reconnect(struct osmo_stream_cli *cli) +{ + xua_cli_close(cli); + osmo_stream_cli_reconnect(cli); +} + static int xua_cli_read_cb(struct osmo_stream_cli *conn) { struct osmo_fd *ofd = osmo_stream_cli_get_ofd(conn); @@ -1271,10 +1287,10 @@ LOGPASP(asp, DLSS7, LOGL_DEBUG, "%s(): sctp_recvmsg() returned %d (flags=0x%x)\n", __func__, rc, flags); if (rc < 0) { - osmo_stream_cli_reconnect(conn); + xua_cli_close_and_reconnect(conn); goto out; } else if (rc == 0) { - osmo_stream_cli_reconnect(conn); + xua_cli_close_and_reconnect(conn); } else { msgb_put(msg, rc); } @@ -1287,7 +1303,7 @@ switch (notif->sn_header.sn_type) { case SCTP_SHUTDOWN_EVENT: osmo_fsm_inst_dispatch(asp->fi, XUA_ASP_E_SCTP_COMM_DOWN_IND, asp); - osmo_stream_cli_reconnect(conn); + xua_cli_close_and_reconnect(conn); break; default: break; @@ -1328,6 +1344,9 @@ /* FIXME: somehow notify ASP FSM and everyone else */ + /* send M-SCTP_RELEASE.ind to Layer Manager */ + xua_asp_send_xlm_prim_simple(asp, OSMO_XLM_PRIM_M_SCTP_RELEASE, PRIM_OP_INDICATION); + return 0; } -- To view, visit https://gerrit.osmocom.org/2301 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I31e7de136545279a75a5faca0927d3dbf11ff46d Gerrit-PatchSet: 3 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Apr 11 21:27:25 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 11 Apr 2017 21:27:25 +0000 Subject: libosmo-sccp[master]: osmo_ss7: Send M-SCTP_RELEASE.ind for close of xUA client or... In-Reply-To: References: Message-ID: Patch Set 3: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2301 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I31e7de136545279a75a5faca0927d3dbf11ff46d Gerrit-PatchSet: 3 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Apr 11 22:27:01 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 11 Apr 2017 22:27:01 +0000 Subject: [MERGED] libosmo-sccp[master]: osmo_ss7: Fix memory leak with sock_name on clients at re-co... In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: osmo_ss7: Fix memory leak with sock_name on clients at re-connect time ...................................................................... osmo_ss7: Fix memory leak with sock_name on clients at re-connect time We cannot use osmo_talloc_replace_string() together with osmo_sock_get_name(), as the latter already creates a dynamically allocated string, and the former will then make a copy of that allocation. Change-Id: I6798221ccb3c70186c1c51dd34b7823fefd6df58 --- M src/osmo_ss7.c 1 file changed, 4 insertions(+), 4 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index 1bcc5c8..24e9fd3 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -1242,7 +1242,9 @@ struct osmo_ss7_asp *asp = osmo_stream_cli_get_data(cli); /* update the socket name */ - osmo_talloc_replace_string(asp, &asp->sock_name, osmo_sock_get_name(asp, ofd->fd)); + if (asp->sock_name) + talloc_free(asp->sock_name); + asp->sock_name = osmo_sock_get_name(asp, ofd->fd); LOGPASP(asp, DLSS7, LOGL_INFO, "Client connected %s\n", asp->sock_name); @@ -1537,9 +1539,7 @@ osmo_ss7_xua_server_set_local_host(struct osmo_xua_server *xs, const char *local_host) { OSMO_ASSERT(ss7_initialized); - if (xs->cfg.local.host) - talloc_free(xs->cfg.local.host); - xs->cfg.local.host = talloc_strdup(xs, local_host); + osmo_talloc_replace_string(xs, &xs->cfg.local.host, local_host); osmo_stream_srv_link_set_addr(xs->server, xs->cfg.local.host); -- To view, visit https://gerrit.osmocom.org/2303 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I6798221ccb3c70186c1c51dd34b7823fefd6df58 Gerrit-PatchSet: 3 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Apr 11 22:27:01 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 11 Apr 2017 22:27:01 +0000 Subject: [MERGED] libosmo-sccp[master]: osmo_ss7: Generate M-SCTP_RESTART.ind towards Layer Manager In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: osmo_ss7: Generate M-SCTP_RESTART.ind towards Layer Manager ...................................................................... osmo_ss7: Generate M-SCTP_RESTART.ind towards Layer Manager The M3UA RFC defines this primitive to the layer manager, but we so far didn't generate it. Let's inform the Layer Manager about such events, in case it wants to take appropriate action. Change-Id: I4e4e86f9b9d8ef4639c835878749ce8d8cc76f7c --- M src/osmo_ss7.c 1 file changed, 9 insertions(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index 7da9ba3..1bcc5c8 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -1203,6 +1203,11 @@ osmo_stream_srv_destroy(conn); osmo_fsm_inst_dispatch(asp->fi, XUA_ASP_E_SCTP_COMM_DOWN_IND, asp); break; + case SCTP_ASSOC_CHANGE: + if (notif->sn_assoc_change.sac_state == SCTP_RESTART) + xua_asp_send_xlm_prim_simple(asp, OSMO_XLM_PRIM_M_SCTP_RESTART, + PRIM_OP_INDICATION); + break; default: break; } @@ -1306,6 +1311,10 @@ osmo_fsm_inst_dispatch(asp->fi, XUA_ASP_E_SCTP_COMM_DOWN_IND, asp); xua_cli_close_and_reconnect(conn); break; + case SCTP_ASSOC_CHANGE: + if (notif->sn_assoc_change.sac_state == SCTP_RESTART) + xua_asp_send_xlm_prim_simple(asp, OSMO_XLM_PRIM_M_SCTP_RESTART, + PRIM_OP_INDICATION); default: break; } -- To view, visit https://gerrit.osmocom.org/2302 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I4e4e86f9b9d8ef4639c835878749ce8d8cc76f7c Gerrit-PatchSet: 3 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Apr 11 22:27:02 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 11 Apr 2017 22:27:02 +0000 Subject: [MERGED] libosmo-sccp[master]: osmo_ss7: Send M-SCTP_RELEASE.ind for close of xUA client or... In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: osmo_ss7: Send M-SCTP_RELEASE.ind for close of xUA client or server socket ...................................................................... osmo_ss7: Send M-SCTP_RELEASE.ind for close of xUA client or server socket Change-Id: I31e7de136545279a75a5faca0927d3dbf11ff46d --- M src/osmo_ss7.c 1 file changed, 22 insertions(+), 3 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index aa331b9..b916094 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -1252,6 +1252,22 @@ return 0; } +static void xua_cli_close(struct osmo_stream_cli *cli) +{ + struct osmo_ss7_asp *asp = osmo_stream_cli_get_data(cli); + + osmo_stream_cli_close(cli); + + /* send M-SCTP_RELEASE.ind to XUA Layer Manager */ + xua_asp_send_xlm_prim_simple(asp, OSMO_XLM_PRIM_M_SCTP_RELEASE, PRIM_OP_INDICATION); +} + +static void xua_cli_close_and_reconnect(struct osmo_stream_cli *cli) +{ + xua_cli_close(cli); + osmo_stream_cli_reconnect(cli); +} + static int xua_cli_read_cb(struct osmo_stream_cli *conn) { struct osmo_fd *ofd = osmo_stream_cli_get_ofd(conn); @@ -1271,10 +1287,10 @@ LOGPASP(asp, DLSS7, LOGL_DEBUG, "%s(): sctp_recvmsg() returned %d (flags=0x%x)\n", __func__, rc, flags); if (rc < 0) { - osmo_stream_cli_reconnect(conn); + xua_cli_close_and_reconnect(conn); goto out; } else if (rc == 0) { - osmo_stream_cli_reconnect(conn); + xua_cli_close_and_reconnect(conn); } else { msgb_put(msg, rc); } @@ -1287,7 +1303,7 @@ switch (notif->sn_header.sn_type) { case SCTP_SHUTDOWN_EVENT: osmo_fsm_inst_dispatch(asp->fi, XUA_ASP_E_SCTP_COMM_DOWN_IND, asp); - osmo_stream_cli_reconnect(conn); + xua_cli_close_and_reconnect(conn); break; default: break; @@ -1328,6 +1344,9 @@ /* FIXME: somehow notify ASP FSM and everyone else */ + /* send M-SCTP_RELEASE.ind to Layer Manager */ + xua_asp_send_xlm_prim_simple(asp, OSMO_XLM_PRIM_M_SCTP_RELEASE, PRIM_OP_INDICATION); + return 0; } -- To view, visit https://gerrit.osmocom.org/2301 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I31e7de136545279a75a5faca0927d3dbf11ff46d Gerrit-PatchSet: 3 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Apr 11 22:27:02 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 11 Apr 2017 22:27:02 +0000 Subject: [MERGED] libosmo-sccp[master]: osmo_ss7: Use proper string name for dynamically-created ASP In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: osmo_ss7: Use proper string name for dynamically-created ASP ...................................................................... osmo_ss7: Use proper string name for dynamically-created ASP Change-Id: Id346002c79ba2aba2183ebd46bead372a727316d --- M src/osmo_ss7.c 1 file changed, 1 insertion(+), 1 deletion(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index b916094..2c17e15 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -1387,7 +1387,7 @@ char namebuf[32]; static uint32_t dyn_asp_num = 0; snprintf(namebuf, sizeof(namebuf), "asp-dyn-%u", dyn_asp_num++); - asp = osmo_ss7_asp_find_or_create(oxs->inst, NULL, 0, 0, + asp = osmo_ss7_asp_find_or_create(oxs->inst, namebuf, 0, 0, OSMO_SS7_ASP_PROT_M3UA); if (asp) LOGP(DLSS7, LOGL_INFO, "%s: created dynamicASP %s\n", -- To view, visit https://gerrit.osmocom.org/2300 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Id346002c79ba2aba2183ebd46bead372a727316d Gerrit-PatchSet: 3 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Apr 11 22:27:02 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 11 Apr 2017 22:27:02 +0000 Subject: [MERGED] libosmo-sccp[master]: osmo_ss7: Instruct libosmo-netif to use {TCP, SCTP}_NODELAY o... In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: osmo_ss7: Instruct libosmo-netif to use {TCP,SCTP}_NODELAY on all sockets ...................................................................... osmo_ss7: Instruct libosmo-netif to use {TCP,SCTP}_NODELAY on all sockets If we don't do this, we get some nasty packet delays, which are sufficient enough to trigger re-transmissions of an M3UA ASP-UP packet even over loopback/localhost on an otherwise unloaded system. Change-Id: I6aa4eb421ecb483d3da1b0ce3aa6511d161c3750 --- M src/osmo_ss7.c 1 file changed, 2 insertions(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index 2c17e15..7da9ba3 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -1044,6 +1044,7 @@ " client for ASP %s\n", asp->cfg.name); return -1; } + osmo_stream_cli_set_nodelay(asp->client, true); osmo_stream_cli_set_addr(asp->client, asp->cfg.remote.host); osmo_stream_cli_set_port(asp->client, asp->cfg.remote.port); osmo_stream_cli_set_local_addr(asp->client, asp->cfg.local.host); @@ -1505,6 +1506,7 @@ osmo_stream_srv_link_set_data(oxs->server, oxs); osmo_stream_srv_link_set_accept_cb(oxs->server, xua_accept_cb); + osmo_stream_srv_link_set_nodelay(oxs->server, true); osmo_stream_srv_link_set_addr(oxs->server, oxs->cfg.local.host); osmo_stream_srv_link_set_port(oxs->server, oxs->cfg.local.port); osmo_stream_srv_link_set_proto(oxs->server, IPPROTO_SCTP); -- To view, visit https://gerrit.osmocom.org/2299 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I6aa4eb421ecb483d3da1b0ce3aa6511d161c3750 Gerrit-PatchSet: 3 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Apr 11 22:27:03 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 11 Apr 2017 22:27:03 +0000 Subject: [MERGED] libosmo-sccp[master]: osmo_ss7: Allocate local routing key ID and use it as lookup... In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: osmo_ss7: Allocate local routing key ID and use it as lookup key for AS ...................................................................... osmo_ss7: Allocate local routing key ID and use it as lookup key for AS In M3UA RKM we need a "Local Routing Key ID" which uniquely identifies a given routing key locally at the node. Allocate this value and store it in each osmo_ss7_as, as well as add a lookup function for it. Change-Id: I89a0abcf66228ce092126a497cc7971df3a6af71 --- M include/osmocom/sigtran/osmo_ss7.h M include/osmocom/sigtran/sigtran_sap.h M src/osmo_ss7.c 3 files changed, 45 insertions(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/include/osmocom/sigtran/osmo_ss7.h b/include/osmocom/sigtran/osmo_ss7.h index bb151d1..5becc0e 100644 --- a/include/osmocom/sigtran/osmo_ss7.h +++ b/include/osmocom/sigtran/osmo_ss7.h @@ -225,6 +225,7 @@ struct osmo_ss7_routing_key { uint32_t context; + uint32_t l_rk_id; uint32_t pc; uint8_t si; @@ -291,6 +292,8 @@ struct osmo_ss7_as * osmo_ss7_as_find_by_rctx(struct osmo_ss7_instance *inst, uint32_t rctx); struct osmo_ss7_as * +osmo_ss7_as_find_by_l_rk_id(struct osmo_ss7_instance *inst, uint32_t l_rk_id); +struct osmo_ss7_as * osmo_ss7_as_find_or_create(struct osmo_ss7_instance *inst, const char *name, enum osmo_ss7_asp_protocol proto); int osmo_ss7_as_add_asp(struct osmo_ss7_as *as, const char *asp_name); diff --git a/include/osmocom/sigtran/sigtran_sap.h b/include/osmocom/sigtran/sigtran_sap.h index d18aa3d..80cfefc 100644 --- a/include/osmocom/sigtran/sigtran_sap.h +++ b/include/osmocom/sigtran/sigtran_sap.h @@ -1,5 +1,6 @@ #pragma once #include +#include enum osmo_sigtran_sap { @@ -46,6 +47,16 @@ uint32_t code; }; +struct osmo_xlm_prim_rk_reg { + /* routing key */ + struct osmo_ss7_routing_key key; + enum osmo_ss7_as_traffic_mode traf_mode; +}; + +struct osmo_xlm_prim_rk_dereg { + uint32_t route_ctx; +}; + struct osmo_xlm_prim { struct osmo_prim_hdr oph; union { diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index 3c7deaf..4f12152 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -54,6 +54,7 @@ static LLIST_HEAD(ss7_instances); static LLIST_HEAD(ss7_xua_servers); static int32_t next_rctx = 1; +static int32_t next_l_rk_id = 1; struct value_string osmo_ss7_as_traffic_mode_vals[] = { { OSMO_SS7_AS_TMOD_BCAST, "broadcast" }, @@ -83,6 +84,18 @@ } return -1; } + +static uint32_t find_free_l_rk_id(struct osmo_ss7_instance *inst) +{ + uint32_t l_rk_id; + + for (l_rk_id = next_l_rk_id; next_l_rk_id; l_rk_id = ++next_l_rk_id) { + if (!osmo_ss7_as_find_by_l_rk_id(inst, next_l_rk_id)) + return l_rk_id; + } + return -1; +} + /*********************************************************************** * SS7 Point Code Parsing / Printing @@ -765,6 +778,23 @@ return NULL; } +/*! \brief Find Application Server by given local routing key ID + * \param[in] inst SS7 Instance on which we operate + * \param[in] l_rk_id Local Routing Key ID + * \returns pointer to Application Server on success; NULL otherwise */ +struct osmo_ss7_as * +osmo_ss7_as_find_by_l_rk_id(struct osmo_ss7_instance *inst, uint32_t l_rk_id) +{ + struct osmo_ss7_as *as; + + OSMO_ASSERT(ss7_initialized); + llist_for_each_entry(as, &inst->as_list, list) { + if (as->cfg.routing_key.l_rk_id == l_rk_id) + return as; + } + return NULL; +} + /*! \brief Find or Create Application Server * \param[in] inst SS7 Instance on which we operate * \param[in] name Name of Application Server @@ -792,6 +822,7 @@ as->cfg.proto = proto; as->cfg.mode = OSMO_SS7_AS_TMOD_LOADSHARE; as->cfg.recovery_timeout_msec = 2000; + as->cfg.routing_key.l_rk_id = find_free_l_rk_id(inst); as->fi = xua_as_fsm_start(as, LOGL_DEBUG); llist_add_tail(&as->list, &inst->as_list); } -- To view, visit https://gerrit.osmocom.org/2308 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I89a0abcf66228ce092126a497cc7971df3a6af71 Gerrit-PatchSet: 3 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Apr 11 22:27:03 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 11 Apr 2017 22:27:03 +0000 Subject: [MERGED] libosmo-sccp[master]: sccp_user: Make sure to create client-side AS with primary PC In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: sccp_user: Make sure to create client-side AS with primary PC ...................................................................... sccp_user: Make sure to create client-side AS with primary PC When we are on the ASP (client) side, we must initialize the routing key of the AS with the proper primary point code of the system. Only this way, the correct point code will be used during dynamic routing key registration via RKM. Change-Id: If586ac9f3449254973a19654dd13dce5793f285f --- M src/sccp_user.c 1 file changed, 2 insertions(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/sccp_user.c b/src/sccp_user.c index 57c0038..01a0638 100644 --- a/src/sccp_user.c +++ b/src/sccp_user.c @@ -258,6 +258,8 @@ if (!as) goto out_strings; + as->cfg.routing_key.pc = pc; + /* install default route */ rt = osmo_ss7_route_create(ss7->rtable_system, 0, 0, as_name); if (!rt) -- To view, visit https://gerrit.osmocom.org/2307 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: If586ac9f3449254973a19654dd13dce5793f285f Gerrit-PatchSet: 3 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Apr 11 22:27:03 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 11 Apr 2017 22:27:03 +0000 Subject: [MERGED] libosmo-sccp[master]: osmo_ss7: destroy any ASPs allocated dynamically at accept()... In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: osmo_ss7: destroy any ASPs allocated dynamically at accept() time ...................................................................... osmo_ss7: destroy any ASPs allocated dynamically at accept() time When we accept SCTP connections from clients for whose IP/port we have no matching local configurations, and it is permitted by local configuration, we dynamically allocate osmo_ss7_asp's in this case. Make sure to properly destroy them at the time the SCTP connection is lost. Change-Id: I07d69a0cd52a049a7a4bb0d996e95d39fee9a106 --- M include/osmocom/sigtran/osmo_ss7.h M src/osmo_ss7.c 2 files changed, 13 insertions(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/include/osmocom/sigtran/osmo_ss7.h b/include/osmocom/sigtran/osmo_ss7.h index cbc6a02..bb151d1 100644 --- a/include/osmocom/sigtran/osmo_ss7.h +++ b/include/osmocom/sigtran/osmo_ss7.h @@ -342,6 +342,9 @@ /* Layer Manager to which we talk */ struct osmo_xua_layer_manager *lm; + /*! Were we dynamically allocated */ + bool dyn_allocated; + struct { char *name; char *description; diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index 63ac72e..3c7deaf 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -1374,6 +1374,15 @@ /* send M-SCTP_RELEASE.ind to Layer Manager */ xua_asp_send_xlm_prim_simple(asp, OSMO_XLM_PRIM_M_SCTP_RELEASE, PRIM_OP_INDICATION); + /* if we were dynamically allocated at accept_cb() time, let's + * self-destruct now. A new connection will re-create the ASP. */ + if (asp->dyn_allocated) { + /* avoid re-entrance via osmo_stream_srv_destroy() which + * called us */ + asp->server = NULL; + osmo_ss7_asp_destroy(asp); + } + return 0; } @@ -1420,6 +1429,7 @@ LOGP(DLSS7, LOGL_INFO, "%s: created dynamicASP %s\n", sock_name, asp->cfg.name); asp->cfg.is_server = true; + asp->dyn_allocated = true; osmo_ss7_asp_restart(asp); } } -- To view, visit https://gerrit.osmocom.org/2306 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I07d69a0cd52a049a7a4bb0d996e95d39fee9a106 Gerrit-PatchSet: 3 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Apr 11 22:27:03 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 11 Apr 2017 22:27:03 +0000 Subject: [MERGED] libosmo-sccp[master]: osmo_ss7: Make sure to start server-side ASP FSM for dynamic... In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: osmo_ss7: Make sure to start server-side ASP FSM for dynamically created ASPs ...................................................................... osmo_ss7: Make sure to start server-side ASP FSM for dynamically created ASPs Change-Id: I5dd079158a8c6b176a94dc251748924ef3e9c937 --- M src/osmo_ss7.c 1 file changed, 4 insertions(+), 1 deletion(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index 12289ec..63ac72e 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -1416,9 +1416,12 @@ snprintf(namebuf, sizeof(namebuf), "asp-dyn-%u", dyn_asp_num++); asp = osmo_ss7_asp_find_or_create(oxs->inst, namebuf, 0, 0, OSMO_SS7_ASP_PROT_M3UA); - if (asp) + if (asp) { LOGP(DLSS7, LOGL_INFO, "%s: created dynamicASP %s\n", sock_name, asp->cfg.name); + asp->cfg.is_server = true; + osmo_ss7_asp_restart(asp); + } } if (!asp) { osmo_stream_srv_destroy(srv); -- To view, visit https://gerrit.osmocom.org/2305 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I5dd079158a8c6b176a94dc251748924ef3e9c937 Gerrit-PatchSet: 3 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Apr 11 22:27:04 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 11 Apr 2017 22:27:04 +0000 Subject: [MERGED] libosmo-sccp[master]: osmo_ss7: When destroying an AS or a linkset, delete all routes In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: osmo_ss7: When destroying an AS or a linkset, delete all routes ...................................................................... osmo_ss7: When destroying an AS or a linkset, delete all routes When we destroy a linkset, it make sense to remove all associated routes pointing to the linkset, as they would point to nowhere anyway. Change-Id: I393400bc758c28997e16bc78e3142719b6a61be8 --- M src/osmo_ss7.c 1 file changed, 15 insertions(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index 24e9fd3..12289ec 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -453,11 +453,18 @@ * \param[in] lset Linkset to be destroyed */ void osmo_ss7_linkset_destroy(struct osmo_ss7_linkset *lset) { + struct osmo_ss7_route *rt, *rt2; unsigned int i; OSMO_ASSERT(ss7_initialized); LOGSS7(lset->inst, LOGL_INFO, "Destroying Linkset %s\n", lset->cfg.name); + + /* find any routes pointing to this AS and remove them */ + llist_for_each_entry_safe(rt, rt2, &lset->inst->rtable_system->routes, list) { + if (rt->dest.linkset == lset) + osmo_ss7_route_destroy(rt); + } for (i = 0; i < ARRAY_SIZE(lset->links); i++) { struct osmo_ss7_link *link = lset->links[i]; @@ -853,12 +860,20 @@ * \param[in] as Application Server to destroy */ void osmo_ss7_as_destroy(struct osmo_ss7_as *as) { + struct osmo_ss7_route *rt, *rt2; + OSMO_ASSERT(ss7_initialized); LOGSS7(as->inst, LOGL_INFO, "Destroying AS %s\n", as->cfg.name); if (as->fi) osmo_fsm_inst_term(as->fi, OSMO_FSM_TERM_REQUEST, NULL); + /* find any routes pointing to this AS and remove them */ + llist_for_each_entry_safe(rt, rt2, &as->inst->rtable_system->routes, list) { + if (rt->dest.as == as) + osmo_ss7_route_destroy(rt); + } + as->inst = NULL; llist_del(&as->list); talloc_free(as); -- To view, visit https://gerrit.osmocom.org/2304 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I393400bc758c28997e16bc78e3142719b6a61be8 Gerrit-PatchSet: 3 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Wed Apr 12 03:42:10 2017 From: gerrit-no-reply at lists.osmocom.org (Holger Freyther) Date: Wed, 12 Apr 2017 03:42:10 +0000 Subject: libosmo-sccp[master]: Add osmo-stp executable as new "Osmocom Signaling Transfer P... In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+1 (3 comments) https://gerrit.osmocom.org/#/c/2281/2//COMMIT_MSG Commit Message: Line 21: * SCCP: no Global Title Translatio (GTT) yet If you rebase, add the 'n' to Translation https://gerrit.osmocom.org/#/c/2281/2/stp/osmo_ss7_vty.c File stp/osmo_ss7_vty.c: Line 226: vty_out(vty, "cannot create route%s", VTY_NEWLINE); Maybe print the dpc and mask here? IIRC the VTY code will not print the failing rule itself? https://gerrit.osmocom.org/#/c/2281/2/stp/stp_main.c File stp/stp_main.c: Line 53: /* Hack to enable debug logging for all relevant (used?) subsystems */ hehe, it is not that bad ;) -- To view, visit https://gerrit.osmocom.org/2281 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: If32227b8d3127c6178e4ee45527ce65f69bc7b1e Gerrit-PatchSet: 2 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Wed Apr 12 03:44:49 2017 From: gerrit-no-reply at lists.osmocom.org (Holger Freyther) Date: Wed, 12 Apr 2017 03:44:49 +0000 Subject: openbsc[master]: nat: Use equal func in bsc_sccp In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 Let's fix the hnbgw issue and merge after the build is fixed. -- To view, visit https://gerrit.osmocom.org/2285 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I9fac7cabedff74f8f6293ad8b54420229b80aa71 Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Pau Espin Pedrol Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Wed Apr 12 03:46:26 2017 From: gerrit-no-reply at lists.osmocom.org (Holger Freyther) Date: Wed, 12 Apr 2017 03:46:26 +0000 Subject: osmo-bts[master]: Signal to BSC when PCU disconnects In-Reply-To: References: Message-ID: Patch Set 2: (1 comment) https://gerrit.osmocom.org/#/c/2288/2/src/common/pcu_sock.c File src/common/pcu_sock.c: Line 673: osmo_signal_dispatch(SS_FAIL, OSMO_EVT_PCU_VERS, ""); Why "" as signal_data? What happens if NULL is sent? -- To view, visit https://gerrit.osmocom.org/2288 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I41a731bd719aee0bbb98d3236405fb3a7f3ddec0 Gerrit-PatchSet: 2 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Wed Apr 12 03:48:14 2017 From: gerrit-no-reply at lists.osmocom.org (Holger Freyther) Date: Wed, 12 Apr 2017 03:48:14 +0000 Subject: openbsc[master]: build: iu: use libosmo-sccp tag 'old_sua' In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+1 But max has a point on branch vs. tag. Feel free to fix. Can you re-submit some of the failing builds as well? -- To view, visit https://gerrit.osmocom.org/2293 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Id74a802fd2ca65f4b6c2079550fbb6b0af3e8340 Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Wed Apr 12 03:50:57 2017 From: gerrit-no-reply at lists.osmocom.org (Holger Freyther) Date: Wed, 12 Apr 2017 03:50:57 +0000 Subject: openbsc[master]: nat: Fix initial buffer size parameter for getline In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 How did you see this? Code review? Compiler warning? The BSD manpage is not that clear here. As linep is NULL a new buffer will be allocated which leads to updating these values. But there is no point to insist on 2342 as initial value. -- To view, visit https://gerrit.osmocom.org/2287 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I36683884106b97ef697264716de13813c00da9bc Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Pau Espin Pedrol Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Wed Apr 12 08:52:43 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Wed, 12 Apr 2017 08:52:43 +0000 Subject: osmo-bts[master]: Signal to BSC when PCU disconnects In-Reply-To: References: Message-ID: Patch Set 2: > What happens if NULL is sent? In this case it's interpreted as PCU version "(null)" because that's how NULL pointer is serialized. I can fix it but not sure if it's worth it - with empty string "" it works just fine. -- To view, visit https://gerrit.osmocom.org/2288 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I41a731bd719aee0bbb98d3236405fb3a7f3ddec0 Gerrit-PatchSet: 2 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Wed Apr 12 10:05:57 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Wed, 12 Apr 2017 10:05:57 +0000 Subject: [PATCH] openbsc[master]: Make BTS type and variant converters shareable In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2286 to look at the new patch set (#5). Make BTS type and variant converters shareable * move value_string definition and corresponding functions for BTS type to shared header to make it re-usable by OsmoBTS * use consistent function naming * add similar functions for BTS variant * add enum to be used by OML Attribute Reporting to distinguish between type, variant and other info Change-Id: Ida94725a6fce968443541e3526f48f13758031fd Related: OS#1614 --- M openbsc/include/openbsc/gsm_data_shared.h M openbsc/src/libbsc/bsc_vty.c M openbsc/src/libcommon/gsm_data.c M openbsc/src/libcommon/gsm_data_shared.c 4 files changed, 70 insertions(+), 21 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/86/2286/5 diff --git a/openbsc/include/openbsc/gsm_data_shared.h b/openbsc/include/openbsc/gsm_data_shared.h index 242889a..e016dd9 100644 --- a/openbsc/include/openbsc/gsm_data_shared.h +++ b/openbsc/include/openbsc/gsm_data_shared.h @@ -504,6 +504,12 @@ _NUM_BTS_VARIANT }; +/* Used by OML layer for BTS Attribute reporting */ +enum bts_attribute { + BTS_TYPE_VARIANT, + BTS_SUB_MODEL, +}; + struct vty; struct gsm_bts_model { @@ -859,6 +865,14 @@ struct gsm_bts_trx *gsm_bts_trx_alloc(struct gsm_bts *bts); struct gsm_bts_trx *gsm_bts_trx_num(const struct gsm_bts *bts, int num); +enum gsm_bts_type str2btstype(const char *arg); +const char *btstype2str(enum gsm_bts_type type); + +enum bts_attribute str2btsattr(const char *s); +const char *btsatttr2str(enum bts_attribute v); + +enum gsm_bts_type_variant str2btsvariant(const char *arg); +const char *btsvariant2str(enum gsm_bts_type_variant v); const struct value_string gsm_pchant_names[13]; const struct value_string gsm_pchant_descs[13]; diff --git a/openbsc/src/libbsc/bsc_vty.c b/openbsc/src/libbsc/bsc_vty.c index c1882fc..702af4a 100644 --- a/openbsc/src/libbsc/bsc_vty.c +++ b/openbsc/src/libbsc/bsc_vty.c @@ -1615,7 +1615,7 @@ struct gsm_bts *bts = vty->index; int rc; - rc = gsm_set_bts_type(bts, parse_btstype(argv[0])); + rc = gsm_set_bts_type(bts, str2btstype(argv[0])); if (rc < 0) return CMD_WARNING; diff --git a/openbsc/src/libcommon/gsm_data.c b/openbsc/src/libcommon/gsm_data.c index fd34793..8ec0be5 100644 --- a/openbsc/src/libcommon/gsm_data.c +++ b/openbsc/src/libcommon/gsm_data.c @@ -90,16 +90,6 @@ return NULL; } -const struct value_string bts_type_names[_NUM_GSM_BTS_TYPE+1] = { - { GSM_BTS_TYPE_UNKNOWN, "unknown" }, - { GSM_BTS_TYPE_BS11, "bs11" }, - { GSM_BTS_TYPE_NANOBTS, "nanobts" }, - { GSM_BTS_TYPE_RBS2000, "rbs2000" }, - { GSM_BTS_TYPE_NOKIA_SITE, "nokia_site" }, - { GSM_BTS_TYPE_OSMOBTS, "sysmobts" }, - { 0, NULL } -}; - const struct value_string bts_type_descs[_NUM_GSM_BTS_TYPE+1] = { { GSM_BTS_TYPE_UNKNOWN, "Unknown BTS Type" }, { GSM_BTS_TYPE_BS11, "Siemens BTS (BS-11 or compatible)" }, @@ -109,16 +99,6 @@ { GSM_BTS_TYPE_OSMOBTS, "sysmocom sysmoBTS" }, { 0, NULL } }; - -enum gsm_bts_type parse_btstype(const char *arg) -{ - return get_string_value(bts_type_names, arg); -} - -const char *btstype2str(enum gsm_bts_type type) -{ - return get_value_string(bts_type_names, type); -} struct gsm_bts_trx *gsm_bts_trx_by_nr(struct gsm_bts *bts, int nr) { diff --git a/openbsc/src/libcommon/gsm_data_shared.c b/openbsc/src/libcommon/gsm_data_shared.c index 387af70..1df92e7 100644 --- a/openbsc/src/libcommon/gsm_data_shared.c +++ b/openbsc/src/libcommon/gsm_data_shared.c @@ -51,6 +51,61 @@ gsm_abis_mo_reset(mo); } +const struct value_string bts_attribute_names[] = { + OSMO_VALUE_STRING(BTS_TYPE_VARIANT), + OSMO_VALUE_STRING(BTS_SUB_MODEL), + { 0, NULL } +}; + +enum bts_attribute str2btsattr(const char *s) +{ + return get_string_value(bts_attribute_names, s); +} + +const char *btsatttr2str(enum bts_attribute v) +{ + return get_value_string(bts_attribute_names, v); +} + +const struct value_string bts_variant_names[_NUM_BTS_VARIANT + 1] = { + { BTS_UNKNOWN, "unknown" }, + { BTS_OSMO_LITECELL15, "Litecell15" }, + { BTS_OSMO_OCTPHY, "OctPHY" }, + { BTS_OSMO_SYSMO, "Sysmo" }, + { BTS_OSMO_TRX, "TRX" }, + { 0, NULL } +}; + +enum gsm_bts_type_variant str2btsvariant(const char *arg) +{ + return get_string_value(bts_variant_names, arg); +} + +const char *btsvariant2str(enum gsm_bts_type_variant v) +{ + return get_value_string(bts_variant_names, v); +} + +const struct value_string bts_type_names[_NUM_GSM_BTS_TYPE + 1] = { + { GSM_BTS_TYPE_UNKNOWN, "unknown" }, + { GSM_BTS_TYPE_BS11, "bs11" }, + { GSM_BTS_TYPE_NANOBTS, "nanobts" }, + { GSM_BTS_TYPE_RBS2000, "rbs2000" }, + { GSM_BTS_TYPE_NOKIA_SITE, "nokia_site" }, + { GSM_BTS_TYPE_OSMOBTS, "sysmobts" }, + { 0, NULL } +}; + +enum gsm_bts_type str2btstype(const char *arg) +{ + return get_string_value(bts_type_names, arg); +} + +const char *btstype2str(enum gsm_bts_type type) +{ + return get_value_string(bts_type_names, type); +} + const struct value_string gsm_pchant_names[13] = { { GSM_PCHAN_NONE, "NONE" }, { GSM_PCHAN_CCCH, "CCCH" }, -- To view, visit https://gerrit.osmocom.org/2286 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ida94725a6fce968443541e3526f48f13758031fd Gerrit-PatchSet: 5 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Wed Apr 12 10:10:47 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Wed, 12 Apr 2017 10:10:47 +0000 Subject: [PATCH] libosmo-netif[master]: SCTP: Fix PPID byte width Message-ID: Review at https://gerrit.osmocom.org/2309 SCTP: Fix PPID byte width In a659590e29412588bca2243b8329e82286244b00 we fixed endianness issues with the Stream ID field, but at the same time mistook the PPID field for 16bits. In reality it is 32bits, and hence our 'htons' is rendering wrong PPID values. Change-Id: I1b60523044835ee630dba9a43d26af4f1ebd1ced --- M src/stream.c 1 file changed, 3 insertions(+), 3 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-netif refs/changes/09/2309/1 diff --git a/src/stream.c b/src/stream.c index 3bc36a3..591cd06 100644 --- a/src/stream.c +++ b/src/stream.c @@ -185,7 +185,7 @@ #ifdef HAVE_LIBSCTP case IPPROTO_SCTP: memset(&sinfo, 0, sizeof(sinfo)); - sinfo.sinfo_ppid = htons(msgb_sctp_ppid(msg)); + sinfo.sinfo_ppid = htonl(msgb_sctp_ppid(msg)); sinfo.sinfo_stream = msgb_sctp_stream(msg); ret = sctp_send(cli->ofd.fd, msg->data, msgb_length(msg), &sinfo, MSG_NOSIGNAL); @@ -752,7 +752,7 @@ #ifdef HAVE_LIBSCTP case IPPROTO_SCTP: memset(&sinfo, 0, sizeof(sinfo)); - sinfo.sinfo_ppid = htons(msgb_sctp_ppid(msg)); + sinfo.sinfo_ppid = htonl(msgb_sctp_ppid(msg)); sinfo.sinfo_stream = msgb_sctp_stream(msg); ret = sctp_send(conn->ofd.fd, msg->data, msgb_length(msg), &sinfo, MSG_NOSIGNAL); @@ -931,7 +931,7 @@ } return -EAGAIN; } - msgb_sctp_ppid(msg) = ntohs(sinfo.sinfo_ppid); + msgb_sctp_ppid(msg) = ntohl(sinfo.sinfo_ppid); msgb_sctp_stream(msg) = sinfo.sinfo_stream; break; #endif -- To view, visit https://gerrit.osmocom.org/2309 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I1b60523044835ee630dba9a43d26af4f1ebd1ced Gerrit-PatchSet: 1 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Wed Apr 12 10:11:52 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Wed, 12 Apr 2017 10:11:52 +0000 Subject: [PATCH] libosmo-sccp[master]: osmo_ss7: Fix SCTP PPID byte width Message-ID: Review at https://gerrit.osmocom.org/2310 osmo_ss7: Fix SCTP PPID byte width In 17df5953ff477e89f1618f5a726df39197e1b826 we fixed endianness issues with the Stream ID field, but at the same time mistook the PPID field for 16bits. In reality it is 32bits, and hence our 'htons' is rendering wrong PPID values. Change-Id: Ief04486e752e6b7e0a853b1fa9ca525ad47800f6 --- M src/osmo_ss7.c 1 file changed, 2 insertions(+), 2 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/10/2310/1 diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index 4f12152..bb13b43 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -1261,7 +1261,7 @@ goto out; } - ppid = ntohs(sinfo.sinfo_ppid); + ppid = ntohl(sinfo.sinfo_ppid); msgb_sctp_ppid(msg) = ppid; msgb_sctp_stream(msg) = sinfo.sinfo_stream; msg->dst = asp; @@ -1373,7 +1373,7 @@ if (rc == 0) goto out; - ppid = ntohs(sinfo.sinfo_ppid); + ppid = ntohl(sinfo.sinfo_ppid); msgb_sctp_ppid(msg) = ppid; msgb_sctp_stream(msg) = sinfo.sinfo_stream; msg->dst = asp; -- To view, visit https://gerrit.osmocom.org/2310 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ief04486e752e6b7e0a853b1fa9ca525ad47800f6 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Wed Apr 12 10:20:34 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Wed, 12 Apr 2017 10:20:34 +0000 Subject: libosmo-netif[master]: SCTP: Fix PPID byte width In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2309 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I1b60523044835ee630dba9a43d26af4f1ebd1ced Gerrit-PatchSet: 1 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Wed Apr 12 10:20:36 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Wed, 12 Apr 2017 10:20:36 +0000 Subject: [MERGED] libosmo-netif[master]: SCTP: Fix PPID byte width In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: SCTP: Fix PPID byte width ...................................................................... SCTP: Fix PPID byte width In a659590e29412588bca2243b8329e82286244b00 we fixed endianness issues with the Stream ID field, but at the same time mistook the PPID field for 16bits. In reality it is 32bits, and hence our 'htons' is rendering wrong PPID values. Change-Id: I1b60523044835ee630dba9a43d26af4f1ebd1ced --- M src/stream.c 1 file changed, 3 insertions(+), 3 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/stream.c b/src/stream.c index 3bc36a3..591cd06 100644 --- a/src/stream.c +++ b/src/stream.c @@ -185,7 +185,7 @@ #ifdef HAVE_LIBSCTP case IPPROTO_SCTP: memset(&sinfo, 0, sizeof(sinfo)); - sinfo.sinfo_ppid = htons(msgb_sctp_ppid(msg)); + sinfo.sinfo_ppid = htonl(msgb_sctp_ppid(msg)); sinfo.sinfo_stream = msgb_sctp_stream(msg); ret = sctp_send(cli->ofd.fd, msg->data, msgb_length(msg), &sinfo, MSG_NOSIGNAL); @@ -752,7 +752,7 @@ #ifdef HAVE_LIBSCTP case IPPROTO_SCTP: memset(&sinfo, 0, sizeof(sinfo)); - sinfo.sinfo_ppid = htons(msgb_sctp_ppid(msg)); + sinfo.sinfo_ppid = htonl(msgb_sctp_ppid(msg)); sinfo.sinfo_stream = msgb_sctp_stream(msg); ret = sctp_send(conn->ofd.fd, msg->data, msgb_length(msg), &sinfo, MSG_NOSIGNAL); @@ -931,7 +931,7 @@ } return -EAGAIN; } - msgb_sctp_ppid(msg) = ntohs(sinfo.sinfo_ppid); + msgb_sctp_ppid(msg) = ntohl(sinfo.sinfo_ppid); msgb_sctp_stream(msg) = sinfo.sinfo_stream; break; #endif -- To view, visit https://gerrit.osmocom.org/2309 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I1b60523044835ee630dba9a43d26af4f1ebd1ced Gerrit-PatchSet: 1 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Wed Apr 12 10:20:40 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Wed, 12 Apr 2017 10:20:40 +0000 Subject: libosmo-sccp[master]: osmo_ss7: Fix SCTP PPID byte width In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2310 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ief04486e752e6b7e0a853b1fa9ca525ad47800f6 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Wed Apr 12 10:20:42 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Wed, 12 Apr 2017 10:20:42 +0000 Subject: [MERGED] libosmo-sccp[master]: osmo_ss7: Fix SCTP PPID byte width In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: osmo_ss7: Fix SCTP PPID byte width ...................................................................... osmo_ss7: Fix SCTP PPID byte width In 17df5953ff477e89f1618f5a726df39197e1b826 we fixed endianness issues with the Stream ID field, but at the same time mistook the PPID field for 16bits. In reality it is 32bits, and hence our 'htons' is rendering wrong PPID values. Change-Id: Ief04486e752e6b7e0a853b1fa9ca525ad47800f6 --- M src/osmo_ss7.c 1 file changed, 2 insertions(+), 2 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index 4f12152..bb13b43 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -1261,7 +1261,7 @@ goto out; } - ppid = ntohs(sinfo.sinfo_ppid); + ppid = ntohl(sinfo.sinfo_ppid); msgb_sctp_ppid(msg) = ppid; msgb_sctp_stream(msg) = sinfo.sinfo_stream; msg->dst = asp; @@ -1373,7 +1373,7 @@ if (rc == 0) goto out; - ppid = ntohs(sinfo.sinfo_ppid); + ppid = ntohl(sinfo.sinfo_ppid); msgb_sctp_ppid(msg) = ppid; msgb_sctp_stream(msg) = sinfo.sinfo_stream; msg->dst = asp; -- To view, visit https://gerrit.osmocom.org/2310 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ief04486e752e6b7e0a853b1fa9ca525ad47800f6 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Wed Apr 12 12:10:18 2017 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Wed, 12 Apr 2017 12:10:18 +0000 Subject: openbsc[master]: build: iu: use libosmo-sccp tag 'old_sua' In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 the "branch" is from when the stuff was still a branch. more accurate would be "tree-ish". I took back the code from before 4aa75e74f48b06ecadc37dffe2875c93fd6ee674 and just changed the branch name to old_sua, which happens to be a tag -- not that git cares. Do you care enough to hold up fixing the openbsc build? Then revert or patch up this commit. I'm submitting this now because I want to quickly fix the build (am on vacation). -- To view, visit https://gerrit.osmocom.org/2293 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Id74a802fd2ca65f4b6c2079550fbb6b0af3e8340 Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Wed Apr 12 12:10:45 2017 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Wed, 12 Apr 2017 12:10:45 +0000 Subject: [MERGED] openbsc[master]: build: iu: use libosmo-sccp tag 'old_sua' In-Reply-To: References: Message-ID: Neels Hofmeyr has submitted this change and it was merged. Change subject: build: iu: use libosmo-sccp tag 'old_sua' ...................................................................... build: iu: use libosmo-sccp tag 'old_sua' libosmo-sccp master is moving ahead, openbsc --enable-iu needs an older version. Change-Id: Id74a802fd2ca65f4b6c2079550fbb6b0af3e8340 --- M contrib/jenkins.sh 1 file changed, 5 insertions(+), 1 deletion(-) Approvals: Neels Hofmeyr: Looks good to me, approved Jenkins Builder: Verified Holger Freyther: Looks good to me, but someone else must approve diff --git a/contrib/jenkins.sh b/contrib/jenkins.sh index 323ae04..0021947 100755 --- a/contrib/jenkins.sh +++ b/contrib/jenkins.sh @@ -17,9 +17,13 @@ export PKG_CONFIG_PATH="$inst/lib/pkgconfig:$PKG_CONFIG_PATH" export LD_LIBRARY_PATH="$inst/lib" +if [ "x$IU" = "x--enable-iu" ]; then + sccp_branch="old_sua" +fi + osmo-build-dep.sh libosmo-abis osmo-build-dep.sh libosmo-netif -osmo-build-dep.sh libosmo-sccp +osmo-build-dep.sh libosmo-sccp $sccp_branch PARALLEL_MAKE="" osmo-build-dep.sh libsmpp34 osmo-build-dep.sh openggsn -- To view, visit https://gerrit.osmocom.org/2293 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Id74a802fd2ca65f4b6c2079550fbb6b0af3e8340 Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Wed Apr 12 12:28:47 2017 From: gerrit-no-reply at lists.osmocom.org (Pau Espin Pedrol) Date: Wed, 12 Apr 2017 12:28:47 +0000 Subject: openbsc[master]: nat: Fix initial buffer size parameter for getline In-Reply-To: References: Message-ID: Patch Set 1: I was reading the code and I was not understanding why that value was being passed to getline() so I went have a look at man to see if I was missing something. -- To view, visit https://gerrit.osmocom.org/2287 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I36683884106b97ef697264716de13813c00da9bc Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Pau Espin Pedrol Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Pau Espin Pedrol Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Wed Apr 12 13:07:26 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Wed, 12 Apr 2017 13:07:26 +0000 Subject: [PATCH] libosmo-netif[master]: stream.h: Add missing stdbool.h include Message-ID: Review at https://gerrit.osmocom.org/2311 stream.h: Add missing stdbool.h include Functions introduced in 9ec26583cd807e0aeaa3b9de927f3d8a768c3a71 are using the bool type without referencing stdbool.h as include file. Change-Id: I736cb04629d516c10c7d5f42f792ed3d5ae6658f --- M include/osmocom/netif/stream.h 1 file changed, 2 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-netif refs/changes/11/2311/1 diff --git a/include/osmocom/netif/stream.h b/include/osmocom/netif/stream.h index 7afb7af..08af3fd 100644 --- a/include/osmocom/netif/stream.h +++ b/include/osmocom/netif/stream.h @@ -1,6 +1,8 @@ #ifndef _OSMO_STREAM_H_ #define _OSMO_STREAM_H_ +#include + /*! \addtogroup stream * @{ */ -- To view, visit https://gerrit.osmocom.org/2311 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I736cb04629d516c10c7d5f42f792ed3d5ae6658f Gerrit-PatchSet: 1 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Wed Apr 12 13:13:54 2017 From: gerrit-no-reply at lists.osmocom.org (Pau Espin Pedrol) Date: Wed, 12 Apr 2017 13:13:54 +0000 Subject: libosmo-netif[master]: stream.h: Add missing stdbool.h include In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+1 Thanks! Looking at the header file, it seems it may also require stdint.h for uint16_t. -- To view, visit https://gerrit.osmocom.org/2311 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I736cb04629d516c10c7d5f42f792ed3d5ae6658f Gerrit-PatchSet: 1 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Pau Espin Pedrol Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Wed Apr 12 13:35:19 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Wed, 12 Apr 2017 13:35:19 +0000 Subject: [PATCH] openbsc[master]: Prepare for extended SI2quater support Message-ID: Review at https://gerrit.osmocom.org/2312 Prepare for extended SI2quater support Supporting SI2quater support as per 3GPP TS 44.018 will require chnages to the way System Information is stored because it uses 1:n instead of 1:1 mapping between SI type and generated SI content. This should not affect other SI types though. To facilitate this transition: * convert the code to always use GSM_BTS_SI helper instead of accessing buffer directly * add similar helper for gsm_lchan Change-Id: I74e4e3cb86364cec869a1472a41b4a95af0d50dd Related: RT#8792 --- M openbsc/include/openbsc/gsm_data_shared.h M openbsc/src/libbsc/bsc_vty.c M openbsc/src/libbsc/system_information.c M openbsc/tests/gsm0408/gsm0408_test.c 4 files changed, 9 insertions(+), 11 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/12/2312/1 diff --git a/openbsc/include/openbsc/gsm_data_shared.h b/openbsc/include/openbsc/gsm_data_shared.h index 242889a..560e548 100644 --- a/openbsc/include/openbsc/gsm_data_shared.h +++ b/openbsc/include/openbsc/gsm_data_shared.h @@ -484,6 +484,7 @@ }; #define GSM_BTS_SI(bts, i) (void *)(bts->si_buf[i]) +#define GSM_LCHAN_SI(lchan, i) (void *)(lchan->si.buf[i]) enum gsm_bts_type { GSM_BTS_TYPE_UNKNOWN, diff --git a/openbsc/src/libbsc/bsc_vty.c b/openbsc/src/libbsc/bsc_vty.c index c1882fc..a2f0264 100644 --- a/openbsc/src/libbsc/bsc_vty.c +++ b/openbsc/src/libbsc/bsc_vty.c @@ -644,7 +644,7 @@ get_value_string(osmo_sitype_strs, i), VTY_NEWLINE); vty_out(vty, " system-information %s static %s%s", get_value_string(osmo_sitype_strs, i), - osmo_hexdump_nospc(bts->si_buf[i], sizeof(bts->si_buf[i])), + osmo_hexdump_nospc(GSM_BTS_SI(bts, i), GSM_MACBLOCK_LEN), VTY_NEWLINE); } } @@ -2688,11 +2688,11 @@ } /* Fill buffer with padding pattern */ - memset(bts->si_buf[type], 0x2b, sizeof(bts->si_buf[type])); + memset(GSM_BTS_SI(bts, type), 0x2b, GSM_MACBLOCK_LEN); /* Parse the user-specified SI in hex format, [partially] overwriting padding */ - rc = osmo_hexparse(argv[1], bts->si_buf[type], sizeof(bts->si_buf[0])); - if (rc < 0 || rc > sizeof(bts->si_buf[0])) { + rc = osmo_hexparse(argv[1], GSM_BTS_SI(bts, type), GSM_MACBLOCK_LEN); + if (rc < 0 || rc > GSM_MACBLOCK_LEN) { vty_out(vty, "Error parsing HEXSTRING%s", VTY_NEWLINE); return CMD_WARNING; } diff --git a/openbsc/src/libbsc/system_information.c b/openbsc/src/libbsc/system_information.c index 2610331..84f3b6f 100644 --- a/openbsc/src/libbsc/system_information.c +++ b/openbsc/src/libbsc/system_information.c @@ -633,8 +633,7 @@ if (n) { /* indicate in SI2 and SI2bis: there is an extension */ struct gsm48_system_information_type_2 *si2 = - (struct gsm48_system_information_type_2 *) - bts->si_buf[SYSINFO_TYPE_2]; + (struct gsm48_system_information_type_2 *) GSM_BTS_SI(bts, SYSINFO_TYPE_2); si2->bcch_frequency_list[0] |= 0x20; si2b->bcch_frequency_list[0] |= 0x20; } else @@ -887,8 +886,7 @@ if (n) { /* indicate in SI5 and SI5bis: there is an extension */ struct gsm48_system_information_type_5 *si5 = - (struct gsm48_system_information_type_5 *) - bts->si_buf[SYSINFO_TYPE_5]; + (struct gsm48_system_information_type_5 *) GSM_BTS_SI(bts, SYSINFO_TYPE_5); si5->bcch_frequency_list[0] |= 0x20; si5b->bcch_frequency_list[0] |= 0x20; } else diff --git a/openbsc/tests/gsm0408/gsm0408_test.c b/openbsc/tests/gsm0408/gsm0408_test.c index 08cf43f..81dc177 100644 --- a/openbsc/tests/gsm0408/gsm0408_test.c +++ b/openbsc/tests/gsm0408/gsm0408_test.c @@ -99,13 +99,12 @@ bts->si_valid = 0; bts->si_valid |= (1 << SYSINFO_TYPE_2quater); /* should be no-op as entire buffer is filled with padding: */ - memset(bts->si_buf[SYSINFO_TYPE_2quater], 0xAE, GSM_MACBLOCK_LEN); + memset(GSM_BTS_SI(bts, SYSINFO_TYPE_2quater), 0xAE, GSM_MACBLOCK_LEN); int r = gsm_generate_si(bts, SYSINFO_TYPE_2quater); bool v = bts->si_valid & (1 << SYSINFO_TYPE_2quater); if (r > 0) printf("generated %s SI2quater: [%d] %s\n", - v ? "valid" : "invalid", r, - osmo_hexdump(bts->si_buf[SYSINFO_TYPE_2quater], r)); + v ? "valid" : "invalid", r, osmo_hexdump(GSM_BTS_SI(bts, SYSINFO_TYPE_2quater), r)); else printf("failed to generate SI2quater: %s\n", strerror(-r)); } -- To view, visit https://gerrit.osmocom.org/2312 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I74e4e3cb86364cec869a1472a41b4a95af0d50dd Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Max From gerrit-no-reply at lists.osmocom.org Wed Apr 12 13:41:07 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Wed, 12 Apr 2017 13:41:07 +0000 Subject: [PATCH] openbsc[master]: Prepare for extended SI2quater support In-Reply-To: References: Message-ID: Prepare for extended SI2quater support Supporting SI2quater support as per 3GPP TS 44.018 will require chnages to the way System Information is stored because it uses 1:n instead of 1:1 mapping between SI type and generated SI content. This should not affect other SI types though. To facilitate this transition: * convert the code to always use GSM_BTS_SI helper instead of accessing buffer directly * add similar helper for gsm_lchan Change-Id: I74e4e3cb86364cec869a1472a41b4a95af0d50dd Related: RT#8792 --- M openbsc/include/openbsc/gsm_data_shared.h M openbsc/src/libbsc/bsc_vty.c M openbsc/src/libbsc/system_information.c M openbsc/tests/gsm0408/gsm0408_test.c 4 files changed, 10 insertions(+), 12 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/12/2312/2 diff --git a/openbsc/include/openbsc/gsm_data_shared.h b/openbsc/include/openbsc/gsm_data_shared.h index 242889a..560e548 100644 --- a/openbsc/include/openbsc/gsm_data_shared.h +++ b/openbsc/include/openbsc/gsm_data_shared.h @@ -484,6 +484,7 @@ }; #define GSM_BTS_SI(bts, i) (void *)(bts->si_buf[i]) +#define GSM_LCHAN_SI(lchan, i) (void *)(lchan->si.buf[i]) enum gsm_bts_type { GSM_BTS_TYPE_UNKNOWN, diff --git a/openbsc/src/libbsc/bsc_vty.c b/openbsc/src/libbsc/bsc_vty.c index c1882fc..a2f0264 100644 --- a/openbsc/src/libbsc/bsc_vty.c +++ b/openbsc/src/libbsc/bsc_vty.c @@ -644,7 +644,7 @@ get_value_string(osmo_sitype_strs, i), VTY_NEWLINE); vty_out(vty, " system-information %s static %s%s", get_value_string(osmo_sitype_strs, i), - osmo_hexdump_nospc(bts->si_buf[i], sizeof(bts->si_buf[i])), + osmo_hexdump_nospc(GSM_BTS_SI(bts, i), GSM_MACBLOCK_LEN), VTY_NEWLINE); } } @@ -2688,11 +2688,11 @@ } /* Fill buffer with padding pattern */ - memset(bts->si_buf[type], 0x2b, sizeof(bts->si_buf[type])); + memset(GSM_BTS_SI(bts, type), 0x2b, GSM_MACBLOCK_LEN); /* Parse the user-specified SI in hex format, [partially] overwriting padding */ - rc = osmo_hexparse(argv[1], bts->si_buf[type], sizeof(bts->si_buf[0])); - if (rc < 0 || rc > sizeof(bts->si_buf[0])) { + rc = osmo_hexparse(argv[1], GSM_BTS_SI(bts, type), GSM_MACBLOCK_LEN); + if (rc < 0 || rc > GSM_MACBLOCK_LEN) { vty_out(vty, "Error parsing HEXSTRING%s", VTY_NEWLINE); return CMD_WARNING; } diff --git a/openbsc/src/libbsc/system_information.c b/openbsc/src/libbsc/system_information.c index 2610331..71916e3 100644 --- a/openbsc/src/libbsc/system_information.c +++ b/openbsc/src/libbsc/system_information.c @@ -633,8 +633,7 @@ if (n) { /* indicate in SI2 and SI2bis: there is an extension */ struct gsm48_system_information_type_2 *si2 = - (struct gsm48_system_information_type_2 *) - bts->si_buf[SYSINFO_TYPE_2]; + (struct gsm48_system_information_type_2 *) GSM_BTS_SI(bts, SYSINFO_TYPE_2); si2->bcch_frequency_list[0] |= 0x20; si2b->bcch_frequency_list[0] |= 0x20; } else @@ -887,8 +886,7 @@ if (n) { /* indicate in SI5 and SI5bis: there is an extension */ struct gsm48_system_information_type_5 *si5 = - (struct gsm48_system_information_type_5 *) - bts->si_buf[SYSINFO_TYPE_5]; + (struct gsm48_system_information_type_5 *) GSM_BTS_SI(bts, SYSINFO_TYPE_5); si5->bcch_frequency_list[0] |= 0x20; si5b->bcch_frequency_list[0] |= 0x20; } else @@ -1090,5 +1088,5 @@ if (!gen_si) return -EINVAL; - return gen_si(bts->si_buf[si_type], bts); + return gen_si(GSM_BTS_SI(bts, si_type), bts); } diff --git a/openbsc/tests/gsm0408/gsm0408_test.c b/openbsc/tests/gsm0408/gsm0408_test.c index 08cf43f..81dc177 100644 --- a/openbsc/tests/gsm0408/gsm0408_test.c +++ b/openbsc/tests/gsm0408/gsm0408_test.c @@ -99,13 +99,12 @@ bts->si_valid = 0; bts->si_valid |= (1 << SYSINFO_TYPE_2quater); /* should be no-op as entire buffer is filled with padding: */ - memset(bts->si_buf[SYSINFO_TYPE_2quater], 0xAE, GSM_MACBLOCK_LEN); + memset(GSM_BTS_SI(bts, SYSINFO_TYPE_2quater), 0xAE, GSM_MACBLOCK_LEN); int r = gsm_generate_si(bts, SYSINFO_TYPE_2quater); bool v = bts->si_valid & (1 << SYSINFO_TYPE_2quater); if (r > 0) printf("generated %s SI2quater: [%d] %s\n", - v ? "valid" : "invalid", r, - osmo_hexdump(bts->si_buf[SYSINFO_TYPE_2quater], r)); + v ? "valid" : "invalid", r, osmo_hexdump(GSM_BTS_SI(bts, SYSINFO_TYPE_2quater), r)); else printf("failed to generate SI2quater: %s\n", strerror(-r)); } -- To view, visit https://gerrit.osmocom.org/2312 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I74e4e3cb86364cec869a1472a41b4a95af0d50dd Gerrit-PatchSet: 2 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Wed Apr 12 13:58:28 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Wed, 12 Apr 2017 13:58:28 +0000 Subject: [PATCH] openbsc[master]: Prepare for extended SI2quater support In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2312 to look at the new patch set (#3). Prepare for extended SI2quater support Supporting SI2quater support as per 3GPP TS 44.018 will require chnages to the way System Information is stored because it uses 1:n instead of 1:1 mapping between SI type and generated SI content. This should not affect other SI types though. To facilitate this transition: * convert the code to always use GSM_BTS_SI helper instead of accessing buffer directly * make helper more robust by adding extra parenthesis * add similar helper for gsm_lchan Change-Id: I74e4e3cb86364cec869a1472a41b4a95af0d50dd Related: RT#8792 --- M openbsc/include/openbsc/gsm_data_shared.h M openbsc/src/libbsc/bsc_vty.c M openbsc/src/libbsc/system_information.c M openbsc/tests/gsm0408/gsm0408_test.c 4 files changed, 11 insertions(+), 13 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/12/2312/3 diff --git a/openbsc/include/openbsc/gsm_data_shared.h b/openbsc/include/openbsc/gsm_data_shared.h index 242889a..d9d508b 100644 --- a/openbsc/include/openbsc/gsm_data_shared.h +++ b/openbsc/include/openbsc/gsm_data_shared.h @@ -483,7 +483,8 @@ struct gsm_bts_trx_ts ts[TRX_NR_TS]; }; -#define GSM_BTS_SI(bts, i) (void *)(bts->si_buf[i]) +#define GSM_BTS_SI(bts, i) (void *)((bts)->si_buf[i]) +#define GSM_LCHAN_SI(lchan, i) (void *)((lchan)->si.buf[i]) enum gsm_bts_type { GSM_BTS_TYPE_UNKNOWN, diff --git a/openbsc/src/libbsc/bsc_vty.c b/openbsc/src/libbsc/bsc_vty.c index c1882fc..a2f0264 100644 --- a/openbsc/src/libbsc/bsc_vty.c +++ b/openbsc/src/libbsc/bsc_vty.c @@ -644,7 +644,7 @@ get_value_string(osmo_sitype_strs, i), VTY_NEWLINE); vty_out(vty, " system-information %s static %s%s", get_value_string(osmo_sitype_strs, i), - osmo_hexdump_nospc(bts->si_buf[i], sizeof(bts->si_buf[i])), + osmo_hexdump_nospc(GSM_BTS_SI(bts, i), GSM_MACBLOCK_LEN), VTY_NEWLINE); } } @@ -2688,11 +2688,11 @@ } /* Fill buffer with padding pattern */ - memset(bts->si_buf[type], 0x2b, sizeof(bts->si_buf[type])); + memset(GSM_BTS_SI(bts, type), 0x2b, GSM_MACBLOCK_LEN); /* Parse the user-specified SI in hex format, [partially] overwriting padding */ - rc = osmo_hexparse(argv[1], bts->si_buf[type], sizeof(bts->si_buf[0])); - if (rc < 0 || rc > sizeof(bts->si_buf[0])) { + rc = osmo_hexparse(argv[1], GSM_BTS_SI(bts, type), GSM_MACBLOCK_LEN); + if (rc < 0 || rc > GSM_MACBLOCK_LEN) { vty_out(vty, "Error parsing HEXSTRING%s", VTY_NEWLINE); return CMD_WARNING; } diff --git a/openbsc/src/libbsc/system_information.c b/openbsc/src/libbsc/system_information.c index 2610331..71916e3 100644 --- a/openbsc/src/libbsc/system_information.c +++ b/openbsc/src/libbsc/system_information.c @@ -633,8 +633,7 @@ if (n) { /* indicate in SI2 and SI2bis: there is an extension */ struct gsm48_system_information_type_2 *si2 = - (struct gsm48_system_information_type_2 *) - bts->si_buf[SYSINFO_TYPE_2]; + (struct gsm48_system_information_type_2 *) GSM_BTS_SI(bts, SYSINFO_TYPE_2); si2->bcch_frequency_list[0] |= 0x20; si2b->bcch_frequency_list[0] |= 0x20; } else @@ -887,8 +886,7 @@ if (n) { /* indicate in SI5 and SI5bis: there is an extension */ struct gsm48_system_information_type_5 *si5 = - (struct gsm48_system_information_type_5 *) - bts->si_buf[SYSINFO_TYPE_5]; + (struct gsm48_system_information_type_5 *) GSM_BTS_SI(bts, SYSINFO_TYPE_5); si5->bcch_frequency_list[0] |= 0x20; si5b->bcch_frequency_list[0] |= 0x20; } else @@ -1090,5 +1088,5 @@ if (!gen_si) return -EINVAL; - return gen_si(bts->si_buf[si_type], bts); + return gen_si(GSM_BTS_SI(bts, si_type), bts); } diff --git a/openbsc/tests/gsm0408/gsm0408_test.c b/openbsc/tests/gsm0408/gsm0408_test.c index 08cf43f..81dc177 100644 --- a/openbsc/tests/gsm0408/gsm0408_test.c +++ b/openbsc/tests/gsm0408/gsm0408_test.c @@ -99,13 +99,12 @@ bts->si_valid = 0; bts->si_valid |= (1 << SYSINFO_TYPE_2quater); /* should be no-op as entire buffer is filled with padding: */ - memset(bts->si_buf[SYSINFO_TYPE_2quater], 0xAE, GSM_MACBLOCK_LEN); + memset(GSM_BTS_SI(bts, SYSINFO_TYPE_2quater), 0xAE, GSM_MACBLOCK_LEN); int r = gsm_generate_si(bts, SYSINFO_TYPE_2quater); bool v = bts->si_valid & (1 << SYSINFO_TYPE_2quater); if (r > 0) printf("generated %s SI2quater: [%d] %s\n", - v ? "valid" : "invalid", r, - osmo_hexdump(bts->si_buf[SYSINFO_TYPE_2quater], r)); + v ? "valid" : "invalid", r, osmo_hexdump(GSM_BTS_SI(bts, SYSINFO_TYPE_2quater), r)); else printf("failed to generate SI2quater: %s\n", strerror(-r)); } -- To view, visit https://gerrit.osmocom.org/2312 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I74e4e3cb86364cec869a1472a41b4a95af0d50dd Gerrit-PatchSet: 3 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Wed Apr 12 14:02:54 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Wed, 12 Apr 2017 14:02:54 +0000 Subject: [PATCH] osmo-bts[master]: Prepare for extended SI2quater support Supporting Message-ID: Review at https://gerrit.osmocom.org/2313 Prepare for extended SI2quater support Supporting SI2quater support as per 3GPP TS 44.018 will require chnages to the way System Information is stored because it uses 1:n instead of 1:1 mapping between SI type and generated SI content. This should not affect other SI types though. To facilitate this transition: * convert the code to always use GSM_LCHAN_SI helper instead of accessing buffer directly * move duplicated code to inline function Requires I74e4e3cb86364cec869a1472a41b4a95af0d50dd in OpenBSC. Change-Id: Ie97be6ead6ce6d2d425fbfac8429bb90afb95acc Related: RT#8792 --- M src/common/rsl.c M src/common/sysinfo.c M tests/misc/misc_test.c 3 files changed, 32 insertions(+), 32 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/13/2313/1 diff --git a/src/common/rsl.c b/src/common/rsl.c index 1d0bcea..7032d27 100644 --- a/src/common/rsl.c +++ b/src/common/rsl.c @@ -432,6 +432,30 @@ TLVP_VAL(&tp, RSL_IE_SMSCB_MSG)); } +static inline void lapdm_ui_prefix(uint8_t *buf, uint32_t *valid, const uint8_t *current, uint8_t osmo_si, uint16_t len) +{ + /* We have to pre-fix with the two-byte LAPDM UI header */ + if (len > sizeof(sysinfo_buf_t) - 2) + len = sizeof(sysinfo_buf_t) - 2; + + (*valid) |= (1 << osmo_si); + buf[0] = 0x03; /* C/R + EA */ + buf[1] = 0x03; /* UI frame */ + + memset(buf + 2, 0x2b, sizeof(sysinfo_buf_t) - 2); + memcpy(buf + 2, current, len); +} + +static inline void lapdm_ui_prefix_bts(struct gsm_bts *bts, const uint8_t *current, uint8_t osmo_si, uint16_t len) +{ + lapdm_ui_prefix(GSM_BTS_SI(bts, osmo_si), &bts->si_valid, current, osmo_si, len); +} + +static inline void lapdm_ui_prefix_lchan(struct gsm_lchan *lchan, const uint8_t *current, uint8_t osmo_si, uint16_t len) +{ + lapdm_ui_prefix(GSM_LCHAN_SI(lchan, osmo_si), &lchan->si.valid, current, osmo_si, len); +} + /* 8.6.2 SACCH FILLING */ static int rsl_rx_sacch_fill(struct gsm_bts_trx *trx, struct msgb *msg) { @@ -457,15 +481,8 @@ } if (TLVP_PRESENT(&tp, RSL_IE_L3_INFO)) { uint16_t len = TLVP_LEN(&tp, RSL_IE_L3_INFO); - /* We have to pre-fix with the two-byte LAPDM UI header */ - if (len > sizeof(sysinfo_buf_t)-2) - len = sizeof(sysinfo_buf_t)-2; - bts->si_valid |= (1 << osmo_si); - bts->si_buf[osmo_si][0] = 0x03; /* C/R + EA */ - bts->si_buf[osmo_si][1] = 0x03; /* UI frame */ - memset(bts->si_buf[osmo_si]+2, 0x2b, sizeof(sysinfo_buf_t)-2); - memcpy(bts->si_buf[osmo_si]+2, - TLVP_VAL(&tp, RSL_IE_L3_INFO), len); + lapdm_ui_prefix_bts(bts, TLVP_VAL(&tp, RSL_IE_L3_INFO), osmo_si, len); + LOGP(DRSL, LOGL_INFO, " Rx RSL SACCH FILLING (SI%s)\n", get_value_string(osmo_sitype_strs, osmo_si)); } else { @@ -699,8 +716,7 @@ continue; } lchan->si.valid |= osmo_si_shifted; - memcpy(lchan->si.buf[osmo_si], bts->si_buf[osmo_si], - sizeof(sysinfo_buf_t)); + memcpy(GSM_LCHAN_SI(lchan, osmo_si), GSM_BTS_SI(bts, osmo_si), sizeof(sysinfo_buf_t)); } } @@ -885,7 +901,6 @@ uint8_t rsl_si = *cur++; uint8_t si_len = *cur++; uint8_t osmo_si; - uint8_t copy_len; if (!OSMO_IN_ARRAY(rsl_si, rsl_sacch_sitypes)) return rsl_tx_error_report(msg->trx, RSL_ERR_IE_CONTENT); @@ -896,15 +911,7 @@ return rsl_tx_error_report(msg->trx, RSL_ERR_IE_CONTENT); } - copy_len = si_len; - /* We have to pre-fix with the two-byte LAPDM UI header */ - if (copy_len > sizeof(sysinfo_buf_t)-2) - copy_len = sizeof(sysinfo_buf_t)-2; - lchan->si.valid |= (1 << osmo_si); - lchan->si.buf[osmo_si][0] = 0x03; - lchan->si.buf[osmo_si][1] = 0x03; - memset(lchan->si.buf[osmo_si]+2, 0x2b, sizeof(sysinfo_buf_t)-2); - memcpy(lchan->si.buf[osmo_si]+2, cur, copy_len); + lapdm_ui_prefix_lchan(lchan, cur, osmo_si, si_len); cur += si_len; if (cur >= val + tot_len) { @@ -1337,15 +1344,8 @@ } if (TLVP_PRESENT(&tp, RSL_IE_L3_INFO)) { uint16_t len = TLVP_LEN(&tp, RSL_IE_L3_INFO); - /* We have to pre-fix with the two-byte LAPDM UI header */ - if (len > sizeof(sysinfo_buf_t)-2) - len = sizeof(sysinfo_buf_t)-2; - lchan->si.valid |= (1 << osmo_si); - lchan->si.buf[osmo_si][0] = 0x03; - lchan->si.buf[osmo_si][1] = 0x03; - memset(lchan->si.buf[osmo_si]+2, 0x2b, sizeof(sysinfo_buf_t)-2); - memcpy(lchan->si.buf[osmo_si]+2, - TLVP_VAL(&tp, RSL_IE_L3_INFO), len); + lapdm_ui_prefix_lchan(lchan, TLVP_VAL(&tp, RSL_IE_L3_INFO), osmo_si, len); + LOGP(DRSL, LOGL_INFO, "%s Rx RSL SACCH FILLING (SI%s)\n", gsm_lchan_name(lchan), get_value_string(osmo_sitype_strs, osmo_si)); diff --git a/src/common/sysinfo.c b/src/common/sysinfo.c index 177ed58..d8671c8 100644 --- a/src/common/sysinfo.c +++ b/src/common/sysinfo.c @@ -154,7 +154,7 @@ if (!(lchan->si.valid & (1 << tmp))) continue; lchan->si.last = tmp; - return lchan->si.buf[tmp]; + return GSM_LCHAN_SI(lchan, tmp); } return NULL; } diff --git a/tests/misc/misc_test.c b/tests/misc/misc_test.c index 80dd317..c2918fb 100644 --- a/tests/misc/misc_test.c +++ b/tests/misc/misc_test.c @@ -142,7 +142,7 @@ /* initialize the input. */ for (i = 1; i < _MAX_SYSINFO_TYPE; ++i) { lchan.si.valid |= (1 << i); - memset(&lchan.si.buf[i], i, sizeof(lchan.si.buf[i])); + memset(GSM_LCHAN_SI(&lchan, i), i, GSM_MACBLOCK_LEN); } /* It will start with '1' */ -- To view, visit https://gerrit.osmocom.org/2313 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ie97be6ead6ce6d2d425fbfac8429bb90afb95acc Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max From gerrit-no-reply at lists.osmocom.org Wed Apr 12 14:12:51 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Wed, 12 Apr 2017 14:12:51 +0000 Subject: [PATCH] osmo-bts[master]: Prepare for extended SI2quater support In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2313 to look at the new patch set (#2). Prepare for extended SI2quater support SI2quater support as per 3GPP TS 44.018 will require chnages to the way System Information is stored because it uses 1:n instead of 1:1 mapping between SI type and generated SI content. This should not affect other SI types though. To facilitate this transition: * convert the code to always use GSM_LCHAN_SI helper instead of accessing buffer directly * move duplicated code to inline function Requires I74e4e3cb86364cec869a1472a41b4a95af0d50dd in OpenBSC. Change-Id: Ie97be6ead6ce6d2d425fbfac8429bb90afb95acc Related: RT#8792 --- M src/common/rsl.c M src/common/sysinfo.c M tests/misc/misc_test.c 3 files changed, 32 insertions(+), 32 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/13/2313/2 diff --git a/src/common/rsl.c b/src/common/rsl.c index 1d0bcea..7032d27 100644 --- a/src/common/rsl.c +++ b/src/common/rsl.c @@ -432,6 +432,30 @@ TLVP_VAL(&tp, RSL_IE_SMSCB_MSG)); } +static inline void lapdm_ui_prefix(uint8_t *buf, uint32_t *valid, const uint8_t *current, uint8_t osmo_si, uint16_t len) +{ + /* We have to pre-fix with the two-byte LAPDM UI header */ + if (len > sizeof(sysinfo_buf_t) - 2) + len = sizeof(sysinfo_buf_t) - 2; + + (*valid) |= (1 << osmo_si); + buf[0] = 0x03; /* C/R + EA */ + buf[1] = 0x03; /* UI frame */ + + memset(buf + 2, 0x2b, sizeof(sysinfo_buf_t) - 2); + memcpy(buf + 2, current, len); +} + +static inline void lapdm_ui_prefix_bts(struct gsm_bts *bts, const uint8_t *current, uint8_t osmo_si, uint16_t len) +{ + lapdm_ui_prefix(GSM_BTS_SI(bts, osmo_si), &bts->si_valid, current, osmo_si, len); +} + +static inline void lapdm_ui_prefix_lchan(struct gsm_lchan *lchan, const uint8_t *current, uint8_t osmo_si, uint16_t len) +{ + lapdm_ui_prefix(GSM_LCHAN_SI(lchan, osmo_si), &lchan->si.valid, current, osmo_si, len); +} + /* 8.6.2 SACCH FILLING */ static int rsl_rx_sacch_fill(struct gsm_bts_trx *trx, struct msgb *msg) { @@ -457,15 +481,8 @@ } if (TLVP_PRESENT(&tp, RSL_IE_L3_INFO)) { uint16_t len = TLVP_LEN(&tp, RSL_IE_L3_INFO); - /* We have to pre-fix with the two-byte LAPDM UI header */ - if (len > sizeof(sysinfo_buf_t)-2) - len = sizeof(sysinfo_buf_t)-2; - bts->si_valid |= (1 << osmo_si); - bts->si_buf[osmo_si][0] = 0x03; /* C/R + EA */ - bts->si_buf[osmo_si][1] = 0x03; /* UI frame */ - memset(bts->si_buf[osmo_si]+2, 0x2b, sizeof(sysinfo_buf_t)-2); - memcpy(bts->si_buf[osmo_si]+2, - TLVP_VAL(&tp, RSL_IE_L3_INFO), len); + lapdm_ui_prefix_bts(bts, TLVP_VAL(&tp, RSL_IE_L3_INFO), osmo_si, len); + LOGP(DRSL, LOGL_INFO, " Rx RSL SACCH FILLING (SI%s)\n", get_value_string(osmo_sitype_strs, osmo_si)); } else { @@ -699,8 +716,7 @@ continue; } lchan->si.valid |= osmo_si_shifted; - memcpy(lchan->si.buf[osmo_si], bts->si_buf[osmo_si], - sizeof(sysinfo_buf_t)); + memcpy(GSM_LCHAN_SI(lchan, osmo_si), GSM_BTS_SI(bts, osmo_si), sizeof(sysinfo_buf_t)); } } @@ -885,7 +901,6 @@ uint8_t rsl_si = *cur++; uint8_t si_len = *cur++; uint8_t osmo_si; - uint8_t copy_len; if (!OSMO_IN_ARRAY(rsl_si, rsl_sacch_sitypes)) return rsl_tx_error_report(msg->trx, RSL_ERR_IE_CONTENT); @@ -896,15 +911,7 @@ return rsl_tx_error_report(msg->trx, RSL_ERR_IE_CONTENT); } - copy_len = si_len; - /* We have to pre-fix with the two-byte LAPDM UI header */ - if (copy_len > sizeof(sysinfo_buf_t)-2) - copy_len = sizeof(sysinfo_buf_t)-2; - lchan->si.valid |= (1 << osmo_si); - lchan->si.buf[osmo_si][0] = 0x03; - lchan->si.buf[osmo_si][1] = 0x03; - memset(lchan->si.buf[osmo_si]+2, 0x2b, sizeof(sysinfo_buf_t)-2); - memcpy(lchan->si.buf[osmo_si]+2, cur, copy_len); + lapdm_ui_prefix_lchan(lchan, cur, osmo_si, si_len); cur += si_len; if (cur >= val + tot_len) { @@ -1337,15 +1344,8 @@ } if (TLVP_PRESENT(&tp, RSL_IE_L3_INFO)) { uint16_t len = TLVP_LEN(&tp, RSL_IE_L3_INFO); - /* We have to pre-fix with the two-byte LAPDM UI header */ - if (len > sizeof(sysinfo_buf_t)-2) - len = sizeof(sysinfo_buf_t)-2; - lchan->si.valid |= (1 << osmo_si); - lchan->si.buf[osmo_si][0] = 0x03; - lchan->si.buf[osmo_si][1] = 0x03; - memset(lchan->si.buf[osmo_si]+2, 0x2b, sizeof(sysinfo_buf_t)-2); - memcpy(lchan->si.buf[osmo_si]+2, - TLVP_VAL(&tp, RSL_IE_L3_INFO), len); + lapdm_ui_prefix_lchan(lchan, TLVP_VAL(&tp, RSL_IE_L3_INFO), osmo_si, len); + LOGP(DRSL, LOGL_INFO, "%s Rx RSL SACCH FILLING (SI%s)\n", gsm_lchan_name(lchan), get_value_string(osmo_sitype_strs, osmo_si)); diff --git a/src/common/sysinfo.c b/src/common/sysinfo.c index 177ed58..d8671c8 100644 --- a/src/common/sysinfo.c +++ b/src/common/sysinfo.c @@ -154,7 +154,7 @@ if (!(lchan->si.valid & (1 << tmp))) continue; lchan->si.last = tmp; - return lchan->si.buf[tmp]; + return GSM_LCHAN_SI(lchan, tmp); } return NULL; } diff --git a/tests/misc/misc_test.c b/tests/misc/misc_test.c index 80dd317..c2918fb 100644 --- a/tests/misc/misc_test.c +++ b/tests/misc/misc_test.c @@ -142,7 +142,7 @@ /* initialize the input. */ for (i = 1; i < _MAX_SYSINFO_TYPE; ++i) { lchan.si.valid |= (1 << i); - memset(&lchan.si.buf[i], i, sizeof(lchan.si.buf[i])); + memset(GSM_LCHAN_SI(&lchan, i), i, GSM_MACBLOCK_LEN); } /* It will start with '1' */ -- To view, visit https://gerrit.osmocom.org/2313 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ie97be6ead6ce6d2d425fbfac8429bb90afb95acc Gerrit-PatchSet: 2 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Wed Apr 12 17:08:38 2017 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Wed, 12 Apr 2017 17:08:38 +0000 Subject: [PATCH] osmo-bts[master]: octphy: set tx/rx antenne IDs via VTY In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/1976 to look at the new patch set (#3). octphy: set tx/rx antenne IDs via VTY add support for the TX/RX antenna-id feature that has been introduced with release OCTSDR-2G-02.07.00-B1314-BETA. The user can now set individual ID numbers for the TX and for the RX antenna. Change-Id: I872fe3c4d7b593358a4ce2f02cf0726611b9f3aa --- M configure.ac M include/osmo-bts/phy_link.h M src/osmo-bts-octphy/l1_oml.c M src/osmo-bts-octphy/octphy_vty.c 4 files changed, 64 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/76/1976/3 diff --git a/configure.ac b/configure.ac index cbfbf12..a03b2dd 100644 --- a/configure.ac +++ b/configure.ac @@ -112,6 +112,13 @@ [], [#include ]) + AC_CHECK_MEMBER([tOCTVC1_GSM_RF_CONFIG.ulTxAntennaId], + AC_DEFINE([OCTPHY_USE_ANTENNA_ID], + [1], + [Define to 1 if your octphy header files support antenna ids in tOCTVC1_GSM_RF_CONFIG]), + [], + [#include ]) + CPPFLAGS=$oldCPPFLAGS fi diff --git a/include/osmo-bts/phy_link.h b/include/osmo-bts/phy_link.h index e644a91..e8fd7eb 100644 --- a/include/osmo-bts/phy_link.h +++ b/include/osmo-bts/phy_link.h @@ -53,6 +53,10 @@ /* configuration */ uint32_t rf_port_index; +#if OCTPHY_USE_ANTENNA_ID == 1 + uint32_t rx_ant_id; + uint32_t tx_ant_id; +#endif uint32_t rx_gain_db; bool tx_atten_flag; uint32_t tx_atten_db; diff --git a/src/osmo-bts-octphy/l1_oml.c b/src/osmo-bts-octphy/l1_oml.c index a68169e..b4d519f 100644 --- a/src/osmo-bts-octphy/l1_oml.c +++ b/src/osmo-bts-octphy/l1_oml.c @@ -1380,6 +1380,11 @@ oc->RfConfig.ulTxAttndB = (trx->max_power_red) << 2; } +#if OCTPHY_USE_ANTENNA_ID == 1 + oc->RfConfig.ulTxAntennaId = plink->u.octphy.tx_ant_id; + oc->RfConfig.ulRxAntennaId = plink->u.octphy.rx_ant_id; +#endif + #if OCTPHY_MULTI_TRX == 1 LOGP(DL1C, LOGL_INFO, "Tx TRX-OPEN.req(trx=%u, rf_port=%u, arfcn=%u, " "center=%u, tsc=%u, rx_gain=%u, tx_atten=%u)\n", diff --git a/src/osmo-bts-octphy/octphy_vty.c b/src/osmo-bts-octphy/octphy_vty.c index 370aff6..fb36493 100644 --- a/src/osmo-bts-octphy/octphy_vty.c +++ b/src/osmo-bts-octphy/octphy_vty.c @@ -117,6 +117,42 @@ return CMD_SUCCESS; } +#if OCTPHY_USE_ANTENNA_ID == 1 +DEFUN(cfg_phy_rx_ant_id, cfg_phy_rx_ant_id_cmd, + "octphy rx-ant-id <0-1>", + OCT_STR "Configure the RX Antenna for this TRX\n" "RX Antenna Id\n") +{ + struct phy_link *plink = vty->index; + + if (plink->state != PHY_LINK_SHUTDOWN) { + vty_out(vty, "Can only reconfigure a PHY link that is down%s", + VTY_NEWLINE); + return CMD_WARNING; + } + + plink->u.octphy.rx_ant_id = atoi(argv[0]); + + return CMD_SUCCESS; +} + +DEFUN(cfg_phy_tx_ant_id, cfg_phy_tx_ant_id_cmd, + "octphy tx-ant-id <0-1>", + OCT_STR "Configure the TX Antenna for this TRX\n" "TX Antenna Id\n") +{ + struct phy_link *plink = vty->index; + + if (plink->state != PHY_LINK_SHUTDOWN) { + vty_out(vty, "Can only reconfigure a PHY link that is down%s", + VTY_NEWLINE); + return CMD_WARNING; + } + + plink->u.octphy.tx_ant_id = atoi(argv[0]); + + return CMD_SUCCESS; +} +#endif + DEFUN(cfg_phy_rx_gain_db, cfg_phy_rx_gain_db_cmd, "octphy rx-gain <0-73>", OCT_STR "Configure the Rx Gain in dB\n" @@ -300,6 +336,14 @@ vty_out(vty, " octphy rf-port-index %u%s", plink->u.octphy.rf_port_index, VTY_NEWLINE); + +#if OCTPHY_USE_ANTENNA_ID == 1 + vty_out(vty, " octphy tx-ant-id %u%s", plink->u.octphy.tx_ant_id, + VTY_NEWLINE); + + vty_out(vty, " octphy rx-ant-id %u%s", plink->u.octphy.rx_ant_id, + VTY_NEWLINE); +#endif } void bts_model_config_write_phy_inst(struct vty *vty, struct phy_instance *pinst) @@ -347,6 +391,10 @@ install_element(PHY_NODE, &cfg_phy_hwaddr_cmd); install_element(PHY_NODE, &cfg_phy_netdev_cmd); install_element(PHY_NODE, &cfg_phy_rf_port_idx_cmd); +#if OCTPHY_USE_ANTENNA_ID == 1 + install_element(PHY_NODE, &cfg_phy_rx_ant_id_cmd); + install_element(PHY_NODE, &cfg_phy_tx_ant_id_cmd); +#endif install_element(PHY_NODE, &cfg_phy_rx_gain_db_cmd); install_element(PHY_NODE, &cfg_phy_tx_atten_db_cmd); -- To view, visit https://gerrit.osmocom.org/1976 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I872fe3c4d7b593358a4ce2f02cf0726611b9f3aa Gerrit-PatchSet: 3 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Wed Apr 12 17:08:38 2017 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Wed, 12 Apr 2017 17:08:38 +0000 Subject: [PATCH] osmo-bts[master]: octphy: WIP: Bug in while auto-activating all SAPIs for the ... Message-ID: Review at https://gerrit.osmocom.org/2314 octphy: WIP: Bug in while auto-activating all SAPIs for the BCCH/CCCH on TS0 This change most likely introduces a bug. The if that detects for TS0 in order to activate the SAPIs for the BCCH/CCCH is changed to match on TS7. (mo->obj_inst.ts_nr == 7). So the activation definetly won't take place when mo is related to TS0. Probably this might be a hack, the SAPIs shall be activated later, so on TS7 (initalization is almost through then) the SAPIS get activated. I need more information on this. Change-Id: Ie307bf9f370a346686e3bd8c8a8483953a1bc279 --- M src/osmo-bts-octphy/l1_oml.c 1 file changed, 1 insertion(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/14/2314/1 diff --git a/src/osmo-bts-octphy/l1_oml.c b/src/osmo-bts-octphy/l1_oml.c index abbb36c..7e1ad88 100644 --- a/src/osmo-bts-octphy/l1_oml.c +++ b/src/osmo-bts-octphy/l1_oml.c @@ -187,7 +187,7 @@ /* hack to auto-activate all SAPIs for the BCCH/CCCH on TS0 */ if (mo->obj_class == NM_OC_CHANNEL && mo->obj_inst.trx_nr == 0 && - mo->obj_inst.ts_nr == 0) { + mo->obj_inst.ts_nr == 7) { struct gsm_lchan *cbch = gsm_bts_get_cbch(mo->bts); mo->bts->c0->ts[0].lchan[CCCH_LCHAN].rel_act_kind = LCHAN_REL_ACT_OML; -- To view, visit https://gerrit.osmocom.org/2314 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ie307bf9f370a346686e3bd8c8a8483953a1bc279 Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: dexter From admin at opensuse.org Wed Apr 12 20:06:28 2017 From: admin at opensuse.org (OBS Notification) Date: Wed, 12 Apr 2017 20:06:28 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in Debian_8.0/x86_64 In-Reply-To: References: Message-ID: <58ee88d8f0ff6_9961156f84507372@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/Debian_8.0/x86_64 Package network:osmocom:nightly/osmo-stp failed to build in Debian_8.0/x86_64 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 173s] ^ [ 173s] CC vty_interface.o [ 174s] CC sctp_m3ua_client.o [ 174s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 174s] #include [ 174s] ^ [ 174s] compilation terminated. [ 174s] Makefile:475: recipe for target 'sctp_m3ua_client.o' failed [ 174s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 174s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 174s] Makefile:370: recipe for target 'all-recursive' failed [ 174s] make[2]: *** [all-recursive] Error 1 [ 174s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 174s] Makefile:310: recipe for target 'all' failed [ 174s] make[1]: *** [all] Error 2 [ 174s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 174s] dh_auto_build: make -j1 returned exit code 2 [ 174s] debian/rules:23: recipe for target 'build' failed [ 174s] make: *** [build] Error 2 [ 174s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 174s] [ 174s] lamb52 failed "build cellmgr-ng_1.4.7.20170412.dsc" at Wed Apr 12 20:06:17 UTC 2017. [ 174s] [ 174s] ### VM INTERACTION START ### [ 175s] Powering off. [ 175s] ### VM INTERACTION END ### [ 175s] [ 175s] lamb52 failed "build cellmgr-ng_1.4.7.20170412.dsc" at Wed Apr 12 20:06:18 UTC 2017. [ 175s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Wed Apr 12 20:06:28 2017 From: admin at opensuse.org (OBS Notification) Date: Wed, 12 Apr 2017 20:06:28 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in xUbuntu_16.10/i586 In-Reply-To: References: Message-ID: <58ee88f5bc650_99c1156f84597011@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/xUbuntu_16.10/i586 Package network:osmocom:nightly/osmo-stp failed to build in xUbuntu_16.10/i586 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 91s] ^~~~~~~ [ 91s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o vty_interface.o vty_interface.c [ 92s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o sctp_m3ua_client.o sctp_m3ua_client.c [ 92s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 92s] #include [ 92s] ^ [ 92s] compilation terminated. [ 92s] Makefile:485: recipe for target 'sctp_m3ua_client.o' failed [ 92s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 92s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 92s] Makefile:380: recipe for target 'all-recursive' failed [ 92s] make[2]: *** [all-recursive] Error 1 [ 92s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 92s] Makefile:321: recipe for target 'all' failed [ 92s] make[1]: *** [all] Error 2 [ 92s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 92s] dh_auto_build: make -j1 returned exit code 2 [ 92s] debian/rules:23: recipe for target 'build' failed [ 92s] make: *** [build] Error 2 [ 92s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 92s] [ 92s] lamb09 failed "build cellmgr-ng_1.4.7.20170412.dsc" at Wed Apr 12 20:06:24 UTC 2017. [ 92s] [ 92s] ### VM INTERACTION START ### [ 95s] [ 82.688535] reboot: Power down [ 95s] ### VM INTERACTION END ### [ 95s] [ 95s] lamb09 failed "build cellmgr-ng_1.4.7.20170412.dsc" at Wed Apr 12 20:06:27 UTC 2017. [ 95s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Wed Apr 12 20:08:46 2017 From: admin at opensuse.org (OBS Notification) Date: Wed, 12 Apr 2017 20:08:46 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in Debian_8.0/i586 In-Reply-To: References: Message-ID: <58ee898ec9be1_c7610b4f7c475521@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/Debian_8.0/i586 Package network:osmocom:nightly/osmo-stp failed to build in Debian_8.0/i586 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 91s] CC vty_interface.o [ 91s] CC sctp_m3ua_client.o [ 91s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 91s] #include [ 91s] ^ [ 91s] compilation terminated. [ 91s] Makefile:475: recipe for target 'sctp_m3ua_client.o' failed [ 91s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 91s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 91s] Makefile:370: recipe for target 'all-recursive' failed [ 91s] make[2]: *** [all-recursive] Error 1 [ 91s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 91s] Makefile:310: recipe for target 'all' failed [ 91s] make[1]: *** [all] Error 2 [ 91s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 91s] dh_auto_build: make -j1 returned exit code 2 [ 91s] debian/rules:23: recipe for target 'build' failed [ 91s] make: *** [build] Error 2 [ 91s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 91s] [ 91s] lamb68 failed "build cellmgr-ng_1.4.7.20170412.dsc" at Wed Apr 12 20:08:30 UTC 2017. [ 91s] [ 91s] ### VM INTERACTION START ### [ 93s] Powering off. [ 93s] [ 79.328159] reboot: Power down [ 93s] ### VM INTERACTION END ### [ 93s] [ 93s] lamb68 failed "build cellmgr-ng_1.4.7.20170412.dsc" at Wed Apr 12 20:08:32 UTC 2017. [ 93s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Wed Apr 12 20:09:03 2017 From: admin at opensuse.org (OBS Notification) Date: Wed, 12 Apr 2017 20:09:03 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in xUbuntu_16.04/x86_64 In-Reply-To: References: Message-ID: <58ee898fe8201_c7610b4f7c4757f5@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/xUbuntu_16.04/x86_64 Package network:osmocom:nightly/osmo-stp failed to build in xUbuntu_16.04/x86_64 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 217s] sctp_m2ua.c:91:3: warning: #warning "Notify any other AS(P) for failover scenario" [-Wcpp] [ 217s] #warning "Notify any other AS(P) for failover scenario" [ 217s] ^ [ 217s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -c -o vty_interface.o vty_interface.c [ 218s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -c -o sctp_m3ua_client.o sctp_m3ua_client.c [ 218s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 218s] compilation terminated. [ 218s] Makefile:485: recipe for target 'sctp_m3ua_client.o' failed [ 218s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 218s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 218s] Makefile:380: recipe for target 'all-recursive' failed [ 218s] make[2]: *** [all-recursive] Error 1 [ 218s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 218s] Makefile:321: recipe for target 'all' failed [ 218s] make[1]: *** [all] Error 2 [ 218s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 218s] dh_auto_build: make -j1 returned exit code 2 [ 218s] debian/rules:23: recipe for target 'build' failed [ 218s] make: *** [build] Error 2 [ 218s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 218s] [ 218s] wildcard2 failed "build cellmgr-ng_1.4.7.20170412.dsc" at Wed Apr 12 20:08:12 UTC 2017. [ 218s] [ 218s] ### VM INTERACTION START ### [ 220s] [ 101.610097] reboot: Power down [ 259s] ### VM INTERACTION END ### [ 261s] [ 261s] wildcard2 failed "build cellmgr-ng_1.4.7.20170412.dsc" at Wed Apr 12 20:08:57 UTC 2017. [ 261s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Wed Apr 12 20:10:11 2017 From: admin at opensuse.org (OBS Notification) Date: Wed, 12 Apr 2017 20:10:11 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in xUbuntu_16.10/x86_64 In-Reply-To: References: Message-ID: <58ee89ac89b41_99c1156f8459767f@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/xUbuntu_16.10/x86_64 Package network:osmocom:nightly/osmo-stp failed to build in xUbuntu_16.10/x86_64 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 80s] ^~~~~~~ [ 80s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o vty_interface.o vty_interface.c [ 81s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o sctp_m3ua_client.o sctp_m3ua_client.c [ 81s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 81s] #include [ 81s] ^ [ 81s] compilation terminated. [ 81s] Makefile:485: recipe for target 'sctp_m3ua_client.o' failed [ 81s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 81s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 81s] Makefile:380: recipe for target 'all-recursive' failed [ 81s] make[2]: *** [all-recursive] Error 1 [ 81s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 81s] Makefile:321: recipe for target 'all' failed [ 81s] make[1]: *** [all] Error 2 [ 81s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 81s] dh_auto_build: make -j1 returned exit code 2 [ 81s] debian/rules:23: recipe for target 'build' failed [ 81s] make: *** [build] Error 2 [ 81s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 81s] [ 81s] lamb11 failed "build cellmgr-ng_1.4.7.20170412.dsc" at Wed Apr 12 20:09:57 UTC 2017. [ 81s] [ 81s] ### VM INTERACTION START ### [ 84s] [ 70.662119] reboot: Power down [ 84s] ### VM INTERACTION END ### [ 84s] [ 84s] lamb11 failed "build cellmgr-ng_1.4.7.20170412.dsc" at Wed Apr 12 20:10:00 UTC 2017. [ 84s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Wed Apr 12 20:11:20 2017 From: admin at opensuse.org (OBS Notification) Date: Wed, 12 Apr 2017 20:11:20 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in xUbuntu_16.04/i586 In-Reply-To: References: Message-ID: <58ee8a055de84_98f1156f8450753e@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/xUbuntu_16.04/i586 Package network:osmocom:nightly/osmo-stp failed to build in xUbuntu_16.04/i586 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 161s] sctp_m2ua.c: In function 'm2ua_conn_destroy': [ 161s] sctp_m2ua.c:91:3: warning: #warning "Notify any other AS(P) for failover scenario" [-Wcpp] [ 161s] #warning "Notify any other AS(P) for failover scenario" [ 161s] ^ [ 162s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -c -o vty_interface.o vty_interface.c [ 162s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -c -o sctp_m3ua_client.o sctp_m3ua_client.c [ 162s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 162s] compilation terminated. [ 162s] Makefile:485: recipe for target 'sctp_m3ua_client.o' failed [ 162s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 162s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 162s] Makefile:380: recipe for target 'all-recursive' failed [ 162s] make[2]: *** [all-recursive] Error 1 [ 162s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 162s] Makefile:321: recipe for target 'all' failed [ 162s] make[1]: *** [all] Error 2 [ 162s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 162s] dh_auto_build: make -j1 returned exit code 2 [ 162s] debian/rules:23: recipe for target 'build' failed [ 162s] make: *** [build] Error 2 [ 162s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 162s] [ 162s] cloud104 failed "build cellmgr-ng_1.4.7.20170412.dsc" at Wed Apr 12 20:10:59 UTC 2017. [ 162s] [ 162s] ### VM INTERACTION START ### [ 167s] ### VM INTERACTION END ### [ 167s] [ 167s] cloud104 failed "build cellmgr-ng_1.4.7.20170412.dsc" at Wed Apr 12 20:11:04 UTC 2017. [ 167s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From gerrit-no-reply at lists.osmocom.org Thu Apr 13 09:23:24 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Thu, 13 Apr 2017 09:23:24 +0000 Subject: [PATCH] openbsc[master]: Prepare for extended SI2quater support In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2312 to look at the new patch set (#4). Prepare for extended SI2quater support Supporting SI2quater support as per 3GPP TS 44.018 will require chnages to the way System Information is stored because it uses 1:n instead of 1:1 mapping between SI type and generated SI content. This should not affect other SI types though. To facilitate this transition: * convert the code to always use GSM_BTS_SI helper instead of accessing buffer directly * make helper more robust by adding extra parenthesis * add similar helper for gsm_lchan * internalize buffer access in generate_si* functions Change-Id: I74e4e3cb86364cec869a1472a41b4a95af0d50dd Related: RT#8792 --- M openbsc/include/openbsc/gsm_data_shared.h M openbsc/src/libbsc/bsc_vty.c M openbsc/src/libbsc/system_information.c M openbsc/tests/gsm0408/gsm0408_test.c 4 files changed, 41 insertions(+), 43 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/12/2312/4 diff --git a/openbsc/include/openbsc/gsm_data_shared.h b/openbsc/include/openbsc/gsm_data_shared.h index 242889a..d9d508b 100644 --- a/openbsc/include/openbsc/gsm_data_shared.h +++ b/openbsc/include/openbsc/gsm_data_shared.h @@ -483,7 +483,8 @@ struct gsm_bts_trx_ts ts[TRX_NR_TS]; }; -#define GSM_BTS_SI(bts, i) (void *)(bts->si_buf[i]) +#define GSM_BTS_SI(bts, i) (void *)((bts)->si_buf[i]) +#define GSM_LCHAN_SI(lchan, i) (void *)((lchan)->si.buf[i]) enum gsm_bts_type { GSM_BTS_TYPE_UNKNOWN, diff --git a/openbsc/src/libbsc/bsc_vty.c b/openbsc/src/libbsc/bsc_vty.c index c1882fc..a2f0264 100644 --- a/openbsc/src/libbsc/bsc_vty.c +++ b/openbsc/src/libbsc/bsc_vty.c @@ -644,7 +644,7 @@ get_value_string(osmo_sitype_strs, i), VTY_NEWLINE); vty_out(vty, " system-information %s static %s%s", get_value_string(osmo_sitype_strs, i), - osmo_hexdump_nospc(bts->si_buf[i], sizeof(bts->si_buf[i])), + osmo_hexdump_nospc(GSM_BTS_SI(bts, i), GSM_MACBLOCK_LEN), VTY_NEWLINE); } } @@ -2688,11 +2688,11 @@ } /* Fill buffer with padding pattern */ - memset(bts->si_buf[type], 0x2b, sizeof(bts->si_buf[type])); + memset(GSM_BTS_SI(bts, type), 0x2b, GSM_MACBLOCK_LEN); /* Parse the user-specified SI in hex format, [partially] overwriting padding */ - rc = osmo_hexparse(argv[1], bts->si_buf[type], sizeof(bts->si_buf[0])); - if (rc < 0 || rc > sizeof(bts->si_buf[0])) { + rc = osmo_hexparse(argv[1], GSM_BTS_SI(bts, type), GSM_MACBLOCK_LEN); + if (rc < 0 || rc > GSM_MACBLOCK_LEN) { vty_out(vty, "Error parsing HEXSTRING%s", VTY_NEWLINE); return CMD_WARNING; } diff --git a/openbsc/src/libbsc/system_information.c b/openbsc/src/libbsc/system_information.c index 2610331..6a34e61 100644 --- a/openbsc/src/libbsc/system_information.c +++ b/openbsc/src/libbsc/system_information.c @@ -557,11 +557,10 @@ return n; } -static int generate_si1(uint8_t *output, struct gsm_bts *bts) +static int generate_si1(enum osmo_sysinfo_type t, struct gsm_bts *bts) { int rc; - struct gsm48_system_information_type_1 *si1 = - (struct gsm48_system_information_type_1 *) output; + struct gsm48_system_information_type_1 *si1 = (struct gsm48_system_information_type_1 *) GSM_BTS_SI(bts, t); memset(si1, GSM_MACBLOCK_PADDING, GSM_MACBLOCK_LEN); @@ -586,11 +585,10 @@ return sizeof(*si1) + rc; } -static int generate_si2(uint8_t *output, struct gsm_bts *bts) +static int generate_si2(enum osmo_sysinfo_type t, struct gsm_bts *bts) { int rc; - struct gsm48_system_information_type_2 *si2 = - (struct gsm48_system_information_type_2 *) output; + struct gsm48_system_information_type_2 *si2 = (struct gsm48_system_information_type_2 *) GSM_BTS_SI(bts, t); memset(si2, GSM_MACBLOCK_PADDING, GSM_MACBLOCK_LEN); @@ -611,11 +609,11 @@ return sizeof(*si2); } -static int generate_si2bis(uint8_t *output, struct gsm_bts *bts) +static int generate_si2bis(enum osmo_sysinfo_type t, struct gsm_bts *bts) { int rc; struct gsm48_system_information_type_2bis *si2b = - (struct gsm48_system_information_type_2bis *) output; + (struct gsm48_system_information_type_2bis *) GSM_BTS_SI(bts, t); int n; memset(si2b, GSM_MACBLOCK_PADDING, GSM_MACBLOCK_LEN); @@ -633,8 +631,7 @@ if (n) { /* indicate in SI2 and SI2bis: there is an extension */ struct gsm48_system_information_type_2 *si2 = - (struct gsm48_system_information_type_2 *) - bts->si_buf[SYSINFO_TYPE_2]; + (struct gsm48_system_information_type_2 *) GSM_BTS_SI(bts, SYSINFO_TYPE_2); si2->bcch_frequency_list[0] |= 0x20; si2b->bcch_frequency_list[0] |= 0x20; } else @@ -645,11 +642,11 @@ return sizeof(*si2b); } -static int generate_si2ter(uint8_t *output, struct gsm_bts *bts) +static int generate_si2ter(enum osmo_sysinfo_type t, struct gsm_bts *bts) { int rc; struct gsm48_system_information_type_2ter *si2t = - (struct gsm48_system_information_type_2ter *) output; + (struct gsm48_system_information_type_2ter *) GSM_BTS_SI(bts, t); int n; memset(si2t, GSM_MACBLOCK_PADDING, GSM_MACBLOCK_LEN); @@ -670,11 +667,11 @@ return sizeof(*si2t); } -static int generate_si2quater(uint8_t *output, struct gsm_bts *bts) +static int generate_si2quater(enum osmo_sysinfo_type t, struct gsm_bts *bts) { int rc, i = MAX_EARFCN_LIST; struct gsm48_system_information_type_2quater *si2q = - (struct gsm48_system_information_type_2quater *) output; + (struct gsm48_system_information_type_2quater *) GSM_BTS_SI(bts, t); memset(si2q, GSM_MACBLOCK_PADDING, GSM_MACBLOCK_LEN); @@ -727,11 +724,10 @@ .break_ind = 0, }; -static int generate_si3(uint8_t *output, struct gsm_bts *bts) +static int generate_si3(enum osmo_sysinfo_type t, struct gsm_bts *bts) { int rc; - struct gsm48_system_information_type_3 *si3 = - (struct gsm48_system_information_type_3 *) output; + struct gsm48_system_information_type_3 *si3 = (struct gsm48_system_information_type_3 *) GSM_BTS_SI(bts, t); memset(si3, GSM_MACBLOCK_PADDING, GSM_MACBLOCK_LEN); @@ -775,11 +771,10 @@ return sizeof(*si3) + rc; } -static int generate_si4(uint8_t *output, struct gsm_bts *bts) +static int generate_si4(enum osmo_sysinfo_type t, struct gsm_bts *bts) { int rc; - struct gsm48_system_information_type_4 *si4 = - (struct gsm48_system_information_type_4 *) output; + struct gsm48_system_information_type_4 *si4 = (struct gsm48_system_information_type_4 *) GSM_BTS_SI(bts, t); struct gsm_lchan *cbch_lchan; uint8_t *restoct = si4->data; @@ -815,14 +810,15 @@ /* SI4 Rest Octets (10.5.2.35), containing Optional Power offset, GPRS Indicator, Cell Identity, LSA ID, Selection Parameter */ - rc = rest_octets_si4(restoct, &si_info, output + GSM_MACBLOCK_LEN - restoct); + rc = rest_octets_si4(restoct, &si_info, (uint8_t *)GSM_BTS_SI(bts, t) + GSM_MACBLOCK_LEN - restoct); return l2_plen + 1 + rc; } -static int generate_si5(uint8_t *output, struct gsm_bts *bts) +static int generate_si5(enum osmo_sysinfo_type t, struct gsm_bts *bts) { struct gsm48_system_information_type_5 *si5; + uint8_t *output = GSM_BTS_SI(bts, t); int rc, l2_plen = 18; memset(output, GSM_MACBLOCK_PADDING, GSM_MACBLOCK_LEN); @@ -838,7 +834,7 @@ break; } - si5 = (struct gsm48_system_information_type_5 *) output; + si5 = (struct gsm48_system_information_type_5 *) GSM_BTS_SI(bts, t); /* l2 pseudo length, not part of msg: 18 */ si5->rr_protocol_discriminator = GSM48_PDISC_RR; @@ -854,9 +850,10 @@ return l2_plen; } -static int generate_si5bis(uint8_t *output, struct gsm_bts *bts) +static int generate_si5bis(enum osmo_sysinfo_type t, struct gsm_bts *bts) { struct gsm48_system_information_type_5bis *si5b; + uint8_t *output = GSM_BTS_SI(bts, t); int rc, l2_plen = 18; int n; @@ -873,7 +870,7 @@ break; } - si5b = (struct gsm48_system_information_type_5bis *) output; + si5b = (struct gsm48_system_information_type_5bis *) GSM_BTS_SI(bts, t); /* l2 pseudo length, not part of msg: 18 */ si5b->rr_protocol_discriminator = GSM48_PDISC_RR; @@ -887,8 +884,7 @@ if (n) { /* indicate in SI5 and SI5bis: there is an extension */ struct gsm48_system_information_type_5 *si5 = - (struct gsm48_system_information_type_5 *) - bts->si_buf[SYSINFO_TYPE_5]; + (struct gsm48_system_information_type_5 *) GSM_BTS_SI(bts, SYSINFO_TYPE_5); si5->bcch_frequency_list[0] |= 0x20; si5b->bcch_frequency_list[0] |= 0x20; } else @@ -898,9 +894,10 @@ return l2_plen; } -static int generate_si5ter(uint8_t *output, struct gsm_bts *bts) +static int generate_si5ter(enum osmo_sysinfo_type t, struct gsm_bts *bts) { struct gsm48_system_information_type_5ter *si5t; + uint8_t *output = GSM_BTS_SI(bts, t); int rc, l2_plen = 18; int n; @@ -917,7 +914,7 @@ break; } - si5t = (struct gsm48_system_information_type_5ter *) output; + si5t = (struct gsm48_system_information_type_5ter *) GSM_BTS_SI(bts, t); /* l2 pseudo length, not part of msg: 18 */ si5t->rr_protocol_discriminator = GSM48_PDISC_RR; @@ -935,9 +932,10 @@ return l2_plen; } -static int generate_si6(uint8_t *output, struct gsm_bts *bts) +static int generate_si6(enum osmo_sysinfo_type t, struct gsm_bts *bts) { struct gsm48_system_information_type_6 *si6; + uint8_t *output = GSM_BTS_SI(bts, t); int l2_plen = 11; int rc; @@ -954,7 +952,7 @@ break; } - si6 = (struct gsm48_system_information_type_6 *) output; + si6 = (struct gsm48_system_information_type_6 *) GSM_BTS_SI(bts, t); /* l2 pseudo length, not part of msg: 11 */ si6->rr_protocol_discriminator = GSM48_PDISC_RR; @@ -1015,10 +1013,10 @@ }, }; -static int generate_si13(uint8_t *output, struct gsm_bts *bts) +static int generate_si13(enum osmo_sysinfo_type t, struct gsm_bts *bts) { struct gsm48_system_information_type_13 *si13 = - (struct gsm48_system_information_type_13 *) output; + (struct gsm48_system_information_type_13 *) GSM_BTS_SI(bts, t); int ret; memset(si13, GSM_MACBLOCK_PADDING, GSM_MACBLOCK_LEN); @@ -1048,7 +1046,7 @@ return sizeof (*si13) + ret; } -typedef int (*gen_si_fn_t)(uint8_t *output, struct gsm_bts *bts); +typedef int (*gen_si_fn_t)(enum osmo_sysinfo_type t, struct gsm_bts *bts); static const gen_si_fn_t gen_si_fn[_MAX_SYSINFO_TYPE] = { [SYSINFO_TYPE_1] = &generate_si1, @@ -1090,5 +1088,5 @@ if (!gen_si) return -EINVAL; - return gen_si(bts->si_buf[si_type], bts); + return gen_si(si_type, bts); } diff --git a/openbsc/tests/gsm0408/gsm0408_test.c b/openbsc/tests/gsm0408/gsm0408_test.c index 08cf43f..81dc177 100644 --- a/openbsc/tests/gsm0408/gsm0408_test.c +++ b/openbsc/tests/gsm0408/gsm0408_test.c @@ -99,13 +99,12 @@ bts->si_valid = 0; bts->si_valid |= (1 << SYSINFO_TYPE_2quater); /* should be no-op as entire buffer is filled with padding: */ - memset(bts->si_buf[SYSINFO_TYPE_2quater], 0xAE, GSM_MACBLOCK_LEN); + memset(GSM_BTS_SI(bts, SYSINFO_TYPE_2quater), 0xAE, GSM_MACBLOCK_LEN); int r = gsm_generate_si(bts, SYSINFO_TYPE_2quater); bool v = bts->si_valid & (1 << SYSINFO_TYPE_2quater); if (r > 0) printf("generated %s SI2quater: [%d] %s\n", - v ? "valid" : "invalid", r, - osmo_hexdump(bts->si_buf[SYSINFO_TYPE_2quater], r)); + v ? "valid" : "invalid", r, osmo_hexdump(GSM_BTS_SI(bts, SYSINFO_TYPE_2quater), r)); else printf("failed to generate SI2quater: %s\n", strerror(-r)); } -- To view, visit https://gerrit.osmocom.org/2312 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I74e4e3cb86364cec869a1472a41b4a95af0d50dd Gerrit-PatchSet: 4 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Thu Apr 13 10:44:40 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Thu, 13 Apr 2017 10:44:40 +0000 Subject: [PATCH] openbsc[master]: Prepare for extended SI2quater support In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2312 to look at the new patch set (#5). Prepare for extended SI2quater support Supporting SI2quater support as per 3GPP TS 44.018 will require chnages to the way System Information is stored because it uses 1:n instead of 1:1 mapping between SI type and generated SI content. This should not affect other SI types though. To facilitate this transition: * convert the code to always use GSM_BTS_SI helper instead of accessing buffer directly * make helper more robust by adding extra parenthesis * add similar helper for gsm_lchan * add function estimating number of SI2quater message to hold configured number of (U|E)ARFCNs * internalize buffer access in generate_si* functions Change-Id: I74e4e3cb86364cec869a1472a41b4a95af0d50dd Related: RT#8792 --- M openbsc/include/openbsc/gsm_data_shared.h M openbsc/include/openbsc/system_information.h M openbsc/src/libbsc/bsc_vty.c M openbsc/src/libbsc/system_information.c M openbsc/tests/gsm0408/gsm0408_test.c 5 files changed, 49 insertions(+), 56 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/12/2312/5 diff --git a/openbsc/include/openbsc/gsm_data_shared.h b/openbsc/include/openbsc/gsm_data_shared.h index 242889a..d9d508b 100644 --- a/openbsc/include/openbsc/gsm_data_shared.h +++ b/openbsc/include/openbsc/gsm_data_shared.h @@ -483,7 +483,8 @@ struct gsm_bts_trx_ts ts[TRX_NR_TS]; }; -#define GSM_BTS_SI(bts, i) (void *)(bts->si_buf[i]) +#define GSM_BTS_SI(bts, i) (void *)((bts)->si_buf[i]) +#define GSM_LCHAN_SI(lchan, i) (void *)((lchan)->si.buf[i]) enum gsm_bts_type { GSM_BTS_TYPE_UNKNOWN, diff --git a/openbsc/include/openbsc/system_information.h b/openbsc/include/openbsc/system_information.h index 1b19c8b..b012107 100644 --- a/openbsc/include/openbsc/system_information.h +++ b/openbsc/include/openbsc/system_information.h @@ -14,7 +14,7 @@ unsigned range512_q(unsigned m); int range_encode(enum gsm48_range r, int *arfcns, int arfcns_used, int *w, int f0, uint8_t *chan_list); -bool si2q_size_check(const struct gsm_bts *bts); +uint8_t si2q_num(const struct gsm_bts *bts); int bts_uarfcn_del(struct gsm_bts *bts, uint16_t arfcn, uint16_t scramble); int bts_uarfcn_add(struct gsm_bts *bts, uint16_t arfcn, uint16_t scramble, bool diversity); diff --git a/openbsc/src/libbsc/bsc_vty.c b/openbsc/src/libbsc/bsc_vty.c index c1882fc..657dfe3 100644 --- a/openbsc/src/libbsc/bsc_vty.c +++ b/openbsc/src/libbsc/bsc_vty.c @@ -644,7 +644,7 @@ get_value_string(osmo_sitype_strs, i), VTY_NEWLINE); vty_out(vty, " system-information %s static %s%s", get_value_string(osmo_sitype_strs, i), - osmo_hexdump_nospc(bts->si_buf[i], sizeof(bts->si_buf[i])), + osmo_hexdump_nospc(GSM_BTS_SI(bts, i), GSM_MACBLOCK_LEN), VTY_NEWLINE); } } @@ -2688,11 +2688,11 @@ } /* Fill buffer with padding pattern */ - memset(bts->si_buf[type], 0x2b, sizeof(bts->si_buf[type])); + memset(GSM_BTS_SI(bts, type), 0x2b, GSM_MACBLOCK_LEN); /* Parse the user-specified SI in hex format, [partially] overwriting padding */ - rc = osmo_hexparse(argv[1], bts->si_buf[type], sizeof(bts->si_buf[0])); - if (rc < 0 || rc > sizeof(bts->si_buf[0])) { + rc = osmo_hexparse(argv[1], GSM_BTS_SI(bts, type), GSM_MACBLOCK_LEN); + if (rc < 0 || rc > GSM_MACBLOCK_LEN) { vty_out(vty, "Error parsing HEXSTRING%s", VTY_NEWLINE); return CMD_WARNING; } @@ -2830,7 +2830,7 @@ e->prio_valid = true; } - if (si2q_size_check(bts)) + if (si2q_num(bts) < 2) return CMD_SUCCESS; vty_out(vty, "Warning: not enough space in SI2quater for a given EARFCN " diff --git a/openbsc/src/libbsc/system_information.c b/openbsc/src/libbsc/system_information.c index 2610331..c332f0f 100644 --- a/openbsc/src/libbsc/system_information.c +++ b/openbsc/src/libbsc/system_information.c @@ -149,18 +149,13 @@ return s + r + append + range1024_p(k); } -bool si2q_size_check(const struct gsm_bts *bts) +uint8_t si2q_num(const struct gsm_bts *bts) { - const struct osmo_earfcn_si2q *e = &bts->si_common.si2quater_neigh_list; - const uint16_t *u = bts->si_common.data.uarfcn_list, - *sc = bts->si_common.data.scramble_list; - size_t len = bts->si_common.uarfcn_length; - unsigned e_sz = e ? earfcn_size(e) : 1, - u_sz = len ? uarfcn_size(u, sc, len) : 1; + const struct osmo_earfcn_si2q *e = &bts->si_common.si2quater_neigh_list; /* EARFCN */ + const uint16_t *u = bts->si_common.data.uarfcn_list, *sc = bts->si_common.data.scramble_list; /* UARFCN */ + size_t l = bts->si_common.uarfcn_length, e_sz = e ? earfcn_size(e) : 1, u_sz = l ? uarfcn_size(u, sc, l) : 1; /* 2 bits are used in between UARFCN and EARFCN structs */ - if (SI2Q_MIN_LEN + u_sz + 2 + e_sz > SI2Q_MAX_LEN) - return false; - return true; + return 1 + (e_sz + u_sz) / (SI2Q_MAX_LEN - (SI2Q_MIN_LEN + 2)); } /* 3GPP TS 44.018, Table 9.1.54.1 - prepend diversity bit to scrambling code */ @@ -233,7 +228,7 @@ scl[k] = scr; bts->si_common.uarfcn_length++; - if (si2q_size_check(bts)) + if (si2q_num(bts) < 2) return 0; bts_uarfcn_del(bts, arfcn, scramble); @@ -557,11 +552,10 @@ return n; } -static int generate_si1(uint8_t *output, struct gsm_bts *bts) +static int generate_si1(enum osmo_sysinfo_type t, struct gsm_bts *bts) { int rc; - struct gsm48_system_information_type_1 *si1 = - (struct gsm48_system_information_type_1 *) output; + struct gsm48_system_information_type_1 *si1 = (struct gsm48_system_information_type_1 *) GSM_BTS_SI(bts, t); memset(si1, GSM_MACBLOCK_PADDING, GSM_MACBLOCK_LEN); @@ -586,11 +580,10 @@ return sizeof(*si1) + rc; } -static int generate_si2(uint8_t *output, struct gsm_bts *bts) +static int generate_si2(enum osmo_sysinfo_type t, struct gsm_bts *bts) { int rc; - struct gsm48_system_information_type_2 *si2 = - (struct gsm48_system_information_type_2 *) output; + struct gsm48_system_information_type_2 *si2 = (struct gsm48_system_information_type_2 *) GSM_BTS_SI(bts, t); memset(si2, GSM_MACBLOCK_PADDING, GSM_MACBLOCK_LEN); @@ -611,11 +604,11 @@ return sizeof(*si2); } -static int generate_si2bis(uint8_t *output, struct gsm_bts *bts) +static int generate_si2bis(enum osmo_sysinfo_type t, struct gsm_bts *bts) { int rc; struct gsm48_system_information_type_2bis *si2b = - (struct gsm48_system_information_type_2bis *) output; + (struct gsm48_system_information_type_2bis *) GSM_BTS_SI(bts, t); int n; memset(si2b, GSM_MACBLOCK_PADDING, GSM_MACBLOCK_LEN); @@ -633,8 +626,7 @@ if (n) { /* indicate in SI2 and SI2bis: there is an extension */ struct gsm48_system_information_type_2 *si2 = - (struct gsm48_system_information_type_2 *) - bts->si_buf[SYSINFO_TYPE_2]; + (struct gsm48_system_information_type_2 *) GSM_BTS_SI(bts, SYSINFO_TYPE_2); si2->bcch_frequency_list[0] |= 0x20; si2b->bcch_frequency_list[0] |= 0x20; } else @@ -645,11 +637,11 @@ return sizeof(*si2b); } -static int generate_si2ter(uint8_t *output, struct gsm_bts *bts) +static int generate_si2ter(enum osmo_sysinfo_type t, struct gsm_bts *bts) { int rc; struct gsm48_system_information_type_2ter *si2t = - (struct gsm48_system_information_type_2ter *) output; + (struct gsm48_system_information_type_2ter *) GSM_BTS_SI(bts, t); int n; memset(si2t, GSM_MACBLOCK_PADDING, GSM_MACBLOCK_LEN); @@ -670,11 +662,11 @@ return sizeof(*si2t); } -static int generate_si2quater(uint8_t *output, struct gsm_bts *bts) +static int generate_si2quater(enum osmo_sysinfo_type t, struct gsm_bts *bts) { int rc, i = MAX_EARFCN_LIST; struct gsm48_system_information_type_2quater *si2q = - (struct gsm48_system_information_type_2quater *) output; + (struct gsm48_system_information_type_2quater *) GSM_BTS_SI(bts, t); memset(si2q, GSM_MACBLOCK_PADDING, GSM_MACBLOCK_LEN); @@ -727,11 +719,10 @@ .break_ind = 0, }; -static int generate_si3(uint8_t *output, struct gsm_bts *bts) +static int generate_si3(enum osmo_sysinfo_type t, struct gsm_bts *bts) { int rc; - struct gsm48_system_information_type_3 *si3 = - (struct gsm48_system_information_type_3 *) output; + struct gsm48_system_information_type_3 *si3 = (struct gsm48_system_information_type_3 *) GSM_BTS_SI(bts, t); memset(si3, GSM_MACBLOCK_PADDING, GSM_MACBLOCK_LEN); @@ -775,11 +766,10 @@ return sizeof(*si3) + rc; } -static int generate_si4(uint8_t *output, struct gsm_bts *bts) +static int generate_si4(enum osmo_sysinfo_type t, struct gsm_bts *bts) { int rc; - struct gsm48_system_information_type_4 *si4 = - (struct gsm48_system_information_type_4 *) output; + struct gsm48_system_information_type_4 *si4 = (struct gsm48_system_information_type_4 *) GSM_BTS_SI(bts, t); struct gsm_lchan *cbch_lchan; uint8_t *restoct = si4->data; @@ -815,14 +805,15 @@ /* SI4 Rest Octets (10.5.2.35), containing Optional Power offset, GPRS Indicator, Cell Identity, LSA ID, Selection Parameter */ - rc = rest_octets_si4(restoct, &si_info, output + GSM_MACBLOCK_LEN - restoct); + rc = rest_octets_si4(restoct, &si_info, (uint8_t *)GSM_BTS_SI(bts, t) + GSM_MACBLOCK_LEN - restoct); return l2_plen + 1 + rc; } -static int generate_si5(uint8_t *output, struct gsm_bts *bts) +static int generate_si5(enum osmo_sysinfo_type t, struct gsm_bts *bts) { struct gsm48_system_information_type_5 *si5; + uint8_t *output = GSM_BTS_SI(bts, t); int rc, l2_plen = 18; memset(output, GSM_MACBLOCK_PADDING, GSM_MACBLOCK_LEN); @@ -838,7 +829,7 @@ break; } - si5 = (struct gsm48_system_information_type_5 *) output; + si5 = (struct gsm48_system_information_type_5 *) GSM_BTS_SI(bts, t); /* l2 pseudo length, not part of msg: 18 */ si5->rr_protocol_discriminator = GSM48_PDISC_RR; @@ -854,9 +845,10 @@ return l2_plen; } -static int generate_si5bis(uint8_t *output, struct gsm_bts *bts) +static int generate_si5bis(enum osmo_sysinfo_type t, struct gsm_bts *bts) { struct gsm48_system_information_type_5bis *si5b; + uint8_t *output = GSM_BTS_SI(bts, t); int rc, l2_plen = 18; int n; @@ -873,7 +865,7 @@ break; } - si5b = (struct gsm48_system_information_type_5bis *) output; + si5b = (struct gsm48_system_information_type_5bis *) GSM_BTS_SI(bts, t); /* l2 pseudo length, not part of msg: 18 */ si5b->rr_protocol_discriminator = GSM48_PDISC_RR; @@ -887,8 +879,7 @@ if (n) { /* indicate in SI5 and SI5bis: there is an extension */ struct gsm48_system_information_type_5 *si5 = - (struct gsm48_system_information_type_5 *) - bts->si_buf[SYSINFO_TYPE_5]; + (struct gsm48_system_information_type_5 *) GSM_BTS_SI(bts, SYSINFO_TYPE_5); si5->bcch_frequency_list[0] |= 0x20; si5b->bcch_frequency_list[0] |= 0x20; } else @@ -898,9 +889,10 @@ return l2_plen; } -static int generate_si5ter(uint8_t *output, struct gsm_bts *bts) +static int generate_si5ter(enum osmo_sysinfo_type t, struct gsm_bts *bts) { struct gsm48_system_information_type_5ter *si5t; + uint8_t *output = GSM_BTS_SI(bts, t); int rc, l2_plen = 18; int n; @@ -917,7 +909,7 @@ break; } - si5t = (struct gsm48_system_information_type_5ter *) output; + si5t = (struct gsm48_system_information_type_5ter *) GSM_BTS_SI(bts, t); /* l2 pseudo length, not part of msg: 18 */ si5t->rr_protocol_discriminator = GSM48_PDISC_RR; @@ -935,9 +927,10 @@ return l2_plen; } -static int generate_si6(uint8_t *output, struct gsm_bts *bts) +static int generate_si6(enum osmo_sysinfo_type t, struct gsm_bts *bts) { struct gsm48_system_information_type_6 *si6; + uint8_t *output = GSM_BTS_SI(bts, t); int l2_plen = 11; int rc; @@ -954,7 +947,7 @@ break; } - si6 = (struct gsm48_system_information_type_6 *) output; + si6 = (struct gsm48_system_information_type_6 *) GSM_BTS_SI(bts, t); /* l2 pseudo length, not part of msg: 11 */ si6->rr_protocol_discriminator = GSM48_PDISC_RR; @@ -1015,10 +1008,10 @@ }, }; -static int generate_si13(uint8_t *output, struct gsm_bts *bts) +static int generate_si13(enum osmo_sysinfo_type t, struct gsm_bts *bts) { struct gsm48_system_information_type_13 *si13 = - (struct gsm48_system_information_type_13 *) output; + (struct gsm48_system_information_type_13 *) GSM_BTS_SI(bts, t); int ret; memset(si13, GSM_MACBLOCK_PADDING, GSM_MACBLOCK_LEN); @@ -1048,7 +1041,7 @@ return sizeof (*si13) + ret; } -typedef int (*gen_si_fn_t)(uint8_t *output, struct gsm_bts *bts); +typedef int (*gen_si_fn_t)(enum osmo_sysinfo_type t, struct gsm_bts *bts); static const gen_si_fn_t gen_si_fn[_MAX_SYSINFO_TYPE] = { [SYSINFO_TYPE_1] = &generate_si1, @@ -1090,5 +1083,5 @@ if (!gen_si) return -EINVAL; - return gen_si(bts->si_buf[si_type], bts); + return gen_si(si_type, bts); } diff --git a/openbsc/tests/gsm0408/gsm0408_test.c b/openbsc/tests/gsm0408/gsm0408_test.c index 08cf43f..81dc177 100644 --- a/openbsc/tests/gsm0408/gsm0408_test.c +++ b/openbsc/tests/gsm0408/gsm0408_test.c @@ -99,13 +99,12 @@ bts->si_valid = 0; bts->si_valid |= (1 << SYSINFO_TYPE_2quater); /* should be no-op as entire buffer is filled with padding: */ - memset(bts->si_buf[SYSINFO_TYPE_2quater], 0xAE, GSM_MACBLOCK_LEN); + memset(GSM_BTS_SI(bts, SYSINFO_TYPE_2quater), 0xAE, GSM_MACBLOCK_LEN); int r = gsm_generate_si(bts, SYSINFO_TYPE_2quater); bool v = bts->si_valid & (1 << SYSINFO_TYPE_2quater); if (r > 0) printf("generated %s SI2quater: [%d] %s\n", - v ? "valid" : "invalid", r, - osmo_hexdump(bts->si_buf[SYSINFO_TYPE_2quater], r)); + v ? "valid" : "invalid", r, osmo_hexdump(GSM_BTS_SI(bts, SYSINFO_TYPE_2quater), r)); else printf("failed to generate SI2quater: %s\n", strerror(-r)); } -- To view, visit https://gerrit.osmocom.org/2312 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I74e4e3cb86364cec869a1472a41b4a95af0d50dd Gerrit-PatchSet: 5 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Thu Apr 13 12:26:03 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Thu, 13 Apr 2017 12:26:03 +0000 Subject: [PATCH] openbsc[master]: Prepare for extended SI2quater support In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2312 to look at the new patch set (#6). Prepare for extended SI2quater support Supporting SI2quater support as per 3GPP TS 44.018 will require chnages to the way System Information is stored because it uses 1:n instead of 1:1 mapping between SI type and generated SI content. This should not affect other SI types though. To facilitate this transition: * convert the code to always use GSM_BTS_SI helper instead of accessing buffer directly * make helper more robust by adding extra parenthesis * add similar helper for gsm_lchan * add function estimating number of SI2quater message to hold configured number of (U|E)ARFCNs * add SI2q index/count fields and pass them to rest_octets generator explicitly * internalize buffer access in generate_si* functions Change-Id: I74e4e3cb86364cec869a1472a41b4a95af0d50dd Related: RT#8792 --- M openbsc/include/openbsc/gsm_data_shared.h M openbsc/include/openbsc/rest_octets.h M openbsc/include/openbsc/system_information.h M openbsc/src/libbsc/bsc_vty.c M openbsc/src/libbsc/rest_octets.c M openbsc/src/libbsc/system_information.c M openbsc/tests/gsm0408/gsm0408_test.c 7 files changed, 57 insertions(+), 61 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/12/2312/6 diff --git a/openbsc/include/openbsc/gsm_data_shared.h b/openbsc/include/openbsc/gsm_data_shared.h index 242889a..166de16 100644 --- a/openbsc/include/openbsc/gsm_data_shared.h +++ b/openbsc/include/openbsc/gsm_data_shared.h @@ -483,7 +483,8 @@ struct gsm_bts_trx_ts ts[TRX_NR_TS]; }; -#define GSM_BTS_SI(bts, i) (void *)(bts->si_buf[i]) +#define GSM_BTS_SI(bts, i) (void *)((bts)->si_buf[i]) +#define GSM_LCHAN_SI(lchan, i) (void *)((lchan)->si.buf[i]) enum gsm_bts_type { GSM_BTS_TYPE_UNKNOWN, @@ -702,6 +703,9 @@ /* bitmask of all SI that are present/valid in si_buf */ uint32_t si_valid; + /* 3GPP TS 44.018 Table 10.5.2.33b.1 INDEX and COUNT for SI2quater */ + uint8_t si2q_index; + uint8_t si2q_count; /* buffers where we put the pre-computed SI */ sysinfo_buf_t si_buf[_MAX_SYSINFO_TYPE]; diff --git a/openbsc/include/openbsc/rest_octets.h b/openbsc/include/openbsc/rest_octets.h index 3b4e598..6da58ea 100644 --- a/openbsc/include/openbsc/rest_octets.h +++ b/openbsc/include/openbsc/rest_octets.h @@ -10,7 +10,7 @@ /* generate SI1 rest octets */ int rest_octets_si1(uint8_t *data, uint8_t *nch_pos, int is1800_net); -int rest_octets_si2quater(uint8_t *data, const struct osmo_earfcn_si2q *e, +int rest_octets_si2quater(uint8_t *data, uint8_t index, uint8_t count, const struct osmo_earfcn_si2q *e, const uint16_t *u, const uint16_t *sc, size_t u_len); int rest_octets_si6(uint8_t *data, bool is1800_net); diff --git a/openbsc/include/openbsc/system_information.h b/openbsc/include/openbsc/system_information.h index 1b19c8b..b012107 100644 --- a/openbsc/include/openbsc/system_information.h +++ b/openbsc/include/openbsc/system_information.h @@ -14,7 +14,7 @@ unsigned range512_q(unsigned m); int range_encode(enum gsm48_range r, int *arfcns, int arfcns_used, int *w, int f0, uint8_t *chan_list); -bool si2q_size_check(const struct gsm_bts *bts); +uint8_t si2q_num(const struct gsm_bts *bts); int bts_uarfcn_del(struct gsm_bts *bts, uint16_t arfcn, uint16_t scramble); int bts_uarfcn_add(struct gsm_bts *bts, uint16_t arfcn, uint16_t scramble, bool diversity); diff --git a/openbsc/src/libbsc/bsc_vty.c b/openbsc/src/libbsc/bsc_vty.c index c1882fc..657dfe3 100644 --- a/openbsc/src/libbsc/bsc_vty.c +++ b/openbsc/src/libbsc/bsc_vty.c @@ -644,7 +644,7 @@ get_value_string(osmo_sitype_strs, i), VTY_NEWLINE); vty_out(vty, " system-information %s static %s%s", get_value_string(osmo_sitype_strs, i), - osmo_hexdump_nospc(bts->si_buf[i], sizeof(bts->si_buf[i])), + osmo_hexdump_nospc(GSM_BTS_SI(bts, i), GSM_MACBLOCK_LEN), VTY_NEWLINE); } } @@ -2688,11 +2688,11 @@ } /* Fill buffer with padding pattern */ - memset(bts->si_buf[type], 0x2b, sizeof(bts->si_buf[type])); + memset(GSM_BTS_SI(bts, type), 0x2b, GSM_MACBLOCK_LEN); /* Parse the user-specified SI in hex format, [partially] overwriting padding */ - rc = osmo_hexparse(argv[1], bts->si_buf[type], sizeof(bts->si_buf[0])); - if (rc < 0 || rc > sizeof(bts->si_buf[0])) { + rc = osmo_hexparse(argv[1], GSM_BTS_SI(bts, type), GSM_MACBLOCK_LEN); + if (rc < 0 || rc > GSM_MACBLOCK_LEN) { vty_out(vty, "Error parsing HEXSTRING%s", VTY_NEWLINE); return CMD_WARNING; } @@ -2830,7 +2830,7 @@ e->prio_valid = true; } - if (si2q_size_check(bts)) + if (si2q_num(bts) < 2) return CMD_SUCCESS; vty_out(vty, "Warning: not enough space in SI2quater for a given EARFCN " diff --git a/openbsc/src/libbsc/rest_octets.c b/openbsc/src/libbsc/rest_octets.c index ed6c573..af660f1 100644 --- a/openbsc/src/libbsc/rest_octets.c +++ b/openbsc/src/libbsc/rest_octets.c @@ -256,7 +256,7 @@ } /* generate SI2quater rest octets: 3GPP TS 44.018 ? 10.5.2.33b */ -int rest_octets_si2quater(uint8_t *data, const struct osmo_earfcn_si2q *e, +int rest_octets_si2quater(uint8_t *data, uint8_t index, uint8_t count, const struct osmo_earfcn_si2q *e, const uint16_t *u, const uint16_t *sc, size_t u_len) { int rc; @@ -275,9 +275,9 @@ /* we do not support multiple si2quater messages at the moment: */ /* SI2quater_INDEX */ - bitvec_set_uint(&bv, 0, 4); + bitvec_set_uint(&bv, index, 4); /* SI2quater_COUNT */ - bitvec_set_uint(&bv, 0, 4); + bitvec_set_uint(&bv, count, 4); /* No Measurement_Parameters Description */ bitvec_set_bit(&bv, 0); diff --git a/openbsc/src/libbsc/system_information.c b/openbsc/src/libbsc/system_information.c index 2610331..37395f0 100644 --- a/openbsc/src/libbsc/system_information.c +++ b/openbsc/src/libbsc/system_information.c @@ -149,18 +149,13 @@ return s + r + append + range1024_p(k); } -bool si2q_size_check(const struct gsm_bts *bts) +uint8_t si2q_num(const struct gsm_bts *bts) { - const struct osmo_earfcn_si2q *e = &bts->si_common.si2quater_neigh_list; - const uint16_t *u = bts->si_common.data.uarfcn_list, - *sc = bts->si_common.data.scramble_list; - size_t len = bts->si_common.uarfcn_length; - unsigned e_sz = e ? earfcn_size(e) : 1, - u_sz = len ? uarfcn_size(u, sc, len) : 1; + const struct osmo_earfcn_si2q *e = &bts->si_common.si2quater_neigh_list; /* EARFCN */ + const uint16_t *u = bts->si_common.data.uarfcn_list, *sc = bts->si_common.data.scramble_list; /* UARFCN */ + size_t l = bts->si_common.uarfcn_length, e_sz = e ? earfcn_size(e) : 1, u_sz = l ? uarfcn_size(u, sc, l) : 1; /* 2 bits are used in between UARFCN and EARFCN structs */ - if (SI2Q_MIN_LEN + u_sz + 2 + e_sz > SI2Q_MAX_LEN) - return false; - return true; + return 1 + (e_sz + u_sz) / (SI2Q_MAX_LEN - (SI2Q_MIN_LEN + 2)); } /* 3GPP TS 44.018, Table 9.1.54.1 - prepend diversity bit to scrambling code */ @@ -233,7 +228,7 @@ scl[k] = scr; bts->si_common.uarfcn_length++; - if (si2q_size_check(bts)) + if (si2q_num(bts) < 2) return 0; bts_uarfcn_del(bts, arfcn, scramble); @@ -557,11 +552,10 @@ return n; } -static int generate_si1(uint8_t *output, struct gsm_bts *bts) +static int generate_si1(enum osmo_sysinfo_type t, struct gsm_bts *bts) { int rc; - struct gsm48_system_information_type_1 *si1 = - (struct gsm48_system_information_type_1 *) output; + struct gsm48_system_information_type_1 *si1 = (struct gsm48_system_information_type_1 *) GSM_BTS_SI(bts, t); memset(si1, GSM_MACBLOCK_PADDING, GSM_MACBLOCK_LEN); @@ -586,11 +580,10 @@ return sizeof(*si1) + rc; } -static int generate_si2(uint8_t *output, struct gsm_bts *bts) +static int generate_si2(enum osmo_sysinfo_type t, struct gsm_bts *bts) { int rc; - struct gsm48_system_information_type_2 *si2 = - (struct gsm48_system_information_type_2 *) output; + struct gsm48_system_information_type_2 *si2 = (struct gsm48_system_information_type_2 *) GSM_BTS_SI(bts, t); memset(si2, GSM_MACBLOCK_PADDING, GSM_MACBLOCK_LEN); @@ -611,11 +604,11 @@ return sizeof(*si2); } -static int generate_si2bis(uint8_t *output, struct gsm_bts *bts) +static int generate_si2bis(enum osmo_sysinfo_type t, struct gsm_bts *bts) { int rc; struct gsm48_system_information_type_2bis *si2b = - (struct gsm48_system_information_type_2bis *) output; + (struct gsm48_system_information_type_2bis *) GSM_BTS_SI(bts, t); int n; memset(si2b, GSM_MACBLOCK_PADDING, GSM_MACBLOCK_LEN); @@ -633,8 +626,7 @@ if (n) { /* indicate in SI2 and SI2bis: there is an extension */ struct gsm48_system_information_type_2 *si2 = - (struct gsm48_system_information_type_2 *) - bts->si_buf[SYSINFO_TYPE_2]; + (struct gsm48_system_information_type_2 *) GSM_BTS_SI(bts, SYSINFO_TYPE_2); si2->bcch_frequency_list[0] |= 0x20; si2b->bcch_frequency_list[0] |= 0x20; } else @@ -645,11 +637,11 @@ return sizeof(*si2b); } -static int generate_si2ter(uint8_t *output, struct gsm_bts *bts) +static int generate_si2ter(enum osmo_sysinfo_type t, struct gsm_bts *bts) { int rc; struct gsm48_system_information_type_2ter *si2t = - (struct gsm48_system_information_type_2ter *) output; + (struct gsm48_system_information_type_2ter *) GSM_BTS_SI(bts, t); int n; memset(si2t, GSM_MACBLOCK_PADDING, GSM_MACBLOCK_LEN); @@ -670,11 +662,11 @@ return sizeof(*si2t); } -static int generate_si2quater(uint8_t *output, struct gsm_bts *bts) +static int generate_si2quater(enum osmo_sysinfo_type t, struct gsm_bts *bts) { int rc, i = MAX_EARFCN_LIST; struct gsm48_system_information_type_2quater *si2q = - (struct gsm48_system_information_type_2quater *) output; + (struct gsm48_system_information_type_2quater *) GSM_BTS_SI(bts, t); memset(si2q, GSM_MACBLOCK_PADDING, GSM_MACBLOCK_LEN); @@ -683,7 +675,7 @@ si2q->header.skip_indicator = 0; si2q->header.system_information = GSM48_MT_RR_SYSINFO_2quater; - rc = rest_octets_si2quater(si2q->rest_octets, + rc = rest_octets_si2quater(si2q->rest_octets, bts->si2q_index, bts->si2q_count, &bts->si_common.si2quater_neigh_list, bts->si_common.data.uarfcn_list, bts->si_common.data.scramble_list, @@ -727,11 +719,10 @@ .break_ind = 0, }; -static int generate_si3(uint8_t *output, struct gsm_bts *bts) +static int generate_si3(enum osmo_sysinfo_type t, struct gsm_bts *bts) { int rc; - struct gsm48_system_information_type_3 *si3 = - (struct gsm48_system_information_type_3 *) output; + struct gsm48_system_information_type_3 *si3 = (struct gsm48_system_information_type_3 *) GSM_BTS_SI(bts, t); memset(si3, GSM_MACBLOCK_PADDING, GSM_MACBLOCK_LEN); @@ -775,11 +766,10 @@ return sizeof(*si3) + rc; } -static int generate_si4(uint8_t *output, struct gsm_bts *bts) +static int generate_si4(enum osmo_sysinfo_type t, struct gsm_bts *bts) { int rc; - struct gsm48_system_information_type_4 *si4 = - (struct gsm48_system_information_type_4 *) output; + struct gsm48_system_information_type_4 *si4 = (struct gsm48_system_information_type_4 *) GSM_BTS_SI(bts, t); struct gsm_lchan *cbch_lchan; uint8_t *restoct = si4->data; @@ -815,14 +805,15 @@ /* SI4 Rest Octets (10.5.2.35), containing Optional Power offset, GPRS Indicator, Cell Identity, LSA ID, Selection Parameter */ - rc = rest_octets_si4(restoct, &si_info, output + GSM_MACBLOCK_LEN - restoct); + rc = rest_octets_si4(restoct, &si_info, (uint8_t *)GSM_BTS_SI(bts, t) + GSM_MACBLOCK_LEN - restoct); return l2_plen + 1 + rc; } -static int generate_si5(uint8_t *output, struct gsm_bts *bts) +static int generate_si5(enum osmo_sysinfo_type t, struct gsm_bts *bts) { struct gsm48_system_information_type_5 *si5; + uint8_t *output = GSM_BTS_SI(bts, t); int rc, l2_plen = 18; memset(output, GSM_MACBLOCK_PADDING, GSM_MACBLOCK_LEN); @@ -838,7 +829,7 @@ break; } - si5 = (struct gsm48_system_information_type_5 *) output; + si5 = (struct gsm48_system_information_type_5 *) GSM_BTS_SI(bts, t); /* l2 pseudo length, not part of msg: 18 */ si5->rr_protocol_discriminator = GSM48_PDISC_RR; @@ -854,9 +845,10 @@ return l2_plen; } -static int generate_si5bis(uint8_t *output, struct gsm_bts *bts) +static int generate_si5bis(enum osmo_sysinfo_type t, struct gsm_bts *bts) { struct gsm48_system_information_type_5bis *si5b; + uint8_t *output = GSM_BTS_SI(bts, t); int rc, l2_plen = 18; int n; @@ -873,7 +865,7 @@ break; } - si5b = (struct gsm48_system_information_type_5bis *) output; + si5b = (struct gsm48_system_information_type_5bis *) GSM_BTS_SI(bts, t); /* l2 pseudo length, not part of msg: 18 */ si5b->rr_protocol_discriminator = GSM48_PDISC_RR; @@ -887,8 +879,7 @@ if (n) { /* indicate in SI5 and SI5bis: there is an extension */ struct gsm48_system_information_type_5 *si5 = - (struct gsm48_system_information_type_5 *) - bts->si_buf[SYSINFO_TYPE_5]; + (struct gsm48_system_information_type_5 *) GSM_BTS_SI(bts, SYSINFO_TYPE_5); si5->bcch_frequency_list[0] |= 0x20; si5b->bcch_frequency_list[0] |= 0x20; } else @@ -898,9 +889,10 @@ return l2_plen; } -static int generate_si5ter(uint8_t *output, struct gsm_bts *bts) +static int generate_si5ter(enum osmo_sysinfo_type t, struct gsm_bts *bts) { struct gsm48_system_information_type_5ter *si5t; + uint8_t *output = GSM_BTS_SI(bts, t); int rc, l2_plen = 18; int n; @@ -917,7 +909,7 @@ break; } - si5t = (struct gsm48_system_information_type_5ter *) output; + si5t = (struct gsm48_system_information_type_5ter *) GSM_BTS_SI(bts, t); /* l2 pseudo length, not part of msg: 18 */ si5t->rr_protocol_discriminator = GSM48_PDISC_RR; @@ -935,9 +927,10 @@ return l2_plen; } -static int generate_si6(uint8_t *output, struct gsm_bts *bts) +static int generate_si6(enum osmo_sysinfo_type t, struct gsm_bts *bts) { struct gsm48_system_information_type_6 *si6; + uint8_t *output = GSM_BTS_SI(bts, t); int l2_plen = 11; int rc; @@ -954,7 +947,7 @@ break; } - si6 = (struct gsm48_system_information_type_6 *) output; + si6 = (struct gsm48_system_information_type_6 *) GSM_BTS_SI(bts, t); /* l2 pseudo length, not part of msg: 11 */ si6->rr_protocol_discriminator = GSM48_PDISC_RR; @@ -1015,10 +1008,10 @@ }, }; -static int generate_si13(uint8_t *output, struct gsm_bts *bts) +static int generate_si13(enum osmo_sysinfo_type t, struct gsm_bts *bts) { struct gsm48_system_information_type_13 *si13 = - (struct gsm48_system_information_type_13 *) output; + (struct gsm48_system_information_type_13 *) GSM_BTS_SI(bts, t); int ret; memset(si13, GSM_MACBLOCK_PADDING, GSM_MACBLOCK_LEN); @@ -1048,7 +1041,7 @@ return sizeof (*si13) + ret; } -typedef int (*gen_si_fn_t)(uint8_t *output, struct gsm_bts *bts); +typedef int (*gen_si_fn_t)(enum osmo_sysinfo_type t, struct gsm_bts *bts); static const gen_si_fn_t gen_si_fn[_MAX_SYSINFO_TYPE] = { [SYSINFO_TYPE_1] = &generate_si1, @@ -1090,5 +1083,5 @@ if (!gen_si) return -EINVAL; - return gen_si(bts->si_buf[si_type], bts); + return gen_si(si_type, bts); } diff --git a/openbsc/tests/gsm0408/gsm0408_test.c b/openbsc/tests/gsm0408/gsm0408_test.c index 08cf43f..81dc177 100644 --- a/openbsc/tests/gsm0408/gsm0408_test.c +++ b/openbsc/tests/gsm0408/gsm0408_test.c @@ -99,13 +99,12 @@ bts->si_valid = 0; bts->si_valid |= (1 << SYSINFO_TYPE_2quater); /* should be no-op as entire buffer is filled with padding: */ - memset(bts->si_buf[SYSINFO_TYPE_2quater], 0xAE, GSM_MACBLOCK_LEN); + memset(GSM_BTS_SI(bts, SYSINFO_TYPE_2quater), 0xAE, GSM_MACBLOCK_LEN); int r = gsm_generate_si(bts, SYSINFO_TYPE_2quater); bool v = bts->si_valid & (1 << SYSINFO_TYPE_2quater); if (r > 0) printf("generated %s SI2quater: [%d] %s\n", - v ? "valid" : "invalid", r, - osmo_hexdump(bts->si_buf[SYSINFO_TYPE_2quater], r)); + v ? "valid" : "invalid", r, osmo_hexdump(GSM_BTS_SI(bts, SYSINFO_TYPE_2quater), r)); else printf("failed to generate SI2quater: %s\n", strerror(-r)); } -- To view, visit https://gerrit.osmocom.org/2312 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I74e4e3cb86364cec869a1472a41b4a95af0d50dd Gerrit-PatchSet: 6 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Thu Apr 13 12:52:23 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Thu, 13 Apr 2017 12:52:23 +0000 Subject: [PATCH] openbsc[master]: Prepare for extended SI2quater support In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2312 to look at the new patch set (#7). Prepare for extended SI2quater support Supporting SI2quater support as per 3GPP TS 44.018 will require chnages to the way System Information is stored because it uses 1:n instead of 1:1 mapping between SI type and generated SI content. This should not affect other SI types though. To facilitate this transition: * convert the code to always use GSM_BTS_SI helper instead of accessing buffer directly * make helper more robust by adding extra parenthesis * add similar helper for gsm_lchan * add function estimating number of SI2quater message to hold configured number of (U|E)ARFCNs * add SI2q index/count fields and pass them to rest_octets generator explicitly * internalize buffer access in generate_si* functions Change-Id: I74e4e3cb86364cec869a1472a41b4a95af0d50dd Related: RT#8792 --- M openbsc/include/openbsc/gsm_data_shared.h M openbsc/include/openbsc/rest_octets.h M openbsc/include/openbsc/system_information.h M openbsc/src/libbsc/bsc_vty.c M openbsc/src/libbsc/rest_octets.c M openbsc/src/libbsc/system_information.c M openbsc/tests/gsm0408/gsm0408_test.c 7 files changed, 60 insertions(+), 61 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/12/2312/7 diff --git a/openbsc/include/openbsc/gsm_data_shared.h b/openbsc/include/openbsc/gsm_data_shared.h index 242889a..166de16 100644 --- a/openbsc/include/openbsc/gsm_data_shared.h +++ b/openbsc/include/openbsc/gsm_data_shared.h @@ -483,7 +483,8 @@ struct gsm_bts_trx_ts ts[TRX_NR_TS]; }; -#define GSM_BTS_SI(bts, i) (void *)(bts->si_buf[i]) +#define GSM_BTS_SI(bts, i) (void *)((bts)->si_buf[i]) +#define GSM_LCHAN_SI(lchan, i) (void *)((lchan)->si.buf[i]) enum gsm_bts_type { GSM_BTS_TYPE_UNKNOWN, @@ -702,6 +703,9 @@ /* bitmask of all SI that are present/valid in si_buf */ uint32_t si_valid; + /* 3GPP TS 44.018 Table 10.5.2.33b.1 INDEX and COUNT for SI2quater */ + uint8_t si2q_index; + uint8_t si2q_count; /* buffers where we put the pre-computed SI */ sysinfo_buf_t si_buf[_MAX_SYSINFO_TYPE]; diff --git a/openbsc/include/openbsc/rest_octets.h b/openbsc/include/openbsc/rest_octets.h index 3b4e598..73ce57b 100644 --- a/openbsc/include/openbsc/rest_octets.h +++ b/openbsc/include/openbsc/rest_octets.h @@ -5,12 +5,15 @@ #include #include +/* 16 is the max. number of SI2quater messages according to 3GPP TS 44.018: 4-bit index is used */ +#define SI2Q_MAX_NUM 16 +/* length in bits (for single SI2quater message) */ #define SI2Q_MAX_LEN 160 #define SI2Q_MIN_LEN 18 /* generate SI1 rest octets */ int rest_octets_si1(uint8_t *data, uint8_t *nch_pos, int is1800_net); -int rest_octets_si2quater(uint8_t *data, const struct osmo_earfcn_si2q *e, +int rest_octets_si2quater(uint8_t *data, uint8_t index, uint8_t count, const struct osmo_earfcn_si2q *e, const uint16_t *u, const uint16_t *sc, size_t u_len); int rest_octets_si6(uint8_t *data, bool is1800_net); diff --git a/openbsc/include/openbsc/system_information.h b/openbsc/include/openbsc/system_information.h index 1b19c8b..b012107 100644 --- a/openbsc/include/openbsc/system_information.h +++ b/openbsc/include/openbsc/system_information.h @@ -14,7 +14,7 @@ unsigned range512_q(unsigned m); int range_encode(enum gsm48_range r, int *arfcns, int arfcns_used, int *w, int f0, uint8_t *chan_list); -bool si2q_size_check(const struct gsm_bts *bts); +uint8_t si2q_num(const struct gsm_bts *bts); int bts_uarfcn_del(struct gsm_bts *bts, uint16_t arfcn, uint16_t scramble); int bts_uarfcn_add(struct gsm_bts *bts, uint16_t arfcn, uint16_t scramble, bool diversity); diff --git a/openbsc/src/libbsc/bsc_vty.c b/openbsc/src/libbsc/bsc_vty.c index c1882fc..657dfe3 100644 --- a/openbsc/src/libbsc/bsc_vty.c +++ b/openbsc/src/libbsc/bsc_vty.c @@ -644,7 +644,7 @@ get_value_string(osmo_sitype_strs, i), VTY_NEWLINE); vty_out(vty, " system-information %s static %s%s", get_value_string(osmo_sitype_strs, i), - osmo_hexdump_nospc(bts->si_buf[i], sizeof(bts->si_buf[i])), + osmo_hexdump_nospc(GSM_BTS_SI(bts, i), GSM_MACBLOCK_LEN), VTY_NEWLINE); } } @@ -2688,11 +2688,11 @@ } /* Fill buffer with padding pattern */ - memset(bts->si_buf[type], 0x2b, sizeof(bts->si_buf[type])); + memset(GSM_BTS_SI(bts, type), 0x2b, GSM_MACBLOCK_LEN); /* Parse the user-specified SI in hex format, [partially] overwriting padding */ - rc = osmo_hexparse(argv[1], bts->si_buf[type], sizeof(bts->si_buf[0])); - if (rc < 0 || rc > sizeof(bts->si_buf[0])) { + rc = osmo_hexparse(argv[1], GSM_BTS_SI(bts, type), GSM_MACBLOCK_LEN); + if (rc < 0 || rc > GSM_MACBLOCK_LEN) { vty_out(vty, "Error parsing HEXSTRING%s", VTY_NEWLINE); return CMD_WARNING; } @@ -2830,7 +2830,7 @@ e->prio_valid = true; } - if (si2q_size_check(bts)) + if (si2q_num(bts) < 2) return CMD_SUCCESS; vty_out(vty, "Warning: not enough space in SI2quater for a given EARFCN " diff --git a/openbsc/src/libbsc/rest_octets.c b/openbsc/src/libbsc/rest_octets.c index ed6c573..af660f1 100644 --- a/openbsc/src/libbsc/rest_octets.c +++ b/openbsc/src/libbsc/rest_octets.c @@ -256,7 +256,7 @@ } /* generate SI2quater rest octets: 3GPP TS 44.018 ? 10.5.2.33b */ -int rest_octets_si2quater(uint8_t *data, const struct osmo_earfcn_si2q *e, +int rest_octets_si2quater(uint8_t *data, uint8_t index, uint8_t count, const struct osmo_earfcn_si2q *e, const uint16_t *u, const uint16_t *sc, size_t u_len) { int rc; @@ -275,9 +275,9 @@ /* we do not support multiple si2quater messages at the moment: */ /* SI2quater_INDEX */ - bitvec_set_uint(&bv, 0, 4); + bitvec_set_uint(&bv, index, 4); /* SI2quater_COUNT */ - bitvec_set_uint(&bv, 0, 4); + bitvec_set_uint(&bv, count, 4); /* No Measurement_Parameters Description */ bitvec_set_bit(&bv, 0); diff --git a/openbsc/src/libbsc/system_information.c b/openbsc/src/libbsc/system_information.c index 2610331..37395f0 100644 --- a/openbsc/src/libbsc/system_information.c +++ b/openbsc/src/libbsc/system_information.c @@ -149,18 +149,13 @@ return s + r + append + range1024_p(k); } -bool si2q_size_check(const struct gsm_bts *bts) +uint8_t si2q_num(const struct gsm_bts *bts) { - const struct osmo_earfcn_si2q *e = &bts->si_common.si2quater_neigh_list; - const uint16_t *u = bts->si_common.data.uarfcn_list, - *sc = bts->si_common.data.scramble_list; - size_t len = bts->si_common.uarfcn_length; - unsigned e_sz = e ? earfcn_size(e) : 1, - u_sz = len ? uarfcn_size(u, sc, len) : 1; + const struct osmo_earfcn_si2q *e = &bts->si_common.si2quater_neigh_list; /* EARFCN */ + const uint16_t *u = bts->si_common.data.uarfcn_list, *sc = bts->si_common.data.scramble_list; /* UARFCN */ + size_t l = bts->si_common.uarfcn_length, e_sz = e ? earfcn_size(e) : 1, u_sz = l ? uarfcn_size(u, sc, l) : 1; /* 2 bits are used in between UARFCN and EARFCN structs */ - if (SI2Q_MIN_LEN + u_sz + 2 + e_sz > SI2Q_MAX_LEN) - return false; - return true; + return 1 + (e_sz + u_sz) / (SI2Q_MAX_LEN - (SI2Q_MIN_LEN + 2)); } /* 3GPP TS 44.018, Table 9.1.54.1 - prepend diversity bit to scrambling code */ @@ -233,7 +228,7 @@ scl[k] = scr; bts->si_common.uarfcn_length++; - if (si2q_size_check(bts)) + if (si2q_num(bts) < 2) return 0; bts_uarfcn_del(bts, arfcn, scramble); @@ -557,11 +552,10 @@ return n; } -static int generate_si1(uint8_t *output, struct gsm_bts *bts) +static int generate_si1(enum osmo_sysinfo_type t, struct gsm_bts *bts) { int rc; - struct gsm48_system_information_type_1 *si1 = - (struct gsm48_system_information_type_1 *) output; + struct gsm48_system_information_type_1 *si1 = (struct gsm48_system_information_type_1 *) GSM_BTS_SI(bts, t); memset(si1, GSM_MACBLOCK_PADDING, GSM_MACBLOCK_LEN); @@ -586,11 +580,10 @@ return sizeof(*si1) + rc; } -static int generate_si2(uint8_t *output, struct gsm_bts *bts) +static int generate_si2(enum osmo_sysinfo_type t, struct gsm_bts *bts) { int rc; - struct gsm48_system_information_type_2 *si2 = - (struct gsm48_system_information_type_2 *) output; + struct gsm48_system_information_type_2 *si2 = (struct gsm48_system_information_type_2 *) GSM_BTS_SI(bts, t); memset(si2, GSM_MACBLOCK_PADDING, GSM_MACBLOCK_LEN); @@ -611,11 +604,11 @@ return sizeof(*si2); } -static int generate_si2bis(uint8_t *output, struct gsm_bts *bts) +static int generate_si2bis(enum osmo_sysinfo_type t, struct gsm_bts *bts) { int rc; struct gsm48_system_information_type_2bis *si2b = - (struct gsm48_system_information_type_2bis *) output; + (struct gsm48_system_information_type_2bis *) GSM_BTS_SI(bts, t); int n; memset(si2b, GSM_MACBLOCK_PADDING, GSM_MACBLOCK_LEN); @@ -633,8 +626,7 @@ if (n) { /* indicate in SI2 and SI2bis: there is an extension */ struct gsm48_system_information_type_2 *si2 = - (struct gsm48_system_information_type_2 *) - bts->si_buf[SYSINFO_TYPE_2]; + (struct gsm48_system_information_type_2 *) GSM_BTS_SI(bts, SYSINFO_TYPE_2); si2->bcch_frequency_list[0] |= 0x20; si2b->bcch_frequency_list[0] |= 0x20; } else @@ -645,11 +637,11 @@ return sizeof(*si2b); } -static int generate_si2ter(uint8_t *output, struct gsm_bts *bts) +static int generate_si2ter(enum osmo_sysinfo_type t, struct gsm_bts *bts) { int rc; struct gsm48_system_information_type_2ter *si2t = - (struct gsm48_system_information_type_2ter *) output; + (struct gsm48_system_information_type_2ter *) GSM_BTS_SI(bts, t); int n; memset(si2t, GSM_MACBLOCK_PADDING, GSM_MACBLOCK_LEN); @@ -670,11 +662,11 @@ return sizeof(*si2t); } -static int generate_si2quater(uint8_t *output, struct gsm_bts *bts) +static int generate_si2quater(enum osmo_sysinfo_type t, struct gsm_bts *bts) { int rc, i = MAX_EARFCN_LIST; struct gsm48_system_information_type_2quater *si2q = - (struct gsm48_system_information_type_2quater *) output; + (struct gsm48_system_information_type_2quater *) GSM_BTS_SI(bts, t); memset(si2q, GSM_MACBLOCK_PADDING, GSM_MACBLOCK_LEN); @@ -683,7 +675,7 @@ si2q->header.skip_indicator = 0; si2q->header.system_information = GSM48_MT_RR_SYSINFO_2quater; - rc = rest_octets_si2quater(si2q->rest_octets, + rc = rest_octets_si2quater(si2q->rest_octets, bts->si2q_index, bts->si2q_count, &bts->si_common.si2quater_neigh_list, bts->si_common.data.uarfcn_list, bts->si_common.data.scramble_list, @@ -727,11 +719,10 @@ .break_ind = 0, }; -static int generate_si3(uint8_t *output, struct gsm_bts *bts) +static int generate_si3(enum osmo_sysinfo_type t, struct gsm_bts *bts) { int rc; - struct gsm48_system_information_type_3 *si3 = - (struct gsm48_system_information_type_3 *) output; + struct gsm48_system_information_type_3 *si3 = (struct gsm48_system_information_type_3 *) GSM_BTS_SI(bts, t); memset(si3, GSM_MACBLOCK_PADDING, GSM_MACBLOCK_LEN); @@ -775,11 +766,10 @@ return sizeof(*si3) + rc; } -static int generate_si4(uint8_t *output, struct gsm_bts *bts) +static int generate_si4(enum osmo_sysinfo_type t, struct gsm_bts *bts) { int rc; - struct gsm48_system_information_type_4 *si4 = - (struct gsm48_system_information_type_4 *) output; + struct gsm48_system_information_type_4 *si4 = (struct gsm48_system_information_type_4 *) GSM_BTS_SI(bts, t); struct gsm_lchan *cbch_lchan; uint8_t *restoct = si4->data; @@ -815,14 +805,15 @@ /* SI4 Rest Octets (10.5.2.35), containing Optional Power offset, GPRS Indicator, Cell Identity, LSA ID, Selection Parameter */ - rc = rest_octets_si4(restoct, &si_info, output + GSM_MACBLOCK_LEN - restoct); + rc = rest_octets_si4(restoct, &si_info, (uint8_t *)GSM_BTS_SI(bts, t) + GSM_MACBLOCK_LEN - restoct); return l2_plen + 1 + rc; } -static int generate_si5(uint8_t *output, struct gsm_bts *bts) +static int generate_si5(enum osmo_sysinfo_type t, struct gsm_bts *bts) { struct gsm48_system_information_type_5 *si5; + uint8_t *output = GSM_BTS_SI(bts, t); int rc, l2_plen = 18; memset(output, GSM_MACBLOCK_PADDING, GSM_MACBLOCK_LEN); @@ -838,7 +829,7 @@ break; } - si5 = (struct gsm48_system_information_type_5 *) output; + si5 = (struct gsm48_system_information_type_5 *) GSM_BTS_SI(bts, t); /* l2 pseudo length, not part of msg: 18 */ si5->rr_protocol_discriminator = GSM48_PDISC_RR; @@ -854,9 +845,10 @@ return l2_plen; } -static int generate_si5bis(uint8_t *output, struct gsm_bts *bts) +static int generate_si5bis(enum osmo_sysinfo_type t, struct gsm_bts *bts) { struct gsm48_system_information_type_5bis *si5b; + uint8_t *output = GSM_BTS_SI(bts, t); int rc, l2_plen = 18; int n; @@ -873,7 +865,7 @@ break; } - si5b = (struct gsm48_system_information_type_5bis *) output; + si5b = (struct gsm48_system_information_type_5bis *) GSM_BTS_SI(bts, t); /* l2 pseudo length, not part of msg: 18 */ si5b->rr_protocol_discriminator = GSM48_PDISC_RR; @@ -887,8 +879,7 @@ if (n) { /* indicate in SI5 and SI5bis: there is an extension */ struct gsm48_system_information_type_5 *si5 = - (struct gsm48_system_information_type_5 *) - bts->si_buf[SYSINFO_TYPE_5]; + (struct gsm48_system_information_type_5 *) GSM_BTS_SI(bts, SYSINFO_TYPE_5); si5->bcch_frequency_list[0] |= 0x20; si5b->bcch_frequency_list[0] |= 0x20; } else @@ -898,9 +889,10 @@ return l2_plen; } -static int generate_si5ter(uint8_t *output, struct gsm_bts *bts) +static int generate_si5ter(enum osmo_sysinfo_type t, struct gsm_bts *bts) { struct gsm48_system_information_type_5ter *si5t; + uint8_t *output = GSM_BTS_SI(bts, t); int rc, l2_plen = 18; int n; @@ -917,7 +909,7 @@ break; } - si5t = (struct gsm48_system_information_type_5ter *) output; + si5t = (struct gsm48_system_information_type_5ter *) GSM_BTS_SI(bts, t); /* l2 pseudo length, not part of msg: 18 */ si5t->rr_protocol_discriminator = GSM48_PDISC_RR; @@ -935,9 +927,10 @@ return l2_plen; } -static int generate_si6(uint8_t *output, struct gsm_bts *bts) +static int generate_si6(enum osmo_sysinfo_type t, struct gsm_bts *bts) { struct gsm48_system_information_type_6 *si6; + uint8_t *output = GSM_BTS_SI(bts, t); int l2_plen = 11; int rc; @@ -954,7 +947,7 @@ break; } - si6 = (struct gsm48_system_information_type_6 *) output; + si6 = (struct gsm48_system_information_type_6 *) GSM_BTS_SI(bts, t); /* l2 pseudo length, not part of msg: 11 */ si6->rr_protocol_discriminator = GSM48_PDISC_RR; @@ -1015,10 +1008,10 @@ }, }; -static int generate_si13(uint8_t *output, struct gsm_bts *bts) +static int generate_si13(enum osmo_sysinfo_type t, struct gsm_bts *bts) { struct gsm48_system_information_type_13 *si13 = - (struct gsm48_system_information_type_13 *) output; + (struct gsm48_system_information_type_13 *) GSM_BTS_SI(bts, t); int ret; memset(si13, GSM_MACBLOCK_PADDING, GSM_MACBLOCK_LEN); @@ -1048,7 +1041,7 @@ return sizeof (*si13) + ret; } -typedef int (*gen_si_fn_t)(uint8_t *output, struct gsm_bts *bts); +typedef int (*gen_si_fn_t)(enum osmo_sysinfo_type t, struct gsm_bts *bts); static const gen_si_fn_t gen_si_fn[_MAX_SYSINFO_TYPE] = { [SYSINFO_TYPE_1] = &generate_si1, @@ -1090,5 +1083,5 @@ if (!gen_si) return -EINVAL; - return gen_si(bts->si_buf[si_type], bts); + return gen_si(si_type, bts); } diff --git a/openbsc/tests/gsm0408/gsm0408_test.c b/openbsc/tests/gsm0408/gsm0408_test.c index 08cf43f..81dc177 100644 --- a/openbsc/tests/gsm0408/gsm0408_test.c +++ b/openbsc/tests/gsm0408/gsm0408_test.c @@ -99,13 +99,12 @@ bts->si_valid = 0; bts->si_valid |= (1 << SYSINFO_TYPE_2quater); /* should be no-op as entire buffer is filled with padding: */ - memset(bts->si_buf[SYSINFO_TYPE_2quater], 0xAE, GSM_MACBLOCK_LEN); + memset(GSM_BTS_SI(bts, SYSINFO_TYPE_2quater), 0xAE, GSM_MACBLOCK_LEN); int r = gsm_generate_si(bts, SYSINFO_TYPE_2quater); bool v = bts->si_valid & (1 << SYSINFO_TYPE_2quater); if (r > 0) printf("generated %s SI2quater: [%d] %s\n", - v ? "valid" : "invalid", r, - osmo_hexdump(bts->si_buf[SYSINFO_TYPE_2quater], r)); + v ? "valid" : "invalid", r, osmo_hexdump(GSM_BTS_SI(bts, SYSINFO_TYPE_2quater), r)); else printf("failed to generate SI2quater: %s\n", strerror(-r)); } -- To view, visit https://gerrit.osmocom.org/2312 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I74e4e3cb86364cec869a1472a41b4a95af0d50dd Gerrit-PatchSet: 7 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Thu Apr 13 13:44:43 2017 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Thu, 13 Apr 2017 13:44:43 +0000 Subject: [PATCH] osmo-bts[master]: octphy: print log message for multi-trx support Message-ID: Review at https://gerrit.osmocom.org/2315 octphy: print log message for multi-trx support Some header file versions support multi-trx and some do not. After to compiling it is very difficult to find out if the binary is multi-trx capable por not. This patch adds a log line that should rule out any doubts. Change-Id: I257c0a5e7c5ff5df2f0a603d1ede6db5679382e0 --- M src/osmo-bts-octphy/l1_oml.c 1 file changed, 6 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/15/2315/1 diff --git a/src/osmo-bts-octphy/l1_oml.c b/src/osmo-bts-octphy/l1_oml.c index 7e1ad88..4652e10 100644 --- a/src/osmo-bts-octphy/l1_oml.c +++ b/src/osmo-bts-octphy/l1_oml.c @@ -1109,6 +1109,12 @@ LOGP(DL1C, LOGL_INFO, "Rx APP-INFO-SYSTEM.resp (platform='%s', version='%s')\n", aisr->szPlatform, aisr->szVersion); +#if OCTPHY_MULTI_TRX == 1 + LOGP(DL1C, LOGL_INFO, "Note: compiled with multi-trx support.\n"); +#else + LOGP(DL1C, LOGL_INFO, "Note: compiled without multi-trx support.\n"); +#endif + talloc_replace(fl1h->info.system.platform, fl1h, aisr->szPlatform); talloc_replace(fl1h->info.system.version, fl1h, aisr->szVersion); -- To view, visit https://gerrit.osmocom.org/2315 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I257c0a5e7c5ff5df2f0a603d1ede6db5679382e0 Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: dexter From gerrit-no-reply at lists.osmocom.org Thu Apr 13 13:44:44 2017 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Thu, 13 Apr 2017 13:44:44 +0000 Subject: [PATCH] osmo-bts[master]: octphy: display hint in case of wrongly configured transceiv... Message-ID: Review at https://gerrit.osmocom.org/2316 octphy: display hint in case of wrongly configured transceiver number Making use of the multi-trx feature requires to tell osmo-bts that more than one transceiver are available. Otherwise it will complain that not enough transceivers are available. This can be quite confusing, even a correct config file will fail to parse if it specifies more transcrivers than available. This patch adds a hint to the error message so that the user knows that he should check the -t commandline option Change-Id: Ifbeacd9d43f7c6cd74a1e1b33288e66828fe843f --- M src/common/vty.c 1 file changed, 2 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/16/2316/1 diff --git a/src/common/vty.c b/src/common/vty.c index a48f809..44c742c 100644 --- a/src/common/vty.c +++ b/src/common/vty.c @@ -224,6 +224,8 @@ if (!trx) { vty_out(vty, "Unknown TRX %u. Available TRX are: 0..%u%s", trx_nr, bts->num_trx - 1, VTY_NEWLINE); + vty_out(vty, "Hint: Check if commandline option -t matches the" + "number of available transceivers!%s", VTY_NEWLINE); return CMD_WARNING; } -- To view, visit https://gerrit.osmocom.org/2316 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ifbeacd9d43f7c6cd74a1e1b33288e66828fe843f Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: dexter From gerrit-no-reply at lists.osmocom.org Thu Apr 13 16:02:05 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 13 Apr 2017 16:02:05 +0000 Subject: [PATCH] libosmo-sccp[master]: sccp_test_server: Don't use '0' as local reference Message-ID: Review at https://gerrit.osmocom.org/2317 sccp_test_server: Don't use '0' as local reference the '0' confuses the Ericsson SCCP code for Eclipse Titan, even though the spec considers it permitted. Change-Id: I21269a7d610a4bf52555ffcef4f8acc55824515e --- M examples/sccp_test_server.c 1 file changed, 1 insertion(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/17/2317/1 diff --git a/examples/sccp_test_server.c b/examples/sccp_test_server.c index 71bed96..6249e45 100644 --- a/examples/sccp_test_server.c +++ b/examples/sccp_test_server.c @@ -12,7 +12,7 @@ #include "internal.h" -unsigned int conn_id; +unsigned int conn_id =1; /* a simple SCCP User which refuses all connections and discards all * unitdata */ -- To view, visit https://gerrit.osmocom.org/2317 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I21269a7d610a4bf52555ffcef4f8acc55824515e Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Thu Apr 13 16:02:06 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 13 Apr 2017 16:02:06 +0000 Subject: [PATCH] libosmo-sccp[master]: sua2sccp: Only encode SCCP options permitted for given msg type Message-ID: Review at https://gerrit.osmocom.org/2318 sua2sccp: Only encode SCCP options permitted for given msg type The SCCP spec clearly defines which optional information element each of the messages supports. We must make sure to not include any other options when converting from SUA. SUA has more relaxed rules about this, and e.g. supports SRC and DEST ADDR in the COAK, while the SCCP CC only permits a CalledParty, but not CallingParty. This was found when interoperating against the Ericsson TTCN-3 SCCP implementation for Eclipse Titan. Change-Id: I7d9e23dec1d3e786d291abd270a261704593befc --- M src/sccp2sua.c 1 file changed, 111 insertions(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/18/2318/1 diff --git a/src/sccp2sua.c b/src/sccp2sua.c index 070a8cb..26e3f44 100644 --- a/src/sccp2sua.c +++ b/src/sccp2sua.c @@ -789,6 +789,94 @@ }, }; +/* This table indicates which information elements are optionally + * permitted in the respective SCCP message type */ +static const uint16_t sccp_optional[NUM_SCCP_MSGT][MAX_IES] = { + /* Table 3/Q.713 */ + [SCCP_MSG_TYPE_CR] = { + SUA_IEI_CREDIT, SUA_IEI_SRC_ADDR, SUA_IEI_DATA, + SUA_IEI_S7_HOP_CTR, SUA_IEI_IMPORTANCE, 0 + }, + /* Table 4/Q.713 */ + [SCCP_MSG_TYPE_CC] = { + SUA_IEI_CREDIT, SUA_IEI_SRC_ADDR, SUA_IEI_DATA, + SUA_IEI_IMPORTANCE, 0 + }, + /* Table 5/Q.713 */ + [SCCP_MSG_TYPE_CREF] = { + SUA_IEI_SRC_ADDR, SUA_IEI_DATA, SUA_IEI_IMPORTANCE, 0 + }, + /* Table 6/Q.713 */ + [SCCP_MSG_TYPE_RLSD] = { + SUA_IEI_DATA, SUA_IEI_IMPORTANCE, 0 + }, + /* Table 7/Q.713 */ + [SCCP_MSG_TYPE_RLC] = { + 0 + }, + /* Table 8/Q.713 */ + [SCCP_MSG_TYPE_DT1] = { + 0 + }, + /* Table 9/Q.713 */ + [SCCP_MSG_TYPE_DT2] = { + 0 + }, + /* Table 10/Q.713 */ + [SCCP_MSG_TYPE_AK] = { + 0 + }, + /* Table 11/Q.713 */ + [SCCP_MSG_TYPE_UDT] = { + 0 + }, + /* Table 12/Q.713 */ + [SCCP_MSG_TYPE_UDTS] = { + 0 + }, + /* Table 13/Q.713 */ + [SCCP_MSG_TYPE_ED] = { + 0 + }, + /* Table 14/Q.713 */ + [SCCP_MSG_TYPE_EA] = { + 0 + }, + /* Table 15/Q.713 */ + [SCCP_MSG_TYPE_RSR] = { + 0 + }, + /* Table 16/Q.713 */ + [SCCP_MSG_TYPE_RSC] = { + 0 + }, + /* Table 17/Q.713 */ + [SCCP_MSG_TYPE_ERR] = { + 0 + }, + /* Table 18/Q.713 */ + [SCCP_MSG_TYPE_IT] = { + 0 + }, + /* Table 19/Q.713 */ + [SCCP_MSG_TYPE_XUDT] = { + SUA_IEI_SEGMENTATION, SUA_IEI_IMPORTANCE, 0 + }, + /* Table 20/Q.713 */ + [SCCP_MSG_TYPE_XUDTS] = { + SUA_IEI_SEGMENTATION, SUA_IEI_IMPORTANCE, 0 + }, + /* Table 21/Q.713 */ + [SCCP_MSG_TYPE_LUDT] = { + SUA_IEI_SEGMENTATION, SUA_IEI_IMPORTANCE, 0 + }, + /* Table 22/Q.713 */ + [SCCP_MSG_TYPE_LUDTS] = { + SUA_IEI_SEGMENTATION, SUA_IEI_IMPORTANCE, 0 + }, +}; + + static bool sccp_is_mandatory(enum sccp_message_types type, const struct xua_msg_part *part) { unsigned int i; @@ -811,6 +899,28 @@ return false; } +static bool sccp_option_permitted(enum sccp_message_types type, const struct xua_msg_part *part) +{ + unsigned int i; + + if (type > ARRAY_SIZE(sccp_optional)) + return false; + + for (i = 0; i < MAX_IES; i++) { + uint16_t val = sccp_optional[type][i]; + if (val == 0) { + /* end of list, don't iterate further */ + return false; + } + if (val == part->tag) { + /* found in list, it's permitted */ + return true; + } + } + /* not permitted */ + return false; +} + static int xua_ies_to_sccp_opts(struct msgb *msg, uint8_t *ptr_opt, enum sccp_message_types type, struct xua_msg *xua) { @@ -823,7 +933,7 @@ /* make sure we don't add a SCCP option for information * that is already present in mandatory fixed or * mandatory variable parts of the header */ - if (!sccp_is_mandatory(type, part)) + if (!sccp_is_mandatory(type, part) && sccp_option_permitted(type, part)) sccp_msg_add_sua_opt(msg, part); } msgb_put_u8(msg, SCCP_PNC_END_OF_OPTIONAL); -- To view, visit https://gerrit.osmocom.org/2318 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I7d9e23dec1d3e786d291abd270a261704593befc Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Thu Apr 13 16:05:34 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 13 Apr 2017 16:05:34 +0000 Subject: libosmo-sccp[master]: sccp_test_server: Don't use '0' as local reference In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2317 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I21269a7d610a4bf52555ffcef4f8acc55824515e Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Apr 13 16:05:41 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 13 Apr 2017 16:05:41 +0000 Subject: libosmo-sccp[master]: sua2sccp: Only encode SCCP options permitted for given msg type In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2318 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I7d9e23dec1d3e786d291abd270a261704593befc Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Apr 13 16:05:45 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 13 Apr 2017 16:05:45 +0000 Subject: [MERGED] libosmo-sccp[master]: sua2sccp: Only encode SCCP options permitted for given msg type In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: sua2sccp: Only encode SCCP options permitted for given msg type ...................................................................... sua2sccp: Only encode SCCP options permitted for given msg type The SCCP spec clearly defines which optional information element each of the messages supports. We must make sure to not include any other options when converting from SUA. SUA has more relaxed rules about this, and e.g. supports SRC and DEST ADDR in the COAK, while the SCCP CC only permits a CalledParty, but not CallingParty. This was found when interoperating against the Ericsson TTCN-3 SCCP implementation for Eclipse Titan. Change-Id: I7d9e23dec1d3e786d291abd270a261704593befc --- M src/sccp2sua.c 1 file changed, 111 insertions(+), 1 deletion(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/sccp2sua.c b/src/sccp2sua.c index 070a8cb..26e3f44 100644 --- a/src/sccp2sua.c +++ b/src/sccp2sua.c @@ -789,6 +789,94 @@ }, }; +/* This table indicates which information elements are optionally + * permitted in the respective SCCP message type */ +static const uint16_t sccp_optional[NUM_SCCP_MSGT][MAX_IES] = { + /* Table 3/Q.713 */ + [SCCP_MSG_TYPE_CR] = { + SUA_IEI_CREDIT, SUA_IEI_SRC_ADDR, SUA_IEI_DATA, + SUA_IEI_S7_HOP_CTR, SUA_IEI_IMPORTANCE, 0 + }, + /* Table 4/Q.713 */ + [SCCP_MSG_TYPE_CC] = { + SUA_IEI_CREDIT, SUA_IEI_SRC_ADDR, SUA_IEI_DATA, + SUA_IEI_IMPORTANCE, 0 + }, + /* Table 5/Q.713 */ + [SCCP_MSG_TYPE_CREF] = { + SUA_IEI_SRC_ADDR, SUA_IEI_DATA, SUA_IEI_IMPORTANCE, 0 + }, + /* Table 6/Q.713 */ + [SCCP_MSG_TYPE_RLSD] = { + SUA_IEI_DATA, SUA_IEI_IMPORTANCE, 0 + }, + /* Table 7/Q.713 */ + [SCCP_MSG_TYPE_RLC] = { + 0 + }, + /* Table 8/Q.713 */ + [SCCP_MSG_TYPE_DT1] = { + 0 + }, + /* Table 9/Q.713 */ + [SCCP_MSG_TYPE_DT2] = { + 0 + }, + /* Table 10/Q.713 */ + [SCCP_MSG_TYPE_AK] = { + 0 + }, + /* Table 11/Q.713 */ + [SCCP_MSG_TYPE_UDT] = { + 0 + }, + /* Table 12/Q.713 */ + [SCCP_MSG_TYPE_UDTS] = { + 0 + }, + /* Table 13/Q.713 */ + [SCCP_MSG_TYPE_ED] = { + 0 + }, + /* Table 14/Q.713 */ + [SCCP_MSG_TYPE_EA] = { + 0 + }, + /* Table 15/Q.713 */ + [SCCP_MSG_TYPE_RSR] = { + 0 + }, + /* Table 16/Q.713 */ + [SCCP_MSG_TYPE_RSC] = { + 0 + }, + /* Table 17/Q.713 */ + [SCCP_MSG_TYPE_ERR] = { + 0 + }, + /* Table 18/Q.713 */ + [SCCP_MSG_TYPE_IT] = { + 0 + }, + /* Table 19/Q.713 */ + [SCCP_MSG_TYPE_XUDT] = { + SUA_IEI_SEGMENTATION, SUA_IEI_IMPORTANCE, 0 + }, + /* Table 20/Q.713 */ + [SCCP_MSG_TYPE_XUDTS] = { + SUA_IEI_SEGMENTATION, SUA_IEI_IMPORTANCE, 0 + }, + /* Table 21/Q.713 */ + [SCCP_MSG_TYPE_LUDT] = { + SUA_IEI_SEGMENTATION, SUA_IEI_IMPORTANCE, 0 + }, + /* Table 22/Q.713 */ + [SCCP_MSG_TYPE_LUDTS] = { + SUA_IEI_SEGMENTATION, SUA_IEI_IMPORTANCE, 0 + }, +}; + + static bool sccp_is_mandatory(enum sccp_message_types type, const struct xua_msg_part *part) { unsigned int i; @@ -811,6 +899,28 @@ return false; } +static bool sccp_option_permitted(enum sccp_message_types type, const struct xua_msg_part *part) +{ + unsigned int i; + + if (type > ARRAY_SIZE(sccp_optional)) + return false; + + for (i = 0; i < MAX_IES; i++) { + uint16_t val = sccp_optional[type][i]; + if (val == 0) { + /* end of list, don't iterate further */ + return false; + } + if (val == part->tag) { + /* found in list, it's permitted */ + return true; + } + } + /* not permitted */ + return false; +} + static int xua_ies_to_sccp_opts(struct msgb *msg, uint8_t *ptr_opt, enum sccp_message_types type, struct xua_msg *xua) { @@ -823,7 +933,7 @@ /* make sure we don't add a SCCP option for information * that is already present in mandatory fixed or * mandatory variable parts of the header */ - if (!sccp_is_mandatory(type, part)) + if (!sccp_is_mandatory(type, part) && sccp_option_permitted(type, part)) sccp_msg_add_sua_opt(msg, part); } msgb_put_u8(msg, SCCP_PNC_END_OF_OPTIONAL); -- To view, visit https://gerrit.osmocom.org/2318 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I7d9e23dec1d3e786d291abd270a261704593befc Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Thu Apr 13 16:05:45 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 13 Apr 2017 16:05:45 +0000 Subject: [MERGED] libosmo-sccp[master]: sccp_test_server: Don't use '0' as local reference In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: sccp_test_server: Don't use '0' as local reference ...................................................................... sccp_test_server: Don't use '0' as local reference the '0' confuses the Ericsson SCCP code for Eclipse Titan, even though the spec considers it permitted. Change-Id: I21269a7d610a4bf52555ffcef4f8acc55824515e --- M examples/sccp_test_server.c 1 file changed, 1 insertion(+), 1 deletion(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/examples/sccp_test_server.c b/examples/sccp_test_server.c index 71bed96..6249e45 100644 --- a/examples/sccp_test_server.c +++ b/examples/sccp_test_server.c @@ -12,7 +12,7 @@ #include "internal.h" -unsigned int conn_id; +unsigned int conn_id =1; /* a simple SCCP User which refuses all connections and discards all * unitdata */ -- To view, visit https://gerrit.osmocom.org/2317 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I21269a7d610a4bf52555ffcef4f8acc55824515e Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Thu Apr 13 16:13:23 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 13 Apr 2017 16:13:23 +0000 Subject: osmo-bts[master]: octphy: add conditional compilation to support latest octasi... In-Reply-To: References: Message-ID: Patch Set 3: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/1964 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I73287983e8bed8bf64b2ab87e6b810c2c59ea6fd Gerrit-PatchSet: 3 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Apr 13 16:14:03 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 13 Apr 2017 16:14:03 +0000 Subject: osmo-bts[master]: octphy: align frame number for new firmware versions In-Reply-To: References: Message-ID: Patch Set 3: Code-Review+1 (1 comment) https://gerrit.osmocom.org/#/c/1965/3/src/osmo-bts-octphy/l1_if.c File src/osmo-bts-octphy/l1_if.c: Line 1042: /* FIXME::PCU is expecting encode frame number*/ why is there a FIXME left? -- To view, visit https://gerrit.osmocom.org/1965 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ib93d5fb3b34ff92f10021a0e9ce9c8aa3044b7ff Gerrit-PatchSet: 3 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Thu Apr 13 16:14:24 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 13 Apr 2017 16:14:24 +0000 Subject: osmo-bts[master]: l1sap: improve log output In-Reply-To: References: Message-ID: Patch Set 3: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/1967 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I3a2dde95947438aa8348a0a9fc8566cbc177aa2d Gerrit-PatchSet: 3 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Apr 13 16:14:45 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 13 Apr 2017 16:14:45 +0000 Subject: osmo-bts[master]: octphy: set tx/rx antenne IDs via VTY In-Reply-To: References: Message-ID: Patch Set 3: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/1976 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I872fe3c4d7b593358a4ce2f02cf0726611b9f3aa Gerrit-PatchSet: 3 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Apr 13 16:15:47 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 13 Apr 2017 16:15:47 +0000 Subject: osmo-bts[master]: octphy: WIP: Bug in while auto-activating all SAPIs for the ... In-Reply-To: References: Message-ID: Patch Set 1: Code-Review-1 -- To view, visit https://gerrit.osmocom.org/2314 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ie307bf9f370a346686e3bd8c8a8483953a1bc279 Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Apr 13 16:15:58 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 13 Apr 2017 16:15:58 +0000 Subject: osmo-bts[master]: octphy: print log message for multi-trx support In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2315 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I257c0a5e7c5ff5df2f0a603d1ede6db5679382e0 Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Apr 13 16:16:09 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 13 Apr 2017 16:16:09 +0000 Subject: osmo-bts[master]: octphy: display hint in case of wrongly configured transceiv... In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2316 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ifbeacd9d43f7c6cd74a1e1b33288e66828fe843f Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Apr 13 16:23:20 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 13 Apr 2017 16:23:20 +0000 Subject: libosmo-sccp[master]: WIP: default layer manager using RKM to register PC with SG In-Reply-To: References: Message-ID: Harald Welte has restored this change. Change subject: WIP: default layer manager using RKM to register PC with SG ...................................................................... Restored -- To view, visit https://gerrit.osmocom.org/2283 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: restore Gerrit-Change-Id: I78d4623dd213b5c59007a026a6cc3cfe5c04af50 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Thu Apr 13 16:23:23 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 13 Apr 2017 16:23:23 +0000 Subject: [PATCH] libosmo-sccp[master]: Add osmo-stp executable as new "Osmocom Signaling Transfer P... In-Reply-To: References: Message-ID: Hello Jenkins Builder, Holger Freyther, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2281 to look at the new patch set (#3). Add osmo-stp executable as new "Osmocom Signaling Transfer Point" osmo-stp is able to define multiple M3UA and/or SUA application servers (AS) as well as application server processes (ASPs). Clients can then connect via M3UA or SUA, perform the respective ASPSM / ASPTM state changes and finally exchange MTP signaling such as ISUP or SCCP on top of it. Routing is currently only based on point codes (PC). Routing table is fully configurable with Destination PC and mask. Shortcomings: * xUA: only "override" traffic mode supported, no load-balance or broadcast * xUA: no SNM supported, i.e. DAVA/DUNA/... messages are neither parsed nor generated * SCCP: no Global Title based Routing (GTR) yet * SCCP: no Global Title Translation (GTT) yet * no M2PA / M2UA sigtran dialects * no classic CS7 based signaling links(E1/T1 TDM) Change-Id: If32227b8d3127c6178e4ee45527ce65f69bc7b1e --- M .gitignore M Makefile.am M configure.ac M include/osmocom/sigtran/osmo_ss7.h M src/osmo_ss7.c A stp/Makefile.am A stp/internal.h R stp/osmo_ss7_vty.c A stp/stp_main.c 9 files changed, 414 insertions(+), 62 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/81/2281/3 diff --git a/.gitignore b/.gitignore index 83f1333..c38bac1 100644 --- a/.gitignore +++ b/.gitignore @@ -62,6 +62,8 @@ examples/m3ua_example +stp/osmo-stp + *.pc config.* diff --git a/Makefile.am b/Makefile.am index dd73ec2..ededdac 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,7 +1,7 @@ AUTOMAKE_OPTIONS = foreign dist-bzip2 1.6 AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -SUBDIRS = include src tests examples +SUBDIRS = include src tests examples stp pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = libosmo-sccp.pc libosmo-mtp.pc libosmo-sigtran.pc libosmo-xua.pc diff --git a/configure.ac b/configure.ac index 6dc0ebd..82c7ee8 100644 --- a/configure.ac +++ b/configure.ac @@ -70,5 +70,6 @@ tests/xua/Makefile tests/ss7/Makefile examples/Makefile + stp/Makefile Makefile) diff --git a/include/osmocom/sigtran/osmo_ss7.h b/include/osmocom/sigtran/osmo_ss7.h index 5becc0e..dff206d 100644 --- a/include/osmocom/sigtran/osmo_ss7.h +++ b/include/osmocom/sigtran/osmo_ss7.h @@ -9,6 +9,8 @@ #include #include +extern struct llist_head osmo_ss7_xua_servers; + struct osmo_ss7_instance; struct osmo_ss7_user; struct osmo_sccp_instance; diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index bb13b43..7ed216a 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -28,6 +28,7 @@ #include #include +#include #include #include @@ -52,7 +53,7 @@ static bool ss7_initialized = false; static LLIST_HEAD(ss7_instances); -static LLIST_HEAD(ss7_xua_servers); +LLIST_HEAD(osmo_ss7_xua_servers); static int32_t next_rctx = 1; static int32_t next_l_rk_id = 1; @@ -1539,7 +1540,7 @@ struct osmo_xua_server *xs; OSMO_ASSERT(ss7_initialized); - llist_for_each_entry(xs, &ss7_xua_servers, list) { + llist_for_each_entry(xs, &osmo_ss7_xua_servers, list) { if (proto == xs->cfg.proto && local_port == xs->cfg.local.port) return xs; @@ -1589,7 +1590,7 @@ } oxs->inst = inst; - llist_add_tail(&oxs->list, &ss7_xua_servers); + llist_add_tail(&oxs->list, &osmo_ss7_xua_servers); return oxs; } diff --git a/stp/Makefile.am b/stp/Makefile.am new file mode 100644 index 0000000..81aa11c --- /dev/null +++ b/stp/Makefile.am @@ -0,0 +1,11 @@ +AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include +AM_CFLAGS=-Wall -g $(LIBOSMOCORE_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(LIBOSMONETIF_CFLAGS) $(COVERAGE_FLAGS) +AM_LDFLAGS=$(COVERAGE_LDFLAGS) + +EXTRA_DIST = internal.h + +bin_PROGRAMS = osmo-stp + +osmo_stp_SOURCES = stp_main.c osmo_ss7_vty.c +osmo_stp_LDADD = $(top_builddir)/src/libosmo-sigtran.la \ + $(LIBOSMOCORE_LIBS) $(LIBOSMOVTY_LIBS) diff --git a/stp/internal.h b/stp/internal.h new file mode 100644 index 0000000..0a434cc --- /dev/null +++ b/stp/internal.h @@ -0,0 +1,18 @@ +#pragma once + +#include + +enum stp_vty_node { + L_CS7_AS_NODE = _LAST_OSMOVTY_NODE + 1, + L_CS7_ASP_NODE, + L_CS7_SUA_NODE, + L_CS7_M3UA_NODE, + L_CS7_RTABLE_NODE, +}; + +int osmo_ss7_vty_init(void); +int osmo_ss7_vty_go_parent(struct vty *vty); +int osmo_ss7_is_config_node(struct vty *vty, int node); + +extern struct osmo_ss7_instance *g_s7i; + diff --git a/src/osmo_ss7_vty.c b/stp/osmo_ss7_vty.c similarity index 68% rename from src/osmo_ss7_vty.c rename to stp/osmo_ss7_vty.c index 80cd4d0..905c4f6 100644 --- a/src/osmo_ss7_vty.c +++ b/stp/osmo_ss7_vty.c @@ -33,6 +33,9 @@ #include #include +#include + +#include "internal.h" #define CS7_STR "ITU-T Signaling System 7\n" #define PC_STR "Point Code\n" @@ -58,7 +61,7 @@ "Reserved Network\n" "Spare Network\n") { - struct osmo_ss7_instance *inst = FIXME; + struct osmo_ss7_instance *inst = g_s7i; int ni = get_string_value(ss7_network_indicator_vals, argv[0]); inst->cfg.network_indicator = ni; @@ -67,13 +70,13 @@ /* TODO: cs7 point-code format */ DEFUN(cs7_pc_format, cs7_pc_format_cmd, - "cs7 point-code format <1-24> [<1-23> [<1-22>]]", + "cs7 point-code format <1-24> [<1-23>] [<1-22>]", CS7_STR PC_STR "Configure Point Code Format\n" "Length of first PC component\n" "Length of second PC component\n" "Length of third PC component\n") { - struct osmo_ss7_instance *inst = FIXME; + struct osmo_ss7_instance *inst = g_s7i; int argind = 0; inst->cfg.pc_fmt.component_len[0] = atoi(argv[argind++]); @@ -96,7 +99,7 @@ CS7_STR PC_STR "Configure Point Code Format\n" "Default Point Code Format (3.8.3)\n") { - struct osmo_ss7_instance *inst = FIXME; + struct osmo_ss7_instance *inst = g_s7i; inst->cfg.pc_fmt.component_len[0] = 3; inst->cfg.pc_fmt.component_len[1] = 8; inst->cfg.pc_fmt.component_len[2] = 3; @@ -111,7 +114,7 @@ "Use dot as delimiter\n" "User dash as delimiter\n") { - struct osmo_ss7_instance *inst = FIXME; + struct osmo_ss7_instance *inst = g_s7i; if (!strcmp(argv[0], "dash")) inst->cfg.pc_fmt.delimiter = '-'; @@ -126,7 +129,7 @@ CS7_STR "Configure the local Point Code\n" "Point Code\n") { - struct osmo_ss7_instance *inst = FIXME; + struct osmo_ss7_instance *inst = g_s7i; uint32_t pc = osmo_ss7_pointcode_parse(inst, argv[0]); inst->cfg.primary_pc = pc; @@ -135,6 +138,40 @@ /* TODO: cs7 secondary-pc */ /* TODO: cs7 capability-pc */ + +static void write_one_ss7_inst(struct vty *vty, struct osmo_ss7_instance *inst) +{ + if (inst->cfg.network_indicator) + vty_out(vty, "cs7 network-indicator %s%s", + get_value_string(ss7_network_indicator_vals, + inst->cfg.network_indicator), + VTY_NEWLINE); + + if (inst->cfg.pc_fmt.component_len[0] != 3 || + inst->cfg.pc_fmt.component_len[1] != 8 || + inst->cfg.pc_fmt.component_len[2] != 3) { + vty_out(vty, "cs7 point-code format %u", + inst->cfg.pc_fmt.component_len[0]); + if (inst->cfg.pc_fmt.component_len[1]) + vty_out(vty, " %u", inst->cfg.pc_fmt.component_len[1]); + if (inst->cfg.pc_fmt.component_len[2]) + vty_out(vty, " %u", inst->cfg.pc_fmt.component_len[2]); + vty_out(vty, "%s", VTY_NEWLINE); + } + + if (inst->cfg.pc_fmt.delimiter != '.') + vty_out(vty, "cs7 point-code delimiter dash%s", VTY_NEWLINE); + + if (inst->cfg.primary_pc) + vty_out(vty, "cs7 point-code %s%s", + osmo_ss7_pointcode_print(inst, inst->cfg.primary_pc), + VTY_NEWLINE); +} + +static void config_write_cs7(struct vty *vty) +{ + write_one_ss7_inst(vty, g_s7i); +} /*********************************************************************** * Routing Table Configuration @@ -151,7 +188,7 @@ CS7_STR "Specify the name of the route table\n" "Name of the route table\n") { - struct osmo_ss7_instance *inst = FIXME; + struct osmo_ss7_instance *inst = g_s7i; struct osmo_ss7_route_table *rtable; rtable = inst->rtable_system; @@ -163,7 +200,7 @@ } DEFUN(cs7_rt_upd, cs7_rt_upd_cmd, - "update route POINT_CODE [MASK | LENGTH] linkset LS_NAME [priority PRIO] [qos-class (CLASS | default", + "update route POINT_CODE MASK linkset LS_NAME [priority PRIO] [qos-class (CLASS|default)]", "Update the Route\n" "Update the Route\n" "Destination Point Code\n" @@ -185,8 +222,11 @@ unsigned int argind; rt = osmo_ss7_route_create(rtable, dpc, mask, ls_name); - if (!rt) + if (!rt) { + vty_out(vty, "cannot create route %s/%s to %s%s", + argv[0], argv[1], argv[2], VTY_NEWLINE); return CMD_WARNING; + } argind = 3; if (argc > argind && !strcmp(argv[argind], "priority")) { @@ -203,7 +243,7 @@ } DEFUN(cs7_rt_rem, cs7_rt_rem_cmd, - "remove route POINT_CODE [MASK | LENGTH]", + "remove route POINT_CODE MASK", "Remove a Route\n" "Remove a Route\n" "Destination Point Code\n" @@ -216,19 +256,22 @@ uint32_t mask = osmo_ss7_pointcode_parse_mask_or_len(rtable->inst, argv[1]); rt = osmo_ss7_route_find_dpc_mask(rtable, dpc, mask); - if (!rt) + if (!rt) { + vty_out(vty, "cannot find route to be deleted%s", VTY_NEWLINE); return CMD_WARNING; + } osmo_ss7_route_destroy(rt); return CMD_SUCCESS; } -static int config_write_rtable(struct vty *vty) +static void write_one_rtable(struct vty *vty, struct osmo_ss7_route_table *rtable) { - struct osmo_ss7_route_table *rtable = vty->index; struct osmo_ss7_route *rt; vty_out(vty, "cs7 route-table %s%s", rtable->cfg.name, VTY_NEWLINE); + if (rtable->cfg.description) + vty_out(vty, " description %s%s", rtable->cfg.description, VTY_NEWLINE); llist_for_each_entry(rt, &rtable->routes, list) { vty_out(vty, " update route %s %s linkset %s", osmo_ss7_pointcode_print(rtable->inst, rt->cfg.pc), @@ -240,6 +283,16 @@ vty_out(vty, " qos-class %u", rt->cfg.qos_class); vty_out(vty, "%s", VTY_NEWLINE); } +} + +static int config_write_rtable(struct vty *vty) +{ + struct osmo_ss7_instance *inst = g_s7i; + struct osmo_ss7_route_table *rtable; + + llist_for_each_entry(rtable, &inst->rtable_list, list) + write_one_rtable(vty, rtable); + return 0; } @@ -259,7 +312,7 @@ "Configure/Enable SUA\n" "SCTP Port number for SUA\n") { - struct osmo_ss7_instance *inst = FIXME; + struct osmo_ss7_instance *inst = g_s7i; struct osmo_xua_server *xs; uint16_t port = atoi(argv[0]); @@ -272,6 +325,24 @@ vty->node = L_CS7_SUA_NODE; vty->index = xs; + return CMD_SUCCESS; +} + +DEFUN(no_cs7_sua, no_cs7_sua_cmd, + "no cs7 sua <0-65534>", + NO_STR CS7_STR "Disable SUA on given SCTP Port\n" + "SCTP Port number for SUA\n") +{ + struct osmo_ss7_instance *inst = g_s7i; + struct osmo_xua_server *xs; + uint16_t port = atoi(argv[0]); + + xs = osmo_ss7_xua_server_find(inst, OSMO_SS7_ASP_PROT_SUA, port); + if (!xs) { + vty_out(vty, "No SUA server for port %u found%s", port, VTY_NEWLINE); + return CMD_WARNING; + } + osmo_ss7_xua_server_destroy(xs); return CMD_SUCCESS; } @@ -291,12 +362,22 @@ return get_string_value(osmo_ss7_asp_protocol_vals, protocol); } +static void write_one_sua(struct vty *vty, struct osmo_xua_server *xs) +{ + vty_out(vty, "cs7 %s %u%s", + get_value_string(osmo_ss7_asp_protocol_vals, xs->cfg.proto), + xs->cfg.local.port, VTY_NEWLINE); + vty_out(vty, " local-ip %s%s", xs->cfg.local.host, VTY_NEWLINE); +} + + static int config_write_sua(struct vty *vty) { - struct osmo_xua_server *xs = vty->index; + struct osmo_xua_server *xs; - vty_out(vty, "cs7 sua %u%s", xs->cfg.local.port, VTY_NEWLINE); - vty_out(vty, " local-ip %s%s", xs->cfg.local.host, VTY_NEWLINE); + llist_for_each_entry(xs, &osmo_ss7_xua_servers, list) + write_one_sua(vty, xs); + return 0; } @@ -316,7 +397,7 @@ "Configure/Enable M3UA\n" "SCTP Port number for M3UA\n") { - struct osmo_ss7_instance *inst = FIXME; + struct osmo_ss7_instance *inst = g_s7i; struct osmo_xua_server *xs; uint16_t port = atoi(argv[0]); @@ -329,6 +410,24 @@ vty->node = L_CS7_M3UA_NODE; vty->index = xs; + return CMD_SUCCESS; +} + +DEFUN(no_cs7_m3ua, no_cs7_m3ua_cmd, + "no cs7 m3ua <0-65534>", + NO_STR CS7_STR "Disable M3UA on given SCTP Port\n" + "SCTP Port number for M3UA\n") +{ + struct osmo_ss7_instance *inst = g_s7i; + struct osmo_xua_server *xs; + uint16_t port = atoi(argv[0]); + + xs = osmo_ss7_xua_server_find(inst, OSMO_SS7_ASP_PROT_M3UA, port); + if (!xs) { + vty_out(vty, "No M3UA server for port %u found%s", port, VTY_NEWLINE); + return CMD_WARNING; + } + osmo_ss7_xua_server_destroy(xs); return CMD_SUCCESS; } @@ -345,10 +444,7 @@ static int config_write_m3ua(struct vty *vty) { - struct osmo_xua_server *xs = vty->index; - - vty_out(vty, "cs7 m3ua %u%s", xs->cfg.local.port, VTY_NEWLINE); - vty_out(vty, " local-ip %s%s", xs->cfg.local.host, VTY_NEWLINE); + /* see config_write_sua */ return 0; } @@ -363,7 +459,7 @@ }; DEFUN(cs7_asp, cs7_asp_cmd, - "cs7 asp NAME <0-65535> <0-65535> [m3ua | sua]", + "cs7 asp NAME <0-65535> <0-65535> (m3ua|sua)", CS7_STR "Configure Application Server Process\n" "Name of ASP\n" @@ -372,19 +468,24 @@ "M3UA Protocol\n" "SUA Protocol\n") { - struct osmo_ss7_instance *inst = FIXME; + struct osmo_ss7_instance *inst = g_s7i; const char *name = argv[0]; uint16_t remote_port = atoi(argv[1]); uint16_t local_port = atoi(argv[2]); enum osmo_ss7_asp_protocol protocol = parse_asp_proto(argv[3]); struct osmo_ss7_asp *asp; - if (protocol == OSMO_SS7_ASP_PROT_NONE) + if (protocol == OSMO_SS7_ASP_PROT_NONE) { + vty_out(vty, "invalid protocol '%s'%s", argv[3], VTY_NEWLINE); return CMD_WARNING; + } asp = osmo_ss7_asp_find_or_create(inst, name, remote_port, local_port, protocol); - if (!asp) + if (!asp) { + vty_out(vty, "cannot create ASP '%s'%s", name, VTY_NEWLINE); return CMD_WARNING; + } + asp->cfg.is_server = true; vty->node = L_CS7_ASP_NODE; vty->index = asp; @@ -392,9 +493,27 @@ return CMD_SUCCESS; } +DEFUN(no_cs7_asp, no_cs7_asp_cmd, + "no cs7 asp NAME", + NO_STR CS7_STR "Disable Application Server Process\n" + "Name of ASP\n") +{ + struct osmo_ss7_instance *inst = g_s7i; + const char *name = argv[0]; + struct osmo_ss7_asp *asp; + + asp = osmo_ss7_asp_find_by_name(inst, name); + if (!asp) { + vty_out(vty, "No ASP named '%s' found%s", name, VTY_NEWLINE); + return CMD_WARNING; + } + osmo_ss7_asp_destroy(asp); + return CMD_SUCCESS; +} + DEFUN(asp_remote_ip, asp_remote_ip_cmd, "remote-ip A.B.C.D", - "Specity Remote IP Address of ASP\n" + "Specify Remote IP Address of ASP\n" "Remote IP Address of ASP\n") { struct osmo_ss7_asp *asp = vty->index; @@ -404,7 +523,7 @@ DEFUN(asp_qos_clas, asp_qos_class_cmd, "qos-class <0-255>", - "Specity QoS Class of ASP\n" + "Specify QoS Class of ASP\n" "QoS Class of ASP\n") { struct osmo_ss7_asp *asp = vty->index; @@ -416,8 +535,8 @@ "block", "Allows a SCTP Association with ASP, but doesn't let it become active\n") { - struct osmo_ss7_asp *asp = vty->index; - vty_out(vty, "Not supported yet\n"); + /* TODO */ + vty_out(vty, "Not supported yet%s", VTY_NEWLINE); return CMD_WARNING; } @@ -425,23 +544,34 @@ "shutdown", "Terminates SCTP association; New associations will be rejected\n") { - struct osmo_ss7_asp *asp = vty->index; - vty_out(vty, "Not supported yet\n"); + /* TODO */ + vty_out(vty, "Not supported yet%s", VTY_NEWLINE); return CMD_WARNING; +} + +static void write_one_asp(struct vty *vty, struct osmo_ss7_asp *asp) +{ + vty_out(vty, "cs7 asp %s %u %u %s%s", + asp->cfg.name, asp->cfg.remote.port, asp->cfg.local.port, + osmo_ss7_asp_protocol_name(asp->cfg.proto), VTY_NEWLINE); + if (asp->cfg.description) + vty_out(vty, " description %s%s", asp->cfg.description, VTY_NEWLINE); + vty_out(vty, " remote-ip %s%s", asp->cfg.remote.host, VTY_NEWLINE); + if (asp->cfg.qos_class) + vty_out(vty, " qos-class %u%s", asp->cfg.qos_class, VTY_NEWLINE); } static int config_write_asp(struct vty *vty) { - struct osmo_ss7_asp *asp = vty->index; + struct osmo_ss7_instance *inst = g_s7i; + struct osmo_ss7_asp *asp; - vty_out(vty, "cs7 asp %s %u %u %s%s", - asp->cfg.name, asp->cfg.remote.port, asp->cfg.local.port, - osmo_ss7_asp_protocol_name(asp->cfg.proto), VTY_NEWLINE); - vty_out(vty, " remote-ip %s%s", asp->cfg.remote.host, VTY_NEWLINE); - if (asp->cfg.qos_class) - vty_out(vty, " qos-class %u%s", asp->cfg.qos_class, VTY_NEWLINE); + llist_for_each_entry(asp, &inst->asp_list, list) + write_one_asp(vty, asp); + return 0; } + /*********************************************************************** * Application Server @@ -454,27 +584,53 @@ }; DEFUN(cs7_as, cs7_as_cmd, - "cs7 as NAME [m3ua | sua]", + "cs7 as NAME (m3ua|sua)", CS7_STR "Configure an Application Server\n" "Name of the Application Server\n" "M3UA Application Server\n" "SUA Application Server\n") { + struct osmo_ss7_instance *inst = g_s7i; struct osmo_ss7_as *as; const char *name = argv[0]; enum osmo_ss7_asp_protocol protocol = parse_asp_proto(argv[1]); - if (protocol == OSMO_SS7_ASP_PROT_NONE) + if (protocol == OSMO_SS7_ASP_PROT_NONE) { + vty_out(vty, "invalid protocol '%s'%s", argv[3], VTY_NEWLINE); return CMD_WARNING; + } - /* FIXME */ + as = osmo_ss7_as_find_or_create(inst, name, protocol); + if (!as) { + vty_out(vty, "cannot create AS '%s'%s", name, VTY_NEWLINE); + return CMD_WARNING; + } + as->cfg.name = talloc_strdup(as, name); vty->node = L_CS7_AS_NODE; vty->index = as; vty->index_sub = &as->cfg.description; + return CMD_SUCCESS; +} + +DEFUN(no_cs7_as, no_cs7_as_cmd, + "no cs7 as NAME", + NO_STR CS7_STR "Disable Application Server\n" + "Name of AS\n") +{ + struct osmo_ss7_instance *inst = g_s7i; + const char *name = argv[0]; + struct osmo_ss7_as *as; + + as = osmo_ss7_as_find_by_name(inst, name); + if (!as) { + vty_out(vty, "No AS named '%s' found%s", name, VTY_NEWLINE); + return CMD_WARNING; + } + osmo_ss7_as_destroy(as); return CMD_SUCCESS; } @@ -486,8 +642,10 @@ { struct osmo_ss7_as *as = vty->index; - if (osmo_ss7_as_add_asp(as, argv[0])) + if (osmo_ss7_as_add_asp(as, argv[0])) { + vty_out(vty, "cannot find ASP '%s'%s", argv[0], VTY_NEWLINE); return CMD_WARNING; + } return CMD_SUCCESS; } @@ -499,8 +657,10 @@ { struct osmo_ss7_as *as = vty->index; - if (osmo_ss7_as_del_asp(as, argv[0])) + if (osmo_ss7_as_del_asp(as, argv[0])) { + vty_out(vty, "cannot find ASP '%s'%s", argv[0], VTY_NEWLINE); return CMD_WARNING; + } return CMD_SUCCESS; } @@ -516,7 +676,7 @@ struct osmo_ss7_as *as = vty->index; as->cfg.mode = get_string_value(osmo_ss7_as_traffic_mode_vals, argv[0]); - return CMD_WARNING; + return CMD_SUCCESS; } DEFUN(as_recov_tout, as_recov_tout_cmd, @@ -554,7 +714,7 @@ }; DEFUN(as_rout_key, as_rout_key_cmd, - "routing-key RCONTEXT DPC [si {aal2 | bicc | b-isup | h248 | isup | sat-isup | sccp | tup }] [ssn SSN]}", + "routing-key RCONTEXT DPC [si (aal2|bicc|b-isup|h248|isup|sat-isup|sccp|tup)] [ssn SSN]}", "Define a routing key\n" "Routing context number\n" "Destination Point Code\n" @@ -571,25 +731,21 @@ "Sub-System Number to match on\n") { struct osmo_ss7_as *as = vty->index; - uint32_t key = atoi(argv[0]); - struct osmo_ss7_routing_key *rkey; + struct osmo_ss7_routing_key *rkey = &as->cfg.routing_key; int argind; - rkey = osmo_ss7_rkey_find_or_create(as, key); - if (!rkey) - return CMD_WARNING; - + rkey->context = atoi(argv[0]); rkey->pc = osmo_ss7_pointcode_parse(as->inst, argv[1]); argind = 2; - if (!strcmp(argv[argind], "si")) { + if (argind < argc && !strcmp(argv[argind], "si")) { const char *si_str; argind++; si_str = argv[argind++]; /* parse numeric SI from string */ rkey->si = get_string_value(mtp_si_vals, si_str); } - if (!strcmp(argv[argind], "ssn")) { + if (argind < argc && !strcmp(argv[argind], "ssn")) { argind++; rkey->ssn = atoi(argv[argind]); } @@ -597,14 +753,15 @@ return CMD_SUCCESS; } -static int config_write_as(struct vty *vty) +static void write_one_as(struct vty *vty, struct osmo_ss7_as *as) { - struct osmo_ss7_as *as = vty->index; struct osmo_ss7_routing_key *rkey; unsigned int i; vty_out(vty, "cs7 as %s %s%s", as->cfg.name, osmo_ss7_asp_protocol_name(as->cfg.proto), VTY_NEWLINE); + if (as->cfg.description) + vty_out(vty, " description %s%s", as->cfg.description, VTY_NEWLINE); for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) { struct osmo_ss7_asp *asp = as->cfg.asps[i]; if (!asp) @@ -618,7 +775,8 @@ vty_out(vty, " recovery-timeout %u%s", as->cfg.recovery_timeout_msec, VTY_NEWLINE); } - vty_out(vty, " qos-class %u%s", as->cfg.qos_class, VTY_NEWLINE); + if (as->cfg.qos_class) + vty_out(vty, " qos-class %u%s", as->cfg.qos_class, VTY_NEWLINE); rkey = &as->cfg.routing_key; vty_out(vty, " routing-key %u %s", rkey->context, osmo_ss7_pointcode_print(as->inst, rkey->pc)); @@ -628,8 +786,62 @@ if (rkey->ssn) vty_out(vty, " ssn %u", rkey->ssn); vty_out(vty, "%s", VTY_NEWLINE); +} + +static int config_write_as(struct vty *vty) +{ + struct osmo_ss7_instance *inst = g_s7i; + struct osmo_ss7_as *as; + + /* HACK to call this here, as we cannot install additional + * 'save' code into the root CONFIG_NODE ... */ + config_write_cs7(vty); + + /* HACK to call this here, but we must make sure that the ASP + * are all configured before we reference them from the AS, and + * VTY code always stores the nodes in alphabetical order */ + + config_write_asp(vty); + + llist_for_each_entry(as, &inst->as_list, list) + write_one_as(vty, as); return 0; +} + +int osmo_ss7_vty_go_parent(struct vty *vty) +{ + struct osmo_ss7_asp *asp; + + switch (vty->node) { + case L_CS7_ASP_NODE: + asp = vty->index; + osmo_ss7_asp_restart(asp); + vty->node = CONFIG_NODE; + break; + case L_CS7_RTABLE_NODE: + case L_CS7_SUA_NODE: + case L_CS7_M3UA_NODE: + case L_CS7_AS_NODE: + default: + vty->node = CONFIG_NODE; + break; + } + return 0; +} + +int osmo_ss7_is_config_node(struct vty *vty, int node) +{ + switch (node) { + case L_CS7_ASP_NODE: + case L_CS7_RTABLE_NODE: + case L_CS7_SUA_NODE: + case L_CS7_M3UA_NODE: + case L_CS7_AS_NODE: + return 1; + default: + return 0; + } } int osmo_ss7_vty_init(void) @@ -650,16 +862,19 @@ install_node(&sua_node, config_write_sua); vty_install_default(L_CS7_SUA_NODE); install_element(CONFIG_NODE, &cs7_sua_cmd); + install_element(CONFIG_NODE, &no_cs7_sua_cmd); install_element(L_CS7_SUA_NODE, &sua_local_ip_cmd); install_node(&m3ua_node, config_write_m3ua); vty_install_default(L_CS7_M3UA_NODE); install_element(CONFIG_NODE, &cs7_m3ua_cmd); + install_element(CONFIG_NODE, &no_cs7_m3ua_cmd); install_element(L_CS7_M3UA_NODE, &m3ua_local_ip_cmd); - install_node(&asp_node, config_write_asp); + install_node(&asp_node, NULL); vty_install_default(L_CS7_ASP_NODE); install_element(CONFIG_NODE, &cs7_asp_cmd); + install_element(CONFIG_NODE, &no_cs7_asp_cmd); install_element(L_CS7_ASP_NODE, &cfg_description_cmd); install_element(L_CS7_ASP_NODE, &asp_remote_ip_cmd); install_element(L_CS7_ASP_NODE, &asp_qos_class_cmd); @@ -669,6 +884,7 @@ install_node(&as_node, config_write_as); vty_install_default(L_CS7_AS_NODE); install_element(CONFIG_NODE, &cs7_as_cmd); + install_element(CONFIG_NODE, &no_cs7_as_cmd); install_element(L_CS7_AS_NODE, &cfg_description_cmd); install_element(L_CS7_AS_NODE, &as_asp_cmd); install_element(L_CS7_AS_NODE, &as_no_asp_cmd); diff --git a/stp/stp_main.c b/stp/stp_main.c new file mode 100644 index 0000000..029c0b2 --- /dev/null +++ b/stp/stp_main.c @@ -0,0 +1,101 @@ +/* Osmocom STP (Signal Transfer Point) */ + +/* (C) 2015-2017 by Harald Welte + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "internal.h" + +struct osmo_ss7_instance *g_s7i; + +static const struct log_info_cat log_info_cat[] = { +}; + +static const struct log_info log_info = { + .cat = log_info_cat, + .num_cat = ARRAY_SIZE(log_info_cat), +}; + +/* Hack to enable debug logging for all relevant (used?) subsystems */ +static void init_logging(void) +{ + const int log_cats[] = { DLSS7, DLSUA, DLM3UA, DLSCCP, DLINP }; + unsigned int i; + + osmo_init_logging(&log_info); + + for (i = 0; i < ARRAY_SIZE(log_cats); i++) + log_set_category_filter(osmo_stderr_target, log_cats[i], 1, LOGL_DEBUG); +} + +static struct vty_app_info vty_info = { + .name = "osmo-stp", + .version = PACKAGE_VERSION, + .go_parent_cb = osmo_ss7_vty_go_parent, + .is_config_node = osmo_ss7_is_config_node, +}; + +int main(int argc, char **argv) +{ + char *config_file = "osmo-stp.cfg"; + int rc; + + init_logging(); + osmo_ss7_init(); + osmo_fsm_log_addr(false); + vty_init(&vty_info); + osmo_ss7_vty_init(); + + g_s7i = osmo_ss7_instance_find_or_create(NULL, 0); + + rc = vty_read_config_file(config_file, NULL); + if (rc < 0) { + fprintf(stderr, "Failed to parse the config file '%s'\n", + config_file); + exit(1); + } + + rc = telnet_init_dynif(NULL, NULL, vty_get_bind_addr(), OSMO_VTY_PORT_STP); + if (rc < 0) { + perror("Erro binding VTY port\n"); + exit(1); + } + + while (1) { + osmo_select_main(0); + } +} -- To view, visit https://gerrit.osmocom.org/2281 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: If32227b8d3127c6178e4ee45527ce65f69bc7b1e Gerrit-PatchSet: 3 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max From gerrit-no-reply at lists.osmocom.org Thu Apr 13 16:23:23 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 13 Apr 2017 16:23:23 +0000 Subject: [PATCH] libosmo-sccp[master]: Add a default layer manager using RKM to register PC with SG In-Reply-To: References: Message-ID: Add a default layer manager using RKM to register PC with SG This "default layer manager" can optionally be used by a xUA ASP. It will handle the xUA Layer Manager (xlm) primitives and use them to behave as follows: * bring the ASP into state "INACTIVE" * see if the SG can match our connection (based on IP address + port information) to a statically configured ASP configuration with associated AS(s). If yes, it will send us a NOTIFY message with AS-INACTIVE. * if the above doesn't work, try to dynamically register a routing key using RKM for the point code that was locally confiured on the ASP/client. If that works, the SG will now have created ASP and AS objects as well as a routing key and be able to serve us, sending the NOTIFY with the AS-INACTIVE state. * After either of the two above, we will attempt to transition into ASP-ACTIVE. The SG should send us an AS-ACTIVE notification in return * if anything fails, abort and disconnect the SCTP connection, restart related FSMs and start from scratch Change-Id: I78d4623dd213b5c59007a026a6cc3cfe5c04af50 --- M include/osmocom/sigtran/osmo_ss7.h M include/osmocom/sigtran/sigtran_sap.h M src/Makefile.am M src/osmo_ss7.c M src/sccp_sap.c M src/sccp_user.c M src/xua_asp_fsm.c A src/xua_default_lm_fsm.c M src/xua_internal.h M src/xua_rkm.c 10 files changed, 604 insertions(+), 14 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/83/2283/2 diff --git a/include/osmocom/sigtran/osmo_ss7.h b/include/osmocom/sigtran/osmo_ss7.h index dff206d..c3a81bb 100644 --- a/include/osmocom/sigtran/osmo_ss7.h +++ b/include/osmocom/sigtran/osmo_ss7.h @@ -345,7 +345,8 @@ bool asp_id_present; /* Layer Manager to which we talk */ - struct osmo_xua_layer_manager *lm; + const struct osmo_xua_layer_manager *lm; + void *lm_priv; /*! Were we dynamically allocated */ bool dyn_allocated; @@ -372,6 +373,7 @@ void osmo_ss7_asp_destroy(struct osmo_ss7_asp *asp); int osmo_ss7_asp_send(struct osmo_ss7_asp *asp, struct msgb *msg); int osmo_ss7_asp_restart(struct osmo_ss7_asp *asp); +int osmo_ss7_asp_use_default_lm(struct osmo_ss7_asp *asp, int log_level); #define LOGPASP(asp, subsys, level, fmt, args ...) \ LOGP(subsys, level, "asp-%s: " fmt, (asp)->cfg.name, ## args) diff --git a/include/osmocom/sigtran/sigtran_sap.h b/include/osmocom/sigtran/sigtran_sap.h index 80cfefc..87504c8 100644 --- a/include/osmocom/sigtran/sigtran_sap.h +++ b/include/osmocom/sigtran/sigtran_sap.h @@ -51,10 +51,16 @@ /* routing key */ struct osmo_ss7_routing_key key; enum osmo_ss7_as_traffic_mode traf_mode; + + /* Status: Confirm only */ + uint32_t status; }; struct osmo_xlm_prim_rk_dereg { uint32_t route_ctx; + + /* Status: Confirm only */ + uint32_t status; }; struct osmo_xlm_prim { @@ -62,9 +68,14 @@ union { struct osmo_xlm_prim_notify notify; struct osmo_xlm_prim_error error; + struct osmo_xlm_prim_rk_reg rk_reg; + struct osmo_xlm_prim_rk_dereg rk_dereg; } u; }; #define msgb_xlm_prim(msg) ((struct osmo_xlm_prim *)(msg)->l1h) char *osmo_xlm_prim_name(struct osmo_prim_hdr *oph); + +/* XUA LM-SAP towards stack */ +int osmo_xlm_sap_down(struct osmo_ss7_asp *asp, struct osmo_prim_hdr *oph); diff --git a/src/Makefile.am b/src/Makefile.am index 7867282..f9b87b0 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -28,7 +28,7 @@ libosmo_sigtran_la_SOURCES = sccp_sap.c sua.c m3ua.c xua_msg.c sccp_helpers.c \ sccp2sua.c sccp_scrc.c sccp_sclc.c sccp_scoc.c \ - sccp_user.c xua_rkm.c \ + sccp_user.c xua_rkm.c xua_default_lm_fsm.c \ osmo_ss7.c osmo_ss7_hmrt.c xua_asp_fsm.c xua_as_fsm.c libosmo_sigtran_la_LDFLAGS = -version-info $(LIBVERSION) -no-undefined -export-symbols-regex '^osmo_' libosmo_sigtran_la_LIBADD = $(LIBOSMOCORE_LIBS) $(LIBOSMONETIF_LIBS) $(LIBSCTP_LIBS) diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index 7ed216a..e66414c 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -1635,6 +1635,7 @@ osmo_fsm_register(&sccp_scoc_fsm); osmo_fsm_register(&xua_as_fsm); osmo_fsm_register(&xua_asp_fsm); + osmo_fsm_register(&xua_default_lm_fsm); ss7_initialized = true; return 0; } diff --git a/src/sccp_sap.c b/src/sccp_sap.c index 2211f71..d4580ae 100644 --- a/src/sccp_sap.c +++ b/src/sccp_sap.c @@ -45,11 +45,43 @@ { const char *name = get_value_string(osmo_scu_prim_names, oph->primitive); - prim_name_buf[0] = '\0'; - strncpy(prim_name_buf, name, sizeof(prim_name_buf)-1); - prim_name_buf[sizeof(prim_name_buf)-1] = '\0'; - name = get_value_string(osmo_prim_op_names, oph->operation); - strncat(prim_name_buf, name, sizeof(prim_name_buf)-strlen(prim_name_buf)-2); + snprintf(prim_name_buf, sizeof(prim_name_buf), "%s.%s", name, + get_value_string(osmo_prim_op_names, oph->operation)); + + return prim_name_buf; +} + + +#include + +const struct value_string osmo_xlm_prim_names[] = { + { OSMO_XLM_PRIM_M_SCTP_ESTABLISH, "M-SCTP_ESTABLISH" }, + { OSMO_XLM_PRIM_M_SCTP_RELEASE, "M-SCTP_RELEASE" }, + { OSMO_XLM_PRIM_M_SCTP_RESTART, "M-SCTP_RESTART" }, + { OSMO_XLM_PRIM_M_SCTP_STATUS, "M-SCTP_STATUS" }, + { OSMO_XLM_PRIM_M_ASP_STATUS, "M-ASP_STATUS" }, + { OSMO_XLM_PRIM_M_AS_STATUS, "M-AS_STATUS" }, + { OSMO_XLM_PRIM_M_NOTIFY, "M-NOTIFY" }, + { OSMO_XLM_PRIM_M_ERROR, "M-ERROR" }, + { OSMO_XLM_PRIM_M_ASP_UP, "M-ASP_UP" }, + { OSMO_XLM_PRIM_M_ASP_DOWN, "M-ASP_DOWN" }, + { OSMO_XLM_PRIM_M_ASP_ACTIVE, "M-ASP_ACTIVE" }, + { OSMO_XLM_PRIM_M_ASP_INACTIVE, "M-ASP_INACTIVE" }, + { OSMO_XLM_PRIM_M_AS_ACTIVE, "M-AS_ACTIVE" }, + { OSMO_XLM_PRIM_M_AS_INACTIVE, "M-AS_INACTIVE" }, + { OSMO_XLM_PRIM_M_AS_DOWN, "M-AS_DOWN" }, + /* optional as per spec, not implemented yet */ + { OSMO_XLM_PRIM_M_RK_REG, "M-RK_REG" }, + { OSMO_XLM_PRIM_M_RK_DEREG, "M-RK_DEREG" }, + { 0, NULL }, +}; + +char *osmo_xlm_prim_name(struct osmo_prim_hdr *oph) +{ + const char *name = get_value_string(osmo_xlm_prim_names, oph->primitive); + + snprintf(prim_name_buf, sizeof(prim_name_buf), "%s.%s", name, + get_value_string(osmo_prim_op_names, oph->operation)); return prim_name_buf; } diff --git a/src/sccp_user.c b/src/sccp_user.c index 01a0638..51cc6b1 100644 --- a/src/sccp_user.c +++ b/src/sccp_user.c @@ -274,6 +274,7 @@ asp->cfg.local.host = talloc_strdup(asp, local_ip); asp->cfg.remote.host = talloc_strdup(asp, remote_ip); osmo_ss7_as_add_asp(as, asp_name); + osmo_ss7_asp_use_default_lm(asp, LOGL_DEBUG); talloc_free(asp_name); osmo_ss7_asp_restart(asp); diff --git a/src/xua_asp_fsm.c b/src/xua_asp_fsm.c index 2830334..59887a4 100644 --- a/src/xua_asp_fsm.c +++ b/src/xua_asp_fsm.c @@ -100,10 +100,14 @@ /* Send a XUA LM Primitive to the XUA Layer Manager (LM) */ void xua_asp_send_xlm_prim(struct osmo_ss7_asp *asp, struct osmo_xlm_prim *prim) { - struct osmo_xua_layer_manager *lm = asp->lm; + const struct osmo_xua_layer_manager *lm = asp->lm; if (lm && lm->prim_cb) lm->prim_cb(&prim->oph, asp); + else { + LOGPASP(asp, DLSS7, LOGL_DEBUG, "No Layer Manager, dropping %s\n", + osmo_xlm_prim_name(&prim->oph)); + } msgb_free(prim->oph.msg); } @@ -334,10 +338,11 @@ ENSURE_ASP_OR_IPSP(fi, event); osmo_fsm_inst_state_chg(fi, XUA_ASP_S_INACTIVE, 0, 0); /* inform layer manager */ - send_xlm_prim_simple(fi, OSMO_XLM_PRIM_M_ASP_UP, - PRIM_OP_CONFIRM); - /* FIXME: This hack should be in layer manager? */ - osmo_fsm_inst_dispatch(fi, XUA_ASP_E_M_ASP_ACTIVE_REQ, NULL); + send_xlm_prim_simple(fi, OSMO_XLM_PRIM_M_ASP_UP, PRIM_OP_CONFIRM); + /* This hack should be in layer manager, but let's try + * to be smart in case there is no layer manager */ + if (!asp->lm) + osmo_fsm_inst_dispatch(fi, XUA_ASP_E_M_ASP_ACTIVE_REQ, NULL); break; case XUA_ASP_E_ASPSM_ASPUP: /* only if role SG */ diff --git a/src/xua_default_lm_fsm.c b/src/xua_default_lm_fsm.c new file mode 100644 index 0000000..fc9ba3c --- /dev/null +++ b/src/xua_default_lm_fsm.c @@ -0,0 +1,383 @@ +/* Default XUA Layer Manager */ +/* (C) 2017 by Harald Welte + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/* The idea of this default Layer Manager is as follows: + * - we wait until a SCTP connection is established + * - we issue the ASP-UP request and wait for the ASP being in UP state + * - we wait if we receive a M-NOTIFY indication about any AS in this ASP + * - if that's not received, we use RKM to register a routing context + * for our locally configured ASP and expect a positive registration + * result as well as a NOTIFY indication about AS-ACTIVE afterwards. + */ + +#include + +#include +#include +#include +#include +#include + +#include "xua_internal.h" +#include "xua_asp_fsm.h" + +#define S(x) (1 << (x)) + +enum lm_state { + /* idle state, SCTP not connected */ + S_IDLE, + /* we're waiting for the ASP-UP to be confirmed */ + S_WAIT_ASP_UP, + /* we are waiting for any NOTIFY about an AS in this ASP */ + S_WAIT_NOTIFY, + /* we've sent a RK REG REQ and wait for the result */ + S_RKM_REG, + /* all systems up, we're communicating */ + S_ACTIVE, +}; + +enum lm_event { + LM_E_SCTP_EST_IND, + LM_E_ASP_UP_CONF, + LM_E_NOTIFY_IND, + LM_E_AS_INACTIVE_IND, + LM_E_AS_ACTIVE_IND, + LM_E_AS_STATUS_IND, + LM_E_RKM_REG_CONF, + LM_E_SCTP_DISC_IND, +}; + +static const struct value_string lm_event_names[] = { + { LM_E_SCTP_EST_IND, "SCTP-ESTABLISH.ind" }, + { LM_E_ASP_UP_CONF, "ASP-UP.conf" }, + { LM_E_NOTIFY_IND, "NOTIFY.ind" }, + { LM_E_AS_INACTIVE_IND, "AS-INACTIVE.ind" }, + { LM_E_AS_ACTIVE_IND, "AS-ACTIVE.ind" }, + { LM_E_AS_STATUS_IND, "AS-STATUS.ind" }, + { LM_E_RKM_REG_CONF, "RKM_REG.conf" }, + { LM_E_SCTP_DISC_IND, "SCTP-RELEASE.ind" }, + { 0, NULL } +}; + +enum lm_timer { + T_WAIT_ASP_UP, + T_WAIT_NOTIFY, + T_WAIT_NOTIFY_RKM, + T_WAIT_RK_REG_RESP, +}; + +struct lm_fsm_priv { + struct osmo_ss7_asp *asp; +}; + +static struct osmo_ss7_as *find_first_as_in_asp(struct osmo_ss7_asp *asp) +{ + struct osmo_ss7_as *as; + + llist_for_each_entry(as, &asp->inst->as_list, list) { + unsigned int i; + for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) { + if (as->cfg.asps[i] == asp) + return as; + } + } + + return NULL; +} + +/* handle an incoming RKM registration response */ +static int handle_reg_conf(struct osmo_fsm_inst *fi, uint32_t l_rk_id, uint32_t rctx) +{ + struct lm_fsm_priv *lmp = fi->priv; + struct osmo_ss7_asp *asp = lmp->asp; + struct osmo_ss7_as *as; + + /* update the application server with the routing context as + * allocated/registered by the SG */ + as = osmo_ss7_as_find_by_l_rk_id(asp->inst, l_rk_id); + if (!as) { + LOGPFSM(fi, "RKM Result for unknown l_rk_id %u\n"); + return -EINVAL; + } + as->cfg.routing_key.context = rctx; + + return 0; +} + +static void restart_asp(struct osmo_fsm_inst *fi) +{ + struct lm_fsm_priv *lmp = fi->priv; + struct osmo_ss7_asp *asp = lmp->asp; + int log_level = fi->log_level; + + osmo_ss7_asp_restart(asp); + osmo_fsm_inst_term(fi, OSMO_FSM_TERM_ERROR, NULL); + osmo_ss7_asp_use_default_lm(asp, log_level); +} + + +static void lm_idle(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct lm_fsm_priv *lmp = fi->priv; + + switch (event) { + case LM_E_SCTP_EST_IND: + /* Try to transition to ASP-UP, wait for 20s */ + osmo_fsm_inst_state_chg(fi, S_WAIT_ASP_UP, 20, T_WAIT_ASP_UP); + osmo_fsm_inst_dispatch(lmp->asp->fi, XUA_ASP_E_M_ASP_UP_REQ, NULL); + break; + } +} + +static void lm_wait_asp_up(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + switch (event) { + case LM_E_ASP_UP_CONF: + /* ASP is sup, wait for some time if any NOTIFY + * indications about AS in this ASP are received */ + osmo_fsm_inst_state_chg(fi, S_WAIT_NOTIFY, 2, T_WAIT_NOTIFY); + break; + } +} + + +static int lm_timer_cb(struct osmo_fsm_inst *fi) +{ + struct lm_fsm_priv *lmp = fi->priv; + struct osmo_xlm_prim *prim; + struct osmo_ss7_as *as; + + switch (fi->T) { + case T_WAIT_ASP_UP: + /* we have been waiting for the ASP to come up, but it + * failed to do so */ + restart_asp(fi); + break; + case T_WAIT_NOTIFY: + /* No AS has reported via NOTIFY that is was + * (statically) configured at the SG for this ASP, so + * let's dynamically register */ + osmo_fsm_inst_state_chg(fi, S_RKM_REG, 10, T_WAIT_RK_REG_RESP); + prim = xua_xlm_prim_alloc(OSMO_XLM_PRIM_M_RK_REG, PRIM_OP_REQUEST); + as = find_first_as_in_asp(lmp->asp); + if (!as) { + LOGPFSML(fi, LOGL_ERROR, "Unable to find AS!\n"); + restart_asp(fi); + return 0; + } + /* Fill in settings from first AS (TODO: multiple AS support) */ + prim->u.rk_reg.key = as->cfg.routing_key; + osmo_xlm_sap_down(lmp->asp, &prim->oph); + break; + case T_WAIT_NOTIFY_RKM: + /* No AS has reported via NOTIFY even after dynamic RKM + * configuration */ + restart_asp(fi); + break; + case T_WAIT_RK_REG_RESP: + /* timeout of registration of routing key */ + restart_asp(fi); + break; + } + return 0; +} + +static void lm_wait_notify(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct lm_fsm_priv *lmp = fi->priv; + struct osmo_xlm_prim *oxp = data; + + switch (event) { + case LM_E_NOTIFY_IND: + OSMO_ASSERT(oxp->oph.primitive == OSMO_XLM_PRIM_M_NOTIFY); + OSMO_ASSERT(oxp->oph.operation == PRIM_OP_INDICATION); + if (oxp->u.notify.status_type == M3UA_NOTIFY_T_STATCHG && + (oxp->u.notify.status_info == M3UA_NOTIFY_I_AS_INACT || + oxp->u.notify.status_info == M3UA_NOTIFY_I_AS_PEND)) { + osmo_fsm_inst_state_chg(fi, S_ACTIVE, 0, 0); + osmo_fsm_inst_dispatch(lmp->asp->fi, XUA_ASP_E_M_ASP_ACTIVE_REQ, NULL); + } + break; + case LM_E_AS_INACTIVE_IND: + /* we now know that an AS is associated with this ASP at + * the SG, and that this AS is currently inactive */ + /* request the ASP to go into active state (which + * hopefully will bring the AS to active, too) */ + osmo_fsm_inst_state_chg(fi, S_ACTIVE, 0, 0); + osmo_fsm_inst_dispatch(lmp->asp->fi, XUA_ASP_E_M_ASP_ACTIVE_REQ, NULL); + break; + } +}; + +static void lm_rkm_reg(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct osmo_xlm_prim *oxp; + int rc; + + switch (event) { + case LM_E_RKM_REG_CONF: + oxp = data; + if (oxp->u.rk_reg.status != M3UA_RKM_REG_SUCCESS) { + LOGPFSML(fi, LOGL_NOTICE, "Received RKM_REG_RSP with negative result\n"); + restart_asp(fi); + } else { + rc = handle_reg_conf(fi, oxp->u.rk_reg.key.l_rk_id, oxp->u.rk_reg.key.context); + if (rc < 0) + restart_asp(fi); + /* RKM registration was successful, we can + * transition to WAIT_NOTIFY state and assume + * that an NOTIFY/AS-INACTIVE arrives within 20 + * seconds */ + osmo_fsm_inst_state_chg(fi, S_WAIT_NOTIFY, 20, T_WAIT_NOTIFY_RKM); + } + break; + } +} + +static void lm_active(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct lm_fsm_priv *lmp = fi->priv; + struct osmo_xlm_prim *oxp; + + switch (event) { + case LM_E_AS_INACTIVE_IND: + /* request the ASP to go into active state */ + osmo_fsm_inst_dispatch(lmp->asp->fi, XUA_ASP_E_M_ASP_ACTIVE_REQ, NULL); + break; + case LM_E_NOTIFY_IND: + oxp = data; + OSMO_ASSERT(oxp->oph.primitive == OSMO_XLM_PRIM_M_NOTIFY); + OSMO_ASSERT(oxp->oph.operation == PRIM_OP_INDICATION); + if (oxp->u.notify.status_type == M3UA_NOTIFY_T_STATCHG && + oxp->u.notify.status_info != M3UA_NOTIFY_I_AS_ACT) + restart_asp(fi); + break; + } +} + +static void lm_allstate(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + switch (event) { + case LM_E_SCTP_DISC_IND: + restart_asp(fi); + break; + } +} + +static const struct osmo_fsm_state lm_states[] = { + [S_IDLE] = { + .in_event_mask = S(LM_E_SCTP_EST_IND), + .out_state_mask = S(S_WAIT_ASP_UP), + .name = "IDLE", + .action = lm_idle, + }, + [S_WAIT_ASP_UP] = { + .in_event_mask = S(LM_E_ASP_UP_CONF), + .out_state_mask = S(S_WAIT_NOTIFY), + .name = "WAIT_ASP_UP", + .action = lm_wait_asp_up, + }, + [S_WAIT_NOTIFY] = { + .in_event_mask = S(LM_E_AS_INACTIVE_IND) | S(LM_E_NOTIFY_IND), + .out_state_mask = S(S_RKM_REG) | S(S_ACTIVE), + .name = "WAIT_NOTIFY", + .action = lm_wait_notify, + }, + [S_RKM_REG] = { + .in_event_mask = S(LM_E_RKM_REG_CONF), + .out_state_mask = S(S_WAIT_NOTIFY), + .name = "RKM_REG", + .action = lm_rkm_reg, + }, + [S_ACTIVE] = { + .in_event_mask = S(LM_E_AS_INACTIVE_IND) | S(LM_E_NOTIFY_IND), + .name = "ACTIVE", + .action = lm_active, + }, +}; + +/* Map from incoming XLM SAP primitives towards FSM events */ +static const struct osmo_prim_event_map lm_event_map[] = { + { XUA_SAP_LM, OSMO_XLM_PRIM_M_SCTP_ESTABLISH, PRIM_OP_INDICATION, LM_E_SCTP_EST_IND }, + { XUA_SAP_LM, OSMO_XLM_PRIM_M_SCTP_RELEASE, PRIM_OP_INDICATION, LM_E_SCTP_DISC_IND }, + { XUA_SAP_LM, OSMO_XLM_PRIM_M_ASP_UP, PRIM_OP_CONFIRM, LM_E_ASP_UP_CONF }, + { XUA_SAP_LM, OSMO_XLM_PRIM_M_AS_STATUS, PRIM_OP_INDICATION, LM_E_AS_STATUS_IND }, + { XUA_SAP_LM, OSMO_XLM_PRIM_M_NOTIFY, PRIM_OP_INDICATION, LM_E_NOTIFY_IND }, + { XUA_SAP_LM, OSMO_XLM_PRIM_M_AS_INACTIVE, PRIM_OP_INDICATION, LM_E_AS_INACTIVE_IND }, + { XUA_SAP_LM, OSMO_XLM_PRIM_M_AS_ACTIVE, PRIM_OP_INDICATION, LM_E_AS_ACTIVE_IND }, + { XUA_SAP_LM, OSMO_XLM_PRIM_M_RK_REG, PRIM_OP_CONFIRM, LM_E_RKM_REG_CONF }, + { 0, 0, 0, OSMO_NO_EVENT }, +}; + + +struct osmo_fsm xua_default_lm_fsm = { + .name = "xua_default_lm", + .states = lm_states, + .num_states = ARRAY_SIZE(lm_states), + .timer_cb = lm_timer_cb, + .event_names = lm_event_names, + .allstate_event_mask = S(LM_E_SCTP_DISC_IND), + .allstate_action = lm_allstate, + .log_subsys = DLSS7, +}; + + +/* layer manager primitive call-back function, registered osmo_ss7 */ +static int default_lm_prim_cb(struct osmo_prim_hdr *oph, void *_asp) +{ + struct osmo_ss7_asp *asp = _asp; + struct osmo_fsm_inst *fi = asp->lm_priv; + uint32_t event = osmo_event_for_prim(oph, lm_event_map); + char *prim_name = osmo_xlm_prim_name(oph); + + LOGPFSM(fi, "Received primitive %s\n", prim_name); + + if (event == OSMO_NO_EVENT) { + LOGPFSML(fi, LOGL_NOTICE, "Ignoring primitive %s\n", prim_name); + return 0; + } + + osmo_fsm_inst_dispatch(fi, event, oph); + + return 0; +} + +static const struct osmo_xua_layer_manager default_layer_manager = { + .prim_cb = default_lm_prim_cb, +}; + +int osmo_ss7_asp_use_default_lm(struct osmo_ss7_asp *asp, int log_level) +{ + struct lm_fsm_priv *lmp; + struct osmo_fsm_inst *fi; + + fi = osmo_fsm_inst_alloc(&xua_default_lm_fsm, asp, NULL, log_level, asp->cfg.name); + + lmp = talloc_zero(fi, struct lm_fsm_priv); + if (!lmp) { + osmo_fsm_inst_term(fi, OSMO_FSM_TERM_ERROR, NULL); + return -ENOMEM; + } + lmp->asp = asp; + fi->priv = lmp; + + asp->lm = &default_layer_manager; + asp->lm_priv = fi; + + return 0; +} diff --git a/src/xua_internal.h b/src/xua_internal.h index 171756b..468b7e4 100644 --- a/src/xua_internal.h +++ b/src/xua_internal.h @@ -56,5 +56,6 @@ enum osmo_xlm_prim_type prim_type, enum osmo_prim_operation op); +extern struct osmo_fsm xua_default_lm_fsm; extern const struct value_string m3ua_rkm_reg_status_vals[]; extern const struct value_string m3ua_rkm_dereg_status_vals[]; diff --git a/src/xua_rkm.c b/src/xua_rkm.c index ad6c880..0d576a7 100644 --- a/src/xua_rkm.c +++ b/src/xua_rkm.c @@ -102,6 +102,41 @@ return msg->tail - old_tail; } +static void xua_rkm_send_reg_req(struct osmo_ss7_asp *asp, + const struct osmo_ss7_routing_key *rkey, + enum osmo_ss7_as_traffic_mode traf_mode) +{ + struct msgb *msg = m3ua_msgb_alloc(__func__); + int tmod = osmo_ss7_tmode_to_xua(traf_mode); + + /* One individual Registration Request according to Chapter 3.6.1 */ + msgb_put_u16(msg, M3UA_IEI_ROUT_KEY); /* outer IEI */ + msgb_put_u16(msg, 32 + 4); /* outer length */ + /* nested IEIs */ + msgb_t16l16vp_put_u32(msg, M3UA_IEI_LOC_RKEY_ID, rkey->l_rk_id); + msgb_t16l16vp_put_u32(msg, M3UA_IEI_ROUTE_CTX, rkey->context); + msgb_t16l16vp_put_u32(msg, M3UA_IEI_TRAF_MODE_TYP, tmod); + msgb_t16l16vp_put_u32(msg, M3UA_IEI_DEST_PC, rkey->pc); + + msgb_push_m3ua_hdr(msg, M3UA_MSGC_RKM, M3UA_RKM_REG_REQ); + + osmo_ss7_asp_send(asp, msg); +} + +static void xua_rkm_send_dereg_req(struct osmo_ss7_asp *asp, uint32_t route_ctx) +{ + struct msgb *msg = m3ua_msgb_alloc(__func__); + + /* One individual De-Registration Request according to Chapter 3.6.3 */ + msgb_t16l16vp_put_u32(msg, M3UA_IEI_ROUTE_CTX, route_ctx); + + msgb_push_m3ua_hdr(msg, M3UA_MSGC_RKM, M3UA_RKM_DEREG_REQ); + + osmo_ss7_asp_send(asp, msg); +} + + + /* handle a single registration request IE (nested IEs in 'innner' */ static int handle_rkey_reg(struct osmo_ss7_asp *asp, struct xua_msg *inner, struct msgb *resp) @@ -277,16 +312,110 @@ return 0; } +/* handle a single registration response IE (nested IEs in 'inner' */ +static int handle_rkey_reg_resp(struct osmo_ss7_asp *asp, struct xua_msg *inner) +{ + struct osmo_xlm_prim *oxp; + + if (!xua_msg_find_tag(inner, M3UA_IEI_LOC_RKEY_ID) || + !xua_msg_find_tag(inner, M3UA_IEI_REG_STATUS) || + !xua_msg_find_tag(inner, M3UA_IEI_ROUTE_CTX)) { + LOGPASP(asp, DLSS7, LOGL_NOTICE, "Missing Inner IE in REG RESP\n"); + /* FIXME: ERROR to peer */ + return -1; + } + + oxp = xua_xlm_prim_alloc(OSMO_XLM_PRIM_M_RK_REG, PRIM_OP_CONFIRM); + if (!oxp) + return -1; + + oxp->u.rk_reg.key.l_rk_id = xua_msg_get_u32(inner, M3UA_IEI_LOC_RKEY_ID); + oxp->u.rk_reg.key.context = xua_msg_get_u32(inner, M3UA_IEI_ROUTE_CTX); + oxp->u.rk_reg.status = xua_msg_get_u32(inner, M3UA_IEI_REG_STATUS); + + LOGPASP(asp, DLSS7, LOGL_INFO, "Received RKM REG RES rctx=%u status=%s\n", + oxp->u.rk_reg.key.context, + get_value_string(m3ua_rkm_reg_status_vals, oxp->u.rk_reg.status)); + + /* Send primitive to LM */ + xua_asp_send_xlm_prim(asp, oxp); + + return 0; +} + /* receive a registration response (ASP role) */ static int m3ua_rx_rkm_reg_rsp(struct osmo_ss7_asp *asp, struct xua_msg *xua) { - /* TODO */ + struct xua_msg_part *part; + struct xua_msg *inner = NULL; + + llist_for_each_entry(part, &xua->headers, entry) { + /* skip other IEs and/or short REG_RES IEs */ + if (part->tag != M3UA_IEI_REG_RESULT || part->len < 24) + continue; + + /* we leave the above loop at the first valid + * registration result (we only support one AS per ASP + * for now) */ + inner = xua_from_nested(part); + if (!inner) + continue; + + handle_rkey_reg_resp(asp, inner); + } + return 0; +} + +/* handle a single deregistration response IE (nested IEs in 'inner' */ +static int handle_rkey_dereg_resp(struct osmo_ss7_asp *asp, struct xua_msg *inner) +{ + struct osmo_xlm_prim *oxp; + + if (!xua_msg_find_tag(inner, M3UA_IEI_DEREG_STATUS) || + !xua_msg_find_tag(inner, M3UA_IEI_ROUTE_CTX)) { + LOGPASP(asp, DLSS7, LOGL_NOTICE, "Missing Inner IE in DEREG RESP\n"); + /* FIXME: ERROR to peer */ + return -1; + } + + oxp = xua_xlm_prim_alloc(OSMO_XLM_PRIM_M_RK_DEREG, PRIM_OP_CONFIRM); + if (!oxp) + return -1; + + oxp->u.rk_dereg.route_ctx = xua_msg_get_u32(inner, M3UA_IEI_ROUTE_CTX); + oxp->u.rk_dereg.status = xua_msg_get_u32(inner, M3UA_IEI_DEREG_STATUS); + + LOGPASP(asp, DLSS7, LOGL_INFO, "Received RKM DEREG RES rctx=%u status=%s\n", + oxp->u.rk_reg.key.context, + get_value_string(m3ua_rkm_dereg_status_vals, oxp->u.rk_dereg.status)); + + /* Send primitive to LM */ + xua_asp_send_xlm_prim(asp, oxp); + + return 0; } /* receive a deregistration response (ASP role) */ static int m3ua_rx_rkm_dereg_rsp(struct osmo_ss7_asp *asp, struct xua_msg *xua) { - /* TODO */ + struct xua_msg_part *part; + struct xua_msg *inner = NULL; + + llist_for_each_entry(part, &xua->headers, entry) { + /* skip other IEs and/or short REG_RES IEs */ + if (part->tag != M3UA_IEI_DEREG_RESULT || part->len < 16) + continue; + + /* we leave the above loop at the first valid + * registration result (we only support one AS per ASP + * for now) */ + inner = xua_from_nested(part); + if (!inner) + continue; + + handle_rkey_dereg_resp(asp, inner); + } + return 0; } /* process an incoming RKM message in xua format */ @@ -321,3 +450,28 @@ } return rc; } + +int osmo_xlm_sap_down(struct osmo_ss7_asp *asp, struct osmo_prim_hdr *oph) +{ + struct osmo_xlm_prim *prim = (struct osmo_xlm_prim *) oph; + + LOGPASP(asp, DLSS7, LOGL_DEBUG, "Received XUA Layer Manager Primitive: %s)\n", + osmo_xlm_prim_name(&prim->oph)); + + switch (OSMO_PRIM_HDR(&prim->oph)) { + case OSMO_PRIM(OSMO_XLM_PRIM_M_RK_REG, PRIM_OP_REQUEST): + /* Layer Manager asks us to send a Routing Key Reg Request */ + xua_rkm_send_reg_req(asp, &prim->u.rk_reg.key, prim->u.rk_reg.traf_mode); + break; + case OSMO_PRIM(OSMO_XLM_PRIM_M_RK_DEREG, PRIM_OP_REQUEST): + /* Layer Manager asks us to send a Routing Key De-Reg Request */ + xua_rkm_send_dereg_req(asp, prim->u.rk_dereg.route_ctx); + break; + default: + LOGPASP(asp, DLSS7, LOGL_ERROR, "Unknown XUA Layer Manager Primitive: %s\n", + osmo_xlm_prim_name(&prim->oph)); + break; + } + + return 0; +} -- To view, visit https://gerrit.osmocom.org/2283 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I78d4623dd213b5c59007a026a6cc3cfe5c04af50 Gerrit-PatchSet: 2 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Thu Apr 13 16:23:24 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 13 Apr 2017 16:23:24 +0000 Subject: [PATCH] libosmo-sccp[master]: osmo_ss7_vty: 'show' commands for AS, ASP, route Message-ID: Review at https://gerrit.osmocom.org/2321 osmo_ss7_vty: 'show' commands for AS, ASP, route Change-Id: Ideb74c9396e5385f6a7c30ff8608d34ededa1f4d --- M stp/osmo_ss7_vty.c 1 file changed, 83 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/21/2321/1 diff --git a/stp/osmo_ss7_vty.c b/stp/osmo_ss7_vty.c index 905c4f6..014fa03 100644 --- a/stp/osmo_ss7_vty.c +++ b/stp/osmo_ss7_vty.c @@ -296,6 +296,33 @@ return 0; } +static void vty_dump_rtable(struct vty *vty, struct osmo_ss7_route_table *rtbl) +{ + struct osmo_ss7_route *rt; + + vty_out(vty, "Routing table = %s%s", rtbl->cfg.name, VTY_NEWLINE); + vty_out(vty, "C=Cong Q=QoS P=Prio%s", VTY_NEWLINE); + vty_out(vty, "%s", VTY_NEWLINE); + vty_out(vty, "Destination C Q P Linkset Name Linkset Non-adj Route%s", VTY_NEWLINE); + vty_out(vty, "---------------------- - - - ------------------- ------- ------- -------%s", VTY_NEWLINE); + + llist_for_each_entry(rt, &rtbl->routes, list) { + vty_out(vty, "%-22s %c %c %u %-19s %-7s %-7s %-7s%s", + osmo_ss7_pointcode_print(rtbl->inst, rt->cfg.mask), + ' ', ' ', rt->cfg.priority, rt->cfg.linkset_name, "?", "?", "?", VTY_NEWLINE); + } +} + +DEFUN(show_cs7_route, show_cs7_route_cmd, + "show cs7 route", + SHOW_STR CS7_STR "Routing Table\n") +{ + struct osmo_ss7_instance *inst = g_s7i; + + vty_dump_rtable(vty, inst->rtable_system); + return CMD_SUCCESS; +} + /*********************************************************************** * SUA Configuration ***********************************************************************/ @@ -547,6 +574,26 @@ /* TODO */ vty_out(vty, "Not supported yet%s", VTY_NEWLINE); return CMD_WARNING; +} + +DEFUN(show_cs7_asp, show_cs7_asp_cmd, + "show cs7 asp", + SHOW_STR CS7_STR "Application Server Process (ASP)\n") +{ + struct osmo_ss7_instance *inst = g_s7i; + struct osmo_ss7_asp *asp; + + vty_out(vty, " Effect Primary%s", VTY_NEWLINE); + vty_out(vty, "ASP Name AS Name State Type Rmt Port Remote IP Addr SCTP%s", VTY_NEWLINE); + vty_out(vty, "------------ ------------ -------- ---- -------- --------------- ----------%s", VTY_NEWLINE); + + llist_for_each_entry(asp, &inst->asp_list, list) { + vty_out(vty, "%-12s %-12s %-8s %-4s %-8u %-15s %-10s%s", + asp->cfg.name, "?", "?", + get_value_string(osmo_ss7_asp_protocol_vals, asp->cfg.proto), + asp->cfg.remote.port, asp->cfg.remote.host, "", VTY_NEWLINE); + } + return CMD_SUCCESS; } static void write_one_asp(struct vty *vty, struct osmo_ss7_asp *asp) @@ -809,6 +856,39 @@ return 0; } +DEFUN(show_cs7_as, show_cs7_as_cmd, + "show cs7 as (active|all|m3ua|sua)", + SHOW_STR CS7_STR "Application Server (AS)\n" + "Display all active ASs\n" + "Display all ASs (default)\n" + "Display all m3ua ASs\n" + "Display all SUA ASs\n") +{ + struct osmo_ss7_instance *inst = g_s7i; + struct osmo_ss7_as *as; + const char *filter = NULL; + + if (argc) + filter = argv[0]; + + vty_out(vty, " Routing Routing Key Cic Cic%s", VTY_NEWLINE); + vty_out(vty, "AS Name State Context Dpc Si Opc Ssn Min Max%s", VTY_NEWLINE); + vty_out(vty, "------------ ------ ---------- ------------- ---- ------------- --- ----- -----%s", VTY_NEWLINE); + + llist_for_each_entry(as, &inst->as_list, list) { + if (filter && !strcmp(filter, "m3ua") && as->cfg.proto != OSMO_SS7_ASP_PROT_M3UA) + continue; + if (filter && !strcmp(filter, "sua") && as->cfg.proto != OSMO_SS7_ASP_PROT_SUA) + continue; + /* FIXME: active filter */ + vty_out(vty, "%-12s %-6s %-10u %-13s %4s %13s %3s %5s %4s%s", + as->cfg.name, "fixme", as->cfg.routing_key.context, + osmo_ss7_pointcode_print(as->inst, as->cfg.routing_key.pc), + "", "", "", "", "", VTY_NEWLINE); + } + return CMD_SUCCESS; +} + int osmo_ss7_vty_go_parent(struct vty *vty) { struct osmo_ss7_asp *asp; @@ -854,6 +934,7 @@ install_node(&rtable_node, config_write_rtable); vty_install_default(L_CS7_RTABLE_NODE); + install_element_ve(&show_cs7_route_cmd); install_element(CONFIG_NODE, &cs7_route_table_cmd); install_element(L_CS7_RTABLE_NODE, &cfg_description_cmd); install_element(L_CS7_RTABLE_NODE, &cs7_rt_upd_cmd); @@ -873,6 +954,7 @@ install_node(&asp_node, NULL); vty_install_default(L_CS7_ASP_NODE); + install_element_ve(&show_cs7_asp_cmd); install_element(CONFIG_NODE, &cs7_asp_cmd); install_element(CONFIG_NODE, &no_cs7_asp_cmd); install_element(L_CS7_ASP_NODE, &cfg_description_cmd); @@ -883,6 +965,7 @@ install_node(&as_node, config_write_as); vty_install_default(L_CS7_AS_NODE); + install_element_ve(&show_cs7_as_cmd); install_element(CONFIG_NODE, &cs7_as_cmd); install_element(CONFIG_NODE, &no_cs7_as_cmd); install_element(L_CS7_AS_NODE, &cfg_description_cmd); -- To view, visit https://gerrit.osmocom.org/2321 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ideb74c9396e5385f6a7c30ff8608d34ededa1f4d Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Thu Apr 13 16:23:25 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 13 Apr 2017 16:23:25 +0000 Subject: [PATCH] libosmo-sccp[master]: xua_rkm: Improve comments about functions Message-ID: Review at https://gerrit.osmocom.org/2322 xua_rkm: Improve comments about functions Change-Id: I2f17baae37718e277eae54d4d225f8fcb2eb4aae --- M src/xua_rkm.c 1 file changed, 13 insertions(+), 10 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/22/2322/1 diff --git a/src/xua_rkm.c b/src/xua_rkm.c index 0d576a7..aa29866 100644 --- a/src/xua_rkm.c +++ b/src/xua_rkm.c @@ -69,7 +69,7 @@ hdr->msg_length = htonl(msgb_l2len(msg)); } -/* append a single registration result to given msgb */ +/* SG: append a single registration result to given msgb */ static int msgb_append_reg_res(struct msgb *msg, uint32_t local_rk_id, uint32_t status, uint32_t rctx) { @@ -86,7 +86,7 @@ return msg->tail - old_tail; } -/* append a single de-registration result to given msgb */ +/* SG: append a single de-registration result to given msgb */ static int msgb_append_dereg_res(struct msgb *msg, uint32_t status, uint32_t rctx) { @@ -102,6 +102,7 @@ return msg->tail - old_tail; } +/* ASP: send a RKM Registration Request message for a single routing key */ static void xua_rkm_send_reg_req(struct osmo_ss7_asp *asp, const struct osmo_ss7_routing_key *rkey, enum osmo_ss7_as_traffic_mode traf_mode) @@ -123,6 +124,7 @@ osmo_ss7_asp_send(asp, msg); } +/* ASP: send a RKM De-Registration Request message for a single routing context */ static void xua_rkm_send_dereg_req(struct osmo_ss7_asp *asp, uint32_t route_ctx) { struct msgb *msg = m3ua_msgb_alloc(__func__); @@ -136,8 +138,7 @@ } - -/* handle a single registration request IE (nested IEs in 'innner' */ +/* SG: handle a single registration request IE (nested IEs in 'innner' */ static int handle_rkey_reg(struct osmo_ss7_asp *asp, struct xua_msg *inner, struct msgb *resp) { @@ -225,7 +226,7 @@ return 0; } -/* receive a registration requuest (SG role) */ +/* SG: receive a registration request from ASP */ static int m3ua_rx_rkm_reg_req(struct osmo_ss7_asp *asp, struct xua_msg *xua) { struct xua_msg_part *part; @@ -254,7 +255,7 @@ return 0; } -/* receive a deregistration requuest (SG role) */ +/* SG: handle a single routing key de-registration IE */ static int handle_rkey_dereg(struct osmo_ss7_asp *asp, uint32_t rctx, struct msgb *resp) { @@ -294,6 +295,7 @@ return 0; } +/* SG: receive a De-Registration request from ASP */ static int m3ua_rx_rkm_dereg_req(struct osmo_ss7_asp *asp, struct xua_msg *xua) { struct xua_msg_part *part = xua_msg_find_tag(xua, M3UA_IEI_ROUTE_CTX); @@ -312,7 +314,7 @@ return 0; } -/* handle a single registration response IE (nested IEs in 'inner' */ +/* ASP: handle a single registration response IE (nested IEs in 'inner') */ static int handle_rkey_reg_resp(struct osmo_ss7_asp *asp, struct xua_msg *inner) { struct osmo_xlm_prim *oxp; @@ -343,7 +345,7 @@ return 0; } -/* receive a registration response (ASP role) */ +/* ASP: receive a registration response (ASP role) */ static int m3ua_rx_rkm_reg_rsp(struct osmo_ss7_asp *asp, struct xua_msg *xua) { struct xua_msg_part *part; @@ -366,7 +368,7 @@ return 0; } -/* handle a single deregistration response IE (nested IEs in 'inner' */ +/* ASP: handle a single De-Registration response IE (nested IEs in 'inner' */ static int handle_rkey_dereg_resp(struct osmo_ss7_asp *asp, struct xua_msg *inner) { struct osmo_xlm_prim *oxp; @@ -395,7 +397,7 @@ return 0; } -/* receive a deregistration response (ASP role) */ +/* ASP: receive a De-Registration response */ static int m3ua_rx_rkm_dereg_rsp(struct osmo_ss7_asp *asp, struct xua_msg *xua) { struct xua_msg_part *part; @@ -451,6 +453,7 @@ return rc; } +/* process a primitive from the xUA Layer Manager (LM) */ int osmo_xlm_sap_down(struct osmo_ss7_asp *asp, struct osmo_prim_hdr *oph) { struct osmo_xlm_prim *prim = (struct osmo_xlm_prim *) oph; -- To view, visit https://gerrit.osmocom.org/2322 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I2f17baae37718e277eae54d4d225f8fcb2eb4aae Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Thu Apr 13 16:23:25 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 13 Apr 2017 16:23:25 +0000 Subject: [PATCH] libosmo-sccp[master]: xua_rkm: Make dynamic registration of Routing Keys work Message-ID: Review at https://gerrit.osmocom.org/2323 xua_rkm: Make dynamic registration of Routing Keys work The existign xua_rkm code was merged a bit pre-maturely as it was not properly tested. This adds a lot of fixes to make it work at all in the first place, as well as the configurable option for fully dynamic routing key management, where ASs and routing keys must not be configured statically by administrative means, but clients (ASPs) can simply come and register for whatever point code they want. Change-Id: I79a070fa7b271b44995511f7b3ff7cc6beec8278 --- M include/osmocom/sigtran/osmo_ss7.h M src/xua_rkm.c 2 files changed, 100 insertions(+), 30 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/23/2323/1 diff --git a/include/osmocom/sigtran/osmo_ss7.h b/include/osmocom/sigtran/osmo_ss7.h index c3a81bb..49a8ca5 100644 --- a/include/osmocom/sigtran/osmo_ss7.h +++ b/include/osmocom/sigtran/osmo_ss7.h @@ -86,6 +86,7 @@ /* capability PCs */ uint8_t network_indicator; struct osmo_ss7_pc_fmt pc_fmt; + bool permit_dyn_rkm_alloc; } cfg; }; @@ -276,6 +277,9 @@ /*! AS FSM */ struct osmo_fsm_inst *fi; + /*! Were we dynamically allocated by RKM? */ + bool rkm_dyn_allocated; + struct { char *name; char *description; diff --git a/src/xua_rkm.c b/src/xua_rkm.c index aa29866..38cbbda 100644 --- a/src/xua_rkm.c +++ b/src/xua_rkm.c @@ -16,6 +16,7 @@ * along with this program. If not, see . */ +#include #include #include @@ -26,6 +27,7 @@ #include #include "xua_internal.h" +#include "xua_as_fsm.h" const struct value_string m3ua_rkm_reg_status_vals[] = { { M3UA_RKM_REG_SUCCESS, "SUCCESS" }, @@ -137,11 +139,15 @@ osmo_ss7_asp_send(asp, msg); } +/* maximum number of newly-assigned Application Servers in one dynamic + * RKM REG request */ +#define MAX_NEW_AS 16 /* SG: handle a single registration request IE (nested IEs in 'innner' */ static int handle_rkey_reg(struct osmo_ss7_asp *asp, struct xua_msg *inner, - struct msgb *resp) + struct msgb *resp, struct osmo_ss7_as **newly_assigned_as) { + unsigned int nas_idx = 0; uint32_t rk_id, rctx, _tmode, dpc; enum osmo_ss7_as_traffic_mode tmode; struct osmo_ss7_as *as; @@ -188,35 +194,67 @@ LOGPASP(asp, DLSS7, LOGL_INFO, "RKM: Registering routing key %u for DPC %s\n", rctx, osmo_ss7_pointcode_print(asp->inst, dpc)); + /* We have two cases here: + * a) pre-configured routing context on both ASP and SG: We will + * find the AS based on the RCTX send by the client, check if + * the routing key matches, associated AS with ASP and return + * success. + * b) no routing context set on ASP, no pre-existing AS + * definition on SG. We have to create the AS, set the RK, + * allocate the RCTX and return that RCTX to the client. This + * is a slightly non-standard interpretation of M3UA RKM + * which requires the SG to not have a-priori-knowledge of + * all AS/RK in situations where the ASP are trusted. + */ + /* check if there is already an AS for this routing key */ - if (osmo_ss7_as_find_by_rctx(asp->inst, rctx)) { - LOGPASP(asp, DLSS7, LOGL_NOTICE, "RKM: RCTX %u already in use\n", rctx); - msgb_append_reg_res(resp, rk_id, M3UA_RKM_REG_ERR_RKEY_ALRDY_REGD, 0); - return -1; - } + as = osmo_ss7_as_find_by_rctx(asp->inst, rctx); + if (as) { + LOGPASP(asp, DLSS7, LOGL_NOTICE, "RKM: Found existing AS for RCTX %u\n", rctx); + if (as->cfg.routing_key.pc != dpc) { + LOGPASP(asp, DLSS7, LOGL_NOTICE, "RKM: DPC doesn't match (%u != %u)\n", + as->cfg.routing_key.pc, dpc); + msgb_append_reg_res(resp, rk_id, M3UA_RKM_REG_ERR_INVAL_RKEY, 0); + return -1; + } + } else if (asp->inst->cfg.permit_dyn_rkm_alloc) { + /* Create an AS for this routing key */ + snprintf(namebuf, sizeof(namebuf), "as-rkm-%u", rctx); + as = osmo_ss7_as_find_or_create(asp->inst, namebuf, OSMO_SS7_ASP_PROT_M3UA); + if (!as) { + LOGPASP(asp, DLSS7, LOGL_ERROR, "RKM: Cannot create AS %s\n", namebuf); + msgb_append_reg_res(resp, rk_id, M3UA_RKM_REG_ERR_INSUFF_RESRC, 0); + return -1; + } - /* Create an AS for this routing key */ - snprintf(namebuf, sizeof(namebuf), "as-rkm-%u", rctx); - as = osmo_ss7_as_find_or_create(asp->inst, namebuf, OSMO_SS7_ASP_PROT_M3UA); - if (!as) { - LOGPASP(asp, DLSS7, LOGL_ERROR, "RKM: Cannot create AS %s\n", namebuf); - msgb_append_reg_res(resp, rk_id, M3UA_RKM_REG_ERR_INSUFF_RESRC, 0); - return -1; - } + as->cfg.description = talloc_strdup(as, "Auto-generated by RKM"); + as->rkm_dyn_allocated = true; + as->cfg.mode = tmode; + /* fill routing key */ + as->cfg.routing_key.pc = dpc; + as->cfg.routing_key.context = rctx; - as->cfg.description = talloc_strdup(as, "Auto-generated by RKM"); - as->cfg.mode = tmode; - /* fill routing key */ - as->cfg.routing_key.context = rctx; - as->cfg.routing_key.pc = dpc; + /* add route for that routing key */ + rt = osmo_ss7_route_create(as->inst->rtable_system, dpc, 0xFFFFFF, namebuf); + if (!rt) { + LOGPASP(asp, DLSS7, LOGL_ERROR, "RKM: Cannot insert route for DPC %s / as %s\n", + osmo_ss7_pointcode_print(asp->inst, dpc), namebuf); + osmo_ss7_as_destroy(as); + msgb_append_reg_res(resp, rk_id, M3UA_RKM_REG_ERR_CANT_SUPP_UNQ_RT, 0); + return -1; + } - /* add route for that routing key */ - rt = osmo_ss7_route_create(as->inst->rtable_system, dpc, 0xFFFFFF, namebuf); - if (!rt) { - LOGPASP(asp, DLSS7, LOGL_ERROR, "RKM: Cannot insert route for DPC %s / as %s\n", - osmo_ss7_pointcode_print(asp->inst, dpc), namebuf); - osmo_ss7_as_destroy(as); - msgb_append_reg_res(resp, rk_id, M3UA_RKM_REG_ERR_CANT_SUPP_UNQ_RT, 0); + /* append to list of newly assigned as */ + if (nas_idx >= MAX_NEW_AS) { + osmo_ss7_route_destroy(rt); + osmo_ss7_as_destroy(as); + msgb_append_reg_res(resp, rk_id, M3UA_RKM_REG_ERR_INSUFF_RESRC, 0); + return -1; + } + newly_assigned_as[nas_idx++] = as; + } else { + /* not permitted to create dynamic RKM entries */ + msgb_append_reg_res(resp, rk_id, M3UA_RKM_REG_ERR_PERM_DENIED, 0); return -1; } @@ -231,6 +269,10 @@ { struct xua_msg_part *part; struct msgb *resp = m3ua_msgb_alloc(__func__); + struct osmo_ss7_as *newly_assigned_as[MAX_NEW_AS]; + unsigned int i; + + memset(newly_assigned_as, 0, sizeof(newly_assigned_as)); /* iterate over all routing key IEs in message */ llist_for_each_entry(part, &xua->headers, entry) { @@ -247,10 +289,24 @@ } /* handle single registration and append result to * 'resp' */ - handle_rkey_reg(asp, inner, resp); + handle_rkey_reg(asp, inner, resp, newly_assigned_as); + + xua_msg_free(inner); } + /* now first send the RKM REG Response */ msgb_push_m3ua_hdr(resp, M3UA_MSGC_RKM, M3UA_RKM_REG_RSP); osmo_ss7_asp_send(asp, resp); + + /* and *after* the RKM REG Response inform the newly assigned + * ASs about the fact that there's an INACTIVE ASP for them, + * which will cause them to send NOTIFY to the client */ + for (i = 0; i < ARRAY_SIZE(newly_assigned_as); i++) { + struct osmo_ss7_as *as = newly_assigned_as[i]; + if (!as) + continue; + /* Notify AS that it has an INACTIVE ASP */ + osmo_fsm_inst_dispatch(as->fi, XUA_ASPAS_ASP_INACTIVE_IND, asp); + } return 0; } @@ -286,9 +342,19 @@ LOGPASP(asp, DLSS7, LOGL_INFO, "RKM: De-Registering rctx %u for DPC %s\n", rctx, osmo_ss7_pointcode_print(inst, as->cfg.routing_key.pc)); - /* remove route + AS definition */ - osmo_ss7_route_destroy(rt); - osmo_ss7_as_destroy(as); + /* remove ASP from AS */ + osmo_ss7_as_del_asp(as, asp->cfg.name); + /* FIXME: Rather than spoofing teh ASP-DOWN.ind to the AS here, + * we should refuse RKM DEREG if the ASP is still ACTIVE */ + osmo_fsm_inst_dispatch(as->fi, XUA_ASPAS_ASP_DOWN_IND, asp); + + /* if we were dynamically allocated, release the associated + * route and destroy the AS */ + if (as->rkm_dyn_allocated) { + /* remove route + AS definition */ + osmo_ss7_route_destroy(rt); + osmo_ss7_as_destroy(as); + } /* report success */ msgb_append_dereg_res(resp, M3UA_RKM_DEREG_SUCCESS, rctx); -- To view, visit https://gerrit.osmocom.org/2323 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I79a070fa7b271b44995511f7b3ff7cc6beec8278 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Thu Apr 13 16:23:26 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 13 Apr 2017 16:23:26 +0000 Subject: [PATCH] libosmo-sccp[master]: osmo_ss7: Release any dynamically-allocated ASs Message-ID: Review at https://gerrit.osmocom.org/2324 osmo_ss7: Release any dynamically-allocated ASs When RKM dynamically allocates ASs on the SGP based on RKM registration requests, we must make sure to properly destroy those at the time the related ASP disconnects. Also, make sure to send XUA_ASP_E_SCTP_COMM_DOWN_IND to the layer manager (if any). Change-Id: Ie6505680bb6890814ae36858c54a2a6d2850f5cf --- M src/osmo_ss7.c M src/xua_internal.h M src/xua_rkm.c 3 files changed, 23 insertions(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/24/2324/1 diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index e66414c..d864916 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -1401,7 +1401,11 @@ LOGP(DLSS7, LOGL_INFO, "%s: SCTP connection closed\n", asp ? asp->cfg.name : "?"); - /* FIXME: somehow notify ASP FSM and everyone else */ + /* notify ASP FSM and everyone else */ + osmo_fsm_inst_dispatch(asp->fi, XUA_ASP_E_SCTP_COMM_DOWN_IND, NULL); + + /* delete any RKM-dynamically allocated ASs for this ASP */ + xua_rkm_cleanup_dyn_as_for_asp(asp); /* send M-SCTP_RELEASE.ind to Layer Manager */ xua_asp_send_xlm_prim_simple(asp, OSMO_XLM_PRIM_M_SCTP_RELEASE, PRIM_OP_INDICATION); diff --git a/src/xua_internal.h b/src/xua_internal.h index 468b7e4..b291703 100644 --- a/src/xua_internal.h +++ b/src/xua_internal.h @@ -47,6 +47,7 @@ int m3ua_decode_notify(struct osmo_xlm_prim_notify *npar, void *ctx, const struct xua_msg *xua); int m3ua_rx_rkm(struct osmo_ss7_asp *asp, struct xua_msg *xua); +void xua_rkm_cleanup_dyn_as_for_asp(struct osmo_ss7_asp *asp); struct osmo_xlm_prim *xua_xlm_prim_alloc(enum osmo_xlm_prim_type prim_type, enum osmo_prim_operation op); diff --git a/src/xua_rkm.c b/src/xua_rkm.c index 38cbbda..62abfdd 100644 --- a/src/xua_rkm.c +++ b/src/xua_rkm.c @@ -544,3 +544,20 @@ return 0; } + +/* clean-up any dynamically created ASs + routes */ +void xua_rkm_cleanup_dyn_as_for_asp(struct osmo_ss7_asp *asp) +{ + struct osmo_ss7_instance *inst = asp->inst; + struct osmo_ss7_as *as, *as2; + + llist_for_each_entry_safe(as, as2, &inst->as_list, list) { + if (!osmo_ss7_as_has_asp(as, asp)) + continue; + /* FIXME: check if there are no other ASPs! */ + if (!as->rkm_dyn_allocated) + continue; + + osmo_ss7_as_destroy(as); + } +} -- To view, visit https://gerrit.osmocom.org/2324 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ie6505680bb6890814ae36858c54a2a6d2850f5cf Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Thu Apr 13 16:25:14 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 13 Apr 2017 16:25:14 +0000 Subject: libosmo-sccp[master]: Add osmo-stp executable as new "Osmocom Signaling Transfer P... In-Reply-To: References: Message-ID: Patch Set 3: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2281 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: If32227b8d3127c6178e4ee45527ce65f69bc7b1e Gerrit-PatchSet: 3 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Apr 13 16:25:16 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 13 Apr 2017 16:25:16 +0000 Subject: [MERGED] libosmo-sccp[master]: Add osmo-stp executable as new "Osmocom Signaling Transfer P... In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: Add osmo-stp executable as new "Osmocom Signaling Transfer Point" ...................................................................... Add osmo-stp executable as new "Osmocom Signaling Transfer Point" osmo-stp is able to define multiple M3UA and/or SUA application servers (AS) as well as application server processes (ASPs). Clients can then connect via M3UA or SUA, perform the respective ASPSM / ASPTM state changes and finally exchange MTP signaling such as ISUP or SCCP on top of it. Routing is currently only based on point codes (PC). Routing table is fully configurable with Destination PC and mask. Shortcomings: * xUA: only "override" traffic mode supported, no load-balance or broadcast * xUA: no SNM supported, i.e. DAVA/DUNA/... messages are neither parsed nor generated * SCCP: no Global Title based Routing (GTR) yet * SCCP: no Global Title Translation (GTT) yet * no M2PA / M2UA sigtran dialects * no classic CS7 based signaling links(E1/T1 TDM) Change-Id: If32227b8d3127c6178e4ee45527ce65f69bc7b1e --- M .gitignore M Makefile.am M configure.ac M include/osmocom/sigtran/osmo_ss7.h M src/osmo_ss7.c A stp/Makefile.am A stp/internal.h R stp/osmo_ss7_vty.c A stp/stp_main.c 9 files changed, 414 insertions(+), 62 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/.gitignore b/.gitignore index 83f1333..c38bac1 100644 --- a/.gitignore +++ b/.gitignore @@ -62,6 +62,8 @@ examples/m3ua_example +stp/osmo-stp + *.pc config.* diff --git a/Makefile.am b/Makefile.am index dd73ec2..ededdac 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,7 +1,7 @@ AUTOMAKE_OPTIONS = foreign dist-bzip2 1.6 AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -SUBDIRS = include src tests examples +SUBDIRS = include src tests examples stp pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = libosmo-sccp.pc libosmo-mtp.pc libosmo-sigtran.pc libosmo-xua.pc diff --git a/configure.ac b/configure.ac index 6dc0ebd..82c7ee8 100644 --- a/configure.ac +++ b/configure.ac @@ -70,5 +70,6 @@ tests/xua/Makefile tests/ss7/Makefile examples/Makefile + stp/Makefile Makefile) diff --git a/include/osmocom/sigtran/osmo_ss7.h b/include/osmocom/sigtran/osmo_ss7.h index 5becc0e..dff206d 100644 --- a/include/osmocom/sigtran/osmo_ss7.h +++ b/include/osmocom/sigtran/osmo_ss7.h @@ -9,6 +9,8 @@ #include #include +extern struct llist_head osmo_ss7_xua_servers; + struct osmo_ss7_instance; struct osmo_ss7_user; struct osmo_sccp_instance; diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index bb13b43..7ed216a 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -28,6 +28,7 @@ #include #include +#include #include #include @@ -52,7 +53,7 @@ static bool ss7_initialized = false; static LLIST_HEAD(ss7_instances); -static LLIST_HEAD(ss7_xua_servers); +LLIST_HEAD(osmo_ss7_xua_servers); static int32_t next_rctx = 1; static int32_t next_l_rk_id = 1; @@ -1539,7 +1540,7 @@ struct osmo_xua_server *xs; OSMO_ASSERT(ss7_initialized); - llist_for_each_entry(xs, &ss7_xua_servers, list) { + llist_for_each_entry(xs, &osmo_ss7_xua_servers, list) { if (proto == xs->cfg.proto && local_port == xs->cfg.local.port) return xs; @@ -1589,7 +1590,7 @@ } oxs->inst = inst; - llist_add_tail(&oxs->list, &ss7_xua_servers); + llist_add_tail(&oxs->list, &osmo_ss7_xua_servers); return oxs; } diff --git a/stp/Makefile.am b/stp/Makefile.am new file mode 100644 index 0000000..81aa11c --- /dev/null +++ b/stp/Makefile.am @@ -0,0 +1,11 @@ +AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include +AM_CFLAGS=-Wall -g $(LIBOSMOCORE_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(LIBOSMONETIF_CFLAGS) $(COVERAGE_FLAGS) +AM_LDFLAGS=$(COVERAGE_LDFLAGS) + +EXTRA_DIST = internal.h + +bin_PROGRAMS = osmo-stp + +osmo_stp_SOURCES = stp_main.c osmo_ss7_vty.c +osmo_stp_LDADD = $(top_builddir)/src/libosmo-sigtran.la \ + $(LIBOSMOCORE_LIBS) $(LIBOSMOVTY_LIBS) diff --git a/stp/internal.h b/stp/internal.h new file mode 100644 index 0000000..0a434cc --- /dev/null +++ b/stp/internal.h @@ -0,0 +1,18 @@ +#pragma once + +#include + +enum stp_vty_node { + L_CS7_AS_NODE = _LAST_OSMOVTY_NODE + 1, + L_CS7_ASP_NODE, + L_CS7_SUA_NODE, + L_CS7_M3UA_NODE, + L_CS7_RTABLE_NODE, +}; + +int osmo_ss7_vty_init(void); +int osmo_ss7_vty_go_parent(struct vty *vty); +int osmo_ss7_is_config_node(struct vty *vty, int node); + +extern struct osmo_ss7_instance *g_s7i; + diff --git a/src/osmo_ss7_vty.c b/stp/osmo_ss7_vty.c similarity index 68% rename from src/osmo_ss7_vty.c rename to stp/osmo_ss7_vty.c index 80cd4d0..905c4f6 100644 --- a/src/osmo_ss7_vty.c +++ b/stp/osmo_ss7_vty.c @@ -33,6 +33,9 @@ #include #include +#include + +#include "internal.h" #define CS7_STR "ITU-T Signaling System 7\n" #define PC_STR "Point Code\n" @@ -58,7 +61,7 @@ "Reserved Network\n" "Spare Network\n") { - struct osmo_ss7_instance *inst = FIXME; + struct osmo_ss7_instance *inst = g_s7i; int ni = get_string_value(ss7_network_indicator_vals, argv[0]); inst->cfg.network_indicator = ni; @@ -67,13 +70,13 @@ /* TODO: cs7 point-code format */ DEFUN(cs7_pc_format, cs7_pc_format_cmd, - "cs7 point-code format <1-24> [<1-23> [<1-22>]]", + "cs7 point-code format <1-24> [<1-23>] [<1-22>]", CS7_STR PC_STR "Configure Point Code Format\n" "Length of first PC component\n" "Length of second PC component\n" "Length of third PC component\n") { - struct osmo_ss7_instance *inst = FIXME; + struct osmo_ss7_instance *inst = g_s7i; int argind = 0; inst->cfg.pc_fmt.component_len[0] = atoi(argv[argind++]); @@ -96,7 +99,7 @@ CS7_STR PC_STR "Configure Point Code Format\n" "Default Point Code Format (3.8.3)\n") { - struct osmo_ss7_instance *inst = FIXME; + struct osmo_ss7_instance *inst = g_s7i; inst->cfg.pc_fmt.component_len[0] = 3; inst->cfg.pc_fmt.component_len[1] = 8; inst->cfg.pc_fmt.component_len[2] = 3; @@ -111,7 +114,7 @@ "Use dot as delimiter\n" "User dash as delimiter\n") { - struct osmo_ss7_instance *inst = FIXME; + struct osmo_ss7_instance *inst = g_s7i; if (!strcmp(argv[0], "dash")) inst->cfg.pc_fmt.delimiter = '-'; @@ -126,7 +129,7 @@ CS7_STR "Configure the local Point Code\n" "Point Code\n") { - struct osmo_ss7_instance *inst = FIXME; + struct osmo_ss7_instance *inst = g_s7i; uint32_t pc = osmo_ss7_pointcode_parse(inst, argv[0]); inst->cfg.primary_pc = pc; @@ -135,6 +138,40 @@ /* TODO: cs7 secondary-pc */ /* TODO: cs7 capability-pc */ + +static void write_one_ss7_inst(struct vty *vty, struct osmo_ss7_instance *inst) +{ + if (inst->cfg.network_indicator) + vty_out(vty, "cs7 network-indicator %s%s", + get_value_string(ss7_network_indicator_vals, + inst->cfg.network_indicator), + VTY_NEWLINE); + + if (inst->cfg.pc_fmt.component_len[0] != 3 || + inst->cfg.pc_fmt.component_len[1] != 8 || + inst->cfg.pc_fmt.component_len[2] != 3) { + vty_out(vty, "cs7 point-code format %u", + inst->cfg.pc_fmt.component_len[0]); + if (inst->cfg.pc_fmt.component_len[1]) + vty_out(vty, " %u", inst->cfg.pc_fmt.component_len[1]); + if (inst->cfg.pc_fmt.component_len[2]) + vty_out(vty, " %u", inst->cfg.pc_fmt.component_len[2]); + vty_out(vty, "%s", VTY_NEWLINE); + } + + if (inst->cfg.pc_fmt.delimiter != '.') + vty_out(vty, "cs7 point-code delimiter dash%s", VTY_NEWLINE); + + if (inst->cfg.primary_pc) + vty_out(vty, "cs7 point-code %s%s", + osmo_ss7_pointcode_print(inst, inst->cfg.primary_pc), + VTY_NEWLINE); +} + +static void config_write_cs7(struct vty *vty) +{ + write_one_ss7_inst(vty, g_s7i); +} /*********************************************************************** * Routing Table Configuration @@ -151,7 +188,7 @@ CS7_STR "Specify the name of the route table\n" "Name of the route table\n") { - struct osmo_ss7_instance *inst = FIXME; + struct osmo_ss7_instance *inst = g_s7i; struct osmo_ss7_route_table *rtable; rtable = inst->rtable_system; @@ -163,7 +200,7 @@ } DEFUN(cs7_rt_upd, cs7_rt_upd_cmd, - "update route POINT_CODE [MASK | LENGTH] linkset LS_NAME [priority PRIO] [qos-class (CLASS | default", + "update route POINT_CODE MASK linkset LS_NAME [priority PRIO] [qos-class (CLASS|default)]", "Update the Route\n" "Update the Route\n" "Destination Point Code\n" @@ -185,8 +222,11 @@ unsigned int argind; rt = osmo_ss7_route_create(rtable, dpc, mask, ls_name); - if (!rt) + if (!rt) { + vty_out(vty, "cannot create route %s/%s to %s%s", + argv[0], argv[1], argv[2], VTY_NEWLINE); return CMD_WARNING; + } argind = 3; if (argc > argind && !strcmp(argv[argind], "priority")) { @@ -203,7 +243,7 @@ } DEFUN(cs7_rt_rem, cs7_rt_rem_cmd, - "remove route POINT_CODE [MASK | LENGTH]", + "remove route POINT_CODE MASK", "Remove a Route\n" "Remove a Route\n" "Destination Point Code\n" @@ -216,19 +256,22 @@ uint32_t mask = osmo_ss7_pointcode_parse_mask_or_len(rtable->inst, argv[1]); rt = osmo_ss7_route_find_dpc_mask(rtable, dpc, mask); - if (!rt) + if (!rt) { + vty_out(vty, "cannot find route to be deleted%s", VTY_NEWLINE); return CMD_WARNING; + } osmo_ss7_route_destroy(rt); return CMD_SUCCESS; } -static int config_write_rtable(struct vty *vty) +static void write_one_rtable(struct vty *vty, struct osmo_ss7_route_table *rtable) { - struct osmo_ss7_route_table *rtable = vty->index; struct osmo_ss7_route *rt; vty_out(vty, "cs7 route-table %s%s", rtable->cfg.name, VTY_NEWLINE); + if (rtable->cfg.description) + vty_out(vty, " description %s%s", rtable->cfg.description, VTY_NEWLINE); llist_for_each_entry(rt, &rtable->routes, list) { vty_out(vty, " update route %s %s linkset %s", osmo_ss7_pointcode_print(rtable->inst, rt->cfg.pc), @@ -240,6 +283,16 @@ vty_out(vty, " qos-class %u", rt->cfg.qos_class); vty_out(vty, "%s", VTY_NEWLINE); } +} + +static int config_write_rtable(struct vty *vty) +{ + struct osmo_ss7_instance *inst = g_s7i; + struct osmo_ss7_route_table *rtable; + + llist_for_each_entry(rtable, &inst->rtable_list, list) + write_one_rtable(vty, rtable); + return 0; } @@ -259,7 +312,7 @@ "Configure/Enable SUA\n" "SCTP Port number for SUA\n") { - struct osmo_ss7_instance *inst = FIXME; + struct osmo_ss7_instance *inst = g_s7i; struct osmo_xua_server *xs; uint16_t port = atoi(argv[0]); @@ -272,6 +325,24 @@ vty->node = L_CS7_SUA_NODE; vty->index = xs; + return CMD_SUCCESS; +} + +DEFUN(no_cs7_sua, no_cs7_sua_cmd, + "no cs7 sua <0-65534>", + NO_STR CS7_STR "Disable SUA on given SCTP Port\n" + "SCTP Port number for SUA\n") +{ + struct osmo_ss7_instance *inst = g_s7i; + struct osmo_xua_server *xs; + uint16_t port = atoi(argv[0]); + + xs = osmo_ss7_xua_server_find(inst, OSMO_SS7_ASP_PROT_SUA, port); + if (!xs) { + vty_out(vty, "No SUA server for port %u found%s", port, VTY_NEWLINE); + return CMD_WARNING; + } + osmo_ss7_xua_server_destroy(xs); return CMD_SUCCESS; } @@ -291,12 +362,22 @@ return get_string_value(osmo_ss7_asp_protocol_vals, protocol); } +static void write_one_sua(struct vty *vty, struct osmo_xua_server *xs) +{ + vty_out(vty, "cs7 %s %u%s", + get_value_string(osmo_ss7_asp_protocol_vals, xs->cfg.proto), + xs->cfg.local.port, VTY_NEWLINE); + vty_out(vty, " local-ip %s%s", xs->cfg.local.host, VTY_NEWLINE); +} + + static int config_write_sua(struct vty *vty) { - struct osmo_xua_server *xs = vty->index; + struct osmo_xua_server *xs; - vty_out(vty, "cs7 sua %u%s", xs->cfg.local.port, VTY_NEWLINE); - vty_out(vty, " local-ip %s%s", xs->cfg.local.host, VTY_NEWLINE); + llist_for_each_entry(xs, &osmo_ss7_xua_servers, list) + write_one_sua(vty, xs); + return 0; } @@ -316,7 +397,7 @@ "Configure/Enable M3UA\n" "SCTP Port number for M3UA\n") { - struct osmo_ss7_instance *inst = FIXME; + struct osmo_ss7_instance *inst = g_s7i; struct osmo_xua_server *xs; uint16_t port = atoi(argv[0]); @@ -329,6 +410,24 @@ vty->node = L_CS7_M3UA_NODE; vty->index = xs; + return CMD_SUCCESS; +} + +DEFUN(no_cs7_m3ua, no_cs7_m3ua_cmd, + "no cs7 m3ua <0-65534>", + NO_STR CS7_STR "Disable M3UA on given SCTP Port\n" + "SCTP Port number for M3UA\n") +{ + struct osmo_ss7_instance *inst = g_s7i; + struct osmo_xua_server *xs; + uint16_t port = atoi(argv[0]); + + xs = osmo_ss7_xua_server_find(inst, OSMO_SS7_ASP_PROT_M3UA, port); + if (!xs) { + vty_out(vty, "No M3UA server for port %u found%s", port, VTY_NEWLINE); + return CMD_WARNING; + } + osmo_ss7_xua_server_destroy(xs); return CMD_SUCCESS; } @@ -345,10 +444,7 @@ static int config_write_m3ua(struct vty *vty) { - struct osmo_xua_server *xs = vty->index; - - vty_out(vty, "cs7 m3ua %u%s", xs->cfg.local.port, VTY_NEWLINE); - vty_out(vty, " local-ip %s%s", xs->cfg.local.host, VTY_NEWLINE); + /* see config_write_sua */ return 0; } @@ -363,7 +459,7 @@ }; DEFUN(cs7_asp, cs7_asp_cmd, - "cs7 asp NAME <0-65535> <0-65535> [m3ua | sua]", + "cs7 asp NAME <0-65535> <0-65535> (m3ua|sua)", CS7_STR "Configure Application Server Process\n" "Name of ASP\n" @@ -372,19 +468,24 @@ "M3UA Protocol\n" "SUA Protocol\n") { - struct osmo_ss7_instance *inst = FIXME; + struct osmo_ss7_instance *inst = g_s7i; const char *name = argv[0]; uint16_t remote_port = atoi(argv[1]); uint16_t local_port = atoi(argv[2]); enum osmo_ss7_asp_protocol protocol = parse_asp_proto(argv[3]); struct osmo_ss7_asp *asp; - if (protocol == OSMO_SS7_ASP_PROT_NONE) + if (protocol == OSMO_SS7_ASP_PROT_NONE) { + vty_out(vty, "invalid protocol '%s'%s", argv[3], VTY_NEWLINE); return CMD_WARNING; + } asp = osmo_ss7_asp_find_or_create(inst, name, remote_port, local_port, protocol); - if (!asp) + if (!asp) { + vty_out(vty, "cannot create ASP '%s'%s", name, VTY_NEWLINE); return CMD_WARNING; + } + asp->cfg.is_server = true; vty->node = L_CS7_ASP_NODE; vty->index = asp; @@ -392,9 +493,27 @@ return CMD_SUCCESS; } +DEFUN(no_cs7_asp, no_cs7_asp_cmd, + "no cs7 asp NAME", + NO_STR CS7_STR "Disable Application Server Process\n" + "Name of ASP\n") +{ + struct osmo_ss7_instance *inst = g_s7i; + const char *name = argv[0]; + struct osmo_ss7_asp *asp; + + asp = osmo_ss7_asp_find_by_name(inst, name); + if (!asp) { + vty_out(vty, "No ASP named '%s' found%s", name, VTY_NEWLINE); + return CMD_WARNING; + } + osmo_ss7_asp_destroy(asp); + return CMD_SUCCESS; +} + DEFUN(asp_remote_ip, asp_remote_ip_cmd, "remote-ip A.B.C.D", - "Specity Remote IP Address of ASP\n" + "Specify Remote IP Address of ASP\n" "Remote IP Address of ASP\n") { struct osmo_ss7_asp *asp = vty->index; @@ -404,7 +523,7 @@ DEFUN(asp_qos_clas, asp_qos_class_cmd, "qos-class <0-255>", - "Specity QoS Class of ASP\n" + "Specify QoS Class of ASP\n" "QoS Class of ASP\n") { struct osmo_ss7_asp *asp = vty->index; @@ -416,8 +535,8 @@ "block", "Allows a SCTP Association with ASP, but doesn't let it become active\n") { - struct osmo_ss7_asp *asp = vty->index; - vty_out(vty, "Not supported yet\n"); + /* TODO */ + vty_out(vty, "Not supported yet%s", VTY_NEWLINE); return CMD_WARNING; } @@ -425,23 +544,34 @@ "shutdown", "Terminates SCTP association; New associations will be rejected\n") { - struct osmo_ss7_asp *asp = vty->index; - vty_out(vty, "Not supported yet\n"); + /* TODO */ + vty_out(vty, "Not supported yet%s", VTY_NEWLINE); return CMD_WARNING; +} + +static void write_one_asp(struct vty *vty, struct osmo_ss7_asp *asp) +{ + vty_out(vty, "cs7 asp %s %u %u %s%s", + asp->cfg.name, asp->cfg.remote.port, asp->cfg.local.port, + osmo_ss7_asp_protocol_name(asp->cfg.proto), VTY_NEWLINE); + if (asp->cfg.description) + vty_out(vty, " description %s%s", asp->cfg.description, VTY_NEWLINE); + vty_out(vty, " remote-ip %s%s", asp->cfg.remote.host, VTY_NEWLINE); + if (asp->cfg.qos_class) + vty_out(vty, " qos-class %u%s", asp->cfg.qos_class, VTY_NEWLINE); } static int config_write_asp(struct vty *vty) { - struct osmo_ss7_asp *asp = vty->index; + struct osmo_ss7_instance *inst = g_s7i; + struct osmo_ss7_asp *asp; - vty_out(vty, "cs7 asp %s %u %u %s%s", - asp->cfg.name, asp->cfg.remote.port, asp->cfg.local.port, - osmo_ss7_asp_protocol_name(asp->cfg.proto), VTY_NEWLINE); - vty_out(vty, " remote-ip %s%s", asp->cfg.remote.host, VTY_NEWLINE); - if (asp->cfg.qos_class) - vty_out(vty, " qos-class %u%s", asp->cfg.qos_class, VTY_NEWLINE); + llist_for_each_entry(asp, &inst->asp_list, list) + write_one_asp(vty, asp); + return 0; } + /*********************************************************************** * Application Server @@ -454,27 +584,53 @@ }; DEFUN(cs7_as, cs7_as_cmd, - "cs7 as NAME [m3ua | sua]", + "cs7 as NAME (m3ua|sua)", CS7_STR "Configure an Application Server\n" "Name of the Application Server\n" "M3UA Application Server\n" "SUA Application Server\n") { + struct osmo_ss7_instance *inst = g_s7i; struct osmo_ss7_as *as; const char *name = argv[0]; enum osmo_ss7_asp_protocol protocol = parse_asp_proto(argv[1]); - if (protocol == OSMO_SS7_ASP_PROT_NONE) + if (protocol == OSMO_SS7_ASP_PROT_NONE) { + vty_out(vty, "invalid protocol '%s'%s", argv[3], VTY_NEWLINE); return CMD_WARNING; + } - /* FIXME */ + as = osmo_ss7_as_find_or_create(inst, name, protocol); + if (!as) { + vty_out(vty, "cannot create AS '%s'%s", name, VTY_NEWLINE); + return CMD_WARNING; + } + as->cfg.name = talloc_strdup(as, name); vty->node = L_CS7_AS_NODE; vty->index = as; vty->index_sub = &as->cfg.description; + return CMD_SUCCESS; +} + +DEFUN(no_cs7_as, no_cs7_as_cmd, + "no cs7 as NAME", + NO_STR CS7_STR "Disable Application Server\n" + "Name of AS\n") +{ + struct osmo_ss7_instance *inst = g_s7i; + const char *name = argv[0]; + struct osmo_ss7_as *as; + + as = osmo_ss7_as_find_by_name(inst, name); + if (!as) { + vty_out(vty, "No AS named '%s' found%s", name, VTY_NEWLINE); + return CMD_WARNING; + } + osmo_ss7_as_destroy(as); return CMD_SUCCESS; } @@ -486,8 +642,10 @@ { struct osmo_ss7_as *as = vty->index; - if (osmo_ss7_as_add_asp(as, argv[0])) + if (osmo_ss7_as_add_asp(as, argv[0])) { + vty_out(vty, "cannot find ASP '%s'%s", argv[0], VTY_NEWLINE); return CMD_WARNING; + } return CMD_SUCCESS; } @@ -499,8 +657,10 @@ { struct osmo_ss7_as *as = vty->index; - if (osmo_ss7_as_del_asp(as, argv[0])) + if (osmo_ss7_as_del_asp(as, argv[0])) { + vty_out(vty, "cannot find ASP '%s'%s", argv[0], VTY_NEWLINE); return CMD_WARNING; + } return CMD_SUCCESS; } @@ -516,7 +676,7 @@ struct osmo_ss7_as *as = vty->index; as->cfg.mode = get_string_value(osmo_ss7_as_traffic_mode_vals, argv[0]); - return CMD_WARNING; + return CMD_SUCCESS; } DEFUN(as_recov_tout, as_recov_tout_cmd, @@ -554,7 +714,7 @@ }; DEFUN(as_rout_key, as_rout_key_cmd, - "routing-key RCONTEXT DPC [si {aal2 | bicc | b-isup | h248 | isup | sat-isup | sccp | tup }] [ssn SSN]}", + "routing-key RCONTEXT DPC [si (aal2|bicc|b-isup|h248|isup|sat-isup|sccp|tup)] [ssn SSN]}", "Define a routing key\n" "Routing context number\n" "Destination Point Code\n" @@ -571,25 +731,21 @@ "Sub-System Number to match on\n") { struct osmo_ss7_as *as = vty->index; - uint32_t key = atoi(argv[0]); - struct osmo_ss7_routing_key *rkey; + struct osmo_ss7_routing_key *rkey = &as->cfg.routing_key; int argind; - rkey = osmo_ss7_rkey_find_or_create(as, key); - if (!rkey) - return CMD_WARNING; - + rkey->context = atoi(argv[0]); rkey->pc = osmo_ss7_pointcode_parse(as->inst, argv[1]); argind = 2; - if (!strcmp(argv[argind], "si")) { + if (argind < argc && !strcmp(argv[argind], "si")) { const char *si_str; argind++; si_str = argv[argind++]; /* parse numeric SI from string */ rkey->si = get_string_value(mtp_si_vals, si_str); } - if (!strcmp(argv[argind], "ssn")) { + if (argind < argc && !strcmp(argv[argind], "ssn")) { argind++; rkey->ssn = atoi(argv[argind]); } @@ -597,14 +753,15 @@ return CMD_SUCCESS; } -static int config_write_as(struct vty *vty) +static void write_one_as(struct vty *vty, struct osmo_ss7_as *as) { - struct osmo_ss7_as *as = vty->index; struct osmo_ss7_routing_key *rkey; unsigned int i; vty_out(vty, "cs7 as %s %s%s", as->cfg.name, osmo_ss7_asp_protocol_name(as->cfg.proto), VTY_NEWLINE); + if (as->cfg.description) + vty_out(vty, " description %s%s", as->cfg.description, VTY_NEWLINE); for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) { struct osmo_ss7_asp *asp = as->cfg.asps[i]; if (!asp) @@ -618,7 +775,8 @@ vty_out(vty, " recovery-timeout %u%s", as->cfg.recovery_timeout_msec, VTY_NEWLINE); } - vty_out(vty, " qos-class %u%s", as->cfg.qos_class, VTY_NEWLINE); + if (as->cfg.qos_class) + vty_out(vty, " qos-class %u%s", as->cfg.qos_class, VTY_NEWLINE); rkey = &as->cfg.routing_key; vty_out(vty, " routing-key %u %s", rkey->context, osmo_ss7_pointcode_print(as->inst, rkey->pc)); @@ -628,8 +786,62 @@ if (rkey->ssn) vty_out(vty, " ssn %u", rkey->ssn); vty_out(vty, "%s", VTY_NEWLINE); +} + +static int config_write_as(struct vty *vty) +{ + struct osmo_ss7_instance *inst = g_s7i; + struct osmo_ss7_as *as; + + /* HACK to call this here, as we cannot install additional + * 'save' code into the root CONFIG_NODE ... */ + config_write_cs7(vty); + + /* HACK to call this here, but we must make sure that the ASP + * are all configured before we reference them from the AS, and + * VTY code always stores the nodes in alphabetical order */ + + config_write_asp(vty); + + llist_for_each_entry(as, &inst->as_list, list) + write_one_as(vty, as); return 0; +} + +int osmo_ss7_vty_go_parent(struct vty *vty) +{ + struct osmo_ss7_asp *asp; + + switch (vty->node) { + case L_CS7_ASP_NODE: + asp = vty->index; + osmo_ss7_asp_restart(asp); + vty->node = CONFIG_NODE; + break; + case L_CS7_RTABLE_NODE: + case L_CS7_SUA_NODE: + case L_CS7_M3UA_NODE: + case L_CS7_AS_NODE: + default: + vty->node = CONFIG_NODE; + break; + } + return 0; +} + +int osmo_ss7_is_config_node(struct vty *vty, int node) +{ + switch (node) { + case L_CS7_ASP_NODE: + case L_CS7_RTABLE_NODE: + case L_CS7_SUA_NODE: + case L_CS7_M3UA_NODE: + case L_CS7_AS_NODE: + return 1; + default: + return 0; + } } int osmo_ss7_vty_init(void) @@ -650,16 +862,19 @@ install_node(&sua_node, config_write_sua); vty_install_default(L_CS7_SUA_NODE); install_element(CONFIG_NODE, &cs7_sua_cmd); + install_element(CONFIG_NODE, &no_cs7_sua_cmd); install_element(L_CS7_SUA_NODE, &sua_local_ip_cmd); install_node(&m3ua_node, config_write_m3ua); vty_install_default(L_CS7_M3UA_NODE); install_element(CONFIG_NODE, &cs7_m3ua_cmd); + install_element(CONFIG_NODE, &no_cs7_m3ua_cmd); install_element(L_CS7_M3UA_NODE, &m3ua_local_ip_cmd); - install_node(&asp_node, config_write_asp); + install_node(&asp_node, NULL); vty_install_default(L_CS7_ASP_NODE); install_element(CONFIG_NODE, &cs7_asp_cmd); + install_element(CONFIG_NODE, &no_cs7_asp_cmd); install_element(L_CS7_ASP_NODE, &cfg_description_cmd); install_element(L_CS7_ASP_NODE, &asp_remote_ip_cmd); install_element(L_CS7_ASP_NODE, &asp_qos_class_cmd); @@ -669,6 +884,7 @@ install_node(&as_node, config_write_as); vty_install_default(L_CS7_AS_NODE); install_element(CONFIG_NODE, &cs7_as_cmd); + install_element(CONFIG_NODE, &no_cs7_as_cmd); install_element(L_CS7_AS_NODE, &cfg_description_cmd); install_element(L_CS7_AS_NODE, &as_asp_cmd); install_element(L_CS7_AS_NODE, &as_no_asp_cmd); diff --git a/stp/stp_main.c b/stp/stp_main.c new file mode 100644 index 0000000..029c0b2 --- /dev/null +++ b/stp/stp_main.c @@ -0,0 +1,101 @@ +/* Osmocom STP (Signal Transfer Point) */ + +/* (C) 2015-2017 by Harald Welte + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "internal.h" + +struct osmo_ss7_instance *g_s7i; + +static const struct log_info_cat log_info_cat[] = { +}; + +static const struct log_info log_info = { + .cat = log_info_cat, + .num_cat = ARRAY_SIZE(log_info_cat), +}; + +/* Hack to enable debug logging for all relevant (used?) subsystems */ +static void init_logging(void) +{ + const int log_cats[] = { DLSS7, DLSUA, DLM3UA, DLSCCP, DLINP }; + unsigned int i; + + osmo_init_logging(&log_info); + + for (i = 0; i < ARRAY_SIZE(log_cats); i++) + log_set_category_filter(osmo_stderr_target, log_cats[i], 1, LOGL_DEBUG); +} + +static struct vty_app_info vty_info = { + .name = "osmo-stp", + .version = PACKAGE_VERSION, + .go_parent_cb = osmo_ss7_vty_go_parent, + .is_config_node = osmo_ss7_is_config_node, +}; + +int main(int argc, char **argv) +{ + char *config_file = "osmo-stp.cfg"; + int rc; + + init_logging(); + osmo_ss7_init(); + osmo_fsm_log_addr(false); + vty_init(&vty_info); + osmo_ss7_vty_init(); + + g_s7i = osmo_ss7_instance_find_or_create(NULL, 0); + + rc = vty_read_config_file(config_file, NULL); + if (rc < 0) { + fprintf(stderr, "Failed to parse the config file '%s'\n", + config_file); + exit(1); + } + + rc = telnet_init_dynif(NULL, NULL, vty_get_bind_addr(), OSMO_VTY_PORT_STP); + if (rc < 0) { + perror("Erro binding VTY port\n"); + exit(1); + } + + while (1) { + osmo_select_main(0); + } +} -- To view, visit https://gerrit.osmocom.org/2281 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: If32227b8d3127c6178e4ee45527ce65f69bc7b1e Gerrit-PatchSet: 3 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max From gerrit-no-reply at lists.osmocom.org Thu Apr 13 16:39:57 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 13 Apr 2017 16:39:57 +0000 Subject: libosmo-netif[master]: stream.h: Add missing stdbool.h include In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2311 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I736cb04629d516c10c7d5f42f792ed3d5ae6658f Gerrit-PatchSet: 1 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Pau Espin Pedrol Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Apr 13 16:40:00 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 13 Apr 2017 16:40:00 +0000 Subject: [MERGED] libosmo-netif[master]: stream.h: Add missing stdbool.h include In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: stream.h: Add missing stdbool.h include ...................................................................... stream.h: Add missing stdbool.h include Functions introduced in 9ec26583cd807e0aeaa3b9de927f3d8a768c3a71 are using the bool type without referencing stdbool.h as include file. Change-Id: I736cb04629d516c10c7d5f42f792ed3d5ae6658f --- M include/osmocom/netif/stream.h 1 file changed, 2 insertions(+), 0 deletions(-) Approvals: Pau Espin Pedrol: Looks good to me, but someone else must approve Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/include/osmocom/netif/stream.h b/include/osmocom/netif/stream.h index 7afb7af..08af3fd 100644 --- a/include/osmocom/netif/stream.h +++ b/include/osmocom/netif/stream.h @@ -1,6 +1,8 @@ #ifndef _OSMO_STREAM_H_ #define _OSMO_STREAM_H_ +#include + /*! \addtogroup stream * @{ */ -- To view, visit https://gerrit.osmocom.org/2311 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I736cb04629d516c10c7d5f42f792ed3d5ae6658f Gerrit-PatchSet: 1 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Pau Espin Pedrol From gerrit-no-reply at lists.osmocom.org Thu Apr 13 16:40:11 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 13 Apr 2017 16:40:11 +0000 Subject: libosmo-sccp[master]: Add a default layer manager using RKM to register PC with SG In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2283 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I78d4623dd213b5c59007a026a6cc3cfe5c04af50 Gerrit-PatchSet: 2 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Apr 13 16:40:13 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 13 Apr 2017 16:40:13 +0000 Subject: libosmo-sccp[master]: osmo_ss7_vty: 'show' commands for AS, ASP, route In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2321 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ideb74c9396e5385f6a7c30ff8608d34ededa1f4d Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Apr 13 16:40:15 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 13 Apr 2017 16:40:15 +0000 Subject: libosmo-sccp[master]: xua_rkm: Improve comments about functions In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2322 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I2f17baae37718e277eae54d4d225f8fcb2eb4aae Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Apr 13 16:40:17 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 13 Apr 2017 16:40:17 +0000 Subject: libosmo-sccp[master]: xua_rkm: Make dynamic registration of Routing Keys work In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2323 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I79a070fa7b271b44995511f7b3ff7cc6beec8278 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Apr 13 16:40:18 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 13 Apr 2017 16:40:18 +0000 Subject: libosmo-sccp[master]: osmo_ss7: Release any dynamically-allocated ASs In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2324 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ie6505680bb6890814ae36858c54a2a6d2850f5cf Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Apr 13 16:40:27 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 13 Apr 2017 16:40:27 +0000 Subject: [MERGED] libosmo-sccp[master]: osmo_ss7: Release any dynamically-allocated ASs In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: osmo_ss7: Release any dynamically-allocated ASs ...................................................................... osmo_ss7: Release any dynamically-allocated ASs When RKM dynamically allocates ASs on the SGP based on RKM registration requests, we must make sure to properly destroy those at the time the related ASP disconnects. Also, make sure to send XUA_ASP_E_SCTP_COMM_DOWN_IND to the layer manager (if any). Change-Id: Ie6505680bb6890814ae36858c54a2a6d2850f5cf --- M src/osmo_ss7.c M src/xua_internal.h M src/xua_rkm.c 3 files changed, 23 insertions(+), 1 deletion(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index e66414c..d864916 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -1401,7 +1401,11 @@ LOGP(DLSS7, LOGL_INFO, "%s: SCTP connection closed\n", asp ? asp->cfg.name : "?"); - /* FIXME: somehow notify ASP FSM and everyone else */ + /* notify ASP FSM and everyone else */ + osmo_fsm_inst_dispatch(asp->fi, XUA_ASP_E_SCTP_COMM_DOWN_IND, NULL); + + /* delete any RKM-dynamically allocated ASs for this ASP */ + xua_rkm_cleanup_dyn_as_for_asp(asp); /* send M-SCTP_RELEASE.ind to Layer Manager */ xua_asp_send_xlm_prim_simple(asp, OSMO_XLM_PRIM_M_SCTP_RELEASE, PRIM_OP_INDICATION); diff --git a/src/xua_internal.h b/src/xua_internal.h index 468b7e4..b291703 100644 --- a/src/xua_internal.h +++ b/src/xua_internal.h @@ -47,6 +47,7 @@ int m3ua_decode_notify(struct osmo_xlm_prim_notify *npar, void *ctx, const struct xua_msg *xua); int m3ua_rx_rkm(struct osmo_ss7_asp *asp, struct xua_msg *xua); +void xua_rkm_cleanup_dyn_as_for_asp(struct osmo_ss7_asp *asp); struct osmo_xlm_prim *xua_xlm_prim_alloc(enum osmo_xlm_prim_type prim_type, enum osmo_prim_operation op); diff --git a/src/xua_rkm.c b/src/xua_rkm.c index 38cbbda..62abfdd 100644 --- a/src/xua_rkm.c +++ b/src/xua_rkm.c @@ -544,3 +544,20 @@ return 0; } + +/* clean-up any dynamically created ASs + routes */ +void xua_rkm_cleanup_dyn_as_for_asp(struct osmo_ss7_asp *asp) +{ + struct osmo_ss7_instance *inst = asp->inst; + struct osmo_ss7_as *as, *as2; + + llist_for_each_entry_safe(as, as2, &inst->as_list, list) { + if (!osmo_ss7_as_has_asp(as, asp)) + continue; + /* FIXME: check if there are no other ASPs! */ + if (!as->rkm_dyn_allocated) + continue; + + osmo_ss7_as_destroy(as); + } +} -- To view, visit https://gerrit.osmocom.org/2324 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ie6505680bb6890814ae36858c54a2a6d2850f5cf Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Thu Apr 13 16:40:27 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 13 Apr 2017 16:40:27 +0000 Subject: [MERGED] libosmo-sccp[master]: xua_rkm: Make dynamic registration of Routing Keys work In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: xua_rkm: Make dynamic registration of Routing Keys work ...................................................................... xua_rkm: Make dynamic registration of Routing Keys work The existign xua_rkm code was merged a bit pre-maturely as it was not properly tested. This adds a lot of fixes to make it work at all in the first place, as well as the configurable option for fully dynamic routing key management, where ASs and routing keys must not be configured statically by administrative means, but clients (ASPs) can simply come and register for whatever point code they want. Change-Id: I79a070fa7b271b44995511f7b3ff7cc6beec8278 --- M include/osmocom/sigtran/osmo_ss7.h M src/xua_rkm.c 2 files changed, 100 insertions(+), 30 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/include/osmocom/sigtran/osmo_ss7.h b/include/osmocom/sigtran/osmo_ss7.h index c3a81bb..49a8ca5 100644 --- a/include/osmocom/sigtran/osmo_ss7.h +++ b/include/osmocom/sigtran/osmo_ss7.h @@ -86,6 +86,7 @@ /* capability PCs */ uint8_t network_indicator; struct osmo_ss7_pc_fmt pc_fmt; + bool permit_dyn_rkm_alloc; } cfg; }; @@ -276,6 +277,9 @@ /*! AS FSM */ struct osmo_fsm_inst *fi; + /*! Were we dynamically allocated by RKM? */ + bool rkm_dyn_allocated; + struct { char *name; char *description; diff --git a/src/xua_rkm.c b/src/xua_rkm.c index aa29866..38cbbda 100644 --- a/src/xua_rkm.c +++ b/src/xua_rkm.c @@ -16,6 +16,7 @@ * along with this program. If not, see . */ +#include #include #include @@ -26,6 +27,7 @@ #include #include "xua_internal.h" +#include "xua_as_fsm.h" const struct value_string m3ua_rkm_reg_status_vals[] = { { M3UA_RKM_REG_SUCCESS, "SUCCESS" }, @@ -137,11 +139,15 @@ osmo_ss7_asp_send(asp, msg); } +/* maximum number of newly-assigned Application Servers in one dynamic + * RKM REG request */ +#define MAX_NEW_AS 16 /* SG: handle a single registration request IE (nested IEs in 'innner' */ static int handle_rkey_reg(struct osmo_ss7_asp *asp, struct xua_msg *inner, - struct msgb *resp) + struct msgb *resp, struct osmo_ss7_as **newly_assigned_as) { + unsigned int nas_idx = 0; uint32_t rk_id, rctx, _tmode, dpc; enum osmo_ss7_as_traffic_mode tmode; struct osmo_ss7_as *as; @@ -188,35 +194,67 @@ LOGPASP(asp, DLSS7, LOGL_INFO, "RKM: Registering routing key %u for DPC %s\n", rctx, osmo_ss7_pointcode_print(asp->inst, dpc)); + /* We have two cases here: + * a) pre-configured routing context on both ASP and SG: We will + * find the AS based on the RCTX send by the client, check if + * the routing key matches, associated AS with ASP and return + * success. + * b) no routing context set on ASP, no pre-existing AS + * definition on SG. We have to create the AS, set the RK, + * allocate the RCTX and return that RCTX to the client. This + * is a slightly non-standard interpretation of M3UA RKM + * which requires the SG to not have a-priori-knowledge of + * all AS/RK in situations where the ASP are trusted. + */ + /* check if there is already an AS for this routing key */ - if (osmo_ss7_as_find_by_rctx(asp->inst, rctx)) { - LOGPASP(asp, DLSS7, LOGL_NOTICE, "RKM: RCTX %u already in use\n", rctx); - msgb_append_reg_res(resp, rk_id, M3UA_RKM_REG_ERR_RKEY_ALRDY_REGD, 0); - return -1; - } + as = osmo_ss7_as_find_by_rctx(asp->inst, rctx); + if (as) { + LOGPASP(asp, DLSS7, LOGL_NOTICE, "RKM: Found existing AS for RCTX %u\n", rctx); + if (as->cfg.routing_key.pc != dpc) { + LOGPASP(asp, DLSS7, LOGL_NOTICE, "RKM: DPC doesn't match (%u != %u)\n", + as->cfg.routing_key.pc, dpc); + msgb_append_reg_res(resp, rk_id, M3UA_RKM_REG_ERR_INVAL_RKEY, 0); + return -1; + } + } else if (asp->inst->cfg.permit_dyn_rkm_alloc) { + /* Create an AS for this routing key */ + snprintf(namebuf, sizeof(namebuf), "as-rkm-%u", rctx); + as = osmo_ss7_as_find_or_create(asp->inst, namebuf, OSMO_SS7_ASP_PROT_M3UA); + if (!as) { + LOGPASP(asp, DLSS7, LOGL_ERROR, "RKM: Cannot create AS %s\n", namebuf); + msgb_append_reg_res(resp, rk_id, M3UA_RKM_REG_ERR_INSUFF_RESRC, 0); + return -1; + } - /* Create an AS for this routing key */ - snprintf(namebuf, sizeof(namebuf), "as-rkm-%u", rctx); - as = osmo_ss7_as_find_or_create(asp->inst, namebuf, OSMO_SS7_ASP_PROT_M3UA); - if (!as) { - LOGPASP(asp, DLSS7, LOGL_ERROR, "RKM: Cannot create AS %s\n", namebuf); - msgb_append_reg_res(resp, rk_id, M3UA_RKM_REG_ERR_INSUFF_RESRC, 0); - return -1; - } + as->cfg.description = talloc_strdup(as, "Auto-generated by RKM"); + as->rkm_dyn_allocated = true; + as->cfg.mode = tmode; + /* fill routing key */ + as->cfg.routing_key.pc = dpc; + as->cfg.routing_key.context = rctx; - as->cfg.description = talloc_strdup(as, "Auto-generated by RKM"); - as->cfg.mode = tmode; - /* fill routing key */ - as->cfg.routing_key.context = rctx; - as->cfg.routing_key.pc = dpc; + /* add route for that routing key */ + rt = osmo_ss7_route_create(as->inst->rtable_system, dpc, 0xFFFFFF, namebuf); + if (!rt) { + LOGPASP(asp, DLSS7, LOGL_ERROR, "RKM: Cannot insert route for DPC %s / as %s\n", + osmo_ss7_pointcode_print(asp->inst, dpc), namebuf); + osmo_ss7_as_destroy(as); + msgb_append_reg_res(resp, rk_id, M3UA_RKM_REG_ERR_CANT_SUPP_UNQ_RT, 0); + return -1; + } - /* add route for that routing key */ - rt = osmo_ss7_route_create(as->inst->rtable_system, dpc, 0xFFFFFF, namebuf); - if (!rt) { - LOGPASP(asp, DLSS7, LOGL_ERROR, "RKM: Cannot insert route for DPC %s / as %s\n", - osmo_ss7_pointcode_print(asp->inst, dpc), namebuf); - osmo_ss7_as_destroy(as); - msgb_append_reg_res(resp, rk_id, M3UA_RKM_REG_ERR_CANT_SUPP_UNQ_RT, 0); + /* append to list of newly assigned as */ + if (nas_idx >= MAX_NEW_AS) { + osmo_ss7_route_destroy(rt); + osmo_ss7_as_destroy(as); + msgb_append_reg_res(resp, rk_id, M3UA_RKM_REG_ERR_INSUFF_RESRC, 0); + return -1; + } + newly_assigned_as[nas_idx++] = as; + } else { + /* not permitted to create dynamic RKM entries */ + msgb_append_reg_res(resp, rk_id, M3UA_RKM_REG_ERR_PERM_DENIED, 0); return -1; } @@ -231,6 +269,10 @@ { struct xua_msg_part *part; struct msgb *resp = m3ua_msgb_alloc(__func__); + struct osmo_ss7_as *newly_assigned_as[MAX_NEW_AS]; + unsigned int i; + + memset(newly_assigned_as, 0, sizeof(newly_assigned_as)); /* iterate over all routing key IEs in message */ llist_for_each_entry(part, &xua->headers, entry) { @@ -247,10 +289,24 @@ } /* handle single registration and append result to * 'resp' */ - handle_rkey_reg(asp, inner, resp); + handle_rkey_reg(asp, inner, resp, newly_assigned_as); + + xua_msg_free(inner); } + /* now first send the RKM REG Response */ msgb_push_m3ua_hdr(resp, M3UA_MSGC_RKM, M3UA_RKM_REG_RSP); osmo_ss7_asp_send(asp, resp); + + /* and *after* the RKM REG Response inform the newly assigned + * ASs about the fact that there's an INACTIVE ASP for them, + * which will cause them to send NOTIFY to the client */ + for (i = 0; i < ARRAY_SIZE(newly_assigned_as); i++) { + struct osmo_ss7_as *as = newly_assigned_as[i]; + if (!as) + continue; + /* Notify AS that it has an INACTIVE ASP */ + osmo_fsm_inst_dispatch(as->fi, XUA_ASPAS_ASP_INACTIVE_IND, asp); + } return 0; } @@ -286,9 +342,19 @@ LOGPASP(asp, DLSS7, LOGL_INFO, "RKM: De-Registering rctx %u for DPC %s\n", rctx, osmo_ss7_pointcode_print(inst, as->cfg.routing_key.pc)); - /* remove route + AS definition */ - osmo_ss7_route_destroy(rt); - osmo_ss7_as_destroy(as); + /* remove ASP from AS */ + osmo_ss7_as_del_asp(as, asp->cfg.name); + /* FIXME: Rather than spoofing teh ASP-DOWN.ind to the AS here, + * we should refuse RKM DEREG if the ASP is still ACTIVE */ + osmo_fsm_inst_dispatch(as->fi, XUA_ASPAS_ASP_DOWN_IND, asp); + + /* if we were dynamically allocated, release the associated + * route and destroy the AS */ + if (as->rkm_dyn_allocated) { + /* remove route + AS definition */ + osmo_ss7_route_destroy(rt); + osmo_ss7_as_destroy(as); + } /* report success */ msgb_append_dereg_res(resp, M3UA_RKM_DEREG_SUCCESS, rctx); -- To view, visit https://gerrit.osmocom.org/2323 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I79a070fa7b271b44995511f7b3ff7cc6beec8278 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Thu Apr 13 16:40:27 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 13 Apr 2017 16:40:27 +0000 Subject: [MERGED] libosmo-sccp[master]: xua_rkm: Improve comments about functions In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: xua_rkm: Improve comments about functions ...................................................................... xua_rkm: Improve comments about functions Change-Id: I2f17baae37718e277eae54d4d225f8fcb2eb4aae --- M src/xua_rkm.c 1 file changed, 13 insertions(+), 10 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/xua_rkm.c b/src/xua_rkm.c index 0d576a7..aa29866 100644 --- a/src/xua_rkm.c +++ b/src/xua_rkm.c @@ -69,7 +69,7 @@ hdr->msg_length = htonl(msgb_l2len(msg)); } -/* append a single registration result to given msgb */ +/* SG: append a single registration result to given msgb */ static int msgb_append_reg_res(struct msgb *msg, uint32_t local_rk_id, uint32_t status, uint32_t rctx) { @@ -86,7 +86,7 @@ return msg->tail - old_tail; } -/* append a single de-registration result to given msgb */ +/* SG: append a single de-registration result to given msgb */ static int msgb_append_dereg_res(struct msgb *msg, uint32_t status, uint32_t rctx) { @@ -102,6 +102,7 @@ return msg->tail - old_tail; } +/* ASP: send a RKM Registration Request message for a single routing key */ static void xua_rkm_send_reg_req(struct osmo_ss7_asp *asp, const struct osmo_ss7_routing_key *rkey, enum osmo_ss7_as_traffic_mode traf_mode) @@ -123,6 +124,7 @@ osmo_ss7_asp_send(asp, msg); } +/* ASP: send a RKM De-Registration Request message for a single routing context */ static void xua_rkm_send_dereg_req(struct osmo_ss7_asp *asp, uint32_t route_ctx) { struct msgb *msg = m3ua_msgb_alloc(__func__); @@ -136,8 +138,7 @@ } - -/* handle a single registration request IE (nested IEs in 'innner' */ +/* SG: handle a single registration request IE (nested IEs in 'innner' */ static int handle_rkey_reg(struct osmo_ss7_asp *asp, struct xua_msg *inner, struct msgb *resp) { @@ -225,7 +226,7 @@ return 0; } -/* receive a registration requuest (SG role) */ +/* SG: receive a registration request from ASP */ static int m3ua_rx_rkm_reg_req(struct osmo_ss7_asp *asp, struct xua_msg *xua) { struct xua_msg_part *part; @@ -254,7 +255,7 @@ return 0; } -/* receive a deregistration requuest (SG role) */ +/* SG: handle a single routing key de-registration IE */ static int handle_rkey_dereg(struct osmo_ss7_asp *asp, uint32_t rctx, struct msgb *resp) { @@ -294,6 +295,7 @@ return 0; } +/* SG: receive a De-Registration request from ASP */ static int m3ua_rx_rkm_dereg_req(struct osmo_ss7_asp *asp, struct xua_msg *xua) { struct xua_msg_part *part = xua_msg_find_tag(xua, M3UA_IEI_ROUTE_CTX); @@ -312,7 +314,7 @@ return 0; } -/* handle a single registration response IE (nested IEs in 'inner' */ +/* ASP: handle a single registration response IE (nested IEs in 'inner') */ static int handle_rkey_reg_resp(struct osmo_ss7_asp *asp, struct xua_msg *inner) { struct osmo_xlm_prim *oxp; @@ -343,7 +345,7 @@ return 0; } -/* receive a registration response (ASP role) */ +/* ASP: receive a registration response (ASP role) */ static int m3ua_rx_rkm_reg_rsp(struct osmo_ss7_asp *asp, struct xua_msg *xua) { struct xua_msg_part *part; @@ -366,7 +368,7 @@ return 0; } -/* handle a single deregistration response IE (nested IEs in 'inner' */ +/* ASP: handle a single De-Registration response IE (nested IEs in 'inner' */ static int handle_rkey_dereg_resp(struct osmo_ss7_asp *asp, struct xua_msg *inner) { struct osmo_xlm_prim *oxp; @@ -395,7 +397,7 @@ return 0; } -/* receive a deregistration response (ASP role) */ +/* ASP: receive a De-Registration response */ static int m3ua_rx_rkm_dereg_rsp(struct osmo_ss7_asp *asp, struct xua_msg *xua) { struct xua_msg_part *part; @@ -451,6 +453,7 @@ return rc; } +/* process a primitive from the xUA Layer Manager (LM) */ int osmo_xlm_sap_down(struct osmo_ss7_asp *asp, struct osmo_prim_hdr *oph) { struct osmo_xlm_prim *prim = (struct osmo_xlm_prim *) oph; -- To view, visit https://gerrit.osmocom.org/2322 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I2f17baae37718e277eae54d4d225f8fcb2eb4aae Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Thu Apr 13 16:40:28 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 13 Apr 2017 16:40:28 +0000 Subject: [MERGED] libosmo-sccp[master]: osmo_ss7_vty: 'show' commands for AS, ASP, route In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: osmo_ss7_vty: 'show' commands for AS, ASP, route ...................................................................... osmo_ss7_vty: 'show' commands for AS, ASP, route Change-Id: Ideb74c9396e5385f6a7c30ff8608d34ededa1f4d --- M stp/osmo_ss7_vty.c 1 file changed, 83 insertions(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/stp/osmo_ss7_vty.c b/stp/osmo_ss7_vty.c index 905c4f6..014fa03 100644 --- a/stp/osmo_ss7_vty.c +++ b/stp/osmo_ss7_vty.c @@ -296,6 +296,33 @@ return 0; } +static void vty_dump_rtable(struct vty *vty, struct osmo_ss7_route_table *rtbl) +{ + struct osmo_ss7_route *rt; + + vty_out(vty, "Routing table = %s%s", rtbl->cfg.name, VTY_NEWLINE); + vty_out(vty, "C=Cong Q=QoS P=Prio%s", VTY_NEWLINE); + vty_out(vty, "%s", VTY_NEWLINE); + vty_out(vty, "Destination C Q P Linkset Name Linkset Non-adj Route%s", VTY_NEWLINE); + vty_out(vty, "---------------------- - - - ------------------- ------- ------- -------%s", VTY_NEWLINE); + + llist_for_each_entry(rt, &rtbl->routes, list) { + vty_out(vty, "%-22s %c %c %u %-19s %-7s %-7s %-7s%s", + osmo_ss7_pointcode_print(rtbl->inst, rt->cfg.mask), + ' ', ' ', rt->cfg.priority, rt->cfg.linkset_name, "?", "?", "?", VTY_NEWLINE); + } +} + +DEFUN(show_cs7_route, show_cs7_route_cmd, + "show cs7 route", + SHOW_STR CS7_STR "Routing Table\n") +{ + struct osmo_ss7_instance *inst = g_s7i; + + vty_dump_rtable(vty, inst->rtable_system); + return CMD_SUCCESS; +} + /*********************************************************************** * SUA Configuration ***********************************************************************/ @@ -547,6 +574,26 @@ /* TODO */ vty_out(vty, "Not supported yet%s", VTY_NEWLINE); return CMD_WARNING; +} + +DEFUN(show_cs7_asp, show_cs7_asp_cmd, + "show cs7 asp", + SHOW_STR CS7_STR "Application Server Process (ASP)\n") +{ + struct osmo_ss7_instance *inst = g_s7i; + struct osmo_ss7_asp *asp; + + vty_out(vty, " Effect Primary%s", VTY_NEWLINE); + vty_out(vty, "ASP Name AS Name State Type Rmt Port Remote IP Addr SCTP%s", VTY_NEWLINE); + vty_out(vty, "------------ ------------ -------- ---- -------- --------------- ----------%s", VTY_NEWLINE); + + llist_for_each_entry(asp, &inst->asp_list, list) { + vty_out(vty, "%-12s %-12s %-8s %-4s %-8u %-15s %-10s%s", + asp->cfg.name, "?", "?", + get_value_string(osmo_ss7_asp_protocol_vals, asp->cfg.proto), + asp->cfg.remote.port, asp->cfg.remote.host, "", VTY_NEWLINE); + } + return CMD_SUCCESS; } static void write_one_asp(struct vty *vty, struct osmo_ss7_asp *asp) @@ -809,6 +856,39 @@ return 0; } +DEFUN(show_cs7_as, show_cs7_as_cmd, + "show cs7 as (active|all|m3ua|sua)", + SHOW_STR CS7_STR "Application Server (AS)\n" + "Display all active ASs\n" + "Display all ASs (default)\n" + "Display all m3ua ASs\n" + "Display all SUA ASs\n") +{ + struct osmo_ss7_instance *inst = g_s7i; + struct osmo_ss7_as *as; + const char *filter = NULL; + + if (argc) + filter = argv[0]; + + vty_out(vty, " Routing Routing Key Cic Cic%s", VTY_NEWLINE); + vty_out(vty, "AS Name State Context Dpc Si Opc Ssn Min Max%s", VTY_NEWLINE); + vty_out(vty, "------------ ------ ---------- ------------- ---- ------------- --- ----- -----%s", VTY_NEWLINE); + + llist_for_each_entry(as, &inst->as_list, list) { + if (filter && !strcmp(filter, "m3ua") && as->cfg.proto != OSMO_SS7_ASP_PROT_M3UA) + continue; + if (filter && !strcmp(filter, "sua") && as->cfg.proto != OSMO_SS7_ASP_PROT_SUA) + continue; + /* FIXME: active filter */ + vty_out(vty, "%-12s %-6s %-10u %-13s %4s %13s %3s %5s %4s%s", + as->cfg.name, "fixme", as->cfg.routing_key.context, + osmo_ss7_pointcode_print(as->inst, as->cfg.routing_key.pc), + "", "", "", "", "", VTY_NEWLINE); + } + return CMD_SUCCESS; +} + int osmo_ss7_vty_go_parent(struct vty *vty) { struct osmo_ss7_asp *asp; @@ -854,6 +934,7 @@ install_node(&rtable_node, config_write_rtable); vty_install_default(L_CS7_RTABLE_NODE); + install_element_ve(&show_cs7_route_cmd); install_element(CONFIG_NODE, &cs7_route_table_cmd); install_element(L_CS7_RTABLE_NODE, &cfg_description_cmd); install_element(L_CS7_RTABLE_NODE, &cs7_rt_upd_cmd); @@ -873,6 +954,7 @@ install_node(&asp_node, NULL); vty_install_default(L_CS7_ASP_NODE); + install_element_ve(&show_cs7_asp_cmd); install_element(CONFIG_NODE, &cs7_asp_cmd); install_element(CONFIG_NODE, &no_cs7_asp_cmd); install_element(L_CS7_ASP_NODE, &cfg_description_cmd); @@ -883,6 +965,7 @@ install_node(&as_node, config_write_as); vty_install_default(L_CS7_AS_NODE); + install_element_ve(&show_cs7_as_cmd); install_element(CONFIG_NODE, &cs7_as_cmd); install_element(CONFIG_NODE, &no_cs7_as_cmd); install_element(L_CS7_AS_NODE, &cfg_description_cmd); -- To view, visit https://gerrit.osmocom.org/2321 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ideb74c9396e5385f6a7c30ff8608d34ededa1f4d Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Thu Apr 13 16:40:28 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 13 Apr 2017 16:40:28 +0000 Subject: [MERGED] libosmo-sccp[master]: Add a default layer manager using RKM to register PC with SG In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: Add a default layer manager using RKM to register PC with SG ...................................................................... Add a default layer manager using RKM to register PC with SG This "default layer manager" can optionally be used by a xUA ASP. It will handle the xUA Layer Manager (xlm) primitives and use them to behave as follows: * bring the ASP into state "INACTIVE" * see if the SG can match our connection (based on IP address + port information) to a statically configured ASP configuration with associated AS(s). If yes, it will send us a NOTIFY message with AS-INACTIVE. * if the above doesn't work, try to dynamically register a routing key using RKM for the point code that was locally confiured on the ASP/client. If that works, the SG will now have created ASP and AS objects as well as a routing key and be able to serve us, sending the NOTIFY with the AS-INACTIVE state. * After either of the two above, we will attempt to transition into ASP-ACTIVE. The SG should send us an AS-ACTIVE notification in return * if anything fails, abort and disconnect the SCTP connection, restart related FSMs and start from scratch Change-Id: I78d4623dd213b5c59007a026a6cc3cfe5c04af50 --- M include/osmocom/sigtran/osmo_ss7.h M include/osmocom/sigtran/sigtran_sap.h M src/Makefile.am M src/osmo_ss7.c M src/sccp_sap.c M src/sccp_user.c M src/xua_asp_fsm.c A src/xua_default_lm_fsm.c M src/xua_internal.h M src/xua_rkm.c 10 files changed, 604 insertions(+), 14 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/include/osmocom/sigtran/osmo_ss7.h b/include/osmocom/sigtran/osmo_ss7.h index dff206d..c3a81bb 100644 --- a/include/osmocom/sigtran/osmo_ss7.h +++ b/include/osmocom/sigtran/osmo_ss7.h @@ -345,7 +345,8 @@ bool asp_id_present; /* Layer Manager to which we talk */ - struct osmo_xua_layer_manager *lm; + const struct osmo_xua_layer_manager *lm; + void *lm_priv; /*! Were we dynamically allocated */ bool dyn_allocated; @@ -372,6 +373,7 @@ void osmo_ss7_asp_destroy(struct osmo_ss7_asp *asp); int osmo_ss7_asp_send(struct osmo_ss7_asp *asp, struct msgb *msg); int osmo_ss7_asp_restart(struct osmo_ss7_asp *asp); +int osmo_ss7_asp_use_default_lm(struct osmo_ss7_asp *asp, int log_level); #define LOGPASP(asp, subsys, level, fmt, args ...) \ LOGP(subsys, level, "asp-%s: " fmt, (asp)->cfg.name, ## args) diff --git a/include/osmocom/sigtran/sigtran_sap.h b/include/osmocom/sigtran/sigtran_sap.h index 80cfefc..87504c8 100644 --- a/include/osmocom/sigtran/sigtran_sap.h +++ b/include/osmocom/sigtran/sigtran_sap.h @@ -51,10 +51,16 @@ /* routing key */ struct osmo_ss7_routing_key key; enum osmo_ss7_as_traffic_mode traf_mode; + + /* Status: Confirm only */ + uint32_t status; }; struct osmo_xlm_prim_rk_dereg { uint32_t route_ctx; + + /* Status: Confirm only */ + uint32_t status; }; struct osmo_xlm_prim { @@ -62,9 +68,14 @@ union { struct osmo_xlm_prim_notify notify; struct osmo_xlm_prim_error error; + struct osmo_xlm_prim_rk_reg rk_reg; + struct osmo_xlm_prim_rk_dereg rk_dereg; } u; }; #define msgb_xlm_prim(msg) ((struct osmo_xlm_prim *)(msg)->l1h) char *osmo_xlm_prim_name(struct osmo_prim_hdr *oph); + +/* XUA LM-SAP towards stack */ +int osmo_xlm_sap_down(struct osmo_ss7_asp *asp, struct osmo_prim_hdr *oph); diff --git a/src/Makefile.am b/src/Makefile.am index 7867282..f9b87b0 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -28,7 +28,7 @@ libosmo_sigtran_la_SOURCES = sccp_sap.c sua.c m3ua.c xua_msg.c sccp_helpers.c \ sccp2sua.c sccp_scrc.c sccp_sclc.c sccp_scoc.c \ - sccp_user.c xua_rkm.c \ + sccp_user.c xua_rkm.c xua_default_lm_fsm.c \ osmo_ss7.c osmo_ss7_hmrt.c xua_asp_fsm.c xua_as_fsm.c libosmo_sigtran_la_LDFLAGS = -version-info $(LIBVERSION) -no-undefined -export-symbols-regex '^osmo_' libosmo_sigtran_la_LIBADD = $(LIBOSMOCORE_LIBS) $(LIBOSMONETIF_LIBS) $(LIBSCTP_LIBS) diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index 7ed216a..e66414c 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -1635,6 +1635,7 @@ osmo_fsm_register(&sccp_scoc_fsm); osmo_fsm_register(&xua_as_fsm); osmo_fsm_register(&xua_asp_fsm); + osmo_fsm_register(&xua_default_lm_fsm); ss7_initialized = true; return 0; } diff --git a/src/sccp_sap.c b/src/sccp_sap.c index 2211f71..d4580ae 100644 --- a/src/sccp_sap.c +++ b/src/sccp_sap.c @@ -45,11 +45,43 @@ { const char *name = get_value_string(osmo_scu_prim_names, oph->primitive); - prim_name_buf[0] = '\0'; - strncpy(prim_name_buf, name, sizeof(prim_name_buf)-1); - prim_name_buf[sizeof(prim_name_buf)-1] = '\0'; - name = get_value_string(osmo_prim_op_names, oph->operation); - strncat(prim_name_buf, name, sizeof(prim_name_buf)-strlen(prim_name_buf)-2); + snprintf(prim_name_buf, sizeof(prim_name_buf), "%s.%s", name, + get_value_string(osmo_prim_op_names, oph->operation)); + + return prim_name_buf; +} + + +#include + +const struct value_string osmo_xlm_prim_names[] = { + { OSMO_XLM_PRIM_M_SCTP_ESTABLISH, "M-SCTP_ESTABLISH" }, + { OSMO_XLM_PRIM_M_SCTP_RELEASE, "M-SCTP_RELEASE" }, + { OSMO_XLM_PRIM_M_SCTP_RESTART, "M-SCTP_RESTART" }, + { OSMO_XLM_PRIM_M_SCTP_STATUS, "M-SCTP_STATUS" }, + { OSMO_XLM_PRIM_M_ASP_STATUS, "M-ASP_STATUS" }, + { OSMO_XLM_PRIM_M_AS_STATUS, "M-AS_STATUS" }, + { OSMO_XLM_PRIM_M_NOTIFY, "M-NOTIFY" }, + { OSMO_XLM_PRIM_M_ERROR, "M-ERROR" }, + { OSMO_XLM_PRIM_M_ASP_UP, "M-ASP_UP" }, + { OSMO_XLM_PRIM_M_ASP_DOWN, "M-ASP_DOWN" }, + { OSMO_XLM_PRIM_M_ASP_ACTIVE, "M-ASP_ACTIVE" }, + { OSMO_XLM_PRIM_M_ASP_INACTIVE, "M-ASP_INACTIVE" }, + { OSMO_XLM_PRIM_M_AS_ACTIVE, "M-AS_ACTIVE" }, + { OSMO_XLM_PRIM_M_AS_INACTIVE, "M-AS_INACTIVE" }, + { OSMO_XLM_PRIM_M_AS_DOWN, "M-AS_DOWN" }, + /* optional as per spec, not implemented yet */ + { OSMO_XLM_PRIM_M_RK_REG, "M-RK_REG" }, + { OSMO_XLM_PRIM_M_RK_DEREG, "M-RK_DEREG" }, + { 0, NULL }, +}; + +char *osmo_xlm_prim_name(struct osmo_prim_hdr *oph) +{ + const char *name = get_value_string(osmo_xlm_prim_names, oph->primitive); + + snprintf(prim_name_buf, sizeof(prim_name_buf), "%s.%s", name, + get_value_string(osmo_prim_op_names, oph->operation)); return prim_name_buf; } diff --git a/src/sccp_user.c b/src/sccp_user.c index 01a0638..51cc6b1 100644 --- a/src/sccp_user.c +++ b/src/sccp_user.c @@ -274,6 +274,7 @@ asp->cfg.local.host = talloc_strdup(asp, local_ip); asp->cfg.remote.host = talloc_strdup(asp, remote_ip); osmo_ss7_as_add_asp(as, asp_name); + osmo_ss7_asp_use_default_lm(asp, LOGL_DEBUG); talloc_free(asp_name); osmo_ss7_asp_restart(asp); diff --git a/src/xua_asp_fsm.c b/src/xua_asp_fsm.c index 2830334..59887a4 100644 --- a/src/xua_asp_fsm.c +++ b/src/xua_asp_fsm.c @@ -100,10 +100,14 @@ /* Send a XUA LM Primitive to the XUA Layer Manager (LM) */ void xua_asp_send_xlm_prim(struct osmo_ss7_asp *asp, struct osmo_xlm_prim *prim) { - struct osmo_xua_layer_manager *lm = asp->lm; + const struct osmo_xua_layer_manager *lm = asp->lm; if (lm && lm->prim_cb) lm->prim_cb(&prim->oph, asp); + else { + LOGPASP(asp, DLSS7, LOGL_DEBUG, "No Layer Manager, dropping %s\n", + osmo_xlm_prim_name(&prim->oph)); + } msgb_free(prim->oph.msg); } @@ -334,10 +338,11 @@ ENSURE_ASP_OR_IPSP(fi, event); osmo_fsm_inst_state_chg(fi, XUA_ASP_S_INACTIVE, 0, 0); /* inform layer manager */ - send_xlm_prim_simple(fi, OSMO_XLM_PRIM_M_ASP_UP, - PRIM_OP_CONFIRM); - /* FIXME: This hack should be in layer manager? */ - osmo_fsm_inst_dispatch(fi, XUA_ASP_E_M_ASP_ACTIVE_REQ, NULL); + send_xlm_prim_simple(fi, OSMO_XLM_PRIM_M_ASP_UP, PRIM_OP_CONFIRM); + /* This hack should be in layer manager, but let's try + * to be smart in case there is no layer manager */ + if (!asp->lm) + osmo_fsm_inst_dispatch(fi, XUA_ASP_E_M_ASP_ACTIVE_REQ, NULL); break; case XUA_ASP_E_ASPSM_ASPUP: /* only if role SG */ diff --git a/src/xua_default_lm_fsm.c b/src/xua_default_lm_fsm.c new file mode 100644 index 0000000..fc9ba3c --- /dev/null +++ b/src/xua_default_lm_fsm.c @@ -0,0 +1,383 @@ +/* Default XUA Layer Manager */ +/* (C) 2017 by Harald Welte + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/* The idea of this default Layer Manager is as follows: + * - we wait until a SCTP connection is established + * - we issue the ASP-UP request and wait for the ASP being in UP state + * - we wait if we receive a M-NOTIFY indication about any AS in this ASP + * - if that's not received, we use RKM to register a routing context + * for our locally configured ASP and expect a positive registration + * result as well as a NOTIFY indication about AS-ACTIVE afterwards. + */ + +#include + +#include +#include +#include +#include +#include + +#include "xua_internal.h" +#include "xua_asp_fsm.h" + +#define S(x) (1 << (x)) + +enum lm_state { + /* idle state, SCTP not connected */ + S_IDLE, + /* we're waiting for the ASP-UP to be confirmed */ + S_WAIT_ASP_UP, + /* we are waiting for any NOTIFY about an AS in this ASP */ + S_WAIT_NOTIFY, + /* we've sent a RK REG REQ and wait for the result */ + S_RKM_REG, + /* all systems up, we're communicating */ + S_ACTIVE, +}; + +enum lm_event { + LM_E_SCTP_EST_IND, + LM_E_ASP_UP_CONF, + LM_E_NOTIFY_IND, + LM_E_AS_INACTIVE_IND, + LM_E_AS_ACTIVE_IND, + LM_E_AS_STATUS_IND, + LM_E_RKM_REG_CONF, + LM_E_SCTP_DISC_IND, +}; + +static const struct value_string lm_event_names[] = { + { LM_E_SCTP_EST_IND, "SCTP-ESTABLISH.ind" }, + { LM_E_ASP_UP_CONF, "ASP-UP.conf" }, + { LM_E_NOTIFY_IND, "NOTIFY.ind" }, + { LM_E_AS_INACTIVE_IND, "AS-INACTIVE.ind" }, + { LM_E_AS_ACTIVE_IND, "AS-ACTIVE.ind" }, + { LM_E_AS_STATUS_IND, "AS-STATUS.ind" }, + { LM_E_RKM_REG_CONF, "RKM_REG.conf" }, + { LM_E_SCTP_DISC_IND, "SCTP-RELEASE.ind" }, + { 0, NULL } +}; + +enum lm_timer { + T_WAIT_ASP_UP, + T_WAIT_NOTIFY, + T_WAIT_NOTIFY_RKM, + T_WAIT_RK_REG_RESP, +}; + +struct lm_fsm_priv { + struct osmo_ss7_asp *asp; +}; + +static struct osmo_ss7_as *find_first_as_in_asp(struct osmo_ss7_asp *asp) +{ + struct osmo_ss7_as *as; + + llist_for_each_entry(as, &asp->inst->as_list, list) { + unsigned int i; + for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) { + if (as->cfg.asps[i] == asp) + return as; + } + } + + return NULL; +} + +/* handle an incoming RKM registration response */ +static int handle_reg_conf(struct osmo_fsm_inst *fi, uint32_t l_rk_id, uint32_t rctx) +{ + struct lm_fsm_priv *lmp = fi->priv; + struct osmo_ss7_asp *asp = lmp->asp; + struct osmo_ss7_as *as; + + /* update the application server with the routing context as + * allocated/registered by the SG */ + as = osmo_ss7_as_find_by_l_rk_id(asp->inst, l_rk_id); + if (!as) { + LOGPFSM(fi, "RKM Result for unknown l_rk_id %u\n"); + return -EINVAL; + } + as->cfg.routing_key.context = rctx; + + return 0; +} + +static void restart_asp(struct osmo_fsm_inst *fi) +{ + struct lm_fsm_priv *lmp = fi->priv; + struct osmo_ss7_asp *asp = lmp->asp; + int log_level = fi->log_level; + + osmo_ss7_asp_restart(asp); + osmo_fsm_inst_term(fi, OSMO_FSM_TERM_ERROR, NULL); + osmo_ss7_asp_use_default_lm(asp, log_level); +} + + +static void lm_idle(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct lm_fsm_priv *lmp = fi->priv; + + switch (event) { + case LM_E_SCTP_EST_IND: + /* Try to transition to ASP-UP, wait for 20s */ + osmo_fsm_inst_state_chg(fi, S_WAIT_ASP_UP, 20, T_WAIT_ASP_UP); + osmo_fsm_inst_dispatch(lmp->asp->fi, XUA_ASP_E_M_ASP_UP_REQ, NULL); + break; + } +} + +static void lm_wait_asp_up(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + switch (event) { + case LM_E_ASP_UP_CONF: + /* ASP is sup, wait for some time if any NOTIFY + * indications about AS in this ASP are received */ + osmo_fsm_inst_state_chg(fi, S_WAIT_NOTIFY, 2, T_WAIT_NOTIFY); + break; + } +} + + +static int lm_timer_cb(struct osmo_fsm_inst *fi) +{ + struct lm_fsm_priv *lmp = fi->priv; + struct osmo_xlm_prim *prim; + struct osmo_ss7_as *as; + + switch (fi->T) { + case T_WAIT_ASP_UP: + /* we have been waiting for the ASP to come up, but it + * failed to do so */ + restart_asp(fi); + break; + case T_WAIT_NOTIFY: + /* No AS has reported via NOTIFY that is was + * (statically) configured at the SG for this ASP, so + * let's dynamically register */ + osmo_fsm_inst_state_chg(fi, S_RKM_REG, 10, T_WAIT_RK_REG_RESP); + prim = xua_xlm_prim_alloc(OSMO_XLM_PRIM_M_RK_REG, PRIM_OP_REQUEST); + as = find_first_as_in_asp(lmp->asp); + if (!as) { + LOGPFSML(fi, LOGL_ERROR, "Unable to find AS!\n"); + restart_asp(fi); + return 0; + } + /* Fill in settings from first AS (TODO: multiple AS support) */ + prim->u.rk_reg.key = as->cfg.routing_key; + osmo_xlm_sap_down(lmp->asp, &prim->oph); + break; + case T_WAIT_NOTIFY_RKM: + /* No AS has reported via NOTIFY even after dynamic RKM + * configuration */ + restart_asp(fi); + break; + case T_WAIT_RK_REG_RESP: + /* timeout of registration of routing key */ + restart_asp(fi); + break; + } + return 0; +} + +static void lm_wait_notify(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct lm_fsm_priv *lmp = fi->priv; + struct osmo_xlm_prim *oxp = data; + + switch (event) { + case LM_E_NOTIFY_IND: + OSMO_ASSERT(oxp->oph.primitive == OSMO_XLM_PRIM_M_NOTIFY); + OSMO_ASSERT(oxp->oph.operation == PRIM_OP_INDICATION); + if (oxp->u.notify.status_type == M3UA_NOTIFY_T_STATCHG && + (oxp->u.notify.status_info == M3UA_NOTIFY_I_AS_INACT || + oxp->u.notify.status_info == M3UA_NOTIFY_I_AS_PEND)) { + osmo_fsm_inst_state_chg(fi, S_ACTIVE, 0, 0); + osmo_fsm_inst_dispatch(lmp->asp->fi, XUA_ASP_E_M_ASP_ACTIVE_REQ, NULL); + } + break; + case LM_E_AS_INACTIVE_IND: + /* we now know that an AS is associated with this ASP at + * the SG, and that this AS is currently inactive */ + /* request the ASP to go into active state (which + * hopefully will bring the AS to active, too) */ + osmo_fsm_inst_state_chg(fi, S_ACTIVE, 0, 0); + osmo_fsm_inst_dispatch(lmp->asp->fi, XUA_ASP_E_M_ASP_ACTIVE_REQ, NULL); + break; + } +}; + +static void lm_rkm_reg(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct osmo_xlm_prim *oxp; + int rc; + + switch (event) { + case LM_E_RKM_REG_CONF: + oxp = data; + if (oxp->u.rk_reg.status != M3UA_RKM_REG_SUCCESS) { + LOGPFSML(fi, LOGL_NOTICE, "Received RKM_REG_RSP with negative result\n"); + restart_asp(fi); + } else { + rc = handle_reg_conf(fi, oxp->u.rk_reg.key.l_rk_id, oxp->u.rk_reg.key.context); + if (rc < 0) + restart_asp(fi); + /* RKM registration was successful, we can + * transition to WAIT_NOTIFY state and assume + * that an NOTIFY/AS-INACTIVE arrives within 20 + * seconds */ + osmo_fsm_inst_state_chg(fi, S_WAIT_NOTIFY, 20, T_WAIT_NOTIFY_RKM); + } + break; + } +} + +static void lm_active(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct lm_fsm_priv *lmp = fi->priv; + struct osmo_xlm_prim *oxp; + + switch (event) { + case LM_E_AS_INACTIVE_IND: + /* request the ASP to go into active state */ + osmo_fsm_inst_dispatch(lmp->asp->fi, XUA_ASP_E_M_ASP_ACTIVE_REQ, NULL); + break; + case LM_E_NOTIFY_IND: + oxp = data; + OSMO_ASSERT(oxp->oph.primitive == OSMO_XLM_PRIM_M_NOTIFY); + OSMO_ASSERT(oxp->oph.operation == PRIM_OP_INDICATION); + if (oxp->u.notify.status_type == M3UA_NOTIFY_T_STATCHG && + oxp->u.notify.status_info != M3UA_NOTIFY_I_AS_ACT) + restart_asp(fi); + break; + } +} + +static void lm_allstate(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + switch (event) { + case LM_E_SCTP_DISC_IND: + restart_asp(fi); + break; + } +} + +static const struct osmo_fsm_state lm_states[] = { + [S_IDLE] = { + .in_event_mask = S(LM_E_SCTP_EST_IND), + .out_state_mask = S(S_WAIT_ASP_UP), + .name = "IDLE", + .action = lm_idle, + }, + [S_WAIT_ASP_UP] = { + .in_event_mask = S(LM_E_ASP_UP_CONF), + .out_state_mask = S(S_WAIT_NOTIFY), + .name = "WAIT_ASP_UP", + .action = lm_wait_asp_up, + }, + [S_WAIT_NOTIFY] = { + .in_event_mask = S(LM_E_AS_INACTIVE_IND) | S(LM_E_NOTIFY_IND), + .out_state_mask = S(S_RKM_REG) | S(S_ACTIVE), + .name = "WAIT_NOTIFY", + .action = lm_wait_notify, + }, + [S_RKM_REG] = { + .in_event_mask = S(LM_E_RKM_REG_CONF), + .out_state_mask = S(S_WAIT_NOTIFY), + .name = "RKM_REG", + .action = lm_rkm_reg, + }, + [S_ACTIVE] = { + .in_event_mask = S(LM_E_AS_INACTIVE_IND) | S(LM_E_NOTIFY_IND), + .name = "ACTIVE", + .action = lm_active, + }, +}; + +/* Map from incoming XLM SAP primitives towards FSM events */ +static const struct osmo_prim_event_map lm_event_map[] = { + { XUA_SAP_LM, OSMO_XLM_PRIM_M_SCTP_ESTABLISH, PRIM_OP_INDICATION, LM_E_SCTP_EST_IND }, + { XUA_SAP_LM, OSMO_XLM_PRIM_M_SCTP_RELEASE, PRIM_OP_INDICATION, LM_E_SCTP_DISC_IND }, + { XUA_SAP_LM, OSMO_XLM_PRIM_M_ASP_UP, PRIM_OP_CONFIRM, LM_E_ASP_UP_CONF }, + { XUA_SAP_LM, OSMO_XLM_PRIM_M_AS_STATUS, PRIM_OP_INDICATION, LM_E_AS_STATUS_IND }, + { XUA_SAP_LM, OSMO_XLM_PRIM_M_NOTIFY, PRIM_OP_INDICATION, LM_E_NOTIFY_IND }, + { XUA_SAP_LM, OSMO_XLM_PRIM_M_AS_INACTIVE, PRIM_OP_INDICATION, LM_E_AS_INACTIVE_IND }, + { XUA_SAP_LM, OSMO_XLM_PRIM_M_AS_ACTIVE, PRIM_OP_INDICATION, LM_E_AS_ACTIVE_IND }, + { XUA_SAP_LM, OSMO_XLM_PRIM_M_RK_REG, PRIM_OP_CONFIRM, LM_E_RKM_REG_CONF }, + { 0, 0, 0, OSMO_NO_EVENT }, +}; + + +struct osmo_fsm xua_default_lm_fsm = { + .name = "xua_default_lm", + .states = lm_states, + .num_states = ARRAY_SIZE(lm_states), + .timer_cb = lm_timer_cb, + .event_names = lm_event_names, + .allstate_event_mask = S(LM_E_SCTP_DISC_IND), + .allstate_action = lm_allstate, + .log_subsys = DLSS7, +}; + + +/* layer manager primitive call-back function, registered osmo_ss7 */ +static int default_lm_prim_cb(struct osmo_prim_hdr *oph, void *_asp) +{ + struct osmo_ss7_asp *asp = _asp; + struct osmo_fsm_inst *fi = asp->lm_priv; + uint32_t event = osmo_event_for_prim(oph, lm_event_map); + char *prim_name = osmo_xlm_prim_name(oph); + + LOGPFSM(fi, "Received primitive %s\n", prim_name); + + if (event == OSMO_NO_EVENT) { + LOGPFSML(fi, LOGL_NOTICE, "Ignoring primitive %s\n", prim_name); + return 0; + } + + osmo_fsm_inst_dispatch(fi, event, oph); + + return 0; +} + +static const struct osmo_xua_layer_manager default_layer_manager = { + .prim_cb = default_lm_prim_cb, +}; + +int osmo_ss7_asp_use_default_lm(struct osmo_ss7_asp *asp, int log_level) +{ + struct lm_fsm_priv *lmp; + struct osmo_fsm_inst *fi; + + fi = osmo_fsm_inst_alloc(&xua_default_lm_fsm, asp, NULL, log_level, asp->cfg.name); + + lmp = talloc_zero(fi, struct lm_fsm_priv); + if (!lmp) { + osmo_fsm_inst_term(fi, OSMO_FSM_TERM_ERROR, NULL); + return -ENOMEM; + } + lmp->asp = asp; + fi->priv = lmp; + + asp->lm = &default_layer_manager; + asp->lm_priv = fi; + + return 0; +} diff --git a/src/xua_internal.h b/src/xua_internal.h index 171756b..468b7e4 100644 --- a/src/xua_internal.h +++ b/src/xua_internal.h @@ -56,5 +56,6 @@ enum osmo_xlm_prim_type prim_type, enum osmo_prim_operation op); +extern struct osmo_fsm xua_default_lm_fsm; extern const struct value_string m3ua_rkm_reg_status_vals[]; extern const struct value_string m3ua_rkm_dereg_status_vals[]; diff --git a/src/xua_rkm.c b/src/xua_rkm.c index ad6c880..0d576a7 100644 --- a/src/xua_rkm.c +++ b/src/xua_rkm.c @@ -102,6 +102,41 @@ return msg->tail - old_tail; } +static void xua_rkm_send_reg_req(struct osmo_ss7_asp *asp, + const struct osmo_ss7_routing_key *rkey, + enum osmo_ss7_as_traffic_mode traf_mode) +{ + struct msgb *msg = m3ua_msgb_alloc(__func__); + int tmod = osmo_ss7_tmode_to_xua(traf_mode); + + /* One individual Registration Request according to Chapter 3.6.1 */ + msgb_put_u16(msg, M3UA_IEI_ROUT_KEY); /* outer IEI */ + msgb_put_u16(msg, 32 + 4); /* outer length */ + /* nested IEIs */ + msgb_t16l16vp_put_u32(msg, M3UA_IEI_LOC_RKEY_ID, rkey->l_rk_id); + msgb_t16l16vp_put_u32(msg, M3UA_IEI_ROUTE_CTX, rkey->context); + msgb_t16l16vp_put_u32(msg, M3UA_IEI_TRAF_MODE_TYP, tmod); + msgb_t16l16vp_put_u32(msg, M3UA_IEI_DEST_PC, rkey->pc); + + msgb_push_m3ua_hdr(msg, M3UA_MSGC_RKM, M3UA_RKM_REG_REQ); + + osmo_ss7_asp_send(asp, msg); +} + +static void xua_rkm_send_dereg_req(struct osmo_ss7_asp *asp, uint32_t route_ctx) +{ + struct msgb *msg = m3ua_msgb_alloc(__func__); + + /* One individual De-Registration Request according to Chapter 3.6.3 */ + msgb_t16l16vp_put_u32(msg, M3UA_IEI_ROUTE_CTX, route_ctx); + + msgb_push_m3ua_hdr(msg, M3UA_MSGC_RKM, M3UA_RKM_DEREG_REQ); + + osmo_ss7_asp_send(asp, msg); +} + + + /* handle a single registration request IE (nested IEs in 'innner' */ static int handle_rkey_reg(struct osmo_ss7_asp *asp, struct xua_msg *inner, struct msgb *resp) @@ -277,16 +312,110 @@ return 0; } +/* handle a single registration response IE (nested IEs in 'inner' */ +static int handle_rkey_reg_resp(struct osmo_ss7_asp *asp, struct xua_msg *inner) +{ + struct osmo_xlm_prim *oxp; + + if (!xua_msg_find_tag(inner, M3UA_IEI_LOC_RKEY_ID) || + !xua_msg_find_tag(inner, M3UA_IEI_REG_STATUS) || + !xua_msg_find_tag(inner, M3UA_IEI_ROUTE_CTX)) { + LOGPASP(asp, DLSS7, LOGL_NOTICE, "Missing Inner IE in REG RESP\n"); + /* FIXME: ERROR to peer */ + return -1; + } + + oxp = xua_xlm_prim_alloc(OSMO_XLM_PRIM_M_RK_REG, PRIM_OP_CONFIRM); + if (!oxp) + return -1; + + oxp->u.rk_reg.key.l_rk_id = xua_msg_get_u32(inner, M3UA_IEI_LOC_RKEY_ID); + oxp->u.rk_reg.key.context = xua_msg_get_u32(inner, M3UA_IEI_ROUTE_CTX); + oxp->u.rk_reg.status = xua_msg_get_u32(inner, M3UA_IEI_REG_STATUS); + + LOGPASP(asp, DLSS7, LOGL_INFO, "Received RKM REG RES rctx=%u status=%s\n", + oxp->u.rk_reg.key.context, + get_value_string(m3ua_rkm_reg_status_vals, oxp->u.rk_reg.status)); + + /* Send primitive to LM */ + xua_asp_send_xlm_prim(asp, oxp); + + return 0; +} + /* receive a registration response (ASP role) */ static int m3ua_rx_rkm_reg_rsp(struct osmo_ss7_asp *asp, struct xua_msg *xua) { - /* TODO */ + struct xua_msg_part *part; + struct xua_msg *inner = NULL; + + llist_for_each_entry(part, &xua->headers, entry) { + /* skip other IEs and/or short REG_RES IEs */ + if (part->tag != M3UA_IEI_REG_RESULT || part->len < 24) + continue; + + /* we leave the above loop at the first valid + * registration result (we only support one AS per ASP + * for now) */ + inner = xua_from_nested(part); + if (!inner) + continue; + + handle_rkey_reg_resp(asp, inner); + } + return 0; +} + +/* handle a single deregistration response IE (nested IEs in 'inner' */ +static int handle_rkey_dereg_resp(struct osmo_ss7_asp *asp, struct xua_msg *inner) +{ + struct osmo_xlm_prim *oxp; + + if (!xua_msg_find_tag(inner, M3UA_IEI_DEREG_STATUS) || + !xua_msg_find_tag(inner, M3UA_IEI_ROUTE_CTX)) { + LOGPASP(asp, DLSS7, LOGL_NOTICE, "Missing Inner IE in DEREG RESP\n"); + /* FIXME: ERROR to peer */ + return -1; + } + + oxp = xua_xlm_prim_alloc(OSMO_XLM_PRIM_M_RK_DEREG, PRIM_OP_CONFIRM); + if (!oxp) + return -1; + + oxp->u.rk_dereg.route_ctx = xua_msg_get_u32(inner, M3UA_IEI_ROUTE_CTX); + oxp->u.rk_dereg.status = xua_msg_get_u32(inner, M3UA_IEI_DEREG_STATUS); + + LOGPASP(asp, DLSS7, LOGL_INFO, "Received RKM DEREG RES rctx=%u status=%s\n", + oxp->u.rk_reg.key.context, + get_value_string(m3ua_rkm_dereg_status_vals, oxp->u.rk_dereg.status)); + + /* Send primitive to LM */ + xua_asp_send_xlm_prim(asp, oxp); + + return 0; } /* receive a deregistration response (ASP role) */ static int m3ua_rx_rkm_dereg_rsp(struct osmo_ss7_asp *asp, struct xua_msg *xua) { - /* TODO */ + struct xua_msg_part *part; + struct xua_msg *inner = NULL; + + llist_for_each_entry(part, &xua->headers, entry) { + /* skip other IEs and/or short REG_RES IEs */ + if (part->tag != M3UA_IEI_DEREG_RESULT || part->len < 16) + continue; + + /* we leave the above loop at the first valid + * registration result (we only support one AS per ASP + * for now) */ + inner = xua_from_nested(part); + if (!inner) + continue; + + handle_rkey_dereg_resp(asp, inner); + } + return 0; } /* process an incoming RKM message in xua format */ @@ -321,3 +450,28 @@ } return rc; } + +int osmo_xlm_sap_down(struct osmo_ss7_asp *asp, struct osmo_prim_hdr *oph) +{ + struct osmo_xlm_prim *prim = (struct osmo_xlm_prim *) oph; + + LOGPASP(asp, DLSS7, LOGL_DEBUG, "Received XUA Layer Manager Primitive: %s)\n", + osmo_xlm_prim_name(&prim->oph)); + + switch (OSMO_PRIM_HDR(&prim->oph)) { + case OSMO_PRIM(OSMO_XLM_PRIM_M_RK_REG, PRIM_OP_REQUEST): + /* Layer Manager asks us to send a Routing Key Reg Request */ + xua_rkm_send_reg_req(asp, &prim->u.rk_reg.key, prim->u.rk_reg.traf_mode); + break; + case OSMO_PRIM(OSMO_XLM_PRIM_M_RK_DEREG, PRIM_OP_REQUEST): + /* Layer Manager asks us to send a Routing Key De-Reg Request */ + xua_rkm_send_dereg_req(asp, prim->u.rk_dereg.route_ctx); + break; + default: + LOGPASP(asp, DLSS7, LOGL_ERROR, "Unknown XUA Layer Manager Primitive: %s\n", + osmo_xlm_prim_name(&prim->oph)); + break; + } + + return 0; +} -- To view, visit https://gerrit.osmocom.org/2283 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I78d4623dd213b5c59007a026a6cc3cfe5c04af50 Gerrit-PatchSet: 2 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Thu Apr 13 17:09:47 2017 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Thu, 13 Apr 2017 17:09:47 +0000 Subject: [PATCH] osmo-bts[master]: bts: revert trx shutdown order In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/1977 to look at the new patch set (#5). bts: revert trx shutdown order The BTS Transcievers are stored in a linked list. When the BTS is shut down, the rf is disabled and the trx is then closed. this patch reverts the order of the list processing. Change-Id: I18485de586b402610f9e98053d69e92bc9b18dc2 --- M src/common/bts.c 1 file changed, 1 insertion(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/77/1977/5 diff --git a/src/common/bts.c b/src/common/bts.c index 540caaa..cb5284d 100644 --- a/src/common/bts.c +++ b/src/common/bts.c @@ -207,7 +207,7 @@ LOGP(DOML, LOGL_NOTICE, "Shutting down BTS %u, Reason %s\n", bts->nr, reason); - llist_for_each_entry(trx, &bts->trx_list, list) { + llist_for_each_entry_reverse(trx, &bts->trx_list, list) { bts_model_trx_deact_rf(trx); bts_model_trx_close(trx); } -- To view, visit https://gerrit.osmocom.org/1977 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I18485de586b402610f9e98053d69e92bc9b18dc2 Gerrit-PatchSet: 5 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Thu Apr 13 17:09:47 2017 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Thu, 13 Apr 2017 17:09:47 +0000 Subject: [PATCH] osmo-bts[master]: octphy: WIP: Bug in while auto-activating all SAPIs for the ... In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2314 to look at the new patch set (#3). octphy: WIP: Bug in while auto-activating all SAPIs for the BCCH/CCCH on TS0 This change most likely introduces a bug. The if that detects for TS0 in order to activate the SAPIs for the BCCH/CCCH is changed to match on TS7. (mo->obj_inst.ts_nr == 7). So the activation definetly won't take place when mo is related to TS0. Probably this might be a hack, the SAPIs shall be activated later, so on TS7 (initalization is almost through then) the SAPIS get activated. I need more information on this. Change-Id: Ie307bf9f370a346686e3bd8c8a8483953a1bc279 --- M src/osmo-bts-octphy/l1_oml.c 1 file changed, 1 insertion(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/14/2314/3 diff --git a/src/osmo-bts-octphy/l1_oml.c b/src/osmo-bts-octphy/l1_oml.c index 21ff907..4652e10 100644 --- a/src/osmo-bts-octphy/l1_oml.c +++ b/src/osmo-bts-octphy/l1_oml.c @@ -187,7 +187,7 @@ /* hack to auto-activate all SAPIs for the BCCH/CCCH on TS0 */ if (mo->obj_class == NM_OC_CHANNEL && mo->obj_inst.trx_nr == 0 && - mo->obj_inst.ts_nr == 0) { + mo->obj_inst.ts_nr == 7) { struct gsm_lchan *cbch = gsm_bts_get_cbch(mo->bts); mo->bts->c0->ts[0].lchan[CCCH_LCHAN].rel_act_kind = LCHAN_REL_ACT_OML; -- To view, visit https://gerrit.osmocom.org/2314 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ie307bf9f370a346686e3bd8c8a8483953a1bc279 Gerrit-PatchSet: 3 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Thu Apr 13 17:09:47 2017 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Thu, 13 Apr 2017 17:09:47 +0000 Subject: [PATCH] osmo-bts[master]: octphy: remove old event control code In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/1980 to look at the new patch set (#6). octphy: remove old event control code Enable/Disable events is no longer required, this commit removes the related code Change-Id: I0652627495f6a9bcb0da2431b8beb839bc22062b --- M src/osmo-bts-octphy/l1_oml.c 1 file changed, 1 insertion(+), 83 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/80/1980/6 diff --git a/src/osmo-bts-octphy/l1_oml.c b/src/osmo-bts-octphy/l1_oml.c index c70b45f..21ff907 100644 --- a/src/osmo-bts-octphy/l1_oml.c +++ b/src/osmo-bts-octphy/l1_oml.c @@ -1089,84 +1089,6 @@ return 0; } -static int enable_events_compl_cb(struct octphy_hdl *fl1, struct msgb *resp, void *data) -{ - tOCTVC1_MAIN_MSG_API_SYSTEM_MODIFY_SESSION_EVT_RSP *mser = - (tOCTVC1_MAIN_MSG_API_SYSTEM_MODIFY_SESSION_EVT_RSP *) resp->l2h; - - /* in a completion call-back, we take msgb ownership and must - * release it before returning */ - - mOCTVC1_MAIN_MSG_API_SYSTEM_MODIFY_SESSION_EVT_RSP_SWAP(mser); - - LOGP(DL1C, LOGL_INFO, "Rx ENABLE-EVT-REC.resp\n"); - - msgb_free(resp); - - return 0; -} - -static int disable_events_compl_cb(struct octphy_hdl *fl1, struct msgb *resp, void *data) -{ - tOCTVC1_MAIN_MSG_API_SYSTEM_MODIFY_SESSION_EVT_RSP *mser = - (tOCTVC1_MAIN_MSG_API_SYSTEM_MODIFY_SESSION_EVT_RSP *) resp->l2h; - - /* in a completion call-back, we take msgb ownership and must - * release it before returning */ - - mOCTVC1_MAIN_MSG_API_SYSTEM_MODIFY_SESSION_EVT_RSP_SWAP(mser); - - LOGP(DL1C, LOGL_INFO, "Rx DISABLE-EVT-REC.resp\n"); - - msgb_free(resp); - - return 0; -} - -int l1if_enable_events(struct gsm_bts_trx *trx) -{ - struct phy_instance *pinst = trx_phy_instance(trx); - struct octphy_hdl *fl1h = pinst->phy_link->u.octphy.hdl; - struct msgb *msg = l1p_msgb_alloc(); - tOCTVC1_MAIN_MSG_API_SYSTEM_MODIFY_SESSION_EVT_CMD *mse; - - mse = (tOCTVC1_MAIN_MSG_API_SYSTEM_MODIFY_SESSION_EVT_CMD *) - msgb_put(msg, sizeof(*mse)); - mOCTVC1_MAIN_MSG_API_SYSTEM_MODIFY_SESSION_EVT_CMD_DEF(mse); - - l1if_fill_msg_hdr(&mse->Header, msg, fl1h, cOCTVC1_MSG_TYPE_COMMAND, - cOCTVC1_MAIN_MSG_API_SYSTEM_MODIFY_SESSION_EVT_CID); - mse->ulEvtActiveFlag = cOCT_TRUE; - - mOCTVC1_MAIN_MSG_API_SYSTEM_MODIFY_SESSION_EVT_CMD_SWAP(mse); - - LOGP(DL1C, LOGL_INFO, "Tx ENABLE-EVT-REC.req\n"); - - return l1if_req_compl(fl1h, msg, disable_events_compl_cb, 0); -} - -int l1if_disable_events(struct gsm_bts_trx *trx) -{ - struct phy_instance *pinst = trx_phy_instance(trx); - struct octphy_hdl *fl1h = pinst->phy_link->u.octphy.hdl; - struct msgb *msg = l1p_msgb_alloc(); - tOCTVC1_MAIN_MSG_API_SYSTEM_MODIFY_SESSION_EVT_CMD *mse; - - mse = (tOCTVC1_MAIN_MSG_API_SYSTEM_MODIFY_SESSION_EVT_CMD *) - msgb_put(msg, sizeof(*mse)); - mOCTVC1_MAIN_MSG_API_SYSTEM_MODIFY_SESSION_EVT_CMD_DEF(mse); - - l1if_fill_msg_hdr(&mse->Header, msg, fl1h, cOCTVC1_MSG_TYPE_COMMAND, - cOCTVC1_MAIN_MSG_API_SYSTEM_MODIFY_SESSION_EVT_CID); - mse->ulEvtActiveFlag = cOCT_FALSE; - - mOCTVC1_MAIN_MSG_API_SYSTEM_MODIFY_SESSION_EVT_CMD_SWAP(mse); - - LOGP(DL1C, LOGL_INFO, "Tx DISABLE-EVT-REC.req\n"); - - return l1if_req_compl(fl1h, msg, disable_events_compl_cb, 0); -} - #define talloc_replace(dst, ctx, src) \ do { \ if (dst) \ @@ -1353,8 +1275,7 @@ octphy_hw_get_clock_sync_info(fl1h); fl1h->opened = 1; - /* Temporary fix for enabling events after TRX Close + Reopen */ - return l1if_enable_events(trx); + return 0; } int l1if_trx_open(struct gsm_bts_trx *trx) @@ -1628,9 +1549,6 @@ int bts_model_trx_close(struct gsm_bts_trx *trx) { - /* disable events */ - l1if_disable_events(trx); - /* FIXME: close only one TRX */ return trx_close(trx); } -- To view, visit https://gerrit.osmocom.org/1980 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I0652627495f6a9bcb0da2431b8beb839bc22062b Gerrit-PatchSet: 6 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From admin at opensuse.org Thu Apr 13 20:01:17 2017 From: admin at opensuse.org (OBS Notification) Date: Thu, 13 Apr 2017 20:01:17 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in xUbuntu_16.10/i586 In-Reply-To: References: Message-ID: <58efd937bd100_98f1156f84558825@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/xUbuntu_16.10/i586 Package network:osmocom:nightly/osmo-stp failed to build in xUbuntu_16.10/i586 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 70s] ^~~~~~~ [ 70s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o vty_interface.o vty_interface.c [ 71s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o sctp_m3ua_client.o sctp_m3ua_client.c [ 71s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 71s] #include [ 71s] ^ [ 71s] compilation terminated. [ 71s] Makefile:485: recipe for target 'sctp_m3ua_client.o' failed [ 71s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 71s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 71s] Makefile:380: recipe for target 'all-recursive' failed [ 71s] make[2]: *** [all-recursive] Error 1 [ 71s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 71s] Makefile:321: recipe for target 'all' failed [ 71s] make[1]: *** [all] Error 2 [ 71s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 71s] dh_auto_build: make -j1 returned exit code 2 [ 71s] debian/rules:23: recipe for target 'build' failed [ 71s] make: *** [build] Error 2 [ 71s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 71s] [ 71s] wildcard2 failed "build cellmgr-ng_1.4.7.20170413.dsc" at Thu Apr 13 20:00:54 UTC 2017. [ 71s] [ 71s] ### VM INTERACTION START ### [ 74s] [ 59.975788] reboot: Power down [ 77s] ### VM INTERACTION END ### [ 77s] [ 77s] wildcard2 failed "build cellmgr-ng_1.4.7.20170413.dsc" at Thu Apr 13 20:01:01 UTC 2017. [ 77s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Thu Apr 13 20:01:34 2017 From: admin at opensuse.org (OBS Notification) Date: Thu, 13 Apr 2017 20:01:34 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in Debian_8.0/x86_64 In-Reply-To: References: Message-ID: <58efd9523300c_c7610b4f7c497879@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/Debian_8.0/x86_64 Package network:osmocom:nightly/osmo-stp failed to build in Debian_8.0/x86_64 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 88s] CC vty_interface.o [ 89s] CC sctp_m3ua_client.o [ 89s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 89s] #include [ 89s] ^ [ 89s] compilation terminated. [ 89s] Makefile:475: recipe for target 'sctp_m3ua_client.o' failed [ 89s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 89s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 89s] Makefile:370: recipe for target 'all-recursive' failed [ 89s] make[2]: *** [all-recursive] Error 1 [ 89s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 89s] Makefile:310: recipe for target 'all' failed [ 89s] make[1]: *** [all] Error 2 [ 89s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 89s] dh_auto_build: make -j1 returned exit code 2 [ 89s] debian/rules:23: recipe for target 'build' failed [ 89s] make: *** [build] Error 2 [ 89s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 89s] [ 89s] lamb12 failed "build cellmgr-ng_1.4.7.20170413.dsc" at Thu Apr 13 20:01:16 UTC 2017. [ 89s] [ 89s] ### VM INTERACTION START ### [ 90s] Powering off. [ 90s] [ 75.865198] reboot: Power down [ 90s] ### VM INTERACTION END ### [ 90s] [ 90s] lamb12 failed "build cellmgr-ng_1.4.7.20170413.dsc" at Thu Apr 13 20:01:18 UTC 2017. [ 90s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Thu Apr 13 20:01:34 2017 From: admin at opensuse.org (OBS Notification) Date: Thu, 13 Apr 2017 20:01:34 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in xUbuntu_16.10/x86_64 In-Reply-To: References: Message-ID: <58efd9526cf43_c7610b4f7c4979ed@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/xUbuntu_16.10/x86_64 Package network:osmocom:nightly/osmo-stp failed to build in xUbuntu_16.10/x86_64 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 74s] ^~~~~~~ [ 75s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o vty_interface.o vty_interface.c [ 75s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o sctp_m3ua_client.o sctp_m3ua_client.c [ 75s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 75s] #include [ 75s] ^ [ 75s] compilation terminated. [ 75s] Makefile:485: recipe for target 'sctp_m3ua_client.o' failed [ 75s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 75s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 75s] Makefile:380: recipe for target 'all-recursive' failed [ 75s] make[2]: *** [all-recursive] Error 1 [ 75s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 75s] Makefile:321: recipe for target 'all' failed [ 75s] make[1]: *** [all] Error 2 [ 75s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 75s] dh_auto_build: make -j1 returned exit code 2 [ 75s] debian/rules:23: recipe for target 'build' failed [ 75s] make: *** [build] Error 2 [ 75s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 75s] [ 75s] lamb04 failed "build cellmgr-ng_1.4.7.20170413.dsc" at Thu Apr 13 20:01:16 UTC 2017. [ 75s] [ 75s] ### VM INTERACTION START ### [ 78s] [ 65.356483] reboot: Power down [ 78s] ### VM INTERACTION END ### [ 78s] [ 78s] lamb04 failed "build cellmgr-ng_1.4.7.20170413.dsc" at Thu Apr 13 20:01:19 UTC 2017. [ 78s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Thu Apr 13 20:03:00 2017 From: admin at opensuse.org (OBS Notification) Date: Thu, 13 Apr 2017 20:03:00 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in Debian_8.0/i586 In-Reply-To: References: Message-ID: <58efd9aec0a08_98f1156f845589b@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/Debian_8.0/i586 Package network:osmocom:nightly/osmo-stp failed to build in Debian_8.0/i586 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 88s] CC vty_interface.o [ 88s] CC sctp_m3ua_client.o [ 88s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 88s] #include [ 88s] ^ [ 88s] compilation terminated. [ 89s] Makefile:475: recipe for target 'sctp_m3ua_client.o' failed [ 89s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 89s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 89s] Makefile:370: recipe for target 'all-recursive' failed [ 89s] make[2]: *** [all-recursive] Error 1 [ 89s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 89s] Makefile:310: recipe for target 'all' failed [ 89s] make[1]: *** [all] Error 2 [ 89s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 89s] dh_auto_build: make -j1 returned exit code 2 [ 89s] debian/rules:23: recipe for target 'build' failed [ 89s] make: *** [build] Error 2 [ 89s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 89s] [ 89s] lamb63 failed "build cellmgr-ng_1.4.7.20170413.dsc" at Thu Apr 13 20:02:46 UTC 2017. [ 89s] [ 89s] ### VM INTERACTION START ### [ 90s] Powering off. [ 90s] [ 75.811614] reboot: Power down [ 90s] ### VM INTERACTION END ### [ 90s] [ 90s] lamb63 failed "build cellmgr-ng_1.4.7.20170413.dsc" at Thu Apr 13 20:02:48 UTC 2017. [ 90s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Thu Apr 13 20:04:26 2017 From: admin at opensuse.org (OBS Notification) Date: Thu, 13 Apr 2017 20:04:26 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in xUbuntu_16.04/x86_64 In-Reply-To: References: Message-ID: <58efd9e912480_99c1156f846528bf@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/xUbuntu_16.04/x86_64 Package network:osmocom:nightly/osmo-stp failed to build in xUbuntu_16.04/x86_64 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 95s] sctp_m2ua.c:91:3: warning: #warning "Notify any other AS(P) for failover scenario" [-Wcpp] [ 95s] #warning "Notify any other AS(P) for failover scenario" [ 95s] ^ [ 95s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -c -o vty_interface.o vty_interface.c [ 96s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -c -o sctp_m3ua_client.o sctp_m3ua_client.c [ 96s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 96s] compilation terminated. [ 96s] Makefile:485: recipe for target 'sctp_m3ua_client.o' failed [ 96s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 96s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 96s] Makefile:380: recipe for target 'all-recursive' failed [ 96s] make[2]: *** [all-recursive] Error 1 [ 96s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 96s] Makefile:321: recipe for target 'all' failed [ 96s] make[1]: *** [all] Error 2 [ 96s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 96s] dh_auto_build: make -j1 returned exit code 2 [ 96s] debian/rules:23: recipe for target 'build' failed [ 96s] make: *** [build] Error 2 [ 96s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 96s] [ 96s] lamb53 failed "build cellmgr-ng_1.4.7.20170413.dsc" at Thu Apr 13 20:04:17 UTC 2017. [ 96s] [ 96s] ### VM INTERACTION START ### [ 99s] [ 85.742301] reboot: Power down [ 99s] ### VM INTERACTION END ### [ 99s] [ 99s] lamb53 failed "build cellmgr-ng_1.4.7.20170413.dsc" at Thu Apr 13 20:04:20 UTC 2017. [ 99s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Thu Apr 13 20:04:43 2017 From: admin at opensuse.org (OBS Notification) Date: Thu, 13 Apr 2017 20:04:43 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in xUbuntu_16.04/i586 In-Reply-To: References: Message-ID: <58efd9e98753f_99c1156f8465296c@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/xUbuntu_16.04/i586 Package network:osmocom:nightly/osmo-stp failed to build in xUbuntu_16.04/i586 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 95s] sctp_m2ua.c:91:3: warning: #warning "Notify any other AS(P) for failover scenario" [-Wcpp] [ 95s] #warning "Notify any other AS(P) for failover scenario" [ 95s] ^ [ 95s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -c -o vty_interface.o vty_interface.c [ 95s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -c -o sctp_m3ua_client.o sctp_m3ua_client.c [ 95s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 95s] compilation terminated. [ 95s] Makefile:485: recipe for target 'sctp_m3ua_client.o' failed [ 95s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 95s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 95s] Makefile:380: recipe for target 'all-recursive' failed [ 95s] make[2]: *** [all-recursive] Error 1 [ 95s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 95s] Makefile:321: recipe for target 'all' failed [ 95s] make[1]: *** [all] Error 2 [ 95s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 95s] dh_auto_build: make -j1 returned exit code 2 [ 95s] debian/rules:23: recipe for target 'build' failed [ 95s] make: *** [build] Error 2 [ 95s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 95s] [ 95s] lamb03 failed "build cellmgr-ng_1.4.7.20170413.dsc" at Thu Apr 13 20:04:27 UTC 2017. [ 95s] [ 95s] ### VM INTERACTION START ### [ 99s] [ 85.202701] reboot: Power down [ 99s] ### VM INTERACTION END ### [ 99s] [ 99s] lamb03 failed "build cellmgr-ng_1.4.7.20170413.dsc" at Thu Apr 13 20:04:32 UTC 2017. [ 99s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From gerrit-no-reply at lists.osmocom.org Fri Apr 14 02:23:16 2017 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 14 Apr 2017 02:23:16 +0000 Subject: [PATCH] osmo-gsm-manuals[master]: Add Osmo-GSM-Tester manual Message-ID: Review at https://gerrit.osmocom.org/2325 Add Osmo-GSM-Tester manual Change-Id: I8a9c0bfbce0072359c5094b940f225082d6847a7 --- M Makefile A Osmo-GSM-Tester/Makefile A Osmo-GSM-Tester/chapters/config.adoc A Osmo-GSM-Tester/chapters/debugging.adoc A Osmo-GSM-Tester/chapters/intro.adoc A Osmo-GSM-Tester/chapters/test_api.adoc A Osmo-GSM-Tester/chapters/trial.adoc A Osmo-GSM-Tester/osmo-gsm-tester-manual-docinfo.xml A Osmo-GSM-Tester/osmo-gsm-tester-manual.adoc 9 files changed, 607 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-gsm-manuals refs/changes/25/2325/1 diff --git a/Makefile b/Makefile index 035595c..362f171 100644 --- a/Makefile +++ b/Makefile @@ -6,6 +6,7 @@ cd OsmoSGSN; $(MAKE) cd OsmoNAT; $(MAKE) cd OsmoPCU; $(MAKE) + cd Osmo-GSM-Tester; $(MAKE) clean: cd OsmoBTS; $(MAKE) clean @@ -15,6 +16,7 @@ cd OsmoSGSN; $(MAKE) clean cd OsmoNAT; $(MAKE) clean cd OsmoPCU; $(MAKE) clean + cd Osmo-GSM-Tester; $(MAKE) clean upload: cd OsmoBTS; $(MAKE) upload @@ -24,6 +26,7 @@ cd OsmoSGSN; $(MAKE) upload cd OsmoNAT; $(MAKE) upload cd OsmoPCU; $(MAKE) upload + cd Osmo-GSM-Tester; $(MAKE) upload check: cd OsmoBTS; $(MAKE) check @@ -34,3 +37,4 @@ # These don't use asciidoc, so they have no 'make check' target: #cd OsmoMGCP; $(MAKE) check #cd OsmoNAT; $(MAKE) check + cd Osmo-GSM-Tester; $(MAKE) check diff --git a/Osmo-GSM-Tester/Makefile b/Osmo-GSM-Tester/Makefile new file mode 100644 index 0000000..79d414f --- /dev/null +++ b/Osmo-GSM-Tester/Makefile @@ -0,0 +1,12 @@ +TOPDIR := .. +ASCIIDOCS := osmo-gsm-tester-manual + +include $(TOPDIR)/build/Makefile.asciidoc.inc +include $(TOPDIR)/build/Makefile.inc + +osmo-gsm-tester-manual.pdf: chapters/*.adoc + +clean: + -rm -rf $(cleanfiles) + -rm osmo-gsm-tester-manual__*.svg + -rm osmo-gsm-tester-manual__*.png diff --git a/Osmo-GSM-Tester/chapters/config.adoc b/Osmo-GSM-Tester/chapters/config.adoc new file mode 100644 index 0000000..66f4b71 --- /dev/null +++ b/Osmo-GSM-Tester/chapters/config.adoc @@ -0,0 +1,225 @@ +== Configuration + +The osmo-gsm-tester looks for configuration files in various standard +directories in this order: + +- '$HOME/.config/osmo-gsm-tester/' +- '/usr/local/etc/osmo-gsm-tester/' +- '/etc/osmo-gsm-tester/' + +The config location can also be set by an environment variable +'$OSMO_GSM_TESTER_CONF', which then overrides the above locations. + +The osmo-gsm-tester expects to find the following configuration files in a +configuration directory: + +- 'paths.conf' +- 'resources.conf' +- 'default-suites.conf' (optional) +- 'defaults.conf' (optional) + +=== Format: YAML, and its Drawbacks + +The general configuration format used is YAML. The stock python YAML parser +does have several drawbacks: too many complex possibilities and alternative +ways of formatting a configuration, but at the time of writing seems to be the +only widely used configuration format that offers a simple and human readable +formatting as well as nested structuring. It is recommended to use only the +exact YAML subset seen in this manual in case the osmo-gsm-tester should move +to a less bloated parser in the future. + +Careful: if a configuration item consists of digits and starts with a zero, you +need to quote it, or it may be interpreted as an octal notation integer! Please +avoid using the octal notation on purpose, it is not provided intentionally. + +[[paths_conf]] +=== 'paths.conf' + +The 'paths.conf' file defines where to store the global state (of reserved +resources) and where to find suite and scenario definitions. + +Any relative paths found in a 'paths.conf' file are interpreted as relative to +the directory of that 'paths.conf' file. + +Example: + +---- +state_dir: '/var/run/osmo-gsm-tester' +suites_dir: './suites' +scenarios_dir: './scenarios' +---- + +If you would like to set up several separate 'paths.conf' files (not typical), +note that the 'state_dir' is used to reserve resources, which only works when +all configurations that share resources also use the same 'state_dir'. + +[[resources_conf]] +=== 'resources.conf' + +The 'resources.conf' file defines which hardware is connected to the main unit, +as well as which limited configuration items (like IP addresses or ARFCNs) +should be used. + +These resources are allocated dynamically and are not configured explicitly: + +- MSISDN: phone numbers are dealt out to test scripts in sequence on request. + +A 'resources.conf' is structured as a list of items for each resource type, +where each item has one or more settings -- for an example, see +<>. + +These kinds of resource are known: + +'nitb_iface':: + List of IP addresses to run osmo-nitb instances on. The main unit + typically has a limited number of such IP addresses configured, which + the connected BTS models can see on their network. + 'addr'::: + IPv4 address of the local interface. + +'bts':: + List of available BTS hardware. + 'label'::: + human readable label for your own reference + 'type'::: + which way to launch this BTS, one of + - 'osmo-bts-sysmo' + - 'osmo-bts-trx' + - 'osmo-bts-octphy' + - 'ipa-nanobts' + 'addr'::: + remote IP address of the BTS, used to start the BTS and tell it where + to find the OsmoNITB. + 'band'::: + GSM band that this BTS shoud use (*TODO*: allow multiple bands). One of: + - 'GSM-1800' + - 'GSM-1900' + - (*TODO*: more bands) + 'trx_list'::: + Specific TRX configurations for this BTS. There should be as many of + these as the BTS has TRXes. (*TODO*: a way to define >1 TRX without + special configuration for them.) + 'hw_addr':::: + Hardware (MAC) address of the TRX in the form of '11:22:33:44:55:66', + only used for osmo-bts-octphy. (*TODO*: and nanobts??) + 'net_device':::: + Local network device to reach the TRX's 'hw_addr' at, only used for + osmo-bts-octphy. + +'arfcn':: + List of ARFCNs to use for running BTSes, which defines the actual RF + frequency bands used. + 'arfcn'::: + ARFCN number, see e.g. + https://en.wikipedia.org/wiki/Absolute_radio-frequency_channel_number + (note that the resource type 'arfcn' contains an item trait also named + 'arfcn') + 'band'::: + GSM band name to use this ARFCN for, same as for 'bts:band' above. + +'modem':: + List of modems reachable via ofono and information on the inserted SIM + card. (Note: the MSISDN is allocated dynamically in test scripts) + 'label'::: + human readable label for your own reference + 'path'::: + ofono's path for this modem, like '/modemkind_99' + 'imsi'::: + IMSI of the inserted SIM card, like '"123456789012345"' + 'ki'::: + 16 byte authentication/encryption KI of the inserted SIM card, in + hexadecimal notation (32 characters) like + + '"00112233445566778899aabbccddeeff"' (*TODO*: authentication algorithm, + currently always comp128v1) + +Side note: at first sight it might make sense to the reader to rather structure +e.g. the 'nitb_iface' or 'arfcn' configuration as + +'"arfcn: GSM-1800: [512, 514, ...]"', + +but the more verbose format is chosen to stay consistent with the general +structure of resource configurations, which the resource allocation algorithm +uses to resolve required resources according to their traits. These +configurations look cumbersome because they exhibit only one trait / a trait +that is repeated numerous times. No special notation for these cases is +available (yet). + +[[default_suites]] +=== 'default-suites.conf' (optional) + +The 'default-suites.conf' file contains a list of 'suite:scenario+scenario+...' +combination strings as defined by the 'osmo-gsm-tester.py -s' commandline +option. If invoking the 'osmo-gsm-tester.py' without any suite definitions, the +'-s' arguments are taken from this file instead. Each of these suite + scenario +combinations is run in sequence. + +A suite name must match the name of a directory in the 'suites_dir' as defined +by 'paths.conf'. + +A scenario name must match the name of a configuration file in the +'scenarios_dir' as defined by 'paths.conf' (optionally without the '.conf' +suffix). + +For 'paths.conf', see <>. + +Example of a 'default-suites.conf' file: + +---- +- sms:sysmo +- voice:sysmo+tch_f +- voice:sysmo+tch_h +- voice:sysmo+dyn_ts +- sms:trx +- voice:trx+tch_f +- voice:trx+tch_h +- voice:trx+dyn_ts +---- + +=== 'defaults.conf' (optional) + +Each binary run by osmo-gsm-tester, e.g. 'osmo-nitb' or 'osmo-bts-sysmo', +typically has a configuration file template that is populated with values for a +trial run. + +Some of these values are provided by the 'resources.conf' from the allocated +resource(s), but not all values can be populated this way: some osmo-nitb +configuration values like the network name, encryption algorithm or timeslot +channel combinations are in fact not resources (only the nitb's interface +address is). These additional settings may be provided by the scenario +configurations, but in case the provided scenarios leave some values unset, +they are taken from this 'defaults.conf'. (A 'scenario.conf' providing a +similar setting always has precedence over the values given in a +'defaults.conf'). + +*TODO* better match this format with 'resources.conf'? + +Example of a 'defaults.conf': + +---- +nitb: + net: + mcc: 1 + mnc: 868 + short_name: osmo-gsm-tester + long_name: osmo-gsm-tester + auth_policy: closed + encryption: a5 0 + +nitb_bts: + location_area_code: 23 + base_station_id_code: 63 + stream_id: 255 + osmobsc_bts_type: sysmobts + trx_list: + - max_power_red: 22 + arfcn: 868 + timeslot_list: + - phys_chan_config: CCCH+SDCCH4 + - phys_chan_config: SDCCH8 + - phys_chan_config: TCH/F_TCH/H_PDCH + - phys_chan_config: TCH/F_TCH/H_PDCH + - phys_chan_config: TCH/F_TCH/H_PDCH + - phys_chan_config: TCH/F_TCH/H_PDCH + - phys_chan_config: TCH/F_TCH/H_PDCH + - phys_chan_config: TCH/F_TCH/H_PDCH +---- + +*TODO*: detailed descriptions diff --git a/Osmo-GSM-Tester/chapters/debugging.adoc b/Osmo-GSM-Tester/chapters/debugging.adoc new file mode 100644 index 0000000..bea1e5c --- /dev/null +++ b/Osmo-GSM-Tester/chapters/debugging.adoc @@ -0,0 +1,4 @@ +[[debugging]] +== Debugging + +*TODO*: describe how to invoke 'ipdb3' and step into a suite's test script diff --git a/Osmo-GSM-Tester/chapters/intro.adoc b/Osmo-GSM-Tester/chapters/intro.adoc new file mode 100644 index 0000000..be753f8 --- /dev/null +++ b/Osmo-GSM-Tester/chapters/intro.adoc @@ -0,0 +1,270 @@ +== Introduction with Examples + +The osmo-gsm-tester is software to run automated tests of real GSM hardware, +foremost to verify that ongoing Osmocom software development continues to work +with various BTS models, while being flexibly configurable and extendable. + +A 'main unit' (general purpose computer) is connected via ethernet and/or USB to +any number of BTS models and to any number of GSM modems via USB. The modems +and BTS instances' RF transceivers are typically wired directly to each other +via RF distribution chambers to bypass the air medium and avoid disturbing real +production cellular networks. Furthermore, the setup may include adjustable RF +attenuators to model various distances between modems and base stations. + +The osmo-gsm-tester software runs on the main unit to orchestrate the various +GSM hardware and run predefined test scripts. It typically receives binary +packages from a jenkins build service. It then automatically configures and +launches an Osmocom core network on the main unit and sets up and runs BTS +models as well as modems to form a complete ad-hoc GSM network. On this setup, +predefined test suites, combined with various scenario definitions, are run to +verify stability of the system. + +The osmo-gsm-tester is implemented in Python (version 3). It uses the ofono +daemon to control the modems connected via USB. BTS software is either run +directly on the main unit (e.g. for osmo-bts-trx, osmo-bts-octphy), run via SSH +(e.g. for a sysmoBTS) or assumed to run on a connected BTS model (e.g. for +ip.access nanoBTS). + +.Typical osmo-gsm-tester setup +[graphviz] +---- +digraph G { + rankdir=LR; + jenkins + subgraph cluster_gsm_hardware { + label = "GSM Hardware"; + style=dotted + + modem0 [shape=box label=Modem] + modem1 [shape=box label=Modem] + modem2 [shape=box label=Modem] + osmo_bts_sysmo [label="sysmocom sysmoBTS\nrunning osmo-bts-sysmo" shape=box] + B200 [label="Ettus B200" shape=box] + octphy [label="Octasic octphy BTS" shape=box] + nanoBTS [label="ip.access nanoBTS" shape=box] + rf_distribution [label="RF distribution"] + + {modem0 modem1 modem2 osmo_bts_sysmo B200 octphy nanoBTS}->rf_distribution [dir=both arrowhead="curve" arrowtail="curve"] + } + subgraph cluster_main_unit { + label = "Main Unit" + osmo_gsm_tester [label="Osmo-GSM-Tester\ntest suites\n& scenarios"] + ofono [label="ofono daemon"] + OsmoNITB + osmo_bts_trx [label="osmo-bts-trx"] + osmo_bts_octphy [label="osmo-bts-octphy"] + } + + + jenkins->osmo_gsm_tester [label="trial\n(binaries)"] + osmo_gsm_tester->jenkins [label="results"] + ofono->modem0 [label="USB"] + ofono->modem1 [label="USB"] + ofono->modem2 [label="USB"] + osmo_gsm_tester-> {OsmoNITB osmo_bts_trx osmo_bts_octphy} + osmo_gsm_tester-> osmo_bts_sysmo [taillabel="SSH"] + osmo_gsm_tester-> ofono [taillabel="DBus"] + osmo_bts_trx->B200 [label="USB"] + osmo_bts_octphy->octphy [label="raw eth"] + {osmo_bts_sysmo B200 octphy nanoBTS}->OsmoNITB [label="eth"] +} +---- + +=== Typical Test Script + +A typical single test script (part of a suite) may look like this: + +---- +#!/usr/bin/env python3 +from osmo_gsm_tester.test import * + +print('use resources...') +nitb = suite.nitb() +bts = suite.bts() +ms_mo = suite.modem() +ms_mt = suite.modem() + +print('start nitb and bts...') +nitb.bts_add(bts) +nitb.start() +sleep(1) +assert nitb.running() +bts.start() + +nitb.subscriber_add(ms_mo) +nitb.subscriber_add(ms_mt) + +ms_mo.connect(nitb) +ms_mt.connect(nitb) +wait(nitb.subscriber_attached, ms_mo, ms_mt) + +sms = ms_mo.sms_send(ms_mt.msisdn) +wait(ms_mt.sms_received, sms) +---- + +=== Resource Resolution + +- A global configuration defines which hardware is connected to the + osmo-gsm-tester main unit. +- Each suite contains a number of test scripts. The amount of resources a test + may use is defined by the test suite's 'suite.conf'. +- Which specific modems, BTS models, NITB IP addresses etc. are made available + to a test run is typically determined by a combination of scenario + configurations -- or picked automatically if not. + +[[resources_conf_example]] +=== Typical 'resources.conf' + +A global configuration of hardware may look like below; for details, see +<>. + +---- +nitb_iface: +- addr: 10.42.42.1 +- addr: 10.42.42.2 +- addr: 10.42.42.3 + +bts: +- label: sysmoBTS 1002 + type: osmo-bts-sysmo + addr: 10.42.42.114 + band: GSM-1800 + +- label: octBTS 3000 + type: osmo-bts-octphy + addr: 10.42.42.115 + band: GSM-1800 + trx_list: + - hw_addr: 00:0c:90:32:b5:8a + net_device: eth0.2342 + +- label: Ettus B210 + type: osmo-bts-trx + addr: 10.42.42.116 + band: GSM-1800 + +- label: nanoBTS 1900 + type: nanobts + addr: 10.42.42.190 + band: GSM-1900 + trx_list: + - hw_addr: 00:02:95:00:41:b3 + +arfcn: + - arfcn: 512 + band: GSM-1800 + - arfcn: 514 + band: GSM-1800 + + - arfcn: 540 + band: GSM-1900 + - arfcn: 542 + band: GSM-1900 + +modem: +- label: m7801 + path: '/wavecom_0' + imsi: 901700000007801 + ki: D620F48487B1B782DA55DF6717F08FF9 + +- label: m7802 + path: '/wavecom_1' + imsi: 901700000007802 + ki: 47FDB2D55CE6A10A85ABDAD034A5B7B3 + +- label: m7803 + path: '/wavecom_2' + imsi: 901700000007803 + ki: ABBED4C91417DF710F60675B6EE2C8D2 +---- + +=== Typical 'suites/*/suite.conf' + +The configuration that reserves a number of resources for a test suite may look +like this: + +---- +resources: + nitb_iface: + - times: 1 + bts: + - times: 1 + modem: + - times: 2 +---- + +It may also request e.g. specific BTS models, but this is typically left to +scenario configurations. + +=== Typical 'scenarios/*.conf' + +For a suite as above run as-is, any available resources are picked. This may be +combined with any number of scenario definitions to constrain which specific +resources should be used, e.g.: + +---- +resources: + bts: + - type: osmo-bts-sysmo +---- + +Which 'nitb_iface' or 'modem' is used in particular doesn't really matter, so +it can be left up to the osmo-gsm-tester to pick these automatically. + +Any number of such scenario configurations can be combined in the form +':++...', e.g. 'my_suite:sysmo+tch_f+amr'. + +=== Typical Invocations + +Each invocation of osmo-gsm-tester deploys a set of pre-compiled binaries for +the Osmocom core network as well as for the Osmocom based BTS models. To create +such a set of binaries, see <>. + +Examples for launching test trials: + +- Run the default suites (see <>) on a given set of binaries: + +---- +osmo-gsm-tester.py path/to/my-trial +---- + +- Run an explicit choice of 'suite:scenario' combinations: + +---- +osmo-gsm-tester.py path/to/my-trial -s sms:sysmo -s sms:trx -s sms:nanobts +---- + +- Run one 'suite:scenario' combination, setting log level to 'debug' and + enabling logging of full python tracebacks, and also only run just the + 'mo_mt_sms.py' test from the suite, e.g. to investigate a test failure: + +---- +osmo-gsm-tester.py path/to/my-trial -s sms:sysmo -l dbg -T -t mo_mt +---- + +A test script may also be run step-by-step in a python debugger, see +<>. + +=== Resource Reservation for Concurrent Trials + +While a test suite runs, the used resources are noted in a global state +directory in a reserved-resources file. This way, any number of trials may be +run consecutively without resource conflicts. Any test trial will only use +resources that are currently not reserved by any other test suite. The +reservation state is human readable. + +The global state directory is protected by a file lock to allow access by +separate processes. + +Also, the binaries from a trial are never installed system-wide, but are run +with a specific 'LD_LIBRARY_PATH' pointing at the trial's 'inst', so that +several trials can run consecutively without conflicting binary versions. + +Once a test suite run is complete, all its reserved resources are torn down (if +the test scripts have not done so already), and the reservations are released +automatically. + +If required resources are unavailable, the test trial fails. For consecutive +test trials, a test run needs to either wait for resources to become available, +or test suites need to be scheduled to make sense. (*<- TODO*) + diff --git a/Osmo-GSM-Tester/chapters/test_api.adoc b/Osmo-GSM-Tester/chapters/test_api.adoc new file mode 100644 index 0000000..cabde4c --- /dev/null +++ b/Osmo-GSM-Tester/chapters/test_api.adoc @@ -0,0 +1,3 @@ +== Test API + +*TODO* diff --git a/Osmo-GSM-Tester/chapters/trial.adoc b/Osmo-GSM-Tester/chapters/trial.adoc new file mode 100644 index 0000000..afe29ce --- /dev/null +++ b/Osmo-GSM-Tester/chapters/trial.adoc @@ -0,0 +1,23 @@ +[[trials]] +== Trial: Binaries to be Tested + +A trial is a set of pre-built binaries to be tested. They are typically built +by jenkins using the build scripts found in osmo-gsm-tester's source in the +'contrib/' dir. + +A trial comes in the form of a directory containing a number of '*.tgz' tar +archives as well as a 'checksums.md5' file to verify the tar archives' +integrity. + +When the osmo-gsm-tester is invoked to run on such a trial directory, it will +create a sub directory named 'inst' and unpack the tar archives into it. + +For each test run on this trial, a new subdirectory in the trial dir is +created, named in the form of 'run.'. A symbolic link 'last-run' +will point at the most recently created run dir. This run dir will accumulate +the rendered configuration files used for the trial run as well as a test log +(<- *TODO*) and stdout and stderr outputs of the binaries run for the trial. +(*TODO*->) When the test is complete, jenkins parsable XML reports for the test +run will be written to the 'run.' subdir. + + diff --git a/Osmo-GSM-Tester/osmo-gsm-tester-manual-docinfo.xml b/Osmo-GSM-Tester/osmo-gsm-tester-manual-docinfo.xml new file mode 100644 index 0000000..923b8ad --- /dev/null +++ b/Osmo-GSM-Tester/osmo-gsm-tester-manual-docinfo.xml @@ -0,0 +1,47 @@ + + + 1 + April 13, 2017 + NH + + Initial version. + + + + + + + Neels + Hofmeyr + nhofmeyr at sysmocom.de + NH + + sysmocom + sysmocom - s.f.m.c. GmbH + Senior Developer + + + + + + 2017 + sysmocom - s.f.m.c. GmbH + + + + + Permission is granted to copy, distribute and/or modify this + document under the terms of the GNU Free Documentation License, + Version 1.3 or any later version published by the Free Software + Foundation; with the Invariant Sections being just 'Foreword', + 'Acknowledgements' and 'Preface', with no Front-Cover Texts, + and no Back-Cover Texts. A copy of the license is included in + the section entitled "GNU Free Documentation License". + + + The Asciidoc source code of this manual can be found at + + http://git.osmocom.org/osmo-gsm-manuals/ + + + diff --git a/Osmo-GSM-Tester/osmo-gsm-tester-manual.adoc b/Osmo-GSM-Tester/osmo-gsm-tester-manual.adoc new file mode 100644 index 0000000..54a0ac9 --- /dev/null +++ b/Osmo-GSM-Tester/osmo-gsm-tester-manual.adoc @@ -0,0 +1,19 @@ +Osmo-GSM-Tester Manual +====================== +Neels Hofmeyr + +== WARNING: Work in Progress + +*NOTE: The osmo-gsm-tester is still in pre-alpha stage: some parts are still +incomplete, and details will still change and move around.* + +include::chapters/intro.adoc[] + +include::chapters/config.adoc[] + +include::chapters/trial.adoc[] + +include::chapters/test_api.adoc[] + +include::chapters/debugging.adoc[] + -- To view, visit https://gerrit.osmocom.org/2325 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I8a9c0bfbce0072359c5094b940f225082d6847a7 Gerrit-PatchSet: 1 Gerrit-Project: osmo-gsm-manuals Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Fri Apr 14 02:27:03 2017 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 14 Apr 2017 02:27:03 +0000 Subject: [PATCH] osmo-gsm-manuals[master]: Add Osmo-GSM-Tester manual In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2325 to look at the new patch set (#2). Add Osmo-GSM-Tester manual Change-Id: I8a9c0bfbce0072359c5094b940f225082d6847a7 --- M Makefile A Osmo-GSM-Tester/Makefile A Osmo-GSM-Tester/chapters/config.adoc A Osmo-GSM-Tester/chapters/debugging.adoc A Osmo-GSM-Tester/chapters/intro.adoc A Osmo-GSM-Tester/chapters/test_api.adoc A Osmo-GSM-Tester/chapters/trial.adoc A Osmo-GSM-Tester/osmo-gsm-tester-manual-docinfo.xml A Osmo-GSM-Tester/osmo-gsm-tester-manual.adoc 9 files changed, 603 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-gsm-manuals refs/changes/25/2325/2 diff --git a/Makefile b/Makefile index 035595c..362f171 100644 --- a/Makefile +++ b/Makefile @@ -6,6 +6,7 @@ cd OsmoSGSN; $(MAKE) cd OsmoNAT; $(MAKE) cd OsmoPCU; $(MAKE) + cd Osmo-GSM-Tester; $(MAKE) clean: cd OsmoBTS; $(MAKE) clean @@ -15,6 +16,7 @@ cd OsmoSGSN; $(MAKE) clean cd OsmoNAT; $(MAKE) clean cd OsmoPCU; $(MAKE) clean + cd Osmo-GSM-Tester; $(MAKE) clean upload: cd OsmoBTS; $(MAKE) upload @@ -24,6 +26,7 @@ cd OsmoSGSN; $(MAKE) upload cd OsmoNAT; $(MAKE) upload cd OsmoPCU; $(MAKE) upload + cd Osmo-GSM-Tester; $(MAKE) upload check: cd OsmoBTS; $(MAKE) check @@ -34,3 +37,4 @@ # These don't use asciidoc, so they have no 'make check' target: #cd OsmoMGCP; $(MAKE) check #cd OsmoNAT; $(MAKE) check + cd Osmo-GSM-Tester; $(MAKE) check diff --git a/Osmo-GSM-Tester/Makefile b/Osmo-GSM-Tester/Makefile new file mode 100644 index 0000000..79d414f --- /dev/null +++ b/Osmo-GSM-Tester/Makefile @@ -0,0 +1,12 @@ +TOPDIR := .. +ASCIIDOCS := osmo-gsm-tester-manual + +include $(TOPDIR)/build/Makefile.asciidoc.inc +include $(TOPDIR)/build/Makefile.inc + +osmo-gsm-tester-manual.pdf: chapters/*.adoc + +clean: + -rm -rf $(cleanfiles) + -rm osmo-gsm-tester-manual__*.svg + -rm osmo-gsm-tester-manual__*.png diff --git a/Osmo-GSM-Tester/chapters/config.adoc b/Osmo-GSM-Tester/chapters/config.adoc new file mode 100644 index 0000000..66f4b71 --- /dev/null +++ b/Osmo-GSM-Tester/chapters/config.adoc @@ -0,0 +1,225 @@ +== Configuration + +The osmo-gsm-tester looks for configuration files in various standard +directories in this order: + +- '$HOME/.config/osmo-gsm-tester/' +- '/usr/local/etc/osmo-gsm-tester/' +- '/etc/osmo-gsm-tester/' + +The config location can also be set by an environment variable +'$OSMO_GSM_TESTER_CONF', which then overrides the above locations. + +The osmo-gsm-tester expects to find the following configuration files in a +configuration directory: + +- 'paths.conf' +- 'resources.conf' +- 'default-suites.conf' (optional) +- 'defaults.conf' (optional) + +=== Format: YAML, and its Drawbacks + +The general configuration format used is YAML. The stock python YAML parser +does have several drawbacks: too many complex possibilities and alternative +ways of formatting a configuration, but at the time of writing seems to be the +only widely used configuration format that offers a simple and human readable +formatting as well as nested structuring. It is recommended to use only the +exact YAML subset seen in this manual in case the osmo-gsm-tester should move +to a less bloated parser in the future. + +Careful: if a configuration item consists of digits and starts with a zero, you +need to quote it, or it may be interpreted as an octal notation integer! Please +avoid using the octal notation on purpose, it is not provided intentionally. + +[[paths_conf]] +=== 'paths.conf' + +The 'paths.conf' file defines where to store the global state (of reserved +resources) and where to find suite and scenario definitions. + +Any relative paths found in a 'paths.conf' file are interpreted as relative to +the directory of that 'paths.conf' file. + +Example: + +---- +state_dir: '/var/run/osmo-gsm-tester' +suites_dir: './suites' +scenarios_dir: './scenarios' +---- + +If you would like to set up several separate 'paths.conf' files (not typical), +note that the 'state_dir' is used to reserve resources, which only works when +all configurations that share resources also use the same 'state_dir'. + +[[resources_conf]] +=== 'resources.conf' + +The 'resources.conf' file defines which hardware is connected to the main unit, +as well as which limited configuration items (like IP addresses or ARFCNs) +should be used. + +These resources are allocated dynamically and are not configured explicitly: + +- MSISDN: phone numbers are dealt out to test scripts in sequence on request. + +A 'resources.conf' is structured as a list of items for each resource type, +where each item has one or more settings -- for an example, see +<>. + +These kinds of resource are known: + +'nitb_iface':: + List of IP addresses to run osmo-nitb instances on. The main unit + typically has a limited number of such IP addresses configured, which + the connected BTS models can see on their network. + 'addr'::: + IPv4 address of the local interface. + +'bts':: + List of available BTS hardware. + 'label'::: + human readable label for your own reference + 'type'::: + which way to launch this BTS, one of + - 'osmo-bts-sysmo' + - 'osmo-bts-trx' + - 'osmo-bts-octphy' + - 'ipa-nanobts' + 'addr'::: + remote IP address of the BTS, used to start the BTS and tell it where + to find the OsmoNITB. + 'band'::: + GSM band that this BTS shoud use (*TODO*: allow multiple bands). One of: + - 'GSM-1800' + - 'GSM-1900' + - (*TODO*: more bands) + 'trx_list'::: + Specific TRX configurations for this BTS. There should be as many of + these as the BTS has TRXes. (*TODO*: a way to define >1 TRX without + special configuration for them.) + 'hw_addr':::: + Hardware (MAC) address of the TRX in the form of '11:22:33:44:55:66', + only used for osmo-bts-octphy. (*TODO*: and nanobts??) + 'net_device':::: + Local network device to reach the TRX's 'hw_addr' at, only used for + osmo-bts-octphy. + +'arfcn':: + List of ARFCNs to use for running BTSes, which defines the actual RF + frequency bands used. + 'arfcn'::: + ARFCN number, see e.g. + https://en.wikipedia.org/wiki/Absolute_radio-frequency_channel_number + (note that the resource type 'arfcn' contains an item trait also named + 'arfcn') + 'band'::: + GSM band name to use this ARFCN for, same as for 'bts:band' above. + +'modem':: + List of modems reachable via ofono and information on the inserted SIM + card. (Note: the MSISDN is allocated dynamically in test scripts) + 'label'::: + human readable label for your own reference + 'path'::: + ofono's path for this modem, like '/modemkind_99' + 'imsi'::: + IMSI of the inserted SIM card, like '"123456789012345"' + 'ki'::: + 16 byte authentication/encryption KI of the inserted SIM card, in + hexadecimal notation (32 characters) like + + '"00112233445566778899aabbccddeeff"' (*TODO*: authentication algorithm, + currently always comp128v1) + +Side note: at first sight it might make sense to the reader to rather structure +e.g. the 'nitb_iface' or 'arfcn' configuration as + +'"arfcn: GSM-1800: [512, 514, ...]"', + +but the more verbose format is chosen to stay consistent with the general +structure of resource configurations, which the resource allocation algorithm +uses to resolve required resources according to their traits. These +configurations look cumbersome because they exhibit only one trait / a trait +that is repeated numerous times. No special notation for these cases is +available (yet). + +[[default_suites]] +=== 'default-suites.conf' (optional) + +The 'default-suites.conf' file contains a list of 'suite:scenario+scenario+...' +combination strings as defined by the 'osmo-gsm-tester.py -s' commandline +option. If invoking the 'osmo-gsm-tester.py' without any suite definitions, the +'-s' arguments are taken from this file instead. Each of these suite + scenario +combinations is run in sequence. + +A suite name must match the name of a directory in the 'suites_dir' as defined +by 'paths.conf'. + +A scenario name must match the name of a configuration file in the +'scenarios_dir' as defined by 'paths.conf' (optionally without the '.conf' +suffix). + +For 'paths.conf', see <>. + +Example of a 'default-suites.conf' file: + +---- +- sms:sysmo +- voice:sysmo+tch_f +- voice:sysmo+tch_h +- voice:sysmo+dyn_ts +- sms:trx +- voice:trx+tch_f +- voice:trx+tch_h +- voice:trx+dyn_ts +---- + +=== 'defaults.conf' (optional) + +Each binary run by osmo-gsm-tester, e.g. 'osmo-nitb' or 'osmo-bts-sysmo', +typically has a configuration file template that is populated with values for a +trial run. + +Some of these values are provided by the 'resources.conf' from the allocated +resource(s), but not all values can be populated this way: some osmo-nitb +configuration values like the network name, encryption algorithm or timeslot +channel combinations are in fact not resources (only the nitb's interface +address is). These additional settings may be provided by the scenario +configurations, but in case the provided scenarios leave some values unset, +they are taken from this 'defaults.conf'. (A 'scenario.conf' providing a +similar setting always has precedence over the values given in a +'defaults.conf'). + +*TODO* better match this format with 'resources.conf'? + +Example of a 'defaults.conf': + +---- +nitb: + net: + mcc: 1 + mnc: 868 + short_name: osmo-gsm-tester + long_name: osmo-gsm-tester + auth_policy: closed + encryption: a5 0 + +nitb_bts: + location_area_code: 23 + base_station_id_code: 63 + stream_id: 255 + osmobsc_bts_type: sysmobts + trx_list: + - max_power_red: 22 + arfcn: 868 + timeslot_list: + - phys_chan_config: CCCH+SDCCH4 + - phys_chan_config: SDCCH8 + - phys_chan_config: TCH/F_TCH/H_PDCH + - phys_chan_config: TCH/F_TCH/H_PDCH + - phys_chan_config: TCH/F_TCH/H_PDCH + - phys_chan_config: TCH/F_TCH/H_PDCH + - phys_chan_config: TCH/F_TCH/H_PDCH + - phys_chan_config: TCH/F_TCH/H_PDCH +---- + +*TODO*: detailed descriptions diff --git a/Osmo-GSM-Tester/chapters/debugging.adoc b/Osmo-GSM-Tester/chapters/debugging.adoc new file mode 100644 index 0000000..bea1e5c --- /dev/null +++ b/Osmo-GSM-Tester/chapters/debugging.adoc @@ -0,0 +1,4 @@ +[[debugging]] +== Debugging + +*TODO*: describe how to invoke 'ipdb3' and step into a suite's test script diff --git a/Osmo-GSM-Tester/chapters/intro.adoc b/Osmo-GSM-Tester/chapters/intro.adoc new file mode 100644 index 0000000..c45e808 --- /dev/null +++ b/Osmo-GSM-Tester/chapters/intro.adoc @@ -0,0 +1,269 @@ +== Introduction with Examples + +The osmo-gsm-tester is software to run automated tests of real GSM hardware, +foremost to verify that ongoing Osmocom software development continues to work +with various BTS models, while being flexibly configurable and extendable. + +A 'main unit' (general purpose computer) is connected via ethernet and/or USB to +any number of BTS models and to any number of GSM modems via USB. The modems +and BTS instances' RF transceivers are typically wired directly to each other +via RF distribution chambers to bypass the air medium and avoid disturbing real +production cellular networks. Furthermore, the setup may include adjustable RF +attenuators to model various distances between modems and base stations. + +The osmo-gsm-tester software runs on the main unit to orchestrate the various +GSM hardware and run predefined test scripts. It typically receives binary +packages from a jenkins build service. It then automatically configures and +launches an Osmocom core network on the main unit and sets up and runs BTS +models as well as modems to form a complete ad-hoc GSM network. On this setup, +predefined test suites, combined with various scenario definitions, are run to +verify stability of the system. + +The osmo-gsm-tester is implemented in Python (version 3). It uses the ofono +daemon to control the modems connected via USB. BTS software is either run +directly on the main unit (e.g. for osmo-bts-trx, osmo-bts-octphy), run via SSH +(e.g. for a sysmoBTS) or assumed to run on a connected BTS model (e.g. for +ip.access nanoBTS). + +.Typical osmo-gsm-tester setup +[graphviz] +---- +digraph G { + rankdir=LR; + jenkins + subgraph cluster_gsm_hardware { + label = "GSM Hardware"; + style=dotted + + modem0 [shape=box label=Modem] + modem1 [shape=box label=Modem] + modem2 [shape=box label=Modem] + osmo_bts_sysmo [label="sysmocom sysmoBTS\nrunning osmo-bts-sysmo" shape=box] + B200 [label="Ettus B200" shape=box] + octphy [label="Octasic octphy BTS" shape=box] + nanoBTS [label="ip.access nanoBTS" shape=box] + rf_distribution [label="RF distribution"] + + {modem0 modem1 modem2 osmo_bts_sysmo B200 octphy nanoBTS}->rf_distribution [dir=both arrowhead="curve" arrowtail="curve"] + } + subgraph cluster_main_unit { + label = "Main Unit" + osmo_gsm_tester [label="Osmo-GSM-Tester\ntest suites\n& scenarios"] + ofono [label="ofono daemon"] + OsmoNITB + osmo_bts_trx [label="osmo-bts-trx"] + osmo_bts_octphy [label="osmo-bts-octphy"] + } + + + jenkins->osmo_gsm_tester [label="trial\n(binaries)"] + osmo_gsm_tester->jenkins [label="results"] + ofono->modem0 [label="USB"] + ofono->modem1 [label="USB"] + ofono->modem2 [label="USB"] + osmo_gsm_tester-> {OsmoNITB osmo_bts_trx osmo_bts_octphy} + osmo_gsm_tester-> osmo_bts_sysmo [taillabel="SSH"] + osmo_gsm_tester-> ofono [taillabel="DBus"] + osmo_bts_trx->B200 [label="USB"] + osmo_bts_octphy->octphy [label="raw eth"] + {osmo_bts_sysmo B200 octphy nanoBTS}->OsmoNITB [label="eth"] +} +---- + +=== Typical Test Script + +A typical single test script (part of a suite) may look like this: + +---- +#!/usr/bin/env python3 +from osmo_gsm_tester.test import * + +print('use resources...') +nitb = suite.nitb() +bts = suite.bts() +ms_mo = suite.modem() +ms_mt = suite.modem() + +print('start nitb and bts...') +nitb.bts_add(bts) +nitb.start() +sleep(1) +assert nitb.running() +bts.start() + +nitb.subscriber_add(ms_mo) +nitb.subscriber_add(ms_mt) + +ms_mo.connect(nitb) +ms_mt.connect(nitb) +wait(nitb.subscriber_attached, ms_mo, ms_mt) + +sms = ms_mo.sms_send(ms_mt.msisdn) +wait(ms_mt.sms_received, sms) +---- + +=== Resource Resolution + +- A global configuration defines which hardware is connected to the + osmo-gsm-tester main unit. +- Each suite contains a number of test scripts. The amount of resources a test + may use is defined by the test suite's 'suite.conf'. +- Which specific modems, BTS models, NITB IP addresses etc. are made available + to a test run is typically determined by a combination of scenario + configurations -- or picked automatically if not. + +[[resources_conf_example]] +=== Typical 'resources.conf' + +A global configuration of hardware may look like below; for details, see +<>. + +---- +nitb_iface: +- addr: 10.42.42.1 +- addr: 10.42.42.2 +- addr: 10.42.42.3 + +bts: +- label: sysmoBTS 1002 + type: osmo-bts-sysmo + addr: 10.42.42.114 + band: GSM-1800 + +- label: octBTS 3000 + type: osmo-bts-octphy + addr: 10.42.42.115 + band: GSM-1800 + trx_list: + - hw_addr: 00:0c:90:32:b5:8a + net_device: eth0.2342 + +- label: Ettus B210 + type: osmo-bts-trx + addr: 10.42.42.116 + band: GSM-1800 + +- label: nanoBTS 1900 + type: nanobts + addr: 10.42.42.190 + band: GSM-1900 + trx_list: + - hw_addr: 00:02:95:00:41:b3 + +arfcn: + - arfcn: 512 + band: GSM-1800 + - arfcn: 514 + band: GSM-1800 + + - arfcn: 540 + band: GSM-1900 + - arfcn: 542 + band: GSM-1900 + +modem: +- label: m7801 + path: '/wavecom_0' + imsi: 901700000007801 + ki: D620F48487B1B782DA55DF6717F08FF9 + +- label: m7802 + path: '/wavecom_1' + imsi: 901700000007802 + ki: 47FDB2D55CE6A10A85ABDAD034A5B7B3 + +- label: m7803 + path: '/wavecom_2' + imsi: 901700000007803 + ki: ABBED4C91417DF710F60675B6EE2C8D2 +---- + +=== Typical 'suites/*/suite.conf' + +The configuration that reserves a number of resources for a test suite may look +like this: + +---- +resources: + nitb_iface: + - times: 1 + bts: + - times: 1 + modem: + - times: 2 +---- + +It may also request e.g. specific BTS models, but this is typically left to +scenario configurations. + +=== Typical 'scenarios/*.conf' + +For a suite as above run as-is, any available resources are picked. This may be +combined with any number of scenario definitions to constrain which specific +resources should be used, e.g.: + +---- +resources: + bts: + - type: osmo-bts-sysmo +---- + +Which 'nitb_iface' or 'modem' is used in particular doesn't really matter, so +it can be left up to the osmo-gsm-tester to pick these automatically. + +Any number of such scenario configurations can be combined in the form +':++...', e.g. 'my_suite:sysmo+tch_f+amr'. + +=== Typical Invocations + +Each invocation of osmo-gsm-tester deploys a set of pre-compiled binaries for +the Osmocom core network as well as for the Osmocom based BTS models. To create +such a set of binaries, see <>. + +Examples for launching test trials: + +- Run the default suites (see <>) on a given set of binaries: + +---- +osmo-gsm-tester.py path/to/my-trial +---- + +- Run an explicit choice of 'suite:scenario' combinations: + +---- +osmo-gsm-tester.py path/to/my-trial -s sms:sysmo -s sms:trx -s sms:nanobts +---- + +- Run one 'suite:scenario' combination, setting log level to 'debug' and + enabling logging of full python tracebacks, and also only run just the + 'mo_mt_sms.py' test from the suite, e.g. to investigate a test failure: + +---- +osmo-gsm-tester.py path/to/my-trial -s sms:sysmo -l dbg -T -t mo_mt +---- + +A test script may also be run step-by-step in a python debugger, see +<>. + +=== Resource Reservation for Concurrent Trials + +While a test suite runs, the used resources are noted in a global state +directory in a reserved-resources file. This way, any number of trials may be +run consecutively without resource conflicts. Any test trial will only use +resources that are currently not reserved by any other test suite. The +reservation state is human readable. + +The global state directory is protected by a file lock to allow access by +separate processes. + +Also, the binaries from a trial are never installed system-wide, but are run +with a specific 'LD_LIBRARY_PATH' pointing at the trial's 'inst', so that +several trials can run consecutively without conflicting binary versions. + +Once a test suite run is complete, all its reserved resources are torn down (if +the test scripts have not done so already), and the reservations are released +automatically. + +If required resources are unavailable, the test trial fails. For consecutive +test trials, a test run needs to either wait for resources to become available, +or test suites need to be scheduled to make sense. (*<- TODO*) diff --git a/Osmo-GSM-Tester/chapters/test_api.adoc b/Osmo-GSM-Tester/chapters/test_api.adoc new file mode 100644 index 0000000..cabde4c --- /dev/null +++ b/Osmo-GSM-Tester/chapters/test_api.adoc @@ -0,0 +1,3 @@ +== Test API + +*TODO* diff --git a/Osmo-GSM-Tester/chapters/trial.adoc b/Osmo-GSM-Tester/chapters/trial.adoc new file mode 100644 index 0000000..16b3641 --- /dev/null +++ b/Osmo-GSM-Tester/chapters/trial.adoc @@ -0,0 +1,21 @@ +[[trials]] +== Trial: Binaries to be Tested + +A trial is a set of pre-built binaries to be tested. They are typically built +by jenkins using the build scripts found in osmo-gsm-tester's source in the +'contrib/' dir. + +A trial comes in the form of a directory containing a number of '*.tgz' tar +archives as well as a 'checksums.md5' file to verify the tar archives' +integrity. + +When the osmo-gsm-tester is invoked to run on such a trial directory, it will +create a sub directory named 'inst' and unpack the tar archives into it. + +For each test run on this trial, a new subdirectory in the trial dir is +created, named in the form of 'run.'. A symbolic link 'last-run' +will point at the most recently created run dir. This run dir will accumulate +the rendered configuration files used for the trial run as well as a test log +(<- *TODO*) and stdout and stderr outputs of the binaries run for the trial. +(*TODO*->) When the test is complete, jenkins parsable XML reports for the test +run will be written to the 'run.' subdir. diff --git a/Osmo-GSM-Tester/osmo-gsm-tester-manual-docinfo.xml b/Osmo-GSM-Tester/osmo-gsm-tester-manual-docinfo.xml new file mode 100644 index 0000000..923b8ad --- /dev/null +++ b/Osmo-GSM-Tester/osmo-gsm-tester-manual-docinfo.xml @@ -0,0 +1,47 @@ + + + 1 + April 13, 2017 + NH + + Initial version. + + + + + + + Neels + Hofmeyr + nhofmeyr at sysmocom.de + NH + + sysmocom + sysmocom - s.f.m.c. GmbH + Senior Developer + + + + + + 2017 + sysmocom - s.f.m.c. GmbH + + + + + Permission is granted to copy, distribute and/or modify this + document under the terms of the GNU Free Documentation License, + Version 1.3 or any later version published by the Free Software + Foundation; with the Invariant Sections being just 'Foreword', + 'Acknowledgements' and 'Preface', with no Front-Cover Texts, + and no Back-Cover Texts. A copy of the license is included in + the section entitled "GNU Free Documentation License". + + + The Asciidoc source code of this manual can be found at + + http://git.osmocom.org/osmo-gsm-manuals/ + + + diff --git a/Osmo-GSM-Tester/osmo-gsm-tester-manual.adoc b/Osmo-GSM-Tester/osmo-gsm-tester-manual.adoc new file mode 100644 index 0000000..a3fb88c --- /dev/null +++ b/Osmo-GSM-Tester/osmo-gsm-tester-manual.adoc @@ -0,0 +1,18 @@ +Osmo-GSM-Tester Manual +====================== +Neels Hofmeyr + +== WARNING: Work in Progress + +*NOTE: The osmo-gsm-tester is still in pre-alpha stage: some parts are still +incomplete, and details will still change and move around.* + +include::chapters/intro.adoc[] + +include::chapters/config.adoc[] + +include::chapters/trial.adoc[] + +include::chapters/test_api.adoc[] + +include::chapters/debugging.adoc[] -- To view, visit https://gerrit.osmocom.org/2325 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I8a9c0bfbce0072359c5094b940f225082d6847a7 Gerrit-PatchSet: 2 Gerrit-Project: osmo-gsm-manuals Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Fri Apr 14 08:16:09 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 14 Apr 2017 08:16:09 +0000 Subject: osmo-gsm-manuals[master]: Add Osmo-GSM-Tester manual In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2325 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I8a9c0bfbce0072359c5094b940f225082d6847a7 Gerrit-PatchSet: 2 Gerrit-Project: osmo-gsm-manuals Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Apr 14 08:56:40 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 14 Apr 2017 08:56:40 +0000 Subject: [PATCH] libosmo-netif[master]: ipa.h: Don't redefine what libosmocore already defines Message-ID: Review at https://gerrit.osmocom.org/2326 ipa.h: Don't redefine what libosmocore already defines Change-Id: Ibd81efc1dc61b8c2019d55a8fa6e3bb99b5acb20 --- M include/osmocom/netif/ipa.h 1 file changed, 5 insertions(+), 33 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-netif refs/changes/26/2326/1 diff --git a/include/osmocom/netif/ipa.h b/include/osmocom/netif/ipa.h index 4e28e1a..8d221e3 100644 --- a/include/osmocom/netif/ipa.h +++ b/include/osmocom/netif/ipa.h @@ -1,49 +1,21 @@ #ifndef _OSMO_NETIF_IPA_H_ #define _OSMO_NETIF_IPA_H_ +#include + +/* This is like 'struct ipaccess_head' in libosmocore, but 'ipa_head' is + * actually the more apropriate name, so rather than making more code + * use the wrong name, let's keep the duplicate header definitions below */ struct ipa_head { uint16_t len; /* network byte order */ uint8_t proto; uint8_t data[0]; } __attribute__ ((packed)); -/* IPA protocols. */ -#define IPAC_PROTO_RSL 0x00 -#define IPAC_PROTO_IPACCESS 0xfe -#define IPAC_PROTO_SCCP 0xfd -#define IPAC_PROTO_OML 0xff -#define IPAC_PROTO_OSMO 0xee /* OpenBSC extension. */ -#define IPAC_PROTO_MGCP_OLD 0xfc /* OpenBSC extension. */ - struct ipa_head_ext { uint8_t proto; uint8_t data[0]; } __attribute__ ((packed)); - -/* Protocol extensions. */ -#define IPAC_PROTO_EXT_CTRL 0x00 -#define IPAC_PROTO_EXT_MGCP 0x01 -#define IPAC_PROTO_EXT_LAC 0x02 - -/* Message types. */ -#define IPAC_MSGT_PING 0x00 -#define IPAC_MSGT_PONG 0x01 -#define IPAC_MSGT_ID_GET 0x04 -#define IPAC_MSGT_ID_RESP 0x05 -#define IPAC_MSGT_ID_ACK 0x06 -#define IPAC_MSGT_SCCP_OLD 0xff /* OpenBSC extension */ - -enum ipaccess_id_tags { - IPAC_IDTAG_SERNR = 0x00, - IPAC_IDTAG_UNITNAME = 0x01, - IPAC_IDTAG_LOCATION1 = 0x02, - IPAC_IDTAG_LOCATION2 = 0x03, - IPAC_IDTAG_EQUIPVERS = 0x04, - IPAC_IDTAG_SWVERSION = 0x05, - IPAC_IDTAG_IPADDR = 0x06, - IPAC_IDTAG_MACADDR = 0x07, - IPAC_IDTAG_UNIT = 0x08, -}; struct msgb *osmo_ipa_msg_alloc(int headroom); void osmo_ipa_msg_push_header(struct msgb *msg, uint8_t proto); -- To view, visit https://gerrit.osmocom.org/2326 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ibd81efc1dc61b8c2019d55a8fa6e3bb99b5acb20 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Fri Apr 14 09:07:04 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 14 Apr 2017 09:07:04 +0000 Subject: libosmo-netif[master]: osmo_stream_srv_fd_cb(): don't leak socket FDs on errors In-Reply-To: References: Message-ID: Harald Welte has restored this change. Change subject: osmo_stream_srv_fd_cb(): don't leak socket FDs on errors ...................................................................... Restored -- To view, visit https://gerrit.osmocom.org/1320 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: restore Gerrit-Change-Id: I3a3ce9194ab7ca5c1921fc79c2a1c9e10a552cf0 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Fri Apr 14 09:07:31 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 14 Apr 2017 09:07:31 +0000 Subject: libosmo-netif[master]: ipa.h: Don't redefine what libosmocore already defines In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2326 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ibd81efc1dc61b8c2019d55a8fa6e3bb99b5acb20 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Apr 14 09:07:32 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 14 Apr 2017 09:07:32 +0000 Subject: [MERGED] libosmo-netif[master]: ipa.h: Don't redefine what libosmocore already defines In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: ipa.h: Don't redefine what libosmocore already defines ...................................................................... ipa.h: Don't redefine what libosmocore already defines Change-Id: Ibd81efc1dc61b8c2019d55a8fa6e3bb99b5acb20 --- M include/osmocom/netif/ipa.h 1 file changed, 5 insertions(+), 33 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/include/osmocom/netif/ipa.h b/include/osmocom/netif/ipa.h index 4e28e1a..8d221e3 100644 --- a/include/osmocom/netif/ipa.h +++ b/include/osmocom/netif/ipa.h @@ -1,49 +1,21 @@ #ifndef _OSMO_NETIF_IPA_H_ #define _OSMO_NETIF_IPA_H_ +#include + +/* This is like 'struct ipaccess_head' in libosmocore, but 'ipa_head' is + * actually the more apropriate name, so rather than making more code + * use the wrong name, let's keep the duplicate header definitions below */ struct ipa_head { uint16_t len; /* network byte order */ uint8_t proto; uint8_t data[0]; } __attribute__ ((packed)); -/* IPA protocols. */ -#define IPAC_PROTO_RSL 0x00 -#define IPAC_PROTO_IPACCESS 0xfe -#define IPAC_PROTO_SCCP 0xfd -#define IPAC_PROTO_OML 0xff -#define IPAC_PROTO_OSMO 0xee /* OpenBSC extension. */ -#define IPAC_PROTO_MGCP_OLD 0xfc /* OpenBSC extension. */ - struct ipa_head_ext { uint8_t proto; uint8_t data[0]; } __attribute__ ((packed)); - -/* Protocol extensions. */ -#define IPAC_PROTO_EXT_CTRL 0x00 -#define IPAC_PROTO_EXT_MGCP 0x01 -#define IPAC_PROTO_EXT_LAC 0x02 - -/* Message types. */ -#define IPAC_MSGT_PING 0x00 -#define IPAC_MSGT_PONG 0x01 -#define IPAC_MSGT_ID_GET 0x04 -#define IPAC_MSGT_ID_RESP 0x05 -#define IPAC_MSGT_ID_ACK 0x06 -#define IPAC_MSGT_SCCP_OLD 0xff /* OpenBSC extension */ - -enum ipaccess_id_tags { - IPAC_IDTAG_SERNR = 0x00, - IPAC_IDTAG_UNITNAME = 0x01, - IPAC_IDTAG_LOCATION1 = 0x02, - IPAC_IDTAG_LOCATION2 = 0x03, - IPAC_IDTAG_EQUIPVERS = 0x04, - IPAC_IDTAG_SWVERSION = 0x05, - IPAC_IDTAG_IPADDR = 0x06, - IPAC_IDTAG_MACADDR = 0x07, - IPAC_IDTAG_UNIT = 0x08, -}; struct msgb *osmo_ipa_msg_alloc(int headroom); void osmo_ipa_msg_push_header(struct msgb *msg, uint8_t proto); -- To view, visit https://gerrit.osmocom.org/2326 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ibd81efc1dc61b8c2019d55a8fa6e3bb99b5acb20 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Fri Apr 14 09:07:42 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 14 Apr 2017 09:07:42 +0000 Subject: [PATCH] libosmo-netif[master]: osmo_stream_srv_fd_cb(): don't leak socket FDs on errors In-Reply-To: References: Message-ID: Hello Neels Hofmeyr, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/1320 to look at the new patch set (#2). osmo_stream_srv_fd_cb(): don't leak socket FDs on errors So far we seem to assume that the accept_cb does all handling of socket fd cleanup. However, there are cases where there is no accept_cb set, the accept_cb returns error, or an earlier sctp_sock_activate_events() or the activation of non-blocking mode fails. For those cases, close the socket and return an error code. Fixes: CID#57915 Change-Id: I3a3ce9194ab7ca5c1921fc79c2a1c9e10a552cf0 --- M src/stream.c 1 file changed, 23 insertions(+), 6 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-netif refs/changes/20/1320/2 diff --git a/src/stream.c b/src/stream.c index 591cd06..653f26b 100644 --- a/src/stream.c +++ b/src/stream.c @@ -529,6 +529,7 @@ static int osmo_stream_srv_fd_cb(struct osmo_fd *ofd, unsigned int what) { int ret; + int sock_fd; struct sockaddr_in sa; socklen_t sa_len = sizeof(sa); struct osmo_stream_srv_link *link = ofd->data; @@ -541,17 +542,33 @@ } LOGP(DLINP, LOGL_DEBUG, "accept()ed new link from %s to port %u\n", inet_ntoa(sa.sin_addr), link->port); + sock_fd = ret; - if (link->proto == IPPROTO_SCTP) - sctp_sock_activate_events(ret); + if (link->proto == IPPROTO_SCTP) { + ret = sctp_sock_activate_events(sock_fd); + if (ret < 0) + goto error_close_socket; + } - if (link->flags & OSMO_STREAM_SRV_F_NODELAY) - setsockopt_nodelay(ret, link->proto, 1); + if (link->flags & OSMO_STREAM_SRV_F_NODELAY) { + ret = setsockopt_nodelay(ret, link->proto, 1); + if (ret < 0) + goto error_close_socket; + } - if (link->accept_cb) - link->accept_cb(link, ret); + if (!link->accept_cb) { + ret = -ENOTSUP; + goto error_close_socket; + } + ret = link->accept_cb(link, sock_fd); + if (ret) + goto error_close_socket; return 0; + +error_close_socket: + close(sock_fd); + return ret; } /*! \brief Create an Osmocom Stream Server Link -- To view, visit https://gerrit.osmocom.org/1320 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I3a3ce9194ab7ca5c1921fc79c2a1c9e10a552cf0 Gerrit-PatchSet: 2 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Fri Apr 14 09:10:52 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 14 Apr 2017 09:10:52 +0000 Subject: [MERGED] osmo-bts[master]: octphy: set tx/rx antenne IDs via VTY In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: octphy: set tx/rx antenne IDs via VTY ...................................................................... octphy: set tx/rx antenne IDs via VTY add support for the TX/RX antenna-id feature that has been introduced with release OCTSDR-2G-02.07.00-B1314-BETA. The user can now set individual ID numbers for the TX and for the RX antenna. Change-Id: I872fe3c4d7b593358a4ce2f02cf0726611b9f3aa --- M configure.ac M include/osmo-bts/phy_link.h M src/osmo-bts-octphy/l1_oml.c M src/osmo-bts-octphy/octphy_vty.c 4 files changed, 64 insertions(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/configure.ac b/configure.ac index cbfbf12..a03b2dd 100644 --- a/configure.ac +++ b/configure.ac @@ -112,6 +112,13 @@ [], [#include ]) + AC_CHECK_MEMBER([tOCTVC1_GSM_RF_CONFIG.ulTxAntennaId], + AC_DEFINE([OCTPHY_USE_ANTENNA_ID], + [1], + [Define to 1 if your octphy header files support antenna ids in tOCTVC1_GSM_RF_CONFIG]), + [], + [#include ]) + CPPFLAGS=$oldCPPFLAGS fi diff --git a/include/osmo-bts/phy_link.h b/include/osmo-bts/phy_link.h index e644a91..e8fd7eb 100644 --- a/include/osmo-bts/phy_link.h +++ b/include/osmo-bts/phy_link.h @@ -53,6 +53,10 @@ /* configuration */ uint32_t rf_port_index; +#if OCTPHY_USE_ANTENNA_ID == 1 + uint32_t rx_ant_id; + uint32_t tx_ant_id; +#endif uint32_t rx_gain_db; bool tx_atten_flag; uint32_t tx_atten_db; diff --git a/src/osmo-bts-octphy/l1_oml.c b/src/osmo-bts-octphy/l1_oml.c index 0cd25f2..c70b45f 100644 --- a/src/osmo-bts-octphy/l1_oml.c +++ b/src/osmo-bts-octphy/l1_oml.c @@ -1394,6 +1394,11 @@ oc->RfConfig.ulTxAttndB = (trx->max_power_red) << 2; } +#if OCTPHY_USE_ANTENNA_ID == 1 + oc->RfConfig.ulTxAntennaId = plink->u.octphy.tx_ant_id; + oc->RfConfig.ulRxAntennaId = plink->u.octphy.rx_ant_id; +#endif + #if OCTPHY_MULTI_TRX == 1 LOGP(DL1C, LOGL_INFO, "Tx TRX-OPEN.req(trx=%u, rf_port=%u, arfcn=%u, " "center=%u, tsc=%u, rx_gain=%u, tx_atten=%u)\n", diff --git a/src/osmo-bts-octphy/octphy_vty.c b/src/osmo-bts-octphy/octphy_vty.c index 370aff6..fb36493 100644 --- a/src/osmo-bts-octphy/octphy_vty.c +++ b/src/osmo-bts-octphy/octphy_vty.c @@ -117,6 +117,42 @@ return CMD_SUCCESS; } +#if OCTPHY_USE_ANTENNA_ID == 1 +DEFUN(cfg_phy_rx_ant_id, cfg_phy_rx_ant_id_cmd, + "octphy rx-ant-id <0-1>", + OCT_STR "Configure the RX Antenna for this TRX\n" "RX Antenna Id\n") +{ + struct phy_link *plink = vty->index; + + if (plink->state != PHY_LINK_SHUTDOWN) { + vty_out(vty, "Can only reconfigure a PHY link that is down%s", + VTY_NEWLINE); + return CMD_WARNING; + } + + plink->u.octphy.rx_ant_id = atoi(argv[0]); + + return CMD_SUCCESS; +} + +DEFUN(cfg_phy_tx_ant_id, cfg_phy_tx_ant_id_cmd, + "octphy tx-ant-id <0-1>", + OCT_STR "Configure the TX Antenna for this TRX\n" "TX Antenna Id\n") +{ + struct phy_link *plink = vty->index; + + if (plink->state != PHY_LINK_SHUTDOWN) { + vty_out(vty, "Can only reconfigure a PHY link that is down%s", + VTY_NEWLINE); + return CMD_WARNING; + } + + plink->u.octphy.tx_ant_id = atoi(argv[0]); + + return CMD_SUCCESS; +} +#endif + DEFUN(cfg_phy_rx_gain_db, cfg_phy_rx_gain_db_cmd, "octphy rx-gain <0-73>", OCT_STR "Configure the Rx Gain in dB\n" @@ -300,6 +336,14 @@ vty_out(vty, " octphy rf-port-index %u%s", plink->u.octphy.rf_port_index, VTY_NEWLINE); + +#if OCTPHY_USE_ANTENNA_ID == 1 + vty_out(vty, " octphy tx-ant-id %u%s", plink->u.octphy.tx_ant_id, + VTY_NEWLINE); + + vty_out(vty, " octphy rx-ant-id %u%s", plink->u.octphy.rx_ant_id, + VTY_NEWLINE); +#endif } void bts_model_config_write_phy_inst(struct vty *vty, struct phy_instance *pinst) @@ -347,6 +391,10 @@ install_element(PHY_NODE, &cfg_phy_hwaddr_cmd); install_element(PHY_NODE, &cfg_phy_netdev_cmd); install_element(PHY_NODE, &cfg_phy_rf_port_idx_cmd); +#if OCTPHY_USE_ANTENNA_ID == 1 + install_element(PHY_NODE, &cfg_phy_rx_ant_id_cmd); + install_element(PHY_NODE, &cfg_phy_tx_ant_id_cmd); +#endif install_element(PHY_NODE, &cfg_phy_rx_gain_db_cmd); install_element(PHY_NODE, &cfg_phy_tx_atten_db_cmd); -- To view, visit https://gerrit.osmocom.org/1976 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I872fe3c4d7b593358a4ce2f02cf0726611b9f3aa Gerrit-PatchSet: 5 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Fri Apr 14 09:10:52 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 14 Apr 2017 09:10:52 +0000 Subject: [MERGED] osmo-bts[master]: l1sap: improve log output In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: l1sap: improve log output ...................................................................... l1sap: improve log output Print toa and ra value with the "RACH for packet access" log message. Change-Id: I3a2dde95947438aa8348a0a9fc8566cbc177aa2d --- M src/common/l1sap.c 1 file changed, 3 insertions(+), 1 deletion(-) Approvals: Max: Looks good to me, but someone else must approve Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/common/l1sap.c b/src/common/l1sap.c index 19b38af..3592096 100644 --- a/src/common/l1sap.c +++ b/src/common/l1sap.c @@ -1029,7 +1029,9 @@ if ((trx == bts->c0 && L1SAP_IS_PACKET_RACH(rach_ind->ra)) || (trx == bts->c0 && rach_ind->is_11bit)) { - LOGP(DL1P, LOGL_INFO, "RACH for packet access\n"); + LOGP(DL1P, LOGL_INFO, "RACH for packet access (toa=%d, ra=%d)\n", + rach_ind->acc_delay, rach_ind->ra); + pcu_tx_rach_ind(bts, rach_ind->acc_delay << 2, rach_ind->ra, rach_ind->fn, rach_ind->is_11bit, rach_ind->burst_type); -- To view, visit https://gerrit.osmocom.org/1967 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I3a2dde95947438aa8348a0a9fc8566cbc177aa2d Gerrit-PatchSet: 4 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max From gerrit-no-reply at lists.osmocom.org Fri Apr 14 09:10:59 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 14 Apr 2017 09:10:59 +0000 Subject: [MERGED] osmo-bts[master]: octphy: fix usage of wrong define constant In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: octphy: fix usage of wrong define constant ...................................................................... octphy: fix usage of wrong define constant octphy_hw_get_rf_ant_tx_config() uses define constant cOCTVC1_HW_MSG_RF_PORT_INFO_ANTENNA_RX_CONFIG_CID instead of cOCTVC1_HW_MSG_RF_PORT_INFO_ANTENNA_TX_CONFIG_CID. This commit replaces exchanges the wrong constant with the correct one. Change-Id: Ie4de23daf79bb07ca0c0b818eefe350d18d27e4d --- M src/osmo-bts-octphy/octphy_hw_api.c 1 file changed, 1 insertion(+), 1 deletion(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/osmo-bts-octphy/octphy_hw_api.c b/src/osmo-bts-octphy/octphy_hw_api.c index 6666f77..0d6fabd 100644 --- a/src/osmo-bts-octphy/octphy_hw_api.c +++ b/src/osmo-bts-octphy/octphy_hw_api.c @@ -237,7 +237,7 @@ msgb_put(msg, sizeof(*psc)); l1if_fill_msg_hdr(&psc->Header, msg, fl1h, cOCTVC1_MSG_TYPE_COMMAND, - cOCTVC1_HW_MSG_RF_PORT_INFO_ANTENNA_RX_CONFIG_CID); + cOCTVC1_HW_MSG_RF_PORT_INFO_ANTENNA_TX_CONFIG_CID); psc->ulPortIndex = port_idx; psc->ulAntennaIndex = ant_idx; -- To view, visit https://gerrit.osmocom.org/1966 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ie4de23daf79bb07ca0c0b818eefe350d18d27e4d Gerrit-PatchSet: 4 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Fri Apr 14 09:11:03 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 14 Apr 2017 09:11:03 +0000 Subject: [MERGED] osmo-bts[master]: octphy: add conditional compilation to support latest octasi... In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: octphy: add conditional compilation to support latest octasic header release ...................................................................... octphy: add conditional compilation to support latest octasic header release With octasics latest release (octsdr-2g-02.07.01-B1351-beta), some struct members are moved or renamed. This patch adds ifdef-logic and configure checks to restore compatibilty. Change-Id: I73287983e8bed8bf64b2ab87e6b810c2c59ea6fd --- M configure.ac M src/osmo-bts-octphy/octphy_hw_api.c M src/osmo-bts-octphy/octphy_vty.c 3 files changed, 74 insertions(+), 3 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/configure.ac b/configure.ac index 001e10e..cbfbf12 100644 --- a/configure.ac +++ b/configure.ac @@ -72,10 +72,46 @@ if test "$enable_octphy" = "yes" ; then oldCPPFLAGS=$CPPFLAGS CPPFLAGS="$CPPFLAGS -I$OCTSDR2G_INCDIR -I$srcdir/include $LIBOSMOCORE_CFLAGS" + AC_CHECK_HEADER([octphy/octvc1/gsm/octvc1_gsm_default.h],[], [AC_MSG_ERROR([octphy/octvc1/gsm/octvc1_gsm_default.h can not be found in $octsdr2g_incdir])], [#include ]) - AC_CHECK_MEMBER([tOCTVC1_GSM_TRX_CONFIG.usCentreArfcn], AC_DEFINE([OCTPHY_MULTI_TRX], [1], [Define to 1 if your octphy header files support multi-trx]), [], [#include ]) + + AC_CHECK_MEMBER([tOCTVC1_GSM_TRX_CONFIG.usCentreArfcn], + AC_DEFINE([OCTPHY_MULTI_TRX], + [1], + [Define to 1 if your octphy header files support multi-trx]), + [], + [#include ]) + + AC_CHECK_MEMBER([tOCTVC1_HW_RF_PORT_RX_STATS.Frequency], + AC_DEFINE([OCTPHY_USE_FREQUENCY], + [1], + [Define to 1 if your octphy header files support tOCTVC1_RADIO_FREQUENCY_VALUE type]), + [], + [#include ]) + + AC_CHECK_MEMBER([tOCTVC1_HW_MSG_CLOCK_SYNC_MGR_STATS_RSP.ulSyncLossCnt], + AC_DEFINE([OCTPHY_USE_SYNC_LOSS_CNT], + [1], + [Define to 1 if your octphy header files renamed ulSyncLosseCnt to ulSyncLossCnt]), + [], + [#include ]) + + AC_CHECK_MEMBER([tOCTVC1_HW_MSG_RF_PORT_INFO_ANTENNA_TX_CONFIG_RSP.TxConfig], + AC_DEFINE([OCTPHY_USE_TX_CONFIG], + [1], + [Define to 1 if your octphy header files support tOCTVC1_HW_RF_PORT_ANTENNA_TX_CONFIG type]), + [], + [#include ]) + + AC_CHECK_MEMBER([tOCTVC1_HW_MSG_RF_PORT_INFO_ANTENNA_RX_CONFIG_RSP.RxConfig], + AC_DEFINE([OCTPHY_USE_RX_CONFIG], + [1], + [Define to 1 if your octphy header files support tOCTVC1_HW_RF_PORT_ANTENNA_RX_CONFIG type]), + [], + [#include ]) + CPPFLAGS=$oldCPPFLAGS fi diff --git a/src/osmo-bts-octphy/octphy_hw_api.c b/src/osmo-bts-octphy/octphy_hw_api.c index 0d6fabd..7b988fe 100644 --- a/src/osmo-bts-octphy/octphy_hw_api.c +++ b/src/osmo-bts-octphy/octphy_hw_api.c @@ -125,11 +125,19 @@ psr->RxStats.ulRxByteCnt, psr->RxStats.ulRxOverflowCnt, psr->RxStats.ulRxAverageBytePerSecond, psr->RxStats.ulRxAveragePeriodUs, +#if OCTPHY_USE_FREQUENCY == 1 + psr->RxStats.Frequency.ulValue, +#else psr->RxStats.ulFrequencyKhz, +#endif psr->TxStats.ulTxByteCnt, psr->TxStats.ulTxUnderflowCnt, psr->TxStats.ulTxAverageBytePerSecond, psr->TxStats.ulTxAveragePeriodUs, +#if OCTPHY_USE_FREQUENCY == 1 + psr->TxStats.Frequency.ulValue); +#else psr->TxStats.ulFrequencyKhz); +#endif get_cb_data = (struct octphy_hw_get_cb_data*) data; get_cb_data->cb(resp,get_cb_data->data); @@ -177,10 +185,15 @@ LOGP(DL1C, LOGL_INFO, "ANT-RX-CONFIG.resp(Port=%u, Ant=%u): %s, " "Gain %d dB, GainCtrlMode=%s\n", arc->ulPortIndex, arc->ulAntennaIndex, +#ifdef OCTPHY_USE_RX_CONFIG + arc->RxConfig.ulEnableFlag ? "Enabled" : "Disabled", + arc->RxConfig.lRxGaindB/512, + get_value_string(rx_gain_mode_vals, arc->RxConfig.ulRxGainMode)); +#else arc->ulEnableFlag ? "Enabled" : "Disabled", arc->lRxGaindB/512, get_value_string(rx_gain_mode_vals, arc->ulRxGainMode)); - +#endif msgb_free(resp); return 0; } @@ -219,9 +232,14 @@ LOGP(DL1C, LOGL_INFO, "ANT-TX-CONFIG.resp(Port=%u, Ant=%u): %s, " "Gain %d dB\n", atc->ulPortIndex, atc->ulAntennaIndex, +#ifdef OCTPHY_USE_TX_CONFIG + atc->TxConfig.ulEnableFlag? "Enabled" : "Disabled", + atc->TxConfig.lTxGaindB/512); +#else atc->ulEnableFlag ? "Enabled" : "Disabled", atc->lTxGaindB/512); +#endif msgb_free(resp); return 0; } @@ -326,7 +344,12 @@ get_value_string(clocksync_state_vals, csr->ulState), csr->lClockError, csr->lDroppedCycles, csr->ulPllFreqHz, csr->ulPllFractionalFreqHz, csr->ulSlipCnt, - csr->ulSyncLosseCnt, csr->ulSourceState, csr->ulDacValue); +#if OCTPHY_USE_SYNC_LOSS_CNT == 1 + csr->ulSyncLossCnt, +#else + csr->ulSyncLosseCnt, +#endif + csr->ulSourceState, csr->ulDacValue); get_cb_data = (struct octphy_hw_get_cb_data*) data; get_cb_data->cb(resp,get_cb_data->data); diff --git a/src/osmo-bts-octphy/octphy_vty.c b/src/osmo-bts-octphy/octphy_vty.c index bc4acd6..370aff6 100644 --- a/src/osmo-bts-octphy/octphy_vty.c +++ b/src/osmo-bts-octphy/octphy_vty.c @@ -187,7 +187,11 @@ VTY_NEWLINE); vty_out(vty, "Rx Period=%u%s", psr->RxStats.ulRxAveragePeriodUs, VTY_NEWLINE); +#if OCTPHY_USE_FREQUENCY == 1 + vty_out(vty, "Rx Freq=%u%s", psr->RxStats.Frequency.ulValue, VTY_NEWLINE); +#else vty_out(vty, "Rx Freq=%u%s", psr->RxStats.ulFrequencyKhz, VTY_NEWLINE); +#endif vty_out(vty, "Tx Bytes=%u%s", psr->TxStats.ulTxByteCnt, VTY_NEWLINE); vty_out(vty, "Tx Underflow=%u%s", psr->TxStats.ulTxUnderflowCnt, VTY_NEWLINE); @@ -195,7 +199,11 @@ VTY_NEWLINE); vty_out(vty, "Tx Period=%u%s", psr->TxStats.ulTxAveragePeriodUs, VTY_NEWLINE); +#if OCTPHY_USE_FREQUENCY == 1 + vty_out(vty, "Tx Freq=%u%s", psr->TxStats.Frequency.ulValue, VTY_NEWLINE); +#else vty_out(vty, "Tx Freq=%u%s", psr->TxStats.ulFrequencyKhz, VTY_NEWLINE); +#endif } DEFUN(show_rf_port_stats, show_rf_port_stats_cmd, @@ -243,7 +251,11 @@ vty_out(vty, "PllFreqHz=%u%s", csr->ulPllFreqHz, VTY_NEWLINE); vty_out(vty, "PllFract=%u%s", csr->ulPllFractionalFreqHz, VTY_NEWLINE); vty_out(vty, "SlipCnt=%u%s", csr->ulSlipCnt, VTY_NEWLINE); +#if OCTPHY_USE_SYNC_LOSS_CNT == 1 + vty_out(vty, "SyncLosses=%u%s", csr->ulSyncLossCnt, VTY_NEWLINE); +#else vty_out(vty, "SyncLosses=%u%s", csr->ulSyncLosseCnt, VTY_NEWLINE); +#endif vty_out(vty, "SourceState=%u%s", csr->ulSourceState, VTY_NEWLINE); vty_out(vty, "DacValue=%u%s", csr->ulDacValue, VTY_NEWLINE); } -- To view, visit https://gerrit.osmocom.org/1964 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I73287983e8bed8bf64b2ab87e6b810c2c59ea6fd Gerrit-PatchSet: 4 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Fri Apr 14 09:11:03 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 14 Apr 2017 09:11:03 +0000 Subject: [MERGED] osmo-bts[master]: octphy: display hint in case of wrongly configured transceiv... In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: octphy: display hint in case of wrongly configured transceiver number ...................................................................... octphy: display hint in case of wrongly configured transceiver number Making use of the multi-trx feature requires to tell osmo-bts that more than one transceiver are available. Otherwise it will complain that not enough transceivers are available. This can be quite confusing, even a correct config file will fail to parse if it specifies more transcrivers than available. This patch adds a hint to the error message so that the user knows that he should check the -t commandline option Change-Id: Ifbeacd9d43f7c6cd74a1e1b33288e66828fe843f --- M src/common/vty.c 1 file changed, 2 insertions(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/common/vty.c b/src/common/vty.c index a48f809..44c742c 100644 --- a/src/common/vty.c +++ b/src/common/vty.c @@ -224,6 +224,8 @@ if (!trx) { vty_out(vty, "Unknown TRX %u. Available TRX are: 0..%u%s", trx_nr, bts->num_trx - 1, VTY_NEWLINE); + vty_out(vty, "Hint: Check if commandline option -t matches the" + "number of available transceivers!%s", VTY_NEWLINE); return CMD_WARNING; } -- To view, visit https://gerrit.osmocom.org/2316 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ifbeacd9d43f7c6cd74a1e1b33288e66828fe843f Gerrit-PatchSet: 2 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Fri Apr 14 09:11:03 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 14 Apr 2017 09:11:03 +0000 Subject: [MERGED] osmo-bts[master]: octphy: print log message for multi-trx support In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: octphy: print log message for multi-trx support ...................................................................... octphy: print log message for multi-trx support Some header file versions support multi-trx and some do not. After to compiling it is very difficult to find out if the binary is multi-trx capable por not. This patch adds a log line that should rule out any doubts. Change-Id: I257c0a5e7c5ff5df2f0a603d1ede6db5679382e0 --- M src/osmo-bts-octphy/l1_oml.c 1 file changed, 6 insertions(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/osmo-bts-octphy/l1_oml.c b/src/osmo-bts-octphy/l1_oml.c index 6857a5d..0cd25f2 100644 --- a/src/osmo-bts-octphy/l1_oml.c +++ b/src/osmo-bts-octphy/l1_oml.c @@ -1187,6 +1187,12 @@ LOGP(DL1C, LOGL_INFO, "Rx APP-INFO-SYSTEM.resp (platform='%s', version='%s')\n", aisr->szPlatform, aisr->szVersion); +#if OCTPHY_MULTI_TRX == 1 + LOGP(DL1C, LOGL_INFO, "Note: compiled with multi-trx support.\n"); +#else + LOGP(DL1C, LOGL_INFO, "Note: compiled without multi-trx support.\n"); +#endif + talloc_replace(fl1h->info.system.platform, fl1h, aisr->szPlatform); talloc_replace(fl1h->info.system.version, fl1h, aisr->szVersion); -- To view, visit https://gerrit.osmocom.org/2315 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I257c0a5e7c5ff5df2f0a603d1ede6db5679382e0 Gerrit-PatchSet: 2 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Fri Apr 14 09:11:03 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 14 Apr 2017 09:11:03 +0000 Subject: [MERGED] osmo-bts[master]: octphy: add CBCH support In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: octphy: add CBCH support ...................................................................... octphy: add CBCH support add Support for CBCH channels in osmo-bts-octphy Change-Id: Ic5c8363b4dd8ba78ab22bd5527c08d1162331540 --- M src/osmo-bts-octphy/l1_if.c M src/osmo-bts-octphy/l1_oml.c 2 files changed, 19 insertions(+), 1 deletion(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/osmo-bts-octphy/l1_if.c b/src/osmo-bts-octphy/l1_if.c index 0fc51fc..b42fb3a 100644 --- a/src/osmo-bts-octphy/l1_if.c +++ b/src/osmo-bts-octphy/l1_if.c @@ -43,6 +43,7 @@ #include #include #include +#include #include "l1_if.h" #include "l1_oml.h" @@ -340,9 +341,11 @@ cbits = 0x02 + subCh; break; case GSM_PCHAN_CCCH_SDCCH4: + case GSM_PCHAN_CCCH_SDCCH4_CBCH: cbits = 0x04 + subCh; break; case GSM_PCHAN_SDCCH8_SACCH8C: + case GSM_PCHAN_SDCCH8_SACCH8C_CBCH: cbits = 0x08 + subCh; break; default: @@ -353,9 +356,11 @@ case cOCTVC1_GSM_SAPI_ENUM_SDCCH: switch (pchan) { case GSM_PCHAN_CCCH_SDCCH4: + case GSM_PCHAN_CCCH_SDCCH4_CBCH: cbits = 0x04 + subCh; break; case GSM_PCHAN_SDCCH8_SACCH8C: + case GSM_PCHAN_SDCCH8_SACCH8C_CBCH: cbits = 0x08 + subCh; break; default: @@ -918,6 +923,10 @@ (g_time.t1 << 7) | (g_time.t2 << 2) | (t3p >> 1); data_req->Data.abyDataContent[3] = (t3p & 1); break; + case cOCTVC1_GSM_SAPI_ENUM_CBCH: + rc = bts_cbch_get(bts, data_req->Data.abyDataContent, &g_time); + data_req->Data.ulDataLength = 23; /* GSM MAX BLK SIZE */ + break; case cOCTVC1_GSM_SAPI_ENUM_PRACH: #if 0 /* in case we decide to send an empty frame... */ @@ -1101,7 +1110,8 @@ l1sap->u.rach_ind.acc_delay = acc_delay; l1sap->u.rach_ind.fn = fn; if (!lchan || lchan->ts->pchan == GSM_PCHAN_CCCH || - lchan->ts->pchan == GSM_PCHAN_CCCH_SDCCH4) + lchan->ts->pchan == GSM_PCHAN_CCCH_SDCCH4 || + lchan->ts->pchan == GSM_PCHAN_CCCH_SDCCH4_CBCH) l1sap->u.rach_ind.chan_nr = 0x88; else l1sap->u.rach_ind.chan_nr = gsm_lchan2chan_nr(lchan); diff --git a/src/osmo-bts-octphy/l1_oml.c b/src/osmo-bts-octphy/l1_oml.c index a68169e..6857a5d 100644 --- a/src/osmo-bts-octphy/l1_oml.c +++ b/src/osmo-bts-octphy/l1_oml.c @@ -64,6 +64,12 @@ // TODO - watch out below two!!! [GSM_PCHAN_PDCH] = cOCTVC1_GSM_LOGICAL_CHANNEL_COMBINATION_ENUM_PDTCHF_PACCHF_PTCCHF, [GSM_PCHAN_TCH_F_PDCH] = cOCTVC1_GSM_LOGICAL_CHANNEL_COMBINATION_ENUM_PDTCHF_PACCHF_PTCCHF, +#ifdef cOCTVC1_GSM_LOGICAL_CHANNEL_COMBINATION_ENUM_FCCH_SCH_BCCH_CCCH_SDCCH4_CBCH_SACCHC4 + [GSM_PCHAN_CCCH_SDCCH4_CBCH] = cOCTVC1_GSM_LOGICAL_CHANNEL_COMBINATION_ENUM_FCCH_SCH_BCCH_CCCH_SDCCH4_CBCH_SACCHC4, +#endif +#ifdef cOCTVC1_GSM_LOGICAL_CHANNEL_COMBINATION_ENUM_SDCCH8_CBCH_SACCHC8 + [GSM_PCHAN_SDCCH8_SACCH8C_CBCH] = cOCTVC1_GSM_LOGICAL_CHANNEL_COMBINATION_ENUM_SDCCH8_CBCH_SACCHC8, +#endif [GSM_PCHAN_UNKNOWN] = cOCTVC1_GSM_LOGICAL_CHANNEL_COMBINATION_ENUM_EMPTY }; @@ -202,11 +208,13 @@ { switch (lchan->ts->pchan) { case GSM_PCHAN_CCCH_SDCCH4: + case GSM_PCHAN_CCCH_SDCCH4_CBCH: if (lchan->type == GSM_LCHAN_CCCH) return cOCTVC1_GSM_ID_SUB_CHANNEL_NB_ENUM_ALL; /* fall-through */ case GSM_PCHAN_TCH_H: case GSM_PCHAN_SDCCH8_SACCH8C: + case GSM_PCHAN_SDCCH8_SACCH8C_CBCH: return (tOCTVC1_GSM_ID_SUB_CHANNEL_NB_ENUM) lchan->nr; case GSM_PCHAN_NONE: case GSM_PCHAN_CCCH: -- To view, visit https://gerrit.osmocom.org/1979 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ic5c8363b4dd8ba78ab22bd5527c08d1162331540 Gerrit-PatchSet: 5 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Fri Apr 14 09:11:57 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 14 Apr 2017 09:11:57 +0000 Subject: libosmo-netif[master]: osmo_stream_srv_fd_cb(): don't leak socket FDs on errors In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/1320 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I3a3ce9194ab7ca5c1921fc79c2a1c9e10a552cf0 Gerrit-PatchSet: 2 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Apr 14 09:12:00 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 14 Apr 2017 09:12:00 +0000 Subject: [MERGED] libosmo-netif[master]: osmo_stream_srv_fd_cb(): don't leak socket FDs on errors In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: osmo_stream_srv_fd_cb(): don't leak socket FDs on errors ...................................................................... osmo_stream_srv_fd_cb(): don't leak socket FDs on errors So far we seem to assume that the accept_cb does all handling of socket fd cleanup. However, there are cases where there is no accept_cb set, the accept_cb returns error, or an earlier sctp_sock_activate_events() or the activation of non-blocking mode fails. For those cases, close the socket and return an error code. Fixes: CID#57915 Change-Id: I3a3ce9194ab7ca5c1921fc79c2a1c9e10a552cf0 --- M src/stream.c 1 file changed, 23 insertions(+), 6 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/stream.c b/src/stream.c index 591cd06..653f26b 100644 --- a/src/stream.c +++ b/src/stream.c @@ -529,6 +529,7 @@ static int osmo_stream_srv_fd_cb(struct osmo_fd *ofd, unsigned int what) { int ret; + int sock_fd; struct sockaddr_in sa; socklen_t sa_len = sizeof(sa); struct osmo_stream_srv_link *link = ofd->data; @@ -541,17 +542,33 @@ } LOGP(DLINP, LOGL_DEBUG, "accept()ed new link from %s to port %u\n", inet_ntoa(sa.sin_addr), link->port); + sock_fd = ret; - if (link->proto == IPPROTO_SCTP) - sctp_sock_activate_events(ret); + if (link->proto == IPPROTO_SCTP) { + ret = sctp_sock_activate_events(sock_fd); + if (ret < 0) + goto error_close_socket; + } - if (link->flags & OSMO_STREAM_SRV_F_NODELAY) - setsockopt_nodelay(ret, link->proto, 1); + if (link->flags & OSMO_STREAM_SRV_F_NODELAY) { + ret = setsockopt_nodelay(ret, link->proto, 1); + if (ret < 0) + goto error_close_socket; + } - if (link->accept_cb) - link->accept_cb(link, ret); + if (!link->accept_cb) { + ret = -ENOTSUP; + goto error_close_socket; + } + ret = link->accept_cb(link, sock_fd); + if (ret) + goto error_close_socket; return 0; + +error_close_socket: + close(sock_fd); + return ret; } /*! \brief Create an Osmocom Stream Server Link -- To view, visit https://gerrit.osmocom.org/1320 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I3a3ce9194ab7ca5c1921fc79c2a1c9e10a552cf0 Gerrit-PatchSet: 2 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Fri Apr 14 12:03:15 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 14 Apr 2017 12:03:15 +0000 Subject: [PATCH] libosmocore[master]: vty/command.h: Introduce VTY nodes for libosmo-sigtran Message-ID: Review at https://gerrit.osmocom.org/2327 vty/command.h: Introduce VTY nodes for libosmo-sigtran This adds several VTY nodes required by the libosmo-sigtran VTY interface. Change-Id: I184a7e3187b48c15c71bf773f86e188fe1daad15 --- M include/osmocom/vty/command.h 1 file changed, 8 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/27/2327/1 diff --git a/include/osmocom/vty/command.h b/include/osmocom/vty/command.h index 135ef2f..b39bbf7 100644 --- a/include/osmocom/vty/command.h +++ b/include/osmocom/vty/command.h @@ -85,6 +85,14 @@ L_BSSGP_NODE, /*!< \brief BSSGP node in libosmo-gb. */ L_CTRL_NODE, /*!< \brief Control interface node. */ + L_CS7_NODE, /*!< \brief SS7 root node */ + L_CS7_AS_NODE, /*!< \brief SS7 Application Server */ + L_CS7_ASP_NODE, /*!< \brief SS7 Application Server Process */ + L_CS7_XUA_NODE, /*!< \brief SS7 xUA Listener */ + L_CS7_RTABLE_NODE, /*!< \brief SS7 Routing Table */ + L_CS7_LINK_NODE, /*!< \brief SS7 Link */ + L_CS7_LINKSET_NODE, /*!< \brief SS7 Linkset */ + /* * When adding new nodes to the libosmocore project, these nodes can be * used to avoid ABI changes for unrelated projects. -- To view, visit https://gerrit.osmocom.org/2327 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I184a7e3187b48c15c71bf773f86e188fe1daad15 Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Fri Apr 14 12:22:20 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 14 Apr 2017 12:22:20 +0000 Subject: libosmocore[master]: vty/command.h: Introduce VTY nodes for libosmo-sigtran In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2327 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I184a7e3187b48c15c71bf773f86e188fe1daad15 Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Apr 14 12:22:31 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 14 Apr 2017 12:22:31 +0000 Subject: [MERGED] libosmocore[master]: vty/command.h: Introduce VTY nodes for libosmo-sigtran In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: vty/command.h: Introduce VTY nodes for libosmo-sigtran ...................................................................... vty/command.h: Introduce VTY nodes for libosmo-sigtran This adds several VTY nodes required by the libosmo-sigtran VTY interface. Change-Id: I184a7e3187b48c15c71bf773f86e188fe1daad15 --- M include/osmocom/vty/command.h 1 file changed, 8 insertions(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/include/osmocom/vty/command.h b/include/osmocom/vty/command.h index 135ef2f..b39bbf7 100644 --- a/include/osmocom/vty/command.h +++ b/include/osmocom/vty/command.h @@ -85,6 +85,14 @@ L_BSSGP_NODE, /*!< \brief BSSGP node in libosmo-gb. */ L_CTRL_NODE, /*!< \brief Control interface node. */ + L_CS7_NODE, /*!< \brief SS7 root node */ + L_CS7_AS_NODE, /*!< \brief SS7 Application Server */ + L_CS7_ASP_NODE, /*!< \brief SS7 Application Server Process */ + L_CS7_XUA_NODE, /*!< \brief SS7 xUA Listener */ + L_CS7_RTABLE_NODE, /*!< \brief SS7 Routing Table */ + L_CS7_LINK_NODE, /*!< \brief SS7 Link */ + L_CS7_LINKSET_NODE, /*!< \brief SS7 Linkset */ + /* * When adding new nodes to the libosmocore project, these nodes can be * used to avoid ABI changes for unrelated projects. -- To view, visit https://gerrit.osmocom.org/2327 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I184a7e3187b48c15c71bf773f86e188fe1daad15 Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Fri Apr 14 12:54:15 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 14 Apr 2017 12:54:15 +0000 Subject: [PATCH] libosmo-sccp[master]: STP: re-structure VTY interface; introduce 'cs7 instance' node Message-ID: Review at https://gerrit.osmocom.org/2328 STP: re-structure VTY interface; introduce 'cs7 instance' node This properly integrates the concept of multiple SS7 instances (each with their own point code format, address indicator, ...) into the VTY. At the same time, this also removes the stp-global "g_s7i" instance that existed so far, moving the VTY code more into the direction of also being able to be used outside the STP - which is underlined by splitting the vty commands between those generally useful, and those useful only for a STP or only for a simpla ASP (client). Change-Id: I30966fbf2e143318cd9127eb8c17cccb24407106 --- M include/osmocom/sigtran/osmo_ss7.h M src/osmo_ss7.c M stp/internal.h M stp/osmo_ss7_vty.c M stp/stp_main.c 5 files changed, 257 insertions(+), 203 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/28/2328/1 diff --git a/include/osmocom/sigtran/osmo_ss7.h b/include/osmocom/sigtran/osmo_ss7.h index 49a8ca5..1d82669 100644 --- a/include/osmocom/sigtran/osmo_ss7.h +++ b/include/osmocom/sigtran/osmo_ss7.h @@ -9,6 +9,7 @@ #include #include +extern struct llist_head osmo_ss7_instances; extern struct llist_head osmo_ss7_xua_servers; struct osmo_ss7_instance; diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index d864916..27e56af 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -52,7 +52,7 @@ static bool ss7_initialized = false; -static LLIST_HEAD(ss7_instances); +LLIST_HEAD(osmo_ss7_instances); LLIST_HEAD(osmo_ss7_xua_servers); static int32_t next_rctx = 1; static int32_t next_l_rk_id = 1; @@ -296,7 +296,7 @@ OSMO_ASSERT(ss7_initialized); struct osmo_ss7_instance *inst; - llist_for_each_entry(inst, &ss7_instances, list) { + llist_for_each_entry(inst, &osmo_ss7_instances, list) { if (inst->cfg.id == id) return inst; } @@ -335,7 +335,7 @@ inst->cfg.pc_fmt.component_len[1] = 8; inst->cfg.pc_fmt.component_len[2] = 3; - llist_add(&inst->list, &ss7_instances); + llist_add(&inst->list, &osmo_ss7_instances); return inst; } @@ -993,7 +993,7 @@ /* check all instances for any ASP definition matching the * address combination of local/remote ip/port */ - llist_for_each_entry(inst, &ss7_instances, list) { + llist_for_each_entry(inst, &osmo_ss7_instances, list) { struct osmo_ss7_asp *asp; llist_for_each_entry(asp, &inst->asp_list, list) { if (asp->cfg.local.port == local_port && diff --git a/stp/internal.h b/stp/internal.h index 0a434cc..31d95ba 100644 --- a/stp/internal.h +++ b/stp/internal.h @@ -3,16 +3,16 @@ #include enum stp_vty_node { - L_CS7_AS_NODE = _LAST_OSMOVTY_NODE + 1, + L_CS7_NODE = _LAST_OSMOVTY_NODE + 1, + L_CS7_AS_NODE, L_CS7_ASP_NODE, L_CS7_SUA_NODE, L_CS7_M3UA_NODE, L_CS7_RTABLE_NODE, }; -int osmo_ss7_vty_init(void); +void osmo_ss7_set_vty_alloc_ctx(void *ctx); +void osmo_ss7_vty_init_asp(void); +void osmo_ss7_vty_init_sg(void); int osmo_ss7_vty_go_parent(struct vty *vty); int osmo_ss7_is_config_node(struct vty *vty, int node); - -extern struct osmo_ss7_instance *g_s7i; - diff --git a/stp/osmo_ss7_vty.c b/stp/osmo_ss7_vty.c index 014fa03..29693a8 100644 --- a/stp/osmo_ss7_vty.c +++ b/stp/osmo_ss7_vty.c @@ -44,6 +44,35 @@ * Core CS7 Configuration ***********************************************************************/ +static void *g_ctx; + +static struct cmd_node cs7_node = { + L_CS7_NODE, + "%s(config-cs7)# ", + 1, +}; + +DEFUN(cs7_instance, cs7_instance_cmd, + "cs7 instance <0-15>", + CS7_STR "Configure a SS7 Instance\n" + "Number of the instance\n") +{ + int id = atoi(argv[0]); + struct osmo_ss7_instance *inst; + + inst = osmo_ss7_instance_find_or_create(g_ctx, id); + if (!inst) { + vty_out(vty, "Unable to create SS7 Instance %d%s", id, VTY_NEWLINE); + return CMD_WARNING; + } + + vty->node = L_CS7_NODE; + vty->index = inst; + vty->index_sub = &inst->cfg.description; + + return CMD_SUCCESS; +} + static const struct value_string ss7_network_indicator_vals[] = { { 0, "international" }, { 1, "spare" }, @@ -54,14 +83,14 @@ /* cs7 network-indicator */ DEFUN(cs7_net_ind, cs7_net_ind_cmd, - "cs7 network-indicator (international | national | reserved | spare)", - CS7_STR "Configure the Network Indicator\n" + "network-indicator (international | national | reserved | spare)", + "Configure the Network Indicator\n" "International Network\n" "National Network\n" "Reserved Network\n" "Spare Network\n") { - struct osmo_ss7_instance *inst = g_s7i; + struct osmo_ss7_instance *inst = vty->index; int ni = get_string_value(ss7_network_indicator_vals, argv[0]); inst->cfg.network_indicator = ni; @@ -70,13 +99,13 @@ /* TODO: cs7 point-code format */ DEFUN(cs7_pc_format, cs7_pc_format_cmd, - "cs7 point-code format <1-24> [<1-23>] [<1-22>]", - CS7_STR PC_STR "Configure Point Code Format\n" + "point-code format <1-24> [<1-23>] [<1-22>]", + PC_STR "Configure Point Code Format\n" "Length of first PC component\n" "Length of second PC component\n" "Length of third PC component\n") { - struct osmo_ss7_instance *inst = g_s7i; + struct osmo_ss7_instance *inst = vty->index; int argind = 0; inst->cfg.pc_fmt.component_len[0] = atoi(argv[argind++]); @@ -95,11 +124,11 @@ } DEFUN(cs7_pc_format_def, cs7_pc_format_def_cmd, - "cs7 point-code format default", - CS7_STR PC_STR "Configure Point Code Format\n" + "point-code format default", + PC_STR "Configure Point Code Format\n" "Default Point Code Format (3.8.3)\n") { - struct osmo_ss7_instance *inst = g_s7i; + struct osmo_ss7_instance *inst = vty->index; inst->cfg.pc_fmt.component_len[0] = 3; inst->cfg.pc_fmt.component_len[1] = 8; inst->cfg.pc_fmt.component_len[2] = 3; @@ -109,12 +138,12 @@ /* cs7 point-code delimiter */ DEFUN(cs7_pc_delimiter, cs7_pc_delimiter_cmd, - "cs7 point-code delimiter (default|dash)", - CS7_STR PC_STR "Configure Point Code Delimiter\n" + "point-code delimiter (default|dash)", + PC_STR "Configure Point Code Delimiter\n" "Use dot as delimiter\n" "User dash as delimiter\n") { - struct osmo_ss7_instance *inst = g_s7i; + struct osmo_ss7_instance *inst = vty->index; if (!strcmp(argv[0], "dash")) inst->cfg.pc_fmt.delimiter = '-'; @@ -125,11 +154,11 @@ } DEFUN(cs7_point_code, cs7_point_code_cmd, - "cs7 point-code POINT_CODE", - CS7_STR "Configure the local Point Code\n" + "point-code POINT_CODE", + "Configure the local Point Code\n" "Point Code\n") { - struct osmo_ss7_instance *inst = g_s7i; + struct osmo_ss7_instance *inst = vty->index; uint32_t pc = osmo_ss7_pointcode_parse(inst, argv[0]); inst->cfg.primary_pc = pc; @@ -138,39 +167,16 @@ /* TODO: cs7 secondary-pc */ /* TODO: cs7 capability-pc */ +static void write_one_cs7(struct vty *vty, struct osmo_ss7_instance *inst); -static void write_one_ss7_inst(struct vty *vty, struct osmo_ss7_instance *inst) +static int config_write_cs7(struct vty *vty) { - if (inst->cfg.network_indicator) - vty_out(vty, "cs7 network-indicator %s%s", - get_value_string(ss7_network_indicator_vals, - inst->cfg.network_indicator), - VTY_NEWLINE); + struct osmo_ss7_instance *inst; - if (inst->cfg.pc_fmt.component_len[0] != 3 || - inst->cfg.pc_fmt.component_len[1] != 8 || - inst->cfg.pc_fmt.component_len[2] != 3) { - vty_out(vty, "cs7 point-code format %u", - inst->cfg.pc_fmt.component_len[0]); - if (inst->cfg.pc_fmt.component_len[1]) - vty_out(vty, " %u", inst->cfg.pc_fmt.component_len[1]); - if (inst->cfg.pc_fmt.component_len[2]) - vty_out(vty, " %u", inst->cfg.pc_fmt.component_len[2]); - vty_out(vty, "%s", VTY_NEWLINE); - } + llist_for_each_entry(inst, &osmo_ss7_instances, list) + write_one_cs7(vty, inst); - if (inst->cfg.pc_fmt.delimiter != '.') - vty_out(vty, "cs7 point-code delimiter dash%s", VTY_NEWLINE); - - if (inst->cfg.primary_pc) - vty_out(vty, "cs7 point-code %s%s", - osmo_ss7_pointcode_print(inst, inst->cfg.primary_pc), - VTY_NEWLINE); -} - -static void config_write_cs7(struct vty *vty) -{ - write_one_ss7_inst(vty, g_s7i); + return 0; } /*********************************************************************** @@ -184,11 +190,11 @@ }; DEFUN(cs7_route_table, cs7_route_table_cmd, - "cs7 route-table system", - CS7_STR "Specify the name of the route table\n" + "route-table system", + "Specify the name of the route table\n" "Name of the route table\n") { - struct osmo_ss7_instance *inst = g_s7i; + struct osmo_ss7_instance *inst = vty->index; struct osmo_ss7_route_table *rtable; rtable = inst->rtable_system; @@ -269,11 +275,11 @@ { struct osmo_ss7_route *rt; - vty_out(vty, "cs7 route-table %s%s", rtable->cfg.name, VTY_NEWLINE); + vty_out(vty, " route-table %s%s", rtable->cfg.name, VTY_NEWLINE); if (rtable->cfg.description) - vty_out(vty, " description %s%s", rtable->cfg.description, VTY_NEWLINE); + vty_out(vty, " description %s%s", rtable->cfg.description, VTY_NEWLINE); llist_for_each_entry(rt, &rtable->routes, list) { - vty_out(vty, " update route %s %s linkset %s", + vty_out(vty, " update route %s %s linkset %s", osmo_ss7_pointcode_print(rtable->inst, rt->cfg.pc), osmo_ss7_pointcode_print(rtable->inst, rt->cfg.mask), rt->cfg.linkset_name); @@ -283,17 +289,6 @@ vty_out(vty, " qos-class %u", rt->cfg.qos_class); vty_out(vty, "%s", VTY_NEWLINE); } -} - -static int config_write_rtable(struct vty *vty) -{ - struct osmo_ss7_instance *inst = g_s7i; - struct osmo_ss7_route_table *rtable; - - llist_for_each_entry(rtable, &inst->rtable_list, list) - write_one_rtable(vty, rtable); - - return 0; } static void vty_dump_rtable(struct vty *vty, struct osmo_ss7_route_table *rtbl) @@ -314,17 +309,26 @@ } DEFUN(show_cs7_route, show_cs7_route_cmd, - "show cs7 route", + "show cs7 route [instance <0-15>]", SHOW_STR CS7_STR "Routing Table\n") { - struct osmo_ss7_instance *inst = g_s7i; + int id = 0; + struct osmo_ss7_instance *inst; + + if (argc > 0) + id = atoi(argv[0]); + inst = osmo_ss7_instance_find(id); + if (!inst) { + vty_out(vty, "No SS7 instance %d found%s", id, VTY_NEWLINE); + return CMD_WARNING; + } vty_dump_rtable(vty, inst->rtable_system); return CMD_SUCCESS; } /*********************************************************************** - * SUA Configuration + * SUA Configuration (SG) ***********************************************************************/ static struct cmd_node sua_node = { @@ -334,12 +338,11 @@ }; DEFUN(cs7_sua, cs7_sua_cmd, - "cs7 sua <0-65534>", - CS7_STR + "sua <0-65534>", "Configure/Enable SUA\n" "SCTP Port number for SUA\n") { - struct osmo_ss7_instance *inst = g_s7i; + struct osmo_ss7_instance *inst = vty->index; struct osmo_xua_server *xs; uint16_t port = atoi(argv[0]); @@ -356,11 +359,11 @@ } DEFUN(no_cs7_sua, no_cs7_sua_cmd, - "no cs7 sua <0-65534>", - NO_STR CS7_STR "Disable SUA on given SCTP Port\n" + "no sua <0-65534>", + NO_STR "Disable SUA on given SCTP Port\n" "SCTP Port number for SUA\n") { - struct osmo_ss7_instance *inst = g_s7i; + struct osmo_ss7_instance *inst = vty->index; struct osmo_xua_server *xs; uint16_t port = atoi(argv[0]); @@ -391,25 +394,15 @@ static void write_one_sua(struct vty *vty, struct osmo_xua_server *xs) { - vty_out(vty, "cs7 %s %u%s", + vty_out(vty, " %s %u%s", get_value_string(osmo_ss7_asp_protocol_vals, xs->cfg.proto), xs->cfg.local.port, VTY_NEWLINE); - vty_out(vty, " local-ip %s%s", xs->cfg.local.host, VTY_NEWLINE); + vty_out(vty, " local-ip %s%s", xs->cfg.local.host, VTY_NEWLINE); } - -static int config_write_sua(struct vty *vty) -{ - struct osmo_xua_server *xs; - - llist_for_each_entry(xs, &osmo_ss7_xua_servers, list) - write_one_sua(vty, xs); - - return 0; -} /*********************************************************************** - * M3UA Configuration + * M3UA Configuration (SG) ***********************************************************************/ static struct cmd_node m3ua_node = { @@ -419,12 +412,11 @@ }; DEFUN(cs7_m3ua, cs7_m3ua_cmd, - "cs7 m3ua <0-65534>", - CS7_STR + "m3ua <0-65534>", "Configure/Enable M3UA\n" "SCTP Port number for M3UA\n") { - struct osmo_ss7_instance *inst = g_s7i; + struct osmo_ss7_instance *inst = vty->index; struct osmo_xua_server *xs; uint16_t port = atoi(argv[0]); @@ -441,11 +433,11 @@ } DEFUN(no_cs7_m3ua, no_cs7_m3ua_cmd, - "no cs7 m3ua <0-65534>", - NO_STR CS7_STR "Disable M3UA on given SCTP Port\n" + "no m3ua <0-65534>", + NO_STR "Disable M3UA on given SCTP Port\n" "SCTP Port number for M3UA\n") { - struct osmo_ss7_instance *inst = g_s7i; + struct osmo_ss7_instance *inst = vty->index; struct osmo_xua_server *xs; uint16_t port = atoi(argv[0]); @@ -469,12 +461,6 @@ return CMD_SUCCESS; } -static int config_write_m3ua(struct vty *vty) -{ - /* see config_write_sua */ - return 0; -} - /*********************************************************************** * Application Server Process ***********************************************************************/ @@ -486,8 +472,7 @@ }; DEFUN(cs7_asp, cs7_asp_cmd, - "cs7 asp NAME <0-65535> <0-65535> (m3ua|sua)", - CS7_STR + "asp NAME <0-65535> <0-65535> (m3ua|sua)", "Configure Application Server Process\n" "Name of ASP\n" "Remote SCTP port number\n" @@ -495,7 +480,7 @@ "M3UA Protocol\n" "SUA Protocol\n") { - struct osmo_ss7_instance *inst = g_s7i; + struct osmo_ss7_instance *inst = vty->index; const char *name = argv[0]; uint16_t remote_port = atoi(argv[1]); uint16_t local_port = atoi(argv[2]); @@ -521,11 +506,11 @@ } DEFUN(no_cs7_asp, no_cs7_asp_cmd, - "no cs7 asp NAME", - NO_STR CS7_STR "Disable Application Server Process\n" + "no asp NAME", + NO_STR "Disable Application Server Process\n" "Name of ASP\n") { - struct osmo_ss7_instance *inst = g_s7i; + struct osmo_ss7_instance *inst = vty->index; const char *name = argv[0]; struct osmo_ss7_asp *asp; @@ -577,11 +562,20 @@ } DEFUN(show_cs7_asp, show_cs7_asp_cmd, - "show cs7 asp", + "show cs7 asp [instance <0-15>]", SHOW_STR CS7_STR "Application Server Process (ASP)\n") { - struct osmo_ss7_instance *inst = g_s7i; + struct osmo_ss7_instance *inst; struct osmo_ss7_asp *asp; + int id = 0; + + if (argc > 0) + id = atoi(argv[0]); + inst = osmo_ss7_instance_find(id); + if (!inst) { + vty_out(vty, "No SS7 instance %d found%s", id, VTY_NEWLINE); + return CMD_WARNING; + } vty_out(vty, " Effect Primary%s", VTY_NEWLINE); vty_out(vty, "ASP Name AS Name State Type Rmt Port Remote IP Addr SCTP%s", VTY_NEWLINE); @@ -598,25 +592,14 @@ static void write_one_asp(struct vty *vty, struct osmo_ss7_asp *asp) { - vty_out(vty, "cs7 asp %s %u %u %s%s", + vty_out(vty, " asp %s %u %u %s%s", asp->cfg.name, asp->cfg.remote.port, asp->cfg.local.port, osmo_ss7_asp_protocol_name(asp->cfg.proto), VTY_NEWLINE); if (asp->cfg.description) - vty_out(vty, " description %s%s", asp->cfg.description, VTY_NEWLINE); - vty_out(vty, " remote-ip %s%s", asp->cfg.remote.host, VTY_NEWLINE); + vty_out(vty, " description %s%s", asp->cfg.description, VTY_NEWLINE); + vty_out(vty, " remote-ip %s%s", asp->cfg.remote.host, VTY_NEWLINE); if (asp->cfg.qos_class) - vty_out(vty, " qos-class %u%s", asp->cfg.qos_class, VTY_NEWLINE); -} - -static int config_write_asp(struct vty *vty) -{ - struct osmo_ss7_instance *inst = g_s7i; - struct osmo_ss7_asp *asp; - - llist_for_each_entry(asp, &inst->asp_list, list) - write_one_asp(vty, asp); - - return 0; + vty_out(vty, " qos-class %u%s", asp->cfg.qos_class, VTY_NEWLINE); } @@ -631,14 +614,13 @@ }; DEFUN(cs7_as, cs7_as_cmd, - "cs7 as NAME (m3ua|sua)", - CS7_STR + "as NAME (m3ua|sua)", "Configure an Application Server\n" "Name of the Application Server\n" "M3UA Application Server\n" "SUA Application Server\n") { - struct osmo_ss7_instance *inst = g_s7i; + struct osmo_ss7_instance *inst = vty->index; struct osmo_ss7_as *as; const char *name = argv[0]; enum osmo_ss7_asp_protocol protocol = parse_asp_proto(argv[1]); @@ -664,11 +646,11 @@ } DEFUN(no_cs7_as, no_cs7_as_cmd, - "no cs7 as NAME", - NO_STR CS7_STR "Disable Application Server\n" + "no as NAME", + NO_STR "Disable Application Server\n" "Name of AS\n") { - struct osmo_ss7_instance *inst = g_s7i; + struct osmo_ss7_instance *inst = vty->index; const char *name = argv[0]; struct osmo_ss7_as *as; @@ -805,27 +787,27 @@ struct osmo_ss7_routing_key *rkey; unsigned int i; - vty_out(vty, "cs7 as %s %s%s", as->cfg.name, + vty_out(vty, " as %s %s%s", as->cfg.name, osmo_ss7_asp_protocol_name(as->cfg.proto), VTY_NEWLINE); if (as->cfg.description) - vty_out(vty, " description %s%s", as->cfg.description, VTY_NEWLINE); + vty_out(vty, " description %s%s", as->cfg.description, VTY_NEWLINE); for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) { struct osmo_ss7_asp *asp = as->cfg.asps[i]; if (!asp) continue; - vty_out(vty, " asp %s%s", asp->cfg.name, VTY_NEWLINE); + vty_out(vty, " asp %s%s", asp->cfg.name, VTY_NEWLINE); } if (as->cfg.mode != OSMO_SS7_AS_TMOD_LOADSHARE) - vty_out(vty, " traffic-mode %s%s", + vty_out(vty, " traffic-mode %s%s", osmo_ss7_as_traffic_mode_name(as->cfg.mode), VTY_NEWLINE); if (as->cfg.recovery_timeout_msec != 2000) { - vty_out(vty, " recovery-timeout %u%s", + vty_out(vty, " recovery-timeout %u%s", as->cfg.recovery_timeout_msec, VTY_NEWLINE); } if (as->cfg.qos_class) - vty_out(vty, " qos-class %u%s", as->cfg.qos_class, VTY_NEWLINE); + vty_out(vty, " qos-class %u%s", as->cfg.qos_class, VTY_NEWLINE); rkey = &as->cfg.routing_key; - vty_out(vty, " routing-key %u %s", rkey->context, + vty_out(vty, " routing-key %u %s", rkey->context, osmo_ss7_pointcode_print(as->inst, rkey->pc)); if (rkey->si) vty_out(vty, " si %s", @@ -835,41 +817,29 @@ vty_out(vty, "%s", VTY_NEWLINE); } -static int config_write_as(struct vty *vty) -{ - struct osmo_ss7_instance *inst = g_s7i; - struct osmo_ss7_as *as; - - /* HACK to call this here, as we cannot install additional - * 'save' code into the root CONFIG_NODE ... */ - config_write_cs7(vty); - - /* HACK to call this here, but we must make sure that the ASP - * are all configured before we reference them from the AS, and - * VTY code always stores the nodes in alphabetical order */ - - config_write_asp(vty); - - llist_for_each_entry(as, &inst->as_list, list) - write_one_as(vty, as); - - return 0; -} - DEFUN(show_cs7_as, show_cs7_as_cmd, - "show cs7 as (active|all|m3ua|sua)", + "show cs7 as (active|all|m3ua|sua) [instance <0-15>]", SHOW_STR CS7_STR "Application Server (AS)\n" "Display all active ASs\n" "Display all ASs (default)\n" "Display all m3ua ASs\n" "Display all SUA ASs\n") { - struct osmo_ss7_instance *inst = g_s7i; + struct osmo_ss7_instance *inst; struct osmo_ss7_as *as; const char *filter = NULL; + int id = 0; if (argc) filter = argv[0]; + + if (argc > 1) + id = atoi(argv[1]); + inst = osmo_ss7_instance_find(id); + if (!inst) { + vty_out(vty, "No SS7 instance %d found%s", id, VTY_NEWLINE); + return CMD_WARNING; + } vty_out(vty, " Routing Routing Key Cic Cic%s", VTY_NEWLINE); vty_out(vty, "AS Name State Context Dpc Si Opc Ssn Min Max%s", VTY_NEWLINE); @@ -889,20 +859,88 @@ return CMD_SUCCESS; } -int osmo_ss7_vty_go_parent(struct vty *vty) +static void write_one_cs7(struct vty *vty, struct osmo_ss7_instance *inst) { struct osmo_ss7_asp *asp; + struct osmo_ss7_as *as; + struct osmo_ss7_route_table *rtable; + struct osmo_xua_server *oxs; + + vty_out(vty, "cs7 instance %u%s", inst->cfg.id, VTY_NEWLINE); + if (inst->cfg.network_indicator) + vty_out(vty, " network-indicator %s%s", + get_value_string(ss7_network_indicator_vals, + inst->cfg.network_indicator), + VTY_NEWLINE); + + if (inst->cfg.pc_fmt.component_len[0] != 3 || + inst->cfg.pc_fmt.component_len[1] != 8 || + inst->cfg.pc_fmt.component_len[2] != 3) { + vty_out(vty, " point-code format %u", + inst->cfg.pc_fmt.component_len[0]); + if (inst->cfg.pc_fmt.component_len[1]) + vty_out(vty, " %u", inst->cfg.pc_fmt.component_len[1]); + if (inst->cfg.pc_fmt.component_len[2]) + vty_out(vty, " %u", inst->cfg.pc_fmt.component_len[2]); + vty_out(vty, "%s", VTY_NEWLINE); + } + + if (inst->cfg.pc_fmt.delimiter != '.') + vty_out(vty, " point-code delimiter dash%s", VTY_NEWLINE); + + if (inst->cfg.primary_pc) + vty_out(vty, " point-code %s%s", + osmo_ss7_pointcode_print(inst, inst->cfg.primary_pc), + VTY_NEWLINE); + + /* first dump ASPs, as ASs reference them */ + llist_for_each_entry(asp, &inst->asp_list, list) + write_one_asp(vty, asp); + + /* then dump ASPs, as routes reference them */ + llist_for_each_entry(as, &inst->as_list, list) + write_one_as(vty, as); + + /* now dump routes, as their target ASs exist */ + llist_for_each_entry(rtable, &inst->rtable_list, list) + write_one_rtable(vty, rtable); + + llist_for_each_entry(oxs, &osmo_ss7_xua_servers, list) + write_one_sua(vty, oxs); +} + + +int osmo_ss7_vty_go_parent(struct vty *vty) +{ + struct osmo_ss7_as *as; + struct osmo_ss7_asp *asp; + struct osmo_ss7_route_table *rtbl; + struct osmo_xua_server *oxs; switch (vty->node) { case L_CS7_ASP_NODE: asp = vty->index; osmo_ss7_asp_restart(asp); - vty->node = CONFIG_NODE; + vty->node = L_CS7_NODE; + vty->index = asp->inst; break; case L_CS7_RTABLE_NODE: + rtbl = vty->index; + vty->node = L_CS7_NODE; + vty->index = rtbl->inst; + break; + case L_CS7_AS_NODE: + as = vty->index; + vty->node = L_CS7_NODE; + vty->index = as->inst; + break; case L_CS7_SUA_NODE: case L_CS7_M3UA_NODE: - case L_CS7_AS_NODE: + oxs = vty->index; + vty->node = L_CS7_NODE; + vty->index = oxs->inst; + break; + case L_CS7_NODE: default: vty->node = CONFIG_NODE; break; @@ -913,6 +951,7 @@ int osmo_ss7_is_config_node(struct vty *vty, int node) { switch (node) { + case L_CS7_NODE: case L_CS7_ASP_NODE: case L_CS7_RTABLE_NODE: case L_CS7_SUA_NODE: @@ -924,50 +963,35 @@ } } -int osmo_ss7_vty_init(void) +static void vty_init_shared(void) { - install_element(CONFIG_NODE, &cs7_net_ind_cmd); - install_element(CONFIG_NODE, &cs7_point_code_cmd); - install_element(CONFIG_NODE, &cs7_pc_format_cmd); - install_element(CONFIG_NODE, &cs7_pc_format_def_cmd); - install_element(CONFIG_NODE, &cs7_pc_delimiter_cmd); + /* the mother of all VTY config nodes */ + install_element(CONFIG_NODE, &cs7_instance_cmd); - install_node(&rtable_node, config_write_rtable); - vty_install_default(L_CS7_RTABLE_NODE); - install_element_ve(&show_cs7_route_cmd); - install_element(CONFIG_NODE, &cs7_route_table_cmd); - install_element(L_CS7_RTABLE_NODE, &cfg_description_cmd); - install_element(L_CS7_RTABLE_NODE, &cs7_rt_upd_cmd); - install_element(L_CS7_RTABLE_NODE, &cs7_rt_rem_cmd); - - install_node(&sua_node, config_write_sua); - vty_install_default(L_CS7_SUA_NODE); - install_element(CONFIG_NODE, &cs7_sua_cmd); - install_element(CONFIG_NODE, &no_cs7_sua_cmd); - install_element(L_CS7_SUA_NODE, &sua_local_ip_cmd); - - install_node(&m3ua_node, config_write_m3ua); - vty_install_default(L_CS7_M3UA_NODE); - install_element(CONFIG_NODE, &cs7_m3ua_cmd); - install_element(CONFIG_NODE, &no_cs7_m3ua_cmd); - install_element(L_CS7_M3UA_NODE, &m3ua_local_ip_cmd); + install_node(&cs7_node, config_write_cs7); + vty_install_default(L_CS7_NODE); + install_element(L_CS7_NODE, &cs7_net_ind_cmd); + install_element(L_CS7_NODE, &cs7_point_code_cmd); + install_element(L_CS7_NODE, &cs7_pc_format_cmd); + install_element(L_CS7_NODE, &cs7_pc_format_def_cmd); + install_element(L_CS7_NODE, &cs7_pc_delimiter_cmd); install_node(&asp_node, NULL); vty_install_default(L_CS7_ASP_NODE); install_element_ve(&show_cs7_asp_cmd); - install_element(CONFIG_NODE, &cs7_asp_cmd); - install_element(CONFIG_NODE, &no_cs7_asp_cmd); + install_element(L_CS7_NODE, &cs7_asp_cmd); + install_element(L_CS7_NODE, &no_cs7_asp_cmd); install_element(L_CS7_ASP_NODE, &cfg_description_cmd); install_element(L_CS7_ASP_NODE, &asp_remote_ip_cmd); install_element(L_CS7_ASP_NODE, &asp_qos_class_cmd); install_element(L_CS7_ASP_NODE, &asp_block_cmd); install_element(L_CS7_ASP_NODE, &asp_shutdown_cmd); - install_node(&as_node, config_write_as); + install_node(&as_node, NULL); vty_install_default(L_CS7_AS_NODE); install_element_ve(&show_cs7_as_cmd); - install_element(CONFIG_NODE, &cs7_as_cmd); - install_element(CONFIG_NODE, &no_cs7_as_cmd); + install_element(L_CS7_NODE, &cs7_as_cmd); + install_element(L_CS7_NODE, &no_cs7_as_cmd); install_element(L_CS7_AS_NODE, &cfg_description_cmd); install_element(L_CS7_AS_NODE, &as_asp_cmd); install_element(L_CS7_AS_NODE, &as_no_asp_cmd); @@ -975,6 +999,39 @@ install_element(L_CS7_AS_NODE, &as_recov_tout_cmd); install_element(L_CS7_AS_NODE, &as_qos_class_cmd); install_element(L_CS7_AS_NODE, &as_rout_key_cmd); - - return 0; } + +void osmo_ss7_vty_init_asp(void) +{ + vty_init_shared(); +} + +void osmo_ss7_vty_init_sg(void) +{ + vty_init_shared(); + + install_node(&rtable_node, NULL); + vty_install_default(L_CS7_RTABLE_NODE); + install_element_ve(&show_cs7_route_cmd); + install_element(L_CS7_NODE, &cs7_route_table_cmd); + install_element(L_CS7_RTABLE_NODE, &cfg_description_cmd); + install_element(L_CS7_RTABLE_NODE, &cs7_rt_upd_cmd); + install_element(L_CS7_RTABLE_NODE, &cs7_rt_rem_cmd); + + install_node(&sua_node, NULL); + vty_install_default(L_CS7_SUA_NODE); + install_element(L_CS7_NODE, &cs7_sua_cmd); + install_element(L_CS7_NODE, &no_cs7_sua_cmd); + install_element(L_CS7_SUA_NODE, &sua_local_ip_cmd); + + install_node(&m3ua_node, NULL); + vty_install_default(L_CS7_M3UA_NODE); + install_element(L_CS7_NODE, &cs7_m3ua_cmd); + install_element(L_CS7_NODE, &no_cs7_m3ua_cmd); + install_element(L_CS7_M3UA_NODE, &m3ua_local_ip_cmd); +} + +void osmo_ss7_set_vty_alloc_ctx(void *ctx) +{ + g_ctx = ctx; +}; diff --git a/stp/stp_main.c b/stp/stp_main.c index 029c0b2..24e2230 100644 --- a/stp/stp_main.c +++ b/stp/stp_main.c @@ -40,8 +40,6 @@ #include "internal.h" -struct osmo_ss7_instance *g_s7i; - static const struct log_info_cat log_info_cat[] = { }; @@ -78,9 +76,7 @@ osmo_ss7_init(); osmo_fsm_log_addr(false); vty_init(&vty_info); - osmo_ss7_vty_init(); - - g_s7i = osmo_ss7_instance_find_or_create(NULL, 0); + osmo_ss7_vty_init_sg(); rc = vty_read_config_file(config_file, NULL); if (rc < 0) { -- To view, visit https://gerrit.osmocom.org/2328 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I30966fbf2e143318cd9127eb8c17cccb24407106 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Fri Apr 14 12:54:16 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 14 Apr 2017 12:54:16 +0000 Subject: [PATCH] libosmo-sccp[master]: osmo_ss7_vty: Merge the SUA and M3UA VTY nodes Message-ID: Review at https://gerrit.osmocom.org/2329 osmo_ss7_vty: Merge the SUA and M3UA VTY nodes The xUA servers have pretty much everything in common, there's no point in introducing a separate VTY note for each xUA flavor. Change-Id: I5b842b7f10d94957398cf0c0406c440c495a0bdc --- M stp/internal.h M stp/osmo_ss7_vty.c 2 files changed, 41 insertions(+), 106 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/29/2329/1 diff --git a/stp/internal.h b/stp/internal.h index 31d95ba..cbd6bac 100644 --- a/stp/internal.h +++ b/stp/internal.h @@ -6,8 +6,7 @@ L_CS7_NODE = _LAST_OSMOVTY_NODE + 1, L_CS7_AS_NODE, L_CS7_ASP_NODE, - L_CS7_SUA_NODE, - L_CS7_M3UA_NODE, + L_CS7_XUA_NODE, L_CS7_RTABLE_NODE, }; diff --git a/stp/osmo_ss7_vty.c b/stp/osmo_ss7_vty.c index 29693a8..fe7bc41 100644 --- a/stp/osmo_ss7_vty.c +++ b/stp/osmo_ss7_vty.c @@ -328,58 +328,67 @@ } /*********************************************************************** - * SUA Configuration (SG) + * xUA Listener Configuration (SG) ***********************************************************************/ -static struct cmd_node sua_node = { - L_CS7_SUA_NODE, - "%s(config-cs7-sua)# ", +static enum osmo_ss7_asp_protocol parse_asp_proto(const char *protocol) +{ + return get_string_value(osmo_ss7_asp_protocol_vals, protocol); +} + +static struct cmd_node xua_node = { + L_CS7_XUA_NODE, + "%s(config-cs7-listen)# ", 1, }; -DEFUN(cs7_sua, cs7_sua_cmd, - "sua <0-65534>", - "Configure/Enable SUA\n" - "SCTP Port number for SUA\n") +#define XUA_STR "SCCP User Adaptation\n" "MTP3 User Adaptation\n" + +DEFUN(cs7_xua, cs7_xua_cmd, + "listen (sua|m3ua) <0-65534>", + "Configure/Enable xUA Listener\n" + XUA_STR "SCTP Port number\n") { struct osmo_ss7_instance *inst = vty->index; struct osmo_xua_server *xs; - uint16_t port = atoi(argv[0]); + enum osmo_ss7_asp_protocol proto = parse_asp_proto(argv[0]); + uint16_t port = atoi(argv[1]); - xs = osmo_ss7_xua_server_find(inst, OSMO_SS7_ASP_PROT_SUA, port); + xs = osmo_ss7_xua_server_find(inst, proto, port); if (!xs) { - xs = osmo_ss7_xua_server_create(inst, OSMO_SS7_ASP_PROT_SUA, port, NULL); + xs = osmo_ss7_xua_server_create(inst, proto, port, NULL); if (!xs) return CMD_SUCCESS; } - vty->node = L_CS7_SUA_NODE; + vty->node = L_CS7_XUA_NODE; vty->index = xs; return CMD_SUCCESS; } -DEFUN(no_cs7_sua, no_cs7_sua_cmd, - "no sua <0-65534>", - NO_STR "Disable SUA on given SCTP Port\n" - "SCTP Port number for SUA\n") +DEFUN(no_cs7_xua, no_cs7_xua_cmd, + "no listen (sua|m3ua) <0-65534>", + NO_STR "Disable xUA Listener on given SCTP Port\n" + XUA_STR "SCTP Port number\n") { struct osmo_ss7_instance *inst = vty->index; struct osmo_xua_server *xs; - uint16_t port = atoi(argv[0]); + enum osmo_ss7_asp_protocol proto = parse_asp_proto(argv[0]); + uint16_t port = atoi(argv[1]); - xs = osmo_ss7_xua_server_find(inst, OSMO_SS7_ASP_PROT_SUA, port); + xs = osmo_ss7_xua_server_find(inst, proto, port); if (!xs) { - vty_out(vty, "No SUA server for port %u found%s", port, VTY_NEWLINE); + vty_out(vty, "No xUA server for port %u found%s", port, VTY_NEWLINE); return CMD_WARNING; } osmo_ss7_xua_server_destroy(xs); return CMD_SUCCESS; } -DEFUN(sua_local_ip, sua_local_ip_cmd, +DEFUN(xua_local_ip, xua_local_ip_cmd, "local-ip A.B.C.D", - "Configure the Local IP Address for SUA\n" - "IP Address to use for SUA\n") + "Configure the Local IP Address for xUA\n" + "IP Address to use for XUA\n") { struct osmo_xua_server *xs = vty->index; @@ -387,12 +396,7 @@ return CMD_SUCCESS; } -enum osmo_ss7_asp_protocol parse_asp_proto(const char *protocol) -{ - return get_string_value(osmo_ss7_asp_protocol_vals, protocol); -} - -static void write_one_sua(struct vty *vty, struct osmo_xua_server *xs) +static void write_one_xua(struct vty *vty, struct osmo_xua_server *xs) { vty_out(vty, " %s %u%s", get_value_string(osmo_ss7_asp_protocol_vals, xs->cfg.proto), @@ -400,66 +404,6 @@ vty_out(vty, " local-ip %s%s", xs->cfg.local.host, VTY_NEWLINE); } - -/*********************************************************************** - * M3UA Configuration (SG) - ***********************************************************************/ - -static struct cmd_node m3ua_node = { - L_CS7_M3UA_NODE, - "%s(config-cs7-m3ua)# ", - 1, -}; - -DEFUN(cs7_m3ua, cs7_m3ua_cmd, - "m3ua <0-65534>", - "Configure/Enable M3UA\n" - "SCTP Port number for M3UA\n") -{ - struct osmo_ss7_instance *inst = vty->index; - struct osmo_xua_server *xs; - uint16_t port = atoi(argv[0]); - - xs = osmo_ss7_xua_server_find(inst, OSMO_SS7_ASP_PROT_M3UA, port); - if (!xs) { - xs = osmo_ss7_xua_server_create(inst, OSMO_SS7_ASP_PROT_M3UA, port, NULL); - if (!xs) - return CMD_SUCCESS; - } - - vty->node = L_CS7_M3UA_NODE; - vty->index = xs; - return CMD_SUCCESS; -} - -DEFUN(no_cs7_m3ua, no_cs7_m3ua_cmd, - "no m3ua <0-65534>", - NO_STR "Disable M3UA on given SCTP Port\n" - "SCTP Port number for M3UA\n") -{ - struct osmo_ss7_instance *inst = vty->index; - struct osmo_xua_server *xs; - uint16_t port = atoi(argv[0]); - - xs = osmo_ss7_xua_server_find(inst, OSMO_SS7_ASP_PROT_M3UA, port); - if (!xs) { - vty_out(vty, "No M3UA server for port %u found%s", port, VTY_NEWLINE); - return CMD_WARNING; - } - osmo_ss7_xua_server_destroy(xs); - return CMD_SUCCESS; -} - -DEFUN(m3ua_local_ip, m3ua_local_ip_cmd, - "local-ip A.B.C.D", - "Configure the Local IP Address for M3UA\n" - "IP Address to use for M3UA\n") -{ - struct osmo_xua_server *xs = vty->index; - - osmo_ss7_xua_server_set_local_host(xs, argv[0]); - return CMD_SUCCESS; -} /*********************************************************************** * Application Server Process @@ -906,7 +850,7 @@ write_one_rtable(vty, rtable); llist_for_each_entry(oxs, &osmo_ss7_xua_servers, list) - write_one_sua(vty, oxs); + write_one_xua(vty, oxs); } @@ -934,8 +878,7 @@ vty->node = L_CS7_NODE; vty->index = as->inst; break; - case L_CS7_SUA_NODE: - case L_CS7_M3UA_NODE: + case L_CS7_XUA_NODE: oxs = vty->index; vty->node = L_CS7_NODE; vty->index = oxs->inst; @@ -954,8 +897,7 @@ case L_CS7_NODE: case L_CS7_ASP_NODE: case L_CS7_RTABLE_NODE: - case L_CS7_SUA_NODE: - case L_CS7_M3UA_NODE: + case L_CS7_XUA_NODE: case L_CS7_AS_NODE: return 1; default: @@ -1018,17 +960,11 @@ install_element(L_CS7_RTABLE_NODE, &cs7_rt_upd_cmd); install_element(L_CS7_RTABLE_NODE, &cs7_rt_rem_cmd); - install_node(&sua_node, NULL); - vty_install_default(L_CS7_SUA_NODE); - install_element(L_CS7_NODE, &cs7_sua_cmd); - install_element(L_CS7_NODE, &no_cs7_sua_cmd); - install_element(L_CS7_SUA_NODE, &sua_local_ip_cmd); - - install_node(&m3ua_node, NULL); - vty_install_default(L_CS7_M3UA_NODE); - install_element(L_CS7_NODE, &cs7_m3ua_cmd); - install_element(L_CS7_NODE, &no_cs7_m3ua_cmd); - install_element(L_CS7_M3UA_NODE, &m3ua_local_ip_cmd); + install_node(&xua_node, NULL); + vty_install_default(L_CS7_XUA_NODE); + install_element(L_CS7_NODE, &cs7_xua_cmd); + install_element(L_CS7_NODE, &no_cs7_xua_cmd); + install_element(L_CS7_XUA_NODE, &xua_local_ip_cmd); } void osmo_ss7_set_vty_alloc_ctx(void *ctx) -- To view, visit https://gerrit.osmocom.org/2329 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I5b842b7f10d94957398cf0c0406c440c495a0bdc Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Fri Apr 14 12:54:16 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 14 Apr 2017 12:54:16 +0000 Subject: [PATCH] libosmo-sccp[master]: move osmo_ss7_vty.c [back] into libosmo-sigtran Message-ID: Review at https://gerrit.osmocom.org/2330 move osmo_ss7_vty.c [back] into libosmo-sigtran Now that the VTY has no static dependencies like a global ss7_instance anymore, we can move it back to libosmo-sigtran and make use of it in other programs outside osmo-stp. This requires Change-Id I184a7e3187b48c15c71bf773f86e188fe1daad15 in libosmocore Change-Id: I2e549f1eadbfb28dde79f620b130cbf022312c42 --- M include/osmocom/sigtran/osmo_ss7.h M src/Makefile.am R src/osmo_ss7_vty.c M stp/Makefile.am D stp/internal.h M stp/stp_main.c 6 files changed, 11 insertions(+), 25 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/30/2330/1 diff --git a/include/osmocom/sigtran/osmo_ss7.h b/include/osmocom/sigtran/osmo_ss7.h index 1d82669..24f83e9 100644 --- a/include/osmocom/sigtran/osmo_ss7.h +++ b/include/osmocom/sigtran/osmo_ss7.h @@ -437,3 +437,11 @@ enum osmo_ss7_as_traffic_mode osmo_ss7_tmode_from_xua(uint32_t in); int osmo_ss7_tmode_to_xua(enum osmo_ss7_as_traffic_mode tmod); + +/* VTY related */ +struct vty; +void osmo_ss7_set_vty_alloc_ctx(void *ctx); +void osmo_ss7_vty_init_asp(void); +void osmo_ss7_vty_init_sg(void); +int osmo_ss7_vty_go_parent(struct vty *vty); +int osmo_ss7_is_config_node(struct vty *vty, int node); diff --git a/src/Makefile.am b/src/Makefile.am index f9b87b0..8e52792 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -29,6 +29,7 @@ libosmo_sigtran_la_SOURCES = sccp_sap.c sua.c m3ua.c xua_msg.c sccp_helpers.c \ sccp2sua.c sccp_scrc.c sccp_sclc.c sccp_scoc.c \ sccp_user.c xua_rkm.c xua_default_lm_fsm.c \ - osmo_ss7.c osmo_ss7_hmrt.c xua_asp_fsm.c xua_as_fsm.c + osmo_ss7.c osmo_ss7_hmrt.c xua_asp_fsm.c xua_as_fsm.c \ + osmo_ss7_vty.c libosmo_sigtran_la_LDFLAGS = -version-info $(LIBVERSION) -no-undefined -export-symbols-regex '^osmo_' libosmo_sigtran_la_LIBADD = $(LIBOSMOCORE_LIBS) $(LIBOSMONETIF_LIBS) $(LIBSCTP_LIBS) diff --git a/stp/osmo_ss7_vty.c b/src/osmo_ss7_vty.c similarity index 99% rename from stp/osmo_ss7_vty.c rename to src/osmo_ss7_vty.c index fe7bc41..59c4008 100644 --- a/stp/osmo_ss7_vty.c +++ b/src/osmo_ss7_vty.c @@ -35,8 +35,6 @@ #include #include -#include "internal.h" - #define CS7_STR "ITU-T Signaling System 7\n" #define PC_STR "Point Code\n" diff --git a/stp/Makefile.am b/stp/Makefile.am index 81aa11c..ae37487 100644 --- a/stp/Makefile.am +++ b/stp/Makefile.am @@ -2,10 +2,8 @@ AM_CFLAGS=-Wall -g $(LIBOSMOCORE_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(LIBOSMONETIF_CFLAGS) $(COVERAGE_FLAGS) AM_LDFLAGS=$(COVERAGE_LDFLAGS) -EXTRA_DIST = internal.h - bin_PROGRAMS = osmo-stp -osmo_stp_SOURCES = stp_main.c osmo_ss7_vty.c +osmo_stp_SOURCES = stp_main.c osmo_stp_LDADD = $(top_builddir)/src/libosmo-sigtran.la \ $(LIBOSMOCORE_LIBS) $(LIBOSMOVTY_LIBS) diff --git a/stp/internal.h b/stp/internal.h deleted file mode 100644 index cbd6bac..0000000 --- a/stp/internal.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -#include - -enum stp_vty_node { - L_CS7_NODE = _LAST_OSMOVTY_NODE + 1, - L_CS7_AS_NODE, - L_CS7_ASP_NODE, - L_CS7_XUA_NODE, - L_CS7_RTABLE_NODE, -}; - -void osmo_ss7_set_vty_alloc_ctx(void *ctx); -void osmo_ss7_vty_init_asp(void); -void osmo_ss7_vty_init_sg(void); -int osmo_ss7_vty_go_parent(struct vty *vty); -int osmo_ss7_is_config_node(struct vty *vty, int node); diff --git a/stp/stp_main.c b/stp/stp_main.c index 24e2230..267806b 100644 --- a/stp/stp_main.c +++ b/stp/stp_main.c @@ -38,8 +38,6 @@ #include #include -#include "internal.h" - static const struct log_info_cat log_info_cat[] = { }; -- To view, visit https://gerrit.osmocom.org/2330 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I2e549f1eadbfb28dde79f620b130cbf022312c42 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Fri Apr 14 12:54:16 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 14 Apr 2017 12:54:16 +0000 Subject: [PATCH] libosmo-sccp[master]: sua: Reject DATA messages on SCTP stream 0 Message-ID: Review at https://gerrit.osmocom.org/2331 sua: Reject DATA messages on SCTP stream 0 RFC3868 states clearly that DATA messages MUST be sent o a stream other than stream '0'. So at the receiver side, we should validate that (just like we do in M3UA. Change-Id: I0784e221ef791557a69be04f7d246de059ea84c8 --- M src/sua.c 1 file changed, 8 insertions(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/31/2331/1 diff --git a/src/sua.c b/src/sua.c index 881191e..3bff855 100644 --- a/src/sua.c +++ b/src/sua.c @@ -630,15 +630,22 @@ goto out; } - /* TODO: check for SCTP Strema ID */ /* TODO: check if any AS configured in ASP */ /* TODO: check for valid routing context */ switch (xua->hdr.msg_class) { case SUA_MSGC_CL: + if (msgb_sctp_stream(msg) == 0) { + rc = SUA_ERR_INVAL_STREAM_ID; + break; + } rc = sua_rx_cl(asp, xua); break; case SUA_MSGC_CO: + if (msgb_sctp_stream(msg) == 0) { + rc = SUA_ERR_INVAL_STREAM_ID; + break; + } rc = sua_rx_co(asp, xua); break; case SUA_MSGC_ASPSM: -- To view, visit https://gerrit.osmocom.org/2331 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I0784e221ef791557a69be04f7d246de059ea84c8 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Fri Apr 14 12:57:27 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 14 Apr 2017 12:57:27 +0000 Subject: libosmo-sccp[master]: move osmo_ss7_vty.c [back] into libosmo-sigtran In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2330 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I2e549f1eadbfb28dde79f620b130cbf022312c42 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Apr 14 12:59:25 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 14 Apr 2017 12:59:25 +0000 Subject: libosmo-sccp[master]: STP: re-structure VTY interface; introduce 'cs7 instance' node In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 Verified+1 this doesn't build anymore with recent libosmocore, it's expected. -- To view, visit https://gerrit.osmocom.org/2328 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I30966fbf2e143318cd9127eb8c17cccb24407106 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Apr 14 12:59:29 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 14 Apr 2017 12:59:29 +0000 Subject: [MERGED] libosmo-sccp[master]: STP: re-structure VTY interface; introduce 'cs7 instance' node In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: STP: re-structure VTY interface; introduce 'cs7 instance' node ...................................................................... STP: re-structure VTY interface; introduce 'cs7 instance' node This properly integrates the concept of multiple SS7 instances (each with their own point code format, address indicator, ...) into the VTY. At the same time, this also removes the stp-global "g_s7i" instance that existed so far, moving the VTY code more into the direction of also being able to be used outside the STP - which is underlined by splitting the vty commands between those generally useful, and those useful only for a STP or only for a simpla ASP (client). Change-Id: I30966fbf2e143318cd9127eb8c17cccb24407106 --- M include/osmocom/sigtran/osmo_ss7.h M src/osmo_ss7.c M stp/internal.h M stp/osmo_ss7_vty.c M stp/stp_main.c 5 files changed, 257 insertions(+), 203 deletions(-) Approvals: Harald Welte: Looks good to me, approved; Verified diff --git a/include/osmocom/sigtran/osmo_ss7.h b/include/osmocom/sigtran/osmo_ss7.h index 49a8ca5..1d82669 100644 --- a/include/osmocom/sigtran/osmo_ss7.h +++ b/include/osmocom/sigtran/osmo_ss7.h @@ -9,6 +9,7 @@ #include #include +extern struct llist_head osmo_ss7_instances; extern struct llist_head osmo_ss7_xua_servers; struct osmo_ss7_instance; diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index d864916..27e56af 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -52,7 +52,7 @@ static bool ss7_initialized = false; -static LLIST_HEAD(ss7_instances); +LLIST_HEAD(osmo_ss7_instances); LLIST_HEAD(osmo_ss7_xua_servers); static int32_t next_rctx = 1; static int32_t next_l_rk_id = 1; @@ -296,7 +296,7 @@ OSMO_ASSERT(ss7_initialized); struct osmo_ss7_instance *inst; - llist_for_each_entry(inst, &ss7_instances, list) { + llist_for_each_entry(inst, &osmo_ss7_instances, list) { if (inst->cfg.id == id) return inst; } @@ -335,7 +335,7 @@ inst->cfg.pc_fmt.component_len[1] = 8; inst->cfg.pc_fmt.component_len[2] = 3; - llist_add(&inst->list, &ss7_instances); + llist_add(&inst->list, &osmo_ss7_instances); return inst; } @@ -993,7 +993,7 @@ /* check all instances for any ASP definition matching the * address combination of local/remote ip/port */ - llist_for_each_entry(inst, &ss7_instances, list) { + llist_for_each_entry(inst, &osmo_ss7_instances, list) { struct osmo_ss7_asp *asp; llist_for_each_entry(asp, &inst->asp_list, list) { if (asp->cfg.local.port == local_port && diff --git a/stp/internal.h b/stp/internal.h index 0a434cc..31d95ba 100644 --- a/stp/internal.h +++ b/stp/internal.h @@ -3,16 +3,16 @@ #include enum stp_vty_node { - L_CS7_AS_NODE = _LAST_OSMOVTY_NODE + 1, + L_CS7_NODE = _LAST_OSMOVTY_NODE + 1, + L_CS7_AS_NODE, L_CS7_ASP_NODE, L_CS7_SUA_NODE, L_CS7_M3UA_NODE, L_CS7_RTABLE_NODE, }; -int osmo_ss7_vty_init(void); +void osmo_ss7_set_vty_alloc_ctx(void *ctx); +void osmo_ss7_vty_init_asp(void); +void osmo_ss7_vty_init_sg(void); int osmo_ss7_vty_go_parent(struct vty *vty); int osmo_ss7_is_config_node(struct vty *vty, int node); - -extern struct osmo_ss7_instance *g_s7i; - diff --git a/stp/osmo_ss7_vty.c b/stp/osmo_ss7_vty.c index 014fa03..29693a8 100644 --- a/stp/osmo_ss7_vty.c +++ b/stp/osmo_ss7_vty.c @@ -44,6 +44,35 @@ * Core CS7 Configuration ***********************************************************************/ +static void *g_ctx; + +static struct cmd_node cs7_node = { + L_CS7_NODE, + "%s(config-cs7)# ", + 1, +}; + +DEFUN(cs7_instance, cs7_instance_cmd, + "cs7 instance <0-15>", + CS7_STR "Configure a SS7 Instance\n" + "Number of the instance\n") +{ + int id = atoi(argv[0]); + struct osmo_ss7_instance *inst; + + inst = osmo_ss7_instance_find_or_create(g_ctx, id); + if (!inst) { + vty_out(vty, "Unable to create SS7 Instance %d%s", id, VTY_NEWLINE); + return CMD_WARNING; + } + + vty->node = L_CS7_NODE; + vty->index = inst; + vty->index_sub = &inst->cfg.description; + + return CMD_SUCCESS; +} + static const struct value_string ss7_network_indicator_vals[] = { { 0, "international" }, { 1, "spare" }, @@ -54,14 +83,14 @@ /* cs7 network-indicator */ DEFUN(cs7_net_ind, cs7_net_ind_cmd, - "cs7 network-indicator (international | national | reserved | spare)", - CS7_STR "Configure the Network Indicator\n" + "network-indicator (international | national | reserved | spare)", + "Configure the Network Indicator\n" "International Network\n" "National Network\n" "Reserved Network\n" "Spare Network\n") { - struct osmo_ss7_instance *inst = g_s7i; + struct osmo_ss7_instance *inst = vty->index; int ni = get_string_value(ss7_network_indicator_vals, argv[0]); inst->cfg.network_indicator = ni; @@ -70,13 +99,13 @@ /* TODO: cs7 point-code format */ DEFUN(cs7_pc_format, cs7_pc_format_cmd, - "cs7 point-code format <1-24> [<1-23>] [<1-22>]", - CS7_STR PC_STR "Configure Point Code Format\n" + "point-code format <1-24> [<1-23>] [<1-22>]", + PC_STR "Configure Point Code Format\n" "Length of first PC component\n" "Length of second PC component\n" "Length of third PC component\n") { - struct osmo_ss7_instance *inst = g_s7i; + struct osmo_ss7_instance *inst = vty->index; int argind = 0; inst->cfg.pc_fmt.component_len[0] = atoi(argv[argind++]); @@ -95,11 +124,11 @@ } DEFUN(cs7_pc_format_def, cs7_pc_format_def_cmd, - "cs7 point-code format default", - CS7_STR PC_STR "Configure Point Code Format\n" + "point-code format default", + PC_STR "Configure Point Code Format\n" "Default Point Code Format (3.8.3)\n") { - struct osmo_ss7_instance *inst = g_s7i; + struct osmo_ss7_instance *inst = vty->index; inst->cfg.pc_fmt.component_len[0] = 3; inst->cfg.pc_fmt.component_len[1] = 8; inst->cfg.pc_fmt.component_len[2] = 3; @@ -109,12 +138,12 @@ /* cs7 point-code delimiter */ DEFUN(cs7_pc_delimiter, cs7_pc_delimiter_cmd, - "cs7 point-code delimiter (default|dash)", - CS7_STR PC_STR "Configure Point Code Delimiter\n" + "point-code delimiter (default|dash)", + PC_STR "Configure Point Code Delimiter\n" "Use dot as delimiter\n" "User dash as delimiter\n") { - struct osmo_ss7_instance *inst = g_s7i; + struct osmo_ss7_instance *inst = vty->index; if (!strcmp(argv[0], "dash")) inst->cfg.pc_fmt.delimiter = '-'; @@ -125,11 +154,11 @@ } DEFUN(cs7_point_code, cs7_point_code_cmd, - "cs7 point-code POINT_CODE", - CS7_STR "Configure the local Point Code\n" + "point-code POINT_CODE", + "Configure the local Point Code\n" "Point Code\n") { - struct osmo_ss7_instance *inst = g_s7i; + struct osmo_ss7_instance *inst = vty->index; uint32_t pc = osmo_ss7_pointcode_parse(inst, argv[0]); inst->cfg.primary_pc = pc; @@ -138,39 +167,16 @@ /* TODO: cs7 secondary-pc */ /* TODO: cs7 capability-pc */ +static void write_one_cs7(struct vty *vty, struct osmo_ss7_instance *inst); -static void write_one_ss7_inst(struct vty *vty, struct osmo_ss7_instance *inst) +static int config_write_cs7(struct vty *vty) { - if (inst->cfg.network_indicator) - vty_out(vty, "cs7 network-indicator %s%s", - get_value_string(ss7_network_indicator_vals, - inst->cfg.network_indicator), - VTY_NEWLINE); + struct osmo_ss7_instance *inst; - if (inst->cfg.pc_fmt.component_len[0] != 3 || - inst->cfg.pc_fmt.component_len[1] != 8 || - inst->cfg.pc_fmt.component_len[2] != 3) { - vty_out(vty, "cs7 point-code format %u", - inst->cfg.pc_fmt.component_len[0]); - if (inst->cfg.pc_fmt.component_len[1]) - vty_out(vty, " %u", inst->cfg.pc_fmt.component_len[1]); - if (inst->cfg.pc_fmt.component_len[2]) - vty_out(vty, " %u", inst->cfg.pc_fmt.component_len[2]); - vty_out(vty, "%s", VTY_NEWLINE); - } + llist_for_each_entry(inst, &osmo_ss7_instances, list) + write_one_cs7(vty, inst); - if (inst->cfg.pc_fmt.delimiter != '.') - vty_out(vty, "cs7 point-code delimiter dash%s", VTY_NEWLINE); - - if (inst->cfg.primary_pc) - vty_out(vty, "cs7 point-code %s%s", - osmo_ss7_pointcode_print(inst, inst->cfg.primary_pc), - VTY_NEWLINE); -} - -static void config_write_cs7(struct vty *vty) -{ - write_one_ss7_inst(vty, g_s7i); + return 0; } /*********************************************************************** @@ -184,11 +190,11 @@ }; DEFUN(cs7_route_table, cs7_route_table_cmd, - "cs7 route-table system", - CS7_STR "Specify the name of the route table\n" + "route-table system", + "Specify the name of the route table\n" "Name of the route table\n") { - struct osmo_ss7_instance *inst = g_s7i; + struct osmo_ss7_instance *inst = vty->index; struct osmo_ss7_route_table *rtable; rtable = inst->rtable_system; @@ -269,11 +275,11 @@ { struct osmo_ss7_route *rt; - vty_out(vty, "cs7 route-table %s%s", rtable->cfg.name, VTY_NEWLINE); + vty_out(vty, " route-table %s%s", rtable->cfg.name, VTY_NEWLINE); if (rtable->cfg.description) - vty_out(vty, " description %s%s", rtable->cfg.description, VTY_NEWLINE); + vty_out(vty, " description %s%s", rtable->cfg.description, VTY_NEWLINE); llist_for_each_entry(rt, &rtable->routes, list) { - vty_out(vty, " update route %s %s linkset %s", + vty_out(vty, " update route %s %s linkset %s", osmo_ss7_pointcode_print(rtable->inst, rt->cfg.pc), osmo_ss7_pointcode_print(rtable->inst, rt->cfg.mask), rt->cfg.linkset_name); @@ -283,17 +289,6 @@ vty_out(vty, " qos-class %u", rt->cfg.qos_class); vty_out(vty, "%s", VTY_NEWLINE); } -} - -static int config_write_rtable(struct vty *vty) -{ - struct osmo_ss7_instance *inst = g_s7i; - struct osmo_ss7_route_table *rtable; - - llist_for_each_entry(rtable, &inst->rtable_list, list) - write_one_rtable(vty, rtable); - - return 0; } static void vty_dump_rtable(struct vty *vty, struct osmo_ss7_route_table *rtbl) @@ -314,17 +309,26 @@ } DEFUN(show_cs7_route, show_cs7_route_cmd, - "show cs7 route", + "show cs7 route [instance <0-15>]", SHOW_STR CS7_STR "Routing Table\n") { - struct osmo_ss7_instance *inst = g_s7i; + int id = 0; + struct osmo_ss7_instance *inst; + + if (argc > 0) + id = atoi(argv[0]); + inst = osmo_ss7_instance_find(id); + if (!inst) { + vty_out(vty, "No SS7 instance %d found%s", id, VTY_NEWLINE); + return CMD_WARNING; + } vty_dump_rtable(vty, inst->rtable_system); return CMD_SUCCESS; } /*********************************************************************** - * SUA Configuration + * SUA Configuration (SG) ***********************************************************************/ static struct cmd_node sua_node = { @@ -334,12 +338,11 @@ }; DEFUN(cs7_sua, cs7_sua_cmd, - "cs7 sua <0-65534>", - CS7_STR + "sua <0-65534>", "Configure/Enable SUA\n" "SCTP Port number for SUA\n") { - struct osmo_ss7_instance *inst = g_s7i; + struct osmo_ss7_instance *inst = vty->index; struct osmo_xua_server *xs; uint16_t port = atoi(argv[0]); @@ -356,11 +359,11 @@ } DEFUN(no_cs7_sua, no_cs7_sua_cmd, - "no cs7 sua <0-65534>", - NO_STR CS7_STR "Disable SUA on given SCTP Port\n" + "no sua <0-65534>", + NO_STR "Disable SUA on given SCTP Port\n" "SCTP Port number for SUA\n") { - struct osmo_ss7_instance *inst = g_s7i; + struct osmo_ss7_instance *inst = vty->index; struct osmo_xua_server *xs; uint16_t port = atoi(argv[0]); @@ -391,25 +394,15 @@ static void write_one_sua(struct vty *vty, struct osmo_xua_server *xs) { - vty_out(vty, "cs7 %s %u%s", + vty_out(vty, " %s %u%s", get_value_string(osmo_ss7_asp_protocol_vals, xs->cfg.proto), xs->cfg.local.port, VTY_NEWLINE); - vty_out(vty, " local-ip %s%s", xs->cfg.local.host, VTY_NEWLINE); + vty_out(vty, " local-ip %s%s", xs->cfg.local.host, VTY_NEWLINE); } - -static int config_write_sua(struct vty *vty) -{ - struct osmo_xua_server *xs; - - llist_for_each_entry(xs, &osmo_ss7_xua_servers, list) - write_one_sua(vty, xs); - - return 0; -} /*********************************************************************** - * M3UA Configuration + * M3UA Configuration (SG) ***********************************************************************/ static struct cmd_node m3ua_node = { @@ -419,12 +412,11 @@ }; DEFUN(cs7_m3ua, cs7_m3ua_cmd, - "cs7 m3ua <0-65534>", - CS7_STR + "m3ua <0-65534>", "Configure/Enable M3UA\n" "SCTP Port number for M3UA\n") { - struct osmo_ss7_instance *inst = g_s7i; + struct osmo_ss7_instance *inst = vty->index; struct osmo_xua_server *xs; uint16_t port = atoi(argv[0]); @@ -441,11 +433,11 @@ } DEFUN(no_cs7_m3ua, no_cs7_m3ua_cmd, - "no cs7 m3ua <0-65534>", - NO_STR CS7_STR "Disable M3UA on given SCTP Port\n" + "no m3ua <0-65534>", + NO_STR "Disable M3UA on given SCTP Port\n" "SCTP Port number for M3UA\n") { - struct osmo_ss7_instance *inst = g_s7i; + struct osmo_ss7_instance *inst = vty->index; struct osmo_xua_server *xs; uint16_t port = atoi(argv[0]); @@ -469,12 +461,6 @@ return CMD_SUCCESS; } -static int config_write_m3ua(struct vty *vty) -{ - /* see config_write_sua */ - return 0; -} - /*********************************************************************** * Application Server Process ***********************************************************************/ @@ -486,8 +472,7 @@ }; DEFUN(cs7_asp, cs7_asp_cmd, - "cs7 asp NAME <0-65535> <0-65535> (m3ua|sua)", - CS7_STR + "asp NAME <0-65535> <0-65535> (m3ua|sua)", "Configure Application Server Process\n" "Name of ASP\n" "Remote SCTP port number\n" @@ -495,7 +480,7 @@ "M3UA Protocol\n" "SUA Protocol\n") { - struct osmo_ss7_instance *inst = g_s7i; + struct osmo_ss7_instance *inst = vty->index; const char *name = argv[0]; uint16_t remote_port = atoi(argv[1]); uint16_t local_port = atoi(argv[2]); @@ -521,11 +506,11 @@ } DEFUN(no_cs7_asp, no_cs7_asp_cmd, - "no cs7 asp NAME", - NO_STR CS7_STR "Disable Application Server Process\n" + "no asp NAME", + NO_STR "Disable Application Server Process\n" "Name of ASP\n") { - struct osmo_ss7_instance *inst = g_s7i; + struct osmo_ss7_instance *inst = vty->index; const char *name = argv[0]; struct osmo_ss7_asp *asp; @@ -577,11 +562,20 @@ } DEFUN(show_cs7_asp, show_cs7_asp_cmd, - "show cs7 asp", + "show cs7 asp [instance <0-15>]", SHOW_STR CS7_STR "Application Server Process (ASP)\n") { - struct osmo_ss7_instance *inst = g_s7i; + struct osmo_ss7_instance *inst; struct osmo_ss7_asp *asp; + int id = 0; + + if (argc > 0) + id = atoi(argv[0]); + inst = osmo_ss7_instance_find(id); + if (!inst) { + vty_out(vty, "No SS7 instance %d found%s", id, VTY_NEWLINE); + return CMD_WARNING; + } vty_out(vty, " Effect Primary%s", VTY_NEWLINE); vty_out(vty, "ASP Name AS Name State Type Rmt Port Remote IP Addr SCTP%s", VTY_NEWLINE); @@ -598,25 +592,14 @@ static void write_one_asp(struct vty *vty, struct osmo_ss7_asp *asp) { - vty_out(vty, "cs7 asp %s %u %u %s%s", + vty_out(vty, " asp %s %u %u %s%s", asp->cfg.name, asp->cfg.remote.port, asp->cfg.local.port, osmo_ss7_asp_protocol_name(asp->cfg.proto), VTY_NEWLINE); if (asp->cfg.description) - vty_out(vty, " description %s%s", asp->cfg.description, VTY_NEWLINE); - vty_out(vty, " remote-ip %s%s", asp->cfg.remote.host, VTY_NEWLINE); + vty_out(vty, " description %s%s", asp->cfg.description, VTY_NEWLINE); + vty_out(vty, " remote-ip %s%s", asp->cfg.remote.host, VTY_NEWLINE); if (asp->cfg.qos_class) - vty_out(vty, " qos-class %u%s", asp->cfg.qos_class, VTY_NEWLINE); -} - -static int config_write_asp(struct vty *vty) -{ - struct osmo_ss7_instance *inst = g_s7i; - struct osmo_ss7_asp *asp; - - llist_for_each_entry(asp, &inst->asp_list, list) - write_one_asp(vty, asp); - - return 0; + vty_out(vty, " qos-class %u%s", asp->cfg.qos_class, VTY_NEWLINE); } @@ -631,14 +614,13 @@ }; DEFUN(cs7_as, cs7_as_cmd, - "cs7 as NAME (m3ua|sua)", - CS7_STR + "as NAME (m3ua|sua)", "Configure an Application Server\n" "Name of the Application Server\n" "M3UA Application Server\n" "SUA Application Server\n") { - struct osmo_ss7_instance *inst = g_s7i; + struct osmo_ss7_instance *inst = vty->index; struct osmo_ss7_as *as; const char *name = argv[0]; enum osmo_ss7_asp_protocol protocol = parse_asp_proto(argv[1]); @@ -664,11 +646,11 @@ } DEFUN(no_cs7_as, no_cs7_as_cmd, - "no cs7 as NAME", - NO_STR CS7_STR "Disable Application Server\n" + "no as NAME", + NO_STR "Disable Application Server\n" "Name of AS\n") { - struct osmo_ss7_instance *inst = g_s7i; + struct osmo_ss7_instance *inst = vty->index; const char *name = argv[0]; struct osmo_ss7_as *as; @@ -805,27 +787,27 @@ struct osmo_ss7_routing_key *rkey; unsigned int i; - vty_out(vty, "cs7 as %s %s%s", as->cfg.name, + vty_out(vty, " as %s %s%s", as->cfg.name, osmo_ss7_asp_protocol_name(as->cfg.proto), VTY_NEWLINE); if (as->cfg.description) - vty_out(vty, " description %s%s", as->cfg.description, VTY_NEWLINE); + vty_out(vty, " description %s%s", as->cfg.description, VTY_NEWLINE); for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) { struct osmo_ss7_asp *asp = as->cfg.asps[i]; if (!asp) continue; - vty_out(vty, " asp %s%s", asp->cfg.name, VTY_NEWLINE); + vty_out(vty, " asp %s%s", asp->cfg.name, VTY_NEWLINE); } if (as->cfg.mode != OSMO_SS7_AS_TMOD_LOADSHARE) - vty_out(vty, " traffic-mode %s%s", + vty_out(vty, " traffic-mode %s%s", osmo_ss7_as_traffic_mode_name(as->cfg.mode), VTY_NEWLINE); if (as->cfg.recovery_timeout_msec != 2000) { - vty_out(vty, " recovery-timeout %u%s", + vty_out(vty, " recovery-timeout %u%s", as->cfg.recovery_timeout_msec, VTY_NEWLINE); } if (as->cfg.qos_class) - vty_out(vty, " qos-class %u%s", as->cfg.qos_class, VTY_NEWLINE); + vty_out(vty, " qos-class %u%s", as->cfg.qos_class, VTY_NEWLINE); rkey = &as->cfg.routing_key; - vty_out(vty, " routing-key %u %s", rkey->context, + vty_out(vty, " routing-key %u %s", rkey->context, osmo_ss7_pointcode_print(as->inst, rkey->pc)); if (rkey->si) vty_out(vty, " si %s", @@ -835,41 +817,29 @@ vty_out(vty, "%s", VTY_NEWLINE); } -static int config_write_as(struct vty *vty) -{ - struct osmo_ss7_instance *inst = g_s7i; - struct osmo_ss7_as *as; - - /* HACK to call this here, as we cannot install additional - * 'save' code into the root CONFIG_NODE ... */ - config_write_cs7(vty); - - /* HACK to call this here, but we must make sure that the ASP - * are all configured before we reference them from the AS, and - * VTY code always stores the nodes in alphabetical order */ - - config_write_asp(vty); - - llist_for_each_entry(as, &inst->as_list, list) - write_one_as(vty, as); - - return 0; -} - DEFUN(show_cs7_as, show_cs7_as_cmd, - "show cs7 as (active|all|m3ua|sua)", + "show cs7 as (active|all|m3ua|sua) [instance <0-15>]", SHOW_STR CS7_STR "Application Server (AS)\n" "Display all active ASs\n" "Display all ASs (default)\n" "Display all m3ua ASs\n" "Display all SUA ASs\n") { - struct osmo_ss7_instance *inst = g_s7i; + struct osmo_ss7_instance *inst; struct osmo_ss7_as *as; const char *filter = NULL; + int id = 0; if (argc) filter = argv[0]; + + if (argc > 1) + id = atoi(argv[1]); + inst = osmo_ss7_instance_find(id); + if (!inst) { + vty_out(vty, "No SS7 instance %d found%s", id, VTY_NEWLINE); + return CMD_WARNING; + } vty_out(vty, " Routing Routing Key Cic Cic%s", VTY_NEWLINE); vty_out(vty, "AS Name State Context Dpc Si Opc Ssn Min Max%s", VTY_NEWLINE); @@ -889,20 +859,88 @@ return CMD_SUCCESS; } -int osmo_ss7_vty_go_parent(struct vty *vty) +static void write_one_cs7(struct vty *vty, struct osmo_ss7_instance *inst) { struct osmo_ss7_asp *asp; + struct osmo_ss7_as *as; + struct osmo_ss7_route_table *rtable; + struct osmo_xua_server *oxs; + + vty_out(vty, "cs7 instance %u%s", inst->cfg.id, VTY_NEWLINE); + if (inst->cfg.network_indicator) + vty_out(vty, " network-indicator %s%s", + get_value_string(ss7_network_indicator_vals, + inst->cfg.network_indicator), + VTY_NEWLINE); + + if (inst->cfg.pc_fmt.component_len[0] != 3 || + inst->cfg.pc_fmt.component_len[1] != 8 || + inst->cfg.pc_fmt.component_len[2] != 3) { + vty_out(vty, " point-code format %u", + inst->cfg.pc_fmt.component_len[0]); + if (inst->cfg.pc_fmt.component_len[1]) + vty_out(vty, " %u", inst->cfg.pc_fmt.component_len[1]); + if (inst->cfg.pc_fmt.component_len[2]) + vty_out(vty, " %u", inst->cfg.pc_fmt.component_len[2]); + vty_out(vty, "%s", VTY_NEWLINE); + } + + if (inst->cfg.pc_fmt.delimiter != '.') + vty_out(vty, " point-code delimiter dash%s", VTY_NEWLINE); + + if (inst->cfg.primary_pc) + vty_out(vty, " point-code %s%s", + osmo_ss7_pointcode_print(inst, inst->cfg.primary_pc), + VTY_NEWLINE); + + /* first dump ASPs, as ASs reference them */ + llist_for_each_entry(asp, &inst->asp_list, list) + write_one_asp(vty, asp); + + /* then dump ASPs, as routes reference them */ + llist_for_each_entry(as, &inst->as_list, list) + write_one_as(vty, as); + + /* now dump routes, as their target ASs exist */ + llist_for_each_entry(rtable, &inst->rtable_list, list) + write_one_rtable(vty, rtable); + + llist_for_each_entry(oxs, &osmo_ss7_xua_servers, list) + write_one_sua(vty, oxs); +} + + +int osmo_ss7_vty_go_parent(struct vty *vty) +{ + struct osmo_ss7_as *as; + struct osmo_ss7_asp *asp; + struct osmo_ss7_route_table *rtbl; + struct osmo_xua_server *oxs; switch (vty->node) { case L_CS7_ASP_NODE: asp = vty->index; osmo_ss7_asp_restart(asp); - vty->node = CONFIG_NODE; + vty->node = L_CS7_NODE; + vty->index = asp->inst; break; case L_CS7_RTABLE_NODE: + rtbl = vty->index; + vty->node = L_CS7_NODE; + vty->index = rtbl->inst; + break; + case L_CS7_AS_NODE: + as = vty->index; + vty->node = L_CS7_NODE; + vty->index = as->inst; + break; case L_CS7_SUA_NODE: case L_CS7_M3UA_NODE: - case L_CS7_AS_NODE: + oxs = vty->index; + vty->node = L_CS7_NODE; + vty->index = oxs->inst; + break; + case L_CS7_NODE: default: vty->node = CONFIG_NODE; break; @@ -913,6 +951,7 @@ int osmo_ss7_is_config_node(struct vty *vty, int node) { switch (node) { + case L_CS7_NODE: case L_CS7_ASP_NODE: case L_CS7_RTABLE_NODE: case L_CS7_SUA_NODE: @@ -924,50 +963,35 @@ } } -int osmo_ss7_vty_init(void) +static void vty_init_shared(void) { - install_element(CONFIG_NODE, &cs7_net_ind_cmd); - install_element(CONFIG_NODE, &cs7_point_code_cmd); - install_element(CONFIG_NODE, &cs7_pc_format_cmd); - install_element(CONFIG_NODE, &cs7_pc_format_def_cmd); - install_element(CONFIG_NODE, &cs7_pc_delimiter_cmd); + /* the mother of all VTY config nodes */ + install_element(CONFIG_NODE, &cs7_instance_cmd); - install_node(&rtable_node, config_write_rtable); - vty_install_default(L_CS7_RTABLE_NODE); - install_element_ve(&show_cs7_route_cmd); - install_element(CONFIG_NODE, &cs7_route_table_cmd); - install_element(L_CS7_RTABLE_NODE, &cfg_description_cmd); - install_element(L_CS7_RTABLE_NODE, &cs7_rt_upd_cmd); - install_element(L_CS7_RTABLE_NODE, &cs7_rt_rem_cmd); - - install_node(&sua_node, config_write_sua); - vty_install_default(L_CS7_SUA_NODE); - install_element(CONFIG_NODE, &cs7_sua_cmd); - install_element(CONFIG_NODE, &no_cs7_sua_cmd); - install_element(L_CS7_SUA_NODE, &sua_local_ip_cmd); - - install_node(&m3ua_node, config_write_m3ua); - vty_install_default(L_CS7_M3UA_NODE); - install_element(CONFIG_NODE, &cs7_m3ua_cmd); - install_element(CONFIG_NODE, &no_cs7_m3ua_cmd); - install_element(L_CS7_M3UA_NODE, &m3ua_local_ip_cmd); + install_node(&cs7_node, config_write_cs7); + vty_install_default(L_CS7_NODE); + install_element(L_CS7_NODE, &cs7_net_ind_cmd); + install_element(L_CS7_NODE, &cs7_point_code_cmd); + install_element(L_CS7_NODE, &cs7_pc_format_cmd); + install_element(L_CS7_NODE, &cs7_pc_format_def_cmd); + install_element(L_CS7_NODE, &cs7_pc_delimiter_cmd); install_node(&asp_node, NULL); vty_install_default(L_CS7_ASP_NODE); install_element_ve(&show_cs7_asp_cmd); - install_element(CONFIG_NODE, &cs7_asp_cmd); - install_element(CONFIG_NODE, &no_cs7_asp_cmd); + install_element(L_CS7_NODE, &cs7_asp_cmd); + install_element(L_CS7_NODE, &no_cs7_asp_cmd); install_element(L_CS7_ASP_NODE, &cfg_description_cmd); install_element(L_CS7_ASP_NODE, &asp_remote_ip_cmd); install_element(L_CS7_ASP_NODE, &asp_qos_class_cmd); install_element(L_CS7_ASP_NODE, &asp_block_cmd); install_element(L_CS7_ASP_NODE, &asp_shutdown_cmd); - install_node(&as_node, config_write_as); + install_node(&as_node, NULL); vty_install_default(L_CS7_AS_NODE); install_element_ve(&show_cs7_as_cmd); - install_element(CONFIG_NODE, &cs7_as_cmd); - install_element(CONFIG_NODE, &no_cs7_as_cmd); + install_element(L_CS7_NODE, &cs7_as_cmd); + install_element(L_CS7_NODE, &no_cs7_as_cmd); install_element(L_CS7_AS_NODE, &cfg_description_cmd); install_element(L_CS7_AS_NODE, &as_asp_cmd); install_element(L_CS7_AS_NODE, &as_no_asp_cmd); @@ -975,6 +999,39 @@ install_element(L_CS7_AS_NODE, &as_recov_tout_cmd); install_element(L_CS7_AS_NODE, &as_qos_class_cmd); install_element(L_CS7_AS_NODE, &as_rout_key_cmd); - - return 0; } + +void osmo_ss7_vty_init_asp(void) +{ + vty_init_shared(); +} + +void osmo_ss7_vty_init_sg(void) +{ + vty_init_shared(); + + install_node(&rtable_node, NULL); + vty_install_default(L_CS7_RTABLE_NODE); + install_element_ve(&show_cs7_route_cmd); + install_element(L_CS7_NODE, &cs7_route_table_cmd); + install_element(L_CS7_RTABLE_NODE, &cfg_description_cmd); + install_element(L_CS7_RTABLE_NODE, &cs7_rt_upd_cmd); + install_element(L_CS7_RTABLE_NODE, &cs7_rt_rem_cmd); + + install_node(&sua_node, NULL); + vty_install_default(L_CS7_SUA_NODE); + install_element(L_CS7_NODE, &cs7_sua_cmd); + install_element(L_CS7_NODE, &no_cs7_sua_cmd); + install_element(L_CS7_SUA_NODE, &sua_local_ip_cmd); + + install_node(&m3ua_node, NULL); + vty_install_default(L_CS7_M3UA_NODE); + install_element(L_CS7_NODE, &cs7_m3ua_cmd); + install_element(L_CS7_NODE, &no_cs7_m3ua_cmd); + install_element(L_CS7_M3UA_NODE, &m3ua_local_ip_cmd); +} + +void osmo_ss7_set_vty_alloc_ctx(void *ctx) +{ + g_ctx = ctx; +}; diff --git a/stp/stp_main.c b/stp/stp_main.c index 029c0b2..24e2230 100644 --- a/stp/stp_main.c +++ b/stp/stp_main.c @@ -40,8 +40,6 @@ #include "internal.h" -struct osmo_ss7_instance *g_s7i; - static const struct log_info_cat log_info_cat[] = { }; @@ -78,9 +76,7 @@ osmo_ss7_init(); osmo_fsm_log_addr(false); vty_init(&vty_info); - osmo_ss7_vty_init(); - - g_s7i = osmo_ss7_instance_find_or_create(NULL, 0); + osmo_ss7_vty_init_sg(); rc = vty_read_config_file(config_file, NULL); if (rc < 0) { -- To view, visit https://gerrit.osmocom.org/2328 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I30966fbf2e143318cd9127eb8c17cccb24407106 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte From gerrit-no-reply at lists.osmocom.org Fri Apr 14 12:59:42 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 14 Apr 2017 12:59:42 +0000 Subject: libosmo-sccp[master]: osmo_ss7_vty: Merge the SUA and M3UA VTY nodes In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 Verified+1 -- To view, visit https://gerrit.osmocom.org/2329 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I5b842b7f10d94957398cf0c0406c440c495a0bdc Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Apr 14 12:59:48 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 14 Apr 2017 12:59:48 +0000 Subject: [MERGED] libosmo-sccp[master]: osmo_ss7_vty: Merge the SUA and M3UA VTY nodes In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: osmo_ss7_vty: Merge the SUA and M3UA VTY nodes ...................................................................... osmo_ss7_vty: Merge the SUA and M3UA VTY nodes The xUA servers have pretty much everything in common, there's no point in introducing a separate VTY note for each xUA flavor. Change-Id: I5b842b7f10d94957398cf0c0406c440c495a0bdc --- M stp/internal.h M stp/osmo_ss7_vty.c 2 files changed, 41 insertions(+), 106 deletions(-) Approvals: Harald Welte: Looks good to me, approved; Verified diff --git a/stp/internal.h b/stp/internal.h index 31d95ba..cbd6bac 100644 --- a/stp/internal.h +++ b/stp/internal.h @@ -6,8 +6,7 @@ L_CS7_NODE = _LAST_OSMOVTY_NODE + 1, L_CS7_AS_NODE, L_CS7_ASP_NODE, - L_CS7_SUA_NODE, - L_CS7_M3UA_NODE, + L_CS7_XUA_NODE, L_CS7_RTABLE_NODE, }; diff --git a/stp/osmo_ss7_vty.c b/stp/osmo_ss7_vty.c index 29693a8..fe7bc41 100644 --- a/stp/osmo_ss7_vty.c +++ b/stp/osmo_ss7_vty.c @@ -328,58 +328,67 @@ } /*********************************************************************** - * SUA Configuration (SG) + * xUA Listener Configuration (SG) ***********************************************************************/ -static struct cmd_node sua_node = { - L_CS7_SUA_NODE, - "%s(config-cs7-sua)# ", +static enum osmo_ss7_asp_protocol parse_asp_proto(const char *protocol) +{ + return get_string_value(osmo_ss7_asp_protocol_vals, protocol); +} + +static struct cmd_node xua_node = { + L_CS7_XUA_NODE, + "%s(config-cs7-listen)# ", 1, }; -DEFUN(cs7_sua, cs7_sua_cmd, - "sua <0-65534>", - "Configure/Enable SUA\n" - "SCTP Port number for SUA\n") +#define XUA_STR "SCCP User Adaptation\n" "MTP3 User Adaptation\n" + +DEFUN(cs7_xua, cs7_xua_cmd, + "listen (sua|m3ua) <0-65534>", + "Configure/Enable xUA Listener\n" + XUA_STR "SCTP Port number\n") { struct osmo_ss7_instance *inst = vty->index; struct osmo_xua_server *xs; - uint16_t port = atoi(argv[0]); + enum osmo_ss7_asp_protocol proto = parse_asp_proto(argv[0]); + uint16_t port = atoi(argv[1]); - xs = osmo_ss7_xua_server_find(inst, OSMO_SS7_ASP_PROT_SUA, port); + xs = osmo_ss7_xua_server_find(inst, proto, port); if (!xs) { - xs = osmo_ss7_xua_server_create(inst, OSMO_SS7_ASP_PROT_SUA, port, NULL); + xs = osmo_ss7_xua_server_create(inst, proto, port, NULL); if (!xs) return CMD_SUCCESS; } - vty->node = L_CS7_SUA_NODE; + vty->node = L_CS7_XUA_NODE; vty->index = xs; return CMD_SUCCESS; } -DEFUN(no_cs7_sua, no_cs7_sua_cmd, - "no sua <0-65534>", - NO_STR "Disable SUA on given SCTP Port\n" - "SCTP Port number for SUA\n") +DEFUN(no_cs7_xua, no_cs7_xua_cmd, + "no listen (sua|m3ua) <0-65534>", + NO_STR "Disable xUA Listener on given SCTP Port\n" + XUA_STR "SCTP Port number\n") { struct osmo_ss7_instance *inst = vty->index; struct osmo_xua_server *xs; - uint16_t port = atoi(argv[0]); + enum osmo_ss7_asp_protocol proto = parse_asp_proto(argv[0]); + uint16_t port = atoi(argv[1]); - xs = osmo_ss7_xua_server_find(inst, OSMO_SS7_ASP_PROT_SUA, port); + xs = osmo_ss7_xua_server_find(inst, proto, port); if (!xs) { - vty_out(vty, "No SUA server for port %u found%s", port, VTY_NEWLINE); + vty_out(vty, "No xUA server for port %u found%s", port, VTY_NEWLINE); return CMD_WARNING; } osmo_ss7_xua_server_destroy(xs); return CMD_SUCCESS; } -DEFUN(sua_local_ip, sua_local_ip_cmd, +DEFUN(xua_local_ip, xua_local_ip_cmd, "local-ip A.B.C.D", - "Configure the Local IP Address for SUA\n" - "IP Address to use for SUA\n") + "Configure the Local IP Address for xUA\n" + "IP Address to use for XUA\n") { struct osmo_xua_server *xs = vty->index; @@ -387,12 +396,7 @@ return CMD_SUCCESS; } -enum osmo_ss7_asp_protocol parse_asp_proto(const char *protocol) -{ - return get_string_value(osmo_ss7_asp_protocol_vals, protocol); -} - -static void write_one_sua(struct vty *vty, struct osmo_xua_server *xs) +static void write_one_xua(struct vty *vty, struct osmo_xua_server *xs) { vty_out(vty, " %s %u%s", get_value_string(osmo_ss7_asp_protocol_vals, xs->cfg.proto), @@ -400,66 +404,6 @@ vty_out(vty, " local-ip %s%s", xs->cfg.local.host, VTY_NEWLINE); } - -/*********************************************************************** - * M3UA Configuration (SG) - ***********************************************************************/ - -static struct cmd_node m3ua_node = { - L_CS7_M3UA_NODE, - "%s(config-cs7-m3ua)# ", - 1, -}; - -DEFUN(cs7_m3ua, cs7_m3ua_cmd, - "m3ua <0-65534>", - "Configure/Enable M3UA\n" - "SCTP Port number for M3UA\n") -{ - struct osmo_ss7_instance *inst = vty->index; - struct osmo_xua_server *xs; - uint16_t port = atoi(argv[0]); - - xs = osmo_ss7_xua_server_find(inst, OSMO_SS7_ASP_PROT_M3UA, port); - if (!xs) { - xs = osmo_ss7_xua_server_create(inst, OSMO_SS7_ASP_PROT_M3UA, port, NULL); - if (!xs) - return CMD_SUCCESS; - } - - vty->node = L_CS7_M3UA_NODE; - vty->index = xs; - return CMD_SUCCESS; -} - -DEFUN(no_cs7_m3ua, no_cs7_m3ua_cmd, - "no m3ua <0-65534>", - NO_STR "Disable M3UA on given SCTP Port\n" - "SCTP Port number for M3UA\n") -{ - struct osmo_ss7_instance *inst = vty->index; - struct osmo_xua_server *xs; - uint16_t port = atoi(argv[0]); - - xs = osmo_ss7_xua_server_find(inst, OSMO_SS7_ASP_PROT_M3UA, port); - if (!xs) { - vty_out(vty, "No M3UA server for port %u found%s", port, VTY_NEWLINE); - return CMD_WARNING; - } - osmo_ss7_xua_server_destroy(xs); - return CMD_SUCCESS; -} - -DEFUN(m3ua_local_ip, m3ua_local_ip_cmd, - "local-ip A.B.C.D", - "Configure the Local IP Address for M3UA\n" - "IP Address to use for M3UA\n") -{ - struct osmo_xua_server *xs = vty->index; - - osmo_ss7_xua_server_set_local_host(xs, argv[0]); - return CMD_SUCCESS; -} /*********************************************************************** * Application Server Process @@ -906,7 +850,7 @@ write_one_rtable(vty, rtable); llist_for_each_entry(oxs, &osmo_ss7_xua_servers, list) - write_one_sua(vty, oxs); + write_one_xua(vty, oxs); } @@ -934,8 +878,7 @@ vty->node = L_CS7_NODE; vty->index = as->inst; break; - case L_CS7_SUA_NODE: - case L_CS7_M3UA_NODE: + case L_CS7_XUA_NODE: oxs = vty->index; vty->node = L_CS7_NODE; vty->index = oxs->inst; @@ -954,8 +897,7 @@ case L_CS7_NODE: case L_CS7_ASP_NODE: case L_CS7_RTABLE_NODE: - case L_CS7_SUA_NODE: - case L_CS7_M3UA_NODE: + case L_CS7_XUA_NODE: case L_CS7_AS_NODE: return 1; default: @@ -1018,17 +960,11 @@ install_element(L_CS7_RTABLE_NODE, &cs7_rt_upd_cmd); install_element(L_CS7_RTABLE_NODE, &cs7_rt_rem_cmd); - install_node(&sua_node, NULL); - vty_install_default(L_CS7_SUA_NODE); - install_element(L_CS7_NODE, &cs7_sua_cmd); - install_element(L_CS7_NODE, &no_cs7_sua_cmd); - install_element(L_CS7_SUA_NODE, &sua_local_ip_cmd); - - install_node(&m3ua_node, NULL); - vty_install_default(L_CS7_M3UA_NODE); - install_element(L_CS7_NODE, &cs7_m3ua_cmd); - install_element(L_CS7_NODE, &no_cs7_m3ua_cmd); - install_element(L_CS7_M3UA_NODE, &m3ua_local_ip_cmd); + install_node(&xua_node, NULL); + vty_install_default(L_CS7_XUA_NODE); + install_element(L_CS7_NODE, &cs7_xua_cmd); + install_element(L_CS7_NODE, &no_cs7_xua_cmd); + install_element(L_CS7_XUA_NODE, &xua_local_ip_cmd); } void osmo_ss7_set_vty_alloc_ctx(void *ctx) -- To view, visit https://gerrit.osmocom.org/2329 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I5b842b7f10d94957398cf0c0406c440c495a0bdc Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte From gerrit-no-reply at lists.osmocom.org Fri Apr 14 12:59:50 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 14 Apr 2017 12:59:50 +0000 Subject: [MERGED] libosmo-sccp[master]: move osmo_ss7_vty.c [back] into libosmo-sigtran In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: move osmo_ss7_vty.c [back] into libosmo-sigtran ...................................................................... move osmo_ss7_vty.c [back] into libosmo-sigtran Now that the VTY has no static dependencies like a global ss7_instance anymore, we can move it back to libosmo-sigtran and make use of it in other programs outside osmo-stp. This requires Change-Id I184a7e3187b48c15c71bf773f86e188fe1daad15 in libosmocore Change-Id: I2e549f1eadbfb28dde79f620b130cbf022312c42 --- M include/osmocom/sigtran/osmo_ss7.h M src/Makefile.am R src/osmo_ss7_vty.c M stp/Makefile.am D stp/internal.h M stp/stp_main.c 6 files changed, 11 insertions(+), 25 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/include/osmocom/sigtran/osmo_ss7.h b/include/osmocom/sigtran/osmo_ss7.h index 1d82669..24f83e9 100644 --- a/include/osmocom/sigtran/osmo_ss7.h +++ b/include/osmocom/sigtran/osmo_ss7.h @@ -437,3 +437,11 @@ enum osmo_ss7_as_traffic_mode osmo_ss7_tmode_from_xua(uint32_t in); int osmo_ss7_tmode_to_xua(enum osmo_ss7_as_traffic_mode tmod); + +/* VTY related */ +struct vty; +void osmo_ss7_set_vty_alloc_ctx(void *ctx); +void osmo_ss7_vty_init_asp(void); +void osmo_ss7_vty_init_sg(void); +int osmo_ss7_vty_go_parent(struct vty *vty); +int osmo_ss7_is_config_node(struct vty *vty, int node); diff --git a/src/Makefile.am b/src/Makefile.am index f9b87b0..8e52792 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -29,6 +29,7 @@ libosmo_sigtran_la_SOURCES = sccp_sap.c sua.c m3ua.c xua_msg.c sccp_helpers.c \ sccp2sua.c sccp_scrc.c sccp_sclc.c sccp_scoc.c \ sccp_user.c xua_rkm.c xua_default_lm_fsm.c \ - osmo_ss7.c osmo_ss7_hmrt.c xua_asp_fsm.c xua_as_fsm.c + osmo_ss7.c osmo_ss7_hmrt.c xua_asp_fsm.c xua_as_fsm.c \ + osmo_ss7_vty.c libosmo_sigtran_la_LDFLAGS = -version-info $(LIBVERSION) -no-undefined -export-symbols-regex '^osmo_' libosmo_sigtran_la_LIBADD = $(LIBOSMOCORE_LIBS) $(LIBOSMONETIF_LIBS) $(LIBSCTP_LIBS) diff --git a/stp/osmo_ss7_vty.c b/src/osmo_ss7_vty.c similarity index 99% rename from stp/osmo_ss7_vty.c rename to src/osmo_ss7_vty.c index fe7bc41..59c4008 100644 --- a/stp/osmo_ss7_vty.c +++ b/src/osmo_ss7_vty.c @@ -35,8 +35,6 @@ #include #include -#include "internal.h" - #define CS7_STR "ITU-T Signaling System 7\n" #define PC_STR "Point Code\n" diff --git a/stp/Makefile.am b/stp/Makefile.am index 81aa11c..ae37487 100644 --- a/stp/Makefile.am +++ b/stp/Makefile.am @@ -2,10 +2,8 @@ AM_CFLAGS=-Wall -g $(LIBOSMOCORE_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(LIBOSMONETIF_CFLAGS) $(COVERAGE_FLAGS) AM_LDFLAGS=$(COVERAGE_LDFLAGS) -EXTRA_DIST = internal.h - bin_PROGRAMS = osmo-stp -osmo_stp_SOURCES = stp_main.c osmo_ss7_vty.c +osmo_stp_SOURCES = stp_main.c osmo_stp_LDADD = $(top_builddir)/src/libosmo-sigtran.la \ $(LIBOSMOCORE_LIBS) $(LIBOSMOVTY_LIBS) diff --git a/stp/internal.h b/stp/internal.h deleted file mode 100644 index cbd6bac..0000000 --- a/stp/internal.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -#include - -enum stp_vty_node { - L_CS7_NODE = _LAST_OSMOVTY_NODE + 1, - L_CS7_AS_NODE, - L_CS7_ASP_NODE, - L_CS7_XUA_NODE, - L_CS7_RTABLE_NODE, -}; - -void osmo_ss7_set_vty_alloc_ctx(void *ctx); -void osmo_ss7_vty_init_asp(void); -void osmo_ss7_vty_init_sg(void); -int osmo_ss7_vty_go_parent(struct vty *vty); -int osmo_ss7_is_config_node(struct vty *vty, int node); diff --git a/stp/stp_main.c b/stp/stp_main.c index 24e2230..267806b 100644 --- a/stp/stp_main.c +++ b/stp/stp_main.c @@ -38,8 +38,6 @@ #include #include -#include "internal.h" - static const struct log_info_cat log_info_cat[] = { }; -- To view, visit https://gerrit.osmocom.org/2330 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I2e549f1eadbfb28dde79f620b130cbf022312c42 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Fri Apr 14 12:59:53 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 14 Apr 2017 12:59:53 +0000 Subject: libosmo-sccp[master]: sua: Reject DATA messages on SCTP stream 0 In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2331 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I0784e221ef791557a69be04f7d246de059ea84c8 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Apr 14 12:59:56 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 14 Apr 2017 12:59:56 +0000 Subject: [MERGED] libosmo-sccp[master]: sua: Reject DATA messages on SCTP stream 0 In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: sua: Reject DATA messages on SCTP stream 0 ...................................................................... sua: Reject DATA messages on SCTP stream 0 RFC3868 states clearly that DATA messages MUST be sent o a stream other than stream '0'. So at the receiver side, we should validate that (just like we do in M3UA. Change-Id: I0784e221ef791557a69be04f7d246de059ea84c8 --- M src/sua.c 1 file changed, 8 insertions(+), 1 deletion(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/sua.c b/src/sua.c index 881191e..3bff855 100644 --- a/src/sua.c +++ b/src/sua.c @@ -630,15 +630,22 @@ goto out; } - /* TODO: check for SCTP Strema ID */ /* TODO: check if any AS configured in ASP */ /* TODO: check for valid routing context */ switch (xua->hdr.msg_class) { case SUA_MSGC_CL: + if (msgb_sctp_stream(msg) == 0) { + rc = SUA_ERR_INVAL_STREAM_ID; + break; + } rc = sua_rx_cl(asp, xua); break; case SUA_MSGC_CO: + if (msgb_sctp_stream(msg) == 0) { + rc = SUA_ERR_INVAL_STREAM_ID; + break; + } rc = sua_rx_co(asp, xua); break; case SUA_MSGC_ASPSM: -- To view, visit https://gerrit.osmocom.org/2331 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I0784e221ef791557a69be04f7d246de059ea84c8 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Fri Apr 14 15:12:43 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 14 Apr 2017 15:12:43 +0000 Subject: [PATCH] libosmo-sccp[master]: osmo_ss7_vty: Make 'instance <0-15>' mandatory of all show c... Message-ID: Review at https://gerrit.osmocom.org/2332 osmo_ss7_vty: Make 'instance <0-15>' mandatory of all show commands This way it is systematic and doesn't clash with other optional arguments we may introduce sooner or later at the end of the commands Change-Id: I5c1050b0564791b5684619d3737d1cb6c4539d63 --- M src/osmo_ss7_vty.c 1 file changed, 12 insertions(+), 20 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/32/2332/1 diff --git a/src/osmo_ss7_vty.c b/src/osmo_ss7_vty.c index 59c4008..d97610d 100644 --- a/src/osmo_ss7_vty.c +++ b/src/osmo_ss7_vty.c @@ -37,6 +37,7 @@ #define CS7_STR "ITU-T Signaling System 7\n" #define PC_STR "Point Code\n" +#define INST_STR "An instance of the SS7 stack\n" /*********************************************************************** * Core CS7 Configuration @@ -52,7 +53,7 @@ DEFUN(cs7_instance, cs7_instance_cmd, "cs7 instance <0-15>", - CS7_STR "Configure a SS7 Instance\n" + CS7_STR "Configure a SS7 Instance\n" INST_STR "Number of the instance\n") { int id = atoi(argv[0]); @@ -307,14 +308,12 @@ } DEFUN(show_cs7_route, show_cs7_route_cmd, - "show cs7 route [instance <0-15>]", - SHOW_STR CS7_STR "Routing Table\n") + "show cs7 instance <0-15> route", + SHOW_STR CS7_STR INST_STR INST_STR "Routing Table\n") { - int id = 0; + int id = atoi(argv[0]); struct osmo_ss7_instance *inst; - if (argc > 0) - id = atoi(argv[0]); inst = osmo_ss7_instance_find(id); if (!inst) { vty_out(vty, "No SS7 instance %d found%s", id, VTY_NEWLINE); @@ -504,15 +503,13 @@ } DEFUN(show_cs7_asp, show_cs7_asp_cmd, - "show cs7 asp [instance <0-15>]", - SHOW_STR CS7_STR "Application Server Process (ASP)\n") + "show cs7 instance <0-15> asp", + SHOW_STR CS7_STR INST_STR INST_STR "Application Server Process (ASP)\n") { struct osmo_ss7_instance *inst; struct osmo_ss7_asp *asp; - int id = 0; + int id = atoi(argv[0]); - if (argc > 0) - id = atoi(argv[0]); inst = osmo_ss7_instance_find(id); if (!inst) { vty_out(vty, "No SS7 instance %d found%s", id, VTY_NEWLINE); @@ -760,8 +757,8 @@ } DEFUN(show_cs7_as, show_cs7_as_cmd, - "show cs7 as (active|all|m3ua|sua) [instance <0-15>]", - SHOW_STR CS7_STR "Application Server (AS)\n" + "show cs7 instance <0-15> as (active|all|m3ua|sua)", + SHOW_STR CS7_STR INST_STR INST_STR "Application Server (AS)\n" "Display all active ASs\n" "Display all ASs (default)\n" "Display all m3ua ASs\n" @@ -769,14 +766,9 @@ { struct osmo_ss7_instance *inst; struct osmo_ss7_as *as; - const char *filter = NULL; - int id = 0; + const char *filter = argv[1]; + int id = atoi(argv[0]); - if (argc) - filter = argv[0]; - - if (argc > 1) - id = atoi(argv[1]); inst = osmo_ss7_instance_find(id); if (!inst) { vty_out(vty, "No SS7 instance %d found%s", id, VTY_NEWLINE); -- To view, visit https://gerrit.osmocom.org/2332 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I5c1050b0564791b5684619d3737d1cb6c4539d63 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Fri Apr 14 15:12:44 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 14 Apr 2017 15:12:44 +0000 Subject: [PATCH] libosmo-sccp[master]: osmo_ss7_vty: Add 'show cs7 instance <0-15> users' command Message-ID: Review at https://gerrit.osmocom.org/2333 osmo_ss7_vty: Add 'show cs7 instance <0-15> users' command This will list which Service Indicators have bound local users (like SCCP) Change-Id: Ibb21810e2ebe520e07cfdda3a0c62172b152015e --- M src/osmo_ss7_vty.c 1 file changed, 28 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/33/2333/1 diff --git a/src/osmo_ss7_vty.c b/src/osmo_ss7_vty.c index d97610d..40f99b1 100644 --- a/src/osmo_ss7_vty.c +++ b/src/osmo_ss7_vty.c @@ -178,6 +178,32 @@ return 0; } +DEFUN(show_cs7_user, show_cs7_user_cmd, + "show cs7 instance <0-15> users", + SHOW_STR CS7_STR INST_STR INST_STR "User Table\n") +{ + int id = atoi(argv[0]); + struct osmo_ss7_instance *inst; + unsigned int i; + + inst = osmo_ss7_instance_find(id); + if (!inst) { + vty_out(vty, "No SS7 instance %d found%s", id, VTY_NEWLINE); + return CMD_WARNING; + } + + for (i = 0; i < ARRAY_SIZE(inst->user); i++) { + const struct osmo_ss7_user *user = inst->user[i]; + if (!user) + continue; + vty_out(vty, "SI %u: %s%s", i, user->name, VTY_NEWLINE); + } + + return CMD_SUCCESS; +} + +/* TODO: Links + Linksets */ + /*********************************************************************** * Routing Table Configuration ***********************************************************************/ @@ -897,6 +923,8 @@ static void vty_init_shared(void) { + install_element_ve(&show_cs7_user_cmd); + /* the mother of all VTY config nodes */ install_element(CONFIG_NODE, &cs7_instance_cmd); -- To view, visit https://gerrit.osmocom.org/2333 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ibb21810e2ebe520e07cfdda3a0c62172b152015e Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Fri Apr 14 15:12:44 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 14 Apr 2017 15:12:44 +0000 Subject: [PATCH] libosmo-sccp[master]: osmo_ss7_vty: Add Command to permit (or disallow) dynamc rou... Message-ID: Review at https://gerrit.osmocom.org/2334 osmo_ss7_vty: Add Command to permit (or disallow) dynamc routing key allocation This feature has been introduced in 8dec5a8ec554bbd56f4d3f45b6e1025d4c1ffb45, but so far hasn't been exposed to the VTY yet. Change-Id: I7355522bacbad1072feb5484b865dfd1be50a64d --- M src/osmo_ss7_vty.c 1 file changed, 21 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/34/2334/1 diff --git a/src/osmo_ss7_vty.c b/src/osmo_ss7_vty.c index 40f99b1..6c19188 100644 --- a/src/osmo_ss7_vty.c +++ b/src/osmo_ss7_vty.c @@ -163,8 +163,25 @@ inst->cfg.primary_pc = pc; return CMD_SUCCESS; } + /* TODO: cs7 secondary-pc */ /* TODO: cs7 capability-pc */ + +DEFUN(cs7_permit_dyn_rkm, cs7_permit_dyn_rkm_cmd, + "xua rkm routing-key-allocation (static-only|dynamic-permitted)", + "SIGTRAN xxxUA related\n" "Routing Key Management Allocation Policy\n" + "Only static (pre-confgured) Routing Keys permitted\n" + "Dynamically allocate Routing Keys for what ASPs request\n") +{ + struct osmo_ss7_instance *inst = vty->index; + + if (!strcmp(argv[0], "dynamic-permitted")) + inst->cfg.permit_dyn_rkm_alloc = true; + else + inst->cfg.permit_dyn_rkm_alloc = false; + + return CMD_SUCCESS; +} static void write_one_cs7(struct vty *vty, struct osmo_ss7_instance *inst); @@ -853,6 +870,9 @@ osmo_ss7_pointcode_print(inst, inst->cfg.primary_pc), VTY_NEWLINE); + if (inst->cfg.permit_dyn_rkm_alloc) + vty_out(vty, " xua rkm routing-key-allocation dynamic-permitted%s", VTY_NEWLINE); + /* first dump ASPs, as ASs reference them */ llist_for_each_entry(asp, &inst->asp_list, list) write_one_asp(vty, asp); @@ -935,6 +955,7 @@ install_element(L_CS7_NODE, &cs7_pc_format_cmd); install_element(L_CS7_NODE, &cs7_pc_format_def_cmd); install_element(L_CS7_NODE, &cs7_pc_delimiter_cmd); + install_element(L_CS7_NODE, &cs7_permit_dyn_rkm_cmd); install_node(&asp_node, NULL); vty_install_default(L_CS7_ASP_NODE); -- To view, visit https://gerrit.osmocom.org/2334 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I7355522bacbad1072feb5484b865dfd1be50a64d Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Fri Apr 14 15:12:44 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 14 Apr 2017 15:12:44 +0000 Subject: [PATCH] libosmo-sccp[master]: osmo_ss7_vty: Add 'description' command for SS7 instances Message-ID: Review at https://gerrit.osmocom.org/2335 osmo_ss7_vty: Add 'description' command for SS7 instances This allows the user to add some description to each SS7 instance Change-Id: Ia5d22f2f70ec12dd13151f949bb45b5fdab42fc5 --- M src/osmo_ss7_vty.c 1 file changed, 3 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/35/2335/1 diff --git a/src/osmo_ss7_vty.c b/src/osmo_ss7_vty.c index 6c19188..5dfa465 100644 --- a/src/osmo_ss7_vty.c +++ b/src/osmo_ss7_vty.c @@ -844,6 +844,8 @@ struct osmo_xua_server *oxs; vty_out(vty, "cs7 instance %u%s", inst->cfg.id, VTY_NEWLINE); + if (inst->cfg.description) + vty_out(vty, " description %s%s", inst->cfg.description, VTY_NEWLINE); if (inst->cfg.network_indicator) vty_out(vty, " network-indicator %s%s", get_value_string(ss7_network_indicator_vals, @@ -950,6 +952,7 @@ install_node(&cs7_node, config_write_cs7); vty_install_default(L_CS7_NODE); + install_element(L_CS7_NODE, &cfg_description_cmd); install_element(L_CS7_NODE, &cs7_net_ind_cmd); install_element(L_CS7_NODE, &cs7_point_code_cmd); install_element(L_CS7_NODE, &cs7_pc_format_cmd); -- To view, visit https://gerrit.osmocom.org/2335 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ia5d22f2f70ec12dd13151f949bb45b5fdab42fc5 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Fri Apr 14 15:12:44 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 14 Apr 2017 15:12:44 +0000 Subject: [PATCH] libosmo-sccp[master]: Don't overwrite existing data in osmo_ss7_instance_find_or_c... Message-ID: Review at https://gerrit.osmocom.org/2336 Don't overwrite existing data in osmo_ss7_instance_find_or_create() If we actually found an instance for the specified ID, return it fast and don't (re)initialize all linked list heads, etc. Change-Id: I91b6aabdb873ed8dd103918ee5e40b7ad3946735 --- M src/osmo_ss7.c 1 file changed, 4 insertions(+), 2 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/36/2336/1 diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index 27e56af..9b2377b 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -315,8 +315,10 @@ OSMO_ASSERT(ss7_initialized); inst = osmo_ss7_instance_find(id); - if (!inst) - inst = talloc_zero(ctx, struct osmo_ss7_instance); + if (inst) + return inst; + + inst = talloc_zero(ctx, struct osmo_ss7_instance); if (!inst) return NULL; -- To view, visit https://gerrit.osmocom.org/2336 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I91b6aabdb873ed8dd103918ee5e40b7ad3946735 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Fri Apr 14 15:12:45 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 14 Apr 2017 15:12:45 +0000 Subject: [PATCH] libosmo-sccp[master]: osmo_ss7_vty: Introduce xUA listener accept-asp-connections ... Message-ID: Review at https://gerrit.osmocom.org/2337 osmo_ss7_vty: Introduce xUA listener accept-asp-connections command Using this command one can specify if ASP connections should be refused if there's no matching configuration, or whether ASPs should simply be create on-demand. Change-Id: Ic93b99047fb566cdb25a2f4139ebef54849dece9 --- M src/osmo_ss7_vty.c 1 file changed, 19 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/37/2337/1 diff --git a/src/osmo_ss7_vty.c b/src/osmo_ss7_vty.c index 5dfa465..e661623 100644 --- a/src/osmo_ss7_vty.c +++ b/src/osmo_ss7_vty.c @@ -436,12 +436,30 @@ return CMD_SUCCESS; } +DEFUN(xua_accept_dyn_asp, xua_accept_dyn_asp_cmd, + "accept-asp-connections (pre-configured|dynamic-permitted)", + "Define what kind of ASP connections to accept\n" + "Accept only pre-confiugred ASPs (source IP/prt)\n" + "Accept any connection and dynamically create an ASP definition\n") +{ + struct osmo_xua_server *xs = vty->index; + + if (!strcmp(argv[0], "dynamic-permitted")) + xs->cfg.accept_dyn_reg = true; + else + xs->cfg.accept_dyn_reg = false; + + return CMD_SUCCESS; +} + static void write_one_xua(struct vty *vty, struct osmo_xua_server *xs) { vty_out(vty, " %s %u%s", get_value_string(osmo_ss7_asp_protocol_vals, xs->cfg.proto), xs->cfg.local.port, VTY_NEWLINE); vty_out(vty, " local-ip %s%s", xs->cfg.local.host, VTY_NEWLINE); + if (xs->cfg.accept_dyn_reg) + vty_out(vty, " accept-asp-connections dynamic-permitted%s", VTY_NEWLINE); } @@ -1007,6 +1025,7 @@ install_element(L_CS7_NODE, &cs7_xua_cmd); install_element(L_CS7_NODE, &no_cs7_xua_cmd); install_element(L_CS7_XUA_NODE, &xua_local_ip_cmd); + install_element(L_CS7_XUA_NODE, &xua_accept_dyn_asp_cmd); } void osmo_ss7_set_vty_alloc_ctx(void *ctx) -- To view, visit https://gerrit.osmocom.org/2337 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ic93b99047fb566cdb25a2f4139ebef54849dece9 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Fri Apr 14 15:12:45 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 14 Apr 2017 15:12:45 +0000 Subject: [PATCH] libosmo-sccp[master]: osmo_ss7_vty: Fix config file writing for xUA listeners Message-ID: Review at https://gerrit.osmocom.org/2338 osmo_ss7_vty: Fix config file writing for xUA listeners We so far generated un-parseable config files.. Change-Id: Iff6940ef6f52739b6f30a152487038cb0220da43 --- M src/osmo_ss7_vty.c 1 file changed, 1 insertion(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/38/2338/1 diff --git a/src/osmo_ss7_vty.c b/src/osmo_ss7_vty.c index e661623..08229dc 100644 --- a/src/osmo_ss7_vty.c +++ b/src/osmo_ss7_vty.c @@ -454,7 +454,7 @@ static void write_one_xua(struct vty *vty, struct osmo_xua_server *xs) { - vty_out(vty, " %s %u%s", + vty_out(vty, " listen %s %u%s", get_value_string(osmo_ss7_asp_protocol_vals, xs->cfg.proto), xs->cfg.local.port, VTY_NEWLINE); vty_out(vty, " local-ip %s%s", xs->cfg.local.host, VTY_NEWLINE); -- To view, visit https://gerrit.osmocom.org/2338 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Iff6940ef6f52739b6f30a152487038cb0220da43 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Fri Apr 14 15:12:45 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 14 Apr 2017 15:12:45 +0000 Subject: [PATCH] libosmo-sccp[master]: Add exampel osmo-stp configuration file Message-ID: Review at https://gerrit.osmocom.org/2339 Add exampel osmo-stp configuration file Change-Id: I45a04dc808e5a419bf5d68eb28c48cbec352b318 --- M Makefile.am A doc/examples/osmo-stp.cfg 2 files changed, 12 insertions(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/39/2339/1 diff --git a/Makefile.am b/Makefile.am index ededdac..9bb711c 100644 --- a/Makefile.am +++ b/Makefile.am @@ -6,7 +6,7 @@ pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = libosmo-sccp.pc libosmo-mtp.pc libosmo-sigtran.pc libosmo-xua.pc -EXTRA_DIST = .version +EXTRA_DIST = .version doc/examples/osmo-stp.cfg BUILT_SOURCES = $(top_srcdir)/.version $(top_srcdir)/.version: diff --git a/doc/examples/osmo-stp.cfg b/doc/examples/osmo-stp.cfg new file mode 100644 index 0000000..45a822b --- /dev/null +++ b/doc/examples/osmo-stp.cfg @@ -0,0 +1,11 @@ +! +! osmo-stp (0.0.6.3.179-b248) configuration saved from vty +!! +! +line vty + no login +! +cs7 instance 0 + xua rkm routing-key-allocation dynamic-permitted + listen m3ua 2905 + accept-asp-connections dynamic-permitted -- To view, visit https://gerrit.osmocom.org/2339 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I45a04dc808e5a419bf5d68eb28c48cbec352b318 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Fri Apr 14 15:12:45 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 14 Apr 2017 15:12:45 +0000 Subject: [PATCH] libosmo-sccp[master]: stp: Add copyright notice Message-ID: Review at https://gerrit.osmocom.org/2340 stp: Add copyright notice Change-Id: I4e074f570eac2e6a0a761f9f5f9c35fa4afa0315 --- M stp/stp_main.c 1 file changed, 12 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/40/2340/1 diff --git a/stp/stp_main.c b/stp/stp_main.c index 267806b..6fbc634 100644 --- a/stp/stp_main.c +++ b/stp/stp_main.c @@ -58,8 +58,17 @@ log_set_category_filter(osmo_stderr_target, log_cats[i], 1, LOGL_DEBUG); } +static const char stp_copyright[] = + "Copyright (C) 2015-2017 by Harald Welte \r\n" + "Contributions by Holger Freyther, Neels Hofmeyr\r\n" + "License GPLv2+: GNU GPL Version 2 or later \r\n" + "This is free software: you are free ot change and redistribute it.\r\n" + "There is NO WARRANTY, to the extent permitted by law.\r\n\r\n" + "Free Software lives by contribution. If you use this, please contribute!\r\n"; + static struct vty_app_info vty_info = { .name = "osmo-stp", + .copyright = stp_copyright, .version = PACKAGE_VERSION, .go_parent_cb = osmo_ss7_vty_go_parent, .is_config_node = osmo_ss7_is_config_node, @@ -70,6 +79,9 @@ char *config_file = "osmo-stp.cfg"; int rc; + fputs(stp_copyright, stdout); + fputs("\n", stdout); + init_logging(); osmo_ss7_init(); osmo_fsm_log_addr(false); -- To view, visit https://gerrit.osmocom.org/2340 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I4e074f570eac2e6a0a761f9f5f9c35fa4afa0315 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Fri Apr 14 15:12:46 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 14 Apr 2017 15:12:46 +0000 Subject: [PATCH] libosmo-sccp[master]: osmo-stp: Remove hack to always enable debug logging Message-ID: Review at https://gerrit.osmocom.org/2341 osmo-stp: Remove hack to always enable debug logging ... and rather use the config file based logging configuration, like other osmocom programs, too. Change-Id: I7e0fb869bd778d8c276dc8afd16ecd7f1965b74a --- M doc/examples/osmo-stp.cfg M stp/stp_main.c 2 files changed, 13 insertions(+), 13 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/41/2341/1 diff --git a/doc/examples/osmo-stp.cfg b/doc/examples/osmo-stp.cfg index 45a822b..960bf33 100644 --- a/doc/examples/osmo-stp.cfg +++ b/doc/examples/osmo-stp.cfg @@ -2,6 +2,15 @@ ! osmo-stp (0.0.6.3.179-b248) configuration saved from vty !! ! +log stderr + logging filter all 1 + logging color 1 + logging print category 1 + logging timestamp 0 + logging level lss7 debug + logging level lsccp debug + logging level lsua debug + logging level lm3ua debug line vty no login ! diff --git a/stp/stp_main.c b/stp/stp_main.c index 6fbc634..5412223 100644 --- a/stp/stp_main.c +++ b/stp/stp_main.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -38,6 +39,7 @@ #include #include +/* we only use logging sub-systems of the various libraries so far */ static const struct log_info_cat log_info_cat[] = { }; @@ -45,18 +47,6 @@ .cat = log_info_cat, .num_cat = ARRAY_SIZE(log_info_cat), }; - -/* Hack to enable debug logging for all relevant (used?) subsystems */ -static void init_logging(void) -{ - const int log_cats[] = { DLSS7, DLSUA, DLM3UA, DLSCCP, DLINP }; - unsigned int i; - - osmo_init_logging(&log_info); - - for (i = 0; i < ARRAY_SIZE(log_cats); i++) - log_set_category_filter(osmo_stderr_target, log_cats[i], 1, LOGL_DEBUG); -} static const char stp_copyright[] = "Copyright (C) 2015-2017 by Harald Welte \r\n" @@ -82,10 +72,11 @@ fputs(stp_copyright, stdout); fputs("\n", stdout); - init_logging(); + osmo_init_logging(&log_info); osmo_ss7_init(); osmo_fsm_log_addr(false); vty_init(&vty_info); + logging_vty_add_cmds(&log_info); osmo_ss7_vty_init_sg(); rc = vty_read_config_file(config_file, NULL); -- To view, visit https://gerrit.osmocom.org/2341 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I7e0fb869bd778d8c276dc8afd16ecd7f1965b74a Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Fri Apr 14 15:12:46 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 14 Apr 2017 15:12:46 +0000 Subject: [PATCH] libosmo-sccp[master]: osmo-stp: Add command line options and daemonize functionality Message-ID: Review at https://gerrit.osmocom.org/2342 osmo-stp: Add command line options and daemonize functionality Change-Id: I267fbe2e5c774960f0b63cfdd9f60df121b4934d --- M stp/stp_main.c 1 file changed, 75 insertions(+), 6 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/42/2342/1 diff --git a/stp/stp_main.c b/stp/stp_main.c index 5412223..3110ec4 100644 --- a/stp/stp_main.c +++ b/stp/stp_main.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -29,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -64,25 +66,82 @@ .is_config_node = osmo_ss7_is_config_node, }; +static struct { + bool daemonize; + const char *config_file; +} cmdline_config = { + .daemonize = false, + .config_file = "osmo-stp.cfg", +}; + +static void print_help(void) +{ + printf(" -h --help This text.\n"); + printf(" -D --daemonize Fork teh process into a background daemon\n"); + printf(" -c --config-file filename The config file to use. Default: ./osmo-stp.cfg\n"); + printf(" -V --version Print the version of OsmoSTP\n"); +} + +static void handle_options(int argc, char **argv) +{ + while (1) { + int option_index = 0, c; + static const struct option long_options[] = { + { "help", 0, 0, 'h' }, + { "daemonize", 0, 0, 'D' }, + { "config-file", 1, 0, 'c' }, + { "version", 0, 0, 'V' }, + { NULL, 0, 0, 0 } + }; + + c = getopt_long(argc, argv, "hDc:V", long_options, &option_index); + if (c == -1) + break; + + switch (c) { + case 'h': + print_help(); + exit(0); + break; + case 'D': + cmdline_config.daemonize = true; + break; + case 'c': + cmdline_config.config_file = optarg; + break; + case 'V': + print_version(1); + exit(0); + break; + default: + fprintf(stderr, "Error in command line options. Exiting\n"); + exit(1); + break; + } + } +} + int main(int argc, char **argv) { - char *config_file = "osmo-stp.cfg"; int rc; + + osmo_init_logging(&log_info); + vty_init(&vty_info); + + handle_options(argc, argv); fputs(stp_copyright, stdout); fputs("\n", stdout); - osmo_init_logging(&log_info); osmo_ss7_init(); osmo_fsm_log_addr(false); - vty_init(&vty_info); logging_vty_add_cmds(&log_info); osmo_ss7_vty_init_sg(); - rc = vty_read_config_file(config_file, NULL); + rc = vty_read_config_file(cmdline_config.config_file, NULL); if (rc < 0) { fprintf(stderr, "Failed to parse the config file '%s'\n", - config_file); + cmdline_config.config_file); exit(1); } @@ -92,7 +151,17 @@ exit(1); } + if (cmdline_config.daemonize) { + rc = osmo_daemonize(); + if (rc < 0) { + perror("Error during daemonize"); + exit(1); + } + } + while (1) { - osmo_select_main(0); + rc = osmo_select_main(0); + if (rc < 0) + exit(3); } } -- To view, visit https://gerrit.osmocom.org/2342 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I267fbe2e5c774960f0b63cfdd9f60df121b4934d Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Fri Apr 14 15:17:38 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 14 Apr 2017 15:17:38 +0000 Subject: libosmo-sccp[master]: osmo_ss7_vty: Make 'instance <0-15>' mandatory of all show c... In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2332 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I5c1050b0564791b5684619d3737d1cb6c4539d63 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Apr 14 15:17:40 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 14 Apr 2017 15:17:40 +0000 Subject: libosmo-sccp[master]: osmo_ss7_vty: Add 'show cs7 instance <0-15> users' command In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2333 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ibb21810e2ebe520e07cfdda3a0c62172b152015e Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Apr 14 15:17:58 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 14 Apr 2017 15:17:58 +0000 Subject: libosmo-sccp[master]: osmo_ss7_vty: Add Command to permit (or disallow) dynamc rou... In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2334 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I7355522bacbad1072feb5484b865dfd1be50a64d Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Apr 14 15:18:01 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 14 Apr 2017 15:18:01 +0000 Subject: libosmo-sccp[master]: osmo_ss7_vty: Add 'description' command for SS7 instances In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2335 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ia5d22f2f70ec12dd13151f949bb45b5fdab42fc5 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Apr 14 15:18:09 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 14 Apr 2017 15:18:09 +0000 Subject: [MERGED] libosmo-sccp[master]: osmo_ss7_vty: Add 'description' command for SS7 instances In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: osmo_ss7_vty: Add 'description' command for SS7 instances ...................................................................... osmo_ss7_vty: Add 'description' command for SS7 instances This allows the user to add some description to each SS7 instance Change-Id: Ia5d22f2f70ec12dd13151f949bb45b5fdab42fc5 --- M src/osmo_ss7_vty.c 1 file changed, 3 insertions(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/osmo_ss7_vty.c b/src/osmo_ss7_vty.c index 6c19188..5dfa465 100644 --- a/src/osmo_ss7_vty.c +++ b/src/osmo_ss7_vty.c @@ -844,6 +844,8 @@ struct osmo_xua_server *oxs; vty_out(vty, "cs7 instance %u%s", inst->cfg.id, VTY_NEWLINE); + if (inst->cfg.description) + vty_out(vty, " description %s%s", inst->cfg.description, VTY_NEWLINE); if (inst->cfg.network_indicator) vty_out(vty, " network-indicator %s%s", get_value_string(ss7_network_indicator_vals, @@ -950,6 +952,7 @@ install_node(&cs7_node, config_write_cs7); vty_install_default(L_CS7_NODE); + install_element(L_CS7_NODE, &cfg_description_cmd); install_element(L_CS7_NODE, &cs7_net_ind_cmd); install_element(L_CS7_NODE, &cs7_point_code_cmd); install_element(L_CS7_NODE, &cs7_pc_format_cmd); -- To view, visit https://gerrit.osmocom.org/2335 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ia5d22f2f70ec12dd13151f949bb45b5fdab42fc5 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Fri Apr 14 15:18:09 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 14 Apr 2017 15:18:09 +0000 Subject: [MERGED] libosmo-sccp[master]: osmo_ss7_vty: Add Command to permit (or disallow) dynamc rou... In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: osmo_ss7_vty: Add Command to permit (or disallow) dynamc routing key allocation ...................................................................... osmo_ss7_vty: Add Command to permit (or disallow) dynamc routing key allocation This feature has been introduced in 8dec5a8ec554bbd56f4d3f45b6e1025d4c1ffb45, but so far hasn't been exposed to the VTY yet. Change-Id: I7355522bacbad1072feb5484b865dfd1be50a64d --- M src/osmo_ss7_vty.c 1 file changed, 21 insertions(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/osmo_ss7_vty.c b/src/osmo_ss7_vty.c index 40f99b1..6c19188 100644 --- a/src/osmo_ss7_vty.c +++ b/src/osmo_ss7_vty.c @@ -163,8 +163,25 @@ inst->cfg.primary_pc = pc; return CMD_SUCCESS; } + /* TODO: cs7 secondary-pc */ /* TODO: cs7 capability-pc */ + +DEFUN(cs7_permit_dyn_rkm, cs7_permit_dyn_rkm_cmd, + "xua rkm routing-key-allocation (static-only|dynamic-permitted)", + "SIGTRAN xxxUA related\n" "Routing Key Management Allocation Policy\n" + "Only static (pre-confgured) Routing Keys permitted\n" + "Dynamically allocate Routing Keys for what ASPs request\n") +{ + struct osmo_ss7_instance *inst = vty->index; + + if (!strcmp(argv[0], "dynamic-permitted")) + inst->cfg.permit_dyn_rkm_alloc = true; + else + inst->cfg.permit_dyn_rkm_alloc = false; + + return CMD_SUCCESS; +} static void write_one_cs7(struct vty *vty, struct osmo_ss7_instance *inst); @@ -853,6 +870,9 @@ osmo_ss7_pointcode_print(inst, inst->cfg.primary_pc), VTY_NEWLINE); + if (inst->cfg.permit_dyn_rkm_alloc) + vty_out(vty, " xua rkm routing-key-allocation dynamic-permitted%s", VTY_NEWLINE); + /* first dump ASPs, as ASs reference them */ llist_for_each_entry(asp, &inst->asp_list, list) write_one_asp(vty, asp); @@ -935,6 +955,7 @@ install_element(L_CS7_NODE, &cs7_pc_format_cmd); install_element(L_CS7_NODE, &cs7_pc_format_def_cmd); install_element(L_CS7_NODE, &cs7_pc_delimiter_cmd); + install_element(L_CS7_NODE, &cs7_permit_dyn_rkm_cmd); install_node(&asp_node, NULL); vty_install_default(L_CS7_ASP_NODE); -- To view, visit https://gerrit.osmocom.org/2334 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I7355522bacbad1072feb5484b865dfd1be50a64d Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Fri Apr 14 15:18:10 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 14 Apr 2017 15:18:10 +0000 Subject: [MERGED] libosmo-sccp[master]: osmo_ss7_vty: Add 'show cs7 instance <0-15> users' command In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: osmo_ss7_vty: Add 'show cs7 instance <0-15> users' command ...................................................................... osmo_ss7_vty: Add 'show cs7 instance <0-15> users' command This will list which Service Indicators have bound local users (like SCCP) Change-Id: Ibb21810e2ebe520e07cfdda3a0c62172b152015e --- M src/osmo_ss7_vty.c 1 file changed, 28 insertions(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/osmo_ss7_vty.c b/src/osmo_ss7_vty.c index d97610d..40f99b1 100644 --- a/src/osmo_ss7_vty.c +++ b/src/osmo_ss7_vty.c @@ -178,6 +178,32 @@ return 0; } +DEFUN(show_cs7_user, show_cs7_user_cmd, + "show cs7 instance <0-15> users", + SHOW_STR CS7_STR INST_STR INST_STR "User Table\n") +{ + int id = atoi(argv[0]); + struct osmo_ss7_instance *inst; + unsigned int i; + + inst = osmo_ss7_instance_find(id); + if (!inst) { + vty_out(vty, "No SS7 instance %d found%s", id, VTY_NEWLINE); + return CMD_WARNING; + } + + for (i = 0; i < ARRAY_SIZE(inst->user); i++) { + const struct osmo_ss7_user *user = inst->user[i]; + if (!user) + continue; + vty_out(vty, "SI %u: %s%s", i, user->name, VTY_NEWLINE); + } + + return CMD_SUCCESS; +} + +/* TODO: Links + Linksets */ + /*********************************************************************** * Routing Table Configuration ***********************************************************************/ @@ -897,6 +923,8 @@ static void vty_init_shared(void) { + install_element_ve(&show_cs7_user_cmd); + /* the mother of all VTY config nodes */ install_element(CONFIG_NODE, &cs7_instance_cmd); -- To view, visit https://gerrit.osmocom.org/2333 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ibb21810e2ebe520e07cfdda3a0c62172b152015e Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Fri Apr 14 15:18:10 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 14 Apr 2017 15:18:10 +0000 Subject: [MERGED] libosmo-sccp[master]: osmo_ss7_vty: Make 'instance <0-15>' mandatory of all show c... In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: osmo_ss7_vty: Make 'instance <0-15>' mandatory of all show commands ...................................................................... osmo_ss7_vty: Make 'instance <0-15>' mandatory of all show commands This way it is systematic and doesn't clash with other optional arguments we may introduce sooner or later at the end of the commands Change-Id: I5c1050b0564791b5684619d3737d1cb6c4539d63 --- M src/osmo_ss7_vty.c 1 file changed, 12 insertions(+), 20 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/osmo_ss7_vty.c b/src/osmo_ss7_vty.c index 59c4008..d97610d 100644 --- a/src/osmo_ss7_vty.c +++ b/src/osmo_ss7_vty.c @@ -37,6 +37,7 @@ #define CS7_STR "ITU-T Signaling System 7\n" #define PC_STR "Point Code\n" +#define INST_STR "An instance of the SS7 stack\n" /*********************************************************************** * Core CS7 Configuration @@ -52,7 +53,7 @@ DEFUN(cs7_instance, cs7_instance_cmd, "cs7 instance <0-15>", - CS7_STR "Configure a SS7 Instance\n" + CS7_STR "Configure a SS7 Instance\n" INST_STR "Number of the instance\n") { int id = atoi(argv[0]); @@ -307,14 +308,12 @@ } DEFUN(show_cs7_route, show_cs7_route_cmd, - "show cs7 route [instance <0-15>]", - SHOW_STR CS7_STR "Routing Table\n") + "show cs7 instance <0-15> route", + SHOW_STR CS7_STR INST_STR INST_STR "Routing Table\n") { - int id = 0; + int id = atoi(argv[0]); struct osmo_ss7_instance *inst; - if (argc > 0) - id = atoi(argv[0]); inst = osmo_ss7_instance_find(id); if (!inst) { vty_out(vty, "No SS7 instance %d found%s", id, VTY_NEWLINE); @@ -504,15 +503,13 @@ } DEFUN(show_cs7_asp, show_cs7_asp_cmd, - "show cs7 asp [instance <0-15>]", - SHOW_STR CS7_STR "Application Server Process (ASP)\n") + "show cs7 instance <0-15> asp", + SHOW_STR CS7_STR INST_STR INST_STR "Application Server Process (ASP)\n") { struct osmo_ss7_instance *inst; struct osmo_ss7_asp *asp; - int id = 0; + int id = atoi(argv[0]); - if (argc > 0) - id = atoi(argv[0]); inst = osmo_ss7_instance_find(id); if (!inst) { vty_out(vty, "No SS7 instance %d found%s", id, VTY_NEWLINE); @@ -760,8 +757,8 @@ } DEFUN(show_cs7_as, show_cs7_as_cmd, - "show cs7 as (active|all|m3ua|sua) [instance <0-15>]", - SHOW_STR CS7_STR "Application Server (AS)\n" + "show cs7 instance <0-15> as (active|all|m3ua|sua)", + SHOW_STR CS7_STR INST_STR INST_STR "Application Server (AS)\n" "Display all active ASs\n" "Display all ASs (default)\n" "Display all m3ua ASs\n" @@ -769,14 +766,9 @@ { struct osmo_ss7_instance *inst; struct osmo_ss7_as *as; - const char *filter = NULL; - int id = 0; + const char *filter = argv[1]; + int id = atoi(argv[0]); - if (argc) - filter = argv[0]; - - if (argc > 1) - id = atoi(argv[1]); inst = osmo_ss7_instance_find(id); if (!inst) { vty_out(vty, "No SS7 instance %d found%s", id, VTY_NEWLINE); -- To view, visit https://gerrit.osmocom.org/2332 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I5c1050b0564791b5684619d3737d1cb6c4539d63 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Fri Apr 14 16:35:58 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 14 Apr 2017 16:35:58 +0000 Subject: libosmo-sccp[master]: Don't overwrite existing data in osmo_ss7_instance_find_or_c... In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2336 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I91b6aabdb873ed8dd103918ee5e40b7ad3946735 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Apr 14 16:36:06 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 14 Apr 2017 16:36:06 +0000 Subject: libosmo-sccp[master]: osmo_ss7_vty: Introduce xUA listener accept-asp-connections ... In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2337 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ic93b99047fb566cdb25a2f4139ebef54849dece9 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Apr 14 16:36:13 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 14 Apr 2017 16:36:13 +0000 Subject: libosmo-sccp[master]: osmo_ss7_vty: Fix config file writing for xUA listeners In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2338 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Iff6940ef6f52739b6f30a152487038cb0220da43 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Apr 14 16:36:15 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 14 Apr 2017 16:36:15 +0000 Subject: libosmo-sccp[master]: Add exampel osmo-stp configuration file In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2339 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I45a04dc808e5a419bf5d68eb28c48cbec352b318 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Apr 14 16:36:17 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 14 Apr 2017 16:36:17 +0000 Subject: libosmo-sccp[master]: stp: Add copyright notice In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2340 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I4e074f570eac2e6a0a761f9f5f9c35fa4afa0315 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Apr 14 16:36:19 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 14 Apr 2017 16:36:19 +0000 Subject: libosmo-sccp[master]: osmo-stp: Remove hack to always enable debug logging In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2341 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I7e0fb869bd778d8c276dc8afd16ecd7f1965b74a Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Apr 14 16:36:22 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 14 Apr 2017 16:36:22 +0000 Subject: libosmo-sccp[master]: osmo-stp: Add command line options and daemonize functionality In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2342 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I267fbe2e5c774960f0b63cfdd9f60df121b4934d Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Apr 14 16:36:24 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 14 Apr 2017 16:36:24 +0000 Subject: [MERGED] libosmo-sccp[master]: osmo-stp: Add command line options and daemonize functionality In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: osmo-stp: Add command line options and daemonize functionality ...................................................................... osmo-stp: Add command line options and daemonize functionality Change-Id: I267fbe2e5c774960f0b63cfdd9f60df121b4934d --- M stp/stp_main.c 1 file changed, 75 insertions(+), 6 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/stp/stp_main.c b/stp/stp_main.c index 5412223..3110ec4 100644 --- a/stp/stp_main.c +++ b/stp/stp_main.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -29,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -64,25 +66,82 @@ .is_config_node = osmo_ss7_is_config_node, }; +static struct { + bool daemonize; + const char *config_file; +} cmdline_config = { + .daemonize = false, + .config_file = "osmo-stp.cfg", +}; + +static void print_help(void) +{ + printf(" -h --help This text.\n"); + printf(" -D --daemonize Fork teh process into a background daemon\n"); + printf(" -c --config-file filename The config file to use. Default: ./osmo-stp.cfg\n"); + printf(" -V --version Print the version of OsmoSTP\n"); +} + +static void handle_options(int argc, char **argv) +{ + while (1) { + int option_index = 0, c; + static const struct option long_options[] = { + { "help", 0, 0, 'h' }, + { "daemonize", 0, 0, 'D' }, + { "config-file", 1, 0, 'c' }, + { "version", 0, 0, 'V' }, + { NULL, 0, 0, 0 } + }; + + c = getopt_long(argc, argv, "hDc:V", long_options, &option_index); + if (c == -1) + break; + + switch (c) { + case 'h': + print_help(); + exit(0); + break; + case 'D': + cmdline_config.daemonize = true; + break; + case 'c': + cmdline_config.config_file = optarg; + break; + case 'V': + print_version(1); + exit(0); + break; + default: + fprintf(stderr, "Error in command line options. Exiting\n"); + exit(1); + break; + } + } +} + int main(int argc, char **argv) { - char *config_file = "osmo-stp.cfg"; int rc; + + osmo_init_logging(&log_info); + vty_init(&vty_info); + + handle_options(argc, argv); fputs(stp_copyright, stdout); fputs("\n", stdout); - osmo_init_logging(&log_info); osmo_ss7_init(); osmo_fsm_log_addr(false); - vty_init(&vty_info); logging_vty_add_cmds(&log_info); osmo_ss7_vty_init_sg(); - rc = vty_read_config_file(config_file, NULL); + rc = vty_read_config_file(cmdline_config.config_file, NULL); if (rc < 0) { fprintf(stderr, "Failed to parse the config file '%s'\n", - config_file); + cmdline_config.config_file); exit(1); } @@ -92,7 +151,17 @@ exit(1); } + if (cmdline_config.daemonize) { + rc = osmo_daemonize(); + if (rc < 0) { + perror("Error during daemonize"); + exit(1); + } + } + while (1) { - osmo_select_main(0); + rc = osmo_select_main(0); + if (rc < 0) + exit(3); } } -- To view, visit https://gerrit.osmocom.org/2342 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I267fbe2e5c774960f0b63cfdd9f60df121b4934d Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Fri Apr 14 16:36:25 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 14 Apr 2017 16:36:25 +0000 Subject: [MERGED] libosmo-sccp[master]: osmo-stp: Remove hack to always enable debug logging In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: osmo-stp: Remove hack to always enable debug logging ...................................................................... osmo-stp: Remove hack to always enable debug logging ... and rather use the config file based logging configuration, like other osmocom programs, too. Change-Id: I7e0fb869bd778d8c276dc8afd16ecd7f1965b74a --- M doc/examples/osmo-stp.cfg M stp/stp_main.c 2 files changed, 13 insertions(+), 13 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/doc/examples/osmo-stp.cfg b/doc/examples/osmo-stp.cfg index 45a822b..960bf33 100644 --- a/doc/examples/osmo-stp.cfg +++ b/doc/examples/osmo-stp.cfg @@ -2,6 +2,15 @@ ! osmo-stp (0.0.6.3.179-b248) configuration saved from vty !! ! +log stderr + logging filter all 1 + logging color 1 + logging print category 1 + logging timestamp 0 + logging level lss7 debug + logging level lsccp debug + logging level lsua debug + logging level lm3ua debug line vty no login ! diff --git a/stp/stp_main.c b/stp/stp_main.c index 6fbc634..5412223 100644 --- a/stp/stp_main.c +++ b/stp/stp_main.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -38,6 +39,7 @@ #include #include +/* we only use logging sub-systems of the various libraries so far */ static const struct log_info_cat log_info_cat[] = { }; @@ -45,18 +47,6 @@ .cat = log_info_cat, .num_cat = ARRAY_SIZE(log_info_cat), }; - -/* Hack to enable debug logging for all relevant (used?) subsystems */ -static void init_logging(void) -{ - const int log_cats[] = { DLSS7, DLSUA, DLM3UA, DLSCCP, DLINP }; - unsigned int i; - - osmo_init_logging(&log_info); - - for (i = 0; i < ARRAY_SIZE(log_cats); i++) - log_set_category_filter(osmo_stderr_target, log_cats[i], 1, LOGL_DEBUG); -} static const char stp_copyright[] = "Copyright (C) 2015-2017 by Harald Welte \r\n" @@ -82,10 +72,11 @@ fputs(stp_copyright, stdout); fputs("\n", stdout); - init_logging(); + osmo_init_logging(&log_info); osmo_ss7_init(); osmo_fsm_log_addr(false); vty_init(&vty_info); + logging_vty_add_cmds(&log_info); osmo_ss7_vty_init_sg(); rc = vty_read_config_file(config_file, NULL); -- To view, visit https://gerrit.osmocom.org/2341 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I7e0fb869bd778d8c276dc8afd16ecd7f1965b74a Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Fri Apr 14 16:36:26 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 14 Apr 2017 16:36:26 +0000 Subject: [MERGED] libosmo-sccp[master]: stp: Add copyright notice In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: stp: Add copyright notice ...................................................................... stp: Add copyright notice Change-Id: I4e074f570eac2e6a0a761f9f5f9c35fa4afa0315 --- M stp/stp_main.c 1 file changed, 12 insertions(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/stp/stp_main.c b/stp/stp_main.c index 267806b..6fbc634 100644 --- a/stp/stp_main.c +++ b/stp/stp_main.c @@ -58,8 +58,17 @@ log_set_category_filter(osmo_stderr_target, log_cats[i], 1, LOGL_DEBUG); } +static const char stp_copyright[] = + "Copyright (C) 2015-2017 by Harald Welte \r\n" + "Contributions by Holger Freyther, Neels Hofmeyr\r\n" + "License GPLv2+: GNU GPL Version 2 or later \r\n" + "This is free software: you are free ot change and redistribute it.\r\n" + "There is NO WARRANTY, to the extent permitted by law.\r\n\r\n" + "Free Software lives by contribution. If you use this, please contribute!\r\n"; + static struct vty_app_info vty_info = { .name = "osmo-stp", + .copyright = stp_copyright, .version = PACKAGE_VERSION, .go_parent_cb = osmo_ss7_vty_go_parent, .is_config_node = osmo_ss7_is_config_node, @@ -70,6 +79,9 @@ char *config_file = "osmo-stp.cfg"; int rc; + fputs(stp_copyright, stdout); + fputs("\n", stdout); + init_logging(); osmo_ss7_init(); osmo_fsm_log_addr(false); -- To view, visit https://gerrit.osmocom.org/2340 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I4e074f570eac2e6a0a761f9f5f9c35fa4afa0315 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Fri Apr 14 16:36:26 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 14 Apr 2017 16:36:26 +0000 Subject: [MERGED] libosmo-sccp[master]: Add exampel osmo-stp configuration file In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: Add exampel osmo-stp configuration file ...................................................................... Add exampel osmo-stp configuration file Change-Id: I45a04dc808e5a419bf5d68eb28c48cbec352b318 --- M Makefile.am A doc/examples/osmo-stp.cfg 2 files changed, 12 insertions(+), 1 deletion(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/Makefile.am b/Makefile.am index ededdac..9bb711c 100644 --- a/Makefile.am +++ b/Makefile.am @@ -6,7 +6,7 @@ pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = libosmo-sccp.pc libosmo-mtp.pc libosmo-sigtran.pc libosmo-xua.pc -EXTRA_DIST = .version +EXTRA_DIST = .version doc/examples/osmo-stp.cfg BUILT_SOURCES = $(top_srcdir)/.version $(top_srcdir)/.version: diff --git a/doc/examples/osmo-stp.cfg b/doc/examples/osmo-stp.cfg new file mode 100644 index 0000000..45a822b --- /dev/null +++ b/doc/examples/osmo-stp.cfg @@ -0,0 +1,11 @@ +! +! osmo-stp (0.0.6.3.179-b248) configuration saved from vty +!! +! +line vty + no login +! +cs7 instance 0 + xua rkm routing-key-allocation dynamic-permitted + listen m3ua 2905 + accept-asp-connections dynamic-permitted -- To view, visit https://gerrit.osmocom.org/2339 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I45a04dc808e5a419bf5d68eb28c48cbec352b318 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Fri Apr 14 16:36:26 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 14 Apr 2017 16:36:26 +0000 Subject: [MERGED] libosmo-sccp[master]: osmo_ss7_vty: Fix config file writing for xUA listeners In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: osmo_ss7_vty: Fix config file writing for xUA listeners ...................................................................... osmo_ss7_vty: Fix config file writing for xUA listeners We so far generated un-parseable config files.. Change-Id: Iff6940ef6f52739b6f30a152487038cb0220da43 --- M src/osmo_ss7_vty.c 1 file changed, 1 insertion(+), 1 deletion(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/osmo_ss7_vty.c b/src/osmo_ss7_vty.c index e661623..08229dc 100644 --- a/src/osmo_ss7_vty.c +++ b/src/osmo_ss7_vty.c @@ -454,7 +454,7 @@ static void write_one_xua(struct vty *vty, struct osmo_xua_server *xs) { - vty_out(vty, " %s %u%s", + vty_out(vty, " listen %s %u%s", get_value_string(osmo_ss7_asp_protocol_vals, xs->cfg.proto), xs->cfg.local.port, VTY_NEWLINE); vty_out(vty, " local-ip %s%s", xs->cfg.local.host, VTY_NEWLINE); -- To view, visit https://gerrit.osmocom.org/2338 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Iff6940ef6f52739b6f30a152487038cb0220da43 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Fri Apr 14 16:36:26 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 14 Apr 2017 16:36:26 +0000 Subject: [MERGED] libosmo-sccp[master]: osmo_ss7_vty: Introduce xUA listener accept-asp-connections ... In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: osmo_ss7_vty: Introduce xUA listener accept-asp-connections command ...................................................................... osmo_ss7_vty: Introduce xUA listener accept-asp-connections command Using this command one can specify if ASP connections should be refused if there's no matching configuration, or whether ASPs should simply be create on-demand. Change-Id: Ic93b99047fb566cdb25a2f4139ebef54849dece9 --- M src/osmo_ss7_vty.c 1 file changed, 19 insertions(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/osmo_ss7_vty.c b/src/osmo_ss7_vty.c index 5dfa465..e661623 100644 --- a/src/osmo_ss7_vty.c +++ b/src/osmo_ss7_vty.c @@ -436,12 +436,30 @@ return CMD_SUCCESS; } +DEFUN(xua_accept_dyn_asp, xua_accept_dyn_asp_cmd, + "accept-asp-connections (pre-configured|dynamic-permitted)", + "Define what kind of ASP connections to accept\n" + "Accept only pre-confiugred ASPs (source IP/prt)\n" + "Accept any connection and dynamically create an ASP definition\n") +{ + struct osmo_xua_server *xs = vty->index; + + if (!strcmp(argv[0], "dynamic-permitted")) + xs->cfg.accept_dyn_reg = true; + else + xs->cfg.accept_dyn_reg = false; + + return CMD_SUCCESS; +} + static void write_one_xua(struct vty *vty, struct osmo_xua_server *xs) { vty_out(vty, " %s %u%s", get_value_string(osmo_ss7_asp_protocol_vals, xs->cfg.proto), xs->cfg.local.port, VTY_NEWLINE); vty_out(vty, " local-ip %s%s", xs->cfg.local.host, VTY_NEWLINE); + if (xs->cfg.accept_dyn_reg) + vty_out(vty, " accept-asp-connections dynamic-permitted%s", VTY_NEWLINE); } @@ -1007,6 +1025,7 @@ install_element(L_CS7_NODE, &cs7_xua_cmd); install_element(L_CS7_NODE, &no_cs7_xua_cmd); install_element(L_CS7_XUA_NODE, &xua_local_ip_cmd); + install_element(L_CS7_XUA_NODE, &xua_accept_dyn_asp_cmd); } void osmo_ss7_set_vty_alloc_ctx(void *ctx) -- To view, visit https://gerrit.osmocom.org/2337 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ic93b99047fb566cdb25a2f4139ebef54849dece9 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Fri Apr 14 16:36:26 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 14 Apr 2017 16:36:26 +0000 Subject: [MERGED] libosmo-sccp[master]: Don't overwrite existing data in osmo_ss7_instance_find_or_c... In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: Don't overwrite existing data in osmo_ss7_instance_find_or_create() ...................................................................... Don't overwrite existing data in osmo_ss7_instance_find_or_create() If we actually found an instance for the specified ID, return it fast and don't (re)initialize all linked list heads, etc. Change-Id: I91b6aabdb873ed8dd103918ee5e40b7ad3946735 --- M src/osmo_ss7.c 1 file changed, 4 insertions(+), 2 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index 27e56af..9b2377b 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -315,8 +315,10 @@ OSMO_ASSERT(ss7_initialized); inst = osmo_ss7_instance_find(id); - if (!inst) - inst = talloc_zero(ctx, struct osmo_ss7_instance); + if (inst) + return inst; + + inst = talloc_zero(ctx, struct osmo_ss7_instance); if (!inst) return NULL; -- To view, visit https://gerrit.osmocom.org/2336 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I91b6aabdb873ed8dd103918ee5e40b7ad3946735 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From admin at opensuse.org Fri Apr 14 20:06:36 2017 From: admin at opensuse.org (OBS Notification) Date: Fri, 14 Apr 2017 20:06:36 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in Debian_8.0/x86_64 In-Reply-To: References: Message-ID: <58f12be1ce8da_98f1156f846073dd@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/Debian_8.0/x86_64 Package network:osmocom:nightly/osmo-stp failed to build in Debian_8.0/x86_64 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 101s] CC vty_interface.o [ 101s] CC sctp_m3ua_client.o [ 102s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 102s] #include [ 102s] ^ [ 102s] compilation terminated. [ 102s] Makefile:475: recipe for target 'sctp_m3ua_client.o' failed [ 102s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 102s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 102s] Makefile:370: recipe for target 'all-recursive' failed [ 102s] make[2]: *** [all-recursive] Error 1 [ 102s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 102s] Makefile:310: recipe for target 'all' failed [ 102s] make[1]: *** [all] Error 2 [ 102s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 102s] dh_auto_build: make -j1 returned exit code 2 [ 102s] debian/rules:23: recipe for target 'build' failed [ 102s] make: *** [build] Error 2 [ 102s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 102s] [ 102s] lamb15 failed "build cellmgr-ng_1.4.7.20170414.dsc" at Fri Apr 14 20:06:24 UTC 2017. [ 102s] [ 102s] ### VM INTERACTION START ### [ 103s] Powering off. [ 103s] [ 90.243917] reboot: Power down [ 103s] ### VM INTERACTION END ### [ 103s] [ 103s] lamb15 failed "build cellmgr-ng_1.4.7.20170414.dsc" at Fri Apr 14 20:06:26 UTC 2017. [ 103s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Fri Apr 14 20:06:36 2017 From: admin at opensuse.org (OBS Notification) Date: Fri, 14 Apr 2017 20:06:36 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in xUbuntu_16.10/x86_64 In-Reply-To: References: Message-ID: <58f12be23628d_98f1156f84607467@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/xUbuntu_16.10/x86_64 Package network:osmocom:nightly/osmo-stp failed to build in xUbuntu_16.10/x86_64 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 114s] #warning "Notify any other AS(P) for failover scenario" [ 114s] ^~~~~~~ [ 115s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o vty_interface.o vty_interface.c [ 115s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o sctp_m3ua_client.o sctp_m3ua_client.c [ 115s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 115s] #include [ 115s] ^ [ 115s] compilation terminated. [ 115s] Makefile:485: recipe for target 'sctp_m3ua_client.o' failed [ 115s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 115s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 115s] Makefile:380: recipe for target 'all-recursive' failed [ 115s] make[2]: *** [all-recursive] Error 1 [ 115s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 115s] Makefile:321: recipe for target 'all' failed [ 115s] make[1]: *** [all] Error 2 [ 115s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 115s] dh_auto_build: make -j1 returned exit code 2 [ 115s] debian/rules:23: recipe for target 'build' failed [ 115s] make: *** [build] Error 2 [ 115s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 115s] [ 115s] lamb60 failed "build cellmgr-ng_1.4.7.20170414.dsc" at Fri Apr 14 20:06:23 UTC 2017. [ 115s] [ 115s] ### VM INTERACTION START ### [ 119s] ### VM INTERACTION END ### [ 119s] [ 119s] lamb60 failed "build cellmgr-ng_1.4.7.20170414.dsc" at Fri Apr 14 20:06:27 UTC 2017. [ 119s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Fri Apr 14 20:06:19 2017 From: admin at opensuse.org (OBS Notification) Date: Fri, 14 Apr 2017 20:06:19 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in Debian_8.0/i586 In-Reply-To: References: Message-ID: <58f12be07d8ac_98f1156f846072f4@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/Debian_8.0/i586 Package network:osmocom:nightly/osmo-stp failed to build in Debian_8.0/i586 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 97s] CC vty_interface.o [ 98s] CC sctp_m3ua_client.o [ 98s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 98s] #include [ 98s] ^ [ 98s] compilation terminated. [ 98s] Makefile:475: recipe for target 'sctp_m3ua_client.o' failed [ 98s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 98s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 98s] Makefile:370: recipe for target 'all-recursive' failed [ 98s] make[2]: *** [all-recursive] Error 1 [ 98s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 98s] Makefile:310: recipe for target 'all' failed [ 98s] make[1]: *** [all] Error 2 [ 98s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 98s] dh_auto_build: make -j1 returned exit code 2 [ 98s] debian/rules:23: recipe for target 'build' failed [ 98s] make: *** [build] Error 2 [ 98s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 98s] [ 98s] build84 failed "build cellmgr-ng_1.4.7.20170414.dsc" at Fri Apr 14 20:06:07 UTC 2017. [ 98s] [ 98s] ### VM INTERACTION START ### [ 99s] Powering off. [ 99s] [ 86.501369] reboot: Power down [ 100s] ### VM INTERACTION END ### [ 100s] [ 100s] build84 failed "build cellmgr-ng_1.4.7.20170414.dsc" at Fri Apr 14 20:06:10 UTC 2017. [ 100s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Fri Apr 14 20:07:45 2017 From: admin at opensuse.org (OBS Notification) Date: Fri, 14 Apr 2017 20:07:45 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in xUbuntu_16.04/i586 In-Reply-To: References: Message-ID: <58f12c1db47f1_9961156f846098be@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/xUbuntu_16.04/i586 Package network:osmocom:nightly/osmo-stp failed to build in xUbuntu_16.04/i586 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 81s] sctp_m2ua.c: In function 'm2ua_conn_destroy': [ 81s] sctp_m2ua.c:91:3: warning: #warning "Notify any other AS(P) for failover scenario" [-Wcpp] [ 81s] #warning "Notify any other AS(P) for failover scenario" [ 81s] ^ [ 81s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -c -o vty_interface.o vty_interface.c [ 82s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -c -o sctp_m3ua_client.o sctp_m3ua_client.c [ 82s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 82s] compilation terminated. [ 82s] Makefile:485: recipe for target 'sctp_m3ua_client.o' failed [ 82s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 82s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 82s] Makefile:380: recipe for target 'all-recursive' failed [ 82s] make[2]: *** [all-recursive] Error 1 [ 82s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 82s] Makefile:321: recipe for target 'all' failed [ 82s] make[1]: *** [all] Error 2 [ 82s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 82s] dh_auto_build: make -j1 returned exit code 2 [ 82s] debian/rules:23: recipe for target 'build' failed [ 82s] make: *** [build] Error 2 [ 82s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 82s] [ 82s] build82 failed "build cellmgr-ng_1.4.7.20170414.dsc" at Fri Apr 14 20:07:41 UTC 2017. [ 82s] [ 82s] ### VM INTERACTION START ### [ 85s] ### VM INTERACTION END ### [ 85s] [ 85s] build82 failed "build cellmgr-ng_1.4.7.20170414.dsc" at Fri Apr 14 20:07:44 UTC 2017. [ 85s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Fri Apr 14 20:09:29 2017 From: admin at opensuse.org (OBS Notification) Date: Fri, 14 Apr 2017 20:09:29 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in xUbuntu_16.10/i586 In-Reply-To: References: Message-ID: <58f12c9648df4_9961156f8461027f@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/xUbuntu_16.10/i586 Package network:osmocom:nightly/osmo-stp failed to build in xUbuntu_16.10/i586 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 163s] ^~~~~~~ [ 163s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o vty_interface.o vty_interface.c [ 164s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o sctp_m3ua_client.o sctp_m3ua_client.c [ 164s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 164s] #include [ 164s] ^ [ 164s] compilation terminated. [ 164s] Makefile:485: recipe for target 'sctp_m3ua_client.o' failed [ 164s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 164s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 164s] Makefile:380: recipe for target 'all-recursive' failed [ 164s] make[2]: *** [all-recursive] Error 1 [ 164s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 164s] Makefile:321: recipe for target 'all' failed [ 164s] make[1]: *** [all] Error 2 [ 164s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 164s] dh_auto_build: make -j1 returned exit code 2 [ 164s] debian/rules:23: recipe for target 'build' failed [ 164s] make: *** [build] Error 2 [ 164s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 164s] [ 164s] lamb69 failed "build cellmgr-ng_1.4.7.20170414.dsc" at Fri Apr 14 20:09:08 UTC 2017. [ 164s] [ 164s] ### VM INTERACTION START ### [ 167s] [ 141.992533] reboot: Power down [ 167s] ### VM INTERACTION END ### [ 167s] [ 167s] lamb69 failed "build cellmgr-ng_1.4.7.20170414.dsc" at Fri Apr 14 20:09:12 UTC 2017. [ 167s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Fri Apr 14 20:15:46 2017 From: admin at opensuse.org (OBS Notification) Date: Fri, 14 Apr 2017 20:15:46 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in xUbuntu_16.04/x86_64 In-Reply-To: References: Message-ID: <58f12e1e240e1_c7610b4f7c54065@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/xUbuntu_16.04/x86_64 Package network:osmocom:nightly/osmo-stp failed to build in xUbuntu_16.04/x86_64 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 329s] sctp_m2ua.c:91:3: warning: #warning "Notify any other AS(P) for failover scenario" [-Wcpp] [ 329s] #warning "Notify any other AS(P) for failover scenario" [ 329s] ^ [ 330s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -c -o vty_interface.o vty_interface.c [ 331s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -c -o sctp_m3ua_client.o sctp_m3ua_client.c [ 331s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 331s] compilation terminated. [ 331s] Makefile:485: recipe for target 'sctp_m3ua_client.o' failed [ 331s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 331s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 331s] Makefile:380: recipe for target 'all-recursive' failed [ 331s] make[2]: *** [all-recursive] Error 1 [ 331s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 331s] Makefile:321: recipe for target 'all' failed [ 331s] make[1]: *** [all] Error 2 [ 331s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 331s] dh_auto_build: make -j1 returned exit code 2 [ 331s] debian/rules:23: recipe for target 'build' failed [ 331s] make: *** [build] Error 2 [ 331s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 331s] [ 331s] cloud116 failed "build cellmgr-ng_1.4.7.20170414.dsc" at Fri Apr 14 20:15:28 UTC 2017. [ 331s] [ 331s] ### VM INTERACTION START ### [ 334s] [ 302.266407] reboot: Power down [ 336s] ### VM INTERACTION END ### [ 336s] [ 336s] cloud116 failed "build cellmgr-ng_1.4.7.20170414.dsc" at Fri Apr 14 20:15:33 UTC 2017. [ 336s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From gerrit-no-reply at lists.osmocom.org Fri Apr 14 20:30:01 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 14 Apr 2017 20:30:01 +0000 Subject: [PATCH] libosmo-sccp[master]: osmo_ss7_vty: Don't save dynamically generated AS / ASP Message-ID: Review at https://gerrit.osmocom.org/2343 osmo_ss7_vty: Don't save dynamically generated AS / ASP If RKM has dynamically generated some AS definitions on the fly, or if we accepted auto-creation of ASPs on SCTP connect time, then we don't wnat to save such objects during vty config file store. Change-Id: I9d0b0b61737a30b9d6e76cecbe42ec071bcddeeb --- M src/osmo_ss7_vty.c 1 file changed, 9 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/43/2343/1 diff --git a/src/osmo_ss7_vty.c b/src/osmo_ss7_vty.c index 08229dc..b08a456 100644 --- a/src/osmo_ss7_vty.c +++ b/src/osmo_ss7_vty.c @@ -592,6 +592,11 @@ static void write_one_asp(struct vty *vty, struct osmo_ss7_asp *asp) { + /* skip any dynamically created ASPs (auto-created at connect + * time) */ + if (asp->dyn_allocated) + return; + vty_out(vty, " asp %s %u %u %s%s", asp->cfg.name, asp->cfg.remote.port, asp->cfg.local.port, osmo_ss7_asp_protocol_name(asp->cfg.proto), VTY_NEWLINE); @@ -787,6 +792,10 @@ struct osmo_ss7_routing_key *rkey; unsigned int i; + /* skip any dynamically allocated AS definitions */ + if (as->rkm_dyn_allocated) + return; + vty_out(vty, " as %s %s%s", as->cfg.name, osmo_ss7_asp_protocol_name(as->cfg.proto), VTY_NEWLINE); if (as->cfg.description) -- To view, visit https://gerrit.osmocom.org/2343 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I9d0b0b61737a30b9d6e76cecbe42ec071bcddeeb Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Fri Apr 14 20:30:02 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 14 Apr 2017 20:30:02 +0000 Subject: [PATCH] libosmo-sccp[master]: sccp_scoc: Memorize if a connection is incoming or outbound Message-ID: Review at https://gerrit.osmocom.org/2344 sccp_scoc: Memorize if a connection is incoming or outbound This is not really needed by the state machines internally, so we have to artificially add it to the sccp_connection. We don't use it yet, but upcoming code for VTY introspection of SCCP connections will be able to use it. Change-Id: Ic3c85152665abfb613e197b098c97392d16d16bf --- M src/sccp_scoc.c 1 file changed, 4 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/44/2344/1 diff --git a/src/sccp_scoc.c b/src/sccp_scoc.c index 4bf340d..8621e6d 100644 --- a/src/sccp_scoc.c +++ b/src/sccp_scoc.c @@ -102,6 +102,9 @@ uint32_t sccp_class; uint32_t release_cause; /* WAIT_CONN_CONF */ + /* incoming (true) or outgoing (false) */ + bool incoming; + /* Osmo FSM Instance of sccp_scoc_fsm */ struct osmo_fsm_inst *fi; @@ -1514,6 +1517,7 @@ /* Allocate new connection */ conn = conn_create(inst); conn->user = scu; + conn->incoming = true; } else { uint32_t conn_id; /* Resolve existing connection */ -- To view, visit https://gerrit.osmocom.org/2344 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ic3c85152665abfb613e197b098c97392d16d16bf Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Fri Apr 14 20:30:03 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 14 Apr 2017 20:30:03 +0000 Subject: [PATCH] libosmo-sccp[master]: SCCP: Add VTY interface for SCCP Message-ID: Review at https://gerrit.osmocom.org/2345 SCCP: Add VTY interface for SCCP Change-Id: I100daaa947dbab6a4528c4e9fbd0d30790288f63 --- M include/osmocom/sigtran/sccp_sap.h M src/Makefile.am M src/osmo_ss7_vty.c M src/sccp_internal.h M src/sccp_scoc.c A src/sccp_vty.c M src/xua_internal.h M tests/ss7/Makefile.am M tests/xua/Makefile.am 9 files changed, 202 insertions(+), 8 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/45/2345/1 diff --git a/include/osmocom/sigtran/sccp_sap.h b/include/osmocom/sigtran/sccp_sap.h index fd25752..f378e5c 100644 --- a/include/osmocom/sigtran/sccp_sap.h +++ b/include/osmocom/sigtran/sccp_sap.h @@ -227,6 +227,8 @@ struct osmo_sccp_instance; struct osmo_sccp_user; +void osmo_sccp_vty_init(void); + struct osmo_sccp_instance * osmo_sccp_instance_create(struct osmo_ss7_instance *ss7, void *priv); void osmo_sccp_instance_destroy(struct osmo_sccp_instance *inst); diff --git a/src/Makefile.am b/src/Makefile.am index 8e52792..217f2f7 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -30,6 +30,6 @@ sccp2sua.c sccp_scrc.c sccp_sclc.c sccp_scoc.c \ sccp_user.c xua_rkm.c xua_default_lm_fsm.c \ osmo_ss7.c osmo_ss7_hmrt.c xua_asp_fsm.c xua_as_fsm.c \ - osmo_ss7_vty.c + osmo_ss7_vty.c sccp_vty.c libosmo_sigtran_la_LDFLAGS = -version-info $(LIBVERSION) -no-undefined -export-symbols-regex '^osmo_' libosmo_sigtran_la_LIBADD = $(LIBOSMOCORE_LIBS) $(LIBOSMONETIF_LIBS) $(LIBSCTP_LIBS) diff --git a/src/osmo_ss7_vty.c b/src/osmo_ss7_vty.c index b08a456..c2ad25c 100644 --- a/src/osmo_ss7_vty.c +++ b/src/osmo_ss7_vty.c @@ -35,9 +35,7 @@ #include #include -#define CS7_STR "ITU-T Signaling System 7\n" -#define PC_STR "Point Code\n" -#define INST_STR "An instance of the SS7 stack\n" +#include "xua_internal.h" /*********************************************************************** * Core CS7 Configuration diff --git a/src/sccp_internal.h b/src/sccp_internal.h index c35ef4b..17dda13 100644 --- a/src/sccp_internal.h +++ b/src/sccp_internal.h @@ -87,3 +87,5 @@ struct msgb *sccp_msgb_alloc(const char *name); struct osmo_fsm sccp_scoc_fsm; + +void sccp_scoc_show_connections(struct vty *vty, struct osmo_sccp_instance *inst); diff --git a/src/sccp_scoc.c b/src/sccp_scoc.c index 8621e6d..6d9916b 100644 --- a/src/sccp_scoc.c +++ b/src/sccp_scoc.c @@ -1649,3 +1649,42 @@ llist_for_each_entry_safe(conn, conn2, &inst->connections, list) conn_destroy(conn); } + +#include + +static void vty_show_connection(struct vty *vty, struct sccp_connection *conn) +{ + struct osmo_ss7_instance *s7i = conn->inst->ss7; + struct osmo_sccp_addr *remote_addr; + uint32_t local_pc; + + if (conn->user->pc_valid) + local_pc = conn->user->pc; + else + local_pc = s7i->cfg.primary_pc; + + if (conn->incoming) + remote_addr = &conn->calling_addr; + else + remote_addr = &conn->called_addr; + + vty_out(vty, "%c %06x %3u %7s ", conn->incoming ? 'I' : 'O', + conn->conn_id, conn->user->ssn, + osmo_ss7_pointcode_print(s7i, local_pc)); + vty_out(vty, "%16s %06x %3u %7s%s", + osmo_fsm_inst_state_name(conn->fi), conn->remote_ref, remote_addr->ssn, + osmo_ss7_pointcode_print(s7i, conn->remote_pc), + VTY_NEWLINE); +} + +void sccp_scoc_show_connections(struct vty *vty, struct osmo_sccp_instance *inst) +{ + struct sccp_connection *conn; + + vty_out(vty, "I Local Conn. Remote %s", VTY_NEWLINE); + vty_out(vty, "O Ref SSN PC State Ref SSN PC %s", VTY_NEWLINE); + vty_out(vty, "- ------ --- ------- ---------------- ------ --- -------%s", VTY_NEWLINE); + + llist_for_each_entry(conn, &inst->connections, list) + vty_show_connection(vty, conn); +} diff --git a/src/sccp_vty.c b/src/sccp_vty.c new file mode 100644 index 0000000..626fefb --- /dev/null +++ b/src/sccp_vty.c @@ -0,0 +1,149 @@ +/* Core SS7 Instance/Linkset/Link/AS/ASP VTY Interface */ + +/* (C) 2015-2017 by Harald Welte + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include "xua_internal.h" +#include "sccp_internal.h" + +static void show_user(struct vty *vty, struct osmo_sccp_user *user) +{ + struct osmo_sccp_instance *sccp = user->inst; + + if (user->pc_valid) + vty_out(vty, "SSN %3u %7s : %s%s", user->ssn, + osmo_ss7_pointcode_print(sccp->ss7, user->pc), + user->name, VTY_NEWLINE); + else + vty_out(vty, "SSN %3u ANY : %s%s", user->ssn, user->name, VTY_NEWLINE); +} + +DEFUN(show_sccp_users, show_sccp_users_cmd, + "show cs7 instance <0-15> sccp users", + SHOW_STR CS7_STR INST_STR INST_STR + "Signaling Connection Control Part\n" + "Show List of SCCP Users registered\n") +{ + int id = atoi(argv[0]); + struct osmo_ss7_instance *inst; + struct osmo_sccp_instance *sccp; + struct osmo_sccp_user *scu; + + inst = osmo_ss7_instance_find(id); + if (!inst) { + vty_out(vty, "No SS7 instance %d found%s", id, VTY_NEWLINE); + return CMD_WARNING; + } + + sccp = inst->sccp; + if (!sccp) { + vty_out(vty, "SS7 instance %d has no SCCP%s", id, VTY_NEWLINE); + return CMD_WARNING; + }; + + llist_for_each_entry(scu, &sccp->users, list) + show_user(vty, scu); + + return CMD_SUCCESS; +} + +DEFUN(show_sccp_user_ssn, show_sccp_user_ssn_cmd, + "show cs7 instance <0-15> sccp ssn <0-65535>", + SHOW_STR CS7_STR INST_STR INST_STR + "Signaling Connection Control Part\n" + "Show List of SCCP Users registered\n") +{ + int id = atoi(argv[0]); + int ssn = atoi(argv[1]); + struct osmo_ss7_instance *inst; + struct osmo_sccp_instance *sccp; + struct osmo_sccp_user *scu; + + inst = osmo_ss7_instance_find(id); + if (!inst) { + vty_out(vty, "No SS7 instance %d found%s", id, VTY_NEWLINE); + return CMD_WARNING; + } + + sccp = inst->sccp; + if (!sccp) { + vty_out(vty, "SS7 instance %d has no SCCP%s", id, VTY_NEWLINE); + return CMD_WARNING; + }; + + scu = sccp_user_find(sccp, ssn, 0); + if (!scu) { + vty_out(vty, "Can't find SCCP User in instance %d%s", id, VTY_NEWLINE); + return CMD_WARNING; + } + + show_user(vty, scu); + + return CMD_SUCCESS; +} + +DEFUN(show_sccp_connections, show_sccp_connections_cmd, + "show cs7 instance <0-15> sccp connections", + SHOW_STR CS7_STR INST_STR INST_STR + "Signaling Connection Control Part\n" + "Show List of SCCP Users registered\n") +{ + int id = atoi(argv[0]); + struct osmo_ss7_instance *inst; + struct osmo_sccp_instance *sccp; + + inst = osmo_ss7_instance_find(id); + if (!inst) { + vty_out(vty, "No SS7 instance %d found%s", id, VTY_NEWLINE); + return CMD_WARNING; + } + + sccp = inst->sccp; + if (!sccp) { + vty_out(vty, "SS7 instance %d has no SCCP%s", id, VTY_NEWLINE); + return CMD_WARNING; + }; + + sccp_scoc_show_connections(vty, sccp); + + return CMD_SUCCESS; +} + +void osmo_sccp_vty_init(void) +{ + install_element_ve(&show_sccp_users_cmd); + install_element_ve(&show_sccp_user_ssn_cmd); + install_element_ve(&show_sccp_connections_cmd); +} diff --git a/src/xua_internal.h b/src/xua_internal.h index b291703..31c941e 100644 --- a/src/xua_internal.h +++ b/src/xua_internal.h @@ -60,3 +60,7 @@ extern struct osmo_fsm xua_default_lm_fsm; extern const struct value_string m3ua_rkm_reg_status_vals[]; extern const struct value_string m3ua_rkm_dereg_status_vals[]; + +#define CS7_STR "ITU-T Signaling System 7\n" +#define PC_STR "Point Code\n" +#define INST_STR "An instance of the SS7 stack\n" diff --git a/tests/ss7/Makefile.am b/tests/ss7/Makefile.am index bc81915..3b6cb2c 100644 --- a/tests/ss7/Makefile.am +++ b/tests/ss7/Makefile.am @@ -1,9 +1,9 @@ AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -Wall -AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) +AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOVTY_CFLAGS) AM_LDFLAGS = -static LDADD = $(top_builddir)/src/libosmo-sigtran.la \ - $(LIBOSMOCORE_LIBS) $(LIBOSMONETIF_LIBS) $(LIBSCTP_LIBS) + $(LIBOSMOCORE_LIBS) $(LIBOSMOVTY_LIBS) $(LIBOSMONETIF_LIBS) $(LIBSCTP_LIBS) EXTRA_DIST = ss7_test.ok ss7_test.err diff --git a/tests/xua/Makefile.am b/tests/xua/Makefile.am index 8a75e6c..c6a9955 100644 --- a/tests/xua/Makefile.am +++ b/tests/xua/Makefile.am @@ -1,9 +1,9 @@ AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -Wall -AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) +AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOVTY_CFLAGS) AM_LDFLAGS = -static LDADD = $(top_builddir)/src/libosmo-sigtran.la \ - $(LIBOSMOCORE_LIBS) $(LIBOSMONETIF_LIBS) $(LIBSCTP_LIBS) + $(LIBOSMOCORE_LIBS) $(LIBOSMOVTY_LIBS) $(LIBOSMONETIF_LIBS) $(LIBSCTP_LIBS) EXTRA_DIST = xua_test.ok -- To view, visit https://gerrit.osmocom.org/2345 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I100daaa947dbab6a4528c4e9fbd0d30790288f63 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Fri Apr 14 20:30:03 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 14 Apr 2017 20:30:03 +0000 Subject: [PATCH] libosmo-sccp[master]: m3ua_example: Add SS7 and SCCP VTY Message-ID: Review at https://gerrit.osmocom.org/2346 m3ua_example: Add SS7 and SCCP VTY Change-Id: Id03d2f94d22445ada01917356a5ec5a8e4fa3fca --- M examples/m3ua_example.c 1 file changed, 2 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/46/2346/1 diff --git a/examples/m3ua_example.c b/examples/m3ua_example.c index d1247f5..d3c6a7c 100644 --- a/examples/m3ua_example.c +++ b/examples/m3ua_example.c @@ -92,6 +92,8 @@ osmo_ss7_init(); osmo_fsm_log_addr(false); vty_init(&vty_info); + osmo_ss7_vty_init_asp(); + osmo_sccp_vty_init(); if (argc <= 1) client = true; -- To view, visit https://gerrit.osmocom.org/2346 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Id03d2f94d22445ada01917356a5ec5a8e4fa3fca Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Fri Apr 14 20:30:04 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 14 Apr 2017 20:30:04 +0000 Subject: [PATCH] libosmo-sccp[master]: ss7_vty: don't re-define xUA dialect strings Message-ID: Review at https://gerrit.osmocom.org/2347 ss7_vty: don't re-define xUA dialect strings If we add more xUA variants/protocols, we want to avoid having to touch too many parts of the code with copy+pasted strings. Change-Id: I085b884d98fb4c45ac15910a8ebf82b91e861fd4 --- M src/osmo_ss7_vty.c 1 file changed, 15 insertions(+), 12 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/47/2347/1 diff --git a/src/osmo_ss7_vty.c b/src/osmo_ss7_vty.c index c2ad25c..a05d74f 100644 --- a/src/osmo_ss7_vty.c +++ b/src/osmo_ss7_vty.c @@ -37,6 +37,13 @@ #include "xua_internal.h" +#define XUA_VAR_STR "(sua|m3ua)" + +#define XUA_VAR_HELP_STR \ + "SCCP User Adaptation\n" \ + "MTP3 User Adaptation\n" + + /*********************************************************************** * Core CS7 Configuration ***********************************************************************/ @@ -380,12 +387,10 @@ 1, }; -#define XUA_STR "SCCP User Adaptation\n" "MTP3 User Adaptation\n" - DEFUN(cs7_xua, cs7_xua_cmd, - "listen (sua|m3ua) <0-65534>", + "listen " XUA_VAR_STR " <0-65534>", "Configure/Enable xUA Listener\n" - XUA_STR "SCTP Port number\n") + XUA_VAR_HELP_STR "SCTP Port number\n") { struct osmo_ss7_instance *inst = vty->index; struct osmo_xua_server *xs; @@ -405,9 +410,9 @@ } DEFUN(no_cs7_xua, no_cs7_xua_cmd, - "no listen (sua|m3ua) <0-65534>", + "no listen " XUA_VAR_STR " <0-65534>", NO_STR "Disable xUA Listener on given SCTP Port\n" - XUA_STR "SCTP Port number\n") + XUA_VAR_HELP_STR "SCTP Port number\n") { struct osmo_ss7_instance *inst = vty->index; struct osmo_xua_server *xs; @@ -472,13 +477,12 @@ }; DEFUN(cs7_asp, cs7_asp_cmd, - "asp NAME <0-65535> <0-65535> (m3ua|sua)", + "asp NAME <0-65535> <0-65535> " XUA_VAR_STR, "Configure Application Server Process\n" "Name of ASP\n" "Remote SCTP port number\n" "Local SCTP port number\n" - "M3UA Protocol\n" - "SUA Protocol\n") + XUA_VAR_HELP_STR) { struct osmo_ss7_instance *inst = vty->index; const char *name = argv[0]; @@ -617,11 +621,10 @@ }; DEFUN(cs7_as, cs7_as_cmd, - "as NAME (m3ua|sua)", + "as NAME " XUA_VAR_STR, "Configure an Application Server\n" "Name of the Application Server\n" - "M3UA Application Server\n" - "SUA Application Server\n") + XUA_VAR_HELP_STR) { struct osmo_ss7_instance *inst = vty->index; struct osmo_ss7_as *as; -- To view, visit https://gerrit.osmocom.org/2347 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I085b884d98fb4c45ac15910a8ebf82b91e861fd4 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Fri Apr 14 20:30:04 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 14 Apr 2017 20:30:04 +0000 Subject: [PATCH] libosmo-sccp[master]: osmo_ss7_vty: Print AS and ASP state names during 'show' Message-ID: Review at https://gerrit.osmocom.org/2348 osmo_ss7_vty: Print AS and ASP state names during 'show' Change-Id: I6a06d93d6e6c0386676742d6d19f5483a46d7fba --- M src/osmo_ss7_vty.c 1 file changed, 10 insertions(+), 10 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/48/2348/1 diff --git a/src/osmo_ss7_vty.c b/src/osmo_ss7_vty.c index a05d74f..8356d16 100644 --- a/src/osmo_ss7_vty.c +++ b/src/osmo_ss7_vty.c @@ -579,13 +579,13 @@ return CMD_WARNING; } - vty_out(vty, " Effect Primary%s", VTY_NEWLINE); - vty_out(vty, "ASP Name AS Name State Type Rmt Port Remote IP Addr SCTP%s", VTY_NEWLINE); - vty_out(vty, "------------ ------------ -------- ---- -------- --------------- ----------%s", VTY_NEWLINE); + vty_out(vty, " Effect Primary%s", VTY_NEWLINE); + vty_out(vty, "ASP Name AS Name State Type Rmt Port Remote IP Addr SCTP%s", VTY_NEWLINE); + vty_out(vty, "------------ ------------ ------------- ---- -------- --------------- ----------%s", VTY_NEWLINE); llist_for_each_entry(asp, &inst->asp_list, list) { - vty_out(vty, "%-12s %-12s %-8s %-4s %-8u %-15s %-10s%s", - asp->cfg.name, "?", "?", + vty_out(vty, "%-12s %-12s %-13s %-4s %-8u %-15s %-10s%s", + asp->cfg.name, "?", osmo_fsm_inst_state_name(asp->fi), get_value_string(osmo_ss7_asp_protocol_vals, asp->cfg.proto), asp->cfg.remote.port, asp->cfg.remote.host, "", VTY_NEWLINE); } @@ -846,9 +846,9 @@ return CMD_WARNING; } - vty_out(vty, " Routing Routing Key Cic Cic%s", VTY_NEWLINE); - vty_out(vty, "AS Name State Context Dpc Si Opc Ssn Min Max%s", VTY_NEWLINE); - vty_out(vty, "------------ ------ ---------- ------------- ---- ------------- --- ----- -----%s", VTY_NEWLINE); + vty_out(vty, " Routing Routing Key Cic Cic%s", VTY_NEWLINE); + vty_out(vty, "AS Name State Context Dpc Si Opc Ssn Min Max%s", VTY_NEWLINE); + vty_out(vty, "------------ ------------ ---------- ------------- ---- ------------- --- ----- -----%s", VTY_NEWLINE); llist_for_each_entry(as, &inst->as_list, list) { if (filter && !strcmp(filter, "m3ua") && as->cfg.proto != OSMO_SS7_ASP_PROT_M3UA) @@ -856,8 +856,8 @@ if (filter && !strcmp(filter, "sua") && as->cfg.proto != OSMO_SS7_ASP_PROT_SUA) continue; /* FIXME: active filter */ - vty_out(vty, "%-12s %-6s %-10u %-13s %4s %13s %3s %5s %4s%s", - as->cfg.name, "fixme", as->cfg.routing_key.context, + vty_out(vty, "%-12s %-12s %-10u %-13s %4s %13s %3s %5s %4s%s", + as->cfg.name, osmo_fsm_inst_state_name(as->fi), as->cfg.routing_key.context, osmo_ss7_pointcode_print(as->inst, as->cfg.routing_key.pc), "", "", "", "", "", VTY_NEWLINE); } -- To view, visit https://gerrit.osmocom.org/2348 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I6a06d93d6e6c0386676742d6d19f5483a46d7fba Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Fri Apr 14 20:30:04 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 14 Apr 2017 20:30:04 +0000 Subject: [PATCH] libosmo-sccp[master]: SUA/M3UA: Implement T(r) recovery timer of Application Serve... Message-ID: Review at https://gerrit.osmocom.org/2349 SUA/M3UA: Implement T(r) recovery timer of Application Server FSM When an AS goes "down" it first entres a recovery state, in which any to-be-transmitted messages are enqueued until the timer T(r) expires. Once the timer expires, the messages are discarded. If the AS goes ACTIVE before timer expiration, queued messages are sent. Change-Id: I22725bf35306299a00c66d7b3637f5e198c26247 --- M src/m3ua.c M src/sua.c M src/xua_as_fsm.c M src/xua_as_fsm.h 4 files changed, 145 insertions(+), 43 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/49/2349/1 diff --git a/src/m3ua.c b/src/m3ua.c index 7dc2afb..a7ef06c 100644 --- a/src/m3ua.c +++ b/src/m3ua.c @@ -39,6 +39,7 @@ #include #include +#include "xua_as_fsm.h" #include "xua_asp_fsm.h" #include "xua_internal.h" @@ -420,16 +421,14 @@ * Transmitting M3UA messsages to SCTP ***********************************************************************/ -/* transmit given xua_msg via given ASP. callee takes xua ownership */ -static int m3ua_tx_xua_asp(struct osmo_ss7_asp *asp, struct xua_msg *xua) +/* Convert M3UA from xua_msg to msgb and set PPID/stream */ +static struct msgb *m3ua_to_msg(struct xua_msg *xua) { struct msgb *msg = xua_to_msg(M3UA_VERSION, xua); - OSMO_ASSERT(asp->cfg.proto == OSMO_SS7_ASP_PROT_M3UA); - if (!msg) { LOGP(DLM3UA, LOGL_ERROR, "Error encoding M3UA Msg\n"); - return -1; + return NULL; } if (xua->hdr.msg_class == M3UA_MSGC_XFER) @@ -437,6 +436,20 @@ else msgb_sctp_stream(msg) = 0; msgb_sctp_ppid(msg) = M3UA_PPID; + + return msg; +} + +/* transmit given xua_msg via given ASP */ +static int m3ua_tx_xua_asp(struct osmo_ss7_asp *asp, struct xua_msg *xua) +{ + struct msgb *msg = m3ua_to_msg(xua); + + OSMO_ASSERT(asp->cfg.proto == OSMO_SS7_ASP_PROT_M3UA); + + if (!msg) + return -1; + return osmo_ss7_asp_send(asp, msg); } @@ -446,8 +459,8 @@ * \return 0 on success; negative on error */ int m3ua_tx_xua_as(struct osmo_ss7_as *as, struct xua_msg *xua) { - struct osmo_ss7_asp *asp; - unsigned int i; + struct msgb *msg; + int rc; OSMO_ASSERT(as->cfg.proto == OSMO_SS7_ASP_PROT_M3UA); @@ -455,19 +468,16 @@ if (as->cfg.routing_key.context) xua_msg_add_u32(xua, M3UA_IEI_ROUTE_CTX, as->cfg.routing_key.context); - for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) { - asp = as->cfg.asps[i]; - if (!asp) - continue; - if (asp) - break; - } - if (!asp) { - LOGP(DLM3UA, LOGL_ERROR, "No ASP entroy in AS, dropping message\n"); - return -ENODEV; - } + msg = m3ua_to_msg(xua); + if (!msg) + return -1; - return m3ua_tx_xua_asp(asp, xua); + /* send the msg to the AS for transmission. The AS FSM might + * (depending on its state) enqueue it before trnsmission */ + rc = osmo_fsm_inst_dispatch(as->fi, XUA_AS_E_TRANSFER_REQ, msg); + if (rc < 0) + msgb_free(msg); + return rc; } /*********************************************************************** diff --git a/src/sua.c b/src/sua.c index 3bff855..97a0785 100644 --- a/src/sua.c +++ b/src/sua.c @@ -40,6 +40,7 @@ #include #include +#include "xua_as_fsm.h" #include "xua_asp_fsm.h" #include "xua_internal.h" #include "sccp_internal.h" @@ -252,18 +253,38 @@ * Transmitting SUA messsages to SCTP ***********************************************************************/ -static int sua_tx_xua_asp(struct osmo_ss7_asp *asp, struct xua_msg *xua) +static struct msgb *sua_to_msg(struct xua_msg *xua) { struct msgb *msg = xua_to_msg(SUA_VERSION, xua); - OSMO_ASSERT(asp->cfg.proto == OSMO_SS7_ASP_PROT_SUA); - if (!msg) { - LOGPASP(asp, DLSUA, LOGL_ERROR, "Error encoding SUA Msg\n"); - return -1; + LOGP(DLSUA, LOGL_ERROR, "Error encoding SUA Msg\n"); + return NULL; } + switch (xua->hdr.msg_class) { + case SUA_MSGC_CL: + case SUA_MSGC_CO: + msgb_sctp_stream(msg) = 1; + break; + default: + msgb_sctp_stream(msg) = 0; + break; + } msgb_sctp_ppid(msg) = SUA_PPID; + + return msg; +} + +static int sua_tx_xua_asp(struct osmo_ss7_asp *asp, struct xua_msg *xua) +{ + struct msgb *msg = sua_to_msg(xua); + + OSMO_ASSERT(asp->cfg.proto == OSMO_SS7_ASP_PROT_SUA); + + if (!msg) + return -1; + return osmo_ss7_asp_send(asp, msg); } @@ -273,25 +294,25 @@ * \return 0 on success; negative on error */ int sua_tx_xua_as(struct osmo_ss7_as *as, struct xua_msg *xua) { - struct osmo_ss7_asp *asp; - unsigned int i; + struct msgb *msg; + int rc; OSMO_ASSERT(as->cfg.proto == OSMO_SS7_ASP_PROT_SUA); - /* FIXME: Select ASP within AS depending on traffic mode */ - for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) { - asp = as->cfg.asps[i]; - if (!asp) - continue; - if (asp) - break; - } - if (!asp) { - LOGP(DLSUA, LOGL_ERROR, "No ASP in AS, dropping message\n"); - return -ENODEV; - } + /* Add RC for this AS */ + if (as->cfg.routing_key.context) + xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, as->cfg.routing_key.context); - return sua_tx_xua_asp(asp, xua); + msg = sua_to_msg(xua); + if (!msg) + return -1; + + /* send the msg to the AS for transmission. The AS FSM might + * (depending on its state) enqueue it before trnsmission */ + rc = osmo_fsm_inst_dispatch(as->fi, XUA_AS_E_TRANSFER_REQ, msg); + if (rc < 0) + msgb_free(msg); + return rc; } /*********************************************************************** diff --git a/src/xua_as_fsm.c b/src/xua_as_fsm.c index 740070b..cbbd85b 100644 --- a/src/xua_as_fsm.c +++ b/src/xua_as_fsm.c @@ -65,12 +65,39 @@ return sent; } +/* actually transmit a message through this AS */ +static int xua_as_transmit_msg(struct osmo_ss7_as *as, struct msgb *msg) +{ + struct osmo_ss7_asp *asp; + unsigned int i; + + /* FIXME: proper selection of the ASP based on the SLS and the + * traffic mode type! */ + for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) { + asp = as->cfg.asps[i]; + if (!asp) + continue; + if (asp) + break; + } + + if (!asp) { + LOGPFSM(as->fi, "No ASP in AS, dropping message\n"); + msgb_free(msg); + return -1; + } + + return osmo_ss7_asp_send(asp, msg); +} + /*********************************************************************** * Actual FSM ***********************************************************************/ #define S(x) (1 << (x)) + +#define MSEC_TO_S_US(x) (x/1000), ((x%1000)*10) enum xua_as_state { XUA_AS_S_DOWN, @@ -88,6 +115,10 @@ struct xua_as_fsm_priv { struct osmo_ss7_as *as; + struct { + struct osmo_timer_list t_r; + struct llist_head queued_msgs; + } recovery; }; /* is any other ASP in this AS in state != DOWN? */ @@ -130,6 +161,11 @@ return false; } +static void t_r_callback(void *_fi) +{ + struct osmo_fsm_inst *fi = _fi; + osmo_fsm_inst_dispatch(fi, XUA_AS_E_RECOVERY_EXPD, NULL); +} static void xua_as_fsm_down(struct osmo_fsm_inst *fi, uint32_t event, void *data) { @@ -205,16 +241,20 @@ static void xua_as_fsm_active(struct osmo_fsm_inst *fi, uint32_t event, void *data) { struct xua_as_fsm_priv *xafp = (struct xua_as_fsm_priv *) fi->priv; - struct osmo_ss7_asp *asp = data; + struct osmo_ss7_asp *asp; + struct msgb *msg; switch (event) { case XUA_ASPAS_ASP_DOWN_IND: case XUA_ASPAS_ASP_INACTIVE_IND: + asp = data; if (check_any_other_asp_in_active(xafp->as, asp)) { /* ignore, we stay AS_ACTIVE */ } else { + uint32_t recovery_msec = xafp->as->cfg.recovery_timeout_msec; osmo_fsm_inst_state_chg(fi, XUA_AS_S_PENDING, 0, 0); - /* FIXME: Start T(r) */ + /* Start T(r) */ + osmo_timer_schedule(&xafp->recovery.t_r, MSEC_TO_S_US(recovery_msec)); /* FIXME: Queue all signalling messages until * recovery or T(r) expiry */ } @@ -222,21 +262,44 @@ case XUA_ASPAS_ASP_ACTIVE_IND: /* ignore */ break; + case XUA_AS_E_TRANSFER_REQ: + /* message for transmission */ + msg = data; + xua_as_transmit_msg(xafp->as, msg); + break; } } static void xua_as_fsm_pending(struct osmo_fsm_inst *fi, uint32_t event, void *data) { + struct xua_as_fsm_priv *xafp = (struct xua_as_fsm_priv *) fi->priv; + struct msgb *msg; + switch (event) { case XUA_ASPAS_ASP_ACTIVE_IND: /* one ASP transitions into ASP-ACTIVE */ + osmo_timer_del(&xafp->recovery.t_r); osmo_fsm_inst_state_chg(fi, XUA_AS_S_ACTIVE, 0, 0); + /* push out any pending queued messages */ + while ((msg = msgb_dequeue(&xafp->recovery.queued_msgs))) + xua_as_transmit_msg(xafp->as, msg); break; case XUA_ASPAS_ASP_INACTIVE_IND: /* ignore */ break; case XUA_ASPAS_ASP_DOWN_IND: /* ignore */ + break; + case XUA_AS_E_RECOVERY_EXPD: + LOGPFSM(fi, "T(r) expired; dropping queued messages\n"); + while ((msg = msgb_dequeue(&xafp->recovery.queued_msgs))) + talloc_free(msg); + osmo_fsm_inst_state_chg(fi, XUA_AS_S_DOWN, 0, 0); + break; + case XUA_AS_E_TRANSFER_REQ: + /* enqueue the to-be-transferred message */ + msg = data; + msgb_enqueue(&xafp->recovery.queued_msgs, msg); break; } } @@ -264,7 +327,8 @@ [XUA_AS_S_ACTIVE] = { .in_event_mask = S(XUA_ASPAS_ASP_DOWN_IND) | S(XUA_ASPAS_ASP_INACTIVE_IND) | - S(XUA_ASPAS_ASP_ACTIVE_IND), + S(XUA_ASPAS_ASP_ACTIVE_IND) | + S(XUA_AS_E_TRANSFER_REQ), .out_state_mask = S(XUA_AS_S_ACTIVE) | S(XUA_AS_S_PENDING), .name = "AS_ACTIVE", @@ -274,7 +338,9 @@ [XUA_AS_S_PENDING] = { .in_event_mask = S(XUA_ASPAS_ASP_INACTIVE_IND) | S(XUA_ASPAS_ASP_DOWN_IND) | - S(XUA_ASPAS_ASP_ACTIVE_IND), + S(XUA_ASPAS_ASP_ACTIVE_IND) | + S(XUA_AS_E_TRANSFER_REQ) | + S(XUA_AS_E_RECOVERY_EXPD), .out_state_mask = S(XUA_AS_S_DOWN) | S(XUA_AS_S_INACTIVE) | S(XUA_AS_S_ACTIVE) | @@ -310,6 +376,9 @@ return NULL; } xafp->as = as; + xafp->recovery.t_r.cb = t_r_callback; + xafp->recovery.t_r.data = fi; + INIT_LLIST_HEAD(&xafp->recovery.queued_msgs); fi->priv = xafp; diff --git a/src/xua_as_fsm.h b/src/xua_as_fsm.h index 3b8e5b7..0128919 100644 --- a/src/xua_as_fsm.h +++ b/src/xua_as_fsm.h @@ -6,6 +6,8 @@ XUA_ASPAS_ASP_INACTIVE_IND, XUA_ASPAS_ASP_DOWN_IND, XUA_ASPAS_ASP_ACTIVE_IND, + XUA_AS_E_RECOVERY_EXPD, + XUA_AS_E_TRANSFER_REQ, }; extern struct osmo_fsm xua_as_fsm; -- To view, visit https://gerrit.osmocom.org/2349 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I22725bf35306299a00c66d7b3637f5e198c26247 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Fri Apr 14 20:30:04 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 14 Apr 2017 20:30:04 +0000 Subject: [PATCH] libosmo-sccp[master]: get rid of global osmo_ss7_xua_servers variable Message-ID: Review at https://gerrit.osmocom.org/2350 get rid of global osmo_ss7_xua_servers variable By moving this variable into the SS7 instance, we avoid one more global variable, and we also fix a bug where the xua servers would be saved multiple times (once per instance). Change-Id: Icbab59d773f23cc8514cbeb6e21e25ca35dd337f --- M include/osmocom/sigtran/osmo_ss7.h M src/osmo_ss7.c M src/osmo_ss7_vty.c 3 files changed, 6 insertions(+), 5 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/50/2350/1 diff --git a/include/osmocom/sigtran/osmo_ss7.h b/include/osmocom/sigtran/osmo_ss7.h index 24f83e9..376e399 100644 --- a/include/osmocom/sigtran/osmo_ss7.h +++ b/include/osmocom/sigtran/osmo_ss7.h @@ -10,7 +10,6 @@ #include extern struct llist_head osmo_ss7_instances; -extern struct llist_head osmo_ss7_xua_servers; struct osmo_ss7_instance; struct osmo_ss7_user; @@ -70,6 +69,8 @@ struct llist_head asp_list; /*! list of \ref osmo_ss7_route_table */ struct llist_head rtable_list; + /*! list of \ref osmo_xua_servers */ + struct llist_head xua_servers; /* array for faster lookup of user (indexed by service * indicator) */ const struct osmo_ss7_user *user[16]; diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index 9b2377b..771501f 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -53,7 +53,6 @@ static bool ss7_initialized = false; LLIST_HEAD(osmo_ss7_instances); -LLIST_HEAD(osmo_ss7_xua_servers); static int32_t next_rctx = 1; static int32_t next_l_rk_id = 1; @@ -329,6 +328,7 @@ INIT_LLIST_HEAD(&inst->as_list); INIT_LLIST_HEAD(&inst->asp_list); INIT_LLIST_HEAD(&inst->rtable_list); + INIT_LLIST_HEAD(&inst->xua_servers); inst->rtable_system = osmo_ss7_route_table_find_or_create(inst, "system"); /* default point code structure + formatting */ @@ -1546,7 +1546,7 @@ struct osmo_xua_server *xs; OSMO_ASSERT(ss7_initialized); - llist_for_each_entry(xs, &osmo_ss7_xua_servers, list) { + llist_for_each_entry(xs, &inst->xua_servers, list) { if (proto == xs->cfg.proto && local_port == xs->cfg.local.port) return xs; @@ -1596,7 +1596,7 @@ } oxs->inst = inst; - llist_add_tail(&oxs->list, &osmo_ss7_xua_servers); + llist_add_tail(&oxs->list, &inst->xua_servers); return oxs; } diff --git a/src/osmo_ss7_vty.c b/src/osmo_ss7_vty.c index 8356d16..282a5a0 100644 --- a/src/osmo_ss7_vty.c +++ b/src/osmo_ss7_vty.c @@ -915,7 +915,7 @@ llist_for_each_entry(rtable, &inst->rtable_list, list) write_one_rtable(vty, rtable); - llist_for_each_entry(oxs, &osmo_ss7_xua_servers, list) + llist_for_each_entry(oxs, &inst->xua_servers, list) write_one_xua(vty, oxs); } -- To view, visit https://gerrit.osmocom.org/2350 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Icbab59d773f23cc8514cbeb6e21e25ca35dd337f Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Fri Apr 14 20:30:05 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 14 Apr 2017 20:30:05 +0000 Subject: [PATCH] libosmo-sccp[master]: osmo_ss7: Clean up all ASPs established via xua_server upon ... Message-ID: Review at https://gerrit.osmocom.org/2351 osmo_ss7: Clean up all ASPs established via xua_server upon destroy When we destroy a xua_server, we would like to close and destroy any ASPs that were established via that xua_server. In order to do so, we need to add a list of ASPs to the xua_server, which we can iterate. Change-Id: Iff3ed099b817e54e563b70d9ab40f63af63cc2fb --- M include/osmocom/sigtran/osmo_ss7.h M src/osmo_ss7.c 2 files changed, 16 insertions(+), 3 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/51/2351/1 diff --git a/include/osmocom/sigtran/osmo_ss7.h b/include/osmocom/sigtran/osmo_ss7.h index 376e399..a8c1c3c 100644 --- a/include/osmocom/sigtran/osmo_ss7.h +++ b/include/osmocom/sigtran/osmo_ss7.h @@ -339,6 +339,7 @@ /*! \ref osmo_xua_server over which we were established */ struct osmo_xua_server *xua_server; + struct llist_head siblings; /*! osmo_stream / libosmo-netif handles */ struct osmo_stream_cli *client; @@ -396,6 +397,9 @@ struct llist_head list; struct osmo_ss7_instance *inst; + /* list of ASPs established via this server */ + struct llist_head asp_list; + struct osmo_stream_srv_link *server; struct { diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index 771501f..57d9d39 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -1050,6 +1050,8 @@ osmo_stream_cli_destroy(asp->client); if (asp->fi) osmo_fsm_inst_term(asp->fi, OSMO_FSM_TERM_REQUEST, NULL); + if (asp->xua_server) + llist_del(&asp->siblings); /* unlink from all ASs we are part of */ llist_for_each_entry(as, &asp->inst->as_list, list) { @@ -1481,6 +1483,7 @@ /* update the ASP reference back to the server over which the * connection came in */ asp->server = srv; + llist_add_tail(&asp->siblings, &oxs->asp_list); /* update the ASP socket name */ if (asp->sock_name) talloc_free(asp->sock_name); @@ -1575,6 +1578,8 @@ LOGP(DLSS7, LOGL_INFO, "Creating XUA Server %s:%u\n", local_host, local_port); + INIT_LLIST_HEAD(&oxs->asp_list); + oxs->cfg.proto = proto; oxs->cfg.local.port = local_port; oxs->cfg.local.host = talloc_strdup(oxs, local_host); @@ -1614,13 +1619,17 @@ void osmo_ss7_xua_server_destroy(struct osmo_xua_server *xs) { + struct osmo_ss7_asp *asp, *asp2; + if (xs->server) { osmo_stream_srv_link_close(xs->server); osmo_stream_srv_link_destroy(xs->server); } - /* FIXME: add asp_list to xua_server so we can iterate it here - * and close all connections established in relation with this - * server */ + /* iterate and close all connections established in relation + * with this server */ + llist_for_each_entry_safe(asp, asp2, &xs->asp_list, siblings) + osmo_ss7_asp_destroy(asp); + llist_del(&xs->list); talloc_free(xs); } -- To view, visit https://gerrit.osmocom.org/2351 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Iff3ed099b817e54e563b70d9ab40f63af63cc2fb Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Fri Apr 14 20:49:05 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 14 Apr 2017 20:49:05 +0000 Subject: [PATCH] libosmo-sccp[master]: SUA/M3UA: Implement T(r) recovery timer of Application Serve... In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2349 to look at the new patch set (#2). SUA/M3UA: Implement T(r) recovery timer of Application Server FSM When an AS goes "down" it first entres a recovery state, in which any to-be-transmitted messages are enqueued until the timer T(r) expires. Once the timer expires, the messages are discarded. If the AS goes ACTIVE before timer expiration, queued messages are sent. Change-Id: I22725bf35306299a00c66d7b3637f5e198c26247 --- M src/m3ua.c M src/sua.c M src/xua_as_fsm.c M src/xua_as_fsm.h M src/xua_asp_fsm.c 5 files changed, 147 insertions(+), 46 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/49/2349/2 diff --git a/src/m3ua.c b/src/m3ua.c index 7dc2afb..a7ef06c 100644 --- a/src/m3ua.c +++ b/src/m3ua.c @@ -39,6 +39,7 @@ #include #include +#include "xua_as_fsm.h" #include "xua_asp_fsm.h" #include "xua_internal.h" @@ -420,16 +421,14 @@ * Transmitting M3UA messsages to SCTP ***********************************************************************/ -/* transmit given xua_msg via given ASP. callee takes xua ownership */ -static int m3ua_tx_xua_asp(struct osmo_ss7_asp *asp, struct xua_msg *xua) +/* Convert M3UA from xua_msg to msgb and set PPID/stream */ +static struct msgb *m3ua_to_msg(struct xua_msg *xua) { struct msgb *msg = xua_to_msg(M3UA_VERSION, xua); - OSMO_ASSERT(asp->cfg.proto == OSMO_SS7_ASP_PROT_M3UA); - if (!msg) { LOGP(DLM3UA, LOGL_ERROR, "Error encoding M3UA Msg\n"); - return -1; + return NULL; } if (xua->hdr.msg_class == M3UA_MSGC_XFER) @@ -437,6 +436,20 @@ else msgb_sctp_stream(msg) = 0; msgb_sctp_ppid(msg) = M3UA_PPID; + + return msg; +} + +/* transmit given xua_msg via given ASP */ +static int m3ua_tx_xua_asp(struct osmo_ss7_asp *asp, struct xua_msg *xua) +{ + struct msgb *msg = m3ua_to_msg(xua); + + OSMO_ASSERT(asp->cfg.proto == OSMO_SS7_ASP_PROT_M3UA); + + if (!msg) + return -1; + return osmo_ss7_asp_send(asp, msg); } @@ -446,8 +459,8 @@ * \return 0 on success; negative on error */ int m3ua_tx_xua_as(struct osmo_ss7_as *as, struct xua_msg *xua) { - struct osmo_ss7_asp *asp; - unsigned int i; + struct msgb *msg; + int rc; OSMO_ASSERT(as->cfg.proto == OSMO_SS7_ASP_PROT_M3UA); @@ -455,19 +468,16 @@ if (as->cfg.routing_key.context) xua_msg_add_u32(xua, M3UA_IEI_ROUTE_CTX, as->cfg.routing_key.context); - for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) { - asp = as->cfg.asps[i]; - if (!asp) - continue; - if (asp) - break; - } - if (!asp) { - LOGP(DLM3UA, LOGL_ERROR, "No ASP entroy in AS, dropping message\n"); - return -ENODEV; - } + msg = m3ua_to_msg(xua); + if (!msg) + return -1; - return m3ua_tx_xua_asp(asp, xua); + /* send the msg to the AS for transmission. The AS FSM might + * (depending on its state) enqueue it before trnsmission */ + rc = osmo_fsm_inst_dispatch(as->fi, XUA_AS_E_TRANSFER_REQ, msg); + if (rc < 0) + msgb_free(msg); + return rc; } /*********************************************************************** diff --git a/src/sua.c b/src/sua.c index 3bff855..97a0785 100644 --- a/src/sua.c +++ b/src/sua.c @@ -40,6 +40,7 @@ #include #include +#include "xua_as_fsm.h" #include "xua_asp_fsm.h" #include "xua_internal.h" #include "sccp_internal.h" @@ -252,18 +253,38 @@ * Transmitting SUA messsages to SCTP ***********************************************************************/ -static int sua_tx_xua_asp(struct osmo_ss7_asp *asp, struct xua_msg *xua) +static struct msgb *sua_to_msg(struct xua_msg *xua) { struct msgb *msg = xua_to_msg(SUA_VERSION, xua); - OSMO_ASSERT(asp->cfg.proto == OSMO_SS7_ASP_PROT_SUA); - if (!msg) { - LOGPASP(asp, DLSUA, LOGL_ERROR, "Error encoding SUA Msg\n"); - return -1; + LOGP(DLSUA, LOGL_ERROR, "Error encoding SUA Msg\n"); + return NULL; } + switch (xua->hdr.msg_class) { + case SUA_MSGC_CL: + case SUA_MSGC_CO: + msgb_sctp_stream(msg) = 1; + break; + default: + msgb_sctp_stream(msg) = 0; + break; + } msgb_sctp_ppid(msg) = SUA_PPID; + + return msg; +} + +static int sua_tx_xua_asp(struct osmo_ss7_asp *asp, struct xua_msg *xua) +{ + struct msgb *msg = sua_to_msg(xua); + + OSMO_ASSERT(asp->cfg.proto == OSMO_SS7_ASP_PROT_SUA); + + if (!msg) + return -1; + return osmo_ss7_asp_send(asp, msg); } @@ -273,25 +294,25 @@ * \return 0 on success; negative on error */ int sua_tx_xua_as(struct osmo_ss7_as *as, struct xua_msg *xua) { - struct osmo_ss7_asp *asp; - unsigned int i; + struct msgb *msg; + int rc; OSMO_ASSERT(as->cfg.proto == OSMO_SS7_ASP_PROT_SUA); - /* FIXME: Select ASP within AS depending on traffic mode */ - for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) { - asp = as->cfg.asps[i]; - if (!asp) - continue; - if (asp) - break; - } - if (!asp) { - LOGP(DLSUA, LOGL_ERROR, "No ASP in AS, dropping message\n"); - return -ENODEV; - } + /* Add RC for this AS */ + if (as->cfg.routing_key.context) + xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, as->cfg.routing_key.context); - return sua_tx_xua_asp(asp, xua); + msg = sua_to_msg(xua); + if (!msg) + return -1; + + /* send the msg to the AS for transmission. The AS FSM might + * (depending on its state) enqueue it before trnsmission */ + rc = osmo_fsm_inst_dispatch(as->fi, XUA_AS_E_TRANSFER_REQ, msg); + if (rc < 0) + msgb_free(msg); + return rc; } /*********************************************************************** diff --git a/src/xua_as_fsm.c b/src/xua_as_fsm.c index 740070b..282a6bf 100644 --- a/src/xua_as_fsm.c +++ b/src/xua_as_fsm.c @@ -65,12 +65,39 @@ return sent; } +/* actually transmit a message through this AS */ +static int xua_as_transmit_msg(struct osmo_ss7_as *as, struct msgb *msg) +{ + struct osmo_ss7_asp *asp; + unsigned int i; + + /* FIXME: proper selection of the ASP based on the SLS and the + * traffic mode type! */ + for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) { + asp = as->cfg.asps[i]; + if (!asp) + continue; + if (asp) + break; + } + + if (!asp) { + LOGPFSM(as->fi, "No ASP in AS, dropping message\n"); + msgb_free(msg); + return -1; + } + + return osmo_ss7_asp_send(asp, msg); +} + /*********************************************************************** * Actual FSM ***********************************************************************/ #define S(x) (1 << (x)) + +#define MSEC_TO_S_US(x) (x/1000), ((x%1000)*10) enum xua_as_state { XUA_AS_S_DOWN, @@ -83,11 +110,17 @@ { XUA_ASPAS_ASP_INACTIVE_IND, "ASPAS-ASP_INACTIVE.ind" }, { XUA_ASPAS_ASP_DOWN_IND, "ASPAS-ASP_DOWN.ind" }, { XUA_ASPAS_ASP_ACTIVE_IND, "ASPAS-ASP_ACTIVE.ind" }, + { XUA_AS_E_RECOVERY_EXPD, "AS-T_REC_EXPD.ind" }, + { XUA_AS_E_TRANSFER_REQ, "AS-TRANSFER.req" }, { 0, NULL } }; struct xua_as_fsm_priv { struct osmo_ss7_as *as; + struct { + struct osmo_timer_list t_r; + struct llist_head queued_msgs; + } recovery; }; /* is any other ASP in this AS in state != DOWN? */ @@ -130,6 +163,11 @@ return false; } +static void t_r_callback(void *_fi) +{ + struct osmo_fsm_inst *fi = _fi; + osmo_fsm_inst_dispatch(fi, XUA_AS_E_RECOVERY_EXPD, NULL); +} static void xua_as_fsm_down(struct osmo_fsm_inst *fi, uint32_t event, void *data) { @@ -205,16 +243,20 @@ static void xua_as_fsm_active(struct osmo_fsm_inst *fi, uint32_t event, void *data) { struct xua_as_fsm_priv *xafp = (struct xua_as_fsm_priv *) fi->priv; - struct osmo_ss7_asp *asp = data; + struct osmo_ss7_asp *asp; + struct msgb *msg; switch (event) { case XUA_ASPAS_ASP_DOWN_IND: case XUA_ASPAS_ASP_INACTIVE_IND: + asp = data; if (check_any_other_asp_in_active(xafp->as, asp)) { /* ignore, we stay AS_ACTIVE */ } else { + uint32_t recovery_msec = xafp->as->cfg.recovery_timeout_msec; osmo_fsm_inst_state_chg(fi, XUA_AS_S_PENDING, 0, 0); - /* FIXME: Start T(r) */ + /* Start T(r) */ + osmo_timer_schedule(&xafp->recovery.t_r, MSEC_TO_S_US(recovery_msec)); /* FIXME: Queue all signalling messages until * recovery or T(r) expiry */ } @@ -222,21 +264,44 @@ case XUA_ASPAS_ASP_ACTIVE_IND: /* ignore */ break; + case XUA_AS_E_TRANSFER_REQ: + /* message for transmission */ + msg = data; + xua_as_transmit_msg(xafp->as, msg); + break; } } static void xua_as_fsm_pending(struct osmo_fsm_inst *fi, uint32_t event, void *data) { + struct xua_as_fsm_priv *xafp = (struct xua_as_fsm_priv *) fi->priv; + struct msgb *msg; + switch (event) { case XUA_ASPAS_ASP_ACTIVE_IND: /* one ASP transitions into ASP-ACTIVE */ + osmo_timer_del(&xafp->recovery.t_r); osmo_fsm_inst_state_chg(fi, XUA_AS_S_ACTIVE, 0, 0); + /* push out any pending queued messages */ + while ((msg = msgb_dequeue(&xafp->recovery.queued_msgs))) + xua_as_transmit_msg(xafp->as, msg); break; case XUA_ASPAS_ASP_INACTIVE_IND: /* ignore */ break; case XUA_ASPAS_ASP_DOWN_IND: /* ignore */ + break; + case XUA_AS_E_RECOVERY_EXPD: + LOGPFSM(fi, "T(r) expired; dropping queued messages\n"); + while ((msg = msgb_dequeue(&xafp->recovery.queued_msgs))) + talloc_free(msg); + osmo_fsm_inst_state_chg(fi, XUA_AS_S_DOWN, 0, 0); + break; + case XUA_AS_E_TRANSFER_REQ: + /* enqueue the to-be-transferred message */ + msg = data; + msgb_enqueue(&xafp->recovery.queued_msgs, msg); break; } } @@ -264,7 +329,8 @@ [XUA_AS_S_ACTIVE] = { .in_event_mask = S(XUA_ASPAS_ASP_DOWN_IND) | S(XUA_ASPAS_ASP_INACTIVE_IND) | - S(XUA_ASPAS_ASP_ACTIVE_IND), + S(XUA_ASPAS_ASP_ACTIVE_IND) | + S(XUA_AS_E_TRANSFER_REQ), .out_state_mask = S(XUA_AS_S_ACTIVE) | S(XUA_AS_S_PENDING), .name = "AS_ACTIVE", @@ -274,7 +340,9 @@ [XUA_AS_S_PENDING] = { .in_event_mask = S(XUA_ASPAS_ASP_INACTIVE_IND) | S(XUA_ASPAS_ASP_DOWN_IND) | - S(XUA_ASPAS_ASP_ACTIVE_IND), + S(XUA_ASPAS_ASP_ACTIVE_IND) | + S(XUA_AS_E_TRANSFER_REQ) | + S(XUA_AS_E_RECOVERY_EXPD), .out_state_mask = S(XUA_AS_S_DOWN) | S(XUA_AS_S_INACTIVE) | S(XUA_AS_S_ACTIVE) | @@ -310,6 +378,9 @@ return NULL; } xafp->as = as; + xafp->recovery.t_r.cb = t_r_callback; + xafp->recovery.t_r.data = fi; + INIT_LLIST_HEAD(&xafp->recovery.queued_msgs); fi->priv = xafp; diff --git a/src/xua_as_fsm.h b/src/xua_as_fsm.h index 3b8e5b7..0128919 100644 --- a/src/xua_as_fsm.h +++ b/src/xua_as_fsm.h @@ -6,6 +6,8 @@ XUA_ASPAS_ASP_INACTIVE_IND, XUA_ASPAS_ASP_DOWN_IND, XUA_ASPAS_ASP_ACTIVE_IND, + XUA_AS_E_RECOVERY_EXPD, + XUA_AS_E_TRANSFER_REQ, }; extern struct osmo_fsm xua_as_fsm; diff --git a/src/xua_asp_fsm.c b/src/xua_asp_fsm.c index 59887a4..f4d9cf0 100644 --- a/src/xua_asp_fsm.c +++ b/src/xua_asp_fsm.c @@ -380,9 +380,6 @@ struct osmo_ss7_instance *inst = asp->inst; struct osmo_ss7_as *as; - if (xafp->role != XUA_ASPFSM_ROLE_SG) - return; - llist_for_each_entry(as, &inst->as_list, list) { if (!osmo_ss7_as_has_asp(as, asp)) continue; -- To view, visit https://gerrit.osmocom.org/2349 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I22725bf35306299a00c66d7b3637f5e198c26247 Gerrit-PatchSet: 2 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Fri Apr 14 20:49:56 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 14 Apr 2017 20:49:56 +0000 Subject: libosmo-sccp[master]: osmo_ss7_vty: Don't save dynamically generated AS / ASP In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2343 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I9d0b0b61737a30b9d6e76cecbe42ec071bcddeeb Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Apr 14 20:50:00 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 14 Apr 2017 20:50:00 +0000 Subject: libosmo-sccp[master]: sccp_scoc: Memorize if a connection is incoming or outbound In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2344 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ic3c85152665abfb613e197b098c97392d16d16bf Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Apr 14 20:50:04 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 14 Apr 2017 20:50:04 +0000 Subject: libosmo-sccp[master]: SCCP: Add VTY interface for SCCP In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2345 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I100daaa947dbab6a4528c4e9fbd0d30790288f63 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Apr 14 20:50:07 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 14 Apr 2017 20:50:07 +0000 Subject: libosmo-sccp[master]: m3ua_example: Add SS7 and SCCP VTY In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2346 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Id03d2f94d22445ada01917356a5ec5a8e4fa3fca Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Apr 14 20:50:10 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 14 Apr 2017 20:50:10 +0000 Subject: libosmo-sccp[master]: ss7_vty: don't re-define xUA dialect strings In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2347 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I085b884d98fb4c45ac15910a8ebf82b91e861fd4 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Apr 14 20:50:12 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 14 Apr 2017 20:50:12 +0000 Subject: libosmo-sccp[master]: osmo_ss7_vty: Print AS and ASP state names during 'show' In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2348 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I6a06d93d6e6c0386676742d6d19f5483a46d7fba Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Apr 14 20:50:24 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 14 Apr 2017 20:50:24 +0000 Subject: libosmo-sccp[master]: SUA/M3UA: Implement T(r) recovery timer of Application Serve... In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2349 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I22725bf35306299a00c66d7b3637f5e198c26247 Gerrit-PatchSet: 2 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sat Apr 15 17:15:28 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 15 Apr 2017 17:15:28 +0000 Subject: [PATCH] libosmo-netif[master]: netif/ipa.h: Don't redefine 'struct ipaccess_unit' from libo... Message-ID: Review at https://gerrit.osmocom.org/2352 netif/ipa.h: Don't redefine 'struct ipaccess_unit' from libosmocore 'struct ipaccess_unit' is defined in libosmocore/gsm/ipa.h, we shouldn't re-define it here. This entire IPA code duplication accross multiple libraries and programs is a big mess. Change-Id: If378a088c741df540befb928a5557fc62dea954a --- M include/osmocom/netif/ipa.h 1 file changed, 1 insertion(+), 13 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-netif refs/changes/52/2352/1 diff --git a/include/osmocom/netif/ipa.h b/include/osmocom/netif/ipa.h index 8d221e3..0a29f01 100644 --- a/include/osmocom/netif/ipa.h +++ b/include/osmocom/netif/ipa.h @@ -2,6 +2,7 @@ #define _OSMO_NETIF_IPA_H_ #include +#include /* This is like 'struct ipaccess_head' in libosmocore, but 'ipa_head' is * actually the more apropriate name, so rather than making more code @@ -21,19 +22,6 @@ void osmo_ipa_msg_push_header(struct msgb *msg, uint8_t proto); int osmo_ipa_process_msg(struct msgb *msg); - -struct ipaccess_unit { - uint16_t site_id; - uint16_t bts_id; - uint16_t trx_id; - char *unit_name; - char *equipvers; - char *swversion; - uint8_t mac_addr[6]; - char *location1; - char *location2; - char *serno; -}; struct osmo_fd; struct tlv_parsed; -- To view, visit https://gerrit.osmocom.org/2352 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: If378a088c741df540befb928a5557fc62dea954a Gerrit-PatchSet: 1 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Harald Welte From admin at opensuse.org Sat Apr 15 19:59:00 2017 From: admin at opensuse.org (OBS Notification) Date: Sat, 15 Apr 2017 19:59:00 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in xUbuntu_16.04/x86_64 In-Reply-To: References: Message-ID: <58f27ba7cfa5e_99c1156f847438dd@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/xUbuntu_16.04/x86_64 Package network:osmocom:nightly/osmo-stp failed to build in xUbuntu_16.04/x86_64 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 55s] sctp_m2ua.c: In function 'm2ua_conn_destroy': [ 55s] sctp_m2ua.c:91:3: warning: #warning "Notify any other AS(P) for failover scenario" [-Wcpp] [ 55s] #warning "Notify any other AS(P) for failover scenario" [ 55s] ^ [ 55s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -c -o vty_interface.o vty_interface.c [ 55s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -c -o sctp_m3ua_client.o sctp_m3ua_client.c [ 55s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 55s] compilation terminated. [ 55s] Makefile:485: recipe for target 'sctp_m3ua_client.o' failed [ 55s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 55s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 55s] Makefile:380: recipe for target 'all-recursive' failed [ 55s] make[2]: *** [all-recursive] Error 1 [ 55s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 55s] Makefile:321: recipe for target 'all' failed [ 55s] make[1]: *** [all] Error 2 [ 55s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 55s] dh_auto_build: make -j1 returned exit code 2 [ 55s] debian/rules:23: recipe for target 'build' failed [ 55s] make: *** [build] Error 2 [ 55s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 55s] [ 55s] build82 failed "build cellmgr-ng_1.4.7.20170415.dsc" at Sat Apr 15 19:58:32 UTC 2017. [ 55s] [ 55s] ### VM INTERACTION START ### [ 59s] ### VM INTERACTION END ### [ 59s] [ 59s] build82 failed "build cellmgr-ng_1.4.7.20170415.dsc" at Sat Apr 15 19:58:36 UTC 2017. [ 59s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Sat Apr 15 20:00:07 2017 From: admin at opensuse.org (OBS Notification) Date: Sat, 15 Apr 2017 20:00:07 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in Debian_8.0/i586 In-Reply-To: References: Message-ID: <58f27bea245d3_98f1156f846456f3@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/Debian_8.0/i586 Package network:osmocom:nightly/osmo-stp failed to build in Debian_8.0/i586 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 54s] CC vty_interface.o [ 55s] CC sctp_m3ua_client.o [ 55s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 55s] #include [ 55s] ^ [ 55s] compilation terminated. [ 55s] Makefile:475: recipe for target 'sctp_m3ua_client.o' failed [ 55s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 55s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 55s] Makefile:370: recipe for target 'all-recursive' failed [ 55s] make[2]: *** [all-recursive] Error 1 [ 55s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 55s] Makefile:310: recipe for target 'all' failed [ 55s] make[1]: *** [all] Error 2 [ 55s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 55s] dh_auto_build: make -j1 returned exit code 2 [ 55s] debian/rules:23: recipe for target 'build' failed [ 55s] make: *** [build] Error 2 [ 55s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 55s] [ 55s] build82 failed "build cellmgr-ng_1.4.7.20170415.dsc" at Sat Apr 15 19:59:55 UTC 2017. [ 55s] [ 55s] ### VM INTERACTION START ### [ 56s] Powering off. [ 56s] [ 47.948425] reboot: Power down [ 56s] ### VM INTERACTION END ### [ 56s] [ 56s] build82 failed "build cellmgr-ng_1.4.7.20170415.dsc" at Sat Apr 15 19:59:57 UTC 2017. [ 56s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Sat Apr 15 20:01:08 2017 From: admin at opensuse.org (OBS Notification) Date: Sat, 15 Apr 2017 20:01:08 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in xUbuntu_16.10/x86_64 In-Reply-To: References: Message-ID: <58f27c222afbf_c7610b4f7c577638@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/xUbuntu_16.10/x86_64 Package network:osmocom:nightly/osmo-stp failed to build in xUbuntu_16.10/x86_64 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 99s] ^~~~~~~ [ 99s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o vty_interface.o vty_interface.c [ 100s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o sctp_m3ua_client.o sctp_m3ua_client.c [ 100s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 100s] #include [ 100s] ^ [ 100s] compilation terminated. [ 100s] Makefile:485: recipe for target 'sctp_m3ua_client.o' failed [ 100s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 100s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 100s] Makefile:380: recipe for target 'all-recursive' failed [ 100s] make[2]: *** [all-recursive] Error 1 [ 100s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 100s] Makefile:321: recipe for target 'all' failed [ 100s] make[1]: *** [all] Error 2 [ 100s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 100s] dh_auto_build: make -j1 returned exit code 2 [ 100s] debian/rules:23: recipe for target 'build' failed [ 100s] make: *** [build] Error 2 [ 100s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 100s] [ 100s] cloud114 failed "build cellmgr-ng_1.4.7.20170415.dsc" at Sat Apr 15 20:00:30 UTC 2017. [ 100s] [ 100s] ### VM INTERACTION START ### [ 103s] [ 81.961917] reboot: Power down [ 107s] ### VM INTERACTION END ### [ 107s] [ 107s] cloud114 failed "build cellmgr-ng_1.4.7.20170415.dsc" at Sat Apr 15 20:00:37 UTC 2017. [ 107s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Sat Apr 15 20:01:45 2017 From: admin at opensuse.org (OBS Notification) Date: Sat, 15 Apr 2017 20:01:45 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in Debian_8.0/x86_64 In-Reply-To: References: Message-ID: <58f27c774430b_c7610b4f7c57782b@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/Debian_8.0/x86_64 Package network:osmocom:nightly/osmo-stp failed to build in Debian_8.0/x86_64 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 118s] CC vty_interface.o [ 119s] CC sctp_m3ua_client.o [ 119s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 119s] #include [ 119s] ^ [ 119s] compilation terminated. [ 119s] Makefile:475: recipe for target 'sctp_m3ua_client.o' failed [ 119s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 119s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 119s] Makefile:370: recipe for target 'all-recursive' failed [ 119s] make[2]: *** [all-recursive] Error 1 [ 119s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 119s] Makefile:310: recipe for target 'all' failed [ 119s] make[1]: *** [all] Error 2 [ 119s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 119s] dh_auto_build: make -j1 returned exit code 2 [ 119s] debian/rules:23: recipe for target 'build' failed [ 119s] make: *** [build] Error 2 [ 119s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 119s] [ 119s] cloud124 failed "build cellmgr-ng_1.4.7.20170415.dsc" at Sat Apr 15 20:01:18 UTC 2017. [ 119s] [ 119s] ### VM INTERACTION START ### [ 120s] Powering off. [ 120s] [ 97.347698] reboot: Power down [ 121s] ### VM INTERACTION END ### [ 121s] [ 121s] cloud124 failed "build cellmgr-ng_1.4.7.20170415.dsc" at Sat Apr 15 20:01:21 UTC 2017. [ 121s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Sat Apr 15 20:01:45 2017 From: admin at opensuse.org (OBS Notification) Date: Sat, 15 Apr 2017 20:01:45 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in xUbuntu_16.10/i586 In-Reply-To: References: Message-ID: <58f27c8e8b5b6_c7610b4f7c5779a8@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/xUbuntu_16.10/i586 Package network:osmocom:nightly/osmo-stp failed to build in xUbuntu_16.10/i586 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 103s] ^~~~~~~ [ 103s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o vty_interface.o vty_interface.c [ 104s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o sctp_m3ua_client.o sctp_m3ua_client.c [ 104s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 104s] #include [ 104s] ^ [ 104s] compilation terminated. [ 104s] Makefile:485: recipe for target 'sctp_m3ua_client.o' failed [ 104s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 104s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 104s] Makefile:380: recipe for target 'all-recursive' failed [ 104s] make[2]: *** [all-recursive] Error 1 [ 104s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 104s] Makefile:321: recipe for target 'all' failed [ 104s] make[1]: *** [all] Error 2 [ 104s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 104s] dh_auto_build: make -j1 returned exit code 2 [ 104s] debian/rules:23: recipe for target 'build' failed [ 104s] make: *** [build] Error 2 [ 104s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 104s] [ 104s] cloud125 failed "build cellmgr-ng_1.4.7.20170415.dsc" at Sat Apr 15 20:01:19 UTC 2017. [ 104s] [ 104s] ### VM INTERACTION START ### [ 107s] [ 85.818780] reboot: Power down [ 109s] ### VM INTERACTION END ### [ 109s] [ 109s] cloud125 failed "build cellmgr-ng_1.4.7.20170415.dsc" at Sat Apr 15 20:01:24 UTC 2017. [ 109s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Sat Apr 15 20:06:02 2017 From: admin at opensuse.org (OBS Notification) Date: Sat, 15 Apr 2017 20:06:02 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in xUbuntu_16.04/i586 In-Reply-To: References: Message-ID: <58f283d186b62_c7610b4f7c5780f0@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/xUbuntu_16.04/i586 Package network:osmocom:nightly/osmo-stp failed to build in xUbuntu_16.04/i586 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 126s] sctp_m2ua.c:91:3: warning: #warning "Notify any other AS(P) for failover scenario" [-Wcpp] [ 126s] #warning "Notify any other AS(P) for failover scenario" [ 126s] ^ [ 126s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -c -o vty_interface.o vty_interface.c [ 126s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -c -o sctp_m3ua_client.o sctp_m3ua_client.c [ 127s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 127s] compilation terminated. [ 127s] Makefile:485: recipe for target 'sctp_m3ua_client.o' failed [ 127s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 127s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 127s] Makefile:380: recipe for target 'all-recursive' failed [ 127s] make[2]: *** [all-recursive] Error 1 [ 127s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 127s] Makefile:321: recipe for target 'all' failed [ 127s] make[1]: *** [all] Error 2 [ 127s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 127s] dh_auto_build: make -j1 returned exit code 2 [ 127s] debian/rules:23: recipe for target 'build' failed [ 127s] make: *** [build] Error 2 [ 127s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 127s] [ 127s] cloud124 failed "build cellmgr-ng_1.4.7.20170415.dsc" at Sat Apr 15 20:05:24 UTC 2017. [ 127s] [ 127s] ### VM INTERACTION START ### [ 130s] [ 106.506916] reboot: Power down [ 133s] ### VM INTERACTION END ### [ 133s] [ 133s] cloud124 failed "build cellmgr-ng_1.4.7.20170415.dsc" at Sat Apr 15 20:05:30 UTC 2017. [ 133s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From gerrit-no-reply at lists.osmocom.org Sat Apr 15 20:54:45 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 15 Apr 2017 20:54:45 +0000 Subject: libosmo-sccp[master]: WIP: Add IPA/SCCPlite stacking In-Reply-To: References: Message-ID: Harald Welte has restored this change. Change subject: WIP: Add IPA/SCCPlite stacking ...................................................................... Restored -- To view, visit https://gerrit.osmocom.org/2282 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: restore Gerrit-Change-Id: I9098574cddeba10fcf8f1b6c196a7069a6805c56 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sat Apr 15 20:54:50 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 15 Apr 2017 20:54:50 +0000 Subject: [PATCH] libosmo-sccp[master]: Add IPA/SCCPlite support as SIGTRAN alternative In-Reply-To: References: Message-ID: Add IPA/SCCPlite support as SIGTRAN alternative This tries as good as possible to fit the IPA/SCCPlite stacking into the existing SIGTRAN/SS7 code architecture/model. To the user, the IPA protocol looks like yet another protocol on the same level as the choice between SUA and M3AU. On the inside, things are obviously quite different. We need to handle TCP with IPA framing instead of SCTP for both server and client. We also implement an alternative "ASP FSM" for IPA, which takes care of the CCM handshake (ID_REQ/ID_RESP/ID_ACK/ID_ACK2) for both client and server mode. In server mode, we use the 'unit name' as identifier to look up the AS, similar to how we use a routing context to look up the AS in the xUA case. We also have to bypass activating the default layer manager in the simple client to make sure we don't run into even more complexity. What's missing right now is some way to manually override/set the point codes. As IPA/SCCPlite is missing any routing label, we currently simply generate one with SPC=0/DPC=0, which will obviously not work in most configurations. Change-Id: I9098574cddeba10fcf8f1b6c196a7069a6805c56 --- M include/osmocom/sigtran/osmo_ss7.h M src/Makefile.am A src/ipa.c M src/osmo_ss7.c M src/osmo_ss7_hmrt.c M src/osmo_ss7_vty.c M src/sccp_scrc.c M src/sccp_user.c M src/xua_as_fsm.c M src/xua_asp_fsm.c M src/xua_asp_fsm.h M src/xua_internal.h 12 files changed, 683 insertions(+), 17 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/82/2282/2 diff --git a/include/osmocom/sigtran/osmo_ss7.h b/include/osmocom/sigtran/osmo_ss7.h index 76403e2..2ae4c1e 100644 --- a/include/osmocom/sigtran/osmo_ss7.h +++ b/include/osmocom/sigtran/osmo_ss7.h @@ -258,6 +258,7 @@ OSMO_SS7_ASP_PROT_NONE, OSMO_SS7_ASP_PROT_SUA, OSMO_SS7_ASP_PROT_M3UA, + OSMO_SS7_ASP_PROT_IPA, _NUM_OSMO_SS7_ASP_PROT }; @@ -359,6 +360,9 @@ /*! Were we dynamically allocated */ bool dyn_allocated; + /*! Pending message for non-blocking IPA read */ + struct msgb *pending_msg; + struct { char *name; char *description; diff --git a/src/Makefile.am b/src/Makefile.am index 217f2f7..15f17fe 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -30,6 +30,6 @@ sccp2sua.c sccp_scrc.c sccp_sclc.c sccp_scoc.c \ sccp_user.c xua_rkm.c xua_default_lm_fsm.c \ osmo_ss7.c osmo_ss7_hmrt.c xua_asp_fsm.c xua_as_fsm.c \ - osmo_ss7_vty.c sccp_vty.c + osmo_ss7_vty.c sccp_vty.c ipa.c libosmo_sigtran_la_LDFLAGS = -version-info $(LIBVERSION) -no-undefined -export-symbols-regex '^osmo_' libosmo_sigtran_la_LIBADD = $(LIBOSMOCORE_LIBS) $(LIBOSMONETIF_LIBS) $(LIBSCTP_LIBS) diff --git a/src/ipa.c b/src/ipa.c new file mode 100644 index 0000000..83dde9b --- /dev/null +++ b/src/ipa.c @@ -0,0 +1,184 @@ +/* implementation of IPA/SCCPlite transport */ + +/* (C) 2015-2017 by Harald Welte + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +//#include +#include +#include + +#include +#include +#include +#include + +#include "xua_internal.h" +#include "xua_asp_fsm.h" + + +/*! \brief Send a given xUA message via a given IPA "Application Server" + * \param[in] as Application Server through which to send \a xua + * \param[in] xua xUA message to be sent + * \return 0 on success; negative on error */ +int ipa_tx_xua_as(struct osmo_ss7_as *as, struct xua_msg *xua) +{ + struct xua_msg_part *data_ie; + struct msgb *msg; + unsigned int src_len; + const uint8_t *src; + uint8_t *dst; + + OSMO_ASSERT(as->cfg.proto == OSMO_SS7_ASP_PROT_IPA); + + /* we're actually only interested in the data part */ + data_ie = xua_msg_find_tag(xua, M3UA_IEI_PROT_DATA); + if (!data_ie || data_ie->len < sizeof(struct m3ua_data_hdr)) + return -1; + + /* and even the data part still has the header prepended */ + src = data_ie->dat + sizeof(struct m3ua_data_hdr); + src_len = data_ie->len - sizeof(struct m3ua_data_hdr); + + /* sufficient headroom for osmo_ipa_msg_push_header() */ + msg = ipa_msg_alloc(16); + if (!msg) + return -1; + + dst = msgb_put(msg, src_len); + memcpy(dst, src, src_len); + + /* TODO: if we ever need something beyond SCCP, we can use the + * M3UA SIO to determine the protocol */ + osmo_ipa_msg_push_header(msg, IPAC_PROTO_SCCP); + + return xua_as_transmit_msg(as, msg); +} + +static int ipa_rx_msg_ccm(struct osmo_ss7_asp *asp, struct msgb *msg) +{ + uint8_t msg_type = msg->l2h[0]; + + LOGPASP(asp, DLSS7, LOGL_DEBUG, "%s:%s\n", __func__, msgb_hexdump(msg)); + + /* Convert CCM into events to the IPA_ASP_FSM */ + switch (msg_type) { + case IPAC_MSGT_ID_ACK: + osmo_fsm_inst_dispatch(asp->fi, IPA_ASP_E_ID_ACK, msg); + break; + case IPAC_MSGT_ID_RESP: + osmo_fsm_inst_dispatch(asp->fi, IPA_ASP_E_ID_RESP, msg); + break; + case IPAC_MSGT_ID_GET: + osmo_fsm_inst_dispatch(asp->fi, IPA_ASP_E_ID_GET, msg); + break; + case IPAC_MSGT_PING: + osmo_fsm_inst_dispatch(asp->fi, XUA_ASP_E_ASPSM_BEAT, msg); + break; + case IPAC_MSGT_PONG: + osmo_fsm_inst_dispatch(asp->fi, XUA_ASP_E_ASPSM_BEAT_ACK, msg); + break; + default: + LOGPASP(asp, DLSS7, LOGL_NOTICE, "Unknown CCM Message 0x%02x: %s\n", + msg_type, msgb_hexdump(msg)); + return -1; + } + + msgb_free(msg); + + return 0; +} + +static int ipa_rx_msg_sccp(struct osmo_ss7_asp *asp, struct msgb *msg) +{ + struct osmo_mtp_prim *omp; + struct m3ua_data_hdr data_hdr; + struct xua_msg *xua = xua_msg_alloc(); + + /* pull the IPA header */ + msgb_pull_to_l2(msg); + + /* We have received an IPA-encapsulated SCCP message, without + * any MTP routing label. This means we have no real idea where + * it came from, nor where it goes to. We could simply treat it + * as being for the local point code, but then this means that + * we would have to implement SCCP connection coupling in order + * to route the connections to any other point code. The reason + * for this is the lack of addressing information inside the + * non-CR/CC connection oriented messages. + * + * The only other alternative we have is to simply have a + * STP (server) side configuration that specifies which point + * code those messages are to be routed to, and then use this + * 'override DPC' in the routing decision. We could do the same + * for the source point code to ensure responses are routed back + * to us. This is all quite ugly, but then what can we do :/ + */ + + memset(&data_hdr, 0, sizeof(data_hdr)); + data_hdr.opc = 0;//FIXME; + data_hdr.dpc = 0;//FIXME; + data_hdr.si = MTP_SI_SCCP; + xua = m3ua_xfer_from_data(&data_hdr, msgb_l2(msg), msgb_l2len(msg)); + + return m3ua_hmdc_rx_from_l2(asp->inst, xua); +} + +/*! \brief process M3UA message received from socket + * \param[in] asp Application Server Process receiving \a msg + * \param[in] msg received message buffer. Callee takes ownership! + * \returns 0 on success; negative on error */ +int ipa_rx_msg(struct osmo_ss7_asp *asp, struct msgb *msg) +{ + struct ipaccess_head *hh; + uint16_t len; + int rc; + + OSMO_ASSERT(asp->cfg.proto == OSMO_SS7_ASP_PROT_IPA); + + /* osmo_ipa_process_msg() will already have verified length + * consistency and set up l2h poiter */ + hh = (struct ipaccess_head *) msg->l1h; + + switch (hh->proto) { + case IPAC_PROTO_IPACCESS: + rc = ipa_rx_msg_ccm(asp, msg); + break; + case IPAC_PROTO_SCCP: + rc = ipa_rx_msg_sccp(asp, msg); + break; + default: + LOGPASP(asp, DLSS7, LOGL_DEBUG, "Unknown Stream ID 0x%02x: %s\n", + hh->proto, msgb_hexdump(msg)); + rc = -1; + } + + return rc; +} diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index 4aa7be5..ffe587c 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -41,6 +41,7 @@ #include #include +#include #include "sccp_internal.h" #include "xua_internal.h" @@ -68,11 +69,24 @@ { OSMO_SS7_ASP_PROT_NONE, "none" }, { OSMO_SS7_ASP_PROT_SUA, "sua" }, { OSMO_SS7_ASP_PROT_M3UA, "m3ua" }, + { OSMO_SS7_ASP_PROT_IPA, "ipa" }, { 0, NULL } }; #define LOGSS7(inst, level, fmt, args ...) \ LOGP(DLSS7, level, "%u: " fmt, inst ? (inst)->cfg.id : 0, ## args) + +static int asp_proto_to_ip_proto(enum osmo_ss7_asp_protocol proto) +{ + switch (proto) { + case OSMO_SS7_ASP_PROT_IPA: + return IPPROTO_TCP; + case OSMO_SS7_ASP_PROT_SUA: + case OSMO_SS7_ASP_PROT_M3UA: + default: + return IPPROTO_SCTP; + } +} int osmo_ss7_find_free_rctx(struct osmo_ss7_instance *inst) { @@ -1070,6 +1084,7 @@ } static int xua_cli_read_cb(struct osmo_stream_cli *conn); +static int ipa_cli_read_cb(struct osmo_stream_cli *conn); static int xua_cli_connect_cb(struct osmo_stream_cli *cli); int osmo_ss7_asp_restart(struct osmo_ss7_asp *asp) @@ -1100,10 +1115,13 @@ osmo_stream_cli_set_port(asp->client, asp->cfg.remote.port); osmo_stream_cli_set_local_addr(asp->client, asp->cfg.local.host); osmo_stream_cli_set_local_port(asp->client, asp->cfg.local.port); - osmo_stream_cli_set_proto(asp->client, IPPROTO_SCTP); + osmo_stream_cli_set_proto(asp->client, asp_proto_to_ip_proto(asp->cfg.proto)); osmo_stream_cli_set_reconnect_timeout(asp->client, 5); osmo_stream_cli_set_connect_cb(asp->client, xua_cli_connect_cb); - osmo_stream_cli_set_read_cb(asp->client, xua_cli_read_cb); + if (asp->cfg.proto == OSMO_SS7_ASP_PROT_IPA) + osmo_stream_cli_set_read_cb(asp->client, ipa_cli_read_cb); + else + osmo_stream_cli_set_read_cb(asp->client, xua_cli_read_cb); osmo_stream_cli_set_data(asp->client, asp); rc = osmo_stream_cli_open2(asp->client, 1); if (rc < 0) { @@ -1213,6 +1231,37 @@ notif->sn_header.sn_type)); break; } +} + +/* netif code tells us we can read something from the socket */ +static int ipa_srv_conn_cb(struct osmo_stream_srv *conn) +{ + struct osmo_fd *ofd = osmo_stream_srv_get_ofd(conn); + struct osmo_ss7_asp *asp = osmo_stream_srv_get_data(conn); + struct msgb *msg = NULL; + int rc; + + /* read IPA message from socket and process it */ + rc = ipa_msg_recv_buffered(ofd->fd, &msg, &asp->pending_msg); + LOGPASP(asp, DLSS7, LOGL_DEBUG, "%s(): ipa_msg_recv_buffered() returned %d\n", + __func__, rc); + if (rc <= 0) { + if (rc == -EAGAIN) { + /* more data needed */ + return 0; + } + osmo_stream_srv_destroy(conn); + return rc; + } + if (osmo_ipa_process_msg(msg) < 0) { + LOGPASP(asp, DLSS7, LOGL_ERROR, "Bad IPA message\n"); + osmo_stream_srv_destroy(conn); + msgb_free(msg); + return -1; + } + msg->dst = asp; + + return ipa_rx_msg(asp, msg); } /* netif code tells us we can read something from the socket */ @@ -1327,6 +1376,36 @@ osmo_stream_cli_reconnect(cli); } +/* read call-back for IPA/SCCPlite socket */ +static int ipa_cli_read_cb(struct osmo_stream_cli *conn) +{ + struct osmo_fd *ofd = osmo_stream_cli_get_ofd(conn); + struct osmo_ss7_asp *asp = osmo_stream_cli_get_data(conn); + struct msgb *msg = NULL; + int rc; + + /* read IPA message from socket and process it */ + rc = ipa_msg_recv_buffered(ofd->fd, &msg, &asp->pending_msg); + LOGPASP(asp, DLSS7, LOGL_DEBUG, "%s(): ipa_msg_recv_buffered() returned %d\n", + __func__, rc); + if (rc <= 0) { + if (rc == -EAGAIN) { + /* more data needed */ + return 0; + } + osmo_stream_cli_reconnect(conn); + return rc; + } + if (osmo_ipa_process_msg(msg) < 0) { + LOGPASP(asp, DLSS7, LOGL_ERROR, "Bad IPA message\n"); + osmo_stream_cli_reconnect(conn); + msgb_free(msg); + return -1; + } + msg->dst = asp; + return ipa_rx_msg(asp, msg); +} + static int xua_cli_read_cb(struct osmo_stream_cli *conn) { struct osmo_fd *ofd = osmo_stream_cli_get_ofd(conn); @@ -1439,15 +1518,21 @@ struct osmo_ss7_asp *asp; char *sock_name = osmo_sock_get_name(link, fd); - LOGP(DLSS7, LOGL_INFO, "%s: New SCTP connection accepted\n", - sock_name); + LOGP(DLSS7, LOGL_INFO, "%s: New %s connection accepted\n", + sock_name, get_value_string(osmo_ss7_asp_protocol_vals, oxs->cfg.proto)); - srv = osmo_stream_srv_create(oxs, link, fd, - xua_srv_conn_cb, - xua_srv_conn_closed_cb, NULL); + if (oxs->cfg.proto == OSMO_SS7_ASP_PROT_IPA) { + srv = osmo_stream_srv_create(oxs, link, fd, + ipa_srv_conn_cb, + xua_srv_conn_closed_cb, NULL); + } else { + srv = osmo_stream_srv_create(oxs, link, fd, + xua_srv_conn_cb, + xua_srv_conn_closed_cb, NULL); + } if (!srv) { LOGP(DLSS7, LOGL_ERROR, "%s: Unable to create stream server " - "for SCTP connection\n", sock_name); + "for connection\n", sock_name); close(fd); talloc_free(sock_name); return -1; @@ -1473,6 +1558,7 @@ sock_name, asp->cfg.name); asp->cfg.is_server = true; asp->dyn_allocated = true; + asp->server = srv; osmo_ss7_asp_restart(asp); } } @@ -1517,6 +1603,8 @@ break; case OSMO_SS7_ASP_PROT_M3UA: msgb_sctp_ppid(msg) = M3UA_PPID; + break; + case OSMO_SS7_ASP_PROT_IPA: break; default: OSMO_ASSERT(0); @@ -1589,8 +1677,8 @@ if (!oxs) return NULL; - LOGP(DLSS7, LOGL_INFO, "Creating XUA Server %s:%u\n", - local_host, local_port); + LOGP(DLSS7, LOGL_INFO, "Creating %s Server %s:%u\n", + get_value_string(osmo_ss7_asp_protocol_vals, proto), local_host, local_port); INIT_LLIST_HEAD(&oxs->asp_list); @@ -1605,7 +1693,7 @@ osmo_stream_srv_link_set_nodelay(oxs->server, true); osmo_stream_srv_link_set_addr(oxs->server, oxs->cfg.local.host); osmo_stream_srv_link_set_port(oxs->server, oxs->cfg.local.port); - osmo_stream_srv_link_set_proto(oxs->server, IPPROTO_SCTP); + osmo_stream_srv_link_set_proto(oxs->server, asp_proto_to_ip_proto(proto)); rc = osmo_stream_srv_link_open(oxs->server); if (rc < 0) { @@ -1664,6 +1752,7 @@ osmo_fsm_register(&sccp_scoc_fsm); osmo_fsm_register(&xua_as_fsm); osmo_fsm_register(&xua_asp_fsm); + osmo_fsm_register(&ipa_asp_fsm); osmo_fsm_register(&xua_default_lm_fsm); ss7_initialized = true; return 0; diff --git a/src/osmo_ss7_hmrt.c b/src/osmo_ss7_hmrt.c index ce0728b..bbbb3a9 100644 --- a/src/osmo_ss7_hmrt.c +++ b/src/osmo_ss7_hmrt.c @@ -141,6 +141,8 @@ switch (as->cfg.proto) { case OSMO_SS7_ASP_PROT_M3UA: return m3ua_tx_xua_as(as,xua); + case OSMO_SS7_ASP_PROT_IPA: + return ipa_tx_xua_as(as, xua); default: LOGP(DLSS7, LOGL_ERROR, "MTP message " "for ASP of unknown protocol%u\n", diff --git a/src/osmo_ss7_vty.c b/src/osmo_ss7_vty.c index 282a5a0..a6a0f5b 100644 --- a/src/osmo_ss7_vty.c +++ b/src/osmo_ss7_vty.c @@ -37,11 +37,12 @@ #include "xua_internal.h" -#define XUA_VAR_STR "(sua|m3ua)" +#define XUA_VAR_STR "(sua|m3ua|ipa)" #define XUA_VAR_HELP_STR \ "SCCP User Adaptation\n" \ - "MTP3 User Adaptation\n" + "MTP3 User Adaptation\n" \ + "IPA Multiplex (SCCP Lite)\n" /*********************************************************************** diff --git a/src/sccp_scrc.c b/src/sccp_scrc.c index 4491ce6..9a6a865 100644 --- a/src/sccp_scrc.c +++ b/src/sccp_scrc.c @@ -142,6 +142,7 @@ case OSMO_SS7_ASP_PROT_SUA: return sua_tx_xua_as(as, xua); case OSMO_SS7_ASP_PROT_M3UA: + case OSMO_SS7_ASP_PROT_IPA: return sua2sccp_tx_m3ua(inst, xua); default: LOGP(DLSCCP, LOGL_ERROR, "MTP-TRANSFER.req for " @@ -296,7 +297,8 @@ const struct osmo_sccp_addr *called) { struct osmo_sccp_user *scu; - + /* it is not really clear that called->pc will be set to + * anything here, in the case of a SSN-only CalledAddr */ scu = sccp_user_find(inst, called->ssn, called->pc); /* Is subsystem equipped? */ diff --git a/src/sccp_user.c b/src/sccp_user.c index 51cc6b1..d9e40b6 100644 --- a/src/sccp_user.c +++ b/src/sccp_user.c @@ -274,7 +274,8 @@ asp->cfg.local.host = talloc_strdup(asp, local_ip); asp->cfg.remote.host = talloc_strdup(asp, remote_ip); osmo_ss7_as_add_asp(as, asp_name); - osmo_ss7_asp_use_default_lm(asp, LOGL_DEBUG); + if (prot != OSMO_SS7_ASP_PROT_IPA) + osmo_ss7_asp_use_default_lm(asp, LOGL_DEBUG); talloc_free(asp_name); osmo_ss7_asp_restart(asp); diff --git a/src/xua_as_fsm.c b/src/xua_as_fsm.c index 282a6bf..0dd6ba1 100644 --- a/src/xua_as_fsm.c +++ b/src/xua_as_fsm.c @@ -38,6 +38,10 @@ struct msgb *msg; unsigned int i, sent = 0; + /* we don't send notify to IPA peers! */ + if (as->cfg.proto == OSMO_SS7_ASP_PROT_IPA) + return 0; + /* iterate over all non-DOWN ASPs and send them the message */ for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) { struct osmo_ss7_asp *asp = as->cfg.asps[i]; @@ -66,7 +70,7 @@ } /* actually transmit a message through this AS */ -static int xua_as_transmit_msg(struct osmo_ss7_as *as, struct msgb *msg) +int xua_as_transmit_msg(struct osmo_ss7_as *as, struct msgb *msg) { struct osmo_ss7_asp *asp; unsigned int i; diff --git a/src/xua_asp_fsm.c b/src/xua_asp_fsm.c index ce15038..147aa45 100644 --- a/src/xua_asp_fsm.c +++ b/src/xua_asp_fsm.c @@ -14,6 +14,11 @@ #include #include #include +#include +#include + +#include +#include #include #include @@ -65,6 +70,14 @@ { XUA_ASP_E_ASPSM_ASPDN_ACK, "ASPSM-ASP_DN_ACK" }, { XUA_ASP_E_ASPTM_ASPIA, "ASPTM-ASP_IA" }, { XUA_ASP_E_ASPTM_ASPIA_ACK, "ASPTM_ASP_IA_ACK" }, + + { XUA_ASP_E_ASPSM_BEAT, "ASPSM_BEAT" }, + { XUA_ASP_E_ASPSM_BEAT_ACK, "ASPSM_BEAT_ACK" }, + + { IPA_ASP_E_ID_RESP, "IPA_CCM_ID_RESP" }, + { IPA_ASP_E_ID_GET, "IPA_CCM_ID_GET" }, + { IPA_ASP_E_ID_ACK, "IPA_CCM_ID_ACK" }, + { 0, NULL } }; @@ -654,6 +667,8 @@ .allstate_action = xua_asp_allstate, }; +static struct osmo_fsm_inst *ipa_asp_fsm_start(struct osmo_ss7_asp *asp, + enum xua_asp_role role, int log_level); /*! \brief Start a new ASP finite stae machine for given ASP * \param[in] asp Application Server Process for which to start FSM @@ -665,6 +680,9 @@ { struct osmo_fsm_inst *fi; struct xua_asp_fsm_priv *xafp; + + if (asp->cfg.proto == OSMO_SS7_ASP_PROT_IPA) + return ipa_asp_fsm_start(asp, role, log_level); /* allocate as child of AS? */ fi = osmo_fsm_inst_alloc(&xua_asp_fsm, asp, NULL, log_level, asp->cfg.name); @@ -681,3 +699,352 @@ return fi; } + + + + + +/*********************************************************************** + * IPA Compatibility FSM + ***********************************************************************/ + +/* The idea here is to have a FSM that handles an IPA / SCCPlite link in + * a way that the higher-layer code considers it the same like an M3UA + * or SUA link. We have a couple of different states and some + * additional events. */ + +enum ipa_asp_state { + IPA_ASP_S_DOWN = XUA_ASP_S_DOWN, + IPA_ASP_S_ACTIVE = XUA_ASP_S_ACTIVE, + IPA_ASP_S_WAIT_ID_RESP, /* Waiting for ID_RESP from peer */ + IPA_ASP_S_WAIT_ID_GET, /* Waiting for ID_GET from peer */ + IPA_ASP_S_WAIT_ID_ACK, /* Waiting for ID_ACK from peer */ + IPA_ASP_S_WAIT_ID_ACK2, /* Waiting for ID_ACK (of ACK) from peer */ +}; + +/* private data structure for each FSM instance */ +struct ipa_asp_fsm_priv { + /* pointer back to ASP to which we belong */ + struct osmo_ss7_asp *asp; + /* Role (ASP/SG/IPSP) */ + enum xua_asp_role role; + + /* Structure holding parsed data of the IPA CCM ID exchange */ + struct ipaccess_unit *ipa_unit; + /* Timer for tracking if no PONG is received in response to PING */ + struct osmo_timer_list pong_timer; +}; + +enum ipa_asp_fsm_t { + T_WAIT_ID_RESP = 1, + T_WAIT_ID_ACK, + T_WAIT_ID_GET, +}; + +/* get the file descriptor related to a given ASP */ +static int get_fd_from_iafp(struct ipa_asp_fsm_priv *iafp) +{ + struct osmo_ss7_asp *asp = iafp->asp; + struct osmo_fd *ofd; + + if (asp->server) + ofd = osmo_stream_srv_get_ofd(asp->server); + else if (asp->client) + ofd = osmo_stream_cli_get_ofd(asp->client); + else + return -1; + + return ofd->fd; +} + +/* Server + Client: Initial State, wait for M-ASP-UP.req */ +static void ipa_asp_fsm_down(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct ipa_asp_fsm_priv *iafp = fi->priv; + int fd = get_fd_from_iafp(iafp); + + switch (event) { + case XUA_ASP_E_M_ASP_UP_REQ: + case XUA_ASP_E_SCTP_EST_IND: + if (iafp->role == XUA_ASPFSM_ROLE_SG) { + /* Server: Transmit IPA ID GET + Wait for Response */ + ipa_ccm_send_id_req(fd); + osmo_fsm_inst_state_chg(fi, IPA_ASP_S_WAIT_ID_RESP, 10, T_WAIT_ID_RESP); + } else { + /* Client: We simply wait for an ID GET */ + osmo_fsm_inst_state_chg(fi, IPA_ASP_S_WAIT_ID_GET, 10, T_WAIT_ID_GET); + } + break; + } +} + +/* Server: We're waiting for an ID RESP */ +static void ipa_asp_fsm_wait_id_resp(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct ipa_asp_fsm_priv *iafp = fi->priv; + struct osmo_ss7_asp *asp = iafp->asp; + int fd = get_fd_from_iafp(iafp); + struct osmo_ss7_as *as; + struct tlv_parsed tp; + struct msgb *msg; + int rc; + + switch (event) { + case IPA_ASP_E_ID_RESP: + /* resolve the AS based on the identity provided by peer. */ + msg = data; + rc = ipa_ccm_idtag_parse(&tp, msgb_l2(msg)+2, msgb_l2len(msg)-2); + if (rc < 0) { + LOGPFSML(fi, LOGL_ERROR, "Error %d parsing ID_RESP TLV: %s\n", rc, + msgb_hexdump(msg)); + goto out_err; + } + rc = ipa_ccm_tlv_to_unitdata(iafp->ipa_unit, &tp); + if (rc < 0) { + LOGPFSML(fi, LOGL_ERROR, "Error %d parsing ID_RESP: %s\n", rc, msgb_hexdump(msg)); + goto out_err; + } + if (!iafp->ipa_unit->unit_name) { + LOGPFSML(fi, LOGL_NOTICE, "No Unit Name specified by client\n"); + goto out_err; + } + as = osmo_ss7_as_find_by_name(asp->inst, iafp->ipa_unit->unit_name); + if (!as) { + LOGPFSML(fi, LOGL_NOTICE, "Cannot find any definition for IPA Unit Name '%s'\n", + iafp->ipa_unit->unit_name); + goto out_err; + } + osmo_ss7_as_add_asp(as, asp->cfg.name); + /* TODO: OAP Authentication? */ + /* Send ID_ACK */ + ipaccess_send_id_ack(fd); + osmo_fsm_inst_state_chg(fi, IPA_ASP_S_WAIT_ID_ACK2, 10, T_WAIT_ID_ACK); + break; + } + return; +out_err: + osmo_ss7_asp_disconnect(asp); + return; +} + +/* Server: We're waiting for an ID ACK */ +static void ipa_asp_fsm_wait_id_ack2(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + switch (event) { + case IPA_ASP_E_ID_ACK: + /* ACK received, we can go to active state now. The + * ACTIVE onenter function will inform the AS */ + osmo_fsm_inst_state_chg(fi, IPA_ASP_S_ACTIVE, 0, 0); + break; + } +} + +/* Client: We're waiting for an ID GET */ +static void ipa_asp_fsm_wait_id_get(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct ipa_asp_fsm_priv *iafp = fi->priv; + struct osmo_ss7_asp *asp = iafp->asp; + struct msgb *msg_get, *msg_resp; + const uint8_t *req_data; + int data_len; + + switch (event) { + case IPA_ASP_E_ID_GET: + msg_get = data; + req_data = msgb_l2(msg_get)+1; + data_len = msgb_l2len(msg_get)-1; + LOGPFSM(fi, "Received IPA CCM IDENTITY REQUEST for IEs %s\n", + osmo_hexdump(req_data, data_len)); + /* Send ID_RESP to server */ + msg_resp = ipa_ccm_make_id_resp_from_req(iafp->ipa_unit, req_data, data_len); + if (!msg_resp) { + LOGPFSML(fi, LOGL_ERROR, "Error building IPA CCM IDENTITY RESPONSE\n"); + break; + } + osmo_ss7_asp_send(asp, msg_resp); + osmo_fsm_inst_state_chg(fi, IPA_ASP_S_WAIT_ID_ACK, 10, T_WAIT_ID_ACK); + break; + } +} + +/* Client: We're waiting for an ID ACK */ +static void ipa_asp_fsm_wait_id_ack(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct ipa_asp_fsm_priv *iafp = fi->priv; + int fd; + + switch (event) { + case IPA_ASP_E_ID_ACK: + /* Send ACK2 to server */ + fd = get_fd_from_iafp(iafp); + ipaccess_send_id_ack(fd); + osmo_fsm_inst_state_chg(fi, IPA_ASP_S_ACTIVE, 0, 0); + break; + } +} + + +/* Server + Client: We're actively transmitting user data */ +static void ipa_asp_fsm_active(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + switch (event) { + case XUA_ASP_E_M_ASP_DOWN_REQ: + case XUA_ASP_E_M_ASP_INACTIVE_REQ: + /* FIXME: kill ASP and (wait for) re-connect */ + break; + } +} + +static void ipa_asp_allstate(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct ipa_asp_fsm_priv *iafp = fi->priv; + int fd; + + switch (event) { + case XUA_ASP_E_SCTP_COMM_DOWN_IND: + case XUA_ASP_E_SCTP_RESTART_IND: + osmo_fsm_inst_state_chg(fi, IPA_ASP_S_DOWN, 0, 0); + send_xlm_prim_simple(fi, OSMO_XLM_PRIM_M_ASP_DOWN, + PRIM_OP_INDICATION); + break; + case XUA_ASP_E_ASPSM_BEAT: + /* PING -> PONG */ + fd = get_fd_from_iafp(iafp); + ipaccess_send_pong(fd); + break; + case XUA_ASP_E_ASPSM_BEAT_ACK: + /* stop timer, if any */ + osmo_timer_del(&iafp->pong_timer); + break; + default: + break; + } +} + +static void ipa_asp_fsm_active_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state) +{ + dispatch_to_all_as(fi, XUA_ASPAS_ASP_INACTIVE_IND); + dispatch_to_all_as(fi, XUA_ASPAS_ASP_ACTIVE_IND); +} + +static void ipa_pong_timer_cb(void *_fi) +{ + struct osmo_fsm_inst *fi = _fi; + struct ipa_asp_fsm_priv *iafp = fi->priv; + + LOGPFSML(fi, LOGL_NOTICE, "Peer didn't respond to PING? with PONG!\n"); + /* kill ASP and (wait for) re-connect */ + osmo_ss7_asp_disconnect(iafp->asp); +} + +static int ipa_asp_fsm_timer_cb(struct osmo_fsm_inst *fi) +{ + struct ipa_asp_fsm_priv *iafp = fi->priv; + + LOGPFSML(fi, LOGL_ERROR, "Timeout waiting for peer response\n"); + /* kill ASP and (wait for) re-connect */ + osmo_ss7_asp_disconnect(iafp->asp); + return -1; +} + +static const struct osmo_fsm_state ipa_asp_states[] = { + [IPA_ASP_S_DOWN] = { + .in_event_mask = S(XUA_ASP_E_M_ASP_UP_REQ) | + S(XUA_ASP_E_SCTP_EST_IND), + .out_state_mask = S(IPA_ASP_S_WAIT_ID_GET) | + S(IPA_ASP_S_WAIT_ID_RESP), + .name = "ASP_DOWN", + .action = ipa_asp_fsm_down, + .onenter = xua_asp_fsm_down_onenter, + }, + /* Server Side */ + [IPA_ASP_S_WAIT_ID_RESP] = { + .in_event_mask = S(IPA_ASP_E_ID_RESP), + .out_state_mask = S(IPA_ASP_S_WAIT_ID_ACK2) | + S(IPA_ASP_S_DOWN), + .name = "WAIT_ID_RESP", + .action = ipa_asp_fsm_wait_id_resp, + }, + /* Server Side */ + [IPA_ASP_S_WAIT_ID_ACK2] = { + .in_event_mask = S(IPA_ASP_E_ID_ACK), + .out_state_mask = S(IPA_ASP_S_ACTIVE) | + S(IPA_ASP_S_DOWN), + .name = "WAIT_ID_ACK2", + .action = ipa_asp_fsm_wait_id_ack2, + }, + /* Client Side */ + [IPA_ASP_S_WAIT_ID_GET] = { + .in_event_mask = S(IPA_ASP_E_ID_GET), + .out_state_mask = S(IPA_ASP_S_WAIT_ID_ACK), + .name = "WAIT_ID_GET", + .action = ipa_asp_fsm_wait_id_get, + }, + /* Client Side */ + [IPA_ASP_S_WAIT_ID_ACK] = { + .in_event_mask = S(IPA_ASP_E_ID_ACK), + .out_state_mask = S(IPA_ASP_S_ACTIVE) | + S(IPA_ASP_S_DOWN), + .name = "WAIT_ID_ACK", + .action = ipa_asp_fsm_wait_id_ack, + }, + [IPA_ASP_S_ACTIVE] = { + .in_event_mask = S(XUA_ASP_E_M_ASP_DOWN_REQ) | + S(XUA_ASP_E_M_ASP_INACTIVE_REQ), + .out_state_mask = S(XUA_ASP_S_INACTIVE) | + S(XUA_ASP_S_DOWN), + .name = "ASP_ACTIVE", + .action = ipa_asp_fsm_active, + .onenter = ipa_asp_fsm_active_onenter, + }, +}; + + +struct osmo_fsm ipa_asp_fsm = { + .name = "IPA_ASP", + .states = ipa_asp_states, + .num_states = ARRAY_SIZE(ipa_asp_states), + .timer_cb = ipa_asp_fsm_timer_cb, + .log_subsys = DLSS7, + .event_names = xua_asp_event_names, + .allstate_event_mask = S(XUA_ASP_E_SCTP_COMM_DOWN_IND) | + S(XUA_ASP_E_SCTP_RESTART_IND) | + S(XUA_ASP_E_ASPSM_BEAT) | + S(XUA_ASP_E_ASPSM_BEAT_ACK), + .allstate_action = ipa_asp_allstate, +}; + + +/*! \brief Start a new ASP finite stae machine for given ASP + * \param[in] asp Application Server Process for which to start FSM + * \param[in] role Role (ASP, SG, IPSP) of this FSM + * \param[in] log_level Logging Level for ASP FSM logging + * \returns FSM instance on success; NULL on error */ +static struct osmo_fsm_inst *ipa_asp_fsm_start(struct osmo_ss7_asp *asp, + enum xua_asp_role role, int log_level) +{ + struct osmo_fsm_inst *fi; + struct ipa_asp_fsm_priv *iafp; + + /* allocate as child of AS? */ + fi = osmo_fsm_inst_alloc(&ipa_asp_fsm, asp, NULL, log_level, asp->cfg.name); + + iafp = talloc_zero(fi, struct ipa_asp_fsm_priv); + if (!iafp) { + osmo_fsm_inst_term(fi, OSMO_FSM_TERM_ERROR, NULL); + return NULL; + } + iafp->role = role; + iafp->asp = asp; + iafp->ipa_unit = talloc_zero(iafp, struct ipaccess_unit); + iafp->ipa_unit->unit_name = talloc_strdup(iafp->ipa_unit, asp->cfg.name); + iafp->pong_timer.cb = ipa_pong_timer_cb; + iafp->pong_timer.data = fi; + + fi->priv = iafp; + + if (role == XUA_ASPFSM_ROLE_ASP) + osmo_fsm_inst_dispatch(fi, XUA_ASP_E_M_ASP_UP_REQ, NULL); + + return fi; +} diff --git a/src/xua_asp_fsm.h b/src/xua_asp_fsm.h index 60e09da..32749ec 100644 --- a/src/xua_asp_fsm.h +++ b/src/xua_asp_fsm.h @@ -28,6 +28,11 @@ XUA_ASP_E_ASPSM_BEAT, XUA_ASP_E_ASPSM_BEAT_ACK, + /* IPA specific */ + IPA_ASP_E_ID_RESP, + IPA_ASP_E_ID_ACK, + IPA_ASP_E_ID_GET, + _NUM_XUA_ASP_E }; @@ -38,6 +43,7 @@ }; extern struct osmo_fsm xua_asp_fsm; +extern struct osmo_fsm ipa_asp_fsm; struct osmo_fsm_inst *xua_asp_fsm_start(struct osmo_ss7_asp *asp, enum xua_asp_role role, int log_level); diff --git a/src/xua_internal.h b/src/xua_internal.h index 3831f56..bb54205 100644 --- a/src/xua_internal.h +++ b/src/xua_internal.h @@ -66,3 +66,9 @@ #define CS7_STR "ITU-T Signaling System 7\n" #define PC_STR "Point Code\n" #define INST_STR "An instance of the SS7 stack\n" + +int xua_as_transmit_msg(struct osmo_ss7_as *as, struct msgb *msg); + + +int ipa_tx_xua_as(struct osmo_ss7_as *as, struct xua_msg *xua); +int ipa_rx_msg(struct osmo_ss7_asp *asp, struct msgb *msg); -- To view, visit https://gerrit.osmocom.org/2282 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I9098574cddeba10fcf8f1b6c196a7069a6805c56 Gerrit-PatchSet: 2 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sat Apr 15 20:54:50 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 15 Apr 2017 20:54:50 +0000 Subject: [PATCH] libosmo-sccp[master]: osmo_ss7: Fix protocol of dynamically allocated ASPs Message-ID: Review at https://gerrit.osmocom.org/2359 osmo_ss7: Fix protocol of dynamically allocated ASPs When dynamically allocating ASPs, we used the hardcoded M3UA protocol, which is of course wrong in case of SUA or other protocols. Let's use the xua_server's configured protocol for the created ASPs. Change-Id: I07832cbaf1ca42f0c7df399e4f96599034b72816 --- M src/osmo_ss7.c 1 file changed, 1 insertion(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/59/2359/1 diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index 57d9d39..907d932 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -1464,7 +1464,7 @@ static uint32_t dyn_asp_num = 0; snprintf(namebuf, sizeof(namebuf), "asp-dyn-%u", dyn_asp_num++); asp = osmo_ss7_asp_find_or_create(oxs->inst, namebuf, 0, 0, - OSMO_SS7_ASP_PROT_M3UA); + oxs->cfg.proto); if (asp) { LOGP(DLSS7, LOGL_INFO, "%s: created dynamicASP %s\n", sock_name, asp->cfg.name); -- To view, visit https://gerrit.osmocom.org/2359 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I07832cbaf1ca42f0c7df399e4f96599034b72816 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Sat Apr 15 20:54:51 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 15 Apr 2017 20:54:51 +0000 Subject: [PATCH] libosmo-sccp[master]: m3ua: Generalize + Export function to generate MTP-TRANSFER ... Message-ID: Review at https://gerrit.osmocom.org/2360 m3ua: Generalize + Export function to generate MTP-TRANSFER xua_msg Change-Id: If82956317ec703341514ad81057eceb3d0714f47 --- M src/m3ua.c M src/osmo_ss7_hmrt.c M src/xua_internal.h 3 files changed, 27 insertions(+), 16 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/60/2360/1 diff --git a/src/m3ua.c b/src/m3ua.c index a7ef06c..b204708 100644 --- a/src/m3ua.c +++ b/src/m3ua.c @@ -318,6 +318,30 @@ M3UA_MSG_HEADROOM, name); } +struct xua_msg *m3ua_xfer_from_data(const struct m3ua_data_hdr *data_hdr, + const uint8_t *data, unsigned int data_len) +{ + struct xua_msg *xua = xua_msg_alloc(); + struct xua_msg_part *data_part; + + xua->hdr = XUA_HDR(M3UA_MSGC_XFER, M3UA_XFER_DATA); + /* Network Appearance: Optional */ + /* Routing Context: Conditional */ + /* Protocol Data: Mandatory */ + data_part = talloc_zero(xua, struct xua_msg_part); + OSMO_ASSERT(data_part); + data_part->tag = M3UA_IEI_PROT_DATA; + data_part->len = sizeof(*data_hdr) + data_len; + data_part->dat = talloc_size(data_part, data_part->len); + OSMO_ASSERT(data_part->dat); + memcpy(data_part->dat, data_hdr, sizeof(*data_hdr)); + memcpy(data_part->dat+sizeof(*data_hdr), data, data_len); + llist_add_tail(&data_part->entry, &xua->headers); + /* Correlation Id: Optional */ + + return xua; +} + /*********************************************************************** * ERROR generation ***********************************************************************/ diff --git a/src/osmo_ss7_hmrt.c b/src/osmo_ss7_hmrt.c index 105a542..ce0728b 100644 --- a/src/osmo_ss7_hmrt.c +++ b/src/osmo_ss7_hmrt.c @@ -51,27 +51,12 @@ static struct xua_msg *mtp_prim_to_m3ua(struct osmo_mtp_prim *prim) { struct msgb *msg = prim->oph.msg; - struct xua_msg *xua = xua_msg_alloc(); struct osmo_mtp_transfer_param *param = &prim->u.transfer; - struct xua_msg_part *data_part; struct m3ua_data_hdr data_hdr; mtp_xfer_param_to_m3ua_dh(&data_hdr, param); - xua->hdr = XUA_HDR(M3UA_MSGC_XFER, M3UA_XFER_DATA); - /* Network Appearance: Optional */ - /* Routing Context: Conditional */ - /* Protocol Data: Mandatory */ - data_part = talloc_zero(xua, struct xua_msg_part); - data_part->tag = M3UA_IEI_PROT_DATA; - data_part->len = sizeof(data_hdr) + msgb_l2len(msg); - data_part->dat = talloc_size(data_part, data_part->len); - memcpy(data_part->dat, &data_hdr, sizeof(data_hdr)); - memcpy(data_part->dat+sizeof(data_hdr), msgb_l2(msg), msgb_l2len(msg)); - llist_add_tail(&data_part->entry, &xua->headers); - /* Correlation Id: Optional */ - - return xua; + return m3ua_xfer_from_data(&data_hdr, msgb_l2(msg), msgb_l2len(msg)); } /* delivery given XUA message to given SS7 user */ diff --git a/src/xua_internal.h b/src/xua_internal.h index 31c941e..3831f56 100644 --- a/src/xua_internal.h +++ b/src/xua_internal.h @@ -25,6 +25,8 @@ int m3ua_rx_msg(struct osmo_ss7_asp *asp, struct msgb *msg); struct msgb *m3ua_msgb_alloc(const char *name); +struct xua_msg *m3ua_xfer_from_data(const struct m3ua_data_hdr *data_hdr, + const uint8_t *data, unsigned int data_len); struct m3ua_data_hdr *data_hdr_from_m3ua(struct xua_msg *xua); void m3ua_dh_to_xfer_param(struct osmo_mtp_transfer_param *param, const struct m3ua_data_hdr *mdh); -- To view, visit https://gerrit.osmocom.org/2360 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: If82956317ec703341514ad81057eceb3d0714f47 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Sat Apr 15 20:54:51 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 15 Apr 2017 20:54:51 +0000 Subject: [PATCH] libosmo-sccp[master]: osmo_ss7: avoid crash during disconnect after unknown ASP Message-ID: Review at https://gerrit.osmocom.org/2361 osmo_ss7: avoid crash during disconnect after unknown ASP Change-Id: Ib201f9f480f25ede0f26d4918007ff22fea28824 --- M src/osmo_ss7.c 1 file changed, 3 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/61/2361/1 diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index 907d932..ef0f3da 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -1405,6 +1405,9 @@ LOGP(DLSS7, LOGL_INFO, "%s: SCTP connection closed\n", asp ? asp->cfg.name : "?"); + if (!asp) + return 0; + /* notify ASP FSM and everyone else */ osmo_fsm_inst_dispatch(asp->fi, XUA_ASP_E_SCTP_COMM_DOWN_IND, NULL); -- To view, visit https://gerrit.osmocom.org/2361 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ib201f9f480f25ede0f26d4918007ff22fea28824 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Sat Apr 15 20:54:51 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 15 Apr 2017 20:54:51 +0000 Subject: [PATCH] libosmo-sccp[master]: Add new ASP event XUA_ASP_E_SCTP_EST_IND Message-ID: Review at https://gerrit.osmocom.org/2362 Add new ASP event XUA_ASP_E_SCTP_EST_IND For classic xUA this is not needed, as the server doesn't have to react to establishment of the SCTP connection. The client will start with an ASP_UP_REQ. However, in upcoming IPA support, the FSM will need to react on this event. Change-Id: Ib10914b27f8761ea44a0fdba96c045821223722a --- M src/osmo_ss7.c M src/xua_asp_fsm.c M src/xua_asp_fsm.h 3 files changed, 7 insertions(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/62/2362/1 diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index ef0f3da..0db39ed 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -1496,6 +1496,7 @@ osmo_stream_srv_set_data(srv, asp); /* send M-SCTP_ESTABLISH.ind to Layer Manager */ + osmo_fsm_inst_dispatch(asp->fi, XUA_ASP_E_SCTP_EST_IND, 0); xua_asp_send_xlm_prim_simple(asp, OSMO_XLM_PRIM_M_SCTP_ESTABLISH, PRIM_OP_INDICATION); return 0; diff --git a/src/xua_asp_fsm.c b/src/xua_asp_fsm.c index f4d9cf0..ce15038 100644 --- a/src/xua_asp_fsm.c +++ b/src/xua_asp_fsm.c @@ -55,6 +55,7 @@ { XUA_ASP_E_SCTP_COMM_DOWN_IND, "SCTP-COMM_DOWN.ind" }, { XUA_ASP_E_SCTP_RESTART_IND, "SCTP-RESTART.ind" }, + { XUA_ASP_E_SCTP_EST_IND, "SCTP-EST.ind" }, { XUA_ASP_E_ASPSM_ASPUP, "ASPSM-ASP_UP" }, { XUA_ASP_E_ASPSM_ASPUP_ACK, "ASPSM-ASP_UP_ACK" }, @@ -368,6 +369,8 @@ * the ASP is already marked as ASP-DOWN at the SGP. */ peer_send(fi, XUA_ASP_E_ASPSM_ASPDN_ACK, NULL); break; + case XUA_ASP_E_SCTP_EST_IND: + break; } } @@ -597,7 +600,8 @@ .in_event_mask = S(XUA_ASP_E_M_ASP_UP_REQ) | S(XUA_ASP_E_ASPSM_ASPUP) | S(XUA_ASP_E_ASPSM_ASPUP_ACK) | - S(XUA_ASP_E_ASPSM_ASPDN), + S(XUA_ASP_E_ASPSM_ASPDN) | + S(XUA_ASP_E_SCTP_EST_IND), .out_state_mask = S(XUA_ASP_S_INACTIVE), .name = "ASP_DOWN", .action = xua_asp_fsm_down, diff --git a/src/xua_asp_fsm.h b/src/xua_asp_fsm.h index ea62484..60e09da 100644 --- a/src/xua_asp_fsm.h +++ b/src/xua_asp_fsm.h @@ -14,6 +14,7 @@ XUA_ASP_E_SCTP_COMM_DOWN_IND, XUA_ASP_E_SCTP_RESTART_IND, + XUA_ASP_E_SCTP_EST_IND, XUA_ASP_E_ASPSM_ASPUP, XUA_ASP_E_ASPSM_ASPUP_ACK, -- To view, visit https://gerrit.osmocom.org/2362 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ib10914b27f8761ea44a0fdba96c045821223722a Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Sat Apr 15 20:54:51 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 15 Apr 2017 20:54:51 +0000 Subject: [PATCH] libosmo-sccp[master]: osmo_ss7: fix missing assignment of asp->xua_server Message-ID: Review at https://gerrit.osmocom.org/2363 osmo_ss7: fix missing assignment of asp->xua_server The ASP is supposed to know via which xua_server it was established Also, as removal from the sibling-list is conditional to asp->xua_server being set, we have linked list corruption without this patch. Change-Id: Ic55cfbf2166381a4bf02596ad7bbe66a37e1a76f --- M src/osmo_ss7.c 1 file changed, 1 insertion(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/63/2363/1 diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index 0db39ed..2d34b53 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -1486,6 +1486,7 @@ /* update the ASP reference back to the server over which the * connection came in */ asp->server = srv; + asp->xua_server = oxs; llist_add_tail(&asp->siblings, &oxs->asp_list); /* update the ASP socket name */ if (asp->sock_name) -- To view, visit https://gerrit.osmocom.org/2363 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ic55cfbf2166381a4bf02596ad7bbe66a37e1a76f Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Sat Apr 15 20:54:52 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 15 Apr 2017 20:54:52 +0000 Subject: [PATCH] libosmo-sccp[master]: introduce new osmo_ss7_asp_disconnect() function Message-ID: Review at https://gerrit.osmocom.org/2364 introduce new osmo_ss7_asp_disconnect() function Higher-layer code shouldn't have to worry between client and server difference. It just wants to close the underlying connection for a given ASP - which it now can by means of osmo_ss7_asp_disconnect(). Change-Id: I36b089abd281b8edac8830fda2d8e57cc06cd0a7 --- M include/osmocom/sigtran/osmo_ss7.h M src/osmo_ss7.c 2 files changed, 10 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/64/2364/1 diff --git a/include/osmocom/sigtran/osmo_ss7.h b/include/osmocom/sigtran/osmo_ss7.h index a8c1c3c..76403e2 100644 --- a/include/osmocom/sigtran/osmo_ss7.h +++ b/include/osmocom/sigtran/osmo_ss7.h @@ -309,6 +309,7 @@ void osmo_ss7_as_destroy(struct osmo_ss7_as *as); bool osmo_ss7_as_has_asp(struct osmo_ss7_as *as, struct osmo_ss7_asp *asp); +void osmo_ss7_asp_disconnect(struct osmo_ss7_asp *asp); /*********************************************************************** diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index 2d34b53..4aa7be5 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -1543,6 +1543,15 @@ return 0; } +void osmo_ss7_asp_disconnect(struct osmo_ss7_asp *asp) +{ + if (asp->server) + osmo_stream_srv_destroy(asp->server); + /* the close_cb() will handle the remaining cleanup here */ + else if (asp->client) + xua_cli_close_and_reconnect(asp->client); +} + /*********************************************************************** * SS7 xUA Server ***********************************************************************/ -- To view, visit https://gerrit.osmocom.org/2364 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I36b089abd281b8edac8830fda2d8e57cc06cd0a7 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Sat Apr 15 20:54:52 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 15 Apr 2017 20:54:52 +0000 Subject: [PATCH] libosmo-sccp[master]: osmo_ss7: make sure to re-set all state on client disconnect Message-ID: Review at https://gerrit.osmocom.org/2365 osmo_ss7: make sure to re-set all state on client disconnect When we disconnect a client, make sure that we always go through xua_cli_close_and_reconnect(), which will make sure to notify the ASP FSM using XUA_ASP_E_SCTP_COMM_DOWN_IND. Change-Id: I6859b8549c8cbbe2e8279da0ede562387a066d04 --- M src/osmo_ss7.c 1 file changed, 3 insertions(+), 5 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/65/2365/1 diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index ffe587c..cdaa770 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -1301,7 +1301,6 @@ switch (notif->sn_header.sn_type) { case SCTP_SHUTDOWN_EVENT: osmo_stream_srv_destroy(conn); - osmo_fsm_inst_dispatch(asp->fi, XUA_ASP_E_SCTP_COMM_DOWN_IND, asp); break; case SCTP_ASSOC_CHANGE: if (notif->sn_assoc_change.sac_state == SCTP_RESTART) @@ -1365,7 +1364,7 @@ struct osmo_ss7_asp *asp = osmo_stream_cli_get_data(cli); osmo_stream_cli_close(cli); - + osmo_fsm_inst_dispatch(asp->fi, XUA_ASP_E_SCTP_COMM_DOWN_IND, asp); /* send M-SCTP_RELEASE.ind to XUA Layer Manager */ xua_asp_send_xlm_prim_simple(asp, OSMO_XLM_PRIM_M_SCTP_RELEASE, PRIM_OP_INDICATION); } @@ -1393,12 +1392,12 @@ /* more data needed */ return 0; } - osmo_stream_cli_reconnect(conn); + xua_cli_close_and_reconnect(conn); return rc; } if (osmo_ipa_process_msg(msg) < 0) { LOGPASP(asp, DLSS7, LOGL_ERROR, "Bad IPA message\n"); - osmo_stream_cli_reconnect(conn); + xua_cli_close_and_reconnect(conn); msgb_free(msg); return -1; } @@ -1440,7 +1439,6 @@ switch (notif->sn_header.sn_type) { case SCTP_SHUTDOWN_EVENT: - osmo_fsm_inst_dispatch(asp->fi, XUA_ASP_E_SCTP_COMM_DOWN_IND, asp); xua_cli_close_and_reconnect(conn); break; case SCTP_ASSOC_CHANGE: -- To view, visit https://gerrit.osmocom.org/2365 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I6859b8549c8cbbe2e8279da0ede562387a066d04 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Sat Apr 15 20:55:07 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 15 Apr 2017 20:55:07 +0000 Subject: libosmo-netif[master]: netif/ipa.h: Don't redefine 'struct ipaccess_unit' from libo... In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2352 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: If378a088c741df540befb928a5557fc62dea954a Gerrit-PatchSet: 1 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sat Apr 15 20:55:09 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 15 Apr 2017 20:55:09 +0000 Subject: [MERGED] libosmo-netif[master]: netif/ipa.h: Don't redefine 'struct ipaccess_unit' from libo... In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: netif/ipa.h: Don't redefine 'struct ipaccess_unit' from libosmocore ...................................................................... netif/ipa.h: Don't redefine 'struct ipaccess_unit' from libosmocore 'struct ipaccess_unit' is defined in libosmocore/gsm/ipa.h, we shouldn't re-define it here. This entire IPA code duplication accross multiple libraries and programs is a big mess. Change-Id: If378a088c741df540befb928a5557fc62dea954a --- M include/osmocom/netif/ipa.h 1 file changed, 1 insertion(+), 13 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/include/osmocom/netif/ipa.h b/include/osmocom/netif/ipa.h index 8d221e3..0a29f01 100644 --- a/include/osmocom/netif/ipa.h +++ b/include/osmocom/netif/ipa.h @@ -2,6 +2,7 @@ #define _OSMO_NETIF_IPA_H_ #include +#include /* This is like 'struct ipaccess_head' in libosmocore, but 'ipa_head' is * actually the more apropriate name, so rather than making more code @@ -21,19 +22,6 @@ void osmo_ipa_msg_push_header(struct msgb *msg, uint8_t proto); int osmo_ipa_process_msg(struct msgb *msg); - -struct ipaccess_unit { - uint16_t site_id; - uint16_t bts_id; - uint16_t trx_id; - char *unit_name; - char *equipvers; - char *swversion; - uint8_t mac_addr[6]; - char *location1; - char *location2; - char *serno; -}; struct osmo_fd; struct tlv_parsed; -- To view, visit https://gerrit.osmocom.org/2352 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: If378a088c741df540befb928a5557fc62dea954a Gerrit-PatchSet: 1 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sat Apr 15 20:56:09 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 15 Apr 2017 20:56:09 +0000 Subject: [PATCH] libosmocore[master]: msgb: Add msgb_pull_to_l2() analogous to msgb_pull_to_l3() Message-ID: Review at https://gerrit.osmocom.org/2366 msgb: Add msgb_pull_to_l2() analogous to msgb_pull_to_l3() Introduce msgb_pull_to_l2() which pulls (removes) any msgb contents in front of the L2 header (msg->l2h). Change-Id: I7786a1b30f9e7eaa3dcdb3cbb2a85a126588f6cd --- M include/osmocom/core/msgb.h 1 file changed, 15 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/66/2366/1 diff --git a/include/osmocom/core/msgb.h b/include/osmocom/core/msgb.h index 9cb1c24..afb887c 100644 --- a/include/osmocom/core/msgb.h +++ b/include/osmocom/core/msgb.h @@ -350,6 +350,21 @@ return ret; } +/*! \brief remove (pull) all headers in front of l2h from the message buffer. + * \param[in] msgb message buffer with a valid l2h + * \returns pointer to new start of msgb (l2h) + * + * This function moves the \a data pointer of the \ref msgb further back + * in the message, thereby shrinking the size of the message. + * l1h will be cleared. + */ +static inline unsigned char *msgb_pull_to_l2(struct msgb *msg) +{ + unsigned char *ret = msgb_pull(msg, msg->l2h - msg->data); + msg->l1h = NULL; + return ret; +} + /*! \brief remove uint8 from front of message * \param[in] msgb message buffer * \returns 8bit value taken from end of msgb -- To view, visit https://gerrit.osmocom.org/2366 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I7786a1b30f9e7eaa3dcdb3cbb2a85a126588f6cd Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Sat Apr 15 20:56:10 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 15 Apr 2017 20:56:10 +0000 Subject: [PATCH] libosmocore[master]: ipa: Introduce helpers to encode IPA CCM ID RESPONSE Message-ID: Review at https://gerrit.osmocom.org/2367 ipa: Introduce helpers to encode IPA CCM ID RESPONSE The ipa.c file already contained code to parse an ID RESPONSE into the 'struct ipaccess_unit', but it didn't so far contain code to put together an ID RESPONSE packet based on that structure. Let's change that with ipa_ccm_make_id_resp() and a helper wrapper ipa_ccm_make_id_resp_from_req(). Change-Id: Icbcd8827a75fd5f3393351c1ca372de85275ad35 --- M include/osmocom/gsm/ipa.h M src/gsm/ipa.c M src/gsm/libosmogsm.map 3 files changed, 127 insertions(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/67/2367/1 diff --git a/include/osmocom/gsm/ipa.h b/include/osmocom/gsm/ipa.h index 0bb01c5..cabee13 100644 --- a/include/osmocom/gsm/ipa.h +++ b/include/osmocom/gsm/ipa.h @@ -37,6 +37,13 @@ int ipa_ccm_tlv_to_unitdata(struct ipaccess_unit *ud, const struct tlv_parsed *tp); + +struct msgb *ipa_ccm_make_id_resp(const struct ipaccess_unit *dev, + const uint8_t *ies_req, unsigned int num_ies_req); + +struct msgb *ipa_ccm_make_id_resp_from_req(const struct ipaccess_unit *dev, + const uint8_t *data, unsigned int len); + /* Send an IPA message to the given FD */ int ipa_send(int fd, const void *msg, size_t msglen); diff --git a/src/gsm/ipa.c b/src/gsm/ipa.c index f44c328..01bd0c5 100644 --- a/src/gsm/ipa.c +++ b/src/gsm/ipa.c @@ -1,6 +1,6 @@ /* OpenBSC Abis input driver for ip.access */ -/* (C) 2009 by Harald Welte +/* (C) 2009-2017 by Harald Welte * (C) 2010 by Holger Hans Peter Freyther * (C) 2010 by On-Waves * @@ -205,6 +205,123 @@ return rc; } +#define IPA_STRING_MAX 64 + +/*! \brief Generate IPA CCM ID RESP based on list of IEs + * \param[in] dev Descriptor describing identity data for response + * \param[in] ies_req List of IEIs to include in response + * \param[in] num_ies_req Number of IEIs in \a ies_req + * \returns Message buffer with IPA CCM ID RESP */ +struct msgb *ipa_ccm_make_id_resp(const struct ipaccess_unit *dev, + const uint8_t *ies_req, unsigned int num_ies_req) +{ + struct msgb *msg = ipa_msg_alloc(16); + char str[IPA_STRING_MAX]; + unsigned int i; + + if (!msg) + return NULL; + + *msgb_put(msg, 1) = IPAC_MSGT_ID_RESP; + + for (i = 0; i < num_ies_req; i++) { + uint8_t *tag; + + str[0] = '\0'; + switch (ies_req[i]) { + case IPAC_IDTAG_UNIT: + snprintf(str, sizeof(str), "%u/%u/%u", + dev->site_id, dev->bts_id, dev->trx_id); + break; + case IPAC_IDTAG_MACADDR: + snprintf(str, sizeof(str), + "%02x:%02x:%02x:%02x:%02x:%02x", + dev->mac_addr[0], dev->mac_addr[1], + dev->mac_addr[2], dev->mac_addr[3], + dev->mac_addr[4], dev->mac_addr[5]); + break; + case IPAC_IDTAG_LOCATION1: + if (dev->location1) + strncpy(str, dev->location1, IPA_STRING_MAX); + break; + case IPAC_IDTAG_LOCATION2: + if (dev->location2) + strncpy(str, dev->location2, IPA_STRING_MAX); + break; + case IPAC_IDTAG_EQUIPVERS: + if (dev->equipvers) + strncpy(str, dev->equipvers, IPA_STRING_MAX); + break; + case IPAC_IDTAG_SWVERSION: + if (dev->swversion) + strncpy(str, dev->swversion, IPA_STRING_MAX); + break; + case IPAC_IDTAG_UNITNAME: + if (dev->unit_name) { + snprintf(str, sizeof(str), dev->unit_name, IPA_STRING_MAX); + } else { + snprintf(str, sizeof(str), + "%02x-%02x-%02x-%02x-%02x-%02x", + dev->mac_addr[0], dev->mac_addr[1], + dev->mac_addr[2], dev->mac_addr[3], + dev->mac_addr[4], dev->mac_addr[5]); + } + break; + case IPAC_IDTAG_SERNR: + if (dev->serno) + strncpy(str, dev->serno, IPA_STRING_MAX); + break; + default: + LOGP(DLINP, LOGL_NOTICE, + "Unknown ipaccess tag 0x%02x\n", ies_req[i]); + msgb_free(msg); + return NULL; + } + str[IPA_STRING_MAX-1] = '\0'; + + LOGP(DLINP, LOGL_INFO, " tag %d: %s\n", ies_req[i], str); + tag = msgb_put(msg, 3 + strlen(str) + 1); + tag[0] = 0x00; + tag[1] = 1 + strlen(str) + 1; + tag[2] = ies_req[1]; + memcpy(tag + 3, str, strlen(str) + 1); + } + ipa_prepend_header(msg, IPAC_PROTO_IPACCESS); + return msg; +} + +/*! \brief Generate IPA CCM ID RESP based on requets payload + * \param[in] dev Descriptor describing identity data for response + * \param[in] data Payload of the IPA CCM ID GET request + * \param[in] len Length of \a data in octets + * \returns Message buffer with IPA CCM ID RESP */ +struct msgb *ipa_ccm_make_id_resp_from_req(const struct ipaccess_unit *dev, + const uint8_t *data, unsigned int len) +{ + uint8_t ies[len/2]; + unsigned int num_ies = 0; + const uint8_t *cur = data; + + /* build a array of the IEIs */ + while (len >= 2) { + uint8_t t_len, t_tag; + len -= 2; + t_len = *cur++; + t_tag = *cur++; + + if (t_len > len + 1) { + LOGP(DLINP, LOGL_ERROR, "IPA CCM tage 0x%02x does not fit\n", t_tag); + break; + } + + ies[num_ies++] = t_tag; + + cur += t_len; + len -= t_len; + } + return ipa_ccm_make_id_resp(dev, ies, num_ies); +} + int ipa_send(int fd, const void *msg, size_t msglen) { int ret; diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map index c825dd5..3ac37e1 100644 --- a/src/gsm/libosmogsm.map +++ b/src/gsm/libosmogsm.map @@ -378,6 +378,8 @@ ipa_ccm_idtag_name; ipa_ccm_idtag_parse; ipa_ccm_idtag_parse_off; +ipa_ccm_make_id_resp; +ipa_ccm_make_id_resp_from_req; ipa_msg_alloc; ipa_msg_recv; ipa_msg_recv_buffered; -- To view, visit https://gerrit.osmocom.org/2367 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Icbcd8827a75fd5f3393351c1ca372de85275ad35 Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Sat Apr 15 20:56:40 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 15 Apr 2017 20:56:40 +0000 Subject: libosmo-sccp[master]: get rid of global osmo_ss7_xua_servers variable In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2350 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Icbab59d773f23cc8514cbeb6e21e25ca35dd337f Gerrit-PatchSet: 2 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sat Apr 15 20:56:51 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 15 Apr 2017 20:56:51 +0000 Subject: libosmocore[master]: msgb: Add msgb_pull_to_l2() analogous to msgb_pull_to_l3() In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2366 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I7786a1b30f9e7eaa3dcdb3cbb2a85a126588f6cd Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sat Apr 15 20:56:56 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 15 Apr 2017 20:56:56 +0000 Subject: libosmocore[master]: ipa: Introduce helpers to encode IPA CCM ID RESPONSE In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2367 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Icbcd8827a75fd5f3393351c1ca372de85275ad35 Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sat Apr 15 20:57:03 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 15 Apr 2017 20:57:03 +0000 Subject: libosmocore[master]: msgb: Add msgb_pull_to_l2() analogous to msgb_pull_to_l3() In-Reply-To: References: Message-ID: Patch Set 1: Verified+1 -- To view, visit https://gerrit.osmocom.org/2366 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I7786a1b30f9e7eaa3dcdb3cbb2a85a126588f6cd Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sat Apr 15 20:57:13 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 15 Apr 2017 20:57:13 +0000 Subject: libosmocore[master]: msgb: Add msgb_pull_to_l2() analogous to msgb_pull_to_l3() In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2366 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I7786a1b30f9e7eaa3dcdb3cbb2a85a126588f6cd Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sat Apr 15 20:57:35 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 15 Apr 2017 20:57:35 +0000 Subject: libosmo-sccp[master]: osmo_ss7: make sure to re-set all state on client disconnect In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+1 -- To view, visit https://gerrit.osmocom.org/2365 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I6859b8549c8cbbe2e8279da0ede562387a066d04 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sat Apr 15 20:57:43 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 15 Apr 2017 20:57:43 +0000 Subject: libosmo-sccp[master]: osmo_ss7: make sure to re-set all state on client disconnect In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2365 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I6859b8549c8cbbe2e8279da0ede562387a066d04 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sat Apr 15 20:58:14 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 15 Apr 2017 20:58:14 +0000 Subject: libosmo-sccp[master]: m3ua: Generalize + Export function to generate MTP-TRANSFER ... In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2360 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: If82956317ec703341514ad81057eceb3d0714f47 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sat Apr 15 20:58:28 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 15 Apr 2017 20:58:28 +0000 Subject: libosmo-sccp[master]: osmo_ss7: Fix protocol of dynamically allocated ASPs In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2359 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I07832cbaf1ca42f0c7df399e4f96599034b72816 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sat Apr 15 20:59:26 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 15 Apr 2017 20:59:26 +0000 Subject: libosmo-sccp[master]: osmo_ss7: fix missing assignment of asp->xua_server In-Reply-To: References: Message-ID: Patch Set 1: Code-Review-1 must be merged in original patch -- To view, visit https://gerrit.osmocom.org/2363 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ic55cfbf2166381a4bf02596ad7bbe66a37e1a76f Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sat Apr 15 20:59:43 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 15 Apr 2017 20:59:43 +0000 Subject: [MERGED] libosmocore[master]: msgb: Add msgb_pull_to_l2() analogous to msgb_pull_to_l3() In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: msgb: Add msgb_pull_to_l2() analogous to msgb_pull_to_l3() ...................................................................... msgb: Add msgb_pull_to_l2() analogous to msgb_pull_to_l3() Introduce msgb_pull_to_l2() which pulls (removes) any msgb contents in front of the L2 header (msg->l2h). Change-Id: I7786a1b30f9e7eaa3dcdb3cbb2a85a126588f6cd --- M include/osmocom/core/msgb.h 1 file changed, 15 insertions(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/include/osmocom/core/msgb.h b/include/osmocom/core/msgb.h index 9cb1c24..afb887c 100644 --- a/include/osmocom/core/msgb.h +++ b/include/osmocom/core/msgb.h @@ -350,6 +350,21 @@ return ret; } +/*! \brief remove (pull) all headers in front of l2h from the message buffer. + * \param[in] msgb message buffer with a valid l2h + * \returns pointer to new start of msgb (l2h) + * + * This function moves the \a data pointer of the \ref msgb further back + * in the message, thereby shrinking the size of the message. + * l1h will be cleared. + */ +static inline unsigned char *msgb_pull_to_l2(struct msgb *msg) +{ + unsigned char *ret = msgb_pull(msg, msg->l2h - msg->data); + msg->l1h = NULL; + return ret; +} + /*! \brief remove uint8 from front of message * \param[in] msgb message buffer * \returns 8bit value taken from end of msgb -- To view, visit https://gerrit.osmocom.org/2366 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I7786a1b30f9e7eaa3dcdb3cbb2a85a126588f6cd Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sat Apr 15 21:00:06 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 15 Apr 2017 21:00:06 +0000 Subject: libosmo-sccp[master]: osmo_ss7: Clean up all ASPs established via xua_server upon ... In-Reply-To: References: Message-ID: Patch Set 2: Code-Review-1 pending fix must be merged -- To view, visit https://gerrit.osmocom.org/2351 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Iff3ed099b817e54e563b70d9ab40f63af63cc2fb Gerrit-PatchSet: 2 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sat Apr 15 21:04:22 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 15 Apr 2017 21:04:22 +0000 Subject: [MERGED] libosmo-sccp[master]: get rid of global osmo_ss7_xua_servers variable In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: get rid of global osmo_ss7_xua_servers variable ...................................................................... get rid of global osmo_ss7_xua_servers variable By moving this variable into the SS7 instance, we avoid one more global variable, and we also fix a bug where the xua servers would be saved multiple times (once per instance). Change-Id: Icbab59d773f23cc8514cbeb6e21e25ca35dd337f --- M include/osmocom/sigtran/osmo_ss7.h M src/osmo_ss7.c M src/osmo_ss7_vty.c 3 files changed, 6 insertions(+), 5 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/include/osmocom/sigtran/osmo_ss7.h b/include/osmocom/sigtran/osmo_ss7.h index 24f83e9..376e399 100644 --- a/include/osmocom/sigtran/osmo_ss7.h +++ b/include/osmocom/sigtran/osmo_ss7.h @@ -10,7 +10,6 @@ #include extern struct llist_head osmo_ss7_instances; -extern struct llist_head osmo_ss7_xua_servers; struct osmo_ss7_instance; struct osmo_ss7_user; @@ -70,6 +69,8 @@ struct llist_head asp_list; /*! list of \ref osmo_ss7_route_table */ struct llist_head rtable_list; + /*! list of \ref osmo_xua_servers */ + struct llist_head xua_servers; /* array for faster lookup of user (indexed by service * indicator) */ const struct osmo_ss7_user *user[16]; diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index 9b2377b..771501f 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -53,7 +53,6 @@ static bool ss7_initialized = false; LLIST_HEAD(osmo_ss7_instances); -LLIST_HEAD(osmo_ss7_xua_servers); static int32_t next_rctx = 1; static int32_t next_l_rk_id = 1; @@ -329,6 +328,7 @@ INIT_LLIST_HEAD(&inst->as_list); INIT_LLIST_HEAD(&inst->asp_list); INIT_LLIST_HEAD(&inst->rtable_list); + INIT_LLIST_HEAD(&inst->xua_servers); inst->rtable_system = osmo_ss7_route_table_find_or_create(inst, "system"); /* default point code structure + formatting */ @@ -1546,7 +1546,7 @@ struct osmo_xua_server *xs; OSMO_ASSERT(ss7_initialized); - llist_for_each_entry(xs, &osmo_ss7_xua_servers, list) { + llist_for_each_entry(xs, &inst->xua_servers, list) { if (proto == xs->cfg.proto && local_port == xs->cfg.local.port) return xs; @@ -1596,7 +1596,7 @@ } oxs->inst = inst; - llist_add_tail(&oxs->list, &osmo_ss7_xua_servers); + llist_add_tail(&oxs->list, &inst->xua_servers); return oxs; } diff --git a/src/osmo_ss7_vty.c b/src/osmo_ss7_vty.c index 8356d16..282a5a0 100644 --- a/src/osmo_ss7_vty.c +++ b/src/osmo_ss7_vty.c @@ -915,7 +915,7 @@ llist_for_each_entry(rtable, &inst->rtable_list, list) write_one_rtable(vty, rtable); - llist_for_each_entry(oxs, &osmo_ss7_xua_servers, list) + llist_for_each_entry(oxs, &inst->xua_servers, list) write_one_xua(vty, oxs); } -- To view, visit https://gerrit.osmocom.org/2350 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Icbab59d773f23cc8514cbeb6e21e25ca35dd337f Gerrit-PatchSet: 2 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sat Apr 15 21:04:23 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 15 Apr 2017 21:04:23 +0000 Subject: [MERGED] libosmo-sccp[master]: SUA/M3UA: Implement T(r) recovery timer of Application Serve... In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: SUA/M3UA: Implement T(r) recovery timer of Application Server FSM ...................................................................... SUA/M3UA: Implement T(r) recovery timer of Application Server FSM When an AS goes "down" it first entres a recovery state, in which any to-be-transmitted messages are enqueued until the timer T(r) expires. Once the timer expires, the messages are discarded. If the AS goes ACTIVE before timer expiration, queued messages are sent. Change-Id: I22725bf35306299a00c66d7b3637f5e198c26247 --- M src/m3ua.c M src/sua.c M src/xua_as_fsm.c M src/xua_as_fsm.h M src/xua_asp_fsm.c 5 files changed, 147 insertions(+), 46 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/m3ua.c b/src/m3ua.c index 7dc2afb..a7ef06c 100644 --- a/src/m3ua.c +++ b/src/m3ua.c @@ -39,6 +39,7 @@ #include #include +#include "xua_as_fsm.h" #include "xua_asp_fsm.h" #include "xua_internal.h" @@ -420,16 +421,14 @@ * Transmitting M3UA messsages to SCTP ***********************************************************************/ -/* transmit given xua_msg via given ASP. callee takes xua ownership */ -static int m3ua_tx_xua_asp(struct osmo_ss7_asp *asp, struct xua_msg *xua) +/* Convert M3UA from xua_msg to msgb and set PPID/stream */ +static struct msgb *m3ua_to_msg(struct xua_msg *xua) { struct msgb *msg = xua_to_msg(M3UA_VERSION, xua); - OSMO_ASSERT(asp->cfg.proto == OSMO_SS7_ASP_PROT_M3UA); - if (!msg) { LOGP(DLM3UA, LOGL_ERROR, "Error encoding M3UA Msg\n"); - return -1; + return NULL; } if (xua->hdr.msg_class == M3UA_MSGC_XFER) @@ -437,6 +436,20 @@ else msgb_sctp_stream(msg) = 0; msgb_sctp_ppid(msg) = M3UA_PPID; + + return msg; +} + +/* transmit given xua_msg via given ASP */ +static int m3ua_tx_xua_asp(struct osmo_ss7_asp *asp, struct xua_msg *xua) +{ + struct msgb *msg = m3ua_to_msg(xua); + + OSMO_ASSERT(asp->cfg.proto == OSMO_SS7_ASP_PROT_M3UA); + + if (!msg) + return -1; + return osmo_ss7_asp_send(asp, msg); } @@ -446,8 +459,8 @@ * \return 0 on success; negative on error */ int m3ua_tx_xua_as(struct osmo_ss7_as *as, struct xua_msg *xua) { - struct osmo_ss7_asp *asp; - unsigned int i; + struct msgb *msg; + int rc; OSMO_ASSERT(as->cfg.proto == OSMO_SS7_ASP_PROT_M3UA); @@ -455,19 +468,16 @@ if (as->cfg.routing_key.context) xua_msg_add_u32(xua, M3UA_IEI_ROUTE_CTX, as->cfg.routing_key.context); - for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) { - asp = as->cfg.asps[i]; - if (!asp) - continue; - if (asp) - break; - } - if (!asp) { - LOGP(DLM3UA, LOGL_ERROR, "No ASP entroy in AS, dropping message\n"); - return -ENODEV; - } + msg = m3ua_to_msg(xua); + if (!msg) + return -1; - return m3ua_tx_xua_asp(asp, xua); + /* send the msg to the AS for transmission. The AS FSM might + * (depending on its state) enqueue it before trnsmission */ + rc = osmo_fsm_inst_dispatch(as->fi, XUA_AS_E_TRANSFER_REQ, msg); + if (rc < 0) + msgb_free(msg); + return rc; } /*********************************************************************** diff --git a/src/sua.c b/src/sua.c index 3bff855..97a0785 100644 --- a/src/sua.c +++ b/src/sua.c @@ -40,6 +40,7 @@ #include #include +#include "xua_as_fsm.h" #include "xua_asp_fsm.h" #include "xua_internal.h" #include "sccp_internal.h" @@ -252,18 +253,38 @@ * Transmitting SUA messsages to SCTP ***********************************************************************/ -static int sua_tx_xua_asp(struct osmo_ss7_asp *asp, struct xua_msg *xua) +static struct msgb *sua_to_msg(struct xua_msg *xua) { struct msgb *msg = xua_to_msg(SUA_VERSION, xua); - OSMO_ASSERT(asp->cfg.proto == OSMO_SS7_ASP_PROT_SUA); - if (!msg) { - LOGPASP(asp, DLSUA, LOGL_ERROR, "Error encoding SUA Msg\n"); - return -1; + LOGP(DLSUA, LOGL_ERROR, "Error encoding SUA Msg\n"); + return NULL; } + switch (xua->hdr.msg_class) { + case SUA_MSGC_CL: + case SUA_MSGC_CO: + msgb_sctp_stream(msg) = 1; + break; + default: + msgb_sctp_stream(msg) = 0; + break; + } msgb_sctp_ppid(msg) = SUA_PPID; + + return msg; +} + +static int sua_tx_xua_asp(struct osmo_ss7_asp *asp, struct xua_msg *xua) +{ + struct msgb *msg = sua_to_msg(xua); + + OSMO_ASSERT(asp->cfg.proto == OSMO_SS7_ASP_PROT_SUA); + + if (!msg) + return -1; + return osmo_ss7_asp_send(asp, msg); } @@ -273,25 +294,25 @@ * \return 0 on success; negative on error */ int sua_tx_xua_as(struct osmo_ss7_as *as, struct xua_msg *xua) { - struct osmo_ss7_asp *asp; - unsigned int i; + struct msgb *msg; + int rc; OSMO_ASSERT(as->cfg.proto == OSMO_SS7_ASP_PROT_SUA); - /* FIXME: Select ASP within AS depending on traffic mode */ - for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) { - asp = as->cfg.asps[i]; - if (!asp) - continue; - if (asp) - break; - } - if (!asp) { - LOGP(DLSUA, LOGL_ERROR, "No ASP in AS, dropping message\n"); - return -ENODEV; - } + /* Add RC for this AS */ + if (as->cfg.routing_key.context) + xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, as->cfg.routing_key.context); - return sua_tx_xua_asp(asp, xua); + msg = sua_to_msg(xua); + if (!msg) + return -1; + + /* send the msg to the AS for transmission. The AS FSM might + * (depending on its state) enqueue it before trnsmission */ + rc = osmo_fsm_inst_dispatch(as->fi, XUA_AS_E_TRANSFER_REQ, msg); + if (rc < 0) + msgb_free(msg); + return rc; } /*********************************************************************** diff --git a/src/xua_as_fsm.c b/src/xua_as_fsm.c index 740070b..282a6bf 100644 --- a/src/xua_as_fsm.c +++ b/src/xua_as_fsm.c @@ -65,12 +65,39 @@ return sent; } +/* actually transmit a message through this AS */ +static int xua_as_transmit_msg(struct osmo_ss7_as *as, struct msgb *msg) +{ + struct osmo_ss7_asp *asp; + unsigned int i; + + /* FIXME: proper selection of the ASP based on the SLS and the + * traffic mode type! */ + for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) { + asp = as->cfg.asps[i]; + if (!asp) + continue; + if (asp) + break; + } + + if (!asp) { + LOGPFSM(as->fi, "No ASP in AS, dropping message\n"); + msgb_free(msg); + return -1; + } + + return osmo_ss7_asp_send(asp, msg); +} + /*********************************************************************** * Actual FSM ***********************************************************************/ #define S(x) (1 << (x)) + +#define MSEC_TO_S_US(x) (x/1000), ((x%1000)*10) enum xua_as_state { XUA_AS_S_DOWN, @@ -83,11 +110,17 @@ { XUA_ASPAS_ASP_INACTIVE_IND, "ASPAS-ASP_INACTIVE.ind" }, { XUA_ASPAS_ASP_DOWN_IND, "ASPAS-ASP_DOWN.ind" }, { XUA_ASPAS_ASP_ACTIVE_IND, "ASPAS-ASP_ACTIVE.ind" }, + { XUA_AS_E_RECOVERY_EXPD, "AS-T_REC_EXPD.ind" }, + { XUA_AS_E_TRANSFER_REQ, "AS-TRANSFER.req" }, { 0, NULL } }; struct xua_as_fsm_priv { struct osmo_ss7_as *as; + struct { + struct osmo_timer_list t_r; + struct llist_head queued_msgs; + } recovery; }; /* is any other ASP in this AS in state != DOWN? */ @@ -130,6 +163,11 @@ return false; } +static void t_r_callback(void *_fi) +{ + struct osmo_fsm_inst *fi = _fi; + osmo_fsm_inst_dispatch(fi, XUA_AS_E_RECOVERY_EXPD, NULL); +} static void xua_as_fsm_down(struct osmo_fsm_inst *fi, uint32_t event, void *data) { @@ -205,16 +243,20 @@ static void xua_as_fsm_active(struct osmo_fsm_inst *fi, uint32_t event, void *data) { struct xua_as_fsm_priv *xafp = (struct xua_as_fsm_priv *) fi->priv; - struct osmo_ss7_asp *asp = data; + struct osmo_ss7_asp *asp; + struct msgb *msg; switch (event) { case XUA_ASPAS_ASP_DOWN_IND: case XUA_ASPAS_ASP_INACTIVE_IND: + asp = data; if (check_any_other_asp_in_active(xafp->as, asp)) { /* ignore, we stay AS_ACTIVE */ } else { + uint32_t recovery_msec = xafp->as->cfg.recovery_timeout_msec; osmo_fsm_inst_state_chg(fi, XUA_AS_S_PENDING, 0, 0); - /* FIXME: Start T(r) */ + /* Start T(r) */ + osmo_timer_schedule(&xafp->recovery.t_r, MSEC_TO_S_US(recovery_msec)); /* FIXME: Queue all signalling messages until * recovery or T(r) expiry */ } @@ -222,21 +264,44 @@ case XUA_ASPAS_ASP_ACTIVE_IND: /* ignore */ break; + case XUA_AS_E_TRANSFER_REQ: + /* message for transmission */ + msg = data; + xua_as_transmit_msg(xafp->as, msg); + break; } } static void xua_as_fsm_pending(struct osmo_fsm_inst *fi, uint32_t event, void *data) { + struct xua_as_fsm_priv *xafp = (struct xua_as_fsm_priv *) fi->priv; + struct msgb *msg; + switch (event) { case XUA_ASPAS_ASP_ACTIVE_IND: /* one ASP transitions into ASP-ACTIVE */ + osmo_timer_del(&xafp->recovery.t_r); osmo_fsm_inst_state_chg(fi, XUA_AS_S_ACTIVE, 0, 0); + /* push out any pending queued messages */ + while ((msg = msgb_dequeue(&xafp->recovery.queued_msgs))) + xua_as_transmit_msg(xafp->as, msg); break; case XUA_ASPAS_ASP_INACTIVE_IND: /* ignore */ break; case XUA_ASPAS_ASP_DOWN_IND: /* ignore */ + break; + case XUA_AS_E_RECOVERY_EXPD: + LOGPFSM(fi, "T(r) expired; dropping queued messages\n"); + while ((msg = msgb_dequeue(&xafp->recovery.queued_msgs))) + talloc_free(msg); + osmo_fsm_inst_state_chg(fi, XUA_AS_S_DOWN, 0, 0); + break; + case XUA_AS_E_TRANSFER_REQ: + /* enqueue the to-be-transferred message */ + msg = data; + msgb_enqueue(&xafp->recovery.queued_msgs, msg); break; } } @@ -264,7 +329,8 @@ [XUA_AS_S_ACTIVE] = { .in_event_mask = S(XUA_ASPAS_ASP_DOWN_IND) | S(XUA_ASPAS_ASP_INACTIVE_IND) | - S(XUA_ASPAS_ASP_ACTIVE_IND), + S(XUA_ASPAS_ASP_ACTIVE_IND) | + S(XUA_AS_E_TRANSFER_REQ), .out_state_mask = S(XUA_AS_S_ACTIVE) | S(XUA_AS_S_PENDING), .name = "AS_ACTIVE", @@ -274,7 +340,9 @@ [XUA_AS_S_PENDING] = { .in_event_mask = S(XUA_ASPAS_ASP_INACTIVE_IND) | S(XUA_ASPAS_ASP_DOWN_IND) | - S(XUA_ASPAS_ASP_ACTIVE_IND), + S(XUA_ASPAS_ASP_ACTIVE_IND) | + S(XUA_AS_E_TRANSFER_REQ) | + S(XUA_AS_E_RECOVERY_EXPD), .out_state_mask = S(XUA_AS_S_DOWN) | S(XUA_AS_S_INACTIVE) | S(XUA_AS_S_ACTIVE) | @@ -310,6 +378,9 @@ return NULL; } xafp->as = as; + xafp->recovery.t_r.cb = t_r_callback; + xafp->recovery.t_r.data = fi; + INIT_LLIST_HEAD(&xafp->recovery.queued_msgs); fi->priv = xafp; diff --git a/src/xua_as_fsm.h b/src/xua_as_fsm.h index 3b8e5b7..0128919 100644 --- a/src/xua_as_fsm.h +++ b/src/xua_as_fsm.h @@ -6,6 +6,8 @@ XUA_ASPAS_ASP_INACTIVE_IND, XUA_ASPAS_ASP_DOWN_IND, XUA_ASPAS_ASP_ACTIVE_IND, + XUA_AS_E_RECOVERY_EXPD, + XUA_AS_E_TRANSFER_REQ, }; extern struct osmo_fsm xua_as_fsm; diff --git a/src/xua_asp_fsm.c b/src/xua_asp_fsm.c index 59887a4..f4d9cf0 100644 --- a/src/xua_asp_fsm.c +++ b/src/xua_asp_fsm.c @@ -380,9 +380,6 @@ struct osmo_ss7_instance *inst = asp->inst; struct osmo_ss7_as *as; - if (xafp->role != XUA_ASPFSM_ROLE_SG) - return; - llist_for_each_entry(as, &inst->as_list, list) { if (!osmo_ss7_as_has_asp(as, asp)) continue; -- To view, visit https://gerrit.osmocom.org/2349 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I22725bf35306299a00c66d7b3637f5e198c26247 Gerrit-PatchSet: 2 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sat Apr 15 21:04:23 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 15 Apr 2017 21:04:23 +0000 Subject: [MERGED] libosmo-sccp[master]: osmo_ss7_vty: Print AS and ASP state names during 'show' In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: osmo_ss7_vty: Print AS and ASP state names during 'show' ...................................................................... osmo_ss7_vty: Print AS and ASP state names during 'show' Change-Id: I6a06d93d6e6c0386676742d6d19f5483a46d7fba --- M src/osmo_ss7_vty.c 1 file changed, 10 insertions(+), 10 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/osmo_ss7_vty.c b/src/osmo_ss7_vty.c index a05d74f..8356d16 100644 --- a/src/osmo_ss7_vty.c +++ b/src/osmo_ss7_vty.c @@ -579,13 +579,13 @@ return CMD_WARNING; } - vty_out(vty, " Effect Primary%s", VTY_NEWLINE); - vty_out(vty, "ASP Name AS Name State Type Rmt Port Remote IP Addr SCTP%s", VTY_NEWLINE); - vty_out(vty, "------------ ------------ -------- ---- -------- --------------- ----------%s", VTY_NEWLINE); + vty_out(vty, " Effect Primary%s", VTY_NEWLINE); + vty_out(vty, "ASP Name AS Name State Type Rmt Port Remote IP Addr SCTP%s", VTY_NEWLINE); + vty_out(vty, "------------ ------------ ------------- ---- -------- --------------- ----------%s", VTY_NEWLINE); llist_for_each_entry(asp, &inst->asp_list, list) { - vty_out(vty, "%-12s %-12s %-8s %-4s %-8u %-15s %-10s%s", - asp->cfg.name, "?", "?", + vty_out(vty, "%-12s %-12s %-13s %-4s %-8u %-15s %-10s%s", + asp->cfg.name, "?", osmo_fsm_inst_state_name(asp->fi), get_value_string(osmo_ss7_asp_protocol_vals, asp->cfg.proto), asp->cfg.remote.port, asp->cfg.remote.host, "", VTY_NEWLINE); } @@ -846,9 +846,9 @@ return CMD_WARNING; } - vty_out(vty, " Routing Routing Key Cic Cic%s", VTY_NEWLINE); - vty_out(vty, "AS Name State Context Dpc Si Opc Ssn Min Max%s", VTY_NEWLINE); - vty_out(vty, "------------ ------ ---------- ------------- ---- ------------- --- ----- -----%s", VTY_NEWLINE); + vty_out(vty, " Routing Routing Key Cic Cic%s", VTY_NEWLINE); + vty_out(vty, "AS Name State Context Dpc Si Opc Ssn Min Max%s", VTY_NEWLINE); + vty_out(vty, "------------ ------------ ---------- ------------- ---- ------------- --- ----- -----%s", VTY_NEWLINE); llist_for_each_entry(as, &inst->as_list, list) { if (filter && !strcmp(filter, "m3ua") && as->cfg.proto != OSMO_SS7_ASP_PROT_M3UA) @@ -856,8 +856,8 @@ if (filter && !strcmp(filter, "sua") && as->cfg.proto != OSMO_SS7_ASP_PROT_SUA) continue; /* FIXME: active filter */ - vty_out(vty, "%-12s %-6s %-10u %-13s %4s %13s %3s %5s %4s%s", - as->cfg.name, "fixme", as->cfg.routing_key.context, + vty_out(vty, "%-12s %-12s %-10u %-13s %4s %13s %3s %5s %4s%s", + as->cfg.name, osmo_fsm_inst_state_name(as->fi), as->cfg.routing_key.context, osmo_ss7_pointcode_print(as->inst, as->cfg.routing_key.pc), "", "", "", "", "", VTY_NEWLINE); } -- To view, visit https://gerrit.osmocom.org/2348 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I6a06d93d6e6c0386676742d6d19f5483a46d7fba Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sat Apr 15 21:04:24 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 15 Apr 2017 21:04:24 +0000 Subject: [MERGED] libosmo-sccp[master]: ss7_vty: don't re-define xUA dialect strings In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: ss7_vty: don't re-define xUA dialect strings ...................................................................... ss7_vty: don't re-define xUA dialect strings If we add more xUA variants/protocols, we want to avoid having to touch too many parts of the code with copy+pasted strings. Change-Id: I085b884d98fb4c45ac15910a8ebf82b91e861fd4 --- M src/osmo_ss7_vty.c 1 file changed, 15 insertions(+), 12 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/osmo_ss7_vty.c b/src/osmo_ss7_vty.c index c2ad25c..a05d74f 100644 --- a/src/osmo_ss7_vty.c +++ b/src/osmo_ss7_vty.c @@ -37,6 +37,13 @@ #include "xua_internal.h" +#define XUA_VAR_STR "(sua|m3ua)" + +#define XUA_VAR_HELP_STR \ + "SCCP User Adaptation\n" \ + "MTP3 User Adaptation\n" + + /*********************************************************************** * Core CS7 Configuration ***********************************************************************/ @@ -380,12 +387,10 @@ 1, }; -#define XUA_STR "SCCP User Adaptation\n" "MTP3 User Adaptation\n" - DEFUN(cs7_xua, cs7_xua_cmd, - "listen (sua|m3ua) <0-65534>", + "listen " XUA_VAR_STR " <0-65534>", "Configure/Enable xUA Listener\n" - XUA_STR "SCTP Port number\n") + XUA_VAR_HELP_STR "SCTP Port number\n") { struct osmo_ss7_instance *inst = vty->index; struct osmo_xua_server *xs; @@ -405,9 +410,9 @@ } DEFUN(no_cs7_xua, no_cs7_xua_cmd, - "no listen (sua|m3ua) <0-65534>", + "no listen " XUA_VAR_STR " <0-65534>", NO_STR "Disable xUA Listener on given SCTP Port\n" - XUA_STR "SCTP Port number\n") + XUA_VAR_HELP_STR "SCTP Port number\n") { struct osmo_ss7_instance *inst = vty->index; struct osmo_xua_server *xs; @@ -472,13 +477,12 @@ }; DEFUN(cs7_asp, cs7_asp_cmd, - "asp NAME <0-65535> <0-65535> (m3ua|sua)", + "asp NAME <0-65535> <0-65535> " XUA_VAR_STR, "Configure Application Server Process\n" "Name of ASP\n" "Remote SCTP port number\n" "Local SCTP port number\n" - "M3UA Protocol\n" - "SUA Protocol\n") + XUA_VAR_HELP_STR) { struct osmo_ss7_instance *inst = vty->index; const char *name = argv[0]; @@ -617,11 +621,10 @@ }; DEFUN(cs7_as, cs7_as_cmd, - "as NAME (m3ua|sua)", + "as NAME " XUA_VAR_STR, "Configure an Application Server\n" "Name of the Application Server\n" - "M3UA Application Server\n" - "SUA Application Server\n") + XUA_VAR_HELP_STR) { struct osmo_ss7_instance *inst = vty->index; struct osmo_ss7_as *as; -- To view, visit https://gerrit.osmocom.org/2347 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I085b884d98fb4c45ac15910a8ebf82b91e861fd4 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sat Apr 15 21:04:24 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 15 Apr 2017 21:04:24 +0000 Subject: [MERGED] libosmo-sccp[master]: m3ua_example: Add SS7 and SCCP VTY In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: m3ua_example: Add SS7 and SCCP VTY ...................................................................... m3ua_example: Add SS7 and SCCP VTY Change-Id: Id03d2f94d22445ada01917356a5ec5a8e4fa3fca --- M examples/m3ua_example.c 1 file changed, 2 insertions(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/examples/m3ua_example.c b/examples/m3ua_example.c index d1247f5..d3c6a7c 100644 --- a/examples/m3ua_example.c +++ b/examples/m3ua_example.c @@ -92,6 +92,8 @@ osmo_ss7_init(); osmo_fsm_log_addr(false); vty_init(&vty_info); + osmo_ss7_vty_init_asp(); + osmo_sccp_vty_init(); if (argc <= 1) client = true; -- To view, visit https://gerrit.osmocom.org/2346 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Id03d2f94d22445ada01917356a5ec5a8e4fa3fca Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sat Apr 15 21:04:24 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 15 Apr 2017 21:04:24 +0000 Subject: [MERGED] libosmo-sccp[master]: SCCP: Add VTY interface for SCCP In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: SCCP: Add VTY interface for SCCP ...................................................................... SCCP: Add VTY interface for SCCP Change-Id: I100daaa947dbab6a4528c4e9fbd0d30790288f63 --- M include/osmocom/sigtran/sccp_sap.h M src/Makefile.am M src/osmo_ss7_vty.c M src/sccp_internal.h M src/sccp_scoc.c A src/sccp_vty.c M src/xua_internal.h M tests/ss7/Makefile.am M tests/xua/Makefile.am 9 files changed, 202 insertions(+), 8 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/include/osmocom/sigtran/sccp_sap.h b/include/osmocom/sigtran/sccp_sap.h index fd25752..f378e5c 100644 --- a/include/osmocom/sigtran/sccp_sap.h +++ b/include/osmocom/sigtran/sccp_sap.h @@ -227,6 +227,8 @@ struct osmo_sccp_instance; struct osmo_sccp_user; +void osmo_sccp_vty_init(void); + struct osmo_sccp_instance * osmo_sccp_instance_create(struct osmo_ss7_instance *ss7, void *priv); void osmo_sccp_instance_destroy(struct osmo_sccp_instance *inst); diff --git a/src/Makefile.am b/src/Makefile.am index 8e52792..217f2f7 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -30,6 +30,6 @@ sccp2sua.c sccp_scrc.c sccp_sclc.c sccp_scoc.c \ sccp_user.c xua_rkm.c xua_default_lm_fsm.c \ osmo_ss7.c osmo_ss7_hmrt.c xua_asp_fsm.c xua_as_fsm.c \ - osmo_ss7_vty.c + osmo_ss7_vty.c sccp_vty.c libosmo_sigtran_la_LDFLAGS = -version-info $(LIBVERSION) -no-undefined -export-symbols-regex '^osmo_' libosmo_sigtran_la_LIBADD = $(LIBOSMOCORE_LIBS) $(LIBOSMONETIF_LIBS) $(LIBSCTP_LIBS) diff --git a/src/osmo_ss7_vty.c b/src/osmo_ss7_vty.c index b08a456..c2ad25c 100644 --- a/src/osmo_ss7_vty.c +++ b/src/osmo_ss7_vty.c @@ -35,9 +35,7 @@ #include #include -#define CS7_STR "ITU-T Signaling System 7\n" -#define PC_STR "Point Code\n" -#define INST_STR "An instance of the SS7 stack\n" +#include "xua_internal.h" /*********************************************************************** * Core CS7 Configuration diff --git a/src/sccp_internal.h b/src/sccp_internal.h index c35ef4b..17dda13 100644 --- a/src/sccp_internal.h +++ b/src/sccp_internal.h @@ -87,3 +87,5 @@ struct msgb *sccp_msgb_alloc(const char *name); struct osmo_fsm sccp_scoc_fsm; + +void sccp_scoc_show_connections(struct vty *vty, struct osmo_sccp_instance *inst); diff --git a/src/sccp_scoc.c b/src/sccp_scoc.c index 8621e6d..6d9916b 100644 --- a/src/sccp_scoc.c +++ b/src/sccp_scoc.c @@ -1649,3 +1649,42 @@ llist_for_each_entry_safe(conn, conn2, &inst->connections, list) conn_destroy(conn); } + +#include + +static void vty_show_connection(struct vty *vty, struct sccp_connection *conn) +{ + struct osmo_ss7_instance *s7i = conn->inst->ss7; + struct osmo_sccp_addr *remote_addr; + uint32_t local_pc; + + if (conn->user->pc_valid) + local_pc = conn->user->pc; + else + local_pc = s7i->cfg.primary_pc; + + if (conn->incoming) + remote_addr = &conn->calling_addr; + else + remote_addr = &conn->called_addr; + + vty_out(vty, "%c %06x %3u %7s ", conn->incoming ? 'I' : 'O', + conn->conn_id, conn->user->ssn, + osmo_ss7_pointcode_print(s7i, local_pc)); + vty_out(vty, "%16s %06x %3u %7s%s", + osmo_fsm_inst_state_name(conn->fi), conn->remote_ref, remote_addr->ssn, + osmo_ss7_pointcode_print(s7i, conn->remote_pc), + VTY_NEWLINE); +} + +void sccp_scoc_show_connections(struct vty *vty, struct osmo_sccp_instance *inst) +{ + struct sccp_connection *conn; + + vty_out(vty, "I Local Conn. Remote %s", VTY_NEWLINE); + vty_out(vty, "O Ref SSN PC State Ref SSN PC %s", VTY_NEWLINE); + vty_out(vty, "- ------ --- ------- ---------------- ------ --- -------%s", VTY_NEWLINE); + + llist_for_each_entry(conn, &inst->connections, list) + vty_show_connection(vty, conn); +} diff --git a/src/sccp_vty.c b/src/sccp_vty.c new file mode 100644 index 0000000..626fefb --- /dev/null +++ b/src/sccp_vty.c @@ -0,0 +1,149 @@ +/* Core SS7 Instance/Linkset/Link/AS/ASP VTY Interface */ + +/* (C) 2015-2017 by Harald Welte + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include "xua_internal.h" +#include "sccp_internal.h" + +static void show_user(struct vty *vty, struct osmo_sccp_user *user) +{ + struct osmo_sccp_instance *sccp = user->inst; + + if (user->pc_valid) + vty_out(vty, "SSN %3u %7s : %s%s", user->ssn, + osmo_ss7_pointcode_print(sccp->ss7, user->pc), + user->name, VTY_NEWLINE); + else + vty_out(vty, "SSN %3u ANY : %s%s", user->ssn, user->name, VTY_NEWLINE); +} + +DEFUN(show_sccp_users, show_sccp_users_cmd, + "show cs7 instance <0-15> sccp users", + SHOW_STR CS7_STR INST_STR INST_STR + "Signaling Connection Control Part\n" + "Show List of SCCP Users registered\n") +{ + int id = atoi(argv[0]); + struct osmo_ss7_instance *inst; + struct osmo_sccp_instance *sccp; + struct osmo_sccp_user *scu; + + inst = osmo_ss7_instance_find(id); + if (!inst) { + vty_out(vty, "No SS7 instance %d found%s", id, VTY_NEWLINE); + return CMD_WARNING; + } + + sccp = inst->sccp; + if (!sccp) { + vty_out(vty, "SS7 instance %d has no SCCP%s", id, VTY_NEWLINE); + return CMD_WARNING; + }; + + llist_for_each_entry(scu, &sccp->users, list) + show_user(vty, scu); + + return CMD_SUCCESS; +} + +DEFUN(show_sccp_user_ssn, show_sccp_user_ssn_cmd, + "show cs7 instance <0-15> sccp ssn <0-65535>", + SHOW_STR CS7_STR INST_STR INST_STR + "Signaling Connection Control Part\n" + "Show List of SCCP Users registered\n") +{ + int id = atoi(argv[0]); + int ssn = atoi(argv[1]); + struct osmo_ss7_instance *inst; + struct osmo_sccp_instance *sccp; + struct osmo_sccp_user *scu; + + inst = osmo_ss7_instance_find(id); + if (!inst) { + vty_out(vty, "No SS7 instance %d found%s", id, VTY_NEWLINE); + return CMD_WARNING; + } + + sccp = inst->sccp; + if (!sccp) { + vty_out(vty, "SS7 instance %d has no SCCP%s", id, VTY_NEWLINE); + return CMD_WARNING; + }; + + scu = sccp_user_find(sccp, ssn, 0); + if (!scu) { + vty_out(vty, "Can't find SCCP User in instance %d%s", id, VTY_NEWLINE); + return CMD_WARNING; + } + + show_user(vty, scu); + + return CMD_SUCCESS; +} + +DEFUN(show_sccp_connections, show_sccp_connections_cmd, + "show cs7 instance <0-15> sccp connections", + SHOW_STR CS7_STR INST_STR INST_STR + "Signaling Connection Control Part\n" + "Show List of SCCP Users registered\n") +{ + int id = atoi(argv[0]); + struct osmo_ss7_instance *inst; + struct osmo_sccp_instance *sccp; + + inst = osmo_ss7_instance_find(id); + if (!inst) { + vty_out(vty, "No SS7 instance %d found%s", id, VTY_NEWLINE); + return CMD_WARNING; + } + + sccp = inst->sccp; + if (!sccp) { + vty_out(vty, "SS7 instance %d has no SCCP%s", id, VTY_NEWLINE); + return CMD_WARNING; + }; + + sccp_scoc_show_connections(vty, sccp); + + return CMD_SUCCESS; +} + +void osmo_sccp_vty_init(void) +{ + install_element_ve(&show_sccp_users_cmd); + install_element_ve(&show_sccp_user_ssn_cmd); + install_element_ve(&show_sccp_connections_cmd); +} diff --git a/src/xua_internal.h b/src/xua_internal.h index b291703..31c941e 100644 --- a/src/xua_internal.h +++ b/src/xua_internal.h @@ -60,3 +60,7 @@ extern struct osmo_fsm xua_default_lm_fsm; extern const struct value_string m3ua_rkm_reg_status_vals[]; extern const struct value_string m3ua_rkm_dereg_status_vals[]; + +#define CS7_STR "ITU-T Signaling System 7\n" +#define PC_STR "Point Code\n" +#define INST_STR "An instance of the SS7 stack\n" diff --git a/tests/ss7/Makefile.am b/tests/ss7/Makefile.am index bc81915..3b6cb2c 100644 --- a/tests/ss7/Makefile.am +++ b/tests/ss7/Makefile.am @@ -1,9 +1,9 @@ AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -Wall -AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) +AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOVTY_CFLAGS) AM_LDFLAGS = -static LDADD = $(top_builddir)/src/libosmo-sigtran.la \ - $(LIBOSMOCORE_LIBS) $(LIBOSMONETIF_LIBS) $(LIBSCTP_LIBS) + $(LIBOSMOCORE_LIBS) $(LIBOSMOVTY_LIBS) $(LIBOSMONETIF_LIBS) $(LIBSCTP_LIBS) EXTRA_DIST = ss7_test.ok ss7_test.err diff --git a/tests/xua/Makefile.am b/tests/xua/Makefile.am index 8a75e6c..c6a9955 100644 --- a/tests/xua/Makefile.am +++ b/tests/xua/Makefile.am @@ -1,9 +1,9 @@ AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -Wall -AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) +AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOVTY_CFLAGS) AM_LDFLAGS = -static LDADD = $(top_builddir)/src/libosmo-sigtran.la \ - $(LIBOSMOCORE_LIBS) $(LIBOSMONETIF_LIBS) $(LIBSCTP_LIBS) + $(LIBOSMOCORE_LIBS) $(LIBOSMOVTY_LIBS) $(LIBOSMONETIF_LIBS) $(LIBSCTP_LIBS) EXTRA_DIST = xua_test.ok -- To view, visit https://gerrit.osmocom.org/2345 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I100daaa947dbab6a4528c4e9fbd0d30790288f63 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sat Apr 15 21:04:24 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 15 Apr 2017 21:04:24 +0000 Subject: [MERGED] libosmo-sccp[master]: sccp_scoc: Memorize if a connection is incoming or outbound In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: sccp_scoc: Memorize if a connection is incoming or outbound ...................................................................... sccp_scoc: Memorize if a connection is incoming or outbound This is not really needed by the state machines internally, so we have to artificially add it to the sccp_connection. We don't use it yet, but upcoming code for VTY introspection of SCCP connections will be able to use it. Change-Id: Ic3c85152665abfb613e197b098c97392d16d16bf --- M src/sccp_scoc.c 1 file changed, 4 insertions(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/sccp_scoc.c b/src/sccp_scoc.c index 4bf340d..8621e6d 100644 --- a/src/sccp_scoc.c +++ b/src/sccp_scoc.c @@ -102,6 +102,9 @@ uint32_t sccp_class; uint32_t release_cause; /* WAIT_CONN_CONF */ + /* incoming (true) or outgoing (false) */ + bool incoming; + /* Osmo FSM Instance of sccp_scoc_fsm */ struct osmo_fsm_inst *fi; @@ -1514,6 +1517,7 @@ /* Allocate new connection */ conn = conn_create(inst); conn->user = scu; + conn->incoming = true; } else { uint32_t conn_id; /* Resolve existing connection */ -- To view, visit https://gerrit.osmocom.org/2344 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ic3c85152665abfb613e197b098c97392d16d16bf Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sat Apr 15 21:04:25 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 15 Apr 2017 21:04:25 +0000 Subject: [MERGED] libosmo-sccp[master]: osmo_ss7_vty: Don't save dynamically generated AS / ASP In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: osmo_ss7_vty: Don't save dynamically generated AS / ASP ...................................................................... osmo_ss7_vty: Don't save dynamically generated AS / ASP If RKM has dynamically generated some AS definitions on the fly, or if we accepted auto-creation of ASPs on SCTP connect time, then we don't wnat to save such objects during vty config file store. Change-Id: I9d0b0b61737a30b9d6e76cecbe42ec071bcddeeb --- M src/osmo_ss7_vty.c 1 file changed, 9 insertions(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/osmo_ss7_vty.c b/src/osmo_ss7_vty.c index 08229dc..b08a456 100644 --- a/src/osmo_ss7_vty.c +++ b/src/osmo_ss7_vty.c @@ -592,6 +592,11 @@ static void write_one_asp(struct vty *vty, struct osmo_ss7_asp *asp) { + /* skip any dynamically created ASPs (auto-created at connect + * time) */ + if (asp->dyn_allocated) + return; + vty_out(vty, " asp %s %u %u %s%s", asp->cfg.name, asp->cfg.remote.port, asp->cfg.local.port, osmo_ss7_asp_protocol_name(asp->cfg.proto), VTY_NEWLINE); @@ -787,6 +792,10 @@ struct osmo_ss7_routing_key *rkey; unsigned int i; + /* skip any dynamically allocated AS definitions */ + if (as->rkm_dyn_allocated) + return; + vty_out(vty, " as %s %s%s", as->cfg.name, osmo_ss7_asp_protocol_name(as->cfg.proto), VTY_NEWLINE); if (as->cfg.description) -- To view, visit https://gerrit.osmocom.org/2343 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I9d0b0b61737a30b9d6e76cecbe42ec071bcddeeb Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sat Apr 15 21:13:33 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 15 Apr 2017 21:13:33 +0000 Subject: [MERGED] libosmocore[master]: ipa: Introduce helpers to encode IPA CCM ID RESPONSE In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: ipa: Introduce helpers to encode IPA CCM ID RESPONSE ...................................................................... ipa: Introduce helpers to encode IPA CCM ID RESPONSE The ipa.c file already contained code to parse an ID RESPONSE into the 'struct ipaccess_unit', but it didn't so far contain code to put together an ID RESPONSE packet based on that structure. Let's change that with ipa_ccm_make_id_resp() and a helper wrapper ipa_ccm_make_id_resp_from_req(). Change-Id: Icbcd8827a75fd5f3393351c1ca372de85275ad35 --- M include/osmocom/gsm/ipa.h M src/gsm/ipa.c M src/gsm/libosmogsm.map 3 files changed, 127 insertions(+), 1 deletion(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/include/osmocom/gsm/ipa.h b/include/osmocom/gsm/ipa.h index 0bb01c5..cabee13 100644 --- a/include/osmocom/gsm/ipa.h +++ b/include/osmocom/gsm/ipa.h @@ -37,6 +37,13 @@ int ipa_ccm_tlv_to_unitdata(struct ipaccess_unit *ud, const struct tlv_parsed *tp); + +struct msgb *ipa_ccm_make_id_resp(const struct ipaccess_unit *dev, + const uint8_t *ies_req, unsigned int num_ies_req); + +struct msgb *ipa_ccm_make_id_resp_from_req(const struct ipaccess_unit *dev, + const uint8_t *data, unsigned int len); + /* Send an IPA message to the given FD */ int ipa_send(int fd, const void *msg, size_t msglen); diff --git a/src/gsm/ipa.c b/src/gsm/ipa.c index f44c328..01bd0c5 100644 --- a/src/gsm/ipa.c +++ b/src/gsm/ipa.c @@ -1,6 +1,6 @@ /* OpenBSC Abis input driver for ip.access */ -/* (C) 2009 by Harald Welte +/* (C) 2009-2017 by Harald Welte * (C) 2010 by Holger Hans Peter Freyther * (C) 2010 by On-Waves * @@ -205,6 +205,123 @@ return rc; } +#define IPA_STRING_MAX 64 + +/*! \brief Generate IPA CCM ID RESP based on list of IEs + * \param[in] dev Descriptor describing identity data for response + * \param[in] ies_req List of IEIs to include in response + * \param[in] num_ies_req Number of IEIs in \a ies_req + * \returns Message buffer with IPA CCM ID RESP */ +struct msgb *ipa_ccm_make_id_resp(const struct ipaccess_unit *dev, + const uint8_t *ies_req, unsigned int num_ies_req) +{ + struct msgb *msg = ipa_msg_alloc(16); + char str[IPA_STRING_MAX]; + unsigned int i; + + if (!msg) + return NULL; + + *msgb_put(msg, 1) = IPAC_MSGT_ID_RESP; + + for (i = 0; i < num_ies_req; i++) { + uint8_t *tag; + + str[0] = '\0'; + switch (ies_req[i]) { + case IPAC_IDTAG_UNIT: + snprintf(str, sizeof(str), "%u/%u/%u", + dev->site_id, dev->bts_id, dev->trx_id); + break; + case IPAC_IDTAG_MACADDR: + snprintf(str, sizeof(str), + "%02x:%02x:%02x:%02x:%02x:%02x", + dev->mac_addr[0], dev->mac_addr[1], + dev->mac_addr[2], dev->mac_addr[3], + dev->mac_addr[4], dev->mac_addr[5]); + break; + case IPAC_IDTAG_LOCATION1: + if (dev->location1) + strncpy(str, dev->location1, IPA_STRING_MAX); + break; + case IPAC_IDTAG_LOCATION2: + if (dev->location2) + strncpy(str, dev->location2, IPA_STRING_MAX); + break; + case IPAC_IDTAG_EQUIPVERS: + if (dev->equipvers) + strncpy(str, dev->equipvers, IPA_STRING_MAX); + break; + case IPAC_IDTAG_SWVERSION: + if (dev->swversion) + strncpy(str, dev->swversion, IPA_STRING_MAX); + break; + case IPAC_IDTAG_UNITNAME: + if (dev->unit_name) { + snprintf(str, sizeof(str), dev->unit_name, IPA_STRING_MAX); + } else { + snprintf(str, sizeof(str), + "%02x-%02x-%02x-%02x-%02x-%02x", + dev->mac_addr[0], dev->mac_addr[1], + dev->mac_addr[2], dev->mac_addr[3], + dev->mac_addr[4], dev->mac_addr[5]); + } + break; + case IPAC_IDTAG_SERNR: + if (dev->serno) + strncpy(str, dev->serno, IPA_STRING_MAX); + break; + default: + LOGP(DLINP, LOGL_NOTICE, + "Unknown ipaccess tag 0x%02x\n", ies_req[i]); + msgb_free(msg); + return NULL; + } + str[IPA_STRING_MAX-1] = '\0'; + + LOGP(DLINP, LOGL_INFO, " tag %d: %s\n", ies_req[i], str); + tag = msgb_put(msg, 3 + strlen(str) + 1); + tag[0] = 0x00; + tag[1] = 1 + strlen(str) + 1; + tag[2] = ies_req[1]; + memcpy(tag + 3, str, strlen(str) + 1); + } + ipa_prepend_header(msg, IPAC_PROTO_IPACCESS); + return msg; +} + +/*! \brief Generate IPA CCM ID RESP based on requets payload + * \param[in] dev Descriptor describing identity data for response + * \param[in] data Payload of the IPA CCM ID GET request + * \param[in] len Length of \a data in octets + * \returns Message buffer with IPA CCM ID RESP */ +struct msgb *ipa_ccm_make_id_resp_from_req(const struct ipaccess_unit *dev, + const uint8_t *data, unsigned int len) +{ + uint8_t ies[len/2]; + unsigned int num_ies = 0; + const uint8_t *cur = data; + + /* build a array of the IEIs */ + while (len >= 2) { + uint8_t t_len, t_tag; + len -= 2; + t_len = *cur++; + t_tag = *cur++; + + if (t_len > len + 1) { + LOGP(DLINP, LOGL_ERROR, "IPA CCM tage 0x%02x does not fit\n", t_tag); + break; + } + + ies[num_ies++] = t_tag; + + cur += t_len; + len -= t_len; + } + return ipa_ccm_make_id_resp(dev, ies, num_ies); +} + int ipa_send(int fd, const void *msg, size_t msglen) { int ret; diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map index c825dd5..3ac37e1 100644 --- a/src/gsm/libosmogsm.map +++ b/src/gsm/libosmogsm.map @@ -378,6 +378,8 @@ ipa_ccm_idtag_name; ipa_ccm_idtag_parse; ipa_ccm_idtag_parse_off; +ipa_ccm_make_id_resp; +ipa_ccm_make_id_resp_from_req; ipa_msg_alloc; ipa_msg_recv; ipa_msg_recv_buffered; -- To view, visit https://gerrit.osmocom.org/2367 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Icbcd8827a75fd5f3393351c1ca372de85275ad35 Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sat Apr 15 21:14:17 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 15 Apr 2017 21:14:17 +0000 Subject: [PATCH] libosmo-sccp[master]: Add IPA/SCCPlite support as SIGTRAN alternative In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2282 to look at the new patch set (#3). Add IPA/SCCPlite support as SIGTRAN alternative This tries as good as possible to fit the IPA/SCCPlite stacking into the existing SIGTRAN/SS7 code architecture/model. To the user, the IPA protocol looks like yet another protocol on the same level as the choice between SUA and M3AU. On the inside, things are obviously quite different. We need to handle TCP with IPA framing instead of SCTP for both server and client. We also implement an alternative "ASP FSM" for IPA, which takes care of the CCM handshake (ID_REQ/ID_RESP/ID_ACK/ID_ACK2) for both client and server mode. In server mode, we use the 'unit name' as identifier to look up the AS, similar to how we use a routing context to look up the AS in the xUA case. We also have to bypass activating the default layer manager in the simple client to make sure we don't run into even more complexity. What's missing right now is some way to manually override/set the point codes. As IPA/SCCPlite is missing any routing label, we currently simply generate one with SPC=0/DPC=0, which will obviously not work in most configurations. Change-Id: I9098574cddeba10fcf8f1b6c196a7069a6805c56 --- M include/osmocom/sigtran/osmo_ss7.h M src/Makefile.am A src/ipa.c M src/osmo_ss7.c M src/osmo_ss7_hmrt.c M src/osmo_ss7_vty.c M src/sccp_scrc.c M src/sccp_user.c M src/xua_as_fsm.c M src/xua_asp_fsm.c M src/xua_asp_fsm.h M src/xua_internal.h 12 files changed, 683 insertions(+), 17 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/82/2282/3 diff --git a/include/osmocom/sigtran/osmo_ss7.h b/include/osmocom/sigtran/osmo_ss7.h index 76403e2..2ae4c1e 100644 --- a/include/osmocom/sigtran/osmo_ss7.h +++ b/include/osmocom/sigtran/osmo_ss7.h @@ -258,6 +258,7 @@ OSMO_SS7_ASP_PROT_NONE, OSMO_SS7_ASP_PROT_SUA, OSMO_SS7_ASP_PROT_M3UA, + OSMO_SS7_ASP_PROT_IPA, _NUM_OSMO_SS7_ASP_PROT }; @@ -359,6 +360,9 @@ /*! Were we dynamically allocated */ bool dyn_allocated; + /*! Pending message for non-blocking IPA read */ + struct msgb *pending_msg; + struct { char *name; char *description; diff --git a/src/Makefile.am b/src/Makefile.am index 217f2f7..15f17fe 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -30,6 +30,6 @@ sccp2sua.c sccp_scrc.c sccp_sclc.c sccp_scoc.c \ sccp_user.c xua_rkm.c xua_default_lm_fsm.c \ osmo_ss7.c osmo_ss7_hmrt.c xua_asp_fsm.c xua_as_fsm.c \ - osmo_ss7_vty.c sccp_vty.c + osmo_ss7_vty.c sccp_vty.c ipa.c libosmo_sigtran_la_LDFLAGS = -version-info $(LIBVERSION) -no-undefined -export-symbols-regex '^osmo_' libosmo_sigtran_la_LIBADD = $(LIBOSMOCORE_LIBS) $(LIBOSMONETIF_LIBS) $(LIBSCTP_LIBS) diff --git a/src/ipa.c b/src/ipa.c new file mode 100644 index 0000000..83dde9b --- /dev/null +++ b/src/ipa.c @@ -0,0 +1,184 @@ +/* implementation of IPA/SCCPlite transport */ + +/* (C) 2015-2017 by Harald Welte + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +//#include +#include +#include + +#include +#include +#include +#include + +#include "xua_internal.h" +#include "xua_asp_fsm.h" + + +/*! \brief Send a given xUA message via a given IPA "Application Server" + * \param[in] as Application Server through which to send \a xua + * \param[in] xua xUA message to be sent + * \return 0 on success; negative on error */ +int ipa_tx_xua_as(struct osmo_ss7_as *as, struct xua_msg *xua) +{ + struct xua_msg_part *data_ie; + struct msgb *msg; + unsigned int src_len; + const uint8_t *src; + uint8_t *dst; + + OSMO_ASSERT(as->cfg.proto == OSMO_SS7_ASP_PROT_IPA); + + /* we're actually only interested in the data part */ + data_ie = xua_msg_find_tag(xua, M3UA_IEI_PROT_DATA); + if (!data_ie || data_ie->len < sizeof(struct m3ua_data_hdr)) + return -1; + + /* and even the data part still has the header prepended */ + src = data_ie->dat + sizeof(struct m3ua_data_hdr); + src_len = data_ie->len - sizeof(struct m3ua_data_hdr); + + /* sufficient headroom for osmo_ipa_msg_push_header() */ + msg = ipa_msg_alloc(16); + if (!msg) + return -1; + + dst = msgb_put(msg, src_len); + memcpy(dst, src, src_len); + + /* TODO: if we ever need something beyond SCCP, we can use the + * M3UA SIO to determine the protocol */ + osmo_ipa_msg_push_header(msg, IPAC_PROTO_SCCP); + + return xua_as_transmit_msg(as, msg); +} + +static int ipa_rx_msg_ccm(struct osmo_ss7_asp *asp, struct msgb *msg) +{ + uint8_t msg_type = msg->l2h[0]; + + LOGPASP(asp, DLSS7, LOGL_DEBUG, "%s:%s\n", __func__, msgb_hexdump(msg)); + + /* Convert CCM into events to the IPA_ASP_FSM */ + switch (msg_type) { + case IPAC_MSGT_ID_ACK: + osmo_fsm_inst_dispatch(asp->fi, IPA_ASP_E_ID_ACK, msg); + break; + case IPAC_MSGT_ID_RESP: + osmo_fsm_inst_dispatch(asp->fi, IPA_ASP_E_ID_RESP, msg); + break; + case IPAC_MSGT_ID_GET: + osmo_fsm_inst_dispatch(asp->fi, IPA_ASP_E_ID_GET, msg); + break; + case IPAC_MSGT_PING: + osmo_fsm_inst_dispatch(asp->fi, XUA_ASP_E_ASPSM_BEAT, msg); + break; + case IPAC_MSGT_PONG: + osmo_fsm_inst_dispatch(asp->fi, XUA_ASP_E_ASPSM_BEAT_ACK, msg); + break; + default: + LOGPASP(asp, DLSS7, LOGL_NOTICE, "Unknown CCM Message 0x%02x: %s\n", + msg_type, msgb_hexdump(msg)); + return -1; + } + + msgb_free(msg); + + return 0; +} + +static int ipa_rx_msg_sccp(struct osmo_ss7_asp *asp, struct msgb *msg) +{ + struct osmo_mtp_prim *omp; + struct m3ua_data_hdr data_hdr; + struct xua_msg *xua = xua_msg_alloc(); + + /* pull the IPA header */ + msgb_pull_to_l2(msg); + + /* We have received an IPA-encapsulated SCCP message, without + * any MTP routing label. This means we have no real idea where + * it came from, nor where it goes to. We could simply treat it + * as being for the local point code, but then this means that + * we would have to implement SCCP connection coupling in order + * to route the connections to any other point code. The reason + * for this is the lack of addressing information inside the + * non-CR/CC connection oriented messages. + * + * The only other alternative we have is to simply have a + * STP (server) side configuration that specifies which point + * code those messages are to be routed to, and then use this + * 'override DPC' in the routing decision. We could do the same + * for the source point code to ensure responses are routed back + * to us. This is all quite ugly, but then what can we do :/ + */ + + memset(&data_hdr, 0, sizeof(data_hdr)); + data_hdr.opc = 0;//FIXME; + data_hdr.dpc = 0;//FIXME; + data_hdr.si = MTP_SI_SCCP; + xua = m3ua_xfer_from_data(&data_hdr, msgb_l2(msg), msgb_l2len(msg)); + + return m3ua_hmdc_rx_from_l2(asp->inst, xua); +} + +/*! \brief process M3UA message received from socket + * \param[in] asp Application Server Process receiving \a msg + * \param[in] msg received message buffer. Callee takes ownership! + * \returns 0 on success; negative on error */ +int ipa_rx_msg(struct osmo_ss7_asp *asp, struct msgb *msg) +{ + struct ipaccess_head *hh; + uint16_t len; + int rc; + + OSMO_ASSERT(asp->cfg.proto == OSMO_SS7_ASP_PROT_IPA); + + /* osmo_ipa_process_msg() will already have verified length + * consistency and set up l2h poiter */ + hh = (struct ipaccess_head *) msg->l1h; + + switch (hh->proto) { + case IPAC_PROTO_IPACCESS: + rc = ipa_rx_msg_ccm(asp, msg); + break; + case IPAC_PROTO_SCCP: + rc = ipa_rx_msg_sccp(asp, msg); + break; + default: + LOGPASP(asp, DLSS7, LOGL_DEBUG, "Unknown Stream ID 0x%02x: %s\n", + hh->proto, msgb_hexdump(msg)); + rc = -1; + } + + return rc; +} diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index 4aa7be5..ffe587c 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -41,6 +41,7 @@ #include #include +#include #include "sccp_internal.h" #include "xua_internal.h" @@ -68,11 +69,24 @@ { OSMO_SS7_ASP_PROT_NONE, "none" }, { OSMO_SS7_ASP_PROT_SUA, "sua" }, { OSMO_SS7_ASP_PROT_M3UA, "m3ua" }, + { OSMO_SS7_ASP_PROT_IPA, "ipa" }, { 0, NULL } }; #define LOGSS7(inst, level, fmt, args ...) \ LOGP(DLSS7, level, "%u: " fmt, inst ? (inst)->cfg.id : 0, ## args) + +static int asp_proto_to_ip_proto(enum osmo_ss7_asp_protocol proto) +{ + switch (proto) { + case OSMO_SS7_ASP_PROT_IPA: + return IPPROTO_TCP; + case OSMO_SS7_ASP_PROT_SUA: + case OSMO_SS7_ASP_PROT_M3UA: + default: + return IPPROTO_SCTP; + } +} int osmo_ss7_find_free_rctx(struct osmo_ss7_instance *inst) { @@ -1070,6 +1084,7 @@ } static int xua_cli_read_cb(struct osmo_stream_cli *conn); +static int ipa_cli_read_cb(struct osmo_stream_cli *conn); static int xua_cli_connect_cb(struct osmo_stream_cli *cli); int osmo_ss7_asp_restart(struct osmo_ss7_asp *asp) @@ -1100,10 +1115,13 @@ osmo_stream_cli_set_port(asp->client, asp->cfg.remote.port); osmo_stream_cli_set_local_addr(asp->client, asp->cfg.local.host); osmo_stream_cli_set_local_port(asp->client, asp->cfg.local.port); - osmo_stream_cli_set_proto(asp->client, IPPROTO_SCTP); + osmo_stream_cli_set_proto(asp->client, asp_proto_to_ip_proto(asp->cfg.proto)); osmo_stream_cli_set_reconnect_timeout(asp->client, 5); osmo_stream_cli_set_connect_cb(asp->client, xua_cli_connect_cb); - osmo_stream_cli_set_read_cb(asp->client, xua_cli_read_cb); + if (asp->cfg.proto == OSMO_SS7_ASP_PROT_IPA) + osmo_stream_cli_set_read_cb(asp->client, ipa_cli_read_cb); + else + osmo_stream_cli_set_read_cb(asp->client, xua_cli_read_cb); osmo_stream_cli_set_data(asp->client, asp); rc = osmo_stream_cli_open2(asp->client, 1); if (rc < 0) { @@ -1213,6 +1231,37 @@ notif->sn_header.sn_type)); break; } +} + +/* netif code tells us we can read something from the socket */ +static int ipa_srv_conn_cb(struct osmo_stream_srv *conn) +{ + struct osmo_fd *ofd = osmo_stream_srv_get_ofd(conn); + struct osmo_ss7_asp *asp = osmo_stream_srv_get_data(conn); + struct msgb *msg = NULL; + int rc; + + /* read IPA message from socket and process it */ + rc = ipa_msg_recv_buffered(ofd->fd, &msg, &asp->pending_msg); + LOGPASP(asp, DLSS7, LOGL_DEBUG, "%s(): ipa_msg_recv_buffered() returned %d\n", + __func__, rc); + if (rc <= 0) { + if (rc == -EAGAIN) { + /* more data needed */ + return 0; + } + osmo_stream_srv_destroy(conn); + return rc; + } + if (osmo_ipa_process_msg(msg) < 0) { + LOGPASP(asp, DLSS7, LOGL_ERROR, "Bad IPA message\n"); + osmo_stream_srv_destroy(conn); + msgb_free(msg); + return -1; + } + msg->dst = asp; + + return ipa_rx_msg(asp, msg); } /* netif code tells us we can read something from the socket */ @@ -1327,6 +1376,36 @@ osmo_stream_cli_reconnect(cli); } +/* read call-back for IPA/SCCPlite socket */ +static int ipa_cli_read_cb(struct osmo_stream_cli *conn) +{ + struct osmo_fd *ofd = osmo_stream_cli_get_ofd(conn); + struct osmo_ss7_asp *asp = osmo_stream_cli_get_data(conn); + struct msgb *msg = NULL; + int rc; + + /* read IPA message from socket and process it */ + rc = ipa_msg_recv_buffered(ofd->fd, &msg, &asp->pending_msg); + LOGPASP(asp, DLSS7, LOGL_DEBUG, "%s(): ipa_msg_recv_buffered() returned %d\n", + __func__, rc); + if (rc <= 0) { + if (rc == -EAGAIN) { + /* more data needed */ + return 0; + } + osmo_stream_cli_reconnect(conn); + return rc; + } + if (osmo_ipa_process_msg(msg) < 0) { + LOGPASP(asp, DLSS7, LOGL_ERROR, "Bad IPA message\n"); + osmo_stream_cli_reconnect(conn); + msgb_free(msg); + return -1; + } + msg->dst = asp; + return ipa_rx_msg(asp, msg); +} + static int xua_cli_read_cb(struct osmo_stream_cli *conn) { struct osmo_fd *ofd = osmo_stream_cli_get_ofd(conn); @@ -1439,15 +1518,21 @@ struct osmo_ss7_asp *asp; char *sock_name = osmo_sock_get_name(link, fd); - LOGP(DLSS7, LOGL_INFO, "%s: New SCTP connection accepted\n", - sock_name); + LOGP(DLSS7, LOGL_INFO, "%s: New %s connection accepted\n", + sock_name, get_value_string(osmo_ss7_asp_protocol_vals, oxs->cfg.proto)); - srv = osmo_stream_srv_create(oxs, link, fd, - xua_srv_conn_cb, - xua_srv_conn_closed_cb, NULL); + if (oxs->cfg.proto == OSMO_SS7_ASP_PROT_IPA) { + srv = osmo_stream_srv_create(oxs, link, fd, + ipa_srv_conn_cb, + xua_srv_conn_closed_cb, NULL); + } else { + srv = osmo_stream_srv_create(oxs, link, fd, + xua_srv_conn_cb, + xua_srv_conn_closed_cb, NULL); + } if (!srv) { LOGP(DLSS7, LOGL_ERROR, "%s: Unable to create stream server " - "for SCTP connection\n", sock_name); + "for connection\n", sock_name); close(fd); talloc_free(sock_name); return -1; @@ -1473,6 +1558,7 @@ sock_name, asp->cfg.name); asp->cfg.is_server = true; asp->dyn_allocated = true; + asp->server = srv; osmo_ss7_asp_restart(asp); } } @@ -1517,6 +1603,8 @@ break; case OSMO_SS7_ASP_PROT_M3UA: msgb_sctp_ppid(msg) = M3UA_PPID; + break; + case OSMO_SS7_ASP_PROT_IPA: break; default: OSMO_ASSERT(0); @@ -1589,8 +1677,8 @@ if (!oxs) return NULL; - LOGP(DLSS7, LOGL_INFO, "Creating XUA Server %s:%u\n", - local_host, local_port); + LOGP(DLSS7, LOGL_INFO, "Creating %s Server %s:%u\n", + get_value_string(osmo_ss7_asp_protocol_vals, proto), local_host, local_port); INIT_LLIST_HEAD(&oxs->asp_list); @@ -1605,7 +1693,7 @@ osmo_stream_srv_link_set_nodelay(oxs->server, true); osmo_stream_srv_link_set_addr(oxs->server, oxs->cfg.local.host); osmo_stream_srv_link_set_port(oxs->server, oxs->cfg.local.port); - osmo_stream_srv_link_set_proto(oxs->server, IPPROTO_SCTP); + osmo_stream_srv_link_set_proto(oxs->server, asp_proto_to_ip_proto(proto)); rc = osmo_stream_srv_link_open(oxs->server); if (rc < 0) { @@ -1664,6 +1752,7 @@ osmo_fsm_register(&sccp_scoc_fsm); osmo_fsm_register(&xua_as_fsm); osmo_fsm_register(&xua_asp_fsm); + osmo_fsm_register(&ipa_asp_fsm); osmo_fsm_register(&xua_default_lm_fsm); ss7_initialized = true; return 0; diff --git a/src/osmo_ss7_hmrt.c b/src/osmo_ss7_hmrt.c index ce0728b..bbbb3a9 100644 --- a/src/osmo_ss7_hmrt.c +++ b/src/osmo_ss7_hmrt.c @@ -141,6 +141,8 @@ switch (as->cfg.proto) { case OSMO_SS7_ASP_PROT_M3UA: return m3ua_tx_xua_as(as,xua); + case OSMO_SS7_ASP_PROT_IPA: + return ipa_tx_xua_as(as, xua); default: LOGP(DLSS7, LOGL_ERROR, "MTP message " "for ASP of unknown protocol%u\n", diff --git a/src/osmo_ss7_vty.c b/src/osmo_ss7_vty.c index 282a5a0..a6a0f5b 100644 --- a/src/osmo_ss7_vty.c +++ b/src/osmo_ss7_vty.c @@ -37,11 +37,12 @@ #include "xua_internal.h" -#define XUA_VAR_STR "(sua|m3ua)" +#define XUA_VAR_STR "(sua|m3ua|ipa)" #define XUA_VAR_HELP_STR \ "SCCP User Adaptation\n" \ - "MTP3 User Adaptation\n" + "MTP3 User Adaptation\n" \ + "IPA Multiplex (SCCP Lite)\n" /*********************************************************************** diff --git a/src/sccp_scrc.c b/src/sccp_scrc.c index 4491ce6..9a6a865 100644 --- a/src/sccp_scrc.c +++ b/src/sccp_scrc.c @@ -142,6 +142,7 @@ case OSMO_SS7_ASP_PROT_SUA: return sua_tx_xua_as(as, xua); case OSMO_SS7_ASP_PROT_M3UA: + case OSMO_SS7_ASP_PROT_IPA: return sua2sccp_tx_m3ua(inst, xua); default: LOGP(DLSCCP, LOGL_ERROR, "MTP-TRANSFER.req for " @@ -296,7 +297,8 @@ const struct osmo_sccp_addr *called) { struct osmo_sccp_user *scu; - + /* it is not really clear that called->pc will be set to + * anything here, in the case of a SSN-only CalledAddr */ scu = sccp_user_find(inst, called->ssn, called->pc); /* Is subsystem equipped? */ diff --git a/src/sccp_user.c b/src/sccp_user.c index 51cc6b1..d9e40b6 100644 --- a/src/sccp_user.c +++ b/src/sccp_user.c @@ -274,7 +274,8 @@ asp->cfg.local.host = talloc_strdup(asp, local_ip); asp->cfg.remote.host = talloc_strdup(asp, remote_ip); osmo_ss7_as_add_asp(as, asp_name); - osmo_ss7_asp_use_default_lm(asp, LOGL_DEBUG); + if (prot != OSMO_SS7_ASP_PROT_IPA) + osmo_ss7_asp_use_default_lm(asp, LOGL_DEBUG); talloc_free(asp_name); osmo_ss7_asp_restart(asp); diff --git a/src/xua_as_fsm.c b/src/xua_as_fsm.c index 282a6bf..0dd6ba1 100644 --- a/src/xua_as_fsm.c +++ b/src/xua_as_fsm.c @@ -38,6 +38,10 @@ struct msgb *msg; unsigned int i, sent = 0; + /* we don't send notify to IPA peers! */ + if (as->cfg.proto == OSMO_SS7_ASP_PROT_IPA) + return 0; + /* iterate over all non-DOWN ASPs and send them the message */ for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) { struct osmo_ss7_asp *asp = as->cfg.asps[i]; @@ -66,7 +70,7 @@ } /* actually transmit a message through this AS */ -static int xua_as_transmit_msg(struct osmo_ss7_as *as, struct msgb *msg) +int xua_as_transmit_msg(struct osmo_ss7_as *as, struct msgb *msg) { struct osmo_ss7_asp *asp; unsigned int i; diff --git a/src/xua_asp_fsm.c b/src/xua_asp_fsm.c index ce15038..147aa45 100644 --- a/src/xua_asp_fsm.c +++ b/src/xua_asp_fsm.c @@ -14,6 +14,11 @@ #include #include #include +#include +#include + +#include +#include #include #include @@ -65,6 +70,14 @@ { XUA_ASP_E_ASPSM_ASPDN_ACK, "ASPSM-ASP_DN_ACK" }, { XUA_ASP_E_ASPTM_ASPIA, "ASPTM-ASP_IA" }, { XUA_ASP_E_ASPTM_ASPIA_ACK, "ASPTM_ASP_IA_ACK" }, + + { XUA_ASP_E_ASPSM_BEAT, "ASPSM_BEAT" }, + { XUA_ASP_E_ASPSM_BEAT_ACK, "ASPSM_BEAT_ACK" }, + + { IPA_ASP_E_ID_RESP, "IPA_CCM_ID_RESP" }, + { IPA_ASP_E_ID_GET, "IPA_CCM_ID_GET" }, + { IPA_ASP_E_ID_ACK, "IPA_CCM_ID_ACK" }, + { 0, NULL } }; @@ -654,6 +667,8 @@ .allstate_action = xua_asp_allstate, }; +static struct osmo_fsm_inst *ipa_asp_fsm_start(struct osmo_ss7_asp *asp, + enum xua_asp_role role, int log_level); /*! \brief Start a new ASP finite stae machine for given ASP * \param[in] asp Application Server Process for which to start FSM @@ -665,6 +680,9 @@ { struct osmo_fsm_inst *fi; struct xua_asp_fsm_priv *xafp; + + if (asp->cfg.proto == OSMO_SS7_ASP_PROT_IPA) + return ipa_asp_fsm_start(asp, role, log_level); /* allocate as child of AS? */ fi = osmo_fsm_inst_alloc(&xua_asp_fsm, asp, NULL, log_level, asp->cfg.name); @@ -681,3 +699,352 @@ return fi; } + + + + + +/*********************************************************************** + * IPA Compatibility FSM + ***********************************************************************/ + +/* The idea here is to have a FSM that handles an IPA / SCCPlite link in + * a way that the higher-layer code considers it the same like an M3UA + * or SUA link. We have a couple of different states and some + * additional events. */ + +enum ipa_asp_state { + IPA_ASP_S_DOWN = XUA_ASP_S_DOWN, + IPA_ASP_S_ACTIVE = XUA_ASP_S_ACTIVE, + IPA_ASP_S_WAIT_ID_RESP, /* Waiting for ID_RESP from peer */ + IPA_ASP_S_WAIT_ID_GET, /* Waiting for ID_GET from peer */ + IPA_ASP_S_WAIT_ID_ACK, /* Waiting for ID_ACK from peer */ + IPA_ASP_S_WAIT_ID_ACK2, /* Waiting for ID_ACK (of ACK) from peer */ +}; + +/* private data structure for each FSM instance */ +struct ipa_asp_fsm_priv { + /* pointer back to ASP to which we belong */ + struct osmo_ss7_asp *asp; + /* Role (ASP/SG/IPSP) */ + enum xua_asp_role role; + + /* Structure holding parsed data of the IPA CCM ID exchange */ + struct ipaccess_unit *ipa_unit; + /* Timer for tracking if no PONG is received in response to PING */ + struct osmo_timer_list pong_timer; +}; + +enum ipa_asp_fsm_t { + T_WAIT_ID_RESP = 1, + T_WAIT_ID_ACK, + T_WAIT_ID_GET, +}; + +/* get the file descriptor related to a given ASP */ +static int get_fd_from_iafp(struct ipa_asp_fsm_priv *iafp) +{ + struct osmo_ss7_asp *asp = iafp->asp; + struct osmo_fd *ofd; + + if (asp->server) + ofd = osmo_stream_srv_get_ofd(asp->server); + else if (asp->client) + ofd = osmo_stream_cli_get_ofd(asp->client); + else + return -1; + + return ofd->fd; +} + +/* Server + Client: Initial State, wait for M-ASP-UP.req */ +static void ipa_asp_fsm_down(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct ipa_asp_fsm_priv *iafp = fi->priv; + int fd = get_fd_from_iafp(iafp); + + switch (event) { + case XUA_ASP_E_M_ASP_UP_REQ: + case XUA_ASP_E_SCTP_EST_IND: + if (iafp->role == XUA_ASPFSM_ROLE_SG) { + /* Server: Transmit IPA ID GET + Wait for Response */ + ipa_ccm_send_id_req(fd); + osmo_fsm_inst_state_chg(fi, IPA_ASP_S_WAIT_ID_RESP, 10, T_WAIT_ID_RESP); + } else { + /* Client: We simply wait for an ID GET */ + osmo_fsm_inst_state_chg(fi, IPA_ASP_S_WAIT_ID_GET, 10, T_WAIT_ID_GET); + } + break; + } +} + +/* Server: We're waiting for an ID RESP */ +static void ipa_asp_fsm_wait_id_resp(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct ipa_asp_fsm_priv *iafp = fi->priv; + struct osmo_ss7_asp *asp = iafp->asp; + int fd = get_fd_from_iafp(iafp); + struct osmo_ss7_as *as; + struct tlv_parsed tp; + struct msgb *msg; + int rc; + + switch (event) { + case IPA_ASP_E_ID_RESP: + /* resolve the AS based on the identity provided by peer. */ + msg = data; + rc = ipa_ccm_idtag_parse(&tp, msgb_l2(msg)+2, msgb_l2len(msg)-2); + if (rc < 0) { + LOGPFSML(fi, LOGL_ERROR, "Error %d parsing ID_RESP TLV: %s\n", rc, + msgb_hexdump(msg)); + goto out_err; + } + rc = ipa_ccm_tlv_to_unitdata(iafp->ipa_unit, &tp); + if (rc < 0) { + LOGPFSML(fi, LOGL_ERROR, "Error %d parsing ID_RESP: %s\n", rc, msgb_hexdump(msg)); + goto out_err; + } + if (!iafp->ipa_unit->unit_name) { + LOGPFSML(fi, LOGL_NOTICE, "No Unit Name specified by client\n"); + goto out_err; + } + as = osmo_ss7_as_find_by_name(asp->inst, iafp->ipa_unit->unit_name); + if (!as) { + LOGPFSML(fi, LOGL_NOTICE, "Cannot find any definition for IPA Unit Name '%s'\n", + iafp->ipa_unit->unit_name); + goto out_err; + } + osmo_ss7_as_add_asp(as, asp->cfg.name); + /* TODO: OAP Authentication? */ + /* Send ID_ACK */ + ipaccess_send_id_ack(fd); + osmo_fsm_inst_state_chg(fi, IPA_ASP_S_WAIT_ID_ACK2, 10, T_WAIT_ID_ACK); + break; + } + return; +out_err: + osmo_ss7_asp_disconnect(asp); + return; +} + +/* Server: We're waiting for an ID ACK */ +static void ipa_asp_fsm_wait_id_ack2(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + switch (event) { + case IPA_ASP_E_ID_ACK: + /* ACK received, we can go to active state now. The + * ACTIVE onenter function will inform the AS */ + osmo_fsm_inst_state_chg(fi, IPA_ASP_S_ACTIVE, 0, 0); + break; + } +} + +/* Client: We're waiting for an ID GET */ +static void ipa_asp_fsm_wait_id_get(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct ipa_asp_fsm_priv *iafp = fi->priv; + struct osmo_ss7_asp *asp = iafp->asp; + struct msgb *msg_get, *msg_resp; + const uint8_t *req_data; + int data_len; + + switch (event) { + case IPA_ASP_E_ID_GET: + msg_get = data; + req_data = msgb_l2(msg_get)+1; + data_len = msgb_l2len(msg_get)-1; + LOGPFSM(fi, "Received IPA CCM IDENTITY REQUEST for IEs %s\n", + osmo_hexdump(req_data, data_len)); + /* Send ID_RESP to server */ + msg_resp = ipa_ccm_make_id_resp_from_req(iafp->ipa_unit, req_data, data_len); + if (!msg_resp) { + LOGPFSML(fi, LOGL_ERROR, "Error building IPA CCM IDENTITY RESPONSE\n"); + break; + } + osmo_ss7_asp_send(asp, msg_resp); + osmo_fsm_inst_state_chg(fi, IPA_ASP_S_WAIT_ID_ACK, 10, T_WAIT_ID_ACK); + break; + } +} + +/* Client: We're waiting for an ID ACK */ +static void ipa_asp_fsm_wait_id_ack(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct ipa_asp_fsm_priv *iafp = fi->priv; + int fd; + + switch (event) { + case IPA_ASP_E_ID_ACK: + /* Send ACK2 to server */ + fd = get_fd_from_iafp(iafp); + ipaccess_send_id_ack(fd); + osmo_fsm_inst_state_chg(fi, IPA_ASP_S_ACTIVE, 0, 0); + break; + } +} + + +/* Server + Client: We're actively transmitting user data */ +static void ipa_asp_fsm_active(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + switch (event) { + case XUA_ASP_E_M_ASP_DOWN_REQ: + case XUA_ASP_E_M_ASP_INACTIVE_REQ: + /* FIXME: kill ASP and (wait for) re-connect */ + break; + } +} + +static void ipa_asp_allstate(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct ipa_asp_fsm_priv *iafp = fi->priv; + int fd; + + switch (event) { + case XUA_ASP_E_SCTP_COMM_DOWN_IND: + case XUA_ASP_E_SCTP_RESTART_IND: + osmo_fsm_inst_state_chg(fi, IPA_ASP_S_DOWN, 0, 0); + send_xlm_prim_simple(fi, OSMO_XLM_PRIM_M_ASP_DOWN, + PRIM_OP_INDICATION); + break; + case XUA_ASP_E_ASPSM_BEAT: + /* PING -> PONG */ + fd = get_fd_from_iafp(iafp); + ipaccess_send_pong(fd); + break; + case XUA_ASP_E_ASPSM_BEAT_ACK: + /* stop timer, if any */ + osmo_timer_del(&iafp->pong_timer); + break; + default: + break; + } +} + +static void ipa_asp_fsm_active_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state) +{ + dispatch_to_all_as(fi, XUA_ASPAS_ASP_INACTIVE_IND); + dispatch_to_all_as(fi, XUA_ASPAS_ASP_ACTIVE_IND); +} + +static void ipa_pong_timer_cb(void *_fi) +{ + struct osmo_fsm_inst *fi = _fi; + struct ipa_asp_fsm_priv *iafp = fi->priv; + + LOGPFSML(fi, LOGL_NOTICE, "Peer didn't respond to PING? with PONG!\n"); + /* kill ASP and (wait for) re-connect */ + osmo_ss7_asp_disconnect(iafp->asp); +} + +static int ipa_asp_fsm_timer_cb(struct osmo_fsm_inst *fi) +{ + struct ipa_asp_fsm_priv *iafp = fi->priv; + + LOGPFSML(fi, LOGL_ERROR, "Timeout waiting for peer response\n"); + /* kill ASP and (wait for) re-connect */ + osmo_ss7_asp_disconnect(iafp->asp); + return -1; +} + +static const struct osmo_fsm_state ipa_asp_states[] = { + [IPA_ASP_S_DOWN] = { + .in_event_mask = S(XUA_ASP_E_M_ASP_UP_REQ) | + S(XUA_ASP_E_SCTP_EST_IND), + .out_state_mask = S(IPA_ASP_S_WAIT_ID_GET) | + S(IPA_ASP_S_WAIT_ID_RESP), + .name = "ASP_DOWN", + .action = ipa_asp_fsm_down, + .onenter = xua_asp_fsm_down_onenter, + }, + /* Server Side */ + [IPA_ASP_S_WAIT_ID_RESP] = { + .in_event_mask = S(IPA_ASP_E_ID_RESP), + .out_state_mask = S(IPA_ASP_S_WAIT_ID_ACK2) | + S(IPA_ASP_S_DOWN), + .name = "WAIT_ID_RESP", + .action = ipa_asp_fsm_wait_id_resp, + }, + /* Server Side */ + [IPA_ASP_S_WAIT_ID_ACK2] = { + .in_event_mask = S(IPA_ASP_E_ID_ACK), + .out_state_mask = S(IPA_ASP_S_ACTIVE) | + S(IPA_ASP_S_DOWN), + .name = "WAIT_ID_ACK2", + .action = ipa_asp_fsm_wait_id_ack2, + }, + /* Client Side */ + [IPA_ASP_S_WAIT_ID_GET] = { + .in_event_mask = S(IPA_ASP_E_ID_GET), + .out_state_mask = S(IPA_ASP_S_WAIT_ID_ACK), + .name = "WAIT_ID_GET", + .action = ipa_asp_fsm_wait_id_get, + }, + /* Client Side */ + [IPA_ASP_S_WAIT_ID_ACK] = { + .in_event_mask = S(IPA_ASP_E_ID_ACK), + .out_state_mask = S(IPA_ASP_S_ACTIVE) | + S(IPA_ASP_S_DOWN), + .name = "WAIT_ID_ACK", + .action = ipa_asp_fsm_wait_id_ack, + }, + [IPA_ASP_S_ACTIVE] = { + .in_event_mask = S(XUA_ASP_E_M_ASP_DOWN_REQ) | + S(XUA_ASP_E_M_ASP_INACTIVE_REQ), + .out_state_mask = S(XUA_ASP_S_INACTIVE) | + S(XUA_ASP_S_DOWN), + .name = "ASP_ACTIVE", + .action = ipa_asp_fsm_active, + .onenter = ipa_asp_fsm_active_onenter, + }, +}; + + +struct osmo_fsm ipa_asp_fsm = { + .name = "IPA_ASP", + .states = ipa_asp_states, + .num_states = ARRAY_SIZE(ipa_asp_states), + .timer_cb = ipa_asp_fsm_timer_cb, + .log_subsys = DLSS7, + .event_names = xua_asp_event_names, + .allstate_event_mask = S(XUA_ASP_E_SCTP_COMM_DOWN_IND) | + S(XUA_ASP_E_SCTP_RESTART_IND) | + S(XUA_ASP_E_ASPSM_BEAT) | + S(XUA_ASP_E_ASPSM_BEAT_ACK), + .allstate_action = ipa_asp_allstate, +}; + + +/*! \brief Start a new ASP finite stae machine for given ASP + * \param[in] asp Application Server Process for which to start FSM + * \param[in] role Role (ASP, SG, IPSP) of this FSM + * \param[in] log_level Logging Level for ASP FSM logging + * \returns FSM instance on success; NULL on error */ +static struct osmo_fsm_inst *ipa_asp_fsm_start(struct osmo_ss7_asp *asp, + enum xua_asp_role role, int log_level) +{ + struct osmo_fsm_inst *fi; + struct ipa_asp_fsm_priv *iafp; + + /* allocate as child of AS? */ + fi = osmo_fsm_inst_alloc(&ipa_asp_fsm, asp, NULL, log_level, asp->cfg.name); + + iafp = talloc_zero(fi, struct ipa_asp_fsm_priv); + if (!iafp) { + osmo_fsm_inst_term(fi, OSMO_FSM_TERM_ERROR, NULL); + return NULL; + } + iafp->role = role; + iafp->asp = asp; + iafp->ipa_unit = talloc_zero(iafp, struct ipaccess_unit); + iafp->ipa_unit->unit_name = talloc_strdup(iafp->ipa_unit, asp->cfg.name); + iafp->pong_timer.cb = ipa_pong_timer_cb; + iafp->pong_timer.data = fi; + + fi->priv = iafp; + + if (role == XUA_ASPFSM_ROLE_ASP) + osmo_fsm_inst_dispatch(fi, XUA_ASP_E_M_ASP_UP_REQ, NULL); + + return fi; +} diff --git a/src/xua_asp_fsm.h b/src/xua_asp_fsm.h index 60e09da..32749ec 100644 --- a/src/xua_asp_fsm.h +++ b/src/xua_asp_fsm.h @@ -28,6 +28,11 @@ XUA_ASP_E_ASPSM_BEAT, XUA_ASP_E_ASPSM_BEAT_ACK, + /* IPA specific */ + IPA_ASP_E_ID_RESP, + IPA_ASP_E_ID_ACK, + IPA_ASP_E_ID_GET, + _NUM_XUA_ASP_E }; @@ -38,6 +43,7 @@ }; extern struct osmo_fsm xua_asp_fsm; +extern struct osmo_fsm ipa_asp_fsm; struct osmo_fsm_inst *xua_asp_fsm_start(struct osmo_ss7_asp *asp, enum xua_asp_role role, int log_level); diff --git a/src/xua_internal.h b/src/xua_internal.h index 3831f56..bb54205 100644 --- a/src/xua_internal.h +++ b/src/xua_internal.h @@ -66,3 +66,9 @@ #define CS7_STR "ITU-T Signaling System 7\n" #define PC_STR "Point Code\n" #define INST_STR "An instance of the SS7 stack\n" + +int xua_as_transmit_msg(struct osmo_ss7_as *as, struct msgb *msg); + + +int ipa_tx_xua_as(struct osmo_ss7_as *as, struct xua_msg *xua); +int ipa_rx_msg(struct osmo_ss7_asp *asp, struct msgb *msg); -- To view, visit https://gerrit.osmocom.org/2282 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I9098574cddeba10fcf8f1b6c196a7069a6805c56 Gerrit-PatchSet: 3 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sat Apr 15 21:14:17 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 15 Apr 2017 21:14:17 +0000 Subject: [PATCH] libosmo-sccp[master]: introduce new osmo_ss7_asp_disconnect() function In-Reply-To: References: Message-ID: introduce new osmo_ss7_asp_disconnect() function Higher-layer code shouldn't have to worry between client and server difference. It just wants to close the underlying connection for a given ASP - which it now can by means of osmo_ss7_asp_disconnect(). Change-Id: I36b089abd281b8edac8830fda2d8e57cc06cd0a7 --- M include/osmocom/sigtran/osmo_ss7.h M src/osmo_ss7.c 2 files changed, 10 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/64/2364/2 diff --git a/include/osmocom/sigtran/osmo_ss7.h b/include/osmocom/sigtran/osmo_ss7.h index a8c1c3c..76403e2 100644 --- a/include/osmocom/sigtran/osmo_ss7.h +++ b/include/osmocom/sigtran/osmo_ss7.h @@ -309,6 +309,7 @@ void osmo_ss7_as_destroy(struct osmo_ss7_as *as); bool osmo_ss7_as_has_asp(struct osmo_ss7_as *as, struct osmo_ss7_asp *asp); +void osmo_ss7_asp_disconnect(struct osmo_ss7_asp *asp); /*********************************************************************** diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index 2d34b53..4aa7be5 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -1543,6 +1543,15 @@ return 0; } +void osmo_ss7_asp_disconnect(struct osmo_ss7_asp *asp) +{ + if (asp->server) + osmo_stream_srv_destroy(asp->server); + /* the close_cb() will handle the remaining cleanup here */ + else if (asp->client) + xua_cli_close_and_reconnect(asp->client); +} + /*********************************************************************** * SS7 xUA Server ***********************************************************************/ -- To view, visit https://gerrit.osmocom.org/2364 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I36b089abd281b8edac8830fda2d8e57cc06cd0a7 Gerrit-PatchSet: 2 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Sat Apr 15 21:14:17 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 15 Apr 2017 21:14:17 +0000 Subject: [PATCH] libosmo-sccp[master]: osmo_ss7: make sure to re-set all state on client disconnect In-Reply-To: References: Message-ID: osmo_ss7: make sure to re-set all state on client disconnect When we disconnect a client, make sure that we always go through xua_cli_close_and_reconnect(), which will make sure to notify the ASP FSM using XUA_ASP_E_SCTP_COMM_DOWN_IND. Change-Id: I6859b8549c8cbbe2e8279da0ede562387a066d04 --- M src/osmo_ss7.c 1 file changed, 3 insertions(+), 5 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/65/2365/2 diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index ffe587c..cdaa770 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -1301,7 +1301,6 @@ switch (notif->sn_header.sn_type) { case SCTP_SHUTDOWN_EVENT: osmo_stream_srv_destroy(conn); - osmo_fsm_inst_dispatch(asp->fi, XUA_ASP_E_SCTP_COMM_DOWN_IND, asp); break; case SCTP_ASSOC_CHANGE: if (notif->sn_assoc_change.sac_state == SCTP_RESTART) @@ -1365,7 +1364,7 @@ struct osmo_ss7_asp *asp = osmo_stream_cli_get_data(cli); osmo_stream_cli_close(cli); - + osmo_fsm_inst_dispatch(asp->fi, XUA_ASP_E_SCTP_COMM_DOWN_IND, asp); /* send M-SCTP_RELEASE.ind to XUA Layer Manager */ xua_asp_send_xlm_prim_simple(asp, OSMO_XLM_PRIM_M_SCTP_RELEASE, PRIM_OP_INDICATION); } @@ -1393,12 +1392,12 @@ /* more data needed */ return 0; } - osmo_stream_cli_reconnect(conn); + xua_cli_close_and_reconnect(conn); return rc; } if (osmo_ipa_process_msg(msg) < 0) { LOGPASP(asp, DLSS7, LOGL_ERROR, "Bad IPA message\n"); - osmo_stream_cli_reconnect(conn); + xua_cli_close_and_reconnect(conn); msgb_free(msg); return -1; } @@ -1440,7 +1439,6 @@ switch (notif->sn_header.sn_type) { case SCTP_SHUTDOWN_EVENT: - osmo_fsm_inst_dispatch(asp->fi, XUA_ASP_E_SCTP_COMM_DOWN_IND, asp); xua_cli_close_and_reconnect(conn); break; case SCTP_ASSOC_CHANGE: -- To view, visit https://gerrit.osmocom.org/2365 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I6859b8549c8cbbe2e8279da0ede562387a066d04 Gerrit-PatchSet: 2 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte From gerrit-no-reply at lists.osmocom.org Sat Apr 15 21:14:17 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 15 Apr 2017 21:14:17 +0000 Subject: [PATCH] libosmo-sccp[master]: osmo_ss7: Clean up all ASPs established via xua_server upon ... In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2351 to look at the new patch set (#3). osmo_ss7: Clean up all ASPs established via xua_server upon destroy When we destroy a xua_server, we would like to close and destroy any ASPs that were established via that xua_server. In order to do so, we need to add a list of ASPs to the xua_server, which we can iterate. Change-Id: Iff3ed099b817e54e563b70d9ab40f63af63cc2fb --- M include/osmocom/sigtran/osmo_ss7.h M src/osmo_ss7.c 2 files changed, 17 insertions(+), 3 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/51/2351/3 diff --git a/include/osmocom/sigtran/osmo_ss7.h b/include/osmocom/sigtran/osmo_ss7.h index 376e399..a8c1c3c 100644 --- a/include/osmocom/sigtran/osmo_ss7.h +++ b/include/osmocom/sigtran/osmo_ss7.h @@ -339,6 +339,7 @@ /*! \ref osmo_xua_server over which we were established */ struct osmo_xua_server *xua_server; + struct llist_head siblings; /*! osmo_stream / libosmo-netif handles */ struct osmo_stream_cli *client; @@ -396,6 +397,9 @@ struct llist_head list; struct osmo_ss7_instance *inst; + /* list of ASPs established via this server */ + struct llist_head asp_list; + struct osmo_stream_srv_link *server; struct { diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index 771501f..44f34fe 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -1050,6 +1050,8 @@ osmo_stream_cli_destroy(asp->client); if (asp->fi) osmo_fsm_inst_term(asp->fi, OSMO_FSM_TERM_REQUEST, NULL); + if (asp->xua_server) + llist_del(&asp->siblings); /* unlink from all ASs we are part of */ llist_for_each_entry(as, &asp->inst->as_list, list) { @@ -1481,6 +1483,8 @@ /* update the ASP reference back to the server over which the * connection came in */ asp->server = srv; + asp->xua_server = oxs; + llist_add_tail(&asp->siblings, &oxs->asp_list); /* update the ASP socket name */ if (asp->sock_name) talloc_free(asp->sock_name); @@ -1575,6 +1579,8 @@ LOGP(DLSS7, LOGL_INFO, "Creating XUA Server %s:%u\n", local_host, local_port); + INIT_LLIST_HEAD(&oxs->asp_list); + oxs->cfg.proto = proto; oxs->cfg.local.port = local_port; oxs->cfg.local.host = talloc_strdup(oxs, local_host); @@ -1614,13 +1620,17 @@ void osmo_ss7_xua_server_destroy(struct osmo_xua_server *xs) { + struct osmo_ss7_asp *asp, *asp2; + if (xs->server) { osmo_stream_srv_link_close(xs->server); osmo_stream_srv_link_destroy(xs->server); } - /* FIXME: add asp_list to xua_server so we can iterate it here - * and close all connections established in relation with this - * server */ + /* iterate and close all connections established in relation + * with this server */ + llist_for_each_entry_safe(asp, asp2, &xs->asp_list, siblings) + osmo_ss7_asp_destroy(asp); + llist_del(&xs->list); talloc_free(xs); } -- To view, visit https://gerrit.osmocom.org/2351 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Iff3ed099b817e54e563b70d9ab40f63af63cc2fb Gerrit-PatchSet: 3 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sat Apr 15 21:15:17 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 15 Apr 2017 21:15:17 +0000 Subject: [ABANDON] libosmo-sccp[master]: osmo_ss7: fix missing assignment of asp->xua_server In-Reply-To: References: Message-ID: Harald Welte has abandoned this change. Change subject: osmo_ss7: fix missing assignment of asp->xua_server ...................................................................... Abandoned now part of Iff3ed099b817e54e563b70d9ab40f63af63cc2fb -- To view, visit https://gerrit.osmocom.org/2363 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: abandon Gerrit-Change-Id: Ic55cfbf2166381a4bf02596ad7bbe66a37e1a76f Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte From gerrit-no-reply at lists.osmocom.org Sat Apr 15 21:15:26 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 15 Apr 2017 21:15:26 +0000 Subject: libosmo-sccp[master]: osmo_ss7: Clean up all ASPs established via xua_server upon ... In-Reply-To: References: Message-ID: Patch Set 3: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2351 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Iff3ed099b817e54e563b70d9ab40f63af63cc2fb Gerrit-PatchSet: 3 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sat Apr 15 21:15:41 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 15 Apr 2017 21:15:41 +0000 Subject: libosmo-sccp[master]: osmo_ss7: avoid crash during disconnect after unknown ASP In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2361 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ib201f9f480f25ede0f26d4918007ff22fea28824 Gerrit-PatchSet: 2 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sat Apr 15 21:15:47 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 15 Apr 2017 21:15:47 +0000 Subject: libosmo-sccp[master]: Add new ASP event XUA_ASP_E_SCTP_EST_IND In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2362 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ib10914b27f8761ea44a0fdba96c045821223722a Gerrit-PatchSet: 2 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sat Apr 15 21:15:52 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 15 Apr 2017 21:15:52 +0000 Subject: libosmo-sccp[master]: introduce new osmo_ss7_asp_disconnect() function In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2364 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I36b089abd281b8edac8830fda2d8e57cc06cd0a7 Gerrit-PatchSet: 2 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sat Apr 15 21:21:50 2017 From: gerrit-no-reply at lists.osmocom.org (Pau Espin Pedrol) Date: Sat, 15 Apr 2017 21:21:50 +0000 Subject: [PATCH] libosmo-netif[master]: stream.h: Add missing stdint.h include Message-ID: Review at https://gerrit.osmocom.org/2368 stream.h: Add missing stdint.h include This header uses uint16_t, which is provided by stdint.h. Change-Id: I399e2986c9d8cb5b3dd31673a6b4bf63070a4770 --- M include/osmocom/netif/stream.h 1 file changed, 1 insertion(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-netif refs/changes/68/2368/1 diff --git a/include/osmocom/netif/stream.h b/include/osmocom/netif/stream.h index 08af3fd..4e1beb6 100644 --- a/include/osmocom/netif/stream.h +++ b/include/osmocom/netif/stream.h @@ -2,6 +2,7 @@ #define _OSMO_STREAM_H_ #include +#include /*! \addtogroup stream * @{ -- To view, visit https://gerrit.osmocom.org/2368 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I399e2986c9d8cb5b3dd31673a6b4bf63070a4770 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Pau Espin Pedrol From gerrit-no-reply at lists.osmocom.org Sat Apr 15 21:33:49 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 15 Apr 2017 21:33:49 +0000 Subject: [PATCH] libosmo-sccp[master]: Add IPA/SCCPlite support as SIGTRAN alternative In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2282 to look at the new patch set (#4). Add IPA/SCCPlite support as SIGTRAN alternative This tries as good as possible to fit the IPA/SCCPlite stacking into the existing SIGTRAN/SS7 code architecture/model. To the user, the IPA protocol looks like yet another protocol on the same level as the choice between SUA and M3AU. On the inside, things are obviously quite different. We need to handle TCP with IPA framing instead of SCTP for both server and client. We also implement an alternative "ASP FSM" for IPA, which takes care of the CCM handshake (ID_REQ/ID_RESP/ID_ACK/ID_ACK2) for both client and server mode. In server mode, we use the 'unit name' as identifier to look up the AS, similar to how we use a routing context to look up the AS in the xUA case. We also have to bypass activating the default layer manager in the simple client to make sure we don't run into even more complexity. What's missing right now is some way to manually override/set the point codes. As IPA/SCCPlite is missing any routing label, we currently simply generate one with SPC=0/DPC=0, which will obviously not work in most configurations. Change-Id: I9098574cddeba10fcf8f1b6c196a7069a6805c56 --- M include/osmocom/sigtran/osmo_ss7.h M src/Makefile.am A src/ipa.c M src/osmo_ss7.c M src/osmo_ss7_hmrt.c M src/osmo_ss7_vty.c M src/sccp_scrc.c M src/sccp_user.c M src/xua_as_fsm.c M src/xua_asp_fsm.c M src/xua_asp_fsm.h M src/xua_internal.h 12 files changed, 681 insertions(+), 17 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/82/2282/4 diff --git a/include/osmocom/sigtran/osmo_ss7.h b/include/osmocom/sigtran/osmo_ss7.h index 76403e2..2ae4c1e 100644 --- a/include/osmocom/sigtran/osmo_ss7.h +++ b/include/osmocom/sigtran/osmo_ss7.h @@ -258,6 +258,7 @@ OSMO_SS7_ASP_PROT_NONE, OSMO_SS7_ASP_PROT_SUA, OSMO_SS7_ASP_PROT_M3UA, + OSMO_SS7_ASP_PROT_IPA, _NUM_OSMO_SS7_ASP_PROT }; @@ -359,6 +360,9 @@ /*! Were we dynamically allocated */ bool dyn_allocated; + /*! Pending message for non-blocking IPA read */ + struct msgb *pending_msg; + struct { char *name; char *description; diff --git a/src/Makefile.am b/src/Makefile.am index 217f2f7..15f17fe 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -30,6 +30,6 @@ sccp2sua.c sccp_scrc.c sccp_sclc.c sccp_scoc.c \ sccp_user.c xua_rkm.c xua_default_lm_fsm.c \ osmo_ss7.c osmo_ss7_hmrt.c xua_asp_fsm.c xua_as_fsm.c \ - osmo_ss7_vty.c sccp_vty.c + osmo_ss7_vty.c sccp_vty.c ipa.c libosmo_sigtran_la_LDFLAGS = -version-info $(LIBVERSION) -no-undefined -export-symbols-regex '^osmo_' libosmo_sigtran_la_LIBADD = $(LIBOSMOCORE_LIBS) $(LIBOSMONETIF_LIBS) $(LIBSCTP_LIBS) diff --git a/src/ipa.c b/src/ipa.c new file mode 100644 index 0000000..1668f0f --- /dev/null +++ b/src/ipa.c @@ -0,0 +1,182 @@ +/* implementation of IPA/SCCPlite transport */ + +/* (C) 2015-2017 by Harald Welte + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +//#include +#include +#include + +#include +#include +#include +#include + +#include "xua_internal.h" +#include "xua_asp_fsm.h" + + +/*! \brief Send a given xUA message via a given IPA "Application Server" + * \param[in] as Application Server through which to send \a xua + * \param[in] xua xUA message to be sent + * \return 0 on success; negative on error */ +int ipa_tx_xua_as(struct osmo_ss7_as *as, struct xua_msg *xua) +{ + struct xua_msg_part *data_ie; + struct msgb *msg; + unsigned int src_len; + const uint8_t *src; + uint8_t *dst; + + OSMO_ASSERT(as->cfg.proto == OSMO_SS7_ASP_PROT_IPA); + + /* we're actually only interested in the data part */ + data_ie = xua_msg_find_tag(xua, M3UA_IEI_PROT_DATA); + if (!data_ie || data_ie->len < sizeof(struct m3ua_data_hdr)) + return -1; + + /* and even the data part still has the header prepended */ + src = data_ie->dat + sizeof(struct m3ua_data_hdr); + src_len = data_ie->len - sizeof(struct m3ua_data_hdr); + + /* sufficient headroom for osmo_ipa_msg_push_header() */ + msg = ipa_msg_alloc(16); + if (!msg) + return -1; + + dst = msgb_put(msg, src_len); + memcpy(dst, src, src_len); + + /* TODO: if we ever need something beyond SCCP, we can use the + * M3UA SIO to determine the protocol */ + osmo_ipa_msg_push_header(msg, IPAC_PROTO_SCCP); + + return xua_as_transmit_msg(as, msg); +} + +static int ipa_rx_msg_ccm(struct osmo_ss7_asp *asp, struct msgb *msg) +{ + uint8_t msg_type = msg->l2h[0]; + + LOGPASP(asp, DLSS7, LOGL_DEBUG, "%s:%s\n", __func__, msgb_hexdump(msg)); + + /* Convert CCM into events to the IPA_ASP_FSM */ + switch (msg_type) { + case IPAC_MSGT_ID_ACK: + osmo_fsm_inst_dispatch(asp->fi, IPA_ASP_E_ID_ACK, msg); + break; + case IPAC_MSGT_ID_RESP: + osmo_fsm_inst_dispatch(asp->fi, IPA_ASP_E_ID_RESP, msg); + break; + case IPAC_MSGT_ID_GET: + osmo_fsm_inst_dispatch(asp->fi, IPA_ASP_E_ID_GET, msg); + break; + case IPAC_MSGT_PING: + osmo_fsm_inst_dispatch(asp->fi, XUA_ASP_E_ASPSM_BEAT, msg); + break; + case IPAC_MSGT_PONG: + osmo_fsm_inst_dispatch(asp->fi, XUA_ASP_E_ASPSM_BEAT_ACK, msg); + break; + default: + LOGPASP(asp, DLSS7, LOGL_NOTICE, "Unknown CCM Message 0x%02x: %s\n", + msg_type, msgb_hexdump(msg)); + return -1; + } + + msgb_free(msg); + + return 0; +} + +static int ipa_rx_msg_sccp(struct osmo_ss7_asp *asp, struct msgb *msg) +{ + struct m3ua_data_hdr data_hdr; + struct xua_msg *xua = xua_msg_alloc(); + + /* pull the IPA header */ + msgb_pull_to_l2(msg); + + /* We have received an IPA-encapsulated SCCP message, without + * any MTP routing label. This means we have no real idea where + * it came from, nor where it goes to. We could simply treat it + * as being for the local point code, but then this means that + * we would have to implement SCCP connection coupling in order + * to route the connections to any other point code. The reason + * for this is the lack of addressing information inside the + * non-CR/CC connection oriented messages. + * + * The only other alternative we have is to simply have a + * STP (server) side configuration that specifies which point + * code those messages are to be routed to, and then use this + * 'override DPC' in the routing decision. We could do the same + * for the source point code to ensure responses are routed back + * to us. This is all quite ugly, but then what can we do :/ + */ + + memset(&data_hdr, 0, sizeof(data_hdr)); + data_hdr.opc = 0;//FIXME; + data_hdr.dpc = 0;//FIXME; + data_hdr.si = MTP_SI_SCCP; + xua = m3ua_xfer_from_data(&data_hdr, msgb_l2(msg), msgb_l2len(msg)); + + return m3ua_hmdc_rx_from_l2(asp->inst, xua); +} + +/*! \brief process M3UA message received from socket + * \param[in] asp Application Server Process receiving \a msg + * \param[in] msg received message buffer. Callee takes ownership! + * \returns 0 on success; negative on error */ +int ipa_rx_msg(struct osmo_ss7_asp *asp, struct msgb *msg) +{ + struct ipaccess_head *hh; + int rc; + + OSMO_ASSERT(asp->cfg.proto == OSMO_SS7_ASP_PROT_IPA); + + /* osmo_ipa_process_msg() will already have verified length + * consistency and set up l2h poiter */ + hh = (struct ipaccess_head *) msg->l1h; + + switch (hh->proto) { + case IPAC_PROTO_IPACCESS: + rc = ipa_rx_msg_ccm(asp, msg); + break; + case IPAC_PROTO_SCCP: + rc = ipa_rx_msg_sccp(asp, msg); + break; + default: + LOGPASP(asp, DLSS7, LOGL_DEBUG, "Unknown Stream ID 0x%02x: %s\n", + hh->proto, msgb_hexdump(msg)); + rc = -1; + } + + return rc; +} diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index 4aa7be5..ffe587c 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -41,6 +41,7 @@ #include #include +#include #include "sccp_internal.h" #include "xua_internal.h" @@ -68,11 +69,24 @@ { OSMO_SS7_ASP_PROT_NONE, "none" }, { OSMO_SS7_ASP_PROT_SUA, "sua" }, { OSMO_SS7_ASP_PROT_M3UA, "m3ua" }, + { OSMO_SS7_ASP_PROT_IPA, "ipa" }, { 0, NULL } }; #define LOGSS7(inst, level, fmt, args ...) \ LOGP(DLSS7, level, "%u: " fmt, inst ? (inst)->cfg.id : 0, ## args) + +static int asp_proto_to_ip_proto(enum osmo_ss7_asp_protocol proto) +{ + switch (proto) { + case OSMO_SS7_ASP_PROT_IPA: + return IPPROTO_TCP; + case OSMO_SS7_ASP_PROT_SUA: + case OSMO_SS7_ASP_PROT_M3UA: + default: + return IPPROTO_SCTP; + } +} int osmo_ss7_find_free_rctx(struct osmo_ss7_instance *inst) { @@ -1070,6 +1084,7 @@ } static int xua_cli_read_cb(struct osmo_stream_cli *conn); +static int ipa_cli_read_cb(struct osmo_stream_cli *conn); static int xua_cli_connect_cb(struct osmo_stream_cli *cli); int osmo_ss7_asp_restart(struct osmo_ss7_asp *asp) @@ -1100,10 +1115,13 @@ osmo_stream_cli_set_port(asp->client, asp->cfg.remote.port); osmo_stream_cli_set_local_addr(asp->client, asp->cfg.local.host); osmo_stream_cli_set_local_port(asp->client, asp->cfg.local.port); - osmo_stream_cli_set_proto(asp->client, IPPROTO_SCTP); + osmo_stream_cli_set_proto(asp->client, asp_proto_to_ip_proto(asp->cfg.proto)); osmo_stream_cli_set_reconnect_timeout(asp->client, 5); osmo_stream_cli_set_connect_cb(asp->client, xua_cli_connect_cb); - osmo_stream_cli_set_read_cb(asp->client, xua_cli_read_cb); + if (asp->cfg.proto == OSMO_SS7_ASP_PROT_IPA) + osmo_stream_cli_set_read_cb(asp->client, ipa_cli_read_cb); + else + osmo_stream_cli_set_read_cb(asp->client, xua_cli_read_cb); osmo_stream_cli_set_data(asp->client, asp); rc = osmo_stream_cli_open2(asp->client, 1); if (rc < 0) { @@ -1213,6 +1231,37 @@ notif->sn_header.sn_type)); break; } +} + +/* netif code tells us we can read something from the socket */ +static int ipa_srv_conn_cb(struct osmo_stream_srv *conn) +{ + struct osmo_fd *ofd = osmo_stream_srv_get_ofd(conn); + struct osmo_ss7_asp *asp = osmo_stream_srv_get_data(conn); + struct msgb *msg = NULL; + int rc; + + /* read IPA message from socket and process it */ + rc = ipa_msg_recv_buffered(ofd->fd, &msg, &asp->pending_msg); + LOGPASP(asp, DLSS7, LOGL_DEBUG, "%s(): ipa_msg_recv_buffered() returned %d\n", + __func__, rc); + if (rc <= 0) { + if (rc == -EAGAIN) { + /* more data needed */ + return 0; + } + osmo_stream_srv_destroy(conn); + return rc; + } + if (osmo_ipa_process_msg(msg) < 0) { + LOGPASP(asp, DLSS7, LOGL_ERROR, "Bad IPA message\n"); + osmo_stream_srv_destroy(conn); + msgb_free(msg); + return -1; + } + msg->dst = asp; + + return ipa_rx_msg(asp, msg); } /* netif code tells us we can read something from the socket */ @@ -1327,6 +1376,36 @@ osmo_stream_cli_reconnect(cli); } +/* read call-back for IPA/SCCPlite socket */ +static int ipa_cli_read_cb(struct osmo_stream_cli *conn) +{ + struct osmo_fd *ofd = osmo_stream_cli_get_ofd(conn); + struct osmo_ss7_asp *asp = osmo_stream_cli_get_data(conn); + struct msgb *msg = NULL; + int rc; + + /* read IPA message from socket and process it */ + rc = ipa_msg_recv_buffered(ofd->fd, &msg, &asp->pending_msg); + LOGPASP(asp, DLSS7, LOGL_DEBUG, "%s(): ipa_msg_recv_buffered() returned %d\n", + __func__, rc); + if (rc <= 0) { + if (rc == -EAGAIN) { + /* more data needed */ + return 0; + } + osmo_stream_cli_reconnect(conn); + return rc; + } + if (osmo_ipa_process_msg(msg) < 0) { + LOGPASP(asp, DLSS7, LOGL_ERROR, "Bad IPA message\n"); + osmo_stream_cli_reconnect(conn); + msgb_free(msg); + return -1; + } + msg->dst = asp; + return ipa_rx_msg(asp, msg); +} + static int xua_cli_read_cb(struct osmo_stream_cli *conn) { struct osmo_fd *ofd = osmo_stream_cli_get_ofd(conn); @@ -1439,15 +1518,21 @@ struct osmo_ss7_asp *asp; char *sock_name = osmo_sock_get_name(link, fd); - LOGP(DLSS7, LOGL_INFO, "%s: New SCTP connection accepted\n", - sock_name); + LOGP(DLSS7, LOGL_INFO, "%s: New %s connection accepted\n", + sock_name, get_value_string(osmo_ss7_asp_protocol_vals, oxs->cfg.proto)); - srv = osmo_stream_srv_create(oxs, link, fd, - xua_srv_conn_cb, - xua_srv_conn_closed_cb, NULL); + if (oxs->cfg.proto == OSMO_SS7_ASP_PROT_IPA) { + srv = osmo_stream_srv_create(oxs, link, fd, + ipa_srv_conn_cb, + xua_srv_conn_closed_cb, NULL); + } else { + srv = osmo_stream_srv_create(oxs, link, fd, + xua_srv_conn_cb, + xua_srv_conn_closed_cb, NULL); + } if (!srv) { LOGP(DLSS7, LOGL_ERROR, "%s: Unable to create stream server " - "for SCTP connection\n", sock_name); + "for connection\n", sock_name); close(fd); talloc_free(sock_name); return -1; @@ -1473,6 +1558,7 @@ sock_name, asp->cfg.name); asp->cfg.is_server = true; asp->dyn_allocated = true; + asp->server = srv; osmo_ss7_asp_restart(asp); } } @@ -1517,6 +1603,8 @@ break; case OSMO_SS7_ASP_PROT_M3UA: msgb_sctp_ppid(msg) = M3UA_PPID; + break; + case OSMO_SS7_ASP_PROT_IPA: break; default: OSMO_ASSERT(0); @@ -1589,8 +1677,8 @@ if (!oxs) return NULL; - LOGP(DLSS7, LOGL_INFO, "Creating XUA Server %s:%u\n", - local_host, local_port); + LOGP(DLSS7, LOGL_INFO, "Creating %s Server %s:%u\n", + get_value_string(osmo_ss7_asp_protocol_vals, proto), local_host, local_port); INIT_LLIST_HEAD(&oxs->asp_list); @@ -1605,7 +1693,7 @@ osmo_stream_srv_link_set_nodelay(oxs->server, true); osmo_stream_srv_link_set_addr(oxs->server, oxs->cfg.local.host); osmo_stream_srv_link_set_port(oxs->server, oxs->cfg.local.port); - osmo_stream_srv_link_set_proto(oxs->server, IPPROTO_SCTP); + osmo_stream_srv_link_set_proto(oxs->server, asp_proto_to_ip_proto(proto)); rc = osmo_stream_srv_link_open(oxs->server); if (rc < 0) { @@ -1664,6 +1752,7 @@ osmo_fsm_register(&sccp_scoc_fsm); osmo_fsm_register(&xua_as_fsm); osmo_fsm_register(&xua_asp_fsm); + osmo_fsm_register(&ipa_asp_fsm); osmo_fsm_register(&xua_default_lm_fsm); ss7_initialized = true; return 0; diff --git a/src/osmo_ss7_hmrt.c b/src/osmo_ss7_hmrt.c index ce0728b..bbbb3a9 100644 --- a/src/osmo_ss7_hmrt.c +++ b/src/osmo_ss7_hmrt.c @@ -141,6 +141,8 @@ switch (as->cfg.proto) { case OSMO_SS7_ASP_PROT_M3UA: return m3ua_tx_xua_as(as,xua); + case OSMO_SS7_ASP_PROT_IPA: + return ipa_tx_xua_as(as, xua); default: LOGP(DLSS7, LOGL_ERROR, "MTP message " "for ASP of unknown protocol%u\n", diff --git a/src/osmo_ss7_vty.c b/src/osmo_ss7_vty.c index 282a5a0..a6a0f5b 100644 --- a/src/osmo_ss7_vty.c +++ b/src/osmo_ss7_vty.c @@ -37,11 +37,12 @@ #include "xua_internal.h" -#define XUA_VAR_STR "(sua|m3ua)" +#define XUA_VAR_STR "(sua|m3ua|ipa)" #define XUA_VAR_HELP_STR \ "SCCP User Adaptation\n" \ - "MTP3 User Adaptation\n" + "MTP3 User Adaptation\n" \ + "IPA Multiplex (SCCP Lite)\n" /*********************************************************************** diff --git a/src/sccp_scrc.c b/src/sccp_scrc.c index 4491ce6..9a6a865 100644 --- a/src/sccp_scrc.c +++ b/src/sccp_scrc.c @@ -142,6 +142,7 @@ case OSMO_SS7_ASP_PROT_SUA: return sua_tx_xua_as(as, xua); case OSMO_SS7_ASP_PROT_M3UA: + case OSMO_SS7_ASP_PROT_IPA: return sua2sccp_tx_m3ua(inst, xua); default: LOGP(DLSCCP, LOGL_ERROR, "MTP-TRANSFER.req for " @@ -296,7 +297,8 @@ const struct osmo_sccp_addr *called) { struct osmo_sccp_user *scu; - + /* it is not really clear that called->pc will be set to + * anything here, in the case of a SSN-only CalledAddr */ scu = sccp_user_find(inst, called->ssn, called->pc); /* Is subsystem equipped? */ diff --git a/src/sccp_user.c b/src/sccp_user.c index 51cc6b1..d9e40b6 100644 --- a/src/sccp_user.c +++ b/src/sccp_user.c @@ -274,7 +274,8 @@ asp->cfg.local.host = talloc_strdup(asp, local_ip); asp->cfg.remote.host = talloc_strdup(asp, remote_ip); osmo_ss7_as_add_asp(as, asp_name); - osmo_ss7_asp_use_default_lm(asp, LOGL_DEBUG); + if (prot != OSMO_SS7_ASP_PROT_IPA) + osmo_ss7_asp_use_default_lm(asp, LOGL_DEBUG); talloc_free(asp_name); osmo_ss7_asp_restart(asp); diff --git a/src/xua_as_fsm.c b/src/xua_as_fsm.c index 282a6bf..0dd6ba1 100644 --- a/src/xua_as_fsm.c +++ b/src/xua_as_fsm.c @@ -38,6 +38,10 @@ struct msgb *msg; unsigned int i, sent = 0; + /* we don't send notify to IPA peers! */ + if (as->cfg.proto == OSMO_SS7_ASP_PROT_IPA) + return 0; + /* iterate over all non-DOWN ASPs and send them the message */ for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) { struct osmo_ss7_asp *asp = as->cfg.asps[i]; @@ -66,7 +70,7 @@ } /* actually transmit a message through this AS */ -static int xua_as_transmit_msg(struct osmo_ss7_as *as, struct msgb *msg) +int xua_as_transmit_msg(struct osmo_ss7_as *as, struct msgb *msg) { struct osmo_ss7_asp *asp; unsigned int i; diff --git a/src/xua_asp_fsm.c b/src/xua_asp_fsm.c index ce15038..147aa45 100644 --- a/src/xua_asp_fsm.c +++ b/src/xua_asp_fsm.c @@ -14,6 +14,11 @@ #include #include #include +#include +#include + +#include +#include #include #include @@ -65,6 +70,14 @@ { XUA_ASP_E_ASPSM_ASPDN_ACK, "ASPSM-ASP_DN_ACK" }, { XUA_ASP_E_ASPTM_ASPIA, "ASPTM-ASP_IA" }, { XUA_ASP_E_ASPTM_ASPIA_ACK, "ASPTM_ASP_IA_ACK" }, + + { XUA_ASP_E_ASPSM_BEAT, "ASPSM_BEAT" }, + { XUA_ASP_E_ASPSM_BEAT_ACK, "ASPSM_BEAT_ACK" }, + + { IPA_ASP_E_ID_RESP, "IPA_CCM_ID_RESP" }, + { IPA_ASP_E_ID_GET, "IPA_CCM_ID_GET" }, + { IPA_ASP_E_ID_ACK, "IPA_CCM_ID_ACK" }, + { 0, NULL } }; @@ -654,6 +667,8 @@ .allstate_action = xua_asp_allstate, }; +static struct osmo_fsm_inst *ipa_asp_fsm_start(struct osmo_ss7_asp *asp, + enum xua_asp_role role, int log_level); /*! \brief Start a new ASP finite stae machine for given ASP * \param[in] asp Application Server Process for which to start FSM @@ -665,6 +680,9 @@ { struct osmo_fsm_inst *fi; struct xua_asp_fsm_priv *xafp; + + if (asp->cfg.proto == OSMO_SS7_ASP_PROT_IPA) + return ipa_asp_fsm_start(asp, role, log_level); /* allocate as child of AS? */ fi = osmo_fsm_inst_alloc(&xua_asp_fsm, asp, NULL, log_level, asp->cfg.name); @@ -681,3 +699,352 @@ return fi; } + + + + + +/*********************************************************************** + * IPA Compatibility FSM + ***********************************************************************/ + +/* The idea here is to have a FSM that handles an IPA / SCCPlite link in + * a way that the higher-layer code considers it the same like an M3UA + * or SUA link. We have a couple of different states and some + * additional events. */ + +enum ipa_asp_state { + IPA_ASP_S_DOWN = XUA_ASP_S_DOWN, + IPA_ASP_S_ACTIVE = XUA_ASP_S_ACTIVE, + IPA_ASP_S_WAIT_ID_RESP, /* Waiting for ID_RESP from peer */ + IPA_ASP_S_WAIT_ID_GET, /* Waiting for ID_GET from peer */ + IPA_ASP_S_WAIT_ID_ACK, /* Waiting for ID_ACK from peer */ + IPA_ASP_S_WAIT_ID_ACK2, /* Waiting for ID_ACK (of ACK) from peer */ +}; + +/* private data structure for each FSM instance */ +struct ipa_asp_fsm_priv { + /* pointer back to ASP to which we belong */ + struct osmo_ss7_asp *asp; + /* Role (ASP/SG/IPSP) */ + enum xua_asp_role role; + + /* Structure holding parsed data of the IPA CCM ID exchange */ + struct ipaccess_unit *ipa_unit; + /* Timer for tracking if no PONG is received in response to PING */ + struct osmo_timer_list pong_timer; +}; + +enum ipa_asp_fsm_t { + T_WAIT_ID_RESP = 1, + T_WAIT_ID_ACK, + T_WAIT_ID_GET, +}; + +/* get the file descriptor related to a given ASP */ +static int get_fd_from_iafp(struct ipa_asp_fsm_priv *iafp) +{ + struct osmo_ss7_asp *asp = iafp->asp; + struct osmo_fd *ofd; + + if (asp->server) + ofd = osmo_stream_srv_get_ofd(asp->server); + else if (asp->client) + ofd = osmo_stream_cli_get_ofd(asp->client); + else + return -1; + + return ofd->fd; +} + +/* Server + Client: Initial State, wait for M-ASP-UP.req */ +static void ipa_asp_fsm_down(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct ipa_asp_fsm_priv *iafp = fi->priv; + int fd = get_fd_from_iafp(iafp); + + switch (event) { + case XUA_ASP_E_M_ASP_UP_REQ: + case XUA_ASP_E_SCTP_EST_IND: + if (iafp->role == XUA_ASPFSM_ROLE_SG) { + /* Server: Transmit IPA ID GET + Wait for Response */ + ipa_ccm_send_id_req(fd); + osmo_fsm_inst_state_chg(fi, IPA_ASP_S_WAIT_ID_RESP, 10, T_WAIT_ID_RESP); + } else { + /* Client: We simply wait for an ID GET */ + osmo_fsm_inst_state_chg(fi, IPA_ASP_S_WAIT_ID_GET, 10, T_WAIT_ID_GET); + } + break; + } +} + +/* Server: We're waiting for an ID RESP */ +static void ipa_asp_fsm_wait_id_resp(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct ipa_asp_fsm_priv *iafp = fi->priv; + struct osmo_ss7_asp *asp = iafp->asp; + int fd = get_fd_from_iafp(iafp); + struct osmo_ss7_as *as; + struct tlv_parsed tp; + struct msgb *msg; + int rc; + + switch (event) { + case IPA_ASP_E_ID_RESP: + /* resolve the AS based on the identity provided by peer. */ + msg = data; + rc = ipa_ccm_idtag_parse(&tp, msgb_l2(msg)+2, msgb_l2len(msg)-2); + if (rc < 0) { + LOGPFSML(fi, LOGL_ERROR, "Error %d parsing ID_RESP TLV: %s\n", rc, + msgb_hexdump(msg)); + goto out_err; + } + rc = ipa_ccm_tlv_to_unitdata(iafp->ipa_unit, &tp); + if (rc < 0) { + LOGPFSML(fi, LOGL_ERROR, "Error %d parsing ID_RESP: %s\n", rc, msgb_hexdump(msg)); + goto out_err; + } + if (!iafp->ipa_unit->unit_name) { + LOGPFSML(fi, LOGL_NOTICE, "No Unit Name specified by client\n"); + goto out_err; + } + as = osmo_ss7_as_find_by_name(asp->inst, iafp->ipa_unit->unit_name); + if (!as) { + LOGPFSML(fi, LOGL_NOTICE, "Cannot find any definition for IPA Unit Name '%s'\n", + iafp->ipa_unit->unit_name); + goto out_err; + } + osmo_ss7_as_add_asp(as, asp->cfg.name); + /* TODO: OAP Authentication? */ + /* Send ID_ACK */ + ipaccess_send_id_ack(fd); + osmo_fsm_inst_state_chg(fi, IPA_ASP_S_WAIT_ID_ACK2, 10, T_WAIT_ID_ACK); + break; + } + return; +out_err: + osmo_ss7_asp_disconnect(asp); + return; +} + +/* Server: We're waiting for an ID ACK */ +static void ipa_asp_fsm_wait_id_ack2(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + switch (event) { + case IPA_ASP_E_ID_ACK: + /* ACK received, we can go to active state now. The + * ACTIVE onenter function will inform the AS */ + osmo_fsm_inst_state_chg(fi, IPA_ASP_S_ACTIVE, 0, 0); + break; + } +} + +/* Client: We're waiting for an ID GET */ +static void ipa_asp_fsm_wait_id_get(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct ipa_asp_fsm_priv *iafp = fi->priv; + struct osmo_ss7_asp *asp = iafp->asp; + struct msgb *msg_get, *msg_resp; + const uint8_t *req_data; + int data_len; + + switch (event) { + case IPA_ASP_E_ID_GET: + msg_get = data; + req_data = msgb_l2(msg_get)+1; + data_len = msgb_l2len(msg_get)-1; + LOGPFSM(fi, "Received IPA CCM IDENTITY REQUEST for IEs %s\n", + osmo_hexdump(req_data, data_len)); + /* Send ID_RESP to server */ + msg_resp = ipa_ccm_make_id_resp_from_req(iafp->ipa_unit, req_data, data_len); + if (!msg_resp) { + LOGPFSML(fi, LOGL_ERROR, "Error building IPA CCM IDENTITY RESPONSE\n"); + break; + } + osmo_ss7_asp_send(asp, msg_resp); + osmo_fsm_inst_state_chg(fi, IPA_ASP_S_WAIT_ID_ACK, 10, T_WAIT_ID_ACK); + break; + } +} + +/* Client: We're waiting for an ID ACK */ +static void ipa_asp_fsm_wait_id_ack(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct ipa_asp_fsm_priv *iafp = fi->priv; + int fd; + + switch (event) { + case IPA_ASP_E_ID_ACK: + /* Send ACK2 to server */ + fd = get_fd_from_iafp(iafp); + ipaccess_send_id_ack(fd); + osmo_fsm_inst_state_chg(fi, IPA_ASP_S_ACTIVE, 0, 0); + break; + } +} + + +/* Server + Client: We're actively transmitting user data */ +static void ipa_asp_fsm_active(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + switch (event) { + case XUA_ASP_E_M_ASP_DOWN_REQ: + case XUA_ASP_E_M_ASP_INACTIVE_REQ: + /* FIXME: kill ASP and (wait for) re-connect */ + break; + } +} + +static void ipa_asp_allstate(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct ipa_asp_fsm_priv *iafp = fi->priv; + int fd; + + switch (event) { + case XUA_ASP_E_SCTP_COMM_DOWN_IND: + case XUA_ASP_E_SCTP_RESTART_IND: + osmo_fsm_inst_state_chg(fi, IPA_ASP_S_DOWN, 0, 0); + send_xlm_prim_simple(fi, OSMO_XLM_PRIM_M_ASP_DOWN, + PRIM_OP_INDICATION); + break; + case XUA_ASP_E_ASPSM_BEAT: + /* PING -> PONG */ + fd = get_fd_from_iafp(iafp); + ipaccess_send_pong(fd); + break; + case XUA_ASP_E_ASPSM_BEAT_ACK: + /* stop timer, if any */ + osmo_timer_del(&iafp->pong_timer); + break; + default: + break; + } +} + +static void ipa_asp_fsm_active_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state) +{ + dispatch_to_all_as(fi, XUA_ASPAS_ASP_INACTIVE_IND); + dispatch_to_all_as(fi, XUA_ASPAS_ASP_ACTIVE_IND); +} + +static void ipa_pong_timer_cb(void *_fi) +{ + struct osmo_fsm_inst *fi = _fi; + struct ipa_asp_fsm_priv *iafp = fi->priv; + + LOGPFSML(fi, LOGL_NOTICE, "Peer didn't respond to PING? with PONG!\n"); + /* kill ASP and (wait for) re-connect */ + osmo_ss7_asp_disconnect(iafp->asp); +} + +static int ipa_asp_fsm_timer_cb(struct osmo_fsm_inst *fi) +{ + struct ipa_asp_fsm_priv *iafp = fi->priv; + + LOGPFSML(fi, LOGL_ERROR, "Timeout waiting for peer response\n"); + /* kill ASP and (wait for) re-connect */ + osmo_ss7_asp_disconnect(iafp->asp); + return -1; +} + +static const struct osmo_fsm_state ipa_asp_states[] = { + [IPA_ASP_S_DOWN] = { + .in_event_mask = S(XUA_ASP_E_M_ASP_UP_REQ) | + S(XUA_ASP_E_SCTP_EST_IND), + .out_state_mask = S(IPA_ASP_S_WAIT_ID_GET) | + S(IPA_ASP_S_WAIT_ID_RESP), + .name = "ASP_DOWN", + .action = ipa_asp_fsm_down, + .onenter = xua_asp_fsm_down_onenter, + }, + /* Server Side */ + [IPA_ASP_S_WAIT_ID_RESP] = { + .in_event_mask = S(IPA_ASP_E_ID_RESP), + .out_state_mask = S(IPA_ASP_S_WAIT_ID_ACK2) | + S(IPA_ASP_S_DOWN), + .name = "WAIT_ID_RESP", + .action = ipa_asp_fsm_wait_id_resp, + }, + /* Server Side */ + [IPA_ASP_S_WAIT_ID_ACK2] = { + .in_event_mask = S(IPA_ASP_E_ID_ACK), + .out_state_mask = S(IPA_ASP_S_ACTIVE) | + S(IPA_ASP_S_DOWN), + .name = "WAIT_ID_ACK2", + .action = ipa_asp_fsm_wait_id_ack2, + }, + /* Client Side */ + [IPA_ASP_S_WAIT_ID_GET] = { + .in_event_mask = S(IPA_ASP_E_ID_GET), + .out_state_mask = S(IPA_ASP_S_WAIT_ID_ACK), + .name = "WAIT_ID_GET", + .action = ipa_asp_fsm_wait_id_get, + }, + /* Client Side */ + [IPA_ASP_S_WAIT_ID_ACK] = { + .in_event_mask = S(IPA_ASP_E_ID_ACK), + .out_state_mask = S(IPA_ASP_S_ACTIVE) | + S(IPA_ASP_S_DOWN), + .name = "WAIT_ID_ACK", + .action = ipa_asp_fsm_wait_id_ack, + }, + [IPA_ASP_S_ACTIVE] = { + .in_event_mask = S(XUA_ASP_E_M_ASP_DOWN_REQ) | + S(XUA_ASP_E_M_ASP_INACTIVE_REQ), + .out_state_mask = S(XUA_ASP_S_INACTIVE) | + S(XUA_ASP_S_DOWN), + .name = "ASP_ACTIVE", + .action = ipa_asp_fsm_active, + .onenter = ipa_asp_fsm_active_onenter, + }, +}; + + +struct osmo_fsm ipa_asp_fsm = { + .name = "IPA_ASP", + .states = ipa_asp_states, + .num_states = ARRAY_SIZE(ipa_asp_states), + .timer_cb = ipa_asp_fsm_timer_cb, + .log_subsys = DLSS7, + .event_names = xua_asp_event_names, + .allstate_event_mask = S(XUA_ASP_E_SCTP_COMM_DOWN_IND) | + S(XUA_ASP_E_SCTP_RESTART_IND) | + S(XUA_ASP_E_ASPSM_BEAT) | + S(XUA_ASP_E_ASPSM_BEAT_ACK), + .allstate_action = ipa_asp_allstate, +}; + + +/*! \brief Start a new ASP finite stae machine for given ASP + * \param[in] asp Application Server Process for which to start FSM + * \param[in] role Role (ASP, SG, IPSP) of this FSM + * \param[in] log_level Logging Level for ASP FSM logging + * \returns FSM instance on success; NULL on error */ +static struct osmo_fsm_inst *ipa_asp_fsm_start(struct osmo_ss7_asp *asp, + enum xua_asp_role role, int log_level) +{ + struct osmo_fsm_inst *fi; + struct ipa_asp_fsm_priv *iafp; + + /* allocate as child of AS? */ + fi = osmo_fsm_inst_alloc(&ipa_asp_fsm, asp, NULL, log_level, asp->cfg.name); + + iafp = talloc_zero(fi, struct ipa_asp_fsm_priv); + if (!iafp) { + osmo_fsm_inst_term(fi, OSMO_FSM_TERM_ERROR, NULL); + return NULL; + } + iafp->role = role; + iafp->asp = asp; + iafp->ipa_unit = talloc_zero(iafp, struct ipaccess_unit); + iafp->ipa_unit->unit_name = talloc_strdup(iafp->ipa_unit, asp->cfg.name); + iafp->pong_timer.cb = ipa_pong_timer_cb; + iafp->pong_timer.data = fi; + + fi->priv = iafp; + + if (role == XUA_ASPFSM_ROLE_ASP) + osmo_fsm_inst_dispatch(fi, XUA_ASP_E_M_ASP_UP_REQ, NULL); + + return fi; +} diff --git a/src/xua_asp_fsm.h b/src/xua_asp_fsm.h index 60e09da..32749ec 100644 --- a/src/xua_asp_fsm.h +++ b/src/xua_asp_fsm.h @@ -28,6 +28,11 @@ XUA_ASP_E_ASPSM_BEAT, XUA_ASP_E_ASPSM_BEAT_ACK, + /* IPA specific */ + IPA_ASP_E_ID_RESP, + IPA_ASP_E_ID_ACK, + IPA_ASP_E_ID_GET, + _NUM_XUA_ASP_E }; @@ -38,6 +43,7 @@ }; extern struct osmo_fsm xua_asp_fsm; +extern struct osmo_fsm ipa_asp_fsm; struct osmo_fsm_inst *xua_asp_fsm_start(struct osmo_ss7_asp *asp, enum xua_asp_role role, int log_level); diff --git a/src/xua_internal.h b/src/xua_internal.h index 3831f56..bb54205 100644 --- a/src/xua_internal.h +++ b/src/xua_internal.h @@ -66,3 +66,9 @@ #define CS7_STR "ITU-T Signaling System 7\n" #define PC_STR "Point Code\n" #define INST_STR "An instance of the SS7 stack\n" + +int xua_as_transmit_msg(struct osmo_ss7_as *as, struct msgb *msg); + + +int ipa_tx_xua_as(struct osmo_ss7_as *as, struct xua_msg *xua); +int ipa_rx_msg(struct osmo_ss7_asp *asp, struct msgb *msg); -- To view, visit https://gerrit.osmocom.org/2282 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I9098574cddeba10fcf8f1b6c196a7069a6805c56 Gerrit-PatchSet: 4 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sat Apr 15 21:33:50 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 15 Apr 2017 21:33:50 +0000 Subject: [PATCH] libosmo-sccp[master]: osmo_ss7: Allocate message buffers with headroom Message-ID: Review at https://gerrit.osmocom.org/2369 osmo_ss7: Allocate message buffers with headroom The use of m3ua_msgb_alloc() from generic code is a bit ugly, but I really don't want to introduce yet another msgb_alloc wrapper. Change-Id: Ic6dc9a1e7bbed2e1f73395bd18b727fa7892e25b --- M src/osmo_ss7.c 1 file changed, 2 insertions(+), 3 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/69/2369/1 diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index cdaa770..935fd87 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -48,7 +48,6 @@ #include "xua_asp_fsm.h" #include "xua_as_fsm.h" -#define ASP_MSGB_SIZE 1500 #define MAX_PC_STR_LEN 32 static bool ss7_initialized = false; @@ -1269,7 +1268,7 @@ { struct osmo_fd *ofd = osmo_stream_srv_get_ofd(conn); struct osmo_ss7_asp *asp = osmo_stream_srv_get_data(conn); - struct msgb *msg = msgb_alloc(ASP_MSGB_SIZE, "xUA Server Rx"); + struct msgb *msg = m3ua_msgb_alloc("xUA Server Rx"); struct sctp_sndrcvinfo sinfo; unsigned int ppid; int flags = 0; @@ -1409,7 +1408,7 @@ { struct osmo_fd *ofd = osmo_stream_cli_get_ofd(conn); struct osmo_ss7_asp *asp = osmo_stream_cli_get_data(conn); - struct msgb *msg = msgb_alloc(ASP_MSGB_SIZE, "xUA Client Rx"); + struct msgb *msg = m3ua_msgb_alloc("xUA Client Rx"); struct sctp_sndrcvinfo sinfo; unsigned int ppid; int flags = 0; -- To view, visit https://gerrit.osmocom.org/2369 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ic6dc9a1e7bbed2e1f73395bd18b727fa7892e25b Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Sat Apr 15 21:33:50 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 15 Apr 2017 21:33:50 +0000 Subject: [PATCH] libosmo-sccp[master]: IPA: Override/Set point codes Message-ID: Review at https://gerrit.osmocom.org/2370 IPA: Override/Set point codes As an IPA SCCPlite message arrives without any MTP routing label, we simply construct one artificially for all inbound IPA/SCCPlite packets: * we set the SPC to the point-code of the routing key of the AS (as this is the PC we route to this IPA/SCCPlite client anyway) * we set the DPC to a point-code from a new vty config command "point-code override dpc" Change-Id: Id556398e1ded3e613cfde7ea8b71aff7a414ff90 --- M include/osmocom/sigtran/osmo_ss7.h M src/ipa.c M src/osmo_ss7_vty.c 3 files changed, 64 insertions(+), 2 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/70/2370/1 diff --git a/include/osmocom/sigtran/osmo_ss7.h b/include/osmocom/sigtran/osmo_ss7.h index 2ae4c1e..7b0a607 100644 --- a/include/osmocom/sigtran/osmo_ss7.h +++ b/include/osmocom/sigtran/osmo_ss7.h @@ -291,6 +291,9 @@ enum osmo_ss7_as_traffic_mode mode; uint32_t recovery_timeout_msec; uint8_t qos_class; + struct { + uint32_t dpc; + } pc_override;; struct osmo_ss7_asp *asps[16]; } cfg; diff --git a/src/ipa.c b/src/ipa.c index 1668f0f..df3dbd1 100644 --- a/src/ipa.c +++ b/src/ipa.c @@ -116,10 +116,33 @@ return 0; } +static struct osmo_ss7_as *find_as_for_asp(struct osmo_ss7_asp *asp) +{ + struct osmo_ss7_as *as; + + /* in the IPA case, weassume there is a 1:1 mapping between the + * ASP and the AS. An AS without ASP means there is no + * connection, and an ASP without AS means that we don't (yet?) + * know the identity of the peer */ + + llist_for_each_entry(as, &asp->inst->as_list, list) { + if (osmo_ss7_as_has_asp(as, asp)) + return as; + } + return NULL; +} + static int ipa_rx_msg_sccp(struct osmo_ss7_asp *asp, struct msgb *msg) { struct m3ua_data_hdr data_hdr; struct xua_msg *xua = xua_msg_alloc(); + struct osmo_ss7_as *as = find_as_for_asp(asp); + + if (!as) { + LOGPASP(asp, DLSS7, LOGL_ERROR, "Rx message for IPA ASP without AS?!\n"); + msgb_free(msg); + return -1; + } /* pull the IPA header */ msgb_pull_to_l2(msg); @@ -142,9 +165,18 @@ */ memset(&data_hdr, 0, sizeof(data_hdr)); - data_hdr.opc = 0;//FIXME; - data_hdr.dpc = 0;//FIXME; data_hdr.si = MTP_SI_SCCP; + if (asp->cfg.is_server) { + /* Source: the PC of the routing key */ + data_hdr.opc = as->cfg.routing_key.pc; + /* Destination: Based on VTY config */ + data_hdr.dpc = as->cfg.pc_override.dpc; + } else { + /* Source: Based on VTY config */ + data_hdr.opc = as->cfg.pc_override.dpc; + /* Destination: PC of the routing key */ + data_hdr.dpc = as->cfg.routing_key.pc; + } xua = m3ua_xfer_from_data(&data_hdr, msgb_l2(msg), msgb_l2len(msg)); return m3ua_hmdc_rx_from_l2(asp->inst, xua); diff --git a/src/osmo_ss7_vty.c b/src/osmo_ss7_vty.c index a6a0f5b..0ff9e76 100644 --- a/src/osmo_ss7_vty.c +++ b/src/osmo_ss7_vty.c @@ -789,6 +789,28 @@ return CMD_SUCCESS; } +DEFUN(as_pc_override, as_pc_override_cmd, + "point-code override dpc PC", + "Point Code Specific Features\n" + "Override (force) a point-code to hard-coded value\n" + "Override Source Point Code\n" + "Override Destination Point Code\n" + "New Point Code\n") +{ + struct osmo_ss7_as *as = vty->index; + uint32_t pc = osmo_ss7_pointcode_parse(as->inst, argv[0]); + + if (as->cfg.proto != OSMO_SS7_ASP_PROT_IPA) { + vty_out(vty, "Only IPA type AS support point-code override. " + "Be happy that you don't need it!%s", VTY_NEWLINE); + return CMD_WARNING; + } + + as->cfg.pc_override.dpc = pc; + + return CMD_SUCCESS; +} + static void write_one_as(struct vty *vty, struct osmo_ss7_as *as) { struct osmo_ss7_routing_key *rkey; @@ -826,6 +848,10 @@ if (rkey->ssn) vty_out(vty, " ssn %u", rkey->ssn); vty_out(vty, "%s", VTY_NEWLINE); + + if (as->cfg.pc_override.dpc) + vty_out(vty, " point-code override dpc %s%s", + osmo_ss7_pointcode_print(as->inst, as->cfg.pc_override.dpc), VTY_NEWLINE); } DEFUN(show_cs7_as, show_cs7_as_cmd, @@ -1012,6 +1038,7 @@ install_element(L_CS7_AS_NODE, &as_recov_tout_cmd); install_element(L_CS7_AS_NODE, &as_qos_class_cmd); install_element(L_CS7_AS_NODE, &as_rout_key_cmd); + install_element(L_CS7_AS_NODE, &as_pc_override_cmd); } void osmo_ss7_vty_init_asp(void) -- To view, visit https://gerrit.osmocom.org/2370 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Id556398e1ded3e613cfde7ea8b71aff7a414ff90 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Sat Apr 15 21:34:06 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sat, 15 Apr 2017 21:34:06 +0000 Subject: libosmo-sccp[master]: osmo_ss7: Allocate message buffers with headroom In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2369 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ic6dc9a1e7bbed2e1f73395bd18b727fa7892e25b Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sun Apr 16 01:13:58 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 16 Apr 2017 01:13:58 +0000 Subject: [PATCH] osmo-gsm-manuals[master]: First step towards an OsmoSTP manual Message-ID: Review at https://gerrit.osmocom.org/2371 First step towards an OsmoSTP manual Change-Id: I450bfac7444ac9cb7f50c086d87cf7157c2e2a31 --- M Makefile A OsmoSTP/Makefile A OsmoSTP/osmostp-usermanual-docinfo.xml A OsmoSTP/osmostp-usermanual.adoc A OsmoSTP/osmostp-vty-reference.xml A OsmoSTP/vty/stp_vty_reference.xml M common/chapters/bibliography.adoc M common/chapters/glossary.adoc A common/chapters/sigtran-osmocom.adoc A common/chapters/sigtran-simple-2g.dot A common/chapters/sigtran-simple-3g.dot A common/chapters/sigtran.adoc 12 files changed, 1,019 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-gsm-manuals refs/changes/71/2371/1 diff --git a/Makefile b/Makefile index 035595c..ed0c894 100644 --- a/Makefile +++ b/Makefile @@ -6,6 +6,7 @@ cd OsmoSGSN; $(MAKE) cd OsmoNAT; $(MAKE) cd OsmoPCU; $(MAKE) + cd OsmoSTP; $(MAKE) clean: cd OsmoBTS; $(MAKE) clean @@ -15,6 +16,7 @@ cd OsmoSGSN; $(MAKE) clean cd OsmoNAT; $(MAKE) clean cd OsmoPCU; $(MAKE) clean + cd OsmoSTP; $(MAKE) clean upload: cd OsmoBTS; $(MAKE) upload @@ -24,6 +26,7 @@ cd OsmoSGSN; $(MAKE) upload cd OsmoNAT; $(MAKE) upload cd OsmoPCU; $(MAKE) upload + cd OsmoSTP; $(MAKE) upload check: cd OsmoBTS; $(MAKE) check @@ -31,6 +34,7 @@ cd OsmoBSC; $(MAKE) check cd OsmoSGSN; $(MAKE) check cd OsmoPCU; $(MAKE) check + cd OsmoSTP; $(MAKE) check # These don't use asciidoc, so they have no 'make check' target: #cd OsmoMGCP; $(MAKE) check #cd OsmoNAT; $(MAKE) check diff --git a/OsmoSTP/Makefile b/OsmoSTP/Makefile new file mode 100644 index 0000000..bf3ba8f --- /dev/null +++ b/OsmoSTP/Makefile @@ -0,0 +1,45 @@ +# XSL stylesheets downloaded from http://docbook.sourceforge.net/release/xsl/current/html/ +# Makefile from BitBake/OpenEmbedded manuals + + +EXTRA_DEPS = gen-stp-vty-docbook + +topdir = . +stp_reference = $(topdir)/osmostp-vty-reference.xml +manuals = $(stp_reference) +# types = pdf txt rtf ps xhtml html man tex texi dvi +# types = pdf txt +types = $(docbooktotypes) +docbooktotypes = pdf +# htmlcssfile = +# htmlcss = + +TOPDIR := .. +ASCIIDOCS := osmostp-usermanual + +include $(TOPDIR)/build/Makefile.asciidoc.inc +include $(TOPDIR)/build/Makefile.inc + +osmostp-usermanual.pdf: chapters/*.adoc + +clean: + -rm -rf $(cleanfiles) + -rm osmostp-usermanual__*.png + -rm osmostp-usermanual__*.svg + -rm osmostp-usermanual*.check + +gen-stp-vty-docbook: FORCE + $(call command,xsltproc -o generated/combined1.xml \ + --stringparam with $(PWD)/../common/vty_additions.xml \ + $(MERGE_DOC) vty/stp_vty_reference.xml, \ + XSLTPROC,Merging Common VTY) + $(call command,xsltproc -o generated/combined2.xml \ + --stringparam with $(PWD)/../common/stp_vty_additions.xml \ + $(MERGE_DOC) generated/combined1.xml, \ + XSLTPROC,Merging Common STP VTY) + $(call command,xsltproc -o generated/combined3.xml \ + --stringparam with $(PWD)/vty/stp_vty_additions.xml \ + $(MERGE_DOC) generated/combined2.xml, \ + XSLTPROC,Merging STP VTY) + $(call command,xsltproc ../vty_reference.xsl generated/combined3.xml > generated/docbook_vty.xml, \ + XSLTPROC,Converting STP VTY to DocBook) diff --git a/OsmoSTP/osmostp-usermanual-docinfo.xml b/OsmoSTP/osmostp-usermanual-docinfo.xml new file mode 100644 index 0000000..4253957 --- /dev/null +++ b/OsmoSTP/osmostp-usermanual-docinfo.xml @@ -0,0 +1,47 @@ + + + 1 + April 16, 2017 + HW + + Initial OsmoSTP manual + + + + + + + Harald + Welte + hwelte at sysmocom.de + HW + + sysmocom + sysmocom - s.f.m.c. GmbH + Managing Director + + + + + + 2012-2017 + sysmocom - s.f.m.c. GmbH + + + + + Permission is granted to copy, distribute and/or modify this + document under the terms of the GNU Free Documentation License, + Version 1.3 or any later version published by the Free Software + Foundation; with the Invariant Sections being just 'Foreword', + 'Acknowledgements' and 'Preface', with no Front-Cover Texts, + and no Back-Cover Texts. A copy of the license is included in + the section entitled "GNU Free Documentation License". + + + The Asciidoc source code of this manual can be found at + + http://git.osmocom.org/osmo-gsm-manuals/ + + + diff --git a/OsmoSTP/osmostp-usermanual.adoc b/OsmoSTP/osmostp-usermanual.adoc new file mode 100644 index 0000000..c7c48ac --- /dev/null +++ b/OsmoSTP/osmostp-usermanual.adoc @@ -0,0 +1,33 @@ +OsmoSTP User Manual +=================== +Harald Welte + + +include::../common/chapters/preface.adoc[] + +// include::chapters/overview.adoc[] + +include::../common/chapters/sigtran.adoc[] +include::../common/chapters/sigtran-osmocom.adoc[] + +//include::chapters/running.adoc[] +// include::chapters/control.adoc[] + +include::../common/chapters/vty.adoc[] + +include::../common/chapters/logging.adoc[] + +include::../common/chapters/bts.adoc[] + +//include::../OsmoNITB/chapters/bts-examples.adoc[] + +include::../common/chapters/control_if.adoc[] + +include::../common/chapters/port_numbers.adoc[] + +include::../common/chapters/bibliography.adoc[] + +include::../common/chapters/glossary.adoc[] + +include::../common/chapters/gfdl.adoc[] + diff --git a/OsmoSTP/osmostp-vty-reference.xml b/OsmoSTP/osmostp-vty-reference.xml new file mode 100644 index 0000000..807d427 --- /dev/null +++ b/OsmoSTP/osmostp-vty-reference.xml @@ -0,0 +1,38 @@ + + + + +]> + + + + + + v1 + April 16, 2017 + h2 + Initial + + + + OsmoSTP VTY Reference + + + 2012-2017 + + + + This work is copyright by sysmocom - s.f.m.c. GmbH. All rights reserved. + + + + + + &chapter-vty; + + diff --git a/OsmoSTP/vty/stp_vty_reference.xml b/OsmoSTP/vty/stp_vty_reference.xml new file mode 100644 index 0000000..a4c675e --- /dev/null +++ b/OsmoSTP/vty/stp_vty_reference.xml @@ -0,0 +1,2 @@ + + diff --git a/common/chapters/bibliography.adoc b/common/chapters/bibliography.adoc index a3c6436..d5e1c1b 100644 --- a/common/chapters/bibliography.adoc +++ b/common/chapters/bibliography.adoc @@ -106,11 +106,29 @@ https://tools.ietf.org/html/rfc1350 - [[[ietf-rfc2131]]] IETF RFC 2131: Dynamic Host Configuration Protocol https://tools.ietf.org/html/rfc2131 +- [[[ietf-rfc2719]]] IETF RFC 2719: Signal Transport over IP + https://tools.ietf.org/html/rfc2719 +- [[[ietf-rfc3331]]] IETF RFC 3331: Message Transfer Part 2 User Adaptation Layer + https://tools.ietf.org/html/rfc3331 - [[[ietf-rfc3550]]] IETF RFC 3550: RTP: A Transport protocol for Real-Time Applications https://tools.ietf.org/html/rfc3550 +- [[[ietf-rfc3868]]] IETF RFC 3868: SCCP User Adaptation Layer + https://tools.ietf.org/html/rfc3868 +- [[[ietf-rfc4165]]] IETF RFC 4165: Message Transfer Part 2 Peer-to-Peeer Adaptation Layer + https://tools.ietf.org/html/rfc4165 - [[[ietf-rfc4251]]] IETF RFC 4251: The Secure Shell (SSH) Protocol Architecture https://tools.ietf.org/html/rfc4251 +- [[[ietf-rfc4666]]] IETF RFC 4666: Message Transfer Part 3 User Adaptation Layer + https://tools.ietf.org/html/rfc4666 +- [[[itu-t-q701]]] ITU-T Q.701: Functional Description of the Message Transfer Part (MTP) + https://www.itu.int/rec/T-REC-Q.701/en/ +- [[[itu-t-q711]]] ITU-T Q.711: Functional Description of the Signalling Connection Control Part + https://www.itu.int/rec/T-REC-Q.711/en/ +- [[[itu-t-q713]]] ITU-T Q.713: Signalling connection control part formats and codes + https://www.itu.int/rec/T-REC-Q.713/en/ +- [[[itu-t-q714]]] ITU-T Q.714: Signalling connection control part procedures + https://www.itu.int/rec/T-REC-Q.714/en/ - [[[itu-t-q921]]] ITU-T Q.921: ISDN user-network interface - Data link layer specification https://www.itu.int/rec/T-REC-Q.921/en diff --git a/common/chapters/glossary.adoc b/common/chapters/glossary.adoc index c39d439..042fd3a 100644 --- a/common/chapters/glossary.adoc +++ b/common/chapters/glossary.adoc @@ -115,6 +115,8 @@ GSMTAP:: GSM tap; pseudo standard for encapsulating GSM protocol layers over UDP/IP for analysis +GT:: + Global Title; an address in SCCP GTP:: GPRS Tunnel Protocol; used between SGSN and GGSN HLR:: @@ -143,6 +145,12 @@ 44.064_ <<3gpp-ts-44-064>>) Location Area:: Location Area; a geographic area containing multiple BTS +M2PA:: + MTP2 Peer-to-Peer Adaptation; a SIGTRAN Variant (_RFC 4165_ <>) +M2UA:: + MTP2 User Adaptation; a SIGTRAN Variant (_RFC 3331_ <>) +M3UA:: + MTP3 User Adaptation; a SIGTRAN Variant (_RFC 4666_ <>) MCC:: Mobile Country Code; unique identifier of a country, e.g. 262 for Germany MFF:: @@ -163,6 +171,8 @@ core network MSISDN:: Mobile Subscriber ISDN Number; telephone number of the subscriber +MTP:: + Message Transfer Part; SS7 signaling protocol (_ITU-T Q.701_ <>) MVNO:: Mobile Virtual Network Operator; Operator without physical radio network NCC:: @@ -206,6 +216,8 @@ OTA:: Over-The-Air; Capability of operators to remotely reconfigure/reprogram ISM/USIM cards +PC:: + Point Code; an address in MTP PCH:: Paging Channel on downlink Um interface; used by network to page an MS PCU:: @@ -249,11 +261,15 @@ SACCH:: Slow Associate Control Channel on Um interface; bundled to a TCH or SDCCH, used for signalling in parallel to active dedicated channel +SCCP:: + Signaling Connection Control Part; SS7 signaling protocol (_ITU-T Q.711_ <>) SDCCH:: Slow Dedicated Control Channel on Um interface; used for signalling and SMS transport in GSM SDK:: Software Development Kit +SIGTRAN:: + Signaling Transport over IP (_IETF RFC 2719_ <>) SIM:: Subscriber Identity Module; small chip card storing subscriber identity Site:: @@ -264,8 +280,16 @@ entities with an SMSC SMSC:: Short Message Service Center; store-and-forward relay for short messages +SS7:: + Signaling System No. 7; Classic digital telephony signaling system SSH:: Secure Shell; _IETF RFC 4250_ <> to 4254 +SSN:: + Sub-System Number; identifies a given SCCP Service such as MSC, HLR +STP:: + Signaling Transfer Point; A Router in SS7 Networks +SUA:: + SCCP User Adaptation; a SIGTRAN Variant (_RFC 3868_ <>) syslog:: System logging service of UNIX-like operating systems System Information:: diff --git a/common/chapters/sigtran-osmocom.adoc b/common/chapters/sigtran-osmocom.adoc new file mode 100644 index 0000000..1e08733 --- /dev/null +++ b/common/chapters/sigtran-osmocom.adoc @@ -0,0 +1,432 @@ +== Osmocom SS7 + SIGTRAN support + +=== History / Background + +If you're upgrading from earlier releases of the Osmocom stack, this +section will give you some background about the evolution. + +==== The Past (before 2017) + +In the original implementation of the GSM BSC inside Osmocom (the +OsmoBSC program, part of OpenBSC), no SS7 support was included. + +This is despite the fact that ETSI/3GPP mandated the use of SCCP over +MTP over E1/T1 TDM lines for the A interface at that time. + +Instead of going down to the TDM based legacy physical layers, OsmoBSC +implemented someting called an IPA multiplex, which apparently some +people also refer to as SCCPlite. We have never seen any +specifications for this interface, but implemented it from scratch +using protocol traces. + +The IPA protocol stack is based on a minimal sub-set of SCCP +(including connection oriented SCCP) wrapped into a 3-byte header to +packetize a TCP stream. + +The IPA/SCCPlite based A interface existed at a time when the +ETSI/3GPP specifications did not offer any IP based transport for the +A interface. An official as added only in Release FIXME of the 3GPP +specifications. + +The A interface BSSMAP protocol refers to voice circuits (E1/T1 +timeslots) using circuit identity codes (CICs). As there are no +physical timeslots on a TCP/IP based transport layer, the CICs get +mapped to RTP streams for circuit-switched data using out-of-band +signaling via MGCP, the IETF-standardized Media Gateway Control +Protocol. + +==== The present (2017) + +In 2017, sysmocom was tasked with implementing a 3GPP AoIP compliant A +interface. This meant that lot of things had to change in the +existing code: + +* removal of the existing hard-wired SCCPlite/IPA code from OsmoBSC +* introduction of a formal SCCP User SAP at the lower boundary of + BSSMAP +* introduction of libosmo-sigtran, a comprehensive SS7 and SIGTRAN + library which includes a SCCP implementation for connectionless and + connection-oriented procedures, offering the SCCP User SAP towards + BSSAP +* introduction of an A interface in OsmoMSC (which so far offered Iu + only) +* port of the existing SUA-baesd IuCS and IuPS over to the SCCP User + SAP of libosmo-sigtran. +* Implementation of ETSI M3UA as preferred/primary transport layer for + SCCP +* Implementation of an IPA transport layer inside libosmo-sigtran, in + order to keep backwards-compatibility. + +This work enables the Osmocom universe to become more compliant +with modern Releases of 3GPP specifications, which enables +interoperability with other MSCs or even BSCs. However, this comes at +a price: Increased complexity in set-up and configuration. + +Using SS7 or SIGTRAN based transport of the A interface adds an +entirely new domain that needs to be understood by system and network +administrators setting up cellular networks based on Osmocom. + +One of the key advantages of the Osmocom architecture with OsmoNITB +was exactly this simplification and reduction of complexity, enabling +more people to set-up and operate cellular networks. + +So we have put some thought into how we can achieve compatibility with +SS7/SIGTRAN and the 3GPP specifications, while at the same time +enabling some degree of auto-configuration where a small network can +be set up without too many configuration related to the signaling +network. We have achieved this by "abusing" (or extending) the M3UA +Routing Key Management slightly. + +=== Osmocom extensions to SIGTRAN + +Osmocom has implemented some extensions to the SIGTRAN protocol suite. +Those extensions will be documented below. + +==== Osmocom M3UA Routing Key Management Extensions + +In classic M3UA, a peer identifies its remote peer based on IP address +and port details. So once an ASP connects to an SG, the SG will check +if there is any configuration that matches the source IP (and possibly +source port) of that connection in order to understand which routing +context is used - and subsequently which traffic is to be routed to +this M3UA peer. + +This is quite inflexible, as it means that every BSC in a GSM network +needs to be manually pre-configured at the SG/STP, and that +configuration on the BSC and MSC must match to enable communication. + +M3UA specifies an optional Routing Key Management (RKM) sub-protocol. +Using RKM, an ASP can dynamically tell the SG/STP, which traffic it +wants to receive. However, the idea is still that the SG has some +matching configuration. + +In OsmoSTP based on libosmo-sigtran, we decided to (optionally) enable +fully dynamic registration. This means that any ASP can simply +connect to the SG and request the dynamic creation of an ASP and AS +with a corresponding routing key for a given point code. As long as +the SG doesn't already have a route to this requested point code, The +SG will simply trust any ASP and set a corresponding route. + +This is of course highly insecure and can only be used in trusted, +internal newtworks. However, it is quite elegant in reducing the +amount of configuration complexity. All that is needed, is that an +unique point code is configured at each of the ASPs (application +programs) that connect to the STP. + +To put things more concretely: Each BSC and MSC connecting to OsmoSTP +simply needs to be configured to have a different point code, and to +know to which IP/port of the STP to connect. There's no other +configuration required for a small, autonomous, self-contained +network. OsmoSTP will automatically insall ASP, AS and route +definitions on demand, and route messages between all connected +entities. + +The same above of course also applies to HNB-GW and OsmoSGSN in the +case of Iu interfaces. + +==== IPA / SCCPlite backwards compatibility + +The fundamental problem with IPA/SCCPlite is that there's no MTP +routing label surrounding the SCCP message. This is generally +problematic in the context of connection-oriented SCCP, as there is no +addressing information inside the SCCP messages after the connection +has been established. Instead, the messages are routed based on the +MTP label, containing point codes established during connection set-up +time. + +This means that even if the SCCP messages did contain Called/Calling +Party Addresses with point codes or global titles, it would only help +us for routing connectionless SCCP. The A interface, however, is +connection-oriented. + +So in order to integrate IPA/SCCPlite with a new full-blown +SS7/SIGTRAN stack, there are the following options: + +. implement SCCP connection coupling. This is something like a proxy + for connection-oriented SCCP, and is what is used in SS7 to route + beyond a given MTP netwokr (e.g. at gateways between different MTP + networks) + +. consider all SCCP messages to be destined for the local point code + of the receiver. This then means that the SG functionality must be + included inside the MSC, and the MSC be bound to the SSN on the + local point code. + +. hard-code some DPC when receiving a message from an IPA connection. + It could be any remote PC and we'd simply route the message towards + that point code. + +But then we also have the return direction: + +. We could "assign" a unique SPC to each connected IPA client (BSC), + and then announce that PC towards the SS7 side. Return packets + would then end up at our IPA-server-bearing STP, which forwards them + to the respective IPA connection and thus BSC. On the transmit + side, we'd simply strip the MTP routing label and send the raw SCCP + message over IPA. + +. If the IPA server / SGW resides within the MSC, one could also have + some kind of handle/reference to the specific TCP connection through + which the BSC connected. All responses for a given peer would then + have to be routed back to the same connection. This is quite ugly + as it completely breaks the concepts of the SCCP User SAP, where a + user has no information (nor to worry about ) any "physical" + signaling links. + + +=== Minimal Osmocom SIGTRAN configurations for small networks + +If you're not an SS7 expert, and all you want is to run your own small +self-contained cellular network, this section explains what you need +to do. + +In general, you can consider OsmoSTP as something like an IP router. +On the application layer (in our case the BSSAP/BSSMAP or RANAP +protocols between Radio Access Network and Core Network), it is +completely invisible/transparent. The BSC connects via SCCP to the +MSC. It doesn't know that there's an STP in between, and that this +STP is performing some routing function. Compares this to your web +browser not knowing about IP routers, it just establishes an http +connection to a web server. + +This is also why most GSM nework architecture diagrams will not +explicitly show an STP. It is not part of the cellular network. +Rather, one or many STPs are part of the underlying SS7 signaling +transport network, on top of which the cellular network elements are +built. + +==== A minimal 2G configuration to get started + +You will be running the following programs: + +* OsmoBSC as the base-station controller between your BTS (possibly + running OsmoBTS) and the MSC +* OsmoMSC as the mobile switching center providing SMS and telephony + service to your subscribers +* OsmoSTP as the signal transfer point, routing messages between one + or more BSCs and the MSC + +[[fig-sigtran-simple-2g]] +.Simple signaling network for 2G (GSM) +[graphviz] +---- +include::sigtran-simple-2g.dot[] +---- + +You can use the OsmoSTP fully dynamic registration feature, so the BSCs +and the MSC will simply register with their point codes to the STP, +and the STP will create most configuration on the fly. + +All you need to make sure is: + +* to assign one unique point code to each BSC and MSC +* to point all BSCs and the MSC to connect to the IP+Port of the STP +* to configure the point code of the MSC in the BSCs + +==== A minimaal 3G configuration to get started + +You will be running the following programs: + +* OsmoHNBGW as the homeNodeB Gateway between your femtocells / small + cells and the MSC+SGSN +* OsmoMSC as the mobile switching center providing SMS and telephony + service to your subscribers +* OsmoSGSN as the Serving GPRS Support Node, providing packet data + (internet) services to your subscribers +* OsmoSTP as the signal transfer point, routing messages between one + or more HNBGWs and the MSC and SGSN + +[[fig-sigtran-simple-3g]] +.Simple signaling network for 3G (UMTS) +[graphviz] +---- +include::sigtran-simple-3g.dot[] +---- + +You can use the OsmoSTP fully dynamic registration feature, so the +HNBGWs, the SMC and the SGSNwill simply register with their point +codes to the STP, and the STP will create most configuration on the +fly. + +All you need to make sure is: + +* to assign one unique point code to each HNBGW, MSC and SGSN +* to point all HNBGWs and the MSC and SGSN to connect to the IP+Port of STP +* to configure the point code of the MSC in the HNBGWs +* to configure the point code of the SGSN in the HNBGWs + +=== Osmocom SS7 Instances + +The entire SS7 stack can be operated multiple times within one +application/program by means of so-called SS7 Instances. + +There can be any number of SS7 Instances, and each instance has its +own set of XUA Servers, ASPs, ASs, Routes, etc. + +Each SS7 Instance can have different point code formats / lengths. + +.Major Attributes of an Osmocom SS7 Instance +[options="header",cols="25%,35%,40%"] +|==== +|Name|VTY Command|Description +|ID|(config)# cs7 instance ID|The numeric identifier of this instance +|Name|(config-cs7)# name NAME|A human-readable name for this instance +|Description|(cnfig-cs7)# description DESC| More verbose description +|Primary PC|(config-cs7)# point-code PC|Primary local point code +|Network Indicator|(config-cs7)# network-indicator|Network Indicator used in MTP3 Routing Label +|Point Code Format|(config-cs7)# point-code format|Point Code Format (Default: 3.8.3) +|Point Code Delimiter|(config-cs7)# point-code delimiter|Point Code Delimiter: . or - +|==== + +=== Osmocom SS7 xUA Server + +A *xUA Server* is a server that binds + listens to a given SCTP +(SIGTRAN) or TCP (IPA) port and accepts connections from remote peers +(ASPs). + +There can be any number of xUA Servers within one SS7 Instance, as +long as they all run on a different combination of IP address and +port. + +.Major Attributes of an Osmocom SS7 xUA Server +[options="header",cols="25%,75%"] +|==== +|Name|Description +|Local IP|Local Port Number to which the server shall bind/listen +|Local Port|Local IP Address to which the server shall bind/listen +|Protocol|Protocol (M3UA, SUA, IPA) to be operated by this server +|Accept Dynamic ASPs|Should we accept connections from ASPs that are not explicitly pre-configured with their source IP and port? +|==== + + +=== Osmocom SS7 Users + +A SS7 User is part of a program that binds to a given MTP-Layer +Service Indicator (SI). The Osmocom SS7 stack offers an API to +register SS7 Users, as well as the VTY command ``show cs7 instance +<0-15> users'' to list the currently registered users. + +=== Osmocom SS7 Links + +TBD. + +=== Osmocom SS7 Linksets + +TBD. + +=== Osmocom SS7 Application Servers + +This corresponds 1:1 to the SIGTRAN concept of an Application Server, +i.e. a given external Application that interfaces the SS7 network via +a SS7 protocol variant such as M3UA. + +In the context of Osmocom, for each program connecting to a STP (like +a BSC or MSC), you will have one Application Server definition. + +An AS has the following properties: + +.Major Attributes of an Osmocom SS7 Application Server +[options="header",cols="25%,75%"] +|==== +|Name|Description +|Name|A human-readable name for this instance +|Description|More verbose description (for human user only) +|Protocol|Protocol (M3UA, SUA, IPA) to be operated by this server +|Routing Key|Routing Key (mostly Point Code) routed to this AS +|Traffic Mode|Theoretically Bradcast, Load-Balance. Currently only Ovverride +|Recovery Timeout|Duration of the AS T(r) recovery timer. During this time, + outgoing messages are queued. If the AS is ACTIVE + before timer expiration, the queue is drained. At + expriation, the queue is flushed. +|State|Application Server State (Down, Inactive, Active, Pending) +|ASPs|Which ASPs are permitted to transfer traffic for this AS +|==== + +=== Osmocom SS7 Application Server Processes + +An Application Server Process corresponds to a given SCTP (or TCP) +connection. From the STP/SG (Server) point-of-view, those are +incoming connections from Application Servers such as the BSCs. From +the ASP (Client) Point of view, it has one ``osmo_ss7_asp'' object for +each outbound SIGTARN connection. + +An ASP has the following properties: + +.Major Attributes of an Osmocom SS7 Application Server Process +[options="header",cols="25%,75%"] +|==== +|Name|Description +|Name|A human-readable name for this instance +|Description|More verbose description (for human user only) +|Protocol|Protocol (M3UA, SUA, IPA) to be operated by this server +|Role|Server (SG) or Client (ASP)? +|Local Port|Port Number of the local end of the connection +|Local IP|IP Address of the local end of the connection +|Remote Port|Port Number of the remote end of the connection +|Remote IP|IP Address of the remote end of the connection +|State|ASP State (Down, Inactive, Active) +|==== + +=== Osmocom SS7 Routes + +An Osmocom SS7 Route routes traffic with a matching destination point +code and point code mask (similar to IP Address + Netmask) towards a +specified SS7 Linkset or Application Server. The Linkset or +Application Servers are identified by their name. + +.Major Attributes of an Osmocom SS7 Application Server Process +[options="header",cols="25%,75%"] +|==== +|Name|Description +|Point Code|Destination Point Code for this route +|Mask|Destination Mask for this route (like an IP netmask) +|Linkset/AS Name|Destination Linkset or AS, identified by name +|==== + + +=== Osmocom SCCP Instances + +An Osmocom SS7 Instance can be bound to an Osmocom SS7 Instance. It +will register/bind for the ITU-standard Service Indicator (SI). + +=== Osmocom SCCP User + +An Program (like a BSC) will _bind_ itself to a given well-known +sub-system number (SSN) in order to receive SCCP messages destined for +this SSN. + +There is an API to bind a program to a SSN, which implicitly generates +an SCCP User object. + +The ``show cs7 instance <0-15> sccp users'' command can be used on the +VTY to obtain a list of currently bound SCCP users, as well as their +corresponding SSNs. + +=== Osmocom SCCP Connection + +This is how Osmocom represents each individual connection of +connection-oriented SCCP. + +To illustrate the practical applicaiton: For the common use case of +the A or Iu interfaces, this means that every dedicated radio channel +that is currently active to any UE/MS has one SCCP connection to the +MSC and/or SGSN. + +The ``show cs7 instance <0-15> sccp connections'' command can be used +on the VTY to obtain a list of currently active SCCP connections, as +well as their source/destination and current state. + + +=== Osmocom SCCP User SAP + +The Osmocom SCCP User SAP (Service Access Point) is the programming +interface between the SCCP Provider (libosmo-sigtran) and the SCCP +User. It follows primitives as laid out in <>, encapsulated +in ``osmo_prim'' structures. + +=== Osmocom MTP User SAP + +The Osmocom MTP User SAP (Service Access Point) is the programming +interface betwen the MTP Provider and the MTP User (e.g. SCCP). It +follows primitives as laid out in <>, encapsulated in +``osmo_prim'' structures. diff --git a/common/chapters/sigtran-simple-2g.dot b/common/chapters/sigtran-simple-2g.dot new file mode 100644 index 0000000..28098fd --- /dev/null +++ b/common/chapters/sigtran-simple-2g.dot @@ -0,0 +1,22 @@ +digraph G { + rankdir=LR; + MS0 [label="MS"]; + MS1 [label="MS"]; + MS2 [label="MS"]; + MS3 [label="MS"]; + BTS0 [label="BTS"]; + BTS1 [label="BTS"]; + BSC [label="OsmoBSC"]; + MSC [label="OsmoMSC"]; + STP [label="OsmoSTP"]; + + MS0 -> BTS0; + MS1 -> BTS0; + MS2 -> BTS1; + MS3 -> BTS1; + BTS0 -> BSC [label="Abis/IP"]; + BTS1 -> BSC [label="Abis/IP"]; + BSC -> STP [label="SCCP/M3UA"]; + STP -> MSC [label="SCCP/M3UA", dir="back"]; +} + diff --git a/common/chapters/sigtran-simple-3g.dot b/common/chapters/sigtran-simple-3g.dot new file mode 100644 index 0000000..eac363d --- /dev/null +++ b/common/chapters/sigtran-simple-3g.dot @@ -0,0 +1,24 @@ +digraph G { + rankdir=LR; + UE0 [label="UE"]; + UE1 [label="UE"]; + UE2 [label="UE"]; + UE3 [label="UE"]; + HNB0 [label="hNodeB"]; + HNB1 [label="hNodeB"]; + HNBGW [label="OsmoHNBGW"]; + MSC [label="OsmoMSC"]; + SGSN [label="OsmoSGSN"]; + STP [label="OsmoSTP"]; + + UE0 -> HNB0; + UE1 -> HNB0; + UE2 -> HNB1; + UE3 -> HNB1; + HNB0 -> HNBGW [label="Iuh (RUA)"]; + HNB1 -> HNBGW [label="Iuh (RUA)"]; + HNBGW -> STP [label="Iu (SCCP/M3UA)"]; + STP -> MSC [label="Iu (SCCP/M3UA)", dir="back"]; + STP -> SGSN [label="Iu (SCCP/M3UA)", dir="back"]; +} + diff --git a/common/chapters/sigtran.adoc b/common/chapters/sigtran.adoc new file mode 100644 index 0000000..9d8e42e --- /dev/null +++ b/common/chapters/sigtran.adoc @@ -0,0 +1,330 @@ +== Signaling Networks: SS7 and SIGTRAN + +Classic digital telephony networks (whether wired or wireless) use the +ITU-T SS7 (Signaling System 7) to exchange signaling information +between network elements. + +Most of the ETIS/3GPP interfaces in the GSM and UMTS network are also +based on top of [parts of] SS7. This includes, among others, the +following interfaces: + +* _A_ interface between BSC and MSC +* _IuCS_ interface between RNC (or HNB-GW) and MSC +* _IuPS_ interface between RNC (or HNB-GW) and SGSN + +NOTE:: This does not include the A-bis interface between BTS and BSC. +While Abis traditionally is spoken over the same physical TDM circuits +as SS7, the protocol stack from L2 upwars is quite different (Abis +uses LAPD, while SS7 uses MTP)! + +=== Physical Layer + +The traditional physical layer of SS7 is based on TDM (time division +multiplex) links of the PDH/SDH family, as they were common in ISDN +networks. Some people may know their smallest incarnation as +so-called E1/T1 links. It can run either on individual 64kBps +timeslots of such a link, or on entire 2Mbps/1.5MBps E1/T1 links. + +There are also specifications for SS7 over ATM, though it is unclear +to the author if this is actually still used anywhere. + +On top of the Physical Layer is the Message Transfer Part (MTP). + +=== Message Transfer Part (MTP) + +MTP is the lower layer of the SS7 protocol stack. It is comprised of +two sub-layes, called MTP2 and MTP3. + +Nodes in a MTP network are addressed by their unique PC (Point Code). + +A _MTP Routing Label_ is in the MTP header and indicates the +_Originationg Point Code_ (OPC) as well as the _Destination Point +Code_ (DPC) and the _Service Indicator Octet_ (SIO). The SIO is used +to de-multiplex between different upper-layer protocol such as ISUP, +TUP or SCCP. + +Routing is performed by means of routers with routing tables, similar +to routing is performed in IP networks. Even the concept of a _point +code mask_ analogous to the _netmask_ exists. + +Routers are connected with one another over one or more _Link Sets_, +each comprised of one or multiple _Links_. Multiple Links in a +Linkset exist both for load sharing as well as for fail over purposes. + +==== Point Codes + +The length of point codes depends on the particular MTP dialect that +is used. In the 1980ies, when international telephony signaling +networks were established, most countries had their own national +dialects with certain specifics. + +Today, mostly the ITU and ANSI variants survive. The ITU variant uses +14bit point codes, while the ANSI variant uses 24 bit point code +length. + +Point Codes can be represented either as unsigned integers, or +grouped. Unfortunately there is no standard as to their +representation. In ITU networks, the _3.8.3_ notation is commonly +used, i.e. one decimal for the first 3 bits, followed by one decimal +for the center 8 bits, followed by another decimal for the final 3 +bits. + +Example:: The Point Code *1.5.3* (in 3.8.3 notation) is 1*2^11^ + 5*2^3^ + 3 = *2091 decimal*. + +=== Higher-Layer Protocols + +There are various higher-layer protocols used on top of MTP3, such as +TUP, ISUP, BICC as well as SCCP. Those protocols exist side-by-side +on top of MTP3, similar to e.g. ICMP, TCP and UDP existing +side-by-side on top of IP. + +In the context of cellular networks, SCCP is the most relevant part. + +=== Signaling Connection Control Part (SCCP) + +SCCP runs on top of MTP3 and creates something like an overlay network +on top of it. SCCP communication can e.g. span multiple different +isolated MTP networks, each with their own MTP dialect and addressing. + +SCCP provides both connectionless (datagram) and connection-oriented +services. Both are used in the context of cellular networks. + +==== SCCP Adresses + +SCCP Adresses are quite complex. This is due to the fact that it is +not simply one address format, but in fact a choice of one or multiple +different types of addresses. + +SCCP Addresses exist as _Calling Party_ and _Called Party_ addresses. +In the context of connectionless datagram services, the sender is +always the Calling Party, and the receiver the Called Party. In +connection-oriented SCCP, they resemble the initiator and recipient of +the connection. + +.SCCP Address Parts +[options="header",cols="10%,20%,70%"] +|==== +|Acronym|Name|Description +|SSN|Sub-System Number|Describes a given application such as e.g. a + GSM MSC, BSC or HLR. Can be compared to port + numbers on the Internet +|PC|Point Code |The Point Code of the underlying MTP network +|GT|Global Title |What most people would call a "phone number". + However, Global Titles come in many different + numbering plans, and only one of them (E.164) + resembles actual phone numbers. +|RI|Routing Indicator |Determines if message shall be routed on PC+SSN + or on GT basis +|==== + +==== Global Titles + +A Global Title is a (typically) globally unique address in the global +telephony network. The body of the Global Title consists of a series +of BCD-encoded digits similar to what everyone knows as phone numbers. + +A GT is however not only the digits of the "phone number", but also +some other equally important information, such as the _Numbering Plan_ +as well as the _Nature of Address Indication_. + +.Global Title Parts +[options="header",cols="10%,20%,70%"] +|==== +|Acronym|Name|Description +|GTI|Global Title Indicator|Determines the GT Format. Ranges from no + GT (0) to GT+TT+NP+ES+NAI (4) +|NAI|Nature of Address Indicator|Exists in GTI=1 and is sort of a mixture of TON + NPI +|TT|Translation Type |Used as a look-up key in Global Title Translation Tables +|NP|Numbering Plan |Indicates ITU Numbering Plan, such as E.164, E.212, E.214 +|ES|Encoding Scheme |Just a peculiar way to idicate the length of the digits +|- |Signals |The actual "phone number digits" +|==== + +For more information about SCCP Adresses and Global Titles, please +refer to <> + + +==== Global Title Translation (GTT) + +Global Title Translation is a process of re-writing the Global Title +on-the-fly while a signaling message passes a STP. + +Basically, a SCCP message is first transported by MTP3 on the MTP +level to the Destination Point Code indicated in the MTP Routing +Label. This process uses MTP routing and is transparent to SCCP. + +Once the SCCP message arrives at the MTP End-Node identified by the +Destination Point Code, the message is handed up to the local SCCP +stack, which then may implement Global Title Translation. + +The input to the GTT process is +* the destination address of the SCCP message +* a local list/database of Global Title Translation Rules + +The successful output of he GTT includes +* A new Routing Indicator +* The Destination Point Code to which the message is forwarded on MTP + level +* a Sub-system Number (if RI is set to "Route on SSN") +* a new Global Title (if RI is set to "Route on GT"), e.g. with translated digits. + +Between sender and recipient of a signaling message, there can be many +instances of Global Title Translation (up to 15 as per the hop +counter). + +For more information on Global Title Translation, please refer to +<>. + + +==== Peculiarities of Connection Oriented SCCP + +Interestingly, Connection-Oriented SCCP messages carry SCCP Adresses +*only during connection establishment*. All data messages during +an ongoing connection do not contain a Called or Calling Party +Address. Instead, they are routed only by the MTP label, which is +constructed from point code information saved at the time the +connection is established. + +This means that connection-oriented SCCP can not be routed across MTP +network boundaries the same way as connectionless SCCP messages. +Instead, an STP would have to perform _connection coupling_, whic is +basically the equivalent of an application-level proxy between two +SCCP connections, each over one of the two MTP networks. + +This is probably mostly of theoretical relevance, as +connection-oriented SCCP is primarily used betwen RAN and CN of +cellular network inside one operator, i.e. not across multiple MTP +networks. + +=== SIGTRAN - SS7 over IP Networks + +At some point, IP based networks became more dominant than classic +ISDN networks, and 3GPP as well as IETF were working out methods in +which telecom signaling traffic can be adapted over IP based +networks. + +Initially, only the edge of the network (i.e. the applications talking +to the network, such as HLR or MSC) were attached to the existing old +SS7 backbone by means as SUA and M3UA. Over time, even the links of +the actual network backbone networks became more and more IP based. + +In order to replace existing TDM-based SS7 links/liksets with SIGTRAN, +the M2UA or M2PA variants are used as a kind of drop-in replacement +for physical links. + +All SIGTRAN share that while they use IP, they don't use TCP or UDP +but operate over a (then) newly-introduced Layer 4 transport protocol +on top of IP: SCTP (Stream Control Transmission Protocol). + +Despite first being specified in October 2000 as IETF RFC 2960, it +took a long time until solid implementations of SCTP ended up in +general-purpose operating systems. SCTP is not used much outside the +context of SIGTAN, which means implementations often suffer from bugs, +and many parts of the public Internet do not carry SCTP traffic due to +restrictive firewalls and/or ignorant network administrators. + +==== SIGTRAN Concepts / Terminology + +Like every protocol or technologoy, SIGTRAN brings with it its own +terminologyand concepts. This section tries to briefly introduce +them. For more information, please see the related IETF RFCs. + +===== Signaling Gateway (SG) + +The Signaling Gateway (SG) interconnects the SS7 network wit external +applications. It translates (parts of) the SS7 protocol stack into an +IP based SIGTRAN protocol stack. Which parts at whcih level of the +protocol stack are translated to what depends on the specific SIGTRAN +dialect. + +A SG is traditionally attached to the TDM-Based SS7 network and offers +SIGTRAN/IP based applications a way to remotely attach to the SS7 +network. + +A SG typically has STP functionality built-in, but it is not +mandatory. + +===== Application Server (AS) + +An Application Server is basically a logical entity representing one +particular external application (from the SS7 point of view) which is +interfaced with the SS7 network by means of one of the SIGTRAN +protocols. + +An Application Server can have one or more Application Server Processes +associated with it. This functionality (currently not implemented in +Osmocom) can be used for load-balancing or fail-over scenarios. + +===== Application Server Process (ASP) + +An Application Server Process represents one particular SCTP +connection used for SIGTRAN signaling between an external application +(e.g. a BSC) and the Signaling Gateway (SG). + +One Application Server Process can route traffic for multiple +Application Servers. In order to differentiate traffic for different +Application Servers, the Routing Context header is used. + +==== SIGTRAN variants / stackings + +SIGTRAN is the name of an IETF working group, which has released an +entire group of different protocol specifications. So rather than one +way of transporting classic telecom signaling over IP, there are now +half a dozen different ones, and all can claim to be an official IETF +standard. + +FIXME: Overview picture comparing the different stackings + +===== MTP3 User Adaptation (M3UA) + +M3UA basically "chops off" everything up to and including the MTP3 +protocol layer of the SS7 protocol stack and replaces it with a stack +comprised of M3UA over SCTP over IP. + +M3UA is specified in <>. + +===== SCCP User Adaptation (SUA) + +SUA basically "chops off" everything up to and including the SCCP +protocol layer of the SS7 protocol stack and replaces it with a stack +comprised of SUA over SCTP over IP. + +This means that SUA can only be used for SCCP based signaling, but not +for other SS7 protocols like e.g. TUP and ISUP. + +SUA is specified in <>. + +===== MTP2 User Adaptation (M2UA) + +M2UA is specified in <>. + +NOTE:: M2UA is not supported in Osmocom SIGTRAN up to this point. Let +us know if we can implement it for you! + +===== MTP2-User Peer-to-Peer Adaptation (M2PA) + +M2PA is specified in <>. + +NOTE:: M2PA is not supported in Osmocom SIGTRAN up to this point. Let +us know if we can implement it for you! + + +==== SIGTRAN security + +There simply is none. There are some hints that TLS shall be used +over SCTP in order to provide authenticity and/or confidentiality for +SIGTRAN, but this is not widely used. + +As telecom signaling is not generally carried over public networks, +private networks/links by means of MPLS, VLANs or VPNs such as IPsec +are often used to isolate and/or secure SIGTRAN. + +Under no circumstances should you use unsecured SIGTRAN with +production data over the public internet! + +==== IPv6 support + +SCTP (and thus all the higher layer protocols of the various SIGTRAN +stackings) operates on top of both IPv4 and IPv6. As the entire +underlying IP transport is transparent to the SS7/SCCP applcations, +there is no restriction on whether to use SIGTRAN over IPv4 or IPv6. -- To view, visit https://gerrit.osmocom.org/2371 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I450bfac7444ac9cb7f50c086d87cf7157c2e2a31 Gerrit-PatchSet: 1 Gerrit-Project: osmo-gsm-manuals Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Sun Apr 16 01:28:45 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 16 Apr 2017 01:28:45 +0000 Subject: [PATCH] osmo-gsm-manuals[master]: First step towards an OsmoSTP manual In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2371 to look at the new patch set (#2). First step towards an OsmoSTP manual Change-Id: I450bfac7444ac9cb7f50c086d87cf7157c2e2a31 --- M Makefile A OsmoSTP/Makefile A OsmoSTP/osmostp-usermanual-docinfo.xml A OsmoSTP/osmostp-usermanual.adoc A OsmoSTP/osmostp-vty-reference.xml A OsmoSTP/vty/stp_vty_reference.xml M common/chapters/bibliography.adoc M common/chapters/glossary.adoc A common/chapters/sigtran-osmocom.adoc A common/chapters/sigtran-simple-2g.dot A common/chapters/sigtran-simple-3g.dot A common/chapters/sigtran.adoc 12 files changed, 1,019 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-gsm-manuals refs/changes/71/2371/2 diff --git a/Makefile b/Makefile index 035595c..ed0c894 100644 --- a/Makefile +++ b/Makefile @@ -6,6 +6,7 @@ cd OsmoSGSN; $(MAKE) cd OsmoNAT; $(MAKE) cd OsmoPCU; $(MAKE) + cd OsmoSTP; $(MAKE) clean: cd OsmoBTS; $(MAKE) clean @@ -15,6 +16,7 @@ cd OsmoSGSN; $(MAKE) clean cd OsmoNAT; $(MAKE) clean cd OsmoPCU; $(MAKE) clean + cd OsmoSTP; $(MAKE) clean upload: cd OsmoBTS; $(MAKE) upload @@ -24,6 +26,7 @@ cd OsmoSGSN; $(MAKE) upload cd OsmoNAT; $(MAKE) upload cd OsmoPCU; $(MAKE) upload + cd OsmoSTP; $(MAKE) upload check: cd OsmoBTS; $(MAKE) check @@ -31,6 +34,7 @@ cd OsmoBSC; $(MAKE) check cd OsmoSGSN; $(MAKE) check cd OsmoPCU; $(MAKE) check + cd OsmoSTP; $(MAKE) check # These don't use asciidoc, so they have no 'make check' target: #cd OsmoMGCP; $(MAKE) check #cd OsmoNAT; $(MAKE) check diff --git a/OsmoSTP/Makefile b/OsmoSTP/Makefile new file mode 100644 index 0000000..bf3ba8f --- /dev/null +++ b/OsmoSTP/Makefile @@ -0,0 +1,45 @@ +# XSL stylesheets downloaded from http://docbook.sourceforge.net/release/xsl/current/html/ +# Makefile from BitBake/OpenEmbedded manuals + + +EXTRA_DEPS = gen-stp-vty-docbook + +topdir = . +stp_reference = $(topdir)/osmostp-vty-reference.xml +manuals = $(stp_reference) +# types = pdf txt rtf ps xhtml html man tex texi dvi +# types = pdf txt +types = $(docbooktotypes) +docbooktotypes = pdf +# htmlcssfile = +# htmlcss = + +TOPDIR := .. +ASCIIDOCS := osmostp-usermanual + +include $(TOPDIR)/build/Makefile.asciidoc.inc +include $(TOPDIR)/build/Makefile.inc + +osmostp-usermanual.pdf: chapters/*.adoc + +clean: + -rm -rf $(cleanfiles) + -rm osmostp-usermanual__*.png + -rm osmostp-usermanual__*.svg + -rm osmostp-usermanual*.check + +gen-stp-vty-docbook: FORCE + $(call command,xsltproc -o generated/combined1.xml \ + --stringparam with $(PWD)/../common/vty_additions.xml \ + $(MERGE_DOC) vty/stp_vty_reference.xml, \ + XSLTPROC,Merging Common VTY) + $(call command,xsltproc -o generated/combined2.xml \ + --stringparam with $(PWD)/../common/stp_vty_additions.xml \ + $(MERGE_DOC) generated/combined1.xml, \ + XSLTPROC,Merging Common STP VTY) + $(call command,xsltproc -o generated/combined3.xml \ + --stringparam with $(PWD)/vty/stp_vty_additions.xml \ + $(MERGE_DOC) generated/combined2.xml, \ + XSLTPROC,Merging STP VTY) + $(call command,xsltproc ../vty_reference.xsl generated/combined3.xml > generated/docbook_vty.xml, \ + XSLTPROC,Converting STP VTY to DocBook) diff --git a/OsmoSTP/osmostp-usermanual-docinfo.xml b/OsmoSTP/osmostp-usermanual-docinfo.xml new file mode 100644 index 0000000..4253957 --- /dev/null +++ b/OsmoSTP/osmostp-usermanual-docinfo.xml @@ -0,0 +1,47 @@ + + + 1 + April 16, 2017 + HW + + Initial OsmoSTP manual + + + + + + + Harald + Welte + hwelte at sysmocom.de + HW + + sysmocom + sysmocom - s.f.m.c. GmbH + Managing Director + + + + + + 2012-2017 + sysmocom - s.f.m.c. GmbH + + + + + Permission is granted to copy, distribute and/or modify this + document under the terms of the GNU Free Documentation License, + Version 1.3 or any later version published by the Free Software + Foundation; with the Invariant Sections being just 'Foreword', + 'Acknowledgements' and 'Preface', with no Front-Cover Texts, + and no Back-Cover Texts. A copy of the license is included in + the section entitled "GNU Free Documentation License". + + + The Asciidoc source code of this manual can be found at + + http://git.osmocom.org/osmo-gsm-manuals/ + + + diff --git a/OsmoSTP/osmostp-usermanual.adoc b/OsmoSTP/osmostp-usermanual.adoc new file mode 100644 index 0000000..2be3372 --- /dev/null +++ b/OsmoSTP/osmostp-usermanual.adoc @@ -0,0 +1,33 @@ +OsmoSTP User Manual +=================== +Harald Welte + + +include::../common/chapters/preface.adoc[] + +// include::chapters/overview.adoc[] + +include::../common/chapters/sigtran.adoc[] +include::../common/chapters/sigtran-osmocom.adoc[] + +//include::chapters/running.adoc[] +// include::chapters/control.adoc[] + +include::../common/chapters/vty.adoc[] + +include::../common/chapters/logging.adoc[] + +//include::../common/chapters/bts.adoc[] + +//include::../OsmoNITB/chapters/bts-examples.adoc[] + +//include::../common/chapters/control_if.adoc[] + +include::../common/chapters/port_numbers.adoc[] + +include::../common/chapters/bibliography.adoc[] + +include::../common/chapters/glossary.adoc[] + +include::../common/chapters/gfdl.adoc[] + diff --git a/OsmoSTP/osmostp-vty-reference.xml b/OsmoSTP/osmostp-vty-reference.xml new file mode 100644 index 0000000..807d427 --- /dev/null +++ b/OsmoSTP/osmostp-vty-reference.xml @@ -0,0 +1,38 @@ + + + + +]> + + + + + + v1 + April 16, 2017 + h2 + Initial + + + + OsmoSTP VTY Reference + + + 2012-2017 + + + + This work is copyright by sysmocom - s.f.m.c. GmbH. All rights reserved. + + + + + + &chapter-vty; + + diff --git a/OsmoSTP/vty/stp_vty_reference.xml b/OsmoSTP/vty/stp_vty_reference.xml new file mode 100644 index 0000000..a4c675e --- /dev/null +++ b/OsmoSTP/vty/stp_vty_reference.xml @@ -0,0 +1,2 @@ + + diff --git a/common/chapters/bibliography.adoc b/common/chapters/bibliography.adoc index a3c6436..d5e1c1b 100644 --- a/common/chapters/bibliography.adoc +++ b/common/chapters/bibliography.adoc @@ -106,11 +106,29 @@ https://tools.ietf.org/html/rfc1350 - [[[ietf-rfc2131]]] IETF RFC 2131: Dynamic Host Configuration Protocol https://tools.ietf.org/html/rfc2131 +- [[[ietf-rfc2719]]] IETF RFC 2719: Signal Transport over IP + https://tools.ietf.org/html/rfc2719 +- [[[ietf-rfc3331]]] IETF RFC 3331: Message Transfer Part 2 User Adaptation Layer + https://tools.ietf.org/html/rfc3331 - [[[ietf-rfc3550]]] IETF RFC 3550: RTP: A Transport protocol for Real-Time Applications https://tools.ietf.org/html/rfc3550 +- [[[ietf-rfc3868]]] IETF RFC 3868: SCCP User Adaptation Layer + https://tools.ietf.org/html/rfc3868 +- [[[ietf-rfc4165]]] IETF RFC 4165: Message Transfer Part 2 Peer-to-Peeer Adaptation Layer + https://tools.ietf.org/html/rfc4165 - [[[ietf-rfc4251]]] IETF RFC 4251: The Secure Shell (SSH) Protocol Architecture https://tools.ietf.org/html/rfc4251 +- [[[ietf-rfc4666]]] IETF RFC 4666: Message Transfer Part 3 User Adaptation Layer + https://tools.ietf.org/html/rfc4666 +- [[[itu-t-q701]]] ITU-T Q.701: Functional Description of the Message Transfer Part (MTP) + https://www.itu.int/rec/T-REC-Q.701/en/ +- [[[itu-t-q711]]] ITU-T Q.711: Functional Description of the Signalling Connection Control Part + https://www.itu.int/rec/T-REC-Q.711/en/ +- [[[itu-t-q713]]] ITU-T Q.713: Signalling connection control part formats and codes + https://www.itu.int/rec/T-REC-Q.713/en/ +- [[[itu-t-q714]]] ITU-T Q.714: Signalling connection control part procedures + https://www.itu.int/rec/T-REC-Q.714/en/ - [[[itu-t-q921]]] ITU-T Q.921: ISDN user-network interface - Data link layer specification https://www.itu.int/rec/T-REC-Q.921/en diff --git a/common/chapters/glossary.adoc b/common/chapters/glossary.adoc index c39d439..042fd3a 100644 --- a/common/chapters/glossary.adoc +++ b/common/chapters/glossary.adoc @@ -115,6 +115,8 @@ GSMTAP:: GSM tap; pseudo standard for encapsulating GSM protocol layers over UDP/IP for analysis +GT:: + Global Title; an address in SCCP GTP:: GPRS Tunnel Protocol; used between SGSN and GGSN HLR:: @@ -143,6 +145,12 @@ 44.064_ <<3gpp-ts-44-064>>) Location Area:: Location Area; a geographic area containing multiple BTS +M2PA:: + MTP2 Peer-to-Peer Adaptation; a SIGTRAN Variant (_RFC 4165_ <>) +M2UA:: + MTP2 User Adaptation; a SIGTRAN Variant (_RFC 3331_ <>) +M3UA:: + MTP3 User Adaptation; a SIGTRAN Variant (_RFC 4666_ <>) MCC:: Mobile Country Code; unique identifier of a country, e.g. 262 for Germany MFF:: @@ -163,6 +171,8 @@ core network MSISDN:: Mobile Subscriber ISDN Number; telephone number of the subscriber +MTP:: + Message Transfer Part; SS7 signaling protocol (_ITU-T Q.701_ <>) MVNO:: Mobile Virtual Network Operator; Operator without physical radio network NCC:: @@ -206,6 +216,8 @@ OTA:: Over-The-Air; Capability of operators to remotely reconfigure/reprogram ISM/USIM cards +PC:: + Point Code; an address in MTP PCH:: Paging Channel on downlink Um interface; used by network to page an MS PCU:: @@ -249,11 +261,15 @@ SACCH:: Slow Associate Control Channel on Um interface; bundled to a TCH or SDCCH, used for signalling in parallel to active dedicated channel +SCCP:: + Signaling Connection Control Part; SS7 signaling protocol (_ITU-T Q.711_ <>) SDCCH:: Slow Dedicated Control Channel on Um interface; used for signalling and SMS transport in GSM SDK:: Software Development Kit +SIGTRAN:: + Signaling Transport over IP (_IETF RFC 2719_ <>) SIM:: Subscriber Identity Module; small chip card storing subscriber identity Site:: @@ -264,8 +280,16 @@ entities with an SMSC SMSC:: Short Message Service Center; store-and-forward relay for short messages +SS7:: + Signaling System No. 7; Classic digital telephony signaling system SSH:: Secure Shell; _IETF RFC 4250_ <> to 4254 +SSN:: + Sub-System Number; identifies a given SCCP Service such as MSC, HLR +STP:: + Signaling Transfer Point; A Router in SS7 Networks +SUA:: + SCCP User Adaptation; a SIGTRAN Variant (_RFC 3868_ <>) syslog:: System logging service of UNIX-like operating systems System Information:: diff --git a/common/chapters/sigtran-osmocom.adoc b/common/chapters/sigtran-osmocom.adoc new file mode 100644 index 0000000..1e08733 --- /dev/null +++ b/common/chapters/sigtran-osmocom.adoc @@ -0,0 +1,432 @@ +== Osmocom SS7 + SIGTRAN support + +=== History / Background + +If you're upgrading from earlier releases of the Osmocom stack, this +section will give you some background about the evolution. + +==== The Past (before 2017) + +In the original implementation of the GSM BSC inside Osmocom (the +OsmoBSC program, part of OpenBSC), no SS7 support was included. + +This is despite the fact that ETSI/3GPP mandated the use of SCCP over +MTP over E1/T1 TDM lines for the A interface at that time. + +Instead of going down to the TDM based legacy physical layers, OsmoBSC +implemented someting called an IPA multiplex, which apparently some +people also refer to as SCCPlite. We have never seen any +specifications for this interface, but implemented it from scratch +using protocol traces. + +The IPA protocol stack is based on a minimal sub-set of SCCP +(including connection oriented SCCP) wrapped into a 3-byte header to +packetize a TCP stream. + +The IPA/SCCPlite based A interface existed at a time when the +ETSI/3GPP specifications did not offer any IP based transport for the +A interface. An official as added only in Release FIXME of the 3GPP +specifications. + +The A interface BSSMAP protocol refers to voice circuits (E1/T1 +timeslots) using circuit identity codes (CICs). As there are no +physical timeslots on a TCP/IP based transport layer, the CICs get +mapped to RTP streams for circuit-switched data using out-of-band +signaling via MGCP, the IETF-standardized Media Gateway Control +Protocol. + +==== The present (2017) + +In 2017, sysmocom was tasked with implementing a 3GPP AoIP compliant A +interface. This meant that lot of things had to change in the +existing code: + +* removal of the existing hard-wired SCCPlite/IPA code from OsmoBSC +* introduction of a formal SCCP User SAP at the lower boundary of + BSSMAP +* introduction of libosmo-sigtran, a comprehensive SS7 and SIGTRAN + library which includes a SCCP implementation for connectionless and + connection-oriented procedures, offering the SCCP User SAP towards + BSSAP +* introduction of an A interface in OsmoMSC (which so far offered Iu + only) +* port of the existing SUA-baesd IuCS and IuPS over to the SCCP User + SAP of libosmo-sigtran. +* Implementation of ETSI M3UA as preferred/primary transport layer for + SCCP +* Implementation of an IPA transport layer inside libosmo-sigtran, in + order to keep backwards-compatibility. + +This work enables the Osmocom universe to become more compliant +with modern Releases of 3GPP specifications, which enables +interoperability with other MSCs or even BSCs. However, this comes at +a price: Increased complexity in set-up and configuration. + +Using SS7 or SIGTRAN based transport of the A interface adds an +entirely new domain that needs to be understood by system and network +administrators setting up cellular networks based on Osmocom. + +One of the key advantages of the Osmocom architecture with OsmoNITB +was exactly this simplification and reduction of complexity, enabling +more people to set-up and operate cellular networks. + +So we have put some thought into how we can achieve compatibility with +SS7/SIGTRAN and the 3GPP specifications, while at the same time +enabling some degree of auto-configuration where a small network can +be set up without too many configuration related to the signaling +network. We have achieved this by "abusing" (or extending) the M3UA +Routing Key Management slightly. + +=== Osmocom extensions to SIGTRAN + +Osmocom has implemented some extensions to the SIGTRAN protocol suite. +Those extensions will be documented below. + +==== Osmocom M3UA Routing Key Management Extensions + +In classic M3UA, a peer identifies its remote peer based on IP address +and port details. So once an ASP connects to an SG, the SG will check +if there is any configuration that matches the source IP (and possibly +source port) of that connection in order to understand which routing +context is used - and subsequently which traffic is to be routed to +this M3UA peer. + +This is quite inflexible, as it means that every BSC in a GSM network +needs to be manually pre-configured at the SG/STP, and that +configuration on the BSC and MSC must match to enable communication. + +M3UA specifies an optional Routing Key Management (RKM) sub-protocol. +Using RKM, an ASP can dynamically tell the SG/STP, which traffic it +wants to receive. However, the idea is still that the SG has some +matching configuration. + +In OsmoSTP based on libosmo-sigtran, we decided to (optionally) enable +fully dynamic registration. This means that any ASP can simply +connect to the SG and request the dynamic creation of an ASP and AS +with a corresponding routing key for a given point code. As long as +the SG doesn't already have a route to this requested point code, The +SG will simply trust any ASP and set a corresponding route. + +This is of course highly insecure and can only be used in trusted, +internal newtworks. However, it is quite elegant in reducing the +amount of configuration complexity. All that is needed, is that an +unique point code is configured at each of the ASPs (application +programs) that connect to the STP. + +To put things more concretely: Each BSC and MSC connecting to OsmoSTP +simply needs to be configured to have a different point code, and to +know to which IP/port of the STP to connect. There's no other +configuration required for a small, autonomous, self-contained +network. OsmoSTP will automatically insall ASP, AS and route +definitions on demand, and route messages between all connected +entities. + +The same above of course also applies to HNB-GW and OsmoSGSN in the +case of Iu interfaces. + +==== IPA / SCCPlite backwards compatibility + +The fundamental problem with IPA/SCCPlite is that there's no MTP +routing label surrounding the SCCP message. This is generally +problematic in the context of connection-oriented SCCP, as there is no +addressing information inside the SCCP messages after the connection +has been established. Instead, the messages are routed based on the +MTP label, containing point codes established during connection set-up +time. + +This means that even if the SCCP messages did contain Called/Calling +Party Addresses with point codes or global titles, it would only help +us for routing connectionless SCCP. The A interface, however, is +connection-oriented. + +So in order to integrate IPA/SCCPlite with a new full-blown +SS7/SIGTRAN stack, there are the following options: + +. implement SCCP connection coupling. This is something like a proxy + for connection-oriented SCCP, and is what is used in SS7 to route + beyond a given MTP netwokr (e.g. at gateways between different MTP + networks) + +. consider all SCCP messages to be destined for the local point code + of the receiver. This then means that the SG functionality must be + included inside the MSC, and the MSC be bound to the SSN on the + local point code. + +. hard-code some DPC when receiving a message from an IPA connection. + It could be any remote PC and we'd simply route the message towards + that point code. + +But then we also have the return direction: + +. We could "assign" a unique SPC to each connected IPA client (BSC), + and then announce that PC towards the SS7 side. Return packets + would then end up at our IPA-server-bearing STP, which forwards them + to the respective IPA connection and thus BSC. On the transmit + side, we'd simply strip the MTP routing label and send the raw SCCP + message over IPA. + +. If the IPA server / SGW resides within the MSC, one could also have + some kind of handle/reference to the specific TCP connection through + which the BSC connected. All responses for a given peer would then + have to be routed back to the same connection. This is quite ugly + as it completely breaks the concepts of the SCCP User SAP, where a + user has no information (nor to worry about ) any "physical" + signaling links. + + +=== Minimal Osmocom SIGTRAN configurations for small networks + +If you're not an SS7 expert, and all you want is to run your own small +self-contained cellular network, this section explains what you need +to do. + +In general, you can consider OsmoSTP as something like an IP router. +On the application layer (in our case the BSSAP/BSSMAP or RANAP +protocols between Radio Access Network and Core Network), it is +completely invisible/transparent. The BSC connects via SCCP to the +MSC. It doesn't know that there's an STP in between, and that this +STP is performing some routing function. Compares this to your web +browser not knowing about IP routers, it just establishes an http +connection to a web server. + +This is also why most GSM nework architecture diagrams will not +explicitly show an STP. It is not part of the cellular network. +Rather, one or many STPs are part of the underlying SS7 signaling +transport network, on top of which the cellular network elements are +built. + +==== A minimal 2G configuration to get started + +You will be running the following programs: + +* OsmoBSC as the base-station controller between your BTS (possibly + running OsmoBTS) and the MSC +* OsmoMSC as the mobile switching center providing SMS and telephony + service to your subscribers +* OsmoSTP as the signal transfer point, routing messages between one + or more BSCs and the MSC + +[[fig-sigtran-simple-2g]] +.Simple signaling network for 2G (GSM) +[graphviz] +---- +include::sigtran-simple-2g.dot[] +---- + +You can use the OsmoSTP fully dynamic registration feature, so the BSCs +and the MSC will simply register with their point codes to the STP, +and the STP will create most configuration on the fly. + +All you need to make sure is: + +* to assign one unique point code to each BSC and MSC +* to point all BSCs and the MSC to connect to the IP+Port of the STP +* to configure the point code of the MSC in the BSCs + +==== A minimaal 3G configuration to get started + +You will be running the following programs: + +* OsmoHNBGW as the homeNodeB Gateway between your femtocells / small + cells and the MSC+SGSN +* OsmoMSC as the mobile switching center providing SMS and telephony + service to your subscribers +* OsmoSGSN as the Serving GPRS Support Node, providing packet data + (internet) services to your subscribers +* OsmoSTP as the signal transfer point, routing messages between one + or more HNBGWs and the MSC and SGSN + +[[fig-sigtran-simple-3g]] +.Simple signaling network for 3G (UMTS) +[graphviz] +---- +include::sigtran-simple-3g.dot[] +---- + +You can use the OsmoSTP fully dynamic registration feature, so the +HNBGWs, the SMC and the SGSNwill simply register with their point +codes to the STP, and the STP will create most configuration on the +fly. + +All you need to make sure is: + +* to assign one unique point code to each HNBGW, MSC and SGSN +* to point all HNBGWs and the MSC and SGSN to connect to the IP+Port of STP +* to configure the point code of the MSC in the HNBGWs +* to configure the point code of the SGSN in the HNBGWs + +=== Osmocom SS7 Instances + +The entire SS7 stack can be operated multiple times within one +application/program by means of so-called SS7 Instances. + +There can be any number of SS7 Instances, and each instance has its +own set of XUA Servers, ASPs, ASs, Routes, etc. + +Each SS7 Instance can have different point code formats / lengths. + +.Major Attributes of an Osmocom SS7 Instance +[options="header",cols="25%,35%,40%"] +|==== +|Name|VTY Command|Description +|ID|(config)# cs7 instance ID|The numeric identifier of this instance +|Name|(config-cs7)# name NAME|A human-readable name for this instance +|Description|(cnfig-cs7)# description DESC| More verbose description +|Primary PC|(config-cs7)# point-code PC|Primary local point code +|Network Indicator|(config-cs7)# network-indicator|Network Indicator used in MTP3 Routing Label +|Point Code Format|(config-cs7)# point-code format|Point Code Format (Default: 3.8.3) +|Point Code Delimiter|(config-cs7)# point-code delimiter|Point Code Delimiter: . or - +|==== + +=== Osmocom SS7 xUA Server + +A *xUA Server* is a server that binds + listens to a given SCTP +(SIGTRAN) or TCP (IPA) port and accepts connections from remote peers +(ASPs). + +There can be any number of xUA Servers within one SS7 Instance, as +long as they all run on a different combination of IP address and +port. + +.Major Attributes of an Osmocom SS7 xUA Server +[options="header",cols="25%,75%"] +|==== +|Name|Description +|Local IP|Local Port Number to which the server shall bind/listen +|Local Port|Local IP Address to which the server shall bind/listen +|Protocol|Protocol (M3UA, SUA, IPA) to be operated by this server +|Accept Dynamic ASPs|Should we accept connections from ASPs that are not explicitly pre-configured with their source IP and port? +|==== + + +=== Osmocom SS7 Users + +A SS7 User is part of a program that binds to a given MTP-Layer +Service Indicator (SI). The Osmocom SS7 stack offers an API to +register SS7 Users, as well as the VTY command ``show cs7 instance +<0-15> users'' to list the currently registered users. + +=== Osmocom SS7 Links + +TBD. + +=== Osmocom SS7 Linksets + +TBD. + +=== Osmocom SS7 Application Servers + +This corresponds 1:1 to the SIGTRAN concept of an Application Server, +i.e. a given external Application that interfaces the SS7 network via +a SS7 protocol variant such as M3UA. + +In the context of Osmocom, for each program connecting to a STP (like +a BSC or MSC), you will have one Application Server definition. + +An AS has the following properties: + +.Major Attributes of an Osmocom SS7 Application Server +[options="header",cols="25%,75%"] +|==== +|Name|Description +|Name|A human-readable name for this instance +|Description|More verbose description (for human user only) +|Protocol|Protocol (M3UA, SUA, IPA) to be operated by this server +|Routing Key|Routing Key (mostly Point Code) routed to this AS +|Traffic Mode|Theoretically Bradcast, Load-Balance. Currently only Ovverride +|Recovery Timeout|Duration of the AS T(r) recovery timer. During this time, + outgoing messages are queued. If the AS is ACTIVE + before timer expiration, the queue is drained. At + expriation, the queue is flushed. +|State|Application Server State (Down, Inactive, Active, Pending) +|ASPs|Which ASPs are permitted to transfer traffic for this AS +|==== + +=== Osmocom SS7 Application Server Processes + +An Application Server Process corresponds to a given SCTP (or TCP) +connection. From the STP/SG (Server) point-of-view, those are +incoming connections from Application Servers such as the BSCs. From +the ASP (Client) Point of view, it has one ``osmo_ss7_asp'' object for +each outbound SIGTARN connection. + +An ASP has the following properties: + +.Major Attributes of an Osmocom SS7 Application Server Process +[options="header",cols="25%,75%"] +|==== +|Name|Description +|Name|A human-readable name for this instance +|Description|More verbose description (for human user only) +|Protocol|Protocol (M3UA, SUA, IPA) to be operated by this server +|Role|Server (SG) or Client (ASP)? +|Local Port|Port Number of the local end of the connection +|Local IP|IP Address of the local end of the connection +|Remote Port|Port Number of the remote end of the connection +|Remote IP|IP Address of the remote end of the connection +|State|ASP State (Down, Inactive, Active) +|==== + +=== Osmocom SS7 Routes + +An Osmocom SS7 Route routes traffic with a matching destination point +code and point code mask (similar to IP Address + Netmask) towards a +specified SS7 Linkset or Application Server. The Linkset or +Application Servers are identified by their name. + +.Major Attributes of an Osmocom SS7 Application Server Process +[options="header",cols="25%,75%"] +|==== +|Name|Description +|Point Code|Destination Point Code for this route +|Mask|Destination Mask for this route (like an IP netmask) +|Linkset/AS Name|Destination Linkset or AS, identified by name +|==== + + +=== Osmocom SCCP Instances + +An Osmocom SS7 Instance can be bound to an Osmocom SS7 Instance. It +will register/bind for the ITU-standard Service Indicator (SI). + +=== Osmocom SCCP User + +An Program (like a BSC) will _bind_ itself to a given well-known +sub-system number (SSN) in order to receive SCCP messages destined for +this SSN. + +There is an API to bind a program to a SSN, which implicitly generates +an SCCP User object. + +The ``show cs7 instance <0-15> sccp users'' command can be used on the +VTY to obtain a list of currently bound SCCP users, as well as their +corresponding SSNs. + +=== Osmocom SCCP Connection + +This is how Osmocom represents each individual connection of +connection-oriented SCCP. + +To illustrate the practical applicaiton: For the common use case of +the A or Iu interfaces, this means that every dedicated radio channel +that is currently active to any UE/MS has one SCCP connection to the +MSC and/or SGSN. + +The ``show cs7 instance <0-15> sccp connections'' command can be used +on the VTY to obtain a list of currently active SCCP connections, as +well as their source/destination and current state. + + +=== Osmocom SCCP User SAP + +The Osmocom SCCP User SAP (Service Access Point) is the programming +interface between the SCCP Provider (libosmo-sigtran) and the SCCP +User. It follows primitives as laid out in <>, encapsulated +in ``osmo_prim'' structures. + +=== Osmocom MTP User SAP + +The Osmocom MTP User SAP (Service Access Point) is the programming +interface betwen the MTP Provider and the MTP User (e.g. SCCP). It +follows primitives as laid out in <>, encapsulated in +``osmo_prim'' structures. diff --git a/common/chapters/sigtran-simple-2g.dot b/common/chapters/sigtran-simple-2g.dot new file mode 100644 index 0000000..28098fd --- /dev/null +++ b/common/chapters/sigtran-simple-2g.dot @@ -0,0 +1,22 @@ +digraph G { + rankdir=LR; + MS0 [label="MS"]; + MS1 [label="MS"]; + MS2 [label="MS"]; + MS3 [label="MS"]; + BTS0 [label="BTS"]; + BTS1 [label="BTS"]; + BSC [label="OsmoBSC"]; + MSC [label="OsmoMSC"]; + STP [label="OsmoSTP"]; + + MS0 -> BTS0; + MS1 -> BTS0; + MS2 -> BTS1; + MS3 -> BTS1; + BTS0 -> BSC [label="Abis/IP"]; + BTS1 -> BSC [label="Abis/IP"]; + BSC -> STP [label="SCCP/M3UA"]; + STP -> MSC [label="SCCP/M3UA", dir="back"]; +} + diff --git a/common/chapters/sigtran-simple-3g.dot b/common/chapters/sigtran-simple-3g.dot new file mode 100644 index 0000000..eac363d --- /dev/null +++ b/common/chapters/sigtran-simple-3g.dot @@ -0,0 +1,24 @@ +digraph G { + rankdir=LR; + UE0 [label="UE"]; + UE1 [label="UE"]; + UE2 [label="UE"]; + UE3 [label="UE"]; + HNB0 [label="hNodeB"]; + HNB1 [label="hNodeB"]; + HNBGW [label="OsmoHNBGW"]; + MSC [label="OsmoMSC"]; + SGSN [label="OsmoSGSN"]; + STP [label="OsmoSTP"]; + + UE0 -> HNB0; + UE1 -> HNB0; + UE2 -> HNB1; + UE3 -> HNB1; + HNB0 -> HNBGW [label="Iuh (RUA)"]; + HNB1 -> HNBGW [label="Iuh (RUA)"]; + HNBGW -> STP [label="Iu (SCCP/M3UA)"]; + STP -> MSC [label="Iu (SCCP/M3UA)", dir="back"]; + STP -> SGSN [label="Iu (SCCP/M3UA)", dir="back"]; +} + diff --git a/common/chapters/sigtran.adoc b/common/chapters/sigtran.adoc new file mode 100644 index 0000000..9d8e42e --- /dev/null +++ b/common/chapters/sigtran.adoc @@ -0,0 +1,330 @@ +== Signaling Networks: SS7 and SIGTRAN + +Classic digital telephony networks (whether wired or wireless) use the +ITU-T SS7 (Signaling System 7) to exchange signaling information +between network elements. + +Most of the ETIS/3GPP interfaces in the GSM and UMTS network are also +based on top of [parts of] SS7. This includes, among others, the +following interfaces: + +* _A_ interface between BSC and MSC +* _IuCS_ interface between RNC (or HNB-GW) and MSC +* _IuPS_ interface between RNC (or HNB-GW) and SGSN + +NOTE:: This does not include the A-bis interface between BTS and BSC. +While Abis traditionally is spoken over the same physical TDM circuits +as SS7, the protocol stack from L2 upwars is quite different (Abis +uses LAPD, while SS7 uses MTP)! + +=== Physical Layer + +The traditional physical layer of SS7 is based on TDM (time division +multiplex) links of the PDH/SDH family, as they were common in ISDN +networks. Some people may know their smallest incarnation as +so-called E1/T1 links. It can run either on individual 64kBps +timeslots of such a link, or on entire 2Mbps/1.5MBps E1/T1 links. + +There are also specifications for SS7 over ATM, though it is unclear +to the author if this is actually still used anywhere. + +On top of the Physical Layer is the Message Transfer Part (MTP). + +=== Message Transfer Part (MTP) + +MTP is the lower layer of the SS7 protocol stack. It is comprised of +two sub-layes, called MTP2 and MTP3. + +Nodes in a MTP network are addressed by their unique PC (Point Code). + +A _MTP Routing Label_ is in the MTP header and indicates the +_Originationg Point Code_ (OPC) as well as the _Destination Point +Code_ (DPC) and the _Service Indicator Octet_ (SIO). The SIO is used +to de-multiplex between different upper-layer protocol such as ISUP, +TUP or SCCP. + +Routing is performed by means of routers with routing tables, similar +to routing is performed in IP networks. Even the concept of a _point +code mask_ analogous to the _netmask_ exists. + +Routers are connected with one another over one or more _Link Sets_, +each comprised of one or multiple _Links_. Multiple Links in a +Linkset exist both for load sharing as well as for fail over purposes. + +==== Point Codes + +The length of point codes depends on the particular MTP dialect that +is used. In the 1980ies, when international telephony signaling +networks were established, most countries had their own national +dialects with certain specifics. + +Today, mostly the ITU and ANSI variants survive. The ITU variant uses +14bit point codes, while the ANSI variant uses 24 bit point code +length. + +Point Codes can be represented either as unsigned integers, or +grouped. Unfortunately there is no standard as to their +representation. In ITU networks, the _3.8.3_ notation is commonly +used, i.e. one decimal for the first 3 bits, followed by one decimal +for the center 8 bits, followed by another decimal for the final 3 +bits. + +Example:: The Point Code *1.5.3* (in 3.8.3 notation) is 1*2^11^ + 5*2^3^ + 3 = *2091 decimal*. + +=== Higher-Layer Protocols + +There are various higher-layer protocols used on top of MTP3, such as +TUP, ISUP, BICC as well as SCCP. Those protocols exist side-by-side +on top of MTP3, similar to e.g. ICMP, TCP and UDP existing +side-by-side on top of IP. + +In the context of cellular networks, SCCP is the most relevant part. + +=== Signaling Connection Control Part (SCCP) + +SCCP runs on top of MTP3 and creates something like an overlay network +on top of it. SCCP communication can e.g. span multiple different +isolated MTP networks, each with their own MTP dialect and addressing. + +SCCP provides both connectionless (datagram) and connection-oriented +services. Both are used in the context of cellular networks. + +==== SCCP Adresses + +SCCP Adresses are quite complex. This is due to the fact that it is +not simply one address format, but in fact a choice of one or multiple +different types of addresses. + +SCCP Addresses exist as _Calling Party_ and _Called Party_ addresses. +In the context of connectionless datagram services, the sender is +always the Calling Party, and the receiver the Called Party. In +connection-oriented SCCP, they resemble the initiator and recipient of +the connection. + +.SCCP Address Parts +[options="header",cols="10%,20%,70%"] +|==== +|Acronym|Name|Description +|SSN|Sub-System Number|Describes a given application such as e.g. a + GSM MSC, BSC or HLR. Can be compared to port + numbers on the Internet +|PC|Point Code |The Point Code of the underlying MTP network +|GT|Global Title |What most people would call a "phone number". + However, Global Titles come in many different + numbering plans, and only one of them (E.164) + resembles actual phone numbers. +|RI|Routing Indicator |Determines if message shall be routed on PC+SSN + or on GT basis +|==== + +==== Global Titles + +A Global Title is a (typically) globally unique address in the global +telephony network. The body of the Global Title consists of a series +of BCD-encoded digits similar to what everyone knows as phone numbers. + +A GT is however not only the digits of the "phone number", but also +some other equally important information, such as the _Numbering Plan_ +as well as the _Nature of Address Indication_. + +.Global Title Parts +[options="header",cols="10%,20%,70%"] +|==== +|Acronym|Name|Description +|GTI|Global Title Indicator|Determines the GT Format. Ranges from no + GT (0) to GT+TT+NP+ES+NAI (4) +|NAI|Nature of Address Indicator|Exists in GTI=1 and is sort of a mixture of TON + NPI +|TT|Translation Type |Used as a look-up key in Global Title Translation Tables +|NP|Numbering Plan |Indicates ITU Numbering Plan, such as E.164, E.212, E.214 +|ES|Encoding Scheme |Just a peculiar way to idicate the length of the digits +|- |Signals |The actual "phone number digits" +|==== + +For more information about SCCP Adresses and Global Titles, please +refer to <> + + +==== Global Title Translation (GTT) + +Global Title Translation is a process of re-writing the Global Title +on-the-fly while a signaling message passes a STP. + +Basically, a SCCP message is first transported by MTP3 on the MTP +level to the Destination Point Code indicated in the MTP Routing +Label. This process uses MTP routing and is transparent to SCCP. + +Once the SCCP message arrives at the MTP End-Node identified by the +Destination Point Code, the message is handed up to the local SCCP +stack, which then may implement Global Title Translation. + +The input to the GTT process is +* the destination address of the SCCP message +* a local list/database of Global Title Translation Rules + +The successful output of he GTT includes +* A new Routing Indicator +* The Destination Point Code to which the message is forwarded on MTP + level +* a Sub-system Number (if RI is set to "Route on SSN") +* a new Global Title (if RI is set to "Route on GT"), e.g. with translated digits. + +Between sender and recipient of a signaling message, there can be many +instances of Global Title Translation (up to 15 as per the hop +counter). + +For more information on Global Title Translation, please refer to +<>. + + +==== Peculiarities of Connection Oriented SCCP + +Interestingly, Connection-Oriented SCCP messages carry SCCP Adresses +*only during connection establishment*. All data messages during +an ongoing connection do not contain a Called or Calling Party +Address. Instead, they are routed only by the MTP label, which is +constructed from point code information saved at the time the +connection is established. + +This means that connection-oriented SCCP can not be routed across MTP +network boundaries the same way as connectionless SCCP messages. +Instead, an STP would have to perform _connection coupling_, whic is +basically the equivalent of an application-level proxy between two +SCCP connections, each over one of the two MTP networks. + +This is probably mostly of theoretical relevance, as +connection-oriented SCCP is primarily used betwen RAN and CN of +cellular network inside one operator, i.e. not across multiple MTP +networks. + +=== SIGTRAN - SS7 over IP Networks + +At some point, IP based networks became more dominant than classic +ISDN networks, and 3GPP as well as IETF were working out methods in +which telecom signaling traffic can be adapted over IP based +networks. + +Initially, only the edge of the network (i.e. the applications talking +to the network, such as HLR or MSC) were attached to the existing old +SS7 backbone by means as SUA and M3UA. Over time, even the links of +the actual network backbone networks became more and more IP based. + +In order to replace existing TDM-based SS7 links/liksets with SIGTRAN, +the M2UA or M2PA variants are used as a kind of drop-in replacement +for physical links. + +All SIGTRAN share that while they use IP, they don't use TCP or UDP +but operate over a (then) newly-introduced Layer 4 transport protocol +on top of IP: SCTP (Stream Control Transmission Protocol). + +Despite first being specified in October 2000 as IETF RFC 2960, it +took a long time until solid implementations of SCTP ended up in +general-purpose operating systems. SCTP is not used much outside the +context of SIGTAN, which means implementations often suffer from bugs, +and many parts of the public Internet do not carry SCTP traffic due to +restrictive firewalls and/or ignorant network administrators. + +==== SIGTRAN Concepts / Terminology + +Like every protocol or technologoy, SIGTRAN brings with it its own +terminologyand concepts. This section tries to briefly introduce +them. For more information, please see the related IETF RFCs. + +===== Signaling Gateway (SG) + +The Signaling Gateway (SG) interconnects the SS7 network wit external +applications. It translates (parts of) the SS7 protocol stack into an +IP based SIGTRAN protocol stack. Which parts at whcih level of the +protocol stack are translated to what depends on the specific SIGTRAN +dialect. + +A SG is traditionally attached to the TDM-Based SS7 network and offers +SIGTRAN/IP based applications a way to remotely attach to the SS7 +network. + +A SG typically has STP functionality built-in, but it is not +mandatory. + +===== Application Server (AS) + +An Application Server is basically a logical entity representing one +particular external application (from the SS7 point of view) which is +interfaced with the SS7 network by means of one of the SIGTRAN +protocols. + +An Application Server can have one or more Application Server Processes +associated with it. This functionality (currently not implemented in +Osmocom) can be used for load-balancing or fail-over scenarios. + +===== Application Server Process (ASP) + +An Application Server Process represents one particular SCTP +connection used for SIGTRAN signaling between an external application +(e.g. a BSC) and the Signaling Gateway (SG). + +One Application Server Process can route traffic for multiple +Application Servers. In order to differentiate traffic for different +Application Servers, the Routing Context header is used. + +==== SIGTRAN variants / stackings + +SIGTRAN is the name of an IETF working group, which has released an +entire group of different protocol specifications. So rather than one +way of transporting classic telecom signaling over IP, there are now +half a dozen different ones, and all can claim to be an official IETF +standard. + +FIXME: Overview picture comparing the different stackings + +===== MTP3 User Adaptation (M3UA) + +M3UA basically "chops off" everything up to and including the MTP3 +protocol layer of the SS7 protocol stack and replaces it with a stack +comprised of M3UA over SCTP over IP. + +M3UA is specified in <>. + +===== SCCP User Adaptation (SUA) + +SUA basically "chops off" everything up to and including the SCCP +protocol layer of the SS7 protocol stack and replaces it with a stack +comprised of SUA over SCTP over IP. + +This means that SUA can only be used for SCCP based signaling, but not +for other SS7 protocols like e.g. TUP and ISUP. + +SUA is specified in <>. + +===== MTP2 User Adaptation (M2UA) + +M2UA is specified in <>. + +NOTE:: M2UA is not supported in Osmocom SIGTRAN up to this point. Let +us know if we can implement it for you! + +===== MTP2-User Peer-to-Peer Adaptation (M2PA) + +M2PA is specified in <>. + +NOTE:: M2PA is not supported in Osmocom SIGTRAN up to this point. Let +us know if we can implement it for you! + + +==== SIGTRAN security + +There simply is none. There are some hints that TLS shall be used +over SCTP in order to provide authenticity and/or confidentiality for +SIGTRAN, but this is not widely used. + +As telecom signaling is not generally carried over public networks, +private networks/links by means of MPLS, VLANs or VPNs such as IPsec +are often used to isolate and/or secure SIGTRAN. + +Under no circumstances should you use unsecured SIGTRAN with +production data over the public internet! + +==== IPv6 support + +SCTP (and thus all the higher layer protocols of the various SIGTRAN +stackings) operates on top of both IPv4 and IPv6. As the entire +underlying IP transport is transparent to the SS7/SCCP applcations, +there is no restriction on whether to use SIGTRAN over IPv4 or IPv6. -- To view, visit https://gerrit.osmocom.org/2371 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I450bfac7444ac9cb7f50c086d87cf7157c2e2a31 Gerrit-PatchSet: 2 Gerrit-Project: osmo-gsm-manuals Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sun Apr 16 01:29:34 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 16 Apr 2017 01:29:34 +0000 Subject: [PATCH] osmo-gsm-manuals[master]: First step towards an OsmoSTP manual In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2371 to look at the new patch set (#3). First step towards an OsmoSTP manual Change-Id: I450bfac7444ac9cb7f50c086d87cf7157c2e2a31 --- M Makefile A OsmoSTP/Makefile A OsmoSTP/chapters/overview.adoc A OsmoSTP/osmostp-usermanual-docinfo.xml A OsmoSTP/osmostp-usermanual.adoc A OsmoSTP/osmostp-vty-reference.xml A OsmoSTP/vty/stp_vty_reference.xml M common/chapters/bibliography.adoc M common/chapters/glossary.adoc A common/chapters/sigtran-osmocom.adoc A common/chapters/sigtran-simple-2g.dot A common/chapters/sigtran-simple-3g.dot A common/chapters/sigtran.adoc 13 files changed, 1,019 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-gsm-manuals refs/changes/71/2371/3 diff --git a/Makefile b/Makefile index 035595c..ed0c894 100644 --- a/Makefile +++ b/Makefile @@ -6,6 +6,7 @@ cd OsmoSGSN; $(MAKE) cd OsmoNAT; $(MAKE) cd OsmoPCU; $(MAKE) + cd OsmoSTP; $(MAKE) clean: cd OsmoBTS; $(MAKE) clean @@ -15,6 +16,7 @@ cd OsmoSGSN; $(MAKE) clean cd OsmoNAT; $(MAKE) clean cd OsmoPCU; $(MAKE) clean + cd OsmoSTP; $(MAKE) clean upload: cd OsmoBTS; $(MAKE) upload @@ -24,6 +26,7 @@ cd OsmoSGSN; $(MAKE) upload cd OsmoNAT; $(MAKE) upload cd OsmoPCU; $(MAKE) upload + cd OsmoSTP; $(MAKE) upload check: cd OsmoBTS; $(MAKE) check @@ -31,6 +34,7 @@ cd OsmoBSC; $(MAKE) check cd OsmoSGSN; $(MAKE) check cd OsmoPCU; $(MAKE) check + cd OsmoSTP; $(MAKE) check # These don't use asciidoc, so they have no 'make check' target: #cd OsmoMGCP; $(MAKE) check #cd OsmoNAT; $(MAKE) check diff --git a/OsmoSTP/Makefile b/OsmoSTP/Makefile new file mode 100644 index 0000000..bf3ba8f --- /dev/null +++ b/OsmoSTP/Makefile @@ -0,0 +1,45 @@ +# XSL stylesheets downloaded from http://docbook.sourceforge.net/release/xsl/current/html/ +# Makefile from BitBake/OpenEmbedded manuals + + +EXTRA_DEPS = gen-stp-vty-docbook + +topdir = . +stp_reference = $(topdir)/osmostp-vty-reference.xml +manuals = $(stp_reference) +# types = pdf txt rtf ps xhtml html man tex texi dvi +# types = pdf txt +types = $(docbooktotypes) +docbooktotypes = pdf +# htmlcssfile = +# htmlcss = + +TOPDIR := .. +ASCIIDOCS := osmostp-usermanual + +include $(TOPDIR)/build/Makefile.asciidoc.inc +include $(TOPDIR)/build/Makefile.inc + +osmostp-usermanual.pdf: chapters/*.adoc + +clean: + -rm -rf $(cleanfiles) + -rm osmostp-usermanual__*.png + -rm osmostp-usermanual__*.svg + -rm osmostp-usermanual*.check + +gen-stp-vty-docbook: FORCE + $(call command,xsltproc -o generated/combined1.xml \ + --stringparam with $(PWD)/../common/vty_additions.xml \ + $(MERGE_DOC) vty/stp_vty_reference.xml, \ + XSLTPROC,Merging Common VTY) + $(call command,xsltproc -o generated/combined2.xml \ + --stringparam with $(PWD)/../common/stp_vty_additions.xml \ + $(MERGE_DOC) generated/combined1.xml, \ + XSLTPROC,Merging Common STP VTY) + $(call command,xsltproc -o generated/combined3.xml \ + --stringparam with $(PWD)/vty/stp_vty_additions.xml \ + $(MERGE_DOC) generated/combined2.xml, \ + XSLTPROC,Merging STP VTY) + $(call command,xsltproc ../vty_reference.xsl generated/combined3.xml > generated/docbook_vty.xml, \ + XSLTPROC,Converting STP VTY to DocBook) diff --git a/OsmoSTP/chapters/overview.adoc b/OsmoSTP/chapters/overview.adoc new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/OsmoSTP/chapters/overview.adoc diff --git a/OsmoSTP/osmostp-usermanual-docinfo.xml b/OsmoSTP/osmostp-usermanual-docinfo.xml new file mode 100644 index 0000000..4253957 --- /dev/null +++ b/OsmoSTP/osmostp-usermanual-docinfo.xml @@ -0,0 +1,47 @@ + + + 1 + April 16, 2017 + HW + + Initial OsmoSTP manual + + + + + + + Harald + Welte + hwelte at sysmocom.de + HW + + sysmocom + sysmocom - s.f.m.c. GmbH + Managing Director + + + + + + 2012-2017 + sysmocom - s.f.m.c. GmbH + + + + + Permission is granted to copy, distribute and/or modify this + document under the terms of the GNU Free Documentation License, + Version 1.3 or any later version published by the Free Software + Foundation; with the Invariant Sections being just 'Foreword', + 'Acknowledgements' and 'Preface', with no Front-Cover Texts, + and no Back-Cover Texts. A copy of the license is included in + the section entitled "GNU Free Documentation License". + + + The Asciidoc source code of this manual can be found at + + http://git.osmocom.org/osmo-gsm-manuals/ + + + diff --git a/OsmoSTP/osmostp-usermanual.adoc b/OsmoSTP/osmostp-usermanual.adoc new file mode 100644 index 0000000..2be3372 --- /dev/null +++ b/OsmoSTP/osmostp-usermanual.adoc @@ -0,0 +1,33 @@ +OsmoSTP User Manual +=================== +Harald Welte + + +include::../common/chapters/preface.adoc[] + +// include::chapters/overview.adoc[] + +include::../common/chapters/sigtran.adoc[] +include::../common/chapters/sigtran-osmocom.adoc[] + +//include::chapters/running.adoc[] +// include::chapters/control.adoc[] + +include::../common/chapters/vty.adoc[] + +include::../common/chapters/logging.adoc[] + +//include::../common/chapters/bts.adoc[] + +//include::../OsmoNITB/chapters/bts-examples.adoc[] + +//include::../common/chapters/control_if.adoc[] + +include::../common/chapters/port_numbers.adoc[] + +include::../common/chapters/bibliography.adoc[] + +include::../common/chapters/glossary.adoc[] + +include::../common/chapters/gfdl.adoc[] + diff --git a/OsmoSTP/osmostp-vty-reference.xml b/OsmoSTP/osmostp-vty-reference.xml new file mode 100644 index 0000000..807d427 --- /dev/null +++ b/OsmoSTP/osmostp-vty-reference.xml @@ -0,0 +1,38 @@ + + + + +]> + + + + + + v1 + April 16, 2017 + h2 + Initial + + + + OsmoSTP VTY Reference + + + 2012-2017 + + + + This work is copyright by sysmocom - s.f.m.c. GmbH. All rights reserved. + + + + + + &chapter-vty; + + diff --git a/OsmoSTP/vty/stp_vty_reference.xml b/OsmoSTP/vty/stp_vty_reference.xml new file mode 100644 index 0000000..a4c675e --- /dev/null +++ b/OsmoSTP/vty/stp_vty_reference.xml @@ -0,0 +1,2 @@ + + diff --git a/common/chapters/bibliography.adoc b/common/chapters/bibliography.adoc index a3c6436..d5e1c1b 100644 --- a/common/chapters/bibliography.adoc +++ b/common/chapters/bibliography.adoc @@ -106,11 +106,29 @@ https://tools.ietf.org/html/rfc1350 - [[[ietf-rfc2131]]] IETF RFC 2131: Dynamic Host Configuration Protocol https://tools.ietf.org/html/rfc2131 +- [[[ietf-rfc2719]]] IETF RFC 2719: Signal Transport over IP + https://tools.ietf.org/html/rfc2719 +- [[[ietf-rfc3331]]] IETF RFC 3331: Message Transfer Part 2 User Adaptation Layer + https://tools.ietf.org/html/rfc3331 - [[[ietf-rfc3550]]] IETF RFC 3550: RTP: A Transport protocol for Real-Time Applications https://tools.ietf.org/html/rfc3550 +- [[[ietf-rfc3868]]] IETF RFC 3868: SCCP User Adaptation Layer + https://tools.ietf.org/html/rfc3868 +- [[[ietf-rfc4165]]] IETF RFC 4165: Message Transfer Part 2 Peer-to-Peeer Adaptation Layer + https://tools.ietf.org/html/rfc4165 - [[[ietf-rfc4251]]] IETF RFC 4251: The Secure Shell (SSH) Protocol Architecture https://tools.ietf.org/html/rfc4251 +- [[[ietf-rfc4666]]] IETF RFC 4666: Message Transfer Part 3 User Adaptation Layer + https://tools.ietf.org/html/rfc4666 +- [[[itu-t-q701]]] ITU-T Q.701: Functional Description of the Message Transfer Part (MTP) + https://www.itu.int/rec/T-REC-Q.701/en/ +- [[[itu-t-q711]]] ITU-T Q.711: Functional Description of the Signalling Connection Control Part + https://www.itu.int/rec/T-REC-Q.711/en/ +- [[[itu-t-q713]]] ITU-T Q.713: Signalling connection control part formats and codes + https://www.itu.int/rec/T-REC-Q.713/en/ +- [[[itu-t-q714]]] ITU-T Q.714: Signalling connection control part procedures + https://www.itu.int/rec/T-REC-Q.714/en/ - [[[itu-t-q921]]] ITU-T Q.921: ISDN user-network interface - Data link layer specification https://www.itu.int/rec/T-REC-Q.921/en diff --git a/common/chapters/glossary.adoc b/common/chapters/glossary.adoc index c39d439..042fd3a 100644 --- a/common/chapters/glossary.adoc +++ b/common/chapters/glossary.adoc @@ -115,6 +115,8 @@ GSMTAP:: GSM tap; pseudo standard for encapsulating GSM protocol layers over UDP/IP for analysis +GT:: + Global Title; an address in SCCP GTP:: GPRS Tunnel Protocol; used between SGSN and GGSN HLR:: @@ -143,6 +145,12 @@ 44.064_ <<3gpp-ts-44-064>>) Location Area:: Location Area; a geographic area containing multiple BTS +M2PA:: + MTP2 Peer-to-Peer Adaptation; a SIGTRAN Variant (_RFC 4165_ <>) +M2UA:: + MTP2 User Adaptation; a SIGTRAN Variant (_RFC 3331_ <>) +M3UA:: + MTP3 User Adaptation; a SIGTRAN Variant (_RFC 4666_ <>) MCC:: Mobile Country Code; unique identifier of a country, e.g. 262 for Germany MFF:: @@ -163,6 +171,8 @@ core network MSISDN:: Mobile Subscriber ISDN Number; telephone number of the subscriber +MTP:: + Message Transfer Part; SS7 signaling protocol (_ITU-T Q.701_ <>) MVNO:: Mobile Virtual Network Operator; Operator without physical radio network NCC:: @@ -206,6 +216,8 @@ OTA:: Over-The-Air; Capability of operators to remotely reconfigure/reprogram ISM/USIM cards +PC:: + Point Code; an address in MTP PCH:: Paging Channel on downlink Um interface; used by network to page an MS PCU:: @@ -249,11 +261,15 @@ SACCH:: Slow Associate Control Channel on Um interface; bundled to a TCH or SDCCH, used for signalling in parallel to active dedicated channel +SCCP:: + Signaling Connection Control Part; SS7 signaling protocol (_ITU-T Q.711_ <>) SDCCH:: Slow Dedicated Control Channel on Um interface; used for signalling and SMS transport in GSM SDK:: Software Development Kit +SIGTRAN:: + Signaling Transport over IP (_IETF RFC 2719_ <>) SIM:: Subscriber Identity Module; small chip card storing subscriber identity Site:: @@ -264,8 +280,16 @@ entities with an SMSC SMSC:: Short Message Service Center; store-and-forward relay for short messages +SS7:: + Signaling System No. 7; Classic digital telephony signaling system SSH:: Secure Shell; _IETF RFC 4250_ <> to 4254 +SSN:: + Sub-System Number; identifies a given SCCP Service such as MSC, HLR +STP:: + Signaling Transfer Point; A Router in SS7 Networks +SUA:: + SCCP User Adaptation; a SIGTRAN Variant (_RFC 3868_ <>) syslog:: System logging service of UNIX-like operating systems System Information:: diff --git a/common/chapters/sigtran-osmocom.adoc b/common/chapters/sigtran-osmocom.adoc new file mode 100644 index 0000000..1e08733 --- /dev/null +++ b/common/chapters/sigtran-osmocom.adoc @@ -0,0 +1,432 @@ +== Osmocom SS7 + SIGTRAN support + +=== History / Background + +If you're upgrading from earlier releases of the Osmocom stack, this +section will give you some background about the evolution. + +==== The Past (before 2017) + +In the original implementation of the GSM BSC inside Osmocom (the +OsmoBSC program, part of OpenBSC), no SS7 support was included. + +This is despite the fact that ETSI/3GPP mandated the use of SCCP over +MTP over E1/T1 TDM lines for the A interface at that time. + +Instead of going down to the TDM based legacy physical layers, OsmoBSC +implemented someting called an IPA multiplex, which apparently some +people also refer to as SCCPlite. We have never seen any +specifications for this interface, but implemented it from scratch +using protocol traces. + +The IPA protocol stack is based on a minimal sub-set of SCCP +(including connection oriented SCCP) wrapped into a 3-byte header to +packetize a TCP stream. + +The IPA/SCCPlite based A interface existed at a time when the +ETSI/3GPP specifications did not offer any IP based transport for the +A interface. An official as added only in Release FIXME of the 3GPP +specifications. + +The A interface BSSMAP protocol refers to voice circuits (E1/T1 +timeslots) using circuit identity codes (CICs). As there are no +physical timeslots on a TCP/IP based transport layer, the CICs get +mapped to RTP streams for circuit-switched data using out-of-band +signaling via MGCP, the IETF-standardized Media Gateway Control +Protocol. + +==== The present (2017) + +In 2017, sysmocom was tasked with implementing a 3GPP AoIP compliant A +interface. This meant that lot of things had to change in the +existing code: + +* removal of the existing hard-wired SCCPlite/IPA code from OsmoBSC +* introduction of a formal SCCP User SAP at the lower boundary of + BSSMAP +* introduction of libosmo-sigtran, a comprehensive SS7 and SIGTRAN + library which includes a SCCP implementation for connectionless and + connection-oriented procedures, offering the SCCP User SAP towards + BSSAP +* introduction of an A interface in OsmoMSC (which so far offered Iu + only) +* port of the existing SUA-baesd IuCS and IuPS over to the SCCP User + SAP of libosmo-sigtran. +* Implementation of ETSI M3UA as preferred/primary transport layer for + SCCP +* Implementation of an IPA transport layer inside libosmo-sigtran, in + order to keep backwards-compatibility. + +This work enables the Osmocom universe to become more compliant +with modern Releases of 3GPP specifications, which enables +interoperability with other MSCs or even BSCs. However, this comes at +a price: Increased complexity in set-up and configuration. + +Using SS7 or SIGTRAN based transport of the A interface adds an +entirely new domain that needs to be understood by system and network +administrators setting up cellular networks based on Osmocom. + +One of the key advantages of the Osmocom architecture with OsmoNITB +was exactly this simplification and reduction of complexity, enabling +more people to set-up and operate cellular networks. + +So we have put some thought into how we can achieve compatibility with +SS7/SIGTRAN and the 3GPP specifications, while at the same time +enabling some degree of auto-configuration where a small network can +be set up without too many configuration related to the signaling +network. We have achieved this by "abusing" (or extending) the M3UA +Routing Key Management slightly. + +=== Osmocom extensions to SIGTRAN + +Osmocom has implemented some extensions to the SIGTRAN protocol suite. +Those extensions will be documented below. + +==== Osmocom M3UA Routing Key Management Extensions + +In classic M3UA, a peer identifies its remote peer based on IP address +and port details. So once an ASP connects to an SG, the SG will check +if there is any configuration that matches the source IP (and possibly +source port) of that connection in order to understand which routing +context is used - and subsequently which traffic is to be routed to +this M3UA peer. + +This is quite inflexible, as it means that every BSC in a GSM network +needs to be manually pre-configured at the SG/STP, and that +configuration on the BSC and MSC must match to enable communication. + +M3UA specifies an optional Routing Key Management (RKM) sub-protocol. +Using RKM, an ASP can dynamically tell the SG/STP, which traffic it +wants to receive. However, the idea is still that the SG has some +matching configuration. + +In OsmoSTP based on libosmo-sigtran, we decided to (optionally) enable +fully dynamic registration. This means that any ASP can simply +connect to the SG and request the dynamic creation of an ASP and AS +with a corresponding routing key for a given point code. As long as +the SG doesn't already have a route to this requested point code, The +SG will simply trust any ASP and set a corresponding route. + +This is of course highly insecure and can only be used in trusted, +internal newtworks. However, it is quite elegant in reducing the +amount of configuration complexity. All that is needed, is that an +unique point code is configured at each of the ASPs (application +programs) that connect to the STP. + +To put things more concretely: Each BSC and MSC connecting to OsmoSTP +simply needs to be configured to have a different point code, and to +know to which IP/port of the STP to connect. There's no other +configuration required for a small, autonomous, self-contained +network. OsmoSTP will automatically insall ASP, AS and route +definitions on demand, and route messages between all connected +entities. + +The same above of course also applies to HNB-GW and OsmoSGSN in the +case of Iu interfaces. + +==== IPA / SCCPlite backwards compatibility + +The fundamental problem with IPA/SCCPlite is that there's no MTP +routing label surrounding the SCCP message. This is generally +problematic in the context of connection-oriented SCCP, as there is no +addressing information inside the SCCP messages after the connection +has been established. Instead, the messages are routed based on the +MTP label, containing point codes established during connection set-up +time. + +This means that even if the SCCP messages did contain Called/Calling +Party Addresses with point codes or global titles, it would only help +us for routing connectionless SCCP. The A interface, however, is +connection-oriented. + +So in order to integrate IPA/SCCPlite with a new full-blown +SS7/SIGTRAN stack, there are the following options: + +. implement SCCP connection coupling. This is something like a proxy + for connection-oriented SCCP, and is what is used in SS7 to route + beyond a given MTP netwokr (e.g. at gateways between different MTP + networks) + +. consider all SCCP messages to be destined for the local point code + of the receiver. This then means that the SG functionality must be + included inside the MSC, and the MSC be bound to the SSN on the + local point code. + +. hard-code some DPC when receiving a message from an IPA connection. + It could be any remote PC and we'd simply route the message towards + that point code. + +But then we also have the return direction: + +. We could "assign" a unique SPC to each connected IPA client (BSC), + and then announce that PC towards the SS7 side. Return packets + would then end up at our IPA-server-bearing STP, which forwards them + to the respective IPA connection and thus BSC. On the transmit + side, we'd simply strip the MTP routing label and send the raw SCCP + message over IPA. + +. If the IPA server / SGW resides within the MSC, one could also have + some kind of handle/reference to the specific TCP connection through + which the BSC connected. All responses for a given peer would then + have to be routed back to the same connection. This is quite ugly + as it completely breaks the concepts of the SCCP User SAP, where a + user has no information (nor to worry about ) any "physical" + signaling links. + + +=== Minimal Osmocom SIGTRAN configurations for small networks + +If you're not an SS7 expert, and all you want is to run your own small +self-contained cellular network, this section explains what you need +to do. + +In general, you can consider OsmoSTP as something like an IP router. +On the application layer (in our case the BSSAP/BSSMAP or RANAP +protocols between Radio Access Network and Core Network), it is +completely invisible/transparent. The BSC connects via SCCP to the +MSC. It doesn't know that there's an STP in between, and that this +STP is performing some routing function. Compares this to your web +browser not knowing about IP routers, it just establishes an http +connection to a web server. + +This is also why most GSM nework architecture diagrams will not +explicitly show an STP. It is not part of the cellular network. +Rather, one or many STPs are part of the underlying SS7 signaling +transport network, on top of which the cellular network elements are +built. + +==== A minimal 2G configuration to get started + +You will be running the following programs: + +* OsmoBSC as the base-station controller between your BTS (possibly + running OsmoBTS) and the MSC +* OsmoMSC as the mobile switching center providing SMS and telephony + service to your subscribers +* OsmoSTP as the signal transfer point, routing messages between one + or more BSCs and the MSC + +[[fig-sigtran-simple-2g]] +.Simple signaling network for 2G (GSM) +[graphviz] +---- +include::sigtran-simple-2g.dot[] +---- + +You can use the OsmoSTP fully dynamic registration feature, so the BSCs +and the MSC will simply register with their point codes to the STP, +and the STP will create most configuration on the fly. + +All you need to make sure is: + +* to assign one unique point code to each BSC and MSC +* to point all BSCs and the MSC to connect to the IP+Port of the STP +* to configure the point code of the MSC in the BSCs + +==== A minimaal 3G configuration to get started + +You will be running the following programs: + +* OsmoHNBGW as the homeNodeB Gateway between your femtocells / small + cells and the MSC+SGSN +* OsmoMSC as the mobile switching center providing SMS and telephony + service to your subscribers +* OsmoSGSN as the Serving GPRS Support Node, providing packet data + (internet) services to your subscribers +* OsmoSTP as the signal transfer point, routing messages between one + or more HNBGWs and the MSC and SGSN + +[[fig-sigtran-simple-3g]] +.Simple signaling network for 3G (UMTS) +[graphviz] +---- +include::sigtran-simple-3g.dot[] +---- + +You can use the OsmoSTP fully dynamic registration feature, so the +HNBGWs, the SMC and the SGSNwill simply register with their point +codes to the STP, and the STP will create most configuration on the +fly. + +All you need to make sure is: + +* to assign one unique point code to each HNBGW, MSC and SGSN +* to point all HNBGWs and the MSC and SGSN to connect to the IP+Port of STP +* to configure the point code of the MSC in the HNBGWs +* to configure the point code of the SGSN in the HNBGWs + +=== Osmocom SS7 Instances + +The entire SS7 stack can be operated multiple times within one +application/program by means of so-called SS7 Instances. + +There can be any number of SS7 Instances, and each instance has its +own set of XUA Servers, ASPs, ASs, Routes, etc. + +Each SS7 Instance can have different point code formats / lengths. + +.Major Attributes of an Osmocom SS7 Instance +[options="header",cols="25%,35%,40%"] +|==== +|Name|VTY Command|Description +|ID|(config)# cs7 instance ID|The numeric identifier of this instance +|Name|(config-cs7)# name NAME|A human-readable name for this instance +|Description|(cnfig-cs7)# description DESC| More verbose description +|Primary PC|(config-cs7)# point-code PC|Primary local point code +|Network Indicator|(config-cs7)# network-indicator|Network Indicator used in MTP3 Routing Label +|Point Code Format|(config-cs7)# point-code format|Point Code Format (Default: 3.8.3) +|Point Code Delimiter|(config-cs7)# point-code delimiter|Point Code Delimiter: . or - +|==== + +=== Osmocom SS7 xUA Server + +A *xUA Server* is a server that binds + listens to a given SCTP +(SIGTRAN) or TCP (IPA) port and accepts connections from remote peers +(ASPs). + +There can be any number of xUA Servers within one SS7 Instance, as +long as they all run on a different combination of IP address and +port. + +.Major Attributes of an Osmocom SS7 xUA Server +[options="header",cols="25%,75%"] +|==== +|Name|Description +|Local IP|Local Port Number to which the server shall bind/listen +|Local Port|Local IP Address to which the server shall bind/listen +|Protocol|Protocol (M3UA, SUA, IPA) to be operated by this server +|Accept Dynamic ASPs|Should we accept connections from ASPs that are not explicitly pre-configured with their source IP and port? +|==== + + +=== Osmocom SS7 Users + +A SS7 User is part of a program that binds to a given MTP-Layer +Service Indicator (SI). The Osmocom SS7 stack offers an API to +register SS7 Users, as well as the VTY command ``show cs7 instance +<0-15> users'' to list the currently registered users. + +=== Osmocom SS7 Links + +TBD. + +=== Osmocom SS7 Linksets + +TBD. + +=== Osmocom SS7 Application Servers + +This corresponds 1:1 to the SIGTRAN concept of an Application Server, +i.e. a given external Application that interfaces the SS7 network via +a SS7 protocol variant such as M3UA. + +In the context of Osmocom, for each program connecting to a STP (like +a BSC or MSC), you will have one Application Server definition. + +An AS has the following properties: + +.Major Attributes of an Osmocom SS7 Application Server +[options="header",cols="25%,75%"] +|==== +|Name|Description +|Name|A human-readable name for this instance +|Description|More verbose description (for human user only) +|Protocol|Protocol (M3UA, SUA, IPA) to be operated by this server +|Routing Key|Routing Key (mostly Point Code) routed to this AS +|Traffic Mode|Theoretically Bradcast, Load-Balance. Currently only Ovverride +|Recovery Timeout|Duration of the AS T(r) recovery timer. During this time, + outgoing messages are queued. If the AS is ACTIVE + before timer expiration, the queue is drained. At + expriation, the queue is flushed. +|State|Application Server State (Down, Inactive, Active, Pending) +|ASPs|Which ASPs are permitted to transfer traffic for this AS +|==== + +=== Osmocom SS7 Application Server Processes + +An Application Server Process corresponds to a given SCTP (or TCP) +connection. From the STP/SG (Server) point-of-view, those are +incoming connections from Application Servers such as the BSCs. From +the ASP (Client) Point of view, it has one ``osmo_ss7_asp'' object for +each outbound SIGTARN connection. + +An ASP has the following properties: + +.Major Attributes of an Osmocom SS7 Application Server Process +[options="header",cols="25%,75%"] +|==== +|Name|Description +|Name|A human-readable name for this instance +|Description|More verbose description (for human user only) +|Protocol|Protocol (M3UA, SUA, IPA) to be operated by this server +|Role|Server (SG) or Client (ASP)? +|Local Port|Port Number of the local end of the connection +|Local IP|IP Address of the local end of the connection +|Remote Port|Port Number of the remote end of the connection +|Remote IP|IP Address of the remote end of the connection +|State|ASP State (Down, Inactive, Active) +|==== + +=== Osmocom SS7 Routes + +An Osmocom SS7 Route routes traffic with a matching destination point +code and point code mask (similar to IP Address + Netmask) towards a +specified SS7 Linkset or Application Server. The Linkset or +Application Servers are identified by their name. + +.Major Attributes of an Osmocom SS7 Application Server Process +[options="header",cols="25%,75%"] +|==== +|Name|Description +|Point Code|Destination Point Code for this route +|Mask|Destination Mask for this route (like an IP netmask) +|Linkset/AS Name|Destination Linkset or AS, identified by name +|==== + + +=== Osmocom SCCP Instances + +An Osmocom SS7 Instance can be bound to an Osmocom SS7 Instance. It +will register/bind for the ITU-standard Service Indicator (SI). + +=== Osmocom SCCP User + +An Program (like a BSC) will _bind_ itself to a given well-known +sub-system number (SSN) in order to receive SCCP messages destined for +this SSN. + +There is an API to bind a program to a SSN, which implicitly generates +an SCCP User object. + +The ``show cs7 instance <0-15> sccp users'' command can be used on the +VTY to obtain a list of currently bound SCCP users, as well as their +corresponding SSNs. + +=== Osmocom SCCP Connection + +This is how Osmocom represents each individual connection of +connection-oriented SCCP. + +To illustrate the practical applicaiton: For the common use case of +the A or Iu interfaces, this means that every dedicated radio channel +that is currently active to any UE/MS has one SCCP connection to the +MSC and/or SGSN. + +The ``show cs7 instance <0-15> sccp connections'' command can be used +on the VTY to obtain a list of currently active SCCP connections, as +well as their source/destination and current state. + + +=== Osmocom SCCP User SAP + +The Osmocom SCCP User SAP (Service Access Point) is the programming +interface between the SCCP Provider (libosmo-sigtran) and the SCCP +User. It follows primitives as laid out in <>, encapsulated +in ``osmo_prim'' structures. + +=== Osmocom MTP User SAP + +The Osmocom MTP User SAP (Service Access Point) is the programming +interface betwen the MTP Provider and the MTP User (e.g. SCCP). It +follows primitives as laid out in <>, encapsulated in +``osmo_prim'' structures. diff --git a/common/chapters/sigtran-simple-2g.dot b/common/chapters/sigtran-simple-2g.dot new file mode 100644 index 0000000..28098fd --- /dev/null +++ b/common/chapters/sigtran-simple-2g.dot @@ -0,0 +1,22 @@ +digraph G { + rankdir=LR; + MS0 [label="MS"]; + MS1 [label="MS"]; + MS2 [label="MS"]; + MS3 [label="MS"]; + BTS0 [label="BTS"]; + BTS1 [label="BTS"]; + BSC [label="OsmoBSC"]; + MSC [label="OsmoMSC"]; + STP [label="OsmoSTP"]; + + MS0 -> BTS0; + MS1 -> BTS0; + MS2 -> BTS1; + MS3 -> BTS1; + BTS0 -> BSC [label="Abis/IP"]; + BTS1 -> BSC [label="Abis/IP"]; + BSC -> STP [label="SCCP/M3UA"]; + STP -> MSC [label="SCCP/M3UA", dir="back"]; +} + diff --git a/common/chapters/sigtran-simple-3g.dot b/common/chapters/sigtran-simple-3g.dot new file mode 100644 index 0000000..eac363d --- /dev/null +++ b/common/chapters/sigtran-simple-3g.dot @@ -0,0 +1,24 @@ +digraph G { + rankdir=LR; + UE0 [label="UE"]; + UE1 [label="UE"]; + UE2 [label="UE"]; + UE3 [label="UE"]; + HNB0 [label="hNodeB"]; + HNB1 [label="hNodeB"]; + HNBGW [label="OsmoHNBGW"]; + MSC [label="OsmoMSC"]; + SGSN [label="OsmoSGSN"]; + STP [label="OsmoSTP"]; + + UE0 -> HNB0; + UE1 -> HNB0; + UE2 -> HNB1; + UE3 -> HNB1; + HNB0 -> HNBGW [label="Iuh (RUA)"]; + HNB1 -> HNBGW [label="Iuh (RUA)"]; + HNBGW -> STP [label="Iu (SCCP/M3UA)"]; + STP -> MSC [label="Iu (SCCP/M3UA)", dir="back"]; + STP -> SGSN [label="Iu (SCCP/M3UA)", dir="back"]; +} + diff --git a/common/chapters/sigtran.adoc b/common/chapters/sigtran.adoc new file mode 100644 index 0000000..9d8e42e --- /dev/null +++ b/common/chapters/sigtran.adoc @@ -0,0 +1,330 @@ +== Signaling Networks: SS7 and SIGTRAN + +Classic digital telephony networks (whether wired or wireless) use the +ITU-T SS7 (Signaling System 7) to exchange signaling information +between network elements. + +Most of the ETIS/3GPP interfaces in the GSM and UMTS network are also +based on top of [parts of] SS7. This includes, among others, the +following interfaces: + +* _A_ interface between BSC and MSC +* _IuCS_ interface between RNC (or HNB-GW) and MSC +* _IuPS_ interface between RNC (or HNB-GW) and SGSN + +NOTE:: This does not include the A-bis interface between BTS and BSC. +While Abis traditionally is spoken over the same physical TDM circuits +as SS7, the protocol stack from L2 upwars is quite different (Abis +uses LAPD, while SS7 uses MTP)! + +=== Physical Layer + +The traditional physical layer of SS7 is based on TDM (time division +multiplex) links of the PDH/SDH family, as they were common in ISDN +networks. Some people may know their smallest incarnation as +so-called E1/T1 links. It can run either on individual 64kBps +timeslots of such a link, or on entire 2Mbps/1.5MBps E1/T1 links. + +There are also specifications for SS7 over ATM, though it is unclear +to the author if this is actually still used anywhere. + +On top of the Physical Layer is the Message Transfer Part (MTP). + +=== Message Transfer Part (MTP) + +MTP is the lower layer of the SS7 protocol stack. It is comprised of +two sub-layes, called MTP2 and MTP3. + +Nodes in a MTP network are addressed by their unique PC (Point Code). + +A _MTP Routing Label_ is in the MTP header and indicates the +_Originationg Point Code_ (OPC) as well as the _Destination Point +Code_ (DPC) and the _Service Indicator Octet_ (SIO). The SIO is used +to de-multiplex between different upper-layer protocol such as ISUP, +TUP or SCCP. + +Routing is performed by means of routers with routing tables, similar +to routing is performed in IP networks. Even the concept of a _point +code mask_ analogous to the _netmask_ exists. + +Routers are connected with one another over one or more _Link Sets_, +each comprised of one or multiple _Links_. Multiple Links in a +Linkset exist both for load sharing as well as for fail over purposes. + +==== Point Codes + +The length of point codes depends on the particular MTP dialect that +is used. In the 1980ies, when international telephony signaling +networks were established, most countries had their own national +dialects with certain specifics. + +Today, mostly the ITU and ANSI variants survive. The ITU variant uses +14bit point codes, while the ANSI variant uses 24 bit point code +length. + +Point Codes can be represented either as unsigned integers, or +grouped. Unfortunately there is no standard as to their +representation. In ITU networks, the _3.8.3_ notation is commonly +used, i.e. one decimal for the first 3 bits, followed by one decimal +for the center 8 bits, followed by another decimal for the final 3 +bits. + +Example:: The Point Code *1.5.3* (in 3.8.3 notation) is 1*2^11^ + 5*2^3^ + 3 = *2091 decimal*. + +=== Higher-Layer Protocols + +There are various higher-layer protocols used on top of MTP3, such as +TUP, ISUP, BICC as well as SCCP. Those protocols exist side-by-side +on top of MTP3, similar to e.g. ICMP, TCP and UDP existing +side-by-side on top of IP. + +In the context of cellular networks, SCCP is the most relevant part. + +=== Signaling Connection Control Part (SCCP) + +SCCP runs on top of MTP3 and creates something like an overlay network +on top of it. SCCP communication can e.g. span multiple different +isolated MTP networks, each with their own MTP dialect and addressing. + +SCCP provides both connectionless (datagram) and connection-oriented +services. Both are used in the context of cellular networks. + +==== SCCP Adresses + +SCCP Adresses are quite complex. This is due to the fact that it is +not simply one address format, but in fact a choice of one or multiple +different types of addresses. + +SCCP Addresses exist as _Calling Party_ and _Called Party_ addresses. +In the context of connectionless datagram services, the sender is +always the Calling Party, and the receiver the Called Party. In +connection-oriented SCCP, they resemble the initiator and recipient of +the connection. + +.SCCP Address Parts +[options="header",cols="10%,20%,70%"] +|==== +|Acronym|Name|Description +|SSN|Sub-System Number|Describes a given application such as e.g. a + GSM MSC, BSC or HLR. Can be compared to port + numbers on the Internet +|PC|Point Code |The Point Code of the underlying MTP network +|GT|Global Title |What most people would call a "phone number". + However, Global Titles come in many different + numbering plans, and only one of them (E.164) + resembles actual phone numbers. +|RI|Routing Indicator |Determines if message shall be routed on PC+SSN + or on GT basis +|==== + +==== Global Titles + +A Global Title is a (typically) globally unique address in the global +telephony network. The body of the Global Title consists of a series +of BCD-encoded digits similar to what everyone knows as phone numbers. + +A GT is however not only the digits of the "phone number", but also +some other equally important information, such as the _Numbering Plan_ +as well as the _Nature of Address Indication_. + +.Global Title Parts +[options="header",cols="10%,20%,70%"] +|==== +|Acronym|Name|Description +|GTI|Global Title Indicator|Determines the GT Format. Ranges from no + GT (0) to GT+TT+NP+ES+NAI (4) +|NAI|Nature of Address Indicator|Exists in GTI=1 and is sort of a mixture of TON + NPI +|TT|Translation Type |Used as a look-up key in Global Title Translation Tables +|NP|Numbering Plan |Indicates ITU Numbering Plan, such as E.164, E.212, E.214 +|ES|Encoding Scheme |Just a peculiar way to idicate the length of the digits +|- |Signals |The actual "phone number digits" +|==== + +For more information about SCCP Adresses and Global Titles, please +refer to <> + + +==== Global Title Translation (GTT) + +Global Title Translation is a process of re-writing the Global Title +on-the-fly while a signaling message passes a STP. + +Basically, a SCCP message is first transported by MTP3 on the MTP +level to the Destination Point Code indicated in the MTP Routing +Label. This process uses MTP routing and is transparent to SCCP. + +Once the SCCP message arrives at the MTP End-Node identified by the +Destination Point Code, the message is handed up to the local SCCP +stack, which then may implement Global Title Translation. + +The input to the GTT process is +* the destination address of the SCCP message +* a local list/database of Global Title Translation Rules + +The successful output of he GTT includes +* A new Routing Indicator +* The Destination Point Code to which the message is forwarded on MTP + level +* a Sub-system Number (if RI is set to "Route on SSN") +* a new Global Title (if RI is set to "Route on GT"), e.g. with translated digits. + +Between sender and recipient of a signaling message, there can be many +instances of Global Title Translation (up to 15 as per the hop +counter). + +For more information on Global Title Translation, please refer to +<>. + + +==== Peculiarities of Connection Oriented SCCP + +Interestingly, Connection-Oriented SCCP messages carry SCCP Adresses +*only during connection establishment*. All data messages during +an ongoing connection do not contain a Called or Calling Party +Address. Instead, they are routed only by the MTP label, which is +constructed from point code information saved at the time the +connection is established. + +This means that connection-oriented SCCP can not be routed across MTP +network boundaries the same way as connectionless SCCP messages. +Instead, an STP would have to perform _connection coupling_, whic is +basically the equivalent of an application-level proxy between two +SCCP connections, each over one of the two MTP networks. + +This is probably mostly of theoretical relevance, as +connection-oriented SCCP is primarily used betwen RAN and CN of +cellular network inside one operator, i.e. not across multiple MTP +networks. + +=== SIGTRAN - SS7 over IP Networks + +At some point, IP based networks became more dominant than classic +ISDN networks, and 3GPP as well as IETF were working out methods in +which telecom signaling traffic can be adapted over IP based +networks. + +Initially, only the edge of the network (i.e. the applications talking +to the network, such as HLR or MSC) were attached to the existing old +SS7 backbone by means as SUA and M3UA. Over time, even the links of +the actual network backbone networks became more and more IP based. + +In order to replace existing TDM-based SS7 links/liksets with SIGTRAN, +the M2UA or M2PA variants are used as a kind of drop-in replacement +for physical links. + +All SIGTRAN share that while they use IP, they don't use TCP or UDP +but operate over a (then) newly-introduced Layer 4 transport protocol +on top of IP: SCTP (Stream Control Transmission Protocol). + +Despite first being specified in October 2000 as IETF RFC 2960, it +took a long time until solid implementations of SCTP ended up in +general-purpose operating systems. SCTP is not used much outside the +context of SIGTAN, which means implementations often suffer from bugs, +and many parts of the public Internet do not carry SCTP traffic due to +restrictive firewalls and/or ignorant network administrators. + +==== SIGTRAN Concepts / Terminology + +Like every protocol or technologoy, SIGTRAN brings with it its own +terminologyand concepts. This section tries to briefly introduce +them. For more information, please see the related IETF RFCs. + +===== Signaling Gateway (SG) + +The Signaling Gateway (SG) interconnects the SS7 network wit external +applications. It translates (parts of) the SS7 protocol stack into an +IP based SIGTRAN protocol stack. Which parts at whcih level of the +protocol stack are translated to what depends on the specific SIGTRAN +dialect. + +A SG is traditionally attached to the TDM-Based SS7 network and offers +SIGTRAN/IP based applications a way to remotely attach to the SS7 +network. + +A SG typically has STP functionality built-in, but it is not +mandatory. + +===== Application Server (AS) + +An Application Server is basically a logical entity representing one +particular external application (from the SS7 point of view) which is +interfaced with the SS7 network by means of one of the SIGTRAN +protocols. + +An Application Server can have one or more Application Server Processes +associated with it. This functionality (currently not implemented in +Osmocom) can be used for load-balancing or fail-over scenarios. + +===== Application Server Process (ASP) + +An Application Server Process represents one particular SCTP +connection used for SIGTRAN signaling between an external application +(e.g. a BSC) and the Signaling Gateway (SG). + +One Application Server Process can route traffic for multiple +Application Servers. In order to differentiate traffic for different +Application Servers, the Routing Context header is used. + +==== SIGTRAN variants / stackings + +SIGTRAN is the name of an IETF working group, which has released an +entire group of different protocol specifications. So rather than one +way of transporting classic telecom signaling over IP, there are now +half a dozen different ones, and all can claim to be an official IETF +standard. + +FIXME: Overview picture comparing the different stackings + +===== MTP3 User Adaptation (M3UA) + +M3UA basically "chops off" everything up to and including the MTP3 +protocol layer of the SS7 protocol stack and replaces it with a stack +comprised of M3UA over SCTP over IP. + +M3UA is specified in <>. + +===== SCCP User Adaptation (SUA) + +SUA basically "chops off" everything up to and including the SCCP +protocol layer of the SS7 protocol stack and replaces it with a stack +comprised of SUA over SCTP over IP. + +This means that SUA can only be used for SCCP based signaling, but not +for other SS7 protocols like e.g. TUP and ISUP. + +SUA is specified in <>. + +===== MTP2 User Adaptation (M2UA) + +M2UA is specified in <>. + +NOTE:: M2UA is not supported in Osmocom SIGTRAN up to this point. Let +us know if we can implement it for you! + +===== MTP2-User Peer-to-Peer Adaptation (M2PA) + +M2PA is specified in <>. + +NOTE:: M2PA is not supported in Osmocom SIGTRAN up to this point. Let +us know if we can implement it for you! + + +==== SIGTRAN security + +There simply is none. There are some hints that TLS shall be used +over SCTP in order to provide authenticity and/or confidentiality for +SIGTRAN, but this is not widely used. + +As telecom signaling is not generally carried over public networks, +private networks/links by means of MPLS, VLANs or VPNs such as IPsec +are often used to isolate and/or secure SIGTRAN. + +Under no circumstances should you use unsecured SIGTRAN with +production data over the public internet! + +==== IPv6 support + +SCTP (and thus all the higher layer protocols of the various SIGTRAN +stackings) operates on top of both IPv4 and IPv6. As the entire +underlying IP transport is transparent to the SS7/SCCP applcations, +there is no restriction on whether to use SIGTRAN over IPv4 or IPv6. -- To view, visit https://gerrit.osmocom.org/2371 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I450bfac7444ac9cb7f50c086d87cf7157c2e2a31 Gerrit-PatchSet: 3 Gerrit-Project: osmo-gsm-manuals Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sun Apr 16 01:30:08 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 16 Apr 2017 01:30:08 +0000 Subject: libosmo-sccp[master]: IPA: Override/Set point codes In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2370 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Id556398e1ded3e613cfde7ea8b71aff7a414ff90 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sun Apr 16 01:30:29 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 16 Apr 2017 01:30:29 +0000 Subject: [MERGED] libosmo-sccp[master]: osmo_ss7: Clean up all ASPs established via xua_server upon ... In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: osmo_ss7: Clean up all ASPs established via xua_server upon destroy ...................................................................... osmo_ss7: Clean up all ASPs established via xua_server upon destroy When we destroy a xua_server, we would like to close and destroy any ASPs that were established via that xua_server. In order to do so, we need to add a list of ASPs to the xua_server, which we can iterate. Change-Id: Iff3ed099b817e54e563b70d9ab40f63af63cc2fb --- M include/osmocom/sigtran/osmo_ss7.h M src/osmo_ss7.c 2 files changed, 17 insertions(+), 3 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/include/osmocom/sigtran/osmo_ss7.h b/include/osmocom/sigtran/osmo_ss7.h index 376e399..a8c1c3c 100644 --- a/include/osmocom/sigtran/osmo_ss7.h +++ b/include/osmocom/sigtran/osmo_ss7.h @@ -339,6 +339,7 @@ /*! \ref osmo_xua_server over which we were established */ struct osmo_xua_server *xua_server; + struct llist_head siblings; /*! osmo_stream / libosmo-netif handles */ struct osmo_stream_cli *client; @@ -396,6 +397,9 @@ struct llist_head list; struct osmo_ss7_instance *inst; + /* list of ASPs established via this server */ + struct llist_head asp_list; + struct osmo_stream_srv_link *server; struct { diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index 771501f..44f34fe 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -1050,6 +1050,8 @@ osmo_stream_cli_destroy(asp->client); if (asp->fi) osmo_fsm_inst_term(asp->fi, OSMO_FSM_TERM_REQUEST, NULL); + if (asp->xua_server) + llist_del(&asp->siblings); /* unlink from all ASs we are part of */ llist_for_each_entry(as, &asp->inst->as_list, list) { @@ -1481,6 +1483,8 @@ /* update the ASP reference back to the server over which the * connection came in */ asp->server = srv; + asp->xua_server = oxs; + llist_add_tail(&asp->siblings, &oxs->asp_list); /* update the ASP socket name */ if (asp->sock_name) talloc_free(asp->sock_name); @@ -1575,6 +1579,8 @@ LOGP(DLSS7, LOGL_INFO, "Creating XUA Server %s:%u\n", local_host, local_port); + INIT_LLIST_HEAD(&oxs->asp_list); + oxs->cfg.proto = proto; oxs->cfg.local.port = local_port; oxs->cfg.local.host = talloc_strdup(oxs, local_host); @@ -1614,13 +1620,17 @@ void osmo_ss7_xua_server_destroy(struct osmo_xua_server *xs) { + struct osmo_ss7_asp *asp, *asp2; + if (xs->server) { osmo_stream_srv_link_close(xs->server); osmo_stream_srv_link_destroy(xs->server); } - /* FIXME: add asp_list to xua_server so we can iterate it here - * and close all connections established in relation with this - * server */ + /* iterate and close all connections established in relation + * with this server */ + llist_for_each_entry_safe(asp, asp2, &xs->asp_list, siblings) + osmo_ss7_asp_destroy(asp); + llist_del(&xs->list); talloc_free(xs); } -- To view, visit https://gerrit.osmocom.org/2351 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Iff3ed099b817e54e563b70d9ab40f63af63cc2fb Gerrit-PatchSet: 3 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sun Apr 16 01:30:29 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 16 Apr 2017 01:30:29 +0000 Subject: [MERGED] libosmo-sccp[master]: introduce new osmo_ss7_asp_disconnect() function In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: introduce new osmo_ss7_asp_disconnect() function ...................................................................... introduce new osmo_ss7_asp_disconnect() function Higher-layer code shouldn't have to worry between client and server difference. It just wants to close the underlying connection for a given ASP - which it now can by means of osmo_ss7_asp_disconnect(). Change-Id: I36b089abd281b8edac8830fda2d8e57cc06cd0a7 --- M include/osmocom/sigtran/osmo_ss7.h M src/osmo_ss7.c 2 files changed, 10 insertions(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/include/osmocom/sigtran/osmo_ss7.h b/include/osmocom/sigtran/osmo_ss7.h index a8c1c3c..76403e2 100644 --- a/include/osmocom/sigtran/osmo_ss7.h +++ b/include/osmocom/sigtran/osmo_ss7.h @@ -309,6 +309,7 @@ void osmo_ss7_as_destroy(struct osmo_ss7_as *as); bool osmo_ss7_as_has_asp(struct osmo_ss7_as *as, struct osmo_ss7_asp *asp); +void osmo_ss7_asp_disconnect(struct osmo_ss7_asp *asp); /*********************************************************************** diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index 2d34b53..4aa7be5 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -1543,6 +1543,15 @@ return 0; } +void osmo_ss7_asp_disconnect(struct osmo_ss7_asp *asp) +{ + if (asp->server) + osmo_stream_srv_destroy(asp->server); + /* the close_cb() will handle the remaining cleanup here */ + else if (asp->client) + xua_cli_close_and_reconnect(asp->client); +} + /*********************************************************************** * SS7 xUA Server ***********************************************************************/ -- To view, visit https://gerrit.osmocom.org/2364 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I36b089abd281b8edac8830fda2d8e57cc06cd0a7 Gerrit-PatchSet: 2 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sun Apr 16 01:30:29 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 16 Apr 2017 01:30:29 +0000 Subject: [MERGED] libosmo-sccp[master]: osmo_ss7: avoid crash during disconnect after unknown ASP In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: osmo_ss7: avoid crash during disconnect after unknown ASP ...................................................................... osmo_ss7: avoid crash during disconnect after unknown ASP Change-Id: Ib201f9f480f25ede0f26d4918007ff22fea28824 --- M src/osmo_ss7.c 1 file changed, 3 insertions(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index 95c5fb1..7a5b59e 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -1405,6 +1405,9 @@ LOGP(DLSS7, LOGL_INFO, "%s: SCTP connection closed\n", asp ? asp->cfg.name : "?"); + if (!asp) + return 0; + /* notify ASP FSM and everyone else */ osmo_fsm_inst_dispatch(asp->fi, XUA_ASP_E_SCTP_COMM_DOWN_IND, NULL); -- To view, visit https://gerrit.osmocom.org/2361 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ib201f9f480f25ede0f26d4918007ff22fea28824 Gerrit-PatchSet: 2 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sun Apr 16 01:30:29 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 16 Apr 2017 01:30:29 +0000 Subject: [MERGED] libosmo-sccp[master]: Add new ASP event XUA_ASP_E_SCTP_EST_IND In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: Add new ASP event XUA_ASP_E_SCTP_EST_IND ...................................................................... Add new ASP event XUA_ASP_E_SCTP_EST_IND For classic xUA this is not needed, as the server doesn't have to react to establishment of the SCTP connection. The client will start with an ASP_UP_REQ. However, in upcoming IPA support, the FSM will need to react on this event. Change-Id: Ib10914b27f8761ea44a0fdba96c045821223722a --- M src/osmo_ss7.c M src/xua_asp_fsm.c M src/xua_asp_fsm.h 3 files changed, 7 insertions(+), 1 deletion(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index 7a5b59e..2d34b53 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -1497,6 +1497,7 @@ osmo_stream_srv_set_data(srv, asp); /* send M-SCTP_ESTABLISH.ind to Layer Manager */ + osmo_fsm_inst_dispatch(asp->fi, XUA_ASP_E_SCTP_EST_IND, 0); xua_asp_send_xlm_prim_simple(asp, OSMO_XLM_PRIM_M_SCTP_ESTABLISH, PRIM_OP_INDICATION); return 0; diff --git a/src/xua_asp_fsm.c b/src/xua_asp_fsm.c index f4d9cf0..ce15038 100644 --- a/src/xua_asp_fsm.c +++ b/src/xua_asp_fsm.c @@ -55,6 +55,7 @@ { XUA_ASP_E_SCTP_COMM_DOWN_IND, "SCTP-COMM_DOWN.ind" }, { XUA_ASP_E_SCTP_RESTART_IND, "SCTP-RESTART.ind" }, + { XUA_ASP_E_SCTP_EST_IND, "SCTP-EST.ind" }, { XUA_ASP_E_ASPSM_ASPUP, "ASPSM-ASP_UP" }, { XUA_ASP_E_ASPSM_ASPUP_ACK, "ASPSM-ASP_UP_ACK" }, @@ -368,6 +369,8 @@ * the ASP is already marked as ASP-DOWN at the SGP. */ peer_send(fi, XUA_ASP_E_ASPSM_ASPDN_ACK, NULL); break; + case XUA_ASP_E_SCTP_EST_IND: + break; } } @@ -597,7 +600,8 @@ .in_event_mask = S(XUA_ASP_E_M_ASP_UP_REQ) | S(XUA_ASP_E_ASPSM_ASPUP) | S(XUA_ASP_E_ASPSM_ASPUP_ACK) | - S(XUA_ASP_E_ASPSM_ASPDN), + S(XUA_ASP_E_ASPSM_ASPDN) | + S(XUA_ASP_E_SCTP_EST_IND), .out_state_mask = S(XUA_ASP_S_INACTIVE), .name = "ASP_DOWN", .action = xua_asp_fsm_down, diff --git a/src/xua_asp_fsm.h b/src/xua_asp_fsm.h index ea62484..60e09da 100644 --- a/src/xua_asp_fsm.h +++ b/src/xua_asp_fsm.h @@ -14,6 +14,7 @@ XUA_ASP_E_SCTP_COMM_DOWN_IND, XUA_ASP_E_SCTP_RESTART_IND, + XUA_ASP_E_SCTP_EST_IND, XUA_ASP_E_ASPSM_ASPUP, XUA_ASP_E_ASPSM_ASPUP_ACK, -- To view, visit https://gerrit.osmocom.org/2362 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ib10914b27f8761ea44a0fdba96c045821223722a Gerrit-PatchSet: 2 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sun Apr 16 01:30:30 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 16 Apr 2017 01:30:30 +0000 Subject: [MERGED] libosmo-sccp[master]: m3ua: Generalize + Export function to generate MTP-TRANSFER ... In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: m3ua: Generalize + Export function to generate MTP-TRANSFER xua_msg ...................................................................... m3ua: Generalize + Export function to generate MTP-TRANSFER xua_msg Change-Id: If82956317ec703341514ad81057eceb3d0714f47 --- M src/m3ua.c M src/osmo_ss7_hmrt.c M src/xua_internal.h 3 files changed, 27 insertions(+), 16 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/m3ua.c b/src/m3ua.c index a7ef06c..b204708 100644 --- a/src/m3ua.c +++ b/src/m3ua.c @@ -318,6 +318,30 @@ M3UA_MSG_HEADROOM, name); } +struct xua_msg *m3ua_xfer_from_data(const struct m3ua_data_hdr *data_hdr, + const uint8_t *data, unsigned int data_len) +{ + struct xua_msg *xua = xua_msg_alloc(); + struct xua_msg_part *data_part; + + xua->hdr = XUA_HDR(M3UA_MSGC_XFER, M3UA_XFER_DATA); + /* Network Appearance: Optional */ + /* Routing Context: Conditional */ + /* Protocol Data: Mandatory */ + data_part = talloc_zero(xua, struct xua_msg_part); + OSMO_ASSERT(data_part); + data_part->tag = M3UA_IEI_PROT_DATA; + data_part->len = sizeof(*data_hdr) + data_len; + data_part->dat = talloc_size(data_part, data_part->len); + OSMO_ASSERT(data_part->dat); + memcpy(data_part->dat, data_hdr, sizeof(*data_hdr)); + memcpy(data_part->dat+sizeof(*data_hdr), data, data_len); + llist_add_tail(&data_part->entry, &xua->headers); + /* Correlation Id: Optional */ + + return xua; +} + /*********************************************************************** * ERROR generation ***********************************************************************/ diff --git a/src/osmo_ss7_hmrt.c b/src/osmo_ss7_hmrt.c index 105a542..ce0728b 100644 --- a/src/osmo_ss7_hmrt.c +++ b/src/osmo_ss7_hmrt.c @@ -51,27 +51,12 @@ static struct xua_msg *mtp_prim_to_m3ua(struct osmo_mtp_prim *prim) { struct msgb *msg = prim->oph.msg; - struct xua_msg *xua = xua_msg_alloc(); struct osmo_mtp_transfer_param *param = &prim->u.transfer; - struct xua_msg_part *data_part; struct m3ua_data_hdr data_hdr; mtp_xfer_param_to_m3ua_dh(&data_hdr, param); - xua->hdr = XUA_HDR(M3UA_MSGC_XFER, M3UA_XFER_DATA); - /* Network Appearance: Optional */ - /* Routing Context: Conditional */ - /* Protocol Data: Mandatory */ - data_part = talloc_zero(xua, struct xua_msg_part); - data_part->tag = M3UA_IEI_PROT_DATA; - data_part->len = sizeof(data_hdr) + msgb_l2len(msg); - data_part->dat = talloc_size(data_part, data_part->len); - memcpy(data_part->dat, &data_hdr, sizeof(data_hdr)); - memcpy(data_part->dat+sizeof(data_hdr), msgb_l2(msg), msgb_l2len(msg)); - llist_add_tail(&data_part->entry, &xua->headers); - /* Correlation Id: Optional */ - - return xua; + return m3ua_xfer_from_data(&data_hdr, msgb_l2(msg), msgb_l2len(msg)); } /* delivery given XUA message to given SS7 user */ diff --git a/src/xua_internal.h b/src/xua_internal.h index 31c941e..3831f56 100644 --- a/src/xua_internal.h +++ b/src/xua_internal.h @@ -25,6 +25,8 @@ int m3ua_rx_msg(struct osmo_ss7_asp *asp, struct msgb *msg); struct msgb *m3ua_msgb_alloc(const char *name); +struct xua_msg *m3ua_xfer_from_data(const struct m3ua_data_hdr *data_hdr, + const uint8_t *data, unsigned int data_len); struct m3ua_data_hdr *data_hdr_from_m3ua(struct xua_msg *xua); void m3ua_dh_to_xfer_param(struct osmo_mtp_transfer_param *param, const struct m3ua_data_hdr *mdh); -- To view, visit https://gerrit.osmocom.org/2360 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: If82956317ec703341514ad81057eceb3d0714f47 Gerrit-PatchSet: 2 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sun Apr 16 01:30:30 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 16 Apr 2017 01:30:30 +0000 Subject: [MERGED] libosmo-sccp[master]: osmo_ss7: Fix protocol of dynamically allocated ASPs In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: osmo_ss7: Fix protocol of dynamically allocated ASPs ...................................................................... osmo_ss7: Fix protocol of dynamically allocated ASPs When dynamically allocating ASPs, we used the hardcoded M3UA protocol, which is of course wrong in case of SUA or other protocols. Let's use the xua_server's configured protocol for the created ASPs. Change-Id: I07832cbaf1ca42f0c7df399e4f96599034b72816 --- M src/osmo_ss7.c 1 file changed, 1 insertion(+), 1 deletion(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index 44f34fe..95c5fb1 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -1464,7 +1464,7 @@ static uint32_t dyn_asp_num = 0; snprintf(namebuf, sizeof(namebuf), "asp-dyn-%u", dyn_asp_num++); asp = osmo_ss7_asp_find_or_create(oxs->inst, namebuf, 0, 0, - OSMO_SS7_ASP_PROT_M3UA); + oxs->cfg.proto); if (asp) { LOGP(DLSS7, LOGL_INFO, "%s: created dynamicASP %s\n", sock_name, asp->cfg.name); -- To view, visit https://gerrit.osmocom.org/2359 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I07832cbaf1ca42f0c7df399e4f96599034b72816 Gerrit-PatchSet: 2 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sun Apr 16 15:28:40 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 16 Apr 2017 15:28:40 +0000 Subject: [PATCH] libosmocore[master]: osmo_fsm: Lookup functions to find FSM Instance by name or ID Message-ID: Review at https://gerrit.osmocom.org/2372 osmo_fsm: Lookup functions to find FSM Instance by name or ID Introduce two lookup helper functions to resolve a fsm_instance based on the FSM and name or ID. Also, add related test cases. Change-Id: I707f3ed2795c28a924e64adc612d378c21baa815 --- M include/osmocom/core/fsm.h M src/fsm.c M tests/fsm/fsm_test.c M tests/fsm/fsm_test.err 4 files changed, 45 insertions(+), 11 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/72/2372/1 diff --git a/include/osmocom/core/fsm.h b/include/osmocom/core/fsm.h index 3a1f233..f42dd0c 100644 --- a/include/osmocom/core/fsm.h +++ b/include/osmocom/core/fsm.h @@ -141,6 +141,10 @@ int osmo_fsm_register(struct osmo_fsm *fsm); void osmo_fsm_unregister(struct osmo_fsm *fsm); struct osmo_fsm *osmo_fsm_find_by_name(const char *name); +struct osmo_fsm_inst *osmo_fsm_inst_find_by_name(const struct osmo_fsm *fsm, + const char *name); +struct osmo_fsm_inst *osmo_fsm_inst_find_by_id(const struct osmo_fsm *fsm, + const char *id); struct osmo_fsm_inst *osmo_fsm_inst_alloc(struct osmo_fsm *fsm, void *ctx, void *priv, int log_level, const char *id); struct osmo_fsm_inst *osmo_fsm_inst_alloc_child(struct osmo_fsm *fsm, diff --git a/src/fsm.c b/src/fsm.c index 0e2c9be..7b2be70 100644 --- a/src/fsm.c +++ b/src/fsm.c @@ -113,6 +113,30 @@ return NULL; } +struct osmo_fsm_inst *osmo_fsm_inst_find_by_name(const struct osmo_fsm *fsm, + const char *name) +{ + struct osmo_fsm_inst *fi; + + llist_for_each_entry(fi, &fsm->instances, list) { + if (!strcmp(name, fi->name)) + return fi; + } + return NULL; +} + +struct osmo_fsm_inst *osmo_fsm_inst_find_by_id(const struct osmo_fsm *fsm, + const char *id) +{ + struct osmo_fsm_inst *fi; + + llist_for_each_entry(fi, &fsm->instances, list) { + if (!strcmp(id, fi->id)) + return fi; + } + return NULL; +} + /*! \brief register a FSM with the core * * A FSM descriptor needs to be registered with the core before any diff --git a/tests/fsm/fsm_test.c b/tests/fsm/fsm_test.c index 7a64421..c3ab91c 100644 --- a/tests/fsm/fsm_test.c +++ b/tests/fsm/fsm_test.c @@ -94,7 +94,7 @@ struct osmo_fsm_inst *fi; LOGP(DMAIN, LOGL_INFO, "Checking FSM allocation\n"); - fi = osmo_fsm_inst_alloc(&fsm, g_ctx, NULL, LOGL_DEBUG, NULL); + fi = osmo_fsm_inst_alloc(&fsm, g_ctx, NULL, LOGL_DEBUG, "my_id"); OSMO_ASSERT(fi); OSMO_ASSERT(fi->fsm == &fsm); OSMO_ASSERT(!strncmp(osmo_fsm_inst_name(fi), fsm.name, strlen(fsm.name))); @@ -143,10 +143,16 @@ log_add_target(stderr_target); log_set_print_filename(stderr_target, 0); - g_ctx = NULL; - osmo_fsm_register(&fsm); + g_ctx = NULL; + OSMO_ASSERT(osmo_fsm_find_by_name(fsm.name) == NULL); + osmo_fsm_register(&fsm); + OSMO_ASSERT(osmo_fsm_find_by_name(fsm.name) == &fsm); + + OSMO_ASSERT(osmo_fsm_inst_find_by_name(&fsm, "my_id") == NULL); finst = foo(); + OSMO_ASSERT(osmo_fsm_inst_find_by_id(&fsm, "my_id") == finst); + OSMO_ASSERT(osmo_fsm_inst_find_by_name(&fsm, "Test FSM(my_id)") == finst); while (1) { osmo_select_main(0); diff --git a/tests/fsm/fsm_test.err b/tests/fsm/fsm_test.err index c9021bb..6f031be 100644 --- a/tests/fsm/fsm_test.err +++ b/tests/fsm/fsm_test.err @@ -1,11 +1,11 @@ Checking FSM allocation -Test FSM{NULL}: Allocated -Test FSM{NULL}: Received Event 1 -Test FSM{NULL}: Event 1 not permitted -Test FSM{NULL}: Received Event 0 -Test FSM{NULL}: state_chg to ONE -Test FSM{ONE}: Received Event 1 -Test FSM{ONE}: state_chg to TWO -Test FSM{TWO}: Timeout of T2342 +Test FSM(my_id){NULL}: Allocated +Test FSM(my_id){NULL}: Received Event 1 +Test FSM(my_id){NULL}: Event 1 not permitted +Test FSM(my_id){NULL}: Received Event 0 +Test FSM(my_id){NULL}: state_chg to ONE +Test FSM(my_id){ONE}: Received Event 1 +Test FSM(my_id){ONE}: state_chg to TWO +Test FSM(my_id){TWO}: Timeout of T2342 Timer  \ No newline at end of file -- To view, visit https://gerrit.osmocom.org/2372 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I707f3ed2795c28a924e64adc612d378c21baa815 Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Sun Apr 16 15:28:41 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 16 Apr 2017 15:28:41 +0000 Subject: [PATCH] libosmocore[master]: fsm: Re-set fsm_inst->T to 0 after timer expiration Message-ID: Review at https://gerrit.osmocom.org/2373 fsm: Re-set fsm_inst->T to 0 after timer expiration If the user starts the FSM timer with a given timer number during fsm_inst_state_chg() with a timeout, we should remove that "T" number after timer expiration. Otherwise it might be confusing if e.g. the VTY interface shows FSM instances with a certain timer number assigned, but that timer is not actually running anymore. Change-Id: I71167ec1000dc4c6954d851d3b92f6bf12984925 --- M src/fsm.c 1 file changed, 4 insertions(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/73/2373/1 diff --git a/src/fsm.c b/src/fsm.c index 7b2be70..9e6ef15 100644 --- a/src/fsm.c +++ b/src/fsm.c @@ -178,13 +178,16 @@ if (fsm->timer_cb) { int rc = fsm->timer_cb(fi); - if (rc != 1) + if (rc != 1) { + fi->T = 0; return; + } LOGPFSM(fi, "timer_cb requested termination\n"); } else LOGPFSM(fi, "No timer_cb, automatic termination\n"); /* if timer_cb returns 1 or there is no timer_cb */ + fi->T = 0; osmo_fsm_inst_term(fi, OSMO_FSM_TERM_TIMEOUT, &T); } -- To view, visit https://gerrit.osmocom.org/2373 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I71167ec1000dc4c6954d851d3b92f6bf12984925 Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Sun Apr 16 15:37:17 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 16 Apr 2017 15:37:17 +0000 Subject: libosmocore[master]: fsm: Re-set fsm_inst->T to 0 after timer expiration In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2373 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I71167ec1000dc4c6954d851d3b92f6bf12984925 Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sun Apr 16 15:37:19 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 16 Apr 2017 15:37:19 +0000 Subject: libosmocore[master]: osmo_fsm: Lookup functions to find FSM Instance by name or ID In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2372 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I707f3ed2795c28a924e64adc612d378c21baa815 Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sun Apr 16 17:23:21 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 16 Apr 2017 17:23:21 +0000 Subject: [PATCH] libosmocore[master]: ctrl: Allow installation of additional node lookup helpers Message-ID: Review at https://gerrit.osmocom.org/2374 ctrl: Allow installation of additional node lookup helpers The existing code assumes that the main application knows about all control command nodes and can thus present one lookup function. As libraries are getting their own control interface handling, this is too restrictive, and we need a way how library code can dynamically register more node lookup helpers. We can now do this by means of a ctrl_lookup_register() function. Change-Id: Ib69908d1c57f5bb721d5496e3b4a5258fca450e3 --- M include/osmocom/ctrl/control_if.h M src/ctrl/control_if.c 2 files changed, 43 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/74/2374/1 diff --git a/include/osmocom/ctrl/control_if.h b/include/osmocom/ctrl/control_if.h index f2af1db..a740a96 100644 --- a/include/osmocom/ctrl/control_if.h +++ b/include/osmocom/ctrl/control_if.h @@ -29,3 +29,5 @@ ctrl_cmd_lookup lookup); struct ctrl_connection *osmo_ctrl_conn_alloc(void *ctx, void *data); int ctrl_cmd_handle(struct ctrl_handle *ctrl, struct ctrl_cmd *cmd, void *data); + +int ctrl_lookup_register(ctrl_cmd_lookup lookup); diff --git a/src/ctrl/control_if.c b/src/ctrl/control_if.c index f49d639..5730850 100644 --- a/src/ctrl/control_if.c +++ b/src/ctrl/control_if.c @@ -61,6 +61,13 @@ vector ctrl_node_vec; +/* global list of control interface lookup helpers */ +struct lookup_helper { + struct llist_head list; + ctrl_cmd_lookup lookup; +}; +static LLIST_HEAD(ctrl_lookup_helpers); + int ctrl_parse_get_num(vector vline, int i, long *num) { char *token, *tmp; @@ -225,12 +232,21 @@ } for (i=0;ilookup) rc = ctrl->lookup(data, vline, &node, &cmd->node, &i); else rc = 0; + + if (!rc) { + llist_for_each_entry(lh, &ctrl_lookup_helpers, list) { + rc = lh->lookup(data, vline, &node, &cmd->node, &i); + if (rc) + break; + } + } if (rc == 1) { /* do nothing */ @@ -733,3 +749,28 @@ talloc_free(ctrl); return NULL; } + +/*! \brief Install a lookup helper function for control nodes + * This function is used by e.g. library code to install lookup helpers + * for additional nodes in the control interface. + * \param[in] lookup The lookup helper function + * \retuns - on success; negative on error. + */ +int ctrl_lookup_register(ctrl_cmd_lookup lookup) +{ + struct lookup_helper *lh; + + /* avoid double registration */ + llist_for_each_entry(lh, &ctrl_lookup_helpers, list) { + if (lh->lookup == lookup) + return -EEXIST; + } + + lh = talloc_zero(NULL, struct lookup_helper); + if (!lh) + return -ENOMEM; + + lh->lookup = lookup; + llist_add_tail(&lh->list, &ctrl_lookup_helpers); + return 0; +} -- To view, visit https://gerrit.osmocom.org/2374 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ib69908d1c57f5bb721d5496e3b4a5258fca450e3 Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Sun Apr 16 17:23:21 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 16 Apr 2017 17:23:21 +0000 Subject: [PATCH] libosmocore[master]: control_if: Add API to initialize control interface without ... Message-ID: Review at https://gerrit.osmocom.org/2375 control_if: Add API to initialize control interface without TCP port bind When executing test cases, we don't want to bind to a local TCP port, as we cannot make assumptions as to which ports are actually free. Change-Id: I5717f9dd92d1f143f069cecd4b4c8ba3d03b25f8 --- M include/osmocom/ctrl/control_if.h M src/ctrl/control_if.c 2 files changed, 62 insertions(+), 18 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/75/2375/1 diff --git a/include/osmocom/ctrl/control_if.h b/include/osmocom/ctrl/control_if.h index a740a96..0d37959 100644 --- a/include/osmocom/ctrl/control_if.h +++ b/include/osmocom/ctrl/control_if.h @@ -21,6 +21,7 @@ int ctrl_cmd_send(struct osmo_wqueue *queue, struct ctrl_cmd *cmd); int ctrl_cmd_send_trap(struct ctrl_handle *ctrl, const char *name, char *value); +struct ctrl_handle *ctrl_handle_alloc(void *ctx, void *data, ctrl_cmd_lookup lookup); struct ctrl_handle *ctrl_interface_setup(void *data, uint16_t port, ctrl_cmd_lookup lookup); struct ctrl_handle *ctrl_interface_setup_dynip(void *data, diff --git a/src/ctrl/control_if.c b/src/ctrl/control_if.c index 5730850..82a78d8 100644 --- a/src/ctrl/control_if.c +++ b/src/ctrl/control_if.c @@ -694,6 +694,66 @@ return ctrl_interface_setup_dynip(data, "127.0.0.1", port, lookup); } +static int ctrl_initialized = 0; + +/* global ctrl initialization */ +static int ctrl_init(void) +{ + int ret; + + if (ctrl_initialized) + return 0; + + ctrl_node_vec = vector_init(5); + if (!ctrl_node_vec) + goto err; + + ret = ctrl_cmd_install(CTRL_NODE_ROOT, &cmd_rate_ctr); + if (ret) + goto err_vec; + ret = ctrl_cmd_install(CTRL_NODE_ROOT, &cmd_counter); + if (ret) + goto err_vec; + + ret = osmo_fsm_ctrl_cmds_install(); + if (ret) + goto err_vec; + + ctrl_initialized = 1; + return 0; + +err_vec: + vector_free(ctrl_node_vec); + ctrl_node_vec = NULL; +err: + return -1; +} + +/*! \brief Allocate a CTRL interface handle + * \param[in] ctx Tallo callocation context to be used + * \param[in] data Pointer which will be made available to each + set_..() get_..() verify_..() control command function + * \param[in] lookup Lookup function pointer, can be NULL + * \returns ctrl_handle pointer or NULL in case of errors + */ +struct ctrl_handle *ctrl_handle_alloc(void *ctx, void *data, ctrl_cmd_lookup lookup) +{ + struct ctrl_handle *ctrl; + + ctrl_init(); + + ctrl = talloc_zero(ctx, struct ctrl_handle); + if (!ctrl) + return NULL; + + INIT_LLIST_HEAD(&ctrl->ccon_list); + + ctrl->data = data; + ctrl->lookup = lookup; + + return ctrl; +} + /*! \brief Setup CTRL interface on a given address * \param[in] data Pointer which will be made available to each set_..() get_..() verify_..() control command function @@ -710,18 +770,9 @@ int ret; struct ctrl_handle *ctrl; - ctrl = talloc_zero(data, struct ctrl_handle); + ctrl = ctrl_handle_alloc(data, data, lookup); if (!ctrl) return NULL; - - INIT_LLIST_HEAD(&ctrl->ccon_list); - - ctrl->data = data; - ctrl->lookup = lookup; - - ctrl_node_vec = vector_init(5); - if (!ctrl_node_vec) - goto err; /* Listen for control connections */ ctrl->listen_fd.cb = listen_fd_cb; @@ -740,14 +791,6 @@ LOGP(DLCTRL, LOGL_NOTICE, "CTRL at %s %u\n", bind_addr, port); return ctrl; -err_vec: - vector_free(ctrl_node_vec); - ctrl_node_vec = NULL; -err: - LOGP(DLCTRL, LOGL_ERROR, "Cannot bind CTRL at %s %u\n", - bind_addr, port); - talloc_free(ctrl); - return NULL; } /*! \brief Install a lookup helper function for control nodes -- To view, visit https://gerrit.osmocom.org/2375 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I5717f9dd92d1f143f069cecd4b4c8ba3d03b25f8 Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Sun Apr 16 17:23:22 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 16 Apr 2017 17:23:22 +0000 Subject: [PATCH] libosmocore[master]: control_if: Add helper function for 'local execution' of con... Message-ID: Review at https://gerrit.osmocom.org/2376 control_if: Add helper function for 'local execution' of control command Sometimes (particularly when testing), we may want to parse+execute an arbitrary control command simply form a string buffer, rather than from a msgb. Let's add a helper for that. Change-Id: Iaca748e0d942bb2a1ee7c2776b37485e1439eb0c --- M include/osmocom/ctrl/control_if.h M src/ctrl/control_if.c M tests/Makefile.am M tests/fsm/fsm_test.c 4 files changed, 31 insertions(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/76/2376/1 diff --git a/include/osmocom/ctrl/control_if.h b/include/osmocom/ctrl/control_if.h index 0d37959..4cd3369 100644 --- a/include/osmocom/ctrl/control_if.h +++ b/include/osmocom/ctrl/control_if.h @@ -30,5 +30,6 @@ ctrl_cmd_lookup lookup); struct ctrl_connection *osmo_ctrl_conn_alloc(void *ctx, void *data); int ctrl_cmd_handle(struct ctrl_handle *ctrl, struct ctrl_cmd *cmd, void *data); +struct ctrl_cmd *ctrl_cmd_exec_from_string(struct ctrl_handle *ch, const char *cmdstr); int ctrl_lookup_register(ctrl_cmd_lookup lookup); diff --git a/src/ctrl/control_if.c b/src/ctrl/control_if.c index 82a78d8..4f357c5 100644 --- a/src/ctrl/control_if.c +++ b/src/ctrl/control_if.c @@ -817,3 +817,31 @@ llist_add_tail(&lh->list, &ctrl_lookup_helpers); return 0; } + +/*! \brief Helper for "local execution" of a CTRL command from a string + * The function will parse + execute the given control command string + * and return a corresponding ctrl_cmd. Caller is responsible to + * talloc_freee() the return value. + * \param[in] Control Interface Command String + * \returns parsed command, including reply; NULL on error */ +struct ctrl_cmd *ctrl_cmd_exec_from_string(struct ctrl_handle *ch, const char *cmdstr) +{ + struct msgb *msg = msgb_alloc(1024, "ctrl-cmd"); + struct ctrl_cmd *cmd; + + if (!msg) + return NULL; + msg->l2h = msg->data; + osmo_strlcpy((char *)msg->data, cmdstr, msgb_tailroom(msg)); + msgb_put(msg, strlen(cmdstr)); + + cmd = ctrl_cmd_parse(ch, msg); + msgb_free(msg); + if (!cmd) + return NULL; + if (ctrl_cmd_handle(ch, cmd, NULL) < 0) { + talloc_free(cmd); + return NULL; + } + return cmd; +} diff --git a/tests/Makefile.am b/tests/Makefile.am index 352b5a7..ab80c1a 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -139,7 +139,7 @@ oap_oap_test_LDADD = $(top_builddir)/src/gsm/libosmogsm.la $(top_builddir)/src/libosmocore.la fsm_fsm_test_SOURCES = fsm/fsm_test.c -fsm_fsm_test_LDADD = $(top_builddir)/src/libosmocore.la +fsm_fsm_test_LDADD = $(top_builddir)/src/libosmocore.la $(top_builddir)/src/ctrl/libosmoctrl.la write_queue_wqueue_test_SOURCES = write_queue/wqueue_test.c write_queue_wqueue_test_LDADD = $(top_builddir)/src/libosmocore.la diff --git a/tests/fsm/fsm_test.c b/tests/fsm/fsm_test.c index c3ab91c..7aade98 100644 --- a/tests/fsm/fsm_test.c +++ b/tests/fsm/fsm_test.c @@ -8,6 +8,7 @@ #include #include #include +#include enum { DMAIN, -- To view, visit https://gerrit.osmocom.org/2376 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Iaca748e0d942bb2a1ee7c2776b37485e1439eb0c Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Sun Apr 16 17:23:22 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 16 Apr 2017 17:23:22 +0000 Subject: [PATCH] libosmocore[master]: control_if: Add control interface commands for FSMs Message-ID: Review at https://gerrit.osmocom.org/2377 control_if: Add control interface commands for FSMs This allows programmatic access to introspection of FSM instances, which is quite handy from e.g. external test cases: Send a message to the code, then use the CTRL interface to check if that message has triggered the right kind of state transition. Change-Id: I2822513ac63a3d9b87b3eefc7c4e6b585c555ee2 --- M include/osmocom/ctrl/control_cmd.h M src/ctrl/Makefile.am M src/ctrl/control_if.c A src/ctrl/fsm_ctrl_commands.c M tests/fsm/fsm_test.c M tests/fsm/fsm_test.err 6 files changed, 226 insertions(+), 12 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/77/2377/1 diff --git a/include/osmocom/ctrl/control_cmd.h b/include/osmocom/ctrl/control_cmd.h index d9092f3..3cef9d8 100644 --- a/include/osmocom/ctrl/control_cmd.h +++ b/include/osmocom/ctrl/control_cmd.h @@ -18,6 +18,8 @@ CTRL_NODE_BTS, /* BTS specific (net.btsN.) */ CTRL_NODE_TRX, /* TRX specific (net.btsN.trxM.) */ CTRL_NODE_TS, /* TS specific (net.btsN.trxM.tsI.) */ + CTRL_NODE_FSM, /* Finite State Machine (description) */ + CTRL_NODE_FSM_INST, /* Finite State Machine (instance) */ _LAST_CTRL_NODE }; diff --git a/src/ctrl/Makefile.am b/src/ctrl/Makefile.am index 1817cac..e8d55e6 100644 --- a/src/ctrl/Makefile.am +++ b/src/ctrl/Makefile.am @@ -8,7 +8,7 @@ if ENABLE_CTRL lib_LTLIBRARIES = libosmoctrl.la -libosmoctrl_la_SOURCES = control_cmd.c control_if.c +libosmoctrl_la_SOURCES = control_cmd.c control_if.c fsm_ctrl_commands.c libosmoctrl_la_LDFLAGS = $(LTLDFLAGS_OSMOCTRL) $(TALLOC_LIBS) -version-info $(LIBVERSION) -no-undefined libosmoctrl_la_LIBADD = \ diff --git a/src/ctrl/control_if.c b/src/ctrl/control_if.c index 4f357c5..081c2b5 100644 --- a/src/ctrl/control_if.c +++ b/src/ctrl/control_if.c @@ -789,6 +789,10 @@ if (ret) goto err_vec; + ret = osmo_fsm_ctrl_cmds_install(); + if (ret) + goto err_vec; + LOGP(DLCTRL, LOGL_NOTICE, "CTRL at %s %u\n", bind_addr, port); return ctrl; } diff --git a/src/ctrl/fsm_ctrl_commands.c b/src/ctrl/fsm_ctrl_commands.c new file mode 100644 index 0000000..0dfc396 --- /dev/null +++ b/src/ctrl/fsm_ctrl_commands.c @@ -0,0 +1,175 @@ +#include +#include + +#include + +#include +#include + +/*! \brief control interface lookup function for FSM's + * \param[in] data Private data passed to controlif_setup() + * \param[in] vline Vector of the line holding the command string + * \param[out] node_type type (CTRL_NODE_) that was determined + * \param[out] node_data private data of node that was determined + * \param i Current index into vline, up to which it is parsed + */ +static int fsm_ctrl_node_lookup(void *data, vector vline, int *node_type, + void **node_data, int *i) +{ + struct osmo_fsm *fsm = NULL; + struct osmo_fsm_inst *fi = NULL;; + const char *token = vector_slot(vline, *i); + + switch (*node_type) { + case CTRL_NODE_ROOT: + if (!strcmp(token, "fsm")) { + const char *fsm_name; + (*i)++; + fsm_name = vector_lookup(vline, *i); + if (!fsm_name) + goto err_index; + fsm = osmo_fsm_find_by_name(fsm_name); + if (!fsm) + goto err_missing; + *node_data = fsm; + *node_type = CTRL_NODE_FSM; + } + break; + case CTRL_NODE_FSM: + fsm = *node_data; + if (!strcmp(token, "name")) { + const char *inst_name; + (*i)++; + inst_name = vector_lookup(vline, *i); + if (!inst_name) + goto err_index; + fi = osmo_fsm_inst_find_by_name(fsm, inst_name); + if (!fi) + goto err_missing; + *node_data = fi; + *node_type = CTRL_NODE_FSM_INST; + } else if (!strcmp(token, "id")) { + const char *inst_id; + (*i)++; + inst_id = vector_lookup(vline, *i); + if (!inst_id) + goto err_index; + fi = osmo_fsm_inst_find_by_id(fsm, inst_id); + if (!fi) + goto err_missing; + *node_data = fi; + *node_type = CTRL_NODE_FSM_INST; + } + break; + default: + return 0; + } + + return 1; + +err_index: + return -ERANGE; +err_missing: + return -ENODEV; +} + +static int get_fsm_inst_state(struct ctrl_cmd *cmd, void *data) +{ + struct osmo_fsm_inst *fi = cmd->node; + + if (!fi) { + cmd->reply = "No such FSM found"; + return CTRL_CMD_ERROR; + } + + cmd->reply = talloc_strdup(cmd, osmo_fsm_state_name(fi->fsm, fi->state)); + return CTRL_CMD_REPLY; +} +CTRL_CMD_DEFINE_RO(fsm_inst_state, "state"); + +static int get_fsm_inst_parent_name(struct ctrl_cmd *cmd, void *data) +{ + struct osmo_fsm_inst *fi = cmd->node; + + if (!fi) { + cmd->reply = "No such FSM found"; + return CTRL_CMD_ERROR; + } + if (!fi->proc.parent) { + cmd->reply = "No parent"; + return CTRL_CMD_ERROR; + } + cmd->reply = talloc_strdup(cmd, fi->proc.parent->name); + return CTRL_CMD_REPLY; +} +CTRL_CMD_DEFINE_RO(fsm_inst_parent_name, "parent-name"); + +static int get_fsm_inst_timer(struct ctrl_cmd *cmd, void *data) +{ + struct osmo_fsm_inst *fi = cmd->node; + struct timeval remaining; + + if (!fi) { + cmd->reply = "No such FSM found"; + return CTRL_CMD_ERROR; + } + if (osmo_timer_remaining(&fi->timer, NULL, &remaining) < 0) + cmd->reply = "0,0,0"; + else + cmd->reply = talloc_asprintf(cmd, "%u,%ld,%ld", fi->T, remaining.tv_sec, remaining.tv_usec); + + return CTRL_CMD_REPLY; +} +CTRL_CMD_DEFINE_RO(fsm_inst_timer, "timer"); + + +static int get_fsm_inst_dump(struct ctrl_cmd *cmd, void *data) +{ + struct osmo_fsm_inst *fi = cmd->node; + struct osmo_fsm_inst *child; + + if (!fi) { + cmd->reply = "No such FSM found"; + return CTRL_CMD_ERROR; + } + + /* Fixed Part: Name, ID, log_level, state, timer number */ + cmd->reply = talloc_asprintf(cmd, "'%s','%s','%s','%s',%u", fi->name, fi->id, + log_level_str(fi->log_level), + osmo_fsm_state_name(fi->fsm, fi->state), fi->T); + + /* Variable Parts below */ + if (fi->T) { + struct timeval remaining; + int rc; + rc = osmo_timer_remaining(&fi->timer, NULL, &remaining); + if (rc == 0) { + cmd->reply = talloc_asprintf_append(cmd->reply, ",timeout_sec=%ld,timeout_usec=%ld", + remaining.tv_sec, remaining.tv_usec); + } + } + + if (fi->proc.parent) + cmd->reply = talloc_asprintf_append(cmd->reply, ",parent='%s'", fi->proc.parent->name); + + llist_for_each_entry(child, &fi->proc.children, list) { + cmd->reply = talloc_asprintf_append(cmd->reply, ",child='%s'", child->name); + } + + return CTRL_CMD_REPLY; +} + +CTRL_CMD_DEFINE_RO(fsm_inst_dump, "dump"); + +int osmo_fsm_ctrl_cmds_install(void) +{ + int rc = 0; + + rc |= ctrl_cmd_install(CTRL_NODE_FSM_INST, &cmd_fsm_inst_dump); + rc |= ctrl_cmd_install(CTRL_NODE_FSM_INST, &cmd_fsm_inst_state); + rc |= ctrl_cmd_install(CTRL_NODE_FSM_INST, &cmd_fsm_inst_parent_name); + rc |= ctrl_cmd_install(CTRL_NODE_FSM_INST, &cmd_fsm_inst_timer); + rc |= ctrl_lookup_register(fsm_ctrl_node_lookup); + + return rc; +} diff --git a/tests/fsm/fsm_test.c b/tests/fsm/fsm_test.c index 7aade98..eea8b22 100644 --- a/tests/fsm/fsm_test.c +++ b/tests/fsm/fsm_test.c @@ -84,15 +84,38 @@ }; static struct osmo_fsm fsm = { - .name = "Test FSM", + .name = "Test_FSM", .states = test_fsm_states, .num_states = ARRAY_SIZE(test_fsm_states), .log_subsys = DMAIN, }; +static struct ctrl_handle *g_ctrl; + +static struct ctrl_cmd *exec_ctrl_cmd(const char *cmdstr) +{ + struct ctrl_cmd *cmd; + return ctrl_cmd_exec_from_string(g_ctrl, cmdstr); + OSMO_ASSERT(cmd); + return cmd; +} + +static void assert_cmd_reply(const char *cmdstr, const char *expres) +{ + struct ctrl_cmd *cmd; + + cmd = exec_ctrl_cmd(cmdstr); + if (strcmp(cmd->reply, expres)) { + fprintf(stderr, "Reply '%s' doesn't match expected '%s'\n", cmd->reply, expres); + OSMO_ASSERT(0); + } + talloc_free(cmd); +} + static struct osmo_fsm_inst *foo(void) { struct osmo_fsm_inst *fi; + struct ctrl_cmd *cmd; LOGP(DMAIN, LOGL_INFO, "Checking FSM allocation\n"); fi = osmo_fsm_inst_alloc(&fsm, g_ctx, NULL, LOGL_DEBUG, "my_id"); @@ -101,20 +124,30 @@ OSMO_ASSERT(!strncmp(osmo_fsm_inst_name(fi), fsm.name, strlen(fsm.name))); OSMO_ASSERT(fi->state == ST_NULL); OSMO_ASSERT(fi->log_level == LOGL_DEBUG); + assert_cmd_reply("GET 1 fsm.Test_FSM.id.my_id.state", "NULL"); + assert_cmd_reply("GET 1 fsm.Test_FSM.id.my_id.timer", "0,0,0"); /* Try invalid state transition */ osmo_fsm_inst_dispatch(fi, EV_B, (void *) 42); OSMO_ASSERT(fi->state == ST_NULL); + assert_cmd_reply("GET 1 fsm.Test_FSM.id.my_id.state", "NULL"); + /* Legitimate state transition */ osmo_fsm_inst_dispatch(fi, EV_A, (void *) 23); OSMO_ASSERT(fi->state == ST_ONE); + assert_cmd_reply("GET 1 fsm.Test_FSM.id.my_id.state", "ONE"); /* Legitimate transition with timer */ fsm.timer_cb = test_fsm_tmr_cb; osmo_fsm_inst_dispatch(fi, EV_B, (void *) 42); OSMO_ASSERT(fi->state == ST_TWO); + assert_cmd_reply("GET 1 fsm.Test_FSM.id.my_id.state", "TWO"); + cmd = exec_ctrl_cmd("GET 2 fsm.Test_FSM.id.my_id.dump"); + const char *exp = "'Test_FSM(my_id)','my_id','DEBUG','TWO',2342,timeout_sec="; + OSMO_ASSERT(!strncmp(cmd->reply, exp, strlen(exp))); + talloc_free(cmd); return fi; } @@ -143,7 +176,7 @@ stderr_target = log_target_create_stderr(); log_add_target(stderr_target); log_set_print_filename(stderr_target, 0); - + g_ctrl = ctrl_handle_alloc(NULL, NULL, NULL); g_ctx = NULL; OSMO_ASSERT(osmo_fsm_find_by_name(fsm.name) == NULL); @@ -153,7 +186,7 @@ OSMO_ASSERT(osmo_fsm_inst_find_by_name(&fsm, "my_id") == NULL); finst = foo(); OSMO_ASSERT(osmo_fsm_inst_find_by_id(&fsm, "my_id") == finst); - OSMO_ASSERT(osmo_fsm_inst_find_by_name(&fsm, "Test FSM(my_id)") == finst); + OSMO_ASSERT(osmo_fsm_inst_find_by_name(&fsm, "Test_FSM(my_id)") == finst); while (1) { osmo_select_main(0); diff --git a/tests/fsm/fsm_test.err b/tests/fsm/fsm_test.err index 6f031be..17a2f2e 100644 --- a/tests/fsm/fsm_test.err +++ b/tests/fsm/fsm_test.err @@ -1,11 +1,11 @@ Checking FSM allocation -Test FSM(my_id){NULL}: Allocated -Test FSM(my_id){NULL}: Received Event 1 -Test FSM(my_id){NULL}: Event 1 not permitted -Test FSM(my_id){NULL}: Received Event 0 -Test FSM(my_id){NULL}: state_chg to ONE -Test FSM(my_id){ONE}: Received Event 1 -Test FSM(my_id){ONE}: state_chg to TWO -Test FSM(my_id){TWO}: Timeout of T2342 +Test_FSM(my_id){NULL}: Allocated +Test_FSM(my_id){NULL}: Received Event 1 +Test_FSM(my_id){NULL}: Event 1 not permitted +Test_FSM(my_id){NULL}: Received Event 0 +Test_FSM(my_id){NULL}: state_chg to ONE +Test_FSM(my_id){ONE}: Received Event 1 +Test_FSM(my_id){ONE}: state_chg to TWO +Test_FSM(my_id){TWO}: Timeout of T2342 Timer  \ No newline at end of file -- To view, visit https://gerrit.osmocom.org/2377 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I2822513ac63a3d9b87b3eefc7c4e6b585c555ee2 Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Sun Apr 16 17:23:53 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 16 Apr 2017 17:23:53 +0000 Subject: [MERGED] libosmocore[master]: osmo_fsm: Lookup functions to find FSM Instance by name or ID In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: osmo_fsm: Lookup functions to find FSM Instance by name or ID ...................................................................... osmo_fsm: Lookup functions to find FSM Instance by name or ID Introduce two lookup helper functions to resolve a fsm_instance based on the FSM and name or ID. Also, add related test cases. Change-Id: I707f3ed2795c28a924e64adc612d378c21baa815 --- M include/osmocom/core/fsm.h M src/fsm.c M tests/fsm/fsm_test.c M tests/fsm/fsm_test.err 4 files changed, 45 insertions(+), 11 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/include/osmocom/core/fsm.h b/include/osmocom/core/fsm.h index 3a1f233..f42dd0c 100644 --- a/include/osmocom/core/fsm.h +++ b/include/osmocom/core/fsm.h @@ -141,6 +141,10 @@ int osmo_fsm_register(struct osmo_fsm *fsm); void osmo_fsm_unregister(struct osmo_fsm *fsm); struct osmo_fsm *osmo_fsm_find_by_name(const char *name); +struct osmo_fsm_inst *osmo_fsm_inst_find_by_name(const struct osmo_fsm *fsm, + const char *name); +struct osmo_fsm_inst *osmo_fsm_inst_find_by_id(const struct osmo_fsm *fsm, + const char *id); struct osmo_fsm_inst *osmo_fsm_inst_alloc(struct osmo_fsm *fsm, void *ctx, void *priv, int log_level, const char *id); struct osmo_fsm_inst *osmo_fsm_inst_alloc_child(struct osmo_fsm *fsm, diff --git a/src/fsm.c b/src/fsm.c index 0e2c9be..7b2be70 100644 --- a/src/fsm.c +++ b/src/fsm.c @@ -113,6 +113,30 @@ return NULL; } +struct osmo_fsm_inst *osmo_fsm_inst_find_by_name(const struct osmo_fsm *fsm, + const char *name) +{ + struct osmo_fsm_inst *fi; + + llist_for_each_entry(fi, &fsm->instances, list) { + if (!strcmp(name, fi->name)) + return fi; + } + return NULL; +} + +struct osmo_fsm_inst *osmo_fsm_inst_find_by_id(const struct osmo_fsm *fsm, + const char *id) +{ + struct osmo_fsm_inst *fi; + + llist_for_each_entry(fi, &fsm->instances, list) { + if (!strcmp(id, fi->id)) + return fi; + } + return NULL; +} + /*! \brief register a FSM with the core * * A FSM descriptor needs to be registered with the core before any diff --git a/tests/fsm/fsm_test.c b/tests/fsm/fsm_test.c index 7a64421..c3ab91c 100644 --- a/tests/fsm/fsm_test.c +++ b/tests/fsm/fsm_test.c @@ -94,7 +94,7 @@ struct osmo_fsm_inst *fi; LOGP(DMAIN, LOGL_INFO, "Checking FSM allocation\n"); - fi = osmo_fsm_inst_alloc(&fsm, g_ctx, NULL, LOGL_DEBUG, NULL); + fi = osmo_fsm_inst_alloc(&fsm, g_ctx, NULL, LOGL_DEBUG, "my_id"); OSMO_ASSERT(fi); OSMO_ASSERT(fi->fsm == &fsm); OSMO_ASSERT(!strncmp(osmo_fsm_inst_name(fi), fsm.name, strlen(fsm.name))); @@ -143,10 +143,16 @@ log_add_target(stderr_target); log_set_print_filename(stderr_target, 0); - g_ctx = NULL; - osmo_fsm_register(&fsm); + g_ctx = NULL; + OSMO_ASSERT(osmo_fsm_find_by_name(fsm.name) == NULL); + osmo_fsm_register(&fsm); + OSMO_ASSERT(osmo_fsm_find_by_name(fsm.name) == &fsm); + + OSMO_ASSERT(osmo_fsm_inst_find_by_name(&fsm, "my_id") == NULL); finst = foo(); + OSMO_ASSERT(osmo_fsm_inst_find_by_id(&fsm, "my_id") == finst); + OSMO_ASSERT(osmo_fsm_inst_find_by_name(&fsm, "Test FSM(my_id)") == finst); while (1) { osmo_select_main(0); diff --git a/tests/fsm/fsm_test.err b/tests/fsm/fsm_test.err index c9021bb..6f031be 100644 --- a/tests/fsm/fsm_test.err +++ b/tests/fsm/fsm_test.err @@ -1,11 +1,11 @@ Checking FSM allocation -Test FSM{NULL}: Allocated -Test FSM{NULL}: Received Event 1 -Test FSM{NULL}: Event 1 not permitted -Test FSM{NULL}: Received Event 0 -Test FSM{NULL}: state_chg to ONE -Test FSM{ONE}: Received Event 1 -Test FSM{ONE}: state_chg to TWO -Test FSM{TWO}: Timeout of T2342 +Test FSM(my_id){NULL}: Allocated +Test FSM(my_id){NULL}: Received Event 1 +Test FSM(my_id){NULL}: Event 1 not permitted +Test FSM(my_id){NULL}: Received Event 0 +Test FSM(my_id){NULL}: state_chg to ONE +Test FSM(my_id){ONE}: Received Event 1 +Test FSM(my_id){ONE}: state_chg to TWO +Test FSM(my_id){TWO}: Timeout of T2342 Timer  \ No newline at end of file -- To view, visit https://gerrit.osmocom.org/2372 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I707f3ed2795c28a924e64adc612d378c21baa815 Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sun Apr 16 17:23:57 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 16 Apr 2017 17:23:57 +0000 Subject: [MERGED] libosmocore[master]: fsm: Re-set fsm_inst->T to 0 after timer expiration In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: fsm: Re-set fsm_inst->T to 0 after timer expiration ...................................................................... fsm: Re-set fsm_inst->T to 0 after timer expiration If the user starts the FSM timer with a given timer number during fsm_inst_state_chg() with a timeout, we should remove that "T" number after timer expiration. Otherwise it might be confusing if e.g. the VTY interface shows FSM instances with a certain timer number assigned, but that timer is not actually running anymore. Change-Id: I71167ec1000dc4c6954d851d3b92f6bf12984925 --- M src/fsm.c 1 file changed, 4 insertions(+), 1 deletion(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/fsm.c b/src/fsm.c index 7b2be70..9e6ef15 100644 --- a/src/fsm.c +++ b/src/fsm.c @@ -178,13 +178,16 @@ if (fsm->timer_cb) { int rc = fsm->timer_cb(fi); - if (rc != 1) + if (rc != 1) { + fi->T = 0; return; + } LOGPFSM(fi, "timer_cb requested termination\n"); } else LOGPFSM(fi, "No timer_cb, automatic termination\n"); /* if timer_cb returns 1 or there is no timer_cb */ + fi->T = 0; osmo_fsm_inst_term(fi, OSMO_FSM_TERM_TIMEOUT, &T); } -- To view, visit https://gerrit.osmocom.org/2373 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I71167ec1000dc4c6954d851d3b92f6bf12984925 Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sun Apr 16 17:46:48 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 16 Apr 2017 17:46:48 +0000 Subject: [PATCH] libosmocore[master]: control_if: Add API to initialize control interface without ... In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2375 to look at the new patch set (#2). control_if: Add API to initialize control interface without TCP port bind When executing test cases, we don't want to bind to a local TCP port, as we cannot make assumptions as to which ports are actually free. Change-Id: I5717f9dd92d1f143f069cecd4b4c8ba3d03b25f8 --- M include/osmocom/ctrl/control_if.h M src/ctrl/control_if.c 2 files changed, 64 insertions(+), 27 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/75/2375/2 diff --git a/include/osmocom/ctrl/control_if.h b/include/osmocom/ctrl/control_if.h index a740a96..0d37959 100644 --- a/include/osmocom/ctrl/control_if.h +++ b/include/osmocom/ctrl/control_if.h @@ -21,6 +21,7 @@ int ctrl_cmd_send(struct osmo_wqueue *queue, struct ctrl_cmd *cmd); int ctrl_cmd_send_trap(struct ctrl_handle *ctrl, const char *name, char *value); +struct ctrl_handle *ctrl_handle_alloc(void *ctx, void *data, ctrl_cmd_lookup lookup); struct ctrl_handle *ctrl_interface_setup(void *data, uint16_t port, ctrl_cmd_lookup lookup); struct ctrl_handle *ctrl_interface_setup_dynip(void *data, diff --git a/src/ctrl/control_if.c b/src/ctrl/control_if.c index 5730850..e1b53b4 100644 --- a/src/ctrl/control_if.c +++ b/src/ctrl/control_if.c @@ -59,6 +59,8 @@ #include #include +extern int osmo_fsm_ctrl_cmds_install(void); + vector ctrl_node_vec; /* global list of control interface lookup helpers */ @@ -694,6 +696,62 @@ return ctrl_interface_setup_dynip(data, "127.0.0.1", port, lookup); } +static int ctrl_initialized = 0; + +/* global ctrl initialization */ +static int ctrl_init(void) +{ + int ret; + + if (ctrl_initialized) + return 0; + + ctrl_node_vec = vector_init(5); + if (!ctrl_node_vec) + goto err; + + ret = ctrl_cmd_install(CTRL_NODE_ROOT, &cmd_rate_ctr); + if (ret) + goto err_vec; + ret = ctrl_cmd_install(CTRL_NODE_ROOT, &cmd_counter); + if (ret) + goto err_vec; + + ctrl_initialized = 1; + return 0; + +err_vec: + vector_free(ctrl_node_vec); + ctrl_node_vec = NULL; +err: + return -1; +} + +/*! \brief Allocate a CTRL interface handle + * \param[in] ctx Tallo callocation context to be used + * \param[in] data Pointer which will be made available to each + set_..() get_..() verify_..() control command function + * \param[in] lookup Lookup function pointer, can be NULL + * \returns ctrl_handle pointer or NULL in case of errors + */ +struct ctrl_handle *ctrl_handle_alloc(void *ctx, void *data, ctrl_cmd_lookup lookup) +{ + struct ctrl_handle *ctrl; + + ctrl_init(); + + ctrl = talloc_zero(ctx, struct ctrl_handle); + if (!ctrl) + return NULL; + + INIT_LLIST_HEAD(&ctrl->ccon_list); + + ctrl->data = data; + ctrl->lookup = lookup; + + return ctrl; +} + /*! \brief Setup CTRL interface on a given address * \param[in] data Pointer which will be made available to each set_..() get_..() verify_..() control command function @@ -710,44 +768,22 @@ int ret; struct ctrl_handle *ctrl; - ctrl = talloc_zero(data, struct ctrl_handle); + ctrl = ctrl_handle_alloc(data, data, lookup); if (!ctrl) return NULL; - - INIT_LLIST_HEAD(&ctrl->ccon_list); - - ctrl->data = data; - ctrl->lookup = lookup; - - ctrl_node_vec = vector_init(5); - if (!ctrl_node_vec) - goto err; /* Listen for control connections */ ctrl->listen_fd.cb = listen_fd_cb; ctrl->listen_fd.data = ctrl; ret = osmo_sock_init_ofd(&ctrl->listen_fd, AF_INET, SOCK_STREAM, IPPROTO_TCP, bind_addr, port, OSMO_SOCK_F_BIND); - if (ret < 0) - goto err_vec; - - ret = ctrl_cmd_install(CTRL_NODE_ROOT, &cmd_rate_ctr); - if (ret) - goto err_vec; - ret = ctrl_cmd_install(CTRL_NODE_ROOT, &cmd_counter); - if (ret) - goto err_vec; + if (ret < 0) { + talloc_free(ctrl); + return NULL; + } LOGP(DLCTRL, LOGL_NOTICE, "CTRL at %s %u\n", bind_addr, port); return ctrl; -err_vec: - vector_free(ctrl_node_vec); - ctrl_node_vec = NULL; -err: - LOGP(DLCTRL, LOGL_ERROR, "Cannot bind CTRL at %s %u\n", - bind_addr, port); - talloc_free(ctrl); - return NULL; } /*! \brief Install a lookup helper function for control nodes -- To view, visit https://gerrit.osmocom.org/2375 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I5717f9dd92d1f143f069cecd4b4c8ba3d03b25f8 Gerrit-PatchSet: 2 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sun Apr 16 17:46:50 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 16 Apr 2017 17:46:50 +0000 Subject: [PATCH] libosmocore[master]: control_if: Add control interface commands for FSMs Message-ID: Review at https://gerrit.osmocom.org/2378 control_if: Add control interface commands for FSMs This allows programmatic access to introspection of FSM instances, which is quite handy from e.g. external test cases: Send a message to the code, then use the CTRL interface to check if that message has triggered the right kind of state transition. Change-Id: I0f80340ee9c61c88962fdd6764a6098a844d0d1e --- M include/osmocom/ctrl/control_cmd.h M src/ctrl/Makefile.am M src/ctrl/control_if.c A src/ctrl/fsm_ctrl_commands.c M tests/fsm/fsm_test.c M tests/fsm/fsm_test.err 6 files changed, 226 insertions(+), 12 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/78/2378/1 diff --git a/include/osmocom/ctrl/control_cmd.h b/include/osmocom/ctrl/control_cmd.h index d9092f3..3cef9d8 100644 --- a/include/osmocom/ctrl/control_cmd.h +++ b/include/osmocom/ctrl/control_cmd.h @@ -18,6 +18,8 @@ CTRL_NODE_BTS, /* BTS specific (net.btsN.) */ CTRL_NODE_TRX, /* TRX specific (net.btsN.trxM.) */ CTRL_NODE_TS, /* TS specific (net.btsN.trxM.tsI.) */ + CTRL_NODE_FSM, /* Finite State Machine (description) */ + CTRL_NODE_FSM_INST, /* Finite State Machine (instance) */ _LAST_CTRL_NODE }; diff --git a/src/ctrl/Makefile.am b/src/ctrl/Makefile.am index 1817cac..e8d55e6 100644 --- a/src/ctrl/Makefile.am +++ b/src/ctrl/Makefile.am @@ -8,7 +8,7 @@ if ENABLE_CTRL lib_LTLIBRARIES = libosmoctrl.la -libosmoctrl_la_SOURCES = control_cmd.c control_if.c +libosmoctrl_la_SOURCES = control_cmd.c control_if.c fsm_ctrl_commands.c libosmoctrl_la_LDFLAGS = $(LTLDFLAGS_OSMOCTRL) $(TALLOC_LIBS) -version-info $(LIBVERSION) -no-undefined libosmoctrl_la_LIBADD = \ diff --git a/src/ctrl/control_if.c b/src/ctrl/control_if.c index 55d4904..729e8d4 100644 --- a/src/ctrl/control_if.c +++ b/src/ctrl/control_if.c @@ -717,6 +717,10 @@ if (ret) goto err_vec; + ret = osmo_fsm_ctrl_cmds_install(); + if (ret) + goto err_vec; + ctrl_initialized = 1; return 0; diff --git a/src/ctrl/fsm_ctrl_commands.c b/src/ctrl/fsm_ctrl_commands.c new file mode 100644 index 0000000..0dfc396 --- /dev/null +++ b/src/ctrl/fsm_ctrl_commands.c @@ -0,0 +1,175 @@ +#include +#include + +#include + +#include +#include + +/*! \brief control interface lookup function for FSM's + * \param[in] data Private data passed to controlif_setup() + * \param[in] vline Vector of the line holding the command string + * \param[out] node_type type (CTRL_NODE_) that was determined + * \param[out] node_data private data of node that was determined + * \param i Current index into vline, up to which it is parsed + */ +static int fsm_ctrl_node_lookup(void *data, vector vline, int *node_type, + void **node_data, int *i) +{ + struct osmo_fsm *fsm = NULL; + struct osmo_fsm_inst *fi = NULL;; + const char *token = vector_slot(vline, *i); + + switch (*node_type) { + case CTRL_NODE_ROOT: + if (!strcmp(token, "fsm")) { + const char *fsm_name; + (*i)++; + fsm_name = vector_lookup(vline, *i); + if (!fsm_name) + goto err_index; + fsm = osmo_fsm_find_by_name(fsm_name); + if (!fsm) + goto err_missing; + *node_data = fsm; + *node_type = CTRL_NODE_FSM; + } + break; + case CTRL_NODE_FSM: + fsm = *node_data; + if (!strcmp(token, "name")) { + const char *inst_name; + (*i)++; + inst_name = vector_lookup(vline, *i); + if (!inst_name) + goto err_index; + fi = osmo_fsm_inst_find_by_name(fsm, inst_name); + if (!fi) + goto err_missing; + *node_data = fi; + *node_type = CTRL_NODE_FSM_INST; + } else if (!strcmp(token, "id")) { + const char *inst_id; + (*i)++; + inst_id = vector_lookup(vline, *i); + if (!inst_id) + goto err_index; + fi = osmo_fsm_inst_find_by_id(fsm, inst_id); + if (!fi) + goto err_missing; + *node_data = fi; + *node_type = CTRL_NODE_FSM_INST; + } + break; + default: + return 0; + } + + return 1; + +err_index: + return -ERANGE; +err_missing: + return -ENODEV; +} + +static int get_fsm_inst_state(struct ctrl_cmd *cmd, void *data) +{ + struct osmo_fsm_inst *fi = cmd->node; + + if (!fi) { + cmd->reply = "No such FSM found"; + return CTRL_CMD_ERROR; + } + + cmd->reply = talloc_strdup(cmd, osmo_fsm_state_name(fi->fsm, fi->state)); + return CTRL_CMD_REPLY; +} +CTRL_CMD_DEFINE_RO(fsm_inst_state, "state"); + +static int get_fsm_inst_parent_name(struct ctrl_cmd *cmd, void *data) +{ + struct osmo_fsm_inst *fi = cmd->node; + + if (!fi) { + cmd->reply = "No such FSM found"; + return CTRL_CMD_ERROR; + } + if (!fi->proc.parent) { + cmd->reply = "No parent"; + return CTRL_CMD_ERROR; + } + cmd->reply = talloc_strdup(cmd, fi->proc.parent->name); + return CTRL_CMD_REPLY; +} +CTRL_CMD_DEFINE_RO(fsm_inst_parent_name, "parent-name"); + +static int get_fsm_inst_timer(struct ctrl_cmd *cmd, void *data) +{ + struct osmo_fsm_inst *fi = cmd->node; + struct timeval remaining; + + if (!fi) { + cmd->reply = "No such FSM found"; + return CTRL_CMD_ERROR; + } + if (osmo_timer_remaining(&fi->timer, NULL, &remaining) < 0) + cmd->reply = "0,0,0"; + else + cmd->reply = talloc_asprintf(cmd, "%u,%ld,%ld", fi->T, remaining.tv_sec, remaining.tv_usec); + + return CTRL_CMD_REPLY; +} +CTRL_CMD_DEFINE_RO(fsm_inst_timer, "timer"); + + +static int get_fsm_inst_dump(struct ctrl_cmd *cmd, void *data) +{ + struct osmo_fsm_inst *fi = cmd->node; + struct osmo_fsm_inst *child; + + if (!fi) { + cmd->reply = "No such FSM found"; + return CTRL_CMD_ERROR; + } + + /* Fixed Part: Name, ID, log_level, state, timer number */ + cmd->reply = talloc_asprintf(cmd, "'%s','%s','%s','%s',%u", fi->name, fi->id, + log_level_str(fi->log_level), + osmo_fsm_state_name(fi->fsm, fi->state), fi->T); + + /* Variable Parts below */ + if (fi->T) { + struct timeval remaining; + int rc; + rc = osmo_timer_remaining(&fi->timer, NULL, &remaining); + if (rc == 0) { + cmd->reply = talloc_asprintf_append(cmd->reply, ",timeout_sec=%ld,timeout_usec=%ld", + remaining.tv_sec, remaining.tv_usec); + } + } + + if (fi->proc.parent) + cmd->reply = talloc_asprintf_append(cmd->reply, ",parent='%s'", fi->proc.parent->name); + + llist_for_each_entry(child, &fi->proc.children, list) { + cmd->reply = talloc_asprintf_append(cmd->reply, ",child='%s'", child->name); + } + + return CTRL_CMD_REPLY; +} + +CTRL_CMD_DEFINE_RO(fsm_inst_dump, "dump"); + +int osmo_fsm_ctrl_cmds_install(void) +{ + int rc = 0; + + rc |= ctrl_cmd_install(CTRL_NODE_FSM_INST, &cmd_fsm_inst_dump); + rc |= ctrl_cmd_install(CTRL_NODE_FSM_INST, &cmd_fsm_inst_state); + rc |= ctrl_cmd_install(CTRL_NODE_FSM_INST, &cmd_fsm_inst_parent_name); + rc |= ctrl_cmd_install(CTRL_NODE_FSM_INST, &cmd_fsm_inst_timer); + rc |= ctrl_lookup_register(fsm_ctrl_node_lookup); + + return rc; +} diff --git a/tests/fsm/fsm_test.c b/tests/fsm/fsm_test.c index 7aade98..eea8b22 100644 --- a/tests/fsm/fsm_test.c +++ b/tests/fsm/fsm_test.c @@ -84,15 +84,38 @@ }; static struct osmo_fsm fsm = { - .name = "Test FSM", + .name = "Test_FSM", .states = test_fsm_states, .num_states = ARRAY_SIZE(test_fsm_states), .log_subsys = DMAIN, }; +static struct ctrl_handle *g_ctrl; + +static struct ctrl_cmd *exec_ctrl_cmd(const char *cmdstr) +{ + struct ctrl_cmd *cmd; + return ctrl_cmd_exec_from_string(g_ctrl, cmdstr); + OSMO_ASSERT(cmd); + return cmd; +} + +static void assert_cmd_reply(const char *cmdstr, const char *expres) +{ + struct ctrl_cmd *cmd; + + cmd = exec_ctrl_cmd(cmdstr); + if (strcmp(cmd->reply, expres)) { + fprintf(stderr, "Reply '%s' doesn't match expected '%s'\n", cmd->reply, expres); + OSMO_ASSERT(0); + } + talloc_free(cmd); +} + static struct osmo_fsm_inst *foo(void) { struct osmo_fsm_inst *fi; + struct ctrl_cmd *cmd; LOGP(DMAIN, LOGL_INFO, "Checking FSM allocation\n"); fi = osmo_fsm_inst_alloc(&fsm, g_ctx, NULL, LOGL_DEBUG, "my_id"); @@ -101,20 +124,30 @@ OSMO_ASSERT(!strncmp(osmo_fsm_inst_name(fi), fsm.name, strlen(fsm.name))); OSMO_ASSERT(fi->state == ST_NULL); OSMO_ASSERT(fi->log_level == LOGL_DEBUG); + assert_cmd_reply("GET 1 fsm.Test_FSM.id.my_id.state", "NULL"); + assert_cmd_reply("GET 1 fsm.Test_FSM.id.my_id.timer", "0,0,0"); /* Try invalid state transition */ osmo_fsm_inst_dispatch(fi, EV_B, (void *) 42); OSMO_ASSERT(fi->state == ST_NULL); + assert_cmd_reply("GET 1 fsm.Test_FSM.id.my_id.state", "NULL"); + /* Legitimate state transition */ osmo_fsm_inst_dispatch(fi, EV_A, (void *) 23); OSMO_ASSERT(fi->state == ST_ONE); + assert_cmd_reply("GET 1 fsm.Test_FSM.id.my_id.state", "ONE"); /* Legitimate transition with timer */ fsm.timer_cb = test_fsm_tmr_cb; osmo_fsm_inst_dispatch(fi, EV_B, (void *) 42); OSMO_ASSERT(fi->state == ST_TWO); + assert_cmd_reply("GET 1 fsm.Test_FSM.id.my_id.state", "TWO"); + cmd = exec_ctrl_cmd("GET 2 fsm.Test_FSM.id.my_id.dump"); + const char *exp = "'Test_FSM(my_id)','my_id','DEBUG','TWO',2342,timeout_sec="; + OSMO_ASSERT(!strncmp(cmd->reply, exp, strlen(exp))); + talloc_free(cmd); return fi; } @@ -143,7 +176,7 @@ stderr_target = log_target_create_stderr(); log_add_target(stderr_target); log_set_print_filename(stderr_target, 0); - + g_ctrl = ctrl_handle_alloc(NULL, NULL, NULL); g_ctx = NULL; OSMO_ASSERT(osmo_fsm_find_by_name(fsm.name) == NULL); @@ -153,7 +186,7 @@ OSMO_ASSERT(osmo_fsm_inst_find_by_name(&fsm, "my_id") == NULL); finst = foo(); OSMO_ASSERT(osmo_fsm_inst_find_by_id(&fsm, "my_id") == finst); - OSMO_ASSERT(osmo_fsm_inst_find_by_name(&fsm, "Test FSM(my_id)") == finst); + OSMO_ASSERT(osmo_fsm_inst_find_by_name(&fsm, "Test_FSM(my_id)") == finst); while (1) { osmo_select_main(0); diff --git a/tests/fsm/fsm_test.err b/tests/fsm/fsm_test.err index 6f031be..17a2f2e 100644 --- a/tests/fsm/fsm_test.err +++ b/tests/fsm/fsm_test.err @@ -1,11 +1,11 @@ Checking FSM allocation -Test FSM(my_id){NULL}: Allocated -Test FSM(my_id){NULL}: Received Event 1 -Test FSM(my_id){NULL}: Event 1 not permitted -Test FSM(my_id){NULL}: Received Event 0 -Test FSM(my_id){NULL}: state_chg to ONE -Test FSM(my_id){ONE}: Received Event 1 -Test FSM(my_id){ONE}: state_chg to TWO -Test FSM(my_id){TWO}: Timeout of T2342 +Test_FSM(my_id){NULL}: Allocated +Test_FSM(my_id){NULL}: Received Event 1 +Test_FSM(my_id){NULL}: Event 1 not permitted +Test_FSM(my_id){NULL}: Received Event 0 +Test_FSM(my_id){NULL}: state_chg to ONE +Test_FSM(my_id){ONE}: Received Event 1 +Test_FSM(my_id){ONE}: state_chg to TWO +Test_FSM(my_id){TWO}: Timeout of T2342 Timer  \ No newline at end of file -- To view, visit https://gerrit.osmocom.org/2378 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I0f80340ee9c61c88962fdd6764a6098a844d0d1e Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Sun Apr 16 17:47:46 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 16 Apr 2017 17:47:46 +0000 Subject: libosmocore[master]: ctrl: Allow installation of additional node lookup helpers In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2374 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ib69908d1c57f5bb721d5496e3b4a5258fca450e3 Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sun Apr 16 17:50:08 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 16 Apr 2017 17:50:08 +0000 Subject: [PATCH] libosmocore[master]: control_if: Don't use magic number '5' when allocating vector Message-ID: Review at https://gerrit.osmocom.org/2379 control_if: Don't use magic number '5' when allocating vector We have a proper constant for this (_LAST_CTRL_NODE), so let's use it. Change-Id: I46275e644166156cb665da70d2964008f1c6cd88 --- M src/ctrl/control_if.c 1 file changed, 1 insertion(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/79/2379/1 diff --git a/src/ctrl/control_if.c b/src/ctrl/control_if.c index 729e8d4..8fd5419 100644 --- a/src/ctrl/control_if.c +++ b/src/ctrl/control_if.c @@ -706,7 +706,7 @@ if (ctrl_initialized) return 0; - ctrl_node_vec = vector_init(5); + ctrl_node_vec = vector_init(_LAST_CTRL_NODE); if (!ctrl_node_vec) goto err; -- To view, visit https://gerrit.osmocom.org/2379 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I46275e644166156cb665da70d2964008f1c6cd88 Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Sun Apr 16 17:50:26 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 16 Apr 2017 17:50:26 +0000 Subject: libosmocore[master]: control_if: Don't use magic number '5' when allocating vector In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2379 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I46275e644166156cb665da70d2964008f1c6cd88 Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sun Apr 16 18:07:46 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 16 Apr 2017 18:07:46 +0000 Subject: libosmocore[master]: control_if: Add API to initialize control interface without ... In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2375 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I5717f9dd92d1f143f069cecd4b4c8ba3d03b25f8 Gerrit-PatchSet: 2 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sun Apr 16 18:20:57 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 16 Apr 2017 18:20:57 +0000 Subject: [ABANDON] libosmocore[master]: control_if: Add control interface commands for FSMs In-Reply-To: References: Message-ID: Harald Welte has abandoned this change. Change subject: control_if: Add control interface commands for FSMs ...................................................................... Abandoned -- To view, visit https://gerrit.osmocom.org/2377 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: abandon Gerrit-Change-Id: I2822513ac63a3d9b87b3eefc7c4e6b585c555ee2 Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Jenkins Builder From admin at opensuse.org Sun Apr 16 19:58:49 2017 From: admin at opensuse.org (OBS Notification) Date: Sun, 16 Apr 2017 19:58:49 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in xUbuntu_16.10/x86_64 In-Reply-To: References: Message-ID: <58f3ccfe8c3fd_98f1156f8469725d@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/xUbuntu_16.10/x86_64 Package network:osmocom:nightly/osmo-stp failed to build in xUbuntu_16.10/x86_64 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 76s] ^~~~~~~ [ 76s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o vty_interface.o vty_interface.c [ 77s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o sctp_m3ua_client.o sctp_m3ua_client.c [ 77s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 77s] #include [ 77s] ^ [ 77s] compilation terminated. [ 77s] Makefile:485: recipe for target 'sctp_m3ua_client.o' failed [ 77s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 77s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 77s] Makefile:380: recipe for target 'all-recursive' failed [ 77s] make[2]: *** [all-recursive] Error 1 [ 77s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 77s] Makefile:321: recipe for target 'all' failed [ 77s] make[1]: *** [all] Error 2 [ 77s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 77s] dh_auto_build: make -j1 returned exit code 2 [ 77s] debian/rules:23: recipe for target 'build' failed [ 77s] make: *** [build] Error 2 [ 77s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 77s] [ 77s] lamb68 failed "build cellmgr-ng_1.4.7.20170416.dsc" at Sun Apr 16 19:58:32 UTC 2017. [ 77s] [ 77s] ### VM INTERACTION START ### [ 80s] [ 66.561580] reboot: Power down [ 80s] ### VM INTERACTION END ### [ 80s] [ 80s] lamb68 failed "build cellmgr-ng_1.4.7.20170416.dsc" at Sun Apr 16 19:58:36 UTC 2017. [ 80s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Sun Apr 16 20:00:49 2017 From: admin at opensuse.org (OBS Notification) Date: Sun, 16 Apr 2017 20:00:49 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in Debian_8.0/x86_64 In-Reply-To: References: Message-ID: <58f3cd9655beb_99c1156f847826b7@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/Debian_8.0/x86_64 Package network:osmocom:nightly/osmo-stp failed to build in Debian_8.0/x86_64 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 119s] CC vty_interface.o [ 120s] CC sctp_m3ua_client.o [ 120s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 120s] #include [ 120s] ^ [ 120s] compilation terminated. [ 120s] Makefile:475: recipe for target 'sctp_m3ua_client.o' failed [ 120s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 120s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 120s] Makefile:370: recipe for target 'all-recursive' failed [ 120s] make[2]: *** [all-recursive] Error 1 [ 120s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 120s] Makefile:310: recipe for target 'all' failed [ 120s] make[1]: *** [all] Error 2 [ 120s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 120s] dh_auto_build: make -j1 returned exit code 2 [ 120s] debian/rules:23: recipe for target 'build' failed [ 120s] make: *** [build] Error 2 [ 120s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 120s] [ 120s] cloud116 failed "build cellmgr-ng_1.4.7.20170416.dsc" at Sun Apr 16 20:00:41 UTC 2017. [ 120s] [ 120s] ### VM INTERACTION START ### [ 121s] Powering off. [ 121s] [ 98.104797] reboot: Power down [ 125s] ### VM INTERACTION END ### [ 125s] [ 125s] cloud116 failed "build cellmgr-ng_1.4.7.20170416.dsc" at Sun Apr 16 20:00:46 UTC 2017. [ 125s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Sun Apr 16 20:01:06 2017 From: admin at opensuse.org (OBS Notification) Date: Sun, 16 Apr 2017 20:01:06 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in xUbuntu_16.10/i586 In-Reply-To: References: Message-ID: <58f3cd969995c_99c1156f84782798@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/xUbuntu_16.10/i586 Package network:osmocom:nightly/osmo-stp failed to build in xUbuntu_16.10/i586 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 43s] #warning "Notify any other AS(P) for failover scenario" [ 43s] ^~~~~~~ [ 43s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o vty_interface.o vty_interface.c [ 43s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o sctp_m3ua_client.o sctp_m3ua_client.c [ 43s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 43s] #include [ 43s] ^ [ 43s] compilation terminated. [ 43s] Makefile:485: recipe for target 'sctp_m3ua_client.o' failed [ 43s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 43s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 43s] Makefile:380: recipe for target 'all-recursive' failed [ 43s] make[2]: *** [all-recursive] Error 1 [ 43s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 43s] Makefile:321: recipe for target 'all' failed [ 43s] make[1]: *** [all] Error 2 [ 43s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 43s] dh_auto_build: make -j1 returned exit code 2 [ 43s] debian/rules:23: recipe for target 'build' failed [ 43s] make: *** [build] Error 2 [ 43s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 43s] [ 43s] build81 failed "build cellmgr-ng_1.4.7.20170416.dsc" at Sun Apr 16 20:00:46 UTC 2017. [ 43s] [ 43s] ### VM INTERACTION START ### [ 47s] ### VM INTERACTION END ### [ 47s] [ 47s] build81 failed "build cellmgr-ng_1.4.7.20170416.dsc" at Sun Apr 16 20:00:50 UTC 2017. [ 47s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Sun Apr 16 20:01:24 2017 From: admin at opensuse.org (OBS Notification) Date: Sun, 16 Apr 2017 20:01:24 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in xUbuntu_16.04/x86_64 In-Reply-To: References: Message-ID: <58f3cdb5c0622_98f1156f846973d3@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/xUbuntu_16.04/x86_64 Package network:osmocom:nightly/osmo-stp failed to build in xUbuntu_16.04/x86_64 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 131s] sctp_m2ua.c:91:3: warning: #warning "Notify any other AS(P) for failover scenario" [-Wcpp] [ 131s] #warning "Notify any other AS(P) for failover scenario" [ 131s] ^ [ 131s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -c -o vty_interface.o vty_interface.c [ 132s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -c -o sctp_m3ua_client.o sctp_m3ua_client.c [ 132s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 132s] compilation terminated. [ 132s] Makefile:485: recipe for target 'sctp_m3ua_client.o' failed [ 132s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 132s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 132s] Makefile:380: recipe for target 'all-recursive' failed [ 132s] make[2]: *** [all-recursive] Error 1 [ 132s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 132s] Makefile:321: recipe for target 'all' failed [ 132s] make[1]: *** [all] Error 2 [ 132s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 132s] dh_auto_build: make -j1 returned exit code 2 [ 132s] debian/rules:23: recipe for target 'build' failed [ 132s] make: *** [build] Error 2 [ 132s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 132s] [ 132s] cloud138 failed "build cellmgr-ng_1.4.7.20170416.dsc" at Sun Apr 16 20:01:15 UTC 2017. [ 132s] [ 132s] ### VM INTERACTION START ### [ 135s] [ 114.279773] reboot: Power down [ 136s] ### VM INTERACTION END ### [ 136s] [ 136s] cloud138 failed "build cellmgr-ng_1.4.7.20170416.dsc" at Sun Apr 16 20:01:20 UTC 2017. [ 136s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Sun Apr 16 20:01:58 2017 From: admin at opensuse.org (OBS Notification) Date: Sun, 16 Apr 2017 20:01:58 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in Debian_8.0/i586 In-Reply-To: References: Message-ID: <58f3cdd46eb3d_99c1156f847830c4@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/Debian_8.0/i586 Package network:osmocom:nightly/osmo-stp failed to build in Debian_8.0/i586 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 99s] CC vty_interface.o [ 100s] CC sctp_m3ua_client.o [ 100s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 100s] #include [ 100s] ^ [ 100s] compilation terminated. [ 100s] Makefile:475: recipe for target 'sctp_m3ua_client.o' failed [ 100s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 100s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 100s] Makefile:370: recipe for target 'all-recursive' failed [ 100s] make[2]: *** [all-recursive] Error 1 [ 100s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 100s] Makefile:310: recipe for target 'all' failed [ 100s] make[1]: *** [all] Error 2 [ 100s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 100s] dh_auto_build: make -j1 returned exit code 2 [ 100s] debian/rules:23: recipe for target 'build' failed [ 100s] make: *** [build] Error 2 [ 100s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 100s] [ 100s] build34 failed "build cellmgr-ng_1.4.7.20170416.dsc" at Sun Apr 16 20:01:41 UTC 2017. [ 100s] [ 100s] ### VM INTERACTION START ### [ 101s] Powering off. [ 101s] [ 84.929702] reboot: Power down [ 102s] ### VM INTERACTION END ### [ 102s] [ 102s] build34 failed "build cellmgr-ng_1.4.7.20170416.dsc" at Sun Apr 16 20:01:43 UTC 2017. [ 102s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Sun Apr 16 20:01:58 2017 From: admin at opensuse.org (OBS Notification) Date: Sun, 16 Apr 2017 20:01:58 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in xUbuntu_16.04/i586 In-Reply-To: References: Message-ID: <58f3cdee8a756_99c1156f8478315d@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/xUbuntu_16.04/i586 Package network:osmocom:nightly/osmo-stp failed to build in xUbuntu_16.04/i586 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 57s] sctp_m2ua.c: In function 'm2ua_conn_destroy': [ 57s] sctp_m2ua.c:91:3: warning: #warning "Notify any other AS(P) for failover scenario" [-Wcpp] [ 57s] #warning "Notify any other AS(P) for failover scenario" [ 57s] ^ [ 57s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -c -o vty_interface.o vty_interface.c [ 57s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -c -o sctp_m3ua_client.o sctp_m3ua_client.c [ 57s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 57s] compilation terminated. [ 57s] Makefile:485: recipe for target 'sctp_m3ua_client.o' failed [ 57s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 57s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 57s] Makefile:380: recipe for target 'all-recursive' failed [ 57s] make[2]: *** [all-recursive] Error 1 [ 57s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 57s] Makefile:321: recipe for target 'all' failed [ 57s] make[1]: *** [all] Error 2 [ 57s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 57s] dh_auto_build: make -j1 returned exit code 2 [ 57s] debian/rules:23: recipe for target 'build' failed [ 57s] make: *** [build] Error 2 [ 57s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 57s] [ 57s] build76 failed "build cellmgr-ng_1.4.7.20170416.dsc" at Sun Apr 16 20:01:52 UTC 2017. [ 57s] [ 57s] ### VM INTERACTION START ### [ 61s] ### VM INTERACTION END ### [ 61s] [ 61s] build76 failed "build cellmgr-ng_1.4.7.20170416.dsc" at Sun Apr 16 20:01:56 UTC 2017. [ 61s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From gerrit-no-reply at lists.osmocom.org Sun Apr 16 21:38:10 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 16 Apr 2017 21:38:10 +0000 Subject: [PATCH] libosmo-netif[master]: stream.c: Fix SCTP_NODELAY setting Message-ID: Review at https://gerrit.osmocom.org/2380 stream.c: Fix SCTP_NODELAY setting We were using the wrong variable when setting the SCTP_NODELAY, resulting in the setsoctkopt() fialing. Change-Id: Ic04cb8bb5ff41f177f7f5b7f7e2a2ecc686dd4c0 --- M src/stream.c 1 file changed, 1 insertion(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-netif refs/changes/80/2380/1 diff --git a/src/stream.c b/src/stream.c index 653f26b..ed73a62 100644 --- a/src/stream.c +++ b/src/stream.c @@ -551,7 +551,7 @@ } if (link->flags & OSMO_STREAM_SRV_F_NODELAY) { - ret = setsockopt_nodelay(ret, link->proto, 1); + ret = setsockopt_nodelay(sock_fd, link->proto, 1); if (ret < 0) goto error_close_socket; } -- To view, visit https://gerrit.osmocom.org/2380 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ic04cb8bb5ff41f177f7f5b7f7e2a2ecc686dd4c0 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Sun Apr 16 22:15:45 2017 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Sun, 16 Apr 2017 22:15:45 +0000 Subject: [MERGED] osmo-gsm-manuals[master]: Add Osmo-GSM-Tester manual In-Reply-To: References: Message-ID: Neels Hofmeyr has submitted this change and it was merged. Change subject: Add Osmo-GSM-Tester manual ...................................................................... Add Osmo-GSM-Tester manual Change-Id: I8a9c0bfbce0072359c5094b940f225082d6847a7 --- M Makefile A Osmo-GSM-Tester/Makefile A Osmo-GSM-Tester/chapters/config.adoc A Osmo-GSM-Tester/chapters/debugging.adoc A Osmo-GSM-Tester/chapters/intro.adoc A Osmo-GSM-Tester/chapters/test_api.adoc A Osmo-GSM-Tester/chapters/trial.adoc A Osmo-GSM-Tester/osmo-gsm-tester-manual-docinfo.xml A Osmo-GSM-Tester/osmo-gsm-tester-manual.adoc 9 files changed, 603 insertions(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/Makefile b/Makefile index 035595c..362f171 100644 --- a/Makefile +++ b/Makefile @@ -6,6 +6,7 @@ cd OsmoSGSN; $(MAKE) cd OsmoNAT; $(MAKE) cd OsmoPCU; $(MAKE) + cd Osmo-GSM-Tester; $(MAKE) clean: cd OsmoBTS; $(MAKE) clean @@ -15,6 +16,7 @@ cd OsmoSGSN; $(MAKE) clean cd OsmoNAT; $(MAKE) clean cd OsmoPCU; $(MAKE) clean + cd Osmo-GSM-Tester; $(MAKE) clean upload: cd OsmoBTS; $(MAKE) upload @@ -24,6 +26,7 @@ cd OsmoSGSN; $(MAKE) upload cd OsmoNAT; $(MAKE) upload cd OsmoPCU; $(MAKE) upload + cd Osmo-GSM-Tester; $(MAKE) upload check: cd OsmoBTS; $(MAKE) check @@ -34,3 +37,4 @@ # These don't use asciidoc, so they have no 'make check' target: #cd OsmoMGCP; $(MAKE) check #cd OsmoNAT; $(MAKE) check + cd Osmo-GSM-Tester; $(MAKE) check diff --git a/Osmo-GSM-Tester/Makefile b/Osmo-GSM-Tester/Makefile new file mode 100644 index 0000000..79d414f --- /dev/null +++ b/Osmo-GSM-Tester/Makefile @@ -0,0 +1,12 @@ +TOPDIR := .. +ASCIIDOCS := osmo-gsm-tester-manual + +include $(TOPDIR)/build/Makefile.asciidoc.inc +include $(TOPDIR)/build/Makefile.inc + +osmo-gsm-tester-manual.pdf: chapters/*.adoc + +clean: + -rm -rf $(cleanfiles) + -rm osmo-gsm-tester-manual__*.svg + -rm osmo-gsm-tester-manual__*.png diff --git a/Osmo-GSM-Tester/chapters/config.adoc b/Osmo-GSM-Tester/chapters/config.adoc new file mode 100644 index 0000000..66f4b71 --- /dev/null +++ b/Osmo-GSM-Tester/chapters/config.adoc @@ -0,0 +1,225 @@ +== Configuration + +The osmo-gsm-tester looks for configuration files in various standard +directories in this order: + +- '$HOME/.config/osmo-gsm-tester/' +- '/usr/local/etc/osmo-gsm-tester/' +- '/etc/osmo-gsm-tester/' + +The config location can also be set by an environment variable +'$OSMO_GSM_TESTER_CONF', which then overrides the above locations. + +The osmo-gsm-tester expects to find the following configuration files in a +configuration directory: + +- 'paths.conf' +- 'resources.conf' +- 'default-suites.conf' (optional) +- 'defaults.conf' (optional) + +=== Format: YAML, and its Drawbacks + +The general configuration format used is YAML. The stock python YAML parser +does have several drawbacks: too many complex possibilities and alternative +ways of formatting a configuration, but at the time of writing seems to be the +only widely used configuration format that offers a simple and human readable +formatting as well as nested structuring. It is recommended to use only the +exact YAML subset seen in this manual in case the osmo-gsm-tester should move +to a less bloated parser in the future. + +Careful: if a configuration item consists of digits and starts with a zero, you +need to quote it, or it may be interpreted as an octal notation integer! Please +avoid using the octal notation on purpose, it is not provided intentionally. + +[[paths_conf]] +=== 'paths.conf' + +The 'paths.conf' file defines where to store the global state (of reserved +resources) and where to find suite and scenario definitions. + +Any relative paths found in a 'paths.conf' file are interpreted as relative to +the directory of that 'paths.conf' file. + +Example: + +---- +state_dir: '/var/run/osmo-gsm-tester' +suites_dir: './suites' +scenarios_dir: './scenarios' +---- + +If you would like to set up several separate 'paths.conf' files (not typical), +note that the 'state_dir' is used to reserve resources, which only works when +all configurations that share resources also use the same 'state_dir'. + +[[resources_conf]] +=== 'resources.conf' + +The 'resources.conf' file defines which hardware is connected to the main unit, +as well as which limited configuration items (like IP addresses or ARFCNs) +should be used. + +These resources are allocated dynamically and are not configured explicitly: + +- MSISDN: phone numbers are dealt out to test scripts in sequence on request. + +A 'resources.conf' is structured as a list of items for each resource type, +where each item has one or more settings -- for an example, see +<>. + +These kinds of resource are known: + +'nitb_iface':: + List of IP addresses to run osmo-nitb instances on. The main unit + typically has a limited number of such IP addresses configured, which + the connected BTS models can see on their network. + 'addr'::: + IPv4 address of the local interface. + +'bts':: + List of available BTS hardware. + 'label'::: + human readable label for your own reference + 'type'::: + which way to launch this BTS, one of + - 'osmo-bts-sysmo' + - 'osmo-bts-trx' + - 'osmo-bts-octphy' + - 'ipa-nanobts' + 'addr'::: + remote IP address of the BTS, used to start the BTS and tell it where + to find the OsmoNITB. + 'band'::: + GSM band that this BTS shoud use (*TODO*: allow multiple bands). One of: + - 'GSM-1800' + - 'GSM-1900' + - (*TODO*: more bands) + 'trx_list'::: + Specific TRX configurations for this BTS. There should be as many of + these as the BTS has TRXes. (*TODO*: a way to define >1 TRX without + special configuration for them.) + 'hw_addr':::: + Hardware (MAC) address of the TRX in the form of '11:22:33:44:55:66', + only used for osmo-bts-octphy. (*TODO*: and nanobts??) + 'net_device':::: + Local network device to reach the TRX's 'hw_addr' at, only used for + osmo-bts-octphy. + +'arfcn':: + List of ARFCNs to use for running BTSes, which defines the actual RF + frequency bands used. + 'arfcn'::: + ARFCN number, see e.g. + https://en.wikipedia.org/wiki/Absolute_radio-frequency_channel_number + (note that the resource type 'arfcn' contains an item trait also named + 'arfcn') + 'band'::: + GSM band name to use this ARFCN for, same as for 'bts:band' above. + +'modem':: + List of modems reachable via ofono and information on the inserted SIM + card. (Note: the MSISDN is allocated dynamically in test scripts) + 'label'::: + human readable label for your own reference + 'path'::: + ofono's path for this modem, like '/modemkind_99' + 'imsi'::: + IMSI of the inserted SIM card, like '"123456789012345"' + 'ki'::: + 16 byte authentication/encryption KI of the inserted SIM card, in + hexadecimal notation (32 characters) like + + '"00112233445566778899aabbccddeeff"' (*TODO*: authentication algorithm, + currently always comp128v1) + +Side note: at first sight it might make sense to the reader to rather structure +e.g. the 'nitb_iface' or 'arfcn' configuration as + +'"arfcn: GSM-1800: [512, 514, ...]"', + +but the more verbose format is chosen to stay consistent with the general +structure of resource configurations, which the resource allocation algorithm +uses to resolve required resources according to their traits. These +configurations look cumbersome because they exhibit only one trait / a trait +that is repeated numerous times. No special notation for these cases is +available (yet). + +[[default_suites]] +=== 'default-suites.conf' (optional) + +The 'default-suites.conf' file contains a list of 'suite:scenario+scenario+...' +combination strings as defined by the 'osmo-gsm-tester.py -s' commandline +option. If invoking the 'osmo-gsm-tester.py' without any suite definitions, the +'-s' arguments are taken from this file instead. Each of these suite + scenario +combinations is run in sequence. + +A suite name must match the name of a directory in the 'suites_dir' as defined +by 'paths.conf'. + +A scenario name must match the name of a configuration file in the +'scenarios_dir' as defined by 'paths.conf' (optionally without the '.conf' +suffix). + +For 'paths.conf', see <>. + +Example of a 'default-suites.conf' file: + +---- +- sms:sysmo +- voice:sysmo+tch_f +- voice:sysmo+tch_h +- voice:sysmo+dyn_ts +- sms:trx +- voice:trx+tch_f +- voice:trx+tch_h +- voice:trx+dyn_ts +---- + +=== 'defaults.conf' (optional) + +Each binary run by osmo-gsm-tester, e.g. 'osmo-nitb' or 'osmo-bts-sysmo', +typically has a configuration file template that is populated with values for a +trial run. + +Some of these values are provided by the 'resources.conf' from the allocated +resource(s), but not all values can be populated this way: some osmo-nitb +configuration values like the network name, encryption algorithm or timeslot +channel combinations are in fact not resources (only the nitb's interface +address is). These additional settings may be provided by the scenario +configurations, but in case the provided scenarios leave some values unset, +they are taken from this 'defaults.conf'. (A 'scenario.conf' providing a +similar setting always has precedence over the values given in a +'defaults.conf'). + +*TODO* better match this format with 'resources.conf'? + +Example of a 'defaults.conf': + +---- +nitb: + net: + mcc: 1 + mnc: 868 + short_name: osmo-gsm-tester + long_name: osmo-gsm-tester + auth_policy: closed + encryption: a5 0 + +nitb_bts: + location_area_code: 23 + base_station_id_code: 63 + stream_id: 255 + osmobsc_bts_type: sysmobts + trx_list: + - max_power_red: 22 + arfcn: 868 + timeslot_list: + - phys_chan_config: CCCH+SDCCH4 + - phys_chan_config: SDCCH8 + - phys_chan_config: TCH/F_TCH/H_PDCH + - phys_chan_config: TCH/F_TCH/H_PDCH + - phys_chan_config: TCH/F_TCH/H_PDCH + - phys_chan_config: TCH/F_TCH/H_PDCH + - phys_chan_config: TCH/F_TCH/H_PDCH + - phys_chan_config: TCH/F_TCH/H_PDCH +---- + +*TODO*: detailed descriptions diff --git a/Osmo-GSM-Tester/chapters/debugging.adoc b/Osmo-GSM-Tester/chapters/debugging.adoc new file mode 100644 index 0000000..bea1e5c --- /dev/null +++ b/Osmo-GSM-Tester/chapters/debugging.adoc @@ -0,0 +1,4 @@ +[[debugging]] +== Debugging + +*TODO*: describe how to invoke 'ipdb3' and step into a suite's test script diff --git a/Osmo-GSM-Tester/chapters/intro.adoc b/Osmo-GSM-Tester/chapters/intro.adoc new file mode 100644 index 0000000..c45e808 --- /dev/null +++ b/Osmo-GSM-Tester/chapters/intro.adoc @@ -0,0 +1,269 @@ +== Introduction with Examples + +The osmo-gsm-tester is software to run automated tests of real GSM hardware, +foremost to verify that ongoing Osmocom software development continues to work +with various BTS models, while being flexibly configurable and extendable. + +A 'main unit' (general purpose computer) is connected via ethernet and/or USB to +any number of BTS models and to any number of GSM modems via USB. The modems +and BTS instances' RF transceivers are typically wired directly to each other +via RF distribution chambers to bypass the air medium and avoid disturbing real +production cellular networks. Furthermore, the setup may include adjustable RF +attenuators to model various distances between modems and base stations. + +The osmo-gsm-tester software runs on the main unit to orchestrate the various +GSM hardware and run predefined test scripts. It typically receives binary +packages from a jenkins build service. It then automatically configures and +launches an Osmocom core network on the main unit and sets up and runs BTS +models as well as modems to form a complete ad-hoc GSM network. On this setup, +predefined test suites, combined with various scenario definitions, are run to +verify stability of the system. + +The osmo-gsm-tester is implemented in Python (version 3). It uses the ofono +daemon to control the modems connected via USB. BTS software is either run +directly on the main unit (e.g. for osmo-bts-trx, osmo-bts-octphy), run via SSH +(e.g. for a sysmoBTS) or assumed to run on a connected BTS model (e.g. for +ip.access nanoBTS). + +.Typical osmo-gsm-tester setup +[graphviz] +---- +digraph G { + rankdir=LR; + jenkins + subgraph cluster_gsm_hardware { + label = "GSM Hardware"; + style=dotted + + modem0 [shape=box label=Modem] + modem1 [shape=box label=Modem] + modem2 [shape=box label=Modem] + osmo_bts_sysmo [label="sysmocom sysmoBTS\nrunning osmo-bts-sysmo" shape=box] + B200 [label="Ettus B200" shape=box] + octphy [label="Octasic octphy BTS" shape=box] + nanoBTS [label="ip.access nanoBTS" shape=box] + rf_distribution [label="RF distribution"] + + {modem0 modem1 modem2 osmo_bts_sysmo B200 octphy nanoBTS}->rf_distribution [dir=both arrowhead="curve" arrowtail="curve"] + } + subgraph cluster_main_unit { + label = "Main Unit" + osmo_gsm_tester [label="Osmo-GSM-Tester\ntest suites\n& scenarios"] + ofono [label="ofono daemon"] + OsmoNITB + osmo_bts_trx [label="osmo-bts-trx"] + osmo_bts_octphy [label="osmo-bts-octphy"] + } + + + jenkins->osmo_gsm_tester [label="trial\n(binaries)"] + osmo_gsm_tester->jenkins [label="results"] + ofono->modem0 [label="USB"] + ofono->modem1 [label="USB"] + ofono->modem2 [label="USB"] + osmo_gsm_tester-> {OsmoNITB osmo_bts_trx osmo_bts_octphy} + osmo_gsm_tester-> osmo_bts_sysmo [taillabel="SSH"] + osmo_gsm_tester-> ofono [taillabel="DBus"] + osmo_bts_trx->B200 [label="USB"] + osmo_bts_octphy->octphy [label="raw eth"] + {osmo_bts_sysmo B200 octphy nanoBTS}->OsmoNITB [label="eth"] +} +---- + +=== Typical Test Script + +A typical single test script (part of a suite) may look like this: + +---- +#!/usr/bin/env python3 +from osmo_gsm_tester.test import * + +print('use resources...') +nitb = suite.nitb() +bts = suite.bts() +ms_mo = suite.modem() +ms_mt = suite.modem() + +print('start nitb and bts...') +nitb.bts_add(bts) +nitb.start() +sleep(1) +assert nitb.running() +bts.start() + +nitb.subscriber_add(ms_mo) +nitb.subscriber_add(ms_mt) + +ms_mo.connect(nitb) +ms_mt.connect(nitb) +wait(nitb.subscriber_attached, ms_mo, ms_mt) + +sms = ms_mo.sms_send(ms_mt.msisdn) +wait(ms_mt.sms_received, sms) +---- + +=== Resource Resolution + +- A global configuration defines which hardware is connected to the + osmo-gsm-tester main unit. +- Each suite contains a number of test scripts. The amount of resources a test + may use is defined by the test suite's 'suite.conf'. +- Which specific modems, BTS models, NITB IP addresses etc. are made available + to a test run is typically determined by a combination of scenario + configurations -- or picked automatically if not. + +[[resources_conf_example]] +=== Typical 'resources.conf' + +A global configuration of hardware may look like below; for details, see +<>. + +---- +nitb_iface: +- addr: 10.42.42.1 +- addr: 10.42.42.2 +- addr: 10.42.42.3 + +bts: +- label: sysmoBTS 1002 + type: osmo-bts-sysmo + addr: 10.42.42.114 + band: GSM-1800 + +- label: octBTS 3000 + type: osmo-bts-octphy + addr: 10.42.42.115 + band: GSM-1800 + trx_list: + - hw_addr: 00:0c:90:32:b5:8a + net_device: eth0.2342 + +- label: Ettus B210 + type: osmo-bts-trx + addr: 10.42.42.116 + band: GSM-1800 + +- label: nanoBTS 1900 + type: nanobts + addr: 10.42.42.190 + band: GSM-1900 + trx_list: + - hw_addr: 00:02:95:00:41:b3 + +arfcn: + - arfcn: 512 + band: GSM-1800 + - arfcn: 514 + band: GSM-1800 + + - arfcn: 540 + band: GSM-1900 + - arfcn: 542 + band: GSM-1900 + +modem: +- label: m7801 + path: '/wavecom_0' + imsi: 901700000007801 + ki: D620F48487B1B782DA55DF6717F08FF9 + +- label: m7802 + path: '/wavecom_1' + imsi: 901700000007802 + ki: 47FDB2D55CE6A10A85ABDAD034A5B7B3 + +- label: m7803 + path: '/wavecom_2' + imsi: 901700000007803 + ki: ABBED4C91417DF710F60675B6EE2C8D2 +---- + +=== Typical 'suites/*/suite.conf' + +The configuration that reserves a number of resources for a test suite may look +like this: + +---- +resources: + nitb_iface: + - times: 1 + bts: + - times: 1 + modem: + - times: 2 +---- + +It may also request e.g. specific BTS models, but this is typically left to +scenario configurations. + +=== Typical 'scenarios/*.conf' + +For a suite as above run as-is, any available resources are picked. This may be +combined with any number of scenario definitions to constrain which specific +resources should be used, e.g.: + +---- +resources: + bts: + - type: osmo-bts-sysmo +---- + +Which 'nitb_iface' or 'modem' is used in particular doesn't really matter, so +it can be left up to the osmo-gsm-tester to pick these automatically. + +Any number of such scenario configurations can be combined in the form +':++...', e.g. 'my_suite:sysmo+tch_f+amr'. + +=== Typical Invocations + +Each invocation of osmo-gsm-tester deploys a set of pre-compiled binaries for +the Osmocom core network as well as for the Osmocom based BTS models. To create +such a set of binaries, see <>. + +Examples for launching test trials: + +- Run the default suites (see <>) on a given set of binaries: + +---- +osmo-gsm-tester.py path/to/my-trial +---- + +- Run an explicit choice of 'suite:scenario' combinations: + +---- +osmo-gsm-tester.py path/to/my-trial -s sms:sysmo -s sms:trx -s sms:nanobts +---- + +- Run one 'suite:scenario' combination, setting log level to 'debug' and + enabling logging of full python tracebacks, and also only run just the + 'mo_mt_sms.py' test from the suite, e.g. to investigate a test failure: + +---- +osmo-gsm-tester.py path/to/my-trial -s sms:sysmo -l dbg -T -t mo_mt +---- + +A test script may also be run step-by-step in a python debugger, see +<>. + +=== Resource Reservation for Concurrent Trials + +While a test suite runs, the used resources are noted in a global state +directory in a reserved-resources file. This way, any number of trials may be +run consecutively without resource conflicts. Any test trial will only use +resources that are currently not reserved by any other test suite. The +reservation state is human readable. + +The global state directory is protected by a file lock to allow access by +separate processes. + +Also, the binaries from a trial are never installed system-wide, but are run +with a specific 'LD_LIBRARY_PATH' pointing at the trial's 'inst', so that +several trials can run consecutively without conflicting binary versions. + +Once a test suite run is complete, all its reserved resources are torn down (if +the test scripts have not done so already), and the reservations are released +automatically. + +If required resources are unavailable, the test trial fails. For consecutive +test trials, a test run needs to either wait for resources to become available, +or test suites need to be scheduled to make sense. (*<- TODO*) diff --git a/Osmo-GSM-Tester/chapters/test_api.adoc b/Osmo-GSM-Tester/chapters/test_api.adoc new file mode 100644 index 0000000..cabde4c --- /dev/null +++ b/Osmo-GSM-Tester/chapters/test_api.adoc @@ -0,0 +1,3 @@ +== Test API + +*TODO* diff --git a/Osmo-GSM-Tester/chapters/trial.adoc b/Osmo-GSM-Tester/chapters/trial.adoc new file mode 100644 index 0000000..16b3641 --- /dev/null +++ b/Osmo-GSM-Tester/chapters/trial.adoc @@ -0,0 +1,21 @@ +[[trials]] +== Trial: Binaries to be Tested + +A trial is a set of pre-built binaries to be tested. They are typically built +by jenkins using the build scripts found in osmo-gsm-tester's source in the +'contrib/' dir. + +A trial comes in the form of a directory containing a number of '*.tgz' tar +archives as well as a 'checksums.md5' file to verify the tar archives' +integrity. + +When the osmo-gsm-tester is invoked to run on such a trial directory, it will +create a sub directory named 'inst' and unpack the tar archives into it. + +For each test run on this trial, a new subdirectory in the trial dir is +created, named in the form of 'run.'. A symbolic link 'last-run' +will point at the most recently created run dir. This run dir will accumulate +the rendered configuration files used for the trial run as well as a test log +(<- *TODO*) and stdout and stderr outputs of the binaries run for the trial. +(*TODO*->) When the test is complete, jenkins parsable XML reports for the test +run will be written to the 'run.' subdir. diff --git a/Osmo-GSM-Tester/osmo-gsm-tester-manual-docinfo.xml b/Osmo-GSM-Tester/osmo-gsm-tester-manual-docinfo.xml new file mode 100644 index 0000000..923b8ad --- /dev/null +++ b/Osmo-GSM-Tester/osmo-gsm-tester-manual-docinfo.xml @@ -0,0 +1,47 @@ + + + 1 + April 13, 2017 + NH + + Initial version. + + + + + + + Neels + Hofmeyr + nhofmeyr at sysmocom.de + NH + + sysmocom + sysmocom - s.f.m.c. GmbH + Senior Developer + + + + + + 2017 + sysmocom - s.f.m.c. GmbH + + + + + Permission is granted to copy, distribute and/or modify this + document under the terms of the GNU Free Documentation License, + Version 1.3 or any later version published by the Free Software + Foundation; with the Invariant Sections being just 'Foreword', + 'Acknowledgements' and 'Preface', with no Front-Cover Texts, + and no Back-Cover Texts. A copy of the license is included in + the section entitled "GNU Free Documentation License". + + + The Asciidoc source code of this manual can be found at + + http://git.osmocom.org/osmo-gsm-manuals/ + + + diff --git a/Osmo-GSM-Tester/osmo-gsm-tester-manual.adoc b/Osmo-GSM-Tester/osmo-gsm-tester-manual.adoc new file mode 100644 index 0000000..a3fb88c --- /dev/null +++ b/Osmo-GSM-Tester/osmo-gsm-tester-manual.adoc @@ -0,0 +1,18 @@ +Osmo-GSM-Tester Manual +====================== +Neels Hofmeyr + +== WARNING: Work in Progress + +*NOTE: The osmo-gsm-tester is still in pre-alpha stage: some parts are still +incomplete, and details will still change and move around.* + +include::chapters/intro.adoc[] + +include::chapters/config.adoc[] + +include::chapters/trial.adoc[] + +include::chapters/test_api.adoc[] + +include::chapters/debugging.adoc[] -- To view, visit https://gerrit.osmocom.org/2325 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I8a9c0bfbce0072359c5094b940f225082d6847a7 Gerrit-PatchSet: 2 Gerrit-Project: osmo-gsm-manuals Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Sun Apr 16 22:22:49 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 16 Apr 2017 22:22:49 +0000 Subject: libosmo-netif[master]: stream.c: Fix SCTP_NODELAY setting In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2380 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ic04cb8bb5ff41f177f7f5b7f7e2a2ecc686dd4c0 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sun Apr 16 22:22:52 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 16 Apr 2017 22:22:52 +0000 Subject: [MERGED] libosmo-netif[master]: stream.c: Fix SCTP_NODELAY setting In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: stream.c: Fix SCTP_NODELAY setting ...................................................................... stream.c: Fix SCTP_NODELAY setting We were using the wrong variable when setting the SCTP_NODELAY, resulting in the setsoctkopt() fialing. Change-Id: Ic04cb8bb5ff41f177f7f5b7f7e2a2ecc686dd4c0 --- M src/stream.c 1 file changed, 1 insertion(+), 1 deletion(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/stream.c b/src/stream.c index 653f26b..ed73a62 100644 --- a/src/stream.c +++ b/src/stream.c @@ -551,7 +551,7 @@ } if (link->flags & OSMO_STREAM_SRV_F_NODELAY) { - ret = setsockopt_nodelay(ret, link->proto, 1); + ret = setsockopt_nodelay(sock_fd, link->proto, 1); if (ret < 0) goto error_close_socket; } -- To view, visit https://gerrit.osmocom.org/2380 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ic04cb8bb5ff41f177f7f5b7f7e2a2ecc686dd4c0 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sun Apr 16 23:00:23 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 16 Apr 2017 23:00:23 +0000 Subject: [PATCH] libosmo-sccp[master]: xua_as_fsm: We might change to AS_INACTIVE after T(r) expiry Message-ID: Review at https://gerrit.osmocom.org/2381 xua_as_fsm: We might change to AS_INACTIVE after T(r) expiry Depending on whether or not any ASP is INACTIVE, we need to go to AS_INACTIVE or AS_DOWN after T(r) expiry in the xua_as_fsm. Found by m3ua-testtool testcase m3ua-sgp-aspsm-o-003 Change-Id: Iad6b176a5c95a28fbd5ba437696c2e6e160bdb00 --- M src/xua_as_fsm.c 1 file changed, 4 insertions(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/81/2381/1 diff --git a/src/xua_as_fsm.c b/src/xua_as_fsm.c index 282a6bf..36aed64 100644 --- a/src/xua_as_fsm.c +++ b/src/xua_as_fsm.c @@ -296,7 +296,10 @@ LOGPFSM(fi, "T(r) expired; dropping queued messages\n"); while ((msg = msgb_dequeue(&xafp->recovery.queued_msgs))) talloc_free(msg); - osmo_fsm_inst_state_chg(fi, XUA_AS_S_DOWN, 0, 0); + if (check_any_other_asp_not_down(xafp->as, NULL)) + osmo_fsm_inst_state_chg(fi, XUA_AS_S_INACTIVE, 0, 0); + else + osmo_fsm_inst_state_chg(fi, XUA_AS_S_DOWN, 0, 0); break; case XUA_AS_E_TRANSFER_REQ: /* enqueue the to-be-transferred message */ -- To view, visit https://gerrit.osmocom.org/2381 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Iad6b176a5c95a28fbd5ba437696c2e6e160bdb00 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Sun Apr 16 23:00:24 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 16 Apr 2017 23:00:24 +0000 Subject: [PATCH] libosmo-sccp[master]: xua_asp_fsm: Fix ordering of messages to pass M3UA_SGP_ASPSM... Message-ID: Review at https://gerrit.osmocom.org/2382 xua_asp_fsm: Fix ordering of messages to pass M3UA_SGP_ASPSM_O_003 I don't think the order of messages is that important (and specified in the RFC), but let's do this to make the m3ua-testtool case happy. Change-Id: I2e150e941a6fcfd203944f5b20bd07c07193f44a --- M src/xua_asp_fsm.c 1 file changed, 2 insertions(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/82/2382/1 diff --git a/src/xua_asp_fsm.c b/src/xua_asp_fsm.c index ce15038..a0f93bd 100644 --- a/src/xua_asp_fsm.c +++ b/src/xua_asp_fsm.c @@ -546,10 +546,11 @@ * an Error message ("Unexpected Message), and the * remote ASP state is changed to ASP-INACTIVE in all * relevant Application Servers */ + peer_send_error(fi, M3UA_ERR_UNEXPECTED_MSG); osmo_fsm_inst_state_chg(fi, XUA_ASP_S_INACTIVE, 0, 0); + peer_send(fi, XUA_ASP_E_ASPSM_ASPUP_ACK, NULL); send_xlm_prim_simple(fi, OSMO_XLM_PRIM_M_ASP_INACTIVE, PRIM_OP_INDICATION); - peer_send_error(fi, M3UA_ERR_UNEXPECTED_MSG); break; case XUA_ASP_E_ASPTM_ASPAC: /* only in role SG */ -- To view, visit https://gerrit.osmocom.org/2382 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I2e150e941a6fcfd203944f5b20bd07c07193f44a Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Mon Apr 17 07:51:16 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 17 Apr 2017 07:51:16 +0000 Subject: libosmo-sccp[master]: xua_as_fsm: We might change to AS_INACTIVE after T(r) expiry In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2381 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Iad6b176a5c95a28fbd5ba437696c2e6e160bdb00 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Mon Apr 17 07:51:19 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 17 Apr 2017 07:51:19 +0000 Subject: libosmo-sccp[master]: xua_asp_fsm: Fix ordering of messages to pass M3UA_SGP_ASPSM... In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2382 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I2e150e941a6fcfd203944f5b20bd07c07193f44a Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Mon Apr 17 07:51:21 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 17 Apr 2017 07:51:21 +0000 Subject: [MERGED] libosmo-sccp[master]: xua_asp_fsm: Fix ordering of messages to pass M3UA_SGP_ASPSM... In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: xua_asp_fsm: Fix ordering of messages to pass M3UA_SGP_ASPSM_O_003 ...................................................................... xua_asp_fsm: Fix ordering of messages to pass M3UA_SGP_ASPSM_O_003 I don't think the order of messages is that important (and specified in the RFC), but let's do this to make the m3ua-testtool case happy. Change-Id: I2e150e941a6fcfd203944f5b20bd07c07193f44a --- M src/xua_asp_fsm.c 1 file changed, 2 insertions(+), 1 deletion(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/xua_asp_fsm.c b/src/xua_asp_fsm.c index ce15038..a0f93bd 100644 --- a/src/xua_asp_fsm.c +++ b/src/xua_asp_fsm.c @@ -546,10 +546,11 @@ * an Error message ("Unexpected Message), and the * remote ASP state is changed to ASP-INACTIVE in all * relevant Application Servers */ + peer_send_error(fi, M3UA_ERR_UNEXPECTED_MSG); osmo_fsm_inst_state_chg(fi, XUA_ASP_S_INACTIVE, 0, 0); + peer_send(fi, XUA_ASP_E_ASPSM_ASPUP_ACK, NULL); send_xlm_prim_simple(fi, OSMO_XLM_PRIM_M_ASP_INACTIVE, PRIM_OP_INDICATION); - peer_send_error(fi, M3UA_ERR_UNEXPECTED_MSG); break; case XUA_ASP_E_ASPTM_ASPAC: /* only in role SG */ -- To view, visit https://gerrit.osmocom.org/2382 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I2e150e941a6fcfd203944f5b20bd07c07193f44a Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Apr 17 07:51:21 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 17 Apr 2017 07:51:21 +0000 Subject: [MERGED] libosmo-sccp[master]: xua_as_fsm: We might change to AS_INACTIVE after T(r) expiry In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: xua_as_fsm: We might change to AS_INACTIVE after T(r) expiry ...................................................................... xua_as_fsm: We might change to AS_INACTIVE after T(r) expiry Depending on whether or not any ASP is INACTIVE, we need to go to AS_INACTIVE or AS_DOWN after T(r) expiry in the xua_as_fsm. Found by m3ua-testtool testcase m3ua-sgp-aspsm-o-003 Change-Id: Iad6b176a5c95a28fbd5ba437696c2e6e160bdb00 --- M src/xua_as_fsm.c 1 file changed, 4 insertions(+), 1 deletion(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/xua_as_fsm.c b/src/xua_as_fsm.c index 282a6bf..36aed64 100644 --- a/src/xua_as_fsm.c +++ b/src/xua_as_fsm.c @@ -296,7 +296,10 @@ LOGPFSM(fi, "T(r) expired; dropping queued messages\n"); while ((msg = msgb_dequeue(&xafp->recovery.queued_msgs))) talloc_free(msg); - osmo_fsm_inst_state_chg(fi, XUA_AS_S_DOWN, 0, 0); + if (check_any_other_asp_not_down(xafp->as, NULL)) + osmo_fsm_inst_state_chg(fi, XUA_AS_S_INACTIVE, 0, 0); + else + osmo_fsm_inst_state_chg(fi, XUA_AS_S_DOWN, 0, 0); break; case XUA_AS_E_TRANSFER_REQ: /* enqueue the to-be-transferred message */ -- To view, visit https://gerrit.osmocom.org/2381 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Iad6b176a5c95a28fbd5ba437696c2e6e160bdb00 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Apr 17 08:33:47 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 17 Apr 2017 08:33:47 +0000 Subject: [PATCH] libosmo-sccp[master]: SUA: Reject unknown Connectionless Message Types Message-ID: Review at https://gerrit.osmocom.org/2383 SUA: Reject unknown Connectionless Message Types This was found by sua-sgp-mtr-i-03 of Michael Tuexen's sua-testtool. Change-Id: I09e96a26d9f9398de07ab46cdc5af10b2ea5acc0 --- M src/sua.c 1 file changed, 11 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/83/2383/1 diff --git a/src/sua.c b/src/sua.c index 97a0785..f003f7b 100644 --- a/src/sua.c +++ b/src/sua.c @@ -498,6 +498,17 @@ { struct osmo_sccp_instance *inst = asp->inst->sccp; + OSMO_ASSERT(xua->hdr.msg_class == SUA_MSGC_CL); + + switch (xua->hdr.msg_type) { + case 0: /* Reserved, permitted by ETSI TS 101 592 5.2.3.2 */ + case SUA_CL_CLDT: + case SUA_CL_CLDR: + break; + default: + return SUA_ERR_UNSUPP_MSG_TYPE; + } + /* We feed into SCRC, which then hands the message into * either SCLC or SCOC, or forwards it to MTP */ return scrc_rx_mtp_xfer_ind_xua(inst, xua); -- To view, visit https://gerrit.osmocom.org/2383 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I09e96a26d9f9398de07ab46cdc5af10b2ea5acc0 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Mon Apr 17 08:33:47 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 17 Apr 2017 08:33:47 +0000 Subject: [PATCH] libosmo-sccp[master]: SUA: Make sure to reject unknown CO message types Message-ID: Review at https://gerrit.osmocom.org/2384 SUA: Make sure to reject unknown CO message types Found using sua-sgp-mtr-i-04 from Michael Tuexen's sua-testtool. Change-Id: Iec5c8deb6cc48a1269fd85243c1350bafd1dd815 --- M src/sua.c 1 file changed, 20 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/84/2384/1 diff --git a/src/sua.c b/src/sua.c index f003f7b..fb7545e 100644 --- a/src/sua.c +++ b/src/sua.c @@ -519,6 +519,26 @@ { struct osmo_sccp_instance *inst = asp->inst->sccp; + OSMO_ASSERT(xua->hdr.msg_class == SUA_MSGC_CO); + + switch (xua->hdr.msg_type) { + case 0: /* Reserved, permitted by ETSI TS 101 592 5.2.3.2 */ + case SUA_CO_CORE: + case SUA_CO_COAK: + case SUA_CO_COREF: + case SUA_CO_RELRE: + case SUA_CO_RELCO: + case SUA_CO_RESCO: + case SUA_CO_RESRE: + case SUA_CO_CODT: + case SUA_CO_CODA: + case SUA_CO_COERR: + case SUA_CO_COIT: + break; + default: + return SUA_ERR_UNSUPP_MSG_TYPE; + } + /* We feed into SCRC, which then hands the message into * either SCLC or SCOC, or forwards it to MTP */ return scrc_rx_mtp_xfer_ind_xua(inst, xua); -- To view, visit https://gerrit.osmocom.org/2384 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Iec5c8deb6cc48a1269fd85243c1350bafd1dd815 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Mon Apr 17 08:45:36 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 17 Apr 2017 08:45:36 +0000 Subject: [PATCH] libosmo-sccp[master]: SUA: Our SUA implementation needs an SCCP instance in ss7_in... Message-ID: Review at https://gerrit.osmocom.org/2385 SUA: Our SUA implementation needs an SCCP instance in ss7_instance So when we create a xua_server for SUA, we must make sure to create that associated SCCP instance, if it doesn't already exist. End-user programs probably normally call this during their initialization anyway, but in something like OsmoSTP, we need to auto-create it. Change-Id: Ib575763dbd00f5bd7bfbf48f227a8f5ef9528e2a --- M src/osmo_ss7.c 1 file changed, 9 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/85/2385/1 diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index 4aa7be5..6b77dc4 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -1033,6 +1033,11 @@ asp->cfg.proto = proto; asp->cfg.name = talloc_strdup(asp, name); llist_add_tail(&asp->list, &inst->asp_list); + + /* The SUA code internally needs SCCP to work */ + if (proto == OSMO_SS7_ASP_PROT_SUA && !inst->sccp) + inst->sccp = osmo_sccp_instance_create(inst, NULL); + } return asp; } @@ -1617,6 +1622,10 @@ oxs->inst = inst; llist_add_tail(&oxs->list, &inst->xua_servers); + /* The SUA code internally needs SCCP to work */ + if (proto == OSMO_SS7_ASP_PROT_SUA && !inst->sccp) + inst->sccp = osmo_sccp_instance_create(inst, NULL); + return oxs; } -- To view, visit https://gerrit.osmocom.org/2385 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ib575763dbd00f5bd7bfbf48f227a8f5ef9528e2a Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Mon Apr 17 08:46:05 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 17 Apr 2017 08:46:05 +0000 Subject: libosmo-sccp[master]: SUA: Reject unknown Connectionless Message Types In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2383 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I09e96a26d9f9398de07ab46cdc5af10b2ea5acc0 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Mon Apr 17 08:46:07 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 17 Apr 2017 08:46:07 +0000 Subject: [MERGED] libosmo-sccp[master]: SUA: Reject unknown Connectionless Message Types In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: SUA: Reject unknown Connectionless Message Types ...................................................................... SUA: Reject unknown Connectionless Message Types This was found by sua-sgp-mtr-i-03 of Michael Tuexen's sua-testtool. Change-Id: I09e96a26d9f9398de07ab46cdc5af10b2ea5acc0 --- M src/sua.c 1 file changed, 11 insertions(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/sua.c b/src/sua.c index 97a0785..f003f7b 100644 --- a/src/sua.c +++ b/src/sua.c @@ -498,6 +498,17 @@ { struct osmo_sccp_instance *inst = asp->inst->sccp; + OSMO_ASSERT(xua->hdr.msg_class == SUA_MSGC_CL); + + switch (xua->hdr.msg_type) { + case 0: /* Reserved, permitted by ETSI TS 101 592 5.2.3.2 */ + case SUA_CL_CLDT: + case SUA_CL_CLDR: + break; + default: + return SUA_ERR_UNSUPP_MSG_TYPE; + } + /* We feed into SCRC, which then hands the message into * either SCLC or SCOC, or forwards it to MTP */ return scrc_rx_mtp_xfer_ind_xua(inst, xua); -- To view, visit https://gerrit.osmocom.org/2383 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I09e96a26d9f9398de07ab46cdc5af10b2ea5acc0 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Apr 17 08:46:15 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 17 Apr 2017 08:46:15 +0000 Subject: libosmo-sccp[master]: SUA: Make sure to reject unknown CO message types In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2384 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Iec5c8deb6cc48a1269fd85243c1350bafd1dd815 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Mon Apr 17 08:46:18 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 17 Apr 2017 08:46:18 +0000 Subject: [MERGED] libosmo-sccp[master]: SUA: Make sure to reject unknown CO message types In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: SUA: Make sure to reject unknown CO message types ...................................................................... SUA: Make sure to reject unknown CO message types Found using sua-sgp-mtr-i-04 from Michael Tuexen's sua-testtool. Change-Id: Iec5c8deb6cc48a1269fd85243c1350bafd1dd815 --- M src/sua.c 1 file changed, 20 insertions(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/sua.c b/src/sua.c index f003f7b..fb7545e 100644 --- a/src/sua.c +++ b/src/sua.c @@ -519,6 +519,26 @@ { struct osmo_sccp_instance *inst = asp->inst->sccp; + OSMO_ASSERT(xua->hdr.msg_class == SUA_MSGC_CO); + + switch (xua->hdr.msg_type) { + case 0: /* Reserved, permitted by ETSI TS 101 592 5.2.3.2 */ + case SUA_CO_CORE: + case SUA_CO_COAK: + case SUA_CO_COREF: + case SUA_CO_RELRE: + case SUA_CO_RELCO: + case SUA_CO_RESCO: + case SUA_CO_RESRE: + case SUA_CO_CODT: + case SUA_CO_CODA: + case SUA_CO_COERR: + case SUA_CO_COIT: + break; + default: + return SUA_ERR_UNSUPP_MSG_TYPE; + } + /* We feed into SCRC, which then hands the message into * either SCLC or SCOC, or forwards it to MTP */ return scrc_rx_mtp_xfer_ind_xua(inst, xua); -- To view, visit https://gerrit.osmocom.org/2384 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Iec5c8deb6cc48a1269fd85243c1350bafd1dd815 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Apr 17 08:47:07 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 17 Apr 2017 08:47:07 +0000 Subject: libosmo-sccp[master]: SUA: Our SUA implementation needs an SCCP instance in ss7_in... In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2385 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ib575763dbd00f5bd7bfbf48f227a8f5ef9528e2a Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Mon Apr 17 08:47:09 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 17 Apr 2017 08:47:09 +0000 Subject: [MERGED] libosmo-sccp[master]: SUA: Our SUA implementation needs an SCCP instance in ss7_in... In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: SUA: Our SUA implementation needs an SCCP instance in ss7_instance ...................................................................... SUA: Our SUA implementation needs an SCCP instance in ss7_instance So when we create a xua_server for SUA, we must make sure to create that associated SCCP instance, if it doesn't already exist. End-user programs probably normally call this during their initialization anyway, but in something like OsmoSTP, we need to auto-create it. Change-Id: Ib575763dbd00f5bd7bfbf48f227a8f5ef9528e2a --- M src/osmo_ss7.c 1 file changed, 9 insertions(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index 4aa7be5..6b77dc4 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -1033,6 +1033,11 @@ asp->cfg.proto = proto; asp->cfg.name = talloc_strdup(asp, name); llist_add_tail(&asp->list, &inst->asp_list); + + /* The SUA code internally needs SCCP to work */ + if (proto == OSMO_SS7_ASP_PROT_SUA && !inst->sccp) + inst->sccp = osmo_sccp_instance_create(inst, NULL); + } return asp; } @@ -1617,6 +1622,10 @@ oxs->inst = inst; llist_add_tail(&oxs->list, &inst->xua_servers); + /* The SUA code internally needs SCCP to work */ + if (proto == OSMO_SS7_ASP_PROT_SUA && !inst->sccp) + inst->sccp = osmo_sccp_instance_create(inst, NULL); + return oxs; } -- To view, visit https://gerrit.osmocom.org/2385 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ib575763dbd00f5bd7bfbf48f227a8f5ef9528e2a Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Apr 17 10:44:33 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 17 Apr 2017 10:44:33 +0000 Subject: [PATCH] osmo-gsm-manuals[master]: First step towards an OsmoSTP manual In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2371 to look at the new patch set (#4). First step towards an OsmoSTP manual Change-Id: I450bfac7444ac9cb7f50c086d87cf7157c2e2a31 --- M Makefile A OsmoSTP/Makefile A OsmoSTP/chapters/overview.adoc A OsmoSTP/osmostp-usermanual-docinfo.xml A OsmoSTP/osmostp-usermanual.adoc A OsmoSTP/osmostp-vty-reference.xml A OsmoSTP/vty/stp_vty_reference.xml M common/chapters/bibliography.adoc M common/chapters/glossary.adoc A common/chapters/sigtran-osmocom.adoc A common/chapters/sigtran-simple-2g.dot A common/chapters/sigtran-simple-3g.dot A common/chapters/sigtran.adoc 13 files changed, 1,019 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-gsm-manuals refs/changes/71/2371/4 diff --git a/Makefile b/Makefile index 362f171..495ce41 100644 --- a/Makefile +++ b/Makefile @@ -7,6 +7,7 @@ cd OsmoNAT; $(MAKE) cd OsmoPCU; $(MAKE) cd Osmo-GSM-Tester; $(MAKE) + cd OsmoSTP; $(MAKE) clean: cd OsmoBTS; $(MAKE) clean @@ -17,6 +18,7 @@ cd OsmoNAT; $(MAKE) clean cd OsmoPCU; $(MAKE) clean cd Osmo-GSM-Tester; $(MAKE) clean + cd OsmoSTP; $(MAKE) clean upload: cd OsmoBTS; $(MAKE) upload @@ -27,6 +29,7 @@ cd OsmoNAT; $(MAKE) upload cd OsmoPCU; $(MAKE) upload cd Osmo-GSM-Tester; $(MAKE) upload + cd OsmoSTP; $(MAKE) upload check: cd OsmoBTS; $(MAKE) check @@ -34,6 +37,7 @@ cd OsmoBSC; $(MAKE) check cd OsmoSGSN; $(MAKE) check cd OsmoPCU; $(MAKE) check + cd OsmoSTP; $(MAKE) check # These don't use asciidoc, so they have no 'make check' target: #cd OsmoMGCP; $(MAKE) check #cd OsmoNAT; $(MAKE) check diff --git a/OsmoSTP/Makefile b/OsmoSTP/Makefile new file mode 100644 index 0000000..bf3ba8f --- /dev/null +++ b/OsmoSTP/Makefile @@ -0,0 +1,45 @@ +# XSL stylesheets downloaded from http://docbook.sourceforge.net/release/xsl/current/html/ +# Makefile from BitBake/OpenEmbedded manuals + + +EXTRA_DEPS = gen-stp-vty-docbook + +topdir = . +stp_reference = $(topdir)/osmostp-vty-reference.xml +manuals = $(stp_reference) +# types = pdf txt rtf ps xhtml html man tex texi dvi +# types = pdf txt +types = $(docbooktotypes) +docbooktotypes = pdf +# htmlcssfile = +# htmlcss = + +TOPDIR := .. +ASCIIDOCS := osmostp-usermanual + +include $(TOPDIR)/build/Makefile.asciidoc.inc +include $(TOPDIR)/build/Makefile.inc + +osmostp-usermanual.pdf: chapters/*.adoc + +clean: + -rm -rf $(cleanfiles) + -rm osmostp-usermanual__*.png + -rm osmostp-usermanual__*.svg + -rm osmostp-usermanual*.check + +gen-stp-vty-docbook: FORCE + $(call command,xsltproc -o generated/combined1.xml \ + --stringparam with $(PWD)/../common/vty_additions.xml \ + $(MERGE_DOC) vty/stp_vty_reference.xml, \ + XSLTPROC,Merging Common VTY) + $(call command,xsltproc -o generated/combined2.xml \ + --stringparam with $(PWD)/../common/stp_vty_additions.xml \ + $(MERGE_DOC) generated/combined1.xml, \ + XSLTPROC,Merging Common STP VTY) + $(call command,xsltproc -o generated/combined3.xml \ + --stringparam with $(PWD)/vty/stp_vty_additions.xml \ + $(MERGE_DOC) generated/combined2.xml, \ + XSLTPROC,Merging STP VTY) + $(call command,xsltproc ../vty_reference.xsl generated/combined3.xml > generated/docbook_vty.xml, \ + XSLTPROC,Converting STP VTY to DocBook) diff --git a/OsmoSTP/chapters/overview.adoc b/OsmoSTP/chapters/overview.adoc new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/OsmoSTP/chapters/overview.adoc diff --git a/OsmoSTP/osmostp-usermanual-docinfo.xml b/OsmoSTP/osmostp-usermanual-docinfo.xml new file mode 100644 index 0000000..4253957 --- /dev/null +++ b/OsmoSTP/osmostp-usermanual-docinfo.xml @@ -0,0 +1,47 @@ + + + 1 + April 16, 2017 + HW + + Initial OsmoSTP manual + + + + + + + Harald + Welte + hwelte at sysmocom.de + HW + + sysmocom + sysmocom - s.f.m.c. GmbH + Managing Director + + + + + + 2012-2017 + sysmocom - s.f.m.c. GmbH + + + + + Permission is granted to copy, distribute and/or modify this + document under the terms of the GNU Free Documentation License, + Version 1.3 or any later version published by the Free Software + Foundation; with the Invariant Sections being just 'Foreword', + 'Acknowledgements' and 'Preface', with no Front-Cover Texts, + and no Back-Cover Texts. A copy of the license is included in + the section entitled "GNU Free Documentation License". + + + The Asciidoc source code of this manual can be found at + + http://git.osmocom.org/osmo-gsm-manuals/ + + + diff --git a/OsmoSTP/osmostp-usermanual.adoc b/OsmoSTP/osmostp-usermanual.adoc new file mode 100644 index 0000000..2be3372 --- /dev/null +++ b/OsmoSTP/osmostp-usermanual.adoc @@ -0,0 +1,33 @@ +OsmoSTP User Manual +=================== +Harald Welte + + +include::../common/chapters/preface.adoc[] + +// include::chapters/overview.adoc[] + +include::../common/chapters/sigtran.adoc[] +include::../common/chapters/sigtran-osmocom.adoc[] + +//include::chapters/running.adoc[] +// include::chapters/control.adoc[] + +include::../common/chapters/vty.adoc[] + +include::../common/chapters/logging.adoc[] + +//include::../common/chapters/bts.adoc[] + +//include::../OsmoNITB/chapters/bts-examples.adoc[] + +//include::../common/chapters/control_if.adoc[] + +include::../common/chapters/port_numbers.adoc[] + +include::../common/chapters/bibliography.adoc[] + +include::../common/chapters/glossary.adoc[] + +include::../common/chapters/gfdl.adoc[] + diff --git a/OsmoSTP/osmostp-vty-reference.xml b/OsmoSTP/osmostp-vty-reference.xml new file mode 100644 index 0000000..807d427 --- /dev/null +++ b/OsmoSTP/osmostp-vty-reference.xml @@ -0,0 +1,38 @@ + + + + +]> + + + + + + v1 + April 16, 2017 + h2 + Initial + + + + OsmoSTP VTY Reference + + + 2012-2017 + + + + This work is copyright by sysmocom - s.f.m.c. GmbH. All rights reserved. + + + + + + &chapter-vty; + + diff --git a/OsmoSTP/vty/stp_vty_reference.xml b/OsmoSTP/vty/stp_vty_reference.xml new file mode 100644 index 0000000..a4c675e --- /dev/null +++ b/OsmoSTP/vty/stp_vty_reference.xml @@ -0,0 +1,2 @@ + + diff --git a/common/chapters/bibliography.adoc b/common/chapters/bibliography.adoc index a3c6436..d5e1c1b 100644 --- a/common/chapters/bibliography.adoc +++ b/common/chapters/bibliography.adoc @@ -106,11 +106,29 @@ https://tools.ietf.org/html/rfc1350 - [[[ietf-rfc2131]]] IETF RFC 2131: Dynamic Host Configuration Protocol https://tools.ietf.org/html/rfc2131 +- [[[ietf-rfc2719]]] IETF RFC 2719: Signal Transport over IP + https://tools.ietf.org/html/rfc2719 +- [[[ietf-rfc3331]]] IETF RFC 3331: Message Transfer Part 2 User Adaptation Layer + https://tools.ietf.org/html/rfc3331 - [[[ietf-rfc3550]]] IETF RFC 3550: RTP: A Transport protocol for Real-Time Applications https://tools.ietf.org/html/rfc3550 +- [[[ietf-rfc3868]]] IETF RFC 3868: SCCP User Adaptation Layer + https://tools.ietf.org/html/rfc3868 +- [[[ietf-rfc4165]]] IETF RFC 4165: Message Transfer Part 2 Peer-to-Peeer Adaptation Layer + https://tools.ietf.org/html/rfc4165 - [[[ietf-rfc4251]]] IETF RFC 4251: The Secure Shell (SSH) Protocol Architecture https://tools.ietf.org/html/rfc4251 +- [[[ietf-rfc4666]]] IETF RFC 4666: Message Transfer Part 3 User Adaptation Layer + https://tools.ietf.org/html/rfc4666 +- [[[itu-t-q701]]] ITU-T Q.701: Functional Description of the Message Transfer Part (MTP) + https://www.itu.int/rec/T-REC-Q.701/en/ +- [[[itu-t-q711]]] ITU-T Q.711: Functional Description of the Signalling Connection Control Part + https://www.itu.int/rec/T-REC-Q.711/en/ +- [[[itu-t-q713]]] ITU-T Q.713: Signalling connection control part formats and codes + https://www.itu.int/rec/T-REC-Q.713/en/ +- [[[itu-t-q714]]] ITU-T Q.714: Signalling connection control part procedures + https://www.itu.int/rec/T-REC-Q.714/en/ - [[[itu-t-q921]]] ITU-T Q.921: ISDN user-network interface - Data link layer specification https://www.itu.int/rec/T-REC-Q.921/en diff --git a/common/chapters/glossary.adoc b/common/chapters/glossary.adoc index c39d439..042fd3a 100644 --- a/common/chapters/glossary.adoc +++ b/common/chapters/glossary.adoc @@ -115,6 +115,8 @@ GSMTAP:: GSM tap; pseudo standard for encapsulating GSM protocol layers over UDP/IP for analysis +GT:: + Global Title; an address in SCCP GTP:: GPRS Tunnel Protocol; used between SGSN and GGSN HLR:: @@ -143,6 +145,12 @@ 44.064_ <<3gpp-ts-44-064>>) Location Area:: Location Area; a geographic area containing multiple BTS +M2PA:: + MTP2 Peer-to-Peer Adaptation; a SIGTRAN Variant (_RFC 4165_ <>) +M2UA:: + MTP2 User Adaptation; a SIGTRAN Variant (_RFC 3331_ <>) +M3UA:: + MTP3 User Adaptation; a SIGTRAN Variant (_RFC 4666_ <>) MCC:: Mobile Country Code; unique identifier of a country, e.g. 262 for Germany MFF:: @@ -163,6 +171,8 @@ core network MSISDN:: Mobile Subscriber ISDN Number; telephone number of the subscriber +MTP:: + Message Transfer Part; SS7 signaling protocol (_ITU-T Q.701_ <>) MVNO:: Mobile Virtual Network Operator; Operator without physical radio network NCC:: @@ -206,6 +216,8 @@ OTA:: Over-The-Air; Capability of operators to remotely reconfigure/reprogram ISM/USIM cards +PC:: + Point Code; an address in MTP PCH:: Paging Channel on downlink Um interface; used by network to page an MS PCU:: @@ -249,11 +261,15 @@ SACCH:: Slow Associate Control Channel on Um interface; bundled to a TCH or SDCCH, used for signalling in parallel to active dedicated channel +SCCP:: + Signaling Connection Control Part; SS7 signaling protocol (_ITU-T Q.711_ <>) SDCCH:: Slow Dedicated Control Channel on Um interface; used for signalling and SMS transport in GSM SDK:: Software Development Kit +SIGTRAN:: + Signaling Transport over IP (_IETF RFC 2719_ <>) SIM:: Subscriber Identity Module; small chip card storing subscriber identity Site:: @@ -264,8 +280,16 @@ entities with an SMSC SMSC:: Short Message Service Center; store-and-forward relay for short messages +SS7:: + Signaling System No. 7; Classic digital telephony signaling system SSH:: Secure Shell; _IETF RFC 4250_ <> to 4254 +SSN:: + Sub-System Number; identifies a given SCCP Service such as MSC, HLR +STP:: + Signaling Transfer Point; A Router in SS7 Networks +SUA:: + SCCP User Adaptation; a SIGTRAN Variant (_RFC 3868_ <>) syslog:: System logging service of UNIX-like operating systems System Information:: diff --git a/common/chapters/sigtran-osmocom.adoc b/common/chapters/sigtran-osmocom.adoc new file mode 100644 index 0000000..1e08733 --- /dev/null +++ b/common/chapters/sigtran-osmocom.adoc @@ -0,0 +1,432 @@ +== Osmocom SS7 + SIGTRAN support + +=== History / Background + +If you're upgrading from earlier releases of the Osmocom stack, this +section will give you some background about the evolution. + +==== The Past (before 2017) + +In the original implementation of the GSM BSC inside Osmocom (the +OsmoBSC program, part of OpenBSC), no SS7 support was included. + +This is despite the fact that ETSI/3GPP mandated the use of SCCP over +MTP over E1/T1 TDM lines for the A interface at that time. + +Instead of going down to the TDM based legacy physical layers, OsmoBSC +implemented someting called an IPA multiplex, which apparently some +people also refer to as SCCPlite. We have never seen any +specifications for this interface, but implemented it from scratch +using protocol traces. + +The IPA protocol stack is based on a minimal sub-set of SCCP +(including connection oriented SCCP) wrapped into a 3-byte header to +packetize a TCP stream. + +The IPA/SCCPlite based A interface existed at a time when the +ETSI/3GPP specifications did not offer any IP based transport for the +A interface. An official as added only in Release FIXME of the 3GPP +specifications. + +The A interface BSSMAP protocol refers to voice circuits (E1/T1 +timeslots) using circuit identity codes (CICs). As there are no +physical timeslots on a TCP/IP based transport layer, the CICs get +mapped to RTP streams for circuit-switched data using out-of-band +signaling via MGCP, the IETF-standardized Media Gateway Control +Protocol. + +==== The present (2017) + +In 2017, sysmocom was tasked with implementing a 3GPP AoIP compliant A +interface. This meant that lot of things had to change in the +existing code: + +* removal of the existing hard-wired SCCPlite/IPA code from OsmoBSC +* introduction of a formal SCCP User SAP at the lower boundary of + BSSMAP +* introduction of libosmo-sigtran, a comprehensive SS7 and SIGTRAN + library which includes a SCCP implementation for connectionless and + connection-oriented procedures, offering the SCCP User SAP towards + BSSAP +* introduction of an A interface in OsmoMSC (which so far offered Iu + only) +* port of the existing SUA-baesd IuCS and IuPS over to the SCCP User + SAP of libosmo-sigtran. +* Implementation of ETSI M3UA as preferred/primary transport layer for + SCCP +* Implementation of an IPA transport layer inside libosmo-sigtran, in + order to keep backwards-compatibility. + +This work enables the Osmocom universe to become more compliant +with modern Releases of 3GPP specifications, which enables +interoperability with other MSCs or even BSCs. However, this comes at +a price: Increased complexity in set-up and configuration. + +Using SS7 or SIGTRAN based transport of the A interface adds an +entirely new domain that needs to be understood by system and network +administrators setting up cellular networks based on Osmocom. + +One of the key advantages of the Osmocom architecture with OsmoNITB +was exactly this simplification and reduction of complexity, enabling +more people to set-up and operate cellular networks. + +So we have put some thought into how we can achieve compatibility with +SS7/SIGTRAN and the 3GPP specifications, while at the same time +enabling some degree of auto-configuration where a small network can +be set up without too many configuration related to the signaling +network. We have achieved this by "abusing" (or extending) the M3UA +Routing Key Management slightly. + +=== Osmocom extensions to SIGTRAN + +Osmocom has implemented some extensions to the SIGTRAN protocol suite. +Those extensions will be documented below. + +==== Osmocom M3UA Routing Key Management Extensions + +In classic M3UA, a peer identifies its remote peer based on IP address +and port details. So once an ASP connects to an SG, the SG will check +if there is any configuration that matches the source IP (and possibly +source port) of that connection in order to understand which routing +context is used - and subsequently which traffic is to be routed to +this M3UA peer. + +This is quite inflexible, as it means that every BSC in a GSM network +needs to be manually pre-configured at the SG/STP, and that +configuration on the BSC and MSC must match to enable communication. + +M3UA specifies an optional Routing Key Management (RKM) sub-protocol. +Using RKM, an ASP can dynamically tell the SG/STP, which traffic it +wants to receive. However, the idea is still that the SG has some +matching configuration. + +In OsmoSTP based on libosmo-sigtran, we decided to (optionally) enable +fully dynamic registration. This means that any ASP can simply +connect to the SG and request the dynamic creation of an ASP and AS +with a corresponding routing key for a given point code. As long as +the SG doesn't already have a route to this requested point code, The +SG will simply trust any ASP and set a corresponding route. + +This is of course highly insecure and can only be used in trusted, +internal newtworks. However, it is quite elegant in reducing the +amount of configuration complexity. All that is needed, is that an +unique point code is configured at each of the ASPs (application +programs) that connect to the STP. + +To put things more concretely: Each BSC and MSC connecting to OsmoSTP +simply needs to be configured to have a different point code, and to +know to which IP/port of the STP to connect. There's no other +configuration required for a small, autonomous, self-contained +network. OsmoSTP will automatically insall ASP, AS and route +definitions on demand, and route messages between all connected +entities. + +The same above of course also applies to HNB-GW and OsmoSGSN in the +case of Iu interfaces. + +==== IPA / SCCPlite backwards compatibility + +The fundamental problem with IPA/SCCPlite is that there's no MTP +routing label surrounding the SCCP message. This is generally +problematic in the context of connection-oriented SCCP, as there is no +addressing information inside the SCCP messages after the connection +has been established. Instead, the messages are routed based on the +MTP label, containing point codes established during connection set-up +time. + +This means that even if the SCCP messages did contain Called/Calling +Party Addresses with point codes or global titles, it would only help +us for routing connectionless SCCP. The A interface, however, is +connection-oriented. + +So in order to integrate IPA/SCCPlite with a new full-blown +SS7/SIGTRAN stack, there are the following options: + +. implement SCCP connection coupling. This is something like a proxy + for connection-oriented SCCP, and is what is used in SS7 to route + beyond a given MTP netwokr (e.g. at gateways between different MTP + networks) + +. consider all SCCP messages to be destined for the local point code + of the receiver. This then means that the SG functionality must be + included inside the MSC, and the MSC be bound to the SSN on the + local point code. + +. hard-code some DPC when receiving a message from an IPA connection. + It could be any remote PC and we'd simply route the message towards + that point code. + +But then we also have the return direction: + +. We could "assign" a unique SPC to each connected IPA client (BSC), + and then announce that PC towards the SS7 side. Return packets + would then end up at our IPA-server-bearing STP, which forwards them + to the respective IPA connection and thus BSC. On the transmit + side, we'd simply strip the MTP routing label and send the raw SCCP + message over IPA. + +. If the IPA server / SGW resides within the MSC, one could also have + some kind of handle/reference to the specific TCP connection through + which the BSC connected. All responses for a given peer would then + have to be routed back to the same connection. This is quite ugly + as it completely breaks the concepts of the SCCP User SAP, where a + user has no information (nor to worry about ) any "physical" + signaling links. + + +=== Minimal Osmocom SIGTRAN configurations for small networks + +If you're not an SS7 expert, and all you want is to run your own small +self-contained cellular network, this section explains what you need +to do. + +In general, you can consider OsmoSTP as something like an IP router. +On the application layer (in our case the BSSAP/BSSMAP or RANAP +protocols between Radio Access Network and Core Network), it is +completely invisible/transparent. The BSC connects via SCCP to the +MSC. It doesn't know that there's an STP in between, and that this +STP is performing some routing function. Compares this to your web +browser not knowing about IP routers, it just establishes an http +connection to a web server. + +This is also why most GSM nework architecture diagrams will not +explicitly show an STP. It is not part of the cellular network. +Rather, one or many STPs are part of the underlying SS7 signaling +transport network, on top of which the cellular network elements are +built. + +==== A minimal 2G configuration to get started + +You will be running the following programs: + +* OsmoBSC as the base-station controller between your BTS (possibly + running OsmoBTS) and the MSC +* OsmoMSC as the mobile switching center providing SMS and telephony + service to your subscribers +* OsmoSTP as the signal transfer point, routing messages between one + or more BSCs and the MSC + +[[fig-sigtran-simple-2g]] +.Simple signaling network for 2G (GSM) +[graphviz] +---- +include::sigtran-simple-2g.dot[] +---- + +You can use the OsmoSTP fully dynamic registration feature, so the BSCs +and the MSC will simply register with their point codes to the STP, +and the STP will create most configuration on the fly. + +All you need to make sure is: + +* to assign one unique point code to each BSC and MSC +* to point all BSCs and the MSC to connect to the IP+Port of the STP +* to configure the point code of the MSC in the BSCs + +==== A minimaal 3G configuration to get started + +You will be running the following programs: + +* OsmoHNBGW as the homeNodeB Gateway between your femtocells / small + cells and the MSC+SGSN +* OsmoMSC as the mobile switching center providing SMS and telephony + service to your subscribers +* OsmoSGSN as the Serving GPRS Support Node, providing packet data + (internet) services to your subscribers +* OsmoSTP as the signal transfer point, routing messages between one + or more HNBGWs and the MSC and SGSN + +[[fig-sigtran-simple-3g]] +.Simple signaling network for 3G (UMTS) +[graphviz] +---- +include::sigtran-simple-3g.dot[] +---- + +You can use the OsmoSTP fully dynamic registration feature, so the +HNBGWs, the SMC and the SGSNwill simply register with their point +codes to the STP, and the STP will create most configuration on the +fly. + +All you need to make sure is: + +* to assign one unique point code to each HNBGW, MSC and SGSN +* to point all HNBGWs and the MSC and SGSN to connect to the IP+Port of STP +* to configure the point code of the MSC in the HNBGWs +* to configure the point code of the SGSN in the HNBGWs + +=== Osmocom SS7 Instances + +The entire SS7 stack can be operated multiple times within one +application/program by means of so-called SS7 Instances. + +There can be any number of SS7 Instances, and each instance has its +own set of XUA Servers, ASPs, ASs, Routes, etc. + +Each SS7 Instance can have different point code formats / lengths. + +.Major Attributes of an Osmocom SS7 Instance +[options="header",cols="25%,35%,40%"] +|==== +|Name|VTY Command|Description +|ID|(config)# cs7 instance ID|The numeric identifier of this instance +|Name|(config-cs7)# name NAME|A human-readable name for this instance +|Description|(cnfig-cs7)# description DESC| More verbose description +|Primary PC|(config-cs7)# point-code PC|Primary local point code +|Network Indicator|(config-cs7)# network-indicator|Network Indicator used in MTP3 Routing Label +|Point Code Format|(config-cs7)# point-code format|Point Code Format (Default: 3.8.3) +|Point Code Delimiter|(config-cs7)# point-code delimiter|Point Code Delimiter: . or - +|==== + +=== Osmocom SS7 xUA Server + +A *xUA Server* is a server that binds + listens to a given SCTP +(SIGTRAN) or TCP (IPA) port and accepts connections from remote peers +(ASPs). + +There can be any number of xUA Servers within one SS7 Instance, as +long as they all run on a different combination of IP address and +port. + +.Major Attributes of an Osmocom SS7 xUA Server +[options="header",cols="25%,75%"] +|==== +|Name|Description +|Local IP|Local Port Number to which the server shall bind/listen +|Local Port|Local IP Address to which the server shall bind/listen +|Protocol|Protocol (M3UA, SUA, IPA) to be operated by this server +|Accept Dynamic ASPs|Should we accept connections from ASPs that are not explicitly pre-configured with their source IP and port? +|==== + + +=== Osmocom SS7 Users + +A SS7 User is part of a program that binds to a given MTP-Layer +Service Indicator (SI). The Osmocom SS7 stack offers an API to +register SS7 Users, as well as the VTY command ``show cs7 instance +<0-15> users'' to list the currently registered users. + +=== Osmocom SS7 Links + +TBD. + +=== Osmocom SS7 Linksets + +TBD. + +=== Osmocom SS7 Application Servers + +This corresponds 1:1 to the SIGTRAN concept of an Application Server, +i.e. a given external Application that interfaces the SS7 network via +a SS7 protocol variant such as M3UA. + +In the context of Osmocom, for each program connecting to a STP (like +a BSC or MSC), you will have one Application Server definition. + +An AS has the following properties: + +.Major Attributes of an Osmocom SS7 Application Server +[options="header",cols="25%,75%"] +|==== +|Name|Description +|Name|A human-readable name for this instance +|Description|More verbose description (for human user only) +|Protocol|Protocol (M3UA, SUA, IPA) to be operated by this server +|Routing Key|Routing Key (mostly Point Code) routed to this AS +|Traffic Mode|Theoretically Bradcast, Load-Balance. Currently only Ovverride +|Recovery Timeout|Duration of the AS T(r) recovery timer. During this time, + outgoing messages are queued. If the AS is ACTIVE + before timer expiration, the queue is drained. At + expriation, the queue is flushed. +|State|Application Server State (Down, Inactive, Active, Pending) +|ASPs|Which ASPs are permitted to transfer traffic for this AS +|==== + +=== Osmocom SS7 Application Server Processes + +An Application Server Process corresponds to a given SCTP (or TCP) +connection. From the STP/SG (Server) point-of-view, those are +incoming connections from Application Servers such as the BSCs. From +the ASP (Client) Point of view, it has one ``osmo_ss7_asp'' object for +each outbound SIGTARN connection. + +An ASP has the following properties: + +.Major Attributes of an Osmocom SS7 Application Server Process +[options="header",cols="25%,75%"] +|==== +|Name|Description +|Name|A human-readable name for this instance +|Description|More verbose description (for human user only) +|Protocol|Protocol (M3UA, SUA, IPA) to be operated by this server +|Role|Server (SG) or Client (ASP)? +|Local Port|Port Number of the local end of the connection +|Local IP|IP Address of the local end of the connection +|Remote Port|Port Number of the remote end of the connection +|Remote IP|IP Address of the remote end of the connection +|State|ASP State (Down, Inactive, Active) +|==== + +=== Osmocom SS7 Routes + +An Osmocom SS7 Route routes traffic with a matching destination point +code and point code mask (similar to IP Address + Netmask) towards a +specified SS7 Linkset or Application Server. The Linkset or +Application Servers are identified by their name. + +.Major Attributes of an Osmocom SS7 Application Server Process +[options="header",cols="25%,75%"] +|==== +|Name|Description +|Point Code|Destination Point Code for this route +|Mask|Destination Mask for this route (like an IP netmask) +|Linkset/AS Name|Destination Linkset or AS, identified by name +|==== + + +=== Osmocom SCCP Instances + +An Osmocom SS7 Instance can be bound to an Osmocom SS7 Instance. It +will register/bind for the ITU-standard Service Indicator (SI). + +=== Osmocom SCCP User + +An Program (like a BSC) will _bind_ itself to a given well-known +sub-system number (SSN) in order to receive SCCP messages destined for +this SSN. + +There is an API to bind a program to a SSN, which implicitly generates +an SCCP User object. + +The ``show cs7 instance <0-15> sccp users'' command can be used on the +VTY to obtain a list of currently bound SCCP users, as well as their +corresponding SSNs. + +=== Osmocom SCCP Connection + +This is how Osmocom represents each individual connection of +connection-oriented SCCP. + +To illustrate the practical applicaiton: For the common use case of +the A or Iu interfaces, this means that every dedicated radio channel +that is currently active to any UE/MS has one SCCP connection to the +MSC and/or SGSN. + +The ``show cs7 instance <0-15> sccp connections'' command can be used +on the VTY to obtain a list of currently active SCCP connections, as +well as their source/destination and current state. + + +=== Osmocom SCCP User SAP + +The Osmocom SCCP User SAP (Service Access Point) is the programming +interface between the SCCP Provider (libosmo-sigtran) and the SCCP +User. It follows primitives as laid out in <>, encapsulated +in ``osmo_prim'' structures. + +=== Osmocom MTP User SAP + +The Osmocom MTP User SAP (Service Access Point) is the programming +interface betwen the MTP Provider and the MTP User (e.g. SCCP). It +follows primitives as laid out in <>, encapsulated in +``osmo_prim'' structures. diff --git a/common/chapters/sigtran-simple-2g.dot b/common/chapters/sigtran-simple-2g.dot new file mode 100644 index 0000000..28098fd --- /dev/null +++ b/common/chapters/sigtran-simple-2g.dot @@ -0,0 +1,22 @@ +digraph G { + rankdir=LR; + MS0 [label="MS"]; + MS1 [label="MS"]; + MS2 [label="MS"]; + MS3 [label="MS"]; + BTS0 [label="BTS"]; + BTS1 [label="BTS"]; + BSC [label="OsmoBSC"]; + MSC [label="OsmoMSC"]; + STP [label="OsmoSTP"]; + + MS0 -> BTS0; + MS1 -> BTS0; + MS2 -> BTS1; + MS3 -> BTS1; + BTS0 -> BSC [label="Abis/IP"]; + BTS1 -> BSC [label="Abis/IP"]; + BSC -> STP [label="SCCP/M3UA"]; + STP -> MSC [label="SCCP/M3UA", dir="back"]; +} + diff --git a/common/chapters/sigtran-simple-3g.dot b/common/chapters/sigtran-simple-3g.dot new file mode 100644 index 0000000..eac363d --- /dev/null +++ b/common/chapters/sigtran-simple-3g.dot @@ -0,0 +1,24 @@ +digraph G { + rankdir=LR; + UE0 [label="UE"]; + UE1 [label="UE"]; + UE2 [label="UE"]; + UE3 [label="UE"]; + HNB0 [label="hNodeB"]; + HNB1 [label="hNodeB"]; + HNBGW [label="OsmoHNBGW"]; + MSC [label="OsmoMSC"]; + SGSN [label="OsmoSGSN"]; + STP [label="OsmoSTP"]; + + UE0 -> HNB0; + UE1 -> HNB0; + UE2 -> HNB1; + UE3 -> HNB1; + HNB0 -> HNBGW [label="Iuh (RUA)"]; + HNB1 -> HNBGW [label="Iuh (RUA)"]; + HNBGW -> STP [label="Iu (SCCP/M3UA)"]; + STP -> MSC [label="Iu (SCCP/M3UA)", dir="back"]; + STP -> SGSN [label="Iu (SCCP/M3UA)", dir="back"]; +} + diff --git a/common/chapters/sigtran.adoc b/common/chapters/sigtran.adoc new file mode 100644 index 0000000..9d8e42e --- /dev/null +++ b/common/chapters/sigtran.adoc @@ -0,0 +1,330 @@ +== Signaling Networks: SS7 and SIGTRAN + +Classic digital telephony networks (whether wired or wireless) use the +ITU-T SS7 (Signaling System 7) to exchange signaling information +between network elements. + +Most of the ETIS/3GPP interfaces in the GSM and UMTS network are also +based on top of [parts of] SS7. This includes, among others, the +following interfaces: + +* _A_ interface between BSC and MSC +* _IuCS_ interface between RNC (or HNB-GW) and MSC +* _IuPS_ interface between RNC (or HNB-GW) and SGSN + +NOTE:: This does not include the A-bis interface between BTS and BSC. +While Abis traditionally is spoken over the same physical TDM circuits +as SS7, the protocol stack from L2 upwars is quite different (Abis +uses LAPD, while SS7 uses MTP)! + +=== Physical Layer + +The traditional physical layer of SS7 is based on TDM (time division +multiplex) links of the PDH/SDH family, as they were common in ISDN +networks. Some people may know their smallest incarnation as +so-called E1/T1 links. It can run either on individual 64kBps +timeslots of such a link, or on entire 2Mbps/1.5MBps E1/T1 links. + +There are also specifications for SS7 over ATM, though it is unclear +to the author if this is actually still used anywhere. + +On top of the Physical Layer is the Message Transfer Part (MTP). + +=== Message Transfer Part (MTP) + +MTP is the lower layer of the SS7 protocol stack. It is comprised of +two sub-layes, called MTP2 and MTP3. + +Nodes in a MTP network are addressed by their unique PC (Point Code). + +A _MTP Routing Label_ is in the MTP header and indicates the +_Originationg Point Code_ (OPC) as well as the _Destination Point +Code_ (DPC) and the _Service Indicator Octet_ (SIO). The SIO is used +to de-multiplex between different upper-layer protocol such as ISUP, +TUP or SCCP. + +Routing is performed by means of routers with routing tables, similar +to routing is performed in IP networks. Even the concept of a _point +code mask_ analogous to the _netmask_ exists. + +Routers are connected with one another over one or more _Link Sets_, +each comprised of one or multiple _Links_. Multiple Links in a +Linkset exist both for load sharing as well as for fail over purposes. + +==== Point Codes + +The length of point codes depends on the particular MTP dialect that +is used. In the 1980ies, when international telephony signaling +networks were established, most countries had their own national +dialects with certain specifics. + +Today, mostly the ITU and ANSI variants survive. The ITU variant uses +14bit point codes, while the ANSI variant uses 24 bit point code +length. + +Point Codes can be represented either as unsigned integers, or +grouped. Unfortunately there is no standard as to their +representation. In ITU networks, the _3.8.3_ notation is commonly +used, i.e. one decimal for the first 3 bits, followed by one decimal +for the center 8 bits, followed by another decimal for the final 3 +bits. + +Example:: The Point Code *1.5.3* (in 3.8.3 notation) is 1*2^11^ + 5*2^3^ + 3 = *2091 decimal*. + +=== Higher-Layer Protocols + +There are various higher-layer protocols used on top of MTP3, such as +TUP, ISUP, BICC as well as SCCP. Those protocols exist side-by-side +on top of MTP3, similar to e.g. ICMP, TCP and UDP existing +side-by-side on top of IP. + +In the context of cellular networks, SCCP is the most relevant part. + +=== Signaling Connection Control Part (SCCP) + +SCCP runs on top of MTP3 and creates something like an overlay network +on top of it. SCCP communication can e.g. span multiple different +isolated MTP networks, each with their own MTP dialect and addressing. + +SCCP provides both connectionless (datagram) and connection-oriented +services. Both are used in the context of cellular networks. + +==== SCCP Adresses + +SCCP Adresses are quite complex. This is due to the fact that it is +not simply one address format, but in fact a choice of one or multiple +different types of addresses. + +SCCP Addresses exist as _Calling Party_ and _Called Party_ addresses. +In the context of connectionless datagram services, the sender is +always the Calling Party, and the receiver the Called Party. In +connection-oriented SCCP, they resemble the initiator and recipient of +the connection. + +.SCCP Address Parts +[options="header",cols="10%,20%,70%"] +|==== +|Acronym|Name|Description +|SSN|Sub-System Number|Describes a given application such as e.g. a + GSM MSC, BSC or HLR. Can be compared to port + numbers on the Internet +|PC|Point Code |The Point Code of the underlying MTP network +|GT|Global Title |What most people would call a "phone number". + However, Global Titles come in many different + numbering plans, and only one of them (E.164) + resembles actual phone numbers. +|RI|Routing Indicator |Determines if message shall be routed on PC+SSN + or on GT basis +|==== + +==== Global Titles + +A Global Title is a (typically) globally unique address in the global +telephony network. The body of the Global Title consists of a series +of BCD-encoded digits similar to what everyone knows as phone numbers. + +A GT is however not only the digits of the "phone number", but also +some other equally important information, such as the _Numbering Plan_ +as well as the _Nature of Address Indication_. + +.Global Title Parts +[options="header",cols="10%,20%,70%"] +|==== +|Acronym|Name|Description +|GTI|Global Title Indicator|Determines the GT Format. Ranges from no + GT (0) to GT+TT+NP+ES+NAI (4) +|NAI|Nature of Address Indicator|Exists in GTI=1 and is sort of a mixture of TON + NPI +|TT|Translation Type |Used as a look-up key in Global Title Translation Tables +|NP|Numbering Plan |Indicates ITU Numbering Plan, such as E.164, E.212, E.214 +|ES|Encoding Scheme |Just a peculiar way to idicate the length of the digits +|- |Signals |The actual "phone number digits" +|==== + +For more information about SCCP Adresses and Global Titles, please +refer to <> + + +==== Global Title Translation (GTT) + +Global Title Translation is a process of re-writing the Global Title +on-the-fly while a signaling message passes a STP. + +Basically, a SCCP message is first transported by MTP3 on the MTP +level to the Destination Point Code indicated in the MTP Routing +Label. This process uses MTP routing and is transparent to SCCP. + +Once the SCCP message arrives at the MTP End-Node identified by the +Destination Point Code, the message is handed up to the local SCCP +stack, which then may implement Global Title Translation. + +The input to the GTT process is +* the destination address of the SCCP message +* a local list/database of Global Title Translation Rules + +The successful output of he GTT includes +* A new Routing Indicator +* The Destination Point Code to which the message is forwarded on MTP + level +* a Sub-system Number (if RI is set to "Route on SSN") +* a new Global Title (if RI is set to "Route on GT"), e.g. with translated digits. + +Between sender and recipient of a signaling message, there can be many +instances of Global Title Translation (up to 15 as per the hop +counter). + +For more information on Global Title Translation, please refer to +<>. + + +==== Peculiarities of Connection Oriented SCCP + +Interestingly, Connection-Oriented SCCP messages carry SCCP Adresses +*only during connection establishment*. All data messages during +an ongoing connection do not contain a Called or Calling Party +Address. Instead, they are routed only by the MTP label, which is +constructed from point code information saved at the time the +connection is established. + +This means that connection-oriented SCCP can not be routed across MTP +network boundaries the same way as connectionless SCCP messages. +Instead, an STP would have to perform _connection coupling_, whic is +basically the equivalent of an application-level proxy between two +SCCP connections, each over one of the two MTP networks. + +This is probably mostly of theoretical relevance, as +connection-oriented SCCP is primarily used betwen RAN and CN of +cellular network inside one operator, i.e. not across multiple MTP +networks. + +=== SIGTRAN - SS7 over IP Networks + +At some point, IP based networks became more dominant than classic +ISDN networks, and 3GPP as well as IETF were working out methods in +which telecom signaling traffic can be adapted over IP based +networks. + +Initially, only the edge of the network (i.e. the applications talking +to the network, such as HLR or MSC) were attached to the existing old +SS7 backbone by means as SUA and M3UA. Over time, even the links of +the actual network backbone networks became more and more IP based. + +In order to replace existing TDM-based SS7 links/liksets with SIGTRAN, +the M2UA or M2PA variants are used as a kind of drop-in replacement +for physical links. + +All SIGTRAN share that while they use IP, they don't use TCP or UDP +but operate over a (then) newly-introduced Layer 4 transport protocol +on top of IP: SCTP (Stream Control Transmission Protocol). + +Despite first being specified in October 2000 as IETF RFC 2960, it +took a long time until solid implementations of SCTP ended up in +general-purpose operating systems. SCTP is not used much outside the +context of SIGTAN, which means implementations often suffer from bugs, +and many parts of the public Internet do not carry SCTP traffic due to +restrictive firewalls and/or ignorant network administrators. + +==== SIGTRAN Concepts / Terminology + +Like every protocol or technologoy, SIGTRAN brings with it its own +terminologyand concepts. This section tries to briefly introduce +them. For more information, please see the related IETF RFCs. + +===== Signaling Gateway (SG) + +The Signaling Gateway (SG) interconnects the SS7 network wit external +applications. It translates (parts of) the SS7 protocol stack into an +IP based SIGTRAN protocol stack. Which parts at whcih level of the +protocol stack are translated to what depends on the specific SIGTRAN +dialect. + +A SG is traditionally attached to the TDM-Based SS7 network and offers +SIGTRAN/IP based applications a way to remotely attach to the SS7 +network. + +A SG typically has STP functionality built-in, but it is not +mandatory. + +===== Application Server (AS) + +An Application Server is basically a logical entity representing one +particular external application (from the SS7 point of view) which is +interfaced with the SS7 network by means of one of the SIGTRAN +protocols. + +An Application Server can have one or more Application Server Processes +associated with it. This functionality (currently not implemented in +Osmocom) can be used for load-balancing or fail-over scenarios. + +===== Application Server Process (ASP) + +An Application Server Process represents one particular SCTP +connection used for SIGTRAN signaling between an external application +(e.g. a BSC) and the Signaling Gateway (SG). + +One Application Server Process can route traffic for multiple +Application Servers. In order to differentiate traffic for different +Application Servers, the Routing Context header is used. + +==== SIGTRAN variants / stackings + +SIGTRAN is the name of an IETF working group, which has released an +entire group of different protocol specifications. So rather than one +way of transporting classic telecom signaling over IP, there are now +half a dozen different ones, and all can claim to be an official IETF +standard. + +FIXME: Overview picture comparing the different stackings + +===== MTP3 User Adaptation (M3UA) + +M3UA basically "chops off" everything up to and including the MTP3 +protocol layer of the SS7 protocol stack and replaces it with a stack +comprised of M3UA over SCTP over IP. + +M3UA is specified in <>. + +===== SCCP User Adaptation (SUA) + +SUA basically "chops off" everything up to and including the SCCP +protocol layer of the SS7 protocol stack and replaces it with a stack +comprised of SUA over SCTP over IP. + +This means that SUA can only be used for SCCP based signaling, but not +for other SS7 protocols like e.g. TUP and ISUP. + +SUA is specified in <>. + +===== MTP2 User Adaptation (M2UA) + +M2UA is specified in <>. + +NOTE:: M2UA is not supported in Osmocom SIGTRAN up to this point. Let +us know if we can implement it for you! + +===== MTP2-User Peer-to-Peer Adaptation (M2PA) + +M2PA is specified in <>. + +NOTE:: M2PA is not supported in Osmocom SIGTRAN up to this point. Let +us know if we can implement it for you! + + +==== SIGTRAN security + +There simply is none. There are some hints that TLS shall be used +over SCTP in order to provide authenticity and/or confidentiality for +SIGTRAN, but this is not widely used. + +As telecom signaling is not generally carried over public networks, +private networks/links by means of MPLS, VLANs or VPNs such as IPsec +are often used to isolate and/or secure SIGTRAN. + +Under no circumstances should you use unsecured SIGTRAN with +production data over the public internet! + +==== IPv6 support + +SCTP (and thus all the higher layer protocols of the various SIGTRAN +stackings) operates on top of both IPv4 and IPv6. As the entire +underlying IP transport is transparent to the SS7/SCCP applcations, +there is no restriction on whether to use SIGTRAN over IPv4 or IPv6. -- To view, visit https://gerrit.osmocom.org/2371 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I450bfac7444ac9cb7f50c086d87cf7157c2e2a31 Gerrit-PatchSet: 4 Gerrit-Project: osmo-gsm-manuals Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Mon Apr 17 14:06:57 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 17 Apr 2017 14:06:57 +0000 Subject: [PATCH] libosmo-netif[master]: SCTP: Don't enable sender_dry_event for SCTP, as it breaks L... Message-ID: Review at https://gerrit.osmocom.org/2386 SCTP: Don't enable sender_dry_event for SCTP, as it breaks Linux SCTP Enabling sender_dry_event in SCTP_FLAGS breaks reliable delivery of DATA chunks to the scoket user on Linux. Let's avoid enabling that, while still enabling various other interesting events. See https://bugzilla.redhat.com/show_bug.cgi?id=1442784 for all related details. Change-Id: Ib616cd07a6044ca2ee7e05093b22df3369c62b56 --- M src/stream.c 1 file changed, 11 insertions(+), 2 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-netif refs/changes/86/2386/1 diff --git a/src/stream.c b/src/stream.c index ed73a62..add08b8 100644 --- a/src/stream.c +++ b/src/stream.c @@ -50,8 +50,17 @@ struct sctp_event_subscribe event; int rc; - /* subscribe for all events */ - memset((uint8_t *)&event, 1, sizeof(event)); + /* subscribe for all relevant events */ + memset((uint8_t *)&event, 0, sizeof(event)); + event.sctp_data_io_event = 1; + event.sctp_association_event = 1; + event.sctp_address_event = 1; + event.sctp_address_event = 1; + event.sctp_send_failure_event = 1; + event.sctp_peer_error_event = 1; + event.sctp_shutdown_event = 1; + /* IMPORTANT: Do NOT enable sender_dry_event here, see + * https://bugzilla.redhat.com/show_bug.cgi?id=1442784 */ rc = setsockopt(fd, IPPROTO_SCTP, SCTP_EVENTS, &event, sizeof(event)); -- To view, visit https://gerrit.osmocom.org/2386 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ib616cd07a6044ca2ee7e05093b22df3369c62b56 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Mon Apr 17 14:09:26 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 17 Apr 2017 14:09:26 +0000 Subject: libosmo-netif[master]: SCTP: Don't enable sender_dry_event for SCTP, as it breaks L... In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2386 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ib616cd07a6044ca2ee7e05093b22df3369c62b56 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Mon Apr 17 14:10:13 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Mon, 17 Apr 2017 14:10:13 +0000 Subject: [MERGED] libosmo-netif[master]: SCTP: Don't enable sender_dry_event for SCTP, as it breaks L... In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: SCTP: Don't enable sender_dry_event for SCTP, as it breaks Linux SCTP ...................................................................... SCTP: Don't enable sender_dry_event for SCTP, as it breaks Linux SCTP Enabling sender_dry_event in SCTP_FLAGS breaks reliable delivery of DATA chunks to the scoket user on Linux. Let's avoid enabling that, while still enabling various other interesting events. See https://bugzilla.redhat.com/show_bug.cgi?id=1442784 for all related details. Change-Id: Ib616cd07a6044ca2ee7e05093b22df3369c62b56 --- M src/stream.c 1 file changed, 11 insertions(+), 2 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/stream.c b/src/stream.c index ed73a62..add08b8 100644 --- a/src/stream.c +++ b/src/stream.c @@ -50,8 +50,17 @@ struct sctp_event_subscribe event; int rc; - /* subscribe for all events */ - memset((uint8_t *)&event, 1, sizeof(event)); + /* subscribe for all relevant events */ + memset((uint8_t *)&event, 0, sizeof(event)); + event.sctp_data_io_event = 1; + event.sctp_association_event = 1; + event.sctp_address_event = 1; + event.sctp_address_event = 1; + event.sctp_send_failure_event = 1; + event.sctp_peer_error_event = 1; + event.sctp_shutdown_event = 1; + /* IMPORTANT: Do NOT enable sender_dry_event here, see + * https://bugzilla.redhat.com/show_bug.cgi?id=1442784 */ rc = setsockopt(fd, IPPROTO_SCTP, SCTP_EVENTS, &event, sizeof(event)); -- To view, visit https://gerrit.osmocom.org/2386 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ib616cd07a6044ca2ee7e05093b22df3369c62b56 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From admin at opensuse.org Mon Apr 17 19:58:33 2017 From: admin at opensuse.org (OBS Notification) Date: Mon, 17 Apr 2017 19:58:33 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in xUbuntu_16.10/x86_64 In-Reply-To: References: Message-ID: <58f51e99c80f5_c7610b4f7c67825a@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/xUbuntu_16.10/x86_64 Package network:osmocom:nightly/osmo-stp failed to build in xUbuntu_16.10/x86_64 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 74s] ^~~~~~~ [ 74s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o vty_interface.o vty_interface.c [ 75s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o sctp_m3ua_client.o sctp_m3ua_client.c [ 75s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 75s] #include [ 75s] ^ [ 75s] compilation terminated. [ 75s] Makefile:485: recipe for target 'sctp_m3ua_client.o' failed [ 75s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 75s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 75s] Makefile:380: recipe for target 'all-recursive' failed [ 75s] make[2]: *** [all-recursive] Error 1 [ 75s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 75s] Makefile:321: recipe for target 'all' failed [ 75s] make[1]: *** [all] Error 2 [ 75s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 75s] dh_auto_build: make -j1 returned exit code 2 [ 75s] debian/rules:23: recipe for target 'build' failed [ 75s] make: *** [build] Error 2 [ 75s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 75s] [ 75s] lamb11 failed "build cellmgr-ng_1.4.7.20170417.dsc" at Mon Apr 17 19:58:22 UTC 2017. [ 75s] [ 75s] ### VM INTERACTION START ### [ 78s] [ 64.859355] reboot: Power down [ 78s] ### VM INTERACTION END ### [ 78s] [ 78s] lamb11 failed "build cellmgr-ng_1.4.7.20170417.dsc" at Mon Apr 17 19:58:26 UTC 2017. [ 78s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Mon Apr 17 19:59:42 2017 From: admin at opensuse.org (OBS Notification) Date: Mon, 17 Apr 2017 19:59:42 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in xUbuntu_16.10/i586 In-Reply-To: References: Message-ID: <58f51ed6356a6_98f1156f847463ed@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/xUbuntu_16.10/i586 Package network:osmocom:nightly/osmo-stp failed to build in xUbuntu_16.10/i586 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 103s] ^~~~~~~ [ 103s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o vty_interface.o vty_interface.c [ 104s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o sctp_m3ua_client.o sctp_m3ua_client.c [ 104s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 104s] #include [ 104s] ^ [ 104s] compilation terminated. [ 104s] Makefile:485: recipe for target 'sctp_m3ua_client.o' failed [ 104s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 104s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 104s] Makefile:380: recipe for target 'all-recursive' failed [ 104s] make[2]: *** [all-recursive] Error 1 [ 104s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 104s] Makefile:321: recipe for target 'all' failed [ 104s] make[1]: *** [all] Error 2 [ 104s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 104s] dh_auto_build: make -j1 returned exit code 2 [ 104s] debian/rules:23: recipe for target 'build' failed [ 104s] make: *** [build] Error 2 [ 104s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 104s] [ 104s] cloud115 failed "build cellmgr-ng_1.4.7.20170417.dsc" at Mon Apr 17 19:59:37 UTC 2017. [ 104s] [ 104s] ### VM INTERACTION START ### [ 107s] [ 85.380530] reboot: Power down [ 108s] ### VM INTERACTION END ### [ 108s] [ 108s] cloud115 failed "build cellmgr-ng_1.4.7.20170417.dsc" at Mon Apr 17 19:59:41 UTC 2017. [ 108s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Mon Apr 17 20:00:51 2017 From: admin at opensuse.org (OBS Notification) Date: Mon, 17 Apr 2017 20:00:51 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in Debian_8.0/x86_64 In-Reply-To: References: Message-ID: <58f51f1455f66_99c1156f8486053b@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/Debian_8.0/x86_64 Package network:osmocom:nightly/osmo-stp failed to build in Debian_8.0/x86_64 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 86s] CC vty_interface.o [ 87s] CC sctp_m3ua_client.o [ 87s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 87s] #include [ 87s] ^ [ 87s] compilation terminated. [ 87s] Makefile:475: recipe for target 'sctp_m3ua_client.o' failed [ 87s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 87s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 87s] Makefile:370: recipe for target 'all-recursive' failed [ 87s] make[2]: *** [all-recursive] Error 1 [ 87s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 87s] Makefile:310: recipe for target 'all' failed [ 87s] make[1]: *** [all] Error 2 [ 87s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 87s] dh_auto_build: make -j1 returned exit code 2 [ 87s] debian/rules:23: recipe for target 'build' failed [ 87s] make: *** [build] Error 2 [ 87s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 87s] [ 87s] lamb51 failed "build cellmgr-ng_1.4.7.20170417.dsc" at Mon Apr 17 20:00:37 UTC 2017. [ 87s] [ 87s] ### VM INTERACTION START ### [ 88s] Powering off. [ 88s] [ 74.486974] reboot: Power down [ 88s] ### VM INTERACTION END ### [ 88s] [ 88s] lamb51 failed "build cellmgr-ng_1.4.7.20170417.dsc" at Mon Apr 17 20:00:38 UTC 2017. [ 88s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Mon Apr 17 20:01:25 2017 From: admin at opensuse.org (OBS Notification) Date: Mon, 17 Apr 2017 20:01:25 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in xUbuntu_16.04/x86_64 In-Reply-To: References: Message-ID: <58f51f4cc2760_9961156f847897f5@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/xUbuntu_16.04/x86_64 Package network:osmocom:nightly/osmo-stp failed to build in xUbuntu_16.04/x86_64 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 96s] sctp_m2ua.c:91:3: warning: #warning "Notify any other AS(P) for failover scenario" [-Wcpp] [ 96s] #warning "Notify any other AS(P) for failover scenario" [ 96s] ^ [ 97s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -c -o vty_interface.o vty_interface.c [ 97s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -c -o sctp_m3ua_client.o sctp_m3ua_client.c [ 97s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 97s] compilation terminated. [ 97s] Makefile:485: recipe for target 'sctp_m3ua_client.o' failed [ 97s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 97s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 97s] Makefile:380: recipe for target 'all-recursive' failed [ 97s] make[2]: *** [all-recursive] Error 1 [ 97s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 97s] Makefile:321: recipe for target 'all' failed [ 97s] make[1]: *** [all] Error 2 [ 97s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 97s] dh_auto_build: make -j1 returned exit code 2 [ 97s] debian/rules:23: recipe for target 'build' failed [ 97s] make: *** [build] Error 2 [ 97s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 97s] [ 97s] lamb53 failed "build cellmgr-ng_1.4.7.20170417.dsc" at Mon Apr 17 20:01:05 UTC 2017. [ 97s] [ 97s] ### VM INTERACTION START ### [ 100s] [ 89.015735] reboot: Power down [ 101s] ### VM INTERACTION END ### [ 101s] [ 101s] lamb53 failed "build cellmgr-ng_1.4.7.20170417.dsc" at Mon Apr 17 20:01:09 UTC 2017. [ 101s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Mon Apr 17 20:02:16 2017 From: admin at opensuse.org (OBS Notification) Date: Mon, 17 Apr 2017 20:02:16 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in Debian_8.0/i586 In-Reply-To: References: Message-ID: <58f51f6ccc215_9961156f8478995b@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/Debian_8.0/i586 Package network:osmocom:nightly/osmo-stp failed to build in Debian_8.0/i586 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 119s] CC vty_interface.o [ 120s] CC sctp_m3ua_client.o [ 120s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 120s] #include [ 120s] ^ [ 120s] compilation terminated. [ 120s] Makefile:475: recipe for target 'sctp_m3ua_client.o' failed [ 120s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 120s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 120s] Makefile:370: recipe for target 'all-recursive' failed [ 120s] make[2]: *** [all-recursive] Error 1 [ 120s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 120s] Makefile:310: recipe for target 'all' failed [ 120s] make[1]: *** [all] Error 2 [ 120s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 120s] dh_auto_build: make -j1 returned exit code 2 [ 120s] debian/rules:23: recipe for target 'build' failed [ 120s] make: *** [build] Error 2 [ 120s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 120s] [ 120s] cloud127 failed "build cellmgr-ng_1.4.7.20170417.dsc" at Mon Apr 17 20:02:10 UTC 2017. [ 120s] [ 120s] ### VM INTERACTION START ### [ 121s] Powering off. [ 121s] [ 98.718586] reboot: Power down [ 123s] ### VM INTERACTION END ### [ 123s] [ 123s] cloud127 failed "build cellmgr-ng_1.4.7.20170417.dsc" at Mon Apr 17 20:02:13 UTC 2017. [ 123s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Mon Apr 17 20:02:16 2017 From: admin at opensuse.org (OBS Notification) Date: Mon, 17 Apr 2017 20:02:16 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in xUbuntu_16.04/i586 In-Reply-To: References: Message-ID: <58f51f6df46b_9961156f847900e9@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/xUbuntu_16.04/i586 Package network:osmocom:nightly/osmo-stp failed to build in xUbuntu_16.04/i586 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 95s] sctp_m2ua.c:91:3: warning: #warning "Notify any other AS(P) for failover scenario" [-Wcpp] [ 95s] #warning "Notify any other AS(P) for failover scenario" [ 95s] ^ [ 95s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -c -o vty_interface.o vty_interface.c [ 96s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -c -o sctp_m3ua_client.o sctp_m3ua_client.c [ 96s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 96s] compilation terminated. [ 96s] Makefile:485: recipe for target 'sctp_m3ua_client.o' failed [ 96s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 96s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 96s] Makefile:380: recipe for target 'all-recursive' failed [ 96s] make[2]: *** [all-recursive] Error 1 [ 96s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 96s] Makefile:321: recipe for target 'all' failed [ 96s] make[1]: *** [all] Error 2 [ 96s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 96s] dh_auto_build: make -j1 returned exit code 2 [ 96s] debian/rules:23: recipe for target 'build' failed [ 96s] make: *** [build] Error 2 [ 96s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 96s] [ 96s] lamb05 failed "build cellmgr-ng_1.4.7.20170417.dsc" at Mon Apr 17 20:02:10 UTC 2017. [ 96s] [ 96s] ### VM INTERACTION START ### [ 99s] [ 85.898249] reboot: Power down [ 99s] ### VM INTERACTION END ### [ 99s] [ 99s] lamb05 failed "build cellmgr-ng_1.4.7.20170417.dsc" at Mon Apr 17 20:02:14 UTC 2017. [ 99s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From gerrit-no-reply at lists.osmocom.org Tue Apr 18 10:08:10 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 18 Apr 2017 10:08:10 +0000 Subject: libosmo-sccp[master]: Add IPA/SCCPlite support as SIGTRAN alternative In-Reply-To: References: Message-ID: Patch Set 4: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2282 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I9098574cddeba10fcf8f1b6c196a7069a6805c56 Gerrit-PatchSet: 4 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Apr 18 10:08:25 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 18 Apr 2017 10:08:25 +0000 Subject: [MERGED] libosmo-sccp[master]: Add IPA/SCCPlite support as SIGTRAN alternative In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: Add IPA/SCCPlite support as SIGTRAN alternative ...................................................................... Add IPA/SCCPlite support as SIGTRAN alternative This tries as good as possible to fit the IPA/SCCPlite stacking into the existing SIGTRAN/SS7 code architecture/model. To the user, the IPA protocol looks like yet another protocol on the same level as the choice between SUA and M3AU. On the inside, things are obviously quite different. We need to handle TCP with IPA framing instead of SCTP for both server and client. We also implement an alternative "ASP FSM" for IPA, which takes care of the CCM handshake (ID_REQ/ID_RESP/ID_ACK/ID_ACK2) for both client and server mode. In server mode, we use the 'unit name' as identifier to look up the AS, similar to how we use a routing context to look up the AS in the xUA case. We also have to bypass activating the default layer manager in the simple client to make sure we don't run into even more complexity. What's missing right now is some way to manually override/set the point codes. As IPA/SCCPlite is missing any routing label, we currently simply generate one with SPC=0/DPC=0, which will obviously not work in most configurations. Change-Id: I9098574cddeba10fcf8f1b6c196a7069a6805c56 --- M include/osmocom/sigtran/osmo_ss7.h M src/Makefile.am A src/ipa.c M src/osmo_ss7.c M src/osmo_ss7_hmrt.c M src/osmo_ss7_vty.c M src/sccp_scrc.c M src/sccp_user.c M src/xua_as_fsm.c M src/xua_asp_fsm.c M src/xua_asp_fsm.h M src/xua_internal.h 12 files changed, 681 insertions(+), 17 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/include/osmocom/sigtran/osmo_ss7.h b/include/osmocom/sigtran/osmo_ss7.h index 76403e2..2ae4c1e 100644 --- a/include/osmocom/sigtran/osmo_ss7.h +++ b/include/osmocom/sigtran/osmo_ss7.h @@ -258,6 +258,7 @@ OSMO_SS7_ASP_PROT_NONE, OSMO_SS7_ASP_PROT_SUA, OSMO_SS7_ASP_PROT_M3UA, + OSMO_SS7_ASP_PROT_IPA, _NUM_OSMO_SS7_ASP_PROT }; @@ -359,6 +360,9 @@ /*! Were we dynamically allocated */ bool dyn_allocated; + /*! Pending message for non-blocking IPA read */ + struct msgb *pending_msg; + struct { char *name; char *description; diff --git a/src/Makefile.am b/src/Makefile.am index 217f2f7..15f17fe 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -30,6 +30,6 @@ sccp2sua.c sccp_scrc.c sccp_sclc.c sccp_scoc.c \ sccp_user.c xua_rkm.c xua_default_lm_fsm.c \ osmo_ss7.c osmo_ss7_hmrt.c xua_asp_fsm.c xua_as_fsm.c \ - osmo_ss7_vty.c sccp_vty.c + osmo_ss7_vty.c sccp_vty.c ipa.c libosmo_sigtran_la_LDFLAGS = -version-info $(LIBVERSION) -no-undefined -export-symbols-regex '^osmo_' libosmo_sigtran_la_LIBADD = $(LIBOSMOCORE_LIBS) $(LIBOSMONETIF_LIBS) $(LIBSCTP_LIBS) diff --git a/src/ipa.c b/src/ipa.c new file mode 100644 index 0000000..1668f0f --- /dev/null +++ b/src/ipa.c @@ -0,0 +1,182 @@ +/* implementation of IPA/SCCPlite transport */ + +/* (C) 2015-2017 by Harald Welte + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +//#include +#include +#include + +#include +#include +#include +#include + +#include "xua_internal.h" +#include "xua_asp_fsm.h" + + +/*! \brief Send a given xUA message via a given IPA "Application Server" + * \param[in] as Application Server through which to send \a xua + * \param[in] xua xUA message to be sent + * \return 0 on success; negative on error */ +int ipa_tx_xua_as(struct osmo_ss7_as *as, struct xua_msg *xua) +{ + struct xua_msg_part *data_ie; + struct msgb *msg; + unsigned int src_len; + const uint8_t *src; + uint8_t *dst; + + OSMO_ASSERT(as->cfg.proto == OSMO_SS7_ASP_PROT_IPA); + + /* we're actually only interested in the data part */ + data_ie = xua_msg_find_tag(xua, M3UA_IEI_PROT_DATA); + if (!data_ie || data_ie->len < sizeof(struct m3ua_data_hdr)) + return -1; + + /* and even the data part still has the header prepended */ + src = data_ie->dat + sizeof(struct m3ua_data_hdr); + src_len = data_ie->len - sizeof(struct m3ua_data_hdr); + + /* sufficient headroom for osmo_ipa_msg_push_header() */ + msg = ipa_msg_alloc(16); + if (!msg) + return -1; + + dst = msgb_put(msg, src_len); + memcpy(dst, src, src_len); + + /* TODO: if we ever need something beyond SCCP, we can use the + * M3UA SIO to determine the protocol */ + osmo_ipa_msg_push_header(msg, IPAC_PROTO_SCCP); + + return xua_as_transmit_msg(as, msg); +} + +static int ipa_rx_msg_ccm(struct osmo_ss7_asp *asp, struct msgb *msg) +{ + uint8_t msg_type = msg->l2h[0]; + + LOGPASP(asp, DLSS7, LOGL_DEBUG, "%s:%s\n", __func__, msgb_hexdump(msg)); + + /* Convert CCM into events to the IPA_ASP_FSM */ + switch (msg_type) { + case IPAC_MSGT_ID_ACK: + osmo_fsm_inst_dispatch(asp->fi, IPA_ASP_E_ID_ACK, msg); + break; + case IPAC_MSGT_ID_RESP: + osmo_fsm_inst_dispatch(asp->fi, IPA_ASP_E_ID_RESP, msg); + break; + case IPAC_MSGT_ID_GET: + osmo_fsm_inst_dispatch(asp->fi, IPA_ASP_E_ID_GET, msg); + break; + case IPAC_MSGT_PING: + osmo_fsm_inst_dispatch(asp->fi, XUA_ASP_E_ASPSM_BEAT, msg); + break; + case IPAC_MSGT_PONG: + osmo_fsm_inst_dispatch(asp->fi, XUA_ASP_E_ASPSM_BEAT_ACK, msg); + break; + default: + LOGPASP(asp, DLSS7, LOGL_NOTICE, "Unknown CCM Message 0x%02x: %s\n", + msg_type, msgb_hexdump(msg)); + return -1; + } + + msgb_free(msg); + + return 0; +} + +static int ipa_rx_msg_sccp(struct osmo_ss7_asp *asp, struct msgb *msg) +{ + struct m3ua_data_hdr data_hdr; + struct xua_msg *xua = xua_msg_alloc(); + + /* pull the IPA header */ + msgb_pull_to_l2(msg); + + /* We have received an IPA-encapsulated SCCP message, without + * any MTP routing label. This means we have no real idea where + * it came from, nor where it goes to. We could simply treat it + * as being for the local point code, but then this means that + * we would have to implement SCCP connection coupling in order + * to route the connections to any other point code. The reason + * for this is the lack of addressing information inside the + * non-CR/CC connection oriented messages. + * + * The only other alternative we have is to simply have a + * STP (server) side configuration that specifies which point + * code those messages are to be routed to, and then use this + * 'override DPC' in the routing decision. We could do the same + * for the source point code to ensure responses are routed back + * to us. This is all quite ugly, but then what can we do :/ + */ + + memset(&data_hdr, 0, sizeof(data_hdr)); + data_hdr.opc = 0;//FIXME; + data_hdr.dpc = 0;//FIXME; + data_hdr.si = MTP_SI_SCCP; + xua = m3ua_xfer_from_data(&data_hdr, msgb_l2(msg), msgb_l2len(msg)); + + return m3ua_hmdc_rx_from_l2(asp->inst, xua); +} + +/*! \brief process M3UA message received from socket + * \param[in] asp Application Server Process receiving \a msg + * \param[in] msg received message buffer. Callee takes ownership! + * \returns 0 on success; negative on error */ +int ipa_rx_msg(struct osmo_ss7_asp *asp, struct msgb *msg) +{ + struct ipaccess_head *hh; + int rc; + + OSMO_ASSERT(asp->cfg.proto == OSMO_SS7_ASP_PROT_IPA); + + /* osmo_ipa_process_msg() will already have verified length + * consistency and set up l2h poiter */ + hh = (struct ipaccess_head *) msg->l1h; + + switch (hh->proto) { + case IPAC_PROTO_IPACCESS: + rc = ipa_rx_msg_ccm(asp, msg); + break; + case IPAC_PROTO_SCCP: + rc = ipa_rx_msg_sccp(asp, msg); + break; + default: + LOGPASP(asp, DLSS7, LOGL_DEBUG, "Unknown Stream ID 0x%02x: %s\n", + hh->proto, msgb_hexdump(msg)); + rc = -1; + } + + return rc; +} diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index 6b77dc4..6495947 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -41,6 +41,7 @@ #include #include +#include #include "sccp_internal.h" #include "xua_internal.h" @@ -68,11 +69,24 @@ { OSMO_SS7_ASP_PROT_NONE, "none" }, { OSMO_SS7_ASP_PROT_SUA, "sua" }, { OSMO_SS7_ASP_PROT_M3UA, "m3ua" }, + { OSMO_SS7_ASP_PROT_IPA, "ipa" }, { 0, NULL } }; #define LOGSS7(inst, level, fmt, args ...) \ LOGP(DLSS7, level, "%u: " fmt, inst ? (inst)->cfg.id : 0, ## args) + +static int asp_proto_to_ip_proto(enum osmo_ss7_asp_protocol proto) +{ + switch (proto) { + case OSMO_SS7_ASP_PROT_IPA: + return IPPROTO_TCP; + case OSMO_SS7_ASP_PROT_SUA: + case OSMO_SS7_ASP_PROT_M3UA: + default: + return IPPROTO_SCTP; + } +} int osmo_ss7_find_free_rctx(struct osmo_ss7_instance *inst) { @@ -1075,6 +1089,7 @@ } static int xua_cli_read_cb(struct osmo_stream_cli *conn); +static int ipa_cli_read_cb(struct osmo_stream_cli *conn); static int xua_cli_connect_cb(struct osmo_stream_cli *cli); int osmo_ss7_asp_restart(struct osmo_ss7_asp *asp) @@ -1105,10 +1120,13 @@ osmo_stream_cli_set_port(asp->client, asp->cfg.remote.port); osmo_stream_cli_set_local_addr(asp->client, asp->cfg.local.host); osmo_stream_cli_set_local_port(asp->client, asp->cfg.local.port); - osmo_stream_cli_set_proto(asp->client, IPPROTO_SCTP); + osmo_stream_cli_set_proto(asp->client, asp_proto_to_ip_proto(asp->cfg.proto)); osmo_stream_cli_set_reconnect_timeout(asp->client, 5); osmo_stream_cli_set_connect_cb(asp->client, xua_cli_connect_cb); - osmo_stream_cli_set_read_cb(asp->client, xua_cli_read_cb); + if (asp->cfg.proto == OSMO_SS7_ASP_PROT_IPA) + osmo_stream_cli_set_read_cb(asp->client, ipa_cli_read_cb); + else + osmo_stream_cli_set_read_cb(asp->client, xua_cli_read_cb); osmo_stream_cli_set_data(asp->client, asp); rc = osmo_stream_cli_open2(asp->client, 1); if (rc < 0) { @@ -1218,6 +1236,37 @@ notif->sn_header.sn_type)); break; } +} + +/* netif code tells us we can read something from the socket */ +static int ipa_srv_conn_cb(struct osmo_stream_srv *conn) +{ + struct osmo_fd *ofd = osmo_stream_srv_get_ofd(conn); + struct osmo_ss7_asp *asp = osmo_stream_srv_get_data(conn); + struct msgb *msg = NULL; + int rc; + + /* read IPA message from socket and process it */ + rc = ipa_msg_recv_buffered(ofd->fd, &msg, &asp->pending_msg); + LOGPASP(asp, DLSS7, LOGL_DEBUG, "%s(): ipa_msg_recv_buffered() returned %d\n", + __func__, rc); + if (rc <= 0) { + if (rc == -EAGAIN) { + /* more data needed */ + return 0; + } + osmo_stream_srv_destroy(conn); + return rc; + } + if (osmo_ipa_process_msg(msg) < 0) { + LOGPASP(asp, DLSS7, LOGL_ERROR, "Bad IPA message\n"); + osmo_stream_srv_destroy(conn); + msgb_free(msg); + return -1; + } + msg->dst = asp; + + return ipa_rx_msg(asp, msg); } /* netif code tells us we can read something from the socket */ @@ -1332,6 +1381,36 @@ osmo_stream_cli_reconnect(cli); } +/* read call-back for IPA/SCCPlite socket */ +static int ipa_cli_read_cb(struct osmo_stream_cli *conn) +{ + struct osmo_fd *ofd = osmo_stream_cli_get_ofd(conn); + struct osmo_ss7_asp *asp = osmo_stream_cli_get_data(conn); + struct msgb *msg = NULL; + int rc; + + /* read IPA message from socket and process it */ + rc = ipa_msg_recv_buffered(ofd->fd, &msg, &asp->pending_msg); + LOGPASP(asp, DLSS7, LOGL_DEBUG, "%s(): ipa_msg_recv_buffered() returned %d\n", + __func__, rc); + if (rc <= 0) { + if (rc == -EAGAIN) { + /* more data needed */ + return 0; + } + osmo_stream_cli_reconnect(conn); + return rc; + } + if (osmo_ipa_process_msg(msg) < 0) { + LOGPASP(asp, DLSS7, LOGL_ERROR, "Bad IPA message\n"); + osmo_stream_cli_reconnect(conn); + msgb_free(msg); + return -1; + } + msg->dst = asp; + return ipa_rx_msg(asp, msg); +} + static int xua_cli_read_cb(struct osmo_stream_cli *conn) { struct osmo_fd *ofd = osmo_stream_cli_get_ofd(conn); @@ -1444,15 +1523,21 @@ struct osmo_ss7_asp *asp; char *sock_name = osmo_sock_get_name(link, fd); - LOGP(DLSS7, LOGL_INFO, "%s: New SCTP connection accepted\n", - sock_name); + LOGP(DLSS7, LOGL_INFO, "%s: New %s connection accepted\n", + sock_name, get_value_string(osmo_ss7_asp_protocol_vals, oxs->cfg.proto)); - srv = osmo_stream_srv_create(oxs, link, fd, - xua_srv_conn_cb, - xua_srv_conn_closed_cb, NULL); + if (oxs->cfg.proto == OSMO_SS7_ASP_PROT_IPA) { + srv = osmo_stream_srv_create(oxs, link, fd, + ipa_srv_conn_cb, + xua_srv_conn_closed_cb, NULL); + } else { + srv = osmo_stream_srv_create(oxs, link, fd, + xua_srv_conn_cb, + xua_srv_conn_closed_cb, NULL); + } if (!srv) { LOGP(DLSS7, LOGL_ERROR, "%s: Unable to create stream server " - "for SCTP connection\n", sock_name); + "for connection\n", sock_name); close(fd); talloc_free(sock_name); return -1; @@ -1478,6 +1563,7 @@ sock_name, asp->cfg.name); asp->cfg.is_server = true; asp->dyn_allocated = true; + asp->server = srv; osmo_ss7_asp_restart(asp); } } @@ -1522,6 +1608,8 @@ break; case OSMO_SS7_ASP_PROT_M3UA: msgb_sctp_ppid(msg) = M3UA_PPID; + break; + case OSMO_SS7_ASP_PROT_IPA: break; default: OSMO_ASSERT(0); @@ -1594,8 +1682,8 @@ if (!oxs) return NULL; - LOGP(DLSS7, LOGL_INFO, "Creating XUA Server %s:%u\n", - local_host, local_port); + LOGP(DLSS7, LOGL_INFO, "Creating %s Server %s:%u\n", + get_value_string(osmo_ss7_asp_protocol_vals, proto), local_host, local_port); INIT_LLIST_HEAD(&oxs->asp_list); @@ -1610,7 +1698,7 @@ osmo_stream_srv_link_set_nodelay(oxs->server, true); osmo_stream_srv_link_set_addr(oxs->server, oxs->cfg.local.host); osmo_stream_srv_link_set_port(oxs->server, oxs->cfg.local.port); - osmo_stream_srv_link_set_proto(oxs->server, IPPROTO_SCTP); + osmo_stream_srv_link_set_proto(oxs->server, asp_proto_to_ip_proto(proto)); rc = osmo_stream_srv_link_open(oxs->server); if (rc < 0) { @@ -1673,6 +1761,7 @@ osmo_fsm_register(&sccp_scoc_fsm); osmo_fsm_register(&xua_as_fsm); osmo_fsm_register(&xua_asp_fsm); + osmo_fsm_register(&ipa_asp_fsm); osmo_fsm_register(&xua_default_lm_fsm); ss7_initialized = true; return 0; diff --git a/src/osmo_ss7_hmrt.c b/src/osmo_ss7_hmrt.c index ce0728b..bbbb3a9 100644 --- a/src/osmo_ss7_hmrt.c +++ b/src/osmo_ss7_hmrt.c @@ -141,6 +141,8 @@ switch (as->cfg.proto) { case OSMO_SS7_ASP_PROT_M3UA: return m3ua_tx_xua_as(as,xua); + case OSMO_SS7_ASP_PROT_IPA: + return ipa_tx_xua_as(as, xua); default: LOGP(DLSS7, LOGL_ERROR, "MTP message " "for ASP of unknown protocol%u\n", diff --git a/src/osmo_ss7_vty.c b/src/osmo_ss7_vty.c index 282a5a0..a6a0f5b 100644 --- a/src/osmo_ss7_vty.c +++ b/src/osmo_ss7_vty.c @@ -37,11 +37,12 @@ #include "xua_internal.h" -#define XUA_VAR_STR "(sua|m3ua)" +#define XUA_VAR_STR "(sua|m3ua|ipa)" #define XUA_VAR_HELP_STR \ "SCCP User Adaptation\n" \ - "MTP3 User Adaptation\n" + "MTP3 User Adaptation\n" \ + "IPA Multiplex (SCCP Lite)\n" /*********************************************************************** diff --git a/src/sccp_scrc.c b/src/sccp_scrc.c index 4491ce6..9a6a865 100644 --- a/src/sccp_scrc.c +++ b/src/sccp_scrc.c @@ -142,6 +142,7 @@ case OSMO_SS7_ASP_PROT_SUA: return sua_tx_xua_as(as, xua); case OSMO_SS7_ASP_PROT_M3UA: + case OSMO_SS7_ASP_PROT_IPA: return sua2sccp_tx_m3ua(inst, xua); default: LOGP(DLSCCP, LOGL_ERROR, "MTP-TRANSFER.req for " @@ -296,7 +297,8 @@ const struct osmo_sccp_addr *called) { struct osmo_sccp_user *scu; - + /* it is not really clear that called->pc will be set to + * anything here, in the case of a SSN-only CalledAddr */ scu = sccp_user_find(inst, called->ssn, called->pc); /* Is subsystem equipped? */ diff --git a/src/sccp_user.c b/src/sccp_user.c index 51cc6b1..d9e40b6 100644 --- a/src/sccp_user.c +++ b/src/sccp_user.c @@ -274,7 +274,8 @@ asp->cfg.local.host = talloc_strdup(asp, local_ip); asp->cfg.remote.host = talloc_strdup(asp, remote_ip); osmo_ss7_as_add_asp(as, asp_name); - osmo_ss7_asp_use_default_lm(asp, LOGL_DEBUG); + if (prot != OSMO_SS7_ASP_PROT_IPA) + osmo_ss7_asp_use_default_lm(asp, LOGL_DEBUG); talloc_free(asp_name); osmo_ss7_asp_restart(asp); diff --git a/src/xua_as_fsm.c b/src/xua_as_fsm.c index 36aed64..8f764f1 100644 --- a/src/xua_as_fsm.c +++ b/src/xua_as_fsm.c @@ -38,6 +38,10 @@ struct msgb *msg; unsigned int i, sent = 0; + /* we don't send notify to IPA peers! */ + if (as->cfg.proto == OSMO_SS7_ASP_PROT_IPA) + return 0; + /* iterate over all non-DOWN ASPs and send them the message */ for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) { struct osmo_ss7_asp *asp = as->cfg.asps[i]; @@ -66,7 +70,7 @@ } /* actually transmit a message through this AS */ -static int xua_as_transmit_msg(struct osmo_ss7_as *as, struct msgb *msg) +int xua_as_transmit_msg(struct osmo_ss7_as *as, struct msgb *msg) { struct osmo_ss7_asp *asp; unsigned int i; diff --git a/src/xua_asp_fsm.c b/src/xua_asp_fsm.c index a0f93bd..2b5bfdd 100644 --- a/src/xua_asp_fsm.c +++ b/src/xua_asp_fsm.c @@ -14,6 +14,11 @@ #include #include #include +#include +#include + +#include +#include #include #include @@ -65,6 +70,14 @@ { XUA_ASP_E_ASPSM_ASPDN_ACK, "ASPSM-ASP_DN_ACK" }, { XUA_ASP_E_ASPTM_ASPIA, "ASPTM-ASP_IA" }, { XUA_ASP_E_ASPTM_ASPIA_ACK, "ASPTM_ASP_IA_ACK" }, + + { XUA_ASP_E_ASPSM_BEAT, "ASPSM_BEAT" }, + { XUA_ASP_E_ASPSM_BEAT_ACK, "ASPSM_BEAT_ACK" }, + + { IPA_ASP_E_ID_RESP, "IPA_CCM_ID_RESP" }, + { IPA_ASP_E_ID_GET, "IPA_CCM_ID_GET" }, + { IPA_ASP_E_ID_ACK, "IPA_CCM_ID_ACK" }, + { 0, NULL } }; @@ -655,6 +668,8 @@ .allstate_action = xua_asp_allstate, }; +static struct osmo_fsm_inst *ipa_asp_fsm_start(struct osmo_ss7_asp *asp, + enum xua_asp_role role, int log_level); /*! \brief Start a new ASP finite stae machine for given ASP * \param[in] asp Application Server Process for which to start FSM @@ -666,6 +681,9 @@ { struct osmo_fsm_inst *fi; struct xua_asp_fsm_priv *xafp; + + if (asp->cfg.proto == OSMO_SS7_ASP_PROT_IPA) + return ipa_asp_fsm_start(asp, role, log_level); /* allocate as child of AS? */ fi = osmo_fsm_inst_alloc(&xua_asp_fsm, asp, NULL, log_level, asp->cfg.name); @@ -682,3 +700,352 @@ return fi; } + + + + + +/*********************************************************************** + * IPA Compatibility FSM + ***********************************************************************/ + +/* The idea here is to have a FSM that handles an IPA / SCCPlite link in + * a way that the higher-layer code considers it the same like an M3UA + * or SUA link. We have a couple of different states and some + * additional events. */ + +enum ipa_asp_state { + IPA_ASP_S_DOWN = XUA_ASP_S_DOWN, + IPA_ASP_S_ACTIVE = XUA_ASP_S_ACTIVE, + IPA_ASP_S_WAIT_ID_RESP, /* Waiting for ID_RESP from peer */ + IPA_ASP_S_WAIT_ID_GET, /* Waiting for ID_GET from peer */ + IPA_ASP_S_WAIT_ID_ACK, /* Waiting for ID_ACK from peer */ + IPA_ASP_S_WAIT_ID_ACK2, /* Waiting for ID_ACK (of ACK) from peer */ +}; + +/* private data structure for each FSM instance */ +struct ipa_asp_fsm_priv { + /* pointer back to ASP to which we belong */ + struct osmo_ss7_asp *asp; + /* Role (ASP/SG/IPSP) */ + enum xua_asp_role role; + + /* Structure holding parsed data of the IPA CCM ID exchange */ + struct ipaccess_unit *ipa_unit; + /* Timer for tracking if no PONG is received in response to PING */ + struct osmo_timer_list pong_timer; +}; + +enum ipa_asp_fsm_t { + T_WAIT_ID_RESP = 1, + T_WAIT_ID_ACK, + T_WAIT_ID_GET, +}; + +/* get the file descriptor related to a given ASP */ +static int get_fd_from_iafp(struct ipa_asp_fsm_priv *iafp) +{ + struct osmo_ss7_asp *asp = iafp->asp; + struct osmo_fd *ofd; + + if (asp->server) + ofd = osmo_stream_srv_get_ofd(asp->server); + else if (asp->client) + ofd = osmo_stream_cli_get_ofd(asp->client); + else + return -1; + + return ofd->fd; +} + +/* Server + Client: Initial State, wait for M-ASP-UP.req */ +static void ipa_asp_fsm_down(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct ipa_asp_fsm_priv *iafp = fi->priv; + int fd = get_fd_from_iafp(iafp); + + switch (event) { + case XUA_ASP_E_M_ASP_UP_REQ: + case XUA_ASP_E_SCTP_EST_IND: + if (iafp->role == XUA_ASPFSM_ROLE_SG) { + /* Server: Transmit IPA ID GET + Wait for Response */ + ipa_ccm_send_id_req(fd); + osmo_fsm_inst_state_chg(fi, IPA_ASP_S_WAIT_ID_RESP, 10, T_WAIT_ID_RESP); + } else { + /* Client: We simply wait for an ID GET */ + osmo_fsm_inst_state_chg(fi, IPA_ASP_S_WAIT_ID_GET, 10, T_WAIT_ID_GET); + } + break; + } +} + +/* Server: We're waiting for an ID RESP */ +static void ipa_asp_fsm_wait_id_resp(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct ipa_asp_fsm_priv *iafp = fi->priv; + struct osmo_ss7_asp *asp = iafp->asp; + int fd = get_fd_from_iafp(iafp); + struct osmo_ss7_as *as; + struct tlv_parsed tp; + struct msgb *msg; + int rc; + + switch (event) { + case IPA_ASP_E_ID_RESP: + /* resolve the AS based on the identity provided by peer. */ + msg = data; + rc = ipa_ccm_idtag_parse(&tp, msgb_l2(msg)+2, msgb_l2len(msg)-2); + if (rc < 0) { + LOGPFSML(fi, LOGL_ERROR, "Error %d parsing ID_RESP TLV: %s\n", rc, + msgb_hexdump(msg)); + goto out_err; + } + rc = ipa_ccm_tlv_to_unitdata(iafp->ipa_unit, &tp); + if (rc < 0) { + LOGPFSML(fi, LOGL_ERROR, "Error %d parsing ID_RESP: %s\n", rc, msgb_hexdump(msg)); + goto out_err; + } + if (!iafp->ipa_unit->unit_name) { + LOGPFSML(fi, LOGL_NOTICE, "No Unit Name specified by client\n"); + goto out_err; + } + as = osmo_ss7_as_find_by_name(asp->inst, iafp->ipa_unit->unit_name); + if (!as) { + LOGPFSML(fi, LOGL_NOTICE, "Cannot find any definition for IPA Unit Name '%s'\n", + iafp->ipa_unit->unit_name); + goto out_err; + } + osmo_ss7_as_add_asp(as, asp->cfg.name); + /* TODO: OAP Authentication? */ + /* Send ID_ACK */ + ipaccess_send_id_ack(fd); + osmo_fsm_inst_state_chg(fi, IPA_ASP_S_WAIT_ID_ACK2, 10, T_WAIT_ID_ACK); + break; + } + return; +out_err: + osmo_ss7_asp_disconnect(asp); + return; +} + +/* Server: We're waiting for an ID ACK */ +static void ipa_asp_fsm_wait_id_ack2(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + switch (event) { + case IPA_ASP_E_ID_ACK: + /* ACK received, we can go to active state now. The + * ACTIVE onenter function will inform the AS */ + osmo_fsm_inst_state_chg(fi, IPA_ASP_S_ACTIVE, 0, 0); + break; + } +} + +/* Client: We're waiting for an ID GET */ +static void ipa_asp_fsm_wait_id_get(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct ipa_asp_fsm_priv *iafp = fi->priv; + struct osmo_ss7_asp *asp = iafp->asp; + struct msgb *msg_get, *msg_resp; + const uint8_t *req_data; + int data_len; + + switch (event) { + case IPA_ASP_E_ID_GET: + msg_get = data; + req_data = msgb_l2(msg_get)+1; + data_len = msgb_l2len(msg_get)-1; + LOGPFSM(fi, "Received IPA CCM IDENTITY REQUEST for IEs %s\n", + osmo_hexdump(req_data, data_len)); + /* Send ID_RESP to server */ + msg_resp = ipa_ccm_make_id_resp_from_req(iafp->ipa_unit, req_data, data_len); + if (!msg_resp) { + LOGPFSML(fi, LOGL_ERROR, "Error building IPA CCM IDENTITY RESPONSE\n"); + break; + } + osmo_ss7_asp_send(asp, msg_resp); + osmo_fsm_inst_state_chg(fi, IPA_ASP_S_WAIT_ID_ACK, 10, T_WAIT_ID_ACK); + break; + } +} + +/* Client: We're waiting for an ID ACK */ +static void ipa_asp_fsm_wait_id_ack(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct ipa_asp_fsm_priv *iafp = fi->priv; + int fd; + + switch (event) { + case IPA_ASP_E_ID_ACK: + /* Send ACK2 to server */ + fd = get_fd_from_iafp(iafp); + ipaccess_send_id_ack(fd); + osmo_fsm_inst_state_chg(fi, IPA_ASP_S_ACTIVE, 0, 0); + break; + } +} + + +/* Server + Client: We're actively transmitting user data */ +static void ipa_asp_fsm_active(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + switch (event) { + case XUA_ASP_E_M_ASP_DOWN_REQ: + case XUA_ASP_E_M_ASP_INACTIVE_REQ: + /* FIXME: kill ASP and (wait for) re-connect */ + break; + } +} + +static void ipa_asp_allstate(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct ipa_asp_fsm_priv *iafp = fi->priv; + int fd; + + switch (event) { + case XUA_ASP_E_SCTP_COMM_DOWN_IND: + case XUA_ASP_E_SCTP_RESTART_IND: + osmo_fsm_inst_state_chg(fi, IPA_ASP_S_DOWN, 0, 0); + send_xlm_prim_simple(fi, OSMO_XLM_PRIM_M_ASP_DOWN, + PRIM_OP_INDICATION); + break; + case XUA_ASP_E_ASPSM_BEAT: + /* PING -> PONG */ + fd = get_fd_from_iafp(iafp); + ipaccess_send_pong(fd); + break; + case XUA_ASP_E_ASPSM_BEAT_ACK: + /* stop timer, if any */ + osmo_timer_del(&iafp->pong_timer); + break; + default: + break; + } +} + +static void ipa_asp_fsm_active_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state) +{ + dispatch_to_all_as(fi, XUA_ASPAS_ASP_INACTIVE_IND); + dispatch_to_all_as(fi, XUA_ASPAS_ASP_ACTIVE_IND); +} + +static void ipa_pong_timer_cb(void *_fi) +{ + struct osmo_fsm_inst *fi = _fi; + struct ipa_asp_fsm_priv *iafp = fi->priv; + + LOGPFSML(fi, LOGL_NOTICE, "Peer didn't respond to PING? with PONG!\n"); + /* kill ASP and (wait for) re-connect */ + osmo_ss7_asp_disconnect(iafp->asp); +} + +static int ipa_asp_fsm_timer_cb(struct osmo_fsm_inst *fi) +{ + struct ipa_asp_fsm_priv *iafp = fi->priv; + + LOGPFSML(fi, LOGL_ERROR, "Timeout waiting for peer response\n"); + /* kill ASP and (wait for) re-connect */ + osmo_ss7_asp_disconnect(iafp->asp); + return -1; +} + +static const struct osmo_fsm_state ipa_asp_states[] = { + [IPA_ASP_S_DOWN] = { + .in_event_mask = S(XUA_ASP_E_M_ASP_UP_REQ) | + S(XUA_ASP_E_SCTP_EST_IND), + .out_state_mask = S(IPA_ASP_S_WAIT_ID_GET) | + S(IPA_ASP_S_WAIT_ID_RESP), + .name = "ASP_DOWN", + .action = ipa_asp_fsm_down, + .onenter = xua_asp_fsm_down_onenter, + }, + /* Server Side */ + [IPA_ASP_S_WAIT_ID_RESP] = { + .in_event_mask = S(IPA_ASP_E_ID_RESP), + .out_state_mask = S(IPA_ASP_S_WAIT_ID_ACK2) | + S(IPA_ASP_S_DOWN), + .name = "WAIT_ID_RESP", + .action = ipa_asp_fsm_wait_id_resp, + }, + /* Server Side */ + [IPA_ASP_S_WAIT_ID_ACK2] = { + .in_event_mask = S(IPA_ASP_E_ID_ACK), + .out_state_mask = S(IPA_ASP_S_ACTIVE) | + S(IPA_ASP_S_DOWN), + .name = "WAIT_ID_ACK2", + .action = ipa_asp_fsm_wait_id_ack2, + }, + /* Client Side */ + [IPA_ASP_S_WAIT_ID_GET] = { + .in_event_mask = S(IPA_ASP_E_ID_GET), + .out_state_mask = S(IPA_ASP_S_WAIT_ID_ACK), + .name = "WAIT_ID_GET", + .action = ipa_asp_fsm_wait_id_get, + }, + /* Client Side */ + [IPA_ASP_S_WAIT_ID_ACK] = { + .in_event_mask = S(IPA_ASP_E_ID_ACK), + .out_state_mask = S(IPA_ASP_S_ACTIVE) | + S(IPA_ASP_S_DOWN), + .name = "WAIT_ID_ACK", + .action = ipa_asp_fsm_wait_id_ack, + }, + [IPA_ASP_S_ACTIVE] = { + .in_event_mask = S(XUA_ASP_E_M_ASP_DOWN_REQ) | + S(XUA_ASP_E_M_ASP_INACTIVE_REQ), + .out_state_mask = S(XUA_ASP_S_INACTIVE) | + S(XUA_ASP_S_DOWN), + .name = "ASP_ACTIVE", + .action = ipa_asp_fsm_active, + .onenter = ipa_asp_fsm_active_onenter, + }, +}; + + +struct osmo_fsm ipa_asp_fsm = { + .name = "IPA_ASP", + .states = ipa_asp_states, + .num_states = ARRAY_SIZE(ipa_asp_states), + .timer_cb = ipa_asp_fsm_timer_cb, + .log_subsys = DLSS7, + .event_names = xua_asp_event_names, + .allstate_event_mask = S(XUA_ASP_E_SCTP_COMM_DOWN_IND) | + S(XUA_ASP_E_SCTP_RESTART_IND) | + S(XUA_ASP_E_ASPSM_BEAT) | + S(XUA_ASP_E_ASPSM_BEAT_ACK), + .allstate_action = ipa_asp_allstate, +}; + + +/*! \brief Start a new ASP finite stae machine for given ASP + * \param[in] asp Application Server Process for which to start FSM + * \param[in] role Role (ASP, SG, IPSP) of this FSM + * \param[in] log_level Logging Level for ASP FSM logging + * \returns FSM instance on success; NULL on error */ +static struct osmo_fsm_inst *ipa_asp_fsm_start(struct osmo_ss7_asp *asp, + enum xua_asp_role role, int log_level) +{ + struct osmo_fsm_inst *fi; + struct ipa_asp_fsm_priv *iafp; + + /* allocate as child of AS? */ + fi = osmo_fsm_inst_alloc(&ipa_asp_fsm, asp, NULL, log_level, asp->cfg.name); + + iafp = talloc_zero(fi, struct ipa_asp_fsm_priv); + if (!iafp) { + osmo_fsm_inst_term(fi, OSMO_FSM_TERM_ERROR, NULL); + return NULL; + } + iafp->role = role; + iafp->asp = asp; + iafp->ipa_unit = talloc_zero(iafp, struct ipaccess_unit); + iafp->ipa_unit->unit_name = talloc_strdup(iafp->ipa_unit, asp->cfg.name); + iafp->pong_timer.cb = ipa_pong_timer_cb; + iafp->pong_timer.data = fi; + + fi->priv = iafp; + + if (role == XUA_ASPFSM_ROLE_ASP) + osmo_fsm_inst_dispatch(fi, XUA_ASP_E_M_ASP_UP_REQ, NULL); + + return fi; +} diff --git a/src/xua_asp_fsm.h b/src/xua_asp_fsm.h index 60e09da..32749ec 100644 --- a/src/xua_asp_fsm.h +++ b/src/xua_asp_fsm.h @@ -28,6 +28,11 @@ XUA_ASP_E_ASPSM_BEAT, XUA_ASP_E_ASPSM_BEAT_ACK, + /* IPA specific */ + IPA_ASP_E_ID_RESP, + IPA_ASP_E_ID_ACK, + IPA_ASP_E_ID_GET, + _NUM_XUA_ASP_E }; @@ -38,6 +43,7 @@ }; extern struct osmo_fsm xua_asp_fsm; +extern struct osmo_fsm ipa_asp_fsm; struct osmo_fsm_inst *xua_asp_fsm_start(struct osmo_ss7_asp *asp, enum xua_asp_role role, int log_level); diff --git a/src/xua_internal.h b/src/xua_internal.h index 3831f56..bb54205 100644 --- a/src/xua_internal.h +++ b/src/xua_internal.h @@ -66,3 +66,9 @@ #define CS7_STR "ITU-T Signaling System 7\n" #define PC_STR "Point Code\n" #define INST_STR "An instance of the SS7 stack\n" + +int xua_as_transmit_msg(struct osmo_ss7_as *as, struct msgb *msg); + + +int ipa_tx_xua_as(struct osmo_ss7_as *as, struct xua_msg *xua); +int ipa_rx_msg(struct osmo_ss7_asp *asp, struct msgb *msg); -- To view, visit https://gerrit.osmocom.org/2282 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I9098574cddeba10fcf8f1b6c196a7069a6805c56 Gerrit-PatchSet: 5 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Apr 18 10:08:26 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 18 Apr 2017 10:08:26 +0000 Subject: [MERGED] libosmo-sccp[master]: IPA: Override/Set point codes In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: IPA: Override/Set point codes ...................................................................... IPA: Override/Set point codes As an IPA SCCPlite message arrives without any MTP routing label, we simply construct one artificially for all inbound IPA/SCCPlite packets: * we set the SPC to the point-code of the routing key of the AS (as this is the PC we route to this IPA/SCCPlite client anyway) * we set the DPC to a point-code from a new vty config command "point-code override dpc" Change-Id: Id556398e1ded3e613cfde7ea8b71aff7a414ff90 --- M include/osmocom/sigtran/osmo_ss7.h M src/ipa.c M src/osmo_ss7_vty.c 3 files changed, 64 insertions(+), 2 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/include/osmocom/sigtran/osmo_ss7.h b/include/osmocom/sigtran/osmo_ss7.h index 2ae4c1e..7b0a607 100644 --- a/include/osmocom/sigtran/osmo_ss7.h +++ b/include/osmocom/sigtran/osmo_ss7.h @@ -291,6 +291,9 @@ enum osmo_ss7_as_traffic_mode mode; uint32_t recovery_timeout_msec; uint8_t qos_class; + struct { + uint32_t dpc; + } pc_override;; struct osmo_ss7_asp *asps[16]; } cfg; diff --git a/src/ipa.c b/src/ipa.c index 1668f0f..df3dbd1 100644 --- a/src/ipa.c +++ b/src/ipa.c @@ -116,10 +116,33 @@ return 0; } +static struct osmo_ss7_as *find_as_for_asp(struct osmo_ss7_asp *asp) +{ + struct osmo_ss7_as *as; + + /* in the IPA case, weassume there is a 1:1 mapping between the + * ASP and the AS. An AS without ASP means there is no + * connection, and an ASP without AS means that we don't (yet?) + * know the identity of the peer */ + + llist_for_each_entry(as, &asp->inst->as_list, list) { + if (osmo_ss7_as_has_asp(as, asp)) + return as; + } + return NULL; +} + static int ipa_rx_msg_sccp(struct osmo_ss7_asp *asp, struct msgb *msg) { struct m3ua_data_hdr data_hdr; struct xua_msg *xua = xua_msg_alloc(); + struct osmo_ss7_as *as = find_as_for_asp(asp); + + if (!as) { + LOGPASP(asp, DLSS7, LOGL_ERROR, "Rx message for IPA ASP without AS?!\n"); + msgb_free(msg); + return -1; + } /* pull the IPA header */ msgb_pull_to_l2(msg); @@ -142,9 +165,18 @@ */ memset(&data_hdr, 0, sizeof(data_hdr)); - data_hdr.opc = 0;//FIXME; - data_hdr.dpc = 0;//FIXME; data_hdr.si = MTP_SI_SCCP; + if (asp->cfg.is_server) { + /* Source: the PC of the routing key */ + data_hdr.opc = as->cfg.routing_key.pc; + /* Destination: Based on VTY config */ + data_hdr.dpc = as->cfg.pc_override.dpc; + } else { + /* Source: Based on VTY config */ + data_hdr.opc = as->cfg.pc_override.dpc; + /* Destination: PC of the routing key */ + data_hdr.dpc = as->cfg.routing_key.pc; + } xua = m3ua_xfer_from_data(&data_hdr, msgb_l2(msg), msgb_l2len(msg)); return m3ua_hmdc_rx_from_l2(asp->inst, xua); diff --git a/src/osmo_ss7_vty.c b/src/osmo_ss7_vty.c index a6a0f5b..0ff9e76 100644 --- a/src/osmo_ss7_vty.c +++ b/src/osmo_ss7_vty.c @@ -789,6 +789,28 @@ return CMD_SUCCESS; } +DEFUN(as_pc_override, as_pc_override_cmd, + "point-code override dpc PC", + "Point Code Specific Features\n" + "Override (force) a point-code to hard-coded value\n" + "Override Source Point Code\n" + "Override Destination Point Code\n" + "New Point Code\n") +{ + struct osmo_ss7_as *as = vty->index; + uint32_t pc = osmo_ss7_pointcode_parse(as->inst, argv[0]); + + if (as->cfg.proto != OSMO_SS7_ASP_PROT_IPA) { + vty_out(vty, "Only IPA type AS support point-code override. " + "Be happy that you don't need it!%s", VTY_NEWLINE); + return CMD_WARNING; + } + + as->cfg.pc_override.dpc = pc; + + return CMD_SUCCESS; +} + static void write_one_as(struct vty *vty, struct osmo_ss7_as *as) { struct osmo_ss7_routing_key *rkey; @@ -826,6 +848,10 @@ if (rkey->ssn) vty_out(vty, " ssn %u", rkey->ssn); vty_out(vty, "%s", VTY_NEWLINE); + + if (as->cfg.pc_override.dpc) + vty_out(vty, " point-code override dpc %s%s", + osmo_ss7_pointcode_print(as->inst, as->cfg.pc_override.dpc), VTY_NEWLINE); } DEFUN(show_cs7_as, show_cs7_as_cmd, @@ -1012,6 +1038,7 @@ install_element(L_CS7_AS_NODE, &as_recov_tout_cmd); install_element(L_CS7_AS_NODE, &as_qos_class_cmd); install_element(L_CS7_AS_NODE, &as_rout_key_cmd); + install_element(L_CS7_AS_NODE, &as_pc_override_cmd); } void osmo_ss7_vty_init_asp(void) -- To view, visit https://gerrit.osmocom.org/2370 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Id556398e1ded3e613cfde7ea8b71aff7a414ff90 Gerrit-PatchSet: 2 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Apr 18 10:08:26 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 18 Apr 2017 10:08:26 +0000 Subject: [MERGED] libosmo-sccp[master]: osmo_ss7: Allocate message buffers with headroom In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: osmo_ss7: Allocate message buffers with headroom ...................................................................... osmo_ss7: Allocate message buffers with headroom The use of m3ua_msgb_alloc() from generic code is a bit ugly, but I really don't want to introduce yet another msgb_alloc wrapper. Change-Id: Ic6dc9a1e7bbed2e1f73395bd18b727fa7892e25b --- M src/osmo_ss7.c 1 file changed, 2 insertions(+), 3 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index 977dae3..31c0dc5 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -48,7 +48,6 @@ #include "xua_asp_fsm.h" #include "xua_as_fsm.h" -#define ASP_MSGB_SIZE 1500 #define MAX_PC_STR_LEN 32 static bool ss7_initialized = false; @@ -1274,7 +1273,7 @@ { struct osmo_fd *ofd = osmo_stream_srv_get_ofd(conn); struct osmo_ss7_asp *asp = osmo_stream_srv_get_data(conn); - struct msgb *msg = msgb_alloc(ASP_MSGB_SIZE, "xUA Server Rx"); + struct msgb *msg = m3ua_msgb_alloc("xUA Server Rx"); struct sctp_sndrcvinfo sinfo; unsigned int ppid; int flags = 0; @@ -1414,7 +1413,7 @@ { struct osmo_fd *ofd = osmo_stream_cli_get_ofd(conn); struct osmo_ss7_asp *asp = osmo_stream_cli_get_data(conn); - struct msgb *msg = msgb_alloc(ASP_MSGB_SIZE, "xUA Client Rx"); + struct msgb *msg = m3ua_msgb_alloc("xUA Client Rx"); struct sctp_sndrcvinfo sinfo; unsigned int ppid; int flags = 0; -- To view, visit https://gerrit.osmocom.org/2369 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ic6dc9a1e7bbed2e1f73395bd18b727fa7892e25b Gerrit-PatchSet: 2 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Apr 18 10:08:27 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 18 Apr 2017 10:08:27 +0000 Subject: [MERGED] libosmo-sccp[master]: osmo_ss7: make sure to re-set all state on client disconnect In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: osmo_ss7: make sure to re-set all state on client disconnect ...................................................................... osmo_ss7: make sure to re-set all state on client disconnect When we disconnect a client, make sure that we always go through xua_cli_close_and_reconnect(), which will make sure to notify the ASP FSM using XUA_ASP_E_SCTP_COMM_DOWN_IND. Change-Id: I6859b8549c8cbbe2e8279da0ede562387a066d04 --- M src/osmo_ss7.c 1 file changed, 3 insertions(+), 5 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index 6495947..977dae3 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -1306,7 +1306,6 @@ switch (notif->sn_header.sn_type) { case SCTP_SHUTDOWN_EVENT: osmo_stream_srv_destroy(conn); - osmo_fsm_inst_dispatch(asp->fi, XUA_ASP_E_SCTP_COMM_DOWN_IND, asp); break; case SCTP_ASSOC_CHANGE: if (notif->sn_assoc_change.sac_state == SCTP_RESTART) @@ -1370,7 +1369,7 @@ struct osmo_ss7_asp *asp = osmo_stream_cli_get_data(cli); osmo_stream_cli_close(cli); - + osmo_fsm_inst_dispatch(asp->fi, XUA_ASP_E_SCTP_COMM_DOWN_IND, asp); /* send M-SCTP_RELEASE.ind to XUA Layer Manager */ xua_asp_send_xlm_prim_simple(asp, OSMO_XLM_PRIM_M_SCTP_RELEASE, PRIM_OP_INDICATION); } @@ -1398,12 +1397,12 @@ /* more data needed */ return 0; } - osmo_stream_cli_reconnect(conn); + xua_cli_close_and_reconnect(conn); return rc; } if (osmo_ipa_process_msg(msg) < 0) { LOGPASP(asp, DLSS7, LOGL_ERROR, "Bad IPA message\n"); - osmo_stream_cli_reconnect(conn); + xua_cli_close_and_reconnect(conn); msgb_free(msg); return -1; } @@ -1445,7 +1444,6 @@ switch (notif->sn_header.sn_type) { case SCTP_SHUTDOWN_EVENT: - osmo_fsm_inst_dispatch(asp->fi, XUA_ASP_E_SCTP_COMM_DOWN_IND, asp); xua_cli_close_and_reconnect(conn); break; case SCTP_ASSOC_CHANGE: -- To view, visit https://gerrit.osmocom.org/2365 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I6859b8549c8cbbe2e8279da0ede562387a066d04 Gerrit-PatchSet: 4 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Apr 18 12:59:44 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 18 Apr 2017 12:59:44 +0000 Subject: openbsc[master]: Prepare for extended SI2quater support In-Reply-To: References: Message-ID: Patch Set 7: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2312 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I74e4e3cb86364cec869a1472a41b4a95af0d50dd Gerrit-PatchSet: 7 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Apr 18 13:02:02 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 18 Apr 2017 13:02:02 +0000 Subject: osmo-bts[master]: Prepare for extended SI2quater support In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 (1 comment) https://gerrit.osmocom.org/#/c/2313/2/src/common/rsl.c File src/common/rsl.c: Line 439: len = sizeof(sysinfo_buf_t) - 2; does truncation here make sense? should we not at the very least print a LOGL_ERROR message that we are effectively generating broken messages? I know you just moved the code, but maybe as a follow-up commit? -- To view, visit https://gerrit.osmocom.org/2313 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ie97be6ead6ce6d2d425fbfac8429bb90afb95acc Gerrit-PatchSet: 2 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Tue Apr 18 13:03:55 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 18 Apr 2017 13:03:55 +0000 Subject: openbsc[master]: Save PCU version reported by BTS In-Reply-To: References: Message-ID: Patch Set 1: (1 comment) https://gerrit.osmocom.org/#/c/2289/1/openbsc/src/libbsc/abis_nm.c File openbsc/src/libbsc/abis_nm.c: Line 317: osmo_strlcpy(bts->pcu_version, text, MAX_VERSION_LENGTH); when copying to some buffer, it always makes sense to use sizeof(buffer). If somebody changes bts->pcu_version[] to have a size differetn than MAX_VERSION_LENGTH, your code will break. If you use sizeof(bts->pcu_version), it should continue to work. -- To view, visit https://gerrit.osmocom.org/2289 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Idb32c73036413ee912f633604150ee17b611cfa7 Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Tue Apr 18 13:05:25 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 18 Apr 2017 13:05:25 +0000 Subject: openbsc[master]: Use libosmocore for SW Description parsing In-Reply-To: References: Message-ID: Patch Set 8: have those changes been tested with a nanoBTS? After all, it changes ipaccess-config... -- To view, visit https://gerrit.osmocom.org/2166 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ib94db414e94a2a1f234ac6f1cb346dca1c7a8be3 Gerrit-PatchSet: 8 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Apr 18 14:19:03 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Tue, 18 Apr 2017 14:19:03 +0000 Subject: libosmo-netif[master]: stream.h: Add missing stdint.h include In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+1 -- To view, visit https://gerrit.osmocom.org/2368 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I399e2986c9d8cb5b3dd31673a6b4bf63070a4770 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Pau Espin Pedrol Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Apr 18 14:21:38 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Tue, 18 Apr 2017 14:21:38 +0000 Subject: openbsc[master]: Use libosmocore for SW Description parsing In-Reply-To: References: Message-ID: Patch Set 8: The changes are related to fw update/select which I don't know how to test. Do we have firmware image for nanoBTS somewhere? Tried to search wiki but found nothing so far. -- To view, visit https://gerrit.osmocom.org/2166 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ib94db414e94a2a1f234ac6f1cb346dca1c7a8be3 Gerrit-PatchSet: 8 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Apr 18 15:29:25 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Tue, 18 Apr 2017 15:29:25 +0000 Subject: [PATCH] openbsc[master]: Prepare for extended SI2quater support In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2312 to look at the new patch set (#8). Prepare for extended SI2quater support Supporting SI2quater as per 3GPP TS 44.018 will require chnages to the way System Information is stored because it uses 1:n instead of 1:1 mapping between SI type and generated SI content. This should not affect other SI types though. To facilitate this transition: * convert the code to always use GSM_BTS_SI helper instead of accessing buffer directly * make helper more robust by adding extra parenthesis * add similar helper for gsm_lchan * add function estimating number of SI2quater message to hold configured number of (U|E)ARFCNs * add SI2q index/count fields and pass them to rest_octets generator explicitly * internalize buffer access in generate_si* functions Change-Id: I74e4e3cb86364cec869a1472a41b4a95af0d50dd Related: RT#8792 --- M openbsc/include/openbsc/gsm_data_shared.h M openbsc/include/openbsc/rest_octets.h M openbsc/include/openbsc/system_information.h M openbsc/src/libbsc/bsc_vty.c M openbsc/src/libbsc/rest_octets.c M openbsc/src/libbsc/system_information.c M openbsc/tests/gsm0408/gsm0408_test.c 7 files changed, 60 insertions(+), 61 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/12/2312/8 diff --git a/openbsc/include/openbsc/gsm_data_shared.h b/openbsc/include/openbsc/gsm_data_shared.h index 242889a..166de16 100644 --- a/openbsc/include/openbsc/gsm_data_shared.h +++ b/openbsc/include/openbsc/gsm_data_shared.h @@ -483,7 +483,8 @@ struct gsm_bts_trx_ts ts[TRX_NR_TS]; }; -#define GSM_BTS_SI(bts, i) (void *)(bts->si_buf[i]) +#define GSM_BTS_SI(bts, i) (void *)((bts)->si_buf[i]) +#define GSM_LCHAN_SI(lchan, i) (void *)((lchan)->si.buf[i]) enum gsm_bts_type { GSM_BTS_TYPE_UNKNOWN, @@ -702,6 +703,9 @@ /* bitmask of all SI that are present/valid in si_buf */ uint32_t si_valid; + /* 3GPP TS 44.018 Table 10.5.2.33b.1 INDEX and COUNT for SI2quater */ + uint8_t si2q_index; + uint8_t si2q_count; /* buffers where we put the pre-computed SI */ sysinfo_buf_t si_buf[_MAX_SYSINFO_TYPE]; diff --git a/openbsc/include/openbsc/rest_octets.h b/openbsc/include/openbsc/rest_octets.h index 3b4e598..73ce57b 100644 --- a/openbsc/include/openbsc/rest_octets.h +++ b/openbsc/include/openbsc/rest_octets.h @@ -5,12 +5,15 @@ #include #include +/* 16 is the max. number of SI2quater messages according to 3GPP TS 44.018: 4-bit index is used */ +#define SI2Q_MAX_NUM 16 +/* length in bits (for single SI2quater message) */ #define SI2Q_MAX_LEN 160 #define SI2Q_MIN_LEN 18 /* generate SI1 rest octets */ int rest_octets_si1(uint8_t *data, uint8_t *nch_pos, int is1800_net); -int rest_octets_si2quater(uint8_t *data, const struct osmo_earfcn_si2q *e, +int rest_octets_si2quater(uint8_t *data, uint8_t index, uint8_t count, const struct osmo_earfcn_si2q *e, const uint16_t *u, const uint16_t *sc, size_t u_len); int rest_octets_si6(uint8_t *data, bool is1800_net); diff --git a/openbsc/include/openbsc/system_information.h b/openbsc/include/openbsc/system_information.h index 1b19c8b..b012107 100644 --- a/openbsc/include/openbsc/system_information.h +++ b/openbsc/include/openbsc/system_information.h @@ -14,7 +14,7 @@ unsigned range512_q(unsigned m); int range_encode(enum gsm48_range r, int *arfcns, int arfcns_used, int *w, int f0, uint8_t *chan_list); -bool si2q_size_check(const struct gsm_bts *bts); +uint8_t si2q_num(const struct gsm_bts *bts); int bts_uarfcn_del(struct gsm_bts *bts, uint16_t arfcn, uint16_t scramble); int bts_uarfcn_add(struct gsm_bts *bts, uint16_t arfcn, uint16_t scramble, bool diversity); diff --git a/openbsc/src/libbsc/bsc_vty.c b/openbsc/src/libbsc/bsc_vty.c index c1882fc..657dfe3 100644 --- a/openbsc/src/libbsc/bsc_vty.c +++ b/openbsc/src/libbsc/bsc_vty.c @@ -644,7 +644,7 @@ get_value_string(osmo_sitype_strs, i), VTY_NEWLINE); vty_out(vty, " system-information %s static %s%s", get_value_string(osmo_sitype_strs, i), - osmo_hexdump_nospc(bts->si_buf[i], sizeof(bts->si_buf[i])), + osmo_hexdump_nospc(GSM_BTS_SI(bts, i), GSM_MACBLOCK_LEN), VTY_NEWLINE); } } @@ -2688,11 +2688,11 @@ } /* Fill buffer with padding pattern */ - memset(bts->si_buf[type], 0x2b, sizeof(bts->si_buf[type])); + memset(GSM_BTS_SI(bts, type), 0x2b, GSM_MACBLOCK_LEN); /* Parse the user-specified SI in hex format, [partially] overwriting padding */ - rc = osmo_hexparse(argv[1], bts->si_buf[type], sizeof(bts->si_buf[0])); - if (rc < 0 || rc > sizeof(bts->si_buf[0])) { + rc = osmo_hexparse(argv[1], GSM_BTS_SI(bts, type), GSM_MACBLOCK_LEN); + if (rc < 0 || rc > GSM_MACBLOCK_LEN) { vty_out(vty, "Error parsing HEXSTRING%s", VTY_NEWLINE); return CMD_WARNING; } @@ -2830,7 +2830,7 @@ e->prio_valid = true; } - if (si2q_size_check(bts)) + if (si2q_num(bts) < 2) return CMD_SUCCESS; vty_out(vty, "Warning: not enough space in SI2quater for a given EARFCN " diff --git a/openbsc/src/libbsc/rest_octets.c b/openbsc/src/libbsc/rest_octets.c index ed6c573..af660f1 100644 --- a/openbsc/src/libbsc/rest_octets.c +++ b/openbsc/src/libbsc/rest_octets.c @@ -256,7 +256,7 @@ } /* generate SI2quater rest octets: 3GPP TS 44.018 ? 10.5.2.33b */ -int rest_octets_si2quater(uint8_t *data, const struct osmo_earfcn_si2q *e, +int rest_octets_si2quater(uint8_t *data, uint8_t index, uint8_t count, const struct osmo_earfcn_si2q *e, const uint16_t *u, const uint16_t *sc, size_t u_len) { int rc; @@ -275,9 +275,9 @@ /* we do not support multiple si2quater messages at the moment: */ /* SI2quater_INDEX */ - bitvec_set_uint(&bv, 0, 4); + bitvec_set_uint(&bv, index, 4); /* SI2quater_COUNT */ - bitvec_set_uint(&bv, 0, 4); + bitvec_set_uint(&bv, count, 4); /* No Measurement_Parameters Description */ bitvec_set_bit(&bv, 0); diff --git a/openbsc/src/libbsc/system_information.c b/openbsc/src/libbsc/system_information.c index 2610331..37395f0 100644 --- a/openbsc/src/libbsc/system_information.c +++ b/openbsc/src/libbsc/system_information.c @@ -149,18 +149,13 @@ return s + r + append + range1024_p(k); } -bool si2q_size_check(const struct gsm_bts *bts) +uint8_t si2q_num(const struct gsm_bts *bts) { - const struct osmo_earfcn_si2q *e = &bts->si_common.si2quater_neigh_list; - const uint16_t *u = bts->si_common.data.uarfcn_list, - *sc = bts->si_common.data.scramble_list; - size_t len = bts->si_common.uarfcn_length; - unsigned e_sz = e ? earfcn_size(e) : 1, - u_sz = len ? uarfcn_size(u, sc, len) : 1; + const struct osmo_earfcn_si2q *e = &bts->si_common.si2quater_neigh_list; /* EARFCN */ + const uint16_t *u = bts->si_common.data.uarfcn_list, *sc = bts->si_common.data.scramble_list; /* UARFCN */ + size_t l = bts->si_common.uarfcn_length, e_sz = e ? earfcn_size(e) : 1, u_sz = l ? uarfcn_size(u, sc, l) : 1; /* 2 bits are used in between UARFCN and EARFCN structs */ - if (SI2Q_MIN_LEN + u_sz + 2 + e_sz > SI2Q_MAX_LEN) - return false; - return true; + return 1 + (e_sz + u_sz) / (SI2Q_MAX_LEN - (SI2Q_MIN_LEN + 2)); } /* 3GPP TS 44.018, Table 9.1.54.1 - prepend diversity bit to scrambling code */ @@ -233,7 +228,7 @@ scl[k] = scr; bts->si_common.uarfcn_length++; - if (si2q_size_check(bts)) + if (si2q_num(bts) < 2) return 0; bts_uarfcn_del(bts, arfcn, scramble); @@ -557,11 +552,10 @@ return n; } -static int generate_si1(uint8_t *output, struct gsm_bts *bts) +static int generate_si1(enum osmo_sysinfo_type t, struct gsm_bts *bts) { int rc; - struct gsm48_system_information_type_1 *si1 = - (struct gsm48_system_information_type_1 *) output; + struct gsm48_system_information_type_1 *si1 = (struct gsm48_system_information_type_1 *) GSM_BTS_SI(bts, t); memset(si1, GSM_MACBLOCK_PADDING, GSM_MACBLOCK_LEN); @@ -586,11 +580,10 @@ return sizeof(*si1) + rc; } -static int generate_si2(uint8_t *output, struct gsm_bts *bts) +static int generate_si2(enum osmo_sysinfo_type t, struct gsm_bts *bts) { int rc; - struct gsm48_system_information_type_2 *si2 = - (struct gsm48_system_information_type_2 *) output; + struct gsm48_system_information_type_2 *si2 = (struct gsm48_system_information_type_2 *) GSM_BTS_SI(bts, t); memset(si2, GSM_MACBLOCK_PADDING, GSM_MACBLOCK_LEN); @@ -611,11 +604,11 @@ return sizeof(*si2); } -static int generate_si2bis(uint8_t *output, struct gsm_bts *bts) +static int generate_si2bis(enum osmo_sysinfo_type t, struct gsm_bts *bts) { int rc; struct gsm48_system_information_type_2bis *si2b = - (struct gsm48_system_information_type_2bis *) output; + (struct gsm48_system_information_type_2bis *) GSM_BTS_SI(bts, t); int n; memset(si2b, GSM_MACBLOCK_PADDING, GSM_MACBLOCK_LEN); @@ -633,8 +626,7 @@ if (n) { /* indicate in SI2 and SI2bis: there is an extension */ struct gsm48_system_information_type_2 *si2 = - (struct gsm48_system_information_type_2 *) - bts->si_buf[SYSINFO_TYPE_2]; + (struct gsm48_system_information_type_2 *) GSM_BTS_SI(bts, SYSINFO_TYPE_2); si2->bcch_frequency_list[0] |= 0x20; si2b->bcch_frequency_list[0] |= 0x20; } else @@ -645,11 +637,11 @@ return sizeof(*si2b); } -static int generate_si2ter(uint8_t *output, struct gsm_bts *bts) +static int generate_si2ter(enum osmo_sysinfo_type t, struct gsm_bts *bts) { int rc; struct gsm48_system_information_type_2ter *si2t = - (struct gsm48_system_information_type_2ter *) output; + (struct gsm48_system_information_type_2ter *) GSM_BTS_SI(bts, t); int n; memset(si2t, GSM_MACBLOCK_PADDING, GSM_MACBLOCK_LEN); @@ -670,11 +662,11 @@ return sizeof(*si2t); } -static int generate_si2quater(uint8_t *output, struct gsm_bts *bts) +static int generate_si2quater(enum osmo_sysinfo_type t, struct gsm_bts *bts) { int rc, i = MAX_EARFCN_LIST; struct gsm48_system_information_type_2quater *si2q = - (struct gsm48_system_information_type_2quater *) output; + (struct gsm48_system_information_type_2quater *) GSM_BTS_SI(bts, t); memset(si2q, GSM_MACBLOCK_PADDING, GSM_MACBLOCK_LEN); @@ -683,7 +675,7 @@ si2q->header.skip_indicator = 0; si2q->header.system_information = GSM48_MT_RR_SYSINFO_2quater; - rc = rest_octets_si2quater(si2q->rest_octets, + rc = rest_octets_si2quater(si2q->rest_octets, bts->si2q_index, bts->si2q_count, &bts->si_common.si2quater_neigh_list, bts->si_common.data.uarfcn_list, bts->si_common.data.scramble_list, @@ -727,11 +719,10 @@ .break_ind = 0, }; -static int generate_si3(uint8_t *output, struct gsm_bts *bts) +static int generate_si3(enum osmo_sysinfo_type t, struct gsm_bts *bts) { int rc; - struct gsm48_system_information_type_3 *si3 = - (struct gsm48_system_information_type_3 *) output; + struct gsm48_system_information_type_3 *si3 = (struct gsm48_system_information_type_3 *) GSM_BTS_SI(bts, t); memset(si3, GSM_MACBLOCK_PADDING, GSM_MACBLOCK_LEN); @@ -775,11 +766,10 @@ return sizeof(*si3) + rc; } -static int generate_si4(uint8_t *output, struct gsm_bts *bts) +static int generate_si4(enum osmo_sysinfo_type t, struct gsm_bts *bts) { int rc; - struct gsm48_system_information_type_4 *si4 = - (struct gsm48_system_information_type_4 *) output; + struct gsm48_system_information_type_4 *si4 = (struct gsm48_system_information_type_4 *) GSM_BTS_SI(bts, t); struct gsm_lchan *cbch_lchan; uint8_t *restoct = si4->data; @@ -815,14 +805,15 @@ /* SI4 Rest Octets (10.5.2.35), containing Optional Power offset, GPRS Indicator, Cell Identity, LSA ID, Selection Parameter */ - rc = rest_octets_si4(restoct, &si_info, output + GSM_MACBLOCK_LEN - restoct); + rc = rest_octets_si4(restoct, &si_info, (uint8_t *)GSM_BTS_SI(bts, t) + GSM_MACBLOCK_LEN - restoct); return l2_plen + 1 + rc; } -static int generate_si5(uint8_t *output, struct gsm_bts *bts) +static int generate_si5(enum osmo_sysinfo_type t, struct gsm_bts *bts) { struct gsm48_system_information_type_5 *si5; + uint8_t *output = GSM_BTS_SI(bts, t); int rc, l2_plen = 18; memset(output, GSM_MACBLOCK_PADDING, GSM_MACBLOCK_LEN); @@ -838,7 +829,7 @@ break; } - si5 = (struct gsm48_system_information_type_5 *) output; + si5 = (struct gsm48_system_information_type_5 *) GSM_BTS_SI(bts, t); /* l2 pseudo length, not part of msg: 18 */ si5->rr_protocol_discriminator = GSM48_PDISC_RR; @@ -854,9 +845,10 @@ return l2_plen; } -static int generate_si5bis(uint8_t *output, struct gsm_bts *bts) +static int generate_si5bis(enum osmo_sysinfo_type t, struct gsm_bts *bts) { struct gsm48_system_information_type_5bis *si5b; + uint8_t *output = GSM_BTS_SI(bts, t); int rc, l2_plen = 18; int n; @@ -873,7 +865,7 @@ break; } - si5b = (struct gsm48_system_information_type_5bis *) output; + si5b = (struct gsm48_system_information_type_5bis *) GSM_BTS_SI(bts, t); /* l2 pseudo length, not part of msg: 18 */ si5b->rr_protocol_discriminator = GSM48_PDISC_RR; @@ -887,8 +879,7 @@ if (n) { /* indicate in SI5 and SI5bis: there is an extension */ struct gsm48_system_information_type_5 *si5 = - (struct gsm48_system_information_type_5 *) - bts->si_buf[SYSINFO_TYPE_5]; + (struct gsm48_system_information_type_5 *) GSM_BTS_SI(bts, SYSINFO_TYPE_5); si5->bcch_frequency_list[0] |= 0x20; si5b->bcch_frequency_list[0] |= 0x20; } else @@ -898,9 +889,10 @@ return l2_plen; } -static int generate_si5ter(uint8_t *output, struct gsm_bts *bts) +static int generate_si5ter(enum osmo_sysinfo_type t, struct gsm_bts *bts) { struct gsm48_system_information_type_5ter *si5t; + uint8_t *output = GSM_BTS_SI(bts, t); int rc, l2_plen = 18; int n; @@ -917,7 +909,7 @@ break; } - si5t = (struct gsm48_system_information_type_5ter *) output; + si5t = (struct gsm48_system_information_type_5ter *) GSM_BTS_SI(bts, t); /* l2 pseudo length, not part of msg: 18 */ si5t->rr_protocol_discriminator = GSM48_PDISC_RR; @@ -935,9 +927,10 @@ return l2_plen; } -static int generate_si6(uint8_t *output, struct gsm_bts *bts) +static int generate_si6(enum osmo_sysinfo_type t, struct gsm_bts *bts) { struct gsm48_system_information_type_6 *si6; + uint8_t *output = GSM_BTS_SI(bts, t); int l2_plen = 11; int rc; @@ -954,7 +947,7 @@ break; } - si6 = (struct gsm48_system_information_type_6 *) output; + si6 = (struct gsm48_system_information_type_6 *) GSM_BTS_SI(bts, t); /* l2 pseudo length, not part of msg: 11 */ si6->rr_protocol_discriminator = GSM48_PDISC_RR; @@ -1015,10 +1008,10 @@ }, }; -static int generate_si13(uint8_t *output, struct gsm_bts *bts) +static int generate_si13(enum osmo_sysinfo_type t, struct gsm_bts *bts) { struct gsm48_system_information_type_13 *si13 = - (struct gsm48_system_information_type_13 *) output; + (struct gsm48_system_information_type_13 *) GSM_BTS_SI(bts, t); int ret; memset(si13, GSM_MACBLOCK_PADDING, GSM_MACBLOCK_LEN); @@ -1048,7 +1041,7 @@ return sizeof (*si13) + ret; } -typedef int (*gen_si_fn_t)(uint8_t *output, struct gsm_bts *bts); +typedef int (*gen_si_fn_t)(enum osmo_sysinfo_type t, struct gsm_bts *bts); static const gen_si_fn_t gen_si_fn[_MAX_SYSINFO_TYPE] = { [SYSINFO_TYPE_1] = &generate_si1, @@ -1090,5 +1083,5 @@ if (!gen_si) return -EINVAL; - return gen_si(bts->si_buf[si_type], bts); + return gen_si(si_type, bts); } diff --git a/openbsc/tests/gsm0408/gsm0408_test.c b/openbsc/tests/gsm0408/gsm0408_test.c index 08cf43f..81dc177 100644 --- a/openbsc/tests/gsm0408/gsm0408_test.c +++ b/openbsc/tests/gsm0408/gsm0408_test.c @@ -99,13 +99,12 @@ bts->si_valid = 0; bts->si_valid |= (1 << SYSINFO_TYPE_2quater); /* should be no-op as entire buffer is filled with padding: */ - memset(bts->si_buf[SYSINFO_TYPE_2quater], 0xAE, GSM_MACBLOCK_LEN); + memset(GSM_BTS_SI(bts, SYSINFO_TYPE_2quater), 0xAE, GSM_MACBLOCK_LEN); int r = gsm_generate_si(bts, SYSINFO_TYPE_2quater); bool v = bts->si_valid & (1 << SYSINFO_TYPE_2quater); if (r > 0) printf("generated %s SI2quater: [%d] %s\n", - v ? "valid" : "invalid", r, - osmo_hexdump(bts->si_buf[SYSINFO_TYPE_2quater], r)); + v ? "valid" : "invalid", r, osmo_hexdump(GSM_BTS_SI(bts, SYSINFO_TYPE_2quater), r)); else printf("failed to generate SI2quater: %s\n", strerror(-r)); } -- To view, visit https://gerrit.osmocom.org/2312 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I74e4e3cb86364cec869a1472a41b4a95af0d50dd Gerrit-PatchSet: 8 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Apr 18 15:33:55 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Tue, 18 Apr 2017 15:33:55 +0000 Subject: [PATCH] openbsc[master]: Save PCU version reported by BTS In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2289 to look at the new patch set (#2). Save PCU version reported by BTS When BTS reports PCU disconnect - clear it. Change-Id: Idb32c73036413ee912f633604150ee17b611cfa7 Related: OS#1615 --- M openbsc/src/libbsc/abis_nm.c 1 file changed, 9 insertions(+), 13 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/89/2289/2 diff --git a/openbsc/src/libbsc/abis_nm.c b/openbsc/src/libbsc/abis_nm.c index 56b6fcf..132e72d 100644 --- a/openbsc/src/libbsc/abis_nm.c +++ b/openbsc/src/libbsc/abis_nm.c @@ -302,31 +302,27 @@ LOGPC(DNM, LOGL_ERROR, "\n"); } -static inline void handle_manufact_report(const struct gsm_bts *bts, - const uint8_t *p_val, const char *type, +static inline void handle_manufact_report(struct gsm_bts *bts, const uint8_t *p_val, const char *type, const char *severity, const char *text) { enum abis_mm_event_causes cause = osmo_load16be(p_val + 1); switch (cause) { case OSMO_EVT_PCU_VERS: - if (text) - LOGPC(DNM, LOGL_NOTICE, - "BTS %u reported connected PCU version %s\n", - bts->nr, text); - else - LOGPC(DNM, LOGL_ERROR, - "BTS %u sent %s without actual version string.\n", - bts->nr, - get_value_string(abis_mm_event_cause_names, - cause)); + if (text) { + LOGPC(DNM, LOGL_NOTICE, "BTS %u reported connected PCU version %s\n", bts->nr, text); + osmo_strlcpy(bts->pcu_version, text, sizeof(bts->pcu_version)); + } else { + LOGPC(DNM, LOGL_ERROR, "BTS %u reported PCU disconnection.\n", bts->nr); + bts->pcu_version[0] = '\0'; + } break; default: log_oml_fail_rep(bts, type, severity, p_val, text); }; } -static int rx_fail_evt_rep(struct msgb *mb, const struct gsm_bts *bts) +static int rx_fail_evt_rep(struct msgb *mb, struct gsm_bts *bts) { struct abis_om_hdr *oh = msgb_l2(mb); struct abis_om_fom_hdr *foh = msgb_l3(mb); -- To view, visit https://gerrit.osmocom.org/2289 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Idb32c73036413ee912f633604150ee17b611cfa7 Gerrit-PatchSet: 2 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Apr 18 17:39:01 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Tue, 18 Apr 2017 17:39:01 +0000 Subject: osmo-gsm-manuals[master]: First step towards an OsmoSTP manual In-Reply-To: References: Message-ID: Patch Set 4: After brief review of first few pages: - "on top of [parts of]" in ?4 seems like editing artifact - TON + NPI in Table 2 are not explained - ?4.4.3 lists are broken - ?4.4.4 point code should be upper case to match the rest of the docs - ?4.5.1 terminologyand - ?4.6.2 SUA-baesd - given the rather complex stacking, picture illustrating different layers and their relation to each other would be very helpful for reader -- To view, visit https://gerrit.osmocom.org/2371 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I450bfac7444ac9cb7f50c086d87cf7157c2e2a31 Gerrit-PatchSet: 4 Gerrit-Project: osmo-gsm-manuals Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-HasComments: No From admin at opensuse.org Tue Apr 18 20:03:18 2017 From: admin at opensuse.org (OBS Notification) Date: Tue, 18 Apr 2017 20:03:18 +0000 Subject: Build failure of network:osmocom:nightly/libosmo-sccp in xUbuntu_16.04/i586 In-Reply-To: References: Message-ID: <58f67127cfe7_9961156f8485043a@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/libosmo-sccp/xUbuntu_16.04/i586 Package network:osmocom:nightly/libosmo-sccp failed to build in xUbuntu_16.04/i586 Check out the package for editing: osc checkout network:osmocom:nightly libosmo-sccp Last lines of build log: [ 129s] /usr/src/packages/BUILD/src/xua_asp_fsm.c:772: undefined reference to `ipa_ccm_send_id_req' [ 129s] ../../src/.libs/libosmo-sigtran.a(ipa.o): In function `ipa_tx_xua_as': [ 129s] /usr/src/packages/BUILD/src/ipa.c:71: undefined reference to `ipa_msg_alloc' [ 129s] collect2: error: ld returned 1 exit status [ 129s] Makefile:360: recipe for target 'xua_test' failed [ 129s] make[4]: *** [xua_test] Error 1 [ 129s] make[4]: Leaving directory '/usr/src/packages/BUILD/tests/xua' [ 129s] Makefile:362: recipe for target 'all-recursive' failed [ 129s] make[3]: *** [all-recursive] Error 1 [ 129s] make[3]: Leaving directory '/usr/src/packages/BUILD/tests' [ 129s] Makefile:454: recipe for target 'all-recursive' failed [ 129s] make[2]: *** [all-recursive] Error 1 [ 129s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 129s] Makefile:372: recipe for target 'all' failed [ 129s] make[1]: *** [all] Error 2 [ 129s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 129s] dh_auto_build: make -j1 returned exit code 2 [ 129s] debian/rules:12: recipe for target 'build' failed [ 129s] make: *** [build] Error 2 [ 129s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 129s] [ 129s] lamb13 failed "build libosmo-sccp_0.7.1.20170418.dsc" at Tue Apr 18 20:02:58 UTC 2017. [ 129s] [ 129s] ### VM INTERACTION START ### [ 133s] [ 119.647583] reboot: Power down [ 133s] ### VM INTERACTION END ### [ 133s] [ 133s] lamb13 failed "build libosmo-sccp_0.7.1.20170418.dsc" at Tue Apr 18 20:03:02 UTC 2017. [ 133s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Tue Apr 18 20:06:28 2017 From: admin at opensuse.org (OBS Notification) Date: Tue, 18 Apr 2017 20:06:28 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in xUbuntu_16.04/i586 In-Reply-To: References: Message-ID: <58f671dd502cc_c7610b4f7c7154cd@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/xUbuntu_16.04/i586 Package network:osmocom:nightly/osmo-stp failed to build in xUbuntu_16.04/i586 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 96s] sctp_m2ua.c:91:3: warning: #warning "Notify any other AS(P) for failover scenario" [-Wcpp] [ 96s] #warning "Notify any other AS(P) for failover scenario" [ 96s] ^ [ 97s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -c -o vty_interface.o vty_interface.c [ 97s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -c -o sctp_m3ua_client.o sctp_m3ua_client.c [ 97s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 97s] compilation terminated. [ 97s] Makefile:485: recipe for target 'sctp_m3ua_client.o' failed [ 97s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 97s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 97s] Makefile:380: recipe for target 'all-recursive' failed [ 97s] make[2]: *** [all-recursive] Error 1 [ 97s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 97s] Makefile:321: recipe for target 'all' failed [ 97s] make[1]: *** [all] Error 2 [ 97s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 97s] dh_auto_build: make -j1 returned exit code 2 [ 97s] debian/rules:23: recipe for target 'build' failed [ 97s] make: *** [build] Error 2 [ 97s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 97s] [ 97s] lamb18 failed "build cellmgr-ng_1.4.7.20170418.dsc" at Tue Apr 18 20:06:14 UTC 2017. [ 97s] [ 97s] ### VM INTERACTION START ### [ 100s] [ 87.960986] reboot: Power down [ 100s] ### VM INTERACTION END ### [ 100s] [ 100s] lamb18 failed "build cellmgr-ng_1.4.7.20170418.dsc" at Tue Apr 18 20:06:18 UTC 2017. [ 100s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Tue Apr 18 20:07:01 2017 From: admin at opensuse.org (OBS Notification) Date: Tue, 18 Apr 2017 20:07:01 +0000 Subject: Build failure of network:osmocom:nightly/libosmo-sccp in xUbuntu_16.10/i586 In-Reply-To: References: Message-ID: <58f6721630d9_c7610b4f7c71559d@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/libosmo-sccp/xUbuntu_16.10/i586 Package network:osmocom:nightly/libosmo-sccp failed to build in xUbuntu_16.10/i586 Check out the package for editing: osc checkout network:osmocom:nightly libosmo-sccp Last lines of build log: [ 104s] ./src/xua_asp_fsm.c:772: undefined reference to `ipa_ccm_send_id_req' [ 104s] ../../src/.libs/libosmo-sigtran.a(ipa.o): In function `ipa_tx_xua_as': [ 104s] ./src/ipa.c:71: undefined reference to `ipa_msg_alloc' [ 104s] collect2: error: ld returned 1 exit status [ 104s] Makefile:360: recipe for target 'xua_test' failed [ 104s] make[4]: *** [xua_test] Error 1 [ 104s] make[4]: Leaving directory '/usr/src/packages/BUILD/tests/xua' [ 104s] Makefile:362: recipe for target 'all-recursive' failed [ 104s] make[3]: *** [all-recursive] Error 1 [ 104s] make[3]: Leaving directory '/usr/src/packages/BUILD/tests' [ 104s] Makefile:454: recipe for target 'all-recursive' failed [ 104s] make[2]: *** [all-recursive] Error 1 [ 104s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 104s] Makefile:372: recipe for target 'all' failed [ 104s] make[1]: *** [all] Error 2 [ 104s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 104s] dh_auto_build: make -j1 returned exit code 2 [ 104s] debian/rules:12: recipe for target 'build' failed [ 104s] make: *** [build] Error 2 [ 104s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 104s] [ 104s] lamb18 failed "build libosmo-sccp_0.7.1.20170418.dsc" at Tue Apr 18 20:06:45 UTC 2017. [ 104s] [ 104s] ### VM INTERACTION START ### [ 107s] [ 93.818440] reboot: Power down [ 107s] ### VM INTERACTION END ### [ 107s] [ 107s] lamb18 failed "build libosmo-sccp_0.7.1.20170418.dsc" at Tue Apr 18 20:06:49 UTC 2017. [ 107s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Tue Apr 18 20:07:18 2017 From: admin at opensuse.org (OBS Notification) Date: Tue, 18 Apr 2017 20:07:18 +0000 Subject: Build failure of network:osmocom:nightly/libosmo-sccp in Debian_8.0/i586 In-Reply-To: References: Message-ID: <58f67236445f4_98f1156f84803665@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/libosmo-sccp/Debian_8.0/i586 Package network:osmocom:nightly/libosmo-sccp failed to build in Debian_8.0/i586 Check out the package for editing: osc checkout network:osmocom:nightly libosmo-sccp Last lines of build log: [ 135s] /usr/bin/ld: ../../src/.libs/libosmo-sigtran.a(osmo_ss7.o): undefined reference to symbol 'ipa_msg_recv_buffered@@LIBOSMOGSM_1.0' [ 135s] //usr/lib/i386-linux-gnu/libosmogsm.so.6: error adding symbols: DSO missing from command line [ 135s] collect2: error: ld returned 1 exit status [ 135s] Makefile:348: recipe for target 'xua_test' failed [ 135s] make[4]: *** [xua_test] Error 1 [ 135s] make[4]: Leaving directory '/usr/src/packages/BUILD/tests/xua' [ 135s] Makefile:350: recipe for target 'all-recursive' failed [ 135s] make[3]: *** [all-recursive] Error 1 [ 135s] make[3]: Leaving directory '/usr/src/packages/BUILD/tests' [ 135s] Makefile:443: recipe for target 'all-recursive' failed [ 135s] make[2]: *** [all-recursive] Error 1 [ 135s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 135s] Makefile:360: recipe for target 'all' failed [ 135s] make[1]: *** [all] Error 2 [ 135s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 135s] dh_auto_build: make -j1 returned exit code 2 [ 135s] debian/rules:12: recipe for target 'build' failed [ 135s] make: *** [build] Error 2 [ 135s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 135s] [ 135s] build31 failed "build libosmo-sccp_0.7.1.20170418.dsc" at Tue Apr 18 20:07:10 UTC 2017. [ 135s] [ 135s] ### VM INTERACTION START ### [ 136s] Powering off. [ 136s] [ 119.745098] reboot: Power down [ 137s] ### VM INTERACTION END ### [ 137s] [ 137s] build31 failed "build libosmo-sccp_0.7.1.20170418.dsc" at Tue Apr 18 20:07:12 UTC 2017. [ 137s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Tue Apr 18 20:08:43 2017 From: admin at opensuse.org (OBS Notification) Date: Tue, 18 Apr 2017 20:08:43 +0000 Subject: Build failure of network:osmocom:nightly/libosmo-sccp in xUbuntu_16.10/x86_64 In-Reply-To: References: Message-ID: <58f6726fc5e8c_98f1156f8480381@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/libosmo-sccp/xUbuntu_16.10/x86_64 Package network:osmocom:nightly/libosmo-sccp failed to build in xUbuntu_16.10/x86_64 Check out the package for editing: osc checkout network:osmocom:nightly libosmo-sccp Last lines of build log: [ 127s] ./src/xua_asp_fsm.c:772: undefined reference to `ipa_ccm_send_id_req' [ 127s] ../../src/.libs/libosmo-sigtran.a(ipa.o): In function `ipa_tx_xua_as': [ 127s] ./src/ipa.c:71: undefined reference to `ipa_msg_alloc' [ 127s] collect2: error: ld returned 1 exit status [ 127s] Makefile:360: recipe for target 'xua_test' failed [ 127s] make[4]: *** [xua_test] Error 1 [ 127s] make[4]: Leaving directory '/usr/src/packages/BUILD/tests/xua' [ 127s] Makefile:362: recipe for target 'all-recursive' failed [ 127s] make[3]: *** [all-recursive] Error 1 [ 127s] make[3]: Leaving directory '/usr/src/packages/BUILD/tests' [ 127s] Makefile:454: recipe for target 'all-recursive' failed [ 127s] make[2]: *** [all-recursive] Error 1 [ 127s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 127s] Makefile:372: recipe for target 'all' failed [ 127s] make[1]: *** [all] Error 2 [ 127s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 127s] dh_auto_build: make -j1 returned exit code 2 [ 127s] debian/rules:12: recipe for target 'build' failed [ 127s] make: *** [build] Error 2 [ 127s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 127s] [ 127s] lamb67 failed "build libosmo-sccp_0.7.1.20170418.dsc" at Tue Apr 18 20:08:38 UTC 2017. [ 127s] [ 127s] ### VM INTERACTION START ### [ 130s] [ 116.088571] reboot: Power down [ 130s] ### VM INTERACTION END ### [ 130s] [ 130s] lamb67 failed "build libosmo-sccp_0.7.1.20170418.dsc" at Tue Apr 18 20:08:41 UTC 2017. [ 130s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Tue Apr 18 20:08:43 2017 From: admin at opensuse.org (OBS Notification) Date: Tue, 18 Apr 2017 20:08:43 +0000 Subject: Build failure of network:osmocom:nightly/libosmo-sccp in Debian_8.0/x86_64 In-Reply-To: References: Message-ID: <58f672703ccc0_98f1156f84803929@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/libosmo-sccp/Debian_8.0/x86_64 Package network:osmocom:nightly/libosmo-sccp failed to build in Debian_8.0/x86_64 Check out the package for editing: osc checkout network:osmocom:nightly libosmo-sccp Last lines of build log: [ 118s] /usr/bin/ld: ../../src/.libs/libosmo-sigtran.a(osmo_ss7.o): undefined reference to symbol 'ipa_msg_recv_buffered@@LIBOSMOGSM_1.0' [ 118s] //usr/lib/x86_64-linux-gnu/libosmogsm.so.6: error adding symbols: DSO missing from command line [ 118s] collect2: error: ld returned 1 exit status [ 118s] Makefile:348: recipe for target 'xua_test' failed [ 118s] make[4]: *** [xua_test] Error 1 [ 118s] make[4]: Leaving directory '/usr/src/packages/BUILD/tests/xua' [ 118s] Makefile:350: recipe for target 'all-recursive' failed [ 118s] make[3]: *** [all-recursive] Error 1 [ 118s] make[3]: Leaving directory '/usr/src/packages/BUILD/tests' [ 118s] Makefile:443: recipe for target 'all-recursive' failed [ 118s] make[2]: *** [all-recursive] Error 1 [ 118s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 118s] Makefile:360: recipe for target 'all' failed [ 118s] make[1]: *** [all] Error 2 [ 118s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 118s] dh_auto_build: make -j1 returned exit code 2 [ 118s] debian/rules:12: recipe for target 'build' failed [ 118s] make: *** [build] Error 2 [ 118s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 118s] [ 118s] lamb19 failed "build libosmo-sccp_0.7.1.20170418.dsc" at Tue Apr 18 20:08:24 UTC 2017. [ 118s] [ 118s] ### VM INTERACTION START ### [ 119s] Powering off. [ 119s] [ 106.134989] reboot: Power down [ 119s] ### VM INTERACTION END ### [ 119s] [ 119s] lamb19 failed "build libosmo-sccp_0.7.1.20170418.dsc" at Tue Apr 18 20:08:26 UTC 2017. [ 119s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Tue Apr 18 20:09:18 2017 From: admin at opensuse.org (OBS Notification) Date: Tue, 18 Apr 2017 20:09:18 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in xUbuntu_16.10/i586 In-Reply-To: References: Message-ID: <58f67291f1af0_c7610b4f7c71572d@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/xUbuntu_16.10/i586 Package network:osmocom:nightly/osmo-stp failed to build in xUbuntu_16.10/i586 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 80s] #warning "Notify any other AS(P) for failover scenario" [ 80s] ^~~~~~~ [ 80s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o vty_interface.o vty_interface.c [ 81s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o sctp_m3ua_client.o sctp_m3ua_client.c [ 81s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 81s] #include [ 81s] ^ [ 81s] compilation terminated. [ 81s] Makefile:485: recipe for target 'sctp_m3ua_client.o' failed [ 81s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 81s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 81s] Makefile:380: recipe for target 'all-recursive' failed [ 81s] make[2]: *** [all-recursive] Error 1 [ 81s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 81s] Makefile:321: recipe for target 'all' failed [ 81s] make[1]: *** [all] Error 2 [ 81s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 81s] dh_auto_build: make -j1 returned exit code 2 [ 81s] debian/rules:23: recipe for target 'build' failed [ 81s] make: *** [build] Error 2 [ 81s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 81s] [ 81s] lamb13 failed "build cellmgr-ng_1.4.7.20170418.dsc" at Tue Apr 18 20:09:10 UTC 2017. [ 81s] [ 81s] ### VM INTERACTION START ### [ 84s] ### VM INTERACTION END ### [ 84s] [ 84s] lamb13 failed "build cellmgr-ng_1.4.7.20170418.dsc" at Tue Apr 18 20:09:14 UTC 2017. [ 84s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Tue Apr 18 20:11:35 2017 From: admin at opensuse.org (OBS Notification) Date: Tue, 18 Apr 2017 20:11:35 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in Debian_8.0/i586 In-Reply-To: References: Message-ID: <58f6730a60c85_98f1156f8480433e@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/Debian_8.0/i586 Package network:osmocom:nightly/osmo-stp failed to build in Debian_8.0/i586 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 103s] CC vty_interface.o [ 104s] CC sctp_m3ua_client.o [ 104s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 104s] #include [ 104s] ^ [ 104s] compilation terminated. [ 104s] Makefile:475: recipe for target 'sctp_m3ua_client.o' failed [ 104s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 104s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 104s] Makefile:370: recipe for target 'all-recursive' failed [ 104s] make[2]: *** [all-recursive] Error 1 [ 104s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 104s] Makefile:310: recipe for target 'all' failed [ 104s] make[1]: *** [all] Error 2 [ 104s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 104s] dh_auto_build: make -j1 returned exit code 2 [ 104s] debian/rules:23: recipe for target 'build' failed [ 104s] make: *** [build] Error 2 [ 104s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 104s] [ 104s] cumulus3 failed "build cellmgr-ng_1.4.7.20170418.dsc" at Tue Apr 18 20:11:29 UTC 2017. [ 104s] [ 104s] ### VM INTERACTION START ### [ 106s] Powering off. [ 106s] [ 85.699497] reboot: Power down [ 106s] ### VM INTERACTION END ### [ 106s] [ 106s] cumulus3 failed "build cellmgr-ng_1.4.7.20170418.dsc" at Tue Apr 18 20:11:31 UTC 2017. [ 106s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Tue Apr 18 20:12:33 2017 From: admin at opensuse.org (OBS Notification) Date: Tue, 18 Apr 2017 20:12:33 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in xUbuntu_16.10/x86_64 In-Reply-To: References: Message-ID: <58f673413f53f_99c1156f849137e8@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/xUbuntu_16.10/x86_64 Package network:osmocom:nightly/osmo-stp failed to build in xUbuntu_16.10/x86_64 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 75s] ^~~~~~~ [ 75s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o vty_interface.o vty_interface.c [ 76s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o sctp_m3ua_client.o sctp_m3ua_client.c [ 76s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 76s] #include [ 76s] ^ [ 76s] compilation terminated. [ 76s] Makefile:485: recipe for target 'sctp_m3ua_client.o' failed [ 76s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 76s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 76s] Makefile:380: recipe for target 'all-recursive' failed [ 76s] make[2]: *** [all-recursive] Error 1 [ 76s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 76s] Makefile:321: recipe for target 'all' failed [ 76s] make[1]: *** [all] Error 2 [ 76s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 76s] dh_auto_build: make -j1 returned exit code 2 [ 76s] debian/rules:23: recipe for target 'build' failed [ 76s] make: *** [build] Error 2 [ 76s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 76s] [ 76s] lamb19 failed "build cellmgr-ng_1.4.7.20170418.dsc" at Tue Apr 18 20:12:11 UTC 2017. [ 76s] [ 76s] ### VM INTERACTION START ### [ 79s] [ 66.177753] reboot: Power down [ 79s] ### VM INTERACTION END ### [ 79s] [ 79s] lamb19 failed "build cellmgr-ng_1.4.7.20170418.dsc" at Tue Apr 18 20:12:15 UTC 2017. [ 79s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Tue Apr 18 20:12:33 2017 From: admin at opensuse.org (OBS Notification) Date: Tue, 18 Apr 2017 20:12:33 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in Debian_8.0/x86_64 In-Reply-To: References: Message-ID: <58f6736774540_9961156f84850789@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/Debian_8.0/x86_64 Package network:osmocom:nightly/osmo-stp failed to build in Debian_8.0/x86_64 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 102s] ^ [ 103s] CC vty_interface.o [ 103s] CC sctp_m3ua_client.o [ 103s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 103s] #include [ 103s] ^ [ 103s] compilation terminated. [ 104s] Makefile:475: recipe for target 'sctp_m3ua_client.o' failed [ 104s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 104s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 104s] Makefile:370: recipe for target 'all-recursive' failed [ 104s] make[2]: *** [all-recursive] Error 1 [ 104s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 104s] Makefile:310: recipe for target 'all' failed [ 104s] make[1]: *** [all] Error 2 [ 104s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 104s] dh_auto_build: make -j1 returned exit code 2 [ 104s] debian/rules:23: recipe for target 'build' failed [ 104s] make: *** [build] Error 2 [ 104s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 104s] [ 104s] build75 failed "build cellmgr-ng_1.4.7.20170418.dsc" at Tue Apr 18 20:12:29 UTC 2017. [ 104s] [ 104s] ### VM INTERACTION START ### [ 105s] Powering off. [ 105s] ### VM INTERACTION END ### [ 105s] [ 105s] build75 failed "build cellmgr-ng_1.4.7.20170418.dsc" at Tue Apr 18 20:12:31 UTC 2017. [ 105s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Tue Apr 18 20:12:50 2017 From: admin at opensuse.org (OBS Notification) Date: Tue, 18 Apr 2017 20:12:50 +0000 Subject: Build failure of network:osmocom:nightly/libosmo-sccp in xUbuntu_16.04/x86_64 In-Reply-To: References: Message-ID: <58f673804de1b_99c1156f849138e6@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/libosmo-sccp/xUbuntu_16.04/x86_64 Package network:osmocom:nightly/libosmo-sccp failed to build in xUbuntu_16.04/x86_64 Check out the package for editing: osc checkout network:osmocom:nightly libosmo-sccp Last lines of build log: [ 161s] /usr/src/packages/BUILD/src/xua_asp_fsm.c:772: undefined reference to `ipa_ccm_send_id_req' [ 161s] ../../src/.libs/libosmo-sigtran.a(ipa.o): In function `ipa_tx_xua_as': [ 161s] /usr/src/packages/BUILD/src/ipa.c:71: undefined reference to `ipa_msg_alloc' [ 161s] collect2: error: ld returned 1 exit status [ 161s] Makefile:360: recipe for target 'xua_test' failed [ 161s] make[4]: *** [xua_test] Error 1 [ 161s] make[4]: Leaving directory '/usr/src/packages/BUILD/tests/xua' [ 161s] Makefile:362: recipe for target 'all-recursive' failed [ 161s] make[3]: *** [all-recursive] Error 1 [ 161s] make[3]: Leaving directory '/usr/src/packages/BUILD/tests' [ 161s] Makefile:454: recipe for target 'all-recursive' failed [ 161s] make[2]: *** [all-recursive] Error 1 [ 161s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 161s] Makefile:372: recipe for target 'all' failed [ 161s] make[1]: *** [all] Error 2 [ 161s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 161s] dh_auto_build: make -j1 returned exit code 2 [ 161s] debian/rules:12: recipe for target 'build' failed [ 161s] make: *** [build] Error 2 [ 161s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 161s] [ 161s] cloud134 failed "build libosmo-sccp_0.7.1.20170418.dsc" at Tue Apr 18 20:12:28 UTC 2017. [ 161s] [ 161s] ### VM INTERACTION START ### [ 164s] [ 136.633446] reboot: Power down [ 165s] ### VM INTERACTION END ### [ 167s] [ 167s] cloud134 failed "build libosmo-sccp_0.7.1.20170418.dsc" at Tue Apr 18 20:12:34 UTC 2017. [ 167s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Tue Apr 18 20:16:14 2017 From: admin at opensuse.org (OBS Notification) Date: Tue, 18 Apr 2017 20:16:14 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in xUbuntu_16.04/x86_64 In-Reply-To: References: Message-ID: <58f67439c82d4_99c1156f849139d@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/xUbuntu_16.04/x86_64 Package network:osmocom:nightly/osmo-stp failed to build in xUbuntu_16.04/x86_64 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 119s] sctp_m2ua.c:91:3: warning: #warning "Notify any other AS(P) for failover scenario" [-Wcpp] [ 119s] #warning "Notify any other AS(P) for failover scenario" [ 119s] ^ [ 119s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -c -o vty_interface.o vty_interface.c [ 120s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -c -o sctp_m3ua_client.o sctp_m3ua_client.c [ 120s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 120s] compilation terminated. [ 120s] Makefile:485: recipe for target 'sctp_m3ua_client.o' failed [ 120s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 120s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 120s] Makefile:380: recipe for target 'all-recursive' failed [ 120s] make[2]: *** [all-recursive] Error 1 [ 120s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 120s] Makefile:321: recipe for target 'all' failed [ 120s] make[1]: *** [all] Error 2 [ 120s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 120s] dh_auto_build: make -j1 returned exit code 2 [ 120s] debian/rules:23: recipe for target 'build' failed [ 120s] make: *** [build] Error 2 [ 120s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 120s] [ 120s] lamb25 failed "build cellmgr-ng_1.4.7.20170418.dsc" at Tue Apr 18 20:15:58 UTC 2017. [ 120s] [ 120s] ### VM INTERACTION START ### [ 123s] [ 109.880886] reboot: Power down [ 123s] ### VM INTERACTION END ### [ 123s] [ 123s] lamb25 failed "build cellmgr-ng_1.4.7.20170418.dsc" at Tue Apr 18 20:16:01 UTC 2017. [ 123s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From gerrit-no-reply at lists.osmocom.org Wed Apr 19 08:39:08 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Wed, 19 Apr 2017 08:39:08 +0000 Subject: osmo-gsm-manuals[master]: First step towards an OsmoSTP manual In-Reply-To: References: Message-ID: Patch Set 4: - ?4.7 newtworks - ?4.7.2 netwokr - ?4.7.2 only explains what problem is and options are, but says nothing about which options are chosen and how the problem actually solved. - ?4.8.* describe minimal config in words, would be nice to see actual config snippets or at least reference to those to make it more clear. - ?4.9 uses cs7 in vty prompts which is not explained before, it's also unclear how it refers to other ? - do we have to configure it for minimal setup? Having cross references between different ? would have helped. - ?4.10-4.14 - would be helpful if the relation between those (and their place in BSC for example) could be illustrated by a picture - textual description might be confusing at first. - Table 4 - 7 would look better if the would follow format of Table 3 (with corresponding vty commands) - ?4.18 mention "well-known SSN" but does not provide any reference to where it's well-known from - rfc? config file? smth else? -- To view, visit https://gerrit.osmocom.org/2371 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I450bfac7444ac9cb7f50c086d87cf7157c2e2a31 Gerrit-PatchSet: 4 Gerrit-Project: osmo-gsm-manuals Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-HasComments: No From admin at opensuse.org Wed Apr 19 19:58:21 2017 From: admin at opensuse.org (OBS Notification) Date: Wed, 19 Apr 2017 19:58:21 +0000 Subject: Build failure of network:osmocom:nightly/libosmo-sccp in xUbuntu_16.10/x86_64 In-Reply-To: References: Message-ID: <58f7c18d60bdc_99c1156f8498014c@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/libosmo-sccp/xUbuntu_16.10/x86_64 Package network:osmocom:nightly/libosmo-sccp failed to build in xUbuntu_16.10/x86_64 Check out the package for editing: osc checkout network:osmocom:nightly libosmo-sccp Last lines of build log: [ 98s] ./src/xua_asp_fsm.c:772: undefined reference to `ipa_ccm_send_id_req' [ 98s] ../../src/.libs/libosmo-sigtran.a(ipa.o): In function `ipa_tx_xua_as': [ 98s] ./src/ipa.c:71: undefined reference to `ipa_msg_alloc' [ 98s] collect2: error: ld returned 1 exit status [ 98s] Makefile:360: recipe for target 'xua_test' failed [ 98s] make[4]: *** [xua_test] Error 1 [ 98s] make[4]: Leaving directory '/usr/src/packages/BUILD/tests/xua' [ 98s] Makefile:362: recipe for target 'all-recursive' failed [ 98s] make[3]: *** [all-recursive] Error 1 [ 98s] make[3]: Leaving directory '/usr/src/packages/BUILD/tests' [ 98s] Makefile:454: recipe for target 'all-recursive' failed [ 98s] make[2]: *** [all-recursive] Error 1 [ 98s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 98s] Makefile:372: recipe for target 'all' failed [ 98s] make[1]: *** [all] Error 2 [ 98s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 98s] dh_auto_build: make -j1 returned exit code 2 [ 98s] debian/rules:12: recipe for target 'build' failed [ 98s] make: *** [build] Error 2 [ 98s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 98s] [ 98s] lamb07 failed "build libosmo-sccp_0.7.1.20170419.dsc" at Wed Apr 19 19:58:09 UTC 2017. [ 98s] [ 98s] ### VM INTERACTION START ### [ 101s] [ 87.008728] reboot: Power down [ 101s] ### VM INTERACTION END ### [ 101s] [ 101s] lamb07 failed "build libosmo-sccp_0.7.1.20170419.dsc" at Wed Apr 19 19:58:13 UTC 2017. [ 101s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Wed Apr 19 19:58:39 2017 From: admin at opensuse.org (OBS Notification) Date: Wed, 19 Apr 2017 19:58:39 +0000 Subject: Build failure of network:osmocom:nightly/libosmo-sccp in Debian_8.0/i586 In-Reply-To: References: Message-ID: <58f7c19075ded_99c1156f8498053e@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/libosmo-sccp/Debian_8.0/i586 Package network:osmocom:nightly/libosmo-sccp failed to build in Debian_8.0/i586 Check out the package for editing: osc checkout network:osmocom:nightly libosmo-sccp Last lines of build log: [ 101s] /usr/bin/ld: ../../src/.libs/libosmo-sigtran.a(osmo_ss7.o): undefined reference to symbol 'ipa_msg_recv_buffered@@LIBOSMOGSM_1.0' [ 101s] //usr/lib/i386-linux-gnu/libosmogsm.so.6: error adding symbols: DSO missing from command line [ 101s] collect2: error: ld returned 1 exit status [ 101s] Makefile:348: recipe for target 'xua_test' failed [ 101s] make[4]: *** [xua_test] Error 1 [ 101s] make[4]: Leaving directory '/usr/src/packages/BUILD/tests/xua' [ 101s] Makefile:350: recipe for target 'all-recursive' failed [ 101s] make[3]: *** [all-recursive] Error 1 [ 101s] make[3]: Leaving directory '/usr/src/packages/BUILD/tests' [ 101s] Makefile:443: recipe for target 'all-recursive' failed [ 101s] make[2]: *** [all-recursive] Error 1 [ 101s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 101s] Makefile:360: recipe for target 'all' failed [ 101s] make[1]: *** [all] Error 2 [ 101s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 101s] dh_auto_build: make -j1 returned exit code 2 [ 101s] debian/rules:12: recipe for target 'build' failed [ 101s] make: *** [build] Error 2 [ 101s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 101s] [ 101s] lamb51 failed "build libosmo-sccp_0.7.1.20170419.dsc" at Wed Apr 19 19:58:36 UTC 2017. [ 101s] [ 101s] ### VM INTERACTION START ### [ 102s] Powering off. [ 102s] [ 88.397925] reboot: Power down [ 102s] ### VM INTERACTION END ### [ 102s] [ 102s] lamb51 failed "build libosmo-sccp_0.7.1.20170419.dsc" at Wed Apr 19 19:58:37 UTC 2017. [ 102s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Wed Apr 19 20:00:04 2017 From: admin at opensuse.org (OBS Notification) Date: Wed, 19 Apr 2017 20:00:04 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in xUbuntu_16.10/x86_64 In-Reply-To: References: Message-ID: <58f7c1ea18489_98f1156f8487832d@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/xUbuntu_16.10/x86_64 Package network:osmocom:nightly/osmo-stp failed to build in xUbuntu_16.10/x86_64 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 75s] ^~~~~~~ [ 75s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o vty_interface.o vty_interface.c [ 76s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o sctp_m3ua_client.o sctp_m3ua_client.c [ 76s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 76s] #include [ 76s] ^ [ 76s] compilation terminated. [ 76s] Makefile:485: recipe for target 'sctp_m3ua_client.o' failed [ 76s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 76s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 76s] Makefile:380: recipe for target 'all-recursive' failed [ 76s] make[2]: *** [all-recursive] Error 1 [ 76s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 76s] Makefile:321: recipe for target 'all' failed [ 76s] make[1]: *** [all] Error 2 [ 76s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 76s] dh_auto_build: make -j1 returned exit code 2 [ 76s] debian/rules:23: recipe for target 'build' failed [ 76s] make: *** [build] Error 2 [ 76s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 76s] [ 76s] lamb13 failed "build cellmgr-ng_1.4.7.20170419.dsc" at Wed Apr 19 19:59:43 UTC 2017. [ 76s] [ 76s] ### VM INTERACTION START ### [ 79s] [ 66.053140] reboot: Power down [ 79s] ### VM INTERACTION END ### [ 79s] [ 79s] lamb13 failed "build cellmgr-ng_1.4.7.20170419.dsc" at Wed Apr 19 19:59:47 UTC 2017. [ 79s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Wed Apr 19 20:00:04 2017 From: admin at opensuse.org (OBS Notification) Date: Wed, 19 Apr 2017 20:00:04 +0000 Subject: Build failure of network:osmocom:nightly/libosmo-sccp in xUbuntu_16.04/i586 In-Reply-To: References: Message-ID: <58f7c1ea90e63_98f1156f84878414@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/libosmo-sccp/xUbuntu_16.04/i586 Package network:osmocom:nightly/libosmo-sccp failed to build in xUbuntu_16.04/i586 Check out the package for editing: osc checkout network:osmocom:nightly libosmo-sccp Last lines of build log: [ 118s] /usr/src/packages/BUILD/src/xua_asp_fsm.c:772: undefined reference to `ipa_ccm_send_id_req' [ 118s] ../../src/.libs/libosmo-sigtran.a(ipa.o): In function `ipa_tx_xua_as': [ 118s] /usr/src/packages/BUILD/src/ipa.c:71: undefined reference to `ipa_msg_alloc' [ 118s] collect2: error: ld returned 1 exit status [ 118s] Makefile:360: recipe for target 'xua_test' failed [ 118s] make[4]: *** [xua_test] Error 1 [ 118s] make[4]: Leaving directory '/usr/src/packages/BUILD/tests/xua' [ 118s] Makefile:362: recipe for target 'all-recursive' failed [ 118s] make[3]: *** [all-recursive] Error 1 [ 118s] make[3]: Leaving directory '/usr/src/packages/BUILD/tests' [ 118s] Makefile:454: recipe for target 'all-recursive' failed [ 118s] make[2]: *** [all-recursive] Error 1 [ 118s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 118s] Makefile:372: recipe for target 'all' failed [ 118s] make[1]: *** [all] Error 2 [ 118s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 118s] dh_auto_build: make -j1 returned exit code 2 [ 118s] debian/rules:12: recipe for target 'build' failed [ 118s] make: *** [build] Error 2 [ 118s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 118s] [ 118s] lamb23 failed "build libosmo-sccp_0.7.1.20170419.dsc" at Wed Apr 19 19:59:48 UTC 2017. [ 118s] [ 118s] ### VM INTERACTION START ### [ 121s] [ 108.524538] reboot: Power down [ 121s] ### VM INTERACTION END ### [ 121s] [ 121s] lamb23 failed "build libosmo-sccp_0.7.1.20170419.dsc" at Wed Apr 19 19:59:51 UTC 2017. [ 121s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Wed Apr 19 20:00:21 2017 From: admin at opensuse.org (OBS Notification) Date: Wed, 19 Apr 2017 20:00:21 +0000 Subject: Build failure of network:osmocom:nightly/libosmo-sccp in xUbuntu_16.10/i586 In-Reply-To: References: Message-ID: <58f7c206539bc_98f1156f8487861d@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/libosmo-sccp/xUbuntu_16.10/i586 Package network:osmocom:nightly/libosmo-sccp failed to build in xUbuntu_16.10/i586 Check out the package for editing: osc checkout network:osmocom:nightly libosmo-sccp Last lines of build log: [ 130s] ./src/xua_asp_fsm.c:772: undefined reference to `ipa_ccm_send_id_req' [ 130s] ../../src/.libs/libosmo-sigtran.a(ipa.o): In function `ipa_tx_xua_as': [ 130s] ./src/ipa.c:71: undefined reference to `ipa_msg_alloc' [ 130s] collect2: error: ld returned 1 exit status [ 130s] Makefile:360: recipe for target 'xua_test' failed [ 130s] make[4]: *** [xua_test] Error 1 [ 130s] make[4]: Leaving directory '/usr/src/packages/BUILD/tests/xua' [ 130s] Makefile:362: recipe for target 'all-recursive' failed [ 130s] make[3]: *** [all-recursive] Error 1 [ 130s] make[3]: Leaving directory '/usr/src/packages/BUILD/tests' [ 130s] Makefile:454: recipe for target 'all-recursive' failed [ 130s] make[2]: *** [all-recursive] Error 1 [ 130s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 130s] Makefile:372: recipe for target 'all' failed [ 130s] make[1]: *** [all] Error 2 [ 130s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 130s] dh_auto_build: make -j1 returned exit code 2 [ 130s] debian/rules:12: recipe for target 'build' failed [ 130s] make: *** [build] Error 2 [ 130s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 130s] [ 130s] cloud129 failed "build libosmo-sccp_0.7.1.20170419.dsc" at Wed Apr 19 20:00:10 UTC 2017. [ 130s] [ 130s] ### VM INTERACTION START ### [ 133s] [ 110.271902] reboot: Power down [ 134s] ### VM INTERACTION END ### [ 134s] [ 134s] cloud129 failed "build libosmo-sccp_0.7.1.20170419.dsc" at Wed Apr 19 20:00:14 UTC 2017. [ 134s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Wed Apr 19 20:00:39 2017 From: admin at opensuse.org (OBS Notification) Date: Wed, 19 Apr 2017 20:00:39 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in Debian_8.0/i586 In-Reply-To: References: Message-ID: <58f7c207708da_98f1156f848788b9@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/Debian_8.0/i586 Package network:osmocom:nightly/osmo-stp failed to build in Debian_8.0/i586 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 88s] CC vty_interface.o [ 89s] CC sctp_m3ua_client.o [ 89s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 89s] #include [ 89s] ^ [ 89s] compilation terminated. [ 89s] Makefile:475: recipe for target 'sctp_m3ua_client.o' failed [ 89s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 89s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 89s] Makefile:370: recipe for target 'all-recursive' failed [ 89s] make[2]: *** [all-recursive] Error 1 [ 89s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 89s] Makefile:310: recipe for target 'all' failed [ 89s] make[1]: *** [all] Error 2 [ 89s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 89s] dh_auto_build: make -j1 returned exit code 2 [ 89s] debian/rules:23: recipe for target 'build' failed [ 89s] make: *** [build] Error 2 [ 89s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 89s] [ 89s] lamb51 failed "build cellmgr-ng_1.4.7.20170419.dsc" at Wed Apr 19 20:00:21 UTC 2017. [ 89s] [ 89s] ### VM INTERACTION START ### [ 90s] Powering off. [ 90s] [ 76.872410] reboot: Power down [ 90s] ### VM INTERACTION END ### [ 90s] [ 90s] lamb51 failed "build cellmgr-ng_1.4.7.20170419.dsc" at Wed Apr 19 20:00:23 UTC 2017. [ 90s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Wed Apr 19 20:00:56 2017 From: admin at opensuse.org (OBS Notification) Date: Wed, 19 Apr 2017 20:00:56 +0000 Subject: Build failure of network:osmocom:nightly/libosmo-sccp in Debian_8.0/x86_64 In-Reply-To: References: Message-ID: <58f7c2093c67f_98f1156f8487919d@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/libosmo-sccp/Debian_8.0/x86_64 Package network:osmocom:nightly/libosmo-sccp failed to build in Debian_8.0/x86_64 Check out the package for editing: osc checkout network:osmocom:nightly libosmo-sccp Last lines of build log: [ 135s] /usr/bin/ld: ../../src/.libs/libosmo-sigtran.a(osmo_ss7.o): undefined reference to symbol 'ipa_msg_recv_buffered@@LIBOSMOGSM_1.0' [ 135s] //usr/lib/x86_64-linux-gnu/libosmogsm.so.6: error adding symbols: DSO missing from command line [ 135s] collect2: error: ld returned 1 exit status [ 135s] Makefile:348: recipe for target 'xua_test' failed [ 135s] make[4]: *** [xua_test] Error 1 [ 135s] make[4]: Leaving directory '/usr/src/packages/BUILD/tests/xua' [ 135s] Makefile:350: recipe for target 'all-recursive' failed [ 135s] make[3]: *** [all-recursive] Error 1 [ 135s] make[3]: Leaving directory '/usr/src/packages/BUILD/tests' [ 135s] Makefile:443: recipe for target 'all-recursive' failed [ 135s] make[2]: *** [all-recursive] Error 1 [ 135s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 135s] Makefile:360: recipe for target 'all' failed [ 135s] make[1]: *** [all] Error 2 [ 135s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 135s] dh_auto_build: make -j1 returned exit code 2 [ 135s] debian/rules:12: recipe for target 'build' failed [ 135s] make: *** [build] Error 2 [ 135s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 135s] [ 135s] cloud120 failed "build libosmo-sccp_0.7.1.20170419.dsc" at Wed Apr 19 20:00:42 UTC 2017. [ 135s] [ 135s] ### VM INTERACTION START ### [ 137s] Powering off. [ 137s] [ 109.343607] reboot: Power down [ 138s] ### VM INTERACTION END ### [ 138s] [ 138s] cloud120 failed "build libosmo-sccp_0.7.1.20170419.dsc" at Wed Apr 19 20:00:45 UTC 2017. [ 138s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Wed Apr 19 20:01:13 2017 From: admin at opensuse.org (OBS Notification) Date: Wed, 19 Apr 2017 20:01:13 +0000 Subject: Build failure of network:osmocom:nightly/libosmo-sccp in xUbuntu_16.04/x86_64 In-Reply-To: References: Message-ID: <58f7c225bd6d4_c7610b4f7c7638e@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/libosmo-sccp/xUbuntu_16.04/x86_64 Package network:osmocom:nightly/libosmo-sccp failed to build in xUbuntu_16.04/x86_64 Check out the package for editing: osc checkout network:osmocom:nightly libosmo-sccp Last lines of build log: [ 118s] /usr/src/packages/BUILD/src/xua_asp_fsm.c:772: undefined reference to `ipa_ccm_send_id_req' [ 118s] ../../src/.libs/libosmo-sigtran.a(ipa.o): In function `ipa_tx_xua_as': [ 118s] /usr/src/packages/BUILD/src/ipa.c:71: undefined reference to `ipa_msg_alloc' [ 118s] collect2: error: ld returned 1 exit status [ 118s] Makefile:360: recipe for target 'xua_test' failed [ 118s] make[4]: *** [xua_test] Error 1 [ 118s] make[4]: Leaving directory '/usr/src/packages/BUILD/tests/xua' [ 118s] Makefile:362: recipe for target 'all-recursive' failed [ 118s] make[3]: *** [all-recursive] Error 1 [ 118s] make[3]: Leaving directory '/usr/src/packages/BUILD/tests' [ 118s] Makefile:454: recipe for target 'all-recursive' failed [ 118s] make[2]: *** [all-recursive] Error 1 [ 118s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 118s] Makefile:372: recipe for target 'all' failed [ 118s] make[1]: *** [all] Error 2 [ 118s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 118s] dh_auto_build: make -j1 returned exit code 2 [ 118s] debian/rules:12: recipe for target 'build' failed [ 118s] make: *** [build] Error 2 [ 118s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 118s] [ 118s] lamb17 failed "build libosmo-sccp_0.7.1.20170419.dsc" at Wed Apr 19 20:00:59 UTC 2017. [ 118s] [ 118s] ### VM INTERACTION START ### [ 121s] [ 107.747604] reboot: Power down [ 121s] ### VM INTERACTION END ### [ 121s] [ 121s] lamb17 failed "build libosmo-sccp_0.7.1.20170419.dsc" at Wed Apr 19 20:01:02 UTC 2017. [ 121s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Wed Apr 19 20:02:39 2017 From: admin at opensuse.org (OBS Notification) Date: Wed, 19 Apr 2017 20:02:39 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in Debian_8.0/x86_64 In-Reply-To: References: Message-ID: <58f7c28248212_c7610b4f7c76392c@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/Debian_8.0/x86_64 Package network:osmocom:nightly/osmo-stp failed to build in Debian_8.0/x86_64 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 89s] CC vty_interface.o [ 89s] CC sctp_m3ua_client.o [ 89s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 89s] #include [ 89s] ^ [ 89s] compilation terminated. [ 89s] Makefile:475: recipe for target 'sctp_m3ua_client.o' failed [ 89s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 89s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 89s] Makefile:370: recipe for target 'all-recursive' failed [ 89s] make[2]: *** [all-recursive] Error 1 [ 89s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 89s] Makefile:310: recipe for target 'all' failed [ 89s] make[1]: *** [all] Error 2 [ 89s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 89s] dh_auto_build: make -j1 returned exit code 2 [ 89s] debian/rules:23: recipe for target 'build' failed [ 89s] make: *** [build] Error 2 [ 89s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 89s] [ 89s] lamb10 failed "build cellmgr-ng_1.4.7.20170419.dsc" at Wed Apr 19 20:02:26 UTC 2017. [ 89s] [ 89s] ### VM INTERACTION START ### [ 90s] Powering off. [ 90s] [ 76.387701] reboot: Power down [ 90s] ### VM INTERACTION END ### [ 90s] [ 90s] lamb10 failed "build cellmgr-ng_1.4.7.20170419.dsc" at Wed Apr 19 20:02:27 UTC 2017. [ 90s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Wed Apr 19 20:02:39 2017 From: admin at opensuse.org (OBS Notification) Date: Wed, 19 Apr 2017 20:02:39 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in xUbuntu_16.04/i586 In-Reply-To: References: Message-ID: <58f7c283be98a_c7610b4f7c7640c6@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/xUbuntu_16.04/i586 Package network:osmocom:nightly/osmo-stp failed to build in xUbuntu_16.04/i586 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 125s] sctp_m2ua.c:91:3: warning: #warning "Notify any other AS(P) for failover scenario" [-Wcpp] [ 125s] #warning "Notify any other AS(P) for failover scenario" [ 125s] ^ [ 125s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -c -o vty_interface.o vty_interface.c [ 126s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -c -o sctp_m3ua_client.o sctp_m3ua_client.c [ 126s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 126s] compilation terminated. [ 126s] Makefile:485: recipe for target 'sctp_m3ua_client.o' failed [ 126s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 126s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 126s] Makefile:380: recipe for target 'all-recursive' failed [ 126s] make[2]: *** [all-recursive] Error 1 [ 126s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 126s] Makefile:321: recipe for target 'all' failed [ 126s] make[1]: *** [all] Error 2 [ 126s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 126s] dh_auto_build: make -j1 returned exit code 2 [ 126s] debian/rules:23: recipe for target 'build' failed [ 126s] make: *** [build] Error 2 [ 126s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 126s] [ 126s] cloud119 failed "build cellmgr-ng_1.4.7.20170419.dsc" at Wed Apr 19 20:02:21 UTC 2017. [ 126s] [ 126s] ### VM INTERACTION START ### [ 129s] [ 107.599964] reboot: Power down [ 130s] ### VM INTERACTION END ### [ 130s] [ 130s] cloud119 failed "build cellmgr-ng_1.4.7.20170419.dsc" at Wed Apr 19 20:02:25 UTC 2017. [ 130s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Wed Apr 19 20:02:56 2017 From: admin at opensuse.org (OBS Notification) Date: Wed, 19 Apr 2017 20:02:56 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in xUbuntu_16.04/x86_64 In-Reply-To: References: Message-ID: <58f7c29d5ef56_99c1156f849807db@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/xUbuntu_16.04/x86_64 Package network:osmocom:nightly/osmo-stp failed to build in xUbuntu_16.04/x86_64 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 56s] sctp_m2ua.c:91:3: warning: #warning "Notify any other AS(P) for failover scenario" [-Wcpp] [ 56s] #warning "Notify any other AS(P) for failover scenario" [ 56s] ^ [ 56s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -c -o vty_interface.o vty_interface.c [ 57s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -c -o sctp_m3ua_client.o sctp_m3ua_client.c [ 57s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 57s] compilation terminated. [ 57s] Makefile:485: recipe for target 'sctp_m3ua_client.o' failed [ 57s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 57s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 57s] Makefile:380: recipe for target 'all-recursive' failed [ 57s] make[2]: *** [all-recursive] Error 1 [ 57s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 57s] Makefile:321: recipe for target 'all' failed [ 57s] make[1]: *** [all] Error 2 [ 57s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 57s] dh_auto_build: make -j1 returned exit code 2 [ 57s] debian/rules:23: recipe for target 'build' failed [ 57s] make: *** [build] Error 2 [ 57s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 57s] [ 57s] build72 failed "build cellmgr-ng_1.4.7.20170419.dsc" at Wed Apr 19 20:02:39 UTC 2017. [ 57s] [ 57s] ### VM INTERACTION START ### [ 60s] [ 51.784155] reboot: Power down [ 60s] ### VM INTERACTION END ### [ 60s] [ 60s] build72 failed "build cellmgr-ng_1.4.7.20170419.dsc" at Wed Apr 19 20:02:43 UTC 2017. [ 60s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Wed Apr 19 20:02:56 2017 From: admin at opensuse.org (OBS Notification) Date: Wed, 19 Apr 2017 20:02:56 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in xUbuntu_16.10/i586 In-Reply-To: References: Message-ID: <58f7c29e3602d_99c1156f849808ad@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/xUbuntu_16.10/i586 Package network:osmocom:nightly/osmo-stp failed to build in xUbuntu_16.10/i586 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 102s] ^~~~~~~ [ 103s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o vty_interface.o vty_interface.c [ 104s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o sctp_m3ua_client.o sctp_m3ua_client.c [ 104s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 104s] #include [ 104s] ^ [ 104s] compilation terminated. [ 104s] Makefile:485: recipe for target 'sctp_m3ua_client.o' failed [ 104s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 104s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 104s] Makefile:380: recipe for target 'all-recursive' failed [ 104s] make[2]: *** [all-recursive] Error 1 [ 104s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 104s] Makefile:321: recipe for target 'all' failed [ 104s] make[1]: *** [all] Error 2 [ 104s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 104s] dh_auto_build: make -j1 returned exit code 2 [ 104s] debian/rules:23: recipe for target 'build' failed [ 104s] make: *** [build] Error 2 [ 104s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 104s] [ 104s] cloud118 failed "build cellmgr-ng_1.4.7.20170419.dsc" at Wed Apr 19 20:02:37 UTC 2017. [ 104s] [ 104s] ### VM INTERACTION START ### [ 107s] [ 85.450584] reboot: Power down [ 113s] ### VM INTERACTION END ### [ 113s] [ 113s] cloud118 failed "build cellmgr-ng_1.4.7.20170419.dsc" at Wed Apr 19 20:02:46 UTC 2017. [ 113s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From gerrit-no-reply at lists.osmocom.org Thu Apr 20 10:16:43 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Thu, 20 Apr 2017 10:16:43 +0000 Subject: libosmocore[master]: control_if: Add helper function for 'local execution' of con... In-Reply-To: References: Message-ID: Patch Set 2: (2 comments) https://gerrit.osmocom.org/#/c/2376/2/src/ctrl/control_if.c File src/ctrl/control_if.c: Line 817: * talloc_freee() the return value. typo https://gerrit.osmocom.org/#/c/2376/2/tests/fsm/fsm_test.c File tests/fsm/fsm_test.c: Line 12: that seems odd - only header is added but no functions from it are used? -- To view, visit https://gerrit.osmocom.org/2376 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Iaca748e0d942bb2a1ee7c2776b37485e1439eb0c Gerrit-PatchSet: 2 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Thu Apr 20 13:14:34 2017 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Thu, 20 Apr 2017 13:14:34 +0000 Subject: [PATCH] osmo-bts[master]: bts: revert trx shutdown order In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/1977 to look at the new patch set (#6). bts: revert trx shutdown order When a new TRX is allocated using gsm_bts_trx_alloc() (see gsm_data_shared.c in openbsc.git), than it is added to the list in order. When octphy is shutting down the BTS, it uses llist_for_each_entry() to iterate the tansceiver list to shut all transceivers down. This means it starts the shut down process with the primary TRX and then continues with the secondary transceivers in order. However, octphy does not allow to close primary TRX if the secondary TRX is open. The shutdown sequence must begin with the secondary transceivers and finish with the primiary transceiver as last item. The problem can be easily fixed by iterating the transceiver list in reverse order using llist_for_each_entry_reverse() instead of llist_for_each_entry() Since this is a change in the common code, all BTS models (not only octphy) are affected, but from the logical perspective, this change makes sense for all other BTS models too. Change-Id: I18485de586b402610f9e98053d69e92bc9b18dc2 --- M src/common/bts.c 1 file changed, 1 insertion(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/77/1977/6 diff --git a/src/common/bts.c b/src/common/bts.c index 540caaa..cb5284d 100644 --- a/src/common/bts.c +++ b/src/common/bts.c @@ -207,7 +207,7 @@ LOGP(DOML, LOGL_NOTICE, "Shutting down BTS %u, Reason %s\n", bts->nr, reason); - llist_for_each_entry(trx, &bts->trx_list, list) { + llist_for_each_entry_reverse(trx, &bts->trx_list, list) { bts_model_trx_deact_rf(trx); bts_model_trx_close(trx); } -- To view, visit https://gerrit.osmocom.org/1977 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I18485de586b402610f9e98053d69e92bc9b18dc2 Gerrit-PatchSet: 6 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Thu Apr 20 13:14:34 2017 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Thu, 20 Apr 2017 13:14:34 +0000 Subject: [PATCH] osmo-bts[master]: octphy: activate CBCH after all physical channels are activated In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2314 to look at the new patch set (#4). octphy: activate CBCH after all physical channels are activated CBCH is activated when the SAPI for TS0 is activated. Since the CBCH can be configured on any physical TS, we wait until all (TS7 is the last) physical timeslots are configured. Change-Id: Ie307bf9f370a346686e3bd8c8a8483953a1bc279 --- M src/osmo-bts-octphy/l1_oml.c 1 file changed, 1 insertion(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/14/2314/4 diff --git a/src/osmo-bts-octphy/l1_oml.c b/src/osmo-bts-octphy/l1_oml.c index 21ff907..4652e10 100644 --- a/src/osmo-bts-octphy/l1_oml.c +++ b/src/osmo-bts-octphy/l1_oml.c @@ -187,7 +187,7 @@ /* hack to auto-activate all SAPIs for the BCCH/CCCH on TS0 */ if (mo->obj_class == NM_OC_CHANNEL && mo->obj_inst.trx_nr == 0 && - mo->obj_inst.ts_nr == 0) { + mo->obj_inst.ts_nr == 7) { struct gsm_lchan *cbch = gsm_bts_get_cbch(mo->bts); mo->bts->c0->ts[0].lchan[CCCH_LCHAN].rel_act_kind = LCHAN_REL_ACT_OML; -- To view, visit https://gerrit.osmocom.org/2314 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ie307bf9f370a346686e3bd8c8a8483953a1bc279 Gerrit-PatchSet: 4 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Thu Apr 20 13:14:34 2017 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Thu, 20 Apr 2017 13:14:34 +0000 Subject: [PATCH] osmo-bts[master]: octphy: remove old event control code In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/1980 to look at the new patch set (#7). octphy: remove old event control code Event handling is done internally in the Octasic BTS. When the TRX is opened, events are enabled automatically and when TRX is closed events are disabled. The change is valid for the recent firmware version and for the last couple of previous releases. Change-Id: I0652627495f6a9bcb0da2431b8beb839bc22062b --- M src/osmo-bts-octphy/l1_oml.c 1 file changed, 1 insertion(+), 83 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/80/1980/7 diff --git a/src/osmo-bts-octphy/l1_oml.c b/src/osmo-bts-octphy/l1_oml.c index c70b45f..21ff907 100644 --- a/src/osmo-bts-octphy/l1_oml.c +++ b/src/osmo-bts-octphy/l1_oml.c @@ -1089,84 +1089,6 @@ return 0; } -static int enable_events_compl_cb(struct octphy_hdl *fl1, struct msgb *resp, void *data) -{ - tOCTVC1_MAIN_MSG_API_SYSTEM_MODIFY_SESSION_EVT_RSP *mser = - (tOCTVC1_MAIN_MSG_API_SYSTEM_MODIFY_SESSION_EVT_RSP *) resp->l2h; - - /* in a completion call-back, we take msgb ownership and must - * release it before returning */ - - mOCTVC1_MAIN_MSG_API_SYSTEM_MODIFY_SESSION_EVT_RSP_SWAP(mser); - - LOGP(DL1C, LOGL_INFO, "Rx ENABLE-EVT-REC.resp\n"); - - msgb_free(resp); - - return 0; -} - -static int disable_events_compl_cb(struct octphy_hdl *fl1, struct msgb *resp, void *data) -{ - tOCTVC1_MAIN_MSG_API_SYSTEM_MODIFY_SESSION_EVT_RSP *mser = - (tOCTVC1_MAIN_MSG_API_SYSTEM_MODIFY_SESSION_EVT_RSP *) resp->l2h; - - /* in a completion call-back, we take msgb ownership and must - * release it before returning */ - - mOCTVC1_MAIN_MSG_API_SYSTEM_MODIFY_SESSION_EVT_RSP_SWAP(mser); - - LOGP(DL1C, LOGL_INFO, "Rx DISABLE-EVT-REC.resp\n"); - - msgb_free(resp); - - return 0; -} - -int l1if_enable_events(struct gsm_bts_trx *trx) -{ - struct phy_instance *pinst = trx_phy_instance(trx); - struct octphy_hdl *fl1h = pinst->phy_link->u.octphy.hdl; - struct msgb *msg = l1p_msgb_alloc(); - tOCTVC1_MAIN_MSG_API_SYSTEM_MODIFY_SESSION_EVT_CMD *mse; - - mse = (tOCTVC1_MAIN_MSG_API_SYSTEM_MODIFY_SESSION_EVT_CMD *) - msgb_put(msg, sizeof(*mse)); - mOCTVC1_MAIN_MSG_API_SYSTEM_MODIFY_SESSION_EVT_CMD_DEF(mse); - - l1if_fill_msg_hdr(&mse->Header, msg, fl1h, cOCTVC1_MSG_TYPE_COMMAND, - cOCTVC1_MAIN_MSG_API_SYSTEM_MODIFY_SESSION_EVT_CID); - mse->ulEvtActiveFlag = cOCT_TRUE; - - mOCTVC1_MAIN_MSG_API_SYSTEM_MODIFY_SESSION_EVT_CMD_SWAP(mse); - - LOGP(DL1C, LOGL_INFO, "Tx ENABLE-EVT-REC.req\n"); - - return l1if_req_compl(fl1h, msg, disable_events_compl_cb, 0); -} - -int l1if_disable_events(struct gsm_bts_trx *trx) -{ - struct phy_instance *pinst = trx_phy_instance(trx); - struct octphy_hdl *fl1h = pinst->phy_link->u.octphy.hdl; - struct msgb *msg = l1p_msgb_alloc(); - tOCTVC1_MAIN_MSG_API_SYSTEM_MODIFY_SESSION_EVT_CMD *mse; - - mse = (tOCTVC1_MAIN_MSG_API_SYSTEM_MODIFY_SESSION_EVT_CMD *) - msgb_put(msg, sizeof(*mse)); - mOCTVC1_MAIN_MSG_API_SYSTEM_MODIFY_SESSION_EVT_CMD_DEF(mse); - - l1if_fill_msg_hdr(&mse->Header, msg, fl1h, cOCTVC1_MSG_TYPE_COMMAND, - cOCTVC1_MAIN_MSG_API_SYSTEM_MODIFY_SESSION_EVT_CID); - mse->ulEvtActiveFlag = cOCT_FALSE; - - mOCTVC1_MAIN_MSG_API_SYSTEM_MODIFY_SESSION_EVT_CMD_SWAP(mse); - - LOGP(DL1C, LOGL_INFO, "Tx DISABLE-EVT-REC.req\n"); - - return l1if_req_compl(fl1h, msg, disable_events_compl_cb, 0); -} - #define talloc_replace(dst, ctx, src) \ do { \ if (dst) \ @@ -1353,8 +1275,7 @@ octphy_hw_get_clock_sync_info(fl1h); fl1h->opened = 1; - /* Temporary fix for enabling events after TRX Close + Reopen */ - return l1if_enable_events(trx); + return 0; } int l1if_trx_open(struct gsm_bts_trx *trx) @@ -1628,9 +1549,6 @@ int bts_model_trx_close(struct gsm_bts_trx *trx) { - /* disable events */ - l1if_disable_events(trx); - /* FIXME: close only one TRX */ return trx_close(trx); } -- To view, visit https://gerrit.osmocom.org/1980 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I0652627495f6a9bcb0da2431b8beb839bc22062b Gerrit-PatchSet: 7 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Thu Apr 20 13:14:34 2017 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Thu, 20 Apr 2017 13:14:34 +0000 Subject: [PATCH] osmo-bts[master]: octphy: align frame number for new firmware versions In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/1965 to look at the new patch set (#6). octphy: align frame number for new firmware versions Firmware releases OCTSDR-2G-02.07.00-B1314-BETA and newer require to align the GPRS frame number (fn-3) for ph_data indications. To preserve compatibility the header version is checked during compile time and the right method is compiled in. Change-Id: Ib93d5fb3b34ff92f10021a0e9ce9c8aa3044b7ff --- M src/osmo-bts-octphy/l1_if.c 1 file changed, 15 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/65/1965/6 diff --git a/src/osmo-bts-octphy/l1_if.c b/src/osmo-bts-octphy/l1_if.c index 00d7df5..7b98785 100644 --- a/src/osmo-bts-octphy/l1_if.c +++ b/src/osmo-bts-octphy/l1_if.c @@ -50,6 +50,12 @@ #include "l1_utils.h" #include "octpkt.h" +#include + +/* NOTE: The octphy GPRS frame number handling changed with + * OCTSDR-2G-02.07.00-B1314-BETA. From that version on, each ph_data_ind must + * subtract 3 from the frame number before passing the frame to the PCU */ +#define cOCTVC1_MAIN_VERSION_ID_FN_PARADIGM_CHG 0x41c0522 #include #define OCTVC1_RC2STRING_DECLARE @@ -1039,7 +1045,16 @@ PRIM_OP_INDICATION, l1p_msg); l1sap->u.data.link_id = link_id; l1sap->u.data.chan_nr = chan_nr; + +#if (cOCTVC1_MAIN_VERSION_ID >= cOCTVC1_MAIN_VERSION_ID_FN_PARADIGM_CHG) + if (sapi == cOCTVC1_GSM_SAPI_ENUM_PDTCH) { + l1sap->u.data.fn = fn - 3; + } else + l1sap->u.data.fn = fn; +#else l1sap->u.data.fn = fn; +#endif + l1sap->u.data.rssi = rssi; b_total = data_ind->MeasurementInfo.usBERTotalBitCnt; b_error =data_ind->MeasurementInfo.usBERCnt; -- To view, visit https://gerrit.osmocom.org/1965 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ib93d5fb3b34ff92f10021a0e9ce9c8aa3044b7ff Gerrit-PatchSet: 6 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Thu Apr 20 13:14:36 2017 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Thu, 20 Apr 2017 13:14:36 +0000 Subject: [PATCH] osmo-bts[master]: measurement/cosmetic: Fixup source code comment Message-ID: Review at https://gerrit.osmocom.org/2387 measurement/cosmetic: Fixup source code comment the function ber10k_to_rxqual() has only a very brief comment with the spec reference. This commit adds a more explainatory comment that makes it easier to understand from where the ber10k constants are taken. Change-Id: I3d3488c97d0bffa7d449d3675afcc75b2a6a2703 --- M src/common/measurement.c 1 file changed, 14 insertions(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/87/2387/1 diff --git a/src/common/measurement.c b/src/common/measurement.c index 6a11888..0814bf1 100644 --- a/src/common/measurement.c +++ b/src/common/measurement.c @@ -114,7 +114,20 @@ /* input: BER in steps of .01%, i.e. percent/100 */ static uint8_t ber10k_to_rxqual(uint32_t ber10k) { - /* 05.08 / 8.2.4 */ + /* Eight levels of Rx quality are defined and are mapped to the + * equivalent BER before channel decoding, as per in 3GPP TS 45.008, + * secton 8.2.4. + * + * RxQual: BER Range: + * RXQUAL_0 BER < 0,2 % Assumed value = 0,14 % + * RXQUAL_1 0,2 % < BER < 0,4 % Assumed value = 0,28 % + * RXQUAL_2 0,4 % < BER < 0,8 % Assumed value = 0,57 % + * RXQUAL_3 0,8 % < BER < 1,6 % Assumed value = 1,13 % + * RXQUAL_4 1,6 % < BER < 3,2 % Assumed value = 2,26 % + * RXQUAL_5 3,2 % < BER < 6,4 % Assumed value = 4,53 % + * RXQUAL_6 6,4 % < BER < 12,8 % Assumed value = 9,05 % + * RXQUAL_7 12,8 % < BER Assumed value = 18,10 % */ + if (ber10k < 20) return 0; if (ber10k < 40) -- To view, visit https://gerrit.osmocom.org/2387 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I3d3488c97d0bffa7d449d3675afcc75b2a6a2703 Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: dexter From gerrit-no-reply at lists.osmocom.org Thu Apr 20 13:14:36 2017 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Thu, 20 Apr 2017 13:14:36 +0000 Subject: [PATCH] osmo-bts[master]: measurement/cosmetic: Fixup source code comment Message-ID: Review at https://gerrit.osmocom.org/2388 measurement/cosmetic: Fixup source code comment the function is_meas_complete() uses the *_meas_rep_fn104[] lookup tables, defined at the beginning of the source file. These lookup tabels contain a lot of magic numbers. This commit adds a more elaborated comment with a reference to the specification/section in order make the values understandable. Change-Id: Ic6e4037f965772e6b851c67662d5e7bf64cc04eb --- M src/common/measurement.c 1 file changed, 15 insertions(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/88/2388/1 diff --git a/src/common/measurement.c b/src/common/measurement.c index 0814bf1..8076413 100644 --- a/src/common/measurement.c +++ b/src/common/measurement.c @@ -8,7 +8,21 @@ #include #include -/* TS 05.08, Chapter 8.4.1 */ +/* Measurment reporting period and mapping of SACCH message block for TCHF + * and TCHH chan As per in 3GPP TS 45.008, secton 8.4.1. + * + * Timeslot number (TN) TDMA frame number (FN) modulo 104 + * Half rate, Half rate, Reporting SACCH + * Full Rate subch.0 subch.1 period Message block + * 0 0 and 1 0 to 103 12, 38, 64, 90 + * 1 0 and 1 13 to 12 25, 51, 77, 103 + * 2 2 and 3 26 to 25 38, 64, 90, 12 + * 3 2 and 3 39 to 38 51, 77, 103, 25 + * 4 4 and 5 52 to 51 64, 90, 12, 38 + * 5 4 and 5 65 to 64 77, 103, 25, 51 + * 6 6 and 7 78 to 77 90, 12, 38, 64 + * 7 6 and 7 91 to 90 103, 25, 51, 77 */ + /* measurement period ends at fn % 104 == ? */ static const uint8_t tchf_meas_rep_fn104[] = { [0] = 103, -- To view, visit https://gerrit.osmocom.org/2388 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ic6e4037f965772e6b851c67662d5e7bf64cc04eb Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: dexter From gerrit-no-reply at lists.osmocom.org Thu Apr 20 13:14:37 2017 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Thu, 20 Apr 2017 13:14:37 +0000 Subject: [PATCH] osmo-bts[master]: measurement: Improve log output Message-ID: Review at https://gerrit.osmocom.org/2389 measurement: Improve log output The debug log does not print much information about the measured rxlev and rxqual values. This commit adds debug output to make measurement debugging simpler Change-Id: Ic871eed6dcbc7d10aca6cd11dbc803b3e6da449f --- M src/common/measurement.c M src/common/rsl.c 2 files changed, 26 insertions(+), 2 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/89/2389/1 diff --git a/src/common/measurement.c b/src/common/measurement.c index 8076413..9987d73 100644 --- a/src/common/measurement.c +++ b/src/common/measurement.c @@ -99,6 +99,11 @@ rc = 0; break; } + + DEBUGP(DMEAS, + "MEAS PERIOD END status:%d for chan:%u, TS:%u, SUBCHAN:%u, FN:%u, FN_MOD:%u\n", + rc, pchan, ts, subch, fn, fn_mod); + return rc; } @@ -219,6 +224,14 @@ mru->full.rx_qual = ber10k_to_rxqual(ber_full_sum); mru->sub.rx_qual = ber10k_to_rxqual(ber_sub_sum); + DEBUGP(DMEAS, "%s UL MEAS RXLEV_FULL(%u), RXLEV_SUB(%u)," + "RXQUAL_FULL(%u), RXQUAL_SUB(%u), num_meas_sub(%u), num_ul_meas(%u) \n", + gsm_lchan_name(lchan), + mru->full.rx_lev, + mru->sub.rx_lev, + mru->full.rx_qual, + mru->sub.rx_qual, num_meas_sub, lchan->meas.num_ul_meas); + lchan->meas.flags |= LC_UL_M_F_RES_VALID; lchan->meas.num_ul_meas = 0; diff --git a/src/common/rsl.c b/src/common/rsl.c index 1d0bcea..a542324 100644 --- a/src/common/rsl.c +++ b/src/common/rsl.c @@ -2228,8 +2228,9 @@ uint8_t chan_nr = gsm_lchan2chan_nr(lchan); int res_valid = lchan->meas.flags & LC_UL_M_F_RES_VALID; - LOGP(DRSL, LOGL_DEBUG, "%s Tx MEAS RES valid(%d)\n", - gsm_lchan_name(lchan), res_valid); + LOGP(DRSL, LOGL_DEBUG, + "%s chan_num:%d Tx MEAS RES valid(%d), flags(%d)\n", + gsm_lchan_name(lchan), chan_nr, res_valid, lchan->meas.flags); if (!res_valid) return -EINPROGRESS; @@ -2238,6 +2239,16 @@ if (!msg) return -ENOMEM; + LOGP(DRSL, LOGL_DEBUG, + "Send Meas RES: NUM:%d, RXLEV_FULL:%d, RXLEV_SUB:%d, RXQUAL_FULL:%d, RXQUAL_SUB:%d, MS_PWR:%d, UL_TA:%d, L3_LEN:%d, TimingOff:%u\n", + lchan->meas.res_nr, + lchan->meas.ul_res.full.rx_lev, + lchan->meas.ul_res.sub.rx_lev, + lchan->meas.ul_res.full.rx_qual, + lchan->meas.ul_res.sub.rx_qual, + lchan->meas.l1_info[0], + lchan->meas.l1_info[1], l3_len, lchan->meas.ms_timing_offset); + msgb_tv_put(msg, RSL_IE_MEAS_RES_NR, lchan->meas.res_nr++); size_t ie_len = gsm0858_rsl_ul_meas_enc(&lchan->meas.ul_res, lchan->tch.dtx.dl_active, -- To view, visit https://gerrit.osmocom.org/2389 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ic871eed6dcbc7d10aca6cd11dbc803b3e6da449f Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: dexter From gerrit-no-reply at lists.osmocom.org Thu Apr 20 13:14:37 2017 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Thu, 20 Apr 2017 13:14:37 +0000 Subject: [PATCH] osmo-bts[master]: octphy: ensure that 11 bit rach flag is not set Message-ID: Review at https://gerrit.osmocom.org/2390 octphy: ensure that 11 bit rach flag is not set The l1 interface does not explicitly set the flag for 11 bit rach when a rach request is received. Since the current and previous octphy firmwares do not support 11 bit rach requests, the flag should be explicitly set to zero. Change-Id: Ifa165c56e54d272caafa45d1bf0e177848fcdfbd --- M src/osmo-bts-octphy/l1_if.c 1 file changed, 2 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/90/2390/1 diff --git a/src/osmo-bts-octphy/l1_if.c b/src/osmo-bts-octphy/l1_if.c index b42fb3a..00d7df5 100644 --- a/src/osmo-bts-octphy/l1_if.c +++ b/src/osmo-bts-octphy/l1_if.c @@ -1109,6 +1109,8 @@ l1sap->u.rach_ind.ra = ra; l1sap->u.rach_ind.acc_delay = acc_delay; l1sap->u.rach_ind.fn = fn; + l1sap->u.rach_ind.is_11bit = 0; + if (!lchan || lchan->ts->pchan == GSM_PCHAN_CCCH || lchan->ts->pchan == GSM_PCHAN_CCCH_SDCCH4 || lchan->ts->pchan == GSM_PCHAN_CCCH_SDCCH4_CBCH) -- To view, visit https://gerrit.osmocom.org/2390 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ifa165c56e54d272caafa45d1bf0e177848fcdfbd Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: dexter From gerrit-no-reply at lists.osmocom.org Thu Apr 20 14:21:40 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Thu, 20 Apr 2017 14:21:40 +0000 Subject: [PATCH] osmo-bts[master]: Add MS TO to RSL measurements In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/1700 to look at the new patch set (#5). Add MS TO to RSL measurements Add optional MS timing offset (3GPP TS 45.010 ? 1.2) to RSL MEASUREMENT RESULT (3GPP TS 48.058 ? 8.4.8). The value is calculated either directly from corresponding BTS measurement or from 3GPP TS 48.058 ? 9.3.17 Access Delay (for known TA) and is invalidated after RSL report is sent until new measurement indication or RACH is received. Change-Id: I4dfe5c48834a083e757d5de3236a02e15a238b28 Related: OS#1574 --- M src/common/l1sap.c M src/common/rsl.c 2 files changed, 38 insertions(+), 5 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/00/1700/5 diff --git a/src/common/l1sap.c b/src/common/l1sap.c index 3592096..07d8c5c 100644 --- a/src/common/l1sap.c +++ b/src/common/l1sap.c @@ -431,6 +431,21 @@ return 0; } + +static inline void set_ms_to_data(struct gsm_lchan *lchan, int16_t data, bool set_ms_to) +{ + if (!lchan) + return; + + if (set_ms_to) { + lchan->ms_t_offs = data + 63; + lchan->p_offs = -1; + } else { + lchan->p_offs = data + 63; + lchan->ms_t_offs = -1; + } +} + /* measurement information received from bts model */ static int l1sap_info_meas_ind(struct gsm_bts_trx *trx, struct osmo_phsap_prim *l1sap, @@ -455,6 +470,9 @@ ulm.ta_offs_qbits = info_meas_ind->ta_offs_qbits; ulm.ber10k = info_meas_ind->ber10k; ulm.inv_rssi = info_meas_ind->inv_rssi; + + /* we assume that symbol period is 1 bit: */ + set_ms_to_data(lchan, info_meas_ind->ta_offs_qbits / 4, true); lchan_new_ul_meas(lchan, &ulm); @@ -1021,6 +1039,9 @@ return 0; } + /* According to 3GPP TS 48.058 ? 9.3.17 Access Delay is expressed same way as TA (number of symbols) */ + set_ms_to_data(get_lchan_by_chan_nr(trx, rach_ind->chan_nr), acc_delay, false); + /* check for handover rach */ if (!L1SAP_IS_CHAN_RACH(rach_ind->chan_nr)) return l1sap_handover_rach(trx, l1sap, rach_ind); diff --git a/src/common/rsl.c b/src/common/rsl.c index 1d0bcea..5fe5a1d 100644 --- a/src/common/rsl.c +++ b/src/common/rsl.c @@ -2220,8 +2220,18 @@ return 0; } +static inline uint8_t ms_to2rsl(const struct gsm_lchan *lchan, const struct lapdm_entity *le) +{ + return (lchan->ms_t_offs >= 0) ? lchan->ms_t_offs : (lchan->p_offs - le->ta); +} + +static inline bool ms_to_valid(const struct gsm_lchan *lchan) +{ + return (lchan->ms_t_offs >= 0) || (lchan->p_offs >= 0); +} + /* 8.4.8 MEASUREMENT RESult */ -static int rsl_tx_meas_res(struct gsm_lchan *lchan, uint8_t *l3, int l3_len) +static int rsl_tx_meas_res(struct gsm_lchan *lchan, uint8_t *l3, int l3_len, const struct lapdm_entity *le) { struct msgb *msg; uint8_t meas_res[16]; @@ -2253,7 +2263,11 @@ lchan->meas.flags &= ~LC_UL_M_F_L1_VALID; } msgb_tl16v_put(msg, RSL_IE_L3_INFO, l3_len, l3); - //msgb_tv_put(msg, RSL_IE_MS_TIMING_OFFSET, FIXME); + if (ms_to_valid(lchan)) { + msgb_tv_put(msg, RSL_IE_MS_TIMING_OFFSET, ms_to2rsl(lchan, le)); + lchan->ms_t_offs = -1; + lchan->p_offs = -1; + } rsl_dch_push_hdr(msg, RSL_MT_MEAS_RES, chan_nr); msg->trx = lchan->ts->trx; @@ -2266,8 +2280,6 @@ { struct gsm_lchan *lchan = ctx; struct abis_rsl_common_hdr *rh; - - /* NOTE: Parameter lapdm_entity *le is ignored */ OSMO_ASSERT(msg); rh = msgb_l2(msg); @@ -2306,7 +2318,7 @@ return 0; } - rc = rsl_tx_meas_res(lchan, msgb_l3(msg), msgb_l3len(msg)); + rc = rsl_tx_meas_res(lchan, msgb_l3(msg), msgb_l3len(msg), le); msgb_free(msg); return rc; } else { -- To view, visit https://gerrit.osmocom.org/1700 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I4dfe5c48834a083e757d5de3236a02e15a238b28 Gerrit-PatchSet: 5 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max From gerrit-no-reply at lists.osmocom.org Thu Apr 20 14:30:36 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Thu, 20 Apr 2017 14:30:36 +0000 Subject: [PATCH] openbsc[master]: Fix measurement display Message-ID: Review at https://gerrit.osmocom.org/2391 Fix measurement display * set proper flag when saving MS Timing Offset * use gsm_subscriber's IMSI or lchan's name if bsc_subscriber is unknown * add comments with spec reference * display MS Timing Offset instead of raw Timing Offset field from RSL * rename ms_timing_offset -> timing_offset to avoid confusion between MS Timing Offset [-63; 192] and Timing Offset field [0; 255] Change-Id: I7e003d23a6edb714c5f17688fd6a8edac131161d Related: OS#1574 --- M openbsc/include/openbsc/meas_rep.h M openbsc/src/libbsc/abis_rsl.c M openbsc/src/libbsc/bsc_vty.c M openbsc/src/libmsc/smpp_openbsc.c M openbsc/src/utils/meas_db.c M openbsc/src/utils/meas_json.c M openbsc/src/utils/meas_vis.c 7 files changed, 24 insertions(+), 15 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/91/2391/1 diff --git a/openbsc/include/openbsc/meas_rep.h b/openbsc/include/openbsc/meas_rep.h index 6d36f34..352a1c0 100644 --- a/openbsc/include/openbsc/meas_rep.h +++ b/openbsc/include/openbsc/meas_rep.h @@ -39,7 +39,7 @@ struct gsm_meas_rep_unidir dl; uint8_t bs_power; - uint8_t ms_timing_offset; + uint8_t timing_offset; struct { int8_t pwr; /* MS power in dBm */ uint8_t ta; /* MS timing advance */ diff --git a/openbsc/src/libbsc/abis_rsl.c b/openbsc/src/libbsc/abis_rsl.c index 5ae707c..a22297c 100644 --- a/openbsc/src/libbsc/abis_rsl.c +++ b/openbsc/src/libbsc/abis_rsl.c @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include @@ -1369,8 +1370,14 @@ int i; const char *name = ""; - if (lchan && lchan->conn) - name = bsc_subscr_name(lchan->conn->bsub); + if (lchan && lchan->conn) { + if (lchan->conn->bsub) + name = bsc_subscr_name(lchan->conn->bsub); + else if (lchan->conn->subscr) + name = lchan->conn->subscr->imsi; + else + name = lchan->name; + } DEBUGP(DMEAS, "[%s] MEASUREMENT RESULT NR=%d ", name, mr->nr); @@ -1379,8 +1386,10 @@ print_meas_rep_uni(&mr->ul, "ul"); DEBUGPC(DMEAS, "BS_POWER=%d ", mr->bs_power); + + /* According to 3GPP TS 48.058 ? MS Timing Offset = Timing Offset field - 63 */ if (mr->flags & MEAS_REP_F_MS_TO) - DEBUGPC(DMEAS, "MS_TO=%d ", mr->ms_timing_offset); + DEBUGPC(DMEAS, "MS_TO=%d ", mr->timing_offset - 63); if (mr->flags & MEAS_REP_F_MS_L1) { DEBUGPC(DMEAS, "L1_MS_PWR=%3ddBm ", mr->ms_l1.pwr); @@ -1452,9 +1461,10 @@ mr->bs_power = *TLVP_VAL(&tp, RSL_IE_BS_POWER); /* Optional Parts */ - if (TLVP_PRESENT(&tp, RSL_IE_MS_TIMING_OFFSET)) - mr->ms_timing_offset = - *TLVP_VAL(&tp, RSL_IE_MS_TIMING_OFFSET); + if (TLVP_PRESENT(&tp, RSL_IE_MS_TIMING_OFFSET)) { + mr->timing_offset = *TLVP_VAL(&tp, RSL_IE_MS_TIMING_OFFSET); + mr->flags |= MEAS_REP_F_MS_TO; + } if (TLVP_PRESENT(&tp, RSL_IE_L1_INFO)) { struct e1inp_sign_link *sign_link = msg->dst; diff --git a/openbsc/src/libbsc/bsc_vty.c b/openbsc/src/libbsc/bsc_vty.c index c1882fc..99d0d49 100644 --- a/openbsc/src/libbsc/bsc_vty.c +++ b/openbsc/src/libbsc/bsc_vty.c @@ -1061,9 +1061,9 @@ mr->flags & MEAS_REP_F_FPC ? "FPC " : "", mr->flags & MEAS_REP_F_DL_VALID ? " " : "DLinval ", VTY_NEWLINE); - if (mr->flags & MEAS_REP_F_MS_TO) - vty_out(vty, "%s MS Timing Offset: %u%s", prefix, - mr->ms_timing_offset, VTY_NEWLINE); + if (mr->flags & MEAS_REP_F_MS_TO) /* According to 3GPP TS 48.058 ? MS Timing Offset = Timing Offset field - 63 */ + vty_out(vty, "%s MS Timing Offset: %d%s", prefix, + mr->timing_offset - 63, VTY_NEWLINE); if (mr->flags & MEAS_REP_F_MS_L1) vty_out(vty, "%s L1 MS Power: %u dBm, Timing Advance: %u%s", prefix, mr->ms_l1.pwr, mr->ms_l1.ta, VTY_NEWLINE); diff --git a/openbsc/src/libmsc/smpp_openbsc.c b/openbsc/src/libmsc/smpp_openbsc.c index 2703a24..4f2aaab 100644 --- a/openbsc/src/libmsc/smpp_openbsc.c +++ b/openbsc/src/libmsc/smpp_openbsc.c @@ -438,7 +438,7 @@ ms_dbm = ms_pwr_dbm(lchan->ts->trx->bts->band, mr->ms_l1.pwr); append_tlv_u8(req_tlv, TLVID_osmo_ms_l1_txpwr, ms_dbm); } else if (mr->flags & MEAS_REP_F_MS_TO) - append_tlv_u8(req_tlv, TLVID_osmo_ta, mr->ms_timing_offset); + append_tlv_u8(req_tlv, TLVID_osmo_ta, mr->timing_offset); append_tlv_u16(req_tlv, TLVID_osmo_rxlev_ul, rxlev2dbm(ul_meas->full.rx_lev)); diff --git a/openbsc/src/utils/meas_db.c b/openbsc/src/utils/meas_db.c index a3b694e..3b63f87 100644 --- a/openbsc/src/utils/meas_db.c +++ b/openbsc/src/utils/meas_db.c @@ -114,8 +114,7 @@ SCK_OK(st->db, sqlite3_bind_int(st->stmt_ins_mr, 6, mr->bs_power)); if (mr->flags & MEAS_REP_F_MS_TO) - SCK_OK(st->db, sqlite3_bind_int(st->stmt_ins_mr, 7, - mr->ms_timing_offset)); + SCK_OK(st->db, sqlite3_bind_int(st->stmt_ins_mr, 7, mr->timing_offset)); else SCK_OK(st->db, sqlite3_bind_null(st->stmt_ins_mr, 7)); diff --git a/openbsc/src/utils/meas_json.c b/openbsc/src/utils/meas_json.c index 51eb6c7..038368e 100644 --- a/openbsc/src/utils/meas_json.c +++ b/openbsc/src/utils/meas_json.c @@ -64,7 +64,7 @@ printf("}"); printf(", \"BS_POWER\":%d", mr->bs_power); if (mr->flags & MEAS_REP_F_MS_TO) - printf(", \"MS_TO\":%d", mr->ms_timing_offset); + printf(", \"MS_TO\":%d", mr->timing_offset); if (mr->flags & MEAS_REP_F_MS_L1) { printf(", \"L1_MS_PWR\":%d", mr->ms_l1.pwr); diff --git a/openbsc/src/utils/meas_vis.c b/openbsc/src/utils/meas_vis.c index 316d203..63ab620 100644 --- a/openbsc/src/utils/meas_vis.c +++ b/openbsc/src/utils/meas_vis.c @@ -202,7 +202,7 @@ //IsVisibleObj(ms->ul.cdk) = FALSE; snprintf(msu->label, sizeof(msu->label), "%1d %3d %2u %2u %4u", qual_col, lq->rx_qual, qual_col, pwr, - ms->mr.ms_l1.ta, ms->mr.ms_timing_offset, + ms->mr.ms_l1.ta, ms->mr.timing_offset, now - msu->last_update); msu->cdk_label = newCDKLabel(g_st.cdkscreen, RIGHT, row, msu->_lbl, 1, FALSE, FALSE); -- To view, visit https://gerrit.osmocom.org/2391 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I7e003d23a6edb714c5f17688fd6a8edac131161d Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Max From gerrit-no-reply at lists.osmocom.org Thu Apr 20 14:35:32 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Thu, 20 Apr 2017 14:35:32 +0000 Subject: osmo-bts[master]: measurement/cosmetic: Fixup source code comment In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+1 -- To view, visit https://gerrit.osmocom.org/2388 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ic6e4037f965772e6b851c67662d5e7bf64cc04eb Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Apr 20 14:36:06 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Thu, 20 Apr 2017 14:36:06 +0000 Subject: osmo-bts[master]: measurement/cosmetic: Fixup source code comment In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+1 -- To view, visit https://gerrit.osmocom.org/2387 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I3d3488c97d0bffa7d449d3675afcc75b2a6a2703 Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Apr 20 19:37:46 2017 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 20 Apr 2017 19:37:46 +0000 Subject: libosmo-netif[master]: api doc: Call the variable by the right ("crx") name In-Reply-To: References: Message-ID: Patch Set 1: (1 comment) https://gerrit.osmocom.org/#/c/2284/1/src/datagram.c File src/datagram.c: Line 101: * \param[in] crx talloc context from which to allocate memory hmm really? "crx" for talloc context almost certainly looks like a typo and many follow-up typos? what is "crx" supposed to mean?? -- To view, visit https://gerrit.osmocom.org/2284 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I27ed1178fdbbcf3fc0e1070dc19b4ecf9a327a04 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: Yes From admin at opensuse.org Thu Apr 20 20:02:18 2017 From: admin at opensuse.org (OBS Notification) Date: Thu, 20 Apr 2017 20:02:18 +0000 Subject: Build failure of network:osmocom:nightly/libosmo-sccp in xUbuntu_16.04/i586 In-Reply-To: References: Message-ID: <58f913f499a8a_1e2461ef7c1126bb@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/libosmo-sccp/xUbuntu_16.04/i586 Package network:osmocom:nightly/libosmo-sccp failed to build in xUbuntu_16.04/i586 Check out the package for editing: osc checkout network:osmocom:nightly libosmo-sccp Last lines of build log: [ 146s] /usr/src/packages/BUILD/src/xua_asp_fsm.c:772: undefined reference to `ipa_ccm_send_id_req' [ 146s] ../../src/.libs/libosmo-sigtran.a(ipa.o): In function `ipa_tx_xua_as': [ 146s] /usr/src/packages/BUILD/src/ipa.c:71: undefined reference to `ipa_msg_alloc' [ 146s] collect2: error: ld returned 1 exit status [ 146s] Makefile:360: recipe for target 'xua_test' failed [ 146s] make[4]: *** [xua_test] Error 1 [ 146s] make[4]: Leaving directory '/usr/src/packages/BUILD/tests/xua' [ 146s] Makefile:362: recipe for target 'all-recursive' failed [ 146s] make[3]: *** [all-recursive] Error 1 [ 146s] make[3]: Leaving directory '/usr/src/packages/BUILD/tests' [ 146s] Makefile:454: recipe for target 'all-recursive' failed [ 146s] make[2]: *** [all-recursive] Error 1 [ 146s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 146s] Makefile:372: recipe for target 'all' failed [ 146s] make[1]: *** [all] Error 2 [ 146s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 146s] dh_auto_build: make -j1 returned exit code 2 [ 146s] debian/rules:12: recipe for target 'build' failed [ 146s] make: *** [build] Error 2 [ 146s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 146s] [ 146s] lamb62 failed "build libosmo-sccp_0.7.1.20170420.dsc" at Thu Apr 20 20:02:09 UTC 2017. [ 146s] [ 146s] ### VM INTERACTION START ### [ 149s] [ 136.418781] reboot: Power down [ 149s] ### VM INTERACTION END ### [ 149s] [ 149s] lamb62 failed "build libosmo-sccp_0.7.1.20170420.dsc" at Thu Apr 20 20:02:12 UTC 2017. [ 149s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Thu Apr 20 20:03:45 2017 From: admin at opensuse.org (OBS Notification) Date: Thu, 20 Apr 2017 20:03:45 +0000 Subject: Build failure of network:osmocom:nightly/libosmo-sccp in Debian_8.0/i586 In-Reply-To: References: Message-ID: <58f9144e72768_1bbd9c0f7c109793@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/libosmo-sccp/Debian_8.0/i586 Package network:osmocom:nightly/libosmo-sccp failed to build in Debian_8.0/i586 Check out the package for editing: osc checkout network:osmocom:nightly libosmo-sccp Last lines of build log: [ 104s] /usr/bin/ld: ../../src/.libs/libosmo-sigtran.a(osmo_ss7.o): undefined reference to symbol 'ipa_msg_recv_buffered@@LIBOSMOGSM_1.0' [ 104s] //usr/lib/i386-linux-gnu/libosmogsm.so.6: error adding symbols: DSO missing from command line [ 104s] collect2: error: ld returned 1 exit status [ 104s] Makefile:348: recipe for target 'xua_test' failed [ 104s] make[4]: *** [xua_test] Error 1 [ 104s] make[4]: Leaving directory '/usr/src/packages/BUILD/tests/xua' [ 104s] Makefile:350: recipe for target 'all-recursive' failed [ 104s] make[3]: *** [all-recursive] Error 1 [ 104s] make[3]: Leaving directory '/usr/src/packages/BUILD/tests' [ 104s] Makefile:443: recipe for target 'all-recursive' failed [ 104s] make[2]: *** [all-recursive] Error 1 [ 104s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 104s] Makefile:360: recipe for target 'all' failed [ 104s] make[1]: *** [all] Error 2 [ 104s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 104s] dh_auto_build: make -j1 returned exit code 2 [ 104s] debian/rules:12: recipe for target 'build' failed [ 104s] make: *** [build] Error 2 [ 104s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 104s] [ 104s] lamb20 failed "build libosmo-sccp_0.7.1.20170420.dsc" at Thu Apr 20 20:03:26 UTC 2017. [ 104s] [ 104s] ### VM INTERACTION START ### [ 106s] Powering off. [ 106s] [ 92.513940] reboot: Power down [ 106s] ### VM INTERACTION END ### [ 106s] [ 106s] lamb20 failed "build libosmo-sccp_0.7.1.20170420.dsc" at Thu Apr 20 20:03:28 UTC 2017. [ 106s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Thu Apr 20 20:05:10 2017 From: admin at opensuse.org (OBS Notification) Date: Thu, 20 Apr 2017 20:05:10 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in xUbuntu_16.04/i586 In-Reply-To: References: Message-ID: <58f9148766d27_1bc39c0f7c1079d6@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/xUbuntu_16.04/i586 Package network:osmocom:nightly/osmo-stp failed to build in xUbuntu_16.04/i586 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 129s] sctp_m2ua.c:91:3: warning: #warning "Notify any other AS(P) for failover scenario" [-Wcpp] [ 129s] #warning "Notify any other AS(P) for failover scenario" [ 129s] ^ [ 130s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -c -o vty_interface.o vty_interface.c [ 130s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -c -o sctp_m3ua_client.o sctp_m3ua_client.c [ 130s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 130s] compilation terminated. [ 130s] Makefile:485: recipe for target 'sctp_m3ua_client.o' failed [ 130s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 130s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 130s] Makefile:380: recipe for target 'all-recursive' failed [ 130s] make[2]: *** [all-recursive] Error 1 [ 130s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 130s] Makefile:321: recipe for target 'all' failed [ 130s] make[1]: *** [all] Error 2 [ 130s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 130s] dh_auto_build: make -j1 returned exit code 2 [ 130s] debian/rules:23: recipe for target 'build' failed [ 130s] make: *** [build] Error 2 [ 130s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 130s] [ 130s] lamb05 failed "build cellmgr-ng_1.4.7.20170420.dsc" at Thu Apr 20 20:04:54 UTC 2017. [ 130s] [ 130s] ### VM INTERACTION START ### [ 134s] [ 121.029723] reboot: Power down [ 134s] ### VM INTERACTION END ### [ 134s] [ 134s] lamb05 failed "build cellmgr-ng_1.4.7.20170420.dsc" at Thu Apr 20 20:04:58 UTC 2017. [ 134s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Thu Apr 20 20:06:35 2017 From: admin at opensuse.org (OBS Notification) Date: Thu, 20 Apr 2017 20:06:35 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in Debian_8.0/i586 In-Reply-To: References: Message-ID: <58f914dfb8e66_1bbd9c0f7c1099cd@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/Debian_8.0/i586 Package network:osmocom:nightly/osmo-stp failed to build in Debian_8.0/i586 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 134s] CC vty_interface.o [ 135s] CC sctp_m3ua_client.o [ 135s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 135s] #include [ 135s] ^ [ 135s] compilation terminated. [ 135s] Makefile:475: recipe for target 'sctp_m3ua_client.o' failed [ 135s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 135s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 135s] Makefile:370: recipe for target 'all-recursive' failed [ 135s] make[2]: *** [all-recursive] Error 1 [ 135s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 135s] Makefile:310: recipe for target 'all' failed [ 135s] make[1]: *** [all] Error 2 [ 135s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 135s] dh_auto_build: make -j1 returned exit code 2 [ 135s] debian/rules:23: recipe for target 'build' failed [ 135s] make: *** [build] Error 2 [ 135s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 135s] [ 135s] wildcard2 failed "build cellmgr-ng_1.4.7.20170420.dsc" at Thu Apr 20 20:06:15 UTC 2017. [ 135s] [ 135s] ### VM INTERACTION START ### [ 136s] Powering off. [ 136s] [ 115.675930] reboot: Power down [ 153s] ### VM INTERACTION END ### [ 153s] [ 153s] wildcard2 failed "build cellmgr-ng_1.4.7.20170420.dsc" at Thu Apr 20 20:06:33 UTC 2017. [ 153s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Thu Apr 20 20:08:18 2017 From: admin at opensuse.org (OBS Notification) Date: Thu, 20 Apr 2017 20:08:18 +0000 Subject: Build failure of network:osmocom:nightly/libosmo-sccp in xUbuntu_16.10/i586 In-Reply-To: References: Message-ID: <58f915575782f_1e2461ef7c1127b1@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/libosmo-sccp/xUbuntu_16.10/i586 Package network:osmocom:nightly/libosmo-sccp failed to build in xUbuntu_16.10/i586 Check out the package for editing: osc checkout network:osmocom:nightly libosmo-sccp Last lines of build log: [ 336s] ../../src/.libs/libosmo-sigtran.a(xua_asp_fsm.o): In function `ipa_asp_fsm_down': [ 336s] ./src/xua_asp_fsm.c:772: undefined reference to `ipa_ccm_send_id_req' [ 336s] ../../src/.libs/libosmo-sigtran.a(ipa.o): In function `ipa_tx_xua_as': [ 336s] ./src/ipa.c:71: undefined reference to `ipa_msg_alloc' [ 336s] collect2: error: ld returned 1 exit status [ 336s] Makefile:360: recipe for target 'xua_test' failed [ 336s] make[4]: *** [xua_test] Error 1 [ 336s] make[4]: Leaving directory '/usr/src/packages/BUILD/tests/xua' [ 336s] Makefile:362: recipe for target 'all-recursive' failed [ 336s] make[3]: *** [all-recursive] Error 1 [ 336s] make[3]: Leaving directory '/usr/src/packages/BUILD/tests' [ 336s] Makefile:454: recipe for target 'all-recursive' failed [ 336s] make[2]: *** [all-recursive] Error 1 [ 336s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 336s] Makefile:372: recipe for target 'all' failed [ 336s] make[1]: *** [all] Error 2 [ 336s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 336s] dh_auto_build: make -j1 returned exit code 2 [ 336s] debian/rules:12: recipe for target 'build' failed [ 336s] make: *** [build] Error 2 [ 336s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 336s] [ 336s] cumulus2 failed "build libosmo-sccp_0.7.1.20170420.dsc" at Thu Apr 20 20:08:02 UTC 2017. [ 336s] [ 336s] ### VM INTERACTION START ### [ 340s] ### VM INTERACTION END ### [ 340s] [ 340s] cumulus2 failed "build libosmo-sccp_0.7.1.20170420.dsc" at Thu Apr 20 20:08:07 UTC 2017. [ 340s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Thu Apr 20 20:10:56 2017 From: admin at opensuse.org (OBS Notification) Date: Thu, 20 Apr 2017 20:10:56 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in xUbuntu_16.10/i586 In-Reply-To: References: Message-ID: <58f915ef199ec_1bc39c0f7c1080d9@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/xUbuntu_16.10/i586 Package network:osmocom:nightly/osmo-stp failed to build in xUbuntu_16.10/i586 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 84s] ^~~~~~~ [ 84s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o vty_interface.o vty_interface.c [ 85s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o sctp_m3ua_client.o sctp_m3ua_client.c [ 85s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 85s] #include [ 85s] ^ [ 85s] compilation terminated. [ 85s] Makefile:485: recipe for target 'sctp_m3ua_client.o' failed [ 85s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 85s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 85s] Makefile:380: recipe for target 'all-recursive' failed [ 85s] make[2]: *** [all-recursive] Error 1 [ 85s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 85s] Makefile:321: recipe for target 'all' failed [ 85s] make[1]: *** [all] Error 2 [ 85s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 85s] dh_auto_build: make -j1 returned exit code 2 [ 85s] debian/rules:23: recipe for target 'build' failed [ 85s] make: *** [build] Error 2 [ 85s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 85s] [ 85s] lamb61 failed "build cellmgr-ng_1.4.7.20170420.dsc" at Thu Apr 20 20:10:37 UTC 2017. [ 85s] [ 85s] ### VM INTERACTION START ### [ 88s] [ 74.661085] reboot: Power down [ 88s] ### VM INTERACTION END ### [ 88s] [ 88s] lamb61 failed "build cellmgr-ng_1.4.7.20170420.dsc" at Thu Apr 20 20:10:41 UTC 2017. [ 88s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Thu Apr 20 20:11:30 2017 From: admin at opensuse.org (OBS Notification) Date: Thu, 20 Apr 2017 20:11:30 +0000 Subject: Build failure of network:osmocom:nightly/libosmo-sccp in Debian_8.0/x86_64 In-Reply-To: References: Message-ID: <58f9162a5866f_1e2461ef7c112898@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/libosmo-sccp/Debian_8.0/x86_64 Package network:osmocom:nightly/libosmo-sccp failed to build in Debian_8.0/x86_64 Check out the package for editing: osc checkout network:osmocom:nightly libosmo-sccp Last lines of build log: [ 127s] /usr/bin/ld: ../../src/.libs/libosmo-sigtran.a(osmo_ss7.o): undefined reference to symbol 'ipa_msg_recv_buffered@@LIBOSMOGSM_1.0' [ 127s] //usr/lib/x86_64-linux-gnu/libosmogsm.so.6: error adding symbols: DSO missing from command line [ 127s] collect2: error: ld returned 1 exit status [ 127s] Makefile:348: recipe for target 'xua_test' failed [ 127s] make[4]: *** [xua_test] Error 1 [ 127s] make[4]: Leaving directory '/usr/src/packages/BUILD/tests/xua' [ 127s] Makefile:350: recipe for target 'all-recursive' failed [ 127s] make[3]: *** [all-recursive] Error 1 [ 127s] make[3]: Leaving directory '/usr/src/packages/BUILD/tests' [ 127s] Makefile:443: recipe for target 'all-recursive' failed [ 127s] make[2]: *** [all-recursive] Error 1 [ 127s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 127s] Makefile:360: recipe for target 'all' failed [ 127s] make[1]: *** [all] Error 2 [ 127s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 127s] dh_auto_build: make -j1 returned exit code 2 [ 127s] debian/rules:12: recipe for target 'build' failed [ 127s] make: *** [build] Error 2 [ 127s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 127s] [ 127s] lamb51 failed "build libosmo-sccp_0.7.1.20170420.dsc" at Thu Apr 20 20:11:18 UTC 2017. [ 127s] [ 127s] ### VM INTERACTION START ### [ 128s] Powering off. [ 128s] [ 113.353570] reboot: Power down [ 128s] ### VM INTERACTION END ### [ 128s] [ 128s] lamb51 failed "build libosmo-sccp_0.7.1.20170420.dsc" at Thu Apr 20 20:11:20 UTC 2017. [ 128s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Thu Apr 20 20:12:24 2017 From: admin at opensuse.org (OBS Notification) Date: Thu, 20 Apr 2017 20:12:24 +0000 Subject: Build failure of network:osmocom:nightly/libosmo-sccp in xUbuntu_16.10/x86_64 In-Reply-To: References: Message-ID: <58f91649c21ab_1e2461ef7c11322d@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/libosmo-sccp/xUbuntu_16.10/x86_64 Package network:osmocom:nightly/libosmo-sccp failed to build in xUbuntu_16.10/x86_64 Check out the package for editing: osc checkout network:osmocom:nightly libosmo-sccp Last lines of build log: [ 64s] ./src/xua_asp_fsm.c:772: undefined reference to `ipa_ccm_send_id_req' [ 64s] ../../src/.libs/libosmo-sigtran.a(ipa.o): In function `ipa_tx_xua_as': [ 64s] ./src/ipa.c:71: undefined reference to `ipa_msg_alloc' [ 64s] collect2: error: ld returned 1 exit status [ 64s] Makefile:360: recipe for target 'xua_test' failed [ 64s] make[4]: *** [xua_test] Error 1 [ 64s] make[4]: Leaving directory '/usr/src/packages/BUILD/tests/xua' [ 64s] Makefile:362: recipe for target 'all-recursive' failed [ 64s] make[3]: *** [all-recursive] Error 1 [ 64s] make[3]: Leaving directory '/usr/src/packages/BUILD/tests' [ 64s] Makefile:454: recipe for target 'all-recursive' failed [ 64s] make[2]: *** [all-recursive] Error 1 [ 64s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 64s] Makefile:372: recipe for target 'all' failed [ 64s] make[1]: *** [all] Error 2 [ 64s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 64s] dh_auto_build: make -j1 returned exit code 2 [ 64s] debian/rules:12: recipe for target 'build' failed [ 64s] make: *** [build] Error 2 [ 64s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 64s] [ 64s] build82 failed "build libosmo-sccp_0.7.1.20170420.dsc" at Thu Apr 20 20:12:08 UTC 2017. [ 64s] [ 64s] ### VM INTERACTION START ### [ 67s] [ 57.618449] reboot: Power down [ 67s] ### VM INTERACTION END ### [ 67s] [ 67s] build82 failed "build libosmo-sccp_0.7.1.20170420.dsc" at Thu Apr 20 20:12:11 UTC 2017. [ 67s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Thu Apr 20 20:15:14 2017 From: admin at opensuse.org (OBS Notification) Date: Thu, 20 Apr 2017 20:15:14 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in Debian_8.0/x86_64 In-Reply-To: References: Message-ID: <58f916fd6d3bf_1bc39c0f7c10863c@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/Debian_8.0/x86_64 Package network:osmocom:nightly/osmo-stp failed to build in Debian_8.0/x86_64 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 143s] CC vty_interface.o [ 144s] CC sctp_m3ua_client.o [ 144s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 144s] #include [ 144s] ^ [ 144s] compilation terminated. [ 144s] Makefile:475: recipe for target 'sctp_m3ua_client.o' failed [ 144s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 144s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 144s] Makefile:370: recipe for target 'all-recursive' failed [ 144s] make[2]: *** [all-recursive] Error 1 [ 144s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 144s] Makefile:310: recipe for target 'all' failed [ 144s] make[1]: *** [all] Error 2 [ 144s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 144s] dh_auto_build: make -j1 returned exit code 2 [ 144s] debian/rules:23: recipe for target 'build' failed [ 144s] make: *** [build] Error 2 [ 144s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 144s] [ 144s] cloud111 failed "build cellmgr-ng_1.4.7.20170420.dsc" at Thu Apr 20 20:14:58 UTC 2017. [ 144s] [ 144s] ### VM INTERACTION START ### [ 145s] Powering off. [ 145s] [ 121.794671] reboot: Power down [ 147s] ### VM INTERACTION END ### [ 147s] [ 147s] cloud111 failed "build cellmgr-ng_1.4.7.20170420.dsc" at Thu Apr 20 20:15:01 UTC 2017. [ 147s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Thu Apr 20 20:17:31 2017 From: admin at opensuse.org (OBS Notification) Date: Thu, 20 Apr 2017 20:17:31 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in xUbuntu_16.10/x86_64 In-Reply-To: References: Message-ID: <58f917952e77a_1bbd9c0f7c11072c@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/xUbuntu_16.10/x86_64 Package network:osmocom:nightly/osmo-stp failed to build in xUbuntu_16.10/x86_64 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 194s] ^~~~~~~ [ 195s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o vty_interface.o vty_interface.c [ 195s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o sctp_m3ua_client.o sctp_m3ua_client.c [ 195s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 195s] #include [ 195s] ^ [ 195s] compilation terminated. [ 195s] Makefile:485: recipe for target 'sctp_m3ua_client.o' failed [ 195s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 195s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 195s] Makefile:380: recipe for target 'all-recursive' failed [ 195s] make[2]: *** [all-recursive] Error 1 [ 195s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 195s] Makefile:321: recipe for target 'all' failed [ 195s] make[1]: *** [all] Error 2 [ 195s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 195s] dh_auto_build: make -j1 returned exit code 2 [ 195s] debian/rules:23: recipe for target 'build' failed [ 195s] make: *** [build] Error 2 [ 195s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 195s] [ 195s] wildcard2 failed "build cellmgr-ng_1.4.7.20170420.dsc" at Thu Apr 20 20:17:11 UTC 2017. [ 195s] [ 195s] ### VM INTERACTION START ### [ 199s] [ 174.803125] reboot: Power down [ 204s] ### VM INTERACTION END ### [ 204s] [ 204s] wildcard2 failed "build cellmgr-ng_1.4.7.20170420.dsc" at Thu Apr 20 20:17:20 UTC 2017. [ 204s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Thu Apr 20 20:18:45 2017 From: admin at opensuse.org (OBS Notification) Date: Thu, 20 Apr 2017 20:18:45 +0000 Subject: Build failure of network:osmocom:nightly/libosmo-sccp in xUbuntu_16.04/x86_64 In-Reply-To: References: Message-ID: <58f917b49669d_1bbd9c0f7c11129b@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/libosmo-sccp/xUbuntu_16.04/x86_64 Package network:osmocom:nightly/libosmo-sccp failed to build in xUbuntu_16.04/x86_64 Check out the package for editing: osc checkout network:osmocom:nightly libosmo-sccp Last lines of build log: [ 182s] /usr/src/packages/BUILD/src/xua_asp_fsm.c:772: undefined reference to `ipa_ccm_send_id_req' [ 182s] ../../src/.libs/libosmo-sigtran.a(ipa.o): In function `ipa_tx_xua_as': [ 182s] /usr/src/packages/BUILD/src/ipa.c:71: undefined reference to `ipa_msg_alloc' [ 182s] collect2: error: ld returned 1 exit status [ 182s] Makefile:360: recipe for target 'xua_test' failed [ 182s] make[4]: *** [xua_test] Error 1 [ 182s] make[4]: Leaving directory '/usr/src/packages/BUILD/tests/xua' [ 182s] Makefile:362: recipe for target 'all-recursive' failed [ 182s] make[3]: *** [all-recursive] Error 1 [ 182s] make[3]: Leaving directory '/usr/src/packages/BUILD/tests' [ 182s] Makefile:454: recipe for target 'all-recursive' failed [ 182s] make[2]: *** [all-recursive] Error 1 [ 182s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 182s] Makefile:372: recipe for target 'all' failed [ 182s] make[1]: *** [all] Error 2 [ 182s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 182s] dh_auto_build: make -j1 returned exit code 2 [ 182s] debian/rules:12: recipe for target 'build' failed [ 182s] make: *** [build] Error 2 [ 182s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 182s] [ 182s] lamb62 failed "build libosmo-sccp_0.7.1.20170420.dsc" at Thu Apr 20 20:18:26 UTC 2017. [ 182s] [ 182s] ### VM INTERACTION START ### [ 186s] [ 173.027425] reboot: Power down [ 186s] ### VM INTERACTION END ### [ 186s] [ 186s] lamb62 failed "build libosmo-sccp_0.7.1.20170420.dsc" at Thu Apr 20 20:18:30 UTC 2017. [ 186s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Thu Apr 20 20:24:10 2017 From: admin at opensuse.org (OBS Notification) Date: Thu, 20 Apr 2017 20:24:10 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in xUbuntu_16.04/x86_64 In-Reply-To: References: Message-ID: <58f91919e45e8_1bbd9c0f7c111537@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/xUbuntu_16.04/x86_64 Package network:osmocom:nightly/osmo-stp failed to build in xUbuntu_16.04/x86_64 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 202s] sctp_m2ua.c:91:3: warning: #warning "Notify any other AS(P) for failover scenario" [-Wcpp] [ 202s] #warning "Notify any other AS(P) for failover scenario" [ 202s] ^ [ 203s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -c -o vty_interface.o vty_interface.c [ 203s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -c -o sctp_m3ua_client.o sctp_m3ua_client.c [ 203s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 203s] compilation terminated. [ 203s] Makefile:485: recipe for target 'sctp_m3ua_client.o' failed [ 203s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 203s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 203s] Makefile:380: recipe for target 'all-recursive' failed [ 203s] make[2]: *** [all-recursive] Error 1 [ 203s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 203s] Makefile:321: recipe for target 'all' failed [ 203s] make[1]: *** [all] Error 2 [ 203s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 204s] dh_auto_build: make -j1 returned exit code 2 [ 204s] debian/rules:23: recipe for target 'build' failed [ 204s] make: *** [build] Error 2 [ 204s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 204s] [ 204s] lamb61 failed "build cellmgr-ng_1.4.7.20170420.dsc" at Thu Apr 20 20:23:59 UTC 2017. [ 204s] [ 204s] ### VM INTERACTION START ### [ 207s] [ 185.064127] reboot: Power down [ 207s] ### VM INTERACTION END ### [ 207s] [ 207s] lamb61 failed "build cellmgr-ng_1.4.7.20170420.dsc" at Thu Apr 20 20:24:03 UTC 2017. [ 207s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Fri Apr 21 19:59:48 2017 From: admin at opensuse.org (OBS Notification) Date: Fri, 21 Apr 2017 19:59:48 +0000 Subject: Build failure of network:osmocom:nightly/libosmo-sccp in xUbuntu_16.04/i586 In-Reply-To: References: Message-ID: <58fa64bea9db2_1e2461ef7c1566bd@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/libosmo-sccp/xUbuntu_16.04/i586 Package network:osmocom:nightly/libosmo-sccp failed to build in xUbuntu_16.04/i586 Check out the package for editing: osc checkout network:osmocom:nightly libosmo-sccp Last lines of build log: [ 104s] ../../src/.libs/libosmo-sigtran.a(xua_asp_fsm.o): In function `ipa_asp_fsm_down': [ 104s] /usr/src/packages/BUILD/src/xua_asp_fsm.c:772: undefined reference to `ipa_ccm_send_id_req' [ 104s] ../../src/.libs/libosmo-sigtran.a(ipa.o): In function `ipa_tx_xua_as': [ 104s] /usr/src/packages/BUILD/src/ipa.c:71: undefined reference to `ipa_msg_alloc' [ 104s] collect2: error: ld returned 1 exit status [ 104s] Makefile:360: recipe for target 'xua_test' failed [ 104s] make[4]: *** [xua_test] Error 1 [ 104s] make[4]: Leaving directory '/usr/src/packages/BUILD/tests/xua' [ 104s] Makefile:362: recipe for target 'all-recursive' failed [ 104s] make[3]: *** [all-recursive] Error 1 [ 104s] make[3]: Leaving directory '/usr/src/packages/BUILD/tests' [ 104s] Makefile:454: recipe for target 'all-recursive' failed [ 104s] make[2]: *** [all-recursive] Error 1 [ 104s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 104s] Makefile:372: recipe for target 'all' failed [ 104s] make[1]: *** [all] Error 2 [ 104s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 104s] dh_auto_build: make -j1 returned exit code 2 [ 104s] debian/rules:12: recipe for target 'build' failed [ 104s] make: *** [build] Error 2 [ 104s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 104s] [ 104s] build81 failed "build libosmo-sccp_0.7.1.20170421.dsc" at Fri Apr 21 19:59:40 UTC 2017. [ 104s] [ 104s] ### VM INTERACTION START ### [ 107s] ### VM INTERACTION END ### [ 107s] [ 107s] build81 failed "build libosmo-sccp_0.7.1.20170421.dsc" at Fri Apr 21 19:59:44 UTC 2017. [ 107s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Fri Apr 21 20:00:57 2017 From: admin at opensuse.org (OBS Notification) Date: Fri, 21 Apr 2017 20:00:57 +0000 Subject: Build failure of network:osmocom:nightly/libosmo-sccp in Debian_8.0/i586 In-Reply-To: References: Message-ID: <58fa651396572_1bbd9c0f7c1712eb@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/libosmo-sccp/Debian_8.0/i586 Package network:osmocom:nightly/libosmo-sccp failed to build in Debian_8.0/i586 Check out the package for editing: osc checkout network:osmocom:nightly libosmo-sccp Last lines of build log: [ 73s] /usr/bin/ld: ../../src/.libs/libosmo-sigtran.a(osmo_ss7.o): undefined reference to symbol 'ipa_msg_recv_buffered@@LIBOSMOGSM_1.0' [ 73s] //usr/lib/i386-linux-gnu/libosmogsm.so.6: error adding symbols: DSO missing from command line [ 73s] collect2: error: ld returned 1 exit status [ 73s] Makefile:348: recipe for target 'xua_test' failed [ 73s] make[4]: *** [xua_test] Error 1 [ 73s] make[4]: Leaving directory '/usr/src/packages/BUILD/tests/xua' [ 73s] Makefile:350: recipe for target 'all-recursive' failed [ 73s] make[3]: *** [all-recursive] Error 1 [ 73s] make[3]: Leaving directory '/usr/src/packages/BUILD/tests' [ 73s] Makefile:443: recipe for target 'all-recursive' failed [ 73s] make[2]: *** [all-recursive] Error 1 [ 73s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 73s] Makefile:360: recipe for target 'all' failed [ 73s] make[1]: *** [all] Error 2 [ 73s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 73s] dh_auto_build: make -j1 returned exit code 2 [ 73s] debian/rules:12: recipe for target 'build' failed [ 73s] make: *** [build] Error 2 [ 73s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 73s] [ 73s] build76 failed "build libosmo-sccp_0.7.1.20170421.dsc" at Fri Apr 21 20:00:49 UTC 2017. [ 73s] [ 73s] ### VM INTERACTION START ### [ 74s] Powering off. [ 74s] [ 65.132076] reboot: Power down [ 74s] ### VM INTERACTION END ### [ 74s] [ 74s] build76 failed "build libosmo-sccp_0.7.1.20170421.dsc" at Fri Apr 21 20:00:51 UTC 2017. [ 74s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Fri Apr 21 20:02:05 2017 From: admin at opensuse.org (OBS Notification) Date: Fri, 21 Apr 2017 20:02:05 +0000 Subject: Build failure of network:osmocom:nightly/libosmo-sccp in xUbuntu_16.10/i586 In-Reply-To: References: Message-ID: <58fa657124c4_1e2461ef7c1567fd@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/libosmo-sccp/xUbuntu_16.10/i586 Package network:osmocom:nightly/libosmo-sccp failed to build in xUbuntu_16.10/i586 Check out the package for editing: osc checkout network:osmocom:nightly libosmo-sccp Last lines of build log: [ 115s] ./src/xua_asp_fsm.c:772: undefined reference to `ipa_ccm_send_id_req' [ 115s] ../../src/.libs/libosmo-sigtran.a(ipa.o): In function `ipa_tx_xua_as': [ 115s] ./src/ipa.c:71: undefined reference to `ipa_msg_alloc' [ 115s] collect2: error: ld returned 1 exit status [ 115s] Makefile:360: recipe for target 'xua_test' failed [ 115s] make[4]: *** [xua_test] Error 1 [ 115s] make[4]: Leaving directory '/usr/src/packages/BUILD/tests/xua' [ 115s] Makefile:362: recipe for target 'all-recursive' failed [ 115s] make[3]: *** [all-recursive] Error 1 [ 115s] make[3]: Leaving directory '/usr/src/packages/BUILD/tests' [ 115s] Makefile:454: recipe for target 'all-recursive' failed [ 115s] make[2]: *** [all-recursive] Error 1 [ 115s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 115s] Makefile:372: recipe for target 'all' failed [ 115s] make[1]: *** [all] Error 2 [ 115s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 115s] dh_auto_build: make -j1 returned exit code 2 [ 115s] debian/rules:12: recipe for target 'build' failed [ 115s] make: *** [build] Error 2 [ 115s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 115s] [ 115s] cumulus2 failed "build libosmo-sccp_0.7.1.20170421.dsc" at Fri Apr 21 20:01:52 UTC 2017. [ 115s] [ 115s] ### VM INTERACTION START ### [ 118s] [ 104.027962] reboot: Power down [ 118s] ### VM INTERACTION END ### [ 118s] [ 118s] cumulus2 failed "build libosmo-sccp_0.7.1.20170421.dsc" at Fri Apr 21 20:01:56 UTC 2017. [ 118s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Fri Apr 21 20:02:59 2017 From: admin at opensuse.org (OBS Notification) Date: Fri, 21 Apr 2017 20:02:59 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in xUbuntu_16.04/i586 In-Reply-To: References: Message-ID: <58fa658d43f58_1bbd9c0f7c1713cb@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/xUbuntu_16.04/i586 Package network:osmocom:nightly/osmo-stp failed to build in xUbuntu_16.04/i586 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 149s] sctp_m2ua.c:91:3: warning: #warning "Notify any other AS(P) for failover scenario" [-Wcpp] [ 149s] #warning "Notify any other AS(P) for failover scenario" [ 149s] ^ [ 150s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -c -o vty_interface.o vty_interface.c [ 150s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -c -o sctp_m3ua_client.o sctp_m3ua_client.c [ 151s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 151s] compilation terminated. [ 151s] Makefile:485: recipe for target 'sctp_m3ua_client.o' failed [ 151s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 151s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 151s] Makefile:380: recipe for target 'all-recursive' failed [ 151s] make[2]: *** [all-recursive] Error 1 [ 151s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 151s] Makefile:321: recipe for target 'all' failed [ 151s] make[1]: *** [all] Error 2 [ 151s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 151s] dh_auto_build: make -j1 returned exit code 2 [ 151s] debian/rules:23: recipe for target 'build' failed [ 151s] make: *** [build] Error 2 [ 151s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 151s] [ 151s] lamb15 failed "build cellmgr-ng_1.4.7.20170421.dsc" at Fri Apr 21 20:02:40 UTC 2017. [ 151s] [ 151s] ### VM INTERACTION START ### [ 154s] [ 140.532552] reboot: Power down [ 154s] ### VM INTERACTION END ### [ 154s] [ 154s] lamb15 failed "build cellmgr-ng_1.4.7.20170421.dsc" at Fri Apr 21 20:02:43 UTC 2017. [ 154s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Fri Apr 21 20:03:50 2017 From: admin at opensuse.org (OBS Notification) Date: Fri, 21 Apr 2017 20:03:50 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in Debian_8.0/i586 In-Reply-To: References: Message-ID: <58fa65b0f3e53_1e2461ef7c156980@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/Debian_8.0/i586 Package network:osmocom:nightly/osmo-stp failed to build in Debian_8.0/i586 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 130s] CC vty_interface.o [ 131s] CC sctp_m3ua_client.o [ 131s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 131s] #include [ 131s] ^ [ 131s] compilation terminated. [ 131s] Makefile:475: recipe for target 'sctp_m3ua_client.o' failed [ 131s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 131s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 131s] Makefile:370: recipe for target 'all-recursive' failed [ 131s] make[2]: *** [all-recursive] Error 1 [ 131s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 131s] Makefile:310: recipe for target 'all' failed [ 131s] make[1]: *** [all] Error 2 [ 131s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 131s] dh_auto_build: make -j1 returned exit code 2 [ 131s] debian/rules:23: recipe for target 'build' failed [ 131s] make: *** [build] Error 2 [ 131s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 131s] [ 131s] cloud116 failed "build cellmgr-ng_1.4.7.20170421.dsc" at Fri Apr 21 20:03:30 UTC 2017. [ 131s] [ 131s] ### VM INTERACTION START ### [ 133s] Powering off. [ 133s] [ 103.297928] reboot: Power down [ 141s] ### VM INTERACTION END ### [ 141s] [ 141s] cloud116 failed "build cellmgr-ng_1.4.7.20170421.dsc" at Fri Apr 21 20:03:40 UTC 2017. [ 141s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Fri Apr 21 20:03:50 2017 From: admin at opensuse.org (OBS Notification) Date: Fri, 21 Apr 2017 20:03:50 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in xUbuntu_16.10/i586 In-Reply-To: References: Message-ID: <58fa65b136f70_1e2461ef7c1570be@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/xUbuntu_16.10/i586 Package network:osmocom:nightly/osmo-stp failed to build in xUbuntu_16.10/i586 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 75s] ^~~~~~~ [ 75s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o vty_interface.o vty_interface.c [ 76s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o sctp_m3ua_client.o sctp_m3ua_client.c [ 76s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 76s] #include [ 76s] ^ [ 76s] compilation terminated. [ 76s] Makefile:485: recipe for target 'sctp_m3ua_client.o' failed [ 76s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 76s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 76s] Makefile:380: recipe for target 'all-recursive' failed [ 76s] make[2]: *** [all-recursive] Error 1 [ 76s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 76s] Makefile:321: recipe for target 'all' failed [ 76s] make[1]: *** [all] Error 2 [ 76s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 76s] dh_auto_build: make -j1 returned exit code 2 [ 76s] debian/rules:23: recipe for target 'build' failed [ 76s] make: *** [build] Error 2 [ 76s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 76s] [ 76s] lamb73 failed "build cellmgr-ng_1.4.7.20170421.dsc" at Fri Apr 21 20:03:39 UTC 2017. [ 76s] [ 76s] ### VM INTERACTION START ### [ 79s] [ 66.267202] reboot: Power down [ 79s] ### VM INTERACTION END ### [ 79s] [ 79s] lamb73 failed "build cellmgr-ng_1.4.7.20170421.dsc" at Fri Apr 21 20:03:42 UTC 2017. [ 79s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Fri Apr 21 20:04:24 2017 From: admin at opensuse.org (OBS Notification) Date: Fri, 21 Apr 2017 20:04:24 +0000 Subject: Build failure of network:osmocom:nightly/libosmo-sccp in xUbuntu_16.10/x86_64 In-Reply-To: References: Message-ID: <58fa65e6bbbed_1e2461ef7c157150@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/libosmo-sccp/xUbuntu_16.10/x86_64 Package network:osmocom:nightly/libosmo-sccp failed to build in xUbuntu_16.10/x86_64 Check out the package for editing: osc checkout network:osmocom:nightly libosmo-sccp Last lines of build log: [ 132s] ./src/xua_asp_fsm.c:772: undefined reference to `ipa_ccm_send_id_req' [ 132s] ../../src/.libs/libosmo-sigtran.a(ipa.o): In function `ipa_tx_xua_as': [ 132s] ./src/ipa.c:71: undefined reference to `ipa_msg_alloc' [ 132s] collect2: error: ld returned 1 exit status [ 132s] Makefile:360: recipe for target 'xua_test' failed [ 132s] make[4]: *** [xua_test] Error 1 [ 132s] make[4]: Leaving directory '/usr/src/packages/BUILD/tests/xua' [ 132s] Makefile:362: recipe for target 'all-recursive' failed [ 132s] make[3]: *** [all-recursive] Error 1 [ 132s] make[3]: Leaving directory '/usr/src/packages/BUILD/tests' [ 132s] Makefile:454: recipe for target 'all-recursive' failed [ 132s] make[2]: *** [all-recursive] Error 1 [ 132s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 132s] Makefile:372: recipe for target 'all' failed [ 132s] make[1]: *** [all] Error 2 [ 132s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 132s] dh_auto_build: make -j1 returned exit code 2 [ 132s] debian/rules:12: recipe for target 'build' failed [ 132s] make: *** [build] Error 2 [ 132s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 132s] [ 132s] build34 failed "build libosmo-sccp_0.7.1.20170421.dsc" at Fri Apr 21 20:04:15 UTC 2017. [ 132s] [ 132s] ### VM INTERACTION START ### [ 135s] [ 116.472741] reboot: Power down [ 135s] ### VM INTERACTION END ### [ 135s] [ 135s] build34 failed "build libosmo-sccp_0.7.1.20170421.dsc" at Fri Apr 21 20:04:19 UTC 2017. [ 135s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Fri Apr 21 20:04:41 2017 From: admin at opensuse.org (OBS Notification) Date: Fri, 21 Apr 2017 20:04:41 +0000 Subject: Build failure of network:osmocom:nightly/libosmo-sccp in xUbuntu_16.04/x86_64 In-Reply-To: References: Message-ID: <58fa660667cb6_1e2461ef7c15728b@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/libosmo-sccp/xUbuntu_16.04/x86_64 Package network:osmocom:nightly/libosmo-sccp failed to build in xUbuntu_16.04/x86_64 Check out the package for editing: osc checkout network:osmocom:nightly libosmo-sccp Last lines of build log: [ 102s] /usr/src/packages/BUILD/src/xua_asp_fsm.c:772: undefined reference to `ipa_ccm_send_id_req' [ 102s] ../../src/.libs/libosmo-sigtran.a(ipa.o): In function `ipa_tx_xua_as': [ 102s] /usr/src/packages/BUILD/src/ipa.c:71: undefined reference to `ipa_msg_alloc' [ 102s] collect2: error: ld returned 1 exit status [ 102s] Makefile:360: recipe for target 'xua_test' failed [ 102s] make[4]: *** [xua_test] Error 1 [ 102s] make[4]: Leaving directory '/usr/src/packages/BUILD/tests/xua' [ 102s] Makefile:362: recipe for target 'all-recursive' failed [ 102s] make[3]: *** [all-recursive] Error 1 [ 102s] make[3]: Leaving directory '/usr/src/packages/BUILD/tests' [ 102s] Makefile:454: recipe for target 'all-recursive' failed [ 102s] make[2]: *** [all-recursive] Error 1 [ 102s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 102s] Makefile:372: recipe for target 'all' failed [ 102s] make[1]: *** [all] Error 2 [ 102s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 102s] dh_auto_build: make -j1 returned exit code 2 [ 102s] debian/rules:12: recipe for target 'build' failed [ 102s] make: *** [build] Error 2 [ 102s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 102s] [ 102s] build73 failed "build libosmo-sccp_0.7.1.20170421.dsc" at Fri Apr 21 20:04:29 UTC 2017. [ 102s] [ 102s] ### VM INTERACTION START ### [ 105s] [ 93.643460] reboot: Power down [ 105s] ### VM INTERACTION END ### [ 105s] [ 105s] build73 failed "build libosmo-sccp_0.7.1.20170421.dsc" at Fri Apr 21 20:04:32 UTC 2017. [ 105s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Fri Apr 21 20:04:41 2017 From: admin at opensuse.org (OBS Notification) Date: Fri, 21 Apr 2017 20:04:41 +0000 Subject: Build failure of network:osmocom:nightly/libosmo-sccp in Debian_8.0/x86_64 In-Reply-To: References: Message-ID: <58fa6606d6b9f_1e2461ef7c157334@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/libosmo-sccp/Debian_8.0/x86_64 Package network:osmocom:nightly/libosmo-sccp failed to build in Debian_8.0/x86_64 Check out the package for editing: osc checkout network:osmocom:nightly libosmo-sccp Last lines of build log: [ 108s] CCLD xua_test [ 109s] /usr/bin/ld: ../../src/.libs/libosmo-sigtran.a(osmo_ss7.o): undefined reference to symbol 'ipa_msg_recv_buffered@@LIBOSMOGSM_1.0' [ 109s] //usr/lib/x86_64-linux-gnu/libosmogsm.so.6: error adding symbols: DSO missing from command line [ 109s] collect2: error: ld returned 1 exit status [ 109s] Makefile:348: recipe for target 'xua_test' failed [ 109s] make[4]: *** [xua_test] Error 1 [ 109s] make[4]: Leaving directory '/usr/src/packages/BUILD/tests/xua' [ 109s] Makefile:350: recipe for target 'all-recursive' failed [ 109s] make[3]: *** [all-recursive] Error 1 [ 109s] make[3]: Leaving directory '/usr/src/packages/BUILD/tests' [ 109s] Makefile:443: recipe for target 'all-recursive' failed [ 109s] make[2]: *** [all-recursive] Error 1 [ 109s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 109s] Makefile:360: recipe for target 'all' failed [ 109s] make[1]: *** [all] Error 2 [ 109s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 109s] dh_auto_build: make -j1 returned exit code 2 [ 109s] debian/rules:12: recipe for target 'build' failed [ 109s] make: *** [build] Error 2 [ 109s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 109s] [ 109s] lamb64 failed "build libosmo-sccp_0.7.1.20170421.dsc" at Fri Apr 21 20:04:31 UTC 2017. [ 109s] [ 109s] ### VM INTERACTION START ### [ 110s] Powering off. [ 110s] ### VM INTERACTION END ### [ 110s] [ 110s] lamb64 failed "build libosmo-sccp_0.7.1.20170421.dsc" at Fri Apr 21 20:04:33 UTC 2017. [ 110s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Fri Apr 21 20:07:32 2017 From: admin at opensuse.org (OBS Notification) Date: Fri, 21 Apr 2017 20:07:32 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in xUbuntu_16.10/x86_64 In-Reply-To: References: Message-ID: <58fa669b4a8ad_1bc39c0f7c178122@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/xUbuntu_16.10/x86_64 Package network:osmocom:nightly/osmo-stp failed to build in xUbuntu_16.10/x86_64 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 143s] ^~~~~~~ [ 143s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o vty_interface.o vty_interface.c [ 144s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o sctp_m3ua_client.o sctp_m3ua_client.c [ 144s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 144s] #include [ 144s] ^ [ 144s] compilation terminated. [ 144s] Makefile:485: recipe for target 'sctp_m3ua_client.o' failed [ 144s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 144s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 144s] Makefile:380: recipe for target 'all-recursive' failed [ 144s] make[2]: *** [all-recursive] Error 1 [ 144s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 144s] Makefile:321: recipe for target 'all' failed [ 144s] make[1]: *** [all] Error 2 [ 144s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 144s] dh_auto_build: make -j1 returned exit code 2 [ 144s] debian/rules:23: recipe for target 'build' failed [ 144s] make: *** [build] Error 2 [ 144s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 144s] [ 144s] lamb27 failed "build cellmgr-ng_1.4.7.20170421.dsc" at Fri Apr 21 20:07:19 UTC 2017. [ 144s] [ 144s] ### VM INTERACTION START ### [ 148s] [ 122.616997] reboot: Power down [ 148s] ### VM INTERACTION END ### [ 148s] [ 148s] lamb27 failed "build cellmgr-ng_1.4.7.20170421.dsc" at Fri Apr 21 20:07:22 UTC 2017. [ 148s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Fri Apr 21 20:08:06 2017 From: admin at opensuse.org (OBS Notification) Date: Fri, 21 Apr 2017 20:08:06 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in Debian_8.0/x86_64 In-Reply-To: References: Message-ID: <58fa66bc53cc_1bbd9c0f7c171482@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/Debian_8.0/x86_64 Package network:osmocom:nightly/osmo-stp failed to build in Debian_8.0/x86_64 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 172s] ^ [ 172s] CC vty_interface.o [ 173s] CC sctp_m3ua_client.o [ 173s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 173s] #include [ 173s] ^ [ 173s] compilation terminated. [ 173s] Makefile:475: recipe for target 'sctp_m3ua_client.o' failed [ 173s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 173s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 173s] Makefile:370: recipe for target 'all-recursive' failed [ 173s] make[2]: *** [all-recursive] Error 1 [ 173s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 173s] Makefile:310: recipe for target 'all' failed [ 173s] make[1]: *** [all] Error 2 [ 173s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 173s] dh_auto_build: make -j1 returned exit code 2 [ 173s] debian/rules:23: recipe for target 'build' failed [ 173s] make: *** [build] Error 2 [ 173s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 173s] [ 173s] lamb66 failed "build cellmgr-ng_1.4.7.20170421.dsc" at Fri Apr 21 20:07:53 UTC 2017. [ 173s] [ 173s] ### VM INTERACTION START ### [ 175s] Powering off. [ 175s] ### VM INTERACTION END ### [ 175s] [ 175s] lamb66 failed "build cellmgr-ng_1.4.7.20170421.dsc" at Fri Apr 21 20:07:55 UTC 2017. [ 175s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Fri Apr 21 20:08:06 2017 From: admin at opensuse.org (OBS Notification) Date: Fri, 21 Apr 2017 20:08:06 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in xUbuntu_16.04/x86_64 In-Reply-To: References: Message-ID: <58fa66bcb89ef_1bbd9c0f7c1715b6@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/xUbuntu_16.04/x86_64 Package network:osmocom:nightly/osmo-stp failed to build in xUbuntu_16.04/x86_64 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 166s] sctp_m2ua.c:91:3: warning: #warning "Notify any other AS(P) for failover scenario" [-Wcpp] [ 166s] #warning "Notify any other AS(P) for failover scenario" [ 166s] ^ [ 167s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -c -o vty_interface.o vty_interface.c [ 167s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -c -o sctp_m3ua_client.o sctp_m3ua_client.c [ 167s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 167s] compilation terminated. [ 167s] Makefile:485: recipe for target 'sctp_m3ua_client.o' failed [ 167s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 167s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 167s] Makefile:380: recipe for target 'all-recursive' failed [ 167s] make[2]: *** [all-recursive] Error 1 [ 167s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 167s] Makefile:321: recipe for target 'all' failed [ 167s] make[1]: *** [all] Error 2 [ 167s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 167s] dh_auto_build: make -j1 returned exit code 2 [ 167s] debian/rules:23: recipe for target 'build' failed [ 167s] make: *** [build] Error 2 [ 167s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 167s] [ 167s] lamb28 failed "build cellmgr-ng_1.4.7.20170421.dsc" at Fri Apr 21 20:07:44 UTC 2017. [ 167s] [ 167s] ### VM INTERACTION START ### [ 171s] [ 151.218066] reboot: Power down [ 171s] ### VM INTERACTION END ### [ 171s] [ 171s] lamb28 failed "build cellmgr-ng_1.4.7.20170421.dsc" at Fri Apr 21 20:07:49 UTC 2017. [ 171s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From gerrit-no-reply at lists.osmocom.org Sat Apr 22 10:12:11 2017 From: gerrit-no-reply at lists.osmocom.org (Holger Freyther) Date: Sat, 22 Apr 2017 10:12:11 +0000 Subject: [PATCH] libosmo-netif[master]: misc: Call the variable ctx like in all other places In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2284 to look at the new patch set (#2). misc: Call the variable ctx like in all other places We couldn't figure out what "crx" as supposed to mean and assume it is a typo. Fix the code and call it ctx, this is fixing the API documentation as well. Change-Id: I27ed1178fdbbcf3fc0e1070dc19b4ecf9a327a04 --- M include/osmocom/netif/datagram.h M src/datagram.c 2 files changed, 11 insertions(+), 11 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-netif refs/changes/84/2284/2 diff --git a/include/osmocom/netif/datagram.h b/include/osmocom/netif/datagram.h index b7ecfe3..a0ff7b4 100644 --- a/include/osmocom/netif/datagram.h +++ b/include/osmocom/netif/datagram.h @@ -3,7 +3,7 @@ struct osmo_dgram_tx; -struct osmo_dgram_tx *osmo_dgram_tx_create(void *crx); +struct osmo_dgram_tx *osmo_dgram_tx_create(void *ctx); void osmo_dgram_tx_destroy(struct osmo_dgram_tx *conn); void osmo_dgram_tx_set_addr(struct osmo_dgram_tx *conn, const char *addr); @@ -19,7 +19,7 @@ struct osmo_dgram_rx; -struct osmo_dgram_rx *osmo_dgram_rx_create(void *crx); +struct osmo_dgram_rx *osmo_dgram_rx_create(void *ctx); void osmo_dgram_rx_set_addr(struct osmo_dgram_rx *conn, const char *addr); void osmo_dgram_rx_set_port(struct osmo_dgram_rx *conn, uint16_t port); @@ -33,7 +33,7 @@ struct osmo_dgram; -struct osmo_dgram *osmo_dgram_create(void *crx); +struct osmo_dgram *osmo_dgram_create(void *ctx); void osmo_dgram_destroy(struct osmo_dgram *conn); int osmo_dgram_open(struct osmo_dgram *conn); diff --git a/src/datagram.c b/src/datagram.c index d98221f..c2c84e0 100644 --- a/src/datagram.c +++ b/src/datagram.c @@ -102,11 +102,11 @@ * This function allocates a new \ref osmo_dgram_tx and initializes * it with default values * \returns Osmocom Datagram Transmitter; NULL on error */ -struct osmo_dgram_tx *osmo_dgram_tx_create(void *crx) +struct osmo_dgram_tx *osmo_dgram_tx_create(void *ctx) { struct osmo_dgram_tx *conn; - conn = talloc_zero(crx, struct osmo_dgram_tx); + conn = talloc_zero(ctx, struct osmo_dgram_tx); if (!conn) return NULL; @@ -276,11 +276,11 @@ * This function allocates a new \ref osmo_dgram_rx and initializes * it with default values * \returns Datagram Receiver; NULL on error */ -struct osmo_dgram_rx *osmo_dgram_rx_create(void *crx) +struct osmo_dgram_rx *osmo_dgram_rx_create(void *ctx) { struct osmo_dgram_rx *conn; - conn = talloc_zero(crx, struct osmo_dgram_rx); + conn = talloc_zero(ctx, struct osmo_dgram_rx); if (!conn) return NULL; @@ -398,22 +398,22 @@ * it with default values. Internally, the Transceiver is based on a * tuple of transmitter (\ref osmo_dgram_tx) and receiver (\ref osmo_dgram_rx) * \returns Osmocom Datagram Transceiver; NULL on error */ -struct osmo_dgram *osmo_dgram_create(void *crx) +struct osmo_dgram *osmo_dgram_create(void *ctx) { struct osmo_dgram *conn; - conn = talloc_zero(crx, struct osmo_dgram); + conn = talloc_zero(ctx, struct osmo_dgram); if (!conn) return NULL; - conn->rx= osmo_dgram_rx_create(crx); + conn->rx= osmo_dgram_rx_create(ctx); if (conn->rx == NULL) return NULL; osmo_dgram_rx_set_read_cb(conn->rx, dgram_rx_cb); conn->rx->data = conn; - conn->tx = osmo_dgram_tx_create(crx); + conn->tx = osmo_dgram_tx_create(ctx); if (conn->tx == NULL) { osmo_dgram_rx_destroy(conn->rx); return NULL; -- To view, visit https://gerrit.osmocom.org/2284 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I27ed1178fdbbcf3fc0e1070dc19b4ecf9a327a04 Gerrit-PatchSet: 2 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Sat Apr 22 12:22:04 2017 From: gerrit-no-reply at lists.osmocom.org (Holger Freyther) Date: Sat, 22 Apr 2017 12:22:04 +0000 Subject: [PATCH] osmo-gsm-manuals[master]: First step towards an OsmoSTP manual In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2371 to look at the new patch set (#5). First step towards an OsmoSTP manual Change-Id: I450bfac7444ac9cb7f50c086d87cf7157c2e2a31 --- M Makefile A OsmoSTP/Makefile A OsmoSTP/chapters/overview.adoc A OsmoSTP/osmostp-usermanual-docinfo.xml A OsmoSTP/osmostp-usermanual.adoc A OsmoSTP/osmostp-vty-reference.xml A OsmoSTP/vty/stp_vty_reference.xml M common/chapters/bibliography.adoc M common/chapters/glossary.adoc A common/chapters/sigtran-osmocom.adoc A common/chapters/sigtran-simple-2g.dot A common/chapters/sigtran-simple-3g.dot A common/chapters/sigtran.adoc 13 files changed, 1,021 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-gsm-manuals refs/changes/71/2371/5 diff --git a/Makefile b/Makefile index 362f171..495ce41 100644 --- a/Makefile +++ b/Makefile @@ -7,6 +7,7 @@ cd OsmoNAT; $(MAKE) cd OsmoPCU; $(MAKE) cd Osmo-GSM-Tester; $(MAKE) + cd OsmoSTP; $(MAKE) clean: cd OsmoBTS; $(MAKE) clean @@ -17,6 +18,7 @@ cd OsmoNAT; $(MAKE) clean cd OsmoPCU; $(MAKE) clean cd Osmo-GSM-Tester; $(MAKE) clean + cd OsmoSTP; $(MAKE) clean upload: cd OsmoBTS; $(MAKE) upload @@ -27,6 +29,7 @@ cd OsmoNAT; $(MAKE) upload cd OsmoPCU; $(MAKE) upload cd Osmo-GSM-Tester; $(MAKE) upload + cd OsmoSTP; $(MAKE) upload check: cd OsmoBTS; $(MAKE) check @@ -34,6 +37,7 @@ cd OsmoBSC; $(MAKE) check cd OsmoSGSN; $(MAKE) check cd OsmoPCU; $(MAKE) check + cd OsmoSTP; $(MAKE) check # These don't use asciidoc, so they have no 'make check' target: #cd OsmoMGCP; $(MAKE) check #cd OsmoNAT; $(MAKE) check diff --git a/OsmoSTP/Makefile b/OsmoSTP/Makefile new file mode 100644 index 0000000..bf3ba8f --- /dev/null +++ b/OsmoSTP/Makefile @@ -0,0 +1,45 @@ +# XSL stylesheets downloaded from http://docbook.sourceforge.net/release/xsl/current/html/ +# Makefile from BitBake/OpenEmbedded manuals + + +EXTRA_DEPS = gen-stp-vty-docbook + +topdir = . +stp_reference = $(topdir)/osmostp-vty-reference.xml +manuals = $(stp_reference) +# types = pdf txt rtf ps xhtml html man tex texi dvi +# types = pdf txt +types = $(docbooktotypes) +docbooktotypes = pdf +# htmlcssfile = +# htmlcss = + +TOPDIR := .. +ASCIIDOCS := osmostp-usermanual + +include $(TOPDIR)/build/Makefile.asciidoc.inc +include $(TOPDIR)/build/Makefile.inc + +osmostp-usermanual.pdf: chapters/*.adoc + +clean: + -rm -rf $(cleanfiles) + -rm osmostp-usermanual__*.png + -rm osmostp-usermanual__*.svg + -rm osmostp-usermanual*.check + +gen-stp-vty-docbook: FORCE + $(call command,xsltproc -o generated/combined1.xml \ + --stringparam with $(PWD)/../common/vty_additions.xml \ + $(MERGE_DOC) vty/stp_vty_reference.xml, \ + XSLTPROC,Merging Common VTY) + $(call command,xsltproc -o generated/combined2.xml \ + --stringparam with $(PWD)/../common/stp_vty_additions.xml \ + $(MERGE_DOC) generated/combined1.xml, \ + XSLTPROC,Merging Common STP VTY) + $(call command,xsltproc -o generated/combined3.xml \ + --stringparam with $(PWD)/vty/stp_vty_additions.xml \ + $(MERGE_DOC) generated/combined2.xml, \ + XSLTPROC,Merging STP VTY) + $(call command,xsltproc ../vty_reference.xsl generated/combined3.xml > generated/docbook_vty.xml, \ + XSLTPROC,Converting STP VTY to DocBook) diff --git a/OsmoSTP/chapters/overview.adoc b/OsmoSTP/chapters/overview.adoc new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/OsmoSTP/chapters/overview.adoc diff --git a/OsmoSTP/osmostp-usermanual-docinfo.xml b/OsmoSTP/osmostp-usermanual-docinfo.xml new file mode 100644 index 0000000..4253957 --- /dev/null +++ b/OsmoSTP/osmostp-usermanual-docinfo.xml @@ -0,0 +1,47 @@ + + + 1 + April 16, 2017 + HW + + Initial OsmoSTP manual + + + + + + + Harald + Welte + hwelte at sysmocom.de + HW + + sysmocom + sysmocom - s.f.m.c. GmbH + Managing Director + + + + + + 2012-2017 + sysmocom - s.f.m.c. GmbH + + + + + Permission is granted to copy, distribute and/or modify this + document under the terms of the GNU Free Documentation License, + Version 1.3 or any later version published by the Free Software + Foundation; with the Invariant Sections being just 'Foreword', + 'Acknowledgements' and 'Preface', with no Front-Cover Texts, + and no Back-Cover Texts. A copy of the license is included in + the section entitled "GNU Free Documentation License". + + + The Asciidoc source code of this manual can be found at + + http://git.osmocom.org/osmo-gsm-manuals/ + + + diff --git a/OsmoSTP/osmostp-usermanual.adoc b/OsmoSTP/osmostp-usermanual.adoc new file mode 100644 index 0000000..2be3372 --- /dev/null +++ b/OsmoSTP/osmostp-usermanual.adoc @@ -0,0 +1,33 @@ +OsmoSTP User Manual +=================== +Harald Welte + + +include::../common/chapters/preface.adoc[] + +// include::chapters/overview.adoc[] + +include::../common/chapters/sigtran.adoc[] +include::../common/chapters/sigtran-osmocom.adoc[] + +//include::chapters/running.adoc[] +// include::chapters/control.adoc[] + +include::../common/chapters/vty.adoc[] + +include::../common/chapters/logging.adoc[] + +//include::../common/chapters/bts.adoc[] + +//include::../OsmoNITB/chapters/bts-examples.adoc[] + +//include::../common/chapters/control_if.adoc[] + +include::../common/chapters/port_numbers.adoc[] + +include::../common/chapters/bibliography.adoc[] + +include::../common/chapters/glossary.adoc[] + +include::../common/chapters/gfdl.adoc[] + diff --git a/OsmoSTP/osmostp-vty-reference.xml b/OsmoSTP/osmostp-vty-reference.xml new file mode 100644 index 0000000..807d427 --- /dev/null +++ b/OsmoSTP/osmostp-vty-reference.xml @@ -0,0 +1,38 @@ + + + + +]> + + + + + + v1 + April 16, 2017 + h2 + Initial + + + + OsmoSTP VTY Reference + + + 2012-2017 + + + + This work is copyright by sysmocom - s.f.m.c. GmbH. All rights reserved. + + + + + + &chapter-vty; + + diff --git a/OsmoSTP/vty/stp_vty_reference.xml b/OsmoSTP/vty/stp_vty_reference.xml new file mode 100644 index 0000000..a4c675e --- /dev/null +++ b/OsmoSTP/vty/stp_vty_reference.xml @@ -0,0 +1,2 @@ + + diff --git a/common/chapters/bibliography.adoc b/common/chapters/bibliography.adoc index a3c6436..d5e1c1b 100644 --- a/common/chapters/bibliography.adoc +++ b/common/chapters/bibliography.adoc @@ -106,11 +106,29 @@ https://tools.ietf.org/html/rfc1350 - [[[ietf-rfc2131]]] IETF RFC 2131: Dynamic Host Configuration Protocol https://tools.ietf.org/html/rfc2131 +- [[[ietf-rfc2719]]] IETF RFC 2719: Signal Transport over IP + https://tools.ietf.org/html/rfc2719 +- [[[ietf-rfc3331]]] IETF RFC 3331: Message Transfer Part 2 User Adaptation Layer + https://tools.ietf.org/html/rfc3331 - [[[ietf-rfc3550]]] IETF RFC 3550: RTP: A Transport protocol for Real-Time Applications https://tools.ietf.org/html/rfc3550 +- [[[ietf-rfc3868]]] IETF RFC 3868: SCCP User Adaptation Layer + https://tools.ietf.org/html/rfc3868 +- [[[ietf-rfc4165]]] IETF RFC 4165: Message Transfer Part 2 Peer-to-Peeer Adaptation Layer + https://tools.ietf.org/html/rfc4165 - [[[ietf-rfc4251]]] IETF RFC 4251: The Secure Shell (SSH) Protocol Architecture https://tools.ietf.org/html/rfc4251 +- [[[ietf-rfc4666]]] IETF RFC 4666: Message Transfer Part 3 User Adaptation Layer + https://tools.ietf.org/html/rfc4666 +- [[[itu-t-q701]]] ITU-T Q.701: Functional Description of the Message Transfer Part (MTP) + https://www.itu.int/rec/T-REC-Q.701/en/ +- [[[itu-t-q711]]] ITU-T Q.711: Functional Description of the Signalling Connection Control Part + https://www.itu.int/rec/T-REC-Q.711/en/ +- [[[itu-t-q713]]] ITU-T Q.713: Signalling connection control part formats and codes + https://www.itu.int/rec/T-REC-Q.713/en/ +- [[[itu-t-q714]]] ITU-T Q.714: Signalling connection control part procedures + https://www.itu.int/rec/T-REC-Q.714/en/ - [[[itu-t-q921]]] ITU-T Q.921: ISDN user-network interface - Data link layer specification https://www.itu.int/rec/T-REC-Q.921/en diff --git a/common/chapters/glossary.adoc b/common/chapters/glossary.adoc index c39d439..042fd3a 100644 --- a/common/chapters/glossary.adoc +++ b/common/chapters/glossary.adoc @@ -115,6 +115,8 @@ GSMTAP:: GSM tap; pseudo standard for encapsulating GSM protocol layers over UDP/IP for analysis +GT:: + Global Title; an address in SCCP GTP:: GPRS Tunnel Protocol; used between SGSN and GGSN HLR:: @@ -143,6 +145,12 @@ 44.064_ <<3gpp-ts-44-064>>) Location Area:: Location Area; a geographic area containing multiple BTS +M2PA:: + MTP2 Peer-to-Peer Adaptation; a SIGTRAN Variant (_RFC 4165_ <>) +M2UA:: + MTP2 User Adaptation; a SIGTRAN Variant (_RFC 3331_ <>) +M3UA:: + MTP3 User Adaptation; a SIGTRAN Variant (_RFC 4666_ <>) MCC:: Mobile Country Code; unique identifier of a country, e.g. 262 for Germany MFF:: @@ -163,6 +171,8 @@ core network MSISDN:: Mobile Subscriber ISDN Number; telephone number of the subscriber +MTP:: + Message Transfer Part; SS7 signaling protocol (_ITU-T Q.701_ <>) MVNO:: Mobile Virtual Network Operator; Operator without physical radio network NCC:: @@ -206,6 +216,8 @@ OTA:: Over-The-Air; Capability of operators to remotely reconfigure/reprogram ISM/USIM cards +PC:: + Point Code; an address in MTP PCH:: Paging Channel on downlink Um interface; used by network to page an MS PCU:: @@ -249,11 +261,15 @@ SACCH:: Slow Associate Control Channel on Um interface; bundled to a TCH or SDCCH, used for signalling in parallel to active dedicated channel +SCCP:: + Signaling Connection Control Part; SS7 signaling protocol (_ITU-T Q.711_ <>) SDCCH:: Slow Dedicated Control Channel on Um interface; used for signalling and SMS transport in GSM SDK:: Software Development Kit +SIGTRAN:: + Signaling Transport over IP (_IETF RFC 2719_ <>) SIM:: Subscriber Identity Module; small chip card storing subscriber identity Site:: @@ -264,8 +280,16 @@ entities with an SMSC SMSC:: Short Message Service Center; store-and-forward relay for short messages +SS7:: + Signaling System No. 7; Classic digital telephony signaling system SSH:: Secure Shell; _IETF RFC 4250_ <> to 4254 +SSN:: + Sub-System Number; identifies a given SCCP Service such as MSC, HLR +STP:: + Signaling Transfer Point; A Router in SS7 Networks +SUA:: + SCCP User Adaptation; a SIGTRAN Variant (_RFC 3868_ <>) syslog:: System logging service of UNIX-like operating systems System Information:: diff --git a/common/chapters/sigtran-osmocom.adoc b/common/chapters/sigtran-osmocom.adoc new file mode 100644 index 0000000..1e08733 --- /dev/null +++ b/common/chapters/sigtran-osmocom.adoc @@ -0,0 +1,432 @@ +== Osmocom SS7 + SIGTRAN support + +=== History / Background + +If you're upgrading from earlier releases of the Osmocom stack, this +section will give you some background about the evolution. + +==== The Past (before 2017) + +In the original implementation of the GSM BSC inside Osmocom (the +OsmoBSC program, part of OpenBSC), no SS7 support was included. + +This is despite the fact that ETSI/3GPP mandated the use of SCCP over +MTP over E1/T1 TDM lines for the A interface at that time. + +Instead of going down to the TDM based legacy physical layers, OsmoBSC +implemented someting called an IPA multiplex, which apparently some +people also refer to as SCCPlite. We have never seen any +specifications for this interface, but implemented it from scratch +using protocol traces. + +The IPA protocol stack is based on a minimal sub-set of SCCP +(including connection oriented SCCP) wrapped into a 3-byte header to +packetize a TCP stream. + +The IPA/SCCPlite based A interface existed at a time when the +ETSI/3GPP specifications did not offer any IP based transport for the +A interface. An official as added only in Release FIXME of the 3GPP +specifications. + +The A interface BSSMAP protocol refers to voice circuits (E1/T1 +timeslots) using circuit identity codes (CICs). As there are no +physical timeslots on a TCP/IP based transport layer, the CICs get +mapped to RTP streams for circuit-switched data using out-of-band +signaling via MGCP, the IETF-standardized Media Gateway Control +Protocol. + +==== The present (2017) + +In 2017, sysmocom was tasked with implementing a 3GPP AoIP compliant A +interface. This meant that lot of things had to change in the +existing code: + +* removal of the existing hard-wired SCCPlite/IPA code from OsmoBSC +* introduction of a formal SCCP User SAP at the lower boundary of + BSSMAP +* introduction of libosmo-sigtran, a comprehensive SS7 and SIGTRAN + library which includes a SCCP implementation for connectionless and + connection-oriented procedures, offering the SCCP User SAP towards + BSSAP +* introduction of an A interface in OsmoMSC (which so far offered Iu + only) +* port of the existing SUA-baesd IuCS and IuPS over to the SCCP User + SAP of libosmo-sigtran. +* Implementation of ETSI M3UA as preferred/primary transport layer for + SCCP +* Implementation of an IPA transport layer inside libosmo-sigtran, in + order to keep backwards-compatibility. + +This work enables the Osmocom universe to become more compliant +with modern Releases of 3GPP specifications, which enables +interoperability with other MSCs or even BSCs. However, this comes at +a price: Increased complexity in set-up and configuration. + +Using SS7 or SIGTRAN based transport of the A interface adds an +entirely new domain that needs to be understood by system and network +administrators setting up cellular networks based on Osmocom. + +One of the key advantages of the Osmocom architecture with OsmoNITB +was exactly this simplification and reduction of complexity, enabling +more people to set-up and operate cellular networks. + +So we have put some thought into how we can achieve compatibility with +SS7/SIGTRAN and the 3GPP specifications, while at the same time +enabling some degree of auto-configuration where a small network can +be set up without too many configuration related to the signaling +network. We have achieved this by "abusing" (or extending) the M3UA +Routing Key Management slightly. + +=== Osmocom extensions to SIGTRAN + +Osmocom has implemented some extensions to the SIGTRAN protocol suite. +Those extensions will be documented below. + +==== Osmocom M3UA Routing Key Management Extensions + +In classic M3UA, a peer identifies its remote peer based on IP address +and port details. So once an ASP connects to an SG, the SG will check +if there is any configuration that matches the source IP (and possibly +source port) of that connection in order to understand which routing +context is used - and subsequently which traffic is to be routed to +this M3UA peer. + +This is quite inflexible, as it means that every BSC in a GSM network +needs to be manually pre-configured at the SG/STP, and that +configuration on the BSC and MSC must match to enable communication. + +M3UA specifies an optional Routing Key Management (RKM) sub-protocol. +Using RKM, an ASP can dynamically tell the SG/STP, which traffic it +wants to receive. However, the idea is still that the SG has some +matching configuration. + +In OsmoSTP based on libosmo-sigtran, we decided to (optionally) enable +fully dynamic registration. This means that any ASP can simply +connect to the SG and request the dynamic creation of an ASP and AS +with a corresponding routing key for a given point code. As long as +the SG doesn't already have a route to this requested point code, The +SG will simply trust any ASP and set a corresponding route. + +This is of course highly insecure and can only be used in trusted, +internal newtworks. However, it is quite elegant in reducing the +amount of configuration complexity. All that is needed, is that an +unique point code is configured at each of the ASPs (application +programs) that connect to the STP. + +To put things more concretely: Each BSC and MSC connecting to OsmoSTP +simply needs to be configured to have a different point code, and to +know to which IP/port of the STP to connect. There's no other +configuration required for a small, autonomous, self-contained +network. OsmoSTP will automatically insall ASP, AS and route +definitions on demand, and route messages between all connected +entities. + +The same above of course also applies to HNB-GW and OsmoSGSN in the +case of Iu interfaces. + +==== IPA / SCCPlite backwards compatibility + +The fundamental problem with IPA/SCCPlite is that there's no MTP +routing label surrounding the SCCP message. This is generally +problematic in the context of connection-oriented SCCP, as there is no +addressing information inside the SCCP messages after the connection +has been established. Instead, the messages are routed based on the +MTP label, containing point codes established during connection set-up +time. + +This means that even if the SCCP messages did contain Called/Calling +Party Addresses with point codes or global titles, it would only help +us for routing connectionless SCCP. The A interface, however, is +connection-oriented. + +So in order to integrate IPA/SCCPlite with a new full-blown +SS7/SIGTRAN stack, there are the following options: + +. implement SCCP connection coupling. This is something like a proxy + for connection-oriented SCCP, and is what is used in SS7 to route + beyond a given MTP netwokr (e.g. at gateways between different MTP + networks) + +. consider all SCCP messages to be destined for the local point code + of the receiver. This then means that the SG functionality must be + included inside the MSC, and the MSC be bound to the SSN on the + local point code. + +. hard-code some DPC when receiving a message from an IPA connection. + It could be any remote PC and we'd simply route the message towards + that point code. + +But then we also have the return direction: + +. We could "assign" a unique SPC to each connected IPA client (BSC), + and then announce that PC towards the SS7 side. Return packets + would then end up at our IPA-server-bearing STP, which forwards them + to the respective IPA connection and thus BSC. On the transmit + side, we'd simply strip the MTP routing label and send the raw SCCP + message over IPA. + +. If the IPA server / SGW resides within the MSC, one could also have + some kind of handle/reference to the specific TCP connection through + which the BSC connected. All responses for a given peer would then + have to be routed back to the same connection. This is quite ugly + as it completely breaks the concepts of the SCCP User SAP, where a + user has no information (nor to worry about ) any "physical" + signaling links. + + +=== Minimal Osmocom SIGTRAN configurations for small networks + +If you're not an SS7 expert, and all you want is to run your own small +self-contained cellular network, this section explains what you need +to do. + +In general, you can consider OsmoSTP as something like an IP router. +On the application layer (in our case the BSSAP/BSSMAP or RANAP +protocols between Radio Access Network and Core Network), it is +completely invisible/transparent. The BSC connects via SCCP to the +MSC. It doesn't know that there's an STP in between, and that this +STP is performing some routing function. Compares this to your web +browser not knowing about IP routers, it just establishes an http +connection to a web server. + +This is also why most GSM nework architecture diagrams will not +explicitly show an STP. It is not part of the cellular network. +Rather, one or many STPs are part of the underlying SS7 signaling +transport network, on top of which the cellular network elements are +built. + +==== A minimal 2G configuration to get started + +You will be running the following programs: + +* OsmoBSC as the base-station controller between your BTS (possibly + running OsmoBTS) and the MSC +* OsmoMSC as the mobile switching center providing SMS and telephony + service to your subscribers +* OsmoSTP as the signal transfer point, routing messages between one + or more BSCs and the MSC + +[[fig-sigtran-simple-2g]] +.Simple signaling network for 2G (GSM) +[graphviz] +---- +include::sigtran-simple-2g.dot[] +---- + +You can use the OsmoSTP fully dynamic registration feature, so the BSCs +and the MSC will simply register with their point codes to the STP, +and the STP will create most configuration on the fly. + +All you need to make sure is: + +* to assign one unique point code to each BSC and MSC +* to point all BSCs and the MSC to connect to the IP+Port of the STP +* to configure the point code of the MSC in the BSCs + +==== A minimaal 3G configuration to get started + +You will be running the following programs: + +* OsmoHNBGW as the homeNodeB Gateway between your femtocells / small + cells and the MSC+SGSN +* OsmoMSC as the mobile switching center providing SMS and telephony + service to your subscribers +* OsmoSGSN as the Serving GPRS Support Node, providing packet data + (internet) services to your subscribers +* OsmoSTP as the signal transfer point, routing messages between one + or more HNBGWs and the MSC and SGSN + +[[fig-sigtran-simple-3g]] +.Simple signaling network for 3G (UMTS) +[graphviz] +---- +include::sigtran-simple-3g.dot[] +---- + +You can use the OsmoSTP fully dynamic registration feature, so the +HNBGWs, the SMC and the SGSNwill simply register with their point +codes to the STP, and the STP will create most configuration on the +fly. + +All you need to make sure is: + +* to assign one unique point code to each HNBGW, MSC and SGSN +* to point all HNBGWs and the MSC and SGSN to connect to the IP+Port of STP +* to configure the point code of the MSC in the HNBGWs +* to configure the point code of the SGSN in the HNBGWs + +=== Osmocom SS7 Instances + +The entire SS7 stack can be operated multiple times within one +application/program by means of so-called SS7 Instances. + +There can be any number of SS7 Instances, and each instance has its +own set of XUA Servers, ASPs, ASs, Routes, etc. + +Each SS7 Instance can have different point code formats / lengths. + +.Major Attributes of an Osmocom SS7 Instance +[options="header",cols="25%,35%,40%"] +|==== +|Name|VTY Command|Description +|ID|(config)# cs7 instance ID|The numeric identifier of this instance +|Name|(config-cs7)# name NAME|A human-readable name for this instance +|Description|(cnfig-cs7)# description DESC| More verbose description +|Primary PC|(config-cs7)# point-code PC|Primary local point code +|Network Indicator|(config-cs7)# network-indicator|Network Indicator used in MTP3 Routing Label +|Point Code Format|(config-cs7)# point-code format|Point Code Format (Default: 3.8.3) +|Point Code Delimiter|(config-cs7)# point-code delimiter|Point Code Delimiter: . or - +|==== + +=== Osmocom SS7 xUA Server + +A *xUA Server* is a server that binds + listens to a given SCTP +(SIGTRAN) or TCP (IPA) port and accepts connections from remote peers +(ASPs). + +There can be any number of xUA Servers within one SS7 Instance, as +long as they all run on a different combination of IP address and +port. + +.Major Attributes of an Osmocom SS7 xUA Server +[options="header",cols="25%,75%"] +|==== +|Name|Description +|Local IP|Local Port Number to which the server shall bind/listen +|Local Port|Local IP Address to which the server shall bind/listen +|Protocol|Protocol (M3UA, SUA, IPA) to be operated by this server +|Accept Dynamic ASPs|Should we accept connections from ASPs that are not explicitly pre-configured with their source IP and port? +|==== + + +=== Osmocom SS7 Users + +A SS7 User is part of a program that binds to a given MTP-Layer +Service Indicator (SI). The Osmocom SS7 stack offers an API to +register SS7 Users, as well as the VTY command ``show cs7 instance +<0-15> users'' to list the currently registered users. + +=== Osmocom SS7 Links + +TBD. + +=== Osmocom SS7 Linksets + +TBD. + +=== Osmocom SS7 Application Servers + +This corresponds 1:1 to the SIGTRAN concept of an Application Server, +i.e. a given external Application that interfaces the SS7 network via +a SS7 protocol variant such as M3UA. + +In the context of Osmocom, for each program connecting to a STP (like +a BSC or MSC), you will have one Application Server definition. + +An AS has the following properties: + +.Major Attributes of an Osmocom SS7 Application Server +[options="header",cols="25%,75%"] +|==== +|Name|Description +|Name|A human-readable name for this instance +|Description|More verbose description (for human user only) +|Protocol|Protocol (M3UA, SUA, IPA) to be operated by this server +|Routing Key|Routing Key (mostly Point Code) routed to this AS +|Traffic Mode|Theoretically Bradcast, Load-Balance. Currently only Ovverride +|Recovery Timeout|Duration of the AS T(r) recovery timer. During this time, + outgoing messages are queued. If the AS is ACTIVE + before timer expiration, the queue is drained. At + expriation, the queue is flushed. +|State|Application Server State (Down, Inactive, Active, Pending) +|ASPs|Which ASPs are permitted to transfer traffic for this AS +|==== + +=== Osmocom SS7 Application Server Processes + +An Application Server Process corresponds to a given SCTP (or TCP) +connection. From the STP/SG (Server) point-of-view, those are +incoming connections from Application Servers such as the BSCs. From +the ASP (Client) Point of view, it has one ``osmo_ss7_asp'' object for +each outbound SIGTARN connection. + +An ASP has the following properties: + +.Major Attributes of an Osmocom SS7 Application Server Process +[options="header",cols="25%,75%"] +|==== +|Name|Description +|Name|A human-readable name for this instance +|Description|More verbose description (for human user only) +|Protocol|Protocol (M3UA, SUA, IPA) to be operated by this server +|Role|Server (SG) or Client (ASP)? +|Local Port|Port Number of the local end of the connection +|Local IP|IP Address of the local end of the connection +|Remote Port|Port Number of the remote end of the connection +|Remote IP|IP Address of the remote end of the connection +|State|ASP State (Down, Inactive, Active) +|==== + +=== Osmocom SS7 Routes + +An Osmocom SS7 Route routes traffic with a matching destination point +code and point code mask (similar to IP Address + Netmask) towards a +specified SS7 Linkset or Application Server. The Linkset or +Application Servers are identified by their name. + +.Major Attributes of an Osmocom SS7 Application Server Process +[options="header",cols="25%,75%"] +|==== +|Name|Description +|Point Code|Destination Point Code for this route +|Mask|Destination Mask for this route (like an IP netmask) +|Linkset/AS Name|Destination Linkset or AS, identified by name +|==== + + +=== Osmocom SCCP Instances + +An Osmocom SS7 Instance can be bound to an Osmocom SS7 Instance. It +will register/bind for the ITU-standard Service Indicator (SI). + +=== Osmocom SCCP User + +An Program (like a BSC) will _bind_ itself to a given well-known +sub-system number (SSN) in order to receive SCCP messages destined for +this SSN. + +There is an API to bind a program to a SSN, which implicitly generates +an SCCP User object. + +The ``show cs7 instance <0-15> sccp users'' command can be used on the +VTY to obtain a list of currently bound SCCP users, as well as their +corresponding SSNs. + +=== Osmocom SCCP Connection + +This is how Osmocom represents each individual connection of +connection-oriented SCCP. + +To illustrate the practical applicaiton: For the common use case of +the A or Iu interfaces, this means that every dedicated radio channel +that is currently active to any UE/MS has one SCCP connection to the +MSC and/or SGSN. + +The ``show cs7 instance <0-15> sccp connections'' command can be used +on the VTY to obtain a list of currently active SCCP connections, as +well as their source/destination and current state. + + +=== Osmocom SCCP User SAP + +The Osmocom SCCP User SAP (Service Access Point) is the programming +interface between the SCCP Provider (libosmo-sigtran) and the SCCP +User. It follows primitives as laid out in <>, encapsulated +in ``osmo_prim'' structures. + +=== Osmocom MTP User SAP + +The Osmocom MTP User SAP (Service Access Point) is the programming +interface betwen the MTP Provider and the MTP User (e.g. SCCP). It +follows primitives as laid out in <>, encapsulated in +``osmo_prim'' structures. diff --git a/common/chapters/sigtran-simple-2g.dot b/common/chapters/sigtran-simple-2g.dot new file mode 100644 index 0000000..28098fd --- /dev/null +++ b/common/chapters/sigtran-simple-2g.dot @@ -0,0 +1,22 @@ +digraph G { + rankdir=LR; + MS0 [label="MS"]; + MS1 [label="MS"]; + MS2 [label="MS"]; + MS3 [label="MS"]; + BTS0 [label="BTS"]; + BTS1 [label="BTS"]; + BSC [label="OsmoBSC"]; + MSC [label="OsmoMSC"]; + STP [label="OsmoSTP"]; + + MS0 -> BTS0; + MS1 -> BTS0; + MS2 -> BTS1; + MS3 -> BTS1; + BTS0 -> BSC [label="Abis/IP"]; + BTS1 -> BSC [label="Abis/IP"]; + BSC -> STP [label="SCCP/M3UA"]; + STP -> MSC [label="SCCP/M3UA", dir="back"]; +} + diff --git a/common/chapters/sigtran-simple-3g.dot b/common/chapters/sigtran-simple-3g.dot new file mode 100644 index 0000000..eac363d --- /dev/null +++ b/common/chapters/sigtran-simple-3g.dot @@ -0,0 +1,24 @@ +digraph G { + rankdir=LR; + UE0 [label="UE"]; + UE1 [label="UE"]; + UE2 [label="UE"]; + UE3 [label="UE"]; + HNB0 [label="hNodeB"]; + HNB1 [label="hNodeB"]; + HNBGW [label="OsmoHNBGW"]; + MSC [label="OsmoMSC"]; + SGSN [label="OsmoSGSN"]; + STP [label="OsmoSTP"]; + + UE0 -> HNB0; + UE1 -> HNB0; + UE2 -> HNB1; + UE3 -> HNB1; + HNB0 -> HNBGW [label="Iuh (RUA)"]; + HNB1 -> HNBGW [label="Iuh (RUA)"]; + HNBGW -> STP [label="Iu (SCCP/M3UA)"]; + STP -> MSC [label="Iu (SCCP/M3UA)", dir="back"]; + STP -> SGSN [label="Iu (SCCP/M3UA)", dir="back"]; +} + diff --git a/common/chapters/sigtran.adoc b/common/chapters/sigtran.adoc new file mode 100644 index 0000000..ebf5619 --- /dev/null +++ b/common/chapters/sigtran.adoc @@ -0,0 +1,332 @@ +== Signaling Networks: SS7 and SIGTRAN + +Classic digital telephony networks (whether wired or wireless) use the +ITU-T SS7 (Signaling System 7) to exchange signaling information +between network elements. + +Most of the ETSI/3GPP interfaces in the GSM and UMTS network are also +based on top of [parts of] SS7. This includes, among others, the +following interfaces: + +* _A_ interface between BSC and MSC +* _IuCS_ interface between RNC (or HNB-GW) and MSC +* _IuPS_ interface between RNC (or HNB-GW) and SGSN + +NOTE:: This does not include the A-bis interface between BTS and BSC. +While Abis traditionally is spoken over the same physical TDM circuits +as SS7, the protocol stack from L2 upwars is quite different (Abis +uses LAPD, while SS7 uses MTP)! + +=== Physical Layer + +The traditional physical layer of SS7 is based on TDM (time division +multiplex) links of the PDH/SDH family, as they were common in ISDN +networks. Some people may know their smallest incarnation as +so-called E1/T1 links. It can run either on individual 64kBps +timeslots of such a link, or on entire 2Mbps/1.5MBps E1/T1 links. + +There are also specifications for SS7 over ATM, though it is unclear +to the author if this is actually still used anywhere. + +On top of the Physical Layer is the Message Transfer Part (MTP). + +=== Message Transfer Part (MTP) + +MTP is the lower layer of the SS7 protocol stack. It is comprised of +two sub-layes, called MTP2 and MTP3. + +Nodes in a MTP network are addressed by their unique PC (Point Code). + +A _MTP Routing Label_ is in the MTP header and indicates the +_Originationg Point Code_ (OPC) as well as the _Destination Point +Code_ (DPC) and the _Service Indicator Octet_ (SIO). The SIO is used +to de-multiplex between different upper-layer protocol such as ISUP, +TUP or SCCP. + +Routing is performed by means of routers with routing tables, similar +to routing is performed in IP networks. Even the concept of a _point +code mask_ analogous to the _netmask_ exists. + +Routers are connected with one another over one or more _Link Sets_, +each comprised of one or multiple _Links_. Multiple Links in a +Linkset exist both for load sharing as well as for fail over purposes. + +==== Point Codes + +The length of point codes depends on the particular MTP dialect that +is used. In the 1980ies, when international telephony signaling +networks were established, most countries had their own national +dialects with certain specifics. + +Today, mostly the ITU and ANSI variants survive. The ITU variant uses +14bit point codes, while the ANSI variant uses 24 bit point code +length. + +Point Codes can be represented either as unsigned integers, or +grouped. Unfortunately there is no standard as to their +representation. In ITU networks, the _3.8.3_ notation is commonly +used, i.e. one decimal for the first 3 bits, followed by one decimal +for the center 8 bits, followed by another decimal for the final 3 +bits. + +Example:: The Point Code *1.5.3* (in 3.8.3 notation) is 1*2^11^ + 5*2^3^ + 3 = *2091 decimal*. + +=== Higher-Layer Protocols + +There are various higher-layer protocols used on top of MTP3, such as +TUP, ISUP, BICC as well as SCCP. Those protocols exist side-by-side +on top of MTP3, similar to e.g. ICMP, TCP and UDP existing +side-by-side on top of IP. + +In the context of cellular networks, SCCP is the most relevant part. + +=== Signaling Connection Control Part (SCCP) + +SCCP runs on top of MTP3 and creates something like an overlay network +on top of it. SCCP communication can e.g. span multiple different +isolated MTP networks, each with their own MTP dialect and addressing. + +SCCP provides both connectionless (datagram) and connection-oriented +services. Both are used in the context of cellular networks. + +==== SCCP Adresses + +SCCP Adresses are quite complex. This is due to the fact that it is +not simply one address format, but in fact a choice of one or multiple +different types of addresses. + +SCCP Addresses exist as _Calling Party_ and _Called Party_ addresses. +In the context of connectionless datagram services, the sender is +always the Calling Party, and the receiver the Called Party. In +connection-oriented SCCP, they resemble the initiator and recipient of +the connection. + +.SCCP Address Parts +[options="header",cols="10%,20%,70%"] +|==== +|Acronym|Name|Description +|SSN|Sub-System Number|Describes a given application such as e.g. a + GSM MSC, BSC or HLR. Can be compared to port + numbers on the Internet +|PC|Point Code |The Point Code of the underlying MTP network +|GT|Global Title |What most people would call a "phone number". + However, Global Titles come in many different + numbering plans, and only one of them (E.164) + resembles actual phone numbers. +|RI|Routing Indicator |Determines if message shall be routed on PC+SSN + or on GT basis +|==== + +==== Global Titles + +A Global Title is a (typically) globally unique address in the global +telephony network. The body of the Global Title consists of a series +of BCD-encoded digits similar to what everyone knows as phone numbers. + +A GT is however not only the digits of the "phone number", but also +some other equally important information, such as the _Numbering Plan_ +as well as the _Nature of Address Indication_. + +.Global Title Parts +[options="header",cols="10%,20%,70%"] +|==== +|Acronym|Name|Description +|GTI|Global Title Indicator|Determines the GT Format. Ranges from no + GT (0) to GT+TT+NP+ES+NAI (4) +|NAI|Nature of Address Indicator|Exists in GTI=1 and is sort of a mixture of TON + NPI +|TT|Translation Type |Used as a look-up key in Global Title Translation Tables +|NP|Numbering Plan |Indicates ITU Numbering Plan, such as E.164, E.212, E.214 +|ES|Encoding Scheme |Just a peculiar way to idicate the length of the digits +|- |Signals |The actual "phone number digits" +|==== + +For more information about SCCP Adresses and Global Titles, please +refer to <> + + +==== Global Title Translation (GTT) + +Global Title Translation is a process of re-writing the Global Title +on-the-fly while a signaling message passes a STP. + +Basically, a SCCP message is first transported by MTP3 on the MTP +level to the Destination Point Code indicated in the MTP Routing +Label. This process uses MTP routing and is transparent to SCCP. + +Once the SCCP message arrives at the MTP End-Node identified by the +Destination Point Code, the message is handed up to the local SCCP +stack, which then may implement Global Title Translation. + +The input to the GTT process is + +* the destination address of the SCCP message +* a local list/database of Global Title Translation Rules + +The successful output of he GTT includes + +* A new Routing Indicator +* The Destination Point Code to which the message is forwarded on MTP + level +* a Sub-system Number (if RI is set to "Route on SSN") +* a new Global Title (if RI is set to "Route on GT"), e.g. with translated digits. + +Between sender and recipient of a signaling message, there can be many +instances of Global Title Translation (up to 15 as per the hop +counter). + +For more information on Global Title Translation, please refer to +<>. + + +==== Peculiarities of Connection Oriented SCCP + +Interestingly, Connection-Oriented SCCP messages carry SCCP Adresses +*only during connection establishment*. All data messages during +an ongoing connection do not contain a Called or Calling Party +Address. Instead, they are routed only by the MTP label, which is +constructed from point code information saved at the time the +connection is established. + +This means that connection-oriented SCCP can not be routed across MTP +network boundaries the same way as connectionless SCCP messages. +Instead, an STP would have to perform _connection coupling_, whic is +basically the equivalent of an application-level proxy between two +SCCP connections, each over one of the two MTP networks. + +This is probably mostly of theoretical relevance, as +connection-oriented SCCP is primarily used betwen RAN and CN of +cellular network inside one operator, i.e. not across multiple MTP +networks. + +=== SIGTRAN - SS7 over IP Networks + +At some point, IP based networks became more dominant than classic +ISDN networks, and 3GPP as well as IETF were working out methods in +which telecom signaling traffic can be adapted over IP based +networks. + +Initially, only the edge of the network (i.e. the applications talking +to the network, such as HLR or MSC) were attached to the existing old +SS7 backbone by means as SUA and M3UA. Over time, even the links of +the actual network backbone networks became more and more IP based. + +In order to replace existing TDM-based SS7 links/liksets with SIGTRAN, +the M2UA or M2PA variants are used as a kind of drop-in replacement +for physical links. + +All SIGTRAN share that while they use IP, they don't use TCP or UDP +but operate over a (then) newly-introduced Layer 4 transport protocol +on top of IP: SCTP (Stream Control Transmission Protocol). + +Despite first being specified in October 2000 as IETF RFC 2960, it +took a long time until solid implementations of SCTP ended up in +general-purpose operating systems. SCTP is not used much outside the +context of SIGTAN, which means implementations often suffer from bugs, +and many parts of the public Internet do not carry SCTP traffic due to +restrictive firewalls and/or ignorant network administrators. + +==== SIGTRAN Concepts / Terminology + +Like every protocol or technologoy, SIGTRAN brings with it its own +terminologyand concepts. This section tries to briefly introduce +them. For more information, please see the related IETF RFCs. + +===== Signaling Gateway (SG) + +The Signaling Gateway (SG) interconnects the SS7 network wit external +applications. It translates (parts of) the SS7 protocol stack into an +IP based SIGTRAN protocol stack. Which parts at whcih level of the +protocol stack are translated to what depends on the specific SIGTRAN +dialect. + +A SG is traditionally attached to the TDM-Based SS7 network and offers +SIGTRAN/IP based applications a way to remotely attach to the SS7 +network. + +A SG typically has STP functionality built-in, but it is not +mandatory. + +===== Application Server (AS) + +An Application Server is basically a logical entity representing one +particular external application (from the SS7 point of view) which is +interfaced with the SS7 network by means of one of the SIGTRAN +protocols. + +An Application Server can have one or more Application Server Processes +associated with it. This functionality (currently not implemented in +Osmocom) can be used for load-balancing or fail-over scenarios. + +===== Application Server Process (ASP) + +An Application Server Process represents one particular SCTP +connection used for SIGTRAN signaling between an external application +(e.g. a BSC) and the Signaling Gateway (SG). + +One Application Server Process can route traffic for multiple +Application Servers. In order to differentiate traffic for different +Application Servers, the Routing Context header is used. + +==== SIGTRAN variants / stackings + +SIGTRAN is the name of an IETF working group, which has released an +entire group of different protocol specifications. So rather than one +way of transporting classic telecom signaling over IP, there are now +half a dozen different ones, and all can claim to be an official IETF +standard. + +FIXME: Overview picture comparing the different stackings + +===== MTP3 User Adaptation (M3UA) + +M3UA basically "chops off" everything up to and including the MTP3 +protocol layer of the SS7 protocol stack and replaces it with a stack +comprised of M3UA over SCTP over IP. + +M3UA is specified in <>. + +===== SCCP User Adaptation (SUA) + +SUA basically "chops off" everything up to and including the SCCP +protocol layer of the SS7 protocol stack and replaces it with a stack +comprised of SUA over SCTP over IP. + +This means that SUA can only be used for SCCP based signaling, but not +for other SS7 protocols like e.g. TUP and ISUP. + +SUA is specified in <>. + +===== MTP2 User Adaptation (M2UA) + +M2UA is specified in <>. + +NOTE:: M2UA is not supported in Osmocom SIGTRAN up to this point. Let +us know if we can implement it for you! + +===== MTP2-User Peer-to-Peer Adaptation (M2PA) + +M2PA is specified in <>. + +NOTE:: M2PA is not supported in Osmocom SIGTRAN up to this point. Let +us know if we can implement it for you! + + +==== SIGTRAN security + +There simply is none. There are some hints that TLS shall be used +over SCTP in order to provide authenticity and/or confidentiality for +SIGTRAN, but this is not widely used. + +As telecom signaling is not generally carried over public networks, +private networks/links by means of MPLS, VLANs or VPNs such as IPsec +are often used to isolate and/or secure SIGTRAN. + +Under no circumstances should you use unsecured SIGTRAN with +production data over the public internet! + +==== IPv6 support + +SCTP (and thus all the higher layer protocols of the various SIGTRAN +stackings) operates on top of both IPv4 and IPv6. As the entire +underlying IP transport is transparent to the SS7/SCCP applcations, +there is no restriction on whether to use SIGTRAN over IPv4 or IPv6. -- To view, visit https://gerrit.osmocom.org/2371 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I450bfac7444ac9cb7f50c086d87cf7157c2e2a31 Gerrit-PatchSet: 5 Gerrit-Project: osmo-gsm-manuals Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max From gerrit-no-reply at lists.osmocom.org Sat Apr 22 12:24:17 2017 From: gerrit-no-reply at lists.osmocom.org (Holger Freyther) Date: Sat, 22 Apr 2017 12:24:17 +0000 Subject: osmo-gsm-manuals[master]: First step towards an OsmoSTP manual In-Reply-To: References: Message-ID: Patch Set 5: I fixed one typo I saw today at OsmoDevCon and fixed the format of a bulletin list. Still need to actually read it. :) -- To view, visit https://gerrit.osmocom.org/2371 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I450bfac7444ac9cb7f50c086d87cf7157c2e2a31 Gerrit-PatchSet: 5 Gerrit-Project: osmo-gsm-manuals Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-HasComments: No From admin at opensuse.org Sat Apr 22 19:57:21 2017 From: admin at opensuse.org (OBS Notification) Date: Sat, 22 Apr 2017 19:57:21 +0000 Subject: Build failure of network:osmocom:nightly/libosmo-sccp in xUbuntu_16.10/i586 In-Reply-To: References: Message-ID: <58fbb5cb328ef_1bc99c0f7c1958d7@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/libosmo-sccp/xUbuntu_16.10/i586 Package network:osmocom:nightly/libosmo-sccp failed to build in xUbuntu_16.10/i586 Check out the package for editing: osc checkout network:osmocom:nightly libosmo-sccp Last lines of build log: [ 99s] ./src/xua_asp_fsm.c:772: undefined reference to `ipa_ccm_send_id_req' [ 99s] ../../src/.libs/libosmo-sigtran.a(ipa.o): In function `ipa_tx_xua_as': [ 99s] ./src/ipa.c:71: undefined reference to `ipa_msg_alloc' [ 99s] collect2: error: ld returned 1 exit status [ 99s] Makefile:360: recipe for target 'xua_test' failed [ 99s] make[4]: *** [xua_test] Error 1 [ 99s] make[4]: Leaving directory '/usr/src/packages/BUILD/tests/xua' [ 99s] Makefile:362: recipe for target 'all-recursive' failed [ 99s] make[3]: *** [all-recursive] Error 1 [ 99s] make[3]: Leaving directory '/usr/src/packages/BUILD/tests' [ 99s] Makefile:454: recipe for target 'all-recursive' failed [ 99s] make[2]: *** [all-recursive] Error 1 [ 99s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 99s] Makefile:372: recipe for target 'all' failed [ 99s] make[1]: *** [all] Error 2 [ 99s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 99s] dh_auto_build: make -j1 returned exit code 2 [ 99s] debian/rules:12: recipe for target 'build' failed [ 99s] make: *** [build] Error 2 [ 99s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 99s] [ 99s] lamb65 failed "build libosmo-sccp_0.7.1.20170422.dsc" at Sat Apr 22 19:57:15 UTC 2017. [ 99s] [ 100s] ### VM INTERACTION START ### [ 103s] [ 89.519542] reboot: Power down [ 103s] ### VM INTERACTION END ### [ 103s] [ 103s] lamb65 failed "build libosmo-sccp_0.7.1.20170422.dsc" at Sat Apr 22 19:57:19 UTC 2017. [ 103s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Sat Apr 22 19:58:30 2017 From: admin at opensuse.org (OBS Notification) Date: Sat, 22 Apr 2017 19:58:30 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in xUbuntu_16.10/i586 In-Reply-To: References: Message-ID: <58fbb607eba26_1bc39c0f7c1950ba@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/xUbuntu_16.10/i586 Package network:osmocom:nightly/osmo-stp failed to build in xUbuntu_16.10/i586 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 45s] ^~~~~~~ [ 46s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o vty_interface.o vty_interface.c [ 46s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o sctp_m3ua_client.o sctp_m3ua_client.c [ 46s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 46s] #include [ 46s] ^ [ 46s] compilation terminated. [ 46s] Makefile:485: recipe for target 'sctp_m3ua_client.o' failed [ 46s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 46s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 46s] Makefile:380: recipe for target 'all-recursive' failed [ 46s] make[2]: *** [all-recursive] Error 1 [ 46s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 46s] Makefile:321: recipe for target 'all' failed [ 46s] make[1]: *** [all] Error 2 [ 46s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 46s] dh_auto_build: make -j1 returned exit code 2 [ 46s] debian/rules:23: recipe for target 'build' failed [ 46s] make: *** [build] Error 2 [ 46s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 46s] [ 46s] build73 failed "build cellmgr-ng_1.4.7.20170422.dsc" at Sat Apr 22 19:58:18 UTC 2017. [ 46s] [ 46s] ### VM INTERACTION START ### [ 49s] [ 39.304400] reboot: Power down [ 49s] ### VM INTERACTION END ### [ 49s] [ 49s] build73 failed "build cellmgr-ng_1.4.7.20170422.dsc" at Sat Apr 22 19:58:22 UTC 2017. [ 49s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Sat Apr 22 19:59:21 2017 From: admin at opensuse.org (OBS Notification) Date: Sat, 22 Apr 2017 19:59:21 +0000 Subject: Build failure of network:osmocom:nightly/libosmo-sccp in xUbuntu_16.04/i586 In-Reply-To: References: Message-ID: <58fbb622cce70_1bc39c0f7c1951d2@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/libosmo-sccp/xUbuntu_16.04/i586 Package network:osmocom:nightly/libosmo-sccp failed to build in xUbuntu_16.04/i586 Check out the package for editing: osc checkout network:osmocom:nightly libosmo-sccp Last lines of build log: [ 126s] /usr/src/packages/BUILD/src/xua_asp_fsm.c:772: undefined reference to `ipa_ccm_send_id_req' [ 126s] ../../src/.libs/libosmo-sigtran.a(ipa.o): In function `ipa_tx_xua_as': [ 126s] /usr/src/packages/BUILD/src/ipa.c:71: undefined reference to `ipa_msg_alloc' [ 126s] collect2: error: ld returned 1 exit status [ 126s] Makefile:360: recipe for target 'xua_test' failed [ 126s] make[4]: *** [xua_test] Error 1 [ 126s] make[4]: Leaving directory '/usr/src/packages/BUILD/tests/xua' [ 126s] Makefile:362: recipe for target 'all-recursive' failed [ 126s] make[3]: *** [all-recursive] Error 1 [ 126s] make[3]: Leaving directory '/usr/src/packages/BUILD/tests' [ 126s] Makefile:454: recipe for target 'all-recursive' failed [ 126s] make[2]: *** [all-recursive] Error 1 [ 126s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 126s] Makefile:372: recipe for target 'all' failed [ 126s] make[1]: *** [all] Error 2 [ 126s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 126s] dh_auto_build: make -j1 returned exit code 2 [ 126s] debian/rules:12: recipe for target 'build' failed [ 126s] make: *** [build] Error 2 [ 126s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 126s] [ 126s] build31 failed "build libosmo-sccp_0.7.1.20170422.dsc" at Sat Apr 22 19:59:05 UTC 2017. [ 126s] [ 126s] ### VM INTERACTION START ### [ 129s] [ 114.367261] reboot: Power down [ 130s] ### VM INTERACTION END ### [ 130s] [ 130s] build31 failed "build libosmo-sccp_0.7.1.20170422.dsc" at Sat Apr 22 19:59:09 UTC 2017. [ 130s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Sat Apr 22 19:59:38 2017 From: admin at opensuse.org (OBS Notification) Date: Sat, 22 Apr 2017 19:59:38 +0000 Subject: Build failure of network:osmocom:nightly/libosmo-sccp in xUbuntu_16.10/x86_64 In-Reply-To: References: Message-ID: <58fbb642a9471_1bc39c0f7c195247@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/libosmo-sccp/xUbuntu_16.10/x86_64 Package network:osmocom:nightly/libosmo-sccp failed to build in xUbuntu_16.10/x86_64 Check out the package for editing: osc checkout network:osmocom:nightly libosmo-sccp Last lines of build log: [ 100s] ./src/xua_asp_fsm.c:772: undefined reference to `ipa_ccm_send_id_req' [ 100s] ../../src/.libs/libosmo-sigtran.a(ipa.o): In function `ipa_tx_xua_as': [ 100s] ./src/ipa.c:71: undefined reference to `ipa_msg_alloc' [ 100s] collect2: error: ld returned 1 exit status [ 100s] Makefile:360: recipe for target 'xua_test' failed [ 100s] make[4]: *** [xua_test] Error 1 [ 100s] make[4]: Leaving directory '/usr/src/packages/BUILD/tests/xua' [ 100s] Makefile:362: recipe for target 'all-recursive' failed [ 100s] make[3]: *** [all-recursive] Error 1 [ 100s] make[3]: Leaving directory '/usr/src/packages/BUILD/tests' [ 100s] Makefile:454: recipe for target 'all-recursive' failed [ 100s] make[2]: *** [all-recursive] Error 1 [ 100s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 100s] Makefile:372: recipe for target 'all' failed [ 100s] make[1]: *** [all] Error 2 [ 100s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 100s] dh_auto_build: make -j1 returned exit code 2 [ 100s] debian/rules:12: recipe for target 'build' failed [ 100s] make: *** [build] Error 2 [ 100s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 100s] [ 100s] lamb67 failed "build libosmo-sccp_0.7.1.20170422.dsc" at Sat Apr 22 19:59:31 UTC 2017. [ 100s] [ 100s] ### VM INTERACTION START ### [ 103s] [ 89.916000] reboot: Power down [ 103s] ### VM INTERACTION END ### [ 103s] [ 103s] lamb67 failed "build libosmo-sccp_0.7.1.20170422.dsc" at Sat Apr 22 19:59:35 UTC 2017. [ 103s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Sat Apr 22 19:59:38 2017 From: admin at opensuse.org (OBS Notification) Date: Sat, 22 Apr 2017 19:59:38 +0000 Subject: Build failure of network:osmocom:nightly/libosmo-sccp in Debian_8.0/i586 In-Reply-To: References: Message-ID: <58fbb6439d21c_1bc39c0f7c195383@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/libosmo-sccp/Debian_8.0/i586 Package network:osmocom:nightly/libosmo-sccp failed to build in Debian_8.0/i586 Check out the package for editing: osc checkout network:osmocom:nightly libosmo-sccp Last lines of build log: [ 135s] /usr/bin/ld: ../../src/.libs/libosmo-sigtran.a(osmo_ss7.o): undefined reference to symbol 'ipa_msg_recv_buffered@@LIBOSMOGSM_1.0' [ 135s] //usr/lib/i386-linux-gnu/libosmogsm.so.6: error adding symbols: DSO missing from command line [ 135s] collect2: error: ld returned 1 exit status [ 135s] Makefile:348: recipe for target 'xua_test' failed [ 135s] make[4]: *** [xua_test] Error 1 [ 135s] make[4]: Leaving directory '/usr/src/packages/BUILD/tests/xua' [ 135s] Makefile:350: recipe for target 'all-recursive' failed [ 135s] make[3]: *** [all-recursive] Error 1 [ 135s] make[3]: Leaving directory '/usr/src/packages/BUILD/tests' [ 135s] Makefile:443: recipe for target 'all-recursive' failed [ 135s] make[2]: *** [all-recursive] Error 1 [ 135s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 135s] Makefile:360: recipe for target 'all' failed [ 135s] make[1]: *** [all] Error 2 [ 135s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 135s] dh_auto_build: make -j1 returned exit code 2 [ 135s] debian/rules:12: recipe for target 'build' failed [ 135s] make: *** [build] Error 2 [ 135s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 135s] [ 135s] cloud101 failed "build libosmo-sccp_0.7.1.20170422.dsc" at Sat Apr 22 19:59:26 UTC 2017. [ 135s] [ 135s] ### VM INTERACTION START ### [ 136s] Powering off. [ 136s] [ 113.002990] reboot: Power down [ 137s] ### VM INTERACTION END ### [ 137s] [ 137s] cloud101 failed "build libosmo-sccp_0.7.1.20170422.dsc" at Sat Apr 22 19:59:29 UTC 2017. [ 137s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Sat Apr 22 20:00:31 2017 From: admin at opensuse.org (OBS Notification) Date: Sat, 22 Apr 2017 20:00:31 +0000 Subject: Build failure of network:osmocom:nightly/libosmo-sccp in xUbuntu_16.04/x86_64 In-Reply-To: References: Message-ID: <58fbb68053249_1bc39c0f7c1954a5@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/libosmo-sccp/xUbuntu_16.04/x86_64 Package network:osmocom:nightly/libosmo-sccp failed to build in xUbuntu_16.04/x86_64 Check out the package for editing: osc checkout network:osmocom:nightly libosmo-sccp Last lines of build log: [ 121s] /usr/src/packages/BUILD/src/xua_asp_fsm.c:772: undefined reference to `ipa_ccm_send_id_req' [ 121s] ../../src/.libs/libosmo-sigtran.a(ipa.o): In function `ipa_tx_xua_as': [ 121s] /usr/src/packages/BUILD/src/ipa.c:71: undefined reference to `ipa_msg_alloc' [ 121s] collect2: error: ld returned 1 exit status [ 121s] Makefile:360: recipe for target 'xua_test' failed [ 121s] make[4]: *** [xua_test] Error 1 [ 121s] make[4]: Leaving directory '/usr/src/packages/BUILD/tests/xua' [ 121s] Makefile:362: recipe for target 'all-recursive' failed [ 121s] make[3]: *** [all-recursive] Error 1 [ 121s] make[3]: Leaving directory '/usr/src/packages/BUILD/tests' [ 121s] Makefile:454: recipe for target 'all-recursive' failed [ 121s] make[2]: *** [all-recursive] Error 1 [ 121s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 121s] Makefile:372: recipe for target 'all' failed [ 121s] make[1]: *** [all] Error 2 [ 121s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 121s] dh_auto_build: make -j1 returned exit code 2 [ 121s] debian/rules:12: recipe for target 'build' failed [ 121s] make: *** [build] Error 2 [ 121s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 121s] [ 121s] lamb68 failed "build libosmo-sccp_0.7.1.20170422.dsc" at Sat Apr 22 20:00:25 UTC 2017. [ 121s] [ 121s] ### VM INTERACTION START ### [ 124s] [ 110.044185] reboot: Power down [ 124s] ### VM INTERACTION END ### [ 124s] [ 124s] lamb68 failed "build libosmo-sccp_0.7.1.20170422.dsc" at Sat Apr 22 20:00:29 UTC 2017. [ 124s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Sat Apr 22 20:01:22 2017 From: admin at opensuse.org (OBS Notification) Date: Sat, 22 Apr 2017 20:01:22 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in xUbuntu_16.10/x86_64 In-Reply-To: References: Message-ID: <58fbb6b81241d_1bc99c0f7c1959ad@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/xUbuntu_16.10/x86_64 Package network:osmocom:nightly/osmo-stp failed to build in xUbuntu_16.10/x86_64 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 76s] ^~~~~~~ [ 76s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o vty_interface.o vty_interface.c [ 76s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o sctp_m3ua_client.o sctp_m3ua_client.c [ 77s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 77s] #include [ 77s] ^ [ 77s] compilation terminated. [ 77s] Makefile:485: recipe for target 'sctp_m3ua_client.o' failed [ 77s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 77s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 77s] Makefile:380: recipe for target 'all-recursive' failed [ 77s] make[2]: *** [all-recursive] Error 1 [ 77s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 77s] Makefile:321: recipe for target 'all' failed [ 77s] make[1]: *** [all] Error 2 [ 77s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 77s] dh_auto_build: make -j1 returned exit code 2 [ 77s] debian/rules:23: recipe for target 'build' failed [ 77s] make: *** [build] Error 2 [ 77s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 77s] [ 77s] lamb19 failed "build cellmgr-ng_1.4.7.20170422.dsc" at Sat Apr 22 20:01:02 UTC 2017. [ 77s] [ 77s] ### VM INTERACTION START ### [ 80s] [ 65.986578] reboot: Power down [ 80s] ### VM INTERACTION END ### [ 80s] [ 80s] lamb19 failed "build cellmgr-ng_1.4.7.20170422.dsc" at Sat Apr 22 20:01:06 UTC 2017. [ 80s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Sat Apr 22 20:01:22 2017 From: admin at opensuse.org (OBS Notification) Date: Sat, 22 Apr 2017 20:01:22 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in Debian_8.0/i586 In-Reply-To: References: Message-ID: <58fbb6b8811cf_1bc99c0f7c1961a4@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/Debian_8.0/i586 Package network:osmocom:nightly/osmo-stp failed to build in Debian_8.0/i586 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 88s] CC vty_interface.o [ 88s] CC sctp_m3ua_client.o [ 88s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 88s] #include [ 88s] ^ [ 88s] compilation terminated. [ 88s] Makefile:475: recipe for target 'sctp_m3ua_client.o' failed [ 88s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 88s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 88s] Makefile:370: recipe for target 'all-recursive' failed [ 88s] make[2]: *** [all-recursive] Error 1 [ 88s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 88s] Makefile:310: recipe for target 'all' failed [ 88s] make[1]: *** [all] Error 2 [ 88s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 88s] dh_auto_build: make -j1 returned exit code 2 [ 88s] debian/rules:23: recipe for target 'build' failed [ 88s] make: *** [build] Error 2 [ 88s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 88s] [ 88s] lamb69 failed "build cellmgr-ng_1.4.7.20170422.dsc" at Sat Apr 22 20:01:09 UTC 2017. [ 88s] [ 88s] ### VM INTERACTION START ### [ 90s] Powering off. [ 90s] [ 75.136056] reboot: Power down [ 90s] ### VM INTERACTION END ### [ 90s] [ 90s] lamb69 failed "build cellmgr-ng_1.4.7.20170422.dsc" at Sat Apr 22 20:01:11 UTC 2017. [ 90s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Sat Apr 22 20:01:22 2017 From: admin at opensuse.org (OBS Notification) Date: Sat, 22 Apr 2017 20:01:22 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in xUbuntu_16.04/i586 In-Reply-To: References: Message-ID: <58fbb6b842d89_1bc99c0f7c196075@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/xUbuntu_16.04/i586 Package network:osmocom:nightly/osmo-stp failed to build in xUbuntu_16.04/i586 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 96s] sctp_m2ua.c:91:3: warning: #warning "Notify any other AS(P) for failover scenario" [-Wcpp] [ 96s] #warning "Notify any other AS(P) for failover scenario" [ 96s] ^ [ 96s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -c -o vty_interface.o vty_interface.c [ 97s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -c -o sctp_m3ua_client.o sctp_m3ua_client.c [ 97s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 97s] compilation terminated. [ 97s] Makefile:485: recipe for target 'sctp_m3ua_client.o' failed [ 97s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 97s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 97s] Makefile:380: recipe for target 'all-recursive' failed [ 97s] make[2]: *** [all-recursive] Error 1 [ 97s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 97s] Makefile:321: recipe for target 'all' failed [ 97s] make[1]: *** [all] Error 2 [ 97s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 97s] dh_auto_build: make -j1 returned exit code 2 [ 97s] debian/rules:23: recipe for target 'build' failed [ 97s] make: *** [build] Error 2 [ 97s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 97s] [ 97s] lamb51 failed "build cellmgr-ng_1.4.7.20170422.dsc" at Sat Apr 22 20:01:05 UTC 2017. [ 97s] [ 97s] ### VM INTERACTION START ### [ 100s] [ 86.941783] reboot: Power down [ 100s] ### VM INTERACTION END ### [ 100s] [ 100s] lamb51 failed "build cellmgr-ng_1.4.7.20170422.dsc" at Sat Apr 22 20:01:09 UTC 2017. [ 100s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Sat Apr 22 20:01:22 2017 From: admin at opensuse.org (OBS Notification) Date: Sat, 22 Apr 2017 20:01:22 +0000 Subject: Build failure of network:osmocom:nightly/libosmo-sccp in Debian_8.0/x86_64 In-Reply-To: References: Message-ID: <58fbb6b8d286b_1bc99c0f7c19625a@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/libosmo-sccp/Debian_8.0/x86_64 Package network:osmocom:nightly/libosmo-sccp failed to build in Debian_8.0/x86_64 Check out the package for editing: osc checkout network:osmocom:nightly libosmo-sccp Last lines of build log: [ 132s] /usr/bin/ld: ../../src/.libs/libosmo-sigtran.a(osmo_ss7.o): undefined reference to symbol 'ipa_msg_recv_buffered@@LIBOSMOGSM_1.0' [ 132s] //usr/lib/x86_64-linux-gnu/libosmogsm.so.6: error adding symbols: DSO missing from command line [ 132s] collect2: error: ld returned 1 exit status [ 132s] Makefile:348: recipe for target 'xua_test' failed [ 132s] make[4]: *** [xua_test] Error 1 [ 132s] make[4]: Leaving directory '/usr/src/packages/BUILD/tests/xua' [ 132s] Makefile:350: recipe for target 'all-recursive' failed [ 132s] make[3]: *** [all-recursive] Error 1 [ 132s] make[3]: Leaving directory '/usr/src/packages/BUILD/tests' [ 132s] Makefile:443: recipe for target 'all-recursive' failed [ 132s] make[2]: *** [all-recursive] Error 1 [ 132s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 132s] Makefile:360: recipe for target 'all' failed [ 132s] make[1]: *** [all] Error 2 [ 132s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 132s] dh_auto_build: make -j1 returned exit code 2 [ 132s] debian/rules:12: recipe for target 'build' failed [ 132s] make: *** [build] Error 2 [ 132s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 132s] [ 132s] cloud104 failed "build libosmo-sccp_0.7.1.20170422.dsc" at Sat Apr 22 20:01:14 UTC 2017. [ 132s] [ 132s] ### VM INTERACTION START ### [ 133s] Powering off. [ 133s] [ 109.114660] reboot: Power down [ 134s] ### VM INTERACTION END ### [ 134s] [ 134s] cloud104 failed "build libosmo-sccp_0.7.1.20170422.dsc" at Sat Apr 22 20:01:17 UTC 2017. [ 134s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Sat Apr 22 20:02:13 2017 From: admin at opensuse.org (OBS Notification) Date: Sat, 22 Apr 2017 20:02:13 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in xUbuntu_16.04/x86_64 In-Reply-To: References: Message-ID: <58fbb6d65f690_1bc39c0f7c19555f@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/xUbuntu_16.04/x86_64 Package network:osmocom:nightly/osmo-stp failed to build in xUbuntu_16.04/x86_64 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 84s] sctp_m2ua.c:91:3: warning: #warning "Notify any other AS(P) for failover scenario" [-Wcpp] [ 84s] #warning "Notify any other AS(P) for failover scenario" [ 84s] ^ [ 84s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -c -o vty_interface.o vty_interface.c [ 85s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -c -o sctp_m3ua_client.o sctp_m3ua_client.c [ 85s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 85s] compilation terminated. [ 85s] Makefile:485: recipe for target 'sctp_m3ua_client.o' failed [ 85s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 85s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 85s] Makefile:380: recipe for target 'all-recursive' failed [ 85s] make[2]: *** [all-recursive] Error 1 [ 85s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 85s] Makefile:321: recipe for target 'all' failed [ 85s] make[1]: *** [all] Error 2 [ 85s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 85s] dh_auto_build: make -j1 returned exit code 2 [ 85s] debian/rules:23: recipe for target 'build' failed [ 85s] make: *** [build] Error 2 [ 85s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 85s] [ 85s] wildcard2 failed "build cellmgr-ng_1.4.7.20170422.dsc" at Sat Apr 22 20:02:05 UTC 2017. [ 85s] [ 85s] ### VM INTERACTION START ### [ 88s] [ 74.493253] reboot: Power down [ 88s] ### VM INTERACTION END ### [ 88s] [ 88s] wildcard2 failed "build cellmgr-ng_1.4.7.20170422.dsc" at Sat Apr 22 20:02:10 UTC 2017. [ 88s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Sat Apr 22 20:03:04 2017 From: admin at opensuse.org (OBS Notification) Date: Sat, 22 Apr 2017 20:03:04 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in Debian_8.0/x86_64 In-Reply-To: References: Message-ID: <58fbb7317795f_1bc99c0f7c19639b@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/Debian_8.0/x86_64 Package network:osmocom:nightly/osmo-stp failed to build in Debian_8.0/x86_64 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 89s] CC vty_interface.o [ 90s] CC sctp_m3ua_client.o [ 90s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 90s] #include [ 90s] ^ [ 90s] compilation terminated. [ 90s] Makefile:475: recipe for target 'sctp_m3ua_client.o' failed [ 90s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 90s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 90s] Makefile:370: recipe for target 'all-recursive' failed [ 90s] make[2]: *** [all-recursive] Error 1 [ 90s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 90s] Makefile:310: recipe for target 'all' failed [ 90s] make[1]: *** [all] Error 2 [ 90s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 90s] dh_auto_build: make -j1 returned exit code 2 [ 90s] debian/rules:23: recipe for target 'build' failed [ 90s] make: *** [build] Error 2 [ 90s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 90s] [ 90s] lamb59 failed "build cellmgr-ng_1.4.7.20170422.dsc" at Sat Apr 22 20:02:58 UTC 2017. [ 90s] [ 90s] ### VM INTERACTION START ### [ 91s] Powering off. [ 91s] [ 77.178256] reboot: Power down [ 91s] ### VM INTERACTION END ### [ 91s] [ 91s] lamb59 failed "build cellmgr-ng_1.4.7.20170422.dsc" at Sat Apr 22 20:03:00 UTC 2017. [ 91s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From gerrit-no-reply at lists.osmocom.org Sun Apr 23 13:05:02 2017 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Sun, 23 Apr 2017 13:05:02 +0000 Subject: [PATCH] osmo-gsm-manuals[master]: cosmetic: OsmoGSMTester: fix dir name Message-ID: Review at https://gerrit.osmocom.org/2396 cosmetic: OsmoGSMTester: fix dir name All other subdirs are without dashes, but I added Osmo-GSM-Tester with dashes. Comply with the naming scheme and remove dashes. Change-Id: I36d0c94dde5deffba04b27436ae499a42c519bec --- M Makefile R OsmoGSMTester/Makefile R OsmoGSMTester/chapters/config.adoc R OsmoGSMTester/chapters/debugging.adoc R OsmoGSMTester/chapters/intro.adoc R OsmoGSMTester/chapters/test_api.adoc R OsmoGSMTester/chapters/trial.adoc R OsmoGSMTester/osmo-gsm-tester-manual-docinfo.xml R OsmoGSMTester/osmo-gsm-tester-manual.adoc 9 files changed, 4 insertions(+), 4 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-gsm-manuals refs/changes/96/2396/1 diff --git a/Makefile b/Makefile index 362f171..fc8ebbf 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,7 @@ cd OsmoSGSN; $(MAKE) cd OsmoNAT; $(MAKE) cd OsmoPCU; $(MAKE) - cd Osmo-GSM-Tester; $(MAKE) + cd OsmoGSMTester; $(MAKE) clean: cd OsmoBTS; $(MAKE) clean @@ -16,7 +16,7 @@ cd OsmoSGSN; $(MAKE) clean cd OsmoNAT; $(MAKE) clean cd OsmoPCU; $(MAKE) clean - cd Osmo-GSM-Tester; $(MAKE) clean + cd OsmoGSMTester; $(MAKE) clean upload: cd OsmoBTS; $(MAKE) upload @@ -26,7 +26,7 @@ cd OsmoSGSN; $(MAKE) upload cd OsmoNAT; $(MAKE) upload cd OsmoPCU; $(MAKE) upload - cd Osmo-GSM-Tester; $(MAKE) upload + cd OsmoGSMTester; $(MAKE) upload check: cd OsmoBTS; $(MAKE) check @@ -37,4 +37,4 @@ # These don't use asciidoc, so they have no 'make check' target: #cd OsmoMGCP; $(MAKE) check #cd OsmoNAT; $(MAKE) check - cd Osmo-GSM-Tester; $(MAKE) check + cd OsmoGSMTester; $(MAKE) check diff --git a/Osmo-GSM-Tester/Makefile b/OsmoGSMTester/Makefile similarity index 100% rename from Osmo-GSM-Tester/Makefile rename to OsmoGSMTester/Makefile diff --git a/Osmo-GSM-Tester/chapters/config.adoc b/OsmoGSMTester/chapters/config.adoc similarity index 100% rename from Osmo-GSM-Tester/chapters/config.adoc rename to OsmoGSMTester/chapters/config.adoc diff --git a/Osmo-GSM-Tester/chapters/debugging.adoc b/OsmoGSMTester/chapters/debugging.adoc similarity index 100% rename from Osmo-GSM-Tester/chapters/debugging.adoc rename to OsmoGSMTester/chapters/debugging.adoc diff --git a/Osmo-GSM-Tester/chapters/intro.adoc b/OsmoGSMTester/chapters/intro.adoc similarity index 100% rename from Osmo-GSM-Tester/chapters/intro.adoc rename to OsmoGSMTester/chapters/intro.adoc diff --git a/Osmo-GSM-Tester/chapters/test_api.adoc b/OsmoGSMTester/chapters/test_api.adoc similarity index 100% rename from Osmo-GSM-Tester/chapters/test_api.adoc rename to OsmoGSMTester/chapters/test_api.adoc diff --git a/Osmo-GSM-Tester/chapters/trial.adoc b/OsmoGSMTester/chapters/trial.adoc similarity index 100% rename from Osmo-GSM-Tester/chapters/trial.adoc rename to OsmoGSMTester/chapters/trial.adoc diff --git a/Osmo-GSM-Tester/osmo-gsm-tester-manual-docinfo.xml b/OsmoGSMTester/osmo-gsm-tester-manual-docinfo.xml similarity index 100% rename from Osmo-GSM-Tester/osmo-gsm-tester-manual-docinfo.xml rename to OsmoGSMTester/osmo-gsm-tester-manual-docinfo.xml diff --git a/Osmo-GSM-Tester/osmo-gsm-tester-manual.adoc b/OsmoGSMTester/osmo-gsm-tester-manual.adoc similarity index 100% rename from Osmo-GSM-Tester/osmo-gsm-tester-manual.adoc rename to OsmoGSMTester/osmo-gsm-tester-manual.adoc -- To view, visit https://gerrit.osmocom.org/2396 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I36d0c94dde5deffba04b27436ae499a42c519bec Gerrit-PatchSet: 1 Gerrit-Project: osmo-gsm-manuals Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Sun Apr 23 13:30:29 2017 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Sun, 23 Apr 2017 13:30:29 +0000 Subject: osmo-gsm-manuals[master]: First step towards an OsmoSTP manual In-Reply-To: References: Message-ID: Patch Set 5: Code-Review+2 (3 comments) https://gerrit.osmocom.org/#/c/2371/5/OsmoSTP/chapters/overview.adoc File OsmoSTP/chapters/overview.adoc: Line 1 (could omit this file until it is used) https://gerrit.osmocom.org/#/c/2371/5/common/chapters/sigtran-simple-2g.dot File common/chapters/sigtran-simple-2g.dot: Line 1: digraph G { (could have this inline in the adoc if it's only used once) https://gerrit.osmocom.org/#/c/2371/5/common/chapters/sigtran-simple-3g.dot File common/chapters/sigtran-simple-3g.dot: Line 1: digraph G { (could have this inline in the adoc if it's only used once) -- To view, visit https://gerrit.osmocom.org/2371 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I450bfac7444ac9cb7f50c086d87cf7157c2e2a31 Gerrit-PatchSet: 5 Gerrit-Project: osmo-gsm-manuals Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Sun Apr 23 14:16:17 2017 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Sun, 23 Apr 2017 14:16:17 +0000 Subject: libosmo-netif[master]: misc: Call the variable ctx like in all other places In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2284 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I27ed1178fdbbcf3fc0e1070dc19b4ecf9a327a04 Gerrit-PatchSet: 2 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sun Apr 23 14:17:24 2017 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Sun, 23 Apr 2017 14:17:24 +0000 Subject: osmo-bts[master]: Name systemd service after the software In-Reply-To: References: Message-ID: Patch Set 2: could you summarize the current status? Why are we not merging yet? -- To view, visit https://gerrit.osmocom.org/2225 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ie336292c275e7415a1deedab7c3b44966aacc3bf Gerrit-PatchSet: 2 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Pau Espin Pedrol Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: Pau Espin Pedrol Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sun Apr 23 14:18:25 2017 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Sun, 23 Apr 2017 14:18:25 +0000 Subject: osmo-pcu[master]: Name systemd service after the software In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2224 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ia7fa4a1868ee04ee043efd61aa55ee0c4001f12b Gerrit-PatchSet: 1 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: Pau Espin Pedrol Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sun Apr 23 14:34:18 2017 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Sun, 23 Apr 2017 14:34:18 +0000 Subject: [MERGED] libosmocore[master]: fix spelling in API docu, command reply, logging, descriptions In-Reply-To: References: Message-ID: Neels Hofmeyr has submitted this change and it was merged. Change subject: fix spelling in API docu, command reply, logging, descriptions ...................................................................... fix spelling in API docu, command reply, logging, descriptions sections: ctrl, gb, gsm, vty Change-Id: Iac211b5cd8504da36b699777b95a2448dd7c3e70 --- M src/ctrl/control_if.c M src/gb/gprs_ns.c M src/gsm/auth_core.c M src/gsm/lapd_core.c M src/vty/logging_vty.c 5 files changed, 5 insertions(+), 5 deletions(-) Approvals: Jenkins Builder: Verified Holger Freyther: Looks good to me, approved diff --git a/src/ctrl/control_if.c b/src/ctrl/control_if.c index f49d639..d2eb3e9 100644 --- a/src/ctrl/control_if.c +++ b/src/ctrl/control_if.c @@ -269,7 +269,7 @@ err: if (!cmd->reply) { if (ret == CTRL_CMD_ERROR) { - cmd->reply = "An error has occured."; + cmd->reply = "An error has occurred."; LOGP(DLCTRL, LOGL_NOTICE, "%s: cmd->reply has not been set (ERROR).\n", cmd->variable); diff --git a/src/gb/gprs_ns.c b/src/gb/gprs_ns.c index 76e70ff..0649899 100644 --- a/src/gb/gprs_ns.c +++ b/src/gb/gprs_ns.c @@ -138,7 +138,7 @@ }; static const struct osmo_stat_item_desc nsvc_stat_description[] = { - { "alive.delay", "ALIVE reponse time ", "ms", 16, 0 }, + { "alive.delay", "ALIVE response time ", "ms", 16, 0 }, }; static const struct osmo_stat_item_group_desc nsvc_statg_desc = { diff --git a/src/gsm/auth_core.c b/src/gsm/auth_core.c index acb65f5..9ca5d93 100644 --- a/src/gsm/auth_core.c +++ b/src/gsm/auth_core.c @@ -180,7 +180,7 @@ * based on the permanent subscriber data, a random value as well as the * AUTS and RAND values returned by the SIM/MS. This special variant is * needed if the sequence numbers between MS and AUC have for some - * reason become diffrent. + * reason become different. */ int osmo_auth_gen_vec_auts(struct osmo_auth_vector *vec, struct osmo_sub_auth_data *aud, diff --git a/src/gsm/lapd_core.c b/src/gsm/lapd_core.c index a602d78..e0bbcab 100644 --- a/src/gsm/lapd_core.c +++ b/src/gsm/lapd_core.c @@ -861,7 +861,7 @@ if (memcmp(dl->cont_res->data, msg->data, length)) { LOGP(DLLAPD, LOGL_INFO, "Another SABM " - "with diffrent content - " + "with different content - " "ignoring! (dl=%p)\n", dl); msgb_free(msg); return 0; diff --git a/src/vty/logging_vty.c b/src/vty/logging_vty.c index aabcaa7..7bb79b8 100644 --- a/src/vty/logging_vty.c +++ b/src/vty/logging_vty.c @@ -342,7 +342,7 @@ gDEFUN(cfg_description, cfg_description_cmd, "description .TEXT", - "Save human-readable decription of the object\n" + "Save human-readable description of the object\n" "Text until the end of the line\n") { char **dptr = vty->index_sub; -- To view, visit https://gerrit.osmocom.org/1968 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Iac211b5cd8504da36b699777b95a2448dd7c3e70 Gerrit-PatchSet: 3 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Thorsten Alteholz Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: Thorsten Alteholz From gerrit-no-reply at lists.osmocom.org Sun Apr 23 16:15:56 2017 From: gerrit-no-reply at lists.osmocom.org (Tom Tsou) Date: Sun, 23 Apr 2017 16:15:56 +0000 Subject: libosmocore[master]: tests/conv: move conv.h to the global include dir In-Reply-To: References: Message-ID: Patch Set 2: Code-Review-1 (1 comment) https://gerrit.osmocom.org/#/c/2075/2/include/osmocom/tests/conv.h File include/osmocom/tests/conv.h: PS2, Line 3: 512 The max length will cause problems if the output message length of the code is larger than 512 (i.e. MCS-1 and higher codes). -- To view, visit https://gerrit.osmocom.org/2075 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I414223f3d9382642fc4f7efb3b35dc950eaaad86 Gerrit-PatchSet: 2 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Vadim Yanitskiy Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: Tom Tsou Gerrit-Reviewer: Vadim Yanitskiy Gerrit-Reviewer: tnt Gerrit-HasComments: Yes From admin at opensuse.org Sun Apr 23 20:00:25 2017 From: admin at opensuse.org (OBS Notification) Date: Sun, 23 Apr 2017 20:00:25 +0000 Subject: Build failure of network:osmocom:nightly/libosmo-sccp in xUbuntu_16.10/x86_64 In-Reply-To: References: Message-ID: <58fd07e2dfb00_1bc39c0f7c2163cf@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/libosmo-sccp/xUbuntu_16.10/x86_64 Package network:osmocom:nightly/libosmo-sccp failed to build in xUbuntu_16.10/x86_64 Check out the package for editing: osc checkout network:osmocom:nightly libosmo-sccp Last lines of build log: [ 111s] ./src/xua_asp_fsm.c:772: undefined reference to `ipa_ccm_send_id_req' [ 111s] ../../src/.libs/libosmo-sigtran.a(ipa.o): In function `ipa_tx_xua_as': [ 111s] ./src/ipa.c:71: undefined reference to `ipa_msg_alloc' [ 111s] collect2: error: ld returned 1 exit status [ 111s] Makefile:360: recipe for target 'xua_test' failed [ 111s] make[4]: *** [xua_test] Error 1 [ 111s] make[4]: Leaving directory '/usr/src/packages/BUILD/tests/xua' [ 111s] Makefile:362: recipe for target 'all-recursive' failed [ 111s] make[3]: *** [all-recursive] Error 1 [ 111s] make[3]: Leaving directory '/usr/src/packages/BUILD/tests' [ 111s] Makefile:454: recipe for target 'all-recursive' failed [ 111s] make[2]: *** [all-recursive] Error 1 [ 111s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 111s] Makefile:372: recipe for target 'all' failed [ 111s] make[1]: *** [all] Error 2 [ 111s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 111s] dh_auto_build: make -j1 returned exit code 2 [ 111s] debian/rules:12: recipe for target 'build' failed [ 111s] make: *** [build] Error 2 [ 111s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 111s] [ 111s] build36 failed "build libosmo-sccp_0.7.1.20170423.dsc" at Sun Apr 23 20:00:04 UTC 2017. [ 111s] [ 111s] ### VM INTERACTION START ### [ 114s] [ 94.417009] reboot: Power down [ 115s] ### VM INTERACTION END ### [ 115s] [ 115s] build36 failed "build libosmo-sccp_0.7.1.20170423.dsc" at Sun Apr 23 20:00:08 UTC 2017. [ 115s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Sun Apr 23 20:00:42 2017 From: admin at opensuse.org (OBS Notification) Date: Sun, 23 Apr 2017 20:00:42 +0000 Subject: Build failure of network:osmocom:nightly/libosmo-sccp in xUbuntu_16.04/x86_64 In-Reply-To: References: Message-ID: <58fd07ffb7a52_1e2461ef7c1865ac@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/libosmo-sccp/xUbuntu_16.04/x86_64 Package network:osmocom:nightly/libosmo-sccp failed to build in xUbuntu_16.04/x86_64 Check out the package for editing: osc checkout network:osmocom:nightly libosmo-sccp Last lines of build log: [ 126s] /usr/src/packages/BUILD/src/xua_asp_fsm.c:772: undefined reference to `ipa_ccm_send_id_req' [ 126s] ../../src/.libs/libosmo-sigtran.a(ipa.o): In function `ipa_tx_xua_as': [ 126s] /usr/src/packages/BUILD/src/ipa.c:71: undefined reference to `ipa_msg_alloc' [ 126s] collect2: error: ld returned 1 exit status [ 126s] Makefile:360: recipe for target 'xua_test' failed [ 126s] make[4]: *** [xua_test] Error 1 [ 126s] make[4]: Leaving directory '/usr/src/packages/BUILD/tests/xua' [ 126s] Makefile:362: recipe for target 'all-recursive' failed [ 126s] make[3]: *** [all-recursive] Error 1 [ 126s] make[3]: Leaving directory '/usr/src/packages/BUILD/tests' [ 126s] Makefile:454: recipe for target 'all-recursive' failed [ 126s] make[2]: *** [all-recursive] Error 1 [ 126s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 126s] Makefile:372: recipe for target 'all' failed [ 126s] make[1]: *** [all] Error 2 [ 126s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 126s] dh_auto_build: make -j1 returned exit code 2 [ 126s] debian/rules:12: recipe for target 'build' failed [ 126s] make: *** [build] Error 2 [ 126s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 127s] [ 127s] lamb70 failed "build libosmo-sccp_0.7.1.20170423.dsc" at Sun Apr 23 20:00:22 UTC 2017. [ 127s] [ 127s] ### VM INTERACTION START ### [ 130s] [ 116.922253] reboot: Power down [ 130s] ### VM INTERACTION END ### [ 130s] [ 130s] lamb70 failed "build libosmo-sccp_0.7.1.20170423.dsc" at Sun Apr 23 20:00:26 UTC 2017. [ 130s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Sun Apr 23 20:01:16 2017 From: admin at opensuse.org (OBS Notification) Date: Sun, 23 Apr 2017 20:01:16 +0000 Subject: Build failure of network:osmocom:nightly/libosmo-sccp in xUbuntu_16.10/i586 In-Reply-To: References: Message-ID: <58fd08201d4a8_1bbd9c0f7c20559b@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/libosmo-sccp/xUbuntu_16.10/i586 Package network:osmocom:nightly/libosmo-sccp failed to build in xUbuntu_16.10/i586 Check out the package for editing: osc checkout network:osmocom:nightly libosmo-sccp Last lines of build log: [ 100s] ./src/xua_asp_fsm.c:772: undefined reference to `ipa_ccm_send_id_req' [ 100s] ../../src/.libs/libosmo-sigtran.a(ipa.o): In function `ipa_tx_xua_as': [ 100s] ./src/ipa.c:71: undefined reference to `ipa_msg_alloc' [ 100s] collect2: error: ld returned 1 exit status [ 100s] Makefile:360: recipe for target 'xua_test' failed [ 100s] make[4]: *** [xua_test] Error 1 [ 100s] make[4]: Leaving directory '/usr/src/packages/BUILD/tests/xua' [ 100s] Makefile:362: recipe for target 'all-recursive' failed [ 100s] make[3]: *** [all-recursive] Error 1 [ 100s] make[3]: Leaving directory '/usr/src/packages/BUILD/tests' [ 100s] Makefile:454: recipe for target 'all-recursive' failed [ 100s] make[2]: *** [all-recursive] Error 1 [ 100s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 100s] Makefile:372: recipe for target 'all' failed [ 100s] make[1]: *** [all] Error 2 [ 100s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 100s] dh_auto_build: make -j1 returned exit code 2 [ 100s] debian/rules:12: recipe for target 'build' failed [ 100s] make: *** [build] Error 2 [ 100s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 100s] [ 100s] lamb73 failed "build libosmo-sccp_0.7.1.20170423.dsc" at Sun Apr 23 20:00:57 UTC 2017. [ 100s] [ 100s] ### VM INTERACTION START ### [ 103s] [ 90.308466] reboot: Power down [ 103s] ### VM INTERACTION END ### [ 103s] [ 103s] lamb73 failed "build libosmo-sccp_0.7.1.20170423.dsc" at Sun Apr 23 20:01:00 UTC 2017. [ 103s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Sun Apr 23 20:01:16 2017 From: admin at opensuse.org (OBS Notification) Date: Sun, 23 Apr 2017 20:01:16 +0000 Subject: Build failure of network:osmocom:nightly/libosmo-sccp in Debian_8.0/i586 In-Reply-To: References: Message-ID: <58fd083dbe956_1e2461ef7c1867c8@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/libosmo-sccp/Debian_8.0/i586 Package network:osmocom:nightly/libosmo-sccp failed to build in Debian_8.0/i586 Check out the package for editing: osc checkout network:osmocom:nightly libosmo-sccp Last lines of build log: [ 126s] /usr/bin/ld: ../../src/.libs/libosmo-sigtran.a(osmo_ss7.o): undefined reference to symbol 'ipa_msg_recv_buffered@@LIBOSMOGSM_1.0' [ 126s] //usr/lib/i386-linux-gnu/libosmogsm.so.6: error adding symbols: DSO missing from command line [ 126s] collect2: error: ld returned 1 exit status [ 126s] Makefile:348: recipe for target 'xua_test' failed [ 126s] make[4]: *** [xua_test] Error 1 [ 126s] make[4]: Leaving directory '/usr/src/packages/BUILD/tests/xua' [ 126s] Makefile:350: recipe for target 'all-recursive' failed [ 126s] make[3]: *** [all-recursive] Error 1 [ 126s] make[3]: Leaving directory '/usr/src/packages/BUILD/tests' [ 126s] Makefile:443: recipe for target 'all-recursive' failed [ 126s] make[2]: *** [all-recursive] Error 1 [ 126s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 126s] Makefile:360: recipe for target 'all' failed [ 126s] make[1]: *** [all] Error 2 [ 126s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 126s] dh_auto_build: make -j1 returned exit code 2 [ 126s] debian/rules:12: recipe for target 'build' failed [ 126s] make: *** [build] Error 2 [ 126s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 126s] [ 126s] build35 failed "build libosmo-sccp_0.7.1.20170423.dsc" at Sun Apr 23 20:01:09 UTC 2017. [ 126s] [ 126s] ### VM INTERACTION START ### [ 127s] Powering off. [ 127s] [ 104.839240] reboot: Power down [ 128s] ### VM INTERACTION END ### [ 128s] [ 128s] build35 failed "build libosmo-sccp_0.7.1.20170423.dsc" at Sun Apr 23 20:01:12 UTC 2017. [ 128s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Sun Apr 23 20:01:16 2017 From: admin at opensuse.org (OBS Notification) Date: Sun, 23 Apr 2017 20:01:16 +0000 Subject: Build failure of network:osmocom:nightly/libosmo-sccp in xUbuntu_16.04/i586 In-Reply-To: References: Message-ID: <58fd083d8bca0_1e2461ef7c186691@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/libosmo-sccp/xUbuntu_16.04/i586 Package network:osmocom:nightly/libosmo-sccp failed to build in xUbuntu_16.04/i586 Check out the package for editing: osc checkout network:osmocom:nightly libosmo-sccp Last lines of build log: [ 121s] ../../src/.libs/libosmo-sigtran.a(xua_asp_fsm.o): In function `ipa_asp_fsm_down': [ 121s] /usr/src/packages/BUILD/src/xua_asp_fsm.c:772: undefined reference to `ipa_ccm_send_id_req' [ 121s] ../../src/.libs/libosmo-sigtran.a(ipa.o): In function `ipa_tx_xua_as': [ 121s] /usr/src/packages/BUILD/src/ipa.c:71: undefined reference to `ipa_msg_alloc' [ 121s] collect2: error: ld returned 1 exit status [ 121s] Makefile:360: recipe for target 'xua_test' failed [ 121s] make[4]: *** [xua_test] Error 1 [ 121s] make[4]: Leaving directory '/usr/src/packages/BUILD/tests/xua' [ 121s] Makefile:362: recipe for target 'all-recursive' failed [ 121s] make[3]: *** [all-recursive] Error 1 [ 121s] make[3]: Leaving directory '/usr/src/packages/BUILD/tests' [ 121s] Makefile:454: recipe for target 'all-recursive' failed [ 121s] make[2]: *** [all-recursive] Error 1 [ 121s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 121s] Makefile:372: recipe for target 'all' failed [ 121s] make[1]: *** [all] Error 2 [ 121s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 121s] dh_auto_build: make -j1 returned exit code 2 [ 121s] debian/rules:12: recipe for target 'build' failed [ 121s] make: *** [build] Error 2 [ 121s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 121s] [ 121s] lamb62 failed "build libosmo-sccp_0.7.1.20170423.dsc" at Sun Apr 23 20:01:08 UTC 2017. [ 121s] [ 121s] ### VM INTERACTION START ### [ 124s] ### VM INTERACTION END ### [ 124s] [ 124s] lamb62 failed "build libosmo-sccp_0.7.1.20170423.dsc" at Sun Apr 23 20:01:11 UTC 2017. [ 124s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Sun Apr 23 20:02:08 2017 From: admin at opensuse.org (OBS Notification) Date: Sun, 23 Apr 2017 20:02:08 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in xUbuntu_16.10/x86_64 In-Reply-To: References: Message-ID: <58fd087a355d0_1bc39c0f7c216437@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/xUbuntu_16.10/x86_64 Package network:osmocom:nightly/osmo-stp failed to build in xUbuntu_16.10/x86_64 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 81s] ^~~~~~~ [ 82s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o vty_interface.o vty_interface.c [ 82s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o sctp_m3ua_client.o sctp_m3ua_client.c [ 82s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 82s] #include [ 82s] ^ [ 82s] compilation terminated. [ 82s] Makefile:485: recipe for target 'sctp_m3ua_client.o' failed [ 82s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 82s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 82s] Makefile:380: recipe for target 'all-recursive' failed [ 82s] make[2]: *** [all-recursive] Error 1 [ 82s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 82s] Makefile:321: recipe for target 'all' failed [ 82s] make[1]: *** [all] Error 2 [ 82s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 82s] dh_auto_build: make -j1 returned exit code 2 [ 82s] debian/rules:23: recipe for target 'build' failed [ 82s] make: *** [build] Error 2 [ 82s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 82s] [ 82s] lamb20 failed "build cellmgr-ng_1.4.7.20170423.dsc" at Sun Apr 23 20:01:50 UTC 2017. [ 82s] [ 82s] ### VM INTERACTION START ### [ 85s] [ 71.540791] reboot: Power down [ 85s] ### VM INTERACTION END ### [ 85s] [ 85s] lamb20 failed "build cellmgr-ng_1.4.7.20170423.dsc" at Sun Apr 23 20:01:53 UTC 2017. [ 85s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Sun Apr 23 20:02:25 2017 From: admin at opensuse.org (OBS Notification) Date: Sun, 23 Apr 2017 20:02:25 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in xUbuntu_16.04/x86_64 In-Reply-To: References: Message-ID: <58fd087abc178_1bc39c0f7c21653a@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/xUbuntu_16.04/x86_64 Package network:osmocom:nightly/osmo-stp failed to build in xUbuntu_16.04/x86_64 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 95s] sctp_m2ua.c:91:3: warning: #warning "Notify any other AS(P) for failover scenario" [-Wcpp] [ 95s] #warning "Notify any other AS(P) for failover scenario" [ 95s] ^ [ 95s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -c -o vty_interface.o vty_interface.c [ 96s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -c -o sctp_m3ua_client.o sctp_m3ua_client.c [ 96s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 96s] compilation terminated. [ 96s] Makefile:485: recipe for target 'sctp_m3ua_client.o' failed [ 96s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 96s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 96s] Makefile:380: recipe for target 'all-recursive' failed [ 96s] make[2]: *** [all-recursive] Error 1 [ 96s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 96s] Makefile:321: recipe for target 'all' failed [ 96s] make[1]: *** [all] Error 2 [ 96s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 96s] dh_auto_build: make -j1 returned exit code 2 [ 96s] debian/rules:23: recipe for target 'build' failed [ 96s] make: *** [build] Error 2 [ 96s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 96s] [ 96s] lamb02 failed "build cellmgr-ng_1.4.7.20170423.dsc" at Sun Apr 23 20:02:13 UTC 2017. [ 96s] [ 96s] ### VM INTERACTION START ### [ 99s] [ 86.355265] reboot: Power down [ 99s] ### VM INTERACTION END ### [ 99s] [ 99s] lamb02 failed "build cellmgr-ng_1.4.7.20170423.dsc" at Sun Apr 23 20:02:16 UTC 2017. [ 99s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Sun Apr 23 20:02:42 2017 From: admin at opensuse.org (OBS Notification) Date: Sun, 23 Apr 2017 20:02:42 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in Debian_8.0/i586 In-Reply-To: References: Message-ID: <58fd089981cec_1bbd9c0f7c20568@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/Debian_8.0/i586 Package network:osmocom:nightly/osmo-stp failed to build in Debian_8.0/i586 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 54s] ^ [ 54s] CC vty_interface.o [ 55s] CC sctp_m3ua_client.o [ 55s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 55s] #include [ 55s] ^ [ 55s] compilation terminated. [ 55s] Makefile:475: recipe for target 'sctp_m3ua_client.o' failed [ 55s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 55s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 55s] Makefile:370: recipe for target 'all-recursive' failed [ 55s] make[2]: *** [all-recursive] Error 1 [ 55s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 55s] Makefile:310: recipe for target 'all' failed [ 55s] make[1]: *** [all] Error 2 [ 55s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 55s] dh_auto_build: make -j1 returned exit code 2 [ 55s] debian/rules:23: recipe for target 'build' failed [ 55s] make: *** [build] Error 2 [ 55s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 55s] [ 55s] build75 failed "build cellmgr-ng_1.4.7.20170423.dsc" at Sun Apr 23 20:02:27 UTC 2017. [ 55s] [ 55s] ### VM INTERACTION START ### [ 56s] Powering off. [ 56s] ### VM INTERACTION END ### [ 56s] [ 56s] build75 failed "build cellmgr-ng_1.4.7.20170423.dsc" at Sun Apr 23 20:02:28 UTC 2017. [ 56s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Sun Apr 23 20:02:59 2017 From: admin at opensuse.org (OBS Notification) Date: Sun, 23 Apr 2017 20:02:59 +0000 Subject: Build failure of network:osmocom:nightly/libosmo-sccp in Debian_8.0/x86_64 In-Reply-To: References: Message-ID: <58fd089a4aa59_1bbd9c0f7c20585@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/libosmo-sccp/Debian_8.0/x86_64 Package network:osmocom:nightly/libosmo-sccp failed to build in Debian_8.0/x86_64 Check out the package for editing: osc checkout network:osmocom:nightly libosmo-sccp Last lines of build log: [ 101s] /usr/bin/ld: ../../src/.libs/libosmo-sigtran.a(osmo_ss7.o): undefined reference to symbol 'ipa_msg_recv_buffered@@LIBOSMOGSM_1.0' [ 101s] //usr/lib/x86_64-linux-gnu/libosmogsm.so.6: error adding symbols: DSO missing from command line [ 101s] collect2: error: ld returned 1 exit status [ 101s] Makefile:348: recipe for target 'xua_test' failed [ 101s] make[4]: *** [xua_test] Error 1 [ 101s] make[4]: Leaving directory '/usr/src/packages/BUILD/tests/xua' [ 101s] Makefile:350: recipe for target 'all-recursive' failed [ 101s] make[3]: *** [all-recursive] Error 1 [ 101s] make[3]: Leaving directory '/usr/src/packages/BUILD/tests' [ 101s] Makefile:443: recipe for target 'all-recursive' failed [ 101s] make[2]: *** [all-recursive] Error 1 [ 101s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 101s] Makefile:360: recipe for target 'all' failed [ 101s] make[1]: *** [all] Error 2 [ 101s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 101s] dh_auto_build: make -j1 returned exit code 2 [ 101s] debian/rules:12: recipe for target 'build' failed [ 101s] make: *** [build] Error 2 [ 101s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 101s] [ 101s] lamb17 failed "build libosmo-sccp_0.7.1.20170423.dsc" at Sun Apr 23 20:02:48 UTC 2017. [ 101s] [ 101s] ### VM INTERACTION START ### [ 102s] Powering off. [ 102s] [ 88.021946] reboot: Power down [ 102s] ### VM INTERACTION END ### [ 102s] [ 102s] lamb17 failed "build libosmo-sccp_0.7.1.20170423.dsc" at Sun Apr 23 20:02:50 UTC 2017. [ 102s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Sun Apr 23 20:03:16 2017 From: admin at opensuse.org (OBS Notification) Date: Sun, 23 Apr 2017 20:03:16 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in xUbuntu_16.04/i586 In-Reply-To: References: Message-ID: <58fd08b478d9_1bbd9c0f7c2059ca@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/xUbuntu_16.04/i586 Package network:osmocom:nightly/osmo-stp failed to build in xUbuntu_16.04/i586 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 94s] sctp_m2ua.c:91:3: warning: #warning "Notify any other AS(P) for failover scenario" [-Wcpp] [ 94s] #warning "Notify any other AS(P) for failover scenario" [ 94s] ^ [ 94s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -c -o vty_interface.o vty_interface.c [ 95s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -c -o sctp_m3ua_client.o sctp_m3ua_client.c [ 95s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 95s] compilation terminated. [ 95s] Makefile:485: recipe for target 'sctp_m3ua_client.o' failed [ 95s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 95s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 95s] Makefile:380: recipe for target 'all-recursive' failed [ 95s] make[2]: *** [all-recursive] Error 1 [ 95s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 95s] Makefile:321: recipe for target 'all' failed [ 95s] make[1]: *** [all] Error 2 [ 95s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 95s] dh_auto_build: make -j1 returned exit code 2 [ 95s] debian/rules:23: recipe for target 'build' failed [ 95s] make: *** [build] Error 2 [ 95s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 95s] [ 95s] lamb11 failed "build cellmgr-ng_1.4.7.20170423.dsc" at Sun Apr 23 20:03:03 UTC 2017. [ 95s] [ 95s] ### VM INTERACTION START ### [ 98s] [ 85.159516] reboot: Power down [ 98s] ### VM INTERACTION END ### [ 98s] [ 98s] lamb11 failed "build cellmgr-ng_1.4.7.20170423.dsc" at Sun Apr 23 20:03:07 UTC 2017. [ 98s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Sun Apr 23 20:04:08 2017 From: admin at opensuse.org (OBS Notification) Date: Sun, 23 Apr 2017 20:04:08 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in Debian_8.0/x86_64 In-Reply-To: References: Message-ID: <58fd08d2c1bcf_1bbd9c0f7c2060c5@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/Debian_8.0/x86_64 Package network:osmocom:nightly/osmo-stp failed to build in Debian_8.0/x86_64 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 52s] CC vty_interface.o [ 52s] CC sctp_m3ua_client.o [ 52s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 52s] #include [ 52s] ^ [ 52s] compilation terminated. [ 53s] Makefile:475: recipe for target 'sctp_m3ua_client.o' failed [ 53s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 53s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 53s] Makefile:370: recipe for target 'all-recursive' failed [ 53s] make[2]: *** [all-recursive] Error 1 [ 53s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 53s] Makefile:310: recipe for target 'all' failed [ 53s] make[1]: *** [all] Error 2 [ 53s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 53s] dh_auto_build: make -j1 returned exit code 2 [ 53s] debian/rules:23: recipe for target 'build' failed [ 53s] make: *** [build] Error 2 [ 53s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 53s] [ 53s] build72 failed "build cellmgr-ng_1.4.7.20170423.dsc" at Sun Apr 23 20:03:57 UTC 2017. [ 53s] [ 53s] ### VM INTERACTION START ### [ 54s] Powering off. [ 54s] [ 45.257739] reboot: Power down [ 54s] ### VM INTERACTION END ### [ 54s] [ 54s] build72 failed "build cellmgr-ng_1.4.7.20170423.dsc" at Sun Apr 23 20:03:59 UTC 2017. [ 54s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Sun Apr 23 20:04:25 2017 From: admin at opensuse.org (OBS Notification) Date: Sun, 23 Apr 2017 20:04:25 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in xUbuntu_16.10/i586 In-Reply-To: References: Message-ID: <58fd08d3fc06_1bbd9c0f7c20612d@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/xUbuntu_16.10/i586 Package network:osmocom:nightly/osmo-stp failed to build in xUbuntu_16.10/i586 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 113s] ^~~~~~~ [ 113s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o vty_interface.o vty_interface.c [ 114s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o sctp_m3ua_client.o sctp_m3ua_client.c [ 114s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 114s] #include [ 114s] ^ [ 114s] compilation terminated. [ 114s] Makefile:485: recipe for target 'sctp_m3ua_client.o' failed [ 114s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 114s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 114s] Makefile:380: recipe for target 'all-recursive' failed [ 114s] make[2]: *** [all-recursive] Error 1 [ 114s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 114s] Makefile:321: recipe for target 'all' failed [ 114s] make[1]: *** [all] Error 2 [ 114s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 114s] dh_auto_build: make -j1 returned exit code 2 [ 114s] debian/rules:23: recipe for target 'build' failed [ 114s] make: *** [build] Error 2 [ 114s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 114s] [ 114s] cloud136 failed "build cellmgr-ng_1.4.7.20170423.dsc" at Sun Apr 23 20:04:14 UTC 2017. [ 114s] [ 114s] ### VM INTERACTION START ### [ 117s] [ 94.276968] reboot: Power down [ 119s] ### VM INTERACTION END ### [ 119s] [ 119s] cloud136 failed "build cellmgr-ng_1.4.7.20170423.dsc" at Sun Apr 23 20:04:20 UTC 2017. [ 119s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From gerrit-no-reply at lists.osmocom.org Mon Apr 24 00:28:59 2017 From: gerrit-no-reply at lists.osmocom.org (Vadim Yanitskiy) Date: Mon, 24 Apr 2017 00:28:59 +0000 Subject: osmo-trx[master]: ssedetect: Add runtime CPU detection In-Reply-To: References: Message-ID: Patch Set 3: Code-Review-1 (1 comment) https://gerrit.osmocom.org/#/c/2100/3/Transceiver52M/x86/convert.c File Transceiver52M/x86/convert.c: Line 197: if (__builtin_cpu_supports("sse4.1")) { It is only supported by GCC, so building with another compiler, for example with clang, fails: convert.c:197:6: error: use of unknown builtin '__builtin_cpu_supports' [-Wimplicit-function-declaration] if (__builtin_cpu_supports("sse4.1")) { ^ 1 error generated. I don't know, is there any way to determine supported instructions sets in clang, but for now we can go this way: #if (defined(__GNUC__) && !defined(__clang__)) if (__builtin_cpu_supports("sse4.1")) // ... #endif -- To view, visit https://gerrit.osmocom.org/2100 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Iba74f8a6e4e921ff31e4bd9f0c7c881fe547423a Gerrit-PatchSet: 3 Gerrit-Project: osmo-trx Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Vadim Yanitskiy Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Mon Apr 24 08:13:16 2017 From: gerrit-no-reply at lists.osmocom.org (Pau Espin Pedrol) Date: Mon, 24 Apr 2017 08:13:16 +0000 Subject: [PATCH] libosmo-netif[master]: osmux: Fix delay between RTP packets Message-ID: Review at https://gerrit.osmocom.org/2397 osmux: Fix delay between RTP packets AMR frame contains 160 samples at 8000Hz -> 20 ms long Change-Id: I36dc69f9caf591dd1b578bc914a2ce426c7f2813 --- M src/osmux.c 1 file changed, 1 insertion(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-netif refs/changes/97/2397/1 diff --git a/src/osmux.c b/src/osmux.c index 5655269..5511cd4 100644 --- a/src/osmux.c +++ b/src/osmux.c @@ -43,7 +43,7 @@ #endif /* delta time between two RTP messages */ -#define DELTA_RTP_MSG 16000 +#define DELTA_RTP_MSG 20000 #define DELTA_RTP_TIMESTAMP 160 static void *osmux_ctx; -- To view, visit https://gerrit.osmocom.org/2397 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I36dc69f9caf591dd1b578bc914a2ce426c7f2813 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Pau Espin Pedrol From gerrit-no-reply at lists.osmocom.org Mon Apr 24 10:01:20 2017 From: gerrit-no-reply at lists.osmocom.org (Pau Espin Pedrol) Date: Mon, 24 Apr 2017 10:01:20 +0000 Subject: [MERGED] openbsc[master]: nat: Fix initial buffer size parameter for getline In-Reply-To: References: Message-ID: Pau Espin Pedrol has submitted this change and it was merged. Change subject: nat: Fix initial buffer size parameter for getline ...................................................................... nat: Fix initial buffer size parameter for getline According to man, lineptr must be set to null AND n to 0. Change-Id: I36683884106b97ef697264716de13813c00da9bc --- M openbsc/src/osmo-bsc_nat/bsc_nat_rewrite_trie.c 1 file changed, 1 insertion(+), 1 deletion(-) Approvals: Jenkins Builder: Verified Holger Freyther: Looks good to me, approved diff --git a/openbsc/src/osmo-bsc_nat/bsc_nat_rewrite_trie.c b/openbsc/src/osmo-bsc_nat/bsc_nat_rewrite_trie.c index 9291c89..633fa87 100644 --- a/openbsc/src/osmo-bsc_nat/bsc_nat_rewrite_trie.c +++ b/openbsc/src/osmo-bsc_nat/bsc_nat_rewrite_trie.c @@ -169,7 +169,7 @@ { FILE *file; char *line = NULL; - size_t n = 2342; + size_t n = 0; struct nat_rewrite *res; file = fopen(filename, "r"); -- To view, visit https://gerrit.osmocom.org/2287 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I36683884106b97ef697264716de13813c00da9bc Gerrit-PatchSet: 2 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Pau Espin Pedrol Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Pau Espin Pedrol From gerrit-no-reply at lists.osmocom.org Mon Apr 24 10:01:21 2017 From: gerrit-no-reply at lists.osmocom.org (Pau Espin Pedrol) Date: Mon, 24 Apr 2017 10:01:21 +0000 Subject: [MERGED] openbsc[master]: nat: Use equal func in bsc_sccp In-Reply-To: References: Message-ID: Pau Espin Pedrol has submitted this change and it was merged. Change subject: nat: Use equal func in bsc_sccp ...................................................................... nat: Use equal func in bsc_sccp It is defined in the file and used twice in there, so let's use it for all of them which makes code smaller and more clear. Change-Id: I9fac7cabedff74f8f6293ad8b54420229b80aa71 --- M openbsc/src/osmo-bsc_nat/bsc_sccp.c 1 file changed, 4 insertions(+), 6 deletions(-) Approvals: Max: Looks good to me, but someone else must approve Jenkins Builder: Verified Holger Freyther: Looks good to me, approved diff --git a/openbsc/src/osmo-bsc_nat/bsc_sccp.c b/openbsc/src/osmo-bsc_nat/bsc_sccp.c index 25c13d4..c6c265f 100644 --- a/openbsc/src/osmo-bsc_nat/bsc_sccp.c +++ b/openbsc/src/osmo-bsc_nat/bsc_sccp.c @@ -45,7 +45,7 @@ struct nat_sccp_connection *conn; llist_for_each_entry(conn, &nat->sccp_connections, list_entry) { - if (memcmp(ref, &conn->patched_ref, sizeof(*ref)) == 0) + if (equal(ref, &conn->patched_ref)) return -1; } @@ -91,7 +91,7 @@ llist_for_each_entry(conn, &bsc->nat->sccp_connections, list_entry) { if (conn->bsc != bsc) continue; - if (memcmp(&conn->real_ref, parsed->src_local_ref, sizeof(conn->real_ref)) != 0) + if (!equal(parsed->src_local_ref, &conn->real_ref)) continue; /* the BSC has reassigned the SRC ref and we failed to keep track */ @@ -159,9 +159,7 @@ struct nat_sccp_connection *conn; llist_for_each_entry(conn, &bsc->nat->sccp_connections, list_entry) { - if (memcmp(parsed->src_local_ref, - &conn->patched_ref, sizeof(conn->patched_ref)) == 0) { - + if (equal(parsed->src_local_ref, &conn->patched_ref)) { sccp_connection_destroy(conn); return; } @@ -241,7 +239,7 @@ struct nat_sccp_connection *conn; llist_for_each_entry(conn, &nat->sccp_connections, list_entry) { - if (memcmp(ref, &conn->real_ref, sizeof(*ref)) == 0) + if (equal(ref, &conn->real_ref)) return conn; } -- To view, visit https://gerrit.osmocom.org/2285 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I9fac7cabedff74f8f6293ad8b54420229b80aa71 Gerrit-PatchSet: 2 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Pau Espin Pedrol Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Pau Espin Pedrol From gerrit-no-reply at lists.osmocom.org Mon Apr 24 14:01:09 2017 From: gerrit-no-reply at lists.osmocom.org (Vadim Yanitskiy) Date: Mon, 24 Apr 2017 14:01:09 +0000 Subject: [PATCH] osmocom-bb[master]: Makefile: add forgotten gsmmap to (dist)clean section Message-ID: Review at https://gerrit.osmocom.org/2398 Makefile: add forgotten gsmmap to (dist)clean section Change-Id: I14abe8a061d218ca81dd2d101b218d3030324aa2 --- M src/Makefile 1 file changed, 2 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmocom-bb refs/changes/98/2398/1 diff --git a/src/Makefile b/src/Makefile index a145880..00231a6 100644 --- a/src/Makefile +++ b/src/Makefile @@ -85,6 +85,7 @@ make -C shared/libosmocore/build-target $@ make -C host/layer23 $@ make -C host/osmocon $@ + make -C host/gsmmap $@ make -C target/firmware $@ make -C target/firmware -f Makefile.mtk $@ @@ -92,5 +93,6 @@ rm -rf shared/libosmocore/build-target make -C host/layer23 $@ make -C host/osmocon $@ + make -C host/gsmmap $@ # 'firmware' also handles 'mtk-firmware' make -C target/firmware $@ -- To view, visit https://gerrit.osmocom.org/2398 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I14abe8a061d218ca81dd2d101b218d3030324aa2 Gerrit-PatchSet: 1 Gerrit-Project: osmocom-bb Gerrit-Branch: master Gerrit-Owner: Vadim Yanitskiy From gerrit-no-reply at lists.osmocom.org Mon Apr 24 14:31:37 2017 From: gerrit-no-reply at lists.osmocom.org (daniel) Date: Mon, 24 Apr 2017 14:31:37 +0000 Subject: libosmo-netif[master]: osmux: Fix delay between RTP packets In-Reply-To: References: Message-ID: Patch Set 1: Code-Review-1 Could you elaborate a bit more on the difference between DELTA_RTP_{MSG,TIMESTAMP}? Just looking at it it's confusing why one should be 160 and the other is 20000. Maybe add a your commit message as a comment in the code? Otherwise nice find! -- To view, visit https://gerrit.osmocom.org/2397 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I36dc69f9caf591dd1b578bc914a2ce426c7f2813 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Pau Espin Pedrol Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: daniel Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Mon Apr 24 14:54:00 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Mon, 24 Apr 2017 14:54:00 +0000 Subject: osmo-trx[master]: ssedetect: Add runtime CPU detection In-Reply-To: References: Message-ID: Patch Set 3: Do we officially support anything besides gcc? -- To view, visit https://gerrit.osmocom.org/2100 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Iba74f8a6e4e921ff31e4bd9f0c7c881fe547423a Gerrit-PatchSet: 3 Gerrit-Project: osmo-trx Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Vadim Yanitskiy Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Mon Apr 24 15:06:49 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Mon, 24 Apr 2017 15:06:49 +0000 Subject: osmocom-bb[master]: Makefile: add forgotten gsmmap to (dist)clean section In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+1 Note: we really need jenkins tests for added confidence :) -- To view, visit https://gerrit.osmocom.org/2398 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I14abe8a061d218ca81dd2d101b218d3030324aa2 Gerrit-PatchSet: 1 Gerrit-Project: osmocom-bb Gerrit-Branch: master Gerrit-Owner: Vadim Yanitskiy Gerrit-Reviewer: Max Gerrit-HasComments: No From admin at opensuse.org Mon Apr 24 15:18:59 2017 From: admin at opensuse.org (OBS Notification) Date: Mon, 24 Apr 2017 15:18:59 +0000 Subject: Build failure of network:osmocom:nightly/libosmo-sccp in xUbuntu_17.04/x86_64 In-Reply-To: References: Message-ID: <58fe178b1ad52_1bbd9c0f7c26266a@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/libosmo-sccp/xUbuntu_17.04/x86_64 Package network:osmocom:nightly/libosmo-sccp failed to build in xUbuntu_17.04/x86_64 Check out the package for editing: osc checkout network:osmocom:nightly libosmo-sccp Last lines of build log: [ 97s] ./src/xua_asp_fsm.c:772: undefined reference to `ipa_ccm_send_id_req' [ 97s] ../../src/.libs/libosmo-sigtran.a(ipa.o): In function `ipa_tx_xua_as': [ 97s] ./src/ipa.c:71: undefined reference to `ipa_msg_alloc' [ 97s] collect2: error: ld returned 1 exit status [ 97s] Makefile:360: recipe for target 'xua_test' failed [ 97s] make[4]: *** [xua_test] Error 1 [ 97s] make[4]: Leaving directory '/usr/src/packages/BUILD/tests/xua' [ 97s] Makefile:362: recipe for target 'all-recursive' failed [ 97s] make[3]: *** [all-recursive] Error 1 [ 97s] make[3]: Leaving directory '/usr/src/packages/BUILD/tests' [ 97s] Makefile:454: recipe for target 'all-recursive' failed [ 97s] make[2]: *** [all-recursive] Error 1 [ 97s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 97s] Makefile:372: recipe for target 'all' failed [ 97s] make[1]: *** [all] Error 2 [ 97s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 97s] dh_auto_build: make -j1 returned exit code 2 [ 97s] debian/rules:12: recipe for target 'build' failed [ 97s] make: *** [build] Error 2 [ 97s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 97s] [ 97s] lamb08 failed "build libosmo-sccp_0.7.1.20170423.dsc" at Mon Apr 24 15:18:53 UTC 2017. [ 97s] [ 97s] ### VM INTERACTION START ### [ 100s] [ 87.098750] reboot: Power down [ 100s] ### VM INTERACTION END ### [ 100s] [ 100s] lamb08 failed "build libosmo-sccp_0.7.1.20170423.dsc" at Mon Apr 24 15:18:57 UTC 2017. [ 100s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Mon Apr 24 15:19:34 2017 From: admin at opensuse.org (OBS Notification) Date: Mon, 24 Apr 2017 15:19:34 +0000 Subject: Build failure of network:osmocom:nightly/libosmo-sccp in xUbuntu_17.04/i586 In-Reply-To: References: Message-ID: <58fe17ab8dbe9_1bc99c0f7c27442e@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/libosmo-sccp/xUbuntu_17.04/i586 Package network:osmocom:nightly/libosmo-sccp failed to build in xUbuntu_17.04/i586 Check out the package for editing: osc checkout network:osmocom:nightly libosmo-sccp Last lines of build log: [ 97s] ./src/xua_asp_fsm.c:772: undefined reference to `ipa_ccm_send_id_req' [ 97s] ../../src/.libs/libosmo-sigtran.a(ipa.o): In function `ipa_tx_xua_as': [ 97s] ./src/ipa.c:71: undefined reference to `ipa_msg_alloc' [ 97s] collect2: error: ld returned 1 exit status [ 97s] Makefile:360: recipe for target 'xua_test' failed [ 97s] make[4]: *** [xua_test] Error 1 [ 97s] make[4]: Leaving directory '/usr/src/packages/BUILD/tests/xua' [ 97s] Makefile:362: recipe for target 'all-recursive' failed [ 97s] make[3]: *** [all-recursive] Error 1 [ 97s] make[3]: Leaving directory '/usr/src/packages/BUILD/tests' [ 97s] Makefile:454: recipe for target 'all-recursive' failed [ 97s] make[2]: *** [all-recursive] Error 1 [ 97s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 97s] Makefile:372: recipe for target 'all' failed [ 97s] make[1]: *** [all] Error 2 [ 97s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 97s] dh_auto_build: make -j1 returned exit code 2 [ 97s] debian/rules:12: recipe for target 'build' failed [ 97s] make: *** [build] Error 2 [ 97s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 97s] [ 97s] lamb65 failed "build libosmo-sccp_0.7.1.20170423.dsc" at Mon Apr 24 15:19:15 UTC 2017. [ 97s] [ 97s] ### VM INTERACTION START ### [ 101s] [ 88.539781] reboot: Power down [ 101s] ### VM INTERACTION END ### [ 101s] [ 101s] lamb65 failed "build libosmo-sccp_0.7.1.20170423.dsc" at Mon Apr 24 15:19:19 UTC 2017. [ 101s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Mon Apr 24 15:21:22 2017 From: admin at opensuse.org (OBS Notification) Date: Mon, 24 Apr 2017 15:21:22 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in xUbuntu_17.04/i586 In-Reply-To: References: Message-ID: <58fe181d915b0_1bc39c0f7c2727eb@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/xUbuntu_17.04/i586 Package network:osmocom:nightly/osmo-stp failed to build in xUbuntu_17.04/i586 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 74s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o vty_interface_cmds.o vty_interface_cmds.c [ 74s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o mgcp_patch.o mgcp_patch.c [ 74s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o mgcp_callagent.o mgcp_callagent.c [ 74s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o isup_filter.o isup_filter.c [ 74s] gcc -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -Wl,-Bsymbolic-functions -Wl,-z,relro -o cellmgr_ng main.o mtp_layer3.o thread.o ipaccess.o pcap.o bss_patch.o bssap_sccp.o bsc_sccp.o bsc_ussd.o links.o msc_conn.o link_udp.o snmp_mtp.o debug.o isup.o mtp_link.o counter.o sccp_state.o bsc.o ss7_application.o vty_interface_legacy.o vty_interface_cmds.o mgcp_patch.o mgcp_callagent.o isup_filter.o -losmosccp -losmoxua -ltalloc -losmogsm -losmocore -ltalloc -losmovty -losmocore -ltalloc -losmocore -lpthread -lnetsnmp -lcrypto [ 74s] /usr/lib/gcc/i686-linux-gnu/6/../../../i386-linux-gnu/libosmosccp.so: undefined reference to `talloc_free' [ 74s] collect2: error: ld returned 1 exit status [ 74s] Makefile:425: recipe for target 'cellmgr_ng' failed [ 74s] make[3]: *** [cellmgr_ng] Error 1 [ 74s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 74s] Makefile:380: recipe for target 'all-recursive' failed [ 74s] make[2]: *** [all-recursive] Error 1 [ 74s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 74s] Makefile:321: recipe for target 'all' failed [ 74s] make[1]: *** [all] Error 2 [ 74s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 74s] dh_auto_build: make -j1 returned exit code 2 [ 74s] debian/rules:23: recipe for target 'build' failed [ 74s] make: *** [build] Error 2 [ 74s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 74s] [ 74s] lamb57 failed "build cellmgr-ng_1.4.7.20170423.dsc" at Mon Apr 24 15:21:06 UTC 2017. [ 74s] [ 74s] ### VM INTERACTION START ### [ 77s] [ 64.434319] reboot: Power down [ 78s] ### VM INTERACTION END ### [ 78s] [ 78s] lamb57 failed "build cellmgr-ng_1.4.7.20170423.dsc" at Mon Apr 24 15:21:10 UTC 2017. [ 78s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Mon Apr 24 15:21:51 2017 From: admin at opensuse.org (OBS Notification) Date: Mon, 24 Apr 2017 15:21:51 +0000 Subject: Build failure of network:osmocom:nightly/openbsc in xUbuntu_17.04/x86_64 In-Reply-To: References: Message-ID: <58fe183faf57e_1bc39c0f7c27408a@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/openbsc/xUbuntu_17.04/x86_64 Package network:osmocom:nightly/openbsc failed to build in xUbuntu_17.04/x86_64 Check out the package for editing: osc checkout network:osmocom:nightly openbsc Last lines of build log: [ 116s] gcc -DHAVE_CONFIG_H -I. -I../.. -I../../include -I../.. -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fPIE -fstack-protector-strong -Wformat -Werror=format-security -Werror=implicit -Werror=maybe-uninitialized -Werror=memset-transposed-args -Werror=null-dereference -Werror=sizeof-array-argument -Werror=sizeof-pointer-memaccess -c -o bsc_nat_filter.o bsc_nat_filter.c [ 116s] gcc -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fPIE -fstack-protector-strong -Wformat -Werror=format-security -Werror=implicit -Werror=maybe-uninitialized -Werror=memset-transposed-args -Werror=null-dereference -Werror=sizeof-array-argument -Werror=sizeof-pointer-memaccess -Wl,-Bsymbolic-functions -fPIE -pie -Wl,-z,relro -Wl,-z,now -o osmo-bsc_nat bsc_filter.o bsc_mgcp_utils.o bsc_nat.o bsc_nat_utils.o bsc_nat_vty.o bsc_sccp.o bsc_ussd.o bsc_nat_ctrl.o bsc_nat_rewrite.o bsc_nat_rewrite_trie.o bsc_nat_filter.o ../../src/libmgcp/libmgcp.a ../../src/libfilter/libfilter.a ../../src/libbsc/libbsc.a ../../src/libcommon-cs/libcommon-cs.a ../../src/libtrau/libtrau.a ../../src/libcommon/libcommon.a -losmosccp -losmoxua -ltalloc -losmocore -ltalloc -losmogsm -losmocore -ltalloc -losmovty -losmocore -ltalloc -losmoctrl -losmogsm -losmocore -losmoabis -losmonetif -lcrypto -lrt [ 116s] /usr/lib/gcc/x86_64-linux-gnu/6/../../../x86_64-linux-gnu/libosmosccp.so: undefined reference to `talloc_free' [ 116s] collect2: error: ld returned 1 exit status [ 116s] Makefile:460: recipe for target 'osmo-bsc_nat' failed [ 116s] make[4]: *** [osmo-bsc_nat] Error 1 [ 116s] make[4]: Leaving directory '/usr/src/packages/BUILD/openbsc/src/osmo-bsc_nat' [ 116s] Makefile:418: recipe for target 'all-recursive' failed [ 116s] make[3]: *** [all-recursive] Error 1 [ 116s] make[3]: Leaving directory '/usr/src/packages/BUILD/openbsc/src' [ 116s] Makefile:486: recipe for target 'all-recursive' failed [ 116s] make[2]: *** [all-recursive] Error 1 [ 116s] make[2]: Leaving directory '/usr/src/packages/BUILD/openbsc' [ 116s] Makefile:404: recipe for target 'all' failed [ 116s] make[1]: *** [all] Error 2 [ 116s] make[1]: Leaving directory '/usr/src/packages/BUILD/openbsc' [ 116s] dh_auto_build: make -j1 returned exit code 2 [ 116s] debian/rules:13: recipe for target 'build' failed [ 116s] make: *** [build] Error 2 [ 116s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 116s] [ 116s] lamb59 failed "build openbsc_0.15.1.20170423.dsc" at Mon Apr 24 15:21:32 UTC 2017. [ 116s] [ 116s] ### VM INTERACTION START ### [ 119s] [ 107.180518] reboot: Power down [ 119s] ### VM INTERACTION END ### [ 119s] [ 119s] lamb59 failed "build openbsc_0.15.1.20170423.dsc" at Mon Apr 24 15:21:36 UTC 2017. [ 119s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Mon Apr 24 15:21:51 2017 From: admin at opensuse.org (OBS Notification) Date: Mon, 24 Apr 2017 15:21:51 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in xUbuntu_17.04/x86_64 In-Reply-To: References: Message-ID: <58fe18404dcd_1bc39c0f7c27419d@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/xUbuntu_17.04/x86_64 Package network:osmocom:nightly/osmo-stp failed to build in xUbuntu_17.04/x86_64 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 104s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o vty_interface_cmds.o vty_interface_cmds.c [ 105s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o mgcp_patch.o mgcp_patch.c [ 105s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o mgcp_callagent.o mgcp_callagent.c [ 105s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o isup_filter.o isup_filter.c [ 105s] gcc -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -Wl,-Bsymbolic-functions -Wl,-z,relro -o cellmgr_ng main.o mtp_layer3.o thread.o ipaccess.o pcap.o bss_patch.o bssap_sccp.o bsc_sccp.o bsc_ussd.o links.o msc_conn.o link_udp.o snmp_mtp.o debug.o isup.o mtp_link.o counter.o sccp_state.o bsc.o ss7_application.o vty_interface_legacy.o vty_interface_cmds.o mgcp_patch.o mgcp_callagent.o isup_filter.o -losmosccp -losmoxua -ltalloc -losmogsm -losmocore -ltalloc -losmovty -losmocore -ltalloc -losmocore -lpthread -lnetsnmp -lcrypto [ 105s] /usr/lib/gcc/x86_64-linux-gnu/6/../../../x86_64-linux-gnu/libosmosccp.so: undefined reference to `talloc_free' [ 105s] collect2: error: ld returned 1 exit status [ 105s] Makefile:425: recipe for target 'cellmgr_ng' failed [ 105s] make[3]: *** [cellmgr_ng] Error 1 [ 105s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 105s] Makefile:380: recipe for target 'all-recursive' failed [ 105s] make[2]: *** [all-recursive] Error 1 [ 105s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 105s] Makefile:321: recipe for target 'all' failed [ 105s] make[1]: *** [all] Error 2 [ 105s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 105s] dh_auto_build: make -j1 returned exit code 2 [ 105s] debian/rules:23: recipe for target 'build' failed [ 105s] make: *** [build] Error 2 [ 105s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 105s] [ 105s] cloud129 failed "build cellmgr-ng_1.4.7.20170423.dsc" at Mon Apr 24 15:21:32 UTC 2017. [ 105s] [ 105s] ### VM INTERACTION START ### [ 108s] [ 81.417110] reboot: Power down [ 110s] ### VM INTERACTION END ### [ 110s] [ 110s] cloud129 failed "build cellmgr-ng_1.4.7.20170423.dsc" at Mon Apr 24 15:21:37 UTC 2017. [ 110s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Mon Apr 24 15:21:51 2017 From: admin at opensuse.org (OBS Notification) Date: Mon, 24 Apr 2017 15:21:51 +0000 Subject: Build failure of network:osmocom:nightly/openbsc in xUbuntu_17.04/i586 In-Reply-To: References: Message-ID: <58fe1840c2f24_1bc39c0f7c2742b5@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/openbsc/xUbuntu_17.04/i586 Package network:osmocom:nightly/openbsc failed to build in xUbuntu_17.04/i586 Check out the package for editing: osc checkout network:osmocom:nightly openbsc Last lines of build log: [ 110s] gcc -DHAVE_CONFIG_H -I. -I../.. -I../../include -I../.. -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fPIE -fstack-protector-strong -Wformat -Werror=format-security -Werror=implicit -Werror=maybe-uninitialized -Werror=memset-transposed-args -Werror=null-dereference -Werror=sizeof-array-argument -Werror=sizeof-pointer-memaccess -c -o bsc_nat_filter.o bsc_nat_filter.c [ 111s] gcc -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fPIE -fstack-protector-strong -Wformat -Werror=format-security -Werror=implicit -Werror=maybe-uninitialized -Werror=memset-transposed-args -Werror=null-dereference -Werror=sizeof-array-argument -Werror=sizeof-pointer-memaccess -Wl,-Bsymbolic-functions -fPIE -pie -Wl,-z,relro -Wl,-z,now -o osmo-bsc_nat bsc_filter.o bsc_mgcp_utils.o bsc_nat.o bsc_nat_utils.o bsc_nat_vty.o bsc_sccp.o bsc_ussd.o bsc_nat_ctrl.o bsc_nat_rewrite.o bsc_nat_rewrite_trie.o bsc_nat_filter.o ../../src/libmgcp/libmgcp.a ../../src/libfilter/libfilter.a ../../src/libbsc/libbsc.a ../../src/libcommon-cs/libcommon-cs.a ../../src/libtrau/libtrau.a ../../src/libcommon/libcommon.a -losmosccp -losmoxua -ltalloc -losmocore -ltalloc -losmogsm -losmocore -ltalloc -losmovty -losmocore -ltalloc -losmoctrl -losmogsm -losmocore -losmoabis -losmonetif -lcrypto -lrt [ 111s] /usr/lib/gcc/i686-linux-gnu/6/../../../i386-linux-gnu/libosmosccp.so: undefined reference to `talloc_free' [ 111s] collect2: error: ld returned 1 exit status [ 111s] Makefile:460: recipe for target 'osmo-bsc_nat' failed [ 111s] make[4]: *** [osmo-bsc_nat] Error 1 [ 111s] make[4]: Leaving directory '/usr/src/packages/BUILD/openbsc/src/osmo-bsc_nat' [ 111s] Makefile:418: recipe for target 'all-recursive' failed [ 111s] make[3]: *** [all-recursive] Error 1 [ 111s] make[3]: Leaving directory '/usr/src/packages/BUILD/openbsc/src' [ 111s] Makefile:486: recipe for target 'all-recursive' failed [ 111s] make[2]: *** [all-recursive] Error 1 [ 111s] make[2]: Leaving directory '/usr/src/packages/BUILD/openbsc' [ 111s] Makefile:404: recipe for target 'all' failed [ 111s] make[1]: *** [all] Error 2 [ 111s] make[1]: Leaving directory '/usr/src/packages/BUILD/openbsc' [ 111s] dh_auto_build: make -j1 returned exit code 2 [ 111s] debian/rules:13: recipe for target 'build' failed [ 111s] make: *** [build] Error 2 [ 111s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 111s] [ 111s] wildcard3 failed "build openbsc_0.15.1.20170423.dsc" at Mon Apr 24 15:21:44 UTC 2017. [ 111s] [ 111s] ### VM INTERACTION START ### [ 114s] [ 99.054356] reboot: Power down [ 114s] ### VM INTERACTION END ### [ 114s] [ 114s] wildcard3 failed "build openbsc_0.15.1.20170423.dsc" at Mon Apr 24 15:21:47 UTC 2017. [ 114s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Mon Apr 24 15:23:16 2017 From: admin at opensuse.org (OBS Notification) Date: Mon, 24 Apr 2017 15:23:16 +0000 Subject: Build failure of network:osmocom:nightly/osmo-bts in xUbuntu_17.04/x86_64 In-Reply-To: References: Message-ID: <58fe18aeea4b1_1bc99c0f7c287447@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-bts/xUbuntu_17.04/x86_64 Package network:osmocom:nightly/osmo-bts failed to build in xUbuntu_17.04/x86_64 Check out the package for editing: osc checkout network:osmocom:nightly osmo-bts Last lines of build log: [ 69s] [ 69s] /* confdefs.h */ [ 69s] #define PACKAGE_NAME "osmo-bts" [ 69s] #define PACKAGE_TARNAME "osmo-bts" [ 69s] #define PACKAGE_VERSION "0.5.0.20170423" [ 69s] #define PACKAGE_STRING "osmo-bts 0.5.0.20170423" [ 69s] #define PACKAGE_BUGREPORT "openbsc-devel at lists.openbsc.org" [ 69s] #define PACKAGE_URL "" [ 69s] #define PACKAGE "osmo-bts" [ 69s] #define VERSION "0.5.0.20170423" [ 69s] #define STDC_HEADERS 1 [ 69s] [ 69s] configure: exit 1 [ 69s] dh_auto_configure: ./configure --build=x86_64-linux-gnu --prefix=/usr --includedir=${prefix}/include --mandir=${prefix}/share/man --infodir=${prefix}/share/info --sysconfdir=/etc --localstatedir=/var --disable-silent-rules --libdir=${prefix}/lib/x86_64-linux-gnu --libexecdir=${prefix}/lib/x86_64-linux-gnu --disable-maintainer-mode --disable-dependency-tracking --enable-trx --with-openbsc=/usr/src/osmocom/openbsc/openbsc/include/ returned exit code 1 [ 69s] debian/rules:22: recipe for target 'override_dh_auto_configure' failed [ 69s] make[1]: *** [override_dh_auto_configure] Error 2 [ 69s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 69s] debian/rules:12: recipe for target 'build' failed [ 69s] make: *** [build] Error 2 [ 69s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 69s] [ 69s] lamb21 failed "build osmo-bts_0.5.0.20170423.dsc" at Mon Apr 24 15:23:03 UTC 2017. [ 69s] [ 69s] ### VM INTERACTION START ### [ 72s] [ 58.962297] reboot: Power down [ 72s] ### VM INTERACTION END ### [ 72s] [ 72s] lamb21 failed "build osmo-bts_0.5.0.20170423.dsc" at Mon Apr 24 15:23:07 UTC 2017. [ 72s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Mon Apr 24 15:23:34 2017 From: admin at opensuse.org (OBS Notification) Date: Mon, 24 Apr 2017 15:23:34 +0000 Subject: Build failure of network:osmocom:nightly/osmo-bts in xUbuntu_17.04/i586 In-Reply-To: References: Message-ID: <58fe18b83d08f_1bc39c0f7c275673@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-bts/xUbuntu_17.04/i586 Package network:osmocom:nightly/osmo-bts failed to build in xUbuntu_17.04/i586 Check out the package for editing: osc checkout network:osmocom:nightly osmo-bts Last lines of build log: [ 69s] [ 69s] /* confdefs.h */ [ 69s] #define PACKAGE_NAME "osmo-bts" [ 69s] #define PACKAGE_TARNAME "osmo-bts" [ 69s] #define PACKAGE_VERSION "0.5.0.20170423" [ 69s] #define PACKAGE_STRING "osmo-bts 0.5.0.20170423" [ 69s] #define PACKAGE_BUGREPORT "openbsc-devel at lists.openbsc.org" [ 69s] #define PACKAGE_URL "" [ 69s] #define PACKAGE "osmo-bts" [ 69s] #define VERSION "0.5.0.20170423" [ 69s] #define STDC_HEADERS 1 [ 69s] [ 69s] configure: exit 1 [ 69s] dh_auto_configure: ./configure --build=i686-linux-gnu --prefix=/usr --includedir=${prefix}/include --mandir=${prefix}/share/man --infodir=${prefix}/share/info --sysconfdir=/etc --localstatedir=/var --disable-silent-rules --libdir=${prefix}/lib/i386-linux-gnu --libexecdir=${prefix}/lib/i386-linux-gnu --disable-maintainer-mode --disable-dependency-tracking --enable-trx --with-openbsc=/usr/src/osmocom/openbsc/openbsc/include/ returned exit code 1 [ 69s] debian/rules:22: recipe for target 'override_dh_auto_configure' failed [ 69s] make[1]: *** [override_dh_auto_configure] Error 2 [ 69s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 69s] debian/rules:12: recipe for target 'build' failed [ 69s] make: *** [build] Error 2 [ 69s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 69s] [ 69s] lamb59 failed "build osmo-bts_0.5.0.20170423.dsc" at Mon Apr 24 15:23:15 UTC 2017. [ 69s] [ 69s] ### VM INTERACTION START ### [ 72s] [ 59.883362] reboot: Power down [ 72s] ### VM INTERACTION END ### [ 72s] [ 72s] lamb59 failed "build osmo-bts_0.5.0.20170423.dsc" at Mon Apr 24 15:23:18 UTC 2017. [ 72s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Mon Apr 24 19:58:01 2017 From: admin at opensuse.org (OBS Notification) Date: Mon, 24 Apr 2017 19:58:01 +0000 Subject: Build failure of network:osmocom:nightly/libosmo-sccp in xUbuntu_16.10/x86_64 In-Reply-To: References: Message-ID: <58fe58ed67f38_1bc99c0f7c329729@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/libosmo-sccp/xUbuntu_16.10/x86_64 Package network:osmocom:nightly/libosmo-sccp failed to build in xUbuntu_16.10/x86_64 Check out the package for editing: osc checkout network:osmocom:nightly libosmo-sccp Last lines of build log: [ 53s] ./src/xua_asp_fsm.c:772: undefined reference to `ipa_ccm_send_id_req' [ 53s] ../../src/.libs/libosmo-sigtran.a(ipa.o): In function `ipa_tx_xua_as': [ 53s] ./src/ipa.c:71: undefined reference to `ipa_msg_alloc' [ 53s] collect2: error: ld returned 1 exit status [ 53s] Makefile:360: recipe for target 'xua_test' failed [ 53s] make[4]: *** [xua_test] Error 1 [ 53s] make[4]: Leaving directory '/usr/src/packages/BUILD/tests/xua' [ 53s] Makefile:362: recipe for target 'all-recursive' failed [ 53s] make[3]: *** [all-recursive] Error 1 [ 53s] make[3]: Leaving directory '/usr/src/packages/BUILD/tests' [ 53s] Makefile:454: recipe for target 'all-recursive' failed [ 53s] make[2]: *** [all-recursive] Error 1 [ 53s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 53s] Makefile:372: recipe for target 'all' failed [ 53s] make[1]: *** [all] Error 2 [ 53s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 53s] dh_auto_build: make -j1 returned exit code 2 [ 53s] debian/rules:12: recipe for target 'build' failed [ 53s] make: *** [build] Error 2 [ 53s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 53s] [ 53s] build71 failed "build libosmo-sccp_0.7.1.20170424.dsc" at Mon Apr 24 19:57:44 UTC 2017. [ 53s] [ 53s] ### VM INTERACTION START ### [ 57s] [ 48.737134] reboot: Power down [ 57s] ### VM INTERACTION END ### [ 57s] [ 57s] build71 failed "build libosmo-sccp_0.7.1.20170424.dsc" at Mon Apr 24 19:57:48 UTC 2017. [ 57s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Mon Apr 24 19:58:35 2017 From: admin at opensuse.org (OBS Notification) Date: Mon, 24 Apr 2017 19:58:35 +0000 Subject: Build failure of network:osmocom:nightly/libosmo-sccp in xUbuntu_17.04/i586 In-Reply-To: References: Message-ID: <58fe58ef2c765_1bc99c0f7c329854@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/libosmo-sccp/xUbuntu_17.04/i586 Package network:osmocom:nightly/libosmo-sccp failed to build in xUbuntu_17.04/i586 Check out the package for editing: osc checkout network:osmocom:nightly libosmo-sccp Last lines of build log: [ 59s] ./src/xua_asp_fsm.c:772: undefined reference to `ipa_ccm_send_id_req' [ 59s] ../../src/.libs/libosmo-sigtran.a(ipa.o): In function `ipa_tx_xua_as': [ 59s] ./src/ipa.c:71: undefined reference to `ipa_msg_alloc' [ 59s] collect2: error: ld returned 1 exit status [ 59s] Makefile:360: recipe for target 'xua_test' failed [ 59s] make[4]: *** [xua_test] Error 1 [ 59s] make[4]: Leaving directory '/usr/src/packages/BUILD/tests/xua' [ 59s] Makefile:362: recipe for target 'all-recursive' failed [ 59s] make[3]: *** [all-recursive] Error 1 [ 59s] make[3]: Leaving directory '/usr/src/packages/BUILD/tests' [ 59s] Makefile:454: recipe for target 'all-recursive' failed [ 59s] make[2]: *** [all-recursive] Error 1 [ 59s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 59s] Makefile:372: recipe for target 'all' failed [ 59s] make[1]: *** [all] Error 2 [ 59s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 59s] dh_auto_build: make -j1 returned exit code 2 [ 59s] debian/rules:12: recipe for target 'build' failed [ 59s] make: *** [build] Error 2 [ 59s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 59s] [ 59s] build85 failed "build libosmo-sccp_0.7.1.20170424.dsc" at Mon Apr 24 19:58:15 UTC 2017. [ 59s] [ 59s] ### VM INTERACTION START ### [ 62s] [ 52.545846] reboot: Power down [ 62s] ### VM INTERACTION END ### [ 62s] [ 62s] build85 failed "build libosmo-sccp_0.7.1.20170424.dsc" at Mon Apr 24 19:58:19 UTC 2017. [ 62s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Mon Apr 24 19:58:35 2017 From: admin at opensuse.org (OBS Notification) Date: Mon, 24 Apr 2017 19:58:35 +0000 Subject: Build failure of network:osmocom:nightly/libosmo-sccp in Debian_8.0/x86_64 In-Reply-To: References: Message-ID: <58fe58ef8cbdf_1bc99c0f7c329939@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/libosmo-sccp/Debian_8.0/x86_64 Package network:osmocom:nightly/libosmo-sccp failed to build in Debian_8.0/x86_64 Check out the package for editing: osc checkout network:osmocom:nightly libosmo-sccp Last lines of build log: [ 99s] CCLD xua_test [ 99s] /usr/bin/ld: ../../src/.libs/libosmo-sigtran.a(osmo_ss7.o): undefined reference to symbol 'ipa_msg_recv_buffered@@LIBOSMOGSM_1.0' [ 99s] //usr/lib/x86_64-linux-gnu/libosmogsm.so.6: error adding symbols: DSO missing from command line [ 99s] collect2: error: ld returned 1 exit status [ 99s] Makefile:348: recipe for target 'xua_test' failed [ 99s] make[4]: *** [xua_test] Error 1 [ 99s] make[4]: Leaving directory '/usr/src/packages/BUILD/tests/xua' [ 99s] Makefile:350: recipe for target 'all-recursive' failed [ 99s] make[3]: *** [all-recursive] Error 1 [ 99s] make[3]: Leaving directory '/usr/src/packages/BUILD/tests' [ 99s] Makefile:443: recipe for target 'all-recursive' failed [ 99s] make[2]: *** [all-recursive] Error 1 [ 99s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 99s] Makefile:360: recipe for target 'all' failed [ 99s] make[1]: *** [all] Error 2 [ 99s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 99s] dh_auto_build: make -j1 returned exit code 2 [ 99s] debian/rules:12: recipe for target 'build' failed [ 99s] make: *** [build] Error 2 [ 99s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 99s] [ 99s] lamb12 failed "build libosmo-sccp_0.7.1.20170424.dsc" at Mon Apr 24 19:58:24 UTC 2017. [ 99s] [ 99s] ### VM INTERACTION START ### [ 100s] Powering off. [ 100s] ### VM INTERACTION END ### [ 100s] [ 100s] lamb12 failed "build libosmo-sccp_0.7.1.20170424.dsc" at Mon Apr 24 19:58:25 UTC 2017. [ 100s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Mon Apr 24 19:59:26 2017 From: admin at opensuse.org (OBS Notification) Date: Mon, 24 Apr 2017 19:59:26 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in xUbuntu_16.10/x86_64 In-Reply-To: References: Message-ID: <58fe59472a9a2_1bc99c0f7c3300ef@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/xUbuntu_16.10/x86_64 Package network:osmocom:nightly/osmo-stp failed to build in xUbuntu_16.10/x86_64 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 76s] ^~~~~~~ [ 76s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o vty_interface.o vty_interface.c [ 76s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o sctp_m3ua_client.o sctp_m3ua_client.c [ 76s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 76s] #include [ 76s] ^ [ 76s] compilation terminated. [ 76s] Makefile:485: recipe for target 'sctp_m3ua_client.o' failed [ 76s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 76s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 76s] Makefile:380: recipe for target 'all-recursive' failed [ 76s] make[2]: *** [all-recursive] Error 1 [ 76s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 76s] Makefile:321: recipe for target 'all' failed [ 76s] make[1]: *** [all] Error 2 [ 76s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 76s] dh_auto_build: make -j1 returned exit code 2 [ 76s] debian/rules:23: recipe for target 'build' failed [ 76s] make: *** [build] Error 2 [ 76s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 77s] [ 77s] lamb03 failed "build cellmgr-ng_1.4.7.20170424.dsc" at Mon Apr 24 19:59:18 UTC 2017. [ 77s] [ 77s] ### VM INTERACTION START ### [ 80s] [ 66.095679] reboot: Power down [ 80s] ### VM INTERACTION END ### [ 80s] [ 80s] lamb03 failed "build cellmgr-ng_1.4.7.20170424.dsc" at Mon Apr 24 19:59:22 UTC 2017. [ 80s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Mon Apr 24 20:00:00 2017 From: admin at opensuse.org (OBS Notification) Date: Mon, 24 Apr 2017 20:00:00 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in xUbuntu_17.04/i586 In-Reply-To: References: Message-ID: <58fe59634dd73_1bbd9c0f7c313571@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/xUbuntu_17.04/i586 Package network:osmocom:nightly/osmo-stp failed to build in xUbuntu_17.04/i586 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 70s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o vty_interface_legacy.o vty_interface_legacy.c [ 70s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o vty_interface_cmds.o vty_interface_cmds.c [ 70s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o mgcp_patch.o mgcp_patch.c [ 70s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o mgcp_callagent.o mgcp_callagent.c [ 70s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o isup_filter.o isup_filter.c [ 70s] gcc -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -Wl,-Bsymbolic-functions -Wl,-z,relro -o cellmgr_ng main.o mtp_layer3.o thread.o ipaccess.o pcap.o bss_patch.o bssap_sccp.o bsc_sccp.o bsc_ussd.o links.o msc_conn.o link_udp.o snmp_mtp.o debug.o isup.o mtp_link.o counter.o sccp_state.o bsc.o ss7_application.o vty_interface_legacy.o vty_interface_cmds.o mgcp_patch.o mgcp_callagent.o isup_filter.o -losmosccp -losmoxua -ltalloc -losmogsm -losmocore -ltalloc -losmovty -losmocore -ltalloc -losmocore -lpthread -lnetsnmp -lcrypto [ 70s] /usr/lib/gcc/i686-linux-gnu/6/../../../i386-linux-gnu/libosmosccp.so: undefined reference to `talloc_free' [ 70s] collect2: error: ld returned 1 exit status [ 70s] Makefile:425: recipe for target 'cellmgr_ng' failed [ 70s] make[3]: *** [cellmgr_ng] Error 1 [ 70s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 70s] Makefile:380: recipe for target 'all-recursive' failed [ 70s] make[2]: *** [all-recursive] Error 1 [ 70s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 70s] Makefile:321: recipe for target 'all' failed [ 70s] make[1]: *** [all] Error 2 [ 70s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 70s] dh_auto_build: make -j1 returned exit code 2 [ 70s] debian/rules:23: recipe for target 'build' failed [ 70s] make: *** [build] Error 2 [ 70s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 70s] [ 70s] wildcard2 failed "build cellmgr-ng_1.4.7.20170424.dsc" at Mon Apr 24 19:59:47 UTC 2017. [ 70s] [ 70s] ### VM INTERACTION START ### [ 75s] ### VM INTERACTION END ### [ 75s] [ 75s] wildcard2 failed "build cellmgr-ng_1.4.7.20170424.dsc" at Mon Apr 24 19:59:52 UTC 2017. [ 75s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Mon Apr 24 20:00:00 2017 From: admin at opensuse.org (OBS Notification) Date: Mon, 24 Apr 2017 20:00:00 +0000 Subject: Build failure of network:osmocom:nightly/libosmo-sccp in xUbuntu_16.10/i586 In-Reply-To: References: Message-ID: <58fe596444ab3_1bbd9c0f7c3136d5@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/libosmo-sccp/xUbuntu_16.10/i586 Package network:osmocom:nightly/libosmo-sccp failed to build in xUbuntu_16.10/i586 Check out the package for editing: osc checkout network:osmocom:nightly libosmo-sccp Last lines of build log: [ 101s] ./src/xua_asp_fsm.c:772: undefined reference to `ipa_ccm_send_id_req' [ 101s] ../../src/.libs/libosmo-sigtran.a(ipa.o): In function `ipa_tx_xua_as': [ 101s] ./src/ipa.c:71: undefined reference to `ipa_msg_alloc' [ 101s] collect2: error: ld returned 1 exit status [ 101s] Makefile:360: recipe for target 'xua_test' failed [ 101s] make[4]: *** [xua_test] Error 1 [ 101s] make[4]: Leaving directory '/usr/src/packages/BUILD/tests/xua' [ 101s] Makefile:362: recipe for target 'all-recursive' failed [ 101s] make[3]: *** [all-recursive] Error 1 [ 101s] make[3]: Leaving directory '/usr/src/packages/BUILD/tests' [ 101s] Makefile:454: recipe for target 'all-recursive' failed [ 101s] make[2]: *** [all-recursive] Error 1 [ 101s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 101s] Makefile:372: recipe for target 'all' failed [ 101s] make[1]: *** [all] Error 2 [ 101s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 101s] dh_auto_build: make -j1 returned exit code 2 [ 101s] debian/rules:12: recipe for target 'build' failed [ 101s] make: *** [build] Error 2 [ 101s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 101s] [ 101s] lamb63 failed "build libosmo-sccp_0.7.1.20170424.dsc" at Mon Apr 24 19:59:43 UTC 2017. [ 101s] [ 101s] ### VM INTERACTION START ### [ 104s] [ 90.392922] reboot: Power down [ 104s] ### VM INTERACTION END ### [ 104s] [ 104s] lamb63 failed "build libosmo-sccp_0.7.1.20170424.dsc" at Mon Apr 24 19:59:46 UTC 2017. [ 104s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Mon Apr 24 20:00:17 2017 From: admin at opensuse.org (OBS Notification) Date: Mon, 24 Apr 2017 20:00:17 +0000 Subject: Build failure of network:osmocom:nightly/libosmo-sccp in xUbuntu_17.04/x86_64 In-Reply-To: References: Message-ID: <58fe59838f8a6_1bc39c0f7c327244@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/libosmo-sccp/xUbuntu_17.04/x86_64 Package network:osmocom:nightly/libosmo-sccp failed to build in xUbuntu_17.04/x86_64 Check out the package for editing: osc checkout network:osmocom:nightly libosmo-sccp Last lines of build log: [ 81s] ./src/xua_asp_fsm.c:772: undefined reference to `ipa_ccm_send_id_req' [ 81s] ../../src/.libs/libosmo-sigtran.a(ipa.o): In function `ipa_tx_xua_as': [ 81s] ./src/ipa.c:71: undefined reference to `ipa_msg_alloc' [ 81s] collect2: error: ld returned 1 exit status [ 81s] Makefile:360: recipe for target 'xua_test' failed [ 81s] make[4]: *** [xua_test] Error 1 [ 81s] make[4]: Leaving directory '/usr/src/packages/BUILD/tests/xua' [ 81s] Makefile:362: recipe for target 'all-recursive' failed [ 81s] make[3]: *** [all-recursive] Error 1 [ 81s] make[3]: Leaving directory '/usr/src/packages/BUILD/tests' [ 81s] Makefile:454: recipe for target 'all-recursive' failed [ 81s] make[2]: *** [all-recursive] Error 1 [ 81s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 81s] Makefile:372: recipe for target 'all' failed [ 81s] make[1]: *** [all] Error 2 [ 81s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 81s] dh_auto_build: make -j1 returned exit code 2 [ 81s] debian/rules:12: recipe for target 'build' failed [ 81s] make: *** [build] Error 2 [ 81s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 81s] [ 81s] wildcard3 failed "build libosmo-sccp_0.7.1.20170424.dsc" at Mon Apr 24 19:59:59 UTC 2017. [ 81s] [ 81s] ### VM INTERACTION START ### [ 84s] [ 71.211259] reboot: Power down [ 87s] ### VM INTERACTION END ### [ 87s] [ 87s] wildcard3 failed "build libosmo-sccp_0.7.1.20170424.dsc" at Mon Apr 24 20:00:05 UTC 2017. [ 87s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Mon Apr 24 20:00:17 2017 From: admin at opensuse.org (OBS Notification) Date: Mon, 24 Apr 2017 20:00:17 +0000 Subject: Build failure of network:osmocom:nightly/libosmo-sccp in Debian_8.0/i586 In-Reply-To: References: Message-ID: <58fe59848a518_1bc39c0f7c327493@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/libosmo-sccp/Debian_8.0/i586 Package network:osmocom:nightly/libosmo-sccp failed to build in Debian_8.0/i586 Check out the package for editing: osc checkout network:osmocom:nightly libosmo-sccp Last lines of build log: [ 102s] /usr/bin/ld: ../../src/.libs/libosmo-sigtran.a(osmo_ss7.o): undefined reference to symbol 'ipa_msg_recv_buffered@@LIBOSMOGSM_1.0' [ 102s] //usr/lib/i386-linux-gnu/libosmogsm.so.6: error adding symbols: DSO missing from command line [ 102s] collect2: error: ld returned 1 exit status [ 102s] Makefile:348: recipe for target 'xua_test' failed [ 102s] make[4]: *** [xua_test] Error 1 [ 102s] make[4]: Leaving directory '/usr/src/packages/BUILD/tests/xua' [ 102s] Makefile:350: recipe for target 'all-recursive' failed [ 102s] make[3]: *** [all-recursive] Error 1 [ 102s] make[3]: Leaving directory '/usr/src/packages/BUILD/tests' [ 102s] Makefile:443: recipe for target 'all-recursive' failed [ 102s] make[2]: *** [all-recursive] Error 1 [ 102s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 102s] Makefile:360: recipe for target 'all' failed [ 102s] make[1]: *** [all] Error 2 [ 102s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 102s] dh_auto_build: make -j1 returned exit code 2 [ 102s] debian/rules:12: recipe for target 'build' failed [ 102s] make: *** [build] Error 2 [ 102s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 102s] [ 102s] lamb57 failed "build libosmo-sccp_0.7.1.20170424.dsc" at Mon Apr 24 20:00:07 UTC 2017. [ 102s] [ 102s] ### VM INTERACTION START ### [ 103s] Powering off. [ 103s] [ 89.628263] reboot: Power down [ 103s] ### VM INTERACTION END ### [ 103s] [ 103s] lamb57 failed "build libosmo-sccp_0.7.1.20170424.dsc" at Mon Apr 24 20:00:08 UTC 2017. [ 103s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Mon Apr 24 20:00:17 2017 From: admin at opensuse.org (OBS Notification) Date: Mon, 24 Apr 2017 20:00:17 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in Debian_8.0/x86_64 In-Reply-To: References: Message-ID: <58fe5984c80f7_1bc39c0f7c3275d1@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/Debian_8.0/x86_64 Package network:osmocom:nightly/osmo-stp failed to build in Debian_8.0/x86_64 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 88s] CC vty_interface.o [ 89s] CC sctp_m3ua_client.o [ 89s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 89s] #include [ 89s] ^ [ 89s] compilation terminated. [ 89s] Makefile:475: recipe for target 'sctp_m3ua_client.o' failed [ 89s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 89s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 89s] Makefile:370: recipe for target 'all-recursive' failed [ 89s] make[2]: *** [all-recursive] Error 1 [ 89s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 89s] Makefile:310: recipe for target 'all' failed [ 89s] make[1]: *** [all] Error 2 [ 89s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 89s] dh_auto_build: make -j1 returned exit code 2 [ 89s] debian/rules:23: recipe for target 'build' failed [ 89s] make: *** [build] Error 2 [ 89s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 89s] [ 89s] lamb26 failed "build cellmgr-ng_1.4.7.20170424.dsc" at Mon Apr 24 20:00:08 UTC 2017. [ 89s] [ 89s] ### VM INTERACTION START ### [ 90s] Powering off. [ 90s] [ 75.675209] reboot: Power down [ 90s] ### VM INTERACTION END ### [ 90s] [ 90s] lamb26 failed "build cellmgr-ng_1.4.7.20170424.dsc" at Mon Apr 24 20:00:10 UTC 2017. [ 90s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Mon Apr 24 20:00:52 2017 From: admin at opensuse.org (OBS Notification) Date: Mon, 24 Apr 2017 20:00:52 +0000 Subject: Build failure of network:osmocom:nightly/openbsc in xUbuntu_17.04/i586 In-Reply-To: References: Message-ID: <58fe59aab26ce_1bbd9c0f7c3138b@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/openbsc/xUbuntu_17.04/i586 Package network:osmocom:nightly/openbsc failed to build in xUbuntu_17.04/i586 Check out the package for editing: osc checkout network:osmocom:nightly openbsc Last lines of build log: [ 119s] gcc -DHAVE_CONFIG_H -I. -I../.. -I../../include -I../.. -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fPIE -fstack-protector-strong -Wformat -Werror=format-security -Werror=implicit -Werror=maybe-uninitialized -Werror=memset-transposed-args -Werror=null-dereference -Werror=sizeof-array-argument -Werror=sizeof-pointer-memaccess -c -o bsc_nat_filter.o bsc_nat_filter.c [ 120s] gcc -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fPIE -fstack-protector-strong -Wformat -Werror=format-security -Werror=implicit -Werror=maybe-uninitialized -Werror=memset-transposed-args -Werror=null-dereference -Werror=sizeof-array-argument -Werror=sizeof-pointer-memaccess -Wl,-Bsymbolic-functions -fPIE -pie -Wl,-z,relro -Wl,-z,now -o osmo-bsc_nat bsc_filter.o bsc_mgcp_utils.o bsc_nat.o bsc_nat_utils.o bsc_nat_vty.o bsc_sccp.o bsc_ussd.o bsc_nat_ctrl.o bsc_nat_rewrite.o bsc_nat_rewrite_trie.o bsc_nat_filter.o ../../src/libmgcp/libmgcp.a ../../src/libfilter/libfilter.a ../../src/libbsc/libbsc.a ../../src/libcommon-cs/libcommon-cs.a ../../src/libtrau/libtrau.a ../../src/libcommon/libcommon.a -losmosccp -losmoxua -ltalloc -losmocore -ltalloc -losmogsm -losmocore -ltalloc -losmovty -losmocore -ltalloc -losmoctrl -losmogsm -losmocore -losmoabis -losmonetif -lcrypto -lrt [ 120s] /usr/lib/gcc/i686-linux-gnu/6/../../../i386-linux-gnu/libosmosccp.so: undefined reference to `talloc_free' [ 120s] collect2: error: ld returned 1 exit status [ 120s] Makefile:460: recipe for target 'osmo-bsc_nat' failed [ 120s] make[4]: *** [osmo-bsc_nat] Error 1 [ 120s] make[4]: Leaving directory '/usr/src/packages/BUILD/openbsc/src/osmo-bsc_nat' [ 120s] Makefile:418: recipe for target 'all-recursive' failed [ 120s] make[3]: *** [all-recursive] Error 1 [ 120s] make[3]: Leaving directory '/usr/src/packages/BUILD/openbsc/src' [ 120s] Makefile:486: recipe for target 'all-recursive' failed [ 120s] make[2]: *** [all-recursive] Error 1 [ 120s] make[2]: Leaving directory '/usr/src/packages/BUILD/openbsc' [ 120s] Makefile:404: recipe for target 'all' failed [ 120s] make[1]: *** [all] Error 2 [ 120s] make[1]: Leaving directory '/usr/src/packages/BUILD/openbsc' [ 120s] dh_auto_build: make -j1 returned exit code 2 [ 120s] debian/rules:13: recipe for target 'build' failed [ 120s] make: *** [build] Error 2 [ 120s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 120s] [ 120s] lamb78 failed "build openbsc_0.15.1.20170424.dsc" at Mon Apr 24 20:00:43 UTC 2017. [ 120s] [ 120s] ### VM INTERACTION START ### [ 123s] [ 110.643583] reboot: Power down [ 123s] ### VM INTERACTION END ### [ 123s] [ 123s] lamb78 failed "build openbsc_0.15.1.20170424.dsc" at Mon Apr 24 20:00:47 UTC 2017. [ 123s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Mon Apr 24 20:01:09 2017 From: admin at opensuse.org (OBS Notification) Date: Mon, 24 Apr 2017 20:01:09 +0000 Subject: Build failure of network:osmocom:nightly/libosmo-sccp in xUbuntu_16.04/i586 In-Reply-To: References: Message-ID: <58fe59c090d87_1bc39c0f7c3277e7@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/libosmo-sccp/xUbuntu_16.04/i586 Package network:osmocom:nightly/libosmo-sccp failed to build in xUbuntu_16.04/i586 Check out the package for editing: osc checkout network:osmocom:nightly libosmo-sccp Last lines of build log: [ 118s] /usr/src/packages/BUILD/src/xua_asp_fsm.c:772: undefined reference to `ipa_ccm_send_id_req' [ 118s] ../../src/.libs/libosmo-sigtran.a(ipa.o): In function `ipa_tx_xua_as': [ 118s] /usr/src/packages/BUILD/src/ipa.c:71: undefined reference to `ipa_msg_alloc' [ 118s] collect2: error: ld returned 1 exit status [ 118s] Makefile:360: recipe for target 'xua_test' failed [ 118s] make[4]: *** [xua_test] Error 1 [ 118s] make[4]: Leaving directory '/usr/src/packages/BUILD/tests/xua' [ 118s] Makefile:362: recipe for target 'all-recursive' failed [ 118s] make[3]: *** [all-recursive] Error 1 [ 118s] make[3]: Leaving directory '/usr/src/packages/BUILD/tests' [ 118s] Makefile:454: recipe for target 'all-recursive' failed [ 118s] make[2]: *** [all-recursive] Error 1 [ 118s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 118s] Makefile:372: recipe for target 'all' failed [ 118s] make[1]: *** [all] Error 2 [ 118s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 118s] dh_auto_build: make -j1 returned exit code 2 [ 118s] debian/rules:12: recipe for target 'build' failed [ 118s] make: *** [build] Error 2 [ 118s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 118s] [ 118s] lamb24 failed "build libosmo-sccp_0.7.1.20170424.dsc" at Mon Apr 24 20:00:57 UTC 2017. [ 118s] [ 118s] ### VM INTERACTION START ### [ 122s] [ 108.471274] reboot: Power down [ 122s] ### VM INTERACTION END ### [ 122s] [ 122s] lamb24 failed "build libosmo-sccp_0.7.1.20170424.dsc" at Mon Apr 24 20:01:01 UTC 2017. [ 122s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Mon Apr 24 20:01:43 2017 From: admin at opensuse.org (OBS Notification) Date: Mon, 24 Apr 2017 20:01:43 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in xUbuntu_17.04/x86_64 In-Reply-To: References: Message-ID: <58fe59c2ea1cf_1bc39c0f7c3279ac@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/xUbuntu_17.04/x86_64 Package network:osmocom:nightly/osmo-stp failed to build in xUbuntu_17.04/x86_64 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 74s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o vty_interface_cmds.o vty_interface_cmds.c [ 74s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o mgcp_patch.o mgcp_patch.c [ 74s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o mgcp_callagent.o mgcp_callagent.c [ 74s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o isup_filter.o isup_filter.c [ 75s] gcc -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -Wl,-Bsymbolic-functions -Wl,-z,relro -o cellmgr_ng main.o mtp_layer3.o thread.o ipaccess.o pcap.o bss_patch.o bssap_sccp.o bsc_sccp.o bsc_ussd.o links.o msc_conn.o link_udp.o snmp_mtp.o debug.o isup.o mtp_link.o counter.o sccp_state.o bsc.o ss7_application.o vty_interface_legacy.o vty_interface_cmds.o mgcp_patch.o mgcp_callagent.o isup_filter.o -losmosccp -losmoxua -ltalloc -losmogsm -losmocore -ltalloc -losmovty -losmocore -ltalloc -losmocore -lpthread -lnetsnmp -lcrypto [ 75s] /usr/lib/gcc/x86_64-linux-gnu/6/../../../x86_64-linux-gnu/libosmosccp.so: undefined reference to `talloc_free' [ 75s] collect2: error: ld returned 1 exit status [ 75s] Makefile:425: recipe for target 'cellmgr_ng' failed [ 75s] make[3]: *** [cellmgr_ng] Error 1 [ 75s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 75s] Makefile:380: recipe for target 'all-recursive' failed [ 75s] make[2]: *** [all-recursive] Error 1 [ 75s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 75s] Makefile:321: recipe for target 'all' failed [ 75s] make[1]: *** [all] Error 2 [ 75s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 75s] dh_auto_build: make -j1 returned exit code 2 [ 75s] debian/rules:23: recipe for target 'build' failed [ 75s] make: *** [build] Error 2 [ 75s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 75s] [ 75s] lamb60 failed "build cellmgr-ng_1.4.7.20170424.dsc" at Mon Apr 24 20:01:37 UTC 2017. [ 75s] [ 75s] ### VM INTERACTION START ### [ 78s] [ 64.003289] reboot: Power down [ 78s] ### VM INTERACTION END ### [ 78s] [ 78s] lamb60 failed "build cellmgr-ng_1.4.7.20170424.dsc" at Mon Apr 24 20:01:41 UTC 2017. [ 78s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Mon Apr 24 20:01:26 2017 From: admin at opensuse.org (OBS Notification) Date: Mon, 24 Apr 2017 20:01:26 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in xUbuntu_16.10/i586 In-Reply-To: References: Message-ID: <58fe59c19c8ba_1bc39c0f7c327834@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/xUbuntu_16.10/i586 Package network:osmocom:nightly/osmo-stp failed to build in xUbuntu_16.10/i586 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 76s] ^~~~~~~ [ 76s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o vty_interface.o vty_interface.c [ 77s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o sctp_m3ua_client.o sctp_m3ua_client.c [ 77s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 77s] #include [ 77s] ^ [ 77s] compilation terminated. [ 77s] Makefile:485: recipe for target 'sctp_m3ua_client.o' failed [ 77s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 77s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 77s] Makefile:380: recipe for target 'all-recursive' failed [ 77s] make[2]: *** [all-recursive] Error 1 [ 77s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 77s] Makefile:321: recipe for target 'all' failed [ 77s] make[1]: *** [all] Error 2 [ 77s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 77s] dh_auto_build: make -j1 returned exit code 2 [ 77s] debian/rules:23: recipe for target 'build' failed [ 77s] make: *** [build] Error 2 [ 77s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 77s] [ 77s] lamb04 failed "build cellmgr-ng_1.4.7.20170424.dsc" at Mon Apr 24 20:01:13 UTC 2017. [ 77s] [ 77s] ### VM INTERACTION START ### [ 80s] [ 67.354451] reboot: Power down [ 80s] ### VM INTERACTION END ### [ 80s] [ 80s] lamb04 failed "build cellmgr-ng_1.4.7.20170424.dsc" at Mon Apr 24 20:01:16 UTC 2017. [ 80s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Mon Apr 24 20:02:00 2017 From: admin at opensuse.org (OBS Notification) Date: Mon, 24 Apr 2017 20:02:00 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in Debian_8.0/i586 In-Reply-To: References: Message-ID: <58fe59dd122ca_1bc99c0f7c330132@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/Debian_8.0/i586 Package network:osmocom:nightly/osmo-stp failed to build in Debian_8.0/i586 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 88s] CC vty_interface.o [ 89s] CC sctp_m3ua_client.o [ 89s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 89s] #include [ 89s] ^ [ 89s] compilation terminated. [ 89s] Makefile:475: recipe for target 'sctp_m3ua_client.o' failed [ 89s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 89s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 89s] Makefile:370: recipe for target 'all-recursive' failed [ 89s] make[2]: *** [all-recursive] Error 1 [ 89s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 89s] Makefile:310: recipe for target 'all' failed [ 89s] make[1]: *** [all] Error 2 [ 89s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 89s] dh_auto_build: make -j1 returned exit code 2 [ 89s] debian/rules:23: recipe for target 'build' failed [ 89s] make: *** [build] Error 2 [ 89s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 89s] [ 89s] lamb70 failed "build cellmgr-ng_1.4.7.20170424.dsc" at Mon Apr 24 20:01:52 UTC 2017. [ 89s] [ 89s] ### VM INTERACTION START ### [ 90s] Powering off. [ 90s] [ 76.048412] reboot: Power down [ 90s] ### VM INTERACTION END ### [ 90s] [ 90s] lamb70 failed "build cellmgr-ng_1.4.7.20170424.dsc" at Mon Apr 24 20:01:54 UTC 2017. [ 90s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Mon Apr 24 20:02:00 2017 From: admin at opensuse.org (OBS Notification) Date: Mon, 24 Apr 2017 20:02:00 +0000 Subject: Build failure of network:osmocom:nightly/libosmo-sccp in xUbuntu_16.04/x86_64 In-Reply-To: References: Message-ID: <58fe59ddcc1e1_1bc99c0f7c330236@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/libosmo-sccp/xUbuntu_16.04/x86_64 Package network:osmocom:nightly/libosmo-sccp failed to build in xUbuntu_16.04/x86_64 Check out the package for editing: osc checkout network:osmocom:nightly libosmo-sccp Last lines of build log: [ 112s] /usr/src/packages/BUILD/src/xua_asp_fsm.c:772: undefined reference to `ipa_ccm_send_id_req' [ 112s] ../../src/.libs/libosmo-sigtran.a(ipa.o): In function `ipa_tx_xua_as': [ 112s] /usr/src/packages/BUILD/src/ipa.c:71: undefined reference to `ipa_msg_alloc' [ 112s] collect2: error: ld returned 1 exit status [ 112s] Makefile:360: recipe for target 'xua_test' failed [ 112s] make[4]: *** [xua_test] Error 1 [ 112s] make[4]: Leaving directory '/usr/src/packages/BUILD/tests/xua' [ 112s] Makefile:362: recipe for target 'all-recursive' failed [ 112s] make[3]: *** [all-recursive] Error 1 [ 112s] make[3]: Leaving directory '/usr/src/packages/BUILD/tests' [ 112s] Makefile:454: recipe for target 'all-recursive' failed [ 112s] make[2]: *** [all-recursive] Error 1 [ 112s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 112s] Makefile:372: recipe for target 'all' failed [ 112s] make[1]: *** [all] Error 2 [ 112s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 112s] dh_auto_build: make -j1 returned exit code 2 [ 112s] debian/rules:12: recipe for target 'build' failed [ 113s] make: *** [build] Error 2 [ 113s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 113s] [ 113s] lamb74 failed "build libosmo-sccp_0.7.1.20170424.dsc" at Mon Apr 24 20:01:40 UTC 2017. [ 113s] [ 113s] ### VM INTERACTION START ### [ 116s] [ 102.736479] reboot: Power down [ 116s] ### VM INTERACTION END ### [ 116s] [ 116s] lamb74 failed "build libosmo-sccp_0.7.1.20170424.dsc" at Mon Apr 24 20:01:44 UTC 2017. [ 116s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Mon Apr 24 20:02:17 2017 From: admin at opensuse.org (OBS Notification) Date: Mon, 24 Apr 2017 20:02:17 +0000 Subject: Build failure of network:osmocom:nightly/osmo-bts in xUbuntu_17.04/i586 In-Reply-To: References: Message-ID: <58fe59fa925c_1bc99c0f7c3303de@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-bts/xUbuntu_17.04/i586 Package network:osmocom:nightly/osmo-bts failed to build in xUbuntu_17.04/i586 Check out the package for editing: osc checkout network:osmocom:nightly osmo-bts Last lines of build log: [ 71s] [ 71s] /* confdefs.h */ [ 71s] #define PACKAGE_NAME "osmo-bts" [ 71s] #define PACKAGE_TARNAME "osmo-bts" [ 71s] #define PACKAGE_VERSION "0.5.0.20170424" [ 71s] #define PACKAGE_STRING "osmo-bts 0.5.0.20170424" [ 71s] #define PACKAGE_BUGREPORT "openbsc-devel at lists.openbsc.org" [ 71s] #define PACKAGE_URL "" [ 71s] #define PACKAGE "osmo-bts" [ 71s] #define VERSION "0.5.0.20170424" [ 71s] #define STDC_HEADERS 1 [ 71s] [ 71s] configure: exit 1 [ 71s] dh_auto_configure: ./configure --build=i686-linux-gnu --prefix=/usr --includedir=${prefix}/include --mandir=${prefix}/share/man --infodir=${prefix}/share/info --sysconfdir=/etc --localstatedir=/var --disable-silent-rules --libdir=${prefix}/lib/i386-linux-gnu --libexecdir=${prefix}/lib/i386-linux-gnu --disable-maintainer-mode --disable-dependency-tracking --enable-trx --with-openbsc=/usr/src/osmocom/openbsc/openbsc/include/ returned exit code 1 [ 71s] debian/rules:22: recipe for target 'override_dh_auto_configure' failed [ 71s] make[1]: *** [override_dh_auto_configure] Error 2 [ 71s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 71s] debian/rules:12: recipe for target 'build' failed [ 71s] make: *** [build] Error 2 [ 71s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 71s] [ 71s] lamb04 failed "build osmo-bts_0.5.0.20170424.dsc" at Mon Apr 24 20:02:07 UTC 2017. [ 71s] [ 71s] ### VM INTERACTION START ### [ 74s] [ 61.048619] reboot: Power down [ 74s] ### VM INTERACTION END ### [ 74s] [ 74s] lamb04 failed "build osmo-bts_0.5.0.20170424.dsc" at Mon Apr 24 20:02:11 UTC 2017. [ 74s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Mon Apr 24 20:02:35 2017 From: admin at opensuse.org (OBS Notification) Date: Mon, 24 Apr 2017 20:02:35 +0000 Subject: Build failure of network:osmocom:nightly/openbsc in xUbuntu_17.04/x86_64 In-Reply-To: References: Message-ID: <58fe59fad1300_1bc99c0f7c3304b3@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/openbsc/xUbuntu_17.04/x86_64 Package network:osmocom:nightly/openbsc failed to build in xUbuntu_17.04/x86_64 Check out the package for editing: osc checkout network:osmocom:nightly openbsc Last lines of build log: [ 118s] gcc -DHAVE_CONFIG_H -I. -I../.. -I../../include -I../.. -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fPIE -fstack-protector-strong -Wformat -Werror=format-security -Werror=implicit -Werror=maybe-uninitialized -Werror=memset-transposed-args -Werror=null-dereference -Werror=sizeof-array-argument -Werror=sizeof-pointer-memaccess -c -o bsc_nat_filter.o bsc_nat_filter.c [ 118s] gcc -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fPIE -fstack-protector-strong -Wformat -Werror=format-security -Werror=implicit -Werror=maybe-uninitialized -Werror=memset-transposed-args -Werror=null-dereference -Werror=sizeof-array-argument -Werror=sizeof-pointer-memaccess -Wl,-Bsymbolic-functions -fPIE -pie -Wl,-z,relro -Wl,-z,now -o osmo-bsc_nat bsc_filter.o bsc_mgcp_utils.o bsc_nat.o bsc_nat_utils.o bsc_nat_vty.o bsc_sccp.o bsc_ussd.o bsc_nat_ctrl.o bsc_nat_rewrite.o bsc_nat_rewrite_trie.o bsc_nat_filter.o ../../src/libmgcp/libmgcp.a ../../src/libfilter/libfilter.a ../../src/libbsc/libbsc.a ../../src/libcommon-cs/libcommon-cs.a ../../src/libtrau/libtrau.a ../../src/libcommon/libcommon.a -losmosccp -losmoxua -ltalloc -losmocore -ltalloc -losmogsm -losmocore -ltalloc -losmovty -losmocore -ltalloc -losmoctrl -losmogsm -losmocore -losmoabis -losmonetif -lcrypto -lrt [ 118s] /usr/lib/gcc/x86_64-linux-gnu/6/../../../x86_64-linux-gnu/libosmosccp.so: undefined reference to `talloc_free' [ 118s] collect2: error: ld returned 1 exit status [ 118s] Makefile:460: recipe for target 'osmo-bsc_nat' failed [ 118s] make[4]: *** [osmo-bsc_nat] Error 1 [ 118s] make[4]: Leaving directory '/usr/src/packages/BUILD/openbsc/src/osmo-bsc_nat' [ 118s] Makefile:418: recipe for target 'all-recursive' failed [ 118s] make[3]: *** [all-recursive] Error 1 [ 118s] make[3]: Leaving directory '/usr/src/packages/BUILD/openbsc/src' [ 118s] Makefile:486: recipe for target 'all-recursive' failed [ 118s] make[2]: *** [all-recursive] Error 1 [ 118s] make[2]: Leaving directory '/usr/src/packages/BUILD/openbsc' [ 118s] Makefile:404: recipe for target 'all' failed [ 118s] make[1]: *** [all] Error 2 [ 118s] make[1]: Leaving directory '/usr/src/packages/BUILD/openbsc' [ 118s] dh_auto_build: make -j1 returned exit code 2 [ 118s] debian/rules:13: recipe for target 'build' failed [ 118s] make: *** [build] Error 2 [ 118s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 118s] [ 118s] lamb67 failed "build openbsc_0.15.1.20170424.dsc" at Mon Apr 24 20:02:21 UTC 2017. [ 118s] [ 118s] ### VM INTERACTION START ### [ 121s] [ 107.611884] reboot: Power down [ 121s] ### VM INTERACTION END ### [ 121s] [ 121s] lamb67 failed "build openbsc_0.15.1.20170424.dsc" at Mon Apr 24 20:02:24 UTC 2017. [ 121s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Mon Apr 24 20:03:09 2017 From: admin at opensuse.org (OBS Notification) Date: Mon, 24 Apr 2017 20:03:09 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in xUbuntu_16.04/i586 In-Reply-To: References: Message-ID: <58fe5a1bc9017_1bbd9c0f7c3139bf@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/xUbuntu_16.04/i586 Package network:osmocom:nightly/osmo-stp failed to build in xUbuntu_16.04/i586 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 104s] sctp_m2ua.c:91:3: warning: #warning "Notify any other AS(P) for failover scenario" [-Wcpp] [ 104s] #warning "Notify any other AS(P) for failover scenario" [ 104s] ^ [ 105s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -c -o vty_interface.o vty_interface.c [ 105s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -c -o sctp_m3ua_client.o sctp_m3ua_client.c [ 106s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 106s] compilation terminated. [ 106s] Makefile:485: recipe for target 'sctp_m3ua_client.o' failed [ 106s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 106s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 106s] Makefile:380: recipe for target 'all-recursive' failed [ 106s] make[2]: *** [all-recursive] Error 1 [ 106s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 106s] Makefile:321: recipe for target 'all' failed [ 106s] make[1]: *** [all] Error 2 [ 106s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 106s] dh_auto_build: make -j1 returned exit code 2 [ 106s] debian/rules:23: recipe for target 'build' failed [ 106s] make: *** [build] Error 2 [ 106s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 106s] [ 106s] build31 failed "build cellmgr-ng_1.4.7.20170424.dsc" at Mon Apr 24 20:03:02 UTC 2017. [ 106s] [ 106s] ### VM INTERACTION START ### [ 109s] [ 93.271010] reboot: Power down [ 109s] ### VM INTERACTION END ### [ 109s] [ 109s] build31 failed "build cellmgr-ng_1.4.7.20170424.dsc" at Mon Apr 24 20:03:05 UTC 2017. [ 109s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Mon Apr 24 20:04:00 2017 From: admin at opensuse.org (OBS Notification) Date: Mon, 24 Apr 2017 20:04:00 +0000 Subject: Build failure of network:osmocom:nightly/osmo-bts in xUbuntu_17.04/x86_64 In-Reply-To: References: Message-ID: <58fe5a39a3cfa_1bbd9c0f7c314365@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-bts/xUbuntu_17.04/x86_64 Package network:osmocom:nightly/osmo-bts failed to build in xUbuntu_17.04/x86_64 Check out the package for editing: osc checkout network:osmocom:nightly osmo-bts Last lines of build log: [ 69s] /* confdefs.h */ [ 69s] #define PACKAGE_NAME "osmo-bts" [ 69s] #define PACKAGE_TARNAME "osmo-bts" [ 69s] #define PACKAGE_VERSION "0.5.0.20170424" [ 69s] #define PACKAGE_STRING "osmo-bts 0.5.0.20170424" [ 69s] #define PACKAGE_BUGREPORT "openbsc-devel at lists.openbsc.org" [ 69s] #define PACKAGE_URL "" [ 69s] #define PACKAGE "osmo-bts" [ 69s] #define VERSION "0.5.0.20170424" [ 69s] #define STDC_HEADERS 1 [ 69s] [ 69s] configure: exit 1 [ 69s] dh_auto_c[ 56.076152] serial8250: too much work for irq4 [ 69s] onfigure: ./configure --build=x86_64-linux-gnu --prefix=/usr --includedir=${prefix}/include --mandir=${prefix}/share/man --infodir=${prefix}/share/info --sysconfdir=/etc --localstatedir=/var --disable-silent-rules --libdir=${prefix}/lib/x86_64-linux-gnu --libexecdir=${prefix}/lib/x86_64-linux-gnu --disable-maintainer-mode --disable-dependency-tracking --enable-trx --with-openbsc=/usr/src/osmocom/openbsc/openbsc/include/ returned exit code 1 [ 69s] debian/rules:22: recipe for target 'override_dh_auto_configure' failed [ 69s] make[1]: *** [override_dh_auto_configure] Error 2 [ 69s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 69s] debian/rules:12: recipe for target 'build' failed [ 69s] make: *** [build] Error 2 [ 69s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 69s] [ 69s] lamb67 failed "build osmo-bts_0.5.0.20170424.dsc" at Mon Apr 24 20:03:45 UTC 2017. [ 69s] [ 69s] ### VM INTERACTION START ### [ 73s] [ 59.283181] reboot: Power down [ 73s] ### VM INTERACTION END ### [ 73s] [ 73s] lamb67 failed "build osmo-bts_0.5.0.20170424.dsc" at Mon Apr 24 20:03:48 UTC 2017. [ 73s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Mon Apr 24 20:04:35 2017 From: admin at opensuse.org (OBS Notification) Date: Mon, 24 Apr 2017 20:04:35 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in xUbuntu_16.04/x86_64 In-Reply-To: References: Message-ID: <58fe5a9279bc5_1bbd9c0f7c3144e@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/xUbuntu_16.04/x86_64 Package network:osmocom:nightly/osmo-stp failed to build in xUbuntu_16.04/x86_64 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 127s] sctp_m2ua.c:91:3: warning: #warning "Notify any other AS(P) for failover scenario" [-Wcpp] [ 127s] #warning "Notify any other AS(P) for failover scenario" [ 127s] ^ [ 127s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -c -o vty_interface.o vty_interface.c [ 128s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -c -o sctp_m3ua_client.o sctp_m3ua_client.c [ 128s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 128s] compilation terminated. [ 128s] Makefile:485: recipe for target 'sctp_m3ua_client.o' failed [ 128s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 128s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 128s] Makefile:380: recipe for target 'all-recursive' failed [ 128s] make[2]: *** [all-recursive] Error 1 [ 128s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 128s] Makefile:321: recipe for target 'all' failed [ 128s] make[1]: *** [all] Error 2 [ 128s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 128s] dh_auto_build: make -j1 returned exit code 2 [ 128s] debian/rules:23: recipe for target 'build' failed [ 128s] make: *** [build] Error 2 [ 128s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 128s] [ 128s] cloud122 failed "build cellmgr-ng_1.4.7.20170424.dsc" at Mon Apr 24 20:04:20 UTC 2017. [ 128s] [ 128s] ### VM INTERACTION START ### [ 131s] [ 108.744067] reboot: Power down [ 133s] ### VM INTERACTION END ### [ 133s] [ 133s] cloud122 failed "build cellmgr-ng_1.4.7.20170424.dsc" at Mon Apr 24 20:04:25 UTC 2017. [ 133s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From gerrit-no-reply at lists.osmocom.org Tue Apr 25 09:21:41 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Tue, 25 Apr 2017 09:21:41 +0000 Subject: [PATCH] osmo-hlr[master]: debian: remove obsolete dependency Message-ID: Review at https://gerrit.osmocom.org/2399 debian: remove obsolete dependency Change-Id: I132515cd4d89132bb59f9ee7804a5a50e8bd2775 --- M debian/control 1 file changed, 1 insertion(+), 2 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-hlr refs/changes/99/2399/1 diff --git a/debian/control b/debian/control index 766d015..571c24e 100644 --- a/debian/control +++ b/debian/control @@ -13,8 +13,7 @@ libosmo-abis-dev, libosmo-netif-dev, libdbd-sqlite3, - libsqlite3-dev, - hardening-wrapper + libsqlite3-dev Standards-Version: 3.9.6 Vcs-Browser: http://cgit.osmocom.org/osmo-hlr Vcs-Git: git://git.osmocom.org/osmo-hlr -- To view, visit https://gerrit.osmocom.org/2399 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I132515cd4d89132bb59f9ee7804a5a50e8bd2775 Gerrit-PatchSet: 1 Gerrit-Project: osmo-hlr Gerrit-Branch: master Gerrit-Owner: Max From gerrit-no-reply at lists.osmocom.org Tue Apr 25 10:48:31 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Tue, 25 Apr 2017 10:48:31 +0000 Subject: [PATCH] osmo-trx[master]: debian: remove obsolete dependency Message-ID: Review at https://gerrit.osmocom.org/2400 debian: remove obsolete dependency Change-Id: I3ea72b4123a280a846086d083c4f3189d611f8cf --- M debian/control 1 file changed, 0 insertions(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/osmo-trx refs/changes/00/2400/1 diff --git a/debian/control b/debian/control index 151aa92..0e3b714 100644 --- a/debian/control +++ b/debian/control @@ -12,7 +12,6 @@ libuhd-dev, libusb-1.0-0-dev, libboost-all-dev, - hardening-wrapper, libfftw3-dev Standards-Version: 3.9.6 Vcs-Browser: http://cgit.osmocom.org/osmo-trx -- To view, visit https://gerrit.osmocom.org/2400 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I3ea72b4123a280a846086d083c4f3189d611f8cf Gerrit-PatchSet: 1 Gerrit-Project: osmo-trx Gerrit-Branch: master Gerrit-Owner: Max From gerrit-no-reply at lists.osmocom.org Tue Apr 25 11:18:55 2017 From: gerrit-no-reply at lists.osmocom.org (Pau Espin Pedrol) Date: Tue, 25 Apr 2017 11:18:55 +0000 Subject: [PATCH] libosmo-netif[master]: osmux: Fix delay between RTP packets In-Reply-To: References: Message-ID: Hello daniel, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2397 to look at the new patch set (#2). osmux: Fix delay between RTP packets AMR frame contains 160 samples at 8000Hz -> 20 ms long Change-Id: I36dc69f9caf591dd1b578bc914a2ce426c7f2813 --- M src/osmux.c 1 file changed, 3 insertions(+), 2 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-netif refs/changes/97/2397/2 diff --git a/src/osmux.c b/src/osmux.c index 5655269..8c7f6e1 100644 --- a/src/osmux.c +++ b/src/osmux.c @@ -42,8 +42,9 @@ #define DEBUG_MSG 0 #endif -/* delta time between two RTP messages */ -#define DELTA_RTP_MSG 16000 +/* delta time between two RTP messages (in microseconds) */ +#define DELTA_RTP_MSG 20000 +/* delta time between two RTP messages (in samples, 8kHz) */ #define DELTA_RTP_TIMESTAMP 160 static void *osmux_ctx; -- To view, visit https://gerrit.osmocom.org/2397 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I36dc69f9caf591dd1b578bc914a2ce426c7f2813 Gerrit-PatchSet: 2 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Pau Espin Pedrol Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: daniel From gerrit-no-reply at lists.osmocom.org Tue Apr 25 11:28:19 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Tue, 25 Apr 2017 11:28:19 +0000 Subject: [PATCH] libosmo-netif[master]: Fix debian packaging Message-ID: Review at https://gerrit.osmocom.org/2401 Fix debian packaging * add separate -doc packages * fix dh_install override * add conflict with previous version Change-Id: I2781c800d39923c5541bac00f00cb128f4acf008 --- M debian/control A debian/libosmo-netif-doc.doc-base A debian/libosmo-netif-doc.install M debian/rules 4 files changed, 23 insertions(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-netif refs/changes/01/2401/1 diff --git a/debian/control b/debian/control index f4c94bb..bf403e5 100644 --- a/debian/control +++ b/debian/control @@ -24,6 +24,7 @@ Section: libs Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends} +Conflicts: libosmonetif2 Multi-Arch: same Description: Common/shared code regarding network interface for OpenBSC The libosmo-netif library is one of the libraries needed by the @@ -47,6 +48,19 @@ This package contains the development files needed for developing with the libosmo-netif library. +Package: libosmo-netif-doc +Architecture: all +Section: doc +Depends: ${misc:Depends}, + libosmonetif3, + libjs-jquery +Description: Documentation for the Osmo network interface library + The libosmo-netif library is one of the libraries needed by the + OpenBSC GSM infrastructure software. This library in particular implements + the shared code for network interfaces. + . + This package contains the documentation for the libosmo-netif library. + Package: libosmo-netif-dbg Section: debug Architecture: any diff --git a/debian/libosmo-netif-doc.doc-base b/debian/libosmo-netif-doc.doc-base new file mode 100644 index 0000000..ce8aa50 --- /dev/null +++ b/debian/libosmo-netif-doc.doc-base @@ -0,0 +1,7 @@ +Document: libosmo-netif-doc +Title: Documentation for the libosmo-netif library +Section: Programming + +Format: HTML +Index: /usr/share/doc/libosmo-netif/html/index.html +Files: /usr/share/doc/libosmo-netif/html/*.html diff --git a/debian/libosmo-netif-doc.install b/debian/libosmo-netif-doc.install new file mode 100644 index 0000000..d199687 --- /dev/null +++ b/debian/libosmo-netif-doc.install @@ -0,0 +1 @@ +usr/share/doc/libosmo-netif/* diff --git a/debian/rules b/debian/rules index f398831..ce5c618 100755 --- a/debian/rules +++ b/debian/rules @@ -20,8 +20,8 @@ dh_autoreconf override_dh_install: - dh_install sed -i "/dependency_libs/ s/'.*'/''/" `find . -name '*.la'` + dh_install override_dh_clean: dh_clean -- To view, visit https://gerrit.osmocom.org/2401 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I2781c800d39923c5541bac00f00cb128f4acf008 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Max From gerrit-no-reply at lists.osmocom.org Tue Apr 25 11:34:48 2017 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Tue, 25 Apr 2017 11:34:48 +0000 Subject: [PATCH] sandbox[master]: t14 Message-ID: Review at https://gerrit.osmocom.org/2402 t14 Change-Id: I45fd0d6e90e1703b51dc6c7be84bfecc36b12be6 --- M x 1 file changed, 1 insertion(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/sandbox refs/changes/02/2402/1 diff --git a/x b/x index 6260bff..a1ca0b9 100644 --- a/x +++ b/x @@ -29,3 +29,4 @@ more yet more yet more and more +t14 -- To view, visit https://gerrit.osmocom.org/2402 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I45fd0d6e90e1703b51dc6c7be84bfecc36b12be6 Gerrit-PatchSet: 1 Gerrit-Project: sandbox Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Tue Apr 25 11:35:06 2017 From: gerrit-no-reply at lists.osmocom.org (Pau Espin Pedrol) Date: Tue, 25 Apr 2017 11:35:06 +0000 Subject: [PATCH] libosmo-netif[master]: osmux: Check batch_factor overflow in osmux_batch_enqueue Message-ID: Review at https://gerrit.osmocom.org/2403 osmux: Check batch_factor overflow in osmux_batch_enqueue This commit should fix a bug present if for instance batch_factor < 8 and osmux_batch_enqueue is called from osmux_replay_lost_packets and enough packets were lost from last received packet. Change-Id: I5d643810949aeca4762f0cad05eed534d35087f7 --- M src/osmux.c 1 file changed, 7 insertions(+), 6 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-netif refs/changes/03/2403/1 diff --git a/src/osmux.c b/src/osmux.c index 5655269..4852c44 100644 --- a/src/osmux.c +++ b/src/osmux.c @@ -206,12 +206,13 @@ int dummy; }; -static int osmux_batch_enqueue(struct msgb *msg, struct osmux_circuit *circuit) +static int osmux_batch_enqueue(struct msgb *msg, struct osmux_circuit *circuit, + int batch_factor) { /* Too many messages per batch, discard it. The counter field of the * osmux header is just 3 bits long, so make sure it doesn't overflow. */ - if (circuit->nmsgs >= 8) { + if (circuit->nmsgs >= batch_factor || circuit->nmsgs >= 8) { struct rtp_hdr *rtph; rtph = osmo_rtp_get_hdr(msg); @@ -454,7 +455,7 @@ } static void osmux_replay_lost_packets(struct osmux_circuit *circuit, - struct rtp_hdr *cur_rtph) + struct rtp_hdr *cur_rtph, int batch_factor) { int16_t diff; struct msgb *last; @@ -500,7 +501,7 @@ DELTA_RTP_TIMESTAMP); /* No more room in this batch, skip padding with more clones */ - if (osmux_batch_enqueue(clone, circuit) < 0) { + if (osmux_batch_enqueue(clone, circuit, batch_factor) < 0) { msgb_free(clone); break; } @@ -609,10 +610,10 @@ } } /* Handle RTP packet loss scenario */ - osmux_replay_lost_packets(circuit, rtph); + osmux_replay_lost_packets(circuit, rtph, batch_factor); /* This batch is full, force batch delivery */ - if (osmux_batch_enqueue(msg, circuit) < 0) + if (osmux_batch_enqueue(msg, circuit, batch_factor) < 0) return 1; #ifdef DEBUG_MSG -- To view, visit https://gerrit.osmocom.org/2403 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I5d643810949aeca4762f0cad05eed534d35087f7 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Pau Espin Pedrol From gerrit-no-reply at lists.osmocom.org Tue Apr 25 11:35:46 2017 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Tue, 25 Apr 2017 11:35:46 +0000 Subject: sandbox[master]: t14 In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 Verified+1 -- To view, visit https://gerrit.osmocom.org/2402 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I45fd0d6e90e1703b51dc6c7be84bfecc36b12be6 Gerrit-PatchSet: 1 Gerrit-Project: sandbox Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Apr 25 11:35:49 2017 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Tue, 25 Apr 2017 11:35:49 +0000 Subject: [MERGED] sandbox[master]: t14 In-Reply-To: References: Message-ID: Neels Hofmeyr has submitted this change and it was merged. Change subject: t14 ...................................................................... t14 Change-Id: I45fd0d6e90e1703b51dc6c7be84bfecc36b12be6 --- M x 1 file changed, 1 insertion(+), 0 deletions(-) Approvals: Neels Hofmeyr: Looks good to me, approved; Verified diff --git a/x b/x index 6260bff..a1ca0b9 100644 --- a/x +++ b/x @@ -29,3 +29,4 @@ more yet more yet more and more +t14 -- To view, visit https://gerrit.osmocom.org/2402 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I45fd0d6e90e1703b51dc6c7be84bfecc36b12be6 Gerrit-PatchSet: 1 Gerrit-Project: sandbox Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Tue Apr 25 11:42:15 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Tue, 25 Apr 2017 11:42:15 +0000 Subject: [PATCH] libosmo-sccp[master]: Fix debian builds Message-ID: Review at https://gerrit.osmocom.org/2404 Fix debian builds Add missing libosmogsm dependency. Change-Id: I6e5cf393ffe81c582966ca0e9479e6deeffa9280 Fixes: OS#2182 --- M configure.ac M src/Makefile.am M src/ipa.c 3 files changed, 4 insertions(+), 2 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/04/2404/1 diff --git a/configure.ac b/configure.ac index 82c7ee8..3a05d54 100644 --- a/configure.ac +++ b/configure.ac @@ -29,6 +29,7 @@ PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 0.3.0) PKG_CHECK_MODULES(LIBOSMOVTY, libosmovty >= 0.3.0) PKG_CHECK_MODULES(LIBOSMONETIF, libosmo-netif >= 0.0.6) +PKG_CHECK_MODULES(LIBOSMOGSM, libosmogsm >= 0.9.5) old_LIBS=$LIBS AC_SEARCH_LIBS([sctp_send], [sctp], [ diff --git a/src/Makefile.am b/src/Makefile.am index 15f17fe..5f0b3f9 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,5 +1,5 @@ AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir) -AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMONETIF_CFLAGS) +AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMONETIF_CFLAGS) noinst_HEADERS = sccp_internal.h xua_asp_fsm.h xua_as_fsm.h xua_internal.h @@ -32,4 +32,4 @@ osmo_ss7.c osmo_ss7_hmrt.c xua_asp_fsm.c xua_as_fsm.c \ osmo_ss7_vty.c sccp_vty.c ipa.c libosmo_sigtran_la_LDFLAGS = -version-info $(LIBVERSION) -no-undefined -export-symbols-regex '^osmo_' -libosmo_sigtran_la_LIBADD = $(LIBOSMOCORE_LIBS) $(LIBOSMONETIF_LIBS) $(LIBSCTP_LIBS) +libosmo_sigtran_la_LIBADD = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMONETIF_LIBS) $(LIBSCTP_LIBS) diff --git a/src/ipa.c b/src/ipa.c index df3dbd1..a7060db 100644 --- a/src/ipa.c +++ b/src/ipa.c @@ -29,6 +29,7 @@ #include #include #include +#include #include //#include -- To view, visit https://gerrit.osmocom.org/2404 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I6e5cf393ffe81c582966ca0e9479e6deeffa9280 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Max From gerrit-no-reply at lists.osmocom.org Tue Apr 25 12:25:41 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Tue, 25 Apr 2017 12:25:41 +0000 Subject: [PATCH] openbsc[master]: Fix MS TO measurement representation In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2391 to look at the new patch set (#2). Fix MS TO measurement representation * set proper flag when saving MS Timing Offset * use gsm_subscriber's IMSI or lchan's name if bsc_subscriber is unknown * add comments with spec reference * store/display MS Timing Offset instead of raw Timing Offset field from RSL * Compute MS Timing Offset [-63; 192] from Timing Offset field [0; 255], adjust structure gsm_meas_rep with proper type to store it Change-Id: I7e003d23a6edb714c5f17688fd6a8edac131161d Related: OS#1574 --- M openbsc/include/openbsc/meas_rep.h M openbsc/src/libbsc/abis_rsl.c M openbsc/src/libbsc/bsc_vty.c M openbsc/src/libmsc/smpp_openbsc.c M openbsc/src/utils/meas_db.c M openbsc/src/utils/meas_vis.c 6 files changed, 22 insertions(+), 13 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/91/2391/2 diff --git a/openbsc/include/openbsc/meas_rep.h b/openbsc/include/openbsc/meas_rep.h index 6d36f34..b0c03f0 100644 --- a/openbsc/include/openbsc/meas_rep.h +++ b/openbsc/include/openbsc/meas_rep.h @@ -39,7 +39,8 @@ struct gsm_meas_rep_unidir dl; uint8_t bs_power; - uint8_t ms_timing_offset; + /* according to 3GPP TS 48.058 ? MS Timing Offset [-63; 192] */ + int16_t ms_timing_offset; struct { int8_t pwr; /* MS power in dBm */ uint8_t ta; /* MS timing advance */ diff --git a/openbsc/src/libbsc/abis_rsl.c b/openbsc/src/libbsc/abis_rsl.c index 5ae707c..4f5a8cd 100644 --- a/openbsc/src/libbsc/abis_rsl.c +++ b/openbsc/src/libbsc/abis_rsl.c @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include @@ -1369,8 +1370,14 @@ int i; const char *name = ""; - if (lchan && lchan->conn) - name = bsc_subscr_name(lchan->conn->bsub); + if (lchan && lchan->conn) { + if (lchan->conn->bsub) + name = bsc_subscr_name(lchan->conn->bsub); + else if (lchan->conn->subscr) + name = lchan->conn->subscr->imsi; + else + name = lchan->name; + } DEBUGP(DMEAS, "[%s] MEASUREMENT RESULT NR=%d ", name, mr->nr); @@ -1379,6 +1386,7 @@ print_meas_rep_uni(&mr->ul, "ul"); DEBUGPC(DMEAS, "BS_POWER=%d ", mr->bs_power); + if (mr->flags & MEAS_REP_F_MS_TO) DEBUGPC(DMEAS, "MS_TO=%d ", mr->ms_timing_offset); @@ -1452,9 +1460,11 @@ mr->bs_power = *TLVP_VAL(&tp, RSL_IE_BS_POWER); /* Optional Parts */ - if (TLVP_PRESENT(&tp, RSL_IE_MS_TIMING_OFFSET)) - mr->ms_timing_offset = - *TLVP_VAL(&tp, RSL_IE_MS_TIMING_OFFSET); + if (TLVP_PRESENT(&tp, RSL_IE_MS_TIMING_OFFSET)) { + /* According to 3GPP TS 48.058 ? MS Timing Offset = Timing Offset field - 63 */ + mr->timing_offset = *TLVP_VAL(&tp, RSL_IE_MS_TIMING_OFFSET) - 63; + mr->flags |= MEAS_REP_F_MS_TO; + } if (TLVP_PRESENT(&tp, RSL_IE_L1_INFO)) { struct e1inp_sign_link *sign_link = msg->dst; diff --git a/openbsc/src/libbsc/bsc_vty.c b/openbsc/src/libbsc/bsc_vty.c index c1882fc..3c70580 100644 --- a/openbsc/src/libbsc/bsc_vty.c +++ b/openbsc/src/libbsc/bsc_vty.c @@ -1062,8 +1062,7 @@ mr->flags & MEAS_REP_F_DL_VALID ? " " : "DLinval ", VTY_NEWLINE); if (mr->flags & MEAS_REP_F_MS_TO) - vty_out(vty, "%s MS Timing Offset: %u%s", prefix, - mr->ms_timing_offset, VTY_NEWLINE); + vty_out(vty, "%s MS Timing Offset: %d%s", prefix, mr->ms_timing_offset, VTY_NEWLINE); if (mr->flags & MEAS_REP_F_MS_L1) vty_out(vty, "%s L1 MS Power: %u dBm, Timing Advance: %u%s", prefix, mr->ms_l1.pwr, mr->ms_l1.ta, VTY_NEWLINE); diff --git a/openbsc/src/libmsc/smpp_openbsc.c b/openbsc/src/libmsc/smpp_openbsc.c index 2703a24..1671a62 100644 --- a/openbsc/src/libmsc/smpp_openbsc.c +++ b/openbsc/src/libmsc/smpp_openbsc.c @@ -437,8 +437,8 @@ append_tlv_u8(req_tlv, TLVID_osmo_ta, mr->ms_l1.ta); ms_dbm = ms_pwr_dbm(lchan->ts->trx->bts->band, mr->ms_l1.pwr); append_tlv_u8(req_tlv, TLVID_osmo_ms_l1_txpwr, ms_dbm); - } else if (mr->flags & MEAS_REP_F_MS_TO) - append_tlv_u8(req_tlv, TLVID_osmo_ta, mr->ms_timing_offset); + } else if (mr->flags & MEAS_REP_F_MS_TO) /* Save Timing Offset field = MS Timing Offset + 63 */ + append_tlv_u8(req_tlv, TLVID_osmo_ta, mr->ms_timing_offset + 63); append_tlv_u16(req_tlv, TLVID_osmo_rxlev_ul, rxlev2dbm(ul_meas->full.rx_lev)); diff --git a/openbsc/src/utils/meas_db.c b/openbsc/src/utils/meas_db.c index a3b694e..d81efca 100644 --- a/openbsc/src/utils/meas_db.c +++ b/openbsc/src/utils/meas_db.c @@ -114,8 +114,7 @@ SCK_OK(st->db, sqlite3_bind_int(st->stmt_ins_mr, 6, mr->bs_power)); if (mr->flags & MEAS_REP_F_MS_TO) - SCK_OK(st->db, sqlite3_bind_int(st->stmt_ins_mr, 7, - mr->ms_timing_offset)); + SCK_OK(st->db, sqlite3_bind_int(st->stmt_ins_mr, 7, mr->ms_timing_offset)); else SCK_OK(st->db, sqlite3_bind_null(st->stmt_ins_mr, 7)); diff --git a/openbsc/src/utils/meas_vis.c b/openbsc/src/utils/meas_vis.c index 316d203..77194de 100644 --- a/openbsc/src/utils/meas_vis.c +++ b/openbsc/src/utils/meas_vis.c @@ -200,7 +200,7 @@ COLS-40, rxlev2dbm(lq->rx_lev), -110, -47, 1, 2, FALSE, FALSE); //IsVisibleObj(ms->ul.cdk) = FALSE; - snprintf(msu->label, sizeof(msu->label), "%1d %3d %2u %2u %4u", + snprintf(msu->label, sizeof(msu->label), "%1d %3d %2u %2d %4u", qual_col, lq->rx_qual, qual_col, pwr, ms->mr.ms_l1.ta, ms->mr.ms_timing_offset, now - msu->last_update); -- To view, visit https://gerrit.osmocom.org/2391 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I7e003d23a6edb714c5f17688fd6a8edac131161d Gerrit-PatchSet: 2 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Ivan Kluchnikov Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Apr 25 12:34:52 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Tue, 25 Apr 2017 12:34:52 +0000 Subject: [PATCH] openbsc[master]: Fix MS TO measurement representation In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2391 to look at the new patch set (#3). Fix MS TO measurement representation * set proper flag when saving MS Timing Offset * use gsm_subscriber's IMSI or lchan's name if bsc_subscriber is unknown * add comments with spec reference * store/display MS Timing Offset instead of raw Timing Offset field from RSL * Compute MS Timing Offset [-63; 192] from Timing Offset field [0; 255], adjust structure gsm_meas_rep with proper type to store it Change-Id: I7e003d23a6edb714c5f17688fd6a8edac131161d Related: OS#1574 --- M openbsc/include/openbsc/meas_rep.h M openbsc/src/libbsc/abis_rsl.c M openbsc/src/libbsc/bsc_vty.c M openbsc/src/libmsc/smpp_openbsc.c M openbsc/src/utils/meas_db.c M openbsc/src/utils/meas_vis.c 6 files changed, 22 insertions(+), 13 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/91/2391/3 diff --git a/openbsc/include/openbsc/meas_rep.h b/openbsc/include/openbsc/meas_rep.h index 6d36f34..b0c03f0 100644 --- a/openbsc/include/openbsc/meas_rep.h +++ b/openbsc/include/openbsc/meas_rep.h @@ -39,7 +39,8 @@ struct gsm_meas_rep_unidir dl; uint8_t bs_power; - uint8_t ms_timing_offset; + /* according to 3GPP TS 48.058 ? MS Timing Offset [-63; 192] */ + int16_t ms_timing_offset; struct { int8_t pwr; /* MS power in dBm */ uint8_t ta; /* MS timing advance */ diff --git a/openbsc/src/libbsc/abis_rsl.c b/openbsc/src/libbsc/abis_rsl.c index 5ae707c..be687eb 100644 --- a/openbsc/src/libbsc/abis_rsl.c +++ b/openbsc/src/libbsc/abis_rsl.c @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include @@ -1369,8 +1370,14 @@ int i; const char *name = ""; - if (lchan && lchan->conn) - name = bsc_subscr_name(lchan->conn->bsub); + if (lchan && lchan->conn) { + if (lchan->conn->bsub) + name = bsc_subscr_name(lchan->conn->bsub); + else if (lchan->conn->subscr) + name = lchan->conn->subscr->imsi; + else + name = lchan->name; + } DEBUGP(DMEAS, "[%s] MEASUREMENT RESULT NR=%d ", name, mr->nr); @@ -1379,6 +1386,7 @@ print_meas_rep_uni(&mr->ul, "ul"); DEBUGPC(DMEAS, "BS_POWER=%d ", mr->bs_power); + if (mr->flags & MEAS_REP_F_MS_TO) DEBUGPC(DMEAS, "MS_TO=%d ", mr->ms_timing_offset); @@ -1452,9 +1460,11 @@ mr->bs_power = *TLVP_VAL(&tp, RSL_IE_BS_POWER); /* Optional Parts */ - if (TLVP_PRESENT(&tp, RSL_IE_MS_TIMING_OFFSET)) - mr->ms_timing_offset = - *TLVP_VAL(&tp, RSL_IE_MS_TIMING_OFFSET); + if (TLVP_PRESENT(&tp, RSL_IE_MS_TIMING_OFFSET)) { + /* According to 3GPP TS 48.058 ? MS Timing Offset = Timing Offset field - 63 */ + mr->ms_timing_offset = *TLVP_VAL(&tp, RSL_IE_MS_TIMING_OFFSET) - 63; + mr->flags |= MEAS_REP_F_MS_TO; + } if (TLVP_PRESENT(&tp, RSL_IE_L1_INFO)) { struct e1inp_sign_link *sign_link = msg->dst; diff --git a/openbsc/src/libbsc/bsc_vty.c b/openbsc/src/libbsc/bsc_vty.c index c1882fc..3c70580 100644 --- a/openbsc/src/libbsc/bsc_vty.c +++ b/openbsc/src/libbsc/bsc_vty.c @@ -1062,8 +1062,7 @@ mr->flags & MEAS_REP_F_DL_VALID ? " " : "DLinval ", VTY_NEWLINE); if (mr->flags & MEAS_REP_F_MS_TO) - vty_out(vty, "%s MS Timing Offset: %u%s", prefix, - mr->ms_timing_offset, VTY_NEWLINE); + vty_out(vty, "%s MS Timing Offset: %d%s", prefix, mr->ms_timing_offset, VTY_NEWLINE); if (mr->flags & MEAS_REP_F_MS_L1) vty_out(vty, "%s L1 MS Power: %u dBm, Timing Advance: %u%s", prefix, mr->ms_l1.pwr, mr->ms_l1.ta, VTY_NEWLINE); diff --git a/openbsc/src/libmsc/smpp_openbsc.c b/openbsc/src/libmsc/smpp_openbsc.c index 2703a24..1671a62 100644 --- a/openbsc/src/libmsc/smpp_openbsc.c +++ b/openbsc/src/libmsc/smpp_openbsc.c @@ -437,8 +437,8 @@ append_tlv_u8(req_tlv, TLVID_osmo_ta, mr->ms_l1.ta); ms_dbm = ms_pwr_dbm(lchan->ts->trx->bts->band, mr->ms_l1.pwr); append_tlv_u8(req_tlv, TLVID_osmo_ms_l1_txpwr, ms_dbm); - } else if (mr->flags & MEAS_REP_F_MS_TO) - append_tlv_u8(req_tlv, TLVID_osmo_ta, mr->ms_timing_offset); + } else if (mr->flags & MEAS_REP_F_MS_TO) /* Save Timing Offset field = MS Timing Offset + 63 */ + append_tlv_u8(req_tlv, TLVID_osmo_ta, mr->ms_timing_offset + 63); append_tlv_u16(req_tlv, TLVID_osmo_rxlev_ul, rxlev2dbm(ul_meas->full.rx_lev)); diff --git a/openbsc/src/utils/meas_db.c b/openbsc/src/utils/meas_db.c index a3b694e..d81efca 100644 --- a/openbsc/src/utils/meas_db.c +++ b/openbsc/src/utils/meas_db.c @@ -114,8 +114,7 @@ SCK_OK(st->db, sqlite3_bind_int(st->stmt_ins_mr, 6, mr->bs_power)); if (mr->flags & MEAS_REP_F_MS_TO) - SCK_OK(st->db, sqlite3_bind_int(st->stmt_ins_mr, 7, - mr->ms_timing_offset)); + SCK_OK(st->db, sqlite3_bind_int(st->stmt_ins_mr, 7, mr->ms_timing_offset)); else SCK_OK(st->db, sqlite3_bind_null(st->stmt_ins_mr, 7)); diff --git a/openbsc/src/utils/meas_vis.c b/openbsc/src/utils/meas_vis.c index 316d203..77194de 100644 --- a/openbsc/src/utils/meas_vis.c +++ b/openbsc/src/utils/meas_vis.c @@ -200,7 +200,7 @@ COLS-40, rxlev2dbm(lq->rx_lev), -110, -47, 1, 2, FALSE, FALSE); //IsVisibleObj(ms->ul.cdk) = FALSE; - snprintf(msu->label, sizeof(msu->label), "%1d %3d %2u %2u %4u", + snprintf(msu->label, sizeof(msu->label), "%1d %3d %2u %2d %4u", qual_col, lq->rx_qual, qual_col, pwr, ms->mr.ms_l1.ta, ms->mr.ms_timing_offset, now - msu->last_update); -- To view, visit https://gerrit.osmocom.org/2391 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I7e003d23a6edb714c5f17688fd6a8edac131161d Gerrit-PatchSet: 3 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Alexander Chemeris Gerrit-Reviewer: Ivan Kluchnikov Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Apr 25 13:55:25 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Tue, 25 Apr 2017 13:55:25 +0000 Subject: [PATCH] osmo-bts[master]: Fix building ith newer autoconf Message-ID: Review at https://gerrit.osmocom.org/2405 Fix building ith newer autoconf Previously AC_CHECK_HEADER merely checked if header is accepted by the preprocessor, now actual compile check is performed. As gsm_data_shared.h has rather lengthy #include list, the easiest fix is to enable old behavior using special include parameter. Change-Id: I865db615359624776c311f4d752075327aadc06c --- M configure.ac 1 file changed, 1 insertion(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/05/2405/1 diff --git a/configure.ac b/configure.ac index a03b2dd..28a6975 100644 --- a/configure.ac +++ b/configure.ac @@ -154,7 +154,7 @@ CPPFLAGS="$CPPFLAGS -I$OPENBSC_INCDIR -I$srcdir/include $LIBOSMOCORE_CFLAGS" AC_CHECK_HEADER([openbsc/gsm_data_shared.h],[], [AC_MSG_ERROR([openbsc/gsm_data_shared.h can not be found in $openbsc_incdir])], - [#include ]) + [-]) CPPFLAGS=$oldCPPFLAGS # Check for the sbts2050_header.h that was added after the 3.6 release -- To view, visit https://gerrit.osmocom.org/2405 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I865db615359624776c311f4d752075327aadc06c Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max From gerrit-no-reply at lists.osmocom.org Tue Apr 25 14:09:44 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Tue, 25 Apr 2017 14:09:44 +0000 Subject: [ABANDON] osmo-bts[master]: Fix building ith newer autoconf In-Reply-To: References: Message-ID: Max has abandoned this change. Change subject: Fix building ith newer autoconf ...................................................................... Abandoned -- To view, visit https://gerrit.osmocom.org/2405 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: abandon Gerrit-Change-Id: I865db615359624776c311f4d752075327aadc06c Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Tue Apr 25 14:27:24 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Tue, 25 Apr 2017 14:27:24 +0000 Subject: libosmo-netif[master]: osmux: Check batch_factor overflow in osmux_batch_enqueue In-Reply-To: References: Message-ID: Patch Set 1: (1 comment) https://gerrit.osmocom.org/#/c/2403/1/src/osmux.c File src/osmux.c: Line 210: int batch_factor) Can batch_factor really be negative? If not, than why not use unsigned type to make it obvious? -- To view, visit https://gerrit.osmocom.org/2403 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I5d643810949aeca4762f0cad05eed534d35087f7 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Pau Espin Pedrol Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: daniel Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Tue Apr 25 14:29:00 2017 From: gerrit-no-reply at lists.osmocom.org (Pau Espin Pedrol) Date: Tue, 25 Apr 2017 14:29:00 +0000 Subject: libosmo-netif[master]: osmux: Check batch_factor overflow in osmux_batch_enqueue In-Reply-To: References: Message-ID: Patch Set 1: While preparing other tests I am adding to osmux + rtp marker support I saw that if this patch is missing, the situation seems to be even worse than I expected. I cannot for instance set h_input.batch_actor=4 and try to push more than 8 consecutive packets to 4 ccids, it will segfault at some point -- To view, visit https://gerrit.osmocom.org/2403 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I5d643810949aeca4762f0cad05eed534d35087f7 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Pau Espin Pedrol Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Pau Espin Pedrol Gerrit-Reviewer: daniel Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Apr 25 14:31:53 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Tue, 25 Apr 2017 14:31:53 +0000 Subject: libosmo-netif[master]: osmux: Check batch_factor overflow in osmux_batch_enqueue In-Reply-To: References: Message-ID: Patch Set 1: I don't see how your answer is related to my question. Could you be more specific? -- To view, visit https://gerrit.osmocom.org/2403 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I5d643810949aeca4762f0cad05eed534d35087f7 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Pau Espin Pedrol Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Pau Espin Pedrol Gerrit-Reviewer: daniel Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Apr 25 15:44:09 2017 From: gerrit-no-reply at lists.osmocom.org (Pau Espin Pedrol) Date: Tue, 25 Apr 2017 15:44:09 +0000 Subject: [PATCH] libosmo-netif[master]: osmux: Check batch_factor overflow in osmux_batch_enqueue In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2403 to look at the new patch set (#2). osmux: Check batch_factor overflow in osmux_batch_enqueue This commit should fix a bug present if for instance batch_factor < 8 and osmux_batch_enqueue is called from osmux_replay_lost_packets and enough packets were lost from last received packet. Change-Id: I5d643810949aeca4762f0cad05eed534d35087f7 --- M src/osmux.c 1 file changed, 7 insertions(+), 6 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-netif refs/changes/03/2403/2 diff --git a/src/osmux.c b/src/osmux.c index ae0bf26..1dcd04f 100644 --- a/src/osmux.c +++ b/src/osmux.c @@ -206,12 +206,13 @@ int dummy; }; -static int osmux_batch_enqueue(struct msgb *msg, struct osmux_circuit *circuit) +static int osmux_batch_enqueue(struct msgb *msg, struct osmux_circuit *circuit, + uint8_t batch_factor) { /* Too many messages per batch, discard it. The counter field of the * osmux header is just 3 bits long, so make sure it doesn't overflow. */ - if (circuit->nmsgs >= 8) { + if (circuit->nmsgs >= batch_factor || circuit->nmsgs >= 8) { struct rtp_hdr *rtph; rtph = osmo_rtp_get_hdr(msg); @@ -454,7 +455,7 @@ } static void osmux_replay_lost_packets(struct osmux_circuit *circuit, - struct rtp_hdr *cur_rtph) + struct rtp_hdr *cur_rtph, int batch_factor) { int16_t diff; struct msgb *last; @@ -500,7 +501,7 @@ DELTA_RTP_TIMESTAMP); /* No more room in this batch, skip padding with more clones */ - if (osmux_batch_enqueue(clone, circuit) < 0) { + if (osmux_batch_enqueue(clone, circuit, batch_factor) < 0) { msgb_free(clone); break; } @@ -609,10 +610,10 @@ } } /* Handle RTP packet loss scenario */ - osmux_replay_lost_packets(circuit, rtph); + osmux_replay_lost_packets(circuit, rtph, batch_factor); /* This batch is full, force batch delivery */ - if (osmux_batch_enqueue(msg, circuit) < 0) + if (osmux_batch_enqueue(msg, circuit, batch_factor) < 0) return 1; #ifdef DEBUG_MSG -- To view, visit https://gerrit.osmocom.org/2403 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I5d643810949aeca4762f0cad05eed534d35087f7 Gerrit-PatchSet: 2 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Pau Espin Pedrol Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Pau Espin Pedrol Gerrit-Reviewer: daniel From gerrit-no-reply at lists.osmocom.org Tue Apr 25 15:44:09 2017 From: gerrit-no-reply at lists.osmocom.org (Pau Espin Pedrol) Date: Tue, 25 Apr 2017 15:44:09 +0000 Subject: [PATCH] libosmo-netif[master]: osmux: use uint8_t everywhere for batch_factor Message-ID: Review at https://gerrit.osmocom.org/2406 osmux: use uint8_t everywhere for batch_factor Change-Id: I9fcc8e94b2fcd843b10cb3f8f009f2348eb3a4af --- M src/osmux.c 1 file changed, 5 insertions(+), 5 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-netif refs/changes/06/2406/1 diff --git a/src/osmux.c b/src/osmux.c index 5655269..ae0bf26 100644 --- a/src/osmux.c +++ b/src/osmux.c @@ -53,7 +53,7 @@ return osmo_amr_bytes(osmuxh->amr_ft) * (osmuxh->ctr+1); } -static uint32_t osmux_ft_dummy_size(uint8_t amr_ft, uint32_t batch_factor) +static uint32_t osmux_ft_dummy_size(uint8_t amr_ft, uint8_t batch_factor) { return sizeof(struct osmux_hdr) + (osmo_amr_bytes(amr_ft) * batch_factor); } @@ -307,7 +307,7 @@ return 0; } -static void osmux_encode_dummy(struct osmux_batch *batch, uint32_t batch_factor, +static void osmux_encode_dummy(struct osmux_batch *batch, uint8_t batch_factor, struct osmux_input_state *state) { struct osmux_hdr *osmuxh; @@ -331,7 +331,7 @@ } static struct msgb *osmux_build_batch(struct osmux_batch *batch, - uint32_t batch_size, uint32_t batch_factor) + uint32_t batch_size, uint8_t batch_factor) { struct msgb *batch_msg; struct osmux_circuit *circuit; @@ -523,7 +523,7 @@ static struct osmux_circuit * osmux_batch_add_circuit(struct osmux_batch *batch, int ccid, int dummy, - int batch_factor) + uint8_t batch_factor) { struct osmux_circuit *circuit; @@ -563,7 +563,7 @@ } static int -osmux_batch_add(struct osmux_batch *batch, int batch_factor, struct msgb *msg, +osmux_batch_add(struct osmux_batch *batch, uint32_t batch_factor, struct msgb *msg, struct rtp_hdr *rtph, int ccid) { int bytes = 0, amr_payload_len; -- To view, visit https://gerrit.osmocom.org/2406 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I9fcc8e94b2fcd843b10cb3f8f009f2348eb3a4af Gerrit-PatchSet: 1 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Pau Espin Pedrol From gerrit-no-reply at lists.osmocom.org Tue Apr 25 15:44:09 2017 From: gerrit-no-reply at lists.osmocom.org (Pau Espin Pedrol) Date: Tue, 25 Apr 2017 15:44:09 +0000 Subject: [PATCH] libosmo-netif[master]: osmux: Add RTP marker bit support Message-ID: Review at https://gerrit.osmocom.org/2407 osmux: Add RTP marker bit support Change-Id: I0315658159429603f1d80a168718b026015060e9 --- M include/osmocom/netif/osmux.h M src/osmux.c M tests/osmux/osmux_test.c 3 files changed, 81 insertions(+), 7 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-netif refs/changes/07/2407/1 diff --git a/include/osmocom/netif/osmux.h b/include/osmocom/netif/osmux.h index 1d93aa0..da319a7 100644 --- a/include/osmocom/netif/osmux.h +++ b/include/osmocom/netif/osmux.h @@ -13,8 +13,9 @@ /* OSmux header: * - * ft (3 bits): 0=signalling, 1=voice, 2=dummy + * ft (2 bits): 0=signalling, 1=voice, 2=dummy * ctr (3 bits): Number of batched AMR payloads (starting 0) + * rtp_m (1 bit): RTP M field (RFC3550) * amr_f (1 bit): AMR F field (RFC3267) * amr_q (1 bit): AMR Q field (RFC3267) * seq (8 bits): Combination of RTP timestamp and seq. number @@ -29,15 +30,17 @@ struct osmux_hdr { #if OSMO_IS_BIG_ENDIAN - uint8_t ft:3, + uint8_t ft:2, ctr:3, + rtp_m:1, amr_f:1, amr_q:1; #elif OSMO_IS_LITTLE_ENDIAN uint8_t amr_q:1, amr_f:1, + rtp_m:1, ctr:3, - ft:3; + ft:2; #endif uint8_t seq; #define OSMUX_CID_MAX 255 /* determined by circuit_id */ diff --git a/src/osmux.c b/src/osmux.c index 1dcd04f..4d12427 100644 --- a/src/osmux.c +++ b/src/osmux.c @@ -105,8 +105,8 @@ } static struct msgb * -osmux_rebuild_rtp(struct osmux_out_handle *h, - struct osmux_hdr *osmuxh, void *payload, int payload_len) +osmux_rebuild_rtp(struct osmux_out_handle *h, struct osmux_hdr *osmuxh, + void *payload, int payload_len, bool first_pkt) { struct msgb *out_msg; struct rtp_hdr *rtph; @@ -129,6 +129,8 @@ rtph->timestamp = htonl(h->rtp_timestamp); rtph->sequence = htons(h->rtp_seq); rtph->ssrc = htonl(h->rtp_ssrc); + /* rtp packet with the marker bit is always warranted to be the first one */ + rtph->marker = first_pkt && osmuxh->rtp_m; msgb_put(out_msg, sizeof(struct rtp_hdr)); @@ -166,7 +168,7 @@ msg = osmux_rebuild_rtp(h, osmuxh, osmux_get_payload(osmuxh) + i * osmo_amr_bytes(osmuxh->amr_ft), - osmo_amr_bytes(osmuxh->amr_ft)); + osmo_amr_bytes(osmuxh->amr_ft), !i); if (msg == NULL) continue; @@ -264,6 +266,7 @@ osmuxh = (struct osmux_hdr *)state->out_msg->tail; osmuxh->ft = OSMUX_FT_VOICE_AMR; osmuxh->ctr = 0; + osmuxh->rtp_m = osmuxh->rtp_m || state->rtph->marker; osmuxh->amr_f = state->amrh->f; osmuxh->amr_q= state->amrh->q; osmuxh->seq = batch->seq++; @@ -593,6 +596,13 @@ if (bytes > batch->remaining_bytes) return 1; + /* Init of talkspurt (RTP M marker bit) needs to be in the first AMR slot + * of the OSMUX packet, enforce sending previous batch if required: + */ + if (rtph->marker && circuit->nmsgs != 0) + return 1; + + /* Extra validation: check if this message already exists, should not * happen but make sure we don't propagate duplicated messages. */ diff --git a/tests/osmux/osmux_test.c b/tests/osmux/osmux_test.c index 2f5a6cd..8b0a56c 100644 --- a/tests/osmux/osmux_test.c +++ b/tests/osmux/osmux_test.c @@ -55,6 +55,7 @@ }; static int rtp_pkts; +static int mark_pkts; #if OSMUX_TEST_USE_TIMING static struct timeval last; #endif @@ -62,6 +63,7 @@ static void tx_cb(struct msgb *msg, void *data) { char buf[4096]; + struct rtp_hdr *rtph = (struct rtp_hdr *)msg->data; #if OSMUX_TEST_USE_TIMING struct timeval now, diff; @@ -87,6 +89,8 @@ exit(EXIT_FAILURE); } + if (rtph->marker) + mark_pkts--; rtp_pkts--; msgb_free(msg); } @@ -122,6 +126,48 @@ { printf("FAIL: test did not run successfully\n"); exit(EXIT_FAILURE); +} + +static void osmux_test_marker(int ccid) { + struct msgb *msg; + struct rtp_hdr *rtph = (struct rtp_hdr *)rtp_pkt; + struct rtp_hdr *cpy_rtph; + uint16_t seq; + int i, j; + + for (i = 0; i < 64; i++) { + + seq = ntohs(rtph->sequence); + seq++; + rtph->sequence = htons(seq); + + for (j=0; j<4; j++) { + msg = msgb_alloc(1500, "test"); + if (!msg) + exit(EXIT_FAILURE); + + memcpy(msg->data, rtp_pkt, sizeof(rtp_pkt)); + cpy_rtph = (struct rtp_hdr *) msgb_put(msg, sizeof(rtp_pkt)); + + if ((i+j) % 7 == 0) { + cpy_rtph->marker = 1; + mark_pkts++; + } + + rtp_pkts++; + while (osmux_xfrm_input(&h_input, msg, j + ccid) > 0) { + osmux_xfrm_input_deliver(&h_input); + } + } + } + + while (rtp_pkts) + osmo_select_main(0); + + if (mark_pkts) { + fprintf(stdout, "RTP M bit (marker) mismatch! %d\n", mark_pkts); + exit(EXIT_FAILURE); + } } static void osmux_test_loop(int ccid) @@ -177,6 +223,11 @@ k = 0; } } + + if (mark_pkts) { + fprintf(stdout, "RTP M bit (marker) mismatch! %d\n", mark_pkts); + exit(EXIT_FAILURE); + } } int main(void) @@ -192,12 +243,22 @@ osmo_init_logging(&osmux_test_log_info); log_set_log_level(osmo_stderr_target, LOGL_DEBUG); - osmux_xfrm_input_init(&h_input); osmux_xfrm_output_init(&h_output, 0x7000000); /* If the test takes longer than 10 seconds, abort it */ alarm(10); + /* Check if marker bit features work correctly */ + osmux_xfrm_input_init(&h_input); + for (i = 0; i < 4; i++) + osmux_xfrm_input_open_circuit(&h_input, i, 0); + osmux_test_marker(0); + for (i = 0; i < 4; i++) + osmux_xfrm_input_close_circuit(&h_input, i); + osmux_xfrm_input_fini(&h_input); + + osmux_xfrm_input_init(&h_input); + for (i = 0; i < 2; i++) osmux_xfrm_input_open_circuit(&h_input, i, 0); -- To view, visit https://gerrit.osmocom.org/2407 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I0315658159429603f1d80a168718b026015060e9 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Pau Espin Pedrol From admin at opensuse.org Tue Apr 25 20:00:38 2017 From: admin at opensuse.org (OBS Notification) Date: Tue, 25 Apr 2017 20:00:38 +0000 Subject: Build failure of network:osmocom:nightly/libosmo-netif in xUbuntu_17.04/i586 In-Reply-To: References: Message-ID: <58ffab10a3ff8_1bc99c0f7c4066b5@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/libosmo-netif/xUbuntu_17.04/i586 Package network:osmocom:nightly/libosmo-netif failed to build in xUbuntu_17.04/i586 Check out the package for editing: osc checkout network:osmocom:nightly libosmo-netif Last lines of build log: [ 141s] [ 141s] You may investigate any problem if you feel able to do so, in which [ 141s] case the test suite provides a good starting point. Its output may [ 141s] be found below `tests/testsuite.dir'. [ 141s] [ 141s] Makefile:642: recipe for target 'check-local' failed [ 141s] make[4]: *** [check-local] Error 1 [ 141s] make[4]: Leaving directory '/usr/src/packages/BUILD/tests' [ 141s] Makefile:495: recipe for target 'check-am' failed [ 141s] make[3]: *** [check-am] Error 2 [ 141s] make[3]: Leaving directory '/usr/src/packages/BUILD/tests' [ 141s] Makefile:493: recipe for target 'check-recursive' failed [ 141s] make[2]: *** [check-recursive] Error 1 [ 141s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 141s] Makefile:784: recipe for target 'check' failed [ 141s] make[1]: *** [check] Error 2 [ 141s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 141s] dh_auto_test: make -j1 check VERBOSE=1 returned exit code 2 [ 141s] debian/rules:13: recipe for target 'build' failed [ 141s] make: *** [build] Error 2 [ 141s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 141s] [ 141s] cloud133 failed "build libosmo-netif_0.0.7.20170425.dsc" at Tue Apr 25 20:00:30 UTC 2017. [ 141s] [ 141s] ### VM INTERACTION START ### [ 145s] ### VM INTERACTION END ### [ 145s] [ 145s] cloud133 failed "build libosmo-netif_0.0.7.20170425.dsc" at Tue Apr 25 20:00:35 UTC 2017. [ 145s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Tue Apr 25 20:02:55 2017 From: admin at opensuse.org (OBS Notification) Date: Tue, 25 Apr 2017 20:02:55 +0000 Subject: Build failure of network:osmocom:nightly/libosmo-sccp in xUbuntu_16.10/x86_64 In-Reply-To: References: Message-ID: <58ffab824c152_1bbd9c0f7c36901c@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/libosmo-sccp/xUbuntu_16.10/x86_64 Package network:osmocom:nightly/libosmo-sccp failed to build in xUbuntu_16.10/x86_64 Check out the package for editing: osc checkout network:osmocom:nightly libosmo-sccp Last lines of build log: [ 194s] ../../src/.libs/libosmo-sigtran.a(xua_asp_fsm.o): In function `ipa_asp_fsm_down': [ 194s] ./src/xua_asp_fsm.c:772: undefined reference to `ipa_ccm_send_id_req' [ 194s] ../../src/.libs/libosmo-sigtran.a(ipa.o): In function `ipa_tx_xua_as': [ 194s] ./src/ipa.c:71: undefined reference to `ipa_msg_alloc' [ 194s] collect2: error: ld returned 1 exit status [ 194s] Makefile:360: recipe for target 'xua_test' failed [ 194s] make[4]: *** [xua_test] Error 1 [ 194s] make[4]: Leaving directory '/usr/src/packages/BUILD/tests/xua' [ 194s] Makefile:362: recipe for target 'all-recursive' failed [ 194s] make[3]: *** [all-recursive] Error 1 [ 194s] make[3]: Leaving directory '/usr/src/packages/BUILD/tests' [ 194s] Makefile:454: recipe for target 'all-recursive' failed [ 194s] make[2]: *** [all-recursive] Error 1 [ 194s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 194s] Makefile:372: recipe for target 'all' failed [ 194s] make[1]: *** [all] Error 2 [ 194s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 194s] dh_auto_build: make -j1 returned exit code 2 [ 194s] debian/rules:12: recipe for target 'build' failed [ 194s] make: *** [build] Error 2 [ 194s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 194s] [ 194s] cloud108 failed "build libosmo-sccp_0.7.1.20170425.dsc" at Tue Apr 25 20:02:45 UTC 2017. [ 194s] [ 194s] ### VM INTERACTION START ### [ 199s] ### VM INTERACTION END ### [ 199s] [ 199s] cloud108 failed "build libosmo-sccp_0.7.1.20170425.dsc" at Tue Apr 25 20:02:50 UTC 2017. [ 199s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Tue Apr 25 20:02:55 2017 From: admin at opensuse.org (OBS Notification) Date: Tue, 25 Apr 2017 20:02:55 +0000 Subject: Build failure of network:osmocom:nightly/libosmo-sccp in xUbuntu_17.04/x86_64 In-Reply-To: References: Message-ID: <58ffaba346753_1e2461ef7c321631@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/libosmo-sccp/xUbuntu_17.04/x86_64 Package network:osmocom:nightly/libosmo-sccp failed to build in xUbuntu_17.04/x86_64 Check out the package for editing: osc checkout network:osmocom:nightly libosmo-sccp Last lines of build log: [ 139s] ./src/xua_asp_fsm.c:772: undefined reference to `ipa_ccm_send_id_req' [ 139s] ../../src/.libs/libosmo-sigtran.a(ipa.o): In function `ipa_tx_xua_as': [ 139s] ./src/ipa.c:71: undefined reference to `ipa_msg_alloc' [ 139s] collect2: error: ld returned 1 exit status [ 139s] Makefile:360: recipe for target 'xua_test' failed [ 139s] make[4]: *** [xua_test] Error 1 [ 139s] make[4]: Leaving directory '/usr/src/packages/BUILD/tests/xua' [ 139s] Makefile:362: recipe for target 'all-recursive' failed [ 139s] make[3]: *** [all-recursive] Error 1 [ 139s] make[3]: Leaving directory '/usr/src/packages/BUILD/tests' [ 139s] Makefile:454: recipe for target 'all-recursive' failed [ 139s] make[2]: *** [all-recursive] Error 1 [ 139s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 139s] Makefile:372: recipe for target 'all' failed [ 139s] make[1]: *** [all] Error 2 [ 139s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 139s] dh_auto_build: make -j1 returned exit code 2 [ 139s] debian/rules:12: recipe for target 'build' failed [ 139s] make: *** [build] Error 2 [ 139s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 139s] [ 139s] lamb61 failed "build libosmo-sccp_0.7.1.20170425.dsc" at Tue Apr 25 20:02:41 UTC 2017. [ 139s] [ 139s] ### VM INTERACTION START ### [ 143s] [ 127.358249] reboot: Power down [ 143s] ### VM INTERACTION END ### [ 143s] [ 143s] lamb61 failed "build libosmo-sccp_0.7.1.20170425.dsc" at Tue Apr 25 20:02:45 UTC 2017. [ 143s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Tue Apr 25 20:03:13 2017 From: admin at opensuse.org (OBS Notification) Date: Tue, 25 Apr 2017 20:03:13 +0000 Subject: Build failure of network:osmocom:nightly/libosmo-sccp in Debian_8.0/i586 In-Reply-To: References: Message-ID: <58ffaba4185be_1e2461ef7c3217f5@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/libosmo-sccp/Debian_8.0/i586 Package network:osmocom:nightly/libosmo-sccp failed to build in Debian_8.0/i586 Check out the package for editing: osc checkout network:osmocom:nightly libosmo-sccp Last lines of build log: [ 150s] CCLD xua_test [ 150s] /usr/bin/ld: ../../src/.libs/libosmo-sigtran.a(osmo_ss7.o): undefined reference to symbol 'ipa_msg_recv_buffered@@LIBOSMOGSM_1.0' [ 150s] //usr/lib/i386-linux-gnu/libosmogsm.so.6: error adding symbols: DSO missing from command line [ 150s] collect2: error: ld returned 1 exit status [ 150s] Makefile:348: recipe for target 'xua_test' failed [ 150s] make[4]: *** [xua_test] Error 1 [ 150s] make[4]: Leaving directory '/usr/src/packages/BUILD/tests/xua' [ 150s] Makefile:350: recipe for target 'all-recursive' failed [ 150s] make[3]: *** [all-recursive] Error 1 [ 150s] make[3]: Leaving directory '/usr/src/packages/BUILD/tests' [ 150s] Makefile:443: recipe for target 'all-recursive' failed [ 150s] make[2]: *** [all-recursive] Error 1 [ 150s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 150s] Makefile:360: recipe for target 'all' failed [ 150s] make[1]: *** [all] Error 2 [ 150s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 150s] dh_auto_build: make -j1 returned exit code 2 [ 150s] debian/rules:12: recipe for target 'build' failed [ 150s] make: *** [build] Error 2 [ 150s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 150s] [ 150s] cloud128 failed "build libosmo-sccp_0.7.1.20170425.dsc" at Tue Apr 25 20:02:53 UTC 2017. [ 150s] [ 150s] ### VM INTERACTION START ### [ 151s] Powering off. [ 154s] ### VM INTERACTION END ### [ 154s] [ 154s] cloud128 failed "build libosmo-sccp_0.7.1.20170425.dsc" at Tue Apr 25 20:02:57 UTC 2017. [ 154s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Tue Apr 25 20:03:30 2017 From: admin at opensuse.org (OBS Notification) Date: Tue, 25 Apr 2017 20:03:30 +0000 Subject: Build failure of network:osmocom:nightly/libosmo-sccp in xUbuntu_17.04/i586 In-Reply-To: References: Message-ID: <58ffaba51e151_1e2461ef7c321879@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/libosmo-sccp/xUbuntu_17.04/i586 Package network:osmocom:nightly/libosmo-sccp failed to build in xUbuntu_17.04/i586 Check out the package for editing: osc checkout network:osmocom:nightly libosmo-sccp Last lines of build log: [ 142s] ./src/xua_asp_fsm.c:772: undefined reference to `ipa_ccm_send_id_req' [ 142s] ../../src/.libs/libosmo-sigtran.a(ipa.o): In function `ipa_tx_xua_as': [ 142s] ./src/ipa.c:71: undefined reference to `ipa_msg_alloc' [ 142s] collect2: error: ld returned 1 exit status [ 142s] Makefile:360: recipe for target 'xua_test' failed [ 142s] make[4]: *** [xua_test] Error 1 [ 143s] make[4]: Leaving directory '/usr/src/packages/BUILD/tests/xua' [ 143s] Makefile:362: recipe for target 'all-recursive' failed [ 143s] make[3]: *** [all-recursive] Error 1 [ 143s] make[3]: Leaving directory '/usr/src/packages/BUILD/tests' [ 143s] Makefile:454: recipe for target 'all-recursive' failed [ 143s] make[2]: *** [all-recursive] Error 1 [ 143s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 143s] Makefile:372: recipe for target 'all' failed [ 143s] make[1]: *** [all] Error 2 [ 143s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 143s] dh_auto_build: make -j1 returned exit code 2 [ 143s] debian/rules:12: recipe for target 'build' failed [ 143s] make: *** [build] Error 2 [ 143s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 143s] [ 143s] lamb14 failed "build libosmo-sccp_0.7.1.20170425.dsc" at Tue Apr 25 20:03:14 UTC 2017. [ 143s] [ 143s] ### VM INTERACTION START ### [ 146s] [ 127.475977] reboot: Power down [ 146s] ### VM INTERACTION END ### [ 146s] [ 146s] lamb14 failed "build libosmo-sccp_0.7.1.20170425.dsc" at Tue Apr 25 20:03:18 UTC 2017. [ 146s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Tue Apr 25 20:04:21 2017 From: admin at opensuse.org (OBS Notification) Date: Tue, 25 Apr 2017 20:04:21 +0000 Subject: Build failure of network:osmocom:nightly/libosmo-sccp in xUbuntu_16.10/i586 In-Reply-To: References: Message-ID: <58ffabddea728_1e2461ef7c32211c@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/libosmo-sccp/xUbuntu_16.10/i586 Package network:osmocom:nightly/libosmo-sccp failed to build in xUbuntu_16.10/i586 Check out the package for editing: osc checkout network:osmocom:nightly libosmo-sccp Last lines of build log: [ 130s] ./src/xua_asp_fsm.c:772: undefined reference to `ipa_ccm_send_id_req' [ 130s] ../../src/.libs/libosmo-sigtran.a(ipa.o): In function `ipa_tx_xua_as': [ 130s] ./src/ipa.c:71: undefined reference to `ipa_msg_alloc' [ 130s] collect2: error: ld returned 1 exit status [ 130s] Makefile:360: recipe for target 'xua_test' failed [ 130s] make[4]: *** [xua_test] Error 1 [ 130s] make[4]: Leaving directory '/usr/src/packages/BUILD/tests/xua' [ 130s] Makefile:362: recipe for target 'all-recursive' failed [ 130s] make[3]: *** [all-recursive] Error 1 [ 130s] make[3]: Leaving directory '/usr/src/packages/BUILD/tests' [ 130s] Makefile:454: recipe for target 'all-recursive' failed [ 130s] make[2]: *** [all-recursive] Error 1 [ 130s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 130s] Makefile:372: recipe for target 'all' failed [ 130s] make[1]: *** [all] Error 2 [ 130s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 130s] dh_auto_build: make -j1 returned exit code 2 [ 130s] debian/rules:12: recipe for target 'build' failed [ 130s] make: *** [build] Error 2 [ 130s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 130s] [ 130s] lamb63 failed "build libosmo-sccp_0.7.1.20170425.dsc" at Tue Apr 25 20:04:03 UTC 2017. [ 130s] [ 130s] ### VM INTERACTION START ### [ 133s] [ 119.752444] reboot: Power down [ 133s] ### VM INTERACTION END ### [ 133s] [ 133s] lamb63 failed "build libosmo-sccp_0.7.1.20170425.dsc" at Tue Apr 25 20:04:07 UTC 2017. [ 133s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Tue Apr 25 20:04:21 2017 From: admin at opensuse.org (OBS Notification) Date: Tue, 25 Apr 2017 20:04:21 +0000 Subject: Build failure of network:osmocom:nightly/libosmo-sccp in xUbuntu_16.04/i586 In-Reply-To: References: Message-ID: <58ffabde4b8e3_1e2461ef7c32221d@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/libosmo-sccp/xUbuntu_16.04/i586 Package network:osmocom:nightly/libosmo-sccp failed to build in xUbuntu_16.04/i586 Check out the package for editing: osc checkout network:osmocom:nightly libosmo-sccp Last lines of build log: [ 178s] /usr/src/packages/BUILD/src/xua_asp_fsm.c:772: undefined reference to `ipa_ccm_send_id_req' [ 178s] ../../src/.libs/libosmo-sigtran.a(ipa.o): In function `ipa_tx_xua_as': [ 178s] /usr/src/packages/BUILD/src/ipa.c:71: undefined reference to `ipa_msg_alloc' [ 178s] collect2: error: ld returned 1 exit status [ 178s] Makefile:360: recipe for target 'xua_test' failed [ 178s] make[4]: *** [xua_test] Error 1 [ 178s] make[4]: Leaving directory '/usr/src/packages/BUILD/tests/xua' [ 178s] Makefile:362: recipe for target 'all-recursive' failed [ 178s] make[3]: *** [all-recursive] Error 1 [ 178s] make[3]: Leaving directory '/usr/src/packages/BUILD/tests' [ 178s] Makefile:454: recipe for target 'all-recursive' failed [ 178s] make[2]: *** [all-recursive] Error 1 [ 178s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 178s] Makefile:372: recipe for target 'all' failed [ 178s] make[1]: *** [all] Error 2 [ 178s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 178s] dh_auto_build: make -j1 returned exit code 2 [ 178s] debian/rules:12: recipe for target 'build' failed [ 178s] make: *** [build] Error 2 [ 178s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 178s] [ 178s] cloud124 failed "build libosmo-sccp_0.7.1.20170425.dsc" at Tue Apr 25 20:04:03 UTC 2017. [ 178s] [ 178s] ### VM INTERACTION START ### [ 181s] [ 149.817671] reboot: Power down [ 182s] ### VM INTERACTION END ### [ 182s] [ 182s] cloud124 failed "build libosmo-sccp_0.7.1.20170425.dsc" at Tue Apr 25 20:04:07 UTC 2017. [ 182s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Tue Apr 25 20:04:21 2017 From: admin at opensuse.org (OBS Notification) Date: Tue, 25 Apr 2017 20:04:21 +0000 Subject: Build failure of network:osmocom:nightly/libosmo-sccp in xUbuntu_16.04/x86_64 In-Reply-To: References: Message-ID: <58ffabdf37635_1e2461ef7c322368@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/libosmo-sccp/xUbuntu_16.04/x86_64 Package network:osmocom:nightly/libosmo-sccp failed to build in xUbuntu_16.04/x86_64 Check out the package for editing: osc checkout network:osmocom:nightly libosmo-sccp Last lines of build log: [ 107s] ../../src/.libs/libosmo-sigtran.a(xua_asp_fsm.o): In function `ipa_asp_fsm_down': [ 107s] /usr/src/packages/BUILD/src/xua_asp_fsm.c:772: undefined reference to `ipa_ccm_send_id_req' [ 107s] ../../src/.libs/libosmo-sigtran.a(ipa.o): In function `ipa_tx_xua_as': [ 107s] /usr/src/packages/BUILD/src/ipa.c:71: undefined reference to `ipa_msg_alloc' [ 107s] collect2: error: ld returned 1 exit status [ 107s] Makefile:360: recipe for target 'xua_test' failed [ 107s] make[4]: *** [xua_test] Error 1 [ 107s] make[4]: Leaving directory '/usr/src/packages/BUILD/tests/xua' [ 107s] Makefile:362: recipe for target 'all-recursive' failed [ 107s] make[3]: *** [all-recursive] Error 1 [ 107s] make[3]: Leaving directory '/usr/src/packages/BUILD/tests' [ 107s] Makefile:454: recipe for target 'all-recursive' failed [ 107s] make[2]: *** [all-recursive] Error 1 [ 107s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 107s] Makefile:372: recipe for target 'all' failed [ 107s] make[1]: *** [all] Error 2 [ 107s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 107s] dh_auto_build: make -j1 returned exit code 2 [ 107s] debian/rules:12: recipe for target 'build' failed [ 107s] make: *** [build] Error 2 [ 107s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 107s] [ 107s] build79 failed "build libosmo-sccp_0.7.1.20170425.dsc" at Tue Apr 25 20:04:09 UTC 2017. [ 107s] [ 107s] ### VM INTERACTION START ### [ 111s] ### VM INTERACTION END ### [ 111s] [ 111s] build79 failed "build libosmo-sccp_0.7.1.20170425.dsc" at Tue Apr 25 20:04:13 UTC 2017. [ 111s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Tue Apr 25 20:04:55 2017 From: admin at opensuse.org (OBS Notification) Date: Tue, 25 Apr 2017 20:04:55 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in xUbuntu_16.10/x86_64 In-Reply-To: References: Message-ID: <58ffabfc46e80_1e2461ef7c3227a7@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/xUbuntu_16.10/x86_64 Package network:osmocom:nightly/osmo-stp failed to build in xUbuntu_16.10/x86_64 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 56s] #warning "Notify any other AS(P) for failover scenario" [ 56s] ^~~~~~~ [ 57s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o vty_interface.o vty_interface.c [ 57s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o sctp_m3ua_client.o sctp_m3ua_client.c [ 57s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 57s] #include [ 57s] ^ [ 57s] compilation terminated. [ 57s] Makefile:485: recipe for target 'sctp_m3ua_client.o' failed [ 57s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 57s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 57s] Makefile:380: recipe for target 'all-recursive' failed [ 57s] make[2]: *** [all-recursive] Error 1 [ 57s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 57s] Makefile:321: recipe for target 'all' failed [ 57s] make[1]: *** [all] Error 2 [ 57s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 57s] dh_auto_build: make -j1 returned exit code 2 [ 57s] debian/rules:23: recipe for target 'build' failed [ 57s] make: *** [build] Error 2 [ 57s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 57s] [ 57s] build84 failed "build cellmgr-ng_1.4.7.20170425.dsc" at Tue Apr 25 20:04:40 UTC 2017. [ 57s] [ 57s] ### VM INTERACTION START ### [ 61s] ### VM INTERACTION END ### [ 61s] [ 61s] build84 failed "build cellmgr-ng_1.4.7.20170425.dsc" at Tue Apr 25 20:04:45 UTC 2017. [ 61s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Tue Apr 25 20:05:31 2017 From: admin at opensuse.org (OBS Notification) Date: Tue, 25 Apr 2017 20:05:31 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in xUbuntu_17.04/i586 In-Reply-To: References: Message-ID: <58ffac1a770dd_1e2461ef7c322875@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/xUbuntu_17.04/i586 Package network:osmocom:nightly/osmo-stp failed to build in xUbuntu_17.04/i586 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 82s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o vty_interface_cmds.o vty_interface_cmds.c [ 83s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o mgcp_patch.o mgcp_patch.c [ 83s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o mgcp_callagent.o mgcp_callagent.c [ 83s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o isup_filter.o isup_filter.c [ 83s] gcc -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -Wl,-Bsymbolic-functions -Wl,-z,relro -o cellmgr_ng main.o mtp_layer3.o thread.o ipaccess.o pcap.o bss_patch.o bssap_sccp.o bsc_sccp.o bsc_ussd.o links.o msc_conn.o link_udp.o snmp_mtp.o debug.o isup.o mtp_link.o counter.o sccp_state.o bsc.o ss7_application.o vty_interface_legacy.o vty_interface_cmds.o mgcp_patch.o mgcp_callagent.o isup_filter.o -losmosccp -losmoxua -ltalloc -losmogsm -losmocore -ltalloc -losmovty -losmocore -ltalloc -losmocore -lpthread -lnetsnmp -lcrypto [ 83s] /usr/lib/gcc/i686-linux-gnu/6/../../../i386-linux-gnu/libosmosccp.so: undefined reference to `talloc_free' [ 83s] collect2: error: ld returned 1 exit status [ 83s] Makefile:425: recipe for target 'cellmgr_ng' failed [ 83s] make[3]: *** [cellmgr_ng] Error 1 [ 83s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 83s] Makefile:380: recipe for target 'all-recursive' failed [ 83s] make[2]: *** [all-recursive] Error 1 [ 83s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 83s] Makefile:321: recipe for target 'all' failed [ 83s] make[1]: *** [all] Error 2 [ 83s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 83s] dh_auto_build: make -j1 returned exit code 2 [ 83s] debian/rules:23: recipe for target 'build' failed [ 83s] make: *** [build] Error 2 [ 83s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 83s] [ 83s] lamb20 failed "build cellmgr-ng_1.4.7.20170425.dsc" at Tue Apr 25 20:05:18 UTC 2017. [ 83s] [ 83s] ### VM INTERACTION START ### [ 86s] [ 73.191015] reboot: Power down [ 86s] ### VM INTERACTION END ### [ 86s] [ 86s] lamb20 failed "build cellmgr-ng_1.4.7.20170425.dsc" at Tue Apr 25 20:05:22 UTC 2017. [ 86s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Tue Apr 25 20:06:21 2017 From: admin at opensuse.org (OBS Notification) Date: Tue, 25 Apr 2017 20:06:21 +0000 Subject: Build failure of network:osmocom:nightly/openbsc in xUbuntu_17.04/x86_64 In-Reply-To: References: Message-ID: <58ffac738d447_1bbd9c0f7c3691c9@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/openbsc/xUbuntu_17.04/x86_64 Package network:osmocom:nightly/openbsc failed to build in xUbuntu_17.04/x86_64 Check out the package for editing: osc checkout network:osmocom:nightly openbsc Last lines of build log: [ 134s] gcc -DHAVE_CONFIG_H -I. -I../.. -I../../include -I../.. -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fPIE -fstack-protector-strong -Wformat -Werror=format-security -Werror=implicit -Werror=maybe-uninitialized -Werror=memset-transposed-args -Werror=null-dereference -Werror=sizeof-array-argument -Werror=sizeof-pointer-memaccess -c -o bsc_nat_filter.o bsc_nat_filter.c [ 134s] gcc -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fPIE -fstack-protector-strong -Wformat -Werror=format-security -Werror=implicit -Werror=maybe-uninitialized -Werror=memset-transposed-args -Werror=null-dereference -Werror=sizeof-array-argument -Werror=sizeof-pointer-memaccess -Wl,-Bsymbolic-functions -fPIE -pie -Wl,-z,relro -Wl,-z,now -o osmo-bsc_nat bsc_filter.o bsc_mgcp_utils.o bsc_nat.o bsc_nat_utils.o bsc_nat_vty.o bsc_sccp.o bsc_ussd.o bsc_nat_ctrl.o bsc_nat_rewrite.o bsc_nat_rewrite_trie.o bsc_nat_filter.o ../../src/libmgcp/libmgcp.a ../../src/libfilter/libfilter.a ../../src/libbsc/libbsc.a ../../src/libcommon-cs/libcommon-cs.a ../../src/libtrau/libtrau.a ../../src/libcommon/libcommon.a -losmosccp -losmoxua -ltalloc -losmocore -ltalloc -losmogsm -losmocore -ltalloc -losmovty -losmocore -ltalloc -losmoctrl -losmogsm -losmocore -losmoabis -losmonetif -lcrypto -lrt [ 134s] /usr/lib/gcc/x86_64-linux-gnu/6/../../../x86_64-linux-gnu/libosmosccp.so: undefined reference to `talloc_free' [ 134s] collect2: error: ld returned 1 exit status [ 134s] Makefile:460: recipe for target 'osmo-bsc_nat' failed [ 134s] make[4]: *** [osmo-bsc_nat] Error 1 [ 134s] make[4]: Leaving directory '/usr/src/packages/BUILD/openbsc/src/osmo-bsc_nat' [ 134s] Makefile:418: recipe for target 'all-recursive' failed [ 134s] make[3]: *** [all-recursive] Error 1 [ 134s] make[3]: Leaving directory '/usr/src/packages/BUILD/openbsc/src' [ 134s] Makefile:486: recipe for target 'all-recursive' failed [ 134s] make[2]: *** [all-recursive] Error 1 [ 134s] make[2]: Leaving directory '/usr/src/packages/BUILD/openbsc' [ 134s] Makefile:404: recipe for target 'all' failed [ 134s] make[1]: *** [all] Error 2 [ 134s] make[1]: Leaving directory '/usr/src/packages/BUILD/openbsc' [ 134s] dh_auto_build: make -j1 returned exit code 2 [ 134s] debian/rules:13: recipe for target 'build' failed [ 134s] make: *** [build] Error 2 [ 134s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 134s] [ 134s] lamb12 failed "build openbsc_0.15.1.20170425.dsc" at Tue Apr 25 20:06:00 UTC 2017. [ 134s] [ 134s] ### VM INTERACTION START ### [ 138s] [ 123.267987] reboot: Power down [ 138s] ### VM INTERACTION END ### [ 138s] [ 138s] lamb12 failed "build openbsc_0.15.1.20170425.dsc" at Tue Apr 25 20:06:04 UTC 2017. [ 138s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Tue Apr 25 20:06:21 2017 From: admin at opensuse.org (OBS Notification) Date: Tue, 25 Apr 2017 20:06:21 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in xUbuntu_17.04/x86_64 In-Reply-To: References: Message-ID: <58ffac73ef8ea_1bbd9c0f7c369226@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/xUbuntu_17.04/x86_64 Package network:osmocom:nightly/osmo-stp failed to build in xUbuntu_17.04/x86_64 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 123s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o vty_interface_cmds.o vty_interface_cmds.c [ 123s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o mgcp_patch.o mgcp_patch.c [ 123s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o mgcp_callagent.o mgcp_callagent.c [ 123s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o isup_filter.o isup_filter.c [ 124s] gcc -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -Wl,-Bsymbolic-functions -Wl,-z,relro -o cellmgr_ng main.o mtp_layer3.o thread.o ipaccess.o pcap.o bss_patch.o bssap_sccp.o bsc_sccp.o bsc_ussd.o links.o msc_conn.o link_udp.o snmp_mtp.o debug.o isup.o mtp_link.o counter.o sccp_state.o bsc.o ss7_application.o vty_interface_legacy.o vty_interface_cmds.o mgcp_patch.o mgcp_callagent.o isup_filter.o -losmosccp -losmoxua -ltalloc -losmogsm -losmocore -ltalloc -losmovty -losmocore -ltalloc -losmocore -lpthread -lnetsnmp -lcrypto [ 124s] /usr/lib/gcc/x86_64-linux-gnu/6/../../../x86_64-linux-gnu/libosmosccp.so: undefined reference to `talloc_free' [ 124s] collect2: error: ld returned 1 exit status [ 124s] Makefile:425: recipe for target 'cellmgr_ng' failed [ 124s] make[3]: *** [cellmgr_ng] Error 1 [ 124s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 124s] Makefile:380: recipe for target 'all-recursive' failed [ 124s] make[2]: *** [all-recursive] Error 1 [ 124s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 124s] Makefile:321: recipe for target 'all' failed [ 124s] make[1]: *** [all] Error 2 [ 124s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 124s] dh_auto_build: make -j1 returned exit code 2 [ 124s] debian/rules:23: recipe for target 'build' failed [ 124s] make: *** [build] Error 2 [ 124s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 124s] [ 124s] cloud111 failed "build cellmgr-ng_1.4.7.20170425.dsc" at Tue Apr 25 20:06:03 UTC 2017. [ 124s] [ 124s] ### VM INTERACTION START ### [ 127s] [ 98.230875] reboot: Power down [ 128s] ### VM INTERACTION END ### [ 128s] [ 128s] cloud111 failed "build cellmgr-ng_1.4.7.20170425.dsc" at Tue Apr 25 20:06:08 UTC 2017. [ 128s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Tue Apr 25 20:06:21 2017 From: admin at opensuse.org (OBS Notification) Date: Tue, 25 Apr 2017 20:06:21 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in xUbuntu_16.10/i586 In-Reply-To: References: Message-ID: <58ffac7477cdb_1bbd9c0f7c369319@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/xUbuntu_16.10/i586 Package network:osmocom:nightly/osmo-stp failed to build in xUbuntu_16.10/i586 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 83s] ^~~~~~~ [ 84s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o vty_interface.o vty_interface.c [ 84s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o sctp_m3ua_client.o sctp_m3ua_client.c [ 85s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 85s] #include [ 85s] ^ [ 85s] compilation terminated. [ 85s] Makefile:485: recipe for target 'sctp_m3ua_client.o' failed [ 85s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 85s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 85s] Makefile:380: recipe for target 'all-recursive' failed [ 85s] make[2]: *** [all-recursive] Error 1 [ 85s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 85s] Makefile:321: recipe for target 'all' failed [ 85s] make[1]: *** [all] Error 2 [ 85s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 85s] dh_auto_build: make -j1 returned exit code 2 [ 85s] debian/rules:23: recipe for target 'build' failed [ 85s] make: *** [build] Error 2 [ 85s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 85s] [ 85s] lamb12 failed "build cellmgr-ng_1.4.7.20170425.dsc" at Tue Apr 25 20:06:06 UTC 2017. [ 85s] [ 85s] ### VM INTERACTION START ### [ 88s] [ 75.128499] reboot: Power down [ 88s] ### VM INTERACTION END ### [ 88s] [ 88s] lamb12 failed "build cellmgr-ng_1.4.7.20170425.dsc" at Tue Apr 25 20:06:10 UTC 2017. [ 88s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Tue Apr 25 20:06:21 2017 From: admin at opensuse.org (OBS Notification) Date: Tue, 25 Apr 2017 20:06:21 +0000 Subject: Build failure of network:osmocom:nightly/libosmo-sccp in Debian_8.0/x86_64 In-Reply-To: References: Message-ID: <58ffac752464f_1bbd9c0f7c36947d@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/libosmo-sccp/Debian_8.0/x86_64 Package network:osmocom:nightly/libosmo-sccp failed to build in Debian_8.0/x86_64 Check out the package for editing: osc checkout network:osmocom:nightly libosmo-sccp Last lines of build log: [ 127s] CCLD xua_test [ 128s] /usr/bin/ld: ../../src/.libs/libosmo-sigtran.a(osmo_ss7.o): undefined reference to symbol 'ipa_msg_recv_buffered@@LIBOSMOGSM_1.0' [ 128s] //usr/lib/x86_64-linux-gnu/libosmogsm.so.6: error adding symbols: DSO missing from command line [ 128s] collect2: error: ld returned 1 exit status [ 128s] Makefile:348: recipe for target 'xua_test' failed [ 128s] make[4]: *** [xua_test] Error 1 [ 128s] make[4]: Leaving directory '/usr/src/packages/BUILD/tests/xua' [ 128s] Makefile:350: recipe for target 'all-recursive' failed [ 128s] make[3]: *** [all-recursive] Error 1 [ 128s] make[3]: Leaving directory '/usr/src/packages/BUILD/tests' [ 128s] Makefile:443: recipe for target 'all-recursive' failed [ 128s] make[2]: *** [all-recursive] Error 1 [ 128s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 128s] Makefile:360: recipe for target 'all' failed [ 128s] make[1]: *** [all] Error 2 [ 128s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 128s] dh_auto_build: make -j1 returned exit code 2 [ 128s] debian/rules:12: recipe for target 'build' failed [ 128s] make: *** [build] Error 2 [ 128s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 128s] [ 128s] lamb71 failed "build libosmo-sccp_0.7.1.20170425.dsc" at Tue Apr 25 20:06:10 UTC 2017. [ 128s] [ 128s] ### VM INTERACTION START ### [ 129s] Powering off. [ 129s] ### VM INTERACTION END ### [ 129s] [ 129s] lamb71 failed "build libosmo-sccp_0.7.1.20170425.dsc" at Tue Apr 25 20:06:11 UTC 2017. [ 129s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Tue Apr 25 20:06:38 2017 From: admin at opensuse.org (OBS Notification) Date: Tue, 25 Apr 2017 20:06:38 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in Debian_8.0/i586 In-Reply-To: References: Message-ID: <58ffac75723f5_1bbd9c0f7c36977d@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/Debian_8.0/i586 Package network:osmocom:nightly/osmo-stp failed to build in Debian_8.0/i586 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 158s] ^ [ 159s] CC vty_interface.o [ 159s] CC sctp_m3ua_client.o [ 159s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 159s] #include [ 159s] ^ [ 159s] compilation terminated. [ 159s] Makefile:475: recipe for target 'sctp_m3ua_client.o' failed [ 159s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 159s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 159s] Makefile:370: recipe for target 'all-recursive' failed [ 159s] make[2]: *** [all-recursive] Error 1 [ 159s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 159s] Makefile:310: recipe for target 'all' failed [ 159s] make[1]: *** [all] Error 2 [ 159s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 159s] dh_auto_build: make -j1 returned exit code 2 [ 159s] debian/rules:23: recipe for target 'build' failed [ 159s] make: *** [build] Error 2 [ 159s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 159s] [ 159s] build75 failed "build cellmgr-ng_1.4.7.20170425.dsc" at Tue Apr 25 20:06:20 UTC 2017. [ 159s] [ 159s] ### VM INTERACTION START ### [ 161s] Powering off. [ 161s] ### VM INTERACTION END ### [ 161s] [ 161s] build75 failed "build cellmgr-ng_1.4.7.20170425.dsc" at Tue Apr 25 20:06:22 UTC 2017. [ 161s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Tue Apr 25 20:07:13 2017 From: admin at opensuse.org (OBS Notification) Date: Tue, 25 Apr 2017 20:07:13 +0000 Subject: Build failure of network:osmocom:nightly/openbsc in xUbuntu_17.04/i586 In-Reply-To: References: Message-ID: <58ffac9352550_1e2461ef7c323067@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/openbsc/xUbuntu_17.04/i586 Package network:osmocom:nightly/openbsc failed to build in xUbuntu_17.04/i586 Check out the package for editing: osc checkout network:osmocom:nightly openbsc Last lines of build log: [ 173s] gcc -DHAVE_CONFIG_H -I. -I../.. -I../../include -I../.. -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fPIE -fstack-protector-strong -Wformat -Werror=format-security -Werror=implicit -Werror=maybe-uninitialized -Werror=memset-transposed-args -Werror=null-dereference -Werror=sizeof-array-argument -Werror=sizeof-pointer-memaccess -c -o bsc_nat_filter.o bsc_nat_filter.c [ 174s] gcc -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fPIE -fstack-protector-strong -Wformat -Werror=format-security -Werror=implicit -Werror=maybe-uninitialized -Werror=memset-transposed-args -Werror=null-dereference -Werror=sizeof-array-argument -Werror=sizeof-pointer-memaccess -Wl,-Bsymbolic-functions -fPIE -pie -Wl,-z,relro -Wl,-z,now -o osmo-bsc_nat bsc_filter.o bsc_mgcp_utils.o bsc_nat.o bsc_nat_utils.o bsc_nat_vty.o bsc_sccp.o bsc_ussd.o bsc_nat_ctrl.o bsc_nat_rewrite.o bsc_nat_rewrite_trie.o bsc_nat_filter.o ../../src/libmgcp/libmgcp.a ../../src/libfilter/libfilter.a ../../src/libbsc/libbsc.a ../../src/libcommon-cs/libcommon-cs.a ../../src/libtrau/libtrau.a ../../src/libcommon/libcommon.a -losmosccp -losmoxua -ltalloc -losmocore -ltalloc -losmogsm -losmocore -ltalloc -losmovty -losmocore -ltalloc -losmoctrl -losmogsm -losmocore -losmoabis -losmonetif -lcrypto -lrt [ 174s] /usr/lib/gcc/i686-linux-gnu/6/../../../i386-linux-gnu/libosmosccp.so: undefined reference to `talloc_free' [ 174s] collect2: error: ld returned 1 exit status [ 174s] Makefile:460: recipe for target 'osmo-bsc_nat' failed [ 174s] make[4]: *** [osmo-bsc_nat] Error 1 [ 174s] make[4]: Leaving directory '/usr/src/packages/BUILD/openbsc/src/osmo-bsc_nat' [ 174s] Makefile:418: recipe for target 'all-recursive' failed [ 174s] make[3]: *** [all-recursive] Error 1 [ 174s] make[3]: Leaving directory '/usr/src/packages/BUILD/openbsc/src' [ 174s] Makefile:486: recipe for target 'all-recursive' failed [ 174s] make[2]: *** [all-recursive] Error 1 [ 174s] make[2]: Leaving directory '/usr/src/packages/BUILD/openbsc' [ 174s] Makefile:404: recipe for target 'all' failed [ 174s] make[1]: *** [all] Error 2 [ 174s] make[1]: Leaving directory '/usr/src/packages/BUILD/openbsc' [ 174s] dh_auto_build: make -j1 returned exit code 2 [ 174s] debian/rules:13: recipe for target 'build' failed [ 174s] make: *** [build] Error 2 [ 174s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 174s] [ 174s] cloud128 failed "build openbsc_0.15.1.20170425.dsc" at Tue Apr 25 20:07:03 UTC 2017. [ 174s] [ 174s] ### VM INTERACTION START ### [ 177s] [ 155.936052] reboot: Power down [ 178s] ### VM INTERACTION END ### [ 178s] [ 178s] cloud128 failed "build openbsc_0.15.1.20170425.dsc" at Tue Apr 25 20:07:08 UTC 2017. [ 178s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Tue Apr 25 20:08:38 2017 From: admin at opensuse.org (OBS Notification) Date: Tue, 25 Apr 2017 20:08:38 +0000 Subject: Build failure of network:osmocom:nightly/osmo-bts in xUbuntu_17.04/x86_64 In-Reply-To: References: Message-ID: <58ffaccfc02c4_1bc39c0f7c3953c2@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-bts/xUbuntu_17.04/x86_64 Package network:osmocom:nightly/osmo-bts failed to build in xUbuntu_17.04/x86_64 Check out the package for editing: osc checkout network:osmocom:nightly osmo-bts Last lines of build log: [ 70s] /* confdefs.h */ [ 70s] #define PACKAGE_NAME "osmo-bts" [ 70s] #define PACKAGE_TARNAME "osmo-bts" [ 70s] #define PACKAGE_VERSION "0.5.0.20170425" [ 70s] #define PACKAGE_STRING "osmo-bts 0.5.0.20170425" [ 70s] #define PACKAGE_BUGREPOR[ 57.236152] serial8250: too much work for irq4 [ 70s] T "openbsc-devel at lists.openbsc.org" [ 70s] #define PACKAGE_URL "" [ 70s] #define PACKAGE "osmo-bts" [ 70s] #define VERSION "0.5.0.20170425" [ 70s] #define STDC_HEADERS 1 [ 70s] [ 70s] configure: exit 1 [ 70s] dh_auto_configure: ./configure --build=x86_64-linux-gnu --prefix=/usr --includedir=${prefix}/include --mandir=${prefix}/share/man --infodir=${prefix}/share/info --sysconfdir=/etc --localstatedir=/var --disable-silent-rules --libdir=${prefix}/lib/x86_64-linux-gnu --libexecdir=${prefix}/lib/x86_64-linux-gnu --disable-maintainer-mode --disable-dependency-tracking --enable-trx --with-openbsc=/usr/src/osmocom/openbsc/openbsc/include/ returned exit code 1 [ 70s] debian/rules:22: recipe for target 'override_dh_auto_configure' failed [ 70s] make[1]: *** [override_dh_auto_configure] Error 2 [ 70s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 70s] debian/rules:12: recipe for target 'build' failed [ 70s] make: *** [build] Error 2 [ 70s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 70s] [ 70s] lamb62 failed "build osmo-bts_0.5.0.20170425.dsc" at Tue Apr 25 20:08:28 UTC 2017. [ 70s] [ 70s] ### VM INTERACTION START ### [ 74s] [ 60.451655] reboot: Power down [ 74s] ### VM INTERACTION END ### [ 74s] [ 74s] lamb62 failed "build osmo-bts_0.5.0.20170425.dsc" at Tue Apr 25 20:08:33 UTC 2017. [ 74s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Tue Apr 25 20:08:38 2017 From: admin at opensuse.org (OBS Notification) Date: Tue, 25 Apr 2017 20:08:38 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in xUbuntu_16.04/i586 In-Reply-To: References: Message-ID: <58ffacd0c74c7_1bc39c0f7c3954e2@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/xUbuntu_16.04/i586 Package network:osmocom:nightly/osmo-stp failed to build in xUbuntu_16.04/i586 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 216s] sctp_m2ua.c:91:3: warning: #warning "Notify any other AS(P) for failover scenario" [-Wcpp] [ 216s] #warning "Notify any other AS(P) for failover scenario" [ 216s] ^ [ 216s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -c -o vty_interface.o vty_interface.c [ 217s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -c -o sctp_m3ua_client.o sctp_m3ua_client.c [ 217s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 217s] compilation terminated. [ 217s] Makefile:485: recipe for target 'sctp_m3ua_client.o' failed [ 217s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 217s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 217s] Makefile:380: recipe for target 'all-recursive' failed [ 217s] make[2]: *** [all-recursive] Error 1 [ 217s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 217s] Makefile:321: recipe for target 'all' failed [ 217s] make[1]: *** [all] Error 2 [ 217s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 217s] dh_auto_build: make -j1 returned exit code 2 [ 217s] debian/rules:23: recipe for target 'build' failed [ 217s] make: *** [build] Error 2 [ 217s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 217s] [ 217s] lamb56 failed "build cellmgr-ng_1.4.7.20170425.dsc" at Tue Apr 25 20:08:22 UTC 2017. [ 217s] [ 217s] ### VM INTERACTION START ### [ 220s] [ 203.353326] reboot: Power down [ 221s] ### VM INTERACTION END ### [ 221s] [ 221s] lamb56 failed "build cellmgr-ng_1.4.7.20170425.dsc" at Tue Apr 25 20:08:27 UTC 2017. [ 221s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Tue Apr 25 20:09:30 2017 From: admin at opensuse.org (OBS Notification) Date: Tue, 25 Apr 2017 20:09:30 +0000 Subject: Build failure of network:osmocom:nightly/osmo-bts in xUbuntu_17.04/i586 In-Reply-To: References: Message-ID: <58ffad094dcf8_1bc39c0f7c3957c1@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-bts/xUbuntu_17.04/i586 Package network:osmocom:nightly/osmo-bts failed to build in xUbuntu_17.04/i586 Check out the package for editing: osc checkout network:osmocom:nightly osmo-bts Last lines of build log: [ 85s] [ 85s] /* confdefs.h */ [ 85s] #define PACKAGE_NAME "osmo-bts" [ 85s] #define PACKAGE_TARNAME "osmo-bts" [ 85s] #define PACKAGE_VERSION "0.5.0.20170425" [ 85s] #define PACKAGE_STRING "osmo-bts 0.5.0.20170425" [ 85s] #define PACKAGE_BUGREPORT "openbsc-devel at lists.openbsc.org" [ 85s] #define PACKAGE_URL "" [ 85s] #define PACKAGE "osmo-bts" [ 85s] #define VERSION "0.5.0.20170425" [ 85s] #define STDC_HEADERS 1 [ 85s] [ 85s] configure: exit 1 [ 85s] dh_auto_configure: ./configure --build=i686-linux-gnu --prefix=/usr --includedir=${prefix}/include --mandir=${prefix}/share/man --infodir=${prefix}/share/info --sysconfdir=/etc --localstatedir=/var --disable-silent-rules --libdir=${prefix}/lib/i386-linux-gnu --libexecdir=${prefix}/lib/i386-linux-gnu --disable-maintainer-mode --disable-dependency-tracking --enable-trx --with-openbsc=/usr/src/osmocom/openbsc/openbsc/include/ returned exit code 1 [ 85s] debian/rules:22: recipe for target 'override_dh_auto_configure' failed [ 85s] make[1]: *** [override_dh_auto_configure] Error 2 [ 85s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 85s] debian/rules:12: recipe for target 'build' failed [ 85s] make: *** [build] Error 2 [ 85s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 85s] [ 85s] lamb08 failed "build osmo-bts_0.5.0.20170425.dsc" at Tue Apr 25 20:09:20 UTC 2017. [ 85s] [ 85s] ### VM INTERACTION START ### [ 88s] [ 75.593914] reboot: Power down [ 88s] ### VM INTERACTION END ### [ 88s] [ 88s] lamb08 failed "build osmo-bts_0.5.0.20170425.dsc" at Tue Apr 25 20:09:23 UTC 2017. [ 88s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Tue Apr 25 20:09:30 2017 From: admin at opensuse.org (OBS Notification) Date: Tue, 25 Apr 2017 20:09:30 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in Debian_8.0/x86_64 In-Reply-To: References: Message-ID: <58ffad0b2d01d_1bc39c0f7c3959a3@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/Debian_8.0/x86_64 Package network:osmocom:nightly/osmo-stp failed to build in Debian_8.0/x86_64 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 110s] CC vty_interface.o [ 111s] CC sctp_m3ua_client.o [ 111s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 111s] #include [ 111s] ^ [ 111s] compilation terminated. [ 111s] Makefile:475: recipe for target 'sctp_m3ua_client.o' failed [ 111s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 111s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 111s] Makefile:370: recipe for target 'all-recursive' failed [ 111s] make[2]: *** [all-recursive] Error 1 [ 111s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 111s] Makefile:310: recipe for target 'all' failed [ 111s] make[1]: *** [all] Error 2 [ 111s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 111s] dh_auto_build: make -j1 returned exit code 2 [ 111s] debian/rules:23: recipe for target 'build' failed [ 111s] make: *** [build] Error 2 [ 111s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 111s] [ 111s] build85 failed "build cellmgr-ng_1.4.7.20170425.dsc" at Tue Apr 25 20:09:16 UTC 2017. [ 111s] [ 111s] ### VM INTERACTION START ### [ 112s] Powering off. [ 112s] [ 95.585644] reboot: Power down [ 112s] ### VM INTERACTION END ### [ 112s] [ 112s] build85 failed "build cellmgr-ng_1.4.7.20170425.dsc" at Tue Apr 25 20:09:18 UTC 2017. [ 112s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Tue Apr 25 20:10:38 2017 From: admin at opensuse.org (OBS Notification) Date: Tue, 25 Apr 2017 20:10:38 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in xUbuntu_16.04/x86_64 In-Reply-To: References: Message-ID: <58ffad6623fe1_1bc99c0f7c4073fc@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/xUbuntu_16.04/x86_64 Package network:osmocom:nightly/osmo-stp failed to build in xUbuntu_16.04/x86_64 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 208s] sctp_m2ua.c:91:3: warning: #warning "Notify any other AS(P) for failover scenario" [-Wcpp] [ 208s] #warning "Notify any other AS(P) for failover scenario" [ 208s] ^ [ 208s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -c -o vty_interface.o vty_interface.c [ 209s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -c -o sctp_m3ua_client.o sctp_m3ua_client.c [ 209s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 209s] compilation terminated. [ 209s] Makefile:485: recipe for target 'sctp_m3ua_client.o' failed [ 209s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 209s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 209s] Makefile:380: recipe for target 'all-recursive' failed [ 209s] make[2]: *** [all-recursive] Error 1 [ 209s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 209s] Makefile:321: recipe for target 'all' failed [ 209s] make[1]: *** [all] Error 2 [ 209s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 209s] dh_auto_build: make -j1 returned exit code 2 [ 209s] debian/rules:23: recipe for target 'build' failed [ 209s] make: *** [build] Error 2 [ 209s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 209s] [ 209s] wildcard2 failed "build cellmgr-ng_1.4.7.20170425.dsc" at Tue Apr 25 20:10:08 UTC 2017. [ 209s] [ 209s] ### VM INTERACTION START ### [ 212s] [ 177.416807] reboot: Power down [ 224s] ### VM INTERACTION END ### [ 224s] [ 224s] wildcard2 failed "build cellmgr-ng_1.4.7.20170425.dsc" at Tue Apr 25 20:10:25 UTC 2017. [ 224s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From gerrit-no-reply at lists.osmocom.org Tue Apr 25 20:38:00 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 25 Apr 2017 20:38:00 +0000 Subject: libosmo-netif[master]: osmux: Add RTP marker bit support In-Reply-To: References: Message-ID: Patch Set 1: (2 comments) https://gerrit.osmocom.org/#/c/2407/1//COMMIT_MSG Commit Message: Line 7: osmux: Add RTP marker bit support the commit message could contain some more verbosity. Like when the marker bit is actually used in RTP (in DTX), ... https://gerrit.osmocom.org/#/c/2407/1/include/osmocom/netif/osmux.h File include/osmocom/netif/osmux.h: PS1, Line 35: r doesn't this break backwards compatibility? The FT has one less bit - ok. But the CTR field is now shifted by one bit, rather than having the rtp_m bit in place of the former FT bit? -- To view, visit https://gerrit.osmocom.org/2407 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I0315658159429603f1d80a168718b026015060e9 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Pau Espin Pedrol Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: daniel Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Tue Apr 25 20:39:12 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 25 Apr 2017 20:39:12 +0000 Subject: libosmo-netif[master]: osmux: use uint8_t everywhere for batch_factor In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2406 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I9fcc8e94b2fcd843b10cb3f8f009f2348eb3a4af Gerrit-PatchSet: 1 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Pau Espin Pedrol Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Apr 25 20:39:40 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 25 Apr 2017 20:39:40 +0000 Subject: osmo-bts[master]: Fix RTP duration adjustment not done when speech resumes in ... In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/1983 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ib51ed95a449369222c957b3acebd9ce1f66c5435 Gerrit-PatchSet: 2 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: jfdionne Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Apr 25 20:40:53 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 25 Apr 2017 20:40:53 +0000 Subject: openbsc[master]: Fix MS TO measurement representation In-Reply-To: References: Message-ID: Patch Set 3: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2391 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I7e003d23a6edb714c5f17688fd6a8edac131161d Gerrit-PatchSet: 3 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Alexander Chemeris Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Ivan Kluchnikov Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Apr 25 20:41:45 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 25 Apr 2017 20:41:45 +0000 Subject: osmo-bts[master]: Add MS TO to RSL measurements In-Reply-To: References: Message-ID: Patch Set 5: (1 comment) https://gerrit.osmocom.org/#/c/1700/5/src/common/l1sap.c File src/common/l1sap.c: Line 441: lchan->ms_t_offs = data + 63; might make sense to validate we're not overflowing here? I'm undecided if it warrants an OSMO_ASSERT. -- To view, visit https://gerrit.osmocom.org/1700 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I4dfe5c48834a083e757d5de3236a02e15a238b28 Gerrit-PatchSet: 5 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Alexander Chemeris Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Ivan Kluchnikov Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Tue Apr 25 20:41:54 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 25 Apr 2017 20:41:54 +0000 Subject: libosmo-sccp[master]: Fix debian builds In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2404 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I6e5cf393ffe81c582966ca0e9479e6deeffa9280 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Apr 25 20:42:12 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 25 Apr 2017 20:42:12 +0000 Subject: libosmo-netif[master]: Fix debian packaging In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2401 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I2781c800d39923c5541bac00f00cb128f4acf008 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Apr 25 20:42:27 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 25 Apr 2017 20:42:27 +0000 Subject: osmo-trx[master]: debian: remove obsolete dependency In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+1 -- To view, visit https://gerrit.osmocom.org/2400 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I3ea72b4123a280a846086d083c4f3189d611f8cf Gerrit-PatchSet: 1 Gerrit-Project: osmo-trx Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Apr 25 20:42:39 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 25 Apr 2017 20:42:39 +0000 Subject: osmo-hlr[master]: debian: remove obsolete dependency In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+1 -- To view, visit https://gerrit.osmocom.org/2399 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I132515cd4d89132bb59f9ee7804a5a50e8bd2775 Gerrit-PatchSet: 1 Gerrit-Project: osmo-hlr Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Apr 25 20:43:22 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 25 Apr 2017 20:43:22 +0000 Subject: openbsc[master]: deb: install openbsc.pc In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+1 not entirely sure if we should continue with installing a pkgconfig file, but well let's at least install it properly in the debian package as long as we have a .pc file -- To view, visit https://gerrit.osmocom.org/2009 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I5472a8fe74a81b98598fbdb688db778cb7d09e62 Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Apr 25 20:43:36 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 25 Apr 2017 20:43:36 +0000 Subject: openbsc[master]: Remove libs from openbsc.pc In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2019 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I4c563d775a84f41f82404e0eaba1a25fdbaac1a5 Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Apr 25 20:45:14 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 25 Apr 2017 20:45:14 +0000 Subject: libosmocore[master]: Add osmo_rand() function In-Reply-To: References: Message-ID: Patch Set 2: Code-Review-1 I think the general concencus at OsmoDevCon 2017 was that we don't want to add a gnutls dependency like this. Rather, we use the glibc function. if it doesn't exist, fall back to issuing the syscall ourselves. And if that fails too, fall back to reading from /dev/urandom. The checks above should be performed during "./configure" step while building. -- To view, visit https://gerrit.osmocom.org/1526 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I0241b814ea4c4ce1458f7ad76e31d390383c2048 Gerrit-PatchSet: 2 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Apr 25 20:46:53 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 25 Apr 2017 20:46:53 +0000 Subject: osmo-trx[master]: ssedetect: Add runtime CPU detection In-Reply-To: References: Message-ID: Patch Set 3: > Do we officially support anything besides gcc? not really, but then it is also nice to be portable. My vote would be to merge the current patch under discussion, but open a ticket as a reminder that this should be made more portable. I suppose mplayer/ffmpeg/fftw or other libs with heavily optimized algorithms also have a solution to that. -- To view, visit https://gerrit.osmocom.org/2100 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Iba74f8a6e4e921ff31e4bd9f0c7c881fe547423a Gerrit-PatchSet: 3 Gerrit-Project: osmo-trx Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Vadim Yanitskiy Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Apr 25 20:47:33 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 25 Apr 2017 20:47:33 +0000 Subject: osmo-gsm-manuals[master]: cosmetic: OsmoGSMTester: fix dir name In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2396 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I36d0c94dde5deffba04b27436ae499a42c519bec Gerrit-PatchSet: 1 Gerrit-Project: osmo-gsm-manuals Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Tue Apr 25 20:47:35 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Tue, 25 Apr 2017 20:47:35 +0000 Subject: [MERGED] osmo-gsm-manuals[master]: cosmetic: OsmoGSMTester: fix dir name In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: cosmetic: OsmoGSMTester: fix dir name ...................................................................... cosmetic: OsmoGSMTester: fix dir name All other subdirs are without dashes, but I added Osmo-GSM-Tester with dashes. Comply with the naming scheme and remove dashes. Change-Id: I36d0c94dde5deffba04b27436ae499a42c519bec --- M Makefile R OsmoGSMTester/Makefile R OsmoGSMTester/chapters/config.adoc R OsmoGSMTester/chapters/debugging.adoc R OsmoGSMTester/chapters/intro.adoc R OsmoGSMTester/chapters/test_api.adoc R OsmoGSMTester/chapters/trial.adoc R OsmoGSMTester/osmo-gsm-tester-manual-docinfo.xml R OsmoGSMTester/osmo-gsm-tester-manual.adoc 9 files changed, 4 insertions(+), 4 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/Makefile b/Makefile index 362f171..fc8ebbf 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,7 @@ cd OsmoSGSN; $(MAKE) cd OsmoNAT; $(MAKE) cd OsmoPCU; $(MAKE) - cd Osmo-GSM-Tester; $(MAKE) + cd OsmoGSMTester; $(MAKE) clean: cd OsmoBTS; $(MAKE) clean @@ -16,7 +16,7 @@ cd OsmoSGSN; $(MAKE) clean cd OsmoNAT; $(MAKE) clean cd OsmoPCU; $(MAKE) clean - cd Osmo-GSM-Tester; $(MAKE) clean + cd OsmoGSMTester; $(MAKE) clean upload: cd OsmoBTS; $(MAKE) upload @@ -26,7 +26,7 @@ cd OsmoSGSN; $(MAKE) upload cd OsmoNAT; $(MAKE) upload cd OsmoPCU; $(MAKE) upload - cd Osmo-GSM-Tester; $(MAKE) upload + cd OsmoGSMTester; $(MAKE) upload check: cd OsmoBTS; $(MAKE) check @@ -37,4 +37,4 @@ # These don't use asciidoc, so they have no 'make check' target: #cd OsmoMGCP; $(MAKE) check #cd OsmoNAT; $(MAKE) check - cd Osmo-GSM-Tester; $(MAKE) check + cd OsmoGSMTester; $(MAKE) check diff --git a/Osmo-GSM-Tester/Makefile b/OsmoGSMTester/Makefile similarity index 100% rename from Osmo-GSM-Tester/Makefile rename to OsmoGSMTester/Makefile diff --git a/Osmo-GSM-Tester/chapters/config.adoc b/OsmoGSMTester/chapters/config.adoc similarity index 100% rename from Osmo-GSM-Tester/chapters/config.adoc rename to OsmoGSMTester/chapters/config.adoc diff --git a/Osmo-GSM-Tester/chapters/debugging.adoc b/OsmoGSMTester/chapters/debugging.adoc similarity index 100% rename from Osmo-GSM-Tester/chapters/debugging.adoc rename to OsmoGSMTester/chapters/debugging.adoc diff --git a/Osmo-GSM-Tester/chapters/intro.adoc b/OsmoGSMTester/chapters/intro.adoc similarity index 100% rename from Osmo-GSM-Tester/chapters/intro.adoc rename to OsmoGSMTester/chapters/intro.adoc diff --git a/Osmo-GSM-Tester/chapters/test_api.adoc b/OsmoGSMTester/chapters/test_api.adoc similarity index 100% rename from Osmo-GSM-Tester/chapters/test_api.adoc rename to OsmoGSMTester/chapters/test_api.adoc diff --git a/Osmo-GSM-Tester/chapters/trial.adoc b/OsmoGSMTester/chapters/trial.adoc similarity index 100% rename from Osmo-GSM-Tester/chapters/trial.adoc rename to OsmoGSMTester/chapters/trial.adoc diff --git a/Osmo-GSM-Tester/osmo-gsm-tester-manual-docinfo.xml b/OsmoGSMTester/osmo-gsm-tester-manual-docinfo.xml similarity index 100% rename from Osmo-GSM-Tester/osmo-gsm-tester-manual-docinfo.xml rename to OsmoGSMTester/osmo-gsm-tester-manual-docinfo.xml diff --git a/Osmo-GSM-Tester/osmo-gsm-tester-manual.adoc b/OsmoGSMTester/osmo-gsm-tester-manual.adoc similarity index 100% rename from Osmo-GSM-Tester/osmo-gsm-tester-manual.adoc rename to OsmoGSMTester/osmo-gsm-tester-manual.adoc -- To view, visit https://gerrit.osmocom.org/2396 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I36d0c94dde5deffba04b27436ae499a42c519bec Gerrit-PatchSet: 1 Gerrit-Project: osmo-gsm-manuals Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Wed Apr 26 08:23:30 2017 From: gerrit-no-reply at lists.osmocom.org (Pau Espin Pedrol) Date: Wed, 26 Apr 2017 08:23:30 +0000 Subject: libosmo-netif[master]: osmux: Add RTP marker bit support In-Reply-To: References: Message-ID: Patch Set 1: (1 comment) https://gerrit.osmocom.org/#/c/2407/1/include/osmocom/netif/osmux.h File include/osmocom/netif/osmux.h: PS1, Line 35: r > doesn't this break backwards compatibility? The FT has one less bit - ok. Indeed, it brakes backwards compatibility. But leaving rtp_m on the 3rd bit I guess would break backwards compatibility anyways. At least if the sender sets the rtp_m bit to 1, then the receiver uses the older version it would not be able to find out which type of packet is it and it would drop it. Of course, the situation would be a better because most packets are probably not dropped. I initially did it this way to have more logical ordering of the fields, but I actually realize other ones are not in the most logical order but just trying to optimize space, so I'll move rtp_m to be next to ft. -- To view, visit https://gerrit.osmocom.org/2407 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I0315658159429603f1d80a168718b026015060e9 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Pau Espin Pedrol Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Pau Espin Pedrol Gerrit-Reviewer: daniel Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Wed Apr 26 08:25:23 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Wed, 26 Apr 2017 08:25:23 +0000 Subject: [MERGED] openbsc[master]: Fix MS TO measurement representation In-Reply-To: References: Message-ID: Max has submitted this change and it was merged. Change subject: Fix MS TO measurement representation ...................................................................... Fix MS TO measurement representation * set proper flag when saving MS Timing Offset * use gsm_subscriber's IMSI or lchan's name if bsc_subscriber is unknown * add comments with spec reference * store/display MS Timing Offset instead of raw Timing Offset field from RSL * Compute MS Timing Offset [-63; 192] from Timing Offset field [0; 255], adjust structure gsm_meas_rep with proper type to store it Change-Id: I7e003d23a6edb714c5f17688fd6a8edac131161d Related: OS#1574 --- M openbsc/include/openbsc/meas_rep.h M openbsc/src/libbsc/abis_rsl.c M openbsc/src/libbsc/bsc_vty.c M openbsc/src/libmsc/smpp_openbsc.c M openbsc/src/utils/meas_db.c M openbsc/src/utils/meas_vis.c 6 files changed, 22 insertions(+), 13 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/openbsc/include/openbsc/meas_rep.h b/openbsc/include/openbsc/meas_rep.h index 6d36f34..b0c03f0 100644 --- a/openbsc/include/openbsc/meas_rep.h +++ b/openbsc/include/openbsc/meas_rep.h @@ -39,7 +39,8 @@ struct gsm_meas_rep_unidir dl; uint8_t bs_power; - uint8_t ms_timing_offset; + /* according to 3GPP TS 48.058 ? MS Timing Offset [-63; 192] */ + int16_t ms_timing_offset; struct { int8_t pwr; /* MS power in dBm */ uint8_t ta; /* MS timing advance */ diff --git a/openbsc/src/libbsc/abis_rsl.c b/openbsc/src/libbsc/abis_rsl.c index 5ae707c..be687eb 100644 --- a/openbsc/src/libbsc/abis_rsl.c +++ b/openbsc/src/libbsc/abis_rsl.c @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include @@ -1369,8 +1370,14 @@ int i; const char *name = ""; - if (lchan && lchan->conn) - name = bsc_subscr_name(lchan->conn->bsub); + if (lchan && lchan->conn) { + if (lchan->conn->bsub) + name = bsc_subscr_name(lchan->conn->bsub); + else if (lchan->conn->subscr) + name = lchan->conn->subscr->imsi; + else + name = lchan->name; + } DEBUGP(DMEAS, "[%s] MEASUREMENT RESULT NR=%d ", name, mr->nr); @@ -1379,6 +1386,7 @@ print_meas_rep_uni(&mr->ul, "ul"); DEBUGPC(DMEAS, "BS_POWER=%d ", mr->bs_power); + if (mr->flags & MEAS_REP_F_MS_TO) DEBUGPC(DMEAS, "MS_TO=%d ", mr->ms_timing_offset); @@ -1452,9 +1460,11 @@ mr->bs_power = *TLVP_VAL(&tp, RSL_IE_BS_POWER); /* Optional Parts */ - if (TLVP_PRESENT(&tp, RSL_IE_MS_TIMING_OFFSET)) - mr->ms_timing_offset = - *TLVP_VAL(&tp, RSL_IE_MS_TIMING_OFFSET); + if (TLVP_PRESENT(&tp, RSL_IE_MS_TIMING_OFFSET)) { + /* According to 3GPP TS 48.058 ? MS Timing Offset = Timing Offset field - 63 */ + mr->ms_timing_offset = *TLVP_VAL(&tp, RSL_IE_MS_TIMING_OFFSET) - 63; + mr->flags |= MEAS_REP_F_MS_TO; + } if (TLVP_PRESENT(&tp, RSL_IE_L1_INFO)) { struct e1inp_sign_link *sign_link = msg->dst; diff --git a/openbsc/src/libbsc/bsc_vty.c b/openbsc/src/libbsc/bsc_vty.c index c1882fc..3c70580 100644 --- a/openbsc/src/libbsc/bsc_vty.c +++ b/openbsc/src/libbsc/bsc_vty.c @@ -1062,8 +1062,7 @@ mr->flags & MEAS_REP_F_DL_VALID ? " " : "DLinval ", VTY_NEWLINE); if (mr->flags & MEAS_REP_F_MS_TO) - vty_out(vty, "%s MS Timing Offset: %u%s", prefix, - mr->ms_timing_offset, VTY_NEWLINE); + vty_out(vty, "%s MS Timing Offset: %d%s", prefix, mr->ms_timing_offset, VTY_NEWLINE); if (mr->flags & MEAS_REP_F_MS_L1) vty_out(vty, "%s L1 MS Power: %u dBm, Timing Advance: %u%s", prefix, mr->ms_l1.pwr, mr->ms_l1.ta, VTY_NEWLINE); diff --git a/openbsc/src/libmsc/smpp_openbsc.c b/openbsc/src/libmsc/smpp_openbsc.c index 2703a24..1671a62 100644 --- a/openbsc/src/libmsc/smpp_openbsc.c +++ b/openbsc/src/libmsc/smpp_openbsc.c @@ -437,8 +437,8 @@ append_tlv_u8(req_tlv, TLVID_osmo_ta, mr->ms_l1.ta); ms_dbm = ms_pwr_dbm(lchan->ts->trx->bts->band, mr->ms_l1.pwr); append_tlv_u8(req_tlv, TLVID_osmo_ms_l1_txpwr, ms_dbm); - } else if (mr->flags & MEAS_REP_F_MS_TO) - append_tlv_u8(req_tlv, TLVID_osmo_ta, mr->ms_timing_offset); + } else if (mr->flags & MEAS_REP_F_MS_TO) /* Save Timing Offset field = MS Timing Offset + 63 */ + append_tlv_u8(req_tlv, TLVID_osmo_ta, mr->ms_timing_offset + 63); append_tlv_u16(req_tlv, TLVID_osmo_rxlev_ul, rxlev2dbm(ul_meas->full.rx_lev)); diff --git a/openbsc/src/utils/meas_db.c b/openbsc/src/utils/meas_db.c index a3b694e..d81efca 100644 --- a/openbsc/src/utils/meas_db.c +++ b/openbsc/src/utils/meas_db.c @@ -114,8 +114,7 @@ SCK_OK(st->db, sqlite3_bind_int(st->stmt_ins_mr, 6, mr->bs_power)); if (mr->flags & MEAS_REP_F_MS_TO) - SCK_OK(st->db, sqlite3_bind_int(st->stmt_ins_mr, 7, - mr->ms_timing_offset)); + SCK_OK(st->db, sqlite3_bind_int(st->stmt_ins_mr, 7, mr->ms_timing_offset)); else SCK_OK(st->db, sqlite3_bind_null(st->stmt_ins_mr, 7)); diff --git a/openbsc/src/utils/meas_vis.c b/openbsc/src/utils/meas_vis.c index 316d203..77194de 100644 --- a/openbsc/src/utils/meas_vis.c +++ b/openbsc/src/utils/meas_vis.c @@ -200,7 +200,7 @@ COLS-40, rxlev2dbm(lq->rx_lev), -110, -47, 1, 2, FALSE, FALSE); //IsVisibleObj(ms->ul.cdk) = FALSE; - snprintf(msu->label, sizeof(msu->label), "%1d %3d %2u %2u %4u", + snprintf(msu->label, sizeof(msu->label), "%1d %3d %2u %2d %4u", qual_col, lq->rx_qual, qual_col, pwr, ms->mr.ms_l1.ta, ms->mr.ms_timing_offset, now - msu->last_update); -- To view, visit https://gerrit.osmocom.org/2391 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I7e003d23a6edb714c5f17688fd6a8edac131161d Gerrit-PatchSet: 4 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Alexander Chemeris Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Ivan Kluchnikov Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max From gerrit-no-reply at lists.osmocom.org Wed Apr 26 08:25:36 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Wed, 26 Apr 2017 08:25:36 +0000 Subject: [MERGED] libosmo-netif[master]: Fix debian packaging In-Reply-To: References: Message-ID: Max has submitted this change and it was merged. Change subject: Fix debian packaging ...................................................................... Fix debian packaging * add separate -doc packages * fix dh_install override * add conflict with previous version Change-Id: I2781c800d39923c5541bac00f00cb128f4acf008 --- M debian/control A debian/libosmo-netif-doc.doc-base A debian/libosmo-netif-doc.install M debian/rules 4 files changed, 23 insertions(+), 1 deletion(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/debian/control b/debian/control index f4c94bb..bf403e5 100644 --- a/debian/control +++ b/debian/control @@ -24,6 +24,7 @@ Section: libs Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends} +Conflicts: libosmonetif2 Multi-Arch: same Description: Common/shared code regarding network interface for OpenBSC The libosmo-netif library is one of the libraries needed by the @@ -47,6 +48,19 @@ This package contains the development files needed for developing with the libosmo-netif library. +Package: libosmo-netif-doc +Architecture: all +Section: doc +Depends: ${misc:Depends}, + libosmonetif3, + libjs-jquery +Description: Documentation for the Osmo network interface library + The libosmo-netif library is one of the libraries needed by the + OpenBSC GSM infrastructure software. This library in particular implements + the shared code for network interfaces. + . + This package contains the documentation for the libosmo-netif library. + Package: libosmo-netif-dbg Section: debug Architecture: any diff --git a/debian/libosmo-netif-doc.doc-base b/debian/libosmo-netif-doc.doc-base new file mode 100644 index 0000000..ce8aa50 --- /dev/null +++ b/debian/libosmo-netif-doc.doc-base @@ -0,0 +1,7 @@ +Document: libosmo-netif-doc +Title: Documentation for the libosmo-netif library +Section: Programming + +Format: HTML +Index: /usr/share/doc/libosmo-netif/html/index.html +Files: /usr/share/doc/libosmo-netif/html/*.html diff --git a/debian/libosmo-netif-doc.install b/debian/libosmo-netif-doc.install new file mode 100644 index 0000000..d199687 --- /dev/null +++ b/debian/libosmo-netif-doc.install @@ -0,0 +1 @@ +usr/share/doc/libosmo-netif/* diff --git a/debian/rules b/debian/rules index f398831..ce5c618 100755 --- a/debian/rules +++ b/debian/rules @@ -20,8 +20,8 @@ dh_autoreconf override_dh_install: - dh_install sed -i "/dependency_libs/ s/'.*'/''/" `find . -name '*.la'` + dh_install override_dh_clean: dh_clean -- To view, visit https://gerrit.osmocom.org/2401 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I2781c800d39923c5541bac00f00cb128f4acf008 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max From gerrit-no-reply at lists.osmocom.org Wed Apr 26 08:25:48 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Wed, 26 Apr 2017 08:25:48 +0000 Subject: [MERGED] libosmo-sccp[master]: Fix debian builds In-Reply-To: References: Message-ID: Max has submitted this change and it was merged. Change subject: Fix debian builds ...................................................................... Fix debian builds Add missing libosmogsm dependency. Change-Id: I6e5cf393ffe81c582966ca0e9479e6deeffa9280 Fixes: OS#2182 --- M configure.ac M src/Makefile.am M src/ipa.c 3 files changed, 4 insertions(+), 2 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/configure.ac b/configure.ac index 82c7ee8..3a05d54 100644 --- a/configure.ac +++ b/configure.ac @@ -29,6 +29,7 @@ PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 0.3.0) PKG_CHECK_MODULES(LIBOSMOVTY, libosmovty >= 0.3.0) PKG_CHECK_MODULES(LIBOSMONETIF, libosmo-netif >= 0.0.6) +PKG_CHECK_MODULES(LIBOSMOGSM, libosmogsm >= 0.9.5) old_LIBS=$LIBS AC_SEARCH_LIBS([sctp_send], [sctp], [ diff --git a/src/Makefile.am b/src/Makefile.am index 15f17fe..5f0b3f9 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,5 +1,5 @@ AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir) -AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMONETIF_CFLAGS) +AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMONETIF_CFLAGS) noinst_HEADERS = sccp_internal.h xua_asp_fsm.h xua_as_fsm.h xua_internal.h @@ -32,4 +32,4 @@ osmo_ss7.c osmo_ss7_hmrt.c xua_asp_fsm.c xua_as_fsm.c \ osmo_ss7_vty.c sccp_vty.c ipa.c libosmo_sigtran_la_LDFLAGS = -version-info $(LIBVERSION) -no-undefined -export-symbols-regex '^osmo_' -libosmo_sigtran_la_LIBADD = $(LIBOSMOCORE_LIBS) $(LIBOSMONETIF_LIBS) $(LIBSCTP_LIBS) +libosmo_sigtran_la_LIBADD = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMONETIF_LIBS) $(LIBSCTP_LIBS) diff --git a/src/ipa.c b/src/ipa.c index df3dbd1..a7060db 100644 --- a/src/ipa.c +++ b/src/ipa.c @@ -29,6 +29,7 @@ #include #include #include +#include #include //#include -- To view, visit https://gerrit.osmocom.org/2404 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I6e5cf393ffe81c582966ca0e9479e6deeffa9280 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max From gerrit-no-reply at lists.osmocom.org Wed Apr 26 08:47:47 2017 From: gerrit-no-reply at lists.osmocom.org (Holger Freyther) Date: Wed, 26 Apr 2017 08:47:47 +0000 Subject: libosmocore[master]: Add osmo_rand() function In-Reply-To: References: Message-ID: Patch Set 2: Sorry to not have been in the room at that time and I thought someone else would raise these points. * OpenSSL/GNUtls take random bits from the kernel and then use something like a KDF to generate new values and only re-seeds if needed (e.g. this explains the OpenSSL/android zygote security issue that existed as after the fork two apps would generate the same random numbers). Still it leaves more rand in the kernel, avoids syscalls, apparently is still secure. * /dev/urandom can block. Be prepared for that. Specially when taking more random out of the kernel. -- To view, visit https://gerrit.osmocom.org/1526 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I0241b814ea4c4ce1458f7ad76e31d390383c2048 Gerrit-PatchSet: 2 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Wed Apr 26 08:53:31 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Wed, 26 Apr 2017 08:53:31 +0000 Subject: libosmocore[master]: Add osmo_rand() function In-Reply-To: References: Message-ID: Patch Set 2: Sure, that's why getrandom has GRND_NONBLOCK flag and return value indicating actual number of random bits returned. The consensus (as I recall it) was to use osmo_rand() for "small" things like tmsi (with fallback to currently used insecure rand()). The "big" things are only necessary for crypto-related primitives which can use smth like gnutls directly. This got to be thoroughly documented of course. -- To view, visit https://gerrit.osmocom.org/1526 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I0241b814ea4c4ce1458f7ad76e31d390383c2048 Gerrit-PatchSet: 2 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Wed Apr 26 09:20:20 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Wed, 26 Apr 2017 09:20:20 +0000 Subject: osmo-bts[master]: bts: revert trx shutdown order In-Reply-To: References: Message-ID: Patch Set 6: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/1977 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I18485de586b402610f9e98053d69e92bc9b18dc2 Gerrit-PatchSet: 6 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Wed Apr 26 09:20:30 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Wed, 26 Apr 2017 09:20:30 +0000 Subject: osmo-bts[master]: octphy: activate CBCH after all physical channels are activated In-Reply-To: References: Message-ID: Patch Set 4: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2314 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ie307bf9f370a346686e3bd8c8a8483953a1bc279 Gerrit-PatchSet: 4 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Wed Apr 26 09:20:42 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Wed, 26 Apr 2017 09:20:42 +0000 Subject: osmo-bts[master]: measurement/cosmetic: Fixup source code comment In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2387 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I3d3488c97d0bffa7d449d3675afcc75b2a6a2703 Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Wed Apr 26 09:20:48 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Wed, 26 Apr 2017 09:20:48 +0000 Subject: osmo-bts[master]: measurement/cosmetic: Fixup source code comment In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2388 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ic6e4037f965772e6b851c67662d5e7bf64cc04eb Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Wed Apr 26 09:21:09 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Wed, 26 Apr 2017 09:21:09 +0000 Subject: osmo-bts[master]: octphy: ensure that 11 bit rach flag is not set In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2390 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ifa165c56e54d272caafa45d1bf0e177848fcdfbd Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Wed Apr 26 09:21:24 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Wed, 26 Apr 2017 09:21:24 +0000 Subject: osmo-bts[master]: octphy: align frame number for new firmware versions In-Reply-To: References: Message-ID: Patch Set 6: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/1965 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ib93d5fb3b34ff92f10021a0e9ce9c8aa3044b7ff Gerrit-PatchSet: 6 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Wed Apr 26 09:22:19 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Wed, 26 Apr 2017 09:22:19 +0000 Subject: [MERGED] libosmocore[master]: ctrl: Allow installation of additional node lookup helpers In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: ctrl: Allow installation of additional node lookup helpers ...................................................................... ctrl: Allow installation of additional node lookup helpers The existing code assumes that the main application knows about all control command nodes and can thus present one lookup function. As libraries are getting their own control interface handling, this is too restrictive, and we need a way how library code can dynamically register more node lookup helpers. We can now do this by means of a ctrl_lookup_register() function. Change-Id: Ib69908d1c57f5bb721d5496e3b4a5258fca450e3 --- M include/osmocom/ctrl/control_if.h M src/ctrl/control_if.c 2 files changed, 43 insertions(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/include/osmocom/ctrl/control_if.h b/include/osmocom/ctrl/control_if.h index f2af1db..a740a96 100644 --- a/include/osmocom/ctrl/control_if.h +++ b/include/osmocom/ctrl/control_if.h @@ -29,3 +29,5 @@ ctrl_cmd_lookup lookup); struct ctrl_connection *osmo_ctrl_conn_alloc(void *ctx, void *data); int ctrl_cmd_handle(struct ctrl_handle *ctrl, struct ctrl_cmd *cmd, void *data); + +int ctrl_lookup_register(ctrl_cmd_lookup lookup); diff --git a/src/ctrl/control_if.c b/src/ctrl/control_if.c index d2eb3e9..f1cc7ab 100644 --- a/src/ctrl/control_if.c +++ b/src/ctrl/control_if.c @@ -61,6 +61,13 @@ vector ctrl_node_vec; +/* global list of control interface lookup helpers */ +struct lookup_helper { + struct llist_head list; + ctrl_cmd_lookup lookup; +}; +static LLIST_HEAD(ctrl_lookup_helpers); + int ctrl_parse_get_num(vector vline, int i, long *num) { char *token, *tmp; @@ -225,12 +232,21 @@ } for (i=0;ilookup) rc = ctrl->lookup(data, vline, &node, &cmd->node, &i); else rc = 0; + + if (!rc) { + llist_for_each_entry(lh, &ctrl_lookup_helpers, list) { + rc = lh->lookup(data, vline, &node, &cmd->node, &i); + if (rc) + break; + } + } if (rc == 1) { /* do nothing */ @@ -733,3 +749,28 @@ talloc_free(ctrl); return NULL; } + +/*! \brief Install a lookup helper function for control nodes + * This function is used by e.g. library code to install lookup helpers + * for additional nodes in the control interface. + * \param[in] lookup The lookup helper function + * \retuns - on success; negative on error. + */ +int ctrl_lookup_register(ctrl_cmd_lookup lookup) +{ + struct lookup_helper *lh; + + /* avoid double registration */ + llist_for_each_entry(lh, &ctrl_lookup_helpers, list) { + if (lh->lookup == lookup) + return -EEXIST; + } + + lh = talloc_zero(NULL, struct lookup_helper); + if (!lh) + return -ENOMEM; + + lh->lookup = lookup; + llist_add_tail(&lh->list, &ctrl_lookup_helpers); + return 0; +} -- To view, visit https://gerrit.osmocom.org/2374 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ib69908d1c57f5bb721d5496e3b4a5258fca450e3 Gerrit-PatchSet: 2 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Wed Apr 26 09:23:08 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Wed, 26 Apr 2017 09:23:08 +0000 Subject: libosmocore[master]: control_if: Add control interface commands for FSMs In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2378 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I0f80340ee9c61c88962fdd6764a6098a844d0d1e Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Wed Apr 26 09:23:47 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Wed, 26 Apr 2017 09:23:47 +0000 Subject: osmo-hlr[master]: add config example (mostly empty) In-Reply-To: References: Message-ID: Patch Set 4: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2012 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I38ef124e9f28bdd744bafd20fa8c310511c0b8ad Gerrit-PatchSet: 4 Gerrit-Project: osmo-hlr Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Wed Apr 26 09:24:21 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Wed, 26 Apr 2017 09:24:21 +0000 Subject: [MERGED] osmo-hlr[master]: add config example (mostly empty) In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: add config example (mostly empty) ...................................................................... add config example (mostly empty) So far only the vty and ctrl bind configs exists. Change-Id: I38ef124e9f28bdd744bafd20fa8c310511c0b8ad --- A doc/examples/osmo-hlr.cfg 1 file changed, 16 insertions(+), 0 deletions(-) Approvals: Max: Looks good to me, but someone else must approve Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/doc/examples/osmo-hlr.cfg b/doc/examples/osmo-hlr.cfg new file mode 100644 index 0000000..2b49958 --- /dev/null +++ b/doc/examples/osmo-hlr.cfg @@ -0,0 +1,16 @@ +! +! OsmoHLR example configuration +! +log stderr + logging filter all 1 + logging color 1 + logging print category 1 + logging timestamp 1 + logging print extended-timestamp 1 + logging level all debug + logging level linp error +! +line vty + bind 127.0.0.1 +ctrl + bind 127.0.0.1 -- To view, visit https://gerrit.osmocom.org/2012 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I38ef124e9f28bdd744bafd20fa8c310511c0b8ad Gerrit-PatchSet: 4 Gerrit-Project: osmo-hlr Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Wed Apr 26 09:25:03 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Wed, 26 Apr 2017 09:25:03 +0000 Subject: osmo-trx[master]: radioInterface: Remove UmTRX 'diversity' option In-Reply-To: References: Message-ID: Patch Set 4: Code-Review+1 -- To view, visit https://gerrit.osmocom.org/2186 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I46752ccf5dbcffbec806081dec03e69a0fbdcdb7 Gerrit-PatchSet: 4 Gerrit-Project: osmo-trx Gerrit-Branch: master Gerrit-Owner: Tom Tsou Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Wed Apr 26 09:25:13 2017 From: gerrit-no-reply at lists.osmocom.org (Pau Espin Pedrol) Date: Wed, 26 Apr 2017 09:25:13 +0000 Subject: [PATCH] libosmo-netif[master]: osmux: Add RTP marker bit support In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2407 to look at the new patch set (#2). osmux: Add RTP marker bit support According to RFC4867 (RTP payload format for AMR): "The RTP header marker bit (M) SHALL be set to 1 if the first frameblock carried in the packet contains a speech frame which is the first in a talkspurt. For all other packets the marker bit SHALL be set to zero (M=0)." This information bit provides a way for the receiver to better synchronize the delay with ther sender. This is specially useful if AMR DTX features are supported and enabled on the sender. Change-Id: I0315658159429603f1d80a168718b026015060e9 --- M include/osmocom/netif/osmux.h M src/osmux.c M tests/osmux/osmux_test.c 3 files changed, 81 insertions(+), 7 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-netif refs/changes/07/2407/2 diff --git a/include/osmocom/netif/osmux.h b/include/osmocom/netif/osmux.h index 1d93aa0..5283059 100644 --- a/include/osmocom/netif/osmux.h +++ b/include/osmocom/netif/osmux.h @@ -13,7 +13,8 @@ /* OSmux header: * - * ft (3 bits): 0=signalling, 1=voice, 2=dummy + * rtp_m (1 bit): RTP M field (RFC3550, RFC4867) + * ft (2 bits): 0=signalling, 1=voice, 2=dummy * ctr (3 bits): Number of batched AMR payloads (starting 0) * amr_f (1 bit): AMR F field (RFC3267) * amr_q (1 bit): AMR Q field (RFC3267) @@ -29,7 +30,8 @@ struct osmux_hdr { #if OSMO_IS_BIG_ENDIAN - uint8_t ft:3, + uint8_t rtp_m:1, + ft:2, ctr:3, amr_f:1, amr_q:1; @@ -37,7 +39,8 @@ uint8_t amr_q:1, amr_f:1, ctr:3, - ft:3; + ft:2, + rtp_m:1; #endif uint8_t seq; #define OSMUX_CID_MAX 255 /* determined by circuit_id */ diff --git a/src/osmux.c b/src/osmux.c index 1dcd04f..4d12427 100644 --- a/src/osmux.c +++ b/src/osmux.c @@ -105,8 +105,8 @@ } static struct msgb * -osmux_rebuild_rtp(struct osmux_out_handle *h, - struct osmux_hdr *osmuxh, void *payload, int payload_len) +osmux_rebuild_rtp(struct osmux_out_handle *h, struct osmux_hdr *osmuxh, + void *payload, int payload_len, bool first_pkt) { struct msgb *out_msg; struct rtp_hdr *rtph; @@ -129,6 +129,8 @@ rtph->timestamp = htonl(h->rtp_timestamp); rtph->sequence = htons(h->rtp_seq); rtph->ssrc = htonl(h->rtp_ssrc); + /* rtp packet with the marker bit is always warranted to be the first one */ + rtph->marker = first_pkt && osmuxh->rtp_m; msgb_put(out_msg, sizeof(struct rtp_hdr)); @@ -166,7 +168,7 @@ msg = osmux_rebuild_rtp(h, osmuxh, osmux_get_payload(osmuxh) + i * osmo_amr_bytes(osmuxh->amr_ft), - osmo_amr_bytes(osmuxh->amr_ft)); + osmo_amr_bytes(osmuxh->amr_ft), !i); if (msg == NULL) continue; @@ -264,6 +266,7 @@ osmuxh = (struct osmux_hdr *)state->out_msg->tail; osmuxh->ft = OSMUX_FT_VOICE_AMR; osmuxh->ctr = 0; + osmuxh->rtp_m = osmuxh->rtp_m || state->rtph->marker; osmuxh->amr_f = state->amrh->f; osmuxh->amr_q= state->amrh->q; osmuxh->seq = batch->seq++; @@ -593,6 +596,13 @@ if (bytes > batch->remaining_bytes) return 1; + /* Init of talkspurt (RTP M marker bit) needs to be in the first AMR slot + * of the OSMUX packet, enforce sending previous batch if required: + */ + if (rtph->marker && circuit->nmsgs != 0) + return 1; + + /* Extra validation: check if this message already exists, should not * happen but make sure we don't propagate duplicated messages. */ diff --git a/tests/osmux/osmux_test.c b/tests/osmux/osmux_test.c index 2f5a6cd..8b0a56c 100644 --- a/tests/osmux/osmux_test.c +++ b/tests/osmux/osmux_test.c @@ -55,6 +55,7 @@ }; static int rtp_pkts; +static int mark_pkts; #if OSMUX_TEST_USE_TIMING static struct timeval last; #endif @@ -62,6 +63,7 @@ static void tx_cb(struct msgb *msg, void *data) { char buf[4096]; + struct rtp_hdr *rtph = (struct rtp_hdr *)msg->data; #if OSMUX_TEST_USE_TIMING struct timeval now, diff; @@ -87,6 +89,8 @@ exit(EXIT_FAILURE); } + if (rtph->marker) + mark_pkts--; rtp_pkts--; msgb_free(msg); } @@ -122,6 +126,48 @@ { printf("FAIL: test did not run successfully\n"); exit(EXIT_FAILURE); +} + +static void osmux_test_marker(int ccid) { + struct msgb *msg; + struct rtp_hdr *rtph = (struct rtp_hdr *)rtp_pkt; + struct rtp_hdr *cpy_rtph; + uint16_t seq; + int i, j; + + for (i = 0; i < 64; i++) { + + seq = ntohs(rtph->sequence); + seq++; + rtph->sequence = htons(seq); + + for (j=0; j<4; j++) { + msg = msgb_alloc(1500, "test"); + if (!msg) + exit(EXIT_FAILURE); + + memcpy(msg->data, rtp_pkt, sizeof(rtp_pkt)); + cpy_rtph = (struct rtp_hdr *) msgb_put(msg, sizeof(rtp_pkt)); + + if ((i+j) % 7 == 0) { + cpy_rtph->marker = 1; + mark_pkts++; + } + + rtp_pkts++; + while (osmux_xfrm_input(&h_input, msg, j + ccid) > 0) { + osmux_xfrm_input_deliver(&h_input); + } + } + } + + while (rtp_pkts) + osmo_select_main(0); + + if (mark_pkts) { + fprintf(stdout, "RTP M bit (marker) mismatch! %d\n", mark_pkts); + exit(EXIT_FAILURE); + } } static void osmux_test_loop(int ccid) @@ -177,6 +223,11 @@ k = 0; } } + + if (mark_pkts) { + fprintf(stdout, "RTP M bit (marker) mismatch! %d\n", mark_pkts); + exit(EXIT_FAILURE); + } } int main(void) @@ -192,12 +243,22 @@ osmo_init_logging(&osmux_test_log_info); log_set_log_level(osmo_stderr_target, LOGL_DEBUG); - osmux_xfrm_input_init(&h_input); osmux_xfrm_output_init(&h_output, 0x7000000); /* If the test takes longer than 10 seconds, abort it */ alarm(10); + /* Check if marker bit features work correctly */ + osmux_xfrm_input_init(&h_input); + for (i = 0; i < 4; i++) + osmux_xfrm_input_open_circuit(&h_input, i, 0); + osmux_test_marker(0); + for (i = 0; i < 4; i++) + osmux_xfrm_input_close_circuit(&h_input, i); + osmux_xfrm_input_fini(&h_input); + + osmux_xfrm_input_init(&h_input); + for (i = 0; i < 2; i++) osmux_xfrm_input_open_circuit(&h_input, i, 0); -- To view, visit https://gerrit.osmocom.org/2407 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I0315658159429603f1d80a168718b026015060e9 Gerrit-PatchSet: 2 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Pau Espin Pedrol Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Pau Espin Pedrol Gerrit-Reviewer: daniel From gerrit-no-reply at lists.osmocom.org Wed Apr 26 09:26:44 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Wed, 26 Apr 2017 09:26:44 +0000 Subject: libosmo-netif[master]: osmux: Fix delay between RTP packets In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+1 -- To view, visit https://gerrit.osmocom.org/2397 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I36dc69f9caf591dd1b578bc914a2ce426c7f2813 Gerrit-PatchSet: 2 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Pau Espin Pedrol Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: daniel Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Wed Apr 26 09:27:24 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Wed, 26 Apr 2017 09:27:24 +0000 Subject: libosmo-netif[master]: osmux: Fix delay between RTP packets In-Reply-To: References: Message-ID: Patch Set 2: (1 comment) https://gerrit.osmocom.org/#/c/2397/2//COMMIT_MSG Commit Message: Line 7: osmux: Fix delay between RTP packets might make sense to write a bit about what kind of implications this wrong #define in the code has, and how it changes with your fix. -- To view, visit https://gerrit.osmocom.org/2397 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I36dc69f9caf591dd1b578bc914a2ce426c7f2813 Gerrit-PatchSet: 2 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Pau Espin Pedrol Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: daniel Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Wed Apr 26 09:29:02 2017 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Wed, 26 Apr 2017 09:29:02 +0000 Subject: [PATCH] libosmocore[master]: l1sap: Add frame-number to measurement indication struct Message-ID: Review at https://gerrit.osmocom.org/2408 l1sap: Add frame-number to measurement indication struct The distribution of the channel measurement calculations over multiple timeslots (continous calculation) requires to keep track of the frame number in struct info_meas_ind_param Change-Id: I8c783b4a92ae2c3cc5d17936a146eb49d47eac37 --- M include/osmocom/gsm/l1sap.h 1 file changed, 1 insertion(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/08/2408/1 diff --git a/include/osmocom/gsm/l1sap.h b/include/osmocom/gsm/l1sap.h index e199efe..183edbc 100644 --- a/include/osmocom/gsm/l1sap.h +++ b/include/osmocom/gsm/l1sap.h @@ -97,6 +97,7 @@ /*! \brief for MEAS MPH-INFO.ind */ struct info_meas_ind_param { uint8_t chan_nr; /*!< \brief Channel Number (Like RSL) */ + uint32_t fn; /*!< \brief GSM Frame Number */ uint16_t ber10k; /*!< \brief BER in units of 0.01% */ int16_t ta_offs_qbits; /*!< \brief timing advance offset (in qbits) */ int16_t c_i_cb; /*!< \brief C/I ratio in 0.1 dB */ -- To view, visit https://gerrit.osmocom.org/2408 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I8c783b4a92ae2c3cc5d17936a146eb49d47eac37 Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: dexter From gerrit-no-reply at lists.osmocom.org Wed Apr 26 09:33:06 2017 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Wed, 26 Apr 2017 09:33:06 +0000 Subject: [PATCH] openbsc[master]: lchan: add ms_timing_offset member to struct gsm_lchan Message-ID: Review at https://gerrit.osmocom.org/2409 lchan: add ms_timing_offset member to struct gsm_lchan The distribution of the channel measurement calculations over multiple timeslots (continous calculation) requires to keep track of the ms timing offset in struct gsm_lchan Change-Id: Ifc4cff7efa4ba0a4b94448767143dd18b6db9325 --- M openbsc/include/openbsc/gsm_data_shared.h 1 file changed, 1 insertion(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/09/2409/1 diff --git a/openbsc/include/openbsc/gsm_data_shared.h b/openbsc/include/openbsc/gsm_data_shared.h index 242889a..fc537ad 100644 --- a/openbsc/include/openbsc/gsm_data_shared.h +++ b/openbsc/include/openbsc/gsm_data_shared.h @@ -308,6 +308,7 @@ /* last L1 header from the MS */ uint8_t l1_info[2]; struct gsm_meas_rep_unidir ul_res; + uint8_t ms_timing_offset; /*Range -63 to 192*/ } meas; struct { struct amr_multirate_conf amr_mr; -- To view, visit https://gerrit.osmocom.org/2409 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ifc4cff7efa4ba0a4b94448767143dd18b6db9325 Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: dexter From gerrit-no-reply at lists.osmocom.org Wed Apr 26 09:38:38 2017 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Wed, 26 Apr 2017 09:38:38 +0000 Subject: [PATCH] osmo-bts[master]: measurement: fix measurement reporting period Message-ID: Review at https://gerrit.osmocom.org/2410 measurement: fix measurement reporting period The measurement reporting for the MS on a SDCCH lacks some of the periods, defined in 3GPP TS 45.008, secton 8.4.2. This adds the missing conditions by adding complete lookup tables. Change-Id: I23fba50f48415314da40cf5bf86fce2ed3e66af6 --- M src/common/measurement.c 1 file changed, 35 insertions(+), 3 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/10/2410/1 diff --git a/src/common/measurement.c b/src/common/measurement.c index 9987d73..472f8f9 100644 --- a/src/common/measurement.c +++ b/src/common/measurement.c @@ -55,11 +55,43 @@ [7] = 90, }; +/* Measurment reporting period for SDCCH8 and SDCCH4 chan + * As per in 3GPP TS 45.008, section 8.4.2. + * + * Logical Chan TDMA frame number + * (FN) modulo 102 + * + * SDCCH/8 12 to 11 + * SDCCH/4 37 to 36 + */ + +/* Added interleve offset to Meas period end Fn which + * would reduce the Meas Res msg load at Abis */ + +static const uint8_t sdcch8_meas_rep_fn102[] = { + [0] = 11 + 7, + [1] = 11 + 11, + [2] = 11 + 15, + [3] = 11 + 19, + [4] = 11 + 23, + [5] = 11 + 27, + [6] = 11 + 31, + [7] = 11 + 35 +}; + +static const uint8_t sdcch4_meas_rep_fn102[] = { + [0] = 36 + 4, + [1] = 36 + 8, + [2] = 36 + 14, + [3] = 36 + 18 +}; + + /* determine if a measurement period ends at the given frame number */ static int is_meas_complete(enum gsm_phys_chan_config pchan, unsigned int ts, unsigned int subch, uint32_t fn) { - unsigned int fn_mod; + unsigned int fn_mod = -1; const uint8_t *tbl; int rc = 0; @@ -86,13 +118,13 @@ case GSM_PCHAN_SDCCH8_SACCH8C: case GSM_PCHAN_SDCCH8_SACCH8C_CBCH: fn_mod = fn % 102; - if (fn_mod == 11) + if (sdcch8_meas_rep_fn102[subch] == fn_mod) rc = 1; break; case GSM_PCHAN_CCCH_SDCCH4: case GSM_PCHAN_CCCH_SDCCH4_CBCH: fn_mod = fn % 102; - if (fn_mod == 36) + if (sdcch4_meas_rep_fn102[subch] == fn_mod) rc = 1; break; default: -- To view, visit https://gerrit.osmocom.org/2410 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I23fba50f48415314da40cf5bf86fce2ed3e66af6 Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: dexter From gerrit-no-reply at lists.osmocom.org Wed Apr 26 09:38:39 2017 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Wed, 26 Apr 2017 09:38:39 +0000 Subject: [PATCH] osmo-bts[master]: measurement: make lchan_meas_check_compute() available to l1... Message-ID: Review at https://gerrit.osmocom.org/2411 measurement: make lchan_meas_check_compute() available to l1sap.c lchan_meas_check_compute() is a static function measurement.c. In order to distribute the measurement result calculation events, we need to be able to call lchan_meas_check_compute() from l1sap.c Change-Id: Ideffe896613e0feda443bc13dac59dcdbbc605aa --- M include/osmo-bts/measurement.h M src/common/measurement.c 2 files changed, 3 insertions(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/11/2411/1 diff --git a/include/osmo-bts/measurement.h b/include/osmo-bts/measurement.h index 2037ff6..2efe40f 100644 --- a/include/osmo-bts/measurement.h +++ b/include/osmo-bts/measurement.h @@ -5,4 +5,6 @@ int trx_meas_check_compute(struct gsm_bts_trx *trx, uint32_t fn); +int lchan_meas_check_compute(struct gsm_lchan *lchan, uint32_t fn); + #endif diff --git a/src/common/measurement.c b/src/common/measurement.c index 472f8f9..79f6ae4 100644 --- a/src/common/measurement.c +++ b/src/common/measurement.c @@ -196,7 +196,7 @@ return 7; } -static int lchan_meas_check_compute(struct gsm_lchan *lchan, uint32_t fn) +int lchan_meas_check_compute(struct gsm_lchan *lchan, uint32_t fn) { struct gsm_meas_rep_unidir *mru; uint32_t ber_full_sum = 0; -- To view, visit https://gerrit.osmocom.org/2411 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ideffe896613e0feda443bc13dac59dcdbbc605aa Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: dexter From gerrit-no-reply at lists.osmocom.org Wed Apr 26 09:38:40 2017 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Wed, 26 Apr 2017 09:38:40 +0000 Subject: [PATCH] osmo-bts[master]: measurement: fix measurement computation Message-ID: Review at https://gerrit.osmocom.org/2412 measurement: fix measurement computation Timing advance is currently not taken into account when computing the measurement results, this commit fixes that Change-Id: I2e0dfd13b53e8aa2822985f12bf2985e683ab553 --- M include/osmo-bts/measurement.h M src/common/measurement.c 2 files changed, 68 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/12/2412/1 diff --git a/include/osmo-bts/measurement.h b/include/osmo-bts/measurement.h index 2efe40f..87c8109 100644 --- a/include/osmo-bts/measurement.h +++ b/include/osmo-bts/measurement.h @@ -1,6 +1,9 @@ #ifndef OSMO_BTS_MEAS_H #define OSMO_BTS_MEAS_H +#define MEAS_MAX_TIMING_ADVANCE 63 +#define MEAS_MIN_TIMING_ADVANCE 0 + int lchan_new_ul_meas(struct gsm_lchan *lchan, struct bts_ul_meas *ulm); int trx_meas_check_compute(struct gsm_bts_trx *trx, uint32_t fn); diff --git a/src/common/measurement.c b/src/common/measurement.c index 79f6ae4..5613894 100644 --- a/src/common/measurement.c +++ b/src/common/measurement.c @@ -196,6 +196,53 @@ return 7; } +/* Update order TA at end of meas period */ +static void lchan_meas_update_ordered_TA(struct gsm_lchan *lchan, + int32_t taqb_sum) +{ + int32_t ms_timing_offset = 0; + uint8_t l1_info_valid; + + l1_info_valid = lchan->meas.flags & LC_UL_M_F_L1_VALID; + + if (l1_info_valid) { + DEBUGP(DMEAS, + "Update TA TimingOffset_Mean:%d, UL RX TA:%d, DL ordered TA:%d, flags:%d \n", + taqb_sum, lchan->meas.l1_info[1], lchan->rqd_ta, + lchan->meas.flags); + + ms_timing_offset = + taqb_sum + (lchan->meas.l1_info[1] - lchan->rqd_ta); + + if (ms_timing_offset > 0) { + if (lchan->rqd_ta < MEAS_MAX_TIMING_ADVANCE) { + /* MS is moving away from BTS. + * So increment Ordered TA by 1 */ + lchan->rqd_ta++; + } + } else if (ms_timing_offset < 0) { + if (lchan->rqd_ta > MEAS_MIN_TIMING_ADVANCE) { + /* MS is moving toward BTS. So decrement + * Ordered TA by 1 */ + lchan->rqd_ta--; + } + } else { + /*MS is not moving so don't change Ordered TA */ + } + + DEBUGP(DMEAS, + "New Update TA--> TimingOff_diff:%d, UL RX TA:%d, DL ordered TA:%d \n", + ms_timing_offset, lchan->meas.l1_info[1], lchan->rqd_ta); + } else { + /*Do Nothing */ + } + + /*Clear L1 INFO valid flag at Meas period end */ + lchan->meas.flags &= ~LC_UL_M_F_L1_VALID; + + return; +} + int lchan_meas_check_compute(struct gsm_lchan *lchan, uint32_t fn) { struct gsm_meas_rep_unidir *mru; @@ -206,6 +253,7 @@ int32_t taqb_sum = 0; unsigned int num_meas_sub = 0; int i; + int32_t ms_timing_offset = 0; /* if measurement period is not complete, abort */ if (!is_meas_complete(ts_pchan(lchan->ts), lchan->ts->nr, @@ -241,6 +289,9 @@ if (num_meas_sub) { ber_sub_sum = ber_sub_sum / num_meas_sub; irssi_sub_sum = irssi_sub_sum / num_meas_sub; + } else { + ber_sub_sum = ber_full_sum; + irssi_sub_sum = irssi_full_sum; } DEBUGP(DMEAS, "%s Computed TA(% 4dqb) BER-FULL(%2u.%02u%%), RSSI-FULL(-%3udBm), " @@ -249,6 +300,20 @@ ber_full_sum%100, irssi_full_sum, ber_sub_sum/100, ber_sub_sum%100, irssi_sub_sum); + /*Update ordered TA for DL SACCH L1 Header */ + lchan_meas_update_ordered_TA(lchan, taqb_sum); + + /* As per 3gpp spec-45.010 sec-1.2, An MS with a round trip + * propagation delay of P symbols, but with a timing advance of T + * symbols, the reported timing offset will be (P-T) quantized to + * the nearest symbol. */ + + ms_timing_offset = taqb_sum + (lchan->meas.l1_info[1] - lchan->rqd_ta); + + /* 0->(-63), 1->(-62)... etc. */ + lchan->meas.ms_timing_offset = + ms_timing_offset + MEAS_MAX_TIMING_ADVANCE; + /* store results */ mru = &lchan->meas.ul_res; mru->full.rx_lev = dbm2rxlev((int)irssi_full_sum * -1); -- To view, visit https://gerrit.osmocom.org/2412 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I2e0dfd13b53e8aa2822985f12bf2985e683ab553 Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: dexter From gerrit-no-reply at lists.osmocom.org Wed Apr 26 09:38:40 2017 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Wed, 26 Apr 2017 09:38:40 +0000 Subject: [PATCH] osmo-bts[master]: measurement: fix clearing of L1 info valid flag Message-ID: Review at https://gerrit.osmocom.org/2413 measurement: fix clearing of L1 info valid flag The layer 1 info valid flag is cleared by rsl_tx_meas_res() when a valid layer 1 info is transmitted via rsl. The flag is now cleared by lchan_meas_update_ordered_TA() in measurement.c, which means that clearing it in rsl.c is no longer needed. Change-Id: Ie511cba7927b4ab80a5b7551c39a253cee14eace --- M src/common/rsl.c 1 file changed, 2 insertions(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/13/2413/1 diff --git a/src/common/rsl.c b/src/common/rsl.c index a542324..7db9939 100644 --- a/src/common/rsl.c +++ b/src/common/rsl.c @@ -2261,7 +2261,8 @@ msgb_tv_put(msg, RSL_IE_BS_POWER, lchan->meas.bts_tx_pwr); if (lchan->meas.flags & LC_UL_M_F_L1_VALID) { msgb_tv_fixed_put(msg, RSL_IE_L1_INFO, 2, lchan->meas.l1_info); - lchan->meas.flags &= ~LC_UL_M_F_L1_VALID; + /* Note: L1 info valid flag is cleared by function + * lchan_meas_update_ordered_TA() in measurement.c */ } msgb_tl16v_put(msg, RSL_IE_L3_INFO, l3_len, l3); //msgb_tv_put(msg, RSL_IE_MS_TIMING_OFFSET, FIXME); -- To view, visit https://gerrit.osmocom.org/2413 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ie511cba7927b4ab80a5b7551c39a253cee14eace Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: dexter From gerrit-no-reply at lists.osmocom.org Wed Apr 26 09:38:40 2017 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Wed, 26 Apr 2017 09:38:40 +0000 Subject: [PATCH] osmo-bts[master]: measurement: Compute measurement results on measurement idic... Message-ID: Review at https://gerrit.osmocom.org/2414 measurement: Compute measurement results on measurement idication Computing the measurement results on in l1sap_info_time_ind() all at once may peak the host CPU. On smaller systems (arm based sysmobts) this might cause a noticable delay of other important tasks (e.g. passing l2 messages back and forth) It makes more sense to compute the measurement results continously when l1sap_info_meas_ind() is executed. Change-Id: Iecb9a30c0d716bfc88221cd752b1ffdc74269e30 --- M src/common/l1sap.c 1 file changed, 4 insertions(+), 5 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/14/2414/1 diff --git a/src/common/l1sap.c b/src/common/l1sap.c index 3592096..0b6874a 100644 --- a/src/common/l1sap.c +++ b/src/common/l1sap.c @@ -419,11 +419,6 @@ /* Update time on PCU interface */ pcu_tx_time_ind(info_time_ind->fn); - /* check if the measurement period of some lchan has ended - * and pre-compute the respective measurement */ - llist_for_each_entry(trx, &bts->trx_list, list) - trx_meas_check_compute(trx, info_time_ind->fn - 1); - /* increment number of RACH slots that have passed by since the * last time indication */ btsb->load.rach.total += @@ -458,6 +453,10 @@ lchan_new_ul_meas(lchan, &ulm); + /* Check measurement period end and prepare the UL measurment + * report at Meas period End*/ + lchan_meas_check_compute(lchan, info_meas_ind->fn); + return 0; } -- To view, visit https://gerrit.osmocom.org/2414 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Iecb9a30c0d716bfc88221cd752b1ffdc74269e30 Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: dexter From gerrit-no-reply at lists.osmocom.org Wed Apr 26 09:38:40 2017 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Wed, 26 Apr 2017 09:38:40 +0000 Subject: [PATCH] osmo-bts[master]: measurement: Fix reporting of ms timing offset Message-ID: Review at https://gerrit.osmocom.org/2415 measurement: Fix reporting of ms timing offset The ms timing offset (RSL_IE_MS_TIMING_OFFSET) is not included in the rsl measurement report message. An incomplete code line, marked with FIXME is present. This commit completes the code. lchan->meas.ms_timing_offset is now included in the rsl measurement report message. Change-Id: I6cdc310497d9210013b257da91369c203c3c445f --- M src/common/rsl.c 1 file changed, 1 insertion(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/15/2415/1 diff --git a/src/common/rsl.c b/src/common/rsl.c index 7db9939..6d5a0d3 100644 --- a/src/common/rsl.c +++ b/src/common/rsl.c @@ -2265,7 +2265,7 @@ * lchan_meas_update_ordered_TA() in measurement.c */ } msgb_tl16v_put(msg, RSL_IE_L3_INFO, l3_len, l3); - //msgb_tv_put(msg, RSL_IE_MS_TIMING_OFFSET, FIXME); + msgb_tv_put(msg, RSL_IE_MS_TIMING_OFFSET, lchan->meas.ms_timing_offset); rsl_dch_push_hdr(msg, RSL_MT_MEAS_RES, chan_nr); msg->trx = lchan->ts->trx; -- To view, visit https://gerrit.osmocom.org/2415 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I6cdc310497d9210013b257da91369c203c3c445f Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: dexter From gerrit-no-reply at lists.osmocom.org Wed Apr 26 09:38:40 2017 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Wed, 26 Apr 2017 09:38:40 +0000 Subject: [PATCH] osmo-bts[master]: WIP: measurement: fix measurement report interval lookup tables Message-ID: Review at https://gerrit.osmocom.org/2416 WIP: measurement: fix measurement report interval lookup tables The measurment reporting interval, generated from the lookup defind at the beginning of the source code file (*_meas_rep_fn104[]) is off by one, in some case off by 2. This commit corrects the timing by subtracting 1 or 2 from the respective lookup table. NOTE: This is still work in progress. To me this looks like something, that might be octasic specific. Is this allignment really needed for all BTS models? Change-Id: I471a767c7974bdacadc3233d0c3e7b7965f6eafa --- M src/common/measurement.c 1 file changed, 29 insertions(+), 24 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/16/2416/1 diff --git a/src/common/measurement.c b/src/common/measurement.c index 5613894..e1adb8d 100644 --- a/src/common/measurement.c +++ b/src/common/measurement.c @@ -24,35 +24,40 @@ * 7 6 and 7 91 to 90 103, 25, 51, 77 */ /* measurement period ends at fn % 104 == ? */ +/* Added (-1) offset in DATA-IND frame number to align with Meas period ends */ static const uint8_t tchf_meas_rep_fn104[] = { - [0] = 103, - [1] = 12, - [2] = 25, - [3] = 38, - [4] = 51, - [5] = 64, - [6] = 77, - [7] = 90, + [0] = 103 - 1, + [1] = 12 - 1, + [2] = 25 - 1, + [3] = 38 - 1, + [4] = 51 - 1, + [5] = 64 - 1, + [6] = 77 - 1, + [7] = 90 - 1, }; + +/* Added (-2) offset in DATA-IND frame number to align with Meas period ends */ static const uint8_t tchh0_meas_rep_fn104[] = { - [0] = 103, - [1] = 103, - [2] = 25, - [3] = 25, - [4] = 51, - [5] = 51, - [6] = 77, - [7] = 77, + [0] = 103 - 2, + [1] = 103 - 2, + [2] = 25 - 2, + [3] = 25 - 2, + [4] = 51 - 2, + [5] = 51 - 2, + [6] = 77 - 2, + [7] = 77 - 2, }; + +/* Added (-1) offset in DATA-IND frame number to align with Meas period ends */ static const uint8_t tchh1_meas_rep_fn104[] = { - [0] = 12, - [1] = 12, - [2] = 38, - [3] = 38, - [4] = 64, - [5] = 64, - [6] = 90, - [7] = 90, + [0] = 12 - 1, + [1] = 12 - 1, + [2] = 38 - 1, + [3] = 38 - 1, + [4] = 64 - 1, + [5] = 64 - 1, + [6] = 90 - 1, + [7] = 90 - 1, }; /* Measurment reporting period for SDCCH8 and SDCCH4 chan -- To view, visit https://gerrit.osmocom.org/2416 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I471a767c7974bdacadc3233d0c3e7b7965f6eafa Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: dexter From gerrit-no-reply at lists.osmocom.org Wed Apr 26 09:38:41 2017 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Wed, 26 Apr 2017 09:38:41 +0000 Subject: [PATCH] osmo-bts[master]: octphy: WIP: fix channel measurement handling Message-ID: Review at https://gerrit.osmocom.org/2417 octphy: WIP: fix channel measurement handling recent octphy firmware versions do no longer compute the channel measurement results internally. Instead, hand out each frame and the computation is done in software. This requires a change to the octphy code. This patch introduces the changes using ifdef statements in order not to break support for older firmware versions. Note: This is still work in progress. We might consider to remove the ifdef statements again since the old method yielded wrong measurement results anyway. So it would be ok to drop the old non working measurement result computation completely. Change-Id: I0f053bb10b1cb112a8814ee591969d607888e686 --- M src/osmo-bts-octphy/l1_if.c M src/osmo-bts-octphy/l1_if.h 2 files changed, 73 insertions(+), 7 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/17/2417/1 diff --git a/src/osmo-bts-octphy/l1_if.c b/src/osmo-bts-octphy/l1_if.c index 7b98785..50b41ee 100644 --- a/src/osmo-bts-octphy/l1_if.c +++ b/src/osmo-bts-octphy/l1_if.c @@ -76,6 +76,20 @@ /* timeout until which we expect PHY to respond */ #define CMD_TIMEOUT 5 +#if (cOCTVC1_MAIN_VERSION_ID >= cOCTVC1_MAIN_VERSION_ID_FN_PARADIGM_CHG) +#define sBurstTiming(x) x +#else +#define sBurstTiming(x) (x >> 2) +#endif + +#if (cOCTVC1_MAIN_VERSION_ID >= cOCTVC1_MAIN_VERSION_ID_FN_PARADIGM_CHG) +/* get rssi, rssi is in q8 format */ +#define sRSSIDbm(x) (x >> 4) +#else +/* get rssi, rssi is in regular format (older firmware versions) */ +#define sRSSIDbm(x) x +#endif + /* allocate a msgb for a Layer1 primitive */ struct msgb *l1p_msgb_alloc(void) { @@ -791,7 +805,8 @@ ***********************************************************************/ static void process_meas_res(struct gsm_bts_trx *trx, uint8_t chan_nr, - tOCTVC1_GSM_MEASUREMENT_INFO * m) + uint32_t fn, uint32_t data_len, + tOCTVC1_GSM_MEASUREMENT_INFO * m) { struct osmo_phsap_prim l1sap; @@ -800,10 +815,40 @@ PRIM_OP_INDICATION, NULL); l1sap.u.info.type = PRIM_INFO_MEAS; l1sap.u.info.u.meas_ind.chan_nr = chan_nr; - l1sap.u.info.u.meas_ind.ta_offs_qbits = m->sBurstTiming; +#if (cOCTVC1_MAIN_VERSION_ID >= cOCTVC1_MAIN_VERSION_ID_FN_PARADIGM_CHG) + /* Update Timing offset for valid radio block */ + if (data_len != 0) { + /* burst timing in 1x */ + l1sap.u.info.u.meas_ind.ta_offs_qbits = m->sBurstTiming; + } else { + /* FIXME, In current implementation, OCTPHY would send DATA_IND + * for all radio blocks (valid or invalid) But timing offset + * is only correct for valid block. so we need different + * counter to accumulate Timing offset.. even we add zero for + * invalid block.. timing offset average calucation would not + * correct. */ + l1sap.u.info.u.meas_ind.ta_offs_qbits = 0; + } + + if (m->usBERTotalBitCnt != 0) { + l1sap.u.info.u.meas_ind.ber10k = + (unsigned int)((m->usBERCnt * BER_10K) / + m->usBERTotalBitCnt); + } else { + l1sap.u.info.u.meas_ind.ber10k = 0; + } + + /* rssi is in q8 format */ + l1sap.u.info.u.meas_ind.inv_rssi = (uint8_t) ((m->sRSSIDbm >> 8) * -1); + + /* copy logical frame number to MEAS IND data structure */ + l1sap.u.info.u.meas_ind.fn = fn; +#else + l1sap.u.info.u.meas_ind.ta_offs_qbits = m->sBurstTiming; l1sap.u.info.u.meas_ind.ber10k = (unsigned int)(m->usBERCnt * 100); l1sap.u.info.u.meas_ind.inv_rssi = (uint8_t) (m->sRSSIDbm * -1); +#endif /* l1sap wants to take msgb ownership. However, as there is no * msg, it will msgb_free(l1sap.oph.msg == NULL) */ @@ -812,9 +857,17 @@ static void dump_meas_res(int ll, tOCTVC1_GSM_MEASUREMENT_INFO * m) { +#if (cOCTVC1_MAIN_VERSION_ID >= cOCTVC1_MAIN_VERSION_ID_FN_PARADIGM_CHG) + LOGPC(DMEAS, ll, + "Meas: RSSI %d dBm, Burst Timing %d Quarter of bits :%d, " + "BER Error Count %d , BER Toatal Bit count %d in last decoded frame\n", + m->sRSSIDbm, m->sBurstTiming, m->sBurstTiming4x, m->usBERCnt, + m->usBERTotalBitCnt); +#else LOGPC(DL1C, ll, ", Meas: RSSI %d dBm, Burst Timing %d Quarter of bits, " "BER Error Count %d in last decoded frame, BER Toatal Bit count %d in last decoded frame\n", m->sRSSIDbm, m->sBurstTiming, m->usBERCnt, m->usBERTotalBitCnt); +#endif } static int handle_mph_time_ind(struct octphy_hdl *fl1, uint8_t trx_id, uint32_t fn) @@ -1007,14 +1060,17 @@ memset(&l1sap, 0, sizeof(l1sap)); /* uplink measurement */ - process_meas_res(trx, chan_nr, &data_ind->MeasurementInfo); + process_meas_res(trx, chan_nr, fn, data_ind->Data.ulDataLength, + &data_ind->MeasurementInfo); /* FIXME: check min_qual_norm! */ - DEBUGP(DL1C, "Rx PH-DATA.ind %s: %s", + DEBUGP(DL1C, "Rx PH-DATA.ind %s: %s data_len:%d \n", get_value_string(octphy_l1sapi_names, sapi), osmo_hexdump(data_ind->Data.abyDataContent, - data_ind->Data.ulDataLength)); + data_ind->Data.ulDataLength), + data_ind->Data.ulDataLength); + dump_meas_res(LOGL_DEBUG, &data_ind->MeasurementInfo); /* check for TCH */ @@ -1026,7 +1082,7 @@ } /* get rssi */ - rssi = (int8_t) data_ind->MeasurementInfo.sRSSIDbm; + rssi = (int8_t) sRSSIDbm(data_ind->MeasurementInfo.sRSSIDbm); /* get data pointer and length */ data = data_ind->Data.abyDataContent; len = data_ind->Data.ulDataLength; @@ -1048,6 +1104,7 @@ #if (cOCTVC1_MAIN_VERSION_ID >= cOCTVC1_MAIN_VERSION_ID_FN_PARADIGM_CHG) if (sapi == cOCTVC1_GSM_SAPI_ENUM_PDTCH) { + /* FIXME::PCU is expecting encode frame number*/ l1sap->u.data.fn = fn - 3; } else l1sap->u.data.fn = fn; @@ -1058,8 +1115,15 @@ l1sap->u.data.rssi = rssi; b_total = data_ind->MeasurementInfo.usBERTotalBitCnt; b_error =data_ind->MeasurementInfo.usBERCnt; +#if (cOCTVC1_MAIN_VERSION_ID >= cOCTVC1_MAIN_VERSION_ID_FN_PARADIGM_CHG) + l1sap->u.data.ber10k = b_total ? BER_10K * b_error / b_total : 0; + + /* FIXME::burst timing in 1x but PCU is expecting 4X */ + l1sap->u.data.ta_offs_qbits = (data_ind->MeasurementInfo.sBurstTiming * 4); +#else l1sap->u.data.ber10k = b_total ? 10000 * b_error / b_total : 0; l1sap->u.data.ta_offs_qbits = data_ind->MeasurementInfo.sBurstTiming4x; +#endif snr = data_ind->MeasurementInfo.sSNRDb; /* FIXME: better converion formulae for SnR -> C / I? l1sap->u.data.lqual_cb = (snr ? snr : (snr - 65536)) * 10 / 256; @@ -1113,7 +1177,7 @@ if (ra_ind->MeasurementInfo.sBurstTiming < 0) acc_delay = 0; else - acc_delay = ra_ind->MeasurementInfo.sBurstTiming >> 2; + acc_delay = sBurstTiming(ra_ind->MeasurementInfo.sBurstTiming); rc = msgb_trim(l1p_msg, sizeof(*l1sap)); if (rc < 0) diff --git a/src/osmo-bts-octphy/l1_if.h b/src/osmo-bts-octphy/l1_if.h index 2dee178..0960482 100644 --- a/src/osmo-bts-octphy/l1_if.h +++ b/src/osmo-bts-octphy/l1_if.h @@ -17,6 +17,8 @@ #include +#define BER_10K 10000 + struct octphy_hdl { /* MAC address of the PHY */ struct sockaddr_ll phy_addr; -- To view, visit https://gerrit.osmocom.org/2417 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I0f053bb10b1cb112a8814ee591969d607888e686 Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: dexter From gerrit-no-reply at lists.osmocom.org Wed Apr 26 10:09:25 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Wed, 26 Apr 2017 10:09:25 +0000 Subject: osmo-bts[master]: measurement: make lchan_meas_check_compute() available to l1... In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+1 -- To view, visit https://gerrit.osmocom.org/2411 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ideffe896613e0feda443bc13dac59dcdbbc605aa Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Wed Apr 26 10:10:33 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Wed, 26 Apr 2017 10:10:33 +0000 Subject: osmo-bts[master]: measurement: Fix reporting of ms timing offset In-Reply-To: References: Message-ID: Patch Set 1: Seems to be duplicate of gerrit 1700. -- To view, visit https://gerrit.osmocom.org/2415 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I6cdc310497d9210013b257da91369c203c3c445f Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Max Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Wed Apr 26 10:14:24 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Wed, 26 Apr 2017 10:14:24 +0000 Subject: libosmo-netif[master]: osmux: Add RTP marker bit support In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+1 -- To view, visit https://gerrit.osmocom.org/2407 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I0315658159429603f1d80a168718b026015060e9 Gerrit-PatchSet: 2 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Pau Espin Pedrol Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Pau Espin Pedrol Gerrit-Reviewer: daniel Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Wed Apr 26 10:20:05 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Wed, 26 Apr 2017 10:20:05 +0000 Subject: openbsc[master]: lchan: add ms_timing_offset member to struct gsm_lchan In-Reply-To: References: Message-ID: Patch Set 1: Code-Review-1 There's already ms_t_offs in gsm_lchan. -- To view, visit https://gerrit.osmocom.org/2409 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ifc4cff7efa4ba0a4b94448767143dd18b6db9325 Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Wed Apr 26 10:26:40 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Wed, 26 Apr 2017 10:26:40 +0000 Subject: [MERGED] openbsc[master]: Remove libs from openbsc.pc In-Reply-To: References: Message-ID: Max has submitted this change and it was merged. Change subject: Remove libs from openbsc.pc ...................................................................... Remove libs from openbsc.pc OpenBSC does not produce any installable libraries, only header files so this section is unnecessary. Change-Id: I4c563d775a84f41f82404e0eaba1a25fdbaac1a5 --- M openbsc/openbsc.pc.in 1 file changed, 0 insertions(+), 1 deletion(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/openbsc/openbsc.pc.in b/openbsc/openbsc.pc.in index aba07e2..17e265d 100644 --- a/openbsc/openbsc.pc.in +++ b/openbsc/openbsc.pc.in @@ -7,5 +7,4 @@ Description: OpenBSC base station controller Requires: Version: @VERSION@ -Libs: -L${libdir} -lopenbsc Cflags: -I${includedir} -- To view, visit https://gerrit.osmocom.org/2019 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I4c563d775a84f41f82404e0eaba1a25fdbaac1a5 Gerrit-PatchSet: 2 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max From gerrit-no-reply at lists.osmocom.org Wed Apr 26 10:42:36 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Wed, 26 Apr 2017 10:42:36 +0000 Subject: [PATCH] osmo-bts[master]: Add MS TO to RSL measurements In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/1700 to look at the new patch set (#6). Add MS TO to RSL measurements Add optional MS timing offset (3GPP TS 45.010 ? 1.2) to RSL MEASUREMENT RESULT (3GPP TS 48.058 ? 8.4.8). The value is calculated either directly from corresponding BTS measurement or from 3GPP TS 48.058 ? 9.3.17 Access Delay (for known TA) and is invalidated after RSL report is sent until new measurement indication or RACH is received. Change-Id: I4dfe5c48834a083e757d5de3236a02e15a238b28 Related: OS#1574 --- M src/common/l1sap.c M src/common/rsl.c 2 files changed, 44 insertions(+), 5 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/00/1700/6 diff --git a/src/common/l1sap.c b/src/common/l1sap.c index 3592096..57a858c 100644 --- a/src/common/l1sap.c +++ b/src/common/l1sap.c @@ -431,6 +431,27 @@ return 0; } + +static inline void set_ms_to_data(struct gsm_lchan *lchan, int16_t data, bool set_ms_to) +{ + if (!lchan) + return; + + if (data + 63 > 255) { /* According to 3GPP TS 48.058 ?9.3.37 Timing Offset field cannot exceed 255 */ + LOGP(DL1P, LOGL_ERROR, "Attempting to set invalid Timing Offset value %d (MS TO = %u)!\n", + data, set_ms_to); + return; + } + + if (set_ms_to) { + lchan->ms_t_offs = data + 63; + lchan->p_offs = -1; + } else { + lchan->p_offs = data + 63; + lchan->ms_t_offs = -1; + } +} + /* measurement information received from bts model */ static int l1sap_info_meas_ind(struct gsm_bts_trx *trx, struct osmo_phsap_prim *l1sap, @@ -455,6 +476,9 @@ ulm.ta_offs_qbits = info_meas_ind->ta_offs_qbits; ulm.ber10k = info_meas_ind->ber10k; ulm.inv_rssi = info_meas_ind->inv_rssi; + + /* we assume that symbol period is 1 bit: */ + set_ms_to_data(lchan, info_meas_ind->ta_offs_qbits / 4, true); lchan_new_ul_meas(lchan, &ulm); @@ -1021,6 +1045,9 @@ return 0; } + /* According to 3GPP TS 48.058 ? 9.3.17 Access Delay is expressed same way as TA (number of symbols) */ + set_ms_to_data(get_lchan_by_chan_nr(trx, rach_ind->chan_nr), acc_delay, false); + /* check for handover rach */ if (!L1SAP_IS_CHAN_RACH(rach_ind->chan_nr)) return l1sap_handover_rach(trx, l1sap, rach_ind); diff --git a/src/common/rsl.c b/src/common/rsl.c index 1d0bcea..5fe5a1d 100644 --- a/src/common/rsl.c +++ b/src/common/rsl.c @@ -2220,8 +2220,18 @@ return 0; } +static inline uint8_t ms_to2rsl(const struct gsm_lchan *lchan, const struct lapdm_entity *le) +{ + return (lchan->ms_t_offs >= 0) ? lchan->ms_t_offs : (lchan->p_offs - le->ta); +} + +static inline bool ms_to_valid(const struct gsm_lchan *lchan) +{ + return (lchan->ms_t_offs >= 0) || (lchan->p_offs >= 0); +} + /* 8.4.8 MEASUREMENT RESult */ -static int rsl_tx_meas_res(struct gsm_lchan *lchan, uint8_t *l3, int l3_len) +static int rsl_tx_meas_res(struct gsm_lchan *lchan, uint8_t *l3, int l3_len, const struct lapdm_entity *le) { struct msgb *msg; uint8_t meas_res[16]; @@ -2253,7 +2263,11 @@ lchan->meas.flags &= ~LC_UL_M_F_L1_VALID; } msgb_tl16v_put(msg, RSL_IE_L3_INFO, l3_len, l3); - //msgb_tv_put(msg, RSL_IE_MS_TIMING_OFFSET, FIXME); + if (ms_to_valid(lchan)) { + msgb_tv_put(msg, RSL_IE_MS_TIMING_OFFSET, ms_to2rsl(lchan, le)); + lchan->ms_t_offs = -1; + lchan->p_offs = -1; + } rsl_dch_push_hdr(msg, RSL_MT_MEAS_RES, chan_nr); msg->trx = lchan->ts->trx; @@ -2266,8 +2280,6 @@ { struct gsm_lchan *lchan = ctx; struct abis_rsl_common_hdr *rh; - - /* NOTE: Parameter lapdm_entity *le is ignored */ OSMO_ASSERT(msg); rh = msgb_l2(msg); @@ -2306,7 +2318,7 @@ return 0; } - rc = rsl_tx_meas_res(lchan, msgb_l3(msg), msgb_l3len(msg)); + rc = rsl_tx_meas_res(lchan, msgb_l3(msg), msgb_l3len(msg), le); msgb_free(msg); return rc; } else { -- To view, visit https://gerrit.osmocom.org/1700 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I4dfe5c48834a083e757d5de3236a02e15a238b28 Gerrit-PatchSet: 6 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Alexander Chemeris Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Ivan Kluchnikov Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: dexter From gerrit-no-reply at lists.osmocom.org Wed Apr 26 10:46:43 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Wed, 26 Apr 2017 10:46:43 +0000 Subject: osmo-bts[master]: Add MS TO to RSL measurements In-Reply-To: References: Message-ID: Patch Set 5: I don't think using assert here is a good idea - the value comes from dsp/l1 so phone might affect them directly. Letting phone to crash bts is undesirable. -- To view, visit https://gerrit.osmocom.org/1700 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I4dfe5c48834a083e757d5de3236a02e15a238b28 Gerrit-PatchSet: 5 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Alexander Chemeris Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Ivan Kluchnikov Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: dexter Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Wed Apr 26 11:32:02 2017 From: gerrit-no-reply at lists.osmocom.org (Pau Espin Pedrol) Date: Wed, 26 Apr 2017 11:32:02 +0000 Subject: libosmo-netif[master]: osmux: Add RTP marker bit support In-Reply-To: References: Message-ID: Patch Set 2: I can see that the test failed in freebsd due to the timer being fired after 10 secs, but I have been running the test in a loop for a while in my linux PC and I cannot make it fail... -- To view, visit https://gerrit.osmocom.org/2407 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I0315658159429603f1d80a168718b026015060e9 Gerrit-PatchSet: 2 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Pau Espin Pedrol Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Pau Espin Pedrol Gerrit-Reviewer: daniel Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Wed Apr 26 13:03:20 2017 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Wed, 26 Apr 2017 13:03:20 +0000 Subject: libosmo-netif[master]: osmux: Add RTP marker bit support In-Reply-To: References: Message-ID: Patch Set 2: is it possible to get this off real time? We have a fake time available in libosmocore. Real time bites us every so often when the build slave is under load. -- To view, visit https://gerrit.osmocom.org/2407 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I0315658159429603f1d80a168718b026015060e9 Gerrit-PatchSet: 2 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Pau Espin Pedrol Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: Pau Espin Pedrol Gerrit-Reviewer: daniel Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Wed Apr 26 13:50:42 2017 From: gerrit-no-reply at lists.osmocom.org (Pau Espin Pedrol) Date: Wed, 26 Apr 2017 13:50:42 +0000 Subject: libosmo-netif[master]: osmux: Add RTP marker bit support In-Reply-To: References: Message-ID: Patch Set 2: I'm adding a new commit to use osmo_gettimeofday in osmux + osmux_test -- To view, visit https://gerrit.osmocom.org/2407 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I0315658159429603f1d80a168718b026015060e9 Gerrit-PatchSet: 2 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Pau Espin Pedrol Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: Pau Espin Pedrol Gerrit-Reviewer: daniel Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Wed Apr 26 14:05:01 2017 From: gerrit-no-reply at lists.osmocom.org (Pau Espin Pedrol) Date: Wed, 26 Apr 2017 14:05:01 +0000 Subject: [PATCH] libosmo-netif[master]: osmux: Add RTP marker bit support In-Reply-To: References: Message-ID: Hello Max, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2407 to look at the new patch set (#3). osmux: Add RTP marker bit support According to RFC4867 (RTP payload format for AMR): "The RTP header marker bit (M) SHALL be set to 1 if the first frameblock carried in the packet contains a speech frame which is the first in a talkspurt. For all other packets the marker bit SHALL be set to zero (M=0)." This information bit provides a way for the receiver to better synchronize the delay with ther sender. This is specially useful if AMR DTX features are supported and enabled on the sender. Change-Id: I0315658159429603f1d80a168718b026015060e9 --- M include/osmocom/netif/osmux.h M src/osmux.c M tests/osmux/osmux_test.c 3 files changed, 83 insertions(+), 7 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-netif refs/changes/07/2407/3 diff --git a/include/osmocom/netif/osmux.h b/include/osmocom/netif/osmux.h index 1d93aa0..5283059 100644 --- a/include/osmocom/netif/osmux.h +++ b/include/osmocom/netif/osmux.h @@ -13,7 +13,8 @@ /* OSmux header: * - * ft (3 bits): 0=signalling, 1=voice, 2=dummy + * rtp_m (1 bit): RTP M field (RFC3550, RFC4867) + * ft (2 bits): 0=signalling, 1=voice, 2=dummy * ctr (3 bits): Number of batched AMR payloads (starting 0) * amr_f (1 bit): AMR F field (RFC3267) * amr_q (1 bit): AMR Q field (RFC3267) @@ -29,7 +30,8 @@ struct osmux_hdr { #if OSMO_IS_BIG_ENDIAN - uint8_t ft:3, + uint8_t rtp_m:1, + ft:2, ctr:3, amr_f:1, amr_q:1; @@ -37,7 +39,8 @@ uint8_t amr_q:1, amr_f:1, ctr:3, - ft:3; + ft:2, + rtp_m:1; #endif uint8_t seq; #define OSMUX_CID_MAX 255 /* determined by circuit_id */ diff --git a/src/osmux.c b/src/osmux.c index 1dcd04f..4d12427 100644 --- a/src/osmux.c +++ b/src/osmux.c @@ -105,8 +105,8 @@ } static struct msgb * -osmux_rebuild_rtp(struct osmux_out_handle *h, - struct osmux_hdr *osmuxh, void *payload, int payload_len) +osmux_rebuild_rtp(struct osmux_out_handle *h, struct osmux_hdr *osmuxh, + void *payload, int payload_len, bool first_pkt) { struct msgb *out_msg; struct rtp_hdr *rtph; @@ -129,6 +129,8 @@ rtph->timestamp = htonl(h->rtp_timestamp); rtph->sequence = htons(h->rtp_seq); rtph->ssrc = htonl(h->rtp_ssrc); + /* rtp packet with the marker bit is always warranted to be the first one */ + rtph->marker = first_pkt && osmuxh->rtp_m; msgb_put(out_msg, sizeof(struct rtp_hdr)); @@ -166,7 +168,7 @@ msg = osmux_rebuild_rtp(h, osmuxh, osmux_get_payload(osmuxh) + i * osmo_amr_bytes(osmuxh->amr_ft), - osmo_amr_bytes(osmuxh->amr_ft)); + osmo_amr_bytes(osmuxh->amr_ft), !i); if (msg == NULL) continue; @@ -264,6 +266,7 @@ osmuxh = (struct osmux_hdr *)state->out_msg->tail; osmuxh->ft = OSMUX_FT_VOICE_AMR; osmuxh->ctr = 0; + osmuxh->rtp_m = osmuxh->rtp_m || state->rtph->marker; osmuxh->amr_f = state->amrh->f; osmuxh->amr_q= state->amrh->q; osmuxh->seq = batch->seq++; @@ -593,6 +596,13 @@ if (bytes > batch->remaining_bytes) return 1; + /* Init of talkspurt (RTP M marker bit) needs to be in the first AMR slot + * of the OSMUX packet, enforce sending previous batch if required: + */ + if (rtph->marker && circuit->nmsgs != 0) + return 1; + + /* Extra validation: check if this message already exists, should not * happen but make sure we don't propagate duplicated messages. */ diff --git a/tests/osmux/osmux_test.c b/tests/osmux/osmux_test.c index 2f5a6cd..9941ce3 100644 --- a/tests/osmux/osmux_test.c +++ b/tests/osmux/osmux_test.c @@ -55,6 +55,7 @@ }; static int rtp_pkts; +static int mark_pkts; #if OSMUX_TEST_USE_TIMING static struct timeval last; #endif @@ -62,6 +63,7 @@ static void tx_cb(struct msgb *msg, void *data) { char buf[4096]; + struct rtp_hdr *rtph = (struct rtp_hdr *)msg->data; #if OSMUX_TEST_USE_TIMING struct timeval now, diff; @@ -87,6 +89,8 @@ exit(EXIT_FAILURE); } + if (rtph->marker) + mark_pkts--; rtp_pkts--; msgb_free(msg); } @@ -122,6 +126,48 @@ { printf("FAIL: test did not run successfully\n"); exit(EXIT_FAILURE); +} + +static void osmux_test_marker(int ccid) { + struct msgb *msg; + struct rtp_hdr *rtph = (struct rtp_hdr *)rtp_pkt; + struct rtp_hdr *cpy_rtph; + uint16_t seq; + int i, j; + + for (i = 0; i < 64; i++) { + + seq = ntohs(rtph->sequence); + seq++; + rtph->sequence = htons(seq); + + for (j=0; j<4; j++) { + msg = msgb_alloc(1500, "test"); + if (!msg) + exit(EXIT_FAILURE); + + memcpy(msg->data, rtp_pkt, sizeof(rtp_pkt)); + cpy_rtph = (struct rtp_hdr *) msgb_put(msg, sizeof(rtp_pkt)); + + if ((i+j) % 7 == 0) { + cpy_rtph->marker = 1; + mark_pkts++; + } + + rtp_pkts++; + while (osmux_xfrm_input(&h_input, msg, j + ccid) > 0) { + osmux_xfrm_input_deliver(&h_input); + } + } + } + + while (rtp_pkts) + osmo_select_main(0); + + if (mark_pkts) { + fprintf(stdout, "RTP M bit (marker) mismatch! %d\n", mark_pkts); + exit(EXIT_FAILURE); + } } static void osmux_test_loop(int ccid) @@ -177,6 +223,11 @@ k = 0; } } + + if (mark_pkts) { + fprintf(stdout, "RTP M bit (marker) mismatch! %d\n", mark_pkts); + exit(EXIT_FAILURE); + } } int main(void) @@ -192,12 +243,24 @@ osmo_init_logging(&osmux_test_log_info); log_set_log_level(osmo_stderr_target, LOGL_DEBUG); - osmux_xfrm_input_init(&h_input); osmux_xfrm_output_init(&h_output, 0x7000000); /* If the test takes longer than 10 seconds, abort it */ alarm(10); +#if !OSMUX_TEST_USE_TIMING + /* Check if marker bit features work correctly */ + osmux_xfrm_input_init(&h_input); + for (i = 0; i < 4; i++) + osmux_xfrm_input_open_circuit(&h_input, i, 0); + osmux_test_marker(0); + for (i = 0; i < 4; i++) + osmux_xfrm_input_close_circuit(&h_input, i); + osmux_xfrm_input_fini(&h_input); +#endif + + osmux_xfrm_input_init(&h_input); + for (i = 0; i < 2; i++) osmux_xfrm_input_open_circuit(&h_input, i, 0); -- To view, visit https://gerrit.osmocom.org/2407 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I0315658159429603f1d80a168718b026015060e9 Gerrit-PatchSet: 3 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Pau Espin Pedrol Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: Pau Espin Pedrol Gerrit-Reviewer: daniel From gerrit-no-reply at lists.osmocom.org Wed Apr 26 14:05:03 2017 From: gerrit-no-reply at lists.osmocom.org (Pau Espin Pedrol) Date: Wed, 26 Apr 2017 14:05:03 +0000 Subject: [PATCH] libosmo-netif[master]: osmux: Use osmo_gettimeofday for testing puroposes Message-ID: Review at https://gerrit.osmocom.org/2418 osmux: Use osmo_gettimeofday for testing puroposes This way we can use fake time and osmux_test take 700ms instead of >2sec to run. Change-Id: Ic39cab74400aca8262a00c0d06884230b1a15ca3 --- M src/osmux.c M tests/osmux/osmux_test.c 2 files changed, 26 insertions(+), 6 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-netif refs/changes/18/2418/1 diff --git a/src/osmux.c b/src/osmux.c index 4d12427..d12a39a 100644 --- a/src/osmux.c +++ b/src/osmux.c @@ -777,7 +777,7 @@ #ifdef DEBUG_TIMING struct timeval now, diff; - gettimeofday(&now, NULL); + osmo_gettimeofday(&now, NULL); timersub(&now, &h->start, &diff); timersub(&diff,&h->when, &diff); LOGP(DLMIB, LOGL_DEBUG, "we are lagging %lu.%.6lu in scheduled " @@ -806,7 +806,7 @@ h->timer.data = h; #ifdef DEBUG_TIMING - gettimeofday(&h->start, NULL); + osmo_gettimeofday(&h->start, NULL); h->when.tv_sec = when->tv_sec; h->when.tv_usec = when->tv_usec; #endif diff --git a/tests/osmux/osmux_test.c b/tests/osmux/osmux_test.c index 9941ce3..9e16da7 100644 --- a/tests/osmux/osmux_test.c +++ b/tests/osmux/osmux_test.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -54,6 +55,8 @@ 0xf2, 0x26, 0x33, 0x65, 0x54, }; +#define PKT_TIME_USEC 20*1000 + static int rtp_pkts; static int mark_pkts; #if OSMUX_TEST_USE_TIMING @@ -67,7 +70,7 @@ #if OSMUX_TEST_USE_TIMING struct timeval now, diff; - gettimeofday(&now, NULL); + osmo_gettimeofday(&now, NULL); timersub(&now, &last, &diff); last = now; @@ -159,10 +162,17 @@ osmux_xfrm_input_deliver(&h_input); } } +#if !OSMUX_TEST_USE_TIMING + osmo_gettimeofday_override_add(0, PKT_TIME_USEC); +#endif } - while (rtp_pkts) + while (rtp_pkts) { +#if !OSMUX_TEST_USE_TIMING + osmo_gettimeofday_override_add(1, 0); +#endif osmo_select_main(0); + } if (mark_pkts) { fprintf(stdout, "RTP M bit (marker) mismatch! %d\n", mark_pkts); @@ -204,7 +214,7 @@ if (i % 4 == 0) { #if OSMUX_TEST_USE_TIMING - gettimeofday(&last, NULL); + osmo_gettimeofday(&last, NULL); #endif /* After four RTP messages, squash them into the OSMUX @@ -217,8 +227,12 @@ * messages that are extracted from OSMUX has been * delivered. */ - for (j = 0; j < k-2; j++) + for (j = 0; j < k-2; j++) { osmo_select_main(0); +#if !OSMUX_TEST_USE_TIMING + osmo_gettimeofday_override_add(0,PKT_TIME_USEC); +#endif + } k = 0; } @@ -239,6 +253,12 @@ exit(EXIT_FAILURE); } +#if !OSMUX_TEST_USE_TIMING + /* This test uses fake time to speedup the run, unless we want to manually + * test time specific stuff */ + osmo_gettimeofday_override = true; +#endif + /* This test doesn't use it, but osmux requires it internally. */ osmo_init_logging(&osmux_test_log_info); log_set_log_level(osmo_stderr_target, LOGL_DEBUG); -- To view, visit https://gerrit.osmocom.org/2418 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ic39cab74400aca8262a00c0d06884230b1a15ca3 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Pau Espin Pedrol From gerrit-no-reply at lists.osmocom.org Wed Apr 26 14:23:29 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Wed, 26 Apr 2017 14:23:29 +0000 Subject: [PATCH] openbsc[master]: gbproxy: add example .service Message-ID: Review at https://gerrit.osmocom.org/2419 gbproxy: add example .service Change-Id: Ic8144777a77efce4bad44abf6c6abde12fc5149c Related: SYS#3610 --- A openbsc/contrib/systemd/osmo-gbproxy.service 1 file changed, 12 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/19/2419/1 diff --git a/openbsc/contrib/systemd/osmo-gbproxy.service b/openbsc/contrib/systemd/osmo-gbproxy.service new file mode 100644 index 0000000..a0b7829 --- /dev/null +++ b/openbsc/contrib/systemd/osmo-gbproxy.service @@ -0,0 +1,12 @@ +[Unit] +Description=Osmocom Gb proxy + +[Service] +Type=simple +ExecStart=/usr/bin/osmo-gbproxy -c /etc/osmocom/osmo-gbproxy.cfg +Restart=always +RestartSec=2 +RestartPreventExitStatus=1 + +[Install] +WantedBy=multi-user.target -- To view, visit https://gerrit.osmocom.org/2419 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ic8144777a77efce4bad44abf6c6abde12fc5149c Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Max From gerrit-no-reply at lists.osmocom.org Wed Apr 26 16:02:41 2017 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Wed, 26 Apr 2017 16:02:41 +0000 Subject: libosmo-netif[master]: osmux: Use osmo_gettimeofday for testing puroposes In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 yay! \o/ -- To view, visit https://gerrit.osmocom.org/2418 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ic39cab74400aca8262a00c0d06884230b1a15ca3 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Pau Espin Pedrol Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Wed Apr 26 17:47:44 2017 From: gerrit-no-reply at lists.osmocom.org (Holger Freyther) Date: Wed, 26 Apr 2017 17:47:44 +0000 Subject: libosmocore[master]: Add osmo_rand() function In-Reply-To: References: Message-ID: Patch Set 2: > Sure, that's why getrandom has GRND_NONBLOCK flag and return value > indicating actual number of random bits returned. The consensus (as > I recall it) was to use osmo_rand() for "small" things like tmsi > (with fallback to currently used insecure rand()). The "big" things > are only necessary for crypto-related primitives which can use smth > like gnutls directly. This got to be thoroughly documented of > course. Okay but then at least seed rand with good crypto on start. But by using the kernel for every request you will get to the -EWOULDBLOCK situation a lot earlier. Something that OpenSSL/GNUtls with their KDF are less prone of. The time for a NONCE to repeat with the KDF is probably also higher (but I am out of my area of expertise here). >From an engineer point of view. My SIP code got stuck as I used /dev/urandom to generate a unique call id. And everytime I remotely logged in through VSAT I generated enough entropy to make it continue... Just keep it in mind. :) -- To view, visit https://gerrit.osmocom.org/1526 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I0241b814ea4c4ce1458f7ad76e31d390383c2048 Gerrit-PatchSet: 2 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From admin at opensuse.org Wed Apr 26 19:56:10 2017 From: admin at opensuse.org (OBS Notification) Date: Wed, 26 Apr 2017 19:56:10 +0000 Subject: Build failure of network:osmocom:nightly/libosmo-netif in xUbuntu_17.04/i586 In-Reply-To: References: Message-ID: <5900fb723ecc_1bc39c0f7c4541c7@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/libosmo-netif/xUbuntu_17.04/i586 Package network:osmocom:nightly/libosmo-netif failed to build in xUbuntu_17.04/i586 Check out the package for editing: osc checkout network:osmocom:nightly libosmo-netif Last lines of build log: [ 56s] make[5]: Entering directory '/usr/src/packages/BUILD' [ 56s] make[5]: Nothing to be done for 'install-data-hook'. [ 56s] make[5]: Leaving directory '/usr/src/packages/BUILD' [ 56s] make[4]: Leaving directory '/usr/src/packages/BUILD' [ 56s] make[3]: Leaving directory '/usr/src/packages/BUILD' [ 56s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 56s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 56s] debian/rules override_dh_install [ 56s] make[1]: Entering directory '/usr/src/packages/BUILD' [ 56s] sed -i "/dependency_libs/ s/'.*'/''/" `find . -name '*.la'` [ 56s] dh_install [ 56s] dh_install: Cannot find (any matches for) "usr/share/doc/libosmo-netif/*" (tried in "." and "debian/tmp") [ 56s] dh_install: libosmo-netif-doc missing files: usr/share/doc/libosmo-netif/* [ 56s] dh_install: missing files, aborting [ 56s] debian/rules:23: recipe for target 'override_dh_install' failed [ 56s] make[1]: *** [override_dh_install] Error 2 [ 56s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 56s] debian/rules:13: recipe for target 'binary' failed [ 56s] make: *** [binary] Error 2 [ 56s] dpkg-buildpackage: error: fakeroot debian/rules binary gave error exit status 2 [ 56s] [ 56s] build78 failed "build libosmo-netif_0.0.7.20170426.dsc" at Wed Apr 26 19:55:57 UTC 2017. [ 56s] [ 56s] ### VM INTERACTION START ### [ 59s] [ 50.903705] reboot: Power down [ 59s] ### VM INTERACTION END ### [ 59s] [ 59s] build78 failed "build libosmo-netif_0.0.7.20170426.dsc" at Wed Apr 26 19:56:00 UTC 2017. [ 59s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Wed Apr 26 19:55:53 2017 From: admin at opensuse.org (OBS Notification) Date: Wed, 26 Apr 2017 19:55:53 +0000 Subject: Build failure of network:osmocom:nightly/libosmo-netif in xUbuntu_16.10/i586 In-Reply-To: References: Message-ID: <5900fb70f10f8_1bc39c0f7c4540d8@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/libosmo-netif/xUbuntu_16.10/i586 Package network:osmocom:nightly/libosmo-netif failed to build in xUbuntu_16.10/i586 Check out the package for editing: osc checkout network:osmocom:nightly libosmo-netif Last lines of build log: [ 97s] make[5]: Entering directory '/usr/src/packages/BUILD' [ 97s] make[5]: Nothing to be done for 'install-data-hook'. [ 97s] make[5]: Leaving directory '/usr/src/packages/BUILD' [ 97s] make[4]: Leaving directory '/usr/src/packages/BUILD' [ 97s] make[3]: Leaving directory '/usr/src/packages/BUILD' [ 97s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 97s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 97s] debian/rules override_dh_install [ 97s] make[1]: Entering directory '/usr/src/packages/BUILD' [ 97s] sed -i "/dependency_libs/ s/'.*'/''/" `find . -name '*.la'` [ 97s] dh_install [ 97s] dh_install: Cannot find (any matches for) "usr/share/doc/libosmo-netif/*" (tried in "." and "debian/tmp") [ 97s] dh_install: libosmo-netif-doc missing files: usr/share/doc/libosmo-netif/* [ 97s] dh_install: missing files, aborting [ 97s] debian/rules:23: recipe for target 'override_dh_install' failed [ 97s] make[1]: *** [override_dh_install] Error 2 [ 97s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 97s] debian/rules:13: recipe for target 'binary' failed [ 97s] make: *** [binary] Error 2 [ 97s] dpkg-buildpackage: error: fakeroot debian/rules binary gave error exit status 2 [ 97s] [ 97s] lamb64 failed "build libosmo-netif_0.0.7.20170426.dsc" at Wed Apr 26 19:55:32 UTC 2017. [ 97s] [ 97s] ### VM INTERACTION START ### [ 100s] [ 86.882381] reboot: Power down [ 100s] ### VM INTERACTION END ### [ 100s] [ 100s] lamb64 failed "build libosmo-netif_0.0.7.20170426.dsc" at Wed Apr 26 19:55:36 UTC 2017. [ 100s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Wed Apr 26 19:56:54 2017 From: admin at opensuse.org (OBS Notification) Date: Wed, 26 Apr 2017 19:56:54 +0000 Subject: Build failure of network:osmocom:nightly/libosmo-netif in Debian_8.0/i586 In-Reply-To: References: Message-ID: <5900fb92dd9c0_1bc99c0f7c4608c2@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/libosmo-netif/Debian_8.0/i586 Package network:osmocom:nightly/libosmo-netif failed to build in Debian_8.0/i586 Check out the package for editing: osc checkout network:osmocom:nightly libosmo-netif Last lines of build log: [ 105s] make install-data-hook [ 105s] make[5]: Entering directory '/usr/src/packages/BUILD' [ 105s] make[5]: Nothing to be done for 'install-data-hook'. [ 105s] make[5]: Leaving directory '/usr/src/packages/BUILD' [ 105s] make[4]: Leaving directory '/usr/src/packages/BUILD' [ 105s] make[3]: Leaving directory '/usr/src/packages/BUILD' [ 105s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 105s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 105s] debian/rules override_dh_install [ 105s] make[1]: Entering directory '/usr/src/packages/BUILD' [ 105s] sed -i "/dependency_libs/ s/'.*'/''/" `find . -name '*.la'` [ 105s] dh_install [ 105s] dh_install: libosmo-netif-doc missing files (usr/share/doc/libosmo-netif/*), aborting [ 105s] debian/rules:23: recipe for target 'override_dh_install' failed [ 105s] make[1]: *** [override_dh_install] Error 2 [ 105s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 105s] debian/rules:13: recipe for target 'binary' failed [ 105s] make: *** [binary] Error 2 [ 105s] dpkg-buildpackage: error: fakeroot debian/rules binary gave error exit status 2 [ 105s] [ 105s] lamb57 failed "build libosmo-netif_0.0.7.20170426.dsc" at Wed Apr 26 19:56:35 UTC 2017. [ 105s] [ 105s] ### VM INTERACTION START ### [ 106s] Powering off. [ 106s] [ 92.532247] reboot: Power down [ 107s] ### VM INTERACTION END ### [ 107s] [ 107s] lamb57 failed "build libosmo-netif_0.0.7.20170426.dsc" at Wed Apr 26 19:56:37 UTC 2017. [ 107s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Wed Apr 26 19:57:02 2017 From: admin at opensuse.org (OBS Notification) Date: Wed, 26 Apr 2017 19:57:02 +0000 Subject: Build failure of network:osmocom:nightly/libosmo-netif in xUbuntu_16.04/i586 In-Reply-To: References: Message-ID: <5900fb935c85f_1bc99c0f7c4609f2@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/libosmo-netif/xUbuntu_16.04/i586 Package network:osmocom:nightly/libosmo-netif failed to build in xUbuntu_16.04/i586 Check out the package for editing: osc checkout network:osmocom:nightly libosmo-netif Last lines of build log: [ 127s] make install-data-hook [ 127s] make[5]: Entering directory '/usr/src/packages/BUILD' [ 127s] make[5]: Nothing to be done for 'install-data-hook'. [ 127s] make[5]: Leaving directory '/usr/src/packages/BUILD' [ 127s] make[4]: Leaving directory '/usr/src/packages/BUILD' [ 127s] make[3]: Leaving directory '/usr/src/packages/BUILD' [ 127s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 127s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 127s] debian/rules override_dh_install [ 127s] make[1]: Entering directory '/usr/src/packages/BUILD' [ 127s] sed -i "/dependency_libs/ s/'.*'/''/" `find . -name '*.la'` [ 127s] dh_install [ 127s] dh_install: libosmo-netif-doc missing files: usr/share/doc/libosmo-netif/* [ 127s] dh_install: missing files, aborting [ 127s] debian/rules:23: recipe for target 'override_dh_install' failed [ 127s] make[1]: *** [override_dh_install] Error 2 [ 127s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 127s] debian/rules:13: recipe for target 'binary' failed [ 127s] make: *** [binary] Error 2 [ 127s] dpkg-buildpackage: error: fakeroot debian/rules binary gave error exit status 2 [ 127s] [ 127s] lamb06 failed "build libosmo-netif_0.0.7.20170426.dsc" at Wed Apr 26 19:56:51 UTC 2017. [ 127s] [ 127s] ### VM INTERACTION START ### [ 131s] [ 118.337905] reboot: Power down [ 131s] ### VM INTERACTION END ### [ 131s] [ 131s] lamb06 failed "build libosmo-netif_0.0.7.20170426.dsc" at Wed Apr 26 19:56:55 UTC 2017. [ 131s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Wed Apr 26 19:57:19 2017 From: admin at opensuse.org (OBS Notification) Date: Wed, 26 Apr 2017 19:57:19 +0000 Subject: Build failure of network:osmocom:nightly/libosmo-netif in Debian_8.0/x86_64 In-Reply-To: References: Message-ID: <5900fbae105f3_1bc99c0f7c4610da@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/libosmo-netif/Debian_8.0/x86_64 Package network:osmocom:nightly/libosmo-netif failed to build in Debian_8.0/x86_64 Check out the package for editing: osc checkout network:osmocom:nightly libosmo-netif Last lines of build log: [ 65s] make install-data-hook [ 65s] make[5]: Entering directory '/usr/src/packages/BUILD' [ 65s] make[5]: Nothing to be done for 'install-data-hook'. [ 65s] make[5]: Leaving directory '/usr/src/packages/BUILD' [ 65s] make[4]: Leaving directory '/usr/src/packages/BUILD' [ 65s] make[3]: Leaving directory '/usr/src/packages/BUILD' [ 65s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 65s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 65s] debian/rules override_dh_install [ 65s] make[1]: Entering directory '/usr/src/packages/BUILD' [ 65s] sed -i "/dependency_libs/ s/'.*'/''/" `find . -name '*.la'` [ 65s] dh_install [ 65s] dh_install: libosmo-netif-doc missing files (usr/share/doc/libosmo-netif/*), aborting [ 65s] debian/rules:23: recipe for target 'override_dh_install' failed [ 65s] make[1]: *** [override_dh_install] Error 2 [ 65s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 65s] debian/rules:13: recipe for target 'binary' failed [ 65s] make: *** [binary] Error 2 [ 65s] dpkg-buildpackage: error: fakeroot debian/rules binary gave error exit status 2 [ 65s] [ 65s] build71 failed "build libosmo-netif_0.0.7.20170426.dsc" at Wed Apr 26 19:57:03 UTC 2017. [ 65s] [ 65s] ### VM INTERACTION START ### [ 66s] Powering off. [ 66s] [ 57.796111] reboot: Power down [ 67s] ### VM INTERACTION END ### [ 67s] [ 67s] build71 failed "build libosmo-netif_0.0.7.20170426.dsc" at Wed Apr 26 19:57:05 UTC 2017. [ 67s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Wed Apr 26 19:57:36 2017 From: admin at opensuse.org (OBS Notification) Date: Wed, 26 Apr 2017 19:57:36 +0000 Subject: Build failure of network:osmocom:nightly/libosmo-netif in xUbuntu_17.04/x86_64 In-Reply-To: References: Message-ID: <5900fbca8bfb8_1bc39c0f7c4542ee@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/libosmo-netif/xUbuntu_17.04/x86_64 Package network:osmocom:nightly/libosmo-netif failed to build in xUbuntu_17.04/x86_64 Check out the package for editing: osc checkout network:osmocom:nightly libosmo-netif Last lines of build log: [ 98s] make[5]: Entering directory '/usr/src/packages/BUILD' [ 98s] make[5]: Nothing to be done for 'install-data-hook'. [ 98s] make[5]: Leaving directory '/usr/src/packages/BUILD' [ 98s] make[4]: Leaving directory '/usr/src/packages/BUILD' [ 98s] make[3]: Leaving directory '/usr/src/packages/BUILD' [ 98s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 98s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 98s] debian/rules override_dh_install [ 98s] make[1]: Entering directory '/usr/src/packages/BUILD' [ 99s] sed -i "/dependency_libs/ s/'.*'/''/" `find . -name '*.la'` [ 99s] dh_install [ 99s] dh_install: Cannot find (any matches for) "usr/share/doc/libosmo-netif/*" (tried in "." and "debian/tmp") [ 99s] dh_install: libosmo-netif-doc missing files: usr/share/doc/libosmo-netif/* [ 99s] dh_install: missing files, aborting [ 99s] debian/rules:23: recipe for target 'override_dh_install' failed [ 99s] make[1]: *** [override_dh_install] Error 2 [ 99s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 99s] debian/rules:13: recipe for target 'binary' failed [ 99s] make: *** [binary] Error 2 [ 99s] dpkg-buildpackage: error: fakeroot debian/rules binary gave error exit status 2 [ 99s] [ 99s] lamb14 failed "build libosmo-netif_0.0.7.20170426.dsc" at Wed Apr 26 19:57:21 UTC 2017. [ 99s] [ 99s] ### VM INTERACTION START ### [ 102s] [ 88.131037] reboot: Power down [ 102s] ### VM INTERACTION END ### [ 102s] [ 102s] lamb14 failed "build libosmo-netif_0.0.7.20170426.dsc" at Wed Apr 26 19:57:25 UTC 2017. [ 102s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Wed Apr 26 19:57:36 2017 From: admin at opensuse.org (OBS Notification) Date: Wed, 26 Apr 2017 19:57:36 +0000 Subject: Build failure of network:osmocom:nightly/libosmo-netif in xUbuntu_16.04/x86_64 In-Reply-To: References: Message-ID: <5900fbcac440c_1bc39c0f7c4543e8@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/libosmo-netif/xUbuntu_16.04/x86_64 Package network:osmocom:nightly/libosmo-netif failed to build in xUbuntu_16.04/x86_64 Check out the package for editing: osc checkout network:osmocom:nightly libosmo-netif Last lines of build log: [ 114s] make install-data-hook [ 114s] make[5]: Entering directory '/usr/src/packages/BUILD' [ 114s] make[5]: Nothing to be done for 'install-data-hook'. [ 114s] make[5]: Leaving directory '/usr/src/packages/BUILD' [ 114s] make[4]: Leaving directory '/usr/src/packages/BUILD' [ 114s] make[3]: Leaving directory '/usr/src/packages/BUILD' [ 114s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 114s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 114s] debian/rules override_dh_install [ 114s] make[1]: Entering directory '/usr/src/packages/BUILD' [ 114s] sed -i "/dependency_libs/ s/'.*'/''/" `find . -name '*.la'` [ 114s] dh_install [ 114s] dh_install: libosmo-netif-doc missing files: usr/share/doc/libosmo-netif/* [ 114s] dh_install: missing files, aborting [ 114s] debian/rules:23: recipe for target 'override_dh_install' failed [ 114s] make[1]: *** [override_dh_install] Error 2 [ 114s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 114s] debian/rules:13: recipe for target 'binary' failed [ 114s] make: *** [binary] Error 2 [ 114s] dpkg-buildpackage: error: fakeroot debian/rules binary gave error exit status 2 [ 114s] [ 114s] lamb26 failed "build libosmo-netif_0.0.7.20170426.dsc" at Wed Apr 26 19:57:24 UTC 2017. [ 114s] [ 114s] ### VM INTERACTION START ### [ 117s] [ 104.731880] reboot: Power down [ 117s] ### VM INTERACTION END ### [ 117s] [ 117s] lamb26 failed "build libosmo-netif_0.0.7.20170426.dsc" at Wed Apr 26 19:57:27 UTC 2017. [ 117s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Wed Apr 26 19:57:36 2017 From: admin at opensuse.org (OBS Notification) Date: Wed, 26 Apr 2017 19:57:36 +0000 Subject: Build failure of network:osmocom:nightly/libosmo-netif in xUbuntu_16.10/x86_64 In-Reply-To: References: Message-ID: <5900fbcb1ba7c_1bc39c0f7c454441@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/libosmo-netif/xUbuntu_16.10/x86_64 Package network:osmocom:nightly/libosmo-netif failed to build in xUbuntu_16.10/x86_64 Check out the package for editing: osc checkout network:osmocom:nightly libosmo-netif Last lines of build log: [ 124s] make install-data-hook [ 124s] make[5]: Entering directory '/usr/src/packages/BUILD' [ 124s] make[5]: Nothing to be done for 'install-data-hook'. [ 124s] make[5]: Leaving directory '/usr/src/packages/BUILD' [ 124s] make[4]: Leaving directory '/usr/src/packages/BUILD' [ 124s] make[3]: Leaving directory '/usr/src/packages/BUILD' [ 124s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 124s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 124s] debian/rules override_dh_install [ 124s] make[1]: Entering directory '/usr/src/packages/BUILD' [ 125s] sed -i "/dependency_libs/ s/'.*'/''/" `find . -name '*.la'` [ 125s] dh_install [ 125s] dh_install: Cannot find (any matches for) "usr/share/doc/libosmo-netif/*" (tried in "." and "debian/tmp") [ 125s] dh_install: libosmo-netif-doc missing files: usr/share/doc/libosmo-netif/* [ 125s] dh_install: missing files, aborting [ 125s] debian/rules:23: recipe for target 'override_dh_install' failed [ 125s] make[1]: *** [override_dh_install] Error 2 [ 125s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 125s] debian/rules:13: recipe for target 'binary' failed [ 125s] make: *** [binary] Error 2 [ 125s] dpkg-buildpackage: error: fakeroot debian/rules binary gave error exit status 2 [ 125s] [ 125s] cloud101 failed "build libosmo-netif_0.0.7.20170426.dsc" at Wed Apr 26 19:57:23 UTC 2017. [ 125s] [ 125s] ### VM INTERACTION START ### [ 129s] ### VM INTERACTION END ### [ 129s] [ 129s] cloud101 failed "build libosmo-netif_0.0.7.20170426.dsc" at Wed Apr 26 19:57:27 UTC 2017. [ 129s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Wed Apr 26 19:58:44 2017 From: admin at opensuse.org (OBS Notification) Date: Wed, 26 Apr 2017 19:58:44 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in xUbuntu_16.10/i586 In-Reply-To: References: Message-ID: <5900fc24a7d5b_1e2461ef7c3604aa@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/xUbuntu_16.10/i586 Package network:osmocom:nightly/osmo-stp failed to build in xUbuntu_16.10/i586 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 75s] ^~~~~~~ [ 75s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o vty_interface.o vty_interface.c [ 76s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o sctp_m3ua_client.o sctp_m3ua_client.c [ 76s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 76s] #include [ 76s] ^ [ 76s] compilation terminated. [ 76s] Makefile:485: recipe for target 'sctp_m3ua_client.o' failed [ 76s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 76s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 76s] Makefile:380: recipe for target 'all-recursive' failed [ 76s] make[2]: *** [all-recursive] Error 1 [ 76s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 76s] Makefile:321: recipe for target 'all' failed [ 76s] make[1]: *** [all] Error 2 [ 76s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 76s] dh_auto_build: make -j1 returned exit code 2 [ 76s] debian/rules:23: recipe for target 'build' failed [ 76s] make: *** [build] Error 2 [ 76s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 76s] [ 76s] lamb18 failed "build cellmgr-ng_1.4.7.20170426.dsc" at Wed Apr 26 19:58:26 UTC 2017. [ 76s] [ 76s] ### VM INTERACTION START ### [ 79s] [ 66.171622] reboot: Power down [ 79s] ### VM INTERACTION END ### [ 79s] [ 79s] lamb18 failed "build cellmgr-ng_1.4.7.20170426.dsc" at Wed Apr 26 19:58:30 UTC 2017. [ 79s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Wed Apr 26 20:00:27 2017 From: admin at opensuse.org (OBS Notification) Date: Wed, 26 Apr 2017 20:00:27 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in xUbuntu_17.04/i586 In-Reply-To: References: Message-ID: <5900fc647c39e_1bbd9c0f7c4313d5@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/xUbuntu_17.04/i586 Package network:osmocom:nightly/osmo-stp failed to build in xUbuntu_17.04/i586 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 75s] ^~~~~~~ [ 75s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o vty_interface.o vty_interface.c [ 76s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o sctp_m3ua_client.o sctp_m3ua_client.c [ 76s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 76s] #include [ 76s] ^ [ 76s] compilation terminated. [ 76s] Makefile:485: recipe for target 'sctp_m3ua_client.o' failed [ 76s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 76s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 76s] Makefile:380: recipe for target 'all-recursive' failed [ 76s] make[2]: *** [all-recursive] Error 1 [ 76s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 76s] Makefile:321: recipe for target 'all' failed [ 76s] make[1]: *** [all] Error 2 [ 76s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 76s] dh_auto_build: make -j1 returned exit code 2 [ 76s] debian/rules:23: recipe for target 'build' failed [ 76s] make: *** [build] Error 2 [ 76s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 76s] [ 76s] lamb09 failed "build cellmgr-ng_1.4.7.20170426.dsc" at Wed Apr 26 20:00:16 UTC 2017. [ 76s] [ 76s] ### VM INTERACTION START ### [ 79s] [ 65.476433] reboot: Power down [ 79s] ### VM INTERACTION END ### [ 79s] [ 79s] lamb09 failed "build cellmgr-ng_1.4.7.20170426.dsc" at Wed Apr 26 20:00:19 UTC 2017. [ 79s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Wed Apr 26 20:00:44 2017 From: admin at opensuse.org (OBS Notification) Date: Wed, 26 Apr 2017 20:00:44 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in Debian_8.0/i586 In-Reply-To: References: Message-ID: <5900fc8062a1d_1bbd9c0f7c4314d4@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/Debian_8.0/i586 Package network:osmocom:nightly/osmo-stp failed to build in Debian_8.0/i586 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 88s] CC vty_interface.o [ 89s] CC sctp_m3ua_client.o [ 89s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 89s] #include [ 89s] ^ [ 89s] compilation terminated. [ 89s] Makefile:475: recipe for target 'sctp_m3ua_client.o' failed [ 89s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 89s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 89s] Makefile:370: recipe for target 'all-recursive' failed [ 89s] make[2]: *** [all-recursive] Error 1 [ 89s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 89s] Makefile:310: recipe for target 'all' failed [ 89s] make[1]: *** [all] Error 2 [ 89s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 89s] dh_auto_build: make -j1 returned exit code 2 [ 89s] debian/rules:23: recipe for target 'build' failed [ 89s] make: *** [build] Error 2 [ 89s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 89s] [ 89s] lamb52 failed "build cellmgr-ng_1.4.7.20170426.dsc" at Wed Apr 26 20:00:27 UTC 2017. [ 89s] [ 89s] ### VM INTERACTION START ### [ 90s] Powering off. [ 90s] [ 76.338182] reboot: Power down [ 90s] ### VM INTERACTION END ### [ 90s] [ 90s] lamb52 failed "build cellmgr-ng_1.4.7.20170426.dsc" at Wed Apr 26 20:00:29 UTC 2017. [ 90s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Wed Apr 26 20:01:02 2017 From: admin at opensuse.org (OBS Notification) Date: Wed, 26 Apr 2017 20:01:02 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in Debian_8.0/x86_64 In-Reply-To: References: Message-ID: <5900fc8175e42_1bbd9c0f7c43157@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/Debian_8.0/x86_64 Package network:osmocom:nightly/osmo-stp failed to build in Debian_8.0/x86_64 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 88s] CC vty_interface.o [ 89s] CC sctp_m3ua_client.o [ 89s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 89s] #include [ 89s] ^ [ 89s] compilation terminated. [ 89s] Makefile:475: recipe for target 'sctp_m3ua_client.o' failed [ 89s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 89s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 89s] Makefile:370: recipe for target 'all-recursive' failed [ 89s] make[2]: *** [all-recursive] Error 1 [ 89s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 89s] Makefile:310: recipe for target 'all' failed [ 89s] make[1]: *** [all] Error 2 [ 89s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 89s] dh_auto_build: make -j1 returned exit code 2 [ 89s] debian/rules:23: recipe for target 'build' failed [ 89s] make: *** [build] Error 2 [ 89s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 89s] [ 89s] lamb21 failed "build cellmgr-ng_1.4.7.20170426.dsc" at Wed Apr 26 20:00:49 UTC 2017. [ 89s] [ 89s] ### VM INTERACTION START ### [ 90s] Powering off. [ 90s] [ 76.599249] reboot: Power down [ 90s] ### VM INTERACTION END ### [ 90s] [ 90s] lamb21 failed "build cellmgr-ng_1.4.7.20170426.dsc" at Wed Apr 26 20:00:51 UTC 2017. [ 90s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Wed Apr 26 20:01:19 2017 From: admin at opensuse.org (OBS Notification) Date: Wed, 26 Apr 2017 20:01:19 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in xUbuntu_16.10/x86_64 In-Reply-To: References: Message-ID: <5900fc9bcf924_1bc39c0f7c454549@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/xUbuntu_16.10/x86_64 Package network:osmocom:nightly/osmo-stp failed to build in xUbuntu_16.10/x86_64 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 74s] ^~~~~~~ [ 74s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o vty_interface.o vty_interface.c [ 75s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o sctp_m3ua_client.o sctp_m3ua_client.c [ 75s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 75s] #include [ 75s] ^ [ 75s] compilation terminated. [ 75s] Makefile:485: recipe for target 'sctp_m3ua_client.o' failed [ 75s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 75s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 75s] Makefile:380: recipe for target 'all-recursive' failed [ 75s] make[2]: *** [all-recursive] Error 1 [ 75s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 75s] Makefile:321: recipe for target 'all' failed [ 75s] make[1]: *** [all] Error 2 [ 75s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 75s] dh_auto_build: make -j1 returned exit code 2 [ 75s] debian/rules:23: recipe for target 'build' failed [ 75s] make: *** [build] Error 2 [ 75s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 75s] [ 75s] lamb19 failed "build cellmgr-ng_1.4.7.20170426.dsc" at Wed Apr 26 20:01:02 UTC 2017. [ 75s] [ 75s] ### VM INTERACTION START ### [ 78s] [ 64.869365] reboot: Power down [ 78s] ### VM INTERACTION END ### [ 78s] [ 78s] lamb19 failed "build cellmgr-ng_1.4.7.20170426.dsc" at Wed Apr 26 20:01:06 UTC 2017. [ 78s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Wed Apr 26 20:01:19 2017 From: admin at opensuse.org (OBS Notification) Date: Wed, 26 Apr 2017 20:01:19 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in xUbuntu_16.04/i586 In-Reply-To: References: Message-ID: <5900fcbfeb356_1bc99c0f7c4611b3@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/xUbuntu_16.04/i586 Package network:osmocom:nightly/osmo-stp failed to build in xUbuntu_16.04/i586 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 93s] sctp_m2ua.c:91:3: warning: #warning "Notify any other AS(P) for failover scenario" [-Wcpp] [ 93s] #warning "Notify any other AS(P) for failover scenario" [ 93s] ^ [ 94s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -c -o vty_interface.o vty_interface.c [ 94s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -c -o sctp_m3ua_client.o sctp_m3ua_client.c [ 94s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 94s] compilation terminated. [ 94s] Makefile:485: recipe for target 'sctp_m3ua_client.o' failed [ 94s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 94s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 94s] Makefile:380: recipe for target 'all-recursive' failed [ 94s] make[2]: *** [all-recursive] Error 1 [ 94s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 94s] Makefile:321: recipe for target 'all' failed [ 94s] make[1]: *** [all] Error 2 [ 94s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 94s] dh_auto_build: make -j1 returned exit code 2 [ 94s] debian/rules:23: recipe for target 'build' failed [ 94s] make: *** [build] Error 2 [ 94s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 94s] [ 94s] lamb16 failed "build cellmgr-ng_1.4.7.20170426.dsc" at Wed Apr 26 20:01:14 UTC 2017. [ 94s] [ 94s] ### VM INTERACTION START ### [ 97s] [ 85.129583] reboot: Power down [ 97s] ### VM INTERACTION END ### [ 97s] [ 97s] lamb16 failed "build cellmgr-ng_1.4.7.20170426.dsc" at Wed Apr 26 20:01:17 UTC 2017. [ 97s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Wed Apr 26 20:02:27 2017 From: admin at opensuse.org (OBS Notification) Date: Wed, 26 Apr 2017 20:02:27 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in xUbuntu_16.04/x86_64 In-Reply-To: References: Message-ID: <5900fcf1dc3e2_1e2461ef7c360997@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/xUbuntu_16.04/x86_64 Package network:osmocom:nightly/osmo-stp failed to build in xUbuntu_16.04/x86_64 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 95s] sctp_m2ua.c:91:3: warning: #warning "Notify any other AS(P) for failover scenario" [-Wcpp] [ 95s] #warning "Notify any other AS(P) for failover scenario" [ 95s] ^ [ 95s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -c -o vty_interface.o vty_interface.c [ 96s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -c -o sctp_m3ua_client.o sctp_m3ua_client.c [ 96s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 96s] compilation terminated. [ 96s] Makefile:485: recipe for target 'sctp_m3ua_client.o' failed [ 96s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 96s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 96s] Makefile:380: recipe for target 'all-recursive' failed [ 96s] make[2]: *** [all-recursive] Error 1 [ 96s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 96s] Makefile:321: recipe for target 'all' failed [ 96s] make[1]: *** [all] Error 2 [ 96s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 96s] dh_auto_build: make -j1 returned exit code 2 [ 96s] debian/rules:23: recipe for target 'build' failed [ 96s] make: *** [build] Error 2 [ 96s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 96s] [ 96s] lamb67 failed "build cellmgr-ng_1.4.7.20170426.dsc" at Wed Apr 26 20:02:23 UTC 2017. [ 96s] [ 96s] ### VM INTERACTION START ### [ 99s] [ 86.264892] reboot: Power down [ 99s] ### VM INTERACTION END ### [ 99s] [ 99s] lamb67 failed "build cellmgr-ng_1.4.7.20170426.dsc" at Wed Apr 26 20:02:26 UTC 2017. [ 99s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From admin at opensuse.org Wed Apr 26 20:02:48 2017 From: admin at opensuse.org (OBS Notification) Date: Wed, 26 Apr 2017 20:02:48 +0000 Subject: Build failure of network:osmocom:nightly/osmo-stp in xUbuntu_17.04/x86_64 In-Reply-To: References: Message-ID: <5900fcf2a68ad_1e2461ef7c361131@build.opensuse.org> Visit https://build.opensuse.org/package/live_build_log/network:osmocom:nightly/osmo-stp/xUbuntu_17.04/x86_64 Package network:osmocom:nightly/osmo-stp failed to build in xUbuntu_17.04/x86_64 Check out the package for editing: osc checkout network:osmocom:nightly osmo-stp Last lines of build log: [ 103s] ^~~~~~~ [ 103s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o vty_interface.o vty_interface.c [ 104s] gcc -DHAVE_CONFIG_H -I. -I.. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -I/usr/include/ -I/usr/include/ -I/usr/include/ -I/usr/include/ -DNO_UNIPORTE -g -O2 -fdebug-prefix-map=/usr/src/packages/BUILD=. -fstack-protector-strong -Wformat -Werror=format-security -c -o sctp_m3ua_client.o sctp_m3ua_client.c [ 104s] sctp_m3ua_client.c:25:40: fatal error: osmocom/sigtran/m3ua_types.h: No such file or directory [ 104s] #include [ 104s] ^ [ 104s] compilation terminated. [ 104s] Makefile:485: recipe for target 'sctp_m3ua_client.o' failed [ 104s] make[3]: *** [sctp_m3ua_client.o] Error 1 [ 104s] make[3]: Leaving directory '/usr/src/packages/BUILD/src' [ 104s] Makefile:380: recipe for target 'all-recursive' failed [ 104s] make[2]: *** [all-recursive] Error 1 [ 104s] make[2]: Leaving directory '/usr/src/packages/BUILD' [ 104s] Makefile:321: recipe for target 'all' failed [ 104s] make[1]: *** [all] Error 2 [ 104s] make[1]: Leaving directory '/usr/src/packages/BUILD' [ 104s] dh_auto_build: make -j1 returned exit code 2 [ 104s] debian/rules:23: recipe for target 'build' failed [ 104s] make: *** [build] Error 2 [ 104s] dpkg-buildpackage: error: debian/rules build gave error exit status 2 [ 104s] [ 104s] cloud122 failed "build cellmgr-ng_1.4.7.20170426.dsc" at Wed Apr 26 20:02:22 UTC 2017. [ 104s] [ 104s] ### VM INTERACTION START ### [ 107s] [ 84.731513] reboot: Power down [ 112s] ### VM INTERACTION END ### [ 112s] [ 112s] cloud122 failed "build cellmgr-ng_1.4.7.20170426.dsc" at Wed Apr 26 20:02:30 UTC 2017. [ 112s] -- Configure notifications at https://build.opensuse.org/user/notifications openSUSE Build Service (https://build.opensuse.org/) From gerrit-no-reply at lists.osmocom.org Wed Apr 26 23:52:13 2017 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Wed, 26 Apr 2017 23:52:13 +0000 Subject: [PATCH] osmo-pcu[master]: fix PACCH paging: don't return early in case of NULL TBF Message-ID: Review at https://gerrit.osmocom.org/2420 fix PACCH paging: don't return early in case of NULL TBF Commit b78a4a6dfef217c538d45949a6ae725e22a36b05 tried to fix a NULL dereference error, but apparently was overly eager to return, because it looked like all code paths would dereference the tbf. In fact the code path further above, for msg != NULL, has "always" dereferenced the tbf, but the lower code path, the one effecting the paging, has only started to dereference tbf since shortly before the overly eager fix: in da7250ad2c1cd5ddc7d3c6e10435a00b357ef8f7, to "update the dl ctrl msg counter for ms". It seems that this tbf dereference in the paging path is bogus and the cause for the segfault that made me write the early exit fix. Fix that fix: Do not exit early if tbf == NULL, stay in there to be able to reach the paging path below. In case of a message to be sent, assume that tbf is present, and verify: print an error message and abort if there is a msg but no tbf, so that we will see the error if I'm wrong there. In case of no message, go on to send pending pagings, but do not attempt to count ctrl messages for a tbf -- IIUC there will never be a tbf if we're paging. This should avoid segfaults while keeping PACCH paging intact. Tweak a log message for and add a blank line above paging section. Related: OS#2176 CID#158969 Change-Id: Ib79f4a945e211a13ac7d1e511cc37b0940ac6202 --- M src/gprs_rlcmac_sched.cpp 1 file changed, 7 insertions(+), 7 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-pcu refs/changes/20/2420/1 diff --git a/src/gprs_rlcmac_sched.cpp b/src/gprs_rlcmac_sched.cpp index 3b940f4..b40ff9a 100644 --- a/src/gprs_rlcmac_sched.cpp +++ b/src/gprs_rlcmac_sched.cpp @@ -178,11 +178,13 @@ } } - if (!tbf) - return NULL; - /* any message */ if (msg) { + if (!tbf) { + LOGP(DRLCMACSCHED, LOGL_ERROR, + "Control message to be scheduled, but no TBF (TRX=%d, TS=%d)\n", trx, ts); + return NULL; + } tbf->rotate_in_list(); LOGP(DRLCMACSCHED, LOGL_DEBUG, "Scheduling control " "message at RTS for %s (TRX=%d, TS=%d)\n", @@ -191,14 +193,12 @@ tbf->ms()->update_dl_ctrl_msg(); return msg; } - /* schedule PACKET PAGING REQUEST */ + + /* schedule PACKET PAGING REQUEST, if any are pending */ msg = pdch->packet_paging_request(); if (msg) { LOGP(DRLCMACSCHED, LOGL_DEBUG, "Scheduling paging request " "message at RTS for (TRX=%d, TS=%d)\n", trx, ts); - - /* Updates the dl ctrl msg counter for ms */ - tbf->ms()->update_dl_ctrl_msg(); return msg; } -- To view, visit https://gerrit.osmocom.org/2420 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ib79f4a945e211a13ac7d1e511cc37b0940ac6202 Gerrit-PatchSet: 1 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Thu Apr 27 02:37:34 2017 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 27 Apr 2017 02:37:34 +0000 Subject: [PATCH] osmo-pcu[master]: fix PACCH paging: don't return early in case of NULL TBF In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2420 to look at the new patch set (#2). fix PACCH paging: don't return early in case of NULL TBF Commit b78a4a6dfef217c538d45949a6ae725e22a36b05 tried to fix a NULL dereference error, but apparently was overly eager to return, because it looked like all code paths would dereference the tbf. In fact the code path further above, for msg != NULL, has "always" dereferenced the tbf, but the lower code path, the one effecting the paging, has only started to dereference tbf since shortly before the overly eager fix: in da7250ad2c1cd5ddc7d3c6e10435a00b357ef8f7, to "update the dl ctrl msg counter for ms". It seems that this tbf dereference in the paging path is bogus and the cause for the segfault that made me write the early exit fix. Fix that fix: Do not exit early if tbf == NULL, stay in there to be able to reach the paging path below. In case of a message to be sent, assume that tbf is present, and verify: print an error message and abort if there is a msg but no tbf, so that we will see the error if I'm wrong there. In case of no message, go on to send pending pagings, but do not attempt to count ctrl messages for a tbf -- IIUC there will never be a tbf if we're paging. This should avoid segfaults while keeping PACCH paging intact. Tweak a comment for and add a blank line above the paging section. Related: OS#2176 CID#158969 Change-Id: Ib79f4a945e211a13ac7d1e511cc37b0940ac6202 --- M src/gprs_rlcmac_sched.cpp 1 file changed, 7 insertions(+), 7 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-pcu refs/changes/20/2420/2 diff --git a/src/gprs_rlcmac_sched.cpp b/src/gprs_rlcmac_sched.cpp index 3b940f4..b40ff9a 100644 --- a/src/gprs_rlcmac_sched.cpp +++ b/src/gprs_rlcmac_sched.cpp @@ -178,11 +178,13 @@ } } - if (!tbf) - return NULL; - /* any message */ if (msg) { + if (!tbf) { + LOGP(DRLCMACSCHED, LOGL_ERROR, + "Control message to be scheduled, but no TBF (TRX=%d, TS=%d)\n", trx, ts); + return NULL; + } tbf->rotate_in_list(); LOGP(DRLCMACSCHED, LOGL_DEBUG, "Scheduling control " "message at RTS for %s (TRX=%d, TS=%d)\n", @@ -191,14 +193,12 @@ tbf->ms()->update_dl_ctrl_msg(); return msg; } - /* schedule PACKET PAGING REQUEST */ + + /* schedule PACKET PAGING REQUEST, if any are pending */ msg = pdch->packet_paging_request(); if (msg) { LOGP(DRLCMACSCHED, LOGL_DEBUG, "Scheduling paging request " "message at RTS for (TRX=%d, TS=%d)\n", trx, ts); - - /* Updates the dl ctrl msg counter for ms */ - tbf->ms()->update_dl_ctrl_msg(); return msg; } -- To view, visit https://gerrit.osmocom.org/2420 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ib79f4a945e211a13ac7d1e511cc37b0940ac6202 Gerrit-PatchSet: 2 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Thu Apr 27 02:41:51 2017 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 27 Apr 2017 02:41:51 +0000 Subject: osmo-gsm-manuals[master]: osmo-sgsn: fix arrow tips in flow diagrams In-Reply-To: References: Message-ID: Patch Set 5: Code-Review-1 wait, it's no longer changing the arrow tips, but now the arrow style? '->' becomes '=>' -- please reflect that in the commit log and maybe explain why. -- To view, visit https://gerrit.osmocom.org/2022 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I7faa0c97ee3705a64289a47bc63f311d05f988b3 Gerrit-PatchSet: 5 Gerrit-Project: osmo-gsm-manuals Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Apr 27 02:48:08 2017 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 27 Apr 2017 02:48:08 +0000 Subject: osmo-trx[master]: buildenv: Split up SSE3 and SSE4.1 code In-Reply-To: References: Message-ID: Patch Set 4: Code-Review+1 (1 comment) I possibly need this patch to be able to get a running binary for our osmo-gsm-tester main unit. Despite building --without-sse, I get an illegal instruction as soon as osmo-trx starts to access the SDR. Hopefully this fixes the problem. See https://osmocom.org/issues/1869#note-24 -- Tom, would you mind to review and possibly accept this? https://gerrit.osmocom.org/#/c/2134/4//COMMIT_MSG Commit Message: Line 11: compiler exidantly mixes SSE4.1 instructions into an SSE3, or funny typo :) accidently -- To view, visit https://gerrit.osmocom.org/2134 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I846e190e92f1258cd412d1b2d79b539e204e04b3 Gerrit-PatchSet: 4 Gerrit-Project: osmo-trx Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Thu Apr 27 07:19:35 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 27 Apr 2017 07:19:35 +0000 Subject: osmo-pcu[master]: fix PACCH paging: don't return early in case of NULL TBF In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2420 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ib79f4a945e211a13ac7d1e511cc37b0940ac6202 Gerrit-PatchSet: 2 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Apr 27 07:19:39 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 27 Apr 2017 07:19:39 +0000 Subject: osmo-pcu[master]: fix PACCH paging: don't return early in case of NULL TBF In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+1 -- To view, visit https://gerrit.osmocom.org/2420 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ib79f4a945e211a13ac7d1e511cc37b0940ac6202 Gerrit-PatchSet: 2 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Apr 27 07:20:04 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 27 Apr 2017 07:20:04 +0000 Subject: openbsc[master]: gbproxy: add example .service In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2419 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ic8144777a77efce4bad44abf6c6abde12fc5149c Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: daniel Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Apr 27 07:22:17 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 27 Apr 2017 07:22:17 +0000 Subject: libosmo-netif[master]: osmux: Add RTP marker bit support In-Reply-To: References: Message-ID: Patch Set 3: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2407 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I0315658159429603f1d80a168718b026015060e9 Gerrit-PatchSet: 3 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Pau Espin Pedrol Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: Pau Espin Pedrol Gerrit-Reviewer: daniel Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Apr 27 07:23:28 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 27 Apr 2017 07:23:28 +0000 Subject: libosmo-netif[master]: osmux: Check batch_factor overflow in osmux_batch_enqueue In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2403 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I5d643810949aeca4762f0cad05eed534d35087f7 Gerrit-PatchSet: 2 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Pau Espin Pedrol Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Pau Espin Pedrol Gerrit-Reviewer: daniel Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Apr 27 07:24:36 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 27 Apr 2017 07:24:36 +0000 Subject: libosmo-netif[master]: osmux: Use osmo_gettimeofday for testing puroposes In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+1 (1 comment) https://gerrit.osmocom.org/#/c/2418/1/tests/osmux/osmux_test.c File tests/osmux/osmux_test.c: Line 233: osmo_gettimeofday_override_add(0,PKT_TIME_USEC); minor coding style: missing space -- To view, visit https://gerrit.osmocom.org/2418 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ic39cab74400aca8262a00c0d06884230b1a15ca3 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Pau Espin Pedrol Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Thu Apr 27 07:25:49 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 27 Apr 2017 07:25:49 +0000 Subject: osmo-bts[master]: Add MS TO to RSL measurements In-Reply-To: References: Message-ID: Patch Set 6: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/1700 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I4dfe5c48834a083e757d5de3236a02e15a238b28 Gerrit-PatchSet: 6 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Alexander Chemeris Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Ivan Kluchnikov Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: dexter Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Apr 27 07:31:06 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 27 Apr 2017 07:31:06 +0000 Subject: libosmocore[master]: l1sap: Add frame-number to measurement indication struct In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2408 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I8c783b4a92ae2c3cc5d17936a146eb49d47eac37 Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Apr 27 07:32:45 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 27 Apr 2017 07:32:45 +0000 Subject: osmo-bts[master]: measurement: fix measurement reporting period In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2410 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I23fba50f48415314da40cf5bf86fce2ed3e66af6 Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Apr 27 07:33:07 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 27 Apr 2017 07:33:07 +0000 Subject: osmo-bts[master]: measurement: make lchan_meas_check_compute() available to l1... In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2411 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ideffe896613e0feda443bc13dac59dcdbbc605aa Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Apr 27 07:36:08 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 27 Apr 2017 07:36:08 +0000 Subject: osmo-bts[master]: measurement: fix measurement computation In-Reply-To: References: Message-ID: Patch Set 1: Code-Review-1 (1 comment) https://gerrit.osmocom.org/#/c/2412/1/src/common/measurement.c File src/common/measurement.c: Line 210: "Update TA TimingOffset_Mean:%d, UL RX TA:%d, DL ordered TA:%d, flags:%d \n", log statements here must include some kind of prefix for the lchan, otherwise you cannot know about which lchan they are logging information. We have gsm_lchan_name() for that, and it is used in other places. -- To view, visit https://gerrit.osmocom.org/2412 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I2e0dfd13b53e8aa2822985f12bf2985e683ab553 Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Thu Apr 27 07:38:25 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 27 Apr 2017 07:38:25 +0000 Subject: osmo-bts[master]: measurement: fix clearing of L1 info valid flag In-Reply-To: References: Message-ID: Patch Set 1: this should be merged into the previous patch, i.e. the one introducing clearing the flag in the new/different place. -- To view, visit https://gerrit.osmocom.org/2413 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ie511cba7927b4ab80a5b7551c39a253cee14eace Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Apr 27 07:40:18 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 27 Apr 2017 07:40:18 +0000 Subject: osmo-bts[master]: measurement: Compute measurement results on measurement idic... In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2414 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Iecb9a30c0d716bfc88221cd752b1ffdc74269e30 Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Apr 27 07:41:48 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 27 Apr 2017 07:41:48 +0000 Subject: [MERGED] osmo-bts[master]: Add MS TO to RSL measurements In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: Add MS TO to RSL measurements ...................................................................... Add MS TO to RSL measurements Add optional MS timing offset (3GPP TS 45.010 ? 1.2) to RSL MEASUREMENT RESULT (3GPP TS 48.058 ? 8.4.8). The value is calculated either directly from corresponding BTS measurement or from 3GPP TS 48.058 ? 9.3.17 Access Delay (for known TA) and is invalidated after RSL report is sent until new measurement indication or RACH is received. Change-Id: I4dfe5c48834a083e757d5de3236a02e15a238b28 Related: OS#1574 --- M src/common/l1sap.c M src/common/rsl.c 2 files changed, 44 insertions(+), 5 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/common/l1sap.c b/src/common/l1sap.c index 3592096..57a858c 100644 --- a/src/common/l1sap.c +++ b/src/common/l1sap.c @@ -431,6 +431,27 @@ return 0; } + +static inline void set_ms_to_data(struct gsm_lchan *lchan, int16_t data, bool set_ms_to) +{ + if (!lchan) + return; + + if (data + 63 > 255) { /* According to 3GPP TS 48.058 ?9.3.37 Timing Offset field cannot exceed 255 */ + LOGP(DL1P, LOGL_ERROR, "Attempting to set invalid Timing Offset value %d (MS TO = %u)!\n", + data, set_ms_to); + return; + } + + if (set_ms_to) { + lchan->ms_t_offs = data + 63; + lchan->p_offs = -1; + } else { + lchan->p_offs = data + 63; + lchan->ms_t_offs = -1; + } +} + /* measurement information received from bts model */ static int l1sap_info_meas_ind(struct gsm_bts_trx *trx, struct osmo_phsap_prim *l1sap, @@ -455,6 +476,9 @@ ulm.ta_offs_qbits = info_meas_ind->ta_offs_qbits; ulm.ber10k = info_meas_ind->ber10k; ulm.inv_rssi = info_meas_ind->inv_rssi; + + /* we assume that symbol period is 1 bit: */ + set_ms_to_data(lchan, info_meas_ind->ta_offs_qbits / 4, true); lchan_new_ul_meas(lchan, &ulm); @@ -1021,6 +1045,9 @@ return 0; } + /* According to 3GPP TS 48.058 ? 9.3.17 Access Delay is expressed same way as TA (number of symbols) */ + set_ms_to_data(get_lchan_by_chan_nr(trx, rach_ind->chan_nr), acc_delay, false); + /* check for handover rach */ if (!L1SAP_IS_CHAN_RACH(rach_ind->chan_nr)) return l1sap_handover_rach(trx, l1sap, rach_ind); diff --git a/src/common/rsl.c b/src/common/rsl.c index 1d0bcea..5fe5a1d 100644 --- a/src/common/rsl.c +++ b/src/common/rsl.c @@ -2220,8 +2220,18 @@ return 0; } +static inline uint8_t ms_to2rsl(const struct gsm_lchan *lchan, const struct lapdm_entity *le) +{ + return (lchan->ms_t_offs >= 0) ? lchan->ms_t_offs : (lchan->p_offs - le->ta); +} + +static inline bool ms_to_valid(const struct gsm_lchan *lchan) +{ + return (lchan->ms_t_offs >= 0) || (lchan->p_offs >= 0); +} + /* 8.4.8 MEASUREMENT RESult */ -static int rsl_tx_meas_res(struct gsm_lchan *lchan, uint8_t *l3, int l3_len) +static int rsl_tx_meas_res(struct gsm_lchan *lchan, uint8_t *l3, int l3_len, const struct lapdm_entity *le) { struct msgb *msg; uint8_t meas_res[16]; @@ -2253,7 +2263,11 @@ lchan->meas.flags &= ~LC_UL_M_F_L1_VALID; } msgb_tl16v_put(msg, RSL_IE_L3_INFO, l3_len, l3); - //msgb_tv_put(msg, RSL_IE_MS_TIMING_OFFSET, FIXME); + if (ms_to_valid(lchan)) { + msgb_tv_put(msg, RSL_IE_MS_TIMING_OFFSET, ms_to2rsl(lchan, le)); + lchan->ms_t_offs = -1; + lchan->p_offs = -1; + } rsl_dch_push_hdr(msg, RSL_MT_MEAS_RES, chan_nr); msg->trx = lchan->ts->trx; @@ -2266,8 +2280,6 @@ { struct gsm_lchan *lchan = ctx; struct abis_rsl_common_hdr *rh; - - /* NOTE: Parameter lapdm_entity *le is ignored */ OSMO_ASSERT(msg); rh = msgb_l2(msg); @@ -2306,7 +2318,7 @@ return 0; } - rc = rsl_tx_meas_res(lchan, msgb_l3(msg), msgb_l3len(msg)); + rc = rsl_tx_meas_res(lchan, msgb_l3(msg), msgb_l3len(msg), le); msgb_free(msg); return rc; } else { -- To view, visit https://gerrit.osmocom.org/1700 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I4dfe5c48834a083e757d5de3236a02e15a238b28 Gerrit-PatchSet: 6 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Alexander Chemeris Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Ivan Kluchnikov Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: dexter From gerrit-no-reply at lists.osmocom.org Thu Apr 27 07:42:16 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 27 Apr 2017 07:42:16 +0000 Subject: osmo-bts[master]: measurement: Fix reporting of ms timing offset In-Reply-To: References: Message-ID: Patch Set 1: Code-Review-1 indeed, it's duplicate of gerrit 1700, and as that's now merged I'll abandon this patch. -- To view, visit https://gerrit.osmocom.org/2415 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I6cdc310497d9210013b257da91369c203c3c445f Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Apr 27 07:42:24 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 27 Apr 2017 07:42:24 +0000 Subject: [ABANDON] osmo-bts[master]: measurement: Fix reporting of ms timing offset In-Reply-To: References: Message-ID: Harald Welte has abandoned this change. Change subject: measurement: Fix reporting of ms timing offset ...................................................................... Abandoned duplicate of gerrit 1700 -- To view, visit https://gerrit.osmocom.org/2415 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: abandon Gerrit-Change-Id: I6cdc310497d9210013b257da91369c203c3c445f Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max From gerrit-no-reply at lists.osmocom.org Thu Apr 27 07:45:07 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 27 Apr 2017 07:45:07 +0000 Subject: osmo-bts[master]: measurement: Improve log output In-Reply-To: References: Message-ID: Patch Set 1: Code-Review-1 (2 comments) https://gerrit.osmocom.org/#/c/2389/1/src/common/measurement.c File src/common/measurement.c: Line 104: "MEAS PERIOD END status:%d for chan:%u, TS:%u, SUBCHAN:%u, FN:%u, FN_MOD:%u\n", typically we start the log line with some kind of identity, so TS and subcan number should be in the beginning. Maybe event formatted similar to gsm_lchan_name() in case somebody wants to use a common grpe/regex to filter https://gerrit.osmocom.org/#/c/2389/1/src/common/rsl.c File src/common/rsl.c: Line 2243: "Send Meas RES: NUM:%d, RXLEV_FULL:%d, RXLEV_SUB:%d, RXQUAL_FULL:%d, RXQUAL_SUB:%d, MS_PWR:%d, UL_TA:%d, L3_LEN:%d, TimingOff:%u\n", no gsm_lchan_name() -- To view, visit https://gerrit.osmocom.org/2389 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ic871eed6dcbc7d10aca6cd11dbc803b3e6da449f Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Thu Apr 27 07:51:36 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 27 Apr 2017 07:51:36 +0000 Subject: libosmocore[master]: control_if: Add helper function for 'local execution' of con... In-Reply-To: References: Message-ID: Patch Set 2: (1 comment) https://gerrit.osmocom.org/#/c/2376/2/tests/fsm/fsm_test.c File tests/fsm/fsm_test.c: Line 12: > that seems odd - only header is added but no functions from it are used? thanks, it actually belonged into the next patch of the series, where control interface test cases are added to fsm_test.c -- To view, visit https://gerrit.osmocom.org/2376 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Iaca748e0d942bb2a1ee7c2776b37485e1439eb0c Gerrit-PatchSet: 2 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Thu Apr 27 07:52:23 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 27 Apr 2017 07:52:23 +0000 Subject: [PATCH] libosmocore[master]: control_if: Add helper function for 'local execution' of con... In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2376 to look at the new patch set (#3). control_if: Add helper function for 'local execution' of control command Sometimes (particularly when testing), we may want to parse+execute an arbitrary control command simply form a string buffer, rather than from a msgb. Let's add a helper for that. Change-Id: Iaca748e0d942bb2a1ee7c2776b37485e1439eb0c --- M include/osmocom/ctrl/control_if.h M src/ctrl/control_if.c M tests/Makefile.am 3 files changed, 30 insertions(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/76/2376/3 diff --git a/include/osmocom/ctrl/control_if.h b/include/osmocom/ctrl/control_if.h index 0d37959..4cd3369 100644 --- a/include/osmocom/ctrl/control_if.h +++ b/include/osmocom/ctrl/control_if.h @@ -30,5 +30,6 @@ ctrl_cmd_lookup lookup); struct ctrl_connection *osmo_ctrl_conn_alloc(void *ctx, void *data); int ctrl_cmd_handle(struct ctrl_handle *ctrl, struct ctrl_cmd *cmd, void *data); +struct ctrl_cmd *ctrl_cmd_exec_from_string(struct ctrl_handle *ch, const char *cmdstr); int ctrl_lookup_register(ctrl_cmd_lookup lookup); diff --git a/src/ctrl/control_if.c b/src/ctrl/control_if.c index 28f696b..c8b4722 100644 --- a/src/ctrl/control_if.c +++ b/src/ctrl/control_if.c @@ -810,3 +810,31 @@ llist_add_tail(&lh->list, &ctrl_lookup_helpers); return 0; } + +/*! \brief Helper for "local execution" of a CTRL command from a string + * The function will parse + execute the given control command string + * and return a corresponding ctrl_cmd. Caller is responsible to + * talloc_free() the return value. + * \param[in] Control Interface Command String + * \returns parsed command, including reply; NULL on error */ +struct ctrl_cmd *ctrl_cmd_exec_from_string(struct ctrl_handle *ch, const char *cmdstr) +{ + struct msgb *msg = msgb_alloc(1024, "ctrl-cmd"); + struct ctrl_cmd *cmd; + + if (!msg) + return NULL; + msg->l2h = msg->data; + osmo_strlcpy((char *)msg->data, cmdstr, msgb_tailroom(msg)); + msgb_put(msg, strlen(cmdstr)); + + cmd = ctrl_cmd_parse(ch, msg); + msgb_free(msg); + if (!cmd) + return NULL; + if (ctrl_cmd_handle(ch, cmd, NULL) < 0) { + talloc_free(cmd); + return NULL; + } + return cmd; +} diff --git a/tests/Makefile.am b/tests/Makefile.am index 352b5a7..ab80c1a 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -139,7 +139,7 @@ oap_oap_test_LDADD = $(top_builddir)/src/gsm/libosmogsm.la $(top_builddir)/src/libosmocore.la fsm_fsm_test_SOURCES = fsm/fsm_test.c -fsm_fsm_test_LDADD = $(top_builddir)/src/libosmocore.la +fsm_fsm_test_LDADD = $(top_builddir)/src/libosmocore.la $(top_builddir)/src/ctrl/libosmoctrl.la write_queue_wqueue_test_SOURCES = write_queue/wqueue_test.c write_queue_wqueue_test_LDADD = $(top_builddir)/src/libosmocore.la -- To view, visit https://gerrit.osmocom.org/2376 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Iaca748e0d942bb2a1ee7c2776b37485e1439eb0c Gerrit-PatchSet: 3 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max From gerrit-no-reply at lists.osmocom.org Thu Apr 27 07:52:23 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 27 Apr 2017 07:52:23 +0000 Subject: [PATCH] libosmocore[master]: control_if: Add control interface commands for FSMs In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2378 to look at the new patch set (#2). control_if: Add control interface commands for FSMs This allows programmatic access to introspection of FSM instances, which is quite handy from e.g. external test cases: Send a message to the code, then use the CTRL interface to check if that message has triggered the right kind of state transition. Change-Id: I0f80340ee9c61c88962fdd6764a6098a844d0d1e --- M include/osmocom/ctrl/control_cmd.h M src/ctrl/Makefile.am M src/ctrl/control_if.c A src/ctrl/fsm_ctrl_commands.c M tests/fsm/fsm_test.c M tests/fsm/fsm_test.err 6 files changed, 227 insertions(+), 12 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/78/2378/2 diff --git a/include/osmocom/ctrl/control_cmd.h b/include/osmocom/ctrl/control_cmd.h index d9092f3..3cef9d8 100644 --- a/include/osmocom/ctrl/control_cmd.h +++ b/include/osmocom/ctrl/control_cmd.h @@ -18,6 +18,8 @@ CTRL_NODE_BTS, /* BTS specific (net.btsN.) */ CTRL_NODE_TRX, /* TRX specific (net.btsN.trxM.) */ CTRL_NODE_TS, /* TS specific (net.btsN.trxM.tsI.) */ + CTRL_NODE_FSM, /* Finite State Machine (description) */ + CTRL_NODE_FSM_INST, /* Finite State Machine (instance) */ _LAST_CTRL_NODE }; diff --git a/src/ctrl/Makefile.am b/src/ctrl/Makefile.am index 1817cac..e8d55e6 100644 --- a/src/ctrl/Makefile.am +++ b/src/ctrl/Makefile.am @@ -8,7 +8,7 @@ if ENABLE_CTRL lib_LTLIBRARIES = libosmoctrl.la -libosmoctrl_la_SOURCES = control_cmd.c control_if.c +libosmoctrl_la_SOURCES = control_cmd.c control_if.c fsm_ctrl_commands.c libosmoctrl_la_LDFLAGS = $(LTLDFLAGS_OSMOCTRL) $(TALLOC_LIBS) -version-info $(LIBVERSION) -no-undefined libosmoctrl_la_LIBADD = \ diff --git a/src/ctrl/control_if.c b/src/ctrl/control_if.c index c8b4722..6ab34c7 100644 --- a/src/ctrl/control_if.c +++ b/src/ctrl/control_if.c @@ -717,6 +717,10 @@ if (ret) goto err_vec; + ret = osmo_fsm_ctrl_cmds_install(); + if (ret) + goto err_vec; + ctrl_initialized = 1; return 0; diff --git a/src/ctrl/fsm_ctrl_commands.c b/src/ctrl/fsm_ctrl_commands.c new file mode 100644 index 0000000..0dfc396 --- /dev/null +++ b/src/ctrl/fsm_ctrl_commands.c @@ -0,0 +1,175 @@ +#include +#include + +#include + +#include +#include + +/*! \brief control interface lookup function for FSM's + * \param[in] data Private data passed to controlif_setup() + * \param[in] vline Vector of the line holding the command string + * \param[out] node_type type (CTRL_NODE_) that was determined + * \param[out] node_data private data of node that was determined + * \param i Current index into vline, up to which it is parsed + */ +static int fsm_ctrl_node_lookup(void *data, vector vline, int *node_type, + void **node_data, int *i) +{ + struct osmo_fsm *fsm = NULL; + struct osmo_fsm_inst *fi = NULL;; + const char *token = vector_slot(vline, *i); + + switch (*node_type) { + case CTRL_NODE_ROOT: + if (!strcmp(token, "fsm")) { + const char *fsm_name; + (*i)++; + fsm_name = vector_lookup(vline, *i); + if (!fsm_name) + goto err_index; + fsm = osmo_fsm_find_by_name(fsm_name); + if (!fsm) + goto err_missing; + *node_data = fsm; + *node_type = CTRL_NODE_FSM; + } + break; + case CTRL_NODE_FSM: + fsm = *node_data; + if (!strcmp(token, "name")) { + const char *inst_name; + (*i)++; + inst_name = vector_lookup(vline, *i); + if (!inst_name) + goto err_index; + fi = osmo_fsm_inst_find_by_name(fsm, inst_name); + if (!fi) + goto err_missing; + *node_data = fi; + *node_type = CTRL_NODE_FSM_INST; + } else if (!strcmp(token, "id")) { + const char *inst_id; + (*i)++; + inst_id = vector_lookup(vline, *i); + if (!inst_id) + goto err_index; + fi = osmo_fsm_inst_find_by_id(fsm, inst_id); + if (!fi) + goto err_missing; + *node_data = fi; + *node_type = CTRL_NODE_FSM_INST; + } + break; + default: + return 0; + } + + return 1; + +err_index: + return -ERANGE; +err_missing: + return -ENODEV; +} + +static int get_fsm_inst_state(struct ctrl_cmd *cmd, void *data) +{ + struct osmo_fsm_inst *fi = cmd->node; + + if (!fi) { + cmd->reply = "No such FSM found"; + return CTRL_CMD_ERROR; + } + + cmd->reply = talloc_strdup(cmd, osmo_fsm_state_name(fi->fsm, fi->state)); + return CTRL_CMD_REPLY; +} +CTRL_CMD_DEFINE_RO(fsm_inst_state, "state"); + +static int get_fsm_inst_parent_name(struct ctrl_cmd *cmd, void *data) +{ + struct osmo_fsm_inst *fi = cmd->node; + + if (!fi) { + cmd->reply = "No such FSM found"; + return CTRL_CMD_ERROR; + } + if (!fi->proc.parent) { + cmd->reply = "No parent"; + return CTRL_CMD_ERROR; + } + cmd->reply = talloc_strdup(cmd, fi->proc.parent->name); + return CTRL_CMD_REPLY; +} +CTRL_CMD_DEFINE_RO(fsm_inst_parent_name, "parent-name"); + +static int get_fsm_inst_timer(struct ctrl_cmd *cmd, void *data) +{ + struct osmo_fsm_inst *fi = cmd->node; + struct timeval remaining; + + if (!fi) { + cmd->reply = "No such FSM found"; + return CTRL_CMD_ERROR; + } + if (osmo_timer_remaining(&fi->timer, NULL, &remaining) < 0) + cmd->reply = "0,0,0"; + else + cmd->reply = talloc_asprintf(cmd, "%u,%ld,%ld", fi->T, remaining.tv_sec, remaining.tv_usec); + + return CTRL_CMD_REPLY; +} +CTRL_CMD_DEFINE_RO(fsm_inst_timer, "timer"); + + +static int get_fsm_inst_dump(struct ctrl_cmd *cmd, void *data) +{ + struct osmo_fsm_inst *fi = cmd->node; + struct osmo_fsm_inst *child; + + if (!fi) { + cmd->reply = "No such FSM found"; + return CTRL_CMD_ERROR; + } + + /* Fixed Part: Name, ID, log_level, state, timer number */ + cmd->reply = talloc_asprintf(cmd, "'%s','%s','%s','%s',%u", fi->name, fi->id, + log_level_str(fi->log_level), + osmo_fsm_state_name(fi->fsm, fi->state), fi->T); + + /* Variable Parts below */ + if (fi->T) { + struct timeval remaining; + int rc; + rc = osmo_timer_remaining(&fi->timer, NULL, &remaining); + if (rc == 0) { + cmd->reply = talloc_asprintf_append(cmd->reply, ",timeout_sec=%ld,timeout_usec=%ld", + remaining.tv_sec, remaining.tv_usec); + } + } + + if (fi->proc.parent) + cmd->reply = talloc_asprintf_append(cmd->reply, ",parent='%s'", fi->proc.parent->name); + + llist_for_each_entry(child, &fi->proc.children, list) { + cmd->reply = talloc_asprintf_append(cmd->reply, ",child='%s'", child->name); + } + + return CTRL_CMD_REPLY; +} + +CTRL_CMD_DEFINE_RO(fsm_inst_dump, "dump"); + +int osmo_fsm_ctrl_cmds_install(void) +{ + int rc = 0; + + rc |= ctrl_cmd_install(CTRL_NODE_FSM_INST, &cmd_fsm_inst_dump); + rc |= ctrl_cmd_install(CTRL_NODE_FSM_INST, &cmd_fsm_inst_state); + rc |= ctrl_cmd_install(CTRL_NODE_FSM_INST, &cmd_fsm_inst_parent_name); + rc |= ctrl_cmd_install(CTRL_NODE_FSM_INST, &cmd_fsm_inst_timer); + rc |= ctrl_lookup_register(fsm_ctrl_node_lookup); + + return rc; +} diff --git a/tests/fsm/fsm_test.c b/tests/fsm/fsm_test.c index c3ab91c..eea8b22 100644 --- a/tests/fsm/fsm_test.c +++ b/tests/fsm/fsm_test.c @@ -8,6 +8,7 @@ #include #include #include +#include enum { DMAIN, @@ -83,15 +84,38 @@ }; static struct osmo_fsm fsm = { - .name = "Test FSM", + .name = "Test_FSM", .states = test_fsm_states, .num_states = ARRAY_SIZE(test_fsm_states), .log_subsys = DMAIN, }; +static struct ctrl_handle *g_ctrl; + +static struct ctrl_cmd *exec_ctrl_cmd(const char *cmdstr) +{ + struct ctrl_cmd *cmd; + return ctrl_cmd_exec_from_string(g_ctrl, cmdstr); + OSMO_ASSERT(cmd); + return cmd; +} + +static void assert_cmd_reply(const char *cmdstr, const char *expres) +{ + struct ctrl_cmd *cmd; + + cmd = exec_ctrl_cmd(cmdstr); + if (strcmp(cmd->reply, expres)) { + fprintf(stderr, "Reply '%s' doesn't match expected '%s'\n", cmd->reply, expres); + OSMO_ASSERT(0); + } + talloc_free(cmd); +} + static struct osmo_fsm_inst *foo(void) { struct osmo_fsm_inst *fi; + struct ctrl_cmd *cmd; LOGP(DMAIN, LOGL_INFO, "Checking FSM allocation\n"); fi = osmo_fsm_inst_alloc(&fsm, g_ctx, NULL, LOGL_DEBUG, "my_id"); @@ -100,20 +124,30 @@ OSMO_ASSERT(!strncmp(osmo_fsm_inst_name(fi), fsm.name, strlen(fsm.name))); OSMO_ASSERT(fi->state == ST_NULL); OSMO_ASSERT(fi->log_level == LOGL_DEBUG); + assert_cmd_reply("GET 1 fsm.Test_FSM.id.my_id.state", "NULL"); + assert_cmd_reply("GET 1 fsm.Test_FSM.id.my_id.timer", "0,0,0"); /* Try invalid state transition */ osmo_fsm_inst_dispatch(fi, EV_B, (void *) 42); OSMO_ASSERT(fi->state == ST_NULL); + assert_cmd_reply("GET 1 fsm.Test_FSM.id.my_id.state", "NULL"); + /* Legitimate state transition */ osmo_fsm_inst_dispatch(fi, EV_A, (void *) 23); OSMO_ASSERT(fi->state == ST_ONE); + assert_cmd_reply("GET 1 fsm.Test_FSM.id.my_id.state", "ONE"); /* Legitimate transition with timer */ fsm.timer_cb = test_fsm_tmr_cb; osmo_fsm_inst_dispatch(fi, EV_B, (void *) 42); OSMO_ASSERT(fi->state == ST_TWO); + assert_cmd_reply("GET 1 fsm.Test_FSM.id.my_id.state", "TWO"); + cmd = exec_ctrl_cmd("GET 2 fsm.Test_FSM.id.my_id.dump"); + const char *exp = "'Test_FSM(my_id)','my_id','DEBUG','TWO',2342,timeout_sec="; + OSMO_ASSERT(!strncmp(cmd->reply, exp, strlen(exp))); + talloc_free(cmd); return fi; } @@ -142,7 +176,7 @@ stderr_target = log_target_create_stderr(); log_add_target(stderr_target); log_set_print_filename(stderr_target, 0); - + g_ctrl = ctrl_handle_alloc(NULL, NULL, NULL); g_ctx = NULL; OSMO_ASSERT(osmo_fsm_find_by_name(fsm.name) == NULL); @@ -152,7 +186,7 @@ OSMO_ASSERT(osmo_fsm_inst_find_by_name(&fsm, "my_id") == NULL); finst = foo(); OSMO_ASSERT(osmo_fsm_inst_find_by_id(&fsm, "my_id") == finst); - OSMO_ASSERT(osmo_fsm_inst_find_by_name(&fsm, "Test FSM(my_id)") == finst); + OSMO_ASSERT(osmo_fsm_inst_find_by_name(&fsm, "Test_FSM(my_id)") == finst); while (1) { osmo_select_main(0); diff --git a/tests/fsm/fsm_test.err b/tests/fsm/fsm_test.err index 6f031be..17a2f2e 100644 --- a/tests/fsm/fsm_test.err +++ b/tests/fsm/fsm_test.err @@ -1,11 +1,11 @@ Checking FSM allocation -Test FSM(my_id){NULL}: Allocated -Test FSM(my_id){NULL}: Received Event 1 -Test FSM(my_id){NULL}: Event 1 not permitted -Test FSM(my_id){NULL}: Received Event 0 -Test FSM(my_id){NULL}: state_chg to ONE -Test FSM(my_id){ONE}: Received Event 1 -Test FSM(my_id){ONE}: state_chg to TWO -Test FSM(my_id){TWO}: Timeout of T2342 +Test_FSM(my_id){NULL}: Allocated +Test_FSM(my_id){NULL}: Received Event 1 +Test_FSM(my_id){NULL}: Event 1 not permitted +Test_FSM(my_id){NULL}: Received Event 0 +Test_FSM(my_id){NULL}: state_chg to ONE +Test_FSM(my_id){ONE}: Received Event 1 +Test_FSM(my_id){ONE}: state_chg to TWO +Test_FSM(my_id){TWO}: Timeout of T2342 Timer  \ No newline at end of file -- To view, visit https://gerrit.osmocom.org/2378 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I0f80340ee9c61c88962fdd6764a6098a844d0d1e Gerrit-PatchSet: 2 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Thu Apr 27 07:57:08 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 27 Apr 2017 07:57:08 +0000 Subject: [MERGED] libosmocore[master]: control_if: Add API to initialize control interface without ... In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: control_if: Add API to initialize control interface without TCP port bind ...................................................................... control_if: Add API to initialize control interface without TCP port bind When executing test cases, we don't want to bind to a local TCP port, as we cannot make assumptions as to which ports are actually free. Change-Id: I5717f9dd92d1f143f069cecd4b4c8ba3d03b25f8 --- M include/osmocom/ctrl/control_if.h M src/ctrl/control_if.c 2 files changed, 64 insertions(+), 27 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/include/osmocom/ctrl/control_if.h b/include/osmocom/ctrl/control_if.h index a740a96..0d37959 100644 --- a/include/osmocom/ctrl/control_if.h +++ b/include/osmocom/ctrl/control_if.h @@ -21,6 +21,7 @@ int ctrl_cmd_send(struct osmo_wqueue *queue, struct ctrl_cmd *cmd); int ctrl_cmd_send_trap(struct ctrl_handle *ctrl, const char *name, char *value); +struct ctrl_handle *ctrl_handle_alloc(void *ctx, void *data, ctrl_cmd_lookup lookup); struct ctrl_handle *ctrl_interface_setup(void *data, uint16_t port, ctrl_cmd_lookup lookup); struct ctrl_handle *ctrl_interface_setup_dynip(void *data, diff --git a/src/ctrl/control_if.c b/src/ctrl/control_if.c index f1cc7ab..28f696b 100644 --- a/src/ctrl/control_if.c +++ b/src/ctrl/control_if.c @@ -59,6 +59,8 @@ #include #include +extern int osmo_fsm_ctrl_cmds_install(void); + vector ctrl_node_vec; /* global list of control interface lookup helpers */ @@ -694,6 +696,62 @@ return ctrl_interface_setup_dynip(data, "127.0.0.1", port, lookup); } +static int ctrl_initialized = 0; + +/* global ctrl initialization */ +static int ctrl_init(void) +{ + int ret; + + if (ctrl_initialized) + return 0; + + ctrl_node_vec = vector_init(5); + if (!ctrl_node_vec) + goto err; + + ret = ctrl_cmd_install(CTRL_NODE_ROOT, &cmd_rate_ctr); + if (ret) + goto err_vec; + ret = ctrl_cmd_install(CTRL_NODE_ROOT, &cmd_counter); + if (ret) + goto err_vec; + + ctrl_initialized = 1; + return 0; + +err_vec: + vector_free(ctrl_node_vec); + ctrl_node_vec = NULL; +err: + return -1; +} + +/*! \brief Allocate a CTRL interface handle + * \param[in] ctx Tallo callocation context to be used + * \param[in] data Pointer which will be made available to each + set_..() get_..() verify_..() control command function + * \param[in] lookup Lookup function pointer, can be NULL + * \returns ctrl_handle pointer or NULL in case of errors + */ +struct ctrl_handle *ctrl_handle_alloc(void *ctx, void *data, ctrl_cmd_lookup lookup) +{ + struct ctrl_handle *ctrl; + + ctrl_init(); + + ctrl = talloc_zero(ctx, struct ctrl_handle); + if (!ctrl) + return NULL; + + INIT_LLIST_HEAD(&ctrl->ccon_list); + + ctrl->data = data; + ctrl->lookup = lookup; + + return ctrl; +} + /*! \brief Setup CTRL interface on a given address * \param[in] data Pointer which will be made available to each set_..() get_..() verify_..() control command function @@ -710,44 +768,22 @@ int ret; struct ctrl_handle *ctrl; - ctrl = talloc_zero(data, struct ctrl_handle); + ctrl = ctrl_handle_alloc(data, data, lookup); if (!ctrl) return NULL; - - INIT_LLIST_HEAD(&ctrl->ccon_list); - - ctrl->data = data; - ctrl->lookup = lookup; - - ctrl_node_vec = vector_init(5); - if (!ctrl_node_vec) - goto err; /* Listen for control connections */ ctrl->listen_fd.cb = listen_fd_cb; ctrl->listen_fd.data = ctrl; ret = osmo_sock_init_ofd(&ctrl->listen_fd, AF_INET, SOCK_STREAM, IPPROTO_TCP, bind_addr, port, OSMO_SOCK_F_BIND); - if (ret < 0) - goto err_vec; - - ret = ctrl_cmd_install(CTRL_NODE_ROOT, &cmd_rate_ctr); - if (ret) - goto err_vec; - ret = ctrl_cmd_install(CTRL_NODE_ROOT, &cmd_counter); - if (ret) - goto err_vec; + if (ret < 0) { + talloc_free(ctrl); + return NULL; + } LOGP(DLCTRL, LOGL_NOTICE, "CTRL at %s %u\n", bind_addr, port); return ctrl; -err_vec: - vector_free(ctrl_node_vec); - ctrl_node_vec = NULL; -err: - LOGP(DLCTRL, LOGL_ERROR, "Cannot bind CTRL at %s %u\n", - bind_addr, port); - talloc_free(ctrl); - return NULL; } /*! \brief Install a lookup helper function for control nodes -- To view, visit https://gerrit.osmocom.org/2375 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I5717f9dd92d1f143f069cecd4b4c8ba3d03b25f8 Gerrit-PatchSet: 3 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Thu Apr 27 07:57:49 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 27 Apr 2017 07:57:49 +0000 Subject: libosmocore[master]: control_if: Add helper function for 'local execution' of con... In-Reply-To: References: Message-ID: Patch Set 3: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2376 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Iaca748e0d942bb2a1ee7c2776b37485e1439eb0c Gerrit-PatchSet: 3 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Apr 27 07:58:03 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 27 Apr 2017 07:58:03 +0000 Subject: libosmocore[master]: control_if: Add control interface commands for FSMs In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2378 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I0f80340ee9c61c88962fdd6764a6098a844d0d1e Gerrit-PatchSet: 2 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Apr 27 08:00:53 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Thu, 27 Apr 2017 08:00:53 +0000 Subject: [MERGED] openbsc[master]: gbproxy: add example .service In-Reply-To: References: Message-ID: Max has submitted this change and it was merged. Change subject: gbproxy: add example .service ...................................................................... gbproxy: add example .service Change-Id: Ic8144777a77efce4bad44abf6c6abde12fc5149c Related: SYS#3610 --- A openbsc/contrib/systemd/osmo-gbproxy.service 1 file changed, 12 insertions(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/openbsc/contrib/systemd/osmo-gbproxy.service b/openbsc/contrib/systemd/osmo-gbproxy.service new file mode 100644 index 0000000..a0b7829 --- /dev/null +++ b/openbsc/contrib/systemd/osmo-gbproxy.service @@ -0,0 +1,12 @@ +[Unit] +Description=Osmocom Gb proxy + +[Service] +Type=simple +ExecStart=/usr/bin/osmo-gbproxy -c /etc/osmocom/osmo-gbproxy.cfg +Restart=always +RestartSec=2 +RestartPreventExitStatus=1 + +[Install] +WantedBy=multi-user.target -- To view, visit https://gerrit.osmocom.org/2419 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ic8144777a77efce4bad44abf6c6abde12fc5149c Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: daniel From gerrit-no-reply at lists.osmocom.org Thu Apr 27 08:03:45 2017 From: gerrit-no-reply at lists.osmocom.org (Pau Espin Pedrol) Date: Thu, 27 Apr 2017 08:03:45 +0000 Subject: [PATCH] libosmo-netif[master]: osmux: Use osmo_gettimeofday for testing puroposes In-Reply-To: References: Message-ID: Hello Neels Hofmeyr, Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2418 to look at the new patch set (#2). osmux: Use osmo_gettimeofday for testing puroposes This way we can use fake time and osmux_test take 700ms instead of >2sec to run. Change-Id: Ic39cab74400aca8262a00c0d06884230b1a15ca3 --- M src/osmux.c M tests/osmux/osmux_test.c 2 files changed, 26 insertions(+), 6 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-netif refs/changes/18/2418/2 diff --git a/src/osmux.c b/src/osmux.c index 4d12427..d12a39a 100644 --- a/src/osmux.c +++ b/src/osmux.c @@ -777,7 +777,7 @@ #ifdef DEBUG_TIMING struct timeval now, diff; - gettimeofday(&now, NULL); + osmo_gettimeofday(&now, NULL); timersub(&now, &h->start, &diff); timersub(&diff,&h->when, &diff); LOGP(DLMIB, LOGL_DEBUG, "we are lagging %lu.%.6lu in scheduled " @@ -806,7 +806,7 @@ h->timer.data = h; #ifdef DEBUG_TIMING - gettimeofday(&h->start, NULL); + osmo_gettimeofday(&h->start, NULL); h->when.tv_sec = when->tv_sec; h->when.tv_usec = when->tv_usec; #endif diff --git a/tests/osmux/osmux_test.c b/tests/osmux/osmux_test.c index 9941ce3..63f89f1 100644 --- a/tests/osmux/osmux_test.c +++ b/tests/osmux/osmux_test.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -54,6 +55,8 @@ 0xf2, 0x26, 0x33, 0x65, 0x54, }; +#define PKT_TIME_USEC 20*1000 + static int rtp_pkts; static int mark_pkts; #if OSMUX_TEST_USE_TIMING @@ -67,7 +70,7 @@ #if OSMUX_TEST_USE_TIMING struct timeval now, diff; - gettimeofday(&now, NULL); + osmo_gettimeofday(&now, NULL); timersub(&now, &last, &diff); last = now; @@ -159,10 +162,17 @@ osmux_xfrm_input_deliver(&h_input); } } +#if !OSMUX_TEST_USE_TIMING + osmo_gettimeofday_override_add(0, PKT_TIME_USEC); +#endif } - while (rtp_pkts) + while (rtp_pkts) { +#if !OSMUX_TEST_USE_TIMING + osmo_gettimeofday_override_add(1, 0); +#endif osmo_select_main(0); + } if (mark_pkts) { fprintf(stdout, "RTP M bit (marker) mismatch! %d\n", mark_pkts); @@ -204,7 +214,7 @@ if (i % 4 == 0) { #if OSMUX_TEST_USE_TIMING - gettimeofday(&last, NULL); + osmo_gettimeofday(&last, NULL); #endif /* After four RTP messages, squash them into the OSMUX @@ -217,8 +227,12 @@ * messages that are extracted from OSMUX has been * delivered. */ - for (j = 0; j < k-2; j++) + for (j = 0; j < k-2; j++) { osmo_select_main(0); +#if !OSMUX_TEST_USE_TIMING + osmo_gettimeofday_override_add(0, PKT_TIME_USEC); +#endif + } k = 0; } @@ -239,6 +253,12 @@ exit(EXIT_FAILURE); } +#if !OSMUX_TEST_USE_TIMING + /* This test uses fake time to speedup the run, unless we want to manually + * test time specific stuff */ + osmo_gettimeofday_override = true; +#endif + /* This test doesn't use it, but osmux requires it internally. */ osmo_init_logging(&osmux_test_log_info); log_set_log_level(osmo_stderr_target, LOGL_DEBUG); -- To view, visit https://gerrit.osmocom.org/2418 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ic39cab74400aca8262a00c0d06884230b1a15ca3 Gerrit-PatchSet: 2 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Pau Espin Pedrol Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Thu Apr 27 08:04:53 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 27 Apr 2017 08:04:53 +0000 Subject: libosmocore[master]: Add osmo_rand() function In-Reply-To: References: Message-ID: Patch Set 2: agreeing with Holger. Let's seed the regular libc rand() with some randomness at program start, and then generate TMSI or other random identiifers from that. The function for that should then verify that the initializtaion was actually performed (so applications cannot forget about that) and the name should include something like omso_get_rand_id() to imply that this is about random identifiers, and not key-generation-grade randomness. -- To view, visit https://gerrit.osmocom.org/1526 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I0241b814ea4c4ce1458f7ad76e31d390383c2048 Gerrit-PatchSet: 2 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Apr 27 08:13:37 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 27 Apr 2017 08:13:37 +0000 Subject: [PATCH] libosmo-sccp[master]: stp: Install VTY commands for FSM introspection Message-ID: Review at https://gerrit.osmocom.org/2421 stp: Install VTY commands for FSM introspection Change-Id: I4ee881715e874eaed3cca6ac42db21260123306a --- M stp/stp_main.c 1 file changed, 1 insertion(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/21/2421/1 diff --git a/stp/stp_main.c b/stp/stp_main.c index 3110ec4..564ced5 100644 --- a/stp/stp_main.c +++ b/stp/stp_main.c @@ -137,6 +137,7 @@ osmo_fsm_log_addr(false); logging_vty_add_cmds(&log_info); osmo_ss7_vty_init_sg(); + osmo_fsm_vty_add_cmds(); rc = vty_read_config_file(cmdline_config.config_file, NULL); if (rc < 0) { -- To view, visit https://gerrit.osmocom.org/2421 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I4ee881715e874eaed3cca6ac42db21260123306a Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Thu Apr 27 08:24:03 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 27 Apr 2017 08:24:03 +0000 Subject: [PATCH] libosmo-sccp[master]: Address some negative integer handling issues Message-ID: Review at https://gerrit.osmocom.org/2422 Address some negative integer handling issues If for some reason we cannot resolve the file descriptor for a given FSM, we shouldn't attempt to send data through it. Fixes: coverity CID#167155, CID#167154, CID#167153, CID#167152, CID#167151, CID#167151 Change-Id: I8b1a676b653bcdad21cb7927d549f499950a2b73 --- M src/xua_asp_fsm.c 1 file changed, 14 insertions(+), 7 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/22/2422/1 diff --git a/src/xua_asp_fsm.c b/src/xua_asp_fsm.c index 2b5bfdd..d54d45e 100644 --- a/src/xua_asp_fsm.c +++ b/src/xua_asp_fsm.c @@ -769,8 +769,10 @@ case XUA_ASP_E_SCTP_EST_IND: if (iafp->role == XUA_ASPFSM_ROLE_SG) { /* Server: Transmit IPA ID GET + Wait for Response */ - ipa_ccm_send_id_req(fd); - osmo_fsm_inst_state_chg(fi, IPA_ASP_S_WAIT_ID_RESP, 10, T_WAIT_ID_RESP); + if (fd >= 0) { + ipa_ccm_send_id_req(fd); + osmo_fsm_inst_state_chg(fi, IPA_ASP_S_WAIT_ID_RESP, 10, T_WAIT_ID_RESP); + } } else { /* Client: We simply wait for an ID GET */ osmo_fsm_inst_state_chg(fi, IPA_ASP_S_WAIT_ID_GET, 10, T_WAIT_ID_GET); @@ -818,8 +820,10 @@ osmo_ss7_as_add_asp(as, asp->cfg.name); /* TODO: OAP Authentication? */ /* Send ID_ACK */ - ipaccess_send_id_ack(fd); - osmo_fsm_inst_state_chg(fi, IPA_ASP_S_WAIT_ID_ACK2, 10, T_WAIT_ID_ACK); + if (fd >= 0) { + ipaccess_send_id_ack(fd); + osmo_fsm_inst_state_chg(fi, IPA_ASP_S_WAIT_ID_ACK2, 10, T_WAIT_ID_ACK); + } break; } return; @@ -878,8 +882,10 @@ case IPA_ASP_E_ID_ACK: /* Send ACK2 to server */ fd = get_fd_from_iafp(iafp); - ipaccess_send_id_ack(fd); - osmo_fsm_inst_state_chg(fi, IPA_ASP_S_ACTIVE, 0, 0); + if (fd >= 0) { + ipaccess_send_id_ack(fd); + osmo_fsm_inst_state_chg(fi, IPA_ASP_S_ACTIVE, 0, 0); + } break; } } @@ -911,7 +917,8 @@ case XUA_ASP_E_ASPSM_BEAT: /* PING -> PONG */ fd = get_fd_from_iafp(iafp); - ipaccess_send_pong(fd); + if (fd >= 0) + ipaccess_send_pong(fd); break; case XUA_ASP_E_ASPSM_BEAT_ACK: /* stop timer, if any */ -- To view, visit https://gerrit.osmocom.org/2422 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I8b1a676b653bcdad21cb7927d549f499950a2b73 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Thu Apr 27 08:26:56 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 27 Apr 2017 08:26:56 +0000 Subject: [PATCH] libosmocore[master]: Uninitialized variable in ipa_ccm_make_id_resp_from_req() Message-ID: Review at https://gerrit.osmocom.org/2423 Uninitialized variable in ipa_ccm_make_id_resp_from_req() We are allocating a buffer on the stack without initializing it, and then passing it into ipa_ccm_make_id_resp(). There is no real danger from this, as the buffer is only uninitialized if num_ies is 0, but let's memset() it for good style Change-Id: If5761a47b8cba73ddcc02a88cfa5c87c1970c04e Fixes: coverity CID#167040 --- M src/gsm/ipa.c 1 file changed, 2 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/23/2423/1 diff --git a/src/gsm/ipa.c b/src/gsm/ipa.c index 01bd0c5..2c0880a 100644 --- a/src/gsm/ipa.c +++ b/src/gsm/ipa.c @@ -302,6 +302,8 @@ unsigned int num_ies = 0; const uint8_t *cur = data; + memset(ies, 0, sizeof(ies)); + /* build a array of the IEIs */ while (len >= 2) { uint8_t t_len, t_tag; -- To view, visit https://gerrit.osmocom.org/2423 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: If5761a47b8cba73ddcc02a88cfa5c87c1970c04e Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Thu Apr 27 08:28:18 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 27 Apr 2017 08:28:18 +0000 Subject: [PATCH] libosmo-sccp[master]: xua_default_lm_fsm: Missing printf() argument Message-ID: Review at https://gerrit.osmocom.org/2424 xua_default_lm_fsm: Missing printf() argument Change-Id: I03c30a0d1e03ff56df80bdd1e8a7846142b6f79c Fixes: coverity CID#166993 --- M src/xua_default_lm_fsm.c 1 file changed, 1 insertion(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/24/2424/1 diff --git a/src/xua_default_lm_fsm.c b/src/xua_default_lm_fsm.c index fc9ba3c..9308de4 100644 --- a/src/xua_default_lm_fsm.c +++ b/src/xua_default_lm_fsm.c @@ -111,7 +111,7 @@ * allocated/registered by the SG */ as = osmo_ss7_as_find_by_l_rk_id(asp->inst, l_rk_id); if (!as) { - LOGPFSM(fi, "RKM Result for unknown l_rk_id %u\n"); + LOGPFSM(fi, "RKM Result for unknown l_rk_id %u\n", l_rk_id); return -EINVAL; } as->cfg.routing_key.context = rctx; -- To view, visit https://gerrit.osmocom.org/2424 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I03c30a0d1e03ff56df80bdd1e8a7846142b6f79c Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Thu Apr 27 08:30:32 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 27 Apr 2017 08:30:32 +0000 Subject: [MERGED] libosmocore[master]: control_if: Add control interface commands for FSMs In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: control_if: Add control interface commands for FSMs ...................................................................... control_if: Add control interface commands for FSMs This allows programmatic access to introspection of FSM instances, which is quite handy from e.g. external test cases: Send a message to the code, then use the CTRL interface to check if that message has triggered the right kind of state transition. Change-Id: I0f80340ee9c61c88962fdd6764a6098a844d0d1e --- M include/osmocom/ctrl/control_cmd.h M src/ctrl/Makefile.am M src/ctrl/control_if.c A src/ctrl/fsm_ctrl_commands.c M tests/fsm/fsm_test.c M tests/fsm/fsm_test.err 6 files changed, 227 insertions(+), 12 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/include/osmocom/ctrl/control_cmd.h b/include/osmocom/ctrl/control_cmd.h index d9092f3..3cef9d8 100644 --- a/include/osmocom/ctrl/control_cmd.h +++ b/include/osmocom/ctrl/control_cmd.h @@ -18,6 +18,8 @@ CTRL_NODE_BTS, /* BTS specific (net.btsN.) */ CTRL_NODE_TRX, /* TRX specific (net.btsN.trxM.) */ CTRL_NODE_TS, /* TS specific (net.btsN.trxM.tsI.) */ + CTRL_NODE_FSM, /* Finite State Machine (description) */ + CTRL_NODE_FSM_INST, /* Finite State Machine (instance) */ _LAST_CTRL_NODE }; diff --git a/src/ctrl/Makefile.am b/src/ctrl/Makefile.am index 1817cac..e8d55e6 100644 --- a/src/ctrl/Makefile.am +++ b/src/ctrl/Makefile.am @@ -8,7 +8,7 @@ if ENABLE_CTRL lib_LTLIBRARIES = libosmoctrl.la -libosmoctrl_la_SOURCES = control_cmd.c control_if.c +libosmoctrl_la_SOURCES = control_cmd.c control_if.c fsm_ctrl_commands.c libosmoctrl_la_LDFLAGS = $(LTLDFLAGS_OSMOCTRL) $(TALLOC_LIBS) -version-info $(LIBVERSION) -no-undefined libosmoctrl_la_LIBADD = \ diff --git a/src/ctrl/control_if.c b/src/ctrl/control_if.c index c8b4722..6ab34c7 100644 --- a/src/ctrl/control_if.c +++ b/src/ctrl/control_if.c @@ -717,6 +717,10 @@ if (ret) goto err_vec; + ret = osmo_fsm_ctrl_cmds_install(); + if (ret) + goto err_vec; + ctrl_initialized = 1; return 0; diff --git a/src/ctrl/fsm_ctrl_commands.c b/src/ctrl/fsm_ctrl_commands.c new file mode 100644 index 0000000..0dfc396 --- /dev/null +++ b/src/ctrl/fsm_ctrl_commands.c @@ -0,0 +1,175 @@ +#include +#include + +#include + +#include +#include + +/*! \brief control interface lookup function for FSM's + * \param[in] data Private data passed to controlif_setup() + * \param[in] vline Vector of the line holding the command string + * \param[out] node_type type (CTRL_NODE_) that was determined + * \param[out] node_data private data of node that was determined + * \param i Current index into vline, up to which it is parsed + */ +static int fsm_ctrl_node_lookup(void *data, vector vline, int *node_type, + void **node_data, int *i) +{ + struct osmo_fsm *fsm = NULL; + struct osmo_fsm_inst *fi = NULL;; + const char *token = vector_slot(vline, *i); + + switch (*node_type) { + case CTRL_NODE_ROOT: + if (!strcmp(token, "fsm")) { + const char *fsm_name; + (*i)++; + fsm_name = vector_lookup(vline, *i); + if (!fsm_name) + goto err_index; + fsm = osmo_fsm_find_by_name(fsm_name); + if (!fsm) + goto err_missing; + *node_data = fsm; + *node_type = CTRL_NODE_FSM; + } + break; + case CTRL_NODE_FSM: + fsm = *node_data; + if (!strcmp(token, "name")) { + const char *inst_name; + (*i)++; + inst_name = vector_lookup(vline, *i); + if (!inst_name) + goto err_index; + fi = osmo_fsm_inst_find_by_name(fsm, inst_name); + if (!fi) + goto err_missing; + *node_data = fi; + *node_type = CTRL_NODE_FSM_INST; + } else if (!strcmp(token, "id")) { + const char *inst_id; + (*i)++; + inst_id = vector_lookup(vline, *i); + if (!inst_id) + goto err_index; + fi = osmo_fsm_inst_find_by_id(fsm, inst_id); + if (!fi) + goto err_missing; + *node_data = fi; + *node_type = CTRL_NODE_FSM_INST; + } + break; + default: + return 0; + } + + return 1; + +err_index: + return -ERANGE; +err_missing: + return -ENODEV; +} + +static int get_fsm_inst_state(struct ctrl_cmd *cmd, void *data) +{ + struct osmo_fsm_inst *fi = cmd->node; + + if (!fi) { + cmd->reply = "No such FSM found"; + return CTRL_CMD_ERROR; + } + + cmd->reply = talloc_strdup(cmd, osmo_fsm_state_name(fi->fsm, fi->state)); + return CTRL_CMD_REPLY; +} +CTRL_CMD_DEFINE_RO(fsm_inst_state, "state"); + +static int get_fsm_inst_parent_name(struct ctrl_cmd *cmd, void *data) +{ + struct osmo_fsm_inst *fi = cmd->node; + + if (!fi) { + cmd->reply = "No such FSM found"; + return CTRL_CMD_ERROR; + } + if (!fi->proc.parent) { + cmd->reply = "No parent"; + return CTRL_CMD_ERROR; + } + cmd->reply = talloc_strdup(cmd, fi->proc.parent->name); + return CTRL_CMD_REPLY; +} +CTRL_CMD_DEFINE_RO(fsm_inst_parent_name, "parent-name"); + +static int get_fsm_inst_timer(struct ctrl_cmd *cmd, void *data) +{ + struct osmo_fsm_inst *fi = cmd->node; + struct timeval remaining; + + if (!fi) { + cmd->reply = "No such FSM found"; + return CTRL_CMD_ERROR; + } + if (osmo_timer_remaining(&fi->timer, NULL, &remaining) < 0) + cmd->reply = "0,0,0"; + else + cmd->reply = talloc_asprintf(cmd, "%u,%ld,%ld", fi->T, remaining.tv_sec, remaining.tv_usec); + + return CTRL_CMD_REPLY; +} +CTRL_CMD_DEFINE_RO(fsm_inst_timer, "timer"); + + +static int get_fsm_inst_dump(struct ctrl_cmd *cmd, void *data) +{ + struct osmo_fsm_inst *fi = cmd->node; + struct osmo_fsm_inst *child; + + if (!fi) { + cmd->reply = "No such FSM found"; + return CTRL_CMD_ERROR; + } + + /* Fixed Part: Name, ID, log_level, state, timer number */ + cmd->reply = talloc_asprintf(cmd, "'%s','%s','%s','%s',%u", fi->name, fi->id, + log_level_str(fi->log_level), + osmo_fsm_state_name(fi->fsm, fi->state), fi->T); + + /* Variable Parts below */ + if (fi->T) { + struct timeval remaining; + int rc; + rc = osmo_timer_remaining(&fi->timer, NULL, &remaining); + if (rc == 0) { + cmd->reply = talloc_asprintf_append(cmd->reply, ",timeout_sec=%ld,timeout_usec=%ld", + remaining.tv_sec, remaining.tv_usec); + } + } + + if (fi->proc.parent) + cmd->reply = talloc_asprintf_append(cmd->reply, ",parent='%s'", fi->proc.parent->name); + + llist_for_each_entry(child, &fi->proc.children, list) { + cmd->reply = talloc_asprintf_append(cmd->reply, ",child='%s'", child->name); + } + + return CTRL_CMD_REPLY; +} + +CTRL_CMD_DEFINE_RO(fsm_inst_dump, "dump"); + +int osmo_fsm_ctrl_cmds_install(void) +{ + int rc = 0; + + rc |= ctrl_cmd_install(CTRL_NODE_FSM_INST, &cmd_fsm_inst_dump); + rc |= ctrl_cmd_install(CTRL_NODE_FSM_INST, &cmd_fsm_inst_state); + rc |= ctrl_cmd_install(CTRL_NODE_FSM_INST, &cmd_fsm_inst_parent_name); + rc |= ctrl_cmd_install(CTRL_NODE_FSM_INST, &cmd_fsm_inst_timer); + rc |= ctrl_lookup_register(fsm_ctrl_node_lookup); + + return rc; +} diff --git a/tests/fsm/fsm_test.c b/tests/fsm/fsm_test.c index c3ab91c..eea8b22 100644 --- a/tests/fsm/fsm_test.c +++ b/tests/fsm/fsm_test.c @@ -8,6 +8,7 @@ #include #include #include +#include enum { DMAIN, @@ -83,15 +84,38 @@ }; static struct osmo_fsm fsm = { - .name = "Test FSM", + .name = "Test_FSM", .states = test_fsm_states, .num_states = ARRAY_SIZE(test_fsm_states), .log_subsys = DMAIN, }; +static struct ctrl_handle *g_ctrl; + +static struct ctrl_cmd *exec_ctrl_cmd(const char *cmdstr) +{ + struct ctrl_cmd *cmd; + return ctrl_cmd_exec_from_string(g_ctrl, cmdstr); + OSMO_ASSERT(cmd); + return cmd; +} + +static void assert_cmd_reply(const char *cmdstr, const char *expres) +{ + struct ctrl_cmd *cmd; + + cmd = exec_ctrl_cmd(cmdstr); + if (strcmp(cmd->reply, expres)) { + fprintf(stderr, "Reply '%s' doesn't match expected '%s'\n", cmd->reply, expres); + OSMO_ASSERT(0); + } + talloc_free(cmd); +} + static struct osmo_fsm_inst *foo(void) { struct osmo_fsm_inst *fi; + struct ctrl_cmd *cmd; LOGP(DMAIN, LOGL_INFO, "Checking FSM allocation\n"); fi = osmo_fsm_inst_alloc(&fsm, g_ctx, NULL, LOGL_DEBUG, "my_id"); @@ -100,20 +124,30 @@ OSMO_ASSERT(!strncmp(osmo_fsm_inst_name(fi), fsm.name, strlen(fsm.name))); OSMO_ASSERT(fi->state == ST_NULL); OSMO_ASSERT(fi->log_level == LOGL_DEBUG); + assert_cmd_reply("GET 1 fsm.Test_FSM.id.my_id.state", "NULL"); + assert_cmd_reply("GET 1 fsm.Test_FSM.id.my_id.timer", "0,0,0"); /* Try invalid state transition */ osmo_fsm_inst_dispatch(fi, EV_B, (void *) 42); OSMO_ASSERT(fi->state == ST_NULL); + assert_cmd_reply("GET 1 fsm.Test_FSM.id.my_id.state", "NULL"); + /* Legitimate state transition */ osmo_fsm_inst_dispatch(fi, EV_A, (void *) 23); OSMO_ASSERT(fi->state == ST_ONE); + assert_cmd_reply("GET 1 fsm.Test_FSM.id.my_id.state", "ONE"); /* Legitimate transition with timer */ fsm.timer_cb = test_fsm_tmr_cb; osmo_fsm_inst_dispatch(fi, EV_B, (void *) 42); OSMO_ASSERT(fi->state == ST_TWO); + assert_cmd_reply("GET 1 fsm.Test_FSM.id.my_id.state", "TWO"); + cmd = exec_ctrl_cmd("GET 2 fsm.Test_FSM.id.my_id.dump"); + const char *exp = "'Test_FSM(my_id)','my_id','DEBUG','TWO',2342,timeout_sec="; + OSMO_ASSERT(!strncmp(cmd->reply, exp, strlen(exp))); + talloc_free(cmd); return fi; } @@ -142,7 +176,7 @@ stderr_target = log_target_create_stderr(); log_add_target(stderr_target); log_set_print_filename(stderr_target, 0); - + g_ctrl = ctrl_handle_alloc(NULL, NULL, NULL); g_ctx = NULL; OSMO_ASSERT(osmo_fsm_find_by_name(fsm.name) == NULL); @@ -152,7 +186,7 @@ OSMO_ASSERT(osmo_fsm_inst_find_by_name(&fsm, "my_id") == NULL); finst = foo(); OSMO_ASSERT(osmo_fsm_inst_find_by_id(&fsm, "my_id") == finst); - OSMO_ASSERT(osmo_fsm_inst_find_by_name(&fsm, "Test FSM(my_id)") == finst); + OSMO_ASSERT(osmo_fsm_inst_find_by_name(&fsm, "Test_FSM(my_id)") == finst); while (1) { osmo_select_main(0); diff --git a/tests/fsm/fsm_test.err b/tests/fsm/fsm_test.err index 6f031be..17a2f2e 100644 --- a/tests/fsm/fsm_test.err +++ b/tests/fsm/fsm_test.err @@ -1,11 +1,11 @@ Checking FSM allocation -Test FSM(my_id){NULL}: Allocated -Test FSM(my_id){NULL}: Received Event 1 -Test FSM(my_id){NULL}: Event 1 not permitted -Test FSM(my_id){NULL}: Received Event 0 -Test FSM(my_id){NULL}: state_chg to ONE -Test FSM(my_id){ONE}: Received Event 1 -Test FSM(my_id){ONE}: state_chg to TWO -Test FSM(my_id){TWO}: Timeout of T2342 +Test_FSM(my_id){NULL}: Allocated +Test_FSM(my_id){NULL}: Received Event 1 +Test_FSM(my_id){NULL}: Event 1 not permitted +Test_FSM(my_id){NULL}: Received Event 0 +Test_FSM(my_id){NULL}: state_chg to ONE +Test_FSM(my_id){ONE}: Received Event 1 +Test_FSM(my_id){ONE}: state_chg to TWO +Test_FSM(my_id){TWO}: Timeout of T2342 Timer  \ No newline at end of file -- To view, visit https://gerrit.osmocom.org/2378 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I0f80340ee9c61c88962fdd6764a6098a844d0d1e Gerrit-PatchSet: 2 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Thu Apr 27 08:30:32 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 27 Apr 2017 08:30:32 +0000 Subject: [MERGED] libosmocore[master]: control_if: Don't use magic number '5' when allocating vector In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: control_if: Don't use magic number '5' when allocating vector ...................................................................... control_if: Don't use magic number '5' when allocating vector We have a proper constant for this (_LAST_CTRL_NODE), so let's use it. Change-Id: I46275e644166156cb665da70d2964008f1c6cd88 --- M src/ctrl/control_if.c 1 file changed, 1 insertion(+), 1 deletion(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/ctrl/control_if.c b/src/ctrl/control_if.c index 6ab34c7..c4b6f91 100644 --- a/src/ctrl/control_if.c +++ b/src/ctrl/control_if.c @@ -706,7 +706,7 @@ if (ctrl_initialized) return 0; - ctrl_node_vec = vector_init(5); + ctrl_node_vec = vector_init(_LAST_CTRL_NODE); if (!ctrl_node_vec) goto err; -- To view, visit https://gerrit.osmocom.org/2379 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I46275e644166156cb665da70d2964008f1c6cd88 Gerrit-PatchSet: 2 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Thu Apr 27 08:30:32 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 27 Apr 2017 08:30:32 +0000 Subject: [MERGED] libosmocore[master]: control_if: Add helper function for 'local execution' of con... In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: control_if: Add helper function for 'local execution' of control command ...................................................................... control_if: Add helper function for 'local execution' of control command Sometimes (particularly when testing), we may want to parse+execute an arbitrary control command simply form a string buffer, rather than from a msgb. Let's add a helper for that. Change-Id: Iaca748e0d942bb2a1ee7c2776b37485e1439eb0c --- M include/osmocom/ctrl/control_if.h M src/ctrl/control_if.c M tests/Makefile.am 3 files changed, 30 insertions(+), 1 deletion(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/include/osmocom/ctrl/control_if.h b/include/osmocom/ctrl/control_if.h index 0d37959..4cd3369 100644 --- a/include/osmocom/ctrl/control_if.h +++ b/include/osmocom/ctrl/control_if.h @@ -30,5 +30,6 @@ ctrl_cmd_lookup lookup); struct ctrl_connection *osmo_ctrl_conn_alloc(void *ctx, void *data); int ctrl_cmd_handle(struct ctrl_handle *ctrl, struct ctrl_cmd *cmd, void *data); +struct ctrl_cmd *ctrl_cmd_exec_from_string(struct ctrl_handle *ch, const char *cmdstr); int ctrl_lookup_register(ctrl_cmd_lookup lookup); diff --git a/src/ctrl/control_if.c b/src/ctrl/control_if.c index 28f696b..c8b4722 100644 --- a/src/ctrl/control_if.c +++ b/src/ctrl/control_if.c @@ -810,3 +810,31 @@ llist_add_tail(&lh->list, &ctrl_lookup_helpers); return 0; } + +/*! \brief Helper for "local execution" of a CTRL command from a string + * The function will parse + execute the given control command string + * and return a corresponding ctrl_cmd. Caller is responsible to + * talloc_free() the return value. + * \param[in] Control Interface Command String + * \returns parsed command, including reply; NULL on error */ +struct ctrl_cmd *ctrl_cmd_exec_from_string(struct ctrl_handle *ch, const char *cmdstr) +{ + struct msgb *msg = msgb_alloc(1024, "ctrl-cmd"); + struct ctrl_cmd *cmd; + + if (!msg) + return NULL; + msg->l2h = msg->data; + osmo_strlcpy((char *)msg->data, cmdstr, msgb_tailroom(msg)); + msgb_put(msg, strlen(cmdstr)); + + cmd = ctrl_cmd_parse(ch, msg); + msgb_free(msg); + if (!cmd) + return NULL; + if (ctrl_cmd_handle(ch, cmd, NULL) < 0) { + talloc_free(cmd); + return NULL; + } + return cmd; +} diff --git a/tests/Makefile.am b/tests/Makefile.am index 352b5a7..ab80c1a 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -139,7 +139,7 @@ oap_oap_test_LDADD = $(top_builddir)/src/gsm/libosmogsm.la $(top_builddir)/src/libosmocore.la fsm_fsm_test_SOURCES = fsm/fsm_test.c -fsm_fsm_test_LDADD = $(top_builddir)/src/libosmocore.la +fsm_fsm_test_LDADD = $(top_builddir)/src/libosmocore.la $(top_builddir)/src/ctrl/libosmoctrl.la write_queue_wqueue_test_SOURCES = write_queue/wqueue_test.c write_queue_wqueue_test_LDADD = $(top_builddir)/src/libosmocore.la -- To view, visit https://gerrit.osmocom.org/2376 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Iaca748e0d942bb2a1ee7c2776b37485e1439eb0c Gerrit-PatchSet: 3 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max From gerrit-no-reply at lists.osmocom.org Thu Apr 27 08:30:47 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 27 Apr 2017 08:30:47 +0000 Subject: libosmocore[master]: Uninitialized variable in ipa_ccm_make_id_resp_from_req() In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2423 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: If5761a47b8cba73ddcc02a88cfa5c87c1970c04e Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Apr 27 08:48:58 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 27 Apr 2017 08:48:58 +0000 Subject: [MERGED] libosmocore[master]: Uninitialized variable in ipa_ccm_make_id_resp_from_req() In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: Uninitialized variable in ipa_ccm_make_id_resp_from_req() ...................................................................... Uninitialized variable in ipa_ccm_make_id_resp_from_req() We are allocating a buffer on the stack without initializing it, and then passing it into ipa_ccm_make_id_resp(). There is no real danger from this, as the buffer is only uninitialized if num_ies is 0, but let's memset() it for good style Change-Id: If5761a47b8cba73ddcc02a88cfa5c87c1970c04e Fixes: coverity CID#167040 --- M src/gsm/ipa.c 1 file changed, 2 insertions(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/gsm/ipa.c b/src/gsm/ipa.c index 01bd0c5..2c0880a 100644 --- a/src/gsm/ipa.c +++ b/src/gsm/ipa.c @@ -302,6 +302,8 @@ unsigned int num_ies = 0; const uint8_t *cur = data; + memset(ies, 0, sizeof(ies)); + /* build a array of the IEIs */ while (len >= 2) { uint8_t t_len, t_tag; -- To view, visit https://gerrit.osmocom.org/2423 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: If5761a47b8cba73ddcc02a88cfa5c87c1970c04e Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Thu Apr 27 08:49:09 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 27 Apr 2017 08:49:09 +0000 Subject: libosmo-sccp[master]: stp: Install VTY commands for FSM introspection In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2421 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I4ee881715e874eaed3cca6ac42db21260123306a Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Apr 27 08:49:10 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 27 Apr 2017 08:49:10 +0000 Subject: [MERGED] libosmo-sccp[master]: stp: Install VTY commands for FSM introspection In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: stp: Install VTY commands for FSM introspection ...................................................................... stp: Install VTY commands for FSM introspection Change-Id: I4ee881715e874eaed3cca6ac42db21260123306a --- M stp/stp_main.c 1 file changed, 1 insertion(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/stp/stp_main.c b/stp/stp_main.c index 3110ec4..564ced5 100644 --- a/stp/stp_main.c +++ b/stp/stp_main.c @@ -137,6 +137,7 @@ osmo_fsm_log_addr(false); logging_vty_add_cmds(&log_info); osmo_ss7_vty_init_sg(); + osmo_fsm_vty_add_cmds(); rc = vty_read_config_file(cmdline_config.config_file, NULL); if (rc < 0) { -- To view, visit https://gerrit.osmocom.org/2421 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I4ee881715e874eaed3cca6ac42db21260123306a Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Thu Apr 27 08:49:14 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 27 Apr 2017 08:49:14 +0000 Subject: libosmo-sccp[master]: Address some negative integer handling issues In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2422 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I8b1a676b653bcdad21cb7927d549f499950a2b73 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Apr 27 08:49:17 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 27 Apr 2017 08:49:17 +0000 Subject: libosmo-sccp[master]: xua_default_lm_fsm: Missing printf() argument In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2424 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I03c30a0d1e03ff56df80bdd1e8a7846142b6f79c Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Apr 27 08:49:32 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 27 Apr 2017 08:49:32 +0000 Subject: libosmo-netif[master]: osmux: Use osmo_gettimeofday for testing puroposes In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2418 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ic39cab74400aca8262a00c0d06884230b1a15ca3 Gerrit-PatchSet: 2 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Pau Espin Pedrol Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Apr 27 08:50:01 2017 From: gerrit-no-reply at lists.osmocom.org (Pau Espin Pedrol) Date: Thu, 27 Apr 2017 08:50:01 +0000 Subject: [MERGED] libosmo-netif[master]: osmux: Use osmo_gettimeofday for testing puroposes In-Reply-To: References: Message-ID: Pau Espin Pedrol has submitted this change and it was merged. Change subject: osmux: Use osmo_gettimeofday for testing puroposes ...................................................................... osmux: Use osmo_gettimeofday for testing puroposes This way we can use fake time and osmux_test take 700ms instead of >2sec to run. Change-Id: Ic39cab74400aca8262a00c0d06884230b1a15ca3 --- M src/osmux.c M tests/osmux/osmux_test.c 2 files changed, 26 insertions(+), 6 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/osmux.c b/src/osmux.c index 4d12427..d12a39a 100644 --- a/src/osmux.c +++ b/src/osmux.c @@ -777,7 +777,7 @@ #ifdef DEBUG_TIMING struct timeval now, diff; - gettimeofday(&now, NULL); + osmo_gettimeofday(&now, NULL); timersub(&now, &h->start, &diff); timersub(&diff,&h->when, &diff); LOGP(DLMIB, LOGL_DEBUG, "we are lagging %lu.%.6lu in scheduled " @@ -806,7 +806,7 @@ h->timer.data = h; #ifdef DEBUG_TIMING - gettimeofday(&h->start, NULL); + osmo_gettimeofday(&h->start, NULL); h->when.tv_sec = when->tv_sec; h->when.tv_usec = when->tv_usec; #endif diff --git a/tests/osmux/osmux_test.c b/tests/osmux/osmux_test.c index 9941ce3..63f89f1 100644 --- a/tests/osmux/osmux_test.c +++ b/tests/osmux/osmux_test.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -54,6 +55,8 @@ 0xf2, 0x26, 0x33, 0x65, 0x54, }; +#define PKT_TIME_USEC 20*1000 + static int rtp_pkts; static int mark_pkts; #if OSMUX_TEST_USE_TIMING @@ -67,7 +70,7 @@ #if OSMUX_TEST_USE_TIMING struct timeval now, diff; - gettimeofday(&now, NULL); + osmo_gettimeofday(&now, NULL); timersub(&now, &last, &diff); last = now; @@ -159,10 +162,17 @@ osmux_xfrm_input_deliver(&h_input); } } +#if !OSMUX_TEST_USE_TIMING + osmo_gettimeofday_override_add(0, PKT_TIME_USEC); +#endif } - while (rtp_pkts) + while (rtp_pkts) { +#if !OSMUX_TEST_USE_TIMING + osmo_gettimeofday_override_add(1, 0); +#endif osmo_select_main(0); + } if (mark_pkts) { fprintf(stdout, "RTP M bit (marker) mismatch! %d\n", mark_pkts); @@ -204,7 +214,7 @@ if (i % 4 == 0) { #if OSMUX_TEST_USE_TIMING - gettimeofday(&last, NULL); + osmo_gettimeofday(&last, NULL); #endif /* After four RTP messages, squash them into the OSMUX @@ -217,8 +227,12 @@ * messages that are extracted from OSMUX has been * delivered. */ - for (j = 0; j < k-2; j++) + for (j = 0; j < k-2; j++) { osmo_select_main(0); +#if !OSMUX_TEST_USE_TIMING + osmo_gettimeofday_override_add(0, PKT_TIME_USEC); +#endif + } k = 0; } @@ -239,6 +253,12 @@ exit(EXIT_FAILURE); } +#if !OSMUX_TEST_USE_TIMING + /* This test uses fake time to speedup the run, unless we want to manually + * test time specific stuff */ + osmo_gettimeofday_override = true; +#endif + /* This test doesn't use it, but osmux requires it internally. */ osmo_init_logging(&osmux_test_log_info); log_set_log_level(osmo_stderr_target, LOGL_DEBUG); -- To view, visit https://gerrit.osmocom.org/2418 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ic39cab74400aca8262a00c0d06884230b1a15ca3 Gerrit-PatchSet: 3 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Pau Espin Pedrol Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: Pau Espin Pedrol From gerrit-no-reply at lists.osmocom.org Thu Apr 27 08:50:01 2017 From: gerrit-no-reply at lists.osmocom.org (Pau Espin Pedrol) Date: Thu, 27 Apr 2017 08:50:01 +0000 Subject: [MERGED] libosmo-netif[master]: osmux: Check batch_factor overflow in osmux_batch_enqueue In-Reply-To: References: Message-ID: Pau Espin Pedrol has submitted this change and it was merged. Change subject: osmux: Check batch_factor overflow in osmux_batch_enqueue ...................................................................... osmux: Check batch_factor overflow in osmux_batch_enqueue This commit should fix a bug present if for instance batch_factor < 8 and osmux_batch_enqueue is called from osmux_replay_lost_packets and enough packets were lost from last received packet. Change-Id: I5d643810949aeca4762f0cad05eed534d35087f7 --- M src/osmux.c 1 file changed, 7 insertions(+), 6 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/osmux.c b/src/osmux.c index ae0bf26..1dcd04f 100644 --- a/src/osmux.c +++ b/src/osmux.c @@ -206,12 +206,13 @@ int dummy; }; -static int osmux_batch_enqueue(struct msgb *msg, struct osmux_circuit *circuit) +static int osmux_batch_enqueue(struct msgb *msg, struct osmux_circuit *circuit, + uint8_t batch_factor) { /* Too many messages per batch, discard it. The counter field of the * osmux header is just 3 bits long, so make sure it doesn't overflow. */ - if (circuit->nmsgs >= 8) { + if (circuit->nmsgs >= batch_factor || circuit->nmsgs >= 8) { struct rtp_hdr *rtph; rtph = osmo_rtp_get_hdr(msg); @@ -454,7 +455,7 @@ } static void osmux_replay_lost_packets(struct osmux_circuit *circuit, - struct rtp_hdr *cur_rtph) + struct rtp_hdr *cur_rtph, int batch_factor) { int16_t diff; struct msgb *last; @@ -500,7 +501,7 @@ DELTA_RTP_TIMESTAMP); /* No more room in this batch, skip padding with more clones */ - if (osmux_batch_enqueue(clone, circuit) < 0) { + if (osmux_batch_enqueue(clone, circuit, batch_factor) < 0) { msgb_free(clone); break; } @@ -609,10 +610,10 @@ } } /* Handle RTP packet loss scenario */ - osmux_replay_lost_packets(circuit, rtph); + osmux_replay_lost_packets(circuit, rtph, batch_factor); /* This batch is full, force batch delivery */ - if (osmux_batch_enqueue(msg, circuit) < 0) + if (osmux_batch_enqueue(msg, circuit, batch_factor) < 0) return 1; #ifdef DEBUG_MSG -- To view, visit https://gerrit.osmocom.org/2403 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I5d643810949aeca4762f0cad05eed534d35087f7 Gerrit-PatchSet: 3 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Pau Espin Pedrol Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Pau Espin Pedrol Gerrit-Reviewer: daniel From gerrit-no-reply at lists.osmocom.org Thu Apr 27 08:50:01 2017 From: gerrit-no-reply at lists.osmocom.org (Pau Espin Pedrol) Date: Thu, 27 Apr 2017 08:50:01 +0000 Subject: [MERGED] libosmo-netif[master]: osmux: Add RTP marker bit support In-Reply-To: References: Message-ID: Pau Espin Pedrol has submitted this change and it was merged. Change subject: osmux: Add RTP marker bit support ...................................................................... osmux: Add RTP marker bit support According to RFC4867 (RTP payload format for AMR): "The RTP header marker bit (M) SHALL be set to 1 if the first frameblock carried in the packet contains a speech frame which is the first in a talkspurt. For all other packets the marker bit SHALL be set to zero (M=0)." This information bit provides a way for the receiver to better synchronize the delay with ther sender. This is specially useful if AMR DTX features are supported and enabled on the sender. Change-Id: I0315658159429603f1d80a168718b026015060e9 --- M include/osmocom/netif/osmux.h M src/osmux.c M tests/osmux/osmux_test.c 3 files changed, 83 insertions(+), 7 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/include/osmocom/netif/osmux.h b/include/osmocom/netif/osmux.h index 1d93aa0..5283059 100644 --- a/include/osmocom/netif/osmux.h +++ b/include/osmocom/netif/osmux.h @@ -13,7 +13,8 @@ /* OSmux header: * - * ft (3 bits): 0=signalling, 1=voice, 2=dummy + * rtp_m (1 bit): RTP M field (RFC3550, RFC4867) + * ft (2 bits): 0=signalling, 1=voice, 2=dummy * ctr (3 bits): Number of batched AMR payloads (starting 0) * amr_f (1 bit): AMR F field (RFC3267) * amr_q (1 bit): AMR Q field (RFC3267) @@ -29,7 +30,8 @@ struct osmux_hdr { #if OSMO_IS_BIG_ENDIAN - uint8_t ft:3, + uint8_t rtp_m:1, + ft:2, ctr:3, amr_f:1, amr_q:1; @@ -37,7 +39,8 @@ uint8_t amr_q:1, amr_f:1, ctr:3, - ft:3; + ft:2, + rtp_m:1; #endif uint8_t seq; #define OSMUX_CID_MAX 255 /* determined by circuit_id */ diff --git a/src/osmux.c b/src/osmux.c index 1dcd04f..4d12427 100644 --- a/src/osmux.c +++ b/src/osmux.c @@ -105,8 +105,8 @@ } static struct msgb * -osmux_rebuild_rtp(struct osmux_out_handle *h, - struct osmux_hdr *osmuxh, void *payload, int payload_len) +osmux_rebuild_rtp(struct osmux_out_handle *h, struct osmux_hdr *osmuxh, + void *payload, int payload_len, bool first_pkt) { struct msgb *out_msg; struct rtp_hdr *rtph; @@ -129,6 +129,8 @@ rtph->timestamp = htonl(h->rtp_timestamp); rtph->sequence = htons(h->rtp_seq); rtph->ssrc = htonl(h->rtp_ssrc); + /* rtp packet with the marker bit is always warranted to be the first one */ + rtph->marker = first_pkt && osmuxh->rtp_m; msgb_put(out_msg, sizeof(struct rtp_hdr)); @@ -166,7 +168,7 @@ msg = osmux_rebuild_rtp(h, osmuxh, osmux_get_payload(osmuxh) + i * osmo_amr_bytes(osmuxh->amr_ft), - osmo_amr_bytes(osmuxh->amr_ft)); + osmo_amr_bytes(osmuxh->amr_ft), !i); if (msg == NULL) continue; @@ -264,6 +266,7 @@ osmuxh = (struct osmux_hdr *)state->out_msg->tail; osmuxh->ft = OSMUX_FT_VOICE_AMR; osmuxh->ctr = 0; + osmuxh->rtp_m = osmuxh->rtp_m || state->rtph->marker; osmuxh->amr_f = state->amrh->f; osmuxh->amr_q= state->amrh->q; osmuxh->seq = batch->seq++; @@ -593,6 +596,13 @@ if (bytes > batch->remaining_bytes) return 1; + /* Init of talkspurt (RTP M marker bit) needs to be in the first AMR slot + * of the OSMUX packet, enforce sending previous batch if required: + */ + if (rtph->marker && circuit->nmsgs != 0) + return 1; + + /* Extra validation: check if this message already exists, should not * happen but make sure we don't propagate duplicated messages. */ diff --git a/tests/osmux/osmux_test.c b/tests/osmux/osmux_test.c index 2f5a6cd..9941ce3 100644 --- a/tests/osmux/osmux_test.c +++ b/tests/osmux/osmux_test.c @@ -55,6 +55,7 @@ }; static int rtp_pkts; +static int mark_pkts; #if OSMUX_TEST_USE_TIMING static struct timeval last; #endif @@ -62,6 +63,7 @@ static void tx_cb(struct msgb *msg, void *data) { char buf[4096]; + struct rtp_hdr *rtph = (struct rtp_hdr *)msg->data; #if OSMUX_TEST_USE_TIMING struct timeval now, diff; @@ -87,6 +89,8 @@ exit(EXIT_FAILURE); } + if (rtph->marker) + mark_pkts--; rtp_pkts--; msgb_free(msg); } @@ -122,6 +126,48 @@ { printf("FAIL: test did not run successfully\n"); exit(EXIT_FAILURE); +} + +static void osmux_test_marker(int ccid) { + struct msgb *msg; + struct rtp_hdr *rtph = (struct rtp_hdr *)rtp_pkt; + struct rtp_hdr *cpy_rtph; + uint16_t seq; + int i, j; + + for (i = 0; i < 64; i++) { + + seq = ntohs(rtph->sequence); + seq++; + rtph->sequence = htons(seq); + + for (j=0; j<4; j++) { + msg = msgb_alloc(1500, "test"); + if (!msg) + exit(EXIT_FAILURE); + + memcpy(msg->data, rtp_pkt, sizeof(rtp_pkt)); + cpy_rtph = (struct rtp_hdr *) msgb_put(msg, sizeof(rtp_pkt)); + + if ((i+j) % 7 == 0) { + cpy_rtph->marker = 1; + mark_pkts++; + } + + rtp_pkts++; + while (osmux_xfrm_input(&h_input, msg, j + ccid) > 0) { + osmux_xfrm_input_deliver(&h_input); + } + } + } + + while (rtp_pkts) + osmo_select_main(0); + + if (mark_pkts) { + fprintf(stdout, "RTP M bit (marker) mismatch! %d\n", mark_pkts); + exit(EXIT_FAILURE); + } } static void osmux_test_loop(int ccid) @@ -177,6 +223,11 @@ k = 0; } } + + if (mark_pkts) { + fprintf(stdout, "RTP M bit (marker) mismatch! %d\n", mark_pkts); + exit(EXIT_FAILURE); + } } int main(void) @@ -192,12 +243,24 @@ osmo_init_logging(&osmux_test_log_info); log_set_log_level(osmo_stderr_target, LOGL_DEBUG); - osmux_xfrm_input_init(&h_input); osmux_xfrm_output_init(&h_output, 0x7000000); /* If the test takes longer than 10 seconds, abort it */ alarm(10); +#if !OSMUX_TEST_USE_TIMING + /* Check if marker bit features work correctly */ + osmux_xfrm_input_init(&h_input); + for (i = 0; i < 4; i++) + osmux_xfrm_input_open_circuit(&h_input, i, 0); + osmux_test_marker(0); + for (i = 0; i < 4; i++) + osmux_xfrm_input_close_circuit(&h_input, i); + osmux_xfrm_input_fini(&h_input); +#endif + + osmux_xfrm_input_init(&h_input); + for (i = 0; i < 2; i++) osmux_xfrm_input_open_circuit(&h_input, i, 0); -- To view, visit https://gerrit.osmocom.org/2407 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I0315658159429603f1d80a168718b026015060e9 Gerrit-PatchSet: 4 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Pau Espin Pedrol Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: Pau Espin Pedrol Gerrit-Reviewer: daniel From gerrit-no-reply at lists.osmocom.org Thu Apr 27 08:50:02 2017 From: gerrit-no-reply at lists.osmocom.org (Pau Espin Pedrol) Date: Thu, 27 Apr 2017 08:50:02 +0000 Subject: [MERGED] libosmo-netif[master]: osmux: use uint8_t everywhere for batch_factor In-Reply-To: References: Message-ID: Pau Espin Pedrol has submitted this change and it was merged. Change subject: osmux: use uint8_t everywhere for batch_factor ...................................................................... osmux: use uint8_t everywhere for batch_factor Change-Id: I9fcc8e94b2fcd843b10cb3f8f009f2348eb3a4af --- M src/osmux.c 1 file changed, 5 insertions(+), 5 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/osmux.c b/src/osmux.c index 5655269..ae0bf26 100644 --- a/src/osmux.c +++ b/src/osmux.c @@ -53,7 +53,7 @@ return osmo_amr_bytes(osmuxh->amr_ft) * (osmuxh->ctr+1); } -static uint32_t osmux_ft_dummy_size(uint8_t amr_ft, uint32_t batch_factor) +static uint32_t osmux_ft_dummy_size(uint8_t amr_ft, uint8_t batch_factor) { return sizeof(struct osmux_hdr) + (osmo_amr_bytes(amr_ft) * batch_factor); } @@ -307,7 +307,7 @@ return 0; } -static void osmux_encode_dummy(struct osmux_batch *batch, uint32_t batch_factor, +static void osmux_encode_dummy(struct osmux_batch *batch, uint8_t batch_factor, struct osmux_input_state *state) { struct osmux_hdr *osmuxh; @@ -331,7 +331,7 @@ } static struct msgb *osmux_build_batch(struct osmux_batch *batch, - uint32_t batch_size, uint32_t batch_factor) + uint32_t batch_size, uint8_t batch_factor) { struct msgb *batch_msg; struct osmux_circuit *circuit; @@ -523,7 +523,7 @@ static struct osmux_circuit * osmux_batch_add_circuit(struct osmux_batch *batch, int ccid, int dummy, - int batch_factor) + uint8_t batch_factor) { struct osmux_circuit *circuit; @@ -563,7 +563,7 @@ } static int -osmux_batch_add(struct osmux_batch *batch, int batch_factor, struct msgb *msg, +osmux_batch_add(struct osmux_batch *batch, uint32_t batch_factor, struct msgb *msg, struct rtp_hdr *rtph, int ccid) { int bytes = 0, amr_payload_len; -- To view, visit https://gerrit.osmocom.org/2406 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I9fcc8e94b2fcd843b10cb3f8f009f2348eb3a4af Gerrit-PatchSet: 2 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Pau Espin Pedrol Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Pau Espin Pedrol From gerrit-no-reply at lists.osmocom.org Thu Apr 27 08:56:36 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 27 Apr 2017 08:56:36 +0000 Subject: [PATCH] libosmo-sccp[master]: ss7_test: Avoid possible NULL pointer dereference in test case Message-ID: Review at https://gerrit.osmocom.org/2425 ss7_test: Avoid possible NULL pointer dereference in test case Change-Id: If2a7b2c988d06e8bbd2a63f3a5ceeb403bfb34ed Fixes: coverity CID#166992 --- M tests/ss7/ss7_test.c 1 file changed, 1 insertion(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/25/2425/1 diff --git a/tests/ss7/ss7_test.c b/tests/ss7/ss7_test.c index 24eabc9..e36e068 100644 --- a/tests/ss7/ss7_test.c +++ b/tests/ss7/ss7_test.c @@ -235,6 +235,7 @@ OSMO_ASSERT(osmo_ss7_as_find_by_name(s7i, "as1") == NULL); as = osmo_ss7_as_find_or_create(s7i, "as1", OSMO_SS7_ASP_PROT_M3UA); + OSMO_ASSERT(as); OSMO_ASSERT(osmo_ss7_as_find_by_name(s7i, "as1") == as); OSMO_ASSERT(osmo_ss7_as_find_by_rctx(s7i, 2342) == NULL); as->cfg.routing_key.context = 2342; -- To view, visit https://gerrit.osmocom.org/2425 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: If2a7b2c988d06e8bbd2a63f3a5ceeb403bfb34ed Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Thu Apr 27 08:56:37 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 27 Apr 2017 08:56:37 +0000 Subject: [PATCH] libosmo-sccp[master]: xua_rkm: Fix handling of RK Registration with multiple Routi... Message-ID: Review at https://gerrit.osmocom.org/2426 xua_rkm: Fix handling of RK Registration with multiple Routing Keys RKM permits multiple routing key IEs to be inside a single Routing Key Registration message. We were trying to handle this, but the counter we used as array index into the 'newly_assigned_as' array was actually always kept at zero. Change-Id: I08a962d2f242cefb67fb2dc93818c1ed532e8990 Fixes: coverity CID#166991 --- M src/xua_rkm.c 1 file changed, 7 insertions(+), 6 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/26/2426/1 diff --git a/src/xua_rkm.c b/src/xua_rkm.c index 62abfdd..d2971bc 100644 --- a/src/xua_rkm.c +++ b/src/xua_rkm.c @@ -145,9 +145,9 @@ /* SG: handle a single registration request IE (nested IEs in 'innner' */ static int handle_rkey_reg(struct osmo_ss7_asp *asp, struct xua_msg *inner, - struct msgb *resp, struct osmo_ss7_as **newly_assigned_as) + struct msgb *resp, struct osmo_ss7_as **newly_assigned_as, + unsigned int max_nas_idx, unsigned int *nas_idx) { - unsigned int nas_idx = 0; uint32_t rk_id, rctx, _tmode, dpc; enum osmo_ss7_as_traffic_mode tmode; struct osmo_ss7_as *as; @@ -245,13 +245,13 @@ } /* append to list of newly assigned as */ - if (nas_idx >= MAX_NEW_AS) { + if (*nas_idx >= max_nas_idx) { osmo_ss7_route_destroy(rt); osmo_ss7_as_destroy(as); msgb_append_reg_res(resp, rk_id, M3UA_RKM_REG_ERR_INSUFF_RESRC, 0); return -1; } - newly_assigned_as[nas_idx++] = as; + newly_assigned_as[(*nas_idx)++] = as; } else { /* not permitted to create dynamic RKM entries */ msgb_append_reg_res(resp, rk_id, M3UA_RKM_REG_ERR_PERM_DENIED, 0); @@ -270,7 +270,7 @@ struct xua_msg_part *part; struct msgb *resp = m3ua_msgb_alloc(__func__); struct osmo_ss7_as *newly_assigned_as[MAX_NEW_AS]; - unsigned int i; + unsigned int i, nas_idx = 0; memset(newly_assigned_as, 0, sizeof(newly_assigned_as)); @@ -289,7 +289,8 @@ } /* handle single registration and append result to * 'resp' */ - handle_rkey_reg(asp, inner, resp, newly_assigned_as); + handle_rkey_reg(asp, inner, resp, newly_assigned_as, + ARRAY_SIZE(newly_assigned_as), &nas_idx); xua_msg_free(inner); } -- To view, visit https://gerrit.osmocom.org/2426 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I08a962d2f242cefb67fb2dc93818c1ed532e8990 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Thu Apr 27 08:56:37 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 27 Apr 2017 08:56:37 +0000 Subject: [PATCH] libosmo-sccp[master]: sccp2sua: Avoid array overruns in sccp_is_{mandatory, optiona... Message-ID: Review at https://gerrit.osmocom.org/2427 sccp2sua: Avoid array overruns in sccp_is_{mandatory,optional}() Change-Id: Ied76c21e20332514c2ad364eea5fc17e24a3f4c6 Fixes: coverity CID#166943, CID#166980 --- M src/sccp2sua.c 1 file changed, 2 insertions(+), 2 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/27/2427/1 diff --git a/src/sccp2sua.c b/src/sccp2sua.c index 26e3f44..7268e27 100644 --- a/src/sccp2sua.c +++ b/src/sccp2sua.c @@ -881,7 +881,7 @@ { unsigned int i; - if (type > ARRAY_SIZE(sccp_mandatory)) + if (type >= ARRAY_SIZE(sccp_mandatory)) return false; for (i = 0; i < MAX_IES; i++) { @@ -903,7 +903,7 @@ { unsigned int i; - if (type > ARRAY_SIZE(sccp_optional)) + if (type >= ARRAY_SIZE(sccp_optional)) return false; for (i = 0; i < MAX_IES; i++) { -- To view, visit https://gerrit.osmocom.org/2427 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ied76c21e20332514c2ad364eea5fc17e24a3f4c6 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Thu Apr 27 09:34:08 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Thu, 27 Apr 2017 09:34:08 +0000 Subject: [PATCH] libosmo-netif[master]: deb: add missing dependency on doxygen Message-ID: Review at https://gerrit.osmocom.org/2428 deb: add missing dependency on doxygen Attempt to fix OBS nightly by adding explicit dependency on doxygen, similar to other libosmo* Change-Id: I9cfc94a115c19eedf0923caacd17d1521b4c8fe4 --- M debian/control 1 file changed, 1 insertion(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-netif refs/changes/28/2428/1 diff --git a/debian/control b/debian/control index bf403e5..11ae7d0 100644 --- a/debian/control +++ b/debian/control @@ -10,6 +10,7 @@ dh-autoreconf, libdpkg-perl, git, + doxygen, libosmocore-dev, libosmo-abis-dev, pkg-config, -- To view, visit https://gerrit.osmocom.org/2428 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I9cfc94a115c19eedf0923caacd17d1521b4c8fe4 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Max From gerrit-no-reply at lists.osmocom.org Thu Apr 27 09:37:51 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Thu, 27 Apr 2017 09:37:51 +0000 Subject: [PATCH] osmo-hlr[master]: debian: remove obsolete dependency In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2399 to look at the new patch set (#2). debian: remove obsolete dependency This should fix package build for latest Ubuntu. Change-Id: I132515cd4d89132bb59f9ee7804a5a50e8bd2775 --- M debian/control 1 file changed, 1 insertion(+), 2 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-hlr refs/changes/99/2399/2 diff --git a/debian/control b/debian/control index 766d015..571c24e 100644 --- a/debian/control +++ b/debian/control @@ -13,8 +13,7 @@ libosmo-abis-dev, libosmo-netif-dev, libdbd-sqlite3, - libsqlite3-dev, - hardening-wrapper + libsqlite3-dev Standards-Version: 3.9.6 Vcs-Browser: http://cgit.osmocom.org/osmo-hlr Vcs-Git: git://git.osmocom.org/osmo-hlr -- To view, visit https://gerrit.osmocom.org/2399 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I132515cd4d89132bb59f9ee7804a5a50e8bd2775 Gerrit-PatchSet: 2 Gerrit-Project: osmo-hlr Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: neels From gerrit-no-reply at lists.osmocom.org Thu Apr 27 09:38:16 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Thu, 27 Apr 2017 09:38:16 +0000 Subject: [PATCH] osmo-trx[master]: debian: remove obsolete dependency In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2400 to look at the new patch set (#2). debian: remove obsolete dependency This should fix package build for latest Ubuntu. Change-Id: I3ea72b4123a280a846086d083c4f3189d611f8cf --- M debian/control 1 file changed, 0 insertions(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/osmo-trx refs/changes/00/2400/2 diff --git a/debian/control b/debian/control index 151aa92..0e3b714 100644 --- a/debian/control +++ b/debian/control @@ -12,7 +12,6 @@ libuhd-dev, libusb-1.0-0-dev, libboost-all-dev, - hardening-wrapper, libfftw3-dev Standards-Version: 3.9.6 Vcs-Browser: http://cgit.osmocom.org/osmo-trx -- To view, visit https://gerrit.osmocom.org/2400 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I3ea72b4123a280a846086d083c4f3189d611f8cf Gerrit-PatchSet: 2 Gerrit-Project: osmo-trx Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Thu Apr 27 09:41:01 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 27 Apr 2017 09:41:01 +0000 Subject: libosmo-sccp[master]: sccp2sua: Avoid array overruns in sccp_is_{mandatory, optiona... In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2427 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ied76c21e20332514c2ad364eea5fc17e24a3f4c6 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Apr 27 09:41:14 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 27 Apr 2017 09:41:14 +0000 Subject: libosmo-sccp[master]: xua_rkm: Fix handling of RK Registration with multiple Routi... In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+1 -- To view, visit https://gerrit.osmocom.org/2426 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I08a962d2f242cefb67fb2dc93818c1ed532e8990 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Apr 27 09:41:23 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 27 Apr 2017 09:41:23 +0000 Subject: libosmo-sccp[master]: ss7_test: Avoid possible NULL pointer dereference in test case In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2425 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: If2a7b2c988d06e8bbd2a63f3a5ceeb403bfb34ed Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Apr 27 09:41:33 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 27 Apr 2017 09:41:33 +0000 Subject: [MERGED] libosmo-sccp[master]: ss7_test: Avoid possible NULL pointer dereference in test case In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: ss7_test: Avoid possible NULL pointer dereference in test case ...................................................................... ss7_test: Avoid possible NULL pointer dereference in test case Change-Id: If2a7b2c988d06e8bbd2a63f3a5ceeb403bfb34ed Fixes: coverity CID#166992 --- M tests/ss7/ss7_test.c 1 file changed, 1 insertion(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/tests/ss7/ss7_test.c b/tests/ss7/ss7_test.c index 24eabc9..e36e068 100644 --- a/tests/ss7/ss7_test.c +++ b/tests/ss7/ss7_test.c @@ -235,6 +235,7 @@ OSMO_ASSERT(osmo_ss7_as_find_by_name(s7i, "as1") == NULL); as = osmo_ss7_as_find_or_create(s7i, "as1", OSMO_SS7_ASP_PROT_M3UA); + OSMO_ASSERT(as); OSMO_ASSERT(osmo_ss7_as_find_by_name(s7i, "as1") == as); OSMO_ASSERT(osmo_ss7_as_find_by_rctx(s7i, 2342) == NULL); as->cfg.routing_key.context = 2342; -- To view, visit https://gerrit.osmocom.org/2425 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: If2a7b2c988d06e8bbd2a63f3a5ceeb403bfb34ed Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Thu Apr 27 09:41:33 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 27 Apr 2017 09:41:33 +0000 Subject: [MERGED] libosmo-sccp[master]: xua_default_lm_fsm: Missing printf() argument In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: xua_default_lm_fsm: Missing printf() argument ...................................................................... xua_default_lm_fsm: Missing printf() argument Change-Id: I03c30a0d1e03ff56df80bdd1e8a7846142b6f79c Fixes: coverity CID#166993 --- M src/xua_default_lm_fsm.c 1 file changed, 1 insertion(+), 1 deletion(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/xua_default_lm_fsm.c b/src/xua_default_lm_fsm.c index fc9ba3c..9308de4 100644 --- a/src/xua_default_lm_fsm.c +++ b/src/xua_default_lm_fsm.c @@ -111,7 +111,7 @@ * allocated/registered by the SG */ as = osmo_ss7_as_find_by_l_rk_id(asp->inst, l_rk_id); if (!as) { - LOGPFSM(fi, "RKM Result for unknown l_rk_id %u\n"); + LOGPFSM(fi, "RKM Result for unknown l_rk_id %u\n", l_rk_id); return -EINVAL; } as->cfg.routing_key.context = rctx; -- To view, visit https://gerrit.osmocom.org/2424 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I03c30a0d1e03ff56df80bdd1e8a7846142b6f79c Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Thu Apr 27 09:41:34 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 27 Apr 2017 09:41:34 +0000 Subject: [MERGED] libosmo-sccp[master]: Address some negative integer handling issues In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: Address some negative integer handling issues ...................................................................... Address some negative integer handling issues If for some reason we cannot resolve the file descriptor for a given FSM, we shouldn't attempt to send data through it. Fixes: coverity CID#167155, CID#167154, CID#167153, CID#167152, CID#167151, CID#167151 Change-Id: I8b1a676b653bcdad21cb7927d549f499950a2b73 --- M src/xua_asp_fsm.c 1 file changed, 14 insertions(+), 7 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/xua_asp_fsm.c b/src/xua_asp_fsm.c index 2b5bfdd..d54d45e 100644 --- a/src/xua_asp_fsm.c +++ b/src/xua_asp_fsm.c @@ -769,8 +769,10 @@ case XUA_ASP_E_SCTP_EST_IND: if (iafp->role == XUA_ASPFSM_ROLE_SG) { /* Server: Transmit IPA ID GET + Wait for Response */ - ipa_ccm_send_id_req(fd); - osmo_fsm_inst_state_chg(fi, IPA_ASP_S_WAIT_ID_RESP, 10, T_WAIT_ID_RESP); + if (fd >= 0) { + ipa_ccm_send_id_req(fd); + osmo_fsm_inst_state_chg(fi, IPA_ASP_S_WAIT_ID_RESP, 10, T_WAIT_ID_RESP); + } } else { /* Client: We simply wait for an ID GET */ osmo_fsm_inst_state_chg(fi, IPA_ASP_S_WAIT_ID_GET, 10, T_WAIT_ID_GET); @@ -818,8 +820,10 @@ osmo_ss7_as_add_asp(as, asp->cfg.name); /* TODO: OAP Authentication? */ /* Send ID_ACK */ - ipaccess_send_id_ack(fd); - osmo_fsm_inst_state_chg(fi, IPA_ASP_S_WAIT_ID_ACK2, 10, T_WAIT_ID_ACK); + if (fd >= 0) { + ipaccess_send_id_ack(fd); + osmo_fsm_inst_state_chg(fi, IPA_ASP_S_WAIT_ID_ACK2, 10, T_WAIT_ID_ACK); + } break; } return; @@ -878,8 +882,10 @@ case IPA_ASP_E_ID_ACK: /* Send ACK2 to server */ fd = get_fd_from_iafp(iafp); - ipaccess_send_id_ack(fd); - osmo_fsm_inst_state_chg(fi, IPA_ASP_S_ACTIVE, 0, 0); + if (fd >= 0) { + ipaccess_send_id_ack(fd); + osmo_fsm_inst_state_chg(fi, IPA_ASP_S_ACTIVE, 0, 0); + } break; } } @@ -911,7 +917,8 @@ case XUA_ASP_E_ASPSM_BEAT: /* PING -> PONG */ fd = get_fd_from_iafp(iafp); - ipaccess_send_pong(fd); + if (fd >= 0) + ipaccess_send_pong(fd); break; case XUA_ASP_E_ASPSM_BEAT_ACK: /* stop timer, if any */ -- To view, visit https://gerrit.osmocom.org/2422 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I8b1a676b653bcdad21cb7927d549f499950a2b73 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Thu Apr 27 09:50:08 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 27 Apr 2017 09:50:08 +0000 Subject: [PATCH] libosmo-sccp[master]: sccp_user: Add missing 'break' statement Message-ID: Review at https://gerrit.osmocom.org/2429 sccp_user: Add missing 'break' statement The missing break statement leads to an unintended fall-through which in turn prints a wrong ERROR message. Change-Id: I6618fa247b889d4162118278cd05dee85cf21899 Fixes: coverity CID#166948 --- M src/sccp_user.c 1 file changed, 1 insertion(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/29/2429/1 diff --git a/src/sccp_user.c b/src/sccp_user.c index d9e40b6..5f89f71 100644 --- a/src/sccp_user.c +++ b/src/sccp_user.c @@ -168,6 +168,7 @@ xua->mtp = omp->u.transfer; /* hand this primitive into SCCP via the SCRC code */ rc = scrc_rx_mtp_xfer_ind_xua(inst, xua); + break; default: LOGP(DLSCCP, LOGL_ERROR, "Unknown primitive %u:%u receivd\n", oph->primitive, oph->operation); -- To view, visit https://gerrit.osmocom.org/2429 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I6618fa247b889d4162118278cd05dee85cf21899 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Thu Apr 27 09:50:08 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 27 Apr 2017 09:50:08 +0000 Subject: [PATCH] libosmo-sccp[master]: osmo_sccp_user_sap_down(): Avoid uninitialized pointer deref Message-ID: Review at https://gerrit.osmocom.org/2430 osmo_sccp_user_sap_down(): Avoid uninitialized pointer deref When receiving an unknown primitive, we end up de-referencing an unassigned/uninitialized pointer for 'conn'. Let's properly catch that case and print an error message. Change-Id: Id1f5f293ea9bce8601d45164be670a7062d91802 Fixes: coverity CID#166947 --- M src/sccp_scoc.c 1 file changed, 5 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/30/2430/1 diff --git a/src/sccp_scoc.c b/src/sccp_scoc.c index 6d9916b..3a52ca6 100644 --- a/src/sccp_scoc.c +++ b/src/sccp_scoc.c @@ -1628,6 +1628,11 @@ goto out; } break; + default: + LOGP(DLSCCP, LOGL_ERROR, "Received unknown primitive %s\n", + osmo_scu_prim_name(&prim->oph)); + rc = -1; + goto out; } /* Map from primitive to event */ -- To view, visit https://gerrit.osmocom.org/2430 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Id1f5f293ea9bce8601d45164be670a7062d91802 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Thu Apr 27 10:03:51 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 27 Apr 2017 10:03:51 +0000 Subject: libosmo-sccp[master]: sccp_user: Add missing 'break' statement In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2429 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I6618fa247b889d4162118278cd05dee85cf21899 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Apr 27 10:03:54 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 27 Apr 2017 10:03:54 +0000 Subject: libosmo-sccp[master]: xua_rkm: Fix handling of RK Registration with multiple Routi... In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2426 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I08a962d2f242cefb67fb2dc93818c1ed532e8990 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Apr 27 10:04:18 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 27 Apr 2017 10:04:18 +0000 Subject: libosmo-sccp[master]: osmo_sccp_user_sap_down(): Avoid uninitialized pointer deref In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2430 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Id1f5f293ea9bce8601d45164be670a7062d91802 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Apr 27 10:12:36 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 27 Apr 2017 10:12:36 +0000 Subject: [PATCH] libosmo-sccp[master]: deliver_to_mtp_user(): Fix null pointer dereference Message-ID: Review at https://gerrit.osmocom.org/2431 deliver_to_mtp_user(): Fix null pointer dereference We had used + derefernced the 'prim' pointer before checking its validity. Change-Id: I0ca5026091e91926924b297f9342bda5f9fd38c9 Fixes: coverity CID#166946 --- M src/osmo_ss7_hmrt.c 1 file changed, 1 insertion(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/31/2431/1 diff --git a/src/osmo_ss7_hmrt.c b/src/osmo_ss7_hmrt.c index bbbb3a9..393530a 100644 --- a/src/osmo_ss7_hmrt.c +++ b/src/osmo_ss7_hmrt.c @@ -67,9 +67,9 @@ /* Create MTP-TRANSFER.ind and feed to user */ prim = m3ua_to_xfer_ind(xua); - prim->u.transfer = xua->mtp; if (!prim) return -1; + prim->u.transfer = xua->mtp; return osu->prim_cb(&prim->oph, (void *) osu->priv); } -- To view, visit https://gerrit.osmocom.org/2431 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I0ca5026091e91926924b297f9342bda5f9fd38c9 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Thu Apr 27 10:12:36 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 27 Apr 2017 10:12:36 +0000 Subject: [PATCH] libosmo-sccp[master]: scu_gen_encode_and_send(): Fix NULL pointer deref Message-ID: Review at https://gerrit.osmocom.org/2432 scu_gen_encode_and_send(): Fix NULL pointer deref We were using the 'xua' pointer before checkin if it actually is valid Change-Id: I5cd3250afc0b787b78683cd8ab6b2512e0d5c69e Fixes: coverity CID#166945 --- M src/sccp_scoc.c 1 file changed, 1 insertion(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/32/2432/1 diff --git a/src/sccp_scoc.c b/src/sccp_scoc.c index 3a52ca6..0eda7ad 100644 --- a/src/sccp_scoc.c +++ b/src/sccp_scoc.c @@ -657,8 +657,8 @@ uconp->calling_addr = conn->calling_addr; uconp->sccp_class = conn->sccp_class; uconp->importance = conn->importance; - data_ie = xua_msg_find_tag(xua, SUA_IEI_DATA); if (xua) { + data_ie = xua_msg_find_tag(xua, SUA_IEI_DATA); if (data_ie) { struct msgb *upmsg = scu_prim->oph.msg; upmsg->l2h = msgb_put(upmsg, data_ie->len); -- To view, visit https://gerrit.osmocom.org/2432 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I5cd3250afc0b787b78683cd8ab6b2512e0d5c69e Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Thu Apr 27 10:12:36 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 27 Apr 2017 10:12:36 +0000 Subject: [PATCH] libosmo-sccp[master]: ss7_test: Fix '=' that should have been '==' Message-ID: Review at https://gerrit.osmocom.org/2433 ss7_test: Fix '=' that should have been '==' Change-Id: I1be4529c73992cb342a62aa19ba79be25e982620 Fixes: coverity CID#166944 --- M tests/ss7/ss7_test.c 1 file changed, 1 insertion(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/33/2433/1 diff --git a/tests/ss7/ss7_test.c b/tests/ss7/ss7_test.c index e36e068..7c51767 100644 --- a/tests/ss7/ss7_test.c +++ b/tests/ss7/ss7_test.c @@ -32,7 +32,7 @@ OSMO_ASSERT(s7i->cfg.pc_fmt.component_len[0] == 3); OSMO_ASSERT(s7i->cfg.pc_fmt.component_len[1] == 8); OSMO_ASSERT(s7i->cfg.pc_fmt.component_len[2] == 3); - OSMO_ASSERT(s7i->cfg.pc_fmt.delimiter = '.'); + OSMO_ASSERT(s7i->cfg.pc_fmt.delimiter == '.'); } static void parse_print_mask(const char *in) -- To view, visit https://gerrit.osmocom.org/2433 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I1be4529c73992cb342a62aa19ba79be25e982620 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Thu Apr 27 10:12:36 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 27 Apr 2017 10:12:36 +0000 Subject: [PATCH] libosmo-sccp[master]: sclc_rx_cldt(): Don't try to dereference user data_ie withou... Message-ID: Review at https://gerrit.osmocom.org/2434 sclc_rx_cldt(): Don't try to dereference user data_ie without check While the SUA / SCCP2SUA code is ensuring that mandatory information elements such as the user data IE in a CLDT message, we might still have current or future callers of sclc_rx_cldt() that don't comply with that. So let's make sure data_ie is valid before dereferencing it. Change-Id: Ia102f6c4cd5c6c3f823cb219635c42b9a87765f8 Fixes: coverity CID#166942 --- M src/sccp_sclc.c 1 file changed, 5 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/34/2434/1 diff --git a/src/sccp_sclc.c b/src/sccp_sclc.c index 7cdfac5..262b2c0 100644 --- a/src/sccp_sclc.c +++ b/src/sccp_sclc.c @@ -156,6 +156,11 @@ struct osmo_sccp_user *scu; uint32_t protocol_class; + if (!data_ie) { + LOGP(DLSCCP, LOGL_ERROR, "SCCP/SUA CLDT without user data?!?\n"); + return -1; + } + /* fill primitive */ prim = (struct osmo_scu_prim *) msgb_put(upmsg, sizeof(*prim)); param = &prim->u.unitdata; -- To view, visit https://gerrit.osmocom.org/2434 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ia102f6c4cd5c6c3f823cb219635c42b9a87765f8 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Thu Apr 27 10:12:37 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 27 Apr 2017 10:12:37 +0000 Subject: [PATCH] libosmo-sccp[master]: m3ua_to_xfer_ind(): don't use data_ie without checking it ex... Message-ID: Review at https://gerrit.osmocom.org/2435 m3ua_to_xfer_ind(): don't use data_ie without checking it exists Change-Id: I5f7551e49c1b4ea417bee3516da1b2ece5ee0699 Fixes: coverity CID#166941 --- M src/osmo_ss7_hmrt.c 1 file changed, 1 insertion(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/35/2435/1 diff --git a/src/osmo_ss7_hmrt.c b/src/osmo_ss7_hmrt.c index 393530a..e66762d 100644 --- a/src/osmo_ss7_hmrt.c +++ b/src/osmo_ss7_hmrt.c @@ -25,7 +25,7 @@ struct m3ua_data_hdr *data_hdr; struct msgb *upmsg = m3ua_msgb_alloc("M3UA MTP-TRANSFER.ind"); - if (data_ie->len < sizeof(*data_hdr)) { + if (!data_ie || data_ie->len < sizeof(*data_hdr)) { /* FIXME: ERROR message */ msgb_free(upmsg); return NULL; -- To view, visit https://gerrit.osmocom.org/2435 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I5f7551e49c1b4ea417bee3516da1b2ece5ee0699 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Thu Apr 27 10:12:37 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 27 Apr 2017 10:12:37 +0000 Subject: [PATCH] libosmo-sccp[master]: sclc_rx_cldr(): Don't try to dereference user data_ie withou... Message-ID: Review at https://gerrit.osmocom.org/2436 sclc_rx_cldr(): Don't try to dereference user data_ie without check While the SUA / SCCP2SUA code is ensuring that mandatory information elements such as the user data IE in a CLD$ message, we might still have current or future callers of sclc_rx_cldr() that don't comply with that. So let's make sure data_ie is valid before dereferencing it. Change-Id: I7c1010b0ac82ee0b7bd5e2c7413899695eae0070 Fixes: coverity CID#166940 --- M src/sccp_sclc.c 1 file changed, 5 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/36/2436/1 diff --git a/src/sccp_sclc.c b/src/sccp_sclc.c index 262b2c0..8f9e577 100644 --- a/src/sccp_sclc.c +++ b/src/sccp_sclc.c @@ -204,6 +204,11 @@ struct msgb *upmsg = sccp_msgb_alloc(__func__); struct osmo_sccp_user *scu; + if (!data_ie) { + LOGP(DLSCCP, LOGL_ERROR, "SCCP/SUA CLDR without user data?!?\n"); + return -1; + } + /* fill primitive */ prim = (struct osmo_scu_prim *) msgb_put(upmsg, sizeof(*prim)); param = &prim->u.notice; -- To view, visit https://gerrit.osmocom.org/2436 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I7c1010b0ac82ee0b7bd5e2c7413899695eae0070 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Thu Apr 27 10:12:37 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 27 Apr 2017 10:12:37 +0000 Subject: [PATCH] libosmo-sccp[master]: m3ua_decode_notify(): Ensure status_ie is valid before using it Message-ID: Review at https://gerrit.osmocom.org/2437 m3ua_decode_notify(): Ensure status_ie is valid before using it Change-Id: I3cdd0fbdffcbeeb68dbc979385de045220ea0b0c Fixes: coverity CID#166939 --- M src/m3ua.c 1 file changed, 4 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/37/2437/1 diff --git a/src/m3ua.c b/src/m3ua.c index b204708..d96bd18 100644 --- a/src/m3ua.c +++ b/src/m3ua.c @@ -412,6 +412,10 @@ /* cannot use xua_msg_get_u32() as it does endian conversion */ status_ie = xua_msg_find_tag(xua, M3UA_IEI_STATUS); + if (!status_ie) { + LOGP(DLM3UA, LOGL_ERROR, "M3UA NOTIFY without Status IE\n"); + return -1; + } status = *(uint32_t *) status_ie->dat; aspid_ie = xua_msg_find_tag(xua, M3UA_IEI_ASP_ID); -- To view, visit https://gerrit.osmocom.org/2437 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I3cdd0fbdffcbeeb68dbc979385de045220ea0b0c Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Thu Apr 27 10:14:59 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Thu, 27 Apr 2017 10:14:59 +0000 Subject: [MERGED] osmo-bts[master]: Fix RTP duration adjustment not done when speech resumes in ... In-Reply-To: References: Message-ID: Max has submitted this change and it was merged. Change subject: Fix RTP duration adjustment not done when speech resumes in DTX mode. ...................................................................... Fix RTP duration adjustment not done when speech resumes in DTX mode. RTP jitter increases continuously because duration is not updated when speech resumes in DTX mode. Change-Id: Ib51ed95a449369222c957b3acebd9ce1f66c5435 --- M src/common/l1sap.c 1 file changed, 2 insertions(+), 6 deletions(-) Approvals: Max: Looks good to me, but someone else must approve Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/common/l1sap.c b/src/common/l1sap.c index 57a858c..6c509e3 100644 --- a/src/common/l1sap.c +++ b/src/common/l1sap.c @@ -76,12 +76,8 @@ { uint32_t samples_passed, r; - /* don't adjust duration: - - when no DTX enabled at all - - for ONSET RTP packet to avoid timestamp gap with subsequent SPEECH - RTP packet*/ - if (lchan->rtp_tx_marker || - lchan->ts->trx->bts->dtxu == GSM48_DTX_SHALL_NOT_BE_USED) + /* don't adjust duration when DTX is not enabled */ + if (lchan->ts->trx->bts->dtxu == GSM48_DTX_SHALL_NOT_BE_USED) return GSM_RTP_DURATION; if (lchan->tch.last_fn != LCHAN_FN_DUMMY) { -- To view, visit https://gerrit.osmocom.org/1983 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ib51ed95a449369222c957b3acebd9ce1f66c5435 Gerrit-PatchSet: 3 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: jfdionne Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max From gerrit-no-reply at lists.osmocom.org Thu Apr 27 10:17:18 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Thu, 27 Apr 2017 10:17:18 +0000 Subject: osmo-trx[master]: cosmetic: remove code duplication In-Reply-To: References: Message-ID: Patch Set 4: Code-Review+1 -- To view, visit https://gerrit.osmocom.org/2103 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ic8d8534a343e27cde79ddc85be4998ebd0cb6e5c Gerrit-PatchSet: 4 Gerrit-Project: osmo-trx Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Apr 27 10:18:42 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 27 Apr 2017 10:18:42 +0000 Subject: libosmo-sccp[master]: deliver_to_mtp_user(): Fix null pointer dereference In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2431 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I0ca5026091e91926924b297f9342bda5f9fd38c9 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Apr 27 10:19:00 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 27 Apr 2017 10:19:00 +0000 Subject: libosmo-sccp[master]: scu_gen_encode_and_send(): Fix NULL pointer deref In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2432 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I5cd3250afc0b787b78683cd8ab6b2512e0d5c69e Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Apr 27 10:19:07 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Thu, 27 Apr 2017 10:19:07 +0000 Subject: osmo-pcu[master]: fix PACCH paging: don't return early in case of NULL TBF In-Reply-To: References: Message-ID: Patch Set 2: Out of curiosity - how this was found? I mean in what way PACCH paging was broken as a result of incorrect fix? Is there a way this can be formulated as a unit test? -- To view, visit https://gerrit.osmocom.org/2420 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ib79f4a945e211a13ac7d1e511cc37b0940ac6202 Gerrit-PatchSet: 2 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Apr 27 10:19:12 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 27 Apr 2017 10:19:12 +0000 Subject: libosmo-sccp[master]: ss7_test: Fix '=' that should have been '==' In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2433 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I1be4529c73992cb342a62aa19ba79be25e982620 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Apr 27 10:19:30 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 27 Apr 2017 10:19:30 +0000 Subject: libosmo-sccp[master]: sclc_rx_cldt(): Don't try to dereference user data_ie withou... In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2434 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ia102f6c4cd5c6c3f823cb219635c42b9a87765f8 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Apr 27 10:19:41 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 27 Apr 2017 10:19:41 +0000 Subject: libosmo-sccp[master]: m3ua_to_xfer_ind(): don't use data_ie without checking it ex... In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2435 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I5f7551e49c1b4ea417bee3516da1b2ece5ee0699 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Apr 27 10:19:58 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 27 Apr 2017 10:19:58 +0000 Subject: libosmo-sccp[master]: sclc_rx_cldr(): Don't try to dereference user data_ie withou... In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2436 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I7c1010b0ac82ee0b7bd5e2c7413899695eae0070 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Apr 27 10:20:10 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 27 Apr 2017 10:20:10 +0000 Subject: libosmo-sccp[master]: m3ua_decode_notify(): Ensure status_ie is valid before using it In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2437 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I3cdd0fbdffcbeeb68dbc979385de045220ea0b0c Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Apr 27 10:20:31 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 27 Apr 2017 10:20:31 +0000 Subject: osmo-hlr[master]: debian: remove obsolete dependency In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2399 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I132515cd4d89132bb59f9ee7804a5a50e8bd2775 Gerrit-PatchSet: 2 Gerrit-Project: osmo-hlr Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: neels Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Apr 27 10:20:46 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 27 Apr 2017 10:20:46 +0000 Subject: osmo-trx[master]: debian: remove obsolete dependency In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+1 -- To view, visit https://gerrit.osmocom.org/2400 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I3ea72b4123a280a846086d083c4f3189d611f8cf Gerrit-PatchSet: 2 Gerrit-Project: osmo-trx Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: neels Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Apr 27 10:20:52 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Thu, 27 Apr 2017 10:20:52 +0000 Subject: [MERGED] osmo-hlr[master]: debian: remove obsolete dependency In-Reply-To: References: Message-ID: Max has submitted this change and it was merged. Change subject: debian: remove obsolete dependency ...................................................................... debian: remove obsolete dependency This should fix package build for latest Ubuntu. Change-Id: I132515cd4d89132bb59f9ee7804a5a50e8bd2775 --- M debian/control 1 file changed, 1 insertion(+), 2 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/debian/control b/debian/control index 766d015..571c24e 100644 --- a/debian/control +++ b/debian/control @@ -13,8 +13,7 @@ libosmo-abis-dev, libosmo-netif-dev, libdbd-sqlite3, - libsqlite3-dev, - hardening-wrapper + libsqlite3-dev Standards-Version: 3.9.6 Vcs-Browser: http://cgit.osmocom.org/osmo-hlr Vcs-Git: git://git.osmocom.org/osmo-hlr -- To view, visit https://gerrit.osmocom.org/2399 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I132515cd4d89132bb59f9ee7804a5a50e8bd2775 Gerrit-PatchSet: 3 Gerrit-Project: osmo-hlr Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: neels From gerrit-no-reply at lists.osmocom.org Thu Apr 27 10:20:57 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 27 Apr 2017 10:20:57 +0000 Subject: libosmo-netif[master]: deb: add missing dependency on doxygen In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2428 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I9cfc94a115c19eedf0923caacd17d1521b4c8fe4 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Apr 27 10:21:00 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 27 Apr 2017 10:21:00 +0000 Subject: [MERGED] libosmo-netif[master]: deb: add missing dependency on doxygen In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: deb: add missing dependency on doxygen ...................................................................... deb: add missing dependency on doxygen Attempt to fix OBS nightly by adding explicit dependency on doxygen, similar to other libosmo* Change-Id: I9cfc94a115c19eedf0923caacd17d1521b4c8fe4 --- M debian/control 1 file changed, 1 insertion(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/debian/control b/debian/control index bf403e5..11ae7d0 100644 --- a/debian/control +++ b/debian/control @@ -10,6 +10,7 @@ dh-autoreconf, libdpkg-perl, git, + doxygen, libosmocore-dev, libosmo-abis-dev, pkg-config, -- To view, visit https://gerrit.osmocom.org/2428 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I9cfc94a115c19eedf0923caacd17d1521b4c8fe4 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Thu Apr 27 10:21:18 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 27 Apr 2017 10:21:18 +0000 Subject: openbsc[master]: deb: install openbsc.pc In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2009 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I5472a8fe74a81b98598fbdb688db778cb7d09e62 Gerrit-PatchSet: 2 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Apr 27 10:21:20 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 27 Apr 2017 10:21:20 +0000 Subject: [MERGED] openbsc[master]: deb: install openbsc.pc In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: deb: install openbsc.pc ...................................................................... deb: install openbsc.pc Previously openbsc.pc was generated but not installed as part of openbsc-dev. Change-Id: I5472a8fe74a81b98598fbdb688db778cb7d09e62 --- M debian/openbsc-dev.install 1 file changed, 1 insertion(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/debian/openbsc-dev.install b/debian/openbsc-dev.install index 398321a..0c05545 100644 --- a/debian/openbsc-dev.install +++ b/debian/openbsc-dev.install @@ -1,3 +1,4 @@ openbsc/include/openbsc/gsm_data_shared.h usr/src/osmocom/openbsc/openbsc/include/openbsc/ openbsc/include/openbsc/common_cs.h usr/src/osmocom/openbsc/openbsc/include/openbsc/ openbsc/src/libcommon/gsm_data_shared.c usr/src/osmocom/openbsc/openbsc/src/libcommon/ +usr/lib/*/pkgconfig/openbsc.pc -- To view, visit https://gerrit.osmocom.org/2009 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I5472a8fe74a81b98598fbdb688db778cb7d09e62 Gerrit-PatchSet: 3 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Thu Apr 27 10:21:45 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 27 Apr 2017 10:21:45 +0000 Subject: [MERGED] libosmo-sccp[master]: osmo_sccp_user_sap_down(): Avoid uninitialized pointer deref In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: osmo_sccp_user_sap_down(): Avoid uninitialized pointer deref ...................................................................... osmo_sccp_user_sap_down(): Avoid uninitialized pointer deref When receiving an unknown primitive, we end up de-referencing an unassigned/uninitialized pointer for 'conn'. Let's properly catch that case and print an error message. Change-Id: Id1f5f293ea9bce8601d45164be670a7062d91802 Fixes: coverity CID#166947 --- M src/sccp_scoc.c 1 file changed, 5 insertions(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/sccp_scoc.c b/src/sccp_scoc.c index 6d9916b..3a52ca6 100644 --- a/src/sccp_scoc.c +++ b/src/sccp_scoc.c @@ -1628,6 +1628,11 @@ goto out; } break; + default: + LOGP(DLSCCP, LOGL_ERROR, "Received unknown primitive %s\n", + osmo_scu_prim_name(&prim->oph)); + rc = -1; + goto out; } /* Map from primitive to event */ -- To view, visit https://gerrit.osmocom.org/2430 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Id1f5f293ea9bce8601d45164be670a7062d91802 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Thu Apr 27 10:21:45 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 27 Apr 2017 10:21:45 +0000 Subject: [MERGED] libosmo-sccp[master]: sccp_user: Add missing 'break' statement In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: sccp_user: Add missing 'break' statement ...................................................................... sccp_user: Add missing 'break' statement The missing break statement leads to an unintended fall-through which in turn prints a wrong ERROR message. Change-Id: I6618fa247b889d4162118278cd05dee85cf21899 Fixes: coverity CID#166948 --- M src/sccp_user.c 1 file changed, 1 insertion(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/sccp_user.c b/src/sccp_user.c index d9e40b6..5f89f71 100644 --- a/src/sccp_user.c +++ b/src/sccp_user.c @@ -168,6 +168,7 @@ xua->mtp = omp->u.transfer; /* hand this primitive into SCCP via the SCRC code */ rc = scrc_rx_mtp_xfer_ind_xua(inst, xua); + break; default: LOGP(DLSCCP, LOGL_ERROR, "Unknown primitive %u:%u receivd\n", oph->primitive, oph->operation); -- To view, visit https://gerrit.osmocom.org/2429 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I6618fa247b889d4162118278cd05dee85cf21899 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Thu Apr 27 10:21:45 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 27 Apr 2017 10:21:45 +0000 Subject: [MERGED] libosmo-sccp[master]: sccp2sua: Avoid array overruns in sccp_is_{mandatory, optiona... In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: sccp2sua: Avoid array overruns in sccp_is_{mandatory,optional}() ...................................................................... sccp2sua: Avoid array overruns in sccp_is_{mandatory,optional}() Change-Id: Ied76c21e20332514c2ad364eea5fc17e24a3f4c6 Fixes: coverity CID#166943, CID#166980 --- M src/sccp2sua.c 1 file changed, 2 insertions(+), 2 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/sccp2sua.c b/src/sccp2sua.c index 26e3f44..7268e27 100644 --- a/src/sccp2sua.c +++ b/src/sccp2sua.c @@ -881,7 +881,7 @@ { unsigned int i; - if (type > ARRAY_SIZE(sccp_mandatory)) + if (type >= ARRAY_SIZE(sccp_mandatory)) return false; for (i = 0; i < MAX_IES; i++) { @@ -903,7 +903,7 @@ { unsigned int i; - if (type > ARRAY_SIZE(sccp_optional)) + if (type >= ARRAY_SIZE(sccp_optional)) return false; for (i = 0; i < MAX_IES; i++) { -- To view, visit https://gerrit.osmocom.org/2427 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ied76c21e20332514c2ad364eea5fc17e24a3f4c6 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Thu Apr 27 10:21:46 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 27 Apr 2017 10:21:46 +0000 Subject: [MERGED] libosmo-sccp[master]: xua_rkm: Fix handling of RK Registration with multiple Routi... In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: xua_rkm: Fix handling of RK Registration with multiple Routing Keys ...................................................................... xua_rkm: Fix handling of RK Registration with multiple Routing Keys RKM permits multiple routing key IEs to be inside a single Routing Key Registration message. We were trying to handle this, but the counter we used as array index into the 'newly_assigned_as' array was actually always kept at zero. Change-Id: I08a962d2f242cefb67fb2dc93818c1ed532e8990 Fixes: coverity CID#166991 --- M src/xua_rkm.c 1 file changed, 7 insertions(+), 6 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/xua_rkm.c b/src/xua_rkm.c index 62abfdd..d2971bc 100644 --- a/src/xua_rkm.c +++ b/src/xua_rkm.c @@ -145,9 +145,9 @@ /* SG: handle a single registration request IE (nested IEs in 'innner' */ static int handle_rkey_reg(struct osmo_ss7_asp *asp, struct xua_msg *inner, - struct msgb *resp, struct osmo_ss7_as **newly_assigned_as) + struct msgb *resp, struct osmo_ss7_as **newly_assigned_as, + unsigned int max_nas_idx, unsigned int *nas_idx) { - unsigned int nas_idx = 0; uint32_t rk_id, rctx, _tmode, dpc; enum osmo_ss7_as_traffic_mode tmode; struct osmo_ss7_as *as; @@ -245,13 +245,13 @@ } /* append to list of newly assigned as */ - if (nas_idx >= MAX_NEW_AS) { + if (*nas_idx >= max_nas_idx) { osmo_ss7_route_destroy(rt); osmo_ss7_as_destroy(as); msgb_append_reg_res(resp, rk_id, M3UA_RKM_REG_ERR_INSUFF_RESRC, 0); return -1; } - newly_assigned_as[nas_idx++] = as; + newly_assigned_as[(*nas_idx)++] = as; } else { /* not permitted to create dynamic RKM entries */ msgb_append_reg_res(resp, rk_id, M3UA_RKM_REG_ERR_PERM_DENIED, 0); @@ -270,7 +270,7 @@ struct xua_msg_part *part; struct msgb *resp = m3ua_msgb_alloc(__func__); struct osmo_ss7_as *newly_assigned_as[MAX_NEW_AS]; - unsigned int i; + unsigned int i, nas_idx = 0; memset(newly_assigned_as, 0, sizeof(newly_assigned_as)); @@ -289,7 +289,8 @@ } /* handle single registration and append result to * 'resp' */ - handle_rkey_reg(asp, inner, resp, newly_assigned_as); + handle_rkey_reg(asp, inner, resp, newly_assigned_as, + ARRAY_SIZE(newly_assigned_as), &nas_idx); xua_msg_free(inner); } -- To view, visit https://gerrit.osmocom.org/2426 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I08a962d2f242cefb67fb2dc93818c1ed532e8990 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Thu Apr 27 10:35:35 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 27 Apr 2017 10:35:35 +0000 Subject: [PATCH] libosmo-sccp[master]: sccp_scoc: don't pass variable as argument if we know it's NULL Message-ID: Review at https://gerrit.osmocom.org/2438 sccp_scoc: don't pass variable as argument if we know it's NULL xua will always be NULL in one particular switch case of scoc_fsm_conn_pend_out(), so let's use NULL directly rather than obscure it though a variable that might be understood as this being non-NULL in some cases. Change-Id: Id6dc56442441489aefc706bcebc49197ca3dae1e Fixes: coverity CID#166934 --- M src/sccp_scoc.c 1 file changed, 1 insertion(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/38/2438/1 diff --git a/src/sccp_scoc.c b/src/sccp_scoc.c index 0eda7ad..5e91ea4 100644 --- a/src/sccp_scoc.c +++ b/src/sccp_scoc.c @@ -824,7 +824,7 @@ break; case SCOC_E_CONN_TMR_EXP: /* N-DISCONNECT.ind to user */ - scu_gen_encode_and_send(conn, event, xua, OSMO_SCU_PRIM_N_DISCONNECT, + scu_gen_encode_and_send(conn, event, NULL, OSMO_SCU_PRIM_N_DISCONNECT, PRIM_OP_INDICATION); /* below implicitly releases resources + local ref */ osmo_fsm_inst_state_chg(fi, S_IDLE, 0, 0); -- To view, visit https://gerrit.osmocom.org/2438 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Id6dc56442441489aefc706bcebc49197ca3dae1e Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Thu Apr 27 10:35:35 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 27 Apr 2017 10:35:35 +0000 Subject: [PATCH] libosmo-sccp[master]: osmo_ss7_user_unregister(): Don't dereference NULL user Message-ID: Review at https://gerrit.osmocom.org/2439 osmo_ss7_user_unregister(): Don't dereference NULL user The 'user' argument to osmo_ss7_user_unregister() can be NULL, so let's make sure we don't dereference it. Change-Id: Ia34b181dcbcb179b2639e2f405364cc952069842 Fixes: coverity CID#166933 --- M src/osmo_ss7.c 1 file changed, 2 insertions(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/39/2439/1 diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index 31c0dc5..d952ecd 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -442,7 +442,8 @@ if (user && (inst->user[service_ind] != user)) return -EINVAL; - user->inst = NULL; + if (user) + user->inst = NULL; inst->user[service_ind] = NULL; return 0; -- To view, visit https://gerrit.osmocom.org/2439 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ia34b181dcbcb179b2639e2f405364cc952069842 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Thu Apr 27 10:35:36 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 27 Apr 2017 10:35:36 +0000 Subject: [PATCH] libosmo-sccp[master]: osmo_sccp_addr_parse() Fix point code integer precision hand... Message-ID: Review at https://gerrit.osmocom.org/2440 osmo_sccp_addr_parse() Fix point code integer precision handling "(cur[1] << 8) & 0x3f" is always 0 regardless of the values of its operands. Change-Id: Ie47e632f4bca490baf4282dc5d55ee55ca7f1ae8 Fixes: coverity CID#166932 --- M src/sccp2sua.c 1 file changed, 2 insertions(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/40/2440/1 diff --git a/src/sccp2sua.c b/src/sccp2sua.c index 7268e27..753d9a4 100644 --- a/src/sccp2sua.c +++ b/src/sccp2sua.c @@ -134,7 +134,8 @@ if (sca->point_code_indicator) { out->presence |= OSMO_SCCP_ADDR_T_PC; - out->pc = ((cur[1] << 8) & 0x3f) | cur[0]; + out->pc = (uint16_t) (cur[1] & 0x3f) << 8; + out->pc |= cur[0]; cur += 2; } -- To view, visit https://gerrit.osmocom.org/2440 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ie47e632f4bca490baf4282dc5d55ee55ca7f1ae8 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte From gerrit-no-reply at lists.osmocom.org Thu Apr 27 14:12:23 2017 From: gerrit-no-reply at lists.osmocom.org (jfdionne) Date: Thu, 27 Apr 2017 14:12:23 +0000 Subject: [PATCH] libosmocore[master]: Fix wrongful GSM codecs SID frame detection in DTX. Message-ID: Review at https://gerrit.osmocom.org/2441 Fix wrongful GSM codecs SID frame detection in DTX. Based on ETSI TS 101 318 section 5.1.2 the 95 bits SID code word is not detected correctly due to a wrongful offset in the bits location indexes. Change-Id: I45d98c6edf267f313883503a65385190ffbc65ca --- M src/codec/gsm610.c 1 file changed, 10 insertions(+), 10 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/41/2441/1 diff --git a/src/codec/gsm610.c b/src/codec/gsm610.c index 47faea2..221ddcc 100644 --- a/src/codec/gsm610.c +++ b/src/codec/gsm610.c @@ -306,16 +306,16 @@ bool osmo_fr_check_sid(uint8_t *rtp_payload, size_t payload_len) { struct bitvec bv; - uint16_t i, z_bits[] = { 59, 60, 62, 63, 65, 66, 68, 69, 71, 72, 74, 75, - 77, 78, 80, 81, 83, 84, 86, 87, 89, 90, 92, 93, - 95, 96, 115, 116, 118, 119, 121, 122, 124, 125, - 127, 128, 130, 131, 133, 134, 136, 137, 139, - 140, 142, 143, 145, 146, 148, 149, 151, 152, - 171, 172, 174, 175, 177, 178, 180, 181, 183, - 184, 186, 187, 189, 190, 192, 193, 195, 196, - 198, 199, 201, 202, 204, 205, 207, 208, 227, - 228, 230, 231, 233, 234, 236, 237, 239, 242, - 245, 248, 251, 254, 257, 260, 263 }; + uint16_t i, z_bits[] = { 57, 58, 60, 61, 63, 64, 66, 67, 69, 70, 72, 73, + 75, 76, 78, 79, 81, 82, 84, 85, 87, 88, 90, 91, + 93, 94, 113, 114, 116, 117, 119, 120, 122, 123, + 125, 126, 128, 129, 131, 132, 134, 135, 137, + 138, 140, 141, 143, 144, 146, 147, 149, 150, + 169, 170, 172, 173, 175, 176, 178, 179, 181, + 182, 184, 185, 187, 189, 190, 191, 193, 194, + 196, 197, 199, 200, 202, 203, 205, 206, 225, + 226, 228, 229, 231, 232, 234, 235, 237, 240, + 243, 246, 249, 252, 255, 258, 261 }; /* signature does not match Full Rate SID */ if ((rtp_payload[0] >> 4) != 0xD) -- To view, visit https://gerrit.osmocom.org/2441 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I45d98c6edf267f313883503a65385190ffbc65ca Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: jfdionne From gerrit-no-reply at lists.osmocom.org Thu Apr 27 14:51:20 2017 From: gerrit-no-reply at lists.osmocom.org (Pau Espin Pedrol) Date: Thu, 27 Apr 2017 14:51:20 +0000 Subject: [PATCH] osmo-gsm-manuals[master]: OsmoGSMTester: fix typo in example Message-ID: Review at https://gerrit.osmocom.org/2442 OsmoGSMTester: fix typo in example Change-Id: Iac0efc7fc561377c6a8a51ab7cd434e47bab458a --- M OsmoGSMTester/chapters/intro.adoc 1 file changed, 1 insertion(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/osmo-gsm-manuals refs/changes/42/2442/1 diff --git a/OsmoGSMTester/chapters/intro.adoc b/OsmoGSMTester/chapters/intro.adoc index c45e808..1ddea63 100644 --- a/OsmoGSMTester/chapters/intro.adoc +++ b/OsmoGSMTester/chapters/intro.adoc @@ -239,7 +239,7 @@ 'mo_mt_sms.py' test from the suite, e.g. to investigate a test failure: ---- -osmo-gsm-tester.py path/to/my-trial -s sms:sysmo -l dbg -T -t mo_mt +osmo-gsm-tester.py path/to/my-trial -s sms:sysmo -l dbg -T -t mo_mt_sms ---- A test script may also be run step-by-step in a python debugger, see -- To view, visit https://gerrit.osmocom.org/2442 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Iac0efc7fc561377c6a8a51ab7cd434e47bab458a Gerrit-PatchSet: 1 Gerrit-Project: osmo-gsm-manuals Gerrit-Branch: master Gerrit-Owner: Pau Espin Pedrol From gerrit-no-reply at lists.osmocom.org Thu Apr 27 16:11:35 2017 From: gerrit-no-reply at lists.osmocom.org (Pau Espin Pedrol) Date: Thu, 27 Apr 2017 16:11:35 +0000 Subject: [PATCH] osmo-gsm-tester[master]: jenkins-run: Provide a link to the latest trial archived Message-ID: Review at https://gerrit.osmocom.org/2443 jenkins-run: Provide a link to the latest trial archived Change-Id: I26ddf55110738bd1944ccbfe72e8410ff9811392 --- M contrib/jenkins-run.sh 1 file changed, 4 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-gsm-tester refs/changes/43/2443/1 diff --git a/contrib/jenkins-run.sh b/contrib/jenkins-run.sh index b0b4925..dc45cf5 100755 --- a/contrib/jenkins-run.sh +++ b/contrib/jenkins-run.sh @@ -34,4 +34,8 @@ ssh "$osmo_gsm_tester_host" "mv $tmp_dir/$trial_name $osmo_gsm_tester_dir" trial_dir="$osmo_gsm_tester_dir/$trial_name" +# Make trial-altest.tgz always point to latest one +ssh "$osmo_gsm_tester_host" "unlink $osmo_gsm_tester_dir/trial-latest" +ssh "$osmo_gsm_tester_host" "ln -s $trial_dir $osmo_gsm_tester_dir/trial-latest" + ssh "$osmo_gsm_tester_host" "$osmo_gsm_tester_src/src/osmo-gsm-tester.py $trial_dir -T" -- To view, visit https://gerrit.osmocom.org/2443 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I26ddf55110738bd1944ccbfe72e8410ff9811392 Gerrit-PatchSet: 1 Gerrit-Project: osmo-gsm-tester Gerrit-Branch: master Gerrit-Owner: Pau Espin Pedrol From gerrit-no-reply at lists.osmocom.org Thu Apr 27 17:01:22 2017 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 27 Apr 2017 17:01:22 +0000 Subject: osmo-gsm-tester[master]: jenkins-run: Provide a link to the latest trial archived In-Reply-To: References: Message-ID: Patch Set 1: Code-Review-1 (1 comment) https://gerrit.osmocom.org/#/c/2443/1/contrib/jenkins-run.sh File contrib/jenkins-run.sh: Line 39: ssh "$osmo_gsm_tester_host" "ln -s $trial_dir $osmo_gsm_tester_dir/trial-latest" There's an issue of "polluting" the namespace of trials. This trial dir serves as a name and trial.py assumes it to be a unique entity. Note that trial.py is capable of finding a trial that has not yet run, for a possible daemon that automatically discovers new trials that showed up (see http://git.osmocom.org/osmo-gsm-tester/tree/src/osmo_gsm_tester/trial.py#n39 ). 'trial-latest' would then reference a trial a second time. trial.py should be able to tell that the trial-latest has already run, but there should be a test for that. So, what if I launch a manual test run on 'latest', and then the jenkins swaps out the symlink? AFAICT the osmo-gsm-tester would continue to use the new path and choke up. Ok, we can add this patch *if* you also make sure that a symlink gets resolved to its actual path before a trial starts. So Trial.__init__() should employ os.path.foo to resolve the link, http://git.osmocom.org/osmo-gsm-tester/tree/src/osmo_gsm_tester/trial.py#n52 and *if* you make sure instead of the link name, the resolved name is used everywhere. The "latest" link is more of a convenience for us to be able to invoke the latest manually, right? The user could also use 'ls -1t | head -n 1'? -- To view, visit https://gerrit.osmocom.org/2443 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I26ddf55110738bd1944ccbfe72e8410ff9811392 Gerrit-PatchSet: 1 Gerrit-Project: osmo-gsm-tester Gerrit-Branch: master Gerrit-Owner: Pau Espin Pedrol Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: neels Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Thu Apr 27 17:12:56 2017 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 27 Apr 2017 17:12:56 +0000 Subject: osmo-gsm-manuals[master]: OsmoGSMTester: fix typo in example In-Reply-To: References: Message-ID: Patch Set 1: Code-Review-1 (1 comment) https://gerrit.osmocom.org/#/c/2442/1/OsmoGSMTester/chapters/intro.adoc File OsmoGSMTester/chapters/intro.adoc: Line 242: osmo-gsm-tester.py path/to/my-trial -s sms:sysmo -l dbg -T -t mo_mt_sms ah, so this is actually not a typo. It should be a matching, by simply testing 'if test_name in test.name()' -- so 'mo_mt' suffices to select all tests that have 'mo_mt' in their name. Now that I attempted to test it, I find a bug though: https://osmocom.org/issues/2214 This should indeed be better documented. -- To view, visit https://gerrit.osmocom.org/2442 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Iac0efc7fc561377c6a8a51ab7cd434e47bab458a Gerrit-PatchSet: 1 Gerrit-Project: osmo-gsm-manuals Gerrit-Branch: master Gerrit-Owner: Pau Espin Pedrol Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: neels Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Thu Apr 27 17:59:55 2017 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 27 Apr 2017 17:59:55 +0000 Subject: [PATCH] osmo-gsm-tester[master]: fix 'make check' Message-ID: Review at https://gerrit.osmocom.org/2444 fix 'make check' Apply various fixes that arose from test case code rot. These tests will now be used to verify patches submitted to gerrit, so they need to be up to par. Change-Id: I5277be0c434226d9d02e038f0bc72fd2557350c1 Related: OS#2215 --- M selftest/conf/resources.conf M selftest/resource_test.ok M selftest/suite_test.ok M selftest/suite_test.py M selftest/suite_test/resources.conf M selftest/template_test.py M src/osmo_gsm_tester/log.py 7 files changed, 25 insertions(+), 13 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-gsm-tester refs/changes/44/2444/1 diff --git a/selftest/conf/resources.conf b/selftest/conf/resources.conf index c17acf5..178e13c 100644 --- a/selftest/conf/resources.conf +++ b/selftest/conf/resources.conf @@ -17,7 +17,7 @@ ipa_unit_id: 5 addr: 10.42.42.115 band: GSM-1800 - trx: + trx_list: - hw_addr: 00:0c:90:32:b5:8a - label: nanoBTS 1900 @@ -25,7 +25,7 @@ ipa_unit_id: 1902 addr: 10.42.42.190 band: GSM-1900 - trx: + trx_list: - hw_addr: 00:02:95:00:41:b3 arfcn: diff --git a/selftest/resource_test.ok b/selftest/resource_test.ok index ae31d3b..413e5d0 100644 --- a/selftest/resource_test.ok +++ b/selftest/resource_test.ok @@ -51,14 +51,14 @@ 'band': 'GSM-1800', 'ipa_unit_id': '5', 'label': 'octBTS 3000', - 'trx': [{'hw_addr': '00:0c:90:32:b5:8a'}], + 'trx_list': [{'hw_addr': '00:0c:90:32:b5:8a'}], 'type': 'oct'}, {'_hash': '0b7fabd512b36aec43d7d496abd00af4e193b0f8', 'addr': '10.42.42.190', 'band': 'GSM-1900', 'ipa_unit_id': '1902', 'label': 'nanoBTS 1900', - 'trx': [{'hw_addr': '00:02:95:00:41:b3'}], + 'trx_list': [{'hw_addr': '00:02:95:00:41:b3'}], 'type': 'nanobts'}], 'modem': [{'_hash': '19c69e45aa090fb511446bd00797690aa82ff52f', 'imsi': '901700000007801', @@ -168,7 +168,7 @@ band: GSM-1800 ipa_unit_id: '5' label: octBTS 3000 - trx: + trx_list: - hw_addr: 00:0c:90:32:b5:8a type: oct --- (want='modem'): DBG: Looking for 2 x modem , candidates: 16 @@ -209,7 +209,7 @@ band: GSM-1800 ipa_unit_id: '5' label: octBTS 3000 - trx: + trx_list: - hw_addr: 00:0c:90:32:b5:8a type: oct modem: diff --git a/selftest/suite_test.ok b/selftest/suite_test.ok index fe7fbcb..2fad8b3 100644 --- a/selftest/suite_test.ok +++ b/selftest/suite_test.ok @@ -16,7 +16,10 @@ - times: '1' - run hello world test +tst test_suite: Suite run start tst test_suite: reserving resources... +tst test_suite: DBG: {combining='resources'} [test_suite?test_suite] +tst test_suite: DBG: {definition_conf={bts=[{'times': '1'}], modem=[{'times': '2'}], nitb_iface=[{'times': '1'}]}} [test_suite?(combining_scenarios='resources')?test_suite] --- (want='bts'): DBG: Looking for 1 x bts , candidates: 3 --- (want='bts'): DBG: Picked - _hash: 07d9c8aaa940b674efcbbabdd69f58a6ce4e94f9 addr: 10.42.42.114 @@ -48,6 +51,7 @@ pass: all 1 tests passed. - a test with an error +tst test_suite: Suite run start [suite.py:191] tst test_error.py: START [test_suite?test_error.py] [suite.py:96] tst test_error.py:3: I am 'test_suite' / 'test_error.py:3' [test_suite?test_error.py:3] [test_error.py:3] tst test_error.py:5: FAIL [test_suite?test_error.py:5] [suite.py:108] diff --git a/selftest/suite_test.py b/selftest/suite_test.py index cbbd6be..315c683 100755 --- a/selftest/suite_test.py +++ b/selftest/suite_test.py @@ -20,7 +20,7 @@ print(config.tostr(s_def.conf)) print('- run hello world test') -s = suite.SuiteRun(None, s_def) +s = suite.SuiteRun(None, 'test_suite', s_def) results = s.run_tests('hello_world.py') print(str(results)) diff --git a/selftest/suite_test/resources.conf b/selftest/suite_test/resources.conf index c17acf5..178e13c 100644 --- a/selftest/suite_test/resources.conf +++ b/selftest/suite_test/resources.conf @@ -17,7 +17,7 @@ ipa_unit_id: 5 addr: 10.42.42.115 band: GSM-1800 - trx: + trx_list: - hw_addr: 00:0c:90:32:b5:8a - label: nanoBTS 1900 @@ -25,7 +25,7 @@ ipa_unit_id: 1902 addr: 10.42.42.190 band: GSM-1900 - trx: + trx_list: - hw_addr: 00:02:95:00:41:b3 arfcn: diff --git a/selftest/template_test.py b/selftest/template_test.py index 2b44ae5..31d9e80 100755 --- a/selftest/template_test.py +++ b/selftest/template_test.py @@ -19,7 +19,7 @@ ) mock_bts = { - 'type': 'val_type', + 'osmobsc_bts_type': 'val_type', 'band': 'val_band', 'location_area_code': 'val_bts.location_area_code', 'base_station_id_code': 'val_bts.base_station_id_code', diff --git a/src/osmo_gsm_tester/log.py b/src/osmo_gsm_tester/log.py index 3e96999..b581e2c 100644 --- a/src/osmo_gsm_tester/log.py +++ b/src/osmo_gsm_tester/log.py @@ -24,6 +24,8 @@ import contextlib from inspect import getframeinfo, stack +from .util import is_dict + L_ERR = 30 L_LOG = 20 L_DBG = 10 @@ -512,14 +514,20 @@ log_exn() return return_on_failure +def _compose_named_items(item): + 'make sure dicts are output sorted, for test expectations' + if is_dict(item): + return '{%s}' % (', '.join( + ['%s=%s' % (k, _compose_named_items(v)) + for k,v in sorted(item.items())])) + return repr(item) + def compose_message(messages, named_items): msgs = [str(m) for m in messages] if named_items: # unfortunately needs to be sorted to get deterministic results - msgs.append('{%s}' % - (', '.join(['%s=%r' % (k,v) - for k,v in sorted(named_items.items())]))) + msgs.append(_compose_named_items(named_items)) return ' '.join(msgs) -- To view, visit https://gerrit.osmocom.org/2444 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I5277be0c434226d9d02e038f0bc72fd2557350c1 Gerrit-PatchSet: 1 Gerrit-Project: osmo-gsm-tester Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Thu Apr 27 18:25:03 2017 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 27 Apr 2017 18:25:03 +0000 Subject: [PATCH] osmo-gsm-tester[master]: fix 'make check' In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2444 to look at the new patch set (#2). fix 'make check' Apply various fixes that arose from test case code rot. These tests will now be used to verify patches submitted to gerrit, so they need to be up to par. Change-Id: I5277be0c434226d9d02e038f0bc72fd2557350c1 Related: OS#2215 --- M selftest/conf/resources.conf M selftest/config_test.py M selftest/resource_test.ok M selftest/suite_test.ok M selftest/suite_test.py M selftest/suite_test/resources.conf M selftest/template_test.py M src/osmo_gsm_tester/log.py 8 files changed, 26 insertions(+), 14 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-gsm-tester refs/changes/44/2444/2 diff --git a/selftest/conf/resources.conf b/selftest/conf/resources.conf index c17acf5..178e13c 100644 --- a/selftest/conf/resources.conf +++ b/selftest/conf/resources.conf @@ -17,7 +17,7 @@ ipa_unit_id: 5 addr: 10.42.42.115 band: GSM-1800 - trx: + trx_list: - hw_addr: 00:0c:90:32:b5:8a - label: nanoBTS 1900 @@ -25,7 +25,7 @@ ipa_unit_id: 1902 addr: 10.42.42.190 band: GSM-1900 - trx: + trx_list: - hw_addr: 00:02:95:00:41:b3 arfcn: diff --git a/selftest/config_test.py b/selftest/config_test.py index ce4d939..61ec73a 100755 --- a/selftest/config_test.py +++ b/selftest/config_test.py @@ -14,7 +14,7 @@ example_config = os.path.join(_prep.script_dir, 'config_test', example_config_file) cfg = config.read(example_config) -pprint.pprint(cfg) +pprint.pprint(cfg, width=81) test_schema = { 'modems[].dbus_path': schema.STR, diff --git a/selftest/resource_test.ok b/selftest/resource_test.ok index ae31d3b..413e5d0 100644 --- a/selftest/resource_test.ok +++ b/selftest/resource_test.ok @@ -51,14 +51,14 @@ 'band': 'GSM-1800', 'ipa_unit_id': '5', 'label': 'octBTS 3000', - 'trx': [{'hw_addr': '00:0c:90:32:b5:8a'}], + 'trx_list': [{'hw_addr': '00:0c:90:32:b5:8a'}], 'type': 'oct'}, {'_hash': '0b7fabd512b36aec43d7d496abd00af4e193b0f8', 'addr': '10.42.42.190', 'band': 'GSM-1900', 'ipa_unit_id': '1902', 'label': 'nanoBTS 1900', - 'trx': [{'hw_addr': '00:02:95:00:41:b3'}], + 'trx_list': [{'hw_addr': '00:02:95:00:41:b3'}], 'type': 'nanobts'}], 'modem': [{'_hash': '19c69e45aa090fb511446bd00797690aa82ff52f', 'imsi': '901700000007801', @@ -168,7 +168,7 @@ band: GSM-1800 ipa_unit_id: '5' label: octBTS 3000 - trx: + trx_list: - hw_addr: 00:0c:90:32:b5:8a type: oct --- (want='modem'): DBG: Looking for 2 x modem , candidates: 16 @@ -209,7 +209,7 @@ band: GSM-1800 ipa_unit_id: '5' label: octBTS 3000 - trx: + trx_list: - hw_addr: 00:0c:90:32:b5:8a type: oct modem: diff --git a/selftest/suite_test.ok b/selftest/suite_test.ok index fe7fbcb..2fad8b3 100644 --- a/selftest/suite_test.ok +++ b/selftest/suite_test.ok @@ -16,7 +16,10 @@ - times: '1' - run hello world test +tst test_suite: Suite run start tst test_suite: reserving resources... +tst test_suite: DBG: {combining='resources'} [test_suite?test_suite] +tst test_suite: DBG: {definition_conf={bts=[{'times': '1'}], modem=[{'times': '2'}], nitb_iface=[{'times': '1'}]}} [test_suite?(combining_scenarios='resources')?test_suite] --- (want='bts'): DBG: Looking for 1 x bts , candidates: 3 --- (want='bts'): DBG: Picked - _hash: 07d9c8aaa940b674efcbbabdd69f58a6ce4e94f9 addr: 10.42.42.114 @@ -48,6 +51,7 @@ pass: all 1 tests passed. - a test with an error +tst test_suite: Suite run start [suite.py:191] tst test_error.py: START [test_suite?test_error.py] [suite.py:96] tst test_error.py:3: I am 'test_suite' / 'test_error.py:3' [test_suite?test_error.py:3] [test_error.py:3] tst test_error.py:5: FAIL [test_suite?test_error.py:5] [suite.py:108] diff --git a/selftest/suite_test.py b/selftest/suite_test.py index cbbd6be..315c683 100755 --- a/selftest/suite_test.py +++ b/selftest/suite_test.py @@ -20,7 +20,7 @@ print(config.tostr(s_def.conf)) print('- run hello world test') -s = suite.SuiteRun(None, s_def) +s = suite.SuiteRun(None, 'test_suite', s_def) results = s.run_tests('hello_world.py') print(str(results)) diff --git a/selftest/suite_test/resources.conf b/selftest/suite_test/resources.conf index c17acf5..178e13c 100644 --- a/selftest/suite_test/resources.conf +++ b/selftest/suite_test/resources.conf @@ -17,7 +17,7 @@ ipa_unit_id: 5 addr: 10.42.42.115 band: GSM-1800 - trx: + trx_list: - hw_addr: 00:0c:90:32:b5:8a - label: nanoBTS 1900 @@ -25,7 +25,7 @@ ipa_unit_id: 1902 addr: 10.42.42.190 band: GSM-1900 - trx: + trx_list: - hw_addr: 00:02:95:00:41:b3 arfcn: diff --git a/selftest/template_test.py b/selftest/template_test.py index 2b44ae5..31d9e80 100755 --- a/selftest/template_test.py +++ b/selftest/template_test.py @@ -19,7 +19,7 @@ ) mock_bts = { - 'type': 'val_type', + 'osmobsc_bts_type': 'val_type', 'band': 'val_band', 'location_area_code': 'val_bts.location_area_code', 'base_station_id_code': 'val_bts.base_station_id_code', diff --git a/src/osmo_gsm_tester/log.py b/src/osmo_gsm_tester/log.py index 3e96999..b581e2c 100644 --- a/src/osmo_gsm_tester/log.py +++ b/src/osmo_gsm_tester/log.py @@ -24,6 +24,8 @@ import contextlib from inspect import getframeinfo, stack +from .util import is_dict + L_ERR = 30 L_LOG = 20 L_DBG = 10 @@ -512,14 +514,20 @@ log_exn() return return_on_failure +def _compose_named_items(item): + 'make sure dicts are output sorted, for test expectations' + if is_dict(item): + return '{%s}' % (', '.join( + ['%s=%s' % (k, _compose_named_items(v)) + for k,v in sorted(item.items())])) + return repr(item) + def compose_message(messages, named_items): msgs = [str(m) for m in messages] if named_items: # unfortunately needs to be sorted to get deterministic results - msgs.append('{%s}' % - (', '.join(['%s=%r' % (k,v) - for k,v in sorted(named_items.items())]))) + msgs.append(_compose_named_items(named_items)) return ' '.join(msgs) -- To view, visit https://gerrit.osmocom.org/2444 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I5277be0c434226d9d02e038f0bc72fd2557350c1 Gerrit-PatchSet: 2 Gerrit-Project: osmo-gsm-tester Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Thu Apr 27 18:26:08 2017 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 27 Apr 2017 18:26:08 +0000 Subject: osmo-gsm-tester[master]: fix 'make check' In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2444 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I5277be0c434226d9d02e038f0bc72fd2557350c1 Gerrit-PatchSet: 2 Gerrit-Project: osmo-gsm-tester Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Apr 27 18:26:10 2017 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Thu, 27 Apr 2017 18:26:10 +0000 Subject: [MERGED] osmo-gsm-tester[master]: fix 'make check' In-Reply-To: References: Message-ID: Neels Hofmeyr has submitted this change and it was merged. Change subject: fix 'make check' ...................................................................... fix 'make check' Apply various fixes that arose from test case code rot. These tests will now be used to verify patches submitted to gerrit, so they need to be up to par. Change-Id: I5277be0c434226d9d02e038f0bc72fd2557350c1 Related: OS#2215 --- M selftest/conf/resources.conf M selftest/config_test.py M selftest/resource_test.ok M selftest/suite_test.ok M selftest/suite_test.py M selftest/suite_test/resources.conf M selftest/template_test.py M src/osmo_gsm_tester/log.py 8 files changed, 26 insertions(+), 14 deletions(-) Approvals: Neels Hofmeyr: Looks good to me, approved Jenkins Builder: Verified diff --git a/selftest/conf/resources.conf b/selftest/conf/resources.conf index c17acf5..178e13c 100644 --- a/selftest/conf/resources.conf +++ b/selftest/conf/resources.conf @@ -17,7 +17,7 @@ ipa_unit_id: 5 addr: 10.42.42.115 band: GSM-1800 - trx: + trx_list: - hw_addr: 00:0c:90:32:b5:8a - label: nanoBTS 1900 @@ -25,7 +25,7 @@ ipa_unit_id: 1902 addr: 10.42.42.190 band: GSM-1900 - trx: + trx_list: - hw_addr: 00:02:95:00:41:b3 arfcn: diff --git a/selftest/config_test.py b/selftest/config_test.py index ce4d939..61ec73a 100755 --- a/selftest/config_test.py +++ b/selftest/config_test.py @@ -14,7 +14,7 @@ example_config = os.path.join(_prep.script_dir, 'config_test', example_config_file) cfg = config.read(example_config) -pprint.pprint(cfg) +pprint.pprint(cfg, width=81) test_schema = { 'modems[].dbus_path': schema.STR, diff --git a/selftest/resource_test.ok b/selftest/resource_test.ok index ae31d3b..413e5d0 100644 --- a/selftest/resource_test.ok +++ b/selftest/resource_test.ok @@ -51,14 +51,14 @@ 'band': 'GSM-1800', 'ipa_unit_id': '5', 'label': 'octBTS 3000', - 'trx': [{'hw_addr': '00:0c:90:32:b5:8a'}], + 'trx_list': [{'hw_addr': '00:0c:90:32:b5:8a'}], 'type': 'oct'}, {'_hash': '0b7fabd512b36aec43d7d496abd00af4e193b0f8', 'addr': '10.42.42.190', 'band': 'GSM-1900', 'ipa_unit_id': '1902', 'label': 'nanoBTS 1900', - 'trx': [{'hw_addr': '00:02:95:00:41:b3'}], + 'trx_list': [{'hw_addr': '00:02:95:00:41:b3'}], 'type': 'nanobts'}], 'modem': [{'_hash': '19c69e45aa090fb511446bd00797690aa82ff52f', 'imsi': '901700000007801', @@ -168,7 +168,7 @@ band: GSM-1800 ipa_unit_id: '5' label: octBTS 3000 - trx: + trx_list: - hw_addr: 00:0c:90:32:b5:8a type: oct --- (want='modem'): DBG: Looking for 2 x modem , candidates: 16 @@ -209,7 +209,7 @@ band: GSM-1800 ipa_unit_id: '5' label: octBTS 3000 - trx: + trx_list: - hw_addr: 00:0c:90:32:b5:8a type: oct modem: diff --git a/selftest/suite_test.ok b/selftest/suite_test.ok index fe7fbcb..2fad8b3 100644 --- a/selftest/suite_test.ok +++ b/selftest/suite_test.ok @@ -16,7 +16,10 @@ - times: '1' - run hello world test +tst test_suite: Suite run start tst test_suite: reserving resources... +tst test_suite: DBG: {combining='resources'} [test_suite?test_suite] +tst test_suite: DBG: {definition_conf={bts=[{'times': '1'}], modem=[{'times': '2'}], nitb_iface=[{'times': '1'}]}} [test_suite?(combining_scenarios='resources')?test_suite] --- (want='bts'): DBG: Looking for 1 x bts , candidates: 3 --- (want='bts'): DBG: Picked - _hash: 07d9c8aaa940b674efcbbabdd69f58a6ce4e94f9 addr: 10.42.42.114 @@ -48,6 +51,7 @@ pass: all 1 tests passed. - a test with an error +tst test_suite: Suite run start [suite.py:191] tst test_error.py: START [test_suite?test_error.py] [suite.py:96] tst test_error.py:3: I am 'test_suite' / 'test_error.py:3' [test_suite?test_error.py:3] [test_error.py:3] tst test_error.py:5: FAIL [test_suite?test_error.py:5] [suite.py:108] diff --git a/selftest/suite_test.py b/selftest/suite_test.py index cbbd6be..315c683 100755 --- a/selftest/suite_test.py +++ b/selftest/suite_test.py @@ -20,7 +20,7 @@ print(config.tostr(s_def.conf)) print('- run hello world test') -s = suite.SuiteRun(None, s_def) +s = suite.SuiteRun(None, 'test_suite', s_def) results = s.run_tests('hello_world.py') print(str(results)) diff --git a/selftest/suite_test/resources.conf b/selftest/suite_test/resources.conf index c17acf5..178e13c 100644 --- a/selftest/suite_test/resources.conf +++ b/selftest/suite_test/resources.conf @@ -17,7 +17,7 @@ ipa_unit_id: 5 addr: 10.42.42.115 band: GSM-1800 - trx: + trx_list: - hw_addr: 00:0c:90:32:b5:8a - label: nanoBTS 1900 @@ -25,7 +25,7 @@ ipa_unit_id: 1902 addr: 10.42.42.190 band: GSM-1900 - trx: + trx_list: - hw_addr: 00:02:95:00:41:b3 arfcn: diff --git a/selftest/template_test.py b/selftest/template_test.py index 2b44ae5..31d9e80 100755 --- a/selftest/template_test.py +++ b/selftest/template_test.py @@ -19,7 +19,7 @@ ) mock_bts = { - 'type': 'val_type', + 'osmobsc_bts_type': 'val_type', 'band': 'val_band', 'location_area_code': 'val_bts.location_area_code', 'base_station_id_code': 'val_bts.base_station_id_code', diff --git a/src/osmo_gsm_tester/log.py b/src/osmo_gsm_tester/log.py index 3e96999..b581e2c 100644 --- a/src/osmo_gsm_tester/log.py +++ b/src/osmo_gsm_tester/log.py @@ -24,6 +24,8 @@ import contextlib from inspect import getframeinfo, stack +from .util import is_dict + L_ERR = 30 L_LOG = 20 L_DBG = 10 @@ -512,14 +514,20 @@ log_exn() return return_on_failure +def _compose_named_items(item): + 'make sure dicts are output sorted, for test expectations' + if is_dict(item): + return '{%s}' % (', '.join( + ['%s=%s' % (k, _compose_named_items(v)) + for k,v in sorted(item.items())])) + return repr(item) + def compose_message(messages, named_items): msgs = [str(m) for m in messages] if named_items: # unfortunately needs to be sorted to get deterministic results - msgs.append('{%s}' % - (', '.join(['%s=%r' % (k,v) - for k,v in sorted(named_items.items())]))) + msgs.append(_compose_named_items(named_items)) return ' '.join(msgs) -- To view, visit https://gerrit.osmocom.org/2444 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I5277be0c434226d9d02e038f0bc72fd2557350c1 Gerrit-PatchSet: 2 Gerrit-Project: osmo-gsm-tester Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Thu Apr 27 19:50:36 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 27 Apr 2017 19:50:36 +0000 Subject: libosmo-sccp[master]: sccp_scoc: don't pass variable as argument if we know it's NULL In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2438 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Id6dc56442441489aefc706bcebc49197ca3dae1e Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Apr 27 19:50:48 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 27 Apr 2017 19:50:48 +0000 Subject: libosmo-sccp[master]: osmo_ss7_user_unregister(): Don't dereference NULL user In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2439 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ia34b181dcbcb179b2639e2f405364cc952069842 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Apr 27 19:50:55 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 27 Apr 2017 19:50:55 +0000 Subject: libosmo-sccp[master]: osmo_sccp_addr_parse() Fix point code integer precision hand... In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2440 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ie47e632f4bca490baf4282dc5d55ee55ca7f1ae8 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Thu Apr 27 19:50:58 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 27 Apr 2017 19:50:58 +0000 Subject: [MERGED] libosmo-sccp[master]: osmo_sccp_addr_parse() Fix point code integer precision hand... In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: osmo_sccp_addr_parse() Fix point code integer precision handling ...................................................................... osmo_sccp_addr_parse() Fix point code integer precision handling "(cur[1] << 8) & 0x3f" is always 0 regardless of the values of its operands. Change-Id: Ie47e632f4bca490baf4282dc5d55ee55ca7f1ae8 Fixes: coverity CID#166932 --- M src/sccp2sua.c 1 file changed, 2 insertions(+), 1 deletion(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/sccp2sua.c b/src/sccp2sua.c index 7268e27..753d9a4 100644 --- a/src/sccp2sua.c +++ b/src/sccp2sua.c @@ -134,7 +134,8 @@ if (sca->point_code_indicator) { out->presence |= OSMO_SCCP_ADDR_T_PC; - out->pc = ((cur[1] << 8) & 0x3f) | cur[0]; + out->pc = (uint16_t) (cur[1] & 0x3f) << 8; + out->pc |= cur[0]; cur += 2; } -- To view, visit https://gerrit.osmocom.org/2440 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ie47e632f4bca490baf4282dc5d55ee55ca7f1ae8 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Thu Apr 27 19:50:59 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 27 Apr 2017 19:50:59 +0000 Subject: [MERGED] libosmo-sccp[master]: osmo_ss7_user_unregister(): Don't dereference NULL user In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: osmo_ss7_user_unregister(): Don't dereference NULL user ...................................................................... osmo_ss7_user_unregister(): Don't dereference NULL user The 'user' argument to osmo_ss7_user_unregister() can be NULL, so let's make sure we don't dereference it. Change-Id: Ia34b181dcbcb179b2639e2f405364cc952069842 Fixes: coverity CID#166933 --- M src/osmo_ss7.c 1 file changed, 2 insertions(+), 1 deletion(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index 31c0dc5..d952ecd 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -442,7 +442,8 @@ if (user && (inst->user[service_ind] != user)) return -EINVAL; - user->inst = NULL; + if (user) + user->inst = NULL; inst->user[service_ind] = NULL; return 0; -- To view, visit https://gerrit.osmocom.org/2439 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ia34b181dcbcb179b2639e2f405364cc952069842 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Thu Apr 27 19:50:59 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 27 Apr 2017 19:50:59 +0000 Subject: [MERGED] libosmo-sccp[master]: sccp_scoc: don't pass variable as argument if we know it's NULL In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: sccp_scoc: don't pass variable as argument if we know it's NULL ...................................................................... sccp_scoc: don't pass variable as argument if we know it's NULL xua will always be NULL in one particular switch case of scoc_fsm_conn_pend_out(), so let's use NULL directly rather than obscure it though a variable that might be understood as this being non-NULL in some cases. Change-Id: Id6dc56442441489aefc706bcebc49197ca3dae1e Fixes: coverity CID#166934 --- M src/sccp_scoc.c 1 file changed, 1 insertion(+), 1 deletion(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/sccp_scoc.c b/src/sccp_scoc.c index 0eda7ad..5e91ea4 100644 --- a/src/sccp_scoc.c +++ b/src/sccp_scoc.c @@ -824,7 +824,7 @@ break; case SCOC_E_CONN_TMR_EXP: /* N-DISCONNECT.ind to user */ - scu_gen_encode_and_send(conn, event, xua, OSMO_SCU_PRIM_N_DISCONNECT, + scu_gen_encode_and_send(conn, event, NULL, OSMO_SCU_PRIM_N_DISCONNECT, PRIM_OP_INDICATION); /* below implicitly releases resources + local ref */ osmo_fsm_inst_state_chg(fi, S_IDLE, 0, 0); -- To view, visit https://gerrit.osmocom.org/2438 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Id6dc56442441489aefc706bcebc49197ca3dae1e Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Thu Apr 27 19:50:59 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 27 Apr 2017 19:50:59 +0000 Subject: [MERGED] libosmo-sccp[master]: m3ua_decode_notify(): Ensure status_ie is valid before using it In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: m3ua_decode_notify(): Ensure status_ie is valid before using it ...................................................................... m3ua_decode_notify(): Ensure status_ie is valid before using it Change-Id: I3cdd0fbdffcbeeb68dbc979385de045220ea0b0c Fixes: coverity CID#166939 --- M src/m3ua.c 1 file changed, 4 insertions(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/m3ua.c b/src/m3ua.c index b204708..d96bd18 100644 --- a/src/m3ua.c +++ b/src/m3ua.c @@ -412,6 +412,10 @@ /* cannot use xua_msg_get_u32() as it does endian conversion */ status_ie = xua_msg_find_tag(xua, M3UA_IEI_STATUS); + if (!status_ie) { + LOGP(DLM3UA, LOGL_ERROR, "M3UA NOTIFY without Status IE\n"); + return -1; + } status = *(uint32_t *) status_ie->dat; aspid_ie = xua_msg_find_tag(xua, M3UA_IEI_ASP_ID); -- To view, visit https://gerrit.osmocom.org/2437 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I3cdd0fbdffcbeeb68dbc979385de045220ea0b0c Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Thu Apr 27 19:50:59 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 27 Apr 2017 19:50:59 +0000 Subject: [MERGED] libosmo-sccp[master]: m3ua_to_xfer_ind(): don't use data_ie without checking it ex... In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: m3ua_to_xfer_ind(): don't use data_ie without checking it exists ...................................................................... m3ua_to_xfer_ind(): don't use data_ie without checking it exists Change-Id: I5f7551e49c1b4ea417bee3516da1b2ece5ee0699 Fixes: coverity CID#166941 --- M src/osmo_ss7_hmrt.c 1 file changed, 1 insertion(+), 1 deletion(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/osmo_ss7_hmrt.c b/src/osmo_ss7_hmrt.c index 393530a..e66762d 100644 --- a/src/osmo_ss7_hmrt.c +++ b/src/osmo_ss7_hmrt.c @@ -25,7 +25,7 @@ struct m3ua_data_hdr *data_hdr; struct msgb *upmsg = m3ua_msgb_alloc("M3UA MTP-TRANSFER.ind"); - if (data_ie->len < sizeof(*data_hdr)) { + if (!data_ie || data_ie->len < sizeof(*data_hdr)) { /* FIXME: ERROR message */ msgb_free(upmsg); return NULL; -- To view, visit https://gerrit.osmocom.org/2435 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I5f7551e49c1b4ea417bee3516da1b2ece5ee0699 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Thu Apr 27 19:51:00 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 27 Apr 2017 19:51:00 +0000 Subject: [MERGED] libosmo-sccp[master]: sclc_rx_cldr(): Don't try to dereference user data_ie withou... In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: sclc_rx_cldr(): Don't try to dereference user data_ie without check ...................................................................... sclc_rx_cldr(): Don't try to dereference user data_ie without check While the SUA / SCCP2SUA code is ensuring that mandatory information elements such as the user data IE in a CLD$ message, we might still have current or future callers of sclc_rx_cldr() that don't comply with that. So let's make sure data_ie is valid before dereferencing it. Change-Id: I7c1010b0ac82ee0b7bd5e2c7413899695eae0070 Fixes: coverity CID#166940 --- M src/sccp_sclc.c 1 file changed, 5 insertions(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/sccp_sclc.c b/src/sccp_sclc.c index 262b2c0..8f9e577 100644 --- a/src/sccp_sclc.c +++ b/src/sccp_sclc.c @@ -204,6 +204,11 @@ struct msgb *upmsg = sccp_msgb_alloc(__func__); struct osmo_sccp_user *scu; + if (!data_ie) { + LOGP(DLSCCP, LOGL_ERROR, "SCCP/SUA CLDR without user data?!?\n"); + return -1; + } + /* fill primitive */ prim = (struct osmo_scu_prim *) msgb_put(upmsg, sizeof(*prim)); param = &prim->u.notice; -- To view, visit https://gerrit.osmocom.org/2436 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I7c1010b0ac82ee0b7bd5e2c7413899695eae0070 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Thu Apr 27 19:51:00 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 27 Apr 2017 19:51:00 +0000 Subject: [MERGED] libosmo-sccp[master]: scu_gen_encode_and_send(): Fix NULL pointer deref In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: scu_gen_encode_and_send(): Fix NULL pointer deref ...................................................................... scu_gen_encode_and_send(): Fix NULL pointer deref We were using the 'xua' pointer before checkin if it actually is valid Change-Id: I5cd3250afc0b787b78683cd8ab6b2512e0d5c69e Fixes: coverity CID#166945 --- M src/sccp_scoc.c 1 file changed, 1 insertion(+), 1 deletion(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/sccp_scoc.c b/src/sccp_scoc.c index 3a52ca6..0eda7ad 100644 --- a/src/sccp_scoc.c +++ b/src/sccp_scoc.c @@ -657,8 +657,8 @@ uconp->calling_addr = conn->calling_addr; uconp->sccp_class = conn->sccp_class; uconp->importance = conn->importance; - data_ie = xua_msg_find_tag(xua, SUA_IEI_DATA); if (xua) { + data_ie = xua_msg_find_tag(xua, SUA_IEI_DATA); if (data_ie) { struct msgb *upmsg = scu_prim->oph.msg; upmsg->l2h = msgb_put(upmsg, data_ie->len); -- To view, visit https://gerrit.osmocom.org/2432 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I5cd3250afc0b787b78683cd8ab6b2512e0d5c69e Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Thu Apr 27 19:51:00 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 27 Apr 2017 19:51:00 +0000 Subject: [MERGED] libosmo-sccp[master]: ss7_test: Fix '=' that should have been '==' In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: ss7_test: Fix '=' that should have been '==' ...................................................................... ss7_test: Fix '=' that should have been '==' Change-Id: I1be4529c73992cb342a62aa19ba79be25e982620 Fixes: coverity CID#166944 --- M tests/ss7/ss7_test.c 1 file changed, 1 insertion(+), 1 deletion(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/tests/ss7/ss7_test.c b/tests/ss7/ss7_test.c index e36e068..7c51767 100644 --- a/tests/ss7/ss7_test.c +++ b/tests/ss7/ss7_test.c @@ -32,7 +32,7 @@ OSMO_ASSERT(s7i->cfg.pc_fmt.component_len[0] == 3); OSMO_ASSERT(s7i->cfg.pc_fmt.component_len[1] == 8); OSMO_ASSERT(s7i->cfg.pc_fmt.component_len[2] == 3); - OSMO_ASSERT(s7i->cfg.pc_fmt.delimiter = '.'); + OSMO_ASSERT(s7i->cfg.pc_fmt.delimiter == '.'); } static void parse_print_mask(const char *in) -- To view, visit https://gerrit.osmocom.org/2433 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I1be4529c73992cb342a62aa19ba79be25e982620 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Thu Apr 27 19:51:00 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 27 Apr 2017 19:51:00 +0000 Subject: [MERGED] libosmo-sccp[master]: sclc_rx_cldt(): Don't try to dereference user data_ie withou... In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: sclc_rx_cldt(): Don't try to dereference user data_ie without check ...................................................................... sclc_rx_cldt(): Don't try to dereference user data_ie without check While the SUA / SCCP2SUA code is ensuring that mandatory information elements such as the user data IE in a CLDT message, we might still have current or future callers of sclc_rx_cldt() that don't comply with that. So let's make sure data_ie is valid before dereferencing it. Change-Id: Ia102f6c4cd5c6c3f823cb219635c42b9a87765f8 Fixes: coverity CID#166942 --- M src/sccp_sclc.c 1 file changed, 5 insertions(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/sccp_sclc.c b/src/sccp_sclc.c index 7cdfac5..262b2c0 100644 --- a/src/sccp_sclc.c +++ b/src/sccp_sclc.c @@ -156,6 +156,11 @@ struct osmo_sccp_user *scu; uint32_t protocol_class; + if (!data_ie) { + LOGP(DLSCCP, LOGL_ERROR, "SCCP/SUA CLDT without user data?!?\n"); + return -1; + } + /* fill primitive */ prim = (struct osmo_scu_prim *) msgb_put(upmsg, sizeof(*prim)); param = &prim->u.unitdata; -- To view, visit https://gerrit.osmocom.org/2434 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ia102f6c4cd5c6c3f823cb219635c42b9a87765f8 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Thu Apr 27 19:51:01 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Thu, 27 Apr 2017 19:51:01 +0000 Subject: [MERGED] libosmo-sccp[master]: deliver_to_mtp_user(): Fix null pointer dereference In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: deliver_to_mtp_user(): Fix null pointer dereference ...................................................................... deliver_to_mtp_user(): Fix null pointer dereference We had used + derefernced the 'prim' pointer before checking its validity. Change-Id: I0ca5026091e91926924b297f9342bda5f9fd38c9 Fixes: coverity CID#166946 --- M src/osmo_ss7_hmrt.c 1 file changed, 1 insertion(+), 1 deletion(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/osmo_ss7_hmrt.c b/src/osmo_ss7_hmrt.c index bbbb3a9..393530a 100644 --- a/src/osmo_ss7_hmrt.c +++ b/src/osmo_ss7_hmrt.c @@ -67,9 +67,9 @@ /* Create MTP-TRANSFER.ind and feed to user */ prim = m3ua_to_xfer_ind(xua); - prim->u.transfer = xua->mtp; if (!prim) return -1; + prim->u.transfer = xua->mtp; return osu->prim_cb(&prim->oph, (void *) osu->priv); } -- To view, visit https://gerrit.osmocom.org/2431 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I0ca5026091e91926924b297f9342bda5f9fd38c9 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-sccp Gerrit-Branch: master Gerrit-Owner: Harald Welte Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Fri Apr 28 04:01:01 2017 From: gerrit-no-reply at lists.osmocom.org (Alexander Chemeris) Date: Fri, 28 Apr 2017 04:01:01 +0000 Subject: osmo-trx[master]: ssedetect: Add runtime CPU detection In-Reply-To: References: Message-ID: Patch Set 3: Code-Review-1 To recap discussion at the OsmoDevCon, the last remaining request before the patch can be merged is to add an AVX target, which is a minor change. Regarding clang support I also vote for moving this out of this ticket into a new one. -- To view, visit https://gerrit.osmocom.org/2100 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Iba74f8a6e4e921ff31e4bd9f0c7c881fe547423a Gerrit-PatchSet: 3 Gerrit-Project: osmo-trx Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Alexander Chemeris Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Apr 28 07:17:43 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 28 Apr 2017 07:17:43 +0000 Subject: openbsc[master]: Prepare for extended SI2quater support In-Reply-To: References: Message-ID: Patch Set 8: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2312 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I74e4e3cb86364cec869a1472a41b4a95af0d50dd Gerrit-PatchSet: 8 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Apr 28 07:19:23 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 28 Apr 2017 07:19:23 +0000 Subject: osmo-bts[master]: Prepare for extended SI2quater support In-Reply-To: References: Message-ID: Patch Set 2: (1 comment) https://gerrit.osmocom.org/#/c/2313/2/src/common/rsl.c File src/common/rsl.c: Line 435: static inline void lapdm_ui_prefix(uint8_t *buf, uint32_t *valid, const uint8_t *current, uint8_t osmo_si, uint16_t len) might make sense to have a comment on top of the function,stating that 'buf' must be caller-allocated and hold len+2 bytes, or 'sizeof(sysinfo_buf_t)? -- To view, visit https://gerrit.osmocom.org/2313 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ie97be6ead6ce6d2d425fbfac8429bb90afb95acc Gerrit-PatchSet: 2 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Fri Apr 28 07:21:29 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 28 Apr 2017 07:21:29 +0000 Subject: libosmocore[master]: Fix wrongful GSM codecs SID frame detection in DTX. In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+1 we should introduce a test case at the same time we fix this, just to validate the old code was wrong, the new code works, and that future versions will not introduce regressions. It should be as straight-forward as to checking against a valid and an invalid FR SID frame from a const uint8_t[] array. If yo can give me some valid FR SID samples, I'd volunteer to write the test case. -- To view, visit https://gerrit.osmocom.org/2441 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I45d98c6edf267f313883503a65385190ffbc65ca Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: jfdionne Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Apr 28 07:45:27 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 28 Apr 2017 07:45:27 +0000 Subject: openbsc[master]: Add gsm_bts_type_variant to gsm_bts struct In-Reply-To: References: Message-ID: Patch Set 3: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2294 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I54fde8c4ccd5d994af08074f5864446e79a93a25 Gerrit-PatchSet: 3 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Apr 28 07:46:06 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 28 Apr 2017 07:46:06 +0000 Subject: osmocom-bb[master]: Makefile: add forgotten gsmmap to (dist)clean section In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+1 -- To view, visit https://gerrit.osmocom.org/2398 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I14abe8a061d218ca81dd2d101b218d3030324aa2 Gerrit-PatchSet: 1 Gerrit-Project: osmocom-bb Gerrit-Branch: master Gerrit-Owner: Vadim Yanitskiy Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Max Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Apr 28 07:46:22 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 28 Apr 2017 07:46:22 +0000 Subject: libosmo-netif[master]: osmux: Fix delay between RTP packets In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2397 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I36dc69f9caf591dd1b578bc914a2ce426c7f2813 Gerrit-PatchSet: 2 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Pau Espin Pedrol Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: daniel Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Apr 28 07:47:43 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 28 Apr 2017 07:47:43 +0000 Subject: libosmocore[master]: Add SW Description (de)marshalling In-Reply-To: References: Message-ID: Patch Set 14: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2165 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ib63b6b5e83b8914864fc7edd789f8958cdc993cd Gerrit-PatchSet: 14 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Apr 28 07:49:43 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 28 Apr 2017 07:49:43 +0000 Subject: openbsc[master]: Make BTS type and variant converters shareable In-Reply-To: References: Message-ID: Patch Set 6: Code-Review+1 (1 comment) https://gerrit.osmocom.org/#/c/2286/6/openbsc/src/libcommon/gsm_data_shared.c File openbsc/src/libcommon/gsm_data_shared.c: Line 74: { BTS_OSMO_SYSMO, "Sysmo" }, should be "sysmoBTS" -- To view, visit https://gerrit.osmocom.org/2286 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ida94725a6fce968443541e3526f48f13758031fd Gerrit-PatchSet: 6 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Fri Apr 28 07:50:16 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 28 Apr 2017 07:50:16 +0000 Subject: openbsc[master]: Save PCU version reported by BTS In-Reply-To: References: Message-ID: Patch Set 3: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2289 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Idb32c73036413ee912f633604150ee17b611cfa7 Gerrit-PatchSet: 3 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Apr 28 07:50:57 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 28 Apr 2017 07:50:57 +0000 Subject: openbsc[master]: Use libosmocore for SW Description parsing In-Reply-To: References: Message-ID: Patch Set 8: Code-Review+1 -- To view, visit https://gerrit.osmocom.org/2166 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ib94db414e94a2a1f234ac6f1cb346dca1c7a8be3 Gerrit-PatchSet: 8 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Apr 28 07:57:28 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 28 Apr 2017 07:57:28 +0000 Subject: osmo-sip-connector[master]: tests: Add a basic test to open a single call and send DTMF In-Reply-To: References: Message-ID: Patch Set 3: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/1994 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Iec65a3490dd2a6c91f0a573aea482f3d113b0c6a Gerrit-PatchSet: 3 Gerrit-Project: osmo-sip-connector Gerrit-Branch: master Gerrit-Owner: Holger Freyther Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Apr 28 07:58:44 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 28 Apr 2017 07:58:44 +0000 Subject: osmo-bts[master]: osmo-bts-trx: cosmetic log fix In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/1974 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ic36c0558cdbd1790c167f290a40007b42f5de65d Gerrit-PatchSet: 2 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Apr 28 07:59:03 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Fri, 28 Apr 2017 07:59:03 +0000 Subject: osmo-bts[master]: osmo-bts-trx: cosmetic log fix In-Reply-To: References: Message-ID: Patch Set 2: not quite sure what happened to Holgers comment? Is this moving to a separate patch? -- To view, visit https://gerrit.osmocom.org/1974 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ic36c0558cdbd1790c167f290a40007b42f5de65d Gerrit-PatchSet: 2 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Apr 28 08:15:52 2017 From: gerrit-no-reply at lists.osmocom.org (Pau Espin Pedrol) Date: Fri, 28 Apr 2017 08:15:52 +0000 Subject: [MERGED] libosmo-netif[master]: osmux: Fix delay between RTP packets In-Reply-To: References: Message-ID: Pau Espin Pedrol has submitted this change and it was merged. Change subject: osmux: Fix delay between RTP packets ...................................................................... osmux: Fix delay between RTP packets AMR frame contains 160 samples at 8000Hz -> 20 ms long Change-Id: I36dc69f9caf591dd1b578bc914a2ce426c7f2813 --- M src/osmux.c 1 file changed, 3 insertions(+), 2 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/osmux.c b/src/osmux.c index d12a39a..91054f1 100644 --- a/src/osmux.c +++ b/src/osmux.c @@ -42,8 +42,9 @@ #define DEBUG_MSG 0 #endif -/* delta time between two RTP messages */ -#define DELTA_RTP_MSG 16000 +/* delta time between two RTP messages (in microseconds) */ +#define DELTA_RTP_MSG 20000 +/* delta time between two RTP messages (in samples, 8kHz) */ #define DELTA_RTP_TIMESTAMP 160 static void *osmux_ctx; -- To view, visit https://gerrit.osmocom.org/2397 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I36dc69f9caf591dd1b578bc914a2ce426c7f2813 Gerrit-PatchSet: 3 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Pau Espin Pedrol Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Pau Espin Pedrol Gerrit-Reviewer: daniel From gerrit-no-reply at lists.osmocom.org Fri Apr 28 08:20:40 2017 From: gerrit-no-reply at lists.osmocom.org (Pau Espin Pedrol) Date: Fri, 28 Apr 2017 08:20:40 +0000 Subject: [ABANDON] osmo-gsm-manuals[master]: OsmoGSMTester: fix typo in example In-Reply-To: References: Message-ID: Pau Espin Pedrol has abandoned this change. Change subject: OsmoGSMTester: fix typo in example ...................................................................... Abandoned -- To view, visit https://gerrit.osmocom.org/2442 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: abandon Gerrit-Change-Id: Iac0efc7fc561377c6a8a51ab7cd434e47bab458a Gerrit-PatchSet: 1 Gerrit-Project: osmo-gsm-manuals Gerrit-Branch: master Gerrit-Owner: Pau Espin Pedrol Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: neels From gerrit-no-reply at lists.osmocom.org Fri Apr 28 08:32:12 2017 From: gerrit-no-reply at lists.osmocom.org (Pau Espin Pedrol) Date: Fri, 28 Apr 2017 08:32:12 +0000 Subject: osmo-gsm-tester[master]: jenkins-run: Provide a link to the latest trial archived In-Reply-To: References: Message-ID: Patch Set 2: The idea behind this patch was to be able to access the latest trial from outside the gsm-tester in a unified fashion. Some use cases apply: - Be able to run the latest trial manually. - If the list of trials is accessible via ssh, ftp or http, give users who want to get the latest trial a unique reference/link. So, the idea here was to have this for user convenience rather than osmo-gsm-tester directly using this. But as you said, it may cause interferences with it, so not sure which is the best approach. It may be a good idea to restrict the directory pattern which is read by osmo-gsm-tester? for instance, only track directories containing "trial-N" where N is a number. This way we avoid osmo-gsm-tester to fail if a user/job ends up polluting the directory. -- To view, visit https://gerrit.osmocom.org/2443 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I26ddf55110738bd1944ccbfe72e8410ff9811392 Gerrit-PatchSet: 2 Gerrit-Project: osmo-gsm-tester Gerrit-Branch: master Gerrit-Owner: Pau Espin Pedrol Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: Pau Espin Pedrol Gerrit-Reviewer: neels Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Apr 28 08:44:19 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Fri, 28 Apr 2017 08:44:19 +0000 Subject: [MERGED] openbsc[master]: Save PCU version reported by BTS In-Reply-To: References: Message-ID: Max has submitted this change and it was merged. Change subject: Save PCU version reported by BTS ...................................................................... Save PCU version reported by BTS When BTS reports PCU disconnect - clear it. Change-Id: Idb32c73036413ee912f633604150ee17b611cfa7 Related: OS#1615 --- M openbsc/src/libbsc/abis_nm.c 1 file changed, 9 insertions(+), 13 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/openbsc/src/libbsc/abis_nm.c b/openbsc/src/libbsc/abis_nm.c index 56b6fcf..132e72d 100644 --- a/openbsc/src/libbsc/abis_nm.c +++ b/openbsc/src/libbsc/abis_nm.c @@ -302,31 +302,27 @@ LOGPC(DNM, LOGL_ERROR, "\n"); } -static inline void handle_manufact_report(const struct gsm_bts *bts, - const uint8_t *p_val, const char *type, +static inline void handle_manufact_report(struct gsm_bts *bts, const uint8_t *p_val, const char *type, const char *severity, const char *text) { enum abis_mm_event_causes cause = osmo_load16be(p_val + 1); switch (cause) { case OSMO_EVT_PCU_VERS: - if (text) - LOGPC(DNM, LOGL_NOTICE, - "BTS %u reported connected PCU version %s\n", - bts->nr, text); - else - LOGPC(DNM, LOGL_ERROR, - "BTS %u sent %s without actual version string.\n", - bts->nr, - get_value_string(abis_mm_event_cause_names, - cause)); + if (text) { + LOGPC(DNM, LOGL_NOTICE, "BTS %u reported connected PCU version %s\n", bts->nr, text); + osmo_strlcpy(bts->pcu_version, text, sizeof(bts->pcu_version)); + } else { + LOGPC(DNM, LOGL_ERROR, "BTS %u reported PCU disconnection.\n", bts->nr); + bts->pcu_version[0] = '\0'; + } break; default: log_oml_fail_rep(bts, type, severity, p_val, text); }; } -static int rx_fail_evt_rep(struct msgb *mb, const struct gsm_bts *bts) +static int rx_fail_evt_rep(struct msgb *mb, struct gsm_bts *bts) { struct abis_om_hdr *oh = msgb_l2(mb); struct abis_om_fom_hdr *foh = msgb_l3(mb); -- To view, visit https://gerrit.osmocom.org/2289 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Idb32c73036413ee912f633604150ee17b611cfa7 Gerrit-PatchSet: 4 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max From gerrit-no-reply at lists.osmocom.org Fri Apr 28 08:45:14 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Fri, 28 Apr 2017 08:45:14 +0000 Subject: [MERGED] libosmocore[master]: Add SW Description (de)marshalling In-Reply-To: References: Message-ID: Max has submitted this change and it was merged. Change subject: Add SW Description (de)marshalling ...................................................................... Add SW Description (de)marshalling * data structure representing 3GPP TS 52.021 ?9.4.62 SW Description * function to serialize it into msgb * function to deserialize it from buffer * functions to extract/estimate buffer size for SW Description * test harness (partially taken from OpenBSC) There are several similar functions to deal with SW Description in OpenBSC, there's also need to use similar functionality in OsmoBTS. Hence it's better to put the code into common library with proper tests and documentation. Change-Id: Ib63b6b5e83b8914864fc7edd789f8958cdc993cd Related: OS#1614 --- M .gitignore M include/osmocom/gsm/protocol/gsm_12_21.h M src/gsm/abis_nm.c M src/gsm/libosmogsm.map M tests/Makefile.am A tests/abis/abis_test.c A tests/abis/abis_test.ok M tests/testsuite.at 8 files changed, 437 insertions(+), 2 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/.gitignore b/.gitignore index ecbcedd..4c6a78f 100644 --- a/.gitignore +++ b/.gitignore @@ -60,6 +60,7 @@ tests/testsuite tests/testsuite.dir/ tests/testsuite.log +tests/abis/abis_test tests/ctrl/ctrl_test tests/utils/utils_test tests/stats/stats_test diff --git a/include/osmocom/gsm/protocol/gsm_12_21.h b/include/osmocom/gsm/protocol/gsm_12_21.h index c88f0b1..b35da44 100644 --- a/include/osmocom/gsm/protocol/gsm_12_21.h +++ b/include/osmocom/gsm/protocol/gsm_12_21.h @@ -29,6 +29,7 @@ /*! \file gsm_12_21.h */ #include +#include #include /*! \brief generic header in front of every OML message according to TS 08.59 */ @@ -791,6 +792,21 @@ IPAC_BINF_CELL_ALLOC = (1 << 2), }; +/*! \brief 3GPP TS 52.021 ?9.4.62 SW Description */ +struct abis_nm_sw_desc { + uint8_t file_id[UINT8_MAX]; + uint8_t file_id_len; + + uint8_t file_version[UINT8_MAX]; + uint8_t file_version_len; +}; + +uint16_t abis_nm_sw_desc_len(const struct abis_nm_sw_desc *sw, bool put_sw_descr); +uint16_t abis_nm_put_sw_desc(struct msgb *msg, const struct abis_nm_sw_desc *sw, bool put_sw_descr); +uint16_t abis_nm_put_sw_file(struct msgb *msg, const char *id, const char *ver, bool put_sw_desc); +uint32_t abis_nm_get_sw_desc_len(const uint8_t * buf, size_t len); +int abis_nm_get_sw_conf(const uint8_t * buf, size_t buf_len, struct abis_nm_sw_desc *sw, uint16_t sw_len); + struct msgb *abis_nm_fail_evt_rep(enum abis_nm_event_type t, enum abis_nm_severity s, enum abis_nm_pcause_type ct, diff --git a/src/gsm/abis_nm.c b/src/gsm/abis_nm.c index 934d7ce..7553f84 100644 --- a/src/gsm/abis_nm.c +++ b/src/gsm/abis_nm.c @@ -751,6 +751,161 @@ return nmsg; } +/*! \brief Compute length of given 3GPP TS 52.021 ?9.4.62 SW Description. + * \param[in] sw SW Description struct + * \param[in] put_sw_descr boolean, whether to put NM_ATT_SW_DESCR IE or not + * \returns length of buffer space necessary to store sw + */ +uint16_t abis_nm_sw_desc_len(const struct abis_nm_sw_desc *sw, bool put_sw_desc) +{ + /* +3: type is 1-byte, length is 2-byte */ + return (put_sw_desc ? 1 : 0) + (sw->file_id_len + 3) + (sw->file_version_len + 3); +} + +/*! \brief Put given 3GPP TS 52.021 ?9.4.62 SW Description into msgb. + * \param[out] msg message buffer + * \param[in] sw SW Description struct + * \param[in] put_sw_descr boolean, whether to put NM_ATT_SW_DESCR IE or not + * \returns length of buffer space necessary to store sw + */ +uint16_t abis_nm_put_sw_desc(struct msgb *msg, const struct abis_nm_sw_desc *sw, bool put_sw_desc) +{ + if (put_sw_desc) + msgb_v_put(msg, NM_ATT_SW_DESCR); + + msgb_tl16v_put(msg, NM_ATT_FILE_ID, sw->file_id_len, sw->file_id); + msgb_tl16v_put(msg, NM_ATT_FILE_VERSION, sw->file_version_len, sw->file_version); + + return abis_nm_sw_desc_len(sw, put_sw_desc); +} + +/*! \brief Put given file ID/Version pair as 3GPP TS 52.021 ?9.4.62 SW Description into msgb. + * \param[out] msg message buffer + * \param[in] id File ID part of SW Description + * \param[in] id File Version part of SW Description + * \param[in] put_sw_descr boolean, whether to put NM_ATT_SW_DESCR IE or not + * \returns length of buffer space necessary to store sw + */ +uint16_t abis_nm_put_sw_file(struct msgb *msg, const char *id, const char *ver, bool put_sw_desc) +{ + struct abis_nm_sw_desc sw = { + .file_id_len = strlen(id), + .file_version_len = strlen(ver), + }; + + memcpy(sw.file_id, id, sw.file_id_len); + memcpy(sw.file_version, ver, sw.file_version_len); + + return abis_nm_put_sw_desc(msg, &sw, put_sw_desc); +} + +/*! \brief Get length of first 3GPP TS 52.021 ?9.4.62 SW Description from buffer. + * \param[in] buf buffer, may contain several SW Descriptions + * \param[in] len buffer length + * \returns length if parsing succeeded, 0 otherwise + */ +uint32_t abis_nm_get_sw_desc_len(const uint8_t *buf, size_t len) +{ + uint16_t sw = 2; /* 1-byte SW tag + 1-byte FILE_* tag */ + + if (buf[0] != NM_ATT_SW_DESCR) + sw = 1; /* 1-byte FILE_* tag */ + + if (buf[sw - 1] != NM_ATT_FILE_ID && buf[sw - 1] != NM_ATT_FILE_VERSION) + return 0; + + /* + length of 1st FILE_* element + 1-byte tag + 2-byte length field of + 1st FILE_* element */ + sw += (osmo_load16be(buf + sw) + 3); + + /* + length of 2nd FILE_* element */ + sw += osmo_load16be(buf + sw); + + return sw + 2; /* + 2-byte length field of 2nd FILE_* element */ +} + +/*! \brief Parse single 3GPP TS 52.021 ?9.4.62 SW Description from buffer. + * \param[out] sw SW Description struct + * \param[in] buf buffer + * \param[in] len buffer length + * \returns 0 if parsing succeeded, negative error code otherwise + */ +static inline int abis_nm_get_sw_desc(struct abis_nm_sw_desc *sw, const uint8_t *buf, size_t length) +{ + int rc; + uint32_t len = abis_nm_get_sw_desc_len(buf, length); + static struct tlv_parsed tp; + const struct tlv_definition sw_tlvdef = { + .def = { + [NM_ATT_SW_DESCR] = { TLV_TYPE_TV }, + [NM_ATT_FILE_ID] = { TLV_TYPE_TL16V }, + [NM_ATT_FILE_VERSION] = { TLV_TYPE_TL16V }, + }, + }; + + /* Basic sanity check */ + if (len > length) + return -EFBIG; + + /* Note: current implementation of TLV parser fails on multilpe SW Descr: + we will only parse the first one */ + if (!len) + return -EINVAL; + + /* Note: the return value is ignored here because SW Description tag + itself is considered optional. */ + tlv_parse(&tp, &sw_tlvdef, buf, len, 0, 0); + + /* Parsing SW Description is tricky for current implementation of TLV + parser which fails to properly handle TV when V has following + structure: | TL16V | TL16V |. Hence, the need for 2nd call: */ + rc = tlv_parse(&tp, &sw_tlvdef, buf + TLVP_LEN(&tp, NM_ATT_SW_DESCR), len - TLVP_LEN(&tp, NM_ATT_SW_DESCR), + 0, 0); + + if (rc < 0) + return rc; + + if (!TLVP_PRESENT(&tp, NM_ATT_FILE_ID)) + return -EBADF; + + if (!TLVP_PRESENT(&tp, NM_ATT_FILE_VERSION)) + return -EBADMSG; + + sw->file_id_len = TLVP_LEN(&tp, NM_ATT_FILE_ID); + sw->file_version_len = TLVP_LEN(&tp, NM_ATT_FILE_VERSION); + + memcpy(sw->file_id, TLVP_VAL(&tp, NM_ATT_FILE_ID), sw->file_id_len); + memcpy(sw->file_version, TLVP_VAL(&tp, NM_ATT_FILE_VERSION), sw->file_version_len); + + return 0; +} + +/*! \brief Parse 3GPP TS 52.021 ?9.4.61 SW Configuration from buffer. + * \param[in] buf buffer + * \param[in] buf_len buffer length + * \param[out] sw SW Description struct array + * \param[in] sw_len Expected number of SW Description entries + * \returns 0 if parsing succeeded, negative error code otherwise + */ +int abis_nm_get_sw_conf(const uint8_t * buf, size_t buf_len, struct abis_nm_sw_desc *sw, uint16_t sw_len) +{ + int rc; + uint16_t len = 0, i; + for (i = 0; i < sw_len; i++) { + memset(&sw[i], 0, sizeof(sw[i])); + rc = abis_nm_get_sw_desc(&sw[i], buf + len, buf_len - len); + if (rc < 0) + return rc; + + len += abis_nm_get_sw_desc_len(buf + len, buf_len - len); + + if (len >= buf_len) + return i + 1; + } + + return i; +} + /*! \brief Obtain OML Channel Combination for phnsical channel config */ int abis_nm_chcomb4pchan(enum gsm_phys_chan_config pchan) { diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map index 3ac37e1..97fd2b4 100644 --- a/src/gsm/libosmogsm.map +++ b/src/gsm/libosmogsm.map @@ -31,6 +31,11 @@ abis_nm_pcause_type_names; abis_nm_msgtype_names; abis_nm_att_names; +abis_nm_sw_desc_len; +abis_nm_put_sw_desc; +abis_nm_put_sw_file; +abis_nm_get_sw_conf; +abis_nm_get_sw_desc_len; osmo_sitype_strs; osmo_c4; diff --git a/tests/Makefile.am b/tests/Makefile.am index ab80c1a..3ce7620 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -15,7 +15,7 @@ bitvec/bitvec_test msgb/msgb_test bits/bitcomp_test \ tlv/tlv_test gsup/gsup_test oap/oap_test fsm/fsm_test \ write_queue/wqueue_test socket/socket_test \ - coding/coding_test + coding/coding_test abis/abis_test if ENABLE_MSGFILE check_PROGRAMS += msgfile/msgfile_test @@ -42,6 +42,9 @@ auth_milenage_test_SOURCES = auth/milenage_test.c auth_milenage_test_LDADD = $(top_builddir)/src/libosmocore.la $(top_builddir)/src/gsm/libosmogsm.la + +abis_abis_test_SOURCES = abis/abis_test.c +abis_abis_test_LDADD = $(top_builddir)/src/libosmocore.la $(top_builddir)/src/gsm/libosmogsm.la ctrl_ctrl_test_SOURCES = ctrl/ctrl_test.c ctrl_ctrl_test_LDADD = $(top_builddir)/src/libosmocore.la $(top_builddir)/src/ctrl/libosmoctrl.la @@ -188,7 +191,7 @@ vty/vty_test.ok comp128/comp128_test.ok \ utils/utils_test.ok stats/stats_test.ok \ bitvec/bitvec_test.ok msgb/msgb_test.ok bits/bitcomp_test.ok \ - sim/sim_test.ok tlv/tlv_test.ok \ + sim/sim_test.ok tlv/tlv_test.ok abis/abis_test.ok \ gsup/gsup_test.ok gsup/gsup_test.err \ oap/oap_test.ok fsm/fsm_test.ok fsm/fsm_test.err \ write_queue/wqueue_test.ok socket/socket_test.ok \ diff --git a/tests/abis/abis_test.c b/tests/abis/abis_test.c new file mode 100644 index 0000000..a303c91 --- /dev/null +++ b/tests/abis/abis_test.c @@ -0,0 +1,208 @@ +/* + * (C) 2012 by Holger Hans Peter Freyther + * (C) 2017 by sysmocom s.m.f.c. GmbH + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +static struct log_info info = {}; + +static const uint8_t simple_config[] = { 66, 18, 0, 3, 1, 2, 3, 19, 0, 3, 3, 4, 5 }; + +static const uint8_t dual_config[] = { + 66, 18, 0, 3, 1, 2, 3, 19, 0, 3, 3, 4, 5, + 66, 18, 0, 3, 9, 7, 5, 19, 0, 3, 6, 7, 8, +}; + +static void test_simple_sw_config(void) +{ + struct abis_nm_sw_desc desc[1]; + uint16_t len; + int rc; + + rc = abis_nm_get_sw_conf(simple_config, ARRAY_SIZE(simple_config), &desc[0], ARRAY_SIZE(desc)); + if (rc != 1) { + printf("%s(): FAILED to parse the File Id/File version: %d\n", __func__, rc); + abort(); + } + + len = abis_nm_sw_desc_len(&desc[0], true); + if (len != 13) { + printf("WRONG SIZE: %u\n", len); + abort(); + } + + printf("len: %u\n", len); + printf("file_id: %s\n", osmo_hexdump(desc[0].file_id, desc[0].file_id_len)); + printf("file_ver: %s\n", osmo_hexdump(desc[0].file_version, desc[0].file_version_len)); + printf("%s(): OK\n", __func__); +} + +static void test_simple_sw_short(void) +{ + struct abis_nm_sw_desc desc[1]; + int i; + + for (i = 1; i < ARRAY_SIZE(simple_config); ++i) { + int rc = abis_nm_get_sw_conf(simple_config, ARRAY_SIZE(simple_config) - i, &desc[0], ARRAY_SIZE(desc)); + if (rc >= 1) { + printf("SHOULD not have parsed: %d\n", rc); + abort(); + } + } + printf("%s(): OK\n", __func__); +} + +static void test_dual_sw_config(void) +{ + struct abis_nm_sw_desc desc[2]; + uint16_t len0, len1; + int rc; + + rc = abis_nm_get_sw_conf(dual_config, ARRAY_SIZE(dual_config), &desc[0], ARRAY_SIZE(desc)); + if (rc != 2) { + printf("%s(): FAILED to parse the File Id/File version: %d (%d,%d)\n", + __func__, -rc, EBADF, EBADMSG); + abort(); + } + + len0 = abis_nm_sw_desc_len(&desc[0], true); + if (len0 != 13) { + printf("WRONG SIZE0: %u\n", len0); + abort(); + } + + len1 = abis_nm_sw_desc_len(&desc[1], true); + if (len1 != 13) { + printf("WRONG SIZE1: %u\n", len1); + abort(); + } + + printf("len: %u\n", len0); + printf("file_id: %s\n", osmo_hexdump(desc[0].file_id, desc[0].file_id_len)); + printf("file_ver: %s\n", osmo_hexdump(desc[0].file_version, desc[0].file_version_len)); + + printf("len: %u\n", len1); + printf("file_id: %s\n", osmo_hexdump(desc[1].file_id, desc[1].file_id_len)); + printf("file_ver: %s\n", osmo_hexdump(desc[1].file_version, desc[1].file_version_len)); + printf("%s(): OK\n", __func__); +} + +static inline void print_chk(const char *what, uint8_t len1, uint8_t len2, const uint8_t *x1, const uint8_t *x2) +{ + int cmp = memcmp(x1, x2, len2); + printf("\tFILE %s [%u == %u -> %d, %s] %d => %s\n", what, len1, len2, len1 == len2, len1 != len2 ? "fail" : "ok", + cmp, cmp != 0 ? "FAIL" : "OK"); +} + +static inline void chk_raw(const char *what, const uint8_t *data, uint16_t len) +{ + struct abis_nm_sw_desc sw = { 0 }; + int res = abis_nm_get_sw_conf(data, len, &sw, 1); + uint16_t xlen = abis_nm_get_sw_desc_len(data, len); + + printf("parsing chained %s <1st: %d, total: %d>\n\tSW Descr (%s)\n", osmo_hexdump(data, len), xlen, len, what); + + if (res < 0) + printf("\tFAIL: %d\n", -res); + else { + printf("\tFILE ID: [%d] %s => OK\n", sw.file_id_len, osmo_hexdump(sw.file_id, sw.file_id_len)); + printf("\tFILE VERSION: [%d] %s => OK\n", sw.file_version_len, + osmo_hexdump(sw.file_version, sw.file_version_len)); + } + + if (len != xlen) + chk_raw(" 2nd", data + xlen, len - xlen); +} + +static inline void chk_descr(struct msgb *msg, const char *f_id, const char *f_ver, const char *desc, bool header) +{ + int res; + uint16_t len; + struct abis_nm_sw_desc sw = { 0 }, put = { + .file_id_len = strlen(f_id), + .file_version_len = strlen(f_ver), + }; + + memcpy(put.file_id, f_id, put.file_id_len); + memcpy(put.file_version, f_ver, put.file_version_len); + len = abis_nm_put_sw_file(msg, f_id, f_ver, header); + + printf("msgb[%u] :: {msgb->len} %u == %u {len} - %s]:\n\tSW DESCR (%s)\n" + "\tlength: {extracted} %u = %u {expected} - %s, failsafe - %s\n", + msg->data_len, msg->len, len, len != msg->len ? "fail" : "ok", desc, + abis_nm_get_sw_desc_len(msgb_data(msg), msg->len), msg->len, + abis_nm_get_sw_desc_len(msgb_data(msg), msg->len) != msg->len ? "FAIL" : "OK", + len > put.file_version_len + put.file_id_len ? "OK" : "FAIL"); + + res = abis_nm_get_sw_conf(msgb_data(msg), msg->len, &sw, 1); + if (res < 0) + printf("\tSW DESCR (%s) parsing error code %d!\n", desc, -res); + else { + print_chk("ID", sw.file_id_len, put.file_id_len, sw.file_id, put.file_id); + print_chk("VERSION", sw.file_version_len, put.file_version_len, sw.file_version, put.file_version); + } +} + +static void test_sw_descr() +{ + const char *f_id = "TEST.L0L", *f_ver = "0.1.666~deadbeeffacefeed-dirty"; + uint8_t chain[] = { 0x42, 0x12, 0x00, 0x03, 0x01, 0x02, 0x03, 0x13, 0x00, 0x03, 0x03, 0x04, 0x05, 0x42, 0x12, + 0x00, 0x03, 0x09, 0x07, 0x05, 0x13, 0x00, 0x03, 0x06, 0x07, 0x08 }; + struct msgb *msg = msgb_alloc_headroom(4096, 128, "sw"); + + printf("Testing SW Description (de)serialization...\n"); + + /* check that parsing |SW|ID|VER| works: */ + chk_descr(msg, f_id, f_ver, "with header", true); + msgb_reset(msg); + + /* check that parsing |ID|VER| works: */ + chk_descr(msg, f_id, f_ver, "without header", false); + + /* check that parsing |ID|VER|SW|ID|VER| fails - notice the lack of msgb_reset() to create bogus msgb data: */ + chk_descr(msg, f_id, f_ver, "expected failure", true); + + /* check multiple, chained SW-descr: */ + chk_raw("half", chain, sizeof(chain) / 2); + chk_raw("full", chain, sizeof(chain)); +} + +int main(int argc, char **argv) +{ + osmo_init_logging(&info); + + test_sw_descr(); + test_simple_sw_config(); + test_simple_sw_short(); + test_dual_sw_config(); + + printf("OK.\n"); + + return 0; +} diff --git a/tests/abis/abis_test.ok b/tests/abis/abis_test.ok new file mode 100644 index 0000000..e6b626b --- /dev/null +++ b/tests/abis/abis_test.ok @@ -0,0 +1,41 @@ +Testing SW Description (de)serialization... +msgb[4096] :: {msgb->len} 45 == 45 {len} - ok]: + SW DESCR (with header) + length: {extracted} 45 = 45 {expected} - OK, failsafe - OK + FILE ID [8 == 8 -> 1, ok] 0 => OK + FILE VERSION [30 == 30 -> 1, ok] 0 => OK +msgb[4096] :: {msgb->len} 44 == 44 {len} - ok]: + SW DESCR (without header) + length: {extracted} 44 = 44 {expected} - OK, failsafe - OK + FILE ID [8 == 8 -> 1, ok] 0 => OK + FILE VERSION [30 == 30 -> 1, ok] 0 => OK +msgb[4096] :: {msgb->len} 89 == 45 {len} - fail]: + SW DESCR (expected failure) + length: {extracted} 44 = 89 {expected} - FAIL, failsafe - OK + FILE ID [8 == 8 -> 1, ok] 0 => OK + FILE VERSION [30 == 30 -> 1, ok] 0 => OK +parsing chained 42 12 00 03 01 02 03 13 00 03 03 04 05 <1st: 13, total: 13> + SW Descr (half) + FILE ID: [3] 01 02 03 => OK + FILE VERSION: [3] 03 04 05 => OK +parsing chained 42 12 00 03 01 02 03 13 00 03 03 04 05 42 12 00 03 09 07 05 13 00 03 06 07 08 <1st: 13, total: 26> + SW Descr (full) + FILE ID: [3] 01 02 03 => OK + FILE VERSION: [3] 03 04 05 => OK +parsing chained 42 12 00 03 09 07 05 13 00 03 06 07 08 <1st: 13, total: 13> + SW Descr ( 2nd) + FILE ID: [3] 09 07 05 => OK + FILE VERSION: [3] 06 07 08 => OK +len: 13 +file_id: 01 02 03 +file_ver: 03 04 05 +test_simple_sw_config(): OK +test_simple_sw_short(): OK +len: 13 +file_id: 01 02 03 +file_ver: 03 04 05 +len: 13 +file_id: 09 07 05 +file_ver: 06 07 08 +test_dual_sw_config(): OK +OK. diff --git a/tests/testsuite.at b/tests/testsuite.at index 64df724..7ee0164 100644 --- a/tests/testsuite.at +++ b/tests/testsuite.at @@ -9,6 +9,12 @@ AT_CHECK([$abs_top_builddir/tests/a5/a5_test], [0], [expout]) AT_CLEANUP +AT_SETUP([abis]) +AT_KEYWORDS([abis]) +cat $abs_srcdir/abis/abis_test.ok > expout +AT_CHECK([$abs_top_builddir/tests/abis/abis_test], [0], [expout], [ignore]) +AT_CLEANUP + AT_SETUP([ctrl]) AT_KEYWORDS([ctrl]) cat $abs_srcdir/ctrl/ctrl_test.ok > expout -- To view, visit https://gerrit.osmocom.org/2165 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ib63b6b5e83b8914864fc7edd789f8958cdc993cd Gerrit-PatchSet: 15 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Fri Apr 28 08:45:37 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Fri, 28 Apr 2017 08:45:37 +0000 Subject: [MERGED] openbsc[master]: Prepare for extended SI2quater support In-Reply-To: References: Message-ID: Max has submitted this change and it was merged. Change subject: Prepare for extended SI2quater support ...................................................................... Prepare for extended SI2quater support Supporting SI2quater as per 3GPP TS 44.018 will require chnages to the way System Information is stored because it uses 1:n instead of 1:1 mapping between SI type and generated SI content. This should not affect other SI types though. To facilitate this transition: * convert the code to always use GSM_BTS_SI helper instead of accessing buffer directly * make helper more robust by adding extra parenthesis * add similar helper for gsm_lchan * add function estimating number of SI2quater message to hold configured number of (U|E)ARFCNs * add SI2q index/count fields and pass them to rest_octets generator explicitly * internalize buffer access in generate_si* functions Change-Id: I74e4e3cb86364cec869a1472a41b4a95af0d50dd Related: RT#8792 --- M openbsc/include/openbsc/gsm_data_shared.h M openbsc/include/openbsc/rest_octets.h M openbsc/include/openbsc/system_information.h M openbsc/src/libbsc/bsc_vty.c M openbsc/src/libbsc/rest_octets.c M openbsc/src/libbsc/system_information.c M openbsc/tests/gsm0408/gsm0408_test.c 7 files changed, 60 insertions(+), 61 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/openbsc/include/openbsc/gsm_data_shared.h b/openbsc/include/openbsc/gsm_data_shared.h index 242889a..166de16 100644 --- a/openbsc/include/openbsc/gsm_data_shared.h +++ b/openbsc/include/openbsc/gsm_data_shared.h @@ -483,7 +483,8 @@ struct gsm_bts_trx_ts ts[TRX_NR_TS]; }; -#define GSM_BTS_SI(bts, i) (void *)(bts->si_buf[i]) +#define GSM_BTS_SI(bts, i) (void *)((bts)->si_buf[i]) +#define GSM_LCHAN_SI(lchan, i) (void *)((lchan)->si.buf[i]) enum gsm_bts_type { GSM_BTS_TYPE_UNKNOWN, @@ -702,6 +703,9 @@ /* bitmask of all SI that are present/valid in si_buf */ uint32_t si_valid; + /* 3GPP TS 44.018 Table 10.5.2.33b.1 INDEX and COUNT for SI2quater */ + uint8_t si2q_index; + uint8_t si2q_count; /* buffers where we put the pre-computed SI */ sysinfo_buf_t si_buf[_MAX_SYSINFO_TYPE]; diff --git a/openbsc/include/openbsc/rest_octets.h b/openbsc/include/openbsc/rest_octets.h index 3b4e598..73ce57b 100644 --- a/openbsc/include/openbsc/rest_octets.h +++ b/openbsc/include/openbsc/rest_octets.h @@ -5,12 +5,15 @@ #include #include +/* 16 is the max. number of SI2quater messages according to 3GPP TS 44.018: 4-bit index is used */ +#define SI2Q_MAX_NUM 16 +/* length in bits (for single SI2quater message) */ #define SI2Q_MAX_LEN 160 #define SI2Q_MIN_LEN 18 /* generate SI1 rest octets */ int rest_octets_si1(uint8_t *data, uint8_t *nch_pos, int is1800_net); -int rest_octets_si2quater(uint8_t *data, const struct osmo_earfcn_si2q *e, +int rest_octets_si2quater(uint8_t *data, uint8_t index, uint8_t count, const struct osmo_earfcn_si2q *e, const uint16_t *u, const uint16_t *sc, size_t u_len); int rest_octets_si6(uint8_t *data, bool is1800_net); diff --git a/openbsc/include/openbsc/system_information.h b/openbsc/include/openbsc/system_information.h index 1b19c8b..b012107 100644 --- a/openbsc/include/openbsc/system_information.h +++ b/openbsc/include/openbsc/system_information.h @@ -14,7 +14,7 @@ unsigned range512_q(unsigned m); int range_encode(enum gsm48_range r, int *arfcns, int arfcns_used, int *w, int f0, uint8_t *chan_list); -bool si2q_size_check(const struct gsm_bts *bts); +uint8_t si2q_num(const struct gsm_bts *bts); int bts_uarfcn_del(struct gsm_bts *bts, uint16_t arfcn, uint16_t scramble); int bts_uarfcn_add(struct gsm_bts *bts, uint16_t arfcn, uint16_t scramble, bool diversity); diff --git a/openbsc/src/libbsc/bsc_vty.c b/openbsc/src/libbsc/bsc_vty.c index 3c70580..195fd6a 100644 --- a/openbsc/src/libbsc/bsc_vty.c +++ b/openbsc/src/libbsc/bsc_vty.c @@ -644,7 +644,7 @@ get_value_string(osmo_sitype_strs, i), VTY_NEWLINE); vty_out(vty, " system-information %s static %s%s", get_value_string(osmo_sitype_strs, i), - osmo_hexdump_nospc(bts->si_buf[i], sizeof(bts->si_buf[i])), + osmo_hexdump_nospc(GSM_BTS_SI(bts, i), GSM_MACBLOCK_LEN), VTY_NEWLINE); } } @@ -2687,11 +2687,11 @@ } /* Fill buffer with padding pattern */ - memset(bts->si_buf[type], 0x2b, sizeof(bts->si_buf[type])); + memset(GSM_BTS_SI(bts, type), 0x2b, GSM_MACBLOCK_LEN); /* Parse the user-specified SI in hex format, [partially] overwriting padding */ - rc = osmo_hexparse(argv[1], bts->si_buf[type], sizeof(bts->si_buf[0])); - if (rc < 0 || rc > sizeof(bts->si_buf[0])) { + rc = osmo_hexparse(argv[1], GSM_BTS_SI(bts, type), GSM_MACBLOCK_LEN); + if (rc < 0 || rc > GSM_MACBLOCK_LEN) { vty_out(vty, "Error parsing HEXSTRING%s", VTY_NEWLINE); return CMD_WARNING; } @@ -2829,7 +2829,7 @@ e->prio_valid = true; } - if (si2q_size_check(bts)) + if (si2q_num(bts) < 2) return CMD_SUCCESS; vty_out(vty, "Warning: not enough space in SI2quater for a given EARFCN " diff --git a/openbsc/src/libbsc/rest_octets.c b/openbsc/src/libbsc/rest_octets.c index ed6c573..af660f1 100644 --- a/openbsc/src/libbsc/rest_octets.c +++ b/openbsc/src/libbsc/rest_octets.c @@ -256,7 +256,7 @@ } /* generate SI2quater rest octets: 3GPP TS 44.018 ? 10.5.2.33b */ -int rest_octets_si2quater(uint8_t *data, const struct osmo_earfcn_si2q *e, +int rest_octets_si2quater(uint8_t *data, uint8_t index, uint8_t count, const struct osmo_earfcn_si2q *e, const uint16_t *u, const uint16_t *sc, size_t u_len) { int rc; @@ -275,9 +275,9 @@ /* we do not support multiple si2quater messages at the moment: */ /* SI2quater_INDEX */ - bitvec_set_uint(&bv, 0, 4); + bitvec_set_uint(&bv, index, 4); /* SI2quater_COUNT */ - bitvec_set_uint(&bv, 0, 4); + bitvec_set_uint(&bv, count, 4); /* No Measurement_Parameters Description */ bitvec_set_bit(&bv, 0); diff --git a/openbsc/src/libbsc/system_information.c b/openbsc/src/libbsc/system_information.c index 2610331..37395f0 100644 --- a/openbsc/src/libbsc/system_information.c +++ b/openbsc/src/libbsc/system_information.c @@ -149,18 +149,13 @@ return s + r + append + range1024_p(k); } -bool si2q_size_check(const struct gsm_bts *bts) +uint8_t si2q_num(const struct gsm_bts *bts) { - const struct osmo_earfcn_si2q *e = &bts->si_common.si2quater_neigh_list; - const uint16_t *u = bts->si_common.data.uarfcn_list, - *sc = bts->si_common.data.scramble_list; - size_t len = bts->si_common.uarfcn_length; - unsigned e_sz = e ? earfcn_size(e) : 1, - u_sz = len ? uarfcn_size(u, sc, len) : 1; + const struct osmo_earfcn_si2q *e = &bts->si_common.si2quater_neigh_list; /* EARFCN */ + const uint16_t *u = bts->si_common.data.uarfcn_list, *sc = bts->si_common.data.scramble_list; /* UARFCN */ + size_t l = bts->si_common.uarfcn_length, e_sz = e ? earfcn_size(e) : 1, u_sz = l ? uarfcn_size(u, sc, l) : 1; /* 2 bits are used in between UARFCN and EARFCN structs */ - if (SI2Q_MIN_LEN + u_sz + 2 + e_sz > SI2Q_MAX_LEN) - return false; - return true; + return 1 + (e_sz + u_sz) / (SI2Q_MAX_LEN - (SI2Q_MIN_LEN + 2)); } /* 3GPP TS 44.018, Table 9.1.54.1 - prepend diversity bit to scrambling code */ @@ -233,7 +228,7 @@ scl[k] = scr; bts->si_common.uarfcn_length++; - if (si2q_size_check(bts)) + if (si2q_num(bts) < 2) return 0; bts_uarfcn_del(bts, arfcn, scramble); @@ -557,11 +552,10 @@ return n; } -static int generate_si1(uint8_t *output, struct gsm_bts *bts) +static int generate_si1(enum osmo_sysinfo_type t, struct gsm_bts *bts) { int rc; - struct gsm48_system_information_type_1 *si1 = - (struct gsm48_system_information_type_1 *) output; + struct gsm48_system_information_type_1 *si1 = (struct gsm48_system_information_type_1 *) GSM_BTS_SI(bts, t); memset(si1, GSM_MACBLOCK_PADDING, GSM_MACBLOCK_LEN); @@ -586,11 +580,10 @@ return sizeof(*si1) + rc; } -static int generate_si2(uint8_t *output, struct gsm_bts *bts) +static int generate_si2(enum osmo_sysinfo_type t, struct gsm_bts *bts) { int rc; - struct gsm48_system_information_type_2 *si2 = - (struct gsm48_system_information_type_2 *) output; + struct gsm48_system_information_type_2 *si2 = (struct gsm48_system_information_type_2 *) GSM_BTS_SI(bts, t); memset(si2, GSM_MACBLOCK_PADDING, GSM_MACBLOCK_LEN); @@ -611,11 +604,11 @@ return sizeof(*si2); } -static int generate_si2bis(uint8_t *output, struct gsm_bts *bts) +static int generate_si2bis(enum osmo_sysinfo_type t, struct gsm_bts *bts) { int rc; struct gsm48_system_information_type_2bis *si2b = - (struct gsm48_system_information_type_2bis *) output; + (struct gsm48_system_information_type_2bis *) GSM_BTS_SI(bts, t); int n; memset(si2b, GSM_MACBLOCK_PADDING, GSM_MACBLOCK_LEN); @@ -633,8 +626,7 @@ if (n) { /* indicate in SI2 and SI2bis: there is an extension */ struct gsm48_system_information_type_2 *si2 = - (struct gsm48_system_information_type_2 *) - bts->si_buf[SYSINFO_TYPE_2]; + (struct gsm48_system_information_type_2 *) GSM_BTS_SI(bts, SYSINFO_TYPE_2); si2->bcch_frequency_list[0] |= 0x20; si2b->bcch_frequency_list[0] |= 0x20; } else @@ -645,11 +637,11 @@ return sizeof(*si2b); } -static int generate_si2ter(uint8_t *output, struct gsm_bts *bts) +static int generate_si2ter(enum osmo_sysinfo_type t, struct gsm_bts *bts) { int rc; struct gsm48_system_information_type_2ter *si2t = - (struct gsm48_system_information_type_2ter *) output; + (struct gsm48_system_information_type_2ter *) GSM_BTS_SI(bts, t); int n; memset(si2t, GSM_MACBLOCK_PADDING, GSM_MACBLOCK_LEN); @@ -670,11 +662,11 @@ return sizeof(*si2t); } -static int generate_si2quater(uint8_t *output, struct gsm_bts *bts) +static int generate_si2quater(enum osmo_sysinfo_type t, struct gsm_bts *bts) { int rc, i = MAX_EARFCN_LIST; struct gsm48_system_information_type_2quater *si2q = - (struct gsm48_system_information_type_2quater *) output; + (struct gsm48_system_information_type_2quater *) GSM_BTS_SI(bts, t); memset(si2q, GSM_MACBLOCK_PADDING, GSM_MACBLOCK_LEN); @@ -683,7 +675,7 @@ si2q->header.skip_indicator = 0; si2q->header.system_information = GSM48_MT_RR_SYSINFO_2quater; - rc = rest_octets_si2quater(si2q->rest_octets, + rc = rest_octets_si2quater(si2q->rest_octets, bts->si2q_index, bts->si2q_count, &bts->si_common.si2quater_neigh_list, bts->si_common.data.uarfcn_list, bts->si_common.data.scramble_list, @@ -727,11 +719,10 @@ .break_ind = 0, }; -static int generate_si3(uint8_t *output, struct gsm_bts *bts) +static int generate_si3(enum osmo_sysinfo_type t, struct gsm_bts *bts) { int rc; - struct gsm48_system_information_type_3 *si3 = - (struct gsm48_system_information_type_3 *) output; + struct gsm48_system_information_type_3 *si3 = (struct gsm48_system_information_type_3 *) GSM_BTS_SI(bts, t); memset(si3, GSM_MACBLOCK_PADDING, GSM_MACBLOCK_LEN); @@ -775,11 +766,10 @@ return sizeof(*si3) + rc; } -static int generate_si4(uint8_t *output, struct gsm_bts *bts) +static int generate_si4(enum osmo_sysinfo_type t, struct gsm_bts *bts) { int rc; - struct gsm48_system_information_type_4 *si4 = - (struct gsm48_system_information_type_4 *) output; + struct gsm48_system_information_type_4 *si4 = (struct gsm48_system_information_type_4 *) GSM_BTS_SI(bts, t); struct gsm_lchan *cbch_lchan; uint8_t *restoct = si4->data; @@ -815,14 +805,15 @@ /* SI4 Rest Octets (10.5.2.35), containing Optional Power offset, GPRS Indicator, Cell Identity, LSA ID, Selection Parameter */ - rc = rest_octets_si4(restoct, &si_info, output + GSM_MACBLOCK_LEN - restoct); + rc = rest_octets_si4(restoct, &si_info, (uint8_t *)GSM_BTS_SI(bts, t) + GSM_MACBLOCK_LEN - restoct); return l2_plen + 1 + rc; } -static int generate_si5(uint8_t *output, struct gsm_bts *bts) +static int generate_si5(enum osmo_sysinfo_type t, struct gsm_bts *bts) { struct gsm48_system_information_type_5 *si5; + uint8_t *output = GSM_BTS_SI(bts, t); int rc, l2_plen = 18; memset(output, GSM_MACBLOCK_PADDING, GSM_MACBLOCK_LEN); @@ -838,7 +829,7 @@ break; } - si5 = (struct gsm48_system_information_type_5 *) output; + si5 = (struct gsm48_system_information_type_5 *) GSM_BTS_SI(bts, t); /* l2 pseudo length, not part of msg: 18 */ si5->rr_protocol_discriminator = GSM48_PDISC_RR; @@ -854,9 +845,10 @@ return l2_plen; } -static int generate_si5bis(uint8_t *output, struct gsm_bts *bts) +static int generate_si5bis(enum osmo_sysinfo_type t, struct gsm_bts *bts) { struct gsm48_system_information_type_5bis *si5b; + uint8_t *output = GSM_BTS_SI(bts, t); int rc, l2_plen = 18; int n; @@ -873,7 +865,7 @@ break; } - si5b = (struct gsm48_system_information_type_5bis *) output; + si5b = (struct gsm48_system_information_type_5bis *) GSM_BTS_SI(bts, t); /* l2 pseudo length, not part of msg: 18 */ si5b->rr_protocol_discriminator = GSM48_PDISC_RR; @@ -887,8 +879,7 @@ if (n) { /* indicate in SI5 and SI5bis: there is an extension */ struct gsm48_system_information_type_5 *si5 = - (struct gsm48_system_information_type_5 *) - bts->si_buf[SYSINFO_TYPE_5]; + (struct gsm48_system_information_type_5 *) GSM_BTS_SI(bts, SYSINFO_TYPE_5); si5->bcch_frequency_list[0] |= 0x20; si5b->bcch_frequency_list[0] |= 0x20; } else @@ -898,9 +889,10 @@ return l2_plen; } -static int generate_si5ter(uint8_t *output, struct gsm_bts *bts) +static int generate_si5ter(enum osmo_sysinfo_type t, struct gsm_bts *bts) { struct gsm48_system_information_type_5ter *si5t; + uint8_t *output = GSM_BTS_SI(bts, t); int rc, l2_plen = 18; int n; @@ -917,7 +909,7 @@ break; } - si5t = (struct gsm48_system_information_type_5ter *) output; + si5t = (struct gsm48_system_information_type_5ter *) GSM_BTS_SI(bts, t); /* l2 pseudo length, not part of msg: 18 */ si5t->rr_protocol_discriminator = GSM48_PDISC_RR; @@ -935,9 +927,10 @@ return l2_plen; } -static int generate_si6(uint8_t *output, struct gsm_bts *bts) +static int generate_si6(enum osmo_sysinfo_type t, struct gsm_bts *bts) { struct gsm48_system_information_type_6 *si6; + uint8_t *output = GSM_BTS_SI(bts, t); int l2_plen = 11; int rc; @@ -954,7 +947,7 @@ break; } - si6 = (struct gsm48_system_information_type_6 *) output; + si6 = (struct gsm48_system_information_type_6 *) GSM_BTS_SI(bts, t); /* l2 pseudo length, not part of msg: 11 */ si6->rr_protocol_discriminator = GSM48_PDISC_RR; @@ -1015,10 +1008,10 @@ }, }; -static int generate_si13(uint8_t *output, struct gsm_bts *bts) +static int generate_si13(enum osmo_sysinfo_type t, struct gsm_bts *bts) { struct gsm48_system_information_type_13 *si13 = - (struct gsm48_system_information_type_13 *) output; + (struct gsm48_system_information_type_13 *) GSM_BTS_SI(bts, t); int ret; memset(si13, GSM_MACBLOCK_PADDING, GSM_MACBLOCK_LEN); @@ -1048,7 +1041,7 @@ return sizeof (*si13) + ret; } -typedef int (*gen_si_fn_t)(uint8_t *output, struct gsm_bts *bts); +typedef int (*gen_si_fn_t)(enum osmo_sysinfo_type t, struct gsm_bts *bts); static const gen_si_fn_t gen_si_fn[_MAX_SYSINFO_TYPE] = { [SYSINFO_TYPE_1] = &generate_si1, @@ -1090,5 +1083,5 @@ if (!gen_si) return -EINVAL; - return gen_si(bts->si_buf[si_type], bts); + return gen_si(si_type, bts); } diff --git a/openbsc/tests/gsm0408/gsm0408_test.c b/openbsc/tests/gsm0408/gsm0408_test.c index 08cf43f..81dc177 100644 --- a/openbsc/tests/gsm0408/gsm0408_test.c +++ b/openbsc/tests/gsm0408/gsm0408_test.c @@ -99,13 +99,12 @@ bts->si_valid = 0; bts->si_valid |= (1 << SYSINFO_TYPE_2quater); /* should be no-op as entire buffer is filled with padding: */ - memset(bts->si_buf[SYSINFO_TYPE_2quater], 0xAE, GSM_MACBLOCK_LEN); + memset(GSM_BTS_SI(bts, SYSINFO_TYPE_2quater), 0xAE, GSM_MACBLOCK_LEN); int r = gsm_generate_si(bts, SYSINFO_TYPE_2quater); bool v = bts->si_valid & (1 << SYSINFO_TYPE_2quater); if (r > 0) printf("generated %s SI2quater: [%d] %s\n", - v ? "valid" : "invalid", r, - osmo_hexdump(bts->si_buf[SYSINFO_TYPE_2quater], r)); + v ? "valid" : "invalid", r, osmo_hexdump(GSM_BTS_SI(bts, SYSINFO_TYPE_2quater), r)); else printf("failed to generate SI2quater: %s\n", strerror(-r)); } -- To view, visit https://gerrit.osmocom.org/2312 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I74e4e3cb86364cec869a1472a41b4a95af0d50dd Gerrit-PatchSet: 9 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max From gerrit-no-reply at lists.osmocom.org Fri Apr 28 08:47:22 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Fri, 28 Apr 2017 08:47:22 +0000 Subject: [MERGED] osmo-bts[master]: osmo-bts-trx: cosmetic log fix In-Reply-To: References: Message-ID: Max has submitted this change and it was merged. Change subject: osmo-bts-trx: cosmetic log fix ...................................................................... osmo-bts-trx: cosmetic log fix Print actual value causing error and the check range. Change-Id: Ic36c0558cdbd1790c167f290a40007b42f5de65d --- M src/common/scheduler.c 1 file changed, 11 insertions(+), 9 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/common/scheduler.c b/src/common/scheduler.c index 724fb5a..27b7630 100644 --- a/src/common/scheduler.c +++ b/src/common/scheduler.c @@ -305,11 +305,11 @@ goto wrong_type; } if (prim_fn > 100) { - LOGP(DL1C, LOGL_NOTICE, "Prim for trx=%u ts=%u at fn=%u " - "is out of range, or channel %s with type %s is " - "already disabled. If this happens in conjunction " - "with PCU, increase 'rts-advance' by 5. " - "(current fn=%u)\n", l1t->trx->nr, tn, + LOGP(DL1C, LOGL_NOTICE, "Prim %u for trx=%u ts=%u at " + "fn=%u is out of range (100), or channel %s with " + "type %s is already disabled. If this happens in " + "conjunction with PCU, increase 'rts-advance' by 5." + " (current fn=%u)\n", prim_fn, l1t->trx->nr, tn, l1sap->u.data.fn, get_lchan_by_chan_nr(l1t->trx, chan_nr)->name, get_value_string(trx_chan_type_names, chan), fn); @@ -1609,10 +1609,12 @@ no_data: /* in case of C0, we need a dummy burst to maintain RF power */ if (bits == NULL && l1t->trx == l1t->trx->bts->c0) { -if (0) if (chan != TRXC_IDLE) // hack - LOGP(DL1C, LOGL_DEBUG, "No burst data for %s fn=%u ts=%u " - "burst=%d on C0, so filling with dummy burst\n", - trx_chan_desc[chan].name, fn, tn, bid); +#if 0 + if (chan != TRXC_IDLE) // hack + LOGP(DL1C, LOGL_DEBUG, "No burst data for %s fn=%u ts=%u " + "burst=%d on C0, so filling with dummy burst\n", + trx_chan_desc[chan].name, fn, tn, bid); +#endif bits = (ubit_t *) dummy_burst; } -- To view, visit https://gerrit.osmocom.org/1974 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ic36c0558cdbd1790c167f290a40007b42f5de65d Gerrit-PatchSet: 3 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Fri Apr 28 08:48:27 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Fri, 28 Apr 2017 08:48:27 +0000 Subject: osmo-bts[master]: osmo-bts-trx: cosmetic log fix In-Reply-To: References: Message-ID: Patch Set 3: Not sure which comment you're referring to. Probably smth from 1582? -- To view, visit https://gerrit.osmocom.org/1974 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ic36c0558cdbd1790c167f290a40007b42f5de65d Gerrit-PatchSet: 3 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Apr 28 08:49:06 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Fri, 28 Apr 2017 08:49:06 +0000 Subject: [MERGED] openbsc[master]: Add gsm_bts_type_variant to gsm_bts struct In-Reply-To: References: Message-ID: Max has submitted this change and it was merged. Change subject: Add gsm_bts_type_variant to gsm_bts struct ...................................................................... Add gsm_bts_type_variant to gsm_bts struct Previously it was only in gsm_bts_model which is not initialized on BTS side. It's more convenient to have it in the struct which is available to BTS as well. Change-Id: I54fde8c4ccd5d994af08074f5864446e79a93a25 Related: OS#1614 --- M openbsc/include/openbsc/gsm_data_shared.h 1 file changed, 1 insertion(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/openbsc/include/openbsc/gsm_data_shared.h b/openbsc/include/openbsc/gsm_data_shared.h index 166de16..8f566d2 100644 --- a/openbsc/include/openbsc/gsm_data_shared.h +++ b/openbsc/include/openbsc/gsm_data_shared.h @@ -664,6 +664,7 @@ uint8_t bsic; /* type of BTS */ enum gsm_bts_type type; + enum gsm_bts_type_variant variant; struct gsm_bts_model *model; enum gsm_band band; char version[MAX_VERSION_LENGTH]; -- To view, visit https://gerrit.osmocom.org/2294 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I54fde8c4ccd5d994af08074f5864446e79a93a25 Gerrit-PatchSet: 4 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max From gerrit-no-reply at lists.osmocom.org Fri Apr 28 09:29:53 2017 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Fri, 28 Apr 2017 09:29:53 +0000 Subject: [PATCH] libosmocore[master]: gsm0808: fix control folow issue Message-ID: Review at https://gerrit.osmocom.org/2445 gsm0808: fix control folow issue Coverity Scan reported a control flow issue in line 206: CID 166898: Control flow issues (DEADCODE) The second branch of the if statement can not be reached. The purpose of the second if branch was to filter out zero length elements if the header states that it is a non extended speech codec type. This makes no sense, since the header needs at least one byte. This patch removes the second if branch, zero length elements are catched by the already existing zero length check at the beginning of the function Change-Id: I89751fc0d598734c64ef1fdced75b7c4fa77c616 --- M src/gsm/gsm0808_utils.c 1 file changed, 2 insertions(+), 3 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/45/2445/1 diff --git a/src/gsm/gsm0808_utils.c b/src/gsm/gsm0808_utils.c index 054372a..b4bb878 100644 --- a/src/gsm/gsm0808_utils.c +++ b/src/gsm/gsm0808_utils.c @@ -200,10 +200,9 @@ header = *elem; - /* Malformed elements */ + /* An extended codec type needs at least two fields, + * bail if the input data length is not sufficient. */ if ((header & 0x0F) == 0x0F && len < 2) - return -EINVAL; - else if ((header & 0x0F) != 0x0F && len < 1) return -EINVAL; elem++; -- To view, visit https://gerrit.osmocom.org/2445 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I89751fc0d598734c64ef1fdced75b7c4fa77c616 Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: dexter From gerrit-no-reply at lists.osmocom.org Fri Apr 28 09:29:53 2017 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Fri, 28 Apr 2017 09:29:53 +0000 Subject: [PATCH] libosmocore[master]: gsm0808: fixup length check of the element decoder functions Message-ID: Review at https://gerrit.osmocom.org/2446 gsm0808: fixup length check of the element decoder functions The length check of the decoder functions is not entirely correct. The check also checks for values below zero, which does not make sense, since the length is encoded as uint8_t. For some elements a minimum length is known (in most caes this is 1, so checking for zero is sufficient but in some cases (e.g. channel type) the spec mentions a minimum and maximum length. This is now also reflected in the code. Change-Id: I78bc887f68d1963d28c6fcd631ac20ccd893d6d6 --- M src/gsm/gsm0808_utils.c 1 file changed, 11 insertions(+), 6 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/46/2446/1 diff --git a/src/gsm/gsm0808_utils.c b/src/gsm/gsm0808_utils.c index b4bb878..4b8b925 100644 --- a/src/gsm/gsm0808_utils.c +++ b/src/gsm/gsm0808_utils.c @@ -88,7 +88,7 @@ OSMO_ASSERT(ss); if (!elem) return -EINVAL; - if (len <= 0) + if (len == 0) return -EINVAL; memset(ss, 0, sizeof(*ss)); @@ -166,6 +166,7 @@ uint8_t gsm0808_enc_speech_codec(struct msgb *msg, const struct gsm0808_speech_codec *sc) { + /* See also 3GPP TS 48.008 3.2.2.103 Speech Codec List */ uint8_t *old_tail; uint8_t *tlv_len; @@ -193,7 +194,7 @@ OSMO_ASSERT(sc); if (!elem) return -EINVAL; - if (len <= 0) + if (len == 0) return -EINVAL; memset(sc, 0, sizeof(*sc)); @@ -242,6 +243,7 @@ uint8_t gsm0808_enc_speech_codec_list(struct msgb *msg, const struct gsm0808_speech_codec_list *scl) { + /* See also 3GPP TS 48.008 3.2.2.103 Speech Codec List */ uint8_t *old_tail; uint8_t *tlv_len; unsigned int i; @@ -273,6 +275,7 @@ int gsm0808_dec_speech_codec_list(struct gsm0808_speech_codec_list *scl, const uint8_t *elem, uint8_t len) { + /* See also 3GPP TS 48.008 3.2.2.103 Speech Codec List */ const uint8_t *old_elem = elem; unsigned int i; int rc; @@ -281,7 +284,7 @@ OSMO_ASSERT(scl); if (!elem) return -EINVAL; - if (len <= 0) + if (len == 0) return -EINVAL; memset(scl, 0, sizeof(*scl)); @@ -313,6 +316,7 @@ uint8_t gsm0808_enc_channel_type(struct msgb *msg, const struct gsm0808_channel_type *ct) { + /* See also 3GPP TS 48.008 3.2.2.11 Channel Type */ unsigned int i; uint8_t byte; uint8_t *old_tail; @@ -351,6 +355,7 @@ int gsm0808_dec_channel_type(struct gsm0808_channel_type *ct, const uint8_t *elem, uint8_t len) { + /* See also 3GPP TS 48.008 3.2.2.11 Channel Type */ unsigned int i; uint8_t byte; const uint8_t *old_elem = elem; @@ -358,7 +363,7 @@ OSMO_ASSERT(ct); if (!elem) return -EINVAL; - if (len <= 0) + if (len < 3 || len > 11) return -EINVAL; memset(ct, 0, sizeof(*ct)); @@ -427,7 +432,7 @@ OSMO_ASSERT(ei); if (!elem) return -EINVAL; - if (len <= 0) + if (len == 0) return -EINVAL; memset(ei, 0, sizeof(*ei)); @@ -497,7 +502,7 @@ OSMO_ASSERT(cil); if (!elem) return -EINVAL; - if (len <= 0) + if (len == 0) return -EINVAL; memset(cil, 0, sizeof(*cil)); -- To view, visit https://gerrit.osmocom.org/2446 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I78bc887f68d1963d28c6fcd631ac20ccd893d6d6 Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: dexter From gerrit-no-reply at lists.osmocom.org Fri Apr 28 10:16:18 2017 From: gerrit-no-reply at lists.osmocom.org (dexter) Date: Fri, 28 Apr 2017 10:16:18 +0000 Subject: osmo-trx[master]: ssedetect: Add runtime CPU detection In-Reply-To: References: Message-ID: Patch Set 3: Hello Alexander, I have some questions about this. You suggested to add some fake-target for avx. Maybe I get the things wrong, but I think the things will be not just some changes in the build system. Currently the targets are compiled with -msse4.1 and -mavx. The targets are both different and result into two different .a files. The function prototypes have also different names to avoid clashing. Then the runtime CPU detection detects which CPU is installed and picks the matching implementation by populating some generically named function pointers. Thats how we switch between the different implementations dynamically. You said the avx is similar to (when I remeber correctly) sse 4.1. So technically the that code should compile with -mavx as well. But I still need the sse 4.1 support. An avx compiled sse code would not run on a pure sse machine, right? I would than have to mangle the function prototypes to avoid clashing between the sse 4.1 and the avx version. And of course we need an additional check to populate the function pointers. Maybe I am thinking this overcomplicated, please let me know if I am wrong or right. regards, Philipp -- To view, visit https://gerrit.osmocom.org/2100 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Iba74f8a6e4e921ff31e4bd9f0c7c881fe547423a Gerrit-PatchSet: 3 Gerrit-Project: osmo-trx Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Alexander Chemeris Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Vadim Yanitskiy Gerrit-Reviewer: dexter Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Apr 28 12:44:58 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Fri, 28 Apr 2017 12:44:58 +0000 Subject: [PATCH] osmo-bts[master]: Prepare for extended SI2quater support In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2313 to look at the new patch set (#3). Prepare for extended SI2quater support SI2quater support as per 3GPP TS 44.018 will require chnages to the way System Information is stored because it uses 1:n instead of 1:1 mapping between SI type and generated SI content. This should not affect other SI types though. To facilitate this transition: * convert the code to always use GSM_LCHAN_SI helper instead of accessing buffer directly * move duplicated code to inline function * add logging for buffer truncation and corresponding length values Requires I74e4e3cb86364cec869a1472a41b4a95af0d50dd in OpenBSC. Change-Id: Ie97be6ead6ce6d2d425fbfac8429bb90afb95acc Related: RT#8792 --- M src/common/rsl.c M src/common/sysinfo.c M tests/misc/misc_test.c 3 files changed, 44 insertions(+), 37 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/13/2313/3 diff --git a/src/common/rsl.c b/src/common/rsl.c index 1d0bcea..b3d8b13 100644 --- a/src/common/rsl.c +++ b/src/common/rsl.c @@ -286,14 +286,17 @@ /* 9.3.39 Full BCCH Information */ if (TLVP_PRESENT(&tp, RSL_IE_FULL_BCCH_INFO)) { uint8_t len = TLVP_LEN(&tp, RSL_IE_FULL_BCCH_INFO); - if (len > sizeof(sysinfo_buf_t)) + if (len > sizeof(sysinfo_buf_t)) { + LOGP(DRSL, LOGL_ERROR, "Truncating received Full BCCH Info (%u -> %zu) for SI%s\n", + len, sizeof(sysinfo_buf_t), get_value_string(osmo_sitype_strs, osmo_si)); len = sizeof(sysinfo_buf_t); + } bts->si_valid |= (1 << osmo_si); memset(bts->si_buf[osmo_si], 0x2b, sizeof(sysinfo_buf_t)); memcpy(bts->si_buf[osmo_si], TLVP_VAL(&tp, RSL_IE_FULL_BCCH_INFO), len); - LOGP(DRSL, LOGL_INFO, " Rx RSL BCCH INFO (SI%s)\n", - get_value_string(osmo_sitype_strs, osmo_si)); + LOGP(DRSL, LOGL_INFO, " Rx RSL BCCH INFO (SI%s, %u bytes)\n", + get_value_string(osmo_sitype_strs, osmo_si), len); if (SYSINFO_TYPE_3 == osmo_si && trx->nr == 0 && num_agch(trx, "RSL") != 1) { @@ -432,6 +435,34 @@ TLVP_VAL(&tp, RSL_IE_SMSCB_MSG)); } +/* 'buf' must be caller-allocated and hold at least len + 2 or sizeof(sysinfo_buf_t) bytes */ +static inline void lapdm_ui_prefix(uint8_t *buf, uint32_t *valid, const uint8_t *current, uint8_t osmo_si, uint16_t len) +{ + /* We have to pre-fix with the two-byte LAPDM UI header */ + if (len > sizeof(sysinfo_buf_t) - 2) { + LOGP(DRSL, LOGL_ERROR, "Truncating received SI%s (%u -> %zu) to prepend LAPDM UI header (2 bytes)\n", + get_value_string(osmo_sitype_strs, osmo_si), len, sizeof(sysinfo_buf_t) - 2); + len = sizeof(sysinfo_buf_t) - 2; + } + + (*valid) |= (1 << osmo_si); + buf[0] = 0x03; /* C/R + EA */ + buf[1] = 0x03; /* UI frame */ + + memset(buf + 2, GSM_MACBLOCK_PADDING, sizeof(sysinfo_buf_t) - 2); + memcpy(buf + 2, current, len); +} + +static inline void lapdm_ui_prefix_bts(struct gsm_bts *bts, const uint8_t *current, uint8_t osmo_si, uint16_t len) +{ + lapdm_ui_prefix(GSM_BTS_SI(bts, osmo_si), &bts->si_valid, current, osmo_si, len); +} + +static inline void lapdm_ui_prefix_lchan(struct gsm_lchan *lchan, const uint8_t *current, uint8_t osmo_si, uint16_t len) +{ + lapdm_ui_prefix(GSM_LCHAN_SI(lchan, osmo_si), &lchan->si.valid, current, osmo_si, len); +} + /* 8.6.2 SACCH FILLING */ static int rsl_rx_sacch_fill(struct gsm_bts_trx *trx, struct msgb *msg) { @@ -457,17 +488,10 @@ } if (TLVP_PRESENT(&tp, RSL_IE_L3_INFO)) { uint16_t len = TLVP_LEN(&tp, RSL_IE_L3_INFO); - /* We have to pre-fix with the two-byte LAPDM UI header */ - if (len > sizeof(sysinfo_buf_t)-2) - len = sizeof(sysinfo_buf_t)-2; - bts->si_valid |= (1 << osmo_si); - bts->si_buf[osmo_si][0] = 0x03; /* C/R + EA */ - bts->si_buf[osmo_si][1] = 0x03; /* UI frame */ - memset(bts->si_buf[osmo_si]+2, 0x2b, sizeof(sysinfo_buf_t)-2); - memcpy(bts->si_buf[osmo_si]+2, - TLVP_VAL(&tp, RSL_IE_L3_INFO), len); - LOGP(DRSL, LOGL_INFO, " Rx RSL SACCH FILLING (SI%s)\n", - get_value_string(osmo_sitype_strs, osmo_si)); + lapdm_ui_prefix_bts(bts, TLVP_VAL(&tp, RSL_IE_L3_INFO), osmo_si, len); + + LOGP(DRSL, LOGL_INFO, " Rx RSL SACCH FILLING (SI%s, %u bytes)\n", + get_value_string(osmo_sitype_strs, osmo_si), len); } else { bts->si_valid &= ~(1 << osmo_si); LOGP(DRSL, LOGL_INFO, " Rx RSL Disabling SACCH FILLING (SI%s)\n", @@ -699,8 +723,7 @@ continue; } lchan->si.valid |= osmo_si_shifted; - memcpy(lchan->si.buf[osmo_si], bts->si_buf[osmo_si], - sizeof(sysinfo_buf_t)); + memcpy(GSM_LCHAN_SI(lchan, osmo_si), GSM_BTS_SI(bts, osmo_si), sizeof(sysinfo_buf_t)); } } @@ -885,7 +908,6 @@ uint8_t rsl_si = *cur++; uint8_t si_len = *cur++; uint8_t osmo_si; - uint8_t copy_len; if (!OSMO_IN_ARRAY(rsl_si, rsl_sacch_sitypes)) return rsl_tx_error_report(msg->trx, RSL_ERR_IE_CONTENT); @@ -896,15 +918,7 @@ return rsl_tx_error_report(msg->trx, RSL_ERR_IE_CONTENT); } - copy_len = si_len; - /* We have to pre-fix with the two-byte LAPDM UI header */ - if (copy_len > sizeof(sysinfo_buf_t)-2) - copy_len = sizeof(sysinfo_buf_t)-2; - lchan->si.valid |= (1 << osmo_si); - lchan->si.buf[osmo_si][0] = 0x03; - lchan->si.buf[osmo_si][1] = 0x03; - memset(lchan->si.buf[osmo_si]+2, 0x2b, sizeof(sysinfo_buf_t)-2); - memcpy(lchan->si.buf[osmo_si]+2, cur, copy_len); + lapdm_ui_prefix_lchan(lchan, cur, osmo_si, si_len); cur += si_len; if (cur >= val + tot_len) { @@ -1337,15 +1351,8 @@ } if (TLVP_PRESENT(&tp, RSL_IE_L3_INFO)) { uint16_t len = TLVP_LEN(&tp, RSL_IE_L3_INFO); - /* We have to pre-fix with the two-byte LAPDM UI header */ - if (len > sizeof(sysinfo_buf_t)-2) - len = sizeof(sysinfo_buf_t)-2; - lchan->si.valid |= (1 << osmo_si); - lchan->si.buf[osmo_si][0] = 0x03; - lchan->si.buf[osmo_si][1] = 0x03; - memset(lchan->si.buf[osmo_si]+2, 0x2b, sizeof(sysinfo_buf_t)-2); - memcpy(lchan->si.buf[osmo_si]+2, - TLVP_VAL(&tp, RSL_IE_L3_INFO), len); + lapdm_ui_prefix_lchan(lchan, TLVP_VAL(&tp, RSL_IE_L3_INFO), osmo_si, len); + LOGP(DRSL, LOGL_INFO, "%s Rx RSL SACCH FILLING (SI%s)\n", gsm_lchan_name(lchan), get_value_string(osmo_sitype_strs, osmo_si)); diff --git a/src/common/sysinfo.c b/src/common/sysinfo.c index 177ed58..d8671c8 100644 --- a/src/common/sysinfo.c +++ b/src/common/sysinfo.c @@ -154,7 +154,7 @@ if (!(lchan->si.valid & (1 << tmp))) continue; lchan->si.last = tmp; - return lchan->si.buf[tmp]; + return GSM_LCHAN_SI(lchan, tmp); } return NULL; } diff --git a/tests/misc/misc_test.c b/tests/misc/misc_test.c index 80dd317..c2918fb 100644 --- a/tests/misc/misc_test.c +++ b/tests/misc/misc_test.c @@ -142,7 +142,7 @@ /* initialize the input. */ for (i = 1; i < _MAX_SYSINFO_TYPE; ++i) { lchan.si.valid |= (1 << i); - memset(&lchan.si.buf[i], i, sizeof(lchan.si.buf[i])); + memset(GSM_LCHAN_SI(&lchan, i), i, GSM_MACBLOCK_LEN); } /* It will start with '1' */ -- To view, visit https://gerrit.osmocom.org/2313 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ie97be6ead6ce6d2d425fbfac8429bb90afb95acc Gerrit-PatchSet: 3 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Fri Apr 28 12:48:55 2017 From: gerrit-no-reply at lists.osmocom.org (Neels Hofmeyr) Date: Fri, 28 Apr 2017 12:48:55 +0000 Subject: [PATCH] openbsc[master]: libmsc: make pitfall in gsm0408_dispatch() more obvious Message-ID: Review at https://gerrit.osmocom.org/2447 libmsc: make pitfall in gsm0408_dispatch() more obvious The function gsm0408_dispatch() accepts a message buffer pointer and accesses the l3h pointer. Even in a properly allocated message buffer, this may lead into a segfault if the user forgets to set the l3h pointer. This commit adds assertions to popup a more expressive error message. Change-Id: Ic0463191e68bac1630481a5cc220222b2f7ef3f2 --- M openbsc/src/libmsc/gsm_04_08.c 1 file changed, 6 insertions(+), 2 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/47/2447/1 diff --git a/openbsc/src/libmsc/gsm_04_08.c b/openbsc/src/libmsc/gsm_04_08.c index 376106f..6641eb9 100644 --- a/openbsc/src/libmsc/gsm_04_08.c +++ b/openbsc/src/libmsc/gsm_04_08.c @@ -3991,13 +3991,17 @@ /* Main entry point for GSM 04.08/44.008 Layer 3 data (e.g. from the BSC). */ int gsm0408_dispatch(struct gsm_subscriber_connection *conn, struct msgb *msg) { - struct gsm48_hdr *gh = msgb_l3(msg); - uint8_t pdisc = gsm48_hdr_pdisc(gh); + struct gsm48_hdr *gh; + uint8_t pdisc; int rc = 0; + OSMO_ASSERT(msg->l3h) OSMO_ASSERT(conn); OSMO_ASSERT(msg); + gh = msgb_l3(msg); + pdisc = gsm48_hdr_pdisc(gh); + LOGP(DRLL, LOGL_DEBUG, "Dispatching 04.08 message, pdisc=%d\n", pdisc); #if 0 if (silent_call_reroute(conn, msg)) -- To view, visit https://gerrit.osmocom.org/2447 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ic0463191e68bac1630481a5cc220222b2f7ef3f2 Gerrit-PatchSet: 1 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: dexter From gerrit-no-reply at lists.osmocom.org Fri Apr 28 12:56:46 2017 From: gerrit-no-reply at lists.osmocom.org (Pau Espin Pedrol) Date: Fri, 28 Apr 2017 12:56:46 +0000 Subject: [PATCH] osmo-gsm-tester[master]: gitignore: Add *.pyc Message-ID: Review at https://gerrit.osmocom.org/2448 gitignore: Add *.pyc Change-Id: I987df905c5d64294488b5a6cdcf4306307616fc6 --- M .gitignore 1 file changed, 1 insertion(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-gsm-tester refs/changes/48/2448/1 diff --git a/.gitignore b/.gitignore index b968e92..4119e7f 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ set_pythonpath test_work state +*.pyc -- To view, visit https://gerrit.osmocom.org/2448 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I987df905c5d64294488b5a6cdcf4306307616fc6 Gerrit-PatchSet: 1 Gerrit-Project: osmo-gsm-tester Gerrit-Branch: master Gerrit-Owner: Pau Espin Pedrol From gerrit-no-reply at lists.osmocom.org Fri Apr 28 12:56:47 2017 From: gerrit-no-reply at lists.osmocom.org (Pau Espin Pedrol) Date: Fri, 28 Apr 2017 12:56:47 +0000 Subject: [PATCH] osmo-gsm-tester[master]: ofono_client: Implement network registration during connect() Message-ID: Review at https://gerrit.osmocom.org/2449 ofono_client: Implement network registration during connect() Change-Id: I1db8c7cba8a83746c16e1ca45f4b8aa0d595caf8 --- M src/osmo_gsm_tester/ofono_client.py 1 file changed, 28 insertions(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/osmo-gsm-tester refs/changes/49/2449/1 diff --git a/src/osmo_gsm_tester/ofono_client.py b/src/osmo_gsm_tester/ofono_client.py index a10784f..974746c 100644 --- a/src/osmo_gsm_tester/ofono_client.py +++ b/src/osmo_gsm_tester/ofono_client.py @@ -113,12 +113,29 @@ self.dbg('Interface enabled:', interface_name) if interface_name == I_SMS: self.dbus_obj()[I_SMS].IncomingMessage.connect(self._on_incoming_message) + if interface_name == I_NETREG: + self.dbus_obj()[I_NETREG].PropertyChanged.connect(self._on_netreg_property_changed) def _on_interface_disabled(self, interface_name): self.dbg('Interface disabled:', interface_name) def has_interface(self, name): return name in self._interfaces + + def _on_netreg_property_changed(self, name, value): + self.log('%r.PropertyChanged() -> %s=%s' % (I_NETREG, name, value)) + + def get_netreg_status(self): + nr = self.dbus_obj()[I_NETREG] + return nr.GetProperties().get('Status') + + def is_roaming(self): + status = self.get_netreg_status() + return status == 'roaming' + + def is_connected(self): + status = self.get_netreg_status() + return status == 'registered' or status == 'roaming' def connect(self, nitb): 'set the modem up to connect to MCC+MNC from NITB config' @@ -127,7 +144,17 @@ if not self.has_interface(I_NETREG): self.log('No %r interface, hoping that the modem connects by itself' % I_NETREG) else: - self.log('Use of %r interface not implemented yet, hoping that the modem connects by itself' % I_NETREG) + if self.is_connected(): + self.log('Already registered with the network') + return + nr = self.dbus_obj()[I_NETREG] + nr.Scan() + nr.Register() + if self.is_connected(): + self.dbg('Registered with network successfully: current status is %s', self.get_netreg_status()) + else: + raise Exception('Failed to register with the network, current status is %s' % self.get_netreg_status()) + def sms_send(self, to_msisdn): if hasattr(to_msisdn, 'msisdn'): -- To view, visit https://gerrit.osmocom.org/2449 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I1db8c7cba8a83746c16e1ca45f4b8aa0d595caf8 Gerrit-PatchSet: 1 Gerrit-Project: osmo-gsm-tester Gerrit-Branch: master Gerrit-Owner: Pau Espin Pedrol From gerrit-no-reply at lists.osmocom.org Fri Apr 28 13:02:43 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Fri, 28 Apr 2017 13:02:43 +0000 Subject: osmo-gsm-tester[master]: gitignore: Add *.pyc In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+1 -- To view, visit https://gerrit.osmocom.org/2448 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I987df905c5d64294488b5a6cdcf4306307616fc6 Gerrit-PatchSet: 1 Gerrit-Project: osmo-gsm-tester Gerrit-Branch: master Gerrit-Owner: Pau Espin Pedrol Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Apr 28 13:04:51 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Fri, 28 Apr 2017 13:04:51 +0000 Subject: libosmocore[master]: gsm0808: fixup length check of the element decoder functions In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+1 -- To view, visit https://gerrit.osmocom.org/2446 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I78bc887f68d1963d28c6fcd631ac20ccd893d6d6 Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Apr 28 13:05:31 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Fri, 28 Apr 2017 13:05:31 +0000 Subject: [PATCH] libosmocore[master]: gsm0808: fixup length check of the element decoder functions In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2446 to look at the new patch set (#2). gsm0808: fixup length check of the element decoder functions The length check of the decoder functions is not entirely correct. The check also checks for values below zero, which does not make sense, since the length is encoded as uint8_t. For some elements a minimum length is known (in most cases this is 1, so checking for zero is sufficient but in some cases (e.g. channel type) the spec mentions a minimum and maximum length. This is now also reflected in the code. Change-Id: I78bc887f68d1963d28c6fcd631ac20ccd893d6d6 --- M src/gsm/gsm0808_utils.c 1 file changed, 11 insertions(+), 6 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/46/2446/2 diff --git a/src/gsm/gsm0808_utils.c b/src/gsm/gsm0808_utils.c index b4bb878..4b8b925 100644 --- a/src/gsm/gsm0808_utils.c +++ b/src/gsm/gsm0808_utils.c @@ -88,7 +88,7 @@ OSMO_ASSERT(ss); if (!elem) return -EINVAL; - if (len <= 0) + if (len == 0) return -EINVAL; memset(ss, 0, sizeof(*ss)); @@ -166,6 +166,7 @@ uint8_t gsm0808_enc_speech_codec(struct msgb *msg, const struct gsm0808_speech_codec *sc) { + /* See also 3GPP TS 48.008 3.2.2.103 Speech Codec List */ uint8_t *old_tail; uint8_t *tlv_len; @@ -193,7 +194,7 @@ OSMO_ASSERT(sc); if (!elem) return -EINVAL; - if (len <= 0) + if (len == 0) return -EINVAL; memset(sc, 0, sizeof(*sc)); @@ -242,6 +243,7 @@ uint8_t gsm0808_enc_speech_codec_list(struct msgb *msg, const struct gsm0808_speech_codec_list *scl) { + /* See also 3GPP TS 48.008 3.2.2.103 Speech Codec List */ uint8_t *old_tail; uint8_t *tlv_len; unsigned int i; @@ -273,6 +275,7 @@ int gsm0808_dec_speech_codec_list(struct gsm0808_speech_codec_list *scl, const uint8_t *elem, uint8_t len) { + /* See also 3GPP TS 48.008 3.2.2.103 Speech Codec List */ const uint8_t *old_elem = elem; unsigned int i; int rc; @@ -281,7 +284,7 @@ OSMO_ASSERT(scl); if (!elem) return -EINVAL; - if (len <= 0) + if (len == 0) return -EINVAL; memset(scl, 0, sizeof(*scl)); @@ -313,6 +316,7 @@ uint8_t gsm0808_enc_channel_type(struct msgb *msg, const struct gsm0808_channel_type *ct) { + /* See also 3GPP TS 48.008 3.2.2.11 Channel Type */ unsigned int i; uint8_t byte; uint8_t *old_tail; @@ -351,6 +355,7 @@ int gsm0808_dec_channel_type(struct gsm0808_channel_type *ct, const uint8_t *elem, uint8_t len) { + /* See also 3GPP TS 48.008 3.2.2.11 Channel Type */ unsigned int i; uint8_t byte; const uint8_t *old_elem = elem; @@ -358,7 +363,7 @@ OSMO_ASSERT(ct); if (!elem) return -EINVAL; - if (len <= 0) + if (len < 3 || len > 11) return -EINVAL; memset(ct, 0, sizeof(*ct)); @@ -427,7 +432,7 @@ OSMO_ASSERT(ei); if (!elem) return -EINVAL; - if (len <= 0) + if (len == 0) return -EINVAL; memset(ei, 0, sizeof(*ei)); @@ -497,7 +502,7 @@ OSMO_ASSERT(cil); if (!elem) return -EINVAL; - if (len <= 0) + if (len == 0) return -EINVAL; memset(cil, 0, sizeof(*cil)); -- To view, visit https://gerrit.osmocom.org/2446 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I78bc887f68d1963d28c6fcd631ac20ccd893d6d6 Gerrit-PatchSet: 2 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max From gerrit-no-reply at lists.osmocom.org Fri Apr 28 13:08:09 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Fri, 28 Apr 2017 13:08:09 +0000 Subject: libosmocore[master]: gsm0808: fix control folow issue In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+1 -- To view, visit https://gerrit.osmocom.org/2445 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I89751fc0d598734c64ef1fdced75b7c4fa77c616 Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Apr 28 13:09:45 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Fri, 28 Apr 2017 13:09:45 +0000 Subject: [PATCH] libosmocore[master]: gsm0808: fix control flow issue In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2445 to look at the new patch set (#2). gsm0808: fix control flow issue Coverity Scan reported a control flow issue in line 206: CID 166898: Control flow issues (DEADCODE) The second branch of the if statement can not be reached. The purpose of the second if branch was to filter out zero length elements if the header states that it is a non extended speech codec type. This makes no sense, since the header needs at least one byte. This patch removes the second if branch, zero length elements are catched by the already existing zero length check at the beginning of the function Change-Id: I89751fc0d598734c64ef1fdced75b7c4fa77c616 --- M src/gsm/gsm0808_utils.c 1 file changed, 2 insertions(+), 3 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/45/2445/2 diff --git a/src/gsm/gsm0808_utils.c b/src/gsm/gsm0808_utils.c index 054372a..b4bb878 100644 --- a/src/gsm/gsm0808_utils.c +++ b/src/gsm/gsm0808_utils.c @@ -200,10 +200,9 @@ header = *elem; - /* Malformed elements */ + /* An extended codec type needs at least two fields, + * bail if the input data length is not sufficient. */ if ((header & 0x0F) == 0x0F && len < 2) - return -EINVAL; - else if ((header & 0x0F) != 0x0F && len < 1) return -EINVAL; elem++; -- To view, visit https://gerrit.osmocom.org/2445 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I89751fc0d598734c64ef1fdced75b7c4fa77c616 Gerrit-PatchSet: 2 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max From gerrit-no-reply at lists.osmocom.org Fri Apr 28 13:09:54 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Fri, 28 Apr 2017 13:09:54 +0000 Subject: libosmocore[master]: gsm0808: fix control flow issue In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+1 -- To view, visit https://gerrit.osmocom.org/2445 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I89751fc0d598734c64ef1fdced75b7c4fa77c616 Gerrit-PatchSet: 2 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Apr 28 13:10:03 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Fri, 28 Apr 2017 13:10:03 +0000 Subject: libosmocore[master]: gsm0808: fixup length check of the element decoder functions In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+1 -- To view, visit https://gerrit.osmocom.org/2446 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I78bc887f68d1963d28c6fcd631ac20ccd893d6d6 Gerrit-PatchSet: 2 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Apr 28 13:37:26 2017 From: gerrit-no-reply at lists.osmocom.org (Max) Date: Fri, 28 Apr 2017 13:37:26 +0000 Subject: [PATCH] openbsc[master]: Make BTS type and variant converters shareable In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2286 to look at the new patch set (#7). Make BTS type and variant converters shareable * move value_string definition and corresponding functions for BTS type to shared header to make it re-usable by OsmoBTS * use consistent function naming * add similar functions for BTS variant * add enum to be used by OML Attribute Reporting to distinguish between type, variant and other info Change-Id: Ida94725a6fce968443541e3526f48f13758031fd Related: OS#1614 --- M openbsc/include/openbsc/gsm_data_shared.h M openbsc/src/libbsc/bsc_vty.c M openbsc/src/libcommon/gsm_data.c M openbsc/src/libcommon/gsm_data_shared.c 4 files changed, 70 insertions(+), 21 deletions(-) git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/86/2286/7 diff --git a/openbsc/include/openbsc/gsm_data_shared.h b/openbsc/include/openbsc/gsm_data_shared.h index 242889a..e016dd9 100644 --- a/openbsc/include/openbsc/gsm_data_shared.h +++ b/openbsc/include/openbsc/gsm_data_shared.h @@ -504,6 +504,12 @@ _NUM_BTS_VARIANT }; +/* Used by OML layer for BTS Attribute reporting */ +enum bts_attribute { + BTS_TYPE_VARIANT, + BTS_SUB_MODEL, +}; + struct vty; struct gsm_bts_model { @@ -859,6 +865,14 @@ struct gsm_bts_trx *gsm_bts_trx_alloc(struct gsm_bts *bts); struct gsm_bts_trx *gsm_bts_trx_num(const struct gsm_bts *bts, int num); +enum gsm_bts_type str2btstype(const char *arg); +const char *btstype2str(enum gsm_bts_type type); + +enum bts_attribute str2btsattr(const char *s); +const char *btsatttr2str(enum bts_attribute v); + +enum gsm_bts_type_variant str2btsvariant(const char *arg); +const char *btsvariant2str(enum gsm_bts_type_variant v); const struct value_string gsm_pchant_names[13]; const struct value_string gsm_pchant_descs[13]; diff --git a/openbsc/src/libbsc/bsc_vty.c b/openbsc/src/libbsc/bsc_vty.c index c1882fc..702af4a 100644 --- a/openbsc/src/libbsc/bsc_vty.c +++ b/openbsc/src/libbsc/bsc_vty.c @@ -1615,7 +1615,7 @@ struct gsm_bts *bts = vty->index; int rc; - rc = gsm_set_bts_type(bts, parse_btstype(argv[0])); + rc = gsm_set_bts_type(bts, str2btstype(argv[0])); if (rc < 0) return CMD_WARNING; diff --git a/openbsc/src/libcommon/gsm_data.c b/openbsc/src/libcommon/gsm_data.c index fd34793..8ec0be5 100644 --- a/openbsc/src/libcommon/gsm_data.c +++ b/openbsc/src/libcommon/gsm_data.c @@ -90,16 +90,6 @@ return NULL; } -const struct value_string bts_type_names[_NUM_GSM_BTS_TYPE+1] = { - { GSM_BTS_TYPE_UNKNOWN, "unknown" }, - { GSM_BTS_TYPE_BS11, "bs11" }, - { GSM_BTS_TYPE_NANOBTS, "nanobts" }, - { GSM_BTS_TYPE_RBS2000, "rbs2000" }, - { GSM_BTS_TYPE_NOKIA_SITE, "nokia_site" }, - { GSM_BTS_TYPE_OSMOBTS, "sysmobts" }, - { 0, NULL } -}; - const struct value_string bts_type_descs[_NUM_GSM_BTS_TYPE+1] = { { GSM_BTS_TYPE_UNKNOWN, "Unknown BTS Type" }, { GSM_BTS_TYPE_BS11, "Siemens BTS (BS-11 or compatible)" }, @@ -109,16 +99,6 @@ { GSM_BTS_TYPE_OSMOBTS, "sysmocom sysmoBTS" }, { 0, NULL } }; - -enum gsm_bts_type parse_btstype(const char *arg) -{ - return get_string_value(bts_type_names, arg); -} - -const char *btstype2str(enum gsm_bts_type type) -{ - return get_value_string(bts_type_names, type); -} struct gsm_bts_trx *gsm_bts_trx_by_nr(struct gsm_bts *bts, int nr) { diff --git a/openbsc/src/libcommon/gsm_data_shared.c b/openbsc/src/libcommon/gsm_data_shared.c index 387af70..73cb9f1 100644 --- a/openbsc/src/libcommon/gsm_data_shared.c +++ b/openbsc/src/libcommon/gsm_data_shared.c @@ -51,6 +51,61 @@ gsm_abis_mo_reset(mo); } +const struct value_string bts_attribute_names[] = { + OSMO_VALUE_STRING(BTS_TYPE_VARIANT), + OSMO_VALUE_STRING(BTS_SUB_MODEL), + { 0, NULL } +}; + +enum bts_attribute str2btsattr(const char *s) +{ + return get_string_value(bts_attribute_names, s); +} + +const char *btsatttr2str(enum bts_attribute v) +{ + return get_value_string(bts_attribute_names, v); +} + +const struct value_string bts_variant_names[_NUM_BTS_VARIANT + 1] = { + { BTS_UNKNOWN, "unknown" }, + { BTS_OSMO_LITECELL15, "Litecell15" }, + { BTS_OSMO_OCTPHY, "OctPHY" }, + { BTS_OSMO_SYSMO, "sysmoBTS" }, + { BTS_OSMO_TRX, "TRX" }, + { 0, NULL } +}; + +enum gsm_bts_type_variant str2btsvariant(const char *arg) +{ + return get_string_value(bts_variant_names, arg); +} + +const char *btsvariant2str(enum gsm_bts_type_variant v) +{ + return get_value_string(bts_variant_names, v); +} + +const struct value_string bts_type_names[_NUM_GSM_BTS_TYPE + 1] = { + { GSM_BTS_TYPE_UNKNOWN, "unknown" }, + { GSM_BTS_TYPE_BS11, "bs11" }, + { GSM_BTS_TYPE_NANOBTS, "nanobts" }, + { GSM_BTS_TYPE_RBS2000, "rbs2000" }, + { GSM_BTS_TYPE_NOKIA_SITE, "nokia_site" }, + { GSM_BTS_TYPE_OSMOBTS, "sysmobts" }, + { 0, NULL } +}; + +enum gsm_bts_type str2btstype(const char *arg) +{ + return get_string_value(bts_type_names, arg); +} + +const char *btstype2str(enum gsm_bts_type type) +{ + return get_value_string(bts_type_names, type); +} + const struct value_string gsm_pchant_names[13] = { { GSM_PCHAN_NONE, "NONE" }, { GSM_PCHAN_CCCH, "CCCH" }, -- To view, visit https://gerrit.osmocom.org/2286 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Ida94725a6fce968443541e3526f48f13758031fd Gerrit-PatchSet: 7 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Fri Apr 28 13:57:43 2017 From: gerrit-no-reply at lists.osmocom.org (Alexander Chemeris) Date: Fri, 28 Apr 2017 13:57:43 +0000 Subject: osmo-trx[master]: ssedetect: Add runtime CPU detection In-Reply-To: References: Message-ID: Patch Set 3: It was Sergey who you were discussing with. I'll ping him. -- To view, visit https://gerrit.osmocom.org/2100 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Iba74f8a6e4e921ff31e4bd9f0c7c881fe547423a Gerrit-PatchSet: 3 Gerrit-Project: osmo-trx Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Alexander Chemeris Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Vadim Yanitskiy Gerrit-Reviewer: dexter Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Apr 28 14:09:10 2017 From: gerrit-no-reply at lists.osmocom.org (jfdionne) Date: Fri, 28 Apr 2017 14:09:10 +0000 Subject: [PATCH] libosmocore[master]: Fix wrongful GSM codecs SID frame detection in DTX. In-Reply-To: References: Message-ID: Hello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2441 to look at the new patch set (#2). Fix wrongful GSM codecs SID frame detection in DTX. Based on ETSI TS 101 318 section 5.1.2 the 95 bits SID code word is not detected correctly due to a wrongful offset in the bits location indexes. Change-Id: I45d98c6edf267f313883503a65385190ffbc65ca --- M src/codec/gsm610.c 1 file changed, 10 insertions(+), 10 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/41/2441/2 diff --git a/src/codec/gsm610.c b/src/codec/gsm610.c index 47faea2..165484d 100644 --- a/src/codec/gsm610.c +++ b/src/codec/gsm610.c @@ -306,16 +306,16 @@ bool osmo_fr_check_sid(uint8_t *rtp_payload, size_t payload_len) { struct bitvec bv; - uint16_t i, z_bits[] = { 59, 60, 62, 63, 65, 66, 68, 69, 71, 72, 74, 75, - 77, 78, 80, 81, 83, 84, 86, 87, 89, 90, 92, 93, - 95, 96, 115, 116, 118, 119, 121, 122, 124, 125, - 127, 128, 130, 131, 133, 134, 136, 137, 139, - 140, 142, 143, 145, 146, 148, 149, 151, 152, - 171, 172, 174, 175, 177, 178, 180, 181, 183, - 184, 186, 187, 189, 190, 192, 193, 195, 196, - 198, 199, 201, 202, 204, 205, 207, 208, 227, - 228, 230, 231, 233, 234, 236, 237, 239, 242, - 245, 248, 251, 254, 257, 260, 263 }; + uint16_t i, z_bits[] = { 57, 58, 60, 61, 63, 64, 66, 67, 69, 70, 72, 73, + 75, 76, 78, 79, 81, 82, 84, 85, 87, 88, 90, 91, + 93, 94, 113, 114, 116, 117, 119, 120, 122, 123, + 125, 126, 128, 129, 131, 132, 134, 135, 137, + 138, 140, 141, 143, 144, 146, 147, 149, 150, + 169, 170, 172, 173, 175, 176, 178, 179, 181, + 182, 184, 185, 187, 188, 190, 191, 193, 194, + 196, 197, 199, 200, 202, 203, 205, 206, 225, + 226, 228, 229, 231, 232, 234, 235, 237, 240, + 243, 246, 249, 252, 255, 258, 261 }; /* signature does not match Full Rate SID */ if ((rtp_payload[0] >> 4) != 0xD) -- To view, visit https://gerrit.osmocom.org/2441 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I45d98c6edf267f313883503a65385190ffbc65ca Gerrit-PatchSet: 2 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: jfdionne Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Fri Apr 28 14:11:00 2017 From: gerrit-no-reply at lists.osmocom.org (Alexander Chemeris) Date: Fri, 28 Apr 2017 14:11:00 +0000 Subject: osmo-trx[master]: debian: remove obsolete dependency In-Reply-To: References: Message-ID: Patch Set 2: Max, please could you explain why is this required? What kind of build issues are you seeing? Would be nice to have at least a short version of this in the commit message with a potentially longer explanation in the comments here. -- To view, visit https://gerrit.osmocom.org/2400 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I3ea72b4123a280a846086d083c4f3189d611f8cf Gerrit-PatchSet: 2 Gerrit-Project: osmo-trx Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Alexander Chemeris Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Tom Tsou Gerrit-Reviewer: neels Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Fri Apr 28 14:14:18 2017 From: gerrit-no-reply at lists.osmocom.org (Pau Espin Pedrol) Date: Fri, 28 Apr 2017 14:14:18 +0000 Subject: [PATCH] osmo-gsm-tester[master]: Add remote user for RemoteProcress Message-ID: Review at https://gerrit.osmocom.org/2450 Add remote user for RemoteProcress Use it to set root user for SysmoBTS, otherwise if osmo-gsm-tester is run by another user it will fail to connect Change-Id: I67d4126fc75cb9c2d249c713cd6f14db1f1e21da --- M selftest/process_test.py M src/osmo_gsm_tester/bts_sysmo.py M src/osmo_gsm_tester/process.py 3 files changed, 8 insertions(+), 6 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-gsm-tester refs/changes/50/2450/1 diff --git a/selftest/process_test.py b/selftest/process_test.py index 9ad082b..71523c9 100755 --- a/selftest/process_test.py +++ b/selftest/process_test.py @@ -38,7 +38,7 @@ test_ssh = False if test_ssh: # this part of the test requires ability to ssh to localhost - p = process.RemoteProcess('localhost', '/tmp', 'ssh-test', tmpdir, + p = process.RemoteProcess('ssh-test', '/tmp', os.getenv('USER'), 'localhost', tmpdir, ('ls', '-al')) p.launch() p.wait() diff --git a/src/osmo_gsm_tester/bts_sysmo.py b/src/osmo_gsm_tester/bts_sysmo.py index dd396ff..0f93661 100644 --- a/src/osmo_gsm_tester/bts_sysmo.py +++ b/src/osmo_gsm_tester/bts_sysmo.py @@ -40,6 +40,7 @@ self.set_name('osmo-bts-sysmo') self.set_log_category(log.C_RUN) self.remote_env = {} + self.remote_user = 'root' def start(self): with self: @@ -62,14 +63,14 @@ self.run_remote('rm-remote-dir', ('test', '!', '-d', SysmoBts.REMOTE_DIR, '||', 'rm', '-rf', SysmoBts.REMOTE_DIR)) self.run_remote('mk-remote-dir', ('mkdir', '-p', SysmoBts.REMOTE_DIR)) self.run_local('scp-inst-to-sysmobts', - ('scp', '-r', str(self.inst), '%s:%s' % (self.remote_addr, str(self.remote_inst)))) + ('scp', '-r', str(self.inst), '%s@%s:%s' % (self.remote_user, self.remote_addr, str(self.remote_inst)))) remote_run_dir = self.remote_dir.child(SysmoBts.BTS_SYSMO_BIN) self.run_remote('mk-remote-run-dir', ('mkdir', '-p', remote_run_dir)) remote_config_file = self.remote_dir.child(SysmoBts.BTS_SYSMO_CFG) self.run_local('scp-cfg-to-sysmobts', - ('scp', '-r', self.config_file, '%s:%s' % (self.remote_addr, remote_config_file))) + ('scp', '-r', self.config_file, '%s@%s:%s' % (self.remote_user, self.remote_addr, remote_config_file))) remote_lib = self.remote_inst.child('lib') remote_binary = self.remote_inst.child('bin', 'osmo-bts-sysmo') @@ -80,7 +81,7 @@ def _process_remote(self, name, popen_args, remote_cwd=None): run_dir = self.run_dir.new_dir(name) - return process.RemoteProcess(name, run_dir, self.remote_addr, remote_cwd, + return process.RemoteProcess(name, run_dir, self.remote_user, self.remote_addr, remote_cwd, popen_args) def run_remote(self, name, popen_args, remote_cwd=None): diff --git a/src/osmo_gsm_tester/process.py b/src/osmo_gsm_tester/process.py index 78814c0..16f7905 100644 --- a/src/osmo_gsm_tester/process.py +++ b/src/osmo_gsm_tester/process.py @@ -210,8 +210,9 @@ class RemoteProcess(Process): - def __init__(self, name, run_dir, remote_host, remote_cwd, popen_args, **popen_kwargs): + def __init__(self, name, run_dir, remote_user, remote_host, remote_cwd, popen_args, **popen_kwargs): super().__init__(name, run_dir, popen_args, **popen_kwargs) + self.remote_user = remote_user self.remote_host = remote_host self.remote_cwd = remote_cwd @@ -222,7 +223,7 @@ cd = 'cd "%s"; ' % self.remote_cwd else: cd = '' - self.popen_args = ['ssh', self.remote_host, + self.popen_args = ['ssh', self.remote_user+'@'+self.remote_host, '%s%s' % (cd, ' '.join(self.popen_args))] self.dbg(self.popen_args, dir=self.run_dir, conf=self.popen_kwargs) -- To view, visit https://gerrit.osmocom.org/2450 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I67d4126fc75cb9c2d249c713cd6f14db1f1e21da Gerrit-PatchSet: 1 Gerrit-Project: osmo-gsm-tester Gerrit-Branch: master Gerrit-Owner: Pau Espin Pedrol From gerrit-no-reply at lists.osmocom.org Fri Apr 28 14:21:39 2017 From: gerrit-no-reply at lists.osmocom.org (jfdionne) Date: Fri, 28 Apr 2017 14:21:39 +0000 Subject: libosmocore[master]: Fix wrongful GSM codecs SID frame detection in DTX. In-Reply-To: References: Message-ID: Patch Set 2: Here are a couple valid SID samples: const uint8_t sid1[] = { d7, e0, a3, 61, 2c, 00, 00, 80, 49, 00, 00, 49, 00, 00, 80, 00, 04, 00, 00, 00, 00, 12, 40, 00, 10, 08, 00, 00, 00, 08, 2d, 04, 09 }; const uint8_t sid2[] = { d7, a2, bb, 65, e5, 00, 00, 10, 00, 04, 82, 00, 00, 00, 00, 49, 00, 02, 41, 00, 00, 00, 00, 20, 80, 01, 00, 00, 00, 42, 40, 10, d2 }; const uint8_t sid3[] = { d9, 60, ab, 21, ea, 00, 00, 80, 48, 20, 00, 09, 00, 00, 00, 00, 24, 80, 00, 00, 00, 10, 08, 00, 10, 08, 00, 00, 00, 00, 01, 00, 08 }; const uint8_t sid4[] = { d8, 21, ab, 25, ea, 00, 00, 00, 00, 04, 10, 00, 00, 00, 02, 41, 00, 02, 48, 00, 00, 00, 01, 20, 00, 00, 00, 00, 00, 42, 00, 02, 50 }; const uint8_t sid5[] = { d9, 61, 9a, 65, 60, 00, 00, 10, 00, 04, 02, 00, 00, 00, 02, 00, 00, 00, 40, 00, 00, 00, 00, 00, 80, 01, 00, 00, 00, 02, 40, 82, 52 }; const uint8_t sid6[] = { d9, a5, 93, e1, a0, 00, 00, 10, 00, 00, 02, 00, 00, 00, 02, 09, 00, 02, 40, 00, 00, 00, 01, 20, 80, 01, 00, 00, 90, 02, 40, 02, 02 }; const uint8_t sid7[] = { d8, 20, a3, e5, aa, 00, 00, 80, 00, 00, 00, 08, 00, 00, 80, 00, 04, 80, 00, 00, 00, 10, 08, 00, 12, 08, 00, 00, 00, 00, 08, 00, 09 }; const uint8_t sid8[] = { d7, e0, a3, a1, 60, 00, 00, 10, 00, 04, 92, 00, 00, 00, 00, 40, 00, 00, 40, 00, 00, 00, 01, 00, 00, 00, 00, 00, 12, 00, 40, 12, 00 }; const uint8_t sid9[] = { d8, 20, a3, a5, 62, 00, 00, 10, 00, 04, 82, 00, 00, 00, 02, 49, 00, 00, 00, 00, 00, 80, 00, 24, 00, 00, 00, 00, 10, 02, 00, 82, 02 }; const uint8_t sid10[] = { d4, aa, ba, 6e, bb, 00, 00, 00, 00, 00, 00, 40, 00, 00, 10, 00, 20, 90, 00, 00, 00, 00, 08, 00, 02, 08, 00, 00, 00, 08, 2c, 20, 00 }; const uint8_t sid11[] = { d9, 64, bb, 6d, 62, 00, 00, 80, 41, 00, 00, 48, 00, 00, 10, 00, 04, 90, 00, 00, 00, 00, 08, 00, 00, 00, 00, 00, 00, 00, 2c, 24, 01 }; const uint8_t sid12[] = { d8, 61, b2, a5, 62, 00, 00, 00, 41, 20, 00, 48, 00, 00, 10, 00, 04, 90, 00, 00, 00, 10, 08, 00, 10, 40, 00, 00, 00, 01, 29, 24, 08 }; const uint8_t sid13[] = { d9, 23, ba, e5, e2, 00, 00, 80, 41, 20, 00, 01, 00, 00, 10, 00, 04, 00, 00, 00, 00, 00, 48, 00, 00, 00, 00, 00, 00, 09, 05, 20, 00 }; const uint8_t sid14[] = { d8, 62, a2, 61, 60, 00, 00, 10, 00, 00, 92, 00, 00, 00, 00, 40, 00, 00, 08, 00, 00, 00, 01, 00, 00, 01, 00, 00, 80, 00, 40, 02, 40 }; const uint8_t sid15[] = { d9, e4, c3, 6d, 12, 00, 00, 80, 00, 20, 00, 40, 00, 00, 00, 00, 00, 10, 00, 00, 00, 10, 48, 00, 10, 48, 00, 00, 00, 00, 2d, 04, 00 }; const uint8_t sid16[] = { d9, a4, c3, 29, 59, 00, 00, 10, 00, 00, 12, 00, 00, 00, 00, 41, 00, 00, 01, 00, 00, 00, 01, 00, 80, 00, 00, 00, 00, 42, 00, 12, 02 }; -- To view, visit https://gerrit.osmocom.org/2441 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I45d98c6edf267f313883503a65385190ffbc65ca Gerrit-PatchSet: 2 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: jfdionne Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: jfdionne Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sat Apr 29 11:56:15 2017 From: gerrit-no-reply at lists.osmocom.org (Holger Freyther) Date: Sat, 29 Apr 2017 11:56:15 +0000 Subject: [MERGED] libosmo-netif[master]: misc: Call the variable ctx like in all other places In-Reply-To: References: Message-ID: Holger Freyther has submitted this change and it was merged. Change subject: misc: Call the variable ctx like in all other places ...................................................................... misc: Call the variable ctx like in all other places We couldn't figure out what "crx" as supposed to mean and assume it is a typo. Fix the code and call it ctx, this is fixing the API documentation as well. Change-Id: I27ed1178fdbbcf3fc0e1070dc19b4ecf9a327a04 --- M include/osmocom/netif/datagram.h M src/datagram.c 2 files changed, 11 insertions(+), 11 deletions(-) Approvals: Neels Hofmeyr: Looks good to me, approved Jenkins Builder: Verified diff --git a/include/osmocom/netif/datagram.h b/include/osmocom/netif/datagram.h index b7ecfe3..a0ff7b4 100644 --- a/include/osmocom/netif/datagram.h +++ b/include/osmocom/netif/datagram.h @@ -3,7 +3,7 @@ struct osmo_dgram_tx; -struct osmo_dgram_tx *osmo_dgram_tx_create(void *crx); +struct osmo_dgram_tx *osmo_dgram_tx_create(void *ctx); void osmo_dgram_tx_destroy(struct osmo_dgram_tx *conn); void osmo_dgram_tx_set_addr(struct osmo_dgram_tx *conn, const char *addr); @@ -19,7 +19,7 @@ struct osmo_dgram_rx; -struct osmo_dgram_rx *osmo_dgram_rx_create(void *crx); +struct osmo_dgram_rx *osmo_dgram_rx_create(void *ctx); void osmo_dgram_rx_set_addr(struct osmo_dgram_rx *conn, const char *addr); void osmo_dgram_rx_set_port(struct osmo_dgram_rx *conn, uint16_t port); @@ -33,7 +33,7 @@ struct osmo_dgram; -struct osmo_dgram *osmo_dgram_create(void *crx); +struct osmo_dgram *osmo_dgram_create(void *ctx); void osmo_dgram_destroy(struct osmo_dgram *conn); int osmo_dgram_open(struct osmo_dgram *conn); diff --git a/src/datagram.c b/src/datagram.c index d98221f..c2c84e0 100644 --- a/src/datagram.c +++ b/src/datagram.c @@ -102,11 +102,11 @@ * This function allocates a new \ref osmo_dgram_tx and initializes * it with default values * \returns Osmocom Datagram Transmitter; NULL on error */ -struct osmo_dgram_tx *osmo_dgram_tx_create(void *crx) +struct osmo_dgram_tx *osmo_dgram_tx_create(void *ctx) { struct osmo_dgram_tx *conn; - conn = talloc_zero(crx, struct osmo_dgram_tx); + conn = talloc_zero(ctx, struct osmo_dgram_tx); if (!conn) return NULL; @@ -276,11 +276,11 @@ * This function allocates a new \ref osmo_dgram_rx and initializes * it with default values * \returns Datagram Receiver; NULL on error */ -struct osmo_dgram_rx *osmo_dgram_rx_create(void *crx) +struct osmo_dgram_rx *osmo_dgram_rx_create(void *ctx) { struct osmo_dgram_rx *conn; - conn = talloc_zero(crx, struct osmo_dgram_rx); + conn = talloc_zero(ctx, struct osmo_dgram_rx); if (!conn) return NULL; @@ -398,22 +398,22 @@ * it with default values. Internally, the Transceiver is based on a * tuple of transmitter (\ref osmo_dgram_tx) and receiver (\ref osmo_dgram_rx) * \returns Osmocom Datagram Transceiver; NULL on error */ -struct osmo_dgram *osmo_dgram_create(void *crx) +struct osmo_dgram *osmo_dgram_create(void *ctx) { struct osmo_dgram *conn; - conn = talloc_zero(crx, struct osmo_dgram); + conn = talloc_zero(ctx, struct osmo_dgram); if (!conn) return NULL; - conn->rx= osmo_dgram_rx_create(crx); + conn->rx= osmo_dgram_rx_create(ctx); if (conn->rx == NULL) return NULL; osmo_dgram_rx_set_read_cb(conn->rx, dgram_rx_cb); conn->rx->data = conn; - conn->tx = osmo_dgram_tx_create(crx); + conn->tx = osmo_dgram_tx_create(ctx); if (conn->tx == NULL) { osmo_dgram_rx_destroy(conn->rx); return NULL; -- To view, visit https://gerrit.osmocom.org/2284 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I27ed1178fdbbcf3fc0e1070dc19b4ecf9a327a04 Gerrit-PatchSet: 3 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Holger Freyther Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Sat Apr 29 12:20:43 2017 From: gerrit-no-reply at lists.osmocom.org (Holger Freyther) Date: Sat, 29 Apr 2017 12:20:43 +0000 Subject: [PATCH] mncc-python[master]: mncc: Make it possible to build a MNCC server for testing Message-ID: Review at https://gerrit.osmocom.org/2451 mncc: Make it possible to build a MNCC server for testing For manual testing the osmo-sip-connector it is nice to run a custom MNCC server to mock certain behavior. Refactor the socket class to share code between client/server. Change-Id: I8387fe1687557c6a1a26ff1e0cc9dbff3087aa82 --- M mncc_sock.py 1 file changed, 32 insertions(+), 13 deletions(-) git pull ssh://gerrit.osmocom.org:29418/mncc-python refs/changes/51/2451/1 diff --git a/mncc_sock.py b/mncc_sock.py index 48da514..3d29691 100644 --- a/mncc_sock.py +++ b/mncc_sock.py @@ -52,21 +52,13 @@ plan = num_plan, present = num_present, screen = num_screen) -class MnccSocket(object): - def __init__(self, address = '/tmp/bsc_mncc'): - self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_SEQPACKET) - print 'connecting to %s' % address - try: - self.sock.connect(address) - except socket.error, errmsg: - print >>sys.stderr, errmsg - sys.exit(1) - - # FIXME: parse the HELLO message - msg = self.recv() - +class MnccSocketBase(object): def send(self, msg): return self.sock.sendall(msg.send()) + + def send_msg(self, msg): + data = buffer(msg)[:] + return self.sock.sendall(data) def recv(self): data = self.sock.recv(1500) @@ -76,3 +68,30 @@ ms = mncc_rtp_msg() ms.receive(data) return ms + +class MnccSocket(MnccSocketBase): + def __init__(self, address = '/tmp/bsc_mncc'): + super(MnccSocketBase, self).__init__() + self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_SEQPACKET) + print('connecting to %s' % address) + try: + self.sock.connect(address) + except socket.error as errmsg: + sys.stderr.write("%s\n" % errmsg) + sys.exit(1) + + # FIXME: parse the HELLO message + msg = self.recv() + +class MnccSocketServer(object): + def __init__(self, address = '/tmp/bsc_mncc'): + os.unlink(address) + self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_SEQPACKET) + self.sock.bind(address) + self.sock.listen(5) + + def accept(self): + (fd,_) = self.sock.accept() + sock = MnccSocketBase() + sock.sock = fd + return sock -- To view, visit https://gerrit.osmocom.org/2451 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I8387fe1687557c6a1a26ff1e0cc9dbff3087aa82 Gerrit-PatchSet: 1 Gerrit-Project: mncc-python Gerrit-Branch: master Gerrit-Owner: Holger Freyther From gerrit-no-reply at lists.osmocom.org Sat Apr 29 12:31:24 2017 From: gerrit-no-reply at lists.osmocom.org (Holger Freyther) Date: Sat, 29 Apr 2017 12:31:24 +0000 Subject: [ABANDON] osmo-sip-connector[master]: tests: Add copies of mncc.py/mncc_sock.py for (manual) tests In-Reply-To: References: Message-ID: Holger Freyther has abandoned this change. Change subject: tests: Add copies of mncc.py/mncc_sock.py for (manual) tests ...................................................................... Abandoned Let's put this into python-mncc directly. -- To view, visit https://gerrit.osmocom.org/1993 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: abandon Gerrit-Change-Id: I83a3ea8cd410a35f324caf9a01fae4cba44446f3 Gerrit-PatchSet: 3 Gerrit-Project: osmo-sip-connector Gerrit-Branch: master Gerrit-Owner: Holger Freyther Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max From gerrit-no-reply at lists.osmocom.org Sat Apr 29 12:31:57 2017 From: gerrit-no-reply at lists.osmocom.org (Holger Freyther) Date: Sat, 29 Apr 2017 12:31:57 +0000 Subject: [MERGED] osmo-bts[master]: sysmobts: Make reservation for mode/netmask/ip and suc In-Reply-To: References: Message-ID: Holger Freyther has submitted this change and it was merged. Change subject: sysmobts: Make reservation for mode/netmask/ip and suc ...................................................................... sysmobts: Make reservation for mode/netmask/ip and suc Change-Id: Ib98856356dc296be9e449d35479bc9234c0c4d32 --- M src/osmo-bts-sysmo/misc/sysmobts_eeprom.h M src/osmo-bts-sysmo/misc/sysmobts_par.c 2 files changed, 16 insertions(+), 1 deletion(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/src/osmo-bts-sysmo/misc/sysmobts_eeprom.h b/src/osmo-bts-sysmo/misc/sysmobts_eeprom.h index 0dec4f6..120d968 100644 --- a/src/osmo-bts-sysmo/misc/sysmobts_eeprom.h +++ b/src/osmo-bts-sysmo/misc/sysmobts_eeprom.h @@ -16,7 +16,15 @@ uint16_t model_flags; /* 34-35 */ uint8_t trx_nr; /* 36 */ uint8_t boot_state[48]; /* 37-84 */ - uint8_t _pad1[36]; /* 85-120 */ + uint8_t _pad1[18]; /* 85-102 */ + struct { + uint8_t mode; /* 103 */ + uint32_t ip; /* 104 - 107 */ + uint32_t mask; /* 108 - 111 */ + uint32_t gw; /* 112 - 115 */ + uint32_t dns; /* 116 - 119 */ + } __attribute__((packed)) net_cfg; + uint8_t crc; /* 120 */ uint8_t gpg_key[128]; /* 121-249 */ } __attribute__((packed)); @@ -26,4 +34,9 @@ MODEL_SYSMOBTS_2050 = 2050, }; +enum sysmobts_net_mode { + NET_MODE_DHCP, + NET_MODE_STATIC, +}; + #endif diff --git a/src/osmo-bts-sysmo/misc/sysmobts_par.c b/src/osmo-bts-sysmo/misc/sysmobts_par.c index d1fc37a..e3a3c56 100644 --- a/src/osmo-bts-sysmo/misc/sysmobts_par.c +++ b/src/osmo-bts-sysmo/misc/sysmobts_par.c @@ -294,4 +294,6 @@ osmo_static_assert(offsetof(struct sysmobts_eeprom, trx_nr) == 36, offset_36); osmo_static_assert(offsetof(struct sysmobts_eeprom, boot_state) == 37, offset_37); osmo_static_assert(offsetof(struct sysmobts_eeprom, _pad1) == 85, offset_85); +osmo_static_assert(offsetof(struct sysmobts_eeprom, net_cfg.mode) == 103, offset_103); +osmo_static_assert((offsetof(struct sysmobts_eeprom, net_cfg.ip) & 0x3) == 0, ip_32bit_aligned); osmo_static_assert(offsetof(struct sysmobts_eeprom, gpg_key) == 121, offset_121); -- To view, visit https://gerrit.osmocom.org/449 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ib98856356dc296be9e449d35479bc9234c0c4d32 Gerrit-PatchSet: 2 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Holger Freyther Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sat Apr 29 13:15:13 2017 From: gerrit-no-reply at lists.osmocom.org (Holger Freyther) Date: Sat, 29 Apr 2017 13:15:13 +0000 Subject: [PATCH] mncc-python[master]: test: Add a manual test to simulate DTMF handling in osmo-si... Message-ID: Review at https://gerrit.osmocom.org/2452 test: Add a manual test to simulate DTMF handling in osmo-sip-connector Add a manul test to the contrib folder that helped and can help during the development of osmo-sip-connector or similar software. This avoids having to create a separate mncc module. It can be started like: $ PYTHONPATH=$PWD/../ python manual_test_server.py Change-Id: I7f62efbc62455e6fcb1f091afb5fa120099834f0 --- A contrib/manual_test_server.py 1 file changed, 126 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/mncc-python refs/changes/52/2452/1 diff --git a/contrib/manual_test_server.py b/contrib/manual_test_server.py new file mode 100644 index 0000000..5625670 --- /dev/null +++ b/contrib/manual_test_server.py @@ -0,0 +1,126 @@ +import mncc +import mncc_sock +import ctypes +import socket + +GSM340_PLAN_ISDN = 1 +GSM340_TYPE_NATIONAL = 2 + +class MnccMessageBuilder(object): + """ + I help in creating messages... + """ + @staticmethod + def build_hello(): + hello = mncc.gsm_mncc_hello() + hello.msg_type = mncc.MNCC_SOCKET_HELLO + hello.version = mncc.MNCC_SOCK_VERSION + hello.mncc_size = ctypes.sizeof(mncc.gsm_mncc) + hello.data_frame_size = ctypes.sizeof(mncc.gsm_data_frame) + hello.called_offset = mncc.gsm_mncc.called.offset + hello.signal_offset = mncc.gsm_mncc.signal.offset + hello.emergency_offset = mncc.gsm_mncc.emergency.offset + hello.lchan_type_offset = mncc.gsm_mncc.lchan_type.offset + return hello + + @staticmethod + def build_mncc_number(number): + return mncc.gsm_mncc_number( + type=GSM340_TYPE_NATIONAL, + plan=GSM340_PLAN_ISDN, + number=number) + + @staticmethod + def build_setup_ind(calling, called, callref=1): + setup = mncc.gsm_mncc() + setup.msg_type = mncc.MNCC_SETUP_IND + setup.callref = callref + setup.fields = mncc.MNCC_F_CALLED | mncc.MNCC_F_CALLING + setup.called = MnccMessageBuilder.build_mncc_number(called) + setup.calling = MnccMessageBuilder.build_mncc_number(calling) + return setup + + @staticmethod + def build_setup_cmpl_ind(callref=1): + setup = mncc.gsm_mncc() + setup.msg_type = mncc.MNCC_SETUP_COMPL_IND + setup.callref = callref + return setup + + @staticmethod + def build_rtp_msg(msg_type, callref, addr, port): + return mncc.gsm_mncc_rtp( + msg_type=msg_type, callref=callref, + ip=addr, port=port, + #payload_type=3, + #payload_msg_type=mncc.GSM_TCHF_FRAME) + payload_type=98, + payload_msg_type=mncc.GSM_TCH_FRAME_AMR) + + @staticmethod + def build_dtmf_start(callref, data): + return mncc.gsm_mncc( + msg_type=mncc.MNCC_START_DTMF_IND, + callref=callref, + fields=mncc.MNCC_F_KEYPAD, + keypad=ord(data)) + + @staticmethod + def build_dtmf_stop(callref, data): + return mncc.gsm_mncc( + callref=callref, + msg_type=mncc.MNCC_STOP_DTMF_IND) + +def send_dtmf(callref): + global conn + + conn.send_msg(MnccMessageBuilder.build_dtmf_start(callref, '1')) + conn.send_msg(MnccMessageBuilder.build_dtmf_stop(callref, '1')) + conn.send_msg(MnccMessageBuilder.build_dtmf_start(callref, '2')) + conn.send_msg(MnccMessageBuilder.build_dtmf_stop(callref, '2')) + + +server = mncc_sock.MnccSocketServer() +conn = server.accept() + +# Say hello and set-up a call +conn.send_msg(MnccMessageBuilder.build_hello()) +conn.send_msg(MnccMessageBuilder.build_setup_ind("1234", "5000")) +print("=> Sent hello + setup indication") + +# Wait for the RTP crate.. and actknowledge it.. +msg = conn.recv() +assert msg.msg_type == mncc.MNCC_RTP_CREATE +print("<= Received request to create a RTP socket") +conn.send_msg(MnccMessageBuilder.build_rtp_msg(mncc.MNCC_RTP_CREATE, + msg.callref, + #socket.INADDR_LOOPBACK, 4000)) + socket.INADDR_ANY, 4000)) +print("=> Claimed socket was created...") + +msg = conn.recv() +assert msg.msg_type == mncc.MNCC_CALL_PROC_REQ +print("<= Received proceeding...") + + + +while True: + msg = conn.recv() + if msg.msg_type == mncc.MNCC_ALERT_REQ: + print("=> I should alert...") + continue + if msg.msg_type == mncc.MNCC_RTP_CONNECT: + conn.send_msg(MnccMessageBuilder.build_rtp_msg(mncc.MNCC_RTP_CONNECT, + msg.callref, + socket.INADDR_LOOPBACK, 4000)) + print("=> I needed to connect RTP...") + continue + if msg.msg_type == mncc.MNCC_SETUP_RSP: + print("=> Call is connected?") + conn.send_msg(MnccMessageBuilder.build_setup_cmpl_ind(msg.callref)) + send_dtmf(msg.callref) + continue + + print(msg) + print(msg.msg_type) +print(type(msg)) -- To view, visit https://gerrit.osmocom.org/2452 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I7f62efbc62455e6fcb1f091afb5fa120099834f0 Gerrit-PatchSet: 1 Gerrit-Project: mncc-python Gerrit-Branch: master Gerrit-Owner: Holger Freyther From gerrit-no-reply at lists.osmocom.org Sat Apr 29 13:17:32 2017 From: gerrit-no-reply at lists.osmocom.org (Holger Freyther) Date: Sat, 29 Apr 2017 13:17:32 +0000 Subject: mncc-python[master]: test: Add a manual test to simulate DTMF handling in osmo-si... In-Reply-To: References: Message-ID: Patch Set 1: I think instead of making mncc.py a proper module, let us start putting the manual test in there. It is not that there will be much development here. -- To view, visit https://gerrit.osmocom.org/2452 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I7f62efbc62455e6fcb1f091afb5fa120099834f0 Gerrit-PatchSet: 1 Gerrit-Project: mncc-python Gerrit-Branch: master Gerrit-Owner: Holger Freyther Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sat Apr 29 13:18:02 2017 From: gerrit-no-reply at lists.osmocom.org (Holger Freyther) Date: Sat, 29 Apr 2017 13:18:02 +0000 Subject: [ABANDON] osmo-sip-connector[master]: tests: Add a basic test to open a single call and send DTMF In-Reply-To: References: Message-ID: Holger Freyther has abandoned this change. Change subject: tests: Add a basic test to open a single call and send DTMF ...................................................................... Abandoned Replaced by I7f62efbc62455e6fcb1f091afb5fa120099834f0 in the mncc-python project -- To view, visit https://gerrit.osmocom.org/1994 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: abandon Gerrit-Change-Id: Iec65a3490dd2a6c91f0a573aea482f3d113b0c6a Gerrit-PatchSet: 3 Gerrit-Project: osmo-sip-connector Gerrit-Branch: master Gerrit-Owner: Holger Freyther Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sat Apr 29 13:19:23 2017 From: gerrit-no-reply at lists.osmocom.org (Holger Freyther) Date: Sat, 29 Apr 2017 13:19:23 +0000 Subject: osmo-sip-connector[master]: evpoll: Implement poll with ppoll and map select to poll.. In-Reply-To: References: Message-ID: Patch Set 2: Shall we discard this implement select with ppoll changeset as we are reporting the error condition unconditionally now? -- To view, visit https://gerrit.osmocom.org/1987 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I12d3af23315d762a8fcd83255647a3df6aff7166 Gerrit-PatchSet: 2 Gerrit-Project: osmo-sip-connector Gerrit-Branch: master Gerrit-Owner: Holger Freyther Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sat Apr 29 19:53:30 2017 From: gerrit-no-reply at lists.osmocom.org (Vadim Yanitskiy) Date: Sat, 29 Apr 2017 19:53:30 +0000 Subject: [PATCH] libosmocore[master]: tests/conv: add GSM 05.03 specific test In-Reply-To: References: Message-ID: Hello Max, Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/1628 to look at the new patch set (#6). tests/conv: add GSM 05.03 specific test This change extends the convolutional code test coverage, adding the GSM 05.03 specific test vectors, generated by the conv_gen.py. Inspired by Tom's patch: http://lists.osmocom.org/pipermail/openbsc/2014-April/007364.html Change-Id: I76d1cd4032d2f74c5bb93bde4fab99aa655b7f1a --- M .gitignore M tests/Makefile.am M tests/conv/conv.h A tests/conv/conv_gsm0503_test.c A tests/conv/conv_gsm0503_test.ok M tests/testsuite.at 6 files changed, 355 insertions(+), 5 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/28/1628/6 diff --git a/.gitignore b/.gitignore index 4c6a78f..5111b25 100644 --- a/.gitignore +++ b/.gitignore @@ -122,6 +122,7 @@ include/osmocom/core/crc*gen.h include/osmocom/core/bit*gen.h include/osmocom/gsm/gsm0503.h +tests/conv/gsm0503_test_vectors.c # vi files *.sw? diff --git a/tests/Makefile.am b/tests/Makefile.am index 3ce7620..ce7e0cb 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -15,7 +15,8 @@ bitvec/bitvec_test msgb/msgb_test bits/bitcomp_test \ tlv/tlv_test gsup/gsup_test oap/oap_test fsm/fsm_test \ write_queue/wqueue_test socket/socket_test \ - coding/coding_test abis/abis_test + coding/coding_test conv/conv_gsm0503_test \ + abis/abis_test if ENABLE_MSGFILE check_PROGRAMS += msgfile/msgfile_test @@ -63,6 +64,10 @@ conv_conv_test_SOURCES = conv/conv_test.c conv/conv.c conv_conv_test_LDADD = $(top_builddir)/src/libosmocore.la $(top_builddir)/src/gsm/libgsmint.la + +conv_conv_gsm0503_test_SOURCES = conv/conv_gsm0503_test.c conv/conv.c conv/gsm0503_test_vectors.c +conv_conv_gsm0503_test_LDADD = $(top_builddir)/src/libosmocore.la $(top_builddir)/src/gsm/libgsmint.la +conv_conv_gsm0503_test_CPPFLAGS = -I$(top_srcdir)/tests/conv gsm0808_gsm0808_test_SOURCES = gsm0808/gsm0808_test.c gsm0808_gsm0808_test_LDADD = $(top_builddir)/src/libosmocore.la $(top_builddir)/src/gsm/libosmogsm.la @@ -198,9 +203,11 @@ socket/socket_test.err coding/coding_test.ok \ osmo-auc-gen/osmo-auc-gen_test.sh \ osmo-auc-gen/osmo-auc-gen_test.ok \ - osmo-auc-gen/osmo-auc-gen_test.err + osmo-auc-gen/osmo-auc-gen_test.err \ + conv/conv_gsm0503_test.ok -DISTCLEANFILES = atconfig atlocal +DISTCLEANFILES = atconfig atlocal conv/gsm0503_test_vectors.c +BUILT_SOURCES = conv/gsm0503_test_vectors.c noinst_HEADERS = conv/conv.h TESTSUITE = $(srcdir)/testsuite @@ -221,3 +228,7 @@ $(TESTSUITE): $(srcdir)/testsuite.at $(srcdir)/package.m4 $(AUTOTEST) -I '$(srcdir)' -o $@.tmp $@.at mv $@.tmp $@ + +conv/gsm0503_test_vectors.c: $(top_srcdir)/utils/conv_gen.py $(top_srcdir)/utils/conv_codes_gsm.py + $(AM_V_GEN)python2 $(top_srcdir)/utils/conv_gen.py gen_vectors gsm \ + --target-path $(builddir)/conv diff --git a/tests/conv/conv.h b/tests/conv/conv.h index 676c5af..0604859 100644 --- a/tests/conv/conv.h +++ b/tests/conv/conv.h @@ -1,7 +1,7 @@ #pragma once -#define MAX_LEN_BITS 512 -#define MAX_LEN_BYTES (512/8) +#define MAX_LEN_BITS 2048 +#define MAX_LEN_BYTES (2048 / 8) struct conv_test_vector { const char *name; diff --git a/tests/conv/conv_gsm0503_test.c b/tests/conv/conv_gsm0503_test.c new file mode 100644 index 0000000..6704129 --- /dev/null +++ b/tests/conv/conv_gsm0503_test.c @@ -0,0 +1,28 @@ +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "conv.h" + +/* Forward declaration of GSM 05.03 specific test vectors */ +extern const struct conv_test_vector gsm0503_vectors[]; +extern const int gsm0503_vectors_len; + +int main(int argc, char *argv[]) +{ + int rc, i; + + for (i = 0; i < gsm0503_vectors_len; i++) { + rc = do_check(&gsm0503_vectors[i]); + if (rc) + return rc; + } + + return 0; +} diff --git a/tests/conv/conv_gsm0503_test.ok b/tests/conv/conv_gsm0503_test.ok new file mode 100644 index 0000000..e6e2572 --- /dev/null +++ b/tests/conv/conv_gsm0503_test.ok @@ -0,0 +1,304 @@ +[+] Testing: gsm0503_xcch +[.] Input length : ret = 224 exp = 224 -> OK +[.] Output length : ret = 456 exp = 456 -> OK +[.] Random vector checks: +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK + +[+] Testing: gsm0503_rach +[.] Input length : ret = 14 exp = 14 -> OK +[.] Output length : ret = 36 exp = 36 -> OK +[.] Random vector checks: +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK + +[+] Testing: gsm0503_sch +[.] Input length : ret = 35 exp = 35 -> OK +[.] Output length : ret = 78 exp = 78 -> OK +[.] Random vector checks: +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK + +[+] Testing: gsm0503_cs2 +[.] Input length : ret = 290 exp = 290 -> OK +[.] Output length : ret = 456 exp = 456 -> OK +[.] Random vector checks: +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK + +[+] Testing: gsm0503_cs3 +[.] Input length : ret = 334 exp = 334 -> OK +[.] Output length : ret = 456 exp = 456 -> OK +[.] Random vector checks: +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK + +[+] Testing: gsm0503_cs2_np +[.] Input length : ret = 290 exp = 290 -> OK +[.] Output length : ret = 588 exp = 588 -> OK +[.] Random vector checks: +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK + +[+] Testing: gsm0503_cs3_np +[.] Input length : ret = 334 exp = 334 -> OK +[.] Output length : ret = 676 exp = 676 -> OK +[.] Random vector checks: +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK + +[+] Testing: gsm0503_tch_afs_12_2 +[.] Input length : ret = 250 exp = 250 -> OK +[.] Output length : ret = 448 exp = 448 -> OK +[.] Random vector checks: +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK + +[+] Testing: gsm0503_tch_afs_10_2 +[.] Input length : ret = 210 exp = 210 -> OK +[.] Output length : ret = 448 exp = 448 -> OK +[.] Random vector checks: +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK + +[+] Testing: gsm0503_tch_afs_7_95 +[.] Input length : ret = 165 exp = 165 -> OK +[.] Output length : ret = 448 exp = 448 -> OK +[.] Random vector checks: +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK + +[+] Testing: gsm0503_tch_afs_7_4 +[.] Input length : ret = 154 exp = 154 -> OK +[.] Output length : ret = 448 exp = 448 -> OK +[.] Random vector checks: +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK + +[+] Testing: gsm0503_tch_afs_6_7 +[.] Input length : ret = 140 exp = 140 -> OK +[.] Output length : ret = 448 exp = 448 -> OK +[.] Random vector checks: +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK + +[+] Testing: gsm0503_tch_afs_5_9 +[.] Input length : ret = 124 exp = 124 -> OK +[.] Output length : ret = 448 exp = 448 -> OK +[.] Random vector checks: +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK + +[+] Testing: gsm0503_tch_afs_5_15 +[.] Input length : ret = 109 exp = 109 -> OK +[.] Output length : ret = 448 exp = 448 -> OK +[.] Random vector checks: +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK + +[+] Testing: gsm0503_tch_afs_4_75 +[.] Input length : ret = 101 exp = 101 -> OK +[.] Output length : ret = 448 exp = 448 -> OK +[.] Random vector checks: +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK + +[+] Testing: gsm0503_tch_fr +[.] Input length : ret = 185 exp = 185 -> OK +[.] Output length : ret = 378 exp = 378 -> OK +[.] Random vector checks: +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK + +[+] Testing: gsm0503_tch_hr +[.] Input length : ret = 98 exp = 98 -> OK +[.] Output length : ret = 211 exp = 211 -> OK +[.] Random vector checks: +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK + +[+] Testing: gsm0503_tch_ahs_7_95 +[.] Input length : ret = 129 exp = 129 -> OK +[.] Output length : ret = 188 exp = 188 -> OK +[.] Random vector checks: +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK + +[+] Testing: gsm0503_tch_ahs_7_4 +[.] Input length : ret = 126 exp = 126 -> OK +[.] Output length : ret = 196 exp = 196 -> OK +[.] Random vector checks: +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK + +[+] Testing: gsm0503_tch_ahs_6_7 +[.] Input length : ret = 116 exp = 116 -> OK +[.] Output length : ret = 200 exp = 200 -> OK +[.] Random vector checks: +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK + +[+] Testing: gsm0503_tch_ahs_5_9 +[.] Input length : ret = 108 exp = 108 -> OK +[.] Output length : ret = 208 exp = 208 -> OK +[.] Random vector checks: +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK + +[+] Testing: gsm0503_tch_ahs_5_15 +[.] Input length : ret = 97 exp = 97 -> OK +[.] Output length : ret = 212 exp = 212 -> OK +[.] Random vector checks: +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK + +[+] Testing: gsm0503_tch_ahs_4_75 +[.] Input length : ret = 89 exp = 89 -> OK +[.] Output length : ret = 212 exp = 212 -> OK +[.] Random vector checks: +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK + +[+] Testing: gsm0503_mcs1_dl_hdr +[.] Input length : ret = 36 exp = 36 -> OK +[.] Output length : ret = 108 exp = 108 -> OK +[.] Random vector checks: +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK + +[+] Testing: gsm0503_mcs1_ul_hdr +[.] Input length : ret = 39 exp = 39 -> OK +[.] Output length : ret = 117 exp = 117 -> OK +[.] Random vector checks: +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK + +[+] Testing: gsm0503_mcs1 +[.] Input length : ret = 190 exp = 190 -> OK +[.] Output length : ret = 588 exp = 588 -> OK +[.] Random vector checks: +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK + +[+] Testing: gsm0503_mcs2 +[.] Input length : ret = 238 exp = 238 -> OK +[.] Output length : ret = 732 exp = 732 -> OK +[.] Random vector checks: +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK + +[+] Testing: gsm0503_mcs3 +[.] Input length : ret = 310 exp = 310 -> OK +[.] Output length : ret = 948 exp = 948 -> OK +[.] Random vector checks: +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK + +[+] Testing: gsm0503_mcs4 +[.] Input length : ret = 366 exp = 366 -> OK +[.] Output length : ret = 1116 exp = 1116 -> OK +[.] Random vector checks: +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK + +[+] Testing: gsm0503_mcs5_dl_hdr +[.] Input length : ret = 33 exp = 33 -> OK +[.] Output length : ret = 99 exp = 99 -> OK +[.] Random vector checks: +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK + +[+] Testing: gsm0503_mcs5_ul_hdr +[.] Input length : ret = 45 exp = 45 -> OK +[.] Output length : ret = 135 exp = 135 -> OK +[.] Random vector checks: +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK + +[+] Testing: gsm0503_mcs5 +[.] Input length : ret = 462 exp = 462 -> OK +[.] Output length : ret = 1404 exp = 1404 -> OK +[.] Random vector checks: +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK + +[+] Testing: gsm0503_mcs6 +[.] Input length : ret = 606 exp = 606 -> OK +[.] Output length : ret = 1836 exp = 1836 -> OK +[.] Random vector checks: +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK + +[+] Testing: gsm0503_mcs7_dl_hdr +[.] Input length : ret = 45 exp = 45 -> OK +[.] Output length : ret = 135 exp = 135 -> OK +[.] Random vector checks: +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK + +[+] Testing: gsm0503_mcs7_ul_hdr +[.] Input length : ret = 54 exp = 54 -> OK +[.] Output length : ret = 162 exp = 162 -> OK +[.] Random vector checks: +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK + +[+] Testing: gsm0503_mcs7 +[.] Input length : ret = 462 exp = 462 -> OK +[.] Output length : ret = 1404 exp = 1404 -> OK +[.] Random vector checks: +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK + +[+] Testing: gsm0503_mcs8 +[.] Input length : ret = 558 exp = 558 -> OK +[.] Output length : ret = 1692 exp = 1692 -> OK +[.] Random vector checks: +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK + +[+] Testing: gsm0503_mcs9 +[.] Input length : ret = 606 exp = 606 -> OK +[.] Output length : ret = 1836 exp = 1836 -> OK +[.] Random vector checks: +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK + diff --git a/tests/testsuite.at b/tests/testsuite.at index 7ee0164..2f9cfe7 100644 --- a/tests/testsuite.at +++ b/tests/testsuite.at @@ -51,6 +51,12 @@ AT_CHECK([$abs_top_builddir/tests/conv/conv_test], [0], [expout]) AT_CLEANUP +AT_SETUP([conv_gsm0503]) +AT_KEYWORDS([conv_gsm0503]) +cat $abs_srcdir/conv/conv_gsm0503_test.ok > expout +AT_CHECK([$abs_top_builddir/tests/conv/conv_gsm0503_test], [0], [expout]) +AT_CLEANUP + AT_SETUP([coding]) AT_KEYWORDS([coding]) cat $abs_srcdir/coding/coding_test.ok > expout -- To view, visit https://gerrit.osmocom.org/1628 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I76d1cd4032d2f74c5bb93bde4fab99aa655b7f1a Gerrit-PatchSet: 6 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Vadim Yanitskiy Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: Tom Tsou Gerrit-Reviewer: Vadim Yanitskiy Gerrit-Reviewer: tnt From gerrit-no-reply at lists.osmocom.org Sat Apr 29 19:54:16 2017 From: gerrit-no-reply at lists.osmocom.org (Vadim Yanitskiy) Date: Sat, 29 Apr 2017 19:54:16 +0000 Subject: [ABANDON] libosmocore[master]: tests/conv: move conv.h to the global include dir In-Reply-To: References: Message-ID: Vadim Yanitskiy has abandoned this change. Change subject: tests/conv: move conv.h to the global include dir ...................................................................... Abandoned -- To view, visit https://gerrit.osmocom.org/2075 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: abandon Gerrit-Change-Id: I414223f3d9382642fc4f7efb3b35dc950eaaad86 Gerrit-PatchSet: 2 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Vadim Yanitskiy Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: Tom Tsou Gerrit-Reviewer: Vadim Yanitskiy Gerrit-Reviewer: tnt From gerrit-no-reply at lists.osmocom.org Sat Apr 29 19:59:55 2017 From: gerrit-no-reply at lists.osmocom.org (Vadim Yanitskiy) Date: Sat, 29 Apr 2017 19:59:55 +0000 Subject: [PATCH] libosmocore[master]: tests/conv: add GSM 05.03 specific test In-Reply-To: References: Message-ID: Hello Max, Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/1628 to look at the new patch set (#7). tests/conv: add GSM 05.03 specific test This change extends the convolutional code test coverage, adding the GSM 05.03 specific test vectors, generated by the conv_gen.py. Inspired by Tom's patch: http://lists.osmocom.org/pipermail/openbsc/2014-April/007364.html Change-Id: I76d1cd4032d2f74c5bb93bde4fab99aa655b7f1a --- M .gitignore M tests/Makefile.am M tests/conv/conv.h A tests/conv/conv_gsm0503_test.c A tests/conv/conv_gsm0503_test.ok M tests/testsuite.at 6 files changed, 355 insertions(+), 5 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/28/1628/7 diff --git a/.gitignore b/.gitignore index 4c6a78f..5111b25 100644 --- a/.gitignore +++ b/.gitignore @@ -122,6 +122,7 @@ include/osmocom/core/crc*gen.h include/osmocom/core/bit*gen.h include/osmocom/gsm/gsm0503.h +tests/conv/gsm0503_test_vectors.c # vi files *.sw? diff --git a/tests/Makefile.am b/tests/Makefile.am index 3ce7620..d9816ef 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -15,7 +15,8 @@ bitvec/bitvec_test msgb/msgb_test bits/bitcomp_test \ tlv/tlv_test gsup/gsup_test oap/oap_test fsm/fsm_test \ write_queue/wqueue_test socket/socket_test \ - coding/coding_test abis/abis_test + coding/coding_test conv/conv_gsm0503_test \ + abis/abis_test if ENABLE_MSGFILE check_PROGRAMS += msgfile/msgfile_test @@ -63,6 +64,10 @@ conv_conv_test_SOURCES = conv/conv_test.c conv/conv.c conv_conv_test_LDADD = $(top_builddir)/src/libosmocore.la $(top_builddir)/src/gsm/libgsmint.la + +conv_conv_gsm0503_test_SOURCES = conv/conv_gsm0503_test.c conv/conv.c conv/gsm0503_test_vectors.c +conv_conv_gsm0503_test_LDADD = $(top_builddir)/src/libosmocore.la $(top_builddir)/src/gsm/libgsmint.la +conv_conv_gsm0503_test_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_srcdir)/tests/conv gsm0808_gsm0808_test_SOURCES = gsm0808/gsm0808_test.c gsm0808_gsm0808_test_LDADD = $(top_builddir)/src/libosmocore.la $(top_builddir)/src/gsm/libosmogsm.la @@ -198,9 +203,11 @@ socket/socket_test.err coding/coding_test.ok \ osmo-auc-gen/osmo-auc-gen_test.sh \ osmo-auc-gen/osmo-auc-gen_test.ok \ - osmo-auc-gen/osmo-auc-gen_test.err + osmo-auc-gen/osmo-auc-gen_test.err \ + conv/conv_gsm0503_test.ok -DISTCLEANFILES = atconfig atlocal +DISTCLEANFILES = atconfig atlocal conv/gsm0503_test_vectors.c +BUILT_SOURCES = conv/gsm0503_test_vectors.c noinst_HEADERS = conv/conv.h TESTSUITE = $(srcdir)/testsuite @@ -221,3 +228,7 @@ $(TESTSUITE): $(srcdir)/testsuite.at $(srcdir)/package.m4 $(AUTOTEST) -I '$(srcdir)' -o $@.tmp $@.at mv $@.tmp $@ + +conv/gsm0503_test_vectors.c: $(top_srcdir)/utils/conv_gen.py $(top_srcdir)/utils/conv_codes_gsm.py + $(AM_V_GEN)python2 $(top_srcdir)/utils/conv_gen.py gen_vectors gsm \ + --target-path $(builddir)/conv diff --git a/tests/conv/conv.h b/tests/conv/conv.h index 676c5af..0604859 100644 --- a/tests/conv/conv.h +++ b/tests/conv/conv.h @@ -1,7 +1,7 @@ #pragma once -#define MAX_LEN_BITS 512 -#define MAX_LEN_BYTES (512/8) +#define MAX_LEN_BITS 2048 +#define MAX_LEN_BYTES (2048 / 8) struct conv_test_vector { const char *name; diff --git a/tests/conv/conv_gsm0503_test.c b/tests/conv/conv_gsm0503_test.c new file mode 100644 index 0000000..6704129 --- /dev/null +++ b/tests/conv/conv_gsm0503_test.c @@ -0,0 +1,28 @@ +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "conv.h" + +/* Forward declaration of GSM 05.03 specific test vectors */ +extern const struct conv_test_vector gsm0503_vectors[]; +extern const int gsm0503_vectors_len; + +int main(int argc, char *argv[]) +{ + int rc, i; + + for (i = 0; i < gsm0503_vectors_len; i++) { + rc = do_check(&gsm0503_vectors[i]); + if (rc) + return rc; + } + + return 0; +} diff --git a/tests/conv/conv_gsm0503_test.ok b/tests/conv/conv_gsm0503_test.ok new file mode 100644 index 0000000..e6e2572 --- /dev/null +++ b/tests/conv/conv_gsm0503_test.ok @@ -0,0 +1,304 @@ +[+] Testing: gsm0503_xcch +[.] Input length : ret = 224 exp = 224 -> OK +[.] Output length : ret = 456 exp = 456 -> OK +[.] Random vector checks: +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK + +[+] Testing: gsm0503_rach +[.] Input length : ret = 14 exp = 14 -> OK +[.] Output length : ret = 36 exp = 36 -> OK +[.] Random vector checks: +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK + +[+] Testing: gsm0503_sch +[.] Input length : ret = 35 exp = 35 -> OK +[.] Output length : ret = 78 exp = 78 -> OK +[.] Random vector checks: +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK + +[+] Testing: gsm0503_cs2 +[.] Input length : ret = 290 exp = 290 -> OK +[.] Output length : ret = 456 exp = 456 -> OK +[.] Random vector checks: +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK + +[+] Testing: gsm0503_cs3 +[.] Input length : ret = 334 exp = 334 -> OK +[.] Output length : ret = 456 exp = 456 -> OK +[.] Random vector checks: +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK + +[+] Testing: gsm0503_cs2_np +[.] Input length : ret = 290 exp = 290 -> OK +[.] Output length : ret = 588 exp = 588 -> OK +[.] Random vector checks: +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK + +[+] Testing: gsm0503_cs3_np +[.] Input length : ret = 334 exp = 334 -> OK +[.] Output length : ret = 676 exp = 676 -> OK +[.] Random vector checks: +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK + +[+] Testing: gsm0503_tch_afs_12_2 +[.] Input length : ret = 250 exp = 250 -> OK +[.] Output length : ret = 448 exp = 448 -> OK +[.] Random vector checks: +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK + +[+] Testing: gsm0503_tch_afs_10_2 +[.] Input length : ret = 210 exp = 210 -> OK +[.] Output length : ret = 448 exp = 448 -> OK +[.] Random vector checks: +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK + +[+] Testing: gsm0503_tch_afs_7_95 +[.] Input length : ret = 165 exp = 165 -> OK +[.] Output length : ret = 448 exp = 448 -> OK +[.] Random vector checks: +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK + +[+] Testing: gsm0503_tch_afs_7_4 +[.] Input length : ret = 154 exp = 154 -> OK +[.] Output length : ret = 448 exp = 448 -> OK +[.] Random vector checks: +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK + +[+] Testing: gsm0503_tch_afs_6_7 +[.] Input length : ret = 140 exp = 140 -> OK +[.] Output length : ret = 448 exp = 448 -> OK +[.] Random vector checks: +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK + +[+] Testing: gsm0503_tch_afs_5_9 +[.] Input length : ret = 124 exp = 124 -> OK +[.] Output length : ret = 448 exp = 448 -> OK +[.] Random vector checks: +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK + +[+] Testing: gsm0503_tch_afs_5_15 +[.] Input length : ret = 109 exp = 109 -> OK +[.] Output length : ret = 448 exp = 448 -> OK +[.] Random vector checks: +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK + +[+] Testing: gsm0503_tch_afs_4_75 +[.] Input length : ret = 101 exp = 101 -> OK +[.] Output length : ret = 448 exp = 448 -> OK +[.] Random vector checks: +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK + +[+] Testing: gsm0503_tch_fr +[.] Input length : ret = 185 exp = 185 -> OK +[.] Output length : ret = 378 exp = 378 -> OK +[.] Random vector checks: +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK + +[+] Testing: gsm0503_tch_hr +[.] Input length : ret = 98 exp = 98 -> OK +[.] Output length : ret = 211 exp = 211 -> OK +[.] Random vector checks: +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK + +[+] Testing: gsm0503_tch_ahs_7_95 +[.] Input length : ret = 129 exp = 129 -> OK +[.] Output length : ret = 188 exp = 188 -> OK +[.] Random vector checks: +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK + +[+] Testing: gsm0503_tch_ahs_7_4 +[.] Input length : ret = 126 exp = 126 -> OK +[.] Output length : ret = 196 exp = 196 -> OK +[.] Random vector checks: +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK + +[+] Testing: gsm0503_tch_ahs_6_7 +[.] Input length : ret = 116 exp = 116 -> OK +[.] Output length : ret = 200 exp = 200 -> OK +[.] Random vector checks: +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK + +[+] Testing: gsm0503_tch_ahs_5_9 +[.] Input length : ret = 108 exp = 108 -> OK +[.] Output length : ret = 208 exp = 208 -> OK +[.] Random vector checks: +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK + +[+] Testing: gsm0503_tch_ahs_5_15 +[.] Input length : ret = 97 exp = 97 -> OK +[.] Output length : ret = 212 exp = 212 -> OK +[.] Random vector checks: +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK + +[+] Testing: gsm0503_tch_ahs_4_75 +[.] Input length : ret = 89 exp = 89 -> OK +[.] Output length : ret = 212 exp = 212 -> OK +[.] Random vector checks: +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK + +[+] Testing: gsm0503_mcs1_dl_hdr +[.] Input length : ret = 36 exp = 36 -> OK +[.] Output length : ret = 108 exp = 108 -> OK +[.] Random vector checks: +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK + +[+] Testing: gsm0503_mcs1_ul_hdr +[.] Input length : ret = 39 exp = 39 -> OK +[.] Output length : ret = 117 exp = 117 -> OK +[.] Random vector checks: +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK + +[+] Testing: gsm0503_mcs1 +[.] Input length : ret = 190 exp = 190 -> OK +[.] Output length : ret = 588 exp = 588 -> OK +[.] Random vector checks: +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK + +[+] Testing: gsm0503_mcs2 +[.] Input length : ret = 238 exp = 238 -> OK +[.] Output length : ret = 732 exp = 732 -> OK +[.] Random vector checks: +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK + +[+] Testing: gsm0503_mcs3 +[.] Input length : ret = 310 exp = 310 -> OK +[.] Output length : ret = 948 exp = 948 -> OK +[.] Random vector checks: +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK + +[+] Testing: gsm0503_mcs4 +[.] Input length : ret = 366 exp = 366 -> OK +[.] Output length : ret = 1116 exp = 1116 -> OK +[.] Random vector checks: +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK + +[+] Testing: gsm0503_mcs5_dl_hdr +[.] Input length : ret = 33 exp = 33 -> OK +[.] Output length : ret = 99 exp = 99 -> OK +[.] Random vector checks: +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK + +[+] Testing: gsm0503_mcs5_ul_hdr +[.] Input length : ret = 45 exp = 45 -> OK +[.] Output length : ret = 135 exp = 135 -> OK +[.] Random vector checks: +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK + +[+] Testing: gsm0503_mcs5 +[.] Input length : ret = 462 exp = 462 -> OK +[.] Output length : ret = 1404 exp = 1404 -> OK +[.] Random vector checks: +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK + +[+] Testing: gsm0503_mcs6 +[.] Input length : ret = 606 exp = 606 -> OK +[.] Output length : ret = 1836 exp = 1836 -> OK +[.] Random vector checks: +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK + +[+] Testing: gsm0503_mcs7_dl_hdr +[.] Input length : ret = 45 exp = 45 -> OK +[.] Output length : ret = 135 exp = 135 -> OK +[.] Random vector checks: +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK + +[+] Testing: gsm0503_mcs7_ul_hdr +[.] Input length : ret = 54 exp = 54 -> OK +[.] Output length : ret = 162 exp = 162 -> OK +[.] Random vector checks: +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK + +[+] Testing: gsm0503_mcs7 +[.] Input length : ret = 462 exp = 462 -> OK +[.] Output length : ret = 1404 exp = 1404 -> OK +[.] Random vector checks: +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK + +[+] Testing: gsm0503_mcs8 +[.] Input length : ret = 558 exp = 558 -> OK +[.] Output length : ret = 1692 exp = 1692 -> OK +[.] Random vector checks: +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK + +[+] Testing: gsm0503_mcs9 +[.] Input length : ret = 606 exp = 606 -> OK +[.] Output length : ret = 1836 exp = 1836 -> OK +[.] Random vector checks: +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK +[..] Encoding / Decoding cycle : OK + diff --git a/tests/testsuite.at b/tests/testsuite.at index 7ee0164..2f9cfe7 100644 --- a/tests/testsuite.at +++ b/tests/testsuite.at @@ -51,6 +51,12 @@ AT_CHECK([$abs_top_builddir/tests/conv/conv_test], [0], [expout]) AT_CLEANUP +AT_SETUP([conv_gsm0503]) +AT_KEYWORDS([conv_gsm0503]) +cat $abs_srcdir/conv/conv_gsm0503_test.ok > expout +AT_CHECK([$abs_top_builddir/tests/conv/conv_gsm0503_test], [0], [expout]) +AT_CLEANUP + AT_SETUP([coding]) AT_KEYWORDS([coding]) cat $abs_srcdir/coding/coding_test.ok > expout -- To view, visit https://gerrit.osmocom.org/1628 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I76d1cd4032d2f74c5bb93bde4fab99aa655b7f1a Gerrit-PatchSet: 7 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Vadim Yanitskiy Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: Tom Tsou Gerrit-Reviewer: Vadim Yanitskiy Gerrit-Reviewer: tnt From gerrit-no-reply at lists.osmocom.org Sun Apr 30 12:12:24 2017 From: gerrit-no-reply at lists.osmocom.org (Vadim Yanitskiy) Date: Sun, 30 Apr 2017 12:12:24 +0000 Subject: osmo-trx[master]: buildenv: Make build CPU invariant In-Reply-To: References: Message-ID: Patch Set 4: Code-Review+1 (2 comments) https://gerrit.osmocom.org/#/c/2102/4/config/ax_ext.m4 File config/ax_ext.m4: Line 22: # HAVE_MMX / HAVE_SSE / HAVE_SSE2 / HAVE_SSE3 / HAVE_SSSE3 / HAVE_SSE4.1 / HAVE_SSE4.2 / HAVE_AVX Now we have only HAVE_SSE3 and HAVE_SSE4.1, right? So, it would be good to update this line with actual info. PS4, Line 47: AC_REQUIRE([AX_GCC_X86_CPUID]) : AC_REQUIRE([AX_GCC_X86_AVX_XGETBV]) : : AX_GCC_X86_CPUID(0x00000001) Do we still need this? -- To view, visit https://gerrit.osmocom.org/2102 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ic913aa13c23c348ae62e78c9dfd6ed8b0a62798c Gerrit-PatchSet: 4 Gerrit-Project: osmo-trx Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Vadim Yanitskiy Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Sun Apr 30 12:15:08 2017 From: gerrit-no-reply at lists.osmocom.org (Vadim Yanitskiy) Date: Sun, 30 Apr 2017 12:15:08 +0000 Subject: osmo-trx[master]: cosmetic: Add info about SSE support In-Reply-To: References: Message-ID: Patch Set 3: Code-Review+1 -- To view, visit https://gerrit.osmocom.org/2101 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Iacc83fd668c31644e0efb3e18962cf2870ed1daf Gerrit-PatchSet: 3 Gerrit-Project: osmo-trx Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Vadim Yanitskiy Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sun Apr 30 12:17:07 2017 From: gerrit-no-reply at lists.osmocom.org (Vadim Yanitskiy) Date: Sun, 30 Apr 2017 12:17:07 +0000 Subject: osmo-trx[master]: buildenv: Turn off native architecture builds In-Reply-To: References: Message-ID: Patch Set 3: Code-Review+1 -- To view, visit https://gerrit.osmocom.org/2098 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I3df4b8db9692016115edbe2247beeec090715687 Gerrit-PatchSet: 3 Gerrit-Project: osmo-trx Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Vadim Yanitskiy Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sun Apr 30 14:25:17 2017 From: gerrit-no-reply at lists.osmocom.org (Vadim Yanitskiy) Date: Sun, 30 Apr 2017 14:25:17 +0000 Subject: [PATCH] libosmocore[master]: configure.ac: add SIMD detection capabilities Message-ID: Review at https://gerrit.osmocom.org/2453 configure.ac: add SIMD detection capabilities This change adds a new configure flag, which triggers a check whether compiller supports some SIMD (Single Instruction, Multiple Data) instructions. The check macro is based on the AX_EXT from autoconf-archive: www.gnu.org/software/autoconf-archive/ax_ext.html And depends on the ax_check_compile_flag macro: www.gnu.org/software/autoconf-archive/ax_check_compile_flag.html Currently only the following SIMD extensions are being checked: AVX2, SSE3, SSE4.1, but adding others is also possible. All found extensions are being defined in the 'config.h' header. Change-Id: Idf8fff984bd936a75c7c307338df88ba4b005817 --- M .gitignore M configure.ac A m4/ax_check_compile_flag.m4 A m4/ax_check_simd.m4 M src/Makefile.am 5 files changed, 174 insertions(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/53/2453/1 diff --git a/.gitignore b/.gitignore index 5111b25..2b0ca64 100644 --- a/.gitignore +++ b/.gitignore @@ -12,6 +12,7 @@ acinclude.m4 aminclude.am m4/*.m4 +!m4/ax_*.m4 autom4te.cache config.cache config.h* diff --git a/configure.ac b/configure.ac index a18197d..61b2af8 100644 --- a/configure.ac +++ b/configure.ac @@ -226,6 +226,22 @@ CPPFLAGS+=" -fsanitize=address -fsanitize=undefined" fi +AC_ARG_ENABLE(simd, + [AS_HELP_STRING( + [--enable-simd], + [Enable SIMD (SSE, AVX) support] + )], + [simd=$enableval], [simd="no"]) +if test x"$simd" = x"yes" +then + # Find and define supported SIMD extensions + AX_CHECK_SIMD +else + AM_CONDITIONAL(HAVE_AVX2, false) + AM_CONDITIONAL(HAVE_SSE3, false) + AM_CONDITIONAL(HAVE_SSE4_1, false) +fi + AC_OUTPUT( libosmocore.pc libosmocodec.pc diff --git a/m4/ax_check_compile_flag.m4 b/m4/ax_check_compile_flag.m4 new file mode 100644 index 0000000..dcabb92 --- /dev/null +++ b/m4/ax_check_compile_flag.m4 @@ -0,0 +1,74 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_check_compile_flag.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_CHECK_COMPILE_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS], [INPUT]) +# +# DESCRIPTION +# +# Check whether the given FLAG works with the current language's compiler +# or gives an error. (Warnings, however, are ignored) +# +# ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on +# success/failure. +# +# If EXTRA-FLAGS is defined, it is added to the current language's default +# flags (e.g. CFLAGS) when the check is done. The check is thus made with +# the flags: "CFLAGS EXTRA-FLAGS FLAG". This can for example be used to +# force the compiler to issue an error when a bad flag is given. +# +# INPUT gives an alternative input source to AC_COMPILE_IFELSE. +# +# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this +# macro in sync with AX_CHECK_{PREPROC,LINK}_FLAG. +# +# LICENSE +# +# Copyright (c) 2008 Guido U. Draheim +# Copyright (c) 2011 Maarten Bosmans +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see . +# +# As a special exception, the respective Autoconf Macro's copyright owner +# gives unlimited permission to copy, distribute and modify the configure +# scripts that are the output of Autoconf when processing the Macro. You +# need not follow the terms of the GNU General Public License when using +# or distributing such scripts, even though portions of the text of the +# Macro appear in them. The GNU General Public License (GPL) does govern +# all other use of the material that constitutes the Autoconf Macro. +# +# This special exception to the GPL applies to versions of the Autoconf +# Macro released by the Autoconf Archive. When you make and distribute a +# modified version of the Autoconf Macro, you may extend this special +# exception to the GPL to apply to your modified version as well. + +#serial 5 + +AC_DEFUN([AX_CHECK_COMPILE_FLAG], +[AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_IF +AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]flags_$4_$1])dnl +AC_CACHE_CHECK([whether _AC_LANG compiler accepts $1], CACHEVAR, [ + ax_check_save_flags=$[]_AC_LANG_PREFIX[]FLAGS + _AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $4 $1" + AC_COMPILE_IFELSE([m4_default([$5],[AC_LANG_PROGRAM()])], + [AS_VAR_SET(CACHEVAR,[yes])], + [AS_VAR_SET(CACHEVAR,[no])]) + _AC_LANG_PREFIX[]FLAGS=$ax_check_save_flags]) +AS_VAR_IF(CACHEVAR,yes, + [m4_default([$2], :)], + [m4_default([$3], :)]) +AS_VAR_POPDEF([CACHEVAR])dnl +])dnl AX_CHECK_COMPILE_FLAGS diff --git a/m4/ax_check_simd.m4 b/m4/ax_check_simd.m4 new file mode 100644 index 0000000..d07d706 --- /dev/null +++ b/m4/ax_check_simd.m4 @@ -0,0 +1,82 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_ext.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_EXT +# +# DESCRIPTION +# +# Find supported SIMD extensions by requesting cpuid. When an SIMD +# extension is found, the -m"simdextensionname" is added to SIMD_FLAGS if +# compiler supports it. For example, if "sse2" is available, then "-msse2" +# is added to SIMD_FLAGS. +# +# This macro calls: +# +# AC_SUBST(SIMD_FLAGS) +# +# And defines: +# +# HAVE_AVX3 / HAVE_SSE3 / HAVE_SSE4.1 +# +# LICENSE +# +# Copyright (c) 2007 Christophe Tournayre +# Copyright (c) 2013 Michael Petch +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. +# +# NOTE: The functionality that requests the cpuid has been stripped because +# this project detects the CPU capabilities during runtime. However, we +# still need to check if the compiler supports the requested SIMD flag. + +#serial 12 + +AC_DEFUN([AX_CHECK_SIMD], +[ + AC_REQUIRE([AC_CANONICAL_HOST]) + + case $host_cpu in + i[[3456]]86*|x86_64*|amd64*) + AX_CHECK_COMPILE_FLAG(-mavx2, ax_cv_support_avx2_ext=yes, []) + if test x"$ax_cv_support_avx2_ext" = x"yes"; then + SIMD_FLAGS="$SIMD_FLAGS -mavx2" + AC_DEFINE(HAVE_AVX2,, + [Support AVX2 (Advanced Vector Extensions 2) instructions]) + AM_CONDITIONAL(HAVE_AVX2, true) + else + AC_MSG_WARN([Your compiler does not support AVX2 instructions]) + AM_CONDITIONAL(HAVE_AVX2, false) + fi + + AX_CHECK_COMPILE_FLAG(-msse3, ax_cv_support_sse3_ext=yes, []) + if test x"$ax_cv_support_sse3_ext" = x"yes"; then + SIMD_FLAGS="$SIMD_FLAGS -msse3" + AC_DEFINE(HAVE_SSE3,, + [Support SSE3 (Streaming SIMD Extensions 3) instructions]) + AM_CONDITIONAL(HAVE_SSE3, true) + else + AC_MSG_WARN([Your compiler does not support SSE3 instructions]) + AM_CONDITIONAL(HAVE_SSE3, false) + fi + + AX_CHECK_COMPILE_FLAG(-msse4.1, ax_cv_support_sse41_ext=yes, []) + if test x"$ax_cv_support_sse41_ext" = x"yes"; then + SIMD_FLAGS="$SIMD_FLAGS -msse4.1" + AC_DEFINE(HAVE_SSE4_1,, + [Support SSE4.1 (Streaming SIMD Extensions 4.1) instructions]) + AM_CONDITIONAL(HAVE_SSE4_1, true) + else + AC_MSG_WARN([Your compiler does not support SSE4.1 instructions]) + AM_CONDITIONAL(HAVE_SSE4_1, false) + fi + ;; + esac + + AC_SUBST(SIMD_FLAGS) +]) diff --git a/src/Makefile.am b/src/Makefile.am index 6948e1a..999436d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -4,7 +4,7 @@ LIBVERSION=8:0:0 AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_builddir)/include -AM_CFLAGS = -Wall $(TALLOC_CFLAGS) +AM_CFLAGS = -Wall $(TALLOC_CFLAGS) $(SIMD_FLAGS) lib_LTLIBRARIES = libosmocore.la -- To view, visit https://gerrit.osmocom.org/2453 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Idf8fff984bd936a75c7c307338df88ba4b005817 Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Vadim Yanitskiy From gerrit-no-reply at lists.osmocom.org Sun Apr 30 14:25:17 2017 From: gerrit-no-reply at lists.osmocom.org (Vadim Yanitskiy) Date: Sun, 30 Apr 2017 14:25:17 +0000 Subject: [PATCH] libosmocore[master]: core/conv: add x86 SSE support for Viterbi decoder Message-ID: Review at https://gerrit.osmocom.org/2454 core/conv: add x86 SSE support for Viterbi decoder Fast convolutional decoding is provided through x86 intrinsic based SSE operations. SSE3, found on virtually all modern x86 processors, is the minimal requirement. SSE4.1 and AVX2 are used if available. To enable this feature, the source code should be configured with SIMD support (see --enable-simd). Otherwise, the viterbi_sse.c won't be compiled. Also, the original code was extended with runtime SIMD detection, so only supported extensions will be used by target CPU. It makes the library more partable, what is very important for binary packages distribution. The SIMD detection is currently implemented through the __builtin_cpu_supports(EXT), which is only supported by GCC. Change-Id: I1da6d71ed0564f1d684f3a836e998d09de5f0351 --- M src/Makefile.am M src/viterbi.c A src/viterbi_sse.c 3 files changed, 699 insertions(+), 6 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/54/2454/1 diff --git a/src/Makefile.am b/src/Makefile.am index 999436d..2f19838 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -19,6 +19,10 @@ macaddr.c stat_item.c stats.c stats_statsd.c prim.c \ viterbi.c viterbi_gen.c +if HAVE_SSE3 +libosmocore_la_SOURCES += viterbi_sse.c +endif + BUILT_SOURCES = crc8gen.c crc16gen.c crc32gen.c crc64gen.c if ENABLE_PLUGIN diff --git a/src/viterbi.c b/src/viterbi.c index ea4fb21..1484a31 100644 --- a/src/viterbi.c +++ b/src/viterbi.c @@ -20,16 +20,30 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#include #include #include #include -#include #include "config.h" + +#include #define BIT2NRZ(REG,N) (((REG >> N) & 0x01) * 2 - 1) * -1 #define NUM_STATES(K) (K == 7 ? 64 : 16) #define SSE_ALIGN 16 + +static int init_complete = 0; + +__attribute__ ((visibility("hidden"))) int avx2_supported = 0; +__attribute__ ((visibility("hidden"))) int sse3_supported = 0; +__attribute__ ((visibility("hidden"))) int sse41_supported = 0; + +/** + * This pointer will be initialized by the osmo_conv_init() + * depending on supported SIMD extensions. + */ +static int16_t *(*vdec_malloc)(size_t n); /* Forward Metric Units */ void osmo_conv_gen_metrics_k5_n2(const int8_t *seq, const int16_t *out, @@ -44,6 +58,21 @@ int16_t *sums, int16_t *paths, int norm); void osmo_conv_gen_metrics_k7_n4(const int8_t *seq, const int16_t *out, int16_t *sums, int16_t *paths, int norm); + +#ifdef HAVE_SSE3 +void osmo_conv_gen_metrics_k5_n2_sse(const int8_t *seq, const int16_t *out, + int16_t *sums, int16_t *paths, int norm); +void osmo_conv_gen_metrics_k5_n3_sse(const int8_t *seq, const int16_t *out, + int16_t *sums, int16_t *paths, int norm); +void osmo_conv_gen_metrics_k5_n4_sse(const int8_t *seq, const int16_t *out, + int16_t *sums, int16_t *paths, int norm); +void osmo_conv_gen_metrics_k7_n2_sse(const int8_t *seq, const int16_t *out, + int16_t *sums, int16_t *paths, int norm); +void osmo_conv_gen_metrics_k7_n3_sse(const int8_t *seq, const int16_t *out, + int16_t *sums, int16_t *paths, int norm); +void osmo_conv_gen_metrics_k7_n4_sse(const int8_t *seq, const int16_t *out, + int16_t *sums, int16_t *paths, int norm); +#endif /* Trellis State * state - Internal lshift register value @@ -96,13 +125,14 @@ * (accumulated sums, outputs, and path decisions) as 16 bit signed integers * so the allocated memory is casted as such. */ -static int16_t *vdec_malloc(size_t n) +static int16_t *vdec_malloc_no_sse3(size_t n) { -#ifdef HAVE_SSE3 - return (int16_t *) memalign(SSE_ALIGN, sizeof(int16_t) * n); -#else return (int16_t *) malloc(sizeof(int16_t) * n); -#endif +} + +static int16_t *vdec_malloc_sse3(size_t n) +{ + return (int16_t *) memalign(SSE_ALIGN, sizeof(int16_t) * n); } /* Accessor calls */ @@ -465,13 +495,31 @@ if (dec->k == 5) { switch (dec->n) { case 2: + #ifdef HAVE_SSE3 + dec->metric_func = !sse3_supported ? + osmo_conv_gen_metrics_k5_n2 : + osmo_conv_gen_metrics_k5_n2_sse; + #else dec->metric_func = osmo_conv_gen_metrics_k5_n2; + #endif break; case 3: + #ifdef HAVE_SSE3 + dec->metric_func = !sse3_supported ? + osmo_conv_gen_metrics_k5_n3 : + osmo_conv_gen_metrics_k5_n3_sse; + #else dec->metric_func = osmo_conv_gen_metrics_k5_n3; + #endif break; case 4: + #ifdef HAVE_SSE3 + dec->metric_func = !sse3_supported ? + osmo_conv_gen_metrics_k5_n4 : + osmo_conv_gen_metrics_k5_n4_sse; + #else dec->metric_func = osmo_conv_gen_metrics_k5_n4; + #endif break; default: goto fail; @@ -479,13 +527,31 @@ } else if (dec->k == 7) { switch (dec->n) { case 2: + #ifdef HAVE_SSE3 + dec->metric_func = !sse3_supported ? + osmo_conv_gen_metrics_k7_n2 : + osmo_conv_gen_metrics_k7_n2_sse; + #else dec->metric_func = osmo_conv_gen_metrics_k7_n2; + #endif break; case 3: + #ifdef HAVE_SSE3 + dec->metric_func = !sse3_supported ? + osmo_conv_gen_metrics_k7_n3 : + osmo_conv_gen_metrics_k7_n3_sse; + #else dec->metric_func = osmo_conv_gen_metrics_k7_n3; + #endif break; case 4: + #ifdef HAVE_SSE3 + dec->metric_func = !sse3_supported ? + osmo_conv_gen_metrics_k7_n4 : + osmo_conv_gen_metrics_k7_n4_sse; + #else dec->metric_func = osmo_conv_gen_metrics_k7_n4; + #endif break; default: goto fail; @@ -578,6 +644,29 @@ return traceback(dec, out, term, len); } +static void osmo_conv_init(void) +{ + init_complete = 1; + +#if (defined(__GNUC__) && !defined(__clang__)) + /* Detect CPU capabilities */ + #ifdef HAVE_AVX2 + avx2_supported = __builtin_cpu_supports("avx2"); + #endif + + #ifdef HAVE_SSE3 + sse3_supported = __builtin_cpu_supports("sse3"); + #endif + + #ifdef HAVE_SSE4_1 + sse41_supported = __builtin_cpu_supports("sse4.1"); + #endif +#endif + + vdec_malloc = sse3_supported ? + &vdec_malloc_no_sse3 : &vdec_malloc_sse3; +} + /* All-in-one Viterbi decoding */ int osmo_conv_decode_acc(const struct osmo_conv_code *code, const sbit_t *input, ubit_t *output) @@ -585,6 +674,9 @@ int rc; struct vdecoder *vdec; + if (!init_complete) + osmo_conv_init(); + if ((code->N < 2) || (code->N > 4) || (code->len < 1) || ((code->K != 5) && (code->K != 7))) return -EINVAL; diff --git a/src/viterbi_sse.c b/src/viterbi_sse.c new file mode 100644 index 0000000..3cd9fcb --- /dev/null +++ b/src/viterbi_sse.c @@ -0,0 +1,597 @@ +/* + * Intel SSE Viterbi decoder + * + * Copyright (C) 2013, 2014 Thomas Tsou + * + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include +#include +#include + +#include "config.h" + +#if defined(HAVE_SSE4_1) || defined(HAVE_SSE41) + #include +#endif + +#ifdef HAVE_AVX2 + #include +#endif + +extern int sse41_supported; +extern int sse3_supported; +extern int avx2_supported; + +/* Octo-Viterbi butterfly + * Compute 8-wide butterfly generating 16 path decisions and 16 accumulated + * sums. Inputs all packed 16-bit integers in three 128-bit XMM registers. + * Two intermediate registers are used and results are set in the upper 4 + * registers. + * + * Input: + * M0 - Path metrics 0 (packed 16-bit integers) + * M1 - Path metrics 1 (packed 16-bit integers) + * M2 - Branch metrics (packed 16-bit integers) + * + * Output: + * M2 - Selected and accumulated path metrics 0 + * M4 - Selected and accumulated path metrics 1 + * M3 - Path selections 0 + * M1 - Path selections 1 + */ +#define SSE_BUTTERFLY(M0, M1, M2, M3, M4) \ +{ \ + M3 = _mm_adds_epi16(M0, M2); \ + M4 = _mm_subs_epi16(M1, M2); \ + M0 = _mm_subs_epi16(M0, M2); \ + M1 = _mm_adds_epi16(M1, M2); \ + M2 = _mm_max_epi16(M3, M4); \ + M3 = _mm_cmpgt_epi16(M3, M4); \ + M4 = _mm_max_epi16(M0, M1); \ + M1 = _mm_cmpgt_epi16(M0, M1); \ +} + +/* Two lane deinterleaving K = 5: + * Take 16 interleaved 16-bit integers and deinterleave to 2 packed 128-bit + * registers. The operation summarized below. Four registers are used with + * the lower 2 as input and upper 2 as output. + * + * In - 10101010 10101010 10101010 10101010 + * Out - 00000000 11111111 00000000 11111111 + * + * Input: + * M0:1 - Packed 16-bit integers + * + * Output: + * M2:3 - Deinterleaved packed 16-bit integers + */ +#define _I8_SHUFFLE_MASK 15, 14, 11, 10, 7, 6, 3, 2, 13, 12, 9, 8, 5, 4, 1, 0 + +#define SSE_DEINTERLEAVE_K5(M0, M1, M2, M3) \ +{ \ + M2 = _mm_set_epi8(_I8_SHUFFLE_MASK); \ + M0 = _mm_shuffle_epi8(M0, M2); \ + M1 = _mm_shuffle_epi8(M1, M2); \ + M2 = _mm_unpacklo_epi64(M0, M1); \ + M3 = _mm_unpackhi_epi64(M0, M1); \ +} + +/* Two lane deinterleaving K = 7: + * Take 64 interleaved 16-bit integers and deinterleave to 8 packed 128-bit + * registers. The operation summarized below. 16 registers are used with the + * lower 8 as input and upper 8 as output. + * + * In - 10101010 10101010 10101010 10101010 ... + * Out - 00000000 11111111 00000000 11111111 ... + * + * Input: + * M0:7 - Packed 16-bit integers + * + * Output: + * M8:15 - Deinterleaved packed 16-bit integers + */ +#define SSE_DEINTERLEAVE_K7(M0, M1, M2, M3, M4, M5, M6, M7, \ + M8, M9, M10, M11, M12, M13, M14, M15) \ +{ \ + M8 = _mm_set_epi8(_I8_SHUFFLE_MASK); \ + M0 = _mm_shuffle_epi8(M0, M8); \ + M1 = _mm_shuffle_epi8(M1, M8); \ + M2 = _mm_shuffle_epi8(M2, M8); \ + M3 = _mm_shuffle_epi8(M3, M8); \ + M4 = _mm_shuffle_epi8(M4, M8); \ + M5 = _mm_shuffle_epi8(M5, M8); \ + M6 = _mm_shuffle_epi8(M6, M8); \ + M7 = _mm_shuffle_epi8(M7, M8); \ + M8 = _mm_unpacklo_epi64(M0, M1); \ + M9 = _mm_unpackhi_epi64(M0, M1); \ + M10 = _mm_unpacklo_epi64(M2, M3); \ + M11 = _mm_unpackhi_epi64(M2, M3); \ + M12 = _mm_unpacklo_epi64(M4, M5); \ + M13 = _mm_unpackhi_epi64(M4, M5); \ + M14 = _mm_unpacklo_epi64(M6, M7); \ + M15 = _mm_unpackhi_epi64(M6, M7); \ +} + +/* Generate branch metrics N = 2: + * Compute 16 branch metrics from trellis outputs and input values. + * + * Input: + * M0:3 - 16 x 2 packed 16-bit trellis outputs + * M4 - Expanded and packed 16-bit input value + * + * Output: + * M6:7 - 16 computed 16-bit branch metrics + */ +#define SSE_BRANCH_METRIC_N2(M0, M1, M2, M3, M4, M6, M7) \ +{ \ + M0 = _mm_sign_epi16(M4, M0); \ + M1 = _mm_sign_epi16(M4, M1); \ + M2 = _mm_sign_epi16(M4, M2); \ + M3 = _mm_sign_epi16(M4, M3); \ + M6 = _mm_hadds_epi16(M0, M1); \ + M7 = _mm_hadds_epi16(M2, M3); \ +} + +/* Generate branch metrics N = 4: + * Compute 8 branch metrics from trellis outputs and input values. This + * macro is reused for N less than 4 where the extra soft input bits are + * padded. + * + * Input: + * M0:3 - 8 x 4 packed 16-bit trellis outputs + * M4 - Expanded and packed 16-bit input value + * + * Output: + * M5 - 8 computed 16-bit branch metrics + */ +#define SSE_BRANCH_METRIC_N4(M0, M1, M2, M3, M4, M5) \ +{ \ + M0 = _mm_sign_epi16(M4, M0); \ + M1 = _mm_sign_epi16(M4, M1); \ + M2 = _mm_sign_epi16(M4, M2); \ + M3 = _mm_sign_epi16(M4, M3); \ + M0 = _mm_hadds_epi16(M0, M1); \ + M1 = _mm_hadds_epi16(M2, M3); \ + M5 = _mm_hadds_epi16(M0, M1); \ +} + +/* Broadcast 16-bit integer + * Repeat the low 16-bit integer to all elements of the 128-bit SSE + * register. Only AVX2 has a dedicated broadcast instruction; use repeat + * unpacks for SSE only architectures. This is a destructive operation and + * the source register is overwritten. + * + * Input: + * M0 - Low 16-bit element is read + * + * Output: + * M0 - Contains broadcasted values + */ +#ifdef HAVE_AVX2 +#define SSE_BROADCAST(M0) \ +{ \ + if (avx2_supported) { \ + M0 = _mm_broadcastw_epi16(M0); \ + } else { \ + M0 = _mm_unpacklo_epi16(M0, M0); \ + M0 = _mm_unpacklo_epi32(M0, M0); \ + M0 = _mm_unpacklo_epi64(M0, M0); \ + } \ +} +#else +#define SSE_BROADCAST(M0) \ +{ \ + M0 = _mm_unpacklo_epi16(M0, M0); \ + M0 = _mm_unpacklo_epi32(M0, M0); \ + M0 = _mm_unpacklo_epi64(M0, M0); \ +} +#endif + +/* Horizontal minimum + * Compute horizontal minimum of packed unsigned 16-bit integers and place + * result in the low 16-bit element of the source register. Only SSE 4.1 + * has a dedicated minpos instruction. One intermediate register is used + * if SSE 4.1 is not available. This is a destructive operation and the + * source register is overwritten. + * + * Input: + * M0 - Packed unsigned 16-bit integers + * + * Output: + * M0 - Minimum value placed in low 16-bit element + */ +#if defined(HAVE_SSE4_1) || defined(HAVE_SSE41) +#define SSE_MINPOS(M0, M1) \ +{ \ + if (sse41_supported) { \ + M0 = _mm_minpos_epu16(M0); \ + } else { \ + M1 = _mm_shuffle_epi32(M0, _MM_SHUFFLE(0, 0, 3, 2)); \ + M0 = _mm_min_epi16(M0, M1); \ + M1 = _mm_shufflelo_epi16(M0, _MM_SHUFFLE(0, 0, 3, 2)); \ + M0 = _mm_min_epi16(M0, M1); \ + M1 = _mm_shufflelo_epi16(M0, _MM_SHUFFLE(0, 0, 0, 1)); \ + M0 = _mm_min_epi16(M0, M1); \ + } \ +} +#else +#define SSE_MINPOS(M0, M1) \ +{ \ + M1 = _mm_shuffle_epi32(M0, _MM_SHUFFLE(0, 0, 3, 2)); \ + M0 = _mm_min_epi16(M0, M1); \ + M1 = _mm_shufflelo_epi16(M0, _MM_SHUFFLE(0, 0, 3, 2)); \ + M0 = _mm_min_epi16(M0, M1); \ + M1 = _mm_shufflelo_epi16(M0, _MM_SHUFFLE(0, 0, 0, 1)); \ + M0 = _mm_min_epi16(M0, M1); \ +} +#endif + +/* Normalize state metrics K = 5: + * Compute 16-wide normalization by subtracting the smallest value from + * all values. Inputs are 16 packed 16-bit integers across 2 XMM registers. + * Two intermediate registers are used and normalized results are placed + * in the originating locations. + * + * Input: + * M0:1 - Path metrics 0:1 (packed 16-bit integers) + * + * Output: + * M0:1 - Normalized path metrics 0:1 + */ +#define SSE_NORMALIZE_K5(M0, M1, M2, M3) \ +{ \ + M2 = _mm_min_epi16(M0, M1); \ + SSE_MINPOS(M2, M3) \ + SSE_BROADCAST(M2) \ + M0 = _mm_subs_epi16(M0, M2); \ + M1 = _mm_subs_epi16(M1, M2); \ +} + +/* Normalize state metrics K = 7: + * Compute 64-wide normalization by subtracting the smallest value from + * all values. Inputs are 8 registers of accumulated sums and 4 temporary + * registers. Normalized results are returned in the originating locations. + * + * Input: + * M0:7 - Path metrics 0:7 (packed 16-bit integers) + * + * Output: + * M0:7 - Normalized path metrics 0:7 + */ +#define SSE_NORMALIZE_K7(M0, M1, M2, M3, M4, M5, M6, M7, M8, M9, M10, M11) \ +{ \ + M8 = _mm_min_epi16(M0, M1); \ + M9 = _mm_min_epi16(M2, M3); \ + M10 = _mm_min_epi16(M4, M5); \ + M11 = _mm_min_epi16(M6, M7); \ + M8 = _mm_min_epi16(M8, M9); \ + M10 = _mm_min_epi16(M10, M11); \ + M8 = _mm_min_epi16(M8, M10); \ + SSE_MINPOS(M8, M9) \ + SSE_BROADCAST(M8) \ + M0 = _mm_subs_epi16(M0, M8); \ + M1 = _mm_subs_epi16(M1, M8); \ + M2 = _mm_subs_epi16(M2, M8); \ + M3 = _mm_subs_epi16(M3, M8); \ + M4 = _mm_subs_epi16(M4, M8); \ + M5 = _mm_subs_epi16(M5, M8); \ + M6 = _mm_subs_epi16(M6, M8); \ + M7 = _mm_subs_epi16(M7, M8); \ +} + +/* Combined BMU/PMU (K=5, N=2) + * Compute branch metrics followed by path metrics for half rate 16-state + * trellis. 8 butterflies are computed. Accumulated path sums are not + * preserved and read and written into the same memory location. Normalize + * sums if requires. + */ +__always_inline static void _sse_metrics_k5_n2(const int16_t *val, + const int16_t *out, int16_t *sums, int16_t *paths, int norm) +{ + __m128i m0, m1, m2, m3, m4, m5, m6; + + /* (BMU) Load input sequence */ + m2 = _mm_castpd_si128(_mm_loaddup_pd((double const *) val)); + + /* (BMU) Load trellis outputs */ + m0 = _mm_load_si128((__m128i *) &out[0]); + m1 = _mm_load_si128((__m128i *) &out[8]); + + /* (BMU) Compute branch metrics */ + m0 = _mm_sign_epi16(m2, m0); + m1 = _mm_sign_epi16(m2, m1); + m2 = _mm_hadds_epi16(m0, m1); + + /* (PMU) Load accumulated path metrics */ + m0 = _mm_load_si128((__m128i *) &sums[0]); + m1 = _mm_load_si128((__m128i *) &sums[8]); + + SSE_DEINTERLEAVE_K5(m0, m1, m3, m4) + + /* (PMU) Butterflies: 0-7 */ + SSE_BUTTERFLY(m3, m4, m2, m5, m6) + + if (norm) + SSE_NORMALIZE_K5(m2, m6, m0, m1) + + _mm_store_si128((__m128i *) &sums[0], m2); + _mm_store_si128((__m128i *) &sums[8], m6); + _mm_store_si128((__m128i *) &paths[0], m5); + _mm_store_si128((__m128i *) &paths[8], m4); +} + +/* Combined BMU/PMU (K=5, N=3 and N=4) + * Compute branch metrics followed by path metrics for 16-state and rates + * to 1/4. 8 butterflies are computed. The input sequence is read four 16-bit + * values at a time, and extra values should be set to zero for rates other + * than 1/4. Normally only rates 1/3 and 1/4 are used as there is a + * dedicated implementation of rate 1/2. + */ +__always_inline static void _sse_metrics_k5_n4(const int16_t *val, + const int16_t *out, int16_t *sums, int16_t *paths, int norm) +{ + __m128i m0, m1, m2, m3, m4, m5, m6; + + /* (BMU) Load input sequence */ + m4 = _mm_castpd_si128(_mm_loaddup_pd((double const *) val)); + + /* (BMU) Load trellis outputs */ + m0 = _mm_load_si128((__m128i *) &out[0]); + m1 = _mm_load_si128((__m128i *) &out[8]); + m2 = _mm_load_si128((__m128i *) &out[16]); + m3 = _mm_load_si128((__m128i *) &out[24]); + + SSE_BRANCH_METRIC_N4(m0, m1, m2, m3, m4, m2) + + /* (PMU) Load accumulated path metrics */ + m0 = _mm_load_si128((__m128i *) &sums[0]); + m1 = _mm_load_si128((__m128i *) &sums[8]); + + SSE_DEINTERLEAVE_K5(m0, m1, m3, m4) + + /* (PMU) Butterflies: 0-7 */ + SSE_BUTTERFLY(m3, m4, m2, m5, m6) + + if (norm) + SSE_NORMALIZE_K5(m2, m6, m0, m1) + + _mm_store_si128((__m128i *) &sums[0], m2); + _mm_store_si128((__m128i *) &sums[8], m6); + _mm_store_si128((__m128i *) &paths[0], m5); + _mm_store_si128((__m128i *) &paths[8], m4); +} + +/* Combined BMU/PMU (K=7, N=2) + * Compute branch metrics followed by path metrics for half rate 64-state + * trellis. 32 butterfly operations are computed. Deinterleaving path + * metrics requires usage of the full SSE register file, so separate sums + * before computing branch metrics to avoid register spilling. + */ +__always_inline static void _sse_metrics_k7_n2(const int16_t *val, + const int16_t *out, int16_t *sums, int16_t *paths, int norm) +{ + __m128i m0, m1, m2, m3, m4, m5, m6, m7, m8, + m9, m10, m11, m12, m13, m14, m15; + + /* (PMU) Load accumulated path metrics */ + m0 = _mm_load_si128((__m128i *) &sums[0]); + m1 = _mm_load_si128((__m128i *) &sums[8]); + m2 = _mm_load_si128((__m128i *) &sums[16]); + m3 = _mm_load_si128((__m128i *) &sums[24]); + m4 = _mm_load_si128((__m128i *) &sums[32]); + m5 = _mm_load_si128((__m128i *) &sums[40]); + m6 = _mm_load_si128((__m128i *) &sums[48]); + m7 = _mm_load_si128((__m128i *) &sums[56]); + + /* (PMU) Deinterleave to even-odd registers */ + SSE_DEINTERLEAVE_K7(m0, m1, m2, m3 ,m4 ,m5, m6, m7, + m8, m9, m10, m11, m12, m13, m14, m15) + + /* (BMU) Load input symbols */ + m7 = _mm_castpd_si128(_mm_loaddup_pd((double const *) val)); + + /* (BMU) Load trellis outputs */ + m0 = _mm_load_si128((__m128i *) &out[0]); + m1 = _mm_load_si128((__m128i *) &out[8]); + m2 = _mm_load_si128((__m128i *) &out[16]); + m3 = _mm_load_si128((__m128i *) &out[24]); + + SSE_BRANCH_METRIC_N2(m0, m1, m2, m3, m7, m4, m5) + + m0 = _mm_load_si128((__m128i *) &out[32]); + m1 = _mm_load_si128((__m128i *) &out[40]); + m2 = _mm_load_si128((__m128i *) &out[48]); + m3 = _mm_load_si128((__m128i *) &out[56]); + + SSE_BRANCH_METRIC_N2(m0, m1, m2, m3, m7, m6, m7) + + /* (PMU) Butterflies: 0-15 */ + SSE_BUTTERFLY(m8, m9, m4, m0, m1) + SSE_BUTTERFLY(m10, m11, m5, m2, m3) + + _mm_store_si128((__m128i *) &paths[0], m0); + _mm_store_si128((__m128i *) &paths[8], m2); + _mm_store_si128((__m128i *) &paths[32], m9); + _mm_store_si128((__m128i *) &paths[40], m11); + + /* (PMU) Butterflies: 17-31 */ + SSE_BUTTERFLY(m12, m13, m6, m0, m2) + SSE_BUTTERFLY(m14, m15, m7, m9, m11) + + _mm_store_si128((__m128i *) &paths[16], m0); + _mm_store_si128((__m128i *) &paths[24], m9); + _mm_store_si128((__m128i *) &paths[48], m13); + _mm_store_si128((__m128i *) &paths[56], m15); + + if (norm) + SSE_NORMALIZE_K7(m4, m1, m5, m3, m6, m2, + m7, m11, m0, m8, m9, m10) + + _mm_store_si128((__m128i *) &sums[0], m4); + _mm_store_si128((__m128i *) &sums[8], m5); + _mm_store_si128((__m128i *) &sums[16], m6); + _mm_store_si128((__m128i *) &sums[24], m7); + _mm_store_si128((__m128i *) &sums[32], m1); + _mm_store_si128((__m128i *) &sums[40], m3); + _mm_store_si128((__m128i *) &sums[48], m2); + _mm_store_si128((__m128i *) &sums[56], m11); +} + +/* Combined BMU/PMU (K=7, N=3 and N=4) + * Compute branch metrics followed by path metrics for half rate 64-state + * trellis. 32 butterfly operations are computed. Deinterleave path + * metrics before computing branch metrics as in the half rate case. + */ +__always_inline static void _sse_metrics_k7_n4(const int16_t *val, + const int16_t *out, int16_t *sums, int16_t *paths, int norm) +{ + __m128i m0, m1, m2, m3, m4, m5, m6, m7; + __m128i m8, m9, m10, m11, m12, m13, m14, m15; + + /* (PMU) Load accumulated path metrics */ + m0 = _mm_load_si128((__m128i *) &sums[0]); + m1 = _mm_load_si128((__m128i *) &sums[8]); + m2 = _mm_load_si128((__m128i *) &sums[16]); + m3 = _mm_load_si128((__m128i *) &sums[24]); + m4 = _mm_load_si128((__m128i *) &sums[32]); + m5 = _mm_load_si128((__m128i *) &sums[40]); + m6 = _mm_load_si128((__m128i *) &sums[48]); + m7 = _mm_load_si128((__m128i *) &sums[56]); + + /* (PMU) Deinterleave into even and odd packed registers */ + SSE_DEINTERLEAVE_K7(m0, m1, m2, m3 ,m4 ,m5, m6, m7, + m8, m9, m10, m11, m12, m13, m14, m15) + + /* (BMU) Load and expand 8-bit input out to 16-bits */ + m7 = _mm_castpd_si128(_mm_loaddup_pd((double const *) val)); + + /* (BMU) Load and compute branch metrics */ + m0 = _mm_load_si128((__m128i *) &out[0]); + m1 = _mm_load_si128((__m128i *) &out[8]); + m2 = _mm_load_si128((__m128i *) &out[16]); + m3 = _mm_load_si128((__m128i *) &out[24]); + + SSE_BRANCH_METRIC_N4(m0, m1, m2, m3, m7, m4) + + m0 = _mm_load_si128((__m128i *) &out[32]); + m1 = _mm_load_si128((__m128i *) &out[40]); + m2 = _mm_load_si128((__m128i *) &out[48]); + m3 = _mm_load_si128((__m128i *) &out[56]); + + SSE_BRANCH_METRIC_N4(m0, m1, m2, m3, m7, m5) + + m0 = _mm_load_si128((__m128i *) &out[64]); + m1 = _mm_load_si128((__m128i *) &out[72]); + m2 = _mm_load_si128((__m128i *) &out[80]); + m3 = _mm_load_si128((__m128i *) &out[88]); + + SSE_BRANCH_METRIC_N4(m0, m1, m2, m3, m7, m6) + + m0 = _mm_load_si128((__m128i *) &out[96]); + m1 = _mm_load_si128((__m128i *) &out[104]); + m2 = _mm_load_si128((__m128i *) &out[112]); + m3 = _mm_load_si128((__m128i *) &out[120]); + + SSE_BRANCH_METRIC_N4(m0, m1, m2, m3, m7, m7) + + /* (PMU) Butterflies: 0-15 */ + SSE_BUTTERFLY(m8, m9, m4, m0, m1) + SSE_BUTTERFLY(m10, m11, m5, m2, m3) + + _mm_store_si128((__m128i *) &paths[0], m0); + _mm_store_si128((__m128i *) &paths[8], m2); + _mm_store_si128((__m128i *) &paths[32], m9); + _mm_store_si128((__m128i *) &paths[40], m11); + + /* (PMU) Butterflies: 17-31 */ + SSE_BUTTERFLY(m12, m13, m6, m0, m2) + SSE_BUTTERFLY(m14, m15, m7, m9, m11) + + _mm_store_si128((__m128i *) &paths[16], m0); + _mm_store_si128((__m128i *) &paths[24], m9); + _mm_store_si128((__m128i *) &paths[48], m13); + _mm_store_si128((__m128i *) &paths[56], m15); + + if (norm) + SSE_NORMALIZE_K7(m4, m1, m5, m3, m6, m2, + m7, m11, m0, m8, m9, m10) + + _mm_store_si128((__m128i *) &sums[0], m4); + _mm_store_si128((__m128i *) &sums[8], m5); + _mm_store_si128((__m128i *) &sums[16], m6); + _mm_store_si128((__m128i *) &sums[24], m7); + _mm_store_si128((__m128i *) &sums[32], m1); + _mm_store_si128((__m128i *) &sums[40], m3); + _mm_store_si128((__m128i *) &sums[48], m2); + _mm_store_si128((__m128i *) &sums[56], m11); +} + +__attribute__ ((visibility("hidden"))) +void osmo_conv_gen_metrics_k5_n2_sse(const int8_t *val, const int16_t *out, + int16_t *sums, int16_t *paths, int norm) +{ + const int16_t _val[4] = { val[0], val[1], val[0], val[1] }; + + _sse_metrics_k5_n2(_val, out, sums, paths, norm); +} + +__attribute__ ((visibility("hidden"))) +void osmo_conv_gen_metrics_k5_n3_sse(const int8_t *val, const int16_t *out, + int16_t *sums, int16_t *paths, int norm) +{ + const int16_t _val[4] = { val[0], val[1], val[2], 0 }; + + _sse_metrics_k5_n4(_val, out, sums, paths, norm); +} + +__attribute__ ((visibility("hidden"))) +void osmo_conv_gen_metrics_k5_n4_sse(const int8_t *val, const int16_t *out, + int16_t *sums, int16_t *paths, int norm) +{ + const int16_t _val[4] = { val[0], val[1], val[2], val[3] }; + + _sse_metrics_k5_n4(_val, out, sums, paths, norm); +} + +__attribute__ ((visibility("hidden"))) +void osmo_conv_gen_metrics_k7_n2_sse(const int8_t *val, const int16_t *out, + int16_t *sums, int16_t *paths, int norm) +{ + const int16_t _val[4] = { val[0], val[1], val[0], val[1] }; + + _sse_metrics_k7_n2(_val, out, sums, paths, norm); +} + +__attribute__ ((visibility("hidden"))) +void osmo_conv_gen_metrics_k7_n3_sse(const int8_t *val, const int16_t *out, + int16_t *sums, int16_t *paths, int norm) +{ + const int16_t _val[4] = { val[0], val[1], val[2], 0 }; + + _sse_metrics_k7_n4(_val, out, sums, paths, norm); +} + +__attribute__ ((visibility("hidden"))) +void osmo_conv_gen_metrics_k7_n4_sse(const int8_t *val, const int16_t *out, + int16_t *sums, int16_t *paths, int norm) +{ + const int16_t _val[4] = { val[0], val[1], val[2], val[3] }; + + _sse_metrics_k7_n4(_val, out, sums, paths, norm); +} -- To view, visit https://gerrit.osmocom.org/2454 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I1da6d71ed0564f1d684f3a836e998d09de5f0351 Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Vadim Yanitskiy From gerrit-no-reply at lists.osmocom.org Sun Apr 30 16:09:56 2017 From: gerrit-no-reply at lists.osmocom.org (Vadim Yanitskiy) Date: Sun, 30 Apr 2017 16:09:56 +0000 Subject: [PATCH] libosmocore[master]: core/conv: add x86 SSE support for Viterbi decoder In-Reply-To: References: Message-ID: Hello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/2454 to look at the new patch set (#2). core/conv: add x86 SSE support for Viterbi decoder Fast convolutional decoding is provided through x86 intrinsic based SSE operations. SSE3, found on virtually all modern x86 processors, is the minimal requirement. SSE4.1 and AVX2 are used if available. To enable this feature, the source code should be configured with SIMD support (see --enable-simd). Otherwise, the viterbi_sse.c won't be compiled. Also, the original code was extended with runtime SIMD detection, so only supported extensions will be used by target CPU. It makes the library more partable, what is very important for binary packages distribution. The SIMD detection is currently implemented through the __builtin_cpu_supports(EXT), which is only supported by GCC. Change-Id: I1da6d71ed0564f1d684f3a836e998d09de5f0351 --- M src/Makefile.am M src/viterbi.c M src/viterbi_gen.c A src/viterbi_sse.c 4 files changed, 746 insertions(+), 19 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/54/2454/2 diff --git a/src/Makefile.am b/src/Makefile.am index 999436d..2f19838 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -19,6 +19,10 @@ macaddr.c stat_item.c stats.c stats_statsd.c prim.c \ viterbi.c viterbi_gen.c +if HAVE_SSE3 +libosmocore_la_SOURCES += viterbi_sse.c +endif + BUILT_SOURCES = crc8gen.c crc16gen.c crc32gen.c crc64gen.c if ENABLE_PLUGIN diff --git a/src/viterbi.c b/src/viterbi.c index ea4fb21..d68db23 100644 --- a/src/viterbi.c +++ b/src/viterbi.c @@ -24,12 +24,34 @@ #include #include -#include #include "config.h" + +#include #define BIT2NRZ(REG,N) (((REG >> N) & 0x01) * 2 - 1) * -1 #define NUM_STATES(K) (K == 7 ? 64 : 16) -#define SSE_ALIGN 16 + +static int init_complete = 0; + +__attribute__ ((visibility("hidden"))) int avx2_supported = 0; +__attribute__ ((visibility("hidden"))) int sse3_supported = 0; +__attribute__ ((visibility("hidden"))) int sse41_supported = 0; + +/** + * This pointers will be initialized by the osmo_conv_init() + * depending on supported SIMD extensions. + */ +static int16_t *(*vdec_malloc)(size_t n); +static void (*vdec_free)(int16_t *ptr); + +/* Forward malloc wrappers */ +int16_t *osmo_conv_vdec_malloc(size_t n); +void osmo_conv_vdec_free(int16_t *ptr); + +#ifdef HAVE_SSE3 +int16_t *osmo_conv_vdec_malloc_sse3(size_t n); +void osmo_conv_vdec_free_sse3(int16_t *ptr); +#endif /* Forward Metric Units */ void osmo_conv_gen_metrics_k5_n2(const int8_t *seq, const int16_t *out, @@ -44,6 +66,21 @@ int16_t *sums, int16_t *paths, int norm); void osmo_conv_gen_metrics_k7_n4(const int8_t *seq, const int16_t *out, int16_t *sums, int16_t *paths, int norm); + +#ifdef HAVE_SSE3 +void osmo_conv_gen_metrics_k5_n2_sse(const int8_t *seq, const int16_t *out, + int16_t *sums, int16_t *paths, int norm); +void osmo_conv_gen_metrics_k5_n3_sse(const int8_t *seq, const int16_t *out, + int16_t *sums, int16_t *paths, int norm); +void osmo_conv_gen_metrics_k5_n4_sse(const int8_t *seq, const int16_t *out, + int16_t *sums, int16_t *paths, int norm); +void osmo_conv_gen_metrics_k7_n2_sse(const int8_t *seq, const int16_t *out, + int16_t *sums, int16_t *paths, int norm); +void osmo_conv_gen_metrics_k7_n3_sse(const int8_t *seq, const int16_t *out, + int16_t *sums, int16_t *paths, int norm); +void osmo_conv_gen_metrics_k7_n4_sse(const int8_t *seq, const int16_t *out, + int16_t *sums, int16_t *paths, int norm); +#endif /* Trellis State * state - Internal lshift register value @@ -90,20 +127,6 @@ void (*metric_func)(const int8_t *, const int16_t *, int16_t *, int16_t *, int); }; - -/* Aligned Memory Allocator - * SSE requires 16-byte memory alignment. We store relevant trellis values - * (accumulated sums, outputs, and path decisions) as 16 bit signed integers - * so the allocated memory is casted as such. - */ -static int16_t *vdec_malloc(size_t n) -{ -#ifdef HAVE_SSE3 - return (int16_t *) memalign(SSE_ALIGN, sizeof(int16_t) * n); -#else - return (int16_t *) malloc(sizeof(int16_t) * n); -#endif -} /* Accessor calls */ static inline int conv_code_recursive(const struct osmo_conv_code *code) @@ -303,9 +326,9 @@ if (!trellis) return; + vdec_free(trellis->outputs); + vdec_free(trellis->sums); free(trellis->vals); - free(trellis->outputs); - free(trellis->sums); free(trellis); } @@ -439,7 +462,7 @@ if (!dec) return; - free(dec->paths[0]); + vdec_free(dec->paths[0]); free(dec->paths); free_trellis(dec->trellis); free(dec); @@ -465,13 +488,31 @@ if (dec->k == 5) { switch (dec->n) { case 2: + #ifdef HAVE_SSE3 + dec->metric_func = !sse3_supported ? + osmo_conv_gen_metrics_k5_n2 : + osmo_conv_gen_metrics_k5_n2_sse; + #else dec->metric_func = osmo_conv_gen_metrics_k5_n2; + #endif break; case 3: + #ifdef HAVE_SSE3 + dec->metric_func = !sse3_supported ? + osmo_conv_gen_metrics_k5_n3 : + osmo_conv_gen_metrics_k5_n3_sse; + #else dec->metric_func = osmo_conv_gen_metrics_k5_n3; + #endif break; case 4: + #ifdef HAVE_SSE3 + dec->metric_func = !sse3_supported ? + osmo_conv_gen_metrics_k5_n4 : + osmo_conv_gen_metrics_k5_n4_sse; + #else dec->metric_func = osmo_conv_gen_metrics_k5_n4; + #endif break; default: goto fail; @@ -479,13 +520,31 @@ } else if (dec->k == 7) { switch (dec->n) { case 2: + #ifdef HAVE_SSE3 + dec->metric_func = !sse3_supported ? + osmo_conv_gen_metrics_k7_n2 : + osmo_conv_gen_metrics_k7_n2_sse; + #else dec->metric_func = osmo_conv_gen_metrics_k7_n2; + #endif break; case 3: + #ifdef HAVE_SSE3 + dec->metric_func = !sse3_supported ? + osmo_conv_gen_metrics_k7_n3 : + osmo_conv_gen_metrics_k7_n3_sse; + #else dec->metric_func = osmo_conv_gen_metrics_k7_n3; + #endif break; case 4: + #ifdef HAVE_SSE3 + dec->metric_func = !sse3_supported ? + osmo_conv_gen_metrics_k7_n4 : + osmo_conv_gen_metrics_k7_n4_sse; + #else dec->metric_func = osmo_conv_gen_metrics_k7_n4; + #endif break; default: goto fail; @@ -578,6 +637,36 @@ return traceback(dec, out, term, len); } +static void osmo_conv_init(void) +{ + init_complete = 1; + +#if (defined(__GNUC__) && !defined(__clang__)) + /* Detect CPU capabilities */ + #ifdef HAVE_AVX2 + avx2_supported = __builtin_cpu_supports("avx2"); + #endif + + #ifdef HAVE_SSE3 + sse3_supported = __builtin_cpu_supports("sse3"); + #endif + + #ifdef HAVE_SSE4_1 + sse41_supported = __builtin_cpu_supports("sse4.1"); + #endif +#endif + +#ifdef HAVE_SSE3 + vdec_malloc = !sse3_supported ? + &osmo_conv_vdec_malloc : &osmo_conv_vdec_malloc_sse3; + vdec_free = !sse3_supported ? + &osmo_conv_vdec_free : &osmo_conv_vdec_free_sse3; +#else + vdec_malloc = &osmo_conv_vdec_malloc; + vdec_free = &osmo_conv_vdec_free; +#endif +} + /* All-in-one Viterbi decoding */ int osmo_conv_decode_acc(const struct osmo_conv_code *code, const sbit_t *input, ubit_t *output) @@ -585,6 +674,9 @@ int rc; struct vdecoder *vdec; + if (!init_complete) + osmo_conv_init(); + if ((code->N < 2) || (code->N > 4) || (code->len < 1) || ((code->K != 5) && (code->K != 7))) return -EINVAL; diff --git a/src/viterbi_gen.c b/src/viterbi_gen.c index 7972c39..2ced615 100644 --- a/src/viterbi_gen.c +++ b/src/viterbi_gen.c @@ -20,6 +20,7 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#include #include #include @@ -126,6 +127,19 @@ memcpy(sums, new_sums, num_states * sizeof(int16_t)); } +/* Not-aligned Memory Allocator */ +__attribute__ ((visibility("hidden"))) +int16_t *osmo_conv_vdec_malloc(size_t n) +{ + return (int16_t *) malloc(sizeof(int16_t) * n); +} + +__attribute__ ((visibility("hidden"))) +void osmo_conv_vdec_free(int16_t *ptr) +{ + free(ptr); +} + /* 16-state branch-path metrics units (K=5) */ __attribute__ ((visibility("hidden"))) void osmo_conv_gen_metrics_k5_n2(const int8_t *seq, const int16_t *out, diff --git a/src/viterbi_sse.c b/src/viterbi_sse.c new file mode 100644 index 0000000..982c59f --- /dev/null +++ b/src/viterbi_sse.c @@ -0,0 +1,617 @@ +/* + * Intel SSE Viterbi decoder + * + * Copyright (C) 2013, 2014 Thomas Tsou + * + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include +#include +#include +#include + +#include "config.h" + +#if defined(HAVE_SSE4_1) || defined(HAVE_SSE41) + #include +#endif + +#ifdef HAVE_AVX2 + #include +#endif + +#define SSE_ALIGN 16 + +extern int sse41_supported; +extern int sse3_supported; +extern int avx2_supported; + +/* Octo-Viterbi butterfly + * Compute 8-wide butterfly generating 16 path decisions and 16 accumulated + * sums. Inputs all packed 16-bit integers in three 128-bit XMM registers. + * Two intermediate registers are used and results are set in the upper 4 + * registers. + * + * Input: + * M0 - Path metrics 0 (packed 16-bit integers) + * M1 - Path metrics 1 (packed 16-bit integers) + * M2 - Branch metrics (packed 16-bit integers) + * + * Output: + * M2 - Selected and accumulated path metrics 0 + * M4 - Selected and accumulated path metrics 1 + * M3 - Path selections 0 + * M1 - Path selections 1 + */ +#define SSE_BUTTERFLY(M0, M1, M2, M3, M4) \ +{ \ + M3 = _mm_adds_epi16(M0, M2); \ + M4 = _mm_subs_epi16(M1, M2); \ + M0 = _mm_subs_epi16(M0, M2); \ + M1 = _mm_adds_epi16(M1, M2); \ + M2 = _mm_max_epi16(M3, M4); \ + M3 = _mm_cmpgt_epi16(M3, M4); \ + M4 = _mm_max_epi16(M0, M1); \ + M1 = _mm_cmpgt_epi16(M0, M1); \ +} + +/* Two lane deinterleaving K = 5: + * Take 16 interleaved 16-bit integers and deinterleave to 2 packed 128-bit + * registers. The operation summarized below. Four registers are used with + * the lower 2 as input and upper 2 as output. + * + * In - 10101010 10101010 10101010 10101010 + * Out - 00000000 11111111 00000000 11111111 + * + * Input: + * M0:1 - Packed 16-bit integers + * + * Output: + * M2:3 - Deinterleaved packed 16-bit integers + */ +#define _I8_SHUFFLE_MASK 15, 14, 11, 10, 7, 6, 3, 2, 13, 12, 9, 8, 5, 4, 1, 0 + +#define SSE_DEINTERLEAVE_K5(M0, M1, M2, M3) \ +{ \ + M2 = _mm_set_epi8(_I8_SHUFFLE_MASK); \ + M0 = _mm_shuffle_epi8(M0, M2); \ + M1 = _mm_shuffle_epi8(M1, M2); \ + M2 = _mm_unpacklo_epi64(M0, M1); \ + M3 = _mm_unpackhi_epi64(M0, M1); \ +} + +/* Two lane deinterleaving K = 7: + * Take 64 interleaved 16-bit integers and deinterleave to 8 packed 128-bit + * registers. The operation summarized below. 16 registers are used with the + * lower 8 as input and upper 8 as output. + * + * In - 10101010 10101010 10101010 10101010 ... + * Out - 00000000 11111111 00000000 11111111 ... + * + * Input: + * M0:7 - Packed 16-bit integers + * + * Output: + * M8:15 - Deinterleaved packed 16-bit integers + */ +#define SSE_DEINTERLEAVE_K7(M0, M1, M2, M3, M4, M5, M6, M7, \ + M8, M9, M10, M11, M12, M13, M14, M15) \ +{ \ + M8 = _mm_set_epi8(_I8_SHUFFLE_MASK); \ + M0 = _mm_shuffle_epi8(M0, M8); \ + M1 = _mm_shuffle_epi8(M1, M8); \ + M2 = _mm_shuffle_epi8(M2, M8); \ + M3 = _mm_shuffle_epi8(M3, M8); \ + M4 = _mm_shuffle_epi8(M4, M8); \ + M5 = _mm_shuffle_epi8(M5, M8); \ + M6 = _mm_shuffle_epi8(M6, M8); \ + M7 = _mm_shuffle_epi8(M7, M8); \ + M8 = _mm_unpacklo_epi64(M0, M1); \ + M9 = _mm_unpackhi_epi64(M0, M1); \ + M10 = _mm_unpacklo_epi64(M2, M3); \ + M11 = _mm_unpackhi_epi64(M2, M3); \ + M12 = _mm_unpacklo_epi64(M4, M5); \ + M13 = _mm_unpackhi_epi64(M4, M5); \ + M14 = _mm_unpacklo_epi64(M6, M7); \ + M15 = _mm_unpackhi_epi64(M6, M7); \ +} + +/* Generate branch metrics N = 2: + * Compute 16 branch metrics from trellis outputs and input values. + * + * Input: + * M0:3 - 16 x 2 packed 16-bit trellis outputs + * M4 - Expanded and packed 16-bit input value + * + * Output: + * M6:7 - 16 computed 16-bit branch metrics + */ +#define SSE_BRANCH_METRIC_N2(M0, M1, M2, M3, M4, M6, M7) \ +{ \ + M0 = _mm_sign_epi16(M4, M0); \ + M1 = _mm_sign_epi16(M4, M1); \ + M2 = _mm_sign_epi16(M4, M2); \ + M3 = _mm_sign_epi16(M4, M3); \ + M6 = _mm_hadds_epi16(M0, M1); \ + M7 = _mm_hadds_epi16(M2, M3); \ +} + +/* Generate branch metrics N = 4: + * Compute 8 branch metrics from trellis outputs and input values. This + * macro is reused for N less than 4 where the extra soft input bits are + * padded. + * + * Input: + * M0:3 - 8 x 4 packed 16-bit trellis outputs + * M4 - Expanded and packed 16-bit input value + * + * Output: + * M5 - 8 computed 16-bit branch metrics + */ +#define SSE_BRANCH_METRIC_N4(M0, M1, M2, M3, M4, M5) \ +{ \ + M0 = _mm_sign_epi16(M4, M0); \ + M1 = _mm_sign_epi16(M4, M1); \ + M2 = _mm_sign_epi16(M4, M2); \ + M3 = _mm_sign_epi16(M4, M3); \ + M0 = _mm_hadds_epi16(M0, M1); \ + M1 = _mm_hadds_epi16(M2, M3); \ + M5 = _mm_hadds_epi16(M0, M1); \ +} + +/* Broadcast 16-bit integer + * Repeat the low 16-bit integer to all elements of the 128-bit SSE + * register. Only AVX2 has a dedicated broadcast instruction; use repeat + * unpacks for SSE only architectures. This is a destructive operation and + * the source register is overwritten. + * + * Input: + * M0 - Low 16-bit element is read + * + * Output: + * M0 - Contains broadcasted values + */ +#ifdef HAVE_AVX2 +#define SSE_BROADCAST(M0) \ +{ \ + if (avx2_supported) { \ + M0 = _mm_broadcastw_epi16(M0); \ + } else { \ + M0 = _mm_unpacklo_epi16(M0, M0); \ + M0 = _mm_unpacklo_epi32(M0, M0); \ + M0 = _mm_unpacklo_epi64(M0, M0); \ + } \ +} +#else +#define SSE_BROADCAST(M0) \ +{ \ + M0 = _mm_unpacklo_epi16(M0, M0); \ + M0 = _mm_unpacklo_epi32(M0, M0); \ + M0 = _mm_unpacklo_epi64(M0, M0); \ +} +#endif + +/* Horizontal minimum + * Compute horizontal minimum of packed unsigned 16-bit integers and place + * result in the low 16-bit element of the source register. Only SSE 4.1 + * has a dedicated minpos instruction. One intermediate register is used + * if SSE 4.1 is not available. This is a destructive operation and the + * source register is overwritten. + * + * Input: + * M0 - Packed unsigned 16-bit integers + * + * Output: + * M0 - Minimum value placed in low 16-bit element + */ +#if defined(HAVE_SSE4_1) || defined(HAVE_SSE41) +#define SSE_MINPOS(M0, M1) \ +{ \ + if (sse41_supported) { \ + M0 = _mm_minpos_epu16(M0); \ + } else { \ + M1 = _mm_shuffle_epi32(M0, _MM_SHUFFLE(0, 0, 3, 2)); \ + M0 = _mm_min_epi16(M0, M1); \ + M1 = _mm_shufflelo_epi16(M0, _MM_SHUFFLE(0, 0, 3, 2)); \ + M0 = _mm_min_epi16(M0, M1); \ + M1 = _mm_shufflelo_epi16(M0, _MM_SHUFFLE(0, 0, 0, 1)); \ + M0 = _mm_min_epi16(M0, M1); \ + } \ +} +#else +#define SSE_MINPOS(M0, M1) \ +{ \ + M1 = _mm_shuffle_epi32(M0, _MM_SHUFFLE(0, 0, 3, 2)); \ + M0 = _mm_min_epi16(M0, M1); \ + M1 = _mm_shufflelo_epi16(M0, _MM_SHUFFLE(0, 0, 3, 2)); \ + M0 = _mm_min_epi16(M0, M1); \ + M1 = _mm_shufflelo_epi16(M0, _MM_SHUFFLE(0, 0, 0, 1)); \ + M0 = _mm_min_epi16(M0, M1); \ +} +#endif + +/* Normalize state metrics K = 5: + * Compute 16-wide normalization by subtracting the smallest value from + * all values. Inputs are 16 packed 16-bit integers across 2 XMM registers. + * Two intermediate registers are used and normalized results are placed + * in the originating locations. + * + * Input: + * M0:1 - Path metrics 0:1 (packed 16-bit integers) + * + * Output: + * M0:1 - Normalized path metrics 0:1 + */ +#define SSE_NORMALIZE_K5(M0, M1, M2, M3) \ +{ \ + M2 = _mm_min_epi16(M0, M1); \ + SSE_MINPOS(M2, M3) \ + SSE_BROADCAST(M2) \ + M0 = _mm_subs_epi16(M0, M2); \ + M1 = _mm_subs_epi16(M1, M2); \ +} + +/* Normalize state metrics K = 7: + * Compute 64-wide normalization by subtracting the smallest value from + * all values. Inputs are 8 registers of accumulated sums and 4 temporary + * registers. Normalized results are returned in the originating locations. + * + * Input: + * M0:7 - Path metrics 0:7 (packed 16-bit integers) + * + * Output: + * M0:7 - Normalized path metrics 0:7 + */ +#define SSE_NORMALIZE_K7(M0, M1, M2, M3, M4, M5, M6, M7, M8, M9, M10, M11) \ +{ \ + M8 = _mm_min_epi16(M0, M1); \ + M9 = _mm_min_epi16(M2, M3); \ + M10 = _mm_min_epi16(M4, M5); \ + M11 = _mm_min_epi16(M6, M7); \ + M8 = _mm_min_epi16(M8, M9); \ + M10 = _mm_min_epi16(M10, M11); \ + M8 = _mm_min_epi16(M8, M10); \ + SSE_MINPOS(M8, M9) \ + SSE_BROADCAST(M8) \ + M0 = _mm_subs_epi16(M0, M8); \ + M1 = _mm_subs_epi16(M1, M8); \ + M2 = _mm_subs_epi16(M2, M8); \ + M3 = _mm_subs_epi16(M3, M8); \ + M4 = _mm_subs_epi16(M4, M8); \ + M5 = _mm_subs_epi16(M5, M8); \ + M6 = _mm_subs_epi16(M6, M8); \ + M7 = _mm_subs_epi16(M7, M8); \ +} + +/* Combined BMU/PMU (K=5, N=2) + * Compute branch metrics followed by path metrics for half rate 16-state + * trellis. 8 butterflies are computed. Accumulated path sums are not + * preserved and read and written into the same memory location. Normalize + * sums if requires. + */ +__always_inline static void _sse_metrics_k5_n2(const int16_t *val, + const int16_t *out, int16_t *sums, int16_t *paths, int norm) +{ + __m128i m0, m1, m2, m3, m4, m5, m6; + + /* (BMU) Load input sequence */ + m2 = _mm_castpd_si128(_mm_loaddup_pd((double const *) val)); + + /* (BMU) Load trellis outputs */ + m0 = _mm_load_si128((__m128i *) &out[0]); + m1 = _mm_load_si128((__m128i *) &out[8]); + + /* (BMU) Compute branch metrics */ + m0 = _mm_sign_epi16(m2, m0); + m1 = _mm_sign_epi16(m2, m1); + m2 = _mm_hadds_epi16(m0, m1); + + /* (PMU) Load accumulated path metrics */ + m0 = _mm_load_si128((__m128i *) &sums[0]); + m1 = _mm_load_si128((__m128i *) &sums[8]); + + SSE_DEINTERLEAVE_K5(m0, m1, m3, m4) + + /* (PMU) Butterflies: 0-7 */ + SSE_BUTTERFLY(m3, m4, m2, m5, m6) + + if (norm) + SSE_NORMALIZE_K5(m2, m6, m0, m1) + + _mm_store_si128((__m128i *) &sums[0], m2); + _mm_store_si128((__m128i *) &sums[8], m6); + _mm_store_si128((__m128i *) &paths[0], m5); + _mm_store_si128((__m128i *) &paths[8], m4); +} + +/* Combined BMU/PMU (K=5, N=3 and N=4) + * Compute branch metrics followed by path metrics for 16-state and rates + * to 1/4. 8 butterflies are computed. The input sequence is read four 16-bit + * values at a time, and extra values should be set to zero for rates other + * than 1/4. Normally only rates 1/3 and 1/4 are used as there is a + * dedicated implementation of rate 1/2. + */ +__always_inline static void _sse_metrics_k5_n4(const int16_t *val, + const int16_t *out, int16_t *sums, int16_t *paths, int norm) +{ + __m128i m0, m1, m2, m3, m4, m5, m6; + + /* (BMU) Load input sequence */ + m4 = _mm_castpd_si128(_mm_loaddup_pd((double const *) val)); + + /* (BMU) Load trellis outputs */ + m0 = _mm_load_si128((__m128i *) &out[0]); + m1 = _mm_load_si128((__m128i *) &out[8]); + m2 = _mm_load_si128((__m128i *) &out[16]); + m3 = _mm_load_si128((__m128i *) &out[24]); + + SSE_BRANCH_METRIC_N4(m0, m1, m2, m3, m4, m2) + + /* (PMU) Load accumulated path metrics */ + m0 = _mm_load_si128((__m128i *) &sums[0]); + m1 = _mm_load_si128((__m128i *) &sums[8]); + + SSE_DEINTERLEAVE_K5(m0, m1, m3, m4) + + /* (PMU) Butterflies: 0-7 */ + SSE_BUTTERFLY(m3, m4, m2, m5, m6) + + if (norm) + SSE_NORMALIZE_K5(m2, m6, m0, m1) + + _mm_store_si128((__m128i *) &sums[0], m2); + _mm_store_si128((__m128i *) &sums[8], m6); + _mm_store_si128((__m128i *) &paths[0], m5); + _mm_store_si128((__m128i *) &paths[8], m4); +} + +/* Combined BMU/PMU (K=7, N=2) + * Compute branch metrics followed by path metrics for half rate 64-state + * trellis. 32 butterfly operations are computed. Deinterleaving path + * metrics requires usage of the full SSE register file, so separate sums + * before computing branch metrics to avoid register spilling. + */ +__always_inline static void _sse_metrics_k7_n2(const int16_t *val, + const int16_t *out, int16_t *sums, int16_t *paths, int norm) +{ + __m128i m0, m1, m2, m3, m4, m5, m6, m7, m8, + m9, m10, m11, m12, m13, m14, m15; + + /* (PMU) Load accumulated path metrics */ + m0 = _mm_load_si128((__m128i *) &sums[0]); + m1 = _mm_load_si128((__m128i *) &sums[8]); + m2 = _mm_load_si128((__m128i *) &sums[16]); + m3 = _mm_load_si128((__m128i *) &sums[24]); + m4 = _mm_load_si128((__m128i *) &sums[32]); + m5 = _mm_load_si128((__m128i *) &sums[40]); + m6 = _mm_load_si128((__m128i *) &sums[48]); + m7 = _mm_load_si128((__m128i *) &sums[56]); + + /* (PMU) Deinterleave to even-odd registers */ + SSE_DEINTERLEAVE_K7(m0, m1, m2, m3 ,m4 ,m5, m6, m7, + m8, m9, m10, m11, m12, m13, m14, m15) + + /* (BMU) Load input symbols */ + m7 = _mm_castpd_si128(_mm_loaddup_pd((double const *) val)); + + /* (BMU) Load trellis outputs */ + m0 = _mm_load_si128((__m128i *) &out[0]); + m1 = _mm_load_si128((__m128i *) &out[8]); + m2 = _mm_load_si128((__m128i *) &out[16]); + m3 = _mm_load_si128((__m128i *) &out[24]); + + SSE_BRANCH_METRIC_N2(m0, m1, m2, m3, m7, m4, m5) + + m0 = _mm_load_si128((__m128i *) &out[32]); + m1 = _mm_load_si128((__m128i *) &out[40]); + m2 = _mm_load_si128((__m128i *) &out[48]); + m3 = _mm_load_si128((__m128i *) &out[56]); + + SSE_BRANCH_METRIC_N2(m0, m1, m2, m3, m7, m6, m7) + + /* (PMU) Butterflies: 0-15 */ + SSE_BUTTERFLY(m8, m9, m4, m0, m1) + SSE_BUTTERFLY(m10, m11, m5, m2, m3) + + _mm_store_si128((__m128i *) &paths[0], m0); + _mm_store_si128((__m128i *) &paths[8], m2); + _mm_store_si128((__m128i *) &paths[32], m9); + _mm_store_si128((__m128i *) &paths[40], m11); + + /* (PMU) Butterflies: 17-31 */ + SSE_BUTTERFLY(m12, m13, m6, m0, m2) + SSE_BUTTERFLY(m14, m15, m7, m9, m11) + + _mm_store_si128((__m128i *) &paths[16], m0); + _mm_store_si128((__m128i *) &paths[24], m9); + _mm_store_si128((__m128i *) &paths[48], m13); + _mm_store_si128((__m128i *) &paths[56], m15); + + if (norm) + SSE_NORMALIZE_K7(m4, m1, m5, m3, m6, m2, + m7, m11, m0, m8, m9, m10) + + _mm_store_si128((__m128i *) &sums[0], m4); + _mm_store_si128((__m128i *) &sums[8], m5); + _mm_store_si128((__m128i *) &sums[16], m6); + _mm_store_si128((__m128i *) &sums[24], m7); + _mm_store_si128((__m128i *) &sums[32], m1); + _mm_store_si128((__m128i *) &sums[40], m3); + _mm_store_si128((__m128i *) &sums[48], m2); + _mm_store_si128((__m128i *) &sums[56], m11); +} + +/* Combined BMU/PMU (K=7, N=3 and N=4) + * Compute branch metrics followed by path metrics for half rate 64-state + * trellis. 32 butterfly operations are computed. Deinterleave path + * metrics before computing branch metrics as in the half rate case. + */ +__always_inline static void _sse_metrics_k7_n4(const int16_t *val, + const int16_t *out, int16_t *sums, int16_t *paths, int norm) +{ + __m128i m0, m1, m2, m3, m4, m5, m6, m7; + __m128i m8, m9, m10, m11, m12, m13, m14, m15; + + /* (PMU) Load accumulated path metrics */ + m0 = _mm_load_si128((__m128i *) &sums[0]); + m1 = _mm_load_si128((__m128i *) &sums[8]); + m2 = _mm_load_si128((__m128i *) &sums[16]); + m3 = _mm_load_si128((__m128i *) &sums[24]); + m4 = _mm_load_si128((__m128i *) &sums[32]); + m5 = _mm_load_si128((__m128i *) &sums[40]); + m6 = _mm_load_si128((__m128i *) &sums[48]); + m7 = _mm_load_si128((__m128i *) &sums[56]); + + /* (PMU) Deinterleave into even and odd packed registers */ + SSE_DEINTERLEAVE_K7(m0, m1, m2, m3 ,m4 ,m5, m6, m7, + m8, m9, m10, m11, m12, m13, m14, m15) + + /* (BMU) Load and expand 8-bit input out to 16-bits */ + m7 = _mm_castpd_si128(_mm_loaddup_pd((double const *) val)); + + /* (BMU) Load and compute branch metrics */ + m0 = _mm_load_si128((__m128i *) &out[0]); + m1 = _mm_load_si128((__m128i *) &out[8]); + m2 = _mm_load_si128((__m128i *) &out[16]); + m3 = _mm_load_si128((__m128i *) &out[24]); + + SSE_BRANCH_METRIC_N4(m0, m1, m2, m3, m7, m4) + + m0 = _mm_load_si128((__m128i *) &out[32]); + m1 = _mm_load_si128((__m128i *) &out[40]); + m2 = _mm_load_si128((__m128i *) &out[48]); + m3 = _mm_load_si128((__m128i *) &out[56]); + + SSE_BRANCH_METRIC_N4(m0, m1, m2, m3, m7, m5) + + m0 = _mm_load_si128((__m128i *) &out[64]); + m1 = _mm_load_si128((__m128i *) &out[72]); + m2 = _mm_load_si128((__m128i *) &out[80]); + m3 = _mm_load_si128((__m128i *) &out[88]); + + SSE_BRANCH_METRIC_N4(m0, m1, m2, m3, m7, m6) + + m0 = _mm_load_si128((__m128i *) &out[96]); + m1 = _mm_load_si128((__m128i *) &out[104]); + m2 = _mm_load_si128((__m128i *) &out[112]); + m3 = _mm_load_si128((__m128i *) &out[120]); + + SSE_BRANCH_METRIC_N4(m0, m1, m2, m3, m7, m7) + + /* (PMU) Butterflies: 0-15 */ + SSE_BUTTERFLY(m8, m9, m4, m0, m1) + SSE_BUTTERFLY(m10, m11, m5, m2, m3) + + _mm_store_si128((__m128i *) &paths[0], m0); + _mm_store_si128((__m128i *) &paths[8], m2); + _mm_store_si128((__m128i *) &paths[32], m9); + _mm_store_si128((__m128i *) &paths[40], m11); + + /* (PMU) Butterflies: 17-31 */ + SSE_BUTTERFLY(m12, m13, m6, m0, m2) + SSE_BUTTERFLY(m14, m15, m7, m9, m11) + + _mm_store_si128((__m128i *) &paths[16], m0); + _mm_store_si128((__m128i *) &paths[24], m9); + _mm_store_si128((__m128i *) &paths[48], m13); + _mm_store_si128((__m128i *) &paths[56], m15); + + if (norm) + SSE_NORMALIZE_K7(m4, m1, m5, m3, m6, m2, + m7, m11, m0, m8, m9, m10) + + _mm_store_si128((__m128i *) &sums[0], m4); + _mm_store_si128((__m128i *) &sums[8], m5); + _mm_store_si128((__m128i *) &sums[16], m6); + _mm_store_si128((__m128i *) &sums[24], m7); + _mm_store_si128((__m128i *) &sums[32], m1); + _mm_store_si128((__m128i *) &sums[40], m3); + _mm_store_si128((__m128i *) &sums[48], m2); + _mm_store_si128((__m128i *) &sums[56], m11); +} + +/* Aligned Memory Allocator + * SSE requires 16-byte memory alignment. We store relevant trellis values + * (accumulated sums, outputs, and path decisions) as 16 bit signed integers + * so the allocated memory is casted as such. + */ +__attribute__ ((visibility("hidden"))) +int16_t *osmo_conv_vdec_malloc_sse3(size_t n) +{ + return (int16_t *) _mm_malloc(sizeof(int16_t) * n, SSE_ALIGN); +} + +__attribute__ ((visibility("hidden"))) +void osmo_conv_vdec_free_sse3(int16_t *ptr) +{ + _mm_free(ptr); +} + +__attribute__ ((visibility("hidden"))) +void osmo_conv_gen_metrics_k5_n2_sse(const int8_t *val, const int16_t *out, + int16_t *sums, int16_t *paths, int norm) +{ + const int16_t _val[4] = { val[0], val[1], val[0], val[1] }; + + _sse_metrics_k5_n2(_val, out, sums, paths, norm); +} + +__attribute__ ((visibility("hidden"))) +void osmo_conv_gen_metrics_k5_n3_sse(const int8_t *val, const int16_t *out, + int16_t *sums, int16_t *paths, int norm) +{ + const int16_t _val[4] = { val[0], val[1], val[2], 0 }; + + _sse_metrics_k5_n4(_val, out, sums, paths, norm); +} + +__attribute__ ((visibility("hidden"))) +void osmo_conv_gen_metrics_k5_n4_sse(const int8_t *val, const int16_t *out, + int16_t *sums, int16_t *paths, int norm) +{ + const int16_t _val[4] = { val[0], val[1], val[2], val[3] }; + + _sse_metrics_k5_n4(_val, out, sums, paths, norm); +} + +__attribute__ ((visibility("hidden"))) +void osmo_conv_gen_metrics_k7_n2_sse(const int8_t *val, const int16_t *out, + int16_t *sums, int16_t *paths, int norm) +{ + const int16_t _val[4] = { val[0], val[1], val[0], val[1] }; + + _sse_metrics_k7_n2(_val, out, sums, paths, norm); +} + +__attribute__ ((visibility("hidden"))) +void osmo_conv_gen_metrics_k7_n3_sse(const int8_t *val, const int16_t *out, + int16_t *sums, int16_t *paths, int norm) +{ + const int16_t _val[4] = { val[0], val[1], val[2], 0 }; + + _sse_metrics_k7_n4(_val, out, sums, paths, norm); +} + +__attribute__ ((visibility("hidden"))) +void osmo_conv_gen_metrics_k7_n4_sse(const int8_t *val, const int16_t *out, + int16_t *sums, int16_t *paths, int norm) +{ + const int16_t _val[4] = { val[0], val[1], val[2], val[3] }; + + _sse_metrics_k7_n4(_val, out, sums, paths, norm); +} -- To view, visit https://gerrit.osmocom.org/2454 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I1da6d71ed0564f1d684f3a836e998d09de5f0351 Gerrit-PatchSet: 2 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Vadim Yanitskiy Gerrit-Reviewer: Jenkins Builder From gerrit-no-reply at lists.osmocom.org Sun Apr 30 17:42:06 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 30 Apr 2017 17:42:06 +0000 Subject: libosmocore[master]: tests/conv: add GSM 05.03 specific test In-Reply-To: References: Message-ID: Patch Set 7: Code-Review+2 deferring to Tom's judgement here, but generally it looks fine to me, and if there are issues remaining, they can be adressed later on. -- To view, visit https://gerrit.osmocom.org/1628 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I76d1cd4032d2f74c5bb93bde4fab99aa655b7f1a Gerrit-PatchSet: 7 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Vadim Yanitskiy Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Neels Hofmeyr Gerrit-Reviewer: Tom Tsou Gerrit-Reviewer: Vadim Yanitskiy Gerrit-Reviewer: tnt Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sun Apr 30 17:43:38 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 30 Apr 2017 17:43:38 +0000 Subject: libosmocore[master]: core/conv: add x86 SSE support for Viterbi decoder In-Reply-To: References: Message-ID: Patch Set 2: (1 comment) https://gerrit.osmocom.org/#/c/2454/2//COMMIT_MSG Commit Message: Line 11: is the minimal requirement. SSE4.1 and AVX2 are used if available. Do you mean this patch introduces a mandatory requirement for SSE3 capable CPUs? if so, it is not acceptable. -- To view, visit https://gerrit.osmocom.org/2454 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I1da6d71ed0564f1d684f3a836e998d09de5f0351 Gerrit-PatchSet: 2 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Vadim Yanitskiy Gerrit-Reviewer: Alexander Chemeris Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Tom Tsou Gerrit-Reviewer: dexter Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Sun Apr 30 17:49:35 2017 From: gerrit-no-reply at lists.osmocom.org (Vadim Yanitskiy) Date: Sun, 30 Apr 2017 17:49:35 +0000 Subject: libosmocore[master]: core/conv: add x86 SSE support for Viterbi decoder In-Reply-To: References: Message-ID: Patch Set 2: > (1 comment) No, of course. SSE3 support is mandatory for accelerated Viterbi implementation only (viterbi_sse.c). If SSE3 isn't supported by target CPU, then not-accelerated Viterbi implementation will be used (viterbi_sse.c). BTW: I forgot to change commit author :( -- To view, visit https://gerrit.osmocom.org/2454 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I1da6d71ed0564f1d684f3a836e998d09de5f0351 Gerrit-PatchSet: 2 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Vadim Yanitskiy Gerrit-Reviewer: Alexander Chemeris Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-Reviewer: Tom Tsou Gerrit-Reviewer: Vadim Yanitskiy Gerrit-Reviewer: dexter Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sun Apr 30 18:26:33 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 30 Apr 2017 18:26:33 +0000 Subject: mncc-python[master]: mncc: Make it possible to build a MNCC server for testing In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2451 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I8387fe1687557c6a1a26ff1e0cc9dbff3087aa82 Gerrit-PatchSet: 1 Gerrit-Project: mncc-python Gerrit-Branch: master Gerrit-Owner: Holger Freyther Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sun Apr 30 18:26:37 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 30 Apr 2017 18:26:37 +0000 Subject: mncc-python[master]: mncc: Make it possible to build a MNCC server for testing In-Reply-To: References: Message-ID: Patch Set 1: Verified+1 -- To view, visit https://gerrit.osmocom.org/2451 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I8387fe1687557c6a1a26ff1e0cc9dbff3087aa82 Gerrit-PatchSet: 1 Gerrit-Project: mncc-python Gerrit-Branch: master Gerrit-Owner: Holger Freyther Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sun Apr 30 18:26:41 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 30 Apr 2017 18:26:41 +0000 Subject: [MERGED] mncc-python[master]: mncc: Make it possible to build a MNCC server for testing In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: mncc: Make it possible to build a MNCC server for testing ...................................................................... mncc: Make it possible to build a MNCC server for testing For manual testing the osmo-sip-connector it is nice to run a custom MNCC server to mock certain behavior. Refactor the socket class to share code between client/server. Change-Id: I8387fe1687557c6a1a26ff1e0cc9dbff3087aa82 --- M mncc_sock.py 1 file changed, 32 insertions(+), 13 deletions(-) Approvals: Harald Welte: Looks good to me, approved; Verified diff --git a/mncc_sock.py b/mncc_sock.py index 48da514..3d29691 100644 --- a/mncc_sock.py +++ b/mncc_sock.py @@ -52,21 +52,13 @@ plan = num_plan, present = num_present, screen = num_screen) -class MnccSocket(object): - def __init__(self, address = '/tmp/bsc_mncc'): - self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_SEQPACKET) - print 'connecting to %s' % address - try: - self.sock.connect(address) - except socket.error, errmsg: - print >>sys.stderr, errmsg - sys.exit(1) - - # FIXME: parse the HELLO message - msg = self.recv() - +class MnccSocketBase(object): def send(self, msg): return self.sock.sendall(msg.send()) + + def send_msg(self, msg): + data = buffer(msg)[:] + return self.sock.sendall(data) def recv(self): data = self.sock.recv(1500) @@ -76,3 +68,30 @@ ms = mncc_rtp_msg() ms.receive(data) return ms + +class MnccSocket(MnccSocketBase): + def __init__(self, address = '/tmp/bsc_mncc'): + super(MnccSocketBase, self).__init__() + self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_SEQPACKET) + print('connecting to %s' % address) + try: + self.sock.connect(address) + except socket.error as errmsg: + sys.stderr.write("%s\n" % errmsg) + sys.exit(1) + + # FIXME: parse the HELLO message + msg = self.recv() + +class MnccSocketServer(object): + def __init__(self, address = '/tmp/bsc_mncc'): + os.unlink(address) + self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_SEQPACKET) + self.sock.bind(address) + self.sock.listen(5) + + def accept(self): + (fd,_) = self.sock.accept() + sock = MnccSocketBase() + sock.sock = fd + return sock -- To view, visit https://gerrit.osmocom.org/2451 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I8387fe1687557c6a1a26ff1e0cc9dbff3087aa82 Gerrit-PatchSet: 1 Gerrit-Project: mncc-python Gerrit-Branch: master Gerrit-Owner: Holger Freyther Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Sun Apr 30 18:26:57 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 30 Apr 2017 18:26:57 +0000 Subject: mncc-python[master]: test: Add a manual test to simulate DTMF handling in osmo-si... In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 Verified+1 -- To view, visit https://gerrit.osmocom.org/2452 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I7f62efbc62455e6fcb1f091afb5fa120099834f0 Gerrit-PatchSet: 1 Gerrit-Project: mncc-python Gerrit-Branch: master Gerrit-Owner: Holger Freyther Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Neels Hofmeyr Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sun Apr 30 18:26:59 2017 From: gerrit-no-reply at lists.osmocom.org (Harald Welte) Date: Sun, 30 Apr 2017 18:26:59 +0000 Subject: [MERGED] mncc-python[master]: test: Add a manual test to simulate DTMF handling in osmo-si... In-Reply-To: References: Message-ID: Harald Welte has submitted this change and it was merged. Change subject: test: Add a manual test to simulate DTMF handling in osmo-sip-connector ...................................................................... test: Add a manual test to simulate DTMF handling in osmo-sip-connector Add a manul test to the contrib folder that helped and can help during the development of osmo-sip-connector or similar software. This avoids having to create a separate mncc module. It can be started like: $ PYTHONPATH=$PWD/../ python manual_test_server.py Change-Id: I7f62efbc62455e6fcb1f091afb5fa120099834f0 --- A contrib/manual_test_server.py 1 file changed, 126 insertions(+), 0 deletions(-) Approvals: Harald Welte: Looks good to me, approved; Verified diff --git a/contrib/manual_test_server.py b/contrib/manual_test_server.py new file mode 100644 index 0000000..5625670 --- /dev/null +++ b/contrib/manual_test_server.py @@ -0,0 +1,126 @@ +import mncc +import mncc_sock +import ctypes +import socket + +GSM340_PLAN_ISDN = 1 +GSM340_TYPE_NATIONAL = 2 + +class MnccMessageBuilder(object): + """ + I help in creating messages... + """ + @staticmethod + def build_hello(): + hello = mncc.gsm_mncc_hello() + hello.msg_type = mncc.MNCC_SOCKET_HELLO + hello.version = mncc.MNCC_SOCK_VERSION + hello.mncc_size = ctypes.sizeof(mncc.gsm_mncc) + hello.data_frame_size = ctypes.sizeof(mncc.gsm_data_frame) + hello.called_offset = mncc.gsm_mncc.called.offset + hello.signal_offset = mncc.gsm_mncc.signal.offset + hello.emergency_offset = mncc.gsm_mncc.emergency.offset + hello.lchan_type_offset = mncc.gsm_mncc.lchan_type.offset + return hello + + @staticmethod + def build_mncc_number(number): + return mncc.gsm_mncc_number( + type=GSM340_TYPE_NATIONAL, + plan=GSM340_PLAN_ISDN, + number=number) + + @staticmethod + def build_setup_ind(calling, called, callref=1): + setup = mncc.gsm_mncc() + setup.msg_type = mncc.MNCC_SETUP_IND + setup.callref = callref + setup.fields = mncc.MNCC_F_CALLED | mncc.MNCC_F_CALLING + setup.called = MnccMessageBuilder.build_mncc_number(called) + setup.calling = MnccMessageBuilder.build_mncc_number(calling) + return setup + + @staticmethod + def build_setup_cmpl_ind(callref=1): + setup = mncc.gsm_mncc() + setup.msg_type = mncc.MNCC_SETUP_COMPL_IND + setup.callref = callref + return setup + + @staticmethod + def build_rtp_msg(msg_type, callref, addr, port): + return mncc.gsm_mncc_rtp( + msg_type=msg_type, callref=callref, + ip=addr, port=port, + #payload_type=3, + #payload_msg_type=mncc.GSM_TCHF_FRAME) + payload_type=98, + payload_msg_type=mncc.GSM_TCH_FRAME_AMR) + + @staticmethod + def build_dtmf_start(callref, data): + return mncc.gsm_mncc( + msg_type=mncc.MNCC_START_DTMF_IND, + callref=callref, + fields=mncc.MNCC_F_KEYPAD, + keypad=ord(data)) + + @staticmethod + def build_dtmf_stop(callref, data): + return mncc.gsm_mncc( + callref=callref, + msg_type=mncc.MNCC_STOP_DTMF_IND) + +def send_dtmf(callref): + global conn + + conn.send_msg(MnccMessageBuilder.build_dtmf_start(callref, '1')) + conn.send_msg(MnccMessageBuilder.build_dtmf_stop(callref, '1')) + conn.send_msg(MnccMessageBuilder.build_dtmf_start(callref, '2')) + conn.send_msg(MnccMessageBuilder.build_dtmf_stop(callref, '2')) + + +server = mncc_sock.MnccSocketServer() +conn = server.accept() + +# Say hello and set-up a call +conn.send_msg(MnccMessageBuilder.build_hello()) +conn.send_msg(MnccMessageBuilder.build_setup_ind("1234", "5000")) +print("=> Sent hello + setup indication") + +# Wait for the RTP crate.. and actknowledge it.. +msg = conn.recv() +assert msg.msg_type == mncc.MNCC_RTP_CREATE +print("<= Received request to create a RTP socket") +conn.send_msg(MnccMessageBuilder.build_rtp_msg(mncc.MNCC_RTP_CREATE, + msg.callref, + #socket.INADDR_LOOPBACK, 4000)) + socket.INADDR_ANY, 4000)) +print("=> Claimed socket was created...") + +msg = conn.recv() +assert msg.msg_type == mncc.MNCC_CALL_PROC_REQ +print("<= Received proceeding...") + + + +while True: + msg = conn.recv() + if msg.msg_type == mncc.MNCC_ALERT_REQ: + print("=> I should alert...") + continue + if msg.msg_type == mncc.MNCC_RTP_CONNECT: + conn.send_msg(MnccMessageBuilder.build_rtp_msg(mncc.MNCC_RTP_CONNECT, + msg.callref, + socket.INADDR_LOOPBACK, 4000)) + print("=> I needed to connect RTP...") + continue + if msg.msg_type == mncc.MNCC_SETUP_RSP: + print("=> Call is connected?") + conn.send_msg(MnccMessageBuilder.build_setup_cmpl_ind(msg.callref)) + send_dtmf(msg.callref) + continue + + print(msg) + print(msg.msg_type) +print(type(msg)) -- To view, visit https://gerrit.osmocom.org/2452 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: merged Gerrit-Change-Id: I7f62efbc62455e6fcb1f091afb5fa120099834f0 Gerrit-PatchSet: 1 Gerrit-Project: mncc-python Gerrit-Branch: master Gerrit-Owner: Holger Freyther Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Neels Hofmeyr From gerrit-no-reply at lists.osmocom.org Sun Apr 30 21:42:25 2017 From: gerrit-no-reply at lists.osmocom.org (Holger Freyther) Date: Sun, 30 Apr 2017 21:42:25 +0000 Subject: osmo-gsm-tester[master]: gitignore: Add *.pyc In-Reply-To: References: Message-ID: Patch Set 1: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2448 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I987df905c5d64294488b5a6cdcf4306307616fc6 Gerrit-PatchSet: 1 Gerrit-Project: osmo-gsm-tester Gerrit-Branch: master Gerrit-Owner: Pau Espin Pedrol Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sun Apr 30 21:44:40 2017 From: gerrit-no-reply at lists.osmocom.org (Holger Freyther) Date: Sun, 30 Apr 2017 21:44:40 +0000 Subject: libosmocore[master]: gsm0808: fix control flow issue In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2445 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I89751fc0d598734c64ef1fdced75b7c4fa77c616 Gerrit-PatchSet: 2 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sun Apr 30 21:48:54 2017 From: gerrit-no-reply at lists.osmocom.org (Holger Freyther) Date: Sun, 30 Apr 2017 21:48:54 +0000 Subject: openbsc[master]: Make BTS type and variant converters shareable In-Reply-To: References: Message-ID: Patch Set 7: (1 comment) https://gerrit.osmocom.org/#/c/2286/7/openbsc/src/libcommon/gsm_data_shared.c File openbsc/src/libcommon/gsm_data_shared.c: Line 70: const struct value_string bts_variant_names[_NUM_BTS_VARIANT + 1] = { BikeShedding: * bts_variant.. they are all osmo-bts variants. Reflect that in the name? * In fact some of them are not BTS variants but more the Phy. So all of them are osmo-bts but have various limitations/features in the Phy (dual-trx, single-trx, no HR1, higher latency due Ethernet?) Maybe do it based on features? Have a name enable/unlock features? So something like.. can_have_multiple_sdcch8, can_be_multi_trx? -- To view, visit https://gerrit.osmocom.org/2286 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ida94725a6fce968443541e3526f48f13758031fd Gerrit-PatchSet: 7 Gerrit-Project: openbsc Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Sun Apr 30 21:52:51 2017 From: gerrit-no-reply at lists.osmocom.org (Holger Freyther) Date: Sun, 30 Apr 2017 21:52:51 +0000 Subject: osmo-trx[master]: debian: remove obsolete dependency In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+1 In two years we won't know what "latest Ubuntu" is. Always better to put a version number in there. Stretch won't have it either. -- To view, visit https://gerrit.osmocom.org/2400 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I3ea72b4123a280a846086d083c4f3189d611f8cf Gerrit-PatchSet: 2 Gerrit-Project: osmo-trx Gerrit-Branch: master Gerrit-Owner: Max Gerrit-Reviewer: Alexander Chemeris Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Tom Tsou Gerrit-Reviewer: neels Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sun Apr 30 21:54:30 2017 From: gerrit-no-reply at lists.osmocom.org (Holger Freyther) Date: Sun, 30 Apr 2017 21:54:30 +0000 Subject: libosmocore[master]: gsm0808: fixup length check of the element decoder functions In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+1 Hmm.. I would prefer to add the comments in another patch. Try to keep patches minimal and on a single topic. -- To view, visit https://gerrit.osmocom.org/2446 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I78bc887f68d1963d28c6fcd631ac20ccd893d6d6 Gerrit-PatchSet: 2 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: dexter Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-HasComments: No From gerrit-no-reply at lists.osmocom.org Sun Apr 30 21:58:12 2017 From: gerrit-no-reply at lists.osmocom.org (Holger Freyther) Date: Sun, 30 Apr 2017 21:58:12 +0000 Subject: osmo-pcu[master]: fix PACCH paging: don't return early in case of NULL TBF In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+1 (2 comments) How long did the fix take? https://gerrit.osmocom.org/#/c/2420/2/src/gprs_rlcmac_sched.cpp File src/gprs_rlcmac_sched.cpp: Line 186: return NULL; msg is leaked now? Line 202: return msg; okay but we might still have a tbf here? -- To view, visit https://gerrit.osmocom.org/2420 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: Ib79f4a945e211a13ac7d1e511cc37b0940ac6202 Gerrit-PatchSet: 2 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr Gerrit-Reviewer: Harald Welte Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-HasComments: Yes From gerrit-no-reply at lists.osmocom.org Sun Apr 30 22:00:12 2017 From: gerrit-no-reply at lists.osmocom.org (Holger Freyther) Date: Sun, 30 Apr 2017 22:00:12 +0000 Subject: libosmo-netif[master]: stream.h: Add missing stdint.h include In-Reply-To: References: Message-ID: Patch Set 2: Code-Review+2 -- To view, visit https://gerrit.osmocom.org/2368 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: comment Gerrit-Change-Id: I399e2986c9d8cb5b3dd31673a6b4bf63070a4770 Gerrit-PatchSet: 2 Gerrit-Project: libosmo-netif Gerrit-Branch: master Gerrit-Owner: Pau Espin Pedrol Gerrit-Reviewer: Holger Freyther Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max Gerrit-HasComments: No