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>
43 #include "common/TelErr.h"
47 /*=============================================================
49 ==============================================================*/
50 #define MAX_GSM_SMS_TPDU_SIZE 244
51 #define MAX_GSM_SMS_MSG_NUM 255
52 #define MAX_GSM_SMS_SERVICE_CENTER_ADDR 12 /* Maximum number of bytes of service center address */
53 #define MAX_GSM_SMS_CBMI_LIST_SIZE 100 /* Maximum number of CBMI list size for CBS 30*2=60 */
54 #define MAX_GSM_SMS_PARAM_RECORD_SIZE 156 /* Maximum number of bytes SMSP Record size (Y + 28), y : 0 ~ 128 */
55 #define MAX_GSM_SMS_STATUS_FILE_SIZE 2 /* Last Used TP-MR + SMS "Memory Cap. Exceeded" Noti Flag */
56 #define TAPI_SIM_SMSP_ADDRESS_LEN 20
58 /*=============================================================
60 ==============================================================*/
61 #define AT_SMS_DEVICE_READY 12 /* AT device ready */
62 #define SMS_DEVICE_READY 1 /* Telephony device ready */
63 #define SMS_DEVICE_NOT_READY 0 /* Telephony device not ready */
65 /*=============================================================
67 ==============================================================*/
68 #define SMS_CBMI_SELECTED_SOME 0x02 /* Some CBMIs are selected */
69 #define SMS_CBMI_SELECTED_ALL 0x01 /* All CBMIs are selected */
71 /*=============================================================
73 ==============================================================*/
74 #define AT_REC_UNREAD 0 /* Received and Unread */
75 #define AT_REC_READ 1 /* Received and Read */
76 #define AT_STO_UNSENT 2 /* Unsent */
77 #define AT_STO_SENT 3 /* Sent */
78 #define AT_ALL 4 /* Unknown */
80 /*=============================================================
82 ==============================================================*/
83 #define AT_MEMORY_AVAILABLE 0 /* Memory Available */
84 #define AT_MEMORY_FULL 1 /* Memory Full */
86 /*=============================================================
87 SIM CRSM SW1 and Sw2 Error definitions */
89 #define AT_SW1_SUCCESS 0x90
90 #define AT_SW2_SUCCESS 0
91 #define AT_SW1_LEN_RESP 0x9F
93 #define AT_MAX_RECORD_LEN 256
94 /* SCA 12 bytes long and TDPU is 164 bytes long */
95 #define PDU_LEN_MAX 176
96 #define HEX_PDU_LEN_MAX ((PDU_LEN_MAX * 2) + 1)
98 /*=============================================================
100 ==============================================================*/
101 #define CR '\r' /* Carriage Return */
103 /*=============================================================
105 ==============================================================*/
106 #define SMS_SWAPBYTES16(x) (((x) & 0xffff0000) | (((x) & 0x0000ff00) >> 8) | (((x) & 0x000000ff) << 8))
108 void print_glib_list_elem(gpointer data, gpointer user_data);
110 static void on_response_class2_read_msg(TcorePending *pending, int data_len, const void *data, void *user_data);
113 gboolean util_byte_to_hex(const char *byte_pdu, char *hex_pdu, int num_bytes);
115 void print_glib_list_elem(gpointer data, gpointer user_data)
117 char *item = (char *)data;
119 dbg("item: [%s]", item);
122 /*=============================================================
124 ==============================================================*/
125 static void on_confirmation_sms_message_send(TcorePending *p, gboolean result, void *user_data)
127 dbg("Entered Function. Request message out from queue");
129 dbg("TcorePending: [%p]", p);
130 dbg("result: [%02x]", result);
131 dbg("user_data: [%p]", user_data);
133 if (result == TRUE) {
135 } else { /* Failed */
139 dbg("Exiting Function. Nothing to return");
142 /*=============================================================
144 ==============================================================*/
145 static void util_sms_free_memory(void *sms_ptr)
149 if (NULL != sms_ptr) {
150 dbg("Freeing memory location: [%p]", sms_ptr);
154 err("Invalid memory location. Nothing to do.");
161 static int util_sms_decode_smsParameters(unsigned char *incoming, unsigned int length, struct telephony_sms_Params *params)
163 int alpha_id_len = 0;
167 dbg(" RecordLen = %d", length);
169 if(incoming == NULL || params == NULL)
172 alpha_id_len = length -SMS_SMSP_PARAMS_MAX_LEN;
174 if (alpha_id_len > 0) {
175 if (alpha_id_len > SMS_SMSP_ALPHA_ID_LEN_MAX) {
176 alpha_id_len = SMS_SMSP_ALPHA_ID_LEN_MAX;
179 for (i = 0; i < alpha_id_len; i++) {
180 if (0xff == incoming[i]) {
186 memcpy(params->szAlphaId, incoming, i);
188 params->alphaIdLen = i;
190 dbg(" Alpha id length = %d", i);
192 params->alphaIdLen = 0;
193 dbg(" Alpha id length is zero");
196 params->paramIndicator = incoming[alpha_id_len];
198 dbg(" Param Indicator = %02x", params->paramIndicator);
200 if ((params->paramIndicator & SMSPValidDestAddr) == 0) {
201 nOffset = nDestAddrOffset;
203 if (0x00 == incoming[alpha_id_len + nOffset] || 0xff == incoming[alpha_id_len + nOffset]) {
204 params->tpDestAddr.dialNumLen = 0;
206 dbg("DestAddr Length is 0");
208 if (0 < (int) incoming[alpha_id_len + nOffset]) {
209 params->tpDestAddr.dialNumLen = (int) (incoming[alpha_id_len + nOffset] - 1);
211 if (params->tpDestAddr.dialNumLen > SMS_SMSP_ADDRESS_LEN)
212 params->tpDestAddr.dialNumLen = SMS_SMSP_ADDRESS_LEN;
214 params->tpDestAddr.dialNumLen = 0;
217 params->tpDestAddr.numPlanId = incoming[alpha_id_len + (++nOffset)] & 0x0f;
218 params->tpDestAddr.typeOfNum = (incoming[alpha_id_len + nOffset] & 0x70) >> 4;
220 memcpy(params->tpDestAddr.diallingNum, &incoming[alpha_id_len + (++nOffset)], (params->tpDestAddr.dialNumLen));
222 dbg("Dest TON is %d", params->tpDestAddr.typeOfNum);
223 dbg("Dest NPI is %d", params->tpDestAddr.numPlanId);
224 dbg("Dest Length = %d", params->tpDestAddr.dialNumLen);
225 dbg("Dest Addr = %s", params->tpDestAddr.diallingNum);
228 params->tpDestAddr.dialNumLen = 0;
231 if ((params->paramIndicator & SMSPValidSvcAddr) == 0) {
232 nOffset = nSCAAddrOffset;
234 if (0x00 == (int) incoming[alpha_id_len + nOffset] || 0xff == (int) incoming[alpha_id_len + nOffset]) {
235 params->tpSvcCntrAddr.dialNumLen = 0;
237 dbg(" SCAddr Length is 0");
239 if (0 < (int) incoming[alpha_id_len + nOffset]) {
240 params->tpSvcCntrAddr.dialNumLen = (int) (incoming[alpha_id_len + nOffset] - 1);
242 if (params->tpSvcCntrAddr.dialNumLen > SMS_SMSP_ADDRESS_LEN)
243 params->tpSvcCntrAddr.dialNumLen = SMS_SMSP_ADDRESS_LEN;
245 params->tpSvcCntrAddr.numPlanId = incoming[alpha_id_len + (++nOffset)] & 0x0f;
246 params->tpSvcCntrAddr.typeOfNum = (incoming[alpha_id_len + nOffset] & 0x70) >> 4;
248 memcpy(params->tpSvcCntrAddr.diallingNum, &incoming[alpha_id_len + (++nOffset)], (params->tpSvcCntrAddr.dialNumLen));
250 dbg("SCAddr Length = %d ", params->tpSvcCntrAddr.dialNumLen);
251 dbg("SCAddr TON is %d", params->tpSvcCntrAddr.typeOfNum);
252 dbg("SCAddr NPI is %d", params->tpSvcCntrAddr.numPlanId);
254 for (i = 0; i < (int) params->tpSvcCntrAddr.dialNumLen; i++)
255 dbg("SCAddr = %d [%02x]", i, params->tpSvcCntrAddr.diallingNum[i]);
257 params->tpSvcCntrAddr.dialNumLen = 0;
260 } else if ((0x00 < (int) incoming[alpha_id_len + nSCAAddrOffset] && (int) incoming[alpha_id_len + nSCAAddrOffset] <= 12)
261 || 0xff != (int) incoming[alpha_id_len + nSCAAddrOffset]) {
262 nOffset = nSCAAddrOffset;
264 if (0x00 == (int) incoming[alpha_id_len + nOffset] || 0xff == (int) incoming[alpha_id_len + nOffset]) {
265 params->tpSvcCntrAddr.dialNumLen = 0;
266 dbg("SCAddr Length is 0");
268 if (0 < (int) incoming[alpha_id_len + nOffset]) {
269 params->tpSvcCntrAddr.dialNumLen = (int) (incoming[alpha_id_len + nOffset] - 1);
271 params->tpSvcCntrAddr.dialNumLen = incoming[alpha_id_len + nOffset] - 1;
273 if (params->tpSvcCntrAddr.dialNumLen > SMS_SMSP_ADDRESS_LEN)
274 params->tpSvcCntrAddr.dialNumLen = SMS_SMSP_ADDRESS_LEN;
276 params->tpSvcCntrAddr.numPlanId = incoming[alpha_id_len + (++nOffset)] & 0x0f;
277 params->tpSvcCntrAddr.typeOfNum = (incoming[alpha_id_len + nOffset] & 0x70) >> 4;
279 memcpy(params->tpSvcCntrAddr.diallingNum, &incoming[alpha_id_len + (++nOffset)],
280 (params->tpSvcCntrAddr.dialNumLen));
282 dbg("SCAddr Length = %d ", params->tpSvcCntrAddr.dialNumLen);
283 dbg("SCAddr TON is %d", params->tpSvcCntrAddr.typeOfNum);
284 dbg("SCAddr NPI is %d", params->tpSvcCntrAddr.numPlanId);
286 for (i = 0; i < (int) params->tpSvcCntrAddr.dialNumLen; i++)
287 dbg("SCAddr = %d [%02x]", i, params->tpSvcCntrAddr.diallingNum[i]);
289 params->tpSvcCntrAddr.dialNumLen = 0;
293 params->tpSvcCntrAddr.dialNumLen = 0;
296 if ((params->paramIndicator & SMSPValidPID) == 0 && (alpha_id_len + nPIDOffset) < MAX_GSM_SMS_PARAM_RECORD_SIZE) {
297 params->tpProtocolId = incoming[alpha_id_len + nPIDOffset];
299 if ((params->paramIndicator & SMSPValidDCS) == 0 && (alpha_id_len + nDCSOffset) < MAX_GSM_SMS_PARAM_RECORD_SIZE) {
300 params->tpDataCodingScheme = incoming[alpha_id_len + nDCSOffset];
302 if ((params->paramIndicator & SMSPValidVP) == 0 && (alpha_id_len + nVPOffset) < MAX_GSM_SMS_PARAM_RECORD_SIZE) {
303 params->tpValidityPeriod = incoming[alpha_id_len + nVPOffset];
306 dbg(" Alpha Id(Len) = %d", (int) params->alphaIdLen);
308 for (i = 0; i < (int) params->alphaIdLen; i++) {
309 dbg(" Alpha Id = [%d] [%c]", i, params->szAlphaId[i]);
311 dbg(" PID = %d",params->tpProtocolId);
312 dbg(" DCS = %d",params->tpDataCodingScheme);
313 dbg(" VP = %d",params->tpValidityPeriod);
319 /*=============================================================
321 ==============================================================*/
322 static gboolean on_event_sms_ready_status(CoreObject *o, const void *event_info, void *user_data)
324 struct tnoti_sms_ready_status readyStatusInfo = {0,};
326 GSList *tokens = NULL;
327 GSList *lines = NULL;
329 //CoreObject *o = NULL;
331 int rtn = -1 , status = 0;
333 dbg(" Func Entrance");
335 lines = (GSList *)event_info;
336 if (1 != g_slist_length(lines)) {
337 dbg("unsolicited msg but multiple line");
340 line = (char *) (lines->data);
342 dbg(" Func Entrance");
346 dbg("noti line is %s", line);
347 tokens = tcore_at_tok_new(line);
348 pResp = g_slist_nth_data(tokens, 0);
350 status = atoi(pResp);
355 if (status == AT_SMS_DEVICE_READY) {
356 readyStatusInfo.status = SMS_DEVICE_READY;
357 tcore_sms_set_ready_status(o, readyStatusInfo.status);
358 dbg("SMS Ready status = [%s]", readyStatusInfo.status ? "TRUE" : "FALSE");
359 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);
360 dbg(" Return value [%d]", rtn);
362 readyStatusInfo.status = SMS_DEVICE_NOT_READY;
367 tcore_at_tok_free(tokens);
371 static gboolean on_event_class2_sms_incom_msg(CoreObject *obj, const void *event_info, void *user_data)
373 //+CMTI: <mem>,<index>
375 GSList *tokens = NULL , *lines = NULL;
376 char *line = NULL, *cmd_str = NULL;
377 int index = 0, mem_type = 0;
378 TcoreHal *hal = NULL;
379 TcoreATRequest *atreq = NULL;
380 TcorePending *pending = NULL;
382 dbg("Entered Function");
384 lines = (GSList *)event_info;
385 line = (char *)g_slist_nth_data(lines, 0); /* Fetch Line 1 */
387 dbg("Line 1: [%s]", line);
390 err("Line 1 is invalid");
394 tokens = tcore_at_tok_new(line); /* Split Line 1 into tokens */
395 mem_type = atoi(g_slist_nth_data(tokens, 0)); // Type of Memory stored
396 index = atoi((char *) g_slist_nth_data(tokens, 1));
398 hal = tcore_object_get_hal(obj);
400 err("NULL input. Unable to proceed");
401 dbg("readMsg: hal: [%p]", hal);
404 return TCORE_RETURN_EINVAL;
407 dbg("index: [%d]", index);
409 cmd_str = g_strdup_printf("AT+CMGR=%d", index);
410 atreq = tcore_at_request_new((const char *)cmd_str, "+CMGR", TCORE_AT_PDU);
411 pending = tcore_pending_new(obj, 0);
413 if (NULL == cmd_str || NULL == atreq || NULL == pending) {
414 err("Out of memory. Unable to proceed");
415 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
419 util_sms_free_memory(atreq);
420 util_sms_free_memory(pending);
423 return TCORE_RETURN_ENOMEM;
426 util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
428 tcore_pending_set_request_data(pending, 0, atreq);
429 tcore_pending_set_response_callback(pending, on_response_class2_read_msg, (void *)(uintptr_t)index); //storing index as user data for response
430 tcore_pending_link_user_request(pending, NULL);
431 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
432 tcore_hal_send_request(hal, pending);
436 tcore_at_tok_free(tokens);
441 static gboolean on_event_sms_incom_msg(CoreObject *o, const void *event_info, void *user_data)
443 //+CMT: [<alpha>],<length><CR><LF><pdu> (PDU mode enabled);
446 GSList *tokens = NULL;
447 GSList *lines = NULL;
449 int pdu_len = 0, no_of_tokens = 0;
450 unsigned char *bytePDU = NULL;
451 struct tnoti_sms_umts_msg gsmMsgInfo;
454 dbg("Entered Function");
456 lines = (GSList *)event_info;
457 memset(&gsmMsgInfo, 0x00, sizeof(struct tnoti_sms_umts_msg));
459 if (2 != g_slist_length(lines)) {
460 err("Invalid number of lines for +CMT. Must be 2");
464 line = (char *)g_slist_nth_data(lines, 0); /* Fetch Line 1 */
466 dbg("Line 1: [%s]", line);
469 err("Line 1 is invalid");
473 tokens = tcore_at_tok_new(line); /* Split Line 1 into tokens */
475 no_of_tokens = g_slist_length(tokens);
477 if (no_of_tokens == 2) { // in case of incoming SMS +CMT
478 dbg("Alpha ID: [%02x]", g_slist_nth_data(tokens, 0)); /* 0: Alpha ID */
479 pdu_len = atoi((char *)g_slist_nth_data(tokens, 1));
480 dbg("pdu_len: [%d]", pdu_len); /* 1: PDU Length */
481 } else if (no_of_tokens == 1) { // in case of incoming status report +CDS
482 pdu_len = atoi((char *)g_slist_nth_data(tokens, 0));
483 dbg("pdu_len: [%d]", pdu_len); /* 1: PDU Length */
486 line = (char *)g_slist_nth_data(lines, 1); /* Fetch Line 2 */
488 dbg("Line 2: [%s]", line);
491 err("Line 2 is invalid");
495 /* Convert to Bytes */
496 bytePDU = (unsigned char *)util_hexStringToBytes(line);
498 sca_length = bytePDU[0];
500 dbg("SCA length = %d", sca_length);
502 gsmMsgInfo.msgInfo.msgLength = pdu_len;
504 if (sca_length == 0) {
505 memcpy(gsmMsgInfo.msgInfo.tpduData, &bytePDU[1], gsmMsgInfo.msgInfo.msgLength);
507 memcpy(gsmMsgInfo.msgInfo.sca, &bytePDU[1], sca_length);
508 memcpy(gsmMsgInfo.msgInfo.tpduData, &bytePDU[sca_length+1], gsmMsgInfo.msgInfo.msgLength);
511 util_hex_dump(" ", strlen(line)/2, bytePDU);
512 util_hex_dump(" ", sca_length, gsmMsgInfo.msgInfo.sca);
513 util_hex_dump(" ", gsmMsgInfo.msgInfo.msgLength,gsmMsgInfo.msgInfo.tpduData);
515 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);
518 tcore_at_tok_free(tokens);
527 static gboolean on_event_sms_memory_status(CoreObject *o, const void *event_info, void *user_data)
529 struct tnoti_sms_memory_status memStatusInfo = {0,};
531 int rtn = -1 ,memoryStatus = -1;
534 char *line = NULL , *pResp = NULL;
538 lines = (GSList *)event_info;
539 if (1 != g_slist_length(lines)) {
540 dbg("unsolicited msg but multiple line");
543 line = (char*)(lines->data);
547 tokens = tcore_at_tok_new(line);
548 pResp = g_slist_nth_data(tokens, 0);
551 memoryStatus = atoi(pResp);
552 dbg("memoryStatus is %d",memoryStatus);
553 if (memoryStatus == 0) {//SIM Full condition
554 memStatusInfo.status = SMS_PHONE_MEMORY_STATUS_FULL;
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);
558 tcore_at_tok_free(tokens);
567 static gboolean on_event_sms_cb_incom_msg(CoreObject *o, const void *event_info, void *user_data)
569 //+CBM: <length><CR><LF><pdu>
571 struct tnoti_sms_cellBroadcast_msg cbMsgInfo;
573 int rtn = -1 , length = 0;
574 char * line = NULL, *pdu = NULL, *pResp = NULL;
575 GSList *tokens = NULL;
576 GSList *lines = NULL;
578 dbg(" Func Entrance");
580 lines = (GSList *)event_info;
582 memset(&cbMsgInfo, 0, sizeof(struct tnoti_sms_cellBroadcast_msg));
584 line = (char *)(lines->data);
588 dbg("Noti line is %s",line);
589 tokens = tcore_at_tok_new(line); /* Split Line 1 into tokens */
591 pResp = g_slist_nth_data(tokens, 0);
593 length = atoi(pResp);
595 dbg("token 0 is null");
598 pdu = g_slist_nth_data(lines, 1);
600 cbMsgInfo.cbMsg.length = length;
601 cbMsgInfo.cbMsg.cbMsgType = SMS_CB_MSG_GSM;
603 dbg("CB Msg LENGTH [%2x]", length);
605 if ((cbMsgInfo.cbMsg.length >0) && (SMS_CB_SIZE_MAX >= cbMsgInfo.cbMsg.length)) {
606 unsigned char *byte_pdu = NULL;
608 byte_pdu = (unsigned char *)util_hexStringToBytes(pdu);
610 memcpy(cbMsgInfo.cbMsg.msgData, (char*)byte_pdu, cbMsgInfo.cbMsg.length);
611 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);
614 dbg("Invalid Message Length");
617 dbg("Recieved NULL pdu");
623 dbg(" Return value [%d]",rtn);
626 tcore_at_tok_free(tokens);
632 /*=============================================================
634 ==============================================================*/
635 static void on_response_sms_delete_msg(TcorePending *p, int data_len, const void *data, void *user_data)
637 struct tresp_sms_delete_msg delMsgInfo = {0,};
638 UserRequest *ur = NULL;
639 const TcoreATResponse *atResp = data;
642 int index = (int) user_data;
644 dbg(" Func Entrance");
646 ur = tcore_pending_ref_user_request(p);
647 if (atResp->success) {
649 delMsgInfo.index = index;
650 delMsgInfo.result = SMS_SENDSMS_SUCCESS;
653 delMsgInfo.index = index;
654 delMsgInfo.result = SMS_DEVICE_FAILURE;
657 rtn = tcore_user_request_send_response(ur, TRESP_SMS_DELETE_MSG, sizeof(struct tresp_sms_delete_msg), &delMsgInfo);
662 static void on_response_sms_save_msg(TcorePending *p, int data_len, const void *data, void *user_data)
664 struct tresp_sms_save_msg saveMsgInfo = {0,};
665 UserRequest *ur = NULL;
666 const TcoreATResponse *atResp = data;
667 GSList *tokens = NULL;
672 ur = tcore_pending_ref_user_request(p);
673 if (atResp->success) {
676 line = (char *)atResp->lines->data;
677 tokens = tcore_at_tok_new(line);
678 pResp = g_slist_nth_data(tokens, 0);
681 saveMsgInfo.index = (atoi(pResp) - 1); /* IMC index starts from 1 */
682 saveMsgInfo.result = SMS_SENDSMS_SUCCESS;
685 saveMsgInfo.index = -1;
686 saveMsgInfo.result = SMS_DEVICE_FAILURE;
688 tcore_at_tok_free(tokens);
692 saveMsgInfo.index = -1;
693 saveMsgInfo.result = SMS_DEVICE_FAILURE;
696 rtn = tcore_user_request_send_response(ur, TRESP_SMS_SAVE_MSG, sizeof(struct tresp_sms_save_msg), &saveMsgInfo);
697 dbg("Return value [%d]", rtn);
701 static void on_response_send_umts_msg(TcorePending *pending, int data_len, const void *data, void *user_data)
703 const TcoreATResponse *at_response = data;
704 struct tresp_sms_send_umts_msg resp_umts;
705 UserRequest *user_req = NULL;
708 GSList *tokens = NULL;
709 char *gslist_line = NULL, *line_token = NULL;
713 user_req = tcore_pending_ref_user_request(pending);
715 if (NULL == user_req) {
716 err("No user request");
722 memset(&resp_umts, 0x00, sizeof(resp_umts));
723 resp_umts.result = SMS_DEVICE_FAILURE;
725 if (at_response->success > 0) { // success
727 if (at_response->lines) { // lines present in at_response
728 gslist_line = (char *)at_response->lines->data;
729 dbg("gslist_line: [%s]", gslist_line);
731 tokens = tcore_at_tok_new(gslist_line); //extract tokens
733 line_token = g_slist_nth_data(tokens, 0);
734 if (line_token != NULL) {
735 msg_ref = atoi(line_token);
736 dbg("Message Reference: [%d]", msg_ref);
738 resp_umts.result = SMS_SENDSMS_SUCCESS;
740 dbg("No Message Reference received");
742 tcore_at_tok_free(tokens);
743 } else { // no lines in at_response
750 tcore_user_request_send_response(user_req, TRESP_SMS_SEND_UMTS_MSG, sizeof(resp_umts), &resp_umts);
756 static void on_response_class2_read_msg(TcorePending *pending, int data_len, const void *data, void *user_data)
758 const TcoreATResponse *at_response = data;
760 char *gslist_line = NULL, *line_token = NULL, *hex_pdu = NULL;
761 int pdu_len = 0, rtn = 0;
762 unsigned char *bytePDU = NULL;
763 struct tnoti_sms_umts_msg gsmMsgInfo;
767 dbg("lines: [%p]", at_response->lines);
768 g_slist_foreach(at_response->lines, print_glib_list_elem, NULL); //for debug log
770 if (at_response->success > 0) {
772 if (at_response->lines) {
774 gslist_line = (char *)at_response->lines->data;
776 dbg("gslist_line: [%s]", gslist_line);
778 tokens = tcore_at_tok_new(gslist_line);
779 dbg("Number of tokens: [%d]", g_slist_length(tokens));
780 g_slist_foreach(tokens, print_glib_list_elem, NULL); //for debug log
782 line_token = g_slist_nth_data(tokens, 2); //Third Token: Length
783 if (line_token != NULL) {
784 pdu_len = atoi(line_token);
785 dbg("Length: [%d]", pdu_len);
789 gslist_line = (char *)at_response->lines->next->data;
791 dbg("gslist_line: [%s]", gslist_line);
793 //free the consumed token
794 tcore_at_tok_free(tokens);
796 tokens = tcore_at_tok_new(gslist_line);
797 dbg("Number of tokens: [%d]", g_slist_length(tokens));
798 g_slist_foreach(tokens, print_glib_list_elem, NULL); //for debug log
800 hex_pdu = g_slist_nth_data(tokens, 0); //Fetch SMS PDU
802 //free the consumed token
803 tcore_at_tok_free(tokens);
811 /* Convert to Bytes */
812 bytePDU = (unsigned char *)util_hexStringToBytes(hex_pdu);
814 sca_length = bytePDU[0];
816 dbg("SCA length = %d", sca_length);
818 gsmMsgInfo.msgInfo.msgLength = pdu_len;
820 if (sca_length == 0) {
821 memcpy(gsmMsgInfo.msgInfo.tpduData, &bytePDU[1], gsmMsgInfo.msgInfo.msgLength);
823 memcpy(gsmMsgInfo.msgInfo.sca, bytePDU, sca_length);
824 memcpy(gsmMsgInfo.msgInfo.tpduData, &bytePDU[sca_length+1], gsmMsgInfo.msgInfo.msgLength);
827 util_hex_dump(" ", strlen(hex_pdu)/2, bytePDU);
828 util_hex_dump(" ", sca_length, gsmMsgInfo.msgInfo.sca);
829 util_hex_dump(" ", gsmMsgInfo.msgInfo.msgLength,gsmMsgInfo.msgInfo.tpduData);
831 rtn = tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(tcore_pending_ref_core_object(pending))), tcore_pending_ref_core_object(pending), TNOTI_SMS_INCOM_MSG, sizeof(struct tnoti_sms_umts_msg), &gsmMsgInfo);
839 static void on_response_read_msg(TcorePending *pending, int data_len, const void *data, void *user_data)
841 const TcoreATResponse *at_response = data;
842 struct tresp_sms_read_msg resp_read_msg;
843 UserRequest *user_req = NULL;
846 char *gslist_line = NULL, *line_token = NULL, *byte_pdu = NULL, *hex_pdu = NULL;
848 int msg_status = 0, alpha_id = 0, pdu_len = 0;
849 int index = (int)(uintptr_t)user_data;
852 dbg("index: [%d]", index);
853 g_slist_foreach(at_response->lines, print_glib_list_elem, NULL); //for debug log
855 user_req = tcore_pending_ref_user_request(pending);
856 if (NULL == user_req) {
857 err("No user request");
863 memset(&resp_read_msg, 0x00, sizeof(resp_read_msg));
864 resp_read_msg.result = SMS_PHONE_FAILURE;
866 if (at_response->success > 0) {
868 if (at_response->lines) {
870 gslist_line = (char *)at_response->lines->data;
872 dbg("gslist_line: [%s]", gslist_line);
874 tokens = tcore_at_tok_new(gslist_line);
875 dbg("Number of tokens: [%d]", g_slist_length(tokens));
876 g_slist_foreach(tokens, print_glib_list_elem, NULL); //for debug log
878 line_token = g_slist_nth_data(tokens, 0); //First Token: Message Status
879 if (line_token != NULL) {
880 msg_status = atoi(line_token);
881 dbg("msg_status is %d",msg_status);
882 switch (msg_status) {
884 resp_read_msg.dataInfo.msgStatus = SMS_STATUS_UNREAD;
888 resp_read_msg.dataInfo.msgStatus = SMS_STATUS_READ;
892 resp_read_msg.dataInfo.msgStatus = SMS_STATUS_UNSENT;
896 resp_read_msg.dataInfo.msgStatus = SMS_STATUS_SENT;
899 case AT_ALL: //Fall Through
900 default: //Fall Through
901 resp_read_msg.dataInfo.msgStatus = SMS_STATUS_RESERVED;
906 line_token = g_slist_nth_data(tokens, 1); //Second Token: AlphaID
907 if (line_token != NULL) {
908 alpha_id = atoi(line_token);
909 dbg("AlphaID: [%d]", alpha_id);
912 line_token = g_slist_nth_data(tokens, 2); //Third Token: Length
913 if (line_token != NULL) {
914 pdu_len = atoi(line_token);
915 dbg("Length: [%d]", pdu_len);
919 hex_pdu = (char *) at_response->lines->next->data;
921 dbg("EF-SMS PDU: [%s]", hex_pdu);
923 //free the consumed token
924 tcore_at_tok_free(tokens);
926 if (NULL != hex_pdu) {
927 util_hex_dump(" ", sizeof(hex_pdu), (void *)hex_pdu);
929 byte_pdu = util_hexStringToBytes(hex_pdu);
931 sca_length = (int)byte_pdu[0];
933 resp_read_msg.dataInfo.simIndex = index; //Retrieving index stored as user_data
935 dbg("SCA Length : %d", sca_length);
937 resp_read_msg.dataInfo.smsData.msgLength = pdu_len;
938 dbg("msgLength: [%d]", resp_read_msg.dataInfo.smsData.msgLength);
940 if(0 == sca_length) {
941 if ((resp_read_msg.dataInfo.smsData.msgLength > 0)
942 && (resp_read_msg.dataInfo.smsData.msgLength <= SMS_SMDATA_SIZE_MAX)) {
943 memset(resp_read_msg.dataInfo.smsData.sca, 0, TAPI_SIM_SMSP_ADDRESS_LEN);
944 memcpy(resp_read_msg.dataInfo.smsData.tpduData, &byte_pdu[1], resp_read_msg.dataInfo.smsData.msgLength);
946 resp_read_msg.result = SMS_SUCCESS;
948 dbg("Invalid Message Length");
949 resp_read_msg.result = SMS_INVALID_PARAMETER_FORMAT;
952 if ((resp_read_msg.dataInfo.smsData.msgLength > 0)
953 && (resp_read_msg.dataInfo.smsData.msgLength <= SMS_SMDATA_SIZE_MAX)) {
954 memcpy(resp_read_msg.dataInfo.smsData.sca, (char *)byte_pdu, (sca_length+1));
955 memcpy(resp_read_msg.dataInfo.smsData.tpduData, &byte_pdu[sca_length+1], resp_read_msg.dataInfo.smsData.msgLength);
957 util_hex_dump(" ", SMS_SMSP_ADDRESS_LEN, (void *)resp_read_msg.dataInfo.smsData.sca);
958 util_hex_dump(" ", (SMS_SMDATA_SIZE_MAX + 1), (void *)resp_read_msg.dataInfo.smsData.tpduData);
959 util_hex_dump(" ", sizeof(byte_pdu), (void *)byte_pdu);
961 resp_read_msg.result = SMS_SUCCESS;
963 dbg("Invalid Message Length");
964 resp_read_msg.result = SMS_INVALID_PARAMETER_FORMAT;
978 tcore_user_request_send_response(user_req, TRESP_SMS_READ_MSG, sizeof(resp_read_msg), &resp_read_msg);
984 static void on_response_get_msg_indices(TcorePending *pending, int data_len, const void *data, void *user_data)
986 const TcoreATResponse *at_response = data;
987 struct tresp_sms_get_storedMsgCnt resp_stored_msg_cnt;
988 UserRequest *user_req = NULL;
989 struct tresp_sms_get_storedMsgCnt *resp_stored_msg_cnt_prev = NULL;
991 GSList *tokens = NULL;
992 char *gslist_line = NULL, *line_token = NULL;
993 int gslist_line_count = 0, ctr_loop = 0;
997 resp_stored_msg_cnt_prev = (struct tresp_sms_get_storedMsgCnt *)user_data;
998 user_req = tcore_pending_ref_user_request(pending);
1000 memset(&resp_stored_msg_cnt, 0x00, sizeof(resp_stored_msg_cnt));
1001 resp_stored_msg_cnt.result = SMS_DEVICE_FAILURE;
1003 if (at_response->success) {
1005 if (at_response->lines) {
1006 gslist_line_count = g_slist_length(at_response->lines);
1008 if (gslist_line_count > SMS_GSM_SMS_MSG_NUM_MAX)
1009 gslist_line_count = SMS_GSM_SMS_MSG_NUM_MAX;
1011 dbg("Number of lines: [%d]", gslist_line_count);
1012 g_slist_foreach(at_response->lines, print_glib_list_elem, NULL); //for debug log
1014 for (ctr_loop = 0; ctr_loop < gslist_line_count; ctr_loop++) {
1015 gslist_line = (char *)g_slist_nth_data(at_response->lines, ctr_loop); /* Fetch Line i */
1017 dbg("gslist_line [%d] is [%s]", ctr_loop, gslist_line);
1019 if (NULL != gslist_line) {
1020 tokens = tcore_at_tok_new(gslist_line);
1022 g_slist_foreach(tokens, print_glib_list_elem, NULL); //for debug log
1024 line_token = g_slist_nth_data(tokens, 0);
1025 if (NULL != line_token) {
1026 resp_stored_msg_cnt.storedMsgCnt.indexList[ctr_loop] = atoi(line_token);
1027 resp_stored_msg_cnt.result = SMS_SENDSMS_SUCCESS;
1029 dbg("line_token of gslist_line [%d] is NULL", ctr_loop);
1032 tcore_at_tok_free(tokens);
1034 dbg("gslist_line [%d] is NULL", ctr_loop);
1040 if (resp_stored_msg_cnt_prev->storedMsgCnt.usedCount == 0) { // Check if used count is zero
1041 resp_stored_msg_cnt.result = SMS_SENDSMS_SUCCESS;
1045 dbg("Respnose NOK");
1048 resp_stored_msg_cnt.storedMsgCnt.totalCount = resp_stored_msg_cnt_prev->storedMsgCnt.totalCount;
1049 resp_stored_msg_cnt.storedMsgCnt.usedCount = resp_stored_msg_cnt_prev->storedMsgCnt.usedCount;
1051 util_sms_free_memory(resp_stored_msg_cnt_prev);
1053 dbg("total: [%d], used: [%d], result: [%d]", resp_stored_msg_cnt.storedMsgCnt.totalCount, resp_stored_msg_cnt.storedMsgCnt.usedCount, resp_stored_msg_cnt.result);
1054 for (ctr_loop = 0; ctr_loop < gslist_line_count; ctr_loop++) {
1055 dbg("index: [%d]", resp_stored_msg_cnt.storedMsgCnt.indexList[ctr_loop]);
1058 tcore_user_request_send_response(user_req, TRESP_SMS_GET_STORED_MSG_COUNT, sizeof(resp_stored_msg_cnt), &resp_stored_msg_cnt);
1064 static void on_response_get_stored_msg_cnt(TcorePending *pending, int data_len, const void *data, void *user_data)
1066 UserRequest *ur = NULL, *ur_dup = NULL;
1067 struct tresp_sms_get_storedMsgCnt *respStoredMsgCnt = NULL;
1068 const TcoreATResponse *atResp = data;
1069 GSList *tokens=NULL;
1070 char *line = NULL , *pResp = NULL , *cmd_str = NULL;
1071 TcoreATRequest *atReq = NULL;
1072 int usedCnt = 0, totalCnt = 0, result = 0;
1074 TcorePending *pending_new = NULL;
1075 CoreObject *o = NULL;
1079 respStoredMsgCnt = malloc(sizeof(struct tresp_sms_get_storedMsgCnt));
1080 result = SMS_DEVICE_FAILURE;
1082 ur = tcore_pending_ref_user_request(pending);
1083 ur_dup = tcore_user_request_ref(ur);
1084 o = tcore_pending_ref_core_object(pending);
1086 if (atResp->success > 0) {
1088 if (NULL != atResp->lines) {
1089 line = (char *)atResp->lines->data;
1090 dbg("line is %s",line);
1092 tokens = tcore_at_tok_new(line);
1093 pResp = g_slist_nth_data(tokens, 0);
1096 usedCnt =atoi(pResp);
1097 dbg("used cnt is %d",usedCnt);
1100 pResp = g_slist_nth_data(tokens, 1);
1102 totalCnt =atoi(pResp);
1103 result = SMS_SENDSMS_SUCCESS;
1105 respStoredMsgCnt->storedMsgCnt.usedCount = usedCnt;
1106 respStoredMsgCnt->storedMsgCnt.totalCount = totalCnt;
1107 respStoredMsgCnt->result = result;
1109 dbg("used %d, total %d, result %d",usedCnt, totalCnt,result);
1111 pending_new = tcore_pending_new(o, 0);
1112 //Get all messages information
1113 cmd_str = g_strdup_printf("AT+CMGL=4");
1114 atReq = tcore_at_request_new((const char *)cmd_str, "+CMGL", TCORE_AT_MULTILINE);
1116 dbg("cmd str is %s",cmd_str);
1118 tcore_pending_set_request_data(pending_new, 0,atReq);
1119 tcore_pending_set_response_callback(pending_new, on_response_get_msg_indices, (void *)respStoredMsgCnt);
1120 tcore_pending_link_user_request(pending_new, ur_dup);
1121 tcore_pending_set_send_callback(pending_new, on_confirmation_sms_message_send, NULL);
1122 tcore_hal_send_request(tcore_object_get_hal(o), pending_new);
1124 //free the consumed token
1125 tcore_at_tok_free(tokens);
1132 //free the consumed token
1134 tcore_at_tok_free(tokens);
1139 err("Response NOK");
1141 respStoredMsgCnt->result = result;
1142 tcore_user_request_send_response(ur, TRESP_SMS_GET_STORED_MSG_COUNT, sizeof(struct tresp_sms_get_storedMsgCnt), &respStoredMsgCnt);
1149 static void on_response_get_sca(TcorePending *pending, int data_len, const void *data, void *user_data)
1151 const TcoreATResponse *at_response = data;
1152 struct tresp_sms_get_sca respGetSca;
1153 UserRequest *user_req = NULL;
1155 GSList *tokens = NULL;
1156 char *gslist_line = NULL, *sca_addr = NULL, *sca_toa = NULL;
1160 memset(&respGetSca, 0, sizeof(respGetSca));
1161 respGetSca.result = SMS_DEVICE_FAILURE;
1163 user_req = tcore_pending_ref_user_request(pending);
1165 if (at_response->success) {
1167 if (at_response->lines) {
1168 gslist_line = (char *)at_response->lines->data;
1170 tokens = tcore_at_tok_new(gslist_line);
1171 sca_addr = g_slist_nth_data(tokens, 0);
1172 sca_toa = g_slist_nth_data(tokens, 1);
1174 if ((NULL != sca_addr)
1175 && (NULL != sca_toa)) {
1176 dbg("sca_addr: [%s]. sca_toa: [%s]", sca_addr, sca_toa);
1178 respGetSca.scaAddress.dialNumLen = strlen(sca_addr);
1180 if (145 == atoi(sca_toa)) {
1181 respGetSca.scaAddress.typeOfNum = SIM_TON_INTERNATIONAL;
1183 respGetSca.scaAddress.typeOfNum = SIM_TON_NATIONAL;
1186 respGetSca.scaAddress.numPlanId = 0;
1188 memcpy(respGetSca.scaAddress.diallingNum, sca_addr, strlen(sca_addr));
1190 dbg("len [%d], sca_addr [%s], TON [%d], NPI [%d]", respGetSca.scaAddress.dialNumLen, respGetSca.scaAddress.diallingNum, respGetSca.scaAddress.typeOfNum, respGetSca.scaAddress.numPlanId);
1192 respGetSca.result = SMS_SENDSMS_SUCCESS;
1194 err("sca_addr OR sca_toa NULL");
1200 dbg("Response NOK");
1203 tcore_user_request_send_response(user_req, TRESP_SMS_GET_SCA, sizeof(respGetSca), &respGetSca);
1206 tcore_at_tok_free(tokens);
1212 static void on_response_set_sca(TcorePending *pending, int data_len, const void *data, void *user_data)
1215 Response is expected in this format
1221 //copies the AT response data to resp
1222 const TcoreATResponse *atResp = data;
1223 struct tresp_sms_set_sca respSetSca;
1225 memset(&respSetSca, 0, sizeof(struct tresp_sms_set_sca));
1227 ur = tcore_pending_ref_user_request(pending);
1229 dbg("no user_request");
1233 if (atResp->success > 0) {
1235 respSetSca.result = SMS_SUCCESS;
1237 dbg("RESPONSE NOK");
1238 respSetSca.result = SMS_DEVICE_FAILURE;
1241 tcore_user_request_send_response(ur, TRESP_SMS_SET_SCA, sizeof(struct tresp_sms_set_sca), &respSetSca);
1246 static void on_response_get_cb_config(TcorePending *p, int data_len, const void *data, void *user_data)
1249 struct tresp_sms_get_cb_config respGetCbConfig;
1250 const TcoreATResponse *atResp = data;
1251 GSList *tokens=NULL;
1253 char *pResp = NULL, *line = NULL;
1256 memset(&respGetCbConfig, 0, sizeof(struct tresp_sms_get_cb_config));
1257 respGetCbConfig.result = SMS_DEVICE_FAILURE;
1259 ur = tcore_pending_ref_user_request(p);
1261 dbg("no user_request");
1265 respGetCbConfig.cbConfig.net3gppType = SMS_NETTYPE_3GPP;
1267 if (atResp->success) {
1269 if (atResp->lines) {
1270 line = (char*)atResp->lines->data;
1272 dbg("line is %s",line);
1273 tokens = tcore_at_tok_new(line);
1274 pResp = g_slist_nth_data(tokens, 0);
1277 respGetCbConfig.cbConfig.cbEnabled = mode;
1279 pResp = g_slist_nth_data(tokens, 1);
1281 GSList *cb_tokens = NULL;
1282 char *cb_mid_str = NULL;
1283 int num_cb_tokens = 0;
1284 char *mid_tok = NULL;
1285 char *first_tok = NULL, *second_tok = NULL;
1287 // 0,1,5,320-478,922
1288 cb_mid_str = util_removeQuotes(pResp);
1289 cb_tokens = tcore_at_tok_new((const char *) cb_mid_str);
1291 num_cb_tokens = g_slist_length(cb_tokens);
1292 dbg("num_cb_tokens = %d", num_cb_tokens);
1294 if (num_cb_tokens == 0) {
1295 if (mode == 1) { // Enable all CBs
1296 respGetCbConfig.cbConfig.msgIdRangeCount = 1;
1297 respGetCbConfig.cbConfig.msgIDs[0].net3gpp.fromMsgId = 0x0000;
1298 respGetCbConfig.cbConfig.msgIDs[0].net3gpp.toMsgId = SMS_GSM_SMS_CBMI_LIST_SIZE_MAX + 1;
1299 respGetCbConfig.cbConfig.msgIDs[0].net3gpp.selected = TRUE;
1300 respGetCbConfig.result = SMS_SENDSMS_SUCCESS;
1301 } else { // all CBs disabled
1302 respGetCbConfig.cbConfig.msgIdRangeCount = 0;
1303 respGetCbConfig.cbConfig.msgIDs[0].net3gpp.selected = FALSE;
1304 respGetCbConfig.result = SMS_SENDSMS_SUCCESS;
1308 for (i = 0; i < num_cb_tokens; i++) {
1309 respGetCbConfig.cbConfig.msgIDs[i].net3gpp.selected = TRUE;
1310 respGetCbConfig.cbConfig.msgIdRangeCount++;
1312 mid_tok = tcore_at_tok_nth(cb_tokens, i);
1313 first_tok = strtok(mid_tok, delim);
1314 second_tok = strtok(NULL, delim);
1316 if ((first_tok != NULL) && (second_tok != NULL)) { // mids in range (320-478)
1317 dbg("inside if mid_range");
1318 respGetCbConfig.cbConfig.msgIDs[i].net3gpp.fromMsgId = atoi(first_tok);
1319 respGetCbConfig.cbConfig.msgIDs[i].net3gpp.toMsgId = atoi(second_tok);
1320 } // single mid value (0,1,5, 922)
1322 respGetCbConfig.cbConfig.msgIDs[i].net3gpp.fromMsgId = atoi(mid_tok);
1323 respGetCbConfig.cbConfig.msgIDs[i].net3gpp.toMsgId = atoi(mid_tok);
1329 respGetCbConfig.cbConfig.msgIdRangeCount = 1;
1330 respGetCbConfig.cbConfig.msgIDs[0].net3gpp.fromMsgId = 0x0000;
1331 respGetCbConfig.cbConfig.msgIDs[0].net3gpp.toMsgId = SMS_GSM_SMS_CBMI_LIST_SIZE_MAX + 1;
1332 respGetCbConfig.cbConfig.msgIDs[0].net3gpp.selected = TRUE;
1333 respGetCbConfig.result = SMS_SENDSMS_SUCCESS;
1335 respGetCbConfig.cbConfig.msgIdRangeCount = 0;
1336 respGetCbConfig.cbConfig.msgIDs[0].net3gpp.selected = FALSE;
1337 respGetCbConfig.result = SMS_SENDSMS_SUCCESS;
1341 dbg("line is NULL");
1344 dbg("atresp->lines is NULL");
1347 dbg("RESPONSE NOK");
1350 tcore_user_request_send_response(ur, TRESP_SMS_GET_CB_CONFIG, sizeof(struct tresp_sms_get_cb_config), &respGetCbConfig);
1353 tcore_at_tok_free(tokens);
1358 static void on_response_set_cb_config(TcorePending *pending, int data_len, const void *data, void *user_data)
1361 Response is expected in this format
1368 const TcoreATResponse *resp = data;
1370 const char *line = NULL;
1371 GSList *tokens=NULL;
1373 struct tresp_sms_set_cb_config respSetCbConfig = {0,};
1375 memset(&respSetCbConfig, 0, sizeof(struct tresp_sms_set_cb_config));
1377 ur = tcore_pending_ref_user_request(pending);
1378 respSetCbConfig.result = SMS_SENDSMS_SUCCESS;
1380 if (resp->success > 0) {
1383 dbg("RESPONSE NOK");
1384 line = (const char*)resp->final_response;
1385 tokens = tcore_at_tok_new(line);
1387 if (g_slist_length(tokens) < 1) {
1388 dbg("err cause not specified or string corrupted");
1389 respSetCbConfig.result = SMS_DEVICE_FAILURE;
1391 response = atoi(g_slist_nth_data(tokens, 0));
1392 /* TODO: CMEE error mapping is required. */
1393 respSetCbConfig.result = SMS_DEVICE_FAILURE;
1397 dbg("no user_request");
1401 tcore_user_request_send_response(ur, TRESP_SMS_SET_CB_CONFIG, sizeof(struct tresp_sms_set_cb_config), &respSetCbConfig);
1404 tcore_at_tok_free(tokens);
1409 static void on_response_set_mem_status(TcorePending *p, int data_len, const void *data, void *user_data)
1412 struct tresp_sms_set_mem_status respSetMemStatus = {0,};
1413 const TcoreATResponse *resp = data;
1415 memset(&respSetMemStatus, 0, sizeof(struct tresp_sms_set_mem_status));
1417 if (resp->success > 0) {
1419 respSetMemStatus.result = SMS_SENDSMS_SUCCESS;
1421 dbg("RESPONSE NOK");
1422 respSetMemStatus.result = SMS_DEVICE_FAILURE;
1425 ur = tcore_pending_ref_user_request(p);
1427 dbg("no user_request");
1431 tcore_user_request_send_response(ur, TRESP_SMS_SET_MEM_STATUS, sizeof(struct tresp_sms_set_mem_status), &respSetMemStatus);
1436 static void on_response_set_msg_status(TcorePending *pending, int data_len, const void *data, void *user_data)
1439 struct tresp_sms_set_msg_status respMsgStatus = {0, };
1440 const TcoreATResponse *atResp = data;
1441 int response = 0, sw1 = 0, sw2 = 0;
1442 const char *line = NULL;
1444 GSList *tokens = NULL;
1448 memset(&respMsgStatus, 0, sizeof(struct tresp_sms_set_msg_status));
1449 respMsgStatus.result = SMS_DEVICE_FAILURE;
1451 ur = tcore_pending_ref_user_request(pending);
1453 if (atResp->success > 0) {
1456 if (atResp->lines) {
1457 line = (const char *) atResp->lines->data;
1458 tokens = tcore_at_tok_new(line);
1459 pResp = g_slist_nth_data(tokens, 0);
1460 if (pResp != NULL) {
1465 pResp = g_slist_nth_data(tokens, 1);
1466 if (pResp != NULL) {
1468 if ((sw1 == AT_SW1_SUCCESS) && (sw2 == 0)) {
1469 respMsgStatus.result = SMS_SENDSMS_SUCCESS;
1474 pResp = g_slist_nth_data(tokens, 3);
1476 if (pResp != NULL) {
1477 response = atoi(pResp);
1478 dbg("response is %s", response);
1484 dbg("RESPONSE NOK");
1487 tcore_user_request_send_response(ur, TRESP_SMS_SET_MSG_STATUS , sizeof(struct tresp_sms_set_msg_status), &respMsgStatus);
1490 tcore_at_tok_free(tokens);
1496 static void on_response_get_sms_params(TcorePending *pending, int data_len, const void *data, void *user_data)
1499 struct tresp_sms_get_params respGetParams ;
1500 const TcoreATResponse *atResp = data;
1501 int sw1 = 0, sw2 = 0;
1502 const char *line = NULL;
1504 GSList *tokens=NULL;
1505 char *hexData = NULL;
1506 char *recordData = NULL;
1509 memset(&respGetParams, 0, sizeof(struct tresp_sms_get_params));
1510 respGetParams.result = SMS_DEVICE_FAILURE;
1512 ur = tcore_pending_ref_user_request(pending);
1514 if (atResp->success > 0) {
1517 if (atResp->lines) {
1518 line = (const char *) atResp->lines->data;
1519 tokens = tcore_at_tok_new(line);
1520 pResp = g_slist_nth_data(tokens, 0);
1521 if (pResp != NULL) {
1523 dbg("sw1 is %d", sw1);
1527 pResp = g_slist_nth_data(tokens, 1);
1528 if (pResp != NULL) {
1530 dbg("sw2 is %d", sw2);
1531 if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
1532 respGetParams.result = SMS_SENDSMS_SUCCESS;
1537 pResp = g_slist_nth_data(tokens, 2);
1538 if (pResp != NULL) {
1539 hexData = util_removeQuotes(pResp);
1541 recordData = util_hexStringToBytes(hexData);
1542 util_hex_dump(" ", strlen(hexData) / 2, recordData);
1544 respGetParams.paramsInfo.recordLen = strlen(hexData) / 2;
1546 util_sms_decode_smsParameters((unsigned char *) recordData, strlen(hexData) / 2, &(respGetParams.paramsInfo));
1547 respGetParams.result = SMS_SENDSMS_SUCCESS;
1549 for (i = 0; i < (int) respGetParams.paramsInfo.tpSvcCntrAddr.dialNumLen; i++)
1550 dbg("SCAddr = %d [%02x]", i, respGetParams.paramsInfo.tpSvcCntrAddr.diallingNum[i]);
1557 tcore_at_tok_free(tokens);
1560 dbg("RESPONSE NOK");
1563 tcore_user_request_send_response(ur, TRESP_SMS_GET_PARAMS, sizeof(struct tresp_sms_get_params), &respGetParams);
1569 static void on_response_set_sms_params(TcorePending *pending, int data_len, const void *data, void *user_data)
1572 struct tresp_sms_set_params respSetParams = {0, };
1573 const TcoreATResponse *atResp = data;
1574 int sw1 =0 , sw2 = 0;
1575 const char *line = NULL;
1577 GSList *tokens=NULL;
1580 memset(&respSetParams, 0, sizeof(struct tresp_sms_set_params));
1581 ur = tcore_pending_ref_user_request(pending);
1583 respSetParams.result = SMS_DEVICE_FAILURE;
1585 if (atResp->success > 0) {
1588 if (atResp->lines) {
1589 line = (const char *) atResp->lines->data;
1590 tokens = tcore_at_tok_new(line);
1591 pResp = g_slist_nth_data(tokens, 0);
1592 if (pResp != NULL) {
1598 pResp = g_slist_nth_data(tokens, 1);
1599 if (pResp != NULL) {
1601 if (((sw1 == AT_SW1_SUCCESS) && (sw2 == AT_SW2_SUCCESS)) || (sw1 == 0x91)) {
1602 respSetParams.result = SMS_SENDSMS_SUCCESS;
1611 dbg("RESPONSE NOK");
1614 tcore_user_request_send_response(ur, TRESP_SMS_SET_PARAMS , sizeof(struct tresp_sms_set_params), &respSetParams);
1617 tcore_at_tok_free(tokens);
1623 static void on_response_get_paramcnt(TcorePending *p, int data_len, const void *data, void *user_data)
1625 UserRequest *ur = NULL;
1626 struct tresp_sms_get_paramcnt respGetParamCnt = {0, };
1627 const TcoreATResponse *atResp = data;
1628 char *line = NULL , *pResp = NULL;
1629 int sw1 = 0 , sw2 = 0, *smsp_record_len = NULL;
1631 GSList *tokens=NULL;
1632 CoreObject *co_sim = NULL; //need this to get the sim type GSM/USIM
1633 TcorePlugin *plugin = NULL;
1637 ur = tcore_pending_ref_user_request(p);
1638 respGetParamCnt.result = SMS_DEVICE_FAILURE;
1640 if (atResp->success > 0) {
1643 if (atResp->lines) {
1644 line = (char *) atResp->lines->data;
1646 dbg("line is %s", line);
1648 tokens = tcore_at_tok_new(line);
1649 pResp = g_slist_nth_data(tokens, 0);
1650 if (pResp != NULL) {
1655 pResp = g_slist_nth_data(tokens, 1);
1656 if (pResp != NULL) {
1658 if ((sw1 == 144) && (sw2 == 0)) {
1659 respGetParamCnt.result = SMS_SENDSMS_SUCCESS;
1664 pResp = g_slist_nth_data(tokens, 2);
1665 if (pResp != NULL) {
1666 char *hexData = NULL;
1667 char *recordData = NULL;
1668 hexData = util_removeQuotes(pResp);
1670 /*1. SIM access success case*/
1671 if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
1672 unsigned char tag_len = 0; /* 1 or 2 bytes ??? */
1674 char num_of_records = 0;
1675 unsigned char file_id_len = 0;
1676 unsigned short file_id = 0;
1677 unsigned short file_size = 0;
1678 unsigned short file_type = 0;
1679 unsigned short arr_file_id = 0;
1680 int arr_file_id_rec_num = 0;
1682 /* handling only last 3 bits */
1683 unsigned char file_type_tag = 0x07;
1684 unsigned char *ptr_data;
1686 recordData = util_hexStringToBytes(hexData);
1687 util_hex_dump(" ", strlen(hexData)/2, recordData);
1689 ptr_data = (unsigned char *)recordData;
1691 co_sim = tcore_plugin_ref_core_object(tcore_pending_ref_plugin(p), CORE_OBJECT_TYPE_SIM);
1692 sim_type = tcore_sim_get_type(co_sim);
1693 dbg("sim type is %d",sim_type);
1695 if (sim_type == SIM_TYPE_USIM) {
1697 ETSI TS 102 221 v7.9.0
1699 '62' FCP template tag
1700 - Response for an EF
1701 '82' M File Descriptor
1702 '83' M File Identifier
1703 'A5' O Proprietary information
1704 '8A' M Life Cycle Status Integer
1705 '8B', '8C' or 'AB' C1 Security attributes
1707 '81' O Total file size
1708 '88' O Short File Identifier (SFI)
1711 /* rsim.res_len has complete data length received */
1713 /* FCP template tag - File Control Parameters tag*/
1714 if (*ptr_data == 0x62) {
1715 /* parse complete FCP tag*/
1716 /* increment to next byte */
1718 tag_len = *ptr_data++;
1719 /* FCP file descriptor - file type, accessibility, DF, ADF etc*/
1720 if (*ptr_data == 0x82) {
1721 /* increment to next byte */
1725 /* unsigned char file_desc_len = *ptr_data++;*/
1726 /* dbg("file descriptor length: [%d]", file_desc_len);*/
1727 /* TBD: currently capture only file type : ignore sharable, non sharable, working, internal etc*/
1728 /* consider only last 3 bits*/
1729 file_type_tag = file_type_tag & (*ptr_data);
1731 switch (file_type_tag) {
1732 /* increment to next byte */
1736 dbg("Getting FileType: [Transparent file type]");
1737 /* increment to next byte */
1739 file_type = 0x01; //SIM_FTYPE_TRANSPARENT
1740 /* data coding byte - value 21 */
1745 dbg("Getting FileType: [Linear fixed file type]");
1746 /* increment to next byte */
1748 /* data coding byte - value 21 */
1751 memcpy(&record_len, ptr_data, 2);
1753 record_len = SMS_SWAPBYTES16(record_len);
1754 ptr_data = ptr_data + 2;
1755 num_of_records = *ptr_data++;
1756 /* Data lossy conversation from enum (int) to unsigned char */
1757 file_type = 0x02; // SIM_FTYPE_LINEAR_FIXED
1761 dbg(" Cyclic fixed file type");
1762 /* increment to next byte */
1764 /* data coding byte - value 21 */
1767 memcpy(&record_len, ptr_data, 2);
1769 record_len = SMS_SWAPBYTES16(record_len);
1770 ptr_data = ptr_data + 2;
1771 num_of_records = *ptr_data++;
1772 file_type = 0x04; //SIM_FTYPE_CYCLIC
1776 dbg("not handled file type [0x%x]", *ptr_data);
1780 dbg("INVALID FCP received - DEbug!");
1783 tcore_at_tok_free(tokens);
1787 /*File identifier - file id?? */ // 0x84,0x85,0x86 etc are currently ignored and not handled
1788 if (*ptr_data == 0x83) {
1789 /* increment to next byte */
1791 file_id_len = *ptr_data++;
1792 memcpy(&file_id, ptr_data, file_id_len);
1794 file_id = SMS_SWAPBYTES16(file_id);
1795 ptr_data = ptr_data + 2;
1796 dbg("Getting FileID=[0x%x]", file_id);
1798 dbg("INVALID FCP received - DEbug!");
1801 tcore_at_tok_free(tokens);
1805 /* proprietary information */
1806 if (*ptr_data == 0xA5) {
1807 unsigned short prop_len;
1808 /* increment to next byte */
1811 prop_len = *ptr_data;
1813 ptr_data = ptr_data + prop_len + 1;
1815 dbg("INVALID FCP received - DEbug!");
1818 /* life cycle status integer [8A][length:0x01][status]*/
1821 00000000 : No information given
1822 00000001 : creation state
1823 00000011 : initialization state
1824 000001-1 : operation state -activated
1825 000001-0 : operation state -deactivated
1826 000011-- : Termination state
1827 b8~b5 !=0, b4~b1=X : Proprietary
1828 Any other value : RFU
1830 if (*ptr_data == 0x8A) {
1831 /* increment to next byte */
1833 /* length - value 1 */
1836 switch (*ptr_data) {
1839 dbg("<IPC_RX> operation state -deactivated");
1845 dbg("<IPC_RX> operation state -activated");
1850 dbg("<IPC_RX> DEBUG! LIFE CYCLE STATUS =[0x%x]",*ptr_data);
1856 /* related to security attributes : currently not handled*/
1857 if (*ptr_data == 0x86 || *ptr_data == 0x8B || *ptr_data == 0x8C || *ptr_data == 0xAB) {
1858 /* increment to next byte */
1860 /* if tag length is 3 */
1861 if (*ptr_data == 0x03) {
1862 /* increment to next byte */
1865 memcpy(&arr_file_id, ptr_data, 2);
1867 arr_file_id = SMS_SWAPBYTES16(arr_file_id);
1868 ptr_data = ptr_data + 2;
1869 arr_file_id_rec_num = *ptr_data++;
1871 /* if tag length is not 3 */
1872 /* ignoring bytes */
1873 // ptr_data = ptr_data + 4;
1874 dbg("Useless security attributes, so jump to next tag");
1875 ptr_data = ptr_data + (*ptr_data + 1);
1878 dbg("INVALID FCP received[0x%x] - DEbug!", *ptr_data);
1881 tcore_at_tok_free(tokens);
1885 dbg("Current ptr_data value is [%x]", *ptr_data);
1887 /* file size excluding structural info*/
1888 if (*ptr_data == 0x80) {
1889 /* for EF file size is body of file and for Linear or cyclic it is
1890 * number of recXsizeof(one record)
1892 /* increment to next byte */
1894 /* length is 1 byte - value is 2 bytes or more */
1896 memcpy(&file_size, ptr_data, 2);
1898 file_size = SMS_SWAPBYTES16(file_size);
1899 ptr_data = ptr_data + 2;
1901 dbg("INVALID FCP received - DEbug!");
1904 tcore_at_tok_free(tokens);
1908 /* total file size including structural info*/
1909 if (*ptr_data == 0x81) {
1911 /* increment to next byte */
1916 ptr_data = ptr_data + 3;
1918 dbg("INVALID FCP received - DEbug!");
1919 /* 0x81 is optional tag?? check out! so do not return -1 from here! */
1922 /*short file identifier ignored*/
1923 if (*ptr_data == 0x88) {
1924 dbg("0x88: Do Nothing");
1928 dbg("INVALID FCP received - DEbug!");
1931 tcore_at_tok_free(tokens);
1934 } else if (sim_type == SIM_TYPE_GSM) {
1935 unsigned char gsm_specific_file_data_len = 0;
1936 /* ignore RFU byte1 and byte2 */
1940 //file_size = p_info->response_len;
1941 memcpy(&file_size, ptr_data, 2);
1943 file_size = SMS_SWAPBYTES16(file_size);
1944 /* parsed file size */
1945 ptr_data = ptr_data + 2;
1947 memcpy(&file_id, ptr_data, 2);
1948 file_id = SMS_SWAPBYTES16(file_id);
1949 dbg(" FILE id --> [%x]", file_id);
1950 ptr_data = ptr_data + 2;
1951 /* save file type - transparent, linear fixed or cyclic */
1952 file_type_tag = (*(ptr_data + 7));
1954 switch (*ptr_data) {
1957 dbg(" RFU file type- not handled - Debug!");
1962 dbg(" MF file type - not handled - Debug!");
1967 dbg(" DF file type - not handled - Debug!");
1972 dbg(" EF file type [%d] ", file_type_tag);
1973 /* increment to next byte */
1976 if (file_type_tag == 0x00 || file_type_tag == 0x01) {
1977 /* increament to next byte as this byte is RFU */
1980 (file_type_tag == 0x00) ? 0x01 : 0x02; // SIM_FTYPE_TRANSPARENT:SIM_FTYPE_LINEAR_FIXED;
1982 /* increment to next byte */
1984 /* For a cyclic EF all bits except bit 7 are RFU; b7=1 indicates that */
1985 /* the INCREASE command is allowed on the selected cyclic file. */
1986 file_type = 0x04; // SIM_FTYPE_CYCLIC;
1988 /* bytes 9 to 11 give SIM file access conditions */
1990 /* byte 10 has one nibble that is RF U and another for INCREASE which is not used currently */
1992 /* byte 11 is invalidate and rehabilate nibbles */
1994 /* byte 12 - file status */
1996 /* byte 13 - GSM specific data */
1997 gsm_specific_file_data_len = *ptr_data;
1999 /* byte 14 - structure of EF - transparent or linear or cyclic , already saved above */
2001 /* byte 15 - length of record for linear and cyclic , for transparent it is set to 0x00. */
2002 record_len = *ptr_data;
2003 dbg("record length[%d], file size[%d]", record_len, file_size);
2005 if (record_len != 0)
2006 num_of_records = (file_size / record_len);
2008 dbg("Number of records [%d]", num_of_records);
2012 dbg(" not handled file type");
2016 dbg(" Card Type - UNKNOWN [%d]", sim_type);
2019 dbg("EF[0x%x] size[%ld] Type[0x%x] NumOfRecords[%ld] RecordLen[%ld]", file_id, file_size, file_type, num_of_records, record_len);
2021 respGetParamCnt.recordCount = num_of_records;
2022 respGetParamCnt.result = SMS_SUCCESS;
2024 //TO Store smsp record length in the property
2025 plugin = tcore_pending_ref_plugin(p);
2026 smsp_record_len = tcore_plugin_ref_property(plugin, "SMSPRECORDLEN");
2027 memcpy(smsp_record_len, &record_len, sizeof(int));
2032 /*2. SIM access fail case*/
2033 dbg("SIM access fail");
2034 respGetParamCnt.result = SMS_UNKNOWN;
2037 dbg("presp is NULL");
2040 dbg("line is blank");
2043 dbg("RESPONSE NOK");
2046 tcore_user_request_send_response(ur, TRESP_SMS_GET_PARAMCNT, sizeof(struct tresp_sms_get_paramcnt), &respGetParamCnt);
2049 tcore_at_tok_free(tokens);
2055 static void _response_get_efsms_data(TcorePending *p, int data_len, const void *data, void *user_data)
2057 UserRequest *ur = NULL;
2058 UserRequest *dup_ur = NULL;
2059 struct tresp_sms_set_msg_status resp_msg_status = {0,};
2060 const struct treq_sms_set_msg_status *req_msg_status = NULL ;
2062 const TcoreATResponse *resp = data;
2063 char *encoded_data = NULL;
2064 char msg_status = 0;
2066 GSList *tokens=NULL;
2067 const char *line = NULL;
2071 TcoreHal *hal = NULL;
2072 TcoreATRequest *atreq = NULL;
2073 TcorePending *pending = NULL;
2074 gchar *cmd_str = NULL;
2076 ur = tcore_pending_ref_user_request(p);
2078 req_msg_status = tcore_user_request_ref_data(ur, NULL);
2080 resp_msg_status.result = SMS_DEVICE_FAILURE;
2082 hal = tcore_object_get_hal(tcore_pending_ref_core_object(pending));
2083 dbg("msgStatus: [%x], index [%x]", req_msg_status->msgStatus, req_msg_status->index);
2085 if (resp->success <= 0) {
2092 line = (const char *) resp->lines->data;
2093 tokens = tcore_at_tok_new(line);
2094 if (g_slist_length(tokens) != 3) {
2095 msg("invalid message");
2099 sw1 = atoi(g_slist_nth_data(tokens, 0));
2100 sw2 = atoi(g_slist_nth_data(tokens, 1));
2101 pResp = g_slist_nth_data(tokens, 2);
2103 if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
2104 switch (req_msg_status->msgStatus) {
2105 case SMS_STATUS_READ:
2109 case SMS_STATUS_UNREAD:
2113 case SMS_STATUS_UNSENT:
2117 case SMS_STATUS_SENT:
2121 case SMS_STATUS_DELIVERED:
2125 case SMS_STATUS_DELIVERY_UNCONFIRMED:
2129 case SMS_STATUS_MESSAGE_REPLACED:
2130 case SMS_STATUS_RESERVED:
2136 encoded_data = util_removeQuotes(pResp);
2138 //overwrite Status byte information
2139 util_byte_to_hex((const char *)&msg_status, (char *)encoded_data, 1);
2141 //Update EF-SMS with just status byte overwritten, rest 175 bytes are same as received in read information
2142 cmd_str = g_strdup_printf("AT+CRSM=220,28476,%d, 4, %d, \"%s\"", (req_msg_status->index+1), PDU_LEN_MAX, encoded_data);
2143 atreq = tcore_at_request_new((const char *)cmd_str, "+CRSM", TCORE_AT_SINGLELINE);
2144 pending = tcore_pending_new(tcore_pending_ref_core_object(pending), 0);
2145 if (NULL == cmd_str || NULL == atreq || NULL == pending) {
2146 err("Out of memory. Unable to proceed");
2147 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
2149 //free memory we own
2152 util_sms_free_memory(atreq);
2153 util_sms_free_memory(pending);
2158 util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
2160 dup_ur = tcore_user_request_ref(ur);
2162 tcore_pending_set_request_data(pending, 0, atreq);
2163 tcore_pending_set_response_callback(pending, on_response_set_msg_status, NULL);
2164 tcore_pending_link_user_request(pending, dup_ur);
2165 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
2166 tcore_hal_send_request(hal, pending);
2175 tcore_at_tok_free(tokens);
2177 tcore_user_request_send_response(ur, TRESP_SMS_SET_MSG_STATUS , sizeof(struct tresp_sms_set_msg_status), &msg_status);
2184 /*=============================================================
2186 ==============================================================*/
2187 static TReturn send_umts_msg(CoreObject *co_sms, UserRequest *ur)
2189 const struct treq_sms_send_umts_msg *send_msg;
2190 const unsigned char *tpdu_byte_data, *sca_byte_data;
2191 int tpdu_byte_len, pdu_byte_len;
2192 char buf[HEX_PDU_LEN_MAX];
2193 char pdu[PDU_LEN_MAX];
2195 int pdu_hex_len, mms;
2200 send_msg = tcore_user_request_ref_data(ur, NULL);
2202 tpdu_byte_data = send_msg->msgDataPackage.tpduData;
2203 sca_byte_data = send_msg->msgDataPackage.sca;
2206 /* TPDU length is in byte */
2207 tpdu_byte_len = send_msg->msgDataPackage.msgLength;
2209 /* Use same Radio Resource Channel */
2210 mms = send_msg->more;
2212 dbg("TDPU length: [%d]", tpdu_byte_len);
2213 dbg("SCA semi-octet length: [%d]", sca_byte_data[0]);
2215 /* Prepare PDU for hex encoding */
2216 pdu_byte_len = tcore_util_pdu_encode(sca_byte_data, tpdu_byte_data,
2217 tpdu_byte_len, pdu);
2219 pdu_hex_len = (int) tcore_util_encode_hex((unsigned char *) pdu,
2222 dbg("PDU hexadecimal length: [%d]", pdu_hex_len);
2225 cmd_str = g_strdup_printf("AT+CMMS=%d", mms);
2227 ret = tcore_prepare_and_send_at_request(co_sms, cmd_str, NULL,
2228 TCORE_AT_NO_RESULT, NULL, NULL, NULL,
2229 on_confirmation_sms_message_send,
2231 if (ret != TCORE_RETURN_SUCCESS) {
2232 err("Failed to prepare and send AT request");
2239 cmd_str = g_strdup_printf("AT+CMGS=%d\r%s\x1A", tpdu_byte_len, buf);
2241 ret = tcore_prepare_and_send_at_request(co_sms, cmd_str, "+CMGS:",
2242 TCORE_AT_SINGLELINE, ur,
2243 on_response_send_umts_msg, NULL,
2244 on_confirmation_sms_message_send, NULL);
2245 if (ret != TCORE_RETURN_SUCCESS)
2246 err("Failed to prepare and send AT request");
2256 static TReturn read_msg(CoreObject *obj, UserRequest *ur)
2258 gchar *cmd_str = NULL;
2259 TcoreHal *hal = NULL;
2260 TcoreATRequest *atreq = NULL;
2261 TcorePending *pending = NULL;
2262 const struct treq_sms_read_msg *readMsg = NULL;
2266 readMsg = tcore_user_request_ref_data(ur, NULL);
2267 hal = tcore_object_get_hal(obj);
2268 if (NULL == readMsg || NULL == hal) {
2269 err("NULL input. Unable to proceed");
2270 dbg("readMsg: [%p], hal: [%p]", readMsg, hal);
2273 return TCORE_RETURN_EINVAL;
2276 if(FALSE == tcore_hal_get_power_state(hal)){
2277 dbg("cp not ready/n");
2278 return TCORE_RETURN_ENOSYS;
2280 dbg("index: [%d]", readMsg->index);
2282 cmd_str = g_strdup_printf("AT+CMGR=%d", (readMsg->index + 1)); //IMC index is one ahead of TAPI
2283 atreq = tcore_at_request_new((const char *)cmd_str, "+CMGR", TCORE_AT_PDU);
2284 pending = tcore_pending_new(obj, 0);
2286 if (NULL == cmd_str || NULL == atreq || NULL == pending) {
2287 err("Out of memory. Unable to proceed");
2288 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
2290 //free memory we own
2292 util_sms_free_memory(atreq);
2293 util_sms_free_memory(pending);
2296 return TCORE_RETURN_ENOMEM;
2299 util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
2301 tcore_pending_set_request_data(pending, 0, atreq);
2302 tcore_pending_set_response_callback(pending, on_response_read_msg, (void *)(uintptr_t)(readMsg->index)); //storing index as user data for response
2303 tcore_pending_link_user_request(pending, ur);
2304 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
2305 tcore_hal_send_request(hal, pending);
2310 return TCORE_RETURN_SUCCESS;
2313 static TReturn save_msg(CoreObject *obj, UserRequest *ur)
2315 gchar *cmd_str = NULL;
2316 TcoreHal *hal = NULL;
2317 TcoreATRequest *atreq = NULL;
2318 TcorePending *pending = NULL;
2319 const struct treq_sms_save_msg *saveMsg = NULL;
2320 int ScLength = 0, pdu_len = 0, stat = 0;
2321 char buf[2*(SMS_SMSP_ADDRESS_LEN+SMS_SMDATA_SIZE_MAX)+1] = {0};
2322 char *hex_pdu = NULL;
2326 saveMsg = tcore_user_request_ref_data(ur, NULL);
2327 hal = tcore_object_get_hal(obj);
2328 if (NULL == saveMsg || NULL == hal) {
2329 err("NULL input. Unable to proceed");
2330 dbg("saveMsg: [%p], hal: [%p]", saveMsg, hal);
2333 return TCORE_RETURN_EINVAL;
2335 if(FALSE == tcore_hal_get_power_state(hal)){
2336 dbg("cp not ready/n");
2337 return TCORE_RETURN_ENOSYS;
2340 dbg("msgStatus: %x, msgLength: [%d]", saveMsg->msgStatus, saveMsg->msgDataPackage.msgLength);
2341 util_hex_dump(" ", (SMS_SMDATA_SIZE_MAX+1), (void *)saveMsg->msgDataPackage.tpduData);
2342 util_hex_dump(" ", SMS_SMSP_ADDRESS_LEN, (void *)saveMsg->msgDataPackage.sca);
2344 switch (saveMsg->msgStatus) {
2345 case SMS_STATUS_READ:
2349 case SMS_STATUS_UNREAD:
2350 stat = AT_REC_UNREAD;
2353 case SMS_STATUS_SENT:
2357 case SMS_STATUS_UNSENT:
2358 stat = AT_STO_UNSENT;
2362 err("Invalid msgStatus");
2364 return TCORE_RETURN_EINVAL;
2367 if ((saveMsg->msgDataPackage.msgLength > 0)
2368 && (saveMsg->msgDataPackage.msgLength <= SMS_SMDATA_SIZE_MAX)) {
2369 ScLength = (int)saveMsg->msgDataPackage.sca[0];
2372 dbg("ScLength = %d", ScLength);
2377 memcpy(&buf[1], saveMsg->msgDataPackage.sca, ScLength);
2380 memcpy(&buf[ScLength+1], saveMsg->msgDataPackage.tpduData, saveMsg->msgDataPackage.msgLength);
2382 pdu_len= saveMsg->msgDataPackage.msgLength + ScLength + 1;
2383 dbg("pdu_len: [%d]", pdu_len);
2385 hex_pdu = malloc(pdu_len * 2 + 1);
2386 util_hex_dump(" ", sizeof(buf), (void *)buf);
2388 memset (hex_pdu, 0x00, pdu_len * 2 + 1);
2390 util_byte_to_hex((const char *)buf, (char *)hex_pdu, pdu_len);
2392 //AT+CMGW=<length>[,<stat>]<CR>PDU is given<ctrl-Z/ESC>
2393 cmd_str = g_strdup_printf("AT+CMGW=%d,%d%s%s\x1A", saveMsg->msgDataPackage.msgLength, stat, "\r", hex_pdu);
2394 pending = tcore_pending_new(obj, 0);
2395 atreq = tcore_at_request_new((const char *)cmd_str, "+CMGW", TCORE_AT_SINGLELINE);
2397 if(NULL == cmd_str || NULL == atreq || NULL == pending) {
2398 err("Out of memory. Unable to proceed");
2399 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
2401 //free memory we own
2403 util_sms_free_memory(atreq);
2404 util_sms_free_memory(pending);
2405 util_sms_free_memory(hex_pdu);
2408 return TCORE_RETURN_ENOMEM;
2411 util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
2413 tcore_pending_set_request_data(pending, 0, atreq);
2414 tcore_pending_set_response_callback(pending, on_response_sms_save_msg, NULL);
2415 tcore_pending_link_user_request(pending, ur);
2416 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
2417 tcore_hal_send_request(hal, pending);
2423 return TCORE_RETURN_SUCCESS;
2426 err("Invalid Data len");
2428 return TCORE_RETURN_SMS_INVALID_DATA_LEN;
2431 static TReturn delete_msg(CoreObject *obj, UserRequest *ur)
2433 gchar *cmd_str = NULL;
2434 TcoreHal *hal = NULL;
2435 TcoreATRequest *atreq = NULL;
2436 TcorePending *pending = NULL;
2437 const struct treq_sms_delete_msg *delete_msg = NULL;
2441 delete_msg = tcore_user_request_ref_data(ur, NULL);
2442 hal = tcore_object_get_hal(obj);
2443 if (NULL == delete_msg || NULL == hal) {
2444 err("NULL input. Unable to proceed");
2445 dbg("deleteMsg: [%p], hal: [%p]", delete_msg, hal);
2448 return TCORE_RETURN_EINVAL;
2451 if(FALSE == tcore_hal_get_power_state(hal)){
2452 dbg("cp not ready/n");
2453 return TCORE_RETURN_ENOSYS;
2456 dbg("index: %d", delete_msg->index);
2458 if (delete_msg->index == -1) {
2459 cmd_str = g_strdup_printf("AT+CMGD=0,4"); // Delete All Messages
2461 cmd_str = g_strdup_printf("AT+CMGD=%d,0", delete_msg->index + 1); // Delete specified index
2464 pending = tcore_pending_new(obj, 0);
2465 atreq = tcore_at_request_new((const char *)cmd_str, NULL, TCORE_AT_NO_RESULT);
2466 if (NULL == cmd_str || NULL == atreq || NULL == pending) {
2467 err("Out of memory. Unable to proceed");
2468 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
2470 //free memory we own
2472 util_sms_free_memory(atreq);
2473 util_sms_free_memory(pending);
2476 return TCORE_RETURN_ENOMEM;
2479 util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
2481 tcore_pending_set_request_data(pending, 0, atreq);
2482 tcore_pending_set_response_callback(pending, on_response_sms_delete_msg, (void *) (uintptr_t) (delete_msg->index)); // storing index as user data for response
2483 tcore_pending_link_user_request(pending, ur);
2484 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
2485 tcore_hal_send_request(hal, pending);
2490 return TCORE_RETURN_SUCCESS;
2493 static TReturn get_stored_msg_cnt(CoreObject *obj, UserRequest *ur)
2495 gchar *cmd_str = NULL;
2496 TcoreHal *hal = NULL;
2497 TcoreATRequest *atreq = NULL;
2498 TcorePending *pending = NULL;
2502 hal = tcore_object_get_hal(obj);
2504 err("NULL HAL. Unable to proceed");
2507 return TCORE_RETURN_EINVAL;
2510 if(FALSE == tcore_hal_get_power_state(hal)){
2511 dbg("cp not ready/n");
2512 return TCORE_RETURN_ENOSYS;
2515 cmd_str = g_strdup_printf("AT+CPMS=\"SM\"");
2516 pending = tcore_pending_new(obj, 0);
2517 atreq = tcore_at_request_new((const char *)cmd_str, "+CPMS", TCORE_AT_SINGLELINE);
2519 if (NULL == cmd_str || NULL == atreq || NULL == pending) {
2520 err("Out of memory. Unable to proceed");
2521 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
2523 //free memory we own
2525 util_sms_free_memory(atreq);
2526 util_sms_free_memory(pending);
2529 return TCORE_RETURN_ENOMEM;
2532 util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
2534 tcore_pending_set_request_data(pending, 0, atreq);
2535 tcore_pending_set_response_callback(pending, on_response_get_stored_msg_cnt, NULL);
2536 tcore_pending_link_user_request(pending, ur);
2537 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
2538 tcore_hal_send_request(hal, pending);
2543 return TCORE_RETURN_SUCCESS;
2546 static TReturn get_sca(CoreObject *obj, UserRequest *ur)
2548 gchar * cmd_str = NULL;
2549 TcoreHal *hal = NULL;
2550 TcoreATRequest *atreq = NULL;
2551 TcorePending *pending = NULL;
2555 hal = tcore_object_get_hal(obj);
2557 err("HAL NULL. Unable to proceed");
2560 return TCORE_RETURN_EINVAL;
2562 if(FALSE == tcore_hal_get_power_state(hal)){
2563 dbg("cp not ready/n");
2564 return TCORE_RETURN_ENOSYS;
2567 cmd_str = g_strdup_printf("AT+CSCA?");
2568 pending = tcore_pending_new(obj, 0);
2569 atreq = tcore_at_request_new((const char *)cmd_str, "+CSCA", TCORE_AT_SINGLELINE);
2571 if (NULL == cmd_str || NULL == atreq || NULL == pending) {
2572 err("Out of memory. Unable to proceed");
2573 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
2575 //free memory we own
2577 util_sms_free_memory(atreq);
2578 util_sms_free_memory(pending);
2581 return TCORE_RETURN_ENOMEM;
2584 util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
2586 tcore_pending_set_request_data(pending, 0, atreq);
2587 tcore_pending_set_response_callback(pending, on_response_get_sca, NULL);
2588 tcore_pending_link_user_request(pending, ur);
2589 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
2590 tcore_hal_send_request(hal, pending);
2595 return TCORE_RETURN_SUCCESS;
2598 static TReturn set_sca(CoreObject *obj, UserRequest *ur)
2600 gchar *cmd_str = NULL;
2601 TcoreHal *hal = NULL;
2602 TcoreATRequest *atreq = NULL;
2603 TcorePending *pending = NULL;
2604 const struct treq_sms_set_sca *setSca = NULL;
2609 setSca = tcore_user_request_ref_data(ur, NULL);
2610 hal = tcore_object_get_hal(obj);
2611 if (NULL == setSca || NULL == hal) {
2612 err("NULL input. Unable to proceed");
2613 dbg("setSca: [%p], hal: [%p]", setSca, hal);
2616 return TCORE_RETURN_EINVAL;
2618 if(FALSE == tcore_hal_get_power_state(hal)){
2619 dbg("cp not ready/n");
2620 return TCORE_RETURN_ENOSYS;
2623 dbg("dialNumLen: %u, typeOfNum: %d, numPlanId: %d, ", setSca->scaInfo.dialNumLen, setSca->scaInfo.typeOfNum, setSca->scaInfo.numPlanId);
2625 util_hex_dump(" ", (SMS_SMSP_ADDRESS_LEN+1), (void *)setSca->scaInfo.diallingNum);
2627 addrType = ((setSca->scaInfo.typeOfNum << 4) | setSca->scaInfo.numPlanId) | 0x80;
2629 cmd_str = g_strdup_printf("AT+CSCA=\"%s\",%d", setSca->scaInfo.diallingNum, addrType);
2630 pending = tcore_pending_new(obj, 0);
2631 atreq = tcore_at_request_new((const char *)cmd_str, NULL, TCORE_AT_NO_RESULT);
2633 if (NULL == cmd_str || NULL == atreq || NULL == pending) {
2634 err("Out of memory. Unable to proceed");
2635 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
2637 //free memory we own
2639 util_sms_free_memory(atreq);
2640 util_sms_free_memory(pending);
2643 return TCORE_RETURN_ENOMEM;
2646 util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
2648 tcore_pending_set_request_data(pending, 0, atreq);
2649 tcore_pending_set_response_callback(pending, on_response_set_sca, NULL);
2650 tcore_pending_link_user_request(pending, ur);
2651 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
2652 tcore_hal_send_request(hal, pending);
2657 return TCORE_RETURN_SUCCESS;
2660 static TReturn get_cb_config(CoreObject *obj, UserRequest *ur)
2662 gchar *cmd_str = NULL;
2663 TcoreHal *hal = NULL;
2664 TcoreATRequest *atreq = NULL;
2665 TcorePending *pending = NULL;
2669 hal = tcore_object_get_hal(obj);
2671 err("NULL HAL. Unable to proceed");
2674 return TCORE_RETURN_EINVAL;
2676 if(FALSE == tcore_hal_get_power_state(hal)){
2677 dbg("cp not ready/n");
2678 return TCORE_RETURN_ENOSYS;
2681 cmd_str = g_strdup_printf("AT+CSCB?");
2682 pending = tcore_pending_new(obj, 0);
2683 atreq = tcore_at_request_new((const char *)cmd_str, "+CSCB", TCORE_AT_SINGLELINE);
2684 if (NULL == cmd_str || NULL == atreq || NULL == pending) {
2685 err("Out of memory. Unable to proceed");
2686 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
2688 //free memory we own
2690 util_sms_free_memory(atreq);
2691 util_sms_free_memory(pending);
2694 return TCORE_RETURN_ENOMEM;
2697 util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
2699 tcore_pending_set_request_data(pending, 0, atreq);
2700 tcore_pending_set_response_callback(pending, on_response_get_cb_config, NULL);
2701 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
2702 tcore_pending_link_user_request(pending, ur);
2703 tcore_hal_send_request(hal, pending);
2708 return TCORE_RETURN_SUCCESS;
2711 static TReturn set_cb_config(CoreObject *obj, UserRequest *ur)
2713 gchar *cmd_str = NULL;
2714 gchar *mids_str = NULL;
2715 GString *mids_GString = NULL;
2717 TcoreHal *hal = NULL;
2718 TcoreATRequest *atreq = NULL;
2719 TcorePending *pending = NULL;
2720 const struct treq_sms_set_cb_config *setCbConfig = NULL;
2721 int ctr1= 0, ctr2 =0;
2722 unsigned short appendMsgId = 0;
2726 setCbConfig = tcore_user_request_ref_data(ur, NULL);
2727 hal = tcore_object_get_hal(obj);
2728 if (NULL == setCbConfig || NULL == hal) {
2729 err("NULL input. Unable to proceed");
2730 dbg("setCbConfig: [%p], hal: [%p]", setCbConfig, hal);
2733 return TCORE_RETURN_EINVAL;
2735 if(FALSE == tcore_hal_get_power_state(hal)){
2736 dbg("cp not ready/n");
2737 return TCORE_RETURN_ENOSYS;
2740 dbg("bCBEnabled: %d, msgIdCount: %d", setCbConfig->cbEnabled, setCbConfig->msgIdRangeCount);
2742 if (setCbConfig->cbEnabled == 2) { //Enable all CBS
2743 cmd_str = g_strdup_printf("AT+CSCB=1");
2744 } else if ((setCbConfig->cbEnabled == 1) && (setCbConfig->msgIdRangeCount == 0)) { // Special case: Enable all CBS
2745 cmd_str = g_strdup_printf("AT+CSCB=1");
2746 } else if (setCbConfig->cbEnabled == 0) {//AT+CSCB=0: Disable CBS
2747 cmd_str = g_strdup_printf("AT+CSCB=0");
2749 mids_GString = g_string_new("AT+CSCB=0,\"");
2751 for(ctr1 = 0; ctr1 < setCbConfig->msgIdRangeCount; ctr1++ ) {
2752 if( setCbConfig->msgIDs[ctr1].net3gpp.selected == FALSE )
2755 if( SMS_GSM_SMS_CBMI_LIST_SIZE_MAX <= (setCbConfig->msgIDs[ctr1].net3gpp.toMsgId - setCbConfig->msgIDs[ctr1].net3gpp.fromMsgId) ) {
2756 mids_GString = g_string_new("AT+CSCB=1");
2760 appendMsgId = setCbConfig->msgIDs[ctr1].net3gpp.fromMsgId;
2762 for( ctr2 = 0; (ctr2 <= ((setCbConfig->msgIDs[ctr1].net3gpp.toMsgId) - (setCbConfig->msgIDs[ctr1].net3gpp.fromMsgId))); ctr2++ ) {
2763 dbg( "%x", appendMsgId);
2764 mids_GString = g_string_append(mids_GString, g_strdup_printf("%d", appendMsgId));
2766 if (ctr2 == ((setCbConfig->msgIDs[ctr1].net3gpp.toMsgId) - (setCbConfig->msgIDs[ctr1].net3gpp.fromMsgId))) {
2767 mids_GString = g_string_append(mids_GString, "\""); //Mids string termination
2769 mids_GString = g_string_append(mids_GString, ",");
2775 mids_str = g_string_free(mids_GString, FALSE);
2776 cmd_str = g_strdup_printf("%s", mids_str);
2780 pending = tcore_pending_new(obj, 0);
2781 atreq = tcore_at_request_new((const char *)cmd_str, NULL, TCORE_AT_NO_RESULT);
2782 if(NULL == cmd_str || NULL == atreq || NULL == pending) {
2783 err("Out of memory. Unable to proceed");
2784 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
2786 //free memory we own
2788 util_sms_free_memory(atreq);
2789 util_sms_free_memory(pending);
2792 return TCORE_RETURN_ENOMEM;
2795 util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
2797 tcore_pending_set_request_data(pending, 0, atreq);
2798 tcore_pending_set_response_callback(pending, on_response_set_cb_config, NULL);
2799 tcore_pending_link_user_request(pending, ur);
2800 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
2801 tcore_hal_send_request(hal, pending);
2806 return TCORE_RETURN_SUCCESS;
2809 static TReturn set_mem_status(CoreObject *obj, UserRequest *ur)
2811 gchar *cmd_str = NULL;
2812 TcoreHal *hal = NULL;
2813 TcoreATRequest *atreq = NULL;
2814 TcorePending *pending = NULL;
2815 const struct treq_sms_set_mem_status *setMemStatus = NULL;
2816 int memoryStatus = 0;
2820 setMemStatus = tcore_user_request_ref_data(ur, NULL);
2821 hal = tcore_object_get_hal(obj);
2822 if (NULL == setMemStatus || NULL == hal) {
2823 err("NULL input. Unable to proceed");
2824 dbg("setMemStatus: [%p], hal: [%p]", setMemStatus, hal);
2827 return TCORE_RETURN_EINVAL;
2829 if(FALSE == tcore_hal_get_power_state(hal)){
2830 dbg("cp not ready/n");
2831 return TCORE_RETURN_ENOSYS;
2834 dbg("memory_status: %d", setMemStatus->memory_status);
2836 if(setMemStatus->memory_status < SMS_PDA_MEMORY_STATUS_AVAILABLE
2837 || setMemStatus->memory_status > SMS_PDA_MEMORY_STATUS_FULL) {
2838 err("Invalid memory_status");
2841 return TCORE_RETURN_EINVAL;
2844 switch (setMemStatus->memory_status) {
2845 case SMS_PDA_MEMORY_STATUS_AVAILABLE:
2846 memoryStatus = AT_MEMORY_AVAILABLE;
2849 case SMS_PDA_MEMORY_STATUS_FULL:
2850 memoryStatus = AT_MEMORY_FULL;
2854 err("Invalid memory_status");
2856 return TCORE_RETURN_EINVAL;
2859 cmd_str = g_strdup_printf("AT+XTESM=%d", memoryStatus);
2860 pending = tcore_pending_new(obj, 0);
2861 atreq = tcore_at_request_new((const char *)cmd_str, NULL, TCORE_AT_NO_RESULT);
2863 if (NULL == cmd_str || NULL == atreq || NULL == pending) {
2864 err("Out of memory. Unable to proceed");
2865 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
2867 //free memory we own
2869 util_sms_free_memory(atreq);
2870 util_sms_free_memory(pending);
2873 return TCORE_RETURN_ENOMEM;
2876 util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
2878 tcore_pending_set_request_data(pending, 0, atreq);
2879 tcore_pending_set_response_callback(pending, on_response_set_mem_status, NULL);
2880 tcore_pending_link_user_request(pending, ur);
2881 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
2882 tcore_hal_send_request(hal, pending);
2887 return TCORE_RETURN_SUCCESS;
2890 static TReturn set_delivery_report(CoreObject *obj, UserRequest *ur)
2892 struct tresp_sms_set_delivery_report respSetDeliveryReport = {0,};
2894 respSetDeliveryReport.result = SMS_SUCCESS;
2897 if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(obj))){
2898 dbg("cp not ready/n");
2899 return TCORE_RETURN_ENOSYS;
2902 dbg("CP takes care of sending SMS ack to network for all classes of SMS. Sending default success.");
2904 tcore_user_request_send_response(ur, TRESP_SMS_SET_DELIVERY_REPORT, sizeof(struct tresp_sms_set_delivery_report), &respSetDeliveryReport);
2907 return TCORE_RETURN_SUCCESS;
2910 static TReturn set_msg_status(CoreObject *obj, UserRequest *ur)
2912 gchar *cmd_str = NULL;
2913 TcoreHal *hal = NULL;
2914 TcoreATRequest *atreq = NULL;
2915 TcorePending *pending = NULL;
2916 const struct treq_sms_set_msg_status *msg_status = NULL;
2919 hal = tcore_object_get_hal(obj);
2920 if(FALSE == tcore_hal_get_power_state(hal)){
2921 dbg("cp not ready/n");
2922 return TCORE_RETURN_ENOSYS;
2924 msg_status = tcore_user_request_ref_data(ur, NULL);
2926 cmd_str = g_strdup_printf("AT+CRSM=178,28476,%d,4,%d", (msg_status->index+1), PDU_LEN_MAX);
2927 atreq = tcore_at_request_new((const char *)cmd_str, "+CRSM", TCORE_AT_SINGLELINE);
2928 pending = tcore_pending_new(obj, 0);
2929 if (NULL == cmd_str || NULL == atreq || NULL == pending) {
2930 err("Out of memory. Unable to proceed");
2931 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
2933 //free memory we own
2935 util_sms_free_memory(atreq);
2936 util_sms_free_memory(pending);
2939 return TCORE_RETURN_ENOMEM;
2942 util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
2944 tcore_pending_set_request_data(pending, 0, atreq);
2945 tcore_pending_set_response_callback(pending, _response_get_efsms_data, NULL);
2946 tcore_pending_link_user_request(pending, ur);
2947 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
2948 tcore_hal_send_request(hal, pending);
2953 return TCORE_RETURN_SUCCESS;
2956 static TReturn get_sms_params(CoreObject *obj, UserRequest *ur)
2958 gchar *cmd_str = NULL;
2959 TcoreHal *hal = NULL;
2960 TcoreATRequest *atreq = NULL;
2961 TcorePending *pending = NULL;
2962 const struct treq_sms_get_params *getSmsParams = NULL;
2963 int record_len = 0 , *smsp_record_len = NULL;
2967 getSmsParams = tcore_user_request_ref_data(ur, NULL);
2968 hal = tcore_object_get_hal(obj);
2969 if (NULL == getSmsParams || NULL == hal) {
2970 err("NULL input. Unable to proceed");
2971 dbg("getSmsParams: [%p], hal: [%p]", getSmsParams, hal);
2974 return TCORE_RETURN_EINVAL;
2976 if(FALSE == tcore_hal_get_power_state(hal)){
2977 dbg("cp not ready/n");
2978 return TCORE_RETURN_ENOSYS;
2981 smsp_record_len = tcore_plugin_ref_property(tcore_object_ref_plugin(obj), "SMSPRECORDLEN");
2982 record_len = *smsp_record_len;
2983 dbg("record len from property %d", record_len);
2985 //AT+CRSM=command>[,<fileid>[,<P1>,<P2>,<P3>[,<data>[,<pathid>]]]]
2986 cmd_str = g_strdup_printf("AT+CRSM=178,28482,%d,4,%d", (getSmsParams->index + 1), record_len);
2988 dbg("cmd_str is %s",cmd_str);
2990 atreq = tcore_at_request_new((const char *)cmd_str, "+CRSM", TCORE_AT_SINGLELINE);
2991 pending = tcore_pending_new(obj, 0);
2992 if (NULL == cmd_str || NULL == atreq || NULL == pending) {
2993 err("Out of memory. Unable to proceed");
2994 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
2996 //free memory we own
2998 util_sms_free_memory(atreq);
2999 util_sms_free_memory(pending);
3002 return TCORE_RETURN_ENOMEM;
3005 util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
3007 tcore_pending_set_request_data(pending, 0, atreq);
3008 tcore_pending_set_response_callback(pending, on_response_get_sms_params, NULL);
3009 tcore_pending_link_user_request(pending, ur);
3010 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
3011 tcore_hal_send_request(hal, pending);
3016 return TCORE_RETURN_SUCCESS;
3019 static TReturn set_sms_params(CoreObject *obj, UserRequest *ur)
3021 gchar *cmd_str = NULL;
3022 char *encoded_data = NULL;
3023 unsigned char *temp_data = NULL;
3024 int SMSPRecordLen = 0;
3026 TcoreHal *hal = NULL;
3027 TcoreATRequest *atreq = NULL;
3028 TcorePending *pending = NULL;
3029 const struct treq_sms_set_params *setSmsParams = NULL;
3030 int encoded_data_len = 0;
3034 setSmsParams = tcore_user_request_ref_data(ur, NULL);
3035 hal = tcore_object_get_hal(obj);
3036 if (NULL == setSmsParams || NULL == hal) {
3037 err("NULL input. Unable to proceed");
3038 dbg("setSmsParams: [%p], hal: [%p]", setSmsParams, hal);
3041 if(FALSE == tcore_hal_get_power_state(hal)){
3042 dbg("cp not ready/n");
3043 return TCORE_RETURN_ENOSYS;
3046 //EFsmsp file size is 28 +Y bytes (Y is alpha id size)
3047 SMSPRecordLen = 28 + setSmsParams->params.alphaIdLen;
3048 temp_data = calloc(SMSPRecordLen,1);
3049 encoded_data = calloc(SMSPRecordLen*2 + 1,1);
3051 _tcore_util_sms_encode_smsParameters(&(setSmsParams->params), temp_data, SMSPRecordLen);
3053 util_byte_to_hex((const char *)temp_data, (char *)encoded_data,SMSPRecordLen);
3055 encoded_data_len = ((SMSPRecordLen) * 2);
3057 hal = tcore_object_get_hal(obj);
3058 pending = tcore_pending_new(obj, 0);
3060 dbg("alpha id len %d encoded data %s. Encoded data len %d",setSmsParams->params.alphaIdLen,encoded_data, encoded_data_len);
3061 cmd_str = g_strdup_printf("AT+CRSM=220,28482,%d,4,%d,\"%s\"",(setSmsParams->params.recordIndex+1),SMSPRecordLen,encoded_data);
3063 dbg("cmd str is %s",cmd_str);
3064 atreq = tcore_at_request_new(cmd_str, "+CRSM:", TCORE_AT_SINGLELINE);
3066 if (NULL == cmd_str || NULL == atreq || NULL == pending) {
3067 err("Out of memory. Unable to proceed");
3068 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
3070 //free memory we own
3072 util_sms_free_memory(atreq);
3073 util_sms_free_memory(pending);
3075 util_sms_free_memory(temp_data);
3076 util_sms_free_memory(encoded_data);
3079 return TCORE_RETURN_ENOMEM;
3082 util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
3084 tcore_pending_set_request_data(pending, 0,atreq);
3085 tcore_pending_set_response_callback(pending, on_response_set_sms_params, NULL);
3086 tcore_pending_link_user_request(pending, ur);
3087 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
3088 tcore_hal_send_request(hal, pending);
3091 util_sms_free_memory(temp_data);
3092 util_sms_free_memory(encoded_data);
3094 return TCORE_RETURN_SUCCESS;
3097 static TReturn get_paramcnt(CoreObject *obj, UserRequest *ur)
3099 gchar *cmd_str = NULL;
3100 TcoreHal *hal = NULL;
3101 TcoreATRequest *atreq = NULL;
3102 TcorePending *pending = NULL;
3106 hal = tcore_object_get_hal(obj);
3108 err("NULL HAL. Unable to proceed");
3111 return TCORE_RETURN_EINVAL;
3113 if(FALSE == tcore_hal_get_power_state(hal)){
3114 dbg("cp not ready/n");
3115 return TCORE_RETURN_ENOSYS;
3118 //AT+CRSM=command>[,<fileid>[,<P1>,<P2>,<P3>[,<data>[,<pathid>]]]]
3119 cmd_str = g_strdup_printf("AT+CRSM=192,28482");
3120 atreq = tcore_at_request_new((const char *)cmd_str, "+CRSM", TCORE_AT_SINGLELINE);
3121 pending = tcore_pending_new(obj, 0);
3123 if (NULL == cmd_str || NULL == atreq || NULL == pending) {
3124 err("NULL pointer. Unable to proceed");
3125 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
3127 //free memory we own
3129 util_sms_free_memory(atreq);
3130 util_sms_free_memory(pending);
3133 return TCORE_RETURN_FAILURE;
3136 util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
3138 tcore_pending_set_request_data(pending, 0, atreq);
3139 tcore_pending_set_response_callback(pending, on_response_get_paramcnt, NULL);
3140 tcore_pending_link_user_request(pending, ur);
3141 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
3142 tcore_hal_send_request(hal, pending);
3147 return TCORE_RETURN_SUCCESS;
3150 static struct tcore_sms_operations sms_ops = {
3151 .send_umts_msg = send_umts_msg,
3152 .read_msg = read_msg,
3153 .save_msg = save_msg,
3154 .delete_msg = delete_msg,
3155 .get_stored_msg_cnt = get_stored_msg_cnt,
3158 .get_cb_config = get_cb_config,
3159 .set_cb_config = set_cb_config,
3160 .set_mem_status = set_mem_status,
3161 .get_pref_brearer = NULL,
3162 .set_pref_brearer = NULL,
3163 .set_delivery_report = set_delivery_report,
3164 .set_msg_status = set_msg_status,
3165 .get_sms_params = get_sms_params,
3166 .set_sms_params = set_sms_params,
3167 .get_paramcnt = get_paramcnt,
3170 gboolean s_sms_init(TcorePlugin *cp, CoreObject *co_sms)
3172 int *smsp_record_len;
3176 tcore_sms_override_ops(co_sms, &sms_ops);
3178 /* Registering for SMS notifications */
3179 tcore_object_override_callback(co_sms, "\e+CMTI", on_event_class2_sms_incom_msg, NULL);
3180 tcore_object_override_callback(co_sms, "\e+CMT", on_event_sms_incom_msg, NULL);
3182 tcore_object_override_callback(co_sms, "\e+CDS", on_event_sms_incom_msg, NULL);
3183 tcore_object_override_callback(co_sms, "+XSMSMMSTAT", on_event_sms_memory_status, NULL);
3184 tcore_object_override_callback(co_sms, "+CMS", on_event_sms_memory_status, NULL);
3186 tcore_object_override_callback(co_sms, "\e+CBMI", on_event_sms_cb_incom_msg, NULL);
3187 tcore_object_override_callback(co_sms, "\e+CBM", on_event_sms_cb_incom_msg, NULL);
3188 tcore_object_override_callback(co_sms, "+XSIM", on_event_sms_ready_status, NULL);
3190 /* storing smsp record length */
3191 smsp_record_len = g_new0(int, 1);
3193 tcore_plugin_link_property(cp, "SMSPRECORDLEN", smsp_record_len);
3200 void s_sms_exit(TcorePlugin *cp, CoreObject *co_sms)
3202 int *smsp_record_len;
3204 smsp_record_len = tcore_plugin_ref_property(cp, "SMSPRECORDLEN");
3205 g_free(smsp_record_len);