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