update tizen source
[framework/messaging/msg-service.git] / plugin / sms_plugin / SmsPluginConcatHandler.cpp
1 /*
2 *
3 * Copyright (c) 2000-2012 Samsung Electronics Co., Ltd. All Rights Reserved.
4 *
5 * This file is part of msg-service.
6 *
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>
13 *
14 * PROPRIETARY/CONFIDENTIAL
15 *
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.
21 *
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.
28 *
29 */
30
31 #include "MsgDebug.h"
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"
40
41
42 /*==================================================================================================
43                                      IMPLEMENTATION OF SmsPluginConcatHandler - Member Functions
44 ==================================================================================================*/
45 SmsPluginConcatHandler* SmsPluginConcatHandler::pInstance = NULL;
46
47
48 SmsPluginConcatHandler::SmsPluginConcatHandler()
49 {
50         concatList.clear();
51 }
52
53
54 SmsPluginConcatHandler::~SmsPluginConcatHandler()
55 {
56         concatList.clear();
57 }
58
59
60 SmsPluginConcatHandler* SmsPluginConcatHandler::instance()
61 {
62         if (!pInstance)
63                 pInstance = new SmsPluginConcatHandler();
64
65         return pInstance;
66 }
67
68
69 bool SmsPluginConcatHandler::IsConcatMsg(SMS_USERDATA_S *pUserData)
70 {
71         MSG_BEGIN();
72
73         MSG_DEBUG("headerCnt [%d]", pUserData->headerCnt);
74
75         for (int i = 0; i < pUserData->headerCnt; i++) {
76                 /**  Handler Concatenated Message */
77                 if (pUserData->header[i].udhType == SMS_UDH_CONCAT_8BIT) {
78                         return true;
79                 } else if (pUserData->header[i].udhType == SMS_UDH_CONCAT_16BIT) {
80                         return true;
81                 }
82         }
83
84         MSG_END();
85
86         return false;
87 }
88
89
90 void SmsPluginConcatHandler::handleConcatMsg(SMS_TPDU_S *pTpdu)
91 {
92         MSG_BEGIN();
93
94         MSG_ERROR_T err = MSG_SUCCESS;
95         bool noneConcatTypeHeader = true;
96
97         if (pTpdu->tpduType != SMS_TPDU_DELIVER) {
98                 MSG_DEBUG("The TPDU type is not deliver [%d]", pTpdu->tpduType);
99                 return;
100         }
101
102         SMS_CONCAT_MSG_S msg = {0};
103
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;
109
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));
113
114                         if (msg.totalSeg > MAX_SEGMENT_NUM) {
115                                 MSG_DEBUG("Total Segment Count is over Maximum [%d]", msg.totalSeg);
116                                 return;
117                         }
118
119                         /**  check noneConcatTypeHeader */
120                         noneConcatTypeHeader = false;
121
122                         break;
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;
127
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));
131
132                         if (msg.totalSeg > MAX_SEGMENT_NUM) {
133                                 MSG_DEBUG("Total Segment Count is over Maximum [%d]", msg.totalSeg);
134                                 return;
135                         }
136
137                         /**  check noneConcatTypeHeader */
138                         noneConcatTypeHeader = false;
139
140                         break;
141                 }
142         }
143
144         unsigned char segCnt = checkConcatMsg(&msg, &(pTpdu->data.deliver.userData));
145
146         MSG_DEBUG("segCnt [%d]", segCnt);
147         MSG_DEBUG("msg.totalSeg [%d]", msg.totalSeg);
148
149         if ((segCnt == msg.totalSeg) || noneConcatTypeHeader) {
150                 MSG_DEBUG("RECEIVED LAST CONCAT : %d", segCnt);
151
152                 int dataSize = 0;
153                 char* pUserData = NULL;
154                 AutoPtr<char> dataBuf(&pUserData);
155
156                 MSG_MESSAGE_INFO_S msgInfo = {0};
157
158                 dataSize = makeConcatUserData(msg.msgRef, &pUserData);
159
160                 if (dataSize > 0) {
161                         if (SmsPluginWapPushHandler::instance()->IsWapPushMsg(&(pTpdu->data.deliver.userData)) == true) {
162                                 SmsPluginWapPushHandler::instance()->copyDeliverData(&(pTpdu->data.deliver));
163                                 SmsPluginWapPushHandler::instance()->handleWapPushMsg(pUserData, dataSize);
164                         } else {
165                                 convertConcatToMsginfo(&(pTpdu->data.deliver), pUserData, dataSize, &msgInfo);
166
167                                 if (msgInfo.msgPort.valid == false) {
168                                         /** Add Concat Msg into DB */
169                                         err = SmsPluginStorage::instance()->addMessage(&msgInfo);
170                                 }
171
172                                 if (err == MSG_SUCCESS) {
173                                         /** Callback */
174                                         err = SmsPluginEventHandler::instance()->callbackMsgIncoming(&msgInfo);
175
176                                         if (err != MSG_SUCCESS) {
177                                                 MSG_DEBUG("callbackMsgIncoming() Error !! [%d]", err);
178                                         }
179                                 } else {
180                                         MSG_DEBUG("addMessage() Error !! [%d]", err);
181                                 }
182                         }
183                 }
184
185                 removeFromConcatList(msg.msgRef);
186         }
187
188         /** Send Deliver Report */
189         SmsPluginTransport::instance()->sendDeliverReport(err);
190
191         MSG_END();
192 }
193
194
195 unsigned char SmsPluginConcatHandler::checkConcatMsg(SMS_CONCAT_MSG_S *pConcatMsg, SMS_USERDATA_S *pUserData)
196 {
197         if (pConcatMsg == NULL || pUserData == NULL) {
198                 MSG_DEBUG("In Parameter is NULL");
199                 return 0;
200         }
201
202         unsigned char currSegCnt = 0;
203
204         bool bFind = false;
205
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);
210                                 return 0;
211                         }
212
213                         CONCAT_DATA_S concatData = {0};
214
215                         memcpy(concatData.data, pUserData->data, pUserData->length);
216                         concatData.length = pUserData->length;
217
218                         pair<unsigned char, CONCAT_DATA_S> newData(pConcatMsg->seqNum, concatData);
219                         concatList[i].data.insert(newData);
220
221                         MSG_DEBUG("MSG DATA : %s", pUserData->data);
222                         MSG_DEBUG("PAIR DATA [%d] : %s", newData.first, newData.second.data);
223
224                         concatList[i].segCnt++;
225                         concatList[i].totalSize += pUserData->length;
226
227                         currSegCnt = concatList[i].segCnt;
228
229                         bFind = true;
230
231                         break;
232                 }
233         }
234
235         /** New Concat Msg */
236         if (bFind == false) {
237                 SMS_CONCAT_INFO_S tmpInfo;
238
239                 tmpInfo.msgRef = pConcatMsg->msgRef;
240                 tmpInfo.totalSeg = pConcatMsg->totalSeg;
241                 tmpInfo.segCnt = 1;
242
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));
246
247                 tmpInfo.totalSize = pUserData->length;
248
249                 CONCAT_DATA_S concatData = {0};
250
251                 memcpy(concatData.data, pUserData->data, pUserData->length);
252                 concatData.length = pUserData->length;
253
254                 pair<unsigned char, CONCAT_DATA_S> newData(pConcatMsg->seqNum, concatData);
255                 tmpInfo.data.insert(newData);
256
257                 MSG_DEBUG("MSG DATA : %s", pUserData->data);
258                 MSG_DEBUG("PAIR DATA [%d] : %s", newData.first, newData.second.data);
259
260                 concatList.push_back(tmpInfo);
261
262                 currSegCnt = tmpInfo.segCnt;
263         }
264
265         return currSegCnt;
266 }
267
268
269 int SmsPluginConcatHandler::makeConcatUserData(unsigned short MsgRef, char **ppTotalData)
270 {
271         concatDataMap::iterator it;
272
273         int totalSize = 0, offset = 0;
274
275         for (unsigned int i = 0; i < concatList.size(); i++) {
276                 if (concatList[i].msgRef == MsgRef) {
277                         totalSize = concatList[i].totalSize;
278
279                         if (totalSize <= 0) {
280                                 MSG_DEBUG("Size Error : totalSize <= 0");
281                                 return 0;
282                         }
283
284                         MSG_DEBUG("totalSize [%d]", totalSize);
285
286                         *ppTotalData = new char[totalSize];
287
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;
291                         }
292                 }
293         }
294
295         return totalSize;
296 }
297
298
299 void SmsPluginConcatHandler::convertConcatToMsginfo(const SMS_DELIVER_S *pTpdu, const char *pUserData, int DataSize, MSG_MESSAGE_INFO_S *pMsgInfo)
300 {
301         /** Convert Type  values */
302         pMsgInfo->msgType.mainType = MSG_SMS_TYPE;
303         pMsgInfo->msgType.subType = MSG_NORMAL_SMS;
304
305         /** set folder id (temporary) */
306         pMsgInfo->folderId = MSG_INBOX_ID;
307
308         switch(pTpdu->dcs.msgClass)
309         {
310                 case SMS_MSG_CLASS_0:
311                         pMsgInfo->msgType.classType = MSG_CLASS_0;
312                         break;
313                 case SMS_MSG_CLASS_1:
314                         pMsgInfo->msgType.classType = MSG_CLASS_1;
315                         break;
316                 case SMS_MSG_CLASS_2:
317                         pMsgInfo->msgType.classType = MSG_CLASS_2;
318                         break;
319                 case SMS_MSG_CLASS_3:
320                         pMsgInfo->msgType.classType = MSG_CLASS_3;
321                         break;
322                 default:
323                         pMsgInfo->msgType.classType = MSG_CLASS_NONE;
324         }
325
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;
331
332
333         time_t rawtime = time(NULL);
334
335         pMsgInfo->displayTime = rawtime;
336
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);
341
342         pMsgInfo->msgPort.valid = false;
343         pMsgInfo->msgPort.dstPort = 0;
344         pMsgInfo->msgPort.srcPort = 0;
345
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;
356                 }
357         }
358
359         int bufSize = (MAX_MSG_DATA_LEN*MAX_SEGMENT_NUM) + 1;
360
361         char tmpBuf[bufSize];
362         memset(tmpBuf, 0x00, sizeof(tmpBuf));
363
364         /** Convert Data values */
365         if (pTpdu->dcs.codingScheme == SMS_CHARSET_7BIT) {
366                 SMS_LANG_INFO_S langInfo = {0};
367
368                 langInfo.bSingleShift = false;
369                 langInfo.bLockingShift = false;
370
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);
380         }
381
382         MSG_DEBUG("Data Size [%d]", pMsgInfo->dataSize);
383         MSG_DEBUG("Data [%s]", tmpBuf);
384
385         if (pMsgInfo->dataSize > MAX_MSG_TEXT_LEN) {
386                 pMsgInfo->bTextSms = false;
387
388                 /** Save Message Data into File */
389                 char fileName[MAX_COMMON_INFO_SIZE+1];
390                 memset(fileName, 0x00, sizeof(fileName));
391
392                 MsgCreateFileName(fileName);
393
394                 MSG_DEBUG("Save Message Data into file : size[%d] name[%s]\n", pMsgInfo->dataSize, fileName);
395                 MsgWriteIpcFile(fileName, tmpBuf, pMsgInfo->dataSize);
396
397                 strncpy(pMsgInfo->msgData, fileName, MAX_MSG_DATA_LEN);
398         } else {
399                 pMsgInfo->bTextSms = true;
400
401                 memset(pMsgInfo->msgText, 0x00, sizeof(pMsgInfo->msgText));
402                 memcpy(pMsgInfo->msgText, tmpBuf, pMsgInfo->dataSize);
403         }
404 }
405
406
407 void SmsPluginConcatHandler::removeFromConcatList(unsigned short MsgRef)
408 {
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);
413                         break;
414                 }
415         }
416 }