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/imc_tel_err.h"
44 #include "imc_common.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 SMS_DEVICE_READY 1 /* Telephony device ready */
62 #define SMS_DEVICE_NOT_READY 0 /* Telephony device not ready */
64 /*=============================================================
66 ==============================================================*/
67 #define SMS_CBMI_SELECTED_SOME 0x02 /* Some CBMIs are selected */
68 #define SMS_CBMI_SELECTED_ALL 0x01 /* All CBMIs are selected */
70 /*=============================================================
72 ==============================================================*/
73 #define AT_REC_UNREAD 0 /* Received and Unread */
74 #define AT_REC_READ 1 /* Received and Read */
75 #define AT_STO_UNSENT 2 /* Unsent */
76 #define AT_STO_SENT 3 /* Sent */
77 #define AT_ALL 4 /* Unknown */
79 /*=============================================================
81 ==============================================================*/
82 #define AT_MEMORY_AVAILABLE 0 /* Memory Available */
83 #define AT_MEMORY_FULL 1 /* Memory Full */
85 /*=============================================================
86 SIM CRSM SW1 and Sw2 Error definitions */
88 #define AT_SW1_SUCCESS 0x90
89 #define AT_SW2_SUCCESS 0
90 #define AT_SW1_LEN_RESP 0x9F
92 #define AT_MAX_RECORD_LEN 256
93 /* SCA 12 bytes long and TDPU is 164 bytes long */
94 #define PDU_LEN_MAX 176
95 #define HEX_PDU_LEN_MAX ((PDU_LEN_MAX * 2) + 1)
97 /*=============================================================
99 ==============================================================*/
100 #define CR '\r' /* Carriage Return */
102 /*=============================================================
104 ==============================================================*/
105 #define SMS_SWAPBYTES16(x) (((x) & 0xffff0000) | (((x) & 0x0000ff00) >> 8) | (((x) & 0x000000ff) << 8))
106 #define SMS_ENCODED_SCA_LEN_MAX 12
107 #define CONVERT_TO_HEX(in, out) (in <= 9) ? \
108 (out = '0' + in) : (out = 'A' + in - 10)
110 void print_glib_list_elem(gpointer data, gpointer user_data);
112 static void on_response_class2_read_msg(TcorePending *pending, int data_len, const void *data, void *user_data);
115 gboolean util_byte_to_hex(const char *byte_pdu, char *hex_pdu, int num_bytes);
117 void print_glib_list_elem(gpointer data, gpointer user_data)
119 char *item = (char *)data;
121 dbg("item: [%s]", item);
124 /*=============================================================
126 ==============================================================*/
127 static void on_confirmation_sms_message_send(TcorePending *p, gboolean result, void *user_data)
129 dbg("Entered Function. Request message out from queue");
131 dbg("TcorePending: [%p]", p);
132 dbg("result: [%02x]", result);
133 dbg("user_data: [%p]", user_data);
135 if (result == TRUE) {
137 } else { /* Failed */
141 dbg("Exiting Function. Nothing to return");
144 /*=============================================================
146 ==============================================================*/
147 static void util_sms_free_memory(void *sms_ptr)
151 if (NULL != sms_ptr) {
152 dbg("Freeing memory location: [%p]", sms_ptr);
156 err("Invalid memory location. Nothing to do.");
163 static guint __util_sms_encode_pdu(const guchar *sca,
164 const guchar *tpdu, guint tpdu_len, gchar *pdu)
167 unsigned char converted_sca[SMS_ENCODED_SCA_LEN_MAX];
170 converted_sca[0] = 0;
176 * For PDU, the SC Address length is the number of packed BCD bytes
177 * + 1 byte for SC Address type whereas the length given in
178 * 3GPP 23.040 Address encoding is the number of digits without 1 byte
181 sca_len = ((sca[0] + 1) / 2) + 1;
183 converted_sca[0] = (unsigned char)sca_len;
185 for (i = 1; i <= sca_len; i++)
186 converted_sca[i] = sca[i];
189 memcpy(pdu, converted_sca, sca_len + 1);
190 memcpy(pdu + sca_len + 1, tpdu, tpdu_len);
192 return sca_len + 1 + tpdu_len;
196 static long __util_sms_encode_hex(const guchar *src, long num_bytes, gchar *buf)
203 for (i = 0, j = 0; i < num_bytes; i++, j++) {
204 CONVERT_TO_HEX(((src[i] >> 4) & 0xf), buf[j++]);
205 CONVERT_TO_HEX((src[i] & 0xf), buf[j]);
213 static int util_sms_decode_smsParameters(unsigned char *incoming, unsigned int length, struct telephony_sms_Params *params)
215 int alpha_id_len = 0;
219 dbg(" RecordLen = %d", length);
221 if(incoming == NULL || params == NULL)
224 alpha_id_len = length -SMS_SMSP_PARAMS_MAX_LEN;
226 if (alpha_id_len > 0) {
227 if (alpha_id_len > SMS_SMSP_ALPHA_ID_LEN_MAX) {
228 alpha_id_len = SMS_SMSP_ALPHA_ID_LEN_MAX;
231 for (i = 0; i < alpha_id_len; i++) {
232 if (0xff == incoming[i]) {
238 memcpy(params->szAlphaId, incoming, i);
240 params->alphaIdLen = i;
242 dbg(" Alpha id length = %d", i);
244 params->alphaIdLen = 0;
245 dbg(" Alpha id length is zero");
248 params->paramIndicator = incoming[alpha_id_len];
250 dbg(" Param Indicator = %02x", params->paramIndicator);
252 if ((params->paramIndicator & SMSPValidDestAddr) == 0) {
253 nOffset = nDestAddrOffset;
255 if (0x00 == incoming[alpha_id_len + nOffset] || 0xff == incoming[alpha_id_len + nOffset]) {
256 params->tpDestAddr.dialNumLen = 0;
258 dbg("DestAddr Length is 0");
260 if (0 < (int) incoming[alpha_id_len + nOffset]) {
261 params->tpDestAddr.dialNumLen = (int) (incoming[alpha_id_len + nOffset] - 1);
263 if (params->tpDestAddr.dialNumLen > SMS_SMSP_ADDRESS_LEN)
264 params->tpDestAddr.dialNumLen = SMS_SMSP_ADDRESS_LEN;
266 params->tpDestAddr.dialNumLen = 0;
269 params->tpDestAddr.numPlanId = incoming[alpha_id_len + (++nOffset)] & 0x0f;
270 params->tpDestAddr.typeOfNum = (incoming[alpha_id_len + nOffset] & 0x70) >> 4;
272 memcpy(params->tpDestAddr.diallingNum, &incoming[alpha_id_len + (++nOffset)], (params->tpDestAddr.dialNumLen));
274 dbg("Dest TON is %d", params->tpDestAddr.typeOfNum);
275 dbg("Dest NPI is %d", params->tpDestAddr.numPlanId);
276 dbg("Dest Length = %d", params->tpDestAddr.dialNumLen);
277 dbg("Dest Addr = %s", params->tpDestAddr.diallingNum);
280 params->tpDestAddr.dialNumLen = 0;
283 if ((params->paramIndicator & SMSPValidSvcAddr) == 0) {
284 nOffset = nSCAAddrOffset;
286 if (0x00 == (int) incoming[alpha_id_len + nOffset] || 0xff == (int) incoming[alpha_id_len + nOffset]) {
287 params->tpSvcCntrAddr.dialNumLen = 0;
289 dbg(" SCAddr Length is 0");
291 if (0 < (int) incoming[alpha_id_len + nOffset]) {
292 params->tpSvcCntrAddr.dialNumLen = (int) (incoming[alpha_id_len + nOffset] - 1);
294 if (params->tpSvcCntrAddr.dialNumLen > SMS_SMSP_ADDRESS_LEN)
295 params->tpSvcCntrAddr.dialNumLen = SMS_SMSP_ADDRESS_LEN;
297 params->tpSvcCntrAddr.numPlanId = incoming[alpha_id_len + (++nOffset)] & 0x0f;
298 params->tpSvcCntrAddr.typeOfNum = (incoming[alpha_id_len + nOffset] & 0x70) >> 4;
300 memcpy(params->tpSvcCntrAddr.diallingNum, &incoming[alpha_id_len + (++nOffset)], (params->tpSvcCntrAddr.dialNumLen));
302 dbg("SCAddr Length = %d ", params->tpSvcCntrAddr.dialNumLen);
303 dbg("SCAddr TON is %d", params->tpSvcCntrAddr.typeOfNum);
304 dbg("SCAddr NPI is %d", params->tpSvcCntrAddr.numPlanId);
306 for (i = 0; i < (int) params->tpSvcCntrAddr.dialNumLen; i++)
307 dbg("SCAddr = %d [%02x]", i, params->tpSvcCntrAddr.diallingNum[i]);
309 params->tpSvcCntrAddr.dialNumLen = 0;
312 } else if ((0x00 < (int) incoming[alpha_id_len + nSCAAddrOffset] && (int) incoming[alpha_id_len + nSCAAddrOffset] <= 12)
313 || 0xff != (int) incoming[alpha_id_len + nSCAAddrOffset]) {
314 nOffset = nSCAAddrOffset;
316 if (0x00 == (int) incoming[alpha_id_len + nOffset] || 0xff == (int) incoming[alpha_id_len + nOffset]) {
317 params->tpSvcCntrAddr.dialNumLen = 0;
318 dbg("SCAddr Length is 0");
320 if (0 < (int) incoming[alpha_id_len + nOffset]) {
321 params->tpSvcCntrAddr.dialNumLen = (int) (incoming[alpha_id_len + nOffset] - 1);
323 params->tpSvcCntrAddr.dialNumLen = incoming[alpha_id_len + nOffset] - 1;
325 if (params->tpSvcCntrAddr.dialNumLen > SMS_SMSP_ADDRESS_LEN)
326 params->tpSvcCntrAddr.dialNumLen = SMS_SMSP_ADDRESS_LEN;
328 params->tpSvcCntrAddr.numPlanId = incoming[alpha_id_len + (++nOffset)] & 0x0f;
329 params->tpSvcCntrAddr.typeOfNum = (incoming[alpha_id_len + nOffset] & 0x70) >> 4;
331 memcpy(params->tpSvcCntrAddr.diallingNum, &incoming[alpha_id_len + (++nOffset)],
332 (params->tpSvcCntrAddr.dialNumLen));
334 dbg("SCAddr Length = %d ", params->tpSvcCntrAddr.dialNumLen);
335 dbg("SCAddr TON is %d", params->tpSvcCntrAddr.typeOfNum);
336 dbg("SCAddr NPI is %d", params->tpSvcCntrAddr.numPlanId);
338 for (i = 0; i < (int) params->tpSvcCntrAddr.dialNumLen; i++)
339 dbg("SCAddr = %d [%02x]", i, params->tpSvcCntrAddr.diallingNum[i]);
341 params->tpSvcCntrAddr.dialNumLen = 0;
345 params->tpSvcCntrAddr.dialNumLen = 0;
348 if ((params->paramIndicator & SMSPValidPID) == 0 && (alpha_id_len + nPIDOffset) < MAX_GSM_SMS_PARAM_RECORD_SIZE) {
349 params->tpProtocolId = incoming[alpha_id_len + nPIDOffset];
351 if ((params->paramIndicator & SMSPValidDCS) == 0 && (alpha_id_len + nDCSOffset) < MAX_GSM_SMS_PARAM_RECORD_SIZE) {
352 params->tpDataCodingScheme = incoming[alpha_id_len + nDCSOffset];
354 if ((params->paramIndicator & SMSPValidVP) == 0 && (alpha_id_len + nVPOffset) < MAX_GSM_SMS_PARAM_RECORD_SIZE) {
355 params->tpValidityPeriod = incoming[alpha_id_len + nVPOffset];
358 dbg(" Alpha Id(Len) = %d", (int) params->alphaIdLen);
360 for (i = 0; i < (int) params->alphaIdLen; i++) {
361 dbg(" Alpha Id = [%d] [%c]", i, params->szAlphaId[i]);
363 dbg(" PID = %d",params->tpProtocolId);
364 dbg(" DCS = %d",params->tpDataCodingScheme);
365 dbg(" VP = %d",params->tpValidityPeriod);
370 /*=============================================================
372 ==============================================================*/
373 static gboolean on_event_class2_sms_incom_msg(CoreObject *obj,
374 const void *event_info, void *user_data)
376 //+CMTI: <mem>,<index>
378 GSList *tokens = NULL , *lines = NULL;
379 char *line = NULL, *cmd_str = NULL;
380 int index = 0, mem_type = 0;
381 TcoreHal *hal = NULL;
382 TcoreATRequest *atreq = NULL;
383 TcorePending *pending = NULL;
385 dbg("Entered Function");
387 lines = (GSList *)event_info;
388 line = (char *)g_slist_nth_data(lines, 0); /* Fetch Line 1 */
390 dbg("Line 1: [%s]", line);
393 err("Line 1 is invalid");
397 tokens = tcore_at_tok_new(line); /* Split Line 1 into tokens */
398 mem_type = atoi(g_slist_nth_data(tokens, 0)); // Type of Memory stored
400 err("Token 0 not present");
402 index = atoi((char *) g_slist_nth_data(tokens, 1));
404 hal = tcore_object_get_hal(obj);
406 err("NULL input. Unable to proceed");
407 dbg("readMsg: hal: [%p]", hal);
410 return TCORE_RETURN_EINVAL;
413 dbg("index: [%d]", index);
415 cmd_str = g_strdup_printf("AT+CMGR=%d", index);
416 atreq = tcore_at_request_new((const char *)cmd_str, "+CMGR", TCORE_AT_PDU);
417 pending = tcore_pending_new(obj, 0);
419 if (NULL == cmd_str || NULL == atreq || NULL == pending) {
420 err("Out of memory. Unable to proceed");
421 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
425 util_sms_free_memory(atreq);
426 util_sms_free_memory(pending);
429 return TCORE_RETURN_ENOMEM;
432 util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
434 tcore_pending_set_request_data(pending, 0, atreq);
435 tcore_pending_set_response_callback(pending, on_response_class2_read_msg, (void *)(uintptr_t)index); //storing index as user data for response
436 tcore_pending_link_user_request(pending, NULL);
437 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
438 tcore_hal_send_request(hal, pending);
442 tcore_at_tok_free(tokens);
447 static gboolean on_event_sms_incom_msg(CoreObject *o, const void *event_info, void *user_data)
449 //+CMT: [<alpha>],<length><CR><LF><pdu> (PDU mode enabled);
452 GSList *tokens = NULL;
453 GSList *lines = NULL;
455 int pdu_len = 0, no_of_tokens = 0;
456 unsigned char *bytePDU = NULL;
457 struct tnoti_sms_incoming_msg gsmMsgInfo;
460 dbg("Entered Function");
462 lines = (GSList *)event_info;
463 memset(&gsmMsgInfo, 0x00, sizeof(struct tnoti_sms_incoming_msg));
465 if (2 != g_slist_length(lines)) {
466 err("Invalid number of lines for +CMT. Must be 2");
470 line = (char *)g_slist_nth_data(lines, 0); /* Fetch Line 1 */
472 dbg("Line 1: [%s]", line);
475 err("Line 1 is invalid");
479 tokens = tcore_at_tok_new(line); /* Split Line 1 into tokens */
481 no_of_tokens = g_slist_length(tokens);
483 if (no_of_tokens == 2) { // in case of incoming SMS +CMT
484 dbg("Alpha ID: [%02x]", g_slist_nth_data(tokens, 0)); /* 0: Alpha ID */
485 pdu_len = atoi((char *)g_slist_nth_data(tokens, 1));
486 dbg("pdu_len: [%d]", pdu_len); /* 1: PDU Length */
487 } else if (no_of_tokens == 1) { // in case of incoming status report +CDS
488 pdu_len = atoi((char *)g_slist_nth_data(tokens, 0));
489 dbg("pdu_len: [%d]", pdu_len); /* 1: PDU Length */
492 line = (char *)g_slist_nth_data(lines, 1); /* Fetch Line 2 */
494 dbg("Line 2: [%s]", line);
497 err("Line 2 is invalid");
501 /* Convert to Bytes */
502 bytePDU = (unsigned char *)util_hexStringToBytes(line);
504 sca_length = bytePDU[0];
506 dbg("SCA length = %d", sca_length);
508 gsmMsgInfo.msgInfo.format = SMS_NETTYPE_3GPP;
509 gsmMsgInfo.msgInfo.msgLength = pdu_len;
511 if (sca_length == 0) {
512 memcpy(gsmMsgInfo.msgInfo.tpduData, &bytePDU[1], gsmMsgInfo.msgInfo.msgLength);
514 gsmMsgInfo.msgInfo.sca[0] = sca_length;
515 memcpy(&(gsmMsgInfo.msgInfo.sca[1]), &bytePDU[1], sca_length);
516 memcpy(gsmMsgInfo.msgInfo.tpduData, &bytePDU[sca_length+1], gsmMsgInfo.msgInfo.msgLength);
519 util_hex_dump(" ", strlen(line)/2, bytePDU);
520 util_hex_dump(" ", sca_length, gsmMsgInfo.msgInfo.sca);
521 util_hex_dump(" ", gsmMsgInfo.msgInfo.msgLength,gsmMsgInfo.msgInfo.tpduData);
523 ret = tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_SMS_INCOM_MSG, sizeof(struct tnoti_sms_incoming_msg), &gsmMsgInfo);
527 tcore_at_tok_free(tokens);
536 static gboolean on_event_sms_memory_status(CoreObject *o, const void *event_info, void *user_data)
538 struct tnoti_sms_memory_status memStatusInfo = {0,};
540 int memoryStatus = -1;
543 char *line = NULL , *pResp = NULL;
548 lines = (GSList *)event_info;
549 if (1 != g_slist_length(lines)) {
550 dbg("unsolicited msg but multiple line");
553 line = (char*)(lines->data);
557 tokens = tcore_at_tok_new(line);
558 pResp = g_slist_nth_data(tokens, 0);
561 memoryStatus = atoi(pResp);
562 dbg("memoryStatus is %d",memoryStatus);
563 if (memoryStatus == 0) {//SIM Full condition
564 memStatusInfo.status = SMS_PHONE_MEMORY_STATUS_FULL;
566 ret = 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);
569 tcore_at_tok_free(tokens);
578 static gboolean on_event_sms_cb_incom_msg(CoreObject *o, const void *event_info, void *user_data)
580 //+CBM: <length><CR><LF><pdu>
582 struct tnoti_sms_cellBroadcast_msg cbMsgInfo;
584 int rtn = -1 , length = 0;
585 char * line = NULL, *pdu = NULL, *pResp = NULL;
586 GSList *tokens = NULL;
587 GSList *lines = NULL;
589 dbg(" Func Entrance");
591 lines = (GSList *)event_info;
593 memset(&cbMsgInfo, 0, sizeof(struct tnoti_sms_cellBroadcast_msg));
595 line = (char *)(lines->data);
599 dbg("Noti line is %s",line);
600 tokens = tcore_at_tok_new(line); /* Split Line 1 into tokens */
602 pResp = g_slist_nth_data(tokens, 0);
604 length = atoi(pResp);
606 dbg("token 0 is null");
609 pdu = g_slist_nth_data(lines, 1);
611 cbMsgInfo.cbMsg.length = length;
612 cbMsgInfo.cbMsg.cbMsgType = SMS_CB_MSG_GSM;
614 dbg("CB Msg LENGTH [%2x]", length);
616 if ((cbMsgInfo.cbMsg.length >0) && (SMS_CB_SIZE_MAX >= cbMsgInfo.cbMsg.length)) {
617 unsigned char *byte_pdu = NULL;
619 byte_pdu = (unsigned char *)util_hexStringToBytes(pdu);
621 memcpy(cbMsgInfo.cbMsg.msgData, (char*)byte_pdu, cbMsgInfo.cbMsg.length);
622 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);
625 dbg("Invalid Message Length");
628 dbg("Recieved NULL pdu");
634 dbg(" Return value [%d]",rtn);
637 tcore_at_tok_free(tokens);
643 /*=============================================================
645 ==============================================================*/
646 static void on_response_sms_delete_msg(TcorePending *p, int data_len, const void *data, void *user_data)
648 struct tresp_sms_delete_msg delMsgInfo = {0,};
649 UserRequest *ur = NULL;
650 const TcoreATResponse *atResp = data;
651 int index = (int) user_data;
653 dbg(" Func Entrance");
655 ur = tcore_pending_ref_user_request(p);
656 if (atResp->success) {
658 delMsgInfo.index = index;
659 delMsgInfo.result = SMS_SENDSMS_SUCCESS;
662 delMsgInfo.index = index;
663 delMsgInfo.result = SMS_DEVICE_FAILURE;
666 tcore_user_request_send_response(ur, TRESP_SMS_DELETE_MSG, sizeof(struct tresp_sms_delete_msg), &delMsgInfo);
671 static void on_response_sms_save_msg(TcorePending *p, int data_len, const void *data, void *user_data)
673 struct tresp_sms_save_msg saveMsgInfo = {0,};
674 UserRequest *ur = NULL;
675 const TcoreATResponse *atResp = data;
676 GSList *tokens = NULL;
681 ur = tcore_pending_ref_user_request(p);
682 if (atResp->success) {
685 line = (char *)atResp->lines->data;
686 tokens = tcore_at_tok_new(line);
687 pResp = g_slist_nth_data(tokens, 0);
690 saveMsgInfo.index = (atoi(pResp) - 1); /* IMC index starts from 1 */
691 saveMsgInfo.result = SMS_SENDSMS_SUCCESS;
694 saveMsgInfo.index = -1;
695 saveMsgInfo.result = SMS_DEVICE_FAILURE;
697 tcore_at_tok_free(tokens);
701 saveMsgInfo.index = -1;
702 saveMsgInfo.result = SMS_DEVICE_FAILURE;
705 rtn = tcore_user_request_send_response(ur, TRESP_SMS_SAVE_MSG, sizeof(struct tresp_sms_save_msg), &saveMsgInfo);
706 dbg("Return value [%d]", rtn);
710 static void on_response_send_umts_msg(TcorePending *pending, int data_len, const void *data, void *user_data)
712 const TcoreATResponse *at_response = data;
713 struct tresp_sms_send_msg resp_umts;
714 UserRequest *user_req = NULL;
717 GSList *tokens = NULL;
718 char *gslist_line = NULL, *line_token = NULL;
722 user_req = tcore_pending_ref_user_request(pending);
724 if (NULL == user_req) {
725 err("No user request");
731 memset(&resp_umts, 0x00, sizeof(resp_umts));
732 resp_umts.result = SMS_DEVICE_FAILURE;
734 if (at_response->success > 0) { /* SUCCESS */
736 if (at_response->lines) { // lines present in at_response
737 gslist_line = (char *)at_response->lines->data;
738 dbg("gslist_line: [%s]", gslist_line);
740 tokens = tcore_at_tok_new(gslist_line); //extract tokens
742 line_token = g_slist_nth_data(tokens, 0);
743 if (line_token != NULL) {
744 msg_ref = atoi(line_token);
745 dbg("Message Reference: [%d]", msg_ref);
747 resp_umts.result = SMS_SENDSMS_SUCCESS;
749 dbg("No Message Reference received");
751 tcore_at_tok_free(tokens);
752 } else { // no lines in at_response
759 tcore_user_request_send_response(user_req, TRESP_SMS_SEND_UMTS_MSG, sizeof(resp_umts), &resp_umts);
765 static void on_response_class2_read_msg(TcorePending *pending, int data_len, const void *data, void *user_data)
767 const TcoreATResponse *at_response = data;
769 char *gslist_line = NULL, *line_token = NULL, *hex_pdu = NULL;
770 int pdu_len = 0, rtn = 0;
771 unsigned char *bytePDU = NULL;
772 struct tnoti_sms_incoming_msg gsmMsgInfo;
776 dbg("lines: [%p]", at_response->lines);
777 g_slist_foreach(at_response->lines, print_glib_list_elem, NULL); //for debug log
779 if (at_response->success > 0) {
781 if (at_response->lines) {
783 gslist_line = (char *)at_response->lines->data;
785 dbg("gslist_line: [%s]", gslist_line);
787 tokens = tcore_at_tok_new(gslist_line);
788 dbg("Number of tokens: [%d]", g_slist_length(tokens));
789 g_slist_foreach(tokens, print_glib_list_elem, NULL); //for debug log
791 line_token = g_slist_nth_data(tokens, 2); //Third Token: Length
792 if (line_token != NULL) {
793 pdu_len = atoi(line_token);
794 dbg("Length: [%d]", pdu_len);
798 gslist_line = (char *)at_response->lines->next->data;
800 dbg("gslist_line: [%s]", gslist_line);
802 //free the consumed token
803 tcore_at_tok_free(tokens);
805 tokens = tcore_at_tok_new(gslist_line);
806 dbg("Number of tokens: [%d]", g_slist_length(tokens));
807 g_slist_foreach(tokens, print_glib_list_elem, NULL); //for debug log
809 hex_pdu = g_slist_nth_data(tokens, 0); //Fetch SMS PDU
811 //free the consumed token
812 tcore_at_tok_free(tokens);
820 /* Convert to Bytes */
821 bytePDU = (unsigned char *)util_hexStringToBytes(hex_pdu);
823 sca_length = bytePDU[0];
825 dbg("SCA length = %d", sca_length);
827 gsmMsgInfo.msgInfo.msgLength = pdu_len;
829 if (sca_length == 0) {
830 memcpy(gsmMsgInfo.msgInfo.tpduData, &bytePDU[1], gsmMsgInfo.msgInfo.msgLength);
832 memcpy(gsmMsgInfo.msgInfo.sca, bytePDU, sca_length);
833 memcpy(gsmMsgInfo.msgInfo.tpduData, &bytePDU[sca_length+1], gsmMsgInfo.msgInfo.msgLength);
836 util_hex_dump(" ", strlen(hex_pdu)/2, bytePDU);
837 util_hex_dump(" ", sca_length, gsmMsgInfo.msgInfo.sca);
838 util_hex_dump(" ", gsmMsgInfo.msgInfo.msgLength,gsmMsgInfo.msgInfo.tpduData);
840 rtn = tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(tcore_pending_ref_core_object(pending))),
841 tcore_pending_ref_core_object(pending), TNOTI_SMS_INCOM_MSG, sizeof(struct tnoti_sms_incoming_msg), &gsmMsgInfo);
842 dbg("rtn: [%d]", rtn);
850 static void on_response_read_msg(TcorePending *pending, int data_len, const void *data, void *user_data)
852 const TcoreATResponse *at_response = data;
853 struct tresp_sms_read_msg resp_read_msg;
854 UserRequest *user_req = NULL;
857 char *gslist_line = NULL, *line_token = NULL, *byte_pdu = NULL, *hex_pdu = NULL;
859 int msg_status = 0, alpha_id = 0, pdu_len = 0;
860 int index = (int)(uintptr_t)user_data;
863 dbg("index: [%d]", index);
864 g_slist_foreach(at_response->lines, print_glib_list_elem, NULL); //for debug log
866 user_req = tcore_pending_ref_user_request(pending);
867 if (NULL == user_req) {
868 err("No user request");
874 memset(&resp_read_msg, 0x00, sizeof(resp_read_msg));
875 resp_read_msg.result = SMS_PHONE_FAILURE;
877 if (at_response->success > 0) {
879 if (at_response->lines) {
880 if (g_slist_length(at_response->lines) != 2) {
881 err("2 lines are required");
885 gslist_line = (char *)at_response->lines->data;
887 dbg("gslist_line: [%s]", gslist_line);
889 tokens = tcore_at_tok_new(gslist_line);
890 dbg("Number of tokens: [%d]", g_slist_length(tokens));
891 g_slist_foreach(tokens, print_glib_list_elem, NULL); //for debug log
893 line_token = g_slist_nth_data(tokens, 0); //First Token: Message Status
894 if (line_token != NULL) {
895 msg_status = atoi(line_token);
896 dbg("msg_status is %d",msg_status);
897 switch (msg_status) {
899 resp_read_msg.dataInfo.msgStatus = SMS_STATUS_UNREAD;
903 resp_read_msg.dataInfo.msgStatus = SMS_STATUS_READ;
907 resp_read_msg.dataInfo.msgStatus = SMS_STATUS_UNSENT;
911 resp_read_msg.dataInfo.msgStatus = SMS_STATUS_SENT;
914 case AT_ALL: //Fall Through
915 default: //Fall Through
916 resp_read_msg.dataInfo.msgStatus = SMS_STATUS_RESERVED;
921 line_token = g_slist_nth_data(tokens, 1); //Second Token: AlphaID
922 if (line_token != NULL) {
923 alpha_id = atoi(line_token);
924 dbg("AlphaID: [%d]", alpha_id);
927 line_token = g_slist_nth_data(tokens, 2); //Third Token: Length
928 if (line_token != NULL) {
929 pdu_len = atoi(line_token);
930 dbg("Length: [%d]", pdu_len);
934 hex_pdu = (char *) at_response->lines->next->data;
936 dbg("EF-SMS PDU: [%s]", hex_pdu);
938 //free the consumed token
939 tcore_at_tok_free(tokens);
941 if (NULL != hex_pdu) {
942 util_hex_dump(" ", strlen(hex_pdu), (void *)hex_pdu);
944 byte_pdu = util_hexStringToBytes(hex_pdu);
946 sca_length = (int)byte_pdu[0];
948 resp_read_msg.dataInfo.simIndex = index; //Retrieving index stored as user_data
950 dbg("SCA Length : %d", sca_length);
952 resp_read_msg.dataInfo.smsData.msgLength = pdu_len;
953 dbg("msgLength: [%d]", resp_read_msg.dataInfo.smsData.msgLength);
955 if(0 == sca_length) {
956 if ((resp_read_msg.dataInfo.smsData.msgLength > 0)
957 && (resp_read_msg.dataInfo.smsData.msgLength <= SMS_SMDATA_SIZE_MAX)) {
958 memset(resp_read_msg.dataInfo.smsData.sca, 0, TAPI_SIM_SMSP_ADDRESS_LEN);
959 memcpy(resp_read_msg.dataInfo.smsData.tpduData, &byte_pdu[1], resp_read_msg.dataInfo.smsData.msgLength);
961 resp_read_msg.result = SMS_SUCCESS;
963 dbg("Invalid Message Length");
964 resp_read_msg.result = SMS_INVALID_PARAMETER_FORMAT;
966 } else if (sca_length > SMS_ENCODED_SCA_LEN_MAX) {
967 dbg("Invalid Message Length");
968 resp_read_msg.result = SMS_INVALID_PARAMETER_FORMAT;
970 if ((resp_read_msg.dataInfo.smsData.msgLength > 0)
971 && (resp_read_msg.dataInfo.smsData.msgLength <= SMS_SMDATA_SIZE_MAX)) {
972 memcpy(resp_read_msg.dataInfo.smsData.sca, (char *)byte_pdu, (sca_length+1));
973 memcpy(resp_read_msg.dataInfo.smsData.tpduData, &byte_pdu[sca_length+1], resp_read_msg.dataInfo.smsData.msgLength);
975 util_hex_dump(" ", SMS_SMSP_ADDRESS_LEN, (void *)resp_read_msg.dataInfo.smsData.sca);
976 util_hex_dump(" ", (SMS_SMDATA_SIZE_MAX + 1), (void *)resp_read_msg.dataInfo.smsData.tpduData);
977 util_hex_dump(" ", strlen(hex_pdu) / 2 + 1, (void *)byte_pdu);
979 resp_read_msg.result = SMS_SUCCESS;
981 dbg("Invalid Message Length");
982 resp_read_msg.result = SMS_INVALID_PARAMETER_FORMAT;
997 tcore_user_request_send_response(user_req, TRESP_SMS_READ_MSG, sizeof(resp_read_msg), &resp_read_msg);
1003 static void on_response_get_msg_indices(TcorePending *pending, int data_len, const void *data, void *user_data)
1005 const TcoreATResponse *at_response = data;
1006 struct tresp_sms_get_storedMsgCnt resp_stored_msg_cnt;
1007 UserRequest *user_req = NULL;
1008 struct tresp_sms_get_storedMsgCnt *resp_stored_msg_cnt_prev = NULL;
1010 GSList *tokens = NULL;
1011 char *gslist_line = NULL, *line_token = NULL;
1012 int gslist_line_count = 0, ctr_loop = 0;
1016 resp_stored_msg_cnt_prev = (struct tresp_sms_get_storedMsgCnt *)user_data;
1017 user_req = tcore_pending_ref_user_request(pending);
1019 memset(&resp_stored_msg_cnt, 0x00, sizeof(resp_stored_msg_cnt));
1020 resp_stored_msg_cnt.result = SMS_DEVICE_FAILURE;
1022 if (at_response->success) {
1024 if (at_response->lines) {
1025 gslist_line_count = g_slist_length(at_response->lines);
1027 if (gslist_line_count > SMS_GSM_SMS_MSG_NUM_MAX)
1028 gslist_line_count = SMS_GSM_SMS_MSG_NUM_MAX;
1030 dbg("Number of lines: [%d]", gslist_line_count);
1031 g_slist_foreach(at_response->lines, print_glib_list_elem, NULL); //for debug log
1033 for (ctr_loop = 0; ctr_loop < gslist_line_count; ctr_loop++) {
1034 gslist_line = (char *)g_slist_nth_data(at_response->lines, ctr_loop); /* Fetch Line i */
1036 dbg("gslist_line [%d] is [%s]", ctr_loop, gslist_line);
1038 if (NULL != gslist_line) {
1039 tokens = tcore_at_tok_new(gslist_line);
1041 g_slist_foreach(tokens, print_glib_list_elem, NULL); //for debug log
1043 line_token = g_slist_nth_data(tokens, 0);
1044 if (NULL != line_token) {
1045 resp_stored_msg_cnt.storedMsgCnt.indexList[ctr_loop] = atoi(line_token);
1046 resp_stored_msg_cnt.result = SMS_SENDSMS_SUCCESS;
1048 dbg("line_token of gslist_line [%d] is NULL", ctr_loop);
1051 tcore_at_tok_free(tokens);
1053 dbg("gslist_line [%d] is NULL", ctr_loop);
1059 if (resp_stored_msg_cnt_prev->storedMsgCnt.usedCount == 0) { // Check if used count is zero
1060 resp_stored_msg_cnt.result = SMS_SENDSMS_SUCCESS;
1064 dbg("Respnose NOK");
1067 resp_stored_msg_cnt.storedMsgCnt.totalCount = resp_stored_msg_cnt_prev->storedMsgCnt.totalCount;
1068 resp_stored_msg_cnt.storedMsgCnt.usedCount = resp_stored_msg_cnt_prev->storedMsgCnt.usedCount;
1070 util_sms_free_memory(resp_stored_msg_cnt_prev);
1072 dbg("total: [%d], used: [%d], result: [%d]", resp_stored_msg_cnt.storedMsgCnt.totalCount, resp_stored_msg_cnt.storedMsgCnt.usedCount, resp_stored_msg_cnt.result);
1073 for (ctr_loop = 0; ctr_loop < gslist_line_count; ctr_loop++) {
1074 dbg("index: [%d]", resp_stored_msg_cnt.storedMsgCnt.indexList[ctr_loop]);
1077 tcore_user_request_send_response(user_req, TRESP_SMS_GET_STORED_MSG_COUNT, sizeof(resp_stored_msg_cnt), &resp_stored_msg_cnt);
1083 static void on_response_get_stored_msg_cnt(TcorePending *pending, int data_len, const void *data, void *user_data)
1085 UserRequest *ur = NULL, *ur_dup = NULL;
1086 struct tresp_sms_get_storedMsgCnt *respStoredMsgCnt = NULL;
1087 const TcoreATResponse *atResp = data;
1088 GSList *tokens=NULL;
1089 char *line = NULL , *pResp = NULL , *cmd_str = NULL;
1090 TcoreATRequest *atReq = NULL;
1091 int usedCnt = 0, totalCnt = 0, result = 0;
1093 TcorePending *pending_new = NULL;
1094 CoreObject *o = NULL;
1098 respStoredMsgCnt = malloc(sizeof(struct tresp_sms_get_storedMsgCnt));
1099 result = SMS_DEVICE_FAILURE;
1101 ur = tcore_pending_ref_user_request(pending);
1102 ur_dup = tcore_user_request_ref(ur);
1103 o = tcore_pending_ref_core_object(pending);
1105 if (atResp->success > 0) {
1107 if (NULL != atResp->lines) {
1108 line = (char *)atResp->lines->data;
1109 dbg("line is %s",line);
1111 tokens = tcore_at_tok_new(line);
1112 pResp = g_slist_nth_data(tokens, 0);
1115 usedCnt =atoi(pResp);
1116 dbg("used cnt is %d",usedCnt);
1119 pResp = g_slist_nth_data(tokens, 1);
1121 totalCnt =atoi(pResp);
1122 result = SMS_SENDSMS_SUCCESS;
1124 respStoredMsgCnt->storedMsgCnt.usedCount = usedCnt;
1125 respStoredMsgCnt->storedMsgCnt.totalCount = totalCnt;
1126 respStoredMsgCnt->result = result;
1128 dbg("used %d, total %d, result %d",usedCnt, totalCnt,result);
1130 pending_new = tcore_pending_new(o, 0);
1131 //Get all messages information
1132 cmd_str = g_strdup_printf("AT+CMGL=4");
1133 atReq = tcore_at_request_new((const char *)cmd_str, "+CMGL", TCORE_AT_MULTILINE);
1135 dbg("cmd str is %s",cmd_str);
1137 tcore_pending_set_request_data(pending_new, 0,atReq);
1138 tcore_pending_set_response_callback(pending_new, on_response_get_msg_indices, (void *)respStoredMsgCnt);
1139 tcore_pending_link_user_request(pending_new, ur_dup);
1140 tcore_pending_set_send_callback(pending_new, on_confirmation_sms_message_send, NULL);
1141 tcore_hal_send_request(tcore_object_get_hal(o), pending_new);
1143 //free the consumed token
1144 tcore_at_tok_free(tokens);
1151 //free the consumed token
1153 tcore_at_tok_free(tokens);
1158 err("Response NOK");
1160 respStoredMsgCnt->result = result;
1161 tcore_user_request_send_response(ur, TRESP_SMS_GET_STORED_MSG_COUNT, sizeof(struct tresp_sms_get_storedMsgCnt), &respStoredMsgCnt);
1168 static void on_response_get_sca(TcorePending *pending, int data_len, const void *data, void *user_data)
1170 const TcoreATResponse *at_response = data;
1171 struct tresp_sms_get_sca respGetSca;
1172 UserRequest *user_req = NULL;
1174 GSList *tokens = NULL;
1175 const char *sca_tok_addr;
1176 char *gslist_line = NULL, *sca_addr = NULL, *sca_toa = NULL;
1180 memset(&respGetSca, 0, sizeof(respGetSca));
1181 respGetSca.result = SMS_DEVICE_FAILURE;
1183 user_req = tcore_pending_ref_user_request(pending);
1185 if (at_response->success) {
1187 if (at_response->lines) {
1188 gslist_line = (char *)at_response->lines->data;
1190 tokens = tcore_at_tok_new(gslist_line);
1191 sca_tok_addr = g_slist_nth_data(tokens, 0);
1192 sca_toa = g_slist_nth_data(tokens, 1);
1194 sca_addr = tcore_at_tok_extract(sca_tok_addr);
1195 if ((NULL != sca_addr)
1196 && (NULL != sca_toa)) {
1197 dbg("sca_addr: [%s]. sca_toa: [%s]", sca_addr, sca_toa);
1199 respGetSca.scaAddress.dialNumLen = strlen(sca_addr);
1201 if (145 == atoi(sca_toa)) {
1202 respGetSca.scaAddress.typeOfNum = SIM_TON_INTERNATIONAL;
1204 respGetSca.scaAddress.typeOfNum = SIM_TON_NATIONAL;
1207 respGetSca.scaAddress.numPlanId = 0;
1209 memcpy(respGetSca.scaAddress.diallingNum, sca_addr, strlen(sca_addr));
1211 dbg("len [%d], sca_addr [%s], TON [%d], NPI [%d]", respGetSca.scaAddress.dialNumLen, respGetSca.scaAddress.diallingNum, respGetSca.scaAddress.typeOfNum, respGetSca.scaAddress.numPlanId);
1213 respGetSca.result = SMS_SENDSMS_SUCCESS;
1215 err("sca_addr OR sca_toa NULL");
1221 dbg("Response NOK");
1224 tcore_user_request_send_response(user_req, TRESP_SMS_GET_SCA, sizeof(respGetSca), &respGetSca);
1226 tcore_at_tok_free(tokens);
1233 static void on_response_set_sca(TcorePending *pending, int data_len, const void *data, void *user_data)
1236 Response is expected in this format
1242 //copies the AT response data to resp
1243 const TcoreATResponse *atResp = data;
1244 struct tresp_sms_set_sca respSetSca;
1246 memset(&respSetSca, 0, sizeof(struct tresp_sms_set_sca));
1248 ur = tcore_pending_ref_user_request(pending);
1250 dbg("no user_request");
1254 if (atResp->success > 0) {
1256 respSetSca.result = SMS_SUCCESS;
1258 dbg("RESPONSE NOK");
1259 respSetSca.result = SMS_DEVICE_FAILURE;
1262 tcore_user_request_send_response(ur, TRESP_SMS_SET_SCA, sizeof(struct tresp_sms_set_sca), &respSetSca);
1267 static void on_response_get_cb_config(TcorePending *p, int data_len, const void *data, void *user_data)
1270 struct tresp_sms_get_cb_config respGetCbConfig;
1271 const TcoreATResponse *atResp = data;
1272 GSList *tokens=NULL;
1274 char *pResp = NULL, *line = NULL;
1277 memset(&respGetCbConfig, 0, sizeof(struct tresp_sms_get_cb_config));
1278 respGetCbConfig.result = SMS_DEVICE_FAILURE;
1280 ur = tcore_pending_ref_user_request(p);
1282 dbg("no user_request");
1286 respGetCbConfig.cbConfig.net3gppType = SMS_NETTYPE_3GPP;
1288 if (atResp->success) {
1290 if (atResp->lines) {
1291 line = (char*)atResp->lines->data;
1293 dbg("line is %s",line);
1294 tokens = tcore_at_tok_new(line);
1295 pResp = g_slist_nth_data(tokens, 0);
1298 respGetCbConfig.cbConfig.cbEnabled = mode;
1300 pResp = g_slist_nth_data(tokens, 1);
1302 GSList *cb_tokens = NULL;
1303 char *cb_mid_str = NULL;
1304 int num_cb_tokens = 0;
1305 char *mid_tok = NULL;
1306 char *first_tok = NULL, *second_tok = NULL;
1308 // 0,1,5,320-478,922
1309 cb_mid_str = util_removeQuotes(pResp);
1310 cb_tokens = tcore_at_tok_new((const char *) cb_mid_str);
1314 num_cb_tokens = g_slist_length(cb_tokens);
1315 dbg("num_cb_tokens = %d", num_cb_tokens);
1317 if (num_cb_tokens == 0) {
1318 if (mode == 1) { // Enable all CBs
1319 respGetCbConfig.cbConfig.msgIdRangeCount = 1;
1320 respGetCbConfig.cbConfig.msgIDs[0].net3gpp.fromMsgId = 0x0000;
1321 respGetCbConfig.cbConfig.msgIDs[0].net3gpp.toMsgId = SMS_GSM_SMS_CBMI_LIST_SIZE_MAX + 1;
1322 respGetCbConfig.cbConfig.msgIDs[0].net3gpp.selected = TRUE;
1323 respGetCbConfig.result = SMS_SENDSMS_SUCCESS;
1324 } else { // all CBs disabled
1325 respGetCbConfig.cbConfig.msgIdRangeCount = 0;
1326 respGetCbConfig.cbConfig.msgIDs[0].net3gpp.selected = FALSE;
1327 respGetCbConfig.result = SMS_SENDSMS_SUCCESS;
1330 respGetCbConfig.cbConfig.msgIdRangeCount = 0;
1331 respGetCbConfig.cbConfig.msgIDs[0].net3gpp.selected = FALSE;
1332 respGetCbConfig.result = SMS_SENDSMS_SUCCESS;
1335 for (i = 0; i < num_cb_tokens; i++) {
1336 respGetCbConfig.cbConfig.msgIDs[i].net3gpp.selected = TRUE;
1337 respGetCbConfig.cbConfig.msgIdRangeCount++;
1339 mid_tok = tcore_at_tok_nth(cb_tokens, i);
1340 first_tok = strtok(mid_tok, delim);
1341 second_tok = strtok(NULL, delim);
1343 if ((first_tok != NULL) && (second_tok != NULL)) { // mids in range (320-478)
1344 dbg("inside if mid_range");
1345 respGetCbConfig.cbConfig.msgIDs[i].net3gpp.fromMsgId = atoi(first_tok);
1346 respGetCbConfig.cbConfig.msgIDs[i].net3gpp.toMsgId = atoi(second_tok);
1347 } // single mid value (0,1,5, 922)
1349 respGetCbConfig.cbConfig.msgIDs[i].net3gpp.fromMsgId = atoi(mid_tok);
1350 respGetCbConfig.cbConfig.msgIDs[i].net3gpp.toMsgId = atoi(mid_tok);
1356 respGetCbConfig.cbConfig.msgIdRangeCount = 1;
1357 respGetCbConfig.cbConfig.msgIDs[0].net3gpp.fromMsgId = 0x0000;
1358 respGetCbConfig.cbConfig.msgIDs[0].net3gpp.toMsgId = SMS_GSM_SMS_CBMI_LIST_SIZE_MAX + 1;
1359 respGetCbConfig.cbConfig.msgIDs[0].net3gpp.selected = TRUE;
1360 respGetCbConfig.result = SMS_SENDSMS_SUCCESS;
1362 respGetCbConfig.cbConfig.msgIdRangeCount = 0;
1363 respGetCbConfig.cbConfig.msgIDs[0].net3gpp.selected = FALSE;
1364 respGetCbConfig.result = SMS_SENDSMS_SUCCESS;
1368 dbg("line is NULL");
1371 dbg("atresp->lines is NULL");
1374 dbg("RESPONSE NOK");
1377 tcore_user_request_send_response(ur, TRESP_SMS_GET_CB_CONFIG, sizeof(struct tresp_sms_get_cb_config), &respGetCbConfig);
1380 tcore_at_tok_free(tokens);
1385 static void on_response_set_cb_config(TcorePending *pending, int data_len, const void *data, void *user_data)
1388 Response is expected in this format
1395 const TcoreATResponse *resp = data;
1397 const char *line = NULL;
1398 GSList *tokens=NULL;
1400 struct tresp_sms_set_cb_config respSetCbConfig = {0,};
1402 memset(&respSetCbConfig, 0, sizeof(struct tresp_sms_set_cb_config));
1404 ur = tcore_pending_ref_user_request(pending);
1405 respSetCbConfig.result = SMS_SENDSMS_SUCCESS;
1407 if (resp->success > 0) {
1410 dbg("RESPONSE NOK");
1411 line = (const char*)resp->final_response;
1412 tokens = tcore_at_tok_new(line);
1414 if (g_slist_length(tokens) < 1) {
1415 dbg("err cause not specified or string corrupted");
1416 respSetCbConfig.result = SMS_DEVICE_FAILURE;
1418 response = atoi(g_slist_nth_data(tokens, 0));
1419 dbg("response is %d", response);
1420 /* TODO: CMEE error mapping is required. */
1421 respSetCbConfig.result = SMS_DEVICE_FAILURE;
1425 dbg("no user_request");
1429 tcore_user_request_send_response(ur, TRESP_SMS_SET_CB_CONFIG, sizeof(struct tresp_sms_set_cb_config), &respSetCbConfig);
1432 tcore_at_tok_free(tokens);
1437 static void on_response_set_mem_status(TcorePending *p, int data_len, const void *data, void *user_data)
1440 struct tresp_sms_set_mem_status respSetMemStatus = {0,};
1441 const TcoreATResponse *resp = data;
1443 memset(&respSetMemStatus, 0, sizeof(struct tresp_sms_set_mem_status));
1445 if (resp->success > 0) {
1447 respSetMemStatus.result = SMS_SENDSMS_SUCCESS;
1449 dbg("RESPONSE NOK");
1450 respSetMemStatus.result = SMS_DEVICE_FAILURE;
1453 ur = tcore_pending_ref_user_request(p);
1455 dbg("no user_request");
1459 tcore_user_request_send_response(ur, TRESP_SMS_SET_MEM_STATUS, sizeof(struct tresp_sms_set_mem_status), &respSetMemStatus);
1464 static void on_response_set_msg_status(TcorePending *pending, int data_len, const void *data, void *user_data)
1467 struct tresp_sms_set_msg_status respMsgStatus = {0, };
1468 const TcoreATResponse *atResp = data;
1469 int response = 0, sw1 = 0, sw2 = 0;
1470 const char *line = NULL;
1472 GSList *tokens = NULL;
1476 memset(&respMsgStatus, 0, sizeof(struct tresp_sms_set_msg_status));
1477 respMsgStatus.result = SMS_DEVICE_FAILURE;
1479 ur = tcore_pending_ref_user_request(pending);
1481 if (atResp->success > 0) {
1484 if (atResp->lines) {
1485 line = (const char *) atResp->lines->data;
1486 tokens = tcore_at_tok_new(line);
1487 pResp = g_slist_nth_data(tokens, 0);
1488 if (pResp != NULL) {
1493 pResp = g_slist_nth_data(tokens, 1);
1494 if (pResp != NULL) {
1496 if ((sw1 == AT_SW1_SUCCESS) && (sw2 == 0)) {
1497 respMsgStatus.result = SMS_SENDSMS_SUCCESS;
1502 pResp = g_slist_nth_data(tokens, 3);
1504 if (pResp != NULL) {
1505 response = atoi(pResp);
1506 dbg("response is %d", response);
1512 dbg("RESPONSE NOK");
1515 tcore_user_request_send_response(ur, TRESP_SMS_SET_MSG_STATUS , sizeof(struct tresp_sms_set_msg_status), &respMsgStatus);
1518 tcore_at_tok_free(tokens);
1524 static void on_response_get_sms_params(TcorePending *pending, int data_len, const void *data, void *user_data)
1527 struct tresp_sms_get_params respGetParams ;
1528 const TcoreATResponse *atResp = data;
1529 int sw1 = 0, sw2 = 0;
1530 const char *line = NULL;
1532 GSList *tokens=NULL;
1533 char *hexData = NULL;
1534 char *recordData = NULL;
1537 memset(&respGetParams, 0, sizeof(struct tresp_sms_get_params));
1538 respGetParams.result = SMS_DEVICE_FAILURE;
1540 ur = tcore_pending_ref_user_request(pending);
1542 if (atResp->success > 0) {
1545 if (atResp->lines) {
1546 line = (const char *) atResp->lines->data;
1547 tokens = tcore_at_tok_new(line);
1548 pResp = g_slist_nth_data(tokens, 0);
1549 if (pResp != NULL) {
1551 dbg("sw1 is %d", sw1);
1555 pResp = g_slist_nth_data(tokens, 1);
1556 if (pResp != NULL) {
1558 dbg("sw2 is %d", sw2);
1559 if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
1560 respGetParams.result = SMS_SENDSMS_SUCCESS;
1565 pResp = g_slist_nth_data(tokens, 2);
1566 if (pResp != NULL) {
1567 hexData = util_removeQuotes(pResp);
1569 recordData = util_hexStringToBytes(hexData);
1570 util_hex_dump(" ", strlen(hexData) / 2, recordData);
1572 respGetParams.paramsInfo.recordLen = strlen(hexData) / 2;
1574 util_sms_decode_smsParameters((unsigned char *) recordData, strlen(hexData) / 2, &(respGetParams.paramsInfo));
1575 respGetParams.result = SMS_SENDSMS_SUCCESS;
1577 for (i = 0; i < (int) respGetParams.paramsInfo.tpSvcCntrAddr.dialNumLen; i++)
1578 dbg("SCAddr = %d [%02x]", i, respGetParams.paramsInfo.tpSvcCntrAddr.diallingNum[i]);
1585 tcore_at_tok_free(tokens);
1588 dbg("RESPONSE NOK");
1591 tcore_user_request_send_response(ur, TRESP_SMS_GET_PARAMS, sizeof(struct tresp_sms_get_params), &respGetParams);
1597 static void on_response_set_sms_params(TcorePending *pending, int data_len, const void *data, void *user_data)
1600 struct tresp_sms_set_params respSetParams = {0, };
1601 const TcoreATResponse *atResp = data;
1602 int sw1 =0 , sw2 = 0;
1603 const char *line = NULL;
1605 GSList *tokens=NULL;
1608 memset(&respSetParams, 0, sizeof(struct tresp_sms_set_params));
1609 ur = tcore_pending_ref_user_request(pending);
1611 respSetParams.result = SMS_DEVICE_FAILURE;
1613 if (atResp->success > 0) {
1616 if (atResp->lines) {
1617 line = (const char *) atResp->lines->data;
1618 tokens = tcore_at_tok_new(line);
1619 pResp = g_slist_nth_data(tokens, 0);
1620 if (pResp != NULL) {
1626 pResp = g_slist_nth_data(tokens, 1);
1627 if (pResp != NULL) {
1629 if (((sw1 == AT_SW1_SUCCESS) && (sw2 == AT_SW2_SUCCESS)) || (sw1 == 0x91)) {
1630 respSetParams.result = SMS_SENDSMS_SUCCESS;
1639 dbg("RESPONSE NOK");
1642 tcore_user_request_send_response(ur, TRESP_SMS_SET_PARAMS , sizeof(struct tresp_sms_set_params), &respSetParams);
1645 tcore_at_tok_free(tokens);
1651 static void on_response_get_paramcnt(TcorePending *p, int data_len, const void *data, void *user_data)
1653 UserRequest *ur = NULL;
1654 struct tresp_sms_get_paramcnt respGetParamCnt = {0, };
1655 const TcoreATResponse *atResp = data;
1656 char *line = NULL , *pResp = NULL;
1657 int sw1 = 0 , sw2 = 0, *smsp_record_len = NULL;
1659 GSList *tokens=NULL;
1660 CoreObject *co_sim = NULL; //need this to get the sim type GSM/USIM
1661 TcorePlugin *plugin = NULL;
1665 ur = tcore_pending_ref_user_request(p);
1666 respGetParamCnt.result = SMS_DEVICE_FAILURE;
1668 if (atResp->success > 0) {
1671 if (atResp->lines) {
1672 line = (char *) atResp->lines->data;
1674 dbg("line is %s", line);
1676 tokens = tcore_at_tok_new(line);
1677 pResp = g_slist_nth_data(tokens, 0);
1678 if (pResp != NULL) {
1683 pResp = g_slist_nth_data(tokens, 1);
1684 if (pResp != NULL) {
1686 if ((sw1 == 144) && (sw2 == 0)) {
1687 respGetParamCnt.result = SMS_SENDSMS_SUCCESS;
1692 pResp = g_slist_nth_data(tokens, 2);
1693 if (pResp != NULL) {
1694 char *hexData = NULL;
1695 char *recordData = NULL;
1696 hexData = util_removeQuotes(pResp);
1698 /*1. SIM access success case*/
1699 if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
1700 unsigned char tag_len = 0; /* 1 or 2 bytes ??? */
1702 char num_of_records = 0;
1703 unsigned char file_id_len = 0;
1704 unsigned short file_id = 0;
1705 unsigned short file_size = 0;
1706 unsigned short file_type = 0;
1707 unsigned short arr_file_id = 0;
1708 int arr_file_id_rec_num = 0;
1710 /* handling only last 3 bits */
1711 unsigned char file_type_tag = 0x07;
1712 unsigned char *ptr_data;
1714 recordData = util_hexStringToBytes(hexData);
1715 util_hex_dump(" ", strlen(hexData)/2, recordData);
1717 ptr_data = (unsigned char *)recordData;
1719 co_sim = tcore_plugin_ref_core_object(tcore_pending_ref_plugin(p), CORE_OBJECT_TYPE_SIM);
1720 sim_type = tcore_sim_get_type(co_sim);
1721 dbg("sim type is %d",sim_type);
1723 if (sim_type == SIM_TYPE_USIM) {
1725 ETSI TS 102 221 v7.9.0
1727 '62' FCP template tag
1728 - Response for an EF
1729 '82' M File Descriptor
1730 '83' M File Identifier
1731 'A5' O Proprietary information
1732 '8A' M Life Cycle Status Integer
1733 '8B', '8C' or 'AB' C1 Security attributes
1735 '81' O Total file size
1736 '88' O Short File Identifier (SFI)
1739 /* rsim.res_len has complete data length received */
1741 /* FCP template tag - File Control Parameters tag*/
1742 if (*ptr_data == 0x62) {
1743 /* parse complete FCP tag*/
1744 /* increment to next byte */
1746 tag_len = *ptr_data++;
1747 dbg("tag_len: [%d]", tag_len);
1748 /* FCP file descriptor - file type, accessibility, DF, ADF etc*/
1749 if (*ptr_data == 0x82) {
1750 /* increment to next byte */
1754 /* unsigned char file_desc_len = *ptr_data++;*/
1755 /* dbg("file descriptor length: [%d]", file_desc_len);*/
1756 /* TBD: currently capture only file type : ignore sharable, non sharable, working, internal etc*/
1757 /* consider only last 3 bits*/
1758 file_type_tag = file_type_tag & (*ptr_data);
1760 switch (file_type_tag) {
1761 /* increment to next byte */
1765 dbg("Getting FileType: [Transparent file type]");
1766 /* increment to next byte */
1768 file_type = 0x01; //SIM_FTYPE_TRANSPARENT
1769 /* data coding byte - value 21 */
1774 dbg("Getting FileType: [Linear fixed file type]");
1775 /* increment to next byte */
1777 /* data coding byte - value 21 */
1780 memcpy(&record_len, ptr_data, 2);
1782 record_len = SMS_SWAPBYTES16(record_len);
1783 ptr_data = ptr_data + 2;
1784 num_of_records = *ptr_data++;
1785 /* Data lossy conversation from enum (int) to unsigned char */
1786 file_type = 0x02; // SIM_FTYPE_LINEAR_FIXED
1790 dbg(" Cyclic fixed file type");
1791 /* increment to next byte */
1793 /* data coding byte - value 21 */
1796 memcpy(&record_len, ptr_data, 2);
1798 record_len = SMS_SWAPBYTES16(record_len);
1799 ptr_data = ptr_data + 2;
1800 num_of_records = *ptr_data++;
1801 file_type = 0x04; //SIM_FTYPE_CYCLIC
1805 dbg("not handled file type [0x%x]", *ptr_data);
1809 dbg("INVALID FCP received - DEbug!");
1812 tcore_at_tok_free(tokens);
1816 /*File identifier - file id?? */ // 0x84,0x85,0x86 etc are currently ignored and not handled
1817 if (*ptr_data == 0x83) {
1818 /* increment to next byte */
1820 file_id_len = *ptr_data++;
1821 memcpy(&file_id, ptr_data, file_id_len);
1823 file_id = SMS_SWAPBYTES16(file_id);
1824 ptr_data = ptr_data + 2;
1825 dbg("Getting FileID=[0x%x]", file_id);
1827 dbg("INVALID FCP received - DEbug!");
1830 tcore_at_tok_free(tokens);
1834 /* proprietary information */
1835 if (*ptr_data == 0xA5) {
1836 unsigned short prop_len;
1837 /* increment to next byte */
1840 prop_len = *ptr_data;
1842 ptr_data = ptr_data + prop_len + 1;
1844 dbg("INVALID FCP received - DEbug!");
1847 /* life cycle status integer [8A][length:0x01][status]*/
1850 00000000 : No information given
1851 00000001 : creation state
1852 00000011 : initialization state
1853 000001-1 : operation state -activated
1854 000001-0 : operation state -deactivated
1855 000011-- : Termination state
1856 b8~b5 !=0, b4~b1=X : Proprietary
1857 Any other value : RFU
1859 if (*ptr_data == 0x8A) {
1860 /* increment to next byte */
1862 /* length - value 1 */
1865 switch (*ptr_data) {
1868 dbg("[RX] Operation State: DEACTIVATED");
1874 dbg("[RX] Operation State: ACTIVATED");
1879 dbg("[RX] DEBUG! LIFE CYCLE STATUS: [0x%x]",*ptr_data);
1885 /* related to security attributes : currently not handled*/
1886 if (*ptr_data == 0x86 || *ptr_data == 0x8B || *ptr_data == 0x8C || *ptr_data == 0xAB) {
1887 /* increment to next byte */
1889 /* if tag length is 3 */
1890 if (*ptr_data == 0x03) {
1891 /* increment to next byte */
1894 memcpy(&arr_file_id, ptr_data, 2);
1896 arr_file_id = SMS_SWAPBYTES16(arr_file_id);
1897 ptr_data = ptr_data + 2;
1898 arr_file_id_rec_num = *ptr_data++;
1899 dbg("arr_file_id_rec_num: [%d]", arr_file_id_rec_num);
1901 /* if tag length is not 3 */
1902 /* ignoring bytes */
1903 // ptr_data = ptr_data + 4;
1904 dbg("Useless security attributes, so jump to next tag");
1905 ptr_data = ptr_data + (*ptr_data + 1);
1908 dbg("INVALID FCP received[0x%x] - DEbug!", *ptr_data);
1911 tcore_at_tok_free(tokens);
1915 dbg("Current ptr_data value is [%x]", *ptr_data);
1917 /* file size excluding structural info*/
1918 if (*ptr_data == 0x80) {
1919 /* for EF file size is body of file and for Linear or cyclic it is
1920 * number of recXsizeof(one record)
1922 /* increment to next byte */
1924 /* length is 1 byte - value is 2 bytes or more */
1926 memcpy(&file_size, ptr_data, 2);
1928 file_size = SMS_SWAPBYTES16(file_size);
1929 ptr_data = ptr_data + 2;
1931 dbg("INVALID FCP received - DEbug!");
1934 tcore_at_tok_free(tokens);
1938 /* total file size including structural info*/
1939 if (*ptr_data == 0x81) {
1941 /* increment to next byte */
1945 dbg("len: [%d]", len);
1947 ptr_data = ptr_data + 3;
1949 dbg("INVALID FCP received - DEbug!");
1950 /* 0x81 is optional tag?? check out! so do not return -1 from here! */
1953 /*short file identifier ignored*/
1954 if (*ptr_data == 0x88) {
1955 dbg("0x88: Do Nothing");
1959 dbg("INVALID FCP received - DEbug!");
1962 tcore_at_tok_free(tokens);
1965 } else if (sim_type == SIM_TYPE_GSM) {
1966 unsigned char gsm_specific_file_data_len = 0;
1967 /* ignore RFU byte1 and byte2 */
1971 //file_size = p_info->response_len;
1972 memcpy(&file_size, ptr_data, 2);
1974 file_size = SMS_SWAPBYTES16(file_size);
1975 /* parsed file size */
1976 ptr_data = ptr_data + 2;
1978 memcpy(&file_id, ptr_data, 2);
1979 file_id = SMS_SWAPBYTES16(file_id);
1980 dbg(" FILE id --> [%x]", file_id);
1981 ptr_data = ptr_data + 2;
1982 /* save file type - transparent, linear fixed or cyclic */
1983 file_type_tag = (*(ptr_data + 7));
1985 switch (*ptr_data) {
1988 dbg(" RFU file type- not handled - Debug!");
1993 dbg(" MF file type - not handled - Debug!");
1998 dbg(" DF file type - not handled - Debug!");
2003 dbg(" EF file type [%d] ", file_type_tag);
2004 /* increment to next byte */
2007 if (file_type_tag == 0x00 || file_type_tag == 0x01) {
2008 /* increament to next byte as this byte is RFU */
2011 (file_type_tag == 0x00) ? 0x01 : 0x02; // SIM_FTYPE_TRANSPARENT:SIM_FTYPE_LINEAR_FIXED;
2013 /* increment to next byte */
2015 /* For a cyclic EF all bits except bit 7 are RFU; b7=1 indicates that */
2016 /* the INCREASE command is allowed on the selected cyclic file. */
2017 file_type = 0x04; // SIM_FTYPE_CYCLIC;
2019 /* bytes 9 to 11 give SIM file access conditions */
2021 /* byte 10 has one nibble that is RF U and another for INCREASE which is not used currently */
2023 /* byte 11 is invalidate and rehabilate nibbles */
2025 /* byte 12 - file status */
2027 /* byte 13 - GSM specific data */
2028 gsm_specific_file_data_len = *ptr_data;
2029 dbg("gsm_specific_file_data_len: [%d]", gsm_specific_file_data_len);
2031 /* byte 14 - structure of EF - transparent or linear or cyclic , already saved above */
2033 /* byte 15 - length of record for linear and cyclic , for transparent it is set to 0x00. */
2034 record_len = *ptr_data;
2035 dbg("record length[%d], file size[%d]", record_len, file_size);
2037 if (record_len != 0)
2038 num_of_records = (file_size / record_len);
2040 dbg("Number of records [%d]", num_of_records);
2044 dbg(" not handled file type");
2048 dbg(" Card Type - UNKNOWN [%d]", sim_type);
2051 dbg("EF[0x%x] size[%ld] Type[0x%x] NumOfRecords[%ld] RecordLen[%ld]", file_id, file_size, file_type, num_of_records, record_len);
2053 respGetParamCnt.recordCount = num_of_records;
2054 respGetParamCnt.result = SMS_SUCCESS;
2056 //TO Store smsp record length in the property
2057 plugin = tcore_pending_ref_plugin(p);
2058 smsp_record_len = tcore_plugin_ref_property(plugin, "SMSPRECORDLEN");
2059 memcpy(smsp_record_len, &record_len, sizeof(int));
2064 /*2. SIM access fail case*/
2065 dbg("SIM access fail");
2066 respGetParamCnt.result = SMS_UNKNOWN;
2069 dbg("presp is NULL");
2072 dbg("line is blank");
2075 dbg("RESPONSE NOK");
2078 tcore_user_request_send_response(ur, TRESP_SMS_GET_PARAMCNT, sizeof(struct tresp_sms_get_paramcnt), &respGetParamCnt);
2081 tcore_at_tok_free(tokens);
2087 static void _response_get_efsms_data(TcorePending *p, int data_len, const void *data, void *user_data)
2089 UserRequest *ur = NULL;
2090 UserRequest *dup_ur = NULL;
2091 struct tresp_sms_set_msg_status resp_msg_status = {0,};
2092 const struct treq_sms_set_msg_status *req_msg_status = NULL ;
2094 const TcoreATResponse *resp = data;
2095 char *encoded_data = NULL;
2096 char msg_status = 0;
2098 GSList *tokens=NULL;
2099 const char *line = NULL;
2103 TcoreHal *hal = NULL;
2104 TcoreATRequest *atreq = NULL;
2105 TcorePending *pending = NULL;
2106 gchar *cmd_str = NULL;
2108 ur = tcore_pending_ref_user_request(p);
2110 req_msg_status = tcore_user_request_ref_data(ur, NULL);
2112 resp_msg_status.result = SMS_DEVICE_FAILURE;
2114 hal = tcore_object_get_hal(tcore_pending_ref_core_object(pending));
2115 dbg("msgStatus: [%x], index [%x]", req_msg_status->msgStatus, req_msg_status->index);
2117 if (resp->success <= 0) {
2124 line = (const char *) resp->lines->data;
2125 tokens = tcore_at_tok_new(line);
2126 if (g_slist_length(tokens) != 3) {
2127 msg("invalid message");
2131 sw1 = atoi(g_slist_nth_data(tokens, 0));
2132 sw2 = atoi(g_slist_nth_data(tokens, 1));
2133 pResp = g_slist_nth_data(tokens, 2);
2135 if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
2136 switch (req_msg_status->msgStatus) {
2137 case SMS_STATUS_READ:
2141 case SMS_STATUS_UNREAD:
2145 case SMS_STATUS_UNSENT:
2149 case SMS_STATUS_SENT:
2153 case SMS_STATUS_DELIVERED:
2157 case SMS_STATUS_DELIVERY_UNCONFIRMED:
2161 case SMS_STATUS_MESSAGE_REPLACED:
2162 case SMS_STATUS_RESERVED:
2168 encoded_data = util_removeQuotes(pResp);
2170 //overwrite Status byte information
2171 util_byte_to_hex((const char *)&msg_status, (char *)encoded_data, 1);
2173 //Update EF-SMS with just status byte overwritten, rest 175 bytes are same as received in read information
2174 cmd_str = g_strdup_printf("AT+CRSM=220,28476,%d, 4, %d, \"%s\"", (req_msg_status->index+1), PDU_LEN_MAX, encoded_data);
2175 atreq = tcore_at_request_new((const char *)cmd_str, "+CRSM", TCORE_AT_SINGLELINE);
2176 pending = tcore_pending_new(tcore_pending_ref_core_object(pending), 0);
2177 if (NULL == cmd_str || NULL == atreq || NULL == pending) {
2178 err("Out of memory. Unable to proceed");
2179 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
2181 //free memory we own
2183 g_free(encoded_data);
2184 util_sms_free_memory(atreq);
2185 util_sms_free_memory(pending);
2190 util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
2192 dup_ur = tcore_user_request_ref(ur);
2194 tcore_pending_set_request_data(pending, 0, atreq);
2195 tcore_pending_set_response_callback(pending, on_response_set_msg_status, NULL);
2196 tcore_pending_link_user_request(pending, dup_ur);
2197 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
2198 tcore_hal_send_request(hal, pending);
2201 g_free(encoded_data);
2203 resp_msg_status.result = SMS_SENDSMS_SUCCESS;
2209 tcore_at_tok_free(tokens);
2211 tcore_user_request_send_response(ur, TRESP_SMS_SET_MSG_STATUS , sizeof(struct tresp_sms_set_msg_status), &resp_msg_status);
2218 /*=============================================================
2220 ==============================================================*/
2221 static TReturn send_umts_msg(CoreObject *co_sms, UserRequest *ur)
2223 const struct treq_sms_send_msg *send_msg;
2224 const unsigned char *tpdu_byte_data;
2225 const unsigned char *sca_byte_data;
2228 int pdu_hex_len = 0;
2229 char buf[HEX_PDU_LEN_MAX];
2230 char pdu[PDU_LEN_MAX];
2237 send_msg = tcore_user_request_ref_data(ur, NULL);
2239 /* Validating the Message Format */
2240 if (SMS_NETTYPE_3GPP == send_msg->msgDataPackage.format) {
2241 info("3gpp format received");
2243 info("invalid format received");
2244 return TCORE_RETURN_EINVAL;
2247 tpdu_byte_data = send_msg->msgDataPackage.tpduData;
2248 sca_byte_data = send_msg->msgDataPackage.sca;
2251 /* TPDU length is in byte */
2252 tpdu_byte_len = send_msg->msgDataPackage.msgLength;
2253 dbg("TDPU length: [%d]", tpdu_byte_len);
2254 dbg("SCA semi-octet length: [%d]", sca_byte_data[0]);
2256 /* Use same Radio Resource Channel */
2257 mms = send_msg->more;
2259 /* Prepare PDU for hex encoding */
2260 pdu_byte_len = __util_sms_encode_pdu(sca_byte_data, tpdu_byte_data,
2261 tpdu_byte_len, pdu);
2263 pdu_hex_len = (int) __util_sms_encode_hex((unsigned char *) pdu,
2266 dbg("PDU hexadecimal length: [%d]", pdu_hex_len);
2269 cmd_str = g_strdup_printf("AT+CMMS=%d", mms);
2271 ret = tcore_prepare_and_send_at_request(co_sms, cmd_str, NULL,
2272 TCORE_AT_NO_RESULT, NULL, NULL, NULL,
2273 on_confirmation_sms_message_send,
2274 NULL, 0, NULL, NULL);
2275 if (ret != TCORE_RETURN_SUCCESS) {
2276 err("Failed to prepare and send AT request");
2283 cmd_str = g_strdup_printf("AT+CMGS=%d\r%s\x1A", tpdu_byte_len, buf);
2285 ret = tcore_prepare_and_send_at_request(co_sms, cmd_str, "+CMGS:",
2286 TCORE_AT_SINGLELINE, ur,
2287 on_response_send_umts_msg, NULL,
2288 on_confirmation_sms_message_send, NULL,
2290 if (ret != TCORE_RETURN_SUCCESS)
2291 err("Failed to prepare and send AT request");
2301 static TReturn read_msg(CoreObject *obj, UserRequest *ur)
2303 gchar *cmd_str = NULL;
2304 TcoreHal *hal = NULL;
2305 TcoreATRequest *atreq = NULL;
2306 TcorePending *pending = NULL;
2307 const struct treq_sms_read_msg *readMsg = NULL;
2311 readMsg = tcore_user_request_ref_data(ur, NULL);
2312 hal = tcore_object_get_hal(obj);
2313 if (NULL == readMsg || NULL == hal) {
2314 err("NULL input. Unable to proceed");
2315 dbg("readMsg: [%p], hal: [%p]", readMsg, hal);
2318 return TCORE_RETURN_EINVAL;
2321 if(FALSE == tcore_hal_get_power_state(hal)){
2322 dbg("cp not ready/n");
2323 return TCORE_RETURN_ENOSYS;
2325 dbg("index: [%d]", readMsg->index);
2327 cmd_str = g_strdup_printf("AT+CMGR=%d", readMsg->index); //IMC index is one ahead of TAPI
2328 atreq = tcore_at_request_new((const char *)cmd_str, "+CMGR", TCORE_AT_PDU);
2329 pending = tcore_pending_new(obj, 0);
2331 if (NULL == cmd_str || NULL == atreq || NULL == pending) {
2332 err("Out of memory. Unable to proceed");
2333 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
2335 //free memory we own
2337 util_sms_free_memory(atreq);
2338 util_sms_free_memory(pending);
2341 return TCORE_RETURN_ENOMEM;
2344 util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
2346 tcore_pending_set_request_data(pending, 0, atreq);
2347 tcore_pending_set_response_callback(pending, on_response_read_msg, (void *)(uintptr_t)(readMsg->index)); //storing index as user data for response
2348 tcore_pending_link_user_request(pending, ur);
2349 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
2350 tcore_hal_send_request(hal, pending);
2355 return TCORE_RETURN_SUCCESS;
2358 static TReturn save_msg(CoreObject *obj, UserRequest *ur)
2360 gchar *cmd_str = NULL;
2361 TcoreHal *hal = NULL;
2362 TcoreATRequest *atreq = NULL;
2363 TcorePending *pending = NULL;
2364 const struct treq_sms_save_msg *saveMsg = NULL;
2365 int ScLength = 0, pdu_len = 0, stat = 0;
2366 char buf[2*(SMS_SMSP_ADDRESS_LEN+SMS_SMDATA_SIZE_MAX)+1] = {0};
2367 char *hex_pdu = NULL;
2371 saveMsg = tcore_user_request_ref_data(ur, NULL);
2372 hal = tcore_object_get_hal(obj);
2373 if (NULL == saveMsg || NULL == hal) {
2374 err("NULL input. Unable to proceed");
2375 dbg("saveMsg: [%p], hal: [%p]", saveMsg, hal);
2378 return TCORE_RETURN_EINVAL;
2380 if(FALSE == tcore_hal_get_power_state(hal)){
2381 dbg("cp not ready/n");
2382 return TCORE_RETURN_ENOSYS;
2385 dbg("msgStatus: %x, msgLength: [%d]", saveMsg->msgStatus, saveMsg->msgDataPackage.msgLength);
2386 util_hex_dump(" ", (SMS_SMDATA_SIZE_MAX+1), (void *)saveMsg->msgDataPackage.tpduData);
2387 util_hex_dump(" ", SMS_SMSP_ADDRESS_LEN, (void *)saveMsg->msgDataPackage.sca);
2389 switch (saveMsg->msgStatus) {
2390 case SMS_STATUS_READ:
2394 case SMS_STATUS_UNREAD:
2395 stat = AT_REC_UNREAD;
2398 case SMS_STATUS_SENT:
2402 case SMS_STATUS_UNSENT:
2403 stat = AT_STO_UNSENT;
2407 err("Invalid msgStatus");
2409 return TCORE_RETURN_EINVAL;
2412 if ((saveMsg->msgDataPackage.msgLength > 0)
2413 && (saveMsg->msgDataPackage.msgLength <= SMS_SMDATA_SIZE_MAX)) {
2414 ScLength = (int)saveMsg->msgDataPackage.sca[0];
2417 dbg("ScLength = %d", ScLength);
2422 memcpy(&buf[1], saveMsg->msgDataPackage.sca, ScLength);
2425 memcpy(&buf[ScLength+1], saveMsg->msgDataPackage.tpduData, saveMsg->msgDataPackage.msgLength);
2427 pdu_len= saveMsg->msgDataPackage.msgLength + ScLength + 1;
2428 dbg("pdu_len: [%d]", pdu_len);
2430 hex_pdu = malloc(pdu_len * 2 + 1);
2431 util_hex_dump(" ", sizeof(buf), (void *)buf);
2433 memset (hex_pdu, 0x00, pdu_len * 2 + 1);
2435 util_byte_to_hex((const char *)buf, (char *)hex_pdu, pdu_len);
2437 //AT+CMGW=<length>[,<stat>]<CR>PDU is given<ctrl-Z/ESC>
2438 cmd_str = g_strdup_printf("AT+CMGW=%d,%d%s%s\x1A", saveMsg->msgDataPackage.msgLength, stat, "\r", hex_pdu);
2439 pending = tcore_pending_new(obj, 0);
2440 atreq = tcore_at_request_new((const char *)cmd_str, "+CMGW", TCORE_AT_SINGLELINE);
2442 if(NULL == cmd_str || NULL == atreq || NULL == pending) {
2443 err("Out of memory. Unable to proceed");
2444 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
2446 //free memory we own
2448 util_sms_free_memory(atreq);
2449 util_sms_free_memory(pending);
2450 util_sms_free_memory(hex_pdu);
2453 return TCORE_RETURN_ENOMEM;
2456 util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
2458 tcore_pending_set_request_data(pending, 0, atreq);
2459 tcore_pending_set_response_callback(pending, on_response_sms_save_msg, NULL);
2460 tcore_pending_link_user_request(pending, ur);
2461 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
2462 tcore_hal_send_request(hal, pending);
2468 return TCORE_RETURN_SUCCESS;
2471 err("Invalid Data len");
2473 return TCORE_RETURN_SMS_INVALID_DATA_LEN;
2476 static TReturn delete_msg(CoreObject *obj, UserRequest *ur)
2478 gchar *cmd_str = NULL;
2479 TcoreHal *hal = NULL;
2480 TcoreATRequest *atreq = NULL;
2481 TcorePending *pending = NULL;
2482 const struct treq_sms_delete_msg *delete_msg = NULL;
2486 delete_msg = tcore_user_request_ref_data(ur, NULL);
2487 hal = tcore_object_get_hal(obj);
2488 if (NULL == delete_msg || NULL == hal) {
2489 err("NULL input. Unable to proceed");
2490 dbg("deleteMsg: [%p], hal: [%p]", delete_msg, hal);
2493 return TCORE_RETURN_EINVAL;
2496 if(FALSE == tcore_hal_get_power_state(hal)){
2497 dbg("cp not ready/n");
2498 return TCORE_RETURN_ENOSYS;
2501 dbg("index: %d", delete_msg->index);
2503 if (delete_msg->index == -1) {
2504 cmd_str = g_strdup_printf("AT+CMGD=0,4"); // Delete All Messages
2506 cmd_str = g_strdup_printf("AT+CMGD=%d,0", delete_msg->index + 1); // Delete specified index
2509 pending = tcore_pending_new(obj, 0);
2510 atreq = tcore_at_request_new((const char *)cmd_str, NULL, TCORE_AT_NO_RESULT);
2511 if (NULL == cmd_str || NULL == atreq || NULL == pending) {
2512 err("Out of memory. Unable to proceed");
2513 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
2515 //free memory we own
2517 util_sms_free_memory(atreq);
2518 util_sms_free_memory(pending);
2521 return TCORE_RETURN_ENOMEM;
2524 util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
2526 tcore_pending_set_request_data(pending, 0, atreq);
2527 tcore_pending_set_response_callback(pending, on_response_sms_delete_msg, (void *) (uintptr_t) (delete_msg->index)); // storing index as user data for response
2528 tcore_pending_link_user_request(pending, ur);
2529 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
2530 tcore_hal_send_request(hal, pending);
2535 return TCORE_RETURN_SUCCESS;
2538 static TReturn get_stored_msg_cnt(CoreObject *obj, UserRequest *ur)
2540 gchar *cmd_str = NULL;
2541 TcoreHal *hal = NULL;
2542 TcoreATRequest *atreq = NULL;
2543 TcorePending *pending = NULL;
2547 hal = tcore_object_get_hal(obj);
2549 err("NULL HAL. Unable to proceed");
2552 return TCORE_RETURN_EINVAL;
2555 if(FALSE == tcore_hal_get_power_state(hal)){
2556 dbg("cp not ready/n");
2557 return TCORE_RETURN_ENOSYS;
2560 cmd_str = g_strdup_printf("AT+CPMS=\"SM\"");
2561 pending = tcore_pending_new(obj, 0);
2562 atreq = tcore_at_request_new((const char *)cmd_str, "+CPMS", TCORE_AT_SINGLELINE);
2564 if (NULL == cmd_str || NULL == atreq || NULL == pending) {
2565 err("Out of memory. Unable to proceed");
2566 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
2568 //free memory we own
2570 util_sms_free_memory(atreq);
2571 util_sms_free_memory(pending);
2574 return TCORE_RETURN_ENOMEM;
2577 util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
2579 tcore_pending_set_request_data(pending, 0, atreq);
2580 tcore_pending_set_response_callback(pending, on_response_get_stored_msg_cnt, NULL);
2581 tcore_pending_link_user_request(pending, ur);
2582 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
2583 tcore_hal_send_request(hal, pending);
2588 return TCORE_RETURN_SUCCESS;
2591 static TReturn get_sca(CoreObject *obj, UserRequest *ur)
2593 gchar * cmd_str = NULL;
2594 TcoreHal *hal = NULL;
2595 TcoreATRequest *atreq = NULL;
2596 TcorePending *pending = NULL;
2600 hal = tcore_object_get_hal(obj);
2602 err("HAL NULL. Unable to proceed");
2605 return TCORE_RETURN_EINVAL;
2607 if(FALSE == tcore_hal_get_power_state(hal)){
2608 dbg("cp not ready/n");
2609 return TCORE_RETURN_ENOSYS;
2612 cmd_str = g_strdup_printf("AT+CSCA?");
2613 pending = tcore_pending_new(obj, 0);
2614 atreq = tcore_at_request_new((const char *)cmd_str, "+CSCA", TCORE_AT_SINGLELINE);
2616 if (NULL == cmd_str || NULL == atreq || NULL == pending) {
2617 err("Out of memory. Unable to proceed");
2618 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
2620 //free memory we own
2622 util_sms_free_memory(atreq);
2623 util_sms_free_memory(pending);
2626 return TCORE_RETURN_ENOMEM;
2629 util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
2631 tcore_pending_set_request_data(pending, 0, atreq);
2632 tcore_pending_set_response_callback(pending, on_response_get_sca, NULL);
2633 tcore_pending_link_user_request(pending, ur);
2634 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
2635 tcore_hal_send_request(hal, pending);
2640 return TCORE_RETURN_SUCCESS;
2643 static TReturn set_sca(CoreObject *obj, UserRequest *ur)
2645 gchar *cmd_str = NULL;
2646 TcoreHal *hal = NULL;
2647 TcoreATRequest *atreq = NULL;
2648 TcorePending *pending = NULL;
2649 const struct treq_sms_set_sca *setSca = NULL;
2654 setSca = tcore_user_request_ref_data(ur, NULL);
2655 hal = tcore_object_get_hal(obj);
2656 if (NULL == setSca || NULL == hal) {
2657 err("NULL input. Unable to proceed");
2658 dbg("setSca: [%p], hal: [%p]", setSca, hal);
2661 return TCORE_RETURN_EINVAL;
2663 if(FALSE == tcore_hal_get_power_state(hal)){
2664 dbg("cp not ready/n");
2665 return TCORE_RETURN_ENOSYS;
2668 dbg("dialNumLen: %u, typeOfNum: %d, numPlanId: %d, ", setSca->scaInfo.dialNumLen, setSca->scaInfo.typeOfNum, setSca->scaInfo.numPlanId);
2670 util_hex_dump(" ", (SMS_SMSP_ADDRESS_LEN+1), (void *)setSca->scaInfo.diallingNum);
2672 addrType = ((setSca->scaInfo.typeOfNum << 4) | setSca->scaInfo.numPlanId) | 0x80;
2674 cmd_str = g_strdup_printf("AT+CSCA=\"%s\",%d", setSca->scaInfo.diallingNum, addrType);
2675 pending = tcore_pending_new(obj, 0);
2676 atreq = tcore_at_request_new((const char *)cmd_str, NULL, TCORE_AT_NO_RESULT);
2678 if (NULL == cmd_str || NULL == atreq || NULL == pending) {
2679 err("Out of memory. Unable to proceed");
2680 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
2682 //free memory we own
2684 util_sms_free_memory(atreq);
2685 util_sms_free_memory(pending);
2688 return TCORE_RETURN_ENOMEM;
2691 util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
2693 tcore_pending_set_request_data(pending, 0, atreq);
2694 tcore_pending_set_response_callback(pending, on_response_set_sca, NULL);
2695 tcore_pending_link_user_request(pending, ur);
2696 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
2697 tcore_hal_send_request(hal, pending);
2702 return TCORE_RETURN_SUCCESS;
2705 static TReturn get_cb_config(CoreObject *obj, UserRequest *ur)
2707 gchar *cmd_str = NULL;
2708 TcoreHal *hal = NULL;
2709 TcoreATRequest *atreq = NULL;
2710 TcorePending *pending = NULL;
2714 hal = tcore_object_get_hal(obj);
2716 err("NULL HAL. Unable to proceed");
2719 return TCORE_RETURN_EINVAL;
2721 if(FALSE == tcore_hal_get_power_state(hal)){
2722 dbg("cp not ready/n");
2723 return TCORE_RETURN_ENOSYS;
2726 cmd_str = g_strdup_printf("AT+CSCB?");
2727 pending = tcore_pending_new(obj, 0);
2728 atreq = tcore_at_request_new((const char *)cmd_str, "+CSCB", TCORE_AT_SINGLELINE);
2729 if (NULL == cmd_str || NULL == atreq || NULL == pending) {
2730 err("Out of memory. Unable to proceed");
2731 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
2733 //free memory we own
2735 util_sms_free_memory(atreq);
2736 util_sms_free_memory(pending);
2739 return TCORE_RETURN_ENOMEM;
2742 util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
2744 tcore_pending_set_request_data(pending, 0, atreq);
2745 tcore_pending_set_response_callback(pending, on_response_get_cb_config, NULL);
2746 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
2747 tcore_pending_link_user_request(pending, ur);
2748 tcore_hal_send_request(hal, pending);
2753 return TCORE_RETURN_SUCCESS;
2756 static TReturn set_cb_config(CoreObject *obj, UserRequest *ur)
2758 gchar *cmd_str = NULL;
2759 gchar *mids_str = NULL;
2760 GString *mids_GString = NULL;
2762 TcoreHal *hal = NULL;
2763 TcoreATRequest *atreq = NULL;
2764 TcorePending *pending = NULL;
2765 const struct treq_sms_set_cb_config *setCbConfig = NULL;
2766 int ctr1= 0, ctr2 =0;
2767 unsigned short appendMsgId = 0;
2771 setCbConfig = tcore_user_request_ref_data(ur, NULL);
2772 hal = tcore_object_get_hal(obj);
2773 if (NULL == setCbConfig || NULL == hal) {
2774 err("NULL input. Unable to proceed");
2775 dbg("setCbConfig: [%p], hal: [%p]", setCbConfig, hal);
2778 return TCORE_RETURN_EINVAL;
2780 if(FALSE == tcore_hal_get_power_state(hal)){
2781 dbg("cp not ready/n");
2782 return TCORE_RETURN_ENOSYS;
2785 dbg("bCBEnabled: %d, msgIdCount: %d", setCbConfig->cbEnabled, setCbConfig->msgIdRangeCount);
2787 if (setCbConfig->cbEnabled == 2) { //Enable all CBS
2788 cmd_str = g_strdup_printf("AT+CSCB=1");
2789 } else if ((setCbConfig->cbEnabled == 1) && (setCbConfig->msgIdRangeCount == 0)) { // Special case: Enable all CBS
2790 cmd_str = g_strdup_printf("AT+CSCB=1");
2791 } else if (setCbConfig->cbEnabled == 0) {//AT+CSCB=0: Disable CBS
2792 cmd_str = g_strdup_printf("AT+CSCB=0");
2794 mids_GString = g_string_new("AT+CSCB=0,\"");
2796 for(ctr1 = 0; ctr1 < setCbConfig->msgIdRangeCount; ctr1++ ) {
2797 if( setCbConfig->msgIDs[ctr1].net3gpp.selected == FALSE )
2800 if( SMS_GSM_SMS_CBMI_LIST_SIZE_MAX <= (setCbConfig->msgIDs[ctr1].net3gpp.toMsgId - setCbConfig->msgIDs[ctr1].net3gpp.fromMsgId) ) {
2801 g_string_free(mids_GString, TRUE);
2802 mids_GString = g_string_new("AT+CSCB=1");
2806 appendMsgId = setCbConfig->msgIDs[ctr1].net3gpp.fromMsgId;
2808 for( ctr2 = 0; (ctr2 <= ((setCbConfig->msgIDs[ctr1].net3gpp.toMsgId) - (setCbConfig->msgIDs[ctr1].net3gpp.fromMsgId))); ctr2++ ) {
2809 gchar *append_str = NULL;
2810 dbg( "%x", appendMsgId);
2811 append_str = g_strdup_printf("%d", appendMsgId);
2812 g_string_append(mids_GString, append_str);
2815 if (ctr2 == ((setCbConfig->msgIDs[ctr1].net3gpp.toMsgId) - (setCbConfig->msgIDs[ctr1].net3gpp.fromMsgId))) {
2816 g_string_append(mids_GString, "\""); //Mids string termination
2818 g_string_append(mids_GString, ",");
2824 mids_str = g_string_free(mids_GString, FALSE);
2825 cmd_str = g_strdup_printf("%s", mids_str);
2829 pending = tcore_pending_new(obj, 0);
2830 atreq = tcore_at_request_new((const char *)cmd_str, NULL, TCORE_AT_NO_RESULT);
2831 if(NULL == cmd_str || NULL == atreq || NULL == pending) {
2832 err("Out of memory. Unable to proceed");
2833 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
2835 //free memory we own
2837 util_sms_free_memory(atreq);
2838 util_sms_free_memory(pending);
2841 return TCORE_RETURN_ENOMEM;
2844 util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
2846 tcore_pending_set_request_data(pending, 0, atreq);
2847 tcore_pending_set_response_callback(pending, on_response_set_cb_config, NULL);
2848 tcore_pending_link_user_request(pending, ur);
2849 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
2850 tcore_hal_send_request(hal, pending);
2855 return TCORE_RETURN_SUCCESS;
2858 static TReturn set_mem_status(CoreObject *obj, UserRequest *ur)
2860 gchar *cmd_str = NULL;
2861 TcoreHal *hal = NULL;
2862 TcoreATRequest *atreq = NULL;
2863 TcorePending *pending = NULL;
2864 const struct treq_sms_set_mem_status *setMemStatus = NULL;
2865 int memoryStatus = 0;
2869 setMemStatus = tcore_user_request_ref_data(ur, NULL);
2870 hal = tcore_object_get_hal(obj);
2871 if (NULL == setMemStatus || NULL == hal) {
2872 err("NULL input. Unable to proceed");
2873 dbg("setMemStatus: [%p], hal: [%p]", setMemStatus, hal);
2876 return TCORE_RETURN_EINVAL;
2878 if(FALSE == tcore_hal_get_power_state(hal)){
2879 dbg("cp not ready/n");
2880 return TCORE_RETURN_ENOSYS;
2883 dbg("memory_status: %d", setMemStatus->memory_status);
2885 if(setMemStatus->memory_status < SMS_PDA_MEMORY_STATUS_AVAILABLE
2886 || setMemStatus->memory_status > SMS_PDA_MEMORY_STATUS_FULL) {
2887 err("Invalid memory_status");
2890 return TCORE_RETURN_EINVAL;
2893 switch (setMemStatus->memory_status) {
2894 case SMS_PDA_MEMORY_STATUS_AVAILABLE:
2895 memoryStatus = AT_MEMORY_AVAILABLE;
2898 case SMS_PDA_MEMORY_STATUS_FULL:
2899 memoryStatus = AT_MEMORY_FULL;
2903 err("Invalid memory_status");
2905 return TCORE_RETURN_EINVAL;
2908 cmd_str = g_strdup_printf("AT+XTESM=%d", memoryStatus);
2909 pending = tcore_pending_new(obj, 0);
2910 atreq = tcore_at_request_new((const char *)cmd_str, NULL, TCORE_AT_NO_RESULT);
2912 if (NULL == cmd_str || NULL == atreq || NULL == pending) {
2913 err("Out of memory. Unable to proceed");
2914 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
2916 //free memory we own
2918 util_sms_free_memory(atreq);
2919 util_sms_free_memory(pending);
2922 return TCORE_RETURN_ENOMEM;
2925 util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
2927 tcore_pending_set_request_data(pending, 0, atreq);
2928 tcore_pending_set_response_callback(pending, on_response_set_mem_status, NULL);
2929 tcore_pending_link_user_request(pending, ur);
2930 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
2931 tcore_hal_send_request(hal, pending);
2936 return TCORE_RETURN_SUCCESS;
2939 static TReturn set_delivery_report(CoreObject *obj, UserRequest *ur)
2941 struct tresp_sms_set_delivery_report respSetDeliveryReport = {0,};
2943 respSetDeliveryReport.result = SMS_SUCCESS;
2946 if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(obj))){
2947 dbg("cp not ready/n");
2948 return TCORE_RETURN_ENOSYS;
2951 dbg("CP takes care of sending SMS ack to network for all classes of SMS. Sending default success.");
2953 tcore_user_request_send_response(ur, TRESP_SMS_SET_DELIVERY_REPORT, sizeof(struct tresp_sms_set_delivery_report), &respSetDeliveryReport);
2956 return TCORE_RETURN_SUCCESS;
2959 static TReturn set_msg_status(CoreObject *obj, UserRequest *ur)
2961 gchar *cmd_str = NULL;
2962 TcoreHal *hal = NULL;
2963 TcoreATRequest *atreq = NULL;
2964 TcorePending *pending = NULL;
2965 const struct treq_sms_set_msg_status *msg_status = NULL;
2968 hal = tcore_object_get_hal(obj);
2969 if(FALSE == tcore_hal_get_power_state(hal)){
2970 dbg("cp not ready/n");
2971 return TCORE_RETURN_ENOSYS;
2973 msg_status = tcore_user_request_ref_data(ur, NULL);
2975 cmd_str = g_strdup_printf("AT+CRSM=178,28476,%d,4,%d", (msg_status->index+1), PDU_LEN_MAX);
2976 atreq = tcore_at_request_new((const char *)cmd_str, "+CRSM", TCORE_AT_SINGLELINE);
2977 pending = tcore_pending_new(obj, 0);
2978 if (NULL == cmd_str || NULL == atreq || NULL == pending) {
2979 err("Out of memory. Unable to proceed");
2980 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
2982 //free memory we own
2984 util_sms_free_memory(atreq);
2985 util_sms_free_memory(pending);
2988 return TCORE_RETURN_ENOMEM;
2991 util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
2993 tcore_pending_set_request_data(pending, 0, atreq);
2994 tcore_pending_set_response_callback(pending, _response_get_efsms_data, NULL);
2995 tcore_pending_link_user_request(pending, ur);
2996 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
2997 tcore_hal_send_request(hal, pending);
3002 return TCORE_RETURN_SUCCESS;
3005 static TReturn get_sms_params(CoreObject *obj, UserRequest *ur)
3007 gchar *cmd_str = NULL;
3008 TcoreHal *hal = NULL;
3009 TcoreATRequest *atreq = NULL;
3010 TcorePending *pending = NULL;
3011 const struct treq_sms_get_params *getSmsParams = NULL;
3012 int record_len = 0 , *smsp_record_len = NULL;
3016 getSmsParams = tcore_user_request_ref_data(ur, NULL);
3017 hal = tcore_object_get_hal(obj);
3018 if (NULL == getSmsParams || NULL == hal) {
3019 err("NULL input. Unable to proceed");
3020 dbg("getSmsParams: [%p], hal: [%p]", getSmsParams, hal);
3023 return TCORE_RETURN_EINVAL;
3025 if(FALSE == tcore_hal_get_power_state(hal)){
3026 dbg("cp not ready/n");
3027 return TCORE_RETURN_ENOSYS;
3030 smsp_record_len = tcore_plugin_ref_property(tcore_object_ref_plugin(obj), "SMSPRECORDLEN");
3031 record_len = *smsp_record_len;
3032 dbg("record len from property %d", record_len);
3034 //AT+CRSM=command>[,<fileid>[,<P1>,<P2>,<P3>[,<data>[,<pathid>]]]]
3035 cmd_str = g_strdup_printf("AT+CRSM=178,28482,%d,4,%d", (getSmsParams->index + 1), record_len);
3037 dbg("cmd_str is %s",cmd_str);
3039 atreq = tcore_at_request_new((const char *)cmd_str, "+CRSM", TCORE_AT_SINGLELINE);
3040 pending = tcore_pending_new(obj, 0);
3041 if (NULL == cmd_str || NULL == atreq || NULL == pending) {
3042 err("Out of memory. Unable to proceed");
3043 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
3045 //free memory we own
3047 util_sms_free_memory(atreq);
3048 util_sms_free_memory(pending);
3051 return TCORE_RETURN_ENOMEM;
3054 util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
3056 tcore_pending_set_request_data(pending, 0, atreq);
3057 tcore_pending_set_response_callback(pending, on_response_get_sms_params, NULL);
3058 tcore_pending_link_user_request(pending, ur);
3059 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
3060 tcore_hal_send_request(hal, pending);
3065 return TCORE_RETURN_SUCCESS;
3068 static TReturn set_sms_params(CoreObject *obj, UserRequest *ur)
3070 gchar *cmd_str = NULL;
3071 char *encoded_data = NULL;
3072 unsigned char *temp_data = NULL;
3073 int SMSPRecordLen = 0;
3074 int *smsp_record_len;
3076 TcoreHal *hal = NULL;
3077 TcoreATRequest *atreq = NULL;
3078 TcorePending *pending = NULL;
3079 const struct treq_sms_set_params *setSmsParams = NULL;
3080 int encoded_data_len = 0;
3084 setSmsParams = tcore_user_request_ref_data(ur, NULL);
3085 hal = tcore_object_get_hal(obj);
3086 if (NULL == setSmsParams || NULL == hal) {
3087 err("NULL input. Unable to proceed");
3088 dbg("setSmsParams: [%p], hal: [%p]", setSmsParams, hal);
3091 if(FALSE == tcore_hal_get_power_state(hal)){
3092 dbg("cp not ready/n");
3093 return TCORE_RETURN_ENOSYS;
3096 //EFsmsp file size is 28 +Y bytes (Y is alpha id size)
3097 smsp_record_len = tcore_plugin_ref_property(tcore_object_ref_plugin(obj), "SMSPRECORDLEN");
3098 SMSPRecordLen = *smsp_record_len;
3099 if (SMSPRecordLen < nDefaultSMSPWithoutAlphaId)
3102 temp_data = calloc(SMSPRecordLen,1);
3103 encoded_data = calloc(SMSPRecordLen*2 + 1,1);
3105 _tcore_util_sms_encode_smsParameters(&(setSmsParams->params), temp_data, SMSPRecordLen);
3107 util_byte_to_hex((const char *)temp_data, (char *)encoded_data,SMSPRecordLen);
3109 encoded_data_len = ((SMSPRecordLen) * 2);
3111 hal = tcore_object_get_hal(obj);
3112 pending = tcore_pending_new(obj, 0);
3114 dbg("alpha id len %d encoded data %s. Encoded data len %d",setSmsParams->params.alphaIdLen,encoded_data, encoded_data_len);
3115 cmd_str = g_strdup_printf("AT+CRSM=220,28482,%d,4,%d,\"%s\"",(setSmsParams->params.recordIndex+1),SMSPRecordLen,encoded_data);
3117 dbg("cmd str is %s",cmd_str);
3118 atreq = tcore_at_request_new(cmd_str, "+CRSM:", TCORE_AT_SINGLELINE);
3120 if (NULL == cmd_str || NULL == atreq || NULL == pending) {
3121 err("Out of memory. Unable to proceed");
3122 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
3124 //free memory we own
3126 util_sms_free_memory(atreq);
3127 util_sms_free_memory(pending);
3129 util_sms_free_memory(temp_data);
3130 util_sms_free_memory(encoded_data);
3133 return TCORE_RETURN_ENOMEM;
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_set_sms_params, 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);
3145 util_sms_free_memory(temp_data);
3146 util_sms_free_memory(encoded_data);
3148 return TCORE_RETURN_SUCCESS;
3151 static TReturn get_paramcnt(CoreObject *obj, UserRequest *ur)
3153 gchar *cmd_str = NULL;
3154 TcoreHal *hal = NULL;
3155 TcoreATRequest *atreq = NULL;
3156 TcorePending *pending = NULL;
3160 hal = tcore_object_get_hal(obj);
3162 err("NULL HAL. Unable to proceed");
3165 return TCORE_RETURN_EINVAL;
3167 if(FALSE == tcore_hal_get_power_state(hal)){
3168 dbg("cp not ready/n");
3169 return TCORE_RETURN_ENOSYS;
3172 //AT+CRSM=command>[,<fileid>[,<P1>,<P2>,<P3>[,<data>[,<pathid>]]]]
3173 cmd_str = g_strdup_printf("AT+CRSM=192,28482");
3174 atreq = tcore_at_request_new((const char *)cmd_str, "+CRSM", TCORE_AT_SINGLELINE);
3175 pending = tcore_pending_new(obj, 0);
3177 if (NULL == cmd_str || NULL == atreq || NULL == pending) {
3178 err("NULL pointer. Unable to proceed");
3179 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
3181 //free memory we own
3183 util_sms_free_memory(atreq);
3184 util_sms_free_memory(pending);
3187 return TCORE_RETURN_FAILURE;
3190 util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
3192 tcore_pending_set_request_data(pending, 0, atreq);
3193 tcore_pending_set_response_callback(pending, on_response_get_paramcnt, NULL);
3194 tcore_pending_link_user_request(pending, ur);
3195 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
3196 tcore_hal_send_request(hal, pending);
3201 return TCORE_RETURN_SUCCESS;
3204 static struct tcore_sms_operations sms_ops = {
3205 .send_umts_msg = send_umts_msg,
3206 .read_msg = read_msg,
3207 .save_msg = save_msg,
3208 .delete_msg = delete_msg,
3209 .get_storedMsgCnt = get_stored_msg_cnt,
3212 .get_cb_config = get_cb_config,
3213 .set_cb_config = set_cb_config,
3214 .set_mem_status = set_mem_status,
3215 .get_pref_brearer = NULL,
3216 .set_pref_brearer = NULL,
3217 .set_delivery_report = set_delivery_report,
3218 .set_msg_status = set_msg_status,
3219 .get_sms_params = get_sms_params,
3220 .set_sms_params = set_sms_params,
3221 .get_paramcnt = get_paramcnt,
3224 gboolean imc_sms_init(TcorePlugin *cp, CoreObject *co_sms)
3226 int *smsp_record_len;
3229 /* Set operations */
3230 tcore_sms_set_ops(co_sms, &sms_ops);
3232 /* Registering for SMS notifications */
3233 tcore_object_add_callback(co_sms, "+CMTI:", on_event_class2_sms_incom_msg, NULL);
3234 tcore_object_add_callback(co_sms, "\e+CMT:", on_event_sms_incom_msg, NULL);
3236 tcore_object_add_callback(co_sms, "\e+CDS", on_event_sms_incom_msg, NULL);
3237 tcore_object_add_callback(co_sms, "+XSMSMMSTAT", on_event_sms_memory_status, NULL);
3238 tcore_object_add_callback(co_sms, "+CMS", on_event_sms_memory_status, NULL);
3240 tcore_object_add_callback(co_sms, "+CBMI:", on_event_sms_cb_incom_msg, NULL);
3241 tcore_object_add_callback(co_sms, "\e+CBM:", on_event_sms_cb_incom_msg, NULL);
3243 /* Storing SMSP record length */
3244 smsp_record_len = g_new0(int, 1);
3245 tcore_plugin_link_property(cp, "SMSPRECORDLEN", smsp_record_len);
3251 void imc_sms_exit(TcorePlugin *cp, CoreObject *co_sms)
3253 int *smsp_record_len;
3255 smsp_record_len = tcore_plugin_ref_property(cp, "SMSPRECORDLEN");
3256 g_free(smsp_record_len);