/**@file @brief Call Control messages, GSM 04.08 9.3 */ /* * Copyright 2008, 2009 Free Software Foundation, Inc. * * This software is distributed under multiple licenses; see the COPYING file in the main directory for licensing information for this specific distribuion. * * This use of this software may be subject to additional restrictions. * See the LEGAL file in the main directory for details. 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. */ #include "GSML3CCElements.h" #include using namespace std; using namespace GSM; void L3BearerCapability::writeV( L3Frame &dest, size_t &wp ) const { // See GSM 10.5.4.5. // This is a hell of a complex element, inherited from ISDN. // But we're going to ignore a lot of it. // "octet 3" // We hard code this octet for circuit switched speech. dest.writeField(wp, 0x04, 8); // "octet 3a" // We hard code for full rate speech v1, the GSM 06.10 codec. dest.writeField(wp,0x80,8); } void L3BearerCapability::parseV( const L3Frame& src, size_t &rp, size_t expectedLength ) { // See GSM 10.5.4.5. // This is a hell of a complex element, inherited from ISDN. // But we're just going to assume circuit-switched speech // with a full rate codec, since every phone supports that. // So we can just ignore this hideously complex element. // Just move the read index and return. // Shhh. Our little secret. rp += 8*expectedLength; } void L3BearerCapability::text(ostream& os) const { os << "(default)"; } void L3BCDDigits::parse(const L3Frame& src, size_t &rp, size_t numOctets, bool international) { unsigned i=0; size_t readOctets = 0; if (international) mDigits[i++] = '+'; while (readOctets < numOctets) { unsigned d2 = src.readField(rp,4); unsigned d1 = src.readField(rp,4); readOctets++; mDigits[i++] = d1 == 10 ? '*' : d1 == 11 ? '#' : d1+'0'; if (d2!=0x0f) mDigits[i++] = d2 == 10 ? '*' : d2 == 11 ? '#' : d2+'0'; if (i>maxDigits) L3_READ_ERROR; } mDigits[i++]='\0'; } int encode(char c) { return c == '*' ? 10 : c == '#' ? 11 : c-'0'; } void L3BCDDigits::write(L3Frame& dest, size_t &wp) const { unsigned index = 0; unsigned numDigits = strlen(mDigits); if (index < numDigits && mDigits[index] == '+') { index++; } while (index < numDigits) { if ((index+1) < numDigits) dest.writeField(wp,encode(mDigits[index+1]),4); else dest.writeField(wp,0x0f,4); dest.writeField(wp,encode(mDigits[index]),4); index += 2; } } size_t L3BCDDigits::lengthV() const { unsigned sz = strlen(mDigits); if (*mDigits == '+') sz--; return (sz/2) + (sz%2); } ostream& GSM::operator<<(ostream& os, const L3BCDDigits& digits) { os << digits.digits(); return os; } void L3CalledPartyBCDNumber::writeV( L3Frame &dest, size_t &wp ) const { dest.writeField(wp, 0x01, 1); dest.writeField(wp, mType, 3); dest.writeField(wp, mPlan, 4); mDigits.write(dest,wp); } void L3CalledPartyBCDNumber::parseV( const L3Frame &src, size_t &rp, size_t expectedLength ) { LOG(DEBUG) << "L3CalledPartyBCDNumber::parseV rp="<