4 * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Madhavi Akella <madhavi.a@samsung.com>
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
30 #include <core_object.h>
35 #include <user_request.h>
41 #include "common/TelErr.h"
45 /*=============================================================
47 ==============================================================*/
48 #define MAX_GSM_SMS_TPDU_SIZE 244
49 #define MAX_GSM_SMS_MSG_NUM 255
50 #define MAX_GSM_SMS_SERVICE_CENTER_ADDR 12 /* Maximum number of bytes of service center address */
51 #define MAX_GSM_SMS_CBMI_LIST_SIZE 100 /* Maximum number of CBMI list size for CBS 30*2=60 */
52 #define MAX_GSM_SMS_PARAM_RECORD_SIZE 156 /* Maximum number of bytes SMSP Record size (Y + 28), y : 0 ~ 128 */
53 #define MAX_GSM_SMS_STATUS_FILE_SIZE 2 /* Last Used TP-MR + SMS "Memory Cap. Exceeded" Noti Flag */
54 #define TAPI_SIM_SMSP_ADDRESS_LEN 20
56 /*=============================================================
58 ==============================================================*/
59 #define AT_SMS_DEVICE_READY 12 /* AT device ready */
60 #define SMS_DEVICE_READY 1 /* Telephony device ready */
61 #define SMS_DEVICE_NOT_READY 0 /* Telephony device not ready */
63 /*=============================================================
65 ==============================================================*/
66 #define SMS_CBMI_SELECTED_SOME 0x02 /* Some CBMIs are selected */
67 #define SMS_CBMI_SELECTED_ALL 0x01 /* All CBMIs are selected */
69 /*=============================================================
71 ==============================================================*/
72 #define AT_REC_UNREAD 0 /* Received and Unread */
73 #define AT_REC_READ 1 /* Received and Read */
74 #define AT_STO_UNSENT 2 /* Unsent */
75 #define AT_STO_SENT 3 /* Sent */
76 #define AT_ALL 4 /* Unknown */
78 /*=============================================================
80 ==============================================================*/
81 #define AT_MEMORY_AVAILABLE 0 /* Memory Available */
82 #define AT_MEMORY_FULL 1 /* Memory Full */
84 /*=============================================================
85 SIM CRSM SW1 and Sw2 Error definitions */
87 #define AT_SW1_SUCCESS 0x90
88 #define AT_SW2_SUCCESS 0
89 #define AT_SW1_LEN_RESP 0x9F
91 #define AT_MAX_RECORD_LEN 256
92 #define AT_EF_SMS_RECORD_LEN 176
94 /*=============================================================
96 ==============================================================*/
97 #define CR '\r' /* Carriage Return */
99 /*=============================================================
101 ==============================================================*/
102 #define SMS_SWAPBYTES16(x) (((x) & 0xffff0000) | (((x) & 0x0000ff00) >> 8) | (((x) & 0x000000ff) << 8))
104 void print_glib_list_elem(gpointer data, gpointer user_data);
106 static void on_response_class2_read_msg(TcorePending *pending, int data_len, const void *data, void *user_data);
109 gboolean util_byte_to_hex(const char *byte_pdu, char *hex_pdu, int num_bytes);
111 void print_glib_list_elem(gpointer data, gpointer user_data)
113 char *item = (char *)data;
115 dbg("item: [%s]", item);
118 /*=============================================================
120 ==============================================================*/
121 static void on_confirmation_sms_message_send(TcorePending *p, gboolean result, void *user_data)
123 dbg("Entered Function. Request message out from queue");
125 dbg("TcorePending: [%p]", p);
126 dbg("result: [%02x]", result);
127 dbg("user_data: [%p]", user_data);
129 if (result == TRUE) {
131 } else { /* Failed */
135 dbg("Exiting Function. Nothing to return");
138 /*=============================================================
140 ==============================================================*/
141 static void util_sms_free_memory(void *sms_ptr)
145 if (NULL != sms_ptr) {
146 dbg("Freeing memory location: [%p]", sms_ptr);
150 err("Invalid memory location. Nothing to do.");
157 static int util_sms_decode_smsParameters(unsigned char *incoming, unsigned int length, struct telephony_sms_Params *params)
159 int alpha_id_len = 0;
163 dbg(" RecordLen = %d", length);
165 if(incoming == NULL || params == NULL)
168 alpha_id_len = length -SMS_SMSP_PARAMS_MAX_LEN;
170 if (alpha_id_len > 0) {
171 if (alpha_id_len > SMS_SMSP_ALPHA_ID_LEN_MAX) {
172 alpha_id_len = SMS_SMSP_ALPHA_ID_LEN_MAX;
175 for (i = 0; i < alpha_id_len; i++) {
176 if (0xff == incoming[i]) {
182 memcpy(params->szAlphaId, incoming, i);
184 params->alphaIdLen = i;
186 dbg(" Alpha id length = %d", i);
188 params->alphaIdLen = 0;
189 dbg(" Alpha id length is zero");
192 params->paramIndicator = incoming[alpha_id_len];
194 dbg(" Param Indicator = %02x", params->paramIndicator);
196 if ((params->paramIndicator & SMSPValidDestAddr) == 0) {
197 nOffset = nDestAddrOffset;
199 if (0x00 == incoming[alpha_id_len + nOffset] || 0xff == incoming[alpha_id_len + nOffset]) {
200 params->tpDestAddr.dialNumLen = 0;
202 dbg("DestAddr Length is 0");
204 if (0 < (int) incoming[alpha_id_len + nOffset]) {
205 params->tpDestAddr.dialNumLen = (int) (incoming[alpha_id_len + nOffset] - 1);
207 if (params->tpDestAddr.dialNumLen > SMS_SMSP_ADDRESS_LEN)
208 params->tpDestAddr.dialNumLen = SMS_SMSP_ADDRESS_LEN;
210 params->tpDestAddr.dialNumLen = 0;
213 params->tpDestAddr.numPlanId = incoming[alpha_id_len + (++nOffset)] & 0x0f;
214 params->tpDestAddr.typeOfNum = (incoming[alpha_id_len + nOffset] & 0x70) >> 4;
216 memcpy(params->tpDestAddr.diallingNum, &incoming[alpha_id_len + (++nOffset)], (params->tpDestAddr.dialNumLen));
218 dbg("Dest TON is %d", params->tpDestAddr.typeOfNum);
219 dbg("Dest NPI is %d", params->tpDestAddr.numPlanId);
220 dbg("Dest Length = %d", params->tpDestAddr.dialNumLen);
221 dbg("Dest Addr = %s", params->tpDestAddr.diallingNum);
224 params->tpDestAddr.dialNumLen = 0;
227 if ((params->paramIndicator & SMSPValidSvcAddr) == 0) {
228 nOffset = nSCAAddrOffset;
230 if (0x00 == (int) incoming[alpha_id_len + nOffset] || 0xff == (int) incoming[alpha_id_len + nOffset]) {
231 params->tpSvcCntrAddr.dialNumLen = 0;
233 dbg(" SCAddr Length is 0");
235 if (0 < (int) incoming[alpha_id_len + nOffset]) {
236 params->tpSvcCntrAddr.dialNumLen = (int) (incoming[alpha_id_len + nOffset] - 1);
238 if (params->tpSvcCntrAddr.dialNumLen > SMS_SMSP_ADDRESS_LEN)
239 params->tpSvcCntrAddr.dialNumLen = SMS_SMSP_ADDRESS_LEN;
241 params->tpSvcCntrAddr.numPlanId = incoming[alpha_id_len + (++nOffset)] & 0x0f;
242 params->tpSvcCntrAddr.typeOfNum = (incoming[alpha_id_len + nOffset] & 0x70) >> 4;
244 memcpy(params->tpSvcCntrAddr.diallingNum, &incoming[alpha_id_len + (++nOffset)], (params->tpSvcCntrAddr.dialNumLen));
246 dbg("SCAddr Length = %d ", params->tpSvcCntrAddr.dialNumLen);
247 dbg("SCAddr TON is %d", params->tpSvcCntrAddr.typeOfNum);
248 dbg("SCAddr NPI is %d", params->tpSvcCntrAddr.numPlanId);
250 for (i = 0; i < (int) params->tpSvcCntrAddr.dialNumLen; i++)
251 dbg("SCAddr = %d [%02x]", i, params->tpSvcCntrAddr.diallingNum[i]);
253 params->tpSvcCntrAddr.dialNumLen = 0;
256 } else if ((0x00 < (int) incoming[alpha_id_len + nSCAAddrOffset] && (int) incoming[alpha_id_len + nSCAAddrOffset] <= 12)
257 || 0xff != (int) incoming[alpha_id_len + nSCAAddrOffset]) {
258 nOffset = nSCAAddrOffset;
260 if (0x00 == (int) incoming[alpha_id_len + nOffset] || 0xff == (int) incoming[alpha_id_len + nOffset]) {
261 params->tpSvcCntrAddr.dialNumLen = 0;
262 dbg("SCAddr Length is 0");
264 if (0 < (int) incoming[alpha_id_len + nOffset]) {
265 params->tpSvcCntrAddr.dialNumLen = (int) (incoming[alpha_id_len + nOffset] - 1);
267 params->tpSvcCntrAddr.dialNumLen = incoming[alpha_id_len + nOffset] - 1;
269 if (params->tpSvcCntrAddr.dialNumLen > SMS_SMSP_ADDRESS_LEN)
270 params->tpSvcCntrAddr.dialNumLen = SMS_SMSP_ADDRESS_LEN;
272 params->tpSvcCntrAddr.numPlanId = incoming[alpha_id_len + (++nOffset)] & 0x0f;
273 params->tpSvcCntrAddr.typeOfNum = (incoming[alpha_id_len + nOffset] & 0x70) >> 4;
275 memcpy(params->tpSvcCntrAddr.diallingNum, &incoming[alpha_id_len + (++nOffset)],
276 (params->tpSvcCntrAddr.dialNumLen));
278 dbg("SCAddr Length = %d ", params->tpSvcCntrAddr.dialNumLen);
279 dbg("SCAddr TON is %d", params->tpSvcCntrAddr.typeOfNum);
280 dbg("SCAddr NPI is %d", params->tpSvcCntrAddr.numPlanId);
282 for (i = 0; i < (int) params->tpSvcCntrAddr.dialNumLen; i++)
283 dbg("SCAddr = %d [%02x]", i, params->tpSvcCntrAddr.diallingNum[i]);
285 params->tpSvcCntrAddr.dialNumLen = 0;
289 params->tpSvcCntrAddr.dialNumLen = 0;
292 if ((params->paramIndicator & SMSPValidPID) == 0 && (alpha_id_len + nPIDOffset) < MAX_GSM_SMS_PARAM_RECORD_SIZE) {
293 params->tpProtocolId = incoming[alpha_id_len + nPIDOffset];
295 if ((params->paramIndicator & SMSPValidDCS) == 0 && (alpha_id_len + nDCSOffset) < MAX_GSM_SMS_PARAM_RECORD_SIZE) {
296 params->tpDataCodingScheme = incoming[alpha_id_len + nDCSOffset];
298 if ((params->paramIndicator & SMSPValidVP) == 0 && (alpha_id_len + nVPOffset) < MAX_GSM_SMS_PARAM_RECORD_SIZE) {
299 params->tpValidityPeriod = incoming[alpha_id_len + nVPOffset];
302 dbg(" Alpha Id(Len) = %d", (int) params->alphaIdLen);
304 for (i = 0; i < (int) params->alphaIdLen; i++) {
305 dbg(" Alpha Id = [%d] [%c]", i, params->szAlphaId[i]);
307 dbg(" PID = %d",params->tpProtocolId);
308 dbg(" DCS = %d",params->tpDataCodingScheme);
309 dbg(" VP = %d",params->tpValidityPeriod);
315 /*=============================================================
317 ==============================================================*/
318 static gboolean on_event_sms_ready_status(CoreObject *o, const void *event_info, void *user_data)
320 struct tnoti_sms_ready_status readyStatusInfo = {0,};
322 GSList *tokens = NULL;
323 GSList *lines = NULL;
325 //CoreObject *o = NULL;
327 int rtn = -1 , status = 0;
329 dbg(" Func Entrance");
331 lines = (GSList *)event_info;
332 if (1 != g_slist_length(lines)) {
333 dbg("unsolicited msg but multiple line");
336 line = (char *) (lines->data);
338 dbg(" Func Entrance");
342 dbg("noti line is %s", line);
343 tokens = tcore_at_tok_new(line);
344 pResp = g_slist_nth_data(tokens, 0);
346 status = atoi(pResp);
351 if (status == AT_SMS_DEVICE_READY) {
352 readyStatusInfo.status = SMS_DEVICE_READY;
353 tcore_sms_set_ready_status(o, readyStatusInfo.status);
354 dbg("SMS Ready status = [%s]", readyStatusInfo.status ? "TRUE" : "FALSE");
355 rtn = tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_SMS_DEVICE_READY, sizeof(struct tnoti_sms_ready_status), &readyStatusInfo);
356 dbg(" Return value [%d]", rtn);
358 readyStatusInfo.status = SMS_DEVICE_NOT_READY;
363 tcore_at_tok_free(tokens);
367 static gboolean on_event_class2_sms_incom_msg(CoreObject *obj, const void *event_info, void *user_data)
369 //+CMTI: <mem>,<index>
371 GSList *tokens = NULL , *lines = NULL;
372 char *line = NULL, *cmd_str = NULL;
373 int index = 0, mem_type = 0;
374 TcoreHal *hal = NULL;
375 TcoreATRequest *atreq = NULL;
376 TcorePending *pending = NULL;
378 dbg("Entered Function");
380 lines = (GSList *)event_info;
381 line = (char *)g_slist_nth_data(lines, 0); /* Fetch Line 1 */
383 dbg("Line 1: [%s]", line);
386 err("Line 1 is invalid");
390 tokens = tcore_at_tok_new(line); /* Split Line 1 into tokens */
391 mem_type = atoi(g_slist_nth_data(tokens, 0)); // Type of Memory stored
392 index = atoi((char *) g_slist_nth_data(tokens, 1));
394 hal = tcore_object_get_hal(obj);
396 err("NULL input. Unable to proceed");
397 dbg("readMsg: hal: [%p]", hal);
400 return TCORE_RETURN_EINVAL;
403 dbg("index: [%d]", index);
405 cmd_str = g_strdup_printf("AT+CMGR=%d", index);
406 atreq = tcore_at_request_new((const char *)cmd_str, "+CMGR", TCORE_AT_PDU);
407 pending = tcore_pending_new(obj, 0);
409 if (NULL == cmd_str || NULL == atreq || NULL == pending) {
410 err("Out of memory. Unable to proceed");
411 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
415 util_sms_free_memory(atreq);
416 util_sms_free_memory(pending);
419 return TCORE_RETURN_ENOMEM;
422 util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
424 tcore_pending_set_request_data(pending, 0, atreq);
425 tcore_pending_set_response_callback(pending, on_response_class2_read_msg, (void *)(uintptr_t)index); //storing index as user data for response
426 tcore_pending_link_user_request(pending, NULL);
427 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
428 tcore_hal_send_request(hal, pending);
432 tcore_at_tok_free(tokens);
437 static gboolean on_event_sms_incom_msg(CoreObject *o, const void *event_info, void *user_data)
439 //+CMT: [<alpha>],<length><CR><LF><pdu> (PDU mode enabled);
442 GSList *tokens = NULL;
443 GSList *lines = NULL;
445 int pdu_len = 0, no_of_tokens = 0;
446 unsigned char *bytePDU = NULL;
447 struct tnoti_sms_umts_msg gsmMsgInfo;
450 dbg("Entered Function");
452 lines = (GSList *)event_info;
453 memset(&gsmMsgInfo, 0x00, sizeof(struct tnoti_sms_umts_msg));
455 if (2 != g_slist_length(lines)) {
456 err("Invalid number of lines for +CMT. Must be 2");
460 line = (char *)g_slist_nth_data(lines, 0); /* Fetch Line 1 */
462 dbg("Line 1: [%s]", line);
465 err("Line 1 is invalid");
469 tokens = tcore_at_tok_new(line); /* Split Line 1 into tokens */
471 no_of_tokens = g_slist_length(tokens);
473 if (no_of_tokens == 2) { // in case of incoming SMS +CMT
474 dbg("Alpha ID: [%02x]", g_slist_nth_data(tokens, 0)); /* 0: Alpha ID */
475 pdu_len = atoi((char *)g_slist_nth_data(tokens, 1));
476 dbg("pdu_len: [%d]", pdu_len); /* 1: PDU Length */
477 } else if (no_of_tokens == 1) { // in case of incoming status report +CDS
478 pdu_len = atoi((char *)g_slist_nth_data(tokens, 0));
479 dbg("pdu_len: [%d]", pdu_len); /* 1: PDU Length */
482 line = (char *)g_slist_nth_data(lines, 1); /* Fetch Line 2 */
484 dbg("Line 2: [%s]", line);
487 err("Line 2 is invalid");
491 /* Convert to Bytes */
492 bytePDU = (unsigned char *)util_hexStringToBytes(line);
494 sca_length = bytePDU[0];
496 dbg("SCA length = %d", sca_length);
498 gsmMsgInfo.msgInfo.msgLength = pdu_len;
500 if (sca_length == 0) {
501 memcpy(gsmMsgInfo.msgInfo.tpduData, &bytePDU[1], gsmMsgInfo.msgInfo.msgLength);
503 memcpy(gsmMsgInfo.msgInfo.sca, &bytePDU[1], sca_length);
504 memcpy(gsmMsgInfo.msgInfo.tpduData, &bytePDU[sca_length+1], gsmMsgInfo.msgInfo.msgLength);
507 util_hex_dump(" ", strlen(line)/2, bytePDU);
508 util_hex_dump(" ", sca_length, gsmMsgInfo.msgInfo.sca);
509 util_hex_dump(" ", gsmMsgInfo.msgInfo.msgLength,gsmMsgInfo.msgInfo.tpduData);
511 rtn = tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_SMS_INCOM_MSG, sizeof(struct tnoti_sms_umts_msg), &gsmMsgInfo);
514 tcore_at_tok_free(tokens);
523 static gboolean on_event_sms_memory_status(CoreObject *o, const void *event_info, void *user_data)
525 struct tnoti_sms_memory_status memStatusInfo = {0,};
527 int rtn = -1 ,memoryStatus = -1;
530 char *line = NULL , *pResp = NULL;
534 lines = (GSList *)event_info;
535 if (1 != g_slist_length(lines)) {
536 dbg("unsolicited msg but multiple line");
539 line = (char*)(lines->data);
543 tokens = tcore_at_tok_new(line);
544 pResp = g_slist_nth_data(tokens, 0);
547 memoryStatus = atoi(pResp);
548 dbg("memoryStatus is %d",memoryStatus);
549 if (memoryStatus == 0) {//SIM Full condition
550 memStatusInfo.status = SMS_PHONE_MEMORY_STATUS_FULL;
552 rtn = tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_SMS_MEMORY_STATUS, sizeof(struct tnoti_sms_memory_status), &memStatusInfo);
554 tcore_at_tok_free(tokens);
563 static gboolean on_event_sms_cb_incom_msg(CoreObject *o, const void *event_info, void *user_data)
565 //+CBM: <length><CR><LF><pdu>
567 struct tnoti_sms_cellBroadcast_msg cbMsgInfo;
569 int rtn = -1 , length = 0;
570 char * line = NULL, *pdu = NULL, *pResp = NULL;
571 GSList *tokens = NULL;
572 GSList *lines = NULL;
574 dbg(" Func Entrance");
576 lines = (GSList *)event_info;
578 memset(&cbMsgInfo, 0, sizeof(struct tnoti_sms_cellBroadcast_msg));
580 line = (char *)(lines->data);
584 dbg("Noti line is %s",line);
585 tokens = tcore_at_tok_new(line); /* Split Line 1 into tokens */
587 pResp = g_slist_nth_data(tokens, 0);
589 length = atoi(pResp);
591 dbg("token 0 is null");
594 pdu = g_slist_nth_data(lines, 1);
596 cbMsgInfo.cbMsg.length = length;
597 cbMsgInfo.cbMsg.cbMsgType = SMS_CB_MSG_GSM;
599 dbg("CB Msg LENGTH [%2x]", length);
601 if ((cbMsgInfo.cbMsg.length >0) && (SMS_CB_SIZE_MAX >= cbMsgInfo.cbMsg.length)) {
602 unsigned char *byte_pdu = NULL;
604 byte_pdu = (unsigned char *)util_hexStringToBytes(pdu);
606 memcpy(cbMsgInfo.cbMsg.msgData, (char*)byte_pdu, cbMsgInfo.cbMsg.length);
607 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);
610 dbg("Invalid Message Length");
613 dbg("Recieved NULL pdu");
619 dbg(" Return value [%d]",rtn);
622 tcore_at_tok_free(tokens);
628 /*=============================================================
630 ==============================================================*/
631 static void on_response_sms_delete_msg(TcorePending *p, int data_len, const void *data, void *user_data)
633 struct tresp_sms_delete_msg delMsgInfo = {0,};
634 UserRequest *ur = NULL;
635 const TcoreATResponse *atResp = data;
638 int index = (int) user_data;
640 dbg(" Func Entrance");
642 ur = tcore_pending_ref_user_request(p);
643 if (atResp->success) {
645 delMsgInfo.index = index;
646 delMsgInfo.result = SMS_SENDSMS_SUCCESS;
649 delMsgInfo.index = index;
650 delMsgInfo.result = SMS_DEVICE_FAILURE;
653 rtn = tcore_user_request_send_response(ur, TRESP_SMS_DELETE_MSG, sizeof(struct tresp_sms_delete_msg), &delMsgInfo);
658 static void on_response_sms_save_msg(TcorePending *p, int data_len, const void *data, void *user_data)
660 struct tresp_sms_save_msg saveMsgInfo = {0,};
661 UserRequest *ur = NULL;
662 const TcoreATResponse *atResp = data;
663 GSList *tokens = NULL;
668 ur = tcore_pending_ref_user_request(p);
669 if (atResp->success) {
672 line = (char *)atResp->lines->data;
673 tokens = tcore_at_tok_new(line);
674 pResp = g_slist_nth_data(tokens, 0);
677 saveMsgInfo.index = (atoi(pResp) - 1); /* IMC index starts from 1 */
678 saveMsgInfo.result = SMS_SENDSMS_SUCCESS;
681 saveMsgInfo.index = -1;
682 saveMsgInfo.result = SMS_DEVICE_FAILURE;
684 tcore_at_tok_free(tokens);
688 saveMsgInfo.index = -1;
689 saveMsgInfo.result = SMS_DEVICE_FAILURE;
692 rtn = tcore_user_request_send_response(ur, TRESP_SMS_SAVE_MSG, sizeof(struct tresp_sms_save_msg), &saveMsgInfo);
693 dbg("Return value [%d]", rtn);
697 static void on_response_send_umts_msg(TcorePending *pending, int data_len, const void *data, void *user_data)
699 const TcoreATResponse *at_response = data;
700 struct tresp_sms_send_umts_msg resp_umts;
701 UserRequest *user_req = NULL;
704 GSList *tokens = NULL;
705 char *gslist_line = NULL, *line_token = NULL;
709 user_req = tcore_pending_ref_user_request(pending);
711 if (NULL == user_req) {
712 err("No user request");
718 memset(&resp_umts, 0x00, sizeof(resp_umts));
719 resp_umts.result = SMS_DEVICE_FAILURE;
721 if (at_response->success > 0) { // success
723 if (at_response->lines) { // lines present in at_response
724 gslist_line = (char *)at_response->lines->data;
725 dbg("gslist_line: [%s]", gslist_line);
727 tokens = tcore_at_tok_new(gslist_line); //extract tokens
729 line_token = g_slist_nth_data(tokens, 0);
730 if (line_token != NULL) {
731 msg_ref = atoi(line_token);
732 dbg("Message Reference: [%d]", msg_ref);
734 resp_umts.result = SMS_SENDSMS_SUCCESS;
736 dbg("No Message Reference received");
738 tcore_at_tok_free(tokens);
739 } else { // no lines in at_response
746 tcore_user_request_send_response(user_req, TRESP_SMS_SEND_UMTS_MSG, sizeof(resp_umts), &resp_umts);
752 static void on_response_class2_read_msg(TcorePending *pending, int data_len, const void *data, void *user_data)
754 const TcoreATResponse *at_response = data;
756 char *gslist_line = NULL, *line_token = NULL, *hex_pdu = NULL;
757 int pdu_len = 0, rtn = 0;
758 unsigned char *bytePDU = NULL;
759 struct tnoti_sms_umts_msg gsmMsgInfo;
763 dbg("lines: [%p]", at_response->lines);
764 g_slist_foreach(at_response->lines, print_glib_list_elem, NULL); //for debug log
766 if (at_response->success > 0) {
768 if (at_response->lines) {
770 gslist_line = (char *)at_response->lines->data;
772 dbg("gslist_line: [%s]", gslist_line);
774 tokens = tcore_at_tok_new(gslist_line);
775 dbg("Number of tokens: [%d]", g_slist_length(tokens));
776 g_slist_foreach(tokens, print_glib_list_elem, NULL); //for debug log
778 line_token = g_slist_nth_data(tokens, 2); //Third Token: Length
779 if (line_token != NULL) {
780 pdu_len = atoi(line_token);
781 dbg("Length: [%d]", pdu_len);
785 gslist_line = (char *)at_response->lines->next->data;
787 dbg("gslist_line: [%s]", gslist_line);
789 //free the consumed token
790 tcore_at_tok_free(tokens);
792 tokens = tcore_at_tok_new(gslist_line);
793 dbg("Number of tokens: [%d]", g_slist_length(tokens));
794 g_slist_foreach(tokens, print_glib_list_elem, NULL); //for debug log
796 hex_pdu = g_slist_nth_data(tokens, 0); //Fetch SMS PDU
798 //free the consumed token
799 tcore_at_tok_free(tokens);
807 /* Convert to Bytes */
808 bytePDU = (unsigned char *)util_hexStringToBytes(hex_pdu);
810 sca_length = bytePDU[0];
812 dbg("SCA length = %d", sca_length);
814 gsmMsgInfo.msgInfo.msgLength = pdu_len;
816 if (sca_length == 0) {
817 memcpy(gsmMsgInfo.msgInfo.tpduData, &bytePDU[1], gsmMsgInfo.msgInfo.msgLength);
819 memcpy(gsmMsgInfo.msgInfo.sca, bytePDU, sca_length);
820 memcpy(gsmMsgInfo.msgInfo.tpduData, &bytePDU[sca_length+1], gsmMsgInfo.msgInfo.msgLength);
823 util_hex_dump(" ", strlen(hex_pdu)/2, bytePDU);
824 util_hex_dump(" ", sca_length, gsmMsgInfo.msgInfo.sca);
825 util_hex_dump(" ", gsmMsgInfo.msgInfo.msgLength,gsmMsgInfo.msgInfo.tpduData);
827 rtn = tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(tcore_pending_ref_core_object(pending))), tcore_pending_ref_core_object(pending), TNOTI_SMS_INCOM_MSG, sizeof(struct tnoti_sms_umts_msg), &gsmMsgInfo);
835 static void on_response_read_msg(TcorePending *pending, int data_len, const void *data, void *user_data)
837 const TcoreATResponse *at_response = data;
838 struct tresp_sms_read_msg resp_read_msg;
839 UserRequest *user_req = NULL;
842 char *gslist_line = NULL, *line_token = NULL, *byte_pdu = NULL, *hex_pdu = NULL;
844 int msg_status = 0, alpha_id = 0, pdu_len = 0;
845 int index = (int)(uintptr_t)user_data;
848 dbg("index: [%d]", index);
849 g_slist_foreach(at_response->lines, print_glib_list_elem, NULL); //for debug log
851 user_req = tcore_pending_ref_user_request(pending);
852 if (NULL == user_req) {
853 err("No user request");
859 memset(&resp_read_msg, 0x00, sizeof(resp_read_msg));
860 resp_read_msg.result = SMS_PHONE_FAILURE;
862 if (at_response->success > 0) {
864 if (at_response->lines) {
866 gslist_line = (char *)at_response->lines->data;
868 dbg("gslist_line: [%s]", gslist_line);
870 tokens = tcore_at_tok_new(gslist_line);
871 dbg("Number of tokens: [%d]", g_slist_length(tokens));
872 g_slist_foreach(tokens, print_glib_list_elem, NULL); //for debug log
874 line_token = g_slist_nth_data(tokens, 0); //First Token: Message Status
875 if (line_token != NULL) {
876 msg_status = atoi(line_token);
877 dbg("msg_status is %d",msg_status);
878 switch (msg_status) {
880 resp_read_msg.dataInfo.msgStatus = SMS_STATUS_UNREAD;
884 resp_read_msg.dataInfo.msgStatus = SMS_STATUS_READ;
888 resp_read_msg.dataInfo.msgStatus = SMS_STATUS_UNSENT;
892 resp_read_msg.dataInfo.msgStatus = SMS_STATUS_SENT;
895 case AT_ALL: //Fall Through
896 default: //Fall Through
897 resp_read_msg.dataInfo.msgStatus = SMS_STATUS_RESERVED;
902 line_token = g_slist_nth_data(tokens, 1); //Second Token: AlphaID
903 if (line_token != NULL) {
904 alpha_id = atoi(line_token);
905 dbg("AlphaID: [%d]", alpha_id);
908 line_token = g_slist_nth_data(tokens, 2); //Third Token: Length
909 if (line_token != NULL) {
910 pdu_len = atoi(line_token);
911 dbg("Length: [%d]", pdu_len);
915 hex_pdu = (char *) at_response->lines->next->data;
917 dbg("EF-SMS PDU: [%s]", hex_pdu);
919 //free the consumed token
920 tcore_at_tok_free(tokens);
922 if (NULL != hex_pdu) {
923 util_hex_dump(" ", sizeof(hex_pdu), (void *)hex_pdu);
925 byte_pdu = util_hexStringToBytes(hex_pdu);
927 sca_length = (int)byte_pdu[0];
929 resp_read_msg.dataInfo.simIndex = index; //Retrieving index stored as user_data
931 dbg("SCA Length : %d", sca_length);
933 resp_read_msg.dataInfo.smsData.msgLength = pdu_len;
934 dbg("msgLength: [%d]", resp_read_msg.dataInfo.smsData.msgLength);
936 if(0 == sca_length) {
937 if ((resp_read_msg.dataInfo.smsData.msgLength > 0)
938 && (resp_read_msg.dataInfo.smsData.msgLength <= SMS_SMDATA_SIZE_MAX)) {
939 memset(resp_read_msg.dataInfo.smsData.sca, 0, TAPI_SIM_SMSP_ADDRESS_LEN);
940 memcpy(resp_read_msg.dataInfo.smsData.tpduData, &byte_pdu[1], resp_read_msg.dataInfo.smsData.msgLength);
942 resp_read_msg.result = SMS_SUCCESS;
944 dbg("Invalid Message Length");
945 resp_read_msg.result = SMS_INVALID_PARAMETER_FORMAT;
948 if ((resp_read_msg.dataInfo.smsData.msgLength > 0)
949 && (resp_read_msg.dataInfo.smsData.msgLength <= SMS_SMDATA_SIZE_MAX)) {
950 memcpy(resp_read_msg.dataInfo.smsData.sca, (char *)byte_pdu, (sca_length+1));
951 memcpy(resp_read_msg.dataInfo.smsData.tpduData, &byte_pdu[sca_length+1], resp_read_msg.dataInfo.smsData.msgLength);
953 util_hex_dump(" ", SMS_SMSP_ADDRESS_LEN, (void *)resp_read_msg.dataInfo.smsData.sca);
954 util_hex_dump(" ", (SMS_SMDATA_SIZE_MAX + 1), (void *)resp_read_msg.dataInfo.smsData.tpduData);
955 util_hex_dump(" ", sizeof(byte_pdu), (void *)byte_pdu);
957 resp_read_msg.result = SMS_SUCCESS;
959 dbg("Invalid Message Length");
960 resp_read_msg.result = SMS_INVALID_PARAMETER_FORMAT;
974 tcore_user_request_send_response(user_req, TRESP_SMS_READ_MSG, sizeof(resp_read_msg), &resp_read_msg);
980 static void on_response_get_msg_indices(TcorePending *pending, int data_len, const void *data, void *user_data)
982 const TcoreATResponse *at_response = data;
983 struct tresp_sms_get_storedMsgCnt resp_stored_msg_cnt;
984 UserRequest *user_req = NULL;
985 struct tresp_sms_get_storedMsgCnt *resp_stored_msg_cnt_prev = NULL;
987 GSList *tokens = NULL;
988 char *gslist_line = NULL, *line_token = NULL;
989 int gslist_line_count = 0, ctr_loop = 0;
993 resp_stored_msg_cnt_prev = (struct tresp_sms_get_storedMsgCnt *)user_data;
994 user_req = tcore_pending_ref_user_request(pending);
996 memset(&resp_stored_msg_cnt, 0x00, sizeof(resp_stored_msg_cnt));
997 resp_stored_msg_cnt.result = SMS_DEVICE_FAILURE;
999 if (at_response->success) {
1001 if (at_response->lines) {
1002 gslist_line_count = g_slist_length(at_response->lines);
1004 if (gslist_line_count > SMS_GSM_SMS_MSG_NUM_MAX)
1005 gslist_line_count = SMS_GSM_SMS_MSG_NUM_MAX;
1007 dbg("Number of lines: [%d]", gslist_line_count);
1008 g_slist_foreach(at_response->lines, print_glib_list_elem, NULL); //for debug log
1010 for (ctr_loop = 0; ctr_loop < gslist_line_count; ctr_loop++) {
1011 gslist_line = (char *)g_slist_nth_data(at_response->lines, ctr_loop); /* Fetch Line i */
1013 dbg("gslist_line [%d] is [%s]", ctr_loop, gslist_line);
1015 if (NULL != gslist_line) {
1016 tokens = tcore_at_tok_new(gslist_line);
1018 g_slist_foreach(tokens, print_glib_list_elem, NULL); //for debug log
1020 line_token = g_slist_nth_data(tokens, 0);
1021 if (NULL != line_token) {
1022 resp_stored_msg_cnt.storedMsgCnt.indexList[ctr_loop] = atoi(line_token);
1023 resp_stored_msg_cnt.result = SMS_SENDSMS_SUCCESS;
1025 dbg("line_token of gslist_line [%d] is NULL", ctr_loop);
1028 tcore_at_tok_free(tokens);
1030 dbg("gslist_line [%d] is NULL", ctr_loop);
1036 if (resp_stored_msg_cnt_prev->storedMsgCnt.usedCount == 0) { // Check if used count is zero
1037 resp_stored_msg_cnt.result = SMS_SENDSMS_SUCCESS;
1041 dbg("Respnose NOK");
1044 resp_stored_msg_cnt.storedMsgCnt.totalCount = resp_stored_msg_cnt_prev->storedMsgCnt.totalCount;
1045 resp_stored_msg_cnt.storedMsgCnt.usedCount = resp_stored_msg_cnt_prev->storedMsgCnt.usedCount;
1047 util_sms_free_memory(resp_stored_msg_cnt_prev);
1049 dbg("total: [%d], used: [%d], result: [%d]", resp_stored_msg_cnt.storedMsgCnt.totalCount, resp_stored_msg_cnt.storedMsgCnt.usedCount, resp_stored_msg_cnt.result);
1050 for (ctr_loop = 0; ctr_loop < gslist_line_count; ctr_loop++) {
1051 dbg("index: [%d]", resp_stored_msg_cnt.storedMsgCnt.indexList[ctr_loop]);
1054 tcore_user_request_send_response(user_req, TRESP_SMS_GET_STORED_MSG_COUNT, sizeof(resp_stored_msg_cnt), &resp_stored_msg_cnt);
1060 static void on_response_get_stored_msg_cnt(TcorePending *pending, int data_len, const void *data, void *user_data)
1062 UserRequest *ur = NULL, *ur_dup = NULL;
1063 struct tresp_sms_get_storedMsgCnt *respStoredMsgCnt = NULL;
1064 const TcoreATResponse *atResp = data;
1065 GSList *tokens=NULL;
1066 char *line = NULL , *pResp = NULL , *cmd_str = NULL;
1067 TcoreATRequest *atReq = NULL;
1068 int usedCnt = 0, totalCnt = 0, result = 0;
1070 TcorePending *pending_new = NULL;
1071 CoreObject *o = NULL;
1075 respStoredMsgCnt = malloc(sizeof(struct tresp_sms_get_storedMsgCnt));
1076 result = SMS_DEVICE_FAILURE;
1078 ur = tcore_pending_ref_user_request(pending);
1079 ur_dup = tcore_user_request_ref(ur);
1080 o = tcore_pending_ref_core_object(pending);
1082 if (atResp->success > 0) {
1084 if (NULL != atResp->lines) {
1085 line = (char *)atResp->lines->data;
1086 dbg("line is %s",line);
1088 tokens = tcore_at_tok_new(line);
1089 pResp = g_slist_nth_data(tokens, 0);
1092 usedCnt =atoi(pResp);
1093 dbg("used cnt is %d",usedCnt);
1096 pResp = g_slist_nth_data(tokens, 1);
1098 totalCnt =atoi(pResp);
1099 result = SMS_SENDSMS_SUCCESS;
1101 respStoredMsgCnt->storedMsgCnt.usedCount = usedCnt;
1102 respStoredMsgCnt->storedMsgCnt.totalCount = totalCnt;
1103 respStoredMsgCnt->result = result;
1105 dbg("used %d, total %d, result %d",usedCnt, totalCnt,result);
1107 pending_new = tcore_pending_new(o, 0);
1108 //Get all messages information
1109 cmd_str = g_strdup_printf("AT+CMGL=4");
1110 atReq = tcore_at_request_new((const char *)cmd_str, "+CMGL", TCORE_AT_MULTILINE);
1112 dbg("cmd str is %s",cmd_str);
1114 tcore_pending_set_request_data(pending_new, 0,atReq);
1115 tcore_pending_set_response_callback(pending_new, on_response_get_msg_indices, (void *)respStoredMsgCnt);
1116 tcore_pending_link_user_request(pending_new, ur_dup);
1117 tcore_pending_set_send_callback(pending_new, on_confirmation_sms_message_send, NULL);
1118 tcore_hal_send_request(tcore_object_get_hal(o), pending_new);
1120 //free the consumed token
1121 tcore_at_tok_free(tokens);
1128 //free the consumed token
1130 tcore_at_tok_free(tokens);
1135 err("Response NOK");
1137 respStoredMsgCnt->result = result;
1138 tcore_user_request_send_response(ur, TRESP_SMS_GET_STORED_MSG_COUNT, sizeof(struct tresp_sms_get_storedMsgCnt), &respStoredMsgCnt);
1145 static void on_response_get_sca(TcorePending *pending, int data_len, const void *data, void *user_data)
1147 const TcoreATResponse *at_response = data;
1148 struct tresp_sms_get_sca respGetSca;
1149 UserRequest *user_req = NULL;
1151 GSList *tokens = NULL;
1152 char *gslist_line = NULL, *sca_addr = NULL, *sca_toa = NULL;
1156 memset(&respGetSca, 0, sizeof(respGetSca));
1157 respGetSca.result = SMS_DEVICE_FAILURE;
1159 user_req = tcore_pending_ref_user_request(pending);
1161 if (at_response->success) {
1163 if (at_response->lines) {
1164 gslist_line = (char *)at_response->lines->data;
1166 tokens = tcore_at_tok_new(gslist_line);
1167 sca_addr = g_slist_nth_data(tokens, 0);
1168 sca_toa = g_slist_nth_data(tokens, 1);
1170 if ((NULL != sca_addr)
1171 && (NULL != sca_toa)) {
1172 dbg("sca_addr: [%s]. sca_toa: [%s]", sca_addr, sca_toa);
1174 respGetSca.scaAddress.dialNumLen = strlen(sca_addr);
1176 if (145 == atoi(sca_toa)) {
1177 respGetSca.scaAddress.typeOfNum = SIM_TON_INTERNATIONAL;
1179 respGetSca.scaAddress.typeOfNum = SIM_TON_NATIONAL;
1182 respGetSca.scaAddress.numPlanId = 0;
1184 memcpy(respGetSca.scaAddress.diallingNum, sca_addr, strlen(sca_addr));
1186 dbg("len [%d], sca_addr [%s], TON [%d], NPI [%d]", respGetSca.scaAddress.dialNumLen, respGetSca.scaAddress.diallingNum, respGetSca.scaAddress.typeOfNum, respGetSca.scaAddress.numPlanId);
1188 respGetSca.result = SMS_SENDSMS_SUCCESS;
1190 err("sca_addr OR sca_toa NULL");
1196 dbg("Response NOK");
1199 tcore_user_request_send_response(user_req, TRESP_SMS_GET_SCA, sizeof(respGetSca), &respGetSca);
1202 tcore_at_tok_free(tokens);
1208 static void on_response_set_sca(TcorePending *pending, int data_len, const void *data, void *user_data)
1211 Response is expected in this format
1217 //copies the AT response data to resp
1218 const TcoreATResponse *atResp = data;
1219 struct tresp_sms_set_sca respSetSca;
1221 memset(&respSetSca, 0, sizeof(struct tresp_sms_set_sca));
1223 ur = tcore_pending_ref_user_request(pending);
1225 dbg("no user_request");
1229 if (atResp->success > 0) {
1231 respSetSca.result = SMS_SUCCESS;
1233 dbg("RESPONSE NOK");
1234 respSetSca.result = SMS_DEVICE_FAILURE;
1237 tcore_user_request_send_response(ur, TRESP_SMS_SET_SCA, sizeof(struct tresp_sms_set_sca), &respSetSca);
1242 static void on_response_get_cb_config(TcorePending *p, int data_len, const void *data, void *user_data)
1245 struct tresp_sms_get_cb_config respGetCbConfig;
1246 const TcoreATResponse *atResp = data;
1247 GSList *tokens=NULL;
1249 char *pResp = NULL, *line = NULL;
1252 memset(&respGetCbConfig, 0, sizeof(struct tresp_sms_get_cb_config));
1253 respGetCbConfig.result = SMS_DEVICE_FAILURE;
1255 ur = tcore_pending_ref_user_request(p);
1257 dbg("no user_request");
1261 respGetCbConfig.cbConfig.net3gppType = SMS_NETTYPE_3GPP;
1263 if (atResp->success) {
1265 if (atResp->lines) {
1266 line = (char*)atResp->lines->data;
1268 dbg("line is %s",line);
1269 tokens = tcore_at_tok_new(line);
1270 pResp = g_slist_nth_data(tokens, 0);
1273 respGetCbConfig.cbConfig.cbEnabled = mode;
1275 pResp = g_slist_nth_data(tokens, 1);
1277 GSList *cb_tokens = NULL;
1278 char *cb_mid_str = NULL;
1279 int num_cb_tokens = 0;
1280 char *mid_tok = NULL;
1281 char *first_tok = NULL, *second_tok = NULL;
1283 // 0,1,5,320-478,922
1284 cb_mid_str = util_removeQuotes(pResp);
1285 cb_tokens = tcore_at_tok_new((const char *) cb_mid_str);
1287 num_cb_tokens = g_slist_length(cb_tokens);
1288 dbg("num_cb_tokens = %d", num_cb_tokens);
1290 if (num_cb_tokens == 0) {
1291 if (mode == 1) { // Enable all CBs
1292 respGetCbConfig.cbConfig.msgIdRangeCount = 1;
1293 respGetCbConfig.cbConfig.msgIDs[0].net3gpp.fromMsgId = 0x0000;
1294 respGetCbConfig.cbConfig.msgIDs[0].net3gpp.toMsgId = SMS_GSM_SMS_CBMI_LIST_SIZE_MAX + 1;
1295 respGetCbConfig.cbConfig.msgIDs[0].net3gpp.selected = TRUE;
1296 respGetCbConfig.result = SMS_SENDSMS_SUCCESS;
1297 } else { // all CBs disabled
1298 respGetCbConfig.cbConfig.msgIdRangeCount = 0;
1299 respGetCbConfig.cbConfig.msgIDs[0].net3gpp.selected = FALSE;
1300 respGetCbConfig.result = SMS_SENDSMS_SUCCESS;
1304 for (i = 0; i < num_cb_tokens; i++) {
1305 respGetCbConfig.cbConfig.msgIDs[i].net3gpp.selected = TRUE;
1306 respGetCbConfig.cbConfig.msgIdRangeCount++;
1308 mid_tok = tcore_at_tok_nth(cb_tokens, i);
1309 first_tok = strtok(mid_tok, delim);
1310 second_tok = strtok(NULL, delim);
1312 if ((first_tok != NULL) && (second_tok != NULL)) { // mids in range (320-478)
1313 dbg("inside if mid_range");
1314 respGetCbConfig.cbConfig.msgIDs[i].net3gpp.fromMsgId = atoi(first_tok);
1315 respGetCbConfig.cbConfig.msgIDs[i].net3gpp.toMsgId = atoi(second_tok);
1316 } // single mid value (0,1,5, 922)
1318 respGetCbConfig.cbConfig.msgIDs[i].net3gpp.fromMsgId = atoi(mid_tok);
1319 respGetCbConfig.cbConfig.msgIDs[i].net3gpp.toMsgId = atoi(mid_tok);
1325 respGetCbConfig.cbConfig.msgIdRangeCount = 1;
1326 respGetCbConfig.cbConfig.msgIDs[0].net3gpp.fromMsgId = 0x0000;
1327 respGetCbConfig.cbConfig.msgIDs[0].net3gpp.toMsgId = SMS_GSM_SMS_CBMI_LIST_SIZE_MAX + 1;
1328 respGetCbConfig.cbConfig.msgIDs[0].net3gpp.selected = TRUE;
1329 respGetCbConfig.result = SMS_SENDSMS_SUCCESS;
1331 respGetCbConfig.cbConfig.msgIdRangeCount = 0;
1332 respGetCbConfig.cbConfig.msgIDs[0].net3gpp.selected = FALSE;
1333 respGetCbConfig.result = SMS_SENDSMS_SUCCESS;
1337 dbg("line is NULL");
1340 dbg("atresp->lines is NULL");
1343 dbg("RESPONSE NOK");
1346 tcore_user_request_send_response(ur, TRESP_SMS_GET_CB_CONFIG, sizeof(struct tresp_sms_get_cb_config), &respGetCbConfig);
1349 tcore_at_tok_free(tokens);
1354 static void on_response_set_cb_config(TcorePending *pending, int data_len, const void *data, void *user_data)
1357 Response is expected in this format
1364 const TcoreATResponse *resp = data;
1366 const char *line = NULL;
1367 GSList *tokens=NULL;
1369 struct tresp_sms_set_cb_config respSetCbConfig = {0,};
1371 memset(&respSetCbConfig, 0, sizeof(struct tresp_sms_set_cb_config));
1373 ur = tcore_pending_ref_user_request(pending);
1374 respSetCbConfig.result = SMS_SENDSMS_SUCCESS;
1376 if (resp->success > 0) {
1379 dbg("RESPONSE NOK");
1380 line = (const char*)resp->final_response;
1381 tokens = tcore_at_tok_new(line);
1383 if (g_slist_length(tokens) < 1) {
1384 dbg("err cause not specified or string corrupted");
1385 respSetCbConfig.result = SMS_DEVICE_FAILURE;
1387 response = atoi(g_slist_nth_data(tokens, 0));
1388 /* TODO: CMEE error mapping is required. */
1389 respSetCbConfig.result = SMS_DEVICE_FAILURE;
1393 dbg("no user_request");
1397 tcore_user_request_send_response(ur, TRESP_SMS_SET_CB_CONFIG, sizeof(struct tresp_sms_set_cb_config), &respSetCbConfig);
1400 tcore_at_tok_free(tokens);
1405 static void on_response_set_mem_status(TcorePending *p, int data_len, const void *data, void *user_data)
1408 struct tresp_sms_set_mem_status respSetMemStatus = {0,};
1409 const TcoreATResponse *resp = data;
1411 memset(&respSetMemStatus, 0, sizeof(struct tresp_sms_set_mem_status));
1413 if (resp->success > 0) {
1415 respSetMemStatus.result = SMS_SENDSMS_SUCCESS;
1417 dbg("RESPONSE NOK");
1418 respSetMemStatus.result = SMS_DEVICE_FAILURE;
1421 ur = tcore_pending_ref_user_request(p);
1423 dbg("no user_request");
1427 tcore_user_request_send_response(ur, TRESP_SMS_SET_MEM_STATUS, sizeof(struct tresp_sms_set_mem_status), &respSetMemStatus);
1432 static void on_response_set_msg_status(TcorePending *pending, int data_len, const void *data, void *user_data)
1435 struct tresp_sms_set_msg_status respMsgStatus = {0, };
1436 const TcoreATResponse *atResp = data;
1437 int response = 0, sw1 = 0, sw2 = 0;
1438 const char *line = NULL;
1440 GSList *tokens = NULL;
1444 memset(&respMsgStatus, 0, sizeof(struct tresp_sms_set_msg_status));
1445 respMsgStatus.result = SMS_DEVICE_FAILURE;
1447 ur = tcore_pending_ref_user_request(pending);
1449 if (atResp->success > 0) {
1452 if (atResp->lines) {
1453 line = (const char *) atResp->lines->data;
1454 tokens = tcore_at_tok_new(line);
1455 pResp = g_slist_nth_data(tokens, 0);
1456 if (pResp != NULL) {
1461 pResp = g_slist_nth_data(tokens, 1);
1462 if (pResp != NULL) {
1464 if ((sw1 == AT_SW1_SUCCESS) && (sw2 == 0)) {
1465 respMsgStatus.result = SMS_SENDSMS_SUCCESS;
1470 pResp = g_slist_nth_data(tokens, 3);
1472 if (pResp != NULL) {
1473 response = atoi(pResp);
1474 dbg("response is %s", response);
1480 dbg("RESPONSE NOK");
1483 tcore_user_request_send_response(ur, TRESP_SMS_SET_MSG_STATUS , sizeof(struct tresp_sms_set_msg_status), &respMsgStatus);
1486 tcore_at_tok_free(tokens);
1492 static void on_response_get_sms_params(TcorePending *pending, int data_len, const void *data, void *user_data)
1495 struct tresp_sms_get_params respGetParams ;
1496 const TcoreATResponse *atResp = data;
1497 int sw1 = 0, sw2 = 0;
1498 const char *line = NULL;
1500 GSList *tokens=NULL;
1501 char *hexData = NULL;
1502 char *recordData = NULL;
1505 memset(&respGetParams, 0, sizeof(struct tresp_sms_get_params));
1506 respGetParams.result = SMS_DEVICE_FAILURE;
1508 ur = tcore_pending_ref_user_request(pending);
1510 if (atResp->success > 0) {
1513 if (atResp->lines) {
1514 line = (const char *) atResp->lines->data;
1515 tokens = tcore_at_tok_new(line);
1516 pResp = g_slist_nth_data(tokens, 0);
1517 if (pResp != NULL) {
1519 dbg("sw1 is %d", sw1);
1523 pResp = g_slist_nth_data(tokens, 1);
1524 if (pResp != NULL) {
1526 dbg("sw2 is %d", sw2);
1527 if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
1528 respGetParams.result = SMS_SENDSMS_SUCCESS;
1533 pResp = g_slist_nth_data(tokens, 2);
1534 if (pResp != NULL) {
1535 hexData = util_removeQuotes(pResp);
1537 recordData = util_hexStringToBytes(hexData);
1538 util_hex_dump(" ", strlen(hexData) / 2, recordData);
1540 respGetParams.paramsInfo.recordLen = strlen(hexData) / 2;
1542 util_sms_decode_smsParameters((unsigned char *) recordData, strlen(hexData) / 2, &(respGetParams.paramsInfo));
1543 respGetParams.result = SMS_SENDSMS_SUCCESS;
1545 for (i = 0; i < (int) respGetParams.paramsInfo.tpSvcCntrAddr.dialNumLen; i++)
1546 dbg("SCAddr = %d [%02x]", i, respGetParams.paramsInfo.tpSvcCntrAddr.diallingNum[i]);
1553 tcore_at_tok_free(tokens);
1556 dbg("RESPONSE NOK");
1559 tcore_user_request_send_response(ur, TRESP_SMS_GET_PARAMS, sizeof(struct tresp_sms_get_params), &respGetParams);
1565 static void on_response_set_sms_params(TcorePending *pending, int data_len, const void *data, void *user_data)
1568 struct tresp_sms_set_params respSetParams = {0, };
1569 const TcoreATResponse *atResp = data;
1570 int sw1 =0 , sw2 = 0;
1571 const char *line = NULL;
1573 GSList *tokens=NULL;
1576 memset(&respSetParams, 0, sizeof(struct tresp_sms_set_params));
1577 ur = tcore_pending_ref_user_request(pending);
1579 respSetParams.result = SMS_DEVICE_FAILURE;
1581 if (atResp->success > 0) {
1584 if (atResp->lines) {
1585 line = (const char *) atResp->lines->data;
1586 tokens = tcore_at_tok_new(line);
1587 pResp = g_slist_nth_data(tokens, 0);
1588 if (pResp != NULL) {
1594 pResp = g_slist_nth_data(tokens, 1);
1595 if (pResp != NULL) {
1597 if (((sw1 == AT_SW1_SUCCESS) && (sw2 == AT_SW2_SUCCESS)) || (sw1 == 0x91)) {
1598 respSetParams.result = SMS_SENDSMS_SUCCESS;
1607 dbg("RESPONSE NOK");
1610 tcore_user_request_send_response(ur, TRESP_SMS_SET_PARAMS , sizeof(struct tresp_sms_set_params), &respSetParams);
1613 tcore_at_tok_free(tokens);
1619 static void on_response_get_paramcnt(TcorePending *p, int data_len, const void *data, void *user_data)
1621 UserRequest *ur = NULL;
1622 struct tresp_sms_get_paramcnt respGetParamCnt = {0, };
1623 const TcoreATResponse *atResp = data;
1624 char *line = NULL , *pResp = NULL;
1625 int sw1 = 0 , sw2 = 0, *smsp_record_len = NULL;
1627 GSList *tokens=NULL;
1628 CoreObject *co_sim = NULL; //need this to get the sim type GSM/USIM
1629 TcorePlugin *plugin = NULL;
1633 ur = tcore_pending_ref_user_request(p);
1634 respGetParamCnt.result = SMS_DEVICE_FAILURE;
1636 if (atResp->success > 0) {
1639 if (atResp->lines) {
1640 line = (char *) atResp->lines->data;
1642 dbg("line is %s", line);
1644 tokens = tcore_at_tok_new(line);
1645 pResp = g_slist_nth_data(tokens, 0);
1646 if (pResp != NULL) {
1651 pResp = g_slist_nth_data(tokens, 1);
1652 if (pResp != NULL) {
1654 if ((sw1 == 144) && (sw2 == 0)) {
1655 respGetParamCnt.result = SMS_SENDSMS_SUCCESS;
1660 pResp = g_slist_nth_data(tokens, 2);
1661 if (pResp != NULL) {
1662 char *hexData = NULL;
1663 char *recordData = NULL;
1664 hexData = util_removeQuotes(pResp);
1666 /*1. SIM access success case*/
1667 if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
1668 unsigned char tag_len = 0; /* 1 or 2 bytes ??? */
1670 char num_of_records = 0;
1671 unsigned char file_id_len = 0;
1672 unsigned short file_id = 0;
1673 unsigned short file_size = 0;
1674 unsigned short file_type = 0;
1675 unsigned short arr_file_id = 0;
1676 int arr_file_id_rec_num = 0;
1678 /* handling only last 3 bits */
1679 unsigned char file_type_tag = 0x07;
1680 unsigned char *ptr_data;
1682 recordData = util_hexStringToBytes(hexData);
1683 util_hex_dump(" ", strlen(hexData)/2, recordData);
1685 ptr_data = (unsigned char *)recordData;
1687 co_sim = tcore_plugin_ref_core_object(tcore_pending_ref_plugin(p), "sim");
1688 sim_type = tcore_sim_get_type(co_sim);
1689 dbg("sim type is %d",sim_type);
1691 if (sim_type == SIM_TYPE_USIM) {
1693 ETSI TS 102 221 v7.9.0
1695 '62' FCP template tag
1696 - Response for an EF
1697 '82' M File Descriptor
1698 '83' M File Identifier
1699 'A5' O Proprietary information
1700 '8A' M Life Cycle Status Integer
1701 '8B', '8C' or 'AB' C1 Security attributes
1703 '81' O Total file size
1704 '88' O Short File Identifier (SFI)
1707 /* rsim.res_len has complete data length received */
1709 /* FCP template tag - File Control Parameters tag*/
1710 if (*ptr_data == 0x62) {
1711 /* parse complete FCP tag*/
1712 /* increment to next byte */
1714 tag_len = *ptr_data++;
1715 /* FCP file descriptor - file type, accessibility, DF, ADF etc*/
1716 if (*ptr_data == 0x82) {
1717 /* increment to next byte */
1721 /* unsigned char file_desc_len = *ptr_data++;*/
1722 /* dbg("file descriptor length: [%d]", file_desc_len);*/
1723 /* TBD: currently capture only file type : ignore sharable, non sharable, working, internal etc*/
1724 /* consider only last 3 bits*/
1725 file_type_tag = file_type_tag & (*ptr_data);
1727 switch (file_type_tag) {
1728 /* increment to next byte */
1732 dbg("Getting FileType: [Transparent file type]");
1733 /* increment to next byte */
1735 file_type = 0x01; //SIM_FTYPE_TRANSPARENT
1736 /* data coding byte - value 21 */
1741 dbg("Getting FileType: [Linear fixed file type]");
1742 /* increment to next byte */
1744 /* data coding byte - value 21 */
1747 memcpy(&record_len, ptr_data, 2);
1749 record_len = SMS_SWAPBYTES16(record_len);
1750 ptr_data = ptr_data + 2;
1751 num_of_records = *ptr_data++;
1752 /* Data lossy conversation from enum (int) to unsigned char */
1753 file_type = 0x02; // SIM_FTYPE_LINEAR_FIXED
1757 dbg(" Cyclic fixed file type");
1758 /* increment to next byte */
1760 /* data coding byte - value 21 */
1763 memcpy(&record_len, ptr_data, 2);
1765 record_len = SMS_SWAPBYTES16(record_len);
1766 ptr_data = ptr_data + 2;
1767 num_of_records = *ptr_data++;
1768 file_type = 0x04; //SIM_FTYPE_CYCLIC
1772 dbg("not handled file type [0x%x]", *ptr_data);
1776 dbg("INVALID FCP received - DEbug!");
1779 tcore_at_tok_free(tokens);
1783 /*File identifier - file id?? */ // 0x84,0x85,0x86 etc are currently ignored and not handled
1784 if (*ptr_data == 0x83) {
1785 /* increment to next byte */
1787 file_id_len = *ptr_data++;
1788 memcpy(&file_id, ptr_data, file_id_len);
1790 file_id = SMS_SWAPBYTES16(file_id);
1791 ptr_data = ptr_data + 2;
1792 dbg("Getting FileID=[0x%x]", file_id);
1794 dbg("INVALID FCP received - DEbug!");
1797 tcore_at_tok_free(tokens);
1801 /* proprietary information */
1802 if (*ptr_data == 0xA5) {
1803 unsigned short prop_len;
1804 /* increment to next byte */
1807 prop_len = *ptr_data;
1809 ptr_data = ptr_data + prop_len + 1;
1811 dbg("INVALID FCP received - DEbug!");
1814 /* life cycle status integer [8A][length:0x01][status]*/
1817 00000000 : No information given
1818 00000001 : creation state
1819 00000011 : initialization state
1820 000001-1 : operation state -activated
1821 000001-0 : operation state -deactivated
1822 000011-- : Termination state
1823 b8~b5 !=0, b4~b1=X : Proprietary
1824 Any other value : RFU
1826 if (*ptr_data == 0x8A) {
1827 /* increment to next byte */
1829 /* length - value 1 */
1832 switch (*ptr_data) {
1835 dbg("<IPC_RX> operation state -deactivated");
1841 dbg("<IPC_RX> operation state -activated");
1846 dbg("<IPC_RX> DEBUG! LIFE CYCLE STATUS =[0x%x]",*ptr_data);
1852 /* related to security attributes : currently not handled*/
1853 if (*ptr_data == 0x86 || *ptr_data == 0x8B || *ptr_data == 0x8C || *ptr_data == 0xAB) {
1854 /* increment to next byte */
1856 /* if tag length is 3 */
1857 if (*ptr_data == 0x03) {
1858 /* increment to next byte */
1861 memcpy(&arr_file_id, ptr_data, 2);
1863 arr_file_id = SMS_SWAPBYTES16(arr_file_id);
1864 ptr_data = ptr_data + 2;
1865 arr_file_id_rec_num = *ptr_data++;
1867 /* if tag length is not 3 */
1868 /* ignoring bytes */
1869 // ptr_data = ptr_data + 4;
1870 dbg("Useless security attributes, so jump to next tag");
1871 ptr_data = ptr_data + (*ptr_data + 1);
1874 dbg("INVALID FCP received[0x%x] - DEbug!", *ptr_data);
1877 tcore_at_tok_free(tokens);
1881 dbg("Current ptr_data value is [%x]", *ptr_data);
1883 /* file size excluding structural info*/
1884 if (*ptr_data == 0x80) {
1885 /* for EF file size is body of file and for Linear or cyclic it is
1886 * number of recXsizeof(one record)
1888 /* increment to next byte */
1890 /* length is 1 byte - value is 2 bytes or more */
1892 memcpy(&file_size, ptr_data, 2);
1894 file_size = SMS_SWAPBYTES16(file_size);
1895 ptr_data = ptr_data + 2;
1897 dbg("INVALID FCP received - DEbug!");
1900 tcore_at_tok_free(tokens);
1904 /* total file size including structural info*/
1905 if (*ptr_data == 0x81) {
1907 /* increment to next byte */
1912 ptr_data = ptr_data + 3;
1914 dbg("INVALID FCP received - DEbug!");
1915 /* 0x81 is optional tag?? check out! so do not return -1 from here! */
1918 /*short file identifier ignored*/
1919 if (*ptr_data == 0x88) {
1920 dbg("0x88: Do Nothing");
1924 dbg("INVALID FCP received - DEbug!");
1927 tcore_at_tok_free(tokens);
1930 } else if (sim_type == SIM_TYPE_GSM) {
1931 unsigned char gsm_specific_file_data_len = 0;
1932 /* ignore RFU byte1 and byte2 */
1936 //file_size = p_info->response_len;
1937 memcpy(&file_size, ptr_data, 2);
1939 file_size = SMS_SWAPBYTES16(file_size);
1940 /* parsed file size */
1941 ptr_data = ptr_data + 2;
1943 memcpy(&file_id, ptr_data, 2);
1944 file_id = SMS_SWAPBYTES16(file_id);
1945 dbg(" FILE id --> [%x]", file_id);
1946 ptr_data = ptr_data + 2;
1947 /* save file type - transparent, linear fixed or cyclic */
1948 file_type_tag = (*(ptr_data + 7));
1950 switch (*ptr_data) {
1953 dbg(" RFU file type- not handled - Debug!");
1958 dbg(" MF file type - not handled - Debug!");
1963 dbg(" DF file type - not handled - Debug!");
1968 dbg(" EF file type [%d] ", file_type_tag);
1969 /* increment to next byte */
1972 if (file_type_tag == 0x00 || file_type_tag == 0x01) {
1973 /* increament to next byte as this byte is RFU */
1976 (file_type_tag == 0x00) ? 0x01 : 0x02; // SIM_FTYPE_TRANSPARENT:SIM_FTYPE_LINEAR_FIXED;
1978 /* increment to next byte */
1980 /* For a cyclic EF all bits except bit 7 are RFU; b7=1 indicates that */
1981 /* the INCREASE command is allowed on the selected cyclic file. */
1982 file_type = 0x04; // SIM_FTYPE_CYCLIC;
1984 /* bytes 9 to 11 give SIM file access conditions */
1986 /* byte 10 has one nibble that is RF U and another for INCREASE which is not used currently */
1988 /* byte 11 is invalidate and rehabilate nibbles */
1990 /* byte 12 - file status */
1992 /* byte 13 - GSM specific data */
1993 gsm_specific_file_data_len = *ptr_data;
1995 /* byte 14 - structure of EF - transparent or linear or cyclic , already saved above */
1997 /* byte 15 - length of record for linear and cyclic , for transparent it is set to 0x00. */
1998 record_len = *ptr_data;
1999 dbg("record length[%d], file size[%d]", record_len, file_size);
2001 if (record_len != 0)
2002 num_of_records = (file_size / record_len);
2004 dbg("Number of records [%d]", num_of_records);
2008 dbg(" not handled file type");
2012 dbg(" Card Type - UNKNOWN [%d]", sim_type);
2015 dbg("EF[0x%x] size[%ld] Type[0x%x] NumOfRecords[%ld] RecordLen[%ld]", file_id, file_size, file_type, num_of_records, record_len);
2017 respGetParamCnt.recordCount = num_of_records;
2018 respGetParamCnt.result = SMS_SUCCESS;
2020 //TO Store smsp record length in the property
2021 plugin = tcore_pending_ref_plugin(p);
2022 smsp_record_len = tcore_plugin_ref_property(plugin, "SMSPRECORDLEN");
2023 memcpy(smsp_record_len, &record_len, sizeof(int));
2028 /*2. SIM access fail case*/
2029 dbg("SIM access fail");
2030 respGetParamCnt.result = SMS_UNKNOWN;
2033 dbg("presp is NULL");
2036 dbg("line is blank");
2039 dbg("RESPONSE NOK");
2042 tcore_user_request_send_response(ur, TRESP_SMS_GET_PARAMCNT, sizeof(struct tresp_sms_get_paramcnt), &respGetParamCnt);
2045 tcore_at_tok_free(tokens);
2051 static void _response_get_efsms_data(TcorePending *p, int data_len, const void *data, void *user_data)
2053 UserRequest *ur = NULL;
2054 UserRequest *dup_ur = NULL;
2055 struct tresp_sms_set_msg_status resp_msg_status = {0,};
2056 const struct treq_sms_set_msg_status *req_msg_status = NULL ;
2058 const TcoreATResponse *resp = data;
2059 char *encoded_data = NULL;
2060 char msg_status = 0;
2062 GSList *tokens=NULL;
2063 const char *line = NULL;
2067 TcoreHal *hal = NULL;
2068 TcoreATRequest *atreq = NULL;
2069 TcorePending *pending = NULL;
2070 gchar *cmd_str = NULL;
2072 ur = tcore_pending_ref_user_request(p);
2074 req_msg_status = tcore_user_request_ref_data(ur, NULL);
2076 resp_msg_status.result = SMS_DEVICE_FAILURE;
2078 hal = tcore_object_get_hal(tcore_pending_ref_core_object(pending));
2079 dbg("msgStatus: [%x], index [%x]", req_msg_status->msgStatus, req_msg_status->index);
2081 if (resp->success <= 0) {
2088 line = (const char *) resp->lines->data;
2089 tokens = tcore_at_tok_new(line);
2090 if (g_slist_length(tokens) != 3) {
2091 msg("invalid message");
2095 sw1 = atoi(g_slist_nth_data(tokens, 0));
2096 sw2 = atoi(g_slist_nth_data(tokens, 1));
2097 pResp = g_slist_nth_data(tokens, 2);
2099 if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
2100 switch (req_msg_status->msgStatus) {
2101 case SMS_STATUS_READ:
2105 case SMS_STATUS_UNREAD:
2109 case SMS_STATUS_UNSENT:
2113 case SMS_STATUS_SENT:
2117 case SMS_STATUS_DELIVERED:
2121 case SMS_STATUS_DELIVERY_UNCONFIRMED:
2125 case SMS_STATUS_MESSAGE_REPLACED:
2126 case SMS_STATUS_RESERVED:
2132 encoded_data = util_removeQuotes(pResp);
2134 //overwrite Status byte information
2135 util_byte_to_hex((const char *)&msg_status, (char *)encoded_data, 1);
2137 //Update EF-SMS with just status byte overwritten, rest 175 bytes are same as received in read information
2138 cmd_str = g_strdup_printf("AT+CRSM=220,28476,%d, 4, %d, \"%s\"", (req_msg_status->index+1), AT_EF_SMS_RECORD_LEN, encoded_data);
2139 atreq = tcore_at_request_new((const char *)cmd_str, "+CRSM", TCORE_AT_SINGLELINE);
2140 pending = tcore_pending_new(tcore_pending_ref_core_object(pending), 0);
2141 if (NULL == cmd_str || NULL == atreq || NULL == pending) {
2142 err("Out of memory. Unable to proceed");
2143 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
2145 //free memory we own
2148 util_sms_free_memory(atreq);
2149 util_sms_free_memory(pending);
2154 util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
2156 dup_ur = tcore_user_request_ref(ur);
2158 tcore_pending_set_request_data(pending, 0, atreq);
2159 tcore_pending_set_response_callback(pending, on_response_set_msg_status, NULL);
2160 tcore_pending_link_user_request(pending, dup_ur);
2161 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
2162 tcore_hal_send_request(hal, pending);
2171 tcore_at_tok_free(tokens);
2173 tcore_user_request_send_response(ur, TRESP_SMS_SET_MSG_STATUS , sizeof(struct tresp_sms_set_msg_status), &msg_status);
2180 /*=============================================================
2182 ==============================================================*/
2183 static TReturn send_umts_msg(CoreObject *obj, UserRequest *ur)
2185 gchar *cmd_str = NULL;
2186 TcoreHal *hal = NULL;
2187 TcoreATRequest *atreq = NULL;
2188 TcorePending *pending = NULL;
2189 const struct treq_sms_send_umts_msg *sendUmtsMsg = NULL;
2190 char buf[2*(SMS_SMSP_ADDRESS_LEN+SMS_SMDATA_SIZE_MAX)+1] = {0};
2196 sendUmtsMsg = tcore_user_request_ref_data(ur, NULL);
2197 hal = tcore_object_get_hal(obj);
2198 if (NULL == sendUmtsMsg || NULL == hal) {
2199 err("NULL input. Unable to proceed");
2200 dbg("sendUmtsMsg: [%p], hal: [%p]", sendUmtsMsg, hal);
2203 return TCORE_RETURN_EINVAL;
2206 if(FALSE == tcore_hal_get_power_state(hal)){
2207 dbg("cp not ready/n");
2208 return TCORE_RETURN_ENOSYS;
2211 dbg("msgLength: [%d]", sendUmtsMsg->msgDataPackage.msgLength);
2212 util_hex_dump(" ", (SMS_SMDATA_SIZE_MAX+1), (void *)sendUmtsMsg->msgDataPackage.tpduData);
2213 util_hex_dump(" ", SMS_SMSP_ADDRESS_LEN, (void *)sendUmtsMsg->msgDataPackage.sca);
2215 ScLength = (int)sendUmtsMsg->msgDataPackage.sca[0];
2217 dbg("ScLength: [%d]", ScLength);
2219 if ((sendUmtsMsg->msgDataPackage.msgLength > 0)
2220 && (sendUmtsMsg->msgDataPackage.msgLength <= SMS_SMDATA_SIZE_MAX)
2221 && (ScLength <= SMS_SCADDRESS_LEN_MAX)) {
2222 if (ScLength == 0) { // ScAddress not specified
2227 dbg("Specifying SCA in TPDU is currently not supported");
2234 util_byte_to_hex((const char *)sendUmtsMsg->msgDataPackage.tpduData, (char *)&buf[pdu_len], sendUmtsMsg->msgDataPackage.msgLength);
2236 pdu_len = pdu_len + 2*sendUmtsMsg->msgDataPackage.msgLength;
2238 buf[pdu_len] = '\0'; //Ensure termination
2240 dbg("pdu_len: [%d]", pdu_len);
2241 util_hex_dump(" ", sizeof(buf), (void *)buf);
2243 //AT+CMGS=<length><CR>PDU is given<ctrl-Z/ESC>
2244 cmd_str = g_strdup_printf("AT+CMGS=%d%s%s\x1A", sendUmtsMsg->msgDataPackage.msgLength,"\r",buf);
2245 atreq = tcore_at_request_new((const char *)cmd_str, "+CMGS", TCORE_AT_SINGLELINE);
2246 pending = tcore_pending_new(obj, 0);
2248 if (NULL == cmd_str || NULL == atreq || NULL == pending) {
2249 err("Out of memory. Unable to proceed");
2250 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
2252 //free memory we own
2254 util_sms_free_memory(atreq);
2255 util_sms_free_memory(pending);
2258 return TCORE_RETURN_ENOMEM;
2261 util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
2263 tcore_pending_set_request_data(pending, 0, atreq);
2264 tcore_pending_set_response_callback(pending, on_response_send_umts_msg, NULL);
2265 tcore_pending_link_user_request(pending, ur);
2266 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
2267 tcore_hal_send_request(hal, pending);
2272 return TCORE_RETURN_SUCCESS;
2275 err("Invalid Data len");
2277 return TCORE_RETURN_SMS_INVALID_DATA_LEN;
2280 static TReturn read_msg(CoreObject *obj, UserRequest *ur)
2282 gchar *cmd_str = NULL;
2283 TcoreHal *hal = NULL;
2284 TcoreATRequest *atreq = NULL;
2285 TcorePending *pending = NULL;
2286 const struct treq_sms_read_msg *readMsg = NULL;
2290 readMsg = tcore_user_request_ref_data(ur, NULL);
2291 hal = tcore_object_get_hal(obj);
2292 if (NULL == readMsg || NULL == hal) {
2293 err("NULL input. Unable to proceed");
2294 dbg("readMsg: [%p], hal: [%p]", readMsg, hal);
2297 return TCORE_RETURN_EINVAL;
2300 if(FALSE == tcore_hal_get_power_state(hal)){
2301 dbg("cp not ready/n");
2302 return TCORE_RETURN_ENOSYS;
2304 dbg("index: [%d]", readMsg->index);
2306 cmd_str = g_strdup_printf("AT+CMGR=%d", (readMsg->index + 1)); //IMC index is one ahead of TAPI
2307 atreq = tcore_at_request_new((const char *)cmd_str, "+CMGR", TCORE_AT_PDU);
2308 pending = tcore_pending_new(obj, 0);
2310 if (NULL == cmd_str || NULL == atreq || NULL == pending) {
2311 err("Out of memory. Unable to proceed");
2312 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
2314 //free memory we own
2316 util_sms_free_memory(atreq);
2317 util_sms_free_memory(pending);
2320 return TCORE_RETURN_ENOMEM;
2323 util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
2325 tcore_pending_set_request_data(pending, 0, atreq);
2326 tcore_pending_set_response_callback(pending, on_response_read_msg, (void *)(uintptr_t)(readMsg->index)); //storing index as user data for response
2327 tcore_pending_link_user_request(pending, ur);
2328 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
2329 tcore_hal_send_request(hal, pending);
2334 return TCORE_RETURN_SUCCESS;
2337 static TReturn save_msg(CoreObject *obj, UserRequest *ur)
2339 gchar *cmd_str = NULL;
2340 TcoreHal *hal = NULL;
2341 TcoreATRequest *atreq = NULL;
2342 TcorePending *pending = NULL;
2343 const struct treq_sms_save_msg *saveMsg = NULL;
2344 int ScLength = 0, pdu_len = 0, stat = 0;
2345 char buf[2*(SMS_SMSP_ADDRESS_LEN+SMS_SMDATA_SIZE_MAX)+1] = {0};
2346 char *hex_pdu = NULL;
2350 saveMsg = tcore_user_request_ref_data(ur, NULL);
2351 hal = tcore_object_get_hal(obj);
2352 if (NULL == saveMsg || NULL == hal) {
2353 err("NULL input. Unable to proceed");
2354 dbg("saveMsg: [%p], hal: [%p]", saveMsg, hal);
2357 return TCORE_RETURN_EINVAL;
2359 if(FALSE == tcore_hal_get_power_state(hal)){
2360 dbg("cp not ready/n");
2361 return TCORE_RETURN_ENOSYS;
2364 dbg("msgStatus: %x, msgLength: [%d]", saveMsg->msgStatus, saveMsg->msgDataPackage.msgLength);
2365 util_hex_dump(" ", (SMS_SMDATA_SIZE_MAX+1), (void *)saveMsg->msgDataPackage.tpduData);
2366 util_hex_dump(" ", SMS_SMSP_ADDRESS_LEN, (void *)saveMsg->msgDataPackage.sca);
2368 switch (saveMsg->msgStatus) {
2369 case SMS_STATUS_READ:
2373 case SMS_STATUS_UNREAD:
2374 stat = AT_REC_UNREAD;
2377 case SMS_STATUS_SENT:
2381 case SMS_STATUS_UNSENT:
2382 stat = AT_STO_UNSENT;
2386 err("Invalid msgStatus");
2388 return TCORE_RETURN_EINVAL;
2391 if ((saveMsg->msgDataPackage.msgLength > 0)
2392 && (saveMsg->msgDataPackage.msgLength <= SMS_SMDATA_SIZE_MAX)) {
2393 ScLength = (int)saveMsg->msgDataPackage.sca[0];
2396 dbg("ScLength = %d", ScLength);
2401 memcpy(&buf[1], saveMsg->msgDataPackage.sca, ScLength);
2404 memcpy(&buf[ScLength+1], saveMsg->msgDataPackage.tpduData, saveMsg->msgDataPackage.msgLength);
2406 pdu_len= saveMsg->msgDataPackage.msgLength + ScLength + 1;
2407 dbg("pdu_len: [%d]", pdu_len);
2409 hex_pdu = malloc(pdu_len * 2 + 1);
2410 util_hex_dump(" ", sizeof(buf), (void *)buf);
2412 memset (hex_pdu, 0x00, pdu_len * 2 + 1);
2414 util_byte_to_hex((const char *)buf, (char *)hex_pdu, pdu_len);
2416 //AT+CMGW=<length>[,<stat>]<CR>PDU is given<ctrl-Z/ESC>
2417 cmd_str = g_strdup_printf("AT+CMGW=%d,%d%s%s\x1A", saveMsg->msgDataPackage.msgLength, stat, "\r", hex_pdu);
2418 pending = tcore_pending_new(obj, 0);
2419 atreq = tcore_at_request_new((const char *)cmd_str, "+CMGW", TCORE_AT_SINGLELINE);
2421 if(NULL == cmd_str || NULL == atreq || NULL == pending) {
2422 err("Out of memory. Unable to proceed");
2423 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
2425 //free memory we own
2427 util_sms_free_memory(atreq);
2428 util_sms_free_memory(pending);
2429 util_sms_free_memory(hex_pdu);
2432 return TCORE_RETURN_ENOMEM;
2435 util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
2437 tcore_pending_set_request_data(pending, 0, atreq);
2438 tcore_pending_set_response_callback(pending, on_response_sms_save_msg, NULL);
2439 tcore_pending_link_user_request(pending, ur);
2440 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
2441 tcore_hal_send_request(hal, pending);
2447 return TCORE_RETURN_SUCCESS;
2450 err("Invalid Data len");
2452 return TCORE_RETURN_SMS_INVALID_DATA_LEN;
2455 static TReturn delete_msg(CoreObject *obj, UserRequest *ur)
2457 gchar *cmd_str = NULL;
2458 TcoreHal *hal = NULL;
2459 TcoreATRequest *atreq = NULL;
2460 TcorePending *pending = NULL;
2461 const struct treq_sms_delete_msg *delete_msg = NULL;
2465 delete_msg = tcore_user_request_ref_data(ur, NULL);
2466 hal = tcore_object_get_hal(obj);
2467 if (NULL == delete_msg || NULL == hal) {
2468 err("NULL input. Unable to proceed");
2469 dbg("deleteMsg: [%p], hal: [%p]", delete_msg, hal);
2472 return TCORE_RETURN_EINVAL;
2475 if(FALSE == tcore_hal_get_power_state(hal)){
2476 dbg("cp not ready/n");
2477 return TCORE_RETURN_ENOSYS;
2480 dbg("index: %d", delete_msg->index);
2482 if (delete_msg->index == -1) {
2483 cmd_str = g_strdup_printf("AT+CMGD=0,4"); // Delete All Messages
2485 cmd_str = g_strdup_printf("AT+CMGD=%d,0", delete_msg->index + 1); // Delete specified index
2488 pending = tcore_pending_new(obj, 0);
2489 atreq = tcore_at_request_new((const char *)cmd_str, NULL, TCORE_AT_NO_RESULT);
2490 if (NULL == cmd_str || NULL == atreq || NULL == pending) {
2491 err("Out of memory. Unable to proceed");
2492 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
2494 //free memory we own
2496 util_sms_free_memory(atreq);
2497 util_sms_free_memory(pending);
2500 return TCORE_RETURN_ENOMEM;
2503 util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
2505 tcore_pending_set_request_data(pending, 0, atreq);
2506 tcore_pending_set_response_callback(pending, on_response_sms_delete_msg, (void *) (uintptr_t) (delete_msg->index)); // storing index as user data for response
2507 tcore_pending_link_user_request(pending, ur);
2508 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
2509 tcore_hal_send_request(hal, pending);
2514 return TCORE_RETURN_SUCCESS;
2517 static TReturn get_storedMsgCnt(CoreObject *obj, UserRequest *ur)
2519 gchar *cmd_str = NULL;
2520 TcoreHal *hal = NULL;
2521 TcoreATRequest *atreq = NULL;
2522 TcorePending *pending = NULL;
2526 hal = tcore_object_get_hal(obj);
2528 err("NULL HAL. Unable to proceed");
2531 return TCORE_RETURN_EINVAL;
2534 if(FALSE == tcore_hal_get_power_state(hal)){
2535 dbg("cp not ready/n");
2536 return TCORE_RETURN_ENOSYS;
2539 cmd_str = g_strdup_printf("AT+CPMS=\"SM\"");
2540 pending = tcore_pending_new(obj, 0);
2541 atreq = tcore_at_request_new((const char *)cmd_str, "+CPMS", TCORE_AT_SINGLELINE);
2543 if (NULL == cmd_str || NULL == atreq || NULL == pending) {
2544 err("Out of memory. Unable to proceed");
2545 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
2547 //free memory we own
2549 util_sms_free_memory(atreq);
2550 util_sms_free_memory(pending);
2553 return TCORE_RETURN_ENOMEM;
2556 util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
2558 tcore_pending_set_request_data(pending, 0, atreq);
2559 tcore_pending_set_response_callback(pending, on_response_get_stored_msg_cnt, NULL);
2560 tcore_pending_link_user_request(pending, ur);
2561 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
2562 tcore_hal_send_request(hal, pending);
2567 return TCORE_RETURN_SUCCESS;
2570 static TReturn get_sca(CoreObject *obj, UserRequest *ur)
2572 gchar * cmd_str = NULL;
2573 TcoreHal *hal = NULL;
2574 TcoreATRequest *atreq = NULL;
2575 TcorePending *pending = NULL;
2579 hal = tcore_object_get_hal(obj);
2581 err("HAL NULL. Unable to proceed");
2584 return TCORE_RETURN_EINVAL;
2586 if(FALSE == tcore_hal_get_power_state(hal)){
2587 dbg("cp not ready/n");
2588 return TCORE_RETURN_ENOSYS;
2591 cmd_str = g_strdup_printf("AT+CSCA?");
2592 pending = tcore_pending_new(obj, 0);
2593 atreq = tcore_at_request_new((const char *)cmd_str, "+CSCA", TCORE_AT_SINGLELINE);
2595 if (NULL == cmd_str || NULL == atreq || NULL == pending) {
2596 err("Out of memory. Unable to proceed");
2597 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
2599 //free memory we own
2601 util_sms_free_memory(atreq);
2602 util_sms_free_memory(pending);
2605 return TCORE_RETURN_ENOMEM;
2608 util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
2610 tcore_pending_set_request_data(pending, 0, atreq);
2611 tcore_pending_set_response_callback(pending, on_response_get_sca, NULL);
2612 tcore_pending_link_user_request(pending, ur);
2613 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
2614 tcore_hal_send_request(hal, pending);
2619 return TCORE_RETURN_SUCCESS;
2622 static TReturn set_sca(CoreObject *obj, UserRequest *ur)
2624 gchar *cmd_str = NULL;
2625 TcoreHal *hal = NULL;
2626 TcoreATRequest *atreq = NULL;
2627 TcorePending *pending = NULL;
2628 const struct treq_sms_set_sca *setSca = NULL;
2633 setSca = tcore_user_request_ref_data(ur, NULL);
2634 hal = tcore_object_get_hal(obj);
2635 if (NULL == setSca || NULL == hal) {
2636 err("NULL input. Unable to proceed");
2637 dbg("setSca: [%p], hal: [%p]", setSca, hal);
2640 return TCORE_RETURN_EINVAL;
2642 if(FALSE == tcore_hal_get_power_state(hal)){
2643 dbg("cp not ready/n");
2644 return TCORE_RETURN_ENOSYS;
2647 dbg("dialNumLen: %u, typeOfNum: %d, numPlanId: %d, ", setSca->scaInfo.dialNumLen, setSca->scaInfo.typeOfNum, setSca->scaInfo.numPlanId);
2649 util_hex_dump(" ", (SMS_SMSP_ADDRESS_LEN+1), (void *)setSca->scaInfo.diallingNum);
2651 addrType = ((setSca->scaInfo.typeOfNum << 4) | setSca->scaInfo.numPlanId) | 0x80;
2653 cmd_str = g_strdup_printf("AT+CSCA=\"%s\",%d", setSca->scaInfo.diallingNum, addrType);
2654 pending = tcore_pending_new(obj, 0);
2655 atreq = tcore_at_request_new((const char *)cmd_str, NULL, TCORE_AT_NO_RESULT);
2657 if (NULL == cmd_str || NULL == atreq || NULL == pending) {
2658 err("Out of memory. Unable to proceed");
2659 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
2661 //free memory we own
2663 util_sms_free_memory(atreq);
2664 util_sms_free_memory(pending);
2667 return TCORE_RETURN_ENOMEM;
2670 util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
2672 tcore_pending_set_request_data(pending, 0, atreq);
2673 tcore_pending_set_response_callback(pending, on_response_set_sca, NULL);
2674 tcore_pending_link_user_request(pending, ur);
2675 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
2676 tcore_hal_send_request(hal, pending);
2681 return TCORE_RETURN_SUCCESS;
2684 static TReturn get_cb_config(CoreObject *obj, UserRequest *ur)
2686 gchar *cmd_str = NULL;
2687 TcoreHal *hal = NULL;
2688 TcoreATRequest *atreq = NULL;
2689 TcorePending *pending = NULL;
2693 hal = tcore_object_get_hal(obj);
2695 err("NULL HAL. Unable to proceed");
2698 return TCORE_RETURN_EINVAL;
2700 if(FALSE == tcore_hal_get_power_state(hal)){
2701 dbg("cp not ready/n");
2702 return TCORE_RETURN_ENOSYS;
2705 cmd_str = g_strdup_printf("AT+CSCB?");
2706 pending = tcore_pending_new(obj, 0);
2707 atreq = tcore_at_request_new((const char *)cmd_str, "+CSCB", TCORE_AT_SINGLELINE);
2708 if (NULL == cmd_str || NULL == atreq || NULL == pending) {
2709 err("Out of memory. Unable to proceed");
2710 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
2712 //free memory we own
2714 util_sms_free_memory(atreq);
2715 util_sms_free_memory(pending);
2718 return TCORE_RETURN_ENOMEM;
2721 util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
2723 tcore_pending_set_request_data(pending, 0, atreq);
2724 tcore_pending_set_response_callback(pending, on_response_get_cb_config, NULL);
2725 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
2726 tcore_pending_link_user_request(pending, ur);
2727 tcore_hal_send_request(hal, pending);
2732 return TCORE_RETURN_SUCCESS;
2735 static TReturn set_cb_config(CoreObject *obj, UserRequest *ur)
2737 gchar *cmd_str = NULL;
2738 gchar *mids_str = NULL;
2739 GString *mids_GString = NULL;
2741 TcoreHal *hal = NULL;
2742 TcoreATRequest *atreq = NULL;
2743 TcorePending *pending = NULL;
2744 const struct treq_sms_set_cb_config *setCbConfig = NULL;
2745 int ctr1= 0, ctr2 =0;
2746 unsigned short appendMsgId = 0;
2750 setCbConfig = tcore_user_request_ref_data(ur, NULL);
2751 hal = tcore_object_get_hal(obj);
2752 if (NULL == setCbConfig || NULL == hal) {
2753 err("NULL input. Unable to proceed");
2754 dbg("setCbConfig: [%p], hal: [%p]", setCbConfig, hal);
2757 return TCORE_RETURN_EINVAL;
2759 if(FALSE == tcore_hal_get_power_state(hal)){
2760 dbg("cp not ready/n");
2761 return TCORE_RETURN_ENOSYS;
2764 dbg("bCBEnabled: %d, msgIdCount: %d", setCbConfig->cbEnabled, setCbConfig->msgIdRangeCount);
2766 if (setCbConfig->cbEnabled == 2) { //Enable all CBS
2767 cmd_str = g_strdup_printf("AT+CSCB=1");
2768 } else if ((setCbConfig->cbEnabled == 1) && (setCbConfig->msgIdRangeCount == 0)) { // Special case: Enable all CBS
2769 cmd_str = g_strdup_printf("AT+CSCB=1");
2770 } else if (setCbConfig->cbEnabled == 0) {//AT+CSCB=0: Disable CBS
2771 cmd_str = g_strdup_printf("AT+CSCB=0");
2773 mids_GString = g_string_new("AT+CSCB=0,\"");
2775 for(ctr1 = 0; ctr1 < setCbConfig->msgIdRangeCount; ctr1++ ) {
2776 if( setCbConfig->msgIDs[ctr1].net3gpp.selected == FALSE )
2779 if( SMS_GSM_SMS_CBMI_LIST_SIZE_MAX <= (setCbConfig->msgIDs[ctr1].net3gpp.toMsgId - setCbConfig->msgIDs[ctr1].net3gpp.fromMsgId) ) {
2780 mids_GString = g_string_new("AT+CSCB=1");
2784 appendMsgId = setCbConfig->msgIDs[ctr1].net3gpp.fromMsgId;
2786 for( ctr2 = 0; (ctr2 <= ((setCbConfig->msgIDs[ctr1].net3gpp.toMsgId) - (setCbConfig->msgIDs[ctr1].net3gpp.fromMsgId))); ctr2++ ) {
2787 dbg( "%x", appendMsgId);
2788 mids_GString = g_string_append(mids_GString, g_strdup_printf("%d", appendMsgId));
2790 if (ctr2 == ((setCbConfig->msgIDs[ctr1].net3gpp.toMsgId) - (setCbConfig->msgIDs[ctr1].net3gpp.fromMsgId))) {
2791 mids_GString = g_string_append(mids_GString, "\""); //Mids string termination
2793 mids_GString = g_string_append(mids_GString, ",");
2799 mids_str = g_string_free(mids_GString, FALSE);
2800 cmd_str = g_strdup_printf("%s", mids_str);
2804 pending = tcore_pending_new(obj, 0);
2805 atreq = tcore_at_request_new((const char *)cmd_str, NULL, TCORE_AT_NO_RESULT);
2806 if(NULL == cmd_str || NULL == atreq || NULL == pending) {
2807 err("Out of memory. Unable to proceed");
2808 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
2810 //free memory we own
2812 util_sms_free_memory(atreq);
2813 util_sms_free_memory(pending);
2816 return TCORE_RETURN_ENOMEM;
2819 util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
2821 tcore_pending_set_request_data(pending, 0, atreq);
2822 tcore_pending_set_response_callback(pending, on_response_set_cb_config, NULL);
2823 tcore_pending_link_user_request(pending, ur);
2824 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
2825 tcore_hal_send_request(hal, pending);
2830 return TCORE_RETURN_SUCCESS;
2833 static TReturn set_mem_status(CoreObject *obj, UserRequest *ur)
2835 gchar *cmd_str = NULL;
2836 TcoreHal *hal = NULL;
2837 TcoreATRequest *atreq = NULL;
2838 TcorePending *pending = NULL;
2839 const struct treq_sms_set_mem_status *setMemStatus = NULL;
2840 int memoryStatus = 0;
2844 setMemStatus = tcore_user_request_ref_data(ur, NULL);
2845 hal = tcore_object_get_hal(obj);
2846 if (NULL == setMemStatus || NULL == hal) {
2847 err("NULL input. Unable to proceed");
2848 dbg("setMemStatus: [%p], hal: [%p]", setMemStatus, hal);
2851 return TCORE_RETURN_EINVAL;
2853 if(FALSE == tcore_hal_get_power_state(hal)){
2854 dbg("cp not ready/n");
2855 return TCORE_RETURN_ENOSYS;
2858 dbg("memory_status: %d", setMemStatus->memory_status);
2860 if(setMemStatus->memory_status < SMS_PDA_MEMORY_STATUS_AVAILABLE
2861 || setMemStatus->memory_status > SMS_PDA_MEMORY_STATUS_FULL) {
2862 err("Invalid memory_status");
2865 return TCORE_RETURN_EINVAL;
2868 switch (setMemStatus->memory_status) {
2869 case SMS_PDA_MEMORY_STATUS_AVAILABLE:
2870 memoryStatus = AT_MEMORY_AVAILABLE;
2873 case SMS_PDA_MEMORY_STATUS_FULL:
2874 memoryStatus = AT_MEMORY_FULL;
2878 err("Invalid memory_status");
2880 return TCORE_RETURN_EINVAL;
2883 cmd_str = g_strdup_printf("AT+XTESM=%d", memoryStatus);
2884 pending = tcore_pending_new(obj, 0);
2885 atreq = tcore_at_request_new((const char *)cmd_str, NULL, TCORE_AT_NO_RESULT);
2887 if (NULL == cmd_str || NULL == atreq || NULL == pending) {
2888 err("Out of memory. Unable to proceed");
2889 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
2891 //free memory we own
2893 util_sms_free_memory(atreq);
2894 util_sms_free_memory(pending);
2897 return TCORE_RETURN_ENOMEM;
2900 util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
2902 tcore_pending_set_request_data(pending, 0, atreq);
2903 tcore_pending_set_response_callback(pending, on_response_set_mem_status, NULL);
2904 tcore_pending_link_user_request(pending, ur);
2905 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
2906 tcore_hal_send_request(hal, pending);
2911 return TCORE_RETURN_SUCCESS;
2914 static TReturn set_delivery_report(CoreObject *obj, UserRequest *ur)
2916 struct tresp_sms_set_delivery_report respSetDeliveryReport = {0,};
2918 respSetDeliveryReport.result = SMS_SUCCESS;
2921 if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(obj))){
2922 dbg("cp not ready/n");
2923 return TCORE_RETURN_ENOSYS;
2926 dbg("CP takes care of sending SMS ack to network for all classes of SMS. Sending default success.");
2928 tcore_user_request_send_response(ur, TRESP_SMS_SET_DELIVERY_REPORT, sizeof(struct tresp_sms_set_delivery_report), &respSetDeliveryReport);
2931 return TCORE_RETURN_SUCCESS;
2934 static TReturn set_msg_status(CoreObject *obj, UserRequest *ur)
2936 gchar *cmd_str = NULL;
2937 TcoreHal *hal = NULL;
2938 TcoreATRequest *atreq = NULL;
2939 TcorePending *pending = NULL;
2940 const struct treq_sms_set_msg_status *msg_status = NULL;
2943 hal = tcore_object_get_hal(obj);
2944 if(FALSE == tcore_hal_get_power_state(hal)){
2945 dbg("cp not ready/n");
2946 return TCORE_RETURN_ENOSYS;
2948 msg_status = tcore_user_request_ref_data(ur, NULL);
2950 cmd_str = g_strdup_printf("AT+CRSM=178,28476,%d,4,%d", (msg_status->index+1), AT_EF_SMS_RECORD_LEN);
2951 atreq = tcore_at_request_new((const char *)cmd_str, "+CRSM", TCORE_AT_SINGLELINE);
2952 pending = tcore_pending_new(obj, 0);
2953 if (NULL == cmd_str || NULL == atreq || NULL == pending) {
2954 err("Out of memory. Unable to proceed");
2955 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
2957 //free memory we own
2959 util_sms_free_memory(atreq);
2960 util_sms_free_memory(pending);
2963 return TCORE_RETURN_ENOMEM;
2966 util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
2968 tcore_pending_set_request_data(pending, 0, atreq);
2969 tcore_pending_set_response_callback(pending, _response_get_efsms_data, NULL);
2970 tcore_pending_link_user_request(pending, ur);
2971 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
2972 tcore_hal_send_request(hal, pending);
2977 return TCORE_RETURN_SUCCESS;
2980 static TReturn get_sms_params(CoreObject *obj, UserRequest *ur)
2982 gchar *cmd_str = NULL;
2983 TcoreHal *hal = NULL;
2984 TcoreATRequest *atreq = NULL;
2985 TcorePending *pending = NULL;
2986 const struct treq_sms_get_params *getSmsParams = NULL;
2987 int record_len = 0 , *smsp_record_len = NULL;
2991 getSmsParams = tcore_user_request_ref_data(ur, NULL);
2992 hal = tcore_object_get_hal(obj);
2993 if (NULL == getSmsParams || NULL == hal) {
2994 err("NULL input. Unable to proceed");
2995 dbg("getSmsParams: [%p], hal: [%p]", getSmsParams, hal);
2998 return TCORE_RETURN_EINVAL;
3000 if(FALSE == tcore_hal_get_power_state(hal)){
3001 dbg("cp not ready/n");
3002 return TCORE_RETURN_ENOSYS;
3005 smsp_record_len = tcore_plugin_ref_property(tcore_object_ref_plugin(obj), "SMSPRECORDLEN");
3006 record_len = *smsp_record_len;
3007 dbg("record len from property %d", record_len);
3009 //AT+CRSM=command>[,<fileid>[,<P1>,<P2>,<P3>[,<data>[,<pathid>]]]]
3010 cmd_str = g_strdup_printf("AT+CRSM=178,28482,%d,4,%d", (getSmsParams->index + 1), record_len);
3012 dbg("cmd_str is %s",cmd_str);
3014 atreq = tcore_at_request_new((const char *)cmd_str, "+CRSM", TCORE_AT_SINGLELINE);
3015 pending = tcore_pending_new(obj, 0);
3016 if (NULL == cmd_str || NULL == atreq || NULL == pending) {
3017 err("Out of memory. Unable to proceed");
3018 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
3020 //free memory we own
3022 util_sms_free_memory(atreq);
3023 util_sms_free_memory(pending);
3026 return TCORE_RETURN_ENOMEM;
3029 util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
3031 tcore_pending_set_request_data(pending, 0, atreq);
3032 tcore_pending_set_response_callback(pending, on_response_get_sms_params, NULL);
3033 tcore_pending_link_user_request(pending, ur);
3034 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
3035 tcore_hal_send_request(hal, pending);
3040 return TCORE_RETURN_SUCCESS;
3043 static TReturn set_sms_params(CoreObject *obj, UserRequest *ur)
3045 gchar *cmd_str = NULL;
3046 char *encoded_data = NULL;
3047 unsigned char *temp_data = NULL;
3048 int SMSPRecordLen = 0;
3050 TcoreHal *hal = NULL;
3051 TcoreATRequest *atreq = NULL;
3052 TcorePending *pending = NULL;
3053 const struct treq_sms_set_params *setSmsParams = NULL;
3054 int encoded_data_len = 0;
3058 setSmsParams = tcore_user_request_ref_data(ur, NULL);
3059 hal = tcore_object_get_hal(obj);
3060 if (NULL == setSmsParams || NULL == hal) {
3061 err("NULL input. Unable to proceed");
3062 dbg("setSmsParams: [%p], hal: [%p]", setSmsParams, hal);
3065 if(FALSE == tcore_hal_get_power_state(hal)){
3066 dbg("cp not ready/n");
3067 return TCORE_RETURN_ENOSYS;
3070 //EFsmsp file size is 28 +Y bytes (Y is alpha id size)
3071 SMSPRecordLen = 28 + setSmsParams->params.alphaIdLen;
3072 temp_data = calloc(SMSPRecordLen,1);
3073 encoded_data = calloc(SMSPRecordLen*2 + 1,1);
3075 _tcore_util_sms_encode_smsParameters(&(setSmsParams->params), temp_data, SMSPRecordLen);
3077 util_byte_to_hex((const char *)temp_data, (char *)encoded_data,SMSPRecordLen);
3079 encoded_data_len = ((SMSPRecordLen) * 2);
3081 hal = tcore_object_get_hal(obj);
3082 pending = tcore_pending_new(obj, 0);
3084 dbg("alpha id len %d encoded data %s. Encoded data len %d",setSmsParams->params.alphaIdLen,encoded_data, encoded_data_len);
3085 cmd_str = g_strdup_printf("AT+CRSM=220,28482,%d,4,%d,\"%s\"",(setSmsParams->params.recordIndex+1),SMSPRecordLen,encoded_data);
3087 dbg("cmd str is %s",cmd_str);
3088 atreq = tcore_at_request_new(cmd_str, "+CRSM:", TCORE_AT_SINGLELINE);
3090 if (NULL == cmd_str || NULL == atreq || NULL == pending) {
3091 err("Out of memory. Unable to proceed");
3092 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
3094 //free memory we own
3096 util_sms_free_memory(atreq);
3097 util_sms_free_memory(pending);
3099 util_sms_free_memory(temp_data);
3100 util_sms_free_memory(encoded_data);
3103 return TCORE_RETURN_ENOMEM;
3106 util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
3108 tcore_pending_set_request_data(pending, 0,atreq);
3109 tcore_pending_set_response_callback(pending, on_response_set_sms_params, NULL);
3110 tcore_pending_link_user_request(pending, ur);
3111 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
3112 tcore_hal_send_request(hal, pending);
3115 util_sms_free_memory(temp_data);
3116 util_sms_free_memory(encoded_data);
3118 return TCORE_RETURN_SUCCESS;
3121 static TReturn get_paramcnt(CoreObject *obj, UserRequest *ur)
3123 gchar *cmd_str = NULL;
3124 TcoreHal *hal = NULL;
3125 TcoreATRequest *atreq = NULL;
3126 TcorePending *pending = NULL;
3130 hal = tcore_object_get_hal(obj);
3132 err("NULL HAL. Unable to proceed");
3135 return TCORE_RETURN_EINVAL;
3137 if(FALSE == tcore_hal_get_power_state(hal)){
3138 dbg("cp not ready/n");
3139 return TCORE_RETURN_ENOSYS;
3142 //AT+CRSM=command>[,<fileid>[,<P1>,<P2>,<P3>[,<data>[,<pathid>]]]]
3143 cmd_str = g_strdup_printf("AT+CRSM=192,28482");
3144 atreq = tcore_at_request_new((const char *)cmd_str, "+CRSM", TCORE_AT_SINGLELINE);
3145 pending = tcore_pending_new(obj, 0);
3147 if (NULL == cmd_str || NULL == atreq || NULL == pending) {
3148 err("NULL pointer. Unable to proceed");
3149 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
3151 //free memory we own
3153 util_sms_free_memory(atreq);
3154 util_sms_free_memory(pending);
3157 return TCORE_RETURN_FAILURE;
3160 util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
3162 tcore_pending_set_request_data(pending, 0, atreq);
3163 tcore_pending_set_response_callback(pending, on_response_get_paramcnt, NULL);
3164 tcore_pending_link_user_request(pending, ur);
3165 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
3166 tcore_hal_send_request(hal, pending);
3171 return TCORE_RETURN_SUCCESS;
3174 static struct tcore_sms_operations sms_ops = {
3175 .send_umts_msg = send_umts_msg,
3176 .read_msg = read_msg,
3177 .save_msg = save_msg,
3178 .delete_msg = delete_msg,
3179 .get_storedMsgCnt = get_storedMsgCnt,
3182 .get_cb_config = get_cb_config,
3183 .set_cb_config = set_cb_config,
3184 .set_mem_status = set_mem_status,
3185 .get_pref_brearer = NULL,
3186 .set_pref_brearer = NULL,
3187 .set_delivery_report = set_delivery_report,
3188 .set_msg_status = set_msg_status,
3189 .get_sms_params = get_sms_params,
3190 .set_sms_params = set_sms_params,
3191 .get_paramcnt = get_paramcnt,
3194 gboolean s_sms_init(TcorePlugin *plugin, TcoreHal *hal)
3196 CoreObject *obj = NULL;
3197 struct property_sms_info *data = NULL;
3198 GQueue *work_queue = NULL;
3199 int *smsp_record_len = NULL;
3202 dbg("plugin: [%p]", plugin);
3203 dbg("hal: [%p]", hal);
3205 obj = tcore_sms_new(plugin, "umts_sms", &sms_ops, hal);
3207 data = calloc(sizeof(struct property_sms_info), 1);
3209 if (NULL == obj || NULL == data) {
3210 err("Unable to initialize. Exiting");
3217 work_queue = g_queue_new();
3218 tcore_object_link_user_data(obj, work_queue);
3220 //Registering for SMS notifications
3221 tcore_object_add_callback(obj, "\e+CMTI", on_event_class2_sms_incom_msg, NULL);
3222 tcore_object_add_callback(obj, "\e+CMT", on_event_sms_incom_msg, NULL);
3224 tcore_object_add_callback(obj, "\e+CDS", on_event_sms_incom_msg, NULL);
3225 tcore_object_add_callback(obj, "+XSMSMMSTAT", on_event_sms_memory_status, NULL);
3226 tcore_object_add_callback(obj, "+CMS", on_event_sms_memory_status, NULL);
3228 tcore_object_add_callback(obj, "\e+CBMI", on_event_sms_cb_incom_msg, NULL);
3229 tcore_object_add_callback(obj, "\e+CBM", on_event_sms_cb_incom_msg, NULL);
3230 tcore_object_add_callback(obj, "+XSIM", on_event_sms_ready_status, NULL);
3232 tcore_plugin_link_property(plugin, "SMS", data);
3234 //storing smsp record length
3235 smsp_record_len = calloc(sizeof(int), 1);
3236 tcore_plugin_link_property(plugin, "SMSPRECORDLEN", smsp_record_len);
3242 void s_sms_exit(TcorePlugin *plugin)
3244 CoreObject *obj = NULL;
3245 struct property_sms_info *data = NULL;
3248 dbg("plugin: [%p]", plugin);
3250 obj = tcore_plugin_ref_core_object(plugin, "umts_sms");
3252 err("NULL core object. Nothing to do.");
3255 tcore_sms_free(obj);
3257 data = tcore_plugin_ref_property(plugin, "SMS");
3258 util_sms_free_memory(data);