3 * Copyright (c) 2000-2012 Samsung Electronics Co., Ltd. All Rights Reserved.
5 * This file is part of msg-service.
7 * Contact: Jaeyun Jeong <jyjeong@samsung.com>
8 * Sangkoo Kim <sangkoo.kim@samsung.com>
9 * Seunghwan Lee <sh.cat.lee@samsung.com>
10 * SoonMin Jung <sm0415.jung@samsung.com>
11 * Jae-Young Lee <jy4710.lee@samsung.com>
12 * KeeBum Kim <keebum.kim@samsung.com>
14 * PROPRIETARY/CONFIDENTIAL
16 * This software is the confidential and proprietary information of
17 * SAMSUNG ELECTRONICS ("Confidential Information"). You shall not
18 * disclose such Confidential Information and shall use it only in
19 * accordance with the terms of the license agreement you entered
20 * into with SAMSUNG ELECTRONICS.
22 * SAMSUNG make no representations or warranties about the suitability
23 * of the software, either express or implied, including but not limited
24 * to the implied warranties of merchantability, fitness for a particular
25 * purpose, or non-infringement. SAMSUNG shall not be liable for any
26 * damages suffered by licensee as a result of using, modifying or
27 * distributing this software or its derivatives.
32 #include "MsgCppTypes.h"
33 #include "MsgUtilFile.h"
34 #include "SmsPluginTextConvert.h"
35 #include "SmsPluginStorage.h"
36 #include "SmsPluginTransport.h"
37 #include "SmsPluginEventHandler.h"
38 #include "SmsPluginWapPushHandler.h"
39 #include "SmsPluginConcatHandler.h"
42 /*==================================================================================================
43 IMPLEMENTATION OF SmsPluginConcatHandler - Member Functions
44 ==================================================================================================*/
45 SmsPluginConcatHandler* SmsPluginConcatHandler::pInstance = NULL;
48 SmsPluginConcatHandler::SmsPluginConcatHandler()
54 SmsPluginConcatHandler::~SmsPluginConcatHandler()
60 SmsPluginConcatHandler* SmsPluginConcatHandler::instance()
63 pInstance = new SmsPluginConcatHandler();
69 bool SmsPluginConcatHandler::IsConcatMsg(SMS_USERDATA_S *pUserData)
73 MSG_DEBUG("headerCnt [%d]", pUserData->headerCnt);
75 for (int i = 0; i < pUserData->headerCnt; i++) {
76 /** Handler Concatenated Message */
77 if (pUserData->header[i].udhType == SMS_UDH_CONCAT_8BIT) {
79 } else if (pUserData->header[i].udhType == SMS_UDH_CONCAT_16BIT) {
90 void SmsPluginConcatHandler::handleConcatMsg(SMS_TPDU_S *pTpdu)
94 MSG_ERROR_T err = MSG_SUCCESS;
95 bool noneConcatTypeHeader = true;
97 if (pTpdu->tpduType != SMS_TPDU_DELIVER) {
98 MSG_DEBUG("The TPDU type is not deliver [%d]", pTpdu->tpduType);
102 SMS_CONCAT_MSG_S msg = {0};
104 for (int i = 0; i < pTpdu->data.deliver.userData.headerCnt; i++) {
105 if (pTpdu->data.deliver.userData.header[i].udhType == SMS_UDH_CONCAT_8BIT) {
106 msg.msgRef = (unsigned short)pTpdu->data.deliver.userData.header[i].udh.concat8bit.msgRef;
107 msg.totalSeg = pTpdu->data.deliver.userData.header[i].udh.concat8bit.totalSeg;
108 msg.seqNum = pTpdu->data.deliver.userData.header[i].udh.concat8bit.seqNum;
110 memcpy(&(msg.timeStamp.time.absolute), &(pTpdu->data.deliver.timeStamp.time.absolute), sizeof(SMS_TIME_ABS_S));
111 memcpy(&(msg.originAddress), &(pTpdu->data.deliver.originAddress), sizeof(SMS_ADDRESS_S));
112 memcpy(&(msg.dcs), &(pTpdu->data.deliver.dcs), sizeof(SMS_DCS_S));
114 if (msg.totalSeg > MAX_SEGMENT_NUM) {
115 MSG_DEBUG("Total Segment Count is over Maximum [%d]", msg.totalSeg);
119 /** check noneConcatTypeHeader */
120 noneConcatTypeHeader = false;
123 } else if (pTpdu->data.deliver.userData.header[i].udhType == SMS_UDH_CONCAT_16BIT) {
124 msg.msgRef = (unsigned short)pTpdu->data.deliver.userData.header[i].udh.concat16bit.msgRef;
125 msg.totalSeg = pTpdu->data.deliver.userData.header[i].udh.concat16bit.totalSeg;
126 msg.seqNum = pTpdu->data.deliver.userData.header[i].udh.concat16bit.seqNum;
128 memcpy(&(msg.timeStamp.time.absolute), &(pTpdu->data.deliver.timeStamp.time.absolute), sizeof(SMS_TIME_ABS_S));
129 memcpy(&(msg.originAddress), &(pTpdu->data.deliver.originAddress), sizeof(SMS_ADDRESS_S));
130 memcpy(&(msg.dcs), &(pTpdu->data.deliver.dcs), sizeof(SMS_DCS_S));
132 if (msg.totalSeg > MAX_SEGMENT_NUM) {
133 MSG_DEBUG("Total Segment Count is over Maximum [%d]", msg.totalSeg);
137 /** check noneConcatTypeHeader */
138 noneConcatTypeHeader = false;
144 unsigned char segCnt = checkConcatMsg(&msg, &(pTpdu->data.deliver.userData));
146 MSG_DEBUG("segCnt [%d]", segCnt);
147 MSG_DEBUG("msg.totalSeg [%d]", msg.totalSeg);
149 if ((segCnt == msg.totalSeg) || noneConcatTypeHeader) {
150 MSG_DEBUG("RECEIVED LAST CONCAT : %d", segCnt);
153 char* pUserData = NULL;
154 AutoPtr<char> dataBuf(&pUserData);
156 MSG_MESSAGE_INFO_S msgInfo = {0};
158 dataSize = makeConcatUserData(msg.msgRef, &pUserData);
161 if (SmsPluginWapPushHandler::instance()->IsWapPushMsg(&(pTpdu->data.deliver.userData)) == true) {
162 SmsPluginWapPushHandler::instance()->copyDeliverData(&(pTpdu->data.deliver));
163 SmsPluginWapPushHandler::instance()->handleWapPushMsg(pUserData, dataSize);
165 convertConcatToMsginfo(&(pTpdu->data.deliver), pUserData, dataSize, &msgInfo);
167 if (msgInfo.msgPort.valid == false) {
168 /** Add Concat Msg into DB */
169 err = SmsPluginStorage::instance()->addMessage(&msgInfo);
172 if (err == MSG_SUCCESS) {
174 err = SmsPluginEventHandler::instance()->callbackMsgIncoming(&msgInfo);
176 if (err != MSG_SUCCESS) {
177 MSG_DEBUG("callbackMsgIncoming() Error !! [%d]", err);
180 MSG_DEBUG("addMessage() Error !! [%d]", err);
185 removeFromConcatList(msg.msgRef);
188 /** Send Deliver Report */
189 SmsPluginTransport::instance()->sendDeliverReport(err);
195 unsigned char SmsPluginConcatHandler::checkConcatMsg(SMS_CONCAT_MSG_S *pConcatMsg, SMS_USERDATA_S *pUserData)
197 if (pConcatMsg == NULL || pUserData == NULL) {
198 MSG_DEBUG("In Parameter is NULL");
202 unsigned char currSegCnt = 0;
206 for (unsigned int i = 0; i < concatList.size(); i++) {
207 if (concatList[i].msgRef == pConcatMsg->msgRef) {
208 if (concatList[i].data.count(pConcatMsg->seqNum) != 0) {
209 MSG_DEBUG("The Sequence Number already exists [%d]", pConcatMsg->seqNum);
213 CONCAT_DATA_S concatData = {0};
215 memcpy(concatData.data, pUserData->data, pUserData->length);
216 concatData.length = pUserData->length;
218 pair<unsigned char, CONCAT_DATA_S> newData(pConcatMsg->seqNum, concatData);
219 concatList[i].data.insert(newData);
221 MSG_DEBUG("MSG DATA : %s", pUserData->data);
222 MSG_DEBUG("PAIR DATA [%d] : %s", newData.first, newData.second.data);
224 concatList[i].segCnt++;
225 concatList[i].totalSize += pUserData->length;
227 currSegCnt = concatList[i].segCnt;
235 /** New Concat Msg */
236 if (bFind == false) {
237 SMS_CONCAT_INFO_S tmpInfo;
239 tmpInfo.msgRef = pConcatMsg->msgRef;
240 tmpInfo.totalSeg = pConcatMsg->totalSeg;
243 memcpy(&(tmpInfo.timeStamp.time.absolute), &(pConcatMsg->timeStamp.time.absolute), sizeof(SMS_TIME_ABS_S));
244 memcpy(&(tmpInfo.originAddress), &(pConcatMsg->originAddress), sizeof(SMS_ADDRESS_S));
245 memcpy(&(tmpInfo.dcs), &(pConcatMsg->dcs), sizeof(SMS_DCS_S));
247 tmpInfo.totalSize = pUserData->length;
249 CONCAT_DATA_S concatData = {0};
251 memcpy(concatData.data, pUserData->data, pUserData->length);
252 concatData.length = pUserData->length;
254 pair<unsigned char, CONCAT_DATA_S> newData(pConcatMsg->seqNum, concatData);
255 tmpInfo.data.insert(newData);
257 MSG_DEBUG("MSG DATA : %s", pUserData->data);
258 MSG_DEBUG("PAIR DATA [%d] : %s", newData.first, newData.second.data);
260 concatList.push_back(tmpInfo);
262 currSegCnt = tmpInfo.segCnt;
269 int SmsPluginConcatHandler::makeConcatUserData(unsigned short MsgRef, char **ppTotalData)
271 concatDataMap::iterator it;
273 int totalSize = 0, offset = 0;
275 for (unsigned int i = 0; i < concatList.size(); i++) {
276 if (concatList[i].msgRef == MsgRef) {
277 totalSize = concatList[i].totalSize;
279 if (totalSize <= 0) {
280 MSG_DEBUG("Size Error : totalSize <= 0");
284 MSG_DEBUG("totalSize [%d]", totalSize);
286 *ppTotalData = new char[totalSize];
288 for (it = concatList[i].data.begin(); it != concatList[i].data.end(); it++) {
289 memcpy(*ppTotalData+offset, it->second.data, it->second.length);
290 offset += it->second.length;
299 void SmsPluginConcatHandler::convertConcatToMsginfo(const SMS_DELIVER_S *pTpdu, const char *pUserData, int DataSize, MSG_MESSAGE_INFO_S *pMsgInfo)
301 /** Convert Type values */
302 pMsgInfo->msgType.mainType = MSG_SMS_TYPE;
303 pMsgInfo->msgType.subType = MSG_NORMAL_SMS;
305 /** set folder id (temporary) */
306 pMsgInfo->folderId = MSG_INBOX_ID;
308 switch(pTpdu->dcs.msgClass)
310 case SMS_MSG_CLASS_0:
311 pMsgInfo->msgType.classType = MSG_CLASS_0;
313 case SMS_MSG_CLASS_1:
314 pMsgInfo->msgType.classType = MSG_CLASS_1;
316 case SMS_MSG_CLASS_2:
317 pMsgInfo->msgType.classType = MSG_CLASS_2;
319 case SMS_MSG_CLASS_3:
320 pMsgInfo->msgType.classType = MSG_CLASS_3;
323 pMsgInfo->msgType.classType = MSG_CLASS_NONE;
326 pMsgInfo->networkStatus = MSG_NETWORK_RECEIVED;
327 pMsgInfo->bRead = false;
328 pMsgInfo->bProtected = false;
329 pMsgInfo->priority = MSG_MESSAGE_PRIORITY_NORMAL;
330 pMsgInfo->direction = MSG_DIRECTION_TYPE_MT;
333 time_t rawtime = time(NULL);
335 pMsgInfo->displayTime = rawtime;
337 /** Convert Address values */
338 pMsgInfo->nAddressCnt = 1;
339 pMsgInfo->addressList[0].addressType = MSG_ADDRESS_TYPE_PLMN;
340 strncpy(pMsgInfo->addressList[0].addressVal, pTpdu->originAddress.address, MAX_ADDRESS_VAL_LEN);
342 pMsgInfo->msgPort.valid = false;
343 pMsgInfo->msgPort.dstPort = 0;
344 pMsgInfo->msgPort.srcPort = 0;
346 for (int i = 0; i < pTpdu->userData.headerCnt; i++) {
347 /** Convert UDH values - Port Number */
348 if (pTpdu->userData.header[i].udhType == SMS_UDH_APP_PORT_8BIT) {
349 pMsgInfo->msgPort.valid = true;
350 pMsgInfo->msgPort.dstPort = pTpdu->userData.header[i].udh.appPort8bit.destPort;
351 pMsgInfo->msgPort.srcPort = pTpdu->userData.header[i].udh.appPort8bit.originPort;
352 } else if (pTpdu->userData.header[i].udhType == SMS_UDH_APP_PORT_16BIT) {
353 pMsgInfo->msgPort.valid = true;
354 pMsgInfo->msgPort.dstPort = pTpdu->userData.header[i].udh.appPort16bit.destPort;
355 pMsgInfo->msgPort.srcPort = pTpdu->userData.header[i].udh.appPort16bit.originPort;
359 int bufSize = (MAX_MSG_DATA_LEN*MAX_SEGMENT_NUM) + 1;
361 char tmpBuf[bufSize];
362 memset(tmpBuf, 0x00, sizeof(tmpBuf));
364 /** Convert Data values */
365 if (pTpdu->dcs.codingScheme == SMS_CHARSET_7BIT) {
366 SMS_LANG_INFO_S langInfo = {0};
368 langInfo.bSingleShift = false;
369 langInfo.bLockingShift = false;
371 pMsgInfo->encodeType = MSG_ENCODE_GSM7BIT;
372 pMsgInfo->dataSize = SmsPluginTextConvert::instance()->convertGSM7bitToUTF8((unsigned char*)tmpBuf, bufSize, (unsigned char*)pUserData, DataSize, &langInfo);
373 } else if (pTpdu->dcs.codingScheme == SMS_CHARSET_8BIT) {
374 pMsgInfo->encodeType = MSG_ENCODE_8BIT;
375 memcpy(tmpBuf, pUserData, DataSize);
376 pMsgInfo->dataSize = DataSize;
377 } else if (pTpdu->dcs.codingScheme == SMS_CHARSET_UCS2) {
378 pMsgInfo->encodeType = MSG_ENCODE_UCS2;
379 pMsgInfo->dataSize = SmsPluginTextConvert::instance()->convertUCS2ToUTF8((unsigned char*)tmpBuf, bufSize, (unsigned char*)pUserData, DataSize);
382 MSG_DEBUG("Data Size [%d]", pMsgInfo->dataSize);
383 MSG_DEBUG("Data [%s]", tmpBuf);
385 if (pMsgInfo->dataSize > MAX_MSG_TEXT_LEN) {
386 pMsgInfo->bTextSms = false;
388 /** Save Message Data into File */
389 char fileName[MAX_COMMON_INFO_SIZE+1];
390 memset(fileName, 0x00, sizeof(fileName));
392 MsgCreateFileName(fileName);
394 MSG_DEBUG("Save Message Data into file : size[%d] name[%s]\n", pMsgInfo->dataSize, fileName);
395 MsgWriteIpcFile(fileName, tmpBuf, pMsgInfo->dataSize);
397 strncpy(pMsgInfo->msgData, fileName, MAX_MSG_DATA_LEN);
399 pMsgInfo->bTextSms = true;
401 memset(pMsgInfo->msgText, 0x00, sizeof(pMsgInfo->msgText));
402 memcpy(pMsgInfo->msgText, tmpBuf, pMsgInfo->dataSize);
407 void SmsPluginConcatHandler::removeFromConcatList(unsigned short MsgRef)
409 for (int index = concatList.size(); index >= 0 ; index--) {
410 if (concatList[index].msgRef == MsgRef) {
411 MSG_DEBUG("remove concatlist of the index [%d]", index);
412 concatList.erase(concatList.begin()+index);