4 * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Madhavi Akella <madhavi.a@samsung.com>
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
30 #include <core_object.h>
35 #include <user_request.h>
43 #include "common/TelErr.h"
47 /*=============================================================
49 ==============================================================*/
50 #define MAX_GSM_SMS_TPDU_SIZE 244
51 #define MAX_GSM_SMS_MSG_NUM 255
52 #define MAX_GSM_SMS_SERVICE_CENTER_ADDR 12 /* Maximum number of bytes of service center address */
53 #define MAX_GSM_SMS_CBMI_LIST_SIZE 100 /* Maximum number of CBMI list size for CBS 30*2=60 */
54 #define MAX_GSM_SMS_PARAM_RECORD_SIZE 156 /* Maximum number of bytes SMSP Record size (Y + 28), y : 0 ~ 128 */
55 #define MAX_GSM_SMS_STATUS_FILE_SIZE 2 /* Last Used TP-MR + SMS "Memory Cap. Exceeded" Noti Flag */
56 #define TAPI_SIM_SMSP_ADDRESS_LEN 20
58 /*=============================================================
60 ==============================================================*/
61 #define SMS_DEVICE_READY 1 /* Telephony device ready */
62 #define SMS_DEVICE_NOT_READY 0 /* Telephony device not ready */
64 /*=============================================================
66 ==============================================================*/
67 #define SMS_CBMI_SELECTED_SOME 0x02 /* Some CBMIs are selected */
68 #define SMS_CBMI_SELECTED_ALL 0x01 /* All CBMIs are selected */
70 /*=============================================================
72 ==============================================================*/
73 #define AT_REC_UNREAD 0 /* Received and Unread */
74 #define AT_REC_READ 1 /* Received and Read */
75 #define AT_STO_UNSENT 2 /* Unsent */
76 #define AT_STO_SENT 3 /* Sent */
77 #define AT_ALL 4 /* Unknown */
79 /*=============================================================
81 ==============================================================*/
82 #define AT_MEMORY_AVAILABLE 0 /* Memory Available */
83 #define AT_MEMORY_FULL 1 /* Memory Full */
85 /*=============================================================
86 SIM CRSM SW1 and Sw2 Error definitions */
88 #define AT_SW1_SUCCESS 0x90
89 #define AT_SW2_SUCCESS 0
90 #define AT_SW1_LEN_RESP 0x9F
92 #define AT_MAX_RECORD_LEN 256
93 /* SCA 12 bytes long and TDPU is 164 bytes long */
94 #define PDU_LEN_MAX 176
95 #define HEX_PDU_LEN_MAX ((PDU_LEN_MAX * 2) + 1)
97 /*=============================================================
99 ==============================================================*/
100 #define CR '\r' /* Carriage Return */
102 /*=============================================================
104 ==============================================================*/
105 #define SMS_SWAPBYTES16(x) (((x) & 0xffff0000) | (((x) & 0x0000ff00) >> 8) | (((x) & 0x000000ff) << 8))
107 void print_glib_list_elem(gpointer data, gpointer user_data);
109 static void on_response_class2_read_msg(TcorePending *pending, int data_len, const void *data, void *user_data);
112 gboolean util_byte_to_hex(const char *byte_pdu, char *hex_pdu, int num_bytes);
114 void print_glib_list_elem(gpointer data, gpointer user_data)
116 char *item = (char *)data;
118 dbg("item: [%s]", item);
121 /*=============================================================
123 ==============================================================*/
124 static void on_confirmation_sms_message_send(TcorePending *p, gboolean result, void *user_data)
126 dbg("Entered Function. Request message out from queue");
128 dbg("TcorePending: [%p]", p);
129 dbg("result: [%02x]", result);
130 dbg("user_data: [%p]", user_data);
132 if (result == TRUE) {
134 } else { /* Failed */
138 dbg("Exiting Function. Nothing to return");
141 /*=============================================================
143 ==============================================================*/
144 static void util_sms_free_memory(void *sms_ptr)
148 if (NULL != sms_ptr) {
149 dbg("Freeing memory location: [%p]", sms_ptr);
153 err("Invalid memory location. Nothing to do.");
160 static int util_sms_decode_smsParameters(unsigned char *incoming, unsigned int length, struct telephony_sms_Params *params)
162 int alpha_id_len = 0;
166 dbg(" RecordLen = %d", length);
168 if(incoming == NULL || params == NULL)
171 alpha_id_len = length -SMS_SMSP_PARAMS_MAX_LEN;
173 if (alpha_id_len > 0) {
174 if (alpha_id_len > SMS_SMSP_ALPHA_ID_LEN_MAX) {
175 alpha_id_len = SMS_SMSP_ALPHA_ID_LEN_MAX;
178 for (i = 0; i < alpha_id_len; i++) {
179 if (0xff == incoming[i]) {
185 memcpy(params->szAlphaId, incoming, i);
187 params->alphaIdLen = i;
189 dbg(" Alpha id length = %d", i);
191 params->alphaIdLen = 0;
192 dbg(" Alpha id length is zero");
195 params->paramIndicator = incoming[alpha_id_len];
197 dbg(" Param Indicator = %02x", params->paramIndicator);
199 if ((params->paramIndicator & SMSPValidDestAddr) == 0) {
200 nOffset = nDestAddrOffset;
202 if (0x00 == incoming[alpha_id_len + nOffset] || 0xff == incoming[alpha_id_len + nOffset]) {
203 params->tpDestAddr.dialNumLen = 0;
205 dbg("DestAddr Length is 0");
207 if (0 < (int) incoming[alpha_id_len + nOffset]) {
208 params->tpDestAddr.dialNumLen = (int) (incoming[alpha_id_len + nOffset] - 1);
210 if (params->tpDestAddr.dialNumLen > SMS_SMSP_ADDRESS_LEN)
211 params->tpDestAddr.dialNumLen = SMS_SMSP_ADDRESS_LEN;
213 params->tpDestAddr.dialNumLen = 0;
216 params->tpDestAddr.numPlanId = incoming[alpha_id_len + (++nOffset)] & 0x0f;
217 params->tpDestAddr.typeOfNum = (incoming[alpha_id_len + nOffset] & 0x70) >> 4;
219 memcpy(params->tpDestAddr.diallingNum, &incoming[alpha_id_len + (++nOffset)], (params->tpDestAddr.dialNumLen));
221 dbg("Dest TON is %d", params->tpDestAddr.typeOfNum);
222 dbg("Dest NPI is %d", params->tpDestAddr.numPlanId);
223 dbg("Dest Length = %d", params->tpDestAddr.dialNumLen);
224 dbg("Dest Addr = %s", params->tpDestAddr.diallingNum);
227 params->tpDestAddr.dialNumLen = 0;
230 if ((params->paramIndicator & SMSPValidSvcAddr) == 0) {
231 nOffset = nSCAAddrOffset;
233 if (0x00 == (int) incoming[alpha_id_len + nOffset] || 0xff == (int) incoming[alpha_id_len + nOffset]) {
234 params->tpSvcCntrAddr.dialNumLen = 0;
236 dbg(" SCAddr Length is 0");
238 if (0 < (int) incoming[alpha_id_len + nOffset]) {
239 params->tpSvcCntrAddr.dialNumLen = (int) (incoming[alpha_id_len + nOffset] - 1);
241 if (params->tpSvcCntrAddr.dialNumLen > SMS_SMSP_ADDRESS_LEN)
242 params->tpSvcCntrAddr.dialNumLen = SMS_SMSP_ADDRESS_LEN;
244 params->tpSvcCntrAddr.numPlanId = incoming[alpha_id_len + (++nOffset)] & 0x0f;
245 params->tpSvcCntrAddr.typeOfNum = (incoming[alpha_id_len + nOffset] & 0x70) >> 4;
247 memcpy(params->tpSvcCntrAddr.diallingNum, &incoming[alpha_id_len + (++nOffset)], (params->tpSvcCntrAddr.dialNumLen));
249 dbg("SCAddr Length = %d ", params->tpSvcCntrAddr.dialNumLen);
250 dbg("SCAddr TON is %d", params->tpSvcCntrAddr.typeOfNum);
251 dbg("SCAddr NPI is %d", params->tpSvcCntrAddr.numPlanId);
253 for (i = 0; i < (int) params->tpSvcCntrAddr.dialNumLen; i++)
254 dbg("SCAddr = %d [%02x]", i, params->tpSvcCntrAddr.diallingNum[i]);
256 params->tpSvcCntrAddr.dialNumLen = 0;
259 } else if ((0x00 < (int) incoming[alpha_id_len + nSCAAddrOffset] && (int) incoming[alpha_id_len + nSCAAddrOffset] <= 12)
260 || 0xff != (int) incoming[alpha_id_len + nSCAAddrOffset]) {
261 nOffset = nSCAAddrOffset;
263 if (0x00 == (int) incoming[alpha_id_len + nOffset] || 0xff == (int) incoming[alpha_id_len + nOffset]) {
264 params->tpSvcCntrAddr.dialNumLen = 0;
265 dbg("SCAddr Length is 0");
267 if (0 < (int) incoming[alpha_id_len + nOffset]) {
268 params->tpSvcCntrAddr.dialNumLen = (int) (incoming[alpha_id_len + nOffset] - 1);
270 params->tpSvcCntrAddr.dialNumLen = incoming[alpha_id_len + nOffset] - 1;
272 if (params->tpSvcCntrAddr.dialNumLen > SMS_SMSP_ADDRESS_LEN)
273 params->tpSvcCntrAddr.dialNumLen = SMS_SMSP_ADDRESS_LEN;
275 params->tpSvcCntrAddr.numPlanId = incoming[alpha_id_len + (++nOffset)] & 0x0f;
276 params->tpSvcCntrAddr.typeOfNum = (incoming[alpha_id_len + nOffset] & 0x70) >> 4;
278 memcpy(params->tpSvcCntrAddr.diallingNum, &incoming[alpha_id_len + (++nOffset)],
279 (params->tpSvcCntrAddr.dialNumLen));
281 dbg("SCAddr Length = %d ", params->tpSvcCntrAddr.dialNumLen);
282 dbg("SCAddr TON is %d", params->tpSvcCntrAddr.typeOfNum);
283 dbg("SCAddr NPI is %d", params->tpSvcCntrAddr.numPlanId);
285 for (i = 0; i < (int) params->tpSvcCntrAddr.dialNumLen; i++)
286 dbg("SCAddr = %d [%02x]", i, params->tpSvcCntrAddr.diallingNum[i]);
288 params->tpSvcCntrAddr.dialNumLen = 0;
292 params->tpSvcCntrAddr.dialNumLen = 0;
295 if ((params->paramIndicator & SMSPValidPID) == 0 && (alpha_id_len + nPIDOffset) < MAX_GSM_SMS_PARAM_RECORD_SIZE) {
296 params->tpProtocolId = incoming[alpha_id_len + nPIDOffset];
298 if ((params->paramIndicator & SMSPValidDCS) == 0 && (alpha_id_len + nDCSOffset) < MAX_GSM_SMS_PARAM_RECORD_SIZE) {
299 params->tpDataCodingScheme = incoming[alpha_id_len + nDCSOffset];
301 if ((params->paramIndicator & SMSPValidVP) == 0 && (alpha_id_len + nVPOffset) < MAX_GSM_SMS_PARAM_RECORD_SIZE) {
302 params->tpValidityPeriod = incoming[alpha_id_len + nVPOffset];
305 dbg(" Alpha Id(Len) = %d", (int) params->alphaIdLen);
307 for (i = 0; i < (int) params->alphaIdLen; i++) {
308 dbg(" Alpha Id = [%d] [%c]", i, params->szAlphaId[i]);
310 dbg(" PID = %d",params->tpProtocolId);
311 dbg(" DCS = %d",params->tpDataCodingScheme);
312 dbg(" VP = %d",params->tpValidityPeriod);
317 /*=============================================================
319 ==============================================================*/
320 static gboolean on_event_class2_sms_incom_msg(CoreObject *obj,
321 const void *event_info, void *user_data)
323 //+CMTI: <mem>,<index>
325 GSList *tokens = NULL , *lines = NULL;
326 char *line = NULL, *cmd_str = NULL;
327 int index = 0, mem_type = 0;
328 TcoreHal *hal = NULL;
329 TcoreATRequest *atreq = NULL;
330 TcorePending *pending = NULL;
332 dbg("Entered Function");
334 lines = (GSList *)event_info;
335 line = (char *)g_slist_nth_data(lines, 0); /* Fetch Line 1 */
337 dbg("Line 1: [%s]", line);
340 err("Line 1 is invalid");
344 tokens = tcore_at_tok_new(line); /* Split Line 1 into tokens */
345 mem_type = atoi(g_slist_nth_data(tokens, 0)); // Type of Memory stored
346 index = atoi((char *) g_slist_nth_data(tokens, 1));
348 hal = tcore_object_get_hal(obj);
350 err("NULL input. Unable to proceed");
351 dbg("readMsg: hal: [%p]", hal);
354 return TCORE_RETURN_EINVAL;
357 dbg("index: [%d]", index);
359 cmd_str = g_strdup_printf("AT+CMGR=%d", index);
360 atreq = tcore_at_request_new((const char *)cmd_str, "+CMGR", TCORE_AT_PDU);
361 pending = tcore_pending_new(obj, 0);
363 if (NULL == cmd_str || NULL == atreq || NULL == pending) {
364 err("Out of memory. Unable to proceed");
365 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
369 util_sms_free_memory(atreq);
370 util_sms_free_memory(pending);
373 return TCORE_RETURN_ENOMEM;
376 util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
378 tcore_pending_set_request_data(pending, 0, atreq);
379 tcore_pending_set_response_callback(pending, on_response_class2_read_msg, (void *)(uintptr_t)index); //storing index as user data for response
380 tcore_pending_link_user_request(pending, NULL);
381 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
382 tcore_hal_send_request(hal, pending);
386 tcore_at_tok_free(tokens);
391 static gboolean on_event_sms_incom_msg(CoreObject *o, const void *event_info, void *user_data)
393 //+CMT: [<alpha>],<length><CR><LF><pdu> (PDU mode enabled);
396 GSList *tokens = NULL;
397 GSList *lines = NULL;
399 int pdu_len = 0, no_of_tokens = 0;
400 unsigned char *bytePDU = NULL;
401 struct tnoti_sms_umts_msg gsmMsgInfo;
404 dbg("Entered Function");
406 lines = (GSList *)event_info;
407 memset(&gsmMsgInfo, 0x00, sizeof(struct tnoti_sms_umts_msg));
409 if (2 != g_slist_length(lines)) {
410 err("Invalid number of lines for +CMT. Must be 2");
414 line = (char *)g_slist_nth_data(lines, 0); /* Fetch Line 1 */
416 dbg("Line 1: [%s]", line);
419 err("Line 1 is invalid");
423 tokens = tcore_at_tok_new(line); /* Split Line 1 into tokens */
425 no_of_tokens = g_slist_length(tokens);
427 if (no_of_tokens == 2) { // in case of incoming SMS +CMT
428 dbg("Alpha ID: [%02x]", g_slist_nth_data(tokens, 0)); /* 0: Alpha ID */
429 pdu_len = atoi((char *)g_slist_nth_data(tokens, 1));
430 dbg("pdu_len: [%d]", pdu_len); /* 1: PDU Length */
431 } else if (no_of_tokens == 1) { // in case of incoming status report +CDS
432 pdu_len = atoi((char *)g_slist_nth_data(tokens, 0));
433 dbg("pdu_len: [%d]", pdu_len); /* 1: PDU Length */
436 line = (char *)g_slist_nth_data(lines, 1); /* Fetch Line 2 */
438 dbg("Line 2: [%s]", line);
441 err("Line 2 is invalid");
445 /* Convert to Bytes */
446 bytePDU = (unsigned char *)util_hexStringToBytes(line);
448 sca_length = bytePDU[0];
450 dbg("SCA length = %d", sca_length);
452 gsmMsgInfo.msgInfo.msgLength = pdu_len;
454 if (sca_length == 0) {
455 memcpy(gsmMsgInfo.msgInfo.tpduData, &bytePDU[1], gsmMsgInfo.msgInfo.msgLength);
457 memcpy(gsmMsgInfo.msgInfo.sca, &bytePDU[1], sca_length);
458 memcpy(gsmMsgInfo.msgInfo.tpduData, &bytePDU[sca_length+1], gsmMsgInfo.msgInfo.msgLength);
461 util_hex_dump(" ", strlen(line)/2, bytePDU);
462 util_hex_dump(" ", sca_length, gsmMsgInfo.msgInfo.sca);
463 util_hex_dump(" ", gsmMsgInfo.msgInfo.msgLength,gsmMsgInfo.msgInfo.tpduData);
465 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);
468 tcore_at_tok_free(tokens);
477 static gboolean on_event_sms_memory_status(CoreObject *o, const void *event_info, void *user_data)
479 struct tnoti_sms_memory_status memStatusInfo = {0,};
481 int rtn = -1 ,memoryStatus = -1;
484 char *line = NULL , *pResp = NULL;
488 lines = (GSList *)event_info;
489 if (1 != g_slist_length(lines)) {
490 dbg("unsolicited msg but multiple line");
493 line = (char*)(lines->data);
497 tokens = tcore_at_tok_new(line);
498 pResp = g_slist_nth_data(tokens, 0);
501 memoryStatus = atoi(pResp);
502 dbg("memoryStatus is %d",memoryStatus);
503 if (memoryStatus == 0) {//SIM Full condition
504 memStatusInfo.status = SMS_PHONE_MEMORY_STATUS_FULL;
506 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);
508 tcore_at_tok_free(tokens);
517 static gboolean on_event_sms_cb_incom_msg(CoreObject *o, const void *event_info, void *user_data)
519 //+CBM: <length><CR><LF><pdu>
521 struct tnoti_sms_cellBroadcast_msg cbMsgInfo;
523 int rtn = -1 , length = 0;
524 char * line = NULL, *pdu = NULL, *pResp = NULL;
525 GSList *tokens = NULL;
526 GSList *lines = NULL;
528 dbg(" Func Entrance");
530 lines = (GSList *)event_info;
532 memset(&cbMsgInfo, 0, sizeof(struct tnoti_sms_cellBroadcast_msg));
534 line = (char *)(lines->data);
538 dbg("Noti line is %s",line);
539 tokens = tcore_at_tok_new(line); /* Split Line 1 into tokens */
541 pResp = g_slist_nth_data(tokens, 0);
543 length = atoi(pResp);
545 dbg("token 0 is null");
548 pdu = g_slist_nth_data(lines, 1);
550 cbMsgInfo.cbMsg.length = length;
551 cbMsgInfo.cbMsg.cbMsgType = SMS_CB_MSG_GSM;
553 dbg("CB Msg LENGTH [%2x]", length);
555 if ((cbMsgInfo.cbMsg.length >0) && (SMS_CB_SIZE_MAX >= cbMsgInfo.cbMsg.length)) {
556 unsigned char *byte_pdu = NULL;
558 byte_pdu = (unsigned char *)util_hexStringToBytes(pdu);
560 memcpy(cbMsgInfo.cbMsg.msgData, (char*)byte_pdu, cbMsgInfo.cbMsg.length);
561 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);
564 dbg("Invalid Message Length");
567 dbg("Recieved NULL pdu");
573 dbg(" Return value [%d]",rtn);
576 tcore_at_tok_free(tokens);
582 /*=============================================================
584 ==============================================================*/
585 static void on_response_sms_delete_msg(TcorePending *p, int data_len, const void *data, void *user_data)
587 struct tresp_sms_delete_msg delMsgInfo = {0,};
588 UserRequest *ur = NULL;
589 const TcoreATResponse *atResp = data;
592 int index = (int) user_data;
594 dbg(" Func Entrance");
596 ur = tcore_pending_ref_user_request(p);
597 if (atResp->success) {
599 delMsgInfo.index = index;
600 delMsgInfo.result = SMS_SENDSMS_SUCCESS;
603 delMsgInfo.index = index;
604 delMsgInfo.result = SMS_DEVICE_FAILURE;
607 rtn = tcore_user_request_send_response(ur, TRESP_SMS_DELETE_MSG, sizeof(struct tresp_sms_delete_msg), &delMsgInfo);
612 static void on_response_sms_save_msg(TcorePending *p, int data_len, const void *data, void *user_data)
614 struct tresp_sms_save_msg saveMsgInfo = {0,};
615 UserRequest *ur = NULL;
616 const TcoreATResponse *atResp = data;
617 GSList *tokens = NULL;
622 ur = tcore_pending_ref_user_request(p);
623 if (atResp->success) {
626 line = (char *)atResp->lines->data;
627 tokens = tcore_at_tok_new(line);
628 pResp = g_slist_nth_data(tokens, 0);
631 saveMsgInfo.index = (atoi(pResp) - 1); /* IMC index starts from 1 */
632 saveMsgInfo.result = SMS_SENDSMS_SUCCESS;
635 saveMsgInfo.index = -1;
636 saveMsgInfo.result = SMS_DEVICE_FAILURE;
638 tcore_at_tok_free(tokens);
642 saveMsgInfo.index = -1;
643 saveMsgInfo.result = SMS_DEVICE_FAILURE;
646 rtn = tcore_user_request_send_response(ur, TRESP_SMS_SAVE_MSG, sizeof(struct tresp_sms_save_msg), &saveMsgInfo);
647 dbg("Return value [%d]", rtn);
651 static void on_response_send_umts_msg(TcorePending *pending, int data_len, const void *data, void *user_data)
653 const TcoreATResponse *at_response = data;
654 struct tresp_sms_send_umts_msg resp_umts;
655 UserRequest *user_req = NULL;
658 GSList *tokens = NULL;
659 char *gslist_line = NULL, *line_token = NULL;
663 user_req = tcore_pending_ref_user_request(pending);
665 if (NULL == user_req) {
666 err("No user request");
672 memset(&resp_umts, 0x00, sizeof(resp_umts));
673 resp_umts.result = SMS_DEVICE_FAILURE;
675 if (at_response->success > 0) { /* SUCCESS */
677 if (at_response->lines) { // lines present in at_response
678 gslist_line = (char *)at_response->lines->data;
679 dbg("gslist_line: [%s]", gslist_line);
681 tokens = tcore_at_tok_new(gslist_line); //extract tokens
683 line_token = g_slist_nth_data(tokens, 0);
684 if (line_token != NULL) {
685 msg_ref = atoi(line_token);
686 dbg("Message Reference: [%d]", msg_ref);
688 resp_umts.result = SMS_SENDSMS_SUCCESS;
690 dbg("No Message Reference received");
692 tcore_at_tok_free(tokens);
693 } else { // no lines in at_response
700 tcore_user_request_send_response(user_req, TRESP_SMS_SEND_UMTS_MSG, sizeof(resp_umts), &resp_umts);
706 static void on_response_class2_read_msg(TcorePending *pending, int data_len, const void *data, void *user_data)
708 const TcoreATResponse *at_response = data;
710 char *gslist_line = NULL, *line_token = NULL, *hex_pdu = NULL;
711 int pdu_len = 0, rtn = 0;
712 unsigned char *bytePDU = NULL;
713 struct tnoti_sms_umts_msg gsmMsgInfo;
717 dbg("lines: [%p]", at_response->lines);
718 g_slist_foreach(at_response->lines, print_glib_list_elem, NULL); //for debug log
720 if (at_response->success <= 0) {
726 if (at_response->lines == NULL) {
732 gslist_line = (char *)at_response->lines->data;
733 if (gslist_line == NULL) {
734 err("Error response data");
738 dbg("gslist_line: [%s]", gslist_line);
740 tokens = tcore_at_tok_new(gslist_line);
741 dbg("Number of tokens: [%d]", g_slist_length(tokens));
742 g_slist_foreach(tokens, print_glib_list_elem, NULL); //for debug log
744 line_token = g_slist_nth_data(tokens, 2); //Third Token: Length
745 if (line_token == NULL) {
746 err("Error response data");
747 tcore_at_tok_free(tokens);
751 pdu_len = atoi(line_token);
752 dbg("Length: [%d]", pdu_len);
753 tcore_at_tok_free(tokens);
756 if (at_response->lines->next == NULL) {
757 err("Error response data");
760 gslist_line = (char *)at_response->lines->next->data;
761 if (gslist_line == NULL) {
762 err("Error response data");
766 dbg("gslist_line: [%s]", gslist_line);
768 tokens = tcore_at_tok_new(gslist_line);
769 dbg("Number of tokens: [%d]", g_slist_length(tokens));
770 g_slist_foreach(tokens, print_glib_list_elem, NULL); //for debug log
772 hex_pdu = g_slist_nth_data(tokens, 0); //Fetch SMS PDU
774 /* Convert to Bytes */
775 bytePDU = (unsigned char *)util_hexStringToBytes(hex_pdu);
776 if (bytePDU == NULL) {
777 tcore_at_tok_free(tokens);
781 sca_length = bytePDU[0];
782 dbg("SCA length = %d", sca_length);
784 gsmMsgInfo.msgInfo.msgLength = pdu_len;
786 if (sca_length == 0) {
787 memcpy(gsmMsgInfo.msgInfo.tpduData, &bytePDU[1], gsmMsgInfo.msgInfo.msgLength);
789 memcpy(gsmMsgInfo.msgInfo.sca, bytePDU, sca_length);
790 memcpy(gsmMsgInfo.msgInfo.tpduData, &bytePDU[sca_length+1], gsmMsgInfo.msgInfo.msgLength);
793 util_hex_dump(" ", strlen(hex_pdu)/2, bytePDU);
794 util_hex_dump(" ", sca_length, gsmMsgInfo.msgInfo.sca);
795 util_hex_dump(" ", gsmMsgInfo.msgInfo.msgLength,gsmMsgInfo.msgInfo.tpduData);
797 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);
800 tcore_at_tok_free(tokens);
803 static void on_response_read_msg(TcorePending *pending, int data_len, const void *data, void *user_data)
805 const TcoreATResponse *at_response = data;
806 struct tresp_sms_read_msg resp_read_msg;
807 UserRequest *user_req = NULL;
810 char *gslist_line = NULL, *line_token = NULL, *byte_pdu = NULL, *hex_pdu = NULL;
812 int msg_status = 0, alpha_id = 0, pdu_len = 0;
813 int index = (int)(uintptr_t)user_data;
816 dbg("index: [%d]", index);
817 g_slist_foreach(at_response->lines, print_glib_list_elem, NULL); //for debug log
819 user_req = tcore_pending_ref_user_request(pending);
820 if (NULL == user_req) {
821 err("No user request");
827 memset(&resp_read_msg, 0x00, sizeof(resp_read_msg));
828 resp_read_msg.result = SMS_PHONE_FAILURE;
830 if (at_response->success > 0) {
832 if (at_response->lines) {
834 gslist_line = (char *)at_response->lines->data;
836 dbg("gslist_line: [%s]", gslist_line);
838 tokens = tcore_at_tok_new(gslist_line);
839 dbg("Number of tokens: [%d]", g_slist_length(tokens));
840 g_slist_foreach(tokens, print_glib_list_elem, NULL); //for debug log
842 line_token = g_slist_nth_data(tokens, 0); //First Token: Message Status
843 if (line_token != NULL) {
844 msg_status = atoi(line_token);
845 dbg("msg_status is %d",msg_status);
846 switch (msg_status) {
848 resp_read_msg.dataInfo.msgStatus = SMS_STATUS_UNREAD;
852 resp_read_msg.dataInfo.msgStatus = SMS_STATUS_READ;
856 resp_read_msg.dataInfo.msgStatus = SMS_STATUS_UNSENT;
860 resp_read_msg.dataInfo.msgStatus = SMS_STATUS_SENT;
863 case AT_ALL: //Fall Through
864 default: //Fall Through
865 resp_read_msg.dataInfo.msgStatus = SMS_STATUS_RESERVED;
870 line_token = g_slist_nth_data(tokens, 1); //Second Token: AlphaID
871 if (line_token != NULL) {
872 alpha_id = atoi(line_token);
873 dbg("AlphaID: [%d]", alpha_id);
876 line_token = g_slist_nth_data(tokens, 2); //Third Token: Length
877 if (line_token != NULL) {
878 pdu_len = atoi(line_token);
879 dbg("Length: [%d]", pdu_len);
883 hex_pdu = (char *) at_response->lines->next->data;
885 dbg("EF-SMS PDU: [%s]", hex_pdu);
887 //free the consumed token
888 tcore_at_tok_free(tokens);
890 if (NULL != hex_pdu) {
891 util_hex_dump(" ", sizeof(hex_pdu), (void *)hex_pdu);
893 byte_pdu = util_hexStringToBytes(hex_pdu);
895 sca_length = (int)byte_pdu[0];
897 resp_read_msg.dataInfo.simIndex = index; //Retrieving index stored as user_data
899 dbg("SCA Length : %d", sca_length);
901 resp_read_msg.dataInfo.smsData.msgLength = pdu_len;
902 dbg("msgLength: [%d]", resp_read_msg.dataInfo.smsData.msgLength);
904 if(0 == sca_length) {
905 if ((resp_read_msg.dataInfo.smsData.msgLength > 0)
906 && (resp_read_msg.dataInfo.smsData.msgLength <= SMS_SMDATA_SIZE_MAX)) {
907 memset(resp_read_msg.dataInfo.smsData.sca, 0, TAPI_SIM_SMSP_ADDRESS_LEN);
908 memcpy(resp_read_msg.dataInfo.smsData.tpduData, &byte_pdu[1], resp_read_msg.dataInfo.smsData.msgLength);
910 resp_read_msg.result = SMS_SUCCESS;
912 dbg("Invalid Message Length");
913 resp_read_msg.result = SMS_INVALID_PARAMETER_FORMAT;
915 } else if (sca_length > SMS_ENCODED_SCA_LEN_MAX) {
916 dbg("Invalid Message Length");
917 resp_read_msg.result = SMS_INVALID_PARAMETER_FORMAT;
919 if ((resp_read_msg.dataInfo.smsData.msgLength > 0)
920 && (resp_read_msg.dataInfo.smsData.msgLength <= SMS_SMDATA_SIZE_MAX)) {
921 memcpy(resp_read_msg.dataInfo.smsData.sca, (char *)byte_pdu, (sca_length+1));
922 memcpy(resp_read_msg.dataInfo.smsData.tpduData, &byte_pdu[sca_length+1], resp_read_msg.dataInfo.smsData.msgLength);
924 util_hex_dump(" ", SMS_SMSP_ADDRESS_LEN, (void *)resp_read_msg.dataInfo.smsData.sca);
925 util_hex_dump(" ", (SMS_SMDATA_SIZE_MAX + 1), (void *)resp_read_msg.dataInfo.smsData.tpduData);
926 util_hex_dump(" ", sizeof(byte_pdu), (void *)byte_pdu);
928 resp_read_msg.result = SMS_SUCCESS;
930 dbg("Invalid Message Length");
931 resp_read_msg.result = SMS_INVALID_PARAMETER_FORMAT;
945 tcore_user_request_send_response(user_req, TRESP_SMS_READ_MSG, sizeof(resp_read_msg), &resp_read_msg);
951 static void on_response_get_msg_indices(TcorePending *pending, int data_len, const void *data, void *user_data)
953 const TcoreATResponse *at_response = data;
954 struct tresp_sms_get_storedMsgCnt resp_stored_msg_cnt;
955 UserRequest *user_req = NULL;
956 struct tresp_sms_get_storedMsgCnt *resp_stored_msg_cnt_prev = NULL;
958 GSList *tokens = NULL;
959 char *gslist_line = NULL, *line_token = NULL;
960 int gslist_line_count = 0, ctr_loop = 0;
964 resp_stored_msg_cnt_prev = (struct tresp_sms_get_storedMsgCnt *)user_data;
965 user_req = tcore_pending_ref_user_request(pending);
967 memset(&resp_stored_msg_cnt, 0x00, sizeof(resp_stored_msg_cnt));
968 resp_stored_msg_cnt.result = SMS_DEVICE_FAILURE;
970 if (at_response->success) {
972 if (at_response->lines) {
973 gslist_line_count = g_slist_length(at_response->lines);
975 if (gslist_line_count > SMS_GSM_SMS_MSG_NUM_MAX)
976 gslist_line_count = SMS_GSM_SMS_MSG_NUM_MAX;
978 dbg("Number of lines: [%d]", gslist_line_count);
979 g_slist_foreach(at_response->lines, print_glib_list_elem, NULL); //for debug log
981 for (ctr_loop = 0; ctr_loop < gslist_line_count; ctr_loop++) {
982 gslist_line = (char *)g_slist_nth_data(at_response->lines, ctr_loop); /* Fetch Line i */
984 dbg("gslist_line [%d] is [%s]", ctr_loop, gslist_line);
986 if (NULL != gslist_line) {
987 tokens = tcore_at_tok_new(gslist_line);
989 g_slist_foreach(tokens, print_glib_list_elem, NULL); //for debug log
991 line_token = g_slist_nth_data(tokens, 0);
992 if (NULL != line_token) {
993 resp_stored_msg_cnt.storedMsgCnt.indexList[ctr_loop] = atoi(line_token);
994 resp_stored_msg_cnt.result = SMS_SENDSMS_SUCCESS;
996 dbg("line_token of gslist_line [%d] is NULL", ctr_loop);
999 tcore_at_tok_free(tokens);
1001 dbg("gslist_line [%d] is NULL", ctr_loop);
1007 if (resp_stored_msg_cnt_prev->storedMsgCnt.usedCount == 0) { // Check if used count is zero
1008 resp_stored_msg_cnt.result = SMS_SENDSMS_SUCCESS;
1012 dbg("Respnose NOK");
1015 resp_stored_msg_cnt.storedMsgCnt.totalCount = resp_stored_msg_cnt_prev->storedMsgCnt.totalCount;
1016 resp_stored_msg_cnt.storedMsgCnt.usedCount = resp_stored_msg_cnt_prev->storedMsgCnt.usedCount;
1018 util_sms_free_memory(resp_stored_msg_cnt_prev);
1020 dbg("total: [%d], used: [%d], result: [%d]", resp_stored_msg_cnt.storedMsgCnt.totalCount, resp_stored_msg_cnt.storedMsgCnt.usedCount, resp_stored_msg_cnt.result);
1021 for (ctr_loop = 0; ctr_loop < gslist_line_count; ctr_loop++) {
1022 dbg("index: [%d]", resp_stored_msg_cnt.storedMsgCnt.indexList[ctr_loop]);
1025 tcore_user_request_send_response(user_req, TRESP_SMS_GET_STORED_MSG_COUNT, sizeof(resp_stored_msg_cnt), &resp_stored_msg_cnt);
1031 static void on_response_get_stored_msg_cnt(TcorePending *pending, int data_len, const void *data, void *user_data)
1033 UserRequest *ur = NULL, *ur_dup = NULL;
1034 struct tresp_sms_get_storedMsgCnt *respStoredMsgCnt = NULL;
1035 const TcoreATResponse *atResp = data;
1036 GSList *tokens=NULL;
1037 char *line = NULL , *pResp = NULL , *cmd_str = NULL;
1038 TcoreATRequest *atReq = NULL;
1039 int usedCnt = 0, totalCnt = 0, result = 0;
1041 TcorePending *pending_new = NULL;
1042 CoreObject *o = NULL;
1046 respStoredMsgCnt = malloc(sizeof(struct tresp_sms_get_storedMsgCnt));
1047 result = SMS_DEVICE_FAILURE;
1049 ur = tcore_pending_ref_user_request(pending);
1050 ur_dup = tcore_user_request_ref(ur);
1051 o = tcore_pending_ref_core_object(pending);
1053 if (atResp->success > 0) {
1055 if (NULL != atResp->lines) {
1056 line = (char *)atResp->lines->data;
1057 dbg("line is %s",line);
1059 tokens = tcore_at_tok_new(line);
1060 pResp = g_slist_nth_data(tokens, 0);
1063 usedCnt =atoi(pResp);
1064 dbg("used cnt is %d",usedCnt);
1067 pResp = g_slist_nth_data(tokens, 1);
1069 totalCnt =atoi(pResp);
1070 result = SMS_SENDSMS_SUCCESS;
1072 respStoredMsgCnt->storedMsgCnt.usedCount = usedCnt;
1073 respStoredMsgCnt->storedMsgCnt.totalCount = totalCnt;
1074 respStoredMsgCnt->result = result;
1076 dbg("used %d, total %d, result %d",usedCnt, totalCnt,result);
1078 pending_new = tcore_pending_new(o, 0);
1079 //Get all messages information
1080 cmd_str = g_strdup_printf("AT+CMGL=4");
1081 atReq = tcore_at_request_new((const char *)cmd_str, "+CMGL", TCORE_AT_MULTILINE);
1083 dbg("cmd str is %s",cmd_str);
1085 tcore_pending_set_request_data(pending_new, 0,atReq);
1086 tcore_pending_set_response_callback(pending_new, on_response_get_msg_indices, (void *)respStoredMsgCnt);
1087 tcore_pending_link_user_request(pending_new, ur_dup);
1088 tcore_pending_set_send_callback(pending_new, on_confirmation_sms_message_send, NULL);
1089 tcore_hal_send_request(tcore_object_get_hal(o), pending_new);
1091 //free the consumed token
1092 tcore_at_tok_free(tokens);
1099 //free the consumed token
1101 tcore_at_tok_free(tokens);
1106 err("Response NOK");
1108 respStoredMsgCnt->result = result;
1109 tcore_user_request_send_response(ur, TRESP_SMS_GET_STORED_MSG_COUNT, sizeof(struct tresp_sms_get_storedMsgCnt), &respStoredMsgCnt);
1116 static void on_response_get_sca(TcorePending *pending, int data_len, const void *data, void *user_data)
1118 const TcoreATResponse *at_response = data;
1119 struct tresp_sms_get_sca respGetSca;
1120 UserRequest *user_req = NULL;
1122 GSList *tokens = NULL;
1123 const char *sca_tok_addr;
1124 char *gslist_line = NULL, *sca_addr = NULL, *sca_toa = NULL;
1128 memset(&respGetSca, 0, sizeof(respGetSca));
1129 respGetSca.result = SMS_DEVICE_FAILURE;
1131 user_req = tcore_pending_ref_user_request(pending);
1133 if (at_response->success) {
1135 if (at_response->lines) {
1136 gslist_line = (char *)at_response->lines->data;
1138 tokens = tcore_at_tok_new(gslist_line);
1139 sca_tok_addr = g_slist_nth_data(tokens, 0);
1140 sca_toa = g_slist_nth_data(tokens, 1);
1142 sca_addr = tcore_at_tok_extract(sca_tok_addr);
1143 if ((NULL != sca_addr)
1144 && (NULL != sca_toa)) {
1145 dbg("sca_addr: [%s]. sca_toa: [%s]", sca_addr, sca_toa);
1147 respGetSca.scaAddress.dialNumLen = strlen(sca_addr);
1149 if (145 == atoi(sca_toa)) {
1150 respGetSca.scaAddress.typeOfNum = SIM_TON_INTERNATIONAL;
1152 respGetSca.scaAddress.typeOfNum = SIM_TON_NATIONAL;
1155 respGetSca.scaAddress.numPlanId = 0;
1157 memcpy(respGetSca.scaAddress.diallingNum, sca_addr, strlen(sca_addr));
1159 dbg("len [%d], sca_addr [%s], TON [%d], NPI [%d]", respGetSca.scaAddress.dialNumLen, respGetSca.scaAddress.diallingNum, respGetSca.scaAddress.typeOfNum, respGetSca.scaAddress.numPlanId);
1161 respGetSca.result = SMS_SENDSMS_SUCCESS;
1163 err("sca_addr OR sca_toa NULL");
1169 dbg("Response NOK");
1172 tcore_user_request_send_response(user_req, TRESP_SMS_GET_SCA, sizeof(respGetSca), &respGetSca);
1174 tcore_at_tok_free(tokens);
1181 static void on_response_set_sca(TcorePending *pending, int data_len, const void *data, void *user_data)
1184 Response is expected in this format
1190 //copies the AT response data to resp
1191 const TcoreATResponse *atResp = data;
1192 struct tresp_sms_set_sca respSetSca;
1194 memset(&respSetSca, 0, sizeof(struct tresp_sms_set_sca));
1196 ur = tcore_pending_ref_user_request(pending);
1198 dbg("no user_request");
1202 if (atResp->success > 0) {
1204 respSetSca.result = SMS_SUCCESS;
1206 dbg("RESPONSE NOK");
1207 respSetSca.result = SMS_DEVICE_FAILURE;
1210 tcore_user_request_send_response(ur, TRESP_SMS_SET_SCA, sizeof(struct tresp_sms_set_sca), &respSetSca);
1215 static void on_response_get_cb_config(TcorePending *p, int data_len, const void *data, void *user_data)
1218 struct tresp_sms_get_cb_config respGetCbConfig;
1219 const TcoreATResponse *atResp = data;
1220 GSList *tokens=NULL;
1222 char *pResp = NULL, *line = NULL;
1225 memset(&respGetCbConfig, 0, sizeof(struct tresp_sms_get_cb_config));
1226 respGetCbConfig.result = SMS_DEVICE_FAILURE;
1228 ur = tcore_pending_ref_user_request(p);
1230 dbg("no user_request");
1234 respGetCbConfig.cbConfig.net3gppType = SMS_NETTYPE_3GPP;
1236 if (atResp->success) {
1238 if (atResp->lines) {
1239 line = (char*)atResp->lines->data;
1241 dbg("line is %s",line);
1242 tokens = tcore_at_tok_new(line);
1243 pResp = g_slist_nth_data(tokens, 0);
1246 respGetCbConfig.cbConfig.cbEnabled = mode;
1248 pResp = g_slist_nth_data(tokens, 1);
1250 GSList *cb_tokens = NULL;
1251 char *cb_mid_str = NULL;
1252 int num_cb_tokens = 0;
1253 char *mid_tok = NULL;
1254 char *first_tok = NULL, *second_tok = NULL;
1256 // 0,1,5,320-478,922
1257 cb_mid_str = util_removeQuotes(pResp);
1258 cb_tokens = tcore_at_tok_new((const char *) cb_mid_str);
1262 num_cb_tokens = g_slist_length(cb_tokens);
1263 dbg("num_cb_tokens = %d", num_cb_tokens);
1265 if (num_cb_tokens == 0) {
1266 if (mode == 1) { // Enable all CBs
1267 respGetCbConfig.cbConfig.msgIdRangeCount = 1;
1268 respGetCbConfig.cbConfig.msgIDs[0].net3gpp.fromMsgId = 0x0000;
1269 respGetCbConfig.cbConfig.msgIDs[0].net3gpp.toMsgId = SMS_GSM_SMS_CBMI_LIST_SIZE_MAX + 1;
1270 respGetCbConfig.cbConfig.msgIDs[0].net3gpp.selected = TRUE;
1271 respGetCbConfig.result = SMS_SENDSMS_SUCCESS;
1272 } else { // all CBs disabled
1273 respGetCbConfig.cbConfig.msgIdRangeCount = 0;
1274 respGetCbConfig.cbConfig.msgIDs[0].net3gpp.selected = FALSE;
1275 respGetCbConfig.result = SMS_SENDSMS_SUCCESS;
1278 respGetCbConfig.cbConfig.msgIdRangeCount = 0;
1279 respGetCbConfig.cbConfig.msgIDs[0].net3gpp.selected = FALSE;
1280 respGetCbConfig.result = SMS_SENDSMS_SUCCESS;
1283 for (i = 0; i < num_cb_tokens; i++) {
1284 respGetCbConfig.cbConfig.msgIDs[i].net3gpp.selected = TRUE;
1285 respGetCbConfig.cbConfig.msgIdRangeCount++;
1287 mid_tok = tcore_at_tok_nth(cb_tokens, i);
1288 first_tok = strtok(mid_tok, delim);
1289 second_tok = strtok(NULL, delim);
1291 if ((first_tok != NULL) && (second_tok != NULL)) { // mids in range (320-478)
1292 dbg("inside if mid_range");
1293 respGetCbConfig.cbConfig.msgIDs[i].net3gpp.fromMsgId = atoi(first_tok);
1294 respGetCbConfig.cbConfig.msgIDs[i].net3gpp.toMsgId = atoi(second_tok);
1295 } // single mid value (0,1,5, 922)
1297 respGetCbConfig.cbConfig.msgIDs[i].net3gpp.fromMsgId = atoi(mid_tok);
1298 respGetCbConfig.cbConfig.msgIDs[i].net3gpp.toMsgId = atoi(mid_tok);
1304 respGetCbConfig.cbConfig.msgIdRangeCount = 1;
1305 respGetCbConfig.cbConfig.msgIDs[0].net3gpp.fromMsgId = 0x0000;
1306 respGetCbConfig.cbConfig.msgIDs[0].net3gpp.toMsgId = SMS_GSM_SMS_CBMI_LIST_SIZE_MAX + 1;
1307 respGetCbConfig.cbConfig.msgIDs[0].net3gpp.selected = TRUE;
1308 respGetCbConfig.result = SMS_SENDSMS_SUCCESS;
1310 respGetCbConfig.cbConfig.msgIdRangeCount = 0;
1311 respGetCbConfig.cbConfig.msgIDs[0].net3gpp.selected = FALSE;
1312 respGetCbConfig.result = SMS_SENDSMS_SUCCESS;
1316 dbg("line is NULL");
1319 dbg("atresp->lines is NULL");
1322 dbg("RESPONSE NOK");
1325 tcore_user_request_send_response(ur, TRESP_SMS_GET_CB_CONFIG, sizeof(struct tresp_sms_get_cb_config), &respGetCbConfig);
1328 tcore_at_tok_free(tokens);
1333 static void on_response_set_cb_config(TcorePending *pending, int data_len, const void *data, void *user_data)
1336 Response is expected in this format
1343 const TcoreATResponse *resp = data;
1345 const char *line = NULL;
1346 GSList *tokens=NULL;
1348 struct tresp_sms_set_cb_config respSetCbConfig = {0,};
1350 memset(&respSetCbConfig, 0, sizeof(struct tresp_sms_set_cb_config));
1352 ur = tcore_pending_ref_user_request(pending);
1353 respSetCbConfig.result = SMS_SENDSMS_SUCCESS;
1355 if (resp->success > 0) {
1358 dbg("RESPONSE NOK");
1359 line = (const char*)resp->final_response;
1360 tokens = tcore_at_tok_new(line);
1362 if (g_slist_length(tokens) < 1) {
1363 dbg("err cause not specified or string corrupted");
1364 respSetCbConfig.result = SMS_DEVICE_FAILURE;
1366 response = atoi(g_slist_nth_data(tokens, 0));
1367 /* TODO: CMEE error mapping is required. */
1368 respSetCbConfig.result = SMS_DEVICE_FAILURE;
1372 dbg("no user_request");
1376 tcore_user_request_send_response(ur, TRESP_SMS_SET_CB_CONFIG, sizeof(struct tresp_sms_set_cb_config), &respSetCbConfig);
1379 tcore_at_tok_free(tokens);
1384 static void on_response_set_mem_status(TcorePending *p, int data_len, const void *data, void *user_data)
1387 struct tresp_sms_set_mem_status respSetMemStatus = {0,};
1388 const TcoreATResponse *resp = data;
1390 memset(&respSetMemStatus, 0, sizeof(struct tresp_sms_set_mem_status));
1392 if (resp->success > 0) {
1394 respSetMemStatus.result = SMS_SENDSMS_SUCCESS;
1396 dbg("RESPONSE NOK");
1397 respSetMemStatus.result = SMS_DEVICE_FAILURE;
1400 ur = tcore_pending_ref_user_request(p);
1402 dbg("no user_request");
1406 tcore_user_request_send_response(ur, TRESP_SMS_SET_MEM_STATUS, sizeof(struct tresp_sms_set_mem_status), &respSetMemStatus);
1411 static void on_response_set_msg_status(TcorePending *pending, int data_len, const void *data, void *user_data)
1414 struct tresp_sms_set_msg_status respMsgStatus = {0, };
1415 const TcoreATResponse *atResp = data;
1416 int response = 0, sw1 = 0, sw2 = 0;
1417 const char *line = NULL;
1419 GSList *tokens = NULL;
1423 memset(&respMsgStatus, 0, sizeof(struct tresp_sms_set_msg_status));
1424 respMsgStatus.result = SMS_DEVICE_FAILURE;
1426 ur = tcore_pending_ref_user_request(pending);
1428 if (atResp->success > 0) {
1431 if (atResp->lines) {
1432 line = (const char *) atResp->lines->data;
1433 tokens = tcore_at_tok_new(line);
1434 pResp = g_slist_nth_data(tokens, 0);
1435 if (pResp != NULL) {
1440 pResp = g_slist_nth_data(tokens, 1);
1441 if (pResp != NULL) {
1443 if ((sw1 == AT_SW1_SUCCESS) && (sw2 == 0)) {
1444 respMsgStatus.result = SMS_SENDSMS_SUCCESS;
1449 pResp = g_slist_nth_data(tokens, 3);
1451 if (pResp != NULL) {
1452 response = atoi(pResp);
1453 dbg("response is %s", response);
1459 dbg("RESPONSE NOK");
1462 tcore_user_request_send_response(ur, TRESP_SMS_SET_MSG_STATUS , sizeof(struct tresp_sms_set_msg_status), &respMsgStatus);
1465 tcore_at_tok_free(tokens);
1471 static void on_response_get_sms_params(TcorePending *pending, int data_len, const void *data, void *user_data)
1474 struct tresp_sms_get_params respGetParams ;
1475 const TcoreATResponse *atResp = data;
1476 int sw1 = 0, sw2 = 0;
1477 const char *line = NULL;
1479 GSList *tokens=NULL;
1480 char *hexData = NULL;
1481 char *recordData = NULL;
1484 memset(&respGetParams, 0, sizeof(struct tresp_sms_get_params));
1485 respGetParams.result = SMS_DEVICE_FAILURE;
1487 ur = tcore_pending_ref_user_request(pending);
1489 if (atResp->success > 0) {
1492 if (atResp->lines) {
1493 line = (const char *) atResp->lines->data;
1494 tokens = tcore_at_tok_new(line);
1495 pResp = g_slist_nth_data(tokens, 0);
1496 if (pResp != NULL) {
1498 dbg("sw1 is %d", sw1);
1502 pResp = g_slist_nth_data(tokens, 1);
1503 if (pResp != NULL) {
1505 dbg("sw2 is %d", sw2);
1506 if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
1507 respGetParams.result = SMS_SENDSMS_SUCCESS;
1512 pResp = g_slist_nth_data(tokens, 2);
1513 if (pResp != NULL) {
1514 hexData = util_removeQuotes(pResp);
1516 recordData = util_hexStringToBytes(hexData);
1517 util_hex_dump(" ", strlen(hexData) / 2, recordData);
1519 respGetParams.paramsInfo.recordLen = strlen(hexData) / 2;
1521 util_sms_decode_smsParameters((unsigned char *) recordData, strlen(hexData) / 2, &(respGetParams.paramsInfo));
1522 respGetParams.result = SMS_SENDSMS_SUCCESS;
1524 for (i = 0; i < (int) respGetParams.paramsInfo.tpSvcCntrAddr.dialNumLen; i++)
1525 dbg("SCAddr = %d [%02x]", i, respGetParams.paramsInfo.tpSvcCntrAddr.diallingNum[i]);
1532 tcore_at_tok_free(tokens);
1535 dbg("RESPONSE NOK");
1538 tcore_user_request_send_response(ur, TRESP_SMS_GET_PARAMS, sizeof(struct tresp_sms_get_params), &respGetParams);
1544 static void on_response_set_sms_params(TcorePending *pending, int data_len, const void *data, void *user_data)
1547 struct tresp_sms_set_params respSetParams = {0, };
1548 const TcoreATResponse *atResp = data;
1549 int sw1 =0 , sw2 = 0;
1550 const char *line = NULL;
1552 GSList *tokens=NULL;
1555 memset(&respSetParams, 0, sizeof(struct tresp_sms_set_params));
1556 ur = tcore_pending_ref_user_request(pending);
1558 respSetParams.result = SMS_DEVICE_FAILURE;
1560 if (atResp->success > 0) {
1563 if (atResp->lines) {
1564 line = (const char *) atResp->lines->data;
1565 tokens = tcore_at_tok_new(line);
1566 pResp = g_slist_nth_data(tokens, 0);
1567 if (pResp != NULL) {
1573 pResp = g_slist_nth_data(tokens, 1);
1574 if (pResp != NULL) {
1576 if (((sw1 == AT_SW1_SUCCESS) && (sw2 == AT_SW2_SUCCESS)) || (sw1 == 0x91)) {
1577 respSetParams.result = SMS_SENDSMS_SUCCESS;
1586 dbg("RESPONSE NOK");
1589 tcore_user_request_send_response(ur, TRESP_SMS_SET_PARAMS , sizeof(struct tresp_sms_set_params), &respSetParams);
1592 tcore_at_tok_free(tokens);
1598 static void on_response_get_paramcnt(TcorePending *p, int data_len, const void *data, void *user_data)
1600 UserRequest *ur = NULL;
1601 struct tresp_sms_get_paramcnt respGetParamCnt = {0, };
1602 const TcoreATResponse *atResp = data;
1603 char *line = NULL , *pResp = NULL;
1604 int sw1 = 0 , sw2 = 0, *smsp_record_len = NULL;
1606 GSList *tokens=NULL;
1607 CoreObject *co_sim = NULL; //need this to get the sim type GSM/USIM
1608 TcorePlugin *plugin = NULL;
1612 ur = tcore_pending_ref_user_request(p);
1613 respGetParamCnt.result = SMS_DEVICE_FAILURE;
1615 if (atResp->success > 0) {
1618 if (atResp->lines) {
1619 line = (char *) atResp->lines->data;
1621 dbg("line is %s", line);
1623 tokens = tcore_at_tok_new(line);
1624 pResp = g_slist_nth_data(tokens, 0);
1625 if (pResp != NULL) {
1630 pResp = g_slist_nth_data(tokens, 1);
1631 if (pResp != NULL) {
1633 if ((sw1 == 144) && (sw2 == 0)) {
1634 respGetParamCnt.result = SMS_SENDSMS_SUCCESS;
1639 pResp = g_slist_nth_data(tokens, 2);
1640 if (pResp != NULL) {
1641 char *hexData = NULL;
1642 char *recordData = NULL;
1643 hexData = util_removeQuotes(pResp);
1645 /*1. SIM access success case*/
1646 if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
1647 unsigned char tag_len = 0; /* 1 or 2 bytes ??? */
1649 char num_of_records = 0;
1650 unsigned char file_id_len = 0;
1651 unsigned short file_id = 0;
1652 unsigned short file_size = 0;
1653 unsigned short file_type = 0;
1654 unsigned short arr_file_id = 0;
1655 int arr_file_id_rec_num = 0;
1657 /* handling only last 3 bits */
1658 unsigned char file_type_tag = 0x07;
1659 unsigned char *ptr_data;
1661 recordData = util_hexStringToBytes(hexData);
1662 util_hex_dump(" ", strlen(hexData)/2, recordData);
1664 ptr_data = (unsigned char *)recordData;
1666 co_sim = tcore_plugin_ref_core_object(tcore_pending_ref_plugin(p), CORE_OBJECT_TYPE_SIM);
1667 sim_type = tcore_sim_get_type(co_sim);
1668 dbg("sim type is %d",sim_type);
1670 if (sim_type == SIM_TYPE_USIM) {
1672 ETSI TS 102 221 v7.9.0
1674 '62' FCP template tag
1675 - Response for an EF
1676 '82' M File Descriptor
1677 '83' M File Identifier
1678 'A5' O Proprietary information
1679 '8A' M Life Cycle Status Integer
1680 '8B', '8C' or 'AB' C1 Security attributes
1682 '81' O Total file size
1683 '88' O Short File Identifier (SFI)
1686 /* rsim.res_len has complete data length received */
1688 /* FCP template tag - File Control Parameters tag*/
1689 if (*ptr_data == 0x62) {
1690 /* parse complete FCP tag*/
1691 /* increment to next byte */
1693 tag_len = *ptr_data++;
1694 /* FCP file descriptor - file type, accessibility, DF, ADF etc*/
1695 if (*ptr_data == 0x82) {
1696 /* increment to next byte */
1700 /* unsigned char file_desc_len = *ptr_data++;*/
1701 /* dbg("file descriptor length: [%d]", file_desc_len);*/
1702 /* TBD: currently capture only file type : ignore sharable, non sharable, working, internal etc*/
1703 /* consider only last 3 bits*/
1704 file_type_tag = file_type_tag & (*ptr_data);
1706 switch (file_type_tag) {
1707 /* increment to next byte */
1711 dbg("Getting FileType: [Transparent file type]");
1712 /* increment to next byte */
1714 file_type = 0x01; //SIM_FTYPE_TRANSPARENT
1715 /* data coding byte - value 21 */
1720 dbg("Getting FileType: [Linear fixed file type]");
1721 /* increment to next byte */
1723 /* data coding byte - value 21 */
1726 memcpy(&record_len, ptr_data, 2);
1728 record_len = SMS_SWAPBYTES16(record_len);
1729 ptr_data = ptr_data + 2;
1730 num_of_records = *ptr_data++;
1731 /* Data lossy conversation from enum (int) to unsigned char */
1732 file_type = 0x02; // SIM_FTYPE_LINEAR_FIXED
1736 dbg(" Cyclic fixed file type");
1737 /* increment to next byte */
1739 /* data coding byte - value 21 */
1742 memcpy(&record_len, ptr_data, 2);
1744 record_len = SMS_SWAPBYTES16(record_len);
1745 ptr_data = ptr_data + 2;
1746 num_of_records = *ptr_data++;
1747 file_type = 0x04; //SIM_FTYPE_CYCLIC
1751 dbg("not handled file type [0x%x]", *ptr_data);
1755 dbg("INVALID FCP received - DEbug!");
1758 tcore_at_tok_free(tokens);
1762 /*File identifier - file id?? */ // 0x84,0x85,0x86 etc are currently ignored and not handled
1763 if (*ptr_data == 0x83) {
1764 /* increment to next byte */
1766 file_id_len = *ptr_data++;
1767 memcpy(&file_id, ptr_data, file_id_len);
1769 file_id = SMS_SWAPBYTES16(file_id);
1770 ptr_data = ptr_data + 2;
1771 dbg("Getting FileID=[0x%x]", file_id);
1773 dbg("INVALID FCP received - DEbug!");
1776 tcore_at_tok_free(tokens);
1780 /* proprietary information */
1781 if (*ptr_data == 0xA5) {
1782 unsigned short prop_len;
1783 /* increment to next byte */
1786 prop_len = *ptr_data;
1788 ptr_data = ptr_data + prop_len + 1;
1790 dbg("INVALID FCP received - DEbug!");
1793 /* life cycle status integer [8A][length:0x01][status]*/
1796 00000000 : No information given
1797 00000001 : creation state
1798 00000011 : initialization state
1799 000001-1 : operation state -activated
1800 000001-0 : operation state -deactivated
1801 000011-- : Termination state
1802 b8~b5 !=0, b4~b1=X : Proprietary
1803 Any other value : RFU
1805 if (*ptr_data == 0x8A) {
1806 /* increment to next byte */
1808 /* length - value 1 */
1811 switch (*ptr_data) {
1814 dbg("[RX] Operation State: DEACTIVATED");
1820 dbg("[RX] Operation State: ACTIVATED");
1825 dbg("[RX] DEBUG! LIFE CYCLE STATUS: [0x%x]",*ptr_data);
1831 /* related to security attributes : currently not handled*/
1832 if (*ptr_data == 0x86 || *ptr_data == 0x8B || *ptr_data == 0x8C || *ptr_data == 0xAB) {
1833 /* increment to next byte */
1835 /* if tag length is 3 */
1836 if (*ptr_data == 0x03) {
1837 /* increment to next byte */
1840 memcpy(&arr_file_id, ptr_data, 2);
1842 arr_file_id = SMS_SWAPBYTES16(arr_file_id);
1843 ptr_data = ptr_data + 2;
1844 arr_file_id_rec_num = *ptr_data++;
1846 /* if tag length is not 3 */
1847 /* ignoring bytes */
1848 // ptr_data = ptr_data + 4;
1849 dbg("Useless security attributes, so jump to next tag");
1850 ptr_data = ptr_data + (*ptr_data + 1);
1853 dbg("INVALID FCP received[0x%x] - DEbug!", *ptr_data);
1856 tcore_at_tok_free(tokens);
1860 dbg("Current ptr_data value is [%x]", *ptr_data);
1862 /* file size excluding structural info*/
1863 if (*ptr_data == 0x80) {
1864 /* for EF file size is body of file and for Linear or cyclic it is
1865 * number of recXsizeof(one record)
1867 /* increment to next byte */
1869 /* length is 1 byte - value is 2 bytes or more */
1871 memcpy(&file_size, ptr_data, 2);
1873 file_size = SMS_SWAPBYTES16(file_size);
1874 ptr_data = ptr_data + 2;
1876 dbg("INVALID FCP received - DEbug!");
1879 tcore_at_tok_free(tokens);
1883 /* total file size including structural info*/
1884 if (*ptr_data == 0x81) {
1886 /* increment to next byte */
1891 ptr_data = ptr_data + 3;
1893 dbg("INVALID FCP received - DEbug!");
1894 /* 0x81 is optional tag?? check out! so do not return -1 from here! */
1897 /*short file identifier ignored*/
1898 if (*ptr_data == 0x88) {
1899 dbg("0x88: Do Nothing");
1903 dbg("INVALID FCP received - DEbug!");
1906 tcore_at_tok_free(tokens);
1909 } else if (sim_type == SIM_TYPE_GSM) {
1910 unsigned char gsm_specific_file_data_len = 0;
1911 /* ignore RFU byte1 and byte2 */
1915 //file_size = p_info->response_len;
1916 memcpy(&file_size, ptr_data, 2);
1918 file_size = SMS_SWAPBYTES16(file_size);
1919 /* parsed file size */
1920 ptr_data = ptr_data + 2;
1922 memcpy(&file_id, ptr_data, 2);
1923 file_id = SMS_SWAPBYTES16(file_id);
1924 dbg(" FILE id --> [%x]", file_id);
1925 ptr_data = ptr_data + 2;
1926 /* save file type - transparent, linear fixed or cyclic */
1927 file_type_tag = (*(ptr_data + 7));
1929 switch (*ptr_data) {
1932 dbg(" RFU file type- not handled - Debug!");
1937 dbg(" MF file type - not handled - Debug!");
1942 dbg(" DF file type - not handled - Debug!");
1947 dbg(" EF file type [%d] ", file_type_tag);
1948 /* increment to next byte */
1951 if (file_type_tag == 0x00 || file_type_tag == 0x01) {
1952 /* increament to next byte as this byte is RFU */
1955 (file_type_tag == 0x00) ? 0x01 : 0x02; // SIM_FTYPE_TRANSPARENT:SIM_FTYPE_LINEAR_FIXED;
1957 /* increment to next byte */
1959 /* For a cyclic EF all bits except bit 7 are RFU; b7=1 indicates that */
1960 /* the INCREASE command is allowed on the selected cyclic file. */
1961 file_type = 0x04; // SIM_FTYPE_CYCLIC;
1963 /* bytes 9 to 11 give SIM file access conditions */
1965 /* byte 10 has one nibble that is RF U and another for INCREASE which is not used currently */
1967 /* byte 11 is invalidate and rehabilate nibbles */
1969 /* byte 12 - file status */
1971 /* byte 13 - GSM specific data */
1972 gsm_specific_file_data_len = *ptr_data;
1974 /* byte 14 - structure of EF - transparent or linear or cyclic , already saved above */
1976 /* byte 15 - length of record for linear and cyclic , for transparent it is set to 0x00. */
1977 record_len = *ptr_data;
1978 dbg("record length[%d], file size[%d]", record_len, file_size);
1980 if (record_len != 0)
1981 num_of_records = (file_size / record_len);
1983 dbg("Number of records [%d]", num_of_records);
1987 dbg(" not handled file type");
1991 dbg(" Card Type - UNKNOWN [%d]", sim_type);
1994 dbg("EF[0x%x] size[%ld] Type[0x%x] NumOfRecords[%ld] RecordLen[%ld]", file_id, file_size, file_type, num_of_records, record_len);
1996 respGetParamCnt.recordCount = num_of_records;
1997 respGetParamCnt.result = SMS_SUCCESS;
1999 //TO Store smsp record length in the property
2000 plugin = tcore_pending_ref_plugin(p);
2001 smsp_record_len = tcore_plugin_ref_property(plugin, "SMSPRECORDLEN");
2002 memcpy(smsp_record_len, &record_len, sizeof(int));
2007 /*2. SIM access fail case*/
2008 dbg("SIM access fail");
2009 respGetParamCnt.result = SMS_UNKNOWN;
2012 dbg("presp is NULL");
2015 dbg("line is blank");
2018 dbg("RESPONSE NOK");
2021 tcore_user_request_send_response(ur, TRESP_SMS_GET_PARAMCNT, sizeof(struct tresp_sms_get_paramcnt), &respGetParamCnt);
2024 tcore_at_tok_free(tokens);
2030 static void _response_get_efsms_data(TcorePending *p, int data_len, const void *data, void *user_data)
2032 UserRequest *ur = NULL;
2033 UserRequest *dup_ur = NULL;
2034 struct tresp_sms_set_msg_status resp_msg_status = {0,};
2035 const struct treq_sms_set_msg_status *req_msg_status = NULL ;
2037 const TcoreATResponse *resp = data;
2038 char *encoded_data = NULL;
2039 char msg_status = 0;
2041 GSList *tokens=NULL;
2042 const char *line = NULL;
2046 TcoreHal *hal = NULL;
2047 TcoreATRequest *atreq = NULL;
2048 TcorePending *pending = NULL;
2049 gchar *cmd_str = NULL;
2051 ur = tcore_pending_ref_user_request(p);
2053 req_msg_status = tcore_user_request_ref_data(ur, NULL);
2055 resp_msg_status.result = SMS_DEVICE_FAILURE;
2057 hal = tcore_object_get_hal(tcore_pending_ref_core_object(pending));
2058 dbg("msgStatus: [%x], index [%x]", req_msg_status->msgStatus, req_msg_status->index);
2060 if (resp->success <= 0) {
2067 line = (const char *) resp->lines->data;
2068 tokens = tcore_at_tok_new(line);
2069 if (g_slist_length(tokens) != 3) {
2070 msg("invalid message");
2074 sw1 = atoi(g_slist_nth_data(tokens, 0));
2075 sw2 = atoi(g_slist_nth_data(tokens, 1));
2076 pResp = g_slist_nth_data(tokens, 2);
2078 if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
2079 switch (req_msg_status->msgStatus) {
2080 case SMS_STATUS_READ:
2084 case SMS_STATUS_UNREAD:
2088 case SMS_STATUS_UNSENT:
2092 case SMS_STATUS_SENT:
2096 case SMS_STATUS_DELIVERED:
2100 case SMS_STATUS_DELIVERY_UNCONFIRMED:
2104 case SMS_STATUS_MESSAGE_REPLACED:
2105 case SMS_STATUS_RESERVED:
2111 encoded_data = util_removeQuotes(pResp);
2113 //overwrite Status byte information
2114 util_byte_to_hex((const char *)&msg_status, (char *)encoded_data, 1);
2116 //Update EF-SMS with just status byte overwritten, rest 175 bytes are same as received in read information
2117 cmd_str = g_strdup_printf("AT+CRSM=220,28476,%d, 4, %d, \"%s\"", (req_msg_status->index+1), PDU_LEN_MAX, encoded_data);
2118 atreq = tcore_at_request_new((const char *)cmd_str, "+CRSM", TCORE_AT_SINGLELINE);
2119 pending = tcore_pending_new(tcore_pending_ref_core_object(pending), 0);
2120 if (NULL == cmd_str || NULL == atreq || NULL == pending) {
2121 err("Out of memory. Unable to proceed");
2122 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
2124 //free memory we own
2126 g_free(encoded_data);
2127 util_sms_free_memory(atreq);
2128 util_sms_free_memory(pending);
2133 util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
2135 dup_ur = tcore_user_request_ref(ur);
2137 tcore_pending_set_request_data(pending, 0, atreq);
2138 tcore_pending_set_response_callback(pending, on_response_set_msg_status, NULL);
2139 tcore_pending_link_user_request(pending, dup_ur);
2140 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
2141 tcore_hal_send_request(hal, pending);
2144 g_free(encoded_data);
2150 tcore_at_tok_free(tokens);
2152 tcore_user_request_send_response(ur, TRESP_SMS_SET_MSG_STATUS , sizeof(struct tresp_sms_set_msg_status), &msg_status);
2159 /*=============================================================
2161 ==============================================================*/
2162 static TReturn send_umts_msg(CoreObject *co_sms, UserRequest *ur)
2164 const struct treq_sms_send_umts_msg *send_msg;
2165 const unsigned char *tpdu_byte_data, *sca_byte_data;
2166 int tpdu_byte_len, pdu_byte_len;
2167 char buf[HEX_PDU_LEN_MAX];
2168 char pdu[PDU_LEN_MAX];
2170 int pdu_hex_len, mms;
2175 send_msg = tcore_user_request_ref_data(ur, NULL);
2177 tpdu_byte_data = send_msg->msgDataPackage.tpduData;
2178 sca_byte_data = send_msg->msgDataPackage.sca;
2181 /* TPDU length is in byte */
2182 tpdu_byte_len = send_msg->msgDataPackage.msgLength;
2184 /* Use same Radio Resource Channel */
2185 mms = send_msg->more;
2187 dbg("TDPU length: [%d]", tpdu_byte_len);
2188 dbg("SCA semi-octet length: [%d]", sca_byte_data[0]);
2190 /* Prepare PDU for hex encoding */
2191 pdu_byte_len = tcore_util_pdu_encode(sca_byte_data, tpdu_byte_data,
2192 tpdu_byte_len, pdu);
2194 pdu_hex_len = (int) tcore_util_encode_hex((unsigned char *) pdu,
2197 dbg("PDU hexadecimal length: [%d]", pdu_hex_len);
2200 cmd_str = g_strdup_printf("AT+CMMS=%d", mms);
2202 ret = tcore_prepare_and_send_at_request(co_sms, cmd_str, NULL,
2203 TCORE_AT_NO_RESULT, NULL, NULL, NULL,
2204 on_confirmation_sms_message_send,
2206 if (ret != TCORE_RETURN_SUCCESS) {
2207 err("Failed to prepare and send AT request");
2214 cmd_str = g_strdup_printf("AT+CMGS=%d\r%s\x1A", tpdu_byte_len, buf);
2216 ret = tcore_prepare_and_send_at_request(co_sms, cmd_str, "+CMGS:",
2217 TCORE_AT_SINGLELINE, ur,
2218 on_response_send_umts_msg, NULL,
2219 on_confirmation_sms_message_send, NULL);
2220 if (ret != TCORE_RETURN_SUCCESS)
2221 err("Failed to prepare and send AT request");
2231 static TReturn read_msg(CoreObject *obj, UserRequest *ur)
2233 gchar *cmd_str = NULL;
2234 TcoreHal *hal = NULL;
2235 TcoreATRequest *atreq = NULL;
2236 TcorePending *pending = NULL;
2237 const struct treq_sms_read_msg *readMsg = NULL;
2241 readMsg = tcore_user_request_ref_data(ur, NULL);
2242 hal = tcore_object_get_hal(obj);
2243 if (NULL == readMsg || NULL == hal) {
2244 err("NULL input. Unable to proceed");
2245 dbg("readMsg: [%p], hal: [%p]", readMsg, hal);
2248 return TCORE_RETURN_EINVAL;
2251 if(FALSE == tcore_hal_get_power_state(hal)){
2252 dbg("cp not ready/n");
2253 return TCORE_RETURN_ENOSYS;
2255 dbg("index: [%d]", readMsg->index);
2257 cmd_str = g_strdup_printf("AT+CMGR=%d", readMsg->index); //IMC index is one ahead of TAPI
2258 atreq = tcore_at_request_new((const char *)cmd_str, "+CMGR", TCORE_AT_PDU);
2259 pending = tcore_pending_new(obj, 0);
2261 if (NULL == cmd_str || NULL == atreq || NULL == pending) {
2262 err("Out of memory. Unable to proceed");
2263 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
2265 //free memory we own
2267 util_sms_free_memory(atreq);
2268 util_sms_free_memory(pending);
2271 return TCORE_RETURN_ENOMEM;
2274 util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
2276 tcore_pending_set_request_data(pending, 0, atreq);
2277 tcore_pending_set_response_callback(pending, on_response_read_msg, (void *)(uintptr_t)(readMsg->index)); //storing index as user data for response
2278 tcore_pending_link_user_request(pending, ur);
2279 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
2280 tcore_hal_send_request(hal, pending);
2285 return TCORE_RETURN_SUCCESS;
2288 static TReturn save_msg(CoreObject *obj, UserRequest *ur)
2290 gchar *cmd_str = NULL;
2291 TcoreHal *hal = NULL;
2292 TcoreATRequest *atreq = NULL;
2293 TcorePending *pending = NULL;
2294 const struct treq_sms_save_msg *saveMsg = NULL;
2295 int ScLength = 0, pdu_len = 0, stat = 0;
2296 char buf[2*(SMS_SMSP_ADDRESS_LEN+SMS_SMDATA_SIZE_MAX)+1] = {0};
2297 char *hex_pdu = NULL;
2301 saveMsg = tcore_user_request_ref_data(ur, NULL);
2302 hal = tcore_object_get_hal(obj);
2303 if (NULL == saveMsg || NULL == hal) {
2304 err("NULL input. Unable to proceed");
2305 dbg("saveMsg: [%p], hal: [%p]", saveMsg, hal);
2308 return TCORE_RETURN_EINVAL;
2310 if(FALSE == tcore_hal_get_power_state(hal)){
2311 dbg("cp not ready/n");
2312 return TCORE_RETURN_ENOSYS;
2315 dbg("msgStatus: %x, msgLength: [%d]", saveMsg->msgStatus, saveMsg->msgDataPackage.msgLength);
2316 util_hex_dump(" ", (SMS_SMDATA_SIZE_MAX+1), (void *)saveMsg->msgDataPackage.tpduData);
2317 util_hex_dump(" ", SMS_SMSP_ADDRESS_LEN, (void *)saveMsg->msgDataPackage.sca);
2319 switch (saveMsg->msgStatus) {
2320 case SMS_STATUS_READ:
2324 case SMS_STATUS_UNREAD:
2325 stat = AT_REC_UNREAD;
2328 case SMS_STATUS_SENT:
2332 case SMS_STATUS_UNSENT:
2333 stat = AT_STO_UNSENT;
2337 err("Invalid msgStatus");
2339 return TCORE_RETURN_EINVAL;
2342 if ((saveMsg->msgDataPackage.msgLength > 0)
2343 && (saveMsg->msgDataPackage.msgLength <= SMS_SMDATA_SIZE_MAX)) {
2344 ScLength = (int)saveMsg->msgDataPackage.sca[0];
2347 dbg("ScLength = %d", ScLength);
2352 memcpy(&buf[1], saveMsg->msgDataPackage.sca, ScLength);
2355 memcpy(&buf[ScLength+1], saveMsg->msgDataPackage.tpduData, saveMsg->msgDataPackage.msgLength);
2357 pdu_len= saveMsg->msgDataPackage.msgLength + ScLength + 1;
2358 dbg("pdu_len: [%d]", pdu_len);
2360 hex_pdu = malloc(pdu_len * 2 + 1);
2361 util_hex_dump(" ", sizeof(buf), (void *)buf);
2363 memset (hex_pdu, 0x00, pdu_len * 2 + 1);
2365 util_byte_to_hex((const char *)buf, (char *)hex_pdu, pdu_len);
2367 //AT+CMGW=<length>[,<stat>]<CR>PDU is given<ctrl-Z/ESC>
2368 cmd_str = g_strdup_printf("AT+CMGW=%d,%d%s%s\x1A", saveMsg->msgDataPackage.msgLength, stat, "\r", hex_pdu);
2369 pending = tcore_pending_new(obj, 0);
2370 atreq = tcore_at_request_new((const char *)cmd_str, "+CMGW", TCORE_AT_SINGLELINE);
2372 if(NULL == cmd_str || NULL == atreq || NULL == pending) {
2373 err("Out of memory. Unable to proceed");
2374 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
2376 //free memory we own
2378 util_sms_free_memory(atreq);
2379 util_sms_free_memory(pending);
2380 util_sms_free_memory(hex_pdu);
2383 return TCORE_RETURN_ENOMEM;
2386 util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
2388 tcore_pending_set_request_data(pending, 0, atreq);
2389 tcore_pending_set_response_callback(pending, on_response_sms_save_msg, NULL);
2390 tcore_pending_link_user_request(pending, ur);
2391 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
2392 tcore_hal_send_request(hal, pending);
2398 return TCORE_RETURN_SUCCESS;
2401 err("Invalid Data len");
2403 return TCORE_RETURN_SMS_INVALID_DATA_LEN;
2406 static TReturn delete_msg(CoreObject *obj, UserRequest *ur)
2408 gchar *cmd_str = NULL;
2409 TcoreHal *hal = NULL;
2410 TcoreATRequest *atreq = NULL;
2411 TcorePending *pending = NULL;
2412 const struct treq_sms_delete_msg *delete_msg = NULL;
2416 delete_msg = tcore_user_request_ref_data(ur, NULL);
2417 hal = tcore_object_get_hal(obj);
2418 if (NULL == delete_msg || NULL == hal) {
2419 err("NULL input. Unable to proceed");
2420 dbg("deleteMsg: [%p], hal: [%p]", delete_msg, hal);
2423 return TCORE_RETURN_EINVAL;
2426 if(FALSE == tcore_hal_get_power_state(hal)){
2427 dbg("cp not ready/n");
2428 return TCORE_RETURN_ENOSYS;
2431 dbg("index: %d", delete_msg->index);
2433 if (delete_msg->index == -1) {
2434 cmd_str = g_strdup_printf("AT+CMGD=0,4"); // Delete All Messages
2436 cmd_str = g_strdup_printf("AT+CMGD=%d,0", delete_msg->index + 1); // Delete specified index
2439 pending = tcore_pending_new(obj, 0);
2440 atreq = tcore_at_request_new((const char *)cmd_str, NULL, TCORE_AT_NO_RESULT);
2441 if (NULL == cmd_str || NULL == atreq || NULL == pending) {
2442 err("Out of memory. Unable to proceed");
2443 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
2445 //free memory we own
2447 util_sms_free_memory(atreq);
2448 util_sms_free_memory(pending);
2451 return TCORE_RETURN_ENOMEM;
2454 util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
2456 tcore_pending_set_request_data(pending, 0, atreq);
2457 tcore_pending_set_response_callback(pending, on_response_sms_delete_msg, (void *) (uintptr_t) (delete_msg->index)); // storing index as user data for response
2458 tcore_pending_link_user_request(pending, ur);
2459 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
2460 tcore_hal_send_request(hal, pending);
2465 return TCORE_RETURN_SUCCESS;
2468 static TReturn get_stored_msg_cnt(CoreObject *obj, UserRequest *ur)
2470 gchar *cmd_str = NULL;
2471 TcoreHal *hal = NULL;
2472 TcoreATRequest *atreq = NULL;
2473 TcorePending *pending = NULL;
2477 hal = tcore_object_get_hal(obj);
2479 err("NULL HAL. Unable to proceed");
2482 return TCORE_RETURN_EINVAL;
2485 if(FALSE == tcore_hal_get_power_state(hal)){
2486 dbg("cp not ready/n");
2487 return TCORE_RETURN_ENOSYS;
2490 cmd_str = g_strdup_printf("AT+CPMS=\"SM\"");
2491 pending = tcore_pending_new(obj, 0);
2492 atreq = tcore_at_request_new((const char *)cmd_str, "+CPMS", TCORE_AT_SINGLELINE);
2494 if (NULL == cmd_str || NULL == atreq || NULL == pending) {
2495 err("Out of memory. Unable to proceed");
2496 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
2498 //free memory we own
2500 util_sms_free_memory(atreq);
2501 util_sms_free_memory(pending);
2504 return TCORE_RETURN_ENOMEM;
2507 util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
2509 tcore_pending_set_request_data(pending, 0, atreq);
2510 tcore_pending_set_response_callback(pending, on_response_get_stored_msg_cnt, NULL);
2511 tcore_pending_link_user_request(pending, ur);
2512 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
2513 tcore_hal_send_request(hal, pending);
2518 return TCORE_RETURN_SUCCESS;
2521 static TReturn get_sca(CoreObject *obj, UserRequest *ur)
2523 gchar * cmd_str = NULL;
2524 TcoreHal *hal = NULL;
2525 TcoreATRequest *atreq = NULL;
2526 TcorePending *pending = NULL;
2530 hal = tcore_object_get_hal(obj);
2532 err("HAL NULL. Unable to proceed");
2535 return TCORE_RETURN_EINVAL;
2537 if(FALSE == tcore_hal_get_power_state(hal)){
2538 dbg("cp not ready/n");
2539 return TCORE_RETURN_ENOSYS;
2542 cmd_str = g_strdup_printf("AT+CSCA?");
2543 pending = tcore_pending_new(obj, 0);
2544 atreq = tcore_at_request_new((const char *)cmd_str, "+CSCA", TCORE_AT_SINGLELINE);
2546 if (NULL == cmd_str || NULL == atreq || NULL == pending) {
2547 err("Out of memory. Unable to proceed");
2548 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
2550 //free memory we own
2552 util_sms_free_memory(atreq);
2553 util_sms_free_memory(pending);
2556 return TCORE_RETURN_ENOMEM;
2559 util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
2561 tcore_pending_set_request_data(pending, 0, atreq);
2562 tcore_pending_set_response_callback(pending, on_response_get_sca, NULL);
2563 tcore_pending_link_user_request(pending, ur);
2564 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
2565 tcore_hal_send_request(hal, pending);
2570 return TCORE_RETURN_SUCCESS;
2573 static TReturn set_sca(CoreObject *obj, UserRequest *ur)
2575 gchar *cmd_str = NULL;
2576 TcoreHal *hal = NULL;
2577 TcoreATRequest *atreq = NULL;
2578 TcorePending *pending = NULL;
2579 const struct treq_sms_set_sca *setSca = NULL;
2584 setSca = tcore_user_request_ref_data(ur, NULL);
2585 hal = tcore_object_get_hal(obj);
2586 if (NULL == setSca || NULL == hal) {
2587 err("NULL input. Unable to proceed");
2588 dbg("setSca: [%p], hal: [%p]", setSca, hal);
2591 return TCORE_RETURN_EINVAL;
2593 if(FALSE == tcore_hal_get_power_state(hal)){
2594 dbg("cp not ready/n");
2595 return TCORE_RETURN_ENOSYS;
2598 dbg("dialNumLen: %u, typeOfNum: %d, numPlanId: %d, ", setSca->scaInfo.dialNumLen, setSca->scaInfo.typeOfNum, setSca->scaInfo.numPlanId);
2600 util_hex_dump(" ", (SMS_SMSP_ADDRESS_LEN+1), (void *)setSca->scaInfo.diallingNum);
2602 addrType = ((setSca->scaInfo.typeOfNum << 4) | setSca->scaInfo.numPlanId) | 0x80;
2604 cmd_str = g_strdup_printf("AT+CSCA=\"%s\",%d", setSca->scaInfo.diallingNum, addrType);
2605 pending = tcore_pending_new(obj, 0);
2606 atreq = tcore_at_request_new((const char *)cmd_str, NULL, TCORE_AT_NO_RESULT);
2608 if (NULL == cmd_str || NULL == atreq || NULL == pending) {
2609 err("Out of memory. Unable to proceed");
2610 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
2612 //free memory we own
2614 util_sms_free_memory(atreq);
2615 util_sms_free_memory(pending);
2618 return TCORE_RETURN_ENOMEM;
2621 util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
2623 tcore_pending_set_request_data(pending, 0, atreq);
2624 tcore_pending_set_response_callback(pending, on_response_set_sca, NULL);
2625 tcore_pending_link_user_request(pending, ur);
2626 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
2627 tcore_hal_send_request(hal, pending);
2632 return TCORE_RETURN_SUCCESS;
2635 static TReturn get_cb_config(CoreObject *obj, UserRequest *ur)
2637 gchar *cmd_str = NULL;
2638 TcoreHal *hal = NULL;
2639 TcoreATRequest *atreq = NULL;
2640 TcorePending *pending = NULL;
2644 hal = tcore_object_get_hal(obj);
2646 err("NULL HAL. Unable to proceed");
2649 return TCORE_RETURN_EINVAL;
2651 if(FALSE == tcore_hal_get_power_state(hal)){
2652 dbg("cp not ready/n");
2653 return TCORE_RETURN_ENOSYS;
2656 cmd_str = g_strdup_printf("AT+CSCB?");
2657 pending = tcore_pending_new(obj, 0);
2658 atreq = tcore_at_request_new((const char *)cmd_str, "+CSCB", TCORE_AT_SINGLELINE);
2659 if (NULL == cmd_str || NULL == atreq || NULL == pending) {
2660 err("Out of memory. Unable to proceed");
2661 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
2663 //free memory we own
2665 util_sms_free_memory(atreq);
2666 util_sms_free_memory(pending);
2669 return TCORE_RETURN_ENOMEM;
2672 util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
2674 tcore_pending_set_request_data(pending, 0, atreq);
2675 tcore_pending_set_response_callback(pending, on_response_get_cb_config, NULL);
2676 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
2677 tcore_pending_link_user_request(pending, ur);
2678 tcore_hal_send_request(hal, pending);
2683 return TCORE_RETURN_SUCCESS;
2686 static TReturn set_cb_config(CoreObject *obj, UserRequest *ur)
2688 gchar *cmd_str = NULL;
2689 gchar *mids_str = NULL;
2690 GString *mids_GString = NULL;
2692 TcoreHal *hal = NULL;
2693 TcoreATRequest *atreq = NULL;
2694 TcorePending *pending = NULL;
2695 const struct treq_sms_set_cb_config *setCbConfig = NULL;
2696 int ctr1= 0, ctr2 =0;
2697 unsigned short appendMsgId = 0;
2701 setCbConfig = tcore_user_request_ref_data(ur, NULL);
2702 hal = tcore_object_get_hal(obj);
2703 if (NULL == setCbConfig || NULL == hal) {
2704 err("NULL input. Unable to proceed");
2705 dbg("setCbConfig: [%p], hal: [%p]", setCbConfig, hal);
2708 return TCORE_RETURN_EINVAL;
2710 if(FALSE == tcore_hal_get_power_state(hal)){
2711 dbg("cp not ready/n");
2712 return TCORE_RETURN_ENOSYS;
2715 dbg("bCBEnabled: %d, msgIdCount: %d", setCbConfig->cbEnabled, setCbConfig->msgIdRangeCount);
2717 if (setCbConfig->cbEnabled == 2) { //Enable all CBS
2718 cmd_str = g_strdup_printf("AT+CSCB=1");
2719 } else if ((setCbConfig->cbEnabled == 1) && (setCbConfig->msgIdRangeCount == 0)) { // Special case: Enable all CBS
2720 cmd_str = g_strdup_printf("AT+CSCB=1");
2721 } else if (setCbConfig->cbEnabled == 0) {//AT+CSCB=0: Disable CBS
2722 cmd_str = g_strdup_printf("AT+CSCB=0");
2724 mids_GString = g_string_new("AT+CSCB=0,\"");
2726 for(ctr1 = 0; ctr1 < setCbConfig->msgIdRangeCount; ctr1++ ) {
2727 if( setCbConfig->msgIDs[ctr1].net3gpp.selected == FALSE )
2730 if( SMS_GSM_SMS_CBMI_LIST_SIZE_MAX <= (setCbConfig->msgIDs[ctr1].net3gpp.toMsgId - setCbConfig->msgIDs[ctr1].net3gpp.fromMsgId) ) {
2731 mids_GString = g_string_new("AT+CSCB=1");
2735 appendMsgId = setCbConfig->msgIDs[ctr1].net3gpp.fromMsgId;
2737 for( ctr2 = 0; (ctr2 <= ((setCbConfig->msgIDs[ctr1].net3gpp.toMsgId) - (setCbConfig->msgIDs[ctr1].net3gpp.fromMsgId))); ctr2++ ) {
2738 dbg( "%x", appendMsgId);
2739 mids_GString = g_string_append(mids_GString, g_strdup_printf("%d", appendMsgId));
2741 if (ctr2 == ((setCbConfig->msgIDs[ctr1].net3gpp.toMsgId) - (setCbConfig->msgIDs[ctr1].net3gpp.fromMsgId))) {
2742 mids_GString = g_string_append(mids_GString, "\""); //Mids string termination
2744 mids_GString = g_string_append(mids_GString, ",");
2750 mids_str = g_string_free(mids_GString, FALSE);
2751 cmd_str = g_strdup_printf("%s", mids_str);
2755 pending = tcore_pending_new(obj, 0);
2756 atreq = tcore_at_request_new((const char *)cmd_str, NULL, TCORE_AT_NO_RESULT);
2757 if(NULL == cmd_str || NULL == atreq || NULL == pending) {
2758 err("Out of memory. Unable to proceed");
2759 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
2761 //free memory we own
2763 util_sms_free_memory(atreq);
2764 util_sms_free_memory(pending);
2767 return TCORE_RETURN_ENOMEM;
2770 util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
2772 tcore_pending_set_request_data(pending, 0, atreq);
2773 tcore_pending_set_response_callback(pending, on_response_set_cb_config, NULL);
2774 tcore_pending_link_user_request(pending, ur);
2775 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
2776 tcore_hal_send_request(hal, pending);
2781 return TCORE_RETURN_SUCCESS;
2784 static TReturn set_mem_status(CoreObject *obj, UserRequest *ur)
2786 gchar *cmd_str = NULL;
2787 TcoreHal *hal = NULL;
2788 TcoreATRequest *atreq = NULL;
2789 TcorePending *pending = NULL;
2790 const struct treq_sms_set_mem_status *setMemStatus = NULL;
2791 int memoryStatus = 0;
2795 setMemStatus = tcore_user_request_ref_data(ur, NULL);
2796 hal = tcore_object_get_hal(obj);
2797 if (NULL == setMemStatus || NULL == hal) {
2798 err("NULL input. Unable to proceed");
2799 dbg("setMemStatus: [%p], hal: [%p]", setMemStatus, hal);
2802 return TCORE_RETURN_EINVAL;
2804 if(FALSE == tcore_hal_get_power_state(hal)){
2805 dbg("cp not ready/n");
2806 return TCORE_RETURN_ENOSYS;
2809 dbg("memory_status: %d", setMemStatus->memory_status);
2811 if(setMemStatus->memory_status < SMS_PDA_MEMORY_STATUS_AVAILABLE
2812 || setMemStatus->memory_status > SMS_PDA_MEMORY_STATUS_FULL) {
2813 err("Invalid memory_status");
2816 return TCORE_RETURN_EINVAL;
2819 switch (setMemStatus->memory_status) {
2820 case SMS_PDA_MEMORY_STATUS_AVAILABLE:
2821 memoryStatus = AT_MEMORY_AVAILABLE;
2824 case SMS_PDA_MEMORY_STATUS_FULL:
2825 memoryStatus = AT_MEMORY_FULL;
2829 err("Invalid memory_status");
2831 return TCORE_RETURN_EINVAL;
2834 cmd_str = g_strdup_printf("AT+XTESM=%d", memoryStatus);
2835 pending = tcore_pending_new(obj, 0);
2836 atreq = tcore_at_request_new((const char *)cmd_str, NULL, TCORE_AT_NO_RESULT);
2838 if (NULL == cmd_str || NULL == atreq || NULL == pending) {
2839 err("Out of memory. Unable to proceed");
2840 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
2842 //free memory we own
2844 util_sms_free_memory(atreq);
2845 util_sms_free_memory(pending);
2848 return TCORE_RETURN_ENOMEM;
2851 util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
2853 tcore_pending_set_request_data(pending, 0, atreq);
2854 tcore_pending_set_response_callback(pending, on_response_set_mem_status, NULL);
2855 tcore_pending_link_user_request(pending, ur);
2856 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
2857 tcore_hal_send_request(hal, pending);
2862 return TCORE_RETURN_SUCCESS;
2865 static TReturn set_delivery_report(CoreObject *obj, UserRequest *ur)
2867 struct tresp_sms_set_delivery_report respSetDeliveryReport = {0,};
2869 respSetDeliveryReport.result = SMS_SUCCESS;
2872 if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(obj))){
2873 dbg("cp not ready/n");
2874 return TCORE_RETURN_ENOSYS;
2877 dbg("CP takes care of sending SMS ack to network for all classes of SMS. Sending default success.");
2879 tcore_user_request_send_response(ur, TRESP_SMS_SET_DELIVERY_REPORT, sizeof(struct tresp_sms_set_delivery_report), &respSetDeliveryReport);
2882 return TCORE_RETURN_SUCCESS;
2885 static TReturn set_msg_status(CoreObject *obj, UserRequest *ur)
2887 gchar *cmd_str = NULL;
2888 TcoreHal *hal = NULL;
2889 TcoreATRequest *atreq = NULL;
2890 TcorePending *pending = NULL;
2891 const struct treq_sms_set_msg_status *msg_status = NULL;
2894 hal = tcore_object_get_hal(obj);
2895 if(FALSE == tcore_hal_get_power_state(hal)){
2896 dbg("cp not ready/n");
2897 return TCORE_RETURN_ENOSYS;
2899 msg_status = tcore_user_request_ref_data(ur, NULL);
2901 cmd_str = g_strdup_printf("AT+CRSM=178,28476,%d,4,%d", (msg_status->index+1), PDU_LEN_MAX);
2902 atreq = tcore_at_request_new((const char *)cmd_str, "+CRSM", TCORE_AT_SINGLELINE);
2903 pending = tcore_pending_new(obj, 0);
2904 if (NULL == cmd_str || NULL == atreq || NULL == pending) {
2905 err("Out of memory. Unable to proceed");
2906 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
2908 //free memory we own
2910 util_sms_free_memory(atreq);
2911 util_sms_free_memory(pending);
2914 return TCORE_RETURN_ENOMEM;
2917 util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
2919 tcore_pending_set_request_data(pending, 0, atreq);
2920 tcore_pending_set_response_callback(pending, _response_get_efsms_data, NULL);
2921 tcore_pending_link_user_request(pending, ur);
2922 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
2923 tcore_hal_send_request(hal, pending);
2928 return TCORE_RETURN_SUCCESS;
2931 static TReturn get_sms_params(CoreObject *obj, UserRequest *ur)
2933 gchar *cmd_str = NULL;
2934 TcoreHal *hal = NULL;
2935 TcoreATRequest *atreq = NULL;
2936 TcorePending *pending = NULL;
2937 const struct treq_sms_get_params *getSmsParams = NULL;
2938 int record_len = 0 , *smsp_record_len = NULL;
2942 getSmsParams = tcore_user_request_ref_data(ur, NULL);
2943 hal = tcore_object_get_hal(obj);
2944 if (NULL == getSmsParams || NULL == hal) {
2945 err("NULL input. Unable to proceed");
2946 dbg("getSmsParams: [%p], hal: [%p]", getSmsParams, hal);
2949 return TCORE_RETURN_EINVAL;
2951 if(FALSE == tcore_hal_get_power_state(hal)){
2952 dbg("cp not ready/n");
2953 return TCORE_RETURN_ENOSYS;
2956 smsp_record_len = tcore_plugin_ref_property(tcore_object_ref_plugin(obj), "SMSPRECORDLEN");
2957 record_len = *smsp_record_len;
2958 dbg("record len from property %d", record_len);
2960 //AT+CRSM=command>[,<fileid>[,<P1>,<P2>,<P3>[,<data>[,<pathid>]]]]
2961 cmd_str = g_strdup_printf("AT+CRSM=178,28482,%d,4,%d", (getSmsParams->index + 1), record_len);
2963 dbg("cmd_str is %s",cmd_str);
2965 atreq = tcore_at_request_new((const char *)cmd_str, "+CRSM", TCORE_AT_SINGLELINE);
2966 pending = tcore_pending_new(obj, 0);
2967 if (NULL == cmd_str || NULL == atreq || NULL == pending) {
2968 err("Out of memory. Unable to proceed");
2969 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
2971 //free memory we own
2973 util_sms_free_memory(atreq);
2974 util_sms_free_memory(pending);
2977 return TCORE_RETURN_ENOMEM;
2980 util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
2982 tcore_pending_set_request_data(pending, 0, atreq);
2983 tcore_pending_set_response_callback(pending, on_response_get_sms_params, NULL);
2984 tcore_pending_link_user_request(pending, ur);
2985 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
2986 tcore_hal_send_request(hal, pending);
2991 return TCORE_RETURN_SUCCESS;
2994 static TReturn set_sms_params(CoreObject *obj, UserRequest *ur)
2996 gchar *cmd_str = NULL;
2997 char *encoded_data = NULL;
2998 unsigned char *temp_data = NULL;
2999 int SMSPRecordLen = 0;
3000 int *smsp_record_len;
3002 TcoreHal *hal = NULL;
3003 TcoreATRequest *atreq = NULL;
3004 TcorePending *pending = NULL;
3005 const struct treq_sms_set_params *setSmsParams = NULL;
3006 int encoded_data_len = 0;
3010 setSmsParams = tcore_user_request_ref_data(ur, NULL);
3011 hal = tcore_object_get_hal(obj);
3012 if (NULL == setSmsParams || NULL == hal) {
3013 err("NULL input. Unable to proceed");
3014 dbg("setSmsParams: [%p], hal: [%p]", setSmsParams, hal);
3017 if(FALSE == tcore_hal_get_power_state(hal)){
3018 dbg("cp not ready/n");
3019 return TCORE_RETURN_ENOSYS;
3022 //EFsmsp file size is 28 +Y bytes (Y is alpha id size)
3023 smsp_record_len = tcore_plugin_ref_property(tcore_object_ref_plugin(obj), "SMSPRECORDLEN");
3024 SMSPRecordLen = *smsp_record_len;
3025 if (SMSPRecordLen < nDefaultSMSPWithoutAlphaId)
3028 temp_data = calloc(SMSPRecordLen,1);
3029 encoded_data = calloc(SMSPRecordLen*2 + 1,1);
3031 _tcore_util_sms_encode_smsParameters(&(setSmsParams->params), temp_data, SMSPRecordLen);
3033 util_byte_to_hex((const char *)temp_data, (char *)encoded_data,SMSPRecordLen);
3035 encoded_data_len = ((SMSPRecordLen) * 2);
3037 hal = tcore_object_get_hal(obj);
3038 pending = tcore_pending_new(obj, 0);
3040 dbg("alpha id len %d encoded data %s. Encoded data len %d",setSmsParams->params.alphaIdLen,encoded_data, encoded_data_len);
3041 cmd_str = g_strdup_printf("AT+CRSM=220,28482,%d,4,%d,\"%s\"",(setSmsParams->params.recordIndex+1),SMSPRecordLen,encoded_data);
3043 dbg("cmd str is %s",cmd_str);
3044 atreq = tcore_at_request_new(cmd_str, "+CRSM:", TCORE_AT_SINGLELINE);
3046 if (NULL == cmd_str || NULL == atreq || NULL == pending) {
3047 err("Out of memory. Unable to proceed");
3048 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
3050 //free memory we own
3052 util_sms_free_memory(atreq);
3053 util_sms_free_memory(pending);
3055 util_sms_free_memory(temp_data);
3056 util_sms_free_memory(encoded_data);
3059 return TCORE_RETURN_ENOMEM;
3062 util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
3064 tcore_pending_set_request_data(pending, 0,atreq);
3065 tcore_pending_set_response_callback(pending, on_response_set_sms_params, NULL);
3066 tcore_pending_link_user_request(pending, ur);
3067 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
3068 tcore_hal_send_request(hal, pending);
3071 util_sms_free_memory(temp_data);
3072 util_sms_free_memory(encoded_data);
3074 return TCORE_RETURN_SUCCESS;
3077 static TReturn get_paramcnt(CoreObject *obj, UserRequest *ur)
3079 gchar *cmd_str = NULL;
3080 TcoreHal *hal = NULL;
3081 TcoreATRequest *atreq = NULL;
3082 TcorePending *pending = NULL;
3086 hal = tcore_object_get_hal(obj);
3088 err("NULL HAL. Unable to proceed");
3091 return TCORE_RETURN_EINVAL;
3093 if(FALSE == tcore_hal_get_power_state(hal)){
3094 dbg("cp not ready/n");
3095 return TCORE_RETURN_ENOSYS;
3098 //AT+CRSM=command>[,<fileid>[,<P1>,<P2>,<P3>[,<data>[,<pathid>]]]]
3099 cmd_str = g_strdup_printf("AT+CRSM=192,28482");
3100 atreq = tcore_at_request_new((const char *)cmd_str, "+CRSM", TCORE_AT_SINGLELINE);
3101 pending = tcore_pending_new(obj, 0);
3103 if (NULL == cmd_str || NULL == atreq || NULL == pending) {
3104 err("NULL pointer. Unable to proceed");
3105 dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
3107 //free memory we own
3109 util_sms_free_memory(atreq);
3110 util_sms_free_memory(pending);
3113 return TCORE_RETURN_FAILURE;
3116 util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
3118 tcore_pending_set_request_data(pending, 0, atreq);
3119 tcore_pending_set_response_callback(pending, on_response_get_paramcnt, NULL);
3120 tcore_pending_link_user_request(pending, ur);
3121 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
3122 tcore_hal_send_request(hal, pending);
3127 return TCORE_RETURN_SUCCESS;
3130 static struct tcore_sms_operations sms_ops = {
3131 .send_umts_msg = send_umts_msg,
3132 .read_msg = read_msg,
3133 .save_msg = save_msg,
3134 .delete_msg = delete_msg,
3135 .get_stored_msg_cnt = get_stored_msg_cnt,
3138 .get_cb_config = get_cb_config,
3139 .set_cb_config = set_cb_config,
3140 .set_mem_status = set_mem_status,
3141 .get_pref_brearer = NULL,
3142 .set_pref_brearer = NULL,
3143 .set_delivery_report = set_delivery_report,
3144 .set_msg_status = set_msg_status,
3145 .get_sms_params = get_sms_params,
3146 .set_sms_params = set_sms_params,
3147 .get_paramcnt = get_paramcnt,
3150 gboolean s_sms_init(TcorePlugin *cp, CoreObject *co_sms)
3152 int *smsp_record_len;
3155 /* Override SMS Operations */
3156 tcore_sms_override_ops(co_sms, &sms_ops);
3158 /* Registering for SMS notifications */
3159 tcore_object_override_callback(co_sms, "+CMTI:", on_event_class2_sms_incom_msg, NULL);
3160 tcore_object_override_callback(co_sms, "\e+CMT:", on_event_sms_incom_msg, NULL);
3162 tcore_object_override_callback(co_sms, "\e+CDS", on_event_sms_incom_msg, NULL);
3163 tcore_object_override_callback(co_sms, "+XSMSMMSTAT", on_event_sms_memory_status, NULL);
3164 tcore_object_override_callback(co_sms, "+CMS", on_event_sms_memory_status, NULL);
3166 tcore_object_override_callback(co_sms, "+CBMI:", on_event_sms_cb_incom_msg, NULL);
3167 tcore_object_override_callback(co_sms, "\e+CBM:", on_event_sms_cb_incom_msg, NULL);
3169 /* Storing SMSP record length */
3170 smsp_record_len = g_new0(int, 1);
3171 tcore_plugin_link_property(cp, "SMSPRECORDLEN", smsp_record_len);
3177 void s_sms_exit(TcorePlugin *cp, CoreObject *co_sms)
3179 int *smsp_record_len;
3181 smsp_record_len = tcore_plugin_ref_property(cp, "SMSPRECORDLEN");
3182 g_free(smsp_record_len);