?? gsm_sms.cc
字號:
// *************************************************************************// * GSM TA/ME library// *// * File: gsm_sms.cc// *// * Purpose: SMS functions// * (ETSI GSM 07.05)// *// * Author: Peter Hofmann (software@pxh.de)// *// * Created: 16.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.h>#include <gsmlib/gsm_util.h>#include <gsmlib/gsm_parser.h>#include <gsmlib/gsm_me_ta.h>#include <strstream>#include <string>using namespace std;using namespace gsmlib;// local constantsstatic const string dashes ="---------------------------------------------------------------------------";// SMSMessage membersRef<SMSMessage> SMSMessage::decode(string pdu, bool SCtoMEdirection, GsmAt *at) throw(GsmException){ Ref<SMSMessage> result; SMSDecoder d(pdu); d.getAddress(true); MessageType messageTypeIndicator = (MessageType)d.get2Bits(); // bits 0..1 if (SCtoMEdirection) // TPDUs from SC to ME switch (messageTypeIndicator) { case SMS_DELIVER: result = new SMSDeliverMessage(pdu); break; case SMS_STATUS_REPORT: result = new SMSStatusReportMessage(pdu); break; case SMS_SUBMIT_REPORT: // observed with Motorola Timeport 260, the SCtoMEdirection can // be wrong in this case if (at != NULL && at->getMeTa().getCapabilities()._wrongSMSStatusCode) result = new SMSSubmitMessage(pdu); else result = new SMSSubmitReportMessage(pdu); break; default: throw GsmException(_("unhandled SMS TPDU type"), OtherError); } else // TPDUs from ME to SC switch (messageTypeIndicator) { case SMS_SUBMIT: result = new SMSSubmitMessage(pdu); break; case SMS_DELIVER_REPORT: result = new SMSDeliverReportMessage(pdu); break; case SMS_COMMAND: result = new SMSCommandMessage(pdu); break; default: throw GsmException(_("unhandled SMS TPDU type"), OtherError); } result->_at = at; return result;}Ref<SMSMessage> SMSMessage::decode(istream& s) throw(gsmlib::GsmException){ string pdu; unsigned char ScToMe; s >> ScToMe; s >> pdu; return decode(pdu,ScToMe=='S');}unsigned char SMSMessage::send(Ref<SMSMessage> &ackPdu) throw(GsmException){ if (_messageTypeIndicator != SMS_SUBMIT && _messageTypeIndicator != SMS_COMMAND) throw GsmException(_("can only send SMS-SUBMIT and SMS-COMMAND TPDUs"), ParameterError); if (_at.isnull()) throw GsmException(_("no device given for sending SMS"), ParameterError); string pdu = encode(); Parser p(_at->sendPdu("+CMGS=" + intToStr(pdu.length() / 2 - getSCAddressLen()), "+CMGS:", pdu)); unsigned char messageReference = p.parseInt(); if (p.parseComma(true)) { string pdu = p.parseEol(); // add missing service centre address if required by ME if (! _at->getMeTa().getCapabilities()._hasSMSSCAprefix) pdu = "00" + pdu; ackPdu = SMSMessage::decode(pdu); } else ackPdu = SMSMessageRef(); return messageReference;}unsigned char SMSMessage::send() throw(GsmException){ SMSMessageRef mref; return send(mref);}unsigned int SMSMessage::getSCAddressLen(){ SMSEncoder e; e.setAddress(_serviceCentreAddress, true); return e.getLength();}unsigned char SMSMessage::userDataLength() const{ unsigned int udhl = _userDataHeader.length(); if (_dataCodingScheme.getAlphabet() == DCS_DEFAULT_ALPHABET) return _userData.length() + (udhl ? ((1 + udhl) * 8 + 6) / 7 : 0); else return _userData.length() + (udhl ? (1 + udhl) : 0);}ostream& SMSMessage::operator<<(ostream& s){ unsigned char ScToMe; if (dynamic_cast<SMSDeliverMessage*>(this) || dynamic_cast<SMSStatusReportMessage*>(this) || dynamic_cast<SMSSubmitReportMessage*>(this)) { ScToMe = 'S'; } else if (dynamic_cast<SMSSubmitMessage*>(this) || dynamic_cast<SMSCommandMessage*>(this) || dynamic_cast<SMSDeliverReportMessage*>(this)) { ScToMe = 'M'; } else { throw GsmException(_("unhandled SMS TPDU type"), OtherError); } s << ScToMe; return s << encode();}// SMSMessage::SMSMessage(SMSMessage &m)// {// _at = m._at; // }// SMSMessage &SMSMessage::operator=(SMSMessage &m)// {// }SMSMessage::~SMSMessage() {}// SMSDeliverMessage membersvoid SMSDeliverMessage::init(){ _messageTypeIndicator = SMS_DELIVER; _moreMessagesToSend = false; _replyPath = false; _statusReportIndication = false; _protocolIdentifier = 0;}SMSDeliverMessage::SMSDeliverMessage(){ init();}SMSDeliverMessage::SMSDeliverMessage(string pdu) throw(GsmException){ SMSDecoder d(pdu); _serviceCentreAddress = d.getAddress(true); _messageTypeIndicator = (MessageType)d.get2Bits(); // bits 0..1 assert(_messageTypeIndicator == SMS_DELIVER); _moreMessagesToSend = d.getBit(); // bit 2 d.getBit(); // bit 3 d.getBit(); // bit 4 _statusReportIndication = d.getBit(); // bit 5 bool userDataHeaderIndicator = d.getBit(); // bit 6 _replyPath = d.getBit(); // bit 7 _originatingAddress = d.getAddress(); _protocolIdentifier = d.getOctet(); _dataCodingScheme = d.getOctet(); _serviceCentreTimestamp = d.getTimestamp(); unsigned char userDataLength = d.getOctet(); d.markSeptet(); if (userDataHeaderIndicator) { _userDataHeader.decode(d); if (_dataCodingScheme.getAlphabet() == DCS_DEFAULT_ALPHABET) userDataLength -= ((_userDataHeader.length() + 1) * 8 + 6) / 7; else userDataLength -= ((string)_userDataHeader).length() + 1; } else _userDataHeader = UserDataHeader(); if (_dataCodingScheme.getAlphabet() == DCS_DEFAULT_ALPHABET) { // userDataLength is length in septets _userData = d.getString(userDataLength); _userData = gsmToLatin1(_userData); } else { // userDataLength is length in octets unsigned char *s = (unsigned char*)alloca(sizeof(unsigned char) * userDataLength); d.getOctets(s, userDataLength); _userData.assign((char*)s, (unsigned int)userDataLength); }}string SMSDeliverMessage::encode(){ SMSEncoder e; e.setAddress(_serviceCentreAddress, true); e.set2Bits(_messageTypeIndicator); // bits 0..1 e.setBit(_moreMessagesToSend); // bit 2 e.setBit(); // bit 3 e.setBit(); // bit 4 e.setBit(_statusReportIndication); // bit 5 e.setBit(_userDataHeader.length() != 0); // bit 6 e.setBit(_replyPath); // bit 7 e.setAddress(_originatingAddress); e.setOctet(_protocolIdentifier); e.setOctet(_dataCodingScheme); e.setTimestamp(_serviceCentreTimestamp); e.setOctet(userDataLength()); e.markSeptet(); if (_userDataHeader.length()) _userDataHeader.encode(e); if (_dataCodingScheme.getAlphabet() == DCS_DEFAULT_ALPHABET) e.setString(latin1ToGsm(_userData)); else e.setOctets((unsigned char*)_userData.data(), _userData.length()); return e.getHexString();}string SMSDeliverMessage::toString() const{ ostrstream os; os << dashes << endl << _("Message type: SMS-DELIVER") << endl << _("SC address: '") << _serviceCentreAddress._number << "'" << endl << _("More messages to send: ") << _moreMessagesToSend << endl << _("Reply path: ") << _replyPath << endl << _("User data header indicator: ") << (_userDataHeader.length()!=0) << endl << _("Status report indication: ") << _statusReportIndication << endl << _("Originating address: '") << _originatingAddress._number << "'" << endl << _("Protocol identifier: 0x") << hex << (unsigned int)_protocolIdentifier << dec << endl << _("Data coding scheme: ") << _dataCodingScheme.toString() << endl << _("SC timestamp: ") << _serviceCentreTimestamp.toString() << endl << _("User data length: ") << (int)userDataLength() << endl << _("User data header: 0x") << bufToHex((unsigned char*) ((string)_userDataHeader).data(), ((string)_userDataHeader).length()) << endl << _("User data: '") << _userData << "'" << endl << dashes << endl << endl << ends; char *ss = os.str(); string result(ss); delete[] ss; return result;}Address SMSDeliverMessage::address() const{ return _originatingAddress;}Ref<SMSMessage> SMSDeliverMessage::clone(){ Ref<SMSMessage> result = new SMSDeliverMessage(*this); return result;}// SMSSubmitMessage membersvoid SMSSubmitMessage::init(){ // set everything to sensible default values _messageTypeIndicator = SMS_SUBMIT; _validityPeriodFormat = TimePeriod::Relative; _validityPeriod._format = TimePeriod::Relative; _validityPeriod._relativeTime = 168; // 2 days _statusReportRequest = false; _replyPath = false; _rejectDuplicates = true; _messageReference = 0; _protocolIdentifier = 0;}SMSSubmitMessage::SMSSubmitMessage(){ init();}SMSSubmitMessage::SMSSubmitMessage(string pdu) throw(GsmException){ SMSDecoder d(pdu); _serviceCentreAddress = d.getAddress(true); _messageTypeIndicator = (MessageType)d.get2Bits(); // bits 0..1 assert(_messageTypeIndicator == SMS_SUBMIT); _rejectDuplicates = d.getBit(); // bit 2 _validityPeriodFormat = (TimePeriod::Format)d.get2Bits(); // bits 3..4 _statusReportRequest = d.getBit(); // bit 5 bool userDataHeaderIndicator = d.getBit(); // bit 6 _replyPath = d.getBit(); // bit 7 _messageReference = d.getOctet(); _destinationAddress = d.getAddress(); _protocolIdentifier = d.getOctet(); _dataCodingScheme = d.getOctet(); if (_validityPeriodFormat != TimePeriod::NotPresent) _validityPeriod = d.getTimePeriod(_validityPeriodFormat); unsigned char userDataLength = d.getOctet(); d.markSeptet(); if (userDataHeaderIndicator) { _userDataHeader.decode(d); if (_dataCodingScheme.getAlphabet() == DCS_DEFAULT_ALPHABET) userDataLength -= ((_userDataHeader.length() + 1) * 8 + 6) / 7; else userDataLength -= ((string)_userDataHeader).length() + 1; } else _userDataHeader = UserDataHeader(); if (_dataCodingScheme.getAlphabet() == DCS_DEFAULT_ALPHABET) { // userDataLength is length in septets _userData = d.getString(userDataLength); _userData = gsmToLatin1(_userData); } else { // _userDataLength is length in octets unsigned char *s = (unsigned char*)alloca(sizeof(unsigned char) * userDataLength); d.getOctets(s, userDataLength); _userData.assign((char*)s, userDataLength); }}SMSSubmitMessage::SMSSubmitMessage(string text, string number){ init(); _destinationAddress = Address(number); _userData = text;}string SMSSubmitMessage::encode(){ SMSEncoder e; e.setAddress(_serviceCentreAddress, true); e.set2Bits(_messageTypeIndicator); // bits 0..1 e.setBit(_rejectDuplicates); // bit 2 e.set2Bits(_validityPeriodFormat); // bits 3..4 e.setBit(_statusReportRequest); // bit 5 bool userDataHeaderIndicator = _userDataHeader.length() != 0; e.setBit(userDataHeaderIndicator); // bit 6 e.setBit(_replyPath); // bit 7 e.setOctet(_messageReference); e.setAddress(_destinationAddress); e.setOctet(_protocolIdentifier); e.setOctet(_dataCodingScheme); e.setTimePeriod(_validityPeriod); e.setOctet(userDataLength()); e.markSeptet(); if (userDataHeaderIndicator) _userDataHeader.encode(e); if (_dataCodingScheme.getAlphabet() == DCS_DEFAULT_ALPHABET) e.setString(latin1ToGsm(_userData)); else e.setOctets((unsigned char*)_userData.data(), _userData.length()); return e.getHexString();}string SMSSubmitMessage::toString() const{ ostrstream os; os << dashes << endl << _("Message type: SMS-SUBMIT") << endl << _("SC address: '") << _serviceCentreAddress._number << "'" << endl << _("Reject duplicates: ") << _rejectDuplicates << endl << _("Validity period format: "); switch (_validityPeriodFormat) { case TimePeriod::NotPresent: os << _("not present");
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -