2 * Copyright 2012-2013 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://floralicense.org
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 "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>
39 extern struct tapi_handle *pTapiHandle;
41 /*==================================================================================================
42 IMPLEMENTATION OF SmsPluginTransport - Member Functions
43 ==================================================================================================*/
44 SmsPluginTransport* SmsPluginTransport::pInstance = NULL;
47 SmsPluginTransport::SmsPluginTransport()
55 SmsPluginTransport::~SmsPluginTransport()
61 SmsPluginTransport* SmsPluginTransport::instance()
64 pInstance = new SmsPluginTransport();
70 void SmsPluginTransport::submitRequest(SMS_REQUEST_INFO_S *pReqInfo)
74 SMS_TPDU_S tpdu = {0,};
76 tpdu.tpduType = SMS_TPDU_SUBMIT;
78 // Set SMS Send Options - Setting
79 setSmsSendOptions(&(tpdu.data.submit));
81 // Set SMS Send Options - Each Message
82 if (pReqInfo->sendOptInfo.bSetting == true)
84 tpdu.data.submit.bStatusReport = pReqInfo->sendOptInfo.bDeliverReq;
85 tpdu.data.submit.bReplyPath = pReqInfo->sendOptInfo.option.smsSendOptInfo.bReplyPath;
88 // Set Coding Scheme for apps that use port number
89 if (pReqInfo->msgInfo.msgPort.valid == true)
91 tpdu.data.submit.dcs.codingScheme = (SMS_CODING_SCHEME_T)pReqInfo->msgInfo.encodeType;
93 MSG_DEBUG("DCS is changed by application : [%d]", tpdu.data.submit.dcs.codingScheme);
97 // Update Msg Ref into Report Table
98 if (tpdu.data.submit.bStatusReport == true)
100 MSG_DEBUG("Update Msg Ref [%d] in Report Table", tpdu.data.submit.msgRef);
102 SmsPluginStorage::instance()->updateMsgRef(pReqInfo->msgInfo.msgId, tpdu.data.submit.msgRef);
108 setSmscOptions(&smsc);
112 MSG_DEBUG("pReqInfo->msgInfo.nAddressCnt [%d]", pReqInfo->msgInfo.nAddressCnt);
114 for (i = 0; i < pReqInfo->msgInfo.nAddressCnt; i++)
116 // Make SMS_SUBMIT_DATA_S from MSG_REQUEST_INFO_S
117 SMS_SUBMIT_DATA_S submitData = {{0},};
118 msgInfoToSubmitData(&(pReqInfo->msgInfo), &submitData, &(tpdu.data.submit.dcs.codingScheme), i);
120 // Encode SMSC Address
121 unsigned char smscAddr[MAX_SMSC_LEN];
122 memset(smscAddr, 0x00, sizeof(smscAddr));
124 int smscLen = SmsPluginParamCodec::encodeSMSC(&smsc, smscAddr);
127 MSG_DEBUG("smscLen <= 0");
131 char smscAddrTmp[(smscLen*2)+1];
132 memset(smscAddrTmp, 0x00, sizeof(smscAddrTmp));
133 for (j = 0; j < smscLen; j++) {
134 snprintf(smscAddrTmp+(j*2), sizeof(smscAddrTmp)-(j*2), "%02X", smscAddr[j]);
136 MSG_DEBUG("pSCAInfo [%s]", smscAddrTmp);
140 char buf[MAX_TPDU_DATA_LEN];
142 int addLen = strlen(submitData.destAddress.address);
144 tpdu.data.submit.destAddress.ton = submitData.destAddress.ton;
145 tpdu.data.submit.destAddress.npi = submitData.destAddress.npi;
147 if (addLen < MAX_ADDRESS_LEN) {
148 memcpy(tpdu.data.submit.destAddress.address, submitData.destAddress.address, addLen);
149 tpdu.data.submit.destAddress.address[addLen] = '\0';
151 memcpy(tpdu.data.submit.destAddress.address, submitData.destAddress.address, MAX_ADDRESS_LEN);
152 tpdu.data.submit.destAddress.address[MAX_ADDRESS_LEN] = '\0';
155 MSG_DEBUG("ton [%d]", tpdu.data.submit.destAddress.ton);
156 MSG_DEBUG("npi [%d]", tpdu.data.submit.destAddress.npi);
157 MSG_DEBUG("address [%s]", tpdu.data.submit.destAddress.address);
159 bool bStatusReport = false;
161 for (unsigned int segCnt = 0; segCnt < submitData.segCount; segCnt++)
163 if (submitData.userData[segCnt].headerCnt > 0) {
164 tpdu.data.submit.bHeaderInd = true;
166 tpdu.data.submit.bHeaderInd = false;
169 if (segCnt == 0 && submitData.segCount > 1) {
170 bStatusReport = tpdu.data.submit.bStatusReport;
171 tpdu.data.submit.bStatusReport = false;
172 } else if ((segCnt+1 == submitData.segCount) && submitData.segCount > 1) {
173 tpdu.data.submit.bStatusReport = bStatusReport;
176 memset(&(tpdu.data.submit.userData), 0x00, sizeof(SMS_USERDATA_S));
177 memcpy(&(tpdu.data.submit.userData), &(submitData.userData[segCnt]), sizeof(SMS_USERDATA_S));
179 // Encode SMS-SUBMIT TPDU
180 memset(buf, 0x00, sizeof(buf));
182 bufLen = SmsPluginTpduCodec::encodeTpdu(&tpdu, buf);
184 // Make Telephony Structure
185 TelSmsDatapackageInfo_t pkgInfo;
188 memset((void*)pkgInfo.szData, 0x00, sizeof(pkgInfo.szData));
189 memcpy((void*)pkgInfo.szData, buf, bufLen);
191 pkgInfo.szData[bufLen] = 0;
192 pkgInfo.MsgLength = bufLen;
195 memset(pkgInfo.Sca, 0x00, sizeof(pkgInfo.Sca));
196 memcpy((void*)pkgInfo.Sca, smscAddr, smscLen);
197 pkgInfo.Sca[smscLen] = '\0';
200 char pkgInfoTmp[(pkgInfo.MsgLength*2)+1];
201 memset(pkgInfoTmp, 0x00, sizeof(pkgInfoTmp));
202 for (j = 0; j < pkgInfo.MsgLength; j++) {
203 snprintf(pkgInfoTmp+(j*2), sizeof(pkgInfoTmp)-(j*2), "%02X", pkgInfo.szData[j]);
205 MSG_DEBUG("Submit Request TPDU.");
206 MSG_DEBUG("[%s]", pkgInfoTmp);
208 SMS_SENT_INFO_S sentInfo;
209 memset(&sentInfo, 0x00, sizeof(SMS_SENT_INFO_S));
211 bool bMoreMsg = FALSE;
213 memcpy(&(sentInfo.reqInfo), pReqInfo, sizeof(SMS_REQUEST_INFO_S));
215 if ((segCnt+1) == submitData.segCount && (i+1)==pReqInfo->msgInfo.nAddressCnt)
217 sentInfo.bLast = true;
223 sentInfo.bLast = false;
228 SmsPluginEventHandler::instance()->SetSentInfo(&sentInfo);
230 curStatus = MSG_NETWORK_SENDING;
233 int tapiRet = TAPI_API_SUCCESS;
235 tapiRet = tel_send_sms(pTapiHandle, &pkgInfo, bMoreMsg, TapiEventSentStatus, NULL);
237 if (tapiRet == TAPI_API_SUCCESS)
239 MSG_DEBUG("######## tel_send_sms Success !!! return : [%d] #######", tapiRet);
243 SmsPluginEventHandler::instance()->handleSentStatus(MSG_NETWORK_SEND_FAIL);
245 THROW(MsgException::SMS_PLG_ERROR, "######## tel_send_sms Fail !!! return : [%d] #######", tapiRet);
248 // Tizen Validation System
250 msisdn = MsgSettingGetString(MSG_SIM_MSISDN);
252 MSG_SMS_VLD_INFO("%d, SMS Send Start, %s->%s, %s", pReqInfo->msgInfo.msgId, \
253 (msisdn == NULL)?"ME":msisdn, \
254 pReqInfo->msgInfo.addressList[0].addressVal, \
255 (tapiRet == TAPI_API_SUCCESS)?"Success":"Fail");
257 MSG_SMS_VLD_TXT("%d, [%s]", pReqInfo->msgInfo.msgId, pReqInfo->msgInfo.msgText);
259 msg_network_status_t retStatus = getNetStatus();
261 #ifdef MSG_SMS_REPORT
262 if (err == MSG_SUCCESS && tmpInfo.msgInfo.msgPort.valid == false)
264 if(pReqInfo->sendOptInfo.bDeliverReq == true)
266 MSG_DEBUG("Update Delivery Report Status : [%d] Msg ID : [%d]", err, tmpInfo.msgInfo.msgId);
268 // Adding delivery report status info.
269 MsgStoAddDeliveryReportStatus( tmpInfo.msgInfo.msgId, (unsigned char)tmpInfo.msgInfo.referenceId);
274 MSG_SMS_VLD_INFO("%d, SMS Send End, %s->%s, %s", pReqInfo->msgInfo.msgId, \
275 (msisdn == NULL)?"ME":msisdn, \
276 pReqInfo->msgInfo.addressList[0].addressVal, \
277 (retStatus == MSG_NETWORK_SEND_SUCCESS)?"Success":"Fail");
280 if (retStatus == MSG_NETWORK_SEND_SUCCESS)
282 if (bMoreMsg == false) {
283 MsgInsertTicker("SMS is sent", SMS_MESSAGE_SENT);
285 MSG_DEBUG("######## Msg Sent was Successful !!! return : [%d] #######", retStatus);
289 MsgInsertTicker("Sending SMS is failed", NULL);
290 MsgInsertTicker("Sending SMS is failed", SMS_MESSAGE_SENDING_FAIL);
292 SmsPluginEventHandler::instance()->handleSentStatus(MSG_NETWORK_SEND_FAIL);
294 THROW(MsgException::SMS_PLG_ERROR, "######## Msg Sent was Failed !!! return : [%d] #######", retStatus);
297 if (tpdu.data.submit.userData.headerCnt > 0) tpdu.data.submit.userData.headerCnt--;
305 void SmsPluginTransport::sendDeliverReport(msg_error_t err)
311 tpdu.tpduType = SMS_TPDU_DELIVER_REP;
313 TelSmsResponse_t response;
315 int tapiRet = TAPI_API_SUCCESS;
317 if (err == MSG_SUCCESS)
319 tpdu.data.deliverRep.reportType = SMS_REPORT_POSITIVE;
320 response = TAPI_NETTEXT_SENDSMS_SUCCESS;
322 tapiRet = tel_set_sms_memory_status(pTapiHandle, TAPI_NETTEXT_PDA_MEMORY_STATUS_AVAILABLE, TapiEventMemoryStatus, NULL);
324 if (tapiRet == TAPI_API_SUCCESS)
326 MSG_DEBUG("######## tel_set_sms_memory_status() Success !!! #######");
330 MSG_DEBUG("######## tel_set_sms_memory_status() Failed !!! return : [%d] #######", tapiRet);
333 else if (err == MSG_ERR_SIM_STORAGE_FULL)
335 tpdu.data.deliverRep.reportType = SMS_REPORT_NEGATIVE;
336 tpdu.data.deliverRep.failCause = SMS_FC_MSG_CAPA_EXCEEDED;
337 response = TAPI_NETTEXT_SIM_FULL;
339 tapiRet = tel_set_sms_memory_status(pTapiHandle, TAPI_NETTEXT_PDA_MEMORY_STATUS_FULL, TapiEventMemoryStatus, NULL);
341 if (tapiRet == TAPI_API_SUCCESS)
343 MSG_DEBUG("######## tel_set_sms_memory_status() Success !!! #######");
347 MSG_DEBUG("######## tel_set_sms_memory_status() Failed !!! return : [%d] #######", tapiRet);
350 else if (err == MSG_ERR_MESSAGE_COUNT_FULL)
352 tpdu.data.deliverRep.reportType = SMS_REPORT_NEGATIVE;
353 tpdu.data.deliverRep.failCause = SMS_FC_MSG_CAPA_EXCEEDED;
354 response = TAPI_NETTEXT_ME_FULL;
356 tapiRet = tel_set_sms_memory_status(pTapiHandle, TAPI_NETTEXT_PDA_MEMORY_STATUS_FULL, TapiEventMemoryStatus, NULL);
358 if (tapiRet == TAPI_API_SUCCESS)
360 MSG_DEBUG("######## tel_set_sms_memory_status() Success !!! #######");
364 MSG_DEBUG("######## tel_set_sms_memory_status() Failed !!! return : [%d] #######", tapiRet);
369 tpdu.data.deliverRep.reportType = SMS_REPORT_NEGATIVE;
370 tpdu.data.deliverRep.failCause = SMS_FC_UNSPEC_ERROR;
371 //response = TAPI_NETTEXT_PROTOCOL_ERROR;
372 // For gcf test [34.2.5.3 class2 message]
373 response = TAPI_NETTEXT_SIM_FULL;
377 MSG_DEBUG("err : [%d], response : [%02x]", err, response);
379 tpdu.data.deliverRep.bHeaderInd = false;
380 tpdu.data.deliverRep.paramInd = 0x00;
382 // Encode SMS-DELIVER-REPORT TPDU
385 char buf[MAX_TPDU_DATA_LEN];
386 memset(buf, 0x00, sizeof(buf));
388 bufLen = SmsPluginTpduCodec::encodeTpdu(&tpdu, buf);
391 /////// print DeliverReport tpdu
392 printf("\n\n######## DeliverReport tpdu #########\n");
393 for(int i=0; i < bufLen; i++)
395 printf("[%02x] ", buf[i]);
397 printf("\n#################################\n\n");
401 // Make Telephony Structure
402 TelSmsDatapackageInfo_t pkgInfo;
405 memset((void*)pkgInfo.szData, 0x00, sizeof(pkgInfo.szData));
406 memcpy((void*)pkgInfo.szData, buf, bufLen);
408 pkgInfo.szData[bufLen] = 0;
409 pkgInfo.MsgLength = bufLen;
415 setSmscOptions(&smsc);
417 // Encode SMSC Address
418 unsigned char smscAddr[MAX_SMSC_LEN];
419 memset(smscAddr, 0x00, sizeof(smscAddr));
421 int smscLen = SmsPluginParamCodec::encodeSMSC(&smsc, smscAddr);
423 if (smscLen <= 0) return;
426 memset(pkgInfo.Sca, 0x00, sizeof(pkgInfo.Sca));
427 memcpy((void*)pkgInfo.Sca, smscAddr, smscLen);
428 pkgInfo.Sca[smscLen] = '\0';
430 // Send Deliver Report
431 tapiRet = tel_send_sms_deliver_report(pTapiHandle, &pkgInfo, response, TapiEventDeliveryReportCNF, NULL);
433 if (tapiRet == TAPI_API_SUCCESS)
435 MSG_DEBUG("######## tel_send_sms_deliver_report() Success !!! #######");
439 MSG_DEBUG("######## tel_send_sms_deliver_report() Fail !!! return : [%d] #######", tapiRet);
445 void SmsPluginTransport::sendClass0DeliverReport(msg_error_t err)
451 tpdu.tpduType = SMS_TPDU_DELIVER_REP;
453 TelSmsResponse_t response;
455 int tapiRet = TAPI_API_SUCCESS;
457 if (err == MSG_SUCCESS)
459 tpdu.data.deliverRep.reportType = SMS_REPORT_POSITIVE;
460 response = TAPI_NETTEXT_SENDSMS_SUCCESS;
462 tapiRet = tel_set_sms_memory_status(pTapiHandle, TAPI_NETTEXT_PDA_MEMORY_STATUS_AVAILABLE, TapiEventMemoryStatus, NULL);
464 if (tapiRet == TAPI_API_SUCCESS)
466 MSG_DEBUG("######## tel_set_sms_memory_status() Success !!! #######");
470 MSG_DEBUG("######## tel_set_sms_memory_status() Failed !!! return : [%d] #######", tapiRet);
473 else if (err == MSG_ERR_SIM_STORAGE_FULL)
475 tpdu.data.deliverRep.reportType = SMS_REPORT_POSITIVE;
476 response = TAPI_NETTEXT_SENDSMS_SUCCESS;
478 tapiRet = tel_set_sms_memory_status(pTapiHandle, TAPI_NETTEXT_PDA_MEMORY_STATUS_FULL, TapiEventMemoryStatus, NULL);
480 if (tapiRet == TAPI_API_SUCCESS)
482 MSG_DEBUG("######## tel_set_sms_memory_status() Success !!! #######");
486 MSG_DEBUG("######## tel_set_sms_memory_status() Failed !!! return : [%d] #######", tapiRet);
489 else if (err == MSG_ERR_MESSAGE_COUNT_FULL)
491 tpdu.data.deliverRep.reportType = SMS_REPORT_POSITIVE;
492 response = TAPI_NETTEXT_SENDSMS_SUCCESS;
494 tapiRet = tel_set_sms_memory_status(pTapiHandle, TAPI_NETTEXT_PDA_MEMORY_STATUS_FULL, TapiEventMemoryStatus, NULL);
496 if (tapiRet == TAPI_API_SUCCESS)
498 MSG_DEBUG("######## tel_set_sms_memory_status() Success !!! #######");
502 MSG_DEBUG("######## tel_set_sms_memory_status() Failed !!! return : [%d] #######", tapiRet);
507 tpdu.data.deliverRep.reportType = SMS_REPORT_NEGATIVE;
508 tpdu.data.deliverRep.failCause = SMS_FC_UNSPEC_ERROR;
509 //response = TAPI_NETTEXT_PROTOCOL_ERROR;
510 // For gcf test [34.2.5.3 class2 message]
511 response = TAPI_NETTEXT_SIM_FULL;
515 MSG_DEBUG("err : [%d], response : [%02x]", err, response);
517 tpdu.data.deliverRep.bHeaderInd = false;
518 tpdu.data.deliverRep.paramInd = 0x00;
520 // Encode SMS-DELIVER-REPORT TPDU
523 char buf[MAX_TPDU_DATA_LEN];
524 memset(buf, 0x00, sizeof(buf));
526 bufLen = SmsPluginTpduCodec::encodeTpdu(&tpdu, buf);
528 // Make Telephony Structure
529 TelSmsDatapackageInfo_t pkgInfo;
532 memset((void*)pkgInfo.szData, 0x00, sizeof(pkgInfo.szData));
533 memcpy((void*)pkgInfo.szData, buf, bufLen);
535 pkgInfo.szData[bufLen] = 0;
536 pkgInfo.MsgLength = bufLen;
542 setSmscOptions(&smsc);
544 // Encode SMSC Address
545 unsigned char smscAddr[MAX_SMSC_LEN];
546 memset(smscAddr, 0x00, sizeof(smscAddr));
548 int smscLen = SmsPluginParamCodec::encodeSMSC(&smsc, smscAddr);
550 if (smscLen <= 0) return;
553 memset(pkgInfo.Sca, 0x00, sizeof(pkgInfo.Sca));
554 memcpy((void*)pkgInfo.Sca, smscAddr, smscLen);
555 pkgInfo.Sca[smscLen] = '\0';
557 // Send Deliver Report
558 tapiRet = tel_send_sms_deliver_report(pTapiHandle, &pkgInfo, response, TapiEventDeliveryReportCNF, NULL);
560 if (tapiRet == TAPI_API_SUCCESS)
562 MSG_DEBUG("######## tel_send_sms_deliver_report() Success !!! #######");
566 MSG_DEBUG("######## tel_send_sms_deliver_report() Fail !!! return : [%d] #######", tapiRet);
574 void SmsPluginTransport::setSmsSendOptions(SMS_SUBMIT_S *pSubmit)
576 // Set SMS Send Options
577 pSubmit->bRejectDup = false;
578 pSubmit->bHeaderInd = false;
580 MsgSettingGetBool(SMS_SEND_DELIVERY_REPORT, &pSubmit->bStatusReport);
581 MsgSettingGetBool(SMS_SEND_REPLY_PATH, &pSubmit->bReplyPath);
583 pSubmit->msgRef = msgRef++;
585 pSubmit->dcs.bCompressed = false;
586 pSubmit->dcs.msgClass = SMS_MSG_CLASS_NONE;
587 pSubmit->dcs.codingGroup = SMS_GROUP_GENERAL;
589 pSubmit->dcs.codingScheme = (SMS_CODING_SCHEME_T)MsgSettingGetInt(SMS_SEND_DCS);
591 MSG_DEBUG("DCS : %d", pSubmit->dcs.codingScheme);
593 int selectIdx = MsgSettingGetInt(SMSC_SELECTED);
597 memset(keyName, 0x00, sizeof(keyName));
598 sprintf(keyName, "%s/%d", SMSC_PID, selectIdx);
599 MSG_SMS_PID_T pid = (MSG_SMS_PID_T)MsgSettingGetInt(keyName);
601 pSubmit->pid = convertPid(pid);
602 MSG_DEBUG("PID : %d", pSubmit->pid);
604 memset(keyName, 0x00, sizeof(keyName));
605 sprintf(keyName, "%s/%d", SMSC_VAL_PERIOD, selectIdx);
606 int valPeriod = MsgSettingGetInt(keyName);
608 MSG_DEBUG("valPeriod : %d", valPeriod);
612 pSubmit->vpf = SMS_VPF_NOT_PRESENT;
616 pSubmit->vpf = SMS_VPF_RELATIVE;
617 pSubmit->validityPeriod.format = SMS_TIME_RELATIVE;
618 pSubmit->validityPeriod.time.relative.time = valPeriod;
623 void SmsPluginTransport::setSmscOptions(SMS_ADDRESS_S *pSmsc)
626 int selectIdx = MsgSettingGetInt(SMSC_SELECTED);
630 memset(keyName, 0x00, sizeof(keyName));
631 sprintf(keyName, "%s/%d", SMSC_ADDRESS, selectIdx);
633 char* tmpValue = NULL;
635 tmpValue = MsgSettingGetString(keyName);
637 if (tmpValue != NULL)
639 memset(pSmsc->address, 0x00, sizeof(pSmsc->address));
640 strncpy(pSmsc->address, tmpValue, MAX_ADDRESS_LEN);
642 MSG_DEBUG("address : %s", pSmsc->address);
646 strncpy(pSmsc->address, "+8210911111", MAX_ADDRESS_LEN);
649 memset(keyName, 0x00, sizeof(keyName));
650 sprintf(keyName, "%s/%d", SMSC_TON, selectIdx);
651 pSmsc->ton = (SMS_TON_T)MsgSettingGetInt(keyName);
653 MSG_DEBUG("ton : %d", pSmsc->ton);
655 memset(keyName, 0x00, sizeof(keyName));
656 sprintf(keyName, "%s/%d", SMSC_NPI, selectIdx);
657 pSmsc->npi = (SMS_NPI_T)MsgSettingGetInt(keyName);
659 MSG_DEBUG("npi : %d", pSmsc->npi);
661 if (tmpValue != NULL)
669 void SmsPluginTransport::msgInfoToSubmitData(const MSG_MESSAGE_INFO_S *pMsgInfo, SMS_SUBMIT_DATA_S *pData, SMS_CODING_SCHEME_T *pCharType, int addrIndex)
671 // Destination Address
672 pData->destAddress.ton = SMS_TON_UNKNOWN;
673 pData->destAddress.npi = SMS_NPI_ISDN;
675 memset(pData->destAddress.address, 0x00, MAX_ADDRESS_LEN+1);
676 memcpy(pData->destAddress.address, pMsgInfo->addressList[addrIndex].addressVal, MAX_ADDRESS_LEN);
678 MSG_DEBUG("ton [%d]", pData->destAddress.ton);
679 MSG_DEBUG("npi [%d]", pData->destAddress.npi);
680 MSG_DEBUG("address [%s]", pData->destAddress.address);
682 int decodeLen = 0, bufSize = (MAX_GSM_7BIT_DATA_LEN*MAX_SEGMENT_NUM) + 1; // SMS_CHARSET_7BIT
684 unsigned char decodeData[bufSize];
685 memset(decodeData, 0x00, sizeof(decodeData));
687 msg_encode_type_t encodeType = MSG_ENCODE_GSM7BIT;
689 MSG_LANGUAGE_ID_T langId = MSG_LANG_ID_RESERVED;
691 bool bAbnormal = false;
694 if (pMsgInfo->bTextSms == true)
696 if (*pCharType == SMS_CHARSET_7BIT)
698 decodeLen = textCvt.convertUTF8ToGSM7bit(decodeData, bufSize, (unsigned char*)pMsgInfo->msgText, (int)pMsgInfo->dataSize, &langId, &bAbnormal);
700 else if (*pCharType == SMS_CHARSET_8BIT)
702 memcpy(decodeData, pMsgInfo->msgText, pMsgInfo->dataSize);
703 decodeLen = pMsgInfo->dataSize;
705 else if (*pCharType == SMS_CHARSET_UCS2)
707 decodeLen = textCvt.convertUTF8ToUCS2(decodeData, bufSize, (unsigned char*)pMsgInfo->msgText, (int)pMsgInfo->dataSize);
709 else if (*pCharType == SMS_CHARSET_AUTO)
711 decodeLen = textCvt.convertUTF8ToAuto(decodeData, bufSize, (unsigned char*)pMsgInfo->msgText, (int)pMsgInfo->dataSize, &encodeType);
712 *pCharType = encodeType;
719 char* pFileData = NULL;
720 AutoPtr<char> FileBuf(&pFileData);
722 // Read Message Data from File
723 if (MsgOpenAndReadFile(pMsgInfo->msgData, &pFileData, &fileSize) == false)
724 THROW(MsgException::FILE_ERROR, "MsgOpenAndReadFile error");
726 MSG_DEBUG("file size : [%d] file data : [%s]", fileSize, pFileData);
728 if (*pCharType == SMS_CHARSET_7BIT)
730 decodeLen = textCvt.convertUTF8ToGSM7bit(decodeData, bufSize, (unsigned char*)pFileData, fileSize, &langId, &bAbnormal);
732 else if (*pCharType == SMS_CHARSET_8BIT)
734 memcpy(decodeData, pFileData, fileSize);
735 decodeLen = fileSize;
737 else if (*pCharType == SMS_CHARSET_UCS2)
739 decodeLen = textCvt.convertUTF8ToUCS2(decodeData, bufSize, (unsigned char*)pFileData, fileSize);
741 else if (*pCharType == SMS_CHARSET_AUTO)
743 decodeLen = textCvt.convertUTF8ToAuto(decodeData, bufSize, (unsigned char*)pFileData, fileSize, &encodeType);
744 *pCharType = encodeType;
748 if (pMsgInfo->nAddressCnt == (addrIndex + 1))
749 MsgDeleteFile(pMsgInfo->msgData);
752 MSG_DEBUG("decode length : [%d]", decodeLen);
753 MSG_DEBUG("character type : [%d]", *pCharType);
754 MSG_DEBUG("Language Identifier : [%d]", langId);
755 MSG_DEBUG("reply address : [%s]", pMsgInfo->replyAddress);
759 char* encodedAddr = NULL;
760 AutoPtr<char> addressBuf(&encodedAddr);
762 if (strlen(pMsgInfo->replyAddress) > 0)
764 SMS_ADDRESS_S replyAddr = {};
766 replyAddr.ton = SMS_TON_NATIONAL;
767 replyAddr.npi = SMS_NPI_ISDN;
769 memset(replyAddr.address, 0x00, MAX_ADDRESS_LEN+1);
770 memcpy(replyAddr.address, pMsgInfo->replyAddress, MAX_ADDRESS_LEN);
772 addrLen = SmsPluginParamCodec::encodeAddress(&replyAddr, &encodedAddr);
774 MSG_DEBUG("reply addr length : [%d]", addrLen);
777 int segSize = 0, index = 0;
779 segSize = getSegmentSize(*pCharType, decodeLen, pMsgInfo->msgPort.valid, langId, addrLen);
781 pData->segCount = ceil((double)decodeLen/(double)segSize);
783 MSG_DEBUG("segment size : [%d], pData->segCount : [%d]", segSize, pData->segCount);
785 if (pData->segCount > MAX_SEGMENT_NUM)
786 THROW(MsgException::SMS_PLG_ERROR, "Segment Count is over maximum : %d", pData->segCount);
790 for (unsigned int i = 0; i < pData->segCount; i++)
794 if ((i + 1) == pData->segCount)
795 pData->userData[i].length = decodeLen - (i*segSize);
797 pData->userData[i].length = segSize;
799 memset(pData->userData[i].data, 0x00, MAX_USER_DATA_LEN+1);
800 memcpy(pData->userData[i].data, &(decodeData[index]), pData->userData[i].length);
801 pData->userData[i].data[pData->userData[i].length] = 0;
803 MSG_DEBUG("user data len [%d]", pData->userData[i].length);
804 MSG_DEBUG("user data [%s]", pData->userData[i].data);
808 // Set User Data Header for Concatenated Message
809 if (pData->segCount > 1)
811 pData->userData[i].header[headerCnt].udhType = SMS_UDH_CONCAT_8BIT;
812 pData->userData[i].header[headerCnt].udh.concat8bit.msgRef = msgRef8bit;
813 pData->userData[i].header[headerCnt].udh.concat8bit.totalSeg = pData->segCount;
814 pData->userData[i].header[headerCnt].udh.concat8bit.seqNum = i + 1;
819 // Set User Data Header Port Information
820 if (pMsgInfo->msgPort.valid == true)
822 pData->userData[i].header[headerCnt].udhType = SMS_UDH_APP_PORT_16BIT;
823 pData->userData[i].header[headerCnt].udh.appPort16bit.destPort = pMsgInfo->msgPort.dstPort;
824 pData->userData[i].header[headerCnt].udh.appPort16bit.originPort = pMsgInfo->msgPort.srcPort;
829 // Set User Data Header for Alternate Reply Address
830 if (strlen(pMsgInfo->replyAddress) > 0)
832 pData->userData[i].header[headerCnt].udhType = SMS_UDH_ALTERNATE_REPLY_ADDRESS;
834 pData->userData[i].header[headerCnt].udh.alternateAddress.ton = SMS_TON_NATIONAL;
835 pData->userData[i].header[headerCnt].udh.alternateAddress.npi = SMS_NPI_ISDN;
837 memset(pData->userData[i].header[headerCnt].udh.alternateAddress.address, 0x00, MAX_ADDRESS_LEN+1);
838 memcpy(pData->userData[i].header[headerCnt].udh.alternateAddress.address, pMsgInfo->replyAddress, MAX_ADDRESS_LEN);
843 // Set User Data Header for National Language Single Shift
844 if (*pCharType == SMS_CHARSET_7BIT && langId != MSG_LANG_ID_RESERVED)
846 pData->userData[i].header[headerCnt].udhType = SMS_UDH_SINGLE_SHIFT;
847 pData->userData[i].header[headerCnt].udh.singleShift.langId = langId;
852 pData->userData[i].headerCnt = headerCnt;
859 int SmsPluginTransport::getSegmentSize(SMS_CODING_SCHEME_T CodingScheme, int DataLen, bool bPortNum, MSG_LANGUAGE_ID_T LangId, int ReplyAddrLen)
861 int headerLen = 1, concat = 5, port = 6, lang = 3, reply = 2;
862 int headerSize = 0, segSize = 0, maxSize = 0;
864 if (CodingScheme == SMS_CHARSET_7BIT)
866 MSG_DEBUG("SMS_CHARSET_7BIT");
867 maxSize = MAX_GSM_7BIT_DATA_LEN;
869 else if (CodingScheme == SMS_CHARSET_8BIT || CodingScheme == SMS_CHARSET_UCS2)
871 MSG_DEBUG("SMS_CHARSET_8BIT or SMS_CHARSET_UCS2 [%d]", CodingScheme);
872 maxSize = MAX_UCS2_DATA_LEN;
875 if (bPortNum == true)
877 MSG_DEBUG("Port Number Exists");
881 if (LangId != MSG_LANG_ID_RESERVED)
883 MSG_DEBUG("National Language Exists");
887 if (ReplyAddrLen > 0)
889 MSG_DEBUG("Reply Address Exists");
891 headerSize += ReplyAddrLen;
894 if (CodingScheme == SMS_CHARSET_7BIT)
896 if ((DataLen+headerSize) > maxSize)
897 segSize = ((140*8) - ((headerLen + concat + headerSize)*8)) / 7;
901 else if (CodingScheme == SMS_CHARSET_8BIT || CodingScheme == SMS_CHARSET_UCS2)
903 if ((DataLen+headerSize) > maxSize)
904 segSize = 140 - (headerLen + concat + headerSize);
913 void SmsPluginTransport::setConcatHeader(SMS_UDH_S *pSrcHeader, SMS_UDH_S *pDstHeader)
915 pDstHeader->udhType = pSrcHeader->udhType;
917 switch (pDstHeader->udhType)
919 case SMS_UDH_CONCAT_8BIT :
921 pDstHeader->udh.concat8bit.msgRef = pSrcHeader->udh.concat8bit.msgRef;
922 pDstHeader->udh.concat8bit.totalSeg = pSrcHeader->udh.concat8bit.totalSeg;
923 pDstHeader->udh.concat8bit.seqNum = pSrcHeader->udh.concat8bit.seqNum;
927 case SMS_UDH_CONCAT_16BIT :
929 pDstHeader->udh.concat16bit.msgRef = pSrcHeader->udh.concat16bit.msgRef;
930 pDstHeader->udh.concat16bit.totalSeg = pSrcHeader->udh.concat16bit.totalSeg;
931 pDstHeader->udh.concat16bit.seqNum = pSrcHeader->udh.concat16bit.seqNum;
938 void SmsPluginTransport::setNetStatus(msg_network_status_t netStatus)
941 curStatus = netStatus;
947 msg_network_status_t SmsPluginTransport::getNetStatus()
953 if (curStatus == MSG_NETWORK_SENDING)
954 ret = cv.timedwait(mx.pMutex(), 125);
958 if (ret == ETIMEDOUT)
960 MSG_DEBUG("WARNING: SENT STATUS TIME-OUT");
961 curStatus = MSG_NETWORK_SEND_TIMEOUT;
968 unsigned char SmsPluginTransport::getMsgRef()
974 SMS_PID_T SmsPluginTransport::convertPid(MSG_SMS_PID_T pid)
981 retPid = SMS_PID_NORMAL;
984 retPid = SMS_PID_VOICE;
987 retPid = SMS_PID_TELEX;
990 retPid = SMS_PID_x400;
993 retPid = SMS_PID_ERMES;
996 retPid = SMS_PID_EMAIL;
999 retPid = SMS_PID_NORMAL;