4 * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Madhavi Akella <madhavi.a@samsung.com>
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
30 #include <core_object.h>
35 #include <user_request.h>
41 #include "common/TelErr.h"
45 /*=============================================================
47 ==============================================================*/
48 #define MAX_GSM_SMS_TPDU_SIZE 244
49 #define MAX_GSM_SMS_MSG_NUM 255
50 #define MAX_GSM_SMS_SERVICE_CENTER_ADDR 12 /* Maximum number of bytes of service center address */
51 #define MAX_GSM_SMS_CBMI_LIST_SIZE 100 /* Maximum number of CBMI list size for CBS 30*2=60 */
52 #define MAX_GSM_SMS_PARAM_RECORD_SIZE 156 /* Maximum number of bytes SMSP Record size (Y + 28), y : 0 ~ 128 */
53 #define MAX_GSM_SMS_STATUS_FILE_SIZE 2 /* Last Used TP-MR + SMS "Memory Cap. Exceeded" Noti Flag */
54 #define TAPI_SIM_SMSP_ADDRESS_LEN 20
56 /*=============================================================
58 ==============================================================*/
59 #define AT_SMS_DEVICE_READY 12 /* AT device ready */
60 #define SMS_DEVICE_READY 1 /* Telephony device ready */
61 #define SMS_DEVICE_NOT_READY 0 /* Telephony device not ready */
63 /*=============================================================
65 ==============================================================*/
66 #define SMS_CBMI_SELECTED_SOME 0x02 /* Some CBMIs are selected */
67 #define SMS_CBMI_SELECTED_ALL 0x01 /* All CBMIs are selected */
69 /*=============================================================
71 ==============================================================*/
72 #define AT_REC_UNREAD 0 /* Received and Unread */
73 #define AT_REC_READ 1 /* Received and Read */
74 #define AT_STO_UNSENT 2 /* Unsent */
75 #define AT_STO_SENT 3 /* Sent */
76 #define AT_ALL 4 /* Unknown */
78 /*=============================================================
80 ==============================================================*/
81 #define AT_MEMORY_AVAILABLE 0 /* Memory Available */
82 #define AT_MEMORY_FULL 1 /* Memory Full */
84 /*=============================================================
85 SIM CRSM SW1 and Sw2 Error definitions */
87 #define AT_SW1_SUCCESS 0x90
88 #define AT_SW2_SUCCESS 0
89 #define AT_SW1_LEN_RESP 0x9F
91 #define AT_MAX_RECORD_LEN 256
92 #define AT_EF_SMS_RECORD_LEN 176
94 /*=============================================================*/
97 /*=========================================================
99 ==============================================================*/
100 #define MAX_SEC_PIN_LEN 8
101 #define MAX_SEC_PUK_LEN 8
102 #define MAX_SEC_PHONE_LOCK_PW_LEN 39 /* Maximum Phone Locking Password Length */
103 #define MAX_SEC_SIM_DATA_STRING 256 /* Maximum Length of the DATA or RESPONSE. Restricted SIM Access, Generic SIM Access Message */
104 #define MAX_SEC_NUM_LOCK_TYPE 8 /* Maximum number of Lock Type used in Lock Information Message */
105 #define MAX_SEC_IMS_AUTH_LEN 512 /* Maximum Length of IMS Authentication Message */
107 /*=============================================================
109 ==============================================================*/
110 #define CR '\r' /* Carriage Return */
112 /*=============================================================
114 ==============================================================*/
115 #define SMS_SWAPBYTES16(x) (((x) & 0xffff0000) | (((x) & 0x0000ff00) >> 8) | (((x) & 0x000000ff) << 8))
117 void print_glib_list_elem(gpointer data, gpointer user_data);
120 gboolean util_byte_to_hex(const char *byte_pdu, char *hex_pdu, int num_bytes);
122 /* gaurav.kalra: For test */
123 void print_glib_list_elem(gpointer data, gpointer user_data)
125 char *item = (char *)data;
126 dbg("item: [%s]", item);
129 /*=============================================================
131 ==============================================================*/
132 static void on_confirmation_sms_message_send(TcorePending *p, gboolean result, void *user_data)
134 dbg("Entered Function. Request message out from queue");
136 dbg("TcorePending: [%p]", p);
137 dbg("result: [%02x]", result);
138 dbg("user_data: [%p]", user_data);
149 dbg("Exiting Function. Nothing to return");
152 /*=============================================================
154 ==============================================================*/
155 static void util_sms_free_memory(void *sms_ptr)
161 dbg("Freeing memory location: [%p]", sms_ptr);
167 err("Invalid memory location. Nothing to do.");
174 static void util_sms_get_length_of_sca(int* nScLength) {
175 if (*nScLength % 2) {
176 *nScLength = (*nScLength / 2) + 1;
178 *nScLength = *nScLength / 2;
185 static int util_sms_decode_smsParameters(unsigned char *incoming, unsigned int length, struct telephony_sms_Params *params)
187 int alpha_id_len = 0;
191 dbg(" RecordLen = %d", length);
193 if(incoming == NULL || params == NULL)
196 alpha_id_len = length -SMS_SMSP_PARAMS_MAX_LEN;
198 if (alpha_id_len > 0)
200 if(alpha_id_len > SMS_SMSP_ALPHA_ID_LEN_MAX)
202 alpha_id_len = SMS_SMSP_ALPHA_ID_LEN_MAX;
205 for(i=0 ; i < alpha_id_len ; i++)
207 if(0xff == incoming[i])
214 memcpy(params->szAlphaId, incoming, i);
216 params->alphaIdLen = i;
218 dbg(" Alpha id length = %d", i);
223 params->alphaIdLen = 0;
224 dbg(" Alpha id length is zero");
227 //dongil01.park - start parse from here.
228 params->paramIndicator = incoming[alpha_id_len];
230 dbg(" Param Indicator = %02x", params->paramIndicator);
232 //dongil01.park(2008/12/26) - DestAddr
233 if((params->paramIndicator & SMSPValidDestAddr) == 0)
235 nOffset = nDestAddrOffset;
237 if(0x00 == incoming[alpha_id_len + nOffset] || 0xff == incoming[alpha_id_len + nOffset])
239 params->tpDestAddr.dialNumLen = 0;
241 dbg("DestAddr Length is 0");
245 if (0 < (int)incoming[alpha_id_len + nOffset])
247 params->tpDestAddr.dialNumLen = (int)(incoming[alpha_id_len + nOffset] - 1);
249 if(params->tpDestAddr.dialNumLen > SMS_SMSP_ADDRESS_LEN)
250 params->tpDestAddr.dialNumLen = SMS_SMSP_ADDRESS_LEN;
254 params->tpDestAddr.dialNumLen = 0;
257 params->tpDestAddr.numPlanId= incoming[alpha_id_len + (++nOffset)] & 0x0f ;
258 params->tpDestAddr.typeOfNum= (incoming[alpha_id_len + nOffset] & 0x70)>>4 ;
260 memcpy(params->tpDestAddr.diallingNum, &incoming[alpha_id_len + (++nOffset)], (params->tpDestAddr.dialNumLen)) ;
262 dbg("Dest TON is %d",params->tpDestAddr.typeOfNum);
263 dbg("Dest NPI is %d",params->tpDestAddr.numPlanId);
264 dbg("Dest Length = %d",params->tpDestAddr.dialNumLen);
265 dbg("Dest Addr = %s",params->tpDestAddr.diallingNum);
270 //dongil01.park(2008/12/26) - SvcAddr
271 if((params->paramIndicator & SMSPValidSvcAddr) == 0)
273 nOffset = nSCAAddrOffset;
275 if(0x00 == (int)incoming[alpha_id_len + nOffset] || 0xff == (int)incoming[alpha_id_len + nOffset])
277 params->tpSvcCntrAddr.dialNumLen = 0;
279 dbg(" SCAddr Length is 0");
283 if (0 < (int)incoming[alpha_id_len + nOffset] )
285 params->tpSvcCntrAddr.dialNumLen = (int)(incoming[alpha_id_len + nOffset] - 1);
287 if(params->tpSvcCntrAddr.dialNumLen > SMS_SMSP_ADDRESS_LEN)
288 params->tpSvcCntrAddr.dialNumLen = SMS_SMSP_ADDRESS_LEN;
290 params->tpSvcCntrAddr.numPlanId= incoming[alpha_id_len + (++nOffset)] & 0x0f ;
291 params->tpSvcCntrAddr.typeOfNum= (incoming[alpha_id_len + nOffset] & 0x70) >>4 ;
293 memcpy(params->tpSvcCntrAddr.diallingNum, &incoming[alpha_id_len + (++nOffset)], (params->tpSvcCntrAddr.dialNumLen));
295 dbg("SCAddr Length = %d ",params->tpSvcCntrAddr.dialNumLen);
296 dbg("SCAddr TON is %d",params->tpSvcCntrAddr.typeOfNum);
297 dbg("SCAddr NPI is %d",params->tpSvcCntrAddr.numPlanId);
299 for(i = 0 ; i < (int)params->tpSvcCntrAddr.dialNumLen ; i ++)
300 dbg("SCAddr = %d [%02x]",i,params->tpSvcCntrAddr.diallingNum[i]);
304 params->tpSvcCntrAddr.dialNumLen = 0;
308 else if ((0x00 < (int)incoming[alpha_id_len +nSCAAddrOffset] && (int)incoming[alpha_id_len +nSCAAddrOffset] <= 12)
309 || 0xff != (int)incoming[alpha_id_len +nSCAAddrOffset])
311 nOffset = nSCAAddrOffset;
313 if(0x00 == (int)incoming[alpha_id_len + nOffset] || 0xff == (int)incoming[alpha_id_len + nOffset])
315 params->tpSvcCntrAddr.dialNumLen = 0;
316 dbg("SCAddr Length is 0");
321 if (0 < (int)incoming[alpha_id_len + nOffset] )
323 params->tpSvcCntrAddr.dialNumLen = (int)(incoming[alpha_id_len + nOffset] - 1);
325 params->tpSvcCntrAddr.dialNumLen = incoming[alpha_id_len + nOffset] -1;
327 if(params->tpSvcCntrAddr.dialNumLen > SMS_SMSP_ADDRESS_LEN)
328 params->tpSvcCntrAddr.dialNumLen = SMS_SMSP_ADDRESS_LEN;
330 params->tpSvcCntrAddr.numPlanId= incoming[alpha_id_len + (++nOffset)] & 0x0f ;
331 params->tpSvcCntrAddr.typeOfNum= (incoming[alpha_id_len + nOffset] & 0x70) >>4 ;
333 memcpy(params->tpSvcCntrAddr.diallingNum, &incoming[alpha_id_len + (++nOffset)],
334 (params->tpSvcCntrAddr.dialNumLen)) ;
336 dbg("SCAddr Length = %d ",params->tpSvcCntrAddr.dialNumLen);
337 dbg("SCAddr TON is %d",params->tpSvcCntrAddr.typeOfNum);
338 dbg("SCAddr NPI is %d",params->tpSvcCntrAddr.numPlanId);
340 for(i = 0 ; i < (int)params->tpSvcCntrAddr.dialNumLen ; i ++)
341 dbg("SCAddr = %d [%02x]",i,params->tpSvcCntrAddr.diallingNum[i]);
345 params->tpSvcCntrAddr.dialNumLen = 0;
351 if((params->paramIndicator & SMSPValidPID) == 0 && (alpha_id_len + nPIDOffset) < MAX_GSM_SMS_PARAM_RECORD_SIZE)
353 params->tpProtocolId = incoming[alpha_id_len + nPIDOffset];
355 if((params->paramIndicator & SMSPValidDCS) == 0 && (alpha_id_len + nDCSOffset) < MAX_GSM_SMS_PARAM_RECORD_SIZE)
357 params->tpDataCodingScheme = incoming[alpha_id_len + nDCSOffset];
359 if((params->paramIndicator & SMSPValidVP) == 0 && (alpha_id_len + nVPOffset) < MAX_GSM_SMS_PARAM_RECORD_SIZE)
361 params->tpValidityPeriod = incoming[alpha_id_len + nVPOffset];
364 dbg(" Alpha Id(Len) = %d",(int)params->alphaIdLen);
366 for (i=0; i< (int)params->alphaIdLen ; i++)
368 dbg(" Alpha Id = [%d] [%c]",i,params->szAlphaId[i]);
370 dbg(" PID = %d",params->tpProtocolId);
371 dbg(" DCS = %d",params->tpDataCodingScheme);
372 dbg(" VP = %d",params->tpValidityPeriod);
378 /*=============================================================
380 ==============================================================*/
381 static gboolean on_event_sms_ready_status(CoreObject *o, const void *event_info, void *user_data)
383 struct tnoti_sms_ready_status readyStatusInfo = {0,};
385 GSList* tokens = NULL;
386 GSList* lines = NULL;
388 //CoreObject *o = NULL;
390 int rtn = -1 , status = 0;
392 dbg(" Func Entrance");
394 lines = (GSList *)event_info;
395 if (1 != g_slist_length(lines))
397 dbg("unsolicited msg but multiple line");
400 line = (char *)(lines->data);
402 dbg(" Func Entrance");
407 dbg("noti line is %s", line);
408 tokens = tcore_at_tok_new(line);
409 pResp = g_slist_nth_data(tokens, 0);
411 status = atoi(pResp);
419 if (status == AT_SMS_DEVICE_READY)
421 readyStatusInfo.status = SMS_DEVICE_READY;
422 tcore_sms_set_ready_status(o, readyStatusInfo.status);
423 dbg("SMS Ready status = [%s]", readyStatusInfo.status ? "TRUE" : "FALSE");
424 rtn = tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_SMS_DEVICE_READY, sizeof(struct tnoti_sms_ready_status), &readyStatusInfo);
425 dbg(" Return value [%d]",rtn);
429 readyStatusInfo.status = SMS_DEVICE_NOT_READY;
434 tcore_at_tok_free(tokens);
438 static gboolean on_event_sms_incom_msg(CoreObject *o, const void *event_info, void *user_data)
441 GSList *tokens = NULL;
442 GSList *lines = NULL;
445 unsigned char *bytePDU = NULL;
446 struct tnoti_sms_umts_msg gsmMsgInfo;
448 dbg("Entered Function");
450 lines = (GSList *)event_info;
451 memset(&gsmMsgInfo, 0x00, sizeof(struct tnoti_sms_umts_msg));
453 if(2 != g_slist_length(lines))
455 err("Invalid number of lines for +CMT. Must be 2");
459 line = (char *)g_slist_nth_data(lines, 0); /* Fetch Line 1 */
461 dbg("Line 1: [%s]", line);
465 err("Line 1 is invalid");
469 tokens = tcore_at_tok_new(line); /* Split Line 1 into tokens */
471 dbg("Alpha ID: [%02x]", g_slist_nth_data(tokens, 0)); /* 0: Alpha ID */
473 length = atoi((char *)g_slist_nth_data(tokens, 1));
475 dbg("Length: [%d]", length); /* 1: PDU Length */
477 gsmMsgInfo.msgInfo.msgLength = length;
479 line = (char *)g_slist_nth_data(lines, 1); /* Fetch Line 2 */
481 dbg("Line 2: [%s]", line);
485 err("Line 2 is invalid");
489 /* Convert to Bytes */
490 bytePDU = (unsigned char *)util_hexStringToBytes(line);
494 err("bytePDU is NULL");
498 memcpy(gsmMsgInfo.msgInfo.sca, bytePDU, (strlen(line)/2 - length));
499 memcpy(gsmMsgInfo.msgInfo.tpduData, &bytePDU[(strlen(line)/2 - length)], length);
501 util_hex_dump(" ", strlen(line)/2, bytePDU);
502 util_hex_dump(" ", (strlen(line)/2 - length), gsmMsgInfo.msgInfo.sca);
503 util_hex_dump(" ", length, gsmMsgInfo.msgInfo.tpduData);
505 rtn = tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_SMS_INCOM_MSG, sizeof(struct tnoti_sms_umts_msg), &gsmMsgInfo);
510 static gboolean on_event_sms_memory_status(CoreObject *o, const void *event_info, void *user_data)
512 struct tnoti_sms_memory_status memStatusInfo = {0,};
514 int rtn = -1 ,memoryStatus = -1;
517 char *line = NULL , *pResp = NULL;
519 lines = (GSList *)event_info;
520 if (1 != g_slist_length(lines))
522 dbg("unsolicited msg but multiple line");
525 line = (char*)(lines->data);
528 dbg(" Func Entrance");
533 tokens = tcore_at_tok_new(line);
534 pResp = g_slist_nth_data(tokens, 0);
538 memoryStatus = atoi(pResp);
539 dbg("memoryStatus is %d",memoryStatus);
548 if (memoryStatus == 0) //SIM Full condition
550 memStatusInfo.status = SMS_PHONE_MEMORY_STATUS_FULL;
554 dbg("memory status - %d",memStatusInfo.status);
556 rtn = tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_SMS_MEMORY_STATUS, sizeof(struct tnoti_sms_memory_status), &memStatusInfo);
557 dbg(" Return value [%d]",rtn);
562 static gboolean on_event_sms_cb_incom_msg(CoreObject *o, const void *event_info, void *user_data)
564 //+CBM: <length><CR><LF><pdu>
566 struct tnoti_sms_cellBroadcast_msg cbMsgInfo;
568 int rtn = -1 , length = 0;
569 char * line = NULL, *pdu = NULL, *pResp = NULL;
570 GSList *tokens = NULL;
571 GSList *lines = NULL;
573 dbg(" Func Entrance");
575 lines = (GSList *)event_info;
577 memset(&cbMsgInfo, 0, sizeof(struct tnoti_sms_cellBroadcast_msg));
579 line = (char *)(lines->data);
584 dbg("Noti line is %s",line);
585 pResp = g_slist_nth_data(tokens, 0);
588 length = atoi(pResp);
591 dbg("token 0 is null");
593 pdu = g_slist_nth_data(tokens, 3);
596 cbMsgInfo.cbMsg.length = length;
597 cbMsgInfo.cbMsg.cbMsgType = SMS_CB_MSG_CBS ; //TODO - Need to check for other CB types
599 dbg("CB Msg LENGTH [%2x](((( %d ))))", length, cbMsgInfo.cbMsg.length);
601 if ( (cbMsgInfo.cbMsg.length >0) && ((SMS_CB_PAGE_SIZE_MAX +1) > cbMsgInfo.cbMsg.length))
603 memcpy(cbMsgInfo.cbMsg.msgData, (char*)pdu, cbMsgInfo.cbMsg.length);
604 rtn = tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_SMS_CB_INCOM_MSG, sizeof(struct tnoti_sms_cellBroadcast_msg), &cbMsgInfo);
608 dbg("Invalid Message Length");
614 dbg("Recieved NULL pdu");
623 dbg(" Return value [%d]",rtn);
628 /*=============================================================
630 ==============================================================*/
631 static void on_response_sms_delete_msg(TcorePending *p, int data_len, const void *data, void *user_data)
633 struct tresp_sms_delete_msg delMsgInfo = {0,};
634 UserRequest *ur = NULL;
635 const TcoreATResponse *atResp = data;
638 int *index = (int *)user_data;
640 dbg(" Func Entrance");
642 ur = tcore_pending_ref_user_request(p);
646 delMsgInfo.index = *index;
647 delMsgInfo.result = SMS_SENDSMS_SUCCESS;
653 delMsgInfo.index = *index;
654 delMsgInfo.result = SMS_DEVICE_FAILURE;
658 rtn = tcore_user_request_send_response(ur, TRESP_SMS_DELETE_MSG, sizeof(struct tresp_sms_delete_msg), &delMsgInfo);
663 static void on_response_sms_save_msg(TcorePending *p, int data_len, const void *data, void *user_data)
665 struct tresp_sms_save_msg saveMsgInfo = {0,};
666 UserRequest *ur = NULL;
667 const TcoreATResponse *atResp = data;
668 GSList *tokens = NULL;
673 ur = tcore_pending_ref_user_request(p);
679 line = (char *)atResp->lines->data;
680 tokens = tcore_at_tok_new(line);
681 pResp = g_slist_nth_data(tokens, 0);
685 saveMsgInfo.index = (atoi(pResp) - 1); /* IMC index starts from 1 */
686 saveMsgInfo.result = SMS_SENDSMS_SUCCESS;
691 saveMsgInfo.index = -1;
692 saveMsgInfo.result = SMS_DEVICE_FAILURE;
700 saveMsgInfo.index = -1;
701 saveMsgInfo.result = SMS_DEVICE_FAILURE;
704 rtn = tcore_user_request_send_response(ur, TRESP_SMS_SAVE_MSG, sizeof(struct tresp_sms_save_msg), &saveMsgInfo);
705 dbg("Return value [%d]", rtn);
710 static void on_response_sms_deliver_rpt_cnf(TcorePending *p, int data_len, const void *data, void *user_data)
713 struct tresp_sms_set_delivery_report deliverReportInfo = {0,};
714 UserRequest *ur = NULL;
715 const TcoreATResponse *atResp = data;
717 char *line = NULL , *pResp = NULL;
720 dbg(" Func Entrance");
728 line = (char*)atResp->lines->data;
729 tokens = tcore_at_tok_new(line);
730 pResp = g_slist_nth_data(tokens, 0);
733 deliverReportInfo.result = SMS_SENDSMS_SUCCESS;
738 deliverReportInfo.result = SMS_DEVICE_FAILURE;
743 deliverReportInfo.result = SMS_DEVICE_FAILURE;
751 rtn = tcore_user_request_send_response(ur, TRESP_SMS_SET_DELIVERY_REPORT, sizeof(struct tresp_sms_set_delivery_report), &deliverReportInfo);
753 dbg(" Return value [%d]",rtn);
760 static void on_response_send_umts_msg(TcorePending *pending, int data_len, const void *data, void *user_data)
762 const TcoreATResponse *at_response = data;
763 struct tresp_sms_send_umts_msg resp_umts;
764 UserRequest *user_req = NULL;
767 GSList *tokens = NULL;
768 char *gslist_line = NULL, *line_token = NULL;
772 user_req = tcore_pending_ref_user_request(pending);
776 err("No user request");
782 memset(&resp_umts, 0x00, sizeof(resp_umts));
783 resp_umts.result = SMS_DEVICE_FAILURE;
785 if(at_response->success > 0) //success
788 if(at_response->lines) //lines present in at_response
790 gslist_line = (char *)at_response->lines->data;
791 dbg("gslist_line: [%s]", gslist_line);
793 tokens = tcore_at_tok_new(gslist_line); //extract tokens
795 line_token = g_slist_nth_data(tokens, 0);
796 if (line_token != NULL)
798 msg_ref = atoi(line_token);
799 dbg("Message Reference: [%d]", msg_ref);
801 resp_umts.result = SMS_SENDSMS_SUCCESS;
805 dbg("No Message Reference received");
808 else //no lines in at_response
818 tcore_user_request_send_response(user_req, TRESP_SMS_SEND_UMTS_MSG, sizeof(resp_umts), &resp_umts);
824 static void on_response_read_msg(TcorePending *pending, int data_len, const void *data, void *user_data)
826 const TcoreATResponse *at_response = data;
827 struct tresp_sms_read_msg resp_read_msg;
828 UserRequest *user_req = NULL;
831 char *gslist_line = NULL, *line_token = NULL, *byte_pdu = NULL, *hex_pdu = NULL;
833 int msg_status = 0, alpha_id = 0, pdu_len = 0;
834 int index = (int)(uintptr_t)user_data;
837 dbg("index: [%d]", index);
838 dbg("lines: [%p]", at_response->lines);
839 g_slist_foreach(at_response->lines, print_glib_list_elem, NULL); //for debug log
841 user_req = tcore_pending_ref_user_request(pending);
842 if (NULL == user_req)
844 err("No user request");
850 memset(&resp_read_msg, 0x00, sizeof(resp_read_msg));
852 if (at_response->success > 0)
855 if (at_response->lines)
858 gslist_line = (char *)at_response->lines->data;
860 dbg("gslist_line: [%s]", gslist_line);
862 tokens = tcore_at_tok_new(gslist_line);
863 dbg("Number of tokens: [%d]", g_slist_length(tokens));
864 g_slist_foreach(tokens, print_glib_list_elem, NULL); //for debug log
866 line_token = g_slist_nth_data(tokens, 0); //First Token: Message Status
867 if (line_token != NULL)
869 msg_status = atoi(line_token);
870 dbg("msg_status is %d",msg_status);
874 resp_read_msg.dataInfo.msgStatus = SMS_STATUS_UNREAD;
878 resp_read_msg.dataInfo.msgStatus = SMS_STATUS_READ;
882 resp_read_msg.dataInfo.msgStatus = SMS_STATUS_UNSENT;
886 resp_read_msg.dataInfo.msgStatus = SMS_STATUS_SENT;
889 case AT_ALL: //Fall Through
890 default: //Fall Through
891 resp_read_msg.dataInfo.msgStatus = SMS_STATUS_RESERVED;
896 line_token = g_slist_nth_data(tokens, 1); //Second Token: AlphaID
897 if (line_token != NULL)
899 alpha_id = atoi(line_token);
900 dbg("AlphaID: [%d]", alpha_id);
903 line_token = g_slist_nth_data(tokens, 2); //Third Token: Length
904 if (line_token != NULL)
906 pdu_len = atoi(line_token);
907 dbg("Length: [%d]", pdu_len);
911 gslist_line = (char *)at_response->lines->next->data;
913 dbg("gslist_line: [%s]", gslist_line);
915 tokens = tcore_at_tok_new(gslist_line);
916 dbg("Number of tokens: [%d]", g_slist_length(tokens));
917 g_slist_foreach(tokens, print_glib_list_elem, NULL); //for debug log
919 hex_pdu = g_slist_nth_data(tokens, 0); //Fetch SMS PDU
922 util_hex_dump(" ", sizeof(hex_pdu), (void *)hex_pdu);
924 byte_pdu = util_hexStringToBytes(hex_pdu);
926 sca_length = (int)byte_pdu[0];
928 resp_read_msg.dataInfo.simIndex = index; //Retrieving index stored as user_data
932 dbg("SCA Length is 0");
934 resp_read_msg.dataInfo.smsData.msgLength = pdu_len - (sca_length+1);
935 dbg("msgLength: [%d]", resp_read_msg.dataInfo.smsData.msgLength);
937 if ((resp_read_msg.dataInfo.smsData.msgLength > 0)
938 && (resp_read_msg.dataInfo.smsData.msgLength <= 0xff))
940 memset(resp_read_msg.dataInfo.smsData.sca, 0, TAPI_SIM_SMSP_ADDRESS_LEN);
941 memcpy(resp_read_msg.dataInfo.smsData.tpduData, &byte_pdu[2], resp_read_msg.dataInfo.smsData.msgLength);
943 resp_read_msg.result = SMS_SUCCESS;
947 err("Invalid Message Length");
949 resp_read_msg.result = SMS_INVALID_PARAMETER_FORMAT;
954 dbg("SCA Length is not 0");
956 resp_read_msg.dataInfo.smsData.msgLength = (pdu_len - (sca_length+1));
957 dbg("msgLength: [%d]", resp_read_msg.dataInfo.smsData.msgLength);
959 if ((resp_read_msg.dataInfo.smsData.msgLength > 0)
960 && (resp_read_msg.dataInfo.smsData.msgLength <= 0xff))
962 memcpy(resp_read_msg.dataInfo.smsData.sca, (char *)byte_pdu, (sca_length+1));
963 memcpy(resp_read_msg.dataInfo.smsData.tpduData, &byte_pdu[sca_length+1], resp_read_msg.dataInfo.smsData.msgLength);
965 util_hex_dump(" ", SMS_SMSP_ADDRESS_LEN, (void *)resp_read_msg.dataInfo.smsData.sca);
966 util_hex_dump(" ", (SMS_SMDATA_SIZE_MAX + 1), (void *)resp_read_msg.dataInfo.smsData.tpduData);
967 util_hex_dump(" ", sizeof(byte_pdu), (void *)byte_pdu);
969 resp_read_msg.result = SMS_SUCCESS;
973 err("Invalid Message Length");
975 resp_read_msg.result = SMS_INVALID_PARAMETER_FORMAT;
982 resp_read_msg.result = SMS_PHONE_FAILURE;
988 resp_read_msg.result = SMS_PHONE_FAILURE;
994 resp_read_msg.result = SMS_PHONE_FAILURE;
997 tcore_user_request_send_response(user_req, TRESP_SMS_READ_MSG, sizeof(resp_read_msg), &resp_read_msg);
1003 static void on_response_get_msg_indices(TcorePending *pending, int data_len, const void *data, void *user_data)
1005 const TcoreATResponse *at_response = data;
1006 struct tresp_sms_get_storedMsgCnt resp_stored_msg_cnt;
1007 UserRequest *user_req = NULL;
1008 struct tresp_sms_get_storedMsgCnt *resp_stored_msg_cnt_prev = NULL;
1010 GSList *tokens = NULL;
1011 char *gslist_line = NULL, *line_token = NULL;
1012 int gslist_line_count = 0, ctr_loop = 0;
1016 resp_stored_msg_cnt_prev = (struct tresp_sms_get_storedMsgCnt *)user_data;
1017 user_req = tcore_pending_ref_user_request(pending);
1019 memset(&resp_stored_msg_cnt, 0x00, sizeof(resp_stored_msg_cnt));
1020 resp_stored_msg_cnt.result = SMS_DEVICE_FAILURE;
1022 if (at_response->success)
1025 if(at_response->lines)
1027 gslist_line_count = g_slist_length(at_response->lines);
1029 if (gslist_line_count > SMS_GSM_SMS_MSG_NUM_MAX)
1030 gslist_line_count = SMS_GSM_SMS_MSG_NUM_MAX;
1032 dbg("Number of lines: [%d]", gslist_line_count);
1033 g_slist_foreach(at_response->lines, print_glib_list_elem, NULL); //for debug log
1035 for (ctr_loop = 0; ctr_loop < gslist_line_count ; ctr_loop++)
1037 gslist_line = (char *)g_slist_nth_data(at_response->lines, ctr_loop); /* Fetch Line i */
1039 dbg("gslist_line [%d] is [%s]", ctr_loop, gslist_line);
1041 if (NULL != gslist_line)
1043 tokens = tcore_at_tok_new(gslist_line);
1045 g_slist_foreach(tokens, print_glib_list_elem, NULL); //for debug log
1047 line_token = g_slist_nth_data(tokens, 0);
1048 if (NULL != line_token)
1050 resp_stored_msg_cnt.storedMsgCnt.indexList[ctr_loop] = atoi(line_token);
1054 dbg("line_token of gslist_line [%d] is NULL", ctr_loop);
1057 tcore_at_tok_free(tokens);
1061 dbg("gslist_line [%d] is NULL", ctr_loop);
1069 if(resp_stored_msg_cnt_prev->storedMsgCnt.usedCount == 0) //Check if used count is zero
1071 resp_stored_msg_cnt.result = SMS_SENDSMS_SUCCESS;
1077 dbg("Respnose NOK");
1080 resp_stored_msg_cnt.storedMsgCnt.totalCount = resp_stored_msg_cnt_prev->storedMsgCnt.totalCount;
1081 resp_stored_msg_cnt.storedMsgCnt.usedCount = resp_stored_msg_cnt_prev->storedMsgCnt.usedCount;
1083 util_sms_free_memory(resp_stored_msg_cnt_prev);
1085 dbg("total: [%d], used: [%d], result: [%d]", resp_stored_msg_cnt.storedMsgCnt.totalCount, resp_stored_msg_cnt.storedMsgCnt.usedCount, resp_stored_msg_cnt.result);
1086 for(ctr_loop = 0; ctr_loop < gslist_line_count; ctr_loop++)
1088 dbg("index: [%d]", resp_stored_msg_cnt.storedMsgCnt.indexList[ctr_loop]);
1091 tcore_user_request_send_response(user_req, TRESP_SMS_GET_STORED_MSG_COUNT, sizeof(resp_stored_msg_cnt), &resp_stored_msg_cnt);
1097 static void on_response_get_stored_msg_cnt(TcorePending *pending, int data_len, const void *data, void *user_data)
1099 UserRequest *ur = NULL, *ur_dup = NULL;
1100 struct tresp_sms_get_storedMsgCnt *respStoredMsgCnt = NULL;
1101 const TcoreATResponse *atResp = data;
1102 GSList *tokens=NULL;
1103 char *line = NULL , *pResp = NULL , *cmd_str = NULL;
1104 TcoreATRequest *atReq = NULL;
1105 int usedCnt = 0, totalCnt = 0, result = 0;
1107 TcorePending *pending_new = NULL;
1108 CoreObject *o = NULL;
1112 respStoredMsgCnt = malloc(sizeof(struct tresp_sms_get_storedMsgCnt));
1114 ur = tcore_pending_ref_user_request(pending);
1115 ur_dup = tcore_user_request_ref(ur);
1116 o = tcore_pending_ref_core_object(pending);
1118 if (atResp->success > 0)
1121 if(NULL != atResp->lines)
1123 line = (char *)atResp->lines->data;
1124 dbg("line is %s",line);
1126 tokens = tcore_at_tok_new(line);
1127 pResp = g_slist_nth_data(tokens, 0);
1131 usedCnt =atoi(pResp);
1132 dbg("used cnt is %d",usedCnt);
1135 pResp = g_slist_nth_data(tokens, 1);
1138 totalCnt =atoi(pResp);
1139 result = SMS_SENDSMS_SUCCESS;
1141 respStoredMsgCnt->storedMsgCnt.usedCount = usedCnt;
1142 respStoredMsgCnt->storedMsgCnt.totalCount = totalCnt;
1143 respStoredMsgCnt->result = result;
1145 dbg("used %d, total %d, result %d",usedCnt, totalCnt,result);
1147 pending_new = tcore_pending_new(o, 0);
1148 //Get all messages information
1149 cmd_str = g_strdup_printf("AT+CMGL=4");
1150 atReq = tcore_at_request_new((const char *)cmd_str, "+CMGL", TCORE_AT_MULTILINE);
1152 dbg("cmd str is %s",cmd_str);
1154 tcore_pending_set_request_data(pending_new, 0,atReq);
1155 tcore_pending_set_response_callback(pending_new, on_response_get_msg_indices, (void *)respStoredMsgCnt);
1156 tcore_pending_link_user_request(pending_new, ur_dup);
1157 tcore_pending_set_send_callback(pending_new, on_confirmation_sms_message_send, NULL);
1158 tcore_hal_send_request(tcore_object_get_hal(o), pending_new);
1169 result = SMS_DEVICE_FAILURE;
1173 err("Response NOK");
1179 static void on_response_get_sca(TcorePending *pending, int data_len, const void *data, void *user_data)
1181 const TcoreATResponse *at_response = data;
1182 struct tresp_sms_get_sca respGetSca;
1183 UserRequest *user_req = NULL;
1185 GSList *tokens = NULL;
1186 char *gslist_line = NULL, *sca_addr = NULL, *sca_toa = NULL;
1190 memset(&respGetSca, 0, sizeof(respGetSca));
1191 respGetSca.result = SMS_DEVICE_FAILURE;
1193 user_req = tcore_pending_ref_user_request(pending);
1195 if (at_response->success)
1198 if(at_response->lines)
1200 gslist_line = (char *)at_response->lines->data;
1202 tokens = tcore_at_tok_new(gslist_line);
1203 sca_addr = g_slist_nth_data(tokens, 0);
1204 sca_toa = g_slist_nth_data(tokens, 1);
1206 if ((NULL != sca_addr)
1207 && (NULL != sca_toa))
1209 dbg("sca_addr: [%s]. sca_toa: [%s]", sca_addr, sca_toa);
1211 respGetSca.scaAddress.dialNumLen = strlen(sca_addr);
1213 if(145 == atoi(sca_toa))
1215 respGetSca.scaAddress.typeOfNum = SIM_TON_INTERNATIONAL;
1219 respGetSca.scaAddress.typeOfNum = SIM_TON_NATIONAL;
1222 respGetSca.scaAddress.numPlanId = 0;
1224 memcpy(respGetSca.scaAddress.diallingNum, sca_addr, strlen(sca_addr));
1226 dbg("len [%d], sca_addr [%s], TON [%d], NPI [%d]", respGetSca.scaAddress.dialNumLen, respGetSca.scaAddress.diallingNum, respGetSca.scaAddress.typeOfNum, respGetSca.scaAddress.numPlanId);
1228 respGetSca.result = SMS_SENDSMS_SUCCESS;
1232 err("sca_addr OR sca_toa NULL");
1242 dbg("Response NOK");
1245 tcore_user_request_send_response(user_req, TRESP_SMS_GET_SCA, sizeof(respGetSca), &respGetSca);
1251 static void on_response_set_sca(TcorePending *pending, int data_len, const void *data, void *user_data)
1254 Response is expected in this format
1260 //CoreObject *obj = user_data;
1262 //copies the AT response data to resp
1263 const TcoreATResponse *atResp = data;
1264 struct tresp_sms_set_sca respSetSca;
1266 memset(&respSetSca, 0, sizeof(struct tresp_sms_set_sca));
1268 ur = tcore_pending_ref_user_request(pending);
1271 dbg("no user_request");
1275 if (atResp->success >0)
1278 respSetSca.result = SMS_SUCCESS;
1282 dbg("RESPONSE NOK");
1283 respSetSca.result = SMS_DEVICE_FAILURE;
1286 tcore_user_request_send_response(ur, TRESP_SMS_SET_SCA, sizeof(struct tresp_sms_set_sca), &respSetSca);
1291 static void on_response_get_cb_config(TcorePending *p, int data_len, const void *data, void *user_data)
1294 struct tresp_sms_get_cb_config respGetCbConfig;
1295 const TcoreATResponse *atResp = data;
1296 GSList *tokens=NULL;
1299 char *mid = NULL, *pResp = NULL, *line = NULL, *res = NULL;
1302 memset(&respGetCbConfig, 0, sizeof(struct tresp_sms_get_cb_config));
1303 respGetCbConfig.result = SMS_DEVICE_FAILURE;
1305 ur = tcore_pending_ref_user_request(p);
1308 dbg("no user_request");
1312 if (atResp->success)
1317 line = (char*)atResp->lines->data;
1320 dbg("line is %s",line);
1321 tokens = tcore_at_tok_new(line);
1322 pResp = g_slist_nth_data(tokens, 0);
1326 respGetCbConfig.cbConfig.bCBEnabled = mode;
1328 respGetCbConfig.result = SMS_SENDSMS_SUCCESS;
1330 pResp = g_slist_nth_data(tokens, 1);
1333 mid = strtok(pResp, delim); i = 0;
1334 while( res != NULL )
1336 res = strtok( NULL, delim );
1337 dbg("mid is %s%s\n", mid,res);
1342 respGetCbConfig.cbConfig.msgIDs[i] = atoi(res);
1348 respGetCbConfig.cbConfig.msgIdCount = i;
1350 //dcs = g_slist_nth_data(tokens, 2); DCS not needed by telephony
1354 dbg("line is NULL");
1359 dbg("atresp->lines is NULL");
1364 dbg("RESPONSE NOK");
1367 tcore_user_request_send_response(ur, TRESP_SMS_GET_CB_CONFIG, sizeof(struct tresp_sms_get_cb_config), &respGetCbConfig);
1372 static void on_response_set_cb_config(TcorePending *pending, int data_len, const void *data, void *user_data)
1375 Response is expected in this format
1382 const TcoreATResponse *resp = data;
1384 const char *line = NULL;
1385 GSList *tokens=NULL;
1387 struct tresp_sms_set_cb_config respSetCbConfig = {0,};
1389 memset(&respSetCbConfig, 0, sizeof(struct tresp_sms_set_cb_config));
1391 ur = tcore_pending_ref_user_request(pending);
1392 respSetCbConfig.result = SMS_SENDSMS_SUCCESS;
1394 if(resp->success > 0)
1401 dbg("RESPONSE NOK");
1402 line = (const char*)resp->final_response;
1403 tokens = tcore_at_tok_new(line);
1405 if (g_slist_length(tokens) < 1) {
1406 dbg("err cause not specified or string corrupted");
1407 respSetCbConfig.result = SMS_DEVICE_FAILURE;
1411 response = atoi(g_slist_nth_data(tokens, 0));
1412 /* TODO: CMEE error mapping is required. */
1413 respSetCbConfig.result = SMS_DEVICE_FAILURE;
1418 dbg("no user_request");
1422 tcore_user_request_send_response(ur, TRESP_SMS_SET_CB_CONFIG, sizeof(struct tresp_sms_set_cb_config), &respSetCbConfig);
1427 static void on_response_set_mem_status(TcorePending *p, int data_len, const void *data, void *user_data)
1430 struct tresp_sms_set_mem_status respSetMemStatus = {0,};
1431 const TcoreATResponse *resp = data;
1433 memset(&respSetMemStatus, 0, sizeof(struct tresp_sms_set_mem_status));
1435 if(resp->success > 0)
1438 respSetMemStatus.result = SMS_SENDSMS_SUCCESS;
1443 dbg("RESPONSE NOK");
1444 respSetMemStatus.result = SMS_DEVICE_FAILURE;
1447 ur = tcore_pending_ref_user_request(p);
1450 dbg("no user_request");
1454 tcore_user_request_send_response(ur, TRESP_SMS_SET_MEM_STATUS, sizeof(struct tresp_sms_set_mem_status), &respSetMemStatus);
1459 static void on_response_set_msg_status(TcorePending *pending, int data_len, const void *data, void *user_data)
1462 struct tresp_sms_set_msg_status respMsgStatus = {0,};
1463 const TcoreATResponse *atResp = data;
1464 int response = 0, sw1 =0 , sw2 = 0;
1465 const char *line = NULL;
1467 GSList *tokens=NULL;
1471 memset(&respMsgStatus, 0, sizeof(struct tresp_sms_set_msg_status));
1472 respMsgStatus.result = SMS_DEVICE_FAILURE;
1474 ur = tcore_pending_ref_user_request(pending);
1476 if(atResp->success > 0)
1482 line = (const char*)atResp->lines->data;
1483 tokens = tcore_at_tok_new(line);
1484 pResp = g_slist_nth_data(tokens, 0);
1493 pResp = g_slist_nth_data(tokens, 1);
1497 if ((sw1 == AT_SW1_SUCCESS) && (sw2 == 0))
1499 respMsgStatus.result = SMS_SENDSMS_SUCCESS;
1506 pResp = g_slist_nth_data(tokens, 3);
1510 response = atoi(pResp);
1511 dbg("response is %s", response);
1522 dbg("RESPONSE NOK");
1525 tcore_user_request_send_response(ur, TRESP_SMS_SET_MSG_STATUS , sizeof(struct tresp_sms_set_msg_status), &respMsgStatus);
1528 tcore_at_tok_free(tokens);
1534 static void on_response_get_sms_params(TcorePending *pending, int data_len, const void *data, void *user_data)
1537 struct tresp_sms_get_params respGetParams;
1538 const TcoreATResponse *atResp = data;
1539 int sw1 =0 , sw2 = 0;
1540 const char *line = NULL;
1542 GSList *tokens=NULL;
1543 char *hexData = NULL;
1544 char *recordData = NULL;
1547 memset(&respGetParams, 0, sizeof(struct tresp_sms_set_params));
1548 respGetParams.result = SMS_DEVICE_FAILURE;
1550 ur = tcore_pending_ref_user_request(pending);
1552 if(atResp->success > 0)
1558 line = (const char*)atResp->lines->data;
1559 tokens = tcore_at_tok_new(line);
1560 pResp = g_slist_nth_data(tokens, 0);
1564 dbg("sw1 is %d",sw1);
1570 pResp = g_slist_nth_data(tokens, 1);
1574 dbg("sw2 is %d",sw2);
1575 if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91)
1577 respGetParams.result = SMS_SENDSMS_SUCCESS;
1584 pResp = g_slist_nth_data(tokens, 2);
1587 hexData = util_removeQuotes(pResp);
1589 recordData = util_hexStringToBytes(hexData);
1590 util_hex_dump(" ", strlen(hexData)/2, recordData);
1592 respGetParams.paramsInfo.recordLen = strlen(hexData)/2;
1594 util_sms_decode_smsParameters((unsigned char *)recordData , strlen(hexData)/2 , &(respGetParams.paramsInfo));
1595 respGetParams.result = SMS_SENDSMS_SUCCESS;
1597 for(i = 0 ; i < (int)respGetParams.paramsInfo.tpSvcCntrAddr.dialNumLen ; i ++)
1598 dbg("SCAddr = %d [%02x]",i,respGetParams.paramsInfo.tpSvcCntrAddr.diallingNum[i]);
1607 tcore_at_tok_free(tokens);
1612 dbg("RESPONSE NOK");
1615 tcore_user_request_send_response(ur, TRESP_SMS_GET_PARAMS, sizeof(struct tresp_sms_get_params), &respGetParams);
1621 static void on_response_set_sms_params(TcorePending *pending, int data_len, const void *data, void *user_data)
1624 struct tresp_sms_set_params respSetParams = {0,};
1625 const TcoreATResponse *atResp = data;
1626 int sw1 =0 , sw2 = 0;
1627 const char *line = NULL;
1629 GSList *tokens=NULL;
1632 memset(&respSetParams, 0, sizeof(struct tresp_sms_set_params));
1633 ur = tcore_pending_ref_user_request(pending);
1635 respSetParams.result = SMS_DEVICE_FAILURE;
1637 if(atResp->success > 0)
1643 line = (const char*)atResp->lines->data;
1644 tokens = tcore_at_tok_new(line);
1645 pResp = g_slist_nth_data(tokens, 0);
1646 if (pResp != NULL) {
1653 pResp = g_slist_nth_data(tokens, 1);
1657 if (((sw1 == AT_SW1_SUCCESS) && (sw2 == AT_SW2_SUCCESS)) || (sw1 == 0x91)){
1658 respSetParams.result = SMS_SENDSMS_SUCCESS;
1673 dbg("RESPONSE NOK");
1676 tcore_user_request_send_response(ur, TRESP_SMS_SET_PARAMS , sizeof(struct tresp_sms_set_params), &respSetParams);
1679 tcore_at_tok_free(tokens);
1685 static void on_response_get_paramcnt(TcorePending *p, int data_len, const void *data, void *user_data)
1688 UserRequest *ur = NULL;
1689 struct tresp_sms_get_paramcnt respGetParamCnt = {0,};
1690 const TcoreATResponse *atResp = data;
1691 char *line = NULL , *pResp = NULL;
1692 int sw1 = 0 , sw2 = 0, *smsp_record_len = NULL;
1694 GSList *tokens=NULL;
1695 CoreObject *co_sim = NULL; //need this to get the sim type GSM/USIM
1696 TcorePlugin *plugin = NULL;
1700 ur = tcore_pending_ref_user_request(p);
1701 respGetParamCnt.result = SMS_DEVICE_FAILURE;
1703 if(atResp->success > 0)
1709 line = (char*)atResp->lines->data;
1711 dbg("line is %s",line);
1713 tokens = tcore_at_tok_new(line);
1714 pResp = g_slist_nth_data(tokens, 0);
1723 pResp = g_slist_nth_data(tokens, 1);
1727 if ((sw1 == 144) && (sw2 == 0))
1729 respGetParamCnt.result = SMS_SENDSMS_SUCCESS;
1736 pResp = g_slist_nth_data(tokens, 2);
1739 char *hexData = NULL;
1740 char *recordData = NULL;
1741 hexData = util_removeQuotes(pResp);
1743 /*1. SIM access success case*/
1744 if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91)
1746 unsigned char tag_len = 0; /* 1 or 2 bytes ??? */
1748 char num_of_records = 0;
1749 unsigned char file_id_len = 0;
1750 unsigned short file_id = 0;
1751 unsigned short file_size = 0;
1752 unsigned short file_type = 0;
1753 unsigned short arr_file_id = 0;
1754 int arr_file_id_rec_num = 0;
1756 /* handling only last 3 bits */
1757 unsigned char file_type_tag = 0x07;
1758 unsigned char *ptr_data;
1760 recordData = util_hexStringToBytes(hexData);
1761 util_hex_dump(" ", strlen(hexData)/2, recordData);
1763 ptr_data = (unsigned char *)recordData;
1765 co_sim = tcore_plugin_ref_core_object(tcore_pending_ref_plugin(p), "sim");
1766 sim_type = tcore_sim_get_type(co_sim);
1767 dbg("sim type is %d",sim_type);
1769 if (sim_type == SIM_TYPE_USIM) {
1771 ETSI TS 102 221 v7.9.0
1773 '62' FCP template tag
1774 - Response for an EF
1775 '82' M File Descriptor
1776 '83' M File Identifier
1777 'A5' O Proprietary information
1778 '8A' M Life Cycle Status Integer
1779 '8B', '8C' or 'AB' C1 Security attributes
1781 '81' O Total file size
1782 '88' O Short File Identifier (SFI)
1785 /* rsim.res_len has complete data length received */
1787 /* FCP template tag - File Control Parameters tag*/
1788 if (*ptr_data == 0x62) {
1789 /* parse complete FCP tag*/
1790 /* increment to next byte */
1792 tag_len = *ptr_data++;
1793 /* FCP file descriptor - file type, accessibility, DF, ADF etc*/
1794 if (*ptr_data == 0x82) {
1795 /* increment to next byte */
1799 /* unsigned char file_desc_len = *ptr_data++;*/
1800 /* dbg("file descriptor length: [%d]", file_desc_len);*/
1801 /* TBD: currently capture only file type : ignore sharable, non sharable, working, internal etc*/
1802 /* consider only last 3 bits*/
1803 file_type_tag = file_type_tag & (*ptr_data);
1805 switch (file_type_tag) {
1806 /* increment to next byte */
1809 dbg("Getting FileType: [Transparent file type]");
1810 /* increment to next byte */
1812 file_type = 0x01; //SIM_FTYPE_TRANSPARENT
1813 /* data coding byte - value 21 */
1818 dbg("Getting FileType: [Linear fixed file type]");
1819 /* increment to next byte */
1821 /* data coding byte - value 21 */
1824 memcpy(&record_len, ptr_data, 2);
1826 record_len = SMS_SWAPBYTES16(record_len);
1827 ptr_data = ptr_data + 2;
1828 num_of_records = *ptr_data++;
1829 /* Data lossy conversation from enum (int) to unsigned char */
1830 file_type = 0x02; // SIM_FTYPE_LINEAR_FIXED
1834 dbg(" Cyclic fixed file type");
1835 /* increment to next byte */
1837 /* data coding byte - value 21 */
1840 memcpy(&record_len, ptr_data, 2);
1842 record_len = SMS_SWAPBYTES16(record_len);
1843 ptr_data = ptr_data + 2;
1844 num_of_records = *ptr_data++;
1845 file_type = 0x04; //SIM_FTYPE_CYCLIC
1849 dbg("not handled file type [0x%x]", *ptr_data);
1855 dbg("INVALID FCP received - DEbug!");
1859 /*File identifier - file id?? */ // 0x84,0x85,0x86 etc are currently ignored and not handled
1860 if (*ptr_data == 0x83) {
1861 /* increment to next byte */
1863 file_id_len = *ptr_data++;
1864 memcpy(&file_id, ptr_data, file_id_len);
1866 file_id = SMS_SWAPBYTES16(file_id);
1867 ptr_data = ptr_data + 2;
1868 dbg("Getting FileID=[0x%x]", file_id);
1870 dbg("INVALID FCP received - DEbug!");
1873 //ReleaseResponse();
1877 /* proprietary information */
1878 if (*ptr_data == 0xA5) {
1879 unsigned short prop_len;
1880 /* increment to next byte */
1883 prop_len = *ptr_data;
1885 ptr_data = ptr_data + prop_len + 1;
1887 dbg("INVALID FCP received - DEbug!");
1890 /* life cycle status integer [8A][length:0x01][status]*/
1893 00000000 : No information given
1894 00000001 : creation state
1895 00000011 : initialization state
1896 000001-1 : operation state -activated
1897 000001-0 : operation state -deactivated
1898 000011-- : Termination state
1899 b8~b5 !=0, b4~b1=X : Proprietary
1900 Any other value : RFU
1902 if (*ptr_data == 0x8A) {
1903 /* increment to next byte */
1905 /* length - value 1 */
1908 switch (*ptr_data) {
1911 dbg("<IPC_RX> operation state -deactivated");
1916 dbg("<IPC_RX> operation state -activated");
1920 dbg("<IPC_RX> DEBUG! LIFE CYCLE STATUS =[0x%x]",*ptr_data);
1926 /* related to security attributes : currently not handled*/
1927 if (*ptr_data == 0x86 || *ptr_data == 0x8B || *ptr_data == 0x8C || *ptr_data == 0xAB) {
1928 /* increment to next byte */
1930 /* if tag length is 3 */
1931 if (*ptr_data == 0x03) {
1932 /* increment to next byte */
1935 memcpy(&arr_file_id, ptr_data, 2);
1937 arr_file_id = SMS_SWAPBYTES16(arr_file_id);
1938 ptr_data = ptr_data + 2;
1939 arr_file_id_rec_num = *ptr_data++;
1941 /* if tag length is not 3 */
1942 /* ignoring bytes */
1943 // ptr_data = ptr_data + 4;
1944 dbg("Useless security attributes, so jump to next tag");
1945 ptr_data = ptr_data + (*ptr_data + 1);
1948 dbg("INVALID FCP received[0x%x] - DEbug!", *ptr_data);
1955 dbg("Current ptr_data value is [%x]", *ptr_data);
1957 /* file size excluding structural info*/
1958 if (*ptr_data == 0x80) {
1959 /* for EF file size is body of file and for Linear or cyclic it is
1960 * number of recXsizeof(one record)
1962 /* increment to next byte */
1964 /* length is 1 byte - value is 2 bytes or more */
1966 memcpy(&file_size, ptr_data, 2);
1968 file_size = SMS_SWAPBYTES16(file_size);
1969 ptr_data = ptr_data + 2;
1971 dbg("INVALID FCP received - DEbug!");
1977 /* total file size including structural info*/
1978 if (*ptr_data == 0x81) {
1980 /* increment to next byte */
1985 ptr_data = ptr_data + 3;
1987 dbg("INVALID FCP received - DEbug!");
1988 /* 0x81 is optional tag?? check out! so do not return -1 from here! */
1991 /*short file identifier ignored*/
1992 if (*ptr_data == 0x88) {
1993 dbg("0x88: Do Nothing");
1997 dbg("INVALID FCP received - DEbug!");
2003 else if (sim_type == SIM_TYPE_GSM)
2005 unsigned char gsm_specific_file_data_len = 0;
2006 /* ignore RFU byte1 and byte2 */
2010 //file_size = p_info->response_len;
2011 memcpy(&file_size, ptr_data, 2);
2013 file_size = SMS_SWAPBYTES16(file_size);
2014 /* parsed file size */
2015 ptr_data = ptr_data + 2;
2017 memcpy(&file_id, ptr_data, 2);
2018 file_id = SMS_SWAPBYTES16(file_id);
2019 dbg(" FILE id --> [%x]", file_id);
2020 ptr_data = ptr_data + 2;
2021 /* save file type - transparent, linear fixed or cyclic */
2022 file_type_tag = (*(ptr_data + 7));
2024 switch (*ptr_data) {
2027 dbg(" RFU file type- not handled - Debug!");
2031 dbg(" MF file type - not handled - Debug!");
2035 dbg(" DF file type - not handled - Debug!");
2039 dbg(" EF file type [%d] ", file_type_tag);
2040 /* increment to next byte */
2043 if (file_type_tag == 0x00 || file_type_tag == 0x01) {
2044 /* increament to next byte as this byte is RFU */
2047 (file_type_tag == 0x00) ? 0x01 : 0x02; // SIM_FTYPE_TRANSPARENT:SIM_FTYPE_LINEAR_FIXED;
2049 /* increment to next byte */
2051 /* For a cyclic EF all bits except bit 7 are RFU; b7=1 indicates that */
2052 /* the INCREASE command is allowed on the selected cyclic file. */
2053 file_type = 0x04; // SIM_FTYPE_CYCLIC;
2055 /* bytes 9 to 11 give SIM file access conditions */
2057 /* byte 10 has one nibble that is RF U and another for INCREASE which is not used currently */
2059 /* byte 11 is invalidate and rehabilate nibbles */
2061 /* byte 12 - file status */
2063 /* byte 13 - GSM specific data */
2064 gsm_specific_file_data_len = *ptr_data;
2066 /* byte 14 - structure of EF - transparent or linear or cyclic , already saved above */
2068 /* byte 15 - length of record for linear and cyclic , for transparent it is set to 0x00. */
2069 record_len = *ptr_data;
2070 dbg("record length[%d], file size[%d]", record_len, file_size);
2072 if (record_len != 0)
2073 num_of_records = (file_size / record_len);
2075 dbg("Number of records [%d]", num_of_records);
2079 dbg(" not handled file type");
2085 dbg(" Card Type - UNKNOWN [%d]", sim_type);
2088 dbg("EF[0x%x] size[%ld] Type[0x%x] NumOfRecords[%ld] RecordLen[%ld]", file_id, file_size, file_type, num_of_records, record_len);
2090 respGetParamCnt.recordCount = num_of_records;
2091 respGetParamCnt.result = SMS_SUCCESS;
2093 //TO Store smsp record length in the property
2094 plugin = tcore_pending_ref_plugin(p);
2095 smsp_record_len = tcore_plugin_ref_property(plugin, "SMSPRECORDLEN");
2096 memcpy(smsp_record_len, &record_len, sizeof(int));
2103 /*2. SIM access fail case*/
2104 dbg("SIM access fail");
2105 respGetParamCnt.result = SMS_UNKNOWN;
2110 dbg("presp is NULL");
2115 dbg("line is blank");
2120 dbg("RESPONSE NOK");
2124 tcore_user_request_send_response(ur, TRESP_SMS_GET_PARAMCNT, sizeof(struct tresp_sms_get_paramcnt), &respGetParamCnt);
2130 /*=============================================================
2132 ==============================================================*/
2133 static TReturn send_umts_msg(CoreObject *obj, UserRequest *ur)
2135 gchar *cmd_str = NULL;
2136 TcoreHal *hal = NULL;
2137 TcoreATRequest *atreq = NULL;
2138 TcorePending *pending = NULL;
2139 const struct treq_sms_send_umts_msg *sendUmtsMsg = NULL;
2140 char buf[2*(SMS_SMSP_ADDRESS_LEN+SMS_SMDATA_SIZE_MAX)+1] = {0};
2146 sendUmtsMsg = tcore_user_request_ref_data(ur, NULL);
2147 hal = tcore_object_get_hal(obj);
2148 if(NULL == sendUmtsMsg || NULL == hal)
2150 err("NULL input. Unable to proceed");
2151 dbg("sendUmtsMsg: [%p], hal: [%p]", sendUmtsMsg, hal);
2154 return TCORE_RETURN_EINVAL;
2157 dbg("msgLength: [%d]", sendUmtsMsg->msgDataPackage.msgLength);
2158 util_hex_dump(" ", (SMS_SMDATA_SIZE_MAX+1), (void *)sendUmtsMsg->msgDataPackage.tpduData);
2159 util_hex_dump(" ", SMS_SMSP_ADDRESS_LEN, (void *)sendUmtsMsg->msgDataPackage.sca);
2161 ScLength = (int)sendUmtsMsg->msgDataPackage.sca[0];
2163 dbg("ScLength: [%d]", ScLength);
2165 if ((sendUmtsMsg->msgDataPackage.msgLength > 0)
2166 && (sendUmtsMsg->msgDataPackage.msgLength <= SMS_SMDATA_SIZE_MAX)
2167 && (ScLength <= SMS_MAX_SMS_SERVICE_CENTER_ADDR))
2169 if(ScLength == 0) //ScAddress not specified
2177 dbg("Specifying SCA in TPDU is currently not supported");
2184 util_byte_to_hex((const char *)sendUmtsMsg->msgDataPackage.tpduData, (char *)&buf[pdu_len], sendUmtsMsg->msgDataPackage.msgLength);
2186 pdu_len = pdu_len + 2*sendUmtsMsg->msgDataPackage.msgLength;
2188 buf[pdu_len] = '\0'; //Ensure termination
2190 dbg("pdu_len: [%d]", pdu_len);
2191 util_hex_dump(" ", sizeof(buf), (void *)buf);
2193 //AT+CMGS=<length><CR>PDU is given<ctrl-Z/ESC>
2194 cmd_str = g_strdup_printf("AT+CMGS=%d%s%s\x1A", sendUmtsMsg->msgDataPackage.msgLength,"\r",buf);
2195 atreq = tcore_at_request_new((const char *)cmd_str, "+CMGS", TCORE_AT_SINGLELINE);
2196 pending = tcore_pending_new(obj, 0);
2198 if(NULL == cmd_str || NULL == atreq || NULL == pending)
2200 err("Out of memory. Unable to proceed");
2201 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
2203 //free memory we own
2205 util_sms_free_memory(atreq);
2206 util_sms_free_memory(pending);
2209 return TCORE_RETURN_ENOMEM;
2212 util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
2214 tcore_pending_set_request_data(pending, 0, atreq);
2215 tcore_pending_set_response_callback(pending, on_response_send_umts_msg, NULL);
2216 tcore_pending_link_user_request(pending, ur);
2217 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
2218 tcore_hal_send_request(hal, pending);
2223 return TCORE_RETURN_SUCCESS;
2226 err("Invalid Data len");
2228 return TCORE_RETURN_SMS_INVALID_DATA_LEN;
2231 static TReturn read_msg(CoreObject *obj, UserRequest *ur)
2233 gchar *cmd_str = NULL;
2234 TcoreHal *hal = NULL;
2235 TcoreATRequest *atreq = NULL;
2236 TcorePending *pending = NULL;
2237 const struct treq_sms_read_msg *readMsg = NULL;
2241 readMsg = tcore_user_request_ref_data(ur, NULL);
2242 hal = tcore_object_get_hal(obj);
2243 if(NULL == readMsg || NULL == hal)
2245 err("NULL input. Unable to proceed");
2246 dbg("readMsg: [%p], hal: [%p]", readMsg, hal);
2249 return TCORE_RETURN_EINVAL;
2252 dbg("index: [%d]", readMsg->index);
2254 cmd_str = g_strdup_printf("AT+CMGR=%d", (readMsg->index + 1)); //IMC index is one ahead of TAPI
2255 atreq = tcore_at_request_new((const char *)cmd_str, "+CMGR", TCORE_AT_PDU);
2256 pending = tcore_pending_new(obj, 0);
2258 if(NULL == cmd_str || NULL == atreq || NULL == pending)
2260 err("Out of memory. Unable to proceed");
2261 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
2263 //free memory we own
2265 util_sms_free_memory(atreq);
2266 util_sms_free_memory(pending);
2269 return TCORE_RETURN_ENOMEM;
2272 util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
2274 tcore_pending_set_request_data(pending, 0, atreq);
2275 tcore_pending_set_response_callback(pending, on_response_read_msg, (void *)(uintptr_t)(readMsg->index)); //storing index as user data for response
2276 tcore_pending_link_user_request(pending, ur);
2277 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
2278 tcore_hal_send_request(hal, pending);
2283 return TCORE_RETURN_SUCCESS;
2286 static TReturn save_msg(CoreObject *obj, UserRequest *ur)
2288 gchar *cmd_str = NULL;
2289 TcoreHal *hal = NULL;
2290 TcoreATRequest *atreq = NULL;
2291 TcorePending *pending = NULL;
2292 const struct treq_sms_save_msg *saveMsg = NULL;
2293 int ScLength = 0, pdu_len = 0, stat = 0;
2294 char buf[2*(SMS_SMSP_ADDRESS_LEN+SMS_SMDATA_SIZE_MAX)+1] = {0};
2298 saveMsg = tcore_user_request_ref_data(ur, NULL);
2299 hal = tcore_object_get_hal(obj);
2300 if(NULL == saveMsg || NULL == hal)
2302 err("NULL input. Unable to proceed");
2303 dbg("saveMsg: [%p], hal: [%p]", saveMsg, hal);
2306 return TCORE_RETURN_EINVAL;
2309 dbg("msgStatus: %x, msgLength: [%d]", saveMsg->msgStatus, saveMsg->msgDataPackage.msgLength);
2310 util_hex_dump(" ", (SMS_SMDATA_SIZE_MAX+1), (void *)saveMsg->msgDataPackage.tpduData);
2311 util_hex_dump(" ", SMS_SMSP_ADDRESS_LEN, (void *)saveMsg->msgDataPackage.sca);
2313 switch (saveMsg->msgStatus) {
2314 case SMS_STATUS_READ:
2318 case SMS_STATUS_UNREAD:
2319 stat = AT_REC_UNREAD;
2322 case SMS_STATUS_SENT:
2326 case SMS_STATUS_UNSENT:
2327 stat = AT_STO_UNSENT;
2331 err("Invalid msgStatus");
2333 return TCORE_RETURN_EINVAL;
2336 if ((saveMsg->msgDataPackage.msgLength > 0)
2337 && (saveMsg->msgDataPackage.msgLength <= SMS_SMDATA_SIZE_MAX))
2339 ScLength = (int)saveMsg->msgDataPackage.sca[0];
2343 dbg("ScLength is zero");
2349 dbg("Specifying SCA is currently not supported");
2355 util_byte_to_hex((const char *)saveMsg->msgDataPackage.tpduData, (char *)&(buf[pdu_len]), saveMsg->msgDataPackage.msgLength);
2357 pdu_len = pdu_len + 2*saveMsg->msgDataPackage.msgLength;
2359 buf[pdu_len] = '\0'; //Ensure termination
2361 dbg("pdu_len: [%d]", pdu_len);
2362 util_hex_dump(" ", sizeof(buf), (void *)buf);
2364 //AT+CMGW=<length>[,<stat>]<CR>PDU is given<ctrl-Z/ESC>
2365 cmd_str = g_strdup_printf("AT+CMGW=%d,%d%s%s\x1A", saveMsg->msgDataPackage.msgLength, stat, "\r", buf);
2366 pending = tcore_pending_new(obj, 0);
2367 atreq = tcore_at_request_new((const char *)cmd_str, "+CMGW", TCORE_AT_SINGLELINE);
2369 if(NULL == cmd_str || NULL == atreq || NULL == pending)
2371 err("Out of memory. Unable to proceed");
2372 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
2374 //free memory we own
2376 util_sms_free_memory(atreq);
2377 util_sms_free_memory(pending);
2380 return TCORE_RETURN_ENOMEM;
2383 util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
2385 tcore_pending_set_request_data(pending, 0, atreq);
2386 tcore_pending_set_response_callback(pending, on_response_sms_save_msg, NULL);
2387 tcore_pending_link_user_request(pending, ur);
2388 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
2389 tcore_hal_send_request(hal, pending);
2394 return TCORE_RETURN_SUCCESS;
2397 err("Invalid Data len");
2399 return TCORE_RETURN_SMS_INVALID_DATA_LEN;
2402 static TReturn delete_msg(CoreObject *obj, UserRequest *ur)
2404 gchar *cmd_str = NULL;
2405 TcoreHal *hal = NULL;
2406 TcoreATRequest *atreq = NULL;
2407 TcorePending *pending = NULL;
2408 const struct treq_sms_delete_msg *deleteMsg = NULL;
2412 deleteMsg = tcore_user_request_ref_data(ur, NULL);
2413 hal = tcore_object_get_hal(obj);
2414 if(NULL == deleteMsg || NULL == hal)
2416 err("NULL input. Unable to proceed");
2417 dbg("deleteMsg: [%p], hal: [%p]", deleteMsg, hal);
2420 return TCORE_RETURN_EINVAL;
2423 dbg("index: %d", deleteMsg->index);
2425 cmd_str =g_strdup_printf("AT+CMGD=%d,0", deleteMsg->index+1);
2426 pending = tcore_pending_new(obj, 0);
2427 atreq = tcore_at_request_new((const char *)cmd_str, NULL, TCORE_AT_NO_RESULT);
2428 if(NULL == cmd_str || NULL == atreq || NULL == pending)
2430 err("Out of memory. Unable to proceed");
2431 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
2433 //free memory we own
2435 util_sms_free_memory(atreq);
2436 util_sms_free_memory(pending);
2439 return TCORE_RETURN_ENOMEM;
2442 util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
2444 tcore_pending_set_request_data(pending, 0, atreq);
2445 tcore_pending_set_response_callback(pending, on_response_sms_delete_msg, (void *)(uintptr_t)(deleteMsg->index)); //storing index as user data for response
2446 tcore_pending_link_user_request(pending, ur);
2447 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
2448 tcore_hal_send_request(hal, pending);
2453 return TCORE_RETURN_SUCCESS;
2456 static TReturn get_storedMsgCnt(CoreObject *obj, UserRequest *ur)
2458 gchar *cmd_str = NULL;
2459 TcoreHal *hal = NULL;
2460 TcoreATRequest *atreq = NULL;
2461 TcorePending *pending = NULL;
2465 hal = tcore_object_get_hal(obj);
2468 err("NULL HAL. Unable to proceed");
2471 return TCORE_RETURN_EINVAL;
2474 cmd_str = g_strdup_printf("AT+CPMS=\"SM\"");
2475 pending = tcore_pending_new(obj, 0);
2476 atreq = tcore_at_request_new((const char *)cmd_str, "+CPMS", TCORE_AT_SINGLELINE);
2478 if(NULL == cmd_str || NULL == atreq || NULL == pending)
2480 err("Out of memory. Unable to proceed");
2481 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
2483 //free memory we own
2485 util_sms_free_memory(atreq);
2486 util_sms_free_memory(pending);
2489 return TCORE_RETURN_ENOMEM;
2492 util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
2494 tcore_pending_set_request_data(pending, 0, atreq);
2495 tcore_pending_set_response_callback(pending, on_response_get_stored_msg_cnt, NULL);
2496 tcore_pending_link_user_request(pending, ur);
2497 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
2498 tcore_hal_send_request(hal, pending);
2503 return TCORE_RETURN_SUCCESS;
2506 static TReturn get_sca(CoreObject *obj, UserRequest *ur)
2508 gchar * cmd_str = NULL;
2509 TcoreHal *hal = NULL;
2510 TcoreATRequest *atreq = NULL;
2511 TcorePending *pending = NULL;
2515 hal = tcore_object_get_hal(obj);
2518 err("HAL NULL. Unable to proceed");
2521 return TCORE_RETURN_EINVAL;
2524 cmd_str = g_strdup_printf("AT+CSCA?");
2525 pending = tcore_pending_new(obj, 0);
2526 atreq = tcore_at_request_new((const char *)cmd_str, "+CSCA", TCORE_AT_SINGLELINE);
2528 if(NULL == cmd_str || NULL == atreq || NULL == pending)
2530 err("Out of memory. Unable to proceed");
2531 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
2533 //free memory we own
2535 util_sms_free_memory(atreq);
2536 util_sms_free_memory(pending);
2539 return TCORE_RETURN_ENOMEM;
2542 util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
2544 tcore_pending_set_request_data(pending, 0, atreq);
2545 tcore_pending_set_response_callback(pending, on_response_get_sca, NULL);
2546 tcore_pending_link_user_request(pending, ur);
2547 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
2548 tcore_hal_send_request(hal, pending);
2553 return TCORE_RETURN_SUCCESS;
2556 static TReturn set_sca(CoreObject *obj, UserRequest *ur)
2558 gchar *cmd_str = NULL;
2559 TcoreHal *hal = NULL;
2560 TcoreATRequest *atreq = NULL;
2561 TcorePending *pending = NULL;
2562 const struct treq_sms_set_sca *setSca = NULL;
2567 setSca = tcore_user_request_ref_data(ur, NULL);
2568 hal = tcore_object_get_hal(obj);
2569 if(NULL == setSca || NULL == hal)
2571 err("NULL input. Unable to proceed");
2572 dbg("setSca: [%p], hal: [%p]", setSca, hal);
2575 return TCORE_RETURN_EINVAL;
2578 dbg("dialNumLen: %u, typeOfNum: %d, numPlanId: %d, ", setSca->scaInfo.dialNumLen, setSca->scaInfo.typeOfNum, setSca->scaInfo.numPlanId);
2580 util_hex_dump(" ", (SMS_SMSP_ADDRESS_LEN+1), (void *)setSca->scaInfo.diallingNum);
2582 addrType = ((setSca->scaInfo.typeOfNum << 4) | setSca->scaInfo.numPlanId) | 0x80;
2584 cmd_str = g_strdup_printf("AT+CSCA=\"%s\",%d", setSca->scaInfo.diallingNum, addrType);
2585 pending = tcore_pending_new(obj, 0);
2586 atreq = tcore_at_request_new((const char *)cmd_str, NULL, TCORE_AT_NO_RESULT);
2588 if(NULL == cmd_str || NULL == atreq || NULL == pending)
2590 err("Out of memory. Unable to proceed");
2591 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
2593 //free memory we own
2595 util_sms_free_memory(atreq);
2596 util_sms_free_memory(pending);
2599 return TCORE_RETURN_ENOMEM;
2602 util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
2604 tcore_pending_set_request_data(pending, 0, atreq);
2605 tcore_pending_set_response_callback(pending, on_response_set_sca, NULL);
2606 tcore_pending_link_user_request(pending, ur);
2607 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
2608 tcore_hal_send_request(hal, pending);
2613 return TCORE_RETURN_SUCCESS;
2616 static TReturn get_cb_config(CoreObject *obj, UserRequest *ur)
2618 gchar *cmd_str = NULL;
2619 TcoreHal *hal = NULL;
2620 TcoreATRequest *atreq = NULL;
2621 TcorePending *pending = NULL;
2625 hal = tcore_object_get_hal(obj);
2628 err("NULL HAL. Unable to proceed");
2631 return TCORE_RETURN_EINVAL;
2634 cmd_str = g_strdup_printf("AT+CSCB?");
2635 pending = tcore_pending_new(obj, 0);
2636 atreq = tcore_at_request_new((const char *)cmd_str, "+CSCB", TCORE_AT_SINGLELINE);
2637 if(NULL == cmd_str || NULL == atreq || NULL == pending)
2639 err("Out of memory. Unable to proceed");
2640 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
2642 //free memory we own
2644 util_sms_free_memory(atreq);
2645 util_sms_free_memory(pending);
2648 return TCORE_RETURN_ENOMEM;
2651 util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
2653 tcore_pending_set_request_data(pending, 0, atreq);
2654 tcore_pending_set_response_callback(pending, on_response_get_cb_config, NULL);
2655 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
2656 tcore_pending_link_user_request(pending, ur);
2657 tcore_hal_send_request(hal, pending);
2662 return TCORE_RETURN_SUCCESS;
2665 static TReturn set_cb_config(CoreObject *obj, UserRequest *ur)
2667 gchar *cmd_str = NULL;
2668 gchar *mids_str = NULL;
2669 GString *mids_GString = NULL;
2671 TcoreHal *hal = NULL;
2672 TcoreATRequest *atreq = NULL;
2673 TcorePending *pending = NULL;
2674 const struct treq_sms_set_cb_config *setCbConfig = NULL;
2679 setCbConfig = tcore_user_request_ref_data(ur, NULL);
2680 hal = tcore_object_get_hal(obj);
2681 if(NULL == setCbConfig || NULL == hal)
2683 err("NULL input. Unable to proceed");
2684 dbg("setCbConfig: [%p], hal: [%p]", setCbConfig, hal);
2687 return TCORE_RETURN_EINVAL;
2690 dbg("bCBEnabled: %d, selectedId: %x, msgIdMaxCount: %x, msgIdCount: %d", setCbConfig->bCBEnabled, setCbConfig->selectedId, setCbConfig->msgIdMaxCount, setCbConfig->msgIdCount);
2691 util_hex_dump(" ", SMS_GSM_SMS_CBMI_LIST_SIZE_MAX, (void *)setCbConfig->msgIDs);
2693 if (setCbConfig->bCBEnabled == FALSE) //AT+CSCB=0: Disable CBS
2695 cmd_str = g_strdup_printf("AT+CSCB=0");
2699 if(setCbConfig->selectedId == SMS_CBMI_SELECTED_SOME) //AT+CSCB=0,<mids>,<dcss>: Enable CBS for specified <mids> and <dcss>
2701 dbg("Enabling specified CBMIs");
2702 mids_GString = g_string_new(g_strdup_printf("%d", setCbConfig->msgIDs[0]));
2704 for(loop_ctr=1; loop_ctr <setCbConfig->msgIdCount; loop_ctr++)
2706 mids_GString = g_string_append(mids_GString, ",");
2707 mids_GString = g_string_append(mids_GString, g_strdup_printf("%d", setCbConfig->msgIDs[loop_ctr]));
2710 mids_str = g_string_free(mids_GString, FALSE);
2711 cmd_str = g_strdup_printf("AT+CSCB=0,\"%s\"", mids_str);
2715 else if (setCbConfig->selectedId == SMS_CBMI_SELECTED_ALL) //AT+CSCB=1: Enable CBS for all <mids> and <dcss>
2717 dbg("Enabling all CBMIs");
2718 cmd_str = g_strdup_printf("AT+CSCB=1");
2722 pending = tcore_pending_new(obj, 0);
2723 atreq = tcore_at_request_new((const char *)cmd_str, NULL, TCORE_AT_NO_RESULT);
2724 if(NULL == cmd_str || NULL == atreq || NULL == pending)
2726 err("Out of memory. Unable to proceed");
2727 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
2729 //free memory we own
2731 util_sms_free_memory(atreq);
2732 util_sms_free_memory(pending);
2735 return TCORE_RETURN_ENOMEM;
2738 util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
2740 tcore_pending_set_request_data(pending, 0, atreq);
2741 tcore_pending_set_response_callback(pending, on_response_set_cb_config, NULL);
2742 tcore_pending_link_user_request(pending, ur);
2743 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
2744 tcore_hal_send_request(hal, pending);
2749 return TCORE_RETURN_SUCCESS;
2752 static TReturn set_mem_status(CoreObject *obj, UserRequest *ur)
2754 gchar *cmd_str = NULL;
2755 TcoreHal *hal = NULL;
2756 TcoreATRequest *atreq = NULL;
2757 TcorePending *pending = NULL;
2758 const struct treq_sms_set_mem_status *setMemStatus = NULL;
2759 int memoryStatus = 0;
2763 setMemStatus = tcore_user_request_ref_data(ur, NULL);
2764 hal = tcore_object_get_hal(obj);
2765 if(NULL == setMemStatus || NULL == hal)
2767 err("NULL input. Unable to proceed");
2768 dbg("setMemStatus: [%p], hal: [%p]", setMemStatus, hal);
2771 return TCORE_RETURN_EINVAL;
2774 dbg("memory_status: %d", setMemStatus->memory_status);
2776 if(setMemStatus->memory_status < SMS_PDA_MEMORY_STATUS_AVAILABLE
2777 || setMemStatus->memory_status > SMS_PDA_MEMORY_STATUS_FULL)
2779 err("Invalid memory_status");
2782 return TCORE_RETURN_EINVAL;
2785 switch (setMemStatus->memory_status)
2787 case SMS_PDA_MEMORY_STATUS_AVAILABLE:
2788 memoryStatus = AT_MEMORY_AVAILABLE;
2791 case SMS_PDA_MEMORY_STATUS_FULL:
2792 memoryStatus = AT_MEMORY_FULL;
2796 err("Invalid memory_status");
2798 return TCORE_RETURN_EINVAL;
2801 cmd_str = g_strdup_printf("AT+XTESM=%d", memoryStatus);
2802 pending = tcore_pending_new(obj, 0);
2803 atreq = tcore_at_request_new((const char *)cmd_str, NULL, TCORE_AT_NO_RESULT);
2805 if(NULL == cmd_str || NULL == atreq || NULL == pending)
2807 err("Out of memory. Unable to proceed");
2808 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
2810 //free memory we own
2812 util_sms_free_memory(atreq);
2813 util_sms_free_memory(pending);
2816 return TCORE_RETURN_ENOMEM;
2819 util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
2821 tcore_pending_set_request_data(pending, 0, atreq);
2822 tcore_pending_set_response_callback(pending, on_response_set_mem_status, NULL);
2823 tcore_pending_link_user_request(pending, ur);
2824 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
2825 tcore_hal_send_request(hal, pending);
2830 return TCORE_RETURN_SUCCESS;
2833 static TReturn set_delivery_report(CoreObject *obj, UserRequest *ur)
2835 struct tresp_sms_set_delivery_report deliverReportInfo;
2838 deliverReportInfo.result = SMS_SUCCESS;
2840 dbg("CP takes care of sending SMS ack to network for all classes of SMS. Sending default success.");
2842 tcore_user_request_send_response(ur, TRESP_SMS_SET_DELIVERY_REPORT, sizeof(struct tresp_sms_set_delivery_report), &deliverReportInfo);
2845 return TCORE_RETURN_SUCCESS;
2848 static TReturn set_msg_status(CoreObject *obj, UserRequest *ur)
2850 gchar *cmd_str = NULL;
2851 char temp_data[AT_EF_SMS_RECORD_LEN];
2852 char encoded_data[AT_EF_SMS_RECORD_LEN * 2 +1];
2855 TcoreHal *hal = NULL;
2856 TcoreATRequest *atreq = NULL;
2857 TcorePending *pending = NULL;
2858 //const struct treq_sms_set_msg_status *msg_status = NULL;
2861 dbg("CoreObject: [%p]", obj);
2862 dbg("UserRequest: [%p]", ur);
2864 memset(temp_data, 0xff, AT_EF_SMS_RECORD_LEN);
2867 hal = tcore_object_get_hal(obj);
2871 case SMS_STATUS_READ:
2875 case SMS_STATUS_UNREAD:
2876 temp_data[0] = 0x03;
2879 case SMS_STATUS_UNSENT:
2880 temp_data[0] = 0x07;
2883 case SMS_STATUS_SENT:
2884 temp_data[0] = 0x05;
2887 case SMS_STATUS_DELIVERED:
2888 temp_data[0] = 0x1D;
2891 case SMS_STATUS_DELIVERY_UNCONFIRMED:
2895 case SMS_STATUS_MESSAGE_REPLACED: //Fall Through
2896 case SMS_STATUS_RESERVED: //Fall Through
2897 temp_data[0] = 0x03;
2901 util_byte_to_hex((const char *)temp_data, (char *)encoded_data,176);
2903 //AT+CRSM=command>[,<fileid>[,<P1>,<P2>,<P3>[,<data>[,<pathid>]]]]
2904 //cmd_str = g_strdup_printf("AT+CRSM=220,28476,%d, 4, 1 \"%s\"", (msg_status->index+1), encoded_data);
2905 cmd_str = g_strdup_printf("AT+CRSM=220,28476,1,4,176,\"%s\"",encoded_data);
2906 dbg("cmd str is %s",cmd_str);
2907 atreq = tcore_at_request_new((const char *)cmd_str, "+CRSM", TCORE_AT_SINGLELINE);
2908 pending = tcore_pending_new(obj, 0);
2909 if(NULL == cmd_str || NULL == atreq || NULL == pending)
2911 err("Out of memory. Unable to proceed");
2912 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
2914 //free memory we own
2916 util_sms_free_memory(atreq);
2917 util_sms_free_memory(pending);
2920 return TCORE_RETURN_ENOMEM;
2923 util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
2925 tcore_pending_set_request_data(pending, 0, atreq);
2926 tcore_pending_set_timeout(pending, 0);
2927 tcore_pending_set_response_callback(pending, on_response_set_msg_status, NULL);
2928 tcore_pending_link_user_request(pending, ur);
2929 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
2930 tcore_hal_send_request(hal, pending);
2935 return TCORE_RETURN_SUCCESS;
2938 static TReturn get_sms_params(CoreObject *obj, UserRequest *ur)
2940 gchar *cmd_str = NULL;
2941 TcoreHal *hal = NULL;
2942 TcoreATRequest *atreq = NULL;
2943 TcorePending *pending = NULL;
2944 const struct treq_sms_get_params *getSmsParams = NULL;
2945 int record_len = 0 , *smsp_record_len = NULL;
2949 getSmsParams = tcore_user_request_ref_data(ur, NULL);
2950 hal = tcore_object_get_hal(obj);
2951 if(NULL == getSmsParams || NULL == hal)
2953 err("NULL input. Unable to proceed");
2954 dbg("getSmsParams: [%p], hal: [%p]", getSmsParams, hal);
2957 return TCORE_RETURN_EINVAL;
2960 smsp_record_len = tcore_plugin_ref_property(tcore_object_ref_plugin(obj), "SMSPRECORDLEN");
2961 record_len = *smsp_record_len;
2962 dbg("record len from property %d", record_len);
2964 //AT+CRSM=command>[,<fileid>[,<P1>,<P2>,<P3>[,<data>[,<pathid>]]]]
2965 cmd_str = g_strdup_printf("AT+CRSM=178,28482,%d,4,%d", (getSmsParams->index + 1), record_len);
2967 dbg("cmd_str is %s",cmd_str);
2969 atreq = tcore_at_request_new((const char *)cmd_str, "+CRSM", TCORE_AT_SINGLELINE);
2970 pending = tcore_pending_new(obj, 0);
2971 if(NULL == cmd_str || NULL == atreq || NULL == pending)
2973 err("Out of memory. Unable to proceed");
2974 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
2976 //free memory we own
2978 util_sms_free_memory(atreq);
2979 util_sms_free_memory(pending);
2982 return TCORE_RETURN_ENOMEM;
2985 util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
2987 tcore_pending_set_request_data(pending, 0, atreq);
2988 tcore_pending_set_timeout(pending, 0);
2989 tcore_pending_set_response_callback(pending, on_response_get_sms_params, NULL);
2990 tcore_pending_link_user_request(pending, ur);
2991 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
2992 tcore_hal_send_request(hal, pending);
2997 return TCORE_RETURN_SUCCESS;
3000 static TReturn set_sms_params(CoreObject *obj, UserRequest *ur)
3002 gchar *cmd_str = NULL;
3003 char *encoded_data = NULL;
3004 unsigned char *temp_data = NULL;
3005 int SMSPRecordLen = 0;
3007 TcoreHal *hal = NULL;
3008 TcoreATRequest *atreq = NULL;
3009 TcorePending *pending = NULL;
3010 const struct treq_sms_set_params *setSmsParams = NULL;
3011 int encoded_data_len = 0;
3015 setSmsParams = tcore_user_request_ref_data(ur, NULL);
3016 hal = tcore_object_get_hal(obj);
3017 if(NULL == setSmsParams || NULL == hal)
3019 err("NULL input. Unable to proceed");
3020 dbg("setSmsParams: [%p], hal: [%p]", setSmsParams, hal);
3025 //EFsmsp file size is 28 +Y bytes (Y is alpha id size)
3026 SMSPRecordLen = 28 + setSmsParams->params.alphaIdLen;
3027 temp_data = calloc(SMSPRecordLen,1);
3028 encoded_data = calloc(SMSPRecordLen*2 + 1,1);
3030 _tcore_util_sms_encode_smsParameters(&(setSmsParams->params), temp_data, SMSPRecordLen);
3032 util_byte_to_hex((const char *)temp_data, (char *)encoded_data,SMSPRecordLen);
3034 encoded_data_len = ((SMSPRecordLen) * 2);
3036 hal = tcore_object_get_hal(obj);
3037 pending = tcore_pending_new(obj, 0);
3039 dbg("alpha id len %d encoded data %s. Encoded data len %d",setSmsParams->params.alphaIdLen,encoded_data, encoded_data_len);
3040 cmd_str = g_strdup_printf("AT+CRSM=220,28482,%d,4,%d,\"%s\"",(setSmsParams->params.recordIndex+1),SMSPRecordLen,encoded_data);
3042 dbg("cmd str is %s",cmd_str);
3043 atreq = tcore_at_request_new(cmd_str, "+CRSM:", TCORE_AT_SINGLELINE);
3045 if(NULL == cmd_str || NULL == atreq || NULL == pending)
3047 err("Out of memory. Unable to proceed");
3048 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
3050 //free memory we own
3052 util_sms_free_memory(atreq);
3053 util_sms_free_memory(pending);
3055 util_sms_free_memory(temp_data);
3056 util_sms_free_memory(encoded_data);
3059 return TCORE_RETURN_ENOMEM;
3062 util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
3064 tcore_pending_set_request_data(pending, 0,atreq);
3065 tcore_pending_set_timeout(pending, 0);
3066 tcore_pending_set_response_callback(pending, on_response_set_sms_params, NULL);
3067 tcore_pending_link_user_request(pending, ur);
3068 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
3069 tcore_hal_send_request(hal, pending);
3072 util_sms_free_memory(temp_data);
3073 util_sms_free_memory(encoded_data);
3078 static TReturn get_paramcnt(CoreObject *obj, UserRequest *ur)
3080 gchar *cmd_str = NULL;
3081 TcoreHal *hal = NULL;
3082 TcoreATRequest *atreq = NULL;
3083 TcorePending *pending = NULL;
3087 hal = tcore_object_get_hal(obj);
3090 err("NULL HAL. Unable to proceed");
3093 return TCORE_RETURN_EINVAL;
3096 //AT+CRSM=command>[,<fileid>[,<P1>,<P2>,<P3>[,<data>[,<pathid>]]]]
3097 cmd_str = g_strdup_printf("AT+CRSM=192,28482");
3098 atreq = tcore_at_request_new((const char *)cmd_str, "+CRSM", TCORE_AT_SINGLELINE);
3099 pending = tcore_pending_new(obj, 0);
3101 if (NULL == cmd_str || NULL == atreq || NULL == pending)
3103 err("NULL pointer. Unable to proceed");
3104 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
3106 //free memory we own
3108 util_sms_free_memory(atreq);
3109 util_sms_free_memory(pending);
3112 return TCORE_RETURN_FAILURE;
3115 util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
3117 tcore_pending_set_request_data(pending, 0, atreq);
3118 tcore_pending_set_timeout(pending, 0);
3119 tcore_pending_set_response_callback(pending, on_response_get_paramcnt, NULL);
3120 tcore_pending_link_user_request(pending, ur);
3121 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
3122 tcore_hal_send_request(hal, pending);
3127 return TCORE_RETURN_SUCCESS;
3130 static struct tcore_sms_operations sms_ops =
3132 .send_umts_msg = send_umts_msg,
3133 .read_msg = read_msg,
3134 .save_msg = save_msg,
3135 .delete_msg = delete_msg,
3136 .get_storedMsgCnt = get_storedMsgCnt,
3139 .get_cb_config = get_cb_config,
3140 .set_cb_config = set_cb_config,
3141 .set_mem_status = set_mem_status,
3142 .get_pref_brearer = NULL,
3143 .set_pref_brearer = NULL,
3144 .set_delivery_report = set_delivery_report,
3145 .set_msg_status = set_msg_status,
3146 .get_sms_params = get_sms_params,
3147 .set_sms_params = set_sms_params,
3148 .get_paramcnt = get_paramcnt,
3151 gboolean s_sms_init(TcorePlugin *plugin, TcoreHal *hal)
3153 CoreObject *obj = NULL;
3154 struct property_sms_info *data = NULL;
3155 GQueue *work_queue = NULL;
3156 int *smsp_record_len = NULL;
3159 dbg("plugin: [%p]", plugin);
3160 dbg("hal: [%p]", hal);
3162 obj = tcore_sms_new(plugin, "umts_sms", &sms_ops, hal);
3164 data = calloc(sizeof(struct property_sms_info), 1);
3166 if (NULL == obj || NULL == data)
3168 err("Unable to initialize. Exiting");
3175 work_queue = g_queue_new();
3176 tcore_object_link_user_data(obj, work_queue);
3178 //Registering for SMS notifications
3179 tcore_object_add_callback(obj, "\e+CMTI", on_event_sms_incom_msg, NULL);
3180 tcore_object_add_callback(obj, "\e+CMT", on_event_sms_incom_msg, NULL);
3182 tcore_object_add_callback(obj, "\e+CDS", on_event_sms_incom_msg, NULL);
3183 tcore_object_add_callback(obj, "\e+CDSI", on_event_sms_incom_msg, NULL);
3185 tcore_object_add_callback(obj, "+XSMSMMSTAT", on_event_sms_memory_status, NULL);
3187 tcore_object_add_callback(obj, "\e+CBMI", on_event_sms_cb_incom_msg, NULL);
3188 tcore_object_add_callback(obj, "\e+CBM", on_event_sms_cb_incom_msg, NULL);
3189 tcore_object_add_callback(obj, "+XSIM", on_event_sms_ready_status, NULL);
3191 tcore_plugin_link_property(plugin, "SMS", data);
3193 //storing smsp record length
3194 smsp_record_len = calloc(sizeof(int), 1);
3195 tcore_plugin_link_property(plugin, "SMSPRECORDLEN", smsp_record_len);
3201 void s_sms_exit(TcorePlugin *plugin)
3203 CoreObject *obj = NULL;
3204 struct property_sms_info *data = NULL;
3207 dbg("plugin: [%p]", plugin);
3209 obj = tcore_plugin_ref_core_object(plugin, "umts_sms");
3212 err("NULL core object. Nothing to do.");
3215 tcore_sms_free(obj);
3217 data = tcore_plugin_ref_property(plugin, "SMS");
3218 util_sms_free_memory(data);