📄 gsm_sms_codec.cc
字号:
++_op; } } alignOctet(); return result;}unsigned long SMSDecoder::getTimeZone(bool &negativeTimeZone){ unsigned long result = 0; alignOctet(); for (unsigned short i = 0; i < 2; ++i) { if (_bi == 0) { if (_op >= _maxop) throw GsmException(_("premature end of PDU"), SMSFormatError); // bits 0..3 are most significant if (i == 0) { // get sign result = result * 10 + (*_op & 0x7); negativeTimeZone = (*_op & 0x8 == 0); } else result = result * 10 + (*_op & 0xf); _bi = 4; } else { if (_op >= _maxop) throw GsmException(_("premature end of PDU"), SMSFormatError); // bits 4..7 are least significant result = result * 10 + (*_op >> 4); _bi = 0; ++_op; } } alignOctet(); return result * 15; // compute minutes}unsigned long SMSDecoder::getInteger(unsigned short length){ unsigned long result = 0; for (unsigned short i = 0; i < length; ++i) result |= (getBit() << i); return result;}string SMSDecoder::getString(unsigned short length){ string result; alignSeptet(); for (unsigned short i = 0; i < length; ++i) { unsigned char c = 0; for (unsigned short j = 0; j < 7; ++j) c |= getBit() << j; result += c; } return result;}Address SMSDecoder::getAddress(bool scAddressFormat){ Address result; alignOctet(); unsigned char addressLength = getOctet(); if (addressLength == 0 && scAddressFormat) return result; // special case for SUBMIT-PDUs // parse Type-of-Address result._plan = (Address::NumberingPlan)getInteger(4); result._type = (Address::Type)getInteger(3); // get address if (result._type == Address::Alphanumeric) { markSeptet(); // addressLength is number of semi-octets // (addressLength / 2) * 8 is number of available bits // divided by 7 is number of 7-bit characters result._number = gsmToLatin1(getString(addressLength * 4 / 7)); alignOctet(); } else result._number = getSemiOctets(scAddressFormat ? (addressLength - 1) * 2 : addressLength); return result;}Timestamp SMSDecoder::getTimestamp(){ Timestamp result; result._year = getSemiOctetsInteger(2); result._month = getSemiOctetsInteger(2); result._day = getSemiOctetsInteger(2); result._hour = getSemiOctetsInteger(2); result._minute = getSemiOctetsInteger(2); result._seconds = getSemiOctetsInteger(2); result._timeZoneMinutes = getTimeZone(result._negativeTimeZone); return result;}TimePeriod SMSDecoder::getTimePeriod(TimePeriod::Format format){ TimePeriod result; result._format = format; switch (format) { case TimePeriod::NotPresent: break; case TimePeriod::Relative: result._relativeTime = getOctet(); break; case TimePeriod::Absolute: result._absoluteTime = getTimestamp(); break; default: throw GsmException(_("unknown time period format"), SMSFormatError); break; } return result;}SMSDecoder::~SMSDecoder(){ delete _p;}// SMSEncoder membersSMSEncoder::SMSEncoder() : _bi(0), _op(_p){ memset((void*)_p, 0, sizeof(_p));}void SMSEncoder::alignOctet(){ if (_bi != 0) { _bi = 0; ++_op; }} void SMSEncoder::alignSeptet(){ while (((_op - _septetStart) * 8 + _bi) % 7 != 0) setBit();} void SMSEncoder::set2Bits(unsigned char twoBits){ setBit(twoBits & 1); setBit((twoBits & 2) == 2);}void SMSEncoder::setOctet(unsigned char octet){ alignOctet(); *_op++ = octet;}void SMSEncoder::setOctets(const unsigned char* octets, unsigned short length){ alignOctet(); for (unsigned short i = 0; i < length; ++i) *_op++ = octets[i];}void SMSEncoder::setSemiOctets(string semiOctets){ alignOctet(); for (unsigned int i = 0; i < semiOctets.length(); ++i) { if (_bi == 0) { *_op = semiOctets[i] - '0'; _bi = 4; } else { *_op++ |= (semiOctets[i] - '0') << 4; _bi = 0; } } if (_bi == 4) *_op++ |= 0xf0; _bi = 0;}void SMSEncoder::setSemiOctetsInteger(unsigned long intValue, unsigned short length){ ostrstream os; os << intValue << ends; char *ss = os.str(); string s(ss); delete[] ss; assert(s.length() <= length); while (s.length() < length) s = '0' + s; setSemiOctets(s);}void SMSEncoder::setTimeZone(bool negativeTimeZone, unsigned long timeZone){ setSemiOctetsInteger(timeZone / 15, 2); if (!negativeTimeZone) *(_op - 1) |= 8;}void SMSEncoder::setInteger(unsigned long intvalue, unsigned short length){ for (unsigned short i = 0; i < length; ++i) setBit((intvalue & (1 << i)) != 0);}void SMSEncoder::setString(string stringValue){ alignSeptet(); for (unsigned int i = 0; i < stringValue.length(); ++i) { unsigned char c = stringValue[i]; for (unsigned short j = 0; j < 7; ++j) setBit(((1 << j) & c) != 0); }}void SMSEncoder::setAddress(Address &address, bool scAddressFormat){ alignOctet(); if (scAddressFormat) { unsigned int numberLen = address._number.length(); if (numberLen == 0) { setOctet(0); // special case: use default SC address return; // (set by +CSCA=) } setOctet(numberLen / 2 + numberLen % 2 + 1); // not supported for SCA format assert(address._type != Address::Alphanumeric); } else if (address._type == Address::Alphanumeric) // address in GSM default encoding, see also comment in getAddress() setOctet((address._number.length() * 7 + 6) / 8 * 2); else setOctet(address._number.length()); setInteger(address._plan, 4); setInteger(address._type, 3); setBit(1); if (address._number.length() > 0) if (address._type == Address::Alphanumeric) { markSeptet(); setString(latin1ToGsm(address._number)); } else setSemiOctets(address._number); alignOctet();}void SMSEncoder::setTimestamp(Timestamp timestamp){ setSemiOctetsInteger(timestamp._year, 2); setSemiOctetsInteger(timestamp._month, 2); setSemiOctetsInteger(timestamp._day, 2); setSemiOctetsInteger(timestamp._hour, 2); setSemiOctetsInteger(timestamp._minute, 2); setSemiOctetsInteger(timestamp._seconds, 2); setTimeZone(timestamp._negativeTimeZone, timestamp._timeZoneMinutes);}void SMSEncoder::setTimePeriod(TimePeriod period){ switch (period._format) { case TimePeriod::NotPresent: break; case TimePeriod::Relative: setOctet(period._relativeTime); break; case TimePeriod::Absolute: setTimestamp(period._absoluteTime); break; default: assert(0); break; }}string SMSEncoder::getHexString(){ short bi = _bi; unsigned char *op = _op; alignOctet(); string result = bufToHex(_p, _op - _p); _bi = bi; _op = op; return result;}unsigned int SMSEncoder::getLength(){ short bi = _bi; unsigned char *op = _op; alignOctet(); unsigned int result = _op - _p; _bi = bi; _op = op; return result;}// UserDataHeader membersvoid UserDataHeader::encode(SMSEncoder &e){ e.setOctet(_udh.length()); e.setOctets((unsigned char*)_udh.data(), _udh.length());}void UserDataHeader::decode(SMSDecoder &d){ unsigned char udhLen = d.getOctet(); unsigned char *s = (unsigned char*)alloca(sizeof(unsigned char) * udhLen); d.getOctets(s, udhLen); string ss((char*)s, (unsigned int)udhLen); _udh = ss;}string UserDataHeader::getIE(unsigned char id){ int udhl, pos = 0; udhl = _udh.length(); while (pos < udhl) { unsigned char iei = _udh[pos++]; unsigned char ieidl = _udh[pos++]; if (iei == id) return _udh.substr(pos, ieidl); pos += ieidl; } return "";}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -