⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gsm_sms_codec.c

📁 这是一款VC++编写的软件
💻 C
📖 第 1 页 / 共 2 页
字号:
      ++_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 / 2) * 8 / 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 members

SMSEncoder::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 members

void 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 + -