2 * Copyright 2012-2013 Samsung Electronics Co., Ltd
4 * Licensed under the Flora License, Version 1.1 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://floralicense.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.
20 #include "MsgCppTypes.h"
21 #include "MsgException.h"
22 #include "MsgGconfWrapper.h"
23 #include "SmsPluginParamCodec.h"
24 #include "SmsPluginTpduCodec.h"
25 #include "SmsPluginTransport.h"
26 #include "SmsPluginStorage.h"
27 #include "SmsPluginEventHandler.h"
28 #include "SmsPluginCallback.h"
29 #include "SmsPluginSimMsg.h"
31 extern struct tapi_handle *pTapiHandle;
33 /*==================================================================================================
34 IMPLEMENTATION OF SmsPluginSimMsg - Member Functions
35 ==================================================================================================*/
36 SmsPluginSimMsg* SmsPluginSimMsg::pInstance = NULL;
39 SmsPluginSimMsg::SmsPluginSimMsg()
41 // Initialize member variables
46 memset(&simMsgDataInfo, 0x00, sizeof(simMsgDataInfo));
50 SmsPluginSimMsg::~SmsPluginSimMsg()
57 SmsPluginSimMsg* SmsPluginSimMsg::instance()
60 pInstance = new SmsPluginSimMsg();
66 void SmsPluginSimMsg::initSimMessage()
70 MSG_SIM_COUNT_S tmpMsgCnt;
71 memset(&tmpMsgCnt, 0x00, sizeof(MSG_SIM_COUNT_S));
73 getSimMsgCount(&tmpMsgCnt);
75 MSG_MESSAGE_INFO_S tmpMsgInfo;
76 memset(&tmpMsgInfo, 0x00, sizeof(MSG_MESSAGE_INFO_S));
78 for (int i = 0; i < tmpMsgCnt.usedCount; i++)
81 if (getSimMsg(tmpMsgCnt.indexList[i], &tmpMsgInfo) == false)
84 if (SmsPluginStorage::instance()->addSimMessage(&tmpMsgInfo) != MSG_SUCCESS)
86 MSG_DEBUG("Fail to addSimMessage()");
94 msg_error_t SmsPluginSimMsg::saveSimMessage(const MSG_MESSAGE_INFO_S *pMsgInfo, SMS_SIM_ID_LIST_S *pSimIdList)
96 // Reset Out Parameter
97 pSimIdList->count = 0;
100 memset(&tpdu, 0x00, sizeof(SMS_TPDU_S));
102 tpdu.tpduType = SMS_TPDU_DELIVER;
104 // Set SMS TPDU Options
105 setSmsOptions(&(tpdu.data.deliver));
108 convertTimeStamp(pMsgInfo, &(tpdu.data.deliver));
112 memset(&smsc, 0x00, sizeof(SMS_ADDRESS_S));
113 SmsPluginTransport::instance()->setSmscOptions(&smsc);
115 // Make SMS_SUBMIT_DATA_S from MSG_REQUEST_INFO_S
116 SMS_SUBMIT_DATA_S submitData;
117 memset(&submitData, 0x00, sizeof(SMS_SUBMIT_DATA_S));
118 SmsPluginTransport::instance()->msgInfoToSubmitData(pMsgInfo, &submitData, &(tpdu.data.deliver.dcs.codingScheme), 0);
120 // Check sim message full.
121 if (checkSimMsgFull(submitData.segCount) == true)
123 MSG_DEBUG("SIM storage is full.");
125 return MSG_ERR_SIM_STORAGE_FULL;
128 tpdu.data.deliver.userData.headerCnt = 0;
130 if (submitData.segCount > 1)
131 tpdu.data.deliver.bHeaderInd = true;
135 char buf[MAX_TPDU_DATA_LEN];
137 int addLen = strlen(submitData.destAddress.address);
139 tpdu.data.deliver.originAddress.ton = submitData.destAddress.ton;
140 tpdu.data.deliver.originAddress.npi = submitData.destAddress.npi;
142 memcpy(tpdu.data.deliver.originAddress.address, submitData.destAddress.address, addLen);
143 tpdu.data.deliver.originAddress.address[addLen] = '\0';
145 for (unsigned int segCnt = 0; segCnt < submitData.segCount; segCnt++)
147 tpdu.data.deliver.userData.length = submitData.userData[segCnt].length;
148 memcpy(tpdu.data.deliver.userData.data, submitData.userData[segCnt].data, submitData.userData[segCnt].length);
150 memset(buf, 0x00, sizeof(buf));
152 // Encode SMS-DELIVER TPDU
153 bufLen = SmsPluginTpduCodec::encodeTpdu(&tpdu, buf);
155 // Make Telephony Structure
156 TelSmsData_t simSmsData;
157 memset((void*)&simSmsData, 0x00, sizeof(simSmsData));
160 memcpy((void*)simSmsData.SmsData.szData, buf, bufLen);
162 simSmsData.SmsData.szData[bufLen] = 0;
163 simSmsData.SmsData.MsgLength = bufLen;
166 MSG_DEBUG("Sim Message.");
167 for (int j = 0; j < simSmsData.SmsData.MsgLength; j++)
169 MSG_DEBUG("[%02x]", simSmsData.SmsData.szData[j]);
173 MSG_DEBUG("Read Status [%d]", pMsgInfo->bRead);
175 if (pMsgInfo->bRead == true)
176 simSmsData.MsgStatus = TAPI_NETTEXT_STATUS_READ;
178 simSmsData.MsgStatus = TAPI_NETTEXT_STATUS_UNREAD;
183 ret = tel_write_sms_in_sim(pTapiHandle, &simSmsData, TapiEventSaveSimMsg, NULL);
185 if (ret == TAPI_API_SUCCESS)
187 MSG_DEBUG("######## tel_write_sms_in_sim Success !!!#######");
191 MSG_DEBUG("######## tel_write_sms_in_sim Fail !!! return : [%d] #######", ret);
193 return MSG_ERR_PLUGIN_STORAGE;
196 msg_sim_id_t SimId = 0;
198 bool bResult = false;
200 bResult = getSimEvent(&SimId);
206 MSG_DEBUG("######## Saving Msg was Successful !!! SIM ID : [%d] #######", SimId);
208 usedCnt = MsgSettingGetInt(SIM_USED_COUNT);
212 if (MsgSettingSetInt(SIM_USED_COUNT, usedCnt) != MSG_SUCCESS)
214 MSG_DEBUG("Error to set config data [%s]", SIM_USED_COUNT);
217 pSimIdList->simId[pSimIdList->count] = SimId;
222 MSG_DEBUG("######## Saving Msg was Failed !!! SIM ID : [%d] #######", SimId);
224 return MSG_ERR_PLUGIN_STORAGE;
232 msg_error_t SmsPluginSimMsg::saveClass2Message(const MSG_MESSAGE_INFO_S *pMsgInfo)
237 tpdu.tpduType = SMS_TPDU_DELIVER;
239 // Set SMS TPDU Options
240 setSmsOptions(&(tpdu.data.deliver));
242 // Make SMS_SUBMIT_DATA_S from MSG_REQUEST_INFO_S to get segment count
243 SMS_SUBMIT_DATA_S submitData;
244 SmsPluginTransport::instance()->msgInfoToSubmitData(pMsgInfo, &submitData, &(tpdu.data.deliver.dcs.codingScheme), 0);
246 // Check sim message full.
247 if (checkSimMsgFull(submitData.segCount) == true)
249 MSG_DEBUG("SIM storage is full.");
251 SmsPluginTransport::instance()->sendDeliverReport(MSG_ERR_SIM_STORAGE_FULL);
253 return MSG_ERR_SIM_STORAGE_FULL;
256 // Create TelSmsData_t data
257 TelSmsData_t simSmsData = {0,};
259 memcpy(&simSmsData.SmsData.Sca, &simMsgDataInfo.sca, sizeof(simSmsData.SmsData.Sca));
260 memcpy(&simSmsData.SmsData.szData, &simMsgDataInfo.szData, sizeof(simSmsData.SmsData.szData)-1);
261 simSmsData.SmsData.MsgLength = simMsgDataInfo.msgLength;
263 // Set message status
264 simSmsData.MsgStatus = TAPI_NETTEXT_STATUS_UNREAD;
266 // Save Class 2 Msg in SIM
267 int tapiRet = TAPI_API_SUCCESS;
269 tapiRet = tel_write_sms_in_sim(pTapiHandle, &simSmsData, TapiEventSaveClass2Msg, NULL);
271 if (tapiRet == TAPI_API_SUCCESS)
273 memset(&simMsgInfo, 0x00, sizeof(MSG_MESSAGE_INFO_S));
274 memcpy(&simMsgInfo, pMsgInfo, sizeof(MSG_MESSAGE_INFO_S));
276 MSG_DEBUG("######## tel_write_sms_in_sim Success !!! #######");
280 MSG_DEBUG("######## tel_write_sms_in_sim Fail !!! return : [%d] #######", tapiRet);
282 SmsPluginTransport::instance()->sendDeliverReport(MSG_ERR_STORAGE_ERROR);
284 return MSG_ERR_PLUGIN_STORAGE;
291 void SmsPluginSimMsg::deleteSimMessage(msg_sim_id_t SimMsgId)
293 int tapiRet = TAPI_API_SUCCESS;
295 tapiRet = tel_delete_sms_in_sim(pTapiHandle, (int)SimMsgId, TapiEventDeleteSimMsg, NULL);
297 if (tapiRet == TAPI_API_SUCCESS)
299 MSG_DEBUG("######## tel_delete_sms_in_sim Success !!! #######");
303 THROW(MsgException::SMS_PLG_ERROR, "######## tel_delete_sms_in_sim Fail !!! return : [%d] #######", tapiRet);
306 msg_sim_id_t SimId = 0;
307 bool bResult = false;
309 bResult = getSimEvent(&SimId);
311 int usedCnt = 0, totalCnt = 0;
315 MSG_DEBUG("######## Deleting Msg was Successful !!! SIM ID : [%d] #######", SimId);
317 usedCnt = MsgSettingGetInt(SIM_USED_COUNT);
318 totalCnt = MsgSettingGetInt(SIM_TOTAL_COUNT);
320 if (usedCnt == totalCnt)
322 tapiRet = tel_set_sms_memory_status(pTapiHandle, TAPI_NETTEXT_PDA_MEMORY_STATUS_AVAILABLE, NULL, NULL);
324 if (tapiRet == TAPI_API_SUCCESS)
326 MSG_DEBUG("######## tel_set_sms_memory_status() Success !!! #######");
330 MSG_DEBUG("######## tel_set_sms_memory_status() Success !!! return : [%d] #######", tapiRet);
336 if (MsgSettingSetInt(SIM_USED_COUNT, usedCnt) != MSG_SUCCESS)
338 MSG_DEBUG("Error to set config data [%s]", SIM_USED_COUNT);
343 THROW(MsgException::SMS_PLG_ERROR, "######## Deleting Msg was Failed !!! SIM ID : [%d] #######", SimId);
348 bool SmsPluginSimMsg::checkSimMsgFull(unsigned int SegCnt)
350 int usedCnt = 0, totalCnt = 0;
352 usedCnt = MsgSettingGetInt(SIM_USED_COUNT);
353 totalCnt = MsgSettingGetInt(SIM_TOTAL_COUNT);
355 MSG_DEBUG("Segment Count [%d]", SegCnt);
356 MSG_DEBUG("usedCnt [%d], totalCnt [%d]", usedCnt, totalCnt);
358 if ((usedCnt + (int)SegCnt) <= totalCnt)
365 void SmsPluginSimMsg::setReadStatus(msg_sim_id_t SimMsgId)
367 MSG_DEBUG("Sim Message ID [%d]", SimMsgId);
369 int ret = TAPI_API_SUCCESS;
371 ret = tel_set_sms_message_status(pTapiHandle, (int)SimMsgId, TAPI_NETTEXT_STATUS_READ, TapiEventSetMsgStatus, (void *)&SimMsgId);
373 if (ret == TAPI_API_SUCCESS)
375 MSG_DEBUG("######## tel_set_sms_message_status Success !!! return : %d #######", ret);
379 THROW(MsgException::SMS_PLG_ERROR, "######## tel_set_sms_message_status Fail !!! return : %d #######", ret);
382 msg_sim_id_t SimId = 0;
383 bool bResult = false;
385 bResult = getSimEvent(&SimId);
389 MSG_DEBUG("######## Setting Read Status was Successful !!!, sim id=[%d] #######", SimId);
393 THROW(MsgException::SMS_PLG_ERROR, "######## Setting Read Status was Failed !!! #######");
398 void SmsPluginSimMsg::getSimMsgCount(MSG_SIM_COUNT_S *pSimMsgCnt)
400 int ret = TAPI_API_SUCCESS;
402 ret = tel_get_sms_count(pTapiHandle, TapiEventGetSimMsgCnt, NULL);
404 if (ret == TAPI_API_SUCCESS)
406 MSG_DEBUG("######## tel_get_sms_count() Success !!! #######");
410 THROW(MsgException::SMS_PLG_ERROR, "######## tel_get_sms_count() Fail !!! return : %d #######", ret);
413 if (getSimMsgCntEvent(pSimMsgCnt) == true)
415 MSG_DEBUG("######## Get Sim Msg Count was Successful !!! #######");
419 THROW(MsgException::SMS_PLG_ERROR, "######## Get Sim Msg Count was Failed !!! #######");
424 bool SmsPluginSimMsg::getSimMsg(msg_sim_id_t SimMsgId, MSG_MESSAGE_INFO_S *pMsgInfo)
426 int ret = TAPI_API_SUCCESS;
428 ret = tel_read_sms_in_sim(pTapiHandle, SimMsgId, TapiEventGetSimMsg, NULL);
430 if (ret == TAPI_API_SUCCESS)
432 MSG_DEBUG("######## tel_read_sms_in_sim() Success !!! Sim ID : [%d] #######", SimMsgId);
436 MSG_DEBUG("######## tel_read_sms_in_sim() Fail !!! return : %d #######", ret);
440 if (getSimMsgEvent(pMsgInfo) == true)
442 MSG_DEBUG("######## Get Sim Msg was Successful !!! #######");
446 MSG_DEBUG("######## Get Sim Msg was Failed !!! #######");
454 void SmsPluginSimMsg::setSmsOptions(SMS_DELIVER_S *pDeliver)
456 pDeliver->bMoreMsg = false;
457 pDeliver->bStatusReport = false;
458 pDeliver->bHeaderInd = false;
459 pDeliver->bReplyPath = false;
461 pDeliver->dcs.bCompressed = false;
462 pDeliver->dcs.msgClass = SMS_MSG_CLASS_NONE;
463 pDeliver->dcs.codingGroup = SMS_GROUP_GENERAL;
465 pDeliver->dcs.codingScheme = (SMS_CODING_SCHEME_T)MsgSettingGetInt(SMS_SEND_DCS);
467 MSG_DEBUG("DCS : %d", pDeliver->dcs.codingScheme);
469 pDeliver->pid = SMS_PID_NORMAL;
471 MSG_DEBUG("PID : %d", pDeliver->pid);
475 void SmsPluginSimMsg::convertTimeStamp(const MSG_MESSAGE_INFO_S* pMsgInfo, SMS_DELIVER_S *pDeliver)
480 pDeliver->timeStamp.format = SMS_TIME_ABSOLUTE;
482 // encode absolute time
483 struct tm timeinfo = {0,};
484 gmtime_r(&pMsgInfo->displayTime, &timeinfo);
486 pDeliver->timeStamp.time.absolute.year = timeinfo.tm_year - 100;
487 MSG_DEBUG("pDeliver->timeStamp.time.absolute.year is %d",pDeliver->timeStamp.time.absolute.year);
489 pDeliver->timeStamp.time.absolute.month = timeinfo.tm_mon + 1;
490 MSG_DEBUG("pDeliver->timeStamp.time.absolute.month is %d",pDeliver->timeStamp.time.absolute.month);
492 pDeliver->timeStamp.time.absolute.day = timeinfo.tm_mday;
493 MSG_DEBUG("pDeliver->timeStamp.time.absolute.day is %d",pDeliver->timeStamp.time.absolute.day);
495 pDeliver->timeStamp.time.absolute.hour = timeinfo.tm_hour;
496 MSG_DEBUG("pDeliver->timeStamp.time.absolute.hour is %d",pDeliver->timeStamp.time.absolute.hour);
498 pDeliver->timeStamp.time.absolute.minute = timeinfo.tm_min;
499 MSG_DEBUG("pDeliver->timeStamp.time.absolute.minute is %d",pDeliver->timeStamp.time.absolute.minute);
501 pDeliver->timeStamp.time.absolute.second = timeinfo.tm_sec;
502 MSG_DEBUG("pDeliver->timeStamp.time.absolute.second is %d",pDeliver->timeStamp.time.absolute.second);
504 pDeliver->timeStamp.time.absolute.timeZone = 0;
505 MSG_DEBUG("pDeliver->timeStamp.time.absolute.timeZone is %d",pDeliver->timeStamp.time.absolute.timeZone);
511 void SmsPluginSimMsg::setSimMsgCntEvent(const MSG_SIM_COUNT_S *pSimMsgCnt)
515 MSG_DEBUG("Sim Message Count is %d.", pSimMsgCnt->usedCount);
517 for (int i=0; i < pSimMsgCnt->usedCount; i++)
519 MSG_DEBUG("Sim Message Index is %d.", pSimMsgCnt->indexList[i]);
522 if (MsgSettingSetInt(SIM_USED_COUNT, pSimMsgCnt->usedCount) != MSG_SUCCESS)
524 MSG_DEBUG("Error to set config data [%s]", SIM_USED_COUNT);
527 if (MsgSettingSetInt(SIM_TOTAL_COUNT, (int)pSimMsgCnt->totalCount) != MSG_SUCCESS)
529 MSG_DEBUG("Error to set config data [%s]", SIM_TOTAL_COUNT);
532 memset(&simMsgCnt, 0x00, sizeof(MSG_SIM_COUNT_S));
533 memcpy(&simMsgCnt, pSimMsgCnt, sizeof(MSG_SIM_COUNT_S));
541 bool SmsPluginSimMsg::getSimMsgCntEvent(MSG_SIM_COUNT_S *pSimMsgCnt)
547 ret = cv.timedwait(mx.pMutex(), 10);
551 if (ret == ETIMEDOUT)
553 MSG_DEBUG("WARNING: TAPI callback TIME-OUT");
557 memcpy(pSimMsgCnt, &simMsgCnt, sizeof(MSG_SIM_COUNT_S));
562 void SmsPluginSimMsg::setSimMsgEvent(const MSG_MESSAGE_INFO_S *pMsgInfo, bool bSuccess)
566 bTapiResult = bSuccess;
568 memset(&simMsgInfo, 0x00, sizeof(MSG_MESSAGE_INFO_S));
570 if (bTapiResult == true)
572 MSG_DEBUG("Success to get sim msg - Id : [%d]", pMsgInfo->msgId);
574 memcpy(&simMsgInfo, pMsgInfo, sizeof(MSG_MESSAGE_INFO_S));
583 bool SmsPluginSimMsg::getSimMsgEvent(MSG_MESSAGE_INFO_S *pMsgInfo)
590 ret = cv.timedwait(mx.pMutex(), 10);
594 if (ret == ETIMEDOUT)
596 MSG_DEBUG("WARNING: TAPI callback TIME-OUT");
600 memset(pMsgInfo, 0x00, sizeof(MSG_MESSAGE_INFO_S));
602 if (bTapiResult == true)
604 memcpy(pMsgInfo, &simMsgInfo, sizeof(MSG_MESSAGE_INFO_S));
611 void SmsPluginSimMsg::setSaveSimMsgEvent(int simMsgId, int result)
613 msg_error_t err = MSG_SUCCESS;
617 if (result != TAPI_NETTEXT_SENDSMS_SUCCESS) {
618 if (result == TAPI_NETTEXT_ROUTING_NOT_AVAILABLE)
619 err = MSG_ERR_SIM_STORAGE_FULL;
621 err = MSG_ERR_UNKNOWN;
624 if (err == MSG_SUCCESS)
633 // Send Deliver Report
634 SmsPluginTransport::instance()->sendDeliverReport(err);
639 void SmsPluginSimMsg::setSaveClass2MsgEvent(int simMsgId, int result)
641 msg_error_t err = MSG_SUCCESS;
643 if (result == TAPI_NETTEXT_SENDSMS_SUCCESS && simMsgId >= 0) {
645 simMsgInfo.msgId = simMsgId;
647 err = SmsPluginStorage::instance()->addSimMessage(&simMsgInfo);
649 if (err == MSG_SUCCESS)
651 MSG_DEBUG("addSimMessage() Success !!");
654 err = SmsPluginEventHandler::instance()->callbackMsgIncoming(&simMsgInfo);
656 if (err != MSG_SUCCESS)
658 MSG_DEBUG("callbackMsgIncoming() Error !! [%d]", err);
661 usedCnt = MsgSettingGetInt(SIM_USED_COUNT);
665 if (MsgSettingSetInt(SIM_USED_COUNT, usedCnt) != MSG_SUCCESS)
667 MSG_DEBUG("Error to set config data [%s]", SIM_USED_COUNT);
670 MSG_DEBUG("addMessage() Error !! [%d]", err);
673 if (result == TAPI_NETTEXT_ROUTING_NOT_AVAILABLE)
674 err = MSG_ERR_SIM_STORAGE_FULL;
676 err = MSG_ERR_UNKNOWN;
679 // Send Deliver Report
680 SmsPluginTransport::instance()->sendDeliverReport(err);
684 void SmsPluginSimMsg::setSimEvent(msg_sim_id_t SimId, bool bResult)
689 bTapiResult = bResult;
697 bool SmsPluginSimMsg::getSimEvent(msg_sim_id_t *pSimId)
704 ret = cv.timedwait(mx.pMutex(), 10);
708 if (ret == ETIMEDOUT)
710 MSG_DEBUG("WARNING: TAPI callback TIME-OUT");
716 MSG_DEBUG("Returned SimMsgId is %d.", simMsgId);
721 void SmsPluginSimMsg::setSmsData(const char *sca, const char *szData, int msgLength)
723 MSG_DEBUG("Set SMS data(class2 message)");
725 memset(&simMsgDataInfo, 0x00, sizeof(simMsgDataInfo));
727 memcpy(&simMsgDataInfo.sca, sca, sizeof(simMsgDataInfo.sca)-1);
728 memcpy(&simMsgDataInfo.szData, szData, sizeof(simMsgDataInfo.szData)-1);
729 simMsgDataInfo.msgLength = msgLength;