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