blob: 4c38581e760708baef1afe31ccc18adc18e29682 [file] [log] [blame]
/* Copyright Statement:
*
* This software/firmware and related documentation ("MediaTek Software") are
* protected under relevant copyright laws. The information contained herein
* is confidential and proprietary to MediaTek Inc. and/or its licensors.
* Without the prior written permission of MediaTek inc. and/or its licensors,
* any reproduction, modification, use or disclosure of MediaTek Software,
* and information contained herein, in whole or in part, shall be strictly prohibited.
*/
/* MediaTek Inc. (C) 2010. All rights reserved.
*
* BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
* THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
* CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
* SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
* STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
* CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
*
* The following software/firmware and/or related documentation ("MediaTek Software")
* have been modified by MediaTek Inc. All revisions are subject to any receiver's
* applicable license agreements with MediaTek Inc.
*/
#include <memory>
#include <vector>
#include <string>
using namespace std;
#include "SmsHeader.h"
#include "HexDump.h"
SmsHeader::SmsHeader() {
// TODO Auto-generated constructor stub
}
SmsHeader::~SmsHeader() {
// TODO Auto-generated destructor stub
}
std::shared_ptr<SmsHeader> SmsHeader::fromByteArray(std::vector<uint8_t> v) {
//ByteArrayInputStream inStream = new ByteArrayInputStream(data);
//uint8_t* temp = data;
std::shared_ptr<SmsHeader> smsHeader = std::make_shared<SmsHeader>();
auto beg = v.begin();
while (beg < v.end() ) {
/**
* NOTE: as defined in the spec, ConcatRef and PortAddr
* fields should not reoccur, but if they do the last
* occurrence is to be used. Also, for ConcatRef
* elements, if the count is zero, sequence is zero, or
* sequence is larger than count, the entire element is to
* be ignored.
*/
int id = (*(beg++));
int len = (*(beg++));
std::shared_ptr<ConcatRef> concatRef;
std::shared_ptr<PortAddrs> portAddrs;
switch (id) {
case ELT_ID_CONCATENATED_8_BIT_REFERENCE:
{
concatRef = make_shared<ConcatRef>();
concatRef->refNumber = (*(beg++));
concatRef->msgCount = (*(beg++));
concatRef->seqNumber = (*(beg++));
concatRef->isEightBits = true;
if (concatRef->msgCount != 0 && concatRef->seqNumber != 0
&& concatRef->seqNumber <= concatRef->msgCount) {
smsHeader->concatRef = concatRef;
}
break;
}
case ELT_ID_CONCATENATED_16_BIT_REFERENCE:
concatRef = make_shared<ConcatRef>();
concatRef->refNumber = ((*(beg++)) << 8) | (*(beg++));
concatRef->msgCount = (*(beg++));
concatRef->seqNumber = (*(beg++));
concatRef->isEightBits = false;
if (concatRef->msgCount != 0 && concatRef->seqNumber != 0
&& concatRef->seqNumber <= concatRef->msgCount) {
smsHeader->concatRef = concatRef;
}
break;
case ELT_ID_APPLICATION_PORT_ADDRESSING_8_BIT:
portAddrs = make_shared<PortAddrs>();
portAddrs->destPort = (*(beg++));
portAddrs->origPort = (*(beg++));
portAddrs->areEightBits = true;
smsHeader->portAddrs = portAddrs;
break;
case ELT_ID_APPLICATION_PORT_ADDRESSING_16_BIT:
portAddrs = make_shared<PortAddrs>();
portAddrs->destPort = ((*(beg++)) << 8) | (*(beg++));
portAddrs->origPort = ((*(beg++)) << 8) | (*(beg++));
portAddrs->areEightBits = false;
smsHeader->portAddrs = portAddrs;
break;
case ELT_ID_NATIONAL_LANGUAGE_SINGLE_SHIFT:
smsHeader->languageShiftTable = (*(beg++));
break;
case ELT_ID_NATIONAL_LANGUAGE_LOCKING_SHIFT:
smsHeader->languageTable = (*(beg++));
break;
case ELT_ID_SPECIAL_SMS_MESSAGE_INDICATION: {
auto specialSmsMsg = make_shared<SpecialSmsMsg>();
specialSmsMsg->msgIndType = (*(beg++));
specialSmsMsg->msgCount = (*(beg++));
smsHeader->specialSmsMsgList.push_back(specialSmsMsg);
break;
}
default:
auto miscElt = make_shared<MiscElt>();
miscElt->id = id;
//miscElt->data.insert(miscElt->data.end(), beg, v.end());
smsHeader->miscEltList.push_back(miscElt);
break;
}
}
return smsHeader;
}
std::vector<uint8_t> SmsHeader::toByteArray(
std::shared_ptr<SmsHeader> smsHeader) {
std::vector<uint8_t> temp;
temp.clear();
if ((smsHeader->portAddrs == nullptr) && (smsHeader->concatRef == nullptr)
&& (smsHeader->specialSmsMsgList.empty())
&& (smsHeader->miscEltList.empty())
&& (smsHeader->languageShiftTable == 0)
&& (smsHeader->languageTable == 0)) {
return temp;
}
auto concatRef = smsHeader->concatRef;
if (concatRef != nullptr) {
if (concatRef->isEightBits) {
temp.push_back(ELT_ID_CONCATENATED_8_BIT_REFERENCE);
temp.push_back(3);
temp.push_back(concatRef->refNumber);
} else {
temp.push_back(ELT_ID_CONCATENATED_16_BIT_REFERENCE);
temp.push_back(4);
temp.push_back(concatRef->refNumber >> 8);
temp.push_back(concatRef->refNumber & 0x00FF);
}
temp.push_back(concatRef->msgCount);
temp.push_back(concatRef->seqNumber);
}
auto portAddrs = smsHeader->portAddrs;
if (portAddrs != nullptr) {
if (portAddrs->areEightBits) {
temp.push_back(ELT_ID_APPLICATION_PORT_ADDRESSING_8_BIT);
temp.push_back(2);
temp.push_back(portAddrs->destPort);
temp.push_back(portAddrs->origPort);
} else {
temp.push_back(ELT_ID_APPLICATION_PORT_ADDRESSING_16_BIT);
temp.push_back(4);
temp.push_back(portAddrs->destPort >> 8);
temp.push_back(portAddrs->destPort & 0x00FF);
temp.push_back(portAddrs->origPort >> 8);
temp.push_back(portAddrs->origPort & 0x00FF);
}
}
if (smsHeader->languageShiftTable != 0) {
temp.push_back(ELT_ID_NATIONAL_LANGUAGE_SINGLE_SHIFT);
temp.push_back(1);
temp.push_back(smsHeader->languageShiftTable);
}
if (smsHeader->languageTable != 0) {
temp.push_back(ELT_ID_NATIONAL_LANGUAGE_LOCKING_SHIFT);
temp.push_back(1);
temp.push_back(smsHeader->languageTable);
}
for (auto specialSmsMsg : smsHeader->specialSmsMsgList) {
temp.push_back(ELT_ID_SPECIAL_SMS_MESSAGE_INDICATION);
temp.push_back(2);
temp.push_back(specialSmsMsg->msgIndType & 0xFF);
temp.push_back(specialSmsMsg->msgCount & 0xFF);
}
for (auto miscElt : smsHeader->miscEltList) {
temp.push_back(miscElt->id);
temp.push_back(miscElt->data.size());
temp.insert(temp.end(), miscElt->data.begin(), miscElt->data.end());
}
return temp;
}
std::string SmsHeader::toString() {
string builder;
builder.append("UserDataHeader ");
builder.append("{ ConcatRef ");
if (concatRef == nullptr) {
builder.append("unset");
} else {
builder.append("{ refNumber=" + std::to_string(concatRef->refNumber));
builder.append(", msgCount=" + std::to_string(concatRef->msgCount));
builder.append(", seqNumber=" + std::to_string(concatRef->seqNumber));
builder.append(", isEightBits=" + std::to_string(concatRef->isEightBits));
builder.append(" }");
}
builder.append(", PortAddrs ");
if (portAddrs == nullptr) {
builder.append("unset");
} else {
builder.append("{ destPort=" + std::to_string(portAddrs->destPort));
builder.append(", origPort=" + std::to_string(portAddrs->origPort));
builder.append(", areEightBits=" + std::to_string(portAddrs->areEightBits));
builder.append(" }");
}
if (languageShiftTable != 0) {
builder.append(
", languageShiftTable=" + std::to_string(languageShiftTable));
}
if (languageTable != 0) {
builder.append(", languageTable=" + std::to_string(languageTable));
}
for (auto specialSmsMsg : specialSmsMsgList) {
builder.append(", SpecialSmsMsg ");
builder.append("{ msgIndType=" + std::to_string(specialSmsMsg->msgIndType));
builder.append(", msgCount=" + std::to_string(specialSmsMsg->msgCount));
builder.append(" }");
}
for (auto miscElt : miscEltList) {
builder.append(", MiscElt ");
builder.append("{ id=" + std::to_string(miscElt->id));
builder.append(", length=" + std::to_string((int) miscElt->data.size()));
builder.append(", data=" + HexDump::toHexString(miscElt->data));
builder.append(" }");
}
builder.append(" }");
return builder;
}