[Feature]add MT2731_MP2_MR2_SVN388 baseline version
Change-Id: Ief04314834b31e27effab435d3ca8ba33b499059
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/SmsMessage.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/SmsMessage.cpp
new file mode 100644
index 0000000..771e861
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/sms/cdma/SmsMessage.cpp
@@ -0,0 +1,416 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <memory>
+#include <iostream>
+#include <numeric>
+using namespace std;
+
+#include <log/log.h>
+
+#include "SmsMessage.h"
+#include "BearerData.h"
+#include "HexDump.h";
+
+#undef LOG_TAG
+#define LOG_TAG "DEMO_CDMA_SMS"
+
+uint32_t SmsMessage::mPos = 0;
+SmsMessage::SmsMessage(std::shared_ptr<SmsAddress> addr,std::shared_ptr<SmsEnvelope> env) {
+ mOriginatingAddress = addr;
+ mEnvelope = env;
+ createPdu();
+}
+
+SmsMessage::SmsMessage() {
+ // TODO Auto-generated constructor stub
+
+}
+
+SmsMessage::~SmsMessage() {
+ // TODO Auto-generated destructor stub
+}
+
+uint8_t SmsMessage::convertDtmfToAscii(uint8_t dtmfDigit) {
+ uint8_t asciiDigit;
+
+ switch (dtmfDigit) {
+ case 0:
+ asciiDigit = 68;
+ break; // 'D'
+ case 1:
+ asciiDigit = 49;
+ break; // '1'
+ case 2:
+ asciiDigit = 50;
+ break; // '2'
+ case 3:
+ asciiDigit = 51;
+ break; // '3'
+ case 4:
+ asciiDigit = 52;
+ break; // '4'
+ case 5:
+ asciiDigit = 53;
+ break; // '5'
+ case 6:
+ asciiDigit = 54;
+ break; // '6'
+ case 7:
+ asciiDigit = 55;
+ break; // '7'
+ case 8:
+ asciiDigit = 56;
+ break; // '8'
+ case 9:
+ asciiDigit = 57;
+ break; // '9'
+ case 10:
+ asciiDigit = 48;
+ break; // '0'
+ case 11:
+ asciiDigit = 42;
+ break; // '*'
+ case 12:
+ asciiDigit = 35;
+ break; // '#'
+ case 13:
+ asciiDigit = 65;
+ break; // 'A'
+ case 14:
+ asciiDigit = 66;
+ break; // 'B'
+ case 15:
+ asciiDigit = 67;
+ break; // 'C'
+ default:
+ asciiDigit = 32; // Invalid DTMF code
+ break;
+ }
+
+ return asciiDigit;
+}
+
+void SmsMessage::writeInt(uint32_t data) {
+ mPdu.push_back((data >> 24) & 0xFF);
+ mPdu.push_back((data >> 16) & 0xFF);
+ mPdu.push_back((data >> 8) & 0xFF);
+ mPdu.push_back((data >> 0) & 0xFF);
+}
+
+uint32_t SmsMessage::readInt(std::vector<uint8_t> pdu) {
+ uint32_t temp = 0;
+ temp = (pdu[mPos++] << 24) & 0xFF000000;
+ temp |= (pdu[mPos++] << 16) & 0xFF0000;
+ temp |= (pdu[mPos++] << 8) & 0xFF00;
+ temp |= (pdu[mPos++] << 0) & 0xFF;
+ return temp;
+}
+
+void SmsMessage::writeVector(std::vector<uint8_t> v) {
+ mPdu.insert(mPdu.end(), v.begin(), v.end());
+}
+
+std::vector<uint8_t> SmsMessage::readVector(std::vector<uint8_t> v,
+ int length) {
+ std::vector<uint8_t> temp;
+ temp.insert(temp.end(), v.begin() + mPos, v.begin() + mPos + length);
+ mPos += length;
+ return temp;
+}
+
+void SmsMessage::writeByte(uint8_t data) {
+ mPdu.push_back(data);
+}
+
+uint8_t SmsMessage::readByte(std::vector<uint8_t> pdu) {
+ return mPdu[mPos++];
+}
+
+void SmsMessage::createPdu() {
+ auto env = mEnvelope;
+ auto addr = env->origAddress;
+ //ByteArrayOutputStream baos = new ByteArrayOutputStream(100);
+ //DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(baos));
+
+ writeInt(env->messageType);
+ writeInt(env->teleService);
+ writeInt(env->serviceCategory);
+
+ writeByte(addr->digitMode);
+ writeByte(addr->numberMode);
+ writeByte(addr->ton);
+ writeByte(addr->numberPlan);
+ writeByte(addr->numberOfDigits);
+ writeVector(addr->origBytes); // digits
+
+ writeInt(env->bearerReply);
+ // CauseCode values:
+ writeByte(env->replySeqNo);
+ writeByte(env->errorClass);
+ writeByte(env->causeCode);
+ //encoded BearerData:
+ writeInt(env->bearerData.size());
+ writeVector(env->bearerData);
+}
+
+void SmsMessage::parsePdu(std::vector<uint8_t> pdu) {
+ int length;
+ int bearerDataLength;
+ auto env = std::make_shared<SmsEnvelope>();
+ auto addr = std::make_shared<CdmaSmsAddress>();
+ // We currently do not parse subaddress in PDU, but it is required when determining
+ // fingerprint (see getIncomingSmsFingerprint()).
+ auto subaddr = std::make_shared<CdmaSmsSubaddress>();
+ mPos = 0;
+ env->messageType = readInt(pdu);
+ env->teleService = readInt(pdu);
+ env->serviceCategory = readInt(pdu);
+
+ addr->digitMode = readByte(pdu);
+ addr->numberMode = readByte(pdu);
+ addr->ton = readByte(pdu);
+ addr->numberPlan = readByte(pdu);
+
+ length = readByte(pdu);
+ addr->numberOfDigits = length;
+
+ // sanity check on the length
+ if (length > pdu.size()) {
+ throw runtime_error(
+ "createFromPdu: Invalid pdu, addr.numberOfDigits "
+ + std::to_string(length) + " > pdu len "
+ + std::to_string(pdu.size()));
+ }
+ addr->origBytes = readVector(pdu, length); // digits
+ env->bearerReply = readInt(pdu);
+ // CauseCode values:
+ env->replySeqNo = readByte(pdu);
+ env->errorClass = readByte(pdu);
+ env->causeCode = readByte(pdu);
+
+ //encoded BearerData:
+ bearerDataLength = readInt(pdu);
+ // sanity check on the length
+ if (bearerDataLength > pdu.size()) {
+ throw runtime_error(
+ "createFromPdu: Invalid pdu, bearerDataLength "
+ + std::to_string(bearerDataLength) + " > pdu len "
+ + std::to_string(pdu.size()));
+ }
+ env->bearerData = readVector(pdu, bearerDataLength);
+ mPos = 0; // reset
+ // link the filled objects to this SMS
+ mOriginatingAddress = addr;
+ env->origAddress = addr;
+ env->origSubaddress = subaddr;
+ mEnvelope = env;
+ mPdu = pdu;
+
+ parseSms();
+}
+std::shared_ptr<SmsMessage> SmsMessage::createFromPdu(
+ std::vector<uint8_t> pdu) {
+ shared_ptr<SmsMessage> msg = make_shared<SmsMessage>();
+
+ msg->parsePdu(pdu);
+ return msg;
+// try {
+// } catch (RuntimeException ex) {
+// Rlog.e(LOG_TAG, "SMS PDU parsing failed: ", ex);
+// return null;
+// } catch (OutOfMemoryError e) {
+// Log.e(LOG_TAG, "SMS PDU parsing failed with out of memory: ", e);
+// return null;
+// }
+}
+
+SmsConstants::MessageClass SmsMessage::getMessageClass() {
+ if (BearerData::DISPLAY_MODE_IMMEDIATE == mBearerData->displayMode) {
+ return SmsConstants::MessageClass::CLASS_0;
+ } else {
+ return SmsConstants::MessageClass::UNKNOWN;
+ }
+}
+
+int SmsMessage::getMessageType() {
+ // NOTE: mEnvelope.messageType is not set correctly for cell broadcasts with some RILs.
+ // Use the service category parameter to detect CMAS and other cell broadcast messages.
+ if (mEnvelope->serviceCategory != 0) {
+ return SmsEnvelope::MESSAGE_TYPE_BROADCAST;
+ } else {
+ return SmsEnvelope::MESSAGE_TYPE_POINT_TO_POINT;
+ }
+}
+
+/**
+ * Note: This function is a GSM specific functionality which is not supported in CDMA mode.
+ */
+int SmsMessage::getProtocolIdentifier() {
+ //Rlog.w(LOG_TAG, "getProtocolIdentifier: is not supported in CDMA mode.");
+ // (3GPP TS 23.040): "no interworking, but SME to SME protocol":
+ return 0;
+}
+
+/**
+ * Note: This function is a GSM specific functionality which is not supported in CDMA mode.
+ */
+bool SmsMessage::isReplace() {
+ //Rlog.w(LOG_TAG, "isReplace: is not supported in CDMA mode.");
+ return false;
+}
+
+/**
+ * Note: This function is a GSM specific functionality which is not supported in CDMA mode.
+ */
+bool SmsMessage::isCphsMwiMessage() {
+ //Rlog.w(LOG_TAG, "isCphsMwiMessage: is not supported in CDMA mode.");
+ return false;
+}
+
+bool SmsMessage::isMWIClearMessage() {
+ return ((mBearerData != nullptr) && (mBearerData->numberOfMessages == 0));
+}
+
+bool SmsMessage::isMWISetMessage() {
+ return ((mBearerData != nullptr) && (mBearerData->numberOfMessages > 0));
+}
+
+bool SmsMessage::isMwiDontStore() {
+ return ((mBearerData != nullptr) && (mBearerData->numberOfMessages > 0)
+ && (mBearerData->userData == nullptr));
+}
+
+/**
+ * Returns the status for a previously submitted message.
+ * For not interfering with status codes from GSM, this status code is
+ * shifted to the bits 31-16.
+ */
+int SmsMessage::getStatus() {
+ return (status << 16);
+}
+
+/** Return true iff the bearer data message type is DELIVERY_ACK. */
+bool SmsMessage::isStatusReportMessage() {
+ return (mBearerData->messageType == BearerData::MESSAGE_TYPE_DELIVERY_ACK);
+}
+
+/**
+ * Note: This function is a GSM specific functionality which is not supported in CDMA mode.
+ */
+bool SmsMessage::isReplyPathPresent() {
+ //Rlog.w(LOG_TAG, "isReplyPathPresent: is not supported in CDMA mode.");
+ return false;
+}
+void SmsMessage::parseSms() {
+ // Message Waiting Info Record defined in 3GPP2 C.S-0005, 3.7.5.6
+ // It contains only an 8-bit number with the number of messages waiting
+ if (mEnvelope->teleService == SmsEnvelope::TELESERVICE_MWI) {
+ mBearerData = make_shared<BearerData>();
+ if (mEnvelope->bearerData.empty()) {
+ mBearerData->numberOfMessages = 0x000000FF & mEnvelope->bearerData[0];
+ }
+ std::cout << "parseSms: get MWI " << mBearerData->numberOfMessages << endl;
+ /* if (VDBG) {
+ Rlog.d(LOG_TAG, "parseSms: get MWI " +
+ Integer.toString(mBearerData.numberOfMessages));
+ }*/
+ return;
+ }
+ mBearerData = BearerData::decode(mEnvelope->bearerData);
+ RLOGD("MT raw BearerData = '%s'", (HexDump::toHexString(mEnvelope->bearerData)).c_str());
+ RLOGD("MT raw BearerData = '%s'",(mBearerData->toString()).c_str());
+ //std::cout << "MT raw BearerData = '"
+ // << HexDump::toHexString(mEnvelope->bearerData) << "'" << endl;
+ //std::cout << "MT (decoded) BearerData = " << mBearerData->toString() << endl;
+// if (Rlog.isLoggable(LOGGABLE_TAG, Log.VERBOSE)) {
+// Rlog.d(LOG_TAG, "MT raw BearerData = '" +
+// HexDump.toHexString(mEnvelope.bearerData) + "'");
+// Rlog.d(LOG_TAG, "MT (decoded) BearerData = " + mBearerData);
+// }
+ mMessageRef = mBearerData->messageId;
+ if (mBearerData->userData != nullptr) {
+ mUserData = mBearerData->userData->payload;
+ mUserDataHeader = mBearerData->userData->userDataHeader;
+ mMessageBody = mBearerData->userData->payloadStr;
+ }
+
+ if (mOriginatingAddress != nullptr) {
+ for(auto c: mOriginatingAddress->origBytes) {
+ mOriginatingAddress->address.push_back(c);
+ }
+ //std::accumulate(mOriginatingAddress->origBytes.begin(), mOriginatingAddress->origBytes.end(), mOriginatingAddress->address);
+ //mOriginatingAddress->address = HexDump::toHexString(mOriginatingAddress->origBytes); // modify
+ if (mOriginatingAddress->ton == CdmaSmsAddress::TON_INTERNATIONAL_OR_IP) {
+ if (mOriginatingAddress->address.at(0) != '+') {
+ mOriginatingAddress->address = "+" + mOriginatingAddress->address;
+ }
+ }
+ //std::cout << "SMS originating address: " << mOriginatingAddress->address<< endl;
+// if (VDBG) Rlog.v(LOG_TAG, "SMS originating address: "
+// + mOriginatingAddress.address);
+ }
+
+ //if (mBearerData->msgCenterTimeStamp != nullptr) {
+ //mScTimeMillis = mBearerData->msgCenterTimeStamp.toMillis(true);
+ //}
+
+ //if (VDBG) Rlog.d(LOG_TAG, "SMS SC timestamp: " + mScTimeMillis);
+
+ // Message Type (See 3GPP2 C.S0015-B, v2, 4.5.1)
+ if (mBearerData->messageType == BearerData::MESSAGE_TYPE_DELIVERY_ACK) {
+ // The BearerData MsgStatus subparameter should only be
+ // included for DELIVERY_ACK messages. If it occurred for
+ // other messages, it would be unclear what the status
+ // being reported refers to. The MsgStatus subparameter
+ // is primarily useful to indicate error conditions -- a
+ // message without this subparameter is assumed to
+ // indicate successful delivery (status == 0).
+ if (!mBearerData->messageStatusSet) {
+ std::cout << "DELIVERY_ACK message without msgStatus ("
+ << (mUserData.empty() ? "also missing" : "does have") << " userData)."
+ << endl;
+// Rlog.d(LOG_TAG, "DELIVERY_ACK message without msgStatus (" +
+// (mUserData == null ? "also missing" : "does have") +
+// " userData).");
+ status = 0;
+ } else {
+ status = mBearerData->errorClass << 8;
+ status |= mBearerData->messageStatus;
+ }
+ } else if (mBearerData->messageType != BearerData::MESSAGE_TYPE_DELIVER) {
+ throw runtime_error(
+ "Unsupported message type: " + mBearerData->messageType);
+ }
+
+ if (!mMessageBody.empty()) {
+ //std::cout << "SMS message body: '" << mMessageBody << "'" << endl;
+ //if (VDBG) Rlog.v(LOG_TAG, "SMS message body: '" + mMessageBody + "'");
+ parseMessageBody();
+ }
+}
+
+std::vector<std::uint8_t> SmsMessage::getIncomingSmsFingerprint() {
+ RLOGD("getIncomingSmsFingerprint: category=%d, teleservices=%d", mEnvelope->serviceCategory, mEnvelope->teleService);
+ std::vector<uint8_t> output;
+ output.push_back(static_cast<uint8_t> (mEnvelope->serviceCategory));
+ output.push_back(static_cast<uint8_t> (mEnvelope->teleService));
+ output.insert(output.end(), (mEnvelope->origAddress->origBytes).begin(), (mEnvelope->origAddress->origBytes).end());
+ output.insert(output.end(), (mEnvelope->bearerData).begin(), (mEnvelope->bearerData).end());
+ if(mEnvelope->origSubaddress && (!(mEnvelope->origSubaddress->origBytes).empty())) {
+ output.insert(output.end(), (mEnvelope->origSubaddress->origBytes).begin(), (mEnvelope->origSubaddress->origBytes).end());
+ }
+ return output;
+}