47e64baa9931bf4d3a2b63f3082363ee54435ee9
[platform/core/messaging/msg-service.git] / plugin / sms_cdma_plugin / SmsCdmaPluginTransport.cpp
1 /*
2  * Copyright (c) 2015 Samsung Electronics Co., Ltd. All rights reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15 */
16
17 #include <errno.h>
18
19 #include "MsgGconfWrapper.h"
20 #include "MsgException.h"
21
22 #include "MsgUtilStorage.h"
23 #include "MsgNotificationWrapper.h"
24
25 #include "SmsCdmaPluginTransport.h"
26 #include "SmsCdmaPluginCodec.h"
27 #include "SmsCdmaPluginEventHandler.h"
28 #include "SmsCdmaPluginCallback.h"
29
30 extern "C" {
31 #include "TapiUtility.h"
32 #include "TelSms.h"
33 #include "TelNetwork.h"
34 #include "ITapiNetText.h"
35 }
36
37 extern struct tapi_handle *pTapiHandle;
38 extern bool isMemAvailable;
39
40
41 /*==================================================================================================
42                                      FUNCTION IMPLEMENTATION
43 ==================================================================================================*/
44
45 SmsPluginTransport* SmsPluginTransport::pInstance = NULL;
46
47
48 SmsPluginTransport::SmsPluginTransport()
49 {
50         msgRef          = 0x00;
51         msgRef8bit      = 0x00;
52         msgRef16bit     = 0x0000;
53
54         msgSeqNum   = 0x00;
55         if (MsgSettingGetInt(MSG_MESSAGE_ID_COUNTER, (int *)&msgSubmitId) != MSG_SUCCESS) {
56                 MSG_INFO("MsgSettingGetInt() is failed");
57         }
58 }
59
60
61 SmsPluginTransport::~SmsPluginTransport()
62 {
63 }
64
65
66 SmsPluginTransport* SmsPluginTransport::instance()
67 {
68         if (!pInstance)
69                 pInstance = new SmsPluginTransport();
70
71         return pInstance;
72 }
73
74
75 unsigned char SmsPluginTransport::getMsgRef()
76 {
77         return msgRef++;
78 }
79
80
81 unsigned char SmsPluginTransport::getSeqNum()
82 {
83         msgSeqNum = ((msgSeqNum + 1) % SMS_SEQ_NUM_MAX);
84
85         return msgSeqNum;
86 }
87
88
89 unsigned char SmsPluginTransport::getSubmitMsgId()
90 {
91         msgSubmitId = ((msgSubmitId + 1) % SMS_MAX_MESSAGE_ID);
92
93         MsgSettingSetInt(MSG_MESSAGE_ID_COUNTER, msgSubmitId);
94
95         return msgSubmitId;
96 }
97
98
99 void SmsPluginTransport::convertMsgInfoToTelesvcMsg(const MSG_MESSAGE_INFO_S *pMsgInfo, sms_trans_msg_s *pTransMsg)
100 {
101         switch (pTransMsg->type) {
102         case SMS_TRANS_P2P_MSG: {
103                 MSG_DEBUG("Convert  MSG_MESSAGE_INFO_S data to SMS_TRANS_MSG_S data.");
104                 sms_trans_p2p_msg_s *pPtpMsg = (sms_trans_p2p_msg_s *)&(pTransMsg->data.p2p_msg);
105
106                 convertMsgInfoToPtp(pMsgInfo, pPtpMsg);
107         }
108                 break;
109         default:
110                 MSG_DEBUG("Error Unsupported Transport Type");
111                 break;
112         }
113 }
114
115
116 void SmsPluginTransport::convertMsgInfoToPtp(const MSG_MESSAGE_INFO_S *pMsgInfo, sms_trans_p2p_msg_s *pPtpMsg)
117 {
118         /* 1. Set Teleservice ID */
119         pPtpMsg->telesvc_id = SMS_TRANS_TELESVC_CMT_95;
120
121         /* 2. Set Service category */
122         pPtpMsg->svc_ctg = SMS_TRANS_SVC_CTG_UNDEFINED;
123
124         /* 3. Convert Address values */
125         pPtpMsg->address.digit_mode = SMS_DIGIT_4BIT_DTMF;
126         pPtpMsg->address.number_mode = SMS_NUMBER_MODE_NONE_DATANETWORK;
127         pPtpMsg->address.number_type = SMS_NUMBER_TYPE_UNKNOWN;
128         pPtpMsg->address.number_plan = SMS_NPI_UNKNOWN;
129         pPtpMsg->address.addr_len = strlen(pMsgInfo->addressList[0].addressVal);
130         strncpy(pPtpMsg->address.szData, pMsgInfo->addressList[0].addressVal, pPtpMsg->address.addr_len);
131
132         if (pMsgInfo->addressList[0].addressVal[0] == '+') {
133                 pPtpMsg->address.digit_mode = SMS_DIGIT_8BIT;
134                 pPtpMsg->address.number_type = SMS_NUMBER_TYPE_INTERNATIONAL;
135         } else {
136                 pPtpMsg->address.number_type = SMS_NUMBER_TYPE_NATIONAL;
137         }
138
139         /* 4. Convert Sub-address values */
140         /* TODO */
141
142         /* 5. Set Reply sequence number. */
143         pPtpMsg->reply_seq = getSeqNum();
144
145         /* convert msgInfo to Teleservice Message */
146         switch (pPtpMsg->telesvc_msg.type) {
147         case SMS_TYPE_SUBMIT:
148                 convertMsgInfoToSubmit(pMsgInfo, &(pPtpMsg->telesvc_msg.data.submit));
149                 break;
150         default:
151                 break;
152         }
153 }
154
155
156 void SmsPluginTransport::convertMsgInfoToSubmit(const MSG_MESSAGE_INFO_S *pMsgInfo, sms_telesvc_submit_s *pSubmit)
157 {
158         if (pSubmit == NULL)
159                 return;
160
161         /* 1. Set msg ID. */
162         pSubmit->msg_id.msg_id = getSubmitMsgId();
163         pSubmit->msg_id.header_ind = false;
164
165         /* 2. Set User Data */
166         unsigned char decodeData[SMS_MAX_USER_DATA_LEN + 1];
167         memset(decodeData, 0x00, sizeof(decodeData));
168
169         MsgTextConvert *textCvt = MsgTextConvert::instance();
170
171         msg_encode_type_t encodeType = MSG_ENCODE_GSM7BIT;
172
173
174         if (pMsgInfo->bTextSms == true) {
175                 if (pMsgInfo->encodeType == MSG_ENCODE_GSM7BIT) {
176                         pSubmit->user_data.encode_type = SMS_ENCODE_GSM7BIT;
177                 } else if (pMsgInfo->encodeType == MSG_ENCODE_8BIT) {
178                         pSubmit->user_data.encode_type = SMS_ENCODE_OCTET;
179                 } else if (pMsgInfo->encodeType == MSG_ENCODE_UCS2) {
180                         pSubmit->user_data.encode_type = SMS_ENCODE_UNICODE;
181                 } else if (pMsgInfo->encodeType == MSG_ENCODE_AUTO) {
182                         textCvt->convertUTF8ToAuto(decodeData, SMS_MAX_USER_DATA_LEN + 1, (unsigned char*)pMsgInfo->msgText, (int)pMsgInfo->dataSize, &encodeType);
183                         if (encodeType == MSG_ENCODE_ASCII7BIT) {
184                                 pSubmit->user_data.encode_type = SMS_ENCODE_7BIT_ASCII;
185                         } else if (encodeType == MSG_ENCODE_8BIT) {
186                                 pSubmit->user_data.encode_type = SMS_ENCODE_OCTET;
187                         } else if (encodeType == MSG_ENCODE_UCS2) {
188                                 pSubmit->user_data.encode_type = SMS_ENCODE_UNICODE;
189                         }
190                 }
191         }
192
193         memset(pSubmit->user_data.user_data, 0x00, sizeof(pSubmit->user_data.user_data));
194         snprintf((char *)pSubmit->user_data.user_data, sizeof(pSubmit->user_data.user_data), "%s", pMsgInfo->msgText);
195         pSubmit->user_data.data_len = pMsgInfo->dataSize;
196
197         MSG_DEBUG("encode type : [%d]", pSubmit->user_data.encode_type);
198
199         /* 3. Set Valid period */
200 #if 0
201         pSubmit->val_period.format = SMS_TIME_ABSOLUTE;
202         pSubmit->val_period.time.abs_time.year = 0;
203         pSubmit->val_period.time.abs_time.month = 0;
204         pSubmit->val_period.time.abs_time.day = 0;
205         pSubmit->val_period.time.abs_time.hours = 0;
206         pSubmit->val_period.time.abs_time.minutes = 0;
207         pSubmit->val_period.time.abs_time.seconds = 0;
208 #else
209         pSubmit->val_period.format = SMS_TIME_RELATIVE;
210         pSubmit->val_period.time.rel_time.rel_time = SMS_REL_TIME_INDEFINITE;
211 #endif
212
213         /* 4. Set Defer valid period */
214         /* TODO */
215
216         /* 5. Set Priority */
217         switch (pMsgInfo->priority) {
218         case MSG_MESSAGE_PRIORITY_HIGH:
219                 pSubmit->priority = SMS_PRIORITY_URGENT;
220                 break;
221         default:
222                 pSubmit->priority = SMS_PRIORITY_NORMAL;
223                 break;
224         }
225
226         /* 6. Set Privacy */
227         pSubmit->privacy = SMS_PRIVACY_NOT_RESTRICTED;
228
229         /* 7. Set Reply option */
230         if (MsgSettingGetBool(SMS_SEND_DELIVERY_REPORT, (bool *)&(pSubmit->reply_opt.deliver_ack_req)) != MSG_SUCCESS)
231                 MSG_INFO("MsgSettingGetBool() is failed");
232
233         /* 8. Set Alert priority */
234         pSubmit->alert_priority = SMS_ALERT_MOBILE_DEFAULT;
235
236         /* 9. Set Language */
237         pSubmit->language = SMS_LAN_UNKNOWN;
238
239         /* 10. Set Callback number */
240         /* TODO :: Set callback number to MSISDN */
241
242         /* 11. Set Multi encode data */
243         /* TODO */
244
245         /* 12. Set Deposit id */
246         /* TODO */
247
248         /* 13. Set Service category program data */
249         /* TODO */
250 }
251
252
253 void SmsPluginTransport::submitRequest(sms_request_info_s *pReqInfo)
254 {
255         int tapiRet = TAPI_API_SUCCESS;
256
257         if (pReqInfo == NULL) {
258                 THROW(MsgException::SMS_PLG_ERROR, "pReqInfo is NULL");
259         }
260
261         /* Get address informations. */
262         MsgDbHandler *dbHandle = getDbHandle();
263         MsgStoGetAddressByMsgId(dbHandle, pReqInfo->msgInfo.msgId, &pReqInfo->msgInfo.nAddressCnt, &pReqInfo->msgInfo.addressList);
264
265         MSG_DEBUG("pReqInfo->msgInfo.nAddressCnt [%d]", pReqInfo->msgInfo.nAddressCnt);
266
267         /* Get MSISDN */
268         char *msisdn = NULL;
269         char keyName[MAX_VCONFKEY_NAME_LEN];
270         int simIndex = 1;
271
272         memset(keyName, 0x00, sizeof(keyName));
273         snprintf(keyName, sizeof(keyName), "%s/%d", MSG_SIM_MSISDN, simIndex);
274
275         if (MsgSettingGetString(keyName, &msisdn) != MSG_SUCCESS) {
276                 MSG_INFO("MsgSettingGetString() is failed");
277         }
278
279         /* Tapi Data Structure */
280         TelSmsDatapackageInfo_t tapi_data_pkg;
281         memset(&tapi_data_pkg, 0x00, sizeof(TelSmsDatapackageInfo_t));
282
283         bool bMoreMsgToSend = false;
284
285         tapi_data_pkg.format = (TelSmsNetType_t)TAPI_NETTEXT_NETTYPE_3GPP2;
286
287         /* convert msg_info to trans_msg */
288         sms_trans_msg_s  trans_msg;
289         memset(&trans_msg, 0x00, sizeof(sms_trans_msg_s));
290
291         trans_msg.type = (sms_trans_msg_type_t)SMS_TRANS_P2P_MSG;
292         trans_msg.data.p2p_msg.telesvc_msg.type = (sms_message_type_t)SMS_TYPE_SUBMIT;
293
294         convertMsgInfoToTelesvcMsg(&pReqInfo->msgInfo, &trans_msg);
295
296         /* encode msg data */
297         unsigned char tel_sms_data[TAPI_NETTEXT_SMDATA_SIZE_MAX+1] = {0, };
298
299         tapi_data_pkg.MsgLength = SmsPluginMsgCodec::instance()->encodeMsg(&trans_msg, tel_sms_data);
300
301         memcpy((void *)tapi_data_pkg.szData, (void *)tel_sms_data, sizeof(tapi_data_pkg.szData));
302
303         MSG_DEBUG("Submit Request TPDU.");
304         char pduDbg[TAPI_NETTEXT_SMDATA_SIZE_MAX*2];
305         memset(pduDbg, 0x00, sizeof(pduDbg));
306
307         for (int i = 0; i < tapi_data_pkg.MsgLength; i++) {
308                 snprintf(pduDbg+(i*2), sizeof(pduDbg)- (i*2), "%02x", tapi_data_pkg.szData[i]);
309         }
310         MSG_DEBUG("Encode PDU= [%s]", pduDbg);
311
312         sms_network_status_t retStatus;
313
314         for (int cnt = 0; cnt < MAX_SMS_SEND_RETRY; ++cnt) {
315                 /* send request */
316                 sms_sent_info_s sent_info;
317                 memset(&sent_info, 0x00, sizeof(sms_sent_info_s));
318                 memcpy(&sent_info.reqInfo, pReqInfo, sizeof(sent_info.reqInfo));
319
320                 sent_info.bLast = true;
321
322                 SmsPluginEventHandler::instance()->SetSentInfo(&sent_info);
323
324                 int svc_type;
325                 tel_get_property_int(pTapiHandle, TAPI_PROP_NETWORK_SERVICE_TYPE, &svc_type);
326
327                 if (svc_type < TAPI_NETWORK_SERVICE_TYPE_2G) {
328                         MSG_DEBUG("Network service is not available : [%d]", svc_type);
329                         SmsPluginEventHandler::instance()->handleSentStatus(MSG_NETWORK_SEND_PENDING);
330                         goto _RETURN_FUNC;
331                 }
332
333                 curStatus = SMS_NETWORK_SENDING;
334
335                 /* Send SMS */
336                 tapiRet = tel_send_sms(pTapiHandle, &tapi_data_pkg, bMoreMsgToSend, TapiEventSentStatus, NULL);
337
338                 if (tapiRet == TAPI_API_SUCCESS) {
339                         MSG_DEBUG("########  tel_send_sms Success !!! return : [%d] #######", tapiRet);
340                 } else {
341                         SmsPluginEventHandler::instance()->handleSentStatus(MSG_NETWORK_SEND_FAIL);
342                         THROW(MsgException::SMS_PLG_ERROR, "########  tel_send_sms Fail !!! return : [%d] #######", tapiRet);
343                 }
344
345                 /* Tizen Validation System */
346                 MSG_SMS_VLD_INFO("%d, SMS Send Start, %s->%s, %s",  pReqInfo->msgInfo.msgId, \
347                                                                                                                                         (msisdn == NULL)?"ME":msisdn, \
348                                                                                                                                         pReqInfo->msgInfo.addressList[0].addressVal, \
349                                                                                                                                         (tapiRet == TAPI_API_SUCCESS)?"Success":"Fail");
350
351                 MSG_SMS_VLD_TXT("%d, [%s]", pReqInfo->msgInfo.msgId, pReqInfo->msgInfo.msgText);
352
353                 retStatus = getNetStatus();
354
355                 if (retStatus != SMS_NETWORK_SEND_FAIL_TEMPORARY)
356                         break;
357         }
358
359         MSG_SMS_VLD_INFO("%d, SMS Send End, %s->%s, %s",  pReqInfo->msgInfo.msgId, \
360                                                                                                                         (msisdn == NULL)?"ME":msisdn, \
361                                                                                                                         pReqInfo->msgInfo.addressList[0].addressVal, \
362                                                                                                                         (retStatus == SMS_NETWORK_SEND_SUCCESS)?"Success":"Fail");
363
364         if (retStatus == SMS_NETWORK_SEND_SUCCESS) {
365                 MSG_DEBUG("########  Msg Sent was Successful !!! #######");
366         } else {
367                 if (retStatus == SMS_NETWORK_SEND_FAIL_TIMEOUT || retStatus == SMS_NETWORK_SEND_FAIL_TEMPORARY
368                         || retStatus == SMS_NETWORK_SEND_FAIL_MANDATORY_INFO_MISSING || retStatus == SMS_NETWORK_SEND_FAIL_FDN_RESTRICED)
369                         SmsPluginEventHandler::instance()->handleSentStatus(MSG_NETWORK_SEND_FAIL);
370
371                 if (retStatus == SMS_NETWORK_SEND_FAIL_FDN_RESTRICED)
372                         MsgInsertTicker("Unable to send the message while Fixed dialling mode is enabled", SMS_FDN_RESTRICTED, true, 0);
373                 else if (retStatus == SMS_NETWORK_SEND_PENDING)
374                         MsgInsertTicker("Unable to send message. It will be sent when service available.", SMS_MESSAGE_SENDING_PENDING, true, 0);
375                 else
376                         MsgInsertTicker("Sending SMS is failed", SMS_MESSAGE_SENDING_FAIL, true, pReqInfo->msgInfo.msgId);
377         }
378
379 _RETURN_FUNC :
380         if (msisdn) {
381                 free(msisdn);
382                 msisdn = NULL;
383         }
384
385         MSG_END();
386
387         return;
388 }
389
390
391 void SmsPluginTransport::sendDeliverReport(msg_error_t err, sms_trans_p2p_msg_s *p_p2p_msg)
392 {
393         MSG_BEGIN();
394
395         int tapiRet = TAPI_API_SUCCESS;
396         TelSmsResponse_t response;
397
398         sms_trans_msg_s  trans_msg;
399         memset(&trans_msg, 0x00, sizeof(sms_trans_msg_s));
400
401         trans_msg.type = (sms_trans_msg_type_t)SMS_TRANS_ACK_MSG;
402
403         if (p_p2p_msg)
404                 memcpy(&(trans_msg.data.ack_msg.address), &(p_p2p_msg->address), sizeof(sms_trans_addr_s));
405
406         sms_trans_cause_code_s  cause_code;
407         memset(&cause_code, 0x00, sizeof(sms_trans_cause_code_s));
408
409         if (p_p2p_msg->reply_seq > 0)
410                 cause_code.reply_seq = p_p2p_msg->reply_seq;
411
412
413         if (err == MSG_SUCCESS) {
414                 cause_code.error_class = SMS_TRANS_ERR_CLASS_NONE;
415
416                 response = TAPI_NETTEXT_SENDSMS_SUCCESS;
417
418                 if (isMemAvailable == false) {
419                         tapiRet = tel_set_sms_memory_status(pTapiHandle, TAPI_NETTEXT_PDA_MEMORY_STATUS_AVAILABLE, TapiEventMemoryStatus, NULL);
420
421                         if (tapiRet == TAPI_API_SUCCESS)
422                                 MSG_DEBUG("########  tel_set_sms_memory_status() Success !!! #######");
423                         else
424                                 MSG_DEBUG("########  tel_set_sms_memory_status() Failed !!! return : [%d] #######", tapiRet);
425                 }
426
427         } else if (err == MSG_ERR_MESSAGE_COUNT_FULL) {
428
429                 cause_code.error_class = SMS_TRANS_ERR_CLASS_TEMPORARY;
430
431                 response = TAPI_NETTEXT_ME_FULL;
432                 /* MsgInsertTicker("Not enough memory. Delete some items.", SMS_MESSAGE_MEMORY_FULL, true, 0); */
433
434                 tapiRet = tel_set_sms_memory_status(pTapiHandle, TAPI_NETTEXT_PDA_MEMORY_STATUS_FULL, TapiEventMemoryStatus, NULL);
435
436                 if (tapiRet == TAPI_API_SUCCESS)
437                         MSG_DEBUG("########  tel_set_sms_memory_status() Success !!! #######");
438                 else
439                         MSG_DEBUG("########  tel_set_sms_memory_status() Failed !!! return : [%d] #######", tapiRet);
440
441         } else if (err == MSG_ERR_UNKNOWN) {
442                 cause_code.error_class = SMS_TRANS_ERR_CLASS_TEMPORARY;
443                 cause_code.cause_code = SMS_CAUSE_CODE_SERVICE_TERMINATION_DENIED;
444
445                 response = TAPI_NETTEXT_SENDSMS_SUCCESS;
446
447         } else if (err == MSG_ERR_INVALID_MSG_TYPE) {
448                 cause_code.error_class = SMS_TRANS_ERR_CLASS_PERMANENT;
449                 cause_code.cause_code = SMS_CAUSE_CODE_INVAILD_TELESERVICE_ID;
450
451                 response = TAPI_NETTEXT_INVALID_MSG;
452         } else {
453                 cause_code.error_class = SMS_TRANS_ERR_CLASS_TEMPORARY;
454                 response = TAPI_NETTEXT_SIM_FULL;
455         }
456
457         memcpy(&(trans_msg.data.ack_msg.cause_code), &(cause_code), sizeof(sms_trans_cause_code_s));
458
459         MSG_DEBUG("err : [%d], response : [%02x]", err, response);
460
461         int bufLen = 0;
462
463         unsigned char buf[512];
464         memset(buf, 0x00, sizeof(buf));
465         bufLen = SmsPluginMsgCodec::encodeMsg(&trans_msg, buf);
466
467
468         MSG_DEBUG("######## DeliverReport tpdu #########");
469         for (int i=0; i < bufLen; i++) {
470                 printf("[%02x] ", buf[i]);
471         }
472         MSG_DEBUG("#################################");
473
474         /* Make Telephony Structure */
475         TelSmsDatapackageInfo_t pkgInfo;
476
477         pkgInfo.format = TAPI_NETTEXT_NETTYPE_3GPP2;
478
479         /* Set TPDU data */
480         memset((void*)pkgInfo.szData, 0x00, sizeof(pkgInfo.szData));
481         memcpy((void*)pkgInfo.szData, buf, bufLen);
482
483         pkgInfo.szData[bufLen] = 0;
484         pkgInfo.MsgLength = bufLen;
485
486
487         /* Send Deliver Report */
488         tapiRet = tel_send_sms_deliver_report(pTapiHandle, &pkgInfo, response, TapiEventDeliveryReportCNF, NULL);
489
490         if (tapiRet == TAPI_API_SUCCESS)
491                 MSG_DEBUG("########  tel_send_sms_deliver_report() Success !!! #######");
492         else
493                 MSG_DEBUG("########  tel_send_sms_deliver_report() Fail !!! return : [%d] #######", tapiRet);
494
495         MSG_END();
496 }
497
498
499 void SmsPluginTransport::setNetStatus(sms_network_status_t sentStatus)
500 {
501         mx.lock();
502         curStatus = sentStatus;
503         cv.signal();
504         mx.unlock();
505 }
506
507
508 sms_network_status_t SmsPluginTransport::getNetStatus()
509 {
510         mx.lock();
511
512         int ret = 0;
513
514         if (curStatus == SMS_NETWORK_SENDING)
515                 ret = cv.timedwait(mx.pMutex(), 125);
516
517         mx.unlock();
518
519         if (ret == ETIMEDOUT) {
520                 MSG_DEBUG("WARNING: SENT STATUS TIME-OUT");
521                 curStatus = SMS_NETWORK_SEND_FAIL_TIMEOUT;
522         }
523
524         return curStatus;
525 }