2 * Copyright 2012 Samsung Electronics Co., Ltd
4 * Licensed under the Flora License, Version 1.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.tizenopensource.org/license
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 "MsgNotificationWrapper.h"
25 #include "MsgUtilFile.h"
26 #include "SmsPluginParamCodec.h"
27 #include "SmsPluginTpduCodec.h"
28 #include "SmsPluginEventHandler.h"
29 #include "SmsPluginStorage.h"
30 #include "SmsPluginCallback.h"
31 #include "SmsPluginTransport.h"
35 #include <ITapiNetText.h>
38 #define MSG_DEBUG_BY_FILE
40 extern struct tapi_handle *pTapiHandle;
42 /*==================================================================================================
43 IMPLEMENTATION OF SmsPluginTransport - Member Functions
44 ==================================================================================================*/
45 SmsPluginTransport* SmsPluginTransport::pInstance = NULL;
48 SmsPluginTransport::SmsPluginTransport()
56 SmsPluginTransport::~SmsPluginTransport()
62 SmsPluginTransport* SmsPluginTransport::instance()
65 pInstance = new SmsPluginTransport();
71 void SmsPluginTransport::submitRequest(SMS_REQUEST_INFO_S *pReqInfo)
77 tpdu.tpduType = SMS_TPDU_SUBMIT;
79 // Set SMS Send Options - Setting
80 setSmsSendOptions(&(tpdu.data.submit));
82 // Set SMS Send Options - Each Message
83 if (pReqInfo->sendOptInfo.bSetting == true)
85 tpdu.data.submit.bStatusReport = pReqInfo->sendOptInfo.bDeliverReq;
86 tpdu.data.submit.bReplyPath = pReqInfo->sendOptInfo.option.smsSendOptInfo.bReplyPath;
89 // Set Coding Scheme for apps that use port number
90 if (pReqInfo->msgInfo.msgPort.valid == true)
92 tpdu.data.submit.dcs.codingScheme = (SMS_CODING_SCHEME_T)pReqInfo->msgInfo.encodeType;
94 MSG_DEBUG("DCS is changed by application : [%d]", tpdu.data.submit.dcs.codingScheme);
99 setSmscOptions(&smsc);
103 MSG_DEBUG("pReqInfo->msgInfo.nAddressCnt [%d]", pReqInfo->msgInfo.nAddressCnt);
105 for (i = 0; i < pReqInfo->msgInfo.nAddressCnt; i++)
107 // Make SMS_SUBMIT_DATA_S from MSG_REQUEST_INFO_S
108 SMS_SUBMIT_DATA_S submitData = {{0},};
109 msgInfoToSubmitData(&(pReqInfo->msgInfo), &submitData, &(tpdu.data.submit.dcs.codingScheme), i);
111 // Encode SMSC Address
112 unsigned char smscAddr[MAX_SMSC_LEN];
113 memset(smscAddr, 0x00, sizeof(smscAddr));
115 int smscLen = SmsPluginParamCodec::encodeSMSC(&smsc, smscAddr);
117 if (smscLen <= 0) return;
119 for (j = 0; j < smscLen; j++)
121 MSG_DEBUG("pSCAInfo [%02x]", smscAddr[j]);
126 char buf[MAX_TPDU_DATA_LEN];
128 int addLen = strlen(submitData.destAddress.address);
130 tpdu.data.submit.destAddress.ton = submitData.destAddress.ton;
131 tpdu.data.submit.destAddress.npi = submitData.destAddress.npi;
133 if (addLen < MAX_ADDRESS_LEN) {
134 memcpy(tpdu.data.submit.destAddress.address, submitData.destAddress.address, addLen);
135 tpdu.data.submit.destAddress.address[addLen] = '\0';
137 memcpy(tpdu.data.submit.destAddress.address, submitData.destAddress.address, MAX_ADDRESS_LEN);
138 tpdu.data.submit.destAddress.address[MAX_ADDRESS_LEN] = '\0';
142 MSG_DEBUG("ton [%d]", tpdu.data.submit.destAddress.ton);
143 MSG_DEBUG("npi [%d]", tpdu.data.submit.destAddress.npi);
144 MSG_DEBUG("address [%s]", tpdu.data.submit.destAddress.address);
147 bool bStatusReport = false;
149 for (unsigned int segCnt = 0; segCnt < submitData.segCount; segCnt++)
151 if (submitData.userData[segCnt].headerCnt > 0) {
152 tpdu.data.submit.bHeaderInd = true;
154 tpdu.data.submit.bHeaderInd = false;
157 if (segCnt == 0 && submitData.segCount > 1) {
158 bStatusReport = tpdu.data.submit.bStatusReport;
159 tpdu.data.submit.bStatusReport = false;
160 } else if ((segCnt+1 == submitData.segCount) && submitData.segCount > 1) {
161 tpdu.data.submit.bStatusReport = bStatusReport;
164 memset(&(tpdu.data.submit.userData), 0x00, sizeof(SMS_USERDATA_S));
165 memcpy(&(tpdu.data.submit.userData), &(submitData.userData[segCnt]), sizeof(SMS_USERDATA_S));
167 // Encode SMS-SUBMIT TPDU
168 memset(buf, 0x00, sizeof(buf));
170 bufLen = SmsPluginTpduCodec::encodeTpdu(&tpdu, buf);
172 // Make Telephony Structure
173 TelSmsDatapackageInfo_t pkgInfo;
176 memset((void*)pkgInfo.szData, 0x00, sizeof(pkgInfo.szData));
177 memcpy((void*)pkgInfo.szData, buf, bufLen);
179 pkgInfo.szData[bufLen] = 0;
180 pkgInfo.MsgLength = bufLen;
183 memset(pkgInfo.Sca, 0x00, sizeof(pkgInfo.Sca));
184 memcpy((void*)pkgInfo.Sca, smscAddr, smscLen);
185 pkgInfo.Sca[smscLen] = '\0';
188 MSG_DEBUG("[submitRequest] TPDU.");
190 for (j = 0; j < pkgInfo.MsgLength; j++)
192 MSG_DEBUG("[%02x]", pkgInfo.szData[j]);
195 for (j = 0; j < smscLen; j++)
197 MSG_DEBUG("pkgInfo.pSCA [%02x]", pkgInfo.Sca[j]);
201 #ifdef MSG_DEBUG_BY_FILE
204 memset(temp, 0x00, sizeof(temp));
205 memset(tempcat, 0x00, sizeof(tempcat));
210 snprintf(temp, sizeof(temp), "[MO] %s", ctime(&rawtime));
212 for (j = 0; j < pkgInfo.MsgLength; j++)
214 snprintf(tempcat, sizeof(tempcat), "[%02x]\n", pkgInfo.szData[j]);
215 strncat(temp, tempcat, sizeof(temp)-strlen(temp)-1);
216 memset(tempcat, 0x00, sizeof(tempcat));
220 snprintf(tempcat, sizeof(tempcat), "\n\n\n");
221 strncat(temp, tempcat, sizeof(temp)-strlen(temp)-1);
223 //MSG_DEBUG("temp [%s], length [%d]", temp, strlen(temp));
225 //MsgOpenCreateAndOverwriteFile(TPDU_LOG_FILE, temp, strlen(temp));
227 pFile = MsgOpenFile(TPDU_LOG_FILE, "a");
228 MsgWriteFile(temp, sizeof(char), strlen(temp), pFile);
235 SMS_SENT_INFO_S sentInfo = {};
237 bool bMoreMsg = FALSE;
239 memcpy(&(sentInfo.reqInfo), pReqInfo, sizeof(SMS_REQUEST_INFO_S));
241 if ((segCnt+1) == submitData.segCount && (i+1)==pReqInfo->msgInfo.nAddressCnt)
243 sentInfo.bLast = true;
249 sentInfo.bLast = false;
254 SmsPluginEventHandler::instance()->SetSentInfo(&sentInfo);
256 curStatus = MSG_NETWORK_SENDING;
259 int tapiRet = TAPI_API_SUCCESS;
261 tapiRet = tel_send_sms(pTapiHandle, &pkgInfo, bMoreMsg, TapiEventSentStatus, NULL);
263 if (tapiRet == TAPI_API_SUCCESS)
265 MSG_DEBUG("######## TelTapiSmsSend Success !!! return : [%d] #######", tapiRet);
269 SmsPluginEventHandler::instance()->handleSentStatus(MSG_NETWORK_SEND_FAIL);
271 THROW(MsgException::SMS_PLG_ERROR, "######## TelTapiSmsSend Fail !!! return : [%d] #######", tapiRet);
274 // Tizen Validation System
276 msisdn = MsgSettingGetString(MSG_SIM_MSISDN);
278 MSG_SMS_VLD_INFO("%d, SMS Send Start, %s->%s, %s", pReqInfo->msgInfo.msgId, \
279 (msisdn == NULL)?"ME":msisdn, \
280 pReqInfo->msgInfo.addressList[0].addressVal, \
281 (tapiRet == TAPI_API_SUCCESS)?"Success":"Fail");
283 MSG_SMS_VLD_TXT("%d, [%s]", pReqInfo->msgInfo.msgId, pReqInfo->msgInfo.msgText);
285 msg_network_status_t retStatus = getNetStatus();
287 #ifdef MSG_SMS_REPORT
288 if (err == MSG_SUCCESS && tmpInfo.msgInfo.msgPort.valid == false)
290 if(pReqInfo->sendOptInfo.bDeliverReq == true)
292 MSG_DEBUG("Update Delivery Report Status : [%d] Msg ID : [%d]", err, tmpInfo.msgInfo.msgId);
294 // Adding delivery report status info.
295 MsgStoAddDeliveryReportStatus( tmpInfo.msgInfo.msgId, (unsigned char)tmpInfo.msgInfo.referenceId);
300 MSG_SMS_VLD_INFO("%d, SMS Send End, %s->%s, %s", pReqInfo->msgInfo.msgId, \
301 (msisdn == NULL)?"ME":msisdn, \
302 pReqInfo->msgInfo.addressList[0].addressVal, \
303 (retStatus == MSG_NETWORK_SEND_SUCCESS)?"Success":"Fail");
306 if (retStatus == MSG_NETWORK_SEND_SUCCESS)
308 if (bMoreMsg == false) {
309 MsgInsertTicker("SMS is sent", SMS_MESSAGE_SENT);
311 MSG_DEBUG("######## Msg Sent was Successful !!! return : [%d] #######", retStatus);
315 MsgInsertTicker("Sending SMS is failed", NULL);
316 MsgInsertTicker("Sending SMS is failed", SMS_MESSAGE_SENDING_FAIL);
318 SmsPluginEventHandler::instance()->handleSentStatus(MSG_NETWORK_SEND_FAIL);
320 THROW(MsgException::SMS_PLG_ERROR, "######## Msg Sent was Failed !!! return : [%d] #######", retStatus);
323 if (tpdu.data.submit.userData.headerCnt > 0) tpdu.data.submit.userData.headerCnt--;
331 void SmsPluginTransport::sendDeliverReport(msg_error_t err)
337 tpdu.tpduType = SMS_TPDU_DELIVER_REP;
339 TelSmsResponse_t response;
341 int tapiRet = TAPI_API_SUCCESS;
343 if (err == MSG_SUCCESS)
345 tpdu.data.deliverRep.reportType = SMS_REPORT_POSITIVE;
346 response = TAPI_NETTEXT_SENDSMS_SUCCESS;
348 tapiRet = tel_set_sms_memory_status(pTapiHandle, TAPI_NETTEXT_PDA_MEMORY_STATUS_AVAILABLE, TapiEventMemoryStatus, NULL);
350 if (tapiRet == TAPI_API_SUCCESS)
352 MSG_DEBUG("######## tel_set_sms_memory_status() Success !!! #######");
356 MSG_DEBUG("######## tel_set_sms_memory_status() Failed !!! return : [%d] #######", tapiRet);
359 else if (err == MSG_ERR_SIM_STORAGE_FULL)
361 tpdu.data.deliverRep.reportType = SMS_REPORT_NEGATIVE;
362 tpdu.data.deliverRep.failCause = SMS_FC_MSG_CAPA_EXCEEDED;
363 response = TAPI_NETTEXT_SIM_FULL;
365 tapiRet = tel_set_sms_memory_status(pTapiHandle, TAPI_NETTEXT_PDA_MEMORY_STATUS_FULL, TapiEventMemoryStatus, NULL);
367 if (tapiRet == TAPI_API_SUCCESS)
369 MSG_DEBUG("######## tel_set_sms_memory_status() Success !!! #######");
373 MSG_DEBUG("######## tel_set_sms_memory_status() Failed !!! return : [%d] #######", tapiRet);
376 else if (err == MSG_ERR_MESSAGE_COUNT_FULL)
378 tpdu.data.deliverRep.reportType = SMS_REPORT_NEGATIVE;
379 tpdu.data.deliverRep.failCause = SMS_FC_MSG_CAPA_EXCEEDED;
380 response = TAPI_NETTEXT_ME_FULL;
382 tapiRet = tel_set_sms_memory_status(pTapiHandle, TAPI_NETTEXT_PDA_MEMORY_STATUS_FULL, TapiEventMemoryStatus, NULL);
384 if (tapiRet == TAPI_API_SUCCESS)
386 MSG_DEBUG("######## tel_set_sms_memory_status() Success !!! #######");
390 MSG_DEBUG("######## tel_set_sms_memory_status() Failed !!! return : [%d] #######", tapiRet);
395 tpdu.data.deliverRep.reportType = SMS_REPORT_NEGATIVE;
396 tpdu.data.deliverRep.failCause = SMS_FC_UNSPEC_ERROR;
397 //response = TAPI_NETTEXT_PROTOCOL_ERROR;
398 // For gcf test [34.2.5.3 class2 message]
399 response = TAPI_NETTEXT_SIM_FULL;
403 MSG_DEBUG("err : [%d], response : [%02x]", err, response);
405 tpdu.data.deliverRep.bHeaderInd = false;
406 tpdu.data.deliverRep.paramInd = 0x00;
408 // Encode SMS-DELIVER-REPORT TPDU
411 char buf[MAX_TPDU_DATA_LEN];
412 memset(buf, 0x00, sizeof(buf));
414 bufLen = SmsPluginTpduCodec::encodeTpdu(&tpdu, buf);
417 /////// print DeliverReport tpdu
418 printf("\n\n######## DeliverReport tpdu #########\n");
419 for(int i=0; i < bufLen; i++)
421 printf("[%02x] ", buf[i]);
423 printf("\n#################################\n\n");
427 // Make Telephony Structure
428 TelSmsDatapackageInfo_t pkgInfo;
431 memset((void*)pkgInfo.szData, 0x00, sizeof(pkgInfo.szData));
432 memcpy((void*)pkgInfo.szData, buf, bufLen);
434 pkgInfo.szData[bufLen] = 0;
435 pkgInfo.MsgLength = bufLen;
441 setSmscOptions(&smsc);
443 // Encode SMSC Address
444 unsigned char smscAddr[MAX_SMSC_LEN];
445 memset(smscAddr, 0x00, sizeof(smscAddr));
447 int smscLen = SmsPluginParamCodec::encodeSMSC(&smsc, smscAddr);
449 if (smscLen <= 0) return;
452 memset(pkgInfo.Sca, 0x00, sizeof(pkgInfo.Sca));
453 memcpy((void*)pkgInfo.Sca, smscAddr, smscLen);
454 pkgInfo.Sca[smscLen] = '\0';
456 // Send Deliver Report
457 tapiRet = tel_send_sms_deliver_report(pTapiHandle, &pkgInfo, response, TapiEventDeliveryReportCNF, NULL);
459 if (tapiRet == TAPI_API_SUCCESS)
461 MSG_DEBUG("######## tel_send_sms_deliver_report() Success !!! #######");
465 MSG_DEBUG("######## tel_send_sms_deliver_report() Fail !!! return : [%d] #######", tapiRet);
471 void SmsPluginTransport::sendClass0DeliverReport(msg_error_t err)
477 tpdu.tpduType = SMS_TPDU_DELIVER_REP;
479 TelSmsResponse_t response;
481 int tapiRet = TAPI_API_SUCCESS;
483 if (err == MSG_SUCCESS)
485 tpdu.data.deliverRep.reportType = SMS_REPORT_POSITIVE;
486 response = TAPI_NETTEXT_SENDSMS_SUCCESS;
488 tapiRet = tel_set_sms_memory_status(pTapiHandle, TAPI_NETTEXT_PDA_MEMORY_STATUS_AVAILABLE, TapiEventMemoryStatus, NULL);
490 if (tapiRet == TAPI_API_SUCCESS)
492 MSG_DEBUG("######## tel_set_sms_memory_status() Success !!! #######");
496 MSG_DEBUG("######## tel_set_sms_memory_status() Failed !!! return : [%d] #######", tapiRet);
499 else if (err == MSG_ERR_SIM_STORAGE_FULL)
501 tpdu.data.deliverRep.reportType = SMS_REPORT_POSITIVE;
502 response = TAPI_NETTEXT_SENDSMS_SUCCESS;
504 tapiRet = tel_set_sms_memory_status(pTapiHandle, TAPI_NETTEXT_PDA_MEMORY_STATUS_FULL, TapiEventMemoryStatus, NULL);
506 if (tapiRet == TAPI_API_SUCCESS)
508 MSG_DEBUG("######## tel_set_sms_memory_status() Success !!! #######");
512 MSG_DEBUG("######## tel_set_sms_memory_status() Failed !!! return : [%d] #######", tapiRet);
515 else if (err == MSG_ERR_MESSAGE_COUNT_FULL)
517 tpdu.data.deliverRep.reportType = SMS_REPORT_POSITIVE;
518 response = TAPI_NETTEXT_SENDSMS_SUCCESS;
520 tapiRet = tel_set_sms_memory_status(pTapiHandle, TAPI_NETTEXT_PDA_MEMORY_STATUS_FULL, TapiEventMemoryStatus, NULL);
522 if (tapiRet == TAPI_API_SUCCESS)
524 MSG_DEBUG("######## tel_set_sms_memory_status() Success !!! #######");
528 MSG_DEBUG("######## tel_set_sms_memory_status() Failed !!! return : [%d] #######", tapiRet);
533 tpdu.data.deliverRep.reportType = SMS_REPORT_NEGATIVE;
534 tpdu.data.deliverRep.failCause = SMS_FC_UNSPEC_ERROR;
535 //response = TAPI_NETTEXT_PROTOCOL_ERROR;
536 // For gcf test [34.2.5.3 class2 message]
537 response = TAPI_NETTEXT_SIM_FULL;
541 MSG_DEBUG("err : [%d], response : [%02x]", err, response);
543 tpdu.data.deliverRep.bHeaderInd = false;
544 tpdu.data.deliverRep.paramInd = 0x00;
546 // Encode SMS-DELIVER-REPORT TPDU
549 char buf[MAX_TPDU_DATA_LEN];
550 memset(buf, 0x00, sizeof(buf));
552 bufLen = SmsPluginTpduCodec::encodeTpdu(&tpdu, buf);
554 // Make Telephony Structure
555 TelSmsDatapackageInfo_t pkgInfo;
558 memset((void*)pkgInfo.szData, 0x00, sizeof(pkgInfo.szData));
559 memcpy((void*)pkgInfo.szData, buf, bufLen);
561 pkgInfo.szData[bufLen] = 0;
562 pkgInfo.MsgLength = bufLen;
568 setSmscOptions(&smsc);
570 // Encode SMSC Address
571 unsigned char smscAddr[MAX_SMSC_LEN];
572 memset(smscAddr, 0x00, sizeof(smscAddr));
574 int smscLen = SmsPluginParamCodec::encodeSMSC(&smsc, smscAddr);
576 if (smscLen <= 0) return;
579 memset(pkgInfo.Sca, 0x00, sizeof(pkgInfo.Sca));
580 memcpy((void*)pkgInfo.Sca, smscAddr, smscLen);
581 pkgInfo.Sca[smscLen] = '\0';
583 // Send Deliver Report
584 tapiRet = tel_send_sms_deliver_report(pTapiHandle, &pkgInfo, response, TapiEventDeliveryReportCNF, NULL);
586 if (tapiRet == TAPI_API_SUCCESS)
588 MSG_DEBUG("######## tel_send_sms_deliver_report() Success !!! #######");
592 MSG_DEBUG("######## tel_send_sms_deliver_report() Fail !!! return : [%d] #######", tapiRet);
600 void SmsPluginTransport::setSmsSendOptions(SMS_SUBMIT_S *pSubmit)
602 // Set SMS Send Options
603 pSubmit->bRejectDup = false;
604 pSubmit->bHeaderInd = false;
606 MsgSettingGetBool(SMS_SEND_DELIVERY_REPORT, &pSubmit->bStatusReport);
607 MsgSettingGetBool(SMS_SEND_REPLY_PATH, &pSubmit->bReplyPath);
609 pSubmit->msgRef = msgRef++;
611 pSubmit->dcs.bCompressed = false;
612 pSubmit->dcs.msgClass = SMS_MSG_CLASS_NONE;
613 pSubmit->dcs.codingGroup = SMS_GROUP_GENERAL;
615 pSubmit->dcs.codingScheme = (SMS_CODING_SCHEME_T)MsgSettingGetInt(SMS_SEND_DCS);
617 MSG_DEBUG("DCS : %d", pSubmit->dcs.codingScheme);
619 int selectIdx = MsgSettingGetInt(SMSC_SELECTED);
623 memset(keyName, 0x00, sizeof(keyName));
624 sprintf(keyName, "%s/%d", SMSC_PID, selectIdx);
625 MSG_SMS_PID_T pid = (MSG_SMS_PID_T)MsgSettingGetInt(keyName);
627 pSubmit->pid = convertPid(pid);
628 MSG_DEBUG("PID : %d", pSubmit->pid);
630 memset(keyName, 0x00, sizeof(keyName));
631 sprintf(keyName, "%s/%d", SMSC_VAL_PERIOD, selectIdx);
632 int valPeriod = MsgSettingGetInt(keyName);
634 MSG_DEBUG("valPeriod : %d", valPeriod);
638 pSubmit->vpf = SMS_VPF_NOT_PRESENT;
642 pSubmit->vpf = SMS_VPF_RELATIVE;
643 pSubmit->validityPeriod.format = SMS_TIME_RELATIVE;
644 pSubmit->validityPeriod.time.relative.time = valPeriod;
649 void SmsPluginTransport::setSmscOptions(SMS_ADDRESS_S *pSmsc)
652 int selectIdx = MsgSettingGetInt(SMSC_SELECTED);
656 memset(keyName, 0x00, sizeof(keyName));
657 sprintf(keyName, "%s/%d", SMSC_ADDRESS, selectIdx);
659 char* tmpValue = NULL;
661 tmpValue = MsgSettingGetString(keyName);
663 if (tmpValue != NULL)
665 memset(pSmsc->address, 0x00, sizeof(pSmsc->address));
666 strncpy(pSmsc->address, tmpValue, MAX_ADDRESS_LEN);
668 MSG_DEBUG("address : %s", pSmsc->address);
672 strncpy(pSmsc->address, "+8210911111", MAX_ADDRESS_LEN);
675 memset(keyName, 0x00, sizeof(keyName));
676 sprintf(keyName, "%s/%d", SMSC_TON, selectIdx);
677 pSmsc->ton = (SMS_TON_T)MsgSettingGetInt(keyName);
679 MSG_DEBUG("ton : %d", pSmsc->ton);
681 memset(keyName, 0x00, sizeof(keyName));
682 sprintf(keyName, "%s/%d", SMSC_NPI, selectIdx);
683 pSmsc->npi = (SMS_NPI_T)MsgSettingGetInt(keyName);
685 MSG_DEBUG("npi : %d", pSmsc->npi);
687 if (tmpValue != NULL)
695 void SmsPluginTransport::msgInfoToSubmitData(const MSG_MESSAGE_INFO_S *pMsgInfo, SMS_SUBMIT_DATA_S *pData, SMS_CODING_SCHEME_T *pCharType, int addrIndex)
697 // Destination Address
698 pData->destAddress.ton = SMS_TON_UNKNOWN;
699 pData->destAddress.npi = SMS_NPI_ISDN;
701 memset(pData->destAddress.address, 0x00, MAX_ADDRESS_LEN+1);
702 memcpy(pData->destAddress.address, pMsgInfo->addressList[addrIndex].addressVal, MAX_ADDRESS_LEN);
704 MSG_DEBUG("ton [%d]", pData->destAddress.ton);
705 MSG_DEBUG("npi [%d]", pData->destAddress.npi);
706 MSG_DEBUG("address [%s]", pData->destAddress.address);
708 int decodeLen = 0, bufSize = (MAX_GSM_7BIT_DATA_LEN*MAX_SEGMENT_NUM) + 1; // SMS_CHARSET_7BIT
710 unsigned char decodeData[bufSize];
711 memset(decodeData, 0x00, sizeof(decodeData));
713 msg_encode_type_t encodeType = MSG_ENCODE_GSM7BIT;
715 MSG_LANGUAGE_ID_T langId = MSG_LANG_ID_RESERVED;
717 bool bAbnormal = false;
720 if (pMsgInfo->bTextSms == true)
722 if (*pCharType == SMS_CHARSET_7BIT)
724 decodeLen = textCvt.convertUTF8ToGSM7bit(decodeData, bufSize, (unsigned char*)pMsgInfo->msgText, (int)pMsgInfo->dataSize, &langId, &bAbnormal);
726 else if (*pCharType == SMS_CHARSET_8BIT)
728 memcpy(decodeData, pMsgInfo->msgText, pMsgInfo->dataSize);
729 decodeLen = pMsgInfo->dataSize;
731 else if (*pCharType == SMS_CHARSET_UCS2)
733 decodeLen = textCvt.convertUTF8ToUCS2(decodeData, bufSize, (unsigned char*)pMsgInfo->msgText, (int)pMsgInfo->dataSize);
735 else if (*pCharType == SMS_CHARSET_AUTO)
737 decodeLen = textCvt.convertUTF8ToAuto(decodeData, bufSize, (unsigned char*)pMsgInfo->msgText, (int)pMsgInfo->dataSize, &encodeType);
738 *pCharType = encodeType;
745 char* pFileData = NULL;
746 AutoPtr<char> FileBuf(&pFileData);
748 // Read Message Data from File
749 if (MsgOpenAndReadFile(pMsgInfo->msgData, &pFileData, &fileSize) == false)
750 THROW(MsgException::FILE_ERROR, "MsgOpenAndReadFile error");
752 MSG_DEBUG("file size : [%d] file data : [%s]", fileSize, pFileData);
754 if (*pCharType == SMS_CHARSET_7BIT)
756 decodeLen = textCvt.convertUTF8ToGSM7bit(decodeData, bufSize, (unsigned char*)pFileData, fileSize, &langId, &bAbnormal);
758 else if (*pCharType == SMS_CHARSET_8BIT)
760 memcpy(decodeData, pFileData, fileSize);
761 decodeLen = fileSize;
763 else if (*pCharType == SMS_CHARSET_UCS2)
765 decodeLen = textCvt.convertUTF8ToUCS2(decodeData, bufSize, (unsigned char*)pFileData, fileSize);
767 else if (*pCharType == SMS_CHARSET_AUTO)
769 decodeLen = textCvt.convertUTF8ToAuto(decodeData, bufSize, (unsigned char*)pFileData, fileSize, &encodeType);
770 *pCharType = encodeType;
774 MsgDeleteFile(pMsgInfo->msgData);
777 MSG_DEBUG("decode length : [%d]", decodeLen);
778 MSG_DEBUG("character type : [%d]", *pCharType);
779 MSG_DEBUG("Language Identifier : [%d]", langId);
780 MSG_DEBUG("reply address : [%s]", pMsgInfo->replyAddress);
784 char* encodedAddr = NULL;
785 AutoPtr<char> addressBuf(&encodedAddr);
787 if (strlen(pMsgInfo->replyAddress) > 0)
789 SMS_ADDRESS_S replyAddr = {};
791 replyAddr.ton = SMS_TON_NATIONAL;
792 replyAddr.npi = SMS_NPI_ISDN;
794 memset(replyAddr.address, 0x00, MAX_ADDRESS_LEN+1);
795 memcpy(replyAddr.address, pMsgInfo->replyAddress, MAX_ADDRESS_LEN);
797 addrLen = SmsPluginParamCodec::encodeAddress(&replyAddr, &encodedAddr);
799 MSG_DEBUG("reply addr length : [%d]", addrLen);
802 int segSize = 0, index = 0;
804 segSize = getSegmentSize(*pCharType, decodeLen, pMsgInfo->msgPort.valid, langId, addrLen);
806 pData->segCount = ceil((double)decodeLen/(double)segSize);
808 MSG_DEBUG("segment size : [%d], pData->segCount : [%d]", segSize, pData->segCount);
810 if (pData->segCount > MAX_SEGMENT_NUM)
811 THROW(MsgException::SMS_PLG_ERROR, "Segment Count is over maximum : %d", pData->segCount);
815 for (unsigned int i = 0; i < pData->segCount; i++)
819 if ((i + 1) == pData->segCount)
820 pData->userData[i].length = decodeLen - (i*segSize);
822 pData->userData[i].length = segSize;
824 memset(pData->userData[i].data, 0x00, MAX_USER_DATA_LEN+1);
825 memcpy(pData->userData[i].data, &(decodeData[index]), pData->userData[i].length);
826 pData->userData[i].data[pData->userData[i].length] = 0;
828 MSG_DEBUG("user data len [%d]", pData->userData[i].length);
829 MSG_DEBUG("user data [%s]", pData->userData[i].data);
833 // Set User Data Header for Concatenated Message
834 if (pData->segCount > 1)
836 pData->userData[i].header[headerCnt].udhType = SMS_UDH_CONCAT_8BIT;
837 pData->userData[i].header[headerCnt].udh.concat8bit.msgRef = msgRef8bit;
838 pData->userData[i].header[headerCnt].udh.concat8bit.totalSeg = pData->segCount;
839 pData->userData[i].header[headerCnt].udh.concat8bit.seqNum = i + 1;
844 // Set User Data Header Port Information
845 if (pMsgInfo->msgPort.valid == true)
847 pData->userData[i].header[headerCnt].udhType = SMS_UDH_APP_PORT_16BIT;
848 pData->userData[i].header[headerCnt].udh.appPort16bit.destPort = pMsgInfo->msgPort.dstPort;
849 pData->userData[i].header[headerCnt].udh.appPort16bit.originPort = pMsgInfo->msgPort.srcPort;
854 // Set User Data Header for Alternate Reply Address
855 if (strlen(pMsgInfo->replyAddress) > 0)
857 pData->userData[i].header[headerCnt].udhType = SMS_UDH_ALTERNATE_REPLY_ADDRESS;
859 pData->userData[i].header[headerCnt].udh.alternateAddress.ton = SMS_TON_NATIONAL;
860 pData->userData[i].header[headerCnt].udh.alternateAddress.npi = SMS_NPI_ISDN;
862 memset(pData->userData[i].header[headerCnt].udh.alternateAddress.address, 0x00, MAX_ADDRESS_LEN+1);
863 memcpy(pData->userData[i].header[headerCnt].udh.alternateAddress.address, pMsgInfo->replyAddress, MAX_ADDRESS_LEN);
868 // Set User Data Header for National Language Single Shift
869 if (*pCharType == SMS_CHARSET_7BIT && langId != MSG_LANG_ID_RESERVED)
871 pData->userData[i].header[headerCnt].udhType = SMS_UDH_SINGLE_SHIFT;
872 pData->userData[i].header[headerCnt].udh.singleShift.langId = langId;
877 pData->userData[i].headerCnt = headerCnt;
884 int SmsPluginTransport::getSegmentSize(SMS_CODING_SCHEME_T CodingScheme, int DataLen, bool bPortNum, MSG_LANGUAGE_ID_T LangId, int ReplyAddrLen)
886 int headerLen = 1, concat = 5, port = 6, lang = 3, reply = 2;
887 int headerSize = 0, segSize = 0, maxSize = 0;
889 if (CodingScheme == SMS_CHARSET_7BIT)
891 MSG_DEBUG("SMS_CHARSET_7BIT");
892 maxSize = MAX_GSM_7BIT_DATA_LEN;
894 else if (CodingScheme == SMS_CHARSET_8BIT || CodingScheme == SMS_CHARSET_UCS2)
896 MSG_DEBUG("SMS_CHARSET_8BIT or SMS_CHARSET_UCS2 [%d]", CodingScheme);
897 maxSize = MAX_UCS2_DATA_LEN;
900 if (bPortNum == true)
902 MSG_DEBUG("Port Number Exists");
906 if (LangId != MSG_LANG_ID_RESERVED)
908 MSG_DEBUG("National Language Exists");
912 if (ReplyAddrLen > 0)
914 MSG_DEBUG("Reply Address Exists");
916 headerSize += ReplyAddrLen;
919 if (CodingScheme == SMS_CHARSET_7BIT)
921 if (((DataLen+headerSize)/maxSize) >= 1)
922 segSize = ((140*8) - ((headerLen + concat + headerSize)*8)) / 7;
926 else if (CodingScheme == SMS_CHARSET_8BIT || CodingScheme == SMS_CHARSET_UCS2)
928 if (((DataLen+headerSize)/maxSize) >= 1)
929 segSize = 140 - (headerLen + concat + headerSize);
938 void SmsPluginTransport::setConcatHeader(SMS_UDH_S *pSrcHeader, SMS_UDH_S *pDstHeader)
940 pDstHeader->udhType = pSrcHeader->udhType;
942 switch (pDstHeader->udhType)
944 case SMS_UDH_CONCAT_8BIT :
946 pDstHeader->udh.concat8bit.msgRef = pSrcHeader->udh.concat8bit.msgRef;
947 pDstHeader->udh.concat8bit.totalSeg = pSrcHeader->udh.concat8bit.totalSeg;
948 pDstHeader->udh.concat8bit.seqNum = pSrcHeader->udh.concat8bit.seqNum;
952 case SMS_UDH_CONCAT_16BIT :
954 pDstHeader->udh.concat16bit.msgRef = pSrcHeader->udh.concat16bit.msgRef;
955 pDstHeader->udh.concat16bit.totalSeg = pSrcHeader->udh.concat16bit.totalSeg;
956 pDstHeader->udh.concat16bit.seqNum = pSrcHeader->udh.concat16bit.seqNum;
963 void SmsPluginTransport::setNetStatus(msg_network_status_t netStatus)
966 curStatus = netStatus;
972 msg_network_status_t SmsPluginTransport::getNetStatus()
978 if (curStatus == MSG_NETWORK_SENDING)
979 ret = cv.timedwait(mx.pMutex(), 125);
983 if (ret == ETIMEDOUT)
985 MSG_DEBUG("WARNING: SENT STATUS TIME-OUT");
986 curStatus = MSG_NETWORK_SEND_TIMEOUT;
993 unsigned char SmsPluginTransport::getMsgRef()
999 SMS_PID_T SmsPluginTransport::convertPid(MSG_SMS_PID_T pid)
1006 retPid = SMS_PID_NORMAL;
1008 case MSG_PID_VOICE :
1009 retPid = SMS_PID_VOICE;
1012 retPid = SMS_PID_TELEX;
1015 retPid = SMS_PID_x400;
1017 case MSG_PID_ERMES :
1018 retPid = SMS_PID_ERMES;
1020 case MSG_PID_EMAIL :
1021 retPid = SMS_PID_EMAIL;
1024 retPid = SMS_PID_NORMAL;