2 * tel-plugin-samsung-atmodem
4 * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Hayoon Ko <hayoon.ko@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.
29 #include <core_object.h>
34 #include <user_request.h>
41 #include "atchannel.h"
44 #define MAX_GSM_SMS_TPDU_SIZE 244
45 #define MAX_GSM_SMS_PARAM_RECORD_SIZE 156 /* Maximum number of bytes SMSP Record size (Y + 28), y : 0 ~ 128 */
46 #define SWAPBYTES16(x) \
48 unsigned short int data = *(unsigned short int*)&(x); \
49 data = ((data & 0xff00) >> 8) | \
50 ((data & 0x00ff) << 8); \
51 *(unsigned short int*)&(x) = data ; \
54 extern struct ATResponse *sp_response;
55 extern char *s_responsePrefix;
56 extern enum ATCommandType s_type;
58 static TReturn Send_SmsSubmitTpdu(CoreObject *o, UserRequest *ur);
60 /************************************************************/
61 /********************* Utility for SMS *************************/
62 /************************************************************/
63 static void util_sms_get_length_of_sca(int* nScLength) {
65 *nScLength = (*nScLength / 2) + 1;
67 *nScLength = *nScLength / 2;
73 static int util_sms_decode_smsParameters(unsigned char *incoming, unsigned int length, struct telephony_sms_Params *params)
79 dbg(" RecordLen = %d", length);
81 if(incoming == NULL || params == NULL)
84 alpha_id_len = length -SMS_SMSP_PARAMS_MAX_LEN;
86 if ( alpha_id_len > 0 )
88 if(alpha_id_len > SMS_SMSP_ALPHA_ID_LEN_MAX)
90 alpha_id_len = SMS_SMSP_ALPHA_ID_LEN_MAX;
93 for( i=0 ; i < alpha_id_len ; i++)
95 if( 0xff == incoming[i])
102 memcpy(params->szAlphaId, incoming, i);
104 params->alphaIdLen = i;
106 dbg(" Alpha id length = %d", i);
111 params->alphaIdLen = 0;
112 dbg(" Alpha id length is zero");
115 // start parse from here.
116 params->paramIndicator = incoming[alpha_id_len];
118 dbg(" Param Indicator = %02x", params->paramIndicator);
121 if( (params->paramIndicator & SMSPValidDestAddr) == 0)
123 nOffset = nDestAddrOffset;
125 if( 0x00 == incoming[alpha_id_len + nOffset] || 0xff == incoming[alpha_id_len + nOffset])
127 params->tpDestAddr.dialNumLen = 0;
129 dbg("DestAddr Length is 0");
133 if ( 0 < (int)incoming[alpha_id_len + nOffset] )
135 params->tpDestAddr.dialNumLen = (int)(incoming[alpha_id_len + nOffset] - 1 );
137 if(params->tpDestAddr.dialNumLen > SMS_SMSP_ADDRESS_LEN)
138 params->tpDestAddr.dialNumLen = SMS_SMSP_ADDRESS_LEN;
142 params->tpDestAddr.dialNumLen = 0;
145 params->tpDestAddr.numPlanId= incoming[alpha_id_len + (++nOffset)] & 0x0f ;
146 params->tpDestAddr.typeOfNum= (incoming[alpha_id_len + nOffset] & 0x70 )>>4 ;
148 memcpy( params->tpDestAddr.diallingNum, &incoming[alpha_id_len + (++nOffset)], (params->tpDestAddr.dialNumLen)) ;
150 dbg("Dest TON is %d",params->tpDestAddr.typeOfNum);
151 dbg("Dest NPI is %d",params->tpDestAddr.numPlanId);
152 dbg("Dest Length = %d",params->tpDestAddr.dialNumLen);
153 dbg("Dest Addr = %s",params->tpDestAddr.diallingNum);
159 if( (params->paramIndicator & SMSPValidSvcAddr) == 0)
161 nOffset = nSCAAddrOffset;
163 if( 0x00 == (int)incoming[alpha_id_len + nOffset] || 0xff == (int)incoming[alpha_id_len + nOffset] )
165 params->tpSvcCntrAddr.dialNumLen = 0;
167 dbg(" SCAddr Length is 0");
171 if ( 0 < (int)incoming[alpha_id_len + nOffset] )
173 params->tpSvcCntrAddr.dialNumLen = (int)(incoming[alpha_id_len + nOffset] - 1);
175 if(params->tpSvcCntrAddr.dialNumLen > SMS_SMSP_ADDRESS_LEN)
176 params->tpSvcCntrAddr.dialNumLen = SMS_SMSP_ADDRESS_LEN;
178 params->tpSvcCntrAddr.numPlanId= incoming[alpha_id_len + (++nOffset)] & 0x0f ;
179 params->tpSvcCntrAddr.typeOfNum= (incoming[alpha_id_len + nOffset] & 0x70) >>4 ;
181 memcpy( params->tpSvcCntrAddr.diallingNum, &incoming[alpha_id_len + (++nOffset)], (params->tpSvcCntrAddr.dialNumLen));
183 dbg("SCAddr Length = %d ",params->tpSvcCntrAddr.dialNumLen);
184 dbg("SCAddr TON is %d",params->tpSvcCntrAddr.typeOfNum);
185 dbg("SCAddr NPI is %d",params->tpSvcCntrAddr.numPlanId);
187 for( i = 0 ; i < (int)params->tpSvcCntrAddr.dialNumLen ; i ++)
188 dbg("SCAddr = %d [%02x]",i,params->tpSvcCntrAddr.diallingNum[i]);
192 params->tpSvcCntrAddr.dialNumLen = 0;
196 else if ( (0x00 < (int)incoming[alpha_id_len +nSCAAddrOffset] && (int)incoming[alpha_id_len +nSCAAddrOffset] <= 12 )
197 || 0xff != (int)incoming[alpha_id_len +nSCAAddrOffset])
199 nOffset = nSCAAddrOffset;
201 if( 0x00 == (int)incoming[alpha_id_len + nOffset] || 0xff == (int)incoming[alpha_id_len + nOffset] )
203 params->tpSvcCntrAddr.dialNumLen = 0;
204 dbg("SCAddr Length is 0");
209 if ( 0 < (int)incoming[alpha_id_len + nOffset] )
211 params->tpSvcCntrAddr.dialNumLen = (int)(incoming[alpha_id_len + nOffset] - 1);
213 params->tpSvcCntrAddr.dialNumLen = incoming[alpha_id_len + nOffset] -1;
215 if(params->tpSvcCntrAddr.dialNumLen > SMS_SMSP_ADDRESS_LEN)
216 params->tpSvcCntrAddr.dialNumLen = SMS_SMSP_ADDRESS_LEN;
218 params->tpSvcCntrAddr.numPlanId= incoming[alpha_id_len + (++nOffset)] & 0x0f ;
219 params->tpSvcCntrAddr.typeOfNum= (incoming[alpha_id_len + nOffset] & 0x70) >>4 ;
221 memcpy( params->tpSvcCntrAddr.diallingNum, &incoming[alpha_id_len + (++nOffset)],
222 (params->tpSvcCntrAddr.dialNumLen)) ;
224 dbg("SCAddr Length = %d ",params->tpSvcCntrAddr.dialNumLen);
225 dbg("SCAddr TON is %d",params->tpSvcCntrAddr.typeOfNum);
226 dbg("SCAddr NPI is %d",params->tpSvcCntrAddr.numPlanId);
228 for( i = 0 ; i < (int)params->tpSvcCntrAddr.dialNumLen ; i ++)
229 dbg("SCAddr = %d [%02x]",i,params->tpSvcCntrAddr.diallingNum[i]);
233 params->tpSvcCntrAddr.dialNumLen = 0;
239 if( (params->paramIndicator & SMSPValidPID) == 0 && (alpha_id_len + nPIDOffset) < MAX_GSM_SMS_PARAM_RECORD_SIZE)
241 params->tpProtocolId = incoming[alpha_id_len + nPIDOffset];
243 if( (params->paramIndicator & SMSPValidDCS) == 0 && (alpha_id_len + nDCSOffset) < MAX_GSM_SMS_PARAM_RECORD_SIZE)
245 params->tpDataCodingScheme = incoming[alpha_id_len + nDCSOffset];
247 if( (params->paramIndicator & SMSPValidVP) == 0 && (alpha_id_len + nVPOffset) < MAX_GSM_SMS_PARAM_RECORD_SIZE)
249 params->tpValidityPeriod = incoming[alpha_id_len + nVPOffset];
252 dbg(" Alpha Id(Len) = %d",(int)params->alphaIdLen);
254 for (i=0; i< (int)params->alphaIdLen ; i++)
256 dbg(" Alpha Id = [%d] [%c]",i,params->szAlphaId[i]);
258 dbg(" PID = %d",params->tpProtocolId);
259 dbg(" DCS = %d",params->tpDataCodingScheme);
260 dbg(" VP = %d",params->tpValidityPeriod);
265 static int util_sms_ipcError2SmsError(int err)
271 case 300: //ME Failure;
272 returnStatus = SMS_PHONE_FAILURE;
274 case 302: //Operation not allowed;
275 case 303: //Operation not supported;
276 returnStatus = SMS_OPERATION_NOT_SUPPORTED;
278 case 304: //Invalid PDU mode parameter;
279 case 305: //Invalid text mode parameter;
280 returnStatus = SMS_INVALID_PARAMETER_FORMAT;
282 case 320: //memory failure;
283 case 321: //invalid memory index;
284 case 322: //memory full;
285 returnStatus = SMS_MEMORY_FAILURE;
287 case 330: //SCA unknown;
288 case 500: //Unknown error;
290 returnStatus = SMS_UNKNOWN;
297 /************************************************************/
298 /************************ Events Cb *************************/
299 /************************************************************/
301 static gboolean on_event_sms_incom_msg(CoreObject *o, const void *event_info, void *user_data)
303 struct smsDeliveryPDU *smsPdu = (struct smsDeliveryPDU *)event_info;
304 struct property_sms_info *property;
305 struct tnoti_sms_umts_msg gsmMsgInfo;
307 int ScLength = 0, i = 0;
308 unsigned char LastSemiOctect;
310 memset(&gsmMsgInfo, 0, sizeof(struct tnoti_sms_umts_msg));
311 // +CMT: <length><CR><LF><pdu>
312 ScLength = smsPdu->pdu[0];
314 dbg(" ScLength is %d",ScLength);
316 LastSemiOctect = smsPdu->pdu[ScLength + 1] & 0xf0;
317 if( LastSemiOctect == 0xf0 )
319 smsPdu->pdu[0] = (ScLength-1)*2 - 1;
323 smsPdu->pdu[0] = (ScLength-1)*2;
326 gsmMsgInfo.msgInfo.msgLength = smsPdu->len - ScLength;
327 dbg(" MSG LENGTH [%d]", gsmMsgInfo.msgInfo.msgLength);
329 if ( (gsmMsgInfo.msgInfo.msgLength >0) && (0xff >= gsmMsgInfo.msgInfo.msgLength))
331 property = tcore_plugin_ref_property(tcore_object_ref_plugin(o), "SMS");
333 dbg("property is NULL");
337 memcpy(gsmMsgInfo.msgInfo.sca, &smsPdu->pdu[0], (ScLength+1));
339 for(i=0;i<(ScLength+1);i++)
341 dbg("SCA is [%02x] ",gsmMsgInfo.msgInfo.sca[i]);
344 if(gsmMsgInfo.msgInfo.msgLength > SMS_SMDATA_SIZE_MAX)
346 gsmMsgInfo.msgInfo.msgLength = SMS_SMDATA_SIZE_MAX;
349 memcpy(gsmMsgInfo.msgInfo.tpduData, &smsPdu->pdu[ScLength +1], gsmMsgInfo.msgInfo.msgLength);
351 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);
356 dbg("Invalid Message Length");
362 static gboolean on_event_sms_device_ready(CoreObject *o, const void *event_info, void *user_data)
364 struct tnoti_sms_ready_status readyStatusInfo = {0,};
367 dbg(" Func Entrance");
368 readyStatusInfo.status = TRUE;
369 tcore_sms_set_ready_status(o, readyStatusInfo.status);
371 dbg("SMS Ready status = [%s]", readyStatusInfo.status ? "TRUE" : "FALSE");
373 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);
375 dbg(" Return value [%d]",rtn);
380 /*************************************************************/
381 /*********************** Responses Cb ************************/
382 /************************************************************/
383 static void on_confirmation_sms_message_send( TcorePending *p, gboolean result, void *user_data )
385 UserRequest* ur = NULL;
386 struct ATReqMetaInfo* metainfo = NULL;
387 unsigned int info_len =0;
388 dbg("on_confirmation_call_message_send - msg out from queue. alloc ATRsp buffer & write rspPrefix if needed\n");
390 ReleaseResponse(); //release leftover
392 sp_response = at_response_new();
394 ur = tcore_pending_ref_user_request(p);
395 metainfo = (struct ATReqMetaInfo*)tcore_user_request_ref_metainfo(ur,&info_len);
397 if((metainfo->type == SINGLELINE)||
398 (metainfo->type == MULTILINE))
401 s_responsePrefix = strdup(metainfo->responsePrefix);
402 dbg("duplicating responsePrefix : %s\n", s_responsePrefix);
406 s_responsePrefix = NULL;
409 //set atcmd type into s_type
410 s_type = metainfo->type;
412 if (result == FALSE) {
421 static void on_response_send_umts_msg(TcorePending *p, int data_len, const void *data, void *user_data)
424 struct tresp_sms_send_umts_msg respSendMsg;
430 memset(&respSendMsg, 0, sizeof(struct tresp_sms_send_umts_msg));
431 ur = tcore_pending_ref_user_request(p);
434 dbg("no user_request");
440 if(sp_response->success == TRUE)
443 ur = tcore_user_request_ref(ur);
444 ret = (int) Send_SmsSubmitTpdu(tcore_pending_ref_core_object(p), ur);
446 if(ret != (int)TCORE_RETURN_SUCCESS)
448 respSendMsg.result = SMS_INVALID_PARAMETER;
449 tcore_user_request_send_response(ur, TRESP_SMS_SEND_UMTS_MSG, sizeof(struct tresp_sms_send_umts_msg), &respSendMsg);
454 //failure case - consider this later
455 line = sp_response->finalResponse;
457 ret = at_tok_start(&line);
461 ret = at_tok_nextint(&line,&error);
465 respSendMsg.result = util_sms_ipcError2SmsError(error);
467 tcore_user_request_send_response(ur, TRESP_SMS_SEND_UMTS_MSG, sizeof(struct tresp_sms_send_umts_msg), &respSendMsg);
473 static void on_response_send_smsSubmitTpdu(TcorePending *p, int data_len, const void *data, void *user_data)
475 UserRequest *ur = NULL;
476 struct tresp_sms_send_umts_msg respUmtsInfo;
489 if(sp_response->success > 0)
491 line = sp_response->p_intermediates->line;
493 memset(&respUmtsInfo, 0 , sizeof(struct tresp_sms_send_umts_msg));
494 // +CMGS: <mr>[, <ackpdu>]
495 // SMS_SMDATA_SIZE_MAX + 1
496 ret = at_tok_start(&line);
500 ret = at_tok_nextint(&line, &mr);
504 ret = at_tok_nextstr(&line, &hexData);
507 dbg(" ackpdu is NULL ");
510 ackpdu = util_hexStringToBytes(hexData);
511 util_hex_dump(" ", strlen(hexData)/2, ackpdu);
514 dbg(" Func Entrance ");
516 ur = tcore_pending_ref_user_request(p);
519 memcpy(respUmtsInfo.dataInfo.sca, &cSCA, sizeof(char));
522 respUmtsInfo.dataInfo.msgLength = strlen(ackpdu);
524 respUmtsInfo.dataInfo.msgLength = 0;
527 if ( (respUmtsInfo.dataInfo.msgLength >= 0) && (0xff >= respUmtsInfo.dataInfo.msgLength))
529 if(respUmtsInfo.dataInfo.msgLength > SMS_SMDATA_SIZE_MAX)
531 respUmtsInfo.dataInfo.msgLength = SMS_SMDATA_SIZE_MAX;
534 memcpy(respUmtsInfo.dataInfo.tpduData, ackpdu, respUmtsInfo.dataInfo.msgLength);
537 dbg(" msg length : %d", respUmtsInfo.dataInfo.msgLength);
538 dbg(" TRESP_SMS_SEND_UMTS_MSG : 0x%x", TRESP_SMS_SEND_UMTS_MSG);
540 respUmtsInfo.result = SMS_SENDSMS_SUCCESS;
542 tcore_user_request_send_response(ur, TRESP_SMS_SEND_UMTS_MSG, sizeof(struct tresp_sms_send_umts_msg), &respUmtsInfo);
547 respUmtsInfo.result = SMS_INVALID_PARAMETER_FORMAT;
549 tcore_user_request_send_response(ur, TRESP_SMS_SEND_UMTS_MSG, sizeof(struct tresp_sms_send_umts_msg), &respUmtsInfo);
555 dbg("no user_request");
560 //failure case - consider this later
561 line = sp_response->finalResponse;
563 ret = at_tok_start(&line);
567 ret = at_tok_nextint(&line,&error);
572 //5. release sp_response & s_responsePrefix - before sending user callback, because user callback can request additional request
573 // and if queue is empty, that req can be directly sent to mdm - can cause sp_response, s_responsePrefix dangling
576 ur = tcore_pending_ref_user_request(p);
578 struct tresp_sms_send_umts_msg respSendMsg;
580 memset(&respSendMsg, 0, sizeof(struct tresp_sms_send_umts_msg));
581 respSendMsg.result = SMS_INVALID_MANDATORY_INFO;
583 respSendMsg.result = util_sms_ipcError2SmsError(error);
585 tcore_user_request_send_response(ur, TRESP_SMS_SEND_UMTS_MSG, sizeof(struct tresp_sms_send_umts_msg), &respSendMsg);
588 dbg("no user_request");
593 static void on_response_get_storedMsgCnt(TcorePending *p, int data_len, const void *data, void *user_data)
596 struct tresp_sms_get_storedMsgCnt respStoredMsgCnt;
604 memset(&respStoredMsgCnt, 0, sizeof(struct tresp_sms_get_storedMsgCnt));
605 ur = tcore_pending_ref_user_request(p);
608 dbg("no user_request");
614 if(sp_response->success > 0)
616 //failure case - consider this later
617 line = sp_response->p_intermediates->line;
619 ret = at_tok_start(&line);
623 ret = at_tok_nextint(&line,&usedCount);
626 ret = at_tok_nextint(&line,&totalCount);
630 respStoredMsgCnt.storedMsgCnt.totalCount = totalCount;
631 respStoredMsgCnt.storedMsgCnt.usedCount = usedCount;
633 dbg(" totalCount:%d, usedCount:%d",respStoredMsgCnt.storedMsgCnt.totalCount , respStoredMsgCnt.storedMsgCnt.usedCount );
635 respStoredMsgCnt.result = SMS_SUCCESS;
639 //failure case - consider this later
640 line = sp_response->finalResponse;
642 ret = at_tok_start(&line);
646 ret = at_tok_nextint(&line,&error);
650 respStoredMsgCnt.result = util_sms_ipcError2SmsError(error);
656 tcore_user_request_send_response(ur, TRESP_SMS_GET_STORED_MSG_COUNT, sizeof(struct tresp_sms_get_storedMsgCnt), &respStoredMsgCnt);
662 static void on_response_get_sca(TcorePending *p, int data_len, const void *data, void *user_data)
665 struct tresp_sms_get_sca respGetSca;
673 ur = tcore_pending_ref_user_request(p);
676 dbg("no user_request");
682 // +CSCA: <sca number>,<sca type>
683 if(sp_response->success > 0)
685 respGetSca.result = SMS_SUCCESS;
687 line = sp_response->p_intermediates->line;
688 ret = at_tok_start(&line);
692 ret = at_tok_nextstr(&line, &scaStr);
695 memcpy(respGetSca.scaAddress.diallingNum, scaStr, strlen(scaStr));
698 line = sp_response->p_intermediates->line;
699 ret = at_tok_start(&line);
703 ret = at_tok_nextstr(&line,&scaStr);
705 ret = at_tok_nextint(&line,&scaType);
707 respGetSca.scaAddress.dialNumLen = strlen(scaStr);
709 respGetSca.scaAddress.typeOfNum = SIM_TON_INTERNATIONAL;
710 else respGetSca.scaAddress.typeOfNum = SIM_TON_NATIONAL;
711 respGetSca.scaAddress.numPlanId = 0;
713 memcpy(respGetSca.scaAddress.diallingNum, scaStr, strlen(scaStr));
718 //failure case - consider this later
719 line = sp_response->finalResponse;
721 ret = at_tok_start(&line);
725 ret = at_tok_nextint(&line,&error);
729 respGetSca.result = util_sms_ipcError2SmsError(error);
735 tcore_user_request_send_response(ur, TRESP_SMS_GET_SCA, sizeof(struct tresp_sms_get_sca), &respGetSca);
740 static void on_response_set_sca(TcorePending *p, int data_len, const void *data, void *user_data)
743 struct tresp_sms_set_sca respSetSca;
748 ur = tcore_pending_ref_user_request(p);
751 dbg("no user_request");
757 if(sp_response->success > 0)
759 respSetSca.result = SMS_SUCCESS;
763 //failure case - consider this later
764 line = sp_response->finalResponse;
766 ret = at_tok_start(&line);
770 ret = at_tok_nextint(&line,&error);
774 respSetSca.result = util_sms_ipcError2SmsError(error);
779 tcore_user_request_send_response(ur, TRESP_SMS_SET_SCA, sizeof(struct tresp_sms_get_sca), &respSetSca);
784 static void on_response_set_delivery_report(TcorePending *p, int data_len, const void *data, void *user_data)
787 struct tresp_sms_set_delivery_report respSetDeliveryReport = {0,};
793 ur = tcore_pending_ref_user_request(p);
796 dbg("no user_request");
802 if(sp_response->success > 0)
804 respSetDeliveryReport.result = SMS_SUCCESS;
808 //failure case - consider this later
809 line = sp_response->finalResponse;
811 ret = at_tok_start(&line);
815 ret = at_tok_nextint(&line,&error);
819 respSetDeliveryReport.result = util_sms_ipcError2SmsError(error);
825 tcore_user_request_send_response(ur, TRESP_SMS_SET_DELIVERY_REPORT, sizeof(struct tresp_sms_set_delivery_report), &respSetDeliveryReport);
830 static void on_response_get_sms_params(TcorePending *p, int data_len, const void *data, void *user_data)
833 struct tresp_sms_get_params respGetSmsParams;
834 struct property_sms_info *property = NULL;
843 memset(&respGetSmsParams, 0, sizeof(struct tresp_sms_get_params));
847 ur = tcore_pending_ref_user_request(p);
850 dbg("no user_request");
854 if(sp_response->success > 0)
856 line = sp_response->p_intermediates->line;
858 ret = at_tok_start(&line);
862 ret = at_tok_nextint(&line,&sw1);
865 ret = at_tok_nextint(&line,&sw2);
869 if(sw1 != 144 || sw2 != 0)
870 respGetSmsParams.result = SMS_UNKNOWN;
875 ret = at_tok_nextstr(&line,&hexData);
879 recordData = util_hexStringToBytes(hexData);
880 util_hex_dump(" ", strlen(hexData)/2, recordData);
882 // respGetSmsParams.paramsInfo.recordIndex = 0;
883 respGetSmsParams.paramsInfo.recordLen = strlen(hexData)/2;
885 property = tcore_plugin_ref_property(tcore_object_ref_plugin(tcore_pending_ref_core_object(p)), "SMS");
888 dbg("property is NULL");
893 util_sms_decode_smsParameters((unsigned char *)recordData, strlen(hexData)/2, &respGetSmsParams.paramsInfo);
894 property->SMSPRecordLen = respGetSmsParams.paramsInfo.recordLen;
896 respGetSmsParams.result = SMS_SUCCESS;
903 respGetSmsParams.result = SMS_UNKNOWN;
904 //failure case - consider this later
905 line = sp_response->finalResponse;
907 ret = at_tok_start(&line);
911 ret = at_tok_nextint(&line,&error);
915 respGetSmsParams.result = util_sms_ipcError2SmsError(error);
920 tcore_user_request_send_response(ur, TRESP_SMS_GET_PARAMS, sizeof(struct tresp_sms_get_params), &respGetSmsParams);
925 static void on_response_get_paramcnt(TcorePending *p, int data_len, const void *data, void *user_data)
928 struct tresp_sms_get_paramcnt respGetParamCnt = {0,};
929 CoreObject *co_sim = NULL;
935 ur = tcore_pending_ref_user_request(p);
937 if(sp_response->success == TRUE)
939 line = sp_response->p_intermediates->line;
940 ret = at_tok_start(&line);
944 ret = at_tok_nextint(&line,&sw1);
947 ret = at_tok_nextint(&line,&sw2);
951 /*1. SIM access success case*/
952 if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
953 unsigned char tag_len = 0; /* 1 or 2 bytes ??? */
954 unsigned short record_len = 0;
955 char num_of_records = 0;
956 unsigned char file_id_len = 0;
957 unsigned short file_id = 0;
958 unsigned short file_size = 0;
959 unsigned short file_type = 0;
960 unsigned short arr_file_id = 0;
961 int arr_file_id_rec_num = 0;
963 /* handling only last 3 bits */
964 unsigned char file_type_tag = 0x07;
965 unsigned char *ptr_data;
969 ret = at_tok_nextstr(&line,&hexData);
973 recordData = util_hexStringToBytes(hexData);
974 util_hex_dump(" ", strlen(hexData)/2, recordData);
976 ptr_data = (unsigned char *)recordData;
978 co_sim = tcore_plugin_ref_core_object(tcore_pending_ref_plugin(p), "sim");
979 if (tcore_sim_get_type(co_sim) == SIM_TYPE_USIM) {
981 ETSI TS 102 221 v7.9.0
983 '62' FCP template tag
985 '82' M File Descriptor
986 '83' M File Identifier
987 'A5' O Proprietary information
988 '8A' M Life Cycle Status Integer
989 '8B', '8C' or 'AB' C1 Security attributes
991 '81' O Total file size
992 '88' O Short File Identifier (SFI)
995 /* rsim.res_len has complete data length received */
997 /* FCP template tag - File Control Parameters tag*/
998 if (*ptr_data == 0x62) {
999 /* parse complete FCP tag*/
1000 /* increment to next byte */
1002 tag_len = *ptr_data++;
1003 /* FCP file descriptor - file type, accessibility, DF, ADF etc*/
1004 if (*ptr_data == 0x82) {
1005 /* increment to next byte */
1009 /* unsigned char file_desc_len = *ptr_data++;*/
1010 /* dbg("file descriptor length: [%d]", file_desc_len);*/
1011 /* TBD: currently capture only file type : ignore sharable, non sharable, working, internal etc*/
1012 /* consider only last 3 bits*/
1013 file_type_tag = file_type_tag & (*ptr_data);
1015 switch (file_type_tag) {
1016 /* increment to next byte */
1019 dbg("Getting FileType: [Transparent file type]");
1020 /* increment to next byte */
1022 file_type = 0x01; //SIM_FTYPE_TRANSPARENT
1023 /* data coding byte - value 21 */
1028 dbg("Getting FileType: [Linear fixed file type]");
1029 /* increment to next byte */
1031 /* data coding byte - value 21 */
1034 memcpy(&record_len, ptr_data, 2);
1036 SWAPBYTES16(record_len);
1037 ptr_data = ptr_data + 2;
1038 num_of_records = *ptr_data++;
1039 /* Data lossy conversation from enum (int) to unsigned char */
1040 file_type = 0x02; // SIM_FTYPE_LINEAR_FIXED
1044 dbg(" Cyclic fixed file type");
1045 /* increment to next byte */
1047 /* data coding byte - value 21 */
1050 memcpy(&record_len, ptr_data, 2);
1052 SWAPBYTES16(record_len);
1053 ptr_data = ptr_data + 2;
1054 num_of_records = *ptr_data++;
1055 file_type = 0x04; //SIM_FTYPE_CYCLIC
1059 dbg("not handled file type [0x%x]", *ptr_data);
1063 dbg("INVALID FCP received - DEbug!");
1067 /*File identifier - file id?? */ // 0x84,0x85,0x86 etc are currently ignored and not handled
1068 if (*ptr_data == 0x83) {
1069 /* increment to next byte */
1071 file_id_len = *ptr_data++;
1072 memcpy(&file_id, ptr_data, file_id_len);
1074 SWAPBYTES16(file_id);
1075 ptr_data = ptr_data + 2;
1076 dbg("Getting FileID=[0x%x]", file_id);
1078 dbg("INVALID FCP received - DEbug!");
1084 /* proprietary information */
1085 if (*ptr_data == 0xA5) {
1086 unsigned short prop_len;
1087 /* increment to next byte */
1090 prop_len = *ptr_data;
1092 ptr_data = ptr_data + prop_len + 1;
1094 dbg("INVALID FCP received - DEbug!");
1097 /* life cycle status integer [8A][length:0x01][status]*/
1100 00000000 : No information given
1101 00000001 : creation state
1102 00000011 : initialization state
1103 000001-1 : operation state -activated
1104 000001-0 : operation state -deactivated
1105 000011-- : Termination state
1106 b8~b5 !=0, b4~b1=X : Proprietary
1107 Any other value : RFU
1109 if (*ptr_data == 0x8A) {
1110 /* increment to next byte */
1112 /* length - value 1 */
1115 switch (*ptr_data) {
1118 dbg("<IPC_RX> operation state -deactivated");
1123 dbg("<IPC_RX> operation state -activated");
1127 dbg("<IPC_RX> DEBUG! LIFE CYCLE STATUS =[0x%x]",*ptr_data);
1133 /* related to security attributes : currently not handled*/
1134 if (*ptr_data == 0x86 || *ptr_data == 0x8B || *ptr_data == 0x8C || *ptr_data == 0xAB) {
1135 /* increment to next byte */
1137 /* if tag length is 3 */
1138 if (*ptr_data == 0x03) {
1139 /* increment to next byte */
1142 memcpy(&arr_file_id, ptr_data, 2);
1144 SWAPBYTES16(arr_file_id);
1145 ptr_data = ptr_data + 2;
1146 arr_file_id_rec_num = *ptr_data++;
1148 /* if tag length is not 3 */
1149 /* ignoring bytes */
1150 // ptr_data = ptr_data + 4;
1151 dbg("Useless security attributes, so jump to next tag");
1152 ptr_data = ptr_data + (*ptr_data + 1);
1155 dbg("INVALID FCP received[0x%x] - DEbug!", *ptr_data);
1161 dbg("Current ptr_data value is [%x]", *ptr_data);
1163 /* file size excluding structural info*/
1164 if (*ptr_data == 0x80) {
1165 /* for EF file size is body of file and for Linear or cyclic it is
1166 * number of recXsizeof(one record)
1168 /* increment to next byte */
1170 /* length is 1 byte - value is 2 bytes or more */
1172 memcpy(&file_size, ptr_data, 2);
1174 SWAPBYTES16(file_size);
1175 ptr_data = ptr_data + 2;
1177 dbg("INVALID FCP received - DEbug!");
1183 /* total file size including structural info*/
1184 if (*ptr_data == 0x81) {
1186 /* increment to next byte */
1191 ptr_data = ptr_data + 3;
1193 dbg("INVALID FCP received - DEbug!");
1194 /* 0x81 is optional tag?? check out! so do not return -1 from here! */
1197 /*short file identifier ignored*/
1198 if (*ptr_data == 0x88) {
1199 dbg("0x88: Do Nothing");
1203 dbg("INVALID FCP received - DEbug!");
1209 else if (tcore_sim_get_type(co_sim) == SIM_TYPE_GSM)
1211 unsigned char gsm_specific_file_data_len = 0;
1212 /* ignore RFU byte1 and byte2 */
1216 //file_size = p_info->response_len;
1217 memcpy(&file_size, ptr_data, 2);
1219 SWAPBYTES16(file_size);
1220 /* parsed file size */
1221 ptr_data = ptr_data + 2;
1223 memcpy(&file_id, ptr_data, 2);
1224 SWAPBYTES16(file_id);
1225 dbg(" FILE id --> [%x]", file_id);
1226 ptr_data = ptr_data + 2;
1227 /* save file type - transparent, linear fixed or cyclic */
1228 file_type_tag = (*(ptr_data + 7));
1230 switch (*ptr_data) {
1233 dbg(" RFU file type- not handled - Debug!");
1237 dbg(" MF file type - not handled - Debug!");
1241 dbg(" DF file type - not handled - Debug!");
1245 dbg(" EF file type [%d] ", file_type_tag);
1246 /* increment to next byte */
1249 if (file_type_tag == 0x00 || file_type_tag == 0x01) {
1250 /* increament to next byte as this byte is RFU */
1253 (file_type_tag == 0x00) ? 0x01 : 0x02; // SIM_FTYPE_TRANSPARENT:SIM_FTYPE_LINEAR_FIXED;
1255 /* increment to next byte */
1257 /* For a cyclic EF all bits except bit 7 are RFU; b7=1 indicates that */
1258 /* the INCREASE command is allowed on the selected cyclic file. */
1259 file_type = 0x04; // SIM_FTYPE_CYCLIC;
1261 /* bytes 9 to 11 give SIM file access conditions */
1263 /* byte 10 has one nibble that is RF U and another for INCREASE which is not used currently */
1265 /* byte 11 is invalidate and rehabilate nibbles */
1267 /* byte 12 - file status */
1269 /* byte 13 - GSM specific data */
1270 gsm_specific_file_data_len = *ptr_data;
1272 /* byte 14 - structure of EF - transparent or linear or cyclic , already saved above */
1274 /* byte 15 - length of record for linear and cyclic , for transparent it is set to 0x00. */
1275 record_len = *ptr_data;
1276 dbg("record length[%d], file size[%d]", record_len, file_size);
1278 if (record_len != 0)
1279 num_of_records = (file_size / record_len);
1281 dbg("Number of records [%d]", num_of_records);
1285 dbg(" not handled file type");
1291 dbg(" Card Type - UNKNOWN [%d]", tcore_sim_get_type(co_sim));
1294 dbg("EF[0x%x] size[%ld] Type[0x%x] NumOfRecords[%ld] RecordLen[%ld]", file_id, file_size, file_type, num_of_records, record_len);
1296 respGetParamCnt.recordCount = num_of_records;
1297 respGetParamCnt.result = SMS_SUCCESS;
1303 /*2. SIM access fail case*/
1304 dbg("SIM access fail");
1305 respGetParamCnt.result = SMS_UNKNOWN;
1310 dbg("response error!!!");
1311 respGetParamCnt.result = SMS_UNKNOWN;
1316 tcore_user_request_send_response(ur, TRESP_SMS_GET_PARAMCNT, sizeof(struct tresp_sms_get_paramcnt), &respGetParamCnt);
1322 /********************************************************/
1323 /*********************** Requests ************************/
1324 /********************************************************/
1325 static TReturn send_umts_msg(CoreObject *o, UserRequest *ur)
1327 TcorePlugin *p = NULL;
1329 TcorePending *pending = NULL;
1330 const struct treq_sms_send_umts_msg *sendUmtsMsg = NULL;
1331 char *cmd_str = NULL;
1332 struct ATReqMetaInfo metainfo;
1335 dbg("new pending(IPC_SMS_SEND_MSG)");
1337 sendUmtsMsg = tcore_user_request_ref_data(ur, NULL);
1339 p = tcore_object_ref_plugin(o);
1340 h = tcore_object_get_hal(o);
1342 if (!sendUmtsMsg || !h)
1343 return TCORE_RETURN_ENOSYS;
1345 memset(&metainfo, 0, sizeof(struct ATReqMetaInfo));
1346 metainfo.type = NO_RESULT;
1347 metainfo.responsePrefix[0] ='\0';
1348 info_len = sizeof(struct ATReqMetaInfo);
1350 tcore_user_request_set_metainfo(ur, info_len, &metainfo);
1353 cmd_str = g_strdup_printf("AT+CMMS=%d%s", sendUmtsMsg->more, "\r");
1354 dbg("[tcore_SMS] *************************MsgLen[%d]", sendUmtsMsg->msgDataPackage.msgLength);
1356 pending = tcore_pending_new(o, ID_RESERVED_AT);
1357 tcore_pending_set_request_data(pending, strlen(cmd_str), cmd_str);
1358 tcore_pending_set_timeout(pending, 0);
1359 tcore_pending_set_response_callback(pending, on_response_send_umts_msg, NULL);
1360 tcore_pending_link_user_request(pending, ur);
1362 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
1366 return tcore_hal_send_request(h, pending);
1369 static TReturn Send_SmsSubmitTpdu(CoreObject *o, UserRequest *ur)
1371 TcorePlugin *p = NULL;
1373 TcorePending *pending = NULL;
1374 const struct treq_sms_send_umts_msg *sendUmtsMsg = NULL;
1375 char *cmd_str = NULL;
1376 struct ATReqMetaInfo metainfo;
1378 char tpdu[MAX_GSM_SMS_TPDU_SIZE];
1380 char *hexString = NULL;
1381 int tpduDataLen = 0;
1384 TReturn api_err = TCORE_RETURN_SUCCESS;
1386 dbg("new pending(IPC_SMS_SEND_MSG)");
1388 sendUmtsMsg = tcore_user_request_ref_data(ur, NULL);
1390 p = tcore_object_ref_plugin(o);
1391 h = tcore_object_get_hal(o);
1393 if (!sendUmtsMsg || !h)
1394 return TCORE_RETURN_ENOSYS;
1397 dbg("[tcore_SMS] MoreToSend[0x%x](1:Persist, 2:NotPersist) MsgLen[%d]",sendUmtsMsg->more, sendUmtsMsg->msgDataPackage.msgLength);
1398 for(i=0; i<sendUmtsMsg->msgDataPackage.msgLength; i++)
1399 dbg("[%02x]", sendUmtsMsg->msgDataPackage.tpduData[i]);
1401 if ((sendUmtsMsg->msgDataPackage.msgLength > 0) && (MAX_GSM_SMS_TPDU_SIZE > sendUmtsMsg->msgDataPackage.msgLength))
1403 if (sendUmtsMsg->msgDataPackage.msgLength < SMS_SMDATA_SIZE_MAX)
1405 memset(tpdu, 0, sizeof(MAX_GSM_SMS_TPDU_SIZE));
1407 memset(&metainfo, 0, sizeof(struct ATReqMetaInfo));
1408 metainfo.type = SINGLELINE;
1409 memcpy(metainfo.responsePrefix,"+CMGS:",strlen("+CMGS:"));
1410 info_len = sizeof(struct ATReqMetaInfo);
1412 tcore_user_request_set_metainfo(ur, info_len, &metainfo);
1414 ScLength = sendUmtsMsg->msgDataPackage.sca[0];
1415 if(sendUmtsMsg->msgDataPackage.sca[0] == 0)
1417 memcpy(&tpdu[0], sendUmtsMsg->msgDataPackage.sca, ScLength+2);
1421 dbg("SC length in ipc tx is %d - before", ScLength);
1423 util_sms_get_length_of_sca(&ScLength);
1425 dbg(" SC length in ipc tx is %d - after", ScLength);
1427 tpdu[0] = ScLength +1 ;
1428 //1Copy SCA to the ipc stream first
1429 memcpy(&(tpdu[1]), &( sendUmtsMsg->msgDataPackage.sca[1]), (ScLength + 1));
1432 if ((ScLength <= SMS_MAX_SMS_SERVICE_CENTER_ADDR) && (sendUmtsMsg->msgDataPackage.msgLength < SMS_SMDATA_SIZE_MAX))
1434 //1Copy rest of the SMS-SUBMIT TPDU
1435 memcpy(&(tpdu[ScLength + 2]), sendUmtsMsg->msgDataPackage.tpduData, sendUmtsMsg->msgDataPackage.msgLength);
1438 dbg("SCA len is %d", ScLength);
1439 api_err = TCORE_RETURN_SMS_INVALID_DATA_LEN;
1443 tpduDataLen = sendUmtsMsg->msgDataPackage.msgLength + (ScLength + 2);
1444 hexString = calloc(tpduDataLen*2, 1);;
1446 for( i=0; i<tpduDataLen*2; i+=2)
1450 value = (tpdu[i/2] & 0xf0 ) >> 4;
1452 hexString[i] = ((tpdu[i/2] & 0xf0 ) >> 4) + '0';
1453 else hexString[i] = ((tpdu[i/2] & 0xf0 ) >> 4) + 'A' -10;
1455 value = tpdu[i/2] & 0x0f;
1457 hexString[i+1] = (tpdu[i/2] & 0x0f ) + '0';
1458 else hexString[i+1] = (tpdu[i/2] & 0x0f ) + 'A' -10;
1462 // AT+CMGS=<length><CR>pdu_is_given<ctrl-z/ESC>
1463 cmd_str = g_strdup_printf("AT+CMGS=%d%s%s%x%s", sendUmtsMsg->msgDataPackage.msgLength, "\r", hexString, 0x1A,"\r");
1464 dbg("cmd_str is %s", cmd_str);
1466 pending = tcore_pending_new(o, ID_RESERVED_AT);
1467 tcore_pending_set_request_data(pending, strlen(cmd_str), cmd_str);
1468 tcore_pending_set_timeout(pending, 0);
1469 tcore_pending_set_response_callback(pending, on_response_send_smsSubmitTpdu, NULL);
1470 tcore_pending_link_user_request(pending, ur);
1472 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
1474 api_err = tcore_hal_send_request(h, pending);
1481 dbg("[tcore_SMS] TPDU size[%d] is over !!!, max is [%d]", sendUmtsMsg->msgDataPackage.msgLength, SMS_SMDATA_SIZE_MAX);
1482 api_err = TCORE_RETURN_SMS_INVALID_DATA_LEN;
1488 dbg("[tcore_SMS] Invalid Data Length");
1489 api_err = TCORE_RETURN_SMS_INVALID_DATA_LEN;
1496 static TReturn send_cdma_msg(CoreObject *o, UserRequest *ur)
1498 dbg("[tcore_SMS] Not supported");
1499 return TCORE_RETURN_ENOSYS;}
1501 static TReturn read_msg(CoreObject *o, UserRequest *ur)
1503 dbg("[tcore_SMS] Not supported");
1504 return TCORE_RETURN_ENOSYS;
1507 static TReturn save_msg(CoreObject *o, UserRequest *ur)
1509 dbg("[tcore_SMS] Not supported");
1510 return TCORE_RETURN_ENOSYS;
1513 static TReturn delete_msg(CoreObject *o, UserRequest *ur)
1515 dbg("[tcore_SMS] Not supported");
1516 return TCORE_RETURN_ENOSYS;
1519 static TReturn get_storedMsgCnt(CoreObject *o, UserRequest *ur)
1521 TcorePlugin *p = NULL;
1523 TcorePending *pending = NULL;
1524 const struct treq_sms_get_msg_count *getStoredMsgCnt = NULL;
1526 char *cmd_str = NULL;
1527 struct ATReqMetaInfo metainfo;
1530 dbg("new pending(IPC_SMS_GET_STORED_MSG_COUNT)");
1532 getStoredMsgCnt = tcore_user_request_ref_data(ur, NULL);
1534 p = tcore_object_ref_plugin(o);
1535 h = tcore_object_get_hal(o);
1539 dbg("[ERR] tcore_object_get_hal() pointer is NULL");
1540 return TCORE_RETURN_ENOSYS;
1543 memset(&metainfo, 0, sizeof(struct ATReqMetaInfo));
1544 metainfo.type = SINGLELINE;
1545 memcpy(metainfo.responsePrefix,"+CPMS:",strlen("+CPMS:"));
1546 info_len = sizeof(struct ATReqMetaInfo);
1548 tcore_user_request_set_metainfo(ur, info_len, &metainfo);
1550 // AT+CPMS=<mem1>[,<mem2>[,<mem3>]]
1551 // Possible response(s) : +CPMS: <used1>,<total1>,<used2>,<total2>,<used3>,<total3>
1552 cmd_str = g_strdup_printf("AT+CPMS=\"SM\"%s", "\r");
1554 pending = tcore_pending_new(o, ID_RESERVED_AT);
1555 tcore_pending_set_request_data(pending, strlen(cmd_str), cmd_str);
1556 tcore_pending_set_timeout(pending, 0);
1557 tcore_pending_set_response_callback(pending, on_response_get_storedMsgCnt, NULL);
1558 tcore_pending_link_user_request(pending, ur);
1560 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
1564 return tcore_hal_send_request(h, pending);
1568 static TReturn get_sca(CoreObject *o, UserRequest *ur)
1570 TcorePlugin *p = NULL;
1572 TcorePending *pending = NULL;
1573 const struct treq_sms_get_sca *getSca = NULL;
1574 char *cmd_str = NULL;
1575 struct ATReqMetaInfo metainfo;
1578 dbg("new pending(IPC_SMS_GET_SCA)");
1580 getSca = tcore_user_request_ref_data(ur, NULL);
1582 p = tcore_object_ref_plugin(o);
1583 h = tcore_object_get_hal(o);
1586 return TCORE_RETURN_ENOSYS;
1588 memset(&metainfo, 0, sizeof(struct ATReqMetaInfo));
1589 metainfo.type = SINGLELINE;
1590 memcpy(metainfo.responsePrefix,"+CSCA:",strlen("+CSCA:"));
1591 info_len = sizeof(struct ATReqMetaInfo);
1593 tcore_user_request_set_metainfo(ur, info_len, &metainfo);
1596 // Possible response(s) : +CSCA: <sca number>,<sca type>
1597 cmd_str = g_strdup_printf("AT +CSCA?%s", "\r");
1599 pending = tcore_pending_new(o, ID_RESERVED_AT);
1600 tcore_pending_set_request_data(pending, strlen(cmd_str), cmd_str);
1601 tcore_pending_set_timeout(pending, 0);
1602 tcore_pending_set_response_callback(pending, on_response_get_sca, NULL);
1603 tcore_pending_link_user_request(pending, ur);
1605 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
1609 return tcore_hal_send_request(h, pending);
1613 static TReturn set_sca(CoreObject *o, UserRequest *ur)
1615 TcorePlugin *p = NULL;
1617 TcorePending *pending = NULL;
1618 const struct treq_sms_set_sca *setSca;
1620 char *cmd_str = NULL;
1621 struct ATReqMetaInfo metainfo;
1624 dbg("new pending(IPC_SMS_SET_SCA)");
1626 setSca = tcore_user_request_ref_data(ur, NULL);
1628 if(setSca->index != 0){
1629 dbg("Index except 0 is supported");
1630 return TCORE_RETURN_EINVAL; // TCORE_API_NOT_SUPPORTED;
1633 p = tcore_object_ref_plugin(o);
1634 h = tcore_object_get_hal(o);
1637 return TCORE_RETURN_ENOSYS;
1639 if(setSca->scaInfo.typeOfNum == SIM_TON_INTERNATIONAL)
1643 memset(&metainfo, 0, sizeof(struct ATReqMetaInfo));
1644 metainfo.type = NO_RESULT;
1645 metainfo.responsePrefix[0] ='\0';
1646 info_len = sizeof(struct ATReqMetaInfo);
1648 tcore_user_request_set_metainfo(ur, info_len, &metainfo);
1650 // AT +CSCA=<sca number>[,<sca type>]
1651 // 129:Unknown numbering plan, national/international number unknown, 145:international number
1652 cmd_str = g_strdup_printf("AT+CSCA=\"%s\", %d%s", setSca->scaInfo.diallingNum, scaType, "\r");
1654 pending = tcore_pending_new(o, ID_RESERVED_AT);
1655 tcore_pending_set_request_data(pending, strlen(cmd_str), cmd_str);
1656 tcore_pending_set_timeout(pending, 0);
1657 tcore_pending_set_response_callback(pending, on_response_set_sca, NULL);
1658 tcore_pending_link_user_request(pending, ur);
1660 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
1664 return tcore_hal_send_request(h, pending);
1668 static TReturn get_cb_config(CoreObject *o, UserRequest *ur)
1670 dbg("[tcore_SMS] Not supported");
1671 return TCORE_RETURN_ENOSYS;
1674 static TReturn set_cb_config(CoreObject *o, UserRequest *ur)
1676 dbg("[tcore_SMS] Not supported");
1677 return TCORE_RETURN_ENOSYS;
1680 static TReturn set_mem_status(CoreObject *o, UserRequest *ur)
1682 dbg("[tcore_SMS] Not supported");
1683 return TCORE_RETURN_ENOSYS;
1686 static TReturn get_pref_brearer(CoreObject *o, UserRequest *ur)
1688 dbg("[tcore_SMS] Not supported");
1689 return TCORE_RETURN_ENOSYS;
1692 static TReturn set_pref_brearer(CoreObject *o, UserRequest *ur)
1694 dbg("[tcore_SMS] Not supported");
1695 return TCORE_RETURN_ENOSYS;
1698 static TReturn set_delivery_report(CoreObject *o, UserRequest *ur)
1700 TcorePlugin *p = NULL;
1702 TcorePending *pending = NULL;
1703 const struct treq_sms_set_delivery_report *deliveryReport = NULL;
1705 struct ATReqMetaInfo metainfo;
1708 dbg("new pending(IPC_SMS_SVC_CENTER_ADDR)");
1710 deliveryReport = tcore_user_request_ref_data(ur, NULL);
1712 p = tcore_object_ref_plugin(o);
1713 h = tcore_object_get_hal(o);
1715 if (!deliveryReport || !h)
1716 return TCORE_RETURN_ENOSYS;
1718 memset(&metainfo, 0, sizeof(struct ATReqMetaInfo));
1719 metainfo.type = NO_RESULT;
1720 metainfo.responsePrefix[0] ='\0';
1721 info_len = sizeof(struct ATReqMetaInfo);
1723 tcore_user_request_set_metainfo(ur, info_len, &metainfo);
1726 if(deliveryReport->rspType == SMS_SENDSMS_SUCCESS)
1727 cmd_str = g_strdup_printf("AT+CNMA=0%s", "\r");
1729 cmd_str = g_strdup_printf("AT+CNMA=2,3%s%x%s", "/n", 0x00ff00, "");
1731 pending = tcore_pending_new(o, ID_RESERVED_AT);
1732 tcore_pending_set_request_data(pending, strlen(cmd_str), cmd_str);
1733 tcore_pending_set_timeout(pending, 0);
1734 tcore_pending_set_response_callback(pending, on_response_set_delivery_report, NULL);
1735 tcore_pending_link_user_request(pending, ur);
1737 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
1741 return tcore_hal_send_request(h, pending);
1745 static TReturn set_msg_status(CoreObject *o, UserRequest *ur)
1747 dbg("[tcore_SMS] Not supported");
1748 return TCORE_RETURN_ENOSYS;
1751 static TReturn get_sms_params(CoreObject *o, UserRequest *ur)
1753 TcorePlugin *p = NULL;
1755 TcorePending *pending = NULL;
1756 const struct treq_sms_get_params *getSmsParams = NULL;
1758 char *cmd_str = NULL;
1759 struct ATReqMetaInfo metainfo;
1762 dbg("new pending(IPC_SMS_GET_CBS_CFG)");
1764 getSmsParams = tcore_user_request_ref_data(ur, NULL);
1766 p = tcore_object_ref_plugin(o);
1767 h = tcore_object_get_hal(o);
1769 if (!getSmsParams || !h)
1771 dbg("[ERR] pointer is NULL, getSmsParams=0x%x, h=0x%x", getSmsParams, h);
1772 return TCORE_RETURN_ENOSYS;
1775 memset(&metainfo, 0, sizeof(struct ATReqMetaInfo));
1776 metainfo.type = SINGLELINE;
1777 memcpy(metainfo.responsePrefix,"+CRSM:",strlen("+CRSM:"));
1778 info_len = sizeof(struct ATReqMetaInfo);
1780 tcore_user_request_set_metainfo(ur, info_len, &metainfo);
1782 // AT+CRSM=<command>,<fildid>,<p1>,<p2+C29,<p3>
1783 cmd_str = g_strdup_printf("AT+CRSM=%d, %d, %d, 4, 40%s", 178, 0x6F42, getSmsParams->index + 1, "\r");
1785 pending = tcore_pending_new(o, ID_RESERVED_AT);
1786 tcore_pending_set_request_data(pending, strlen(cmd_str), cmd_str);
1787 tcore_pending_set_timeout(pending, 0);
1788 tcore_pending_set_response_callback(pending, on_response_get_sms_params, NULL);
1789 tcore_pending_link_user_request(pending, ur);
1791 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
1795 return tcore_hal_send_request(h, pending);
1799 static TReturn set_sms_params(CoreObject *o, UserRequest *ur)
1801 dbg("[tcore_SMS] Not supported");
1802 return TCORE_RETURN_ENOSYS;
1805 static TReturn get_paramcnt(CoreObject *o, UserRequest *ur)
1807 TcorePlugin *p = NULL;
1809 TcorePending *pending = NULL;
1810 const struct treq_sms_get_paramcnt *getParamCnt = NULL;
1812 char *cmd_str = NULL;
1813 struct ATReqMetaInfo metainfo;
1816 getParamCnt = tcore_user_request_ref_data(ur, NULL);
1818 p = tcore_object_ref_plugin(o);
1819 h = tcore_object_get_hal(o);
1821 if (!h) // request data is NULL, so do not NULL check for getParamCnt
1823 dbg("[ERR] pointer is NULL, getParamCnt=0x%x, h=0x%x", getParamCnt, h);
1824 return TCORE_RETURN_ENOSYS;
1827 memset(&metainfo, 0, sizeof(struct ATReqMetaInfo));
1828 metainfo.type = SINGLELINE;
1829 memcpy(metainfo.responsePrefix,"+CRSM:",strlen("+CRSM:"));
1830 info_len = sizeof(struct ATReqMetaInfo);
1832 tcore_user_request_set_metainfo(ur, info_len, &metainfo);
1834 // AT+CRSM=<command>,<fildid>,<p1>,<p2+C29,<p3>, EFsmsp: 0x6F42
1835 cmd_str = g_strdup_printf("AT+CRSM=192, %d%s", 0x6F42, "\r");
1837 pending = tcore_pending_new(o, ID_RESERVED_AT);
1838 tcore_pending_set_request_data(pending, strlen(cmd_str), cmd_str);
1839 tcore_pending_set_timeout(pending, 0);
1840 tcore_pending_set_response_callback(pending, on_response_get_paramcnt, NULL);
1841 tcore_pending_link_user_request(pending, ur);
1843 tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
1847 return tcore_hal_send_request(h, pending);
1850 static struct tcore_sms_operations sms_ops =
1852 .send_umts_msg = send_umts_msg,
1853 .read_msg = read_msg,
1854 .save_msg = save_msg,
1855 .delete_msg = delete_msg,
1856 .get_storedMsgCnt = get_storedMsgCnt,
1859 .get_cb_config = get_cb_config,
1860 .set_cb_config = set_cb_config,
1861 .set_mem_status = set_mem_status,
1862 .get_pref_brearer = get_pref_brearer,
1863 .set_pref_brearer = set_pref_brearer,
1864 .set_delivery_report = set_delivery_report,
1865 .set_msg_status = set_msg_status,
1866 .get_sms_params = get_sms_params,
1867 .set_sms_params = set_sms_params,
1868 .get_paramcnt = get_paramcnt,
1869 .send_cdma_msg = send_cdma_msg,
1872 gboolean s_sms_init(TcorePlugin *p, TcoreHal *h)
1875 struct property_sms_info *data;
1878 o = tcore_sms_new(p, "umts_sms", &sms_ops, h);
1882 work_queue = g_queue_new();
1883 tcore_object_link_user_data(o, work_queue);
1885 tcore_object_add_callback(o, EVENT_SMS_INCOM_MSG, on_event_sms_incom_msg, NULL);
1886 tcore_object_add_callback(o, EVENT_SMS_DEVICE_READY, on_event_sms_device_ready, NULL);
1888 data = calloc(sizeof(struct property_sms_info), 1);
1889 tcore_plugin_link_property(p, "SMS", data);
1895 void s_sms_exit(TcorePlugin *p)
1898 struct property_sms_info *data;
1900 o = tcore_plugin_ref_core_object(p, "umts_sms");
1904 data = tcore_plugin_ref_property(p, "SMS");