Merge branch 'tizen_3.0' into tizen
[platform/core/messaging/msg-service.git] / plugin / sms_plugin / SmsPluginConcatHandler.cpp
1 /*
2  * Copyright (c) 2014 Samsung Electronics Co., Ltd. All rights reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15 */
16
17 #include "MsgDebug.h"
18 #include "MsgException.h"
19 #include "MsgCppTypes.h"
20 #include "MsgUtilFile.h"
21 #include "MsgGconfWrapper.h"
22 #include "MsgNotificationWrapper.h"
23 #include "SmsPluginStorage.h"
24 #include "SmsPluginTransport.h"
25 #include "SmsPluginEventHandler.h"
26 #include "SmsPluginWapPushHandler.h"
27 #include "SmsPluginConcatHandler.h"
28 #include "SmsPluginSimMsg.h"
29 #include "SmsPluginDSHandler.h"
30
31 /*==================================================================================================
32                                      IMPLEMENTATION OF SmsPluginConcatHandler - Member Functions
33 ==================================================================================================*/
34 SmsPluginConcatHandler* SmsPluginConcatHandler::pInstance = NULL;
35
36
37 SmsPluginConcatHandler::SmsPluginConcatHandler()
38 {
39         concatList.clear();
40 }
41
42
43 SmsPluginConcatHandler::~SmsPluginConcatHandler()
44 {
45         concatList.clear();
46 }
47
48
49 SmsPluginConcatHandler* SmsPluginConcatHandler::instance()
50 {
51         if (!pInstance)
52                 pInstance = new SmsPluginConcatHandler();
53
54         return pInstance;
55 }
56
57
58 bool SmsPluginConcatHandler::IsConcatMsg(SMS_USERDATA_S *pUserData)
59 {
60         MSG_BEGIN();
61
62         MSG_DEBUG("headerCnt [%d]", pUserData->headerCnt);
63
64         for (int i = 0; i < pUserData->headerCnt; i++) {
65                 /**  Handler Concatenated Message */
66                 if (pUserData->header[i].udhType == SMS_UDH_CONCAT_8BIT) {
67                         return true;
68                 } else if (pUserData->header[i].udhType == SMS_UDH_CONCAT_16BIT) {
69                         return true;
70                 }
71         }
72
73         MSG_END();
74
75         return false;
76 }
77
78
79 void SmsPluginConcatHandler::handleConcatMsg(TapiHandle *handle, SMS_TPDU_S *pTpdu)
80 {
81         MSG_BEGIN();
82
83         msg_error_t err = MSG_SUCCESS;
84         bool noneConcatTypeHeader = true;
85
86         if (pTpdu->tpduType != SMS_TPDU_DELIVER) {
87                 MSG_DEBUG("The TPDU type is not deliver [%d]", pTpdu->tpduType);
88                 return;
89         }
90
91         SMS_CONCAT_MSG_S msg = {0};
92
93         msg.simIndex = SmsPluginDSHandler::instance()->getSimIndex(handle);
94
95         for (int i = 0; i < pTpdu->data.deliver.userData.headerCnt; i++) {
96                 if (pTpdu->data.deliver.userData.header[i].udhType == SMS_UDH_CONCAT_8BIT) {
97                         msg.msgRef = (unsigned short)pTpdu->data.deliver.userData.header[i].udh.concat8bit.msgRef;
98                         msg.totalSeg = pTpdu->data.deliver.userData.header[i].udh.concat8bit.totalSeg;
99                         msg.seqNum = pTpdu->data.deliver.userData.header[i].udh.concat8bit.seqNum;
100
101                         memcpy(&(msg.timeStamp.time.absolute), &(pTpdu->data.deliver.timeStamp.time.absolute), sizeof(SMS_TIME_ABS_S));
102                         memcpy(&(msg.originAddress), &(pTpdu->data.deliver.originAddress), sizeof(SMS_ADDRESS_S));
103                         memcpy(&(msg.dcs), &(pTpdu->data.deliver.dcs), sizeof(SMS_DCS_S));
104
105 #if 0
106                         if (msg.totalSeg > MAX_SEGMENT_NUM) {
107                                 MSG_DEBUG("Total Segment Count is over Maximum [%d]", msg.totalSeg);
108                                 return;
109                         }
110 #endif
111                         /**  check noneConcatTypeHeader */
112                         noneConcatTypeHeader = false;
113
114                         break;
115                 } else if (pTpdu->data.deliver.userData.header[i].udhType == SMS_UDH_CONCAT_16BIT) {
116                         msg.msgRef = (unsigned short)pTpdu->data.deliver.userData.header[i].udh.concat16bit.msgRef;
117                         msg.totalSeg = pTpdu->data.deliver.userData.header[i].udh.concat16bit.totalSeg;
118                         msg.seqNum = pTpdu->data.deliver.userData.header[i].udh.concat16bit.seqNum;
119
120                         memcpy(&(msg.timeStamp.time.absolute), &(pTpdu->data.deliver.timeStamp.time.absolute), sizeof(SMS_TIME_ABS_S));
121                         memcpy(&(msg.originAddress), &(pTpdu->data.deliver.originAddress), sizeof(SMS_ADDRESS_S));
122                         memcpy(&(msg.dcs), &(pTpdu->data.deliver.dcs), sizeof(SMS_DCS_S));
123 #if 0
124                         if (msg.totalSeg > MAX_SEGMENT_NUM) {
125                                 MSG_DEBUG("Total Segment Count is over Maximum [%d]", msg.totalSeg);
126                                 return;
127                         }
128 #endif
129
130                         /**  check noneConcatTypeHeader */
131                         noneConcatTypeHeader = false;
132
133                         break;
134                 }
135         }
136
137         unsigned char segCnt = checkConcatMsg(&msg, &(pTpdu->data.deliver.userData));
138
139         MSG_DEBUG("segCnt [%d]", segCnt);
140         MSG_DEBUG("msg.totalSeg [%d]", msg.totalSeg);
141
142         if ((segCnt == msg.totalSeg) || noneConcatTypeHeader) {
143                 MSG_DEBUG("RECEIVED LAST CONCAT : %d", segCnt);
144
145                 int dataSize = 0;
146                 char* pUserData = NULL;
147                 bool simSlotSizeOver = false;
148                 unique_ptr<char*, void(*)(char**)> dataBuf(&pUserData, unique_ptr_deleter);
149
150                 MSG_MESSAGE_INFO_S msgInfo = {0};
151
152                 msgInfo.addressList = NULL;
153                 unique_ptr<MSG_ADDRESS_INFO_S*, void(*)(MSG_ADDRESS_INFO_S**)> addressListBuf(&msgInfo.addressList, unique_ptr_deleter);
154                 msgInfo.sim_idx = msg.simIndex;
155
156                 dataSize = makeConcatUserData(msg.msgRef, msg.simIndex, &pUserData, msg.originAddress.address);
157
158                 if (dataSize > 0) {
159                         if (SmsPluginWapPushHandler::instance()->IsWapPushMsg(&(pTpdu->data.deliver.userData)) == true) {
160                                 SmsPluginWapPushHandler::instance()->copyDeliverData(&(pTpdu->data.deliver));
161                                 msgInfo.msgType.mainType = MSG_SMS_TYPE;
162                                 if (err == MSG_SUCCESS) {
163                                         time_t sent_time = 0;
164                                         if (pTpdu->data.deliver.timeStamp.format == SMS_TIME_ABSOLUTE) {
165                                                 sent_time = time(NULL);
166                                         }
167
168                                         SmsPluginWapPushHandler::instance()->handleWapPushMsg(pUserData, dataSize, msg.simIndex, sent_time);
169                                 }
170                         } else {
171                                 convertConcatToMsginfo(&(pTpdu->data.deliver), pUserData, dataSize, &msgInfo);
172
173                                 if (msgInfo.msgType.classType == MSG_CLASS_2) {
174                                         msgInfo.storageId = MSG_STORAGE_SIM;
175                                         SmsPluginSimMsg::instance()->setSmsTpduTotalSegCount(msg.totalSeg);
176                                 }
177
178                                 if (msgInfo.msgPort.valid == true) {
179                                         if ((msgInfo.msgPort.dstPort >= 0x23F4 && msgInfo.msgPort.dstPort <= 0x23F7) || /** Check unsupported message (Vcalendar WAP push) **/
180                                                 (msgInfo.msgPort.dstPort == 0x1581)) { /** Check unsupported message (ringtone smart message) **/
181                                                 memset(msgInfo.msgText, 0x00, sizeof(msgInfo.msgText));
182                                                 snprintf(msgInfo.msgText, sizeof(msgInfo.msgText), "<<Content not supported>>");
183                                                 msgInfo.dataSize = strlen(msgInfo.msgText);
184                                                 msgInfo.msgPort.valid = false;
185                                         }
186                                 }
187
188                                 if (msgInfo.msgPort.valid == false) {
189                                         /** Add Concat Msg into DB */
190
191                                         /* check Class2 Normal SMS is longer than SIM slot full size and send DeliveryReport SUCCESS because that Class2 msg cannot be saved on SIM
192                                          * It MUST be done before calling addClass2Message(thread) beause 10+ page message body ipc file is deleted after SmsPluginTransport::instance()->msgInfoToSubmitData() */
193                                         if (msgInfo.msgType.subType == MSG_NORMAL_SMS && msgInfo.msgType.classType == MSG_CLASS_2 &&
194                                                 (SmsPluginSimMsg::instance()->checkSimMsgFull(msg.simIndex, segCnt) == true)) {
195                                                 char keyName[MAX_VCONFKEY_NAME_LEN];
196                                                 memset(keyName, 0x00, sizeof(keyName));
197                                                 snprintf(keyName, sizeof(keyName), "%s/%d", SIM_TOTAL_COUNT, msg.simIndex);
198                                                 int totalCnt;
199                                                 if (MsgSettingGetInt(keyName, &totalCnt) != MSG_SUCCESS) {
200                                                         MSG_INFO("MsgSettingGetInt() is failed");
201                                                 }
202
203                                                 if (segCnt > totalCnt) {
204                                                         /* send DeliveryResport as MSG_SUCCESS and return when total sim storage cnt is less than segment cnt. */
205                                                         MSG_INFO("SIM slot total count [%d] is less than total sement count of Class2 message [%d], send delivery report as SUCCESS and save it only PHONE", totalCnt, segCnt);
206
207                                                         SmsPluginTransport::instance()->sendDeliverReport(handle, MSG_SUCCESS);
208
209                                                         MsgInsertTicker("Message is too large to store as a single message to SIM card.", SMS_MESSAGE_SIZE_OVER_SIM_SLOT_SIZE, false, 0);
210
211                                                         simSlotSizeOver = true;
212                                                 }
213                                         } else {
214                                                 err = SmsPluginStorage::instance()->checkMessage(&msgInfo);
215                                         }
216                                 }
217
218                                 if (err == MSG_SUCCESS) {
219                                         if (simSlotSizeOver || (msgInfo.msgType.classType != MSG_CLASS_2)) {
220                                                 if (simSlotSizeOver)
221                                                         msgInfo.storageId = MSG_STORAGE_PHONE;
222
223                                                 /** Callback */
224                                                 err = SmsPluginEventHandler::instance()->callbackMsgIncoming(&msgInfo);
225
226                                                 if (err != MSG_SUCCESS) {
227                                                         MSG_WARN("callbackMsgIncoming() Error !! [%d]", err);
228                                                 }
229                                         }
230                                 } else {
231                                         MSG_DEBUG("addMessage() Error !! [%d]", err);
232                                 }
233                         }
234                 }
235
236                 removeFromConcatList(msg.msgRef, msg.simIndex, msg.originAddress.address);
237         }
238
239         /** Send Deliver Report */
240         SmsPluginTransport::instance()->sendDeliverReport(handle, err);
241
242         MSG_END();
243 }
244
245 void SmsPluginConcatHandler::handleSimConcatMsg(TapiHandle *handle, SMS_TPDU_S *pTpdu, int msgId, int bRead, int *simIdList)
246 {
247         MSG_BEGIN();
248
249         bool noneConcatTypeHeader = true;
250
251         if (pTpdu->tpduType == SMS_TPDU_DELIVER) {
252                 SMS_CONCAT_MSG_S msg = {0};
253
254                 msg.simIndex = SmsPluginDSHandler::instance()->getSimIndex(handle);
255
256                 for (int i = 0; i < pTpdu->data.deliver.userData.headerCnt; i++) {
257                         if (pTpdu->data.deliver.userData.header[i].udhType == SMS_UDH_CONCAT_8BIT) {
258                                 msg.msgRef = (unsigned short)pTpdu->data.deliver.userData.header[i].udh.concat8bit.msgRef;
259                                 msg.totalSeg = pTpdu->data.deliver.userData.header[i].udh.concat8bit.totalSeg;
260                                 msg.seqNum = pTpdu->data.deliver.userData.header[i].udh.concat8bit.seqNum;
261                                 msg.simId = msgId;
262                                 memcpy(&(msg.timeStamp.time.absolute), &(pTpdu->data.deliver.timeStamp.time.absolute), sizeof(SMS_TIME_ABS_S));
263                                 memcpy(&(msg.originAddress), &(pTpdu->data.deliver.originAddress), sizeof(SMS_ADDRESS_S));
264                                 memcpy(&(msg.dcs), &(pTpdu->data.deliver.dcs), sizeof(SMS_DCS_S));
265
266
267                                 /**  check noneConcatTypeHeader */
268                                 noneConcatTypeHeader = false;
269
270                                 break;
271                         } else if (pTpdu->data.deliver.userData.header[i].udhType == SMS_UDH_CONCAT_16BIT) {
272                                 msg.msgRef = (unsigned short)pTpdu->data.deliver.userData.header[i].udh.concat16bit.msgRef;
273                                 msg.totalSeg = pTpdu->data.deliver.userData.header[i].udh.concat16bit.totalSeg;
274                                 msg.seqNum = pTpdu->data.deliver.userData.header[i].udh.concat16bit.seqNum;
275                                 msg.simId = msgId;
276                                 memcpy(&(msg.timeStamp.time.absolute), &(pTpdu->data.deliver.timeStamp.time.absolute), sizeof(SMS_TIME_ABS_S));
277                                 memcpy(&(msg.originAddress), &(pTpdu->data.deliver.originAddress), sizeof(SMS_ADDRESS_S));
278                                 memcpy(&(msg.dcs), &(pTpdu->data.deliver.dcs), sizeof(SMS_DCS_S));
279
280                                 /**  check noneConcatTypeHeader */
281                                 noneConcatTypeHeader = false;
282
283                                 break;
284                         }
285                 }
286
287                 unsigned char segCnt = checkConcatMsg(&msg, &(pTpdu->data.deliver.userData));
288                 MSG_DEBUG("segCnt [%d]", segCnt);
289                 MSG_DEBUG("msg.totalSeg [%d]", msg.totalSeg);
290
291                 if ((segCnt == msg.totalSeg) || noneConcatTypeHeader) {
292                         MSG_DEBUG("RECEIVED LAST CONCAT : %d", segCnt);
293
294                         int dataSize = 0;
295                         char* pUserData = NULL;
296                         unique_ptr<char*, void(*)(char**)> dataBuf(&pUserData, unique_ptr_deleter);
297
298                         MSG_MESSAGE_INFO_S msgInfo = {0};
299
300                         msgInfo.addressList = NULL;
301                         unique_ptr<MSG_ADDRESS_INFO_S*, void(*)(MSG_ADDRESS_INFO_S**)> addressListBuf(&msgInfo.addressList, unique_ptr_deleter);
302                         msgInfo.sim_idx = msg.simIndex;
303
304                         dataSize = makeConcatUserData(msg.msgRef, msg.simIndex, &pUserData, msg.originAddress.address);
305
306                         if (dataSize > 0) {
307                                 convertConcatToMsginfo(&(pTpdu->data.deliver), pUserData, dataSize, &msgInfo);
308                                 /* set Sim Message ID */
309                                 msgInfo.msgId = msgId;
310
311                                 /* set read status */
312                                 msgInfo.bRead = bRead;
313                                 /* set storage id */
314                                 msgInfo.storageId = MSG_STORAGE_SIM;
315                         }
316                         for (int index = concatList.size(); index >= 0 ; index--) {
317                                 if (concatList[index].msgRef == msg.msgRef && concatList[index].simIndex == msg.simIndex
318                                         && g_strcmp0(concatList[index].originAddress.address, msg.originAddress.address) == 0) {
319                                         memcpy(simIdList, concatList[index].simIdList, sizeof(int) * MAX_SIM_SMS_NUM);
320                                         for (int i = 0; i < 255; ++i) {
321                                                 MSG_DEBUG("sim id [%d]", simIdList[i]);
322                                         }
323                                         break;
324                                 }
325                         }
326                         removeFromConcatList(msg.msgRef, msg.simIndex, msg.originAddress.address);
327                         /* Call Event Handler */
328                         SmsPluginSimMsg::instance()->setSimMsgEvent(handle, &msgInfo, true);
329                         return;
330                 }
331                 /* Call Event Handler */
332                 SmsPluginSimMsg::instance()->setSimMsgEvent(handle, NULL, false);
333         } else {
334                 SMS_CONCAT_MSG_S msg = {0};
335
336                 msg.simIndex = SmsPluginDSHandler::instance()->getSimIndex(handle);
337
338                 for (int i = 0; i < pTpdu->data.submit.userData.headerCnt; i++) {
339                         if (pTpdu->data.submit.userData.header[i].udhType == SMS_UDH_CONCAT_8BIT) {
340                                 msg.msgRef = (unsigned short)pTpdu->data.submit.userData.header[i].udh.concat8bit.msgRef;
341                                 msg.totalSeg = pTpdu->data.submit.userData.header[i].udh.concat8bit.totalSeg;
342                                 msg.seqNum = pTpdu->data.submit.userData.header[i].udh.concat8bit.seqNum;
343                                 msg.simId = msgId;
344                                 memcpy(&(msg.originAddress), &(pTpdu->data.submit.destAddress), sizeof(SMS_ADDRESS_S));
345                                 memcpy(&(msg.dcs), &(pTpdu->data.submit.dcs), sizeof(SMS_DCS_S));
346
347
348                                 /**  check noneConcatTypeHeader */
349                                 noneConcatTypeHeader = false;
350
351                                 break;
352                         } else if (pTpdu->data.submit.userData.header[i].udhType == SMS_UDH_CONCAT_16BIT) {
353                                 msg.msgRef = (unsigned short)pTpdu->data.submit.userData.header[i].udh.concat16bit.msgRef;
354                                 msg.totalSeg = pTpdu->data.submit.userData.header[i].udh.concat16bit.totalSeg;
355                                 msg.seqNum = pTpdu->data.submit.userData.header[i].udh.concat16bit.seqNum;
356                                 msg.simId = msgId;
357                                 memcpy(&(msg.originAddress), &(pTpdu->data.submit.destAddress), sizeof(SMS_ADDRESS_S));
358                                 memcpy(&(msg.dcs), &(pTpdu->data.submit.dcs), sizeof(SMS_DCS_S));
359
360                                 /**  check noneConcatTypeHeader */
361                                 noneConcatTypeHeader = false;
362
363                                 break;
364                         }
365                 }
366
367                 unsigned char segCnt = checkConcatMsg(&msg, &(pTpdu->data.submit.userData));
368
369                 MSG_DEBUG("segCnt [%d]", segCnt);
370                 MSG_DEBUG("msg.totalSeg [%d]", msg.totalSeg);
371
372                 if ((segCnt == msg.totalSeg) || noneConcatTypeHeader) {
373                         MSG_DEBUG("RECEIVED LAST CONCAT : %d", segCnt);
374
375                         int dataSize = 0;
376                         char* pUserData = NULL;
377                         unique_ptr<char*, void(*)(char**)> dataBuf(&pUserData, unique_ptr_deleter);
378
379                         MSG_MESSAGE_INFO_S msgInfo = {0};
380
381                         msgInfo.addressList = NULL;
382                         unique_ptr<MSG_ADDRESS_INFO_S*, void(*)(MSG_ADDRESS_INFO_S**)> addressListBuf(&msgInfo.addressList, unique_ptr_deleter);
383                         msgInfo.sim_idx = msg.simIndex;
384
385                         dataSize = makeConcatUserData(msg.msgRef, msg.simIndex, &pUserData, msg.originAddress.address);
386
387                         if (dataSize > 0) {
388                                 convertConcatToMsginfo(&(pTpdu->data.submit), pUserData, dataSize, &msgInfo);
389
390                                 /* set Sim Message ID */
391                                 msgInfo.msgId = msgId;
392                                 /* set read status */
393                                 msgInfo.bRead = bRead;
394
395                                 msgInfo.msgType.subType = MSG_CONCAT_SIM_SMS;
396
397                                 /* set storage id */
398                                 msgInfo.storageId = MSG_STORAGE_SIM;
399                         }
400                         for (int index = concatList.size(); index >= 0 ; index--) {
401                                 if (concatList[index].msgRef == msg.msgRef && concatList[index].simIndex == msg.simIndex
402                                         && g_strcmp0(concatList[index].originAddress.address, msg.originAddress.address) == 0) {
403                                         memcpy(simIdList, concatList[index].simIdList, sizeof(int) * MAX_SIM_SMS_NUM);
404                                         break;
405                                 }
406                         }
407                         /* Call Event Handler */
408                         SmsPluginSimMsg::instance()->setSimMsgEvent(handle, &msgInfo, true);
409                         removeFromConcatList(msg.msgRef, msg.simIndex, msg.originAddress.address);
410                         return;
411                 }
412                 /* Call Event Handler */
413                 SmsPluginSimMsg::instance()->setSimMsgEvent(handle, NULL, false);
414         }
415
416         MSG_END();
417 }
418
419 #ifdef CONCAT_SIM_MSG_OPERATION
420 void SmsPluginConcatHandler::handleConcatMsg(SMS_TPDU_S *pTpdu, msg_sim_id_t SimMsgId, bool bRead)
421 {
422         MSG_BEGIN();
423
424         if (pTpdu->tpduType != SMS_TPDU_DELIVER) {
425                 MSG_DEBUG("The TPDU type is not deliver [%d]", pTpdu->tpduType);
426                 return;
427         }
428
429         SMS_CONCAT_MSG_S msg;
430         memset(&msg, 0x00, sizeof(SMS_CONCAT_MSG_S));
431
432         for (int i = 0; i < pTpdu->data.deliver.userData.headerCnt; i++) {
433                 if (pTpdu->data.deliver.userData.header[i].udhType == SMS_UDH_CONCAT_8BIT) {
434                         msg.msgRef = (unsigned short)pTpdu->data.deliver.userData.header[i].udh.concat8bit.msgRef;
435                         msg.totalSeg = pTpdu->data.deliver.userData.header[i].udh.concat8bit.totalSeg;
436                         msg.seqNum = pTpdu->data.deliver.userData.header[i].udh.concat8bit.seqNum;
437
438                         memcpy(&(msg.timeStamp.time.absolute), &(pTpdu->data.deliver.timeStamp.time.absolute), sizeof(SMS_TIME_ABS_S));
439                         memcpy(&(msg.originAddress), &(pTpdu->data.deliver.originAddress), sizeof(SMS_ADDRESS_S));
440                         memcpy(&(msg.dcs), &(pTpdu->data.deliver.dcs), sizeof(SMS_DCS_S));
441
442                         msg.bRead = bRead;
443
444                         if (msg.totalSeg > MAX_SEGMENT_NUM) {
445                                 MSG_DEBUG("Total Segment Count is over Maximum [%d]", msg.totalSeg);
446                                 return;
447                         }
448
449                         break;
450                 } else if (pTpdu->data.deliver.userData.header[i].udhType == SMS_UDH_CONCAT_16BIT) {
451                         msg.msgRef = (unsigned short)pTpdu->data.deliver.userData.header[i].udh.concat16bit.msgRef;
452                         msg.totalSeg = pTpdu->data.deliver.userData.header[i].udh.concat16bit.totalSeg;
453                         msg.seqNum = pTpdu->data.deliver.userData.header[i].udh.concat16bit.seqNum;
454
455                         memcpy(&(msg.timeStamp.time.absolute), &(pTpdu->data.deliver.timeStamp.time.absolute), sizeof(SMS_TIME_ABS_S));
456                         memcpy(&(msg.originAddress), &(pTpdu->data.deliver.originAddress), sizeof(SMS_ADDRESS_S));
457                         memcpy(&(msg.dcs), &(pTpdu->data.deliver.dcs), sizeof(SMS_DCS_S));
458
459                         msg.bRead = bRead;
460
461                         if (msg.totalSeg > MAX_SEGMENT_NUM) {
462                                 MSG_DEBUG("Total Segment Count is over Maximum [%d]", msg.totalSeg);
463                                 return;
464                         }
465
466                         break;
467                 }
468         }
469
470         unsigned char segCnt = checkConcatMsg(&msg, &(pTpdu->data.deliver.userData));
471
472         addToSimIdList(msg.msgRef, SimMsgId);
473
474         if (segCnt == msg.totalSeg) {
475                 MSG_DEBUG("RECEIVED LAST CONCAT : %d", segCnt);
476
477                 int dataSize = 0;
478                 char* pUserData = NULL;
479                 unique_ptr<char*, void(*)(char**)> dataBuf(&pUserData, unique_ptr_deleter);
480
481                 MSG_MESSAGE_INFO_S msgInfo = {0};
482
483                 dataSize = makeConcatUserData(msg.msgRef, &pUserData);
484
485                 if (dataSize >= 0) {
486                         MSG_DEBUG("TOTAL DATA : %s", pUserData);
487
488                         convertSimMsgToMsginfo(&msg, pUserData, dataSize, &msgInfo);
489
490                         /* set Sim Message ID */
491                         msgInfo.msgId = SimMsgId;
492
493                         /* set read status */
494                         msgInfo.bRead = bRead;
495
496                         /* Print MSG_MESSAGE_INFO_S */
497                         MSG_DEBUG("############# Convert  tpdu values to Message Info values ####################");
498
499                         MSG_DEBUG("msgInfo.msgId : %d", msgInfo.msgId);
500                         MSG_DEBUG("msgInfo.nAddressCnt : %d", msgInfo.nAddressCnt);
501                         MSG_DEBUG("msgInfo.addressList[0].addressType : %d", msgInfo.addressList[0].addressType);
502                         MSG_SEC_DEBUG("msgInfo.addressList[0].addressVal : %s", msgInfo.addressList[0].addressVal);
503                         MSG_DEBUG("msgInfo.priority : %d", msgInfo.priority);
504                         MSG_DEBUG("msgInfo.bProtected : %d", msgInfo.bProtected);
505                         MSG_DEBUG("msgInfo.bRead : %d", msgInfo.bRead);
506                         MSG_DEBUG("msgInfo.bTextSms : %d", msgInfo.bTextSms);
507                         MSG_DEBUG("msgInfo.direction : %d", msgInfo.direction);
508                         MSG_DEBUG("msgInfo.msgType.mainType : %d", msgInfo.msgType.mainType);
509                         MSG_DEBUG("msgInfo.msgType.subType : %d", msgInfo.msgType.subType);
510                         MSG_DEBUG("msgInfo.msgType.classType : %d", msgInfo.msgType.classType);
511                         MSG_DEBUG("msgInfo.displayTime : %s", ctime(&msgInfo.displayTime));
512                         MSG_DEBUG("msgInfo.dataSize : %d", msgInfo.dataSize);
513
514                         if (msgInfo.bTextSms == true)
515                                 MSG_SEC_DEBUG("msgInfo.msgText : %s", msgInfo.msgText);
516                         else
517                                 MSG_SEC_DEBUG("msgInfo.msgData : %s", msgInfo.msgData);
518
519                         MSG_DEBUG("###############################################################");
520
521                         /* Remove from List */
522                         removeFromConcatList(msg.msgRef);
523                         removeFromSimIdList(msg.msgRef);
524
525                         /* add msgInfo to msg list */
526                         SmsPluginStorage::instance()->addSimMsgToList(&msgInfo, true);
527
528                         /* Callback to MSG FW */
529                         SmsPluginEventHandler::instance()->callbackGetSimMsg();
530                 }
531         } else {
532                 /* add index count to msg list */
533                 SmsPluginStorage::instance()->addSimMsgToList(NULL, false);
534
535                 /* Callback to MSG FW */
536                 SmsPluginEventHandler::instance()->callbackGetSimMsg();
537         }
538
539         MSG_END();
540 }
541
542
543 void SmsPluginConcatHandler::handleBrokenMsg()
544 {
545         if (concatList.size() <= 0 || simIdList.size() <= 0) {
546                 MSG_DEBUG("No Broken Concatenated Message");
547                 return;
548         }
549
550         do {
551                 int index = 0, dataSize = 0;
552                 char* pUserData = NULL;
553                 unique_ptr<char*, void(*)(char**)> dataBuf(&pUserData, unique_ptr_deleter);
554
555                 MSG_MESSAGE_INFO_S msgInfo = {0};
556
557                 dataSize = makeConcatUserData(concatList[index].msgRef, &pUserData);
558
559                 if (dataSize > 0) {
560                         MSG_DEBUG("TOTAL DATA : %s", pUserData);
561
562                         SMS_CONCAT_MSG_S msg;
563                         memset(&msg, 0x00, sizeof(SMS_CONCAT_MSG_S));
564
565                         msg.msgRef = concatList[index].msgRef;
566                         msg.totalSeg = concatList[index].totalSeg;
567
568                         memcpy(&(msg.timeStamp.time.absolute), &(concatList[index].timeStamp.time.absolute), sizeof(SMS_TIME_ABS_S));
569                         memcpy(&(msg.originAddress), &(concatList[index].originAddress), sizeof(SMS_ADDRESS_S));
570                         memcpy(&(msg.dcs), &(concatList[index].dcs), sizeof(SMS_DCS_S));
571
572                         convertSimMsgToMsginfo(&msg, pUserData, dataSize, &msgInfo);
573
574                         /* set Sim Message ID */
575                         msgInfo.msgId = 0;
576
577                         /* set read status */
578                         msgInfo.bRead = concatList[index].bRead;
579
580                         /* Print MSG_MESSAGE_INFO_S */
581                         MSG_DEBUG("############# Convert  tpdu values to Message Info values ####################");
582                         MSG_DEBUG("msgInfo.msgId : %d", msgInfo.msgId);
583                         MSG_DEBUG("msgInfo.nAddressCnt : %d", msgInfo.nAddressCnt);
584                         MSG_DEBUG("msgInfo.addressList[0].addressType : %d", msgInfo.addressList[0].addressType);
585                         MSG_SEC_DEBUG("msgInfo.addressList[0].addressVal : %s", msgInfo.addressList[0].addressVal);
586                         MSG_DEBUG("msgInfo.priority : %d", msgInfo.priority);
587                         MSG_DEBUG("msgInfo.bProtected : %d", msgInfo.bProtected);
588                         MSG_DEBUG("msgInfo.bRead : %d", msgInfo.bRead);
589                         MSG_DEBUG("msgInfo.bTextSms : %d", msgInfo.bTextSms);
590                         MSG_DEBUG("msgInfo.direction : %d", msgInfo.direction);
591                         MSG_DEBUG("msgInfo.msgType.mainType : %d", msgInfo.msgType.mainType);
592                         MSG_DEBUG("msgInfo.msgType.subType : %d", msgInfo.msgType.subType);
593                         MSG_DEBUG("msgInfo.msgType.classType : %d", msgInfo.msgType.classType);
594                         MSG_DEBUG("msgInfo.displayTime : %s", ctime(&msgInfo.displayTime));
595                         MSG_DEBUG("msgInfo.dataSize : %d", msgInfo.dataSize);
596                         if (msgInfo.bTextSms == true)
597                                 MSG_SEC_DEBUG("msgInfo.msgText : %s", msgInfo.msgText);
598                         else
599                                 MSG_SEC_DEBUG("msgInfo.msgData : %s", msgInfo.msgData);
600                         MSG_DEBUG("###############################################################");
601
602                         /* add msgInfo to msg list */
603                         SmsPluginStorage::instance()->addSimMsgToList(&msgInfo, true);
604                 }
605
606                 removeFromConcatList(concatList[index].msgRef);
607                 removeFromSimIdList(concatList[index].msgRef);
608         } while (concatList.size() > 0);
609 }
610 #endif
611
612
613 unsigned char SmsPluginConcatHandler::checkConcatMsg(SMS_CONCAT_MSG_S *pConcatMsg, SMS_USERDATA_S *pUserData)
614 {
615         if (pConcatMsg == NULL || pUserData == NULL) {
616                 MSG_DEBUG("In Parameter is NULL");
617                 return 0;
618         }
619
620         unsigned char currSegCnt = 0;
621
622         bool bFind = false;
623
624         for (unsigned int i = 0; i < concatList.size(); i++) {
625                 if (concatList[i].msgRef == pConcatMsg->msgRef && concatList[i].simIndex == pConcatMsg->simIndex
626                         && g_strcmp0(concatList[i].originAddress.address, pConcatMsg->originAddress.address) == 0) {
627                         if (concatList[i].data.count(pConcatMsg->seqNum) != 0) {
628                                 MSG_DEBUG("The Sequence Number already exists [%d]", pConcatMsg->seqNum);
629                                 return 0;
630                         }
631                         CONCAT_DATA_S concatData = {0};
632
633                         memcpy(concatData.data, pUserData->data, pUserData->length);
634                         concatData.length = pUserData->length;
635
636                         pair<unsigned char, CONCAT_DATA_S> newData(pConcatMsg->seqNum, concatData);
637                         concatList[i].data.insert(newData);
638                         concatList[i].simIdList[concatList[i].segCnt] = pConcatMsg->simId + 1;
639
640                         MSG_DEBUG("MSG DATA : %s", pUserData->data);
641                         MSG_DEBUG("PAIR DATA [%d] : %s", newData.first, newData.second.data);
642
643                         concatList[i].segCnt++;
644                         concatList[i].totalSize += pUserData->length;
645                         currSegCnt = concatList[i].segCnt;
646
647                         bFind = true;
648
649                         break;
650                 }
651         }
652
653         /** New Concat Msg */
654         if (bFind == false) {
655                 SMS_CONCAT_INFO_S tmpInfo;
656                 memset(tmpInfo.simIdList, 0x00, sizeof(int) * MAX_SIM_SMS_NUM);
657                 tmpInfo.msgRef = pConcatMsg->msgRef;
658                 tmpInfo.totalSeg = pConcatMsg->totalSeg;
659                 tmpInfo.segCnt = 1;
660                 tmpInfo.simIdList[0] = pConcatMsg->simId + 1;
661                 tmpInfo.simIndex = pConcatMsg->simIndex;
662                 tmpInfo.bRead = false;
663
664                 memcpy(&(tmpInfo.timeStamp.time.absolute), &(pConcatMsg->timeStamp.time.absolute), sizeof(SMS_TIME_ABS_S));
665                 memcpy(&(tmpInfo.originAddress), &(pConcatMsg->originAddress), sizeof(SMS_ADDRESS_S));
666                 memcpy(&(tmpInfo.dcs), &(pConcatMsg->dcs), sizeof(SMS_DCS_S));
667
668                 tmpInfo.totalSize = pUserData->length;
669                 tmpInfo.display_time = time(NULL);
670
671                 CONCAT_DATA_S concatData = {0};
672
673                 memcpy(concatData.data, pUserData->data, pUserData->length);
674                 concatData.length = pUserData->length;
675
676                 pair<unsigned char, CONCAT_DATA_S> newData(pConcatMsg->seqNum, concatData);
677                 tmpInfo.data.insert(newData);
678
679                 MSG_DEBUG("MSG DATA : %s", pUserData->data);
680                 MSG_DEBUG("PAIR DATA [%d] : %s", newData.first, newData.second.data);
681
682                 concatList.push_back(tmpInfo);
683
684                 currSegCnt = tmpInfo.segCnt;
685         }
686
687         return currSegCnt;
688 }
689
690
691 int SmsPluginConcatHandler::makeConcatUserData(unsigned short MsgRef, int simIndex, char **ppTotalData, char *originAddress)
692 {
693         concatDataMap::iterator it;
694
695         int totalSize = 0, offset = 0;
696
697         for (unsigned int i = 0; i < concatList.size(); i++) {
698                 if (concatList[i].msgRef == MsgRef && concatList[i].simIndex == simIndex
699                         && g_strcmp0(concatList[i].originAddress.address, originAddress) == 0) {
700                         totalSize = concatList[i].totalSize;
701
702                         if (totalSize <= 0) {
703                                 MSG_DEBUG("Size Error : totalSize <= 0");
704                                 return 0;
705                         }
706
707                         MSG_DEBUG("totalSize [%d]", totalSize);
708
709                         if (*ppTotalData == NULL)
710                                 *ppTotalData = new char[totalSize];
711
712                         for (it = concatList[i].data.begin(); it != concatList[i].data.end(); it++) {
713                                 memcpy(*ppTotalData+offset, it->second.data, it->second.length);
714                                 offset += it->second.length;
715                         }
716                 }
717         }
718
719         return totalSize;
720 }
721
722
723 void SmsPluginConcatHandler::convertConcatToMsginfo(const SMS_DELIVER_S *pTpdu, const char *pUserData, int DataSize, MSG_MESSAGE_INFO_S *pMsgInfo)
724 {
725         /** Convert Type  values */
726         pMsgInfo->msgType.mainType = MSG_SMS_TYPE;
727         pMsgInfo->msgType.subType = SmsPluginEventHandler::instance()->convertMsgSubType(pTpdu->pid);
728
729         /** set folder id */
730         pMsgInfo->folderId = MSG_INBOX_ID;
731
732         /** set storage id */
733         pMsgInfo->storageId = MSG_STORAGE_PHONE;
734
735         switch (pTpdu->dcs.msgClass) {
736         case SMS_MSG_CLASS_0:
737                 pMsgInfo->msgType.classType = MSG_CLASS_0;
738                 break;
739         case SMS_MSG_CLASS_1:
740                 pMsgInfo->msgType.classType = MSG_CLASS_1;
741                 break;
742         case SMS_MSG_CLASS_2:
743                 pMsgInfo->msgType.classType = MSG_CLASS_2;
744                 break;
745         case SMS_MSG_CLASS_3:
746                 pMsgInfo->msgType.classType = MSG_CLASS_3;
747                 break;
748         default:
749                 pMsgInfo->msgType.classType = MSG_CLASS_NONE;
750                 break;
751         }
752
753         pMsgInfo->networkStatus = MSG_NETWORK_RECEIVED;
754         pMsgInfo->bRead = false;
755         pMsgInfo->bProtected = false;
756         pMsgInfo->priority = MSG_MESSAGE_PRIORITY_NORMAL;
757         pMsgInfo->direction = MSG_DIRECTION_TYPE_MT;
758
759
760         time_t rawtime = time(NULL);
761
762 /*** Comment below lines to save local UTC time..... (it could be used later.)
763
764         if (pTpdu->timeStamp.format == SMS_TIME_ABSOLUTE) {
765
766                 MSG_DEBUG("year : %d", pTpdu->timeStamp.time.absolute.year);
767                 MSG_DEBUG("month : %d", pTpdu->timeStamp.time.absolute.month);
768                 MSG_DEBUG("day : %d", pTpdu->timeStamp.time.absolute.day);
769                 MSG_DEBUG("hour : %d", pTpdu->timeStamp.time.absolute.hour);
770                 MSG_DEBUG("minute : %d", pTpdu->timeStamp.time.absolute.minute);
771                 MSG_DEBUG("second : %d", pTpdu->timeStamp.time.absolute.second);
772                 MSG_DEBUG("timezone : %d", pTpdu->timeStamp.time.absolute.timeZone);
773
774                 char displayTime[32];
775                 struct tm * timeTM;
776
777                 struct tm timeinfo;
778                 memset(&timeinfo, 0x00, sizeof(tm));
779
780                 timeinfo.tm_year = (pTpdu->timeStamp.time.absolute.year + 100);
781                 timeinfo.tm_mon = (pTpdu->timeStamp.time.absolute.month - 1);
782                 timeinfo.tm_mday = pTpdu->timeStamp.time.absolute.day;
783                 timeinfo.tm_hour = pTpdu->timeStamp.time.absolute.hour;
784                 timeinfo.tm_min = pTpdu->timeStamp.time.absolute.minute;
785                 timeinfo.tm_sec = pTpdu->timeStamp.time.absolute.second;
786                 timeinfo.tm_isdst = 0;
787
788                 rawtime = mktime(&timeinfo);
789
790                 MSG_DEBUG("tzname[0] [%s]", tzname[0]);
791                 MSG_DEBUG("tzname[1] [%s]", tzname[1]);
792                 MSG_DEBUG("timezone [%d]", timezone);
793                 MSG_DEBUG("daylight [%d]", daylight);
794
795                 memset(displayTime, 0x00, sizeof(displayTime));
796                 strftime(displayTime, 32, "%Y-%02m-%02d %T %z", &timeinfo);
797                 MSG_DEBUG("displayTime [%s]", displayTime);
798
799                 rawtime -= (pTpdu->timeStamp.time.absolute.timeZone * (3600/4));
800
801                 timeTM = localtime(&rawtime);
802                 memset(displayTime, 0x00, sizeof(displayTime));
803                 strftime(displayTime, 32, "%Y-%02m-%02d %T %z", timeTM);
804                 MSG_DEBUG("displayTime [%s]", displayTime);
805
806                 rawtime -= timezone;
807
808                 timeTM = localtime(&rawtime);
809                 memset(displayTime, 0x00, sizeof(displayTime));
810                 strftime(displayTime, 32, "%Y-%02m-%02d %T %z", timeTM);
811                 MSG_DEBUG("displayTime [%s]", displayTime);
812         }
813
814 ***/
815
816         pMsgInfo->displayTime = rawtime;
817
818         /** Convert Address values */
819         pMsgInfo->addressList = (MSG_ADDRESS_INFO_S *)new char[sizeof(MSG_ADDRESS_INFO_S)];
820         memset(pMsgInfo->addressList, 0x00, sizeof(MSG_ADDRESS_INFO_S));
821
822         pMsgInfo->nAddressCnt = 1;
823         pMsgInfo->addressList[0].addressType = MSG_ADDRESS_TYPE_PLMN;
824         strncpy(pMsgInfo->addressList[0].addressVal, pTpdu->originAddress.address, MAX_ADDRESS_VAL_LEN);
825
826         pMsgInfo->msgPort.valid = false;
827         pMsgInfo->msgPort.dstPort = 0;
828         pMsgInfo->msgPort.srcPort = 0;
829
830         for (int i = 0; i < pTpdu->userData.headerCnt; i++) {
831                 /** Convert UDH values - Port Number */
832                 if (pTpdu->userData.header[i].udhType == SMS_UDH_APP_PORT_8BIT) {
833                         pMsgInfo->msgPort.valid = true;
834                         pMsgInfo->msgPort.dstPort = pTpdu->userData.header[i].udh.appPort8bit.destPort;
835                         pMsgInfo->msgPort.srcPort = pTpdu->userData.header[i].udh.appPort8bit.originPort;
836                 } else if (pTpdu->userData.header[i].udhType == SMS_UDH_APP_PORT_16BIT) {
837                         pMsgInfo->msgPort.valid = true;
838                         pMsgInfo->msgPort.dstPort = pTpdu->userData.header[i].udh.appPort16bit.destPort;
839                         pMsgInfo->msgPort.srcPort = pTpdu->userData.header[i].udh.appPort16bit.originPort;
840                 }
841         }
842
843         /* For UTF8 */
844         int bufSize = (DataSize*4) + 1;
845
846         char tmpBuf[bufSize];
847         memset(tmpBuf, 0x00, sizeof(tmpBuf));
848
849         /** Convert Data values */
850         MsgTextConvert *textCvt = MsgTextConvert::instance();
851         if (pTpdu->dcs.codingScheme == SMS_CHARSET_7BIT) {
852                 MSG_LANG_INFO_S langInfo = {0, };
853
854                 langInfo.bSingleShift = false;
855                 langInfo.bLockingShift = false;
856
857                 pMsgInfo->encodeType = MSG_ENCODE_GSM7BIT;
858                 pMsgInfo->dataSize = textCvt->convertGSM7bitToUTF8((unsigned char*)tmpBuf, bufSize, (unsigned char*)pUserData, DataSize, &langInfo);
859         } else if (pTpdu->dcs.codingScheme == SMS_CHARSET_8BIT) {
860                 pMsgInfo->encodeType = MSG_ENCODE_8BIT;
861                 memcpy(tmpBuf, pUserData, DataSize);
862                 pMsgInfo->dataSize = DataSize;
863         } else if (pTpdu->dcs.codingScheme == SMS_CHARSET_UCS2) {
864                 pMsgInfo->encodeType = MSG_ENCODE_UCS2;
865                 pMsgInfo->dataSize = textCvt->convertUCS2ToUTF8((unsigned char*)tmpBuf, bufSize, (unsigned char*)pUserData, DataSize);
866         }
867
868         MSG_DEBUG("Data Size [%d]", pMsgInfo->dataSize);
869         MSG_DEBUG("Data [%s]", tmpBuf);
870
871 #ifdef MSG_FW_FOR_DEBUG
872 printf("\n");
873
874 for (int i = 0; i < pMsgInfo->dataSize; i++)
875 {
876         printf("[%02x]", tmpBuf[i]);
877 }
878
879 printf("\n");
880 #endif
881
882         if (pMsgInfo->dataSize > MAX_MSG_TEXT_LEN) {
883                 pMsgInfo->bTextSms = false;
884
885                 /** Save Message Data into File */
886                 char fileName[MSG_FILENAME_LEN_MAX+1];
887                 memset(fileName, 0x00, sizeof(fileName));
888
889                 if (MsgCreateFileName(fileName) == false)
890                         THROW(MsgException::FILE_ERROR, "########  MsgCreateFileName Fail !!! #######");
891
892                 MSG_SEC_DEBUG("Save Message Data into file : size[%d] name[%s]\n", pMsgInfo->dataSize, fileName);
893                 if (MsgWriteIpcFile(fileName, tmpBuf, pMsgInfo->dataSize) == false)
894                         THROW(MsgException::FILE_ERROR, "########  MsgWriteIpcFile Fail !!! #######");
895
896                 strncpy(pMsgInfo->msgData, fileName, MAX_MSG_DATA_LEN);
897         } else {
898                 pMsgInfo->bTextSms = true;
899
900                 memset(pMsgInfo->msgText, 0x00, sizeof(pMsgInfo->msgText));
901                 memcpy(pMsgInfo->msgText, tmpBuf, pMsgInfo->dataSize);
902         }
903 }
904
905
906 void SmsPluginConcatHandler::convertConcatToMsginfo(const SMS_SUBMIT_S *pTpdu, const char *pUserData, int DataSize, MSG_MESSAGE_INFO_S *pMsgInfo)
907 {
908         /** Convert Type  values */
909         pMsgInfo->msgType.mainType = MSG_SMS_TYPE;
910         pMsgInfo->msgType.subType = SmsPluginEventHandler::instance()->convertMsgSubType(pTpdu->pid);
911
912         /** set folder id */
913         pMsgInfo->folderId = MSG_INBOX_ID;
914
915         /** set storage id */
916         pMsgInfo->storageId = MSG_STORAGE_PHONE;
917
918         switch (pTpdu->dcs.msgClass) {
919         case SMS_MSG_CLASS_0:
920                 pMsgInfo->msgType.classType = MSG_CLASS_0;
921                 break;
922         case SMS_MSG_CLASS_1:
923                 pMsgInfo->msgType.classType = MSG_CLASS_1;
924                 break;
925         case SMS_MSG_CLASS_2:
926                 pMsgInfo->msgType.classType = MSG_CLASS_2;
927                 break;
928         case SMS_MSG_CLASS_3:
929                 pMsgInfo->msgType.classType = MSG_CLASS_3;
930                 break;
931         default:
932                 pMsgInfo->msgType.classType = MSG_CLASS_NONE;
933                 break;
934         }
935
936         pMsgInfo->networkStatus = MSG_NETWORK_RECEIVED;
937         pMsgInfo->bRead = false;
938         pMsgInfo->bProtected = false;
939         pMsgInfo->priority = MSG_MESSAGE_PRIORITY_NORMAL;
940         pMsgInfo->direction = MSG_DIRECTION_TYPE_MT;
941
942
943         time_t rawtime = time(NULL);
944         pMsgInfo->displayTime = rawtime;
945
946         /** Convert Address values */
947         pMsgInfo->addressList = (MSG_ADDRESS_INFO_S *)new char[sizeof(MSG_ADDRESS_INFO_S)];
948         memset(pMsgInfo->addressList, 0x00, sizeof(MSG_ADDRESS_INFO_S));
949
950         pMsgInfo->nAddressCnt = 1;
951         pMsgInfo->addressList[0].addressType = MSG_ADDRESS_TYPE_PLMN;
952         strncpy(pMsgInfo->addressList[0].addressVal, pTpdu->destAddress.address, MAX_ADDRESS_VAL_LEN);
953
954         pMsgInfo->msgPort.valid = false;
955         pMsgInfo->msgPort.dstPort = 0;
956         pMsgInfo->msgPort.srcPort = 0;
957
958         for (int i = 0; i < pTpdu->userData.headerCnt; i++) {
959                 /** Convert UDH values - Port Number */
960                 if (pTpdu->userData.header[i].udhType == SMS_UDH_APP_PORT_8BIT) {
961                         pMsgInfo->msgPort.valid = true;
962                         pMsgInfo->msgPort.dstPort = pTpdu->userData.header[i].udh.appPort8bit.destPort;
963                         pMsgInfo->msgPort.srcPort = pTpdu->userData.header[i].udh.appPort8bit.originPort;
964                 } else if (pTpdu->userData.header[i].udhType == SMS_UDH_APP_PORT_16BIT) {
965                         pMsgInfo->msgPort.valid = true;
966                         pMsgInfo->msgPort.dstPort = pTpdu->userData.header[i].udh.appPort16bit.destPort;
967                         pMsgInfo->msgPort.srcPort = pTpdu->userData.header[i].udh.appPort16bit.originPort;
968                 }
969         }
970
971         /* For UTF8 */
972         int bufSize = (DataSize*4) + 1;
973
974         char tmpBuf[bufSize];
975         memset(tmpBuf, 0x00, sizeof(tmpBuf));
976
977         /** Convert Data values */
978         MsgTextConvert *textCvt = MsgTextConvert::instance();
979         if (pTpdu->dcs.codingScheme == SMS_CHARSET_7BIT) {
980                 MSG_LANG_INFO_S langInfo = {0, };
981
982                 langInfo.bSingleShift = false;
983                 langInfo.bLockingShift = false;
984
985                 pMsgInfo->encodeType = MSG_ENCODE_GSM7BIT;
986                 pMsgInfo->dataSize = textCvt->convertGSM7bitToUTF8((unsigned char*)tmpBuf, bufSize, (unsigned char*)pUserData, DataSize, &langInfo);
987         } else if (pTpdu->dcs.codingScheme == SMS_CHARSET_8BIT) {
988                 pMsgInfo->encodeType = MSG_ENCODE_8BIT;
989                 memcpy(tmpBuf, pUserData, DataSize);
990                 pMsgInfo->dataSize = DataSize;
991         } else if (pTpdu->dcs.codingScheme == SMS_CHARSET_UCS2) {
992                 pMsgInfo->encodeType = MSG_ENCODE_UCS2;
993                 pMsgInfo->dataSize = textCvt->convertUCS2ToUTF8((unsigned char*)tmpBuf, bufSize, (unsigned char*)pUserData, DataSize);
994         }
995
996         MSG_DEBUG("Data Size [%d]", pMsgInfo->dataSize);
997         MSG_DEBUG("Data [%s]", tmpBuf);
998
999         if (pMsgInfo->dataSize > MAX_MSG_TEXT_LEN) {
1000                 pMsgInfo->bTextSms = false;
1001
1002                 /** Save Message Data into File */
1003                 char fileName[MSG_FILENAME_LEN_MAX+1];
1004                 memset(fileName, 0x00, sizeof(fileName));
1005
1006                 if (MsgCreateFileName(fileName) == false)
1007                         THROW(MsgException::FILE_ERROR, "########  MsgCreateFileName Fail !!! #######");
1008
1009                 MSG_SEC_DEBUG("Save Message Data into file : size[%d] name[%s]\n", pMsgInfo->dataSize, fileName);
1010                 if (MsgWriteIpcFile(fileName, tmpBuf, pMsgInfo->dataSize) == false)
1011                         THROW(MsgException::FILE_ERROR, "########  MsgWriteIpcFile Fail !!! #######");
1012
1013                 strncpy(pMsgInfo->msgData, fileName, MAX_MSG_DATA_LEN);
1014         } else {
1015                 pMsgInfo->bTextSms = true;
1016
1017                 memset(pMsgInfo->msgText, 0x00, sizeof(pMsgInfo->msgText));
1018                 memcpy(pMsgInfo->msgText, tmpBuf, pMsgInfo->dataSize);
1019         }
1020 }
1021
1022 #ifdef CONCAT_SIM_MSG_OPERATION
1023 void SmsPluginConcatHandler::convertSimMsgToMsginfo(const SMS_CONCAT_MSG_S *pConcatMsg, const char *pUserData, int DataSize, MSG_MESSAGE_INFO_S *pMsgInfo)
1024 {
1025         /* Convert Type  values */
1026         pMsgInfo->msgType.mainType = MSG_SMS_TYPE;
1027         pMsgInfo->msgType.subType = MSG_CONCAT_SIM_SMS;
1028
1029         /* set folder id (temporary) */
1030         pMsgInfo->folderId = MSG_INBOX_ID;
1031
1032         pMsgInfo->storageId = MSG_STORAGE_SIM;
1033
1034         switch (pConcatMsg->dcs.msgClass) {
1035         case SMS_MSG_CLASS_0:
1036                 pMsgInfo->msgType.classType = MSG_CLASS_0;
1037                 break;
1038         case SMS_MSG_CLASS_1:
1039                 pMsgInfo->msgType.classType = MSG_CLASS_1;
1040                 break;
1041         case SMS_MSG_CLASS_2:
1042                 pMsgInfo->msgType.classType = MSG_CLASS_2;
1043                 break;
1044         case SMS_MSG_CLASS_3:
1045                 pMsgInfo->msgType.classType = MSG_CLASS_3;
1046                 break;
1047         default:
1048                 pMsgInfo->msgType.classType = MSG_CLASS_NONE;
1049         }
1050
1051         pMsgInfo->networkStatus = MSG_NETWORK_RECEIVED;
1052         pMsgInfo->bRead = false;
1053         pMsgInfo->bProtected = false;
1054         pMsgInfo->priority = MSG_MESSAGE_PRIORITY_NORMAL;
1055         pMsgInfo->direction = MSG_DIRECTION_TYPE_MT;
1056
1057         time_t rawtime = time(NULL);
1058
1059 /*** Comment below lines to save local UTC time..... (it could be used later.)
1060
1061         if (pTpdu->timeStamp.format == SMS_TIME_ABSOLUTE) {
1062
1063                 MSG_DEBUG("year : %d", pTpdu->timeStamp.time.absolute.year);
1064                 MSG_DEBUG("month : %d", pTpdu->timeStamp.time.absolute.month);
1065                 MSG_DEBUG("day : %d", pTpdu->timeStamp.time.absolute.day);
1066                 MSG_DEBUG("hour : %d", pTpdu->timeStamp.time.absolute.hour);
1067                 MSG_DEBUG("minute : %d", pTpdu->timeStamp.time.absolute.minute);
1068                 MSG_DEBUG("second : %d", pTpdu->timeStamp.time.absolute.second);
1069                 MSG_DEBUG("timezone : %d", pTpdu->timeStamp.time.absolute.timeZone);
1070
1071                 char displayTime[32];
1072                 struct tm * timeTM;
1073
1074                 struct tm timeinfo;
1075                 memset(&timeinfo, 0x00, sizeof(tm));
1076
1077                 timeinfo.tm_year = (pTpdu->timeStamp.time.absolute.year + 100);
1078                 timeinfo.tm_mon = (pTpdu->timeStamp.time.absolute.month - 1);
1079                 timeinfo.tm_mday = pTpdu->timeStamp.time.absolute.day;
1080                 timeinfo.tm_hour = pTpdu->timeStamp.time.absolute.hour;
1081                 timeinfo.tm_min = pTpdu->timeStamp.time.absolute.minute;
1082                 timeinfo.tm_sec = pTpdu->timeStamp.time.absolute.second;
1083                 timeinfo.tm_isdst = 0;
1084
1085                 rawtime = mktime(&timeinfo);
1086
1087                 MSG_DEBUG("tzname[0] [%s]", tzname[0]);
1088                 MSG_DEBUG("tzname[1] [%s]", tzname[1]);
1089                 MSG_DEBUG("timezone [%d]", timezone);
1090                 MSG_DEBUG("daylight [%d]", daylight);
1091
1092                 memset(displayTime, 0x00, sizeof(displayTime));
1093                 strftime(displayTime, 32, "%Y-%02m-%02d %T %z", &timeinfo);
1094                 MSG_DEBUG("displayTime [%s]", displayTime);
1095                 rawtime -= (pTpdu->timeStamp.time.absolute.timeZone * (3600/4));
1096
1097                 timeTM = localtime(&rawtime);
1098                 memset(displayTime, 0x00, sizeof(displayTime));
1099                 strftime(displayTime, 32, "%Y-%02m-%02d %T %z", timeTM);
1100                 MSG_DEBUG("displayTime [%s]", displayTime);
1101
1102                 rawtime -= timezone;
1103
1104                 timeTM = localtime(&rawtime);
1105                 memset(displayTime, 0x00, sizeof(displayTime));
1106                 strftime(displayTime, 32, "%Y-%02m-%02d %T %z", timeTM);
1107                 MSG_DEBUG("displayTime [%s]", displayTime);
1108         }
1109
1110 ***/
1111
1112         pMsgInfo->displayTime = rawtime;
1113
1114         /* Convert Address values */
1115         pMsgInfo->nAddressCnt = 1;
1116         pMsgInfo->addressList[0].addressType = MSG_ADDRESS_TYPE_PLMN;
1117         strncpy(pMsgInfo->addressList[0].addressVal, pConcatMsg->originAddress.address, MAX_ADDRESS_VAL_LEN);
1118
1119         pMsgInfo->msgPort.valid = false;
1120         pMsgInfo->msgPort.dstPort = 0;
1121         pMsgInfo->msgPort.srcPort = 0;
1122
1123         /* Insert SMS_CONCAT_SIM_MSG_S into File */
1124         SMS_CONCAT_SIM_MSG_S concatSimMsg = {0};
1125
1126         for (unsigned int i = 0; i < simIdList.size(); i++) {
1127                 if (simIdList[i].msgRef == pConcatMsg->msgRef) {
1128                         MSG_DEBUG("Get SIM ID [%d] - List Index [%d]", simIdList[i].simId, concatSimMsg.simIdCnt);
1129
1130                         concatSimMsg.simIdList[concatSimMsg.simIdCnt] = simIdList[i].simId;
1131                         concatSimMsg.simIdCnt++;
1132                 }
1133         }
1134
1135         int bufSize = (MAX_MSG_DATA_LEN*MAX_SEGMENT_NUM) + 1;
1136
1137         char tmpBuf[bufSize];
1138         memset(tmpBuf, 0x00, sizeof(tmpBuf));
1139
1140         /* Convert Data values */
1141         if (pConcatMsg->dcs.codingScheme == SMS_CHARSET_7BIT) {
1142                 SMS_LANG_INFO_S langInfo = {0};
1143
1144                 langInfo.bSingleShift = false;
1145                 langInfo.bLockingShift = false;
1146
1147                 pMsgInfo->encodeType = MSG_ENCODE_GSM7BIT;
1148                 pMsgInfo->dataSize = SmsPluginTextConvert::instance()->convertGSM7bitToUTF8((unsigned char*)tmpBuf, bufSize, (unsigned char*)pUserData, DataSize, &langInfo);
1149         } else if (pConcatMsg->dcs.codingScheme == SMS_CHARSET_8BIT) {
1150                 pMsgInfo->encodeType = MSG_ENCODE_8BIT;
1151                 memcpy(tmpBuf, pUserData, DataSize);
1152                 pMsgInfo->dataSize = DataSize;
1153         } else if (pConcatMsg->dcs.codingScheme == SMS_CHARSET_UCS2) {
1154                 pMsgInfo->encodeType = MSG_ENCODE_UCS2;
1155                 pMsgInfo->dataSize = SmsPluginTextConvert::instance()->convertUCS2ToUTF8((unsigned char*)tmpBuf, bufSize, (unsigned char*)pUserData, DataSize);
1156         }
1157
1158         MSG_DEBUG("Data Size [%d]", pMsgInfo->dataSize);
1159
1160         pMsgInfo->bTextSms = false;
1161
1162         if (pMsgInfo->dataSize > 0)
1163                 memcpy(concatSimMsg.msgData, tmpBuf, pMsgInfo->dataSize);
1164
1165         /* Save Message Data into File */
1166         char fileName[MAX_COMMON_INFO_SIZE+1];
1167         memset(fileName, 0x00, sizeof(fileName));
1168
1169         if (MsgCreateFileName(fileName) == false)
1170                 THROW(MsgException::FILE_ERROR, "MsgCreateFileName error");
1171
1172         if (MsgWriteIpcFile(fileName, (char*)(&concatSimMsg), sizeof(SMS_CONCAT_SIM_MSG_S)) == false)
1173                 THROW(MsgException::FILE_ERROR, "MsgWriteIpcFile error");
1174
1175         memset(pMsgInfo->msgData, 0x00, sizeof(pMsgInfo->msgData));
1176         strncpy(pMsgInfo->msgData, fileName, MAX_MSG_DATA_LEN);
1177
1178         MSG_SEC_DEBUG("Save Message Data into file : size[%d] name[%s]", pMsgInfo->dataSize, fileName);
1179 }
1180 #endif
1181
1182
1183 void SmsPluginConcatHandler::removeFromConcatList(unsigned short MsgRef, int simIndex, char *originAddress)
1184 {
1185         for (int index = concatList.size()-1; index >= 0 ; index--) {
1186                 if (concatList[index].msgRef == MsgRef && concatList[index].simIndex == simIndex
1187                         && g_strcmp0(concatList[index].originAddress.address, originAddress) == 0) {
1188                         MSG_DEBUG("remove concatlist of the index [%d]", index);
1189                         concatList.erase(concatList.begin()+index);
1190                         break;
1191                 }
1192         }
1193 }
1194
1195 #ifdef CONCAT_SIM_MSG_OPERATION
1196 void SmsPluginConcatHandler::addToSimIdList(unsigned short MsgRef, msg_sim_id_t SimMsgId)
1197 {
1198         SMS_SIM_ID_S simIdStruct;
1199
1200         simIdStruct.msgRef = MsgRef;
1201         simIdStruct.simId = SimMsgId;
1202
1203         simIdList.push_back(simIdStruct);
1204 }
1205
1206
1207 void SmsPluginConcatHandler::removeFromSimIdList(unsigned short MsgRef)
1208 {
1209         for (int index = simIdList.size()-1; index >= 0 ; index--) {
1210                 if (simIdList[index].msgRef == MsgRef) {
1211                         MSG_DEBUG("remove simIdList of the index [%d]", index);
1212
1213                         simIdList.erase(simIdList.begin()+index);
1214                 }
1215         }
1216 }
1217 #endif