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) & 0xff00) >> 8) | (((x) & 0x00ff) << 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;
175 * For PDU, the SC Address length is the number of packed BCD bytes
176 * + 1 byte for SC Address type whereas the length given in
177 * 3GPP 23.040 Address encoding is the number of digits without 1 byte
180 sca_len = ((sca[0] + 1) / 2) + 1;
182 converted_sca[0] = (unsigned char)sca_len;
184 for (i = 1; i <= sca_len; i++)
185 converted_sca[i] = sca[i];
188 memcpy(pdu, converted_sca, sca_len + 1);
189 memcpy(pdu + sca_len + 1, tpdu, tpdu_len);
191 return sca_len + 1 + tpdu_len;
195 static long __util_sms_encode_hex(const guchar *src, long num_bytes, gchar *buf)
202 for (i = 0, j = 0; i < num_bytes; i++, j++) {
203 CONVERT_TO_HEX(((src[i] >> 4) & 0xf), buf[j++]);
204 CONVERT_TO_HEX((src[i] & 0xf), buf[j]);
212 static int util_sms_decode_smsParameters(unsigned char *incoming,
213 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;
230 for (i = 0; i < alpha_id_len; i++) {
231 if (0xff == incoming[i]) {
237 memcpy(params->szAlphaId, incoming, i);
239 params->alphaIdLen = i;
241 dbg(" Alpha id length = %d", i);
243 params->alphaIdLen = 0;
244 dbg(" Alpha id length is zero");
247 params->paramIndicator = incoming[alpha_id_len];
249 dbg(" Param Indicator = %02x", params->paramIndicator);
251 if ((params->paramIndicator & SMSPValidDestAddr) == 0) {
252 nOffset = nDestAddrOffset;
254 if (0x00 == incoming[alpha_id_len + nOffset] || 0xff == incoming[alpha_id_len + nOffset]) {
255 params->tpDestAddr.dialNumLen = 0;
257 dbg("DestAddr Length is 0");
259 if (0 < (int) incoming[alpha_id_len + nOffset]) {
260 params->tpDestAddr.dialNumLen = (int) (incoming[alpha_id_len + nOffset] - 1);
262 if (params->tpDestAddr.dialNumLen > SMS_SMSP_ADDRESS_LEN)
263 params->tpDestAddr.dialNumLen = SMS_SMSP_ADDRESS_LEN;
265 params->tpDestAddr.dialNumLen = 0;
268 params->tpDestAddr.numPlanId = incoming[alpha_id_len + (++nOffset)] & 0x0f;
269 params->tpDestAddr.typeOfNum = (incoming[alpha_id_len + nOffset] & 0x70) >> 4;
271 memcpy(params->tpDestAddr.diallingNum, &incoming[alpha_id_len + (++nOffset)], (params->tpDestAddr.dialNumLen));
273 dbg("Dest TON is %d", params->tpDestAddr.typeOfNum);
274 dbg("Dest NPI is %d", params->tpDestAddr.numPlanId);
275 dbg("Dest Length = %d", params->tpDestAddr.dialNumLen);
276 dbg("Dest Addr = %s", params->tpDestAddr.diallingNum);
279 params->tpDestAddr.dialNumLen = 0;
282 if ((params->paramIndicator & SMSPValidSvcAddr) == 0) {
283 nOffset = nSCAAddrOffset;
285 if (0x00 == (int) incoming[alpha_id_len + nOffset] || 0xff == (int) incoming[alpha_id_len + nOffset]) {
286 params->tpSvcCntrAddr.dialNumLen = 0;
288 dbg(" SCAddr Length is 0");
290 if (0 < (int) incoming[alpha_id_len + nOffset]) {
291 params->tpSvcCntrAddr.dialNumLen = (int) (incoming[alpha_id_len + nOffset] - 1);
293 if (params->tpSvcCntrAddr.dialNumLen > SMS_SMSP_ADDRESS_LEN)
294 params->tpSvcCntrAddr.dialNumLen = SMS_SMSP_ADDRESS_LEN;
296 params->tpSvcCntrAddr.numPlanId = incoming[alpha_id_len + (++nOffset)] & 0x0f;
297 params->tpSvcCntrAddr.typeOfNum = (incoming[alpha_id_len + nOffset] & 0x70) >> 4;
299 memcpy(params->tpSvcCntrAddr.diallingNum, &incoming[alpha_id_len + (++nOffset)], (params->tpSvcCntrAddr.dialNumLen));
301 dbg("SCAddr Length = %d ", params->tpSvcCntrAddr.dialNumLen);
302 dbg("SCAddr TON is %d", params->tpSvcCntrAddr.typeOfNum);
303 dbg("SCAddr NPI is %d", params->tpSvcCntrAddr.numPlanId);
305 for (i = 0; i < (int) params->tpSvcCntrAddr.dialNumLen; i++)
306 dbg("SCAddr = %d [%02x]", i, params->tpSvcCntrAddr.diallingNum[i]);
308 params->tpSvcCntrAddr.dialNumLen = 0;
311 } else if ((0x00 < (int) incoming[alpha_id_len + nSCAAddrOffset] && (int) incoming[alpha_id_len + nSCAAddrOffset] <= 12)
312 || 0xff != (int) incoming[alpha_id_len + nSCAAddrOffset]) {
313 nOffset = nSCAAddrOffset;
315 if (0x00 == (int) incoming[alpha_id_len + nOffset] || 0xff == (int) incoming[alpha_id_len + nOffset]) {
316 params->tpSvcCntrAddr.dialNumLen = 0;
317 dbg("SCAddr Length is 0");
319 if (0 < (int) incoming[alpha_id_len + nOffset]) {
320 params->tpSvcCntrAddr.dialNumLen = (int) (incoming[alpha_id_len + nOffset] - 1);
322 params->tpSvcCntrAddr.dialNumLen = incoming[alpha_id_len + nOffset] - 1;
324 if (params->tpSvcCntrAddr.dialNumLen > SMS_SMSP_ADDRESS_LEN)
325 params->tpSvcCntrAddr.dialNumLen = SMS_SMSP_ADDRESS_LEN;
327 params->tpSvcCntrAddr.numPlanId = incoming[alpha_id_len + (++nOffset)] & 0x0f;
328 params->tpSvcCntrAddr.typeOfNum = (incoming[alpha_id_len + nOffset] & 0x70) >> 4;
330 memcpy(params->tpSvcCntrAddr.diallingNum, &incoming[alpha_id_len + (++nOffset)],
331 (params->tpSvcCntrAddr.dialNumLen));
333 dbg("SCAddr Length = %d ", params->tpSvcCntrAddr.dialNumLen);
334 dbg("SCAddr TON is %d", params->tpSvcCntrAddr.typeOfNum);
335 dbg("SCAddr NPI is %d", params->tpSvcCntrAddr.numPlanId);
337 for (i = 0; i < (int) params->tpSvcCntrAddr.dialNumLen; i++)
338 dbg("SCAddr = %d [%02x]", i, params->tpSvcCntrAddr.diallingNum[i]);
340 params->tpSvcCntrAddr.dialNumLen = 0;
344 params->tpSvcCntrAddr.dialNumLen = 0;
347 if ((params->paramIndicator & SMSPValidPID) == 0
348 && (alpha_id_len + nPIDOffset) < MAX_GSM_SMS_PARAM_RECORD_SIZE)
349 params->tpProtocolId = incoming[alpha_id_len + nPIDOffset];
351 if ((params->paramIndicator & SMSPValidDCS) == 0
352 && (alpha_id_len + nDCSOffset) < MAX_GSM_SMS_PARAM_RECORD_SIZE)
353 params->tpDataCodingScheme = incoming[alpha_id_len + nDCSOffset];
355 if ((params->paramIndicator & SMSPValidVP) == 0
356 && (alpha_id_len + nVPOffset) < MAX_GSM_SMS_PARAM_RECORD_SIZE)
357 params->tpValidityPeriod = incoming[alpha_id_len + nVPOffset];
359 dbg(" Alpha Id(Len) = %d", (int) params->alphaIdLen);
361 for (i = 0; i < (int) params->alphaIdLen; i++)
362 dbg(" Alpha Id = [%d] [%c]", i, params->szAlphaId[i]);
364 dbg(" PID = %d", params->tpProtocolId);
365 dbg(" DCS = %d", params->tpDataCodingScheme);
366 dbg(" VP = %d", params->tpValidityPeriod);
374 static gboolean on_event_class2_sms_incom_msg(CoreObject *obj,
375 const void *event_info, void *user_data)
377 /* +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);
424 util_sms_free_memory(atreq);
425 util_sms_free_memory(pending);
428 return TCORE_RETURN_ENOMEM;
431 tcore_util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
433 tcore_pending_set_request_data(pending, 0, atreq);
434 tcore_pending_set_response_callback(pending, on_response_class2_read_msg, (void *)(uintptr_t)index); /* storing index as user data for response */
435 tcore_pending_link_user_request(pending, NULL);
436 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
437 tcore_hal_send_request(hal, pending);
441 tcore_at_tok_free(tokens);
446 static gboolean on_event_sms_incom_msg(CoreObject *o, const void *event_info, void *user_data)
448 /* +CMT: [<alpha>], <length><CR><LF><pdu> (PDU mode enabled); */
450 GSList *tokens = NULL;
451 GSList *lines = NULL;
453 int pdu_len = 0, no_of_tokens = 0;
454 unsigned char *bytePDU = NULL;
455 struct tnoti_sms_incoming_msg gsmMsgInfo;
458 dbg("Entered Function");
460 lines = (GSList *)event_info;
461 memset(&gsmMsgInfo, 0x00, sizeof(struct tnoti_sms_incoming_msg));
463 if (2 != g_slist_length(lines)) {
464 err("Invalid number of lines for +CMT. Must be 2");
468 line = (char *)g_slist_nth_data(lines, 0); /* Fetch Line 1 */
470 dbg("Line 1: [%s]", line);
473 err("Line 1 is invalid");
477 tokens = tcore_at_tok_new(line); /* Split Line 1 into tokens */
479 no_of_tokens = g_slist_length(tokens);
481 if (no_of_tokens == 2) { /* in case of incoming SMS +CMT */
482 dbg("Alpha ID: [%02x]", g_slist_nth_data(tokens, 0)); /* 0: Alpha ID */
483 pdu_len = atoi((char *)g_slist_nth_data(tokens, 1));
484 dbg("pdu_len: [%d]", pdu_len); /* 1: PDU Length */
485 } else if (no_of_tokens == 1) { /* in case of incoming status report +CDS */
486 pdu_len = atoi((char *)g_slist_nth_data(tokens, 0));
487 dbg("pdu_len: [%d]", pdu_len); /* 1: PDU Length */
490 line = (char *)g_slist_nth_data(lines, 1); /* Fetch Line 2 */
492 dbg("Line 2: [%s]", line);
495 err("Line 2 is invalid");
499 /* Convert to Bytes */
500 bytePDU = (unsigned char *)util_hexStringToBytes(line);
502 err("NULL data received[%p]", bytePDU);
503 tcore_at_tok_free(tokens);
506 sca_length = bytePDU[0];
508 dbg("SCA length = %d", sca_length);
510 gsmMsgInfo.msgInfo.format = SMS_NETTYPE_3GPP;
511 gsmMsgInfo.msgInfo.msgLength = pdu_len;
513 if (sca_length == 0) {
514 memcpy(gsmMsgInfo.msgInfo.tpduData, &bytePDU[1], gsmMsgInfo.msgInfo.msgLength);
516 gsmMsgInfo.msgInfo.sca[0] = sca_length;
517 memcpy(&(gsmMsgInfo.msgInfo.sca[1]), &bytePDU[1], sca_length);
518 memcpy(gsmMsgInfo.msgInfo.tpduData, &bytePDU[sca_length + 1], gsmMsgInfo.msgInfo.msgLength);
521 tcore_util_hex_dump(" ", strlen(line) / 2, bytePDU);
522 tcore_util_hex_dump(" ", sca_length, gsmMsgInfo.msgInfo.sca);
523 tcore_util_hex_dump(" ", gsmMsgInfo.msgInfo.msgLength, gsmMsgInfo.msgInfo.tpduData);
525 ret = tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)),
528 sizeof(struct tnoti_sms_incoming_msg), &gsmMsgInfo);
532 tcore_at_tok_free(tokens);
541 static gboolean on_event_sms_memory_status(CoreObject *o, const void *event_info, void *user_data)
543 struct tnoti_sms_memory_status memStatusInfo = {0, };
545 int memoryStatus = -1;
546 GSList *tokens = NULL;
547 GSList *lines = NULL;
548 char *line = NULL, *pResp = NULL;
553 lines = (GSList *)event_info;
554 if (1 != g_slist_length(lines))
555 dbg("unsolicited msg but multiple line");
557 line = (char *)(lines->data);
561 tokens = tcore_at_tok_new(line);
562 pResp = g_slist_nth_data(tokens, 0);
565 memoryStatus = atoi(pResp);
566 dbg("memoryStatus is %d", memoryStatus);
567 if (memoryStatus == 0) /* SIM Full condition */
568 memStatusInfo.status = SMS_PHONE_MEMORY_STATUS_FULL;
570 ret = tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)),
572 TNOTI_SMS_MEMORY_STATUS,
573 sizeof(struct tnoti_sms_memory_status), &memStatusInfo);
576 tcore_at_tok_free(tokens);
585 static gboolean on_event_sms_cb_incom_msg(CoreObject *o, const void *event_info, void *user_data)
587 /* +CBM: <length><CR><LF><pdu> */
588 struct tnoti_sms_cellBroadcast_msg cbMsgInfo;
590 int rtn = -1, length = 0;
591 char *line = NULL, *pdu = NULL, *pResp = NULL;
592 GSList *tokens = NULL;
593 GSList *lines = NULL;
595 dbg(" Func Entrance");
597 lines = (GSList *)event_info;
599 memset(&cbMsgInfo, 0, sizeof(struct tnoti_sms_cellBroadcast_msg));
601 line = (char *)(lines->data);
605 dbg("Noti line is %s", line);
606 tokens = tcore_at_tok_new(line); /* Split Line 1 into tokens */
608 pResp = g_slist_nth_data(tokens, 0);
610 length = atoi(pResp);
612 dbg("token 0 is null");
614 pdu = g_slist_nth_data(lines, 1);
616 cbMsgInfo.cbMsg.length = length;
617 cbMsgInfo.cbMsg.cbMsgType = SMS_CB_MSG_GSM;
619 dbg("CB Msg LENGTH [%2x]", length);
621 if ((cbMsgInfo.cbMsg.length > 0)
622 && (SMS_CB_SIZE_MAX >= cbMsgInfo.cbMsg.length)) {
623 unsigned char *byte_pdu = NULL;
625 byte_pdu = (unsigned char *)util_hexStringToBytes(pdu);
627 memcpy(cbMsgInfo.cbMsg.msgData, (char *)byte_pdu, cbMsgInfo.cbMsg.length);
628 rtn = tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)),
630 TNOTI_SMS_CB_INCOM_MSG,
631 sizeof(struct tnoti_sms_cellBroadcast_msg), &cbMsgInfo);
634 err("util_hexStringToBytes Failed!!");
637 dbg("Invalid Message Length");
640 dbg("Recieved NULL pdu");
646 dbg(" Return value [%d]", rtn);
649 tcore_at_tok_free(tokens);
658 static void on_response_sms_delete_msg(TcorePending *p,
659 int data_len, const void *data, void *user_data)
661 struct tresp_sms_delete_msg delMsgInfo = {0, };
662 UserRequest *ur = NULL;
663 const TcoreATResponse *atResp = data;
664 int index = GPOINTER_TO_INT(user_data);
666 dbg(" Func Entrance");
668 ur = tcore_pending_ref_user_request(p);
669 if (atResp->success) {
671 delMsgInfo.index = index;
672 delMsgInfo.result = SMS_SENDSMS_SUCCESS;
675 delMsgInfo.index = index;
676 delMsgInfo.result = SMS_DEVICE_FAILURE;
679 tcore_user_request_send_response(ur,
680 TRESP_SMS_DELETE_MSG,
681 sizeof(struct tresp_sms_delete_msg), &delMsgInfo);
686 static void on_response_sms_save_msg(TcorePending *p,
687 int data_len, const void *data, void *user_data)
689 struct tresp_sms_save_msg saveMsgInfo = {0, };
690 UserRequest *ur = NULL;
691 const TcoreATResponse *atResp = data;
692 GSList *tokens = NULL;
697 ur = tcore_pending_ref_user_request(p);
698 if (atResp->success) {
701 line = (char *)atResp->lines->data;
702 tokens = tcore_at_tok_new(line);
703 pResp = g_slist_nth_data(tokens, 0);
706 saveMsgInfo.index = (atoi(pResp) - 1); /* IMC index starts from 1 */
707 saveMsgInfo.result = SMS_SENDSMS_SUCCESS;
710 saveMsgInfo.index = -1;
711 saveMsgInfo.result = SMS_DEVICE_FAILURE;
713 tcore_at_tok_free(tokens);
717 saveMsgInfo.index = -1;
718 saveMsgInfo.result = SMS_DEVICE_FAILURE;
721 rtn = tcore_user_request_send_response(ur,
723 sizeof(struct tresp_sms_save_msg), &saveMsgInfo);
724 dbg("Return value [%d]", rtn);
728 static void on_response_send_umts_msg(TcorePending *pending,
729 int data_len, const void *data, void *user_data)
731 const TcoreATResponse *at_response = data;
732 struct tresp_sms_send_msg resp_umts;
733 UserRequest *user_req = NULL;
736 GSList *tokens = NULL;
737 char *gslist_line = NULL, *line_token = NULL;
741 user_req = tcore_pending_ref_user_request(pending);
743 if (NULL == user_req) {
744 err("No user request");
750 memset(&resp_umts, 0x00, sizeof(resp_umts));
751 resp_umts.result = SMS_DEVICE_FAILURE;
753 if (at_response->success > 0) { /* SUCCESS */
755 if (at_response->lines) { /* lines present in at_response */
756 gslist_line = (char *)at_response->lines->data;
757 dbg("gslist_line: [%s]", gslist_line);
759 tokens = tcore_at_tok_new(gslist_line); /* extract tokens */
761 line_token = g_slist_nth_data(tokens, 0);
762 if (line_token != NULL) {
763 msg_ref = atoi(line_token);
764 dbg("Message Reference: [%d]", msg_ref);
766 resp_umts.result = SMS_SENDSMS_SUCCESS;
768 dbg("No Message Reference received");
770 tcore_at_tok_free(tokens);
771 } else { /* no lines in at_response */
774 } else { /* failure */
778 tcore_user_request_send_response(user_req,
779 TRESP_SMS_SEND_UMTS_MSG,
780 sizeof(resp_umts), &resp_umts);
786 static void on_response_class2_read_msg(TcorePending *pending,
787 int data_len, const void *data, void *user_data)
789 const TcoreATResponse *at_response = data;
790 GSList *tokens = NULL;
791 char *gslist_line = NULL, *line_token = NULL, *hex_pdu = NULL;
792 int pdu_len = 0, rtn = 0;
793 unsigned char *bytePDU = NULL;
794 struct tnoti_sms_incoming_msg gsmMsgInfo;
798 dbg("lines: [%p]", at_response->lines);
799 g_slist_foreach(at_response->lines, print_glib_list_elem, NULL);
801 if (at_response->success > 0) {
803 if (at_response->lines) {
804 /* fetch first line */
805 gslist_line = (char *)at_response->lines->data;
807 dbg("gslist_line: [%s]", gslist_line);
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);
813 line_token = g_slist_nth_data(tokens, 2); /* Third Token: Length */
814 if (line_token != NULL) {
815 pdu_len = atoi(line_token);
816 dbg("Length: [%d]", pdu_len);
819 /* fetch second line */
820 gslist_line = (char *)at_response->lines->next->data;
822 dbg("gslist_line: [%s]", gslist_line);
824 /* free the consumed token */
825 tcore_at_tok_free(tokens);
827 tokens = tcore_at_tok_new(gslist_line);
828 dbg("Number of tokens: [%d]", g_slist_length(tokens));
829 g_slist_foreach(tokens, print_glib_list_elem, NULL);
831 hex_pdu = g_slist_nth_data(tokens, 0); /* Fetch SMS PDU */
833 /* free the consumed token */
834 tcore_at_tok_free(tokens);
842 /* Convert to Bytes */
843 bytePDU = (unsigned char *)util_hexStringToBytes(hex_pdu);
845 err("util_hexStringToBytes Failed!!");
848 sca_length = bytePDU[0];
850 dbg("SCA length = %d", sca_length);
852 gsmMsgInfo.msgInfo.msgLength = pdu_len;
854 if (sca_length == 0) {
855 memcpy(gsmMsgInfo.msgInfo.tpduData, &bytePDU[1], gsmMsgInfo.msgInfo.msgLength);
857 memcpy(gsmMsgInfo.msgInfo.sca, bytePDU, sca_length);
858 memcpy(gsmMsgInfo.msgInfo.tpduData, &bytePDU[sca_length+1], gsmMsgInfo.msgInfo.msgLength);
861 tcore_util_hex_dump(" ", strlen(hex_pdu)/2, bytePDU);
862 tcore_util_hex_dump(" ", sca_length, gsmMsgInfo.msgInfo.sca);
863 tcore_util_hex_dump(" ", gsmMsgInfo.msgInfo.msgLength, gsmMsgInfo.msgInfo.tpduData);
865 rtn = tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(tcore_pending_ref_core_object(pending))),
866 tcore_pending_ref_core_object(pending),
868 sizeof(struct tnoti_sms_incoming_msg), &gsmMsgInfo);
869 dbg("rtn: [%d]", rtn);
877 static void on_response_read_msg(TcorePending *pending,
878 int data_len, const void *data, void *user_data)
880 const TcoreATResponse *at_response = data;
881 struct tresp_sms_read_msg resp_read_msg;
882 UserRequest *user_req = NULL;
884 GSList *tokens = NULL;
885 char *gslist_line = NULL, *line_token = NULL, *byte_pdu = NULL, *hex_pdu = NULL;
887 int msg_status = 0, alpha_id = 0, pdu_len = 0;
888 int index = (int)(uintptr_t)user_data;
891 dbg("index: [%d]", index);
892 g_slist_foreach(at_response->lines, print_glib_list_elem, NULL);
894 user_req = tcore_pending_ref_user_request(pending);
895 if (NULL == user_req) {
896 err("No user request");
902 memset(&resp_read_msg, 0x00, sizeof(resp_read_msg));
903 resp_read_msg.result = SMS_PHONE_FAILURE;
905 if (at_response->success > 0) {
907 if (at_response->lines) {
908 if (g_slist_length(at_response->lines) != 2) {
909 err("2 lines are required");
912 /* fetch first line */
913 gslist_line = (char *)at_response->lines->data;
915 dbg("gslist_line: [%s]", gslist_line);
917 tokens = tcore_at_tok_new(gslist_line);
918 dbg("Number of tokens: [%d]", g_slist_length(tokens));
919 g_slist_foreach(tokens, print_glib_list_elem, NULL);
921 line_token = g_slist_nth_data(tokens, 0); /* First Token: Message Status */
922 if (line_token != NULL) {
923 msg_status = atoi(line_token);
924 dbg("msg_status is %d", msg_status);
925 switch (msg_status) {
927 resp_read_msg.dataInfo.msgStatus = SMS_STATUS_UNREAD;
931 resp_read_msg.dataInfo.msgStatus = SMS_STATUS_READ;
935 resp_read_msg.dataInfo.msgStatus = SMS_STATUS_UNSENT;
939 resp_read_msg.dataInfo.msgStatus = SMS_STATUS_SENT;
942 case AT_ALL: /* Fall Through */
943 default: /* Fall Through */
944 resp_read_msg.dataInfo.msgStatus = SMS_STATUS_RESERVED;
949 line_token = g_slist_nth_data(tokens, 1); /* Second Token: AlphaID */
950 if (line_token != NULL) {
951 alpha_id = atoi(line_token);
952 dbg("AlphaID: [%d]", alpha_id);
955 line_token = g_slist_nth_data(tokens, 2); /* Third Token: Length */
956 if (line_token != NULL) {
957 pdu_len = atoi(line_token);
958 dbg("Length: [%d]", pdu_len);
961 /* fetch second line */
962 hex_pdu = (char *)at_response->lines->next->data;
964 dbg("EF-SMS PDU: [%s]", hex_pdu);
966 /* free the consumed token */
967 tcore_at_tok_free(tokens);
969 if (NULL != hex_pdu) {
970 tcore_util_hex_dump(" ", strlen(hex_pdu), (void *)hex_pdu);
972 byte_pdu = util_hexStringToBytes(hex_pdu);
974 err("util_hexStringToBytes Failed!!");
977 sca_length = (int)byte_pdu[0];
979 resp_read_msg.dataInfo.simIndex = index; /* Retrieving index stored as user_data */
981 dbg("SCA Length : %d", sca_length);
983 resp_read_msg.dataInfo.smsData.msgLength = pdu_len;
984 dbg("msgLength: [%d]", resp_read_msg.dataInfo.smsData.msgLength);
986 if (0 == sca_length) {
987 if ((resp_read_msg.dataInfo.smsData.msgLength > 0)
988 && (resp_read_msg.dataInfo.smsData.msgLength <= SMS_SMDATA_SIZE_MAX)) {
989 memset(resp_read_msg.dataInfo.smsData.sca, 0, TAPI_SIM_SMSP_ADDRESS_LEN);
990 memcpy(resp_read_msg.dataInfo.smsData.tpduData, &byte_pdu[1], resp_read_msg.dataInfo.smsData.msgLength);
992 resp_read_msg.result = SMS_SUCCESS;
994 dbg("Invalid Message Length");
995 resp_read_msg.result = SMS_INVALID_PARAMETER_FORMAT;
997 } else if (sca_length > SMS_ENCODED_SCA_LEN_MAX) {
998 dbg("Invalid Message Length");
999 resp_read_msg.result = SMS_INVALID_PARAMETER_FORMAT;
1001 if ((resp_read_msg.dataInfo.smsData.msgLength > 0)
1002 && (resp_read_msg.dataInfo.smsData.msgLength <= SMS_SMDATA_SIZE_MAX)) {
1003 memcpy(resp_read_msg.dataInfo.smsData.sca, (char *)byte_pdu, (sca_length+1));
1004 memcpy(resp_read_msg.dataInfo.smsData.tpduData, &byte_pdu[sca_length+1], resp_read_msg.dataInfo.smsData.msgLength);
1006 tcore_util_hex_dump(" ", SMS_SMSP_ADDRESS_LEN, (void *)resp_read_msg.dataInfo.smsData.sca);
1007 tcore_util_hex_dump(" ", (SMS_SMDATA_SIZE_MAX + 1), (void *)resp_read_msg.dataInfo.smsData.tpduData);
1008 tcore_util_hex_dump(" ", strlen(hex_pdu) / 2 + 1, (void *)byte_pdu);
1010 resp_read_msg.result = SMS_SUCCESS;
1012 dbg("Invalid Message Length");
1013 resp_read_msg.result = SMS_INVALID_PARAMETER_FORMAT;
1024 err("Response NOK");
1028 tcore_user_request_send_response(user_req,
1030 sizeof(resp_read_msg), &resp_read_msg);
1036 static void on_response_get_msg_indices(TcorePending *pending,
1037 int data_len, const void *data, void *user_data)
1039 const TcoreATResponse *at_response = data;
1040 struct tresp_sms_get_storedMsgCnt resp_stored_msg_cnt;
1041 UserRequest *user_req = NULL;
1042 struct tresp_sms_get_storedMsgCnt *resp_stored_msg_cnt_prev = NULL;
1044 GSList *tokens = NULL;
1045 char *gslist_line = NULL, *line_token = NULL;
1046 int gslist_line_count = 0, ctr_loop = 0;
1050 resp_stored_msg_cnt_prev = (struct tresp_sms_get_storedMsgCnt *)user_data;
1051 user_req = tcore_pending_ref_user_request(pending);
1053 memset(&resp_stored_msg_cnt, 0x00, sizeof(resp_stored_msg_cnt));
1054 resp_stored_msg_cnt.result = SMS_DEVICE_FAILURE;
1056 if (at_response->success) {
1058 if (at_response->lines) {
1059 gslist_line_count = g_slist_length(at_response->lines);
1061 if (gslist_line_count > SMS_GSM_SMS_MSG_NUM_MAX)
1062 gslist_line_count = SMS_GSM_SMS_MSG_NUM_MAX;
1064 dbg("Number of lines: [%d]", gslist_line_count);
1065 g_slist_foreach(at_response->lines, print_glib_list_elem, NULL);
1067 for (ctr_loop = 0; ctr_loop < gslist_line_count; ctr_loop++) {
1068 gslist_line = (char *)g_slist_nth_data(at_response->lines, ctr_loop); /* Fetch Line i */
1070 dbg("gslist_line [%d] is [%s]", ctr_loop, gslist_line);
1072 if (NULL != gslist_line) {
1073 tokens = tcore_at_tok_new(gslist_line);
1075 g_slist_foreach(tokens, print_glib_list_elem, NULL);
1077 line_token = g_slist_nth_data(tokens, 0);
1078 if (NULL != line_token) {
1079 resp_stored_msg_cnt.storedMsgCnt.indexList[ctr_loop] = atoi(line_token);
1080 resp_stored_msg_cnt.result = SMS_SENDSMS_SUCCESS;
1082 dbg("line_token of gslist_line [%d] is NULL", ctr_loop);
1085 tcore_at_tok_free(tokens);
1087 dbg("gslist_line [%d] is NULL", ctr_loop);
1093 if (resp_stored_msg_cnt_prev->storedMsgCnt.usedCount == 0) /* Check if used count is zero */
1094 resp_stored_msg_cnt.result = SMS_SENDSMS_SUCCESS;
1097 dbg("Respnose NOK");
1100 resp_stored_msg_cnt.storedMsgCnt.totalCount = resp_stored_msg_cnt_prev->storedMsgCnt.totalCount;
1101 resp_stored_msg_cnt.storedMsgCnt.usedCount = resp_stored_msg_cnt_prev->storedMsgCnt.usedCount;
1103 util_sms_free_memory(resp_stored_msg_cnt_prev);
1105 dbg("total: [%d], used: [%d], result: [%d]",
1106 resp_stored_msg_cnt.storedMsgCnt.totalCount,
1107 resp_stored_msg_cnt.storedMsgCnt.usedCount,
1108 resp_stored_msg_cnt.result);
1109 for (ctr_loop = 0; ctr_loop < gslist_line_count; ctr_loop++)
1110 dbg("index: [%d]", resp_stored_msg_cnt.storedMsgCnt.indexList[ctr_loop]);
1112 tcore_user_request_send_response(user_req,
1113 TRESP_SMS_GET_STORED_MSG_COUNT,
1114 sizeof(resp_stored_msg_cnt), &resp_stored_msg_cnt);
1120 static void on_response_get_stored_msg_cnt(TcorePending *pending,
1121 int data_len, const void *data, void *user_data)
1123 UserRequest *ur = NULL, *ur_dup = NULL;
1124 struct tresp_sms_get_storedMsgCnt *respStoredMsgCnt = NULL;
1125 const TcoreATResponse *atResp = data;
1126 GSList *tokens = NULL;
1127 char *line = NULL, *pResp = NULL, *cmd_str = NULL;
1128 TcoreATRequest *atReq = NULL;
1129 int usedCnt = 0, totalCnt = 0, result = 0;
1131 TcorePending *pending_new = NULL;
1132 CoreObject *o = NULL;
1136 respStoredMsgCnt = malloc(sizeof(struct tresp_sms_get_storedMsgCnt));
1137 if (!respStoredMsgCnt)
1140 result = SMS_DEVICE_FAILURE;
1142 ur = tcore_pending_ref_user_request(pending);
1143 ur_dup = tcore_user_request_ref(ur);
1144 o = tcore_pending_ref_core_object(pending);
1146 if (atResp->success > 0) {
1148 if (NULL != atResp->lines) {
1149 line = (char *)atResp->lines->data;
1150 dbg("line is %s", line);
1152 tokens = tcore_at_tok_new(line);
1153 pResp = g_slist_nth_data(tokens, 0);
1156 usedCnt = atoi(pResp);
1157 dbg("used cnt is %d", usedCnt);
1160 pResp = g_slist_nth_data(tokens, 1);
1162 totalCnt = atoi(pResp);
1163 result = SMS_SENDSMS_SUCCESS;
1165 respStoredMsgCnt->storedMsgCnt.usedCount = usedCnt;
1166 respStoredMsgCnt->storedMsgCnt.totalCount = totalCnt;
1167 respStoredMsgCnt->result = result;
1169 dbg("used %d, total %d, result %d", usedCnt, totalCnt, result);
1171 pending_new = tcore_pending_new(o, 0);
1172 /* Get all messages information */
1173 cmd_str = g_strdup_printf("AT+CMGL=4");
1174 atReq = tcore_at_request_new((const char *)cmd_str, "+CMGL", TCORE_AT_MULTILINE);
1176 dbg("cmd str is %s", cmd_str);
1178 tcore_pending_set_request_data(pending_new, 0, atReq);
1179 tcore_pending_set_response_callback(pending_new, on_response_get_msg_indices, (void *)respStoredMsgCnt);
1180 tcore_pending_link_user_request(pending_new, ur_dup);
1181 tcore_pending_set_send_callback(pending_new, on_confirmation_sms_message_send, NULL);
1182 tcore_hal_send_request(tcore_object_get_hal(o), pending_new);
1184 /* free the consumed token */
1185 tcore_at_tok_free(tokens);
1192 /* free the consumed token */
1194 tcore_at_tok_free(tokens);
1199 err("Response NOK");
1202 respStoredMsgCnt->result = result;
1203 tcore_user_request_send_response(ur,
1204 TRESP_SMS_GET_STORED_MSG_COUNT,
1205 sizeof(struct tresp_sms_get_storedMsgCnt), &respStoredMsgCnt);
1212 static void on_response_get_sca(TcorePending *pending,
1213 int data_len, const void *data, void *user_data)
1215 const TcoreATResponse *at_response = data;
1216 struct tresp_sms_get_sca respGetSca;
1217 UserRequest *user_req = NULL;
1219 GSList *tokens = NULL;
1220 const char *sca_tok_addr;
1221 char *gslist_line = NULL, *sca_addr = NULL, *sca_toa = NULL;
1225 memset(&respGetSca, 0, sizeof(respGetSca));
1226 respGetSca.result = SMS_DEVICE_FAILURE;
1228 user_req = tcore_pending_ref_user_request(pending);
1230 if (at_response->success) {
1232 if (at_response->lines) {
1233 gslist_line = (char *)at_response->lines->data;
1235 tokens = tcore_at_tok_new(gslist_line);
1236 sca_tok_addr = g_slist_nth_data(tokens, 0);
1237 sca_toa = g_slist_nth_data(tokens, 1);
1239 sca_addr = tcore_at_tok_extract(sca_tok_addr);
1240 if ((NULL != sca_addr)
1241 && (NULL != sca_toa)) {
1242 dbg("sca_addr: [%s]. sca_toa: [%s]", sca_addr, sca_toa);
1244 respGetSca.scaAddress.dialNumLen = strlen(sca_addr);
1246 if (145 == atoi(sca_toa))
1247 respGetSca.scaAddress.typeOfNum = SIM_TON_INTERNATIONAL;
1249 respGetSca.scaAddress.typeOfNum = SIM_TON_NATIONAL;
1251 respGetSca.scaAddress.numPlanId = 0;
1253 memcpy(respGetSca.scaAddress.diallingNum, sca_addr, strlen(sca_addr));
1255 dbg("len [%d], sca_addr [%s], TON [%d], NPI [%d]",
1256 respGetSca.scaAddress.dialNumLen,
1257 respGetSca.scaAddress.diallingNum,
1258 respGetSca.scaAddress.typeOfNum,
1259 respGetSca.scaAddress.numPlanId);
1261 respGetSca.result = SMS_SENDSMS_SUCCESS;
1263 err("sca_addr OR sca_toa NULL");
1269 dbg("Response NOK");
1272 tcore_user_request_send_response(user_req,
1274 sizeof(respGetSca), &respGetSca);
1276 tcore_at_tok_free(tokens);
1282 static void on_response_set_sca(TcorePending *pending,
1283 int data_len, const void *data, void *user_data)
1286 * Response is expected in this format
1292 const TcoreATResponse *atResp = data;
1293 struct tresp_sms_set_sca respSetSca;
1295 memset(&respSetSca, 0, sizeof(struct tresp_sms_set_sca));
1297 ur = tcore_pending_ref_user_request(pending);
1299 dbg("no user_request");
1303 if (atResp->success > 0) {
1305 respSetSca.result = SMS_SUCCESS;
1307 dbg("RESPONSE NOK");
1308 respSetSca.result = SMS_DEVICE_FAILURE;
1311 tcore_user_request_send_response(ur,
1313 sizeof(struct tresp_sms_set_sca), &respSetSca);
1316 static void on_response_get_cb_config(TcorePending *p,
1317 int data_len, const void *data, void *user_data)
1320 struct tresp_sms_get_cb_config respGetCbConfig;
1321 const TcoreATResponse *atResp = data;
1322 GSList *tokens = NULL;
1323 int i = 0, mode = 0;
1324 char *pResp = NULL, *line = NULL;
1326 memset(&respGetCbConfig, 0, sizeof(struct tresp_sms_get_cb_config));
1327 respGetCbConfig.result = SMS_DEVICE_FAILURE;
1329 ur = tcore_pending_ref_user_request(p);
1331 dbg("no user_request");
1335 respGetCbConfig.cbConfig.net3gppType = SMS_NETTYPE_3GPP;
1336 respGetCbConfig.cbConfig.msgIdMaxCount = SMS_GSM_SMS_CBMI_LIST_SIZE_MAX;
1338 if (atResp->success) {
1340 if (atResp->lines) {
1341 line = (char *)atResp->lines->data;
1343 dbg("line is %s", line);
1344 tokens = tcore_at_tok_new(line);
1345 pResp = g_slist_nth_data(tokens, 0);
1348 respGetCbConfig.cbConfig.cbEnabled = mode;
1350 pResp = g_slist_nth_data(tokens, 1);
1352 GSList *cb_tokens = NULL;
1353 char *cb_mid_str = NULL;
1354 int num_cb_tokens = 0;
1355 char *mid_tok = NULL;
1356 char *first_tok = NULL, *second_tok = NULL;
1359 /* 0, 1, 5, 320-478, 922 */
1360 cb_mid_str = tcore_at_tok_extract(pResp);
1361 cb_tokens = tcore_at_tok_new((const char *)cb_mid_str);
1365 num_cb_tokens = g_slist_length(cb_tokens);
1366 dbg("num_cb_tokens = %d", num_cb_tokens);
1368 if (num_cb_tokens == 0) {
1369 if (mode == 1) { /* Enable all CBs */
1370 respGetCbConfig.cbConfig.msgIdRangeCount = 1;
1371 respGetCbConfig.cbConfig.msgIDs[0].net3gpp.fromMsgId = 0x0000;
1372 respGetCbConfig.cbConfig.msgIDs[0].net3gpp.toMsgId = SMS_GSM_SMS_CBMI_LIST_SIZE_MAX + 1;
1373 respGetCbConfig.cbConfig.msgIDs[0].net3gpp.selected = TRUE;
1374 respGetCbConfig.result = SMS_SENDSMS_SUCCESS;
1375 } else { /* all CBs disabled */
1376 respGetCbConfig.cbConfig.msgIdRangeCount = 0;
1377 respGetCbConfig.cbConfig.msgIDs[0].net3gpp.selected = FALSE;
1378 respGetCbConfig.result = SMS_SENDSMS_SUCCESS;
1381 respGetCbConfig.cbConfig.msgIdRangeCount = 0;
1382 respGetCbConfig.cbConfig.msgIDs[0].net3gpp.selected = FALSE;
1383 respGetCbConfig.result = SMS_SENDSMS_SUCCESS;
1386 for (i = 0; i < num_cb_tokens; i++) {
1387 respGetCbConfig.cbConfig.msgIDs[i].net3gpp.selected = TRUE;
1388 respGetCbConfig.cbConfig.msgIdRangeCount++;
1390 mid_tok = tcore_at_tok_nth(cb_tokens, i);
1391 first_tok = strtok_r(mid_tok, "-", &ptr);
1392 second_tok = strtok_r(NULL, "-", &ptr);
1394 if ((first_tok != NULL) && (second_tok != NULL)) {
1395 /* mids in range (320-478) */
1396 dbg("inside if mid_range");
1397 respGetCbConfig.cbConfig.msgIDs[i].net3gpp.fromMsgId = atoi(first_tok);
1398 respGetCbConfig.cbConfig.msgIDs[i].net3gpp.toMsgId = atoi(second_tok);
1400 /* single mid value (0, 1, 5, 922) */
1401 respGetCbConfig.cbConfig.msgIDs[i].net3gpp.fromMsgId = atoi(mid_tok);
1402 respGetCbConfig.cbConfig.msgIDs[i].net3gpp.toMsgId = atoi(mid_tok);
1408 dbg("line is NULL");
1411 dbg("atresp->lines is NULL");
1414 dbg("RESPONSE NOK");
1417 tcore_user_request_send_response(ur,
1418 TRESP_SMS_GET_CB_CONFIG,
1419 sizeof(struct tresp_sms_get_cb_config), &respGetCbConfig);
1422 tcore_at_tok_free(tokens);
1425 static void on_response_set_cb_config(TcorePending *pending,
1426 int data_len, const void *data, void *user_data)
1429 * Response is expected in this format
1435 const TcoreATResponse *resp = data;
1437 const char *line = NULL;
1438 GSList *tokens = NULL;
1440 struct tresp_sms_set_cb_config respSetCbConfig = {0, };
1442 memset(&respSetCbConfig, 0, sizeof(struct tresp_sms_set_cb_config));
1444 ur = tcore_pending_ref_user_request(pending);
1445 respSetCbConfig.result = SMS_SENDSMS_SUCCESS;
1447 if (resp->success > 0) {
1450 dbg("RESPONSE NOK");
1451 line = (const char *)resp->final_response;
1452 tokens = tcore_at_tok_new(line);
1454 if (g_slist_length(tokens) < 1) {
1455 dbg("err cause not specified or string corrupted");
1456 respSetCbConfig.result = SMS_DEVICE_FAILURE;
1458 response = atoi(g_slist_nth_data(tokens, 0));
1459 dbg("response is %d", response);
1460 /* TODO: CMEE error mapping is required. */
1461 respSetCbConfig.result = SMS_DEVICE_FAILURE;
1466 dbg("no user_request");
1470 tcore_user_request_send_response(ur,
1471 TRESP_SMS_SET_CB_CONFIG,
1472 sizeof(struct tresp_sms_set_cb_config), &respSetCbConfig);
1475 tcore_at_tok_free(tokens);
1478 static void on_response_set_mem_status(TcorePending *p,
1479 int data_len, const void *data, void *user_data)
1482 struct tresp_sms_set_mem_status respSetMemStatus = {0, };
1483 const TcoreATResponse *resp = data;
1485 memset(&respSetMemStatus, 0, sizeof(struct tresp_sms_set_mem_status));
1487 if (resp->success > 0) {
1489 respSetMemStatus.result = SMS_SENDSMS_SUCCESS;
1491 dbg("RESPONSE NOK");
1492 respSetMemStatus.result = SMS_DEVICE_FAILURE;
1495 ur = tcore_pending_ref_user_request(p);
1497 dbg("no user_request");
1501 tcore_user_request_send_response(ur,
1502 TRESP_SMS_SET_MEM_STATUS,
1503 sizeof(struct tresp_sms_set_mem_status), &respSetMemStatus);
1506 static void on_response_set_msg_status(TcorePending *pending,
1507 int data_len, const void *data, void *user_data)
1510 struct tresp_sms_set_msg_status respMsgStatus = {0, };
1511 const TcoreATResponse *atResp = data;
1512 int response = 0, sw1 = 0, sw2 = 0;
1513 const char *line = NULL;
1515 GSList *tokens = NULL;
1519 memset(&respMsgStatus, 0, sizeof(struct tresp_sms_set_msg_status));
1520 respMsgStatus.result = SMS_DEVICE_FAILURE;
1522 ur = tcore_pending_ref_user_request(pending);
1524 if (atResp->success > 0) {
1527 if (atResp->lines) {
1528 line = (const char *)atResp->lines->data;
1529 tokens = tcore_at_tok_new(line);
1530 pResp = g_slist_nth_data(tokens, 0);
1536 pResp = g_slist_nth_data(tokens, 1);
1537 if (pResp != NULL) {
1539 if ((sw1 == AT_SW1_SUCCESS) && (sw2 == 0))
1540 respMsgStatus.result = SMS_SENDSMS_SUCCESS;
1544 pResp = g_slist_nth_data(tokens, 3);
1546 if (pResp != NULL) {
1547 response = atoi(pResp);
1548 dbg("response is %d", response);
1554 dbg("RESPONSE NOK");
1557 tcore_user_request_send_response(ur,
1558 TRESP_SMS_SET_MSG_STATUS,
1559 sizeof(struct tresp_sms_set_msg_status), &respMsgStatus);
1562 tcore_at_tok_free(tokens);
1567 static void on_response_get_sms_params(TcorePending *pending,
1568 int data_len, const void *data, void *user_data)
1571 struct tresp_sms_get_params respGetParams ;
1572 const TcoreATResponse *atResp = data;
1573 int sw1 = 0, sw2 = 0;
1574 const char *line = NULL;
1576 GSList *tokens = NULL;
1577 char *hexData = NULL;
1578 char *recordData = NULL;
1581 memset(&respGetParams, 0, sizeof(struct tresp_sms_get_params));
1582 respGetParams.result = SMS_DEVICE_FAILURE;
1584 ur = tcore_pending_ref_user_request(pending);
1586 if (atResp->success > 0) {
1589 if (atResp->lines) {
1590 line = (const char *)atResp->lines->data;
1591 tokens = tcore_at_tok_new(line);
1592 pResp = g_slist_nth_data(tokens, 0);
1593 if (pResp != NULL) {
1595 dbg("sw1 is %d", sw1);
1599 pResp = g_slist_nth_data(tokens, 1);
1600 if (pResp != NULL) {
1602 dbg("sw2 is %d", sw2);
1603 if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91)
1604 respGetParams.result = SMS_SENDSMS_SUCCESS;
1608 pResp = g_slist_nth_data(tokens, 2);
1609 if (pResp != NULL) {
1610 hexData = tcore_at_tok_extract(pResp);
1612 recordData = util_hexStringToBytes(hexData);
1613 tcore_util_hex_dump(" ", strlen(hexData) / 2, recordData);
1615 respGetParams.paramsInfo.recordLen = strlen(hexData) / 2;
1617 util_sms_decode_smsParameters((unsigned char *)recordData, strlen(hexData) / 2, &(respGetParams.paramsInfo));
1618 respGetParams.result = SMS_SENDSMS_SUCCESS;
1620 for (i = 0; i < (int) respGetParams.paramsInfo.tpSvcCntrAddr.dialNumLen; i++)
1621 dbg("SCAddr = %d [%02x]", i, respGetParams.paramsInfo.tpSvcCntrAddr.diallingNum[i]);
1629 tcore_at_tok_free(tokens);
1632 dbg("RESPONSE NOK");
1635 tcore_user_request_send_response(ur,
1636 TRESP_SMS_GET_PARAMS,
1637 sizeof(struct tresp_sms_get_params), &respGetParams);
1642 static void on_response_set_sms_params(TcorePending *pending,
1643 int data_len, const void *data, void *user_data)
1646 struct tresp_sms_set_params respSetParams = {0, };
1647 const TcoreATResponse *atResp = data;
1648 int sw1 = 0, sw2 = 0;
1649 const char *line = NULL;
1651 GSList *tokens = NULL;
1654 memset(&respSetParams, 0, sizeof(struct tresp_sms_set_params));
1655 ur = tcore_pending_ref_user_request(pending);
1657 respSetParams.result = SMS_DEVICE_FAILURE;
1659 if (atResp->success > 0) {
1662 if (atResp->lines) {
1663 line = (const char *)atResp->lines->data;
1664 tokens = tcore_at_tok_new(line);
1665 pResp = g_slist_nth_data(tokens, 0);
1671 pResp = g_slist_nth_data(tokens, 1);
1672 if (pResp != NULL) {
1674 if (((sw1 == AT_SW1_SUCCESS) && (sw2 == AT_SW2_SUCCESS)) || (sw1 == 0x91))
1675 respSetParams.result = SMS_SENDSMS_SUCCESS;
1683 dbg("RESPONSE NOK");
1686 tcore_user_request_send_response(ur,
1687 TRESP_SMS_SET_PARAMS,
1688 sizeof(struct tresp_sms_set_params), &respSetParams);
1691 tcore_at_tok_free(tokens);
1696 static void on_response_get_paramcnt(TcorePending *p,
1697 int data_len, const void *data, void *user_data)
1699 UserRequest *ur = NULL;
1700 struct tresp_sms_get_paramcnt respGetParamCnt = {0, };
1701 const TcoreATResponse *atResp = data;
1702 char *line = NULL, *pResp = NULL;
1703 int sw1 = 0, sw2 = 0, *smsp_record_len = NULL;
1705 GSList *tokens = NULL;
1706 CoreObject *co_sim = NULL; /* need this to get the sim type GSM/USIM */
1707 TcorePlugin *plugin = NULL;
1711 ur = tcore_pending_ref_user_request(p);
1712 respGetParamCnt.result = SMS_DEVICE_FAILURE;
1714 if (atResp->success > 0) {
1717 if (atResp->lines) {
1718 line = (char *)atResp->lines->data;
1720 dbg("line is %s", line);
1722 tokens = tcore_at_tok_new(line);
1723 pResp = g_slist_nth_data(tokens, 0);
1729 pResp = g_slist_nth_data(tokens, 1);
1730 if (pResp != NULL) {
1732 if ((sw1 == 144) && (sw2 == 0))
1733 respGetParamCnt.result = SMS_SENDSMS_SUCCESS;
1737 pResp = g_slist_nth_data(tokens, 2);
1738 if (pResp != NULL) {
1739 char *hexData = NULL;
1740 char *recordData = NULL;
1741 hexData = tcore_at_tok_extract(pResp);
1743 /*1. SIM access success case*/
1744 if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
1745 unsigned char tag_len = 0; /* 1 or 2 bytes ??? */
1747 char num_of_records = 0;
1748 unsigned char file_id_len = 0;
1749 unsigned short file_id = 0;
1750 unsigned short file_size = 0;
1751 unsigned short file_type = 0;
1752 unsigned short arr_file_id = 0;
1753 int arr_file_id_rec_num = 0;
1755 /* handling only last 3 bits */
1756 unsigned char file_type_tag = 0x07;
1757 unsigned char *ptr_data;
1759 recordData = util_hexStringToBytes(hexData);
1761 err("util_hexStringToBytes Failed!!");
1762 tcore_at_tok_free(tokens);
1765 tcore_util_hex_dump(" ", strlen(hexData)/2, recordData);
1767 ptr_data = (unsigned char *)recordData;
1769 co_sim = tcore_plugin_ref_core_object(tcore_pending_ref_plugin(p), CORE_OBJECT_TYPE_SIM);
1770 sim_type = tcore_sim_get_type(co_sim);
1771 dbg("sim type is %d", sim_type);
1773 if (sim_type == SIM_TYPE_USIM) {
1775 * ETSI TS 102 221 v7.9.0
1777 * '62' FCP template tag
1778 * - Response for an EF
1779 * '82' M File Descriptor
1780 * '83' M File Identifier
1781 * 'A5' O Proprietary information
1782 * '8A' M Life Cycle Status Integer
1783 * '8B', '8C' or 'AB' C1 Security attributes
1785 * '81' O Total file size
1786 * '88' O Short File Identifier (SFI)
1789 /* rsim.res_len has complete data length received */
1791 /* FCP template tag - File Control Parameters tag*/
1792 if (*ptr_data == 0x62) {
1793 /* parse complete FCP tag*/
1794 /* increment to next byte */
1796 tag_len = *ptr_data++;
1797 dbg("tag_len: [%d]", tag_len);
1799 /* FCP file descriptor - file type, accessibility, DF, ADF etc*/
1800 if (*ptr_data == 0x82) {
1801 /* increment to next byte */
1807 /* unsigned char file_desc_len = *ptr_data++;*/
1808 /* dbg("file descriptor length: [%d]", file_desc_len);*/
1809 /* TBD: currently capture only file type : ignore sharable, non sharable, working, internal etc*/
1810 /* consider only last 3 bits*/
1811 file_type_tag = file_type_tag & (*ptr_data);
1813 switch (file_type_tag) {
1814 /* increment to next byte */
1818 dbg("Getting FileType: [Transparent file type]");
1819 /* increment to next byte */
1821 file_type = 0x01; /* SIM_FTYPE_TRANSPARENT */
1823 /* data coding byte - value 21 */
1828 dbg("Getting FileType: [Linear fixed file type]");
1829 /* increment to next byte */
1832 /* data coding byte - value 21 */
1836 memcpy(&record_len, ptr_data, 2);
1839 record_len = SMS_SWAPBYTES16(record_len);
1840 ptr_data = ptr_data + 2;
1841 num_of_records = *ptr_data++;
1843 /* Data lossy conversation from enum (int) to unsigned char */
1844 file_type = 0x02; /* SIM_FTYPE_LINEAR_FIXED */
1848 dbg(" Cyclic fixed file type");
1849 /* increment to next byte */
1852 /* data coding byte - value 21 */
1856 memcpy(&record_len, ptr_data, 2);
1859 record_len = SMS_SWAPBYTES16(record_len);
1860 ptr_data = ptr_data + 2;
1861 num_of_records = *ptr_data++;
1862 file_type = 0x04; /* SIM_FTYPE_CYCLIC */
1866 dbg("not handled file type [0x%x]", *ptr_data);
1870 dbg("INVALID FCP received - DEbug!");
1873 tcore_at_tok_free(tokens);
1878 * File identifier - file id??
1880 * 0x84, 0x85, 0x86 etc are currently ignored and not handled
1882 if (*ptr_data == 0x83) {
1883 /* increment to next byte */
1885 file_id_len = *ptr_data++;
1886 memcpy(&file_id, ptr_data, file_id_len);
1889 file_id = SMS_SWAPBYTES16(file_id);
1890 ptr_data = ptr_data + 2;
1891 dbg("Getting FileID=[0x%x]", file_id);
1893 dbg("INVALID FCP received - DEbug!");
1896 tcore_at_tok_free(tokens);
1900 /* proprietary information */
1901 if (*ptr_data == 0xA5) {
1902 unsigned short prop_len;
1903 /* increment to next byte */
1907 prop_len = *ptr_data;
1910 ptr_data = ptr_data + prop_len + 1;
1912 dbg("INVALID FCP received - DEbug!");
1915 /* life cycle status integer [8A][length:0x01][status]*/
1918 * 00000000 : No information given
1919 * 00000001 : creation state
1920 * 00000011 : initialization state
1921 * 000001-1 : operation state -activated
1922 * 000001-0 : operation state -deactivated
1923 * 000011-- : Termination state
1924 * b8~b5 !=0, b4~b1=X : Proprietary
1925 * Any other value : RFU
1927 if (*ptr_data == 0x8A) {
1928 /* increment to next byte */
1930 /* length - value 1 */
1933 switch (*ptr_data) {
1936 dbg("[RX] Operation State: DEACTIVATED");
1942 dbg("[RX] Operation State: ACTIVATED");
1947 dbg("[RX] DEBUG! LIFE CYCLE STATUS: [0x%x]", *ptr_data);
1953 /* related to security attributes : currently not handled*/
1954 if (*ptr_data == 0x86 || *ptr_data == 0x8B || *ptr_data == 0x8C || *ptr_data == 0xAB) {
1955 /* increment to next byte */
1958 /* if tag length is 3 */
1959 if (*ptr_data == 0x03) {
1960 /* increment to next byte */
1964 memcpy(&arr_file_id, ptr_data, 2);
1967 arr_file_id = SMS_SWAPBYTES16(arr_file_id);
1968 ptr_data = ptr_data + 2;
1969 arr_file_id_rec_num = *ptr_data++;
1970 dbg("arr_file_id_rec_num: [%d]", arr_file_id_rec_num);
1972 /* if tag length is not 3 */
1973 /* ignoring bytes */
1974 dbg("Useless security attributes, so jump to next tag");
1975 ptr_data = ptr_data + (*ptr_data + 1);
1978 dbg("INVALID FCP received[0x%x] - DEbug!", *ptr_data);
1981 tcore_at_tok_free(tokens);
1985 dbg("Current ptr_data value is [%x]", *ptr_data);
1987 /* file size excluding structural info*/
1988 if (*ptr_data == 0x80) {
1990 * for EF file size is body of file and for Linear or cyclic it is
1991 * number of recXsizeof(one record)
1993 /* increment to next byte */
1996 /* length is 1 byte - value is 2 bytes or more */
1998 memcpy(&file_size, ptr_data, 2);
2001 file_size = SMS_SWAPBYTES16(file_size);
2002 ptr_data = ptr_data + 2;
2004 dbg("INVALID FCP received - DEbug!");
2007 tcore_at_tok_free(tokens);
2011 /* total file size including structural info*/
2012 if (*ptr_data == 0x81) {
2014 /* increment to next byte */
2019 dbg("len: [%d]", len);
2022 ptr_data = ptr_data + 3;
2024 dbg("INVALID FCP received - DEbug!");
2025 /* 0x81 is optional tag?? check out! so do not return -1 from here! */
2028 /*short file identifier ignored*/
2029 if (*ptr_data == 0x88) {
2030 dbg("0x88: Do Nothing");
2034 dbg("INVALID FCP received - DEbug!");
2037 tcore_at_tok_free(tokens);
2040 } else if (sim_type == SIM_TYPE_GSM) {
2041 unsigned char gsm_specific_file_data_len = 0;
2042 /* ignore RFU byte1 and byte2 */
2047 memcpy(&file_size, ptr_data, 2);
2050 file_size = SMS_SWAPBYTES16(file_size);
2052 /* parsed file size */
2053 ptr_data = ptr_data + 2;
2056 memcpy(&file_id, ptr_data, 2);
2057 file_id = SMS_SWAPBYTES16(file_id);
2058 dbg(" FILE id --> [%x]", file_id);
2059 ptr_data = ptr_data + 2;
2061 /* save file type - transparent, linear fixed or cyclic */
2062 file_type_tag = (*(ptr_data + 7));
2064 switch (*ptr_data) {
2067 dbg(" RFU file type- not handled - Debug!");
2072 dbg(" MF file type - not handled - Debug!");
2077 dbg(" DF file type - not handled - Debug!");
2082 dbg(" EF file type [%d] ", file_type_tag);
2083 /* increment to next byte */
2086 if (file_type_tag == 0x00 || file_type_tag == 0x01) {
2087 /* increament to next byte as this byte is RFU */
2089 file_type = (file_type_tag == 0x00) ? 0x01 : 0x02; /* SIM_FTYPE_TRANSPARENT:SIM_FTYPE_LINEAR_FIXED; */
2091 /* increment to next byte */
2094 /* For a cyclic EF all bits except bit 7 are RFU; b7=1 indicates that */
2095 /* the INCREASE command is allowed on the selected cyclic file. */
2096 file_type = 0x04; /* SIM_FTYPE_CYCLIC; */
2099 /* bytes 9 to 11 give SIM file access conditions */
2102 /* byte 10 has one nibble that is RF U and another for INCREASE which is not used currently */
2105 /* byte 11 is invalidate and rehabilate nibbles */
2108 /* byte 12 - file status */
2111 /* byte 13 - GSM specific data */
2112 gsm_specific_file_data_len = *ptr_data;
2113 dbg("gsm_specific_file_data_len: [%d]", gsm_specific_file_data_len);
2116 /* byte 14 - structure of EF - transparent or linear or cyclic, already saved above */
2119 /* byte 15 - length of record for linear and cyclic, for transparent it is set to 0x00. */
2120 record_len = *ptr_data;
2121 dbg("record length[%d], file size[%d]", record_len, file_size);
2123 if (record_len != 0)
2124 num_of_records = (file_size / record_len);
2126 dbg("Number of records [%d]", num_of_records);
2130 dbg(" not handled file type");
2134 dbg(" Card Type - UNKNOWN [%d]", sim_type);
2137 dbg("EF[0x%x] size[%ld] Type[0x%x] NumOfRecords[%ld] RecordLen[%ld]",
2138 file_id, file_size, file_type, num_of_records, record_len);
2140 respGetParamCnt.recordCount = num_of_records;
2141 respGetParamCnt.result = SMS_SUCCESS;
2143 /* TO Store smsp record length in the property */
2144 plugin = tcore_pending_ref_plugin(p);
2145 smsp_record_len = tcore_plugin_ref_property(plugin, "SMSPRECORDLEN");
2146 memcpy(smsp_record_len, &record_len, sizeof(int));
2151 /*2. SIM access fail case*/
2152 dbg("SIM access fail");
2153 respGetParamCnt.result = SMS_UNKNOWN;
2156 dbg("presp is NULL");
2159 dbg("line is blank");
2162 dbg("RESPONSE NOK");
2165 tcore_user_request_send_response(ur,
2166 TRESP_SMS_GET_PARAMCNT,
2167 sizeof(struct tresp_sms_get_paramcnt), &respGetParamCnt);
2170 tcore_at_tok_free(tokens);
2176 static void _response_get_efsms_data(TcorePending *p, int data_len, const void *data, void *user_data)
2178 UserRequest *ur = NULL;
2179 UserRequest *dup_ur = NULL;
2180 struct tresp_sms_set_msg_status resp_msg_status = {0, };
2181 const struct treq_sms_set_msg_status *req_msg_status = NULL ;
2183 const TcoreATResponse *resp = data;
2184 char *encoded_data = NULL;
2185 char msg_status = 0;
2187 GSList *tokens = NULL;
2188 const char *line = NULL;
2192 TcoreHal *hal = NULL;
2193 TcoreATRequest *atreq = NULL;
2194 TcorePending *pending = NULL;
2195 gchar *cmd_str = NULL;
2197 ur = tcore_pending_ref_user_request(p);
2199 req_msg_status = tcore_user_request_ref_data(ur, NULL);
2201 resp_msg_status.result = SMS_DEVICE_FAILURE;
2203 hal = tcore_object_get_hal(tcore_pending_ref_core_object(pending));
2204 dbg("msgStatus: [%x], index [%x]", req_msg_status->msgStatus, req_msg_status->index);
2206 if (resp->success <= 0)
2211 line = (const char *)resp->lines->data;
2212 tokens = tcore_at_tok_new(line);
2213 if (g_slist_length(tokens) != 3) {
2214 msg("invalid message");
2218 sw1 = atoi(g_slist_nth_data(tokens, 0));
2219 sw2 = atoi(g_slist_nth_data(tokens, 1));
2220 pResp = g_slist_nth_data(tokens, 2);
2222 if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
2223 switch (req_msg_status->msgStatus) {
2224 case SMS_STATUS_READ:
2228 case SMS_STATUS_UNREAD:
2232 case SMS_STATUS_UNSENT:
2236 case SMS_STATUS_SENT:
2240 case SMS_STATUS_DELIVERED:
2244 case SMS_STATUS_DELIVERY_UNCONFIRMED:
2248 case SMS_STATUS_MESSAGE_REPLACED:
2249 case SMS_STATUS_RESERVED:
2255 encoded_data = tcore_at_tok_extract(pResp);
2256 if (!encoded_data) {
2257 err("Encoded data is NULL");
2261 /* Overwrite Status byte information */
2262 util_byte_to_hex((const char *)&msg_status, (char *)encoded_data, 1);
2264 /* Update EF-SMS with just status byte overwritten, rest 175 bytes are same as received in read information */
2265 cmd_str = g_strdup_printf("AT+CRSM=220, 28476, %d, 4, %d, \"%s\"", (req_msg_status->index+1), PDU_LEN_MAX, encoded_data);
2266 atreq = tcore_at_request_new((const char *)cmd_str, "+CRSM", TCORE_AT_SINGLELINE);
2267 pending = tcore_pending_new(tcore_pending_ref_core_object(pending), 0);
2268 if (NULL == cmd_str || NULL == atreq || NULL == pending) {
2269 err("Out of memory. Unable to proceed");
2270 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
2273 g_free(encoded_data);
2274 util_sms_free_memory(atreq);
2275 util_sms_free_memory(pending);
2280 tcore_util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
2282 dup_ur = tcore_user_request_ref(ur);
2284 tcore_pending_set_request_data(pending, 0, atreq);
2285 tcore_pending_set_response_callback(pending, on_response_set_msg_status, NULL);
2286 tcore_pending_link_user_request(pending, dup_ur);
2287 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
2288 tcore_hal_send_request(hal, pending);
2291 g_free(encoded_data);
2293 resp_msg_status.result = SMS_SENDSMS_SUCCESS;
2298 tcore_at_tok_free(tokens);
2300 tcore_user_request_send_response(ur,
2301 TRESP_SMS_SET_MSG_STATUS,
2302 sizeof(struct tresp_sms_set_msg_status), &resp_msg_status);
2312 static TReturn send_umts_msg(CoreObject *co_sms, UserRequest *ur)
2314 const struct treq_sms_send_msg *send_msg;
2315 const unsigned char *tpdu_byte_data;
2316 const unsigned char *sca_byte_data;
2319 int pdu_hex_len = 0;
2320 char buf[HEX_PDU_LEN_MAX];
2321 char pdu[PDU_LEN_MAX];
2328 send_msg = tcore_user_request_ref_data(ur, NULL);
2330 /* Validating the Message Format */
2331 if (SMS_NETTYPE_3GPP == send_msg->msgDataPackage.format) {
2332 info("3gpp format received");
2334 info("invalid format received");
2335 return TCORE_RETURN_EINVAL;
2338 tpdu_byte_data = send_msg->msgDataPackage.tpduData;
2339 sca_byte_data = send_msg->msgDataPackage.sca;
2342 /* TPDU length is in byte */
2343 tpdu_byte_len = send_msg->msgDataPackage.msgLength;
2344 dbg("TDPU length: [%d]", tpdu_byte_len);
2345 dbg("SCA semi-octet length: [%d]", sca_byte_data[0]);
2347 /* Use same Radio Resource Channel */
2348 mms = send_msg->more;
2350 /* Prepare PDU for hex encoding */
2351 pdu_byte_len = __util_sms_encode_pdu(sca_byte_data, tpdu_byte_data,
2352 tpdu_byte_len, pdu);
2354 pdu_hex_len = (int) __util_sms_encode_hex((unsigned char *)pdu,
2357 dbg("PDU hexadecimal length: [%d]", pdu_hex_len);
2360 cmd_str = g_strdup_printf("AT+CMMS=%d", mms);
2362 ret = tcore_prepare_and_send_at_request(co_sms, cmd_str, NULL,
2363 TCORE_AT_NO_RESULT, NULL, NULL, NULL,
2364 on_confirmation_sms_message_send,
2365 NULL, 0, NULL, NULL);
2366 if (ret != TCORE_RETURN_SUCCESS) {
2367 err("Failed to prepare and send AT request");
2374 cmd_str = g_strdup_printf("AT+CMGS=%d\r%s\x1A", tpdu_byte_len, buf);
2376 ret = tcore_prepare_and_send_at_request(co_sms, cmd_str, "+CMGS:",
2377 TCORE_AT_SINGLELINE, ur,
2378 on_response_send_umts_msg, NULL,
2379 on_confirmation_sms_message_send, NULL,
2381 if (ret != TCORE_RETURN_SUCCESS)
2382 err("Failed to prepare and send AT request");
2392 static TReturn read_msg(CoreObject *obj, UserRequest *ur)
2394 gchar *cmd_str = NULL;
2395 TcoreHal *hal = NULL;
2396 TcoreATRequest *atreq = NULL;
2397 TcorePending *pending = NULL;
2398 const struct treq_sms_read_msg *readMsg = NULL;
2402 readMsg = tcore_user_request_ref_data(ur, NULL);
2403 hal = tcore_object_get_hal(obj);
2404 if (NULL == readMsg || NULL == hal) {
2405 err("NULL input. Unable to proceed");
2406 dbg("readMsg: [%p], hal: [%p]", readMsg, hal);
2409 return TCORE_RETURN_EINVAL;
2412 if (FALSE == tcore_hal_get_power_state(hal)) {
2413 dbg("cp not ready/n");
2414 return TCORE_RETURN_ENOSYS;
2416 dbg("index: [%d]", readMsg->index);
2418 cmd_str = g_strdup_printf("AT+CMGR=%d", readMsg->index);
2419 atreq = tcore_at_request_new((const char *)cmd_str, "+CMGR", TCORE_AT_PDU);
2420 pending = tcore_pending_new(obj, 0);
2422 if (NULL == cmd_str || NULL == atreq || NULL == pending) {
2423 err("Out of memory. Unable to proceed");
2424 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
2427 util_sms_free_memory(atreq);
2428 util_sms_free_memory(pending);
2431 return TCORE_RETURN_ENOMEM;
2434 tcore_util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
2436 tcore_pending_set_request_data(pending, 0, atreq);
2437 tcore_pending_set_response_callback(pending, on_response_read_msg, (void *)(uintptr_t)(readMsg->index)); /* storing index as user data for response */
2438 tcore_pending_link_user_request(pending, ur);
2439 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
2440 tcore_hal_send_request(hal, pending);
2445 return TCORE_RETURN_SUCCESS;
2448 static TReturn save_msg(CoreObject *obj, UserRequest *ur)
2450 gchar *cmd_str = NULL;
2451 TcoreHal *hal = NULL;
2452 TcoreATRequest *atreq = NULL;
2453 TcorePending *pending = NULL;
2454 const struct treq_sms_save_msg *saveMsg = NULL;
2455 int ScLength = 0, pdu_len = 0, stat = 0;
2456 char buf[2 * (SMS_SMSP_ADDRESS_LEN + SMS_SMDATA_SIZE_MAX) + 1] = {0};
2457 char *hex_pdu = NULL;
2461 saveMsg = tcore_user_request_ref_data(ur, NULL);
2462 hal = tcore_object_get_hal(obj);
2463 if (NULL == saveMsg || NULL == hal) {
2464 err("NULL input. Unable to proceed");
2465 dbg("saveMsg: [%p], hal: [%p]", saveMsg, hal);
2468 return TCORE_RETURN_EINVAL;
2470 if (FALSE == tcore_hal_get_power_state(hal)) {
2471 dbg("cp not ready/n");
2472 return TCORE_RETURN_ENOSYS;
2475 dbg("msgStatus: %x, msgLength: [%d]", saveMsg->msgStatus, saveMsg->msgDataPackage.msgLength);
2476 tcore_util_hex_dump(" ", (SMS_SMDATA_SIZE_MAX+1), (void *)saveMsg->msgDataPackage.tpduData);
2477 tcore_util_hex_dump(" ", SMS_SMSP_ADDRESS_LEN, (void *)saveMsg->msgDataPackage.sca);
2479 switch (saveMsg->msgStatus) {
2480 case SMS_STATUS_READ:
2484 case SMS_STATUS_UNREAD:
2485 stat = AT_REC_UNREAD;
2488 case SMS_STATUS_SENT:
2492 case SMS_STATUS_UNSENT:
2493 stat = AT_STO_UNSENT;
2497 err("Invalid msgStatus");
2499 return TCORE_RETURN_EINVAL;
2502 if ((saveMsg->msgDataPackage.msgLength > 0)
2503 && (saveMsg->msgDataPackage.msgLength <= SMS_SMDATA_SIZE_MAX)) {
2504 ScLength = (int)saveMsg->msgDataPackage.sca[0];
2507 dbg("ScLength = %d", ScLength);
2512 memcpy(&buf[1], saveMsg->msgDataPackage.sca, ScLength);
2514 memcpy(&buf[ScLength + 1], saveMsg->msgDataPackage.tpduData, saveMsg->msgDataPackage.msgLength);
2516 pdu_len = saveMsg->msgDataPackage.msgLength + ScLength + 1;
2517 dbg("pdu_len: [%d]", pdu_len);
2519 hex_pdu = g_malloc0(pdu_len * 2 + 1);
2520 tcore_util_hex_dump(" ", sizeof(buf), (void *)buf);
2522 memset(hex_pdu, 0x00, pdu_len * 2 + 1);
2524 util_byte_to_hex((const char *)buf, (char *)hex_pdu, pdu_len);
2526 /* AT+CMGW=<length>[, <stat>]<CR>PDU is given<ctrl-Z/ESC> */
2527 cmd_str = g_strdup_printf("AT+CMGW=%d, %d%s%s\x1A", saveMsg->msgDataPackage.msgLength, stat, "\r", hex_pdu);
2528 pending = tcore_pending_new(obj, 0);
2529 atreq = tcore_at_request_new((const char *)cmd_str, "+CMGW", TCORE_AT_SINGLELINE);
2531 if (NULL == cmd_str || NULL == atreq || NULL == pending) {
2532 err("Out of memory. Unable to proceed");
2533 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
2536 util_sms_free_memory(atreq);
2537 util_sms_free_memory(pending);
2538 util_sms_free_memory(hex_pdu);
2541 return TCORE_RETURN_ENOMEM;
2544 tcore_util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
2546 tcore_pending_set_request_data(pending, 0, atreq);
2547 tcore_pending_set_response_callback(pending, on_response_sms_save_msg, NULL);
2548 tcore_pending_link_user_request(pending, ur);
2549 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
2550 tcore_hal_send_request(hal, pending);
2556 return TCORE_RETURN_SUCCESS;
2559 err("Invalid Data len");
2561 return TCORE_RETURN_SMS_INVALID_DATA_LEN;
2564 static TReturn delete_msg(CoreObject *obj, UserRequest *ur)
2566 gchar *cmd_str = NULL;
2567 TcoreHal *hal = NULL;
2568 TcoreATRequest *atreq = NULL;
2569 TcorePending *pending = NULL;
2570 const struct treq_sms_delete_msg *delete_msg = NULL;
2574 delete_msg = tcore_user_request_ref_data(ur, NULL);
2575 hal = tcore_object_get_hal(obj);
2576 if (NULL == delete_msg || NULL == hal) {
2577 err("NULL input. Unable to proceed");
2578 dbg("deleteMsg: [%p], hal: [%p]", delete_msg, hal);
2581 return TCORE_RETURN_EINVAL;
2584 if (FALSE == tcore_hal_get_power_state(hal)) {
2585 dbg("cp not ready/n");
2586 return TCORE_RETURN_ENOSYS;
2589 dbg("index: %d", delete_msg->index);
2591 if (delete_msg->index == -1)
2592 cmd_str = g_strdup_printf("AT+CMGD=0, 4"); /* Delete All Messages */
2594 cmd_str = g_strdup_printf("AT+CMGD=%d, 0", delete_msg->index + 1); /* Delete specified index */
2596 pending = tcore_pending_new(obj, 0);
2597 atreq = tcore_at_request_new((const char *)cmd_str, NULL, TCORE_AT_NO_RESULT);
2598 if (NULL == cmd_str || NULL == atreq || NULL == pending) {
2599 err("Out of memory. Unable to proceed");
2600 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
2603 util_sms_free_memory(atreq);
2604 util_sms_free_memory(pending);
2607 return TCORE_RETURN_ENOMEM;
2610 tcore_util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
2612 tcore_pending_set_request_data(pending, 0, atreq);
2613 tcore_pending_set_response_callback(pending, on_response_sms_delete_msg, (void *) (uintptr_t) (delete_msg->index)); /* storing index as user data for response */
2614 tcore_pending_link_user_request(pending, ur);
2615 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
2616 tcore_hal_send_request(hal, pending);
2621 return TCORE_RETURN_SUCCESS;
2624 static TReturn get_stored_msg_cnt(CoreObject *obj, UserRequest *ur)
2626 gchar *cmd_str = NULL;
2627 TcoreHal *hal = NULL;
2628 TcoreATRequest *atreq = NULL;
2629 TcorePending *pending = NULL;
2633 hal = tcore_object_get_hal(obj);
2635 err("NULL HAL. Unable to proceed");
2638 return TCORE_RETURN_EINVAL;
2641 if (FALSE == tcore_hal_get_power_state(hal)) {
2642 dbg("cp not ready/n");
2643 return TCORE_RETURN_ENOSYS;
2646 cmd_str = g_strdup_printf("AT+CPMS=\"SM\"");
2647 pending = tcore_pending_new(obj, 0);
2648 atreq = tcore_at_request_new((const char *)cmd_str, "+CPMS", TCORE_AT_SINGLELINE);
2650 if (NULL == cmd_str || NULL == atreq || NULL == pending) {
2651 err("Out of memory. Unable to proceed");
2652 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
2655 util_sms_free_memory(atreq);
2656 util_sms_free_memory(pending);
2659 return TCORE_RETURN_ENOMEM;
2662 tcore_util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
2664 tcore_pending_set_request_data(pending, 0, atreq);
2665 tcore_pending_set_response_callback(pending, on_response_get_stored_msg_cnt, NULL);
2666 tcore_pending_link_user_request(pending, ur);
2667 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
2668 tcore_hal_send_request(hal, pending);
2673 return TCORE_RETURN_SUCCESS;
2676 static TReturn get_sca(CoreObject *obj, UserRequest *ur)
2678 gchar *cmd_str = NULL;
2679 TcoreHal *hal = NULL;
2680 TcoreATRequest *atreq = NULL;
2681 TcorePending *pending = NULL;
2685 hal = tcore_object_get_hal(obj);
2687 err("HAL NULL. Unable to proceed");
2690 return TCORE_RETURN_EINVAL;
2692 if (FALSE == tcore_hal_get_power_state(hal)) {
2693 dbg("cp not ready/n");
2694 return TCORE_RETURN_ENOSYS;
2697 cmd_str = g_strdup_printf("AT+CSCA?");
2698 pending = tcore_pending_new(obj, 0);
2699 atreq = tcore_at_request_new((const char *)cmd_str, "+CSCA", TCORE_AT_SINGLELINE);
2701 if (NULL == cmd_str || NULL == atreq || NULL == pending) {
2702 err("Out of memory. Unable to proceed");
2703 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
2706 util_sms_free_memory(atreq);
2707 util_sms_free_memory(pending);
2710 return TCORE_RETURN_ENOMEM;
2713 tcore_util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
2715 tcore_pending_set_request_data(pending, 0, atreq);
2716 tcore_pending_set_response_callback(pending, on_response_get_sca, NULL);
2717 tcore_pending_link_user_request(pending, ur);
2718 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
2719 tcore_hal_send_request(hal, pending);
2724 return TCORE_RETURN_SUCCESS;
2727 static TReturn set_sca(CoreObject *obj, UserRequest *ur)
2729 gchar *cmd_str = NULL;
2730 TcoreHal *hal = NULL;
2731 TcoreATRequest *atreq = NULL;
2732 TcorePending *pending = NULL;
2733 const struct treq_sms_set_sca *setSca = NULL;
2738 setSca = tcore_user_request_ref_data(ur, NULL);
2739 hal = tcore_object_get_hal(obj);
2740 if (NULL == setSca || NULL == hal) {
2741 err("NULL input. Unable to proceed");
2742 dbg("setSca: [%p], hal: [%p]", setSca, hal);
2745 return TCORE_RETURN_EINVAL;
2747 if (FALSE == tcore_hal_get_power_state(hal)) {
2748 dbg("cp not ready/n");
2749 return TCORE_RETURN_ENOSYS;
2752 dbg("dialNumLen: %u, typeOfNum: %d, numPlanId: %d, ", setSca->scaInfo.dialNumLen, setSca->scaInfo.typeOfNum, setSca->scaInfo.numPlanId);
2754 tcore_util_hex_dump(" ", (SMS_SMSP_ADDRESS_LEN+1), (void *)setSca->scaInfo.diallingNum);
2756 addrType = ((setSca->scaInfo.typeOfNum << 4) | setSca->scaInfo.numPlanId) | 0x80;
2758 cmd_str = g_strdup_printf("AT+CSCA=\"%s\", %d", setSca->scaInfo.diallingNum, addrType);
2759 pending = tcore_pending_new(obj, 0);
2760 atreq = tcore_at_request_new((const char *)cmd_str, NULL, TCORE_AT_NO_RESULT);
2762 if (NULL == cmd_str || NULL == atreq || NULL == pending) {
2763 err("Out of memory. Unable to proceed");
2764 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
2767 util_sms_free_memory(atreq);
2768 util_sms_free_memory(pending);
2771 return TCORE_RETURN_ENOMEM;
2774 tcore_util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
2776 tcore_pending_set_request_data(pending, 0, atreq);
2777 tcore_pending_set_response_callback(pending, on_response_set_sca, NULL);
2778 tcore_pending_link_user_request(pending, ur);
2779 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
2780 tcore_hal_send_request(hal, pending);
2785 return TCORE_RETURN_SUCCESS;
2788 static TReturn get_cb_config(CoreObject *obj, UserRequest *ur)
2790 gchar *cmd_str = NULL;
2791 TcoreHal *hal = NULL;
2792 TcoreATRequest *atreq = NULL;
2793 TcorePending *pending = NULL;
2797 hal = tcore_object_get_hal(obj);
2799 err("NULL HAL. Unable to proceed");
2802 return TCORE_RETURN_EINVAL;
2805 if (FALSE == tcore_hal_get_power_state(hal)) {
2806 dbg("cp not ready/n");
2807 return TCORE_RETURN_ENOSYS;
2810 cmd_str = g_strdup_printf("AT+CSCB?");
2811 pending = tcore_pending_new(obj, 0);
2812 atreq = tcore_at_request_new((const char *)cmd_str, "+CSCB", TCORE_AT_SINGLELINE);
2813 if (NULL == cmd_str || NULL == atreq || NULL == pending) {
2814 err("Out of memory. Unable to proceed");
2815 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
2818 util_sms_free_memory(atreq);
2819 util_sms_free_memory(pending);
2822 return TCORE_RETURN_ENOMEM;
2825 tcore_util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
2827 tcore_pending_set_request_data(pending, 0, atreq);
2828 tcore_pending_set_response_callback(pending, on_response_get_cb_config, NULL);
2829 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
2830 tcore_pending_link_user_request(pending, ur);
2831 tcore_hal_send_request(hal, pending);
2836 return TCORE_RETURN_SUCCESS;
2839 static TReturn set_cb_config(CoreObject *obj, UserRequest *ur)
2841 gchar *cmd_str = NULL;
2842 gchar *mids_str = NULL;
2843 GString *mids_GString = NULL;
2845 TcoreHal *hal = NULL;
2846 TcoreATRequest *atreq = NULL;
2847 TcorePending *pending = NULL;
2848 const struct treq_sms_set_cb_config *setCbConfig = NULL;
2849 int ctr1 = 0, ctr2 = 0;
2850 unsigned short appendMsgId = 0;
2854 setCbConfig = tcore_user_request_ref_data(ur, NULL);
2855 hal = tcore_object_get_hal(obj);
2856 if (NULL == setCbConfig || NULL == hal) {
2857 err("NULL input. Unable to proceed");
2858 dbg("setCbConfig: [%p], hal: [%p]", setCbConfig, hal);
2861 return TCORE_RETURN_EINVAL;
2864 if (FALSE == tcore_hal_get_power_state(hal)) {
2865 dbg("cp not ready/n");
2866 return TCORE_RETURN_ENOSYS;
2869 dbg("bCBEnabled: %d, msgIdCount: %d", setCbConfig->cbEnabled, setCbConfig->msgIdRangeCount);
2871 if (setCbConfig->cbEnabled == 2) { /* Enable all CBS */
2872 cmd_str = g_strdup_printf("AT+CSCB=1");
2873 } else if ((setCbConfig->cbEnabled == 1) && (setCbConfig->msgIdRangeCount == 0)) { /* Special case: Enable all CBS */
2874 cmd_str = g_strdup_printf("AT+CSCB=1");
2875 } else if (setCbConfig->cbEnabled == 0) {/* AT+CSCB=0: Disable CBS */
2876 cmd_str = g_strdup_printf("AT+CSCB=0");
2878 mids_GString = g_string_new("AT+CSCB=0, \"");
2880 for (ctr1 = 0; ctr1 < setCbConfig->msgIdRangeCount; ctr1++) {
2881 if (setCbConfig->msgIDs[ctr1].net3gpp.selected == FALSE)
2884 if (SMS_GSM_SMS_CBMI_LIST_SIZE_MAX <= (setCbConfig->msgIDs[ctr1].net3gpp.toMsgId - setCbConfig->msgIDs[ctr1].net3gpp.fromMsgId)) {
2885 g_string_free(mids_GString, TRUE);
2886 mids_GString = g_string_new("AT+CSCB=1");
2890 appendMsgId = setCbConfig->msgIDs[ctr1].net3gpp.fromMsgId;
2892 for (ctr2 = 0; (ctr2 <= ((setCbConfig->msgIDs[ctr1].net3gpp.toMsgId) - (setCbConfig->msgIDs[ctr1].net3gpp.fromMsgId))); ctr2++) {
2893 gchar *append_str = NULL;
2894 dbg("%x", appendMsgId);
2895 append_str = g_strdup_printf("%d", appendMsgId);
2896 g_string_append(mids_GString, append_str);
2899 if (ctr2 == ((setCbConfig->msgIDs[ctr1].net3gpp.toMsgId) - (setCbConfig->msgIDs[ctr1].net3gpp.fromMsgId)))
2900 g_string_append(mids_GString, "\""); /* Mids string termination */
2902 g_string_append(mids_GString, ", ");
2907 mids_str = g_string_free(mids_GString, FALSE);
2908 cmd_str = g_strdup_printf("%s", mids_str);
2912 pending = tcore_pending_new(obj, 0);
2913 atreq = tcore_at_request_new((const char *)cmd_str, NULL, TCORE_AT_NO_RESULT);
2914 if (NULL == cmd_str || NULL == atreq || NULL == pending) {
2915 err("Out of memory. Unable to proceed");
2916 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
2919 util_sms_free_memory(atreq);
2920 util_sms_free_memory(pending);
2923 return TCORE_RETURN_ENOMEM;
2926 tcore_util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
2928 tcore_pending_set_request_data(pending, 0, atreq);
2929 tcore_pending_set_response_callback(pending, on_response_set_cb_config, NULL);
2930 tcore_pending_link_user_request(pending, ur);
2931 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
2932 tcore_hal_send_request(hal, pending);
2937 return TCORE_RETURN_SUCCESS;
2940 static TReturn set_mem_status(CoreObject *obj, UserRequest *ur)
2942 gchar *cmd_str = NULL;
2943 TcoreHal *hal = NULL;
2944 TcoreATRequest *atreq = NULL;
2945 TcorePending *pending = NULL;
2946 const struct treq_sms_set_mem_status *setMemStatus = NULL;
2947 int memoryStatus = 0;
2951 setMemStatus = tcore_user_request_ref_data(ur, NULL);
2952 hal = tcore_object_get_hal(obj);
2953 if (NULL == setMemStatus || NULL == hal) {
2954 err("NULL input. Unable to proceed");
2955 dbg("setMemStatus: [%p], hal: [%p]", setMemStatus, hal);
2958 return TCORE_RETURN_EINVAL;
2960 if (FALSE == tcore_hal_get_power_state(hal)) {
2961 dbg("cp not ready/n");
2962 return TCORE_RETURN_ENOSYS;
2965 dbg("memory_status: %d", setMemStatus->memory_status);
2967 if (setMemStatus->memory_status < SMS_PDA_MEMORY_STATUS_AVAILABLE
2968 || setMemStatus->memory_status > SMS_PDA_MEMORY_STATUS_FULL) {
2969 err("Invalid memory_status");
2972 return TCORE_RETURN_EINVAL;
2975 switch (setMemStatus->memory_status) {
2976 case SMS_PDA_MEMORY_STATUS_AVAILABLE:
2977 memoryStatus = AT_MEMORY_AVAILABLE;
2980 case SMS_PDA_MEMORY_STATUS_FULL:
2981 memoryStatus = AT_MEMORY_FULL;
2985 err("Invalid memory_status");
2987 return TCORE_RETURN_EINVAL;
2990 cmd_str = g_strdup_printf("AT+XTESM=%d", memoryStatus);
2991 pending = tcore_pending_new(obj, 0);
2992 atreq = tcore_at_request_new((const char *)cmd_str, NULL, TCORE_AT_NO_RESULT);
2994 if (NULL == cmd_str || NULL == atreq || NULL == pending) {
2995 err("Out of memory. Unable to proceed");
2996 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
2999 util_sms_free_memory(atreq);
3000 util_sms_free_memory(pending);
3003 return TCORE_RETURN_ENOMEM;
3006 tcore_util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
3008 tcore_pending_set_request_data(pending, 0, atreq);
3009 tcore_pending_set_response_callback(pending, on_response_set_mem_status, NULL);
3010 tcore_pending_link_user_request(pending, ur);
3011 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
3012 tcore_hal_send_request(hal, pending);
3017 return TCORE_RETURN_SUCCESS;
3020 static TReturn set_delivery_report(CoreObject *obj, UserRequest *ur)
3022 struct tresp_sms_set_delivery_report respSetDeliveryReport = {0, };
3024 respSetDeliveryReport.result = SMS_SUCCESS;
3027 if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(obj))) {
3028 dbg("cp not ready/n");
3029 return TCORE_RETURN_ENOSYS;
3032 dbg("CP takes care of sending SMS ack to network for all classes of SMS. Sending default success.");
3034 tcore_user_request_send_response(ur, TRESP_SMS_SET_DELIVERY_REPORT, sizeof(struct tresp_sms_set_delivery_report), &respSetDeliveryReport);
3037 return TCORE_RETURN_SUCCESS;
3040 static TReturn set_msg_status(CoreObject *obj, UserRequest *ur)
3042 gchar *cmd_str = NULL;
3043 TcoreHal *hal = NULL;
3044 TcoreATRequest *atreq = NULL;
3045 TcorePending *pending = NULL;
3046 const struct treq_sms_set_msg_status *msg_status = NULL;
3049 hal = tcore_object_get_hal(obj);
3050 if (FALSE == tcore_hal_get_power_state(hal)) {
3051 dbg("cp not ready/n");
3052 return TCORE_RETURN_ENOSYS;
3054 msg_status = tcore_user_request_ref_data(ur, NULL);
3056 cmd_str = g_strdup_printf("AT+CRSM=178, 28476, %d, 4, %d", (msg_status->index+1), PDU_LEN_MAX);
3057 atreq = tcore_at_request_new((const char *)cmd_str, "+CRSM", TCORE_AT_SINGLELINE);
3058 pending = tcore_pending_new(obj, 0);
3059 if (NULL == cmd_str || NULL == atreq || NULL == pending) {
3060 err("Out of memory. Unable to proceed");
3061 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
3064 util_sms_free_memory(atreq);
3065 util_sms_free_memory(pending);
3068 return TCORE_RETURN_ENOMEM;
3071 tcore_util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
3073 tcore_pending_set_request_data(pending, 0, atreq);
3074 tcore_pending_set_response_callback(pending, _response_get_efsms_data, NULL);
3075 tcore_pending_link_user_request(pending, ur);
3076 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
3077 tcore_hal_send_request(hal, pending);
3082 return TCORE_RETURN_SUCCESS;
3085 static TReturn get_sms_params(CoreObject *obj, UserRequest *ur)
3087 gchar *cmd_str = NULL;
3088 TcoreHal *hal = NULL;
3089 TcoreATRequest *atreq = NULL;
3090 TcorePending *pending = NULL;
3091 const struct treq_sms_get_params *getSmsParams = NULL;
3092 int record_len = 0, *smsp_record_len = NULL;
3096 getSmsParams = tcore_user_request_ref_data(ur, NULL);
3097 hal = tcore_object_get_hal(obj);
3098 if (NULL == getSmsParams || NULL == hal) {
3099 err("NULL input. Unable to proceed");
3100 dbg("getSmsParams: [%p], hal: [%p]", getSmsParams, hal);
3103 return TCORE_RETURN_EINVAL;
3106 if (FALSE == tcore_hal_get_power_state(hal)) {
3107 dbg("cp not ready/n");
3108 return TCORE_RETURN_ENOSYS;
3111 smsp_record_len = tcore_plugin_ref_property(tcore_object_ref_plugin(obj), "SMSPRECORDLEN");
3112 record_len = *smsp_record_len;
3113 dbg("record len from property %d", record_len);
3115 /* AT+CRSM=command>[, <fileid>[, <P1>, <P2>, <P3>[, <data>[, <pathid>]]]] */
3116 cmd_str = g_strdup_printf("AT+CRSM=178, 28482, %d, 4, %d", (getSmsParams->index + 1), record_len);
3118 dbg("cmd_str is %s", cmd_str);
3120 atreq = tcore_at_request_new((const char *)cmd_str, "+CRSM", TCORE_AT_SINGLELINE);
3121 pending = tcore_pending_new(obj, 0);
3122 if (NULL == cmd_str || NULL == atreq || NULL == pending) {
3123 err("Out of memory. Unable to proceed");
3124 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
3127 util_sms_free_memory(atreq);
3128 util_sms_free_memory(pending);
3131 return TCORE_RETURN_ENOMEM;
3134 tcore_util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
3136 tcore_pending_set_request_data(pending, 0, atreq);
3137 tcore_pending_set_response_callback(pending, on_response_get_sms_params, NULL);
3138 tcore_pending_link_user_request(pending, ur);
3139 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
3140 tcore_hal_send_request(hal, pending);
3145 return TCORE_RETURN_SUCCESS;
3148 static TReturn set_sms_params(CoreObject *obj, UserRequest *ur)
3150 gchar *cmd_str = NULL;
3151 char *encoded_data = NULL;
3152 unsigned char *temp_data = NULL;
3153 int SMSPRecordLen = 0;
3154 int *smsp_record_len;
3156 TcoreHal *hal = NULL;
3157 TcoreATRequest *atreq = NULL;
3158 TcorePending *pending = NULL;
3159 const struct treq_sms_set_params *setSmsParams = NULL;
3160 int encoded_data_len = 0;
3164 setSmsParams = tcore_user_request_ref_data(ur, NULL);
3165 hal = tcore_object_get_hal(obj);
3166 if (NULL == setSmsParams || NULL == hal) {
3167 err("NULL input. Unable to proceed");
3168 dbg("setSmsParams: [%p], hal: [%p]", setSmsParams, hal);
3171 if (FALSE == tcore_hal_get_power_state(hal)) {
3172 dbg("cp not ready/n");
3173 return TCORE_RETURN_ENOSYS;
3176 /* EFsmsp file size is 28 +Y bytes (Y is alpha id size) */
3177 smsp_record_len = tcore_plugin_ref_property(tcore_object_ref_plugin(obj), "SMSPRECORDLEN");
3178 if (NULL == smsp_record_len) {
3179 err("SMSP record is NULL");
3180 return TCORE_RETURN_FAILURE;
3182 SMSPRecordLen = *smsp_record_len;
3183 if (SMSPRecordLen < nDefaultSMSPWithoutAlphaId)
3186 temp_data = g_malloc0(SMSPRecordLen);
3187 encoded_data = g_malloc0(SMSPRecordLen*2 + 1);
3189 _tcore_util_sms_encode_smsParameters(&(setSmsParams->params), temp_data, SMSPRecordLen);
3191 util_byte_to_hex((const char *)temp_data, (char *)encoded_data, SMSPRecordLen);
3193 encoded_data_len = ((SMSPRecordLen) * 2);
3195 hal = tcore_object_get_hal(obj);
3196 pending = tcore_pending_new(obj, 0);
3198 dbg("alpha id len %d encoded data %s. Encoded data len %d", setSmsParams->params.alphaIdLen, encoded_data, encoded_data_len);
3199 cmd_str = g_strdup_printf("AT+CRSM=220, 28482, %d, 4, %d, \"%s\"", (setSmsParams->params.recordIndex+1), SMSPRecordLen, encoded_data);
3201 dbg("cmd str is %s", cmd_str);
3202 atreq = tcore_at_request_new(cmd_str, "+CRSM:", TCORE_AT_SINGLELINE);
3204 if (NULL == cmd_str || NULL == atreq || NULL == pending) {
3205 err("Out of memory. Unable to proceed");
3206 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
3209 util_sms_free_memory(atreq);
3210 util_sms_free_memory(pending);
3212 util_sms_free_memory(temp_data);
3213 util_sms_free_memory(encoded_data);
3216 return TCORE_RETURN_ENOMEM;
3219 tcore_util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
3221 tcore_pending_set_request_data(pending, 0, atreq);
3222 tcore_pending_set_response_callback(pending, on_response_set_sms_params, NULL);
3223 tcore_pending_link_user_request(pending, ur);
3224 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
3225 tcore_hal_send_request(hal, pending);
3228 util_sms_free_memory(temp_data);
3229 util_sms_free_memory(encoded_data);
3231 return TCORE_RETURN_SUCCESS;
3234 static TReturn get_paramcnt(CoreObject *obj, UserRequest *ur)
3236 gchar *cmd_str = NULL;
3237 TcoreHal *hal = NULL;
3238 TcoreATRequest *atreq = NULL;
3239 TcorePending *pending = NULL;
3243 hal = tcore_object_get_hal(obj);
3245 err("NULL HAL. Unable to proceed");
3248 return TCORE_RETURN_EINVAL;
3250 if (FALSE == tcore_hal_get_power_state(hal)) {
3251 dbg("cp not ready/n");
3252 return TCORE_RETURN_ENOSYS;
3255 /* AT+CRSM=command>[, <fileid>[, <P1>, <P2>, <P3>[, <data>[, <pathid>]]]] */
3256 cmd_str = g_strdup_printf("AT+CRSM=192, 28482");
3257 atreq = tcore_at_request_new((const char *)cmd_str, "+CRSM", TCORE_AT_SINGLELINE);
3258 pending = tcore_pending_new(obj, 0);
3260 if (NULL == cmd_str || NULL == atreq || NULL == pending) {
3261 err("NULL pointer. Unable to proceed");
3262 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
3265 util_sms_free_memory(atreq);
3266 util_sms_free_memory(pending);
3269 return TCORE_RETURN_FAILURE;
3272 tcore_util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
3274 tcore_pending_set_request_data(pending, 0, atreq);
3275 tcore_pending_set_response_callback(pending, on_response_get_paramcnt, NULL);
3276 tcore_pending_link_user_request(pending, ur);
3277 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
3278 tcore_hal_send_request(hal, pending);
3283 return TCORE_RETURN_SUCCESS;
3286 static struct tcore_sms_operations sms_ops = {
3287 .send_umts_msg = send_umts_msg,
3288 .read_msg = read_msg,
3289 .save_msg = save_msg,
3290 .delete_msg = delete_msg,
3291 .get_storedMsgCnt = get_stored_msg_cnt,
3294 .get_cb_config = get_cb_config,
3295 .set_cb_config = set_cb_config,
3296 .set_mem_status = set_mem_status,
3297 .get_pref_brearer = NULL,
3298 .set_pref_brearer = NULL,
3299 .set_delivery_report = set_delivery_report,
3300 .set_msg_status = set_msg_status,
3301 .get_sms_params = get_sms_params,
3302 .set_sms_params = set_sms_params,
3303 .get_paramcnt = get_paramcnt,
3306 gboolean imc_sms_init(TcorePlugin *cp, CoreObject *co_sms)
3308 int *smsp_record_len;
3311 /* Set operations */
3312 tcore_sms_set_ops(co_sms, &sms_ops, TCORE_OPS_TYPE_CP);
3314 /* Registering for SMS notifications */
3315 tcore_object_add_callback(co_sms, "+CMTI:", on_event_class2_sms_incom_msg, NULL);
3316 tcore_object_add_callback(co_sms, "\e+CMT:", on_event_sms_incom_msg, NULL);
3318 tcore_object_add_callback(co_sms, "\e+CDS", on_event_sms_incom_msg, NULL);
3319 tcore_object_add_callback(co_sms, "+XSMSMMSTAT", on_event_sms_memory_status, NULL);
3320 tcore_object_add_callback(co_sms, "+CMS", on_event_sms_memory_status, NULL);
3322 tcore_object_add_callback(co_sms, "+CBMI:", on_event_sms_cb_incom_msg, NULL);
3323 tcore_object_add_callback(co_sms, "\e+CBM:", on_event_sms_cb_incom_msg, NULL);
3325 /* Storing SMSP record length */
3326 smsp_record_len = g_new0(int, 1);
3327 tcore_plugin_link_property(cp, "SMSPRECORDLEN", smsp_record_len);
3333 void imc_sms_exit(TcorePlugin *cp, CoreObject *co_sms)
3335 int *smsp_record_len;
3337 smsp_record_len = tcore_plugin_ref_property(cp, "SMSPRECORDLEN");
3338 g_free(smsp_record_len);