+++ /dev/null
-Jongman Park <jman.park@samsung.com>
-Ja-young Gu <jygu@samsung.com>
-Kyeongchul Kim <kyeongchul.kim@samsung.com>
-DongHoo Park <donghoo.park@samsung.>
-Youngman Park <youngman.park@samsung.com>
-Inho Oh <inho48.oh@samsung.com>
-Hayoon Ko <hayoon.ko@samsung.com>
-Junhwan An <jh48.an@samsung.com>
-Kyoungyoup Park <gynaru.park@samsung.com>
-Jinyup Kim <kjy9411@samsung.com>
# Set required packages
INCLUDE(FindPkgConfig)
-pkg_check_modules(pkgs REQUIRED glib-2.0 tcore dlog libtzplatform-config)
+pkg_check_modules(pkgs REQUIRED glib-2.0 tcore dlog libtzplatform-config vconf)
FOREACH(flag ${pkgs_CFLAGS})
SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -Wextra -Wno-unused-parameter -Wno-missing-field-initializers -Wdeclaration-after-statement -Wmissing-declarations -Wredundant-decls -Wcast-align")
-ADD_DEFINITIONS("-DFEATURE_DLOG_DEBUG")
-ADD_DEFINITIONS("-DTCORE_LOG_TAG=\"TEL_PLUGIN_ATMODEM\"")
+ADD_DEFINITIONS("-DFEATURE_TLOG_DEBUG")
+ADD_DEFINITIONS("-DTCORE_LOG_TAG=\"ATMODEM\"")
MESSAGE(${CMAKE_C_FLAGS})
MESSAGE(${CMAKE_EXE_LINKER_FLAGS})
SET(SRCS
- src/desc_at.c
- src/s_modem.c
- src/s_common.c
- src/s_network.c
- src/s_sim.c
- src/s_call.c
- src/s_ps.c
- src/s_sms.c
- src/at_tok.c
- src/atchannel.c
- src/s_ss.c
+ src/desc_atmodem.c
+ src/atmodem_modem.c
+ src/atmodem_common.c
+ src/atmodem_network.c
+ src/atmodem_sim.c
+ src/atmodem_call.c
+ src/atmodem_ps.c
+ src/atmodem_sms.c
+ src/atmodem_ss.c
)
+++ /dev/null
-/* //device/system/reference-ril/at_tok.h
-**
-** Copyright 2006, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-#ifndef AT_TOK_H
-#define AT_TOK_H 1
-
-int at_tok_start(char **p_cur);
-int at_tok_nextint(char **p_cur, int *p_out);
-int at_tok_nexthexint(char **p_cur, int *p_out);
-
-int at_tok_nextbool(char **p_cur, char *p_out);
-int at_tok_nextstr(char **p_cur, char **out);
-
-int at_tok_hasmore(char **p_cur);
-void at_tok_skip_bracket(char **p_cur);
-
-#endif /*AT_TOK_H */
+++ /dev/null
-#ifndef __ATCHANNEL_H__
-#define __ATCHANNEL_H__
-
-/* //device/system/reference-ril/atchannel.c
-**
-** Copyright 2006, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-//code from atchannel.c - android
-#include "type/common.h"
-
-#define AT_ERROR_GENERIC -1
-#define AT_ERROR_COMMAND_PENDING -2
-#define AT_ERROR_CHANNEL_CLOSED -3
-#define AT_ERROR_TIMEOUT -4
-#define AT_ERROR_INVALID_THREAD -5 /* AT commands may not be issued from
- reader thread (or unsolicited response
- callback */
-#define AT_ERROR_INVALID_RESPONSE -6 /* eg an at_send_command_singleline that
- did not get back an intermediate
- response */
-
-#define MAX_AT_RESPONSE (8 * 1024)
-#define MAX_AT_RESP_PREFIX 10
-
-#define NUM_ELEMS(x) (sizeof(x)/sizeof(x[0]))
-
-#define ID_RESERVED_AT 0x0229
-
-
-enum ATCommandType{
- NO_RESULT, /* no intermediate response expected */
- NUMERIC, /* a single intermediate response starting with a 0-9 */
- SINGLELINE, /* a single intermediate response starting with a prefix */
- MULTILINE /* multiple line intermediate response
- starting with a prefix */
-};
-
-enum ATCMEError{
- AT_ERROR_MOBILE_FAILRURE =0,
- AT_ERROR_NOT_CONNECTED_TO_PHONE =1,
- AT_ERROR_LINK_RESERVED =2,
- AT_ERROR_OPER_NOT_ALLOWED =3,
- AT_ERROR_OPER_NOT_SUPPORTED =4,
- AT_ERROR_PH_SIM_PIN_REQUIRED =5,
- AT_ERROR_PH_FSIM_PIN_REQUIRED =6,
- AT_ERROR_PH_FSIM_PUK_REQUIRED =7,
-
- AT_ERROR_SIM_NOT_INSERTED =10,
- AT_ERROR_SIM_PIN_REQUIRED =11,
- AT_ERROR_SIM_PUK_REQUIRED =12,
- AT_ERROR_SIM_FAILURE =13,
- AT_ERROR_SIM_BUSY =14,
- AT_ERROR_SIM_WRONG =15,
- AT_ERROR_INCORRECT_PWD =16,
- AT_ERROR_SIM_PIN2_REQUIRED =17,
- AT_ERROR_SIM_PUK2_REQUIRED =18,
-
- AT_ERROR_MEMORY_FULL =20,
- AT_ERROR_INVALID_INDEX =21,
- AT_ERROR_NOT_FOUND =22,
- AT_ERROR_MEMORY_FAILURE =23,
- AT_ERROR_TEXT_TOO_LONG =24,
- AT_ERROR_INVALID_CHAR_IN_STR =25,
- AT_ERROR_DIAL_TOO_LONG =26,
- AT_ERROR_INVALID_CHAR_IN_DIAL =27,
-
- AT_ERROR_NO_NETWORK_SVC =30,
- AT_ERROR_NETWORK_TIMEOUT =31,
- AT_ERROR_EMERGENCY_CALL_ONLY =32,
-
- AT_ERROR_NET_PERSONAL_PIN_REQ =40,
- AT_ERROR_NET_PERSONAL_PUN_REQ =41,
- AT_ERROR_NET_SUB_PERSONAL_PIN_REQ =42,
- AT_ERROR_NET_SUB_PERSONAL_PUK_REQ =43,
- AT_ERROR_PROVIDER_PERSONAL_PIN_REQ =44,
- AT_ERROR_PROVIDER_PERSONAL_PUK_REQ =45,
- AT_ERROR_CORP_PERSONAL_PIN_REQ =46,
- AT_ERROR_CORP_PERSONAL_PUK_REQ =47,
- AT_ERROR_HIDDEN_KEY_REQUIRED =48,
- AT_ERROR_EAP_METHOD_NOT_SUPPORTED =49,
- AT_ERROR_INCORRECT_PARAM =50,
-
- AT_ERROR_UNKNOWN =100
-};
-
-
-
-/** a singly-lined list of intermediate responses */
-struct ATLine {
- struct ATLine *p_next;
- char *line;
-} ;
-
-/** Free this with at_response_free() */
-struct ATResponse{
- int success; /* true if final response indicates
- success (eg "OK") */
- char *finalResponse; /* eg OK, ERROR */
- struct ATLine *p_intermediates; /* any intermediate responses */
-} ;
-
-struct ATReqMetaInfo{
- enum ATCommandType type;
- char responsePrefix[MAX_AT_RESP_PREFIX];
-};
-
-struct smsDeliveryPDU{
-char* cmdLine;
-char* pdu;
-int len;
-};
-
-//utility API for at command response parsing
-/**
- * Returns a pointer to the end of the next line
- * special-cases the "> " SMS prompt
- *
- * returns NULL if there is no complete line
- */
-char * findNextEOL(char *cur);
-struct ATResponse * at_response_new();
-void at_response_free(struct ATResponse *p_response);
-int strStartsWith(const char *line, const char *prefix);
- /* SMS prompt character...not \r terminated */
-int isFinalResponseError(const char *line);
-int isFinalResponseSuccess(const char *line);
-
-int isFinalResponse(const char *line);
-void addIntermediate(const char *line);
-void ReleaseResponse(void);
-void reverseIntermediates(struct ATResponse *p_response);
-void printResponse(void);
-TReturn convertCMEError(enum ATCMEError error);
-
-#include <log.h> /* err */
-#include <stdio.h> /* __file__, __line__ */
-
-#define AT_TOK_ERROR(token) AT_TOK_ERROR_INTERNEL(token, __FILE__, __LINE__)
-#define AT_TOK_ERROR_INTERNEL(token, file, line) \
-{\
- ReleaseResponse();\
- err("AT_TOK_ERROR %s:%d %s",file,line,token?token:"");\
- return;\
-}\
-
-#define AT_NOTI_TOK_ERROR(token) AT_NOTI_TOK_ERROR_INTERNEL(token, __FILE__, __LINE__)
-#define AT_NOTI_TOK_ERROR_INTERNEL(token, file, line) \
-{\
- err("AT_NOTI_TOK_ERROR_INTERNEL %s:%d %s",file,line,token?token:"");\
- return TRUE;\
-}\
-
-#endif /* __ATCHANNEL_H__ */
-/*EOF*/
-
--- /dev/null
+/*
+ * tel-plugin-atmodem
+ *
+ * Copyright (c) 2013 Samsung Electronics Co. Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __ATMODEM_CALL_H__
+#define __ATMODEM_CALL_H__
+
+gboolean atmodem_call_init(TcorePlugin *p, CoreObject *co);
+void atmodem_call_exit(TcorePlugin *p, CoreObject *co);
+
+#endif /* __ATMODEM_CALL_H__ */
--- /dev/null
+/*
+ * tel-plugin-atmodem
+ *
+ * Copyright (c) 2013 Samsung Electronics Co. Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __ATMODEM_COMMON_H__
+#define __ATMODEM_COMMON_H__
+
+#define ATMODEM_SWAP_BYTES_16(x) \
+{ \
+ unsigned short int data = *(unsigned short int *)&(x); \
+ data = ((data & 0xff00) >> 8) | \
+ ((data & 0x00ff) << 8); \
+ *(unsigned short int *)&(x) = data; \
+}
+
+typedef struct {
+ TcoreObjectResponseCallback cb;
+ void *cb_data;
+ char data[]; /* Additional data */
+} AtmodemRespCbData;
+
+#define ATMODEM_GET_DATA_FROM_RESP_CB_DATA(ptr) (gpointer)ptr->data
+#define ATMODEM_CHECK_REQUEST_RET(ret, resp_cb_data, request) \
+do {\
+ if (ret != TEL_RETURN_SUCCESS) { \
+ err("Failed to process request - [%s]", request); \
+ atmodem_destroy_resp_cb_data(resp_cb_data); \
+ } \
+} while(0)
+
+AtmodemRespCbData *atmodem_create_resp_cb_data(TcoreObjectResponseCallback cb,
+ void *cb_data, void *data, guint data_len);
+void atmodem_destroy_resp_cb_data(AtmodemRespCbData *resp_cb_data);
+
+void on_send_atmodem_request(TcorePending *p,
+ TelReturn send_status, void *user_data);
+
+#endif /* __ATMODEM_COMMON_H__ */
/*
* tel-plugin-atmodem
*
- * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: Hayoon Ko <hayoon.ko@samsung.com>
+ * Copyright (c) 2013 Samsung Electronics Co. Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* limitations under the License.
*/
-#ifndef __S_MODEM_H__
-#define __S_MODEM_H__
+#ifndef __ATMODEM_MODEM_H__
+#define __ATMODEM_MODEM_H__
-gboolean s_modem_init(TcorePlugin *cp, CoreObject *co);
-void s_modem_exit(TcorePlugin *cp, CoreObject *co);
+gboolean atmodem_modem_init(TcorePlugin *p, CoreObject *co);
+void atmodem_modem_exit(TcorePlugin *p, CoreObject *co);
-gboolean s_modem_send_poweron(TcorePlugin *cp);
+gboolean atmodem_modem_power_on_modem(TcorePlugin *plugin);
-#endif
+#endif /* __ATMODEM_MODEM_H__ */
/*
* tel-plugin-atmodem
*
- * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: Hayoon Ko <hayoon.ko@samsung.com>
+ * Copyright (c) 2013 Samsung Electronics Co. Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* limitations under the License.
*/
-#ifndef __S_NETWORK_H__
-#define __S_NETWORK_H__
+#ifndef __ATMODEM_NETWORK_H__
+#define __ATMODEM_NETWORK_H__
-gboolean s_network_init(TcorePlugin *cp, CoreObject *co);
-void s_network_exit(TcorePlugin *cp, CoreObject *co);
+gboolean atmodem_network_init(TcorePlugin *p, CoreObject *co);
+void atmodem_network_exit(TcorePlugin *p, CoreObject *co);
-#endif
+#endif /* __ATMODEM_NETWORK_H__ */
/*
* tel-plugin-atmodem
*
- * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: Hayoon Ko <hayoon.ko@samsung.com>
+ * Copyright (c) 2013 Samsung Electronics Co. Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* limitations under the License.
*/
-#ifndef __S_PS_H__
-#define __S_PS_H__
+#ifndef __ATMODEM_PS_H__
+#define __ATMODEM_PS_H__
-gboolean s_ps_init(TcorePlugin *cp, CoreObject *co);
-void s_ps_exit(TcorePlugin *cp, CoreObject *co);
+gboolean atmodem_ps_init(TcorePlugin *p, CoreObject *co);
+void atmodem_ps_exit(TcorePlugin *p, CoreObject *co);
-#endif
+#endif /* __ATMODEM_PS_H__ */
/*
* tel-plugin-atmodem
*
- * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: Hayoon Ko <hayoon.ko@samsung.com>
+ * Copyright (c) 2013 Samsung Electronics Co. Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* limitations under the License.
*/
-#ifndef __S_SS_H__
-#define __S_SS_H__
+#ifndef __ATMODEM_SIM_H__
+#define __ATMODEM_SIM_H__
-gboolean s_ss_init(TcorePlugin *cp, CoreObject *co);
-void s_ss_exit(TcorePlugin *cp, CoreObject *co);
+gboolean atmodem_sim_init(TcorePlugin *p, CoreObject *co);
+void atmodem_sim_exit(TcorePlugin *p, CoreObject *co);
-#endif
+#endif /* __ATMODEM_SIM_H__ */
/*
* tel-plugin-atmodem
*
- * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: Hayoon Ko <hayoon.ko@samsung.com>
+ * Copyright (c) 2013 Samsung Electronics Co. Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* limitations under the License.
*/
-#ifndef __S_SIM_H__
-#define __S_SIM_H__
+#ifndef __ATMODEM_SMS_H__
+#define __ATMODEM_SMS_H__
-gboolean s_sim_init(TcorePlugin *cp, CoreObject *co);
-void s_sim_exit(TcorePlugin *cp, CoreObject *co);
+gboolean atmodem_sms_init(TcorePlugin *p, CoreObject *co);
+void atmodem_sms_exit(TcorePlugin *p, CoreObject *co);
-#endif
+#endif /* __ATMODEM_SMS_H__ */
/*
* tel-plugin-atmodem
*
- * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: Hayoon Ko <hayoon.ko@samsung.com>
+ * Copyright (c) 2013 Samsung Electronics Co. Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* limitations under the License.
*/
-#ifndef __S_SMS_H__
-#define __S_SMS_H__
+#ifndef __ATMODEM_SS_H__
+#define __ATMODEM_SS_H__
-gboolean s_sms_init(TcorePlugin *cp, CoreObject *co);
-void s_sms_exit(TcorePlugin *cp, CoreObject *co);
+gboolean atmodem_ss_init(TcorePlugin *p, CoreObject *co);
+void atmodem_ss_exit(TcorePlugin *p, CoreObject *co);
-#endif
+#endif /* __ATMODEM_SS_H__ */
+++ /dev/null
-/*
- * tel-plugin-atmodem
- *
- * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: Hayoon Ko <hayoon.ko@samsung.com>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef __S_CALL_H__
-#define __S_CALL_H__
-
-gboolean s_call_init(TcorePlugin *cp, CoreObject *co);
-void s_call_exit(TcorePlugin *cp, CoreObject *co);
-
-#endif
-
+++ /dev/null
-/*
- * tel-plugin-atmodem
- *
- * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: Hayoon Ko <hayoon.ko@samsung.com>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef __S_COMMON_H__
-#define __S_COMMON_H__
-
-#include <tcore.h>
-#include <glib.h>
-#include <user_request.h>
-
-#define EVENT_SYS_NOTI_MODEM_POWER "system_power"
-#define EVENT_MODEM_POWER "modem_power"
-#define EVENT_MODEM_PHONE_STATE "modem_phone_state"
-
-#define EVENT_CALL_STATUS "call_status"
-#define EVENT_CALL_INCOMING "call_incoming"
-#define EVENT_CALL_WAITING "call_waiting"
-
-#define EVENT_SS_INFO "ss_info"
-#define EVENT_SS_USSD "ss_ussd"
-
-#define EVENT_PS_CALL_STATUS "ps_call_status"
-#define EVENT_PS_DATA_COUNTER "ps_data_counter"
-#define EVENT_PS_IPCONFIGURATION "ps_ipconfiguration"
-#define EVENT_PS_PIN_CTRL "ps_pin_control"
-#define EVENT_PS_HSDPA_STATUS "ps_hsdpa_status"
-#define EVENT_PS_ATTACH_DETACH "ps_attach_detach"
-#define EVENT_PS_EXTERNAL_CALL "ps_external_call"
-
-#define EVENT_SAP_STATUS "sap_status"
-#define EVENT_SAP_DISCONNECT "sap_disconnect"
-
-#define EVENT_SIM_PIN_STATUS "sim_pin_status"
-
-#define EVENT_SAT_ENVELOPE_RESP "sat_envelope_response"
-#define EVENT_SAT_REFRESH_STATUS "sat_refresh_status"
-#define EVENT_SAT_PROACTIVE_COMMAND "sat_proactive_command"
-#define EVENT_SAT_CONTROL_RESULT "sat_control_result"
-
-
-#define EVENT_CALL_STATUS "call_status"
-#define EVENT_CALL_INCOMING "call_incoming"
-
-#define EVENT_NETWORK_REGISTRATION "network_regist"
-#define EVENT_NETWORK_ICON_INFO "network_icon_info"
-#define EVENT_NETWORK_TIME_INFO "network_time_info"
-#define EVENT_NETWORK_IDENTITY "network_identity"
-
-#define EVENT_SMS_INCOM_MSG "sms_incom_msg"
-#define EVENT_SMS_SEND_ACK "sms_send_ack"
-#define EVENT_SMS_MEMORY_STATUS "sms_memory_status"
-#define EVENT_SMS_CB_INCOM_MSG "sms_cb_incom_msg"
-#define EVENT_SMS_DELETE_MSG_CNF "sms_delete_msg_cnf"
-#define EVENT_SMS_WRITE_MSG_CNF "sms_write_msg_cnf"
-#define EVENT_SMS_DELIVERY_RPT_CNF "sms_deliver_rpt_cnf"
-#define EVENT_SMS_DEVICE_READY "sms_device_ready"
-
-#define EVENT_PHONEBOOK_STATUS "phonebook_status"
-#define EVENT_PHONEBOOK_FIRST_INDEX "phonebook_first_index"
-
-enum direction_e {
- RX,
- TX
-};
-
-struct global_data {
- unsigned int msg_auto_id_current;
- unsigned int msg_auto_id_start;
- unsigned int msg_auto_id_end;
-};
-
-struct work_queue_data {
- unsigned int id;
- UserRequest *ur;
-};
-
-#define UTIL_ID(hdr) ((hdr).main_cmd << 8 | (hdr).sub_cmd)
-#define UTIL_IDP(hdr) ((hdr)->main_cmd << 8 | (hdr)->sub_cmd)
-
-void hook_hex_dump(enum direction_e d, int size, const void *data);
-unsigned int util_assign_message_sequence_id(TcorePlugin *p);
-gboolean util_add_waiting_job(GQueue *queue, unsigned int id, UserRequest *ur);
-UserRequest* util_pop_waiting_job(GQueue *queue, unsigned int id);
-void util_hex_dump(char *pad, int size, const void *data);
-unsigned char util_hexCharToInt(char c);
-char* util_hexStringToBytes(char * s);
-
-#endif
-#sbs-git:slp/pkgs/t/tel-plugin-atmodem
-Name: tel-plugin-atmodem
-Summary: Telephony AT Modem library
-Version: 0.1.40
+%define major 3
+%define minor 0
+%define patchlevel 1
+
+Name: tel-plugin-atmodem
+Summary: Telephony AT Modem library
+Version: %{major}.%{minor}.%{patchlevel}
Release: 1
Group: System/Libraries
License: Apache-2.0
BuildRequires: pkgconfig(dlog)
BuildRequires: pkgconfig(tcore)
BuildRequires: pkgconfig(libtzplatform-config)
+BuildRequires: pkgconfig(vconf)
%description
Telephony AT Modem library
/*
* tel-plugin-atmodem
*
- * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: Ja-young Gu <jygu@samsung.com>
+ * Copyright (c) 2013 Samsung Electronics Co. Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
+++ /dev/null
-/* //device/system/reference-ril/at_tok.c
-**
-** Copyright 2006, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-#include "at_tok.h"
-#include <string.h>
-#include <ctype.h>
-#include <stdlib.h>
-
-/**
- * Starts tokenizing an AT response string
- * returns -1 if this is not a valid response string, 0 on success.
- * updates *p_cur with current position
- */
-int at_tok_start(char **p_cur)
-{
- if (*p_cur == NULL) {
- return -1;
- }
-
- // skip prefix
- // consume "^[^:]:"
-
- *p_cur = strchr(*p_cur, ':');
-
- if (*p_cur == NULL) {
- return -1;
- }
-
- (*p_cur)++;
-
- return 0;
-}
-
-static void skipWhiteSpace(char **p_cur)
-{
- if (*p_cur == NULL) return;
-
- while (**p_cur != '\0' && isspace(**p_cur)) {
- (*p_cur)++;
- }
-}
-
-static void skipNextComma(char **p_cur)
-{
- if (*p_cur == NULL) return;
-
- while (**p_cur != '\0' && **p_cur != ',') {
- (*p_cur)++;
- }
-
- if (**p_cur == ',') {
- (*p_cur)++;
- }
-}
-
-static char * nextTok(char **p_cur)
-{
- char *ret = NULL;
-
- skipWhiteSpace(p_cur);
-
- if (*p_cur == NULL) {
- ret = NULL;
- } else if (**p_cur == '"') {
- (*p_cur)++;
- ret = strsep(p_cur, "\"");
- skipNextComma(p_cur);
- } else {
- ret = strsep(p_cur, ",");
- }
-
- return ret;
-}
-
-
-/**
- * Parses the next integer in the AT response line and places it in *p_out
- * returns 0 on success and -1 on fail
- * updates *p_cur
- * "base" is the same as the base param in strtol
- */
-
-static int at_tok_nextint_base(char **p_cur, int *p_out, int base, int uns)
-{
- char *ret;
-
- if (*p_cur == NULL) {
- return -1;
- }
-
- ret = nextTok(p_cur);
-
- if (ret == NULL) {
- return -1;
- } else {
- long l;
- char *end;
-
- if (uns)
- l = strtoul(ret, &end, base);
- else
- l = strtol(ret, &end, base);
-
- *p_out = (int)l;
-
- if (end == ret) {
- return -1;
- }
- }
-
- return 0;
-}
-
-/**
- * Parses the next base 10 integer in the AT response line
- * and places it in *p_out
- * returns 0 on success and -1 on fail
- * updates *p_cur
- */
-int at_tok_nextint(char **p_cur, int *p_out)
-{
- return at_tok_nextint_base(p_cur, p_out, 10, 0);
-}
-
-/**
- * Parses the next base 16 integer in the AT response line
- * and places it in *p_out
- * returns 0 on success and -1 on fail
- * updates *p_cur
- */
-int at_tok_nexthexint(char **p_cur, int *p_out)
-{
- return at_tok_nextint_base(p_cur, p_out, 16, 1);
-}
-
-int at_tok_nextbool(char **p_cur, char *p_out)
-{
- int ret;
- int result;
-
- ret = at_tok_nextint(p_cur, &result);
-
- if (ret < 0) {
- return -1;
- }
-
- // booleans should be 0 or 1
- if (!(result == 0 || result == 1)) {
- return -1;
- }
-
- if (p_out != NULL) {
- *p_out = (char)result;
- }
-
- return ret;
-}
-
-int at_tok_nextstr(char **p_cur, char **p_out)
-{
- if (*p_cur == NULL) {
- return -1;
- }
-
- *p_out = nextTok(p_cur);
-
- return 0;
-}
-
-/** returns 1 on "has more tokens" and 0 if no */
-int at_tok_hasmore(char **p_cur)
-{
- return ! (*p_cur == NULL || **p_cur == '\0');
-}
-
-void at_tok_skip_bracket(char **p_cur)
-{
- if (*p_cur == NULL) return;
-
- while (**p_cur != '\0' && **p_cur == '(') {
- (*p_cur)++;
- }
-}
-
-
+++ /dev/null
-/* //device/system/reference-ril/atchannel.c
-**
-** Copyright 2006, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-#include "atchannel.h"
-#include "at_tok.h"
-
-#include <stdio.h>
-#include <string.h>
-#include <pthread.h>
-#include <ctype.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <sys/time.h>
-#include <time.h>
-#include <unistd.h>
-
-extern enum ATCommandType s_type;
-extern char *s_responsePrefix;
-extern struct ATResponse *sp_response;
-
-/**
- * returns 1 if line is a final response indicating success
- * See 27.007 annex B
- */
-static const char * s_finalResponsesSuccess[] = {
- "OK",
-};
-/**
- * returns 1 if line is a final response indicating error
- * See 27.007 annex B
- */
-static const char * s_finalResponsesError[] = {
- "ERROR",
- "+CMS ERROR:",
- "+CME ERROR:",
- "NO ANSWER",
- "NO DIALTONE",
-};
-
-
-struct ATResponse * at_response_new()
-{
- return (struct ATResponse *) calloc(1, sizeof(struct ATResponse));
-}
-
-void at_response_free(struct ATResponse *p_response)
-{
- struct ATLine *p_line;
-
- if (p_response == NULL) return;
-
- p_line = p_response->p_intermediates;
-
- while (p_line != NULL) {
- struct ATLine *p_toFree;
-
- p_toFree = p_line;
- p_line = p_line->p_next;
-
- free(p_toFree->line);
- free(p_toFree);
- }
-
- free (p_response->finalResponse);
- free (p_response);
-}
-
-char * findNextEOL(char *cur)
-{
- if (cur[0] == '>' && cur[1] == ' ' && cur[2] == '\0') {
- /* SMS prompt character...not \r terminated */
- return cur+2;
- }
-
- // Find next newline
- while (*cur != '\0' && *cur != '\r' && *cur != '\n') cur++;
-
- return *cur == '\0' ? NULL : cur;
-}
-
-/** returns 1 if line starts with prefix, 0 if it does not */
-int strStartsWith(const char *line, const char *prefix)
-{
- for ( ; *line != '\0' && *prefix != '\0' ; line++, prefix++) {
- if (*line != *prefix) {
- return 0;
- }
- }
-
- return *prefix == '\0';
-}
-
-int isFinalResponseError(const char *line)
-{
- unsigned int i;
-
- for (i = 0 ; i < NUM_ELEMS(s_finalResponsesError) ; i++) {
- if (strStartsWith(line, s_finalResponsesError[i])) {
- return 1;
- }
- }
-
- return 0;
-}
-
-int isFinalResponseSuccess(const char *line)
-{
- unsigned int i;
-
- for (i = 0 ; i < NUM_ELEMS(s_finalResponsesSuccess) ; i++) {
- if (strStartsWith(line, s_finalResponsesSuccess[i])) {
- return 1;
- }
- }
-
- return 0;
-}
-
-/**
- * returns 1 if line is a final response, either error or success
- * See 27.007 annex B
- */
-int isFinalResponse(const char *line)
-{
- return isFinalResponseSuccess(line) || isFinalResponseError(line);
-}
-
-/** add an intermediate response to sp_response*/
-void addIntermediate(const char *line)
-{
- struct ATLine *p_new;
-
- printf("addIntermediate line arrived : %s", line);
-
- p_new = (struct ATLine*) malloc(sizeof(struct ATLine));
-
- p_new->line = strdup(line);
-
- /* note: this adds to the head of the list, so the list
- will be in reverse order of lines received. the order is flipped
- again before passing on to the command issuer */
- p_new->p_next = sp_response->p_intermediates;
- sp_response->p_intermediates = p_new;
-}
-
-
-//** release sp_response & s_responsePrefix
-void ReleaseResponse(void)
-{
- if(sp_response!=NULL)
- {
- at_response_free(sp_response);
- sp_response = NULL;
- }
-
- if(s_responsePrefix!= NULL)
- {
- free(s_responsePrefix);
- s_responsePrefix = NULL;
- }
-
- s_type = NO_RESULT;
-}
-
-void reverseIntermediates(struct ATResponse *p_response)
-{
- struct ATLine *pcur,*pnext;
-
- pcur = p_response->p_intermediates;
- p_response->p_intermediates = NULL;
-
- while (pcur != NULL) {
- pnext = pcur->p_next;
- pcur->p_next = p_response->p_intermediates;
- p_response->p_intermediates = pcur;
- pcur = pnext;
- }
-}
-
-void printResponse(void)
-{
- struct ATLine *pcur= NULL;
- struct ATLine *pnext= NULL;
- int count =0;
-
- printf("sp_response.success : %d\n", sp_response->success);
-
- if(sp_response->finalResponse ==NULL)
- {
- printf("sp_response.finalResponse : NULL\n");
- }
- else
- {
- printf("sp_response.finalResponse : %s\n",sp_response->finalResponse);
- }
-
-
- pcur = sp_response->p_intermediates;
-
- if(pcur ==NULL)
- {
- printf("sp_response.p_intermediates : NULL\n");
- }
-
- while(pcur != NULL)
- {
- printf("sp_response.p_intermediates[%d] : %s\n",count,pcur->line);
- pnext = pcur->p_next;
- pcur = pnext;
- count++;
- }
-}
-
-TReturn convertCMEError(enum ATCMEError error)
-{
- printf("CMEerror : %d", error);
-
- //mapping will be done later
- return TCORE_RETURN_3GPP_ERROR;
-
-}
--- /dev/null
+/*
+ * tel-plugin-atmodem
+ *
+ * Copyright (c) 2013 Samsung Electronics Co. Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <glib.h>
+
+#include <tcore.h>
+#include <server.h>
+#include <plugin.h>
+#include <core_object.h>
+#include <hal.h>
+#include <queue.h>
+#include <storage.h>
+#include <at.h>
+
+#include <co_call.h>
+
+#include "atmodem_call.h"
+#include "atmodem_common.h"
+
+/* Call Status */
+typedef enum {
+ ATMODEM_CALL_STATUS_ACTIVE,
+ ATMODEM_CALL_STATUS_HELD,
+ ATMODEM_CALL_STATUS_DIALING,
+ ATMODEM_CALL_STATUS_ALERT,
+ ATMODEM_CALL_STATUS_INCOMING,
+ ATMODEM_CALL_STATUS_WAITING,
+ ATMODEM_CALL_STATUS_CONNECTING,
+ ATMODEM_CALL_STATUS_DISCONNECTED,
+ ATMODEM_CALL_STATUS_IDLE
+} AtmodemCallStatus;
+
+static void on_response_atmodem_call_default(TcorePending *p,
+ guint data_len, const void *data, void *user_data);
+
+static TelReturn __atmodem_call_get_call_list(CoreObject *co, gboolean flag);
+
+static TelCallType __atmodem_call_type(gint type)
+{
+ dbg("Entry");
+
+ switch (type) {
+ case 0:
+ return TEL_CALL_TYPE_VOICE;
+ case 1:
+ return TEL_CALL_TYPE_VIDEO;
+ default:
+ err("invalid call type, returing default call type as voice");
+ return TEL_CALL_TYPE_VOICE;
+ }
+}
+
+static TelCallState __atmodem_call_state(AtmodemCallStatus state)
+{
+ dbg("Entry");
+
+ switch (state) {
+ case ATMODEM_CALL_STATUS_ACTIVE:
+ return TEL_CALL_STATE_ACTIVE;
+
+ case ATMODEM_CALL_STATUS_HELD:
+ return TEL_CALL_STATE_HELD;
+
+ case ATMODEM_CALL_STATUS_DIALING:
+ return TEL_CALL_STATE_DIALING;
+
+ case ATMODEM_CALL_STATUS_ALERT:
+ return TEL_CALL_STATE_ALERT;
+
+ case ATMODEM_CALL_STATUS_INCOMING:
+ case ATMODEM_CALL_STATUS_WAITING:
+ return TEL_CALL_STATE_INCOMING;
+
+ default:
+ return TEL_CALL_STATE_IDLE;
+ }
+}
+
+static void __atmodem_call_branch_by_status(CoreObject *co,
+ CallObject *call_obj, TelCallState call_state)
+{
+ guint call_id;
+ TelCallType call_type;
+ TelCallState state;
+ TcoreNotification command = TCORE_NOTIFICATION_UNKNOWN;
+
+ if (tcore_call_object_get_state(call_obj, &state) == FALSE) {
+ err("Unable to get Call status");
+ return;
+ }
+
+ dbg("Call State - Present : [%d] New: [%d]", state, call_state);
+ if (call_state == state) {
+ dbg("No change in Call State...");
+ return;
+ }
+
+ if (tcore_call_object_get_call_type(call_obj, &call_type) == FALSE) {
+ err("Unable to get Call type");
+ return;
+ }
+
+ if (tcore_call_object_get_id(call_obj, &call_id) == FALSE) {
+ err("Unable to get Call id");
+ return;
+ }
+
+ /* Update Call state */
+ tcore_call_object_set_state(call_obj, call_state);
+
+ if (call_type == TEL_CALL_TYPE_VOICE) { /* Voice call notification */
+ switch (call_state) {
+ case TEL_CALL_STATE_ACTIVE:
+ command = TCORE_NOTIFICATION_CALL_STATUS_ACTIVE;
+ break;
+
+ case TEL_CALL_STATE_HELD:
+ command = TCORE_NOTIFICATION_CALL_STATUS_HELD;
+ break;
+
+ case TEL_CALL_STATE_DIALING:
+ command = TCORE_NOTIFICATION_CALL_STATUS_DIALING;
+ break;
+
+ case TEL_CALL_STATE_ALERT:
+ command = TCORE_NOTIFICATION_CALL_STATUS_ALERT;
+ break;
+
+ case TEL_CALL_STATE_INCOMING:
+ case TEL_CALL_STATE_WAITING:
+ command = TCORE_NOTIFICATION_CALL_STATUS_INCOMING;
+ break;
+
+ case TEL_CALL_STATE_IDLE: {
+ TelCallStatusIdleNoti idle;
+
+ idle.call_id = call_id;
+ /* TODO - get proper call end cause. */
+ idle.cause = TEL_CALL_END_CAUSE_NONE;
+
+ /* Send notification */
+ tcore_object_send_notification(co,
+ TCORE_NOTIFICATION_CALL_STATUS_IDLE,
+ sizeof(TelCallStatusIdleNoti), &idle);
+
+ /* Free Call object */
+ tcore_call_object_free(co, call_obj);
+
+ return;
+ }
+ }
+ } else {
+ err("Unknown Call type: [%d]", call_type);
+ return;
+ }
+
+ /* Send notification */
+ tcore_object_send_notification(co,
+ command, sizeof(call_id), &call_id);
+}
+
+static void __atmodem_handle_call_get_call_list(CoreObject *co,
+ gboolean flag, void *data)
+{
+ gint call_id;
+ gint direction;
+ gint mode;
+ gint state;
+ gint mpty;
+ gint ton;
+ GSList *tokens = NULL;
+ gchar *resp = NULL;
+ gchar *line;
+ gchar *num = NULL;
+ gint num_type;
+ gchar number[TEL_CALL_CALLING_NUMBER_LEN_MAX + 1] = {0, };
+ GSList *lines = data;
+ CallObject *call_obj = NULL;
+
+ while (lines != NULL) {
+ line = (gchar *)lines->data;
+ /* point to next node */
+ lines = lines->next;
+
+ /* free previous tokens*/
+ tcore_at_tok_free(tokens);
+
+ tokens = tcore_at_tok_new(line);
+ resp = g_slist_nth_data(tokens, 0);
+ if (NULL == resp) {
+ err("Invalid call_id");
+ continue;
+ }
+
+ call_id = atoi(resp);
+ resp = g_slist_nth_data(tokens, 1);
+ if (NULL == resp) {
+ err("Invalid direction");
+ continue;
+ }
+
+ direction = (atoi(resp) == 0) ? 1 : 0;
+ resp = g_slist_nth_data(tokens, 2);
+ if (NULL == resp) {
+ err("Invalid state");
+ continue;
+ }
+
+ state = __atmodem_call_state(atoi(resp));
+ resp = g_slist_nth_data(tokens, 3);
+ if (NULL == resp) {
+ err("Invalid mode");
+ continue;
+ }
+ mode = __atmodem_call_type(atoi(resp));
+
+ resp = g_slist_nth_data(tokens, 4);
+ if (NULL == resp) {
+ err("Invalid mpty");
+ continue;
+ }
+ mpty = atoi(resp);
+
+ resp = g_slist_nth_data(tokens, 5);
+ if (NULL == resp) {
+ err("Number is NULL");
+ } else {
+ /* Strike off double quotes */
+ num = tcore_at_tok_extract(resp);
+ dbg("Number: [%s]", num);
+
+ resp = g_slist_nth_data(tokens, 6);
+ if (!resp) {
+ err("Invalid Number type");
+ } else {
+ num_type = atoi(resp);
+
+ /* Check if number is International or National */
+ ton = ((num_type) >> 4) & 0x07;
+ if (ton == 1 && num[0] != '+') {
+ /* International number */
+ number[0] = '+';
+ memcpy(&number[1], num, strlen(num));
+ } else {
+ memcpy(number, num, strlen(num));
+ }
+ }
+ g_free(num);
+ }
+
+ dbg("Call ID: [%d] Direction: [%s] Call Type: [%d] " \
+ "Multi-party: [%s] Number: [%s] Type-of-Number: [%d] State: [%d]", \
+ call_id, (direction ? "Outgoing" : "Incoming"),
+ mode, (mpty ? "YES" : "NO"), number, ton, state);
+
+ call_obj = tcore_call_object_find_by_id(co, call_id);
+ if (NULL == call_obj) {
+ call_obj = tcore_call_object_new(co, call_id);
+ if (NULL == call_obj) {
+ err("Unable to create call object");
+ continue;
+ }
+ }
+
+ /* Set Call parameters */
+ tcore_call_object_set_type(call_obj, mode);
+ tcore_call_object_set_direction(call_obj, direction);
+ tcore_call_object_set_multiparty_state(call_obj, mpty);
+ if (number[0] != '\0')
+ tcore_call_object_set_cli_info(call_obj,
+ TEL_CALL_CLI_VALIDITY_VALID, number);
+ else
+ tcore_call_object_set_cli_info(call_obj,
+ TEL_CALL_CLI_VALIDITY_NOT_AVAILABLE, number);
+ tcore_call_object_set_active_line(call_obj, TEL_CALL_ACTIVE_LINE1);
+ if (flag == TRUE)
+ __atmodem_call_branch_by_status(co, call_obj, state);
+ else
+ tcore_call_object_set_state(call_obj, state);
+ }
+}
+
+/* Incoming Call notification */
+static void __on_notification_atmodem_call_incoming(CoreObject *co,
+ guint call_id, const void *data)
+{
+ GSList *list = NULL;
+ GSList *tokens = NULL;
+ gchar *resp = NULL;
+ gchar *line;
+ gboolean direction = TRUE;
+ gint mode;
+ gpointer state;
+ gint call_state;
+ gint mpty;
+ gint ton;
+ gchar *num = NULL;
+ gchar number[TEL_CALL_CALLING_NUMBER_LEN_MAX + 1] = {0, };
+ GSList *lines = (GSList *)data;
+ CallObject *call_obj = NULL;
+
+ dbg("Entry");
+
+ /* Check call with 'Incoming' status already exist */
+ list = tcore_call_object_find_by_status(co, TEL_CALL_STATE_INCOMING);
+ if (list != NULL) {
+ err("Incoming Call already exist... Skip!!!");
+ return;
+ }
+
+ call_obj = tcore_call_object_find_by_id(co, call_id);
+ if (call_obj != NULL) {
+ err("co with same id already exist. skip");
+ return;
+ }
+
+ /* Create Call object */
+ call_obj = tcore_call_object_new(co, (guint)call_id);
+ if (NULL == call_obj) {
+ err(" Unable to create call object");
+ return;
+ }
+
+ lines = (GSList *)data;
+ if (lines == NULL) {
+ err("Invalid response received");
+ return;
+ }
+
+ line = (gchar *)lines->data;
+
+ /* Tokenize */
+ tokens = tcore_at_tok_new(line);
+
+ state = g_slist_nth_data(tokens, 2);
+ if (NULL == state) {
+ err("State is missing");
+ goto out;
+ }
+ call_state = __atmodem_call_state(atoi(state));
+
+ resp = g_slist_nth_data(tokens, 3);
+ if (NULL == resp) {
+ err("Invalid mode");
+ goto out;
+ }
+ mode = __atmodem_call_type(atoi(resp));
+
+ resp = g_slist_nth_data(tokens, 4);
+ if (NULL == resp) {
+ err("Invalid mpty");
+ goto out;
+ }
+ mpty = atoi(resp);
+
+ resp = g_slist_nth_data(tokens, 5);
+ if (NULL == resp) {
+ err("Number is NULL");
+ } else {
+ /* Strike off double quotes */
+ num = tcore_at_tok_extract(resp);
+ dbg("Number: [%s]", num);
+
+ memcpy(number, num, strlen(num));
+ number[strlen(num)] = '\0';
+ g_free(num);
+ }
+
+ dbg("Call ID: [%d] Direction: [%s] Call Type: [%d] " \
+ "Multi-party: [%s] Number: [%s] Type-of-Number: [%d] State: [%d]", \
+ call_id, (direction ? "Outgoing" : "Incoming"),
+ mode, (mpty ? "YES" : "NO"), number, ton, call_state); /* Set Call parameters */
+
+ /* Update Call Object */
+ tcore_call_object_set_type(call_obj, mode);
+ tcore_call_object_set_direction(call_obj, direction);
+ tcore_call_object_set_multiparty_state(call_obj, mpty);
+ if (number[0] != '\0')
+ tcore_call_object_set_cli_info(call_obj,
+ TEL_CALL_CLI_VALIDITY_VALID, number);
+ else
+ tcore_call_object_set_cli_info(call_obj,
+ TEL_CALL_CLI_VALIDITY_NOT_AVAILABLE, number);
+ tcore_call_object_set_active_line(call_obj, TEL_CALL_ACTIVE_LINE1);
+
+ /* Send notification */
+ __atmodem_call_branch_by_status(co, call_obj, call_state);
+
+out:
+ /* Free tokens */
+ tcore_at_tok_free(tokens);
+}
+
+static void __on_notification_atmodem_call_status(CoreObject *co,
+ guint call_id, AtmodemCallStatus call_state)
+{
+ CallObject *call_obj = NULL;
+ TelCallState state;
+
+ state = __atmodem_call_state(call_state);
+ dbg("Call state [%d]", state);
+
+ switch (state) {
+ case TEL_CALL_STATE_ACTIVE:
+ case TEL_CALL_STATE_HELD:
+ case TEL_CALL_STATE_ALERT:
+ case TEL_CALL_STATE_IDLE: {
+ call_obj = tcore_call_object_find_by_id(co, call_id);
+ if (call_obj == NULL) {
+ err("Unable to find Call Object - Call ID: [%d]", call_id);
+ return;
+ }
+
+ /* Send notification to application */
+ __atmodem_call_branch_by_status(co, call_obj, state);
+ }
+ break;
+
+ case TEL_CALL_STATE_DIALING: {
+ call_obj = tcore_call_object_find_by_id(co, call_id);
+ if (!call_obj) {
+ call_obj = tcore_call_object_new(co, call_id);
+ if (!call_obj) {
+ err("Unable to create Call Object");
+ return;
+ }
+ }
+
+ /*
+ * Make request to get current Call list.
+ * Update CallObject with <number>
+ * and send notification to application
+ */
+ __atmodem_call_get_call_list(co, TRUE);
+ }
+ break;
+
+ default:
+ err("Unhandled Call Status: [%d]", state);
+ break;
+ }
+}
+
+/* Internal response operation */
+static void __on_response_atmodem_call_get_call_list(TcorePending *p,
+ guint data_len, const void *data, void *user_data)
+{
+ const TcoreAtResponse *at_resp = data;
+ CoreObject *co = tcore_pending_ref_core_object(p);
+ AtmodemRespCbData *resp_cb_data = user_data;
+ GSList *lines = NULL;
+ TelCallResult result = TEL_CALL_RESULT_FAILURE; //TODO - CME error mapping required
+ gboolean *flag = ATMODEM_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
+ gint count;
+ dbg("Entry");
+
+ tcore_check_return_assert(co != NULL);
+ tcore_check_return_assert(resp_cb_data != NULL);
+
+ if (at_resp && at_resp->success) {
+ result = TEL_CALL_RESULT_SUCCESS;
+ if (NULL == at_resp->lines) {
+ err("invalid response received");
+ return;
+ }
+
+ lines = (GSList *)at_resp->lines;
+ count = g_slist_length(lines);
+ dbg("Total records : %d", g_slist_length(lines));
+ if (0 == count) {
+ err("Call count is zero");
+ return;
+ }
+
+ dbg("RESPONSE OK");
+
+ /* Process +CLCC notification parameter */
+ __atmodem_handle_call_get_call_list(co, *flag, lines);
+
+ } else {
+ err("RESPONSE NOK");
+ }
+
+ atmodem_destroy_resp_cb_data(resp_cb_data);
+}
+
+/*internal request operation */
+static TelReturn __atmodem_send_call_request(CoreObject *co,
+ TcoreObjectResponseCallback cb, void *cb_data,
+ gchar *at_cmd, gchar *func_name)
+{
+ AtmodemRespCbData *resp_cb_data;
+ TelReturn ret;
+
+ /* Response callback data */
+ resp_cb_data = atmodem_create_resp_cb_data(cb, cb_data, func_name, strlen(func_name) + 1);
+
+ /* Send Request to modem */
+ ret = tcore_at_prepare_and_send_request(co,
+ at_cmd, NULL,
+ TCORE_AT_COMMAND_TYPE_NO_RESULT,
+ TCORE_PENDING_PRIORITY_DEFAULT,
+ NULL,
+ on_response_atmodem_call_default, resp_cb_data,
+ on_send_atmodem_request, NULL,
+ 0, NULL, NULL);
+ ATMODEM_CHECK_REQUEST_RET(ret, resp_cb_data, func_name);
+
+ /* Free resources */
+ g_free(at_cmd);
+ return ret;
+}
+
+ /*
+ * Operation - Get current call list.
+ *
+ * Request -
+ * AT-Command: AT+CLCC
+ *
+ * Response -
+ * Success:
+ *[+CLCC: <id1>, <dir>, <stat>, <mode>,<mpty>[,<number>,<type>[,<alpha>[,<priority>]]]
+ *[<CR><LF> +CLCC: <id2>,<dir>,<stat>,<mode>,<mpty>[,<number>,<type>[,<alpha>[,<priority>]]][\85]]]
+ * OK
+ * Failure:
+ * +CME ERROR: <error>
+ */
+static TelReturn __atmodem_call_get_call_list(CoreObject *co, gboolean flag)
+{
+ AtmodemRespCbData *resp_cb_data;
+ TelReturn ret =TEL_RETURN_FAILURE;
+ dbg("Entry");
+
+ if (NULL == co) {
+ err("Core Object is NULL");
+ return ret;
+ }
+ /* Response callback data */
+ resp_cb_data = atmodem_create_resp_cb_data(NULL, NULL, &flag, sizeof(gboolean));
+
+ /* Send Request to modem */
+ ret = tcore_at_prepare_and_send_request(co,
+ "AT+CLCC","+CLCC",
+ TCORE_AT_COMMAND_TYPE_MULTILINE,
+ TCORE_PENDING_PRIORITY_DEFAULT,
+ NULL,
+ __on_response_atmodem_call_get_call_list, resp_cb_data,
+ on_send_atmodem_request, NULL,
+ 0, NULL, NULL);
+ ATMODEM_CHECK_REQUEST_RET(ret, resp_cb_data, "Get current call list");
+
+ return ret;
+}
+
+/* Notification */
+/*
+* Operation - call status notification from network.
+* notification message format:
+* %SCLCC: <call_id><direction><status><type><mpty>
+* where
+* <call_id>
+* indicates the call identification.
+* <direction>
+* indicates call direction (MO or MT)
+* <status>
+* 0 active
+* 1 hold
+* 2 dialling (MO call)
+* 3 alerting (MO call; ringing for the remote party)
+* 4 ringing (MT call)
+* 5 waiting (MT call)
+* 6 connecting (MO call)
+* 7 disconneted
+* <type>
+* call type
+* <mpty>
+* multiparty call
+*
+*/
+static gboolean on_notification_atmodem_call_status(CoreObject *co,
+ const void *data, void *user_data)
+{
+ GSList *tokens = NULL;
+ GSList *lines = NULL;
+ const gchar *line = NULL;
+ gchar *state = NULL, *call_handle = NULL;
+ AtmodemCallStatus status;
+ guint call_id;
+
+ dbg("Entry");
+
+ lines = (GSList *)data;
+ if (lines == NULL) {
+ err("Invalid response received");
+ return TRUE;
+ }
+
+ line = (gchar *)lines->data;
+
+ /* Tokenize */
+ tokens = tcore_at_tok_new(line);
+ call_handle = g_slist_nth_data(tokens, 0);
+ if (NULL == call_handle) {
+ err("call_id missing");
+ goto out;
+ }
+ call_id = atoi(call_handle);
+
+ state = g_slist_nth_data(tokens, 2);
+ if (NULL == state) {
+ err("State is missing");
+ goto out;
+ }
+ status = atoi(state);
+
+ dbg("Call ID: [%d] Call Status: [%d]", call_id, status);
+
+ switch (status) {
+ case ATMODEM_CALL_STATUS_INCOMING:
+ case ATMODEM_CALL_STATUS_WAITING:
+ dbg("Incoming/Waiting Call...");
+ __on_notification_atmodem_call_incoming(co, call_id, data);
+ break;
+
+ default:
+ __on_notification_atmodem_call_status(co, call_id, status);
+ break;
+ }
+
+out:
+ /* Free tokens */
+ tcore_at_tok_free(tokens);
+ return TRUE;
+}
+
+/*
+ * Operation - SS network initiated notification.
+ *
+ * notification message format:
+ * +CSSU: <code2>[<index> [,<number>,<type>]]
+ * <code2>
+ * (it is manufacturer specific, which of these codes are supported):
+ * 0 this is a forwarded call (MT call setup)
+ * 1 this is a CUG call (<index> present) (MT call setup)
+ * 2 call has been put on hold (during a voice call)
+ * 3 call has been retrieved (during a voice call)
+ * 4 multiparty call entered (during a voice call)
+ * 5 Call has been released - not a SS notification (during a voice call)
+ * 6 forward check SS message received (can be received whenever)
+ * 7 call is being connected (alerting) with the remote party in alerting state
+ * in explicit call transfer operation
+ * (during a voice call)
+ * 8 call has been connected with the other remote party in explicit call transfer
+ * operation (during a voice call or MT call setup)
+ * 9 this is a deflected call (MT call setup)
+ * 10 additional incoming call forwarded
+ * <index>
+ * refer Closed user group +CCUG
+ * <number>
+ * string type phone of format specified by <type>
+ * <type>
+ * type of address octet in integer format.
+ */
+static gboolean on_notification_atmodem_call_ss_cssu_info(CoreObject *co,
+ const void *event_data, void *user_data)
+{
+ GSList *tokens = NULL;
+ TcoreNotification command = TCORE_NOTIFICATION_UNKNOWN;
+ gchar *resp = NULL;
+ gchar *cmd = 0;
+ gint index = 0;
+ gint code2 = -1;
+ gchar number[TEL_CALL_CALLING_NUMBER_LEN_MAX + 1] = {'\0',};
+
+ dbg("Entry");
+
+ if (1 != g_slist_length((GSList *) event_data)) {
+ err("unsolicited msg but multiple line");
+ return TRUE;
+ }
+
+ cmd = (gchar *) ((GSList *) event_data)->data;
+ dbg("ss notification message[%s]", cmd);
+
+ tokens = tcore_at_tok_new(cmd);
+
+ /* parse <code2> */
+ resp = g_slist_nth_data(tokens, 0);
+ if (NULL == resp) {
+ err("Code2 is missing from %CSSU indiaction");
+ tcore_at_tok_free(tokens);
+ return TRUE;
+ }
+ code2 = atoi(resp);
+
+ /* parse [ <index>, <number>] */
+ if ((resp = g_slist_nth_data(tokens, 1)))
+ index = atoi(resp);
+
+ if ((resp = g_slist_nth_data(tokens, 2))) {
+ resp = tcore_at_tok_extract((const gchar *)resp);
+ memcpy(number, resp, strlen(resp));
+ number[strlen(resp)] = '\0';;
+ g_free(resp);
+ }
+ dbg("+CSSU: <code2>: %d <index>: %d <number>: %s ", code2, index, number);
+
+ /* <code2> - other values will be ignored */
+ switch (code2) {
+ case 0:
+ command = TCORE_NOTIFICATION_CALL_INFO_MT_FORWARDED;
+ break;
+
+ case 2:
+ command = TCORE_NOTIFICATION_CALL_INFO_HELD;
+ break;
+
+ case 3:
+ command = TCORE_NOTIFICATION_CALL_INFO_ACTIVE;
+ break;
+
+ case 4:
+ command = TCORE_NOTIFICATION_CALL_INFO_JOINED;
+ break;
+
+ case 7:
+ case 8:
+ command = TCORE_NOTIFICATION_CALL_INFO_TRANSFERED;
+ break;
+
+ case 9:
+ command = TCORE_NOTIFICATION_CALL_INFO_MT_DEFLECTED;
+ break;
+
+ default:
+ dbg("Unsupported +CSSU notification: [%d]", code2);
+ break;
+ }
+
+ if (command != TCORE_NOTIFICATION_UNKNOWN)
+ tcore_object_send_notification(co, command, 0, NULL);
+
+ tcore_at_tok_free(tokens);
+ return TRUE;
+}
+
+/* Response */
+static void on_response_atmodem_call_default(TcorePending *p,
+ guint data_len, const void *data, void *user_data)
+{
+ const TcoreAtResponse *at_resp = data;
+ CoreObject *co = tcore_pending_ref_core_object(p);
+ AtmodemRespCbData *resp_cb_data = user_data;
+
+ TelCallResult result;
+ dbg("Entry");
+
+ tcore_check_return_assert(co != NULL);
+ tcore_check_return_assert(resp_cb_data != NULL);
+
+ if (at_resp && at_resp->success) {
+ result = TEL_CALL_RESULT_SUCCESS;
+ } else {
+ err("ERROR: [%s]", at_resp->final_response);
+ result = TEL_CALL_RESULT_FAILURE;
+ /*
+ * TODO -
+ * need to map CME error and final response
+ * error to TelCallResult
+ */
+ }
+ dbg("%s: [%s]", ATMODEM_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data),
+ (result == TEL_CALL_RESULT_SUCCESS ? "SUCCESS" : "FAIL"));
+
+ /* Invoke callback */
+ if (resp_cb_data->cb)
+ resp_cb_data->cb(co, (gint)result, NULL, resp_cb_data->cb_data);
+
+ /* Free callback data */
+ atmodem_destroy_resp_cb_data(resp_cb_data);
+}
+
+ /* Request */
+ /*
+ * Operation - dial
+ *
+ * Request -
+ * AT-Command: ATD <num> [I] [G] [;]
+ * <num> - dialed number
+ * [I][i] - CLI presentation(supression or invocation)
+ * [G] - control the CUG supplementary service information for this call.
+ *
+ * Response -
+ * Success:
+ * OK or CONNECT
+ * Failure:
+ * "ERROR"
+ * "NO ANSWER"
+ * "NO CARRIER"
+ * "BUSY"
+ * "NO DIALTONE"
+ * +CME ERROR: <error>
+ */
+static TelReturn atmodem_call_dial(CoreObject *co, const TelCallDial *dial_info,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ gchar *at_cmd;
+ const gchar *clir;
+ gchar *num;
+ dbg("Entry");
+
+ if (dial_info->call_type == TEL_CALL_TYPE_VIDEO) {
+ err("Video call is not supported in atmodem");
+ return TEL_RETURN_OPERATION_NOT_SUPPORTED;
+ }
+
+ if (!strncmp(dial_info->number, "*31#", 4)) {
+ dbg("clir suppression");
+ clir = "i";
+ num = (gchar *)&(dial_info->number[4]);
+ } else if (!strncmp(dial_info->number, "#31#", 4)) {
+ dbg("clir invocation");
+ clir = "I";
+ num = (gchar *)&(dial_info->number[4]);
+ } else {
+ dbg("set clir state to default");
+ clir = "";
+ num = (gchar *)dial_info->number;
+ }
+
+ /* AT-Command */
+ at_cmd = g_strdup_printf("ATD%s%s;", num, clir);
+ dbg(" at command : %s", at_cmd);
+
+ return __atmodem_send_call_request(co, cb, cb_data, at_cmd, "atmodem_call_answer");
+}
+
+/*
+ * Operation - Answer/Reject/Replace/hold(current call) & accept incoming call.
+ *
+ * Request -
+ *
+ * 1. AT-Command: ATA
+ * Response -
+ * Success:
+ * OK
+ * Failure:
+ * +CME ERROR: <error>
+ *
+ * 2. AT-Command: AT+CHLD=[<n>]
+ * <n>
+ * 0 - (deafult)release all held calls or set User Determined User Busy for a waiting/incoming
+ * call; if both exists then only the waiting call will be rejected.
+ * 1 - release all active calls and accepts the other (held or waiting)
+ * Note: In the scenario: An active call, a waiting call and held call, when the active call is
+ * terminated, we will make the Waiting call as active.
+ * 2 - place all active calls (if exist) on hold and accepts the other call (held or waiting/in-coming).
+ * If only one call exists which is active, place it on hold and if only held call exists make it active call.
+ * Response -
+ * Success:
+ * OK
+ * Failure:
+ * +CME ERROR: <error>
+ * For more informatiion refer 3GPP TS 27.007.
+ */
+static TelReturn atmodem_call_answer(CoreObject *co, TelCallAnswerType ans_type,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ gchar *at_cmd;
+ dbg("Entry");
+
+ if (ans_type == TEL_CALL_ANSWER_ACCEPT) {
+ /* AT-Command */
+ at_cmd = g_strdup_printf("%s", "ATA");
+ }else if (ans_type == TEL_CALL_ANSWER_REJECT) {
+ /* AT-Command */
+ at_cmd = g_strdup_printf("%s", "AT+CHLD=0");
+ } else if (ans_type == TEL_CALL_ANSWER_REPLACE) {
+ /* AT-Command */
+ at_cmd = g_strdup_printf("%s", "AT+CHLD=1");
+ } else if (ans_type == TEL_CALL_ANSWER_HOLD_AND_ACCEPT) {
+ /* AT-Command */
+ at_cmd = g_strdup_printf("%s", "AT+CHLD=2");
+ }else {
+ err("Unsupported call answer type");
+ return TEL_RETURN_FAILURE;
+ }
+
+ dbg("at command : %s", at_cmd);
+
+ return __atmodem_send_call_request(co, cb, cb_data, at_cmd, "atmodem_call_answer");
+}
+
+/*
+ * Operation - release all calls/release specific call/release all active call/release all held calls.
+ *
+ * Request -
+ * 1. AT-Command: AT+CHLD=[<n>]
+ * <n>
+ * 0 - (defualt)release all held calls or set User Determined User Busy for a waiting/incoming.
+ * call; if both exists then only the waiting call will be rejected.
+ * 1 - release all active calls and accepts the other (held or waiting).
+ * 1x - release a specific call (x specific call number as indicated by call id).
+ * 8 - release all calls.
+ * Response -
+ * Success:
+ * OK
+ * Failure:
+ * +CME ERROR: <error>
+ */
+static TelReturn atmodem_call_end(CoreObject *co, const TelCallEnd *end_info,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ gchar *at_cmd;
+ dbg("Entry");
+
+ if (end_info->end_type == TEL_CALL_END_ALL) {
+ /* AT-Command */
+ at_cmd = g_strdup_printf("%s", "AT+CHLD=8");
+ }else if (end_info->end_type == TEL_CALL_END) {
+ /* AT-Command */
+ at_cmd = g_strdup_printf("%s%d", "AT+CHLD=1",end_info->call_id);
+ } else if (end_info->end_type == TEL_CALL_END_ACTIVE_ALL) {
+ /* AT-Command */
+ at_cmd = g_strdup_printf("%s", "AT+CHLD=1");
+ } else if (end_info->end_type == TEL_CALL_END_HOLD_ALL) {
+ /* AT-Command */
+ at_cmd = g_strdup_printf("%s", "AT+CHLD=0");
+ }else {
+ err("Unsupported call end type");
+ return TEL_RETURN_FAILURE;
+ }
+
+ dbg("at command : %s", at_cmd);
+
+ return __atmodem_send_call_request(co, cb, cb_data, at_cmd, "atmodem_call_end");
+}
+
+/*
+ * Operation - call hold.
+ *
+ * Request -
+ * 1. AT-Command: AT+CHLD=[<n>]
+ * Where
+ * <n>
+ * 2 - place all active calls (if exist) on hold and accepts the other call (held or waiting/incoming).
+ * If only one call exists which is active, place it on hold and if only held call exists
+ * make it active call
+ * Response -
+ * Success:
+ * OK
+ * Failure:
+ * +CME ERROR: <error>
+ */
+static TelReturn atmodem_call_hold(CoreObject *co, TcoreObjectResponseCallback cb,
+ void *cb_data)
+
+{
+ gchar *at_cmd;
+ dbg("Entry");
+
+ at_cmd = g_strdup_printf("%s", "AT+CHLD=2");
+ dbg("at command : %s", at_cmd);
+
+ return __atmodem_send_call_request(co, cb, cb_data, at_cmd, "atmodem_call_hold");
+}
+
+/*
+ * Operation - call active.
+ *
+ * Request -
+ * 1. AT-Command: AT+CHLD=[<n>]
+ * Where
+ * <n>
+ * 2 - place all active calls (if exist) on hold and accepts the other call (held or waiting/incoming).
+ * If only one call exists which is active, place it on hold and if only held call exists
+ * make it active call
+ * Response -
+ * Success:
+ * OK
+ * Failure:
+ * +CME ERROR: <error>
+ */
+static TelReturn atmodem_call_active(CoreObject *co, TcoreObjectResponseCallback cb,
+ void *cb_data)
+{
+ gchar *at_cmd;
+ dbg("Entry");
+
+ at_cmd = g_strdup_printf("%s", "AT+CHLD=2");
+ dbg("at command : %s", at_cmd);
+
+ return __atmodem_send_call_request(co, cb, cb_data, at_cmd, "atmodem_call_active");
+}
+
+/*
+ * Operation - call swap.
+ *
+ * Request -
+ * 1. AT-Command: AT+CHLD=[<n>]
+ * Where
+ * <n>
+ * 2 - place all active calls (if exist) on hold and accepts the other call (held or waiting/incoming).
+ * If only one call exists which is active, place it on hold and if only held call exists
+ * make it active call
+ * Response -
+ * Success:
+ * OK
+ * Failure:
+ * +CME ERROR: <error>
+ */
+static TelReturn atmodem_call_swap(CoreObject *co, TcoreObjectResponseCallback cb,
+ void *cb_data)
+{
+ gchar *at_cmd;
+ dbg("Entry");
+
+ at_cmd = g_strdup_printf("%s", "AT+CHLD=2");
+ dbg("at command : %s", at_cmd);
+
+ return __atmodem_send_call_request(co, cb, cb_data, at_cmd, "atmodem_call_swap");
+}
+
+/*
+ * Operation - call join.
+ *
+ * Request -
+ * 1. AT-Command: AT+CHLD=[<n>]
+ * Where
+ * <n>
+ * 3 - adds a held call to the conversation
+ * Response -
+ * Success:
+ * OK
+ * Failure:
+ * +CME ERROR: <error>
+ */
+static TelReturn atmodem_call_join(CoreObject *co, TcoreObjectResponseCallback cb,
+ void *cb_data)
+{
+ gchar *at_cmd;
+ dbg("Entry");
+
+ at_cmd = g_strdup_printf("%s", "AT+CHLD=3");
+ dbg("at command : %s", at_cmd);
+
+ return __atmodem_send_call_request(co, cb, cb_data, at_cmd, "atmodem_call_join");
+}
+
+/*
+ * Operation - call split.
+ *
+ * Request -
+ * 1. AT-Command: AT+CHLD=[<n>]
+ * Where
+ * <n>
+ * 2x - place all active calls on hold except call x with which communication is supported
+ * Response -
+ * Success:
+ * OK
+ * Failure:
+ * +CME ERROR: <error>
+ */
+static TelReturn atmodem_call_split(CoreObject *co, guint call_id,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ gchar *at_cmd;
+ dbg("Entry");
+
+ at_cmd = g_strdup_printf("%s%d", "AT+CHLD=2", call_id);
+ dbg("at command : %s", at_cmd);
+
+ return __atmodem_send_call_request(co, cb, cb_data, at_cmd, "atmodem_call_split");
+}
+
+/*
+ * Operation - call transfer.
+ *
+ * Request -
+ * 1. AT-Command: AT+CHLD=[<n>]
+ * Where
+ * <n>
+ * 4 connects the two calls and disconnects the subscriber from both calls (Explicit Call Transfer)
+ * Response -
+ * Success:
+ * OK
+ * Failure:
+ * +CME ERROR: <error>
+ */
+static TelReturn atmodem_call_transfer(CoreObject *co, TcoreObjectResponseCallback cb,
+ void *cb_data)
+{
+ gchar *at_cmd;
+ dbg("Entry");
+
+ at_cmd = g_strdup_printf("%s", "AT+CHLD=4");
+ dbg("at command : %s", at_cmd);
+
+ return __atmodem_send_call_request(co, cb, cb_data, at_cmd, "atmodem_call_transfer");
+}
+
+/*
+ * Operation - call transfer.
+ *
+ * Request -
+ * 1. AT-Command: AT+CTFR= <number>[,<type>]
+ * Where
+ * number>
+ * string type phone number
+ * <type>
+ * type of address octet in integer format. It is optional parameter.
+ *
+ * Response -
+ * Success:
+ * OK
+ * Failure:
+ * +CME ERROR: <error>
+ */
+static TelReturn atmodem_call_deflect(CoreObject *co, const gchar *deflect_to,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ gchar *at_cmd;
+ dbg("Entry");
+
+ at_cmd = g_strdup_printf("AT+CTFR=%s", deflect_to);
+ dbg("at command : %s", at_cmd);
+
+ return __atmodem_send_call_request(co, cb, cb_data, at_cmd, "atmodem_call_deflect");
+}
+
+/* Call Operations */
+static TcoreCallOps atmodem_call_ops = {
+ .dial = atmodem_call_dial,
+ .answer = atmodem_call_answer,
+ .end = atmodem_call_end,
+ .send_dtmf = NULL,
+ .hold = atmodem_call_hold,
+ .active = atmodem_call_active,
+ .swap = atmodem_call_swap,
+ .join = atmodem_call_join,
+ .split = atmodem_call_split,
+ .transfer = atmodem_call_transfer,
+ .deflect = atmodem_call_deflect,
+ .set_active_line = NULL,
+ .get_active_line = NULL,
+ .set_volume_info = NULL,
+ .get_volume_info = NULL,
+ .set_sound_path = NULL,
+ .set_mute = NULL,
+ .get_mute_status = NULL,
+ .set_sound_recording = NULL,
+ .set_sound_equalization = NULL,
+};
+
+gboolean atmodem_call_init(TcorePlugin *p, CoreObject *co)
+{
+ dbg("Entry");
+
+ /* Set operations */
+ tcore_call_set_ops(co, &atmodem_call_ops);
+
+ /* Add Callbacks */
+ tcore_object_add_callback(co,
+ "%SCLCC:",
+ on_notification_atmodem_call_status, NULL);
+ tcore_object_add_callback(co,
+ "+CSSU:",
+ on_notification_atmodem_call_ss_cssu_info, NULL);
+
+ return TRUE;
+}
+
+void atmodem_call_exit(TcorePlugin *p, CoreObject *co)
+{
+ dbg("Exit");
+}
--- /dev/null
+/*
+ * tel-plugin-atmodem
+ *
+ * Copyright (c) 2013 Samsung Electronics Co. Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <glib.h>
+
+#include <log.h>
+#include <tcore.h>
+
+#include "atmodem_common.h"
+
+void on_send_atmodem_request(TcorePending *p,
+ TelReturn send_status, void *user_data)
+{
+ dbg("Send - [%s]",
+ (send_status == TEL_RETURN_SUCCESS ? "OK" : "NOK"));
+}
+
+AtmodemRespCbData *atmodem_create_resp_cb_data(TcoreObjectResponseCallback cb,
+ void *cb_data, void *data, guint data_len)
+{
+ AtmodemRespCbData *resp_cb_data;
+
+ resp_cb_data = tcore_malloc0(sizeof(AtmodemRespCbData) + data_len);
+ resp_cb_data->cb = cb;
+ resp_cb_data->cb_data = cb_data;
+ if ((data != NULL) && (data_len > 0))
+ memcpy(resp_cb_data->data, data, data_len);
+
+ return resp_cb_data;
+}
+
+void atmodem_destroy_resp_cb_data(AtmodemRespCbData *resp_cb_data)
+{
+ if (resp_cb_data)
+ tcore_free(resp_cb_data);
+}
--- /dev/null
+/*
+ * tel-plugin-atmodem
+ *
+ * Copyright (c) 2013 Samsung Electronics Co. Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <glib.h>
+
+#include <tcore.h>
+#include <server.h>
+#include <plugin.h>
+#include <core_object.h>
+#include <hal.h>
+#include <queue.h>
+#include <storage.h>
+#include <at.h>
+
+#include <co_modem.h>
+
+#include "atmodem_modem.h"
+#include "atmodem_common.h"
+
+typedef enum {
+ ATMODEM_CP_STATE_OFFLINE,
+ ATMODEM_CP_STATE_CRASH_RESET,
+ ATMODEM_CP_STATE_CRASH_EXIT,
+ ATMODEM_CP_STATE_BOOTING,
+ ATMODEM_CP_STATE_ONLINE,
+ ATMODEM_CP_STATE_NV_REBUILDING,
+ ATMODEM_CP_STATE_LOADER_DONE,
+} AtmodemCpState;
+
+/* Notifications */
+#if 0 /* To be supported later */
+static gboolean on_event_atmodem_cp_power(CoreObject *co, const void *event_info, void *user_data)
+{
+ GSList *lines = (GSList *)event_info;
+ const gchar *line;
+
+ dbg("Modem Power notification - SIM status: [\%SCSIM]");
+
+ if (g_slist_length(lines) != 1) {
+ err("\%SCSIM unsolicited message expected to be "
+ "Single line but received multiple lines");
+ return TRUE;
+ }
+
+ line = (const gchar *)lines->data;
+ if (line != NULL) {
+ GSList *tokens;
+ AtmodemCpState cp_state;
+ TelModemPowerStatus power_status;
+
+ tokens = tcore_at_tok_new(line);
+
+ /* <CP state> */
+ cp_state = atoi(g_slist_nth_data(tokens, 0));
+ dbg("CP state: [0x%x]", cp_state);
+ switch (cp_state) {
+ case ATMODEM_CP_STATE_OFFLINE:
+ power_status = TEL_MODEM_POWER_OFF;
+ break;
+
+ case ATMODEM_CP_STATE_CRASH_RESET:
+ power_status = TEL_MODEM_POWER_ERROR;
+ break;
+
+ default:
+ dbg("Unhandled State : [0x%x]", cp_state);
+ goto out;
+ }
+
+ /* Set Power */
+ tcore_modem_set_powered(co, FALSE);
+
+ /* Send notification */
+ tcore_object_send_notification(co,
+ TCORE_NOTIFICATION_MODEM_POWER,
+ sizeof(TelModemPowerStatus), &power_status);
+
+out:
+ tcore_at_tok_free(tokens);
+ }
+
+ return TRUE;
+}
+#endif /* To be supported later */
+
+static gboolean on_event_atmodem_phone_state(CoreObject *co, const void *event_info, void *user_data)
+{
+ GSList *lines = (GSList *)event_info;
+ const gchar *line;
+
+ dbg("Modem Power notification - SIM status: [\%SCFUN]");
+
+ if (g_slist_length(lines) != 1) {
+ err("\%SCFUN unsolicited message expected to be "
+ "Single line but received multiple lines");
+ return TRUE;
+ }
+
+ line = (const gchar *)lines->data;
+ if (line != NULL) {
+ GSList *tokens;
+ guint state;
+
+ tokens = tcore_at_tok_new(line);
+
+ /* <CP state> */
+ state = atoi(g_slist_nth_data(tokens, 0));
+ dbg("Flight mdoe State: [%s]", (state ? "OFF" : "ON"));
+
+ /* Set Flight mode */
+ tcore_modem_set_flight_mode_state(co, !state);
+
+ tcore_at_tok_free(tokens);
+
+ /*
+ * TODO:
+ * Handle Notification as response to Request
+ */
+ }
+
+ return TRUE;
+}
+
+/* System function responses */
+static void on_response_modem_set_flight_mode_internal(TcorePlugin *plugin,
+ gint result, const void *response, void *user_data)
+{
+ CoreObject *co;
+ gboolean flight_mode;
+ dbg("Enter");
+
+ co = tcore_plugin_ref_core_object(plugin, CORE_OBJECT_TYPE_MODEM);
+ tcore_check_return_assert(co != NULL);
+
+ tcore_check_return(result == TEL_MODEM_RESULT_SUCCESS);
+
+ /* Get Flight mode state */
+ (void)tcore_modem_get_flight_mode_state(co, &flight_mode);
+
+ dbg("Setting Modem Fiight mode (internal) - [%s] - [SUCCESS]",
+ (flight_mode ? "ON": "OFF"));
+
+ /*
+ * Send notification
+ *
+ * This is an internal request to set Flight mode, which is sent during
+ * boot-up based on AP-side configuration (VCONF).
+ *
+ * Need to notify TAPI through Notiifcation -
+ * TCORE_NOTIFICATION_MODEM_FLIGHT_MODE
+ */
+ (void)tcore_object_send_notification(co,
+ TCORE_NOTIFICATION_MODEM_FLIGHT_MODE,
+ sizeof(gboolean), &flight_mode);
+}
+
+/* System functions */
+gboolean atmodem_modem_power_on_modem(TcorePlugin *plugin)
+{
+ CoreObject *co;
+ TcoreStorage *strg;
+ gboolean flight_mode;
+ TelModemPowerStatus power_status;
+
+ co = tcore_plugin_ref_core_object(plugin, CORE_OBJECT_TYPE_MODEM);
+ tcore_check_return_value_assert(co != NULL, FALSE);
+
+ /* Set Modem Power State to 'ON' */
+ tcore_modem_set_powered(co, TRUE);
+
+ /*
+ * Set Flight mode (as per AP settings -VCONF)
+ */
+ /* Get Flight mode from VCONFKEY */
+ strg = tcore_server_find_storage(tcore_plugin_ref_server(plugin), "vconf");
+ tcore_check_return_value_assert(strg != NULL, FALSE);
+
+ flight_mode = tcore_storage_get_bool(strg, STORAGE_KEY_FLIGHT_MODE);
+
+ /*
+ * Set Flight mode request is dispatched to Core Object (Modem)
+ * to ensure that 'Request Hooks' get executed.
+ */
+ (void)tcore_object_dispatch_request(co, TRUE,
+ TCORE_COMMAND_MODEM_SET_FLIGHTMODE,
+ &flight_mode, sizeof(gboolean),
+ on_response_modem_set_flight_mode_internal, NULL);
+
+ /*
+ * Send notification
+ *
+ * Need to notify Modem is Powered UP through Notiifcation -
+ * TCORE_NOTIFICATION_MODEM_POWER
+ */
+ power_status = TEL_MODEM_POWER_ON;
+ (void)tcore_object_send_notification(co,
+ TCORE_NOTIFICATION_MODEM_POWER,
+ sizeof(TelModemPowerStatus), &power_status);
+ dbg("Modem Powered ON");
+
+ return FALSE;
+}
+
+/* Modem Responses */
+static void on_response_atmodem_modem_set_flight_mode(TcorePending *p,
+ guint data_len, const void *data, void *user_data)
+{
+ const TcoreAtResponse *at_resp = data;
+ CoreObject *co = tcore_pending_ref_core_object(p);
+ AtmodemRespCbData *resp_cb_data = user_data;
+ gboolean *enable;
+
+ TelModemResult result = TEL_MODEM_RESULT_FAILURE;
+ dbg("Enter");
+
+ tcore_check_return_assert(co != NULL);
+ tcore_check_return_assert(resp_cb_data != NULL);
+
+ if (at_resp && at_resp->success)
+ result = TEL_MODEM_RESULT_SUCCESS;
+
+ enable = (gboolean *)ATMODEM_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
+
+ dbg("Setting Modem Flight mode - [%s] - [%s]",
+ (*enable ? "ON": "OFF"),
+ (result == TEL_MODEM_RESULT_SUCCESS ? "SUCCESS" : "FAIL"));
+
+ /* Update Core Object */
+ (void)tcore_modem_set_flight_mode_state(co, *enable);
+
+ /* Invoke callback */
+ if (resp_cb_data->cb)
+ resp_cb_data->cb(co, (gint)result, NULL, resp_cb_data->cb_data);
+
+ /* Free callback data */
+ atmodem_destroy_resp_cb_data(resp_cb_data);
+
+ /*
+ * In case Flight mode is set to OFF, we need to trigger
+ * Network Registration.
+ *
+ * This is taken care by Network module which hooks on
+ * Set Flight mode Request of Modem module.
+ */
+}
+
+static void on_response_atmodem_modem_get_version(TcorePending *p,
+ guint data_len, const void *data, void *user_data)
+{
+ const TcoreAtResponse *at_resp = data;
+ CoreObject *co = tcore_pending_ref_core_object(p);
+ AtmodemRespCbData *resp_cb_data = user_data;
+ TelModemVersion version = {{0}, {0}, {0}, {0}};
+
+ TelModemResult result = TEL_MODEM_RESULT_FAILURE;
+ dbg("Enter");
+
+ tcore_check_return_assert(co != NULL);
+ tcore_check_return_assert(resp_cb_data != NULL);
+
+ if (at_resp) {
+ if (at_resp->lines) {
+ const gchar *line;
+ GSList *tokens = NULL;
+
+ line = (const gchar *)at_resp->lines->data;
+ tokens = tcore_at_tok_new(line);
+ if (g_slist_length(tokens) > 0) {
+ if (at_resp->success) {
+ gchar *sw_ver = NULL, *hw_ver = NULL;
+ gchar *calib_date = NULL, *p_code = NULL;
+
+ sw_ver = g_slist_nth_data(tokens, 0);
+ hw_ver = g_slist_nth_data(tokens, 1);
+ calib_date = g_slist_nth_data(tokens, 2);
+ p_code = g_slist_nth_data(tokens, 3);
+
+ g_strlcpy(version.software_version,
+ sw_ver,
+ TEL_MODEM_VERSION_LENGTH_MAX + 1);
+ g_strlcpy(version.hardware_version,
+ hw_ver,
+ TEL_MODEM_VERSION_LENGTH_MAX + 1);
+ g_strlcpy(version.calibration_date,
+ calib_date,
+ TEL_MODEM_VERSION_LENGTH_MAX + 1);
+ g_strlcpy(version.product_code,
+ p_code,
+ TEL_MODEM_VERSION_LENGTH_MAX + 1);
+
+ dbg("Version - Software: [%s] Hardware: [%s] "
+ "Calibration date: [%s] Product "
+ "Code: [%s]", sw_ver, hw_ver,
+ calib_date, p_code);
+
+ result = TEL_MODEM_RESULT_SUCCESS;
+ } else {
+ err("RESPONSE - [NOK]");
+ err("[%s]", g_slist_nth_data(tokens, 0));
+ }
+ } else {
+ err("Invalid response message");
+ result = TEL_MODEM_RESULT_UNKNOWN_FAILURE;
+ }
+ tcore_at_tok_free(tokens);
+ }
+ }
+
+ /* Invoke callback */
+ if (resp_cb_data->cb)
+ resp_cb_data->cb(co, (gint)result, &version, resp_cb_data->cb_data);
+
+ /* Free callback data */
+ atmodem_destroy_resp_cb_data(resp_cb_data);
+}
+
+static void on_response_atmodem_modem_get_imei(TcorePending *p,
+ guint data_len, const void *data, void *user_data)
+{
+ const TcoreAtResponse *at_resp = data;
+ CoreObject *co = tcore_pending_ref_core_object(p);
+ AtmodemRespCbData *resp_cb_data = user_data;
+ gchar imei[TEL_MODEM_IMEI_LENGTH_MAX +1] = {0};
+
+ TelModemResult result = TEL_MODEM_RESULT_FAILURE;
+ dbg("Enter");
+
+ tcore_check_return_assert(co != NULL);
+ tcore_check_return_assert(resp_cb_data != NULL);
+
+ if (at_resp) {
+ if (at_resp->lines) {
+ const gchar *line;
+ GSList *tokens = NULL;
+
+ line = (const gchar *)at_resp->lines->data;
+ tokens = tcore_at_tok_new(line);
+ if (g_slist_length(tokens) == 1) {
+ if (at_resp->success) {
+ dbg("RESPONSE - [OK]");
+ g_strlcpy(imei,
+ (const gchar *)g_slist_nth_data(tokens, 0),
+ TEL_MODEM_IMEI_LENGTH_MAX+1);
+ dbg("IMEI: [%s]", imei);
+
+ result = TEL_MODEM_RESULT_SUCCESS;
+ } else {
+ err("RESPONSE - [NOK]");
+ err("[%s]", g_slist_nth_data(tokens, 0));
+ }
+ } else {
+ err("Invalid response message");
+ result = TEL_MODEM_RESULT_UNKNOWN_FAILURE;
+ }
+ tcore_at_tok_free(tokens);
+ }
+ }
+
+ /* Invoke callback */
+ if (resp_cb_data->cb)
+ resp_cb_data->cb(co, (gint)result, imei, resp_cb_data->cb_data);
+
+ /* Free callback data */
+ atmodem_destroy_resp_cb_data(resp_cb_data);
+}
+
+/* Modem Operations */
+/*
+ * Operation - set_flight_mode
+ *
+ * Request -
+ * AT-Command: AT+CFUN=<fun>
+ * where,
+ * <fun>
+ * 0 ENABLE Flight Mode
+ * 1 DISABLE Flight Mode
+ * Response -
+ * Success: (No Result)
+ * OK
+ * Failure:
+ * +CME ERROR: <error>
+ */
+static TelReturn atmodem_modem_set_flight_mode(CoreObject *co, gboolean enable,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ gchar *at_cmd;
+ guint power_mode;
+
+ AtmodemRespCbData *resp_cb_data;
+ TelReturn ret;
+
+ if (enable) {
+ dbg("Flight mode - [ON]");
+ power_mode = 0;
+ } else {
+ dbg("Flight mode - [OFF]");
+ power_mode = 1;
+ }
+
+ /* AT-Command */
+ at_cmd = g_strdup_printf("AT+CFUN=%d", power_mode);
+
+ /* Response callback data */
+ resp_cb_data = atmodem_create_resp_cb_data(cb, cb_data,
+ &enable, sizeof(gboolean));
+
+ /* Send Request to modem */
+ ret = tcore_at_prepare_and_send_request(co,
+ at_cmd, NULL,
+ TCORE_AT_COMMAND_TYPE_NO_RESULT,
+ TCORE_PENDING_PRIORITY_DEFAULT,
+ NULL,
+ on_response_atmodem_modem_set_flight_mode, resp_cb_data,
+ on_send_atmodem_request, NULL,
+ 0, NULL, NULL);
+ ATMODEM_CHECK_REQUEST_RET(ret, resp_cb_data, "Set Flight mode");
+
+ /* Free resources */
+ g_free(at_cmd);
+
+ return ret;
+}
+
+/*
+ * Operation - get_flight_mode
+ *
+ * Request -
+ * AT-Command: None
+ * Fetch information from Core Object
+ *
+ * Response - flight_mode (gboolean)
+ */
+static TelReturn atmodem_modem_get_flight_mode(CoreObject *co,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ gboolean flight_mode;
+
+ /* Fetch Flight mode from Core Object */
+ (void)tcore_modem_get_flight_mode_state(co, &flight_mode);
+ dbg("Modem Flight mode - [%s]", (flight_mode ? "ON": "OFF"));
+
+ /* Invoke response callback */
+ if (cb)
+ cb(co, (gint)TEL_MODEM_RESULT_SUCCESS, &flight_mode, cb_data);
+
+ return TEL_RETURN_SUCCESS;
+}
+
+/*
+ * Operation - get_version
+ *
+ * Request -
+ * AT-Command: AT+CGMR
+ *
+ * Response - version (TelModemVersion)
+ * Success: (Single line) -
+ * <sw_ver>, <hw_ver>, <calib_date>, <p_code>
+ * OK
+ * Note:
+ * Success Response is different from standard 3GPP AT-Command (+CGMR)
+ * Failure:
+ * +CME ERROR: <error>
+ */
+static TelReturn atmodem_modem_get_version(CoreObject *co,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ AtmodemRespCbData *resp_cb_data;
+ TelReturn ret;
+
+ /* Response callback data */
+ resp_cb_data = atmodem_create_resp_cb_data(cb, cb_data,
+ NULL, 0);
+
+ /* Send Request to modem */
+ ret = tcore_at_prepare_and_send_request(co,
+ "AT+CGMR", NULL,
+ TCORE_AT_COMMAND_TYPE_SINGLELINE,
+ TCORE_PENDING_PRIORITY_DEFAULT,
+ NULL,
+ on_response_atmodem_modem_get_version, resp_cb_data,
+ on_send_atmodem_request, NULL,
+ 0, NULL, NULL);
+ ATMODEM_CHECK_REQUEST_RET(ret, resp_cb_data, "Get Version");
+
+ return ret;
+}
+
+/*
+ * Operation - get_imei
+ *
+ * Request -
+ * AT-Command: AT+CGSN
+ *
+ * Response - imei (gchar array of length 20+'\0' bytes)
+ * Success: (Single line)
+ * <IMEI>
+ * OK
+ * Failure:
+ * +CME ERROR: <error>
+ */
+static TelReturn atmodem_modem_get_imei(CoreObject *co,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ AtmodemRespCbData *resp_cb_data;
+ TelReturn ret;
+
+ /* Response callback data */
+ resp_cb_data = atmodem_create_resp_cb_data(cb, cb_data,
+ NULL, 0);
+
+ /* Send Request to modem */
+ ret = tcore_at_prepare_and_send_request(co,
+ "AT+CGSN", NULL,
+ TCORE_AT_COMMAND_TYPE_NUMERIC,
+ TCORE_PENDING_PRIORITY_DEFAULT,
+ NULL,
+ on_response_atmodem_modem_get_imei, resp_cb_data,
+ on_send_atmodem_request, NULL,
+ 0, NULL, NULL);
+ ATMODEM_CHECK_REQUEST_RET(ret, resp_cb_data, "Get IMEI");
+
+ return ret;
+}
+
+/* Modem Operations */
+static TcoreModemOps atmodem_modem_ops = {
+ .set_power_status = NULL,
+ .set_flight_mode = atmodem_modem_set_flight_mode,
+ .get_flight_mode = atmodem_modem_get_flight_mode,
+ .get_version = atmodem_modem_get_version,
+ .get_imei = atmodem_modem_get_imei
+};
+
+gboolean atmodem_modem_init(TcorePlugin *p, CoreObject *co)
+{
+ dbg("Enter");
+
+ /* Set operations */
+ tcore_modem_set_ops(co, &atmodem_modem_ops);
+
+ /* Add Callbacks */
+#if 0 /* To be supported later */
+ tcore_object_add_callback(co, "\%SCSIM:",
+ on_event_atmodem_cp_power, NULL);
+#endif /* To be supported later */
+ tcore_object_add_callback(co, "\%SCFUN:",
+ on_event_atmodem_phone_state, NULL);
+
+ dbg("Exit");
+ return TRUE;
+}
+
+void atmodem_modem_exit(TcorePlugin *p, CoreObject *co)
+{
+ dbg("Exit");
+}
--- /dev/null
+/*
+ * tel-plugin-atmodem
+ *
+ * Copyright (c) 2013 Samsung Electronics Co. Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <glib.h>
+
+#include <tcore.h>
+#include <server.h>
+#include <plugin.h>
+#include <core_object.h>
+#include <hal.h>
+#include <queue.h>
+#include <storage.h>
+#include <at.h>
+
+#include <co_network.h>
+
+#include "atmodem_network.h"
+#include "atmodem_common.h"
+
+#define ATMODEM_NETWORK_BASE_16 16
+
+typedef enum {
+ ATMDOEM_NETWORK_ACT_GSM, /* GSM */
+ ATMDOEM_NETWORK_ACT_GSM_COMPACT, /* GSM Compact */
+ ATMDOEM_NETWORK_ACT_UTRAN, /* UTRAN */
+ ATMDOEM_NETWORK_ACT_GSM_EGPRS, /* GSM w/EGPRS */
+ ATMDOEM_NETWORK_ACT_UTRAN_HSDPA, /* UTRAN w/HSDPA */
+ ATMDOEM_NETWORK_ACT_UTRAN_HSUPA, /* UTRAN w/HSUPA */
+ ATMDOEM_NETWORK_ACT_UTRAN_HSDPA_HSUPA, /* UTRAN w/HSDPA and HSUPA */
+ ATMDOEM_NETWORK_ACT_E_UTRAN, /* E-UTRAN */
+} AtmodemNetworkAct;
+
+static TelNetworkAct __atmodem_network_map_act(AtmodemNetworkAct act)
+{
+ /*
+ * <ACT>
+ * 0 GSM
+ * 1 GSM Compact
+ * 2 UTRAN
+ * 3 GSM w/EGPRS
+ * 4 UTRAN w/HSDPA
+ * 5 UTRAN w/HSUPA
+ * 6 UTRAN w/HSDPA and HSUPA - HSPA
+ */
+ switch (act) {
+ case ATMDOEM_NETWORK_ACT_GSM:
+ case ATMDOEM_NETWORK_ACT_GSM_COMPACT:
+ return TEL_NETWORK_ACT_GSM;
+
+ case ATMDOEM_NETWORK_ACT_UTRAN:
+ return TEL_NETWORK_ACT_UMTS;
+
+ case ATMDOEM_NETWORK_ACT_GSM_EGPRS:
+ return TEL_NETWORK_ACT_EGPRS;
+
+ case ATMDOEM_NETWORK_ACT_UTRAN_HSDPA:
+ return TEL_NETWORK_ACT_HSDPA;
+
+ case ATMDOEM_NETWORK_ACT_UTRAN_HSUPA:
+ return TEL_NETWORK_ACT_HSUPA;
+
+ case ATMDOEM_NETWORK_ACT_UTRAN_HSDPA_HSUPA:
+ return TEL_NETWORK_ACT_HSPA;
+
+ default:
+ return TEL_NETWORK_ACT_UNKNOWN;
+ }
+}
+
+static TelNetworkRegStatus __atmodem_network_map_stat(guint stat)
+{
+ /*
+ * <stat>
+ * 0 Not registered, ME is not currently searching a
+ * new operator to register to
+ * 1 Registered, home network
+ * 2 Not registered, but ME is currently searching a
+ * new operator to register
+ * 3 Registration denied
+ * 4 Unknown
+ * 5 Registered, in roaming
+ */
+ switch (stat) {
+ case 0:
+ return TEL_NETWORK_REG_STATUS_UNREGISTERED;
+
+ case 1:
+ return TEL_NETWORK_REG_STATUS_REGISTERED;
+
+ case 2:
+ return TEL_NETWORK_REG_STATUS_SEARCHING;
+
+ case 3:
+ return TEL_NETWORK_REG_STATUS_DENIED;
+
+ case 4:
+ return TEL_NETWORK_REG_STATUS_UNKNOWN;
+
+ case 5:
+ return TEL_NETWORK_REG_STATUS_ROAMING;
+
+ default:
+ return TEL_NETWORK_REG_STATUS_UNKNOWN;
+ }
+}
+
+static void __on_response_atmodem_network_registration(TcorePending *p,
+ guint data_len, const void *data, void *user_data)
+{
+ const TcoreAtResponse *at_resp = data;
+ dbg("Entry");
+
+ if (at_resp && at_resp->success) {
+ dbg("Network Registration - [OK]");
+ } else {
+ err("Network Registration - [NOK]");
+ }
+}
+
+static void __atmodem_network_register_to_network(CoreObject *co)
+{
+ TelReturn ret;
+
+ /* Send Request to modem */
+ ret = tcore_at_prepare_and_send_request(co,
+ "AT+COPS=0", NULL,
+ TCORE_AT_COMMAND_TYPE_NO_RESULT,
+ TCORE_PENDING_PRIORITY_DEFAULT,
+ NULL,
+ __on_response_atmodem_network_registration, NULL,
+ on_send_atmodem_request, NULL,
+ 0, NULL, NULL);
+ dbg("Sending Network Registration request: [%s]",
+ (ret == TEL_RETURN_SUCCESS ? "SUCCESS" : "FAIL"));
+}
+
+static void __on_response_atmodem_network_fetch_nw_name_internal(CoreObject *co,
+ gint result, const void *response, void *user_data)
+{
+ TelNetworkIdentityInfo *identity = (TelNetworkIdentityInfo *)response;
+
+ /* Send notification if result is SUCCESS */
+ if (result == TEL_NETWORK_RESULT_SUCCESS)
+ tcore_plugin_send_notification(tcore_object_ref_plugin(co),
+ TCORE_NOTIFICATION_NETWORK_IDENTITY,
+ sizeof(TelNetworkIdentityInfo), &identity);
+}
+
+static TcoreHookReturn __on_response_atmodem_hook_set_flight_mode(CoreObject *co,
+ gint result, TcoreCommand command, const void *response, const void *user_data)
+{
+
+ tcore_check_return_value(result == TEL_MODEM_RESULT_SUCCESS,
+ TCORE_HOOK_RETURN_CONTINUE);
+
+ dbg("Flight mode 'disabled', register to Network");
+
+ /*
+ * TODO - Check for selection_mode
+ * Need to check if it is Manual or Automatic and based on
+ * that need to initiate Network Registratin accordingly.
+ */
+ __atmodem_network_register_to_network(co);
+
+ return TCORE_HOOK_RETURN_CONTINUE;
+}
+
+static void __on_response_atmodem_network_fetch_nw_name(TcorePending *p,
+ guint data_len, const void *data, void *user_data)
+{
+ const TcoreAtResponse *at_resp = data;
+ CoreObject *co = tcore_pending_ref_core_object(p);
+ AtmodemRespCbData *resp_cb_data = user_data;
+ TelNetworkIdentityInfo identity = {0, };
+
+ TelNetworkResult result = TEL_NETWORK_RESULT_FAILURE;
+
+ dbg("Enter");
+
+ tcore_check_return_assert(co != NULL);
+ tcore_check_return_assert(resp_cb_data != NULL);
+
+ if (at_resp && at_resp->success) {
+ if (at_resp->lines) {
+ const gchar *line;
+ GSList *tokens = NULL;
+ gchar *token_str;
+ guint i, nol;
+
+ /* Validate that only 3 lines of response is received */
+ nol = g_slist_length(at_resp->lines);
+ if (nol > 3) {
+ err("Invalid response message");
+ return;
+ }
+
+ /* Process the Multi-line response */
+ for (i = 0; i < nol; i++) {
+ line = g_slist_nth_data(at_resp->lines, i);
+
+ /*
+ * Tokenize
+ *
+ * +COPS: <mode>[,<format>,<oper>[,< AcT>]]
+ */
+ tokens = tcore_at_tok_new(line);
+
+ if ((token_str = tcore_at_tok_nth(tokens, 0))) {
+ guint mode = atoi(token_str);
+ dbg("<mode> : [%d]", mode);
+ }
+
+ if ((token_str = tcore_at_tok_nth(tokens, 0))) {
+ guint format = atoi(token_str);
+ dbg("<format> : [%d]", format);
+
+ switch (format) {
+ case 0: /* Long Network Name */
+ if ((token_str = tcore_at_tok_nth(tokens, 1))) {
+ if (strlen(token_str) > 0) {
+ identity.long_name = tcore_at_tok_extract((const char *)token_str);
+
+ /* Update Long name */
+ tcore_network_set_long_name(co, identity.long_name);
+ }
+ }
+ break;
+
+ case 1: /* Short Network Name */
+ if ((token_str = tcore_at_tok_nth(tokens, 1))) {
+ if (strlen(token_str) > 0) {
+ identity.short_name = tcore_at_tok_extract((const char *)token_str);
+
+ /* Update Short name */
+ tcore_network_set_short_name(co, identity.short_name);
+ }
+ }
+ break;
+
+ case 2: /* PLMN (mcc, mnc) */
+ if ((token_str = tcore_at_tok_nth(tokens, 1))) {
+ if (strlen(token_str) > 0) {
+ identity.plmn = tcore_at_tok_extract((const char *)token_str);
+
+ /* Update PLMN */
+ tcore_network_set_plmn( co, identity.plmn);
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ /* Free resource */
+ tcore_at_tok_free(tokens);
+ }
+
+ /* Send Notification - Network identity */
+ dbg("Network name - Long name: [%s] Short name: [%s] "
+ "PLMN: [%s]", identity.long_name,
+ identity.short_name, identity.plmn);
+
+ result = TEL_NETWORK_RESULT_SUCCESS;
+ }
+ }
+
+ /* Invoke callback */
+ if (resp_cb_data->cb)
+ resp_cb_data->cb(co, (gint)result, &identity, resp_cb_data->cb_data);
+
+ /* Free resource */
+ tcore_free(identity.long_name);
+ tcore_free(identity.short_name);
+ tcore_free(identity.plmn);
+
+ /* Free callback data */
+ atmodem_destroy_resp_cb_data(resp_cb_data);
+}
+
+/*
+ * Operation - fetch_nw_name
+ *
+ * Request -
+ * AT-Command: AT+COPS=[<mode>[,<format>[,<oper>[,< AcT>]]]]
+ *
+ * <mode> may be
+ * 1 Manual. Other parameters like format and operator need to be passed
+ * 2 Deregister from network
+ * 3 It sets <format> value. In this case <format> becomes a mandatory input
+ * 4 Manual / Automatic. In this case if manual selection fails then automatic mode
+ * is entered
+ *
+ * <format> may be
+ * 0 format presentations are set to long alphanumeric. If Network name not
+ * available it displays combination of Mcc and MNC in string format.
+ * 1 format presentation is set to short alphanumeric.
+ * 2 format presentations set to numeric.
+ *
+ * <oper> may be
+ * string type given in format <format>
+ *
+ * Response - Network name
+ * Success: (Multiple Single line)
+ * +COPS: <mode>[,<format>,<oper>[,< AcT>]]
+ * OK
+ * Failure:
+ * +CME ERROR: <error>
+ */
+static TelReturn __atmodem_network_fetch_nw_name(CoreObject *co,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ AtmodemRespCbData *resp_cb_data = NULL;
+ TelReturn ret;
+
+ /* Response callback data */
+ resp_cb_data = atmodem_create_resp_cb_data(cb, cb_data, NULL, 0);
+
+ /* Send Request to modem */
+ ret = tcore_at_prepare_and_send_request(co,
+ "AT+COPS=3,0;+COPS?;+COPS=3,1;+COPS?;+COPS=3,0+COPS?;", "+COPS",
+ TCORE_AT_COMMAND_TYPE_MULTILINE,
+ TCORE_PENDING_PRIORITY_DEFAULT,
+ NULL,
+ __on_response_atmodem_network_fetch_nw_name, resp_cb_data,
+ on_send_atmodem_request, NULL,
+ 0, NULL, NULL);
+ ATMODEM_CHECK_REQUEST_RET(ret, resp_cb_data, "Fetch Network name");
+
+ return ret;
+}
+
+/* Hook functions */
+static TcoreHookReturn on_hook_atmodem_set_flight_mode(CoreObject *co,
+ TcoreCommand command, const void *request, const void *user_data,
+ TcoreObjectResponseCallback cb, const void *cb_data)
+{
+ gboolean *flight_mode = (gboolean *)request;
+
+ /*
+ * Hook Set Flight mode request.
+ *
+ * Disable Flight mode - Hook response (if success Register to Network)
+ * Enable Flight mode - return
+ */
+ if(*flight_mode != TRUE) {
+ /* Add response hook */
+ tcore_object_add_response_hook(co, command, request,
+ __on_response_atmodem_hook_set_flight_mode, NULL);
+
+ return TCORE_HOOK_RETURN_CONTINUE;
+ }
+
+ dbg("Flight mode - [Enabled]");
+ return TCORE_HOOK_RETURN_CONTINUE;
+}
+
+static TcoreHookReturn on_hook_atmodem_sim_status(TcorePlugin *plugin,
+ TcoreNotification command, guint data_len, void *data, void *user_data)
+{
+ const TelSimCardStatus *sim_status = (TelSimCardStatus *)data;
+
+ tcore_check_return_value(sim_status != NULL,
+ TCORE_HOOK_RETURN_CONTINUE);
+
+ /*
+ * Hook SIM initialization Notification
+ *
+ * SIM INIT complete - Attach to network (Register to network)
+ * SIM INIT not complete - return
+ */
+ if (*sim_status == TEL_SIM_STATUS_SIM_INIT_COMPLETED) {
+ CoreObject *co = (CoreObject *)user_data;
+ dbg("SIM Initialized!!! Attach to Network");
+
+ tcore_check_return_value_assert(co != NULL,
+ TCORE_HOOK_RETURN_CONTINUE);
+
+ /*
+ * TODO - Check for selection_mode
+ * Need to check if it is Manual or Automatic and based on
+ * that need to initiate Network Registratin accordingly.
+ */
+ __atmodem_network_register_to_network(co);
+
+ return TCORE_HOOK_RETURN_CONTINUE;
+ }
+
+ dbg("SIM not yet initialized - SIM Status: [%d]", *sim_status);
+ return TCORE_HOOK_RETURN_CONTINUE;
+}
+
+/* Notification callbacks */
+/*
+ * Notification: +CREG: <stat>[,<lac>,<ci>[,<AcT>]]
+ *
+ * Possible values of <stat> can be
+ * 0 Not registered, ME is not currently searching
+ * a new operator to register to
+ * 1 Registered, home network
+ * 2 Not registered, but ME is currently searching
+ * a new operator to register
+ * 3 Registration denied
+ * 4 Unknown
+ * 5 Registered, in roaming
+ *
+ * <lac>
+ * string type; two byte location area code in
+ * hexadecimal format (e.g. 00C3)
+ *
+ * <ci>
+ * string type; four byte cell ID in hexadecimal
+ * format (e.g. 0000A13F)
+ *
+ * <ACT>
+ * 0 GSM
+ * 2 UTRAN
+ * 3 GSM w/EGPRS
+ * 4 UTRAN w/HSDPA
+ * 5 UTRAN w/HSUPA
+ * 6 UTRAN w/HSDPA and HSUPA
+ */
+static gboolean on_notification_atmodem_cs_network_info(CoreObject *co,
+ const void *event_info, void *user_data)
+{
+ GSList *lines = NULL;
+ gchar *line = NULL;
+
+ dbg("Network notification - CS network info: [+CREG]");
+
+ lines = (GSList *)event_info;
+ if (g_slist_length(lines) != 1) {
+ err("+CREG unsolicited message expected to be Single line "
+ "but received multiple lines");
+ return TRUE;
+ }
+
+ line = (gchar *) (lines->data);
+ if (line != NULL) {
+ TelNetworkRegStatusInfo registration_status = {0, };
+ TelNetworkCellInfo cell_info = {0, };
+ GSList *tokens = NULL;
+ gchar *token_str;
+ guint stat = 0, act = 0, lac = 0, ci = 0;
+ gboolean roam_state = FALSE;
+
+ /*
+ * Tokenize
+ *
+ * +CREG: <stat>[,<lac>,<ci>[,<AcT>]]
+ */
+ tokens = tcore_at_tok_new(line);
+ if (g_slist_length(tokens) < 1) {
+ err("Invalid notification message");
+ goto out;
+ }
+
+ /* <stat> */
+ if ((token_str = g_slist_nth_data(tokens, 0)) == NULL) {
+ err("No <stat> in +CREG");
+ goto out;
+ }
+ stat = __atmodem_network_map_stat(atoi(token_str));
+ (void)tcore_network_set_cs_reg_status(co, stat);
+
+ /* <lac> */
+ if ((token_str = g_slist_nth_data(tokens, 1))) {
+ token_str = tcore_at_tok_extract((const gchar *)token_str);
+
+ lac = (guint)strtol(token_str, NULL, ATMODEM_NETWORK_BASE_16);
+
+ /* Update Location Area Code (lac) information */
+ (void)tcore_network_set_lac(co, lac);
+
+ tcore_free(token_str);
+ } else {
+ dbg("No <lac> in +CREG");
+ (void)tcore_network_get_lac(co, &lac);
+ }
+
+ /* <ci> */
+ if ((token_str = g_slist_nth_data(tokens, 2))) {
+ token_str = tcore_at_tok_extract((const gchar *)token_str);
+
+ ci = (guint)strtol(token_str, NULL, ATMODEM_NETWORK_BASE_16);
+
+ /* Update Cell ID (ci) information */
+ (void)tcore_network_set_cell_id(co, ci);
+
+ tcore_free(token_str);
+ } else {
+ dbg("No <ci> in +CREG");
+ (void)tcore_network_get_cell_id(co, &ci);
+ }
+
+ /* <AcT> */
+ if ((token_str = g_slist_nth_data(tokens, 3))) {
+ act = __atmodem_network_map_act(atoi(token_str));
+ (void)tcore_network_set_access_technology(co, act);
+ } else {
+ dbg("No <AcT> in +CREG");
+ (void)tcore_network_get_access_technology(co, &act);
+ }
+ dbg("<stat>: %d <lac>: 0x%x <ci>: 0x%x <AcT>: %d", stat, lac, ci, act);
+
+ /* Send Notification - Network (CS) Registration status */
+ registration_status.cs_status = stat;
+ registration_status.act = act;
+ (void)tcore_network_get_ps_reg_status(co, ®istration_status.ps_status);
+
+ tcore_object_send_notification(co,
+ TCORE_NOTIFICATION_NETWORK_REGISTRATION_STATUS,
+ sizeof(TelNetworkRegStatusInfo), ®istration_status);
+
+ switch (stat) {
+ case TEL_NETWORK_REG_STATUS_ROAMING:
+ roam_state = TRUE; // no break
+ case TEL_NETWORK_REG_STATUS_REGISTERED:
+ /* Fetch Network name - Internal request */
+ (void)__atmodem_network_fetch_nw_name(co,
+ __on_response_atmodem_network_fetch_nw_name_internal, NULL);
+ break;
+ default:
+ break;
+ }
+
+ /* Set Roaming state */
+ tcore_network_set_roam_state(co, roam_state);
+
+ /* Send Notification - Cell info */
+ cell_info.lac = (gint)lac;
+ cell_info.cell_id = (gint)ci;
+ (void)tcore_network_get_rac(co, &cell_info.rac);
+
+ tcore_plugin_send_notification(tcore_object_ref_plugin(co),
+ TCORE_NOTIFICATION_NETWORK_LOCATION_CELLINFO,
+ sizeof(TelNetworkCellInfo), &cell_info);
+
+out:
+ /* Free resource */
+ tcore_at_tok_free(tokens);
+ }
+
+ return TRUE;
+}
+
+/*
+ * Notification: +CGREG: <stat>[,<lac>,<ci>[,<AcT>,<rac>]]
+ *
+ * Possible values of <stat> can be
+ * 0 Not registered, ME is not currently searching a
+ * new operator to register to
+ * 1 Registered, home network
+ * 2 Not registered, but ME is currently searching a
+ * new operator to register
+ * 3 Registration denied
+ * 4 Unknown
+ * 5 Registered, in roaming
+ *
+ * <lac>
+ * string type; two byte location area code in
+ * hexadecimal format (e.g. 00C3)
+ *
+ * <ci>
+ * string type; four byte cell ID in hexadecimal
+ * format (e.g. 0000A13F)
+ *
+ * <ACT>
+ * 0 GSM
+ * 2 UTRAN
+ * 3 GSM w/EGPRS
+ * 4 UTRAN w/HSDPA
+ * 5 UTRAN w/HSUPA
+ * 6 UTRAN w/HSDPA and HSUPA
+ *
+ * <rac>:
+ * string type; one byte routing area code in hexadecimal format
+ */
+static gboolean on_notification_atmodem_ps_network_info(CoreObject *co,
+ const void *event_info, void *user_data)
+{
+ GSList *lines = NULL;
+ gchar *line = NULL;
+
+ dbg("Network notification - PS network info: [+CGREG]");
+
+ lines = (GSList *)event_info;
+ if (g_slist_length(lines) != 1) {
+ err("+CGREG unsolicited message expected to be Single line "
+ "but received multiple lines");
+ return TRUE;
+ }
+
+ line = (gchar *) (lines->data);
+ if (line != NULL) {
+ TelNetworkRegStatusInfo registration_status = {0, };
+ TelNetworkCellInfo cell_info = {0, };
+ GSList *tokens = NULL;
+ gchar *token_str;
+ guint stat = 0, act = 0, lac = 0, ci = 0, rac = 0;
+ gboolean roam_state = FALSE;
+
+ /*
+ * Tokenize
+ *
+ * +CGREG: <stat>[,<lac>,<ci>[,<AcT>,<rac>]]
+ */
+ tokens = tcore_at_tok_new(line);
+ if (g_slist_length(tokens) < 1) {
+ err("Invalid notification message");
+ goto out;
+ }
+
+ /* <stat> */
+ if ((token_str = g_slist_nth_data(tokens, 0)) == NULL) {
+ err("No <stat> in +CGREG");
+ goto out;
+ }
+ stat = __atmodem_network_map_stat(atoi(token_str));
+ (void)tcore_network_set_ps_reg_status(co, stat);
+
+ /* <lac> */
+ if ((token_str = g_slist_nth_data(tokens, 1))) {
+ token_str = tcore_at_tok_extract((const gchar *)token_str);
+
+ lac = (guint)strtol(token_str, NULL, ATMODEM_NETWORK_BASE_16);
+
+ /* Update Location Area Code (lac) information */
+ (void)tcore_network_set_lac(co, lac);
+
+ tcore_free(token_str);
+ } else {
+ dbg("No <lac> in +CGREG");
+ (void)tcore_network_get_lac(co, &lac);
+ }
+
+ /* <ci> */
+ if ((token_str = g_slist_nth_data(tokens, 2))) {
+ token_str = tcore_at_tok_extract((const gchar *)token_str);
+
+ ci = (guint)strtol(token_str, NULL, ATMODEM_NETWORK_BASE_16);
+
+ /* Update Cell ID (ci) information */
+ (void)tcore_network_set_cell_id(co, ci);
+
+ tcore_free(token_str);
+ } else {
+ dbg("No <ci> in +CGREG");
+ (void)tcore_network_get_cell_id(co, &ci);
+ }
+
+ /* <AcT> */
+ if ((token_str = g_slist_nth_data(tokens, 3))) {
+ act = __atmodem_network_map_act(atoi(token_str));
+ (void)tcore_network_set_access_technology(co, act);
+ } else {
+ dbg("No <AcT> in +CGREG");
+ (void)tcore_network_get_access_technology(co, &act);
+ }
+
+ /* <rac> */
+ if ((token_str = g_slist_nth_data(tokens, 4))) {
+ token_str = tcore_at_tok_extract((const gchar *)token_str);
+
+ rac = (guint)strtol(token_str, NULL, ATMODEM_NETWORK_BASE_16);
+
+ /* Update Routing Area Code (rac) information */
+ (void)tcore_network_set_rac(co, rac);
+
+ tcore_free(token_str);
+ } else {
+ err("No <ci> in +CGREG");
+ (void)tcore_network_get_rac(co, &rac);
+ }
+ dbg("<stat>: %d <lac>: 0x%x <ci>: 0x%x <AcT>: %d <rac>: 0x%x", stat, lac, ci, act, rac);
+
+ /* Send Notification - Network (PS) Registration status */
+ registration_status.ps_status = stat;
+ registration_status.act = act;
+ (void)tcore_network_get_cs_reg_status(co, ®istration_status.cs_status);
+
+ tcore_object_send_notification(co,
+ TCORE_NOTIFICATION_NETWORK_REGISTRATION_STATUS,
+ sizeof(TelNetworkRegStatusInfo), ®istration_status);
+
+
+ /* Set Roaming state */
+ if (registration_status.ps_status == TEL_NETWORK_REG_STATUS_ROAMING)
+ roam_state = TRUE;
+
+ tcore_network_set_roam_state(co, roam_state);
+
+ /* Send Notification - Cell info */
+ cell_info.lac = lac;
+ cell_info.cell_id = ci;
+ cell_info.rac = rac;
+ tcore_plugin_send_notification(tcore_object_ref_plugin(co),
+ TCORE_NOTIFICATION_NETWORK_LOCATION_CELLINFO,
+ sizeof(TelNetworkCellInfo), &cell_info);
+
+out:
+ /* Free resource */
+ tcore_at_tok_free(tokens);
+ }
+
+ return TRUE;
+}
+
+static gboolean on_notification_atmodem_network_rssi(CoreObject *co,
+ const void *event_info, void *user_data)
+{
+ GSList *lines;
+ const gchar *line = NULL;
+
+ dbg("Network notification - Icon (rssi) info: [+CIEV]");
+
+ lines = (GSList *)event_info;
+ if (g_slist_length(lines) != 1) {
+ err("+CIEV unsolicited message expected to be "
+ "Single line but received multiple lines");
+ return TRUE;
+ }
+
+ line = (const gchar *)lines->data;
+ if (line != NULL) {
+ GSList *tokens;
+ guint descriptor;
+ guint value;
+
+ tokens = tcore_at_tok_new(line);
+
+ /* <desc> */
+ descriptor = atoi(g_slist_nth_data(tokens, 0));
+ dbg("Descriptor: [%s]", (descriptor == 10 ? "RSSI"
+ : (descriptor == 15 ? "Battery" : "Unknown")));
+
+ /* <value> */
+ value = atoi(g_slist_nth_data(tokens, 1));
+
+ switch (descriptor) {
+ case 10:
+ dbg("RSSI Level: [%d]", value);
+
+ /* Send Notification - Network Rssi */
+ tcore_object_send_notification(co,
+ TCORE_NOTIFICATION_NETWORK_RSSI,
+ sizeof(guint), &value);
+ break;
+ case 15:
+ dbg("Battery Level: [%d]", value);
+ break;
+ default:
+ warn("Unknown descriptor: [%d]", descriptor);
+ break;
+ }
+
+ /* Free resource */
+ tcore_at_tok_free(tokens);
+ }
+
+ return TRUE;
+}
+
+/* Network Responses */
+static void on_response_atmodem_network_search(TcorePending *p,
+ guint data_len, const void *data, void *user_data)
+{
+ const TcoreAtResponse *at_resp = data;
+ CoreObject *co = tcore_pending_ref_core_object(p);
+ AtmodemRespCbData *resp_cb_data = user_data;
+ TelNetworkResult result = TEL_NETWORK_RESULT_FAILURE; //TODO - CME Error mapping required.
+ TelNetworkPlmnList plmn_list = {0,};
+ guint num_network_avail;
+ guint count;
+ GSList *tokens = NULL;
+
+ dbg("Enter");
+ tcore_check_return_assert(co != NULL);
+ tcore_check_return_assert(resp_cb_data != NULL);
+
+ if (at_resp && at_resp->success) {
+ const gchar *line;
+ GSList *net_token = NULL;
+ gchar *resp;
+ gint act;
+
+ if (!at_resp->lines) {
+ err("invalid response received");
+ goto END;
+ }
+
+ line = (char *) at_resp->lines->data;
+ tokens = tcore_at_tok_new(line);
+ num_network_avail = g_slist_length(tokens);
+ if (num_network_avail < 1) {
+ err("invalid message");
+ goto END;
+ }
+
+ plmn_list.network_list = tcore_malloc0(sizeof(TelNetworkInfo) * num_network_avail);
+ dbg("RESPONSE OK");
+ plmn_list.count = 0;
+ for (count = 0; count < num_network_avail; count++) {
+
+ net_token = tcore_at_tok_new(g_slist_nth_data(tokens, count));
+ if (NULL == net_token)
+ continue;
+
+ resp = tcore_at_tok_nth(net_token, 0);
+ if (resp != NULL) {
+ plmn_list.network_list[count].plmn_status = atoi(resp);
+ dbg("status[%d]", plmn_list.network_list[count].plmn_status);
+ }
+
+ if ((resp = tcore_at_tok_nth(net_token, 1))) {
+ /* Long Alpha name */
+ dbg("long alpha name[%s]", resp);
+ plmn_list.network_list[count].network_identity.long_name =
+ tcore_at_tok_extract(resp);
+ }
+
+ if ((resp = tcore_at_tok_nth(net_token, 2))) {
+ /* Short Alpha name */
+ dbg("Short Alpha name[%s]", resp);
+ plmn_list.network_list[count].network_identity.short_name =
+ tcore_at_tok_extract(resp);
+ }
+
+ /* PLMN ID */
+ if ((resp = tcore_at_tok_nth(net_token, 3))) {
+ dbg("PLMN ID[%s]", resp);
+ plmn_list.network_list[count].network_identity.plmn =
+ tcore_at_tok_extract(resp);
+ }
+
+ /* Parse Access Technology */
+ if ((resp = tcore_at_tok_nth(tokens, 4))) {
+ act = atoi(resp);
+ if (0 == act)
+ plmn_list.network_list[count].act = TEL_NETWORK_ACT_GSM;
+ else if (2 == act)
+ plmn_list.network_list[count].act = TEL_NETWORK_ACT_UMTS;
+ }
+
+ dbg("Operator [%d] :: status = %d, long_name = %s, short_name = %s plmn = %s, AcT=%d",
+ plmn_list.network_list[count].plmn_status,
+ plmn_list.network_list[count].network_identity.long_name,
+ plmn_list.network_list[count].network_identity.short_name,
+ plmn_list.network_list[count].network_identity.plmn,
+ plmn_list.network_list[count].act);
+
+ plmn_list.count ++;
+ tcore_at_tok_free(net_token);
+ }
+ result = TEL_NETWORK_RESULT_SUCCESS;
+ } else {
+ err("RESPONSE NOK");
+ if (at_resp->lines)
+ err("CME Error[%s]",(char *)at_resp->lines->data);
+ }
+
+END:
+ dbg("Network search : [%s]",
+ (result == TEL_NETWORK_RESULT_SUCCESS ? "SUCCESS" : "FAIL"));
+
+ /* Invoke callback */
+ if(resp_cb_data->cb)
+ resp_cb_data->cb(co, (gint)result, &plmn_list, resp_cb_data->cb_data);
+
+ atmodem_destroy_resp_cb_data(resp_cb_data);
+ /* Free resources*/
+ for (count = 0; count < num_network_avail; count++) {
+ g_free(plmn_list.network_list[count].network_identity.long_name);
+ g_free(plmn_list.network_list[count].network_identity.short_name);
+ g_free(plmn_list.network_list[count].network_identity.plmn);
+ }
+
+ tcore_free(plmn_list.network_list);
+ tcore_at_tok_free(tokens);
+}
+
+static void on_response_atmodem_network_get_selection_mode(TcorePending *p,
+ guint data_len, const void *data, void *user_data)
+{
+ const TcoreAtResponse *at_resp = data;
+ CoreObject *co = tcore_pending_ref_core_object(p);
+ AtmodemRespCbData *resp_cb_data = user_data;
+ TelNetworkSelectionMode selection_mode = -1;
+ GSList *tokens = NULL;
+
+ TelNetworkResult result = TEL_NETWORK_RESULT_FAILURE; //TODO - CME Error mapping required.
+ dbg("Enter");
+
+ tcore_check_return_assert(co != NULL);
+ tcore_check_return_assert(resp_cb_data != NULL);
+
+ if (at_resp && at_resp->success) {
+ const gchar *line;
+ gint mode;
+
+ if (!at_resp->lines) {
+ err("invalid response received");
+ goto END;
+ }
+
+ line = (char *) at_resp->lines->data;
+ tokens = tcore_at_tok_new(line);
+ if (g_slist_length(tokens) < 1) {
+ msg("invalid message");
+ goto END;
+ }
+ dbg("RESPONSE OK");
+
+ mode = atoi(tcore_at_tok_nth(tokens, 0));
+ if(mode == 0)
+ selection_mode = TEL_NETWORK_SELECTION_MODE_AUTOMATIC;
+ else if (mode == 1)
+ selection_mode = TEL_NETWORK_SELECTION_MODE_MANUAL;
+
+ dbg("selection mode[%d]", selection_mode);
+ result = TEL_NETWORK_RESULT_SUCCESS;
+
+ } else {
+ err("RESPONSE NOK");
+ }
+
+END:
+ dbg("Get selection mode : [%s]",
+ (result == TEL_NETWORK_RESULT_SUCCESS ? "SUCCESS" : "FAIL"));
+
+ /* Invoke callback */
+ if (resp_cb_data->cb)
+ resp_cb_data->cb(co, (gint)result, &selection_mode, resp_cb_data->cb_data);
+
+ /* Free callback data */
+ atmodem_destroy_resp_cb_data(resp_cb_data);
+
+ /* Free resource*/
+ tcore_at_tok_free(tokens);
+}
+
+static void on_response_atmodem_network_default(TcorePending *p,
+ guint data_len, const void *data, void *user_data)
+{
+ const TcoreAtResponse *at_resp = data;
+ CoreObject *co = tcore_pending_ref_core_object(p);
+ AtmodemRespCbData *resp_cb_data = user_data;
+ TelNetworkResult result = TEL_NETWORK_RESULT_FAILURE; //TODO - CME Error mapping required.
+
+ dbg("Enter");
+ tcore_check_return_assert(co != NULL);
+ tcore_check_return_assert(resp_cb_data != NULL);
+
+ if (at_resp && at_resp->success) {
+ dbg("RESPONSE OK");
+ result = TEL_NETWORK_RESULT_SUCCESS;
+ } else {
+ err("RESPONSE NOK");
+ if (at_resp->lines)
+ err("CME Error[%s]",(char *)at_resp->lines->data);
+ }
+
+ /* Invoke callback */
+ if(resp_cb_data->cb)
+ resp_cb_data->cb(co, (gint)result, NULL, resp_cb_data->cb_data);
+
+ atmodem_destroy_resp_cb_data(resp_cb_data);
+}
+
+/* Network Operations */
+/*
+ * Operation - fetch_nw_name
+ *
+ * Request -
+ * AT-Command: AT+COPS=[<mode>[,<format>[,<oper>[,< AcT>]]]]
+ *
+ * <mode> may be
+ * 1 Manual. Other parameters like format and operator need to be passed
+ * 2 Deregister from network
+ * 3 It sets <format> value. In this case <format> becomes a mandatory input
+ * 4 Manual / Automatic. In this case if manual selection fails then automatic mode
+ * is entered
+ *
+ * <format> may be
+ * 0 format presentations are set to long alphanumeric. If Network name not
+ * available it displays combination of Mcc and MNC in string format.
+ * 1 format presentation is set to short alphanumeric.
+ * 2 format presentations set to numeric.
+ *
+ * <oper> may be
+ * string type given in format <format>
+ *
+ * Response - Network name
+ * Success: (Multiple Single line)
+ * +COPS: <mode>[,<format>,<oper>[,< AcT>]]
+ * OK
+ * Failure:
+ * +CME ERROR: <error>
+ */
+static TelReturn atmodem_network_get_identity_info(CoreObject *co,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ return __atmodem_network_fetch_nw_name(co, cb, cb_data);
+}
+
+/*
+ * Operation - network search
+ * Request -
+ * AT-Command: AT+COPS=?
+ *
+ * Response -
+ * Success: (Single line)
+ * +COPS: [list of supported (<stat>,long alphanumeric <oper>
+ * ,short alphanumeric <oper>,numeric <oper>[,< AcT>]
+ * [,,(list of supported <mode>s),(list of supported <format>s)]
+
+ * <format>
+ * describes the format in which operator name is to be displayed. Different values of <format> can be:
+ * 0 <oper> format presentations are set to long alphanumeric. If Network name not available it displays
+ * combination of Mcc and MNC in string format.
+ * 1 <oper> format presentation is set to short alphanumeric.
+ * 2 <oper> format presentations set to numeric.
+ * <oper>:
+ * string type given in format <format>; this field may be up to 16 character long for long alphanumeric format, up
+ * to 8 characters for short alphanumeric format and 5 Characters long for numeric format (MCC/MNC codes)
+ * <stat>:
+ * describes the status of the network. It is one of the response parameter for test command.
+ * 0 Unknown Networks
+ * 1 Network Available
+ * 2 Current
+ * 3 Forbidden Network
+ * <AcT>
+ * indicates the radio access technology and values can be:
+ * 0 GSM
+ * 2 UMTS
+ * OK
+ * Failure:
+ * +CME ERROR: <error>
+ */
+
+static TelReturn atmodem_network_search(CoreObject *co,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ AtmodemRespCbData *resp_cb_data;
+ TelReturn ret = TEL_RETURN_INVALID_PARAMETER;
+
+ /* Response callback data */
+ resp_cb_data = atmodem_create_resp_cb_data(cb, cb_data, NULL, 0);
+
+ /* Send Request to modem */
+ ret = tcore_at_prepare_and_send_request(co,
+ "AT+COPS=?", "+COPS",
+ TCORE_AT_COMMAND_TYPE_SINGLELINE,
+ TCORE_PENDING_PRIORITY_DEFAULT,
+ NULL,
+ on_response_atmodem_network_search, resp_cb_data,
+ on_send_atmodem_request, NULL,
+ 0, NULL, NULL);
+
+ ATMODEM_CHECK_REQUEST_RET(ret, resp_cb_data, "Network Search");
+ return ret;
+}
+
+/*
+ * Operation - automatic network selection
+ * Request -
+ * AT-Command: AT+COPS= [<mode> [, <format> [, <oper>> [, <AcT>]]]]
+ * where
+ * <mode>
+ * is used to select, whether the selection is done automatically by the ME or is forced by this command to
+ * operator <oper> given in the format <format>.
+ * The values of <mode> can be:
+ * 0 Automatic, in this case other fields are ignored and registration is done automatically by ME
+ * 1 Manual. Other parameters like format and operator need to be passed
+ * 2 Deregister from network
+ * 3 It sets <format> value. In this case <format> becomes a mandatory input
+ * 4 Manual / Automatic. In this case if manual selection fails then automatic mode is entered
+ *
+ * Response -
+ * Success:(No result)
+ * OK or
+ * +CME ERROR: <err>
+ */
+static TelReturn atmodem_network_select_automatic(CoreObject *co,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ AtmodemRespCbData *resp_cb_data;
+ TelReturn ret = TEL_RETURN_INVALID_PARAMETER;
+ dbg("entry");
+
+ /* Response callback data */
+ resp_cb_data = atmodem_create_resp_cb_data(cb, cb_data, NULL, 0);
+
+ /* Send Request to modem */
+ ret = tcore_at_prepare_and_send_request(co,
+ "AT+COPS=0", NULL,
+ TCORE_AT_COMMAND_TYPE_NO_RESULT,
+ TCORE_PENDING_PRIORITY_DEFAULT,
+ NULL,
+ on_response_atmodem_network_default, resp_cb_data,
+ on_send_atmodem_request, NULL,
+ 0, NULL, NULL);
+
+ ATMODEM_CHECK_REQUEST_RET(ret, resp_cb_data, "Automatic network selection");
+ return ret;
+}
+
+/*
+ * Operation - manual network selection
+ * Request -
+ * AT-Command: AT+COPS= [<mode> [, <format> [, <oper>> [, <AcT>]]]]
+ * where
+ * <mode>
+ * is used to select, whether the selection is done automatically by the ME or is forced by this command to
+ * operator <oper> given in the format <format>.
+ * The values of <mode> can be:
+ * 0 Automatic, in this case other fields are ignored and registration is done automatically by ME
+ * 1 Manual. Other parameters like format and operator need to be passed
+ * 2 Deregister from network
+ * 3 It sets <format> value. In this case <format> becomes a mandatory input
+ * 4 Manual / Automatic. In this case if manual selection fails then automatic mode is entered.
+ * <oper>
+ * string type given in format <format>; this field may be up to 16 character long for long alphanumeric format, up
+ * to 8 characters for short alphanumeric format and 5 Characters long for numeric format (MCC/MNC codes)
+ * <AcT>
+ * indicates the radio access technology and values can be:
+ * 0 GSM
+ * 2 UMTS
+ *
+ * Response -
+ * Success:(No result)
+ * OK or
+ * +CME ERROR: <err>
+ */
+static TelReturn atmodem_network_select_manual(CoreObject *co,
+ const TelNetworkSelectManualInfo *sel_manual,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ AtmodemRespCbData *resp_cb_data;
+ TelReturn ret = TEL_RETURN_INVALID_PARAMETER;
+ gchar *at_cmd;
+ gint act;
+ dbg("entry");
+
+ switch(sel_manual->act) {
+ case TEL_NETWORK_ACT_GSM:
+ case TEL_NETWORK_ACT_GPRS:
+ case TEL_NETWORK_ACT_EGPRS:
+ act = 0;
+ break;
+ case TEL_NETWORK_ACT_UMTS:
+ case TEL_NETWORK_ACT_GSM_AND_UMTS:
+ case TEL_NETWORK_ACT_HSDPA:
+ case TEL_NETWORK_ACT_HSPA:
+ act = 2;
+ break;
+ default:
+ err("unsupported AcT");
+ return ret;
+ }
+
+ /* AT-Command */
+ at_cmd = g_strdup_printf("AT+COPS=1,2,\"%s\",%d", sel_manual->plmn, act);
+
+ /* Response callback data */
+ resp_cb_data = atmodem_create_resp_cb_data(cb, cb_data, NULL, 0);
+
+ /* Send Request to modem */
+ ret = tcore_at_prepare_and_send_request(co,
+ at_cmd, NULL,
+ TCORE_AT_COMMAND_TYPE_NO_RESULT,
+ TCORE_PENDING_PRIORITY_DEFAULT,
+ NULL,
+ on_response_atmodem_network_default, resp_cb_data,
+ on_send_atmodem_request, NULL,
+ 0, NULL, NULL);
+
+ ATMODEM_CHECK_REQUEST_RET(ret, resp_cb_data, "Manual network selection");
+ /* Free resources*/
+ g_free(at_cmd);
+ return ret;
+}
+
+/*
+ * Operation - get network selection mode
+ * Request -
+ * AT-Command: AT+COPS?
+ *
+ * Response -
+ * Success: (Single line)
+ * +COPS: <mode>[,<format>,<oper>[,< AcT>]]
+ * <mode>
+ * is used to select, whether the selection is done automatically by the ME or is forced by this command to
+ * operator <oper> given in the format <format>.
+ * The values of <mode> can be:
+ * 0 Automatic, in this case other fields are ignored and registration is done automatically by ME
+ * 1 Manual. Other parameters like format and operator need to be passed
+ * 2 Deregister from network
+ * 3 It sets <format> value. In this case <format> becomes a mandatory input
+ * 4 Manual / Automatic. In this case if manual selection fails then automatic mode is entered
+ * OK
+ * Failure:
+ * +CME ERROR: <error>
+ */
+static TelReturn atmodem_network_get_selection_mode(CoreObject *co,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ AtmodemRespCbData *resp_cb_data;
+ TelReturn ret = TEL_RETURN_INVALID_PARAMETER;
+
+ /* Response callback data */
+ resp_cb_data = atmodem_create_resp_cb_data(cb, cb_data, NULL, 0);
+
+ /* Send Request to modem */
+ ret = tcore_at_prepare_and_send_request(co,
+ "AT+COPS?", "+COPS",
+ TCORE_AT_COMMAND_TYPE_SINGLELINE,
+ TCORE_PENDING_PRIORITY_DEFAULT,
+ NULL,
+ on_response_atmodem_network_get_selection_mode, resp_cb_data,
+ on_send_atmodem_request, NULL,
+ 0, NULL, NULL);
+
+ ATMODEM_CHECK_REQUEST_RET(ret, resp_cb_data, "Get selection mode");
+ return ret;
+}
+
+/* Network Operations */
+static TcoreNetworkOps atmodem_network_ops = {
+ .get_identity_info = atmodem_network_get_identity_info,
+ .search = atmodem_network_search,
+ .cancel_search = NULL,
+ .select_automatic = atmodem_network_select_automatic,
+ .select_manual = atmodem_network_select_manual,
+ .get_selection_mode = atmodem_network_get_selection_mode,
+ .set_preferred_plmn = NULL,
+ .get_preferred_plmn = NULL,
+ .set_mode = NULL,
+ .get_mode = NULL,
+ .get_neighboring_cell_info = NULL
+};
+
+gboolean atmodem_network_init(TcorePlugin *p, CoreObject *co)
+{
+ dbg("Enter");
+
+ /* Set operations */
+ tcore_network_set_ops(co, &atmodem_network_ops);
+
+ /* Add Callbacks */
+ tcore_object_add_callback(co,
+ "+CREG:",
+ on_notification_atmodem_cs_network_info, NULL);
+ tcore_object_add_callback(co,
+ "+CGREG:",
+ on_notification_atmodem_ps_network_info, NULL);
+ tcore_object_add_callback(co,
+ "+CIEV:",
+ on_notification_atmodem_network_rssi, NULL);
+
+ /*
+ * Add Hooks - Request and Notification
+ */
+ tcore_plugin_add_request_hook(p,
+ TCORE_COMMAND_MODEM_SET_FLIGHTMODE,
+ on_hook_atmodem_set_flight_mode, NULL);
+ tcore_plugin_add_notification_hook(p,
+ TCORE_NOTIFICATION_SIM_STATUS,
+ on_hook_atmodem_sim_status, co);
+
+ //_insert_mcc_mnc_oper_list(cp, co_network);
+
+ dbg("Exit");
+ return TRUE;
+}
+
+void atmodem_network_exit(TcorePlugin *p, CoreObject *co)
+{
+ dbg("Exit");
+}
--- /dev/null
+/*
+ * tel-plugin-atmodem
+ *
+ * Copyright (c) 2013 Samsung Electronics Co. Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <glib.h>
+
+#include <tcore.h>
+#include <server.h>
+#include <plugin.h>
+#include <core_object.h>
+#include <hal.h>
+#include <queue.h>
+#include <storage.h>
+#include <at.h>
+
+#include <co_ps.h>
+#include <co_context.h>
+
+#include "atmodem_ps.h"
+#include "atmodem_common.h"
+
+typedef struct {
+ TcorePsCallState ps_call_status;
+} PrivateInfo;
+
+static void __notify_context_status_changed(CoreObject *co_ps, guint context_id,
+ TcorePsCallState status)
+{
+ PrivateInfo *private_info = tcore_object_ref_user_data(co_ps);
+ TcorePsCallStatusInfo data_resp = {0,};
+ tcore_check_return_assert(private_info != NULL);
+
+ dbg("Entry");
+
+ private_info->ps_call_status = status;
+ data_resp.context_id = context_id;
+ data_resp.state = status;
+ dbg("Sending PS Call Status Notification - Context ID: [%d] Context State: [%d]",
+ data_resp.context_id, data_resp.state);
+
+ /* Send PS CALL Status Notification */
+ (void)tcore_object_send_notification(co_ps,
+ TCORE_NOTIFICATION_PS_CALL_STATUS,
+ sizeof(TcorePsCallStatusInfo),
+ &data_resp);
+
+ dbg("Exit");
+}
+
+static void __atmodem_ps_setup_pdp(CoreObject *co_ps, gint result, const gchar *netif_name,
+ void *user_data)
+{
+ CoreObject *ps_context = user_data;
+ guint context_id;
+
+ tcore_check_return_assert(ps_context != NULL);
+
+ dbg("Enter");
+
+ if (result < 0) {
+ /* Deactivate PDP context */
+ (void)tcore_object_dispatch_request(co_ps, TRUE,
+ TCORE_COMMAND_PS_DEACTIVATE_CONTEXT,
+ NULL, 0,
+ NULL, NULL);
+
+ return;
+ }
+
+ dbg("devname = [%s]", netif_name);
+
+ tcore_context_set_ipv4_devname(ps_context, netif_name);
+
+ (void)tcore_context_get_id(ps_context, &context_id);
+ dbg("Context ID : %d", context_id);
+
+ __notify_context_status_changed(co_ps, context_id, TCORE_PS_CALL_STATE_CONNECTED);
+
+ dbg("Exit");
+}
+
+static void __on_response_atmodem_get_ipconfiguration(TcorePending *p, guint data_len, const void *data, void *user_data)
+{
+ CoreObject *co_ps = tcore_pending_ref_core_object(p);
+ CoreObject *ps_context = user_data;
+ const TcoreAtResponse *at_resp = data;
+ TcoreHal *hal = tcore_object_get_hal(co_ps);
+ PrivateInfo *private_info = tcore_object_ref_user_data(co_ps);
+ guint context_id;
+ TcorePsCallState curr_call_status;
+ GSList *p_cur = NULL;
+
+ (void)tcore_context_get_id(ps_context, &context_id);
+
+ if (at_resp && at_resp->success) {
+ for (p_cur = at_resp->lines; p_cur != NULL; p_cur = p_cur->next) {
+ const gchar *line;
+ GSList *tokens = NULL;
+
+ line = (const char *) p_cur->data;
+ tokens = tcore_at_tok_new(line);
+
+ if (g_slist_length(tokens) >= 2) {
+ gchar *pdp_type = NULL, *apn = NULL;
+ gchar *ip = NULL, *pdp_address = NULL, *p_cid = NULL;
+
+ p_cid = g_slist_nth_data(tokens, 0);
+ dbg("cid: %d", p_cid);
+
+ /* Send IP Configuration noti only on the requested CID. */
+ if (atoi(p_cid) && (context_id == (unsigned int)atoi(p_cid))) {
+ pdp_type = g_slist_nth_data(tokens, 1);
+ dbg("PDP type: %s", pdp_type);
+
+ if (pdp_type != NULL) {
+ apn = g_slist_nth_data(tokens, 2);
+ dbg("APN: %s", apn);
+ }
+ if (apn != NULL) {
+ ip = g_slist_nth_data(tokens, 3);
+ pdp_address = tcore_at_tok_extract(ip);
+ dbg("IP address: %s", ip);
+ }
+
+ (void)tcore_context_set_ipv4_addr(ps_context, (const char*)pdp_address);
+ tcore_free(pdp_address);
+
+ dbg("Adding default DNS pri: 8.8.8.8 sec: 8.8.4.4");
+
+ tcore_context_set_ipv4_dns(ps_context, "8.8.8.8", "8.8.4.4");
+
+ /* Mount network interface */
+ if (tcore_hal_setup_netif(hal, co_ps, __atmodem_ps_setup_pdp, ps_context, context_id, TRUE)
+ != TEL_RETURN_SUCCESS) {
+ err("Setup network interface failed");
+ return;
+ }
+ } else {
+ err("No matched response with CID: %d", atoi(p_cid));
+ }
+ }
+ }
+ }else {
+ err("Response NOK");
+
+ (void)tcore_context_get_id(ps_context, &context_id);
+
+ curr_call_status = private_info->ps_call_status;
+
+ __notify_context_status_changed(co_ps, context_id, curr_call_status);
+ }
+}
+
+static void __atmodem_get_ipconfiguration(CoreObject *co_ps, CoreObject *ps_context)
+{
+ TelReturn ret;
+
+ dbg("Enter");
+
+ /* Send Request to modem */
+ ret = tcore_at_prepare_and_send_request(co_ps,
+ "AT+CGDCONT?", NULL,
+ TCORE_AT_COMMAND_TYPE_NO_RESULT,
+ TCORE_PENDING_PRIORITY_DEFAULT,
+ NULL,
+ __on_response_atmodem_get_ipconfiguration,
+ ps_context,
+ on_send_atmodem_request, NULL,
+ 0, NULL, NULL);
+
+ if (ret != TEL_RETURN_SUCCESS){
+ err("Failed to prepare and send AT request");
+ /* Deactivate PDP context */
+ (void)tcore_object_dispatch_request(co_ps, TRUE,
+ TCORE_COMMAND_PS_DEACTIVATE_CONTEXT,
+ NULL, 0,
+ NULL, NULL);
+ }
+
+ dbg("Exit");
+}
+
+static void __on_response_atmodem_attach_ps(TcorePending *p, guint data_len,
+ const void *data, void *user_data)
+{
+ CoreObject *co_ps = tcore_pending_ref_core_object(p);
+ CoreObject *ps_context = user_data;
+ const TcoreAtResponse *at_resp = data;
+ PrivateInfo *private_info = tcore_object_ref_user_data(co_ps);
+ guint context_id;
+ TcorePsCallState curr_call_status;
+
+ tcore_check_return_assert(at_resp != NULL);
+ tcore_check_return_assert(ps_context != NULL);
+
+ if (at_resp && at_resp->success) {
+ __atmodem_get_ipconfiguration(co_ps, ps_context);
+ return;
+ }
+
+ err("Response NOK");
+
+ (void)tcore_context_get_id(ps_context, &context_id);
+
+ curr_call_status = private_info->ps_call_status;
+
+ __notify_context_status_changed(co_ps, context_id, curr_call_status);
+
+ dbg("Exit");
+}
+
+static void __atmodem_attach_ps(CoreObject *co_ps, CoreObject *ps_context)
+{
+ TelReturn ret;
+
+ dbg("Enter");
+
+ /* Send Request to modem */
+ ret = tcore_at_prepare_and_send_request(co_ps,
+ "ATD*99***1#", NULL,
+ TCORE_AT_COMMAND_TYPE_NO_RESULT,
+ TCORE_PENDING_PRIORITY_DEFAULT,
+ NULL,
+ __on_response_atmodem_attach_ps,
+ ps_context,
+ on_send_atmodem_request, NULL,
+ 0, NULL, NULL);
+
+ if (ret != TEL_RETURN_SUCCESS){
+ err("Failed to prepare and send AT request");
+ /* Deactivate PDP context */
+ (void)tcore_object_dispatch_request(co_ps, TRUE,
+ TCORE_COMMAND_PS_DEACTIVATE_CONTEXT,
+ NULL, 0,
+ NULL, NULL);
+ }
+
+ dbg("Exit");
+}
+
+static void on_response_atmodem_ps_activate_context(TcorePending *p, guint data_len,
+ const void *data,
+ void *user_data)
+{
+ CoreObject *co_ps = tcore_pending_ref_core_object(p);
+ const TcoreAtResponse *at_resp = data;
+ CoreObject *ps_context = user_data;
+ PrivateInfo *private_info = tcore_object_ref_user_data(co_ps);
+ tcore_check_return_assert(private_info != NULL);
+
+ dbg("Enter");
+
+ tcore_check_return_assert(at_resp != NULL);
+ tcore_check_return_assert(ps_context != NULL);
+
+ if (at_resp && at_resp->success) {
+ dbg("Response OK");
+ __atmodem_attach_ps(co_ps, ps_context);
+ } else {
+ guint context_id;
+ TcorePsCallState curr_call_status;
+
+ (void)tcore_context_get_id(ps_context, &context_id);
+
+ err("Response NOK");
+ curr_call_status = private_info->ps_call_status;
+ __notify_context_status_changed(co_ps, context_id, curr_call_status);
+ }
+
+ dbg("Exit");
+}
+
+static void on_response_atmodem_ps_deactivate_context(TcorePending *p, guint data_len,
+ const void *data,
+ void *user_data)
+{
+ CoreObject *co_ps = tcore_pending_ref_core_object(p);
+ TcoreHal *hal = tcore_object_get_hal(co_ps);
+ const TcoreAtResponse *at_resp = data;
+ CoreObject *ps_context = user_data;
+ guint context_id;
+
+ dbg("Enter");
+
+ tcore_check_return_assert(at_resp != NULL);
+ tcore_check_return_assert(ps_context != NULL);
+
+ (void)tcore_context_get_id(ps_context, &context_id);
+ dbg("Context ID : %d", context_id);
+
+ /*
+ * AT+CGACT = 0 is returning NO CARRIER or an error. Just test if the
+ * response contains NO CARRIER else decode CME error.
+ */
+ if (at_resp && at_resp->success) {
+ const gchar *line;
+
+ line = (const gchar *)at_resp->lines->data;
+ if (g_strcmp0(line, "NO CARRIER") != 0) {
+ err("%s", line);
+ err("Context %d has not been deactivated", context_id);
+
+ goto out;
+ }
+ }
+
+ __notify_context_status_changed(co_ps, context_id, TCORE_PS_CALL_STATE_NOT_CONNECTED);
+
+ if (tcore_hal_setup_netif(hal, co_ps, NULL, NULL, context_id, FALSE) != TEL_RETURN_SUCCESS)
+ err("Failed to disable network interface");
+
+out:
+ dbg("Exit");
+}
+
+static void on_response_atmodem_ps_define_context(TcorePending *p,
+ guint data_len, const void *data, void *user_data)
+{
+ const TcoreAtResponse *at_resp = data;
+ CoreObject *ps_context = (CoreObject *) user_data;
+ CoreObject *co_ps = tcore_pending_ref_core_object(p);
+ PrivateInfo *private_info = tcore_object_ref_user_data(co_ps);
+ guint context_id;
+ TcorePsCallState curr_call_status;
+
+ dbg("entry");
+
+ tcore_check_return_assert(at_resp != NULL);
+ tcore_check_return_assert(ps_context != NULL);
+ tcore_check_return_assert(private_info != NULL);
+
+ if (at_resp && at_resp->success) {
+ dbg("Response OK");
+ curr_call_status = TCORE_PS_CALL_STATE_CTX_DEFINED;
+ tcore_context_set_state(co_ps, curr_call_status);
+ }else {
+ err("ERROR[%s]",at_resp->final_response);
+ curr_call_status =private_info->ps_call_status;
+ }
+ (void)tcore_context_get_id(ps_context, &context_id);
+ __notify_context_status_changed(co_ps, context_id, curr_call_status);
+}
+
+/*
+ * Operation - PDP Context Activate
+ *
+ * Request -
+ * AT-Command: AT+CGACT= [<state> [, <cid> [, <cid> [,...]]]]
+ *
+ * where,
+ * <state>
+ * indicates the state of PDP context activation
+ *
+ * 1 activated
+ *
+ * <cid>
+ * It is a numeric parameter which specifies a particular PDP context definition
+ *
+ * Response -
+ * Success: (No Result)
+ * OK
+ * Failure:
+ * +CME ERROR: <error>
+ */
+
+static TelReturn atmodem_ps_activate_context(CoreObject *co_ps, CoreObject *ps_context,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ gchar *at_cmd = NULL;
+ TelReturn ret;
+ guint context_id;
+ PrivateInfo *private_info = tcore_object_ref_user_data(co_ps);
+ tcore_check_return_value_assert(private_info != NULL, TEL_RETURN_INVALID_PARAMETER);
+
+ dbg("Entry");
+
+ (void)tcore_context_get_id(ps_context, &context_id);
+ dbg("Context ID : %d", context_id);
+
+ at_cmd = g_strdup_printf("AT+CGACT=1,%d", context_id);
+ dbg(" at command : %s", at_cmd);
+
+ /* Send Request to modem */
+ ret = tcore_at_prepare_and_send_request(co_ps,
+ at_cmd, NULL,
+ TCORE_AT_COMMAND_TYPE_NO_RESULT,
+ TCORE_PENDING_PRIORITY_DEFAULT,
+ NULL,
+ on_response_atmodem_ps_activate_context,
+ ps_context,
+ on_send_atmodem_request, NULL,
+ 0, NULL, NULL);
+
+ if (ret != TEL_RETURN_SUCCESS){
+ TcorePsCallState curr_call_status;
+
+ curr_call_status = private_info->ps_call_status;
+ err("AT request failed. Send notification for call status [%d]", curr_call_status);
+ __notify_context_status_changed(co_ps, context_id, curr_call_status);
+ }
+ tcore_free(at_cmd);
+ dbg("Exit");
+
+ return ret;
+}
+
+/*
+ * Operation - PDP Context Deactivate
+ *
+ * Request -
+ * AT-Command: AT+CGACT= [<state> [, <cid> [, <cid> [,...]]]]
+ *
+ * where,
+ * <state>
+ * indicates the state of PDP context activation
+ *
+ * 0 deactivated
+ *
+ * <cid>
+ * It is a numeric parameter which specifies a particular PDP context definition
+ *
+ * Response -
+ * Success: (No Result)
+ * OK
+ * Failure:
+ * +CME ERROR: <error>
+ */
+static TelReturn atmodem_ps_deactivate_context(CoreObject *co_ps, CoreObject *ps_context,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ gchar *at_cmd = NULL;
+ TelReturn ret;
+ guint context_id;
+ PrivateInfo *private_info = tcore_object_ref_user_data(co_ps);
+ tcore_check_return_value_assert(private_info != NULL, TEL_RETURN_INVALID_PARAMETER);
+
+ dbg("Entry");
+
+ (void)tcore_context_get_id(ps_context, &context_id);
+ dbg("Context ID : %d", context_id);
+
+ at_cmd = g_strdup_printf("AT+CGACT=0,%d", context_id);
+ dbg(" at command : %s", at_cmd);
+
+ /* Send Request to modem */
+ ret = tcore_at_prepare_and_send_request(co_ps,
+ at_cmd, NULL,
+ TCORE_AT_COMMAND_TYPE_NO_RESULT,
+ TCORE_PENDING_PRIORITY_DEFAULT,
+ NULL,
+ on_response_atmodem_ps_deactivate_context,
+ ps_context,
+ on_send_atmodem_request, NULL,
+ 0, NULL, NULL);
+
+ if (ret != TEL_RETURN_SUCCESS){
+ TcorePsCallState curr_call_status;
+
+ curr_call_status = private_info->ps_call_status;
+ err("AT request failed. Send notification for call status [%d]", curr_call_status);
+ __notify_context_status_changed(co_ps, context_id, curr_call_status);
+ }
+ tcore_free(at_cmd);
+ dbg("Exit");
+
+ return ret;
+}
+
+/*
+ * Operation - Define PDP Context
+ *
+ * Request -
+ * AT-Command: AT+CGDCONT= [<cid> [, <PDP_type> [, <APN> [, <PDP_addr> [,
+ * <d_comp> [, <h_comp> [, <pd1> [... [, pdN]]]]]]]]]
+ * where,
+ * <cid>
+ * It is a numeric parameter, which specifies a particular PDP context definition
+ *
+ * <PDP_type>
+ * "IP" Internet Protocol (IETF STD 5)
+ * "IPV6" Internet Protocol, version 6 (IETF RFC 2460)
+ * "IPV4V6" Virtual <PDP_type>introduced to handle dual IP stack UE capability (see 3GPP
+ * TS 24.301[83])
+ *
+ * <APN>
+ * Access Point Name
+ *
+ * <PDP_address>
+ * It is the string parameter that identifies the MT in the address space applicable to the PDP
+ * The allocated address may be read using the command +CGPADDR command
+ *
+ * <d_comp>
+ * A numeric parameter that controls PDP data compression
+ * 0 off
+ * 1 on
+ * 2 V.42 bis
+ *
+ * <h_comp>
+ * A numeric parameter that controls PDP header compression
+ * 0 off
+ * 1 on
+ * 2 RFC1144
+ * 3 RFC2507
+ * 4 RFC3095
+ *
+ * <pd1>...<pdN>
+ * zero to N string parameters whose meanings are specific to the <PDP_type>
+ *
+ * Response -
+ * Success: (No Result)
+ * OK
+ * Failure:
+ * +CME ERROR: <error>
+ */
+static TelReturn atmodem_ps_define_context(CoreObject *co_ps, CoreObject *ps_context,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ guint context_id = 0;
+ gchar *at_cmd = NULL;
+ gchar *apn = NULL;
+ gchar *pdp_type_str = NULL;
+ TcoreContextType pdp_type;
+ TcoreContextDComp d_comp;
+ TcoreContextHComp h_comp;
+ TelReturn ret = TEL_RETURN_FAILURE;
+ TcorePsCallState curr_call_status;
+ PrivateInfo *private_info = tcore_object_ref_user_data(co_ps);
+ tcore_check_return_value_assert(private_info != NULL, TEL_RETURN_INVALID_PARAMETER);
+
+ dbg("Entry");
+
+ (void)tcore_context_get_id(ps_context, &context_id);
+ (void)tcore_context_get_type(ps_context, &pdp_type);
+
+ switch (pdp_type) {
+ case TCORE_CONTEXT_TYPE_X25:
+ dbg("CONTEXT_TYPE_X25");
+ pdp_type_str = g_strdup("X.25");
+ break;
+
+ case TCORE_CONTEXT_TYPE_IP:
+ dbg("CONTEXT_TYPE_IP");
+ pdp_type_str = g_strdup("IP");
+ break;
+
+ case TCORE_CONTEXT_TYPE_PPP:
+ dbg("CONTEXT_TYPE_PPP");
+ pdp_type_str = g_strdup("PPP");
+ break;
+
+ case TCORE_CONTEXT_TYPE_IPV6:
+ dbg("CONTEXT_TYPE_IPV6");
+ pdp_type_str = g_strdup("IPV6");
+ break;
+
+ default:
+ /*PDP Type not supported*/
+ dbg("Unsupported PDP type: %d", pdp_type);
+ goto error;
+ }
+
+ (void)tcore_context_get_data_compression(ps_context, &d_comp);
+ (void)tcore_context_get_header_compression(ps_context, &h_comp);
+ (void) tcore_context_get_apn(ps_context, &apn);
+
+ dbg("Define context for CID: %d", context_id);
+ /* AT-Command */
+ at_cmd = g_strdup_printf("AT+CGDCONT=%d,\"%s\",\"%s\",,%d,%d", context_id, pdp_type_str, apn, d_comp, h_comp);
+ dbg(" at command : %s", at_cmd);
+
+ /* Send Request to modem */
+ ret = tcore_at_prepare_and_send_request(co_ps,
+ at_cmd, NULL,
+ TCORE_AT_COMMAND_TYPE_NO_RESULT,
+ TCORE_PENDING_PRIORITY_DEFAULT,
+ NULL,
+ on_response_atmodem_ps_define_context,
+ ps_context,
+ on_send_atmodem_request, NULL,
+ 0, NULL, NULL);
+
+ tcore_free(pdp_type_str);
+ tcore_free(at_cmd);
+ tcore_free(apn);
+
+ if (ret == TEL_RETURN_SUCCESS)
+ goto out;
+
+error:
+ err("Failed to prepare and send AT request");
+
+ curr_call_status = private_info->ps_call_status;
+ __notify_context_status_changed(co_ps, context_id, curr_call_status);
+
+out:
+ dbg("Exit");
+ return ret;
+}
+
+/* PS Operations */
+static TcorePsOps atmodem_ps_ops = {
+ .define_context = atmodem_ps_define_context,
+ .activate_context = atmodem_ps_activate_context,
+ .deactivate_context = atmodem_ps_deactivate_context
+};
+
+
+gboolean atmodem_ps_init(TcorePlugin *p, CoreObject *co)
+{
+ PrivateInfo *private_info;
+
+ dbg("Entry");
+
+ /* Set PrivateInfo */
+ private_info = tcore_malloc0(sizeof(PrivateInfo));
+ tcore_object_link_user_data(co, private_info);
+
+ /* Set operations */
+ tcore_ps_set_ops(co, &atmodem_ps_ops);
+
+ dbg("Exit");
+ return TRUE;
+}
+
+void atmodem_ps_exit(TcorePlugin *p, CoreObject *co)
+{
+ PrivateInfo *private_info;
+
+ private_info = tcore_object_ref_user_data(co);
+ tcore_check_return_assert(private_info != NULL);
+
+ tcore_free(private_info);
+
+ dbg("Exit");
+}
--- /dev/null
+/*
+ * tel-plugin-atmodem
+ *
+ * Copyright (c) 2013 Samsung Electronics Co. Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <glib.h>
+
+#include <tcore.h>
+#include <server.h>
+#include <plugin.h>
+#include <core_object.h>
+#include <hal.h>
+#include <queue.h>
+#include <storage.h>
+#include <at.h>
+#include <vconf.h>
+
+#include <co_sim.h>
+#include <co_sms.h>
+
+#include "atmodem_sim.h"
+#include "atmodem_common.h"
+
+#define ENABLE_FLAG 1
+#define DISABLE_FLAG 2
+
+#define ATMODEM_SIM_ACCESS_READ_BINARY 176
+#define ATMODEM_SIM_ACCESS_READ_RECORD 178
+#define ATMODEM_SIM_ACCESS_GET_RESPONSE 192
+#define ATMODEM_SIM_ACCESS_UPDATE_BINARY 214
+#define ATMODEM_SIM_ACCESS_UPDATE_RECORD 220
+
+typedef enum {
+ ATMODEM_SIM_FILE_TYPE_DEDICATED = 0x00, /**< Dedicated */
+ ATMODEM_SIM_FILE_TYPE_TRANSPARENT = 0x01, /**< Transparent -binary type*/
+ ATMODEM_SIM_FILE_TYPE_LINEAR_FIXED = 0x02, /**< Linear fixed - record type*/
+ ATMODEM_SIM_FILE_TYPE_CYCLIC = 0x04, /**< Cyclic - record type*/
+ ATMODEM_SIM_FILE_TYPE_INVALID_TYPE = 0xFF /**< Invalid type */
+} AtmodemSimFileType;
+
+typedef enum {
+ ATMODEM_SIM_CURR_SEC_OP_PIN1_VERIFY,
+ ATMODEM_SIM_CURR_SEC_OP_PIN2_VERIFY,
+ ATMODEM_SIM_CURR_SEC_OP_PUK1_VERIFY,
+ ATMODEM_SIM_CURR_SEC_OP_PUK2_VERIFY,
+ ATMODEM_SIM_CURR_SEC_OP_SIM_VERIFY,
+ ATMODEM_SIM_CURR_SEC_OP_ADM_VERIFY,
+ ATMODEM_SIM_CURR_SEC_OP_PIN1_CHANGE,
+ ATMODEM_SIM_CURR_SEC_OP_PIN2_CHANGE,
+ ATMODEM_SIM_CURR_SEC_OP_PIN1_ENABLE,
+ ATMODEM_SIM_CURR_SEC_OP_PIN1_DISABLE,
+ ATMODEM_SIM_CURR_SEC_OP_PIN2_ENABLE,
+ ATMODEM_SIM_CURR_SEC_OP_PIN2_DISABLE, // 10
+ ATMODEM_SIM_CURR_SEC_OP_SIM_ENABLE,
+ ATMODEM_SIM_CURR_SEC_OP_SIM_DISABLE,
+ ATMODEM_SIM_CURR_SEC_OP_NET_ENABLE,
+ ATMODEM_SIM_CURR_SEC_OP_NET_DISABLE,
+ ATMODEM_SIM_CURR_SEC_OP_NS_ENABLE,
+ ATMODEM_SIM_CURR_SEC_OP_NS_DISABLE,
+ ATMODEM_SIM_CURR_SEC_OP_SP_ENABLE,
+ ATMODEM_SIM_CURR_SEC_OP_SP_DISABLE,
+ ATMODEM_SIM_CURR_SEC_OP_CP_ENABLE,
+ ATMODEM_SIM_CURR_SEC_OP_CP_DISABLE, // 20
+ ATMODEM_SIM_CURR_SEC_OP_FDN_ENABLE,
+ ATMODEM_SIM_CURR_SEC_OP_FDN_DISABLE,
+ ATMODEM_SIM_CURR_SEC_OP_PIN1_STATUS,
+ ATMODEM_SIM_CURR_SEC_OP_PIN2_STATUS,
+ ATMODEM_SIM_CURR_SEC_OP_FDN_STATUS,
+ ATMODEM_SIM_CURR_SEC_OP_NET_STATUS,
+ ATMODEM_SIM_CURR_SEC_OP_NS_STATUS,
+ ATMODEM_SIM_CURR_SEC_OP_SP_STATUS,
+ ATMODEM_SIM_CURR_SEC_OP_CP_STATUS,
+ ATMODEM_SIM_CURR_SEC_OP_SIM_STATUS,
+ ATMODEM_SIM_CURR_SEC_OP_SIM_UNKNOWN = 0xff
+} AtmodemSimCurrSecOp;
+
+typedef enum {
+ SEC_LOCK_TYPE_NONE =0,
+ SEC_LOCK_TYPE_READY, /* ME is not locked */
+ SEC_LOCK_TYPE_PS, /* PH-SIM, Lock Phone to SIM/UICC card(MT asks password when other than current SIM/UICC card inserted; MT may remember certain amount of
+ previously used cards thus not requiring password when they are inserted ) */
+ SEC_LOCK_TYPE_PF, /* PH-FSIM, Lock Phone to the very First inserted SIM/UICC card ( MT asks password when other than the first SIM/UICC card is inserted ) */
+ SEC_LOCK_TYPE_SC, /*Lock SIM/UICC card ( SIM asks password in ME power-up and when this command is issued ) */
+ SEC_LOCK_TYPE_FD, /* SIM card or active application in the UICC(GSM or USIM) fixed dialing memory feature */
+ SEC_LOCK_TYPE_PN, /* Network Personalization */
+ SEC_LOCK_TYPE_PU, /* Network subset Personalization */
+ SEC_LOCK_TYPE_PP, /* Service Provider Personalization */
+ SEC_LOCK_TYPE_PC, /* Corporate Personalization */
+ SEC_LOCK_TYPE_SC2, /* Lock PIN2 ( ... ) */
+ SEC_LOCK_TYPE_PUK2, /* Lock PUK2 (... ) */
+ SEC_LOCK_TYPE_ACL, /* ACL */
+
+ SEC_LOCK_TYPE_NO_SIM, /* SIM is not inserted */
+ SEC_LOCK_TYPE_UNAVAIL, /* SIM is inserted but can not communicate with SIM ( SIM interface error ) */
+ SEC_SIM_INIT_COMPLETED, /* SIM Initialize Completed */
+ SEC_PB_INIT_COMPLETED, /* Phonebook Initialize Completed*/
+ SEC_SIM_INIT_CRASH, /* SIM Crash request from SMC lab*/
+
+ SEC_LOCK_TYPE_MAX
+} AtmodemSimSecLockType;
+
+typedef enum {
+ SEC_LOCK_KEY_NONE,
+ SEC_LOCK_KEY_UNLOCKED, /* Not necessary */
+ SEC_LOCK_KEY_PIN, /* PIN required as a password */
+ SEC_LOCK_KEY_PUK, /* 0PUK required as a password */
+ SEC_LOCK_KEY_PIN2, /* PIN2 required as a password */
+ SEC_LOCK_KEY_PUK2, /* PUK2 required as a password */
+ SEC_LOCK_KEY_PERM_BLOCKED, /* PIN Permanent Blocked */
+ SEC_LOCK_KEY_PIN2_DISABLE, /* PIN2 Lock Disabled*/
+ SEC_LOCK_KEY_MAX
+} AtmodemSimSecLockKey;
+
+typedef struct {
+ guint smsp_count; /**< SMSP record count */
+ guint smsp_rec_len; /**< SMSP record length */
+} AtmodemSimPrivateInfo;
+
+typedef struct {
+ gboolean b_valid; /**< Valid or not */
+ guint rec_length; /**< Length of one record in file */
+ guint rec_count; /**< Number of records in file */
+ guint data_size; /**< File size */
+ guint current_index; /**< Current index to read */
+ AtmodemSimFileType file_type; /**< File type and structure */
+ AtmodemSimCurrSecOp sec_op; /**< Current index to read */
+ TelSimMailboxList mbi_list; /**< Mailbox List */
+ TelSimMailBoxNumber mb_list[TEL_SIM_MSP_CNT_MAX*5]; /**< Mailbox number */
+ TelSimFileId file_id; /**< Current file id */
+ TelSimResult file_result; /**< File access result */
+ TelSimFileResult files; /**< File read data */
+ TcoreCommand req_command; /**< Request command Id */
+ TelSimImsiInfo imsi; /**< Stored locally as of now,
+ Need to store in secure storage*/
+} AtmodemSimMetaInfo;
+
+/* Request Function Declaration */
+static TelReturn atmodem_sim_get_imsi (CoreObject *co_sim, TcoreObjectResponseCallback cb, void *cb_data);
+static TelReturn atmodem_sim_verify_pins(CoreObject *co, const TelSimSecPinPw *request,
+ TcoreObjectResponseCallback cb, void *cb_data);
+static TelReturn atmodem_sim_verify_puks(CoreObject *co, const TelSimSecPukPw *request,
+ TcoreObjectResponseCallback cb, void *cb_data);
+static TelReturn atmodem_sim_change_pins(CoreObject *co, const TelSimSecChangePinPw *request,
+ TcoreObjectResponseCallback cb, void *cb_data);
+static TelReturn atmodem_sim_disable_facility(CoreObject *co, const TelSimFacilityPw *request,
+ TcoreObjectResponseCallback cb, void *cb_data);
+static TelReturn atmodem_sim_enable_facility(CoreObject *co, const TelSimFacilityPw *request,
+ TcoreObjectResponseCallback cb, void *cb_data);
+static TelReturn atmodem_sim_get_facility(CoreObject *co, TelSimLockType lock_type,
+ TcoreObjectResponseCallback cb, void *cb_data);
+
+/* Utility Function Declaration */
+static TelSimResult __atmodem_sim_decode_status_word(unsigned short status_word1, unsigned short status_word2);
+static void __atmodem_sim_update_sim_status(CoreObject *co, TelSimCardStatus sim_status);
+static void __atmodem_sim_get_sim_type(CoreObject *co, TcoreObjectResponseCallback cb, void *cb_data);
+static void __atmodem_sim_next_from_get_file_data(CoreObject *co,
+ AtmodemRespCbData *resp_cb_data, TelSimResult sim_result, gboolean decode_ret);
+static void __atmodem_sim_next_from_get_file_info(CoreObject *co,
+ AtmodemRespCbData *resp_cb_data, TelSimResult sim_result);
+static void __atmodem_sim_get_file_record(CoreObject *co,
+ AtmodemRespCbData *resp_cb_data);
+static void __atmodem_sim_get_file_data(CoreObject *co,
+ AtmodemRespCbData *resp_cb_data);
+static TelReturn __atmodem_sim_get_file_info(CoreObject *co,
+ AtmodemRespCbData *resp_cb_data);
+static char *__atmodem_sim_get_fac_from_lock_type(TelSimLockType lock_type,
+ AtmodemSimCurrSecOp *sec_op, int flag);
+static int __atmodem_sim_get_lock_type(AtmodemSimCurrSecOp sec_op);
+static gboolean __atmodem_convert_scpin_str_to_enum(char* line,
+ AtmodemSimSecLockType* lock_type, AtmodemSimSecLockKey* lock_key);
+
+/* Internal Response Functions*/
+static void __atmodem_sim_next_from_read_binary(CoreObject *co,
+ AtmodemRespCbData *resp_cb_data,
+ TelSimResult sim_result, gboolean decode_ret);
+static void __atmodem_sim_next_from_get_response(CoreObject *co,
+ AtmodemRespCbData *resp_cb_data, TelSimResult sim_result);
+
+#if 0 //blocking for the moment
+static TelReturn __atmodem_sim_update_file(CoreObject *co,
+ AtmodemRespCbData *resp_cb_data,
+ int cmd, TelSimFileId ef,
+ int p1, int p2, int p3, char *encoded_data);
+#endif
+static void __atmodem_sim_read_record(CoreObject *co, AtmodemRespCbData *resp_cb_data);
+static void __atmodem_sim_read_binary(CoreObject *co, AtmodemRespCbData *resp_cb_data);
+static TelReturn __atmodem_sim_get_response (CoreObject *co, AtmodemRespCbData *resp_cb_data);
+static void __on_response_atmodem_sim_get_sim_type_internal(CoreObject *co,
+ gint result, const void *response, void *user_data);
+static void __on_response_atmodem_sim_get_sim_type(TcorePending *p,
+ guint data_len, const void *data, void *user_data);
+static void __on_response_atmodem_sim_get_file_data(TcorePending *p,
+ guint data_len, const void *data, void *user_data);
+static void __on_response_atmodem_sim_get_file_info(TcorePending *p,
+ guint data_len, const void *data, void *user_data);
+
+#define ATMODEM_SIM_READ_FILE(co, cb, cb_data, fileId, ret) \
+{ \
+ AtmodemSimMetaInfo file_meta = {0, }; \
+ AtmodemRespCbData *resp_cb_data = NULL; \
+ \
+ file_meta.file_id = fileId; \
+ file_meta.file_result = TEL_SIM_RESULT_FAILURE; \
+ \
+ resp_cb_data = atmodem_create_resp_cb_data(cb, cb_data, &file_meta, sizeof(AtmodemSimMetaInfo)); \
+ \
+ ret = __atmodem_sim_get_response(co, resp_cb_data); \
+}
+
+static void __atmodem_sim_set_identity(CoreObject *co, TelSimImsiInfo *imsi)
+{
+ gchar new_imsi[15 + 1] = {0, };
+ gchar *old_imsi;
+
+ memcpy(&new_imsi, imsi->mcc, strlen(imsi->mcc));
+ memcpy(&new_imsi[strlen(imsi->mcc)], imsi->mnc, strlen(imsi->mnc));
+ memcpy(&new_imsi[strlen(imsi->mcc) + strlen(imsi->mnc)], imsi->msin, strlen(imsi->msin));
+
+ /* TODO: This is temporary code, we should use secure storage instead of vconf */
+ old_imsi = vconf_get_str("db/telephony/imsi");
+ if (old_imsi) {
+ if (g_strcmp0(old_imsi, new_imsi) != 0) {
+ dbg("New SIM");
+ vconf_set_str("db/telephony/imsi", new_imsi);
+ tcore_sim_set_identification(co, TRUE);
+ } else {
+ dbg("Same SIM");
+ tcore_sim_set_identification(co, FALSE);
+ }
+ } else {
+ dbg("Old IMSI value is NULL, set IMSI");
+ vconf_set_str("db/telephony/imsi", new_imsi);
+ tcore_sim_set_identification(co, TRUE);
+ }
+}
+
+/* Utility Functions */
+static TelSimResult __atmodem_sim_decode_status_word(unsigned short status_word1,
+ unsigned short status_word2)
+{
+ TelSimResult rst = TEL_SIM_RESULT_FAILURE;
+
+ if (status_word1 == 0x93 && status_word2 == 0x00) {
+ /*Failed SIM request command*/
+ dbg("error - SIM application toolkit busy [%x][%x]",
+ status_word1, status_word2);
+ } else if (status_word1 == 0x94 && status_word2 == 0x00) {
+ /*Failed SIM request command*/
+ dbg("error - No EF Selected [%x][%x]", status_word1, status_word2);
+ } else if (status_word1 == 0x94 && status_word2 == 0x02) {
+ /*Failed SIM request command*/
+ dbg("error - Out of Range - Invalid address or record number[%x][%x]",
+ status_word1, status_word2);
+ } else if (status_word1 == 0x94 && status_word2 == 0x04) {
+ /*Failed SIM request command*/
+ dbg("error - File ID not found [%x][%x]",
+ status_word1, status_word2);
+ } else if (status_word1 == 0x94 && status_word2 == 0x08) {
+ /*Failed SIM request command*/
+ dbg("error - File is inconsistent with command - "\
+ "Modem not support or USE IPC [%x][%x]",
+ status_word1, status_word2);
+ } else if (status_word1 == 0x98 && status_word2 == 0x02) {
+ /*Failed SIM request command*/
+ dbg("error - CHV not initialized [%x][%x]",
+ status_word1, status_word2);
+ } else if (status_word1 == 0x98 && status_word2 == 0x04) {
+ /*Failed SIM request command*/
+ dbg("error - Access condition not fullfilled [%x][%x]",
+ status_word1, status_word2);
+ dbg("error -Unsuccessful CHV verification - "\
+ "at least one attempt left [%x][%x]",
+ status_word1, status_word2);
+ dbg("error - Unsuccessful Unblock CHV - at least one attempt left [%x][%x]",
+ status_word1, status_word2);
+ dbg("error - Authentication failure [%x][%x]",
+ status_word1, status_word2);
+ } else if (status_word1 == 0x98 && status_word2 == 0x08) {
+ /*Failed SIM request command*/
+ dbg("error - Contradiction with CHV status [%x][%x]",
+ status_word1, status_word2);
+ } else if (status_word1 == 0x98 && status_word2 == 0x10) {
+ /*Failed SIM request command*/
+ dbg("error - Contradiction with invalidation status [%x][%x]",
+ status_word1, status_word2);
+ } else if (status_word1 == 0x98 && status_word2 == 0x40) {
+ /*Failed SIM request command*/
+ dbg("error -Unsuccessful CHV verification - no attempt left [%x][%x]",
+ status_word1, status_word2);
+ dbg("error - Unsuccessful Unblock CHV - no attempt left [%x][%x]",
+ status_word1, status_word2);
+ dbg("error - CHV blocked [%x][%x]", status_word1, status_word2);
+ } else if (status_word1 == 0x67 && status_word2 == 0x00) {
+ dbg("error -Incorrect Parameter 3 [%x][%x]", status_word1, status_word2);
+ } else if (status_word1 == 0x6B && status_word2 == 0x00) {
+ dbg("error -Incorrect Parameter 1 or 2 [%x][%x]", status_word1, status_word2);
+ } else if (status_word1 == 0x6D && status_word2 == 0x00) {
+ dbg("error -Unknown instruction given as command [%x][%x]",
+ status_word1, status_word2);
+ } else if (status_word1 == 0x6E && status_word2 == 0x00) {
+ dbg("error -Unknown instruction given as command [%x][%x]",
+ status_word1, status_word2);
+ } else if (status_word1 == 0x69 && status_word2 == 0x82) {
+ dbg("error -Access denied [%x][%x]", status_word1, status_word2);
+ } else if (status_word1 == 0x6A && status_word2 == 0x87) {
+ dbg("error -Incorrect parameters [%x][%x]", status_word1, status_word2);
+ } else if (status_word1 == 0x6A && status_word2 == 0x82) {
+ dbg("error -File Not found [%x][%x]", status_word1, status_word2);
+ } else if (status_word1 == 0x6A && status_word2 == 0x83) {
+ dbg("error -Record Not found [%x][%x]", status_word1, status_word2);
+ } else {
+ rst = TEL_SIM_RESULT_CARD_ERROR;
+ dbg("error -Unknown state [%x][%x]", status_word1, status_word2);
+ }
+ return rst;
+}
+
+static void __atmodem_sim_update_sim_status(CoreObject *co_sim,
+ TelSimCardStatus sim_status)
+{
+ TelSimCardStatus curr_sim_status;
+
+ /*
+ * Send SIM Init status, if not sent already
+ */
+ (void)tcore_sim_get_status(co_sim, &curr_sim_status);
+ if (sim_status != curr_sim_status) {
+ TelSimCardStatusInfo sim_status_noti = {0, };
+
+ dbg("Change in SIM State - Old State: [0x%02x] --> New State: [0x%02x]",
+ curr_sim_status, sim_status);
+
+ /* Update SIM Status */
+ tcore_sim_set_status(co_sim, sim_status);
+ sim_status_noti.status = sim_status;
+ sim_status_noti.change_status = TEL_SIM_CHANGE_STATUS_SAME; /* TODO: checkout */
+
+ /* Send notification: SIM Status */
+ tcore_object_send_notification(co_sim,
+ TCORE_NOTIFICATION_SIM_STATUS,
+ sizeof(sim_status_noti), &sim_status_noti);
+ }
+}
+
+static gboolean __atmodem_convert_scpin_str_to_enum(char* line,
+ AtmodemSimSecLockType *lock_type, AtmodemSimSecLockKey *lock_key)
+{
+ char *type =NULL, *key = NULL;
+ GSList *tokens = NULL;
+
+ if(line == NULL)
+ return FALSE;
+
+ tokens = tcore_at_tok_new(line);
+
+ type = g_slist_nth_data(tokens, 0);
+ if (!type) {
+ err("Type is missing");
+ tcore_at_tok_free(tokens);
+ return FALSE;
+ }
+
+ if (g_strcmp0(type, "NO_LOCK") == 0) {
+ key = g_slist_nth_data(tokens, 1);
+ if (!key) {
+ err("Key is missing");
+ tcore_at_tok_free(tokens);
+ return FALSE;
+ }
+
+ dbg("type: [%s], key: [%s]", type, key);
+ }
+
+ if(g_str_has_prefix (type, "NO_SIM"))
+ *lock_type = SEC_LOCK_TYPE_NO_SIM;
+ else if(g_str_has_prefix (type, "UNAVAIL"))
+ *lock_type = SEC_LOCK_TYPE_UNAVAIL;
+ else if(g_str_has_prefix (type, "NO_LOCK"))
+ *lock_type = SEC_LOCK_TYPE_READY;
+ else if(g_str_has_prefix (type, "LOCK_PS"))
+ *lock_type = SEC_LOCK_TYPE_PS;
+ else if(g_str_has_prefix (type, "LOCK_PF"))
+ *lock_type = SEC_LOCK_TYPE_PF ;
+ else if(g_str_has_prefix (type, "LOCK_SC"))
+ *lock_type = SEC_LOCK_TYPE_SC;
+ else if(g_str_has_prefix (type, "LOCK_FD"))
+ *lock_type = SEC_LOCK_TYPE_FD;
+ else if(g_str_has_prefix (type, "LOCK_PN"))
+ *lock_type = SEC_LOCK_TYPE_PN ;
+ else if(g_str_has_prefix (type, "LOCK_PU"))
+ *lock_type = SEC_LOCK_TYPE_PU ;
+ else if(g_str_has_prefix (type, "LOCK_PP"))
+ *lock_type = SEC_LOCK_TYPE_PP;
+ else if(g_str_has_prefix (type, "LOCK_PC"))
+ *lock_type = SEC_LOCK_TYPE_PC;
+ else if(g_str_has_prefix (type, "LOCK_SC2"))
+ *lock_type = SEC_LOCK_TYPE_SC2 ;
+ else if(g_str_has_prefix (type, "LOCK_ACL"))
+ *lock_type = SEC_LOCK_TYPE_ACL;
+ else if(g_str_has_prefix (type, "LOCK_PUK2"))
+ *lock_type = SEC_LOCK_TYPE_PUK2;
+ else if(g_str_has_prefix (type, "INIT_COMP"))
+ *lock_type = SEC_SIM_INIT_COMPLETED;
+ else if(g_str_has_prefix (type, "INIT_ERROR"))
+ *lock_type = SEC_SIM_INIT_CRASH;
+ else
+ *lock_type = SEC_LOCK_TYPE_NONE;
+
+ if(g_str_has_prefix (key, "PIN"))
+ *lock_key = SEC_LOCK_KEY_PIN;
+ else if(g_str_has_prefix (key, "PUK"))
+ *lock_key = SEC_LOCK_KEY_PUK;
+ else if(g_str_has_prefix (key, "PIN2"))
+ *lock_key = SEC_LOCK_KEY_PIN2;
+ else if(g_str_has_prefix (key, "PUK2"))
+ *lock_key = SEC_LOCK_KEY_PUK2;
+ else if(g_str_has_prefix (key, "BLOCKED"))
+ *lock_key = SEC_LOCK_KEY_PERM_BLOCKED ;
+ else if(g_str_has_prefix (key, "UNLOCKED"))
+ *lock_key = SEC_LOCK_KEY_UNLOCKED ;
+ else if(g_str_has_prefix (key, "PIN2_DISABLE"))
+ *lock_key = SEC_LOCK_KEY_PIN2_DISABLE;
+ else
+ *lock_key = SEC_LOCK_KEY_NONE;
+
+ if(*lock_type == SEC_LOCK_TYPE_READY)
+ *lock_key = SEC_LOCK_KEY_UNLOCKED;
+
+ if((*lock_type == SEC_LOCK_TYPE_NO_SIM)||(*lock_type == SEC_LOCK_TYPE_UNAVAIL)||
+ (*lock_type == SEC_SIM_INIT_COMPLETED)||(*lock_type == SEC_SIM_INIT_CRASH))
+ *lock_key = SEC_LOCK_KEY_NONE;
+
+ dbg("type: [%d], key: [%d]", *lock_type, *lock_key);
+
+ tcore_at_tok_free(tokens);
+
+ return TRUE;
+}
+
+static void __on_response_atmodem_sim_get_sim_type_internal(CoreObject *co_sim,
+ gint result, const void *response, void *user_data)
+{
+ dbg("SIM Response - SIM Type (internal): [\%SCCT]");
+
+ /* Get SIM type if SIM is initialized */
+ if (result == TEL_SIM_RESULT_SUCCESS) {
+ TelSimCardType *sim_type = (TelSimCardType *)response;
+
+ /* Update SIM type */
+ tcore_sim_set_type(co_sim, *sim_type);
+ if (*sim_type != TEL_SIM_CARD_TYPE_UNKNOWN) {
+ /* Send SIM Type notification */
+ tcore_object_send_notification(co_sim,
+ TCORE_NOTIFICATION_SIM_TYPE,
+ sizeof(TelSimCardType), sim_type);
+ }
+ }
+}
+
+static void __on_response_atmodem_sim_get_sim_type(TcorePending *p,
+ guint data_len, const void *data, void *user_data)
+{
+ const TcoreAtResponse *at_resp = data;
+ CoreObject *co_sim = tcore_pending_ref_core_object(p);
+ AtmodemRespCbData *resp_cb_data = user_data;
+ TelSimCardType sim_type = TEL_SIM_CARD_TYPE_UNKNOWN;
+
+ TelSimResult result = TEL_SIM_RESULT_FAILURE;
+
+ dbg("SIM Response - SIM Type: [\%SCCT]");
+
+ tcore_check_return_assert(co_sim != NULL);
+ tcore_check_return_assert(resp_cb_data != NULL);
+
+ if (at_resp && at_resp->success) {
+ if (at_resp->lines) {
+ const gchar *line;
+ GSList *tokens;
+
+ line = (const gchar *)at_resp->lines->data;
+
+ /*
+ * Tokenize
+ *
+ * %SCCT: <state>
+ */
+ tokens = tcore_at_tok_new(line);
+
+ /* <state> */
+ if (g_slist_length(tokens) == 1) {
+ sim_type = atoi(g_slist_nth_data(tokens, 0));
+ dbg("SIM Type: [%d]", sim_type);
+
+ result = TEL_SIM_RESULT_SUCCESS;
+ }
+ else {
+ err("Invalid message");
+ }
+
+ tcore_at_tok_free(tokens);
+ }
+ }
+
+ /* Invoke callback */
+ if (resp_cb_data->cb)
+ resp_cb_data->cb(co_sim, (gint)result, &sim_type, resp_cb_data->cb_data);
+
+ /* Free callback data */
+ atmodem_destroy_resp_cb_data(resp_cb_data);
+}
+
+/*
+ * Operation - get_sim_type
+ *
+ * Request -
+ * AT-Command: AT%SCCT?
+ *
+ * Response - sim_type (TelSimCardType)
+ * Success: (Single line) -
+ * +SCCT: <state>
+ * OK
+ * Failure:
+ * +CME ERROR: <error>
+ */
+static void __atmodem_sim_get_sim_type(CoreObject *co_sim,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ AtmodemRespCbData *resp_cb_data;
+ TelReturn ret;
+
+ /* Response callback data */
+ resp_cb_data = atmodem_create_resp_cb_data(cb, cb_data,
+ NULL, 0);
+
+ /* Send Request to modem */
+ ret = tcore_at_prepare_and_send_request(co_sim,
+ "AT\%SCCT?", "\%SCCT:",
+ TCORE_AT_COMMAND_TYPE_SINGLELINE,
+ TCORE_PENDING_PRIORITY_DEFAULT,
+ NULL,
+ __on_response_atmodem_sim_get_sim_type, resp_cb_data,
+ on_send_atmodem_request, NULL,
+ 0, NULL, NULL);
+ ATMODEM_CHECK_REQUEST_RET(ret, resp_cb_data, "Get SIM Type");
+
+ dbg("ret: [%d]", ret);
+}
+
+static void __atmodem_sim_process_sim_status(CoreObject *co,
+ TelSimCardStatus sim_card_status)
+{
+ switch (sim_card_status) {
+ case TEL_SIM_STATUS_SIM_INIT_COMPLETED: {
+ TelReturn ret;
+
+ dbg("SIM INIT COMPLETED");
+
+ ATMODEM_SIM_READ_FILE(co, NULL, NULL, TEL_SIM_EF_IMSI, ret);
+ dbg("ret: [%d]", ret);
+
+ return;
+ }
+
+ case TEL_SIM_STATUS_SIM_INITIALIZING: {
+ TelSimCardType sim_type;
+
+ dbg("SIM INITIALIZING");
+
+ (void)tcore_sim_get_type(co, &sim_type);
+ if (sim_type == TEL_SIM_CARD_TYPE_UNKNOWN) {
+ /*
+ * SIM is initialized for first time, need to
+ * fetch SIM type
+ */
+ __atmodem_sim_get_sim_type(co,
+ __on_response_atmodem_sim_get_sim_type_internal, NULL);
+
+ return;
+ }
+ }
+ break;
+
+ case TEL_SIM_STATUS_CARD_REMOVED:
+ dbg("SIM CARD REMOVED");
+ tcore_sim_set_type(co, TEL_SIM_CARD_TYPE_UNKNOWN);
+ break;
+
+ case TEL_SIM_STATUS_CARD_NOT_PRESENT:
+ dbg("SIM CARD NOT PRESENT");
+ tcore_sim_set_type(co, TEL_SIM_CARD_TYPE_UNKNOWN);
+ break;
+
+ case TEL_SIM_STATUS_CARD_ERROR:
+ dbg("SIM CARD ERROR");
+ tcore_sim_set_type(co, TEL_SIM_CARD_TYPE_UNKNOWN);
+ break;
+
+ default:
+ err("SIM Status: [0x%02x]", sim_card_status);
+ break;
+ }
+
+ /* Update SIM Status */
+ return __atmodem_sim_update_sim_status(co, sim_card_status);
+}
+
+static void __atmodem_sim_next_from_get_file_data(CoreObject *co_sim,
+ AtmodemRespCbData *resp_cb_data,
+ TelSimResult sim_result, gboolean decode_ret)
+{
+ AtmodemSimMetaInfo *file_meta =
+ (AtmodemSimMetaInfo *)ATMODEM_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
+ TelSimCardType card_type = TEL_SIM_CARD_TYPE_UNKNOWN;
+
+ dbg("Entry");
+
+ dbg("[SIM]EF[0x%x] read sim_result[%d] Decode rt[%d]",
+ file_meta->file_id, sim_result, decode_ret);
+ switch (file_meta->file_id) {
+ case TEL_SIM_EF_ELP:
+ case TEL_SIM_EF_USIM_PL:
+ case TEL_SIM_EF_LP:
+ case TEL_SIM_EF_USIM_LI:
+ if (decode_ret == TRUE) {
+ if (resp_cb_data->cb)
+ resp_cb_data->cb(co_sim, (gint)sim_result,
+ &file_meta->files.data, resp_cb_data->cb_data);
+ } else {
+ tcore_sim_get_type(co_sim, &card_type);
+ /* 2G */
+ /*
+ * The ME requests the Extended Language Preference.
+ * The ME only requests the Language Preference (EFLP) if at
+ * least one of the following conditions holds:
+ * - EFELP is not available;
+ * - EFELP does not contain an entry corresponding to a
+ * language specified in ISO 639[30];
+ * - the ME does not support any of the languages in EFELP.
+ */
+ /* 3G */
+ /*
+ * The ME only requests the Language Preference (EFPL)
+ * if at least one of the following conditions holds:
+ * - if the EFLI has the value 'FFFF' in its highest
+ * priority position
+ * - if the ME does not support any of the language codes
+ * indicated in EFLI , or if EFLI is not present
+ */
+ if (TEL_SIM_CARD_TYPE_GSM == card_type) {
+ if (file_meta->file_id == TEL_SIM_EF_LP) {
+ if (resp_cb_data->cb)
+ resp_cb_data->cb(co_sim, (gint)sim_result,
+ &file_meta->files.data, resp_cb_data->cb_data);
+ } else {
+ file_meta->file_id = TEL_SIM_EF_LP;
+ __atmodem_sim_get_file_info(co_sim, resp_cb_data);
+ }
+ } else if (TEL_SIM_CARD_TYPE_USIM) {
+ if (file_meta->file_id == TEL_SIM_EF_LP
+ || file_meta->file_id == TEL_SIM_EF_USIM_LI) {
+ file_meta->file_id = TEL_SIM_EF_ELP;
+ __atmodem_sim_get_file_info(co_sim, resp_cb_data);
+ } else {
+ if (resp_cb_data->cb)
+ resp_cb_data->cb(co_sim, (gint)sim_result,
+ &file_meta->files.data, resp_cb_data->cb_data);
+ }
+ }
+ }
+ break;
+
+ case TEL_SIM_EF_ECC:
+ tcore_sim_get_type(co_sim, &card_type);
+ if (TEL_SIM_CARD_TYPE_USIM == card_type) {
+ if (file_meta->current_index == file_meta->rec_count) {
+ if (resp_cb_data->cb)
+ resp_cb_data->cb(co_sim, (gint)sim_result,
+ &file_meta->files.data, resp_cb_data->cb_data);
+ } else {
+ file_meta->current_index++;
+ __atmodem_sim_get_file_record(co_sim, resp_cb_data);
+ }
+ } else if (TEL_SIM_CARD_TYPE_GSM == card_type) {
+ if (resp_cb_data->cb)
+ resp_cb_data->cb(co_sim, (gint)sim_result,
+ &file_meta->files.data, resp_cb_data->cb_data);
+ } else {
+ dbg("[SIM DATA] Invalid CardType: [%d]. Unable to handle", card_type);
+ }
+ break;
+
+ case TEL_SIM_EF_IMSI:
+ if (resp_cb_data->cb) {
+ resp_cb_data->cb(co_sim, (gint)sim_result,
+ &file_meta->files.data, resp_cb_data->cb_data);
+ } else {
+ /* Update Status */
+ __atmodem_sim_update_sim_status(co_sim, TEL_SIM_STATUS_SIM_INIT_COMPLETED);
+ }
+ break;
+
+ case TEL_SIM_EF_MSISDN:
+ if (file_meta->current_index == file_meta->rec_count) {
+ if (resp_cb_data->cb)
+ resp_cb_data->cb(co_sim, (gint)sim_result,
+ &file_meta->files.data, resp_cb_data->cb_data);
+ } else {
+ file_meta->current_index++;
+ __atmodem_sim_get_file_record(co_sim, resp_cb_data);
+ }
+ break;
+
+ case TEL_SIM_EF_OPL:
+ if (file_meta->current_index == file_meta->rec_count) {
+ if (resp_cb_data->cb)
+ resp_cb_data->cb(co_sim, (gint)sim_result,
+ &file_meta->files.data, resp_cb_data->cb_data);
+ } else {
+ file_meta->current_index++;
+ __atmodem_sim_get_file_record(co_sim, resp_cb_data);
+ }
+ break;
+
+ case TEL_SIM_EF_PNN:
+ if (file_meta->current_index == file_meta->rec_count) {
+ if (resp_cb_data->cb)
+ resp_cb_data->cb(co_sim, (gint)sim_result,
+ &file_meta->files.data, resp_cb_data->cb_data);
+ } else {
+ file_meta->current_index++;
+ __atmodem_sim_get_file_record(co_sim, resp_cb_data);
+ }
+ break;
+
+ case TEL_SIM_EF_USIM_CFIS:
+ case TEL_SIM_EF_USIM_MWIS:
+ case TEL_SIM_EF_USIM_MBI:
+ case TEL_SIM_EF_MBDN:
+ case TEL_SIM_EF_CPHS_MAILBOX_NUMBERS:
+ case TEL_SIM_EF_CPHS_INFORMATION_NUMBERS:
+ if (file_meta->current_index == file_meta->rec_count) {
+ if (resp_cb_data->cb)
+ resp_cb_data->cb(co_sim, (gint)sim_result,
+ &file_meta->files.data, resp_cb_data->cb_data);
+ } else {
+ file_meta->current_index++;
+ __atmodem_sim_get_file_record(co_sim, resp_cb_data);
+ }
+ break;
+
+ case TEL_SIM_EF_CPHS_OPERATOR_NAME_STRING:
+ {
+ file_meta->files.result = sim_result;
+ if (decode_ret == TRUE && sim_result == TEL_SIM_RESULT_SUCCESS) {
+ memcpy(file_meta->files.data.cphs_net.full_name, file_meta->files.data.cphs_net.full_name, strlen((char *)file_meta->files.data.cphs_net.full_name));
+ }
+
+ file_meta->file_id = TEL_SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING;
+ file_meta->file_result = TEL_SIM_RESULT_FAILURE;
+ file_meta->req_command = TCORE_COMMAND_SIM_GET_CPHS_NET_NAME;
+
+ __atmodem_sim_get_file_info(co_sim, resp_cb_data);
+ }
+ break;
+
+ case TEL_SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING:
+ if (file_meta->files.result == TEL_SIM_RESULT_SUCCESS)
+ file_meta->files.result = TEL_SIM_RESULT_SUCCESS;
+
+ if (strlen((char *)file_meta->files.data.cphs_net.full_name))
+ memcpy(&file_meta->files.data.cphs_net.full_name,
+ &file_meta->files.data.cphs_net.full_name,
+ strlen((char *)file_meta->files.data.cphs_net.full_name));
+
+ if (resp_cb_data->cb)
+ resp_cb_data->cb(co_sim, (gint)sim_result,
+ &file_meta->files.data, resp_cb_data->cb_data);
+ break;
+
+ case TEL_SIM_EF_ICCID:
+ case TEL_SIM_EF_SST:
+ case TEL_SIM_EF_SPN:
+ case TEL_SIM_EF_SPDI:
+ case TEL_SIM_EF_OPLMN_ACT:
+ case TEL_SIM_EF_CPHS_CPHS_INFO:
+ case TEL_SIM_EF_CPHS_CALL_FORWARD_FLAGS:
+ case TEL_SIM_EF_CPHS_VOICE_MSG_WAITING:
+ case TEL_SIM_EF_CPHS_DYNAMICFLAGS:
+ case TEL_SIM_EF_CPHS_DYNAMIC2FLAG:
+ case TEL_SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE:
+ case TEL_SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE_LINE2:
+ if (resp_cb_data->cb)
+ resp_cb_data->cb(co_sim, (gint)sim_result,
+ &file_meta->files.data, resp_cb_data->cb_data);
+ break;
+
+ default:
+ err("File id not handled [0x%x]", file_meta->file_id);
+ break;
+ }
+}
+
+static void __atmodem_sim_next_from_get_file_info(CoreObject *co_sim,
+ AtmodemRespCbData *resp_cb_data, TelSimResult sim_result)
+{
+ AtmodemSimMetaInfo *file_meta =
+ (AtmodemSimMetaInfo *)ATMODEM_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
+ TelSimCardType card_type = TEL_SIM_CARD_TYPE_UNKNOWN;
+
+ dbg("EF[0x%x] access Result[%d]", file_meta->file_id, sim_result);
+
+ file_meta->files.result = sim_result;
+ memset(&file_meta->files.data, 0x00, sizeof(file_meta->files.data));
+
+ if ((file_meta->file_id != TEL_SIM_EF_ELP
+ && file_meta->file_id != TEL_SIM_EF_LP
+ && file_meta->file_id != TEL_SIM_EF_USIM_PL
+ && file_meta->file_id != TEL_SIM_EF_CPHS_CPHS_INFO)
+ && (sim_result != TEL_SIM_RESULT_SUCCESS)) {
+ if (resp_cb_data->cb)
+ resp_cb_data->cb(co_sim, (gint)sim_result,
+ &file_meta->files.data, resp_cb_data->cb_data);
+
+ return;
+ }
+
+ switch (file_meta->file_id) {
+ case TEL_SIM_EF_ELP:
+ if (sim_result == TEL_SIM_RESULT_SUCCESS) {
+ dbg("[SIM DATA] exist EFELP/PL(0x2F05)");
+ __atmodem_sim_get_file_data(co_sim, resp_cb_data);
+ } else {
+ tcore_sim_get_type(co_sim, &card_type);
+ if (TEL_SIM_CARD_TYPE_GSM == card_type) {
+ AtmodemSimMetaInfo file_meta_new = {0,};
+
+ dbg("[SIM DATA]SIM_EF_ELP(2F05) access fail. Request SIM_EF_LP(0x6F05) info");
+ /* The ME requests the Language Preference (EFLP) if EFELP is not available */
+ file_meta_new.file_id = TEL_SIM_EF_LP;
+ file_meta_new.file_result = TEL_SIM_RESULT_FAILURE;
+ file_meta_new.req_command = TCORE_COMMAND_SIM_GET_LANGUAGE;
+
+ memcpy(resp_cb_data->data, &file_meta_new, sizeof(AtmodemSimMetaInfo));
+
+ __atmodem_sim_get_file_info(co_sim, resp_cb_data);
+ } else if (TEL_SIM_CARD_TYPE_USIM == card_type) {
+ dbg(" [SIM DATA]fail to get Language information in USIM(EF-LI(6F05),EF-PL(2F05))");
+ if (resp_cb_data->cb)
+ resp_cb_data->cb(co_sim, (gint)sim_result,
+ &file_meta->files.data, resp_cb_data->cb_data);
+
+ return;
+ }
+ }
+ break;
+
+ case TEL_SIM_EF_LP:
+ if (sim_result == TEL_SIM_RESULT_SUCCESS) {
+ dbg("[SIM DATA] exist EFLP/LI(0x6F05)");
+ __atmodem_sim_get_file_data(co_sim, resp_cb_data);
+ } else {
+ tcore_sim_get_type(co_sim, &card_type);
+ dbg("[SIM DATA]SIM_EF_LP/LI(6F05) access fail. Current CardType[%d]", card_type);
+ if (TEL_SIM_CARD_TYPE_GSM == card_type) {
+ if (resp_cb_data->cb)
+ resp_cb_data->cb(co_sim, (gint)sim_result,
+ &file_meta->files.data, resp_cb_data->cb_data);
+ return;
+ }
+
+ /*
+ * If EFLI is not present, then the language selection
+ * shall be as defined in EFPL at the MF level
+ */
+ else if (TEL_SIM_CARD_TYPE_USIM == card_type) {
+ AtmodemSimMetaInfo file_meta_new = {0,};
+
+ dbg("[SIM DATA] try USIM EFPL(0x2F05)");
+ file_meta_new.file_id = TEL_SIM_EF_ELP;
+ file_meta_new.file_result = TEL_SIM_RESULT_FAILURE;
+ file_meta_new.req_command = TCORE_COMMAND_SIM_GET_LANGUAGE;
+
+ memcpy(resp_cb_data->data, &file_meta_new, sizeof(AtmodemSimMetaInfo));
+
+ __atmodem_sim_get_file_info(co_sim, resp_cb_data);
+ }
+ }
+ break;
+
+ case TEL_SIM_EF_USIM_PL:
+ if (sim_result == TEL_SIM_RESULT_SUCCESS) {
+ dbg("[SIM DATA] exist EFELP/PL(0x2F05)");
+ __atmodem_sim_get_file_data(co_sim, resp_cb_data);
+ } else {
+ /*
+ * EFELIand EFPL not present, so set language
+ * count as zero and select ECC
+ */
+ dbg("[SIM DATA] SIM_EF_USIM_PL(2A05) access fail. "\
+ "Request SIM_EF_ECC(0x6FB7) info");
+ if (resp_cb_data->cb)
+ resp_cb_data->cb(co_sim, (gint)sim_result,
+ &file_meta->files.data, resp_cb_data->cb_data);
+
+ return;
+ }
+ break;
+
+ case TEL_SIM_EF_ECC:
+ tcore_sim_get_type(co_sim, &card_type);
+ if (TEL_SIM_CARD_TYPE_GSM == card_type) {
+ __atmodem_sim_get_file_data(co_sim, resp_cb_data);
+ } else if (TEL_SIM_CARD_TYPE_USIM == card_type) {
+ if (file_meta->rec_count > TEL_SIM_ECC_LIST_MAX)
+ file_meta->rec_count = TEL_SIM_ECC_LIST_MAX;
+
+ file_meta->current_index++;
+ __atmodem_sim_get_file_record(co_sim, resp_cb_data);
+ }
+ break;
+
+ case TEL_SIM_EF_ICCID:
+ case TEL_SIM_EF_IMSI:
+ case TEL_SIM_EF_SST:
+ case TEL_SIM_EF_SPN:
+ case TEL_SIM_EF_SPDI:
+ case TEL_SIM_EF_CPHS_CALL_FORWARD_FLAGS:
+ case TEL_SIM_EF_CPHS_VOICE_MSG_WAITING:
+ case TEL_SIM_EF_CPHS_OPERATOR_NAME_STRING:
+ case TEL_SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING:
+ case TEL_SIM_EF_CPHS_DYNAMICFLAGS:
+ case TEL_SIM_EF_CPHS_DYNAMIC2FLAG:
+ case TEL_SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE:
+ case TEL_SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE_LINE2:
+ __atmodem_sim_get_file_data(co_sim, resp_cb_data);
+ break;
+
+ case TEL_SIM_EF_CPHS_CPHS_INFO:
+ if (sim_result == TEL_SIM_RESULT_SUCCESS) {
+ tcore_sim_set_cphs_status(co_sim, TRUE);
+ __atmodem_sim_update_sim_status(co_sim, TEL_SIM_STATUS_SIM_INIT_COMPLETED);
+
+ __atmodem_sim_get_file_data(co_sim, resp_cb_data);
+ } else {
+ tcore_sim_set_cphs_status(co_sim, FALSE);
+ __atmodem_sim_update_sim_status(co_sim, TEL_SIM_STATUS_SIM_INIT_COMPLETED);
+
+ if (resp_cb_data->cb)
+ resp_cb_data->cb(co_sim, (gint)sim_result,
+ &file_meta->files.data, resp_cb_data->cb_data);
+ }
+ break;
+
+
+ case TEL_SIM_EF_USIM_CFIS:
+ if (file_meta->rec_count > TEL_SIM_CALL_FORWARDING_TYPE_MAX)
+ file_meta->rec_count = TEL_SIM_CALL_FORWARDING_TYPE_MAX;
+
+ file_meta->current_index++;
+
+ __atmodem_sim_get_file_record(co_sim, resp_cb_data);
+ break;
+
+ case TEL_SIM_EF_OPL:
+ case TEL_SIM_EF_PNN:
+ case TEL_SIM_EF_USIM_MWIS:
+ case TEL_SIM_EF_USIM_MBI:
+ case TEL_SIM_EF_MBDN:
+ case TEL_SIM_EF_CPHS_MAILBOX_NUMBERS:
+ case TEL_SIM_EF_CPHS_INFORMATION_NUMBERS:
+ case TEL_SIM_EF_MSISDN:
+ file_meta->current_index++;
+
+ __atmodem_sim_get_file_record(co_sim, resp_cb_data);
+ break;
+
+ default:
+ err("Unknown File ID for get File info: [0x%x]", file_meta->file_id);
+ break;
+ }
+}
+
+static void __on_response_atmodem_sim_get_file_data(TcorePending *p,
+ guint data_len, const void *data, void *user_data)
+{
+ const TcoreAtResponse *resp = data;
+ CoreObject *co_sim = NULL;
+ GSList *tokens = NULL;
+ TelSimResult sim_result;
+ gboolean dr = FALSE;
+ const char *line = NULL;
+ char *res = NULL;
+ char *tmp = NULL;
+ int res_len;
+ int sw1 = 0;
+ int sw2 = 0;
+ TelSimCardType card_type = TEL_SIM_CARD_TYPE_UNKNOWN;
+ AtmodemRespCbData *resp_cb_data = (AtmodemRespCbData *) user_data;
+ AtmodemSimMetaInfo *file_meta =
+ (AtmodemSimMetaInfo *)ATMODEM_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
+
+ dbg("Entry");
+
+ co_sim = tcore_pending_ref_core_object(p);
+
+ if (resp->success > 0) {
+ dbg("RESPONSE OK");
+ if (resp->lines) {
+ line = (const char *)resp->lines->data;
+ tokens = tcore_at_tok_new(line);
+ if (g_slist_length(tokens) != 2) {
+ msg("Invalid message");
+ tcore_at_tok_free(tokens);
+ return;
+ }
+ }
+ sw1 = atoi(g_slist_nth_data(tokens, 0));
+ sw2 = atoi(g_slist_nth_data(tokens, 1));
+ res = g_slist_nth_data(tokens, 2);
+
+ tmp = tcore_at_tok_extract(res);
+ tcore_util_hexstring_to_bytes(tmp, &res, (guint *)&res_len);
+
+ dbg("Response: [%s] Response length: [%d]", res, res_len);
+
+ if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
+ sim_result = TEL_SIM_RESULT_SUCCESS;
+ file_meta->files.result = sim_result;
+
+ dbg("File ID: [0x%x]", file_meta->file_id);
+ switch (file_meta->file_id) {
+ case TEL_SIM_EF_IMSI: {
+ dbg("Data: [%s]", res);
+#if 0
+ dr = tcore_sim_decode_imsi((unsigned char *)res, res_len,
+ &file_meta->files.data.imsi);
+ if (dr == FALSE) {
+ err("IMSI decoding failed");
+ } else {
+ /* TBD */
+ tcore_sim_set_imsi(co_sim, &file_meta->files.data.imsi);
+ }
+#endif
+ }
+ break;
+
+ case TEL_SIM_EF_ICCID:
+ dr = tcore_sim_decode_iccid((unsigned char *)res, res_len,
+ file_meta->files.data.iccid);
+ break;
+
+ case TEL_SIM_EF_ELP: /* 2G EF - 2 bytes decoding */
+ case TEL_SIM_EF_USIM_LI: /* 3G EF - 2 bytes decoding */
+ case TEL_SIM_EF_USIM_PL: /* 3G EF - same as EFELP, so 2 byte decoding */
+ case TEL_SIM_EF_LP: /* 1 byte encoding */
+ {
+ tcore_sim_get_type(co_sim, &card_type);
+ if ((TEL_SIM_CARD_TYPE_GSM == card_type)
+ && (file_meta->file_id == TEL_SIM_EF_LP)) {
+ /*
+ * 2G LP(0x6F05) has 1 byte for each language
+ */
+ dr = tcore_sim_decode_lp((unsigned char *)res, res_len,
+ &file_meta->files.data.language);
+ } else {
+ /*
+ * 3G LI(0x6F05)/PL(0x2F05),
+ * 2G ELP(0x2F05) has 2 bytes for each language
+ */
+ dr = tcore_sim_decode_li((unsigned char *)res, res_len,
+ file_meta->file_id, &file_meta->files.data.language);
+ }
+ }
+ break;
+
+ case TEL_SIM_EF_SPN:
+ dr = tcore_sim_decode_spn((unsigned char *)res, res_len,
+ &file_meta->files.data.spn);
+ break;
+
+ case TEL_SIM_EF_SPDI:
+ dr = tcore_sim_decode_spdi((unsigned char *)res, res_len,
+ &file_meta->files.data.spdi);
+ break;
+
+ case TEL_SIM_EF_SST: {
+ TelSimServiceTable *svct = NULL;
+
+ svct = g_try_new0(TelSimServiceTable, 1);
+ tcore_sim_get_type(co_sim, &card_type);
+ svct->sim_type = card_type;
+ if (TEL_SIM_CARD_TYPE_GSM == card_type) {
+ dr = tcore_sim_decode_sst((unsigned char *)res, res_len,
+ svct->table.sst_service);
+ } else if (TEL_SIM_CARD_TYPE_USIM == card_type) {
+ dr = tcore_sim_decode_ust((unsigned char *)res, res_len,
+ svct->table.ust_service);
+ } else {
+ err("Not handled card_type[%d]", card_type);
+ }
+
+ if (dr == FALSE) {
+ err("SST/UST decoding failed");
+ } else {
+ tcore_sim_set_service_table(co_sim, svct);
+ }
+
+ /* Free memory */
+ g_free(svct);
+ }
+ break;
+
+ case TEL_SIM_EF_ECC: {
+ tcore_sim_get_type(co_sim, &card_type);
+ if (TEL_SIM_CARD_TYPE_GSM == card_type) {
+ dr = tcore_sim_decode_ecc((unsigned char *)res, res_len,
+ &file_meta->files.data.ecc);
+ } else if (TEL_SIM_CARD_TYPE_USIM == card_type) {
+ TelSimEcc *ecc = NULL;
+
+ ecc = g_try_new0(TelSimEcc, 1);
+ dbg("Index [%d]", file_meta->current_index);
+
+ dr = tcore_sim_decode_uecc((unsigned char *)res, res_len, ecc);
+ if (dr == TRUE) {
+ memcpy(&file_meta->files.data.ecc.list[file_meta->files.data.ecc.count],
+ ecc, sizeof(TelSimEcc));
+ file_meta->files.data.ecc.count++;
+ }
+
+ /* Free memory */
+ g_free(ecc);
+ } else {
+ dbg("Unknown/Unsupported SIM card Type: [%d]", card_type);
+ }
+ }
+ break;
+
+ case TEL_SIM_EF_MSISDN: {
+ TelSimSubscriberInfo *msisdn = NULL;
+
+ dbg("Index [%d]", file_meta->current_index);
+ msisdn = g_try_new0(TelSimSubscriberInfo, 1);
+ dr = tcore_sim_decode_msisdn((unsigned char *)res, res_len, msisdn);
+ if (dr == TRUE) {
+ memcpy(&file_meta->files.data.msisdn_list.list[file_meta->files.data.msisdn_list.count],
+ msisdn, sizeof(TelSimSubscriberInfo));
+
+ file_meta->files.data.msisdn_list.count++;
+ }
+
+ /* Free memory */
+ g_free(msisdn);
+ }
+ break;
+
+ case TEL_SIM_EF_OPL: {
+ TelSimOpl *opl = NULL;
+
+ dbg("decode w/ index [%d]", file_meta->current_index);
+ opl = g_try_new0(TelSimOpl, 1);
+
+ dr = tcore_sim_decode_opl((unsigned char *)res, res_len, opl);
+ if (dr == TRUE) {
+ memcpy(&file_meta->files.data.opl.list[file_meta->files.data.opl.opl_count],
+ opl, sizeof(TelSimOpl));
+
+ file_meta->files.data.opl.opl_count++;
+ }
+
+ /* Free memory */
+ g_free(opl);
+ }
+ break;
+
+ case TEL_SIM_EF_PNN: {
+ TelSimPnn *pnn = NULL;
+
+ dbg("decode w/ index [%d]", file_meta->current_index);
+ pnn = g_try_new0(TelSimPnn, 1);
+
+ dr = tcore_sim_decode_pnn((unsigned char *)res, res_len, pnn);
+ if (dr == TRUE) {
+ memcpy(&file_meta->files.data.pnn.list[file_meta->files.data.pnn.pnn_count],
+ pnn, sizeof(TelSimPnn));
+
+ file_meta->files.data.pnn.pnn_count++;
+ }
+
+ /* Free memory */
+ g_free(pnn);
+ }
+ break;
+
+ case TEL_SIM_EF_OPLMN_ACT:
+ /*dr = tcore_sim_decode_oplmnwact(&file_meta->files.data.opwa,
+ (unsigned char *)res, res_len);*/
+ break;
+
+ case TEL_SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE:
+ /*dr = tcore_sim_decode_csp(&po->p_cphs->csp,
+ p_data->response, p_data->response_len);*/
+ break;
+
+ case TEL_SIM_EF_USIM_MBI: { /* linear type */
+ TelSimMbi *mbi = NULL;
+
+ mbi = g_try_new0(TelSimMbi, 1);
+ dr = tcore_sim_decode_mbi((unsigned char *)res, res_len, mbi);
+ if (dr == TRUE) {
+ memcpy(&file_meta->mbi_list.list[file_meta->mbi_list.count],
+ mbi, sizeof(TelSimMbi));
+ file_meta->mbi_list.count++;
+
+ dbg("mbi count[%d]", file_meta->mbi_list.count);
+ }
+
+ /* Free memory */
+ g_free(mbi);
+ }
+ break;
+
+ case TEL_SIM_EF_CPHS_MAILBOX_NUMBERS: /* linear type */
+ case TEL_SIM_EF_MBDN: /* linear type */
+ dr = tcore_sim_decode_xdn((unsigned char *)res, res_len,
+ file_meta->mb_list[file_meta->current_index-1].alpha_id,
+ file_meta->mb_list[file_meta->current_index-1].number);
+
+ file_meta->mb_list[file_meta->current_index-1].alpha_id_len =
+ strlen(file_meta->mb_list[file_meta->current_index-1].alpha_id);
+
+ file_meta->mb_list[file_meta->current_index-1].profile_id =
+ file_meta->current_index;
+ break;
+
+ case TEL_SIM_EF_CPHS_VOICE_MSG_WAITING: /* transparent type */
+ dr = tcore_sim_decode_vmwf((unsigned char *)res, res_len,
+ file_meta->files.data.mw.mw);
+ break;
+
+ case TEL_SIM_EF_USIM_MWIS: { /* linear type */
+ TelSimMwis *mw = NULL;
+
+ mw = g_try_new0(TelSimMwis, 1);
+
+ dr = tcore_sim_decode_mwis((unsigned char *)res, res_len, mw);
+ if (dr == TRUE) {
+ memcpy(&file_meta->files.data.mw.mw[file_meta->files.data.mw.profile_count],
+ mw, sizeof(TelSimMwis));
+
+ file_meta->files.data.mw.profile_count++;
+ }
+
+ /* Free memory */
+ g_free(mw);
+ }
+ break;
+
+ case TEL_SIM_EF_CPHS_CALL_FORWARD_FLAGS: /* transparent type */
+ dr = tcore_sim_decode_cff((unsigned char *)res, res_len,
+ file_meta->files.data.mw.mw);
+ break;
+
+ case TEL_SIM_EF_USIM_CFIS: /* linear type */
+ {
+ TelSimCfis *cf = NULL;
+
+ cf = g_try_new0(TelSimCfis, 1);
+ dr = tcore_sim_decode_cfis((unsigned char *)res, res_len, cf);
+ if (dr == TRUE) {
+ memcpy(&file_meta->files.data.cf.cf[file_meta->files.data.cf.profile_count],
+ cf, sizeof(TelSimCfis));
+
+ file_meta->files.data.cf.profile_count++;
+ }
+
+ /* Free memory */
+ g_free(cf);
+ }
+ break;
+
+ case TEL_SIM_EF_CPHS_SERVICE_STRING_TABLE:
+ dbg("not handled - TEL_SIM_EF_CPHS_SERVICE_STRING_TABLE ");
+ break;
+
+ case TEL_SIM_EF_CPHS_OPERATOR_NAME_STRING:
+ dr = tcore_sim_decode_ons((unsigned char *)res, res_len,
+ (unsigned char*)&file_meta->files.data.cphs_net.full_name);
+ dbg("file_meta->files.result: [%d] " \
+ "file_meta->files.data.cphs_net.full_name[%s]",
+ file_meta->files.result,
+ file_meta->files.data.cphs_net.full_name);
+ break;
+
+ case TEL_SIM_EF_CPHS_DYNAMICFLAGS:
+ /*dr = tcore_sim_decode_dynamic_flag(&po->p_cphs->dflagsinfo,
+ p_data->response, p_data->response_len);*/
+ break;
+
+ case TEL_SIM_EF_CPHS_DYNAMIC2FLAG:
+ /*dr = tcore_sim_decode_dynamic2_flag(&po->p_cphs->d2flagsinfo,
+ p_data->response, p_data->response_len);*/
+ break;
+
+ case TEL_SIM_EF_CPHS_CPHS_INFO:
+ /*dr = tcore_sim_decode_cphs_info(&file_meta->files.data.cphs,
+ (unsigned char *)res, res_len);*/
+ break;
+
+ case TEL_SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING:
+ dr = tcore_sim_decode_short_ons((unsigned char *)res, res_len,
+ (unsigned char*)&file_meta->files.data.cphs_net.short_name);
+
+ dbg("file_meta->files.result[%d] "\
+ "file_meta->files.data.cphs_net.short_name[%s]",
+ file_meta->files.result,
+ file_meta->files.data.cphs_net.short_name);
+ break;
+
+ case TEL_SIM_EF_CPHS_INFORMATION_NUMBERS:
+ /*dr = tcore_sim_decode_information_number(&po->p_cphs->infn,
+ p_data->response, p_data->response_len);*/
+ break;
+
+ default:
+ dbg("File Decoding Failed - not handled File[0x%x]",
+ file_meta->file_id);
+ dr = 0;
+ break;
+ }
+ } else {
+ sim_result = __atmodem_sim_decode_status_word(sw1, sw2);
+ file_meta->files.result = sim_result;
+ }
+
+ /* Free memory */
+ g_free(tmp);
+ g_free(res);
+
+ /* Free tokens */
+ tcore_at_tok_free(tokens);
+ } else {
+ dbg("RESPONSE NOK");
+ dbg("Error - File ID: [0x%x]", file_meta->file_id);
+ sim_result = TEL_SIM_RESULT_FAILURE;
+ }
+
+ /* Get File data */
+ __atmodem_sim_next_from_get_file_data(tcore_pending_ref_core_object(p),
+ resp_cb_data, sim_result, dr);
+
+ dbg("Exit");
+}
+
+static void __on_response_atmodem_sim_get_file_info(TcorePending *p,
+ guint data_len, const void *data, void *user_data)
+{
+ const TcoreAtResponse *resp = data;
+ CoreObject *co_sim = NULL;
+ TelSimResult sim_result;
+ GSList *tokens = NULL;
+ const char *line = NULL;
+ int sw1 = 0;
+ int sw2 = 0;
+ AtmodemRespCbData *resp_cb_data = (AtmodemRespCbData *)user_data;
+ AtmodemSimMetaInfo *file_meta =
+ (AtmodemSimMetaInfo *)ATMODEM_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
+
+ dbg("SIM Response - SIM File info: [+CRSM]");
+
+ co_sim = tcore_pending_ref_core_object(p);
+
+ if (resp->success > 0) {
+ dbg("RESPONSE OK");
+ if (resp->lines) {
+ line = (const char *)resp->lines->data;
+ tokens = tcore_at_tok_new(line);
+ if (g_slist_length(tokens) < 2) {
+ err("Invalid message");
+ tcore_at_tok_free(tokens);
+ return;
+ }
+ }
+ sw1 = atoi(g_slist_nth_data(tokens, 0));
+ sw2 = atoi(g_slist_nth_data(tokens, 1));
+
+ /*1. SIM access success case*/
+ if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
+ unsigned char tag_len = 0;
+ unsigned short record_len = 0;
+ char num_of_records = 0;
+ unsigned char file_id_len = 0;
+ unsigned short file_id = 0;
+ unsigned short file_size = 0;
+ unsigned short file_type = 0;
+ unsigned short arr_file_id = 0;
+ int arr_file_id_rec_num = 0;
+ guint buf_len = 0;
+ TelSimCardType card_type = TEL_SIM_CARD_TYPE_UNKNOWN;
+
+ /* handling only last 3 bits */
+ unsigned char file_type_tag = 0x07;
+ unsigned char *ptr_data;
+
+ char *hexData;
+ char *tmp;
+ char *record_data = NULL;
+ hexData = g_slist_nth_data(tokens, 2);
+ dbg("hexData: %s", hexData);
+ dbg("hexData: %s", hexData + 1);
+
+ tmp = tcore_at_tok_extract(hexData);
+ tcore_util_hexstring_to_bytes(tmp, &record_data, &buf_len); /*TODO : Check*/
+ tcore_util_hex_dump(" ", buf_len, record_data);
+ g_free(tmp);
+
+ ptr_data = (unsigned char *)record_data;
+ tcore_sim_get_type(co_sim, &card_type);
+ if (TEL_SIM_CARD_TYPE_USIM == card_type) {
+ /*
+ ETSI TS 102 221 v7.9.0
+ - Response Data
+ '62' FCP template tag
+ - Response for an EF
+ '82' M File Descriptor
+ '83' M File Identifier
+ 'A5' O Proprietary information
+ '8A' M Life Cycle Status Integer
+ '8B', '8C' or 'AB' C1 Security attributes
+ '80' M File size
+ '81' O Total file size
+ '88' O Short File Identifier (SFI)
+ */
+
+ /* rsim.res_len has complete data length received */
+
+ /* FCP template tag - File Control Parameters tag*/
+ if (*ptr_data == 0x62) {
+ /* parse complete FCP tag*/
+ /* increment to next byte */
+ ptr_data++;
+ tag_len = *ptr_data++;
+ dbg("tag_len: %02x", tag_len);
+ /* FCP file descriptor - file type, accessibility, DF, ADF etc*/
+ if (*ptr_data == 0x82) {
+ /* increment to next byte */
+ ptr_data++;
+ /* 2 or 5 value*/
+ ptr_data++;
+ /* consider only last 3 bits*/
+ dbg("file_type_tag: %02x", file_type_tag);
+ file_type_tag = file_type_tag & (*ptr_data);
+ dbg("file_type_tag: %02x", file_type_tag);
+
+ switch (file_type_tag) {
+ /* increment to next byte */
+ // ptr_data++;
+ case 0x1:
+ dbg("Getting FileType: [Transparent file type]");
+ file_type = ATMODEM_SIM_FILE_TYPE_TRANSPARENT;
+
+ /* increment to next byte */
+ ptr_data++;
+ /* increment to next byte */
+ ptr_data++;
+ break;
+
+ case 0x2:
+ dbg("Getting FileType: [Linear fixed file type]");
+ /* increment to next byte */
+ ptr_data++;
+ /* data coding byte - value 21 */
+ ptr_data++;
+ /* 2bytes */
+ memcpy(&record_len, ptr_data, 2);
+ /* swap bytes */
+ ATMODEM_SWAP_BYTES_16(record_len);
+ ptr_data = ptr_data + 2;
+ num_of_records = *ptr_data++;
+ /* Data lossy conversation from enum (int) to unsigned char */
+ file_type = ATMODEM_SIM_FILE_TYPE_LINEAR_FIXED;
+ break;
+
+ case 0x6:
+ dbg("Cyclic fixed file type");
+ /* increment to next byte */
+ ptr_data++;
+ /* data coding byte - value 21 */
+ ptr_data++;
+ /* 2bytes */
+ memcpy(&record_len, ptr_data, 2);
+ /* swap bytes */
+ ATMODEM_SWAP_BYTES_16(record_len);
+ ptr_data = ptr_data + 2;
+ num_of_records = *ptr_data++;
+ file_type = ATMODEM_SIM_FILE_TYPE_CYCLIC;
+ break;
+
+ default:
+ dbg("not handled file type [0x%x]", *ptr_data);
+ break;
+ }
+ } else {
+ dbg("INVALID FCP received - DEbug!");
+ tcore_at_tok_free(tokens);
+ g_free(record_data);
+ return;
+ }
+
+ /*File identifier - 0x84,0x85,0x86 etc are currently ignored and not handled */
+ if (*ptr_data == 0x83) {
+ /* increment to next byte */
+ ptr_data++;
+ file_id_len = *ptr_data++;
+ dbg("file_id_len: %02x", file_id_len);
+
+ memcpy(&file_id, ptr_data, file_id_len);
+ dbg("file_id: %x", file_id);
+
+ /* swap bytes */
+ ATMODEM_SWAP_BYTES_16(file_id);
+ dbg("file_id: %x", file_id);
+
+ ptr_data = ptr_data + 2;
+ dbg("Getting FileID=[0x%x]", file_id);
+ } else {
+ dbg("INVALID FCP received - DEbug!");
+ tcore_at_tok_free(tokens);
+ g_free(record_data);
+ return;
+ }
+
+ /* proprietary information */
+ if (*ptr_data == 0xA5) {
+ unsigned short prop_len;
+ /* increment to next byte */
+ ptr_data++;
+
+ /* length */
+ prop_len = *ptr_data;
+ dbg("prop_len: %02x", prop_len);
+
+ /* skip data */
+ ptr_data = ptr_data + prop_len + 1;
+ } else {
+ dbg("INVALID FCP received - DEbug!");
+ }
+
+ /* life cycle status integer [8A][length:0x01][status]*/
+ /*
+ status info b8~b1
+ 00000000 : No information given
+ 00000001 : creation state
+ 00000011 : initialization state
+ 000001-1 : operation state -activated
+ 000001-0 : operation state -deactivated
+ 000011-- : Termination state
+ b8~b5 !=0, b4~b1=X : Proprietary
+ Any other value : RFU
+ */
+ if (*ptr_data == 0x8A) {
+ /* increment to next byte */
+ ptr_data++;
+ /* length - value 1 */
+ ptr_data++;
+
+ switch (*ptr_data) {
+ case 0x04:
+ case 0x06:
+ dbg("<RX> operation state -deactivated");
+ ptr_data++;
+ break;
+
+ case 0x05:
+ case 0x07:
+ dbg("<RX> operation state -activated");
+ ptr_data++;
+ break;
+
+ default:
+ dbg("<RX> DEBUG! LIFE CYCLE STATUS =[0x%x]", *ptr_data);
+ ptr_data++;
+ break;
+ }
+ }
+
+ /* related to security attributes : currently not handled*/
+ if (*ptr_data == 0x86 || *ptr_data == 0x8B || *ptr_data == 0x8C || *ptr_data == 0xAB) {
+ /* increment to next byte */
+ ptr_data++;
+ /* if tag length is 3 */
+ if (*ptr_data == 0x03) {
+ /* increment to next byte */
+ ptr_data++;
+ /* EFARR file id */
+ memcpy(&arr_file_id, ptr_data, 2);
+ /* swap byes */
+ ATMODEM_SWAP_BYTES_16(arr_file_id);
+ ptr_data = ptr_data + 2;
+ arr_file_id_rec_num = *ptr_data++;
+ dbg("arr_file_id_rec_num:[%d]", arr_file_id_rec_num);
+ } else {
+ /* if tag length is not 3 */
+ /* ignoring bytes */
+ // ptr_data = ptr_data + 4;
+ dbg("Useless security attributes, so jump to next tag");
+ ptr_data = ptr_data + (*ptr_data + 1);
+ }
+ } else {
+ dbg("INVALID FCP received[0x%x] - DEbug!", *ptr_data);
+ tcore_at_tok_free(tokens);
+ g_free(record_data);
+ return;
+ }
+
+ dbg("Current ptr_data value is [%x]", *ptr_data);
+
+ /* file size excluding structural info*/
+ if (*ptr_data == 0x80) {
+ /* for EF file size is body of file and for Linear or cyclic it is
+ * number of recXsizeof(one record)
+ */
+ /* increment to next byte */
+ ptr_data++;
+ /* length is 1 byte - value is 2 bytes or more */
+ ptr_data++;
+ memcpy(&file_size, ptr_data, 2);
+ /* swap bytes */
+ ATMODEM_SWAP_BYTES_16(file_size);
+ ptr_data = ptr_data + 2;
+ } else {
+ dbg("INVALID FCP received - DEbug!");
+ tcore_at_tok_free(tokens);
+ g_free(record_data);
+ return;
+ }
+
+ /* total file size including structural info*/
+ if (*ptr_data == 0x81) {
+ int len;
+ /* increment to next byte */
+ ptr_data++;
+ /* length */
+ len = *ptr_data;
+ dbg("len:[%d]", len);
+ /* ignored bytes */
+ ptr_data = ptr_data + 3;
+ } else {
+ dbg("INVALID FCP received - DEbug!");
+ /* 0x81 is optional tag?? check out! so do not return -1 from here! */
+ }
+ /*short file identifier ignored*/
+ if (*ptr_data == 0x88) {
+ dbg("0x88: Do Nothing");
+ /*DO NOTHING*/
+ }
+ } else {
+ dbg("INVALID FCP received - DEbug!");
+ tcore_at_tok_free(tokens);
+ g_free(record_data);
+ return;
+ }
+ } else if (TEL_SIM_CARD_TYPE_GSM == card_type) {
+ unsigned char gsm_specific_file_data_len = 0;
+ /* ignore RFU byte1 and byte2 */
+ ptr_data++;
+ ptr_data++;
+ /* file size */
+ // file_size = p_info->response_len;
+ memcpy(&file_size, ptr_data, 2);
+ /* swap bytes */
+ ATMODEM_SWAP_BYTES_16(file_size);
+ /* parsed file size */
+ ptr_data = ptr_data + 2;
+ /* file id */
+ memcpy(&file_id, ptr_data, 2);
+ ATMODEM_SWAP_BYTES_16(file_id);
+ dbg("FILE id --> [%x]", file_id);
+ ptr_data = ptr_data + 2;
+ /* save file type - transparent, linear fixed or cyclic */
+ file_type_tag = (*(ptr_data + 7));
+
+ switch (*ptr_data) {
+ case 0x0:
+ /* RFU file type */
+ dbg("RFU file type- not handled - Debug!");
+ break;
+
+ case 0x1:
+ /* MF file type */
+ dbg("MF file type - not handled - Debug!");
+ break;
+
+ case 0x2:
+ /* DF file type */
+ dbg("DF file type - not handled - Debug!");
+ break;
+
+ case 0x4:
+ /* EF file type */
+ dbg("EF file type [%d] ", file_type_tag);
+ /* increment to next byte */
+ ptr_data++;
+
+ if (file_type_tag == 0x00 || file_type_tag == 0x01) {
+ /* increament to next byte as this byte is RFU */
+ ptr_data++;
+ file_type =
+ (file_type_tag == 0x00) ? ATMODEM_SIM_FILE_TYPE_TRANSPARENT : ATMODEM_SIM_FILE_TYPE_LINEAR_FIXED;
+ } else {
+ /* increment to next byte */
+ ptr_data++;
+ /* For a cyclic EF all bits except bit 7 are RFU; b7=1 indicates that */
+ /* the INCREASE command is allowed on the selected cyclic file. */
+ file_type = ATMODEM_SIM_FILE_TYPE_CYCLIC;
+ }
+ /* bytes 9 to 11 give SIM file access conditions */
+ ptr_data++;
+ /* byte 10 has one nibble that is RF U and another for INCREASE which is not used currently */
+ ptr_data++;
+ /* byte 11 is invalidate and rehabilate nibbles */
+ ptr_data++;
+ /* byte 12 - file status */
+ ptr_data++;
+ /* byte 13 - GSM specific data */
+ gsm_specific_file_data_len = *ptr_data;
+ dbg("gsm_specific_file_data_len:[%d]", gsm_specific_file_data_len);
+ ptr_data++;
+ /* byte 14 - structure of EF - transparent or linear or cyclic , already saved above */
+ ptr_data++;
+ /* byte 15 - length of record for linear and cyclic , for transparent it is set to 0x00. */
+ record_len = *ptr_data;
+ dbg("record length[%d], file size[%d]", record_len, file_size);
+ if (record_len != 0)
+ num_of_records = (file_size / record_len);
+
+ dbg("Number of records [%d]", num_of_records);
+ break;
+
+ default:
+ dbg("not handled file type");
+ break;
+ }
+ } else {
+ err("Unknown Card Type - [%d]", card_type);
+ }
+
+ dbg("req ef[0x%x] resp ef[0x%x] size[%ld] Type[0x%x] NumOfRecords[%ld] RecordLen[%ld]",
+ file_meta->file_id, file_id, file_size, file_type, num_of_records, record_len);
+
+ file_meta->file_type = file_type;
+ file_meta->data_size = file_size;
+ file_meta->rec_length = record_len;
+ file_meta->rec_count = num_of_records;
+ file_meta->current_index = 0; /* reset for new record type EF */
+ sim_result = TEL_SIM_RESULT_SUCCESS;
+ g_free(record_data);
+ } else {
+ /*2. SIM access fail case*/
+ err("Failed to get ef[0x%x] (file_meta->file_id) ", file_meta->file_id);
+ sim_result = __atmodem_sim_decode_status_word(sw1, sw2);
+ }
+
+ tcore_at_tok_free(tokens);
+ } else {
+ err("RESPONSE NOK");
+ err("Failed to get ef[0x%x] (file_meta->file_id) ", file_meta->file_id);
+ sim_result = TEL_SIM_RESULT_FAILURE;
+ }
+ dbg("Calling __atmodem_sim_next_from_get_file_info");
+ __atmodem_sim_next_from_get_file_info(co_sim, resp_cb_data, sim_result);
+ dbg("Exit");
+}
+
+static void __atmodem_sim_get_file_record(CoreObject *co_sim, AtmodemRespCbData *resp_cb_data)
+{
+ gchar *at_cmd = NULL;
+ int p1 = 0;
+ int p2 = 0;
+ int p3 = 0;
+ AtmodemSimMetaInfo *file_meta =
+ (AtmodemSimMetaInfo *)ATMODEM_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
+ TelReturn ret = TEL_RETURN_FAILURE;
+
+ dbg("Entry File-id:[0x%02x]", file_meta->file_id);
+
+ /* According to TS 102 221, values of p1, p2, p3 can be as below:
+ * 11.1.5 READ RECORD
+ * P1: Record number
+ * P2: Mode, see table 11.11
+ * Lc: Not present
+ * Data: Not present
+ * Le: Number of bytes to be read (P3)
+ */
+
+ p1 = (unsigned char) file_meta->current_index;
+ p2 = (unsigned char) 0x04; /* 0x4 for absolute mode */
+ p3 = (unsigned char) file_meta->rec_length;
+
+ at_cmd = g_strdup_printf("AT+CRSM=%d, %d, %d, %d, %d",
+ ATMODEM_SIM_ACCESS_READ_RECORD, file_meta->file_id, p1, p2, p3);
+
+ ret = tcore_at_prepare_and_send_request(co_sim,
+ at_cmd, "+CRSM:",
+ TCORE_AT_COMMAND_TYPE_SINGLELINE,
+ TCORE_PENDING_PRIORITY_DEFAULT,
+ NULL,
+ __on_response_atmodem_sim_get_file_data, resp_cb_data,
+ on_send_atmodem_request, NULL,
+ 0, NULL, NULL);
+ ATMODEM_CHECK_REQUEST_RET(ret, resp_cb_data, "Get File Record");
+
+ dbg("ret:[%d]", ret);
+ g_free(at_cmd);
+
+ dbg("Exit");
+}
+
+static void __atmodem_sim_get_file_data(CoreObject *co_sim,
+ AtmodemRespCbData *resp_cb_data)
+{
+ gchar *at_cmd = NULL;
+ int p1 = 0;
+ int p2 = 0;
+ int p3 = 0;
+ int offset = 0;
+ AtmodemSimMetaInfo *file_meta =
+ (AtmodemSimMetaInfo *)ATMODEM_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
+ TelReturn ret = TEL_RETURN_FAILURE;
+
+ dbg("Entry File-id:[0x%02x]", file_meta->file_id);
+
+ /*
+ * According to TS 102 221, values of P1, P2, P3 can be as below:
+ * 11.1.3 READ BINARY
+ * P1: See table 11.10
+ * P2: Offset low
+ * Lc: Not present
+ * Data: Not present
+ * Le: Number of bytes to be read (P3)
+ */
+
+ p1 = (unsigned char) (offset & 0xFF00) >> 8;
+ p2 = (unsigned char) offset & 0x00FF; /* offset low */
+ p3 = (unsigned char) file_meta->data_size;
+
+ at_cmd = g_strdup_printf("AT+CRSM=%d, %d, %d, %d, %d",
+ ATMODEM_SIM_ACCESS_READ_BINARY, file_meta->file_id, p1, p2, p3);
+
+ ret = tcore_at_prepare_and_send_request(co_sim,
+ at_cmd, "+CRSM:",
+ TCORE_AT_COMMAND_TYPE_SINGLELINE,
+ TCORE_PENDING_PRIORITY_DEFAULT,
+ NULL,
+ __on_response_atmodem_sim_get_file_data, resp_cb_data,
+ on_send_atmodem_request, NULL,
+ 0, NULL, NULL);
+ ATMODEM_CHECK_REQUEST_RET(ret, resp_cb_data, "Get File Data");
+
+ dbg("ret:[%d]", ret);
+ g_free(at_cmd);
+
+ dbg("Exit");
+}
+
+static TelReturn __atmodem_sim_get_file_info(CoreObject *co_sim,
+ AtmodemRespCbData *resp_cb_data)
+{
+ gchar *at_cmd = NULL;
+ AtmodemSimMetaInfo *file_meta =
+ (AtmodemSimMetaInfo *)ATMODEM_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
+ TelReturn ret = TEL_RETURN_FAILURE;
+
+ dbg("Entry File-id:[0x%02x]", file_meta->file_id);
+
+ at_cmd = g_strdup_printf("AT+CRSM=%d, %d",
+ ATMODEM_SIM_ACCESS_GET_RESPONSE, file_meta->file_id);
+
+ ret = tcore_at_prepare_and_send_request(co_sim,
+ at_cmd, "+CRSM:",
+ TCORE_AT_COMMAND_TYPE_SINGLELINE,
+ TCORE_PENDING_PRIORITY_DEFAULT, NULL,
+ __on_response_atmodem_sim_get_file_info, resp_cb_data,
+ on_send_atmodem_request, NULL,
+ 0, NULL, NULL);
+ ATMODEM_CHECK_REQUEST_RET(ret, resp_cb_data, "Get File Info");
+
+ g_free(at_cmd);
+ dbg("Exit");
+ return ret;
+}
+
+static char *__atmodem_sim_get_fac_from_lock_type(TelSimLockType lock_type,
+ AtmodemSimCurrSecOp *sec_op, int flag)
+{
+ char *fac = NULL;
+ switch(lock_type) {
+ case TEL_SIM_LOCK_PS:
+ fac = "PS";
+ if (flag == ENABLE_FLAG)
+ *sec_op = ATMODEM_SIM_CURR_SEC_OP_SIM_ENABLE;
+ else if (flag == DISABLE_FLAG)
+ *sec_op = ATMODEM_SIM_CURR_SEC_OP_SIM_DISABLE;
+ else
+ *sec_op = ATMODEM_SIM_CURR_SEC_OP_SIM_STATUS;
+ break;
+
+ case TEL_SIM_LOCK_SC:
+ fac = "SC";
+ if (flag == ENABLE_FLAG)
+ *sec_op = ATMODEM_SIM_CURR_SEC_OP_PIN1_ENABLE;
+ else if (flag == DISABLE_FLAG)
+ *sec_op = ATMODEM_SIM_CURR_SEC_OP_PIN1_DISABLE;
+ else
+ *sec_op = ATMODEM_SIM_CURR_SEC_OP_PIN1_STATUS;
+ break;
+
+ case TEL_SIM_LOCK_FD:
+ fac = "FD";
+ if (flag == ENABLE_FLAG)
+ *sec_op = ATMODEM_SIM_CURR_SEC_OP_FDN_ENABLE;
+ else if (flag == DISABLE_FLAG)
+ *sec_op = ATMODEM_SIM_CURR_SEC_OP_FDN_DISABLE;
+ else
+ *sec_op = ATMODEM_SIM_CURR_SEC_OP_FDN_STATUS;
+ break;
+
+ case TEL_SIM_LOCK_PN:
+ fac = "PN";
+ if (flag == ENABLE_FLAG)
+ *sec_op = ATMODEM_SIM_CURR_SEC_OP_NET_ENABLE;
+ else if (flag == DISABLE_FLAG)
+ *sec_op = ATMODEM_SIM_CURR_SEC_OP_NET_DISABLE;
+ else
+ *sec_op = ATMODEM_SIM_CURR_SEC_OP_NET_STATUS;
+ break;
+
+ case TEL_SIM_LOCK_PU:
+ fac = "PU";
+ if (flag == ENABLE_FLAG)
+ *sec_op = ATMODEM_SIM_CURR_SEC_OP_NS_ENABLE;
+ else if (flag == DISABLE_FLAG)
+ *sec_op = ATMODEM_SIM_CURR_SEC_OP_NS_DISABLE;
+ else
+ *sec_op = ATMODEM_SIM_CURR_SEC_OP_NS_STATUS;
+ break;
+
+ case TEL_SIM_LOCK_PP:
+ fac = "PP";
+ if (flag == ENABLE_FLAG)
+ *sec_op = ATMODEM_SIM_CURR_SEC_OP_SP_ENABLE;
+ else if (flag == DISABLE_FLAG)
+ *sec_op = ATMODEM_SIM_CURR_SEC_OP_SP_DISABLE;
+ else
+ *sec_op = ATMODEM_SIM_CURR_SEC_OP_SP_STATUS;
+ break;
+
+ case TEL_SIM_LOCK_PC:
+ fac = "PC";
+ if (flag == ENABLE_FLAG)
+ *sec_op = ATMODEM_SIM_CURR_SEC_OP_CP_ENABLE;
+ else if (flag == DISABLE_FLAG)
+ *sec_op = ATMODEM_SIM_CURR_SEC_OP_CP_DISABLE;
+ else
+ *sec_op = ATMODEM_SIM_CURR_SEC_OP_CP_STATUS;
+ break;
+
+ default:
+ err("Unhandled sim lock type [%d]", lock_type);
+ }
+
+ return fac;
+}
+
+static void __atmodem_sim_next_from_read_binary(CoreObject *co,
+ AtmodemRespCbData *resp_cb_data, TelSimResult sim_result, gboolean decode_ret)
+{
+ AtmodemSimMetaInfo *file_meta =
+ (AtmodemSimMetaInfo *)ATMODEM_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
+ TelSimCardType card_type = TEL_SIM_CARD_TYPE_UNKNOWN;
+
+ dbg("Entry");
+
+ dbg("[SIM]EF[0x%x] read sim_result[%d] Decode rt[%d]",
+ file_meta->file_id, sim_result, decode_ret);
+ switch (file_meta->file_id) {
+ case TEL_SIM_EF_ELP:
+ case TEL_SIM_EF_USIM_PL:
+ case TEL_SIM_EF_LP:
+ case TEL_SIM_EF_USIM_LI:
+ if (decode_ret == TRUE) {
+ if (resp_cb_data->cb)
+ resp_cb_data->cb(co, (gint)sim_result,
+ &file_meta->files.data, resp_cb_data->cb_data);
+ } else {
+ tcore_sim_get_type(co, &card_type);
+ /* 2G */
+ /* The ME requests the Extended Language Preference.
+ * The ME only requests the Language Preference (EFLP)
+ * if at least one of the following conditions holds:
+ * - EFELP is not available;
+ * - EFELP does not contain an entry corresponding to
+ * a language specified in ISO 639[30];
+ * - the ME does not support any of the languages in EFELP.
+ */
+ /* 3G */
+ /*
+ * The ME only requests the Language Preference (EFPL)
+ * if at least one of the following conditions holds:
+ * - if the EFLI has the value 'FFFF' in its highest
+ * priority position
+ * - if the ME does not support any of the language
+ * codes indicated in EFLI , or if EFLI is not present
+ */
+ if (TEL_SIM_CARD_TYPE_GSM == card_type) {
+ if (file_meta->file_id == TEL_SIM_EF_LP) {
+ if (resp_cb_data->cb)
+ resp_cb_data->cb(co, (gint)sim_result,
+ &file_meta->files.data, resp_cb_data->cb_data);
+ } else {
+ file_meta->file_id = TEL_SIM_EF_LP;
+ __atmodem_sim_get_response(co, resp_cb_data);
+ }
+ } else if (TEL_SIM_CARD_TYPE_USIM) {
+ if (file_meta->file_id == TEL_SIM_EF_LP
+ || file_meta->file_id == TEL_SIM_EF_USIM_LI) {
+ file_meta->file_id = TEL_SIM_EF_ELP;
+ __atmodem_sim_get_response(co, resp_cb_data);
+ } else {
+ if (resp_cb_data->cb)
+ resp_cb_data->cb(co, (gint)sim_result,
+ &file_meta->files.data, resp_cb_data->cb_data);
+ }
+ }
+ }
+ break;
+
+ case TEL_SIM_EF_ECC:
+ tcore_sim_get_type(co, &card_type);
+ if (TEL_SIM_CARD_TYPE_USIM == card_type) {
+ if (file_meta->current_index == file_meta->rec_count) {
+ if (resp_cb_data->cb)
+ resp_cb_data->cb(co, (gint)sim_result,
+ &file_meta->files.data, resp_cb_data->cb_data);
+ } else {
+ file_meta->current_index++;
+ __atmodem_sim_read_record(co, resp_cb_data);
+ }
+ } else if (TEL_SIM_CARD_TYPE_GSM == card_type) {
+ if (resp_cb_data->cb)
+ resp_cb_data->cb(co, (gint)sim_result,
+ &file_meta->files.data, resp_cb_data->cb_data);
+ } else {
+ dbg("[SIM DATA]Invalid CardType[%d] Unable to handle", card_type);
+ }
+ break;
+
+ case TEL_SIM_EF_IMSI:
+ __atmodem_sim_update_sim_status(co, TEL_SIM_STATUS_SIM_INIT_COMPLETED);
+ break;
+
+ case TEL_SIM_EF_MSISDN:
+ if (file_meta->current_index == file_meta->rec_count) {
+ if (resp_cb_data->cb)
+ resp_cb_data->cb(co, (gint)sim_result,
+ &file_meta->files.data, resp_cb_data->cb_data);
+ } else {
+ file_meta->current_index++;
+ __atmodem_sim_read_record(co, resp_cb_data);
+ }
+ break;
+
+ case TEL_SIM_EF_OPL:
+ if (file_meta->current_index == file_meta->rec_count) {
+ if (resp_cb_data->cb)
+ resp_cb_data->cb(co, (gint)sim_result,
+ &file_meta->files.data, resp_cb_data->cb_data);
+ } else {
+ file_meta->current_index++;
+ __atmodem_sim_read_record(co, resp_cb_data);
+ }
+ break;
+
+ case TEL_SIM_EF_PNN:
+ if (file_meta->current_index == file_meta->rec_count) {
+ if (resp_cb_data->cb)
+ resp_cb_data->cb(co, (gint)sim_result,
+ &file_meta->files.data, resp_cb_data->cb_data);
+ } else {
+ file_meta->current_index++;
+ __atmodem_sim_read_record(co, resp_cb_data);
+ }
+ break;
+
+ case TEL_SIM_EF_USIM_CFIS:
+ case TEL_SIM_EF_USIM_MWIS:
+ case TEL_SIM_EF_USIM_MBI:
+ case TEL_SIM_EF_MBDN:
+ case TEL_SIM_EF_CPHS_MAILBOX_NUMBERS:
+ case TEL_SIM_EF_CPHS_INFORMATION_NUMBERS:
+ if (file_meta->current_index == file_meta->rec_count) {
+ if (resp_cb_data->cb)
+ resp_cb_data->cb(co, (gint)sim_result,
+ &file_meta->files.data, resp_cb_data->cb_data);
+ } else {
+ file_meta->current_index++;
+ __atmodem_sim_read_record(co, resp_cb_data);
+ }
+ break;
+
+ case TEL_SIM_EF_CPHS_OPERATOR_NAME_STRING:
+ {
+ file_meta->files.result = sim_result;
+ if (decode_ret == TRUE && sim_result == TEL_SIM_RESULT_SUCCESS) {
+ memcpy(file_meta->files.data.cphs_net.full_name,
+ file_meta->files.data.cphs_net.full_name,
+ strlen((char *)file_meta->files.data.cphs_net.full_name));
+ }
+
+ file_meta->file_id = TEL_SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING;
+ file_meta->file_result = TEL_SIM_RESULT_FAILURE;
+ __atmodem_sim_get_response(co, resp_cb_data);
+ }
+ break;
+
+ case TEL_SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING:
+ if (file_meta->files.result == TEL_SIM_RESULT_SUCCESS) {
+ file_meta->files.result = TEL_SIM_RESULT_SUCCESS;
+ }
+ if (strlen((char *)file_meta->files.data.cphs_net.full_name)) {
+ memcpy(&file_meta->files.data.cphs_net.full_name,
+ &file_meta->files.data.cphs_net.full_name,
+ strlen((char *)file_meta->files.data.cphs_net.full_name));
+ }
+ if (resp_cb_data->cb)
+ resp_cb_data->cb(co, (gint)sim_result,
+ &file_meta->files.data, resp_cb_data->cb_data);
+ break;
+
+ case TEL_SIM_EF_ICCID:
+ if (resp_cb_data->cb)
+ resp_cb_data->cb(co, (gint)sim_result,
+ &file_meta->files.data.iccid, resp_cb_data->cb_data);
+ break;
+
+ case TEL_SIM_EF_SST:
+ case TEL_SIM_EF_SPN:
+ case TEL_SIM_EF_SPDI:
+ case TEL_SIM_EF_OPLMN_ACT:
+ case TEL_SIM_EF_CPHS_CPHS_INFO:
+ case TEL_SIM_EF_CPHS_CALL_FORWARD_FLAGS:
+ case TEL_SIM_EF_CPHS_VOICE_MSG_WAITING:
+ case TEL_SIM_EF_CPHS_DYNAMICFLAGS:
+ case TEL_SIM_EF_CPHS_DYNAMIC2FLAG:
+ case TEL_SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE:
+ case TEL_SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE_LINE2:
+ if (resp_cb_data->cb)
+ resp_cb_data->cb(co, (gint)sim_result,
+ &file_meta->files.data, resp_cb_data->cb_data);
+ break;
+
+ default:
+ err("File id not handled [0x%x]", file_meta->file_id);
+ break;
+ }
+}
+
+static void __atmodem_sim_next_from_get_response(CoreObject *co,
+ AtmodemRespCbData *resp_cb_data, TelSimResult sim_result)
+{
+ AtmodemSimMetaInfo *file_meta =
+ (AtmodemSimMetaInfo *)ATMODEM_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
+ TelSimCardType card_type = TEL_SIM_CARD_TYPE_UNKNOWN;
+
+ dbg("EF[0x%x] access Result[%d]", file_meta->file_id, sim_result);
+
+ file_meta->files.result = sim_result;
+ memset(&file_meta->files.data, 0x00, sizeof(file_meta->files.data));
+
+ if ((file_meta->file_id != TEL_SIM_EF_ELP
+ && file_meta->file_id != TEL_SIM_EF_LP
+ && file_meta->file_id != TEL_SIM_EF_USIM_PL
+ && file_meta->file_id != TEL_SIM_EF_CPHS_CPHS_INFO)
+ && (sim_result != TEL_SIM_RESULT_SUCCESS)) {
+ if (resp_cb_data->cb)
+ resp_cb_data->cb(co, (gint)sim_result,
+ &file_meta->files.data, resp_cb_data->cb_data);
+
+ return;
+ }
+
+ switch (file_meta->file_id) {
+ case TEL_SIM_EF_ELP: {
+ if (sim_result == TEL_SIM_RESULT_SUCCESS) {
+ dbg("[SIM DATA] exist EFELP/PL(0x2F05)");
+ __atmodem_sim_read_binary(co, resp_cb_data);
+ } else {
+ tcore_sim_get_type(co, &card_type);
+ if (TEL_SIM_CARD_TYPE_GSM == card_type) {
+ AtmodemSimMetaInfo file_meta_new = {0,};
+
+ dbg("[SIM DATA]SIM_EF_ELP(2F05) access fail. Request SIM_EF_LP(0x6F05) info");
+ /* The ME requests the Language Preference (EFLP) if EFELP is not available */
+ file_meta_new.file_id = TEL_SIM_EF_LP;
+ file_meta_new.file_result = TEL_SIM_RESULT_FAILURE;
+ file_meta_new.req_command = TCORE_COMMAND_SIM_GET_LANGUAGE;
+
+ memcpy(resp_cb_data->data, &file_meta_new, sizeof(AtmodemSimMetaInfo));
+
+ __atmodem_sim_get_response(co, resp_cb_data);
+ } else if (TEL_SIM_CARD_TYPE_USIM == card_type) {
+ dbg(" [SIM DATA]fail to get Language information "\
+ "in USIM(EF-LI(6F05),EF-PL(2F05))");
+ if (resp_cb_data->cb)
+ resp_cb_data->cb(co, (gint)sim_result,
+ &file_meta->files.data, resp_cb_data->cb_data);
+ return;
+ }
+ }
+ }
+ break;
+
+ case TEL_SIM_EF_LP: {
+ if (sim_result == TEL_SIM_RESULT_SUCCESS) {
+ dbg("[SIM DATA] exist EFLP/LI(0x6F05)");
+ __atmodem_sim_read_binary(co, resp_cb_data);
+ } else {
+ tcore_sim_get_type(co, &card_type);
+ dbg("[SIM DATA]SIM_EF_LP/LI(6F05) access fail. Current CardType[%d]", card_type);
+ if (TEL_SIM_CARD_TYPE_GSM == card_type) {
+ if (resp_cb_data->cb)
+ resp_cb_data->cb(co, (gint)sim_result,
+ &file_meta->files.data, resp_cb_data->cb_data);
+ return;
+ }
+ /*
+ * If EFLI is not present, then the language selection
+ * shall be as defined in EFPL at the MF level
+ */
+ else if (TEL_SIM_CARD_TYPE_USIM == card_type) {
+ AtmodemSimMetaInfo file_meta_new = {0,};
+
+ dbg("[SIM DATA] try USIM EFPL(0x2F05)");
+ file_meta_new.file_id = TEL_SIM_EF_ELP;
+ file_meta_new.file_result = TEL_SIM_RESULT_FAILURE;
+ file_meta_new.req_command = TCORE_COMMAND_SIM_GET_LANGUAGE;
+
+ memcpy(resp_cb_data->data, &file_meta_new, sizeof(AtmodemSimMetaInfo));
+
+ __atmodem_sim_get_response(co, resp_cb_data);
+ }
+ }
+ }
+ break;
+
+ case TEL_SIM_EF_USIM_PL: {
+ if (sim_result == TEL_SIM_RESULT_SUCCESS) {
+ dbg("[SIM DATA] exist EFELP/PL(0x2F05)");
+ __atmodem_sim_read_binary(co, resp_cb_data);
+ } else {
+ /*
+ * EFELIand EFPL not present, so set language count
+ * as zero and select ECC
+ */
+ dbg("[SIM DATA]SIM_EF_USIM_PL(2A05) access fail. "\
+ "Request SIM_EF_ECC(0x6FB7) info");
+ if (resp_cb_data->cb)
+ resp_cb_data->cb(co, (gint)sim_result,
+ &file_meta->files.data, resp_cb_data->cb_data);
+
+ return;
+ }
+ }
+ break;
+
+ case TEL_SIM_EF_ECC: {
+ tcore_sim_get_type(co, &card_type);
+ if (TEL_SIM_CARD_TYPE_GSM == card_type) {
+ __atmodem_sim_read_binary(co, resp_cb_data);
+ } else if (TEL_SIM_CARD_TYPE_USIM == card_type) {
+ if (file_meta->rec_count > TEL_SIM_ECC_LIST_MAX)
+ file_meta->rec_count = TEL_SIM_ECC_LIST_MAX;
+
+ file_meta->current_index++;
+ __atmodem_sim_read_record(co, resp_cb_data);
+ }
+ }
+ break;
+
+ case TEL_SIM_EF_ICCID:
+ case TEL_SIM_EF_IMSI:
+ case TEL_SIM_EF_SST:
+ case TEL_SIM_EF_SPN:
+ case TEL_SIM_EF_SPDI:
+ case TEL_SIM_EF_CPHS_CALL_FORWARD_FLAGS:
+ case TEL_SIM_EF_CPHS_VOICE_MSG_WAITING:
+ case TEL_SIM_EF_CPHS_OPERATOR_NAME_STRING:
+ case TEL_SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING:
+ case TEL_SIM_EF_CPHS_DYNAMICFLAGS:
+ case TEL_SIM_EF_CPHS_DYNAMIC2FLAG:
+ case TEL_SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE:
+ case TEL_SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE_LINE2:
+ __atmodem_sim_read_binary(co, resp_cb_data);
+ break;
+
+ case TEL_SIM_EF_CPHS_CPHS_INFO: {
+ if (sim_result == TEL_SIM_RESULT_SUCCESS) {
+ tcore_sim_set_cphs_status(co, TRUE);
+ __atmodem_sim_update_sim_status(co, TEL_SIM_STATUS_SIM_INIT_COMPLETED);
+
+ __atmodem_sim_read_binary(co, resp_cb_data);
+ } else {
+ tcore_sim_set_cphs_status(co, FALSE);
+ __atmodem_sim_update_sim_status(co, TEL_SIM_STATUS_SIM_INIT_COMPLETED);
+
+ if (resp_cb_data->cb)
+ resp_cb_data->cb(co, (gint)sim_result,
+ &file_meta->files.data, resp_cb_data->cb_data);
+ }
+ }
+ break;
+
+
+ case TEL_SIM_EF_USIM_CFIS: {
+ if (file_meta->rec_count > TEL_SIM_CALL_FORWARDING_TYPE_MAX)
+ file_meta->rec_count = TEL_SIM_CALL_FORWARDING_TYPE_MAX;
+
+ file_meta->current_index++;
+ __atmodem_sim_read_record(co, resp_cb_data);
+ }
+ break;
+
+ case TEL_SIM_EF_OPL:
+ case TEL_SIM_EF_PNN:
+ case TEL_SIM_EF_USIM_MWIS:
+ case TEL_SIM_EF_USIM_MBI:
+ case TEL_SIM_EF_MBDN:
+ case TEL_SIM_EF_CPHS_MAILBOX_NUMBERS:
+ case TEL_SIM_EF_CPHS_INFORMATION_NUMBERS:
+ case TEL_SIM_EF_MSISDN:
+ file_meta->current_index++;
+ __atmodem_sim_read_record(co, resp_cb_data);
+ break;
+
+ case TEL_SIM_EF_SMSP: {
+ AtmodemSimPrivateInfo *priv_info = NULL;
+
+ priv_info = tcore_sim_ref_userdata(co);
+
+ dbg("SMSP info set to tcore : count:[%d], rec_len:[%d]",
+ file_meta->rec_count, file_meta->rec_length);
+ priv_info->smsp_count = file_meta->rec_count;
+ priv_info->smsp_rec_len = file_meta->rec_length;
+ }
+ break;
+
+ default:
+ dbg("error - File id for get file info [0x%x]", file_meta->file_id);
+ break;
+ }
+ return;
+}
+
+#if 0 //blocking for the moment
+static void __on_response_atmodem_sim_update_file(TcorePending *p,
+ guint data_len, const void *data, void *user_data)
+{
+ const TcoreAtResponse *resp = data;
+ CoreObject *co_sim = NULL;
+ GSList *tokens = NULL;
+ TelSimResult sim_result = TEL_SIM_RESULT_CARD_ERROR;
+ const char *line;
+ AtmodemRespCbData *resp_cb_data = (AtmodemRespCbData *)user_data;
+ AtmodemSimMetaInfo *file_meta =
+ (AtmodemSimMetaInfo *)ATMODEM_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
+
+ dbg("Entry");
+
+ co_sim = tcore_pending_ref_core_object(p);
+
+ dbg("file_id:[0x%x]", file_meta->file_id);
+
+ if (resp->success > 0) {
+ int sw1 = 0;
+ int sw2 = 0;
+ dbg("RESPONSE OK");
+ if (resp->lines) {
+ line = (const char *)resp->lines->data;
+ tokens = tcore_at_tok_new(line);
+ if (g_slist_length(tokens) != 2) {
+ err("Invalid message");
+ goto out;
+ }
+ sw1 = atoi(g_slist_nth_data(tokens, 0));
+ sw2 = atoi(g_slist_nth_data(tokens, 1));
+ }
+
+ if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
+ sim_result = TEL_SIM_RESULT_SUCCESS;
+ } else {
+ sim_result = __atmodem_sim_decode_status_word(sw1, sw2);
+ }
+ } else {
+ err("RESPONSE NOK");
+ sim_result = TEL_SIM_RESULT_FAILURE;
+ }
+out:
+ /* Send Response */
+ if (resp_cb_data->cb)
+ resp_cb_data->cb(co_sim, (gint)sim_result,
+ NULL, resp_cb_data->cb_data);
+
+ tcore_at_tok_free(tokens);
+ dbg("Exit");
+}
+#endif
+
+static void __on_response_atmodem_sim_read_data(TcorePending *p,
+ guint data_len, const void *data, void *user_data)
+{
+ const TcoreAtResponse *resp = data;
+ CoreObject *co = NULL;
+ GSList *tokens = NULL;
+ TelSimResult sim_result;
+ gboolean dr = FALSE;
+ const char *line = NULL;
+ char *res = NULL;
+ char *tmp = NULL;
+ guint res_len;
+ int sw1 = 0;
+ int sw2 = 0;
+ TelSimCardType card_type = TEL_SIM_CARD_TYPE_UNKNOWN;
+ AtmodemRespCbData *resp_cb_data = (AtmodemRespCbData *) user_data;
+ AtmodemSimMetaInfo *file_meta =
+ (AtmodemSimMetaInfo *)ATMODEM_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
+
+ dbg("Entry");
+
+ co = tcore_pending_ref_core_object(p);
+
+ if (resp->success > 0) {
+ dbg("RESPONSE OK");
+ if (resp->lines) {
+ line = (const char *)resp->lines->data;
+ tokens = tcore_at_tok_new(line);
+ if (g_slist_length(tokens) != 2) {
+ err("Invalid message");
+ tcore_at_tok_free(tokens);
+ return;
+ }
+ }
+ sw1 = atoi(g_slist_nth_data(tokens, 0));
+ sw2 = atoi(g_slist_nth_data(tokens, 1));
+ res = g_slist_nth_data(tokens, 2);
+
+ tmp = tcore_at_tok_extract(res);
+ tcore_util_hexstring_to_bytes(tmp, &res, &res_len);
+ dbg("Response: [%s] Response length: [%d]", res, res_len);
+
+ if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
+ sim_result = TEL_SIM_RESULT_SUCCESS;
+ file_meta->files.result = sim_result;
+
+ dbg("File ID: [0x%x]", file_meta->file_id);
+ switch (file_meta->file_id) {
+ case TEL_SIM_EF_IMSI: {
+ dbg("Data: [%s]", res);
+ dr = tcore_sim_decode_imsi((unsigned char *)res,
+ res_len, &file_meta->imsi);
+ if (dr == FALSE) {
+ err("IMSI decoding failed");
+ } else {
+ __atmodem_sim_set_identity(co, &file_meta->imsi);
+
+ /* Update IMSI */
+ tcore_sim_set_imsi(co, &file_meta->imsi);
+ }
+ }
+ break;
+
+ case TEL_SIM_EF_ICCID: {
+ dr = tcore_sim_decode_iccid((unsigned char *)res, res_len,
+ file_meta->files.data.iccid);
+ }
+ break;
+
+ case TEL_SIM_EF_ELP: /* 2G EF - 2 bytes decoding */
+ case TEL_SIM_EF_USIM_LI: /* 3G EF - 2 bytes decoding */
+ case TEL_SIM_EF_USIM_PL: /* 3G EF - same as EFELP, so 2 byte decoding */
+ case TEL_SIM_EF_LP: /* 1 byte encoding */
+ {
+ tcore_sim_get_type(co, &card_type);
+ if ((TEL_SIM_CARD_TYPE_GSM == card_type)
+ && (file_meta->file_id == TEL_SIM_EF_LP)) {
+ /*
+ * 2G LP(0x6F05) has 1 byte for each language
+ */
+ dr = tcore_sim_decode_lp((unsigned char *)res,
+ res_len, &file_meta->files.data.language);
+ } else {
+ /*
+ * 3G LI(0x6F05)/PL(0x2F05),
+ * 2G ELP(0x2F05) has 2 bytes for each language
+ */
+ dr = tcore_sim_decode_li((unsigned char *)res, res_len,
+ file_meta->file_id, &file_meta->files.data.language);
+ }
+ }
+ break;
+
+ case TEL_SIM_EF_SPN:
+ dr = tcore_sim_decode_spn((unsigned char *)res,
+ res_len, &file_meta->files.data.spn);
+ break;
+
+ case TEL_SIM_EF_SPDI:
+ dr = tcore_sim_decode_spdi((unsigned char *)res,
+ res_len, &file_meta->files.data.spdi);
+ break;
+
+ case TEL_SIM_EF_SST: {
+ TelSimServiceTable *svct = NULL;
+
+ svct = g_try_new0(TelSimServiceTable, 1);
+ tcore_sim_get_type(co, &card_type);
+ svct->sim_type = card_type;
+ if (TEL_SIM_CARD_TYPE_GSM == card_type) {
+ dr = tcore_sim_decode_sst((unsigned char *)res,
+ res_len, svct->table.sst_service);
+ } else if (TEL_SIM_CARD_TYPE_USIM == card_type) {
+ dr = tcore_sim_decode_ust((unsigned char *)res,
+ res_len, svct->table.ust_service);
+ } else {
+ err("Not handled card_type[%d]", card_type);
+ }
+
+ if (dr == FALSE) {
+ err("SST/UST decoding failed");
+ } else {
+ tcore_sim_set_service_table(co, svct);
+ }
+
+ /* Free memory */
+ g_free(svct);
+ }
+ break;
+
+ case TEL_SIM_EF_ECC: {
+ tcore_sim_get_type(co, &card_type);
+ if (TEL_SIM_CARD_TYPE_GSM == card_type) {
+ dr = tcore_sim_decode_ecc((unsigned char *)res,
+ res_len, &file_meta->files.data.ecc);
+ } else if (TEL_SIM_CARD_TYPE_USIM == card_type) {
+ TelSimEcc *ecc = NULL;
+
+ ecc = g_try_new0(TelSimEcc, 1);
+ dbg("Index [%d]", file_meta->current_index);
+
+ dr = tcore_sim_decode_uecc((unsigned char *)res, res_len, ecc);
+ if (dr == TRUE) {
+ memcpy(&file_meta->files.data.ecc.list[file_meta->files.data.ecc.count],
+ ecc, sizeof(TelSimEcc));
+ file_meta->files.data.ecc.count++;
+ }
+
+ /* Free memory */
+ g_free(ecc);
+ } else {
+ dbg("Unknown/Unsupported SIM card Type: [%d]", card_type);
+ }
+ }
+ break;
+
+ case TEL_SIM_EF_MSISDN: {
+ TelSimSubscriberInfo *msisdn = NULL;
+
+ dbg("Index [%d]", file_meta->current_index);
+ msisdn = g_try_new0(TelSimSubscriberInfo, 1);
+ dr = tcore_sim_decode_msisdn((unsigned char *)res, res_len, msisdn);
+ if (dr == TRUE) {
+ memcpy(&file_meta->files.data.msisdn_list.list[file_meta->files.data.msisdn_list.count],
+ msisdn, sizeof(TelSimSubscriberInfo));
+
+ file_meta->files.data.msisdn_list.count++;
+ }
+
+ /* Free memory */
+ g_free(msisdn);
+ }
+ break;
+
+ case TEL_SIM_EF_OPL: {
+ TelSimOpl *opl = NULL;
+
+ dbg("decode w/ index [%d]", file_meta->current_index);
+ opl = g_try_new0(TelSimOpl, 1);
+
+ dr = tcore_sim_decode_opl((unsigned char *)res, res_len, opl);
+ if (dr == TRUE) {
+ memcpy(&file_meta->files.data.opl.list[file_meta->files.data.opl.opl_count],
+ opl, sizeof(TelSimOpl));
+
+ file_meta->files.data.opl.opl_count++;
+ }
+
+ /* Free memory */
+ g_free(opl);
+ }
+ break;
+
+ case TEL_SIM_EF_PNN: {
+ TelSimPnn *pnn = NULL;
+
+ dbg("decode w/ index [%d]", file_meta->current_index);
+ pnn = g_try_new0(TelSimPnn, 1);
+
+ dr = tcore_sim_decode_pnn((unsigned char *)res, res_len, pnn);
+ if (dr == TRUE) {
+ memcpy(&file_meta->files.data.pnn.list[file_meta->files.data.pnn.pnn_count],
+ pnn, sizeof(TelSimPnn));
+
+ file_meta->files.data.pnn.pnn_count++;
+ }
+
+ /* Free memory */
+ g_free(pnn);
+ }
+ break;
+
+ case TEL_SIM_EF_OPLMN_ACT:
+ /*dr = tcore_sim_decode_oplmnwact(&file_meta->files.data.opwa,
+ (unsigned char *)res, res_len);*/
+ break;
+
+ case TEL_SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE:
+ /*dr = tcore_sim_decode_csp(&po->p_cphs->csp,
+ p_data->response, p_data->response_len);*/
+ break;
+
+ case TEL_SIM_EF_USIM_MBI: { /* linear type */
+ TelSimMbi *mbi = NULL;
+
+ mbi = g_try_new0(TelSimMbi, 1);
+ dr = tcore_sim_decode_mbi((unsigned char *)res, res_len, mbi);
+ if (dr == TRUE) {
+ memcpy(&file_meta->mbi_list.list[file_meta->mbi_list.count],
+ mbi, sizeof(TelSimMbi));
+ file_meta->mbi_list.count++;
+
+ dbg("mbi count[%d]", file_meta->mbi_list.count);
+ }
+
+ /* Free memory */
+ g_free(mbi);
+ }
+ break;
+
+ case TEL_SIM_EF_CPHS_MAILBOX_NUMBERS: /* linear type */
+ case TEL_SIM_EF_MBDN: /* linear type */
+ dr = tcore_sim_decode_xdn((unsigned char *)res, res_len,
+ file_meta->mb_list[file_meta->current_index-1].alpha_id,
+ file_meta->mb_list[file_meta->current_index-1].number);
+ file_meta->mb_list[file_meta->current_index-1].alpha_id_len =
+ strlen(file_meta->mb_list[file_meta->current_index-1].alpha_id);
+ file_meta->mb_list[file_meta->current_index-1].profile_id =
+ file_meta->current_index;
+ break;
+
+ case TEL_SIM_EF_CPHS_VOICE_MSG_WAITING: /* transparent type */
+ dr = tcore_sim_decode_vmwf((unsigned char *)res,
+ res_len, file_meta->files.data.mw.mw);
+ break;
+
+ case TEL_SIM_EF_USIM_MWIS: { /* linear type */
+ TelSimMwis *mw = NULL;
+
+ mw = g_try_new0(TelSimMwis, 1);
+
+ dr = tcore_sim_decode_mwis((unsigned char *)res, res_len, mw);
+ if (dr == TRUE) {
+ memcpy(&file_meta->files.data.mw.mw[file_meta->files.data.mw.profile_count],
+ mw, sizeof(TelSimMwis));
+ file_meta->files.data.mw.profile_count++;
+ }
+
+ /* Free memory */
+ g_free(mw);
+ }
+ break;
+
+ case TEL_SIM_EF_CPHS_CALL_FORWARD_FLAGS: /* transparent type */
+ dr = tcore_sim_decode_cff((unsigned char *)res,
+ res_len, file_meta->files.data.mw.mw);
+ break;
+
+ case TEL_SIM_EF_USIM_CFIS: { /* linear type */
+ TelSimCfis *cf = NULL;
+
+ cf = g_try_new0(TelSimCfis, 1);
+ dr = tcore_sim_decode_cfis((unsigned char *)res, res_len, cf);
+ if (dr == TRUE) {
+ memcpy(&file_meta->files.data.cf.cf[file_meta->files.data.cf.profile_count],
+ cf, sizeof(TelSimCfis));
+ file_meta->files.data.cf.profile_count++;
+ }
+
+ /* Free memory */
+ g_free(cf);
+ }
+ break;
+
+ case TEL_SIM_EF_CPHS_SERVICE_STRING_TABLE:
+ dbg("not handled - TEL_SIM_EF_CPHS_SERVICE_STRING_TABLE ");
+ break;
+
+ case TEL_SIM_EF_CPHS_OPERATOR_NAME_STRING:
+ dr = tcore_sim_decode_ons((unsigned char *)res,
+ res_len,
+ (unsigned char*)&file_meta->files.data.cphs_net.full_name);
+ dbg("file_meta->files.result[%d],file_meta->files.data.cphs_net.full_name[%s]",
+ file_meta->files.result, file_meta->files.data.cphs_net.full_name);
+ break;
+
+ case TEL_SIM_EF_CPHS_DYNAMICFLAGS:
+ /*dr = tcore_sim_decode_dynamic_flag(&po->p_cphs->dflagsinfo,
+ p_data->response, p_data->response_len);*/
+ break;
+
+ case TEL_SIM_EF_CPHS_DYNAMIC2FLAG:
+ /*dr = tcore_sim_decode_dynamic2_flag(&po->p_cphs->d2flagsinfo, p_data->response,
+ p_data->response_len);*/
+ break;
+
+ case TEL_SIM_EF_CPHS_CPHS_INFO:
+ /*dr = tcore_sim_decode_cphs_info(&file_meta->files.data.cphs,
+ (unsigned char *)res, res_len);*/
+ break;
+
+ case TEL_SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING:
+ dr = tcore_sim_decode_short_ons((unsigned char *)res, res_len,
+ (unsigned char*)&file_meta->files.data.cphs_net.short_name);
+ dbg("file_meta->files.result[%d],file_meta->files.data.cphs_net.short_name[%s]",
+ file_meta->files.result, file_meta->files.data.cphs_net.short_name);
+ break;
+
+ case TEL_SIM_EF_CPHS_INFORMATION_NUMBERS:
+ /*dr = tcore_sim_decode_information_number(&po->p_cphs->infn,
+ p_data->response, p_data->response_len);*/
+ break;
+
+ default:
+ dbg("File Decoding Failed - not handled File[0x%x]", file_meta->file_id);
+ dr = 0;
+ break;
+ }
+ } else {
+ sim_result = __atmodem_sim_decode_status_word(sw1, sw2);
+ file_meta->files.result = sim_result;
+ }
+
+ /* Free memory */
+ g_free(tmp);
+ g_free(res);
+
+ /* Free tokens */
+ tcore_at_tok_free(tokens);
+ } else {
+ err("RESPONSE NOK");
+ dbg("Error - File ID: [0x%x]", file_meta->file_id);
+ sim_result = TEL_SIM_RESULT_FAILURE;
+ }
+
+ /* Get File data */
+ __atmodem_sim_next_from_read_binary(tcore_pending_ref_core_object(p),
+ resp_cb_data, sim_result, dr);
+
+ dbg("Exit");
+}
+
+static void __on_response_atmodem_sim_get_response(TcorePending *p,
+ guint data_len, const void *data, void *user_data)
+{
+ const TcoreAtResponse *resp = data;
+ CoreObject *co = NULL;
+ TelSimResult sim_result;
+ GSList *tokens = NULL;
+ const char *line = NULL;
+ int sw1 = 0;
+ int sw2 = 0;
+ AtmodemRespCbData *resp_cb_data = (AtmodemRespCbData *)user_data;
+ AtmodemSimMetaInfo *file_meta =
+ (AtmodemSimMetaInfo *)ATMODEM_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
+
+ dbg("SIM Response - SIM File info: [+CRSM]");
+
+ co = tcore_pending_ref_core_object(p);
+
+ if (resp->success > 0) {
+ dbg("RESPONSE OK");
+ if (resp->lines) {
+ line = (const char *)resp->lines->data;
+ tokens = tcore_at_tok_new(line);
+ if (g_slist_length(tokens) < 2) {
+ err("Invalid message");
+ tcore_at_tok_free(tokens);
+ return;
+ }
+ }
+ sw1 = atoi(g_slist_nth_data(tokens, 0));
+ sw2 = atoi(g_slist_nth_data(tokens, 1));
+
+ /*1. SIM access success case*/
+ if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
+ unsigned char tag_len = 0;
+ unsigned short record_len = 0;
+ char num_of_records = 0;
+ unsigned char file_id_len = 0;
+ unsigned short file_id = 0;
+ unsigned short file_size = 0;
+ unsigned short file_type = 0;
+ unsigned short arr_file_id = 0;
+ int arr_file_id_rec_num = 0;
+ TelSimCardType card_type = TEL_SIM_CARD_TYPE_UNKNOWN;
+
+ /* handling only last 3 bits */
+ unsigned char file_type_tag = 0x07;
+ unsigned char *ptr_data;
+
+ char *hexData;
+ char *tmp;
+ char *record_data = NULL;
+ guint record_data_len;
+ hexData = g_slist_nth_data(tokens, 2);
+ dbg("hexData: %s", hexData);
+ dbg("hexData: %s", hexData + 1);
+
+ tmp = tcore_at_tok_extract(hexData);
+ tcore_util_hexstring_to_bytes(tmp, &record_data, &record_data_len);
+ tcore_util_hex_dump(" ", record_data_len, record_data);
+ g_free(tmp);
+
+ ptr_data = (unsigned char *)record_data;
+ tcore_sim_get_type(co, &card_type);
+ if (TEL_SIM_CARD_TYPE_USIM == card_type) {
+ /*
+ * ETSI TS 102 221 v7.9.0
+ * - Response Data
+ * '62' FCP template tag
+ *
+ * - Response for an EF
+ * '82' M File Descriptor
+ * '83' M File Identifier
+ * 'A5' O Proprietary information
+ * '8A' M Life Cycle Status Integer
+ * '8B', '8C' or 'AB' C1 Security attributes
+ * '80' M File size
+ * '81' O Total file size
+ * '88' O Short File Identifier (SFI)
+ */
+
+ /* rsim.res_len has complete data length received */
+
+ /* FCP template tag - File Control Parameters tag*/
+ if (*ptr_data == 0x62) {
+ /* parse complete FCP tag*/
+ /* increment to next byte */
+ ptr_data++;
+ tag_len = *ptr_data++;
+ dbg("tag_len: %02x", tag_len);
+ /* FCP file descriptor - file type, accessibility, DF, ADF etc*/
+ if (*ptr_data == 0x82) {
+ /* increment to next byte */
+ ptr_data++;
+ /* 2 or 5 value*/
+ ptr_data++;
+ /* consider only last 3 bits*/
+ dbg("file_type_tag: %02x", file_type_tag);
+ file_type_tag = file_type_tag & (*ptr_data);
+ dbg("file_type_tag: %02x", file_type_tag);
+
+ switch (file_type_tag) {
+ /* increment to next byte */
+ // ptr_data++;
+ case 0x1:
+ dbg("Getting FileType: [Transparent file type]");
+ file_type = ATMODEM_SIM_FILE_TYPE_TRANSPARENT;
+
+ /* increment to next byte */
+ ptr_data++;
+ /* increment to next byte */
+ ptr_data++;
+ break;
+
+ case 0x2:
+ dbg("Getting FileType: [Linear fixed file type]");
+ /* increment to next byte */
+ ptr_data++;
+ /* data coding byte - value 21 */
+ ptr_data++;
+ /* 2bytes */
+ memcpy(&record_len, ptr_data, 2);
+ /* swap bytes */
+ ATMODEM_SWAP_BYTES_16(record_len);
+ ptr_data = ptr_data + 2;
+ num_of_records = *ptr_data++;
+ /* Data lossy conversation from enum (int) to unsigned char */
+ file_type = ATMODEM_SIM_FILE_TYPE_LINEAR_FIXED;
+ break;
+
+ case 0x6:
+ dbg("Cyclic fixed file type");
+ /* increment to next byte */
+ ptr_data++;
+ /* data coding byte - value 21 */
+ ptr_data++;
+ /* 2bytes */
+ memcpy(&record_len, ptr_data, 2);
+ /* swap bytes */
+ ATMODEM_SWAP_BYTES_16(record_len);
+ ptr_data = ptr_data + 2;
+ num_of_records = *ptr_data++;
+ file_type = ATMODEM_SIM_FILE_TYPE_CYCLIC;
+ break;
+
+ default:
+ dbg("not handled file type [0x%x]", *ptr_data);
+ break;
+ }
+ } else {
+ dbg("INVALID FCP received - DEbug!");
+ tcore_at_tok_free(tokens);
+ g_free(record_data);
+ return;
+ }
+
+ /*File identifier - 0x84,0x85,0x86 etc are currently ignored and not handled */
+ if (*ptr_data == 0x83) {
+ /* increment to next byte */
+ ptr_data++;
+ file_id_len = *ptr_data++;
+ dbg("file_id_len: %02x", file_id_len);
+
+ memcpy(&file_id, ptr_data, file_id_len);
+ dbg("file_id: %x", file_id);
+
+ /* swap bytes */
+ ATMODEM_SWAP_BYTES_16(file_id);
+ dbg("file_id: %x", file_id);
+
+ ptr_data = ptr_data + 2;
+ dbg("Getting FileID=[0x%x]", file_id);
+ } else {
+ dbg("INVALID FCP received - DEbug!");
+ tcore_at_tok_free(tokens);
+ g_free(record_data);
+ return;
+ }
+
+ /* proprietary information */
+ if (*ptr_data == 0xA5) {
+ unsigned short prop_len;
+ /* increment to next byte */
+ ptr_data++;
+
+ /* length */
+ prop_len = *ptr_data;
+ dbg("prop_len: %02x", prop_len);
+
+ /* skip data */
+ ptr_data = ptr_data + prop_len + 1;
+ } else {
+ dbg("INVALID FCP received - DEbug!");
+ }
+
+ /* life cycle status integer [8A][length:0x01][status]*/
+ /*
+ status info b8~b1
+ 00000000 : No information given
+ 00000001 : creation state
+ 00000011 : initialization state
+ 000001-1 : operation state -activated
+ 000001-0 : operation state -deactivated
+ 000011-- : Termination state
+ b8~b5 !=0, b4~b1=X : Proprietary
+ Any other value : RFU
+ */
+ if (*ptr_data == 0x8A) {
+ /* increment to next byte */
+ ptr_data++;
+ /* length - value 1 */
+ ptr_data++;
+
+ switch (*ptr_data) {
+ case 0x04:
+ case 0x06:
+ dbg("<RX> operation state -deactivated");
+ ptr_data++;
+ break;
+
+ case 0x05:
+ case 0x07:
+ dbg("<RX> operation state -activated");
+ ptr_data++;
+ break;
+
+ default:
+ dbg("<RX> DEBUG! LIFE CYCLE STATUS =[0x%x]", *ptr_data);
+ ptr_data++;
+ break;
+ }
+ }
+
+ /* related to security attributes : currently not handled*/
+ if (*ptr_data == 0x86 || *ptr_data == 0x8B || *ptr_data == 0x8C || *ptr_data == 0xAB) {
+ /* increment to next byte */
+ ptr_data++;
+ /* if tag length is 3 */
+ if (*ptr_data == 0x03) {
+ /* increment to next byte */
+ ptr_data++;
+ /* EFARR file id */
+ memcpy(&arr_file_id, ptr_data, 2);
+ /* swap byes */
+ ATMODEM_SWAP_BYTES_16(arr_file_id);
+ ptr_data = ptr_data + 2;
+ arr_file_id_rec_num = *ptr_data++;
+ dbg("arr_file_id_rec_num:[%d]", arr_file_id_rec_num);
+ } else {
+ /* if tag length is not 3 */
+ /* ignoring bytes */
+ // ptr_data = ptr_data + 4;
+ dbg("Useless security attributes, so jump to next tag");
+ ptr_data = ptr_data + (*ptr_data + 1);
+ }
+ } else {
+ dbg("INVALID FCP received[0x%x] - DEbug!", *ptr_data);
+ tcore_at_tok_free(tokens);
+ g_free(record_data);
+ return;
+ }
+
+ dbg("Current ptr_data value is [%x]", *ptr_data);
+
+ /* file size excluding structural info*/
+ if (*ptr_data == 0x80) {
+ /* for EF file size is body of file and for Linear or cyclic it is
+ * number of recXsizeof(one record)
+ */
+ /* increment to next byte */
+ ptr_data++;
+ /* length is 1 byte - value is 2 bytes or more */
+ ptr_data++;
+ memcpy(&file_size, ptr_data, 2);
+ /* swap bytes */
+ ATMODEM_SWAP_BYTES_16(file_size);
+ ptr_data = ptr_data + 2;
+ } else {
+ dbg("INVALID FCP received - DEbug!");
+ tcore_at_tok_free(tokens);
+ g_free(record_data);
+ return;
+ }
+
+ /* total file size including structural info*/
+ if (*ptr_data == 0x81) {
+ int len;
+ /* increment to next byte */
+ ptr_data++;
+ /* length */
+ len = *ptr_data;
+ dbg("len:[%d]", len);
+ /* ignored bytes */
+ ptr_data = ptr_data + 3;
+ } else {
+ dbg("INVALID FCP received - DEbug!");
+ /* 0x81 is optional tag?? check out! so do not return -1 from here! */
+ }
+ /*short file identifier ignored*/
+ if (*ptr_data == 0x88) {
+ dbg("0x88: Do Nothing");
+ /*DO NOTHING*/
+ }
+ } else {
+ dbg("INVALID FCP received - DEbug!");
+ tcore_at_tok_free(tokens);
+ g_free(record_data);
+ return;
+ }
+ } else if (TEL_SIM_CARD_TYPE_GSM == card_type) {
+ unsigned char gsm_specific_file_data_len = 0;
+ /* ignore RFU byte1 and byte2 */
+ ptr_data++;
+ ptr_data++;
+ /* file size */
+ // file_size = p_info->response_len;
+ memcpy(&file_size, ptr_data, 2);
+ /* swap bytes */
+ ATMODEM_SWAP_BYTES_16(file_size);
+ /* parsed file size */
+ ptr_data = ptr_data + 2;
+ /* file id */
+ memcpy(&file_id, ptr_data, 2);
+ ATMODEM_SWAP_BYTES_16(file_id);
+ dbg("FILE id --> [%x]", file_id);
+ ptr_data = ptr_data + 2;
+ /* save file type - transparent, linear fixed or cyclic */
+ file_type_tag = (*(ptr_data + 7));
+
+ switch (*ptr_data) {
+ case 0x0:
+ /* RFU file type */
+ dbg("RFU file type- not handled - Debug!");
+ break;
+
+ case 0x1:
+ /* MF file type */
+ dbg("MF file type - not handled - Debug!");
+ break;
+
+ case 0x2:
+ /* DF file type */
+ dbg("DF file type - not handled - Debug!");
+ break;
+
+ case 0x4:
+ /* EF file type */
+ dbg("EF file type [%d] ", file_type_tag);
+ /* increment to next byte */
+ ptr_data++;
+
+ if (file_type_tag == 0x00 || file_type_tag == 0x01) {
+ /* increament to next byte as this byte is RFU */
+ ptr_data++;
+ file_type =
+ (file_type_tag == 0x00) ? ATMODEM_SIM_FILE_TYPE_TRANSPARENT : ATMODEM_SIM_FILE_TYPE_LINEAR_FIXED;
+ } else {
+ /* increment to next byte */
+ ptr_data++;
+ /* For a cyclic EF all bits except bit 7 are RFU; b7=1 indicates that */
+ /* the INCREASE command is allowed on the selected cyclic file. */
+ file_type = ATMODEM_SIM_FILE_TYPE_CYCLIC;
+ }
+ /* bytes 9 to 11 give SIM file access conditions */
+ ptr_data++;
+ /* byte 10 has one nibble that is RF U and another for INCREASE which is not used currently */
+ ptr_data++;
+ /* byte 11 is invalidate and rehabilate nibbles */
+ ptr_data++;
+ /* byte 12 - file status */
+ ptr_data++;
+ /* byte 13 - GSM specific data */
+ gsm_specific_file_data_len = *ptr_data;
+ dbg("gsm_specific_file_data_len:[%d]", gsm_specific_file_data_len);
+ ptr_data++;
+ /* byte 14 - structure of EF - transparent or linear or cyclic , already saved above */
+ ptr_data++;
+ /* byte 15 - length of record for linear and cyclic , for transparent it is set to 0x00. */
+ record_len = *ptr_data;
+ dbg("record length[%d], file size[%d]", record_len, file_size);
+ if (record_len != 0)
+ num_of_records = (file_size / record_len);
+
+ dbg("Number of records [%d]", num_of_records);
+ break;
+
+ default:
+ dbg("not handled file type");
+ break;
+ }
+ } else {
+ err("Unknown Card Type - [%d]", card_type);
+ }
+
+ dbg("req ef[0x%x] resp ef[0x%x] size[%ld] Type[0x%x] "\
+ "NumOfRecords[%ld] RecordLen[%ld]",
+ file_meta->file_id, file_id, file_size,
+ file_type, num_of_records, record_len);
+
+ file_meta->file_type = file_type;
+ file_meta->data_size = file_size;
+ file_meta->rec_length = record_len;
+ file_meta->rec_count = num_of_records;
+ file_meta->current_index = 0; /* reset for new record type EF */
+ sim_result = TEL_SIM_RESULT_SUCCESS;
+ g_free(record_data);
+ } else {
+ /*2. SIM access fail case*/
+ err("Failed to get ef[0x%x] (file_meta->file_id) ", file_meta->file_id);
+ sim_result = __atmodem_sim_decode_status_word(sw1, sw2);
+ }
+
+ tcore_at_tok_free(tokens);
+ } else {
+ err("RESPONSE NOK");
+ err("Failed to get ef[0x%x] (file_meta->file_id)",
+ file_meta->file_id);
+ sim_result = TEL_SIM_RESULT_FAILURE;
+ }
+
+ dbg("Calling __atmodem_sim_next_from_get_response");
+ __atmodem_sim_next_from_get_response(co, resp_cb_data, sim_result);
+ dbg("Exit");
+}
+
+#if 0 //blocking for the moment
+static TelReturn __atmodem_sim_update_file(CoreObject *co,
+ AtmodemRespCbData *resp_cb_data,
+ int cmd, TelSimFileId ef,
+ int p1, int p2, int p3, char *encoded_data)
+{
+ char *cmd_str = NULL;
+ TelReturn ret = TEL_RETURN_FAILURE;
+ AtmodemSimMetaInfo *file_meta =
+ (AtmodemSimMetaInfo *)ATMODEM_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
+
+ dbg("Entry File-id:[0x%02x]", file_meta->file_id);
+
+ cmd_str = g_strdup_printf("AT+CRSM=%d,%d,%d,%d,%d,\"%s\"",
+ cmd, ef, p1, p2, p3, encoded_data);
+
+ ret = tcore_at_prepare_and_send_request(co,
+ cmd_str, "+CRSM:",
+ TCORE_AT_COMMAND_TYPE_SINGLELINE,
+ TCORE_PENDING_PRIORITY_DEFAULT,
+ NULL,
+ __on_response_atmodem_sim_update_file, resp_cb_data,
+ on_send_atmodem_request, NULL,
+ 0, NULL, NULL);
+ ATMODEM_CHECK_REQUEST_RET(ret, resp_cb_data, "Update SIM File");
+
+ tcore_free(encoded_data);
+ g_free(cmd_str);
+
+ dbg("Exit");
+ return ret;
+}
+#endif
+
+static void __atmodem_sim_read_record(CoreObject *co,
+ AtmodemRespCbData *resp_cb_data)
+{
+ gchar *at_cmd = NULL;
+ int p1 = 0;
+ int p2 = 0;
+ int p3 = 0;
+ AtmodemSimMetaInfo *file_meta = (AtmodemSimMetaInfo *)ATMODEM_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
+ TelReturn ret = TEL_RETURN_FAILURE;
+
+ dbg("Entry File-id:[0x%02x]", file_meta->file_id);
+
+ /* According to TS 102 221, values of p1, p2, p3 can be as below:
+ * 11.1.5 READ RECORD
+ * P1: Record number
+ * P2: Mode, see table 11.11
+ * Lc: Not present
+ * Data: Not present
+ * Le: Number of bytes to be read (P3)
+ */
+
+ p1 = (unsigned char) file_meta->current_index;
+ p2 = (unsigned char) 0x04; /* 0x4 for absolute mode */
+ p3 = (unsigned char) file_meta->rec_length;
+
+ at_cmd = g_strdup_printf("AT+CRSM=%d, %d, %d, %d, %d",
+ ATMODEM_SIM_ACCESS_READ_RECORD, file_meta->file_id, p1, p2, p3);
+
+ ret = tcore_at_prepare_and_send_request(co, at_cmd, "+CRSM:",
+ TCORE_AT_COMMAND_TYPE_SINGLELINE,
+ TCORE_PENDING_PRIORITY_DEFAULT, NULL,
+ __on_response_atmodem_sim_read_data, resp_cb_data,
+ on_send_atmodem_request, NULL, 0, NULL, NULL);
+
+ ATMODEM_CHECK_REQUEST_RET(ret, resp_cb_data, "Get File Record");
+
+ dbg("ret:[%d]", ret);
+ g_free(at_cmd);
+
+ dbg("Exit");
+}
+
+static void __atmodem_sim_read_binary(CoreObject *co, AtmodemRespCbData *resp_cb_data)
+{
+ gchar *at_cmd = NULL;
+ int p1 = 0;
+ int p2 = 0;
+ int p3 = 0;
+ int offset = 0;
+ AtmodemSimMetaInfo *file_meta = (AtmodemSimMetaInfo *)ATMODEM_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
+ TelReturn ret = TEL_RETURN_FAILURE;
+
+ dbg("Entry File-id:[0x%02x]", file_meta->file_id);
+
+ /* According to TS 102 221, values of P1, P2, P3 can be as below:
+ * 11.1.3 READ BINARY
+ * P1: See table 11.10
+ * P2: Offset low
+ * Lc: Not present
+ * Data: Not present
+ * Le: Number of bytes to be read (P3)
+ */
+
+ p1 = (unsigned char) (offset & 0xFF00) >> 8;
+ p2 = (unsigned char) offset & 0x00FF; /* offset low */
+ p3 = (unsigned char) file_meta->data_size;
+
+ at_cmd = g_strdup_printf("AT+CRSM=%d, %d, %d, %d, %d",
+ ATMODEM_SIM_ACCESS_READ_BINARY, file_meta->file_id, p1, p2, p3);
+
+ ret = tcore_at_prepare_and_send_request(co, at_cmd, "+CRSM:",
+ TCORE_AT_COMMAND_TYPE_SINGLELINE,
+ TCORE_PENDING_PRIORITY_DEFAULT, NULL,
+ __on_response_atmodem_sim_read_data, resp_cb_data,
+ on_send_atmodem_request, NULL, 0, NULL, NULL);
+
+ ATMODEM_CHECK_REQUEST_RET(ret, resp_cb_data, "Get File Data");
+
+ dbg("ret:[%d]", ret);
+ g_free(at_cmd);
+
+ dbg("Exit");
+}
+
+static TelReturn __atmodem_sim_get_response(CoreObject *co, AtmodemRespCbData *resp_cb_data)
+{
+ gchar *at_cmd = NULL;
+ AtmodemSimMetaInfo *file_meta =
+ (AtmodemSimMetaInfo *)ATMODEM_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
+ TelReturn ret = TEL_RETURN_FAILURE;
+
+ dbg("Entry File-id:[0x%02x]", file_meta->file_id);
+
+ at_cmd = g_strdup_printf("AT+CRSM=%d, %d",
+ ATMODEM_SIM_ACCESS_GET_RESPONSE, file_meta->file_id);
+
+ ret = tcore_at_prepare_and_send_request(co,
+ at_cmd, "+CRSM:",
+ TCORE_AT_COMMAND_TYPE_SINGLELINE,
+ TCORE_PENDING_PRIORITY_DEFAULT, NULL,
+ __on_response_atmodem_sim_get_response, resp_cb_data,
+ on_send_atmodem_request, NULL,
+ 0, NULL, NULL);
+ ATMODEM_CHECK_REQUEST_RET(ret, resp_cb_data, "Get File Info");
+
+ g_free(at_cmd);
+ dbg("Exit");
+ return ret;
+}
+
+static int __atmodem_sim_get_lock_type(AtmodemSimCurrSecOp sec_op)
+{
+ switch(sec_op) {
+ case ATMODEM_SIM_CURR_SEC_OP_SIM_DISABLE :
+ case ATMODEM_SIM_CURR_SEC_OP_SIM_ENABLE :
+ case ATMODEM_SIM_CURR_SEC_OP_SIM_STATUS :
+ return TEL_SIM_LOCK_PS;
+ case ATMODEM_SIM_CURR_SEC_OP_PIN1_DISABLE :
+ case ATMODEM_SIM_CURR_SEC_OP_PIN1_ENABLE :
+ case ATMODEM_SIM_CURR_SEC_OP_PIN1_STATUS :
+ return TEL_SIM_LOCK_SC;
+ case ATMODEM_SIM_CURR_SEC_OP_FDN_DISABLE :
+ case ATMODEM_SIM_CURR_SEC_OP_FDN_ENABLE :
+ case ATMODEM_SIM_CURR_SEC_OP_FDN_STATUS :
+ return TEL_SIM_LOCK_FD;
+ case ATMODEM_SIM_CURR_SEC_OP_NET_DISABLE :
+ case ATMODEM_SIM_CURR_SEC_OP_NET_ENABLE :
+ case ATMODEM_SIM_CURR_SEC_OP_NET_STATUS :
+ return TEL_SIM_LOCK_PN;
+ case ATMODEM_SIM_CURR_SEC_OP_NS_DISABLE :
+ case ATMODEM_SIM_CURR_SEC_OP_NS_ENABLE :
+ case ATMODEM_SIM_CURR_SEC_OP_NS_STATUS :
+ return TEL_SIM_LOCK_PU;
+ case ATMODEM_SIM_CURR_SEC_OP_SP_DISABLE :
+ case ATMODEM_SIM_CURR_SEC_OP_SP_ENABLE :
+ case ATMODEM_SIM_CURR_SEC_OP_SP_STATUS :
+ return TEL_SIM_LOCK_PP;
+ case ATMODEM_SIM_CURR_SEC_OP_CP_DISABLE :
+ case ATMODEM_SIM_CURR_SEC_OP_CP_ENABLE :
+ case ATMODEM_SIM_CURR_SEC_OP_CP_STATUS :
+ return TEL_SIM_LOCK_PC ;
+ default :
+ err("Invalid sec op [%d]", sec_op);
+ return -1;
+ }
+}
+
+/* Notifications */
+/*
+ * Notification: +SCSIM: <SIM state>
+ *
+ * Possible values of <SIM state> can be
+ * 0 SIM not present
+ * 1 PIN verification needed
+ * 2 PIN verification not needed - Ready
+ * 3 PIN verified - Ready
+ * 4 PUK verification needed
+ * 5 SIM permanently blocked
+ * 6 SIM Error
+ * 7 ready for attach (+COPS)
+ * 8 SIM Technical Problem
+ * 9 SIM Removed
+ * 10 SIM Reactivating
+ * 11 SIM Reactivated
+ * 12 SIM SMS Caching Completed. (Sent only when SMS caching enabled)
+ * 99 SIM State Unknown
+ */
+static gboolean on_notification_atmodem_sim_status(CoreObject *co,
+ const void *event_info, void *user_data)
+{
+ GSList *lines = (GSList *)event_info;
+ const gchar *line = (const gchar *)lines->data;
+ TelSimCardStatus sim_status = TEL_SIM_STATUS_SIM_INITIALIZING;
+ AtmodemSimSecLockType locktype = SEC_LOCK_TYPE_NONE;
+ AtmodemSimSecLockKey lockkey = SEC_LOCK_KEY_NONE;
+
+ if (__atmodem_convert_scpin_str_to_enum((char *)line, &locktype, &lockkey) == FALSE)
+ return TRUE;
+
+ switch (locktype) {
+ case SEC_LOCK_TYPE_READY:
+ if (lockkey == SEC_LOCK_KEY_UNLOCKED)
+ sim_status = TEL_SIM_STATUS_SIM_INITIALIZING;
+ else
+ sim_status = TEL_SIM_STATUS_UNKNOWN;
+ break;
+
+ case SEC_LOCK_TYPE_PS:
+ sim_status = TEL_SIM_STATUS_SIM_LOCK_REQUIRED;
+ break;
+
+ case SEC_LOCK_TYPE_PF:
+ sim_status = TEL_SIM_STATUS_CARD_ERROR;
+ break;
+
+ case SEC_LOCK_TYPE_SC:
+ switch (lockkey) {
+ case SEC_LOCK_KEY_UNLOCKED:
+ break;
+
+ case SEC_LOCK_KEY_PIN:
+ sim_status = TEL_SIM_STATUS_SIM_PIN_REQUIRED;
+ break;
+
+ case SEC_LOCK_KEY_PUK:
+ sim_status = TEL_SIM_STATUS_SIM_PUK_REQUIRED;
+ break;
+
+ case SEC_LOCK_KEY_PERM_BLOCKED:
+ sim_status = TEL_SIM_STATUS_CARD_BLOCKED;
+ break;
+
+ default:
+ err("Not handled SEC Lock key: [%d]", lockkey);
+ sim_status = TEL_SIM_STATUS_UNKNOWN;
+ break;
+ }
+ break;
+
+ case SEC_LOCK_TYPE_FD:
+ break;
+
+ case SEC_LOCK_TYPE_PN:
+ if (SEC_LOCK_KEY_PIN)
+ sim_status = TEL_SIM_STATUS_SIM_NCK_REQUIRED;
+ else
+ sim_status = TEL_SIM_STATUS_UNKNOWN;
+ break;
+
+ case SEC_LOCK_TYPE_PU:
+ if (SEC_LOCK_KEY_PIN)
+ sim_status = TEL_SIM_STATUS_SIM_NSCK_REQUIRED;
+ else
+ sim_status = TEL_SIM_STATUS_UNKNOWN;
+ break;
+
+ case SEC_LOCK_TYPE_PP:
+ if (SEC_LOCK_KEY_PIN)
+ sim_status = TEL_SIM_STATUS_SIM_SPCK_REQUIRED;
+ else
+ sim_status = TEL_SIM_STATUS_UNKNOWN;
+ break;
+
+ case SEC_LOCK_TYPE_PC:
+ if (SEC_LOCK_KEY_PIN)
+ sim_status = TEL_SIM_STATUS_SIM_CCK_REQUIRED;
+ else
+ sim_status = TEL_SIM_STATUS_UNKNOWN;
+ break;
+
+ case SEC_LOCK_TYPE_SC2:
+ case SEC_LOCK_TYPE_PUK2:
+ break;
+
+ case SEC_LOCK_TYPE_NO_SIM:
+ sim_status = TEL_SIM_STATUS_CARD_NOT_PRESENT;
+ break;
+
+ case SEC_LOCK_TYPE_UNAVAIL:
+ case SEC_SIM_INIT_CRASH:
+ sim_status = TEL_SIM_STATUS_CARD_ERROR;
+ break;
+
+ case SEC_SIM_INIT_COMPLETED:
+ sim_status = TEL_SIM_STATUS_SIM_INIT_COMPLETED;
+ break;
+
+ case SEC_PB_INIT_COMPLETED:
+ break;
+
+ default:
+ err("Not handled SEC lock type: [%d]", locktype);
+ sim_status = TEL_SIM_STATUS_UNKNOWN;
+ break;
+ }
+
+ __atmodem_sim_process_sim_status(co, sim_status);
+
+ return TRUE;
+}
+
+/* Response Functions */
+static void on_response_atmodem_sim_verify_pins(TcorePending *p,
+ guint data_len, const void *data, void *user_data)
+{
+ const TcoreAtResponse *at_resp = data;
+ AtmodemRespCbData *resp_cb_data = user_data;
+ CoreObject *co_sim = tcore_pending_ref_core_object(p);
+ TelSimResult result = TEL_SIM_RESULT_FAILURE;
+ AtmodemSimCurrSecOp *sec_op = NULL;
+ TelSimSecPinResult verify_pin_resp = {0, };
+
+ dbg("Entry");
+
+ tcore_check_return_assert(co_sim != NULL);
+ tcore_check_return_assert(resp_cb_data != NULL);
+
+ sec_op = (AtmodemSimCurrSecOp *)ATMODEM_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
+
+ if (*sec_op == ATMODEM_SIM_CURR_SEC_OP_PIN1_VERIFY) {
+ TelSimCardStatus status;
+
+ verify_pin_resp.pin_type = TEL_SIM_PIN_TYPE_PIN1;
+
+ tcore_sim_get_status(co_sim, &status);
+ if (status != TEL_SIM_STATUS_SIM_INIT_COMPLETED) {
+ /*Update sim status*/
+ __atmodem_sim_update_sim_status(co_sim,
+ TEL_SIM_STATUS_SIM_INITIALIZING);
+ }
+ } else if (*sec_op == ATMODEM_SIM_CURR_SEC_OP_PIN2_VERIFY) {
+ verify_pin_resp.pin_type = TEL_SIM_PIN_TYPE_PIN2;
+ }
+
+ if (at_resp && at_resp->success) {
+ dbg("SIM Verify Pin Response- [OK]");
+ result = TEL_SIM_RESULT_SUCCESS;
+
+ } else {
+ err("SIM Verify Pin Response- [NOK]");
+
+ /* Update retry count */
+ verify_pin_resp.retry_count = 3;
+ }
+
+ /*Invoke callback*/
+ if (resp_cb_data->cb)
+ resp_cb_data->cb(co_sim, (gint)result,
+ &verify_pin_resp, resp_cb_data->cb_data);
+
+ atmodem_destroy_resp_cb_data(resp_cb_data);
+}
+
+static void on_response_atmodem_sim_verify_puks(TcorePending *p,
+ guint data_len, const void *data, void *user_data)
+{
+ const TcoreAtResponse *at_resp = data;
+ AtmodemRespCbData *resp_cb_data = user_data;
+ CoreObject *co_sim = tcore_pending_ref_core_object(p);
+ TelSimResult result = TEL_SIM_RESULT_FAILURE;
+ AtmodemSimCurrSecOp *sec_op = NULL;
+ TelSimSecPukResult verify_puk_resp = {0, };
+
+ dbg("Entry");
+
+ tcore_check_return_assert(co_sim != NULL);
+ tcore_check_return_assert(resp_cb_data != NULL);
+
+ sec_op = (AtmodemSimCurrSecOp *)ATMODEM_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
+
+ if (*sec_op == ATMODEM_SIM_CURR_SEC_OP_PUK1_VERIFY) {
+ verify_puk_resp.puk_type = TEL_SIM_PUK_TYPE_PUK1;
+ } else if (*sec_op == ATMODEM_SIM_CURR_SEC_OP_PUK2_VERIFY) {
+ verify_puk_resp.puk_type = TEL_SIM_PUK_TYPE_PUK2;
+ }
+ if (at_resp && at_resp->success) {
+ dbg("SIM Verify Puk Response- [OK]");
+ result = TEL_SIM_RESULT_SUCCESS;
+ } else {
+ err("SIM Verify Puk Response- [NOK]");
+
+ /* Update retry count */
+ verify_puk_resp.retry_count = 3;
+ }
+
+ /*Invoke callback*/
+ if (resp_cb_data->cb)
+ resp_cb_data->cb(co_sim, (gint)result,
+ &verify_puk_resp,
+ resp_cb_data->cb_data);
+ atmodem_destroy_resp_cb_data(resp_cb_data);
+}
+
+static void on_response_atmodem_sim_change_pins(TcorePending *p,
+ guint data_len, const void *data, void *user_data)
+{
+ const TcoreAtResponse *at_resp = data;
+ AtmodemRespCbData *resp_cb_data = user_data;
+ CoreObject *co_sim = tcore_pending_ref_core_object(p);
+ TelSimResult result = TEL_SIM_RESULT_FAILURE;
+ AtmodemSimCurrSecOp *sec_op = NULL;
+ TelSimSecPinResult change_pin_resp = {0, };
+
+ dbg("Entry");
+
+ tcore_check_return_assert(co_sim != NULL);
+ tcore_check_return_assert(resp_cb_data != NULL);
+
+ sec_op = (AtmodemSimCurrSecOp *)ATMODEM_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
+
+ if (at_resp && at_resp->success) {
+ dbg("SIM Change Pin Response- [OK]");
+
+ result = TEL_SIM_RESULT_SUCCESS;
+
+ if (*sec_op == ATMODEM_SIM_CURR_SEC_OP_PIN1_CHANGE) {
+ change_pin_resp.pin_type = TEL_SIM_PIN_TYPE_PIN1;
+ } else if (*sec_op == ATMODEM_SIM_CURR_SEC_OP_PIN2_CHANGE) {
+ change_pin_resp.pin_type = TEL_SIM_PIN_TYPE_PIN2;
+ }
+
+ /*Invoke callback*/
+ if (resp_cb_data->cb)
+ resp_cb_data->cb(co_sim, (gint)result,
+ &change_pin_resp, resp_cb_data->cb_data);
+ }
+ atmodem_destroy_resp_cb_data(resp_cb_data);
+}
+
+static void on_response_atmodem_sim_disable_facility(TcorePending *p,
+ guint data_len, const void *data, void *user_data)
+{
+ const TcoreAtResponse *at_resp = data;
+ AtmodemRespCbData *resp_cb_data = user_data;
+ CoreObject *co_sim = tcore_pending_ref_core_object(p);
+ TelSimResult result = TEL_SIM_RESULT_FAILURE;
+ AtmodemSimCurrSecOp *sec_op = NULL;
+ TelSimFacilityResult disable_facility_resp = {0, };
+
+ dbg("Entry");
+
+ tcore_check_return_assert(co_sim != NULL);
+ tcore_check_return_assert(resp_cb_data != NULL);
+
+ sec_op = (AtmodemSimCurrSecOp *)ATMODEM_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
+
+ if (at_resp && at_resp->success) {
+ int lock_type;
+ dbg("SIM Disable Facility Response- [OK]");
+
+ lock_type = __atmodem_sim_get_lock_type(*sec_op);
+ if (lock_type == -1) {
+ result = TEL_SIM_RESULT_INVALID_PARAMETER;
+
+ /*Invoke callback*/
+ if (resp_cb_data->cb)
+ resp_cb_data->cb(co_sim, (gint)result,
+ NULL, resp_cb_data->cb_data);
+ atmodem_destroy_resp_cb_data(resp_cb_data);
+ return;
+ }
+
+ disable_facility_resp.type = lock_type;
+ result = TEL_SIM_RESULT_SUCCESS;
+
+ /*Invoke callback*/
+ if (resp_cb_data->cb)
+ resp_cb_data->cb(co_sim, (gint)result,
+ &disable_facility_resp, resp_cb_data->cb_data);
+ }
+
+ atmodem_destroy_resp_cb_data(resp_cb_data);
+}
+
+static void on_response_atmodem_sim_enable_facility(TcorePending *p,
+ guint data_len, const void *data, void *user_data)
+{
+ const TcoreAtResponse *at_resp = data;
+ AtmodemRespCbData *resp_cb_data = user_data;
+ CoreObject *co_sim = tcore_pending_ref_core_object(p);
+ TelSimResult result = TEL_SIM_RESULT_FAILURE;
+ AtmodemSimCurrSecOp *sec_op = NULL;
+ TelSimFacilityResult enable_facility_resp = {0, };
+
+ dbg("Entry");
+
+ tcore_check_return_assert(co_sim != NULL);
+ tcore_check_return_assert(resp_cb_data != NULL);
+
+ sec_op = (AtmodemSimCurrSecOp *)ATMODEM_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
+
+ if (at_resp && at_resp->success) {
+ int lock_type;
+ dbg("SIM Enable Facility Response- [OK]");
+
+ lock_type = __atmodem_sim_get_lock_type(*sec_op);
+ if (lock_type == -1) {
+ result = TEL_SIM_RESULT_INVALID_PARAMETER;
+
+ /*Invoke callback*/
+ if (resp_cb_data->cb)
+ resp_cb_data->cb(co_sim, (gint)result,
+ NULL, resp_cb_data->cb_data);
+ atmodem_destroy_resp_cb_data(resp_cb_data);
+ return;
+ }
+
+ enable_facility_resp.type = lock_type;
+ result = TEL_SIM_RESULT_SUCCESS;
+
+ /*Invoke callback*/
+ if (resp_cb_data->cb)
+ resp_cb_data->cb(co_sim, (gint)result,
+ &enable_facility_resp,
+ resp_cb_data->cb_data);
+ }
+ atmodem_destroy_resp_cb_data(resp_cb_data);
+}
+
+static void on_response_atmodem_sim_get_facility(TcorePending *p, guint data_len,
+ const void *data, void *user_data)
+{
+ const TcoreAtResponse *at_resp = data;
+ AtmodemRespCbData *resp_cb_data = user_data;
+ CoreObject *co_sim = tcore_pending_ref_core_object(p);
+ TelSimResult result = TEL_SIM_RESULT_FAILURE;
+ AtmodemSimCurrSecOp *sec_op = NULL;
+ TelSimFacilityInfo get_facility_resp = {0, };
+
+ dbg("Entry");
+
+ tcore_check_return_assert(co_sim != NULL);
+ tcore_check_return_assert(resp_cb_data != NULL);
+
+ sec_op = (AtmodemSimCurrSecOp *)ATMODEM_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
+
+ if (at_resp && at_resp->success) {
+ GSList *tokens = NULL;
+ const char *line;
+ int lock_type;
+
+ dbg("SIM Get Facility Response- [OK]");
+
+ lock_type = __atmodem_sim_get_lock_type(*sec_op);
+ if (lock_type == -1) {
+ result = TEL_SIM_RESULT_INVALID_PARAMETER;
+ goto out;
+ }
+ if (at_resp->lines) {
+ line = (const char *)at_resp->lines->data;
+ tokens = tcore_at_tok_new(line);
+ if (g_slist_length(tokens) != 1) {
+ err("Invalid message");
+ tcore_at_tok_free(tokens);
+ goto out;
+ }
+ get_facility_resp.f_status = atoi(g_slist_nth_data(tokens, 0));
+ get_facility_resp.type = lock_type;
+ result = TEL_SIM_RESULT_SUCCESS;
+ }
+
+ tcore_at_tok_free(tokens);
+ } else {
+ err("SIM Get Facility Response- [NOK]");
+ }
+out:
+ /* Invoke callback */
+ if (resp_cb_data->cb)
+ resp_cb_data->cb(co_sim, (gint)result, &get_facility_resp, resp_cb_data->cb_data);
+ atmodem_destroy_resp_cb_data(resp_cb_data);
+}
+
+/* SIM Operations */
+/*
+ * Operation - get_imsi
+ *
+ * Request -
+ * AT-Command: AT+CRSM= <command>[,<fileid>[,<P1>,<P2>,<P3>[,<data>[,<pathid>]]]]
+ * where,
+ * <command>
+ * 176 READ BINARY
+ * 178 READ RECORD
+ * 192 GET RESPONSE
+ * 214 UPDATE BINARY
+ * 220 UPDATE RECORD
+ * 242 STATUS
+ *
+ * <fileid>
+ * 28423 meaning IMSI file (6F07)
+ * 28473 meaning ACM file (6F39)
+ * 28481 meaning PUKT file (6F41)
+ * 28482 meaning SMS file (6F42)
+ *
+ * <P1>, <P2>, <P3>
+ * Integer type defining the request.
+ * These parameters are mandatory for every command, except GET RESPONSE and STATUS.
+ *
+ * <data>
+ * Information which shall be written to the SIM
+ *
+ * <pathid>
+ * String type, contains the path of an elementary file on the SIM/USIM in hexadecimal format
+ *
+ * <status>
+ * 0 not active
+ * 1 active
+ *
+ * Success:
+ * OK
+ * +CRSM: <sw1>,<sw2>[,<response>]
+ *
+ * <sw1>, <sw2>
+ * Integer type containing the SIM information
+ *
+ * <response>
+ * Response of successful completion of the command previously issued
+ *
+ * Failure:
+ * +CME ERROR: <error>
+ */
+static TelReturn atmodem_sim_get_imsi (CoreObject *co,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ AtmodemSimMetaInfo file_meta = {0, };
+ AtmodemRespCbData *resp_cb_data = NULL;
+
+ dbg("Entry");
+
+ file_meta.file_id = TEL_SIM_EF_IMSI;
+ file_meta.file_result = TEL_SIM_RESULT_FAILURE;
+ file_meta.req_command = TCORE_COMMAND_SIM_GET_IMSI;
+
+ resp_cb_data = atmodem_create_resp_cb_data(cb, cb_data,
+ &file_meta, sizeof(AtmodemSimMetaInfo));
+
+ return __atmodem_sim_get_file_info(co, resp_cb_data);
+}
+
+/*
+ * Operation - verify_pins/verify_puks/change_pins
+ *
+ * Request -
+ * For SIM PIN
+ * AT-Command: AT+CPIN= <pin> [, <newpin>]
+ * where,
+ * <pin>, <newpin>
+ * String type values
+ *
+ * For SIM PIN2
+ * AT-Command: AT+CPIN2= <puk2/oldpin2> [, <newpin2>]andAT+CPIN2=<oldpin2>
+ * where,
+ * <puk2/pin2>, <newpin2>
+ * String type values
+ *
+ * Success:
+ * OK
+ *
+ * Failure:
+ * +CME ERROR: <error>
+ */
+static TelReturn atmodem_sim_verify_pins(CoreObject *co,
+ const TelSimSecPinPw *request,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ TelReturn ret = TEL_RETURN_FAILURE;
+ AtmodemRespCbData *resp_cb_data = NULL;
+ AtmodemSimCurrSecOp sec_op;
+ gchar *cmd_str = NULL;
+
+ dbg("Entry");
+
+ if (request->pin_type == TEL_SIM_PIN_TYPE_PIN1) {
+ sec_op = ATMODEM_SIM_CURR_SEC_OP_PIN1_VERIFY;
+ } else if (request->pin_type == TEL_SIM_PIN_TYPE_PIN2) {
+ sec_op = ATMODEM_SIM_CURR_SEC_OP_PIN2_VERIFY;
+ } else {
+ err("Invalid pin type [%d]", request->pin_type);
+ return TEL_RETURN_INVALID_PARAMETER;
+ }
+
+ cmd_str = g_strdup_printf("AT+CPIN=\"%s\"", request->pw);
+
+ resp_cb_data = atmodem_create_resp_cb_data(cb, cb_data,
+ &sec_op, sizeof(sec_op));
+
+ ret = tcore_at_prepare_and_send_request(co,
+ cmd_str, NULL,
+ TCORE_AT_COMMAND_TYPE_NO_RESULT,
+ TCORE_PENDING_PRIORITY_DEFAULT,
+ NULL,
+ on_response_atmodem_sim_verify_pins, resp_cb_data,
+ on_send_atmodem_request, NULL,
+ 0, NULL, NULL);
+ ATMODEM_CHECK_REQUEST_RET(ret, resp_cb_data, "SIM Verify PIN");
+
+ g_free(cmd_str);
+ return ret;
+}
+
+static TelReturn atmodem_sim_verify_puks(CoreObject *co,
+ const TelSimSecPukPw *request,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ TelReturn ret = TEL_RETURN_FAILURE;
+ AtmodemRespCbData *resp_cb_data = NULL;
+ AtmodemSimCurrSecOp sec_op;
+ gchar *cmd_str = NULL;
+
+ dbg("Entry");
+
+ if (request->puk_type == TEL_SIM_PUK_TYPE_PUK1) {
+ sec_op = ATMODEM_SIM_CURR_SEC_OP_PUK1_VERIFY;
+ } else if (request->puk_type == TEL_SIM_PUK_TYPE_PUK2) {
+ sec_op = ATMODEM_SIM_CURR_SEC_OP_PUK2_VERIFY;
+ } else {
+ err("Invalid puk type [%d]", request->puk_type);
+ return TEL_RETURN_INVALID_PARAMETER;
+ }
+
+ cmd_str = g_strdup_printf("AT+CPIN=\"%s\", \"%s\"",
+ request->puk_pw, request->new_pin_pw);
+
+ resp_cb_data = atmodem_create_resp_cb_data(cb, cb_data,
+ &sec_op, sizeof(sec_op));
+
+ ret = tcore_at_prepare_and_send_request(co,
+ cmd_str, NULL,
+ TCORE_AT_COMMAND_TYPE_NO_RESULT,
+ TCORE_PENDING_PRIORITY_DEFAULT,
+ NULL,
+ on_response_atmodem_sim_verify_puks, resp_cb_data,
+ on_send_atmodem_request, NULL,
+ 0, NULL, NULL);
+ ATMODEM_CHECK_REQUEST_RET(ret, resp_cb_data, "SIM Verify PUK");
+
+ g_free(cmd_str);
+ return ret;
+}
+
+static TelReturn atmodem_sim_change_pins(CoreObject *co,
+ const TelSimSecChangePinPw *request,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ TelReturn ret = TEL_RETURN_FAILURE;
+ AtmodemRespCbData *resp_cb_data = NULL;
+ AtmodemSimCurrSecOp sec_op;
+ gchar *cmd_str = NULL;
+
+ dbg("Entry");
+
+ if (request->pin_type == TEL_SIM_PIN_TYPE_PIN1) {
+ sec_op = ATMODEM_SIM_CURR_SEC_OP_PIN1_CHANGE;
+ } else if (request->pin_type == TEL_SIM_PIN_TYPE_PIN2) {
+ sec_op = ATMODEM_SIM_CURR_SEC_OP_PIN2_CHANGE;
+ } else {
+ err("Invalid pin type [%d]", request->pin_type);
+ return TEL_RETURN_INVALID_PARAMETER;
+ }
+
+ cmd_str = g_strdup_printf("AT+CPIN=\"%s\", \"%s\"", request->old_pw, request->new_pw);
+
+ resp_cb_data = atmodem_create_resp_cb_data(cb, cb_data,
+ &sec_op, sizeof(sec_op));
+
+ ret = tcore_at_prepare_and_send_request(co,
+ cmd_str, NULL,
+ TCORE_AT_COMMAND_TYPE_NO_RESULT,
+ TCORE_PENDING_PRIORITY_DEFAULT,
+ NULL,
+ on_response_atmodem_sim_change_pins, resp_cb_data,
+ on_send_atmodem_request, NULL,
+ 0, NULL, NULL);
+ ATMODEM_CHECK_REQUEST_RET(ret, resp_cb_data, "SIM Change PIN");
+
+ g_free(cmd_str);
+ return ret;
+}
+
+/*
+ * Operation - disable_facility/enable_facility/get_facility
+ *
+ * Request -
+ * AT-Command: AT+CLCK = <fac>, <mode> [, <passwd> [, <class>]]
+ * where,
+ * <fac>
+ * SIM facility
+ *
+ * <mode>
+ * 0 unlock
+ * 1 lock
+ * 2 query status
+ *
+ * <passwd>
+ * Password string
+ *
+ * <status>
+ * 0 not active
+ * 1 active
+ *
+ * Success: when <mode>=2:
+ * OK
+ * +CLCK: <status>[,<class1> [<CR><LF>
+ * +CLCK: <status>,<class2> [...]]
+ *
+ * Failure:
+ */
+static TelReturn atmodem_sim_disable_facility(CoreObject *co,
+ const TelSimFacilityPw *request,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ TelReturn ret = TEL_RETURN_FAILURE;
+ AtmodemRespCbData *resp_cb_data = NULL;
+ AtmodemSimCurrSecOp sec_op;
+ gchar *cmd_str = NULL;
+ char *fac = "SC";
+ int mode = 0; /*mode = 0 for disable lock*/
+
+ dbg("Entry");
+
+ fac = __atmodem_sim_get_fac_from_lock_type(request->lock_type,
+ &sec_op, DISABLE_FLAG);
+ if (!fac)
+ return TEL_RETURN_INVALID_PARAMETER;
+
+ cmd_str = g_strdup_printf("AT+CLCK=\"%s\", %d, \"%s\"",
+ fac, mode, request->pw);
+
+ resp_cb_data = atmodem_create_resp_cb_data(cb, cb_data,
+ &sec_op, sizeof(sec_op));
+
+ ret = tcore_at_prepare_and_send_request(co,
+ cmd_str, "+CLCK:",
+ TCORE_AT_COMMAND_TYPE_SINGLELINE,
+ TCORE_PENDING_PRIORITY_DEFAULT,
+ NULL,
+ on_response_atmodem_sim_disable_facility, resp_cb_data,
+ on_send_atmodem_request, NULL,
+ 0, NULL, NULL);
+ ATMODEM_CHECK_REQUEST_RET(ret, resp_cb_data, "SIM Disable Facility");
+
+ g_free(cmd_str);
+ return ret;
+}
+
+static TelReturn atmodem_sim_enable_facility(CoreObject *co,
+ const TelSimFacilityPw *request,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ TelReturn ret = TEL_RETURN_FAILURE;
+ AtmodemRespCbData *resp_cb_data = NULL;
+ AtmodemSimCurrSecOp sec_op;
+ gchar *cmd_str = NULL;
+ char *fac = "SC";
+ int mode = 1; /*mode = 1 for enable lock*/
+
+ dbg("Entry");
+
+ fac = __atmodem_sim_get_fac_from_lock_type(request->lock_type,
+ &sec_op, ENABLE_FLAG);
+ if (!fac)
+ return TEL_RETURN_INVALID_PARAMETER;
+
+ cmd_str = g_strdup_printf("AT+CLCK=\"%s\", %d, \"%s\"",
+ fac, mode, request->pw);
+
+ resp_cb_data = atmodem_create_resp_cb_data(cb, cb_data,
+ &sec_op, sizeof(sec_op));
+
+ ret = tcore_at_prepare_and_send_request(co,
+ cmd_str, "+CLCK:",
+ TCORE_AT_COMMAND_TYPE_SINGLELINE,
+ TCORE_PENDING_PRIORITY_DEFAULT,
+ NULL,
+ on_response_atmodem_sim_enable_facility, resp_cb_data,
+ on_send_atmodem_request, NULL,
+ 0, NULL, NULL);
+ ATMODEM_CHECK_REQUEST_RET(ret, resp_cb_data, "SIM Disable Facility");
+
+ g_free(cmd_str);
+ return ret;
+}
+
+static TelReturn atmodem_sim_get_facility(CoreObject *co,
+ TelSimLockType lock_type,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ TelReturn ret = TEL_RETURN_FAILURE;
+ AtmodemRespCbData *resp_cb_data = NULL;
+ AtmodemSimCurrSecOp sec_op;
+ gchar *cmd_str = NULL;
+ char *fac = "SC";
+ int mode = 2; /*mode = 2 for Get Facility*/
+
+ dbg("Entry");
+
+ fac = __atmodem_sim_get_fac_from_lock_type(lock_type,
+ &sec_op, 0);
+ if (!fac)
+ return TEL_RETURN_INVALID_PARAMETER;
+
+ cmd_str = g_strdup_printf("AT+CLCK=\"%s\", %d", fac, mode);
+
+ resp_cb_data = atmodem_create_resp_cb_data(cb, cb_data,
+ &sec_op, sizeof(sec_op));
+
+ ret = tcore_at_prepare_and_send_request(co,
+ cmd_str, "+CLCK:",
+ TCORE_AT_COMMAND_TYPE_SINGLELINE,
+ TCORE_PENDING_PRIORITY_DEFAULT,
+ NULL,
+ on_response_atmodem_sim_get_facility, resp_cb_data,
+ on_send_atmodem_request, NULL,
+ 0, NULL, NULL);
+ ATMODEM_CHECK_REQUEST_RET(ret, resp_cb_data, "SIM Get Facility");
+
+ g_free(cmd_str);
+ return ret;
+}
+
+/* SIM Operations */
+static TcoreSimOps atmodem_sim_ops = {
+ .get_imsi = atmodem_sim_get_imsi,
+ .get_ecc = NULL,
+ .get_iccid = NULL,
+ .get_language = NULL,
+ .set_language = NULL,
+ .get_callforwarding_info = NULL,
+ .get_messagewaiting_info = NULL,
+ .set_messagewaiting_info = NULL,
+ .get_mailbox_info = NULL,
+ .set_mailbox_info = NULL,
+ .get_msisdn = NULL,
+ .get_spn = NULL,
+ .get_cphs_netname = NULL,
+ .get_sp_display_info = NULL,
+ .req_authentication = NULL,
+ .verify_pins = atmodem_sim_verify_pins,
+ .verify_puks = atmodem_sim_verify_puks,
+ .change_pins = atmodem_sim_change_pins,
+ .disable_facility = atmodem_sim_disable_facility,
+ .enable_facility = atmodem_sim_enable_facility,
+ .get_facility = atmodem_sim_get_facility,
+ .get_lock_info = NULL,
+ .req_apdu = NULL,
+ .req_atr = NULL
+};
+
+gboolean atmodem_sim_init(TcorePlugin *p, CoreObject *co_sim)
+{
+ dbg("Entry");
+
+ /* Set operations */
+ tcore_sim_set_ops(co_sim, &atmodem_sim_ops);
+
+ /* Add Callbacks */
+ tcore_object_add_callback(co_sim, "\%SCSIM:",
+ on_notification_atmodem_sim_status, NULL);
+
+ dbg("Exit");
+ return TRUE;
+}
+
+void atmodem_sim_exit(TcorePlugin *plugin, CoreObject *co_sim)
+{
+ dbg("Entry");
+}
--- /dev/null
+/*
+ * tel-plugin-atmodem
+ *
+ * Copyright (c) 2013 Samsung Electronics Co. Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <glib.h>
+
+#include <tcore.h>
+#include <server.h>
+#include <plugin.h>
+#include <core_object.h>
+#include <hal.h>
+#include <queue.h>
+#include <storage.h>
+#include <at.h>
+
+#include <co_sms.h>
+
+#include "atmodem_sms.h"
+#include "atmodem_common.h"
+
+#define CR '\r'
+#define CTRL_Z '\x1A'
+
+#define AT_MT_UNREAD 0 /* Received and Unread */
+#define AT_MT_READ 1 /* Received and Read */
+#define AT_MO_UNSENT 2 /* Unsent */
+#define AT_MO_SENT 3 /* Sent */
+#define AT_ALL 4 /* Unknown */
+
+#define ATMODEM_NUM_PLAN_ID(sca) (gchar)(sca & 0x0F)
+#define ATMODEM_TYPE_OF_NUM(sca) (gchar)((sca & 0x70) >> 4)
+
+/* SCA 12 bytes long and TDPU is 164 bytes long */
+#define PDU_LEN_MAX 176
+#define HEX_PDU_LEN_MAX ((PDU_LEN_MAX * 2) + 1)
+
+#define ATMODEM_SIM_TON_INTERNATIONAL 1
+#define ATMODEM_SIM_TON_NATIONAL 2
+
+/*
+ * Notification - SMS-DELIVER
+ * +CMT = [<alpha>],<length><CR><LF><pdu> (PDU mode enabled)
+ *
+ * where,
+ * <alpha> alpha_id
+ * <length> length of the PDU
+ * <pdu> Incomming SMS PDU
+ *
+ * Notification - SMS-STATUS-REPORT
+ * +CDS: <length><CR><LF><pdu> (PDU mode enabled)
+ *
+ * where,
+ * <length> length of the PDU
+ * <pdu> Incomming SMS PDU
+ *
+ */
+static gboolean on_notification_atmodem_sms_incoming_msg(CoreObject *co,
+ const void *event_info, void *user_data)
+{
+ GSList *tokens = NULL;
+ GSList *lines = NULL;
+ char *line = NULL;
+ int pdu_len = 0, no_of_tokens = 0;
+ gchar *byte_pdu = NULL;
+ guint buf_len = 0;
+
+ TelSmsDatapackageInfo incoming_msg = {{0}, };
+ int sca_length = 0;
+ dbg("Enter");
+
+ lines = (GSList *)event_info;
+ if (2 != g_slist_length(lines)) {
+ err("Invalid number of lines for +CMT. Must be 2");
+ return TRUE;
+ }
+ line = (char *)g_slist_nth_data(lines, 0); /* Fetch Line 1 */
+ if (!line) {
+ err("Line 1 is invalid");
+ return TRUE;
+ }
+ dbg("Line 1: [%s]", line);
+ tokens = tcore_at_tok_new(line); /* Split Line 1 into tokens */
+ no_of_tokens = g_slist_length(tokens);
+
+ /*
+ * Incoming SMS: +CMT
+ * Number of tokens: 2
+ *
+ * Incoming SMS-STATUS-REPORT: +CDS
+ * Number of tokens: 1
+ */
+ if (2 == no_of_tokens) {
+ /* Token 0: Alpha ID */
+ dbg("Alpha ID: [0x%x]", g_slist_nth_data(tokens, 0));
+
+ /* Token 1: PDU Length */
+ pdu_len = atoi((char *)g_slist_nth_data(tokens, 1));
+ dbg("pdu_len: [%d]", pdu_len);
+ } else if (1 == no_of_tokens) {
+ /* 0: PDU Length */
+ pdu_len = atoi((char *)g_slist_nth_data(tokens, 0));
+ dbg("pdu_len: [%d]", pdu_len);
+ }
+
+ /* Fetch Line 2 */
+ line = (char *)g_slist_nth_data(lines, 1);
+ if (!line) {
+ err("Line 2 is invalid");
+ tcore_at_tok_free(tokens);
+ return TRUE;
+ }
+ dbg("Line 2: [%s]", line);
+
+ /* Convert to Bytes */
+ tcore_util_hexstring_to_bytes(line, &byte_pdu, &buf_len);
+
+ sca_length = byte_pdu[0];
+ dbg("SCA length = %d", sca_length);
+
+ if (sca_length) {
+ gchar *decoded_sca;
+ guint encoded_sca_len;
+ /*
+ * byte_pdu[1] - sca_address_type
+ * Excluding sca_address_type and copy SCA
+ */
+ encoded_sca_len = sca_length - 1;
+ decoded_sca =
+ tcore_util_convert_bcd_to_ascii(&byte_pdu[2], encoded_sca_len, encoded_sca_len*2);
+ dbg("Decoded SCA: [%s]", decoded_sca);
+ g_strlcpy(incoming_msg.sca.number, decoded_sca, strlen(decoded_sca)+1);
+ tcore_free(decoded_sca);
+
+ /*SCA Conversion for Address type*/
+ incoming_msg.sca.ton = ATMODEM_TYPE_OF_NUM(byte_pdu[1]);
+ incoming_msg.sca.npi = ATMODEM_NUM_PLAN_ID(byte_pdu[1]);
+ dbg("TON: [%d] NPI: [%d] SCA: [%s]",
+ incoming_msg.sca.ton, incoming_msg.sca.npi,
+ incoming_msg.sca.number);
+ }
+ else {
+ dbg("NO SCA Present");
+ }
+
+
+ /* TPDU */
+ incoming_msg.tpdu_length = pdu_len;
+ memcpy(incoming_msg.tpdu,
+ &byte_pdu[sca_length+1], incoming_msg.tpdu_length);
+
+ /* Send notification */
+ tcore_object_send_notification(co,
+ TCORE_NOTIFICATION_SMS_INCOM_MSG,
+ sizeof(TelSmsDatapackageInfo), &incoming_msg);
+
+ tcore_at_tok_free(tokens);
+ g_free(byte_pdu);
+
+ return TRUE;
+}
+
+static gboolean on_notification_atmodem_sms_device_ready(CoreObject *co,
+ const void *event_info, void *user_data)
+{
+ gboolean sms_status = TRUE;
+
+ dbg("SMS notification - [Device Ready]");
+
+ /* Set Device Ready */
+ tcore_sms_set_ready_status(co, sms_status);
+
+ /* Send notification: SMS Device ready */
+ tcore_object_send_notification(co,
+ TCORE_NOTIFICATION_SMS_DEVICE_READY,
+ sizeof(sms_status), &sms_status);
+
+ return TRUE;
+}
+
+static void on_response_atmodem_sms_send_more_msg(TcorePending *p,
+ guint data_len, const void *data, void *user_data)
+{
+ const TcoreAtResponse *at_resp = data;
+
+ dbg("Enter");
+
+ if (at_resp && at_resp->success)
+ dbg("Response OK for AT+CMMS: More msgs to send!!");
+ else
+ err("Response NOK for AT+CMMS: More msgs to send");
+
+ /* Need not send any response */
+}
+
+static void on_response_atmodem_sms_send_sms(TcorePending *p,
+ guint data_len, const void *data, void *user_data)
+{
+ const TcoreAtResponse *at_resp = data;
+ CoreObject *co = tcore_pending_ref_core_object(p);
+ AtmodemRespCbData *resp_cb_data = user_data;
+
+ TelSmsResult result = TEL_SMS_RESULT_FAILURE;/*TODO: CMS error mapping required */
+ dbg("Enter");
+
+ tcore_check_return_assert(co != NULL);
+ tcore_check_return_assert(resp_cb_data != NULL);
+
+ if (at_resp && at_resp->success) {
+ dbg("Response OK");
+ if (at_resp->lines) {
+ const gchar *line;
+ gchar* line_token;
+ GSList *tokens = NULL;
+ gint msg_ref = 0;
+
+ line = (const gchar *)at_resp->lines->data;
+ tokens = tcore_at_tok_new(line);
+ line_token = g_slist_nth_data(tokens, 0);
+ if (line_token != NULL) {
+ /*Response from MODEM for send SMS: +CMGS: <mr>[,<ackpdu>]*/
+ /*Message Reference is not used by MSG_SERVER and application.So Filling only result*/
+ msg_ref = atoi(line_token);
+
+ dbg("Message Reference: [%d]", msg_ref);
+
+ result = TEL_SMS_RESULT_SUCCESS;
+ } else {
+ dbg("No Message Reference received");
+ }
+ tcore_at_tok_free(tokens);
+ }
+ } else {
+ err("Response NOK");
+ }
+ /* Invoke callback */
+ if (resp_cb_data->cb)
+ resp_cb_data->cb(co, (gint)result, NULL, resp_cb_data->cb_data);
+
+ /* Free callback data */
+ atmodem_destroy_resp_cb_data(resp_cb_data);
+}
+
+static void on_response_atmodem_sms_get_count(TcorePending *p,
+ guint data_len, const void *data, void *user_data)
+{
+ TelSmsStoredMsgCountInfo count_info = {0, };
+
+ const TcoreAtResponse *at_resp = data;
+ CoreObject *co = tcore_pending_ref_core_object(p);
+ AtmodemRespCbData *resp_cb_data = user_data;
+
+ GSList *tokens = NULL;
+ TelSmsResult result = TEL_SMS_RESULT_FAILURE;
+
+ dbg("Enter");
+
+ if (at_resp && at_resp->success) {
+ dbg("RESPONSE OK");
+ if (at_resp->lines) {
+ char *line = NULL, *line_token = NULL;
+
+ line = (char *)at_resp->lines->data;
+ dbg("line: [%s]",line);
+
+ /*
+ * Tokenize
+ *
+ * +CPMS: <used1>, <total1>, <used2>, <total2>, <used3>, <total3>
+ */
+ tokens = tcore_at_tok_new(line);
+
+ /* <used1> */
+ line_token = g_slist_nth_data(tokens, 0);
+ if (line_token == NULL) {
+ err("Line Token for used count is NULL");
+ goto ERROR;
+ }
+ count_info.used_count = atoi(line_token);
+
+ /* <total1> */
+ line_token = g_slist_nth_data(tokens, 1);
+ if (line_token == NULL) {
+ err("Line Token for Total count is NULL");
+ goto ERROR;
+ }
+ count_info.total_count = atoi(line_token);
+
+ dbg("Count - used: [%d] total: [%d]",
+ count_info.used_count, count_info.total_count);
+ result = TEL_SMS_RESULT_SUCCESS;
+ }
+ else {
+ err("Invalid Response Received: NO Lines Present");
+ }
+ }
+ else {
+ err("RESPONSE NOK");
+ }
+
+ERROR:
+ /* Invoke callback in case of error*/
+ if (resp_cb_data->cb)
+ resp_cb_data->cb(co, (gint)result, &count_info, resp_cb_data->cb_data);
+
+ /* Free callback data */
+ atmodem_destroy_resp_cb_data(resp_cb_data);
+
+ tcore_at_tok_free(tokens);
+}
+
+static void on_response_atmodem_sms_send_deliver_report(TcorePending *p,
+ guint data_len, const void *data, void *user_data)
+{
+ const TcoreAtResponse *at_resp = data;
+ CoreObject *co = tcore_pending_ref_core_object(p);
+ AtmodemRespCbData *resp_cb_data = user_data;
+
+ TelSmsResult result = TEL_SMS_RESULT_FAILURE; // TODO: CMEE error mapping is required
+ dbg("Enter");
+
+ tcore_check_return_assert(co != NULL);
+ tcore_check_return_assert(resp_cb_data != NULL);
+
+ if (at_resp && at_resp->success)
+ result = TEL_SMS_RESULT_SUCCESS;
+
+ dbg("Send Deliver Report: [%s]",
+ (result == TEL_SMS_RESULT_SUCCESS ? "SUCCESS" : "FAIL"));
+
+ /* Invoke callback */
+ if (resp_cb_data->cb)
+ resp_cb_data->cb(co, (gint)result, NULL, resp_cb_data->cb_data);
+
+ atmodem_destroy_resp_cb_data(resp_cb_data);
+}
+
+static void on_response_atmodem_sms_set_sca(TcorePending *p,
+ guint data_len, const void *data, void *user_data)
+{
+ const TcoreAtResponse *at_resp = data;
+ CoreObject *co = tcore_pending_ref_core_object(p);
+ AtmodemRespCbData *resp_cb_data = user_data;
+
+ TelSmsResult result = TEL_SMS_RESULT_FAILURE;
+ dbg("Enter");
+
+ if (at_resp && at_resp->success) {
+ dbg("Response OK");
+ result = TEL_SMS_RESULT_SUCCESS;
+ } else {
+ err("Response NOK");
+ }
+ /* Invoke callback */
+ if (resp_cb_data->cb)
+ resp_cb_data->cb(co, (gint)result, NULL, resp_cb_data->cb_data);
+
+ /* Free callback data */
+ atmodem_destroy_resp_cb_data(resp_cb_data);
+}
+
+static void on_response_atmodem_sms_get_sca(TcorePending *p,
+ guint data_len, const void *data, void *user_data)
+{
+ const TcoreAtResponse *at_resp = data;
+ CoreObject *co = tcore_pending_ref_core_object(p);
+ AtmodemRespCbData *resp_cb_data = user_data;
+
+ TelSmsSca sca_resp = { 0, };
+ TelSmsResult result = TEL_SMS_RESULT_FAILURE;
+ dbg("Enter");
+
+ if (at_resp && at_resp->success) {
+ dbg("Response OK");
+ if (at_resp->lines) {
+ GSList *tokens = NULL;
+ const char *sca_tok_addr;
+ gchar *line = NULL, *sca_addr = NULL, *sca_toa = NULL;
+
+ line = (char *)at_resp->lines->data;
+ tokens = tcore_at_tok_new(line);
+ sca_tok_addr = g_slist_nth_data(tokens, 0);
+ sca_toa = g_slist_nth_data(tokens, 1);
+
+ sca_addr = tcore_at_tok_extract(sca_tok_addr);
+ dbg("SCA: [%s] SCA-TOA: [%s]", sca_addr, sca_toa);
+ if ((NULL != sca_addr) && (NULL != sca_toa)) {
+ gchar *sca;
+ guint sca_len = 0;
+ tcore_util_hexstring_to_bytes(sca_addr, &sca, &sca_len); /*TODO : Check*/
+ memcpy(sca_resp.number, sca, sca_len);
+ g_free(sca);
+
+ /* Type-of-Address */
+ if (145 == atoi(sca_toa)) {
+ sca_resp.ton = ATMODEM_SIM_TON_INTERNATIONAL;
+ } else {
+ sca_resp.ton = ATMODEM_SIM_TON_NATIONAL;
+ }
+ sca_resp.npi = 0;/* TODO */
+ result = TEL_SMS_RESULT_SUCCESS;
+ } else {
+ err("SCA is NULL");
+ }
+ tcore_at_tok_free(tokens);
+ g_free(sca_addr);
+ } else {
+ err("Invalid Response.No Lines Received");
+ }
+ } else {
+ err("Response NOK");
+ }
+ /* Invoke callback */
+ if (resp_cb_data->cb)
+ resp_cb_data->cb(co, (gint)result, &sca_resp, resp_cb_data->cb_data);
+
+ /* Free callback data */
+ atmodem_destroy_resp_cb_data(resp_cb_data);
+}
+
+/* SMS Operations */
+/*
+ * Operation - send_sms
+ *
+ * Request -
+ * AT-Command: AT+CMGS
+ * For PDU mode (+CMGF=0):
+ * +CMGS=<length><CR>
+ * PDU is given<ctrl-Z/ESC>
+ * where,
+ * <length> Length of the pdu.
+ * <PDU> PDU to send.
+ *
+ * Response -
+ *+CMGS: <mr>[,<ackpdu>]
+ * OK
+ * Failure:
+ * +CMS ERROR: <error>
+ */
+static TelReturn atmodem_sms_send_sms(CoreObject *co,
+ const TelSmsSendInfo *send_info,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ gchar *at_cmd;
+
+ AtmodemRespCbData *resp_cb_data;
+ TelReturn ret;
+
+ const unsigned char *tpdu_byte_data;
+ gint tpdu_byte_len, pdu_byte_len;
+ char buf[HEX_PDU_LEN_MAX];
+ char pdu[PDU_LEN_MAX];
+ dbg("Enter");
+
+ tpdu_byte_data = send_info->send_data.tpdu;
+
+ /* TPDU length is in byte */
+ tpdu_byte_len = send_info->send_data.tpdu_length;
+
+ /* Prepare PDU for hex encoding */
+ pdu_byte_len = tcore_util_encode_pdu(&(send_info->send_data.sca),
+ tpdu_byte_data, tpdu_byte_len, pdu);
+
+ tcore_util_encode_hex((unsigned char *) pdu, pdu_byte_len, buf);
+
+ /* Response callback data */
+ resp_cb_data = atmodem_create_resp_cb_data(cb, cb_data, NULL, 0);
+
+ /*
+ * More messages
+ * Use same Radio Resource Channel :More Messages to send
+ */
+ if (send_info->more_msgs > 0) {
+ /* AT Command: More Msgs to Send */
+ ret = tcore_at_prepare_and_send_request(co,
+ "AT+CMMS=1", "+CMMS:",
+ TCORE_AT_COMMAND_TYPE_SINGLELINE,
+ TCORE_PENDING_PRIORITY_DEFAULT,
+ NULL,
+ on_response_atmodem_sms_send_more_msg, NULL,
+ on_send_atmodem_request, NULL,
+ 0, NULL, NULL);
+ ATMODEM_CHECK_REQUEST_RET(ret, NULL, "More Msgs to Send");
+ }
+ /* AT-Command : Send SMS */
+ at_cmd = g_strdup_printf("AT+CMGS=%d\r%s\x1A", tpdu_byte_len, buf);
+
+ /* Send Request to modem */
+ ret = tcore_at_prepare_and_send_request(co,
+ at_cmd, "+CMGS:",
+ TCORE_AT_COMMAND_TYPE_SINGLELINE,
+ TCORE_PENDING_PRIORITY_DEFAULT,
+ NULL,
+ on_response_atmodem_sms_send_sms, resp_cb_data,
+ on_send_atmodem_request, NULL,
+ 0, NULL, NULL);
+ ATMODEM_CHECK_REQUEST_RET(ret, resp_cb_data, "Send SMS");
+
+ /* Free resources */
+ g_free(at_cmd);
+
+ return ret;
+}
+
+/*
+ * Operation - get_sms_count_in_sim
+ *
+ * Request -
+ * AT-Command: AT+CPMS
+ * +CPMS=<mem1>[, <mem2>[,<mem3>]]
+ * where
+ * <mem1> memory storage to read.
+ *
+ * Response -
+ * Success: (Single-line output)
+ * +CPMS: <mem1>,<used1>,<total1>,<mem2>,<used2>,<total2>,
+ * <mem3>,<used3>,<total3>
+ * OK
+ *
+ * Failure:
+ * +CMS ERROR: <error>
+ */
+static TelReturn atmodem_sms_get_count(CoreObject *co,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ gchar *at_cmd;
+
+ AtmodemRespCbData *resp_cb_data;
+ TelReturn ret;
+ dbg("Enter");
+
+ /*AT Command*/
+ at_cmd = g_strdup_printf("AT+CPMS=\"SM\"");
+
+ /* Response callback data */
+ resp_cb_data = atmodem_create_resp_cb_data(cb, cb_data, NULL, 0);
+
+ /* Send Request to modem */
+ ret = tcore_at_prepare_and_send_request(co,
+ at_cmd, "+CPMS",
+ TCORE_AT_COMMAND_TYPE_SINGLELINE,
+ TCORE_PENDING_PRIORITY_DEFAULT,
+ NULL,
+ on_response_atmodem_sms_get_count, resp_cb_data,
+ on_send_atmodem_request, NULL,
+ 0, NULL, NULL);
+ ATMODEM_CHECK_REQUEST_RET(ret, resp_cb_data, "Get SMS Count");
+
+ /* Free resources */
+ g_free(at_cmd);
+
+ return ret;
+}
+
+/*
+ * Operation - send_deliver_report
+ *
+ * Request -
+ * Modem Takes care of sending the ACK to the network
+ *
+ * Response -
+ * Success: Default response always SUCCESS posted
+ *
+ */
+static TelReturn atmodem_sms_send_deliver_report(CoreObject *co,
+ const TelSmsDeliverReportInfo *dr_info,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ gchar *at_cmd;
+ AtmodemRespCbData *resp_cb_data;
+ TelReturn ret;
+ dbg("Enter");
+
+ /*AT Command*/
+ if(dr_info->report== TEL_SMS_DELIVERY_REPORT_SUCCESS)
+ at_cmd = g_strdup_printf("AT+CNMA=0%s", "\r");
+ else
+ at_cmd = g_strdup_printf("AT+CNMA=2,3%s%x%s", "/n", 0x00ff00, "");
+
+
+ /* Response callback data */
+ resp_cb_data = atmodem_create_resp_cb_data(cb, cb_data, NULL, 0);
+
+ /* Send Request to modem */
+ ret = tcore_at_prepare_and_send_request(co,
+ at_cmd, NULL,
+ TCORE_AT_COMMAND_TYPE_NO_RESULT,
+ TCORE_PENDING_PRIORITY_DEFAULT,
+ NULL,
+ on_response_atmodem_sms_send_deliver_report, resp_cb_data,
+ on_send_atmodem_request, NULL,
+ 0, NULL, NULL);
+ ATMODEM_CHECK_REQUEST_RET(ret, resp_cb_data, "Send deliver Report");
+
+ /* Free resources */
+ g_free(at_cmd);
+ return ret;
+}
+
+/*
+ * Operation - set SCA
+ *
+ * Request -
+ * AT-Command: AT+CSCA
+ * AT+CSCA=<sca>[,<tosca>]
+ * where
+ * <sca> Service center number
+ * <tosca> address type of SCA
+ *
+ * Response -
+ * Success: No result
+ * OK
+ *
+ * Failure:
+ * +CMS ERROR: <error>
+ */
+ static TelReturn atmodem_sms_set_sca(CoreObject *co,
+ const TelSmsSca *sca,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ gchar *at_cmd;
+
+ AtmodemRespCbData *resp_cb_data;
+ TelReturn ret;
+ gint address_type;
+
+ address_type = ((sca->ton << 4) | sca->npi ) | 0x80;
+
+ /* AT Command */
+ at_cmd = g_strdup_printf("AT+CSCA=\"%s\",%d", sca->number, address_type);
+
+ /* Response callback data */
+ resp_cb_data = atmodem_create_resp_cb_data(cb, cb_data, NULL, 0);
+
+ /* Send Request to modem */
+ ret = tcore_at_prepare_and_send_request(co,
+ at_cmd, NULL,
+ TCORE_AT_COMMAND_TYPE_NO_RESULT,
+ TCORE_PENDING_PRIORITY_DEFAULT,
+ NULL,
+ on_response_atmodem_sms_set_sca, resp_cb_data,
+ on_send_atmodem_request, NULL,
+ 0, NULL, NULL);
+ ATMODEM_CHECK_REQUEST_RET(ret, resp_cb_data, "Set SCA");
+
+ /* Free resources */
+ g_free(at_cmd);
+
+ return ret;
+}
+
+/*
+ * Operation - get SCA
+ *
+ * Request -
+ * AT-Command: AT+CSCA?
+ *
+ * Response -
+ * Success: Single-Line
+ * +CSCA: <sca>,<tosca>
+ * OK
+ * where
+ * <sca> Service center number
+ * <tosca> address type of SCA
+ *
+ */
+ static TelReturn atmodem_sms_get_sca(CoreObject *co,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ gchar *at_cmd;
+
+ AtmodemRespCbData *resp_cb_data;
+ TelReturn ret;
+ dbg("Enter");
+
+ /* AT Command */
+ at_cmd = g_strdup_printf("AT+CSCA?");
+
+ /* Response callback data */
+ resp_cb_data = atmodem_create_resp_cb_data(cb, cb_data, NULL, 0);
+
+ /* Send Request to modem */
+ ret = tcore_at_prepare_and_send_request(co,
+ at_cmd, "+CSCA",
+ TCORE_AT_COMMAND_TYPE_SINGLELINE,
+ TCORE_PENDING_PRIORITY_DEFAULT,
+ NULL,
+ on_response_atmodem_sms_get_sca, resp_cb_data,
+ on_send_atmodem_request, NULL,
+ 0, NULL, NULL);
+ ATMODEM_CHECK_REQUEST_RET(ret, resp_cb_data, "Get SCA");
+
+ /* Free resources */
+ g_free(at_cmd);
+
+ return ret;
+}
+
+/* SMS Operations */
+static TcoreSmsOps atmodem_sms_ops = {
+ .send_sms = atmodem_sms_send_sms,
+ .read_in_sim = NULL,
+ .write_in_sim = NULL,
+ .delete_in_sim = NULL,
+ .get_count = atmodem_sms_get_count,
+ .set_cb_config = NULL,
+ .get_cb_config = NULL,
+ .get_parameters = NULL, /* TODO - After implemented in imc code */
+ .set_parameters = NULL, /* TODO - After implemented in imc code */
+ .send_deliver_report = atmodem_sms_send_deliver_report,
+ .set_sca = atmodem_sms_set_sca,
+ .get_sca = atmodem_sms_get_sca,
+ .set_memory_status = NULL,
+ .set_message_status = NULL
+};
+
+gboolean atmodem_sms_init(TcorePlugin *p, CoreObject *co)
+{
+ dbg("Entry");
+
+ /* Set operations */
+ tcore_sms_set_ops(co, &atmodem_sms_ops);
+
+ /* Add Callbacks */
+ tcore_object_add_callback(co,
+ "\e+CMT:",
+ on_notification_atmodem_sms_incoming_msg, NULL);
+ tcore_object_add_callback(co,
+ "\%SCDEV",
+ on_notification_atmodem_sms_device_ready, NULL);
+
+ dbg("Exit");
+ return TRUE;
+}
+
+void atmodem_sms_exit(TcorePlugin *p, CoreObject *co)
+{
+ dbg("Exit");
+}
--- /dev/null
+/*
+ * tel-plugin-atmodem
+ *
+ * Copyright (c) 2013 Samsung Electronics Co. Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <glib.h>
+
+#include <tcore.h>
+#include <server.h>
+#include <plugin.h>
+#include <core_object.h>
+#include <hal.h>
+#include <queue.h>
+#include <storage.h>
+#include <at.h>
+
+#include <co_ss.h>
+
+#include "atmodem_ss.h"
+#include "atmodem_common.h"
+
+/* AT+CUSD = [<n> [, <str> [, <dcs>]]]
+ * where,
+ * <n>
+ * 0 Disable
+ * 1 Enable
+ * 2 Cancel the session
+ *
+ * <str>
+ * Ussd string
+ *
+ * <dcs>
+ * Decoding format
+ */
+static gboolean on_notification_atmodem_ss_ussd(CoreObject *co,
+ const void *event_data, void *user_data)
+{
+ gchar *cmd;
+ gchar *resp_str = NULL;
+ guchar *dcs_str = NULL;
+ TelUtilAlphabetFormat dcs = TEL_UTIL_ALPHABET_FORMAT_SMS_DEFAULT;
+ gushort len;
+ GSList *tokens = NULL;
+ GSList *lines = NULL;
+ gint ussd_status = 0;
+ TelSsUssdNoti ussd_noti = {0,};
+
+ lines = (GSList *) event_data;
+ if (g_slist_length(lines) != 1) {
+ dbg("Unsolicited message but multiple lines");
+ return TRUE;
+ }
+
+ cmd = (gchar *)lines->data;
+ tokens = tcore_at_tok_new(cmd);
+
+ /* Parse USSD status */
+ resp_str = g_slist_nth_data(tokens, 0);
+ if (NULL == resp_str) {
+ err("Status is missing from +CUSD Notification");
+ goto out;
+ } else {
+ ussd_status = atoi(resp_str);
+ dbg("USSD status[%d]", ussd_status);
+
+ if (ussd_status < TEL_SS_USSD_STATUS_NO_ACTION_REQUIRED ||
+ ussd_status > TEL_SS_USSD_STATUS_TIME_OUT) {
+ err("Invalid USSD status");
+ goto out;
+ }
+
+ /*
+ * When network terminated the USSD session,
+ * no need to send notification to application
+ */
+ if (ussd_status == TEL_SS_USSD_STATUS_TERMINATED_BY_NETWORK) {
+ /* Destroy USSD session, if any exists */
+ UssdSession *ussd_session = tcore_ss_ussd_get_session(co);
+ if (ussd_session)
+ tcore_ss_ussd_destroy_session(ussd_session);
+
+ goto out;
+ }
+
+ /* Parse USSD string */
+ resp_str = g_slist_nth_data(tokens, 1);
+
+ resp_str = tcore_at_tok_extract(resp_str);
+ if (resp_str) {
+ len = strlen((gchar *)resp_str);
+ dbg("USSD String: [%s] Length: [%d]", resp_str, len);
+ } else {
+ dbg("USSD strings is missing from +CUSD Notification");
+ goto out;
+ }
+
+ dcs_str = g_slist_nth_data(tokens, 2);
+ }
+
+ if (dcs_str) {
+ dcs = tcore_util_get_cbs_coding_scheme(atoi((gchar *)dcs_str));
+ } else {
+ warn("No DCS string! Using default DCS value");
+ }
+
+ ussd_noti.str = tcore_malloc0(len+1);
+ tcore_util_convert_str_to_utf8(ussd_noti.str,
+ &len, dcs, (const guchar *)resp_str, len+1);
+ ussd_noti.status = ussd_status;
+
+ /* Send notification */
+ tcore_object_send_notification(co,
+ TCORE_NOTIFICATION_SS_USSD,
+ sizeof(TelSsUssdNoti), (void *)&ussd_noti);
+
+ tcore_free(resp_str);
+ tcore_free(ussd_noti.str);
+
+out:
+ tcore_at_tok_free(tokens);
+ return TRUE;
+}
+
+static gboolean __atmodem_ss_convert_modem_class_to_class(gint classx,
+ TelSsClass *class)
+{
+ switch (classx) {
+ case 7:
+ *class = TEL_SS_CLASS_ALL_TELE;
+ break;
+
+ case 1:
+ *class = TEL_SS_CLASS_VOICE;
+ break;
+
+ case 2:
+ *class = TEL_SS_CLASS_ALL_DATA_TELE;
+ break;
+
+ case 4:
+ *class = TEL_SS_CLASS_FAX;
+ break;
+
+ case 8:
+ *class = TEL_SS_CLASS_SMS;
+ break;
+
+ case 16:
+ *class = TEL_SS_CLASS_ALL_CS_SYNC;
+ break;
+
+ case 32:
+ *class = TEL_SS_CLASS_ALL_CS_ASYNC;
+ break;
+
+ case 64:
+ *class = TEL_SS_CLASS_ALL_DEDI_PS;
+ break;
+
+ case 128:
+ *class = TEL_SS_CLASS_ALL_DEDI_PAD;
+ break;
+
+ default:
+ err("Invalid modem class: [%d]", classx);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static guint __atmodem_ss_convert_class_to_atmodem_class(TelSsClass class)
+{
+ switch (class) {
+ case TEL_SS_CLASS_ALL_TELE:
+ return 7;
+
+ case TEL_SS_CLASS_VOICE:
+ return 1;
+
+ case TEL_SS_CLASS_ALL_DATA_TELE:
+ return 2;
+
+ case TEL_SS_CLASS_FAX:
+ return 4;
+
+ case TEL_SS_CLASS_SMS:
+ return 8;
+
+ case TEL_SS_CLASS_ALL_CS_SYNC:
+ return 16;
+
+ case TEL_SS_CLASS_ALL_CS_ASYNC:
+ return 32;
+
+ case TEL_SS_CLASS_ALL_DEDI_PS:
+ return 64;
+
+ case TEL_SS_CLASS_ALL_DEDI_PAD:
+ return 128;
+
+ default:
+ dbg("Unsupported class: [%d], returning default value 7", class);
+ return 7;
+ }
+}
+
+static gboolean __atmodem_ss_convert_barring_type_to_facility(TelSsBarringType type,
+ gchar **facility)
+{
+ switch (type) {
+ case TEL_SS_CB_TYPE_BAOC:
+ *facility = "AO";
+ break;
+
+ case TEL_SS_CB_TYPE_BOIC:
+ *facility = "OI";
+ break;
+
+ case TEL_SS_CB_TYPE_BOIC_NOT_HC:
+ *facility = "OX";
+ break;
+
+ case TEL_SS_CB_TYPE_BAIC:
+ *facility = "AI";
+ break;
+
+ case TEL_SS_CB_TYPE_BIC_ROAM:
+ *facility = "IR";
+ break;
+
+ case TEL_SS_CB_TYPE_AB:
+ *facility = "AB";
+ break;
+
+ case TEL_SS_CB_TYPE_AOB:
+ *facility = "AG";
+ break;
+
+ case TEL_SS_CB_TYPE_AIB:
+ *facility = "AC";
+ break;
+
+ case TEL_SS_CB_TYPE_NS:
+ *facility = "NS";
+ break;
+
+ default:
+ err("Unspported type: [%d]", type);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+static gboolean __atmodem_ss_convert_forwarding_mode_to_modem_mode(TelSsForwardMode mode,
+ guint *modex)
+{
+ switch (mode) {
+ case TEL_SS_CF_MODE_DISABLE:
+ *modex = 0;
+ break;
+
+ case TEL_SS_CF_MODE_ENABLE:
+ *modex = 1;
+ break;
+
+ case TEL_SS_CF_MODE_REGISTER:
+ *modex = 3;
+ break;
+
+ case TEL_SS_CF_MODE_DEREGISTER:
+ *modex = 4;
+ break;
+
+ default:
+ err("Unspported mode: [%d]", mode);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static gboolean __atmodem_ss_convert_forwarding_condition_to_modem_reason(TelSsForwardCondition condition,
+ guint *reason)
+{
+ switch (condition) {
+ case TEL_SS_CF_COND_CFU:
+ *reason = 0;
+ break;
+
+ case TEL_SS_CF_COND_CFB:
+ *reason = 1;
+ break;
+
+ case TEL_SS_CF_COND_CFNRY:
+ *reason = 2;
+ break;
+
+ case TEL_SS_CF_COND_CFNRC:
+ *reason = 3;
+ break;
+
+ case TEL_SS_CF_COND_ALL:
+ *reason = 4;
+ break;
+
+ case TEL_SS_CF_COND_ALL_CFC:
+ *reason = 5;
+ break;
+
+ default:
+ dbg("Unsupported condition: [%d]", condition);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+static gboolean __atmodem_ss_convert_modem_cli_dev_status_cli_status(TelSsCliType cli_type,
+ gint dev_status, gint *status)
+{
+ if (cli_type == TEL_SS_CLI_CLIR) {
+ switch (dev_status) {
+ case 0:
+ *status = TEL_CLIR_STATUS_DEFAULT;
+ break;
+
+ case 1:
+ *status = TEL_CLIR_STATUS_INVOCATION;
+ break;
+
+ case 2:
+ *status = TEL_CLIR_STATUS_SUPPRESSION;
+ break;
+ default:
+ err("Invalid dev status: [%d]", dev_status);
+ return FALSE;
+ }
+ } else { //CLIP, COLP,COLR,CNAP.
+ switch (dev_status) {
+ case 0:
+ *status = TEL_SS_CLI_DISABLE;
+ break;
+
+ case 1:
+ *status = TEL_SS_CLI_ENABLE;
+ break;
+
+ default:
+ err("Invalid dev status: [%d]", dev_status);
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+static gboolean __atmodem_ss_convert_modem_cli_net_status_cli_status(TelSsCliType cli_type, gint net_status,
+ gint *status)
+{
+ if (cli_type == TEL_SS_CLI_CLIR) {
+ switch (net_status) {
+ case 0:
+ *status = TEL_CLIR_STATUS_NOT_PROVISIONED;
+ break;
+ case 1:
+ *status = TEL_CLIR_STATUS_PROVISIONED;
+ break;
+ case 2:
+ *status = TEL_CLIR_STATUS_UNKNOWN;
+ break;
+ case 3:
+ *status = TEL_CLIR_STATUS_TEMP_RESTRICTED;
+ break;
+ case 4:
+ *status = TEL_CLIR_STATUS_TEMP_ALLOWED;
+ break;
+ default:
+ err("Invalid clir net status: [%d]", net_status);
+ return FALSE;
+ }
+ } else { //CLIP, COLP,COLR,CNAP.
+ switch (net_status) {
+ case 0:
+ *status = TEL_SS_CLI_NOT_PROVISIONED;
+ break;
+ case 1:
+ *status = TEL_SS_CLI_PROVISIONED;
+ break;
+ case 2:
+ *status = TEL_SS_CLI_UNKNOWN;
+ break;
+ default:
+ err("Invalid status: [%d]", net_status);
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+
+/* SS Responses */
+static void on_response_atmodem_ss_set_barring(TcorePending *p,
+ guint data_len, const void *data, void *user_data)
+{
+ const TcoreAtResponse *at_resp = data;
+ CoreObject *co = tcore_pending_ref_core_object(p);
+ AtmodemRespCbData *resp_cb_data = user_data;
+
+ TelSsResult result = TEL_SS_RESULT_FAILURE; // TODO: CMEE error mapping is required
+ dbg("Enter");
+
+ tcore_check_return_assert(co != NULL);
+ tcore_check_return_assert(resp_cb_data != NULL);
+
+ if (at_resp && at_resp->success)
+ result = TEL_SS_RESULT_SUCCESS;
+
+ dbg("Setting Barring status: [%s]",
+ (result == TEL_SS_RESULT_SUCCESS ? "SUCCESS" : "FAIL"));
+
+ /* Invoke callback */
+ if (resp_cb_data->cb)
+ resp_cb_data->cb(co, (gint)result, NULL, resp_cb_data->cb_data);
+
+ atmodem_destroy_resp_cb_data(resp_cb_data);
+}
+
+static void on_response_atmodem_ss_get_barring_status(TcorePending *p,
+ guint data_len, const void *data, void *user_data)
+{
+ const TcoreAtResponse *at_resp = data;
+ CoreObject *co = tcore_pending_ref_core_object(p);
+ AtmodemRespCbData *resp_cb_data = user_data;
+ TelSsBarringResp barring_resp = {0,};
+ TelSsBarringGetInfo *req_info;
+ gint valid_records = 0;
+ GSList *resp_data = NULL;
+
+ TelSsResult result = TEL_SS_RESULT_FAILURE; // TODO: CMEE error mapping is required
+ dbg("Enter");
+
+ tcore_check_return_assert(co != NULL);
+ tcore_check_return_assert(resp_cb_data != NULL);
+
+ req_info = (TelSsBarringGetInfo *)ATMODEM_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
+
+ if (at_resp) {
+ if (at_resp->lines && at_resp->success) {
+ resp_data = (GSList *) at_resp->lines;
+ barring_resp.record_num= g_slist_length(resp_data);
+ dbg("Total records: [%d]", barring_resp.record_num);
+ }
+ else {
+ err("RESPONSE - [NOK]");
+ }
+ } else {
+ err("No response data");
+ }
+
+ if (barring_resp.record_num > 0) {
+ barring_resp.records = tcore_malloc0(
+ (barring_resp.record_num) * sizeof(TelSsBarringInfoRecord));
+ for (valid_records = 0; resp_data != NULL; resp_data = resp_data->next) {
+ const gchar *line;
+ GSList *tokens = NULL;
+
+ line = (const gchar *) resp_data->data;
+ tokens = tcore_at_tok_new(line);
+ if (g_slist_length(tokens) > 0) {
+ gchar *classx_str;
+ gchar *status = NULL;
+
+ status = g_slist_nth_data(tokens, 0);
+ if (!status) {
+ dbg("Status is missing");
+ tcore_at_tok_free(tokens);
+ continue;
+ }
+
+ if (atoi(status) == 1) {
+ barring_resp.records[valid_records].enable = TRUE;
+ } else {
+ barring_resp.records[valid_records].enable = FALSE;
+ }
+
+ classx_str = g_slist_nth_data(tokens, 1);
+ if (!classx_str) {
+ dbg("Class error. Setting to the requested class: [%d]", req_info->class);
+ barring_resp.records[valid_records].class = req_info->class;
+ } else {
+ if (__atmodem_ss_convert_modem_class_to_class(atoi(classx_str),
+ &(barring_resp.records[valid_records].class)) == FALSE) {
+ tcore_at_tok_free(tokens);
+ continue;
+ }
+ }
+
+ barring_resp.records[valid_records].type= req_info->type;
+ result = TEL_SS_RESULT_SUCCESS;
+ valid_records++;
+ } else {
+ err("Invalid response message");
+ }
+ tcore_at_tok_free(tokens);
+ }
+ }
+
+ dbg("Getting Barring status: [%s]",
+ (result == TEL_SS_RESULT_SUCCESS ? "SUCCESS" : "FAIL"));
+ barring_resp.record_num = valid_records;
+
+ /* Invoke callback */
+ if (resp_cb_data->cb)
+ resp_cb_data->cb(co, (gint)result, &barring_resp, resp_cb_data->cb_data);
+
+ atmodem_destroy_resp_cb_data(resp_cb_data);
+
+ if (barring_resp.records) {
+ tcore_free(barring_resp.records);
+ }
+}
+
+static void on_response_atmodem_ss_change_barring_password(TcorePending *p,
+ guint data_len, const void *data, void *user_data)
+{
+ const TcoreAtResponse *at_resp = data;
+ CoreObject *co = tcore_pending_ref_core_object(p);
+ AtmodemRespCbData *resp_cb_data = user_data;
+
+ TelSsResult result = TEL_SS_RESULT_FAILURE; // TODO: CMEE error mapping is required
+ dbg("Enter");
+
+ tcore_check_return_assert(co != NULL);
+ tcore_check_return_assert(resp_cb_data != NULL);
+
+ if (at_resp && at_resp->success)
+ result = TEL_SS_RESULT_SUCCESS;
+
+ dbg("Change Barring Password: [%s]",
+ (result == TEL_SS_RESULT_SUCCESS ? "SUCCESS" : "FAIL"));
+
+ /* Invoke callback */
+ if (resp_cb_data->cb)
+ resp_cb_data->cb(co, (gint)result, NULL, resp_cb_data->cb_data);
+
+ atmodem_destroy_resp_cb_data(resp_cb_data);
+}
+
+static void on_response_atmodem_ss_set_forwarding(TcorePending *p,
+ guint data_len, const void *data, void *user_data)
+{
+ const TcoreAtResponse *at_resp = data;
+ CoreObject *co = tcore_pending_ref_core_object(p);
+ AtmodemRespCbData *resp_cb_data = user_data;
+
+ TelSsResult result = TEL_SS_RESULT_FAILURE; // TODO: CMEE error mapping is required
+ dbg("Enter");
+
+ tcore_check_return_assert(co != NULL);
+ tcore_check_return_assert(resp_cb_data != NULL);
+
+ if (at_resp && at_resp->success)
+ result = TEL_SS_RESULT_SUCCESS;
+
+ dbg("Set Forwarding Status: [%s]",
+ (result == TEL_SS_RESULT_SUCCESS ? "SUCCESS" : "FAIL"));
+
+ /* Invoke callback */
+ if (resp_cb_data->cb)
+ resp_cb_data->cb(co, (gint)result, NULL, resp_cb_data->cb_data);
+
+ atmodem_destroy_resp_cb_data(resp_cb_data);
+}
+
+static void on_response_atmodem_ss_get_forwarding_status(TcorePending *p,
+ guint data_len, const void *data, void *user_data)
+{
+ const TcoreAtResponse *at_resp = data;
+ CoreObject *co = tcore_pending_ref_core_object(p);
+ AtmodemRespCbData *resp_cb_data = user_data;
+ TelSsForwardingResp forwarding_resp = {0,};
+ TelSsForwardGetInfo *req_info;
+ gint valid_records = 0;
+ GSList *resp_data = NULL;
+
+ TelSsResult result = TEL_SS_RESULT_FAILURE; // TODO: CMEE error mapping is required
+ dbg("Enter");
+
+ tcore_check_return_assert(co != NULL);
+ tcore_check_return_assert(resp_cb_data != NULL);
+
+ req_info = (TelSsForwardGetInfo *)ATMODEM_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
+
+ if (at_resp) {
+ if (at_resp->lines && at_resp->success) {
+ resp_data = (GSList *) at_resp->lines;
+ forwarding_resp.record_num= g_slist_length(resp_data);
+ dbg("Total records: [%d]", forwarding_resp.record_num);
+ }
+ else {
+ err("RESPONSE - [NOK]");
+ }
+ } else {
+ err("No response data");
+ }
+
+ if (forwarding_resp.record_num > 0) {
+ forwarding_resp.records = tcore_malloc0(
+ (forwarding_resp.record_num) * sizeof(TelSsForwardingInfoRecord));
+ for (valid_records = 0; resp_data != NULL; resp_data = resp_data->next) {
+ const gchar *line;
+ GSList *tokens = NULL;
+
+ line = (const gchar *) resp_data->data;
+ tokens = tcore_at_tok_new(line);
+ if (g_slist_length(tokens) > 0) {
+ gchar *classx_str;
+ gchar *status = NULL;
+ gchar *number = NULL;
+ gchar *time_str = NULL;
+
+ status = g_slist_nth_data(tokens, 0);
+ if (!status) {
+ dbg("Status is missing");
+ tcore_at_tok_free(tokens);
+ continue;
+ }
+
+ if (atoi(status) == 1) {
+ forwarding_resp.records[valid_records].enable = TRUE;
+ } else {
+ forwarding_resp.records[valid_records].enable = FALSE;
+ }
+
+ classx_str = g_slist_nth_data(tokens, 1);
+ if (!classx_str) {
+ dbg("Class error. Setting to the requested class: [%d]", req_info->class);
+ forwarding_resp.records[valid_records].class = req_info->class;
+ } else {
+ if (__atmodem_ss_convert_modem_class_to_class(atoi(classx_str),
+ &(forwarding_resp.records[valid_records].class)) == FALSE) {
+ tcore_at_tok_free(tokens);
+ continue;
+ }
+ }
+
+ number = g_slist_nth_data(tokens, 2);
+ if (number)
+ memcpy((forwarding_resp.records[valid_records].number),
+ number, strlen(number));
+
+ time_str = g_slist_nth_data(tokens, 6);
+ if (time_str)
+ forwarding_resp.records[valid_records].wait_time = atoi(time_str);
+
+ forwarding_resp.records[valid_records].condition = req_info->condition;
+
+ result = TEL_SS_RESULT_SUCCESS;
+ valid_records++;
+ } else {
+ err("Invalid response message");
+ }
+ tcore_at_tok_free(tokens);
+ }
+ }
+
+ dbg("Getting Forwarding Status: [%s]",
+ (result == TEL_SS_RESULT_SUCCESS ? "SUCCESS" : "FAIL"));
+ forwarding_resp.record_num = valid_records;
+
+ /* Invoke callback */
+ if (resp_cb_data->cb)
+ resp_cb_data->cb(co, (gint)result, &forwarding_resp, resp_cb_data->cb_data);
+
+ atmodem_destroy_resp_cb_data(resp_cb_data);
+
+ if (forwarding_resp.records) {
+ tcore_free(forwarding_resp.records);
+ }
+}
+
+static void on_response_atmodem_ss_set_waiting(TcorePending *p,
+ guint data_len, const void *data, void *user_data)
+{
+ const TcoreAtResponse *at_resp = data;
+ CoreObject *co = tcore_pending_ref_core_object(p);
+ AtmodemRespCbData *resp_cb_data = user_data;
+
+ TelSsResult result = TEL_SS_RESULT_FAILURE; // TODO: CMEE error mapping is required
+ dbg("Enter");
+
+ tcore_check_return_assert(co != NULL);
+ tcore_check_return_assert(resp_cb_data != NULL);
+
+ if (at_resp && at_resp->success)
+ result = TEL_SS_RESULT_SUCCESS;
+
+ dbg("Set Waiting Status: [%s]",
+ (result == TEL_SS_RESULT_SUCCESS ? "SUCCESS" : "FAIL"));
+
+ /* Invoke callback */
+ if (resp_cb_data->cb)
+ resp_cb_data->cb(co, (gint)result, NULL, resp_cb_data->cb_data);
+
+ atmodem_destroy_resp_cb_data(resp_cb_data);
+}
+
+static void on_response_atmodem_ss_get_waiting_status(TcorePending *p,
+ guint data_len, const void *data, void *user_data)
+{
+ const TcoreAtResponse *at_resp = data;
+ CoreObject *co = tcore_pending_ref_core_object(p);
+ AtmodemRespCbData *resp_cb_data = user_data;
+ TelSsWaitingResp waiting_resp = {0,};
+ TelSsClass *class;
+ gint valid_records = 0;
+ GSList *resp_data = NULL;
+
+ TelSsResult result = TEL_SS_RESULT_FAILURE; // TODO: CMEE error mapping is required
+ dbg("Enter");
+
+ tcore_check_return_assert(co != NULL);
+ tcore_check_return_assert(resp_cb_data != NULL);
+
+ class = (TelSsClass *)ATMODEM_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
+
+ if (at_resp) {
+ if (at_resp->lines && at_resp->success) {
+ resp_data = (GSList *) at_resp->lines;
+ waiting_resp.record_num= g_slist_length(resp_data);
+ dbg("Total records: [%d]", waiting_resp.record_num);
+ }
+ else {
+ err("RESPONSE - [NOK]");
+ }
+ } else {
+ err("No response data");
+ }
+
+ if (waiting_resp.record_num > 0) {
+ waiting_resp.records = tcore_malloc0(
+ (waiting_resp.record_num) * sizeof(TelSsWaitingInfo));
+ for (valid_records = 0; resp_data != NULL; resp_data = resp_data->next) {
+ const gchar *line;
+ GSList *tokens = NULL;
+
+ line = (const gchar *) resp_data->data;
+ tokens = tcore_at_tok_new(line);
+ if (g_slist_length(tokens) > 0) {
+ gchar *classx_str;
+ gchar *status = NULL;
+
+ status = g_slist_nth_data(tokens, 0);
+ if (!status) {
+ dbg("Status is missing");
+ tcore_at_tok_free(tokens);
+ continue;
+ }
+
+ if (atoi(status) == 1) {
+ waiting_resp.records[valid_records].enable= TRUE;
+ } else {
+ waiting_resp.records[valid_records].enable = FALSE;
+ }
+
+ classx_str = g_slist_nth_data(tokens, 1);
+ if (!classx_str) {
+ dbg("Class error. Setting to the requested class: [%d]", *class);
+ waiting_resp.records[valid_records].class = *class;
+ } else {
+ if (__atmodem_ss_convert_modem_class_to_class(atoi(classx_str),
+ &(waiting_resp.records[valid_records].class)) == FALSE) {
+ tcore_at_tok_free(tokens);
+ continue;
+ }
+ }
+
+ result = TEL_SS_RESULT_SUCCESS;
+ valid_records++;
+ } else {
+ err("Invalid response message");
+ }
+ tcore_at_tok_free(tokens);
+ }
+ }
+
+ dbg("Getting Waiting Status: [%s]",
+ (result == TEL_SS_RESULT_SUCCESS ? "SUCCESS" : "FAIL"));
+ waiting_resp.record_num = valid_records;
+
+ /* Invoke callback */
+ if (resp_cb_data->cb)
+ resp_cb_data->cb(co, (gint)result,
+ &waiting_resp, resp_cb_data->cb_data);
+
+ atmodem_destroy_resp_cb_data(resp_cb_data);
+
+ if (waiting_resp.records)
+ tcore_free(waiting_resp.records);
+}
+
+static void on_response_atmodem_ss_get_cli_status(TcorePending *p,
+ guint data_len, const void *data, void *user_data)
+{
+ const TcoreAtResponse *at_resp = data;
+ CoreObject *co = tcore_pending_ref_core_object(p);
+ AtmodemRespCbData *resp_cb_data = user_data;
+ TelSsCliResp cli_resp = {0,};
+ TelSsCliType *cli_type;
+ GSList *tokens = NULL;
+
+ TelSsResult result = TEL_SS_RESULT_FAILURE; // TODO: CMEE error mapping is required
+ dbg("Enter");
+
+ tcore_check_return_assert(co != NULL);
+ tcore_check_return_assert(resp_cb_data != NULL);
+
+ cli_type = (TelSsCliType *)ATMODEM_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
+
+ if (*cli_type == TEL_SS_CLI_CDIP) {
+ err("Unsupported CLI type: [%d]", *cli_type);
+ result = TEL_SS_RESULT_INVALID_PARAMETER;
+ goto out;
+ }
+
+ if (at_resp && at_resp->success) {
+ const gchar *line;
+ gchar *status = NULL;
+ gint net_status;
+ gint dev_status;
+
+ if (!at_resp->lines) {
+ err("Invalid response message");
+ goto out;
+ }
+ line = (const gchar *)at_resp->lines->data;
+ tokens = tcore_at_tok_new(line);
+ if (g_slist_length(tokens) < 1) {
+ err("Invalid response message");
+ goto out;
+ }
+
+ dbg("RESPONSE OK");
+ status = g_slist_nth_data(tokens, 0);
+ if (!status) {
+ err("dev_status is missing");
+ goto out;
+ }
+ if (!__atmodem_ss_convert_modem_cli_dev_status_cli_status(*cli_type,
+ atoi(status), &dev_status))
+ goto out;
+
+ status = g_slist_nth_data(tokens, 1);
+ if (!status) {
+ err("net_status is missing");
+ goto out;
+ }
+ if (!__atmodem_ss_convert_modem_cli_net_status_cli_status(*cli_type,
+ atoi(status), &net_status))
+ goto out;
+
+ switch (*cli_type){
+ case TEL_SS_CLI_CLIR:
+ cli_resp.status.clir.net_status = net_status;
+ cli_resp.status.clir.dev_status = dev_status;
+ break;
+
+ case TEL_SS_CLI_CLIP:
+ cli_resp.status.clip.net_status = net_status;
+ cli_resp.status.clip.dev_status = dev_status;
+ break;
+
+ case TEL_SS_CLI_COLP:
+ cli_resp.status.colp.net_status = net_status;
+ cli_resp.status.colp.dev_status = dev_status;
+ break;
+
+ case TEL_SS_CLI_COLR:
+ cli_resp.status.colr.net_status = net_status;
+ cli_resp.status.colr.dev_status = dev_status;
+ break;
+
+ case TEL_SS_CLI_CNAP:
+ cli_resp.status.cnap.net_status = net_status;
+ cli_resp.status.cnap.dev_status = dev_status;
+ break;
+
+ default:
+ err("Unsupported CLI type: [%d]", *cli_type);
+ result = TEL_SS_RESULT_INVALID_PARAMETER;
+ goto out;
+ }
+
+ cli_resp.type = *cli_type;
+ } else {
+ err("RESPONSE NOK");
+ }
+
+out:
+ tcore_at_tok_free(tokens);
+
+ /* Invoke callback */
+ if (resp_cb_data->cb)
+ resp_cb_data->cb(co, (gint)result,
+ &cli_resp, resp_cb_data->cb_data);
+
+ atmodem_destroy_resp_cb_data(resp_cb_data);
+}
+
+static void on_response_atmodem_ss_send_ussd_request(TcorePending *p,
+ guint data_len, const void *data, void *user_data)
+{
+ const TcoreAtResponse *at_resp = data;
+ CoreObject *co = tcore_pending_ref_core_object(p);
+ AtmodemRespCbData *resp_cb_data = user_data;
+ TelSsUssdResp ussd_resp = {0,};
+ UssdSession *ussd_s = NULL;
+
+
+ TelSsResult result = TEL_SS_RESULT_FAILURE; // TODO: CMEE error mapping is required
+ dbg("Enter");
+
+ tcore_check_return_assert(co != NULL);
+ tcore_check_return_assert(resp_cb_data != NULL);
+
+ ussd_s = tcore_ss_ussd_get_session(co);
+ tcore_check_return(ussd_s != NULL);
+
+ tcore_ss_ussd_get_session_type(ussd_s, &ussd_resp.type);
+
+ if (at_resp && at_resp->success)
+ result = TEL_SS_RESULT_SUCCESS;
+
+ dbg("Send Ussd Request: [%s]",
+ (result == TEL_SS_RESULT_SUCCESS ? "SUCCESS" : "FAIL"));
+
+ tcore_ss_ussd_destroy_session(ussd_s);
+
+ /* Invoke callback */
+ if (resp_cb_data->cb)
+ resp_cb_data->cb(co, (gint)result, &ussd_resp, resp_cb_data->cb_data);
+
+ atmodem_destroy_resp_cb_data(resp_cb_data);
+}
+
+/* SS Operations */
+/*
+ * Operation - set_barring/get_barring_status
+ *
+ * Request -
+ * AT-Command: AT+CLCK=<fac>,<mode>[,<passwd>[,<class>]]
+ * where,
+ * <fac>
+ * Barring facility type. Ref #TelSsBarringType
+ *
+ * <mode>
+ * 0 unlock
+ * 1 lock
+ * 2 query status
+ *
+ * <passwd>
+ * Barring Password
+ *
+ * <class>
+ * SS class. Ref #TelSsClass
+ *
+ * <status>
+ * 0 not active
+ * 1 active
+ *
+ * Success: when <mode>=2:
+ * OK
+ * +CLCK: <status>[,<class1> [<CR><LF>
+ * +CLCK: <status>,<class2> [...]]
+ *
+ * Failure:
+ * +CME ERROR: <error>
+ */
+static TelReturn atmodem_ss_set_barring(CoreObject *co,
+ const TelSsBarringInfo *barring_info,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ gchar *at_cmd = NULL;
+ guint mode;
+ guint classx;
+ gchar *facility = NULL;
+ AtmodemRespCbData *resp_cb_data = NULL;
+ TelReturn ret = TEL_RETURN_INVALID_PARAMETER;
+
+ if (barring_info->enable == TRUE)
+ mode = 1;
+ else
+ mode = 0;
+
+ if (__atmodem_ss_convert_barring_type_to_facility(
+ barring_info->type, &facility) == FALSE) {
+ err("Invalid arguments");
+ return ret;
+ }
+
+ classx = __atmodem_ss_convert_class_to_atmodem_class(barring_info->class);
+
+ dbg("facility: [%s], classx:[%d], mode: [%d]", facility, classx, mode);
+
+ /* AT-Command */
+ at_cmd = g_strdup_printf("AT+CLCK=\"%s\",%d,\"%s\",%d",
+ facility, mode, barring_info->pwd, classx);
+
+ resp_cb_data = atmodem_create_resp_cb_data(cb, cb_data, NULL, 0);
+
+ /* Send Request to modem */
+ ret = tcore_at_prepare_and_send_request(co,
+ at_cmd, NULL,
+ TCORE_AT_COMMAND_TYPE_NO_RESULT,
+ TCORE_PENDING_PRIORITY_DEFAULT,
+ NULL,
+ on_response_atmodem_ss_set_barring, resp_cb_data,
+ on_send_atmodem_request, NULL,
+ 0, NULL, NULL);
+ ATMODEM_CHECK_REQUEST_RET(ret, resp_cb_data, "Set Barring");
+
+ g_free(at_cmd);
+ return ret;
+}
+
+static TelReturn atmodem_ss_get_barring_status(CoreObject *co,
+ const TelSsBarringGetInfo *get_barring_info,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ gchar *at_cmd = NULL;
+ guint mode;
+ guint classx;
+ gchar *facility = NULL;
+ AtmodemRespCbData *resp_cb_data = NULL;
+ TelReturn ret = TEL_RETURN_INVALID_PARAMETER;
+
+ mode = 2; /* query status - mode is fixed to 2 */
+
+ if (__atmodem_ss_convert_barring_type_to_facility(
+ get_barring_info->type, &facility) == FALSE) {
+ err("Invalid arguments");
+ return ret;
+ }
+
+ classx = __atmodem_ss_convert_class_to_atmodem_class(get_barring_info->class);
+
+ dbg("facility: [%s], classx:[%d], mode: [%d]", facility, classx, mode);
+
+ /* AT-Command */
+ at_cmd = g_strdup_printf("AT+CLCK=\"%s\",%d,,%d",
+ facility, mode, classx);
+
+ resp_cb_data = atmodem_create_resp_cb_data(cb, cb_data,
+ (void *)get_barring_info, sizeof(TelSsBarringGetInfo));
+
+ /* Send Request to modem */
+ ret = tcore_at_prepare_and_send_request(co,
+ at_cmd, "+CLCK",
+ TCORE_AT_COMMAND_TYPE_MULTILINE,
+ TCORE_PENDING_PRIORITY_DEFAULT,
+ NULL,
+ on_response_atmodem_ss_get_barring_status, resp_cb_data,
+ on_send_atmodem_request, NULL,
+ 0, NULL, NULL);
+ ATMODEM_CHECK_REQUEST_RET(ret, resp_cb_data, "Get Barring Status");
+
+ g_free(at_cmd);
+ return ret;
+}
+
+/*
+ * Operation - change_barring_password
+ *
+ * Request -
+ * AT-Command: AT+CPWD= <fac>,<oldpwd>,<newpwd>
+ * where,
+ * <fac>
+ * Barring facility type. Ref #TelSsBarringType
+ * Eg: "AB" All Barring services
+ *
+ * <oldpwd>
+ * Old Barring Password
+ *
+ * <newpwd>
+ * New Barring Password
+ *
+ * Success:
+ * OK
+ *
+ * Failure:
+ * +CME ERROR: <error>
+ */
+static TelReturn atmodem_ss_change_barring_password(CoreObject *co,
+ const TelSsBarringPwdInfo *barring_pwd_info,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ gchar *at_cmd = NULL;
+ AtmodemRespCbData *resp_cb_data = NULL;
+ TelReturn ret = TEL_RETURN_INVALID_PARAMETER;
+
+ if (barring_pwd_info->old_pwd== NULL || barring_pwd_info->new_pwd == NULL) {
+ err("Invalid data");
+ return ret;
+ }
+
+ dbg("Old password: [%s], New password: [%s]",
+ barring_pwd_info->old_pwd, barring_pwd_info->new_pwd);
+
+ at_cmd = g_strdup_printf("AT+CPWD=\"%s\",\"%s\",\"%s\"", "AB",
+ barring_pwd_info->old_pwd, barring_pwd_info->new_pwd);
+
+ resp_cb_data = atmodem_create_resp_cb_data(cb, cb_data, NULL, 0);
+
+ /* Send Request to modem */
+ ret = tcore_at_prepare_and_send_request(co,
+ at_cmd, NULL,
+ TCORE_AT_COMMAND_TYPE_NO_RESULT,
+ TCORE_PENDING_PRIORITY_DEFAULT,
+ NULL,
+ on_response_atmodem_ss_change_barring_password, resp_cb_data,
+ on_send_atmodem_request, NULL,
+ 0, NULL, NULL);
+ ATMODEM_CHECK_REQUEST_RET(ret, resp_cb_data, "Change Barring Password");
+
+ g_free(at_cmd);
+ return ret;
+}
+
+/*
+ * Operation - set_forwarding/get_forwarding_status
+ *
+ * Request -
+ * AT-Command: AT+CCFC=<reason>,<mode>[,<number>[,<type>[,<class>[,<subaddr>[,<satype>[,<time>]]]]]]
+ * where,
+ * <reason>
+ * Forwarding Condition. Ref #TelSsForwardCondition
+ *
+ * <mode>
+ * Forwarding Mode. Ref #TelSsForwardMode
+ * 0 disable
+ * 1 enable
+ * 2 query status
+ * 3 registration
+ * 4 erasure
+ *
+ *
+ * <number>
+ * Call Forwarding Number
+ *
+ * <type>
+ * Default 145 when available string includes "+"
+ * Otherwise 129
+ *
+ * <subaddr>
+ * Parameter String type subaddress of format specified by <satype>
+ *
+ * <satype>
+ * Parameter type of subaddress octet in integer format
+ * Default 128
+ *
+ * <time>
+ * Parameter time in seconds to wait before call is forwarded
+ * Default 20, but only when <reason>=2 (no reply) is enabled
+ *
+ * <class>
+ * SS class. Ref #TelSsClass
+ *
+ * <status>
+ * 0 not active
+ * 1 active
+ *
+ * Success: when <mode>=2:
+ * OK
+ * +CCFC: <status>,<class1>[,<number>,<type>[,<subaddr>,<satype>[,<time>]]][<CR><LF>
+ * +CCFC: <status>,<class2>[,<number>,<type>[,<subaddr>,<satype>[,<time>]]][...]]
+ *
+ * Failure:
+ * +CME ERROR: <error>
+ */
+static TelReturn atmodem_ss_set_forwarding(CoreObject *co,
+ const TelSsForwardInfo *forwarding_info,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ gchar *at_cmd = NULL;
+ gchar *tmp_cmd = NULL;
+ guint classx;
+ guint reason;
+ guint mode;
+ guint num_type;
+ AtmodemRespCbData *resp_cb_data = NULL;
+ TelReturn ret = TEL_RETURN_INVALID_PARAMETER;
+
+ classx = __atmodem_ss_convert_class_to_atmodem_class(forwarding_info->class);
+
+ if (__atmodem_ss_convert_forwarding_mode_to_modem_mode(
+ forwarding_info->mode, &mode) == FALSE) {
+ err("Invalid arguments");
+ return ret;
+ }
+
+ if (__atmodem_ss_convert_forwarding_condition_to_modem_reason(
+ forwarding_info->condition, &reason) == FALSE) {
+ err("Invalid arguments");
+ return ret;
+ }
+
+ if (forwarding_info->number[0] == '+')
+ num_type = 145;
+ else
+ num_type = 129;
+
+ dbg("classx: [%d], reason:[%d], mode: [%d]", classx, reason, mode);
+
+ if (mode == 3) /* TEL_SS_CF_MODE_REGISTER */
+ tmp_cmd = g_strdup_printf("AT+CCFC=%d,%d,\"%s\",%d,%d",
+ reason, mode, forwarding_info->number, num_type, classx);
+ else
+ tmp_cmd = g_strdup_printf("AT+CCFC=%d,%d,,,%d",
+ reason, mode, classx);
+
+ if (reason == 2) /* TEL_SS_CF_COND_CFNRY */
+ at_cmd = g_strdup_printf("%s,,,%d", tmp_cmd, forwarding_info->wait_time);
+ else
+ at_cmd = g_strdup_printf("%s", tmp_cmd);
+
+ resp_cb_data = atmodem_create_resp_cb_data(cb, cb_data, NULL, 0);
+
+ /* Send Request to modem */
+ ret = tcore_at_prepare_and_send_request(co,
+ at_cmd, NULL,
+ TCORE_AT_COMMAND_TYPE_NO_RESULT,
+ TCORE_PENDING_PRIORITY_DEFAULT,
+ NULL,
+ on_response_atmodem_ss_set_forwarding, resp_cb_data,
+ on_send_atmodem_request, NULL,
+ 0, NULL, NULL);
+ ATMODEM_CHECK_REQUEST_RET(ret, resp_cb_data, "Set Forwarding");
+
+ g_free(tmp_cmd);
+ g_free(at_cmd);
+ return ret;
+}
+
+static TelReturn atmodem_ss_get_forwarding_status(CoreObject *co,
+ const TelSsForwardGetInfo *get_forwarding_info,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ gchar *at_cmd = NULL;
+ guint classx;
+ guint reason;
+ guint mode = 2; /* query status */
+ AtmodemRespCbData *resp_cb_data = NULL;
+ TelReturn ret = TEL_RETURN_INVALID_PARAMETER;
+
+ classx = __atmodem_ss_convert_class_to_atmodem_class(get_forwarding_info->class);
+
+ if (__atmodem_ss_convert_forwarding_condition_to_modem_reason(
+ get_forwarding_info->condition, &reason) == FALSE) {
+ err("Invalid arguments");
+ return ret;
+ }
+
+ dbg("classx: [%d], reason: [%d], mode: [%d]", classx, reason, mode);
+
+ at_cmd = g_strdup_printf("AT+CCFC=%d,%d,,,%d", reason, mode, classx);
+
+ resp_cb_data = atmodem_create_resp_cb_data(cb, cb_data,
+ (void *)get_forwarding_info, sizeof(TelSsForwardGetInfo));
+
+ /* Send Request to modem */
+ ret = tcore_at_prepare_and_send_request(co,
+ at_cmd, "+CCFC",
+ TCORE_AT_COMMAND_TYPE_MULTILINE,
+ TCORE_PENDING_PRIORITY_DEFAULT,
+ NULL,
+ on_response_atmodem_ss_get_forwarding_status, resp_cb_data,
+ on_send_atmodem_request, NULL,
+ 0, NULL, NULL);
+ ATMODEM_CHECK_REQUEST_RET(ret, resp_cb_data, "Get Forwarding Status");
+
+ g_free(at_cmd);
+ return ret;
+}
+
+/*
+ * Operation - set_waiting/get_waiting_status
+ *
+ * Request -
+ * AT-Command: AT+CCWA=[<n>[,<mode>[,<class>]]]
+ * where,
+ * <n>
+ * Parameter Sets/shows the result code presentation status to the TE.
+ * 0 presentation status is disabled to TE(default)
+ * 1 presentation status is enabled to TE
+ *
+ * <mode>
+ * 0 Disable call waiting
+ * 1 Enable call waiting
+ * 2 Query status
+ *
+ * <class>
+ * SS class. Ref #TelSsClass
+ *
+ * <status>
+ * 0 not active
+ * 1 active
+ *
+ * Success: when <mode>=2:
+ * OK
+ * +CCWA: <status>,<class1>
+ * +CCWA: <status>,<class2>
+ *
+ * Failure:
+ * +CME ERROR: <error>
+ */
+static TelReturn atmodem_ss_set_waiting(CoreObject *co,
+ const TelSsWaitingInfo *waiting_info,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ gchar *at_cmd = NULL;
+ guint classx;
+ guint mode;
+ AtmodemRespCbData *resp_cb_data = NULL;
+ TelReturn ret = TEL_RETURN_INVALID_PARAMETER;
+
+ if (waiting_info->enable == TRUE)
+ mode = 1;
+ else
+ mode = 0;
+
+ classx = __atmodem_ss_convert_class_to_atmodem_class(waiting_info->class);
+
+ dbg("mode: [%d], class: [%d]", mode, classx);
+
+ at_cmd = g_strdup_printf("AT+CCWA=1,%d,%d", mode, classx);
+
+ resp_cb_data = atmodem_create_resp_cb_data(cb, cb_data, NULL, 0);
+
+ /* Send Request to modem */
+ ret = tcore_at_prepare_and_send_request(co,
+ at_cmd, NULL,
+ TCORE_AT_COMMAND_TYPE_NO_RESULT,
+ TCORE_PENDING_PRIORITY_DEFAULT,
+ NULL,
+ on_response_atmodem_ss_set_waiting, resp_cb_data,
+ on_send_atmodem_request, NULL,
+ 0, NULL, NULL);
+ ATMODEM_CHECK_REQUEST_RET(ret, resp_cb_data, "Set Waiting");
+
+ g_free(at_cmd);
+ return ret;
+}
+
+static TelReturn atmodem_ss_get_waiting_status(CoreObject *co,
+ TelSsClass ss_class,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ gchar *at_cmd = NULL;
+ guint classx;
+ AtmodemRespCbData *resp_cb_data = NULL;
+ TelReturn ret = TEL_RETURN_INVALID_PARAMETER;
+
+ classx = __atmodem_ss_convert_class_to_atmodem_class(ss_class);
+
+ dbg("class: [%d]", classx);
+
+ at_cmd = g_strdup_printf("AT+CCWA=1,2,%d", classx);
+
+ resp_cb_data = atmodem_create_resp_cb_data(cb, cb_data,
+ &ss_class, sizeof(TelSsClass));
+
+ /* Send Request to modem */
+ ret = tcore_at_prepare_and_send_request(co,
+ at_cmd, "+CCWA",
+ TCORE_AT_COMMAND_TYPE_MULTILINE,
+ TCORE_PENDING_PRIORITY_DEFAULT,
+ NULL,
+ on_response_atmodem_ss_get_waiting_status, resp_cb_data,
+ on_send_atmodem_request, NULL,
+ 0, NULL, NULL);
+ ATMODEM_CHECK_REQUEST_RET(ret, resp_cb_data, "Get Waiting Status");
+
+ g_free(at_cmd);
+ return ret;
+}
+
+/*
+ * Operation - get_cli_status
+ *
+ * Request -
+ * AT-Command:
+ * For CLIR: AT+CLIR?
+ * For CLIP: AT+CLIP?
+ * For COLP: AT+COLP?
+ * For COLR: AT+COLR?
+ * For CNAP: AT+CNAP?
+ *
+ * Success:
+ * OK
+ * +CLIR: <n>,<m>
+ *
+ * where,
+ * <m> All CLI except CLIR
+ * 0 Not provisioned
+ * 1 Provisioned
+ * 2 Unknown
+ *
+ *<m> For CLIR
+ * 0 Not provisioned
+ * 1 Provisioned in permanent mode
+ * 2 Unknown (e.g. no network, etc.)
+ * 3 Temporary mode presentation restricted
+ * 4 Temporary mode presentation allowed
+ *
+ * Failure:
+ * +CME ERROR: <error>
+ */
+static TelReturn atmodem_ss_get_cli_status(CoreObject *co,
+ TelSsCliType cli_type,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ gchar *at_cmd = NULL;
+ gchar *cmd_prefix = NULL;
+ AtmodemRespCbData *resp_cb_data = NULL;
+ TelReturn ret = TEL_RETURN_INVALID_PARAMETER;
+
+ switch (cli_type) {
+ case TEL_SS_CLI_CLIR:
+ cmd_prefix = "+CLIR";
+ break;
+
+ case TEL_SS_CLI_CLIP:
+ cmd_prefix = "+CLIP";
+ break;
+
+ case TEL_SS_CLI_COLP:
+ cmd_prefix = "+COLP";
+ break;
+
+ case TEL_SS_CLI_COLR:
+ cmd_prefix = "+COLR";
+ break;
+
+ case TEL_SS_CLI_CNAP:
+ cmd_prefix = "+CNAP";
+ break;
+
+ case TEL_SS_CLI_CDIP:
+ default:
+ dbg("Unsupported CLI type: [%d]", cli_type);
+ return ret;
+ }
+
+ at_cmd = g_strdup_printf("AT%s?", cmd_prefix);
+
+ resp_cb_data = atmodem_create_resp_cb_data(cb, cb_data, &cli_type, sizeof(TelSsCliType));
+
+ /* Send Request to modem */
+ ret = tcore_at_prepare_and_send_request(co,
+ at_cmd, cmd_prefix,
+ TCORE_AT_COMMAND_TYPE_SINGLELINE,
+ TCORE_PENDING_PRIORITY_DEFAULT,
+ NULL,
+ on_response_atmodem_ss_get_cli_status, resp_cb_data,
+ on_send_atmodem_request, NULL,
+ 0, NULL, NULL);
+ ATMODEM_CHECK_REQUEST_RET(ret, resp_cb_data, "Get Cli Status");
+
+ g_free(at_cmd);
+ return ret;
+}
+
+/*
+ * Operation - send_ussd_request
+ *
+ * Request -
+ * AT-Command: AT+CUSD = [<n> [, <str> [, <dcs>]]]
+ * where,
+ * <n>
+ * 0 Disable the result code presentation to the TE(default)
+ * 1 Enable the result code presentation to the TE
+ * 2 Cancel session (not applicable to read command response)
+ *
+ * <str>
+ * USSD string
+ *
+ * <dcs>
+ * Cell Broadcast Data Coding Scheme. Default value is 0.
+ *
+ * Success:
+ * OK
+ *
+ * Failure:
+ * +CME ERROR: <error>
+ */
+static TelReturn atmodem_ss_send_ussd_request(CoreObject *co,
+ const TelSsUssdInfo *ussd_request,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ gchar *at_cmd = NULL;
+ UssdSession *ussd_s = NULL;
+ AtmodemRespCbData *resp_cb_data = NULL;
+ TelReturn ret = TEL_RETURN_INVALID_PARAMETER;
+
+ ussd_s = tcore_ss_ussd_get_session(co);
+ if (!ussd_s) {
+ dbg("USSD session does not exist");
+ tcore_ss_ussd_create_session(co, ussd_request->type,
+ (void *)ussd_request->str,
+ strlen((gchar *)ussd_request->str));
+ } else {
+ if (ussd_request->type == TEL_SS_USSD_TYPE_USER_INIT) {
+ err("USSD session exists");
+ return TEL_RETURN_OPERATION_NOT_SUPPORTED;
+ }
+ tcore_ss_ussd_set_session_type(ussd_s, ussd_request->type);
+ }
+
+ at_cmd = g_strdup_printf("AT+CUSD=1,\"%s\",%d", ussd_request->str, 0x0f);
+
+ resp_cb_data = atmodem_create_resp_cb_data(cb, cb_data, NULL, 0);
+
+ /* Send Request to modem */
+ ret = tcore_at_prepare_and_send_request(co,
+ at_cmd, NULL,
+ TCORE_AT_COMMAND_TYPE_NO_RESULT,
+ TCORE_PENDING_PRIORITY_DEFAULT,
+ NULL,
+ on_response_atmodem_ss_send_ussd_request, resp_cb_data,
+ on_send_atmodem_request, NULL,
+ 0, NULL, NULL);
+ ATMODEM_CHECK_REQUEST_RET(ret, resp_cb_data, "Send Ussd Request");
+
+ g_free(at_cmd);
+ return ret;
+}
+
+/* SS Operations */
+static TcoreSsOps atmodem_ss_ops = {
+ .set_barring = atmodem_ss_set_barring,
+ .get_barring_status = atmodem_ss_get_barring_status,
+ .change_barring_password = atmodem_ss_change_barring_password,
+ .set_forwarding = atmodem_ss_set_forwarding,
+ .get_forwarding_status = atmodem_ss_get_forwarding_status,
+ .set_waiting = atmodem_ss_set_waiting,
+ .get_waiting_status = atmodem_ss_get_waiting_status,
+ .set_cli = NULL,
+ .get_cli_status = atmodem_ss_get_cli_status,
+ .send_ussd_request = atmodem_ss_send_ussd_request
+};
+
+gboolean atmodem_ss_init(TcorePlugin *p, CoreObject *co)
+{
+ dbg("Entry");
+
+ /* Set operations */
+ tcore_ss_set_ops(co, &atmodem_ss_ops);
+
+ /* Add Callbacks */
+ tcore_object_add_callback(co,
+ "+CUSD:",
+ on_notification_atmodem_ss_ussd, NULL);
+
+ dbg("Exit");
+ return TRUE;
+}
+
+void atmodem_ss_exit(TcorePlugin *p, CoreObject *co)
+{
+ dbg("Exit");
+}
+++ /dev/null
-/*
- * tel-plugin-atmodem
- *
- * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: Hayoon Ko <hayoon.ko@samsung.com>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <ctype.h>
-#include <string.h>
-#include <glib.h>
-
-#include <tcore.h>
-#include <plugin.h>
-#include <hal.h>
-#include <server.h>
-#include <queue.h>
-#include <core_object.h>
-
-#include "s_common.h"
-#include "s_sim.h"
-#include "s_ps.h"
-#include "s_call.h"
-#include "s_ss.h"
-#include "s_sms.h"
-#include "s_network.h"
-#include "s_modem.h"
-#include "atchannel.h"
-#include "at_tok.h"
-
-static char s_ATBuffer[MAX_AT_RESPONSE+1];
-static char *s_ATBufferCur = s_ATBuffer;
-
-struct sms_pdu_control
-{
- gboolean sms_pdu_mode;
-
- int sms_pdu_len;
- int cum_pdu_len;
- char* line1 ;
- char* ppdu ;
- char* ppdu_marker;
-};
-
-static struct sms_pdu_control spc;
-
-static int s_readCount = 0;
-
-enum ATCommandType s_type;
-char *s_responsePrefix= NULL;
-struct ATResponse *sp_response= NULL;
-
-
-static const char * s_smsUnsoliciteds[] = {
- "+CMT:"
-};
-
-static int isSMSUnsolicited(const char *line)
-{
- unsigned int i;
-
- for (i = 0 ; i < NUM_ELEMS(s_smsUnsoliciteds) ; i++) {
- if (strStartsWith(line, s_smsUnsoliciteds[i])) {
- return 1;
- }
- }
-
- return 0;
-}
-
-static void startSMSBuffering(char* line)
-{
- char* temp_line = NULL;
- int sms_pdu_len;
-
- spc.line1 = strdup(line);
-
- temp_line = line;
-
- at_tok_start(&temp_line);
- at_tok_nextint(&temp_line, &sms_pdu_len);
-
- dbg("total pdu length : %d", sms_pdu_len);
- spc.sms_pdu_len = sms_pdu_len;
-
- //allocate pdu buffer
- spc.ppdu = malloc(sizeof(char) *sms_pdu_len);
- spc.sms_pdu_mode = TRUE;
- spc.cum_pdu_len = 0;
-}
-
-static void stopSMSBuffering()
-{
- if(spc.line1 != NULL)
- free(spc.line1);
- spc.line1 = NULL;
-
- spc.sms_pdu_len = 0;
- spc.cum_pdu_len =0;
-
- spc.sms_pdu_mode = FALSE;
-
- if(spc.ppdu !=NULL)
- free(spc.ppdu);
- spc.ppdu = NULL;
-
- spc.ppdu_marker = NULL;
-
- dbg("sms pdu data buffering ended!");
-}
-
-static void handleFinalResponse(TcoreHal* hal, const char *line)
-{
- dbg("Final response arrived. call response callback");
-
- // 1. add final rsp string into sp_response
- sp_response->finalResponse = strdup(line);
-
- // 1.1 reverse intermediates
- reverseIntermediates(sp_response);
-
- // 2. pop head pending from queue -> call callback hung pending(on_response) ->
- // release sp_response/s_responsePrefix -> release userRequest/pending -> send next pending from queue
- // warning) length have no meaning. data always pointer sp_response
- tcore_hal_dispatch_response_data(hal, ID_RESERVED_AT, strlen(line), sp_response);
-}
-
-static void onUnsolicited (const char *s, TcorePlugin* plugin, char* sms_pdu, int pdu_len)
-{
- char *line = NULL, *p= NULL;
- char *cmd = NULL;
- struct smsDeliveryPDU smsPdu;
-
- int id;
- int status, direction;
-
- dbg("%s", s);
-
-#define STATUS_INCOMING 4
-#define STATUS_WAITING 5
-
-
- if(strStartsWith(s,"+CMT:")){
- //SMS incoming
- cmd = EVENT_SMS_INCOM_MSG;
-
- smsPdu.cmdLine = strdup(s);
- smsPdu.pdu = malloc(pdu_len);
- memcpy(smsPdu.pdu, sms_pdu, pdu_len);
- smsPdu.len = pdu_len;
-
- tcore_plugin_core_object_event_emit(plugin, cmd, &smsPdu);
- free(smsPdu.cmdLine);
- free(smsPdu.pdu);
-
- return;
- }
- /* Ignore unsolicited responses until we're initialized.
- * This is OK because the RIL library will poll for initial state
- */
- else if (strStartsWith(s,"%SCFUN:")){
- /* SS specific -- modem power status notification */
- cmd = EVENT_MODEM_PHONE_STATE;
- }
- else if(strStartsWith(s,"%SCSIM:")){
- cmd = EVENT_SIM_PIN_STATUS;
- }
- else if(strStartsWith(s,"%SCLCC:")){
- line = strdup(s);
- p = line;
-
- at_tok_start(&p);
- at_tok_nextint(&p, &id);
- at_tok_nextint(&p, &direction);
- at_tok_nextint(&p, &status);
-
- switch(status){
- case STATUS_INCOMING:
- cmd = EVENT_CALL_INCOMING;
- break;
- case STATUS_WAITING:
- cmd = EVENT_CALL_WAITING;
- break;
- default:
- cmd = EVENT_CALL_STATUS;
- break;
- }
-
- free(line);
-
- dbg("%SCLCC cmd : %d",cmd);
- }
- else if (strStartsWith(s,"+CRING:")
- || strStartsWith(s,"RING")){
- dbg("incoming call notification - wait for SCLCC with status 4");
- return;
- }
- else if (strStartsWith(s,"CONNECT")){
- dbg("call connect notification - wait for SCLCC with status 0");
- return;
- }
- else if (strStartsWith(s,"NO CARRIER")){
- dbg("call release notification - wait for SCLCC with status 7");
- return ;
- }
- else if(strStartsWith(s,"+CCWA:")){
- dbg("call waiting notification - wait for SCLCC with status 5");
- return;
- }
- else if (strStartsWith(s,"+CREG:")
- || strStartsWith(s,"+CGREG:")){
- cmd = EVENT_NETWORK_REGISTRATION;
- }
- else if (strStartsWith(s,"+CMGS:")) {
- cmd = EVENT_SMS_SEND_ACK;
- }
- else if (strStartsWith(s,"%SCDEV:")) {
- cmd = EVENT_SMS_DEVICE_READY;
- }
- else if(strStartsWith(s,"+CIEV:")){
- cmd = EVENT_NETWORK_ICON_INFO;
- }
- else if (strStartsWith(s,"+CSSU:")){
- cmd = EVENT_SS_INFO;
- }
- else if (strStartsWith(s,"+CUSD:")){
- cmd = EVENT_SS_USSD;
- }
-
- /* Send Event */
- if(cmd)
- {
- line = strdup(s);
- tcore_plugin_core_object_event_emit(plugin, cmd, line);
- free(line);
- }
-
-}
-
-static void processLine(TcoreHal *hal, char *line, TcorePlugin* p)
-{
- TcoreQueue* pPendingQueue = NULL;
- TcorePending* pPending =NULL;
- gboolean result_status = FALSE;
- pPendingQueue =(TcoreQueue*)tcore_hal_ref_queue(hal);
- pPending = (TcorePending*)tcore_queue_ref_head(pPendingQueue); //topmost request
-
- dbg("processLine -------start");
-
- if(TCORE_RETURN_SUCCESS == tcore_pending_get_send_status(pPending, &result_status)
- && (result_status == FALSE))//request not sent but data comes - Unsolicited msg!
- {
- /* no command pending */
- dbg("no command pending. call onUnsolicited()");
- onUnsolicited(line, p, NULL, 0);
- } else if (isFinalResponseSuccess(line)) {
- dbg("final response -success. call handleFinalResponse()");
-
- if (sp_response == NULL)
- return;
-
- sp_response->success = 1;
- handleFinalResponse(hal, line);
- } else if (isFinalResponseError(line)) {
- dbg("final response -ERROR. call handleFinalResponse()");
-
- if (sp_response == NULL)
- return;
-
- sp_response->success = 0;
- handleFinalResponse(hal, line);
- } else switch (s_type) {
- case NO_RESULT:
- {
- dbg("[NO_RESULT]:call onUnsolicited()");
- onUnsolicited(line, p, NULL, 0);
- }
- break;
- case NUMERIC:
- {
- dbg("Process intermediate NUMERIC response");
-
- if (sp_response == NULL)
- return;
-
- if (sp_response->p_intermediates == NULL
- && isdigit(line[0])
- ) {
- dbg("[NUMERIC]:line[0] is digit. call addIntermediate()");
- addIntermediate(line);
- } else {
- /* either we already have an intermediate response or
- the line doesn't begin with a digit */
- dbg("[NUMERIC]:either we already have an intermediate response or the line doesn't begin with a digit. call onUnsolicited()");
- onUnsolicited(line,p,NULL, 0);
- }
- }
- break;
- case SINGLELINE:
- {
- dbg("Process intermediate SINGLELINE response");
-
- if (sp_response == NULL)
- return;
-
- if (sp_response->p_intermediates == NULL
- && strStartsWith (line, s_responsePrefix)) {
- dbg("[SINGLELINE]:line starts with s_responsePrefix. call addIntermediate()");
- addIntermediate(line);
- } else {
- /* we already have an intermediate response */
- dbg("[SINGLELINE]:we already have an intermediate response. call onUnsolicited()");
- onUnsolicited(line,p, NULL, 0);
- }
- }
- break;
- case MULTILINE:
- dbg("Process intermediate MULTILINE response");
-
- if (strStartsWith (line, s_responsePrefix)) {
- dbg("[MULTILINE]:line starts with s_responsePrefix. call addIntermediate()");
- addIntermediate(line);
- } else {
- dbg("[MULTILINE]:line don't starts with s_responsePrefix. call onUnsolicited()");
- onUnsolicited(line,p, NULL, 0);
- }
- break;
-
- default: /* this should never be reached */
- err("Unsupported AT command type %d\n", s_type);
- onUnsolicited(line,p, NULL, 0);
- break;
- }
-}
-
-static gboolean readline(TcoreHal *hal, unsigned int data_len, const void *data, TcorePlugin* p)
-{
- char *ret;
- char *p_read = NULL;
- char *p_eol = NULL;
- char *p_marker = NULL;
- int len, leftover_len;
-
- char* act_data;
- int act_len;
-
- act_data = (char*)data;
- act_len = data_len;
-
- dbg("recv string = %s, length : %d", (char*)act_data, act_len);
- /* this is a little odd. I use *s_ATBufferCur == 0 to
- * mean "buffer consumed completely". If it points to a character, than
- * the buffer continues until a \0
- */
-
- /*check sms pdu cumulating process - data hijacking*/
- if(spc.sms_pdu_mode == TRUE)
- { //continue sms pdu buffering
- dbg("resume pdu buffering. pdu size : %d, gathered size : %d",spc.sms_pdu_len,spc.cum_pdu_len);
- len = spc.sms_pdu_len - spc.cum_pdu_len; //length needed
-
- if(act_len > len){
- dbg("whole pdu received - data surplus");
- memcpy(spc.ppdu_marker, act_data,len);//data fully copied
- spc.cum_pdu_len = spc.cum_pdu_len + len;
-
- //change data & datalen
- act_data = act_data + len;
- act_len = act_len - len;
- dbg("recv string changed to = %s, length changed to : %d", (char*)act_data, act_len);
-
- onUnsolicited(spc.line1, p, spc.ppdu, spc.sms_pdu_len);
- stopSMSBuffering();
- dbg("incoming sms handled. back to normal mode & continue");
- }
- else if(act_len == len){
- dbg("exactly whole pdu received");
-
- memcpy(spc.ppdu_marker, act_data,len);//data fully copied
- spc.cum_pdu_len = spc.cum_pdu_len + len;
-
- onUnsolicited(spc.line1, p, spc.ppdu, spc.sms_pdu_len);
- stopSMSBuffering();
- dbg("all incoming data consumed. return");
- return TRUE;
- }
- else {
- dbg("data received but not sufficient");
- memcpy(spc.ppdu_marker, act_data,act_len);
- spc.ppdu_marker = spc.ppdu_marker +act_len;
- spc.cum_pdu_len = spc.cum_pdu_len + act_len;
- dbg("data buffered. wait for more data");
- return TRUE;
- }
- }
-
-
- if (*s_ATBufferCur == '\0')
- {
- /* empty buffer */
- s_ATBufferCur = s_ATBuffer;
- *s_ATBufferCur = '\0';
- p_read = s_ATBuffer;
- }
- else
- {
- /* *s_ATBufferCur != '\0' */
- /* there's data in the buffer from the last read */
-
- // skip over leading newlines
- while (*s_ATBufferCur == '\r' || *s_ATBufferCur == '\n')
- s_ATBufferCur++;
-
- p_eol = findNextEOL(s_ATBufferCur);
-
- if (p_eol == NULL)
- {
- /* a partial line. move it up and prepare to read more */
- unsigned int len;
- len = strlen(s_ATBufferCur);
-
- memmove(s_ATBuffer, s_ATBufferCur, len + 1);
- p_read = s_ATBuffer + len;
- s_ATBufferCur = s_ATBuffer;
- }
- /* Otherwise, (p_eol !- NULL) there is a complete line */
- else
- {
- err("this should not be happening - complete data pending??");
- }
-
- }
-
- if (0 > MAX_AT_RESPONSE - ((p_read - s_ATBuffer)+(int)act_len))
- {
- dbg("ERROR: Input line exceeded buffer\n");
- /* ditch buffer and start over again */
- s_ATBufferCur = s_ATBuffer;
- *s_ATBufferCur = '\0';
- p_read = s_ATBuffer;
- }
-
- //copy data into buffer
- memcpy(p_read, act_data, act_len);
-
- if (act_len <= 0)
- {
- /* read error encountered or EOF reached */
- if(act_len == 0) {
- err("atchannel: EOF reached");
- }
- else {
- err("invalid data coming");
- }
- return FALSE;
- }
- else
- {
- s_readCount += act_len;
- p_read[act_len] = '\0';
-
- p_marker = p_read + act_len; //pin the last position of data copy
- }
-
-
- do
- {
- // skip over leading newlines
- while (*s_ATBufferCur == '\r' || *s_ATBufferCur == '\n')
- s_ATBufferCur++;
-
- p_eol = findNextEOL(s_ATBufferCur);
-
- if(p_eol !=NULL) /*end of line found!*/
- {
- /* a full line in the buffer. Place a \0 over the \r and return */
- ret = s_ATBufferCur;
- *p_eol = '\0';
- s_ATBufferCur = p_eol + 1; /* this will always be <= p_read, */
- /* and there will be a \0 at *p_read */
-
- dbg("complete line found. process it/n");
- dbg("rsp line : %s/n",ret);
- if(1 == isSMSUnsolicited(ret))
- {
- dbg("start of incoming sms found!!! - next data is PDU");
- startSMSBuffering(ret);
- s_ATBufferCur++; //move starting point by 1 - it goes to the very starting point of PDU
- leftover_len = p_marker - s_ATBufferCur;
-
- dbg("count leftover : %d", leftover_len);
- if(leftover_len <0){
- dbg("pointer address error -serious!");
- return FALSE;
- }
- else if(leftover_len ==0){
- dbg("no pdu received - wait for incoming data");
- spc.cum_pdu_len =0;
- spc.ppdu_marker = spc.ppdu;
- }
- else if(leftover_len >= spc.sms_pdu_len){
- dbg("whole pdu already received!");
- memcpy(spc.ppdu, s_ATBufferCur, spc.sms_pdu_len);
- spc.cum_pdu_len = spc.sms_pdu_len;
- onUnsolicited(spc.line1, p, spc.ppdu, spc.sms_pdu_len);
- s_ATBufferCur = s_ATBufferCur+spc.sms_pdu_len;
- dbg("move buffercur to point the very end of pdu!");
- stopSMSBuffering();
- }
- else {
- dbg("staring part of pdu received!");
- memcpy(spc.ppdu, s_ATBufferCur,leftover_len);
- spc.ppdu_marker = spc.ppdu + leftover_len;
- spc.cum_pdu_len = leftover_len;
- s_ATBufferCur = s_ATBufferCur + leftover_len;
- }
-
- }
- else {
- processLine(hal, ret,p);
- }
- }
- else
- {
- dbg("complete responses all handled/n");
- }
- }while(p_eol != NULL);
-
- dbg("all the pending rsp's handled. wait for next incoming data/n");
- return TRUE;
-}
-
-static void on_hal_recv(TcoreHal *hal, unsigned int data_len, const void *data, void *user_data)
-{
- gboolean ret = FALSE;
- TcorePlugin *plugin = user_data;
-
- ret = readline(hal,data_len, data,plugin);
-}
-
-static enum tcore_hook_return on_hal_send(TcoreHal *hal, unsigned int data_len, void *data, void *user_data)
-{
- hook_hex_dump(TX, data_len, data);
- return TCORE_HOOK_RETURN_CONTINUE;
-}
-
-/* Initializer Table */
-struct object_initializer init_table = {
- .modem_init = s_modem_init,
- .sim_init = s_sim_init,
- .sat_init = NULL,
- .sap_init = NULL,
- .network_init = s_network_init,
- .ps_init = s_ps_init,
- .call_init = s_call_init,
- .ss_init = s_ss_init,
- .sms_init = s_sms_init,
- .phonebook_init = NULL,
- .gps_init = NULL,
-};
-
-/* Deinitializer Table */
-struct object_deinitializer deinit_table = {
- .modem_deinit = s_modem_exit,
- .sim_deinit = s_sim_exit,
- .sat_deinit = NULL,
- .sap_deinit = NULL,
- .network_deinit = s_network_exit,
- .ps_deinit = s_ps_exit,
- .call_deinit = s_call_exit,
- .ss_deinit = s_ss_exit,
- .sms_deinit = s_sms_exit,
- .phonebook_deinit = NULL,
- .gps_deinit = NULL,
-};
-
-static gboolean on_load()
-{
- dbg("i'm load!");
-
- return TRUE;
-}
-
-static gboolean on_init(TcorePlugin *p)
-{
- TcoreHal *hal;
- CoreObject *co_modem;
-
- dbg("INIT");
-
- /* Initialize Modules (Core Objects) */
- if (tcore_object_init_objects(p, &init_table)
- != TCORE_RETURN_SUCCESS) {
- err("Failed to initialize Core Objects");
- return FALSE;
- }
-
- co_modem = tcore_plugin_ref_core_object(p, CORE_OBJECT_TYPE_MODEM);
- hal = tcore_object_get_hal(co_modem);
-
- tcore_hal_add_send_hook(hal, on_hal_send, p);
- tcore_hal_add_recv_callback(hal, on_hal_recv, p);
-
- s_modem_send_poweron(p);
-
- dbg("Init - Successful");
-
- return TRUE;
-}
-
-static void on_unload(TcorePlugin *p)
-{
- dbg("UNLOAD");
-
- if (!p)
- return;
-
- /* Deinitialize Modules (Core Objects) */
- tcore_object_deinit_objects(p, &deinit_table);
-}
-
-struct tcore_plugin_define_desc plugin_define_desc =
-{
- .name = "ATMODEM",
- .priority = TCORE_PLUGIN_PRIORITY_MID,
- .version = 1,
- .load = on_load,
- .init = on_init,
- .unload = on_unload
-};
--- /dev/null
+/*
+ * tel-plugin-atmodem
+ *
+ * Copyright (c) 2013 Samsung Electronics Co. Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+
+#include <glib.h>
+
+#include <tcore.h>
+#include <plugin.h>
+#include <hal.h>
+#include <server.h>
+#include <queue.h>
+#include <core_object.h>
+#include <at.h>
+
+#include "atmodem_common.h"
+#include "atmodem_sim.h"
+#include "atmodem_ps.h"
+#include "atmodem_call.h"
+#include "atmodem_ss.h"
+#include "atmodem_sms.h"
+#include "atmodem_network.h"
+#include "atmodem_modem.h"
+
+/* Initializer Table */
+TcoreObjectInitializer atmodem_init_table = {
+ .modem_init = atmodem_modem_init,
+ .sim_init = atmodem_sim_init,
+ .sat_init = NULL,
+ .sap_init = NULL,
+ .network_init = atmodem_network_init,
+ .ps_init = atmodem_ps_init,
+ .call_init = atmodem_call_init,
+ .ss_init = atmodem_ss_init,
+ .sms_init = atmodem_sms_init,
+ .phonebook_init = NULL,
+ .gps_init = NULL,
+};
+
+/* Deinitializer Table */
+TcoreObjectDeinitializer atmodem_deinit_table = {
+ .modem_deinit = atmodem_modem_exit,
+ .sim_deinit = atmodem_sim_exit,
+ .sat_deinit = NULL,
+ .sap_deinit = NULL,
+ .network_deinit = atmodem_network_exit,
+ .ps_deinit = atmodem_ps_exit,
+ .call_deinit = atmodem_call_exit,
+ .ss_deinit = atmodem_ss_exit,
+ .sms_deinit = atmodem_sms_exit,
+ .phonebook_deinit = NULL,
+ .gps_deinit = NULL,
+};
+
+static gboolean on_load()
+{
+ dbg("Load!!!");
+
+ return TRUE;
+}
+
+static gboolean on_init(TcorePlugin *p)
+{
+ dbg("Init!!!");
+
+ tcore_check_return_value(p != NULL, FALSE);
+
+ /* Initialize Modules (Core Objects) */
+ if (tcore_object_init_objects(p, &atmodem_init_table)
+ != TEL_RETURN_SUCCESS) {
+ err("Failed to initialize Core Objects");
+ return FALSE;
+ }
+
+ /* Power ON modem */
+ (void)g_idle_add((GSourceFunc)atmodem_modem_power_on_modem, (gpointer)p);
+
+ dbg("Init - Successful");
+ return TRUE;
+}
+
+static void on_unload(TcorePlugin *p)
+{
+ dbg("Unload!!!");
+ tcore_check_return(p != NULL);
+
+ /* Deinitialize Modules (Core Objects) */
+ tcore_object_deinit_objects(p, &atmodem_deinit_table);
+}
+
+struct tcore_plugin_define_desc plugin_define_desc = {
+ .name = "atmodem",
+ .priority = TCORE_PLUGIN_PRIORITY_MID,
+ .version = 1,
+ .load = on_load,
+ .init = on_init,
+ .unload = on_unload
+};
+++ /dev/null
-/*
- * tel-plugin-atmodem
- *
- * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: Hayoon Ko <hayoon.ko@samsung.com>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <glib.h>
-
-#include <tcore.h>
-#include <hal.h>
-#include <core_object.h>
-#include <plugin.h>
-#include <queue.h>
-#include <server.h>
-#include <co_call.h>
-#include <user_request.h>
-
-#include "s_common.h"
-#include "s_call.h"
-
-#include "atchannel.h"
-#include "at_tok.h"
-
-
-extern struct ATResponse *sp_response;
-extern char *s_responsePrefix;
-extern enum ATCommandType s_type;
-
-struct CLCC_call_t {
- struct CLCC_call_info_t {
- int id;
- enum tcore_call_direction direction;
- enum tcore_call_status status;
- enum tcore_call_type type;
- int mpty;
- int num_len;
- int num_type;
- } info;
- char number[90];
-};
-
-
-static gboolean _call_request_message( CoreObject *o, UserRequest* ur, char* cmd_string,
- unsigned int cmd_length, void* on_resp, void* user_data);
-
-static void _call_status_idle( TcorePlugin *p, CallObject *co );
-static void _call_status_active( TcorePlugin *p, CallObject *co );
-static void _call_status_dialing( TcorePlugin *p, CallObject *co );
-static void _call_status_alert( TcorePlugin *p, CallObject *co );
-static void _call_status_incoming( TcorePlugin *p, CallObject *co );
-static void _call_status_waiting( TcorePlugin *p, CallObject *co );
-
-static void _call_branch_by_status( TcorePlugin *p, CallObject *co, unsigned int status );
-static enum tcore_call_type _call_type( int type );
-static enum tcore_call_status _call_status(unsigned int status);
-static gboolean _call_is_in_mpty(int mpty);
-
-static TReturn _call_list_get( CoreObject *o, CallObject *co );
-
-static void on_confirmation_call_message_send( TcorePending *p, gboolean result, void *user_data ); // from Kernel
-
-static void on_response_call_list_get(TcorePending *p, int data_len, const void *data, void *user_data);
-static gboolean on_notification_call_waiting( CoreObject *o, const void *data, void *user_data );
-static gboolean on_notification_call_incoming( CoreObject *o, const void *data, void *user_data );
-static gboolean on_notification_call_status( CoreObject *o, const void *data, void *user_data);
-
-
-static int _callFromCLCCLine(char *line, struct CLCC_call_t *p_call);
-
-
-static enum tcore_call_cli_mode _get_clir_status( char *num )
-{
- enum tcore_call_cli_mode clir = CALL_CLI_MODE_DEFAULT;
-
- if( !strncmp( num, "*31#", 4 ) )
- return TCORE_CALL_CLI_MODE_RESTRICT;
-
- if( !strncmp( num, "#31#", 4 ) )
- return TCORE_CALL_CLI_MODE_PRESENT;
-
- return clir;
-}
-
-
-static enum tcore_call_status _call_status(unsigned int status)
-{
- switch(status)
- {
- case 0:
- return TCORE_CALL_STATUS_ACTIVE;
- case 1:
- return TCORE_CALL_STATUS_HELD;
- case 2:
- return TCORE_CALL_STATUS_DIALING;
- case 3:
- return TCORE_CALL_STATUS_ALERT;
- case 4:
- return TCORE_CALL_STATUS_INCOMING;
- case 5:
- return TCORE_CALL_STATUS_WAITING;
- case 6:
- return TCORE_CALL_STATUS_DIALING; //connecting not exist. set to dialing
- case 7:
- return TCORE_CALL_STATUS_IDLE;
-
- default:
- return TCORE_CALL_STATUS_IDLE;
- break;
- }
-
- return TCORE_CALL_STATUS_IDLE;
-}
-
-static gboolean _call_is_in_mpty(int mpty)
-{
- switch(mpty){
- case 0:
- return FALSE;
- break;
-
- case 1:
- return TRUE;
-
- default:
- break;
- }
- return FALSE;
-}
-
-static enum tcore_call_type _call_type(int type )
-{
- switch (type) {
- case 0:
- return TCORE_CALL_TYPE_VOICE;
- case 1:
- return TCORE_CALL_TYPE_VIDEO;
- default:
- break;
- }
-
- return TCORE_CALL_TYPE_VOICE;
-}
-
-static gboolean _call_request_message( CoreObject *o,
- UserRequest *ur,
- char *cmd_string,
- unsigned int cmd_len,
- void* on_resp,
- void* user_data)
-{
- TcorePending *pending = NULL;
- TcoreHal *h = NULL;
-
- unsigned int info_len = 0;
- info_len = sizeof(struct ATReqMetaInfo);
-
- dbg("_call_request_message - cmd : %s, cmdlen :%d (including '\r')",cmd_string, cmd_len);
-
-
- pending = tcore_pending_new(o, ID_RESERVED_AT);
- tcore_pending_set_request_data(pending, cmd_len, cmd_string);
- tcore_pending_set_timeout(pending, 0);
- tcore_pending_set_priority(pending, TCORE_PENDING_PRIORITY_DEFAULT);
-
- if ( on_resp )
- tcore_pending_set_response_callback(pending, on_resp, user_data);
-
- tcore_pending_set_send_callback(pending, on_confirmation_call_message_send, NULL);
-
- if ( !ur ) {
- dbg("[ check ] ur is NULL, is this internal request??");
- } else {
- tcore_pending_link_user_request(pending, ur);
- }
-
- h = tcore_object_get_hal(o);
-
- tcore_hal_send_request(h, pending);
-
- return TRUE;
-}
-
-static void _call_status_idle( TcorePlugin *p, CallObject *co )
-{
- struct tnoti_call_status_idle data;
- CoreObject *o;
-
- o = tcore_plugin_ref_core_object(p, CORE_OBJECT_TYPE_CALL);
- dbg("call id [%d], call status [%d]", tcore_call_object_get_id(co), tcore_call_object_get_status(co));
-
- if ( tcore_call_object_get_status( co ) != TCORE_CALL_STATUS_IDLE ) {
- data.type = tcore_call_object_get_type( co );
- dbg("data.type : [%d]", data.type );
-
- data.id = tcore_call_object_get_id( co );
- dbg("data.id : [%d]", data.id );
-
- tcore_call_object_set_status( co, TCORE_CALL_STATUS_IDLE );
-
- tcore_server_send_notification( tcore_plugin_ref_server(p),
- o,
- TNOTI_CALL_STATUS_IDLE,
- sizeof(struct tnoti_call_status_idle),
- (void*)&data );
-
- tcore_call_object_free( o, co );
- } else {
- dbg("call object was freed");
- tcore_call_object_free(o, co);
- }
-}
-
-static void _call_status_dialing( TcorePlugin *p, CallObject *co )
-{
- CoreObject* o = 0;
-
- struct tnoti_call_status_dialing data;
-
- o = tcore_plugin_ref_core_object( p, CORE_OBJECT_TYPE_CALL);
-
- if ( tcore_call_object_get_status( co ) != TCORE_CALL_STATUS_DIALING ) {
-
- data.type = tcore_call_object_get_type( co );
- dbg("data.type : [%d]", data.type );
-
- data.id = tcore_call_object_get_id( co );
- dbg("data.id : [%d]", data.id );
-
- tcore_call_object_set_status( co, TCORE_CALL_STATUS_DIALING );
-
- tcore_server_send_notification( tcore_plugin_ref_server(p),
- tcore_plugin_ref_core_object(p, CORE_OBJECT_TYPE_CALL),
- TNOTI_CALL_STATUS_DIALING,
- sizeof(struct tnoti_call_status_dialing),
- (void*)&data );
-
- }
-
-#if 0
- _call_list_get( o, co );
-#endif
-}
-
-static void _call_status_alert( TcorePlugin *p, CallObject *co )
-{
- CoreObject* o = 0;
- struct tnoti_call_status_alert data;
-
- o = tcore_plugin_ref_core_object( p, CORE_OBJECT_TYPE_CALL);
-
- if ( tcore_call_object_get_status( co ) != TCORE_CALL_STATUS_ALERT ) {
-
- data.type = tcore_call_object_get_type( co );
- dbg("data.type : [%d]", data.type );
-
- data.id = tcore_call_object_get_id( co );
- dbg("data.id : [%d]", data.id );
-
- tcore_call_object_set_status( co, TCORE_CALL_STATUS_ALERT );
-
- tcore_server_send_notification( tcore_plugin_ref_server(p),
- tcore_plugin_ref_core_object(p, CORE_OBJECT_TYPE_CALL),
- TNOTI_CALL_STATUS_ALERT,
- sizeof(struct tnoti_call_status_alert),
- (void*)&data );
-
- }
-
-#if 0
- _call_list_get( o, co );
-#endif
-}
-
-static void _call_status_active( TcorePlugin *p, CallObject *co )
-{
- struct tnoti_call_status_active data;
-
- if ( tcore_call_object_get_status( co ) != TCORE_CALL_STATUS_ACTIVE ) {
-
- data.type = tcore_call_object_get_type( co );
- dbg("data.type : [%d]", data.type );
-
- data.id = tcore_call_object_get_id( co );
- dbg("data.id : [%d]", data.id );
-
- tcore_call_object_set_status( co, TCORE_CALL_STATUS_ACTIVE );
-
- tcore_server_send_notification( tcore_plugin_ref_server(p),
- tcore_plugin_ref_core_object(p, CORE_OBJECT_TYPE_CALL),
- TNOTI_CALL_STATUS_ACTIVE,
- sizeof(struct tnoti_call_status_active),
- (void*)&data );
-
- }
-}
-
-static void _call_status_held( TcorePlugin *p, CallObject *co )
-{
- struct tnoti_call_status_held data;
-
- if ( tcore_call_object_get_status( co ) != TCORE_CALL_STATUS_HELD ) {
-
- data.type = tcore_call_object_get_type( co );
- dbg("data.type : [%d]", data.type );
-
- data.id = tcore_call_object_get_id( co );
- dbg("data.id : [%d]", data.id );
-
- tcore_call_object_set_status( co, TCORE_CALL_STATUS_HELD );
-
- tcore_server_send_notification( tcore_plugin_ref_server(p),
- tcore_plugin_ref_core_object(p, CORE_OBJECT_TYPE_CALL),
- TNOTI_CALL_STATUS_HELD,
- sizeof(struct tnoti_call_status_held),
- (void*)&data );
-
- }
-}
-
-static void _call_status_incoming( TcorePlugin *p, CallObject *co )
-{
- struct tnoti_call_status_incoming data;
- CoreObject* o = 0;
- o = tcore_plugin_ref_core_object( p, CORE_OBJECT_TYPE_CALL);
-
- if ( tcore_call_object_get_status( co ) != TCORE_CALL_STATUS_INCOMING ) {
-
- tcore_call_object_set_status( co, TCORE_CALL_STATUS_INCOMING );
-
- data.type = tcore_call_object_get_type( co );
- dbg("data.type : [%d]", data.type );
-
- data.id = tcore_call_object_get_id( co );
- dbg("data.id : [%d]", data.id );
-
- data.cli.mode = tcore_call_object_get_cli_mode( co );
- dbg("data.cli.mode : [%d]", data.cli.mode );
-
- tcore_call_object_get_number( co, data.cli.number );
- dbg("data.cli.number : [%s]", data.cli.number );
-
- data.cna.mode = tcore_call_object_get_cna_mode( co );
- dbg("data.cna.mode : [%d]", data.cna.mode );
-
- tcore_call_object_get_name( co, data.cna.name );
- dbg("data.cna.name : [%s]", data.cna.name );
-
- data.forward = FALSE; // this is tmp code
- data.active_line = tcore_call_object_get_active_line( co );
- dbg("data.active_line : [%d]", data.active_line );
-
- tcore_server_send_notification( tcore_plugin_ref_server(p),
- tcore_plugin_ref_core_object(p, CORE_OBJECT_TYPE_CALL),
- TNOTI_CALL_STATUS_INCOMING,
- sizeof(struct tnoti_call_status_incoming),
- (void*)&data );
- }
-
-}
-
-static void _call_status_waiting( TcorePlugin *p, CallObject *co )
-{
- _call_status_incoming( p, co );
-}
-
-static void _call_branch_by_status( TcorePlugin *p, CallObject *co, unsigned int status )
-{
- switch ( status ) {
- case TCORE_CALL_STATUS_IDLE:
- _call_status_idle( p, co );
- break;
-
- case TCORE_CALL_STATUS_ACTIVE:
- _call_status_active( p, co );
- break;
-
- case TCORE_CALL_STATUS_HELD:
- _call_status_held( p, co );
- break;
-
- case TCORE_CALL_STATUS_DIALING:
- _call_status_dialing( p, co );
- break;
-
- case TCORE_CALL_STATUS_ALERT:
- _call_status_alert( p, co );
- break;
-
- case TCORE_CALL_STATUS_INCOMING:
- _call_status_incoming( p, co );
- break;
-
- case TCORE_CALL_STATUS_WAITING:
- _call_status_waiting( p, co );
- break;
- }
-}
-
-
-static TReturn _call_list_get( CoreObject *o, CallObject *co )
-{
- gboolean ret = FALSE;
- UserRequest* ur = NULL;
-
- char* cmd_str = NULL;
- struct ATReqMetaInfo metainfo;
- int info_len =0;
-
- if ( !o )
- return TCORE_RETURN_FAILURE;
-
- ur = tcore_user_request_new(NULL, NULL);
-
- memset(&metainfo, 0, sizeof(struct ATReqMetaInfo));
-
- metainfo.type = MULTILINE;
- memcpy(metainfo.responsePrefix,"+CLCC:",strlen("+CLCC:"));
- info_len = sizeof(struct ATReqMetaInfo);
- tcore_user_request_set_metainfo(ur, info_len, &metainfo);
-
- cmd_str = g_strdup("AT+CLCC\r");
-
- ret = _call_request_message ( o, ur, cmd_str, strlen(cmd_str), on_response_call_list_get, NULL);
-
- if ( !ret )
- return TCORE_RETURN_FAILURE;
-
- return TCORE_RETURN_SUCCESS;
-}
-
-
-
-
-// CONFIRMATION
-
-static void on_confirmation_call_message_send( TcorePending *p, gboolean result, void *user_data )
-{
- UserRequest* ur = NULL;
- struct ATReqMetaInfo* metainfo = NULL;
- unsigned int info_len =0;
- dbg("on_confirmation_call_message_send - msg out from queue. alloc ATRsp buffer & write rspPrefix if needed\n");
-
- ReleaseResponse(); //release leftover
-//alloc new sp_response
-
- sp_response = at_response_new();
-
- ur = tcore_pending_ref_user_request(p);
- metainfo = (struct ATReqMetaInfo*)tcore_user_request_ref_metainfo(ur,&info_len);
-
- if((metainfo->type == SINGLELINE)||
- (metainfo->type == MULTILINE))
- {
- //cp rsp prefix
- s_responsePrefix = strdup(metainfo->responsePrefix);
- dbg("duplicating responsePrefix : %s\n", s_responsePrefix);
- }
- else
- {
- s_responsePrefix = NULL;
- }
-
-//set atcmd type into s_type
- s_type = metainfo->type;
-
- if (result == FALSE) {
- /* Fail */
- dbg("SEND FAIL");
- }
- else {
- dbg("SEND OK");
- }
-}
-
-static void on_confirmation_call_outgoing( TcorePending *p, int data_len, const void *data, void *user_data )
-{
- CoreObject *o = 0;
- UserRequest *ur = 0;
-
- struct tresp_call_dial resp;
-
- o = tcore_pending_ref_core_object(p);
- ur = tcore_pending_ref_user_request(p);
-
- if(sp_response->success >0)
- resp.err = CALL_ERROR_NONE;
- else
- resp.err = CALL_ERROR_SERVICE_UNAVAIL;
-
- ReleaseResponse();
-
- if (ur) {
- tcore_user_request_send_response(ur, TRESP_CALL_DIAL, sizeof(struct tresp_call_dial), &resp);
-
- } else {
- dbg("[ error ] ur is NULL");
- return ;
- }
-}
-
-static void on_confirmation_call_accept( TcorePending *p, int data_len, const void *data, void *user_data )
-{
- CoreObject *o = 0;
- UserRequest *ur = 0;
-
- struct tresp_call_answer resp;
-
- o = tcore_pending_ref_core_object(p);
- ur = tcore_pending_ref_user_request(p);
-
- if(sp_response->success >0)
- resp.err = CALL_ERROR_NONE;
- else
- resp.err = CALL_ERROR_SERVICE_UNAVAIL;
-
- ReleaseResponse();
-
- resp.id = tcore_call_object_get_id( (CallObject*)user_data );
-
- if (ur) {
- tcore_user_request_send_response(ur, TRESP_CALL_ANSWER, sizeof(struct tresp_call_answer), &resp);
-
- } else {
- dbg("[ error ] ur is NULL");
- return ;
- }
-}
-
-
-static void on_confirmation_call_reject( TcorePending *p, int data_len, const void *data, void *user_data )
-{
- CoreObject *o = 0;
- UserRequest *ur = 0;
-
- struct tresp_call_answer resp;
-
- o = tcore_pending_ref_core_object(p);
- ur = tcore_pending_ref_user_request(p);
-
- if(sp_response->success >0)
- resp.err = CALL_ERROR_NONE;
- else
- resp.err = CALL_ERROR_SERVICE_UNAVAIL;
-
- ReleaseResponse();
-
- resp.id = tcore_call_object_get_id( (CallObject*)user_data );
-
- if (ur) {
- tcore_user_request_send_response(ur, TRESP_CALL_ANSWER, sizeof(struct tresp_call_answer), &resp);
-
- } else {
- dbg("[ error ] ur is NULL");
- return ;
- }
-}
-
-static void on_confirmation_call_replace( TcorePending *p, int data_len, const void *data, void *user_data )
-{
- CoreObject *o = 0;
- UserRequest *ur = 0;
-
- struct tresp_call_answer resp;
-
- o = tcore_pending_ref_core_object(p);
- ur = tcore_pending_ref_user_request(p);
-
- resp.id = tcore_call_object_get_id( (CallObject*)user_data );
-
- if(sp_response->success >0)
- resp.err = CALL_ERROR_NONE;
- else
- resp.err = CALL_ERROR_SERVICE_UNAVAIL;
-
- ReleaseResponse();
-
-
- if (ur) {
- tcore_user_request_send_response(ur, TRESP_CALL_ANSWER, sizeof(struct tresp_call_answer), &resp);
-
- } else {
- dbg("[ error ] ur is NULL");
- return ;
- }
-}
-
-static void on_confirmation_call_hold_and_accept( TcorePending *p, int data_len, const void *data, void *user_data )
-{
- CoreObject* o = 0;
- UserRequest* ur = 0;
-
- struct tresp_call_answer resp;
-
- dbg("ok, function entrance");
-
- o = tcore_pending_ref_core_object(p);
- ur = tcore_pending_ref_user_request(p);
-
- resp.id = tcore_call_object_get_id( (CallObject*)user_data );
-
- if(sp_response->success >0)
- resp.err = CALL_ERROR_NONE;
- else
- resp.err = CALL_ERROR_SERVICE_UNAVAIL;
-
- ReleaseResponse();
-
-
- if ( ur ) {
- tcore_user_request_send_response(ur, TRESP_CALL_ANSWER, sizeof(struct tresp_call_answer), &resp);
-
- } else {
- dbg("[ error ] ur is NULL");
- return ;
- }
-
- if ( !resp.err ) {
-
- GSList *l = 0;
- CallObject *co = 0;
- dbg("set hold with already active calls and accept incoming call");
-
- l = tcore_call_object_find_by_status( o, TCORE_CALL_STATUS_ACTIVE );
- if ( !l ) {
- dbg("[ error ] can't find active call");
- return ;
- }
- while (l) {
- co = (CallObject*)l->data;
- if ( !co ) {
- dbg("[ error ] can't get active call object");
- return ;
- }
- tcore_call_object_set_status( co, TCORE_CALL_STATUS_HELD );
- l = g_slist_next(l);
- }
- g_slist_free(l);
- }
-}
-
-static void on_confirmation_call_release_all( TcorePending *p, int data_len, const void *data, void *user_data )
-{
- CoreObject *o = 0;
- UserRequest *ur = 0;
-
- struct tresp_call_end resp;
-
- o = tcore_pending_ref_core_object(p);
- ur = tcore_pending_ref_user_request(p);
-
-
- resp.type = CALL_END_TYPE_ALL;
- resp.id = tcore_call_object_get_id( (CallObject*)user_data );
-
- if(sp_response->success >0)
- resp.err = CALL_ERROR_NONE;
- else
- resp.err = CALL_ERROR_SERVICE_UNAVAIL;
-
- ReleaseResponse();
-
- if (ur) {
- tcore_user_request_send_response(ur, TRESP_CALL_END, sizeof(struct tresp_call_end), &resp);
-
- } else {
- dbg("[ error ] ur is NULL");
- return ;
- }
-}
-
-
-
-static void on_confirmation_call_release_specific( TcorePending *p, int data_len, const void *data, void *user_data )
-{
- CoreObject *o = 0;
- UserRequest *ur = 0;
-
- struct tresp_call_end resp;
-
- o = tcore_pending_ref_core_object(p);
- ur = tcore_pending_ref_user_request(p);
-
- resp.type = CALL_END_TYPE_DEFAULT;
- resp.id = tcore_call_object_get_id( (CallObject*)user_data );
-
- if(sp_response->success >0)
- resp.err = CALL_ERROR_NONE;
- else
- resp.err = CALL_ERROR_SERVICE_UNAVAIL;
-
- ReleaseResponse();
-
- if (ur) {
- tcore_user_request_send_response(ur, TRESP_CALL_END, sizeof(struct tresp_call_end), &resp);
-
- } else {
- dbg("[ error ] ur is NULL");
- return ;
- }
-}
-
-static void on_confirmation_call_release_all_active( TcorePending *p, int data_len, const void *data, void *user_data )
-{
- CoreObject *o = 0;
- UserRequest *ur = 0;
-
- struct tresp_call_end resp;
-
- o = tcore_pending_ref_core_object(p);
- ur = tcore_pending_ref_user_request(p);
-
- resp.type = CALL_END_TYPE_ACTIVE_ALL;
- resp.id = tcore_call_object_get_id( (CallObject*)user_data );
-
- if(sp_response->success >0)
- resp.err = CALL_ERROR_NONE;
- else
- resp.err = CALL_ERROR_SERVICE_UNAVAIL;
-
- ReleaseResponse();
-
- if (ur) {
- tcore_user_request_send_response(ur, TRESP_CALL_END, sizeof(struct tresp_call_end), &resp);
-
- } else {
- dbg("[ error ] ur is NULL");
- return ;
- }
-}
-
-static void on_confirmation_call_release_all_held( TcorePending *p, int data_len, const void *data, void *user_data )
-{
- CoreObject *o = 0;
- UserRequest *ur = 0;
-
- struct tresp_call_end resp;
-
- o = tcore_pending_ref_core_object(p);
- ur = tcore_pending_ref_user_request(p);
-
- resp.type = CALL_END_TYPE_HOLD_ALL;
- resp.id = tcore_call_object_get_id( (CallObject*)user_data );
-
- if(sp_response->success >0)
- resp.err = CALL_ERROR_NONE;
- else
- resp.err = CALL_ERROR_SERVICE_UNAVAIL;
-
- ReleaseResponse();
-
- if (ur) {
- tcore_user_request_send_response(ur, TRESP_CALL_END, sizeof(struct tresp_call_end), &resp);
-
- } else {
- dbg("[ error ] ur is NULL");
- return ;
- }
-}
-
-static void on_confirmation_call_hold( TcorePending *p, int data_len, const void *data, void *user_data )
-{
- CoreObject* o = 0;
- UserRequest* ur = 0;
-
- struct tresp_call_hold resp;
-
- dbg("ok, function entrance");
-
- o = tcore_pending_ref_core_object(p);
- ur = tcore_pending_ref_user_request(p);
-
- resp.id = tcore_call_object_get_id( (CallObject*)user_data );
-
- if(sp_response->success >0)
- resp.err = CALL_ERROR_NONE;
- else
- resp.err = CALL_ERROR_SERVICE_UNAVAIL;
-
- ReleaseResponse();
-
- if ( ur ) {
- tcore_user_request_send_response(ur, TRESP_CALL_HOLD, sizeof(struct tresp_call_hold), &resp);
-
- } else {
- dbg("[ error ] ur is NULL");
- return ;
- }
-
- if ( !resp.err ) {
-
- GSList *active = 0;
- CallObject *co = 0;
-
- dbg("set hold status");
- active = tcore_call_object_find_by_status( o, TCORE_CALL_STATUS_ACTIVE );
- if ( !active ) {
- dbg("[ error ] can't find active call");
- return ;
- }
-
- while (active) {
- co = (CallObject*)active->data;
- if ( !co ) {
- dbg("[ error ] can't get active call object");
- return ;
- }
- tcore_call_object_set_status( co, TCORE_CALL_STATUS_HELD );
- active = g_slist_next(active);
- }
- }
-
-}
-
-static void on_confirmation_call_active( TcorePending *p, int data_len, const void *data, void *user_data )
-{
- CoreObject *o = 0;
- UserRequest *ur = 0;
-
- struct tresp_call_active resp;
-
- o = tcore_pending_ref_core_object(p);
- ur = tcore_pending_ref_user_request(p);
-
- resp.id = tcore_call_object_get_id( (CallObject*)user_data );
-
- if(sp_response->success >0)
- resp.err = CALL_ERROR_NONE;
- else
- resp.err = CALL_ERROR_SERVICE_UNAVAIL;
-
- ReleaseResponse();
-
- if (ur) {
- tcore_user_request_send_response(ur, TRESP_CALL_ACTIVE, sizeof(struct tresp_call_active), &resp);
-
- } else {
- dbg("[ error ] ur is NULL");
- return ;
- }
- if ( !resp.err ) {
-
- GSList *active = 0;
- CallObject *co = 0;
- dbg("set active status");
- active = tcore_call_object_find_by_status( o, TCORE_CALL_STATUS_HELD);
- if ( !active ) {
- dbg("[ error ] can't find active call");
- return ;
- }
- while (active) {
- co = (CallObject*)active->data;
- if ( !co ) {
- dbg("[ error ] can't get active call object");
- return ;
- }
- tcore_call_object_set_status( co, TCORE_CALL_STATUS_ACTIVE );
- active = g_slist_next(active);
- }
- }
-}
-
-static void on_confirmation_call_swap( TcorePending *p, int data_len, const void *data, void *user_data )
-{
- CoreObject* o = 0;
- UserRequest* ur = 0;
-
- struct tresp_call_swap resp;
-
- dbg("ok, function entrance");
-
- o = tcore_pending_ref_core_object(p);
- ur = tcore_pending_ref_user_request(p);
-
- resp.id = tcore_call_object_get_id( (CallObject*)user_data );
-
- if(sp_response->success >0)
- resp.err = CALL_ERROR_NONE;
- else
- resp.err = CALL_ERROR_SERVICE_UNAVAIL;
-
- ReleaseResponse();
-
- if ( ur ) {
- tcore_user_request_send_response(ur, TRESP_CALL_SWAP, sizeof(struct tresp_call_swap), &resp);
-
- } else {
- dbg("[ error ] ur is NULL");
- return ;
- }
-
- if ( !resp.err ) {
-
- GSList *active = 0, *held = 0;
- CallObject *co = 0;
-
- held = tcore_call_object_find_by_status( o, TCORE_CALL_STATUS_HELD );
- if ( !held ) {
- dbg("[ error ] can't find held call");
- return ;
- }
-
- active = tcore_call_object_find_by_status( o, TCORE_CALL_STATUS_ACTIVE );
- if ( !active ) {
- dbg("[ error ] can't find active call");
- return ;
- }
-
- while (held){
- co = (CallObject*)held->data;
- if ( !co ) {
- dbg("[ error ] can't get held call object");
- return ;
- }
- resp.id = tcore_call_object_get_id( co );
- tcore_call_object_set_status( co, TCORE_CALL_STATUS_ACTIVE );
- tcore_user_request_send_response(ur, TRESP_CALL_ACTIVE, sizeof(struct tresp_call_active), &resp);
- held = g_slist_next(held);
- }
- g_slist_free(held);
-
- while (active){
- co = (CallObject*)active->data;
- if ( !co ) {
- dbg("[ error ] can't get active call object");
- return ;
- }
- resp.id = tcore_call_object_get_id( co );
- tcore_call_object_set_status( co, TCORE_CALL_STATUS_HELD );
- tcore_user_request_send_response(ur, TRESP_CALL_HOLD, sizeof(struct tresp_call_hold), &resp);
- active = g_slist_next(active);
- }
- g_slist_free(active);
- }
-}
-
-static void on_confirmation_call_join( TcorePending *p, int data_len, const void *data, void *user_data )
-{
- CoreObject *o = 0;
- UserRequest *ur = 0;
-
- struct tresp_call_join resp;
-
- o = tcore_pending_ref_core_object(p);
- ur = tcore_pending_ref_user_request(p);
-
- resp.id = tcore_call_object_get_id( (CallObject*)user_data );
-
- if(sp_response->success >0)
- resp.err = CALL_ERROR_NONE;
- else
- resp.err = CALL_ERROR_SERVICE_UNAVAIL;
-
- ReleaseResponse();
-
- if (ur) {
- tcore_user_request_send_response(ur, TRESP_CALL_JOIN, sizeof(struct tresp_call_join), &resp);
-
- } else {
- dbg("[ error ] ur is NULL");
- return ;
- }
-}
-
-static void on_confirmation_call_split( TcorePending *p, int data_len, const void *data, void *user_data )
-{
- CoreObject* o = 0;
- UserRequest* ur = 0;
-
-
- struct tresp_call_split resp;
-
- dbg("ok, function entrance");
-
- o = tcore_pending_ref_core_object(p);
- ur = tcore_pending_ref_user_request(p);
-
- resp.id = tcore_call_object_get_id( (CallObject*)user_data );
-
- if(sp_response->success >0)
- resp.err = CALL_ERROR_NONE;
- else
- resp.err = CALL_ERROR_SERVICE_UNAVAIL;
-
- ReleaseResponse();
-
- if ( ur ) {
- tcore_user_request_send_response(ur, TRESP_CALL_SPLIT, sizeof(struct tresp_call_split), &resp);
-
- } else {
- dbg("[ error ] ur is NULL");
- return ;
- }
-
- if ( !resp.err ) {
-
- GSList *active = 0;
- CallObject *co = 0;
-
- active = tcore_call_object_find_by_status( o, TCORE_CALL_STATUS_ACTIVE );
- if ( !active ) {
- dbg("[ error ] can't find active call");
- return ;
- }
- while (active){
- co = (CallObject*)active->data;
- if ( !co ) {
- dbg("[ error ] can't get active call object");
- return ;
- }
- tcore_call_object_set_status( co, TCORE_CALL_STATUS_HELD );
- active = g_slist_next(active);
- }
- g_slist_free(active);
- tcore_call_object_set_status( (CallObject*)user_data, TCORE_CALL_STATUS_ACTIVE );
- }
-}
-
-static void on_confirmation_call_deflect( TcorePending *p, int data_len, const void *data, void *user_data )
-{
- CoreObject *o = 0;
- UserRequest *ur = 0;
-
- struct tresp_call_deflect resp;
-
- o = tcore_pending_ref_core_object(p);
- ur = tcore_pending_ref_user_request(p);
-
- resp.id = tcore_call_object_get_id( (CallObject*)user_data );
-
- if(sp_response->success >0)
- resp.err = CALL_ERROR_NONE;
- else
- resp.err = CALL_ERROR_SERVICE_UNAVAIL;
-
- ReleaseResponse();
-
- if (ur) {
- tcore_user_request_send_response(ur, TRESP_CALL_DEFLECT, sizeof(struct tresp_call_deflect), &resp);
-
- } else {
- dbg("[ error ] ur is NULL");
- return ;
- }
-}
-
-static void on_confirmation_call_transfer( TcorePending *p, int data_len, const void *data, void *user_data )
-{
- CoreObject *o = 0;
- UserRequest *ur = 0;
-
- struct tresp_call_transfer resp;
-
- o = tcore_pending_ref_core_object(p);
- ur = tcore_pending_ref_user_request(p);
-
- resp.id = tcore_call_object_get_id( (CallObject*)user_data );
-
- if(sp_response->success >0)
- resp.err = CALL_ERROR_NONE;
- else
- resp.err = CALL_ERROR_SERVICE_UNAVAIL;
-
- ReleaseResponse();
-
- if (ur) {
- tcore_user_request_send_response(ur, TRESP_CALL_TRANSFER, sizeof(struct tresp_call_transfer), &resp);
-
- } else {
- dbg("[ error ] ur is NULL");
- return ;
- }
-}
-
-// RESPONSE
-static void on_confirmation_call_endall( TcorePending *p, int data_len, const void *data, void *user_data )
-{
- CoreObject* o = 0;
- UserRequest* ur = 0;
-
- dbg("on_confirmation_call_endall - 1st result. wait for final result");
-
-
- o = tcore_pending_ref_core_object(p);
- ur = tcore_pending_ref_user_request(p);
-
-//skip response handling - actual result will be handled in on_confirmation_call_request
- ReleaseResponse();
-}
-
-// RESPONSE
-
-static void on_response_call_list_get(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- TcorePlugin* plugin = 0;
- CoreObject* o = 0;
- CallObject* co = 0;
- struct ATLine *p_cur;
-
- char* cmd= 0;
- struct CLCC_call_t* call_list = 0;
-
- int i = 0, countCalls =0, countValidCalls =0, err =0;
-
-
- plugin = tcore_pending_ref_plugin( p );
- o = tcore_pending_ref_core_object( p );
-
- cmd = (char*)data;
-
-
- if(sp_response->success > 0)
- {
-
- /* count the calls */
- for (countCalls = 0, p_cur = sp_response->p_intermediates
- ; p_cur != NULL
- ; p_cur = p_cur->p_next
- ) {
- countCalls++;
- }
- dbg("total calls : %d",countCalls);
-
- if(countCalls ==0)
- return;
-
- call_list = g_new0( struct CLCC_call_t, countCalls);
-
-
- for (countValidCalls = 0, p_cur = sp_response->p_intermediates
- ; p_cur != NULL
- ; p_cur = p_cur->p_next)
- {
-
- err = _callFromCLCCLine( p_cur->line, &call_list[countValidCalls] );
-
- if ( countCalls > countValidCalls )
- countValidCalls++;
-
- if (err != 0) {
- continue;
- }
-
- co = tcore_call_object_find_by_id( o, call_list[i].info.id );
- if ( !co ) {
- co = tcore_call_object_new( o, call_list[i].info.id );
- if ( !co ) {
- dbg("error : tcore_call_object_new [ id : %d ]", call_list[i].info.id);
- continue ;
- }
- }
-
- tcore_call_object_set_type( co, _call_type( call_list[i].info.type ) );
- tcore_call_object_set_direction( co, call_list[i].info.direction );
- tcore_call_object_set_multiparty_state( co, _call_is_in_mpty(call_list[i].info.mpty) );
- tcore_call_object_set_cli_info( co, CALL_CLI_MODE_DEFAULT, call_list[i].number );
-
- _call_branch_by_status( plugin, co, call_list[i].info.status );
-
- i++;
-
- if ( i == countCalls )
- break;
- }
- }
-
- ReleaseResponse();
-}
-
-static int _callFromCLCCLine(char *line, struct CLCC_call_t*p_call)
-{
- //+CLCC: 1,0,2,0,0,\"+18005551212\",145
- // index,isMT,state,mode,isMpty(,number,TOA)?
-
- int err;
- int state;
- int mode;
- int isMT;
- char* num;
-
- err = at_tok_start(&line);
- if (err < 0) goto error;
-
- //id
- err = at_tok_nextint(&line, &(p_call->info.id));
- if (err < 0) goto error;
- dbg("id : [%d]\n", p_call->info.id );
- //MO/MTcall
- err = at_tok_nextint(&line, &isMT);
- if (err < 0) goto error;
-
- if(isMT ==0)
- p_call->info.direction = TCORE_CALL_DIRECTION_OUTGOING;
- else
- p_call->info.direction = TCORE_CALL_DIRECTION_INCOMING;
-
- dbg("direction : [ %d ]\n", p_call->info.direction);
-
- //state
- err = at_tok_nextint(&line, &state);
- if (err < 0) goto error;
-
- switch(state){
- case 0: //active
- p_call->info.status = TCORE_CALL_STATUS_ACTIVE;
- break;
- case 1:
- p_call->info.status = TCORE_CALL_STATUS_HELD;
- break;
- case 2:
- p_call->info.status = TCORE_CALL_STATUS_DIALING;
- break;
- case 3:
- p_call->info.status = TCORE_CALL_STATUS_ALERT;
- break;
- case 4:
- p_call->info.status = TCORE_CALL_STATUS_INCOMING;
- break;
- case 5:
- p_call->info.status = TCORE_CALL_STATUS_WAITING;
- break;
- }
- dbg("status : [%d]\n", p_call->info.status );
-
- //mode
- err = at_tok_nextint(&line, &mode);
- if (err < 0) goto error;
-
- switch(mode)
- {
- case 0:
- p_call->info.type = TCORE_CALL_TYPE_VOICE;
- break;
-
- case 1:
- p_call->info.type = TCORE_CALL_TYPE_VIDEO;
- break;
-
- default: // only Voice/VT call is supported in CS. treat other unknown calls as error
- dbg("invalid type : [%d]\n", mode );
- goto error;
- break;
- }
- dbg("type : [%d]\n", p_call->info.type );
-
-
- err = at_tok_nextint(&line, &(p_call->info.mpty));
- if (err < 0) goto error;
- dbg("mpty : [%d]\n", p_call->info.mpty );
-
- if (at_tok_hasmore(&line)) {
- err = at_tok_nextstr(&line, &num);
-
- /* tolerate null here */
- if (err < 0) return 0;
-
- memcpy(p_call->number, num, strlen(num));
- dbg("number : [ %s ]\n", p_call->number );
-
- p_call->info.num_len = strlen(num);
- dbg("num_len : [0x%x]\n", p_call->info.num_len );
-
- err = at_tok_nextint(&line, &(p_call->info.num_type));
- if (err < 0) goto error;
- dbg("num_type : [0x%x]\n", p_call->info.num_type );
-
- }
-
- return 0;
-
-error:
- err("invalid CLCC line\n");
- return -1;
-}
-
-// NOTIFICATION
-
-static gboolean on_notification_call_waiting( CoreObject *o, const void *data, void *user_data )
-{
- TcorePlugin* plugin = NULL;
- char* cmd = NULL, *num = NULL;
- CallObject *co, *dupco = 0;
- int id, status, err, type, mpty,direction;
- GSList* pList = NULL;
-#define LINE_DEFAULT 0
-
- dbg("call waiting noti : %s", cmd);
- plugin = tcore_object_ref_plugin(o);
-
- cmd = (char*)data;
-
- at_tok_start(&cmd);
-
- err = at_tok_nextint(&cmd,&id);
- err = at_tok_nextint(&cmd,&direction);
- err = at_tok_nextint(&cmd,&status);
- err = at_tok_nextint(&cmd,&type);
- err = at_tok_nextint(&cmd,&mpty);
-
- if(at_tok_hasmore(&cmd)){
- err = at_tok_nextstr(&cmd,&num);
- dbg("id: %d, direction : %d, status : %d, type :%d, mpty : %d, num : %s", id,direction,status, type, mpty, num);
- }
- else {
- dbg("id: %d, direction : %d, status : %d, type :%d, mpty : %d, num : NULL", id,direction,status, type, mpty);
- }
-// check call with incoming status already exist
- pList = tcore_call_object_find_by_status(o, TCORE_CALL_STATUS_WAITING);
- if(pList != NULL){
- dbg("waiting call already exist. skip");
- return TRUE;
- }
-
- pList = tcore_call_object_find_by_status(o, TCORE_CALL_STATUS_INCOMING);
- if(pList != NULL){
- dbg("incoming call already exist. skip");
- return TRUE;
- }
-
- dupco = tcore_call_object_find_by_id(o, id);
- if(dupco!= NULL){
- dbg("co with same id already exist. skip");
- return TRUE;
- }
-
-// make new co, add to list
- co = tcore_call_object_new( o, id);
- if ( !co ) {
- dbg("[ error ] co is NULL");
- return TRUE;
- }
-
- tcore_call_object_set_type(co, _call_type(type));
- tcore_call_object_set_multiparty_state(co,_call_is_in_mpty(mpty));
- tcore_call_object_set_direction(co, TCORE_CALL_DIRECTION_INCOMING);
- tcore_call_object_set_cli_info(co, TCORE_CALL_CLI_MODE_DEFAULT, num);
- tcore_call_object_set_active_line(co, LINE_DEFAULT);
-
- _call_status_incoming(plugin, co);
-
- return TRUE;
-}
-
-static gboolean on_notification_call_incoming( CoreObject *o, const void *data, void *user_data )
-{
- TcorePlugin* plugin = NULL;
- char* cmd = NULL, *num = NULL;
- CallObject *co, *dupco = 0;
- int id, status, err, type, mpty,direction;
- GSList* pList = NULL;
-#define LINE_DEFAULT 0
-
- dbg("call incoming noti : %s", cmd);
- plugin = tcore_object_ref_plugin(o);
-
- cmd = (char*)data;
-
- at_tok_start(&cmd);
-
- err = at_tok_nextint(&cmd,&id);
- err = at_tok_nextint(&cmd,&direction);
- err = at_tok_nextint(&cmd,&status);
- err = at_tok_nextint(&cmd,&type);
- err = at_tok_nextint(&cmd,&mpty);
-
- if(at_tok_hasmore(&cmd)) {
- err = at_tok_nextstr(&cmd,&num);
- dbg("id: %d, direction : %d, status : %d, type :%d, mpty : %d, num : %s", id,direction,status, type, mpty, num);
- }
- else {
- dbg("id: %d, direction : %d, status : %d, type :%d, mpty : %d, num : NULL", id,direction,status, type, mpty);
- }
-// check call with incoming status already exist
- pList = tcore_call_object_find_by_status(o, TCORE_CALL_STATUS_INCOMING);
- if(pList != NULL){
- dbg("incoming call already exist. skip");
- return TRUE;
- }
-
- dupco = tcore_call_object_find_by_id(o, id);
- if(dupco!= NULL){
- dbg("co with same id already exist. skip");
- return TRUE;
- }
-
-// make new co, add to list
- co = tcore_call_object_new( o, id);
- if ( !co ) {
- dbg("[ error ] co is NULL");
- return TRUE;
- }
-
- tcore_call_object_set_type(co, _call_type(type));
- tcore_call_object_set_multiparty_state(co,_call_is_in_mpty(mpty));
- tcore_call_object_set_direction(co, TCORE_CALL_DIRECTION_INCOMING);
- tcore_call_object_set_cli_info(co, TCORE_CALL_CLI_MODE_DEFAULT, num);
- tcore_call_object_set_active_line(co, LINE_DEFAULT);
-
- _call_status_incoming(plugin, co);
-
- return TRUE;
-}
-
-static gboolean on_notification_call_status( CoreObject *o, const void *data, void *user_data)
-{
- char* cmd = NULL, *num = NULL;
- TcorePlugin* p = 0;
- CallObject* co = 0;
- int id, status, type, mpty,direction;
- int err;
-
- enum tcore_call_status co_status;
-
- p = tcore_object_ref_plugin( o );
- cmd = (char*)data;
-
- at_tok_start(&cmd);
-
- err = at_tok_nextint(&cmd,&id);
- err = at_tok_nextint(&cmd,&direction);
- err = at_tok_nextint(&cmd,&status);
- err = at_tok_nextint(&cmd,&type);
- err = at_tok_nextint(&cmd,&mpty);
-
- if (at_tok_hasmore(&cmd)) {
- err = at_tok_nextstr(&cmd,&num);
- dbg("id: %d, direction : %d, status : %d, type :%d, mpty : %d, num : %s", id,direction,status, type, mpty, num);
- }
- else {
- dbg("id: %d, direction : %d, status : %d, type :%d, mpty : %d, num : NULL", id,direction,status, type, mpty);
- }
-
- co_status = _call_status(status);
-
- switch (co_status) {
- case CALL_STATUS_ACTIVE:{
-
- dbg("call(%d) status : [ ACTIVE ]", id);
- co = tcore_call_object_find_by_id(o,id);
- if ( !co ) {
- dbg("co is NULL");
- return TRUE;
- }
- _call_status_active( p, co );
-
- } break;
- case CALL_STATUS_HELD:
- break;
- case CALL_STATUS_DIALING:
- {
- dbg("call(%d) status : [ dialing ]", id);
- co = tcore_call_object_find_by_id(o,id);
- if ( !co ) {
- co = tcore_call_object_new( o, id );
- if ( !co ) {
- dbg("error : tcore_call_object_new [ id : %d ]", id);
- return TRUE;
- }
- }
-
- tcore_call_object_set_type( co, _call_type(type) );
- tcore_call_object_set_direction( co, TCORE_CALL_DIRECTION_OUTGOING );
-
- _call_status_dialing( p, co );
- }
- break;
- case CALL_STATUS_ALERT:
- {
-
- dbg("call(%d) status : [ alert ]", id);
- co = tcore_call_object_find_by_id(o, id);
- if ( !co ) {
- dbg("co is NULL");
- return TRUE;
- }
-
- _call_list_get( o, co );
-
- } break;
- case CALL_STATUS_INCOMING:
- case CALL_STATUS_WAITING:
- break;
- case CALL_STATUS_IDLE: {
-
- dbg("call(%d) status : [ release ]", id);
-
- co = tcore_call_object_find_by_id( o, id );
- if ( !co )
- dbg("co is NULL");
-
- p = tcore_object_ref_plugin( o );
- if ( !p )
- dbg("plugin is NULL");
-
- _call_status_idle( p, co );
-
- } break;
-
- default:
- break;
- }
-
- return TRUE;
-}
-
-static TReturn s_call_outgoing( CoreObject *o, UserRequest *ur )
-{
- TcorePlugin* p = NULL;
- CallObject* co = 0;
- struct treq_call_dial* data = 0;
- char* raw_str= NULL;
- char* cmd_str = NULL;
- const char *cclir;
- struct ATReqMetaInfo metainfo;
- int info_len =0;
- enum tcore_call_cli_mode clir = CALL_CLI_MODE_DEFAULT;
-
- gboolean ret = FALSE;
-
- data = (struct treq_call_dial*)tcore_user_request_ref_data( ur, 0 );
- p = tcore_object_ref_plugin( o );
-
- clir = _get_clir_status( data->number );
-
-//Compose ATCmd string
- switch (clir)
- {
- case TCORE_CALL_CLI_MODE_PRESENT:
- cclir = "I";
- break; /*invocation*/
- case TCORE_CALL_CLI_MODE_RESTRICT:
- cclir = "i";
- break; /*suppression*/
- case TCORE_CALL_CLI_MODE_DEFAULT:
- default:
- cclir = "";
- break; /*subscription default*/
- }
-
- raw_str = g_strdup_printf("ATD%s%s;", data->number, cclir);
- cmd_str = g_strdup_printf("%s%s",raw_str,"\r");
-
- memset(&metainfo, 0, sizeof(struct ATReqMetaInfo));
-
-//set metainfo
- metainfo.type = NO_RESULT;
- metainfo.responsePrefix[0] ='\0';
- info_len = sizeof(struct ATReqMetaInfo);
-
- tcore_user_request_set_metainfo(ur, info_len, &metainfo);
-
- ret = _call_request_message ( o, ur, cmd_str, strlen(cmd_str), on_confirmation_call_outgoing, co);
-
- free(raw_str);
- free(cmd_str);
-
- if ( !ret ) {
- tcore_call_object_free( o, co );
- return TCORE_RETURN_FAILURE;
- }
-
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn s_call_answer( CoreObject *o, UserRequest *ur )
-{
- CallObject* co = 0;
- struct treq_call_answer* data = 0;
- gboolean ret = FALSE;
- char* cmd_str = NULL;
- struct ATReqMetaInfo metainfo ;
- unsigned int info_len =0;
-
- data = (struct treq_call_answer*)tcore_user_request_ref_data( ur, 0 );
-
- co = tcore_call_object_find_by_id( o, data->id );
-
- memset(&metainfo, 0, sizeof(struct ATReqMetaInfo));
-
-//set metainfo
- metainfo.type = NO_RESULT;
- metainfo.responsePrefix[0] = '\0';
- info_len = sizeof(struct ATReqMetaInfo);
-
- tcore_user_request_set_metainfo(ur, info_len, &metainfo);
-
- if ( data->type == CALL_ANSWER_TYPE_ACCEPT ) {
-
- cmd_str = g_strdup_printf("%s%s","ATA","\r");
- ret = _call_request_message ( o, ur, (void*)cmd_str, strlen(cmd_str), on_confirmation_call_accept, co);
- free(cmd_str);
- if ( !ret )
- return TCORE_RETURN_FAILURE;
-
- } else {
-
- switch ( data->type ) {
- case CALL_ANSWER_TYPE_REJECT: {
- dbg("call answer reject");
- tcore_call_control_answer_reject( o, ur, on_confirmation_call_reject, co );
- } break;
-
- case CALL_ANSWER_TYPE_REPLACE: {
- dbg("call answer replace");
- tcore_call_control_answer_replace( o, ur, on_confirmation_call_replace, co );
- } break;
-
- case CALL_ANSWER_TYPE_HOLD_ACCEPT: {
- dbg("call answer hold and accept");
- tcore_call_control_answer_hold_and_accept( o, ur, on_confirmation_call_hold_and_accept, co );
- } break;
-
- default :
- dbg("[ error ] wrong answer type [ %d ]", data->type);
- return TCORE_RETURN_FAILURE;
- }
- }
-
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn s_call_release( CoreObject *o, UserRequest *ur )
-{
- CallObject* co = 0;
-
- struct treq_call_end* data = 0;
- gboolean ret = FALSE;
- UserRequest* ur_dup = 0;
-
- char* chld0_cmd = NULL;
- char* chld1_cmd = NULL;
- struct ATReqMetaInfo metainfo1 ;
- struct ATReqMetaInfo metainfo2 ;
- unsigned int info_len1, info_len2 =0;
-
- data = (struct treq_call_end*)tcore_user_request_ref_data( ur, 0 );
-
- co = tcore_call_object_find_by_id( o, data->id );
-
- if ( data->type == CALL_END_TYPE_ALL ) {
-
- //releaseAll do not exist on legacy request. send CHLD=0, CHLD=1 in sequence
- chld0_cmd = g_strdup("AT+CHLD=0\r");
- chld1_cmd = g_strdup("AT+CHLD=1\r");
-
- memset(&metainfo1, 0, sizeof(struct ATReqMetaInfo));
- memset(&metainfo2, 0, sizeof(struct ATReqMetaInfo));
-
-
-//set metainfo
- metainfo1.type = NO_RESULT;
- metainfo1.responsePrefix[0] = '\0';
- info_len1 = sizeof(struct ATReqMetaInfo);
-
-//set metainfo
- metainfo2.type = NO_RESULT;
- metainfo2.responsePrefix[0] = '\0';
- info_len2 = sizeof(struct ATReqMetaInfo);
-
- ur_dup = tcore_user_request_new(NULL, NULL);
-
- tcore_user_request_set_metainfo(ur_dup, info_len1, &metainfo1);
- tcore_user_request_set_metainfo(ur, info_len2, &metainfo2);
-
- ret = _call_request_message(o, ur_dup, chld0_cmd, strlen(chld0_cmd), on_confirmation_call_endall, NULL);
- free(chld0_cmd);
- if ( !ret )
- return TCORE_RETURN_FAILURE;
-
- ret = _call_request_message(o, ur, chld1_cmd, strlen(chld1_cmd), on_confirmation_call_release_all, co);
- free(chld1_cmd);
- if ( !ret )
- return TCORE_RETURN_FAILURE;
-
- } else {
-
- switch ( data->type ) {
- case CALL_END_TYPE_DEFAULT: {
- int id = 0;
- id = tcore_call_object_get_id( co );
-
- dbg("call end call id [%d]", id);
- tcore_call_control_end_specific( o, ur, id, on_confirmation_call_release_specific, co );
- } break;
-
- case CALL_END_TYPE_ACTIVE_ALL: {
-
- dbg("call end all active");
- tcore_call_control_end_all_active( o, ur, on_confirmation_call_release_all_active, co );
- } break;
-
- case TCORE_CALL_END_ALL_HELD: {
-
- dbg("call end all held");
- tcore_call_control_end_all_held( o, ur, on_confirmation_call_release_all_held, co );
- } break;
-
- default :
- dbg("[ error ] wrong end type [ %d ]", data->type);
- return TCORE_RETURN_FAILURE;
- }
-
- }
-
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn s_call_hold( CoreObject *o, UserRequest *ur )
-{
- struct treq_call_hold *hold = 0;
- CallObject *co = 0;
- GSList *list_active, *list_incoming, *list_held;
-
- hold = (struct treq_call_hold*)tcore_user_request_ref_data( ur, 0 );
-
- /*
- * When Incoming Call and Outgoing Call operates concurrently with one
- * already exist Call. Telephony intend to having one Active Call and
- * one Incoming Call. But, at that time, Application does not received
- * Incoming Call Notification. Therefore, Application call
- * tel_hold_call() to hold already exist Active Call. At this point,
- * Telephony should reject the request of tel_hold_call() because
- * tel_hold_call() sends AT+CHLD=2 which means "place active call on
- * hold and accepts the incoming call".
- */
- list_active = tcore_call_object_find_by_status(o, TCORE_CALL_STATUS_ACTIVE);
- list_incoming = tcore_call_object_find_by_status(o, TCORE_CALL_STATUS_INCOMING);
- list_held = tcore_call_object_find_by_status(o, TCORE_CALL_STATUS_HELD);
- if (!(list_active != NULL && list_incoming == NULL && list_held == NULL)) {
- struct tresp_call_hold resp;
-
- dbg("Hold Call operation is not allowed");
-
- resp.err = CALL_ERROR_SERVICE_NOT_ALLOWED;
- resp.id = hold->id;
- tcore_user_request_send_response(ur, TRESP_CALL_HOLD, sizeof(resp), &resp);
-
- return TCORE_RETURN_FAILURE;
- }
-
- dbg("call id : [ %d ]", hold->id);
-
- co = tcore_call_object_find_by_id( o, hold->id );
-
- tcore_call_control_hold( o, ur, on_confirmation_call_hold, co );
-
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn s_call_active( CoreObject *o, UserRequest *ur )
-{
- struct treq_call_active *active = 0;
- CallObject *co = 0;
- GSList *list_active, *list_incoming, *list_held;
-
- active = (struct treq_call_active*)tcore_user_request_ref_data( ur, 0 );
- dbg("Active ID = %d", active->id);
-
- list_active = tcore_call_object_find_by_status(o, TCORE_CALL_STATUS_ACTIVE);
- list_incoming = tcore_call_object_find_by_status(o, TCORE_CALL_STATUS_INCOMING);
- list_held = tcore_call_object_find_by_status(o, TCORE_CALL_STATUS_HELD);
-
- if (!(list_held != NULL && list_incoming == NULL && list_active == NULL)) {
- struct tresp_call_active resp;
-
- dbg("Active Call operation is not allowed");
-
- resp.err = CALL_ERROR_SERVICE_NOT_ALLOWED;
- resp.id = active->id;
- tcore_user_request_send_response(ur, TRESP_CALL_ACTIVE, sizeof(resp), &resp);
-
- return TCORE_RETURN_FAILURE;
- }
-
- dbg("call id : [ %d ]", active->id);
-
- co = tcore_call_object_find_by_id( o, active->id );
-
- tcore_call_control_active( o, ur, on_confirmation_call_active, co );
-
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn s_call_swap( CoreObject *o, UserRequest *ur )
-{
- struct treq_call_swap *swap = 0;
- CallObject *co = 0;
- swap = (struct treq_call_swap*)tcore_user_request_ref_data( ur, 0 );
-
- dbg("call id : [ %d ]", swap->id);
-
- co = tcore_call_object_find_by_id( o, swap->id );
-
- tcore_call_control_swap( o, ur, on_confirmation_call_swap, co );
-
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn s_call_join( CoreObject *o, UserRequest *ur )
-{
- struct treq_call_join *join = 0;
- CallObject *co = 0;
-
- join = (struct treq_call_join*)tcore_user_request_ref_data( ur, 0 );
-
- dbg("call id : [ %d ]", join->id);
-
- co = tcore_call_object_find_by_id( o, join->id );
-
- tcore_call_control_join( o, ur, on_confirmation_call_join, co );
-
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn s_call_split( CoreObject *o, UserRequest *ur )
-{
- struct treq_call_split *split = 0;
- CallObject *co = 0;
-
- split = (struct treq_call_split*)tcore_user_request_ref_data( ur, 0 );
-
- co = tcore_call_object_find_by_id ( o, split->id );
-
- tcore_call_control_split( o, ur, split->id, on_confirmation_call_split, co );
-
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn s_call_deflect( CoreObject *o, UserRequest *ur )
-{
- struct treq_call_deflect *deflect = 0;
- CallObject *co = 0;
-
- deflect = (struct treq_call_deflect*)tcore_user_request_ref_data( ur, 0 );
-
- co = tcore_call_object_find_by_number( o, deflect->number );
-
- tcore_call_control_deflect( o, ur, deflect->number, on_confirmation_call_deflect, co );
-
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn s_call_transfer( CoreObject *o, UserRequest *ur )
-{
- struct treq_call_transfer *transfer = 0;
- CallObject *co = 0;
-
- transfer = (struct treq_call_transfer*)tcore_user_request_ref_data( ur, 0 );
-
- dbg("call id : [ %d ]", transfer->id);
-
- co = tcore_call_object_find_by_id( o, transfer->id );
-
- tcore_call_control_transfer( o, ur, on_confirmation_call_transfer, co );
-
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn s_call_send_dtmf( CoreObject *o, UserRequest *ur )
-{
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn s_call_set_sound_path( CoreObject *o, UserRequest *ur )
-{
-
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn s_call_set_sound_volume_level( CoreObject *o, UserRequest *ur )
-{
-
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn s_call_get_sound_volume_level( CoreObject *o, UserRequest *ur )
-{
-
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn s_call_mute( CoreObject *o, UserRequest *ur )
-{
-
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn s_call_unmute( CoreObject *o, UserRequest *ur )
-{
-
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn s_call_get_mute_status( CoreObject *o, UserRequest *ur )
-{
-
- return TCORE_RETURN_SUCCESS;
-}
-
-static struct tcore_call_operations call_ops = {
- .dial = s_call_outgoing,
- .answer = s_call_answer,
- .end = s_call_release,
- .hold = s_call_hold,
- .active = s_call_active,
- .swap = s_call_swap,
- .join = s_call_join,
- .split = s_call_split,
- .deflect = s_call_deflect,
- .transfer = s_call_transfer,
- .send_dtmf = s_call_send_dtmf,
- .set_sound_path = s_call_set_sound_path,
- .set_sound_volume_level = s_call_set_sound_volume_level,
- .get_sound_volume_level = s_call_get_sound_volume_level,
- .mute = s_call_mute,
- .unmute = s_call_unmute,
- .get_mute_status = s_call_get_mute_status,
-};
-
-gboolean s_call_init(TcorePlugin *cp, CoreObject *co)
-{
- tcore_call_override_ops(co, &call_ops, NULL);
-
- tcore_object_override_callback( co, EVENT_CALL_STATUS, on_notification_call_status, NULL );
- tcore_object_override_callback( co, EVENT_CALL_INCOMING, on_notification_call_incoming, NULL );
- tcore_object_override_callback( co, EVENT_CALL_WAITING, on_notification_call_waiting, NULL );
-
- return TRUE;
-}
-
-void s_call_exit(TcorePlugin *cp, CoreObject *co)
-{
- dbg("Exit");
-}
+++ /dev/null
-/*
- * tel-plugin-atmodem
- *
- * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: Hayoon Ko <hayoon.ko@samsung.com>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-
-#include <glib.h>
-
-
-#include "s_common.h"
-
-#include <plugin.h>
-
-#undef MAX
-#define MAX(a, b) (((a) > (b)) ? (a) : (b))
-
-#define bitsize(type) (sizeof(type) * 8)
-
-#define copymask(type) ((0xffffffff) >> (32 - bitsize(type)))
-
-#define MASK(width, offset, data) \
- (((width) == bitsize(data)) ? (data) : \
- ((((copymask(data) << (bitsize(data) - ((width) % bitsize(data)))) & copymask(data)) >> (offset)) & (data))) \
-
-
-#define MASK_AND_SHIFT(width, offset, shift, data) \
- ((((signed) (shift)) < 0) ? \
- MASK((width), (offset), (data)) << -(shift) : \
- MASK((width), (offset), (data)) >> (((signed) (shift)))) \
-
-char _util_unpackb(const char *src, int pos, int len);
-char _util_convert_byte_hexChar(char val);
-gboolean util_byte_to_hex(const char *byte_pdu, char *hex_pdu, int num_bytes);
-
-char _util_unpackb(const char *src, int pos, int len)
-{
- char result = 0;
- int rshift = 0;
-
- src += pos / 8;
- pos %= 8;
-
- rshift = MAX(8 - (pos + len), 0);
-
- if (rshift > 0) {
- result = MASK_AND_SHIFT(len, pos, rshift, (unsigned char)*src);
- } else {
- result = MASK(8 - pos, pos, (unsigned char)*src);
- src++;
- len -= 8 - pos;
-
- if (len > 0) result = (result << len) | (*src >> (8 - len)); // if any bits left
- }
-
- return result;
-}
-
-char _util_convert_byte_hexChar(char val)
-{
- char hex_char;
-
- if (val <= 9) {
- hex_char = (char) (val + '0');
- } else if (val >= 10 && val <= 15) {
- hex_char = (char) (val - 10 + 'A');
- } else {
- hex_char = '0';
-}
-
- return (hex_char);
-}
-
-gboolean util_byte_to_hex(const char *byte_pdu, char *hex_pdu, int num_bytes)
-{
- int i;
- char nibble;
- int buf_pos = 0;
-
- for (i = 0; i < num_bytes * 2; i++) {
- nibble = _util_unpackb(byte_pdu, buf_pos, 4);
- buf_pos += 4;
- hex_pdu[i] = _util_convert_byte_hexChar(nibble);
- }
-
- return TRUE;
-}
-
-void util_hex_dump(char *pad, int size, const void *data)
-{
- char buf[255] = {0, };
- char hex[4] = {0, };
- int i;
- unsigned char *p;
-
- if (size <= 0) {
- msg("%sno data", pad);
- return;
- }
-
- p = (unsigned char *)data;
-
- snprintf(buf, 255, "%s%04X: ", pad, 0);
- for (i = 0; i<size; i++) {
- snprintf(hex, 4, "%02X ", p[i]);
- strcat(buf, hex);
-
- if ((i + 1) % 8 == 0) {
- if ((i + 1) % 16 == 0) {
- msg("%s", buf);
- memset(buf, 0, 255);
- snprintf(buf, 255, "%s%04X: ", pad, i + 1);
- }
- else {
- strcat(buf, " ");
- }
- }
- }
-
- msg("%s", buf);
-}
-
-void hook_hex_dump(enum direction_e d, int size, const void *data)
-{
- msg("=== TX data DUMP =====");
- util_hex_dump(" ", size, data);
- msg("=== TX data DUMP =====");
-
-}
-
-unsigned int util_assign_message_sequence_id(TcorePlugin *p)
-{
- struct global_data *gd;
-
- if (!p) {
- dbg("plugin is NULL");
- return -1;
- }
-
- gd = tcore_plugin_ref_user_data(p);
- if (!gd) {
- dbg("global data is NULL");
- return -1;
- }
-
- if (gd->msg_auto_id_current == 0) {
- gd->msg_auto_id_current = gd->msg_auto_id_start;
- dbg("pending_auto_id_current is 0, reset to start");
- }
- else if (gd->msg_auto_id_current >= gd->msg_auto_id_end) {
- gd->msg_auto_id_current = gd->msg_auto_id_start;
- dbg("pending_auto_id_current is over, reset to start");
- }
- else {
- gd->msg_auto_id_current++;
- }
-
- dbg("message_sequence_id = %d", gd->msg_auto_id_current);
-
- return gd->msg_auto_id_current;
-}
-
-gboolean util_add_waiting_job(GQueue *queue, unsigned int id, UserRequest *ur)
-{
- struct work_queue_data *wqd;
-
- if (!queue)
- return FALSE;
-
- wqd = calloc(sizeof(struct work_queue_data), 1);
- if (!wqd)
- return FALSE;
-
- wqd->id = id;
- wqd->ur = tcore_user_request_ref(ur);
- g_queue_push_tail(queue, wqd);
-
- dbg("id = %d, ur = 0x%x", wqd->id, wqd->ur);
- return TRUE;
-}
-
-UserRequest *util_pop_waiting_job(GQueue *queue, unsigned int id)
-{
- int i = 0;
- UserRequest *ur;
- struct work_queue_data *wqd;
-
- if (!queue)
- return NULL;
-
-
- dbg("before waiting job count: %d", g_queue_get_length(queue));
-
- do {
- wqd = g_queue_peek_nth(queue, i);
- if (!wqd)
- return NULL;
-
- if (wqd->id == id) {
- wqd = g_queue_pop_nth(queue, i);
- break;
- }
-
- i++;
- } while (wqd != NULL);
-
- dbg("after waiting job count: %d", g_queue_get_length(queue));
-
- if (!wqd)
- return NULL;
-
- ur = wqd->ur;
- free(wqd);
-
- return ur;
-}
-
-unsigned char util_hexCharToInt(char c)
-{
- if (c >= '0' && c <= '9')
- return (c - '0');
- else if (c >= 'A' && c <= 'F')
- return (c - 'A' + 10);
- else if (c >= 'a' && c <= 'f')
- return (c - 'a' + 10);
- else
- {
- dbg("invalid charater!!");
- return -1;
- }
-}
-
-char * util_hexStringToBytes(char * s)
-{
- char * ret;
- int i;
- int sz;
-
- if (s == NULL)
- return NULL;
-
- sz = strlen(s);
-
- ret = calloc((sz/2)+1, 1);
-
- dbg("Convert String to Binary!!");
-
- for (i = 0; i < sz; i += 2) {
- ret[i / 2] = (char) ((util_hexCharToInt(s[i]) << 4) | util_hexCharToInt(s[i + 1]));
- dbg("[%02x]", ret[i/2]);
- }
-
- return ret;
-}
-
+++ /dev/null
-/*
- * tel-plugin-atmodem
- *
- * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: Hayoon Ko <hayoon.ko@samsung.com>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <glib.h>
-
-#include <tcore.h>
-#include <hal.h>
-#include <core_object.h>
-#include <plugin.h>
-#include <queue.h>
-#include <co_modem.h>
-#include <storage.h>
-#include <server.h>
-
-#include "s_common.h"
-#include "s_modem.h"
-
-#include "atchannel.h"
-#include "at_tok.h"
-
-#define MAX_VERSION_LEN 32
-#define TAPI_MISC_ME_SN_LEN_MAX 32
-#define TAPI_MISC_PRODUCT_CODE_LEN_MAX 32
-#define TAPI_MISC_MODEL_ID_LEN_MAX 17
-#define TAPI_MISC_PRL_ERI_VER_LEN_MAX 17
-
-enum cp_state {
- CP_STATE_OFFLINE,
- CP_STATE_CRASH_RESET,
- CP_STATE_CRASH_EXIT,
- CP_STATE_BOOTING,
- CP_STATE_ONLINE,
- CP_STATE_NV_REBUILDING,
- CP_STATE_LOADER_DONE,
-};
-
-
-enum TelMiscSNIndexType_t{
- TAPI_MISC_ME_IMEI = 0x00, /**< 0x00: IMEI, GSM/UMTS device */
- TAPI_MISC_ME_ESN = 0x01, /**< 0x01: ESN(Electronic Serial Number), It`s essentially run out. CDMA device */
- TAPI_MISC_ME_MEID = 0x02, /**< 0x02: MEID, This value can have hexa decimal digits. CDMA device */
- TAPI_MISC_ME_MAX = 0xff /**< 0xff: reserved */
-};
-
-struct TelMiscSNInformation{
- enum TelMiscSNIndexType_t sn_index; /**< serial number index */
- int sn_len; /**< Length */
- unsigned char szNumber[TAPI_MISC_ME_SN_LEN_MAX]; /**< Number */
-};
-
-/**
- * Mobile Equipment Version Information
- */
-struct TelMiscVersionInformation{
- unsigned char ver_mask; /**< version mask - 0x01:SW_ver, 0x02:HW_ver, 0x04:RF_CAL_date, 0x08:Product_code, 0x10:Model_ID, 0x20:PRL, 0x04:ERI, 0xff:all */
- unsigned char szSwVersion[MAX_VERSION_LEN]; /**< Software version, null termination */
- unsigned char szHwVersion[MAX_VERSION_LEN]; /**< Hardware version, null termination */
- unsigned char szRfCalDate[MAX_VERSION_LEN]; /**< Calculation Date, null termination */
- unsigned char szProductCode[TAPI_MISC_PRODUCT_CODE_LEN_MAX]; /**< product code, null termination */
- unsigned char szModelId[TAPI_MISC_MODEL_ID_LEN_MAX]; /**< model id (only for CDMA), null termination */
- unsigned char prl_nam_num; /**< number of PRL NAM fields */
- unsigned char szPrlVersion[TAPI_MISC_PRL_ERI_VER_LEN_MAX * 3];/**< prl version (only for CDMA), null termination */
- unsigned char eri_nam_num; /**< number of PRL NAM fields */
- unsigned char szEriVersion[TAPI_MISC_PRL_ERI_VER_LEN_MAX * 3];/**< eri version (only for CDMA), null termination */
-};
-
-extern struct ATResponse *sp_response;
-extern char *s_responsePrefix;
-extern enum ATCommandType s_type;
-
-static void on_confirmation_modem_message_send(TcorePending *p, gboolean result, void *user_data ); // from Kernel
-
-static void on_confirmation_modem_message_send( TcorePending *p, gboolean result, void *user_data )
-{
- UserRequest* ur = NULL;
- struct ATReqMetaInfo* metainfo = NULL;
- unsigned int info_len =0;
- dbg("on_confirmation_modem_message_send - msg out from queue. alloc ATRsp buffer & write rspPrefix if needed\n");
-
- ReleaseResponse(); // release leftover
-//alloc new sp_response
- sp_response = at_response_new();
-
-
- ur = tcore_pending_ref_user_request(p);
- metainfo = (struct ATReqMetaInfo*)tcore_user_request_ref_metainfo(ur,&info_len);
-
- if((metainfo->type == SINGLELINE)||
- (metainfo->type == MULTILINE))
- {
- //cp rsp prefix
- s_responsePrefix = strdup(metainfo->responsePrefix);
- dbg("duplicating responsePrefix : %s\n", s_responsePrefix);
- }
- else
- {
- s_responsePrefix = NULL;
- }
-
-//set atcmd type into s_type
- s_type = metainfo->type;
-
- if (result == FALSE) {
- /* Fail */
- dbg("SEND FAIL");
- }
- else {
- dbg("SEND OK");
- }
-}
-static gboolean on_sys_event_modem_power(CoreObject *o, const void *event_info, void *user_data)
-{
- struct tnoti_modem_power modem_power;
- enum cp_state *state;
-
- state = (enum cp_state*)event_info;
- dbg("state : (0x%x)", *state);
-
- if ( *state == CP_STATE_OFFLINE || *state == CP_STATE_CRASH_RESET ) {
-
- tcore_modem_set_powered(o, FALSE);
-
- if ( *state == CP_STATE_OFFLINE )
- modem_power.state = MODEM_STATE_OFFLINE;
- else
- modem_power.state = MODEM_STATE_ERROR;
-
- } else {
- dbg("useless state : (0x%x)", *state);
- return TRUE;
- }
-
- tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_MODEM_POWER,
- sizeof(struct tnoti_modem_power), &modem_power);
-
- return TRUE;
-}
-
-static gboolean on_event_modem_power(CoreObject *o, const void *event_info, void *user_data)
-{
- struct treq_modem_set_flightmode flight_mode_set;
- struct tnoti_modem_power modem_power;
- UserRequest *ur;
- TcoreHal *h;
- Storage *strg;
-
- strg = tcore_server_find_storage(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), "vconf");
- flight_mode_set.enable = tcore_storage_get_bool(strg, STORAGE_KEY_FLIGHT_MODE_BOOL);
-
- h = tcore_object_get_hal(o);
-
- tcore_hal_set_power_state(h, TRUE);
-
- ur = tcore_user_request_new(NULL, NULL);
- tcore_user_request_set_data(ur, sizeof(struct treq_modem_set_flightmode), &flight_mode_set);
- tcore_user_request_set_command(ur, TREQ_MODEM_SET_FLIGHTMODE);
- tcore_object_dispatch_request(o, ur);
-
- ur = tcore_user_request_new(NULL, NULL);
- tcore_user_request_set_command(ur, TREQ_MODEM_GET_IMEI);
- tcore_object_dispatch_request(o, ur);
-
- ur = tcore_user_request_new(NULL, NULL);
- tcore_user_request_set_command(ur, TREQ_MODEM_GET_VERSION);
- tcore_object_dispatch_request(o, ur);
-
- tcore_modem_set_powered(o, TRUE);
-
- modem_power.state = MODEM_STATE_ONLINE;
-
- tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_MODEM_POWER,
- sizeof(struct tnoti_modem_power), &modem_power);
-
- return TRUE;
-}
-
-static gboolean on_event_modem_phone_state(CoreObject *o, const void *event_info, void *user_data)
-{
- char* line = (char*)event_info;
- GQueue *queue;
- UserRequest *ur;
- int err, status;
- struct tresp_modem_set_flightmode res;
- const struct treq_modem_set_flightmode *req_data = NULL;
- #define SCFUN_MIN_FUNC 0
- #define SCFUN_FULL_FUNC 1
-
- dbg("received notification : %s", line);
-
- at_tok_start(&line);
-
- err = at_tok_nextint(&line, &status);
-
- switch (status) {
- case SCFUN_MIN_FUNC:
- res.result = 0x01;
- tcore_modem_set_flight_mode_state(o, TRUE);
- break;
-
- case SCFUN_FULL_FUNC:
- res.result = 0x02;
- tcore_modem_set_flight_mode_state(o, FALSE);
- break;
- }
-
- queue = tcore_object_ref_user_data(o);
- if (queue) {
- ur = util_pop_waiting_job(queue, ID_RESERVED_AT);
- if (tcore_user_request_ref_communicator(ur)) {
- req_data = tcore_user_request_ref_data(ur, NULL);
- if (TRUE == req_data->enable) {
- res.result = 1;
- tcore_modem_set_flight_mode_state(o, TRUE);
- } else {
- res.result = 2;
- tcore_modem_set_flight_mode_state(o, FALSE);
- }
- tcore_user_request_send_response(ur, TRESP_MODEM_SET_FLIGHTMODE, sizeof(struct tresp_modem_set_flightmode), &res);
- }
- }
- return TRUE;
-}
-
-static void on_response_poweron(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- printResponse();
-
- if(sp_response->success > 0) {
- dbg("RESPONSE OK");
- ReleaseResponse();
- on_event_modem_power(tcore_pending_ref_core_object(p), NULL, NULL);
- } else{
- dbg("RESPONSE NOK");
- ReleaseResponse();
- s_modem_send_poweron(tcore_object_ref_plugin(tcore_pending_ref_core_object(p)));
- }
-}
-
-static void on_response_set_flight_mode(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- CoreObject *o = user_data;
- UserRequest *ur;
- struct tresp_modem_set_flightmode res;
- GQueue *queue;
-
-//print sp_response - for debug
- printResponse();
- ur = tcore_pending_ref_user_request(p);
-
- if (sp_response->success > 0) {
- dbg("RESPONSE OK");
- //parse response
- queue = tcore_object_ref_user_data(o);
- if (queue) {
- ur = tcore_user_request_ref(ur);
- util_add_waiting_job(queue, ID_RESERVED_AT, ur);
- }
-
- ReleaseResponse();
- } else {
- dbg("RESPONSE NOK");
- res.result = 3;
-
- ReleaseResponse();
-
- tcore_user_request_send_response(ur, TRESP_MODEM_SET_FLIGHTMODE, sizeof(struct tresp_modem_set_flightmode), &res);
- }
-}
-static void on_response_imei(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- TcorePlugin *plugin;
- struct tresp_modem_get_imei res;
- UserRequest *ur;
- struct TelMiscSNInformation *imei_property;
- char *line;
- int response;
- int err;
-
- printResponse();
-
- memset(&res, 0, sizeof(struct tresp_modem_get_imei));
-
- if(sp_response->success > 0)
- {
- dbg("RESPONSE OK");
-
- line = sp_response->p_intermediates->line;
-
- res.result = TCORE_RETURN_SUCCESS;
- strncpy(res.imei, line, 16);
-
- dbg("imei = [%s]", res.imei);
-
- plugin = tcore_pending_ref_plugin(p);
- imei_property = tcore_plugin_ref_property(plugin, "IMEI");
- if (imei_property)
- {
- imei_property->sn_index = TAPI_MISC_ME_IMEI;
- imei_property->sn_len = strlen(res.imei);
- memcpy(imei_property->szNumber, res.imei, imei_property->sn_len);
- }
- }
- else
- {
- dbg("RESPONSE NOK");
- line = sp_response->finalResponse;
-
- err = at_tok_start(&line);
- if (err < 0)
- {
- dbg("err cause not specified or string corrupted");
- res.result = TCORE_RETURN_3GPP_ERROR;
- }
- else
- {
- err = at_tok_nextint(&line, &response);
- if (err < 0)
- {
- dbg("err not specified or string not contail error");
- res.result = TCORE_RETURN_3GPP_ERROR;
- }
- else
- {
- res.result = convertCMEError((enum ATCMEError)response);
- }
- }
- }
-
- ReleaseResponse();
-
- ur = tcore_pending_ref_user_request(p);
- tcore_user_request_send_response(ur, TRESP_MODEM_GET_IMEI, sizeof(struct tresp_modem_get_imei), &res);
-
-}
-
-static void on_response_version(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- TcorePlugin *plugin;
- struct TelMiscVersionInformation *vi;
- struct TelMiscVersionInformation *vi_property;
- struct tresp_modem_get_version res;
- UserRequest *ur;
- char* line=NULL;
- char *swver= NULL,*hwver=NULL, *caldate=NULL,*pcode=NULL,*id=NULL;
-
- int response, err;
-
- printResponse();
-
-#define AT_VER_LEN 20
- if(sp_response->success > 0)
- {
- dbg("RESPONSE OK");
-
- line = sp_response->p_intermediates->line;
- err = at_tok_start(&line);
-
- err = at_tok_nextstr(&line,&swver);
- if(swver!=NULL)
- err = at_tok_nextstr(&line,&hwver);
- if(hwver!=NULL)
- err = at_tok_nextstr(&line,&caldate);
- if(caldate !=NULL)
- err = at_tok_nextstr(&line,&pcode);
- if(pcode !=NULL)
- err = at_tok_nextstr(&line,&id);
-
- dbg("version: sw=[%s], hw=[%s], rf_cal=[%s], product_code=[%s], model_id=[%s]", swver, hwver, caldate, pcode, id);
-
- vi = calloc(sizeof(struct TelMiscVersionInformation), 1);
- memcpy(vi->szSwVersion, swver, strlen(swver));
- memcpy(vi->szHwVersion, hwver, strlen(hwver));
- memcpy(vi->szRfCalDate, caldate, strlen(caldate));
- memcpy(vi->szProductCode, pcode,strlen(pcode));
- memcpy(vi->szModelId, id, strlen(id));
-
- memset(&res, 0, sizeof(struct tresp_modem_get_imei));
- snprintf(res.software, (AT_VER_LEN >strlen(swver) ?strlen(swver):AT_VER_LEN), "%s", swver);
- snprintf(res.hardware, (AT_VER_LEN >strlen(hwver) ?strlen(hwver):AT_VER_LEN), "%s", hwver);
-
- plugin = tcore_pending_ref_plugin(p);
- vi_property = tcore_plugin_ref_property(plugin, "VERSION");
- memcpy(vi_property, vi, sizeof(struct TelMiscVersionInformation));
- }
- else
- {
- dbg("RESPONSE NOK");
- line = sp_response->finalResponse;
-
- memset(&res, 0, sizeof(struct tresp_modem_get_version));
-
- err = at_tok_start(&line);
- if (err < 0)
- {
- dbg("err cause not specified or string corrupted");
- res.result = TCORE_RETURN_3GPP_ERROR;
- }
- else
- {
- err = at_tok_nextint(&line, &response);
- if (err < 0)
- {
- dbg("err not specified or string not contail error");
- res.result = TCORE_RETURN_3GPP_ERROR;
- }
- else
- {
- res.result = convertCMEError((enum ATCMEError)response);
- }
- }
- }
-
- ReleaseResponse();
-
- ur = tcore_pending_ref_user_request(p);
- tcore_user_request_send_response(ur, TRESP_MODEM_GET_VERSION, sizeof(struct tresp_modem_get_version), &res);
-
-}
-
-static TReturn power_on(CoreObject *o, UserRequest *ur)
-{
-
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn power_off(CoreObject *o, UserRequest *ur)
-{
- struct tnoti_modem_power modem_power;
- modem_power.state = MODEM_STATE_OFFLINE;
-
- tcore_modem_set_powered(o, FALSE);
-
- tcore_server_send_notification( tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_MODEM_POWER,
- sizeof(struct tnoti_modem_power), &modem_power);
-
- return TCORE_RETURN_SUCCESS;
-}
-static TReturn power_reset(CoreObject *o, UserRequest *ur)
-{
-
- return TCORE_RETURN_SUCCESS;
-}
-static TReturn get_imei(CoreObject *o, UserRequest *ur)
-{
- TcorePlugin *p = NULL;
- TcoreHal *h = NULL;
- TcorePending *pending = NULL;
- char* cmd_str = NULL;
- struct ATReqMetaInfo metainfo;
- int info_len =0;
-
- p = tcore_object_ref_plugin(o);
- h = tcore_object_get_hal(o);
-
- memset(&metainfo, 0, sizeof(struct ATReqMetaInfo));
- metainfo.type = NUMERIC;
- metainfo.responsePrefix[0] ='\0';
- info_len = sizeof(struct ATReqMetaInfo);
-
- tcore_user_request_set_metainfo(ur, info_len, &metainfo);
-
- cmd_str = g_strdup("AT+CGSN\r");
- dbg("cmd : %s, prefix(if any) : %s, cmd_len : %d",cmd_str, "N/A", strlen(cmd_str));
-
- pending = tcore_pending_new(o, ID_RESERVED_AT);
- tcore_pending_set_request_data(pending, strlen(cmd_str), cmd_str);
- free(cmd_str);
- tcore_pending_set_timeout(pending, 0);
- tcore_pending_set_response_callback(pending, on_response_imei, NULL);
- tcore_pending_link_user_request(pending, ur);
- tcore_pending_set_priority(pending, TCORE_PENDING_PRIORITY_DEFAULT);
-
- tcore_pending_set_send_callback(pending, on_confirmation_modem_message_send, NULL);
-
-
- tcore_hal_send_request(h, pending);
-
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn get_version(CoreObject *o, UserRequest *ur)
-{
- TcorePlugin *p = NULL;
- TcoreHal *h = NULL;
- TcorePending *pending = NULL;
- char* cmd_str = NULL;
- struct ATReqMetaInfo metainfo;
- int info_len =0;
-
- p = tcore_object_ref_plugin(o);
- h = tcore_object_get_hal(o);
-
- memset(&metainfo, 0, sizeof(struct ATReqMetaInfo));
- metainfo.type = SINGLELINE;
- memcpy(metainfo.responsePrefix,"+CGMR:",strlen("+CGMR:"));
- info_len = sizeof(struct ATReqMetaInfo);
-
- tcore_user_request_set_metainfo(ur, info_len, &metainfo);
-
- cmd_str = g_strdup("AT+CGMR\r");
-
- dbg("cmd : %s, prefix(if any) : %s, cmd_len : %d",cmd_str, "N/A", strlen(cmd_str));
-
- pending = tcore_pending_new(o, ID_RESERVED_AT);
- tcore_pending_set_request_data(pending, strlen(cmd_str), cmd_str);
- free(cmd_str);
- tcore_pending_set_timeout(pending, 0);
- tcore_pending_set_response_callback(pending, on_response_version, NULL);
- tcore_pending_link_user_request(pending, ur);
- tcore_pending_set_priority(pending, TCORE_PENDING_PRIORITY_DEFAULT);
-
- tcore_pending_set_send_callback(pending, on_confirmation_modem_message_send, NULL);
-
- tcore_hal_send_request(h, pending);
-
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn set_flight_mode(CoreObject *o, UserRequest *ur)
-{
- TcorePlugin *p = NULL;
- TcoreHal *h = NULL;
- TcorePending *pending = NULL;
- const struct treq_modem_set_flightmode *req_data;
- char* cmd_str = NULL;
- struct ATReqMetaInfo metainfo;
- int info_len =0;
-
- p = tcore_object_ref_plugin(o);
- h = tcore_object_get_hal(o);
-
- req_data = tcore_user_request_ref_data(ur, NULL);
-
- if (req_data->enable) {
- dbg("Flight mode on/n");
- cmd_str = g_strdup("AT+CFUN=0\r");
- }
- else {
- dbg("Flight mode off/n");
- cmd_str = g_strdup("AT+CFUN=1\r");
- }
-
- memset(&metainfo, 0, sizeof(struct ATReqMetaInfo));
- metainfo.type = NO_RESULT;
- metainfo.responsePrefix[0] ='\0';
- info_len = sizeof(struct ATReqMetaInfo);
-
- tcore_user_request_set_metainfo(ur, info_len, &metainfo);
-
- dbg("cmd : %s, prefix(if any) : %s, cmd_len : %d",cmd_str, "N/A", strlen(cmd_str));
-
- pending = tcore_pending_new(o, ID_RESERVED_AT);
- tcore_pending_set_request_data(pending, strlen(cmd_str), cmd_str);
- free(cmd_str);
- tcore_pending_set_timeout(pending, 0);
- tcore_pending_set_response_callback(pending, on_response_set_flight_mode, o);
- tcore_pending_link_user_request(pending, ur);
- tcore_pending_set_priority(pending, TCORE_PENDING_PRIORITY_DEFAULT);
-
- tcore_pending_set_send_callback(pending, on_confirmation_modem_message_send, NULL);
-
- tcore_hal_send_request(h, pending);
-
- return TCORE_RETURN_SUCCESS;
-}
-
-static struct tcore_modem_operations modem_ops =
-{
- .power_on = power_on,
- .power_off = power_off,
- .power_reset = power_reset,
- .set_flight_mode = set_flight_mode,
- .get_imei = get_imei,
- .get_version = get_version,
-};
-
-gboolean s_modem_init(TcorePlugin *cp, CoreObject *co)
-{
- GQueue *work_queue;
- struct TelMiscVersionInformation *vi_property;
- struct TelMiscSNInformation *imei_property;
-
- dbg("Entry");
-
- tcore_modem_override_ops(co, &modem_ops);
-
- work_queue = g_queue_new();
- tcore_object_link_user_data(co, work_queue);
-
- tcore_object_override_callback(co, EVENT_SYS_NOTI_MODEM_POWER, on_sys_event_modem_power, NULL);
- tcore_object_override_callback(co, EVENT_MODEM_PHONE_STATE, on_event_modem_phone_state, NULL);
-
- vi_property = calloc(sizeof(struct TelMiscVersionInformation), 1);
- tcore_plugin_link_property(cp, "VERSION", vi_property);
-
- imei_property = calloc(sizeof(struct TelMiscSNInformation), 1);
- tcore_plugin_link_property(cp, "IMEI", imei_property);
-
- dbg("Exit");
-
- return TRUE;
-}
-
-void s_modem_exit(TcorePlugin *cp, CoreObject *co)
-{
- GQueue *work_queue;
- struct TelMiscVersionInformation *vi_property;
- struct TelMiscSNInformation *imei_property;
-
- work_queue = tcore_object_ref_user_data(co);
- g_queue_free(work_queue);
-
- vi_property = tcore_plugin_ref_property(cp, "VERSION");
- if (vi_property)
- free(vi_property);
-
- imei_property = tcore_plugin_ref_property(cp, "IMEI");
- if (imei_property)
- free(imei_property);
-
- dbg("Exit");
-}
-
-gboolean s_modem_send_poweron(TcorePlugin *cp)
-{
- UserRequest* ur;
- TcoreHal* hal;
- TcorePending *pending = NULL;
- CoreObject *o;
-
- char *cmd_str = NULL;
- struct ATReqMetaInfo metainfo;
- int info_len =0;
-
- o = tcore_plugin_ref_core_object(cp, CORE_OBJECT_TYPE_MODEM);
- ur = tcore_user_request_new(NULL, NULL);
-
- memset(&metainfo, 0, sizeof(struct ATReqMetaInfo));
- metainfo.type = SINGLELINE;
- memcpy(metainfo.responsePrefix,"+CPAS:",strlen("+CPAS:"));
- info_len = sizeof(struct ATReqMetaInfo);
- tcore_user_request_set_metainfo(ur, info_len, &metainfo);
-
- cmd_str = g_strdup("AT+CPAS\r");
-
- dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d",cmd_str, metainfo.responsePrefix, strlen(cmd_str));
-
- hal = tcore_object_get_hal(o);
-
- pending = tcore_pending_new(o, ID_RESERVED_AT);
- tcore_pending_set_request_data(pending, strlen(cmd_str), cmd_str);
- free(cmd_str);
- tcore_pending_set_timeout(pending, 0);
- tcore_pending_set_response_callback(pending, on_response_poweron, NULL);
- tcore_pending_link_user_request(pending, ur);
- tcore_pending_set_priority(pending, TCORE_PENDING_PRIORITY_DEFAULT);
-
- tcore_pending_set_send_callback(pending, on_confirmation_modem_message_send, NULL);
-
- tcore_hal_send_request(hal, pending);
-
- return TRUE;
-
-}
+++ /dev/null
-/*
- * tel-plugin-atmodem
- *
- * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: Hayoon Ko <hayoon.ko@samsung.com>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <glib.h>
-
-#define FEATURE_SAMSUNG_ONEDRAM
-
-#include <tcore.h>
-#include <hal.h>
-#include <core_object.h>
-#include <plugin.h>
-#include <queue.h>
-#include <co_ps.h>
-#include <co_network.h>
-#include <server.h>
-#include <storage.h>
-#include <tzplatform_config.h>
-
-#include "s_common.h"
-#include "s_network.h"
-#include "atchannel.h"
-#include "at_tok.h"
-
-extern struct ATResponse *sp_response;
-extern char *s_responsePrefix;
-extern enum ATCommandType s_type;
-
-#define AT_CREG_STAT_NOT_REG 0 /* not registered, MT is not currently searching a new operator to register to */
-#define AT_CREG_STAT_REG_HOME 1 /* registered, home network */
-#define AT_CREG_STAT_SEARCHING 2 /* not registered, but MT is currently searching a new operator to register to */
-#define AT_CREG_STAT_REG_DENIED 3 /* registration denied */
-#define AT_CREG_STAT_UNKNOWN 4 /* unknown */
-#define AT_CREG_STAT_REG_ROAM 5 /* registered, roaming */
-
-static unsigned int lookup_tbl_net_status[] = {
- [AT_CREG_STAT_NOT_REG] = NETWORK_SERVICE_DOMAIN_STATUS_NO,
- [AT_CREG_STAT_REG_HOME] = NETWORK_SERVICE_DOMAIN_STATUS_FULL,
- [AT_CREG_STAT_SEARCHING] = NETWORK_SERVICE_DOMAIN_STATUS_SEARCH,
- [AT_CREG_STAT_REG_DENIED] = NETWORK_SERVICE_DOMAIN_STATUS_EMERGENCY,
- [AT_CREG_STAT_UNKNOWN] = NETWORK_SERVICE_DOMAIN_STATUS_NO,
- [AT_CREG_STAT_REG_ROAM] = NETWORK_SERVICE_DOMAIN_STATUS_FULL,
-};
-
-#define AT_COPS_MODE_AUTOMATIC 0 /* automatic (<oper> field is ignored) */
-#define AT_COPS_MODE_MANUAL 1 /* manual (<oper> field shall be present, and <AcT> optionally) */
-#define AT_COPS_MODE_DEREGISTER 2 /* deregister from network */
-#define AT_COPS_MODE_SET_ONLY 3 /* set only <format> */
-
-#define AT_COPS_FORMAT_LONG_ALPHANUMERIC 0 /* long format alphanumeric <oper> */
-#define AT_COPS_FORMAT_SHORT_ALPHANUMERIC 1 /* short format alphanumeric <oper> */
-#define AT_COPS_FORMAT_NUMERIC 2 /* numeric <oper> */
-
-#define AT_COPS_ACT_GSM 0 /* GSM */
-#define AT_COPS_ACT_GSM_COMPACT 1 /* GSM Compact */
-#define AT_COPS_ACT_UTRAN 2 /* UTRAN */
-#define AT_COPS_ACT_GSM_EGPRS 3 /* GSM w/EGPRS */
-#define AT_COPS_ACT_UTRAN_HSDPA 4 /* UTRAN w/HSDPA */
-#define AT_COPS_ACT_UTRAN_HSUPA 5 /* UTRAN w/HSUPA */
-#define AT_COPS_ACT_UTRAN_HSDPA_HSUPA 6 /* UTRAN w/HSDPA and HSUPA */
-#define AT_COPS_ACT_E_UTRAN 7 /* E-UTRAN */
-
-static unsigned int lookup_tbl_access_technology[] = {
- [AT_COPS_ACT_GSM] = NETWORK_ACT_GSM,
- [AT_COPS_ACT_GSM_COMPACT] = NETWORK_ACT_GSM,
- [AT_COPS_ACT_UTRAN] = NETWORK_ACT_UTRAN,
- [AT_COPS_ACT_GSM_EGPRS] = NETWORK_ACT_EGPRS,
- [AT_COPS_ACT_UTRAN_HSDPA] = NETWORK_ACT_UTRAN,
- [AT_COPS_ACT_UTRAN_HSUPA] = NETWORK_ACT_UTRAN,
- [AT_COPS_ACT_UTRAN_HSDPA_HSUPA] = NETWORK_ACT_UTRAN,
- [AT_COPS_ACT_E_UTRAN] = NETWORK_ACT_GSM_UTRAN,
-};
-static unsigned int current_lac=0;
-static gboolean get_serving_network(CoreObject *o, UserRequest *ur);
-static void on_confirmation_network_message_send( TcorePending *pending, gboolean result, void *user_data );
-
-static void __set_metainfo(UserRequest *ur, struct ATReqMetaInfo *info, enum ATCommandType type, char *prefix)
-{
- if (!info || !ur)
- return;
- memset(info, 0, sizeof(struct ATReqMetaInfo));
- info->type = type;
- if (!prefix)
- info->responsePrefix[0] ='\0';
- else
- memcpy(info->responsePrefix, prefix, strlen(prefix));
- tcore_user_request_set_metainfo(ur, sizeof(struct ATReqMetaInfo), info);
-}
-static void __send_at_request(CoreObject *o, char* atcmd, UserRequest *ur, TcorePendingResponseCallback func)
-{
- TcorePlugin *plugin = NULL;
- TcoreHal *hal = NULL;
- TcorePending *pending = NULL;
-
- plugin = tcore_object_ref_plugin(o);
- hal = tcore_object_get_hal(o);
-
- pending = tcore_pending_new(o, ID_RESERVED_AT);
- tcore_pending_set_request_data(pending, strlen(atcmd), atcmd);
- tcore_pending_set_timeout(pending, 0);
- tcore_pending_set_priority(pending, TCORE_PENDING_PRIORITY_DEFAULT);
- tcore_pending_set_response_callback(pending, func, NULL);
- tcore_pending_link_user_request(pending, ur);
-
- tcore_pending_set_send_callback(pending, on_confirmation_network_message_send, NULL);
-
- tcore_hal_send_request(hal, pending);
-}
-
-static void _insert_mcc_mnc_oper_list(TcorePlugin *plugin, CoreObject *o)
-{
- Server *s;
- Storage *strg;
- void *handle;
- char query[255] = { 0, };
- GHashTableIter iter;
- gpointer key, value;
- GHashTable *result = NULL, *row = NULL;
- struct tcore_network_operator_info *noi = NULL;
- const char *path = NULL;
- int count = 0;
-
- s = tcore_plugin_ref_server(plugin);
- strg = tcore_server_find_storage(s, "database");
-
- path = tzplatform_mkpath(TZ_SYS_DB, ".mcc_mnc_oper_list.db");
-
- handle = tcore_storage_create_handle(strg, path);
- if (!handle) {
- dbg("fail to create database handle");
- return;
- }
-
- snprintf(query, 255, "select country, mcc, mnc, oper from mcc_mnc_oper_list");
-
- result = g_hash_table_new_full(g_str_hash, g_str_equal, NULL,
- (GDestroyNotify) g_hash_table_destroy);
-
- tcore_storage_read_query_database(strg, handle, query, NULL, result, 4);
-
- g_hash_table_iter_init(&iter, result);
- while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
- row = value;
-
- noi = calloc(sizeof(struct tcore_network_operator_info), 1);
-
- snprintf(noi->mcc, 4, "%s",(const gchar *)(g_hash_table_lookup(row, "1")));
- snprintf(noi->mnc, 4, "%s",(const gchar *)(g_hash_table_lookup(row, "2")));
- snprintf(noi->name, 41, "%s",(const gchar *)(g_hash_table_lookup(row, "3")));
- snprintf(noi->country, 4, "%s",(const gchar *)(g_hash_table_lookup(row, "0")));
-
- tcore_network_operator_info_add(o, noi);
-
- count++;
- }
-
- dbg("count = %d", count);
-
- g_hash_table_destroy(result);
-
- tcore_storage_remove_handle(strg, handle);
-}
-
-
-static gboolean _is_cdma(int act)
-{
- switch (act) {
- case NETWORK_ACT_IS95A:
- case NETWORK_ACT_IS95B:
- case NETWORK_ACT_CDMA_1X:
- case NETWORK_ACT_EVDO_REV0:
- case NETWORK_ACT_CDMA_1X_EVDO_REV0:
- case NETWORK_ACT_EVDO_REVA:
- case NETWORK_ACT_CDMA_1X_EVDO_REVA:
- case NETWORK_ACT_EVDV:
- return TRUE;
- break;
- }
-
- return FALSE;
-}
-
-static enum telephony_network_service_type _get_service_type(enum telephony_network_service_type prev_type,
- int domain, int act, int cs_status, int ps_status)
-{
- enum telephony_network_service_type ret;
-
- ret = prev_type;
-
- switch (act) {
- case NETWORK_ACT_NOT_SPECIFIED:
- ret = NETWORK_SERVICE_TYPE_UNKNOWN;
- break;
-
- case NETWORK_ACT_GSM:
- if (prev_type == NETWORK_SERVICE_TYPE_2_5G_EDGE && domain == NETWORK_SERVICE_DOMAIN_CS)
- ret = NETWORK_SERVICE_TYPE_2_5G_EDGE;
- else
- ret = NETWORK_SERVICE_TYPE_2G;
- break;
-
- case NETWORK_ACT_IS95A:
- case NETWORK_ACT_IS95B:
- ret = NETWORK_SERVICE_TYPE_2G;
- break;
-
- case NETWORK_ACT_CDMA_1X:
- case NETWORK_ACT_GPRS:
- ret = NETWORK_SERVICE_TYPE_2_5G;
- break;
-
- case NETWORK_ACT_EGPRS:
- return NETWORK_SERVICE_TYPE_2_5G_EDGE;
- break;
-
- case NETWORK_ACT_UMTS:
- ret = NETWORK_SERVICE_TYPE_3G;
- break;
-
- case NETWORK_ACT_EVDO_REV0:
- case NETWORK_ACT_CDMA_1X_EVDO_REV0:
- case NETWORK_ACT_EVDO_REVA:
- case NETWORK_ACT_CDMA_1X_EVDO_REVA:
- case NETWORK_ACT_EVDV:
- ret = NETWORK_SERVICE_TYPE_3G;
- break;
- }
-
- if (cs_status == NETWORK_SERVICE_DOMAIN_STATUS_NO && ps_status == NETWORK_SERVICE_DOMAIN_STATUS_NO) {
- ret = NETWORK_SERVICE_TYPE_NO_SERVICE;
- }
- else if (cs_status == NETWORK_SERVICE_DOMAIN_STATUS_SEARCH || ps_status == NETWORK_SERVICE_DOMAIN_STATUS_SEARCH) {
- if (cs_status == NETWORK_SERVICE_DOMAIN_STATUS_FULL || ps_status == NETWORK_SERVICE_DOMAIN_STATUS_FULL) {
- /* no change */
- }
- else {
- ret = NETWORK_SERVICE_TYPE_SEARCH;
- }
- }
- else if (cs_status == NETWORK_SERVICE_DOMAIN_STATUS_EMERGENCY || ps_status == NETWORK_SERVICE_DOMAIN_STATUS_EMERGENCY) {
- if (cs_status == NETWORK_SERVICE_DOMAIN_STATUS_FULL || ps_status == NETWORK_SERVICE_DOMAIN_STATUS_FULL) {
- /* no change */
- }
- else {
- ret = NETWORK_SERVICE_TYPE_EMERGENCY;
- }
- }
-
- return ret;
-}
-
-static void _ps_set(TcorePlugin *plugin, int status)
-{
- GSList *co_list = NULL;
-
- co_list = tcore_plugin_get_core_objects_bytype(plugin, CORE_OBJECT_TYPE_PS);
- do {
- CoreObject *o = NULL;
- o = (CoreObject *) co_list->data;
- if (!o)
- break;
-
- if (status == NETWORK_SERVICE_DOMAIN_STATUS_FULL) {
- tcore_ps_set_online(o, TRUE);
- }
- else {
- tcore_ps_set_online(o, FALSE);
- }
- } while ((co_list = g_slist_next(co_list)));
-
- g_slist_free(co_list);
-}
-
-static TReturn _network_general_response_result(void)
-{
- if (sp_response->success > 0) {
- ReleaseResponse();
- return TCORE_RETURN_SUCCESS;
- }
- else {
- int ret, error;
- char* line=NULL;
- line = sp_response->finalResponse;
- ret = at_tok_start(&line);
- if (ret < 0) {
- err("err cause not specified or string corrupted");
- ReleaseResponse();
- return TCORE_RETURN_3GPP_ERROR;
- }
- else {
- ret = at_tok_nextint(&line, &error);
- if (ret < 0) {
- err("err not specified or string not contail error");
- ReleaseResponse();
- return TCORE_RETURN_3GPP_ERROR;
-
- }
- else {
- ReleaseResponse();
- return convertCMEError((enum ATCMEError)error);
- }
- }
- }
-}
-
-static void on_confirmation_network_message_send( TcorePending *pending, gboolean result, void *user_data )
-{
- UserRequest* ur = NULL;
- struct ATReqMetaInfo* metainfo = NULL;
- unsigned int info_len =0;
- dbg("AT msg goes out from queue. Allocate ATRsp buffer and write rspPrefix\n");
-
- ReleaseResponse();
- sp_response = at_response_new();
-
- ur = tcore_pending_ref_user_request(pending);
- metainfo = (struct ATReqMetaInfo*)tcore_user_request_ref_metainfo(ur,&info_len);
-
- if ((metainfo->type == SINGLELINE) || (metainfo->type == MULTILINE)) {
- s_responsePrefix = strdup(metainfo->responsePrefix);
- dbg("duplicating responsePrefix : %s\n", s_responsePrefix);
- }
- else {
- s_responsePrefix = NULL;
- }
-
- s_type = metainfo->type;
-
- if (result == FALSE) {
- dbg("SEND FAIL");
- }
- else {
- dbg("SEND OK");
- }
-}
-
-static void on_response_set_plmn_selection_mode(TcorePending *pending, int data_len, const void *data, void *user_data)
-{
- UserRequest *ur;
- struct tresp_network_set_plmn_selection_mode resp;
-
- dbg("RESPONSE OK");
-
- resp.result = _network_general_response_result();
-
- ur = tcore_pending_ref_user_request(pending);
- if (ur) {
- tcore_user_request_send_response(ur, TRESP_NETWORK_SET_PLMN_SELECTION_MODE, sizeof(struct tresp_network_set_plmn_selection_mode), &resp);
- }
-}
-
-static void on_response_get_plmn_selection_mode(TcorePending *pending, int data_len, const void *data, void *user_data)
-{
- UserRequest *ur;
- struct tresp_network_get_plmn_selection_mode resp = {0};
- char* line=NULL;
- int mode=0;
- int ret;
-
- printResponse();
-
- if (sp_response->success > 0) {
- dbg("RESPONSE OK");
- line = sp_response->p_intermediates->line;
- ret = at_tok_start(&line);
- if (ret < 0)
- AT_TOK_ERROR(line);
-
- ret = at_tok_nextint(&line,&mode);
- if (ret < 0)
- AT_TOK_ERROR(line);
-
- dbg("mode = %d", mode);
- switch(mode) {
- case AT_COPS_MODE_AUTOMATIC:
- resp.mode = NETWORK_SELECT_MODE_AUTOMATIC;
- break;
- case AT_COPS_MODE_MANUAL:
- resp.mode = NETWORK_SELECT_MODE_MANUAL;
- break;
- }
- }
- else {
- err("RESPONSE NOK");
- }
- ReleaseResponse();
-
- dbg("resp.mode = %d", resp.mode);
- ur = tcore_pending_ref_user_request(pending);
- if (ur) {
- tcore_user_request_send_response(ur, TRESP_NETWORK_GET_PLMN_SELECTION_MODE, sizeof(struct tresp_network_get_plmn_selection_mode), &resp);
- }
-}
-
-static void on_response_search_network(TcorePending *pending, int data_len, const void *data, void *user_data)
-{
- UserRequest *ur;
- struct tresp_network_search resp;
- int i = 0, ret=0;
- char* line=NULL;
-
- memset(&resp, 0, sizeof(struct tresp_network_search));
-
- if (sp_response->success > 0) {
- dbg("RESPONSE OK");
- line = sp_response->p_intermediates->line;
- ret = at_tok_start(&line);
- if (ret < 0)
- AT_TOK_ERROR(line);
- while(at_tok_hasmore(&line))
- {
- /*
- * +COPS: [list of supported (<stat>,long alphanumeric <oper>,short alphanumeric <oper>,numeric <oper>[,<AcT>])s]
- * [,,(list of supported <mode>s),(list of supported <format>s)]
- */
- int stat=0, AcT=0;
- char* oper=NULL, *p;
- int commas = 0;
-
- dbg("line0 %s", line);
- at_tok_skip_bracket(&line);
- for (p = line ; *p != ')' ;p++) {
- if (*p == ',')
- commas++;
- }
-
- /* <stat>: integer type */
- ret = at_tok_nextint(&line,&stat);
- if (ret < 0)
- AT_TOK_ERROR(line);
-
- /* long alphanumeric <oper> */
- ret = at_tok_nextstr(&line,&oper);
- if (ret < 0)
- AT_TOK_ERROR(line);
-
- /* short alphanumeric <oper> */
- ret = at_tok_nextstr(&line,&oper);
- if (ret < 0)
- AT_TOK_ERROR(line);
-
- /* numeric <oper> */
- /* [NOTICE] struct "tresp_network_search" only supports numeric type */
- ret = at_tok_nextstr(&line,&oper);
- if (ret < 0)
- AT_TOK_ERROR(line);
-
- if (commas == 4) {
- /* [,<AcT>]: integer type; access technology selected */
- ret = at_tok_nextint(&line,&AcT);
- if (ret < 0)
- AT_TOK_ERROR(line);
- }
-
- dbg("mode = %d, oper=%s, AcT=%d", stat, oper?oper:"null", AcT);
- resp.list[i].status = stat;
- resp.list[i].act = lookup_tbl_access_technology[AcT];
- memcpy(resp.list[i].plmn, oper, 6);
- if (resp.list[i].plmn[5] == '#')
- resp.list[i].plmn[5] = '\0';
-
- dbg("resp.list[%d].act = 0x%x, resp.list[%d].plmn=%s", i, resp.list[i].act, i, resp.list[i].plmn);
- i++;
- }
- resp.list_count = i;
- dbg("resp.list_count=%d", resp.list_count);
- ur = tcore_pending_ref_user_request(pending);
- if (ur) {
- tcore_user_request_send_response(ur, TRESP_NETWORK_SEARCH, sizeof(struct tresp_network_search), &resp);
- }
-
- }
- else {
- err("RESPONSE NOK");
- }
- ReleaseResponse();
-}
-
-static void on_response_get_serving_network(TcorePending *pending, int data_len, const void *data, void *user_data)
-{
- UserRequest *ur;
- struct tresp_network_get_serving_network resp;
- CoreObject *o;
- char plmn[7];
- enum telephony_network_access_technology act = NETWORK_ACT_UNKNOWN;
- int ret;
-
- /* AT parsing variable */
- char* line=NULL;
- int mode=0, format=0, AcT=0;
- char* oper=NULL;
-
- if (sp_response->success > 0) {
- dbg("RESPONSE OK");
- line = sp_response->p_intermediates->line;
- ret = at_tok_start(&line);
- if (ret < 0)
- AT_TOK_ERROR(line);
-
- ret = at_tok_nextint(&line,&mode);
- if (ret < 0)
- AT_TOK_ERROR(line);
-
- ret = at_tok_nextint(&line,&format);
- if (ret < 0)
- AT_TOK_ERROR(line);
-
- ret = at_tok_nextstr(&line,&oper);
- if (ret < 0)
- AT_TOK_ERROR(line);
-
- ret = at_tok_nextint(&line,&AcT);
- if (ret < 0)
- AT_TOK_ERROR(line);
-
- dbg("mode = %d, format=%d, oper=%s, AcT=%d\n", mode, format, oper, AcT);
-
- memset(plmn, 0, 7);
- memcpy(plmn, oper, 6);
- if (plmn[5] == '#')
- plmn[5] = '\0';
-
- o = tcore_pending_ref_core_object(pending);
-
- tcore_network_set_plmn(o, plmn);
- tcore_network_get_access_technology(o, &act);
- dbg("prev_act = 0x%x, new_act = 0x%x", act,lookup_tbl_access_technology[AcT]);
- act = lookup_tbl_access_technology[AcT];
- tcore_network_set_access_technology(o, act);
-
- if (_is_cdma(act) == FALSE) {
- tcore_network_set_lac(o, current_lac);
- }
-
- memcpy(resp.plmn, plmn, 6);
- resp.act = act;
- resp.gsm.lac = current_lac;
- ur = tcore_pending_ref_user_request(pending);
- if (tcore_user_request_ref_communicator(ur)) {
- tcore_user_request_send_response(ur, TRESP_NETWORK_GET_SERVING_NETWORK, sizeof(struct tresp_network_get_serving_network), &resp);
- }
- else {
- struct tnoti_network_change network_change;
-
- memset(&network_change, 0, sizeof(struct tnoti_network_change));
- memcpy(network_change.plmn, plmn, 6);
-
- network_change.act = act;
- network_change.gsm.lac = current_lac;
-
- tcore_server_send_notification(tcore_plugin_ref_server(tcore_pending_ref_plugin(pending)), tcore_pending_ref_core_object(pending),
- TNOTI_NETWORK_CHANGE, sizeof(struct tnoti_network_change), &network_change);
- }
- }
- else {
- err("RESPONSE NOK");
- }
- ReleaseResponse();
- return;
-}
-
-static gboolean on_event_network_regist(CoreObject *o, const void *event_info, void *user_data)
-{
- struct tnoti_network_registration_status regist_status;
- enum telephony_network_service_domain_status cs_status;
- enum telephony_network_service_domain_status ps_status;
- enum telephony_network_service_type service_type;
- enum telephony_network_access_technology act = NETWORK_ACT_UNKNOWN;
-
- char *line = (char *)event_info;
- int ret;
- unsigned char svc_domain;
- int stat=0, AcT=0;
- unsigned int lac=0, ci=0, rac=0;
-
- dbg("NOTI RECEIVED");
-
- /* CS domain */
- if (strStartsWith(line,"+CREG:"))
- svc_domain = NETWORK_SERVICE_DOMAIN_CS;
- /* PS domain */
- else if (strStartsWith(line,"+CGREG:"))
- svc_domain = NETWORK_SERVICE_DOMAIN_PS;
- else
- return TRUE;
-
- dbg("svc_domain = 0x%x", svc_domain);
-
- ret = at_tok_start(&line);
- if (ret < 0)
- AT_NOTI_TOK_ERROR(line);
-
- ret = at_tok_nextint(&line, &stat);
- if (ret < 0)
- goto process;
-
- ret = at_tok_nexthexint(&line, (int *)&lac);
- if (ret < 0)
- goto process;
- else {
- dbg("Found lac=0x%x",lac);
- /* <stat> 1 : registered, home network */
- /* 5 : registered, roaming */
- if ( stat==1 || stat==5 )
- current_lac = lac;
- }
-
- ret = at_tok_nexthexint(&line, (int *)&ci);
- if (ret < 0)
- goto process;
- else
- dbg("Found ci=0x%x", ci);
-
- ret = at_tok_nextint(&line, (int *)&AcT);
- if (ret < 0)
- goto process;
-
- if (svc_domain == NETWORK_SERVICE_DOMAIN_PS) {
- ret = at_tok_nexthexint(&line, (int *)&rac);
- if (ret < 0)
- goto process;
- else
- dbg("Found rac=0x%x", rac);
- }
- /*
- * <lac>: string type; two byte location area code or tracking area code in hexadecimal format
- * <tac>: string type; two byte tracking area code in hexadecimal format (for +CEREG:)
- * <ci>: string type; four byte GERAN/UTRAN/E-UTRAN cell ID in hexadecimal format
- * <rac>: string type; one byte routing area code in hexadecimal format
- */
-
-process:
- dbg("stat=%d, lac=0x%lx, ci=0x%lx, Act=%d, rac=0x%lx", stat, lac, ci, AcT, rac);
-
- switch (svc_domain) {
- case NETWORK_SERVICE_DOMAIN_CS:
- cs_status = lookup_tbl_net_status[stat];
- tcore_network_set_service_status(o, TCORE_NETWORK_SERVICE_DOMAIN_TYPE_CIRCUIT, cs_status);
- break;
-
- case NETWORK_SERVICE_DOMAIN_PS:
- ps_status = lookup_tbl_net_status[stat];
- tcore_network_set_service_status(o, TCORE_NETWORK_SERVICE_DOMAIN_TYPE_PACKET, ps_status);
-
- _ps_set(tcore_object_ref_plugin(o), ps_status);
- break;
- }
-
- tcore_network_get_service_status(o, TCORE_NETWORK_SERVICE_DOMAIN_TYPE_CIRCUIT, &cs_status);
- tcore_network_get_service_status(o, TCORE_NETWORK_SERVICE_DOMAIN_TYPE_PACKET, &ps_status);
-
- act = lookup_tbl_access_technology[AcT];
- tcore_network_set_access_technology(o, act);
-
- if (stat == AT_CREG_STAT_REG_ROAM)
- tcore_network_set_roaming_state(o, TRUE);
- else
- tcore_network_set_roaming_state(o, FALSE);
-
- tcore_network_get_service_type(o, &service_type);
- dbg("prev_service_type = 0x%x", service_type);
- service_type = _get_service_type(service_type, svc_domain, act, cs_status, ps_status);
- dbg("new_service_type = 0x%x", service_type);
- tcore_network_set_service_type(o, service_type);
-
- tcore_network_set_lac(o, lac);
- tcore_network_set_rac(o, rac);
- tcore_network_set_cell_id(o, ci);
-
- if (_is_cdma(act) == FALSE) {
- struct tnoti_network_location_cellinfo net_lac_cell_info;
- net_lac_cell_info.lac = lac;
- net_lac_cell_info.cell_id = ci;
-
- tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_NETWORK_LOCATION_CELLINFO,
- sizeof(struct tnoti_network_location_cellinfo), &net_lac_cell_info);
- }
-
- regist_status.cs_domain_status = cs_status;
- regist_status.ps_domain_status = ps_status;
- regist_status.service_type = service_type;
- regist_status.roaming_status = tcore_network_get_roaming_state(o);
-
- tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o,
- TNOTI_NETWORK_REGISTRATION_STATUS, sizeof(struct tnoti_network_registration_status), ®ist_status);
-
- get_serving_network(o, NULL);
-
- return TRUE;
-}
-
-static gboolean on_event_network_icon_info(CoreObject *o, const void *event_info, void *user_data)
-{
- char *line = (char *)event_info;
- static struct tnoti_network_icon_info net_icon_info = {0xff,0,0,0};
- int ret;
- int descr=0, ind=0;
-
-#define CIND_NOTI_RSSI 10
-#define CIND_NOTI_BATTERY 15
-
- ret = at_tok_start(&line);
- if (ret < 0)
- AT_NOTI_TOK_ERROR(line);
-
- ret = at_tok_nextint(&line, &descr);
- if (ret < 0)
- AT_NOTI_TOK_ERROR(line);
-
- ret = at_tok_nextint(&line, &ind);
- if (ret < 0)
- AT_NOTI_TOK_ERROR(line);
-
- switch(descr) {
- case CIND_NOTI_RSSI:
- dbg("CIND_NOTI_RSSI. ind=%d",ind);
- net_icon_info.rssi = ind;
- break;
- case CIND_NOTI_BATTERY:
- dbg("CIND_NOTI_BATTERY. ind=%d",ind);
- net_icon_info.battery = ind;
- break;
-
- default:
- err("This event is not handled val=%d",descr);
- return TRUE;
- }
-
- dbg("type=%d, rssi=%d, battery=%d, hdr_rssi=%d",
- net_icon_info.type, net_icon_info.rssi, net_icon_info.battery, net_icon_info.hdr_rssi);
-
- tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_NETWORK_ICON_INFO,
- sizeof(struct tnoti_network_icon_info), &net_icon_info);
-
- return TRUE;
-}
-
-static void on_sim_resp_hook_get_netname(UserRequest *ur, enum tcore_response_command command, unsigned int data_len,
- const void *data, void *user_data)
-{
- const struct tresp_sim_read *resp = data;
- CoreObject *o = user_data;
- struct tnoti_network_registration_status regist_status;
-
- if (command == TRESP_SIM_GET_SPN) {
- dbg("OK SPN GETTING!!");
- dbg("resp->result = 0x%x", resp->result);
- dbg("resp->data.spn.display_condition = 0x%x", resp->data.spn.display_condition);
- dbg("resp->data.spn.spn = [%s]", resp->data.spn.spn);
-
- tcore_network_set_network_name(o, TCORE_NETWORK_NAME_TYPE_SPN, (const char *)resp->data.spn.spn);
-
- /**
- * display condition
- * bit[0]: 0 = display of registered PLMN name not required when registered PLMN is either HPLMN or a PLMN in the service provider PLMN list
- * 1 = display of registered PLMN name required when registered PLMN is either HPLMN or a PLMN in the service provider PLMN list
- * bit[1]: 0 = display of the service provider name is required when registered PLMN is neither HPLMN nor a PLMN in the service provider PLMN list
- * 1 = display of the service provider name is not required when registered PLMN is neither HPLMN nor a PLMN in the service provider PLMN list
- */
- if (resp->data.spn.display_condition & 0x01) {
- tcore_network_set_network_name_priority(o, TCORE_NETWORK_NAME_PRIORITY_NETWORK);
- }
- if ((resp->data.spn.display_condition & 0x02) == 0) {
- tcore_network_set_network_name_priority(o, TCORE_NETWORK_NAME_PRIORITY_SPN);
- }
- if ((resp->data.spn.display_condition & 0x03) == 0x01) {
- tcore_network_set_network_name_priority(o, TCORE_NETWORK_NAME_PRIORITY_ANY);
- }
- }
-
- tcore_network_get_service_status(o, TCORE_NETWORK_SERVICE_DOMAIN_TYPE_CIRCUIT, ®ist_status.cs_domain_status);
- tcore_network_get_service_status(o, TCORE_NETWORK_SERVICE_DOMAIN_TYPE_PACKET, ®ist_status.ps_domain_status);
- tcore_network_get_service_type(o, ®ist_status.service_type);
- regist_status.roaming_status = tcore_network_get_roaming_state(o);
-
- tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o,
- TNOTI_NETWORK_REGISTRATION_STATUS, sizeof(struct tnoti_network_registration_status), ®ist_status);
-}
-
-static enum tcore_hook_return on_hook_sim_init(Server *s, CoreObject *source, enum tcore_notification_command command,
- unsigned int data_len, void *data, void *user_data)
-{
- const struct tnoti_sim_status *sim = data;
- UserRequest *ur = NULL;
-
- if (sim->sim_status == SIM_STATUS_INIT_COMPLETED) {
- ur = tcore_user_request_new(NULL, NULL);
- tcore_user_request_set_command(ur, TREQ_SIM_GET_SPN);
- tcore_user_request_set_response_hook(ur, on_sim_resp_hook_get_netname, user_data);
- tcore_object_dispatch_request(source, ur);
- }
-
- return TCORE_HOOK_RETURN_CONTINUE;
-}
-
-static TReturn search_network(CoreObject *o, UserRequest *ur)
-{
- /* AT command variable*/
- struct ATReqMetaInfo metainfo;
- char* atcmd = NULL;
-
- if (!o || !ur)
- return TCORE_RETURN_EINVAL;
-
- __set_metainfo(ur, &metainfo, SINGLELINE,"+COPS:");
-
- atcmd = g_strdup("AT+COPS=?\r");
- dbg("cmd : %s, prefix(if any) : %s, cmd_len : %d",atcmd, "N/A", strlen(atcmd));
-
- __send_at_request(o, atcmd, ur, on_response_search_network);
- free(atcmd);
-
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn set_plmn_selection_mode(CoreObject *o, UserRequest *ur)
-{
- const struct treq_network_set_plmn_selection_mode *req_data;
-
- /* AT command variable*/
- struct ATReqMetaInfo metainfo;
- char* atcmd = NULL;
- char plmn[7];
-
- if (!o || !ur)
- return TCORE_RETURN_EINVAL;
-
- req_data = tcore_user_request_ref_data(ur, NULL);
- __set_metainfo(ur, &metainfo, NO_RESULT, NULL);
-
- if (req_data->mode != NETWORK_SELECT_MODE_MANUAL) {
- /* AT_COPS_MODE_AUTOMATIC 0*/
- atcmd = g_strdup("AT+COPS=0\r");
- }
- else {
- memset(plmn, 0, 7);
- memcpy(plmn, req_data->plmn, 6);
-
- if (strlen(req_data->plmn) == 5) {
- plmn[5] = '#';
- }
- /* AT_COPS_MODE_MANUAL 1*/
- /* AT_COPS_FORMAT_NUMERIC 2*/
- atcmd = g_strdup_printf("AT+COPS=0%s\r", plmn);
- }
- dbg("cmd : %s, prefix(if any) : %s, cmd_len : %d",atcmd, "N/A", strlen(atcmd));
-
- __send_at_request(o, atcmd, ur, on_response_set_plmn_selection_mode);
- free(atcmd);
-
- return TCORE_RETURN_SUCCESS;
-}
-
-
-static TReturn get_plmn_selection_mode(CoreObject *o, UserRequest *ur)
-{
- /* AT command variable*/
- struct ATReqMetaInfo metainfo;
- char* atcmd = NULL;
-
- if (!o || !ur)
- return TCORE_RETURN_EINVAL;
-
- __set_metainfo(ur, &metainfo, SINGLELINE,"+COPS:");
-
- atcmd = g_strdup("AT+COPS?\r");
- dbg("cmd : %s, prefix(if any) : %s, cmd_len : %d",atcmd, "N/A", strlen(atcmd));
-
- __send_at_request(o, atcmd, ur, on_response_get_plmn_selection_mode);
- free(atcmd);
-
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn set_service_domain(CoreObject *o, UserRequest *ur)
-{
- dbg("set_service_domain is not supported!");
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn get_service_domain(CoreObject *o, UserRequest *ur)
-{
- dbg("get_service_domain is not supported!");
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn set_band(CoreObject *o, UserRequest *ur)
-{
- dbg("set_band is not supported!");
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn get_band(CoreObject *o, UserRequest *ur)
-{
- dbg("get_band is not supported!");
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn set_preferred_plmn(CoreObject *o, UserRequest *ur)
-{
- dbg("set_preferred_plmn is not supported!");
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn get_preferred_plmn(CoreObject *o, UserRequest *ur)
-{
- dbg("get_preferred_plmn is not supported!");
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn set_order(CoreObject *o, UserRequest *ur)
-{
- dbg("set_order is not supported!");
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn get_order(CoreObject *o, UserRequest *ur)
-{
- dbg("get_order is not supported!");
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn set_power_on_attach(CoreObject *o, UserRequest *ur)
-{
- dbg("set_power_on_attach is not supported!");
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn get_power_on_attach(CoreObject *o, UserRequest *ur)
-{
- dbg("get_power_on_attach is not supported!");
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn set_cancel_manual_search(CoreObject *o, UserRequest *ur)
-{
- dbg("set_cancel_manual_search is not supported!");
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn get_serving_network(CoreObject *o, UserRequest *ur)
-{
- /* AT command variable*/
- struct ATReqMetaInfo metainfo;
- char* atcmd = NULL;
-
- if (!o)
- return TCORE_RETURN_EINVAL;
-
- if (!ur)
- ur = tcore_user_request_new(NULL, NULL);
-
- __set_metainfo(ur, &metainfo, SINGLELINE,"+COPS:");
-
- atcmd = g_strdup("AT+COPS?\r");
- dbg("cmd : %s, prefix(if any) : %s, cmd_len : %d",atcmd, "N/A", strlen(atcmd));
-
- __send_at_request(o, atcmd, ur, on_response_get_serving_network);
- free(atcmd);
- return TCORE_RETURN_SUCCESS;
-}
-
-
-
-static struct tcore_network_operations network_ops = {
- .search = search_network,
- .set_plmn_selection_mode = set_plmn_selection_mode,
- .get_plmn_selection_mode = get_plmn_selection_mode,
- .set_service_domain = set_service_domain,
- .get_service_domain = get_service_domain,
- .set_band = set_band,
- .get_band = get_band,
- .set_preferred_plmn = set_preferred_plmn,
- .get_preferred_plmn = get_preferred_plmn,
- .set_order = set_order,
- .get_order = get_order,
- .set_power_on_attach = set_power_on_attach,
- .get_power_on_attach = get_power_on_attach,
- .set_cancel_manual_search = set_cancel_manual_search,
- .get_serving_network = get_serving_network,
-};
-
-gboolean s_network_init(TcorePlugin *cp, CoreObject *co)
-{
- tcore_network_override_ops(co, &network_ops);
-
- tcore_object_override_callback(co, EVENT_NETWORK_REGISTRATION, on_event_network_regist, NULL);
- tcore_object_override_callback(co, EVENT_NETWORK_ICON_INFO, on_event_network_icon_info, NULL);
-
- tcore_server_add_notification_hook(tcore_plugin_ref_server(cp), TNOTI_SIM_STATUS, on_hook_sim_init, co);
-
- _insert_mcc_mnc_oper_list(cp, co);
-
- return TRUE;
-}
-
-void s_network_exit(TcorePlugin *cp, CoreObject *co)
-{
- dbg("Exit");
-}
+++ /dev/null
-/**
- * tel-plugin-atmodem
- *
- * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: Kyoungyoup Park <gynaru.park@samsung.com>
- * Hayoon Ko <hayoon.ko@samsung.com>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include <glib.h>
-#include <arpa/inet.h>
-
-#include <fcntl.h>
-
-#include <tcore.h>
-#include <hal.h>
-#include <core_object.h>
-#include <plugin.h>
-#include <queue.h>
-#include <co_ps.h>
-#include <co_context.h>
-#include <user_request.h>
-#include <server.h>
-#include <util.h>
-
-#include "s_common.h"
-#include "s_ps.h"
-
-#include "atchannel.h"
-#include "at_tok.h"
-
-extern struct ATResponse *sp_response;
-extern char *s_responsePrefix;
-extern enum ATCommandType s_type;
-
-static void on_confirmation_ps_message_send( TcorePending *p, gboolean result, void *user_data )
-{
- UserRequest* ur = NULL;
- struct ATReqMetaInfo* metainfo = NULL;
- unsigned int info_len =0;
- dbg("on_confirmation_ps_message_send - msg out from queue. alloc ATRsp buffer & write rspPrefix if needed\n");
-
- ReleaseResponse(); // release leftover
- //alloc new sp_response
- sp_response = at_response_new();
-
- ur = tcore_pending_ref_user_request(p);
- metainfo = (struct ATReqMetaInfo*)tcore_user_request_ref_metainfo(ur,&info_len);
-
- if ((metainfo->type == SINGLELINE)||(metainfo->type == MULTILINE)) {
- //cp rsp prefix
- s_responsePrefix = strdup(metainfo->responsePrefix);
- dbg("duplicating responsePrefix : %s\n", s_responsePrefix);
- }
- else {
- s_responsePrefix = NULL;
- }
-
- //set atcmd type into s_type
- s_type = metainfo->type;
-
- if (result == FALSE) {
- /* Fail */
- dbg("SEND FAIL");
- }
- else {
- dbg("SEND OK");
- }
-}
-
-static void on_setup_pdp(CoreObject *co_ps, int result,
- const char *netif_name, void *user_data)
-{
- CoreObject *ps_context = user_data;
- struct tnoti_ps_call_status data_status = {0};
- Server *server;
-
- dbg("Entry");
-
- if (result < 0) {
- /* Deactivate PDP context */
- tcore_ps_deactivate_context(co_ps, ps_context, NULL);
- return;
- }
-
- dbg("Device name: [%s]", netif_name);
-
- /* Set Device name */
- tcore_context_set_ipv4_devname(ps_context, netif_name);
-
- /* Set State - CONNECTED */
- data_status.context_id = tcore_context_get_id(ps_context);
- data_status.state = PS_DATA_CALL_CONNECTED;
- dbg("Sending Call Status Notification - Context ID: [%d] Context State: [CONNECTED]", data_status.context_id);
-
- /* Send Notification */
- server = tcore_plugin_ref_server(tcore_object_ref_plugin(co_ps));
- tcore_server_send_notification(server, co_ps,
- TNOTI_PS_CALL_STATUS,
- sizeof(struct tnoti_ps_call_status),
- &data_status);
-
- dbg("Exit");
-}
-
-static void on_event_ps_ipconfiguration(CoreObject *o, const void *event_info, void *user_data)
-{
- /* Parsing the response line and map into noti. */
- CoreObject *ps_context = (CoreObject *)user_data;
- unsigned int cid = tcore_context_get_id(ps_context);
- struct ATLine *p_cur = NULL;
- const struct ATResponse *p_response = event_info;
- int err, p_cid = 0, d_comp = -1, h_comp = -1;
- char *pdp_type = NULL, *apn = NULL;
- char *line = NULL, *ip = NULL;
- TcoreHal *h = tcore_object_get_hal(o);
-
- for (p_cur = p_response->p_intermediates; p_cur != NULL;
- p_cur = p_cur->p_next) {
- line = p_response->p_intermediates->line;
-
- err = at_tok_start(&line);
- err = at_tok_nextint(&line,&p_cid);
- dbg("cid: %d", p_cid);
-
- /* Send IP Configuration noti only on the requested CID. */
- if (p_cid && (cid == (unsigned int)p_cid)) {
- err = at_tok_nextstr(&line,&pdp_type);
- dbg("PDP type: %s", pdp_type);
-
- if (pdp_type != NULL) {
- err = at_tok_nextstr(&line,&apn);
- dbg("APN: %s", apn);
- }
- if (apn != NULL) {
- err = at_tok_nextstr(&line,&ip);
- dbg("IP address: %s", ip);
- }
- if (ip != NULL) {
- err = at_tok_nextint(&line,&d_comp);
- dbg("d_comp: %d", d_comp);
- }
- if (d_comp != -1) {
- err = at_tok_nextint(&line,&h_comp);
- dbg("h_comp: %d", h_comp);
- }
-
- (void)tcore_context_set_ipv4_addr(ps_context, (const char *)ip);
-
- dbg("ip = [%s]", ip);
-
- (void)tcore_context_set_ipv4_addr(ps_context, (const char *)ip);
-
- dbg("Adding default DNS pri: 8.8.8.8 sec: 8.8.4.4");
-
- tcore_context_set_ipv4_dns(ps_context, "8.8.8.8", "8.8.4.4");
-
- /* Mount network interface */
- if (tcore_hal_setup_netif(h, o, on_setup_pdp, ps_context, cid, TRUE)
- != TCORE_RETURN_SUCCESS) {
- err("Setup network interface failed");
- return;
- }
- } else {
- dbg("No matched response with CID: %d", cid);
- tcore_context_set_state(ps_context, CONTEXT_STATE_DEACTIVATED);
- }
- }
-}
-
-static void on_response_get_ipconfiguration(TcorePending *pending, int data_len, const void *data, void *user_data)
-{
- struct ATLine *p_cur;
- CoreObject *ps_context = (CoreObject *)user_data;
- char *line = NULL;
-
- printResponse();
-
- if (sp_response->success > 0) {
- dbg("RESPONSE OK");
-
- for (p_cur = sp_response->p_intermediates
- ; p_cur != NULL
- ; p_cur = p_cur->p_next) {
- line = sp_response->p_intermediates->line;
- dbg("%s\n", line);
- }
-
- dbg("Call on_ipc_event_ps_ipconfiguration");
- on_event_ps_ipconfiguration(tcore_pending_ref_core_object(pending), sp_response, ps_context);
- }
- else {
- dbg("RESPONSE NOK");
- tcore_context_set_state(ps_context, CONTEXT_STATE_DEACTIVATED);
- }
-
- ReleaseResponse();
-}
-
-static void on_response_ps_attached(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- TcorePlugin *pl = NULL;
- TcoreHal *h = NULL;
- TcorePending *pending = NULL;
- CoreObject *o = tcore_pending_ref_core_object(p);
- CoreObject *ps_context = (CoreObject *)user_data;
- UserRequest *ur;
-
- char* cmd_str = NULL;
- struct ATReqMetaInfo metainfo;
- int info_len =0;
- char* line = NULL;
-
- printResponse();
-
- if (sp_response->success > 0) {
- dbg("RESPONSE OK");
- line = sp_response->p_intermediates->line;
- dbg("on_response_ps_attached: %s", line);
-
- ur = tcore_user_request_new(NULL, NULL);
- memset(&metainfo, 0, sizeof(struct ATReqMetaInfo));
- memcpy(metainfo.responsePrefix,"+CGDCONT:",strlen("+CGDCONT:"));
- metainfo.type = MULTILINE;
- info_len = sizeof(struct ATReqMetaInfo);
-
- tcore_user_request_set_metainfo(ur, info_len, &metainfo);
-
- dbg(" Send: AT+CGDCONT?\r ");
- cmd_str = g_strdup("AT+CGDCONT?\r");
-
- pl = tcore_object_ref_plugin(o);
- h = tcore_object_get_hal(o);
- pending = tcore_pending_new(o, ID_RESERVED_AT);
- tcore_pending_set_request_data(pending, strlen(cmd_str), cmd_str);
- free(cmd_str);
-
- tcore_pending_set_timeout(pending, 0);
- tcore_pending_set_response_callback(pending, on_response_get_ipconfiguration, ps_context);
- tcore_pending_link_user_request(pending, ur);
- tcore_pending_set_priority(pending, TCORE_PENDING_PRIORITY_DEFAULT);
- tcore_pending_set_send_callback(pending, on_confirmation_ps_message_send, NULL);
- tcore_hal_send_request(h, pending);
- }
- else {
- dbg("RESPONSE NOK");
- tcore_context_set_state(ps_context, CONTEXT_STATE_DEACTIVATED);
- }
-
- ReleaseResponse();
-}
-
-static void on_response_active_set(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- TcorePlugin *pl = NULL;
- TcoreHal *h = NULL;
- TcorePending *pending = NULL;
- CoreObject *o = tcore_pending_ref_core_object(p);
- CoreObject *ps_context = (CoreObject *)user_data;
- UserRequest *ur;
-
- char* cmd_str = NULL;
- struct ATReqMetaInfo metainfo;
- int info_len =0;
-
- printResponse();
-
- if (sp_response->success > 0) {
- dbg("RESPONSE OK");
-
- ur = tcore_user_request_new(NULL, NULL);
- memset(&metainfo, 0, sizeof(struct ATReqMetaInfo));
- metainfo.type = SINGLELINE;
- info_len = sizeof(struct ATReqMetaInfo);
-
- tcore_user_request_set_metainfo(ur, info_len, &metainfo);
-
- dbg(" Send: ATD*99***1#\r ");
- cmd_str = g_strdup("ATD*99***1#\r");
-
- pl = tcore_object_ref_plugin(o);
- h = tcore_object_get_hal(o);
- pending = tcore_pending_new(o, ID_RESERVED_AT);
-
- tcore_pending_set_request_data(pending, strlen(cmd_str), cmd_str);
- free(cmd_str);
-
- tcore_pending_set_timeout(pending, 0);
- tcore_pending_set_response_callback(pending, on_response_ps_attached, ps_context);
- tcore_pending_link_user_request(pending, ur);
- tcore_pending_set_priority(pending, TCORE_PENDING_PRIORITY_DEFAULT);
- tcore_pending_set_send_callback(pending, on_confirmation_ps_message_send, NULL);
- tcore_hal_send_request(h, pending);
- }
- else {
- dbg("RESPONSE NOK");
- tcore_context_set_state(ps_context, CONTEXT_STATE_DEACTIVATED);
- }
-
- ReleaseResponse();
-}
-
-static void on_response_deactive_set(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- CoreObject *ps_context = user_data;
- CoreObject *co_ps = tcore_pending_ref_core_object(p);
- TcoreHal *h = tcore_object_get_hal(co_ps);
- unsigned int cid = tcore_context_get_id(ps_context);
-
- printResponse();
-
- if (sp_response->success > 0) {
- dbg("RESPONSE OK");
- if (tcore_hal_setup_netif(h, co_ps, NULL, ps_context, cid,
- FALSE) != TCORE_RETURN_SUCCESS)
- err("Failed to disable network interface");
-
- tcore_context_set_state(ps_context, CONTEXT_STATE_DEACTIVATED);
- }
- else {
- dbg("RESPONSE NOK");
- }
-
- ReleaseResponse();
-}
-
-static TReturn activate_ps_context(CoreObject *o, CoreObject *ps_context, void* user_data)
-{
- TcorePlugin *p = NULL;
- TcoreHal *h = NULL;
- TcorePending *pending = NULL;
- UserRequest *ur;
-
- unsigned int cid;
- char* cmd_str = NULL;
- struct ATReqMetaInfo metainfo;
- int info_len =0;
-
- if ( !o )
- return TCORE_RETURN_FAILURE;
-
- p = tcore_object_ref_plugin(o);
- h = tcore_object_get_hal(o);
-
-
- ur = tcore_user_request_new(NULL, NULL);
- memset(&metainfo, 0, sizeof(struct ATReqMetaInfo));
- metainfo.type = NO_RESULT;
- info_len = sizeof(struct ATReqMetaInfo);
-
- tcore_user_request_set_metainfo(ur, info_len, &metainfo);
-
- cid = tcore_context_get_id(ps_context);
-
- dbg("Example: AT+CGACT=1,0");
- cmd_str = g_strdup_printf("%s=%d,%d%s","AT+CGACT", 1, cid, "\r");
-
- pending = tcore_pending_new(o, ID_RESERVED_AT);
- tcore_pending_set_request_data(pending, strlen(cmd_str), cmd_str);
- free(cmd_str);
-
- tcore_pending_set_timeout(pending, 0);
- tcore_pending_set_response_callback(pending, on_response_active_set, ps_context);
- tcore_pending_link_user_request(pending, ur);
- tcore_pending_set_priority(pending, TCORE_PENDING_PRIORITY_DEFAULT);
- tcore_pending_set_send_callback(pending, on_confirmation_ps_message_send, NULL);
- tcore_hal_send_request(h, pending);
-
- return TRUE;
-}
-
-static void on_response_define_pdp(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- //CoreObject *ps_context = user_data;
-
- printResponse();
-
- if (sp_response->success > 0) {
- dbg("RESPONSE OK");
- //pdp_active_set(tcore_pending_ref_core_object(p), ps_context);
- }
- else {
- dbg("RESPONSE NOK");
- tcore_context_set_state(tcore_pending_ref_core_object(p), CONTEXT_STATE_DEACTIVATED);
- }
-
- ReleaseResponse();
-}
-
-static TReturn define_ps_context(CoreObject *o, CoreObject *ps_context, void *user_data)
-{
- TcorePlugin *p = NULL;
- TcoreHal *h = NULL;
- TcorePending *pending = NULL;
- UserRequest *ur;
-
- char *apn=NULL, *addr=NULL;
-
- unsigned int cid;
- enum co_context_type pdp_type;
- enum co_context_d_comp d_comp;
- enum co_context_h_comp h_comp;
- char *cmd_str = NULL;
- struct ATReqMetaInfo metainfo;
- int info_len =0;
-
- if ( !o )
- return TCORE_RETURN_FAILURE;
-
- p = tcore_object_ref_plugin(o);
- h = tcore_object_get_hal(o);
- ur = tcore_user_request_new(NULL, NULL);
- memset(&metainfo, 0, sizeof(struct ATReqMetaInfo));
- metainfo.type = NO_RESULT;
- info_len = sizeof(struct ATReqMetaInfo);
-
- tcore_user_request_set_metainfo(ur, info_len, &metainfo);
-
- cid = tcore_context_get_id(ps_context);
- pdp_type = tcore_context_get_type(ps_context);
- d_comp = tcore_context_get_data_compression(ps_context);
- h_comp = tcore_context_get_header_compression(ps_context);
-
- dbg("Example: AT+CGDCONT=1,\"IP\",\"www.example.co.kr\",,0,0");
- cmd_str = g_strdup_printf("AT+CGDCONT=%d,\"%d\",\"%s\",%s,%d,%d%s",
- cid, pdp_type, apn, addr, d_comp, h_comp, "\r");
-
- pending = tcore_pending_new(o, ID_RESERVED_AT);
- tcore_pending_set_request_data(pending, strlen(cmd_str), cmd_str);
- free(cmd_str);
-
- tcore_pending_set_timeout(pending, 0);
- tcore_pending_set_response_callback(pending, on_response_define_pdp, ps_context);
- tcore_pending_link_user_request(pending, ur);
- tcore_pending_set_priority(pending, TCORE_PENDING_PRIORITY_DEFAULT);
- tcore_pending_set_send_callback(pending, on_confirmation_ps_message_send, NULL);
- tcore_hal_send_request(h, pending);
-
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn deactivate_ps_context(CoreObject *o, CoreObject *ps_context, void *user_data)
-{
- TcorePlugin *p = NULL;
- TcoreHal *h = NULL;
- TcorePending *pending = NULL;
- UserRequest *ur;
-
- unsigned int cid;
- char* cmd_str = NULL;
- struct ATReqMetaInfo metainfo;
- int info_len =0;
-
- if ( !o )
- return TCORE_RETURN_FAILURE;
-
- p = tcore_object_ref_plugin(o);
- h = tcore_object_get_hal(o);
- ur = tcore_user_request_new(NULL, NULL);
-
- memset(&metainfo, 0, sizeof(struct ATReqMetaInfo));
- metainfo.type = NO_RESULT;
- info_len = sizeof(struct ATReqMetaInfo);
-
- cid = tcore_context_get_id(ps_context);
-
- dbg("Example: AT+CGACT=0,1");
- cmd_str = g_strdup_printf("%s=%d,%d%s","AT+CGACT", 0, cid, "\r");
-
- pending = tcore_pending_new(o, ID_RESERVED_AT);
- tcore_pending_set_request_data(pending, strlen(cmd_str), cmd_str);
- free(cmd_str);
-
- tcore_pending_set_timeout(pending, 0);
- tcore_pending_set_response_callback(pending, on_response_deactive_set, ps_context);
- tcore_pending_link_user_request(pending, ur);
- tcore_pending_set_priority(pending, TCORE_PENDING_PRIORITY_DEFAULT);
- tcore_pending_set_send_callback(pending, on_confirmation_ps_message_send, NULL);
- tcore_hal_send_request(h, pending);
-
- return TCORE_RETURN_SUCCESS;
-}
-
-static struct tcore_ps_operations ps_ops =
-{
- .define_context = define_ps_context,
- .activate_context = activate_ps_context,
- .deactivate_context = deactivate_ps_context
-};
-
-gboolean s_ps_init(TcorePlugin *cp, CoreObject *co)
-{
- GQueue *work_queue;
-
- dbg("Entry");
-
- tcore_ps_override_ops(co, &ps_ops);
-
- work_queue = g_queue_new();
- tcore_object_link_user_data(co, work_queue);
-
- dbg("Exit");
-
- return TRUE;
-}
-
-void s_ps_exit(TcorePlugin *cp, CoreObject *co)
-{
- GQueue *work_queue;
-
- work_queue = tcore_object_ref_user_data(co);
- if (work_queue)
- g_queue_free(work_queue);
-
- dbg("Exit");
-}
+++ /dev/null
-/*
- * tel-plugin-atmodem
- *
- * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: Hayoon Ko <hayoon.ko@samsung.com>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <glib.h>
-
-
-#include <tcore.h>
-#include <hal.h>
-#include <core_object.h>
-#include <plugin.h>
-#include <server.h>
-#include <queue.h>
-#include <co_sim.h>
-#include <storage.h>
-#include <user_request.h>
-
-#include "s_common.h"
-#include "s_sim.h"
-
-#include "atchannel.h"
-#include "at_tok.h"
-
-extern struct ATResponse *sp_response;
-extern char *s_responsePrefix;
-extern enum ATCommandType s_type;
-
-#define SWAPBYTES16(x) \
-{ \
- unsigned short int data = *(unsigned short int*)&(x); \
- data = ((data & 0xff00) >> 8) | \
- ((data & 0x00ff) << 8); \
- *(unsigned short int*)&(x) = data ; \
-}
-
-enum s_sim_file_type_e {
- SIM_FTYPE_DEDICATED = 0x00, /**< Dedicated */
- SIM_FTYPE_TRANSPARENT = 0x01, /**< Transparent -binary type*/
- SIM_FTYPE_LINEAR_FIXED = 0x02, /**< Linear fixed - record type*/
- SIM_FTYPE_CYCLIC = 0x04, /**< Cyclic - record type*/
- SIM_FTYPE_INVALID_TYPE = 0xFF /**< Invalid type */
-};
-
-enum s_sim_sec_op_e {
- SEC_PIN1_VERIFY,
- SEC_PIN2_VERIFY,
- SEC_PUK1_VERIFY,
- SEC_PUK2_VERIFY,
- SEC_SIM_VERIFY,
- SEC_ADM_VERIFY,
- SEC_PIN1_CHANGE,
- SEC_PIN2_CHANGE,
- SEC_PIN1_ENABLE,
- SEC_PIN1_DISABLE,
- SEC_PIN2_ENABLE,
- SEC_PIN2_DISABLE, //10
- SEC_SIM_ENABLE,
- SEC_SIM_DISABLE,
- SEC_NET_ENABLE,
- SEC_NET_DISABLE,
- SEC_NS_ENABLE,
- SEC_NS_DISABLE,
- SEC_SP_ENABLE,
- SEC_SP_DISABLE,
- SEC_CP_ENABLE,
- SEC_CP_DISABLE, //20
- SEC_FDN_ENABLE,
- SEC_FDN_DISABLE,
- SEC_PIN1_STATUS,
- SEC_PIN2_STATUS,
- SEC_FDN_STATUS,
- SEC_NET_STATUS,
- SEC_NS_STATUS,
- SEC_SP_STATUS,
- SEC_CP_STATUS,
- SEC_SIM_STATUS
-};
-
-struct s_sim_property {
- gboolean b_valid; /**< Valid or not */
- enum tel_sim_file_id file_id; /**< File identifier */
- enum s_sim_file_type_e file_type; /**< File type and structure */
- int rec_length; /**< Length of one record in file */
- int rec_count; /**< Number of records in file */
- int data_size; /**< File size */
- int current_index; /**< current index to read */
- enum tel_sim_status first_recv_status;
- enum s_sim_sec_op_e current_sec_op; /**< current index to read */
- struct tresp_sim_read files;
- struct ATReqMetaInfo metainfo;
-};
-
-enum s_sim_sec_locktype_e{
- SEC_LOCK_TYPE_NONE =0,
- SEC_LOCK_TYPE_READY, /* ME is not locked */
- SEC_LOCK_TYPE_PS, /* PH-SIM, Lock Phone to SIM/UICC card(MT asks password when other than current SIM/UICC card inserted; MT may remember certain amount of
- previously used cards thus not requiring password when they are inserted ) */
- SEC_LOCK_TYPE_PF, /* PH-FSIM, Lock Phone to the very First inserted SIM/UICC card ( MT asks password when other than the first SIM/UICC card is inserted ) */
- SEC_LOCK_TYPE_SC, /*Lock SIM/UICC card ( SIM asks password in ME power-up and when this command is issued ) */
- SEC_LOCK_TYPE_FD, /* SIM card or active application in the UICC(GSM or USIM) fixed dialing memory feature */
- SEC_LOCK_TYPE_PN, /* Network Personalization */
- SEC_LOCK_TYPE_PU, /* Network subset Personalization */
- SEC_LOCK_TYPE_PP, /* Service Provider Personalization */
- SEC_LOCK_TYPE_PC, /* Corporate Personalization */
- SEC_LOCK_TYPE_SC2, /* Lock PIN2 ( ... ) */
- SEC_LOCL_TYPE_PUK2, /* Lock PUK2 (... ) */
- SEC_LOCK_TYPE_ACL, /* ACL */
-
- SEC_LOCK_TYPE_NO_SIM, /* SIM is not inserted */
- SEC_LOCK_TYPE_UNAVAIL, /* SIM is inserted but can not communicate with SIM ( SIM interface error ) */
- SEC_SIM_INIT_COMPLETED, /* SIM Initialize Completed */
- SEC_PB_INIT_COMPLETED, /* Phonebook Initialize Completed*/
- SEC_SIM_INIT_CRASH, /* SIM Crash request from SMC lab*/
-
- SEC_LOCK_TYPE_MAX
-};
-
-enum s_sim_sec_lockkey_e{
- SEC_LOCK_KEY_NONE,
- SEC_LOCK_KEY_UNLOCKED, /* Not necessary */
- SEC_LOCK_KEY_PIN, /* PIN required as a password */
- SEC_LOCK_KEY_PUK, /* 0PUK required as a password */
- SEC_LOCK_KEY_PIN2, /* PIN2 required as a password */
- SEC_LOCK_KEY_PUK2, /* PUK2 required as a password */
- SEC_LOCK_KEY_PERM_BLOCKED, /* PIN Permanent Blocked */
- SEC_LOCK_KEY_PIN2_DISABLE, /* PIN2 Lock Disabled*/
- SEC_LOCK_KEY_MAX
-};
-
-
-
-static void _next_from_get_file_info(CoreObject *o, UserRequest *ur, enum tel_sim_file_id ef, enum tel_sim_access_result rt);
-static void _next_from_get_file_data(CoreObject *o, UserRequest *ur, enum tel_sim_access_result rt, int decode_ret);
-static gboolean _get_sim_type(CoreObject *o);
-static TReturn _get_file_info(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef);
-static gboolean _get_file_data(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef, const int offset, const int length);
-static gboolean _get_file_record(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef, const int index, const int length);
-static void _sim_status_update(CoreObject *o, enum tel_sim_status sim_status);
-
-static gboolean _convert_SCPIN_noti(char* line, enum s_sim_sec_locktype_e* lock_type, enum s_sim_sec_lockkey_e* lock_key);
-
-static gboolean _convert_SCPIN_noti(char* line, enum s_sim_sec_locktype_e* lock_type, enum s_sim_sec_lockkey_e* lock_key)
-{
- char *type =NULL, *key = NULL;
- int err;
- if(line == NULL)
- return FALSE;
-
- dbg("incoming string : %s\n", line);
-
- //rip off %SCPIN:
- at_tok_start(&line);
-
- // 1. find type string
- err = at_tok_nextstr(&line, &type);
- if(err<0){
- // no type string found.
- type = NULL;
- }
- if(type !=NULL){
- // 2. find key string
- err = at_tok_nextstr(&line, &key);
- }
- if(err<0){
- // no key found
- key = NULL;
- }
-
- dbg("type : %s, key : %s\n", type, key);
-
-// 3. convert string into enum
- if(type!=NULL)
- {
- if(strStartsWith (type, "NO_SIM"))
- *lock_type = SEC_LOCK_TYPE_NO_SIM;
- else if(strStartsWith (type, "UNAVAIL"))
- *lock_type = SEC_LOCK_TYPE_UNAVAIL;
- else if(strStartsWith (type, "NO_LOCK"))
- *lock_type = SEC_LOCK_TYPE_READY;
- else if(strStartsWith (type, "LOCK_PS"))
- *lock_type = SEC_LOCK_TYPE_PS;
- else if(strStartsWith (type, "LOCK_PF"))
- *lock_type = SEC_LOCK_TYPE_PF ;
- else if(strStartsWith (type, "LOCK_SC"))
- *lock_type = SEC_LOCK_TYPE_SC;
- else if(strStartsWith (type, "LOCK_FD"))
- *lock_type = SEC_LOCK_TYPE_FD;
- else if(strStartsWith (type, "LOCK_PN"))
- *lock_type = SEC_LOCK_TYPE_PN ;
- else if(strStartsWith (type, "LOCK_PU"))
- *lock_type = SEC_LOCK_TYPE_PU ;
- else if(strStartsWith (type, "LOCK_PP"))
- *lock_type = SEC_LOCK_TYPE_PP;
- else if(strStartsWith (type, "LOCK_PC"))
- *lock_type = SEC_LOCK_TYPE_PC;
- else if(strStartsWith (type, "LOCK_SC2"))
- *lock_type = SEC_LOCK_TYPE_SC2 ;
- else if(strStartsWith (type, "LOCK_ACL"))
- *lock_type = SEC_LOCK_TYPE_ACL;
- else if(strStartsWith (type, "LOCK_PUK2"))
- *lock_type = SEC_LOCL_TYPE_PUK2;
- else if(strStartsWith (type, "INIT_COMP"))
- *lock_type = SEC_SIM_INIT_COMPLETED;
- else if(strStartsWith (type, "INIT_ERROR"))
- *lock_type = SEC_SIM_INIT_CRASH;
- else
- *lock_type = SEC_LOCK_TYPE_NONE;
- }
- else
- type = SEC_LOCK_TYPE_NONE;
-
- if(key!=NULL)
- {
- if(strStartsWith (type, "PIN"))
- *lock_key = SEC_LOCK_KEY_PIN;
- else if(strStartsWith (type, "PUK"))
- *lock_key = SEC_LOCK_KEY_PUK;
- else if(strStartsWith (type, "PIN2"))
- *lock_key = SEC_LOCK_KEY_PIN2;
- else if(strStartsWith (type, "PUK2"))
- *lock_key = SEC_LOCK_KEY_PUK2;
- else if(strStartsWith (type, "BLOCKED"))
- *lock_key = SEC_LOCK_KEY_PERM_BLOCKED ;
- else if(strStartsWith (type, "UNLOCKED"))
- *lock_key = SEC_LOCK_KEY_UNLOCKED ;
- else if(strStartsWith (type, "PIN2_DISABLE"))
- *lock_key = SEC_LOCK_KEY_PIN2_DISABLE;
- else
- *lock_key = SEC_LOCK_KEY_NONE;
- }
- else
- *lock_key = SEC_LOCK_KEY_NONE;
-
-
- // 4. apply exceptional case.
- //if type is READY, key has no meanig
- if(*lock_type == SEC_LOCK_TYPE_READY)
- *lock_key = SEC_LOCK_KEY_UNLOCKED;
-
- // no sim, unvail, init_comp, init_error have no key info
- if((*lock_type == SEC_LOCK_TYPE_NO_SIM)||(*lock_type == SEC_LOCK_TYPE_UNAVAIL)||
- (*lock_type == SEC_SIM_INIT_COMPLETED)||(*lock_type == SEC_SIM_INIT_CRASH))
- *lock_key = SEC_LOCK_KEY_NONE;
-
- dbg("type : %d, key : %d\n", *lock_type, *lock_key);
-
- return TRUE;
-}
-
-static enum tcore_response_command _find_resp_command(UserRequest *ur)
-{
- enum tcore_request_command command;
- command = tcore_user_request_get_command(ur);
- switch(command){
- case TREQ_SIM_VERIFY_PINS:
- return TRESP_SIM_VERIFY_PINS;
- break;
- case TREQ_SIM_VERIFY_PUKS:
- return TRESP_SIM_VERIFY_PUKS;
- break;
- case TREQ_SIM_CHANGE_PINS:
- return TRESP_SIM_CHANGE_PINS;
- break;
- case TREQ_SIM_GET_FACILITY_STATUS:
- return TRESP_SIM_GET_FACILITY_STATUS;
- break;
- case TREQ_SIM_DISABLE_FACILITY:
- return TRESP_SIM_DISABLE_FACILITY;
- break;
- case TREQ_SIM_ENABLE_FACILITY:
- return TRESP_SIM_ENABLE_FACILITY;
- break;
- case TREQ_SIM_TRANSMIT_APDU:
- return TRESP_SIM_TRANSMIT_APDU;
- break;
- case TREQ_SIM_GET_ATR:
- return TRESP_SIM_GET_ATR;
- break;
- case TREQ_SIM_GET_ECC:
- return TRESP_SIM_GET_ECC;
- break;
- case TREQ_SIM_GET_LANGUAGE:
- return TRESP_SIM_GET_LANGUAGE;
- break;
- case TREQ_SIM_SET_LANGUAGE:
- return TRESP_SIM_SET_LANGUAGE;
- break;
- case TREQ_SIM_GET_ICCID:
- return TRESP_SIM_GET_ICCID;
- break;
- case TREQ_SIM_GET_MAILBOX:
- return TRESP_SIM_GET_MAILBOX;
- break;
- case TREQ_SIM_GET_CALLFORWARDING:
- return TRESP_SIM_GET_CALLFORWARDING;
- break;
- case TREQ_SIM_GET_MESSAGEWAITING:
- return TRESP_SIM_GET_MESSAGEWAITING;
- break;
- case TREQ_SIM_GET_CPHS_INFO:
- return TRESP_SIM_GET_CPHS_INFO;
- break;
- case TREQ_SIM_GET_MSISDN:
- return TRESP_SIM_GET_MSISDN;
- break;
- case TREQ_SIM_GET_SPN:
- return TRESP_SIM_GET_SPN;
- break;
- case TREQ_SIM_GET_SPDI:
- return TRESP_SIM_GET_SPDI;
- break;
- case TREQ_SIM_GET_OPL:
- return TRESP_SIM_GET_OPL;
- break;
- case TREQ_SIM_GET_PNN:
- return TRESP_SIM_GET_PNN;
- break;
- case TREQ_SIM_GET_CPHS_NETNAME:
- return TRESP_SIM_GET_CPHS_NETNAME;
- break;
- case TREQ_SIM_GET_OPLMNWACT:
- return TRESP_SIM_GET_OPLMNWACT;
- break;
- case TREQ_SIM_REQ_AUTHENTICATION:
- return TRESP_SIM_REQ_AUTHENTICATION;
- break;
- default:
- break;
- }
- return TRESP_UNKNOWN;
-}
-
-static int _sim_get_current_pin_facility(struct s_sim_property *sp)
-{
- int ret_type = 0;
- dbg("current sp->current_sec_op[%d]", sp->current_sec_op);
- switch(sp->current_sec_op){
- case SEC_PIN1_VERIFY :
- case SEC_PIN1_CHANGE :
- ret_type = SIM_PTYPE_PIN1;
- break;
- case SEC_PIN2_VERIFY :
- case SEC_PIN2_CHANGE :
- ret_type = SIM_PTYPE_PIN2;
- break;
- case SEC_PUK1_VERIFY :
- ret_type = SIM_PTYPE_PUK1;
- break;
- case SEC_PUK2_VERIFY :
- ret_type = SIM_PTYPE_PUK2;
- break;
- case SEC_SIM_VERIFY :
- ret_type = SIM_PTYPE_SIM;
- break;
- case SEC_ADM_VERIFY :
- ret_type = SIM_PTYPE_ADM;
- break;
-
- case SEC_PIN1_ENABLE :
- case SEC_PIN1_DISABLE :
- case SEC_PIN1_STATUS :
- ret_type = SIM_FACILITY_SC;
- break;
- case SEC_SIM_ENABLE :
- case SEC_SIM_DISABLE :
- case SEC_SIM_STATUS :
- ret_type = SIM_FACILITY_PS;
- break;
- case SEC_NET_ENABLE :
- case SEC_NET_DISABLE :
- case SEC_NET_STATUS :
- ret_type = SIM_FACILITY_PN;
- break;
- case SEC_NS_ENABLE :
- case SEC_NS_DISABLE :
- case SEC_NS_STATUS :
- ret_type = SIM_FACILITY_PU;
- break;
- case SEC_SP_ENABLE :
- case SEC_SP_DISABLE :
- case SEC_SP_STATUS :
- ret_type = SIM_FACILITY_PP;
- break;
- case SEC_CP_ENABLE :
- case SEC_CP_DISABLE :
- case SEC_CP_STATUS :
- ret_type = SIM_FACILITY_PC;
- break;
- case SEC_FDN_ENABLE :
- case SEC_FDN_DISABLE :
- case SEC_FDN_STATUS :
- ret_type = SIM_FACILITY_FD;
- break;
-
- default:
- dbg("not handled current op[%d]",sp->current_sec_op );
- break;
- }
- return ret_type;
-}
-
-static enum tel_sim_access_result _decode_status_word(unsigned short status_word1, unsigned short status_word2)
-{
- enum tel_sim_access_result rst = SIM_ACCESS_FAILED;
-
- if (status_word1 == 0x93 && status_word2 == 0x00) {
- rst = SIM_ACCESS_FAILED;
- /*Failed SIM request command*/
- dbg(" error - SIM application toolkit busy [%x][%x]", status_word1, status_word2);
- }
- else if (status_word1 == 0x94 && status_word2 == 0x00) {
- rst = SIM_ACCESS_FAILED;
- /*Failed SIM request command*/
- dbg(" error - No EF Selected [%x][%x]", status_word1, status_word2);
- }
- else if (status_word1 == 0x94 && status_word2 == 0x02) {
- rst = SIM_ACCESS_FAILED;
- /*Failed SIM request command*/
- dbg("error - Out of Range - Invalid address or record number[%x][%x]",
- status_word1, status_word2);
- }
- else if (status_word1 == 0x94 && status_word2 == 0x04) {
- rst = SIM_ACCESS_FILE_NOT_FOUND;
- /*Failed SIM request command*/
- dbg(" error - File ID not found [%x][%x]", status_word1, status_word2);
- }
- else if (status_word1 == 0x94 && status_word2 == 0x08) {
- rst = SIM_ACCESS_FAILED; /* MOdem not support */
- /*Failed SIM request command*/
- dbg(" error - File is inconsistent with command - Modem not support or USE IPC [%x][%x]",
- status_word1, status_word2);
- }
- else if (status_word1 == 0x98 && status_word2 == 0x02) {
- rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
- /*Failed SIM request command*/
- dbg(" error - CHV not initialized [%x][%x]", status_word1, status_word2);
- }
- else if (status_word1 == 0x98 && status_word2 == 0x04) {
- rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
- /*Failed SIM request command*/
- dbg(" error - Access condition not fullfilled [%x][%x]", status_word1, status_word2);
- dbg(" error -Unsuccessful CHV verification - at least one attempt left [%x][%x]",
- status_word1, status_word2);
- dbg(" error - Unsuccessful Unblock CHV - at least one attempt left [%x][%x]",
- status_word1, status_word2);
- dbg(" error - Authentication failure [%x][%x]", status_word1, status_word2);
- }
- else if (status_word1 == 0x98 && status_word2 == 0x08) {
- rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
- /*Failed SIM request command*/
- dbg(" error - Contradiction with CHV status [%x][%x]", status_word1, status_word2);
- }
- else if (status_word1 == 0x98 && status_word2 == 0x10) {
- rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
- /*Failed SIM request command*/
- dbg(" error - Contradiction with invalidation status [%x][%x]",
- status_word1, status_word2);
- }
- else if (status_word1 == 0x98 && status_word2 == 0x40) {
- rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
- /*Failed SIM request command*/
- dbg(" error -Unsuccessful CHV verification - no attempt left [%x][%x]",
- status_word1, status_word2);
- dbg(" error - Unsuccessful Unblock CHV - no attempt left [%x][%x]",
- status_word1, status_word2);
- dbg(" error - CHV blocked [%x][%x]", status_word1, status_word2);
- }
- else if (status_word1 == 0x67 && status_word2 == 0x00) {
- rst = SIM_ACCESS_FAILED;
- dbg(" error -Incorrect Parameter 3 [%x][%x]", status_word1, status_word2);
- }
- else if (status_word1 == 0x6B && status_word2 == 0x00) {
- rst = SIM_ACCESS_FAILED;
- dbg(" error -Incorrect Parameter 1 or 2 [%x][%x]", status_word1, status_word2);
- }
- else if (status_word1 == 0x6D && status_word2 == 0x00) {
- rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
- dbg(" error -Unknown instruction given as command [%x][%x]", status_word1, status_word2);
- }
- else if (status_word1 == 0x6E && status_word2 == 0x00) {
- rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
- dbg(" error -Unknown instruction given as command [%x][%x]", status_word1, status_word2);
- }
- else if (status_word1 == 0x69 && status_word2 == 0x82) {
- rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
- dbg(" error -Access denied [%x][%x]", status_word1, status_word2);
- }
- else if (status_word1 == 0x6A && status_word2 == 0x87) {
- rst = SIM_ACCESS_FAILED;
- dbg(" error -Incorrect parameters [%x][%x]", status_word1, status_word2);
- }
- else if (status_word1 == 0x6A && status_word2 == 0x82) {
- rst = SIM_ACCESS_FILE_NOT_FOUND; // not sure of the SW1 and SW2 meaning here
- dbg(" error -File Not found [%x][%x]", status_word1, status_word2);
- }
- else if (status_word1 == 0x6A && status_word2 == 0x83) {
- rst = SIM_ACCESS_FILE_NOT_FOUND; // not sure of the SW1 and SW2 meaning here
- dbg(" error -Record Not found [%x][%x]", status_word1, status_word2);
- }
- else {
- rst = SIM_ACCESS_CARD_ERROR;
- dbg(" error -Unknown state [%x][%x]", status_word1, status_word2);
- }
- return rst;
-}
-
-static gboolean _sim_check_identity(CoreObject *o, struct tel_sim_imsi *imsi)
-{
- Server *s = NULL;
- Storage *strg = NULL;
- char* old_imsi = NULL;
- char new_imsi[15+1] = {0,};
-
- s = tcore_plugin_ref_server(tcore_object_ref_plugin(o));
- if(!s){
- dbg("there is no valid server at this point");
- return FALSE;
- }
-
- strg = (Storage*)tcore_server_find_storage(s, "vconf");
- if(!strg){
- dbg("there is no valid storage plugin");
- return FALSE;
- }
-
- memcpy(&new_imsi, imsi->plmn, strlen(imsi->plmn));
- memcpy(&new_imsi[strlen(imsi->plmn)], imsi->msin, strlen(imsi->msin));
- new_imsi[strlen(imsi->plmn)+strlen(imsi->msin)] = '\0';
-
- old_imsi = tcore_storage_get_string(strg, STORAGE_KEY_TELEPHONY_IMSI);
- dbg("old_imsi[%s],newImsi[%s]", old_imsi, new_imsi);
-
- if (old_imsi != NULL) {
- if (strncmp(old_imsi, new_imsi, 15) != 0) {
- dbg("NEW SIM");
- if (tcore_storage_set_string(strg, STORAGE_KEY_TELEPHONY_IMSI, (const char*) &new_imsi) == FALSE )
- dbg("[FAIL] UPDATE STORAGE_KEY_TELEPHONY_IMSI");
- tcore_sim_set_identification(o, TRUE);
- }
- else {
- dbg("SAME SIM");
- tcore_sim_set_identification(o, FALSE);
- }
- }
- else {
- dbg("OLD SIM VALUE IS NULL. NEW SIM");
- if (tcore_storage_set_string(strg, STORAGE_KEY_TELEPHONY_IMSI, (const char*) &new_imsi) == FALSE)
- dbg("[FAIL] UPDATE STORAGE_KEY_TELEPHONY_IMSI");
- tcore_sim_set_identification(o, TRUE);
- }
- return 1;
-}
-
-static void _next_from_get_file_info(CoreObject *o, UserRequest *ur, enum tel_sim_file_id ef, enum tel_sim_access_result rt )
-{
- struct tresp_sim_read resp = {0,};
- struct s_sim_property *file_meta = NULL;
-
- dbg("EF[0x%x] access Result[%d]", ef, rt);
-
- resp.result = rt;
- memset(&resp.data, 0x00, sizeof(resp.data));
-
- if ((ef != SIM_EF_ELP || ef != SIM_EF_LP || ef != SIM_EF_USIM_PL)
- && (rt != SIM_ACCESS_SUCCESS)) {
- tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read),
- &resp);
- return;
- }
-
- file_meta = (struct s_sim_property*)tcore_user_request_ref_metainfo(ur, NULL);
-
- switch (ef) {
- case SIM_EF_ELP:
- if (rt == SIM_ACCESS_SUCCESS) {
- dbg("[SIM DATA] exist EFELP/PL(0x2F05)");
- /* if (po->language_file == 0x00)
- po->language_file = SIM_EF_ELP;*/
- _get_file_data(o, ur, ef, 0, file_meta->data_size);
- }
- else {
- if (tcore_sim_get_type(o) == SIM_TYPE_GSM) {
- dbg(" [SIM DATA]SIM_EF_ELP(2F05) access fail. Request SIM_EF_LP(0x6F05) info");
- /* The ME requests the Language Preference (EFLP) if EFELP is not available */
- _get_file_info(o, ur, SIM_EF_LP);
- }
- else if (tcore_sim_get_type(o) == SIM_TYPE_USIM) {
- dbg(
- " [SIM DATA]fail to get Language information in USIM(EF-LI(6F05),EF-PL(2F05)). Request SIM_EF_ECC(0x6FB7) info");
- /* EFELPand EFLI not present at this point. */
- /* po->language.lang_cnt = 0;*/
- tcore_user_request_send_response(ur, _find_resp_command(ur),
- sizeof(struct tresp_sim_read), &resp);
- return;
- }
- }
- break;
-
- case SIM_EF_LP: //same with SIM_EF_USIM_LI
- if (rt == SIM_ACCESS_SUCCESS) {
- dbg("[SIM DATA] exist EFLP/LI(0x6F05)");
- /* if (po->language_file == 0x00)
- po->language_file = SIM_EF_LP;*/
- _get_file_data(o, ur, ef, 0, file_meta->data_size);
- }
- else {
- dbg("[SIM DATA]SIM_EF_LP/LI(6F05) access fail. Current CardType[%d]",
- tcore_sim_get_type(o));
- if (tcore_sim_get_type(o) == SIM_TYPE_GSM) {
- /* EFELPand EFLP not present at this point.*/
- /* po->language.lang_cnt = 0;*/
- tcore_user_request_send_response(ur, _find_resp_command(ur),
- sizeof(struct tresp_sim_read), &resp);
- return;
- }
- /* if EFLI is not present, then the language selection shall be as defined in EFPL at the MF level */
- else if (tcore_sim_get_type(o) == SIM_TYPE_USIM) {
- dbg("[SIM DATA] try USIM EFPL(0x2F05)");
- _get_file_info(o, ur, SIM_EF_ELP);
- }
- }
- break;
-
- case SIM_EF_USIM_PL:
- if (rt == SIM_ACCESS_SUCCESS) {
- dbg("[SIM DATA] exist EFELP/PL(0x2F05)");
- /* if (po->language_file == 0x00)
- po->language_file = SIM_EF_ELP;*/
- _get_file_data(o, ur, SIM_EF_ELP, 0, file_meta->data_size);
- }
- else {
- /* EFELIand EFPL not present, so set language count as zero and select ECC */
- dbg(
- " [SIM DATA]SIM_EF_USIM_PL(2A05) access fail. Request SIM_EF_ECC(0x6FB7) info");
- /* po->language.lang_cnt = 0;*/
- tcore_user_request_send_response(ur, _find_resp_command(ur),
- sizeof(struct tresp_sim_read), &resp);
- return;
- }
- break;
-
- case SIM_EF_ECC:
- if (tcore_sim_get_type(o) == SIM_TYPE_GSM) {
- _get_file_data(o, ur, ef, 0, file_meta->data_size);
- }
- else if (tcore_sim_get_type(o) == SIM_TYPE_USIM) {
- if (file_meta->rec_count > SIM_ECC_RECORD_CNT_MAX)
- file_meta->rec_count = SIM_ECC_RECORD_CNT_MAX;
-
- file_meta->current_index++;
- _get_file_record(o, ur, ef, file_meta->current_index, file_meta->rec_length);
- }
- break;
-
- case SIM_EF_ICCID:
- case SIM_EF_IMSI:
- case SIM_EF_SPN:
- case SIM_EF_SPDI:
- case SIM_EF_CPHS_CPHS_INFO:
- case SIM_EF_CPHS_OPERATOR_NAME_STRING:
- case SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING:
- _get_file_data(o, ur, ef, 0, file_meta->data_size);
- break;
-
- case SIM_EF_OPL:
- case SIM_EF_PNN:
- file_meta->current_index++;
- _get_file_record(o, ur, ef, file_meta->current_index, file_meta->rec_length);
- break;
-
- case SIM_EF_SST:
- case SIM_EF_CPHS_CALL_FORWARD_FLAGS:
- case SIM_EF_CPHS_VOICE_MSG_WAITING:
- case SIM_EF_CPHS_DYNAMICFLAGS:
- case SIM_EF_CPHS_DYNAMIC2FLAG:
- case SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE:
- case SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE_LINE2:
- case SIM_EF_USIM_CFIS:
- case SIM_EF_USIM_MWIS:
- case SIM_EF_USIM_MBI:
- case SIM_EF_MBDN:
- case SIM_EF_CPHS_MAILBOX_NUMBERS:
- case SIM_EF_CPHS_INFORMATION_NUMBERS:
- default:
- dbg( "error - File id for get file info [0x%x]", ef);
- break;
- }
- return;
-}
-
-static void _next_from_get_file_data(CoreObject *o, UserRequest *ur, enum tel_sim_access_result rt, int decode_ret)
-{
- struct s_sim_property *file_meta = NULL;
- file_meta = (struct s_sim_property*)tcore_user_request_ref_metainfo(ur, NULL);
-
- dbg("[SIM]EF[0x%x] read rt[%d] Decode rt[%d]", file_meta->file_id, rt, decode_ret);
-
- switch (file_meta->file_id) {
- case SIM_EF_ELP:
- case SIM_EF_USIM_PL:
- case SIM_EF_LP:
- case SIM_EF_USIM_LI:
- if (decode_ret == TRUE) {
- if (file_meta->file_id == SIM_EF_LP || file_meta->file_id == SIM_EF_USIM_LI) {
-/* po->language_file = SIM_EF_LP;*/
- } else if (file_meta->file_id == SIM_EF_ELP || file_meta->file_id == SIM_EF_USIM_PL) {
-/* po->language_file = SIM_EF_ELP;*/
- }
- tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
- } else {
- /* 2G */
- /* The ME requests the Extended Language Preference. The ME only requests the Language Preference (EFLP) if at least one of the following conditions holds:
- - EFELP is not available;
- - EFELP does not contain an entry corresponding to a language specified in ISO 639[30];
- - the ME does not support any of the languages in EFELP.
- */
- /* 3G */
- /* The ME only requests the Language Preference (EFPL) if at least one of the following conditions holds:
- - if the EFLI has the value 'FFFF' in its highest priority position
- - if the ME does not support any of the language codes indicated in EFLI , or if EFLI is not present
- */
- if (tcore_sim_get_type(o) == SIM_TYPE_GSM) {
- if (file_meta->file_id == SIM_EF_LP)
- tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
- else
- _get_file_info(o, ur, SIM_EF_LP);
- } else if (tcore_sim_get_type(o) == SIM_TYPE_USIM) {
- if (file_meta->file_id == SIM_EF_LP || file_meta->file_id == SIM_EF_USIM_LI)
- _get_file_info(o, ur, SIM_EF_ELP);
- else
- tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
- }
- }
- break;
-
- case SIM_EF_ECC:
- if (tcore_sim_get_type(o) == SIM_TYPE_USIM) {
- file_meta->files.data.ecc.ecc_count++;
- if (file_meta->current_index == file_meta->rec_count) {
- tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
- } else {
- file_meta->current_index++;
- _get_file_record(o, ur, file_meta->file_id, file_meta->current_index, file_meta->rec_length );
- }
- } else if (tcore_sim_get_type(o) == SIM_TYPE_GSM) {
- tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
- } else {
- dbg("[SIM DATA]Invalid CardType[%d] Unable to handle", tcore_sim_get_type(o));
- }
- break;
-
- case SIM_EF_IMSI:
- _sim_status_update(o, SIM_STATUS_INIT_COMPLETED);
- break;
-
- case SIM_EF_OPL:
- file_meta->files.data.opl.opl_count++;
- dbg("file_meta->files.data.opl.opl_count[%d], current index[%d], rec_cnt[%d]",
- file_meta->files.data.opl.opl_count, file_meta->current_index,file_meta->rec_count);
- if (file_meta->current_index == file_meta->rec_count) {
- tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
- } else {
- file_meta->current_index++;
- _get_file_record(o, ur, file_meta->file_id, file_meta->current_index, file_meta->rec_length );
- }
- break;
- case SIM_EF_PNN:
- file_meta->files.data.pnn.pnn_count++;
- if (file_meta->current_index == file_meta->rec_count) {
- tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
- } else {
- file_meta->current_index++;
- _get_file_record(o, ur, file_meta->file_id, file_meta->current_index, file_meta->rec_length );
- }
- break;
-
- case SIM_EF_ICCID:
- case SIM_EF_SPN:
- case SIM_EF_SPDI:
- case SIM_EF_CPHS_CPHS_INFO:
- case SIM_EF_CPHS_OPERATOR_NAME_STRING:
- case SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING:
- tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
- break;
-
- case SIM_EF_SST:
- case SIM_EF_USIM_CFIS:
- case SIM_EF_USIM_MWIS:
- case SIM_EF_USIM_MBI:
- case SIM_EF_MBDN:
- case SIM_EF_CPHS_MAILBOX_NUMBERS:
- case SIM_EF_CPHS_INFORMATION_NUMBERS:
- case SIM_EF_CPHS_CALL_FORWARD_FLAGS:
- case SIM_EF_CPHS_VOICE_MSG_WAITING:
- case SIM_EF_CPHS_DYNAMICFLAGS:
- case SIM_EF_CPHS_DYNAMIC2FLAG:
- case SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE:
- case SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE_LINE2:
- default:
- dbg("File id not handled [0x%x]", file_meta->file_id);
- break;
- }
-}
-
-static void _sim_status_update(CoreObject *o, enum tel_sim_status sim_status)
-{
- struct tnoti_sim_status noti_data = {0,};
-
- dbg("tcore_sim_set_status and send noti w/ [%d]", sim_status);
- tcore_sim_set_status(o, sim_status);
- noti_data.sim_status = sim_status;
- tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_SIM_STATUS,
- sizeof(struct tnoti_sim_status), ¬i_data);
-}
-
-static void on_confirmation_sim_message_send( TcorePending *p, gboolean result, void *user_data )
-{
- UserRequest* ur = NULL;
- struct ATReqMetaInfo* metainfo = NULL;
- unsigned int info_len =0;
- struct s_sim_property *file_meta = NULL;
- dbg("on_confirmation_sim_message_send - msg out from queue. alloc ATRsp buffer & write rspPrefix if needed\n");
-
-//alloc new sp_response
- ReleaseResponse(); //release leftover
-//alloc new sp_response
-
- sp_response = at_response_new();
-
- ur = tcore_pending_ref_user_request(p);
-
- dbg("********************************tcore_user_request_get_command[0x%x]", tcore_user_request_get_command(ur));
-
- file_meta = (struct s_sim_property *)tcore_user_request_ref_metainfo(ur,&info_len);
- metainfo = &(file_meta->metainfo);
-
- dbg("file_meta->type[%d]", file_meta->metainfo.type);
- dbg("metainfo->type[%d]", metainfo->type);
-
- if((metainfo->type == SINGLELINE)||
- (metainfo->type == MULTILINE))
- {
- //cp rsp prefix
- s_responsePrefix = strdup(metainfo->responsePrefix);
- dbg("duplicating responsePrefix : %s\n", s_responsePrefix);
- }
- else
- {
- s_responsePrefix = NULL;
- }
-
- //set atcmd type into s_type
- s_type = metainfo->type;
-
- if (result == FALSE) {
- /* Fail */
- dbg("SEND FAIL");
- }
- else {
- dbg("SEND OK");
- }
-}
-
-static void _response_get_sim_type(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- struct s_sim_property *sp = NULL;
- CoreObject *co_sim = NULL;
- enum tel_sim_type sim_type = SIM_TYPE_UNKNOWN;
- char* line=NULL;
- int ret = 0;
-
- if(sp_response->success > 0)
- {
- line = sp_response->p_intermediates->line;
-
- ret = at_tok_start(&line);
- if (ret < 0)
- AT_TOK_ERROR(line);
-
- ret = at_tok_nextint(&line,(int *)&sim_type);
- if (ret < 0)
- AT_TOK_ERROR(line);
- }
- else
- {
- sim_type = SIM_TYPE_UNKNOWN;
- }
-
- dbg("resp sim type[%d]", sim_type);
-
- ReleaseResponse();
-
- co_sim = tcore_pending_ref_core_object(p);
- tcore_sim_set_type(co_sim, sim_type);
- sp = tcore_sim_ref_userdata(co_sim);
- _sim_status_update(co_sim, sp->first_recv_status);
-}
-
-static void _response_get_file_info(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- CoreObject *co_sim = NULL;
- UserRequest *ur = NULL;
- struct s_sim_property *file_meta = NULL;
- enum tel_sim_access_result rt;
-
- char *line = NULL;
- int ret = 0;
- int sw1 = 0;
- int sw2 = 0;
- //char *hexData;
- //char *recordData;
-
- co_sim = tcore_pending_ref_core_object(p);
- if(!co_sim){
- dbg("error - core object is null");
- return;
- }
- ur = tcore_pending_ref_user_request(p);
- file_meta = (struct s_sim_property*)tcore_user_request_ref_metainfo(ur, NULL);
-
- if(sp_response->success > 0)
- {
- line = sp_response->p_intermediates->line;
- ret = at_tok_start(&line);
- if (ret < 0)
- AT_TOK_ERROR(line);
-
- ret = at_tok_nextint(&line,&sw1);
- if (ret < 0)
- AT_TOK_ERROR(line);
- ret = at_tok_nextint(&line,&sw2);
- if (ret < 0)
- AT_TOK_ERROR(line);
-
- /*1. SIM access success case*/
- if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
- unsigned char tag_len = 0; /* 1 or 2 bytes ??? */
- unsigned short record_len = 0;
- char num_of_records = 0;
- unsigned char file_id_len = 0;
- unsigned short file_id = 0;
- unsigned short file_size = 0;
- unsigned short file_type = 0;
- unsigned short arr_file_id = 0;
- int arr_file_id_rec_num = 0;
-
- /* handling only last 3 bits */
- unsigned char file_type_tag = 0x07;
- unsigned char *ptr_data;
-
- char *hexData;
- char *recordData;
- ret = at_tok_nextstr(&line,&hexData);
- if (ret < 0)
- AT_TOK_ERROR(line);
-
- recordData = util_hexStringToBytes(hexData);
- util_hex_dump(" ", strlen(hexData)/2, recordData);
-
- ptr_data = (unsigned char *)recordData;
- if (tcore_sim_get_type(co_sim) == SIM_TYPE_USIM) {
- /*
- ETSI TS 102 221 v7.9.0
- - Response Data
- '62' FCP template tag
- - Response for an EF
- '82' M File Descriptor
- '83' M File Identifier
- 'A5' O Proprietary information
- '8A' M Life Cycle Status Integer
- '8B', '8C' or 'AB' C1 Security attributes
- '80' M File size
- '81' O Total file size
- '88' O Short File Identifier (SFI)
- */
-
- /* rsim.res_len has complete data length received */
-
- /* FCP template tag - File Control Parameters tag*/
- if (*ptr_data == 0x62) {
- /* parse complete FCP tag*/
- /* increment to next byte */
- ptr_data++;
- tag_len = *ptr_data++;
- /* FCP file descriptor - file type, accessibility, DF, ADF etc*/
- if (*ptr_data == 0x82) {
- /* increment to next byte */
- ptr_data++;
- /*2 or 5 value*/
- ptr_data++;
- /* unsigned char file_desc_len = *ptr_data++;*/
- /* dbg("file descriptor length: [%d]", file_desc_len);*/
- /* TBD: currently capture only file type : ignore sharable, non sharable, working, internal etc*/
- /* consider only last 3 bits*/
- file_type_tag = file_type_tag & (*ptr_data);
-
- switch (file_type_tag) {
- /* increment to next byte */
- ptr_data++;
- case 0x1:
- dbg("Getting FileType: [Transparent file type]");
- /* increment to next byte */
- ptr_data++;
- file_type = SIM_FTYPE_TRANSPARENT;
- /* data coding byte - value 21 */
- ptr_data++;
- break;
-
- case 0x2:
- dbg("Getting FileType: [Linear fixed file type]");
- /* increment to next byte */
- ptr_data++;
- /* data coding byte - value 21 */
- ptr_data++;
- /* 2bytes */
- memcpy(&record_len, ptr_data, 2);
- /* swap bytes */
- SWAPBYTES16(record_len);
- ptr_data = ptr_data + 2;
- num_of_records = *ptr_data++;
- /* Data lossy conversation from enum (int) to unsigned char */
- file_type = SIM_FTYPE_LINEAR_FIXED;
- break;
-
- case 0x6:
- dbg(" Cyclic fixed file type");
- /* increment to next byte */
- ptr_data++;
- /* data coding byte - value 21 */
- ptr_data++;
- /* 2bytes */
- memcpy(&record_len, ptr_data, 2);
- /* swap bytes */
- SWAPBYTES16(record_len);
- ptr_data = ptr_data + 2;
- num_of_records = *ptr_data++;
- file_type = SIM_FTYPE_CYCLIC;
- break;
-
- default:
- dbg("not handled file type [0x%x]", *ptr_data);
- break;
- }
- } else {
- dbg("INVALID FCP received - DEbug!");
- return;
- }
-
- /*File identifier - file id?? */ // 0x84,0x85,0x86 etc are currently ignored and not handled
- if (*ptr_data == 0x83) {
- /* increment to next byte */
- ptr_data++;
- file_id_len = *ptr_data++;
- memcpy(&file_id, ptr_data, file_id_len);
- /* swap bytes */
- SWAPBYTES16(file_id);
- ptr_data = ptr_data + 2;
- dbg("Getting FileID=[0x%x]", file_id);
- } else {
- dbg("INVALID FCP received - DEbug!");
- free(recordData);
- ReleaseResponse();
- return;
- }
-
- /* proprietary information */
- if (*ptr_data == 0xA5) {
- unsigned short prop_len;
- /* increment to next byte */
- ptr_data++;
- /* length */
- prop_len = *ptr_data;
- /* skip data */
- ptr_data = ptr_data + prop_len + 1;
- } else {
- dbg("INVALID FCP received - DEbug!");
- }
-
- /* life cycle status integer [8A][length:0x01][status]*/
- /*
- status info b8~b1
- 00000000 : No information given
- 00000001 : creation state
- 00000011 : initialization state
- 000001-1 : operation state -activated
- 000001-0 : operation state -deactivated
- 000011-- : Termination state
- b8~b5 !=0, b4~b1=X : Proprietary
- Any other value : RFU
- */
- if (*ptr_data == 0x8A) {
- /* increment to next byte */
- ptr_data++;
- /* length - value 1 */
- ptr_data++;
-
- switch (*ptr_data) {
- case 0x04:
- case 0x06:
- dbg("<IPC_RX> operation state -deactivated");
- ptr_data++;
- break;
- case 0x05:
- case 0x07:
- dbg("<IPC_RX> operation state -activated");
- ptr_data++;
- break;
- default:
- dbg("<IPC_RX> DEBUG! LIFE CYCLE STATUS =[0x%x]",*ptr_data);
- ptr_data++;
- break;
- }
- }
-
- /* related to security attributes : currently not handled*/
- if (*ptr_data == 0x86 || *ptr_data == 0x8B || *ptr_data == 0x8C || *ptr_data == 0xAB) {
- /* increment to next byte */
- ptr_data++;
- /* if tag length is 3 */
- if (*ptr_data == 0x03) {
- /* increment to next byte */
- ptr_data++;
- /* EFARR file id */
- memcpy(&arr_file_id, ptr_data, 2);
- /* swap byes */
- SWAPBYTES16(arr_file_id);
- ptr_data = ptr_data + 2;
- arr_file_id_rec_num = *ptr_data++;
- } else {
- /* if tag length is not 3 */
- /* ignoring bytes */
- // ptr_data = ptr_data + 4;
- dbg("Useless security attributes, so jump to next tag");
- ptr_data = ptr_data + (*ptr_data + 1);
- }
- } else {
- dbg("INVALID FCP received[0x%x] - DEbug!", *ptr_data);
- free(recordData);
- ReleaseResponse();
- return;
- }
-
- dbg("Current ptr_data value is [%x]", *ptr_data);
-
- /* file size excluding structural info*/
- if (*ptr_data == 0x80) {
- /* for EF file size is body of file and for Linear or cyclic it is
- * number of recXsizeof(one record)
- */
- /* increment to next byte */
- ptr_data++;
- /* length is 1 byte - value is 2 bytes or more */
- ptr_data++;
- memcpy(&file_size, ptr_data, 2);
- /* swap bytes */
- SWAPBYTES16(file_size);
- ptr_data = ptr_data + 2;
- } else {
- dbg("INVALID FCP received - DEbug!");
- free(recordData);
- ReleaseResponse();
- return;
- }
-
- /* total file size including structural info*/
- if (*ptr_data == 0x81) {
- int len;
- /* increment to next byte */
- ptr_data++;
- /* length */
- len = *ptr_data;
- /* ignored bytes */
- ptr_data = ptr_data + 3;
- } else {
- dbg("INVALID FCP received - DEbug!");
- /* 0x81 is optional tag?? check out! so do not return -1 from here! */
- /* return -1; */
- }
- /*short file identifier ignored*/
- if (*ptr_data == 0x88) {
- dbg("0x88: Do Nothing");
- /*DO NOTHING*/
- }
- } else {
- dbg("INVALID FCP received - DEbug!");
- free(recordData);
- ReleaseResponse();
- return;
- }
- } else if (tcore_sim_get_type(co_sim) == SIM_TYPE_GSM) {
- unsigned char gsm_specific_file_data_len = 0;
- /* ignore RFU byte1 and byte2 */
- ptr_data++;
- ptr_data++;
- /* file size */
- //file_size = p_info->response_len;
- memcpy(&file_size, ptr_data, 2);
- /* swap bytes */
- SWAPBYTES16(file_size);
- /* parsed file size */
- ptr_data = ptr_data + 2;
- /* file id */
- memcpy(&file_id, ptr_data, 2);
- SWAPBYTES16(file_id);
- dbg(" FILE id --> [%x]", file_id);
- ptr_data = ptr_data + 2;
- /* save file type - transparent, linear fixed or cyclic */
- file_type_tag = (*(ptr_data + 7));
-
- switch (*ptr_data) {
- case 0x0:
- /* RFU file type */
- dbg(" RFU file type- not handled - Debug!");
- break;
- case 0x1:
- /* MF file type */
- dbg(" MF file type - not handled - Debug!");
- break;
- case 0x2:
- /* DF file type */
- dbg(" DF file type - not handled - Debug!");
- break;
- case 0x4:
- /* EF file type */
- dbg(" EF file type [%d] ", file_type_tag);
- /* increment to next byte */
- ptr_data++;
-
- if (file_type_tag == 0x00 || file_type_tag == 0x01) {
- /* increament to next byte as this byte is RFU */
- ptr_data++;
- file_type =
- (file_type_tag == 0x00) ? SIM_FTYPE_TRANSPARENT : SIM_FTYPE_LINEAR_FIXED;
- } else {
- /* increment to next byte */
- ptr_data++;
- /* For a cyclic EF all bits except bit 7 are RFU; b7=1 indicates that */
- /* the INCREASE command is allowed on the selected cyclic file. */
- file_type = SIM_FTYPE_CYCLIC;
- }
- /* bytes 9 to 11 give SIM file access conditions */
- ptr_data++;
- /* byte 10 has one nibble that is RF U and another for INCREASE which is not used currently */
- ptr_data++;
- /* byte 11 is invalidate and rehabilate nibbles */
- ptr_data++;
- /* byte 12 - file status */
- ptr_data++;
- /* byte 13 - GSM specific data */
- gsm_specific_file_data_len = *ptr_data;
- ptr_data++;
- /* byte 14 - structure of EF - transparent or linear or cyclic , already saved above */
- ptr_data++;
- /* byte 15 - length of record for linear and cyclic , for transparent it is set to 0x00. */
- record_len = *ptr_data;
- dbg("record length[%d], file size[%d]", record_len, file_size);
-
- if (record_len != 0)
- num_of_records = (file_size / record_len);
-
- dbg("Number of records [%d]", num_of_records);
- break;
-
- default:
- dbg(" not handled file type");
- break;
- }
- }
- else
- {
- dbg(" Card Type - UNKNOWN [%d]", tcore_sim_get_type(co_sim));
- }
-
- dbg("req ef[0x%x] resp ef[0x%x] size[%ld] Type[0x%x] NumOfRecords[%ld] RecordLen[%ld]",
- file_meta->file_id, file_id, file_size, file_type, num_of_records, record_len);
-
- file_meta->file_type = file_type;
- file_meta->data_size = file_size;
- file_meta->rec_length = record_len;
- file_meta->rec_count = num_of_records;
- file_meta->current_index = 0; //reset for new record type EF
- rt = SIM_ACCESS_SUCCESS;
- free(recordData);
- }
- else
- {
- /*2. SIM access fail case*/
- dbg("error to get ef[0x%x]", file_meta->file_id);
- rt = _decode_status_word(sw1, sw2);
- }
-
- ReleaseResponse();
-
- ur = tcore_user_request_ref(ur);
- _next_from_get_file_info(co_sim, ur, file_meta->file_id, rt);
- }
- else
- {
- ReleaseResponse();
- dbg("error to get ef[0x%x]", file_meta->file_id);
- rt = SIM_ACCESS_FAILED;;
-
- ur = tcore_user_request_ref(ur);
- _next_from_get_file_info(co_sim, ur, file_meta->file_id, rt);
- }
-}
-
-static void _response_get_file_data(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- UserRequest *ur = NULL;
- CoreObject *co_sim = NULL;
- enum tel_sim_access_result rt;
- struct tel_sim_imsi imsi;
- struct s_sim_property *file_meta = NULL;
- gboolean dr = FALSE;
-
- char *line = NULL;
- int ret = 0;
- int sw1 = 0;
- int sw2 = 0;
-
- dbg("[SIM_READ_BINARY] or [SIM_READ_RECORD]");
-
- dbg("sizeof struct tresp_sim_read = [%d]", sizeof(struct tresp_sim_read));
-
- co_sim = tcore_pending_ref_core_object(p);
- if(!co_sim){
- dbg("error - core object is null");
- return;
- }
- ur = tcore_pending_ref_user_request(p);
- file_meta = (struct s_sim_property*)tcore_user_request_ref_metainfo(ur, NULL);
-
- if(sp_response->success > 0)
- {
- line = sp_response->p_intermediates->line;
-
- ret = at_tok_start(&line);
- if (ret < 0)
- AT_TOK_ERROR(line);
-
- ret = at_tok_nextint(&line,&sw1);
- if (ret < 0)
- AT_TOK_ERROR(line);
- ret = at_tok_nextint(&line,&sw2);
- if (ret < 0)
- AT_TOK_ERROR(line);
-
- if((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
- char *hexStr;
- char *fileData;
-
- ret = at_tok_nextstr(&line,&hexStr);
- if (ret < 0)
- AT_TOK_ERROR(line);
-
- fileData = util_hexStringToBytes(hexStr);
- util_hex_dump(" ", strlen(hexStr)/2, fileData);
-
- rt = SIM_ACCESS_SUCCESS;
- file_meta->files.result = rt;
-
- switch (file_meta->file_id)
- {
- case SIM_EF_IMSI:
- dr = tcore_sim_decode_imsi(&imsi, (unsigned char *)fileData, strlen(fileData));
- if (dr == FALSE) {
- dbg("imsi decoding failed");
- } else {
- _sim_check_identity(co_sim,&imsi);
- tcore_sim_set_imsi(co_sim,&imsi);
- }
- break;
-
- case SIM_EF_ICCID:
- dr = tcore_sim_decode_iccid(&file_meta->files.data.iccid, (unsigned char *)fileData, strlen(fileData));
- break;
-
- case SIM_EF_ELP:/* 2G EF - 2 bytes decoding*/
- case SIM_EF_USIM_LI: /* 3G EF - 2 bytes decoding*/
- case SIM_EF_USIM_PL:/* 3G EF - same as EFELP, so 2 byte decoding*/
- case SIM_EF_LP:/* 1 byte encoding*/
- if (tcore_sim_get_type(co_sim) == SIM_TYPE_GSM && file_meta->file_id == SIM_EF_LP) {
- /*2G LP(0x6F05) has 1 byte for each language*/
- dr = tcore_sim_decode_lp(&file_meta->files.data.language, (unsigned char *)fileData, strlen(fileData));
- } else {
- /*3G LI(0x6F05)/PL(0x2F05), 2G ELP(0x2F05) has 2 bytes for each language*/
- dr = tcore_sim_decode_li(file_meta->file_id, &file_meta->files.data.language, (unsigned char *)fileData, strlen(fileData));
- }
- break;
-
- case SIM_EF_SPN:
- dr = tcore_sim_decode_spn(&file_meta->files.data.spn, (unsigned char *)fileData, strlen(fileData));
- break;
-
- case SIM_EF_SPDI:
- dr = tcore_sim_decode_spdi(&file_meta->files.data.spdi, (unsigned char *)fileData, strlen(fileData));
- break;
-
- case SIM_EF_ECC:
- if(tcore_sim_get_type(co_sim) == SIM_TYPE_GSM) {
- dr = tcore_sim_decode_ecc(&file_meta->files.data.ecc, (unsigned char *)fileData, strlen(fileData));
- } else if(tcore_sim_get_type(co_sim) == SIM_TYPE_USIM){
- dr = tcore_sim_decode_uecc(&file_meta->files.data.ecc.ecc[file_meta->current_index-1], (unsigned char *)fileData, strlen(fileData));
- } else {
- dbg("err not handled tcore_sim_get_type(o)[%d] in here",tcore_sim_get_type(co_sim));
- }
- break;
-
- case SIM_EF_OPL:
- dr = tcore_sim_decode_opl(&file_meta->files.data.opl.opl[file_meta->current_index-1], (unsigned char *)fileData, strlen(fileData));
- break;
-
- case SIM_EF_PNN:
- dr = tcore_sim_decode_pnn(&file_meta->files.data.pnn.pnn[file_meta->current_index-1], (unsigned char *)fileData, strlen(fileData));
- break;
-
- case SIM_EF_OPLMN_ACT:
- dr = tcore_sim_decode_oplmnwact(&file_meta->files.data.opwa, (unsigned char *)fileData, strlen(fileData));
- break;
-
- case SIM_EF_CPHS_OPERATOR_NAME_STRING:
- dr = tcore_sim_decode_ons((unsigned char*)&file_meta->files.data.cphs_net.full_name, (unsigned char *)fileData, strlen(fileData));
- break;
-
- case SIM_EF_CPHS_CPHS_INFO:
- dr = tcore_sim_decode_cphs_info(&file_meta->files.data.cphs, (unsigned char *)fileData, strlen(fileData));
- break;
-
- case SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING:
- dr = tcore_sim_decode_short_ons((unsigned char*)&file_meta->files.data.cphs_net.short_name, (unsigned char *)fileData, strlen(fileData));
- break;
-
- case SIM_EF_CPHS_INFORMATION_NUMBERS:
- case SIM_EF_CPHS_CALL_FORWARD_FLAGS:
- case SIM_EF_USIM_MBI:
- case SIM_EF_MBDN:
- case SIM_EF_SST:
- case SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE:
- case SIM_EF_CPHS_VOICE_MSG_WAITING:
- case SIM_EF_CPHS_MAILBOX_NUMBERS:
- case SIM_EF_USIM_MWIS:
- case SIM_EF_USIM_CFIS:
- case SIM_EF_CPHS_SERVICE_STRING_TABLE:
- case SIM_EF_CPHS_DYNAMICFLAGS:
- case SIM_EF_CPHS_DYNAMIC2FLAG:
- default:
- dbg("File Decoding Failed - not handled File[0x%x]", file_meta->file_id);
- dr = 0;
- break;
- }
-
- free(fileData);
- }
- else
- {
- rt = _decode_status_word(sw1, sw2);
- file_meta->files.result = rt;
- }
-
- ReleaseResponse();
- }
- else
- {
- ReleaseResponse();
- rt = SIM_ACCESS_FAILED;;
- file_meta->files.result = rt;
- }
-
- ur = tcore_user_request_ref(ur);
- _next_from_get_file_data(tcore_pending_ref_core_object(p), ur, rt, dr);
-}
-
-static gboolean _get_sim_type(CoreObject *o)
-{
- TcorePlugin *p = NULL;
- TcoreHal *h = NULL;
- TcorePending *pending = NULL;
-
- char *cmd_str = NULL;
- struct s_sim_property file_meta={0,};
- TReturn trt = 0;
- UserRequest *ur = NULL;
-
- if (!o)
- return FALSE;
-
- p = tcore_object_ref_plugin(o);
- h = tcore_object_get_hal(o);
-
- file_meta.metainfo.type = SINGLELINE;
- memcpy(file_meta.metainfo.responsePrefix,"%SCCT:",strlen("%SCCT:"));
-
- ur = tcore_user_request_new(NULL, NULL);
-
- trt = tcore_user_request_set_metainfo(ur, sizeof(struct s_sim_property), &file_meta);
- dbg("trt[%d]",trt);
-
-
- // AT+CPIN=<pin>[,<newpin>]
- cmd_str = g_strdup("AT%SCCT\r");
-
- pending = tcore_pending_new(o, ID_RESERVED_AT);
- tcore_pending_set_request_data(pending, strlen(cmd_str), cmd_str);
- tcore_pending_set_timeout(pending, 0);
- tcore_pending_set_response_callback(pending, _response_get_sim_type, NULL);
- tcore_pending_link_user_request(pending, ur);
-
- tcore_pending_set_send_callback(pending, on_confirmation_sim_message_send, NULL);
-
- tcore_hal_send_request(h, pending);
-
- free(cmd_str);
-
- return TRUE;
-}
-
-static TReturn _get_file_info(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef)
-{
- TcorePlugin *p = NULL;
- TcoreHal *h = NULL;
- TcorePending *pending = NULL;
- //size_t size = 0;
- struct s_sim_property file_meta={0,};
- TReturn trt = 0;
-
- char *cmd_str = NULL;
-
- if (!o)
- return TCORE_RETURN_EINVAL;
-
- p = tcore_object_ref_plugin(o);
- h = tcore_object_get_hal(o);
-
- file_meta.file_id = ef;
- file_meta.metainfo.type = SINGLELINE;
- memcpy(file_meta.metainfo.responsePrefix,"+CRSM:",strlen("+CRSM:"));
-
- trt = tcore_user_request_set_metainfo(ur, sizeof(struct s_sim_property), &file_meta);
- dbg("trt[%d]",trt);
-
- // AT+CRSM=<command>,<fildid>,<p1>,<p2+C29,<p3>
- cmd_str = g_strdup_printf("AT+CRSM=192, %d%s", ef, "\r");
-
- dbg("new pending(IPC_SEC_RSIM_ACCESS GET - SELECT EF[0x%x])",ef);
- pending = tcore_pending_new(o, ID_RESERVED_AT);
- tcore_pending_set_request_data(pending, strlen(cmd_str), cmd_str);
- tcore_pending_set_timeout(pending, 0);
- tcore_pending_set_response_callback(pending, _response_get_file_info, NULL);
- tcore_pending_link_user_request(pending, ur);
-
- tcore_pending_set_send_callback(pending, on_confirmation_sim_message_send, NULL);
-
- tcore_hal_send_request(h, pending);
- free(cmd_str);
-
- return TCORE_RETURN_SUCCESS;
-}
-
-static gboolean _get_file_data(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef, const int offset, const int length)
-{
- TcorePlugin *p = NULL;
- TcoreHal *h = NULL;
- TcorePending *pending = NULL;
- //size_t size = 0;
-
- char *cmd_str = NULL;
- struct ATReqMetaInfo metainfo;
- int info_len =0;
- int p1;
- int p2;
- int p3;
-
- if (!o)
- return FALSE;
-
- dbg("new pending(IPC_SEC_RSIM_ACCESS GET - READ BIN)");
-
- p = tcore_object_ref_plugin(o);
- h = tcore_object_get_hal(o);
-
-// offset for reading the TRANSPARENT data
- p1 = (unsigned char)(offset & 0xFF00) >> 8;
- p2 = (unsigned char)offset & 0x00FF; //offset low
- p3 = (unsigned char)length;
- dbg("EF[0x%x]", ef);
-
- memset(&metainfo, 0, sizeof(struct ATReqMetaInfo));
- metainfo.type = SINGLELINE;
- memcpy(metainfo.responsePrefix,"+CRSM:",strlen("+CRSM:"));
- info_len = sizeof(struct ATReqMetaInfo);
-
- // AT+CRSM=<command>,<fildid>,<p1>,<p2+C29,<p3>
- cmd_str = g_strdup_printf("AT+CRSM=176, %d%s", ef, "\r");
-
- pending = tcore_pending_new(o, ID_RESERVED_AT);
- tcore_pending_set_request_data(pending, strlen(cmd_str), cmd_str);
- tcore_pending_set_timeout(pending, 0);
- tcore_pending_set_response_callback(pending, _response_get_file_data, NULL);
- tcore_pending_link_user_request(pending, ur);
-
- tcore_pending_set_send_callback(pending, on_confirmation_sim_message_send, NULL);
-
- tcore_hal_send_request(h, pending);
- free(cmd_str);
- return TRUE;
-}
-
-static gboolean _get_file_record(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef, const int index, const int length)
-{
- dbg("need to be implemented to use ATCMD");
-
- return TRUE;
-}
-
-static gboolean on_event_pin_status(CoreObject *o, const void *event_info, void *user_data)
-{
- UserRequest *ur;
- char *line = (char *) event_info;
- //struct tnoti_sim_status noti_data;
- struct s_sim_property *sp = NULL;
- enum tel_sim_status sim_status = SIM_STATUS_INITIALIZING;
- enum s_sim_sec_locktype_e locktype = SEC_LOCK_TYPE_NONE;
- enum s_sim_sec_lockkey_e lockkey = SEC_LOCK_KEY_NONE;
-
- dbg("PIN_STATUS NOTI : %s", line);
-
- _convert_SCPIN_noti(line,&locktype, &lockkey);
-
- sp = tcore_sim_ref_userdata(o);
-
-
- switch (locktype) {
- case SEC_LOCK_TYPE_READY:
- if (lockkey == SEC_LOCK_KEY_UNLOCKED) {
- sim_status = SIM_STATUS_INITIALIZING;
- dbg(" Inside PIN disabled at BOOT UP");
- }
- else {
- dbg(" not handled case p_status->lock_key[%d]", lockkey);
- }
- break;
-
- case SEC_LOCK_TYPE_PS:
- sim_status = SIM_STATUS_LOCK_REQUIRED;
- dbg( " SIM LOCK required");
- break;
-
- case SEC_LOCK_TYPE_PF:
- sim_status = SIM_STATUS_CARD_ERROR;
- dbg( "PF required ");
- break;
-
- case SEC_LOCK_TYPE_SC:
- switch (lockkey) {
- case SEC_LOCK_KEY_UNLOCKED:
- break;
- case SEC_LOCK_KEY_PIN:
- sim_status = SIM_STATUS_PIN_REQUIRED;
- dbg( " PIN1 required");
- break;
- case SEC_LOCK_KEY_PUK:
- sim_status = SIM_STATUS_PUK_REQUIRED;
- dbg( " PUK required");
- break;
- case SEC_LOCK_KEY_PERM_BLOCKED:
- sim_status = SIM_STATUS_CARD_BLOCKED;
- dbg( " Card permanently blocked");
- break;
- default:
- dbg(" SEC_SIM_LOCK_SC -not handled SEC Lock key ");
- break;
- }
- break;
-
- case SEC_LOCK_TYPE_FD:
- dbg(" SEC_LOCK_TYPE_FD -not handled Notification");
- break;
-
- case SEC_LOCK_TYPE_PN:
- switch (lockkey) {
- case SEC_LOCK_KEY_PIN:
- dbg(" ADMIN-NCK required");
- sim_status = SIM_STATUS_NCK_REQUIRED;
- break;
- default:
- dbg(" SIM_LOCK_PN/PU/PP/PC -not handled SEC Lock key =[%d]",
- lockkey);
- break;
- }
- break;
-
- case SEC_LOCK_TYPE_PU:
- dbg("Lock Personalization p_status->lock_key =[%d]", lockkey);
- switch (lockkey) {
- case SEC_LOCK_KEY_PIN:
- dbg(" ADMIN-NSCK required");
- sim_status = SIM_STATUS_NSCK_REQUIRED;
- break;
- default:
- dbg(" SIM_LOCK_PN/PU/PP/PC -not handled SEC Lock key =[%d]",
- lockkey);
- break;
- }
- break;
-
- case SEC_LOCK_TYPE_PP:
- switch (lockkey) {
- dbg("Lock Personalization p_status->lock_key =[%d]", lockkey);
- case SEC_LOCK_KEY_PIN:
- dbg(" ADMIN-SPCK required");
- sim_status = SIM_STATUS_SPCK_REQUIRED;
- break;
- default:
- dbg(" SIM_LOCK_PN/PU/PP/PC -not handled SEC Lock key =[%d]",
- lockkey);
- break;
- }
- break;
-
- case SEC_LOCK_TYPE_PC:
- switch (lockkey) {
- dbg("Lock Personalization p_status->lock_key =[%d]", lockkey);
- case SEC_LOCK_KEY_PIN:
- dbg(" ADMIN-CCK required");
- sim_status = SIM_STATUS_CCK_REQUIRED;
- break;
- default:
- dbg(" SIM_LOCK_PN/PU/PP/PC -not handled SEC Lock key =[%d]",
- lockkey);
- break;
- }
- break;
-
- case SEC_LOCK_TYPE_SC2:
- dbg("SEC_LOCK_TYPE_SC2: NOT Handled - Debug");
- break;
-
- case SEC_LOCL_TYPE_PUK2:
- dbg("SEC_LOCL_TYPE_PUK2: NOT Handled - Debug");
- break;
-
- case SEC_LOCK_TYPE_NO_SIM:
- sim_status = SIM_STATUS_CARD_NOT_PRESENT;
- dbg( "NO SIM");
- break;
-
- case SEC_LOCK_TYPE_UNAVAIL:
- case SEC_SIM_INIT_CRASH: //SMC Lab requirement
- sim_status = SIM_STATUS_CARD_ERROR;
- dbg( "SIM unavailable");
- break;
-
- case SEC_SIM_INIT_COMPLETED:
- dbg( "[SIM DATA] MODEM SIM INIT COMPLETED");
- sim_status = SIM_STATUS_INIT_COMPLETED;
- break;
-
- case SEC_PB_INIT_COMPLETED:
- dbg("[SIM DATA] MODEM SIM PB INIT COMPLETED. not handled here! s_phonebook should handle!");
- return TRUE;
- break;
-
- default:
- dbg(" not handled SEC lock type ");
- break;
- }
-
- dbg("[SIM]Current co->sim_status[%d] and from modem[0x%x]",tcore_sim_get_status(o), sim_status);
-
- switch (sim_status) {
- case SIM_STATUS_INIT_COMPLETED:
- ur = tcore_user_request_new(NULL, NULL); //this is for using ur metainfo set/ref functionality.
- _get_file_info(o, ur, SIM_EF_IMSI);
- break;
-
- case SIM_STATUS_INITIALIZING:
- case SIM_STATUS_PIN_REQUIRED:
- case SIM_STATUS_PUK_REQUIRED:
- case SIM_STATUS_CARD_BLOCKED:
- case SIM_STATUS_NCK_REQUIRED:
- case SIM_STATUS_NSCK_REQUIRED:
- case SIM_STATUS_SPCK_REQUIRED:
- case SIM_STATUS_CCK_REQUIRED:
- case SIM_STATUS_LOCK_REQUIRED:
- if( sp->first_recv_status == SIM_STATUS_UNKNOWN ) {
- dbg("first received sim status[%d]",sim_status);
- sp->first_recv_status = sim_status;
- _get_sim_type(o);
- }
- break;
-
- case SIM_STATUS_CARD_REMOVED:
- case SIM_STATUS_CARD_NOT_PRESENT:
- case SIM_STATUS_CARD_ERROR:
- if (sim_status == SIM_STATUS_CARD_NOT_PRESENT && tcore_sim_get_status(o) != SIM_STATUS_UNKNOWN) {
- dbg("[SIM]SIM CARD REMOVED!!");
- sim_status = SIM_STATUS_CARD_REMOVED;
- }
- _sim_status_update(o,sim_status);
- break;
-
- default:
- dbg("not handled status[%d]", sim_status);
- break;
- }
-
- return TRUE;
-}
-
-static void on_response_verify_pins(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- UserRequest *ur = NULL;
- CoreObject *co_sim = NULL;
- struct s_sim_property *sp = NULL;
- struct tresp_sim_verify_pins resp = {0,};
-
- char* line=NULL;
- int ret;
- int error;
-
- co_sim = tcore_pending_ref_core_object(p);
- sp = tcore_sim_ref_userdata(co_sim);
-
- ur = tcore_pending_ref_user_request(p);
- if(!ur)
- dbg("error - current ur is NULL");
-
- printResponse();
-
- if(sp_response->success > 0)
- {
- ReleaseResponse();
-
- resp.result = SIM_PIN_OPERATION_SUCCESS;
- resp.pin_type = _sim_get_current_pin_facility(sp);
- tcore_user_request_send_response(ur, TRESP_SIM_VERIFY_PINS, sizeof(struct tresp_sim_verify_pins), &resp);
- }
- else
- {
- //failure case - consider this later
- line = sp_response->finalResponse;
-
- ret = at_tok_start(&line);
- if (ret < 0)
- AT_TOK_ERROR(line);
-
- ret = at_tok_nextint(&line,&error);
- if (ret < 0)
- AT_TOK_ERROR(line);
-
- ReleaseResponse();
-
- // ur = user_request_dup(ur);
- // _get_retry_count(co_sim, ur);
-
- resp.result = SIM_INCORRECT_PASSWORD;
- resp.pin_type = _sim_get_current_pin_facility(sp);
- resp.retry_count = 3;
- tcore_user_request_send_response(ur, TRESP_SIM_VERIFY_PINS, sizeof(struct tresp_sim_verify_pins), &resp);
-
- }
-}
-
-static void on_response_verify_puks(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- UserRequest *ur = NULL;
- CoreObject *co_sim = NULL;
- struct s_sim_property *sp = NULL;
- struct tresp_sim_verify_puks resp = {0,};
-
- char* line=NULL;
- int ret;
- int error;
-
- co_sim = tcore_pending_ref_core_object(p);
- sp = tcore_sim_ref_userdata(co_sim);
-
- ur = tcore_pending_ref_user_request(p);
- if(!ur)
- dbg("error - current ur is NULL");
-
- printResponse();
-
- if(sp_response->success > 0)
- {
- ReleaseResponse();
-
- resp.result = SIM_PIN_OPERATION_SUCCESS;
- resp.pin_type = _sim_get_current_pin_facility(sp);
- tcore_user_request_send_response(ur, TRESP_SIM_VERIFY_PINS, sizeof(struct tresp_sim_verify_pins), &resp);
- }
- else
- {
- //failure case - consider this later
- line = sp_response->finalResponse;
-
- ret = at_tok_start(&line);
- if (ret < 0)
- AT_TOK_ERROR(line);
-
- ret = at_tok_nextint(&line,&error);
- if (ret < 0)
- AT_TOK_ERROR(line);
-
- ReleaseResponse();
-
- // ur = user_request_dup(ur);
- // _get_retry_count(co_sim, ur);
-
- resp.result = SIM_INCORRECT_PASSWORD;
- resp.pin_type = _sim_get_current_pin_facility(sp);
- tcore_user_request_send_response(ur, TRESP_SIM_VERIFY_PUKS, sizeof(struct tresp_sim_verify_puks), &resp);
-
- }
-}
-
-static void on_response_change_pins(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- UserRequest *ur = NULL;
- CoreObject *co_sim = NULL;
- struct s_sim_property *sp = NULL;
- struct tresp_sim_change_pins resp = {0,};
-
- char* line=NULL;
- int ret;
- int error;
-
- co_sim = tcore_pending_ref_core_object(p);
- sp = tcore_sim_ref_userdata(co_sim);
-
- ur = tcore_pending_ref_user_request(p);
- if(!ur)
- dbg("error - current ur is NULL");
-
- printResponse();
-
- if(sp_response->success > 0)
- {
- ReleaseResponse();
-
- resp.result = SIM_PIN_OPERATION_SUCCESS;
- resp.pin_type = _sim_get_current_pin_facility(sp);
- tcore_user_request_send_response(ur, TRESP_SIM_VERIFY_PINS, sizeof(struct tresp_sim_verify_pins), &resp);
- }
- else
- {
- //failure case - consider this later
- line = sp_response->finalResponse;
-
- ret = at_tok_start(&line);
- if (ret < 0)
- AT_TOK_ERROR(line);
-
- ret = at_tok_nextint(&line,&error);
- if (ret < 0)
- AT_TOK_ERROR(line);
-
- ReleaseResponse();
-
- // ur = user_request_dup(ur);
- // _get_retry_count(co_sim, ur);
-
- resp.result = SIM_INCORRECT_PASSWORD;
- resp.pin_type = _sim_get_current_pin_facility(sp);
- tcore_user_request_send_response(ur, TRESP_SIM_CHANGE_PINS, sizeof(struct tresp_sim_change_pins), &resp);
- }
-}
-
-static void on_response_get_facility_status(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- UserRequest *ur = NULL;
- CoreObject *co_sim = NULL;
- struct s_sim_property *sec_meta = NULL;
- struct tresp_sim_get_facility_status resp = {0,};
-
- char *line = NULL;
- int ret;
-
- co_sim = tcore_pending_ref_core_object(p);
- ur = tcore_pending_ref_user_request(p);
- sec_meta = (struct s_sim_property*)tcore_user_request_ref_metainfo(ur, NULL);
-
- resp.result = SIM_PIN_OPERATION_SUCCESS;
- resp.type = _sim_get_current_pin_facility(sec_meta);
-
- printResponse();
-
- if(sp_response->success > 0)
- {
- line = sp_response->p_intermediates->line;
-
- ret = at_tok_start(&line);
- if (ret < 0)
- AT_TOK_ERROR(line);
-
- ret = at_tok_nextint(&line,(int *)&resp.b_enable);
- if (ret < 0)
- AT_TOK_ERROR(line);
- }
- else
- {
- resp.result = SIM_INCOMPATIBLE_PIN_OPERATION;
- }
-
- ReleaseResponse();
-
- if (ur) {
- tcore_user_request_send_response(ur, TRESP_SIM_GET_FACILITY_STATUS,
- sizeof(struct tresp_sim_get_facility_status), &resp);
- }
-}
-
-static void on_response_enable_facility(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- UserRequest *ur = NULL;
- CoreObject *co_sim = NULL;
- struct s_sim_property *sec_meta = NULL;
- struct tresp_sim_enable_facility resp = {0,};
- struct s_sim_property *sp = NULL;
-
- char *line = NULL;
- int ret;
-
- co_sim = tcore_pending_ref_core_object(p);
- ur = tcore_pending_ref_user_request(p);
- sp = tcore_sim_ref_userdata(co_sim);
- sec_meta = (struct s_sim_property*)tcore_user_request_ref_metainfo(ur, NULL);
-
- resp.result = SIM_PIN_OPERATION_SUCCESS;
- resp.type = _sim_get_current_pin_facility(sec_meta);
-
- printResponse();
-
- if(sp_response->success > 0)
- {
- line = sp_response->p_intermediates->line;
-
- ret = at_tok_start(&line);
- if (ret < 0)
- AT_TOK_ERROR(line);
-
- ret = at_tok_nextint(&line,(int *)&resp.result);
- if (ret < 0)
- AT_TOK_ERROR(line);
- }
- else
- {
- resp.result = SIM_INCOMPATIBLE_PIN_OPERATION;
- }
-
- ReleaseResponse();
-
- if (ur) {
- resp.type = _sim_get_current_pin_facility(sp);
- tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_enable_facility), &resp);
- }
-}
-
-static void on_response_disable_facility(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- UserRequest *ur = NULL;
- CoreObject *co_sim = NULL;
- struct s_sim_property *sec_meta = NULL;
- struct tresp_sim_disable_facility resp = {0,};
- struct s_sim_property *sp = NULL;
-
- char *line = NULL;
- int ret;
-
- co_sim = tcore_pending_ref_core_object(p);
- ur = tcore_pending_ref_user_request(p);
- sp = tcore_sim_ref_userdata(co_sim);
- sec_meta = (struct s_sim_property*)tcore_user_request_ref_metainfo(ur, NULL);
-
- resp.result = SIM_PIN_OPERATION_SUCCESS;
- resp.type = _sim_get_current_pin_facility(sec_meta);
-
- printResponse();
-
- if(sp_response->success > 0)
- {
- line = sp_response->p_intermediates->line;
-
- ret = at_tok_start(&line);
- if (ret < 0)
- AT_TOK_ERROR(line);
-
- ret = at_tok_nextint(&line,(int *)&resp.result);
- if (ret < 0)
- AT_TOK_ERROR(line);
- }
- else
- {
- resp.result = SIM_INCOMPATIBLE_PIN_OPERATION;
- }
-
- ReleaseResponse();
-
- if (ur) {
- resp.type = _sim_get_current_pin_facility(sp);
- tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_disable_facility), &resp);
- }
-}
-
-static TReturn s_verify_pins(CoreObject *o, UserRequest *ur)
-{
- TcorePlugin *p = NULL;
- TcoreHal *h = NULL;
- TcorePending *pending = NULL;
-
- struct s_sim_property *sp = NULL;
- const struct treq_sim_verify_pins *req_data;
- TReturn trt = 0;
-
- char *cmd_str = NULL;
-
- if (!o || !ur)
- return TCORE_RETURN_EINVAL;
-
- p = tcore_object_ref_plugin(o);
- h = tcore_object_get_hal(o);
- req_data = tcore_user_request_ref_data(ur, NULL);
- sp = tcore_sim_ref_userdata(o);
-
- if (req_data->pin_type == SIM_PTYPE_PIN1) {
- sp->current_sec_op = SEC_PIN1_VERIFY;
- }
- else if (req_data->pin_type == SIM_PTYPE_PIN2) {
- sp->current_sec_op = SEC_PIN2_VERIFY;
- }
- else if (req_data->pin_type == SIM_PTYPE_SIM) {
- sp->current_sec_op = SEC_SIM_VERIFY;
- }
- else if (req_data->pin_type == SIM_PTYPE_ADM) {
- sp->current_sec_op = SEC_ADM_VERIFY;
- }
- else {
- return TCORE_RETURN_EINVAL;
- }
-
- sp->metainfo.type = NO_RESULT;
- sp->metainfo.responsePrefix[0] = '\0';
-
- trt = tcore_user_request_set_metainfo(ur, sizeof(struct s_sim_property), sp);
- dbg("trt[%d]",trt);
-
-
- // AT+CPIN=<pin>[,<newpin>]
- cmd_str = g_strdup_printf("AT+CPIN=\"%s\"%s", req_data->pin, "\r");
- dbg("new pending(verify - pins), %s", cmd_str);
-
- pending = tcore_pending_new(o,ID_RESERVED_AT);
- tcore_pending_set_request_data(pending, strlen(cmd_str), cmd_str);
- tcore_pending_set_timeout(pending, 0);
- tcore_pending_set_priority(pending, TCORE_PENDING_PRIORITY_DEFAULT);
- tcore_pending_set_response_callback(pending, on_response_verify_pins, NULL);
- tcore_pending_link_user_request(pending, ur);
-
- tcore_pending_set_send_callback(pending, on_confirmation_sim_message_send, NULL);
-
- tcore_hal_send_request(h, pending);
-
- free(cmd_str);
-
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn s_verify_puks(CoreObject *o, UserRequest *ur)
-{
- TcorePlugin *p = NULL;
- TcoreHal *h = NULL;
- TcorePending *pending = NULL;
-
- const struct treq_sim_verify_puks *req_data;
- struct s_sim_property *sp = NULL;
- TReturn trt = 0;
-
- char *cmd_str = NULL;
-
- if (!o || !ur)
- return TCORE_RETURN_EINVAL;
-
- p = tcore_object_ref_plugin(o);
- h = tcore_object_get_hal(o);
- req_data = tcore_user_request_ref_data(ur, NULL);
- sp = tcore_sim_ref_userdata(o);
-
-
- if(req_data->puk_type == SIM_PTYPE_PUK1){
- sp->current_sec_op = SEC_PUK1_VERIFY;
- }
- else if(req_data->puk_type == SIM_PTYPE_PUK2){
- sp->current_sec_op = SEC_PUK2_VERIFY;
- }
- else {
- return TCORE_RETURN_EINVAL;
- }
-
- sp->metainfo.type = NO_RESULT;
- sp->metainfo.responsePrefix[0] = '\0';
-
- trt = tcore_user_request_set_metainfo(ur, sizeof(struct s_sim_property), sp);
- dbg("trt[%d]",trt);
-
- // AT+CPIN=<pin>[,<newpin>]
- cmd_str = g_strdup_printf("AT+CPIN=\"%s\", \"%s\"%s", req_data->puk, req_data->pin, "\r");
-
- dbg("new pending(IPC_SEC_PIN_STATUS SET - verify puks)");
- pending = tcore_pending_new(o, ID_RESERVED_AT);
- tcore_pending_set_request_data(pending, strlen(cmd_str), cmd_str);
- tcore_pending_set_timeout(pending, 0);
- tcore_pending_set_priority(pending, TCORE_PENDING_PRIORITY_DEFAULT);
- tcore_pending_set_response_callback(pending, on_response_verify_puks, NULL);
- tcore_pending_link_user_request(pending, ur);
-
- tcore_pending_set_send_callback(pending, on_confirmation_sim_message_send, NULL);
-
- tcore_hal_send_request(h, pending);
-
- free(cmd_str);
-
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn s_change_pins(CoreObject *o, UserRequest *ur)
-{
- TcorePlugin *p = NULL;
- TcoreHal *h = NULL;
- TcorePending *pending = NULL;
-
- const struct treq_sim_change_pins *req_data;
- struct s_sim_property *sp = NULL;
- TReturn trt = 0;
-
- char *cmd_str = NULL;
-
- if (!o || !ur)
- return TCORE_RETURN_EINVAL;
-
- p = tcore_object_ref_plugin(o);
- h = tcore_object_get_hal(o);
- req_data = tcore_user_request_ref_data(ur, NULL);
- sp = tcore_sim_ref_userdata(o);
-
- if(req_data->type == SIM_PTYPE_PIN1) {
- sp->current_sec_op = SEC_PIN1_CHANGE;
- }
- else if(req_data->type == SIM_PTYPE_PIN2) {
- sp->current_sec_op = SEC_PIN2_CHANGE;
- }
- else {
- return TCORE_RETURN_EINVAL;
- }
-
- sp->metainfo.type = NO_RESULT;
- sp->metainfo.responsePrefix[0] = '\0';
-
- trt = tcore_user_request_set_metainfo(ur, sizeof(struct s_sim_property), sp);
- dbg("trt[%d]",trt);
-
- // AT+CPIN=<pin>[,<newpin>]
- cmd_str = g_strdup_printf("AT+CPIN=\"%s\", \"%s\"%s", req_data->old_pin, req_data->new_pin, "\r");
-
- dbg("new pending(IPC_SEC_CHANGE_LOCKING_PW SET)");
- pending = tcore_pending_new(o, ID_RESERVED_AT);
- tcore_pending_set_request_data(pending, strlen(cmd_str), cmd_str);
- tcore_pending_set_timeout(pending, 0);
- tcore_pending_set_priority(pending, TCORE_PENDING_PRIORITY_DEFAULT);
- tcore_pending_set_response_callback(pending, on_response_change_pins, NULL);
- tcore_pending_link_user_request(pending, ur);
-
- tcore_pending_set_send_callback(pending, on_confirmation_sim_message_send, NULL);
-
- tcore_hal_send_request(h, pending);
-
- free(cmd_str);
-
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn s_get_facility_status(CoreObject *o, UserRequest *ur)
-{
- TcorePlugin *p = NULL;
- TcoreHal *h = NULL;
- TcorePending *pending = NULL;
- struct s_sim_property sec_meta = {0,};
- TReturn trt = 0;
-
- const struct treq_sim_get_facility_status *req_data;
- char *fac = "SC";
- int mode = 2; // 2:query, 0: unlock, 1:lock
-
- char *cmd_str = NULL;
-// struct ATReqMetaInfo metainfo;
-
- if (!o || !ur)
- return TCORE_RETURN_EINVAL;
-
- p = tcore_object_ref_plugin(o);
- h = tcore_object_get_hal(o);
- req_data = tcore_user_request_ref_data(ur, NULL);
-
- if(req_data->type == SIM_FACILITY_PS)
- fac = "PS";
- else if(req_data->type == SIM_FACILITY_SC)
- fac = "SC";
- else if(req_data->type == SIM_FACILITY_FD)
- fac = "FD";
- else if(req_data->type == SIM_FACILITY_PN)
- fac = "PN";
- else if(req_data->type == SIM_FACILITY_PU)
- fac = "PU";
- else if(req_data->type == SIM_FACILITY_PP)
- fac = "PP";
- else if(req_data->type == SIM_FACILITY_PC)
- fac = "PC";
- else
- return TCORE_RETURN_EINVAL;
-
- sec_meta.current_sec_op = req_data->type;
- sec_meta.metainfo.type = SINGLELINE;
- memcpy(sec_meta.metainfo.responsePrefix,"+CLCK:",strlen("+CLCK:"));
-
- trt = tcore_user_request_set_metainfo(ur, sizeof(struct s_sim_property), &sec_meta);
- dbg("trt[%d]",trt);
-
- // AT+CLCK=<fac>,<mode>,<password>
- cmd_str = g_strdup_printf("AT+CLCK=\"%s\", %d%s", fac, mode, "\r");
-
- dbg("new pending(IPC_SEC_PHONE_LOCK GET)");
- pending = tcore_pending_new(o, ID_RESERVED_AT);
- tcore_pending_set_request_data(pending, strlen(cmd_str), cmd_str);
- tcore_pending_set_timeout(pending, 0);
- tcore_pending_set_priority(pending, TCORE_PENDING_PRIORITY_DEFAULT);
- tcore_pending_set_response_callback(pending, on_response_get_facility_status, NULL);
- tcore_pending_link_user_request(pending, ur);
-
- tcore_pending_set_send_callback(pending, on_confirmation_sim_message_send, NULL);
-
- tcore_hal_send_request(h, pending);
-
- free(cmd_str);
-
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn s_enable_facility(CoreObject *o, UserRequest *ur)
-{
- TcorePlugin *p = NULL;
- TcoreHal *h = NULL;
- TcorePending *pending = NULL;
- struct s_sim_property sec_meta = {0,};
- const struct treq_sim_enable_facility *req_data;
- struct s_sim_property *sp = NULL;
- char *fac = "SC";
- int mode = 1; // 2:query, 0: unlock, 1:lock
-
- char *cmd_str = NULL;
-// struct ATReqMetaInfo metainfo;
-
- if (!o || !ur)
- return TCORE_RETURN_EINVAL;
-
- p = tcore_object_ref_plugin(o);
- h = tcore_object_get_hal(o);
- req_data = tcore_user_request_ref_data(ur, NULL);
- sp = tcore_sim_ref_userdata(o);
-
- if (req_data->type == SIM_FACILITY_PS)
- fac = "PS";
- else if (req_data->type == SIM_FACILITY_SC)
- fac = "SC";
- else if (req_data->type == SIM_FACILITY_FD)
- fac = "FD";
- else if (req_data->type == SIM_FACILITY_PN)
- fac = "PN";
- else if (req_data->type == SIM_FACILITY_PU)
- fac = "PU";
- else if (req_data->type == SIM_FACILITY_PP)
- fac = "PP";
- else if (req_data->type == SIM_FACILITY_PC)
- fac = "PC";
- else
- return TCORE_RETURN_EINVAL;
-
- sp->current_sec_op = SEC_SIM_ENABLE;
-
- sec_meta.current_sec_op = req_data->type;
- sec_meta.metainfo.type = SINGLELINE;
- memcpy(sec_meta.metainfo.responsePrefix,"+CLCK:",strlen("+CLCK:"));
-
- tcore_user_request_set_metainfo(ur, sizeof(struct s_sim_property), &sec_meta);
-
- // AT+CLCK=<fac>,<mode>,<password>
- cmd_str = g_strdup_printf("AT+CLCK=\"%s\", %d, %s%s", fac, mode, req_data->password,"\r");
- dbg("new pending(enable_facility), %s", cmd_str);
-
- pending = tcore_pending_new(o, ID_RESERVED_AT);
- tcore_pending_set_request_data(pending, strlen(cmd_str), cmd_str);
- tcore_pending_set_timeout(pending, 0);
- tcore_pending_set_priority(pending, TCORE_PENDING_PRIORITY_DEFAULT);
- tcore_pending_set_response_callback(pending, on_response_enable_facility, NULL);
- tcore_pending_link_user_request(pending, ur);
-
- tcore_pending_set_send_callback(pending, on_confirmation_sim_message_send, NULL);
-
- tcore_hal_send_request(h, pending);
-
- free(cmd_str);
-
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn s_disable_facility(CoreObject *o, UserRequest *ur)
-{
- TcorePlugin *p = NULL;
- TcoreHal *h = NULL;
- TcorePending *pending = NULL;
- struct s_sim_property sec_meta = {0,};
- const struct treq_sim_enable_facility *req_data;
- struct s_sim_property *sp = NULL;
- char *fac = "SC";
- int mode = 0; // 2:query, 0: unlock, 1:lock
-
- char *cmd_str = NULL;
- // struct ATReqMetaInfo metainfo;
-
- if (!o || !ur)
- return TCORE_RETURN_EINVAL;
-
- p = tcore_object_ref_plugin(o);
- h = tcore_object_get_hal(o);
- req_data = tcore_user_request_ref_data(ur, NULL);
- sp = tcore_sim_ref_userdata(o);
-
- if (req_data->type == SIM_FACILITY_PS)
- fac = "PS";
- else if (req_data->type == SIM_FACILITY_SC)
- fac = "SC";
- else if (req_data->type == SIM_FACILITY_FD)
- fac = "FD";
- else if (req_data->type == SIM_FACILITY_PN)
- fac = "PN";
- else if (req_data->type == SIM_FACILITY_PU)
- fac = "PU";
- else if (req_data->type == SIM_FACILITY_PP)
- fac = "PP";
- else if (req_data->type == SIM_FACILITY_PC)
- fac = "PC";
- else
- return TCORE_RETURN_EINVAL;
-
- sp->current_sec_op = SEC_SIM_ENABLE;
-
- sec_meta.current_sec_op = req_data->type;
- sec_meta.metainfo.type = SINGLELINE;
- memcpy(sec_meta.metainfo.responsePrefix,"+CLCK:",strlen("+CLCK:"));
-
- tcore_user_request_set_metainfo(ur, sizeof(struct s_sim_property), &sec_meta);
-
- // AT+CLCK=<fac>,<mode>,<password>
- cmd_str = g_strdup_printf("AT+CLCK=\"%s\", %d, %s%s", fac, mode, req_data->password,"\r");
- dbg("new pending(enable_facility), %s", cmd_str);
-
- pending = tcore_pending_new(o, ID_RESERVED_AT);
- tcore_pending_set_request_data(pending, strlen(cmd_str), cmd_str);
- tcore_pending_set_timeout(pending, 0);
- tcore_pending_set_priority(pending, TCORE_PENDING_PRIORITY_DEFAULT);
- tcore_pending_set_response_callback(pending, on_response_disable_facility, NULL);
- tcore_pending_link_user_request(pending, ur);
-
- tcore_pending_set_send_callback(pending, on_confirmation_sim_message_send, NULL);
-
- tcore_hal_send_request(h, pending);
-
- free(cmd_str);
-
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn s_read_file(CoreObject *o, UserRequest *ur)
-{
- TReturn api_ret = TCORE_RETURN_SUCCESS;
- enum tcore_request_command command;
- command = tcore_user_request_get_command(ur);
-
- dbg("enter");
-
- switch (command) {
- case TREQ_SIM_GET_ECC:
- api_ret = _get_file_info(o, ur, SIM_EF_ECC);
- break;
-
- case TREQ_SIM_GET_LANGUAGE:
- if (tcore_sim_get_type(o) == SIM_TYPE_GSM)
- api_ret = _get_file_info(o, ur, SIM_EF_ELP);
- else if (tcore_sim_get_type(o) == SIM_TYPE_USIM)
- api_ret = _get_file_info(o, ur, SIM_EF_LP);
- else
- api_ret = TCORE_RETURN_ENOSYS;
- break;
-
- case TREQ_SIM_GET_ICCID:
- api_ret = _get_file_info(o, ur, SIM_EF_ICCID);
- break;
-
- case TREQ_SIM_GET_MAILBOX:
- if(tcore_sim_get_cphs_status(o))
- api_ret = _get_file_info(o, ur, SIM_EF_CPHS_MAILBOX_NUMBERS);
- else
- api_ret = _get_file_info(o, ur, SIM_EF_MBDN);
- break;
-
- case TREQ_SIM_GET_CALLFORWARDING:
- if(tcore_sim_get_cphs_status(o))
- api_ret = _get_file_info(o, ur, SIM_EF_CPHS_CALL_FORWARD_FLAGS);
- else
- api_ret = _get_file_info(o, ur, SIM_EF_USIM_CFIS);
- break;
-
- case TREQ_SIM_GET_MESSAGEWAITING:
- if(tcore_sim_get_cphs_status(o))
- api_ret = _get_file_info(o, ur, SIM_EF_CPHS_VOICE_MSG_WAITING);
- else
- api_ret = _get_file_info(o, ur, SIM_EF_USIM_MWIS);
- break;
-
- case TREQ_SIM_GET_CPHS_INFO:
- if(tcore_sim_get_cphs_status(o))
- api_ret = _get_file_info(o, ur, SIM_EF_CPHS_CPHS_INFO);
- else
- api_ret = TCORE_RETURN_ENOSYS;
- break;
-
- case TREQ_SIM_GET_MSISDN:
- api_ret = _get_file_info(o, ur, SIM_EF_MSISDN);
- break;
-
- case TREQ_SIM_GET_SPN:
- dbg("enter case SPN");
- api_ret = _get_file_info(o, ur, SIM_EF_SPN);
- break;
-
- case TREQ_SIM_GET_SPDI:
- api_ret = _get_file_info(o, ur, SIM_EF_SPDI);
- break;
-
- case TREQ_SIM_GET_OPL:
- api_ret = _get_file_info(o, ur, SIM_EF_OPL);
- break;
-
- case TREQ_SIM_GET_PNN:
- api_ret = _get_file_info(o, ur, SIM_EF_PNN);
- break;
-
- case TREQ_SIM_GET_CPHS_NETNAME:
- api_ret = _get_file_info(o, ur, SIM_EF_CPHS_OPERATOR_NAME_STRING);
- break;
-
- case TREQ_SIM_GET_OPLMNWACT:
- api_ret = _get_file_info(o, ur, SIM_EF_OPLMN_ACT);
- break;
-
- default:
- dbg("error - not handled read treq command[%d]", command);
- api_ret = TCORE_RETURN_EINVAL;
- break;
- }
- return api_ret;
-}
-
-static TReturn s_update_file(CoreObject *o, UserRequest *ur)
-{
- TReturn api_ret = TCORE_RETURN_ENOSYS;
- return api_ret;
-}
-
-static TReturn s_transmit_apdu(CoreObject *o, UserRequest *ur)
-{
- dbg("need to be implemented to use ATCMD");
-
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn s_get_atr(CoreObject *o, UserRequest *ur)
-{
- dbg("need to be implemented to use ATCMD");
-
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn s_req_authentication(CoreObject *o, UserRequest *ur)
-{
- return TCORE_RETURN_SUCCESS;
-}
-
-static struct tcore_sim_operations sim_ops =
-{
- .verify_pins = s_verify_pins,
- .verify_puks = s_verify_puks,
- .change_pins = s_change_pins,
- .get_facility_status = s_get_facility_status,
- .enable_facility = s_enable_facility,
- .disable_facility = s_disable_facility,
- .read_file = s_read_file,
- .update_file = s_update_file,
- .transmit_apdu = s_transmit_apdu,
- .get_atr = s_get_atr,
- .req_authentication = s_req_authentication
-};
-
-gboolean s_sim_init(TcorePlugin *cp, CoreObject *co)
-{
- struct s_sim_property *sp = NULL;
-
- dbg("Entry");
-
- tcore_sim_override_ops(co, &sim_ops);
-
- sp = calloc(sizeof(struct s_sim_property),1);
- if (!sp)
- return FALSE;
-
- sp->first_recv_status = SIM_STATUS_UNKNOWN;
- tcore_sim_link_userdata(co, sp);
-
- tcore_object_override_callback(co, EVENT_SIM_PIN_STATUS, on_event_pin_status, NULL);
-
- dbg("Exit");
-
- return TRUE;
-}
-
-
-void s_sim_exit(TcorePlugin *cp, CoreObject *co)
-{
- struct s_sim_property *sp = tcore_object_ref_user_data(co);
-
- if (sp)
- free(sp);
-
- dbg("Exit");
-}
+++ /dev/null
-/*
- * tel-plugin-atmodem
- *
- * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: Hayoon Ko <hayoon.ko@samsung.com>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <glib.h>
-
-#include <tcore.h>
-#include <hal.h>
-#include <core_object.h>
-#include <plugin.h>
-#include <queue.h>
-#include <co_sms.h>
-#include <co_sim.h>
-#include <user_request.h>
-#include <storage.h>
-#include <server.h>
-
-#include "s_common.h"
-#include "s_sms.h"
-
-#include "atchannel.h"
-#include "at_tok.h"
-
-#define MAX_GSM_SMS_TPDU_SIZE 244
-#define MAX_GSM_SMS_PARAM_RECORD_SIZE 156 /* Maximum number of bytes SMSP Record size (Y + 28), y : 0 ~ 128 */
-#define SWAPBYTES16(x) \
-{ \
- unsigned short int data = *(unsigned short int*)&(x); \
- data = ((data & 0xff00) >> 8) | \
- ((data & 0x00ff) << 8); \
- *(unsigned short int*)&(x) = data ; \
-}
-
-extern struct ATResponse *sp_response;
-extern char *s_responsePrefix;
-extern enum ATCommandType s_type;
-
-gboolean util_byte_to_hex(const char *byte_pdu, char *hex_pdu, int num_bytes);
-
-static TReturn Send_SmsSubmitTpdu(CoreObject *o, UserRequest *ur);
-
-/************************************************************/
-/********************* Utility for SMS *************************/
-/************************************************************/
-static void util_sms_get_length_of_sca(int* nScLength) {
- if (*nScLength % 2) {
- *nScLength = (*nScLength / 2) + 1;
- } else {
- *nScLength = *nScLength / 2;
- }
-
- return;
-}
-
-static int util_sms_decode_smsParameters(unsigned char *incoming, unsigned int length, struct telephony_sms_Params *params)
-{
- int alpha_id_len = 0;
- int i = 0;
- int nOffset = 0;
-
- dbg(" RecordLen = %d", length);
-
- if(incoming == NULL || params == NULL)
- return FALSE;
-
- alpha_id_len = length -SMS_SMSP_PARAMS_MAX_LEN;
-
- if ( alpha_id_len > 0 )
- {
- if(alpha_id_len > SMS_SMSP_ALPHA_ID_LEN_MAX)
- {
- alpha_id_len = SMS_SMSP_ALPHA_ID_LEN_MAX;
- }
-
- for( i=0 ; i < alpha_id_len ; i++)
- {
- if( 0xff == incoming[i])
- {
- dbg(" found");
- break;
- }
- }
-
- memcpy(params->szAlphaId, incoming, i);
-
- params->alphaIdLen = i;
-
- dbg(" Alpha id length = %d", i);
-
- }
- else
- {
- params->alphaIdLen = 0;
- dbg(" Alpha id length is zero");
- }
-
- // start parse from here.
- params->paramIndicator = incoming[alpha_id_len];
-
- dbg(" Param Indicator = %02x", params->paramIndicator);
-
- // DestAddr
- if( (params->paramIndicator & SMSPValidDestAddr) == 0)
- {
- nOffset = nDestAddrOffset;
-
- if( 0x00 == incoming[alpha_id_len + nOffset] || 0xff == incoming[alpha_id_len + nOffset])
- {
- params->tpDestAddr.dialNumLen = 0;
-
- dbg("DestAddr Length is 0");
- }
- else
- {
- if ( 0 < (int)incoming[alpha_id_len + nOffset] )
- {
- params->tpDestAddr.dialNumLen = (int)(incoming[alpha_id_len + nOffset] - 1 );
-
- if(params->tpDestAddr.dialNumLen > SMS_SMSP_ADDRESS_LEN)
- params->tpDestAddr.dialNumLen = SMS_SMSP_ADDRESS_LEN;
- }
- else
- {
- params->tpDestAddr.dialNumLen = 0;
- }
-
- params->tpDestAddr.numPlanId= incoming[alpha_id_len + (++nOffset)] & 0x0f ;
- params->tpDestAddr.typeOfNum= (incoming[alpha_id_len + nOffset] & 0x70 )>>4 ;
-
- memcpy( params->tpDestAddr.diallingNum, &incoming[alpha_id_len + (++nOffset)], (params->tpDestAddr.dialNumLen)) ;
-
- dbg("Dest TON is %d",params->tpDestAddr.typeOfNum);
- dbg("Dest NPI is %d",params->tpDestAddr.numPlanId);
- dbg("Dest Length = %d",params->tpDestAddr.dialNumLen);
- dbg("Dest Addr = %s",params->tpDestAddr.diallingNum);
-
- }
- }
-
- // SvcAddr
- if( (params->paramIndicator & SMSPValidSvcAddr) == 0)
- {
- nOffset = nSCAAddrOffset;
-
- if( 0x00 == (int)incoming[alpha_id_len + nOffset] || 0xff == (int)incoming[alpha_id_len + nOffset] )
- {
- params->tpSvcCntrAddr.dialNumLen = 0;
-
- dbg(" SCAddr Length is 0");
- }
- else
- {
- if ( 0 < (int)incoming[alpha_id_len + nOffset] )
- {
- params->tpSvcCntrAddr.dialNumLen = (int)(incoming[alpha_id_len + nOffset] - 1);
-
- if(params->tpSvcCntrAddr.dialNumLen > SMS_SMSP_ADDRESS_LEN)
- params->tpSvcCntrAddr.dialNumLen = SMS_SMSP_ADDRESS_LEN;
-
- params->tpSvcCntrAddr.numPlanId= incoming[alpha_id_len + (++nOffset)] & 0x0f ;
- params->tpSvcCntrAddr.typeOfNum= (incoming[alpha_id_len + nOffset] & 0x70) >>4 ;
-
- memcpy( params->tpSvcCntrAddr.diallingNum, &incoming[alpha_id_len + (++nOffset)], (params->tpSvcCntrAddr.dialNumLen));
-
- dbg("SCAddr Length = %d ",params->tpSvcCntrAddr.dialNumLen);
- dbg("SCAddr TON is %d",params->tpSvcCntrAddr.typeOfNum);
- dbg("SCAddr NPI is %d",params->tpSvcCntrAddr.numPlanId);
-
- for( i = 0 ; i < (int)params->tpSvcCntrAddr.dialNumLen ; i ++)
- dbg("SCAddr = %d [%02x]",i,params->tpSvcCntrAddr.diallingNum[i]);
- }
- else
- {
- params->tpSvcCntrAddr.dialNumLen = 0;
- }
- }
- }
- else if ( (0x00 < (int)incoming[alpha_id_len +nSCAAddrOffset] && (int)incoming[alpha_id_len +nSCAAddrOffset] <= 12 )
- || 0xff != (int)incoming[alpha_id_len +nSCAAddrOffset])
- {
- nOffset = nSCAAddrOffset;
-
- if( 0x00 == (int)incoming[alpha_id_len + nOffset] || 0xff == (int)incoming[alpha_id_len + nOffset] )
- {
- params->tpSvcCntrAddr.dialNumLen = 0;
- dbg("SCAddr Length is 0");
- }
- else
- {
-
- if ( 0 < (int)incoming[alpha_id_len + nOffset] )
- {
- params->tpSvcCntrAddr.dialNumLen = (int)(incoming[alpha_id_len + nOffset] - 1);
-
- params->tpSvcCntrAddr.dialNumLen = incoming[alpha_id_len + nOffset] -1;
-
- if(params->tpSvcCntrAddr.dialNumLen > SMS_SMSP_ADDRESS_LEN)
- params->tpSvcCntrAddr.dialNumLen = SMS_SMSP_ADDRESS_LEN;
-
- params->tpSvcCntrAddr.numPlanId= incoming[alpha_id_len + (++nOffset)] & 0x0f ;
- params->tpSvcCntrAddr.typeOfNum= (incoming[alpha_id_len + nOffset] & 0x70) >>4 ;
-
- memcpy( params->tpSvcCntrAddr.diallingNum, &incoming[alpha_id_len + (++nOffset)],
- (params->tpSvcCntrAddr.dialNumLen)) ;
-
- dbg("SCAddr Length = %d ",params->tpSvcCntrAddr.dialNumLen);
- dbg("SCAddr TON is %d",params->tpSvcCntrAddr.typeOfNum);
- dbg("SCAddr NPI is %d",params->tpSvcCntrAddr.numPlanId);
-
- for( i = 0 ; i < (int)params->tpSvcCntrAddr.dialNumLen ; i ++)
- dbg("SCAddr = %d [%02x]",i,params->tpSvcCntrAddr.diallingNum[i]);
- }
- else
- {
- params->tpSvcCntrAddr.dialNumLen = 0;
- }
- }
-
- }
-
- if( (params->paramIndicator & SMSPValidPID) == 0 && (alpha_id_len + nPIDOffset) < MAX_GSM_SMS_PARAM_RECORD_SIZE)
- {
- params->tpProtocolId = incoming[alpha_id_len + nPIDOffset];
- }
- if( (params->paramIndicator & SMSPValidDCS) == 0 && (alpha_id_len + nDCSOffset) < MAX_GSM_SMS_PARAM_RECORD_SIZE)
- {
- params->tpDataCodingScheme = incoming[alpha_id_len + nDCSOffset];
- }
- if( (params->paramIndicator & SMSPValidVP) == 0 && (alpha_id_len + nVPOffset) < MAX_GSM_SMS_PARAM_RECORD_SIZE)
- {
- params->tpValidityPeriod = incoming[alpha_id_len + nVPOffset];
- }
-
- dbg(" Alpha Id(Len) = %d",(int)params->alphaIdLen);
-
- for (i=0; i< (int)params->alphaIdLen ; i++)
- {
- dbg(" Alpha Id = [%d] [%c]",i,params->szAlphaId[i]);
- }
- dbg(" PID = %d",params->tpProtocolId);
- dbg(" DCS = %d",params->tpDataCodingScheme);
- dbg(" VP = %d",params->tpValidityPeriod);
-
- return TRUE;
-}
-
-static int util_sms_ipcError2SmsError(int err)
-{
- int returnStatus=0;
-
- switch(err)
- {
- case 300: //ME Failure;
- returnStatus = SMS_PHONE_FAILURE;
- break;
- case 302: //Operation not allowed;
- case 303: //Operation not supported;
- returnStatus = SMS_OPERATION_NOT_SUPPORTED;
- break;
- case 304: //Invalid PDU mode parameter;
- case 305: //Invalid text mode parameter;
- returnStatus = SMS_INVALID_PARAMETER_FORMAT;
- break;
- case 320: //memory failure;
- case 321: //invalid memory index;
- case 322: //memory full;
- returnStatus = SMS_MEMORY_FAILURE;
- break;
- case 330: //SCA unknown;
- case 500: //Unknown error;
- default:
- returnStatus = SMS_UNKNOWN;
- break;
- }
-
- return returnStatus;
-}
-
-/************************************************************/
-/************************ Events Cb *************************/
-/************************************************************/
-
-static gboolean on_event_sms_incom_msg(CoreObject *o, const void *event_info, void *user_data)
-{
- struct smsDeliveryPDU *smsPdu = (struct smsDeliveryPDU *)event_info;
- int *property;
- struct tnoti_sms_umts_msg gsmMsgInfo;
-
- int ScLength = 0, i = 0;
- unsigned char LastSemiOctect;
-
- memset(&gsmMsgInfo, 0, sizeof(struct tnoti_sms_umts_msg));
- // +CMT: <length><CR><LF><pdu>
- ScLength = smsPdu->pdu[0];
-
- dbg(" ScLength is %d",ScLength);
-
- LastSemiOctect = smsPdu->pdu[ScLength + 1] & 0xf0;
- if( LastSemiOctect == 0xf0 )
- {
- smsPdu->pdu[0] = (ScLength-1)*2 - 1;
- }
- else
- {
- smsPdu->pdu[0] = (ScLength-1)*2;
- }
-
- gsmMsgInfo.msgInfo.msgLength = smsPdu->len - ScLength;
- dbg(" MSG LENGTH [%d]", gsmMsgInfo.msgInfo.msgLength);
-
- if ( (gsmMsgInfo.msgInfo.msgLength >0) && (0xff >= gsmMsgInfo.msgInfo.msgLength))
- {
- property = tcore_plugin_ref_property(tcore_object_ref_plugin(o), "SMSPRECORDLEN");
- if(!property) {
- dbg("property is NULL");
- return TRUE;
- }
-
- memcpy(gsmMsgInfo.msgInfo.sca, &smsPdu->pdu[0], (ScLength+1));
-
- for(i=0;i<(ScLength+1);i++)
- {
- dbg("SCA is [%02x] ",gsmMsgInfo.msgInfo.sca[i]);
- }
-
- if(gsmMsgInfo.msgInfo.msgLength > SMS_SMDATA_SIZE_MAX)
- {
- gsmMsgInfo.msgInfo.msgLength = SMS_SMDATA_SIZE_MAX;
- }
-
- memcpy(gsmMsgInfo.msgInfo.tpduData, &smsPdu->pdu[ScLength +1], gsmMsgInfo.msgInfo.msgLength);
-
- 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);
-
- }
- else
- {
- dbg("Invalid Message Length");
- }
-
- return TRUE;
-}
-
-static gboolean on_event_sms_device_ready(CoreObject *o, const void *event_info, void *user_data)
-{
- struct tnoti_sms_ready_status readyStatusInfo = {0,};
- int rtn = -1;
-
- dbg(" Func Entrance");
- readyStatusInfo.status = TRUE;
- tcore_sms_set_ready_status(o, readyStatusInfo.status);
-
- dbg("SMS Ready status = [%s]", readyStatusInfo.status ? "TRUE" : "FALSE");
-
- 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);
-
- dbg(" Return value [%d]",rtn);
-
- return TRUE;
-}
-
-/*************************************************************/
-/*********************** Responses Cb ************************/
-/************************************************************/
-static void on_confirmation_sms_message_send( TcorePending *p, gboolean result, void *user_data )
-{
- UserRequest* ur = NULL;
- struct ATReqMetaInfo* metainfo = NULL;
- unsigned int info_len =0;
- dbg("on_confirmation_call_message_send - msg out from queue. alloc ATRsp buffer & write rspPrefix if needed\n");
-
- ReleaseResponse(); //release leftover
-
- sp_response = at_response_new();
-
- ur = tcore_pending_ref_user_request(p);
- metainfo = (struct ATReqMetaInfo*)tcore_user_request_ref_metainfo(ur,&info_len);
-
- if((metainfo->type == SINGLELINE)||
- (metainfo->type == MULTILINE))
- {
- //cp rsp prefix
- s_responsePrefix = strdup(metainfo->responsePrefix);
- dbg("duplicating responsePrefix : %s\n", s_responsePrefix);
- }
- else
- {
- s_responsePrefix = NULL;
- }
-
- //set atcmd type into s_type
- s_type = metainfo->type;
-
- if (result == FALSE) {
- /* Fail */
- dbg("SEND FAIL");
- }
- else {
- dbg("SEND OK");
- }
-}
-
-static void on_response_send_umts_msg(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- UserRequest *ur;
- struct tresp_sms_send_umts_msg respSendMsg;
-
- int error;
- char *line = NULL;
- int ret;
-
- memset(&respSendMsg, 0, sizeof(struct tresp_sms_send_umts_msg));
- ur = tcore_pending_ref_user_request(p);
- if (!ur)
- {
- dbg("no user_request");
- return;
- }
-
- printResponse();
-
- if(sp_response->success == TRUE)
- {
- ReleaseResponse();
- ur = tcore_user_request_ref(ur);
- ret = (int) Send_SmsSubmitTpdu(tcore_pending_ref_core_object(p), ur);
-
- if(ret != (int)TCORE_RETURN_SUCCESS)
- {
- respSendMsg.result = SMS_INVALID_PARAMETER;
- tcore_user_request_send_response(ur, TRESP_SMS_SEND_UMTS_MSG, sizeof(struct tresp_sms_send_umts_msg), &respSendMsg);
- }
- }
- else
- {
- //failure case - consider this later
- line = sp_response->finalResponse;
-
- ret = at_tok_start(&line);
- if (ret < 0)
- AT_TOK_ERROR(line);
-
- ret = at_tok_nextint(&line,&error);
- if (ret < 0)
- AT_TOK_ERROR(line);
-
- respSendMsg.result = util_sms_ipcError2SmsError(error);
-
- tcore_user_request_send_response(ur, TRESP_SMS_SEND_UMTS_MSG, sizeof(struct tresp_sms_send_umts_msg), &respSendMsg);
- }
-
- return;
-}
-
-static void on_response_send_smsSubmitTpdu(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- UserRequest *ur = NULL;
- struct tresp_sms_send_umts_msg respUmtsInfo;
-
- char *line = NULL;
- char *ackpdu = NULL;
- int ret;
- int mr;
- int error;
- char *hexData;
-
- printResponse();
-
- if(sp_response->success > 0)
- {
- line = sp_response->p_intermediates->line;
-
- memset(&respUmtsInfo, 0 , sizeof(struct tresp_sms_send_umts_msg));
- // +CMGS: <mr>[, <ackpdu>]
- // SMS_SMDATA_SIZE_MAX + 1
- ret = at_tok_start(&line);
- if (ret < 0)
- AT_TOK_ERROR(line);
-
- ret = at_tok_nextint(&line, &mr);
- if (ret < 0)
- return;
-
- ret = at_tok_nextstr(&line, &hexData);
- if (ret < 0)
- {
- dbg(" ackpdu is NULL ");
- ackpdu = NULL;
- } else {
- ackpdu = util_hexStringToBytes(hexData);
- util_hex_dump(" ", strlen(hexData)/2, ackpdu);
- }
-
- dbg(" Func Entrance ");
-
- ur = tcore_pending_ref_user_request(p);
- if(ur)
- {
- respUmtsInfo.result = SMS_SENDSMS_SUCCESS;
-
- tcore_user_request_send_response(ur, TRESP_SMS_SEND_UMTS_MSG, sizeof(struct tresp_sms_send_umts_msg), &respUmtsInfo);
-
- } else
- dbg("no user_request");
- }
- else
- {
- //failure case - consider this later
- line = sp_response->finalResponse;
-
- ret = at_tok_start(&line);
- if (ret < 0)
- AT_TOK_ERROR(line);
-
- ret = at_tok_nextint(&line,&error);
- if (ret < 0)
- AT_TOK_ERROR(line);
-
-
- //5. release sp_response & s_responsePrefix - before sending user callback, because user callback can request additional request
- // and if queue is empty, that req can be directly sent to mdm - can cause sp_response, s_responsePrefix dangling
- ReleaseResponse();
-
- ur = tcore_pending_ref_user_request(p);
- if (ur) {
- struct tresp_sms_send_umts_msg respSendMsg;
-
- memset(&respSendMsg, 0, sizeof(struct tresp_sms_send_umts_msg));
- respSendMsg.result = SMS_INVALID_MANDATORY_INFO;
-
- respSendMsg.result = util_sms_ipcError2SmsError(error);
-
- tcore_user_request_send_response(ur, TRESP_SMS_SEND_UMTS_MSG, sizeof(struct tresp_sms_send_umts_msg), &respSendMsg);
- }
- else {
- dbg("no user_request");
- }
- }
-}
-
-static void on_response_get_storedMsgCnt(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- UserRequest *ur;
- struct tresp_sms_get_storedMsgCnt respStoredMsgCnt;
-
- int error;
- char *line = NULL;
- int ret;
- int usedCount = 0;
- int totalCount = 0;
-
- memset(&respStoredMsgCnt, 0, sizeof(struct tresp_sms_get_storedMsgCnt));
- ur = tcore_pending_ref_user_request(p);
- if (!ur)
- {
- dbg("no user_request");
- return;
- }
-
- printResponse();
-
- if(sp_response->success > 0)
- {
- //failure case - consider this later
- line = sp_response->p_intermediates->line;
-
- ret = at_tok_start(&line);
- if (ret < 0)
- AT_TOK_ERROR(line);
-
- ret = at_tok_nextint(&line,&usedCount);
- if (ret < 0)
- AT_TOK_ERROR(line);
- ret = at_tok_nextint(&line,&totalCount);
- if (ret < 0)
- AT_TOK_ERROR(line);
-
- respStoredMsgCnt.storedMsgCnt.totalCount = totalCount;
- respStoredMsgCnt.storedMsgCnt.usedCount = usedCount;
-
- dbg(" totalCount:%d, usedCount:%d",respStoredMsgCnt.storedMsgCnt.totalCount , respStoredMsgCnt.storedMsgCnt.usedCount );
-
- respStoredMsgCnt.result = SMS_SUCCESS;
- }
- else
- {
- //failure case - consider this later
- line = sp_response->finalResponse;
-
- ret = at_tok_start(&line);
- if (ret < 0)
- AT_TOK_ERROR(line);
-
- ret = at_tok_nextint(&line,&error);
- if (ret < 0)
- AT_TOK_ERROR(line);
-
- respStoredMsgCnt.result = util_sms_ipcError2SmsError(error);
- }
-
- ReleaseResponse();
-
-
- tcore_user_request_send_response(ur, TRESP_SMS_GET_STORED_MSG_COUNT, sizeof(struct tresp_sms_get_storedMsgCnt), &respStoredMsgCnt);
-
- return;
-
-}
-
-static void on_response_get_sca(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- UserRequest *ur;
- struct tresp_sms_get_sca respGetSca;
-
- char* line=NULL;
- int ret = 0;
- char *scaStr = NULL;
- int scaType = 0;
- int error;
-
- ur = tcore_pending_ref_user_request(p);
- if (!ur)
- {
- dbg("no user_request");
- return;
- }
-
- printResponse();
-
- // +CSCA: <sca number>,<sca type>
- if(sp_response->success > 0)
- {
- respGetSca.result = SMS_SUCCESS;
-
- line = sp_response->p_intermediates->line;
- ret = at_tok_start(&line);
- if (ret < 0)
- AT_TOK_ERROR(line);
-
- ret = at_tok_nextstr(&line, &scaStr);
- if (ret < 0)
- AT_TOK_ERROR(line);
- memcpy(respGetSca.scaAddress.diallingNum, scaStr, strlen(scaStr));
-
-
- line = sp_response->p_intermediates->line;
- ret = at_tok_start(&line);
- if (ret < 0)
- AT_TOK_ERROR(line);
-
- ret = at_tok_nextstr(&line,&scaStr);
- if(scaStr!=NULL)
- ret = at_tok_nextint(&line,&scaType);
-
- respGetSca.scaAddress.dialNumLen = strlen(scaStr);
- if(scaType == 145)
- respGetSca.scaAddress.typeOfNum = SIM_TON_INTERNATIONAL;
- else respGetSca.scaAddress.typeOfNum = SIM_TON_NATIONAL;
- respGetSca.scaAddress.numPlanId = 0;
-
- memcpy(respGetSca.scaAddress.diallingNum, scaStr, strlen(scaStr));
-
- }
- else
- {
- //failure case - consider this later
- line = sp_response->finalResponse;
-
- ret = at_tok_start(&line);
- if (ret < 0)
- AT_TOK_ERROR(line);
-
- ret = at_tok_nextint(&line,&error);
- if (ret < 0)
- AT_TOK_ERROR(line);
-
- respGetSca.result = util_sms_ipcError2SmsError(error);
-
- }
-
- ReleaseResponse();
-
- tcore_user_request_send_response(ur, TRESP_SMS_GET_SCA, sizeof(struct tresp_sms_get_sca), &respGetSca);
-
- return;
-}
-
-static void on_response_set_sca(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- UserRequest *ur;
- struct tresp_sms_set_sca respSetSca;
- int ret;
- int error;
- char *line = NULL;
-
- ur = tcore_pending_ref_user_request(p);
- if (!ur)
- {
- dbg("no user_request");
- return;
- }
-
- printResponse();
-
- if(sp_response->success > 0)
- {
- respSetSca.result = SMS_SUCCESS;
- }
- else
- {
- //failure case - consider this later
- line = sp_response->finalResponse;
-
- ret = at_tok_start(&line);
- if (ret < 0)
- AT_TOK_ERROR(line);
-
- ret = at_tok_nextint(&line,&error);
- if (ret < 0)
- AT_TOK_ERROR(line);
-
- respSetSca.result = util_sms_ipcError2SmsError(error);
- }
-
- ReleaseResponse();
-
- tcore_user_request_send_response(ur, TRESP_SMS_SET_SCA, sizeof(struct tresp_sms_get_sca), &respSetSca);
-
- return;
-}
-
-static void on_response_set_delivery_report(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- UserRequest *ur;
- struct tresp_sms_set_delivery_report respSetDeliveryReport = {0,};
-
- int error;
- char *line = NULL;
- int ret;
-
- ur = tcore_pending_ref_user_request(p);
- if (!ur)
- {
- dbg("no user_request");
- return;
- }
-
- printResponse();
-
- if(sp_response->success > 0)
- {
- respSetDeliveryReport.result = SMS_SUCCESS;
- }
- else
- {
- //failure case - consider this later
- line = sp_response->finalResponse;
-
- ret = at_tok_start(&line);
- if (ret < 0)
- AT_TOK_ERROR(line);
-
- ret = at_tok_nextint(&line,&error);
- if (ret < 0)
- AT_TOK_ERROR(line);
-
- respSetDeliveryReport.result = util_sms_ipcError2SmsError(error);
- }
-
- ReleaseResponse();
-
-
- tcore_user_request_send_response(ur, TRESP_SMS_SET_DELIVERY_REPORT, sizeof(struct tresp_sms_set_delivery_report), &respSetDeliveryReport);
-
- return;
-}
-
-static void on_response_get_sms_params(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- UserRequest *ur;
- struct tresp_sms_get_params respGetSmsParams;
- int *property = NULL;
-
- char *line = NULL;
- int error;
- int ret = 0;
- int sw1 = 0;
- int sw2 = 0;
- char *recordData;
-
- memset(&respGetSmsParams, 0, sizeof(struct tresp_sms_get_params));
- printResponse();
-
-
- ur = tcore_pending_ref_user_request(p);
- if (!ur)
- {
- dbg("no user_request");
- return;
- }
-
- if(sp_response->success > 0)
- {
- line = sp_response->p_intermediates->line;
-
- ret = at_tok_start(&line);
- if (ret < 0)
- AT_TOK_ERROR(line);
-
- ret = at_tok_nextint(&line,&sw1);
- if (ret < 0)
- AT_TOK_ERROR(line);
- ret = at_tok_nextint(&line,&sw2);
- if (ret < 0)
- AT_TOK_ERROR(line);
-
- if(sw1 != 144 || sw2 != 0)
- respGetSmsParams.result = SMS_UNKNOWN;
- else
- {
- char *hexData;
-
- ret = at_tok_nextstr(&line,&hexData);
- if (ret < 0)
- AT_TOK_ERROR(line);
-
- recordData = util_hexStringToBytes(hexData);
- util_hex_dump(" ", strlen(hexData)/2, recordData);
-
- // respGetSmsParams.paramsInfo.recordIndex = 0;
- respGetSmsParams.paramsInfo.recordLen = strlen(hexData)/2;
-
- property = tcore_plugin_ref_property(tcore_object_ref_plugin(tcore_pending_ref_core_object(p)), "SMSPRECORDLEN");
-
- if(!property) {
- dbg("property is NULL");
- free(recordData);
- return;
- }
-
- util_sms_decode_smsParameters((unsigned char *)recordData, strlen(hexData) / 2, &respGetSmsParams.paramsInfo);
- *property = respGetSmsParams.paramsInfo.recordLen;
-
- respGetSmsParams.result = SMS_SUCCESS;
-
- free(recordData);
- }
- }
- else
- {
- respGetSmsParams.result = SMS_UNKNOWN;
- //failure case - consider this later
- line = sp_response->finalResponse;
-
- ret = at_tok_start(&line);
- if (ret < 0)
- AT_TOK_ERROR(line);
-
- ret = at_tok_nextint(&line,&error);
- if (ret < 0)
- AT_TOK_ERROR(line);
-
- respGetSmsParams.result = util_sms_ipcError2SmsError(error);
- }
-
- ReleaseResponse();
-
- tcore_user_request_send_response(ur, TRESP_SMS_GET_PARAMS, sizeof(struct tresp_sms_get_params), &respGetSmsParams);
-
- return;
-}
-
-static void on_response_set_sms_params(TcorePending *p, int data_len,
- const void *data, void *user_data)
-{
- char *line;
- int sw1, sw2;
- int ret;
- struct tresp_sms_set_params respSetParams;
- UserRequest *ur = tcore_pending_ref_user_request(p);
-
- memset(&respSetParams, 0, sizeof(struct tresp_sms_set_params));
- respSetParams.result = SMS_DEVICE_FAILURE;
-
- if (sp_response->success != TRUE) {
- dbg("Response NOK");
- goto OUT;
- }
-
- dbg("Response OK");
-
- line = sp_response->p_intermediates->line;
- ret = at_tok_start(&line);
- if (ret < 0)
- AT_TOK_ERROR(line);
-
- ret = at_tok_nextint(&line, &sw1);
- if (ret < 0)
- AT_TOK_ERROR(line);
-
- ret = at_tok_nextint(&line, &sw2);
- if (ret < 0)
- AT_TOK_ERROR(line);
-
- if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91)
- respSetParams.result = SMS_SENDSMS_SUCCESS;
-
-OUT:
- ReleaseResponse();
- tcore_user_request_send_response(ur, TRESP_SMS_SET_PARAMS,
- sizeof(struct tresp_sms_set_params), &respSetParams);
-
- return;
-}
-
-static void on_response_get_paramcnt(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- UserRequest *ur;
- struct tresp_sms_get_paramcnt respGetParamCnt = {0,};
- CoreObject *co_sim = NULL;
- char *line = NULL;
- int ret = 0;
- int sw1 = 0;
- int sw2 = 0;
- int *smsp_record_len;
- TcorePlugin *plugin = tcore_pending_ref_plugin(p);
-
- ur = tcore_pending_ref_user_request(p);
-
- if(sp_response->success == TRUE)
- {
- line = sp_response->p_intermediates->line;
- ret = at_tok_start(&line);
- if (ret < 0)
- AT_TOK_ERROR(line);
-
- ret = at_tok_nextint(&line,&sw1);
- if (ret < 0)
- AT_TOK_ERROR(line);
- ret = at_tok_nextint(&line,&sw2);
- if (ret < 0)
- AT_TOK_ERROR(line);
-
- /*1. SIM access success case*/
- if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
- unsigned char tag_len = 0; /* 1 or 2 bytes ??? */
- unsigned short record_len = 0;
- char num_of_records = 0;
- unsigned char file_id_len = 0;
- unsigned short file_id = 0;
- unsigned short file_size = 0;
- unsigned short file_type = 0;
- unsigned short arr_file_id = 0;
- int arr_file_id_rec_num = 0;
-
- /* handling only last 3 bits */
- unsigned char file_type_tag = 0x07;
- unsigned char *ptr_data;
-
- char *hexData;
- char *recordData;
- ret = at_tok_nextstr(&line,&hexData);
- if (ret < 0)
- AT_TOK_ERROR(line);
-
- recordData = util_hexStringToBytes(hexData);
- util_hex_dump(" ", strlen(hexData)/2, recordData);
-
- ptr_data = (unsigned char *)recordData;
-
- co_sim = tcore_plugin_ref_core_object(tcore_pending_ref_plugin(p), CORE_OBJECT_TYPE_SIM);
- if (tcore_sim_get_type(co_sim) == SIM_TYPE_USIM) {
- /*
- ETSI TS 102 221 v7.9.0
- - Response Data
- '62' FCP template tag
- - Response for an EF
- '82' M File Descriptor
- '83' M File Identifier
- 'A5' O Proprietary information
- '8A' M Life Cycle Status Integer
- '8B', '8C' or 'AB' C1 Security attributes
- '80' M File size
- '81' O Total file size
- '88' O Short File Identifier (SFI)
- */
-
- /* rsim.res_len has complete data length received */
-
- /* FCP template tag - File Control Parameters tag*/
- if (*ptr_data == 0x62) {
- /* parse complete FCP tag*/
- /* increment to next byte */
- ptr_data++;
- tag_len = *ptr_data++;
- /* FCP file descriptor - file type, accessibility, DF, ADF etc*/
- if (*ptr_data == 0x82) {
- /* increment to next byte */
- ptr_data++;
- /*2 or 5 value*/
- ptr_data++;
- /* unsigned char file_desc_len = *ptr_data++;*/
- /* dbg("file descriptor length: [%d]", file_desc_len);*/
- /* TBD: currently capture only file type : ignore sharable, non sharable, working, internal etc*/
- /* consider only last 3 bits*/
- file_type_tag = file_type_tag & (*ptr_data);
-
- switch (file_type_tag) {
- /* increment to next byte */
- ptr_data++;
- case 0x1:
- dbg("Getting FileType: [Transparent file type]");
- /* increment to next byte */
- ptr_data++;
- file_type = 0x01; //SIM_FTYPE_TRANSPARENT
- /* data coding byte - value 21 */
- ptr_data++;
- break;
-
- case 0x2:
- dbg("Getting FileType: [Linear fixed file type]");
- /* increment to next byte */
- ptr_data++;
- /* data coding byte - value 21 */
- ptr_data++;
- /* 2bytes */
- memcpy(&record_len, ptr_data, 2);
- /* swap bytes */
- SWAPBYTES16(record_len);
- ptr_data = ptr_data + 2;
- num_of_records = *ptr_data++;
- /* Data lossy conversation from enum (int) to unsigned char */
- file_type = 0x02; // SIM_FTYPE_LINEAR_FIXED
- break;
-
- case 0x6:
- dbg(" Cyclic fixed file type");
- /* increment to next byte */
- ptr_data++;
- /* data coding byte - value 21 */
- ptr_data++;
- /* 2bytes */
- memcpy(&record_len, ptr_data, 2);
- /* swap bytes */
- SWAPBYTES16(record_len);
- ptr_data = ptr_data + 2;
- num_of_records = *ptr_data++;
- file_type = 0x04; //SIM_FTYPE_CYCLIC
- break;
-
- default:
- dbg("not handled file type [0x%x]", *ptr_data);
- break;
- }
- } else {
- dbg("INVALID FCP received - DEbug!");
- return;
- }
-
- /*File identifier - file id?? */ // 0x84,0x85,0x86 etc are currently ignored and not handled
- if (*ptr_data == 0x83) {
- /* increment to next byte */
- ptr_data++;
- file_id_len = *ptr_data++;
- memcpy(&file_id, ptr_data, file_id_len);
- /* swap bytes */
- SWAPBYTES16(file_id);
- ptr_data = ptr_data + 2;
- dbg("Getting FileID=[0x%x]", file_id);
- } else {
- dbg("INVALID FCP received - DEbug!");
- free(recordData);
- ReleaseResponse();
- return;
- }
-
- /* proprietary information */
- if (*ptr_data == 0xA5) {
- unsigned short prop_len;
- /* increment to next byte */
- ptr_data++;
- /* length */
- prop_len = *ptr_data;
- /* skip data */
- ptr_data = ptr_data + prop_len + 1;
- } else {
- dbg("INVALID FCP received - DEbug!");
- }
-
- /* life cycle status integer [8A][length:0x01][status]*/
- /*
- status info b8~b1
- 00000000 : No information given
- 00000001 : creation state
- 00000011 : initialization state
- 000001-1 : operation state -activated
- 000001-0 : operation state -deactivated
- 000011-- : Termination state
- b8~b5 !=0, b4~b1=X : Proprietary
- Any other value : RFU
- */
- if (*ptr_data == 0x8A) {
- /* increment to next byte */
- ptr_data++;
- /* length - value 1 */
- ptr_data++;
-
- switch (*ptr_data) {
- case 0x04:
- case 0x06:
- dbg("<IPC_RX> operation state -deactivated");
- ptr_data++;
- break;
- case 0x05:
- case 0x07:
- dbg("<IPC_RX> operation state -activated");
- ptr_data++;
- break;
- default:
- dbg("<IPC_RX> DEBUG! LIFE CYCLE STATUS =[0x%x]",*ptr_data);
- ptr_data++;
- break;
- }
- }
-
- /* related to security attributes : currently not handled*/
- if (*ptr_data == 0x86 || *ptr_data == 0x8B || *ptr_data == 0x8C || *ptr_data == 0xAB) {
- /* increment to next byte */
- ptr_data++;
- /* if tag length is 3 */
- if (*ptr_data == 0x03) {
- /* increment to next byte */
- ptr_data++;
- /* EFARR file id */
- memcpy(&arr_file_id, ptr_data, 2);
- /* swap byes */
- SWAPBYTES16(arr_file_id);
- ptr_data = ptr_data + 2;
- arr_file_id_rec_num = *ptr_data++;
- } else {
- /* if tag length is not 3 */
- /* ignoring bytes */
- // ptr_data = ptr_data + 4;
- dbg("Useless security attributes, so jump to next tag");
- ptr_data = ptr_data + (*ptr_data + 1);
- }
- } else {
- dbg("INVALID FCP received[0x%x] - DEbug!", *ptr_data);
- free(recordData);
- ReleaseResponse();
- return;
- }
-
- dbg("Current ptr_data value is [%x]", *ptr_data);
-
- /* file size excluding structural info*/
- if (*ptr_data == 0x80) {
- /* for EF file size is body of file and for Linear or cyclic it is
- * number of recXsizeof(one record)
- */
- /* increment to next byte */
- ptr_data++;
- /* length is 1 byte - value is 2 bytes or more */
- ptr_data++;
- memcpy(&file_size, ptr_data, 2);
- /* swap bytes */
- SWAPBYTES16(file_size);
- ptr_data = ptr_data + 2;
- } else {
- dbg("INVALID FCP received - DEbug!");
- free(recordData);
- ReleaseResponse();
- return;
- }
-
- /* total file size including structural info*/
- if (*ptr_data == 0x81) {
- int len;
- /* increment to next byte */
- ptr_data++;
- /* length */
- len = *ptr_data;
- /* ignored bytes */
- ptr_data = ptr_data + 3;
- } else {
- dbg("INVALID FCP received - DEbug!");
- /* 0x81 is optional tag?? check out! so do not return -1 from here! */
- /* return -1; */
- }
- /*short file identifier ignored*/
- if (*ptr_data == 0x88) {
- dbg("0x88: Do Nothing");
- /*DO NOTHING*/
- }
- } else {
- dbg("INVALID FCP received - DEbug!");
- free(recordData);
- ReleaseResponse();
- return;
- }
- }
- else if (tcore_sim_get_type(co_sim) == SIM_TYPE_GSM)
- {
- unsigned char gsm_specific_file_data_len = 0;
- /* ignore RFU byte1 and byte2 */
- ptr_data++;
- ptr_data++;
- /* file size */
- //file_size = p_info->response_len;
- memcpy(&file_size, ptr_data, 2);
- /* swap bytes */
- SWAPBYTES16(file_size);
- /* parsed file size */
- ptr_data = ptr_data + 2;
- /* file id */
- memcpy(&file_id, ptr_data, 2);
- SWAPBYTES16(file_id);
- dbg(" FILE id --> [%x]", file_id);
- ptr_data = ptr_data + 2;
- /* save file type - transparent, linear fixed or cyclic */
- file_type_tag = (*(ptr_data + 7));
-
- switch (*ptr_data) {
- case 0x0:
- /* RFU file type */
- dbg(" RFU file type- not handled - Debug!");
- break;
- case 0x1:
- /* MF file type */
- dbg(" MF file type - not handled - Debug!");
- break;
- case 0x2:
- /* DF file type */
- dbg(" DF file type - not handled - Debug!");
- break;
- case 0x4:
- /* EF file type */
- dbg(" EF file type [%d] ", file_type_tag);
- /* increment to next byte */
- ptr_data++;
-
- if (file_type_tag == 0x00 || file_type_tag == 0x01) {
- /* increament to next byte as this byte is RFU */
- ptr_data++;
- file_type =
- (file_type_tag == 0x00) ? 0x01 : 0x02; // SIM_FTYPE_TRANSPARENT:SIM_FTYPE_LINEAR_FIXED;
- } else {
- /* increment to next byte */
- ptr_data++;
- /* For a cyclic EF all bits except bit 7 are RFU; b7=1 indicates that */
- /* the INCREASE command is allowed on the selected cyclic file. */
- file_type = 0x04; // SIM_FTYPE_CYCLIC;
- }
- /* bytes 9 to 11 give SIM file access conditions */
- ptr_data++;
- /* byte 10 has one nibble that is RF U and another for INCREASE which is not used currently */
- ptr_data++;
- /* byte 11 is invalidate and rehabilate nibbles */
- ptr_data++;
- /* byte 12 - file status */
- ptr_data++;
- /* byte 13 - GSM specific data */
- gsm_specific_file_data_len = *ptr_data;
- ptr_data++;
- /* byte 14 - structure of EF - transparent or linear or cyclic , already saved above */
- ptr_data++;
- /* byte 15 - length of record for linear and cyclic , for transparent it is set to 0x00. */
- record_len = *ptr_data;
- dbg("record length[%d], file size[%d]", record_len, file_size);
-
- if (record_len != 0)
- num_of_records = (file_size / record_len);
-
- dbg("Number of records [%d]", num_of_records);
- break;
-
- default:
- dbg(" not handled file type");
- break;
- }
- }
- else
- {
- dbg(" Card Type - UNKNOWN [%d]", tcore_sim_get_type(co_sim));
- }
-
- dbg("EF[0x%x] size[%ld] Type[0x%x] NumOfRecords[%ld] RecordLen[%ld]", file_id, file_size, file_type, num_of_records, record_len);
-
- respGetParamCnt.recordCount = num_of_records;
- respGetParamCnt.result = SMS_SUCCESS;
-
- smsp_record_len = tcore_plugin_ref_property(plugin, "SMSPRECORDLEN");
- memcpy(smsp_record_len, &record_len, sizeof(int));
-
- free(recordData);
- }
- else
- {
- /*2. SIM access fail case*/
- dbg("SIM access fail");
- respGetParamCnt.result = SMS_UNKNOWN;
- }
- }
- else
- {
- dbg("response error!!!");
- respGetParamCnt.result = SMS_UNKNOWN;
- }
-
- ReleaseResponse();
-
- tcore_user_request_send_response(ur, TRESP_SMS_GET_PARAMCNT, sizeof(struct tresp_sms_get_paramcnt), &respGetParamCnt);
-
- return;
-
-}
-
-/********************************************************/
-/*********************** Requests ************************/
-/********************************************************/
-static TReturn send_umts_msg(CoreObject *o, UserRequest *ur)
-{
- TcorePlugin *p = NULL;
- TcoreHal *h = NULL;
- TcorePending *pending = NULL;
- const struct treq_sms_send_umts_msg *sendUmtsMsg = NULL;
- char *cmd_str = NULL;
- struct ATReqMetaInfo metainfo;
- int info_len =0;
-
- dbg("new pending(IPC_SMS_SEND_MSG)");
-
- sendUmtsMsg = tcore_user_request_ref_data(ur, NULL);
-
- p = tcore_object_ref_plugin(o);
- h = tcore_object_get_hal(o);
-
- if (!sendUmtsMsg || !h)
- return TCORE_RETURN_ENOSYS;
-
- memset(&metainfo, 0, sizeof(struct ATReqMetaInfo));
- metainfo.type = NO_RESULT;
- metainfo.responsePrefix[0] ='\0';
- info_len = sizeof(struct ATReqMetaInfo);
-
- tcore_user_request_set_metainfo(ur, info_len, &metainfo);
-
- // AT+CMMS=<mode>
- cmd_str = g_strdup_printf("AT+CMMS=%d%s", sendUmtsMsg->more, "\r");
- dbg("[tcore_SMS] *************************MsgLen[%d]", sendUmtsMsg->msgDataPackage.msgLength);
-
- pending = tcore_pending_new(o, ID_RESERVED_AT);
- tcore_pending_set_request_data(pending, strlen(cmd_str), cmd_str);
- tcore_pending_set_timeout(pending, 0);
- tcore_pending_set_response_callback(pending, on_response_send_umts_msg, NULL);
- tcore_pending_link_user_request(pending, ur);
-
- tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
-
- free(cmd_str);
-
- return tcore_hal_send_request(h, pending);
-}
-
-static TReturn Send_SmsSubmitTpdu(CoreObject *o, UserRequest *ur)
-{
- TcorePlugin *p = NULL;
- TcoreHal *h = NULL;
- TcorePending *pending = NULL;
- const struct treq_sms_send_umts_msg *sendUmtsMsg = NULL;
- char *cmd_str = NULL;
- struct ATReqMetaInfo metainfo;
- int info_len =0;
- char tpdu[MAX_GSM_SMS_TPDU_SIZE];
- int ScLength = 0;
- char *hexString = NULL;
- int tpduDataLen = 0;
- int i = 0;
-
- TReturn api_err = TCORE_RETURN_SUCCESS;
-
- dbg("new pending(IPC_SMS_SEND_MSG)");
-
- sendUmtsMsg = tcore_user_request_ref_data(ur, NULL);
-
- p = tcore_object_ref_plugin(o);
- h = tcore_object_get_hal(o);
-
- if (!sendUmtsMsg || !h)
- return TCORE_RETURN_ENOSYS;
-
- /* Populate data */
- dbg("[tcore_SMS] MoreToSend[0x%x](1:Persist, 2:NotPersist) MsgLen[%d]",sendUmtsMsg->more, sendUmtsMsg->msgDataPackage.msgLength);
- for(i=0; i<sendUmtsMsg->msgDataPackage.msgLength; i++)
- dbg("[%02x]", sendUmtsMsg->msgDataPackage.tpduData[i]);
-
- if ((sendUmtsMsg->msgDataPackage.msgLength > 0) && (MAX_GSM_SMS_TPDU_SIZE > sendUmtsMsg->msgDataPackage.msgLength))
- {
- if (sendUmtsMsg->msgDataPackage.msgLength < SMS_SMDATA_SIZE_MAX)
- {
- memset(tpdu, 0, sizeof(MAX_GSM_SMS_TPDU_SIZE));
-
- memset(&metainfo, 0, sizeof(struct ATReqMetaInfo));
- metainfo.type = SINGLELINE;
- memcpy(metainfo.responsePrefix,"+CMGS:",strlen("+CMGS:"));
- info_len = sizeof(struct ATReqMetaInfo);
-
- tcore_user_request_set_metainfo(ur, info_len, &metainfo);
-
- ScLength = sendUmtsMsg->msgDataPackage.sca[0];
- if(sendUmtsMsg->msgDataPackage.sca[0] == 0)
- {
- memcpy(&tpdu[0], sendUmtsMsg->msgDataPackage.sca, ScLength+2);
- }
- else
- {
- dbg("SC length in ipc tx is %d - before", ScLength);
-
- util_sms_get_length_of_sca(&ScLength);
-
- dbg(" SC length in ipc tx is %d - after", ScLength);
-
- tpdu[0] = ScLength +1 ;
- //1Copy SCA to the ipc stream first
- memcpy(&(tpdu[1]), &( sendUmtsMsg->msgDataPackage.sca[1]), (ScLength + 1));
- }
-
- if ((ScLength <= SMS_SMSP_ADDRESS_LEN) && (sendUmtsMsg->msgDataPackage.msgLength < SMS_SMDATA_SIZE_MAX))
- {
- //1Copy rest of the SMS-SUBMIT TPDU
- memcpy(&(tpdu[ScLength + 2]), sendUmtsMsg->msgDataPackage.tpduData, sendUmtsMsg->msgDataPackage.msgLength);
- } else
- {
- dbg("SCA len is %d", ScLength);
- api_err = TCORE_RETURN_SMS_INVALID_DATA_LEN;
- return api_err;
- }
-
- tpduDataLen = sendUmtsMsg->msgDataPackage.msgLength + (ScLength + 2);
- hexString = calloc(tpduDataLen*2, 1);;
-
- for( i=0; i<tpduDataLen*2; i+=2)
- {
- char value = 0;
-
- value = (tpdu[i/2] & 0xf0 ) >> 4;
- if(value < 0xA)
- hexString[i] = ((tpdu[i/2] & 0xf0 ) >> 4) + '0';
- else hexString[i] = ((tpdu[i/2] & 0xf0 ) >> 4) + 'A' -10;
-
- value = tpdu[i/2] & 0x0f;
- if(value < 0xA)
- hexString[i+1] = (tpdu[i/2] & 0x0f ) + '0';
- else hexString[i+1] = (tpdu[i/2] & 0x0f ) + 'A' -10;
-
- }
-
- // AT+CMGS=<length><CR>pdu_is_given<ctrl-z/ESC>
- cmd_str = g_strdup_printf("AT+CMGS=%d%s%s%x%s", sendUmtsMsg->msgDataPackage.msgLength, "\r", hexString, 0x1A,"\r");
- dbg("cmd_str is %s", cmd_str);
-
- pending = tcore_pending_new(o, ID_RESERVED_AT);
- tcore_pending_set_request_data(pending, strlen(cmd_str), cmd_str);
- tcore_pending_set_timeout(pending, 0);
- tcore_pending_set_response_callback(pending, on_response_send_smsSubmitTpdu, NULL);
- tcore_pending_link_user_request(pending, ur);
-
- tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
-
- api_err = tcore_hal_send_request(h, pending);
-
- free(cmd_str);
- free(hexString);
- }
- else
- {
- dbg("[tcore_SMS] TPDU size[%d] is over !!!, max is [%d]", sendUmtsMsg->msgDataPackage.msgLength, SMS_SMDATA_SIZE_MAX);
- api_err = TCORE_RETURN_SMS_INVALID_DATA_LEN;
- return api_err;
- }
- }
- else
- {
- dbg("[tcore_SMS] Invalid Data Length");
- api_err = TCORE_RETURN_SMS_INVALID_DATA_LEN;
- }
-
- return api_err;
-
-}
-
-static TReturn send_cdma_msg(CoreObject *o, UserRequest *ur)
-{
- dbg("[tcore_SMS] Not supported");
- return TCORE_RETURN_ENOSYS;}
-
-static TReturn read_msg(CoreObject *o, UserRequest *ur)
-{
- dbg("[tcore_SMS] Not supported");
- return TCORE_RETURN_ENOSYS;
-}
-
-static TReturn save_msg(CoreObject *o, UserRequest *ur)
-{
- dbg("[tcore_SMS] Not supported");
- return TCORE_RETURN_ENOSYS;
-}
-
-static TReturn delete_msg(CoreObject *o, UserRequest *ur)
-{
- dbg("[tcore_SMS] Not supported");
- return TCORE_RETURN_ENOSYS;
-}
-
-static TReturn get_storedMsgCnt(CoreObject *o, UserRequest *ur)
-{
- TcorePlugin *p = NULL;
- TcoreHal *h = NULL;
- TcorePending *pending = NULL;
- const struct treq_sms_get_msg_count *getStoredMsgCnt = NULL;
-
- char *cmd_str = NULL;
- struct ATReqMetaInfo metainfo;
- int info_len =0;
-
- dbg("new pending(IPC_SMS_GET_STORED_MSG_COUNT)");
-
- getStoredMsgCnt = tcore_user_request_ref_data(ur, NULL);
-
- p = tcore_object_ref_plugin(o);
- h = tcore_object_get_hal(o);
-
- if (!h)
- {
- dbg("[ERR] tcore_object_get_hal() pointer is NULL");
- return TCORE_RETURN_ENOSYS;
- }
-
- memset(&metainfo, 0, sizeof(struct ATReqMetaInfo));
- metainfo.type = SINGLELINE;
- memcpy(metainfo.responsePrefix,"+CPMS:",strlen("+CPMS:"));
- info_len = sizeof(struct ATReqMetaInfo);
-
- tcore_user_request_set_metainfo(ur, info_len, &metainfo);
-
- // AT+CPMS=<mem1>[,<mem2>[,<mem3>]]
- // Possible response(s) : +CPMS: <used1>,<total1>,<used2>,<total2>,<used3>,<total3>
- cmd_str = g_strdup_printf("AT+CPMS=\"SM\"%s", "\r");
-
- pending = tcore_pending_new(o, ID_RESERVED_AT);
- tcore_pending_set_request_data(pending, strlen(cmd_str), cmd_str);
- tcore_pending_set_timeout(pending, 0);
- tcore_pending_set_response_callback(pending, on_response_get_storedMsgCnt, NULL);
- tcore_pending_link_user_request(pending, ur);
-
- tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
-
- free(cmd_str);
-
- return tcore_hal_send_request(h, pending);
-
-}
-
-static TReturn get_sca(CoreObject *o, UserRequest *ur)
-{
- TcorePlugin *p = NULL;
- TcoreHal *h = NULL;
- TcorePending *pending = NULL;
- const struct treq_sms_get_sca *getSca = NULL;
- char *cmd_str = NULL;
- struct ATReqMetaInfo metainfo;
- int info_len =0;
-
- dbg("new pending(IPC_SMS_GET_SCA)");
-
- getSca = tcore_user_request_ref_data(ur, NULL);
-
- p = tcore_object_ref_plugin(o);
- h = tcore_object_get_hal(o);
-
- if (!getSca || !h)
- return TCORE_RETURN_ENOSYS;
-
- memset(&metainfo, 0, sizeof(struct ATReqMetaInfo));
- metainfo.type = SINGLELINE;
- memcpy(metainfo.responsePrefix,"+CSCA:",strlen("+CSCA:"));
- info_len = sizeof(struct ATReqMetaInfo);
-
- tcore_user_request_set_metainfo(ur, info_len, &metainfo);
-
- // AT +CSCA?
- // Possible response(s) : +CSCA: <sca number>,<sca type>
- cmd_str = g_strdup_printf("AT +CSCA?%s", "\r");
-
- pending = tcore_pending_new(o, ID_RESERVED_AT);
- tcore_pending_set_request_data(pending, strlen(cmd_str), cmd_str);
- tcore_pending_set_timeout(pending, 0);
- tcore_pending_set_response_callback(pending, on_response_get_sca, NULL);
- tcore_pending_link_user_request(pending, ur);
-
- tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
-
- free(cmd_str);
-
- return tcore_hal_send_request(h, pending);
-
-}
-
-static TReturn set_sca(CoreObject *o, UserRequest *ur)
-{
- TcorePlugin *p = NULL;
- TcoreHal *h = NULL;
- TcorePending *pending = NULL;
- const struct treq_sms_set_sca *setSca;
- int scaType = 0;
- char *cmd_str = NULL;
- struct ATReqMetaInfo metainfo;
- int info_len =0;
-
- dbg("new pending(IPC_SMS_SET_SCA)");
-
- setSca = tcore_user_request_ref_data(ur, NULL);
-
- if(setSca->index != 0){
- dbg("Index except 0 is supported");
- return TCORE_RETURN_EINVAL; // TCORE_API_NOT_SUPPORTED;
- }
-
- p = tcore_object_ref_plugin(o);
- h = tcore_object_get_hal(o);
-
- if (!setSca || !h)
- return TCORE_RETURN_ENOSYS;
-
- if(setSca->scaInfo.typeOfNum == SIM_TON_INTERNATIONAL)
- scaType = 145;
- else scaType = 129;
-
- memset(&metainfo, 0, sizeof(struct ATReqMetaInfo));
- metainfo.type = NO_RESULT;
- metainfo.responsePrefix[0] ='\0';
- info_len = sizeof(struct ATReqMetaInfo);
-
- tcore_user_request_set_metainfo(ur, info_len, &metainfo);
-
- // AT +CSCA=<sca number>[,<sca type>]
- // 129:Unknown numbering plan, national/international number unknown, 145:international number
- cmd_str = g_strdup_printf("AT+CSCA=\"%s\", %d%s", setSca->scaInfo.diallingNum, scaType, "\r");
-
- pending = tcore_pending_new(o, ID_RESERVED_AT);
- tcore_pending_set_request_data(pending, strlen(cmd_str), cmd_str);
- tcore_pending_set_timeout(pending, 0);
- tcore_pending_set_response_callback(pending, on_response_set_sca, NULL);
- tcore_pending_link_user_request(pending, ur);
-
- tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
-
- free(cmd_str);
-
- return tcore_hal_send_request(h, pending);
-
-}
-
-static TReturn get_cb_config(CoreObject *o, UserRequest *ur)
-{
- dbg("[tcore_SMS] Not supported");
- return TCORE_RETURN_ENOSYS;
-}
-
-static TReturn set_cb_config(CoreObject *o, UserRequest *ur)
-{
- dbg("[tcore_SMS] Not supported");
- return TCORE_RETURN_ENOSYS;
-}
-
-static TReturn set_mem_status(CoreObject *o, UserRequest *ur)
-{
- dbg("[tcore_SMS] Not supported");
- return TCORE_RETURN_ENOSYS;
-}
-
-static TReturn get_pref_brearer(CoreObject *o, UserRequest *ur)
-{
- dbg("[tcore_SMS] Not supported");
- return TCORE_RETURN_ENOSYS;
-}
-
-static TReturn set_pref_brearer(CoreObject *o, UserRequest *ur)
-{
- dbg("[tcore_SMS] Not supported");
- return TCORE_RETURN_ENOSYS;
-}
-
-static TReturn set_delivery_report(CoreObject *o, UserRequest *ur)
-{
- TcorePlugin *p = NULL;
- TcoreHal *h = NULL;
- TcorePending *pending = NULL;
- const struct treq_sms_set_delivery_report *deliveryReport = NULL;
- char *cmd_str;
- struct ATReqMetaInfo metainfo;
- int info_len =0;
-
- dbg("new pending(IPC_SMS_SVC_CENTER_ADDR)");
-
- deliveryReport = tcore_user_request_ref_data(ur, NULL);
-
- p = tcore_object_ref_plugin(o);
- h = tcore_object_get_hal(o);
-
- if (!deliveryReport || !h)
- return TCORE_RETURN_ENOSYS;
-
- memset(&metainfo, 0, sizeof(struct ATReqMetaInfo));
- metainfo.type = NO_RESULT;
- metainfo.responsePrefix[0] ='\0';
- info_len = sizeof(struct ATReqMetaInfo);
-
- tcore_user_request_set_metainfo(ur, info_len, &metainfo);
-
- // AT+CNMA
- if(deliveryReport->rspType == SMS_SENDSMS_SUCCESS)
- cmd_str = g_strdup_printf("AT+CNMA=0%s", "\r");
- else
- cmd_str = g_strdup_printf("AT+CNMA=2,3%s%x%s", "/n", 0x00ff00, "");
-
- pending = tcore_pending_new(o, ID_RESERVED_AT);
- tcore_pending_set_request_data(pending, strlen(cmd_str), cmd_str);
- tcore_pending_set_timeout(pending, 0);
- tcore_pending_set_response_callback(pending, on_response_set_delivery_report, NULL);
- tcore_pending_link_user_request(pending, ur);
-
- tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
-
- free(cmd_str);
-
- return tcore_hal_send_request(h, pending);
-
-}
-
-static TReturn set_msg_status(CoreObject *o, UserRequest *ur)
-{
- dbg("[tcore_SMS] Not supported");
- return TCORE_RETURN_ENOSYS;
-}
-
-static TReturn get_sms_params(CoreObject *o, UserRequest *ur)
-{
- TcorePlugin *p = NULL;
- TcoreHal *h = NULL;
- TcorePending *pending = NULL;
- const struct treq_sms_get_params *getSmsParams = NULL;
-
- char *cmd_str = NULL;
- struct ATReqMetaInfo metainfo;
- int info_len =0;
-
- dbg("new pending(IPC_SMS_GET_CBS_CFG)");
-
- getSmsParams = tcore_user_request_ref_data(ur, NULL);
-
- p = tcore_object_ref_plugin(o);
- h = tcore_object_get_hal(o);
-
- if (!getSmsParams || !h)
- {
- dbg("[ERR] pointer is NULL, getSmsParams=0x%x, h=0x%x", getSmsParams, h);
- return TCORE_RETURN_ENOSYS;
- }
-
- memset(&metainfo, 0, sizeof(struct ATReqMetaInfo));
- metainfo.type = SINGLELINE;
- memcpy(metainfo.responsePrefix,"+CRSM:",strlen("+CRSM:"));
- info_len = sizeof(struct ATReqMetaInfo);
-
- tcore_user_request_set_metainfo(ur, info_len, &metainfo);
-
- // AT+CRSM=<command>,<fildid>,<p1>,<p2+C29,<p3>
- cmd_str = g_strdup_printf("AT+CRSM=%d, %d, %d, 4, 40%s", 178, 0x6F42, getSmsParams->index + 1, "\r");
-
- pending = tcore_pending_new(o, ID_RESERVED_AT);
- tcore_pending_set_request_data(pending, strlen(cmd_str), cmd_str);
- tcore_pending_set_timeout(pending, 0);
- tcore_pending_set_response_callback(pending, on_response_get_sms_params, NULL);
- tcore_pending_link_user_request(pending, ur);
-
- tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
-
- free(cmd_str);
-
- return tcore_hal_send_request(h, pending);
-
-}
-
-static TReturn set_sms_params(CoreObject *o, UserRequest *ur)
-{
- TcorePending *pending;
- const struct treq_sms_set_params *setSmsParams;
- struct ATReqMetaInfo metainfo;
- int *smsp_record_len;
- int SMSPRecordLen;
- unsigned char *temp_data;
- char *encoded_data;
- int info_len;
- char *cmd_str;
- int encoded_data_len;
- TcorePlugin *plugin = tcore_object_ref_plugin(o);
- TcoreHal *hal = tcore_object_get_hal(o);
-
- dbg("Enter");
-
- setSmsParams = tcore_user_request_ref_data(ur, NULL);
- smsp_record_len = tcore_plugin_ref_property(plugin, "SMSPRECORDLEN");
- SMSPRecordLen = *smsp_record_len;
-
- memset(&metainfo, 0, sizeof(struct ATReqMetaInfo));
- metainfo.type = SINGLELINE;
- memcpy(metainfo.responsePrefix, "+CRSM:", strlen("+CRSM:"));
- info_len = sizeof(struct ATReqMetaInfo);
- tcore_user_request_set_metainfo(ur, info_len, &metainfo);
-
- temp_data = calloc(SMSPRecordLen, 1);
- encoded_data = calloc(SMSPRecordLen * 2 + 1, 1);
-
- _tcore_util_sms_encode_smsParameters(&(setSmsParams->params),
- temp_data, SMSPRecordLen);
- util_byte_to_hex((const char *)temp_data,
- (char *)encoded_data, SMSPRecordLen);
-
- encoded_data_len = SMSPRecordLen * 2;
-
- cmd_str = g_strdup_printf("AT+CRSM=220,28482,%d,4,%d,\"%s\"\r",
- setSmsParams->params.recordIndex + 1,
- SMSPRecordLen, encoded_data);
-
- pending = tcore_pending_new(o, ID_RESERVED_AT);
- tcore_pending_set_request_data(pending, strlen(cmd_str), cmd_str);
- tcore_pending_set_response_callback(pending, on_response_set_sms_params, NULL);
- tcore_pending_link_user_request(pending, ur);
- tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
-
- free(cmd_str);
- free(temp_data);
- free(encoded_data);
-
- return tcore_hal_send_request(hal, pending);
-}
-
-static TReturn get_paramcnt(CoreObject *o, UserRequest *ur)
-{
- TcorePlugin *p = NULL;
- TcoreHal *h = NULL;
- TcorePending *pending = NULL;
- const struct treq_sms_get_paramcnt *getParamCnt = NULL;
-
- char *cmd_str = NULL;
- struct ATReqMetaInfo metainfo;
- int info_len =0;
-
- getParamCnt = tcore_user_request_ref_data(ur, NULL);
-
- p = tcore_object_ref_plugin(o);
- h = tcore_object_get_hal(o);
-
- if (!h) // request data is NULL, so do not NULL check for getParamCnt
- {
- dbg("[ERR] pointer is NULL, getParamCnt=0x%x, h=0x%x", getParamCnt, h);
- return TCORE_RETURN_ENOSYS;
- }
-
- memset(&metainfo, 0, sizeof(struct ATReqMetaInfo));
- metainfo.type = SINGLELINE;
- memcpy(metainfo.responsePrefix,"+CRSM:",strlen("+CRSM:"));
- info_len = sizeof(struct ATReqMetaInfo);
-
- tcore_user_request_set_metainfo(ur, info_len, &metainfo);
-
- // AT+CRSM=<command>,<fildid>,<p1>,<p2+C29,<p3>, EFsmsp: 0x6F42
- cmd_str = g_strdup_printf("AT+CRSM=192, %d%s", 0x6F42, "\r");
-
- pending = tcore_pending_new(o, ID_RESERVED_AT);
- tcore_pending_set_request_data(pending, strlen(cmd_str), cmd_str);
- tcore_pending_set_timeout(pending, 0);
- tcore_pending_set_response_callback(pending, on_response_get_paramcnt, NULL);
- tcore_pending_link_user_request(pending, ur);
-
- tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
-
- free(cmd_str);
-
- return tcore_hal_send_request(h, pending);
-}
-
-static struct tcore_sms_operations sms_ops =
-{
- .send_umts_msg = send_umts_msg,
- .read_msg = read_msg,
- .save_msg = save_msg,
- .delete_msg = delete_msg,
- .get_stored_msg_cnt = get_storedMsgCnt,
- .get_sca = get_sca,
- .set_sca = set_sca,
- .get_cb_config = get_cb_config,
- .set_cb_config = set_cb_config,
- .set_mem_status = set_mem_status,
- .get_pref_brearer = get_pref_brearer,
- .set_pref_brearer = set_pref_brearer,
- .set_delivery_report = set_delivery_report,
- .set_msg_status = set_msg_status,
- .get_sms_params = get_sms_params,
- .set_sms_params = set_sms_params,
- .get_paramcnt = get_paramcnt,
- .send_cdma_msg = send_cdma_msg,
-};
-
-gboolean s_sms_init(TcorePlugin *cp, CoreObject *co)
-{
- int *smsp_record_len;
- GQueue *work_queue;
-
- dbg("Entry");
-
- /* Override SMS Operations */
- tcore_sms_override_ops(co, &sms_ops);
-
- work_queue = g_queue_new();
- tcore_object_link_user_data(co, work_queue);
-
- tcore_object_override_callback(co, EVENT_SMS_INCOM_MSG, on_event_sms_incom_msg, NULL);
- tcore_object_override_callback(co, EVENT_SMS_DEVICE_READY, on_event_sms_device_ready, NULL);
-
- /* Storing SMSP record length */
- smsp_record_len = g_new0(int, 1);
- tcore_plugin_link_property(cp, "SMSPRECORDLEN", smsp_record_len);
-
- dbg("Exit");
-
- return TRUE;
-}
-
-void s_sms_exit(TcorePlugin *cp, CoreObject *co)
-{
- GQueue *work_queue;
- int *smsp_record_len;
-
- smsp_record_len = tcore_plugin_ref_property(cp, "SMSPRECORDLEN");
- g_free(smsp_record_len);
-
- work_queue = tcore_object_ref_user_data(co);
- if (work_queue)
- g_queue_free(work_queue);
-
- dbg("Exit");
-}
-
+++ /dev/null
-/*
- * tel-plugin-atmodem
- *
- * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: Hayoon Ko <hayoon.ko@samsung.com>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <glib.h>
-
-#include <tcore.h>
-#include <hal.h>
-#include <core_object.h>
-#include <plugin.h>
-#include <queue.h>
-#include <co_call.h>
-#include <co_ss.h>
-#include <user_request.h>
-#include <server.h>
-
-#include "s_common.h"
-#include "s_ss.h"
-#include "util.h"
-
-#include "atchannel.h"
-#include "at_tok.h"
-
-extern struct ATResponse *sp_response;
-extern char *s_responsePrefix;
-extern enum ATCommandType s_type;
-
-
-gboolean gcf = FALSE;
-
-enum telephony_ss_opcode {
- TIZEN_SS_OPCO_REG=0x01, /* 0x01 : Registration */
- TIZEN_SS_OPCO_DEREG, /* 0x02 : De-registration( erase ) */
- TIZEN_SS_OPCO_ACTIVATE, /* 0x03 : Activation */
- TIZEN_SS_OPCO_DEACTIVATE, /* 0x04 : De-activation */
- TIZEN_SS_OPCO_MAX
-} ;
-
-
-struct ss_confirm_info {
- enum telephony_ss_class class;
- int flavor_type;
- enum tcore_response_command resp;
- void *data;
- int data_len;
-};
-
-#define TIZEN_NUM_TYPE_INTERNATIONAL 0x01
-#define TIZEN_NUM_PLAN_ISDN 0x01
-
-
-static gboolean _ss_request_message( CoreObject *o,
- UserRequest *ur,
- char *cmd,
- unsigned int cmd_len,
- void* on_resp,
- void* user_data );
-#if 0
-static TReturn _ss_general_response_result(const int result);
-#endif
-
-static TReturn _ss_barring_get( CoreObject *o,
- UserRequest *ur,
- enum telephony_ss_class class,
- enum telephony_ss_barring_mode type,
- enum tcore_response_command resp );
-
-static TReturn _ss_forwarding_get( CoreObject *o,
- UserRequest *ur,
- enum telephony_ss_class class,
- enum telephony_ss_forwarding_mode type,
- enum tcore_response_command resp );
-
-static TReturn _ss_waiting_get( CoreObject *o,
- UserRequest *ur,
- enum telephony_ss_class class,
- enum tcore_response_command resp );
-
-
-static TReturn s_ss_barring_activate( CoreObject *o, UserRequest *ur );
-static TReturn s_ss_barring_deactivate( CoreObject *o, UserRequest *ur );
-static TReturn s_ss_barring_change_password( CoreObject *o, UserRequest *ur );
-static TReturn s_ss_barring_get_status( CoreObject *o, UserRequest *ur );
-
-static TReturn s_ss_forwarding_activate( CoreObject *o, UserRequest *ur );
-static TReturn s_ss_forwarding_deactivate( CoreObject *o, UserRequest *ur );
-static TReturn s_ss_forwarding_register( CoreObject *o, UserRequest *ur );
-static TReturn s_ss_forwarding_deregister( CoreObject *o, UserRequest *ur );
-static TReturn s_ss_forwarding_get_status( CoreObject *o, UserRequest *ur );
-
-static TReturn s_ss_waiting_activate( CoreObject *o, UserRequest *ur );
-static TReturn s_ss_waiting_deactivate( CoreObject *o, UserRequest *ur );
-static TReturn s_ss_waiting_get_status( CoreObject *o, UserRequest *ur );
-
-static TReturn s_ss_cli_activate( CoreObject *o, UserRequest *ur );
-static TReturn s_ss_cli_deactivate( CoreObject *o, UserRequest *ur );
-static TReturn s_ss_cli_get_status( CoreObject *o, UserRequest *ur );
-
-static TReturn s_ss_send_ussd( CoreObject *o, UserRequest *ur );
-
-static TReturn s_ss_set_aoc( CoreObject *o, UserRequest *ur );
-static TReturn s_ss_get_aoc( CoreObject *o, UserRequest *ur );
-
-static TReturn s_ss_manage_call_0_send( CoreObject* o, UserRequest* ur, ConfirmCallback cb, void* user_data );
-static TReturn s_ss_manage_call_1_send( CoreObject* o, UserRequest* ur, ConfirmCallback cb, void* user_data );
-static TReturn s_ss_manage_call_1x_send( CoreObject* o, UserRequest* ur, const int id, ConfirmCallback cb, void* user_data );
-static TReturn s_ss_manage_call_2_send( CoreObject* o, UserRequest* ur, ConfirmCallback cb, void* user_data );
-static TReturn s_ss_manage_call_2x_send( CoreObject* o, UserRequest* ur, const int id, ConfirmCallback cb, void* user_data );
-static TReturn s_ss_manage_call_3_send( CoreObject* o, UserRequest* ur, ConfirmCallback cb, void* user_data );
-static TReturn s_ss_manage_call_4_send( CoreObject* o, UserRequest* ur, ConfirmCallback cb, void* user_data );
-static TReturn s_ss_manage_call_4dn_send( CoreObject* o, UserRequest* ur, const char* number, ConfirmCallback cb, void* user_data );
-/*
-static TReturn s_ss_manage_call_5_send( CoreObject* o, UserRequest* ur, ConfirmCallback cb, void* user_data );
-static TReturn s_ss_manage_call_6_send( CoreObject* o, UserRequest* ur, ConfirmCallback cb, void* user_data );
-*/
-
-static void on_confirmation_call_control_ss_message_send( TcorePending *p, gboolean result, void *user_data );
-
-static void on_confirmation_ss_message_send( TcorePending *p, gboolean result, void *user_data );
-
-
-static gboolean on_notification_ss_info( CoreObject *o, const void *data, void *user_data );
-
-static void _ss_ussd_response( UserRequest *ur, const char* ussd_str, enum telephony_ss_ussd_type type, enum telephony_ss_ussd_status status );
-static void _ss_ussd_notification( TcorePlugin *p, const char* ussd_str, enum telephony_ss_ussd_status status );
-static gboolean on_notification_ss_ussd( CoreObject *o, const void *data, void *user_data );
-
-
-static gboolean _ss_request_message( CoreObject *o,
- UserRequest *ur,
- char *cmd,
- unsigned int cmd_len,
- void* on_resp,
- void* user_data )
-{
- TcorePending *pending = 0;
- TcorePlugin *p = 0;
- TcoreHal *h = 0;
- UserRequest *ur2 = 0;
-
- ur2 = tcore_user_request_ref( ur );
-
- pending = tcore_pending_new(o, ID_RESERVED_AT);
- tcore_pending_set_request_data(pending, cmd_len, cmd);
- tcore_pending_set_timeout(pending, 0);
-
- if ( on_resp )
- tcore_pending_set_response_callback(pending, on_resp, user_data);
-
- tcore_pending_set_send_callback(pending, on_confirmation_ss_message_send, 0);
-
- if ( !ur2 ) {
- dbg("[ check ] ur is 0, is this internal request??");
- } else {
- tcore_pending_link_user_request(pending, ur2);
- }
-
- p = tcore_object_ref_plugin(o);
- h = tcore_object_get_hal(o);
- tcore_hal_send_request(h, pending);
-
- return TRUE;
-}
-
-#if 0
-static TReturn _ss_general_response_result(const int ret)
-{
- if (ret == 0x8000 || ret == 0x8100) {
- return TCORE_RETURN_SUCCESS;
- }
-
- return TCORE_RETURN_3GPP_ERROR + ret;
-}
-#endif
-
-static void _ss_ussd_response( UserRequest *ur, const char* ussd_str, enum telephony_ss_ussd_type type, enum telephony_ss_ussd_status status )
-{
- struct tresp_ss_ussd resp;
-
- if ( !ur ) {
- dbg("[ error ] ur : (NULL)");
- return ;
- }
-
- resp.type = type;
- resp.status = status;
- resp.err = SS_ERROR_NONE;
-
- if ( ussd_str ) {
-
- int len = strlen( ussd_str );
-
- if ( len < MAX_SS_USSD_LEN ) {
- memcpy( resp.str, ussd_str, len );
- resp.str[ len ] = '\0';
- } else {
- memcpy( resp.str, ussd_str, MAX_SS_USSD_LEN );
- resp.str[ MAX_SS_USSD_LEN - 1 ] = '\0';
- }
-
- dbg("resp.str : %s", resp.str);
-
- } else {
-
- memset( resp.str, '\0', MAX_SS_USSD_LEN );
-
- }
-
- tcore_user_request_send_response(ur, TRESP_SS_SEND_USSD, sizeof(struct tresp_ss_ussd), &resp);
-}
-
-static void _ss_ussd_notification( TcorePlugin *p, const char* ussd_str, enum telephony_ss_ussd_status status )
-{
- CoreObject *o = 0;
- struct tnoti_ss_ussd noti;
-
- if ( !p ) {
- dbg("[ error ] p : (NULL)");
- return ;
- }
-
- noti.status = status;
-
- if ( ussd_str ) {
-
- int len = strlen( ussd_str );
-
- if ( len < MAX_SS_USSD_LEN ) {
- memcpy( noti.str, ussd_str, len );
- noti.str[ len ] = '\0';
- } else {
- memcpy( noti.str, ussd_str, MAX_SS_USSD_LEN );
- noti.str[ MAX_SS_USSD_LEN - 1 ] = '\0';
- }
-
- } else {
-
- memset( noti.str, '\0', MAX_SS_USSD_LEN );
-
- }
-
- o = tcore_plugin_ref_core_object(p, CORE_OBJECT_TYPE_SS);
-
- tcore_server_send_notification( tcore_plugin_ref_server(p),
- o,
- TNOTI_SS_USSD,
- sizeof(struct tnoti_ss_ussd),
- (void*)¬i );
-
-}
-
-static gboolean on_notification_ss_ussd( CoreObject *o, const void *data, void *user_data )
-{
- enum telephony_ss_ussd_status status;
- UssdSession *ussd_session = 0;
- char *ussd_str = 0, *cmd = 0, *tmp_str=0;
- TcorePlugin *p = 0;
- int err =0, m=0, dcs=0;
-
- p = tcore_object_ref_plugin(o);
-
- ussd_session = tcore_ss_ussd_get_session(o);
-
- cmd = (char*)data;
-
- // parse ussd status
- at_tok_start(&cmd);
- err = at_tok_nextint(&cmd, &m);
- dbg("m: %d", m);
-
- switch(m){
- case 0:
- status = SS_USSD_NO_ACTION_REQUIRE;
- break;
-
- case 1:
- status = SS_USSD_ACTION_REQUIRE;
- break;
-
- case 2:
- status = SS_USSD_TERMINATED_BY_NET;
- break;
-
- case 3:
- status = SS_USSD_OTHER_CLIENT;
- break;
-
- case 4:
- status = SS_USSD_NOT_SUPPORT;
- break;
-
- case 5:
- status = SS_USSD_TIME_OUT;
- break;
-
- default:
- dbg("unsupported m : %d", m);
- status = SS_USSD_MAX;
- break;
- }
-
- if(at_tok_hasmore(&cmd))
- {
- err = at_tok_nextstr(&cmd, &tmp_str);
- err = at_tok_nextint(&cmd, &dcs);
-
- dbg("ussdstr: %s, dcs :%d", tmp_str, dcs);
- }
-
- switch ( tcore_util_get_cbs_coding_scheme(dcs) ) {
- case TCORE_DCS_TYPE_7_BIT:
- case TCORE_DCS_TYPE_UNSPECIFIED: {
- ussd_str = (char *)tcore_util_unpack_gsm7bit((const unsigned char *)tmp_str, strlen(tmp_str));
- } break;
-
- case TCORE_DCS_TYPE_UCS2:
- case TCORE_DCS_TYPE_8_BIT: {
- if ( strlen(tmp_str) > 0 ) {
- ussd_str = g_new0( char, strlen(tmp_str) + 1);
- memcpy( ussd_str,tmp_str, strlen(tmp_str) );
- ussd_str[ strlen(tmp_str) ] = '\0';
- }
- } break;
- default: {
- dbg("[ error ] unknown dcs type. ussd_session : %x", ussd_session);
- if ( ussd_session ) {
-
- UserRequest *ur = 0;
- enum telephony_ss_ussd_type type;
-
- tcore_ss_ussd_get_session_data( ussd_session, (void**)&ur );
- if ( !ur ) {
- dbg("[ error ] ur : (0)");
- return TRUE;
- }
-
- type = (enum telephony_ss_ussd_type)tcore_ss_ussd_get_session_type( ussd_session );
-
- _ss_ussd_response( ur, ussd_str, type, status );
- }
- return TRUE;
- }
- }
-
- switch ( status ) {
- case SS_USSD_NO_ACTION_REQUIRE:
- case SS_USSD_ACTION_REQUIRE:
- case SS_USSD_OTHER_CLIENT:
- case SS_USSD_NOT_SUPPORT:
- case SS_USSD_TIME_OUT: {
-
- // UserRequest *ur = 0;
-
- if ( ussd_session ) {
-
- UserRequest *ur = 0;
- enum telephony_ss_ussd_type type;
-
- tcore_ss_ussd_get_session_data( ussd_session, (void**)&ur );
- if ( !ur ) {
- dbg("[ error ] ur : (0)");
- return TRUE;
- }
-
- type = (enum telephony_ss_ussd_type)tcore_ss_ussd_get_session_type( ussd_session );
-
- _ss_ussd_response( ur, (const char*)ussd_str, type, status );
-
- g_free( ussd_str );
-
- } else {
-
- tcore_ss_ussd_create_session( o, TCORE_SS_USSD_TYPE_NETWORK_INITIATED, 0, 0 );
-
- _ss_ussd_notification( p, (const char*)ussd_str, status );
-
- g_free( ussd_str );
- }
-
- } break;
- case SS_USSD_TERMINATED_BY_NET: {
-
- if ( ussd_session ) {
- UserRequest *ur = 0;
-
- tcore_ss_ussd_get_session_data( ussd_session, (void**)&ur );
-
- if ( ur )
- tcore_user_request_unref( ur );
-
- tcore_ss_ussd_destroy_session( ussd_session );
- }
-
- } break;
- default:
- break;
- }
-
- return TRUE;
-}
-
-static gboolean on_notification_ss_info( CoreObject *o, const void *data, void *user_data )
-{
- TcorePlugin *p = 0;
- CoreObject *co = 0;
- char* cmd = 0, *number = 0;
- int code2 =0, err=0, index=0, ton=0;
-
-
- p = tcore_object_ref_plugin( o );
- co = tcore_plugin_ref_core_object( p, CORE_OBJECT_TYPE_CALL );
- if (!co) {
- dbg("[ error ] plugin_ref_core_object : call");
- return TRUE;
- }
-
- cmd = (char*)data;
- at_tok_start(&cmd);
-
- err = at_tok_nextint(&cmd, &code2);
- dbg("code2 : %d",code2);
-
- if(at_tok_hasmore(&cmd))
- err = at_tok_nextint(&cmd, &index); //cug index - skip
- if(at_tok_hasmore(&cmd)){
- err = at_tok_nextstr(&cmd, &number);
- dbg("number : %s",number);
- err = at_tok_nextint(&cmd, &ton);
- }
-
- switch(code2){
- case 0: //this is a forwarded call (MT call setup)
- tcore_call_information_mt_forwarded_call( co, number );
- break;
-
- case 2: //call has been put on hold (during a voice call)
- tcore_call_information_held( co, number );
- break;
-
- case 3: //call has been retrieved (during a voice call)
- tcore_call_information_active( co, number );
- break;
-
- case 4: //multiparty call entered (during a voice call)
- tcore_call_information_joined( co, number );
- break;
-
- case 5: //call on hold has been released
- tcore_call_information_released_on_hold( co, number );
- break;
-
- case 6: //forward check SS message received (can be received whenever)
- tcore_call_information_cf_check_ss_message( co, number );
- break;
-
- case 7: //call is being connected (alerting) with the remote party in alerting state in explicit call transfer operation (during a voice call)
- tcore_call_information_transfer_alert( co, number );
- break;
-
- case 8: //call has been connected with the other remote party in explicit call transfer operation (also number and subaddress parameters may be present) (during a voice call or MT call setup)
- tcore_call_information_transfered( co, number );
- break;
-
- case 9: //this is a deflected call (MT call setup):
- tcore_call_information_mt_deflected_call( co, number );
- break;
-
- default:
- dbg("unsupported cmd2 : %d",code2);
- break;
- }
-
- return TRUE;
-}
-
-static void on_confirmation_ss_message_send( TcorePending *p, gboolean result, void *user_data )
-{
- UserRequest* ur = NULL;
- struct ATReqMetaInfo* metainfo = NULL;
- unsigned int info_len =0;
- dbg("on_confirmation_ss_message_send - msg out from queue. alloc ATRsp buffer & write rspPrefix if needed\n");
-
- ReleaseResponse(); // release leftover
-//alloc new sp_response
- sp_response = at_response_new();
-
-
- ur = tcore_pending_ref_user_request(p);
- metainfo = (struct ATReqMetaInfo*)tcore_user_request_ref_metainfo(ur,&info_len);
-
- if((metainfo->type == SINGLELINE)||
- (metainfo->type == MULTILINE))
- {
- //cp rsp prefix
- s_responsePrefix = strdup(metainfo->responsePrefix);
- dbg("duplicating responsePrefix : %s\n", s_responsePrefix);
- }
- else
- {
- s_responsePrefix = NULL;
- }
-
-//set atcmd type into s_type
- s_type = metainfo->type;
-}
-
-static void on_confirmation_call_control_ss_message_send( TcorePending *p, gboolean result, void *user_data )
-{
- UserRequest* ur = NULL;
- struct ATReqMetaInfo* metainfo = NULL;
- unsigned int info_len =0;
- dbg("on_confirmation_call_control_ss_message_send - msg out from queue. alloc ATRsp buffer & write rspPrefix if needed\n");
-
- ReleaseResponse(); // release leftover
-//alloc new sp_response
- sp_response = at_response_new();
-
-
- ur = tcore_pending_ref_user_request(p);
- metainfo = (struct ATReqMetaInfo*)tcore_user_request_ref_metainfo(ur,&info_len);
-
- if((metainfo->type == SINGLELINE)||
- (metainfo->type == MULTILINE))
- {
- //cp rsp prefix
- s_responsePrefix = strdup(metainfo->responsePrefix);
- dbg("duplicating responsePrefix : %s\n", s_responsePrefix);
- }
- else
- {
- s_responsePrefix = NULL;
- }
-
- //set atcmd type into s_type
- s_type = metainfo->type;
-}
-
-static void on_response_ss_barring_set( TcorePending *p, int data_len, const void *data, void *user_data )
-{
- struct ss_confirm_info *info = 0;
- enum telephony_ss_class class;
-
- CoreObject* o = 0;
- UserRequest *ur;
- struct tresp_ss_barring resp;
- UserRequest *ur_dup=0;
-
- o = tcore_pending_ref_core_object(p);
- ur = tcore_pending_ref_user_request(p);
-
- printResponse();
-
- info = (struct ss_confirm_info*)user_data;
- class = info->class;
-
-
- if(sp_response->success > 0){
- resp.err = SS_ERROR_NONE;
- }
- else{
- resp.record_num = 0;
- resp.err = SS_ERROR_SYSTEMFAILURE;
- }
-
- dbg("on_response_ss_barring_set - rsp.err : %d, ur : %x", resp.err, ur);
-
-
- if(sp_response->success > 0)
- {
- ReleaseResponse();
-
- if ( info->class == SS_CLASS_VOICE )
- class = SS_CLASS_ALL_TELE_BEARER;
-
- ur_dup = tcore_user_request_ref(ur);
-
- if ( info->flavor_type == SS_BARR_MODE_AB ||
- info->flavor_type == SS_BARR_MODE_AOB )
- _ss_barring_get( o, ur_dup, class, SS_BARR_MODE_BAOC, info->resp );
- else if ( info->flavor_type == SS_BARR_MODE_AIB )
- _ss_barring_get( o, ur_dup, class, SS_BARR_MODE_BAIC, info->resp );
- else
- _ss_barring_get( o, ur_dup, class, info->flavor_type, info->resp );
-
- }
- else
- {
- ReleaseResponse();
-
- if ( ur )
- tcore_user_request_send_response(ur, info->resp, sizeof(struct tresp_ss_barring), &resp);
- else
- dbg("[ error ] ur is 0");
-
- }
-
- g_free(user_data);
-
-
-}
-
-static void on_response_ss_barring_change_pwd( TcorePending *p, int data_len, const void *data, void *user_data )
-{
- struct ss_confirm_info *info = 0;
- UserRequest *ur;
- struct tresp_ss_general resp;
-
- ur = tcore_pending_ref_user_request(p);
-
- info = (struct ss_confirm_info*)user_data;
-
- printResponse();
-
- if(sp_response->success > 0){
- resp.err = SS_ERROR_NONE;
- }
- else{
- resp.err = SS_ERROR_SYSTEMFAILURE;
- }
-
- ReleaseResponse();
-
- dbg("on_response_ss_barring_change_pwd: rsp.err : %d, usr : %x", resp.err, ur);
-
- if ( ur )
- tcore_user_request_send_response(ur, info->resp, sizeof(struct tresp_ss_general), &resp);
- else
- dbg("[ error ] ur is 0");
-
- g_free(user_data);
-}
-
-
-static void on_response_ss_barring_get( TcorePending *p, int data_len, const void *data, void *user_data )
-{
- CoreObject* o = 0;
- UserRequest* ur = 0;
- struct ATLine *p_cur;
- int status=0, classx =0, err=0;
-
- struct ss_confirm_info* info = 0;
- struct tresp_ss_barring resp;
- int countRecords=0, countValidRecords =0;
-
- o = tcore_pending_ref_core_object(p);
- ur = tcore_pending_ref_user_request(p);
-
- printResponse();
-
- info = (struct ss_confirm_info*)user_data;
-
- /* count the calls */
- for (countRecords = 0, p_cur = sp_response->p_intermediates
- ; p_cur != NULL
- ; p_cur = p_cur->p_next
- ) {
- countRecords++;
- }
- dbg("total records : %d",countRecords);
-
-
- resp.record_num = countRecords;
-
- if ( resp.record_num > 0 ) {
-// int i = 0;
-
- resp.record = g_new0( struct barring_info, resp.record_num );
-
- for (countValidRecords = 0, p_cur = sp_response->p_intermediates
- ; p_cur != NULL
- ; p_cur = p_cur->p_next)
- {
- err = at_tok_start(&(p_cur->line));
- if (err < 0){
- dbg("start line error. skip this line");
- goto error;
- }
- err = at_tok_nextint(&(p_cur->line), &status);// status
- if (err < 0) {
- dbg("status error. skip this line");
- goto error;
- }
-
- if(status == 1){
- resp.record[countValidRecords].status = SS_STATUS_ACTIVATE;
- }
- else {
- resp.record[countValidRecords].status = SS_STATUS_DEACTIVATE;
- }
-
- err = at_tok_nextint(&(p_cur->line), &classx); //class
- if (err < 0) {
- dbg("class error. classx not exist - set to requested one : %d", info->class);
- switch(info->class){
- case SS_CLASS_ALL_TELE:
- classx =7;
- break;
- case SS_CLASS_VOICE:
- classx =1;
- break;
- case SS_CLASS_ALL_DATA_TELE:
- classx =2;
- break;
- case SS_CLASS_FAX:
- classx =4;
- break;
- case SS_CLASS_SMS:
- classx = 8;
- break;
- case SS_CLASS_ALL_CS_SYNC:
- classx = 16;
- break;
-
- default:
- classx =7;
- dbg("unsupported class %d. set to default : 7", info->class);
- break;
- }
- }
-
- switch(classx){
- case 1:
- resp.record[countValidRecords].class = SS_CLASS_VOICE;
- break;
- case 2:
- resp.record[countValidRecords].class = SS_CLASS_ALL_DATA_TELE;
- break;
- case 4:
- resp.record[countValidRecords].class = SS_CLASS_FAX;
- break;
- case 7:
- resp.record[countValidRecords].class = SS_CLASS_ALL_TELE;
- break;
- case 8:
- resp.record[countValidRecords].class = SS_CLASS_SMS;
- break;
- case 16:
- resp.record[countValidRecords].class = SS_CLASS_ALL_CS_SYNC;
- break;
- case 32:
- resp.record[countValidRecords].class = SS_CLASS_ALL_CS_ASYNC;
- break;
- default:
- dbg("unspoorted class : [%d]\n", classx );
- goto error;
- break;
- }
-
- resp.record[countValidRecords].mode = (enum telephony_ss_barring_mode)(info->flavor_type);
-
- countValidRecords++;
- continue;
-error:
- dbg("invalid field found. coutinue");
- continue;
- }
-
- dbg("valid count :%d",countValidRecords);
- resp.record_num = countValidRecords;
- resp.err = SS_ERROR_NONE;
-
- }
- else
- {
- dbg("no active status - return to user");
- }
-
- if(sp_response->success > 0){
- resp.err = SS_ERROR_NONE;
- }
- else{
- resp.err = SS_ERROR_SYSTEMFAILURE;
- }
-
- dbg("on_response_ss_barring_get- rsp.err : %d, ur : %x", resp.err, ur);
-
- ReleaseResponse();
-
- if ( ur )
- tcore_user_request_send_response(ur, info->resp, sizeof(struct tresp_ss_barring), &resp);
- else
- dbg("[ error ] ur is 0");
-
- g_free( user_data );
-
-}
-
-static void on_response_ss_forwarding_set( TcorePending *p, int data_len, const void *data, void *user_data )
-{
- CoreObject* o = 0;
- UserRequest* ur = 0, *dup_ur=0;
- struct ss_confirm_info *info = 0;
- struct tresp_ss_general resp;
-
- o = tcore_pending_ref_core_object(p);
- ur = tcore_pending_ref_user_request(p);
-
- info = (struct ss_confirm_info*)user_data;
-
- printResponse();
-
- if(sp_response->success > 0){
- resp.err = SS_ERROR_NONE;
- }else{
- resp.err = SS_ERROR_SYSTEMFAILURE;
- }
-
- dbg("[ check ] class : 0x%x", info->class );
- dbg("[ check ] flavor_type : 0x%x", info->flavor_type );
-
- dbg("on_response_ss_forwarding_set - rsp.err : %d, ur : %x", resp.err, ur);
-
- if ( sp_response->success > 0) {
-
- ReleaseResponse();
-
- if ( info->flavor_type == SS_CF_MODE_CF_ALL ||
- info->flavor_type == SS_CF_MODE_CFC ) {
-
- if ( ur )
- tcore_user_request_send_response(ur, info->resp, sizeof(struct tresp_ss_general), &resp);
- else
- dbg("[ error ] ur is 0");
-
- } else {
- dup_ur = tcore_user_request_ref(ur);
- _ss_forwarding_get( o, dup_ur, info->class, info->flavor_type, info->resp );
- }
-
- } else {
- ReleaseResponse();
-
- if ( ur )
- tcore_user_request_send_response(ur, info->resp, sizeof(struct tresp_ss_general), &resp);
- else
- dbg("[ error ] ur is 0");
-
- }
- g_free(user_data);
-}
-
-static void on_response_ss_forwarding_get( TcorePending *p, int data_len, const void *data, void *user_data )
-{
- CoreObject* o = 0;
- UserRequest* ur = 0;
- struct ATLine *p_cur;
- int status=0, classx =0, err=0, ton =0, time=0;
- char* num, *subaddr;
-
- struct ss_confirm_info* info = 0;
- struct tresp_ss_forwarding resp;
- int countRecords=0, countValidRecords =0;
-
- o = tcore_pending_ref_core_object(p);
- ur = tcore_pending_ref_user_request(p);
-
- printResponse();
-
- info = (struct ss_confirm_info*)user_data;
-
- /* count the calls */
- for (countRecords = 0, p_cur = sp_response->p_intermediates
- ; p_cur != NULL
- ; p_cur = p_cur->p_next
- ) {
- countRecords++;
- }
- dbg("total records : %d",countRecords);
-
-
- resp.record_num = countRecords;
-
- if ( resp.record_num > 0 ) {
- // int i = 0;
-
- resp.record = g_new0( struct forwarding_info, resp.record_num );
-
- for (countValidRecords = 0, p_cur = sp_response->p_intermediates
- ; p_cur != NULL
- ; p_cur = p_cur->p_next)
- {
- err = at_tok_start(&(p_cur->line));
- if (err < 0){
- dbg("start line error. skip this line");
- goto error;
- }
- err = at_tok_nextint(&(p_cur->line), &status);// status
- if (err < 0) {
- dbg("status error. skip this line");
- goto error;
- }
-
- if(status == 1){
- resp.record[countValidRecords].status = SS_STATUS_ACTIVATE;
- }
- else {
- resp.record[countValidRecords].status = SS_STATUS_DEACTIVATE;
- }
-
- err = at_tok_nextint(&(p_cur->line), &classx); //class
- if (err < 0) {
- dbg("class error. skip this line");
- goto error;
- }
-
- switch(classx){
- case 1:
- resp.record[countValidRecords].class = SS_CLASS_VOICE;
- break;
- case 2:
- resp.record[countValidRecords].class = SS_CLASS_ALL_DATA_TELE;
- break;
- case 4:
- resp.record[countValidRecords].class = SS_CLASS_FAX;
- break;
- case 7:
- resp.record[countValidRecords].class = SS_CLASS_ALL_TELE;
- break;
- case 8:
- resp.record[countValidRecords].class = SS_CLASS_SMS;
- break;
- case 16:
- resp.record[countValidRecords].class = SS_CLASS_ALL_CS_SYNC;
- break;
- case 32:
- resp.record[countValidRecords].class = SS_CLASS_ALL_CS_ASYNC;
- break;
- default:
- dbg("unspoorted class : [%d]\n", classx );
- goto error;
- break;
- }
-
- if(at_tok_hasmore(&(p_cur->line)) ==1){ //more data present
- err = at_tok_nextstr(&(p_cur->line), &num); //number
- memcpy((resp.record[countValidRecords].number), num, strlen(num));
- resp.record[countValidRecords].number_present = TRUE;
-
- err = at_tok_nextint(&(p_cur->line), &ton); // type of number - skip
- resp.record[countValidRecords].number_type = ton;
-
- if(at_tok_hasmore(&(p_cur->line)) ==1){
- err = at_tok_nextstr(&(p_cur->line), &subaddr); //subaddr - skip
- err =at_tok_nextint(&(p_cur->line), &ton); //ton of subaddr - skip
-
- if(at_tok_hasmore(&(p_cur->line)) ==1){
- err = at_tok_nextint(&(p_cur->line), &time); //time
- resp.record[countValidRecords].time = (enum telephony_ss_forwarding_no_reply_time)time;
- }
-
- }
-
- }
-
- resp.record[countValidRecords].mode = (enum telephony_ss_forwarding_mode)(info->flavor_type);
-
- countValidRecords++;
- continue;
-error:
- dbg("invalid field found. coutinue");
- continue;
- }
-
- dbg("valid count :%d",countValidRecords);
- resp.record_num = countValidRecords;
- resp.err = SS_ERROR_NONE;
-
- }
- else
- {
- dbg("no active status - return to user");
- }
-
- if(sp_response->success > 0){
- resp.err = SS_ERROR_NONE;
- }
- else{
- resp.err = SS_ERROR_SYSTEMFAILURE;
- }
-
- ReleaseResponse();
- dbg("on_response_ss_forwarding_get - rsp.err : %d, ur : %x", resp.err, ur);
-
- if ( ur )
- tcore_user_request_send_response(ur, info->resp, sizeof(struct tresp_ss_forwarding), &resp);
- else
- dbg("[ error ] ur is 0");
-
- g_free( user_data );
-
-}
-
-static void on_response_ss_waiting_set( TcorePending *p, int data_len, const void *data, void *user_data )
-{
- CoreObject* o = 0;
- UserRequest* ur = 0;
- struct ss_confirm_info *info = 0;
- struct tresp_ss_general resp;
-
- o = tcore_pending_ref_core_object(p);
- ur = tcore_pending_ref_user_request(p);
-
- info = (struct ss_confirm_info*)user_data;
-
- if(sp_response->success > 0){
- resp.err = SS_ERROR_NONE;
- }else{
- resp.err = SS_ERROR_SYSTEMFAILURE;
- }
-
- ReleaseResponse();
-
- dbg("on_response_ss_waiting_set - rsp.err : %d, ur : %x, class : %d", resp.err, ur, info->class );
-
- if ( resp.err == SS_ERROR_NONE ) {
-
- _ss_waiting_get( o, ur, info->class, info->resp );
-
- } else {
-
- if ( ur )
- tcore_user_request_send_response(ur, info->resp, sizeof(struct tresp_ss_general), &resp);
- else
- dbg("[ error ] ur is 0");
-
- }
- g_free( user_data );
-}
-
-static void on_response_ss_waiting_get( TcorePending *p, int data_len, const void *data, void *user_data )
-{
- CoreObject* o = 0;
- UserRequest* ur = 0;
- struct ATLine *p_cur;
- int status=0, classx =0, err=0;
-
- struct ss_confirm_info* info = 0;
- struct tresp_ss_waiting resp;
- int countRecords=0, countValidRecords =0;
- char *line;
-
- o = tcore_pending_ref_core_object(p);
- ur = tcore_pending_ref_user_request(p);
-
- printResponse();
-
- info = (struct ss_confirm_info*)user_data;
-
- /* count the calls */
- for (countRecords = 0, p_cur = sp_response->p_intermediates
- ; p_cur != NULL
- ; p_cur = p_cur->p_next
- ) {
- countRecords++;
- }
- dbg("total records : %d",countRecords);
-
-
- resp.record_num = countRecords;
-
- if ( resp.record_num > 0 ) {
- // int i = 0;
-
- resp.record = g_new0( struct waiting_info, resp.record_num );
-
- for (countValidRecords = 0, p_cur = sp_response->p_intermediates
- ; p_cur != NULL
- ; p_cur = p_cur->p_next)
- {
- line = p_cur->line;
- err = at_tok_start(&line);
- if (err < 0){
- dbg("start line error. skip this line");
- goto error;
- }
-
- err = at_tok_nextint(&line, &status);// status
- if (err < 0) {
- dbg("status error. skip this line");
- goto error;
- }
-
- if(status == 1){
- resp.record[countValidRecords].status = SS_STATUS_ACTIVATE;
- }
- else {
- resp.record[countValidRecords].status = SS_STATUS_DEACTIVATE;
- }
-
- err = at_tok_nextint(&line, &classx); //class
- if (err < 0) {
- dbg("class error. skip this line");
- goto error;
- }
-
- switch(classx){
- case 1:
- resp.record[countValidRecords].class = SS_CLASS_VOICE;
- break;
- case 2:
- resp.record[countValidRecords].class = SS_CLASS_ALL_DATA_TELE;
- break;
- case 4:
- resp.record[countValidRecords].class = SS_CLASS_FAX;
- break;
- case 7:
- resp.record[countValidRecords].class = SS_CLASS_ALL_TELE;
- break;
- case 8:
- resp.record[countValidRecords].class = SS_CLASS_SMS;
- break;
- case 16:
- resp.record[countValidRecords].class = SS_CLASS_ALL_CS_SYNC;
- break;
- case 32:
- resp.record[countValidRecords].class = SS_CLASS_ALL_CS_ASYNC;
- break;
- default:
- dbg("unspoorted class : [%d]\n", classx );
- goto error;
- break;
- }
-
- countValidRecords++;
- continue;
-error:
- dbg("invalid field found. coutinue");
- continue;
- }
-
- dbg("valid count :%d",countValidRecords);
- resp.record_num = countValidRecords;
- resp.err = SS_ERROR_NONE;
- }
- else
- {
- dbg("no active status - return to user");
- }
-
- if(sp_response->success > 0){
- resp.err = SS_ERROR_NONE;
- }
- else{
- resp.err = SS_ERROR_SYSTEMFAILURE;
- }
-
- dbg("on_response_ss_waiting_get - rsp.err : %d, ur : %x", resp.err, ur);
-
- ReleaseResponse();
-
- if ( ur )
- tcore_user_request_send_response(ur, info->resp, sizeof(struct tresp_ss_waiting), &resp);
- else
- dbg("[ error ] ur is 0");
-
- g_free( user_data );
-
-}
-
-static void on_confirmation_ss_ussd( TcorePending *p, int data_len, const void *data, void *user_data )
-{
- struct ss_confirm_info *info = 0;
-
- struct tresp_ss_ussd resp;
- CoreObject* o = 0;
- UserRequest* ur = 0;
-
- o = tcore_pending_ref_core_object(p);
- ur = tcore_pending_ref_user_request(p);
-
-
- printResponse();
-
- info = (struct ss_confirm_info*)user_data;
-
- if(sp_response->success > 0){
- resp.err = SS_ERROR_NONE;
- }
- else{
- resp.err = SS_ERROR_SYSTEMFAILURE;
- }
-
- dbg("on_confirmation_ss_ussd - rsp.err : %d, ur : %x", resp.err, ur);
-
-
- if (sp_response->success > 0) {
-
- UssdSession *ussd_s = 0;
- enum tcore_ss_ussd_type type = 0;
-
- ussd_s = tcore_ss_ussd_get_session( o );
-
- if ( ussd_s )
- type = tcore_ss_ussd_get_session_type( ussd_s );
- else
- dbg("[ error ] ussd_s : (0)");
-
- resp.type = (enum telephony_ss_ussd_type)type;
-
- if ( type == TCORE_SS_USSD_TYPE_USER_INITIATED ) {
- UserRequest *ur2 = 0;
-
- tcore_ss_ussd_get_session_data( ussd_s, (void**)&ur2 );
- if ( ur2 )
- tcore_user_request_unref( ur2 );
-
- tcore_ss_ussd_destroy_session( ussd_s );
- }
-
- if ( ur )
- tcore_user_request_send_response(ur, info->resp, sizeof(struct tresp_ss_ussd), &resp);
- else
- dbg("[ error ] ur : (0)");
-
- ReleaseResponse();
- }
-
- g_free( user_data );
-
-}
-
-
-static struct tcore_ss_operations ss_ops = {
- .barring_activate = s_ss_barring_activate,
- .barring_deactivate = s_ss_barring_deactivate,
- .barring_change_password= s_ss_barring_change_password,
- .barring_get_status = s_ss_barring_get_status,
- .forwarding_activate = s_ss_forwarding_activate,
- .forwarding_deactivate = s_ss_forwarding_deactivate,
- .forwarding_register = s_ss_forwarding_register,
- .forwarding_deregister = s_ss_forwarding_deregister,
- .forwarding_get_status = s_ss_forwarding_get_status,
- .waiting_activate = s_ss_waiting_activate,
- .waiting_deactivate = s_ss_waiting_deactivate,
- .waiting_get_status = s_ss_waiting_get_status,
- .cli_activate = s_ss_cli_activate,
- .cli_deactivate = s_ss_cli_deactivate,
- .cli_get_status = s_ss_cli_get_status,
- .send_ussd = s_ss_send_ussd,
- .set_aoc = s_ss_set_aoc,
- .get_aoc = s_ss_get_aoc,
-};
-
-
-static TReturn _ss_barring_set( CoreObject *o, UserRequest *ur, enum telephony_ss_opcode op )
-{
- struct treq_ss_barring *barring = 0;
- TcorePlugin *p = 0;
- struct ss_confirm_info *user_data = 0;
- gboolean ret = FALSE;
- char passwd[MAX_SS_BARRING_PASSWORD_LEN+1];
-
- struct ATReqMetaInfo metainfo;
- int info_len =0;
- char* cmd_str = NULL;
- int opco;
- int classx;
- char* facility = NULL;
-
-
- barring = (struct treq_ss_barring*)tcore_user_request_ref_data( ur, 0 );
- p = tcore_object_ref_plugin( o );
-
- memset(&metainfo, 0, sizeof(struct ATReqMetaInfo));
- metainfo.type = NO_RESULT;
- metainfo.responsePrefix[0] ='\0';
- info_len = sizeof(struct ATReqMetaInfo);
-
- tcore_user_request_set_metainfo(ur, info_len, &metainfo);
-
-
- switch(op){
- case TIZEN_SS_OPCO_ACTIVATE:
- opco = 1;
- break;
- case TIZEN_SS_OPCO_DEACTIVATE:
- opco = 0;
- break;
- default:
- dbg("unsupported opco : %d", op);
- return TCORE_RETURN_FAILURE;
- }
-
-
- switch(barring->mode){
- case SS_BARR_MODE_BAOC:
- facility = "AO";
- break;
- case SS_BARR_MODE_BOIC:
- facility = "OI";
- break;
- case SS_BARR_MODE_BOIC_NOT_HC:
- facility = "OX";
- break;
- case SS_BARR_MODE_BAIC:
- facility = "AI";
- break;
- case SS_BARR_MODE_BIC_ROAM:
- facility = "IR";
- break;
- case SS_BARR_MODE_AB:
- facility = "AB";
- break;
- case SS_BARR_MODE_AOB:
- facility = "AG";
- break;
- case SS_BARR_MODE_AIB:
- facility = "AC";
- break;
- case SS_BARR_MODE_BIC_NOT_SIM:
- facility = "NS";
- break;
- default:
- dbg("unspported mode %d", barring->mode);
- return TCORE_RETURN_FAILURE;
- }
-
- switch(barring->class)
- {
- case SS_CLASS_ALL_TELE:
- classx =7;
- break;
- case SS_CLASS_VOICE:
- classx =1;
- break;
- case SS_CLASS_ALL_DATA_TELE:
- classx =2;
- break;
- case SS_CLASS_FAX:
- classx =4;
- break;
- case SS_CLASS_SMS:
- classx = 8;
- break;
- case SS_CLASS_ALL_CS_SYNC:
- classx = 16;
- break;
-
- default:
- classx =7;
- dbg("unsupported class %d. set to default : 7", barring->class);
- break;
- }
-
- // null-ended pwd handling added - unexpected 0x11 value observed in req string
- memcpy(passwd, barring->password, MAX_SS_BARRING_PASSWORD_LEN);
- passwd[MAX_SS_BARRING_PASSWORD_LEN]='\0';
-
-
- cmd_str = g_strdup_printf("AT+CLCK=\"%s\",%d,\"%s\",%d%s", facility, opco, passwd, classx,"\r");
- dbg("request command : %s", cmd_str);
-
- user_data = g_new0( struct ss_confirm_info, 1 );
-
- if ( op == TIZEN_SS_OPCO_ACTIVATE) {
- user_data->resp = TRESP_SS_BARRING_ACTIVATE;
-
- } else if ( op == TIZEN_SS_OPCO_DEACTIVATE) {
- user_data->resp = TRESP_SS_BARRING_DEACTIVATE;
-
- } else {
- dbg("[ error ] wrong ss opco ( 0x%x )", op );
- return TCORE_RETURN_FAILURE;
- }
-
- user_data->flavor_type = (int)(barring->mode);
- user_data->class = barring->class;
-
- ret = _ss_request_message( o, ur, cmd_str, strlen(cmd_str), on_response_ss_barring_set, user_data );
-
- g_free(cmd_str);
-
- if ( !ret )
- return TCORE_RETURN_FAILURE;
-
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn _ss_barring_get( CoreObject *o,
- UserRequest *ur,
- enum telephony_ss_class class,
- enum telephony_ss_barring_mode mode,
- enum tcore_response_command resp )
-{
- TcorePlugin *p = 0;
- struct ss_confirm_info *user_data = 0;
- gboolean ret = FALSE;
-
- struct ATReqMetaInfo metainfo;
- int info_len =0;
- char* cmd_str = NULL;
- int opco, classx;
- char* facility = NULL;
-
- p = tcore_object_ref_plugin( o );
-
- memset(&metainfo, 0, sizeof(struct ATReqMetaInfo));
- metainfo.type = MULTILINE;
- memcpy(metainfo.responsePrefix,"+CLCK:",strlen("+CLCK:"));
- info_len = sizeof(struct ATReqMetaInfo);
-
- tcore_user_request_set_metainfo(ur, info_len, &metainfo);
-
- //query status - opco is fixed to 2
- opco = 2;
-
- //barring mode
- switch(mode){
- case SS_BARR_MODE_BAOC:
- facility = "AO";
- break;
- case SS_BARR_MODE_BOIC:
- facility = "OI";
- break;
- case SS_BARR_MODE_BOIC_NOT_HC:
- facility = "OX";
- break;
- case SS_BARR_MODE_BAIC:
- facility = "AI";
- break;
- case SS_BARR_MODE_BIC_ROAM:
- facility = "IR";
- break;
- case SS_BARR_MODE_AB:
- facility = "AB";
- break;
- case SS_BARR_MODE_AOB:
- facility = "AG";
- break;
- case SS_BARR_MODE_AIB:
- facility = "AC";
- break;
- case SS_BARR_MODE_BIC_NOT_SIM:
- facility = "NS";
- break;
- default:
- dbg("unspported mode %d", mode);
- return TCORE_RETURN_FAILURE;
- }
-
- switch(class)
- {
- case SS_CLASS_ALL_TELE:
- classx =7;
- break;
- case SS_CLASS_VOICE:
- classx =1;
- break;
- case SS_CLASS_ALL_DATA_TELE:
- classx =2;
- break;
- case SS_CLASS_FAX:
- classx =4;
- break;
- case SS_CLASS_SMS:
- classx = 8;
- break;
- case SS_CLASS_ALL_CS_SYNC:
- classx = 16;
- break;
-
- default:
- classx =7;
- dbg("unsupported class %d. set to default : 7", class);
- break;
- }
-
-
- if(classx ==7)
- cmd_str = g_strdup_printf("AT+CLCK=\"%s\",%d%s", facility, opco,"\r");
- else
- cmd_str = g_strdup_printf("AT+CLCK=\"%s\",%d,,%d%s", facility, opco,classx,"\r");
-
- dbg("request command : %s", cmd_str);
-
- user_data = g_new0( struct ss_confirm_info, 1 );
- user_data->resp = resp;
-
- user_data->flavor_type = (int)(mode);
- user_data->class = class;
-
- ret = _ss_request_message( o, ur, cmd_str, strlen(cmd_str), on_response_ss_barring_get, user_data );
-
- g_free(cmd_str);
-
- if ( !ret )
- return TCORE_RETURN_FAILURE;
-
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn s_ss_barring_activate( CoreObject *o, UserRequest *ur )
-{
- return _ss_barring_set( o, ur, TIZEN_SS_OPCO_ACTIVATE );
-}
-
-static TReturn s_ss_barring_deactivate( CoreObject *o, UserRequest *ur )
-{
- return _ss_barring_set( o, ur, TIZEN_SS_OPCO_DEACTIVATE );
-}
-
-static TReturn s_ss_barring_change_password( CoreObject *o, UserRequest *ur )
-{
- TcorePlugin *p = 0;
- struct treq_ss_barring_change_password *barring = 0;
-
- struct ss_confirm_info *user_data = 0;
-
- gboolean ret = FALSE;
-
-// struct ATReqMetaInfo metainfo;
-// int info_len =0;
- char* cmd_str = NULL;
-
- p = tcore_object_ref_plugin( o );
- barring = (struct treq_ss_barring_change_password*)tcore_user_request_ref_data( ur, 0 );
-
-
- cmd_str = g_strdup_printf("AT+CPWD=\"%s\",\"%s\",\"%s\"%s", "AB", barring->password_old, barring->password_new,"\r");
- dbg("request command : %s", cmd_str);
-
-
- user_data = g_new0( struct ss_confirm_info, 1 );
- user_data->resp = TRESP_SS_BARRING_CHANGE_PASSWORD;
-
- ret = _ss_request_message( o, ur, cmd_str, strlen(cmd_str), on_response_ss_barring_change_pwd, user_data );
-
- g_free(cmd_str);
- if ( !ret )
- return TCORE_RETURN_FAILURE;
-
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn s_ss_barring_get_status( CoreObject *o, UserRequest *ur )
-{
- struct treq_ss_barring *barring = 0;
- barring = (struct treq_ss_barring*)tcore_user_request_ref_data( ur, 0 );
-
- return _ss_barring_get( o, ur, barring->class, barring->mode, TRESP_SS_BARRING_GET_STATUS );
-}
-
-static TReturn _ss_forwarding_set( CoreObject *o, UserRequest *ur, enum telephony_ss_opcode op )
-{
- TcorePlugin *p = 0;
- struct treq_ss_forwarding *forwarding = 0;
-
- struct ss_confirm_info *user_data = 0;
-
- gboolean ret = FALSE;
- int len = 0;
-
- struct ATReqMetaInfo metainfo;
- int info_len =0;
- char* cmd_str = NULL;
- char* tmp_str = NULL;
- int reason=0,mode=0,num_type=0, classx=0,time=0;
- gboolean valid_num = FALSE;
-
- dbg("_ss_forwarding_set with opco %d ", op);
-
-
- forwarding = (struct treq_ss_forwarding*) tcore_user_request_ref_data( ur, 0 );
- p = tcore_object_ref_plugin( o );
-
- memset(&metainfo, 0, sizeof(struct ATReqMetaInfo));
- metainfo.type = NO_RESULT;
- metainfo.responsePrefix[0] ='\0';
- info_len = sizeof(struct ATReqMetaInfo);
-
- tcore_user_request_set_metainfo(ur, info_len, &metainfo);
-
- switch(forwarding->mode)
- {
- case SS_CF_MODE_CFU:
- reason =0;
- break;
- case SS_CF_MODE_CFB:
- reason =1;
- break;
- case SS_CF_MODE_CFNRy:
- reason =2;
- break;
- case SS_CF_MODE_CFNRc:
- reason =3;
- break;
- case SS_CF_MODE_CF_ALL:
- reason = 4;
- break;
- case SS_CF_MODE_CFC:
- reason = 5;
- break;
-
- default:
- dbg("unsupported reason : %d");
- break;
- }
-
- switch(op){
- case TIZEN_SS_OPCO_DEACTIVATE:
- mode = 0;
- break;
- case TIZEN_SS_OPCO_ACTIVATE:
- mode = 1;
- break;
- case TIZEN_SS_OPCO_REG:
- mode = 3;
- break;
- case TIZEN_SS_OPCO_DEREG:
- mode = 4;
- break;
-
- default:
- dbg("unsupported opco : %d", op);
- return TCORE_RETURN_FAILURE;
- }
-
-
-// class
- switch(forwarding->class)
- {
- case SS_CLASS_ALL_TELE:
- classx =7;
- break;
- case SS_CLASS_VOICE:
- classx =1;
- break;
- case SS_CLASS_ALL_DATA_TELE:
- classx =2;
- break;
- case SS_CLASS_FAX:
- classx =4;
- break;
- case SS_CLASS_SMS:
- classx = 8;
- break;
- case SS_CLASS_ALL_CS_SYNC:
- classx = 16;
- break;
-
- default:
- classx =7;
- dbg("unsupported class %d. set to default : 7", forwarding->class);
- break;
- }
-
-//number
- len = strlen(forwarding->number);
- if ( len > 0 ){
- valid_num = TRUE;
- if ( forwarding->number[0] == '+' )
- num_type = ((TIZEN_NUM_TYPE_INTERNATIONAL << 4)|TIZEN_NUM_PLAN_ISDN);
- else
- num_type = 0;
- }
- user_data = g_new0( struct ss_confirm_info, 1 );
-
- switch ( op ) {
- case TIZEN_SS_OPCO_REG:
- user_data->resp = TRESP_SS_FORWARDING_REGISTER;
- break;
- case TIZEN_SS_OPCO_DEREG:
- user_data->resp = TRESP_SS_FORWARDING_DEREGISTER;
- break;
- case TIZEN_SS_OPCO_ACTIVATE:
- user_data->resp = TRESP_SS_FORWARDING_ACTIVATE;
- break;
- case TIZEN_SS_OPCO_DEACTIVATE:
- user_data->resp = TRESP_SS_FORWARDING_DEACTIVATE;
- break;
- default:
- dbg("[ error ] unknown op ( 0x%x )", op );
- break;
- }
-
- if(op == TIZEN_SS_OPCO_REG)
- tmp_str = g_strdup_printf("AT+CCFC=%d,%d,\"%s\",%d,%d", reason, mode, forwarding->number, num_type, classx);
- else// other opcode does not need num field
- tmp_str = g_strdup_printf("AT+CCFC=%d,%d,,,%d", reason, mode, classx);
-
- if(forwarding->mode == SS_CF_MODE_CFNRy){
- //add time info to 'no reply' case
- time = (int)(forwarding->time);
- cmd_str = g_strdup_printf("%s,,,%d%s", tmp_str,time,"\r");
- }
- else {
- cmd_str = g_strdup_printf("%s%s", tmp_str,"\r");
- }
-
- dbg("request command : %s", cmd_str);
-
- user_data->flavor_type = forwarding->mode;
- user_data->class = forwarding->class;
-
- ret = _ss_request_message( o, ur, cmd_str, strlen(cmd_str), on_response_ss_forwarding_set, user_data );
- g_free(tmp_str);
- g_free(cmd_str);
-
- if ( !ret )
- return TCORE_RETURN_FAILURE;
-
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn _ss_forwarding_get( CoreObject *o,
- UserRequest *ur,
- enum telephony_ss_class class,
- enum telephony_ss_forwarding_mode type,
- enum tcore_response_command resp )
-{
- TcorePlugin *p = 0;
- struct ss_confirm_info *user_data = 0;
-
- gboolean ret = FALSE;
-// int len = 0;
-
- struct ATReqMetaInfo metainfo;
- int info_len=0, reason=0, mode=0, classx =0;
- char* cmd_str = NULL;
-
- p = tcore_object_ref_plugin( o );
-
- memset(&metainfo, 0, sizeof(struct ATReqMetaInfo));
- metainfo.type = MULTILINE;
- memcpy(metainfo.responsePrefix,"+CCFC:",strlen("+CCFC:"));
- info_len = sizeof(struct ATReqMetaInfo);
-
- tcore_user_request_set_metainfo(ur, info_len, &metainfo);
-
- switch(type)
- {
- case SS_CF_MODE_CFU:
- reason =0;
- break;
- case SS_CF_MODE_CFB:
- reason =1;
- break;
- case SS_CF_MODE_CFNRy:
- reason =2;
- break;
- case SS_CF_MODE_CFNRc:
- reason =3;
- break;
- case SS_CF_MODE_CF_ALL:
- reason = 4;
- break;
- case SS_CF_MODE_CFC:
- reason = 5;
- break;
-
- default:
- dbg("unsupported reason : %d");
- break;
- }
-
- switch(class)
- {
- case SS_CLASS_ALL_TELE:
- classx =7;
- break;
- case SS_CLASS_VOICE:
- classx =1;
- break;
- case SS_CLASS_ALL_DATA_TELE:
- classx =2;
- break;
- case SS_CLASS_FAX:
- classx =4;
- break;
- case SS_CLASS_SMS:
- classx = 8;
- break;
- case SS_CLASS_ALL_CS_SYNC:
- classx = 16;
- break;
- default:
- classx =7;
- dbg("unsupported class %d. set to default : 7", class);
- break;
- }
-
- //query status - mode set to 2
- mode =2;
-
- user_data = g_new0( struct ss_confirm_info, 1 );
- user_data->resp = resp;
-
- user_data->class = class;
- user_data->flavor_type = type;
-
- if(classx ==7)
- cmd_str = g_strdup_printf("AT+CCFC=%d,%d%s", reason, mode,"\r");
- else
- cmd_str = g_strdup_printf("AT+CCFC=%d,%d,,,%d%s", reason, mode,classx,"\r");
-
- dbg("request command : %s", cmd_str);
- ret = _ss_request_message( o, ur, cmd_str, strlen(cmd_str), on_response_ss_forwarding_get, user_data );
- g_free(cmd_str);
-
- if ( !ret )
- return TCORE_RETURN_FAILURE;
-
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn s_ss_forwarding_activate( CoreObject *o, UserRequest *ur )
-{
- return _ss_forwarding_set( o, ur, TIZEN_SS_OPCO_ACTIVATE );
-}
-
-static TReturn s_ss_forwarding_deactivate( CoreObject *o, UserRequest *ur )
-{
- return _ss_forwarding_set( o, ur, TIZEN_SS_OPCO_DEACTIVATE );
-}
-
-static TReturn s_ss_forwarding_register( CoreObject *o, UserRequest *ur )
-{
- return _ss_forwarding_set( o, ur, TIZEN_SS_OPCO_REG );
-}
-
-static TReturn s_ss_forwarding_deregister( CoreObject *o, UserRequest *ur )
-{
- return _ss_forwarding_set( o, ur, TIZEN_SS_OPCO_DEREG );
-}
-
-static TReturn s_ss_forwarding_get_status( CoreObject *o, UserRequest *ur )
-{
- struct treq_ss_forwarding *forwarding = 0;
- forwarding = (struct treq_ss_forwarding*)tcore_user_request_ref_data( ur, 0 );
-
- return _ss_forwarding_get( o, ur, forwarding->class, forwarding->mode, TRESP_SS_FORWARDING_GET_STATUS );
-}
-
-static TReturn _ss_waiting_set( CoreObject *o, UserRequest *ur, enum telephony_ss_opcode opco )
-{
- TcorePlugin *p = 0;
- struct treq_ss_waiting *waiting = 0;
-
- struct ss_confirm_info *user_data = 0;
-
- gboolean ret = FALSE;
- int mode=0, classx=0;
- char* cmd_str;
- struct ATReqMetaInfo metainfo;
-
-//set metainfo
- memset(&metainfo, 0, sizeof(struct ATReqMetaInfo));
- metainfo.type = NO_RESULT;
- metainfo.responsePrefix[0] ='\0';
-
- tcore_user_request_set_metainfo(ur, sizeof(struct ATReqMetaInfo), &metainfo);
-
- p = tcore_object_ref_plugin( o );
-
- waiting = (struct treq_ss_waiting*) tcore_user_request_ref_data( ur, 0 );
-
- user_data = g_new0( struct ss_confirm_info, 1 );
-
- if ( opco == TIZEN_SS_OPCO_ACTIVATE ){
- user_data->resp = TRESP_SS_WAITING_ACTIVATE;
- mode = 1;//enable
- }
- else if ( opco == TIZEN_SS_OPCO_DEACTIVATE ){
- user_data->resp = TRESP_SS_WAITING_DEACTIVATE;
- mode =0; //diable
- }
- else
- dbg("[ error ] unknown ss mode (0x%x)", opco);
-
- switch(waiting->class)
- {
- case SS_CLASS_ALL_TELE:
- classx =7;
- break;
- case SS_CLASS_VOICE:
- classx =1;
- break;
- case SS_CLASS_ALL_DATA_TELE:
- classx =2;
- break;
- case SS_CLASS_FAX:
- classx =4;
- break;
- case SS_CLASS_SMS:
- classx = 8;
- break;
-
- default:
- classx =7;
- dbg("unsupported class %d. set to default : 7", waiting->class);
- break;
- }
-
-
-user_data->class = waiting->class;
- user_data->flavor_type = (int)opco;
-
- cmd_str = g_strdup_printf("AT+CCWA=1,%d,%d%s", mode, classx,"\r"); //always enable +CCWA: unsolicited cmd
- dbg("request command : %s",cmd_str);
-
- ret = _ss_request_message( o, ur, cmd_str, strlen(cmd_str), on_response_ss_waiting_set, user_data );
-
- g_free(cmd_str);
- if ( !ret )
- return TCORE_RETURN_FAILURE;
-
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn _ss_waiting_get( CoreObject *o,
- UserRequest *ur,
- enum telephony_ss_class class,
- enum tcore_response_command resp )
-{
- TcorePlugin *p = 0;
-
- struct ss_confirm_info *user_data = 0;
-
- gboolean ret = FALSE;
- int classx, info_len=0;//mode,
- char* cmd_str;
- struct ATReqMetaInfo metainfo;
-
-//set metainfo
- memset(&metainfo, 0, sizeof(struct ATReqMetaInfo));
- metainfo.type = MULTILINE;
- memcpy(metainfo.responsePrefix,"+CCWA:",strlen("+CCWA:"));
- info_len = sizeof(struct ATReqMetaInfo);
-
- tcore_user_request_set_metainfo(ur, sizeof(struct ATReqMetaInfo), &metainfo);
-
- p = tcore_object_ref_plugin( o );
-
- switch(class)
- {
- case SS_CLASS_ALL_TELE:
- classx =7;
- break;
- case SS_CLASS_VOICE:
- classx =1;
- break;
- case SS_CLASS_ALL_DATA_TELE:
- classx =2;
- break;
- case SS_CLASS_FAX:
- classx =4;
- break;
- case SS_CLASS_SMS:
- classx = 8;
- break;
-
- default:
- classx =7;
- dbg("unsupported class %d. set to default : 7", class);
- break;
- }
-
- dbg("allocating user data");
- user_data = g_new0( struct ss_confirm_info, 1 );
- user_data->resp = resp;
- user_data->class = class;
-
- cmd_str = g_strdup_printf("AT+CCWA=1,2,%d%s", classx,"\r"); //always enable +CCWA: unsolicited cmd , mode is fixed to 2(query status)
- dbg("request cmd : %s", cmd_str);
-
- ret = _ss_request_message( o, ur, cmd_str, strlen(cmd_str), on_response_ss_waiting_get, user_data );
-
- g_free(cmd_str);
-
- if ( !ret )
- return TCORE_RETURN_FAILURE;
-
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn s_ss_waiting_activate( CoreObject *o, UserRequest *ur )
-{
- return _ss_waiting_set( o, ur, TIZEN_SS_OPCO_ACTIVATE );
-}
-
-static TReturn s_ss_waiting_deactivate( CoreObject *o, UserRequest *ur )
-{
- return _ss_waiting_set( o, ur, TIZEN_SS_OPCO_DEACTIVATE );
-}
-
-static TReturn s_ss_waiting_get_status( CoreObject *o, UserRequest *ur )
-{
- struct treq_ss_waiting *waiting = 0;
- waiting = (struct treq_ss_waiting*)tcore_user_request_ref_data( ur, 0 );
-
- return _ss_waiting_get( o, ur, waiting->class, TRESP_SS_WAITING_GET_STATUS );
-}
-
-static TReturn s_ss_cli_activate( CoreObject *o, UserRequest *ur )
-{
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn s_ss_cli_deactivate( CoreObject *o, UserRequest *ur )
-{
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn s_ss_cli_get_status( CoreObject *o, UserRequest *ur )
-{
- TcorePlugin *p = 0;
-
- struct treq_ss_cli *cli = 0;
- gboolean ret = FALSE;
- char *cmd_prefix = NULL, *rsp_prefix = NULL, *cmd_str = NULL;
- struct ATReqMetaInfo metainfo;
- enum telephony_ss_cli_type *user_data = 0;
-
- int info_len =0;
-
- p = tcore_object_ref_plugin(o);
-
- cli = (struct treq_ss_cli*)tcore_user_request_ref_data( ur, 0 );
-
- switch(cli->type){
- case SS_CLI_TYPE_CLIP:
- cmd_prefix = "+CLIP";
- rsp_prefix = "+CLIP:";
- break;
-
- case SS_CLI_TYPE_CLIR:
- cmd_prefix = "+CLIR";
- rsp_prefix = "+CLIR:";
- break;
-
- case SS_CLI_TYPE_COLP:
- cmd_prefix = "+COLP";
- rsp_prefix = "+COLP:";
- break;
-
- case SS_CLI_TYPE_CDIP:
- cmd_prefix = "+CDIP";
- rsp_prefix = "+CDIP:";
- break;
-
- default:
- dbg("unsupported cli_type : %d", cli->type);
- return TCORE_RETURN_FAILURE;
- break;
- }
-
- dbg("cmd_prefix : %s",cmd_prefix);
-
-//set metaInfo
- memset(&metainfo, 0, sizeof(struct ATReqMetaInfo));
- metainfo.type = SINGLELINE;
- memcpy(metainfo.responsePrefix,rsp_prefix,strlen(rsp_prefix));
- info_len = sizeof(struct ATReqMetaInfo);
-
- tcore_user_request_set_metainfo(ur, sizeof(struct ATReqMetaInfo), &metainfo);
-
- //make cmd string
-
- cmd_str = g_strdup_printf("AT%s?%s", cmd_prefix, "\r");
- dbg("request cmd : %s", cmd_str);
-
- // make userinfo for callback
- user_data = g_new0( enum telephony_ss_cli_type, 1 );
- *user_data = cli->type;
-
- ret = _ss_request_message( o, ur, cmd_str, strlen(cmd_str), on_response_ss_waiting_get, user_data );
-
- g_free(cmd_str);
-
- if ( !ret )
- return TCORE_RETURN_FAILURE;
-
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn s_ss_send_ussd( CoreObject *o, UserRequest *ur )
-{
- TcorePlugin *p = 0;
- UssdSession *ussd_s = 0;
-
- struct treq_ss_ussd *ussd = 0;
- struct ss_confirm_info *user_data = 0;
-
- gboolean ret = FALSE;
- char* cmd_str;
- struct ATReqMetaInfo metainfo;
-
- //set metainfo
- memset(&metainfo, 0, sizeof(struct ATReqMetaInfo));
- metainfo.type = NO_RESULT;
- metainfo.responsePrefix[0] ='\0';
- tcore_user_request_set_metainfo(ur, sizeof(struct ATReqMetaInfo), &metainfo);
-
- p = tcore_object_ref_plugin(o);
- ussd = (struct treq_ss_ussd*)tcore_user_request_ref_data( ur, 0 );
-
- cmd_str = g_strdup_printf("AT+CUSD=1,\"%s\",%d%s", ussd->str, 0x0f,"\r"); //always enable +CUSD: unsolicited cmd. set to dcs to 0x0f. only supports HEX type
- dbg("request command : %s",cmd_str);
-
-
- user_data = g_new0( struct ss_confirm_info, 1 );
- user_data->resp = TRESP_SS_SEND_USSD;
-
- ussd_s = tcore_ss_ussd_get_session( o );
- if ( !ussd_s ) {
- tcore_ss_ussd_create_session( o, (enum tcore_ss_ussd_type)ussd->type, (void*)tcore_user_request_ref(ur), 0 );
- } else {
-
- if ( ussd->type == SS_USSD_TYPE_USER_INITIATED ) {
- dbg("[ error ] ussd session is already exist");
-
- g_free( user_data );
- return TCORE_RETURN_FAILURE;
- }
-
- tcore_ss_ussd_set_session_type( ussd_s, (enum tcore_ss_ussd_type)ussd->type);
- }
-
- ret = _ss_request_message( o, ur, cmd_str, strlen(cmd_str), on_confirmation_ss_ussd, user_data );
-
- if ( !ret )
- return TCORE_RETURN_FAILURE;
-
-
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn s_ss_set_aoc( CoreObject *o, UserRequest *ur )
-{
- dbg("[ error ] unsupported function");
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn s_ss_get_aoc( CoreObject *o, UserRequest *ur )
-{
- dbg("[ error ] unsupported function");
- return TCORE_RETURN_SUCCESS;
-}
-
-static struct tcore_call_control_operations call_ops = {
- .answer_hold_and_accept = s_ss_manage_call_2_send,
- .answer_replace = s_ss_manage_call_1_send,
- .answer_reject = s_ss_manage_call_0_send,
- .end_specific = s_ss_manage_call_1x_send,
- .end_all_active = s_ss_manage_call_1_send,
- .end_all_held = s_ss_manage_call_0_send,
- .active = s_ss_manage_call_2_send,
- .hold = s_ss_manage_call_2_send,
- .swap = s_ss_manage_call_2_send,
- .join = s_ss_manage_call_3_send,
- .split = s_ss_manage_call_2x_send,
- .transfer = s_ss_manage_call_4_send,
- .deflect = s_ss_manage_call_4dn_send,
-};
-
-static TReturn s_ss_manage_call_0_send( CoreObject* o, UserRequest* ur, ConfirmCallback cb, void* user_data )
-{
- TcorePlugin *p = NULL;
- TcoreHal *h = NULL;
- TcorePending *pending = NULL;
- char* cmd_str = NULL;
- struct ATReqMetaInfo metainfo;
- int info_len =0;
-
- p = tcore_object_ref_plugin(o);
- h = tcore_object_get_hal(o);
-
- memset(&metainfo, 0, sizeof(struct ATReqMetaInfo));
- metainfo.type = NO_RESULT;
- metainfo.responsePrefix[0] ='\0';
- info_len = sizeof(struct ATReqMetaInfo);
-
- tcore_user_request_set_metainfo(ur, info_len, &metainfo);
-
- cmd_str = g_strdup_printf("%s%s", "AT+CHLD=0", "\r");
- dbg("cmd : %s, prefix(if any) : %s, cmd_len : %d",cmd_str, "N/A", strlen(cmd_str));
-
- pending = tcore_pending_new(o, ID_RESERVED_AT);
- tcore_pending_set_request_data(pending, strlen(cmd_str), cmd_str);
- g_free(cmd_str);
- tcore_pending_set_timeout(pending, 0);
- tcore_pending_set_response_callback(pending, (TcorePendingResponseCallback)cb, user_data);
- tcore_pending_link_user_request(pending, ur);
- tcore_pending_set_priority(pending, TCORE_PENDING_PRIORITY_DEFAULT);
-
- tcore_pending_set_send_callback(pending, on_confirmation_call_control_ss_message_send, NULL);
-
-
- tcore_hal_send_request(h, pending);
-
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn s_ss_manage_call_1_send( CoreObject* o, UserRequest* ur, ConfirmCallback cb, void* user_data )
-{
- TcorePlugin *p = NULL;
- TcoreHal *h = NULL;
- TcorePending *pending = NULL;
- char* cmd_str = NULL;
- struct ATReqMetaInfo metainfo;
- int info_len =0;
-
- p = tcore_object_ref_plugin(o);
- h = tcore_object_get_hal(o);
-
- memset(&metainfo, 0, sizeof(struct ATReqMetaInfo));
- metainfo.type = NO_RESULT;
- metainfo.responsePrefix[0] ='\0';
- info_len = sizeof(struct ATReqMetaInfo);
-
- tcore_user_request_set_metainfo(ur, info_len, &metainfo);
-
- cmd_str = g_strdup_printf("%s%s", "AT+CHLD=1", "\r");
- dbg("cmd : %s, prefix(if any) : %s, cmd_len : %d",cmd_str, "N/A", strlen(cmd_str));
-
- pending = tcore_pending_new(o, ID_RESERVED_AT);
- tcore_pending_set_request_data(pending, strlen(cmd_str), cmd_str);
- g_free(cmd_str);
- tcore_pending_set_timeout(pending, 0);
- tcore_pending_set_response_callback(pending, (TcorePendingResponseCallback)cb, user_data);
- tcore_pending_link_user_request(pending, ur);
- tcore_pending_set_priority(pending, TCORE_PENDING_PRIORITY_DEFAULT);
-
- tcore_pending_set_send_callback(pending, on_confirmation_call_control_ss_message_send, NULL);
-
-
- tcore_hal_send_request(h, pending);
-
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn s_ss_manage_call_1x_send( CoreObject* o, UserRequest* ur, const int id, ConfirmCallback cb, void* user_data )
-{
- TcorePlugin *p = NULL;
- TcoreHal *h = NULL;
- TcorePending *pending = NULL;
- char* cmd_str = NULL;
- struct ATReqMetaInfo metainfo;
- int info_len =0;
-
- p = tcore_object_ref_plugin(o);
- h = tcore_object_get_hal(o);
-
- memset(&metainfo, 0, sizeof(struct ATReqMetaInfo));
- metainfo.type = NO_RESULT;
- metainfo.responsePrefix[0] ='\0';
- info_len = sizeof(struct ATReqMetaInfo);
-
- tcore_user_request_set_metainfo(ur, info_len, &metainfo);
-
- cmd_str = g_strdup_printf("%s%d%s", "AT+CHLD=1", id,"\r");
- dbg("cmd : %s, prefix(if any) : %s, cmd_len : %d",cmd_str, "N/A", strlen(cmd_str));
-
- pending = tcore_pending_new(o, ID_RESERVED_AT);
- tcore_pending_set_request_data(pending, strlen(cmd_str), cmd_str);
- g_free(cmd_str);
- tcore_pending_set_timeout(pending, 0);
- tcore_pending_set_response_callback(pending, (TcorePendingResponseCallback)cb, user_data);
- tcore_pending_link_user_request(pending, ur);
- tcore_pending_set_priority(pending, TCORE_PENDING_PRIORITY_DEFAULT);
-
- tcore_pending_set_send_callback(pending, on_confirmation_call_control_ss_message_send, NULL);
-
-
- tcore_hal_send_request(h, pending);
-
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn s_ss_manage_call_2_send( CoreObject* o, UserRequest* ur, ConfirmCallback cb, void* user_data )
-{
- TcorePlugin *p = NULL;
- TcoreHal *h = NULL;
- TcorePending *pending = NULL;
- char* cmd_str = NULL;
- struct ATReqMetaInfo metainfo;
- int info_len =0;
-
- p = tcore_object_ref_plugin(o);
- h = tcore_object_get_hal(o);
-
- memset(&metainfo, 0, sizeof(struct ATReqMetaInfo));
- metainfo.type = NO_RESULT;
- metainfo.responsePrefix[0] ='\0';
- info_len = sizeof(struct ATReqMetaInfo);
-
- tcore_user_request_set_metainfo(ur, info_len, &metainfo);
-
- cmd_str = g_strdup_printf("%s%s", "AT+CHLD=2", "\r");
- dbg("cmd : %s, prefix(if any) : %s, cmd_len : %d",cmd_str, "N/A", strlen(cmd_str));
-
- pending = tcore_pending_new(o, ID_RESERVED_AT);
- tcore_pending_set_request_data(pending, strlen(cmd_str), cmd_str);
- g_free(cmd_str);
- tcore_pending_set_timeout(pending, 0);
- tcore_pending_set_response_callback(pending, (TcorePendingResponseCallback)cb, user_data);
- tcore_pending_link_user_request(pending, ur);
- tcore_pending_set_priority(pending, TCORE_PENDING_PRIORITY_DEFAULT);
-
- tcore_pending_set_send_callback(pending, on_confirmation_call_control_ss_message_send, NULL);
-
-
- tcore_hal_send_request(h, pending);
-
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn s_ss_manage_call_2x_send( CoreObject* o, UserRequest* ur, const int id, ConfirmCallback cb, void* user_data )
-{
- TcorePlugin *p = NULL;
- TcoreHal *h = NULL;
- TcorePending *pending = NULL;
- char* cmd_str = NULL;
- struct ATReqMetaInfo metainfo;
- int info_len =0;
-
- p = tcore_object_ref_plugin(o);
- h = tcore_object_get_hal(o);
-
- memset(&metainfo, 0, sizeof(struct ATReqMetaInfo));
- metainfo.type = NO_RESULT;
- metainfo.responsePrefix[0] ='\0';
- info_len = sizeof(struct ATReqMetaInfo);
-
- tcore_user_request_set_metainfo(ur, info_len, &metainfo);
-
- cmd_str = g_strdup_printf("%s%d%s", "AT+CHLD=2", id,"\r");
- dbg("cmd : %s, prefix(if any) : %s, cmd_len : %d",cmd_str, "N/A", strlen(cmd_str));
-
- pending = tcore_pending_new(o, ID_RESERVED_AT);
- tcore_pending_set_request_data(pending, strlen(cmd_str), cmd_str);
- g_free(cmd_str);
- tcore_pending_set_timeout(pending, 0);
- tcore_pending_set_response_callback(pending, (TcorePendingResponseCallback)cb, user_data);
- tcore_pending_link_user_request(pending, ur);
- tcore_pending_set_priority(pending, TCORE_PENDING_PRIORITY_DEFAULT);
-
- tcore_pending_set_send_callback(pending, on_confirmation_call_control_ss_message_send, NULL);
-
-
- tcore_hal_send_request(h, pending);
-
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn s_ss_manage_call_3_send( CoreObject* o, UserRequest* ur, ConfirmCallback cb, void* user_data )
-{
-// gboolean ret = FALSE;
- TcorePlugin *p = NULL;
- TcoreHal *h = NULL;
- TcorePending *pending = NULL;
- char* cmd_str = NULL;
- struct ATReqMetaInfo metainfo;
- int info_len =0;
-
- GSList *l = 0;
- CallObject *co = 0;
- int id = 0;
-
- l = tcore_call_object_find_by_status( o, CALL_STATUS_ACTIVE );
- if ( !l || !l->data ) {
- dbg("[ error ] there is no call status [ call_active ]");
- return TCORE_RETURN_FAILURE;
- }
-
- co = l->data;
- id = tcore_call_object_get_id( co );
- dbg("active call id : [ %d ]");
-
- p = tcore_object_ref_plugin(o);
- h = tcore_object_get_hal(o);
-
- memset(&metainfo, 0, sizeof(struct ATReqMetaInfo));
- metainfo.type = NO_RESULT;
- metainfo.responsePrefix[0] ='\0';
- info_len = sizeof(struct ATReqMetaInfo);
-
- tcore_user_request_set_metainfo(ur, info_len, &metainfo);
-
- cmd_str = g_strdup_printf("%s%s", "AT+CHLD=3","\r");
-
- dbg("cmd : %s, prefix(if any) : %s, cmd_len : %d",cmd_str, "N/A", strlen(cmd_str));
-
- pending = tcore_pending_new(o, ID_RESERVED_AT);
- tcore_pending_set_request_data(pending, strlen(cmd_str), cmd_str);
- g_free(cmd_str);
- tcore_pending_set_timeout(pending, 0);
- tcore_pending_set_response_callback(pending, (TcorePendingResponseCallback)cb, user_data);
- tcore_pending_link_user_request(pending, ur);
- tcore_pending_set_priority(pending, TCORE_PENDING_PRIORITY_DEFAULT);
-
- tcore_pending_set_send_callback(pending, on_confirmation_call_control_ss_message_send, NULL);
-
-
- tcore_hal_send_request(h, pending);
-
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn s_ss_manage_call_4_send( CoreObject* o, UserRequest* ur, ConfirmCallback cb, void* user_data )
-{
- TcorePlugin *p = NULL;
- TcoreHal *h = NULL;
- TcorePending *pending = NULL;
- char* cmd_str = NULL;
- struct ATReqMetaInfo metainfo;
- int info_len =0;
-
- p = tcore_object_ref_plugin(o);
- h = tcore_object_get_hal(o);
-
- memset(&metainfo, 0, sizeof(struct ATReqMetaInfo));
- metainfo.type = NO_RESULT;
- metainfo.responsePrefix[0] ='\0';
- info_len = sizeof(struct ATReqMetaInfo);
-
- tcore_user_request_set_metainfo(ur, info_len, &metainfo);
-
-
- cmd_str = g_strdup_printf("%s%s", "AT+CHLD=4", "\r");
-
- dbg("cmd : %s, prefix(if any) : %s, cmd_len : %d",cmd_str, "N/A", strlen(cmd_str));
-
- pending = tcore_pending_new(o, ID_RESERVED_AT);
- tcore_pending_set_request_data(pending, strlen(cmd_str), cmd_str);
- g_free(cmd_str);
- tcore_pending_set_timeout(pending, 0);
- tcore_pending_set_response_callback(pending, (TcorePendingResponseCallback)cb, user_data);
- tcore_pending_link_user_request(pending, ur);
- tcore_pending_set_priority(pending, TCORE_PENDING_PRIORITY_DEFAULT);
-
- tcore_pending_set_send_callback(pending, on_confirmation_call_control_ss_message_send, NULL);
-
-
- tcore_hal_send_request(h, pending);
-
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn s_ss_manage_call_4dn_send( CoreObject* o, UserRequest* ur, const char* number, ConfirmCallback cb, void* user_data )
-{
- TcorePlugin *p = NULL;
- TcoreHal *h = NULL;
- TcorePending *pending = NULL;
- char* cmd_str = NULL;
- struct ATReqMetaInfo metainfo;
- int info_len =0;
-
- p = tcore_object_ref_plugin(o);
- h = tcore_object_get_hal(o);
-
- memset(&metainfo, 0, sizeof(struct ATReqMetaInfo));
- metainfo.type = NO_RESULT;
- metainfo.responsePrefix[0] ='\0';
- info_len = sizeof(struct ATReqMetaInfo);
-
- tcore_user_request_set_metainfo(ur, info_len, &metainfo);
-
-
- cmd_str = g_strdup_printf("%s%s%s", "AT+CHLD=4", number,"\r");
-
- dbg("cmd : %s, prefix(if any) : %s, cmd_len : %d",cmd_str, "N/A", strlen(cmd_str));
-
- pending = tcore_pending_new(o, ID_RESERVED_AT);
- tcore_pending_set_request_data(pending, strlen(cmd_str), cmd_str);
- g_free(cmd_str);
- tcore_pending_set_timeout(pending, 0);
- tcore_pending_set_response_callback(pending, (TcorePendingResponseCallback)cb, user_data);
- tcore_pending_link_user_request(pending, ur);
- tcore_pending_set_priority(pending, TCORE_PENDING_PRIORITY_DEFAULT);
-
- tcore_pending_set_send_callback(pending, on_confirmation_call_control_ss_message_send, NULL);
-
-
- tcore_hal_send_request(h, pending);
-
- return TCORE_RETURN_SUCCESS;
-}
-
-gboolean s_ss_init(TcorePlugin *cp, CoreObject *co)
-{
- CoreObject *co_call;
-
- dbg("Entry");
-
- tcore_ss_override_ops(co, &ss_ops);
-
- co_call = tcore_plugin_ref_core_object(cp, CORE_OBJECT_TYPE_CALL);
- if (co_call == NULL) {
- err("Can't find CALL core object");
- return FALSE;
- }
-
- tcore_call_override_ops(co_call, NULL, &call_ops);
-
- tcore_object_add_callback(co, EVENT_SS_INFO, on_notification_ss_info, 0);
- tcore_object_add_callback(co, EVENT_SS_USSD, on_notification_ss_ussd, 0);
-
- dbg("Exit");
-
- return TRUE;
-}
-
-void s_ss_exit(TcorePlugin *cp, CoreObject *co)
-{
- dbg("Exit");
-}