update tizen source
[framework/messaging/msg-service.git] / plugin / sms_plugin / SmsPluginTransport.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 <errno.h>
32
33 #include "MsgDebug.h"
34 #include "MsgCppTypes.h"
35 #include "MsgException.h"
36 #include "MsgGconfWrapper.h"
37 #include "MsgUtilFile.h"
38 #include "SmsPluginTextConvert.h"
39 #include "SmsPluginParamCodec.h"
40 #include "SmsPluginTpduCodec.h"
41 #include "SmsPluginEventHandler.h"
42 #include "SmsPluginStorage.h"
43 #include "SmsPluginTransport.h"
44
45 extern "C"
46 {
47         #include <ITapiNetText.h>
48 }
49
50 #define MSG_DEBUG_BY_FILE
51
52 /*==================================================================================================
53                                      IMPLEMENTATION OF SmsPluginTransport - Member Functions
54 ==================================================================================================*/
55 SmsPluginTransport* SmsPluginTransport::pInstance = NULL;
56
57
58 SmsPluginTransport::SmsPluginTransport()
59 {
60         msgRef          = 0x00;
61         msgRef8bit      = 0x00;
62         msgRef16bit     = 0x0000;
63 }
64
65
66 SmsPluginTransport::~SmsPluginTransport()
67 {
68
69 }
70
71
72 SmsPluginTransport* SmsPluginTransport::instance()
73 {
74         if (!pInstance)
75                 pInstance = new SmsPluginTransport();
76
77         return pInstance;
78 }
79
80
81 void SmsPluginTransport::submitRequest(SMS_REQUEST_INFO_S *pReqInfo)
82 {
83         MSG_BEGIN();
84
85         SMS_TPDU_S tpdu;
86
87         tpdu.tpduType = SMS_TPDU_SUBMIT;
88
89         // Set SMS Send Options - Setting
90         setSmsSendOptions(&(tpdu.data.submit));
91
92         // Set SMS Send Options - Each Message
93         if (pReqInfo->sendOptInfo.bSetting == true)
94         {
95                 tpdu.data.submit.bStatusReport = pReqInfo->sendOptInfo.bDeliverReq;
96                 tpdu.data.submit.bReplyPath = pReqInfo->sendOptInfo.option.smsSendOptInfo.bReplyPath;
97         }
98
99         // Set Coding Scheme for apps that use port number
100         if (pReqInfo->msgInfo.msgPort.valid == true)
101         {
102                 tpdu.data.submit.dcs.codingScheme = (SMS_CODING_SCHEME_T)pReqInfo->msgInfo.encodeType;
103
104                 MSG_DEBUG("DCS is changed by application : [%d]", tpdu.data.submit.dcs.codingScheme);
105         }
106
107         // Set SMSC Options
108         SMS_ADDRESS_S smsc;
109         setSmscOptions(&smsc);
110
111         // Make SMS_SUBMIT_DATA_S from MSG_REQUEST_INFO_S
112         SMS_SUBMIT_DATA_S submitData = {{0},};
113         msgInfoToSubmitData(&(pReqInfo->msgInfo), &submitData, &(tpdu.data.submit.dcs.codingScheme));
114
115         // Encode SMSC Address
116         unsigned char smscAddr[MAX_SMSC_LEN];
117         memset(smscAddr, 0x00, sizeof(smscAddr));
118
119         int smscLen = SmsPluginParamCodec::encodeSMSC(&smsc, smscAddr);
120
121         if (smscLen <= 0) return;
122
123         for (int i = 0; i < smscLen; i++)
124         {
125                 MSG_DEBUG("pSCAInfo [%02x]", smscAddr[i]);
126         }
127
128         int bufLen = 0, reqId = 0;
129
130         char buf[MAX_TPDU_DATA_LEN];
131
132         int addLen = strlen(submitData.destAddress.address);
133
134         tpdu.data.submit.destAddress.ton = submitData.destAddress.ton;
135         tpdu.data.submit.destAddress.npi = submitData.destAddress.npi;
136
137         memcpy(tpdu.data.submit.destAddress.address, submitData.destAddress.address, addLen);
138         tpdu.data.submit.destAddress.address[addLen] = '\0';
139
140         for (unsigned int segCnt = 0; segCnt < submitData.segCount; segCnt++)
141         {
142                 if (submitData.userData[segCnt].headerCnt > 0)
143                 {
144                         tpdu.data.submit.bHeaderInd = true;
145                 }
146                 else
147                 {
148                         tpdu.data.submit.bHeaderInd = false;
149                 }
150
151                 memset(&(tpdu.data.submit.userData), 0x00, sizeof(SMS_USERDATA_S));
152                 memcpy(&(tpdu.data.submit.userData), &(submitData.userData[segCnt]), sizeof(SMS_USERDATA_S));
153
154                 // Encode SMS-SUBMIT TPDU
155                 memset(buf, 0x00, sizeof(buf));
156
157                 bufLen = SmsPluginTpduCodec::encodeTpdu(&tpdu, buf);
158
159                 // Make Telephony Structure
160                 TelSmsDatapackageInfo_t pkgInfo;
161
162                 // Set TPDU data
163                 memset((void*)pkgInfo.szData, 0x00, sizeof(pkgInfo.szData));
164                 memcpy((void*)pkgInfo.szData, buf, bufLen);
165
166                 pkgInfo.szData[bufLen] = 0;
167                 pkgInfo.MsgLength = bufLen;
168
169                 // Set SMSC data
170                 memset(pkgInfo.Sca, 0x00, sizeof(pkgInfo.Sca));
171                 memcpy((void*)pkgInfo.Sca, smscAddr, smscLen);
172                 pkgInfo.Sca[smscLen] = '\0';
173
174                 MSG_DEBUG("bReqCb [%d]", pReqInfo->bReqCb);
175
176                 SMS_SENT_INFO_S sentInfo = {};
177
178                 TS_BOOL bMoreMsg = FALSE;
179
180                 memcpy(&(sentInfo.reqInfo), pReqInfo, sizeof(SMS_REQUEST_INFO_S));
181
182                 if ((segCnt+1) == submitData.segCount)
183                 {
184                         sentInfo.bLast = true;
185
186                         bMoreMsg = FALSE;
187                 }
188                 else
189                 {
190                         sentInfo.bLast = false;
191
192                         bMoreMsg = TRUE;
193                 }
194
195                 SmsPluginEventHandler::instance()->SetSentInfo(&sentInfo);
196
197                 curStatus = MSG_NETWORK_SENDING;
198
199                 // Send SMS
200                 int tapiRet = TAPI_API_SUCCESS;
201
202                 tapiRet = tel_send_sms(&pkgInfo, bMoreMsg, &reqId);
203
204                 if (tapiRet == TAPI_API_SUCCESS)
205                 {
206                         MSG_DEBUG("########  TelTapiSmsSend Success !!! req Id : [%d] return : [%d] #######", reqId, tapiRet);
207                 }
208                 else
209                 {
210                         SmsPluginEventHandler::instance()->handleSentStatus(reqId, MSG_NETWORK_SEND_FAIL);
211
212                         THROW(MsgException::SMS_PLG_ERROR, "########  TelTapiSmsSend Fail !!! req Id : [%d] return : [%d] #######", reqId, tapiRet);
213                 }
214
215                 MSG_NETWORK_STATUS_T retStatus = getNetStatus();
216
217                 if (retStatus == MSG_NETWORK_SEND_SUCCESS)
218                 {
219                         MSG_DEBUG("########  Msg Sent was Successful !!! req Id : [%d] return : [%d] #######", reqId, retStatus);
220                 }
221                 else
222                 {
223                         THROW(MsgException::SMS_PLG_ERROR, "########  Msg Sent was Failed !!! req Id : [%d] return : [%d] #######", reqId, retStatus);
224                 }
225
226                 if (tpdu.data.submit.userData.headerCnt > 0) tpdu.data.submit.userData.headerCnt--;
227         }
228
229         MSG_END();
230 }
231
232
233 void SmsPluginTransport::sendDeliverReport(MSG_ERROR_T err)
234 {
235         MSG_BEGIN();
236
237         SMS_TPDU_S tpdu;
238
239         tpdu.tpduType = SMS_TPDU_DELIVER_REP;
240
241         TelSmsResponse_t response;
242
243         int tapiRet = TAPI_API_SUCCESS, reqId = 0;
244
245         if (err == MSG_SUCCESS)
246         {
247                 tpdu.data.deliverRep.reportType = SMS_REPORT_POSITIVE;
248                 response = TAPI_NETTEXT_SENDSMS_SUCCESS;
249
250                 tapiRet = tel_set_sms_memory_status(TAPI_NETTEXT_PDA_MEMORY_STATUS_AVAILABLE, &reqId);
251
252                 if (tapiRet == TAPI_API_SUCCESS)
253                 {
254                         MSG_DEBUG("########  tel_set_sms_memory_status() Success !!! req Id : [%d] #######", reqId);
255                 }
256                 else
257                 {
258                         MSG_DEBUG("########  tel_set_sms_memory_status() Success !!! req Id : [%d] return : [%d] #######", reqId, tapiRet);
259                 }
260         }
261         else if (err == MSG_ERR_SIM_STORAGE_FULL)
262         {
263                 tpdu.data.deliverRep.reportType = SMS_REPORT_NEGATIVE;
264                 tpdu.data.deliverRep.failCause = SMS_FC_MSG_CAPA_EXCEEDED;
265                 response = TAPI_NETTEXT_SIM_FULL;
266
267                 tapiRet = tel_set_sms_memory_status(TAPI_NETTEXT_PDA_MEMORY_STATUS_FULL, &reqId);
268
269                 if (tapiRet == TAPI_API_SUCCESS)
270                 {
271                         MSG_DEBUG("########  tel_set_sms_memory_status() Success !!! req Id : [%d] #######", reqId);
272                 }
273                 else
274                 {
275                         MSG_DEBUG("########  tel_set_sms_memory_status() Success !!! req Id : [%d] return : [%d] #######", reqId, tapiRet);
276                 }
277         }
278         else if (err == MSG_ERR_MESSAGE_COUNT_FULL)
279         {
280                 tpdu.data.deliverRep.reportType = SMS_REPORT_NEGATIVE;
281                 tpdu.data.deliverRep.failCause = SMS_FC_MSG_CAPA_EXCEEDED;
282                 response = TAPI_NETTEXT_ME_FULL;
283
284                 tapiRet = tel_set_sms_memory_status(TAPI_NETTEXT_PDA_MEMORY_STATUS_FULL, &reqId);
285
286                 if (tapiRet == TAPI_API_SUCCESS)
287                 {
288                         MSG_DEBUG("########  tel_set_sms_memory_status() Success !!! req Id : [%d] #######", reqId);
289                 }
290                 else
291                 {
292                         MSG_DEBUG("########  tel_set_sms_memory_status() Success !!! req Id : [%d] return : [%d] #######", reqId, tapiRet);
293                 }
294         }
295         else
296         {
297                 tpdu.data.deliverRep.reportType = SMS_REPORT_NEGATIVE;
298                 tpdu.data.deliverRep.failCause = SMS_FC_UNSPEC_ERROR;
299                 response = TAPI_NETTEXT_SIM_FULL;
300
301         }
302
303         MSG_DEBUG("err : [%d], response : [%02x]", err, response);
304
305         tpdu.data.deliverRep.bHeaderInd = false;
306         tpdu.data.deliverRep.paramInd = 0x00;
307
308         // Encode SMS-DELIVER-REPORT TPDU
309         int bufLen = 0;
310
311         char buf[MAX_TPDU_DATA_LEN];
312         memset(buf, 0x00, sizeof(buf));
313
314         bufLen = SmsPluginTpduCodec::encodeTpdu(&tpdu, buf);
315
316         // Make Telephony Structure
317         TelSmsDatapackageInfo_t pkgInfo;
318
319         // Set TPDU data
320         memset((void*)pkgInfo.szData, 0x00, sizeof(pkgInfo.szData));
321         memcpy((void*)pkgInfo.szData, buf, bufLen);
322
323         pkgInfo.szData[bufLen] = 0;
324         pkgInfo.MsgLength = bufLen;
325
326         // Set SMSC Address
327         SMS_ADDRESS_S smsc;
328
329         // Set SMSC Options
330         setSmscOptions(&smsc);
331
332         // Encode SMSC Address
333         unsigned char smscAddr[MAX_SMSC_LEN];
334         memset(smscAddr, 0x00, sizeof(smscAddr));
335
336         int smscLen = SmsPluginParamCodec::encodeSMSC(&smsc, smscAddr);
337
338         if (smscLen <= 0) return;
339
340         // Set SMSC data
341         memset(pkgInfo.Sca, 0x00, sizeof(pkgInfo.Sca));
342         memcpy((void*)pkgInfo.Sca, smscAddr, smscLen);
343         pkgInfo.Sca[smscLen] = '\0';
344
345         // Send Deliver Report
346         tapiRet = tel_send_sms_deliver_report(&pkgInfo, response, &reqId);
347
348         if (tapiRet == TAPI_API_SUCCESS)
349         {
350                 MSG_DEBUG("########  tel_send_sms_deliver_report() Success !!! req Id : [%d] #######", reqId);
351         }
352         else
353         {
354                 MSG_DEBUG("########  tel_send_sms_deliver_report() Fail !!! req Id : [%d] return : [%d] #######", reqId, tapiRet);
355         }
356
357         MSG_END();
358 }
359
360
361 void SmsPluginTransport::setSmsSendOptions(SMS_SUBMIT_S *pSubmit)
362 {
363         // Set SMS Send Options
364         pSubmit->bRejectDup = false;
365         pSubmit->bHeaderInd = false;
366
367         MsgSettingGetBool(SMS_SEND_DELIVERY_REPORT, &pSubmit->bStatusReport);
368         MsgSettingGetBool(SMS_SEND_REPLY_PATH, &pSubmit->bReplyPath);
369
370         pSubmit->msgRef = msgRef++;
371
372         pSubmit->dcs.bCompressed = false;
373         pSubmit->dcs.msgClass = SMS_MSG_CLASS_NONE;
374         pSubmit->dcs.codingGroup = SMS_GROUP_GENERAL;
375
376         pSubmit->dcs.codingScheme = (SMS_CODING_SCHEME_T)MsgSettingGetInt(SMS_SEND_DCS);
377
378         MSG_DEBUG("DCS : %d", pSubmit->dcs.codingScheme);
379
380         int selectIdx = MsgSettingGetInt(SMSC_SELECTED);
381
382         char keyName[128];
383
384         memset(keyName, 0x00, sizeof(keyName));
385         sprintf(keyName, "%s/%d", SMSC_PID, selectIdx);
386         MSG_SMS_PID_T pid = (MSG_SMS_PID_T)MsgSettingGetInt(keyName);
387
388         pSubmit->pid = convertPid(pid);
389         MSG_DEBUG("PID : %d", pSubmit->pid);
390
391         memset(keyName, 0x00, sizeof(keyName));
392         sprintf(keyName, "%s/%d", SMSC_VAL_PERIOD, selectIdx);
393         int valPeriod = MsgSettingGetInt(keyName);
394
395         MSG_DEBUG("valPeriod : %d", valPeriod);
396
397         if (valPeriod == 0)
398         {
399                 pSubmit->vpf = SMS_VPF_NOT_PRESENT;
400         }
401         else
402         {
403                 pSubmit->vpf = SMS_VPF_RELATIVE;
404                 pSubmit->validityPeriod.format = SMS_TIME_RELATIVE;
405                 pSubmit->validityPeriod.time.relative.time = valPeriod;
406         }
407 }
408
409
410 void SmsPluginTransport::setSmscOptions(SMS_ADDRESS_S *pSmsc)
411 {
412         // Set SMSC Options
413         int selectIdx = MsgSettingGetInt(SMSC_SELECTED);
414
415         char keyName[128];
416
417         memset(keyName, 0x00, sizeof(keyName));
418         sprintf(keyName, "%s/%d", SMSC_ADDRESS, selectIdx);
419
420         char* tmpValue = NULL;
421
422         tmpValue = MsgSettingGetString(keyName);
423
424         if (tmpValue != NULL)
425         {
426                 memset(pSmsc->address, 0x00, sizeof(pSmsc->address));
427                 strncpy(pSmsc->address, tmpValue, MAX_ADDRESS_LEN);
428
429                 MSG_DEBUG("address : %s", pSmsc->address);
430         }
431         else
432         {
433                 strncpy(pSmsc->address, "", MAX_ADDRESS_LEN);
434         }
435
436         memset(keyName, 0x00, sizeof(keyName));
437         sprintf(keyName, "%s/%d", SMSC_TON, selectIdx);
438         pSmsc->ton = (SMS_TON_T)MsgSettingGetInt(keyName);
439
440         MSG_DEBUG("ton : %d", pSmsc->ton);
441
442         memset(keyName, 0x00, sizeof(keyName));
443         sprintf(keyName, "%s/%d", SMSC_NPI, selectIdx);
444         pSmsc->npi = (SMS_NPI_T)MsgSettingGetInt(keyName);
445
446         MSG_DEBUG("npi : %d", pSmsc->npi);
447
448         if (tmpValue != NULL)
449         {
450                 free(tmpValue);
451                 tmpValue = NULL;
452         }
453 }
454
455
456 void SmsPluginTransport::msgInfoToSubmitData(const MSG_MESSAGE_INFO_S *pMsgInfo, SMS_SUBMIT_DATA_S *pData, SMS_CODING_SCHEME_T *pCharType)
457 {
458         // Destination Address
459         pData->destAddress.ton = SMS_TON_NATIONAL;
460         pData->destAddress.npi = SMS_NPI_ISDN;
461
462         memset(pData->destAddress.address, 0x00, MAX_ADDRESS_LEN+1);
463         memcpy(pData->destAddress.address, pMsgInfo->addressList[0].addressVal, MAX_ADDRESS_LEN);
464
465         MSG_DEBUG("ton [%d]", pData->destAddress.ton);
466         MSG_DEBUG("npi [%d]", pData->destAddress.npi);
467         MSG_DEBUG("address [%s]", pData->destAddress.address);
468
469         int decodeLen = 0, bufSize = (MAX_GSM_7BIT_DATA_LEN*MAX_SEGMENT_NUM) + 1;       // SMS_CHARSET_7BIT
470
471         unsigned char decodeData[bufSize];
472         memset(decodeData, 0x00, sizeof(decodeData));
473
474         MSG_ENCODE_TYPE_T encodeType = MSG_ENCODE_GSM7BIT;
475
476         SMS_LANGUAGE_ID_T langId = SMS_LANG_ID_RESERVED;
477
478         // User Data
479         if (pMsgInfo->bTextSms == true)
480         {
481                 if (*pCharType == SMS_CHARSET_7BIT)
482                 {
483                         decodeLen = SmsPluginTextConvert::instance()->convertUTF8ToGSM7bit(decodeData, bufSize, (unsigned char*)pMsgInfo->msgText, pMsgInfo->dataSize, &langId);
484                 }
485                 else if (*pCharType == SMS_CHARSET_8BIT)
486                 {
487                         memcpy(decodeData, pMsgInfo->msgText, pMsgInfo->dataSize);
488                         decodeLen = pMsgInfo->dataSize;
489                 }
490                 else if (*pCharType == SMS_CHARSET_UCS2)
491                 {
492                         decodeLen = SmsPluginTextConvert::instance()->convertUTF8ToUCS2(decodeData, bufSize, (unsigned char*)pMsgInfo->msgText, pMsgInfo->dataSize);
493                 }
494                 else if (*pCharType == SMS_CHARSET_AUTO)
495                 {
496                         decodeLen = SmsPluginTextConvert::instance()->convertUTF8ToAuto(decodeData, bufSize, (unsigned char*)pMsgInfo->msgText, pMsgInfo->dataSize, &encodeType);
497                         *pCharType = encodeType;
498                 }
499         }
500         else
501         {
502                 int fileSize = 0;
503
504                 char* pFileData = NULL;
505                 AutoPtr<char> FileBuf(&pFileData);
506
507                 // Read Message Data from File
508                 if (MsgOpenAndReadFile(pMsgInfo->msgData, &pFileData, &fileSize) == false)
509                 THROW(MsgException::FILE_ERROR, "MsgOpenAndReadFile error");
510
511                 MSG_DEBUG("file size : [%d] file data : [%s]", fileSize, pFileData);
512
513                 if (*pCharType == SMS_CHARSET_7BIT)
514                 {
515                         decodeLen = SmsPluginTextConvert::instance()->convertUTF8ToGSM7bit(decodeData, bufSize, (unsigned char*)pFileData, fileSize, &langId);
516                 }
517                 else if (*pCharType == SMS_CHARSET_8BIT)
518                 {
519                         memcpy(decodeData, pFileData, fileSize);
520                         decodeLen = fileSize;
521                 }
522                 else if (*pCharType == SMS_CHARSET_UCS2)
523                 {
524                         decodeLen = SmsPluginTextConvert::instance()->convertUTF8ToUCS2(decodeData, bufSize, (unsigned char*)pFileData, fileSize);
525                 }
526                 else if (*pCharType == SMS_CHARSET_AUTO)
527                 {
528                         decodeLen = SmsPluginTextConvert::instance()->convertUTF8ToAuto(decodeData, bufSize, (unsigned char*)pFileData, fileSize, &encodeType);
529                         *pCharType = encodeType;
530                 }
531
532                 // Delete File
533                 MsgDeleteFile(pMsgInfo->msgData);
534         }
535
536 MSG_DEBUG("decode length : [%d]", decodeLen);
537 MSG_DEBUG("character type : [%d]", *pCharType);
538 MSG_DEBUG("Language Identifier : [%d]", langId);
539 MSG_DEBUG("reply address : [%s]", pMsgInfo->replyAddress);
540
541         int addrLen = 0;
542
543         char* encodedAddr = NULL;
544         AutoPtr<char> addressBuf(&encodedAddr);
545
546         if (strlen(pMsgInfo->replyAddress) > 0)
547         {
548                 SMS_ADDRESS_S replyAddr = {};
549
550                 replyAddr.ton = SMS_TON_NATIONAL;
551                 replyAddr.npi = SMS_NPI_ISDN;
552
553                 memset(replyAddr.address, 0x00, MAX_ADDRESS_LEN+1);
554                 memcpy(replyAddr.address, pMsgInfo->replyAddress, MAX_ADDRESS_LEN);
555
556                 addrLen = SmsPluginParamCodec::encodeAddress(&replyAddr, &encodedAddr);
557
558                 MSG_DEBUG("reply addr length : [%d]", addrLen);
559         }
560
561         int segSize = 0, index = 0;
562
563         segSize = getSegmentSize(*pCharType, decodeLen, pMsgInfo->msgPort.valid, langId, addrLen);
564
565         if (segSize >= decodeLen)
566                 pData->segCount = 1;
567         else
568                 pData->segCount = (decodeLen/segSize) + 1;
569
570 MSG_DEBUG("segment size : [%d], pData->segCount : [%d]", segSize, pData->segCount);
571
572         if (pData->segCount > MAX_SEGMENT_NUM)
573                 THROW(MsgException::SMS_PLG_ERROR, "Segment Count is over maximum : %d", pData->segCount);
574
575         int headerCnt = 0;
576
577         for (unsigned int i = 0; i < pData->segCount; i++)
578         {
579                 headerCnt = 0;
580
581                 if ((i + 1) == pData->segCount)
582                         pData->userData[i].length = decodeLen - (i*segSize);
583                 else
584                         pData->userData[i].length = segSize;
585
586                 memset(pData->userData[i].data, 0x00, MAX_USER_DATA_LEN+1);
587                 memcpy(pData->userData[i].data, &(decodeData[index]), pData->userData[i].length);
588                 pData->userData[i].data[pData->userData[i].length] = 0;
589
590 MSG_DEBUG("user data len [%d]", pData->userData[i].length);
591 MSG_DEBUG("user data [%s]", pData->userData[i].data);
592
593                 index += segSize;
594
595                 // Set User Data Header for Concatenated Message
596                 if (pData->segCount > 1)
597                 {
598                         pData->userData[i].header[headerCnt].udhType = SMS_UDH_CONCAT_8BIT;
599                         pData->userData[i].header[headerCnt].udh.concat8bit.msgRef = msgRef8bit;
600                         pData->userData[i].header[headerCnt].udh.concat8bit.totalSeg = pData->segCount;
601                         pData->userData[i].header[headerCnt].udh.concat8bit.seqNum = i + 1;
602
603                         headerCnt++;
604                 }
605
606                 // Set User Data Header Port Information
607                 if (pMsgInfo->msgPort.valid == true)
608                 {
609                         pData->userData[i].header[headerCnt].udhType = SMS_UDH_APP_PORT_16BIT;
610                         pData->userData[i].header[headerCnt].udh.appPort16bit.destPort = pMsgInfo->msgPort.dstPort;
611                         pData->userData[i].header[headerCnt].udh.appPort16bit.originPort = pMsgInfo->msgPort.srcPort;
612
613                         headerCnt++;
614                 }
615
616                 // Set User Data Header for Alternate Reply Address
617                 if (strlen(pMsgInfo->replyAddress) > 0)
618                 {
619                         pData->userData[i].header[headerCnt].udhType = SMS_UDH_ALTERNATE_REPLY_ADDRESS;
620
621                         pData->userData[i].header[headerCnt].udh.alternateAddress.ton = SMS_TON_NATIONAL;
622                         pData->userData[i].header[headerCnt].udh.alternateAddress.npi = SMS_NPI_ISDN;
623
624                         memset(pData->userData[i].header[headerCnt].udh.alternateAddress.address, 0x00, MAX_ADDRESS_LEN+1);
625                         memcpy(pData->userData[i].header[headerCnt].udh.alternateAddress.address, pMsgInfo->replyAddress, MAX_ADDRESS_LEN);
626
627                         headerCnt++;
628                 }
629
630                 // Set User Data Header for National Language Single Shift
631                 if (*pCharType == SMS_CHARSET_7BIT && langId != SMS_LANG_ID_RESERVED)
632                 {
633                         pData->userData[i].header[headerCnt].udhType = SMS_UDH_SINGLE_SHIFT;
634                         pData->userData[i].header[headerCnt].udh.singleShift.langId = langId;
635
636                         headerCnt++;
637                 }
638
639                 pData->userData[i].headerCnt = headerCnt;
640         }
641
642         msgRef8bit++;
643 }
644
645
646 int SmsPluginTransport::getSegmentSize(SMS_CODING_SCHEME_T CodingScheme, int DataLen, bool bPortNum, SMS_LANGUAGE_ID_T LangId, int ReplyAddrLen)
647 {
648         int headerLen = 1, concat = 5, port = 6, lang = 3, reply = 2;
649         int headerSize = 0, segSize = 0, maxSize = 0;
650
651         if (CodingScheme == SMS_CHARSET_7BIT)
652         {
653                 MSG_DEBUG("SMS_CHARSET_7BIT");
654                 maxSize = MAX_GSM_7BIT_DATA_LEN;
655         }
656         else if (CodingScheme == SMS_CHARSET_8BIT || CodingScheme == SMS_CHARSET_UCS2)
657         {
658                 MSG_DEBUG("SMS_CHARSET_8BIT or SMS_CHARSET_UCS2 [%d]", CodingScheme);
659                 maxSize = MAX_UCS2_DATA_LEN;
660         }
661
662         if (bPortNum == true)
663         {
664                 MSG_DEBUG("Port Number Exists");
665                 headerSize += port;
666         }
667
668         if (LangId != SMS_LANG_ID_RESERVED)
669         {
670                 MSG_DEBUG("National Language Exists");
671                 headerSize += lang;
672         }
673
674         if (ReplyAddrLen > 0)
675         {
676                 MSG_DEBUG("Reply Address Exists");
677                 headerSize += reply;
678                 headerSize += ReplyAddrLen;
679         }
680
681         if (CodingScheme == SMS_CHARSET_7BIT)
682         {
683                 if (((DataLen+headerSize)/maxSize) >= 1)
684                         segSize = ((140*8) - ((headerLen + concat + headerSize)*8)) / 7;
685                 else
686                         segSize = DataLen;
687         }
688         else if (CodingScheme == SMS_CHARSET_8BIT || CodingScheme == SMS_CHARSET_UCS2)
689         {
690                 if (((DataLen+headerSize)/maxSize) >= 1)
691                         segSize = 140 - (headerLen + concat + headerSize);
692                 else
693                         segSize = DataLen;
694         }
695
696         return segSize;
697 }
698
699
700 void SmsPluginTransport::setConcatHeader(SMS_UDH_S *pSrcHeader, SMS_UDH_S *pDstHeader)
701 {
702         pDstHeader->udhType = pSrcHeader->udhType;
703
704         switch (pDstHeader->udhType)
705         {
706                 case SMS_UDH_CONCAT_8BIT :
707                 {
708                         pDstHeader->udh.concat8bit.msgRef = pSrcHeader->udh.concat8bit.msgRef;
709                         pDstHeader->udh.concat8bit.totalSeg = pSrcHeader->udh.concat8bit.totalSeg;
710                         pDstHeader->udh.concat8bit.seqNum = pSrcHeader->udh.concat8bit.seqNum;
711                 }
712                 break;
713
714                 case SMS_UDH_CONCAT_16BIT :
715                 {
716                         pDstHeader->udh.concat16bit.msgRef = pSrcHeader->udh.concat16bit.msgRef;
717                         pDstHeader->udh.concat16bit.totalSeg = pSrcHeader->udh.concat16bit.totalSeg;
718                         pDstHeader->udh.concat16bit.seqNum = pSrcHeader->udh.concat16bit.seqNum;
719                 }
720                 break;
721         }
722 }
723
724
725 void SmsPluginTransport::setNetStatus(MSG_NETWORK_STATUS_T netStatus)
726 {
727         mx.lock();
728         curStatus = netStatus;
729         cv.signal();
730         mx.unlock();
731 }
732
733
734 MSG_NETWORK_STATUS_T SmsPluginTransport::getNetStatus()
735 {
736         mx.lock();
737
738         int ret = 0;
739
740         if (curStatus == MSG_NETWORK_SENDING)
741                 ret = cv.timedwait(mx.pMutex(), 65);
742
743         mx.unlock();
744
745         if (ret == ETIMEDOUT)
746         {
747                 MSG_DEBUG("WARNING: SENT STATUS TIME-OUT");
748                 curStatus = MSG_NETWORK_SEND_TIMEOUT;
749         }
750
751         return curStatus;
752 }
753
754
755 unsigned char SmsPluginTransport::getMsgRef()
756 {
757         return msgRef++;
758 }
759
760
761 SMS_PID_T SmsPluginTransport::convertPid(MSG_SMS_PID_T pid)
762 {
763         SMS_PID_T retPid;
764
765         switch (pid)
766         {
767                 case MSG_PID_TEXT :
768                         retPid = SMS_PID_NORMAL;
769                 break;
770                 case MSG_PID_VOICE :
771                         retPid = SMS_PID_VOICE;
772                 break;
773                 case MSG_PID_FAX :
774                         retPid = SMS_PID_TELEX;
775                 break;
776                 case MSG_PID_X400 :
777                         retPid = SMS_PID_x400;
778                 break;
779                 case MSG_PID_ERMES :
780                         retPid = SMS_PID_ERMES;
781                 break;
782                 case MSG_PID_EMAIL :
783                         retPid = SMS_PID_EMAIL;
784                 break;
785                 default :
786                         retPid = SMS_PID_NORMAL;
787                 break;
788         }
789
790         return retPid;
791 }