2 * Copyright (c) 2014 Samsung Electronics Co., Ltd. All rights reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
21 #include "MsgCppTypes.h"
22 #include "MsgException.h"
23 #include "MsgGconfWrapper.h"
24 #include "MsgUtilFile.h"
25 #include "MsgNotificationWrapper.h"
26 #include "MsgUtilStorage.h"
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"
38 #include <ITapiNetText.h>
39 #include <TelNetwork.h>
43 extern bool isMemAvailable;
45 /*==================================================================================================
46 IMPLEMENTATION OF SmsPluginTransport - Member Functions
47 ==================================================================================================*/
48 SmsPluginTransport* SmsPluginTransport::pInstance = NULL;
51 SmsPluginTransport::SmsPluginTransport()
57 memset(&curMoCtrlData, 0x00, sizeof(curMoCtrlData));
61 SmsPluginTransport::~SmsPluginTransport()
66 SmsPluginTransport* SmsPluginTransport::instance()
69 pInstance = new SmsPluginTransport();
75 void SmsPluginTransport::submitRequest(SMS_REQUEST_INFO_S *pReqInfo)
79 SMS_TPDU_S tpdu = {0, };
81 tpdu.tpduType = SMS_TPDU_SUBMIT;
83 /* Get SMS Send Options - Setting */
84 getSmsSendOption(pReqInfo->msgInfo.sim_idx, &(tpdu.data.submit));
86 /* Set SMS Send Options - Each Message */
87 setSmsSendOption(pReqInfo, &tpdu);
89 /* Set coding scheme */
90 setSmsDcsOption(pReqInfo, &tpdu);
92 /* Set SMS report request */
93 setSmsReportOption(pReqInfo, &tpdu);
95 /* Set SMSC Options */
96 SMS_ADDRESS_S smsc = {0, };
97 setSmscOptions(pReqInfo->msgInfo.sim_idx, &smsc);
100 TapiHandle *handle = SmsPluginDSHandler::instance()->getTelHandle(pReqInfo->msgInfo.sim_idx);
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);
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");
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);
121 /* Insert message reference into db */
122 if (tpdu.data.submit.bStatusReport == true) {
123 SmsPluginStorage::instance()->insertMsgRef(&(pReqInfo->msgInfo), tpdu.data.submit.msgRef, i);
126 /* Encode SMSC Address */
127 unsigned char smscAddr[MAX_SMSC_LEN];
128 memset(smscAddr, 0x00, sizeof(smscAddr));
130 int smscLen = SmsPluginParamCodec::encodeSMSC(&smsc, smscAddr);
133 MSG_DEBUG("smscLen <= 0");
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]);
142 MSG_DEBUG("pSCAInfo [%s]", smscAddrTmp);
146 char buf[MAX_TPDU_DATA_LEN];
148 int addLen = strlen(submitData.destAddress.address);
150 tpdu.data.submit.destAddress.ton = submitData.destAddress.ton;
151 tpdu.data.submit.destAddress.npi = submitData.destAddress.npi;
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';
157 if (submitData.destAddress.address[0] == '+')
158 memcpy(tpdu.data.submit.destAddress.address, submitData.destAddress.address, MAX_ADDRESS_LEN);
160 memcpy(tpdu.data.submit.destAddress.address, submitData.destAddress.address, MAX_ADDRESS_LEN-1);
162 tpdu.data.submit.destAddress.address[MAX_ADDRESS_LEN] = '\0';
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);
169 bool bStatusReport = false;
171 for (unsigned int segCnt = 0; segCnt < submitData.segCount; segCnt++) {
172 if (submitData.userData[segCnt].headerCnt > 0) {
173 tpdu.data.submit.bHeaderInd = true;
175 tpdu.data.submit.bHeaderInd = false;
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;
185 memset(&(tpdu.data.submit.userData), 0x00, sizeof(SMS_USERDATA_S));
186 memcpy(&(tpdu.data.submit.userData), &(submitData.userData[segCnt]), sizeof(SMS_USERDATA_S));
188 SMS_NETWORK_STATUS_T retStatus = SMS_NETWORK_SENDING;
190 bool bMoreMsg = false;
192 int retMoCtrlStatus = TAPI_SAT_CALL_CTRL_R_ALLOWED_NO_MOD;
193 bool bRetryByMoCtrl = false;
194 bool bSatMoCtrl = false;
196 for (int cnt = 0; cnt < MAX_SMS_SEND_RETRY; ++cnt) {
197 /* Encode SMS-SUBMIT TPDU */
198 memset(buf, 0x00, sizeof(buf));
201 tpdu.data.submit.bRejectDup = true;
203 bufLen = SmsPluginTpduCodec::encodeTpdu(&tpdu, buf);
205 /* Make Telephony Structure */
206 TelSmsDatapackageInfo_t pkgInfo;
209 memset((void*)pkgInfo.szData, 0x00, sizeof(pkgInfo.szData));
210 memcpy((void*)pkgInfo.szData, buf, bufLen);
212 pkgInfo.szData[bufLen] = 0;
213 pkgInfo.MsgLength = bufLen;
214 pkgInfo.format = TAPI_NETTEXT_NETTYPE_3GPP;
217 memset(pkgInfo.Sca, 0x00, sizeof(pkgInfo.Sca));
218 memcpy((void*)pkgInfo.Sca, smscAddr, smscLen);
219 pkgInfo.Sca[smscLen] = '\0';
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]);
227 MSG_INFO("Submit Request TPDU. try cnt : %d", cnt+1);
228 MSG_INFO("[%s]", pkgInfoTmp);
230 SMS_SENT_INFO_S sentInfo;
231 memset(&sentInfo, 0x00, sizeof(SMS_SENT_INFO_S));
235 memcpy(&(sentInfo.reqInfo), pReqInfo, sizeof(SMS_REQUEST_INFO_S));
237 if ((segCnt + 1) == submitData.segCount && (i + 1) == pReqInfo->msgInfo.nAddressCnt) {
238 sentInfo.bLast = true;
241 sentInfo.bLast = false;
245 SmsPluginEventHandler::instance()->SetSentInfo(&sentInfo);
248 tel_get_property_int(handle, TAPI_PROP_NETWORK_SERVICE_TYPE, &svc_type);
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);
257 curStatus = SMS_NETWORK_SENDING;
260 int tapiRet = TAPI_API_SUCCESS;
262 tapiRet = tel_send_sms(handle, &pkgInfo, bMoreMsg, TapiEventSentStatus, (void *)&curMoCtrlData);
264 if (tapiRet == TAPI_API_SUCCESS) {
265 MSG_DEBUG("######## tel_send_sms Success !!! return : [%d] #######", tapiRet);
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);
273 /* Get SAT MO SM control */
274 retMoCtrlStatus = getMoCtrlStatus();
275 MSG_DEBUG("retMoCtrlStatus = [%d]", retMoCtrlStatus);
277 if (retMoCtrlStatus == TAPI_SAT_CALL_CTRL_R_ALLOWED_WITH_MOD) {
278 if (bRetryByMoCtrl == false) {
279 bRetryByMoCtrl = true;
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);
285 memset(smscAddr, 0x00, sizeof(smscAddr));
286 smscLen = SmsPluginParamCodec::encodeSMSC(&smsc, smscAddr);
288 MSG_SEC_DEBUG("SMSC address=[%s], Encoded length=[%d]", smsc.address, smscLen);
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';
294 memcpy(tpdu.data.submit.destAddress.address, submitData.destAddress.address, MAX_ADDRESS_LEN);
295 tpdu.data.submit.destAddress.address[MAX_ADDRESS_LEN] = '\0';
298 curMoCtrlData.moSmsCtrlResult = TAPI_SAT_CALL_CTRL_R_NOT_ALLOWED;
303 SmsPluginEventHandler::instance()->handleSentStatus(MSG_NETWORK_SEND_FAIL);
309 THROW(MsgException::SMS_PLG_ERROR, "######## tel_send_sms Fail !!! return : [%d] #######", tapiRet);
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, \
318 MSG_SMS_VLD_TXT("%d, [%s]", pReqInfo->msgInfo.msgId, pReqInfo->msgInfo.msgText);
320 retStatus = getNetStatus();
322 if (retStatus != SMS_NETWORK_SEND_FAIL_TEMPORARY && retStatus != SMS_NETWORK_SEND_FAIL_BY_MO_CONTROL_WITH_MOD)
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);
331 /* Adding delivery report status info. */
332 MsgStoAddDeliveryReportStatus(tmpInfo.msgInfo.msgId, (unsigned char)tmpInfo.msgInfo.referenceId);
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");
342 if (retStatus == SMS_NETWORK_SEND_SUCCESS) {
345 if (MsgSettingGetBool(VCONFKEY_SETAPPL_ACCESSIBILITY_TTS, &bTTS) != MSG_SUCCESS) {
346 MSG_DEBUG("MsgSettingGetBool is failed.");
350 if (bMoreMsg == false) {
351 MsgInsertTicker("SMS is sent", SMS_MESSAGE_SENT, false, 0);
353 MSG_DEBUG("######## Msg Sent was Successful !!! #######");
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);
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);
365 MsgInsertTicker("Sending SMS is failed", SMS_MESSAGE_SENDING_FAIL, true, pReqInfo->msgInfo.msgId);
372 THROW(MsgException::SMS_PLG_ERROR, "######## Msg Sent was Failed !!! return : [%d] #######", retStatus);
375 if (tpdu.data.submit.userData.headerCnt > 0)
376 tpdu.data.submit.userData.headerCnt--;
390 void SmsPluginTransport::sendDeliverReport(TapiHandle *handle, msg_error_t err)
396 tpdu.tpduType = SMS_TPDU_DELIVER_REP;
398 TelSmsResponse_t response;
400 int tapiRet = TAPI_API_SUCCESS;
402 int simIndex = SmsPluginDSHandler::instance()->getSimIndex(handle);
404 if (err == MSG_SUCCESS) {
405 tpdu.data.deliverRep.reportType = SMS_REPORT_POSITIVE;
406 response = TAPI_NETTEXT_SENDSMS_SUCCESS;
408 if (isMemAvailable == false) {
409 tapiRet = tel_set_sms_memory_status(handle, TAPI_NETTEXT_PDA_MEMORY_STATUS_AVAILABLE, TapiEventMemoryStatus, NULL);
411 if (tapiRet == TAPI_API_SUCCESS)
412 MSG_DEBUG("######## tel_set_sms_memory_status() Success !!! #######");
414 MSG_DEBUG("######## tel_set_sms_memory_status() Failed !!! return : [%d] #######", tapiRet);
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;
420 response = TAPI_NETTEXT_SIM_FULL;
421 MsgInsertTicker("Sim memory full. Delete some items", SMS_MESSAGE_SIM_MESSAGE_FULL, true, 0);
424 tapiRet = tel_set_sms_memory_status(handle, TAPI_NETTEXT_PDA_MEMORY_STATUS_FULL, TapiEventMemoryStatus, NULL);
426 if (tapiRet == TAPI_API_SUCCESS) {
427 MSG_DEBUG("######## tel_set_sms_memory_status() Success !!! #######");
429 MSG_DEBUG("######## tel_set_sms_memory_status() Failed !!! return : [%d] #######", tapiRet);
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);
439 if (tapiRet == TAPI_API_SUCCESS)
440 MSG_DEBUG("######## tel_set_sms_memory_status() Success !!! #######");
442 MSG_DEBUG("######## tel_set_sms_memory_status() Failed !!! return : [%d] #######", tapiRet);
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;
451 MSG_DEBUG("err : [%d], response : [%02x]", err, response);
453 tpdu.data.deliverRep.bHeaderInd = false;
454 tpdu.data.deliverRep.paramInd = 0x00;
456 /* Encode SMS-DELIVER-REPORT TPDU */
459 char buf[MAX_TPDU_DATA_LEN];
460 memset(buf, 0x00, sizeof(buf));
462 bufLen = SmsPluginTpduCodec::encodeTpdu(&tpdu, buf);
465 /* print DeliverReport tpdu */
466 printf("\n\n######## DeliverReport tpdu #########\n");
467 for (int i=0; i < bufLen; i++) {
468 printf("[%02x] ", buf[i]);
470 printf("\n#################################\n\n");
473 /* Make Telephony Structure */
474 TelSmsDatapackageInfo_t pkgInfo;
477 memset((void*)pkgInfo.szData, 0x00, sizeof(pkgInfo.szData));
478 memcpy((void*)pkgInfo.szData, buf, bufLen);
480 pkgInfo.szData[bufLen] = 0;
481 pkgInfo.MsgLength = bufLen;
482 pkgInfo.format = TAPI_NETTEXT_NETTYPE_3GPP;
484 /* Set SMSC Address */
487 /* Set SMSC Options */
488 setSmscOptions(simIndex, &smsc);
490 /* Encode SMSC Address */
491 unsigned char smscAddr[MAX_SMSC_LEN];
492 memset(smscAddr, 0x00, sizeof(smscAddr));
494 int smscLen = SmsPluginParamCodec::encodeSMSC(&smsc, smscAddr);
496 if (smscLen <= 0) return;
499 memset(pkgInfo.Sca, 0x00, sizeof(pkgInfo.Sca));
500 memcpy((void*)pkgInfo.Sca, smscAddr, smscLen);
501 pkgInfo.Sca[smscLen] = '\0';
503 /* Send Deliver Report */
504 tapiRet = tel_send_sms_deliver_report(handle, &pkgInfo, response, TapiEventDeliveryReportCNF, NULL);
506 if (tapiRet == TAPI_API_SUCCESS)
507 MSG_DEBUG("######## tel_send_sms_deliver_report() Success !!! #######");
509 MSG_DEBUG("######## tel_send_sms_deliver_report() Fail !!! return : [%d] #######", tapiRet);
514 void SmsPluginTransport::sendClass0DeliverReport(TapiHandle *handle, msg_error_t err)
520 tpdu.tpduType = SMS_TPDU_DELIVER_REP;
522 TelSmsResponse_t response;
524 int tapiRet = TAPI_API_SUCCESS;
526 int simIndex = SmsPluginDSHandler::instance()->getSimIndex(handle);
528 if (err == MSG_SUCCESS) {
529 tpdu.data.deliverRep.reportType = SMS_REPORT_POSITIVE;
530 response = TAPI_NETTEXT_SENDSMS_SUCCESS;
532 tapiRet = tel_set_sms_memory_status(handle, TAPI_NETTEXT_PDA_MEMORY_STATUS_AVAILABLE, TapiEventMemoryStatus, NULL);
534 if (tapiRet == TAPI_API_SUCCESS)
535 MSG_DEBUG("######## tel_set_sms_memory_status() Success !!! #######");
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;
542 tapiRet = tel_set_sms_memory_status(handle, TAPI_NETTEXT_PDA_MEMORY_STATUS_FULL, TapiEventMemoryStatus, NULL);
544 if (tapiRet == TAPI_API_SUCCESS)
545 MSG_DEBUG("######## tel_set_sms_memory_status() Success !!! #######");
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;
552 tapiRet = tel_set_sms_memory_status(handle, TAPI_NETTEXT_PDA_MEMORY_STATUS_FULL, TapiEventMemoryStatus, NULL);
554 if (tapiRet == TAPI_API_SUCCESS)
555 MSG_DEBUG("######## tel_set_sms_memory_status() Success !!! #######");
557 MSG_DEBUG("######## tel_set_sms_memory_status() Failed !!! return : [%d] #######", tapiRet);
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;
566 MSG_DEBUG("err : [%d], response : [%02x]", err, response);
568 tpdu.data.deliverRep.bHeaderInd = false;
569 tpdu.data.deliverRep.paramInd = 0x00;
571 /* Encode SMS-DELIVER-REPORT TPDU */
574 char buf[MAX_TPDU_DATA_LEN];
575 memset(buf, 0x00, sizeof(buf));
577 bufLen = SmsPluginTpduCodec::encodeTpdu(&tpdu, buf);
579 /* Make Telephony Structure */
580 TelSmsDatapackageInfo_t pkgInfo;
583 memset((void*)pkgInfo.szData, 0x00, sizeof(pkgInfo.szData));
584 memcpy((void*)pkgInfo.szData, buf, bufLen);
586 pkgInfo.szData[bufLen] = 0;
587 pkgInfo.MsgLength = bufLen;
588 pkgInfo.format = TAPI_NETTEXT_NETTYPE_3GPP;
590 /* Set SMSC Address */
593 /* Set SMSC Options */
594 setSmscOptions(simIndex, &smsc);
596 /* Encode SMSC Address */
597 unsigned char smscAddr[MAX_SMSC_LEN];
598 memset(smscAddr, 0x00, sizeof(smscAddr));
600 int smscLen = SmsPluginParamCodec::encodeSMSC(&smsc, smscAddr);
602 if (smscLen <= 0) return;
605 memset(pkgInfo.Sca, 0x00, sizeof(pkgInfo.Sca));
606 memcpy((void*)pkgInfo.Sca, smscAddr, smscLen);
607 pkgInfo.Sca[smscLen] = '\0';
609 /* Send Deliver Report */
610 tapiRet = tel_send_sms_deliver_report(handle, &pkgInfo, response, TapiEventDeliveryReportCNF, NULL);
612 if (tapiRet == TAPI_API_SUCCESS)
613 MSG_DEBUG("######## tel_send_sms_deliver_report() Success !!! #######");
615 MSG_DEBUG("######## tel_send_sms_deliver_report() Fail !!! return : [%d] #######", tapiRet);
621 void SmsPluginTransport::getSmsSendOption(int simIndex, SMS_SUBMIT_S *pSubmit)
623 /* Set SMS Send Options */
624 pSubmit->bRejectDup = false;
625 pSubmit->bHeaderInd = false;
627 if (MsgSettingGetBool(SMS_SEND_DELIVERY_REPORT, &pSubmit->bStatusReport) != MSG_SUCCESS)
628 MSG_INFO("MsgSettingGetBool() is failed");
630 if (MsgSettingGetBool(SMS_SEND_REPLY_PATH, &pSubmit->bReplyPath) != MSG_SUCCESS)
631 MSG_INFO("MsgSettingGetBool() is failed");
633 pSubmit->msgRef = msgRef++;
635 pSubmit->dcs.bCompressed = false;
636 pSubmit->dcs.msgClass = SMS_MSG_CLASS_NONE;
637 pSubmit->dcs.codingGroup = SMS_GROUP_GENERAL;
639 int codingScheme = 0;
640 if (MsgSettingGetInt(SMS_SEND_DCS, &codingScheme) != MSG_SUCCESS) {
641 MSG_INFO("MsgSettingGetInt() is failed");
643 pSubmit->dcs.codingScheme = (SMS_CODING_SCHEME_T)codingScheme;
644 MSG_DEBUG("DCS : %d", pSubmit->dcs.codingScheme);
646 MSG_SMSC_LIST_S smscList = {0, };
647 SmsPluginSetting::instance()->getSmscListInfo(simIndex, &smscList);
649 int selectIdx = smscList.selected;
652 if (selectIdx < SMSC_LIST_MAX) {
653 MSG_SMS_PID_T pid = smscList.smscData[selectIdx].pid;
654 pSubmit->pid = convertPid(pid);
656 valPeriod = smscList.smscData[selectIdx].valPeriod;
658 MSG_WARN("Invalid case");
659 pSubmit->pid = SMS_PID_NORMAL;
663 MSG_DEBUG("PID : %d", pSubmit->pid);
665 pSubmit->vpf = SMS_VPF_NOT_PRESENT; /* default value */
667 MSG_DEBUG("valPeriod : %d", valPeriod);
668 MSG_DEBUG("vpf : %d", pSubmit->vpf);
672 void SmsPluginTransport::setSmsSendOption(SMS_REQUEST_INFO_S *pReqInfo, SMS_TPDU_S* pSmsTpdu)
674 if (!pReqInfo || !pSmsTpdu) {
675 MSG_DEBUG("Input param is NULL");
679 if (pReqInfo->sendOptInfo.bSetting == true) {
680 pSmsTpdu->data.submit.bStatusReport = pReqInfo->sendOptInfo.bDeliverReq;
681 pSmsTpdu->data.submit.bReplyPath = pReqInfo->sendOptInfo.option.smsSendOptInfo.bReplyPath;
686 void SmsPluginTransport::setSmsDcsOption(SMS_REQUEST_INFO_S *pReqInfo, SMS_TPDU_S* pSmsTpdu)
688 if (!pReqInfo || !pSmsTpdu) {
689 MSG_DEBUG("Input param is NULL");
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);
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);
707 void SmsPluginTransport::setSmsReportOption(SMS_REQUEST_INFO_S *pReqInfo, SMS_TPDU_S* pSmsTpdu)
709 if (!pReqInfo || !pSmsTpdu) {
710 MSG_DEBUG("Input param is NULL");
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);
719 SmsPluginStorage::instance()->updateMsgRef(pReqInfo->msgInfo.msgId, pSmsTpdu->data.submit.msgRef);
723 /* Set Message Reference */
724 if (pSmsTpdu->data.submit.bStatusReport == true) {
725 pSmsTpdu->data.submit.msgRef = (pReqInfo->msgInfo.msgId % 256);
730 void SmsPluginTransport::setSmscOptions(int simIndex, SMS_ADDRESS_S *pSmsc)
732 /* Set SMSC Options */
733 MSG_SMSC_LIST_S smscList = {0, };
734 SmsPluginSetting::instance()->getSmscListInfo(simIndex, &smscList);
736 int selectIdx = smscList.selected;
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);
743 MSG_SEC_DEBUG("address : %s", pSmsc->address);
745 memset(pSmsc->address, 0x00, MAX_ADDRESS_LEN);
748 pSmsc->ton = (SMS_TON_T)smscList.smscData[selectIdx].smscAddr.ton;
749 MSG_DEBUG("ton : %d", pSmsc->ton);
751 pSmsc->npi = (SMS_NPI_T)smscList.smscData[selectIdx].smscAddr.npi;
752 MSG_DEBUG("npi : %d", pSmsc->npi);
757 void SmsPluginTransport::msgInfoToSubmitData(const MSG_MESSAGE_INFO_S *pMsgInfo, SMS_SUBMIT_DATA_S *pData, SMS_CODING_SCHEME_T *pCharType, int addrIndex)
759 /* Destination Address */
760 pData->destAddress.ton = SMS_TON_UNKNOWN;
761 pData->destAddress.npi = SMS_NPI_ISDN;
763 memset(pData->destAddress.address, 0x00, MAX_ADDRESS_LEN+1);
764 memcpy(pData->destAddress.address, pMsgInfo->addressList[addrIndex].addressVal, MAX_ADDRESS_LEN);
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);
770 int decodeLen = 0, bufSize = (MAX_GSM_7BIT_DATA_LEN*MAX_SEGMENT_NUM) + 1; /* SMS_CHARSET_7BIT */
772 unsigned char decodeData[bufSize];
773 memset(decodeData, 0x00, sizeof(decodeData));
775 MsgTextConvert *textCvt = MsgTextConvert::instance();
777 msg_encode_type_t encodeType = MSG_ENCODE_GSM7BIT;
779 MSG_LANGUAGE_ID_T langId = MSG_LANG_ID_RESERVED;
781 bool bAbnormal = false;
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;
799 char* pFileData = NULL;
800 unique_ptr<char*, void(*)(char**)> FileBuf(&pFileData, unique_ptr_deleter);
802 /* Read Message Data from File */
803 if (MsgOpenAndReadFile(pMsgInfo->msgData, &pFileData, &fileSize) == false)
804 THROW(MsgException::FILE_ERROR, "MsgOpenAndReadFile error");
806 MSG_DEBUG("file size : [%d] file data : [%s]", fileSize, pFileData);
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;
821 if (pMsgInfo->nAddressCnt == (addrIndex + 1))
822 MsgDeleteFile(pMsgInfo->msgData);
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);
832 char* encodedAddr = NULL;
833 unique_ptr<char*, void(*)(char**)> addressBuf(&encodedAddr, unique_ptr_deleter);
835 if (strlen(pMsgInfo->replyAddress) > 0) {
836 SMS_ADDRESS_S replyAddr = {};
838 replyAddr.ton = SMS_TON_NATIONAL;
839 replyAddr.npi = SMS_NPI_ISDN;
841 memset(replyAddr.address, 0x00, MAX_ADDRESS_LEN+1);
842 memcpy(replyAddr.address, pMsgInfo->replyAddress, MAX_ADDRESS_LEN);
844 addrLen = SmsPluginParamCodec::encodeAddress(&replyAddr, &encodedAddr);
846 MSG_DEBUG("reply addr length : [%d]", addrLen);
849 int segSize = 0, index = 0;
851 segSize = getSegmentSize(*pCharType, decodeLen, pMsgInfo->msgPort.valid, langId, addrLen);
854 if (decodeLen == 0) /* to handle empty message -> (pMsgInfo->msgText = NULL) */
857 THROW(MsgException::SMS_PLG_ERROR, "DIVIDE_BY_ZERO : %d", segSize);
859 pData->segCount = ceil((double)decodeLen/(double)segSize);
862 MSG_DEBUG("segment size : [%d], pData->segCount : [%d]", segSize, pData->segCount);
864 if (pData->segCount > MAX_SEGMENT_NUM)
865 THROW(MsgException::SMS_PLG_ERROR, "Segment Count is over maximum : %d", pData->segCount);
869 for (unsigned int i = 0; i < pData->segCount; i++) {
872 if ((i + 1) == pData->segCount)
873 pData->userData[i].length = decodeLen - (i*segSize);
875 pData->userData[i].length = segSize;
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;
881 MSG_DEBUG("user data len [%d]", pData->userData[i].length);
882 MSG_DEBUG("user data [%s]", pData->userData[i].data);
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;
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;
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;
909 pData->userData[i].header[headerCnt].udh.alternateAddress.ton = SMS_TON_NATIONAL;
910 pData->userData[i].header[headerCnt].udh.alternateAddress.npi = SMS_NPI_ISDN;
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);
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;
926 pData->userData[i].headerCnt = headerCnt;
933 int SmsPluginTransport::getSegmentSize(SMS_CODING_SCHEME_T CodingScheme, int DataLen, bool bPortNum, MSG_LANGUAGE_ID_T LangId, int ReplyAddrLen)
935 int headerLen = 1, concat = 5, port = 6, lang = 3, reply = 2;
936 int headerSize = 0, segSize = 0, maxSize = 0;
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;
946 if (bPortNum == true) {
947 MSG_DEBUG("Port Number Exists");
951 if (LangId != MSG_LANG_ID_RESERVED) {
952 MSG_DEBUG("National Language Exists");
956 if (ReplyAddrLen > 0) {
957 MSG_DEBUG("Reply Address Exists");
959 headerSize += ReplyAddrLen;
962 if (CodingScheme == SMS_CHARSET_7BIT) {
963 if ((DataLen+headerSize) > maxSize)
964 segSize = ((140*8) - ((headerLen + concat + headerSize)*8)) / 7;
967 } else if (CodingScheme == SMS_CHARSET_8BIT || CodingScheme == SMS_CHARSET_UCS2) {
968 if ((DataLen+headerSize) > maxSize)
969 segSize = 140 - (headerLen + concat + headerSize);
978 void SmsPluginTransport::setConcatHeader(SMS_UDH_S *pSrcHeader, SMS_UDH_S *pDstHeader)
980 pDstHeader->udhType = pSrcHeader->udhType;
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;
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;
1000 void SmsPluginTransport::setNetStatus(SMS_NETWORK_STATUS_T sentStatus)
1003 curStatus = sentStatus;
1009 SMS_NETWORK_STATUS_T SmsPluginTransport::getNetStatus()
1015 if (curStatus == SMS_NETWORK_SENDING)
1016 ret = cv.timedwait(mx.pMsgMutex(), 125);
1020 if (ret == ETIMEDOUT) {
1021 MSG_DEBUG("WARNING: SENT STATUS TIME-OUT");
1022 curStatus = SMS_NETWORK_SEND_FAIL_TIMEOUT;
1029 void SmsPluginTransport::setMoCtrlStatus(TelSatMoSmCtrlIndData_t *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");
1044 int SmsPluginTransport::getMoCtrlStatus()
1050 ret = cv.timedwait(mx.pMsgMutex(), 10);
1054 if (ret == ETIMEDOUT) {
1055 MSG_DEBUG("WARNING: SENT STATUS TIME-OUT");
1059 return (curMoCtrlData.moSmsCtrlResult);
1063 unsigned char SmsPluginTransport::getMsgRef()
1069 SMS_PID_T SmsPluginTransport::convertPid(MSG_SMS_PID_T pid)
1075 retPid = SMS_PID_NORMAL;
1077 case MSG_PID_VOICE :
1078 retPid = SMS_PID_VOICE;
1081 retPid = SMS_PID_TELEX;
1084 retPid = SMS_PID_x400;
1086 case MSG_PID_ERMES :
1087 retPid = SMS_PID_ERMES;
1089 case MSG_PID_EMAIL :
1090 retPid = SMS_PID_EMAIL;
1093 retPid = SMS_PID_NORMAL;