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