📄 gsm_sms_codec.cc
字号:
// *************************************************************************// * GSM TA/ME library// *// * File: gsm_sms_codec.cc// *// * Purpose: Coder and Encoder for SMS TPDUs// *// * Author: Peter Hofmann (software@pxh.de)// *// * Created: 17.5.1999// *************************************************************************#ifdef HAVE_CONFIG_H#include <gsm_config.h>#endif#include <gsmlib/gsm_nls.h>#include <gsmlib/gsm_sysdep.h>#include <gsmlib/gsm_sms_codec.h>#include <gsmlib/gsm_util.h>#include <time.h>#include <strstream>#include <iomanip>#ifdef HAVE_STRING_H#include <string.h>#endif#include <string>using namespace std;using namespace gsmlib;// Address membersAddress::Address(string number) : _plan(ISDN_Telephone){ number = removeWhiteSpace(number); if (number.length() > 0 && number[0] == '+') { _type = International; _number = number.substr(1, number.length() - 1); } else { _type = Unknown; _number = number; }}string Address::toString() const{ if (_type == International) return "+" + _number; else return _number;}bool gsmlib::operator<(const Address &x, const Address &y){ // normalize numbers according to the following two rules: // - prepend "+" if international number // - append 0s to the shorter number so that both numbers have equal length string xnumber = x._number; string ynumber = y._number; static string twenty0s = "00000000000000000000"; if (x._type == Address::International) xnumber = "+" + xnumber; if (y._type == Address::International) ynumber = "+" + ynumber; while (xnumber.length() != ynumber.length()) if (xnumber.length() < ynumber.length()) { int diff = ynumber.length() - xnumber.length(); xnumber += twenty0s.substr(0, (diff > 20 ? 20 : diff)); } else { int diff = xnumber.length() - ynumber.length(); ynumber += twenty0s.substr(0, (diff > 20 ? 20 : diff)); } return xnumber < ynumber;}bool gsmlib::operator==(const Address &x, const Address &y){ return x._number == y._number && x._plan == y._plan;}// Timestamp membersbool Timestamp::empty() const{ return _year == 0 && _month == 0 && _day == 0 && _hour == 0 && _minute == 0 && _seconds == 0 && _timeZoneMinutes == 0;}string Timestamp::toString(bool appendTimeZone) const{ short timeZoneMinutes = _timeZoneMinutes; short timeZoneHours = timeZoneMinutes / 60; timeZoneMinutes %= 60; // format date and time in a locale-specific way struct tm t; t.tm_sec = _seconds; t.tm_min = _minute; t.tm_hour = _hour; t.tm_mon = _month - 1; // year 2000 heuristics, SMSs cannot be older than start of GSM network t.tm_year = _year < 80 ? _year + 100 : _year; t.tm_mday = _day; t.tm_isdst = -1; t.tm_yday = 0; t.tm_wday = 0; #ifdef BROKEN_STRFTIME char formattedTime[1024]; strftime(formattedTime, 1024, "%x %X", &t);#else int formattedTimeSize = strftime(NULL, INT_MAX, "%x %X", &t) + 1; char *formattedTime = (char*)alloca(sizeof(char) * formattedTimeSize); strftime(formattedTime, formattedTimeSize, "%x %X", &t);#endif if (! appendTimeZone) return formattedTime; ostrstream os; os << formattedTime << " (" << (_negativeTimeZone ? '-' : '+') << setfill('0') << setw(2) << timeZoneHours << setw(2) << timeZoneMinutes << ')' << ends; char *ss = os.str(); string result(ss); delete[] ss; return result;}bool gsmlib::operator<(const Timestamp &x, const Timestamp &y){ // we don't take time zone info into account because // - it's more complicated to compute // - it might confuse the user for whom it's also too complicated if (x._year < y._year) return true; else if (x._year > y._year) return false; if (x._month < y._month) return true; else if (x._month > y._month) return false; if (x._day < y._day) return true; else if (x._day > y._day) return false; if (x._hour < y._hour) return true; else if (x._hour > y._hour) return false; if (x._minute < y._minute) return true; else if (x._minute > y._minute) return false; return x._seconds < y._seconds;}bool gsmlib::operator==(const Timestamp &x, const Timestamp &y){ // we don't take time zone info in order to be consistent with operator< return x._year == y._year && x._month == y._month && x._day == y._day && x._hour == y._hour && x._minute == y._minute && x._seconds == y._seconds;}// TimePeriod membersstring TimePeriod::toString() const{ switch (_format) { case NotPresent: return _("not present"); case Relative: { ostrstream os; if (_relativeTime <= 143) os << ((int)_relativeTime + 1) * 5 << _(" minutes"); else if (_relativeTime <= 167) os << 12 * 60 + ((int)_relativeTime - 143) * 30 << _(" minutes"); else if (_relativeTime <= 196) os << (int)_relativeTime - 166 << _(" days"); else if (_relativeTime <= 143) os << (int)_relativeTime - 192 << _(" weeks"); os << ends; char *ss = os.str(); string result(ss); delete[] ss; return result; } case Absolute: return _absoluteTime.toString(); default: return _("unknown"); }}// DataCodingScheme membersstring DataCodingScheme::toString() const{ string result; if (compressed()) result += _("compressed "); if (messageWaitingIndication()) switch (getMessageWaitingType()) { case DCS_VOICEMAIL_MESSAGE_WAITING: result += _("voicemail message waiting"); break; case DCS_FAX_MESSAGE_WAITING: result += _("fax message waiting"); break; case DCS_ELECTRONIC_MAIL_MESSAGE_WAITING: result += _("electronic mail message waiting"); break; case DCS_OTHER_MESSAGE_WAITING: result += _("other message waiting"); break; } else switch (getAlphabet()) { case DCS_DEFAULT_ALPHABET: result += _("default alphabet"); break; case DCS_EIGHT_BIT_ALPHABET: result += _("8-bit alphabet"); break; case DCS_SIXTEEN_BIT_ALPHABET: result += _("16-bit alphabet"); break; case DCS_RESERVED_ALPHABET: result += _("reserved alphabet"); break; } return result;}// SMSDecoder membersSMSDecoder::SMSDecoder(string pdu) : _bi(0), _septetStart(NULL){ _p = new unsigned char[pdu.length() / 2]; _op = _p; if (! hexToBuf(pdu, _p)) throw GsmException(_("bad hexadecimal PDU format"), SMSFormatError); _maxop = _op + pdu.length() / 2;}void SMSDecoder::alignOctet(){ if (_bi != 0) { _bi = 0; ++_op; }} void SMSDecoder::alignSeptet(){ assert(_septetStart != NULL); while (((_op - _septetStart) * 8 + _bi) % 7 != 0) getBit();} unsigned char SMSDecoder::get2Bits(){ unsigned char result = getBit(); return result | (getBit() << 1);}unsigned char SMSDecoder::getOctet(){ alignOctet(); if (_op >= _maxop) throw GsmException(_("premature end of PDU"), SMSFormatError); return *_op++;}void SMSDecoder::getOctets(unsigned char* octets, unsigned short length){ alignOctet(); for (unsigned short i = 0; i < length; ++i) { if (_op >= _maxop) throw GsmException(_("premature end of PDU"), SMSFormatError); *octets++ = *_op++; }}string SMSDecoder::getSemiOctets(unsigned short length){ string result; result.reserve(length); alignOctet(); for (unsigned short i = 0; i < length; ++i) { if (_bi == 0) { if (_op >= _maxop) throw GsmException(_("premature end of PDU"), SMSFormatError); // bits 0..3 are most significant result += '0' + (*_op & 0xf); _bi = 4; } else { if (_op >= _maxop) throw GsmException(_("premature end of PDU"), SMSFormatError); // bits 4..7 are least significant, skip 0xf digit if ((*_op & 0xf0) != 0xf0) result += '0' + (*_op >> 4); _bi = 0; ++_op; } } alignOctet(); return result;}unsigned long SMSDecoder::getSemiOctetsInteger(unsigned short length){ unsigned long result = 0; alignOctet(); for (unsigned short i = 0; i < length; ++i) { if (_bi == 0) { if (_op >= _maxop) throw GsmException(_("premature end of PDU"), SMSFormatError); // bits 0..3 are most significant result = result * 10 + (*_op & 0xf); _bi = 4; } else { if (_op >= _maxop) throw GsmException(_("premature end of PDU"), SMSFormatError); // bits 4..7 are least significant, skip 0xf digit if ((*_op & 0xf0) != 0xf0) result = result * 10 + (*_op >> 4); _bi = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -