/**@file Elements for call independent Supplementary Service Control, GSM 04.80 3. */ /* * Copyright 2008, 2009, 2010 Free Software Foundation, 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 "GSML3NonCallSSElements.h" #include using namespace std; using namespace GSM; void L3NonCallSSElementOctetLength::writeV( L3Frame& dest, size_t &wp ) const { dest.writeField(wp,mValue,8); } void L3NonCallSSElementOctetLength::parseV( const L3Frame& src, size_t &rp) { mValue = src.readField(rp, 8); setValue(); } size_t L3NonCallSSElementUndefLength::lengthV() const { size_t size = sizeof(mValue); uint64_t tmp = 0; do { size--; tmp = mValue>>(size*8); } while ((tmp == 0) &&(size>0)); size++; return size; } void L3NonCallSSElementUndefLength::writeV( L3Frame& dest, size_t &wp ) const { dest.writeField(wp,mValue,lengthV()*8); } void L3NonCallSSElementUndefLength::writeV( L3Frame& dest, size_t &wp, size_t numBits) const { dest.writeField(wp,mValue,numBits); } void L3NonCallSSElementUndefLength::parseV( const L3Frame& src, size_t &rp, size_t numOctets) { mValue = src.readField(rp, numOctets*8); } void L3NonCallSSOperationCode::text(ostream& os) const { switch (mOperationCode){ case ProcessUnstructuredSSRequest: os << "ProcessUnstructuredSSRequest"; break; case UnstructuredSSRequest: os << "UnstructuredSSRequest"; break; case UnstructuredSSNotify: os << "UnstructuredSSNotify"; break; } } size_t L3NonCallSSLengthField::lengthV() const { size_t length = 0; if (mValue <= 0x7f) length = 1; else { uint64_t tmp = mValue; do { length++; tmp>>=8; } while(tmp!=0); length++; } return length; } void L3NonCallSSLengthField::writeV( L3Frame& dest, size_t &wp ) const { if (mValue <= 0x7f) { dest.writeField(wp,mValue,8); } else { uint64_t tmp = mValue; size_t numOctets = 0; do { numOctets++; tmp>>=8; } while(tmp!=0); dest.writeField(wp,numOctets|0x80,8); dest.writeField(wp,mValue,numOctets*8); } } void L3NonCallSSLengthField::parseV( const L3Frame& source, size_t &rp) { uint64_t tmp = source.readField(rp, 8); if ((tmp>>7)==0) mValue = tmp; else mValue = source.readField(rp, (tmp&0x7f)*8); } size_t L3NonCallSSParameters::length() { unsigned numChar = strlen(mData); unsigned ussdStringLength = (numChar*7)/8; if ((numChar*7)%8!=0) ussdStringLength +=1; mDataLength.setValue(ussdStringLength); unsigned sequenceLength = mDataLength.value()+mDataLength.lengthV()+4; if (mHaveAlertingPattern) sequenceLength+=0x3; mSequenceLength.setValue(sequenceLength); return mSequenceLength.value()+mSequenceLength.lengthV()+1; } void L3NonCallSSParameters::parseV(const L3Frame& src, size_t& rp) { rp+=8; mSequenceLength.parseV(src, rp); rp+=16; mDataCodingScheme = src.readField(rp,8); rp+=8; mDataLength.parseV(src, rp); unsigned numChar = mDataLength.value()*8/7; BitVector chars(src.tail(rp)); chars.LSB8MSB(); size_t crp=0; for (int i=0; i