/**@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