RSA sync with private
[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 "MsgNotificationWrapper.h"
25 #include "MsgUtilFile.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;
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 #ifdef MSG_FOR_DEBUG
142 MSG_DEBUG("ton [%d]", tpdu.data.submit.destAddress.ton);
143 MSG_DEBUG("npi [%d]", tpdu.data.submit.destAddress.npi);
144 MSG_DEBUG("address [%s]", tpdu.data.submit.destAddress.address);
145 #endif
146
147                 bool bStatusReport = false;
148
149                 for (unsigned int segCnt = 0; segCnt < submitData.segCount; segCnt++)
150                 {
151                         if (submitData.userData[segCnt].headerCnt > 0) {
152                                 tpdu.data.submit.bHeaderInd = true;
153                         } else {
154                                 tpdu.data.submit.bHeaderInd = false;
155                         }
156
157                         if (segCnt == 0 && submitData.segCount > 1) {
158                                 bStatusReport = tpdu.data.submit.bStatusReport;
159                                 tpdu.data.submit.bStatusReport = false;
160                         } else if ((segCnt+1 == submitData.segCount) && submitData.segCount > 1) {
161                                 tpdu.data.submit.bStatusReport = bStatusReport;
162                         }
163
164                         memset(&(tpdu.data.submit.userData), 0x00, sizeof(SMS_USERDATA_S));
165                         memcpy(&(tpdu.data.submit.userData), &(submitData.userData[segCnt]), sizeof(SMS_USERDATA_S));
166
167                         // Encode SMS-SUBMIT TPDU
168                         memset(buf, 0x00, sizeof(buf));
169
170                         bufLen = SmsPluginTpduCodec::encodeTpdu(&tpdu, buf);
171
172                         // Make Telephony Structure
173                         TelSmsDatapackageInfo_t pkgInfo;
174
175                         // Set TPDU data
176                         memset((void*)pkgInfo.szData, 0x00, sizeof(pkgInfo.szData));
177                         memcpy((void*)pkgInfo.szData, buf, bufLen);
178
179                         pkgInfo.szData[bufLen] = 0;
180                         pkgInfo.MsgLength = bufLen;
181
182                         // Set SMSC data
183                         memset(pkgInfo.Sca, 0x00, sizeof(pkgInfo.Sca));
184                         memcpy((void*)pkgInfo.Sca, smscAddr, smscLen);
185                         pkgInfo.Sca[smscLen] = '\0';
186
187 #ifdef MSG_FOR_DEBUG
188                         MSG_DEBUG("[submitRequest] TPDU.");
189
190                         for (j = 0; j < pkgInfo.MsgLength; j++)
191                         {
192                                 MSG_DEBUG("[%02x]", pkgInfo.szData[j]);
193                         }
194
195                         for (j = 0; j < smscLen; j++)
196                         {
197                                 MSG_DEBUG("pkgInfo.pSCA [%02x]", pkgInfo.Sca[j]);
198                         }
199 #endif
200
201 #ifdef MSG_DEBUG_BY_FILE
202                         char temp[2048];
203                         char tempcat[100];
204                         memset(temp, 0x00, sizeof(temp));
205                         memset(tempcat, 0x00, sizeof(tempcat));
206
207                         time_t rawtime;
208                         time(&rawtime);
209
210                         snprintf(temp, sizeof(temp), "[MO] %s", ctime(&rawtime));
211
212                         for (j = 0; j < pkgInfo.MsgLength; j++)
213                         {
214                                 snprintf(tempcat, sizeof(tempcat), "[%02x]\n", pkgInfo.szData[j]);
215                                 strncat(temp, tempcat, sizeof(temp)-strlen(temp)-1);
216                                 memset(tempcat, 0x00, sizeof(tempcat));
217                         }
218
219
220                         snprintf(tempcat, sizeof(tempcat), "\n\n\n");
221                         strncat(temp, tempcat, sizeof(temp)-strlen(temp)-1);
222
223                         //MSG_DEBUG("temp [%s], length [%d]", temp, strlen(temp));
224
225                         //MsgOpenCreateAndOverwriteFile(TPDU_LOG_FILE, temp, strlen(temp));
226                         FILE*   pFile=NULL ;
227                         pFile = MsgOpenFile(TPDU_LOG_FILE, "a");
228                         MsgWriteFile(temp, sizeof(char), strlen(temp), pFile);
229
230                         MsgFflush(pFile);
231                         MsgCloseFile(pFile);
232
233 #endif
234
235                         SMS_SENT_INFO_S sentInfo = {};
236
237                         bool bMoreMsg = FALSE;
238
239                         memcpy(&(sentInfo.reqInfo), pReqInfo, sizeof(SMS_REQUEST_INFO_S));
240
241                         if ((segCnt+1) == submitData.segCount && (i+1)==pReqInfo->msgInfo.nAddressCnt)
242                         {
243                                 sentInfo.bLast = true;
244
245                                 bMoreMsg = FALSE;
246                         }
247                         else
248                         {
249                                 sentInfo.bLast = false;
250
251                                 bMoreMsg = TRUE;
252                         }
253
254                         SmsPluginEventHandler::instance()->SetSentInfo(&sentInfo);
255
256                         curStatus = MSG_NETWORK_SENDING;
257
258                         // Send SMS
259                         int tapiRet = TAPI_API_SUCCESS;
260
261                         tapiRet = tel_send_sms(pTapiHandle, &pkgInfo, bMoreMsg, TapiEventSentStatus, NULL);
262
263                         if (tapiRet == TAPI_API_SUCCESS)
264                         {
265                                 MSG_DEBUG("########  TelTapiSmsSend Success !!! return : [%d] #######", tapiRet);
266                         }
267                         else
268                         {
269                                 SmsPluginEventHandler::instance()->handleSentStatus(MSG_NETWORK_SEND_FAIL);
270
271                                 THROW(MsgException::SMS_PLG_ERROR, "########  TelTapiSmsSend Fail !!! return : [%d] #######", tapiRet);
272                         }
273
274                         // Tizen Validation System
275                         char *msisdn = NULL;
276                         msisdn = MsgSettingGetString(MSG_SIM_MSISDN);
277
278                         MSG_SMS_VLD_INFO("%d, SMS Send Start, %s->%s, %s",  pReqInfo->msgInfo.msgId, \
279                                                                                                                                                 (msisdn == NULL)?"ME":msisdn, \
280                                                                                                                                                 pReqInfo->msgInfo.addressList[0].addressVal, \
281                                                                                                                                                 (tapiRet == TAPI_API_SUCCESS)?"Success":"Fail");
282
283                         MSG_SMS_VLD_TXT("%d, [%s]", pReqInfo->msgInfo.msgId, pReqInfo->msgInfo.msgText);
284
285                         msg_network_status_t retStatus = getNetStatus();
286
287         #ifdef MSG_SMS_REPORT
288                         if (err == MSG_SUCCESS && tmpInfo.msgInfo.msgPort.valid == false)
289                         {
290                                 if(pReqInfo->sendOptInfo.bDeliverReq == true)
291                                 {
292                                         MSG_DEBUG("Update Delivery Report Status : [%d] Msg ID : [%d]", err, tmpInfo.msgInfo.msgId);
293
294                                         // Adding delivery report status info.
295                                         MsgStoAddDeliveryReportStatus( tmpInfo.msgInfo.msgId, (unsigned char)tmpInfo.msgInfo.referenceId);
296                                 }
297                         }
298         #endif
299
300                         MSG_SMS_VLD_INFO("%d, SMS Send End, %s->%s, %s",  pReqInfo->msgInfo.msgId, \
301                                                                                                                                         (msisdn == NULL)?"ME":msisdn, \
302                                                                                                                                         pReqInfo->msgInfo.addressList[0].addressVal, \
303                                                                                                                                         (retStatus == MSG_NETWORK_SEND_SUCCESS)?"Success":"Fail");
304
305
306                         if (retStatus == MSG_NETWORK_SEND_SUCCESS)
307                         {
308                                 if (bMoreMsg == false) {
309                                         MsgInsertTicker("SMS is sent", SMS_MESSAGE_SENT);
310                                 }
311                                 MSG_DEBUG("########  Msg Sent was Successful !!! return : [%d] #######", retStatus);
312                         }
313                         else
314                         {
315                                 MsgInsertTicker("Sending SMS is failed", NULL);
316                                 MsgInsertTicker("Sending SMS is failed", SMS_MESSAGE_SENDING_FAIL);
317
318                                 SmsPluginEventHandler::instance()->handleSentStatus(MSG_NETWORK_SEND_FAIL);
319
320                                 THROW(MsgException::SMS_PLG_ERROR, "########  Msg Sent was Failed !!! return : [%d] #######", retStatus);
321                         }
322
323                         if (tpdu.data.submit.userData.headerCnt > 0) tpdu.data.submit.userData.headerCnt--;
324                 }
325         }
326
327         MSG_END();
328 }
329
330
331 void SmsPluginTransport::sendDeliverReport(msg_error_t err)
332 {
333         MSG_BEGIN();
334
335         SMS_TPDU_S tpdu;
336
337         tpdu.tpduType = SMS_TPDU_DELIVER_REP;
338
339         TelSmsResponse_t response;
340
341         int tapiRet = TAPI_API_SUCCESS;
342
343         if (err == MSG_SUCCESS)
344         {
345                 tpdu.data.deliverRep.reportType = SMS_REPORT_POSITIVE;
346                 response = TAPI_NETTEXT_SENDSMS_SUCCESS;
347
348                 tapiRet = tel_set_sms_memory_status(pTapiHandle, TAPI_NETTEXT_PDA_MEMORY_STATUS_AVAILABLE, TapiEventMemoryStatus, NULL);
349
350                 if (tapiRet == TAPI_API_SUCCESS)
351                 {
352                         MSG_DEBUG("########  tel_set_sms_memory_status() Success !!! #######");
353                 }
354                 else
355                 {
356                         MSG_DEBUG("########  tel_set_sms_memory_status() Failed !!! return : [%d] #######", tapiRet);
357                 }
358         }
359         else if (err == MSG_ERR_SIM_STORAGE_FULL)
360         {
361                 tpdu.data.deliverRep.reportType = SMS_REPORT_NEGATIVE;
362                 tpdu.data.deliverRep.failCause = SMS_FC_MSG_CAPA_EXCEEDED;
363                 response = TAPI_NETTEXT_SIM_FULL;
364
365                 tapiRet = tel_set_sms_memory_status(pTapiHandle, TAPI_NETTEXT_PDA_MEMORY_STATUS_FULL, TapiEventMemoryStatus, NULL);
366
367                 if (tapiRet == TAPI_API_SUCCESS)
368                 {
369                         MSG_DEBUG("########  tel_set_sms_memory_status() Success !!! #######");
370                 }
371                 else
372                 {
373                         MSG_DEBUG("########  tel_set_sms_memory_status() Failed !!! return : [%d] #######", tapiRet);
374                 }
375         }
376         else if (err == MSG_ERR_MESSAGE_COUNT_FULL)
377         {
378                 tpdu.data.deliverRep.reportType = SMS_REPORT_NEGATIVE;
379                 tpdu.data.deliverRep.failCause = SMS_FC_MSG_CAPA_EXCEEDED;
380                 response = TAPI_NETTEXT_ME_FULL;
381
382                 tapiRet = tel_set_sms_memory_status(pTapiHandle, TAPI_NETTEXT_PDA_MEMORY_STATUS_FULL, TapiEventMemoryStatus, NULL);
383
384                 if (tapiRet == TAPI_API_SUCCESS)
385                 {
386                         MSG_DEBUG("########  tel_set_sms_memory_status() Success !!! #######");
387                 }
388                 else
389                 {
390                         MSG_DEBUG("########  tel_set_sms_memory_status() Failed !!! return : [%d] #######", tapiRet);
391                 }
392         }
393         else
394         {
395                 tpdu.data.deliverRep.reportType = SMS_REPORT_NEGATIVE;
396                 tpdu.data.deliverRep.failCause = SMS_FC_UNSPEC_ERROR;
397                 //response = TAPI_NETTEXT_PROTOCOL_ERROR;
398                 // For gcf test [34.2.5.3 class2 message]
399                 response = TAPI_NETTEXT_SIM_FULL;
400
401         }
402
403         MSG_DEBUG("err : [%d], response : [%02x]", err, response);
404
405         tpdu.data.deliverRep.bHeaderInd = false;
406         tpdu.data.deliverRep.paramInd = 0x00;
407
408         // Encode SMS-DELIVER-REPORT TPDU
409         int bufLen = 0;
410
411         char buf[MAX_TPDU_DATA_LEN];
412         memset(buf, 0x00, sizeof(buf));
413
414         bufLen = SmsPluginTpduCodec::encodeTpdu(&tpdu, buf);
415
416 #ifdef MSG_FOR_DEBUG
417         /////// print DeliverReport tpdu
418         printf("\n\n######## DeliverReport tpdu #########\n");
419         for(int i=0; i < bufLen; i++)
420         {
421                 printf("[%02x] ", buf[i]);
422         }
423         printf("\n#################################\n\n");
424         //////
425 #endif
426
427         // Make Telephony Structure
428         TelSmsDatapackageInfo_t pkgInfo;
429
430         // Set TPDU data
431         memset((void*)pkgInfo.szData, 0x00, sizeof(pkgInfo.szData));
432         memcpy((void*)pkgInfo.szData, buf, bufLen);
433
434         pkgInfo.szData[bufLen] = 0;
435         pkgInfo.MsgLength = bufLen;
436
437         // Set SMSC Address
438         SMS_ADDRESS_S smsc;
439
440         // Set SMSC Options
441         setSmscOptions(&smsc);
442
443         // Encode SMSC Address
444         unsigned char smscAddr[MAX_SMSC_LEN];
445         memset(smscAddr, 0x00, sizeof(smscAddr));
446
447         int smscLen = SmsPluginParamCodec::encodeSMSC(&smsc, smscAddr);
448
449         if (smscLen <= 0) return;
450
451         // Set SMSC data
452         memset(pkgInfo.Sca, 0x00, sizeof(pkgInfo.Sca));
453         memcpy((void*)pkgInfo.Sca, smscAddr, smscLen);
454         pkgInfo.Sca[smscLen] = '\0';
455
456         // Send Deliver Report
457         tapiRet = tel_send_sms_deliver_report(pTapiHandle, &pkgInfo, response, TapiEventDeliveryReportCNF, NULL);
458
459         if (tapiRet == TAPI_API_SUCCESS)
460         {
461                 MSG_DEBUG("########  tel_send_sms_deliver_report() Success !!! #######");
462         }
463         else
464         {
465                 MSG_DEBUG("########  tel_send_sms_deliver_report() Fail !!! return : [%d] #######", tapiRet);
466         }
467
468         MSG_END();
469 }
470
471 void SmsPluginTransport::sendClass0DeliverReport(msg_error_t err)
472 {
473         MSG_BEGIN();
474
475         SMS_TPDU_S tpdu;
476
477         tpdu.tpduType = SMS_TPDU_DELIVER_REP;
478
479         TelSmsResponse_t response;
480
481         int tapiRet = TAPI_API_SUCCESS;
482
483         if (err == MSG_SUCCESS)
484         {
485                 tpdu.data.deliverRep.reportType = SMS_REPORT_POSITIVE;
486                 response = TAPI_NETTEXT_SENDSMS_SUCCESS;
487
488                 tapiRet = tel_set_sms_memory_status(pTapiHandle, TAPI_NETTEXT_PDA_MEMORY_STATUS_AVAILABLE, TapiEventMemoryStatus, NULL);
489
490                 if (tapiRet == TAPI_API_SUCCESS)
491                 {
492                         MSG_DEBUG("########  tel_set_sms_memory_status() Success !!! #######");
493                 }
494                 else
495                 {
496                         MSG_DEBUG("########  tel_set_sms_memory_status() Failed !!! return : [%d] #######", tapiRet);
497                 }
498         }
499         else if (err == MSG_ERR_SIM_STORAGE_FULL)
500         {
501                 tpdu.data.deliverRep.reportType = SMS_REPORT_POSITIVE;
502                 response = TAPI_NETTEXT_SENDSMS_SUCCESS;
503
504                 tapiRet = tel_set_sms_memory_status(pTapiHandle, TAPI_NETTEXT_PDA_MEMORY_STATUS_FULL, TapiEventMemoryStatus, NULL);
505
506                 if (tapiRet == TAPI_API_SUCCESS)
507                 {
508                         MSG_DEBUG("########  tel_set_sms_memory_status() Success !!! #######");
509                 }
510                 else
511                 {
512                         MSG_DEBUG("########  tel_set_sms_memory_status() Failed !!! return : [%d] #######", tapiRet);
513                 }
514         }
515         else if (err == MSG_ERR_MESSAGE_COUNT_FULL)
516         {
517                 tpdu.data.deliverRep.reportType = SMS_REPORT_POSITIVE;
518                 response = TAPI_NETTEXT_SENDSMS_SUCCESS;
519
520                 tapiRet = tel_set_sms_memory_status(pTapiHandle, TAPI_NETTEXT_PDA_MEMORY_STATUS_FULL, TapiEventMemoryStatus, NULL);
521
522                 if (tapiRet == TAPI_API_SUCCESS)
523                 {
524                         MSG_DEBUG("########  tel_set_sms_memory_status() Success !!! #######");
525                 }
526                 else
527                 {
528                         MSG_DEBUG("########  tel_set_sms_memory_status() Failed !!! return : [%d] #######", tapiRet);
529                 }
530         }
531         else
532         {
533                 tpdu.data.deliverRep.reportType = SMS_REPORT_NEGATIVE;
534                 tpdu.data.deliverRep.failCause = SMS_FC_UNSPEC_ERROR;
535                 //response = TAPI_NETTEXT_PROTOCOL_ERROR;
536                 // For gcf test [34.2.5.3 class2 message]
537                 response = TAPI_NETTEXT_SIM_FULL;
538
539         }
540
541         MSG_DEBUG("err : [%d], response : [%02x]", err, response);
542
543         tpdu.data.deliverRep.bHeaderInd = false;
544         tpdu.data.deliverRep.paramInd = 0x00;
545
546         // Encode SMS-DELIVER-REPORT TPDU
547         int bufLen = 0;
548
549         char buf[MAX_TPDU_DATA_LEN];
550         memset(buf, 0x00, sizeof(buf));
551
552         bufLen = SmsPluginTpduCodec::encodeTpdu(&tpdu, buf);
553
554         // Make Telephony Structure
555         TelSmsDatapackageInfo_t pkgInfo;
556
557         // Set TPDU data
558         memset((void*)pkgInfo.szData, 0x00, sizeof(pkgInfo.szData));
559         memcpy((void*)pkgInfo.szData, buf, bufLen);
560
561         pkgInfo.szData[bufLen] = 0;
562         pkgInfo.MsgLength = bufLen;
563
564         // Set SMSC Address
565         SMS_ADDRESS_S smsc;
566
567         // Set SMSC Options
568         setSmscOptions(&smsc);
569
570         // Encode SMSC Address
571         unsigned char smscAddr[MAX_SMSC_LEN];
572         memset(smscAddr, 0x00, sizeof(smscAddr));
573
574         int smscLen = SmsPluginParamCodec::encodeSMSC(&smsc, smscAddr);
575
576         if (smscLen <= 0) return;
577
578         // Set SMSC data
579         memset(pkgInfo.Sca, 0x00, sizeof(pkgInfo.Sca));
580         memcpy((void*)pkgInfo.Sca, smscAddr, smscLen);
581         pkgInfo.Sca[smscLen] = '\0';
582
583         // Send Deliver Report
584         tapiRet = tel_send_sms_deliver_report(pTapiHandle, &pkgInfo, response, TapiEventDeliveryReportCNF, NULL);
585
586         if (tapiRet == TAPI_API_SUCCESS)
587         {
588                 MSG_DEBUG("########  tel_send_sms_deliver_report() Success !!! #######");
589         }
590         else
591         {
592                 MSG_DEBUG("########  tel_send_sms_deliver_report() Fail !!! return : [%d] #######", tapiRet);
593         }
594
595         MSG_END();
596 }
597
598
599
600 void SmsPluginTransport::setSmsSendOptions(SMS_SUBMIT_S *pSubmit)
601 {
602         // Set SMS Send Options
603         pSubmit->bRejectDup = false;
604         pSubmit->bHeaderInd = false;
605
606         MsgSettingGetBool(SMS_SEND_DELIVERY_REPORT, &pSubmit->bStatusReport);
607         MsgSettingGetBool(SMS_SEND_REPLY_PATH, &pSubmit->bReplyPath);
608
609         pSubmit->msgRef = msgRef++;
610
611         pSubmit->dcs.bCompressed = false;
612         pSubmit->dcs.msgClass = SMS_MSG_CLASS_NONE;
613         pSubmit->dcs.codingGroup = SMS_GROUP_GENERAL;
614
615         pSubmit->dcs.codingScheme = (SMS_CODING_SCHEME_T)MsgSettingGetInt(SMS_SEND_DCS);
616
617         MSG_DEBUG("DCS : %d", pSubmit->dcs.codingScheme);
618
619         int selectIdx = MsgSettingGetInt(SMSC_SELECTED);
620
621         char keyName[128];
622
623         memset(keyName, 0x00, sizeof(keyName));
624         sprintf(keyName, "%s/%d", SMSC_PID, selectIdx);
625         MSG_SMS_PID_T pid = (MSG_SMS_PID_T)MsgSettingGetInt(keyName);
626
627         pSubmit->pid = convertPid(pid);
628         MSG_DEBUG("PID : %d", pSubmit->pid);
629
630         memset(keyName, 0x00, sizeof(keyName));
631         sprintf(keyName, "%s/%d", SMSC_VAL_PERIOD, selectIdx);
632         int valPeriod = MsgSettingGetInt(keyName);
633
634         MSG_DEBUG("valPeriod : %d", valPeriod);
635
636         if (valPeriod == 0)
637         {
638                 pSubmit->vpf = SMS_VPF_NOT_PRESENT;
639         }
640         else
641         {
642                 pSubmit->vpf = SMS_VPF_RELATIVE;
643                 pSubmit->validityPeriod.format = SMS_TIME_RELATIVE;
644                 pSubmit->validityPeriod.time.relative.time = valPeriod;
645         }
646 }
647
648
649 void SmsPluginTransport::setSmscOptions(SMS_ADDRESS_S *pSmsc)
650 {
651         // Set SMSC Options
652         int selectIdx = MsgSettingGetInt(SMSC_SELECTED);
653
654         char keyName[128];
655
656         memset(keyName, 0x00, sizeof(keyName));
657         sprintf(keyName, "%s/%d", SMSC_ADDRESS, selectIdx);
658
659         char* tmpValue = NULL;
660
661         tmpValue = MsgSettingGetString(keyName);
662
663         if (tmpValue != NULL)
664         {
665                 memset(pSmsc->address, 0x00, sizeof(pSmsc->address));
666                 strncpy(pSmsc->address, tmpValue, MAX_ADDRESS_LEN);
667
668                 MSG_DEBUG("address : %s", pSmsc->address);
669         }
670         else
671         {
672                 strncpy(pSmsc->address, "+8210911111", MAX_ADDRESS_LEN);
673         }
674
675         memset(keyName, 0x00, sizeof(keyName));
676         sprintf(keyName, "%s/%d", SMSC_TON, selectIdx);
677         pSmsc->ton = (SMS_TON_T)MsgSettingGetInt(keyName);
678
679         MSG_DEBUG("ton : %d", pSmsc->ton);
680
681         memset(keyName, 0x00, sizeof(keyName));
682         sprintf(keyName, "%s/%d", SMSC_NPI, selectIdx);
683         pSmsc->npi = (SMS_NPI_T)MsgSettingGetInt(keyName);
684
685         MSG_DEBUG("npi : %d", pSmsc->npi);
686
687         if (tmpValue != NULL)
688         {
689                 free(tmpValue);
690                 tmpValue = NULL;
691         }
692 }
693
694
695 void SmsPluginTransport::msgInfoToSubmitData(const MSG_MESSAGE_INFO_S *pMsgInfo, SMS_SUBMIT_DATA_S *pData, SMS_CODING_SCHEME_T *pCharType, int addrIndex)
696 {
697         // Destination Address
698         pData->destAddress.ton = SMS_TON_UNKNOWN;
699         pData->destAddress.npi = SMS_NPI_ISDN;
700
701         memset(pData->destAddress.address, 0x00, MAX_ADDRESS_LEN+1);
702         memcpy(pData->destAddress.address, pMsgInfo->addressList[addrIndex].addressVal, MAX_ADDRESS_LEN);
703
704         MSG_DEBUG("ton [%d]", pData->destAddress.ton);
705         MSG_DEBUG("npi [%d]", pData->destAddress.npi);
706         MSG_DEBUG("address [%s]", pData->destAddress.address);
707
708         int decodeLen = 0, bufSize = (MAX_GSM_7BIT_DATA_LEN*MAX_SEGMENT_NUM) + 1;       // SMS_CHARSET_7BIT
709
710         unsigned char decodeData[bufSize];
711         memset(decodeData, 0x00, sizeof(decodeData));
712
713         msg_encode_type_t encodeType = MSG_ENCODE_GSM7BIT;
714
715         MSG_LANGUAGE_ID_T langId = MSG_LANG_ID_RESERVED;
716
717         bool bAbnormal = false;
718
719         // User Data
720         if (pMsgInfo->bTextSms == true)
721         {
722                 if (*pCharType == SMS_CHARSET_7BIT)
723                 {
724                         decodeLen = textCvt.convertUTF8ToGSM7bit(decodeData, bufSize, (unsigned char*)pMsgInfo->msgText, (int)pMsgInfo->dataSize, &langId, &bAbnormal);
725                 }
726                 else if (*pCharType == SMS_CHARSET_8BIT)
727                 {
728                         memcpy(decodeData, pMsgInfo->msgText, pMsgInfo->dataSize);
729                         decodeLen = pMsgInfo->dataSize;
730                 }
731                 else if (*pCharType == SMS_CHARSET_UCS2)
732                 {
733                         decodeLen = textCvt.convertUTF8ToUCS2(decodeData, bufSize, (unsigned char*)pMsgInfo->msgText, (int)pMsgInfo->dataSize);
734                 }
735                 else if (*pCharType == SMS_CHARSET_AUTO)
736                 {
737                         decodeLen = textCvt.convertUTF8ToAuto(decodeData, bufSize, (unsigned char*)pMsgInfo->msgText, (int)pMsgInfo->dataSize, &encodeType);
738                         *pCharType = encodeType;
739                 }
740         }
741         else
742         {
743                 int fileSize = 0;
744
745                 char* pFileData = NULL;
746                 AutoPtr<char> FileBuf(&pFileData);
747
748                 // Read Message Data from File
749                 if (MsgOpenAndReadFile(pMsgInfo->msgData, &pFileData, &fileSize) == false)
750                 THROW(MsgException::FILE_ERROR, "MsgOpenAndReadFile error");
751
752                 MSG_DEBUG("file size : [%d] file data : [%s]", fileSize, pFileData);
753
754                 if (*pCharType == SMS_CHARSET_7BIT)
755                 {
756                         decodeLen = textCvt.convertUTF8ToGSM7bit(decodeData, bufSize, (unsigned char*)pFileData, fileSize, &langId, &bAbnormal);
757                 }
758                 else if (*pCharType == SMS_CHARSET_8BIT)
759                 {
760                         memcpy(decodeData, pFileData, fileSize);
761                         decodeLen = fileSize;
762                 }
763                 else if (*pCharType == SMS_CHARSET_UCS2)
764                 {
765                         decodeLen = textCvt.convertUTF8ToUCS2(decodeData, bufSize, (unsigned char*)pFileData, fileSize);
766                 }
767                 else if (*pCharType == SMS_CHARSET_AUTO)
768                 {
769                         decodeLen = textCvt.convertUTF8ToAuto(decodeData, bufSize, (unsigned char*)pFileData, fileSize, &encodeType);
770                         *pCharType = encodeType;
771                 }
772
773                 // Delete File
774                 MsgDeleteFile(pMsgInfo->msgData);
775         }
776
777 MSG_DEBUG("decode length : [%d]", decodeLen);
778 MSG_DEBUG("character type : [%d]", *pCharType);
779 MSG_DEBUG("Language Identifier : [%d]", langId);
780 MSG_DEBUG("reply address : [%s]", pMsgInfo->replyAddress);
781
782         int addrLen = 0;
783
784         char* encodedAddr = NULL;
785         AutoPtr<char> addressBuf(&encodedAddr);
786
787         if (strlen(pMsgInfo->replyAddress) > 0)
788         {
789                 SMS_ADDRESS_S replyAddr = {};
790
791                 replyAddr.ton = SMS_TON_NATIONAL;
792                 replyAddr.npi = SMS_NPI_ISDN;
793
794                 memset(replyAddr.address, 0x00, MAX_ADDRESS_LEN+1);
795                 memcpy(replyAddr.address, pMsgInfo->replyAddress, MAX_ADDRESS_LEN);
796
797                 addrLen = SmsPluginParamCodec::encodeAddress(&replyAddr, &encodedAddr);
798
799                 MSG_DEBUG("reply addr length : [%d]", addrLen);
800         }
801
802         int segSize = 0, index = 0;
803
804         segSize = getSegmentSize(*pCharType, decodeLen, pMsgInfo->msgPort.valid, langId, addrLen);
805
806         pData->segCount = ceil((double)decodeLen/(double)segSize);
807
808 MSG_DEBUG("segment size : [%d], pData->segCount : [%d]", segSize, pData->segCount);
809
810         if (pData->segCount > MAX_SEGMENT_NUM)
811                 THROW(MsgException::SMS_PLG_ERROR, "Segment Count is over maximum : %d", pData->segCount);
812
813         int headerCnt = 0;
814
815         for (unsigned int i = 0; i < pData->segCount; i++)
816         {
817                 headerCnt = 0;
818
819                 if ((i + 1) == pData->segCount)
820                         pData->userData[i].length = decodeLen - (i*segSize);
821                 else
822                         pData->userData[i].length = segSize;
823
824                 memset(pData->userData[i].data, 0x00, MAX_USER_DATA_LEN+1);
825                 memcpy(pData->userData[i].data, &(decodeData[index]), pData->userData[i].length);
826                 pData->userData[i].data[pData->userData[i].length] = 0;
827
828 MSG_DEBUG("user data len [%d]", pData->userData[i].length);
829 MSG_DEBUG("user data [%s]", pData->userData[i].data);
830
831                 index += segSize;
832
833                 // Set User Data Header for Concatenated Message
834                 if (pData->segCount > 1)
835                 {
836                         pData->userData[i].header[headerCnt].udhType = SMS_UDH_CONCAT_8BIT;
837                         pData->userData[i].header[headerCnt].udh.concat8bit.msgRef = msgRef8bit;
838                         pData->userData[i].header[headerCnt].udh.concat8bit.totalSeg = pData->segCount;
839                         pData->userData[i].header[headerCnt].udh.concat8bit.seqNum = i + 1;
840
841                         headerCnt++;
842                 }
843
844                 // Set User Data Header Port Information
845                 if (pMsgInfo->msgPort.valid == true)
846                 {
847                         pData->userData[i].header[headerCnt].udhType = SMS_UDH_APP_PORT_16BIT;
848                         pData->userData[i].header[headerCnt].udh.appPort16bit.destPort = pMsgInfo->msgPort.dstPort;
849                         pData->userData[i].header[headerCnt].udh.appPort16bit.originPort = pMsgInfo->msgPort.srcPort;
850
851                         headerCnt++;
852                 }
853
854                 // Set User Data Header for Alternate Reply Address
855                 if (strlen(pMsgInfo->replyAddress) > 0)
856                 {
857                         pData->userData[i].header[headerCnt].udhType = SMS_UDH_ALTERNATE_REPLY_ADDRESS;
858
859                         pData->userData[i].header[headerCnt].udh.alternateAddress.ton = SMS_TON_NATIONAL;
860                         pData->userData[i].header[headerCnt].udh.alternateAddress.npi = SMS_NPI_ISDN;
861
862                         memset(pData->userData[i].header[headerCnt].udh.alternateAddress.address, 0x00, MAX_ADDRESS_LEN+1);
863                         memcpy(pData->userData[i].header[headerCnt].udh.alternateAddress.address, pMsgInfo->replyAddress, MAX_ADDRESS_LEN);
864
865                         headerCnt++;
866                 }
867
868                 // Set User Data Header for National Language Single Shift
869                 if (*pCharType == SMS_CHARSET_7BIT && langId != MSG_LANG_ID_RESERVED)
870                 {
871                         pData->userData[i].header[headerCnt].udhType = SMS_UDH_SINGLE_SHIFT;
872                         pData->userData[i].header[headerCnt].udh.singleShift.langId = langId;
873
874                         headerCnt++;
875                 }
876
877                 pData->userData[i].headerCnt = headerCnt;
878         }
879
880         msgRef8bit++;
881 }
882
883
884 int SmsPluginTransport::getSegmentSize(SMS_CODING_SCHEME_T CodingScheme, int DataLen, bool bPortNum, MSG_LANGUAGE_ID_T LangId, int ReplyAddrLen)
885 {
886         int headerLen = 1, concat = 5, port = 6, lang = 3, reply = 2;
887         int headerSize = 0, segSize = 0, maxSize = 0;
888
889         if (CodingScheme == SMS_CHARSET_7BIT)
890         {
891                 MSG_DEBUG("SMS_CHARSET_7BIT");
892                 maxSize = MAX_GSM_7BIT_DATA_LEN;
893         }
894         else if (CodingScheme == SMS_CHARSET_8BIT || CodingScheme == SMS_CHARSET_UCS2)
895         {
896                 MSG_DEBUG("SMS_CHARSET_8BIT or SMS_CHARSET_UCS2 [%d]", CodingScheme);
897                 maxSize = MAX_UCS2_DATA_LEN;
898         }
899
900         if (bPortNum == true)
901         {
902                 MSG_DEBUG("Port Number Exists");
903                 headerSize += port;
904         }
905
906         if (LangId != MSG_LANG_ID_RESERVED)
907         {
908                 MSG_DEBUG("National Language Exists");
909                 headerSize += lang;
910         }
911
912         if (ReplyAddrLen > 0)
913         {
914                 MSG_DEBUG("Reply Address Exists");
915                 headerSize += reply;
916                 headerSize += ReplyAddrLen;
917         }
918
919         if (CodingScheme == SMS_CHARSET_7BIT)
920         {
921                 if (((DataLen+headerSize)/maxSize) >= 1)
922                         segSize = ((140*8) - ((headerLen + concat + headerSize)*8)) / 7;
923                 else
924                         segSize = DataLen;
925         }
926         else if (CodingScheme == SMS_CHARSET_8BIT || CodingScheme == SMS_CHARSET_UCS2)
927         {
928                 if (((DataLen+headerSize)/maxSize) >= 1)
929                         segSize = 140 - (headerLen + concat + headerSize);
930                 else
931                         segSize = DataLen;
932         }
933
934         return segSize;
935 }
936
937
938 void SmsPluginTransport::setConcatHeader(SMS_UDH_S *pSrcHeader, SMS_UDH_S *pDstHeader)
939 {
940         pDstHeader->udhType = pSrcHeader->udhType;
941
942         switch (pDstHeader->udhType)
943         {
944                 case SMS_UDH_CONCAT_8BIT :
945                 {
946                         pDstHeader->udh.concat8bit.msgRef = pSrcHeader->udh.concat8bit.msgRef;
947                         pDstHeader->udh.concat8bit.totalSeg = pSrcHeader->udh.concat8bit.totalSeg;
948                         pDstHeader->udh.concat8bit.seqNum = pSrcHeader->udh.concat8bit.seqNum;
949                 }
950                 break;
951
952                 case SMS_UDH_CONCAT_16BIT :
953                 {
954                         pDstHeader->udh.concat16bit.msgRef = pSrcHeader->udh.concat16bit.msgRef;
955                         pDstHeader->udh.concat16bit.totalSeg = pSrcHeader->udh.concat16bit.totalSeg;
956                         pDstHeader->udh.concat16bit.seqNum = pSrcHeader->udh.concat16bit.seqNum;
957                 }
958                 break;
959         }
960 }
961
962
963 void SmsPluginTransport::setNetStatus(msg_network_status_t netStatus)
964 {
965         mx.lock();
966         curStatus = netStatus;
967         cv.signal();
968         mx.unlock();
969 }
970
971
972 msg_network_status_t SmsPluginTransport::getNetStatus()
973 {
974         mx.lock();
975
976         int ret = 0;
977
978         if (curStatus == MSG_NETWORK_SENDING)
979                 ret = cv.timedwait(mx.pMutex(), 125);
980
981         mx.unlock();
982
983         if (ret == ETIMEDOUT)
984         {
985                 MSG_DEBUG("WARNING: SENT STATUS TIME-OUT");
986                 curStatus = MSG_NETWORK_SEND_TIMEOUT;
987         }
988
989         return curStatus;
990 }
991
992
993 unsigned char SmsPluginTransport::getMsgRef()
994 {
995         return msgRef++;
996 }
997
998
999 SMS_PID_T SmsPluginTransport::convertPid(MSG_SMS_PID_T pid)
1000 {
1001         SMS_PID_T retPid;
1002
1003         switch (pid)
1004         {
1005                 case MSG_PID_TEXT :
1006                         retPid = SMS_PID_NORMAL;
1007                 break;
1008                 case MSG_PID_VOICE :
1009                         retPid = SMS_PID_VOICE;
1010                 break;
1011                 case MSG_PID_FAX :
1012                         retPid = SMS_PID_TELEX;
1013                 break;
1014                 case MSG_PID_X400 :
1015                         retPid = SMS_PID_x400;
1016                 break;
1017                 case MSG_PID_ERMES :
1018                         retPid = SMS_PID_ERMES;
1019                 break;
1020                 case MSG_PID_EMAIL :
1021                         retPid = SMS_PID_EMAIL;
1022                 break;
1023                 default :
1024                         retPid = SMS_PID_NORMAL;
1025                 break;
1026         }
1027
1028         return retPid;
1029 }