/**@file
@brief Radio Resource messages, GSM 04.08 9.1.
*/
/*
* Copyright 2008, 2009 Free Software Foundation, Inc.
* Copyright 2010 Kestrel Signal Processing, Inc.
*
* This software is distributed under the terms of the GNU Affero Public License.
* See the COPYING file in the main directory for details.
*
* This use of this software may be subject to additional restrictions.
* See the LEGAL file in the main directory for details.
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 // for L3APDUData::text
#include "GSML3RRElements.h"
#include
using namespace std;
using namespace GSM;
void L3CellOptionsBCCH::writeV(L3Frame& dest, size_t &wp) const
{
dest.writeField(wp,0,1);
dest.writeField(wp,mPWRC,1);
dest.writeField(wp,mDTX,2);
dest.writeField(wp,mRADIO_LINK_TIMEOUT,4);
}
void L3CellOptionsBCCH::text(ostream& os) const
{
os << "PWRC=" << mPWRC;
os << " DTX=" << mDTX;
os << " RADIO_LINK_TIMEOUT=" << mRADIO_LINK_TIMEOUT;
}
void L3CellOptionsSACCH::writeV(L3Frame& dest, size_t &wp) const
{
dest.writeField(wp,(mDTX>>2)&0x01,1);
dest.writeField(wp,mPWRC,1);
dest.writeField(wp,mDTX&0x03,2);
dest.writeField(wp,mRADIO_LINK_TIMEOUT,4);
}
void L3CellOptionsSACCH::text(ostream& os) const
{
os << "PWRC=" << mPWRC;
os << " DTX=" << mDTX;
os << " RADIO_LINK_TIMEOUT=" << mRADIO_LINK_TIMEOUT;
}
void L3CellSelectionParameters::writeV(L3Frame& dest, size_t &wp) const
{
dest.writeField(wp,mCELL_RESELECT_HYSTERESIS,3);
dest.writeField(wp,mMS_TXPWR_MAX_CCH,5);
dest.writeField(wp,mACS,1);
dest.writeField(wp,mNECI,1);
dest.writeField(wp,mRXLEV_ACCESS_MIN,6);
}
void L3CellSelectionParameters::text(ostream& os) const
{
os << "CELL-RESELECT-HYSTERESIS=" << mCELL_RESELECT_HYSTERESIS;
os << " MS-TXPWR-MAX-CCH=" << mMS_TXPWR_MAX_CCH;
os << " ACS=" << mACS;
os << " NECI=" << mNECI;
os << " RXLEV-ACCESS-MIN=" << mRXLEV_ACCESS_MIN;
}
void L3ControlChannelDescription::writeV(L3Frame& dest, size_t &wp) const
{
dest.writeField(wp,0,1);
dest.writeField(wp,mATT,1);
dest.writeField(wp,mBS_AG_BLKS_RES,3);
dest.writeField(wp,mCCCH_CONF,3);
dest.writeField(wp,0,5);
dest.writeField(wp,mBS_PA_MFRMS,3);
dest.writeField(wp,mT3212,8);
}
void L3ControlChannelDescription::text(ostream& os) const
{
os << "ATT=" << mATT;
os << " BS_AG_BLKS_RES=" << mBS_AG_BLKS_RES;
os << " CCCH_CONF=" << mCCCH_CONF;
os << " BS_PA_MFRMS=" << mBS_PA_MFRMS;
os << " T3212=" << mT3212;
}
bool L3FrequencyList::contains(unsigned wARFCN) const
{
for (unsigned i=0; imax) max=mARFCNs[i];
}
return max - base();
}
void L3FrequencyList::writeV(L3Frame& dest, size_t &wp) const
{
// If this were used as Frequency List, it had to be coded
// as the variable bit map format, GSM 04.08 10.5.2.13.7.
// But it is used as Cell Channel Description and is coded
// as the variable bit map format, GSM 04.08 10.5.2.1b.7.
// Difference is in abscence of Length field.
// The header occupies first 7 most significant bits of
// the first V-part octet and should be 1000111b=0x47 for
// the variable length bitmap.
dest.writeField(wp,0x47,7);
// base ARFCN
unsigned baseARFCN = base();
dest.writeField(wp,baseARFCN,10);
// bit map
unsigned delta = spread();
unsigned numBits = 8*lengthV() - 17;
if (numBits output( os, "" );
//std::copy( mData.begin(), mData.end(), output );
for (size_t i = 0 ; i < mData.size() ; ++i) {
os << (mData[i] ? "1" : "0");
}
}
void L3MeasurementResults::parseV(const L3Frame& frame, size_t &rp)
{
// GSM 04.08 10.5.2.20
mBA_USED = frame.readField(rp,1);
mDTX_USED = frame.readField(rp,1);
mRXLEV_FULL_SERVING_CELL = frame.readField(rp,6);
rp++; // spare
mMEAS_VALID = frame.readField(rp,1);
mRXLEV_SUB_SERVING_CELL = frame.readField(rp,6);
rp++; // spare
mRXQUAL_FULL_SERVING_CELL = frame.readField(rp,3);
mRXQUAL_SUB_SERVING_CELL = frame.readField(rp,3);
mNO_NCELL = frame.readField(rp,3);
for (unsigned i=0; i<6; i++) {
mRXLEV_NCELL[i] = frame.readField(rp,6);
mBCCH_FREQ_NCELL[i] = frame.readField(rp,5);
mBSIC_NCELL[i] = frame.readField(rp,6);
}
}
void L3MeasurementResults::text(ostream& os) const
{
// GSM 04.08 10.5.2.20
os << "BA_USED=" << mBA_USED;
os << " DTX_USED=" << mDTX_USED;
os << " MEAS_VALID=" << mMEAS_VALID;
// Note that the value of the MEAS-VALID bit is reversed
// from what you might expect.
if (mMEAS_VALID) return;
os << " RXLEV_FULL_SERVING_CELL=" << mRXLEV_FULL_SERVING_CELL;
os << " RXLEV_SUB_SERVING_CELL=" << mRXLEV_SUB_SERVING_CELL;
os << " RXQUAL_FULL_SERVING_CELL=" << mRXQUAL_FULL_SERVING_CELL;
os << " RXQUAL_SUB_SERVING_CELL=" << mRXQUAL_SUB_SERVING_CELL;
os << " NO_NCELL=" << mNO_NCELL;
// no measurements?
if (mNO_NCELL==0) return;
// no neighbor list?
if (mNO_NCELL==7) return;
for (unsigned i=0; i