[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;
+}