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);
119 static void on_response_class2_read_msg(TcorePending *pending, int data_len, const void *data, void *user_data);
122 gboolean util_byte_to_hex(const char *byte_pdu, char *hex_pdu, int num_bytes);
124 /* gaurav.kalra: For test */
125 void print_glib_list_elem(gpointer data, gpointer user_data)
127 char *item = (char *) data;
129 dbg("item: [%s]", item);
132 /*=============================================================
134 ==============================================================*/
135 static void on_confirmation_sms_message_send(TcorePending *p, gboolean result, void *user_data)
137 dbg("Entered Function. Request message out from queue");
139 dbg("TcorePending: [%p]", p);
140 dbg("result: [%02x]", result);
141 dbg("user_data: [%p]", user_data);
143 if (result == TRUE) {
145 } else { /* Failed */
149 dbg("Exiting Function. Nothing to return");
152 /*=============================================================
154 ==============================================================*/
155 static void util_sms_free_memory(void *sms_ptr)
159 if (NULL != sms_ptr) {
160 dbg("Freeing memory location: [%p]", sms_ptr);
164 err("Invalid memory location. Nothing to do.");
171 static int util_sms_decode_smsParameters(unsigned char *incoming, unsigned int length, struct telephony_sms_Params *params)
173 int alpha_id_len = 0;
177 dbg(" RecordLen = %d", length);
179 if (incoming == NULL || params == NULL)
182 alpha_id_len = length - SMS_SMSP_PARAMS_MAX_LEN;
184 if (alpha_id_len > 0) {
185 if (alpha_id_len > SMS_SMSP_ALPHA_ID_LEN_MAX) {
186 alpha_id_len = SMS_SMSP_ALPHA_ID_LEN_MAX;
189 for (i = 0; i < alpha_id_len; i++) {
190 if (0xff == incoming[i]) {
196 memcpy(params->szAlphaId, incoming, i);
198 params->alphaIdLen = i;
200 dbg(" Alpha id length = %d", i);
202 params->alphaIdLen = 0;
203 dbg(" Alpha id length is zero");
206 // dongil01.park - start parse from here.
207 params->paramIndicator = incoming[alpha_id_len];
209 dbg(" Param Indicator = %02x", params->paramIndicator);
211 // dongil01.park(2008/12/26) - DestAddr
212 if ((params->paramIndicator & SMSPValidDestAddr) == 0) {
213 nOffset = nDestAddrOffset;
215 if (0x00 == incoming[alpha_id_len + nOffset] || 0xff == incoming[alpha_id_len + nOffset]) {
216 params->tpDestAddr.dialNumLen = 0;
218 dbg("DestAddr Length is 0");
220 if (0 < (int) incoming[alpha_id_len + nOffset]) {
221 params->tpDestAddr.dialNumLen = (int) (incoming[alpha_id_len + nOffset] - 1);
223 if (params->tpDestAddr.dialNumLen > SMS_SMSP_ADDRESS_LEN)
224 params->tpDestAddr.dialNumLen = SMS_SMSP_ADDRESS_LEN;
226 params->tpDestAddr.dialNumLen = 0;
229 params->tpDestAddr.numPlanId = incoming[alpha_id_len + (++nOffset)] & 0x0f;
230 params->tpDestAddr.typeOfNum = (incoming[alpha_id_len + nOffset] & 0x70) >> 4;
232 memcpy(params->tpDestAddr.diallingNum, &incoming[alpha_id_len + (++nOffset)], (params->tpDestAddr.dialNumLen));
234 dbg("Dest TON is %d", params->tpDestAddr.typeOfNum);
235 dbg("Dest NPI is %d", params->tpDestAddr.numPlanId);
236 dbg("Dest Length = %d", params->tpDestAddr.dialNumLen);
237 dbg("Dest Addr = %s", params->tpDestAddr.diallingNum);
240 params->tpDestAddr.dialNumLen = 0;
243 // dongil01.park(2008/12/26) - SvcAddr
244 if ((params->paramIndicator & SMSPValidSvcAddr) == 0) {
245 nOffset = nSCAAddrOffset;
247 if (0x00 == (int) incoming[alpha_id_len + nOffset] || 0xff == (int) incoming[alpha_id_len + nOffset]) {
248 params->tpSvcCntrAddr.dialNumLen = 0;
250 dbg(" SCAddr Length is 0");
252 if (0 < (int) incoming[alpha_id_len + nOffset]) {
253 params->tpSvcCntrAddr.dialNumLen = (int) (incoming[alpha_id_len + nOffset] - 1);
255 if (params->tpSvcCntrAddr.dialNumLen > SMS_SMSP_ADDRESS_LEN)
256 params->tpSvcCntrAddr.dialNumLen = SMS_SMSP_ADDRESS_LEN;
258 params->tpSvcCntrAddr.numPlanId = incoming[alpha_id_len + (++nOffset)] & 0x0f;
259 params->tpSvcCntrAddr.typeOfNum = (incoming[alpha_id_len + nOffset] & 0x70) >> 4;
261 memcpy(params->tpSvcCntrAddr.diallingNum, &incoming[alpha_id_len + (++nOffset)], (params->tpSvcCntrAddr.dialNumLen));
263 dbg("SCAddr Length = %d ", params->tpSvcCntrAddr.dialNumLen);
264 dbg("SCAddr TON is %d", params->tpSvcCntrAddr.typeOfNum);
265 dbg("SCAddr NPI is %d", params->tpSvcCntrAddr.numPlanId);
267 for (i = 0; i < (int) params->tpSvcCntrAddr.dialNumLen; i++)
268 dbg("SCAddr = %d [%02x]", i, params->tpSvcCntrAddr.diallingNum[i]);
270 params->tpSvcCntrAddr.dialNumLen = 0;
273 } else if ((0x00 < (int) incoming[alpha_id_len + nSCAAddrOffset] && (int) incoming[alpha_id_len + nSCAAddrOffset] <= 12)
274 || 0xff != (int) incoming[alpha_id_len + nSCAAddrOffset]) {
275 nOffset = nSCAAddrOffset;
277 if (0x00 == (int) incoming[alpha_id_len + nOffset] || 0xff == (int) incoming[alpha_id_len + nOffset]) {
278 params->tpSvcCntrAddr.dialNumLen = 0;
279 dbg("SCAddr Length is 0");
281 if (0 < (int) incoming[alpha_id_len + nOffset]) {
282 params->tpSvcCntrAddr.dialNumLen = (int) (incoming[alpha_id_len + nOffset] - 1);
284 params->tpSvcCntrAddr.dialNumLen = incoming[alpha_id_len + nOffset] - 1;
286 if (params->tpSvcCntrAddr.dialNumLen > SMS_SMSP_ADDRESS_LEN)
287 params->tpSvcCntrAddr.dialNumLen = SMS_SMSP_ADDRESS_LEN;
289 params->tpSvcCntrAddr.numPlanId = incoming[alpha_id_len + (++nOffset)] & 0x0f;
290 params->tpSvcCntrAddr.typeOfNum = (incoming[alpha_id_len + nOffset] & 0x70) >> 4;
292 memcpy(params->tpSvcCntrAddr.diallingNum, &incoming[alpha_id_len + (++nOffset)],
293 (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]);
302 params->tpSvcCntrAddr.dialNumLen = 0;
306 params->tpSvcCntrAddr.dialNumLen = 0;
309 if ((params->paramIndicator & SMSPValidPID) == 0 && (alpha_id_len + nPIDOffset) < MAX_GSM_SMS_PARAM_RECORD_SIZE) {
310 params->tpProtocolId = incoming[alpha_id_len + nPIDOffset];
312 if ((params->paramIndicator & SMSPValidDCS) == 0 && (alpha_id_len + nDCSOffset) < MAX_GSM_SMS_PARAM_RECORD_SIZE) {
313 params->tpDataCodingScheme = incoming[alpha_id_len + nDCSOffset];
315 if ((params->paramIndicator & SMSPValidVP) == 0 && (alpha_id_len + nVPOffset) < MAX_GSM_SMS_PARAM_RECORD_SIZE) {
316 params->tpValidityPeriod = incoming[alpha_id_len + nVPOffset];
319 dbg(" Alpha Id(Len) = %d", (int) params->alphaIdLen);
321 for (i = 0; i < (int) params->alphaIdLen; i++) {
322 dbg(" Alpha Id = [%d] [%c]", i, params->szAlphaId[i]);
324 dbg(" PID = %d", params->tpProtocolId);
325 dbg(" DCS = %d", params->tpDataCodingScheme);
326 dbg(" VP = %d", params->tpValidityPeriod);
332 /*=============================================================
334 ==============================================================*/
335 static gboolean on_event_sms_ready_status(CoreObject *o, const void *event_info, void *user_data)
337 struct tnoti_sms_ready_status readyStatusInfo = {0, };
339 GSList *tokens = NULL;
340 GSList *lines = NULL;
342 // CoreObject *o = NULL;
344 int rtn = -1, status = 0;
346 dbg(" Func Entrance");
348 lines = (GSList *) event_info;
349 if (1 != g_slist_length(lines)) {
350 dbg("unsolicited msg but multiple line");
353 line = (char *) (lines->data);
355 dbg(" Func Entrance");
359 dbg("noti line is %s", line);
360 tokens = tcore_at_tok_new(line);
361 pResp = g_slist_nth_data(tokens, 0);
363 status = atoi(pResp);
368 if (status == AT_SMS_DEVICE_READY) {
369 readyStatusInfo.status = SMS_DEVICE_READY;
370 tcore_sms_set_ready_status(o, readyStatusInfo.status);
371 dbg("SMS Ready status = [%s]", readyStatusInfo.status ? "TRUE" : "FALSE");
372 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);
373 dbg(" Return value [%d]", rtn);
375 readyStatusInfo.status = SMS_DEVICE_NOT_READY;
380 tcore_at_tok_free(tokens);
384 static gboolean on_event_class2_sms_incom_msg(CoreObject *obj, const void *event_info, void *user_data)
386 // +CMTI: <mem>,<index>
388 GSList *tokens = NULL, *lines = NULL;
389 char *line = NULL, *cmd_str = NULL;
390 int index = 0, mem_type = 0;
391 TcoreHal *hal = NULL;
392 TcoreATRequest *atreq = NULL;
393 TcorePending *pending = NULL;
395 dbg("Entered Function");
397 lines = (GSList *) event_info;
398 line = (char *) g_slist_nth_data(lines, 0); /* Fetch Line 1 */
400 dbg("Line 1: [%s]", line);
403 err("Line 1 is invalid");
407 tokens = tcore_at_tok_new(line); /* Split Line 1 into tokens */
408 mem_type = atoi(g_slist_nth_data(tokens, 0)); // Type of Memory stored
409 index = atoi((char *) g_slist_nth_data(tokens, 1));
411 hal = tcore_object_get_hal(obj);
413 err("NULL input. Unable to proceed");
414 dbg("readMsg: hal: [%p]", hal);
417 return TCORE_RETURN_EINVAL;
420 dbg("index: [%d]", index);
422 cmd_str = g_strdup_printf("AT+CMGR=%d", index);
423 atreq = tcore_at_request_new((const char *) cmd_str, "+CMGR", TCORE_AT_PDU);
424 pending = tcore_pending_new(obj, 0);
426 if (NULL == cmd_str || NULL == atreq || NULL == pending) {
427 err("Out of memory. Unable to proceed");
428 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
430 // free memory we own
432 util_sms_free_memory(atreq);
433 util_sms_free_memory(pending);
436 return TCORE_RETURN_ENOMEM;
439 util_hex_dump(" ", strlen(cmd_str), (void *) cmd_str);
441 tcore_pending_set_request_data(pending, 0, atreq);
442 tcore_pending_set_response_callback(pending, on_response_class2_read_msg, (void *) (uintptr_t) index); // storing index as user data for response
443 tcore_pending_link_user_request(pending, NULL);
444 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
445 tcore_hal_send_request(hal, pending);
449 tcore_at_tok_free(tokens);
454 static gboolean on_event_sms_incom_msg(CoreObject *o, const void *event_info, void *user_data)
456 // +CMT: [<alpha>],<length><CR><LF><pdu> (PDU mode enabled);
459 GSList *tokens = NULL;
460 GSList *lines = NULL;
462 int pdu_len = 0, no_of_tokens = 0;
463 unsigned char *bytePDU = NULL;
464 struct tnoti_sms_umts_msg gsmMsgInfo;
467 dbg("Entered Function");
469 lines = (GSList *) event_info;
470 memset(&gsmMsgInfo, 0x00, sizeof(struct tnoti_sms_umts_msg));
472 if (2 != g_slist_length(lines)) {
473 err("Invalid number of lines for +CMT. Must be 2");
477 line = (char *) g_slist_nth_data(lines, 0); /* Fetch Line 1 */
479 dbg("Line 1: [%s]", line);
482 err("Line 1 is invalid");
486 tokens = tcore_at_tok_new(line); /* Split Line 1 into tokens */
488 no_of_tokens = g_slist_length(tokens);
490 if (no_of_tokens == 2) { // in case of incoming SMS +CMT
491 dbg("Alpha ID: [%02x]", g_slist_nth_data(tokens, 0)); /* 0: Alpha ID */
492 pdu_len = atoi((char *) g_slist_nth_data(tokens, 1));
493 dbg("pdu_len: [%d]", pdu_len); /* 1: PDU Length */
494 } else if (no_of_tokens == 1) { // in case of incoming status report +CDS
495 pdu_len = atoi((char *) g_slist_nth_data(tokens, 0));
496 dbg("pdu_len: [%d]", pdu_len); /* 1: PDU Length */
499 line = (char *) g_slist_nth_data(lines, 1); /* Fetch Line 2 */
501 dbg("Line 2: [%s]", line);
504 err("Line 2 is invalid");
508 /* Convert to Bytes */
509 bytePDU = (unsigned char *) util_hexStringToBytes(line);
511 sca_length = bytePDU[0];
513 dbg("SCA length = %d", sca_length);
515 gsmMsgInfo.msgInfo.msgLength = pdu_len - (sca_length + 1);
517 if (sca_length == 0) {
518 memcpy(gsmMsgInfo.msgInfo.tpduData, &bytePDU[1], gsmMsgInfo.msgInfo.msgLength);
520 memcpy(gsmMsgInfo.msgInfo.sca, &bytePDU[1], sca_length);
521 memcpy(gsmMsgInfo.msgInfo.tpduData, &bytePDU[sca_length + 1], gsmMsgInfo.msgInfo.msgLength);
524 util_hex_dump(" ", strlen(line) / 2, bytePDU);
525 util_hex_dump(" ", sca_length, gsmMsgInfo.msgInfo.sca);
526 util_hex_dump(" ", gsmMsgInfo.msgInfo.msgLength, gsmMsgInfo.msgInfo.tpduData);
528 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);
531 tcore_at_tok_free(tokens);
540 static gboolean on_event_sms_memory_status(CoreObject *o, const void *event_info, void *user_data)
542 struct tnoti_sms_memory_status memStatusInfo = {0, };
544 int rtn = -1, memoryStatus = -1;
545 GSList *tokens = NULL;
546 GSList *lines = NULL;
547 char *line = NULL, *pResp = NULL;
551 lines = (GSList *) event_info;
552 if (1 != g_slist_length(lines)) {
553 dbg("unsolicited msg but multiple line");
556 line = (char *) (lines->data);
560 tokens = tcore_at_tok_new(line);
561 pResp = g_slist_nth_data(tokens, 0);
564 memoryStatus = atoi(pResp);
565 dbg("memoryStatus is %d", memoryStatus);
566 if (memoryStatus == 0) { // SIM Full condition
567 memStatusInfo.status = SMS_PHONE_MEMORY_STATUS_FULL;
569 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);
571 tcore_at_tok_free(tokens);
580 static gboolean on_event_sms_cb_incom_msg(CoreObject *o, const void *event_info, void *user_data)
582 // +CBM: <length><CR><LF><pdu>
584 struct tnoti_sms_cellBroadcast_msg cbMsgInfo;
586 int rtn = -1, length = 0;
587 char *line = NULL, *pdu = NULL, *pResp = NULL;
588 GSList *tokens = NULL;
589 GSList *lines = NULL;
591 dbg(" Func Entrance");
593 lines = (GSList *) event_info;
595 memset(&cbMsgInfo, 0, sizeof(struct tnoti_sms_cellBroadcast_msg));
597 line = (char *) (lines->data);
601 dbg("Noti line is %s", line);
602 tokens = tcore_at_tok_new(line); /* Split Line 1 into tokens */
604 pResp = g_slist_nth_data(tokens, 0);
606 length = atoi(pResp);
608 dbg("token 0 is null");
611 pdu = g_slist_nth_data(lines, 1);
613 cbMsgInfo.cbMsg.length = length;
614 cbMsgInfo.cbMsg.cbMsgType = SMS_CB_MSG_CBS;
616 dbg("CB Msg LENGTH [%2x]", length);
618 if ((cbMsgInfo.cbMsg.length > 0) && (SMS_CB_SIZE_MAX >= cbMsgInfo.cbMsg.length)) {
619 unsigned char *byte_pdu = NULL;
621 byte_pdu = (unsigned char *) util_hexStringToBytes(pdu);
623 memcpy(cbMsgInfo.cbMsg.msgData, (char *) byte_pdu, cbMsgInfo.cbMsg.length);
624 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);
627 dbg("Invalid Message Length");
630 dbg("Recieved NULL pdu");
636 dbg(" Return value [%d]", rtn);
639 tcore_at_tok_free(tokens);
645 /*=============================================================
647 ==============================================================*/
648 static void on_response_sms_delete_msg(TcorePending *p, int data_len, const void *data, void *user_data)
650 struct tresp_sms_delete_msg delMsgInfo = {0, };
651 UserRequest *ur = NULL;
652 const TcoreATResponse *atResp = data;
655 int index = (int) user_data;
657 dbg(" Func Entrance");
659 ur = tcore_pending_ref_user_request(p);
660 if (atResp->success) {
662 delMsgInfo.index = index;
663 delMsgInfo.result = SMS_SENDSMS_SUCCESS;
666 delMsgInfo.index = index;
667 delMsgInfo.result = SMS_DEVICE_FAILURE;
670 rtn = tcore_user_request_send_response(ur, TRESP_SMS_DELETE_MSG, sizeof(struct tresp_sms_delete_msg), &delMsgInfo);
675 static void on_response_sms_save_msg(TcorePending *p, int data_len, const void *data, void *user_data)
677 struct tresp_sms_save_msg saveMsgInfo = {0, };
678 UserRequest *ur = NULL;
679 const TcoreATResponse *atResp = data;
680 GSList *tokens = NULL;
685 ur = tcore_pending_ref_user_request(p);
686 if (atResp->success) {
689 line = (char *) atResp->lines->data;
690 tokens = tcore_at_tok_new(line);
691 pResp = g_slist_nth_data(tokens, 0);
694 saveMsgInfo.index = (atoi(pResp) - 1); /* IMC index starts from 1 */
695 saveMsgInfo.result = SMS_SENDSMS_SUCCESS;
698 saveMsgInfo.index = -1;
699 saveMsgInfo.result = SMS_DEVICE_FAILURE;
701 tcore_at_tok_free(tokens);
705 saveMsgInfo.index = -1;
706 saveMsgInfo.result = SMS_DEVICE_FAILURE;
709 rtn = tcore_user_request_send_response(ur, TRESP_SMS_SAVE_MSG, sizeof(struct tresp_sms_save_msg), &saveMsgInfo);
710 dbg("Return value [%d]", rtn);
714 static void on_response_send_umts_msg(TcorePending *pending, int data_len, const void *data, void *user_data)
716 const TcoreATResponse *at_response = data;
717 struct tresp_sms_send_umts_msg resp_umts;
718 UserRequest *user_req = NULL;
721 GSList *tokens = NULL;
722 char *gslist_line = NULL, *line_token = NULL;
726 user_req = tcore_pending_ref_user_request(pending);
728 if (NULL == user_req) {
729 err("No user request");
735 memset(&resp_umts, 0x00, sizeof(resp_umts));
736 resp_umts.result = SMS_DEVICE_FAILURE;
738 if (at_response->success > 0) { // success
740 if (at_response->lines) { // lines present in at_response
741 gslist_line = (char *) at_response->lines->data;
742 dbg("gslist_line: [%s]", gslist_line);
744 tokens = tcore_at_tok_new(gslist_line); // extract tokens
746 line_token = g_slist_nth_data(tokens, 0);
747 if (line_token != NULL) {
748 msg_ref = atoi(line_token);
749 dbg("Message Reference: [%d]", msg_ref);
751 resp_umts.result = SMS_SENDSMS_SUCCESS;
753 dbg("No Message Reference received");
755 tcore_at_tok_free(tokens);
756 } else { // no lines in at_response
763 tcore_user_request_send_response(user_req, TRESP_SMS_SEND_UMTS_MSG, sizeof(resp_umts), &resp_umts);
769 static void on_response_class2_read_msg(TcorePending *pending, int data_len, const void *data, void *user_data)
771 const TcoreATResponse *at_response = data;
772 GSList *tokens = NULL;
773 char *gslist_line = NULL, *line_token = NULL, *hex_pdu = NULL;
774 int pdu_len = 0, rtn = 0;
775 unsigned char *bytePDU = NULL;
776 struct tnoti_sms_umts_msg gsmMsgInfo;
780 dbg("lines: [%p]", at_response->lines);
781 g_slist_foreach(at_response->lines, print_glib_list_elem, NULL); // for debug log
783 if (at_response->success > 0) {
785 if (at_response->lines) {
787 gslist_line = (char *) at_response->lines->data;
789 dbg("gslist_line: [%s]", gslist_line);
791 tokens = tcore_at_tok_new(gslist_line);
792 dbg("Number of tokens: [%d]", g_slist_length(tokens));
793 g_slist_foreach(tokens, print_glib_list_elem, NULL); // for debug log
795 line_token = g_slist_nth_data(tokens, 2); // Third Token: Length
796 if (line_token != NULL) {
797 pdu_len = atoi(line_token);
798 dbg("Length: [%d]", pdu_len);
802 gslist_line = (char *) at_response->lines->next->data;
804 dbg("gslist_line: [%s]", gslist_line);
806 // free the consumed token
807 tcore_at_tok_free(tokens);
809 tokens = tcore_at_tok_new(gslist_line);
810 dbg("Number of tokens: [%d]", g_slist_length(tokens));
811 g_slist_foreach(tokens, print_glib_list_elem, NULL); // for debug log
813 hex_pdu = g_slist_nth_data(tokens, 0); // Fetch SMS PDU
815 // free the consumed token
816 tcore_at_tok_free(tokens);
824 /* Convert to Bytes */
825 bytePDU = (unsigned char *) util_hexStringToBytes(hex_pdu);
827 sca_length = bytePDU[0];
829 dbg("SCA length = %d", sca_length);
831 gsmMsgInfo.msgInfo.msgLength = pdu_len - (sca_length + 1);
833 if (sca_length == 0) {
834 memcpy(gsmMsgInfo.msgInfo.tpduData, &bytePDU[1], gsmMsgInfo.msgInfo.msgLength);
836 memcpy(gsmMsgInfo.msgInfo.sca, bytePDU, sca_length);
837 memcpy(gsmMsgInfo.msgInfo.tpduData, &bytePDU[sca_length + 1], gsmMsgInfo.msgInfo.msgLength);
840 util_hex_dump(" ", strlen(hex_pdu) / 2, bytePDU);
841 util_hex_dump(" ", sca_length, gsmMsgInfo.msgInfo.sca);
842 util_hex_dump(" ", gsmMsgInfo.msgInfo.msgLength, gsmMsgInfo.msgInfo.tpduData);
844 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);
852 static void on_response_read_msg(TcorePending *pending, int data_len, const void *data, void *user_data)
854 const TcoreATResponse *at_response = data;
855 struct tresp_sms_read_msg resp_read_msg;
856 UserRequest *user_req = NULL;
858 GSList *tokens = NULL;
859 char *gslist_line = NULL, *line_token = NULL, *byte_pdu = NULL, *hex_pdu = NULL;
861 int msg_status = 0, alpha_id = 0, pdu_len = 0;
862 int index = (int) (uintptr_t) user_data;
865 dbg("index: [%d]", index);
866 g_slist_foreach(at_response->lines, print_glib_list_elem, NULL); // for debug log
868 user_req = tcore_pending_ref_user_request(pending);
869 if (NULL == user_req) {
870 err("No user request");
876 memset(&resp_read_msg, 0x00, sizeof(resp_read_msg));
877 resp_read_msg.result = SMS_PHONE_FAILURE;
879 if (at_response->success > 0) {
881 if (at_response->lines) {
883 gslist_line = (char *) at_response->lines->data;
885 dbg("gslist_line: [%s]", gslist_line);
887 tokens = tcore_at_tok_new(gslist_line);
888 dbg("Number of tokens: [%d]", g_slist_length(tokens));
889 g_slist_foreach(tokens, print_glib_list_elem, NULL); // for debug log
891 line_token = g_slist_nth_data(tokens, 0); // First Token: Message Status
892 if (line_token != NULL) {
893 msg_status = atoi(line_token);
894 dbg("msg_status is %d", msg_status);
895 switch (msg_status) {
897 resp_read_msg.dataInfo.msgStatus = SMS_STATUS_UNREAD;
901 resp_read_msg.dataInfo.msgStatus = SMS_STATUS_READ;
905 resp_read_msg.dataInfo.msgStatus = SMS_STATUS_UNSENT;
909 resp_read_msg.dataInfo.msgStatus = SMS_STATUS_SENT;
912 case AT_ALL: // Fall Through
913 default: // Fall Through
914 resp_read_msg.dataInfo.msgStatus = SMS_STATUS_RESERVED;
919 line_token = g_slist_nth_data(tokens, 1); // Second Token: AlphaID
920 if (line_token != NULL) {
921 alpha_id = atoi(line_token);
922 dbg("AlphaID: [%d]", alpha_id);
925 line_token = g_slist_nth_data(tokens, 2); // Third Token: Length
926 if (line_token != NULL) {
927 pdu_len = atoi(line_token);
928 dbg("Length: [%d]", pdu_len);
932 hex_pdu = (char *) at_response->lines->next->data;
934 dbg("EF-SMS PDU: [%s]", hex_pdu);
936 // free the consumed token
937 tcore_at_tok_free(tokens);
939 if (NULL != hex_pdu) {
940 util_hex_dump(" ", sizeof(hex_pdu), (void *) hex_pdu);
942 byte_pdu = util_hexStringToBytes(hex_pdu);
944 sca_length = (int) byte_pdu[0];
946 resp_read_msg.dataInfo.simIndex = index; // Retrieving index stored as user_data
948 dbg("SCA Length : %d", sca_length);
950 resp_read_msg.dataInfo.smsData.msgLength = pdu_len;
951 dbg("msgLength: [%d]", resp_read_msg.dataInfo.smsData.msgLength);
953 if (0 == sca_length) {
954 if ((resp_read_msg.dataInfo.smsData.msgLength > 0)
955 && (resp_read_msg.dataInfo.smsData.msgLength <= SMS_SMDATA_SIZE_MAX)) {
956 memset(resp_read_msg.dataInfo.smsData.sca, 0, TAPI_SIM_SMSP_ADDRESS_LEN);
957 memcpy(resp_read_msg.dataInfo.smsData.tpduData, &byte_pdu[1], resp_read_msg.dataInfo.smsData.msgLength);
959 resp_read_msg.result = SMS_SUCCESS;
961 dbg("Invalid Message Length");
962 resp_read_msg.result = SMS_INVALID_PARAMETER_FORMAT;
965 if ((resp_read_msg.dataInfo.smsData.msgLength > 0)
966 && (resp_read_msg.dataInfo.smsData.msgLength <= SMS_SMDATA_SIZE_MAX)) {
967 memcpy(resp_read_msg.dataInfo.smsData.sca, (char *) byte_pdu, (sca_length + 1));
968 memcpy(resp_read_msg.dataInfo.smsData.tpduData, &byte_pdu[sca_length + 1], resp_read_msg.dataInfo.smsData.msgLength);
970 util_hex_dump(" ", SMS_SMSP_ADDRESS_LEN, (void *) resp_read_msg.dataInfo.smsData.sca);
971 util_hex_dump(" ", (SMS_SMDATA_SIZE_MAX + 1), (void *) resp_read_msg.dataInfo.smsData.tpduData);
972 util_hex_dump(" ", sizeof(byte_pdu), (void *) byte_pdu);
974 resp_read_msg.result = SMS_SUCCESS;
976 dbg("Invalid Message Length");
977 resp_read_msg.result = SMS_INVALID_PARAMETER_FORMAT;
991 tcore_user_request_send_response(user_req, TRESP_SMS_READ_MSG, sizeof(resp_read_msg), &resp_read_msg);
997 static void on_response_get_msg_indices(TcorePending *pending, int data_len, const void *data, void *user_data)
999 const TcoreATResponse *at_response = data;
1000 struct tresp_sms_get_storedMsgCnt resp_stored_msg_cnt;
1001 UserRequest *user_req = NULL;
1002 struct tresp_sms_get_storedMsgCnt *resp_stored_msg_cnt_prev = NULL;
1004 GSList *tokens = NULL;
1005 char *gslist_line = NULL, *line_token = NULL;
1006 int gslist_line_count = 0, ctr_loop = 0;
1010 resp_stored_msg_cnt_prev = (struct tresp_sms_get_storedMsgCnt *) user_data;
1011 user_req = tcore_pending_ref_user_request(pending);
1013 memset(&resp_stored_msg_cnt, 0x00, sizeof(resp_stored_msg_cnt));
1014 resp_stored_msg_cnt.result = SMS_DEVICE_FAILURE;
1016 if (at_response->success) {
1018 if (at_response->lines) {
1019 gslist_line_count = g_slist_length(at_response->lines);
1021 if (gslist_line_count > SMS_GSM_SMS_MSG_NUM_MAX)
1022 gslist_line_count = SMS_GSM_SMS_MSG_NUM_MAX;
1024 dbg("Number of lines: [%d]", gslist_line_count);
1025 g_slist_foreach(at_response->lines, print_glib_list_elem, NULL); // for debug log
1027 for (ctr_loop = 0; ctr_loop < gslist_line_count; ctr_loop++) {
1028 gslist_line = (char *) g_slist_nth_data(at_response->lines, ctr_loop); /* Fetch Line i */
1030 dbg("gslist_line [%d] is [%s]", ctr_loop, gslist_line);
1032 if (NULL != gslist_line) {
1033 tokens = tcore_at_tok_new(gslist_line);
1035 g_slist_foreach(tokens, print_glib_list_elem, NULL); // for debug log
1037 line_token = g_slist_nth_data(tokens, 0);
1038 if (NULL != line_token) {
1039 resp_stored_msg_cnt.storedMsgCnt.indexList[ctr_loop] = atoi(line_token);
1040 resp_stored_msg_cnt.result = SMS_SENDSMS_SUCCESS;
1042 dbg("line_token of gslist_line [%d] is NULL", ctr_loop);
1045 tcore_at_tok_free(tokens);
1047 dbg("gslist_line [%d] is NULL", ctr_loop);
1053 if (resp_stored_msg_cnt_prev->storedMsgCnt.usedCount == 0) { // Check if used count is zero
1054 resp_stored_msg_cnt.result = SMS_SENDSMS_SUCCESS;
1058 dbg("Respnose NOK");
1061 resp_stored_msg_cnt.storedMsgCnt.totalCount = resp_stored_msg_cnt_prev->storedMsgCnt.totalCount;
1062 resp_stored_msg_cnt.storedMsgCnt.usedCount = resp_stored_msg_cnt_prev->storedMsgCnt.usedCount;
1064 util_sms_free_memory(resp_stored_msg_cnt_prev);
1066 dbg("total: [%d], used: [%d], result: [%d]", resp_stored_msg_cnt.storedMsgCnt.totalCount, resp_stored_msg_cnt.storedMsgCnt.usedCount, resp_stored_msg_cnt.result);
1067 for (ctr_loop = 0; ctr_loop < gslist_line_count; ctr_loop++) {
1068 dbg("index: [%d]", resp_stored_msg_cnt.storedMsgCnt.indexList[ctr_loop]);
1071 tcore_user_request_send_response(user_req, TRESP_SMS_GET_STORED_MSG_COUNT, sizeof(resp_stored_msg_cnt), &resp_stored_msg_cnt);
1077 static void on_response_get_stored_msg_cnt(TcorePending *pending, int data_len, const void *data, void *user_data)
1079 UserRequest *ur = NULL, *ur_dup = NULL;
1080 struct tresp_sms_get_storedMsgCnt *respStoredMsgCnt = NULL;
1081 const TcoreATResponse *atResp = data;
1082 GSList *tokens = NULL;
1083 char *line = NULL, *pResp = NULL, *cmd_str = NULL;
1084 TcoreATRequest *atReq = NULL;
1085 int usedCnt = 0, totalCnt = 0, result = 0;
1087 TcorePending *pending_new = NULL;
1088 CoreObject *o = NULL;
1092 respStoredMsgCnt = malloc(sizeof(struct tresp_sms_get_storedMsgCnt));
1093 result = SMS_DEVICE_FAILURE;
1095 ur = tcore_pending_ref_user_request(pending);
1096 ur_dup = tcore_user_request_ref(ur);
1097 o = tcore_pending_ref_core_object(pending);
1099 if (atResp->success > 0) {
1101 if (NULL != atResp->lines) {
1102 line = (char *) atResp->lines->data;
1103 dbg("line is %s", line);
1105 tokens = tcore_at_tok_new(line);
1106 pResp = g_slist_nth_data(tokens, 0);
1109 usedCnt = atoi(pResp);
1110 dbg("used cnt is %d", usedCnt);
1113 pResp = g_slist_nth_data(tokens, 1);
1115 totalCnt = atoi(pResp);
1116 result = SMS_SENDSMS_SUCCESS;
1118 respStoredMsgCnt->storedMsgCnt.usedCount = usedCnt;
1119 respStoredMsgCnt->storedMsgCnt.totalCount = totalCnt;
1120 respStoredMsgCnt->result = result;
1122 dbg("used %d, total %d, result %d", usedCnt, totalCnt, result);
1124 pending_new = tcore_pending_new(o, 0);
1125 // Get all messages information
1126 cmd_str = g_strdup_printf("AT+CMGL=4");
1127 atReq = tcore_at_request_new((const char *) cmd_str, "+CMGL", TCORE_AT_MULTILINE);
1129 dbg("cmd str is %s", cmd_str);
1131 tcore_pending_set_request_data(pending_new, 0, atReq);
1132 tcore_pending_set_response_callback(pending_new, on_response_get_msg_indices, (void *) respStoredMsgCnt);
1133 tcore_pending_link_user_request(pending_new, ur_dup);
1134 tcore_pending_set_send_callback(pending_new, on_confirmation_sms_message_send, NULL);
1135 tcore_hal_send_request(tcore_object_get_hal(o), pending_new);
1137 // free the consumed token
1138 tcore_at_tok_free(tokens);
1145 // free the consumed token
1147 tcore_at_tok_free(tokens);
1152 err("Response NOK");
1154 respStoredMsgCnt->result = result;
1155 tcore_user_request_send_response(ur, TRESP_SMS_GET_STORED_MSG_COUNT, sizeof(struct tresp_sms_get_storedMsgCnt), &respStoredMsgCnt);
1162 static void on_response_get_sca(TcorePending *pending, int data_len, const void *data, void *user_data)
1164 const TcoreATResponse *at_response = data;
1165 struct tresp_sms_get_sca respGetSca;
1166 UserRequest *user_req = NULL;
1168 GSList *tokens = NULL;
1169 char *gslist_line = NULL, *sca_addr = NULL, *sca_toa = NULL;
1173 memset(&respGetSca, 0, sizeof(respGetSca));
1174 respGetSca.result = SMS_DEVICE_FAILURE;
1176 user_req = tcore_pending_ref_user_request(pending);
1178 if (at_response->success) {
1180 if (at_response->lines) {
1181 gslist_line = (char *) at_response->lines->data;
1183 tokens = tcore_at_tok_new(gslist_line);
1184 sca_addr = g_slist_nth_data(tokens, 0);
1185 sca_toa = g_slist_nth_data(tokens, 1);
1187 if ((NULL != sca_addr)
1188 && (NULL != sca_toa)) {
1189 dbg("sca_addr: [%s]. sca_toa: [%s]", sca_addr, sca_toa);
1191 respGetSca.scaAddress.dialNumLen = strlen(sca_addr);
1193 if (145 == atoi(sca_toa)) {
1194 respGetSca.scaAddress.typeOfNum = SIM_TON_INTERNATIONAL;
1196 respGetSca.scaAddress.typeOfNum = SIM_TON_NATIONAL;
1199 respGetSca.scaAddress.numPlanId = 0;
1201 memcpy(respGetSca.scaAddress.diallingNum, sca_addr, strlen(sca_addr));
1203 dbg("len [%d], sca_addr [%s], TON [%d], NPI [%d]", respGetSca.scaAddress.dialNumLen, respGetSca.scaAddress.diallingNum, respGetSca.scaAddress.typeOfNum, respGetSca.scaAddress.numPlanId);
1205 respGetSca.result = SMS_SENDSMS_SUCCESS;
1207 err("sca_addr OR sca_toa NULL");
1213 dbg("Response NOK");
1216 tcore_user_request_send_response(user_req, TRESP_SMS_GET_SCA, sizeof(respGetSca), &respGetSca);
1219 tcore_at_tok_free(tokens);
1225 static void on_response_set_sca(TcorePending *pending, int data_len, const void *data, void *user_data)
1228 Response is expected in this format
1234 // CoreObject *obj = user_data;
1236 // copies the AT response data to resp
1237 const TcoreATResponse *atResp = data;
1238 struct tresp_sms_set_sca respSetSca;
1240 memset(&respSetSca, 0, sizeof(struct tresp_sms_set_sca));
1242 ur = tcore_pending_ref_user_request(pending);
1244 dbg("no user_request");
1248 if (atResp->success > 0) {
1250 respSetSca.result = SMS_SUCCESS;
1252 dbg("RESPONSE NOK");
1253 respSetSca.result = SMS_DEVICE_FAILURE;
1256 tcore_user_request_send_response(ur, TRESP_SMS_SET_SCA, sizeof(struct tresp_sms_set_sca), &respSetSca);
1261 static void on_response_get_cb_config(TcorePending *p, int data_len, const void *data, void *user_data)
1264 struct tresp_sms_get_cb_config respGetCbConfig;
1265 const TcoreATResponse *atResp = data;
1266 GSList *tokens = NULL;
1267 int i = 0, mode = 0, h_flag = FALSE;
1268 char *mid = NULL, *mid1 = NULL, *pResp = NULL, *line = NULL;
1269 char delim[] = ",", delim1[] = "-";
1271 memset(&respGetCbConfig, 0, sizeof(struct tresp_sms_get_cb_config));
1272 respGetCbConfig.result = SMS_DEVICE_FAILURE;
1274 ur = tcore_pending_ref_user_request(p);
1276 dbg("no user_request");
1280 respGetCbConfig.cbConfig.net3gppType = SMS_NETTYPE_3GPP;
1282 if (atResp->success) {
1284 if (atResp->lines) {
1285 line = (char *) atResp->lines->data;
1287 dbg("line is %s", line);
1288 tokens = tcore_at_tok_new(line);
1289 pResp = g_slist_nth_data(tokens, 0);
1292 respGetCbConfig.cbConfig.cbEnabled = mode;
1294 pResp = g_slist_nth_data(tokens, 1);
1296 mid = strtok(pResp, delim); // check for multiple msg ids seperated by comma delimiter
1297 while (mid != NULL) {
1298 mid1 = strtok(mid, delim1); // check for msg id ranges where delim is hyphen. Ex 0 -21
1299 while (mid1 != NULL) {
1300 respGetCbConfig.cbConfig.msgIDs[i].net3gpp.fromMsgId = atoi(mid1);
1301 mid1 = strtok(NULL, delim1);
1303 respGetCbConfig.cbConfig.msgIDs[i].net3gpp.toMsgId = atoi(mid1);
1305 respGetCbConfig.cbConfig.msgIDs[i].net3gpp.selected = TRUE;
1306 respGetCbConfig.result = SMS_SENDSMS_SUCCESS;
1310 if ((h_flag == FALSE) && (mid != NULL) && (strlen(mid) > 0)) {
1311 respGetCbConfig.cbConfig.msgIDs[i].net3gpp.fromMsgId = atoi(mid);
1312 respGetCbConfig.cbConfig.msgIDs[i].net3gpp.toMsgId = atoi(mid);
1313 respGetCbConfig.cbConfig.msgIDs[i].net3gpp.selected = TRUE;
1315 respGetCbConfig.result = SMS_SENDSMS_SUCCESS;
1317 dbg("mid is %s\n", mid);
1318 mid = strtok(NULL, delim);
1321 respGetCbConfig.cbConfig.msgIdRangeCount = i;
1324 respGetCbConfig.cbConfig.msgIdRangeCount = 1;
1325 respGetCbConfig.cbConfig.msgIDs[0].net3gpp.fromMsgId = 0x0000;
1326 respGetCbConfig.cbConfig.msgIDs[0].net3gpp.toMsgId = 0xFFFF;
1327 respGetCbConfig.cbConfig.msgIDs[0].net3gpp.selected = TRUE;
1328 respGetCbConfig.result = SMS_SENDSMS_SUCCESS;
1330 respGetCbConfig.cbConfig.msgIdRangeCount = 0;
1331 respGetCbConfig.cbConfig.msgIDs[0].net3gpp.selected = FALSE;
1332 respGetCbConfig.result = SMS_SENDSMS_SUCCESS;
1337 dbg("line is NULL");
1340 dbg("atresp->lines is NULL");
1343 dbg("RESPONSE NOK");
1346 tcore_user_request_send_response(ur, TRESP_SMS_GET_CB_CONFIG, sizeof(struct tresp_sms_get_cb_config), &respGetCbConfig);
1349 tcore_at_tok_free(tokens);
1354 static void on_response_set_cb_config(TcorePending *pending, int data_len, const void *data, void *user_data)
1357 Response is expected in this format
1364 const TcoreATResponse *resp = data;
1366 const char *line = NULL;
1367 GSList *tokens = NULL;
1369 struct tresp_sms_set_cb_config respSetCbConfig = {0, };
1371 memset(&respSetCbConfig, 0, sizeof(struct tresp_sms_set_cb_config));
1373 ur = tcore_pending_ref_user_request(pending);
1374 respSetCbConfig.result = SMS_SENDSMS_SUCCESS;
1376 if (resp->success > 0) {
1379 dbg("RESPONSE NOK");
1380 line = (const char *) resp->final_response;
1381 tokens = tcore_at_tok_new(line);
1383 if (g_slist_length(tokens) < 1) {
1384 dbg("err cause not specified or string corrupted");
1385 respSetCbConfig.result = SMS_DEVICE_FAILURE;
1387 response = atoi(g_slist_nth_data(tokens, 0));
1388 /* TODO: CMEE error mapping is required. */
1389 respSetCbConfig.result = SMS_DEVICE_FAILURE;
1393 dbg("no user_request");
1397 tcore_user_request_send_response(ur, TRESP_SMS_SET_CB_CONFIG, sizeof(struct tresp_sms_set_cb_config), &respSetCbConfig);
1400 tcore_at_tok_free(tokens);
1405 static void on_response_set_mem_status(TcorePending *p, int data_len, const void *data, void *user_data)
1408 struct tresp_sms_set_mem_status respSetMemStatus = {0, };
1409 const TcoreATResponse *resp = data;
1411 memset(&respSetMemStatus, 0, sizeof(struct tresp_sms_set_mem_status));
1413 if (resp->success > 0) {
1415 respSetMemStatus.result = SMS_SENDSMS_SUCCESS;
1417 dbg("RESPONSE NOK");
1418 respSetMemStatus.result = SMS_DEVICE_FAILURE;
1421 ur = tcore_pending_ref_user_request(p);
1423 dbg("no user_request");
1427 tcore_user_request_send_response(ur, TRESP_SMS_SET_MEM_STATUS, sizeof(struct tresp_sms_set_mem_status), &respSetMemStatus);
1432 static void on_response_set_msg_status(TcorePending *pending, int data_len, const void *data, void *user_data)
1435 struct tresp_sms_set_msg_status respMsgStatus = {0, };
1436 const TcoreATResponse *atResp = data;
1437 int response = 0, sw1 = 0, sw2 = 0;
1438 const char *line = NULL;
1440 GSList *tokens = NULL;
1444 memset(&respMsgStatus, 0, sizeof(struct tresp_sms_set_msg_status));
1445 respMsgStatus.result = SMS_DEVICE_FAILURE;
1447 ur = tcore_pending_ref_user_request(pending);
1449 if (atResp->success > 0) {
1452 if (atResp->lines) {
1453 line = (const char *) atResp->lines->data;
1454 tokens = tcore_at_tok_new(line);
1455 pResp = g_slist_nth_data(tokens, 0);
1456 if (pResp != NULL) {
1461 pResp = g_slist_nth_data(tokens, 1);
1462 if (pResp != NULL) {
1464 if ((sw1 == AT_SW1_SUCCESS) && (sw2 == 0)) {
1465 respMsgStatus.result = SMS_SENDSMS_SUCCESS;
1470 pResp = g_slist_nth_data(tokens, 3);
1472 if (pResp != NULL) {
1473 response = atoi(pResp);
1474 dbg("response is %s", response);
1480 dbg("RESPONSE NOK");
1483 tcore_user_request_send_response(ur, TRESP_SMS_SET_MSG_STATUS, sizeof(struct tresp_sms_set_msg_status), &respMsgStatus);
1486 tcore_at_tok_free(tokens);
1492 static void on_response_get_sms_params(TcorePending *pending, int data_len, const void *data, void *user_data)
1495 struct tresp_sms_get_params respGetParams;
1496 const TcoreATResponse *atResp = data;
1497 int sw1 = 0, sw2 = 0;
1498 const char *line = NULL;
1500 GSList *tokens = NULL;
1501 char *hexData = NULL;
1502 char *recordData = NULL;
1505 memset(&respGetParams, 0, sizeof(struct tresp_sms_get_params));
1506 respGetParams.result = SMS_DEVICE_FAILURE;
1508 ur = tcore_pending_ref_user_request(pending);
1510 if (atResp->success > 0) {
1513 if (atResp->lines) {
1514 line = (const char *) atResp->lines->data;
1515 tokens = tcore_at_tok_new(line);
1516 pResp = g_slist_nth_data(tokens, 0);
1517 if (pResp != NULL) {
1519 dbg("sw1 is %d", sw1);
1523 pResp = g_slist_nth_data(tokens, 1);
1524 if (pResp != NULL) {
1526 dbg("sw2 is %d", sw2);
1527 if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
1528 respGetParams.result = SMS_SENDSMS_SUCCESS;
1533 pResp = g_slist_nth_data(tokens, 2);
1534 if (pResp != NULL) {
1535 hexData = util_removeQuotes(pResp);
1537 recordData = util_hexStringToBytes(hexData);
1538 util_hex_dump(" ", strlen(hexData) / 2, recordData);
1540 respGetParams.paramsInfo.recordLen = strlen(hexData) / 2;
1542 util_sms_decode_smsParameters((unsigned char *) recordData, strlen(hexData) / 2, &(respGetParams.paramsInfo));
1543 respGetParams.result = SMS_SENDSMS_SUCCESS;
1545 for (i = 0; i < (int) respGetParams.paramsInfo.tpSvcCntrAddr.dialNumLen; i++)
1546 dbg("SCAddr = %d [%02x]", i, respGetParams.paramsInfo.tpSvcCntrAddr.diallingNum[i]);
1553 tcore_at_tok_free(tokens);
1556 dbg("RESPONSE NOK");
1559 tcore_user_request_send_response(ur, TRESP_SMS_GET_PARAMS, sizeof(struct tresp_sms_get_params), &respGetParams);
1565 static void on_response_set_sms_params(TcorePending *pending, int data_len, const void *data, void *user_data)
1568 struct tresp_sms_set_params respSetParams = {0, };
1569 const TcoreATResponse *atResp = data;
1570 int sw1 = 0, sw2 = 0;
1571 const char *line = NULL;
1573 GSList *tokens = NULL;
1576 memset(&respSetParams, 0, sizeof(struct tresp_sms_set_params));
1577 ur = tcore_pending_ref_user_request(pending);
1579 respSetParams.result = SMS_DEVICE_FAILURE;
1581 if (atResp->success > 0) {
1584 if (atResp->lines) {
1585 line = (const char *) atResp->lines->data;
1586 tokens = tcore_at_tok_new(line);
1587 pResp = g_slist_nth_data(tokens, 0);
1588 if (pResp != NULL) {
1594 pResp = g_slist_nth_data(tokens, 1);
1595 if (pResp != NULL) {
1597 if (((sw1 == AT_SW1_SUCCESS) && (sw2 == AT_SW2_SUCCESS)) || (sw1 == 0x91)) {
1598 respSetParams.result = SMS_SENDSMS_SUCCESS;
1607 dbg("RESPONSE NOK");
1610 tcore_user_request_send_response(ur, TRESP_SMS_SET_PARAMS, sizeof(struct tresp_sms_set_params), &respSetParams);
1613 tcore_at_tok_free(tokens);
1619 static void on_response_get_paramcnt(TcorePending *p, int data_len, const void *data, void *user_data)
1621 UserRequest *ur = NULL;
1622 struct tresp_sms_get_paramcnt respGetParamCnt = {0, };
1623 const TcoreATResponse *atResp = data;
1624 char *line = NULL, *pResp = NULL;
1625 int sw1 = 0, sw2 = 0, *smsp_record_len = NULL;
1627 GSList *tokens = NULL;
1628 CoreObject *co_sim = NULL; // need this to get the sim type GSM/USIM
1629 TcorePlugin *plugin = NULL;
1633 ur = tcore_pending_ref_user_request(p);
1634 respGetParamCnt.result = SMS_DEVICE_FAILURE;
1636 if (atResp->success > 0) {
1639 if (atResp->lines) {
1640 line = (char *) atResp->lines->data;
1642 dbg("line is %s", line);
1644 tokens = tcore_at_tok_new(line);
1645 pResp = g_slist_nth_data(tokens, 0);
1646 if (pResp != NULL) {
1651 pResp = g_slist_nth_data(tokens, 1);
1652 if (pResp != NULL) {
1654 if ((sw1 == 144) && (sw2 == 0)) {
1655 respGetParamCnt.result = SMS_SENDSMS_SUCCESS;
1660 pResp = g_slist_nth_data(tokens, 2);
1661 if (pResp != NULL) {
1662 char *hexData = NULL;
1663 char *recordData = NULL;
1664 hexData = util_removeQuotes(pResp);
1666 /*1. SIM access success case*/
1667 if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
1668 unsigned char tag_len = 0; /* 1 or 2 bytes ??? */
1670 char num_of_records = 0;
1671 unsigned char file_id_len = 0;
1672 unsigned short file_id = 0;
1673 unsigned short file_size = 0;
1674 unsigned short file_type = 0;
1675 unsigned short arr_file_id = 0;
1676 int arr_file_id_rec_num = 0;
1678 /* handling only last 3 bits */
1679 unsigned char file_type_tag = 0x07;
1680 unsigned char *ptr_data;
1682 recordData = util_hexStringToBytes(hexData);
1683 util_hex_dump(" ", strlen(hexData) / 2, recordData);
1685 ptr_data = (unsigned char *) recordData;
1687 co_sim = tcore_plugin_ref_core_object(tcore_pending_ref_plugin(p), "sim");
1688 sim_type = tcore_sim_get_type(co_sim);
1689 dbg("sim type is %d", sim_type);
1691 if (sim_type == SIM_TYPE_USIM) {
1693 ETSI TS 102 221 v7.9.0
1695 '62' FCP template tag
1696 - Response for an EF
1697 '82' M File Descriptor
1698 '83' M File Identifier
1699 'A5' O Proprietary information
1700 '8A' M Life Cycle Status Integer
1701 '8B', '8C' or 'AB' C1 Security attributes
1703 '81' O Total file size
1704 '88' O Short File Identifier (SFI)
1707 /* rsim.res_len has complete data length received */
1709 /* FCP template tag - File Control Parameters tag*/
1710 if (*ptr_data == 0x62) {
1711 /* parse complete FCP tag*/
1712 /* increment to next byte */
1714 tag_len = *ptr_data++;
1715 /* FCP file descriptor - file type, accessibility, DF, ADF etc*/
1716 if (*ptr_data == 0x82) {
1717 /* increment to next byte */
1721 /* unsigned char file_desc_len = *ptr_data++;*/
1722 /* dbg("file descriptor length: [%d]", file_desc_len);*/
1723 /* TBD: currently capture only file type : ignore sharable, non sharable, working, internal etc*/
1724 /* consider only last 3 bits*/
1725 file_type_tag = file_type_tag & (*ptr_data);
1727 switch (file_type_tag) {
1728 /* increment to next byte */
1732 dbg("Getting FileType: [Transparent file type]");
1733 /* increment to next byte */
1735 file_type = 0x01; // SIM_FTYPE_TRANSPARENT
1736 /* data coding byte - value 21 */
1741 dbg("Getting FileType: [Linear fixed file type]");
1742 /* increment to next byte */
1744 /* data coding byte - value 21 */
1747 memcpy(&record_len, ptr_data, 2);
1749 record_len = SMS_SWAPBYTES16(record_len);
1750 ptr_data = ptr_data + 2;
1751 num_of_records = *ptr_data++;
1752 /* Data lossy conversation from enum (int) to unsigned char */
1753 file_type = 0x02; // SIM_FTYPE_LINEAR_FIXED
1757 dbg(" Cyclic fixed file type");
1758 /* increment to next byte */
1760 /* data coding byte - value 21 */
1763 memcpy(&record_len, ptr_data, 2);
1765 record_len = SMS_SWAPBYTES16(record_len);
1766 ptr_data = ptr_data + 2;
1767 num_of_records = *ptr_data++;
1768 file_type = 0x04; // SIM_FTYPE_CYCLIC
1772 dbg("not handled file type [0x%x]", *ptr_data);
1776 dbg("INVALID FCP received - DEbug!");
1777 tcore_at_tok_free(tokens);
1781 /*File identifier - file id?? */ // 0x84,0x85,0x86 etc are currently ignored and not handled
1782 if (*ptr_data == 0x83) {
1783 /* increment to next byte */
1785 file_id_len = *ptr_data++;
1786 memcpy(&file_id, ptr_data, file_id_len);
1788 file_id = SMS_SWAPBYTES16(file_id);
1789 ptr_data = ptr_data + 2;
1790 dbg("Getting FileID=[0x%x]", file_id);
1792 dbg("INVALID FCP received - DEbug!");
1795 tcore_at_tok_free(tokens);
1799 /* proprietary information */
1800 if (*ptr_data == 0xA5) {
1801 unsigned short prop_len;
1802 /* increment to next byte */
1805 prop_len = *ptr_data;
1807 ptr_data = ptr_data + prop_len + 1;
1809 dbg("INVALID FCP received - DEbug!");
1812 /* life cycle status integer [8A][length:0x01][status]*/
1815 00000000 : No information given
1816 00000001 : creation state
1817 00000011 : initialization state
1818 000001-1 : operation state -activated
1819 000001-0 : operation state -deactivated
1820 000011-- : Termination state
1821 b8~b5 !=0, b4~b1=X : Proprietary
1822 Any other value : RFU
1824 if (*ptr_data == 0x8A) {
1825 /* increment to next byte */
1827 /* length - value 1 */
1830 switch (*ptr_data) {
1833 dbg("<IPC_RX> operation state -deactivated");
1839 dbg("<IPC_RX> operation state -activated");
1844 dbg("<IPC_RX> DEBUG! LIFE CYCLE STATUS =[0x%x]", *ptr_data);
1850 /* related to security attributes : currently not handled*/
1851 if (*ptr_data == 0x86 || *ptr_data == 0x8B || *ptr_data == 0x8C || *ptr_data == 0xAB) {
1852 /* increment to next byte */
1854 /* if tag length is 3 */
1855 if (*ptr_data == 0x03) {
1856 /* increment to next byte */
1859 memcpy(&arr_file_id, ptr_data, 2);
1861 arr_file_id = SMS_SWAPBYTES16(arr_file_id);
1862 ptr_data = ptr_data + 2;
1863 arr_file_id_rec_num = *ptr_data++;
1865 /* if tag length is not 3 */
1866 /* ignoring bytes */
1867 // ptr_data = ptr_data + 4;
1868 dbg("Useless security attributes, so jump to next tag");
1869 ptr_data = ptr_data + (*ptr_data + 1);
1872 dbg("INVALID FCP received[0x%x] - DEbug!", *ptr_data);
1875 tcore_at_tok_free(tokens);
1879 dbg("Current ptr_data value is [%x]", *ptr_data);
1881 /* file size excluding structural info*/
1882 if (*ptr_data == 0x80) {
1883 /* for EF file size is body of file and for Linear or cyclic it is
1884 * number of recXsizeof(one record)
1886 /* increment to next byte */
1888 /* length is 1 byte - value is 2 bytes or more */
1890 memcpy(&file_size, ptr_data, 2);
1892 file_size = SMS_SWAPBYTES16(file_size);
1893 ptr_data = ptr_data + 2;
1895 dbg("INVALID FCP received - DEbug!");
1898 tcore_at_tok_free(tokens);
1902 /* total file size including structural info*/
1903 if (*ptr_data == 0x81) {
1905 /* increment to next byte */
1910 ptr_data = ptr_data + 3;
1912 dbg("INVALID FCP received - DEbug!");
1913 /* 0x81 is optional tag?? check out! so do not return -1 from here! */
1916 /*short file identifier ignored*/
1917 if (*ptr_data == 0x88) {
1918 dbg("0x88: Do Nothing");
1922 dbg("INVALID FCP received - DEbug!");
1925 tcore_at_tok_free(tokens);
1928 } else if (sim_type == SIM_TYPE_GSM) {
1929 unsigned char gsm_specific_file_data_len = 0;
1930 /* ignore RFU byte1 and byte2 */
1934 // file_size = p_info->response_len;
1935 memcpy(&file_size, ptr_data, 2);
1937 file_size = SMS_SWAPBYTES16(file_size);
1938 /* parsed file size */
1939 ptr_data = ptr_data + 2;
1941 memcpy(&file_id, ptr_data, 2);
1942 file_id = SMS_SWAPBYTES16(file_id);
1943 dbg(" FILE id --> [%x]", file_id);
1944 ptr_data = ptr_data + 2;
1945 /* save file type - transparent, linear fixed or cyclic */
1946 file_type_tag = (*(ptr_data + 7));
1948 switch (*ptr_data) {
1951 dbg(" RFU file type- not handled - Debug!");
1956 dbg(" MF file type - not handled - Debug!");
1961 dbg(" DF file type - not handled - Debug!");
1966 dbg(" EF file type [%d] ", file_type_tag);
1967 /* increment to next byte */
1970 if (file_type_tag == 0x00 || file_type_tag == 0x01) {
1971 /* increament to next byte as this byte is RFU */
1974 (file_type_tag == 0x00) ? 0x01 : 0x02; // SIM_FTYPE_TRANSPARENT:SIM_FTYPE_LINEAR_FIXED;
1976 /* increment to next byte */
1978 /* For a cyclic EF all bits except bit 7 are RFU; b7=1 indicates that */
1979 /* the INCREASE command is allowed on the selected cyclic file. */
1980 file_type = 0x04; // SIM_FTYPE_CYCLIC;
1982 /* bytes 9 to 11 give SIM file access conditions */
1984 /* byte 10 has one nibble that is RF U and another for INCREASE which is not used currently */
1986 /* byte 11 is invalidate and rehabilate nibbles */
1988 /* byte 12 - file status */
1990 /* byte 13 - GSM specific data */
1991 gsm_specific_file_data_len = *ptr_data;
1993 /* byte 14 - structure of EF - transparent or linear or cyclic , already saved above */
1995 /* byte 15 - length of record for linear and cyclic , for transparent it is set to 0x00. */
1996 record_len = *ptr_data;
1997 dbg("record length[%d], file size[%d]", record_len, file_size);
1999 if (record_len != 0)
2000 num_of_records = (file_size / record_len);
2002 dbg("Number of records [%d]", num_of_records);
2006 dbg(" not handled file type");
2010 dbg(" Card Type - UNKNOWN [%d]", sim_type);
2013 dbg("EF[0x%x] size[%ld] Type[0x%x] NumOfRecords[%ld] RecordLen[%ld]", file_id, file_size, file_type, num_of_records, record_len);
2015 respGetParamCnt.recordCount = num_of_records;
2016 respGetParamCnt.result = SMS_SUCCESS;
2018 // TO Store smsp record length in the property
2019 plugin = tcore_pending_ref_plugin(p);
2020 smsp_record_len = tcore_plugin_ref_property(plugin, "SMSPRECORDLEN");
2021 memcpy(smsp_record_len, &record_len, sizeof(int));
2026 /*2. SIM access fail case*/
2027 dbg("SIM access fail");
2028 respGetParamCnt.result = SMS_UNKNOWN;
2031 dbg("presp is NULL");
2034 dbg("line is blank");
2037 dbg("RESPONSE NOK");
2040 tcore_user_request_send_response(ur, TRESP_SMS_GET_PARAMCNT, sizeof(struct tresp_sms_get_paramcnt), &respGetParamCnt);
2043 tcore_at_tok_free(tokens);
2049 static void _response_get_efsms_data(TcorePending *p, int data_len, const void *data, void *user_data)
2051 UserRequest *ur = NULL;
2052 UserRequest *dup_ur = NULL;
2053 struct tresp_sms_set_msg_status resp_msg_status = {0, };
2054 const struct treq_sms_set_msg_status *req_msg_status = NULL;
2056 const TcoreATResponse *resp = data;
2057 char *encoded_data = NULL;
2058 char msg_status = 0;
2060 GSList *tokens = NULL;
2061 const char *line = NULL;
2065 TcoreHal *hal = NULL;
2066 TcoreATRequest *atreq = NULL;
2067 TcorePending *pending = NULL;
2068 gchar *cmd_str = NULL;
2070 ur = tcore_pending_ref_user_request(p);
2072 req_msg_status = tcore_user_request_ref_data(ur, NULL);
2074 resp_msg_status.result = SMS_DEVICE_FAILURE;
2076 hal = tcore_object_get_hal(tcore_pending_ref_core_object(pending));
2077 dbg("msgStatus: [%x], index [%x]", req_msg_status->msgStatus, req_msg_status->index);
2079 if (resp->success <= 0) {
2086 line = (const char *) resp->lines->data;
2087 tokens = tcore_at_tok_new(line);
2088 if (g_slist_length(tokens) != 3) {
2089 msg("invalid message");
2093 sw1 = atoi(g_slist_nth_data(tokens, 0));
2094 sw2 = atoi(g_slist_nth_data(tokens, 1));
2095 pResp = g_slist_nth_data(tokens, 2);
2097 if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
2098 switch (req_msg_status->msgStatus) {
2099 case SMS_STATUS_READ:
2103 case SMS_STATUS_UNREAD:
2107 case SMS_STATUS_UNSENT:
2111 case SMS_STATUS_SENT:
2115 case SMS_STATUS_DELIVERED:
2119 case SMS_STATUS_DELIVERY_UNCONFIRMED:
2123 case SMS_STATUS_MESSAGE_REPLACED:
2124 case SMS_STATUS_RESERVED:
2130 encoded_data = util_removeQuotes(pResp);
2132 // overwrite Status byte information
2133 util_byte_to_hex((const char *) &msg_status, (char *) encoded_data, 1);
2135 // Update EF-SMS with just status byte overwritten, rest 175 bytes are same as received in read information
2136 cmd_str = g_strdup_printf("AT+CRSM=220,28476,%d, 4, %d, \"%s\"", (req_msg_status->index + 1), AT_EF_SMS_RECORD_LEN, encoded_data);
2137 atreq = tcore_at_request_new((const char *) cmd_str, "+CRSM", TCORE_AT_SINGLELINE);
2138 pending = tcore_pending_new(tcore_pending_ref_core_object(pending), 0);
2139 if (NULL == cmd_str || NULL == atreq || NULL == pending) {
2140 err("Out of memory. Unable to proceed");
2141 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
2143 // free memory we own
2146 util_sms_free_memory(atreq);
2147 util_sms_free_memory(pending);
2152 util_hex_dump(" ", strlen(cmd_str), (void *) cmd_str);
2154 dup_ur = tcore_user_request_ref(ur);
2156 tcore_pending_set_request_data(pending, 0, atreq);
2157 tcore_pending_set_response_callback(pending, on_response_set_msg_status, NULL);
2158 tcore_pending_link_user_request(pending, dup_ur);
2159 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
2160 tcore_hal_send_request(hal, pending);
2169 tcore_at_tok_free(tokens);
2171 tcore_user_request_send_response(ur, TRESP_SMS_SET_MSG_STATUS, sizeof(struct tresp_sms_set_msg_status), &msg_status);
2178 /*=============================================================
2180 ==============================================================*/
2181 static TReturn send_umts_msg(CoreObject *obj, UserRequest *ur)
2183 gchar *cmd_str = NULL;
2184 TcoreHal *hal = NULL;
2185 TcoreATRequest *atreq = NULL;
2186 TcorePending *pending = NULL;
2187 const struct treq_sms_send_umts_msg *sendUmtsMsg = NULL;
2188 char buf[2 * (SMS_SMSP_ADDRESS_LEN + SMS_SMDATA_SIZE_MAX) + 1] = {0};
2194 sendUmtsMsg = tcore_user_request_ref_data(ur, NULL);
2195 hal = tcore_object_get_hal(obj);
2196 if (NULL == sendUmtsMsg || NULL == hal) {
2197 err("NULL input. Unable to proceed");
2198 dbg("sendUmtsMsg: [%p], hal: [%p]", sendUmtsMsg, hal);
2201 return TCORE_RETURN_EINVAL;
2204 dbg("msgLength: [%d]", sendUmtsMsg->msgDataPackage.msgLength);
2205 util_hex_dump(" ", (SMS_SMDATA_SIZE_MAX + 1), (void *) sendUmtsMsg->msgDataPackage.tpduData);
2206 util_hex_dump(" ", SMS_SMSP_ADDRESS_LEN, (void *) sendUmtsMsg->msgDataPackage.sca);
2208 ScLength = (int) sendUmtsMsg->msgDataPackage.sca[0];
2210 dbg("ScLength: [%d]", ScLength);
2212 if ((sendUmtsMsg->msgDataPackage.msgLength > 0)
2213 && (sendUmtsMsg->msgDataPackage.msgLength <= SMS_SMDATA_SIZE_MAX)
2214 && (ScLength <= SMS_MAX_SMS_SERVICE_CENTER_ADDR)) {
2215 if (ScLength == 0) { // ScAddress not specified
2220 dbg("Specifying SCA in TPDU is currently not supported");
2227 util_byte_to_hex((const char *) sendUmtsMsg->msgDataPackage.tpduData, (char *) &buf[pdu_len], sendUmtsMsg->msgDataPackage.msgLength);
2229 pdu_len = pdu_len + 2 * sendUmtsMsg->msgDataPackage.msgLength;
2231 buf[pdu_len] = '\0'; // Ensure termination
2233 dbg("pdu_len: [%d]", pdu_len);
2234 util_hex_dump(" ", sizeof(buf), (void *) buf);
2236 // AT+CMGS=<length><CR>PDU is given<ctrl-Z/ESC>
2237 cmd_str = g_strdup_printf("AT+CMGS=%d%s%s\x1A", sendUmtsMsg->msgDataPackage.msgLength, "\r", buf);
2238 atreq = tcore_at_request_new((const char *) cmd_str, "+CMGS", TCORE_AT_SINGLELINE);
2239 pending = tcore_pending_new(obj, 0);
2241 if (NULL == cmd_str || NULL == atreq || NULL == pending) {
2242 err("Out of memory. Unable to proceed");
2243 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
2245 // free memory we own
2247 util_sms_free_memory(atreq);
2248 util_sms_free_memory(pending);
2251 return TCORE_RETURN_ENOMEM;
2254 util_hex_dump(" ", strlen(cmd_str), (void *) cmd_str);
2256 tcore_pending_set_request_data(pending, 0, atreq);
2257 tcore_pending_set_response_callback(pending, on_response_send_umts_msg, NULL);
2258 tcore_pending_link_user_request(pending, ur);
2259 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
2260 tcore_hal_send_request(hal, pending);
2265 return TCORE_RETURN_SUCCESS;
2268 err("Invalid Data len");
2270 return TCORE_RETURN_SMS_INVALID_DATA_LEN;
2273 static TReturn read_msg(CoreObject *obj, UserRequest *ur)
2275 gchar *cmd_str = NULL;
2276 TcoreHal *hal = NULL;
2277 TcoreATRequest *atreq = NULL;
2278 TcorePending *pending = NULL;
2279 const struct treq_sms_read_msg *readMsg = NULL;
2283 readMsg = tcore_user_request_ref_data(ur, NULL);
2284 hal = tcore_object_get_hal(obj);
2285 if (NULL == readMsg || NULL == hal) {
2286 err("NULL input. Unable to proceed");
2287 dbg("readMsg: [%p], hal: [%p]", readMsg, hal);
2290 return TCORE_RETURN_EINVAL;
2293 dbg("index: [%d]", readMsg->index);
2295 cmd_str = g_strdup_printf("AT+CMGR=%d", (readMsg->index + 1)); // IMC index is one ahead of TAPI
2296 atreq = tcore_at_request_new((const char *) cmd_str, "+CMGR", TCORE_AT_PDU);
2297 pending = tcore_pending_new(obj, 0);
2299 if (NULL == cmd_str || NULL == atreq || NULL == pending) {
2300 err("Out of memory. Unable to proceed");
2301 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
2303 // free memory we own
2305 util_sms_free_memory(atreq);
2306 util_sms_free_memory(pending);
2309 return TCORE_RETURN_ENOMEM;
2312 util_hex_dump(" ", strlen(cmd_str), (void *) cmd_str);
2314 tcore_pending_set_request_data(pending, 0, atreq);
2315 tcore_pending_set_response_callback(pending, on_response_read_msg, (void *) (uintptr_t) (readMsg->index)); // storing index as user data for response
2316 tcore_pending_link_user_request(pending, ur);
2317 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
2318 tcore_hal_send_request(hal, pending);
2323 return TCORE_RETURN_SUCCESS;
2326 static TReturn save_msg(CoreObject *obj, UserRequest *ur)
2328 gchar *cmd_str = NULL;
2329 TcoreHal *hal = NULL;
2330 TcoreATRequest *atreq = NULL;
2331 TcorePending *pending = NULL;
2332 const struct treq_sms_save_msg *saveMsg = NULL;
2333 int ScLength = 0, pdu_len = 0, stat = 0;
2334 char buf[2 * (SMS_SMSP_ADDRESS_LEN + SMS_SMDATA_SIZE_MAX) + 1] = {0};
2335 char *hex_pdu = NULL;
2339 saveMsg = tcore_user_request_ref_data(ur, NULL);
2340 hal = tcore_object_get_hal(obj);
2341 if (NULL == saveMsg || NULL == hal) {
2342 err("NULL input. Unable to proceed");
2343 dbg("saveMsg: [%p], hal: [%p]", saveMsg, hal);
2346 return TCORE_RETURN_EINVAL;
2349 dbg("msgStatus: %x, msgLength: [%d]", saveMsg->msgStatus, saveMsg->msgDataPackage.msgLength);
2350 util_hex_dump(" ", (SMS_SMDATA_SIZE_MAX + 1), (void *) saveMsg->msgDataPackage.tpduData);
2351 util_hex_dump(" ", SMS_SMSP_ADDRESS_LEN, (void *) saveMsg->msgDataPackage.sca);
2353 switch (saveMsg->msgStatus) {
2354 case SMS_STATUS_READ:
2358 case SMS_STATUS_UNREAD:
2359 stat = AT_REC_UNREAD;
2362 case SMS_STATUS_SENT:
2366 case SMS_STATUS_UNSENT:
2367 stat = AT_STO_UNSENT;
2371 err("Invalid msgStatus");
2373 return TCORE_RETURN_EINVAL;
2376 if ((saveMsg->msgDataPackage.msgLength > 0)
2377 && (saveMsg->msgDataPackage.msgLength <= SMS_SMDATA_SIZE_MAX)) {
2378 ScLength = (int) saveMsg->msgDataPackage.sca[0];
2381 dbg("ScLength = %d", ScLength);
2383 if (ScLength == 0) {
2386 memcpy(&buf[1], saveMsg->msgDataPackage.sca, ScLength);
2389 memcpy(&buf[ScLength + 1], saveMsg->msgDataPackage.tpduData, saveMsg->msgDataPackage.msgLength);
2391 pdu_len = saveMsg->msgDataPackage.msgLength + ScLength + 1;
2392 dbg("pdu_len: [%d]", pdu_len);
2394 hex_pdu = malloc(pdu_len * 2 + 1);
2395 util_hex_dump(" ", sizeof(buf), (void *) buf);
2397 memset(hex_pdu, 0x00, pdu_len * 2 + 1);
2399 util_byte_to_hex((const char *) buf, (char *) hex_pdu, pdu_len);
2401 // AT+CMGW=<length>[,<stat>]<CR>PDU is given<ctrl-Z/ESC>
2402 cmd_str = g_strdup_printf("AT+CMGW=%d,%d%s%s\x1A", saveMsg->msgDataPackage.msgLength, stat, "\r", hex_pdu);
2403 pending = tcore_pending_new(obj, 0);
2404 atreq = tcore_at_request_new((const char *) cmd_str, "+CMGW", TCORE_AT_SINGLELINE);
2406 if (NULL == cmd_str || NULL == atreq || NULL == pending) {
2407 err("Out of memory. Unable to proceed");
2408 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
2410 // free memory we own
2412 util_sms_free_memory(atreq);
2413 util_sms_free_memory(pending);
2414 util_sms_free_memory(hex_pdu);
2417 return TCORE_RETURN_ENOMEM;
2420 util_hex_dump(" ", strlen(cmd_str), (void *) cmd_str);
2422 tcore_pending_set_request_data(pending, 0, atreq);
2423 tcore_pending_set_response_callback(pending, on_response_sms_save_msg, NULL);
2424 tcore_pending_link_user_request(pending, ur);
2425 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
2426 tcore_hal_send_request(hal, pending);
2432 return TCORE_RETURN_SUCCESS;
2435 err("Invalid Data len");
2437 return TCORE_RETURN_SMS_INVALID_DATA_LEN;
2440 static TReturn delete_msg(CoreObject *obj, UserRequest *ur)
2442 gchar *cmd_str = NULL;
2443 TcoreHal *hal = NULL;
2444 TcoreATRequest *atreq = NULL;
2445 TcorePending *pending = NULL;
2446 const struct treq_sms_delete_msg *delete_msg = NULL;
2450 delete_msg = tcore_user_request_ref_data(ur, NULL);
2451 hal = tcore_object_get_hal(obj);
2452 if (NULL == delete_msg || NULL == hal) {
2453 err("NULL input. Unable to proceed");
2454 dbg("deleteMsg: [%p], hal: [%p]", delete_msg, hal);
2457 return TCORE_RETURN_EINVAL;
2460 dbg("index: %d", delete_msg->index);
2462 if (delete_msg->index == -1) {
2463 cmd_str = g_strdup_printf("AT+CMGD=0,4"); // Delete All Messages
2465 cmd_str = g_strdup_printf("AT+CMGD=%d,0", delete_msg->index + 1); // Delete specified index
2468 pending = tcore_pending_new(obj, 0);
2469 atreq = tcore_at_request_new((const char *) cmd_str, NULL, TCORE_AT_NO_RESULT);
2470 if (NULL == cmd_str || NULL == atreq || NULL == pending) {
2471 err("Out of memory. Unable to proceed");
2472 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
2474 // free memory we own
2476 util_sms_free_memory(atreq);
2477 util_sms_free_memory(pending);
2480 return TCORE_RETURN_ENOMEM;
2483 util_hex_dump(" ", strlen(cmd_str), (void *) cmd_str);
2485 tcore_pending_set_request_data(pending, 0, atreq);
2486 tcore_pending_set_response_callback(pending, on_response_sms_delete_msg, (void *) (uintptr_t) (delete_msg->index)); // storing index as user data for response
2487 tcore_pending_link_user_request(pending, ur);
2488 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
2489 tcore_hal_send_request(hal, pending);
2494 return TCORE_RETURN_SUCCESS;
2497 static TReturn get_storedMsgCnt(CoreObject *obj, UserRequest *ur)
2499 gchar *cmd_str = NULL;
2500 TcoreHal *hal = NULL;
2501 TcoreATRequest *atreq = NULL;
2502 TcorePending *pending = NULL;
2506 hal = tcore_object_get_hal(obj);
2508 err("NULL HAL. Unable to proceed");
2511 return TCORE_RETURN_EINVAL;
2514 cmd_str = g_strdup_printf("AT+CPMS=\"SM\"");
2515 pending = tcore_pending_new(obj, 0);
2516 atreq = tcore_at_request_new((const char *) cmd_str, "+CPMS", TCORE_AT_SINGLELINE);
2518 if (NULL == cmd_str || NULL == atreq || NULL == pending) {
2519 err("Out of memory. Unable to proceed");
2520 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
2522 // free memory we own
2524 util_sms_free_memory(atreq);
2525 util_sms_free_memory(pending);
2528 return TCORE_RETURN_ENOMEM;
2531 util_hex_dump(" ", strlen(cmd_str), (void *) cmd_str);
2533 tcore_pending_set_request_data(pending, 0, atreq);
2534 tcore_pending_set_response_callback(pending, on_response_get_stored_msg_cnt, NULL);
2535 tcore_pending_link_user_request(pending, ur);
2536 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
2537 tcore_hal_send_request(hal, pending);
2542 return TCORE_RETURN_SUCCESS;
2545 static TReturn get_sca(CoreObject *obj, UserRequest *ur)
2547 gchar *cmd_str = NULL;
2548 TcoreHal *hal = NULL;
2549 TcoreATRequest *atreq = NULL;
2550 TcorePending *pending = NULL;
2554 hal = tcore_object_get_hal(obj);
2556 err("HAL NULL. Unable to proceed");
2559 return TCORE_RETURN_EINVAL;
2562 cmd_str = g_strdup_printf("AT+CSCA?");
2563 pending = tcore_pending_new(obj, 0);
2564 atreq = tcore_at_request_new((const char *) cmd_str, "+CSCA", TCORE_AT_SINGLELINE);
2566 if (NULL == cmd_str || NULL == atreq || NULL == pending) {
2567 err("Out of memory. Unable to proceed");
2568 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
2570 // free memory we own
2572 util_sms_free_memory(atreq);
2573 util_sms_free_memory(pending);
2576 return TCORE_RETURN_ENOMEM;
2579 util_hex_dump(" ", strlen(cmd_str), (void *) cmd_str);
2581 tcore_pending_set_request_data(pending, 0, atreq);
2582 tcore_pending_set_response_callback(pending, on_response_get_sca, NULL);
2583 tcore_pending_link_user_request(pending, ur);
2584 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
2585 tcore_hal_send_request(hal, pending);
2590 return TCORE_RETURN_SUCCESS;
2593 static TReturn set_sca(CoreObject *obj, UserRequest *ur)
2595 gchar *cmd_str = NULL;
2596 TcoreHal *hal = NULL;
2597 TcoreATRequest *atreq = NULL;
2598 TcorePending *pending = NULL;
2599 const struct treq_sms_set_sca *setSca = NULL;
2604 setSca = tcore_user_request_ref_data(ur, NULL);
2605 hal = tcore_object_get_hal(obj);
2606 if (NULL == setSca || NULL == hal) {
2607 err("NULL input. Unable to proceed");
2608 dbg("setSca: [%p], hal: [%p]", setSca, hal);
2611 return TCORE_RETURN_EINVAL;
2614 dbg("dialNumLen: %u, typeOfNum: %d, numPlanId: %d, ", setSca->scaInfo.dialNumLen, setSca->scaInfo.typeOfNum, setSca->scaInfo.numPlanId);
2616 util_hex_dump(" ", (SMS_SMSP_ADDRESS_LEN + 1), (void *) setSca->scaInfo.diallingNum);
2618 addrType = ((setSca->scaInfo.typeOfNum << 4) | setSca->scaInfo.numPlanId) | 0x80;
2620 cmd_str = g_strdup_printf("AT+CSCA=\"%s\",%d", setSca->scaInfo.diallingNum, addrType);
2621 pending = tcore_pending_new(obj, 0);
2622 atreq = tcore_at_request_new((const char *) cmd_str, NULL, TCORE_AT_NO_RESULT);
2624 if (NULL == cmd_str || NULL == atreq || NULL == pending) {
2625 err("Out of memory. Unable to proceed");
2626 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
2628 // free memory we own
2630 util_sms_free_memory(atreq);
2631 util_sms_free_memory(pending);
2634 return TCORE_RETURN_ENOMEM;
2637 util_hex_dump(" ", strlen(cmd_str), (void *) cmd_str);
2639 tcore_pending_set_request_data(pending, 0, atreq);
2640 tcore_pending_set_response_callback(pending, on_response_set_sca, NULL);
2641 tcore_pending_link_user_request(pending, ur);
2642 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
2643 tcore_hal_send_request(hal, pending);
2648 return TCORE_RETURN_SUCCESS;
2651 static TReturn get_cb_config(CoreObject *obj, UserRequest *ur)
2653 gchar *cmd_str = NULL;
2654 TcoreHal *hal = NULL;
2655 TcoreATRequest *atreq = NULL;
2656 TcorePending *pending = NULL;
2660 hal = tcore_object_get_hal(obj);
2662 err("NULL HAL. Unable to proceed");
2665 return TCORE_RETURN_EINVAL;
2668 cmd_str = g_strdup_printf("AT+CSCB?");
2669 pending = tcore_pending_new(obj, 0);
2670 atreq = tcore_at_request_new((const char *) cmd_str, "+CSCB", TCORE_AT_SINGLELINE);
2671 if (NULL == cmd_str || NULL == atreq || NULL == pending) {
2672 err("Out of memory. Unable to proceed");
2673 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
2675 // free memory we own
2677 util_sms_free_memory(atreq);
2678 util_sms_free_memory(pending);
2681 return TCORE_RETURN_ENOMEM;
2684 util_hex_dump(" ", strlen(cmd_str), (void *) cmd_str);
2686 tcore_pending_set_request_data(pending, 0, atreq);
2687 tcore_pending_set_response_callback(pending, on_response_get_cb_config, NULL);
2688 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
2689 tcore_pending_link_user_request(pending, ur);
2690 tcore_hal_send_request(hal, pending);
2695 return TCORE_RETURN_SUCCESS;
2698 static TReturn set_cb_config(CoreObject *obj, UserRequest *ur)
2700 gchar *cmd_str = NULL;
2701 gchar *mids_str = NULL;
2702 GString *mids_GString = NULL;
2704 TcoreHal *hal = NULL;
2705 TcoreATRequest *atreq = NULL;
2706 TcorePending *pending = NULL;
2707 const struct treq_sms_set_cb_config *setCbConfig = NULL;
2708 int ctr1 = 0, ctr2 = 0;
2709 unsigned short appendMsgId = 0;
2713 setCbConfig = tcore_user_request_ref_data(ur, NULL);
2714 hal = tcore_object_get_hal(obj);
2715 if (NULL == setCbConfig || NULL == hal) {
2716 err("NULL input. Unable to proceed");
2717 dbg("setCbConfig: [%p], hal: [%p]", setCbConfig, hal);
2720 return TCORE_RETURN_EINVAL;
2723 dbg("bCBEnabled: %d, msgIdMaxCount: %x, msgIdCount: %d", setCbConfig->cbEnabled, setCbConfig->msgIdMaxCount, setCbConfig->msgIdRangeCount);
2724 // util_hex_dump(" ", SMS_GSM_SMS_CBMI_LIST_SIZE_MAX, (void *)setCbConfig->msgIDs);
2726 if (setCbConfig->cbEnabled == 2) { // Enable all CBS
2727 cmd_str = g_strdup_printf("AT+CSCB=1");
2728 } else if (setCbConfig->cbEnabled == 0) { // AT+CSCB=0: Disable CBS
2729 cmd_str = g_strdup_printf("AT+CSCB=0");
2731 mids_GString = g_string_new("AT+CSCB=0,\"");
2733 for (ctr1 = 0; ctr1 < setCbConfig->msgIdRangeCount; ctr1++) {
2734 if (setCbConfig->msgIDs[ctr1].net3gpp.selected == FALSE)
2737 if (SMS_GSM_SMS_CBMI_LIST_SIZE_MAX <= (setCbConfig->msgIDs[ctr1].net3gpp.toMsgId - setCbConfig->msgIDs[ctr1].net3gpp.fromMsgId)) {
2738 mids_GString = g_string_new("AT+CSCB=1");
2742 appendMsgId = setCbConfig->msgIDs[ctr1].net3gpp.fromMsgId;
2744 for (ctr2 = 0; (ctr2 <= ((setCbConfig->msgIDs[ctr1].net3gpp.toMsgId) - (setCbConfig->msgIDs[ctr1].net3gpp.fromMsgId))); ctr2++) {
2745 dbg("%x", appendMsgId);
2746 mids_GString = g_string_append(mids_GString, g_strdup_printf("%d", appendMsgId));
2748 if (ctr2 == ((setCbConfig->msgIDs[ctr1].net3gpp.toMsgId) - (setCbConfig->msgIDs[ctr1].net3gpp.fromMsgId))) {
2749 mids_GString = g_string_append(mids_GString, "\""); // Mids string termination
2751 mids_GString = g_string_append(mids_GString, ",");
2757 mids_str = g_string_free(mids_GString, FALSE);
2758 cmd_str = g_strdup_printf("%s", mids_str);
2762 pending = tcore_pending_new(obj, 0);
2763 atreq = tcore_at_request_new((const char *) cmd_str, NULL, TCORE_AT_NO_RESULT);
2764 if (NULL == cmd_str || NULL == atreq || NULL == pending) {
2765 err("Out of memory. Unable to proceed");
2766 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
2768 // free memory we own
2770 util_sms_free_memory(atreq);
2771 util_sms_free_memory(pending);
2774 return TCORE_RETURN_ENOMEM;
2777 util_hex_dump(" ", strlen(cmd_str), (void *) cmd_str);
2779 tcore_pending_set_request_data(pending, 0, atreq);
2780 tcore_pending_set_response_callback(pending, on_response_set_cb_config, NULL);
2781 tcore_pending_link_user_request(pending, ur);
2782 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
2783 tcore_hal_send_request(hal, pending);
2788 return TCORE_RETURN_SUCCESS;
2791 static TReturn set_mem_status(CoreObject *obj, UserRequest *ur)
2793 gchar *cmd_str = NULL;
2794 TcoreHal *hal = NULL;
2795 TcoreATRequest *atreq = NULL;
2796 TcorePending *pending = NULL;
2797 const struct treq_sms_set_mem_status *setMemStatus = NULL;
2798 int memoryStatus = 0;
2802 setMemStatus = tcore_user_request_ref_data(ur, NULL);
2803 hal = tcore_object_get_hal(obj);
2804 if (NULL == setMemStatus || NULL == hal) {
2805 err("NULL input. Unable to proceed");
2806 dbg("setMemStatus: [%p], hal: [%p]", setMemStatus, hal);
2809 return TCORE_RETURN_EINVAL;
2812 dbg("memory_status: %d", setMemStatus->memory_status);
2814 if (setMemStatus->memory_status < SMS_PDA_MEMORY_STATUS_AVAILABLE
2815 || setMemStatus->memory_status > SMS_PDA_MEMORY_STATUS_FULL) {
2816 err("Invalid memory_status");
2819 return TCORE_RETURN_EINVAL;
2822 switch (setMemStatus->memory_status) {
2823 case SMS_PDA_MEMORY_STATUS_AVAILABLE:
2824 memoryStatus = AT_MEMORY_AVAILABLE;
2827 case SMS_PDA_MEMORY_STATUS_FULL:
2828 memoryStatus = AT_MEMORY_FULL;
2832 err("Invalid memory_status");
2834 return TCORE_RETURN_EINVAL;
2837 cmd_str = g_strdup_printf("AT+XTESM=%d", memoryStatus);
2838 pending = tcore_pending_new(obj, 0);
2839 atreq = tcore_at_request_new((const char *) cmd_str, NULL, TCORE_AT_NO_RESULT);
2841 if (NULL == cmd_str || NULL == atreq || NULL == pending) {
2842 err("Out of memory. Unable to proceed");
2843 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
2845 // free memory we own
2847 util_sms_free_memory(atreq);
2848 util_sms_free_memory(pending);
2851 return TCORE_RETURN_ENOMEM;
2854 util_hex_dump(" ", strlen(cmd_str), (void *) cmd_str);
2856 tcore_pending_set_request_data(pending, 0, atreq);
2857 tcore_pending_set_response_callback(pending, on_response_set_mem_status, NULL);
2858 tcore_pending_link_user_request(pending, ur);
2859 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
2860 tcore_hal_send_request(hal, pending);
2865 return TCORE_RETURN_SUCCESS;
2868 static TReturn set_delivery_report(CoreObject *obj, UserRequest *ur)
2870 struct tresp_sms_set_delivery_report respSetDeliveryReport = {0, };
2872 respSetDeliveryReport.result = SMS_SUCCESS;
2876 dbg("CP takes care of sending SMS ack to network for all classes of SMS. Sending default success.");
2878 tcore_user_request_send_response(ur, TRESP_SMS_SET_DELIVERY_REPORT, sizeof(struct tresp_sms_set_delivery_report), &respSetDeliveryReport);
2881 return TCORE_RETURN_SUCCESS;
2884 static TReturn set_msg_status(CoreObject *obj, UserRequest *ur)
2886 gchar *cmd_str = NULL;
2887 TcoreHal *hal = NULL;
2888 TcoreATRequest *atreq = NULL;
2889 TcorePending *pending = NULL;
2890 const struct treq_sms_set_msg_status *msg_status = NULL;
2894 msg_status = tcore_user_request_ref_data(ur, NULL);
2896 cmd_str = g_strdup_printf("AT+CRSM=178,28476,%d,4,%d", (msg_status->index + 1), AT_EF_SMS_RECORD_LEN);
2897 atreq = tcore_at_request_new((const char *) cmd_str, "+CRSM", TCORE_AT_SINGLELINE);
2898 pending = tcore_pending_new(obj, 0);
2899 if (NULL == cmd_str || NULL == atreq || NULL == pending) {
2900 err("Out of memory. Unable to proceed");
2901 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
2903 // free memory we own
2905 util_sms_free_memory(atreq);
2906 util_sms_free_memory(pending);
2909 return TCORE_RETURN_ENOMEM;
2912 util_hex_dump(" ", strlen(cmd_str), (void *) cmd_str);
2914 tcore_pending_set_request_data(pending, 0, atreq);
2915 tcore_pending_set_response_callback(pending, _response_get_efsms_data, NULL);
2916 tcore_pending_link_user_request(pending, ur);
2917 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
2918 tcore_hal_send_request(hal, pending);
2923 return TCORE_RETURN_SUCCESS;
2926 static TReturn get_sms_params(CoreObject *obj, UserRequest *ur)
2928 gchar *cmd_str = NULL;
2929 TcoreHal *hal = NULL;
2930 TcoreATRequest *atreq = NULL;
2931 TcorePending *pending = NULL;
2932 const struct treq_sms_get_params *getSmsParams = NULL;
2933 int record_len = 0, *smsp_record_len = NULL;
2937 getSmsParams = tcore_user_request_ref_data(ur, NULL);
2938 hal = tcore_object_get_hal(obj);
2939 if (NULL == getSmsParams || NULL == hal) {
2940 err("NULL input. Unable to proceed");
2941 dbg("getSmsParams: [%p], hal: [%p]", getSmsParams, hal);
2944 return TCORE_RETURN_EINVAL;
2947 smsp_record_len = tcore_plugin_ref_property(tcore_object_ref_plugin(obj), "SMSPRECORDLEN");
2948 record_len = *smsp_record_len;
2949 dbg("record len from property %d", record_len);
2951 // AT+CRSM=command>[,<fileid>[,<P1>,<P2>,<P3>[,<data>[,<pathid>]]]]
2952 cmd_str = g_strdup_printf("AT+CRSM=178,28482,%d,4,%d", (getSmsParams->index + 1), record_len);
2954 dbg("cmd_str is %s", cmd_str);
2956 atreq = tcore_at_request_new((const char *) cmd_str, "+CRSM", TCORE_AT_SINGLELINE);
2957 pending = tcore_pending_new(obj, 0);
2958 if (NULL == cmd_str || NULL == atreq || NULL == pending) {
2959 err("Out of memory. Unable to proceed");
2960 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
2962 // free memory we own
2964 util_sms_free_memory(atreq);
2965 util_sms_free_memory(pending);
2968 return TCORE_RETURN_ENOMEM;
2971 util_hex_dump(" ", strlen(cmd_str), (void *) cmd_str);
2973 tcore_pending_set_request_data(pending, 0, atreq);
2974 tcore_pending_set_response_callback(pending, on_response_get_sms_params, NULL);
2975 tcore_pending_link_user_request(pending, ur);
2976 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
2977 tcore_hal_send_request(hal, pending);
2982 return TCORE_RETURN_SUCCESS;
2985 static TReturn set_sms_params(CoreObject *obj, UserRequest *ur)
2987 gchar *cmd_str = NULL;
2988 char *encoded_data = NULL;
2989 unsigned char *temp_data = NULL;
2990 int SMSPRecordLen = 0;
2992 TcoreHal *hal = NULL;
2993 TcoreATRequest *atreq = NULL;
2994 TcorePending *pending = NULL;
2995 const struct treq_sms_set_params *setSmsParams = NULL;
2996 int encoded_data_len = 0;
3000 setSmsParams = tcore_user_request_ref_data(ur, NULL);
3001 hal = tcore_object_get_hal(obj);
3002 if (NULL == setSmsParams || NULL == hal) {
3003 err("NULL input. Unable to proceed");
3004 dbg("setSmsParams: [%p], hal: [%p]", setSmsParams, hal);
3008 // EFsmsp file size is 28 +Y bytes (Y is alpha id size)
3009 SMSPRecordLen = 28 + setSmsParams->params.alphaIdLen;
3010 temp_data = calloc(SMSPRecordLen, 1);
3011 encoded_data = calloc(SMSPRecordLen * 2 + 1, 1);
3013 _tcore_util_sms_encode_smsParameters(&(setSmsParams->params), temp_data, SMSPRecordLen);
3015 util_byte_to_hex((const char *) temp_data, (char *) encoded_data, SMSPRecordLen);
3017 encoded_data_len = ((SMSPRecordLen) * 2);
3019 hal = tcore_object_get_hal(obj);
3020 pending = tcore_pending_new(obj, 0);
3022 dbg("alpha id len %d encoded data %s. Encoded data len %d", setSmsParams->params.alphaIdLen, encoded_data, encoded_data_len);
3023 cmd_str = g_strdup_printf("AT+CRSM=220,28482,%d,4,%d,\"%s\"", (setSmsParams->params.recordIndex + 1), SMSPRecordLen, encoded_data);
3025 dbg("cmd str is %s", cmd_str);
3026 atreq = tcore_at_request_new(cmd_str, "+CRSM:", TCORE_AT_SINGLELINE);
3028 if (NULL == cmd_str || NULL == atreq || NULL == pending) {
3029 err("Out of memory. Unable to proceed");
3030 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
3032 // free memory we own
3034 util_sms_free_memory(atreq);
3035 util_sms_free_memory(pending);
3037 util_sms_free_memory(temp_data);
3038 util_sms_free_memory(encoded_data);
3041 return TCORE_RETURN_ENOMEM;
3044 util_hex_dump(" ", strlen(cmd_str), (void *) cmd_str);
3046 tcore_pending_set_request_data(pending, 0, atreq);
3047 tcore_pending_set_response_callback(pending, on_response_set_sms_params, NULL);
3048 tcore_pending_link_user_request(pending, ur);
3049 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
3050 tcore_hal_send_request(hal, pending);
3053 util_sms_free_memory(temp_data);
3054 util_sms_free_memory(encoded_data);
3059 static TReturn get_paramcnt(CoreObject *obj, UserRequest *ur)
3061 gchar *cmd_str = NULL;
3062 TcoreHal *hal = NULL;
3063 TcoreATRequest *atreq = NULL;
3064 TcorePending *pending = NULL;
3068 hal = tcore_object_get_hal(obj);
3070 err("NULL HAL. Unable to proceed");
3073 return TCORE_RETURN_EINVAL;
3076 // AT+CRSM=command>[,<fileid>[,<P1>,<P2>,<P3>[,<data>[,<pathid>]]]]
3077 cmd_str = g_strdup_printf("AT+CRSM=192,28482");
3078 atreq = tcore_at_request_new((const char *) cmd_str, "+CRSM", TCORE_AT_SINGLELINE);
3079 pending = tcore_pending_new(obj, 0);
3081 if (NULL == cmd_str || NULL == atreq || NULL == pending) {
3082 err("NULL pointer. Unable to proceed");
3083 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
3085 // free memory we own
3087 util_sms_free_memory(atreq);
3088 util_sms_free_memory(pending);
3091 return TCORE_RETURN_FAILURE;
3094 util_hex_dump(" ", strlen(cmd_str), (void *) cmd_str);
3096 tcore_pending_set_request_data(pending, 0, atreq);
3097 tcore_pending_set_response_callback(pending, on_response_get_paramcnt, NULL);
3098 tcore_pending_link_user_request(pending, ur);
3099 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
3100 tcore_hal_send_request(hal, pending);
3105 return TCORE_RETURN_SUCCESS;
3108 static struct tcore_sms_operations sms_ops = {
3109 .send_umts_msg = send_umts_msg,
3110 .read_msg = read_msg,
3111 .save_msg = save_msg,
3112 .delete_msg = delete_msg,
3113 .get_storedMsgCnt = get_storedMsgCnt,
3116 .get_cb_config = get_cb_config,
3117 .set_cb_config = set_cb_config,
3118 .set_mem_status = set_mem_status,
3119 .get_pref_brearer = NULL,
3120 .set_pref_brearer = NULL,
3121 .set_delivery_report = set_delivery_report,
3122 .set_msg_status = set_msg_status,
3123 .get_sms_params = get_sms_params,
3124 .set_sms_params = set_sms_params,
3125 .get_paramcnt = get_paramcnt,
3128 gboolean s_sms_init(TcorePlugin *plugin, TcoreHal *hal)
3130 CoreObject *obj = NULL;
3131 struct property_sms_info *data = NULL;
3132 GQueue *work_queue = NULL;
3133 int *smsp_record_len = NULL;
3136 dbg("plugin: [%p]", plugin);
3137 dbg("hal: [%p]", hal);
3139 obj = tcore_sms_new(plugin, "umts_sms", &sms_ops, hal);
3141 data = calloc(sizeof(struct property_sms_info), 1);
3143 if (NULL == obj || NULL == data) {
3144 err("Unable to initialize. Exiting");
3151 work_queue = g_queue_new();
3152 tcore_object_link_user_data(obj, work_queue);
3154 // Registering for SMS notifications
3155 tcore_object_add_callback(obj, "\e+CMTI", on_event_class2_sms_incom_msg, NULL);
3156 tcore_object_add_callback(obj, "\e+CMT", on_event_sms_incom_msg, NULL);
3158 tcore_object_add_callback(obj, "\e+CDS", on_event_sms_incom_msg, NULL);
3159 tcore_object_add_callback(obj, "+XSMSMMSTAT", on_event_sms_memory_status, NULL);
3160 tcore_object_add_callback(obj, "+CMS", on_event_sms_memory_status, NULL);
3162 tcore_object_add_callback(obj, "\e+CBMI", on_event_sms_cb_incom_msg, NULL);
3163 tcore_object_add_callback(obj, "\e+CBM", on_event_sms_cb_incom_msg, NULL);
3164 tcore_object_add_callback(obj, "+XSIM", on_event_sms_ready_status, NULL);
3166 tcore_plugin_link_property(plugin, "SMS", data);
3168 // storing smsp record length
3169 smsp_record_len = calloc(sizeof(int), 1);
3170 tcore_plugin_link_property(plugin, "SMSPRECORDLEN", smsp_record_len);
3176 void s_sms_exit(TcorePlugin *plugin)
3178 CoreObject *obj = NULL;
3179 struct property_sms_info *data = NULL;
3182 dbg("plugin: [%p]", plugin);
3184 obj = tcore_plugin_ref_core_object(plugin, "umts_sms");
3186 err("NULL core object. Nothing to do.");
3189 tcore_sms_free(obj);
3191 data = tcore_plugin_ref_property(plugin, "SMS");
3192 util_sms_free_memory(data);