# Set required packages
INCLUDE(FindPkgConfig)
-pkg_check_modules(pkgs REQUIRED glib-2.0 tcore dlog db-util libxml-2.0 libtzplatform-config)
+pkg_check_modules(pkgs REQUIRED glib-2.0 tcore dlog db-util libxml-2.0 libtzplatform-config vconf)
FOREACH(flag ${pkgs_CFLAGS})
SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
MESSAGE(${CMAKE_EXE_LINKER_FLAGS})
SET(SRCS
- src/desc.c
- src/s_modem.c
- src/s_common.c
- src/s_network.c
- src/s_sim.c
- src/s_sat.c
- src/s_call.c
- src/s_ss.c
- src/s_ps.c
- src/s_sms.c
- src/s_phonebook.c
- src/s_sap.c
- src/s_gps.c
- src/nvm/nvm.c
+ src/desc-imc.c
+ src/imc_modem.c
+ src/imc_network.c
+ src/imc_sim.c
+ src/imc_sat.c
+ src/imc_call.c
+ src/imc_ss.c
+ src/imc_ps.c
+ src/imc_sms.c
+ src/imc_phonebook.c
+ src/imc_sap.c
+ src/imc_gps.c
+ src/imc_common.c
+ src/nvm/nvm.c
)
+++ /dev/null
-/*
- * tel-plugin-imc
- *
- * 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.
- */
-
-/**
- * @open
- * @ingroup TelephonyAPI
- * @addtogroup COMMON_TAPI COMMON
- * @{
- * These error codes are used by Applications.
- */
-
-
-#ifndef _TEL_ERR_H_
-#define _TEL_ERR_H_
-/*==================================================================================================
- INCLUDE FILES
-==================================================================================================*/
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-/*==================================================================================================
- CONSTANTS
-==================================================================================================*/
-
-
-/*==================================================================================================
- MACROS
-==================================================================================================*/
-
-
-/*==================================================================================================
- ENUMS
-==================================================================================================*/
-
-/************************************************************
-** Errors defined in "+CME ERROR" ,
-** - see 3GPP TS 27.007
-** - ranges are 0x00 ~ 0x7FFF
-************************************************************/
-/**
- Error codes sent by the modem in response to the above operations.
-*/
-typedef enum {
- /* GENERAL ERRORS */
- TAPI_OP_GEN_ERR_PHONE_FAILURE = 0, /* 0 */
- TAPI_OP_GEN_ERR_NO_CONNECTION_TO_PHONE, /* 1 */
- TAPI_OP_GEN_ERR_PHONE_ADAPTOR_LINK_RESERVED, /* 2 */
- TAPI_OP_GEN_ERR_OPER_NOT_ALLOWED, /* 3 */
- TAPI_OP_GEN_ERR_OPER_NOT_SUPPORTED, /* 4 */
- TAPI_OP_GEN_ERR_PH_SIM_PIN_REQU, /* 5 */
- TAPI_OP_GEN_ERR_PH_FSIM_PIN_REQU, /* 6 */
- TAPI_OP_GEN_ERR_PH_FSIM_PUK_REQU, /* 7 */
- TAPI_OP_GEN_ERR_SIM_NOT_INSERTED = 10, /* 10 */
- TAPI_OP_GEN_ERR_SIM_PIN_REQU, /* 11 */
- TAPI_OP_GEN_ERR_SIM_PUK_REQU, /* 12 */
- TAPI_OP_GEN_ERR_SIM_FAILURE, /* 13 */
- TAPI_OP_GEN_ERR_SIM_BUSY, /* 14 */
- TAPI_OP_GEN_ERR_SIM_WRONG, /* 15 */
- TAPI_OP_GEN_ERR_INCORRECT_PW, /* 16 */
- TAPI_OP_GEN_ERR_SIM_PIN2_REQU, /* 17 */
- TAPI_OP_GEN_ERR_SIM_PUK2_REQU, /* 18 */
- TAPI_OP_GEN_ERR_MEM_FULL = 20, /* 20 */
- TAPI_OP_GEN_ERR_INVALID_INDEX, /* 21 */
- TAPI_OP_GEN_ERR_NOT_FOUND, /* 22 */
- TAPI_OP_GEN_ERR_MEM_FAILURE, /* 23 */
- TAPI_OP_GEN_ERR_TEXT_STR_TOO_LONG, /* 24 */
- TAPI_OP_GEN_ERR_INVALID_CHARACTERS_IN_TEXT_STR, /* 25 */
- TAPI_OP_GEN_ERR_DIAL_STR_TOO_LONG, /* 26 */
- TAPI_OP_GEN_ERR_INVALID_CHARACTERS_IN_DIAL_STR, /* 27 */
- TAPI_OP_GEN_ERR_NO_NET_SVC = 30, /* 30 */
- TAPI_OP_GEN_ERR_NET_TIMEOUT, /* 31 */
- TAPI_OP_GEN_ERR_NET_NOT_ALLOWED_EMERGENCY_CALLS_ONLY, /* 32 */
- TAPI_OP_GEN_ERR_NET_PERS_PIN_REQU = 40, /* 40 */
- TAPI_OP_GEN_ERR_NET_PERS_PUK_REQU, /* 41 */
- TAPI_OP_GEN_ERR_NET_SUBSET_PERS_PIN_REQU, /* 42 */
- TAPI_OP_GEN_ERR_NET_SUBSET_PERS_PUK_REQU, /* 43 */
- TAPI_OP_GEN_ERR_SVC_PROVIDER_PERS_PIN_REQU, /* 44 */
- TAPI_OP_GEN_ERR_SVC_PROVIDER_PERS_PUK_REQU, /* 45 */
- TAPI_OP_GEN_ERR_CORPORATE_PERS_PIN_REQU, /* 46 */
- TAPI_OP_GEN_ERR_CORPORATE_PERS_PUK_REQU, /* 47 */
- TAPI_OP_GEN_ERR_HIDDEN_KEY_REQU, /* 48 */
- TAPI_OP_GEN_ERR_UNKNOWN = 100, /* 100 */
-
- /* Errors related to a failure to perform an Attach */
- TAPI_OP_GEN_ERR_ILLEGAL_MS = 103, /* 103 */
- TAPI_OP_GEN_ERR_ILLEGAL_ME = 106, /* 106 */
- TAPI_OP_GEN_ERR_GPRS_SVC_NOT_ALLOWED, /* 107 */
- TAPI_OP_GEN_ERR_PLMN_NOT_ALLOWED = 111, /* 111 */
- TAPI_OP_GEN_ERR_LOCATION_AREA_NOT_ALLOWED, /* 112 */
- TAPI_OP_GEN_ERR_ROAMING_NOT_ALLOWED_IN_THIS_LOCATION_AREA, /* 113 */
-
- /* Errors related to a failure to Activate a Context */
- TAPI_OP_GEN_ERR_SVC_OPT_NOT_SUPPORTED = 132, /* 132 */
- TAPI_OP_GEN_ERR_REQ_SVC_OPT_NOT_SUBSCRIBED, /* 133 */
- TAPI_OP_GEN_ERR_SVC_OPT_TEMPORARILY_OUT_OF_ORDER, /* 134 */
- TAPI_OP_GEN_ERR_UNSPECIFIED_GPRS_ERR = 148, /* 148 */
- TAPI_OP_GEN_ERR_PDP_AUTHENTICATION_FAILURE, /* 149 */
- TAPI_OP_GEN_ERR_INVALID_MOBILE_CLASS, /* 150 */
-
- /* VBS / VGCS and eMLPP -related errors */
- TAPI_OP_GEN_ERR_VBS_VGCS_NOT_SUPPORTED_BY_THE_NET = 151, /* 151 */
- TAPI_OP_GEN_ERR_NO_SVC_SUBSCRIPTION_ON_SIM, /* 152 */
- TAPI_OP_GEN_ERR_NO_SUBSCRIPTION_FOR_GROUP_ID, /* 153 */
- TAPI_OP_GEN_ERR_GROUP_ID_NOT_ACTIVATED_ON_SIM, /* 154 */
- TAPI_OP_GEN_ERR_NO_MATCHING_NOTI = 155, /* 155 */
- TAPI_OP_GEN_ERR_VBS_VGCS_CALL_ALREADY_PRESENT, /* 156 */
- TAPI_OP_GEN_ERR_CONGESTION, /* 157 */
- TAPI_OP_GEN_ERR_NET_FAILURE, /* 158 */
- TAPI_OP_GEN_ERR_UPLINK_BUSY, /* 159 */
- TAPI_OP_GEN_ERR_NO_ACCESS_RIGHTS_FOR_SIM_FILE = 160, /* 160 */
- TAPI_OP_GEN_ERR_NO_SUBSCRIPTION_FOR_PRIORITY, /* 161 */
- TAPI_OP_GEN_ERR_OPER_NOT_APPLICABLE_OR_NOT_POSSIBLE, /* 162 */
-
-
- /************************************************************
- ** SAMSUNG ADDED ERRORS
- ************************************************************/
- TAPI_OP_GEN_ERR_NONE = 0x8000, /* 0x8000 : No Errors */
-
- /* General Common Errors : 0x8000 - 0x80FF */
- TAPI_OP_GEN_ERR_INVALID_FORMAT, /* 0x8001 : Invalid Parameter or Format */
- TAPI_OP_GEN_ERR_PHONE_OFFLINE, /* 0x8002 : */
- TAPI_OP_GEN_ERR_CMD_NOT_ALLOWED, /* 0x8003 : */
- TAPI_OP_GEN_ERR_PHONE_IS_INUSE, /* 0x8004 : */
- TAPI_OP_GEN_ERR_INVALID_STATE = 0x8005, /* 0x8005 : */
-
- TAPI_OP_GEN_ERR_NO_BUFFER, /* 0x8006 : No internal free buffers */
- TAPI_OP_GEN_ERR_OPER_REJ, /* 0x8007 : Operation Rejected */
- TAPI_OP_GEN_ERR_INSUFFICIENT_RESOURCE, /* 0x8008 : insufficient resource */
- TAPI_OP_GEN_ERR_NET_NOT_RESPOND, /* 0x8009 : Network not responding */
- TAPI_OP_GEN_ERR_SIM_PIN_ENABLE_REQ = 0x800A, /* 0x800A : SIM Pin Enable Required */
- TAPI_OP_GEN_ERR_SIM_PERM_BLOCKED, /* 0x800B : SIM Permanent Blocked */
- TAPI_OP_GEN_ERR_SIM_PHONEBOOK_RESTRICTED, /*0x800C: SIM Phonebook Restricted*/
- TAPI_OP_GEM_ERR_FIXED_DIALING_NUMBER_ONLY, /*0x800D: Restricted By FDN Mode */
-
- /* Reserved : 0x800E ~ 0x80FF */
- TAPI_OP_GEN_ERR_800E_RESERVED_START = 0x800E, /* 0x800E */
-
- TAPI_OP_GEN_ERR_80FF_RESERVED_END = 0x80ff, /* 0x80FF */
-
- /* the other errors */
- TAPI_OP_GEN_ERR_OTHERS = 0xFFFE, /* 0xFFFE */
-
- TAPI_OP_GEN_ERR_MAX = 0xFFFF
-} tapi_phone_err_t;
-
-
-/*==================================================================================================
- STRUCTURES AND OTHER TYPEDEFS
-==================================================================================================*/
-
-
-/*==================================================================================================
- FUNCTION PROTOTYPES
-==================================================================================================*/
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // _TEL_ERR_H_
-
-/**
-* @}
-*/
/*
* tel-plugin-imc
*
- * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: Arun Shukla <arun.shukla@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_GPS_H__
-#define __S_GPS_H__
+#ifndef __IMC_CALL_H__
+#define __IMC_CALL_H__
-gboolean s_gps_init(TcorePlugin *cp, CoreObject *co_gps);
-void s_gps_exit(TcorePlugin *cp, CoreObject *co_gps);
+gboolean imc_call_init(TcorePlugin *p, CoreObject *co);
+void imc_call_exit(TcorePlugin *p, CoreObject *co);
-#endif
+#endif /* __IMC_CALL_H__ */
--- /dev/null
+/*
+ * tel-plugin-imc
+ *
+ * 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 __IMC_COMMON_H__
+#define __IMC_COMMON_H__
+
+#define IMC_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 */
+} ImcRespCbData;
+
+#define IMC_GET_DATA_FROM_RESP_CB_DATA(ptr) (gpointer)ptr->data
+#define IMC_CHECK_REQUEST_RET(ret, resp_cb_data, request) \
+do {\
+ if (ret != TEL_RETURN_SUCCESS) { \
+ err("Failed to process request - [%s]", request); \
+ imc_destroy_resp_cb_data(resp_cb_data); \
+ } \
+} while(0)
+
+ImcRespCbData *imc_create_resp_cb_data(TcoreObjectResponseCallback cb,
+ void *cb_data, void *data, guint data_len);
+void imc_destroy_resp_cb_data(ImcRespCbData *resp_cb_data);
+
+void on_send_imc_request(TcorePending *p,
+ TelReturn send_status, void *user_data);
+
+#endif /* __IMC_COMMON_H__ */
/*
* tel-plugin-imc
*
- * 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.
* limitations under the License.
*/
-#ifndef __S_DISPATCH_H__
-#define __S_DISPATCH_H__
+#ifndef __IMC_DISPATCH_H__
+#define __IMC_DISPATCH_H__
void do_factory(TcoreHal *h, const ipc_message_type *ipc);
void do_notification_message(TcorePlugin *p, const ipc_message_type *ipc);
void do_notification_sys_message(TcorePlugin *p, const void *data);
-#endif
+#endif /* __IMC_DISPATCH_H__ */
/*
* tel-plugin-imc
*
- * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: Sharanayya Mathapati <sharan.m@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 __IMC_GPS_H__
+#define __IMC_GPS_H__
-gboolean s_ss_init(TcorePlugin *cp, CoreObject *co_ss);
-void s_ss_exit(TcorePlugin *cp, CoreObject *co_ss);
+gboolean imc_gps_init(TcorePlugin *p, CoreObject *co);
+void imc_gps_exit(TcorePlugin *p, CoreObject *co);
-#endif
+#endif /* __IMC_GPS_H__ */
/*
* tel-plugin-imc
*
- * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: Sharanayya Mathapati <sharan.m@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_CALL_H__
-#define __S_CALL_H__
+#ifndef __IMC_MODEM_H__
+#define __IMC_MODEM_H__
+
+gboolean imc_modem_init(TcorePlugin *p, CoreObject *co);
+void imc_modem_exit(TcorePlugin *p, CoreObject *co);
-gboolean s_call_init(TcorePlugin *cp, CoreObject *co_call);
-void s_call_exit(TcorePlugin *cp, CoreObject *co_call);
+void imc_modem_register_nvm(CoreObject *co);
+gboolean imc_modem_power_on_modem(TcorePlugin *plugin);
-#endif
+#endif /* __IMC_MODEM_H__ */
/*
* tel-plugin-imc
*
- * 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_SAP_H_
-#define S_SAP_H_
+#ifndef __IMC_NETWORK_H__
+#define __IMC_NETWORK_H__
-gboolean s_sap_init(TcorePlugin *cp, CoreObject *co_sap);
-void s_sap_exit(TcorePlugin *cp, CoreObject *co_sap);
+gboolean imc_network_init(TcorePlugin *p, CoreObject *co);
+void imc_network_exit(TcorePlugin *p, CoreObject *co);
-#endif /* S_SAP_H_ */
+#endif /* __IMC_NETWORK_H__ */
/*
* tel-plugin-imc
*
- * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: Madhavi Akella <madhavi.a@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 __IMC_PHONEBOOK_H__
+#define __IMC_PHONEBOOK_H__
-gboolean s_sms_init(TcorePlugin *cp, CoreObject *co_sms);
-void s_sms_exit(TcorePlugin *cp, CoreObject *co_sms);
+gboolean imc_phonebook_init(TcorePlugin *p, CoreObject *co);
+void imc_phonebook_exit(TcorePlugin *p, CoreObject *co);
-#endif // S_SMS_H_
+#endif /* __IMC_PHONEBOOK_H__ */
--- /dev/null
+/*
+ * tel-plugin-imc
+ *
+ * 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 __IMC_PS_H__
+#define __IMC_PS_H__
+
+gboolean imc_ps_init(TcorePlugin *p, CoreObject *co);
+void imc_ps_exit(TcorePlugin *p, CoreObject *co);
+
+#endif /*__IMC_PS_H__*/
--- /dev/null
+/*
+ * tel-plugin-imc
+ *
+ * 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 __IMC_SAP_H__
+#define __IMC_SAP_H__
+
+gboolean imc_sap_init(TcorePlugin *p, CoreObject *co);
+void imc_sap_exit(TcorePlugin *p, CoreObject *co);
+
+#endif /* __IMC_SAP_H__ */
--- /dev/null
+/*
+ * tel-plugin-imc
+ *
+ * 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 __IMC_SAT_H__
+#define __IMC_SAT_H__
+
+gboolean imc_sat_init(TcorePlugin *p, CoreObject *co);
+void imc_sat_exit(TcorePlugin *p, CoreObject *co);
+
+#endif /* __IMC_SAT_H__ */
/*
* tel-plugin-imc
*
- * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: Harish Bishnoi <hbishnoi@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 __IMC_SIM_H__
+#define __IMC_SIM_H__
-#ifndef S_SAT_H_
-#define S_SAT_H_
+gboolean imc_sim_get_smsp_info(TcorePlugin *plugin, int *rec_count, int *rec_len);
-gboolean s_sat_init(TcorePlugin *cp, CoreObject *co_sat);
-void s_sat_exit(TcorePlugin *cp, CoreObject *co_sat);
+gboolean imc_sim_init(TcorePlugin *p, CoreObject *co);
+void imc_sim_exit(TcorePlugin *p, CoreObject *co);
-#endif /* S_SAT_H_ */
+#endif /* __IMC_SIM_H__ */
--- /dev/null
+/*
+ * tel-plugin-imc
+ *
+ * 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 __IMC_SMS_H__
+#define __IMC_SMS_H__
+
+gboolean imc_sms_init(TcorePlugin *p, CoreObject *co);
+void imc_sms_exit(TcorePlugin *p, CoreObject *co);
+
+#endif /* __IMC_SMS_H__ */
--- /dev/null
+/*
+ * tel-plugin-imc
+ *
+ * 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 __IMC_SS_H__
+#define __IMC_SS_H__
+
+gboolean imc_ss_init(TcorePlugin *p, CoreObject *co);
+void imc_ss_exit(TcorePlugin *p, CoreObject *co);
+
+#endif /* __IMC_SS_H__ */
/*
* tel-plugin-imc
*
- * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: Paresh Agarwal<paresh.agwl@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
-/*
- * tel-plugin-imc
- *
- * 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 <glib.h>
-
-void util_hex_dump(char *pad, int size, const void *data);
-unsigned char util_hexCharToInt(char c);
-char *util_hex_to_string(const char *src, unsigned int src_len);
-char* util_hexStringToBytes(char *s);
-char* util_removeQuotes(void *data);
-
-#endif
+++ /dev/null
-/*
- * tel-plugin-imc
- *
- * 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_MODEM_H__
-#define __S_MODEM_H__
-
-gboolean s_modem_init(TcorePlugin *cp, CoreObject *co_modem);
-void s_modem_exit(TcorePlugin *cp, CoreObject *co_modem);
-
-gboolean modem_power_on(TcorePlugin *plugin);
-void modem_register_nvm(CoreObject *co_modem);
-
-#endif
+++ /dev/null
-/*
- * tel-plugin-imc
- *
- * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: Harish Bishnoi <hbishnoi@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_NETWORK_H__
-#define __S_NETWORK_H__
-
-gboolean s_network_init(TcorePlugin *cp, CoreObject *co_network);
-void s_network_exit(TcorePlugin *cp, CoreObject *co_network);
-
-#endif
+++ /dev/null
-/*
- * tel-plugin-imc
- *
- * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: Ja-young Gu <jygu@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_PHONEBOOK_H_
-#define S_PHONEBOOK_H_
-
-gboolean s_phonebook_init(TcorePlugin *cp, CoreObject *co_phonebook);
-void s_phonebook_exit(TcorePlugin *cp, CoreObject *co_phonebook);
-
-#endif /* S_PHONEBOOK_H_ */
+++ /dev/null
-/*
- * tel-plugin-imc
- *
- * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: Arun Shukla <arun.shukla@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_PS_H__
-#define __S_PS_H__
-
-gboolean s_ps_init(TcorePlugin *cp, CoreObject *co_ps);
-void s_ps_exit(TcorePlugin *cp, CoreObject *co_ps);
-
-#endif /*__S_PS_H__*/
+++ /dev/null
-/**
- * tel-plugin-imc
- *
- * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Contact: Ankit Jogi <ankit.jogi@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_SIM_H__
-#define __S_SIM_H__
-
-gboolean s_sim_init(TcorePlugin *cp, CoreObject *co_sim);
-void s_sim_exit(TcorePlugin *cp, CoreObject *co_sim);
-
-#endif
--- /dev/null
+<manifest>
+ <request>
+ <domain name="telephony_framework"/>
+ </request>
+ <assign>
+ <filesystem path="/usr/lib/telephony/plugins/imc-plugin.so" label="telephony_framework"/>
+ </assign>
+ <request>
+ <domain name="telephony_framework"/>
+ </request>
+</manifest>
#sbs-git:slp/pkgs/t/tel-plugin-imc
+%define major 3
+%define minor 0
+%define patchlevel 1
+
Name: tel-plugin-imc
Summary: imc plugin for telephony
-Version: 0.1.42
-Release: 1
+Version: %{major}.%{minor}.%{patchlevel}
+Release: 1
Group: Development/Libraries
License: Apache-2.0
Source0: tel-plugin-imc-%{version}.tar.gz
BuildRequires: pkgconfig(db-util)
BuildRequires: pkgconfig(libxml-2.0)
BuildRequires: pkgconfig(libtzplatform-config)
+BuildRequires: pkgconfig(vconf)
%description
IMC plugin for telephony
/*
* tel-plugin-imc
*
- * 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.
--- /dev/null
+/*
+ * tel-plugin-imc
+ *
+ * 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 <at.h>
+
+#include "imc_modem.h"
+#include "imc_sim.h"
+#include "imc_sat.h"
+#include "imc_sap.h"
+#include "imc_network.h"
+#include "imc_ps.h"
+#include "imc_call.h"
+#include "imc_ss.h"
+#include "imc_sms.h"
+#include "imc_phonebook.h"
+#include "imc_gps.h"
+
+#include "imc_common.h"
+
+/* Initializer Table */
+TcoreObjectInitializer imc_init_table = {
+ .modem_init = imc_modem_init,
+ .sim_init = imc_sim_init,
+ .sat_init = imc_sat_init,
+ .sap_init = imc_sap_init,
+ .network_init = imc_network_init,
+ .ps_init = imc_ps_init,
+ .call_init = imc_call_init,
+ .ss_init = imc_ss_init,
+ .sms_init = imc_sms_init,
+ .phonebook_init = imc_phonebook_init,
+ .gps_init = imc_gps_init,
+};
+
+/* Deinitializer Table */
+TcoreObjectDeinitializer imc_deinit_table = {
+ .modem_deinit = imc_modem_exit,
+ .sim_deinit = imc_sim_exit,
+ .sat_deinit = imc_sat_exit,
+ .sap_deinit = imc_sap_exit,
+ .network_deinit = imc_network_exit,
+ .ps_deinit = imc_ps_exit,
+ .call_deinit = imc_call_exit,
+ .ss_deinit = imc_ss_exit,
+ .sms_deinit = imc_sms_exit,
+ .phonebook_deinit = imc_phonebook_exit,
+ .gps_deinit = imc_gps_exit,
+};
+
+static void __send_request(CoreObject *co, const gchar *at_cmd,
+ TcorePendingResponseCallback resp_cb, void *resp_cb_data)
+{
+ (void)tcore_at_prepare_and_send_request(co, at_cmd, NULL,
+ TCORE_AT_COMMAND_TYPE_NO_RESULT,
+ TCORE_PENDING_PRIORITY_DEFAULT,
+ NULL,
+ resp_cb, resp_cb_data,
+ on_send_imc_request, NULL,
+ 0, NULL, NULL);
+}
+
+static void __on_response_subscribe_bootup_notification(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("Subscription for '%s' - [OK]", (gchar *)user_data);
+ } else {
+ err("Subscription for '%s' - [NOK]", (gchar *)user_data);
+ }
+
+ /* Free resource */
+ tcore_free(user_data);
+}
+
+static void __on_response_subscribe_bootup_notification_last(TcorePending *p,
+ guint data_len, const void *data, void *user_data)
+{
+ const TcoreAtResponse *at_resp = data;
+ TcorePlugin *plugin = tcore_pending_ref_plugin(p);
+ gboolean ret;
+
+ if (at_resp && at_resp->success) {
+ dbg("[Last] Subscription for '%s' - [OK]", (gchar *)user_data);
+ } else {
+ err("[Last] Subscription for '%s' - [NOK]", (gchar *)user_data);
+ }
+
+ /* Free resource */
+ tcore_free(user_data);
+
+ dbg("Boot-up configration completed for IMC modem, "
+ "Bring CP to ONLINE state based on Flight mode status");
+
+ /* Modem Power */
+ ret = imc_modem_power_on_modem(plugin);
+ dbg("Modem Power ON: [%s]", (ret == TRUE ? "SUCCESS" : "FAIL"));
+
+ /* NVM Registration */
+ dbg("Registering modem for NVM manager");
+ imc_modem_register_nvm(tcore_plugin_ref_core_object(plugin, CORE_OBJECT_TYPE_MODEM));
+}
+
+static void __subscribe_modem_notifications(TcorePlugin *plugin)
+{
+ CoreObject *call, *sim, *sms, *network, *ps, *gps;
+ dbg("Entry");
+
+ /*
+ * URC Subscriptions
+ */
+ /****** SIM subscriptions ******/
+ sim = tcore_plugin_ref_core_object(plugin, CORE_OBJECT_TYPE_SIM);
+ /* XSIMSTATE */
+ __send_request(sim, "AT+XSIMSTATE=1",
+ __on_response_subscribe_bootup_notification,
+ tcore_strdup("AT+XSIMSTATE=1"));
+
+ /****** CALL subscriptions ******/
+ call = tcore_plugin_ref_core_object(plugin, CORE_OBJECT_TYPE_CALL);
+ /* XCALLSTAT */
+ __send_request(call, "AT+XCALLSTAT=1",
+ __on_response_subscribe_bootup_notification,
+ tcore_strdup("AT+XCALLSTAT=1"));
+
+ /* CSSN */
+ __send_request(call, "AT+CSSN=1,1",
+ __on_response_subscribe_bootup_notification,
+ tcore_strdup("AT+CSSN=1,1"));
+
+ /* CUSD */
+ __send_request(call, "AT+CUSD=1",
+ __on_response_subscribe_bootup_notification,
+ tcore_strdup("AT+CUSD=1"));
+
+ /* CLIP */
+ __send_request(call, "AT+CLIP=1",
+ __on_response_subscribe_bootup_notification,
+ tcore_strdup("AT+CLIP=1"));
+
+ /****** NETWORK subscriptions ******/
+ network = tcore_plugin_ref_core_object(plugin, CORE_OBJECT_TYPE_NETWORK);
+ /* CREG */
+ __send_request(network, "AT+CREG=2",
+ __on_response_subscribe_bootup_notification,
+ tcore_strdup("AT+CREG=2"));
+
+ /* CGREG */
+ __send_request(network, "AT+CGREG=2",
+ __on_response_subscribe_bootup_notification,
+ tcore_strdup("AT+CGREG=2"));
+
+ /* Allow Automatic Time Zone updation via NITZ */
+ __send_request(network, "AT+CTZU=1",
+ __on_response_subscribe_bootup_notification,
+ tcore_strdup("AT+CTZU=1"));
+
+ /* TZ, Time & Daylight changing event reporting Subscription */
+ __send_request(network, "AT+CTZR=1",
+ __on_response_subscribe_bootup_notification,
+ tcore_strdup("AT+CTZR=1"));
+
+ /* XMER */
+ __send_request(network, "AT+XMER=1",
+ __on_response_subscribe_bootup_notification,
+ tcore_strdup("AT+XMER=1"));
+
+ /****** PS subscriptions ******/
+ ps = tcore_plugin_ref_core_object(plugin, CORE_OBJECT_TYPE_PS);
+ /* CGEREP */
+ __send_request(ps, "AT+CGEREP=1",
+ __on_response_subscribe_bootup_notification,
+ tcore_strdup("AT+CGEREP=1"));
+
+ /* XDATASTAT */
+ __send_request(ps, "AT+XDATASTAT=1",
+ __on_response_subscribe_bootup_notification,
+ tcore_strdup("AT+XDATASTAT=1"));
+
+ /* XDNS */
+ __send_request(ps, "AT+XDNS=1,1",
+ __on_response_subscribe_bootup_notification,
+ tcore_strdup("AT+XDNS=1,1"));
+
+ /* CMEE */
+ __send_request(ps, "AT+CMEE=2",
+ __on_response_subscribe_bootup_notification,
+ tcore_strdup("AT+CMEE=2"));
+
+ /****** SMS subscriptions ******/
+ sms = tcore_plugin_ref_core_object(plugin, CORE_OBJECT_TYPE_SMS);
+ /* CMEE */
+ __send_request(sms, "AT+CMEE=2",
+ __on_response_subscribe_bootup_notification,
+ tcore_strdup("AT+CMEE=2"));
+
+ /* Incoming SMS, Cell Broadcast, Status Report Subscription */
+ __send_request(sms, "AT+CNMI=1,2,2,1,0",
+ __on_response_subscribe_bootup_notification,
+ tcore_strdup("AT+CNMI=1,2,2,1,0"));
+
+ /* Text/PDU mode Subscription */
+ __send_request(sms, "AT+CMGF=0",
+ __on_response_subscribe_bootup_notification,
+ tcore_strdup("AT+CMGF=0"));
+
+#if 0 /* Temporarily Blocking as modem doesn't support */
+ /****** SAP subscriptions ******/
+ sap = tcore_plugin_ref_core_object(plugin, CORE_OBJECT_TYPE_SAP);
+ /* XBCSTAT */
+ __send_request(sap, "AT+XBCSTAT=1",
+ __on_response_subscribe_bootup_notification,
+ tcore_strdup("AT+XBCSTAT=1"));
+#endif /* Temporarily Blocking as modem doesn't support */
+
+ /****** GPS subscriptions ******/
+ gps = tcore_plugin_ref_core_object(plugin, CORE_OBJECT_TYPE_GPS);
+ /* AGPS- Assist Data and Reset Assist Data Subscription */
+ __send_request(gps, "AT+CPOSR=1",
+ __on_response_subscribe_bootup_notification,
+ tcore_strdup("AT+CPOSR=1"));
+
+ __send_request(gps, "AT+XCPOSR=1",
+ __on_response_subscribe_bootup_notification_last,
+ tcore_strdup("AT+XCPOSR=1"));
+
+ dbg("Exit");
+}
+
+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, &imc_init_table)
+ != TEL_RETURN_SUCCESS) {
+ err("Failed to initialize Core Objects");
+ return FALSE;
+ }
+
+ /* Subscribe for the Events from CP */
+ __subscribe_modem_notifications(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, &imc_deinit_table);
+}
+
+/* IMC - Modem Plug-in Descriptor */
+struct tcore_plugin_define_desc plugin_define_desc = {
+ .name = "imc",
+ .priority = TCORE_PLUGIN_PRIORITY_MID,
+ .version = 1,
+ .load = on_load,
+ .init = on_init,
+ .unload = on_unload
+};
+++ /dev/null
-/*
- * tel-plugin-imc
- *
- * 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 <sys/utsname.h>
-#include <glib.h>
-#include <tcore.h>
-#include <server.h>
-#include <plugin.h>
-#include <core_object.h>
-#include <hal.h>
-#include <at.h>
-#include <server.h>
-
-#include "s_network.h"
-#include "s_modem.h"
-#include "s_sim.h"
-#include "s_sap.h"
-#include "s_ps.h"
-#include "s_call.h"
-#include "s_ss.h"
-#include "s_sms.h"
-#include "s_sat.h"
-#include "s_phonebook.h"
-#include "s_gps.h"
-
-static void on_confirmation_modem_message_send(TcorePending *p,
- gboolean result,
- void *user_data)
-{
- dbg("msg out from queue");
-
- dbg("%s", result == FALSE ? "SEND FAIL" : "SEND OK");
-}
-
-static void on_response_bootup_subscription(TcorePending *p,
- int data_len, const void *data, void *user_data)
-{
- const TcoreATResponse *resp = data;
- dbg("Entry");
-
- if (resp->success > 0) {
- dbg("RESULT - OK");
- } else {
- err("RESULT - ERROR");
- }
-}
-
-static void on_response_last_bootup_subscription(TcorePending *p,
- int data_len, const void *data, void *user_data)
-{
- const TcoreATResponse *resp = data;
- TcorePlugin *plugin = tcore_pending_ref_plugin(p);
- gboolean ret;
- dbg("Last Subscription - COMPLETED");
-
- if (resp->success) {
- dbg("RESULT - OK");
- } else {
- err("RESULT - FAIL");
- }
-
- dbg("Boot-up configration completed for IMC modem. %s",
- "Bring CP to ONLINE state based on Flightmode status");
-
- /* Modem Power */
- ret = modem_power_on(plugin);
- dbg("Modem Power ON: [%s]", (ret == TRUE ? "SUCCESS" : "FAIL"));
-
- /* NVM Registration */
- dbg("Registering modem for NVM manager");
- modem_register_nvm(tcore_plugin_ref_core_object(plugin, CORE_OBJECT_TYPE_MODEM));
-}
-
-static void _modem_subscribe_events(TcorePlugin *plugin)
-{
- CoreObject *co_call = tcore_plugin_ref_core_object(plugin, CORE_OBJECT_TYPE_CALL);
- CoreObject *co_sim = tcore_plugin_ref_core_object(plugin, CORE_OBJECT_TYPE_SIM);
- CoreObject *co_sms = tcore_plugin_ref_core_object(plugin, CORE_OBJECT_TYPE_SMS);
- CoreObject *co_network = tcore_plugin_ref_core_object(plugin, CORE_OBJECT_TYPE_NETWORK);
- CoreObject *co_ps = tcore_plugin_ref_core_object(plugin, CORE_OBJECT_TYPE_PS);
- CoreObject *co_sap = tcore_plugin_ref_core_object(plugin, CORE_OBJECT_TYPE_SAP);
- CoreObject *co_gps = tcore_plugin_ref_core_object(plugin, CORE_OBJECT_TYPE_GPS);
-
- dbg("Entry");
-
- /* URC Subscriptions per Module */
-
- /****** SIM subscriptions ******/
- /* XSIMSTATE */
- tcore_prepare_and_send_at_request(co_sim, "at+xsimstate=1", NULL, TCORE_AT_NO_RESULT, NULL,
- on_response_bootup_subscription, NULL,
- on_confirmation_modem_message_send, NULL);
-
- /****** CALL subscriptions ******/
- /* XCALLSTAT */
- tcore_prepare_and_send_at_request(co_call, "at+xcallstat=1", NULL, TCORE_AT_NO_RESULT, NULL,
- on_response_bootup_subscription, NULL,
- on_confirmation_modem_message_send, NULL);
-
- /* CSSN */
- tcore_prepare_and_send_at_request(co_call, "at+cssn=1,1", NULL, TCORE_AT_NO_RESULT, NULL,
- on_response_bootup_subscription, NULL,
- on_confirmation_modem_message_send, NULL);
-
- /* CUSD */
- tcore_prepare_and_send_at_request(co_call, "at+cusd=1", NULL, TCORE_AT_NO_RESULT, NULL,
- on_response_bootup_subscription, NULL,
- on_confirmation_modem_message_send, NULL);
-
- /* CLIP */
- tcore_prepare_and_send_at_request(co_call, "at+clip=1", NULL, TCORE_AT_NO_RESULT, NULL,
- on_response_bootup_subscription, NULL,
- on_confirmation_modem_message_send, NULL);
-
- /****** NETWORK subscriptions ******/
- /* CREG */
- tcore_prepare_and_send_at_request(co_network, "at+creg=2", NULL, TCORE_AT_NO_RESULT, NULL,
- on_response_bootup_subscription, NULL,
- on_confirmation_modem_message_send, NULL);
-
- /* CGREG */
- tcore_prepare_and_send_at_request(co_network, "at+cgreg=2", NULL, TCORE_AT_NO_RESULT, NULL,
- on_response_bootup_subscription, NULL,
- on_confirmation_modem_message_send, NULL);
-
- /* Allow Automatic Time Zone updation via NITZ */
- tcore_prepare_and_send_at_request(co_network, "at+ctzu=1", NULL, TCORE_AT_NO_RESULT, NULL,
- on_response_bootup_subscription, NULL,
- on_confirmation_modem_message_send, NULL);
-
- /* TZ, Time & Daylight changing event reporting Subscription */
- tcore_prepare_and_send_at_request(co_network, "at+ctzr=1", NULL, TCORE_AT_NO_RESULT, NULL,
- on_response_bootup_subscription, NULL,
- on_confirmation_modem_message_send, NULL);
-
- /* XMER */
- tcore_prepare_and_send_at_request(co_network, "at+xmer=1", NULL, TCORE_AT_NO_RESULT, NULL,
- on_response_bootup_subscription, NULL,
- on_confirmation_modem_message_send, NULL);
-
- /****** PS subscriptions ******/
- /* CGEREP */
- tcore_prepare_and_send_at_request(co_ps, "at+cgerep=1", NULL, TCORE_AT_NO_RESULT, NULL,
- on_response_bootup_subscription, NULL,
- on_confirmation_modem_message_send, NULL);
-
- /* XDATASTAT */
- tcore_prepare_and_send_at_request(co_ps, "at+xdatastat=1", NULL, TCORE_AT_NO_RESULT, NULL,
- on_response_bootup_subscription, NULL,
- on_confirmation_modem_message_send, NULL);
-
-
- /* XDNS */
- tcore_prepare_and_send_at_request(co_ps, "at+xdns=1,1", NULL, TCORE_AT_NO_RESULT, NULL,
- on_response_bootup_subscription, NULL,
- on_confirmation_modem_message_send, NULL);
-
- /* CMEE */
- tcore_prepare_and_send_at_request(co_ps, "at+cmee=2", NULL, TCORE_AT_NO_RESULT, NULL,
- on_response_bootup_subscription, NULL,
- on_confirmation_modem_message_send, NULL);
-
- /****** SMS subscriptions ******/
- /* CMEE */
- tcore_prepare_and_send_at_request(co_sms, "at+cmee=2", NULL, TCORE_AT_NO_RESULT, NULL,
- on_response_bootup_subscription, NULL,
- on_confirmation_modem_message_send, NULL);
-
- /* Incoming SMS, Cell Broadcast, Status Report Subscription */
- tcore_prepare_and_send_at_request(co_sms, "at+cnmi=1,2,2,1,0", NULL, TCORE_AT_NO_RESULT, NULL,
- on_response_bootup_subscription, NULL,
- on_confirmation_modem_message_send, NULL);
-
- /* Text/PDU mode Subscription */
- tcore_prepare_and_send_at_request(co_sms, "at+cmgf=0", NULL, TCORE_AT_NO_RESULT, NULL,
- on_response_bootup_subscription, NULL,
- on_confirmation_modem_message_send, NULL);
-
- /****** GPS subscriptions ******/
- /* AGPS- Assist Data and Reset Assist Data Subscription */
- tcore_prepare_and_send_at_request(co_gps, "at+cposr=1", NULL, TCORE_AT_NO_RESULT, NULL,
- on_response_bootup_subscription, NULL,
- on_confirmation_modem_message_send, NULL);
-
- tcore_prepare_and_send_at_request(co_gps, "at+xcposr=1", NULL, TCORE_AT_NO_RESULT, NULL,
- on_response_bootup_subscription, NULL,
- on_confirmation_modem_message_send, NULL);
-
- /****** SAP subscriptions ******/
- /* XBCSTAT */
- tcore_prepare_and_send_at_request(co_sap, "at+xbcstat=1", NULL, TCORE_AT_NO_RESULT, NULL,
- on_response_last_bootup_subscription, NULL,
- on_confirmation_modem_message_send, NULL);
-
- dbg("Exit");
-}
-
-/* Initializer Table */
-struct object_initializer init_table = {
- .modem_init = s_modem_init,
- .sim_init = s_sim_init,
- .sat_init = s_sat_init,
- .sap_init = s_sap_init,
- .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 = s_phonebook_init,
- .gps_init = s_gps_init,
-};
-
-/* Deinitializer Table */
-struct object_deinitializer deinit_table = {
- .modem_deinit = s_modem_exit,
- .sim_deinit = s_sim_exit,
- .sat_deinit = s_sat_exit,
- .sap_deinit = s_sap_exit,
- .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 = s_phonebook_exit,
- .gps_deinit = s_gps_exit,
-};
-
-static gboolean on_load()
-{
- dbg("Load!!!");
-
- return TRUE;
-}
-
-static gboolean on_init(TcorePlugin *p)
-{
- dbg("Init!!!");
- if (p == NULL)
- return FALSE;
-
- /* Initialize Modules (Core Objects) */
- if (tcore_object_init_objects(p, &init_table)
- != TCORE_RETURN_SUCCESS) {
- err("Failed to initialize Core Objects");
- return FALSE;
- }
-
- /* Subscribe for the Events from CP */
- _modem_subscribe_events(p);
-
- dbg("Init - Successful");
- return TRUE;
-}
-
-static void on_unload(TcorePlugin *p)
-{
- dbg("Unload!!!");
-
- if (p == NULL)
- return;
-
- /* Deinitialize Modules (Core Objects) */
- tcore_object_deinit_objects(p, &deinit_table);
-}
-
-/* IMC - Modem Plug-in Descriptor */
-struct tcore_plugin_define_desc plugin_define_desc = {
- .name = "IMC",
- .priority = TCORE_PLUGIN_PRIORITY_MID,
- .version = 1,
- .load = on_load,
- .init = on_init,
- .unload = on_unload
-};
--- /dev/null
+/*
+ * tel-plugin-imc
+ *
+ * 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_call.h>
+
+#include "imc_call.h"
+#include "imc_common.h"
+
+#define COMMA 0X2c
+#define STATUS_INCOMING 4
+#define STATUS_WAITING 5
+#define STATUS_CONNECTED 7
+
+#define find_call_object(co, call_id, call_obj) \
+ do { \
+ call_obj = tcore_call_object_find_by_id(co, call_id); \
+ if (!call_obj) { \
+ err("unable to find call object"); \
+ return; \
+ } \
+ } while (0)
+
+struct imc_set_volume_info {
+ guint next_index;
+ guint volume;
+};
+
+static gchar *xdrv_set_volume[] = {
+ "AT+XDRV=40,7,3,88",
+ "AT+XDRV=40,7,0,88",
+ "AT+XDRV=40,8,0,88",
+ "AT+XDRV=40,8,2,",
+ NULL
+};
+
+/*Forward Declarations*/
+static void on_response_imc_call_default(TcorePending *p,
+ guint data_len, const void *data, void *user_data);
+
+static TelReturn __call_list_get(CoreObject *co, gboolean flag);
+
+
+static TelCallType __call_type(int 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 __call_state(int state)
+{
+ dbg("Entry");
+
+ switch (state) {
+ case 0:
+ return TEL_CALL_STATE_ACTIVE;
+
+ case 1:
+ return TEL_CALL_STATE_HELD;
+
+ case 2:
+ return TEL_CALL_STATE_DIALING;
+
+ case 3:
+ return TEL_CALL_STATE_ALERT;
+
+ case 4:
+ case 5:
+ return TEL_CALL_STATE_INCOMING;
+
+ default:
+ return TEL_CALL_STATE_IDLE;
+ }
+}
+
+static void __call_branch_by_status(CoreObject *co, CallObject *call_obj, TelCallState call_state)
+{
+ unsigned int call_id;
+ TelCallType call_type;
+ TelCallState state;
+ TcoreNotification command = TCORE_NOTIFICATION_UNKNOWN;
+ dbg("Call State[%d]", call_state);
+
+ if (tcore_call_object_get_state(call_obj, &state) == FALSE) {
+ err("unable to get call status");
+ return;
+ }
+
+ if (call_state == state) {
+ dbg("current call state and existing call state are same");
+ 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;
+ }
+
+ /* Set Status */
+ 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: {
+ TelCallIncomingInfo incoming = {0,};
+ command = TCORE_NOTIFICATION_CALL_STATUS_INCOMING;
+ incoming.call_id = call_id;
+ tcore_call_object_get_cli_validity(call_obj, &incoming.cli_validity);
+ tcore_call_object_get_number(call_obj, incoming.number);
+ tcore_call_object_get_cni_validity(call_obj, &incoming.cni_validity);
+ tcore_call_object_get_name(call_obj, incoming.name);
+ tcore_call_object_get_mt_forward(call_obj, &incoming.forward);
+ tcore_call_object_get_active_line(call_obj, &incoming.active_line);
+
+ /* Send notification */
+ tcore_object_send_notification(co, command, sizeof(TelCallIncomingInfo), &incoming);
+ return;
+ }
+
+ case TEL_CALL_STATE_IDLE: {
+ TelCallStatusIdleNoti idle;
+ command = TCORE_NOTIFICATION_CALL_STATUS_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, command,
+ sizeof(TelCallStatusIdleNoti), &idle);
+
+ /* Free Call object */
+ tcore_call_object_free(co, call_obj);
+ return;
+ }
+ }
+
+ }
+ else if (call_type == TEL_CALL_TYPE_VIDEO) {
+ /* video call notification */
+ switch (call_state) {
+ case TEL_CALL_STATE_ACTIVE:
+ command = TCORE_NOTIFICATION_VIDEO_CALL_STATUS_ACTIVE;
+ break;
+
+ case TEL_CALL_STATE_HELD:
+ err("invalid state");
+ break;
+
+ case TEL_CALL_STATE_DIALING:
+ command = TCORE_NOTIFICATION_VIDEO_CALL_STATUS_DIALING;
+ break;
+
+ case TEL_CALL_STATE_ALERT:
+ command = TCORE_NOTIFICATION_VIDEO_CALL_STATUS_ALERT;
+ break;
+
+ case TEL_CALL_STATE_INCOMING:
+ case TEL_CALL_STATE_WAITING:
+ command = TCORE_NOTIFICATION_VIDEO_CALL_STATUS_INCOMING;
+ break;
+
+ case TEL_CALL_STATE_IDLE: {
+ TelCallStatusIdleNoti idle;
+ command = TCORE_NOTIFICATION_VIDEO_CALL_STATUS_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, command,
+ sizeof(TelCallStatusIdleNoti), &idle);
+
+ /* Free Call object */
+ tcore_call_object_free(co, call_obj);
+ return;
+ }
+ }
+ }
+ else {
+ err("Unknown Call type: [%d]", call_type);
+ }
+
+ if (command != TCORE_NOTIFICATION_UNKNOWN)
+ tcore_object_send_notification(co, command, sizeof(call_id), &call_id);
+}
+
+static void __handle_call_list_get(CoreObject *co, gboolean flag, void *data)
+{
+ int call_id;
+ int direction;
+ int call_type;
+ int state;
+ int mpty;
+ int ton;
+ GSList *tokens = NULL;
+ char *resp = NULL;
+ char *line;
+ char *num = NULL;
+ int num_type;
+ char number[TEL_CALL_CALLING_NUMBER_LEN_MAX +1] = {0,};
+ GSList *lines = data;
+ CallObject *call_obj = NULL;
+
+ while (lines != NULL) {
+ line = (char *)lines->data;
+ /* point to next node */
+ lines = lines->next;
+ /* free previous tokens*/
+ tcore_at_tok_free(tokens);
+
+ tokens = tcore_at_tok_new(line);
+
+ /* <id1> */
+ resp = g_slist_nth_data(tokens, 0);
+ if (NULL == resp) {
+ err("Invalid call_id");
+ continue;
+ }
+ call_id = atoi(resp);
+
+ /* <dir> */
+ resp = g_slist_nth_data(tokens, 1);
+ if (NULL == resp) {
+ err("Invalid direction");
+ continue;
+ }
+ direction = (atoi(resp) == 0) ? 1 : 0;
+
+ /* <stat> */
+ resp = g_slist_nth_data(tokens, 2);
+ if (NULL == resp) {
+ err("Invalid state");
+ continue;
+ }
+ state = __call_state(atoi(resp));
+
+ /* <mode> */
+ resp = g_slist_nth_data(tokens, 3);
+ if (NULL == resp) {
+ err("Invalid call_type");
+ continue;
+ }
+ call_type = __call_type(atoi(resp));
+
+ /* <mpty> */
+ resp = g_slist_nth_data(tokens, 4);
+ if (NULL == resp) {
+ err("Invalid mpty");
+ continue;
+ }
+ mpty = atoi(resp);
+
+ /* <number> */
+ 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);
+
+ /* <type> */
+ resp = g_slist_nth_data(tokens, 6);
+ if (!resp) {
+ err("Invalid num type");
+ } else {
+ num_type = atoi(resp);
+ /* check 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] TON: [%d] State: [%d]",
+ call_id, (direction ? "Outgoing" : "Incoming"), call_type,
+ (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, call_type);
+ tcore_call_object_set_direction(call_obj, direction);
+ tcore_call_object_set_multiparty_state(call_obj, mpty);
+ tcore_call_object_set_cli_info(call_obj, TEL_CALL_CLI_VALIDITY_VALID, number);
+ tcore_call_object_set_active_line(call_obj, TEL_CALL_ACTIVE_LINE1);
+ if (flag == TRUE)
+ __call_branch_by_status(co, call_obj, state);
+ else
+ tcore_call_object_set_state(call_obj, state);
+ }
+}
+
+/* internal notification operation */
+static void __on_notification_imc_call_incoming(CoreObject *co, unsigned int call_id,
+ void *user_data)
+{
+ GSList *list = NULL;
+ 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...");
+ g_slist_free(list);
+ return;
+ }
+ g_slist_free(list);
+
+ call_obj = tcore_call_object_find_by_id(co, call_id);
+ if (call_obj != NULL) {
+ err("Call object for Call ID [%d] already exist! Skip...", call_id);
+ return;
+ }
+
+ /* Create new Call object */
+ call_obj = tcore_call_object_new(co, (unsigned int)call_id);
+ if (NULL == call_obj) {
+ err("Failed to create Call object");
+ return;
+ }
+
+ /* Make request to get current Call list */
+ __call_list_get(co, TRUE);
+}
+
+static void __on_notification_imc_call_status(CoreObject *co, unsigned int call_id,
+ unsigned int call_state, void *user_data)
+{
+ CallObject *call_obj = NULL;
+ TelCallState state;
+
+ state = __call_state(call_state);
+ dbg("state [%d]", state);
+
+ switch (state) {
+ case TEL_CALL_STATE_ACTIVE: {
+ find_call_object(co, call_id, call_obj);
+ /* Send notification to application */
+ __call_branch_by_status(co, call_obj, state);
+ }
+ break;
+
+ case TEL_CALL_STATE_HELD: {
+ find_call_object(co, call_id, call_obj);
+ /* Send notification to application */
+ __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 */
+ __call_list_get(co, TRUE);
+ }
+ break;
+
+ case TEL_CALL_STATE_ALERT: {
+ find_call_object(co, call_id, call_obj);
+ /* Send notification to application */
+ __call_branch_by_status(co, call_obj, TEL_CALL_STATE_ALERT);
+ }
+ break;
+
+ case TEL_CALL_STATE_IDLE: {
+ find_call_object(co, call_id, call_obj);
+ /* Send notification to application */
+ __call_branch_by_status(co, call_obj, state);
+ }
+ break;
+
+ default:
+ err("invalid call status");
+ break;
+ }
+}
+
+/*internal response operation */
+static void __on_response_imc_call_list_get(TcorePending *p, guint data_len, const void *data,
+ void *user_data)
+{
+ const TcoreAtResponse *at_resp = data;
+ CoreObject *co = tcore_pending_ref_core_object(p);
+ ImcRespCbData *resp_cb_data = user_data;
+ GSList *lines = NULL;
+ TelCallResult result = TEL_CALL_RESULT_FAILURE; //TODO - CME error mapping required
+ gboolean *flag = IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
+ int 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");
+
+ /* parse +CLCC notification parameter */
+ __handle_call_list_get(co, *flag, lines);
+
+ } else {
+ err("RESPONSE NOK");
+ }
+}
+
+/*internal request operation */
+static TelReturn __send_call_request(CoreObject *co, TcoreObjectResponseCallback cb,
+ void *cb_data, gchar *at_cmd, gchar *func_name)
+{
+ ImcRespCbData *resp_cb_data;
+ TelReturn ret;
+
+ /* Response callback data */
+ resp_cb_data = imc_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_imc_call_default, resp_cb_data,
+ on_send_imc_request, NULL,
+ 0, NULL, NULL);
+
+ IMC_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 __call_list_get(CoreObject *co, gboolean flag)
+{
+ ImcRespCbData *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 = imc_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_imc_call_list_get, resp_cb_data,
+ on_send_imc_request, NULL,
+ 0, NULL, NULL);
+ IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Get current call list");
+
+ return ret;
+}
+
+/* Notification */
+
+/*
+* Operation - call status notification from network.
+* notification message format:
+* +XCALLSTAT: <call_id><stat>
+* where
+* <call_id>
+* indicates the call identification (GSM02.30 4.5.5.1)
+* <stat>
+* 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 disconnected
+* 7 connected (indicates the completion of a call setup first time for MT and MO calls \96 this is reported in
+addition to state active)
+*/
+static gboolean on_notification_imc_call_status(CoreObject *co, const void *data,
+ void *user_data)
+{
+ GSList *tokens = NULL;
+ GSList *lines = NULL;
+ const char *line = NULL;
+ char *state = NULL, *call_handle = NULL;
+ unsigned int status, call_id;
+
+ dbg("Entry");
+
+ lines = (GSList *) data;
+ if (lines == NULL) {
+ err("Invalid response received");
+ return TRUE;
+ }
+ line = (char *) (lines->data);
+ tokens = tcore_at_tok_new(line);
+
+ call_handle = g_slist_nth_data(tokens, 0);
+ if (NULL == call_handle) {
+ err("call_id missing from %XCALLSTAT indiaction");
+ goto OUT;
+ }
+ call_id = atoi(call_handle);
+ state = g_slist_nth_data(tokens, 1);
+ if (NULL == state) {
+ err("State is missing from %XCALLSTAT indication");
+ goto OUT;
+ }
+ status = atoi(state);
+ dbg("call_id[%d], status[%d]", call_id, status);
+
+ switch (status) {
+ case STATUS_INCOMING:
+ case STATUS_WAITING:
+ __on_notification_imc_call_incoming(co, call_id, user_data);
+ break;
+
+ case STATUS_CONNECTED: /* ignore Connected state. */
+ dbg("ignore connected state");
+ break;
+
+ default:
+ __on_notification_imc_call_status(co, call_id, status, user_data);
+ 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_imc_call_ss_cssu_info(CoreObject *co, const void *event_data,
+ void *user_data)
+{
+ GSList *tokens = NULL;
+ TcoreNotification command = TCORE_NOTIFICATION_UNKNOWN;
+ char *resp = NULL;
+ char *cmd = 0;
+ int index = 0;
+ int code2 = -1;
+ char 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 = (char *) ((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> <type>] */
+ if ((resp = g_slist_nth_data(tokens, 1)))
+ index = atoi(resp);
+
+ if ((resp = g_slist_nth_data(tokens, 2))) {
+ /* Strike off double quotes */
+ int len = strlen(resp) - 2;
+ memcpy(number, resp + 1, len);
+ number[len] = '\0';;
+ }
+
+ 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;
+}
+
+/*
+* Operation - SS network initiated notification.
+* notification message format:
+* +CSSI : <code1>[,<index>]
+* where
+* <code1>
+* 0 unconditional call forwarding is active
+* 1 some of the conditional call forwarding are active
+* 2 call has been forwarded
+* 3 call is waiting
+* 4 this is a CUG call (also <index> present)
+* 5 outgoing calls are barred
+* 6 incoming calls are barred
+* 7 CLIR suppression rejected
+* 8 call has been deflected
+
+* <index>
+* refer Closed user group +CCUG.
+*/
+static gboolean on_notification_imc_call_ss_cssi_info(CoreObject *co, const void *event_data,
+ void *user_data)
+{
+ GSList *tokens = NULL;
+ TcoreNotification command = TCORE_NOTIFICATION_UNKNOWN;
+ char *resp = NULL;
+ char *cmd = 0;
+ int index = 0;
+ int code1 = -1;
+
+ dbg("entry");
+
+ if (1 != g_slist_length((GSList *) event_data)) {
+ err("unsolicited msg but multiple line");
+ return TRUE;
+ }
+ cmd = (char *) ((GSList *) event_data)->data;
+ dbg("ss notification message[%s]", cmd);
+
+ tokens = tcore_at_tok_new(cmd);
+ /* parse <code1> */
+ resp = g_slist_nth_data(tokens, 0);
+ if (NULL == resp) {
+ err("<code1> is missing from %CSSI indiaction");
+ tcore_at_tok_free(tokens);
+ return TRUE;
+ }
+
+ code1 = atoi(resp);
+
+ /* parse [ <index>] */
+ if ((resp = g_slist_nth_data(tokens, 1)))
+ index = atoi(resp);
+
+ dbg("+CSSI: <code1> = %d <index> = %d ", code1, index);
+
+ /* <code1> - other values will be ignored */
+ switch (code1) {
+ case 0:
+ command = TCORE_NOTIFICATION_CALL_INFO_MO_FORWARD_UNCONDITIONAL;
+ break;
+ case 1:
+ command = TCORE_NOTIFICATION_CALL_INFO_MO_FORWARD_CONDITIONAL;
+ break;
+ case 2:
+ command = TCORE_NOTIFICATION_CALL_INFO_MO_FORWARDED;
+ break;
+ case 3:
+ command = TCORE_NOTIFICATION_CALL_INFO_MO_WAITING;
+ break;
+ case 5:
+ command = TCORE_NOTIFICATION_CALL_INFO_MO_BARRED_OUTGOING;
+ break;
+ case 6:
+ command = TCORE_NOTIFICATION_CALL_INFO_MO_BARRED_INCOMING;
+ break;
+ case 8:
+ command = TCORE_NOTIFICATION_CALL_INFO_MO_DEFLECTED;
+ break;
+ default:
+ dbg("Unsupported +CSSI notification : %d", code1);
+ break;
+ }
+
+ if (command != TCORE_NOTIFICATION_UNKNOWN)
+ tcore_object_send_notification(co, command, 0, NULL);
+ tcore_at_tok_free(tokens);
+
+ return TRUE;
+}
+
+static gboolean on_notification_imc_call_clip_info(CoreObject *co, const void *data,
+ void *user_data)
+{
+ dbg("entry");
+ /* TODO - handle +CLIP notification*/
+ return TRUE;
+}
+
+/* Response */
+static void on_response_imc_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);
+ ImcRespCbData *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]", IMC_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 */
+ imc_destroy_resp_cb_data(resp_cb_data);
+}
+
+static void on_response_imc_call_set_volume_info(TcorePending *p,
+ guint data_len, const void *data, void *user_data)
+{
+ const TcoreAtResponse *at_resp = data;
+ CoreObject *co = tcore_pending_ref_core_object(p);
+ ImcRespCbData *resp_cb_data = user_data;
+ GSList *tokens = NULL;
+ GSList *line = NULL;
+ char *resp_str = NULL;
+ gboolean error;
+
+ TelCallResult result = TEL_CALL_RESULT_FAILURE; // TODO: XDRV 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) {
+ line = at_resp->lines;
+ tokens = tcore_at_tok_new(line->data);
+
+ if (!g_slist_nth_data(tokens, 0)) {
+ err("group_id is missing");
+ goto OUT;
+ }
+
+ if (!g_slist_nth_data(tokens, 1)) {
+ err(" function_id is missing");
+ goto OUT;
+ }
+
+ resp_str = g_slist_nth_data(tokens, 2);
+ if (!resp_str) {
+ err("xdrv result missing");
+ goto OUT;
+ } else {
+ struct imc_set_volume_info *volume_info;
+ gchar *vol = "";
+ gchar *at_cmd;
+ TelReturn ret;
+
+ error = atoi(resp_str);
+ if (error) {
+ err("RESPONSE NOK");
+ goto OUT;
+ }
+
+ /* Fetch from resp_cb_data */
+ volume_info = (struct imc_set_volume_info *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
+ dbg("volume info index[%d]", volume_info->next_index);
+
+ if (xdrv_set_volume[volume_info->next_index] == NULL) {
+ /*Processing of xdrv commands completed */
+ dbg("RESPONSE OK");
+ result = TEL_CALL_RESULT_SUCCESS;
+ goto OUT;
+ } else if (volume_info->next_index == 3) {
+ switch ((volume_info->volume) / 10) {
+ case 0 :
+ vol = "0";
+ break;
+ case 1 :
+ vol = "40";
+ break;
+ case 2 :
+ vol = "46";
+ break;
+ case 3 :
+ vol = "52";
+ break;
+ case 4 :
+ vol = "58";
+ break;
+ case 5 :
+ vol = "64";
+ break;
+ case 6 :
+ vol = "70";
+ break;
+ case 7 :
+ vol = "76";
+ break;
+ case 8 :
+ vol = "82";
+ break;
+ case 9 :
+ default :
+ vol = "88";
+ }
+ }
+
+ at_cmd = g_strdup_printf("%s%s",
+ xdrv_set_volume[volume_info->next_index], vol);
+
+ /* Increament index to point to next command */
+ volume_info->next_index += 1;
+
+ /* Send Request to modem */
+ ret = tcore_at_prepare_and_send_request(co,
+ at_cmd, "+XDRV",
+ TCORE_AT_COMMAND_TYPE_SINGLELINE,
+ TCORE_PENDING_PRIORITY_DEFAULT,
+ NULL,
+ on_response_imc_call_set_volume_info, resp_cb_data,
+ on_send_imc_request, NULL,
+ (guint)0, NULL, NULL);
+
+ IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "imc_call_set_volume_info");
+ g_free(at_cmd);
+
+ return;
+ }
+ }
+
+OUT :
+ dbg("Set Volume Info: [%s]",
+ (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);
+
+ imc_destroy_resp_cb_data(resp_cb_data);
+ tcore_at_tok_free(tokens);
+}
+
+static void on_response_imc_call_set_sound_path(TcorePending *p,
+ guint data_len, const void *data, void *user_data)
+{
+ const TcoreAtResponse *at_resp = data;
+ CoreObject *co = tcore_pending_ref_core_object(p);
+ ImcRespCbData *resp_cb_data = user_data;
+ GSList *tokens = NULL;
+ GSList *line = NULL;
+ char *resp_str = NULL;
+ gboolean error;
+ gint xdrv_func_id = -1;
+
+ TelCallResult result = TEL_CALL_RESULT_FAILURE; // TODO: XDRV 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) {
+ line = at_resp->lines;
+ tokens = tcore_at_tok_new(line->data);
+ if (!g_slist_nth_data(tokens, 0)) {
+ err("group_id is missing");
+ goto OUT;
+ }
+
+ if (!(resp_str = g_slist_nth_data(tokens, 1))) {
+ err(" function_id is missing");
+ goto OUT;
+ }
+
+ xdrv_func_id = atoi(resp_str);
+
+ resp_str = g_slist_nth_data(tokens, 2);
+ if (resp_str) {
+ error = atoi(resp_str);
+ if (error) {
+ err("RESPONSE NOK");
+ goto OUT;
+ } else {
+ if (xdrv_func_id == 4) {
+ /* Send next command to configure destination device type */
+ gchar *at_cmd;
+ TelReturn ret;
+ gint *device_type = IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
+
+ at_cmd = g_strdup_printf("AT+XDRV=40,5,2,0,0,0,0,0,1,0,1,0,%d",
+ *device_type);
+
+ ret = tcore_at_prepare_and_send_request(co,
+ at_cmd, "+XDRV",
+ TCORE_AT_COMMAND_TYPE_SINGLELINE,
+ TCORE_PENDING_PRIORITY_DEFAULT,
+ NULL,
+ on_response_imc_call_set_sound_path, resp_cb_data,
+ on_send_imc_request, NULL,
+ (guint)0, NULL, NULL);
+
+ IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "imc_call_set_sound_path");
+ g_free(at_cmd);
+
+ return;
+ }
+ dbg("RESPONSE OK");
+ result = TEL_CALL_RESULT_SUCCESS;
+ }
+ }
+ }
+
+OUT :
+ dbg("Set Sound Path: [%s]",
+ (result == TEL_CALL_RESULT_SUCCESS ? "SUCCESS" : "FAIL"));
+
+ tcore_at_tok_free(tokens);
+
+ /* Invoke callback */
+ if (resp_cb_data->cb)
+ resp_cb_data->cb(co, (gint)result, NULL, resp_cb_data->cb_data);
+
+ imc_destroy_resp_cb_data(resp_cb_data);
+}
+
+static void on_response_imc_call_set_mute(TcorePending *p, guint data_len,
+ const void *data, void *user_data)
+{
+ const TcoreAtResponse *at_resp = data;
+ CoreObject *co = tcore_pending_ref_core_object(p);
+ ImcRespCbData *resp_cb_data = user_data;
+ GSList *tokens = NULL;
+ const char *line = NULL;
+ char *resp_str = NULL;
+ gboolean error;
+
+ TelCallResult result = TEL_CALL_RESULT_FAILURE; // TODO: XDRV 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_CALL_RESULT_SUCCESS;
+ line = (((GSList *)at_resp->lines)->data);
+ tokens = tcore_at_tok_new(line);
+
+ resp_str = g_slist_nth_data(tokens, 0);
+ if (!g_slist_nth_data(tokens, 0)) {
+ err("group_id is missing");
+ result = TEL_CALL_RESULT_FAILURE;
+ goto OUT;
+ }
+
+ if (!g_slist_nth_data(tokens, 1)) {
+ err(" function_id is missing");
+ result = TEL_CALL_RESULT_FAILURE;
+ goto OUT;
+ }
+
+ resp_str = g_slist_nth_data(tokens, 2);
+ if (resp_str) {
+ error = atoi(resp_str);
+ if (error) {
+ result = TEL_CALL_RESULT_FAILURE;
+ goto OUT;
+ } else {
+ result = TEL_CALL_RESULT_SUCCESS;
+ }
+ }
+ }
+
+OUT :
+ dbg("Set Mute: [%s]",
+ (result == TEL_CALL_RESULT_SUCCESS ? "SUCCESS" : "FAIL"));
+ tcore_at_tok_free(tokens);
+
+ /* Invoke callback */
+ if (resp_cb_data->cb)
+ resp_cb_data->cb(co, (gint)result, NULL, resp_cb_data->cb_data);
+
+ imc_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 imc_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 imc modem");
+ 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 {
+ int cli = 0;
+
+ dbg("no clir string in number");
+
+ /* it will be removed when setting application use tapi_ss_set_cli()
+ * instead of his own vconfkey. (0 : By network, 1 : Show, 2 : Hide)
+ */
+ vconf_get_int("db/ciss/show_my_number", &cli);
+ if(cli == 2){
+ dbg("clir invocation from setting application");
+ clir = "I";
+ } 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 __send_call_request(co, cb, cb_data, at_cmd, "imc_call_dial");
+}
+
+/*
+ * 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 imc_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 __send_call_request(co, cb, cb_data, at_cmd, "imc_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 imc_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 __send_call_request(co, cb, cb_data, at_cmd, "imc_call_end");
+}
+
+/*
+ * Operation - send dtmf.
+ *
+ * Request -
+ * 1. AT-Command: AT+VTS=<DTMF>,{<DTMF>,<duration>}.
+ * where
+ * <DTMF>:
+ * is a single ASCII character in the set 0-9, #, *, A-D. Even it will support string DTMF.
+ * <duration>:
+ * integer in range 0-255, meaning 1/10(10 millisec) seconds multiples. The string parameter
+ * of the command consists of combinations of the following separated by commas:
+ * NOTE : There is a limit of 50 dtmf tones can be requested through a single VTS command.
+ * Response -
+ * Success:
+ * OK
+ * Failure:
+ * +CME ERROR: <error>
+ */
+static TelReturn imc_call_send_dtmf(CoreObject *co, const char *dtmf_str,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ gchar *at_cmd;
+ char *tmp_dtmf = NULL, *dtmf;
+ unsigned int count;
+
+ dbg("entry");
+
+ //(void) _set_dtmf_tone_duration(o, dup);
+ tmp_dtmf = tcore_malloc0((strlen(dtmf_str) * 2) + 1); // DTMF digits + comma for each dtmf digit.
+ tcore_check_return_value_assert(tmp_dtmf != NULL, TEL_RETURN_FAILURE);
+ /* Save initial pointer */
+ dtmf = tmp_dtmf;
+
+ for (count = 0; count < strlen(dtmf_str); count++) {
+ *tmp_dtmf = dtmf_str[count];
+ tmp_dtmf++;
+
+ *tmp_dtmf = COMMA;
+ tmp_dtmf++;
+ }
+
+ // last digit is having COMMA , overwrite it with '\0' .
+ *(--tmp_dtmf) = '\0';
+
+ // AT+VTS = <d1>,<d2>,<d3>,<d4>,<d5>,<d6>, ..... <d32>
+ at_cmd = g_strdup_printf("AT+VTS=%s", dtmf);
+ dbg("at command : %s", at_cmd);
+
+ tcore_free(dtmf);
+
+ return __send_call_request(co, cb, cb_data, at_cmd, "imc_call_send_dtmf");
+}
+
+/*
+ * 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 imc_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 __send_call_request(co, cb, cb_data, at_cmd, "imc_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 imc_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 __send_call_request(co, cb, cb_data, at_cmd, "imc_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 imc_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 __send_call_request(co, cb, cb_data, at_cmd, "imc_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 imc_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 __send_call_request(co, cb, cb_data, at_cmd, "imc_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 imc_call_split(CoreObject *co, unsigned int 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 __send_call_request(co, cb, cb_data, at_cmd, "imc_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 imc_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 __send_call_request(co, cb, cb_data, at_cmd, "imc_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 imc_call_deflect(CoreObject *co, const char *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 __send_call_request(co, cb, cb_data, at_cmd, "imc_call_deflect");
+}
+
+static TelReturn imc_call_set_active_line(CoreObject *co, TelCallActiveLine active_line,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ dbg("entry");
+
+ dbg("exit");
+ return TEL_RETURN_OPERATION_NOT_SUPPORTED;
+}
+
+static TelReturn imc_call_get_active_line(CoreObject *co, TcoreObjectResponseCallback cb,
+ void *cb_data)
+{
+ dbg("entry");
+
+ dbg("exit");
+ return TEL_RETURN_OPERATION_NOT_SUPPORTED;
+}
+
+/*
+ * Operation - Set voule info.
+ *
+ * Request -
+ * AT-Command: AT+XDRV=<group_id>,<function_id>[,<param_n>]
+ * The first command parameter defines the involved driver group.
+ * The second command parameter defines a certain function in the selected driver group.
+ * Other parameters are dependent on the first two parameters.
+ * Nearly all parameters are integer values, also if they are represented by literals.
+ * Only very few are strings or
+ * hex data strings.
+ *
+ * Response -
+ * +XDRV: <group_id>,<function_id>,<xdrv_result>[,<response_n>]
+ * The first response parameter defines the involved driver group.
+ * The second response parameter defines the current function in the selected driver group.
+ * The third response parameter defines the xdrv_result of the operation.
+ * Additional response parameters dependent on the first two parameters.
+ */
+static TelReturn imc_call_set_volume_info(CoreObject *co, const TelCallVolumeInfo *volume_info,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ ImcRespCbData *resp_cb_data = NULL;
+ gchar *at_cmd;
+ TelReturn ret;
+ struct imc_set_volume_info cb_volume_info;
+
+ dbg("entry");
+
+ cb_volume_info.next_index = 1;
+ cb_volume_info.volume = volume_info->volume;
+
+ /* Response callback data */
+ resp_cb_data = imc_create_resp_cb_data(cb, cb_data,
+ &cb_volume_info, sizeof(struct imc_set_volume_info));
+
+ at_cmd = g_strdup_printf("%s", xdrv_set_volume[0]);
+
+ /* Send Request to modem */
+ ret = tcore_at_prepare_and_send_request(co,
+ at_cmd, "+XDRV",
+ TCORE_AT_COMMAND_TYPE_SINGLELINE,
+ TCORE_PENDING_PRIORITY_DEFAULT,
+ NULL,
+ on_response_imc_call_set_volume_info, resp_cb_data,
+ on_send_imc_request, NULL,
+ (guint)0, NULL, NULL);
+
+ IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "imc_call_set_volume_info");
+
+ g_free(at_cmd);
+ return ret;
+}
+
+
+static TelReturn imc_call_get_volume_info(CoreObject *co, TelCallSoundDevice sound_device,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ dbg("Entry");
+
+ dbg("Exit");
+ return TEL_RETURN_OPERATION_NOT_SUPPORTED;
+}
+
+/*
+ * Operation - Set sound path.
+ *
+ * Request -
+ * AT-Command: AT+XDRV=<group_id>,<function_id>[,<param_n>]
+ * The first command parameter defines the involved driver group.
+ * The second command parameter defines a certain function in the selected driver group.
+ * Other parameters are dependent on the first two parameters.
+ * Nearly all parameters are integer values, also if they are represented by literals.
+ * Only very few are strings or
+ * hex data strings.
+ *
+ * Response -
+ * +XDRV: <group_id>,<function_id>,<xdrv_result>[,<response_n>]
+ * The first response parameter defines the involved driver group.
+ * The second response parameter defines the current function in the selected driver group.
+ * The third response parameter defines the xdrv_result of the operation.
+ * Additional response parameters dependent on the first two parameters.
+ */
+
+static TelReturn imc_call_set_sound_path(CoreObject *co, const TelCallSoundPathInfo *sound_path_info,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ ImcRespCbData *resp_cb_data = NULL;
+ TelReturn ret;
+ gchar *at_cmd;
+ gint device_type = -1;
+
+ dbg("audio device type - 0x%x", sound_path_info->path);
+
+ switch (sound_path_info->path) {
+ case TEL_SOUND_PATH_HANDSET:
+ device_type = 1;
+ break;
+ case TEL_SOUND_PATH_HEADSET:
+ device_type = 2;
+ break;
+ case TEL_SOUND_PATH_HEADSET_3_5PI:
+ device_type = 3;
+ break;
+ case TEL_SOUND_PATH_SPK_PHONE:
+ device_type = 4;
+ break;
+ case TEL_SOUND_PATH_HANDSFREE:
+ device_type = 5;
+ break;
+ case TEL_SOUND_PATH_HEADSET_HAC:
+ device_type = 6;
+ break;
+ case TEL_SOUND_PATH_BLUETOOTH:
+ case TEL_SOUND_PATH_STEREO_BLUETOOTH:
+ device_type = 7;
+ break;
+ case TEL_SOUND_PATH_BT_NSEC_OFF:
+ case TEL_SOUND_PATH_MIC1:
+ case TEL_SOUND_PATH_MIC2:
+ default:
+ dbg("unsupported device type");
+ return TEL_RETURN_INVALID_PARAMETER;
+ }
+
+ /* Response callback data */
+ resp_cb_data = imc_create_resp_cb_data(cb, cb_data, &device_type, sizeof(gint));
+
+ at_cmd = g_strdup_printf("AT+XDRV=40,4,3,0,0,0,0,0,1,0,1,0,%d", device_type);
+
+ ret = tcore_at_prepare_and_send_request(co,
+ at_cmd, "+XDRV",
+ TCORE_AT_COMMAND_TYPE_SINGLELINE,
+ TCORE_PENDING_PRIORITY_DEFAULT,
+ NULL,
+ on_response_imc_call_set_sound_path, resp_cb_data,
+ on_send_imc_request, NULL,
+ (guint)0, NULL, NULL);
+
+ IMC_CHECK_REQUEST_RET(ret, NULL, "imc_call_set_sound_path");
+ g_free(at_cmd);
+
+ return ret;
+}
+
+/*
+ * Operation - Set/Unset mute status.
+ *
+ * Request -
+ * AT-Command: AT+XDRV=<group_id>,<function_id>[,<param_n>]
+ * The first command parameter defines the involved driver group.
+ * The second command parameter defines a certain function in the selected driver group.
+ * Other parameters are dependent on the first two parameters.
+ * Nearly all parameters are integer values, also if they are represented by literals.
+ * Only very few are strings or
+ * hex data strings.
+ *
+ * Response -
+ * +XDRV: <group_id>,<function_id>,<xdrv_result>[,<response_n>]
+ * The first response parameter defines the involved driver group.
+ * The second response parameter defines the current function in the selected driver group.
+ * The third response parameter defines the xdrv_result of the operation.
+ * Additional response parameters dependent on the first two parameters.
+ */
+static TelReturn imc_call_set_mute(CoreObject *co, gboolean mute, TcoreObjectResponseCallback cb,
+ void *cb_data)
+{
+ ImcRespCbData *resp_cb_data = NULL;
+ gchar *at_cmd;
+ TelReturn ret;
+
+ dbg("entry");
+
+ /* Response callback data */
+ resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
+
+ /* AT - Command */
+ if (mute)
+ at_cmd = g_strdup_printf("%s", "AT+XDRV=40,8,0,0,0"); /*MUTE*/
+ else
+ at_cmd = g_strdup_printf("%s", "AT+XDRV=40,8,0,0,88"); /*UNMUTE*/
+
+ /* Send Request to modem */
+ ret = tcore_at_prepare_and_send_request(co,
+ at_cmd, "+XDRV",
+ TCORE_AT_COMMAND_TYPE_SINGLELINE,
+ TCORE_PENDING_PRIORITY_DEFAULT,
+ NULL,
+ on_response_imc_call_set_mute, resp_cb_data,
+ on_send_imc_request, NULL,
+ (guint)0, NULL, NULL);
+
+ IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "imc_call_set_mute");
+
+ g_free(at_cmd);
+
+ return ret;
+}
+
+static TelReturn imc_call_get_mute_status(CoreObject *co, TcoreObjectResponseCallback cb,
+ void *cb_data)
+{
+ dbg("entry");
+
+ dbg("exit");
+ return TEL_RETURN_OPERATION_NOT_SUPPORTED;
+}
+
+
+static TelReturn imc_call_set_sound_recording(CoreObject *co, TelCallSoundRecording sound_rec,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ dbg("entry");
+
+ dbg("exit");
+ return TEL_RETURN_OPERATION_NOT_SUPPORTED;
+}
+
+static TelReturn imc_call_set_sound_equalization(CoreObject *co, const TelCallSoundEqualization *sound_eq,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ dbg("entry");
+
+ dbg("exit");
+ return TEL_RETURN_OPERATION_NOT_SUPPORTED;
+}
+
+/* Call Operations */
+static TcoreCallOps imc_call_ops = {
+ .dial = imc_call_dial,
+ .answer = imc_call_answer,
+ .end = imc_call_end,
+ .send_dtmf = imc_call_send_dtmf,
+ .hold = imc_call_hold,
+ .active = imc_call_active,
+ .swap = imc_call_swap,
+ .join = imc_call_join,
+ .split = imc_call_split,
+ .transfer = imc_call_transfer,
+ .deflect = imc_call_deflect,
+ .set_active_line = imc_call_set_active_line,
+ .get_active_line = imc_call_get_active_line,
+ .set_volume_info = imc_call_set_volume_info,
+ .get_volume_info = imc_call_get_volume_info,
+ .set_sound_path = imc_call_set_sound_path,
+ .set_mute = imc_call_set_mute,
+ .get_mute_status = imc_call_get_mute_status,
+ .set_sound_recording = imc_call_set_sound_recording,
+ .set_sound_equalization = imc_call_set_sound_equalization,
+};
+
+gboolean imc_call_init(TcorePlugin *p, CoreObject *co)
+{
+ dbg("Entry");
+
+ /* Set operations */
+ tcore_call_set_ops(co, &imc_call_ops);
+
+ /* Add Callbacks */
+ tcore_object_add_callback(co, "+XCALLSTAT", on_notification_imc_call_status, NULL);
+ tcore_object_add_callback(co, "+CLIP", on_notification_imc_call_clip_info, NULL);
+ tcore_object_add_callback(co, "+CSSU", on_notification_imc_call_ss_cssu_info, NULL);
+ tcore_object_add_callback(co, "+CSSI", on_notification_imc_call_ss_cssi_info, NULL);
+
+ return TRUE;
+}
+
+void imc_call_exit(TcorePlugin *p, CoreObject *co)
+{
+ dbg("Exit");
+}
/*
* tel-plugin-imc
*
- * 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.
*/
#include <stdio.h>
-#include <string.h>
#include <stdlib.h>
+#include <string.h>
#include <glib.h>
+
#include <log.h>
+#include <tcore.h>
+
+#include "imc_common.h"
+
+void on_send_imc_request(TcorePending *p,
+ TelReturn send_status, void *user_data)
+{
+ dbg("Send - [%s]",
+ (send_status == TEL_RETURN_SUCCESS ? "OK" : "NOK"));
+}
+
+ImcRespCbData *imc_create_resp_cb_data(TcoreObjectResponseCallback cb,
+ void *cb_data, void *data, guint data_len)
+{
+ ImcRespCbData *resp_cb_data;
+ resp_cb_data = tcore_malloc0(sizeof(ImcRespCbData) + 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);
-#include "s_common.h"
+ return resp_cb_data;
+}
+
+void imc_destroy_resp_cb_data(ImcRespCbData *resp_cb_data)
+{
+ if (resp_cb_data)
+ tcore_free(resp_cb_data);
+}
+#if 0
#undef MAX
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
return tmp;
}
+#endif
/*
* tel-plugin-imc
*
- * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: sharanayya mathapati <sharan.m@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.
#include <glib.h>
#include <tcore.h>
-#include <hal.h>
-#include <core_object.h>
+#include <server.h>
#include <plugin.h>
+#include <core_object.h>
+#include <hal.h>
#include <queue.h>
-#include <co_gps.h>
-#include <user_request.h>
-#include <util.h>
-#include <server.h>
+#include <storage.h>
#include <at.h>
+#include <type/notification.h>
+
+
#include <libxml/xmlreader.h>
#include <libxml/parser.h>
#include <libxml/tree.h>
+
#include <tzplatform_config.h>
+#include <co_gps.h>
-#include "s_common.h"
-#include "s_gps.h"
+#include "imc_gps.h"
+#include "imc_common.h"
-#define POSITION_NODE "pos"
-#define POSITION_NODE_ATTR_XSI "xsi:noNamespaceSchemaLocation"
-#define POSITION_NODE_ATTR_VAL_XSI "pos.xsd"
-#define POSITION_NODE_ATTR_XMLNS "xmlns:xsi"
-#define POSITION_NODE_ATTR_VAL_XMLNS "http://www.w3.org/2001/XMLSchema-instance"
+#define POSITION_NODE "pos"
+#define POSITION_NODE_ATTR_XSI "xsi:noNamespaceSchemaLocation"
+#define POSITION_NODE_ATTR_VAL_XSI "pos.xsd"
+#define POSITION_NODE_ATTR_XMLNS "xmlns:xsi"
+#define POSITION_NODE_ATTR_VAL_XMLNS "http://www.w3.org/2001/XMLSchema-instance"
#define MAX_NUM_OF_GPS_REF_TIME_ELEMENT 12 // max number of gps satalite
-#define MAX_NUM_OF_GPS_NAV_ELEMENT 16 // max num of navigation gps element.
-#define MAX_NUM_OF_GPS_ALMANC_ELEMENTS 64 // Max num of almanc elements.
+#define MAX_NUM_OF_GPS_NAV_ELEMENT 16 // max num of navigation gps element.
+#define MAX_NUM_OF_GPS_ALMANC_ELEMENTS 64 // Max num of almanc elements.
-#define NUM_OF_ELEMENTS(array) (sizeof(array) / sizeof(*(array)))
+#define NUM_OF_ELEMENTS(array) (sizeof(array) / sizeof(*(array)))
static char node_name[128]; // max len of xml node
static char node_value[128]; // max len of xml node value.
unsigned long int gpsTow;
unsigned long int gpsWeek;
unsigned char nrOfSats;
- union { // Not supported.
+ union { // Not supported.
gps_gsm_time_t gsm_time;
gps_utran_time_t UtranTime;
} networkTimeInfo;
} __attribute__((packed)) gps_navi_subframe_rsv_t;
typedef struct {
- unsigned char ephemCodeOnL2; // 0~3
- unsigned char ephemUra; // 0~15
- unsigned char ephemSvHealth; // 0~63
- unsigned short ephemIodc; // 0~1023
- unsigned char ephemL2PFlag; // 0~1
+ unsigned char ephemCodeOnL2; // 0~3
+ unsigned char ephemUra; // 0~15
+ unsigned char ephemSvHealth; // 0~63
+ unsigned short ephemIodc; // 0~1023
+ unsigned char ephemL2PFlag; // 0~1
gps_navi_subframe_rsv_t NavigationSubFrameRsv;
- signed char ephemTgd; // -128~127
- unsigned short ephemToc; // 0~37799
- signed char ephemAf2; // -128~12
- signed short ephemAf1; // -32768~32767
- signed long int ephemAf0; // -2097152~2097151
- signed short ephemCrs; // -32768~32767
- signed short ephemDeltaN; // -32768~32767
- signed long int ephemM0; // -2147483648~2147483647
- signed short ephemCuc; // -32768~32767
- unsigned long int ephemE; // 0~4294967295
- signed short ephemCus; // -32768~32767
- unsigned long int ephemAPowrHalf; // 0~4294967295
- unsigned short ephemToe; // 0~37799
- signed char ephemFitFlag; // 0~1
- unsigned char ephemAoda; // 0~31
- signed short ephemCic; // -32768~32767
- signed long int ephemOmegaA0; // -2147483648~2147483647
- signed short ephemCis; // -32768~32767
- signed long int ephemI0; // -2147483648~2147483647
- signed short ephemCrc; // -32768~32767
- signed long int ephemW; // -2147483648~2147483647
- signed long int ephemOmegaADot; // -8388608~8388607
- signed short ephemIDot; // -8192~8191
+ signed char ephemTgd; // -128~127
+ unsigned short ephemToc; // 0~37799
+ signed char ephemAf2; // -128~12
+ signed short ephemAf1; // -32768~32767
+ signed long int ephemAf0; // -2097152~2097151
+ signed short ephemCrs; // -32768~32767
+ signed short ephemDeltaN; // -32768~32767
+ signed long int ephemM0; // -2147483648~2147483647
+ signed short ephemCuc; // -32768~32767
+ unsigned long int ephemE; // 0~4294967295
+ signed short ephemCus; // -32768~32767
+ unsigned long int ephemAPowrHalf; // 0~4294967295
+ unsigned short ephemToe; // 0~37799
+ signed char ephemFitFlag; // 0~1
+ unsigned char ephemAoda; // 0~31
+ signed short ephemCic; // -32768~32767
+ signed long int ephemOmegaA0; // -2147483648~2147483647
+ signed short ephemCis; // -32768~32767
+ signed long int ephemI0; // -2147483648~2147483647
+ signed short ephemCrc; // -32768~32767
+ signed long int ephemW; // -2147483648~2147483647
+ signed long int ephemOmegaADot; // -8388608~8388607
+ signed short ephemIDot; // -8192~8191
} __attribute__((packed)) gps_navi_ephe_t;
typedef enum {
signed char dataId; // only for 3G, 0~3, if this value is -1, it means this value is invalid
unsigned char satId;
unsigned short almanacE; // 0~65536
- unsigned char almanacToa; // 0~255
- signed short almanacKsii; // -32768~3276
- signed short almanacOmegaDot; // -32768~3276
- unsigned char almanacSvHealth; // 0~255
+ unsigned char almanacToa; // 0~255
+ signed short almanacKsii; // -32768~3276
+ signed short almanacOmegaDot; // -32768~3276
+ unsigned char almanacSvHealth; // 0~255
unsigned long int almanacAPowerHalf; // 0~16777215
signed long int almanacOmega0; // -8388608~8388607
signed long int almanacW; // -8388608~8388607
signed long int almanacM0; // -8388608~8388607
- signed short almanacAf0; // -1024~1023
- signed short almanacAf1; // -1024~1023
+ signed short almanacAf0; // -1024~1023
+ signed short almanacAf1; // -1024~1023
} __attribute__((packed)) gps_almanac_sat_info_t;
typedef struct {
typedef struct {
unsigned long int gpsTow;
- union {
+ union {
gps_gsm_time_t gsm_time;
gps_acq_utran_time_t AcqUtranTime;
- } acquisitionTimeInfo; // --- not supported.
+ } acquisitionTimeInfo; // --- not supported.
unsigned long int numberOfSat;
gps_acq_sat_info_t lcsAcquisitionSatInfo[16];
} __attribute__((packed)) gps_acq_assist_t;
{"acqu_assist", ACQU_ASSIST},
};
-
-/**************************************************************************
-* Local Function Prototypes
-**************************************************************************/
-
-static inline int _modem_sat_status_info_2_tel_sat_info(char *sat_info);
-
-static inline int _modem_acqa_assit_doppler_2_tel_doppler(char *doppler_info);
-
-static int _gps_element_compare(char *element[], char *element_str, int nelem);
-
-static enum gps_assist_element_type _get_element_type(char *element_str);
-
-static void _parse_ref_time_gps_elements(char *element_str, char *element_value, gps_assist_data_noti_t *gpsdata_assist, gboolean GPS_TOW_assist, int count);
-
-static void _parse_location_parameters(char *element_str, char *element_value, gps_assist_data_noti_t *gpsdata_assist);
-
-static void _parse_dgps_correction_gps_elements(char *element_str, char *element_value, gps_assist_data_noti_t *gpsdata_assist);
-
-static void _parse_ionospheric_model_gps_elements(char *element_str, char *element_value, gps_assist_data_noti_t *gpsdata_assist);
-
-static void _parse_utc_model_gps_elements(char *element_str, char *element_value, gps_assist_data_noti_t *gpsdata_assist);
-
-static void _parse_almanc_model_gps_elements(char *element_str, char *element_value, gps_assist_data_noti_t *gpsdata_assist, gboolean alm_elem, int count);
-
-static void _parse_acqu_assist_gps_elements(char *element_str, char *element_value, gps_assist_data_noti_t *gpsdata_assist);
-
-static void _parse_nav_model_gps_elements(char *element_str, char *element_value, gps_assist_data_noti_t *gpsdata_assist, gboolean ephem_and_clock, int element_count);
-
-static void _set_coordinate(xmlNodePtr node, gps_ellipsoid_po_t *point, int isalt, int altitude);
-
-static void _set_loc_info_ellipse_elements(xmlNodePtr node, void *elliplse, int is_unc_ellipse);
-
-static xmlChar* _generate_confirm_measure_pos_xml_text(gps_measure_position_confirm_t *gps_measure_position_confirm);
-
-static gboolean on_notification_gps_measure_position_from_modem(CoreObject *o, char *file_name, void *user_data);
-
-/**************************************************************************
-* Local Function Definitions
- **************************************************************************/
-
static inline int _modem_sat_status_info_2_tel_sat_info(char *sat_info)
{
int count;
for (count = 0; count < (int) (sizeof(sat_status_info_table) / sizeof(sat_status_info_t)); count++) {
- if (strcmp(sat_status_info_table[count].psat_status, sat_info) == 0)
+ if (g_strcmp0(sat_status_info_table[count].psat_status, sat_info) == 0)
return (sat_status_info_table[count].stat_status);
}
return (-1);
int count;
for (count = 0; count < (int) (sizeof(doppler_status_info_table) / sizeof(doppler_status_info_t)); count++) {
- if (strcmp(doppler_status_info_table[count].pdoppler_status, doppler_info) == 0)
+ if (g_strcmp0(doppler_status_info_table[count].pdoppler_status, doppler_info) == 0)
return (doppler_status_info_table[count].doppler_status);
}
return (-1);
int count;
for (count = 0; count < nelem; count++) {
- if (strcmp(element[count], element_str) == 0)
+ if (g_strcmp0(element[count], element_str) == 0)
return count;
}
return -1;
}
-
static enum gps_assist_element_type _get_element_type(char *element_str)
{
unsigned int index;
for (index = 0; index < sizeof(elements) / sizeof(t_element); index++) {
- if (strcmp(elements[index].name, element_str) == 0)
+ if (g_strcmp0(elements[index].name, element_str) == 0)
return elements[index].type;
}
return -1;
}
-
static void _parse_ref_time_gps_elements(char *element_str, char *element_value, gps_assist_data_noti_t *gpsdata_assist, gboolean GPS_TOW_assist, int count)
{
int node_count;
dbg("Enter");
if (count < 0 || count >= MAX_NUM_OF_GPS_REF_TIME_ELEMENT) {
- dbg("invalid count");
+ err("invalid count");
return;
}
nelem = (int) NUM_OF_ELEMENTS(element);
break;
default:
- dbg("Invalid gps element");
+ err("Invalid gps element");
}
}
}
case 0:
{
// gpsdata_assist.ref_loc.latitude_data.north = atoi(element_str_text);
- // dbg("gpsdata_assist.ref_loc.latitude_data.north - %d\n",gpsdata_assist.ref_loc.latitude_data.north);
+ // dbg("gpsdata_assist.ref_loc.latitude_data.north - %d\n",gpsdata_assist.ref_loc.latitude_data.north);
}
break;
case 2:
{
// gpsdata_assist.ref_loc.altitude_data.height_above_surface = atoi(element_str_text);
- // dbg("altitude_data.height_above_surface - %d\n",gpsdata_assist.ref_loc.altitude_data.height_above_surface);
+ // dbg("altitude_data.height_above_surface - %d\n",gpsdata_assist.ref_loc.altitude_data.height_above_surface);
}
break;
case 3:
{
- gpsdata_assist->ref_loc.altitude = atoi(element_value); // todo- need to confirm
+ gpsdata_assist->ref_loc.altitude = atoi(element_value); // todo- need to confirm
dbg("altitude_data.height - %d\n", gpsdata_assist->ref_loc.altitude);
}
break;
case 4:
{
gpsdata_assist->ref_loc.longitude = atoi(element_value);
- dbg("longitude - %d\n", gpsdata_assist->ref_loc.longitude);
+ dbg("longitude - %d\n", gpsdata_assist->ref_loc.longitude);
}
break;
break;
default:
- dbg("invalid element");
+ err("invalid element");
}
}
{
dbg("Enter");
- if (strcmp(element_str, "sat_id") == 0) {
+ if (g_strcmp0(element_str, "sat_id") == 0) {
gpsdata_assist->dgps_corrections.seqOfSatElement[0].satId = *element_value;
dbg("seqOfSatElement[0].satId - %d\n", gpsdata_assist->dgps_corrections.seqOfSatElement[0].satId);
- } else if (strcmp(element_str, "IODE") == 0) {
+ } else if (g_strcmp0(element_str, "IODE") == 0) {
gpsdata_assist->dgps_corrections.seqOfSatElement[0].iode = atoi(element_value);
dbg("seqOfSatElement[0].iode - %d\n", gpsdata_assist->dgps_corrections.seqOfSatElement[0].iode);
- } else if (strcmp(element_str, "UDRE") == 0) {
+ } else if (g_strcmp0(element_str, "UDRE") == 0) {
gpsdata_assist->dgps_corrections.seqOfSatElement[0].udre = *element_value;
dbg("seqOfSatElement[0].udre- %d\n", gpsdata_assist->dgps_corrections.seqOfSatElement[0].udre);
- } else if (strcmp(element_str, "PRC") == 0) {
+ } else if (g_strcmp0(element_str, "PRC") == 0) {
gpsdata_assist->dgps_corrections.seqOfSatElement[0].pseudoRangeCor = atoi(element_value);
dbg("seqOfSatElement[0].pseudoRangeCor - %d\n", gpsdata_assist->dgps_corrections.seqOfSatElement[0].pseudoRangeCor);
- } else if (strcmp(element_str, "RRC") == 0) {
+ } else if (g_strcmp0(element_str, "RRC") == 0) {
gpsdata_assist->dgps_corrections.seqOfSatElement[0].rangeRateCor = atoi(element_value);
dbg("seqOfSatElement[0].rangeRateCor - %d\n", gpsdata_assist->dgps_corrections.seqOfSatElement[0].rangeRateCor);
}
case 0:
{
gpsdata_assist->iono_model.alfa0 = *element_value;
- dbg("alfa0 - 0x%X\n", gpsdata_assist->iono_model.alfa0);
+ dbg("alfa0 - 0x%X\n", gpsdata_assist->iono_model.alfa0);
}
break;
case 2:
{
gpsdata_assist->iono_model.alfa2 = *element_value;
- dbg("alfa2 - 0x%X\n", gpsdata_assist->iono_model.alfa2);
+ dbg("alfa2 - 0x%X\n", gpsdata_assist->iono_model.alfa2);
}
break;
case 3:
{
gpsdata_assist->iono_model.alfa3 = *element_value;
- dbg("alfa3 - 0x%X\n", gpsdata_assist->iono_model.alfa3);
+ dbg("alfa3 - 0x%X\n", gpsdata_assist->iono_model.alfa3);
}
break;
case 4:
{
gpsdata_assist->iono_model.beta0 = *element_value;
- dbg("beta0 - 0x%X\n", gpsdata_assist->iono_model.beta0);
+ dbg("beta0 - 0x%X\n", gpsdata_assist->iono_model.beta0);
}
break;
case 5:
{
gpsdata_assist->iono_model.beta1 = *element_value;
- dbg("beta1 -0x%X\n", gpsdata_assist->iono_model.beta1);
+ dbg("beta1 -0x%X\n", gpsdata_assist->iono_model.beta1);
}
break;
case 6:
{
gpsdata_assist->iono_model.beta2 = *element_value;
- dbg("beta2 - 0x%X\n", gpsdata_assist->iono_model.beta2);
+ dbg("beta2 - 0x%X\n", gpsdata_assist->iono_model.beta2);
}
break;
case 7:
{
gpsdata_assist->iono_model.beta3 = *element_value;
- dbg("beta3 - 0x%X\n", gpsdata_assist->iono_model.beta3);
+ dbg("beta3 - 0x%X\n", gpsdata_assist->iono_model.beta3);
}
break;
default:
- dbg("invalid gps element");
+ err("invalid gps element");
}
}
-void _parse_utc_model_gps_elements(char *element_str, char *element_value, gps_assist_data_noti_t *gpsdata_assist)
+static void _parse_utc_model_gps_elements(char *element_str, char *element_value, gps_assist_data_noti_t *gpsdata_assist)
{
static char *element[] = {"a1", "a0", "tot", "wnt", "dtls", "wnlsf", "dn", "dtlsf"};
int nelem = (int) NUM_OF_ELEMENTS(element);
case 0:
{
gpsdata_assist->utc_model.utcA1 = atoi(element_value);
- dbg("utcA1 - %d\n", gpsdata_assist->utc_model.utcA1);
+ dbg("utcA1 - %d\n", gpsdata_assist->utc_model.utcA1);
}
break;
case 1:
{
gpsdata_assist->utc_model.utcA0 = atoi(element_value);
- dbg("utcA0 - %d\n", gpsdata_assist->utc_model.utcA0);
+ dbg("utcA0 - %d\n", gpsdata_assist->utc_model.utcA0);
}
break;
case 6:
{
gpsdata_assist->utc_model.utcDN = *element_value;
- dbg("utcDN - 0x%X\n", gpsdata_assist->utc_model.utcDN);
+ dbg("utcDN - 0x%X\n", gpsdata_assist->utc_model.utcDN);
}
break;
break;
default:
- dbg("invalid gps element");
+ err("invalid gps element");
}
}
case 2:
{
gpsdata_assist->almanac.AlmanacSatInfo[count].satId = *element_value;
- dbg("AlmanacSatInfo[%d].sat_id - 0x%X\n", count, gpsdata_assist->almanac.AlmanacSatInfo[count].satId);
+ dbg("AlmanacSatInfo[%d].sat_id - 0x%X\n", count, gpsdata_assist->almanac.AlmanacSatInfo[count].satId);
}
break;
case 4:
{
gpsdata_assist->almanac.AlmanacSatInfo[count].almanacToa = *element_value;
- dbg("AlmanacSatInfo[%d].almanacToa - 0x%X\n", count, gpsdata_assist->almanac.AlmanacSatInfo[count].almanacToa);
+ dbg("AlmanacSatInfo[%d].almanacToa - 0x%X\n", count, gpsdata_assist->almanac.AlmanacSatInfo[count].almanacToa);
}
break;
case 12:
{
gpsdata_assist->almanac.AlmanacSatInfo[count].almanacAf0 = atoi(element_value);
- dbg("AlmanacSatInfo[%d].almanacAf0 - %d\n", count, gpsdata_assist->almanac.AlmanacSatInfo[count].almanacAf0);
+ dbg("AlmanacSatInfo[%d].almanacAf0 - %d\n", count, gpsdata_assist->almanac.AlmanacSatInfo[count].almanacAf0);
}
break;
case 13:
{
gpsdata_assist->almanac.AlmanacSatInfo[count].almanacAf1 = atoi(element_value);
- dbg("AlmanacSatInfo[%d].almanacAf1 - %d\n", count, gpsdata_assist->almanac.AlmanacSatInfo[count].almanacAf1);
+ dbg("AlmanacSatInfo[%d].almanacAf1 - %d\n", count, gpsdata_assist->almanac.AlmanacSatInfo[count].almanacAf1);
}
break;
default:
- dbg("invalid gps element");
+ err("invalid gps element");
}
}
return;
switch (count) {
case 0:
gpsdata_assist->acq_assist.gpsTow = atoi(element_value);
- dbg("acq_assist.gpsTow - %d\n", gpsdata_assist->acq_assist.gpsTow);
+ dbg("acq_assist.gpsTow - %d\n", gpsdata_assist->acq_assist.gpsTow);
break;
case 1:
case 3:
gpsdata_assist->acq_assist.lcsAcquisitionSatInfo[0].doppler1 = *element_value;
- dbg("lcsAcquisitionSatInfo[0].doppler1 - 0x%X\n", gpsdata_assist->acq_assist.lcsAcquisitionSatInfo[0].doppler1);
+ dbg("lcsAcquisitionSatInfo[0].doppler1 - 0x%X\n", gpsdata_assist->acq_assist.lcsAcquisitionSatInfo[0].doppler1);
break;
case 4:
case 5:
gpsdata_assist->acq_assist.lcsAcquisitionSatInfo[0].intCodePhase = *element_value;
- dbg("lcsAcquisitionSatInfo[0].intCodePhase - 0x%X\n", gpsdata_assist->acq_assist.lcsAcquisitionSatInfo[0].intCodePhase);
+ dbg("lcsAcquisitionSatInfo[0].intCodePhase - 0x%X\n", gpsdata_assist->acq_assist.lcsAcquisitionSatInfo[0].intCodePhase);
break;
case 6:
break;
default:
- dbg("invalid gps element");
+ err("invalid gps element");
}
}
int count;
if (element_count < 0 || element_count >= MAX_NUM_OF_GPS_NAV_ELEMENT) {
- dbg("invalid count");
+ err("invalid count");
return;
}
count = _gps_element_compare(element, element_str, nelem);
break;
default:
- dbg("invalid gps element");
+ err("invalid gps element");
}
}
}
-
-// Set coordinate elements : <latitude> <longitude> <altitude>
+// Set coordinate elements : <latitude> <longitude> <altitude>
static void _set_coordinate(xmlNodePtr node, gps_ellipsoid_po_t *point, int isalt, int altitude)
{
// <parent_node> .. .. (xmlNodePtr node)
return;
}
+
+
static void _set_loc_info_ellipse_elements(xmlNodePtr node, void *elliplse, int is_unc_ellipse)
{
gps_po_unc_ellipse_t *p_unc_ellipse;
int count = 0, altitude, size;
/*
- Creates a new XML document
+ Creates a new XML document
================================================================================================================================
- <?xml version="1.0"?>
- <pos xsi:noNamespaceSchemaLocation="pos.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
- <GPS_meas>
- <ref_time_only>
- <tow_msec></tow_msec>
- </ref_time_only>
- <meas_params>
- <sat_id></sat_id><carr2_noise></carr2_noise><dopl></dopl><whole_chips></whole_chips><fract_chips></fract_chips>
- <multi_path literal="xx"></multi_path> <psr_rms_err></psr_rms_err>
- </meas_params>
- </GPS_meas>
- <location>
- <time_of_fix></time_of_fix><
- <location_parameters>
- <shape_data>
- <ellipsoid_point>
- <coordinate>
- <latitude><north></north><degrees></degrees></latitude><longitude></longitude>
- </coordinate>
- </ellipsoid_point>
- <ellipsoid_point_uncert_circle>
- <uncert_circle></uncert_circle>
- <coordinate>
- <latitude> <> <\> ...</latitude> <longitude></longitude>
- </coordinate>
- </ellipsoid_point_uncert_circle>
- <ellipsoid_point_uncert_ellipse>
- <coordinate>
- <latitude><> <\>..<longitude></longitude>
- </coordinate>
- <uncert_ellipse><uncert_semi_major></uncert_semi_major><uncert_semi_minor></uncert_semi_minor>
- <orient_major></orient_major><confidence></confidence></uncert_ellipse>
- </ellipsoid_point_uncert_ellipse>
- <polygon>
- <coordinate*>
- <latitude><> <\>...</latitude><longitude></longitude>
- </coordinate>
- </polygon>
- <ellipsoid_point_alt>
- <coordinate>
- <latitude><> <\>..</latitude><longitude></longitude>
- </coordinate>
- <altitude>
- <height_above_surface></height_above_surface><height></height>
- </altitude>
- </ellipsoid_point_alt>
- <ellipsoid_point_alt_uncertellipse>
- <coordinate>
- <latitude> <> <\>.. ..</latitude><longitude></longitude>
- </coordinate>
- <altitude>
- <height_above_surface></height_above_surface><height></height>
- </altitude>
- <uncert_semi_major></uncert_semi_major><uncert_semi_minor></uncert_semi_minor><orient_major></orient_major>
- <confidence></confidence><uncert_alt></uncert_alt>
- </ellipsoid_point_alt_uncertellipse>
- <ellips_arc>
- <coordinate>
- <latitude><> <\> .. </latitude><longitude></longitude>
- </coordinate><
- <inner_rad></inner_rad>
- <uncert_rad></uncert_rad><offset_angle></offset_angle><included_angle></included_angle>
- <confidence></confidence>
- </ellips_arc>
- </shape_data>
- </location_parameters>
- </location>
- <assist_data>
- <msr_assist_data/>
- </assist_data>
- </pos>
+ <?xml version="1.0"?>
+ <pos xsi:noNamespaceSchemaLocation="pos.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <GPS_meas>
+ <ref_time_only>
+ <tow_msec></tow_msec>
+ </ref_time_only>
+ <meas_params>
+ <sat_id></sat_id><carr2_noise></carr2_noise><dopl></dopl><whole_chips></whole_chips><fract_chips></fract_chips>
+ <multi_path literal="xx"></multi_path> <psr_rms_err></psr_rms_err>
+ </meas_params>
+ </GPS_meas>
+ <location>
+ <time_of_fix></time_of_fix><
+ <location_parameters>
+ <shape_data>
+ <ellipsoid_point>
+ <coordinate>
+ <latitude><north></north><degrees></degrees></latitude><longitude></longitude>
+ </coordinate>
+ </ellipsoid_point>
+ <ellipsoid_point_uncert_circle>
+ <uncert_circle></uncert_circle>
+ <coordinate>
+ <latitude> <> <\> ...</latitude> <longitude></longitude>
+ </coordinate>
+ </ellipsoid_point_uncert_circle>
+ <ellipsoid_point_uncert_ellipse>
+ <coordinate>
+ <latitude><> <\>..<longitude></longitude>
+ </coordinate>
+ <uncert_ellipse><uncert_semi_major></uncert_semi_major><uncert_semi_minor></uncert_semi_minor>
+ <orient_major></orient_major><confidence></confidence></uncert_ellipse>
+ </ellipsoid_point_uncert_ellipse>
+ <polygon>
+ <coordinate*>
+ <latitude><> <\>...</latitude><longitude></longitude>
+ </coordinate>
+ </polygon>
+ <ellipsoid_point_alt>
+ <coordinate>
+ <latitude><> <\>..</latitude><longitude></longitude>
+ </coordinate>
+ <altitude>
+ <height_above_surface></height_above_surface><height></height>
+ </altitude>
+ </ellipsoid_point_alt>
+ <ellipsoid_point_alt_uncertellipse>
+ <coordinate>
+ <latitude> <> <\>.. ..</latitude><longitude></longitude>
+ </coordinate>
+ <altitude>
+ <height_above_surface></height_above_surface><height></height>
+ </altitude>
+ <uncert_semi_major></uncert_semi_major><uncert_semi_minor></uncert_semi_minor><orient_major></orient_major>
+ <confidence></confidence><uncert_alt></uncert_alt>
+ </ellipsoid_point_alt_uncertellipse>
+ <ellips_arc>
+ <coordinate>
+ <latitude><> <\> .. </latitude><longitude></longitude>
+ </coordinate><
+ <inner_rad></inner_rad>
+ <uncert_rad></uncert_rad><offset_angle></offset_angle><included_angle></included_angle>
+ <confidence></confidence>
+ </ellips_arc>
+ </shape_data>
+ </location_parameters>
+ </location>
+ <assist_data>
+ <msr_assist_data/>
+ </assist_data>
+ </pos>
================================================================================================================================
*/
return xml;
}
-static gboolean on_notification_gps_assist_data(CoreObject *o, const void *event_info, void *user_data)
+
+static gboolean on_notification_gps_measure_position_from_modem(CoreObject *o, char *file_name, void *user_data)
+{
+ char *node = NULL, *node_value = NULL;
+ char *attribute = NULL;
+ char *attr_value = NULL;
+ gps_measure_position_indi_t gps_measure_position_indi;
+ gboolean rep_quant = FALSE;
+ xmlTextReaderPtr reader;
+
+ memset(&gps_measure_position_indi, 0x00, sizeof(gps_measure_position_indi));
+ reader = xmlReaderForFile(file_name, NULL, 0);
+
+ while (xmlTextReaderRead(reader)) {
+ switch (xmlTextReaderNodeType(reader)) {
+ case XML_READER_TYPE_ELEMENT:
+ {
+ node = (char *) xmlTextReaderConstName(reader);
+ dbg("Element: %s", node);
+ if (node != NULL) {
+ // Read attribute value.
+ while (xmlTextReaderMoveToNextAttribute(reader)) {
+ attribute = (char *) xmlTextReaderConstName(reader);
+ dbg("Attribute value - %s\n", attribute);
+ attr_value = (char *) xmlTextReaderConstValue(reader);
+ dbg("=\"%s\"\n", attr_value);
+
+ if (g_strcmp0(node, "mult_sets") == 0) {
+ if (g_strcmp0(attribute, "literal") == 0) {
+ if (g_strcmp0(attr_value, "one") == 0)
+ gps_measure_position_indi.use_multi_sets = GPS_MULTIPLESETS_ONESET;
+ else if (g_strcmp0(attr_value, "multiple") == 0)
+ gps_measure_position_indi.use_multi_sets = GPS_MULTIPLESETS_MULTIPLESETS;
+ }
+ dbg("gps_measure_position_indi.use_multi_sets - 0x%x\n", gps_measure_position_indi.use_multi_sets);
+ } else if (g_strcmp0(node, "rep_quant") == 0) {
+ rep_quant = TRUE;
+ if (g_strcmp0(attribute, "addl_assist_data_req") == 0) {
+ if (g_strcmp0(attr_value, "true") == 0)
+ gps_measure_position_indi.add_assist_req = GPS_ADDITIONAL_ASSISREQ_REQ;
+ else
+ gps_measure_position_indi.add_assist_req = GPS_ADDITIONAL_ASSISREQ_NOT_REQ;
+ } else if (g_strcmp0(attribute, "gps_timing_of_cell_wanted") == 0) {
+ if (g_strcmp0(attr_value, "true") == 0)
+ gps_measure_position_indi.cell_timing_wnt = GPS_CELLTIMING_WANTED;
+ else
+ gps_measure_position_indi.cell_timing_wnt = GPS_CELLTIMING_NOT_WANTED;
+ }
+ }
+ } // end of attribute check
+
+ if (g_strcmp0(node, "ms_assisted") == 0) {
+ gps_measure_position_indi.method_type = GPS_METHODTYPE_MS_ASSISTED;
+ } else if (g_strcmp0(node, "ms_assisted_no_accuracy") == 0) {
+ gps_measure_position_indi.method_type = GPS_METHODTYPE_MS_ASSISTED;
+ } else if (g_strcmp0(node, "ms_based") == 0) {
+ gps_measure_position_indi.method_type = GPS_METHODTYPE_MS_BASED;
+ } else if (g_strcmp0(node, "ms_based_pref") == 0) {
+ gps_measure_position_indi.method_type = GPS_METHODTYPE_MS_BASED_PREF;
+ } else if (g_strcmp0(node, "ms_assisted_pref") == 0) {
+ gps_measure_position_indi.method_type = GPS_METHODTYPE_MS_ASSISTED_PREF;
+ }
+ }
+ xmlTextReaderMoveToElement(reader);
+ }
+ break;
+
+ case XML_READER_TYPE_TEXT:
+ {
+ node_value = (char *) xmlTextReaderConstValue(reader);
+ dbg("element-value: %s", node_value);
+ if (node_value != NULL) {
+ if (g_strcmp0(node, "resp_time_seconds") == 0) {
+ gps_measure_position_indi.rsp_time = *node_value;
+ dbg("gps_measure_position_indi.rsp_time - 0x%x", gps_measure_position_indi.rsp_time);
+ }
+ if (rep_quant == TRUE) {
+ if (g_strcmp0(node, "hor_acc") == 0)
+ gps_measure_position_indi.accuracy.horizontalAccuracy = *node_value;
+ else if (g_strcmp0(node, "vert_acc") == 0)
+ gps_measure_position_indi.accuracy.vertcalAccuracy = *node_value;
+ }
+ }
+ }
+ break;
+ }
+ }
+ xmlFreeTextReader(reader);
+ xmlCleanupParser();
+
+ tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)),(tcore_object_ref_plugin(o)),
+ TCORE_NOTIFICATION_GPS_MEASURE_POSITION, sizeof(gps_measure_position_indi), &gps_measure_position_indi);
+ return TRUE;
+}
+
+
+static gboolean on_notification_imc_gps_assist_data(CoreObject *o, const void *event_info, void *user_data)
{
int fd;
gps_assist_data_noti_t gps_data_assist;
dbg("enter");
/*
- Example:GPS assist XML data will be in below format.
+ Example:GPS assist XML data will be in below format.
================================================================================================================================
- +CPOSR:<?xml version="1.0" encoding="UTF-8"?>
- <pos xsi:noNamespaceSchemaLocation="pos.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
- <assist_data>
- <GPS_assist>
- <ref_time>
- <GPS_time> <> <\>..<\GPS_time> <GPS_TOW_assist*> <> <\> ..<\GPS_TOW_assist>
- </ref_time>
-
- <location_parameters>
- <shape_data> <ellipsoid_point_alt_uncertellipse> </coordinate> <> <\>...</coordinate> <altitude> <\altitude>
- <uncert_semi_major> </uncert_semi_major> <uncert_semi_minor> </uncert_semi_minor> <orient_major> </orient_major> <confidence> </confidence>
- <uncert_alt> </uncert_alt> </ellipsoid_point_alt_uncertellipse> </shape_data>
- </location_parameters>
-
- <DGPS_corrections>
- <sat_id> </sat_id> <IODE> </IODE> <UDRE></UDRE> <PRC></PRC> <RRC></RRC>
- </DGPS_corrections>
-
- <nav_model_elem*>
- <sat_id> </sat_id> <sat_status literal="xx"></sat_status>
- <ephem_and_clock?> <l2_code></l2_code> <> <\> .. .. <\ephem_and_clock>
- </nav_model_elem>
-
- <ionospheric_model> <alfa0> </alfa0> <alfa1> </alfa1> <alfa2> </alfa2> <alfa3></alfa3>
- <beta0></beta0> <beta1></beta1> <beta2></beta2> <beta3> </beta3>
- </ionospheric_model>
-
- <UTC_model>
- <a1></a1><a0></a0><tot></tot><wnt></wnt> <dtls></dtls> <wnlsf></wnlsf> <dn></dn><dtlsf></dtlsf>
- </UTC_model>
- <almanac>
- <wna>0</wna> <alm_elem*> <> <\> ...<\alm_elem>
- </almanac>
-
- <acqu_assist>
- <tow_msec></tow_msec> <sat_info> <> <\> ... <\sat_info>
- </acqu_assist>
-
- </GPS_assist>
- </assist_data>
- </pos>
+ +CPOSR:<?xml version="1.0" encoding="UTF-8"?>
+ <pos xsi:noNamespaceSchemaLocation="pos.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <assist_data>
+ <GPS_assist>
+ <ref_time>
+ <GPS_time> <> <\>..<\GPS_time> <GPS_TOW_assist*> <> <\> ..<\GPS_TOW_assist>
+ </ref_time>
+
+ <location_parameters>
+ <shape_data> <ellipsoid_point_alt_uncertellipse> </coordinate> <> <\>...</coordinate> <altitude> <\altitude>
+ <uncert_semi_major> </uncert_semi_major> <uncert_semi_minor> </uncert_semi_minor> <orient_major> </orient_major> <confidence> </confidence>
+ <uncert_alt> </uncert_alt> </ellipsoid_point_alt_uncertellipse> </shape_data>
+ </location_parameters>
+
+ <DGPS_corrections>
+ <sat_id> </sat_id> <IODE> </IODE> <UDRE></UDRE> <PRC></PRC> <RRC></RRC>
+ </DGPS_corrections>
+
+ <nav_model_elem*>
+ <sat_id> </sat_id> <sat_status literal="xx"></sat_status>
+ <ephem_and_clock?> <l2_code></l2_code> <> <\> .. .. <\ephem_and_clock>
+ </nav_model_elem>
+
+ <ionospheric_model> <alfa0> </alfa0> <alfa1> </alfa1> <alfa2> </alfa2> <alfa3></alfa3>
+ <beta0></beta0> <beta1></beta1> <beta2></beta2> <beta3> </beta3>
+ </ionospheric_model>
+
+ <UTC_model>
+ <a1></a1><a0></a0><tot></tot><wnt></wnt> <dtls></dtls> <wnlsf></wnlsf> <dn></dn><dtlsf></dtlsf>
+ </UTC_model>
+ <almanac>
+ <wna>0</wna> <alm_elem*> <> <\> ...<\alm_elem>
+ </almanac>
+
+ <acqu_assist>
+ <tow_msec></tow_msec> <sat_info> <> <\> ... <\sat_info>
+ </acqu_assist>
+
+ </GPS_assist>
+ </assist_data>
+ </pos>
================================================================================================================================
*/
path = tzplatform_mkpath(TZ_SYS_ROOT, "sample.xml");
// open file.
if ((fd = open(path, O_WRONLY | O_CREAT | O_TRUNC | S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH, S_IRWXU)) == -1) {
- dbg("Cannot open file\n");
+ err("Cannot open file\n");
g_free(line);
return FALSE;
}
// write gps xml data into file.
if (write(fd, (const void *) line, strlen(line)) == -1) {
- dbg("Cannot write into file\n");
+ err("Cannot write into file\n");
close(fd);
g_free(line);
return FALSE;
dbg("read xml file");
reader = xmlReaderForFile(path, NULL, 0);
- while (xmlTextReaderRead(reader) == 1) {
+ while (xmlTextReaderRead(reader)) {
// Get the node type of the current node
switch (xmlTextReaderNodeType(reader)) {
case XML_READER_TYPE_ELEMENT:
if (node != NULL) {
// check type of sub element of <GPS_assist>
set_element_type = _get_element_type(node);
- if ((int) set_element_type != -1) // ignore negative value as excepted element type not set.
+ if ((int) set_element_type != -1) // ignore negative value as excepted element type not set.
node_type = set_element_type;
- dbg("xml node type : %d", node_type);
+ dbg("xml node type : %d", node_type);
// Check for position measurement data.
- if (strcmp(node, "pos_meas") == 0) {
+ if (g_strcmp0(node, "pos_meas") == 0) {
// Deallocate all the resources associated to the reader
xmlFreeTextReader(reader);
xmlCleanupParser();
// Read attribute value of <nav_model_elem>
if (node_type == NAV_MODEL_ELEM) {
- if (strcmp(node, "sat_status") == 0 && strcmp(attribute, "literal") == 0) {
+ if (g_strcmp0(node, "sat_status") == 0 && g_strcmp0(attribute, "literal") == 0) {
gps_data_assist.navi_model.NavigationSatInfo[nav_model_node_count].NavigationSatStatus = _modem_sat_status_info_2_tel_sat_info(attr_value);
dbg("navigation sat status of nav model element - %d\n", gps_data_assist.navi_model.NavigationSatInfo[nav_model_node_count].NavigationSatStatus);
}
}
// Read attribute value of <acqu_assist>
else if (node_type == ACQU_ASSIST) {
- if (strcmp(node, "dopl1_uncert") == 0 && strcmp(attribute, "literal") == 0) {
+ if (g_strcmp0(node, "dopl1_uncert") == 0 && g_strcmp0(attribute, "literal") == 0) {
gps_data_assist.acq_assist.lcsAcquisitionSatInfo[0].dopplerUncertainty = _modem_acqa_assit_doppler_2_tel_doppler(attr_value);
dbg("doppler uncertainty of acqu assist data- %d", gps_data_assist.acq_assist.lcsAcquisitionSatInfo[0].dopplerUncertainty);
}
}
- } // end of attribute check.
+ } // end of attribute check.
// check GPS data is having GPS_assist data.
- if (strcmp(node, "GPS_assist") == 0) {
+ if (g_strcmp0(node, "GPS_assist") == 0) {
_gps_assist_data = TRUE;
}
if (_gps_assist_data == TRUE) {
// number of GPS_TOW_assist elements.
- if (strcmp(node, "GPS_TOW_assist") == 0) {
+ if (g_strcmp0(node, "GPS_TOW_assist") == 0) {
gps_tow_assist_count++;
gps_tow_assist = TRUE;
- } else if (strcmp(node, "nav_model_elem") == 0) {
+ } else if (g_strcmp0(node, "nav_model_elem") == 0) {
// number of nav_model_elem.
nav_model_node_count++;
- } else if (strcmp(node, "alm_elem") == 0) {
+ } else if (g_strcmp0(node, "alm_elem") == 0) {
// number of alm_elem elements.
alm_node_count++;
dbg("alm_elem_count - %d", alm_node_count);
if (node_type == ALMANAC)
alm_elem = TRUE;
- } else if (strcmp(node, "ephem_and_clock") == 0 && node_type == NAV_MODEL_ELEM) {
+ } else if (g_strcmp0(node, "ephem_and_clock") == 0 && node_type == NAV_MODEL_ELEM) {
ephem_and_clock = TRUE;
}
}
}
xmlTextReaderMoveToElement(reader);
- } // end of reading node type.
+ } // end of reading node type.
break;
case XML_READER_TYPE_TEXT:
break;
default:
- dbg("invalid element");
+ err("invalid element");
}
}
- } // end of reading node value.
+ } // end of reading node value.
break;
}
} // end of parsing.
dbg("file removed");
}
- tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)),
- o, TNOTI_GPS_ASSIST_DATA, sizeof(gps_data_assist), &gps_data_assist);
+ tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)),(tcore_object_ref_plugin(o)),
+ TCORE_NOTIFICATION_GPS_ASSIST_DATA, sizeof(gps_data_assist), &gps_data_assist);
+
return TRUE;
}
-static gboolean on_notification_gps_measure_position_from_modem(CoreObject *o, char *file_name, void *user_data)
+static gboolean on_notification_imc_reset_assist_data(CoreObject *o, const void *event_info, void *user_data)
{
- char *node = NULL, *node_value = NULL;
- char *attribute = NULL;
- char *attr_value = NULL;
- gps_measure_position_indi_t gps_measure_position_indi;
- gboolean rep_quant = FALSE;
- xmlTextReaderPtr reader;
-
- memset(&gps_measure_position_indi, 0x00, sizeof(gps_measure_position_indi));
- reader = xmlReaderForFile(file_name, NULL, 0);
-
- while (xmlTextReaderRead(reader) == 1) {
- switch (xmlTextReaderNodeType(reader)) {
- case XML_READER_TYPE_ELEMENT:
- {
- node = (char *) xmlTextReaderConstName(reader);
- dbg("Element: %s", node);
- if (node != NULL) {
- // Read attribute value.
- while (xmlTextReaderMoveToNextAttribute(reader)) {
- attribute = (char *) xmlTextReaderConstName(reader);
- dbg("Attribute value - %s\n", attribute);
- attr_value = (char *) xmlTextReaderConstValue(reader);
- dbg("=\"%s\"\n", attr_value);
-
- if (strcmp(node, "mult_sets") == 0) {
- if (strcmp(attribute, "literal") == 0) {
- if (strcmp(attr_value, "one") == 0)
- gps_measure_position_indi.use_multi_sets = GPS_MULTIPLESETS_ONESET;
- else if (strcmp(attr_value, "multiple") == 0)
- gps_measure_position_indi.use_multi_sets = GPS_MULTIPLESETS_MULTIPLESETS;
- }
- dbg("gps_measure_position_indi.use_multi_sets - 0x%x\n", gps_measure_position_indi.use_multi_sets);
- } else if (strcmp(node, "rep_quant") == 0) {
- rep_quant = TRUE;
- if (strcmp(attribute, "addl_assist_data_req") == 0) {
- if (strcmp(attr_value, "true") == 0)
- gps_measure_position_indi.add_assist_req = GPS_ADDITIONAL_ASSISREQ_REQ;
- else
- gps_measure_position_indi.add_assist_req = GPS_ADDITIONAL_ASSISREQ_NOT_REQ;
- } else if (strcmp(attribute, "gps_timing_of_cell_wanted") == 0) {
- if (strcmp(attr_value, "true") == 0)
- gps_measure_position_indi.cell_timing_wnt = GPS_CELLTIMING_WANTED;
- else
- gps_measure_position_indi.cell_timing_wnt = GPS_CELLTIMING_NOT_WANTED;
- }
- }
- } // end of attribute check
-
- if (strcmp(node, "ms_assisted") == 0) {
- gps_measure_position_indi.method_type = GPS_METHODTYPE_MS_ASSISTED;
- } else if (strcmp(node, "ms_assisted_no_accuracy") == 0) {
- gps_measure_position_indi.method_type = GPS_METHODTYPE_MS_ASSISTED;
- } else if (strcmp(node, "ms_based") == 0) {
- gps_measure_position_indi.method_type = GPS_METHODTYPE_MS_BASED;
- } else if (strcmp(node, "ms_based_pref") == 0) {
- gps_measure_position_indi.method_type = GPS_METHODTYPE_MS_BASED_PREF;
- } else if (strcmp(node, "ms_assisted_pref") == 0) {
- gps_measure_position_indi.method_type = GPS_METHODTYPE_MS_ASSISTED_PREF;
- }
- }
- xmlTextReaderMoveToElement(reader);
- }
- break;
+ dbg("enter!\n");
+ tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)),(tcore_object_ref_plugin(o)),
+ TCORE_NOTIFICATION_GPS_RESET_ASSIST_DATA, 0, NULL);
- case XML_READER_TYPE_TEXT:
- {
- node_value = (char *) xmlTextReaderConstValue(reader);
- dbg("element-value: %s", node_value);
- if (node_value != NULL) {
- if (strcmp(node, "resp_time_seconds") == 0) {
- gps_measure_position_indi.rsp_time = *node_value;
- dbg("gps_measure_position_indi.rsp_time - 0x%x", gps_measure_position_indi.rsp_time);
- }
- if (rep_quant == TRUE) {
- if (strcmp(node, "hor_acc") == 0)
- gps_measure_position_indi.accuracy.horizontalAccuracy = *node_value;
- else if (strcmp(node, "vert_acc") == 0)
- gps_measure_position_indi.accuracy.vertcalAccuracy = *node_value;
- }
- }
- }
- break;
- }
- }
- xmlFreeTextReader(reader);
- xmlCleanupParser();
- tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)),
- o, TNOTI_GPS_MEASURE_POSITION, sizeof(gps_measure_position_indi), &gps_measure_position_indi);
return TRUE;
}
-
-// CONFIRMATION
-static void on_confirmation_gps_message_send(TcorePending *p, gboolean result, void *user_data)
+/* GPS Responses */
+static void on_response_imc_gps_confirm_measure_pos(TcorePending *p, guint data_len, const void *data, void *user_data)
{
+ //GPS server does not except confirmation for GPS measure position request.
+ const TcoreAtResponse *at_resp = data;
+ ImcRespCbData *resp_cb_data = user_data;
+
dbg("Entry");
- if (result == FALSE) { // Fail
- dbg("SEND FAIL");
+ if (at_resp && at_resp->success) {
+ dbg("Confirm measure position - [OK]");
} else {
- dbg("SEND OK");
+ err("Confirm measure position - [NOK]");
}
- dbg("Exit");
- return;
+ imc_destroy_resp_cb_data(resp_cb_data);
}
-static gboolean on_notification_reset_assist_data(CoreObject *o, const void *event_info, void *user_data)
-{
- dbg("enter!\n");
- tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)),
- o, TNOTI_GPS_RESET_ASSIST_DATA, 0, NULL);
-
- return TRUE;
-}
-static void on_confirmation_gps_measure_position(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- //GPS server does not except confirmation for GPS measure position request.
- dbg("enter");
-
- dbg("exit");
-}
+/* GPS Operations */
+/*
+ * Operation - confirm measure position
+ *
+ * Request -
+ * AT-Command: AT+CPOS=<cr>
+ * text is entered <ctrl-z/ESC>
+ *
+ * Success:
+ * OK
+ *
+ * Failure:
+ * +CME ERROR: <error>
+ */
-static TReturn gps_confirm_measure_pos(CoreObject *o, UserRequest *ur)
+static TelReturn imc_gps_confirm_measure_pos (CoreObject *co, const TelGpsDataInfo *gps_data,
+ TcoreObjectResponseCallback cb, void *cb_data)
{
- char *raw_str = NULL;
+ ImcRespCbData *resp_cb_data = NULL;
char *cmd_str = NULL;
- TcorePending *pending = NULL;
- TcoreATRequest *req = NULL;
- TcoreHal *hal = NULL;
- gboolean ret = FALSE;
xmlChar *xml = NULL;
- unsigned char *data = NULL;
- unsigned int data_len;
gps_measure_position_confirm_t gps_measure_pos_confirm;
+ TelReturn ret;
- dbg("enter!");
- if (!o || !ur)
- return TCORE_RETURN_EINVAL;
+ memcpy(&gps_measure_pos_confirm, gps_data->data, gps_data->data_len);
- data = (unsigned char *) tcore_user_request_ref_data(ur, &data_len);
- memcpy(&gps_measure_pos_confirm, data, data_len);
-
- // make confirm measure postion request in xml format.
xml = _generate_confirm_measure_pos_xml_text(&gps_measure_pos_confirm);
if (!xml) {
err("xml text generation failed");
- return TCORE_RETURN_EINVAL;
+ return TEL_RETURN_FAILURE;
}
- // AT+CPOS<cr>text is entered<ctrl-z/esc>
- raw_str = g_strdup_printf("AT+CPOS%s", "\r");
- cmd_str = g_strdup_printf("%s%s\x1A", raw_str, xml);
-
- dbg("command string : %s", cmd_str);
- pending = tcore_pending_new(o, 0);
- req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
- dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
- tcore_pending_set_request_data(pending, strlen(cmd_str), req);
- tcore_pending_set_priority(pending, TCORE_PENDING_PRIORITY_DEFAULT);
- tcore_pending_set_send_callback(pending, on_confirmation_gps_message_send, NULL);
- tcore_pending_set_response_callback(pending, on_confirmation_gps_measure_position, NULL);
- tcore_pending_link_user_request(pending, ur);
-
- // HAL
- hal = tcore_object_get_hal(o);
- // Send request to HAL
- ret = tcore_hal_send_request(hal, pending);
- if (TCORE_RETURN_SUCCESS != ret) {
- err("Request send failed");
- ret = FALSE;
- }
+ /* AT - Command */
+ cmd_str = g_strdup_printf("AT+CPOS%s%s\x1A", "\r", xml);
+
+ resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
+
+ /* Send Request to modem */
+ ret = tcore_at_prepare_and_send_request(co,
+ cmd_str, NULL,
+ TCORE_AT_COMMAND_TYPE_NO_RESULT,
+ TCORE_PENDING_PRIORITY_DEFAULT,
+ NULL,
+ on_response_imc_gps_confirm_measure_pos, resp_cb_data,
+ on_send_imc_request, NULL,
+ (guint)0, NULL, NULL);
+
+ IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Confirm Measure Position");
- dbg("exit");
- g_free(raw_str);
g_free(cmd_str);
- xmlFree(xml);
+
return ret;
+
}
-static struct tcore_gps_operations gps_ops = {
- .confirm_measure_pos = gps_confirm_measure_pos,
+
+ static TelReturn imc_gps_set_frequency_aiding (CoreObject *co, gboolean state,
+ TcoreObjectResponseCallback cb, void *cb_data)
+ {
+ return TEL_RETURN_OPERATION_NOT_SUPPORTED;
+ }
+
+
+static TcoreGpsOps imc_gps_ops = {
+ .confirm_measure_pos = imc_gps_confirm_measure_pos,
+ .set_frequency_aiding = imc_gps_set_frequency_aiding
};
-gboolean s_gps_init(TcorePlugin *cp, CoreObject *co_gps)
+gboolean imc_gps_init(TcorePlugin *p, CoreObject *co)
{
dbg("Enter");
- tcore_gps_override_ops(co_gps, &gps_ops);
+ /* Set operations */
+ tcore_gps_set_ops(co, &imc_gps_ops);
- tcore_object_override_callback(co_gps, "+CPOSR", on_notification_gps_assist_data, NULL);
- tcore_object_override_callback(co_gps, "+XCPOSR", on_notification_reset_assist_data, NULL);
+ /* Add Callbacks */
+ tcore_object_override_callback(co, "+CPOSR", on_notification_imc_gps_assist_data, NULL);
+ tcore_object_override_callback(co, "+XCPOSR", on_notification_imc_reset_assist_data, NULL);
dbg("Exit");
-
return TRUE;
}
-void s_gps_exit(TcorePlugin *cp, CoreObject *co_gps)
+void imc_gps_exit(TcorePlugin *p, CoreObject *co)
{
dbg("Exit");
}
--- /dev/null
+/*
+ * tel-plugin-imc
+ *
+ * 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 "imc_modem.h"
+#include "imc_common.h"
+#include "nvm/nvm.h"
+
+static gboolean on_event_imc_nvm_update(CoreObject *co,
+ const void *event_info, void *user_data);
+
+/* NVM Req/Response */
+static gboolean __imc_modem_check_nvm_response(const void *data, int command)
+{
+ const TcoreAtResponse *at_resp = data;
+ const char *line;
+ char *resp_str;
+ GSList *tokens = NULL;
+ gboolean ret = FALSE;
+
+ dbg("Entered");
+
+ /* +XDRV: <group_id>,<function_id>,<xdrv_result>[,<response_n>] */
+ if (NULL == at_resp) {
+ err("Input data is NULL");
+ return FALSE;
+ }
+
+ if (at_resp->success > 0) {
+ dbg("RESPONSE OK");
+ line = (const char *) (((GSList *) at_resp->lines)->data);
+ tokens = tcore_at_tok_new(line);
+
+ /* Group ID */
+ resp_str = g_slist_nth_data(tokens, 0);
+ if (NULL == resp_str) {
+ err("Group ID is missing ");
+ goto OUT;
+ }
+ else if (IUFP_GROUP_ID != atoi(resp_str)) {
+ err("Group ID mismatch");
+ goto OUT;
+ }
+
+ /* Function ID */
+ resp_str = g_slist_nth_data(tokens, 1);
+ if (NULL == resp_str) {
+ err("Function ID is missing ");
+ goto OUT;
+ }
+ else if (command != atoi(resp_str)) {
+ err("Function ID mismatch");
+ goto OUT;
+ }
+
+ /* XDRV Result */
+ resp_str = g_slist_nth_data(tokens, 2);
+ if (NULL == resp_str) {
+ err("XDRV result is missing ");
+ goto OUT;
+ }
+ else if (XDRV_RESULT_OK != atoi(resp_str)) {
+ err("XDRV result[%d] ", atoi(resp_str));
+ goto OUT;
+ }
+
+ /* Result code */
+ resp_str = g_slist_nth_data(tokens, 3);
+ if (NULL == resp_str) {
+ err("UTA result is missing ");
+ goto OUT;
+ }
+ else if (UTA_SUCCESS != atoi(resp_str)) {
+ err("uta result[%d] ", atoi(resp_str));
+ goto OUT;
+ }
+
+ ret = TRUE;
+ } else {
+ dbg("Response NOK");
+ }
+
+OUT:
+ tcore_at_tok_free(tokens);
+
+ dbg("Exit");
+ return ret;
+}
+
+static void __on_response_modem_unsuspend_nvm_updates(TcorePending *p,
+ guint data_len, const void *data, void *user_data)
+{
+ /* Check NVM response */
+ if (TRUE == __imc_modem_check_nvm_response(data, IUFP_SUSPEND)) {
+ dbg("Priority level is set to get all updates since Boot-up");
+
+ /* Create NV data file */
+ if (nvm_create_nvm_data() == FALSE) {
+ err("Failed to Create NV data file");
+ }
+
+ return;
+ }
+
+ err("Response NOT OK");
+}
+
+static void __imc_modem_unsuspend_nvm_updates(CoreObject *co)
+{
+ char *cmd_str;
+ TelReturn ret;
+
+ /* Prepare AT-Command */
+ cmd_str = g_strdup_printf("AT+XDRV=%d, %d, %d, %d",
+ IUFP_GROUP_ID, IUFP_SUSPEND,
+ 0, UTA_FLASH_PLUGIN_PRIO_UNSUSPEND_ALL);
+
+ /* Send Request to modem */
+ ret = tcore_at_prepare_and_send_request(co,
+ cmd_str, "+XDRV:",
+ TCORE_AT_COMMAND_TYPE_SINGLELINE,
+ TCORE_PENDING_PRIORITY_DEFAULT,
+ NULL,
+ __on_response_modem_unsuspend_nvm_updates, NULL,
+ on_send_imc_request, NULL,
+ 0, NULL, NULL);
+
+ IMC_CHECK_REQUEST_RET(ret, NULL, "Unsuspend Nvm Updates");
+
+ g_free(cmd_str);
+}
+
+static void __on_response_modem_send_nvm_update_ack(TcorePending *p,
+ guint data_len, const void *data, void *user_data)
+{
+ /* Check NVM response */
+ if (TRUE == __imc_modem_check_nvm_response(data, IUFP_UPDATE_ACK)) {
+ dbg("[UPDATE ACK] OK");
+ return;
+ }
+
+ err("[UPDATE ACK] NOT OK");
+}
+
+static void __imc_modem_send_nvm_update_ack(CoreObject *co)
+{
+ char *cmd_str;
+ TelReturn ret;
+
+ /* Prepare AT-Command */
+ cmd_str = g_strdup_printf("AT+XDRV=%s, %s", IUFP_GROUP, IUFP_UPDATE_ACK_STR);
+
+ /* Send Request to modem */
+ ret = tcore_at_prepare_and_send_request(co,
+ cmd_str, "+XDRV:",
+ TCORE_AT_COMMAND_TYPE_SINGLELINE,
+ TCORE_PENDING_PRIORITY_DEFAULT,
+ NULL,
+ __on_response_modem_send_nvm_update_ack, NULL,
+ on_send_imc_request, NULL,
+ 0, NULL, NULL);
+
+ IMC_CHECK_REQUEST_RET(ret, NULL, "Nvm Update Ack");
+
+ g_free(cmd_str);
+}
+
+static void __on_response_modem_send_nvm_update_request_ack(TcorePending *p,
+ guint data_len, const void *data, void *user_data)
+{
+ /* Check NVM response */
+ if (TRUE == __imc_modem_check_nvm_response(data, IUFP_UPDATE_REQ_ACK)) {
+ dbg("[REQUEST ACK] OK");
+ return;
+ }
+
+ err("[REQUEST ACK] NOT OK");
+}
+
+static void __imc_modem_send_nvm_update_request_ack(CoreObject *co)
+{
+ char *cmd_str;
+ TelReturn ret;
+
+ /* Prepare AT-Command */
+ cmd_str = g_strdup_printf("AT+XDRV=%s, %s", IUFP_GROUP, IUFP_UPDATE_REQ_ACK_STR);
+
+ /* Send Request to modem */
+ ret = tcore_at_prepare_and_send_request(co,
+ cmd_str, "+XDRV:",
+ TCORE_AT_COMMAND_TYPE_SINGLELINE,
+ TCORE_PENDING_PRIORITY_DEFAULT,
+ NULL,
+ __on_response_modem_send_nvm_update_request_ack, NULL,
+ on_send_imc_request, NULL,
+ 0, NULL, NULL);
+
+ IMC_CHECK_REQUEST_RET(ret, NULL, "Nvm Update Request Ack");
+
+ g_free(cmd_str);
+}
+
+static void __on_response_modem_register_nvm(TcorePending *p,
+ guint data_len, const void *data, void *user_data)
+{
+ /* Check NVM response */
+ if (TRUE == __imc_modem_check_nvm_response(data, IUFP_REGISTER)) {
+ dbg("Registering successful");
+
+ /* Send SUSPEND_UPDATE for all UPDATES */
+ __imc_modem_unsuspend_nvm_updates(tcore_pending_ref_core_object(p));
+
+ dbg("Exit");
+ return;
+ }
+
+ err("Response NOT OK");
+}
+
+/* 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 imc_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);
+
+ return TRUE;
+}
+
+/* Modem Responses */
+static void on_response_imc_modem_set_power_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);
+ ImcRespCbData *resp_cb_data = user_data;
+ TelModemPowerStatus *status;
+ gboolean powered = FALSE;
+
+ 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;
+
+ status = (TelModemPowerStatus *)
+ IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
+
+ /* Update Core Object */
+ switch (*status) {
+ case TEL_MODEM_POWER_ON:
+ dbg("Setting Modem Power status [ON] - [%s]",
+ (result == TEL_MODEM_RESULT_SUCCESS ? "SUCCESS" : "FAIL"));
+ powered = TRUE;
+ break;
+ case TEL_MODEM_POWER_OFF:
+ dbg("Setting Modem Power status [OFF] - [%s]",
+ (result == TEL_MODEM_RESULT_SUCCESS ? "SUCCESS" : "FAIL"));
+ powered = FALSE;
+ break;
+ default:
+ warn("Unexpected - Setting Modem Power status [RESET] - [%s]",
+ (result == TEL_MODEM_RESULT_SUCCESS ? "SUCCESS" : "FAIL"));
+ break;
+ }
+ tcore_modem_set_powered(co, powered);
+
+ /* Invoke callback */
+ if (resp_cb_data->cb)
+ resp_cb_data->cb(co, (gint)result, NULL, resp_cb_data->cb_data);
+
+ /* Free callback data */
+ imc_destroy_resp_cb_data(resp_cb_data);
+}
+
+static void on_response_imc_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);
+ ImcRespCbData *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 *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
+
+ dbg("Setting Modem Fiight 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 */
+ imc_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.
+ */
+}
+
+/* Current modem does not support this operation */
+#if 0
+static void on_response_imc_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);
+ ImcRespCbData *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);
+ if (sw_ver != NULL){
+ g_strlcpy(version.software_version,
+ sw_ver,
+ TEL_MODEM_VERSION_LENGTH_MAX + 1);
+ }
+ if (hw_ver != NULL){
+ g_strlcpy(version.hardware_version,
+ hw_ver,
+ TEL_MODEM_VERSION_LENGTH_MAX + 1);
+ }
+ if (calib_date != NULL){
+ g_strlcpy(version.calibration_date,
+ calib_date,
+ TEL_MODEM_VERSION_LENGTH_MAX + 1);
+ }
+ if (p_code != NULL){
+ 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 */
+ imc_destroy_resp_cb_data(resp_cb_data);
+}
+#endif
+
+static void on_response_imc_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);
+ ImcRespCbData *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 */
+ imc_destroy_resp_cb_data(resp_cb_data);
+}
+
+/* Modem Operations */
+/*
+ * Operation - set_power_status
+ *
+ * Request -
+ * AT-Command: AT+CFUN=<fun>
+ * where,
+ * <fun>
+ * 0 Mode to switch off MS
+ * ... Other modes are available for other oprations
+ *
+ * Response -
+ * Success: (No Result)
+ * OK
+ * Failure:
+ * +CME ERROR: <error>
+ */
+static TelReturn imc_modem_set_power_status(CoreObject *co,
+ TelModemPowerStatus status,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ gchar *at_cmd;
+ guint power_mode;
+
+ ImcRespCbData *resp_cb_data;
+ TelReturn ret;
+
+ if (status == TEL_MODEM_POWER_ON) {
+ warn("Modem Power ON - Not supported by CP");
+ return TEL_RETURN_OPERATION_NOT_SUPPORTED;
+ } else if (status == TEL_MODEM_POWER_ERROR) {
+ err("Modem Power ERROR - Invalid mode");
+ return TEL_RETURN_INVALID_PARAMETER;
+ } else {
+ dbg("Modem Power OFF");
+ power_mode = 0;
+ }
+
+ /* AT-Command */
+ at_cmd = g_strdup_printf("AT+CFUN=%d", power_mode);
+
+ /* Response callback data */
+ resp_cb_data = imc_create_resp_cb_data(cb, cb_data,
+ &status, sizeof(TelModemPowerStatus));
+
+ /* 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_imc_modem_set_power_status, resp_cb_data,
+ on_send_imc_request, NULL,
+ 0, NULL, NULL);
+ IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Set Power Status");
+
+ /* Free resources */
+ g_free(at_cmd);
+
+ return ret;
+}
+
+/*
+ * Operation - set_flight_mode
+ *
+ * Request -
+ * AT-Command: AT+CFUN=<fun>
+ * where,
+ * <fun>
+ * 0 Mode to switch off MS
+ * 1 Full functionality
+ * 4 Mode to disable phone both transmit and receive
+ * RF circuits. Airplane mode.
+ * ... Other modes are available for other oprations
+ *
+ * Response -
+ * Success: (No Result)
+ * OK
+ * Failure:
+ * +CME ERROR: <error>
+ */
+static TelReturn imc_modem_set_flight_mode(CoreObject *co, gboolean enable,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ gchar *at_cmd;
+ guint power_mode;
+
+ ImcRespCbData *resp_cb_data;
+ TelReturn ret;
+
+ if (enable) {
+ dbg("Flight mode - [ON]");
+ power_mode = 4;
+ } 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 = imc_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_imc_modem_set_flight_mode, resp_cb_data,
+ on_send_imc_request, NULL,
+ 0, NULL, NULL);
+ IMC_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 imc_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 imc_modem_get_version(CoreObject *co,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ dbg("entry");
+
+/* Current modem does not support this operation */
+#if 0
+ ImcRespCbData *resp_cb_data;
+ TelReturn ret;
+
+ /* Response callback data */
+ resp_cb_data = imc_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_imc_modem_get_version, resp_cb_data,
+ on_send_imc_request, NULL,
+ 0, NULL, NULL);
+ IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Get Version");
+
+ return ret;
+#endif
+
+ dbg("exit");
+ return TEL_RETURN_OPERATION_NOT_SUPPORTED;
+}
+
+/*
+ * 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 imc_modem_get_imei(CoreObject *co,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ ImcRespCbData *resp_cb_data;
+ TelReturn ret;
+
+ dbg("Enter");
+
+ /* Response callback data */
+ resp_cb_data = imc_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_imc_modem_get_imei, resp_cb_data,
+ on_send_imc_request, NULL,
+ 0, NULL, NULL);
+ IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Get IMEI");
+
+ return ret;
+}
+
+/* Modem Operations */
+static TcoreModemOps imc_modem_ops = {
+ .set_power_status = imc_modem_set_power_status,
+ .set_flight_mode = imc_modem_set_flight_mode,
+ .get_flight_mode = imc_modem_get_flight_mode,
+ .get_version = imc_modem_get_version,
+ .get_imei = imc_modem_get_imei
+};
+
+gboolean imc_modem_init(TcorePlugin *p, CoreObject *co)
+{
+ dbg("Enter");
+
+ /* Set operations */
+ tcore_modem_set_ops(co, &imc_modem_ops);
+
+ /* Add Callbacks */
+ tcore_object_add_callback(co, "+XDRVI:", on_event_imc_nvm_update, NULL);
+
+ dbg("Exit");
+ return TRUE;
+}
+
+void imc_modem_exit(TcorePlugin *p, CoreObject *co)
+{
+ dbg("Exit");
+}
+
+/*
+ * NV Manager - Support for Remote File System
+ */
+/* NVM Hook */
+static gboolean __imc_nvm_modem_rfs_hook(const char *data)
+{
+ if (data != NULL)
+ if (data[NVM_FUNCTION_ID_OFFSET] == XDRV_INDICATION)
+ return TRUE;
+
+ return FALSE;
+}
+
+/* NVM Event */
+gboolean on_event_imc_nvm_update(CoreObject *co,
+ const void *event_info, void *user_data)
+{
+ GSList *tokens = NULL;
+ GSList *lines;
+ const char *line;
+ int function_id;
+
+ gboolean ret = TRUE;
+ dbg("Entered");
+
+ lines = (GSList *)event_info;
+ line = lines->data;
+ dbg("Line: [%s]", line);
+
+ function_id = nvm_sum_4_bytes(&line[NVM_FUNCTION_ID_OFFSET]);
+ dbg("Function ID: [%d]", function_id);
+ if (IUFP_UPDATE == function_id) {
+ dbg("Calling process nvm_update");
+
+ /*
+ * Process NV Update indication
+ *
+ * +XDRVI: IUFP_GROUP, IUFP_UPDATE, <xdrv_result>, <data>
+ */
+ if (NVM_NO_ERR == nvm_process_nv_update(line)) {
+ dbg("NV data processed successfully");
+
+ /* Acknowledge NV Update */
+ __imc_modem_send_nvm_update_ack(co);
+
+ return ret;
+ } else {
+ err("NV data processing failed");
+ ret = FALSE;
+ }
+ } else {
+ tokens = tcore_at_tok_new(line);
+ if (g_slist_length(tokens) < 3) {
+ err("XDRVI event with less number of tokens, Ignore!!!");
+ ret = FALSE;
+ }
+ else if (IUFP_GROUP_ID != atoi(g_slist_nth_data(tokens, 0))) {
+ err("Group ID mismatch, Ignore!!!");
+ ret = FALSE;
+ }
+ else {
+ switch (atoi(g_slist_nth_data(tokens, 1))) {
+ case IUFP_UPDATE_REQ:
+ dbg("NV Update Request");
+
+ /* Acknowledge the Update Request */
+ __imc_modem_send_nvm_update_request_ack(co);
+ break;
+
+ case IUFP_NO_PENDING_UPDATE:
+ dbg("NO pending NV Update(s)!!!");
+ /* Can send FLUSH request to get fresh updates */
+ break;
+
+ default:
+ err("Unspported Function ID [%d], Ignore", atoi(g_slist_nth_data(tokens, 1)));
+ ret = FALSE;
+ }
+ }
+
+ tcore_at_tok_free(tokens);
+ }
+
+ dbg("Exit");
+ return ret;
+}
+
+/* NVM Register */
+void imc_modem_register_nvm(CoreObject *co)
+{
+ char *cmd_str;
+ TelReturn ret;
+
+ /* Prepare AT-Command */
+ cmd_str = g_strdup_printf("AT+XDRV=%s, %s, %s",
+ IUFP_GROUP, IUFP_REGISTER_STR, XDRV_ENABLE);
+
+ /* Send Request to modem */
+ ret = tcore_at_prepare_and_send_request(co,
+ cmd_str, "+XDRV:",
+ TCORE_AT_COMMAND_TYPE_SINGLELINE,
+ TCORE_PENDING_PRIORITY_DEFAULT,
+ NULL,
+ __on_response_modem_register_nvm, NULL,
+ on_send_imc_request, NULL,
+ 0, NULL, NULL);
+ if (ret != TEL_RETURN_SUCCESS) {
+ err("Failed to process request - [Register NVM]");
+ }
+ else {
+ /* Add RFS hook */
+ dbg("Adding NVM hook");
+ tcore_at_add_hook(tcore_object_get_hal(co), __imc_nvm_modem_rfs_hook);
+ }
+
+ g_free(cmd_str);
+}
--- /dev/null
+/*
+ * tel-plugin-imc
+ *
+ * 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 <tzplatform_config.h>
+
+#include <co_network.h>
+
+#include "imc_network.h"
+#include "imc_common.h"
+
+#define IMC_NETWORK_BASE_16 16
+
+static TelNetworkAct __imc_network_map_act(guint act)
+{
+ /*
+ * <ACT>
+ * 0 GSM
+ * 2 UTRAN
+ * 3 GSM w/EGPRS
+ * 4 UTRAN w/HSDPA
+ * 5 UTRAN w/HSUPA
+ * 6 UTRAN w/HSDPA and HSUPA
+ */
+ switch (act) {
+ case 0:
+ return TEL_NETWORK_ACT_GSM;
+ case 2:
+ return TEL_NETWORK_ACT_UMTS;
+ case 3:
+ return TEL_NETWORK_ACT_EGPRS;
+ case 4:
+ return TEL_NETWORK_ACT_HSDPA;
+ case 5:
+ return TEL_NETWORK_ACT_HSUPA;
+ case 6:
+ return TEL_NETWORK_ACT_HSPA;
+ default:
+ return TEL_NETWORK_ACT_UNKNOWN;
+ }
+}
+
+static TelNetworkRegStatus __imc_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_imc_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 __imc_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_imc_network_registration, NULL,
+ on_send_imc_request, NULL,
+ 0, NULL, NULL);
+ dbg("Sending Network Registration request: [%s]",
+ (ret == TEL_RETURN_SUCCESS ? "SUCCESS" : "FAIL"));
+}
+
+static void __on_response_imc_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_object_send_notification(co,
+ TCORE_NOTIFICATION_NETWORK_IDENTITY,
+ sizeof(TelNetworkIdentityInfo), identity);
+}
+
+static TcoreHookReturn __on_response_imc_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.
+ */
+ __imc_network_register_to_network(co);
+
+ return TCORE_HOOK_RETURN_CONTINUE;
+}
+
+static void __on_response_imc_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);
+ ImcRespCbData *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
+ *
+ * +XCOPS: <type>[,<name>[,<display_condition>]]
+ */
+ dbg("<line> : [%s]", line);
+ tokens = tcore_at_tok_new(line);
+
+ if ((token_str = tcore_at_tok_nth(tokens, 0))) {
+ guint type = atoi(token_str);
+ dbg("<type> : [%d]", type);
+
+ switch (type) {
+ case 0: /* 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;
+
+ case 1: /* Short Name in ROM (NV-RAM) */
+ case 3: /* Short Network Operator Name (CPHS) */
+ case 5: /* Short NITZ 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: /* Long Name in ROM (NV-RAM) */
+ case 4: /* Long Network Operator Name (CPHS) */
+ case 6: /* Full NITZ 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;
+
+ 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 */
+ imc_destroy_resp_cb_data(resp_cb_data);
+}
+
+/*
+ * Operation - fetch_nw_name
+ *
+ * Request -
+ * AT-Command: AT+XCOPS=<Type>
+ *
+ * <type> may be
+ * 0 numeric format of network MCC/MNC (three BCD
+ * digit country code and two/three BCD digit network code)
+ * 1 Short Name in ROM (NV-RAM)
+ * 2 Long Name in ROM (NV-RAM)
+ * 3 Short Network Operator Name (CPHS)
+ * 4 Long Network Operator Name (CPHS)
+ * 5 Short NITZ Name
+ * 6 Full NITZ Name
+ * 7 Service Provider Name
+ * 8 EONS short operator name from EF-PNN
+ * 9 EONS long operator name from EF-PNN
+ * 11 Short PLMN name (When PS or CS is registered)
+ * 12 Long PLMN name (When PS or CS is registered)
+ * 13 numeric format of network MCC/MNC even in limited service
+ *
+ * Response - Network name
+ * Success: (Multiple Single line)
+ * +XCOPS: <type>[,<name>[,<display_condition>]]
+ * OK
+ * Failure:
+ * +CME ERROR: <error>
+ */
+static TelReturn __imc_network_fetch_nw_name(CoreObject *co,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ ImcRespCbData *resp_cb_data = NULL;
+ TelReturn ret;
+
+ /* Response callback data */
+ resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
+
+ /* Send Request to modem */
+ ret = tcore_at_prepare_and_send_request(co,
+ "AT+XCOPS=0;+XCOPS=5;+XCOPS=6", "+XCOPS",
+ TCORE_AT_COMMAND_TYPE_MULTILINE,
+ TCORE_PENDING_PRIORITY_DEFAULT,
+ NULL,
+ __on_response_imc_network_fetch_nw_name, resp_cb_data,
+ on_send_imc_request, NULL,
+ 0, NULL, NULL);
+ IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Fetch Network name");
+
+ return ret;
+}
+
+/* Hook functions */
+static TcoreHookReturn on_hook_imc_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_imc_hook_set_flight_mode, NULL);
+
+ return TCORE_HOOK_RETURN_CONTINUE;
+ }
+
+ dbg("Flight mode - [Enabled]");
+ return TCORE_HOOK_RETURN_CONTINUE;
+}
+
+static TcoreHookReturn on_hook_imc_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.
+ */
+ __imc_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_imc_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 = __imc_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, IMC_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, IMC_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 = __imc_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)__imc_network_fetch_nw_name(co,
+ __on_response_imc_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_object_send_notification(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_imc_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 = __imc_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, IMC_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, IMC_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 = __imc_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, IMC_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_object_send_notification(co,
+ TCORE_NOTIFICATION_NETWORK_LOCATION_CELLINFO,
+ sizeof(TelNetworkCellInfo), &cell_info);
+
+out:
+ /* Free resource */
+ tcore_at_tok_free(tokens);
+ }
+
+ return TRUE;
+}
+
+/*
+ * Notification: +XNITZINFO: <fullname>,<shortname>,<LTZ>,<UT>,<DST>
+ *
+ * <longname>
+ * string type; Network name in long alphanumeric format.
+ *
+ * <shortname>
+ * string type; Network name in short alphanumeric format.
+ *
+ * <LTZ>
+ * Local Time Zone; represented as 1 unit = 15 minutes.
+ *
+ * <UT>
+ * string type value; Universal Time
+ * format is "yy/MM/dd,hh:mm:ss",
+ * wherein characters indicates year, month, day, hour,
+ * minutes, seconds.
+ * <DST>
+ * Daylight Saving Time; represented in hours.
+ */
+static gboolean on_notification_imc_network_time_info(CoreObject *co,
+ const void *event_info, void *user_data)
+{
+ GSList *lines = NULL;
+ gchar *line = NULL;
+
+ dbg("Network notification - Time info: [+XNITZINFO]");
+
+ lines = (GSList *)event_info;
+ if (g_slist_length(lines) != 1) {
+ err("+XNITZINFO unsolicited message expected to be Single line "
+ "but received multiple lines");
+ return TRUE;
+ }
+
+ line = (gchar *)lines->data;
+ if (line != NULL) {
+ GSList *tokens = NULL;
+ TelNetworkNitzInfoNoti nitz_info = {0, };
+ gchar *fullname, *shortname;
+ gchar *ltz, *time;
+ gchar tmp_time[8] = {0};
+ gchar *dstoff;
+
+ /*
+ * Tokenize
+ *
+ * +XNITZINFO: <fullname>,<shortname>,<LTZ>,<UT>,<DST>
+ */
+ tokens = tcore_at_tok_new(line);
+
+ /* <fullname> */
+ if ((fullname = tcore_at_tok_nth(tokens, 1))) {
+ if (strlen(fullname) > 0) {
+ fullname = tcore_at_tok_extract((const char *)fullname);
+
+ /* Update Long name */
+ tcore_network_set_long_name(co, fullname);
+
+ tcore_free(fullname);
+ }
+ }
+
+ /* <shortname> */
+ if ((shortname = tcore_at_tok_nth(tokens, 1))) {
+ if (strlen(shortname) > 0) {
+ shortname = tcore_at_tok_extract((const char *)shortname);
+
+ /* Update Short name */
+ tcore_network_set_short_name(co, shortname);
+
+ tcore_free(shortname);
+ }
+ }
+
+ /* <LTZ> */
+ if ((ltz = g_slist_nth_data(tokens, 2)))
+ nitz_info.gmtoff = atoi(ltz) * 15;/* gmtoff in minutes */
+
+ if ((time = g_slist_nth_data(tokens, 3))
+ && (strlen(time) > 18)) {
+ /* (time + 1) - Skip past initial quote (") */
+ g_strlcpy(tmp_time, time + 1, 2+1);
+ nitz_info.year = atoi(tmp_time);
+
+ /* skip slash (/) after year param */
+ g_strlcpy(tmp_time, time + 4, 2+1);
+ nitz_info.month = atoi(tmp_time);
+
+ /* skip past slash (/) after month param */
+ g_strlcpy(tmp_time, time + 7, 2+1);
+ nitz_info.day = atoi(tmp_time);
+
+ /* skip past comma (,) after day param */
+ g_strlcpy(tmp_time, time + 10, 2+1);
+ nitz_info.hour = atoi(tmp_time);
+
+ /* skip past colon (:) after hour param */
+ g_strlcpy(tmp_time, time + 13, 2+1);
+ nitz_info.minute = atoi(tmp_time);
+
+ /* skip past colon (:) after minute param */
+ g_strlcpy(tmp_time, time + 16, 2+1);
+ nitz_info.second = atoi(tmp_time);
+ }
+
+ /* <DST> */
+ if ((dstoff = g_slist_nth_data(tokens, 4))) {
+ nitz_info.dstoff = atoi(dstoff);
+ nitz_info.isdst = TRUE;
+ }
+
+ /* Get PLMN */
+ tcore_network_get_plmn(co, &nitz_info.plmn);
+
+ /* Send Notification - Network time info */
+ tcore_object_send_notification(co,
+ TCORE_NOTIFICATION_NETWORK_TIMEINFO,
+ sizeof(TelNetworkNitzInfoNoti), &nitz_info);
+
+ /* Free resource */
+ tcore_free(nitz_info.plmn);
+ tcore_at_tok_free(tokens);
+ }
+
+ return TRUE;
+}
+
+/*
+ * Notification:
+ * +XCIEV: <rssi>,
+ * or
+ * +XCIEV:,<battery_level>
+ *
+ * 'Radio Signal Strength' <rssi> can have the values
+ * 0 -107 dBm or less or unknown
+ * 1 -99 dBm or less
+ * 2 -91 dBm or less
+ * 3 -83 dBm or less
+ * 4 -75 dBm or less
+ * 5 -67 dBm or less
+ * 6 -59 dBm or less
+ * 7 -51 dBm or less
+ *
+ * 'Battery Level' <battery_level> can have the values
+ * 0 0 % <= level < 5 %
+ * 1 5 % <= level < 15 %
+ * 2 15 % <= level < 25 %
+ * 3 25 % <= level < 40 %
+ * 4 40 % <= level < 55 %
+ * 5 55 % <= level < 70 %
+ * 6 70 % <= level < 85 %
+ * 7 85 % <= level <= 100 %
+ *
+ * NOTE:
+ * <battery_level> is not consider for
+ * TCORE_NOTIFICATION_NETWORK_RSSI notification
+ */
+static gboolean on_notification_imc_network_rssi(CoreObject *co,
+ const void *event_info, void *user_data)
+{
+ GSList *lines = NULL;
+ gchar *line = NULL;
+
+ dbg("Network notification - Icon (rssi) info: [+XCIEV]");
+
+ lines = (GSList *)event_info;
+ if (g_slist_length(lines) != 1) {
+ err("+XCIEV unsolicited message expected to be Single line "
+ "but received multiple lines");
+ return TRUE;
+ }
+
+ line = (gchar *)lines->data;
+ if (line != NULL) {
+ GSList *tokens = NULL;
+ gchar *rssi_token;
+
+ /*
+ * Tokenize
+ *
+ * +XCIEV: <rssi>,
+ */
+ tokens = tcore_at_tok_new(line);
+
+ rssi_token = (gchar *)g_slist_nth_data(tokens, 0);
+ if (rssi_token && strlen(rssi_token)) {
+ guint rssi_bar = atoi(rssi_token);
+ dbg("RSSI Level: [%d]", rssi_bar);
+
+ /* Send Notification - Network Rssi */
+ tcore_object_send_notification(co,
+ TCORE_NOTIFICATION_NETWORK_RSSI,
+ sizeof(guint), &rssi_bar);
+ }
+
+ /* Free resource */
+ tcore_at_tok_free(tokens);
+ }
+
+ return TRUE;
+}
+
+/* Network Responses */
+
+static void on_response_imc_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);
+ ImcRespCbData *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.count,
+ 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);
+
+ imc_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_imc_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);
+ ImcRespCbData *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;
+
+ result = TEL_NETWORK_RESULT_SUCCESS;
+ dbg("selection mode[%d]", selection_mode);
+
+ } 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 */
+ imc_destroy_resp_cb_data(resp_cb_data);
+ /* Free resource*/
+ tcore_at_tok_free(tokens);
+}
+
+static void on_response_imc_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);
+ ImcRespCbData *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);
+
+ imc_destroy_resp_cb_data(resp_cb_data);
+}
+
+
+static void on_response_imc_network_get_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);
+ ImcRespCbData *resp_cb_data = user_data;
+ TelNetworkResult result = TEL_NETWORK_RESULT_FAILURE; //TODO - CME Error mapping required.
+ TelNetworkMode mode = -1;
+ 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;
+ gint net_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) {
+ err("invalid message");
+ goto END;
+ }
+
+ dbg("RESPONSE OK");
+ net_mode = atoi(tcore_at_tok_nth(tokens, 0));
+ dbg("mode = %d", net_mode);
+
+ switch(net_mode) {
+ case 0:
+ mode = TEL_NETWORK_MODE_2G;
+ break;
+ case 1:
+ mode = TEL_NETWORK_MODE_AUTO;
+ break;
+ case 2:
+ mode = TEL_NETWORK_MODE_3G;
+ break;
+ default:
+ err("Unsupported mode [%d]", net_mode);
+ goto END;
+ }
+ result = TEL_NETWORK_RESULT_SUCCESS;
+ } else {
+ err("RESPONSE NOK");
+ }
+END:
+ /* Invoke callback */
+ if (resp_cb_data->cb)
+ resp_cb_data->cb(co, (gint)result, &mode, resp_cb_data->cb_data);
+
+ /* Free callback data */
+ imc_destroy_resp_cb_data(resp_cb_data);
+ /* Free resource*/
+ tcore_at_tok_free(tokens);
+}
+
+static void on_response_imc_network_get_preferred_plmn(TcorePending *p,
+ guint data_len, const void *data, void *user_data)
+{
+ const TcoreAtResponse *at_resp = data;
+ CoreObject *co = tcore_pending_ref_core_object(p);
+ ImcRespCbData *resp_cb_data = user_data;
+ TelNetworkPreferredPlmnList plmn_list = {0,};
+ guint count = 0, total_lines = 0;
+ 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) {
+ GSList *tokens;
+ gchar *resp;
+ gchar *line;
+ gboolean gsm_act2 = FALSE, gsm_compact_act2 = FALSE;
+ gboolean utran_act2 = FALSE;
+
+ if (!at_resp->lines) {
+ err("invalid response received");
+ goto END;
+ }
+
+ total_lines = g_slist_length(at_resp->lines);
+ if (total_lines < 1) {
+ msg("invalid message");
+ goto END;
+ }
+
+ dbg("RESPONSE OK");
+ result = TEL_NETWORK_RESULT_SUCCESS;
+
+ plmn_list.list = tcore_malloc0(sizeof(TelNetworkPreferredPlmnInfo) * total_lines);
+ plmn_list.count = 0;
+
+ for (count = 0; count < total_lines; count++) {
+ /* Take each line response at a time & parse it */
+ line = tcore_at_tok_nth(at_resp->lines, count);
+ tokens = tcore_at_tok_new(line);
+
+ /*Index */
+ if ((resp = tcore_at_tok_nth(tokens, 0))) {
+ plmn_list.list[count].index = atoi(resp);
+ }
+
+ /* PLMN ID */
+ if ((resp = tcore_at_tok_nth(tokens, 2))) {
+ plmn_list.list[count].plmn = tcore_at_tok_extract(resp);
+ }
+
+ /*GSM_AcT1 */
+ if ((resp = tcore_at_tok_nth(tokens, 3))) {
+ gsm_act2 = atoi(resp);
+ }
+
+ /*GSM_Compact_AcT2 */
+ if ((resp = tcore_at_tok_nth(tokens, 4))) {
+ gsm_compact_act2 = atoi(resp);
+ }
+
+ /*UTRAN_AcT2 */
+ if ((resp = tcore_at_tok_nth(tokens, 5))) {
+ utran_act2 = atoi(resp);
+ }
+
+ if (gsm_act2)
+ plmn_list.list[count].act = TEL_NETWORK_ACT_UMTS;
+ else if (utran_act2 || gsm_compact_act2)
+ plmn_list.list[count].act = TEL_NETWORK_ACT_GSM;
+
+ /* free tokens*/
+ tcore_at_tok_free(tokens);
+
+ dbg("index[%d], plmn[%s], act[%d]",
+ plmn_list.list[count].index,
+ plmn_list.list[count].plmn,
+ plmn_list.list[count].act);
+
+ }
+ plmn_list.count = count;
+ } else {
+ err("RESPONSE NOK");
+ if (at_resp->lines)
+ err("CME Error[%s]",(char *)at_resp->lines->data);
+ }
+
+END:
+ dbg("get preferred plmn : [%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);
+
+ /* Free callback data */
+ imc_destroy_resp_cb_data(resp_cb_data);
+
+ for(count = 0; count < total_lines; count++) {
+ g_free(plmn_list.list[count].plmn);
+ }
+ tcore_free(plmn_list.list);
+}
+
+
+/* Network Operations */
+/*
+ * Operation - set_power_status
+ *
+ * Request -
+ * AT-Command: AT+XCOPS=<Type>
+ *
+ * <type> may be
+ * 0 numeric format of network MCC/MNC (three BCD
+ * digit country code and two/three BCD digit network code)
+ * 1 Short Name in ROM (NV-RAM)
+ * 2 Long Name in ROM (NV-RAM)
+ * 3 Short Network Operator Name (CPHS)
+ * 4 Long Network Operator Name (CPHS)
+ * 5 Short NITZ Name
+ * 6 Full NITZ Name
+ * 7 Service Provider Name
+ * 8 EONS short operator name from EF-PNN
+ * 9 EONS long operator name from EF-PNN
+ * 11 Short PLMN name (When PS or CS is registered)
+ * 12 Long PLMN name (When PS or CS is registered)
+ * 13 numeric format of network MCC/MNC even in limited service
+ *
+ * Response - Network name
+ * Success: (Multiple Single line)
+ * +XCOPS: <type>[,<name>[,<display_condition>]]
+ * OK
+ * Failure:
+ * +CME ERROR: <error>
+ */
+static TelReturn imc_network_get_identity_info(CoreObject *co,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ return __imc_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 imc_network_search(CoreObject *co,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ ImcRespCbData *resp_cb_data;
+ TelReturn ret = TEL_RETURN_INVALID_PARAMETER;
+
+ /* Response callback data */
+ resp_cb_data = imc_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_imc_network_search, resp_cb_data,
+ on_send_imc_request, NULL,
+ 0, NULL, NULL);
+
+ IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Network Search");
+ return ret;
+}
+
+static TelReturn imc_network_cancel_search(CoreObject *co,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ ImcRespCbData *resp_cb_data;
+ TelReturn ret = TEL_RETURN_INVALID_PARAMETER;
+
+ /* Response callback data */
+ resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
+
+ /* Send Request to modem */
+ ret = tcore_at_prepare_and_send_request(co,
+ "\e", NULL,
+ TCORE_AT_COMMAND_TYPE_NO_RESULT,
+ TCORE_PENDING_PRIORITY_IMMEDIATELY,
+ NULL,
+ on_response_imc_network_default, resp_cb_data,
+ on_send_imc_request, NULL,
+ 0, NULL, NULL);
+
+ IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Cancel 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 imc_network_select_automatic(CoreObject *co,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ ImcRespCbData *resp_cb_data;
+ TelReturn ret = TEL_RETURN_INVALID_PARAMETER;
+ dbg("entry");
+
+ /* Response callback data */
+ resp_cb_data = imc_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_imc_network_default, resp_cb_data,
+ on_send_imc_request, NULL,
+ 0, NULL, NULL);
+
+ IMC_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 imc_network_select_manual(CoreObject *co,
+ const TelNetworkSelectManualInfo *sel_manual,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ ImcRespCbData *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 = imc_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_imc_network_default, resp_cb_data,
+ on_send_imc_request, NULL,
+ 0, NULL, NULL);
+
+ IMC_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 imc_network_get_selection_mode(CoreObject *co,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ ImcRespCbData *resp_cb_data;
+ TelReturn ret = TEL_RETURN_INVALID_PARAMETER;
+
+ /* Response callback data */
+ resp_cb_data = imc_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_imc_network_get_selection_mode, resp_cb_data,
+ on_send_imc_request, NULL,
+ 0, NULL, NULL);
+
+ IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Get selection mode");
+ return ret;
+}
+
+/*
+ * Operation - set preferred plmn
+ * Request -
+ * AT-Command: AT+CPOL=<index>][,<format>[,<oper>[,<GSM_AcT>,<GSM_Compact_AcT>,<UTRAN_AcT>]]]
+ * where
+ * <indexn> integer type; the order number of operator in the SIM/USIM preferred operator list
+ * <format>
+ * 0 long format alphanumeric <oper>
+ * 1 short format alphanumeric <oper>
+ * 2 numeric <oper>
+ * <opern> string type; <format> indicates if the format is alphanumeric or numeric (see +COPS)
+ * <GSM_AcTn>: GSM access technology
+ * 0 access technology not selected
+ * 1 access technology selected
+ * <GSM_Compact_AcTn>: GSM compact access technology
+ * 0 access technology not selected
+ * 1 access technology selected
+ * <UTRA_AcTn>: UTRA access technology
+ * 0 access technology not selected
+ * 1 access technology selected
+ *
+ * Response -
+ * Success:(No Result)
+ * OK
+ * Failure:
+ * +CME ERROR: <error>
+ */
+static TelReturn imc_network_set_preferred_plmn(CoreObject *co,
+ const TelNetworkPreferredPlmnInfo *pref_plmn,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ ImcRespCbData *resp_cb_data;
+ gchar *at_cmd;
+ gboolean gsm_act = FALSE;
+ gboolean gsm_compact_act = FALSE;
+ gboolean utran_act = FALSE;
+ TelReturn ret = TEL_RETURN_INVALID_PARAMETER;
+ dbg("entry");
+
+ switch(pref_plmn->act) {
+ case TEL_NETWORK_ACT_GSM:
+ case TEL_NETWORK_ACT_GPRS:
+ case TEL_NETWORK_ACT_EGPRS:
+ gsm_act = TRUE;
+ break;
+ case TEL_NETWORK_ACT_UMTS:
+ case TEL_NETWORK_ACT_HSDPA:
+ case TEL_NETWORK_ACT_HSPA:
+ utran_act = TRUE;
+ break;
+ case TEL_NETWORK_ACT_GSM_AND_UMTS:
+ gsm_act = utran_act = TRUE;
+ break;
+ default:
+ warn("unsupported AcT");
+ }
+
+ /* AT-Command */
+ at_cmd = g_strdup_printf("AT+CPOL=%d,%d,\"%s\",%d,%d,%d",
+ pref_plmn->index, 2, pref_plmn->plmn, gsm_act, gsm_compact_act, utran_act);
+
+ /* Response callback data */
+ resp_cb_data = imc_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_imc_network_default, resp_cb_data,
+ on_send_imc_request, NULL,
+ 0, NULL, NULL);
+
+ IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Set preferred plmn");
+ g_free(at_cmd);
+ return ret;
+}
+
+/*
+ * Operation - get preferred plmn
+ * Request -
+ * AT-Command: AT+CPOL?
+ * Response -
+ * Success: (multiline)
+ * +CPOL: <index1>,<format>,<oper1>
+ * [,<GSM_AcT1>,<GSM_Compact_AcT1>,<UTRAN_AcT1>][<CR><LF>
+ * +CPOL: <index2>,<format>,<oper2>[,<GSM_AcT2>,<GSM_Compact_AcT2>,<UTRAN_AcT2>] [\85]]
+ * OK
+ * Failure
+ * +CME ERROR: <err>
+ */
+static TelReturn imc_network_get_preferred_plmn(CoreObject *co,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ ImcRespCbData *resp_cb_data;
+ TelReturn ret = TEL_RETURN_INVALID_PARAMETER;
+ dbg("entry");
+
+ /* Response callback data */
+ resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
+
+ /* Send Request to modem */
+ ret = tcore_at_prepare_and_send_request(co,
+ "AT+CPOL=,2;+CPOL?", "+CPOL", //to make sure <oper> is numeric type in reponse.
+ TCORE_AT_COMMAND_TYPE_MULTILINE,
+ TCORE_PENDING_PRIORITY_DEFAULT,
+ NULL,
+ on_response_imc_network_get_preferred_plmn, resp_cb_data,
+ on_send_imc_request, NULL,
+ 0, NULL, NULL);
+
+ IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Get preferred plmn");
+ return ret;
+}
+
+/*
+ * Operation - set network mode
+ * Request -
+ * AT-Command: AT+XRAT=<AcT> [, <PreferredAct>]
+ * where
+ * <AcT> indicates the radio access technology and may be
+ * 0 GSM single mode
+ * 1 GSM / UMTS Dual mode
+ * 2 UTRAN (UMTS)
+ * 3-7 Reserved for future use.
+ * 8 This option is to swap the RAT mode between the two stacks. Example: If Stack1 is in GSM mode and
+ * Stack2 is in UMTS mode, this will configure Stack1 in UMTS mode and Stack2 in GSM mode.
+ * Note : <Act> = 8 is used only for dual sim configuration. In this case < PreferredAct > is ignored
+ * <PreferredAct>
+ * This parameter is used for network registration in case of <AcT>=1.
+ * 0 RAT GSM
+ * 2 RAT UMTS
+ * Response -
+ * Success: (No result)
+ * OK
+ * Failure:
+ * +CME ERROR: <error>
+ */
+static TelReturn imc_network_set_mode(CoreObject *co, TelNetworkMode mode,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ ImcRespCbData *resp_cb_data;
+ TelReturn ret = TEL_RETURN_INVALID_PARAMETER;
+ int act;
+ gchar *at_cmd;
+
+ switch(mode) {
+ case TEL_NETWORK_MODE_AUTO:
+ act = 1;
+ break;
+ case TEL_NETWORK_MODE_2G:
+ act = 0;
+ break;
+ case TEL_NETWORK_MODE_3G:
+ act = 2;
+ break;
+ case TEL_NETWORK_MODE_LTE:
+ default:
+ err("Unsupported mode");
+ return ret;
+ }
+
+ if (act == 1)
+ /* AT-Command */
+ at_cmd = g_strdup_printf("AT+XRAT=%d,2", act); //PreferredAct is UMTS
+ else
+ /* AT-Command */
+ at_cmd = g_strdup_printf("AT+XRAT=%d", act);
+
+ /* Response callback data */
+ resp_cb_data = imc_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_imc_network_default, resp_cb_data,
+ on_send_imc_request, NULL,
+ 0, NULL, NULL);
+ IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Set network mode");
+ g_free(at_cmd);
+ return ret;
+}
+
+/*
+ * Operation - get network mode
+ * Request -
+ * AT-Command: AT+XRAT?
+ *
+ * Response -
+ * Success: (Single line)
+ * +XRAT : <Act>,<PreferredAct>
+ * <AcT> indicates the radio access technology and may be
+ * 0 GSM single mode
+ * 1 GSM / UMTS Dual mode
+ * 2 UTRAN (UMTS)
+ * 3-7 Reserved for future use.
+ * 8 This option is to swap the RAT mode between the two stacks. Example: If Stack1 is in GSM mode and
+ * Stack2 is in UMTS mode, this will configure Stack1 in UMTS mode and Stack2 in GSM mode.
+ * Note : <Act> = 8 is used only for dual sim configuration. In this case < PreferredAct > is ignored
+ * <PreferredAct>
+ * This parameter is used for network registration in case of <AcT>=1.
+ * 0 RAT GSM
+ * 2 RAT UMTS
+ * OK
+ * Failure:
+ * +CME ERROR: <error>
+ */
+
+static TelReturn imc_network_get_mode(CoreObject *co,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ ImcRespCbData *resp_cb_data;
+ TelReturn ret;
+ dbg("entry");
+
+ /* Response callback data */
+ resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
+
+ /* Send Request to modem */
+ ret = tcore_at_prepare_and_send_request(co,
+ "AT+XRAT?", "+XRAT",
+ TCORE_AT_COMMAND_TYPE_SINGLELINE,
+ TCORE_PENDING_PRIORITY_DEFAULT,
+ NULL,
+ on_response_imc_network_get_mode, resp_cb_data,
+ on_send_imc_request, NULL,
+ 0, NULL, NULL);
+
+ IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Get network mode");
+ return ret;
+}
+
+static TelReturn imc_network_get_neighboring_cell_info(CoreObject *co,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ /* TODO*/
+ dbg("entry");
+ return TEL_RETURN_OPERATION_NOT_SUPPORTED;
+}
+
+/* Network Operations */
+static TcoreNetworkOps imc_network_ops = {
+ .get_identity_info = imc_network_get_identity_info,
+ .search = imc_network_search,
+ .cancel_search = imc_network_cancel_search,
+ .select_automatic = imc_network_select_automatic,
+ .select_manual = imc_network_select_manual,
+ .get_selection_mode = imc_network_get_selection_mode,
+ .set_preferred_plmn = imc_network_set_preferred_plmn,
+ .get_preferred_plmn = imc_network_get_preferred_plmn,
+ .set_mode = imc_network_set_mode,
+ .get_mode = imc_network_get_mode,
+ .get_neighboring_cell_info = imc_network_get_neighboring_cell_info
+};
+
+gboolean imc_network_init(TcorePlugin *p, CoreObject *co)
+{
+ dbg("Enter");
+
+ /* Set operations */
+ tcore_network_set_ops(co, &imc_network_ops);
+
+ /* Add Callbacks */
+ tcore_object_add_callback(co, "+CREG", on_notification_imc_cs_network_info, NULL);
+ tcore_object_add_callback(co, "+CGREG", on_notification_imc_ps_network_info, NULL);
+ tcore_object_add_callback(co, "+XNITZINFO", on_notification_imc_network_time_info, NULL);
+ tcore_object_add_callback(co, "+XCIEV", on_notification_imc_network_rssi, NULL);
+
+ /*
+ * Add Hooks - Request and Notification
+ */
+ tcore_plugin_add_request_hook(p,
+ TCORE_COMMAND_MODEM_SET_FLIGHTMODE,
+ on_hook_imc_set_flight_mode, NULL);
+ tcore_plugin_add_notification_hook(p,
+ TCORE_NOTIFICATION_SIM_STATUS,
+ on_hook_imc_sim_status, co);
+
+ //_insert_mcc_mnc_oper_list(cp, co_network);
+
+ dbg("Exit");
+ return TRUE;
+}
+
+void imc_network_exit(TcorePlugin *p, CoreObject *co)
+{
+ dbg("Exit");
+}
--- /dev/null
+/*
+ * tel-plugin-imc
+ *
+ * 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_phonebook.h>
+#include <co_sim.h>
+
+#include "imc_phonebook.h"
+#include "imc_common.h"
+
+typedef struct {
+ GSList *used_index_fdn;
+ gboolean used_index_fdn_valid;
+
+ GSList *used_index_adn;
+ gboolean used_index_adn_valid;
+
+ GSList *used_index_sdn;
+ gboolean used_index_sdn_valid;
+
+ GSList *used_index_usim;
+ gboolean used_index_usim_valid;
+} PrivateInfo;
+
+static gboolean __imc_phonebook_get_sim_type(CoreObject *co_pb,
+ TelSimCardType *sim_type)
+{
+ TcorePlugin *plugin;
+ CoreObject *co_sim;
+ tcore_check_return_value_assert(co_pb != NULL, FALSE);
+ tcore_check_return_value_assert(sim_type != NULL, FALSE);
+
+ plugin = tcore_object_ref_plugin(co_pb);
+ co_sim = tcore_plugin_ref_core_object(plugin, CORE_OBJECT_TYPE_SIM);
+ return tcore_sim_get_type(co_sim, sim_type);
+}
+
+static gboolean __imc_phonebook_get_pb_type_str(TelPbType pb_type,
+ gchar **req_type_str)
+{
+ tcore_check_return_value_assert(req_type_str != NULL, FALSE);
+
+ switch (pb_type) {
+ case TEL_PB_FDN:
+ *req_type_str = g_strdup("FD");
+ break;
+ case TEL_PB_ADN:
+ case TEL_PB_USIM:
+ *req_type_str = g_strdup("SM");
+ break;
+ case TEL_PB_SDN:
+ *req_type_str = g_strdup("SN");
+ break;
+ }
+
+ return TRUE;
+}
+
+static gboolean __imc_phonebook_check_and_select_type(CoreObject *co,
+ TelPbType req_type, gchar **set_pb_cmd)
+{
+ TelPbList *support_list;
+ TelPbType current_type;
+
+ /* Check whether pb_type is supported or not */
+ tcore_phonebook_get_support_list(co, &support_list);
+ if ((req_type == TEL_PB_FDN && support_list->fdn == FALSE)
+ || (req_type == TEL_PB_ADN && support_list->adn == FALSE)
+ || (req_type == TEL_PB_SDN && support_list->sdn == FALSE)
+ || (req_type == TEL_PB_USIM && support_list->usim == FALSE)) {
+ err("Not supported pb_type");
+ g_free(support_list);
+ return FALSE;
+ }
+ g_free(support_list);
+
+ /* Check Current type & Request type */
+ tcore_phonebook_get_selected_type(co, ¤t_type);
+ if (current_type != req_type) {
+ gchar *req_type_str = NULL;
+ __imc_phonebook_get_pb_type_str(req_type, &req_type_str);
+ dbg("Add AT-Command to change [%s] Type", req_type_str);
+ /* Select Phonebook type */
+ *set_pb_cmd = g_strdup_printf("AT+CPBS=\"%s\";", req_type_str);
+ } else {
+ *set_pb_cmd = g_strdup_printf("AT");
+ }
+
+ return TRUE;
+}
+
+static gboolean __imc_phonebook_get_index_list_by_type(CoreObject *co,
+ TelPbType pb_type, GSList **list)
+{
+ PrivateInfo *private_info = tcore_object_ref_user_data(co);
+ tcore_check_return_value_assert(private_info != NULL, FALSE);
+
+ switch (pb_type) {
+ case TEL_PB_FDN:
+ if (private_info->used_index_fdn_valid != TRUE)
+ return FALSE;
+ *list = private_info->used_index_fdn;
+ break;
+ case TEL_PB_ADN:
+ if (private_info->used_index_adn_valid != TRUE)
+ return FALSE;
+ *list = private_info->used_index_adn;
+ break;
+ case TEL_PB_SDN:
+ if (private_info->used_index_sdn_valid != TRUE)
+ return FALSE;
+ *list = private_info->used_index_sdn;
+ break;
+ case TEL_PB_USIM:
+ if (private_info->used_index_usim_valid != TRUE)
+ return FALSE;
+ *list = private_info->used_index_usim;
+ break;
+ }
+
+ return TRUE;
+}
+
+static void __imc_phonebook_check_used_index(CoreObject *co,
+ TelPbType pb_type, guint req_index, guint *used_index)
+{
+ GSList *list = NULL;
+
+ /* Get used_index list by req_type */
+ if (__imc_phonebook_get_index_list_by_type(co, pb_type, &list) != TRUE) {
+ err("used_index list is NOT valid");
+ *used_index = req_index;
+ return;
+ }
+
+ /* Use first used_index in case req_index is not used */
+ *used_index = (guint)g_slist_nth_data(list, 0);
+ while (list) {
+ if ((guint)list->data == req_index) {
+ /* req_index is equal to one of used_index */
+ *used_index = req_index;
+ return;
+ }
+ list = g_slist_next(list);
+ }
+}
+
+static gint __imc_phonebook_compare_index(gconstpointer a, gconstpointer b)
+{
+ guint index1 = (guint)a;
+ guint index2 = (guint)b;
+
+ return index1 - index2;
+}
+
+static void on_response_imc_phonebook_get_used_index(TcorePending *p,
+ guint data_len, const void *data, void *user_data)
+{
+ const TcoreAtResponse *at_resp = data;
+ ImcRespCbData *resp_cb_data = user_data;
+ CoreObject *co = tcore_pending_ref_core_object(p);
+ tcore_check_return_assert(at_resp != NULL);
+ tcore_check_return_assert(resp_cb_data != NULL);
+
+ dbg("Entry");
+
+ if (at_resp->success != TRUE) {
+ err("Response NOK");
+ return;
+ }
+
+ dbg("Response OK");
+
+ if (at_resp->lines == NULL) {
+ err("at_resp->lines is NULL");
+ } else {
+ GSList *lines = at_resp->lines;
+ TelPbType *req_type;
+ GSList **list = NULL;
+ PrivateInfo *private_info = tcore_object_ref_user_data(co);
+ tcore_check_return_assert(private_info != NULL);
+
+ /* Select used_index_list by req_type */
+ req_type = (TelPbType *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
+ switch (*req_type) {
+ case TEL_PB_FDN:
+ list = &private_info->used_index_fdn;
+ private_info->used_index_fdn_valid = TRUE;
+ break;
+ case TEL_PB_ADN:
+ list = &private_info->used_index_adn;
+ private_info->used_index_adn_valid = TRUE;
+ break;
+ case TEL_PB_SDN:
+ list = &private_info->used_index_sdn;
+ private_info->used_index_sdn_valid = TRUE;
+ break;
+ case TEL_PB_USIM:
+ list = &private_info->used_index_usim;
+ private_info->used_index_usim_valid = TRUE;
+ break;
+ }
+
+ while (lines) {
+ const gchar *line = lines->data;
+ GSList *tokens = NULL;
+ gchar *temp;
+
+ dbg("Line: [%s]", line);
+
+ tokens = tcore_at_tok_new(line);
+ if (tokens == NULL) {
+ err("tokens is NULL");
+ return;
+ }
+
+ /* Get only used_index */
+ temp = g_slist_nth_data(tokens, 0);
+ if (temp) {
+ /* Insert used_index in PrivateInfo sorted in ascending */
+ *list = g_slist_insert_sorted(*list, (gpointer)atoi(temp),
+ __imc_phonebook_compare_index);
+ }
+ tcore_at_tok_free(tokens);
+
+ /* Get next lines */
+ lines = g_slist_next(lines);
+ }
+ dbg("pb_type: [%d], used_index Length: [%d]",
+ *req_type, g_slist_length(*list));
+ }
+}
+
+static void __imc_phonebook_get_used_index(CoreObject *co, TelPbType pb_type, guint max_index)
+{
+ gchar *at_cmd;
+ ImcRespCbData *resp_cb_data;
+ TelReturn ret = TEL_RETURN_FAILURE;
+
+ dbg("Entry");
+
+ /* AT-Command */
+ at_cmd = g_strdup_printf("AT+CPBR=1,%d", max_index);
+
+ /* Response callback data */
+ resp_cb_data = imc_create_resp_cb_data(NULL, NULL,
+ (void *)&pb_type, sizeof(TelPbType));
+
+ /* Send Request to Modem */
+ ret = tcore_at_prepare_and_send_request(co,
+ at_cmd, "+CPBR",
+ TCORE_AT_COMMAND_TYPE_MULTILINE,
+ TCORE_PENDING_PRIORITY_DEFAULT,
+ NULL,
+ on_response_imc_phonebook_get_used_index, resp_cb_data,
+ on_send_imc_request, NULL,
+ 0, NULL, NULL);
+ IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Get Used Index");
+
+ /* Free resources */
+ g_free(at_cmd);
+}
+
+static void on_response_imc_phonebook_get_support_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);
+ TelPbInitInfo init_info = {0, };
+ tcore_check_return_assert(at_resp != NULL);
+
+ dbg("Entry");
+
+ if (at_resp->success != TRUE) {
+ err("Response NOK");
+ return;
+ }
+
+ dbg("Response OK");
+
+ if (at_resp->lines == NULL) {
+ err("at_resp->lines is NULL");
+ return;
+ } else {
+ const gchar *line = (const gchar *)at_resp->lines->data;
+ GSList *tokens = NULL;
+ gchar *pb_type_list;
+ gchar *pb_type;
+
+ dbg("Line: [%s]", line);
+
+ tokens = tcore_at_tok_new(line);
+ if (tokens == NULL) {
+ err("tokens is NULL");
+ return;
+ }
+
+ pb_type_list = g_slist_nth_data(tokens, 0);
+ pb_type = strtok(pb_type_list, "(,)");
+ while (pb_type) {
+ pb_type = tcore_at_tok_extract(pb_type);
+ if (g_strcmp0(pb_type, "FD") == 0) {
+ init_info.pb_list.fdn = TRUE;
+ } else if (g_strcmp0(pb_type, "SN") == 0) {
+ init_info.pb_list.sdn = TRUE;
+ } else if (g_strcmp0(pb_type, "SM") == 0) {
+ TelSimCardType sim_type;
+ __imc_phonebook_get_sim_type(co, &sim_type);
+ if (sim_type == TEL_SIM_CARD_TYPE_USIM)
+ init_info.pb_list.usim = TRUE;
+ else
+ init_info.pb_list.adn = TRUE;
+ }
+ g_free(pb_type);
+ /* Get Next pb_type */
+ pb_type = strtok(NULL, "(,)");
+ }
+ tcore_at_tok_free(tokens);
+ }
+
+ dbg("FDN: [%s], ADN: [%s], SDN: [%s], USIM: [%s]",
+ init_info.pb_list.fdn ? "TRUE" : "FALSE",
+ init_info.pb_list.adn ? "TRUE" : "FALSE",
+ init_info.pb_list.sdn ? "TRUE" : "FALSE",
+ init_info.pb_list.usim ? "TRUE" : "FALSE");
+
+ init_info.init_status = TRUE;
+ tcore_phonebook_set_support_list(co, &init_info.pb_list);
+ tcore_phonebook_set_status(co, init_info.init_status);
+
+ /* Send Notification */
+ tcore_object_send_notification(co,
+ TCORE_NOTIFICATION_PHONEBOOK_STATUS,
+ sizeof(TelPbInitInfo), &init_info);
+}
+
+/*
+ * Operation - get_support_list
+ *
+ * Request -
+ * AT-Command: AT+CPBS=?
+ *
+ * Response -
+ * Success: (Single line)
+ * (list of supported <storage>s)
+ * OK
+ * Failure:
+ * +CME ERROR: <error>
+ */
+static void __imc_phonebook_get_support_list(CoreObject *co)
+{
+ TelReturn ret;
+
+ dbg("Entry");
+
+ /* Send Request to Modem */
+ ret = tcore_at_prepare_and_send_request(co,
+ "AT+CPBS=?", "+CPBS",
+ TCORE_AT_COMMAND_TYPE_SINGLELINE,
+ TCORE_PENDING_PRIORITY_DEFAULT,
+ NULL,
+ on_response_imc_phonebook_get_support_list, NULL,
+ on_send_imc_request, NULL,
+ 0, NULL, NULL);
+ IMC_CHECK_REQUEST_RET(ret, NULL, "Get Support List");
+}
+
+static gboolean on_notification_imc_phonebook_status(CoreObject *co,
+ const void *event_info, void *user_data)
+{
+ dbg("Phonebook Init Completed");
+
+ /* Get Supported list */
+ __imc_phonebook_get_support_list(co);
+
+ return TRUE;
+}
+
+static void on_response_imc_phonebook_get_info(TcorePending *p,
+ guint data_len, const void *data, void *user_data)
+{
+ const TcoreAtResponse *at_resp = data;
+ ImcRespCbData *resp_cb_data = user_data;
+ CoreObject *co = tcore_pending_ref_core_object(p);
+ TelPbResult result = TEL_PB_RESULT_FAILURE;
+ TelPbInfo pb_info = {0, };
+ tcore_check_return_assert(at_resp != NULL);
+ tcore_check_return_assert(resp_cb_data != NULL);
+
+ dbg("Entry");
+
+ if (at_resp->success != TRUE) {
+ err("Response NOK");
+ goto out;
+ }
+
+ dbg("Response OK");
+
+ if (at_resp->lines == NULL) {
+ err("at_resp->lines is NULL");
+ } else {
+ GSList *lines = at_resp->lines;
+ const gchar *line;
+ GSList *tokens = NULL;
+ gchar *temp;
+ gint used = 0, total = 0;
+ gint nlen = 0, tlen = 0;
+ TelPbType *req_type;
+ PrivateInfo *private_info;
+
+ /* +CPBS: <storage>[,<used>][,total] */
+ line = g_slist_nth_data(lines, 0);
+ dbg("First Line: [%s]", line);
+ tokens = tcore_at_tok_new(line);
+ if (tokens == NULL) {
+ err("tokens is NULL");
+ goto out;
+ }
+
+ /* Get used_count */
+ temp = g_slist_nth_data(tokens, 1);
+ if (temp)
+ used = atoi(temp);
+ /* Get total_count */
+ temp = g_slist_nth_data(tokens, 2);
+ if (temp)
+ total = atoi(temp);
+
+ tcore_at_tok_free(tokens);
+
+ /* +CPBF: [<nlength>],[<tlength>],[<glength>],[<slength>],[<elength>] */
+ line = g_slist_nth_data(lines, 1);
+ dbg("Second Line: [%s]", line);
+ tokens = tcore_at_tok_new(line);
+ if (tokens == NULL) {
+ err("tokens is NULL");
+ goto out;
+ }
+
+ /* Get number Length */
+ temp = g_slist_nth_data(tokens, 0);
+ if (temp)
+ nlen = atoi(temp);
+ /* Get text Length */
+ temp = g_slist_nth_data(tokens, 1);
+ if (temp)
+ tlen = atoi(temp);
+
+ /* Set Response Data */
+ req_type = (TelPbType *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
+ pb_info.pb_type = *req_type;
+ if (*req_type == TEL_PB_USIM) {
+ pb_info.info_u.usim.max_count = total;
+ pb_info.info_u.usim.used_count = used;
+ pb_info.info_u.usim.max_num_len = nlen;
+ pb_info.info_u.usim.max_text_len = tlen;
+ /* Get group name Length */
+ temp = g_slist_nth_data(tokens, 2);
+ if (temp)
+ pb_info.info_u.usim.max_gas_len = atoi(temp);
+ /* Get second name Length */
+ temp = g_slist_nth_data(tokens, 3);
+ if (temp)
+ pb_info.info_u.usim.max_sne_len = atoi(temp);
+ /* Get email Length */
+ temp = g_slist_nth_data(tokens, 4);
+ if (temp)
+ pb_info.info_u.usim.max_email_len = atoi(temp);
+ } else {
+ pb_info.info_u.sim.max_count = total;
+ pb_info.info_u.sim.used_count = used;
+ pb_info.info_u.sim.max_num_len = nlen;
+ pb_info.info_u.sim.max_text_len = tlen;
+ }
+
+ /* Set Request type in PrivateObject */
+ tcore_phonebook_set_selected_type(co, *req_type);
+ result = TEL_PB_RESULT_SUCCESS;
+ tcore_at_tok_free(tokens);
+
+ /* If don't have valid used_index, get used_index by req_type */
+ private_info = tcore_object_ref_user_data(co);
+ if ((*req_type == TEL_PB_FDN && private_info->used_index_fdn_valid == FALSE)
+ || (*req_type == TEL_PB_ADN && private_info->used_index_adn_valid == FALSE)
+ || (*req_type == TEL_PB_SDN && private_info->used_index_sdn_valid == FALSE)
+ || (*req_type == TEL_PB_USIM && private_info->used_index_usim_valid == FALSE))
+ __imc_phonebook_get_used_index(co, *req_type, total);
+ }
+
+out:
+ /* Invoke callback */
+ if (resp_cb_data->cb)
+ resp_cb_data->cb(co, (gint)result, &pb_info, resp_cb_data->cb_data);
+
+ /* Free callback data */
+ imc_destroy_resp_cb_data(resp_cb_data);
+}
+
+static void on_response_imc_phonebook_read_record(TcorePending *p,
+ guint data_len, const void *data, void *user_data)
+{
+ const TcoreAtResponse *at_resp = data;
+ ImcRespCbData *resp_cb_data = user_data;
+ CoreObject *co = tcore_pending_ref_core_object(p);
+ TelPbResult result = TEL_PB_RESULT_FAILURE;
+ GSList *tokens = NULL;
+ gchar *index = NULL, *number = NULL, *name = NULL;
+ TelPbReadRecord read_record = {0, };
+ tcore_check_return_assert(at_resp != NULL);
+ tcore_check_return_assert(resp_cb_data != NULL);
+
+ dbg("Entry");
+
+ if (at_resp->success != TRUE) {
+ err("Response NOK");
+ goto out;
+ }
+
+ dbg("Response OK");
+
+ if (at_resp->lines == NULL) {
+ err("at_resp->lines is NULL");
+ } else {
+ const gchar *line = (const gchar *)at_resp->lines->data;
+ TelPbType *req_type;
+ GSList *list = NULL;
+
+ dbg("Line: [%s]", line);
+
+ tokens = tcore_at_tok_new(line);
+ if (tokens == NULL) {
+ err("tokens is NULL");
+ goto out;
+ }
+
+ /* Get index */
+ index = g_slist_nth_data(tokens, 0);
+ if (index == NULL) {
+ err("No index");
+ goto out;
+ }
+
+ /* Get number */
+ number = g_slist_nth_data(tokens, 1);
+ if (number) {
+ number = tcore_at_tok_extract(number);
+ } else {
+ err("No number");
+ goto out;
+ }
+
+ /* Get name */
+ name = g_slist_nth_data(tokens, 3);
+ if (name) {
+ name = tcore_at_tok_extract(name);
+ } else {
+ err("No name");
+ goto out;
+ }
+
+ /* Set Request type in PrivateObject */
+ req_type = (TelPbType *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
+ tcore_phonebook_set_selected_type(co, *req_type);
+
+ /* Set Response Data */
+ read_record.index = atoi(index);
+ read_record.pb_type = *req_type;
+
+ /* Get used_index list by req_type */
+ if (__imc_phonebook_get_index_list_by_type(co, *req_type, &list) == TRUE) {
+ while (list) {
+ if ((guint)list->data == read_record.index) {
+ if ((list = g_slist_next(list)) != NULL) {
+ /* If exist, set next_index */
+ read_record.next_index = (guint)list->data;
+ dbg("next_index is [%u]", read_record.next_index);
+ } else {
+ /* read_record.index is the end of used_index */
+ read_record.next_index = -1;
+ dbg("End of used_index");
+ }
+ break;
+ }
+ list = g_slist_next(list);
+ }
+ } else {
+ /* No PrivateInfo */
+ read_record.next_index = 0;
+ }
+
+ if (*req_type == TEL_PB_USIM) {
+ gchar *hidden, *group, *anr, *sne, *email;
+
+ /* Get Name and Number */
+ g_strlcpy(read_record.rec_u.usim.name, name, TEL_PB_TEXT_MAX_LEN + 1);
+ g_strlcpy(read_record.rec_u.usim.number, number, TEL_PB_NUMBER_MAX_LEN + 1);
+
+ /* Get Hidden */
+ hidden = g_slist_nth_data(tokens, 4);
+ if (hidden) {
+ read_record.rec_u.usim.hidden = atoi(hidden);
+ }
+
+ /* Get Group name */
+ group = g_slist_nth_data(tokens, 5);
+ if (group) {
+ group = tcore_at_tok_extract(group);
+ g_strlcpy(read_record.rec_u.usim.grp_name, group, TEL_PB_TEXT_MAX_LEN + 1);
+ g_free(group);
+ }
+
+ /* Get ANR */
+ anr = g_slist_nth_data(tokens, 6);
+ if (anr) {
+ anr = tcore_at_tok_extract(anr);
+ if (strlen(anr)) {
+ g_strlcpy(read_record.rec_u.usim.anr[0].number,
+ anr, TEL_PB_NUMBER_MAX_LEN + 1);
+ read_record.rec_u.usim.anr_count = 1;
+ }
+ g_free(anr);
+ }
+
+ /* Get SNE */
+ sne = g_slist_nth_data(tokens, 8);
+ if (sne) {
+ sne = tcore_at_tok_extract(sne);
+ g_strlcpy(read_record.rec_u.usim.sne, sne, TEL_PB_TEXT_MAX_LEN + 1);
+ g_free(sne);
+ }
+
+ /* Get email */
+ email = g_slist_nth_data(tokens, 9);
+ if (email) {
+ email = tcore_at_tok_extract(email);
+ if (strlen(email)) {
+ g_strlcpy(read_record.rec_u.usim.email[0], email, TEL_PB_TEXT_MAX_LEN + 1);
+ read_record.rec_u.usim.email_count = 1;
+ }
+ g_free(email);
+ }
+ }
+ else {
+ /* Get Name and Number */
+ g_strlcpy(read_record.rec_u.sim.name, name, TEL_PB_TEXT_MAX_LEN + 1);
+ g_strlcpy(read_record.rec_u.sim.number, number, TEL_PB_NUMBER_MAX_LEN + 1);
+ }
+
+ result = TEL_PB_RESULT_SUCCESS;
+ }
+
+out:
+ /* Invoke callback */
+ if (resp_cb_data->cb)
+ resp_cb_data->cb(co, (gint)result, &read_record, resp_cb_data->cb_data);
+
+ /* Free callback data */
+ imc_destroy_resp_cb_data(resp_cb_data);
+
+ /* Free resources */
+ tcore_at_tok_free(tokens);
+ g_free(number);
+ g_free(name);
+}
+
+static void on_response_imc_phonebook_update_record(TcorePending *p,
+ guint data_len, const void *data, void *user_data)
+{
+ const TcoreAtResponse *at_resp = data;
+ ImcRespCbData *resp_cb_data = user_data;
+ CoreObject *co = tcore_pending_ref_core_object(p);
+ TelPbUpdateRecord *req_data;
+ TelPbResult result = TEL_PB_RESULT_FAILURE;
+ GSList *list = NULL;
+ tcore_check_return_assert(at_resp != NULL);
+ tcore_check_return_assert(resp_cb_data != NULL);
+
+ dbg("Entry");
+
+ if (at_resp->success != TRUE) {
+ err("Response NOK");
+ goto out;
+ }
+
+ dbg("Response OK");
+ result = TEL_PB_RESULT_SUCCESS;
+
+ /* Set Request type in PrivateObject */
+ req_data = (TelPbUpdateRecord *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
+ tcore_phonebook_set_selected_type(co, req_data->pb_type);
+
+ /* Get used_index list by req_type */
+ if (__imc_phonebook_get_index_list_by_type(co,
+ req_data->pb_type, &list) != TRUE) {
+ err("used_index list is NOT valid");
+ } else {
+ list = g_slist_insert_sorted(list, (gpointer)req_data->index,
+ __imc_phonebook_compare_index);
+ }
+
+out:
+ /* Invoke callback */
+ if (resp_cb_data->cb)
+ resp_cb_data->cb(co, (gint)result, NULL, resp_cb_data->cb_data);
+
+ /* Free callback data */
+ imc_destroy_resp_cb_data(resp_cb_data);
+}
+
+static void on_response_imc_phonebook_delete_record(TcorePending *p,
+ guint data_len, const void *data, void *user_data)
+{
+ const TcoreAtResponse *at_resp = data;
+ ImcRespCbData *resp_cb_data = user_data;
+ CoreObject *co = tcore_pending_ref_core_object(p);
+ TelPbRecordInfo *req_data;
+ GSList *list = NULL;
+ TelPbResult result = TEL_PB_RESULT_FAILURE;
+ tcore_check_return_assert(at_resp != NULL);
+ tcore_check_return_assert(resp_cb_data != NULL);
+
+ dbg("Entry");
+
+ if (at_resp->success != TRUE) {
+ err("Response NOK");
+ goto out;
+ }
+
+ dbg("Response OK");
+ result = TEL_PB_RESULT_SUCCESS;
+
+ /* Set Request type in PrivateObject */
+ req_data = (TelPbRecordInfo *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
+ tcore_phonebook_set_selected_type(co, req_data->pb_type);
+
+ /* Get used_index list by req_type */
+ if (__imc_phonebook_get_index_list_by_type(co,
+ req_data->pb_type, &list) != TRUE) {
+ err("used_index list is NOT valid");
+ } else {
+ list = g_slist_remove(list, (gconstpointer)req_data->index);
+ dbg("Remove index: [%u]", req_data->index);
+ }
+
+out:
+ /* Invoke callback */
+ if (resp_cb_data->cb)
+ resp_cb_data->cb(co, (gint)result, NULL, resp_cb_data->cb_data);
+
+ /* Free callback data */
+ imc_destroy_resp_cb_data(resp_cb_data);
+}
+
+/*
+ * Operation - get_info
+ *
+ * Request -
+ * AT-Command: AT+CPBS?;+CPBF=?
+ *
+ * Response -
+ * Success: (Multi line)
+ * +CPBS: <storage>[,<used>][,total]
+ * +CPBF: [<nlength>],[<tlength>],[<glength>],[<slength>],[<elength>]
+ * OK
+ * where,
+ * <nlength> Maximum length of field <number>
+ * <tlength> Maximum length of field <text>
+ * <glength> Maximum length of field <group>
+ * <slength> Maximum length of field <secondtext>
+ * <elength> Maximum length of field <email>
+ *
+ * Failure:
+ * +CME ERROR: <error>
+ */
+static TelReturn imc_phonebook_get_info(CoreObject *co,
+ const TelPbType pb_type,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ gchar *at_cmd;
+ gchar *set_pb_cmd;
+ ImcRespCbData *resp_cb_data;
+ TelReturn ret = TEL_RETURN_FAILURE;
+
+ dbg("Entry");
+
+ /* Check whether pb_type is supported or not, and Select pb_type */
+ if (__imc_phonebook_check_and_select_type(co, pb_type, &set_pb_cmd) != TRUE) {
+ return ret;
+ }
+
+ /* AT-Command */
+ at_cmd = g_strdup_printf("%s+CPBS?;+CPBF=?", set_pb_cmd);
+
+ /* Response callback data */
+ resp_cb_data = imc_create_resp_cb_data(cb, cb_data,
+ (void *)&pb_type, sizeof(TelPbType));
+
+ /* Send Request to Modem */
+ ret = tcore_at_prepare_and_send_request(co,
+ at_cmd, "+CPB",
+ TCORE_AT_COMMAND_TYPE_MULTILINE,
+ TCORE_PENDING_PRIORITY_DEFAULT,
+ NULL,
+ on_response_imc_phonebook_get_info, resp_cb_data,
+ on_send_imc_request, NULL,
+ 0, NULL, NULL);
+ IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Get Info");
+
+ /* Free resources */
+ g_free(at_cmd);
+ g_free(set_pb_cmd);
+
+ return ret;
+}
+
+/*
+ * Operation - read_record
+ *
+ * Request -
+ * AT-Command: AT+CPBR=<index>
+ * where,
+ * <index>
+ * 1 Integer type values in range of location numbers of phonebook memory
+ * ...
+ *
+ * Response -
+ * Success: (Single line);
+ * +CPBR: <index>,<number>,<type>,<text>[,<hidden>][,<group>]
+ * [,<adnumber>][,<adtype>][,<secondtext>][,<email>]]
+ * OK
+ * where,
+ * <number> String type phone number of format <type>
+ * <type> Type of address octet in integer format
+ * <text> String type field of maximum length <tlength>
+ * <hidden> Indicates if the entry is hidden or not – only available,
+ * if a UICC with an active USIM application is present
+ * 0 Phonebook entry not hidden
+ * 1 Phonebook entry hidden
+ * <group> String type field of maximum length <glength>
+ * <adnumber> String type phone number of format <adtype>
+ * <adtype> Type of address octet in integer format
+ * <secondtext> String type field of maximum length <slength>
+ * <email> String type field of maximum length <elength>
+ *
+ * Failure:
+ * +CME ERROR: <error>
+ */
+static TelReturn imc_phonebook_read_record(CoreObject *co,
+ const TelPbRecordInfo *record,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ gchar *at_cmd;
+ gchar *set_pb_cmd;
+ ImcRespCbData *resp_cb_data;
+ guint used_index = 0;
+ TelReturn ret = TEL_RETURN_FAILURE;
+
+ dbg("Entry");
+
+ /* Check whether pb_type is supported or not, and Select pb_type */
+ if (__imc_phonebook_check_and_select_type(co, record->pb_type, &set_pb_cmd) != TRUE) {
+ return ret;
+ }
+
+ /* Check whether index is used or not */
+ __imc_phonebook_check_used_index(co, record->pb_type, record->index, &used_index);
+
+ /* AT-Command */
+ at_cmd = g_strdup_printf("%s+CPBR=%u", set_pb_cmd, used_index);
+
+ /* Response callback data */
+ resp_cb_data = imc_create_resp_cb_data(cb, cb_data,
+ (void *)&(record->pb_type), sizeof(TelPbType));
+
+ /* Send Request to Modem */
+ ret = tcore_at_prepare_and_send_request(co,
+ at_cmd, "+CPBR",
+ TCORE_AT_COMMAND_TYPE_SINGLELINE,
+ TCORE_PENDING_PRIORITY_DEFAULT,
+ NULL,
+ on_response_imc_phonebook_read_record, resp_cb_data,
+ on_send_imc_request, NULL,
+ 0, NULL, NULL);
+ IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Read Record");
+
+ /* Free resources */
+ g_free(at_cmd);
+ g_free(set_pb_cmd);
+
+ return ret;
+}
+
+/*
+ * Operation - update_record
+ *
+ * Request -
+ * AT-Command: AT+CPBW=[<index>][,<number>[,<type>[,<text>[,<group>[,<adnumber>
+ * [,<adtype>[,<secondtext>[,<email>[,<hidden>]]]]]]]]]
+ * where,
+ * ... same read_record Operation
+ *
+ * Response -
+ * Success: (No Result)
+ * OK
+ * Failure:
+ * +CME ERROR: <error>
+ */
+static TelReturn imc_phonebook_update_record(CoreObject *co,
+ const TelPbUpdateRecord *req_data,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ gchar *at_cmd;
+ gchar *set_pb_cmd;
+ ImcRespCbData *resp_cb_data;
+ TelReturn ret = TEL_RETURN_FAILURE;
+
+ dbg("Entry");
+
+ /* Check whether pb_type is supported or not, and Select pb_type */
+ if (__imc_phonebook_check_and_select_type(co, req_data->pb_type, &set_pb_cmd) != TRUE) {
+ return ret;
+ }
+
+ /* Set AT-Command according pb_type */
+ if (req_data->pb_type == TEL_PB_USIM) {
+ at_cmd = g_strdup_printf("%s+CPBW=%u,\"%s\",,\"%s\",\"%s\",\"%s\",,\"%s\",\"%s\",%d",
+ set_pb_cmd, req_data->index,
+ req_data->rec_u.usim.number, req_data->rec_u.usim.name,
+ req_data->rec_u.usim.grp_name, req_data->rec_u.usim.anr[0].number,
+ req_data->rec_u.usim.sne, req_data->rec_u.usim.email[0],
+ req_data->rec_u.usim.hidden);
+ } else {
+ at_cmd = g_strdup_printf("%s+CPBW=%u,\"%s\",,\"%s\"",
+ set_pb_cmd, req_data->index,
+ req_data->rec_u.sim.number,
+ req_data->rec_u.sim.name);
+ }
+
+ /* Response callback data */
+ resp_cb_data = imc_create_resp_cb_data(cb, cb_data,
+ (void *)req_data, sizeof(TelPbUpdateRecord));
+
+ /* 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_imc_phonebook_update_record, resp_cb_data,
+ on_send_imc_request, NULL,
+ 0, NULL, NULL);
+ IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Update Record");
+
+ /* Free resources */
+ g_free(at_cmd);
+ g_free(set_pb_cmd);
+
+ return ret;
+}
+
+/*
+ * Operation - delete_record
+ *
+ * Request -
+ * AT-Command: AT+CPBW=<index>
+ * where,
+ * <index>
+ * 1 Integer type values in range of location numbers of phonebook memory
+ * ...
+ *
+ * Response -
+ * Success: (No Result)
+ * OK
+ * Failure:
+ * +CME ERROR: <error>
+ */
+static TelReturn imc_phonebook_delete_record(CoreObject *co,
+ const TelPbRecordInfo *record,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ gchar *at_cmd;
+ gchar *set_pb_cmd;
+ ImcRespCbData *resp_cb_data;
+ TelReturn ret = TEL_RETURN_FAILURE;
+
+ dbg("Entry");
+
+ /* Check whether pb_type is supported or not, and Select pb_type */
+ if (__imc_phonebook_check_and_select_type(co, record->pb_type, &set_pb_cmd) != TRUE) {
+ return ret;
+ }
+
+ /* AT-Command */
+ at_cmd = g_strdup_printf("%s+CPBW=%u", set_pb_cmd, record->index);
+
+ /* Response callback data */
+ resp_cb_data = imc_create_resp_cb_data(cb, cb_data,
+ (void *)record, sizeof(TelPbRecordInfo));
+
+ /* 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_imc_phonebook_delete_record, resp_cb_data,
+ on_send_imc_request, NULL,
+ 0, NULL, NULL);
+ IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Delete Record");
+
+ /* Free resources */
+ g_free(at_cmd);
+ g_free(set_pb_cmd);
+
+ return ret;
+}
+
+/* Phonebook Operations */
+static TcorePbOps imc_phonebook_ops = {
+ .get_info = imc_phonebook_get_info,
+ .read_record = imc_phonebook_read_record,
+ .update_record = imc_phonebook_update_record,
+ .delete_record = imc_phonebook_delete_record,
+};
+
+gboolean imc_phonebook_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_phonebook_set_ops(co, &imc_phonebook_ops);
+
+ /* Add Callbacks */
+ tcore_object_add_callback(co, "+PBREADY", on_notification_imc_phonebook_status, NULL);
+
+ dbg("Exit");
+ return TRUE;
+}
+
+void imc_phonebook_exit(TcorePlugin *p, CoreObject *co)
+{
+ PrivateInfo *private_info;
+
+ private_info = tcore_object_ref_user_data(co);
+ tcore_check_return_assert(private_info != NULL);
+
+ /* Free PrivateInfo */
+ g_slist_free_full(private_info->used_index_fdn, g_free);
+ g_slist_free_full(private_info->used_index_adn, g_free);
+ g_slist_free_full(private_info->used_index_sdn, g_free);
+ g_slist_free_full(private_info->used_index_usim, g_free);
+ tcore_free(private_info);
+
+ dbg("Exit");
+}
--- /dev/null
+/*
+ * tel-plugin-imc
+ *
+ * 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 "imc_ps.h"
+#include "imc_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);
+
+ 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);
+
+}
+
+static TcoreHookReturn on_hook_imc_nw_registration_status(TcorePlugin *plugin,
+ TcoreNotification command, guint data_len, void *data, void *user_data)
+{
+ const TelNetworkRegStatusInfo *nw_reg_status = (TelNetworkRegStatusInfo *)data;
+ gboolean state = FALSE;
+
+ tcore_check_return_value(nw_reg_status != NULL,
+ TCORE_HOOK_RETURN_CONTINUE);
+
+
+ dbg("nw_reg_status->ps_status [%d]",nw_reg_status->ps_status);
+ dbg("nw_reg_status->cs_status [%d]",nw_reg_status->cs_status);
+
+ /* Setting if PS is online or not */
+ if(nw_reg_status->ps_status == TEL_NETWORK_REG_STATUS_REGISTERED ||
+ nw_reg_status->ps_status == TEL_NETWORK_REG_STATUS_ROAMING) {
+ /* Set PS is online */
+ state = TRUE;
+ }
+
+ dbg("PS online state [%d]", state);
+
+ /* Set Online state */
+ tcore_ps_set_online((CoreObject *)user_data, state);
+ return TCORE_HOOK_RETURN_CONTINUE;
+}
+
+/*
+ * Notification - GPRS event reporting
+ *
+ * Notification -
+ * +CGEV: NW DEACT <PDP_type>, <PDP_addr>, [<cid>]
+ * The network has forced a context deactivation. The <cid> that was used to activate the context is provided if
+ * known to the MT
+ */
+static gboolean on_notification_imc_ps_cgev(CoreObject *co_ps,
+ const void *data, void *user_data)
+{
+ GSList *tokens = NULL;
+ GSList *lines = (GSList *)data;
+ const gchar *line = lines->data;
+ gchar *noti_data;
+ guint context_id;
+ TcoreHal *hal;
+
+ dbg("Entry");
+
+ if (line == NULL) {
+ err("Ignore, No data present in notification received for CGEV");
+ return TRUE;
+ }
+
+ dbg("Lines->data :%s", line);
+
+ tokens = tcore_at_tok_new(line);
+ if (g_slist_length(tokens) != 3) {
+ err("Ignore, sufficient data not present for deactivation");
+ goto out;
+
+ }
+ noti_data = g_slist_nth_data(tokens, 0);
+
+ /* Only care about NW context deactivation */
+ if (g_str_has_prefix(noti_data, "NW DEACT") == FALSE) {
+ err("Ignore, only care about nw deactivation");
+ goto out;
+ }
+
+ noti_data = g_slist_nth_data(tokens, 1);
+ dbg("PDP Address: %s", noti_data);
+
+ noti_data = g_slist_nth_data(tokens, 2);
+ /*TODO: Need to handle context id with multiple PDP*/
+ if (noti_data != NULL)
+ context_id = (guint)atoi(noti_data);
+ else{
+ err("No Context ID!");
+ goto out;
+ }
+
+ dbg("Context %d deactivated", context_id);
+
+ __notify_context_status_changed(co_ps, context_id, TCORE_PS_CALL_STATE_NOT_CONNECTED);
+
+ hal = tcore_object_get_hal(co_ps);
+ if (tcore_hal_setup_netif(hal, co_ps, NULL, NULL, context_id,
+ FALSE) != TEL_RETURN_SUCCESS)
+ err("Failed to disable network interface");
+out:
+ tcore_at_tok_free(tokens);
+ return TRUE;
+}
+
+static void __imc_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) {
+ err("Result [%d],Hence Deactivating context ", result);
+ /* 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_imc_ps_send_get_dns_cmd(TcorePending *p, guint data_len, const void *data, void *user_data)
+{
+ const TcoreAtResponse *at_resp = data;
+ CoreObject *ps_context = user_data;
+ CoreObject *co_ps = tcore_pending_ref_core_object(p);
+ guint context_id;
+ GSList *tokens = NULL;
+ GSList *lines;
+ const char *line = NULL;
+ char *dns_prim = NULL;
+ char *dns_sec = NULL;
+ char *token_dns = NULL;
+ gint no_pdp_active = 0;
+ TcoreHal *hal = tcore_object_get_hal(co_ps);
+
+ dbg("Entered");
+
+ 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);
+
+ if (at_resp && at_resp->success) {
+ dbg("Response OK");
+ if (at_resp->lines) {
+ dbg("DNS data present in the Response");
+ lines = (GSList *) at_resp->lines;
+ no_pdp_active = g_slist_length(lines);
+ dbg("Total Number of Active PS Context: [%d]", no_pdp_active);
+ if (0 == no_pdp_active) {
+ goto fail;
+ }
+
+ while (lines) {
+ line = (const char *) lines->data;
+ dbg("Received Data: [%s]", line);
+ tokens = tcore_at_tok_new(line);
+
+ /* Check if Context ID is matching */
+ if (context_id == (guint)(atoi(g_slist_nth_data(tokens, 0)))) {
+ dbg("Found the DNS details for the Current Context - Context ID: [%d]", context_id);
+ break;
+ }
+
+ tcore_at_tok_free(tokens);
+ tokens = NULL;
+
+ /* Move to next line */
+ lines = lines->next;
+ }
+
+ /* Read primary DNS */
+ {
+ token_dns = g_slist_nth_data(tokens, 1);
+ dns_prim = tcore_at_tok_extract(token_dns);
+ dbg("Primary DNS: [%s]", dns_prim);
+ }
+
+ /* Read Secondary DNS */
+ {
+ token_dns = g_slist_nth_data(tokens, 2);
+ dns_sec = tcore_at_tok_extract(token_dns);
+ dbg("Secondary DNS: [%s]", dns_sec);
+ }
+
+ if ((g_strcmp0("0.0.0.0", dns_prim) == 0)
+ && (g_strcmp0("0.0.0.0", dns_sec) == 0)) {
+ dbg("Invalid DNS");
+
+ tcore_free(dns_prim);
+ tcore_free(dns_sec);
+
+ tcore_at_tok_free(tokens);
+ tokens = NULL;
+
+ goto fail;
+ }
+
+ /* Set DNS Address */
+ tcore_context_set_ipv4_dns(ps_context, dns_prim, dns_sec);
+ tcore_free(dns_prim);
+ tcore_free(dns_sec);
+
+ tcore_at_tok_free(tokens);
+ tokens = NULL;
+ goto success;
+ } else {
+ dbg("No data present in the Response");
+ }
+ }
+ dbg("Response NOK");
+
+fail:
+ dbg("Adding default DNS");
+ tcore_context_set_ipv4_dns(ps_context, "8.8.8.8", "8.8.4.4");
+
+success:
+ /* Mount network interface */
+ if (tcore_hal_setup_netif(hal, co_ps, __imc_ps_setup_pdp, ps_context, context_id, TRUE)
+ != TEL_RETURN_SUCCESS) {
+ err("Setup network interface failed");
+ return;
+ }
+}
+
+static void __imc_ps_send_get_dns_cmd(CoreObject *co_ps, CoreObject *ps_context)
+{
+ TelReturn ret = TEL_RETURN_FAILURE;
+ guint context_id;
+ PrivateInfo *private_info = tcore_object_ref_user_data(co_ps);
+
+ dbg("Entered");
+
+ tcore_check_return_assert(private_info != NULL);
+
+ (void)tcore_context_get_id(ps_context, &context_id);
+ dbg("Context ID : %d", context_id);
+
+ /* Send Request to modem */
+ ret = tcore_at_prepare_and_send_request(co_ps,
+ "AT+XDNS?", "+XDNS",
+ TCORE_AT_COMMAND_TYPE_MULTILINE,
+ TCORE_PENDING_PRIORITY_DEFAULT,
+ NULL,
+ __on_response_imc_ps_send_get_dns_cmd,
+ ps_context,
+ on_send_imc_request, NULL,
+ 0, NULL, NULL);
+
+ if (ret != TEL_RETURN_SUCCESS){
+ TcorePsCallState curr_call_status;
+ 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);
+ }
+}
+
+static void __on_response_imc_ps_get_pdp_address(TcorePending *p, guint data_len,
+ const void *data, void *user_data)
+{
+ const TcoreAtResponse *at_resp = data;
+ CoreObject *co_ps = tcore_pending_ref_core_object(p);
+ CoreObject *ps_context = user_data;
+ GSList *tokens = NULL;
+ const char *line;
+ char *pdp_address;
+ char *real_pdp_address;
+
+ dbg("Entered");
+
+ tcore_check_return_assert(at_resp != NULL);
+ tcore_check_return_assert(ps_context != NULL);
+
+ if (at_resp->success != TRUE) {
+ err("Response NOt OK");
+ goto error;
+ }
+
+ dbg("Response OK");
+
+ if (at_resp->lines == NULL) {
+ err("Invalid response line");
+ goto error;
+ }
+
+ line = (const char *)at_resp->lines->data;
+ tokens = tcore_at_tok_new(line);
+ if (g_slist_length(tokens) < 2) {
+ err("Invalid message");
+ goto error;
+ }
+
+ dbg("Line: %s", line);
+
+ /* Skip CID & read directly IP address */
+ pdp_address = g_slist_nth_data(tokens, 1);
+ real_pdp_address = tcore_at_tok_extract(pdp_address);
+
+ tcore_context_set_ipv4_addr(ps_context, real_pdp_address);
+
+ dbg("PDP address: %s", real_pdp_address);
+
+ tcore_free(real_pdp_address);
+
+ /* Get DNS Address */
+ dbg("Getting DNS Address");
+ __imc_ps_send_get_dns_cmd(co_ps, ps_context);
+ goto exit;
+
+error:
+ err("Failed to get PDP address deactivating context...");
+ /* Deactivate PDP context */
+ (void)tcore_object_dispatch_request(co_ps, TRUE,
+ TCORE_COMMAND_PS_DEACTIVATE_CONTEXT,
+ NULL, 0,
+ NULL, NULL);
+exit:
+ tcore_at_tok_free(tokens);
+ dbg("Exit");
+}
+
+static void __imc_ps_get_pdp_address(CoreObject *co_ps, CoreObject *ps_context)
+{
+ TelReturn ret;
+ gchar *at_cmd = NULL;
+ guint context_id;
+
+ dbg("Entered");
+
+ (void)tcore_context_get_id(ps_context, &context_id);
+ dbg("Context ID : %d", context_id);
+
+ /* AT-Command */
+ at_cmd = g_strdup_printf("AT+CGPADDR=%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_SINGLELINE,
+ TCORE_PENDING_PRIORITY_DEFAULT,
+ NULL,
+ __on_response_imc_ps_get_pdp_address,
+ ps_context,
+ on_send_imc_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,
+ &ps_context, sizeof(CoreObject *),
+ NULL, NULL);
+ }
+ tcore_free(at_cmd);
+}
+
+static void __on_response_imc_ps_send_xdns_enable_cmd(TcorePending *p,
+ guint data_len, const void *data, void *user_data)
+{
+ const TcoreAtResponse *at_resp = data;
+ CoreObject *co_ps = tcore_pending_ref_core_object(p);
+ CoreObject *ps_context = (CoreObject *) user_data;
+ guint context_id;
+ TcorePsCallState status = TCORE_PS_CALL_STATE_NOT_CONNECTED;
+
+ tcore_check_return_assert(at_resp != NULL);
+ tcore_check_return_assert(ps_context != NULL);
+
+ dbg("Entered");
+
+ (void)tcore_context_get_id(ps_context, &context_id);
+ dbg("Context ID : %d", context_id);
+
+ if (at_resp->success) {
+ dbg("Response OK, Dynamic DNS is enabled successfully");
+ status = TCORE_PS_CALL_STATE_CTX_DEFINED;
+ } else {
+ PrivateInfo *private_info = tcore_object_ref_user_data(co_ps);
+ tcore_check_return_assert(private_info != NULL);
+
+ status = private_info->ps_call_status;
+ err("ERROR [%s]", at_resp->final_response);
+ }
+ /* Send PS CALL Status Notification */
+ __notify_context_status_changed(co_ps, context_id, status);
+}
+
+static TelReturn __imc_ps_send_xdns_enable_cmd(CoreObject *co_ps, CoreObject *ps_context)
+{
+ guint context_id;
+ gchar *at_cmd = NULL;
+ TelReturn ret;
+ PrivateInfo *private_info = tcore_object_ref_user_data(co_ps);
+
+ tcore_check_return_value_assert(private_info != NULL, TEL_RETURN_INVALID_PARAMETER);
+
+ dbg("Entered");
+
+ (void)tcore_context_get_id(ps_context, &context_id);
+ dbg("Context ID : %d", context_id);
+
+ /* AT-Command */
+ at_cmd = g_strdup_printf("AT+XDNS=%d,1", 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_SINGLELINE,
+ TCORE_PENDING_PRIORITY_DEFAULT,
+ NULL,
+ __on_response_imc_ps_send_xdns_enable_cmd,
+ ps_context,
+ on_send_imc_request, NULL,
+ 0, NULL, NULL);
+
+ if (ret != TEL_RETURN_SUCCESS){
+ TcorePsCallState curr_call_status;
+
+ 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);
+ }
+ return ret;
+}
+
+static void on_response_imc_ps_activate_context(TcorePending *p, guint data_len,
+ const void *data,
+ void *user_data)
+{
+ const TcoreAtResponse *at_resp = data;
+ CoreObject *co_ps = tcore_pending_ref_core_object(p);
+ CoreObject *ps_context = user_data;
+ PrivateInfo *private_info = tcore_object_ref_user_data(co_ps);
+
+ dbg("Entered");
+
+ tcore_check_return_assert(at_resp != NULL);
+ tcore_check_return_assert(ps_context != NULL);
+ tcore_check_return_assert(private_info != NULL);
+
+ if (at_resp->success) {
+ dbg("Response OK, Get IP address of data session");
+ __imc_ps_get_pdp_address(co_ps, ps_context);
+ } else {
+ guint context_id;
+ TcorePsCallState curr_call_status;
+ (void)tcore_context_get_id(ps_context, &context_id);
+ err("Response NOT OK,Sending call disconnect notification");
+ curr_call_status = private_info->ps_call_status;
+ __notify_context_status_changed(co_ps, context_id, curr_call_status);
+ }
+}
+
+static void on_response_imc_ps_deactivate_context(TcorePending *p, guint data_len,
+ const void *data,
+ void *user_data)
+{
+ const TcoreAtResponse *at_resp = data;
+ CoreObject *co_ps = tcore_pending_ref_core_object(p);
+ CoreObject *ps_context = user_data;
+ TcoreHal *hal = tcore_object_get_hal(co_ps);
+ guint context_id;
+
+ dbg("Entered");
+
+ 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 0
+ if (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;
+ }
+ }
+
+#endif
+ __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");
+}
+
+static void on_response_imc_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);
+
+ dbg("Entred");
+
+ tcore_check_return_assert(at_resp != NULL);
+ tcore_check_return_assert(ps_context != NULL);
+ tcore_check_return_assert(private_info != NULL);
+
+ if (at_resp->success) {
+ dbg("Response OK,Sending DNS enable command");
+ __imc_ps_send_xdns_enable_cmd(co_ps, ps_context);
+ } else {
+ guint context_id;
+ TcorePsCallState curr_call_status;
+
+ err("ERROR[%s]", at_resp->final_response);
+ (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);
+ }
+}
+
+/*
+ * 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 imc_ps_activate_context(CoreObject *co_ps, CoreObject *ps_context,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ TelReturn ret = TEL_RETURN_FAILURE;
+ gchar *at_cmd = NULL;
+ 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("Entered");
+
+ (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_imc_ps_activate_context,
+ ps_context,
+ on_send_imc_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);
+ 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 imc_ps_deactivate_context(CoreObject *co_ps, CoreObject *ps_context,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ TelReturn ret = TEL_RETURN_FAILURE;
+ gchar *at_cmd = NULL;
+ 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("Entered");
+
+ (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_imc_ps_deactivate_context,
+ ps_context,
+ on_send_imc_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);
+ 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 imc_ps_define_context(CoreObject *co_ps, CoreObject *ps_context,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ TelReturn ret = TEL_RETURN_FAILURE;
+ gchar *at_cmd = NULL;
+ guint context_id = 0;
+ gchar *apn = NULL;
+ gchar *pdp_type_str = NULL;
+ TcoreContextType pdp_type;
+ TcoreContextDComp d_comp;
+ TcoreContextHComp h_comp;
+ 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("Entred");
+
+ (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_imc_ps_define_context,
+ ps_context,
+ on_send_imc_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:
+ return ret;
+}
+
+/* PS Operations */
+static TcorePsOps imc_ps_ops = {
+ .define_context = imc_ps_define_context,
+ .activate_context = imc_ps_activate_context,
+ .deactivate_context = imc_ps_deactivate_context
+};
+
+
+gboolean imc_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, &imc_ps_ops);
+
+ /* Add Callbacks */
+ tcore_object_add_callback(co, "+CGEV", on_notification_imc_ps_cgev, NULL);
+
+ tcore_plugin_add_notification_hook(p,
+ TCORE_NOTIFICATION_NETWORK_REGISTRATION_STATUS,
+ on_hook_imc_nw_registration_status, co);
+
+ dbg("Exit");
+ return TRUE;
+}
+
+void imc_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-imc
+ *
+ * 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_sap.h>
+
+#include "imc_sap.h"
+#include "imc_common.h"
+
+static TelSapResult __map_sap_status_to_result(int sap_status)
+{
+ switch(sap_status){
+ case 0:
+ return TEL_SAP_RESULT_SUCCESS;
+ case 1:
+ return TEL_SAP_RESULT_FAILURE_NO_REASON;
+ case 2:
+ return TEL_SAP_RESULT_CARD_NOT_ACCESSIBLE;
+ case 3:
+ return TEL_SAP_RESULT_CARD_ALREADY_POWERED_OFF;
+ case 4:
+ return TEL_SAP_RESULT_CARD_REMOVED;
+ case 5:
+ return TEL_SAP_RESULT_CARD_ALREADY_POWERED_ON;
+ case 6:
+ return TEL_SAP_RESULT_DATA_NOT_AVAILABLE;
+ case 7:
+ return TEL_SAP_RESULT_NOT_SUPPORTED;
+ default:
+ return TEL_SAP_RESULT_FAILURE_NO_REASON;
+ }
+}
+
+/* Notification */
+static gboolean on_notification_imc_sap_status(CoreObject *co,
+ const void *event_info, void *user_data)
+{
+ GSList *tokens = NULL;
+ GSList *lines = NULL;
+ const char *line = NULL;
+ TelSapCardStatus status;
+
+ dbg("Entry");
+
+ lines = (GSList *) event_info;
+ if (g_slist_length(lines) != 1) {
+ err("unsolicited msg but multiple lines");
+ return FALSE;
+ }
+
+ line = (char *)lines->data;
+ tokens = tcore_at_tok_new(line);
+ tcore_check_return_value(tokens != NULL, FALSE);
+
+ status = atoi(g_slist_nth_data(tokens, 0));
+
+ switch(status){
+ case 0:
+ status = TEL_SAP_CARD_STATUS_UNKNOWN;
+ break;
+ case 1:
+ status = TEL_SAP_CARD_STATUS_RESET;
+ break;
+ case 2:
+ status = TEL_SAP_CARD_STATUS_NOT_ACCESSIBLE;
+ break;
+ case 3:
+ status = TEL_SAP_CARD_STATUS_REMOVED;
+ break;
+ case 4:
+ status = TEL_SAP_CARD_STATUS_INSERTED;
+ break;
+ case 5:
+ status = TEL_SAP_CARD_STATUS_RECOVERED;
+ break;
+ default:
+ status = TEL_SAP_CARD_STATUS_NOT_ACCESSIBLE;
+ break;
+ }
+
+ tcore_at_tok_free(tokens);
+ tcore_object_send_notification(co,
+ TCORE_NOTIFICATION_SAP_STATUS,
+ sizeof(TelSapCardStatus), &status);
+ return TRUE;
+}
+
+/* Response */
+static void on_response_imc_sap_req_connect(TcorePending *p,
+ guint data_len, const void *data, void *user_data)
+{
+ const TcoreAtResponse *at_resp = data;
+ CoreObject *co = tcore_pending_ref_core_object(p);
+ ImcRespCbData *resp_cb_data = user_data;
+ TelSapResult result = TEL_SAP_RESULT_UNABLE_TO_ESTABLISH;
+ unsigned int max_msg_size = 0;
+ dbg("entry");
+
+ tcore_check_return_assert(co != NULL);
+ tcore_check_return_assert(resp_cb_data != NULL);
+
+ if (at_resp && at_resp->success) {
+ result = TEL_SAP_RESULT_SUCCESS;
+ memcpy(&max_msg_size, IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data), sizeof(unsigned int));
+ } else {
+ err("CME error[%s]", at_resp->lines->data);
+ /*TODO - need to map CME error to TelSapResult */
+ }
+
+ dbg("Request to sap connection : [%s]",
+ (result == TEL_SAP_RESULT_SUCCESS ? "SUCCESS" : "FAIL"));
+
+ /* Invoke callback */
+ if (resp_cb_data->cb)
+ resp_cb_data->cb(co, (gint)result, &max_msg_size, resp_cb_data->cb_data);
+
+ /* Free callback data */
+ imc_destroy_resp_cb_data(resp_cb_data);
+}
+
+static void on_response_imc_sap_req_disconnect(TcorePending *p,
+ guint data_len, const void *data, void *user_data)
+{
+ const TcoreAtResponse *at_resp = data;
+ CoreObject *co = tcore_pending_ref_core_object(p);
+ ImcRespCbData *resp_cb_data = user_data;
+ TelSapResult result = TEL_SAP_RESULT_FAILURE_NO_REASON;
+ dbg("entry");
+
+ tcore_check_return_assert(co != NULL);
+ tcore_check_return_assert(resp_cb_data != NULL);
+
+ if (at_resp && at_resp->success) {
+ result = TEL_SAP_RESULT_SUCCESS;
+ } else {
+ err("CME error[%s]", at_resp->lines->data);
+ /*TODO - need to map CME error to TelSapResult */
+ }
+
+ dbg("Request to sap connection : [%s]",
+ (result == TEL_SAP_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 */
+ imc_destroy_resp_cb_data(resp_cb_data);
+}
+
+static void on_response_imc_sap_get_atr(TcorePending *p,
+ guint data_len, const void *data, void *user_data)
+{
+ const TcoreAtResponse *at_resp = data;
+ CoreObject *co = tcore_pending_ref_core_object(p);
+ ImcRespCbData *resp_cb_data = user_data;
+ TelSapResult result = TEL_SAP_RESULT_FAILURE_NO_REASON;
+ TelSapAtr atr_resp = {0,};
+
+ dbg("entry");
+
+ if (at_resp && at_resp->success) {
+ const gchar *line;
+ char *atr_data;
+ GSList *tokens = NULL;
+
+ dbg("RESPONSE OK");
+ if (at_resp->lines == NULL) {
+ err("invalid response recieved");
+ goto END;
+ }
+
+ line = (const char*)at_resp->lines->data;
+ tokens = tcore_at_tok_new(line);
+ if (g_slist_length(tokens) < 1) {
+ err("invalid response message");
+ tcore_at_tok_free(tokens);
+ goto END;
+ }
+ atr_data = (char *) g_slist_nth_data(tokens, 1);
+ atr_resp.atr_len = strlen(atr_data);
+ if (atr_resp.atr_len > TEL_SAP_ATR_LEN_MAX) {
+ err(" invalid atr data length");
+ tcore_at_tok_free(tokens);
+ goto END;
+ }
+ memcpy(atr_resp.atr, atr_data, atr_resp.atr_len);
+
+ result = __map_sap_status_to_result(atoi(g_slist_nth_data(tokens, 0)));
+ tcore_at_tok_free(tokens);
+ } else {
+ err("RESPONSE NOK");
+ }
+
+END:
+ dbg("Request to get sap atr : [%s]",
+ (result == TEL_SAP_RESULT_SUCCESS ? "SUCCESS" : "FAIL"));
+
+ /* Invoke callback */
+ if (resp_cb_data->cb)
+ resp_cb_data->cb(co, (gint)result, &atr_resp, resp_cb_data->cb_data);
+
+ /* Free callback data */
+ imc_destroy_resp_cb_data(resp_cb_data);
+}
+
+static void on_response_imc_sap_req_transfer_apdu(TcorePending *p,
+ guint data_len, const void *data, void *user_data)
+{
+ const TcoreAtResponse *at_resp = data;
+ CoreObject *co = tcore_pending_ref_core_object(p);
+ ImcRespCbData *resp_cb_data = user_data;
+ TelSapResult result = TEL_SAP_RESULT_FAILURE_NO_REASON;
+ TelSapApduResp apdu_resp = {0,};
+
+ dbg("entry");
+
+ if (at_resp && at_resp->success) {
+ const gchar *line;
+ int sap_status;
+ char *apdu_data;
+ GSList *tokens = NULL;
+
+ dbg("RESPONSE OK");
+ if (at_resp->lines == NULL) {
+ err("invalid response recieved");
+ goto END;
+ }
+
+ line = (const char*)at_resp->lines->data;
+ tokens = tcore_at_tok_new(line);
+ if (g_slist_length(tokens) < 1) {
+ err("invalid response message");
+ tcore_at_tok_free(tokens);
+ goto END;
+ }
+
+ apdu_data = (char *) g_slist_nth_data(tokens, 1);
+ apdu_resp.apdu_resp_len = strlen(apdu_data);
+ if (apdu_resp.apdu_resp_len > TEL_SAP_APDU_RESP_LEN_MAX) {
+ err(" invalid apdu data length");
+ tcore_at_tok_free(tokens);
+ goto END;
+ }
+ memcpy(apdu_resp.apdu_resp, apdu_data, apdu_resp.apdu_resp_len);
+
+ sap_status = atoi(g_slist_nth_data(tokens, 0));
+ if (sap_status > 4)
+ /* In this case modem does not provide sap_status 5 ('Card already powered ON'),
+ instead it will provide status 5 ('Data not available') and 6 ('Not Supported'),
+ So to align 'sap_status' value with __map_sap_status_to_result(), it is increased by 1.
+ */
+ result = __map_sap_status_to_result(sap_status + 1);
+ else
+ result = __map_sap_status_to_result(sap_status);
+
+ tcore_at_tok_free(tokens);
+ } else {
+ err("RESPONSE NOK");
+ }
+
+END:
+ dbg("Request to transfer apdu : [%s]",
+ (result == TEL_SAP_RESULT_SUCCESS ? "SUCCESS" : "FAIL"));
+
+ /* Invoke callback */
+ if (resp_cb_data->cb)
+ resp_cb_data->cb(co, (gint)result, &apdu_resp, resp_cb_data->cb_data);
+
+ /* Free callback data */
+ imc_destroy_resp_cb_data(resp_cb_data);
+}
+
+static void on_response_imc_sap_req_power_operation(TcorePending *p,
+ guint data_len, const void *data, void *user_data)
+{
+ const TcoreAtResponse *at_resp = data;
+ CoreObject *co = tcore_pending_ref_core_object(p);
+ ImcRespCbData *resp_cb_data = user_data;
+ TelSapResult result = TEL_SAP_RESULT_FAILURE_NO_REASON;
+
+ dbg("entry");
+
+ if (at_resp && at_resp->success) {
+ const gchar *line;
+ GSList *tokens = NULL;
+
+ dbg("RESPONSE OK");
+ if (at_resp->lines == NULL) {
+ err("invalid response recieved");
+ goto END;
+ }
+
+ line = (const char*)at_resp->lines->data;
+ tokens = tcore_at_tok_new(line);
+ if (g_slist_length(tokens) < 1) {
+ err("invalid response message");
+ tcore_at_tok_free(tokens);
+ goto END;
+ }
+ result = __map_sap_status_to_result(atoi(g_slist_nth_data(tokens, 0)));
+ tcore_at_tok_free(tokens);
+ } else {
+ err("RESPONSE NOK");
+ }
+
+END:
+ dbg("Request to sap power operation : [%s]",
+ (result == TEL_SAP_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 */
+ imc_destroy_resp_cb_data(resp_cb_data);
+}
+
+static void on_response_imc_sap_get_cardreader_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);
+ ImcRespCbData *resp_cb_data = user_data;
+ TelSapResult result = TEL_SAP_RESULT_FAILURE_NO_REASON;
+ TelSapCardStatus card_status = TEL_SAP_CARD_STATUS_UNKNOWN;
+ dbg("entry");
+
+ if (at_resp && at_resp->success) {
+ const gchar *line;
+ GSList *tokens = NULL;
+ unsigned char card_reader_status;
+ int count;
+
+ dbg("RESPONSE OK");
+ if (at_resp->lines == NULL) {
+ err("invalid response recieved");
+ goto END;
+ }
+
+ line = (const char*)at_resp->lines->data;
+ tokens = tcore_at_tok_new(line);
+ if (g_slist_length(tokens) < 1) {
+ err("invalid response message");
+ tcore_at_tok_free(tokens);
+ goto END;
+ }
+ result = __map_sap_status_to_result(atoi(g_slist_nth_data(tokens, 0)));
+
+ card_reader_status = (unsigned char)atoi(g_slist_nth_data(tokens, 1));
+ card_reader_status = card_reader_status >> 3;
+ for (count = 8; count > 3; count--) { //check bit 8 to 3
+ if ((card_reader_status & 0x80) == TRUE) { //Check most significant bit
+ //card_status = //TODO - Need to map card reader status to TelSapCardStatus.
+ break;
+ }
+ card_reader_status = card_reader_status << 1; //left shift by 1
+ }
+ tcore_at_tok_free(tokens);
+ } else {
+ err("RESPONSE NOK");
+ result = TEL_SAP_RESULT_FAILURE_NO_REASON;
+ }
+
+END:
+ dbg("Request to get card reader status : [%s]",
+ (result == TEL_SAP_RESULT_SUCCESS ? "SUCCESS" : "FAIL"));
+
+ /* Invoke callback */
+ if (resp_cb_data->cb)
+ resp_cb_data->cb(co, (gint)result, &card_status, resp_cb_data->cb_data);
+
+ /* Free callback data */
+ imc_destroy_resp_cb_data(resp_cb_data);
+}
+
+/* Sap operations */
+
+/*
+ * Operation - switch the modem to the BT SAP server mode.
+ *
+ * Request -
+ * AT-Command: AT+ XBCON = <op_mode>, <change_mode>, <reject_mode>
+ * where,
+ * <op_mode>
+ * 0 - BT SAP Server modes
+ * 1 - BT SAP Client mode (Client mode is currently not supported)
+ * <change_mode>
+ * 0 - gracefully, or Time out
+ * 1 - immediately
+ * <reject_mode>
+ * 0 - Reject is not allowed.
+ * 1 - Reject is allowed.
+ * Response -
+ * Success: (No Result)
+ * OK
+ * Failure:
+ * +CME ERROR: <error>
+ */
+static TelReturn imc_sap_req_connect(CoreObject *co, unsigned int max_msg_size,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ ImcRespCbData *resp_cb_data;
+ TelReturn ret;
+
+ /* Response callback data */
+ resp_cb_data = imc_create_resp_cb_data(cb, cb_data,
+ &max_msg_size, sizeof(unsigned int));
+
+ /* Send Request to modem */
+ ret = tcore_at_prepare_and_send_request(co,
+ "AT+XBCON=0,0,0", NULL,
+ TCORE_AT_COMMAND_TYPE_NO_RESULT,
+ TCORE_PENDING_PRIORITY_DEFAULT,
+ NULL,
+ on_response_imc_sap_req_connect, resp_cb_data,
+ on_send_imc_request, NULL,
+ 0, NULL, NULL);
+
+ IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "imc_sap_req_connect");
+ return ret;
+}
+
+/*
+ * Operation - disconnects BT SAP.
+ *
+ * Request -
+ * AT-Command: AT+ XBDISC
+ *
+ * Response -
+ * Success: (No Result)
+ * OK
+ * Failure:
+ * +CME ERROR: <error>
+ */
+static TelReturn imc_sap_req_disconnect(CoreObject *co, TcoreObjectResponseCallback cb,
+ void *cb_data)
+{
+ ImcRespCbData *resp_cb_data;
+ TelReturn ret;
+
+ /* Response callback data */
+ resp_cb_data = imc_create_resp_cb_data(cb, cb_data,
+ NULL, 0);
+
+ /* Send Request to modem */
+ ret = tcore_at_prepare_and_send_request(co,
+ "AT+XBDISC", NULL,
+ TCORE_AT_COMMAND_TYPE_NO_RESULT,
+ TCORE_PENDING_PRIORITY_DEFAULT,
+ NULL,
+ on_response_imc_sap_req_disconnect, resp_cb_data,
+ on_send_imc_request, NULL,
+ 0, NULL, NULL);
+
+ IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "imc_sap_req_disconnect");
+ return ret;
+}
+
+/*
+ * Operation - In BT SAP server mode, request the ATR from the stack to the Application.
+ *
+ * Request -
+ * AT-Command: AT+ XBATR
+ *
+ * Response -
+ * Success: +XBATR: <status>, <data_ATR>
+ * OK
+ * where
+ * <status>
+ * 0 OK, request processed correctly
+ * 1 No Reason defined
+ * 2 Card not accessible
+ * 3 Card (already) powered off
+ * 4 Card Removed
+ * 6 Data Not available
+ * 7 Not Supported
+ * <data_ATR>
+ * Hex Data (an array of bytes)
+ *
+ * Failure:
+ * +CME ERROR: <error>
+ */
+static TelReturn imc_sap_get_atr(CoreObject *co, TcoreObjectResponseCallback cb,
+ void *cb_data)
+{
+ ImcRespCbData *resp_cb_data;
+ TelReturn ret;
+
+ /* Response callback data */
+ resp_cb_data = imc_create_resp_cb_data(cb, cb_data,
+ NULL, 0);
+
+ /* Send Request to modem */
+ ret = tcore_at_prepare_and_send_request(co,
+ "AT+XBATR", "+XBATR:",
+ TCORE_AT_COMMAND_TYPE_SINGLELINE,
+ TCORE_PENDING_PRIORITY_DEFAULT,
+ NULL,
+ on_response_imc_sap_get_atr, resp_cb_data,
+ on_send_imc_request, NULL,
+ 0, NULL, NULL);
+
+ IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "imc_sap_get_atr");
+ return ret;
+}
+
+/*
+ * Operation - BT SAP server mode, Forward command APDU from application to SIM.
+ *
+ * Request -
+ * AT-Command: AT+ XBAPDU = <data: command_APDU >
+ * where
+ * <data: command_APDU >
+ * Hex Data (an array of bytes). CP supports Command_APDU up to 261 bytes long.
+ *
+ * Response -
+ * Success: +XBAPDU: <status>, [<data:Response_APDU>]
+ * OK
+ * where
+ * <status>
+ * 0 OK, request processed correctly
+ * 1 No Reason defined
+ * 2 Card not accessible
+ * 3 Card (already) powered off
+ * 4 Card Removed
+ * 5 Data not available
+ * 6 Not Supported
+ * <data:Response_APDU>
+ * Hex Data (an array of bytes). CP supports Response_APDU up to 258 bytes long
+ * Failure:
+ * +CME ERROR: <error>
+ */
+static TelReturn imc_sap_req_transfer_apdu(CoreObject *co, const TelSapApdu *apdu_data,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ ImcRespCbData *resp_cb_data;
+ TelReturn ret;
+ gchar *at_cmd;
+
+ /* AT-Command */
+ at_cmd = g_strdup_printf("AT+XBAPDU=\"%s\"", apdu_data->apdu);
+
+ /* Response callback data */
+ resp_cb_data = imc_create_resp_cb_data(cb, cb_data,
+ NULL, 0);
+
+ /* Send Request to modem */
+ ret = tcore_at_prepare_and_send_request(co,
+ at_cmd, "+XBAPDU:",
+ TCORE_AT_COMMAND_TYPE_SINGLELINE,
+ TCORE_PENDING_PRIORITY_DEFAULT,
+ NULL,
+ on_response_imc_sap_req_transfer_apdu, resp_cb_data,
+ on_send_imc_request, NULL,
+ 0, NULL, NULL);
+
+ IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "imc_sap_req_transfer_apdu");
+ g_free(at_cmd);
+ return ret;
+}
+
+static TelReturn imc_sap_req_transport_protocol(CoreObject *co, TelSimSapProtocol protocol,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ err("Operation not supported");
+ return TEL_RETURN_OPERATION_NOT_SUPPORTED;
+}
+
+/*
+ * Operation - In BT SAP server mode, Power ON,OFF and Reset the SIM.
+ *
+ * Request -
+ * AT-Command: AT+ XBPWR =<action>
+ * where
+ * <Action>:
+ * 0 SIM Power ON
+ * 1 SIM Power OFF
+ * 2 SIM RESET
+ *
+ * Response -
+ * Success: + XBPWR: <status>
+ * OK
+ * where
+ * <status>
+ * 0 OK, Request processed correctly
+ * 1 Error no reason defined
+ * 2 Card not Accessible
+ * 3 Card already powered OFF
+ * 4 Card removed
+ * 5 Card already powered ON
+ * 6 Data Not vailable
+ * 7 Not Supported
+ * Failure:
+ * +CME ERROR: <error>
+ */
+static TelReturn imc_sap_req_power_operation(CoreObject *co, TelSapPowerMode power_mode,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ ImcRespCbData *resp_cb_data;
+ TelReturn ret = TEL_RETURN_FAILURE;
+ gchar *at_cmd;
+ int action;
+
+ if(power_mode == TEL_SAP_SIM_POWER_ON_REQ) {
+ action = 0;
+ } else if(power_mode == TEL_SAP_SIM_POWER_OFF_REQ) {
+ action = 1;
+ } else if (power_mode == TEL_SAP_SIM_RESET_REQ) {
+ action = 2;
+ } else {
+ err("invalid power mode");
+ return ret;
+ }
+
+ /* AT-Command */
+ at_cmd = g_strdup_printf("AT+XBPWR=%d", action);
+
+ /* Response callback data */
+ resp_cb_data = imc_create_resp_cb_data(cb, cb_data,
+ NULL, 0);
+
+ /* Send Request to modem */
+ ret = tcore_at_prepare_and_send_request(co,
+ at_cmd, "+XBPWR:",
+ TCORE_AT_COMMAND_TYPE_SINGLELINE,
+ TCORE_PENDING_PRIORITY_DEFAULT,
+ NULL,
+ on_response_imc_sap_req_power_operation, resp_cb_data,
+ on_send_imc_request, NULL,
+ 0, NULL, NULL);
+
+ IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "imc_sap_req_power_operation");
+ g_free(at_cmd);
+ return ret;
+}
+
+/*
+ * Operation - In BT SAP server mode, get the Card reader Status.
+ *
+ * Request -
+ * AT-Command: AT+XBCRDSTAT
+ *
+ * Response -
+ * Success: +XBCRDSTAT: <status>, <card_reader_status>
+ * OK
+ * where
+ * <status>
+ * 0 OK, Request processed correctly
+ * 1 Error no reason defined
+ * 2 Card not Accessible
+ * 3 Card already powered OFF
+ * 4 Card removed
+ * 5 Card already powered ON
+ * 6 Data Not vailable
+ * 7 Not Supported
+ * <card_reader_status>
+ * One byte. It represents card reader identity and status.
+ * The value of this byte indicates the identity and status of a card reader.
+ * Bits 1-3 = identity of card reader x.
+ * bit 4, 0 = Card reader is not removable, 1 = Card reader is removable
+ * bit 5, 0 = Card reader is not present, 1 = Card reader is present
+ * bit 6, 0 = Card reader present is not ID-1 size, 1 = Card reader present is ID-1 size
+ * bit 7, 0 = No card present, 1 = Card is present in reader
+ * bit 8, 0 = No card powered, 1 = Card in reader is powered
+ * Failure:
+ * +CME ERROR: <error>
+ */
+static TelReturn imc_sap_get_cardreader_status(CoreObject *co, TcoreObjectResponseCallback cb,
+ void *cb_data)
+{
+ ImcRespCbData *resp_cb_data;
+ TelReturn ret;
+
+ /* Response callback data */
+ resp_cb_data = imc_create_resp_cb_data(cb, cb_data,
+ NULL, 0);
+
+ /* Send Request to modem */
+ ret = tcore_at_prepare_and_send_request(co,
+ "AT+XBCRDSTAT", "+XBCRDSTAT:",
+ TCORE_AT_COMMAND_TYPE_SINGLELINE,
+ TCORE_PENDING_PRIORITY_DEFAULT,
+ NULL,
+ on_response_imc_sap_get_cardreader_status, resp_cb_data,
+ on_send_imc_request, NULL,
+ 0, NULL, NULL);
+
+ IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "imc_sap_get_cardreader_status");
+ return ret;
+}
+
+/* SAP Operations */
+static TcoreSapOps imc_sap_ops = {
+ .req_connect = imc_sap_req_connect,
+ .req_disconnect = imc_sap_req_disconnect,
+ .get_atr = imc_sap_get_atr,
+ .req_transfer_apdu = imc_sap_req_transfer_apdu,
+ .req_transport_protocol = imc_sap_req_transport_protocol,
+ .req_power_operation = imc_sap_req_power_operation,
+ .get_cardreader_status = imc_sap_get_cardreader_status
+};
+
+gboolean imc_sap_init(TcorePlugin *p, CoreObject *co)
+{
+ dbg("Entry");
+
+ /* Set operations */
+ tcore_sap_set_ops(co, &imc_sap_ops);
+
+ /* Add Callbacks */
+ tcore_object_add_callback(co, "+XBCSTAT", on_notification_imc_sap_status, NULL);
+
+ dbg("Exit");
+ return TRUE;
+}
+
+void imc_sap_exit(TcorePlugin *p, CoreObject *co)
+{
+ dbg("Exit");
+}
--- /dev/null
+/*
+ * tel-plugin-imc
+ *
+ * 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_sat.h>
+
+#include "imc_sat.h"
+#include "imc_common.h"
+
+#define PROACTV_CMD_LEN 256
+
+static void on_response_enable_sat(TcorePending *p,
+ guint data_len, const void *data, void *user_data)
+{
+ const TcoreAtResponse *at_resp = data;
+
+ if (at_resp && at_resp->success) {
+ dbg("Enable SAT (Proactive command) - [OK]");
+ }
+ else {
+ err("Enable SAT (Proactive command) - [NOK]");
+ }
+}
+
+/* Hook functions */
+static TcoreHookReturn on_hook_imc_sim_status(TcorePlugin *plugin,
+ TcoreNotification command, guint data_len, void *data, void *user_data)
+{
+ const TelSimCardStatus *sim_status = (TelSimCardStatus *)data;
+ CoreObject *co = (CoreObject *)user_data;
+
+ tcore_check_return_value(sim_status != NULL, TCORE_HOOK_RETURN_CONTINUE);
+
+ /*
+ * If SIM is initialized -
+ * * Enable SAT
+ */
+ dbg("SIM Status: [%d]", *sim_status);
+ if (*sim_status == TEL_SIM_STATUS_SIM_INIT_COMPLETED) {
+ dbg("SIM Initialized!!! Enable SAT");
+
+ /* Enable SAT - Send AT+CFUN=6 */
+ tcore_at_prepare_and_send_request(co,
+ "AT+CFUN=6", NULL,
+ TCORE_AT_COMMAND_TYPE_NO_RESULT,
+ TCORE_PENDING_PRIORITY_DEFAULT,
+ NULL,
+ on_response_enable_sat, NULL,
+ on_send_imc_request, NULL,
+ 0, NULL, NULL);
+ }
+
+ return TCORE_HOOK_RETURN_CONTINUE;
+}
+
+static gboolean on_response_imc_sat_terminal_response_confirm
+ (CoreObject *co, const void *event_info, void *user_data)
+{
+ dbg("Entry");
+ return TRUE;
+}
+
+static gboolean on_notification_imc_sat_proactive_command
+ (CoreObject *co, const void *event_info, void *user_data)
+{
+ TelSatDecodedProactiveData decoded_data;
+ TelSatNotiProactiveData proactive_noti;
+ gint proactive_cmd_len = 0;
+ GSList *lines = NULL;
+ GSList *tokens = NULL;
+ gchar *line = NULL;
+ gchar *hex_data = NULL;
+ gchar *tmp = NULL;
+ gchar *record_data = NULL;
+ guint record_data_len;
+ gint decode_err;
+ gboolean decode_ret = FALSE;
+
+ dbg("Entry");
+
+ tcore_check_return_value_assert(co != NULL, FALSE);
+ memset(&proactive_noti, 0x00, sizeof(TelSatNotiProactiveData));
+ memset(&decoded_data, 0x00, sizeof(TelSatDecodedProactiveData));
+
+ lines = (GSList *) event_info;
+ line = (gchar *) lines->data;
+ tokens = tcore_at_tok_new(line);
+ if (g_slist_length(tokens) != 1) {
+ err("Invalid message");
+ tcore_at_tok_free(tokens);
+ return TRUE;
+ }
+
+ hex_data = (gchar *)g_slist_nth_data(tokens, 0);
+ dbg("SAT data: [%s] SAT data length: [%d]", hex_data, strlen(hex_data));
+
+ tmp = (gchar *)tcore_at_tok_extract((gchar *)hex_data);
+ tcore_util_hexstring_to_bytes(tmp, &record_data, &record_data_len);
+ dbg("record_data: %x", record_data);
+ tcore_free(tmp);
+
+ tcore_util_hex_dump(" ", strlen(hex_data) / 2, record_data);
+ proactive_cmd_len = strlen(record_data);
+ dbg("proactive_cmd_len = %d", proactive_cmd_len);
+
+ decode_ret = tcore_sat_decode_proactive_command((guchar *) record_data,
+ record_data_len, &decoded_data, &decode_err);
+ if (!decode_ret) {
+ err("Proactive Command decoding failed");
+ tcore_at_tok_free(tokens);
+ return TRUE;
+ }
+
+ tcore_free(record_data);
+
+ proactive_noti.cmd_number = decoded_data.cmd_num;
+ proactive_noti.cmd_type = decoded_data.cmd_type;
+ proactive_noti.decode_err_code = decode_err;
+
+ switch (decoded_data.cmd_type) {
+ case TEL_SAT_PROATV_CMD_DISPLAY_TEXT:
+ dbg("decoded command is display text!!");
+ memcpy(&proactive_noti.proactive_ind_data.display_text,
+ &decoded_data.data.display_text,
+ sizeof(TelSatDisplayTextTlv));
+ break;
+
+ case TEL_SAT_PROATV_CMD_GET_INKEY:
+ dbg("decoded command is get inkey!!");
+ memcpy(&proactive_noti.proactive_ind_data.get_inkey,
+ &decoded_data.data.get_inkey,
+ sizeof(TelSatGetInkeyTlv));
+ break;
+
+ case TEL_SAT_PROATV_CMD_GET_INPUT:
+ dbg("decoded command is get input!!");
+ memcpy(&proactive_noti.proactive_ind_data.get_input,
+ &decoded_data.data.get_input,
+ sizeof(TelSatGetInputTlv));
+ break;
+
+ case TEL_SAT_PROATV_CMD_MORE_TIME:
+ dbg("decoded command is more time!!");
+ memcpy(&proactive_noti.proactive_ind_data.more_time,
+ &decoded_data.data.more_time,
+ sizeof(TelSatMoreTimeTlv));
+ break;
+
+ case TEL_SAT_PROATV_CMD_PLAY_TONE:
+ dbg("decoded command is play tone!!");
+ memcpy(&proactive_noti.proactive_ind_data.play_tone,
+ &decoded_data.data.play_tone,
+ sizeof(TelSatPlayToneTlv));
+ break;
+
+ case TEL_SAT_PROATV_CMD_SETUP_MENU:
+ dbg("decoded command is SETUP MENU!!");
+ memcpy(&proactive_noti.proactive_ind_data.setup_menu,
+ &decoded_data.data.setup_menu, sizeof(TelSatSetupMenuTlv));
+ break;
+
+ case TEL_SAT_PROATV_CMD_SELECT_ITEM:
+ dbg("decoded command is select item!!");
+ memcpy(&proactive_noti.proactive_ind_data.select_item,
+ &decoded_data.data.select_item,
+ sizeof(TelSatSelectItemTlv));
+ break;
+
+ case TEL_SAT_PROATV_CMD_SEND_SMS:
+ dbg("decoded command is send sms!!");
+ memcpy(&proactive_noti.proactive_ind_data.send_sms,
+ &decoded_data.data.send_sms,
+ sizeof(TelSatSendSmsTlv));
+ break;
+
+ case TEL_SAT_PROATV_CMD_SEND_SS:
+ dbg("decoded command is send ss!!");
+ memcpy(&proactive_noti.proactive_ind_data.send_ss,
+ &decoded_data.data.send_ss,
+ sizeof(TelSatSendSsTlv));
+ break;
+
+ case TEL_SAT_PROATV_CMD_SEND_USSD:
+ dbg("decoded command is send ussd!!");
+ memcpy(&proactive_noti.proactive_ind_data.send_ussd,
+ &decoded_data.data.send_ussd,
+ sizeof(TelSatSendUssdTlv));
+ break;
+
+ case TEL_SAT_PROATV_CMD_SETUP_CALL:
+ dbg("decoded command is setup call!!");
+ memcpy(&proactive_noti.proactive_ind_data.setup_call,
+ &decoded_data.data.setup_call,
+ sizeof(TelSatSetupCallTlv));
+ break;
+
+ case TEL_SAT_PROATV_CMD_REFRESH:
+ dbg("decoded command is refresh");
+ memcpy(&proactive_noti.proactive_ind_data.refresh,
+ &decoded_data.data.refresh, sizeof(TelSatRefreshTlv));
+ break;
+
+ case TEL_SAT_PROATV_CMD_PROVIDE_LOCAL_INFO:
+ dbg("decoded command is provide local info");
+ memcpy(&proactive_noti.proactive_ind_data.provide_local_info,
+ &decoded_data.data.provide_local_info,
+ sizeof(TelSatProvideLocalInfoTlv));
+ break;
+
+ case TEL_SAT_PROATV_CMD_SETUP_EVENT_LIST:
+ dbg("decoded command is setup event list!!");
+ memcpy(&proactive_noti.proactive_ind_data.setup_event_list,
+ &decoded_data.data.setup_event_list,
+ sizeof(TelSatSetupEventListTlv));
+ // setup_event_rsp_get(o, &decoded_data.data.setup_event_list);
+ break;
+
+ case TEL_SAT_PROATV_CMD_SETUP_IDLE_MODE_TEXT:
+ dbg("decoded command is setup idle mode text");
+ memcpy(&proactive_noti.proactive_ind_data.setup_idle_mode_text,
+ &decoded_data.data.setup_idle_mode_text,
+ sizeof(TelSatSetupIdleModeTextTlv));
+ break;
+
+ case TEL_SAT_PROATV_CMD_SEND_DTMF:
+ dbg("decoded command is send dtmf");
+ memcpy(&proactive_noti.proactive_ind_data.send_dtmf,
+ &decoded_data.data.send_dtmf,
+ sizeof(TelSatSendDtmfTlv));
+ break;
+
+ case TEL_SAT_PROATV_CMD_LANGUAGE_NOTIFICATION:
+ dbg("decoded command is language notification");
+ memcpy(&proactive_noti.proactive_ind_data.language_notification,
+ &decoded_data.data.language_notification,
+ sizeof(TelSatLanguageNotificationTlv));
+ break;
+
+ case TEL_SAT_PROATV_CMD_LAUNCH_BROWSER:
+ dbg("decoded command is launch browser");
+ memcpy(&proactive_noti.proactive_ind_data.launch_browser,
+ &decoded_data.data.launch_browser,
+ sizeof(TelSatLaunchBrowserTlv));
+ break;
+
+ case TEL_SAT_PROATV_CMD_OPEN_CHANNEL:
+ dbg("decoded command is open channel!!");
+ memcpy(&proactive_noti.proactive_ind_data.open_channel,
+ &decoded_data.data.open_channel,
+ sizeof(TelSatOpenChannelTlv));
+ break;
+
+ case TEL_SAT_PROATV_CMD_CLOSE_CHANNEL:
+ dbg("decoded command is close channel!!");
+ memcpy(&proactive_noti.proactive_ind_data.close_channel,
+ &decoded_data.data.close_channel,
+ sizeof(TelSatCloseChannelTlv));
+ break;
+
+ case TEL_SAT_PROATV_CMD_RECEIVE_DATA:
+ dbg("decoded command is receive data!!");
+ memcpy(&proactive_noti.proactive_ind_data.receive_data,
+ &decoded_data.data.receive_data,
+ sizeof(TelSatReceiveChannelTlv));
+ break;
+
+ case TEL_SAT_PROATV_CMD_SEND_DATA:
+ dbg("decoded command is send data!!");
+ memcpy(&proactive_noti.proactive_ind_data.send_data,
+ &decoded_data.data.send_data,
+ sizeof(TelSatSendChannelTlv));
+ break;
+
+ case TEL_SAT_PROATV_CMD_GET_CHANNEL_STATUS:
+ dbg("decoded command is get channel status!!");
+ memcpy(&proactive_noti.proactive_ind_data.get_channel_status,
+ &decoded_data.data.get_channel_status,
+ sizeof(TelSatGetChannelStatusTlv));
+ break;
+
+ default:
+ dbg("invalid command:[%d]", decoded_data.cmd_type);
+ break;
+ }
+
+ if (decoded_data.cmd_type == TEL_SAT_PROATV_CMD_REFRESH) {
+ /*Not supported*/
+ dbg("Not suported Proactive command");
+ tcore_at_tok_free(tokens);
+ return TRUE;
+ }
+
+ /* Send notification */
+ tcore_object_send_notification(co,
+ TCORE_NOTIFICATION_SAT_PROACTIVE_CMD,
+ sizeof(TelSatNotiProactiveData), &proactive_noti);
+
+ tcore_at_tok_free(tokens);
+
+ dbg("Exit");
+ return TRUE;
+}
+
+/* SAT Responses */
+static void on_response_imc_sat_send_envelop_cmd(TcorePending *p,
+ guint data_len, const void *data, void *user_data)
+{
+ const TcoreAtResponse *at_resp = data;
+ CoreObject *co = tcore_pending_ref_core_object(p);
+ ImcRespCbData *resp_cb_data = user_data;
+ TelSatEnvelopeResp envelop_resp;
+ TelSatResult result = TEL_SAT_RESULT_FAILURE;
+ GSList *tokens = NULL;
+ const gchar *line = NULL;
+ const gchar *env_res = NULL;
+ gint sw2 = -1;
+
+ dbg("Entry");
+
+ tcore_check_return_assert(co != NULL);
+ tcore_check_return_assert(resp_cb_data != NULL);
+ tcore_check_return_assert(resp_cb_data->cb != NULL);
+
+ if (at_resp && at_resp->success) {
+ result = TEL_SAT_RESULT_SUCCESS;
+ dbg("RESPONSE OK");
+ if (at_resp->lines) {
+ line = (const gchar *) at_resp->lines->data;
+ tokens = tcore_at_tok_new(line);
+ if (g_slist_length(tokens) < 1) {
+ err("invalid message");
+ tcore_at_tok_free(tokens);
+ return;
+ }
+ }
+ env_res = g_slist_nth_data(tokens, 0);
+ envelop_resp = TEL_SAT_ENVELOPE_SUCCESS;
+ dbg("RESPONSE tokens present");
+ if (NULL != g_slist_nth_data(tokens, 1)) {
+ sw2 = atoi(g_slist_nth_data(tokens, 1));
+ dbg("status word SW2:[%d]", sw2);
+ if (sw2 == 0) {
+ dbg("Response is processed completely and sending session end notification");
+ /* Send Session End notification */
+ tcore_object_send_notification(co,
+ TCORE_NOTIFICATION_SAT_SESSION_END, 0, NULL);
+ }
+ }
+ } else {
+ dbg("RESPONSE NOK");
+ envelop_resp = TEL_SAT_ENVELOPE_FAILED;
+ }
+
+ /* Invoke callback */
+ if (resp_cb_data->cb)
+ resp_cb_data->cb(co, (gint)result, &envelop_resp, resp_cb_data->cb_data);
+
+ imc_destroy_resp_cb_data(resp_cb_data);
+ tcore_at_tok_free(tokens);
+ dbg("Exit");
+}
+
+static void on_response_imc_sat_send_terminal_response(TcorePending *p,
+ guint data_len, const void *data, void *user_data)
+{
+ const TcoreAtResponse *at_resp = data;
+ CoreObject *co = tcore_pending_ref_core_object(p);
+ ImcRespCbData *resp_cb_data = user_data;
+ TelSatResult result = TEL_SAT_RESULT_FAILURE;
+
+ dbg("Entry");
+
+ tcore_check_return_assert(co != NULL);
+ tcore_check_return_assert(resp_cb_data != NULL);
+ tcore_check_return_assert(resp_cb_data->cb != NULL);
+
+ if (at_resp && at_resp->success) {
+ result = TEL_SAT_RESULT_SUCCESS;
+ dbg("RESPONSE OK");
+ dbg(" at_resp->success = %d", at_resp->success);
+ /* Send Session End notification */
+ tcore_object_send_notification(co, TCORE_NOTIFICATION_SAT_SESSION_END, 0, NULL);
+ }
+
+ /* Invoke callback */
+ if (resp_cb_data->cb)
+ resp_cb_data->cb(co, (gint)result, NULL, resp_cb_data->cb_data);
+
+ imc_destroy_resp_cb_data(resp_cb_data);
+ dbg("Exit");
+}
+
+static void on_response_imc_sat_send_user_confirmation(TcorePending *p,
+ guint data_len, const void *data, void *user_data)
+{
+ const TcoreAtResponse *at_resp = data;
+ CoreObject *co = tcore_pending_ref_core_object(p);
+ ImcRespCbData *resp_cb_data = user_data;
+ TelSatResult result = TEL_SAT_RESULT_FAILURE;
+
+ dbg("Entry");
+
+ tcore_check_return_assert(co != NULL);
+ tcore_check_return_assert(resp_cb_data != NULL);
+ tcore_check_return_assert(resp_cb_data->cb != NULL);
+
+ if (at_resp && at_resp->success) {
+ dbg("RESPONSE OK");
+ result = TEL_SAT_RESULT_SUCCESS;
+ }
+
+ /* Invoke callback */
+ if (resp_cb_data->cb)
+ resp_cb_data->cb(co, (gint)result, NULL, resp_cb_data->cb_data);
+
+ imc_destroy_resp_cb_data(resp_cb_data);
+ dbg("Exit");
+}
+
+/* SAT Requests */
+/*
+ * Operation - Send Envelop Command
+ *
+ * Request -
+ * AT-Command: AT+SATE
+ *
+ * Response - SW
+ * Success: (Single line)
+ * <sw1>,<sw2>
+ * OK
+ * Failure:
+ * +CME ERROR: <error>
+ */
+static TelReturn imc_sat_send_envelope(CoreObject *co,
+ const TelSatRequestEnvelopCmdData *envelop_data,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ gchar *at_cmd;
+ gint envelope_cmd_len = 0;
+ gchar envelope_cmd[PROACTV_CMD_LEN];
+ gint count = 0;
+ gchar hex_string[PROACTV_CMD_LEN * 2];
+ gchar *buffer = NULL;
+ gboolean encode_ret = FALSE;
+
+ ImcRespCbData *resp_cb_data;
+ TelReturn ret;
+
+ dbg("Entry");
+ memset(&hex_string, 0x00, sizeof(hex_string));
+ buffer = hex_string;
+
+ encode_ret = tcore_sat_encode_envelop_cmd(envelop_data,
+ (gchar *)envelope_cmd, (gint *)&envelope_cmd_len);
+ if (!encode_ret) {
+ err("Envelope Command encoding failed");
+ return TEL_RETURN_FAILURE;
+ }
+
+ dbg("envelope_cmd_len after encoding :[%d]", envelope_cmd_len);
+ if (envelope_cmd_len == 0) {
+ err("Envelope command length after encoding is NULL");
+ return TEL_RETURN_INVALID_PARAMETER;
+ }
+
+ for (count = 0; count < envelope_cmd_len; count++) {
+ dbg("envelope_cmd: %02x", (guchar)envelope_cmd[count]);
+ sprintf(buffer, "%02x", (guchar)envelope_cmd[count]);
+ buffer += 2;
+ }
+ dbg("hex_string: %s", hex_string);
+
+ /* AT-Command */
+ at_cmd = g_strdup_printf("AT+SATE=\"%s\"", hex_string);
+
+ resp_cb_data = imc_create_resp_cb_data(cb, cb_data,
+ (void *)&envelop_data->sub_cmd, sizeof(TelSatEnvelopSubCmd));
+
+ /* Send Request to modem */
+ ret = tcore_at_prepare_and_send_request(co,
+ at_cmd, NULL,
+ TCORE_AT_COMMAND_TYPE_SINGLELINE,
+ TCORE_PENDING_PRIORITY_DEFAULT,
+ NULL,
+ on_response_imc_sat_send_envelop_cmd, resp_cb_data,
+ on_send_imc_request, NULL,
+ 0, NULL, NULL);
+ IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Send Envelop Command");
+
+ /* Free resources */
+ tcore_free(at_cmd);
+ dbg("Exit");
+ return ret;
+}
+
+/*
+ * Operation - Send Terminal Response
+ *
+ * Request -
+ * AT-Command: AT+SATR
+ *
+ * Response - OK
+ * Success: (NO Result)
+ * OK
+ * Failure:
+ * +CME ERROR: <error>
+ */
+static TelReturn imc_sat_send_terminal_response(CoreObject *co,
+ const TelSatRequestTerminalResponseData *terminal_rsp_data,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ gchar *at_cmd;
+ gint terminal_resp_len = 0;
+ gchar terminal_resp[PROACTV_CMD_LEN];
+ gint i = 0;
+ gchar *hex_string = NULL;
+ gboolean encode_ret = FALSE;
+
+ ImcRespCbData *resp_cb_data;
+ TelReturn ret;
+
+ dbg("Entry");
+
+ encode_ret = tcore_sat_encode_terminal_response(terminal_rsp_data,
+ (gchar *)terminal_resp, (gint *)&terminal_resp_len);
+ if (!encode_ret) {
+ err("Envelope Command encoding failed");
+ return TEL_RETURN_FAILURE;
+ }
+
+ dbg("terminal_resp after encoding: %s", terminal_resp);
+ dbg("terminal_resp length after encoding:[%d]", strlen(terminal_resp));
+ if (terminal_resp_len == 0) {
+ err("Terminal Response length after encoding is NULL");
+ return TEL_RETURN_INVALID_PARAMETER;
+ }
+ hex_string = calloc((terminal_resp_len * 2) + 1, 1);
+
+ for (i = 0; i < terminal_resp_len * 2; i += 2) {
+ gchar value = 0;
+ value = (terminal_resp[i / 2] & 0xf0) >> 4;
+ if (value < 0xA)
+ hex_string[i] = ((terminal_resp[i / 2] & 0xf0) >> 4) + '0';
+ else
+ hex_string[i] = ((terminal_resp[i / 2] & 0xf0) >> 4) + 'A' - 10;
+
+ value = terminal_resp[i / 2] & 0x0f;
+ if (value < 0xA)
+ hex_string[i + 1] = (terminal_resp[i / 2] & 0x0f) + '0';
+ else
+ hex_string[i + 1] = (terminal_resp[i / 2] & 0x0f) + 'A' - 10;
+ }
+ dbg("hex_string: %s", hex_string);
+
+ /* AT-Command */
+ at_cmd = g_strdup_printf("AT+SATR=\"%s\"", hex_string);
+
+ resp_cb_data = imc_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_imc_sat_send_terminal_response, resp_cb_data,
+ on_send_imc_request, NULL,
+ 0, NULL, NULL);
+ IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Send Terminal Response");
+
+ /* Free resources */
+ tcore_free(at_cmd);
+ dbg("Exit");
+ return ret;
+}
+
+/*
+ * Operation - Send User Confirmation
+ *
+ * Request -
+ * AT-Command: AT+SATD
+ *
+ * Response - OK
+ * Success: (NO Result)
+ * OK
+ * Failure:
+ * +CME ERROR: <error>
+ */
+static TelReturn imc_sat_send_user_confirmation(CoreObject *co,
+ const TelSatRequestUserConfirmationData *user_conf_data,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ gchar *at_cmd;
+ guint usr_conf;
+ ImcRespCbData *resp_cb_data;
+ TelReturn ret;
+
+ dbg("Entry");
+
+ usr_conf = (guint)user_conf_data->user_conf;
+ dbg("User confirmation:[%d]", usr_conf);
+
+ /* AT-Command */
+ at_cmd = g_strdup_printf("AT+SATD=%d", usr_conf);
+
+ resp_cb_data = imc_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_imc_sat_send_user_confirmation, resp_cb_data,
+ on_send_imc_request, NULL,
+ 0, NULL, NULL);
+ IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Send User Confirmation");
+
+ /* Free resources */
+ tcore_free(at_cmd);
+ dbg("Exit");
+ return ret;
+
+}
+
+/* SAT Operations */
+static TcoreSatOps imc_sat_ops = {
+ .send_envelope = imc_sat_send_envelope,
+ .send_terminal_response = imc_sat_send_terminal_response,
+ .send_user_confirmation = imc_sat_send_user_confirmation
+};
+
+/* SAT Init */
+gboolean imc_sat_init(TcorePlugin *p, CoreObject *co)
+{
+ dbg("Entry");
+
+ /* Set operations */
+ tcore_sat_set_ops(co, &imc_sat_ops);
+
+ /* Add Callbacks */
+ /*
+ * At present keeping the same notification processing for
+ * both SATI and SATN command. But in future notification processing
+ * will be seperated for both command depending on SAT re-architecure.
+ */
+ tcore_object_add_callback(co, "+SATI",
+ on_notification_imc_sat_proactive_command, NULL);
+ tcore_object_add_callback(co, "+SATN",
+ on_notification_imc_sat_proactive_command, NULL);
+ tcore_object_add_callback(co, "+SATF",
+ on_response_imc_sat_terminal_response_confirm, NULL);
+
+ /* Hooks */
+ tcore_plugin_add_notification_hook(p,
+ TCORE_NOTIFICATION_SIM_STATUS, on_hook_imc_sim_status, co);
+
+ dbg("Exit");
+ return TRUE;
+}
+
+/* SAT Exit */
+void imc_sat_exit(TcorePlugin *p, CoreObject *co)
+{
+ dbg("Exit");
+}
--- /dev/null
+/*
+ * tel-plugin-imc
+ *
+ * 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 "imc_sim.h"
+#include "imc_common.h"
+
+#define ENABLE_FLAG 1
+#define DISABLE_FLAG 2
+
+#define IMC_SIM_ACCESS_READ_BINARY 176
+#define IMC_SIM_ACCESS_READ_RECORD 178
+#define IMC_SIM_ACCESS_GET_RESPONSE 192
+#define IMC_SIM_ACCESS_UPDATE_BINARY 214
+#define IMC_SIM_ACCESS_UPDATE_RECORD 220
+
+#define IMC_SIM_READ_FILE(co, cb, cb_data, fileId, ret) \
+{ \
+ ImcSimMetaInfo file_meta = {0, }; \
+ ImcRespCbData *resp_cb_data = NULL; \
+ \
+ file_meta.file_id = fileId; \
+ file_meta.file_result = TEL_SIM_RESULT_FAILURE; \
+ \
+ resp_cb_data = imc_create_resp_cb_data(cb, cb_data, &file_meta, sizeof(ImcSimMetaInfo)); \
+ \
+ ret = __imc_sim_get_response(co, resp_cb_data); \
+ dbg("Request reading '%s' - [%s]", #fileId, (ret == TEL_RETURN_SUCCESS ? "SUCCESS" : "FAILURE")); \
+}
+
+typedef enum {
+ IMC_SIM_FILE_TYPE_DEDICATED = 0x00, /**< Dedicated */
+ IMC_SIM_FILE_TYPE_TRANSPARENT = 0x01, /**< Transparent -binary type*/
+ IMC_SIM_FILE_TYPE_LINEAR_FIXED = 0x02, /**< Linear fixed - record type*/
+ IMC_SIM_FILE_TYPE_CYCLIC = 0x04, /**< Cyclic - record type*/
+ IMC_SIM_FILE_TYPE_INVALID_TYPE = 0xFF /**< Invalid type */
+} ImcSimFileType;
+
+typedef enum {
+ IMC_SIM_CURR_SEC_OP_PIN1_VERIFY,
+ IMC_SIM_CURR_SEC_OP_PIN2_VERIFY,
+ IMC_SIM_CURR_SEC_OP_PUK1_VERIFY,
+ IMC_SIM_CURR_SEC_OP_PUK2_VERIFY,
+ IMC_SIM_CURR_SEC_OP_SIM_VERIFY,
+ IMC_SIM_CURR_SEC_OP_ADM_VERIFY,
+ IMC_SIM_CURR_SEC_OP_PIN1_CHANGE,
+ IMC_SIM_CURR_SEC_OP_PIN2_CHANGE,
+ IMC_SIM_CURR_SEC_OP_PIN1_ENABLE,
+ IMC_SIM_CURR_SEC_OP_PIN1_DISABLE,
+ IMC_SIM_CURR_SEC_OP_PIN2_ENABLE,
+ IMC_SIM_CURR_SEC_OP_PIN2_DISABLE, // 10
+ IMC_SIM_CURR_SEC_OP_SIM_ENABLE,
+ IMC_SIM_CURR_SEC_OP_SIM_DISABLE,
+ IMC_SIM_CURR_SEC_OP_NET_ENABLE,
+ IMC_SIM_CURR_SEC_OP_NET_DISABLE,
+ IMC_SIM_CURR_SEC_OP_NS_ENABLE,
+ IMC_SIM_CURR_SEC_OP_NS_DISABLE,
+ IMC_SIM_CURR_SEC_OP_SP_ENABLE,
+ IMC_SIM_CURR_SEC_OP_SP_DISABLE,
+ IMC_SIM_CURR_SEC_OP_CP_ENABLE,
+ IMC_SIM_CURR_SEC_OP_CP_DISABLE, // 20
+ IMC_SIM_CURR_SEC_OP_FDN_ENABLE,
+ IMC_SIM_CURR_SEC_OP_FDN_DISABLE,
+ IMC_SIM_CURR_SEC_OP_PIN1_STATUS,
+ IMC_SIM_CURR_SEC_OP_PIN2_STATUS,
+ IMC_SIM_CURR_SEC_OP_FDN_STATUS,
+ IMC_SIM_CURR_SEC_OP_NET_STATUS,
+ IMC_SIM_CURR_SEC_OP_NS_STATUS,
+ IMC_SIM_CURR_SEC_OP_SP_STATUS,
+ IMC_SIM_CURR_SEC_OP_CP_STATUS,
+ IMC_SIM_CURR_SEC_OP_SIM_STATUS,
+ IMC_SIM_CURR_SEC_OP_SIM_UNKNOWN = 0xff
+} ImcSimCurrSecOp;
+
+typedef struct {
+ guint smsp_count; /**< SMSP record count */
+ guint smsp_rec_len; /**< SMSP record length */
+} ImcSimPrivateInfo;
+
+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 */
+ ImcSimFileType file_type; /**< File type and structure */
+ ImcSimCurrSecOp 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*/
+} ImcSimMetaInfo;
+
+/* Utility Function Declaration */
+static TelSimResult __imc_sim_decode_status_word(unsigned short status_word1, unsigned short status_word2);
+static void __imc_sim_update_sim_status(CoreObject *co, TelSimCardStatus sim_status);
+static void __imc_sim_notify_sms_state(CoreObject *co, gboolean sms_ready);
+static TelReturn __imc_sim_start_to_cache(CoreObject *co);
+static gboolean __imc_sim_get_sim_type(CoreObject *co, TcoreObjectResponseCallback cb, void *cb_data);
+static void __imc_sim_next_from_read_binary(CoreObject *co, ImcRespCbData *resp_cb_data, TelSimResult sim_result, gboolean decode_ret);
+static void __imc_sim_next_from_get_response(CoreObject *co, ImcRespCbData *resp_cb_data, TelSimResult sim_result);
+static TelReturn __imc_sim_update_file(CoreObject *co, ImcRespCbData *resp_cb_data, int cmd, TelSimFileId ef,
+ int p1, int p2, int p3, char *encoded_data);
+static void __imc_sim_read_record(CoreObject *co, ImcRespCbData *resp_cb_data);
+static void __imc_sim_read_binary(CoreObject *co, ImcRespCbData *resp_cb_data);
+static TelReturn __imc_sim_get_response (CoreObject *co, ImcRespCbData *resp_cb_data);
+static TelReturn __imc_sim_get_retry_count(CoreObject *co, ImcRespCbData *resp_cb_data);
+static TelSimLockType __imc_sim_lock_type(int lock_type);
+static char *__imc_sim_get_fac_from_lock_type(TelSimLockType lock_type, ImcSimCurrSecOp *sec_op, int flag);
+static int __imc_sim_get_lock_type(ImcSimCurrSecOp sec_op);
+
+/* Internal Response Functions*/
+static void __on_response_imc_sim_get_sim_type_internal(CoreObject *co, gint result, const void *response, void *user_data);
+static void __on_response_imc_sim_get_sim_type(TcorePending *p, guint data_len, const void *data, void *user_data);
+static void __on_response_imc_sim_read_data(TcorePending *p, guint data_len, const void *data, void *user_data);
+static void __on_response_imc_sim_get_response(TcorePending *p, guint data_len, const void *data, void *user_data);
+static void __on_response_imc_sim_get_retry_count(TcorePending *p, guint data_len, const void *data, void *user_data);
+static void __on_response_imc_sim_update_file(TcorePending *p, guint data_len, const void *data, void *user_data);
+
+/* GET SMSP info for SMS module */
+gboolean imc_sim_get_smsp_info(TcorePlugin *plugin, int *rec_count, int *rec_len)
+{
+ CoreObject *co = NULL;
+ ImcSimPrivateInfo *priv_info = NULL;
+
+ dbg("Entry");
+
+ co = tcore_plugin_ref_core_object(plugin, CORE_OBJECT_TYPE_SIM);
+ priv_info = tcore_sim_ref_userdata(co);
+ if(!priv_info)
+ return FALSE;
+
+ *rec_count = priv_info->smsp_count;
+ *rec_len = priv_info->smsp_rec_len;
+
+ dbg("smsp_count:[%d], smsp_rec_len:[%d]", priv_info->smsp_count, priv_info->smsp_rec_len);
+ return TRUE;
+}
+
+static void __imc_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 __imc_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 __imc_sim_update_sim_status(CoreObject *co, TelSimCardStatus sim_status)
+{
+ TelSimCardStatus curr_sim_status;
+
+ /*
+ * Send SIM Init status, if not sent already
+ */
+ (void)tcore_sim_get_status(co, &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_status);
+ sim_status_noti.status = sim_status;
+ tcore_sim_get_identification(co, &sim_status_noti.change_status);
+
+ /* Send notification: SIM Status */
+ tcore_object_send_notification(co,
+ TCORE_NOTIFICATION_SIM_STATUS,
+ sizeof(sim_status_noti), &sim_status_noti);
+ }
+}
+
+static void __imc_sim_notify_sms_state(CoreObject *co,
+ gboolean sms_ready)
+{
+ TcorePlugin *plugin;
+ CoreObject *co_sms;
+ gboolean sms_status = FALSE;
+
+ dbg("Entry");
+
+ plugin = tcore_object_ref_plugin(co);
+ co_sms = tcore_plugin_ref_core_object(plugin, CORE_OBJECT_TYPE_SMS);
+ tcore_check_return_assert(co_sms != NULL);
+
+ (void)tcore_sms_get_ready_status(co_sms, &sms_status);
+ if (sms_status == sms_ready) {
+ dbg("No change in SMS Status: [%s]",
+ (sms_status ? "INITIALIZED" : "UNINITIALIZED"));
+ } else {
+ TelSimCardStatus sim_status;
+
+ /* Update SMS State */
+ tcore_sms_set_ready_status(co_sms, sms_ready);
+
+ dbg("SMS Status - Changed [%s] --> [%s]",
+ (sms_status ? "INITIALIZED" : "UNINITIALIZED"),
+ (sms_ready ? "INITIALIZED" : "UNINITIALIZED"));
+
+ /*
+ * Send SMS device ready notification, if SIM is initialiazed.
+ */
+ (void)tcore_sim_get_status(co, &sim_status);
+ if (sim_status == TEL_SIM_STATUS_SIM_INIT_COMPLETED) {
+ /* Send notification: SMS Device ready */
+ tcore_object_send_notification(co_sms,
+ TCORE_NOTIFICATION_SMS_DEVICE_READY,
+ sizeof(sms_ready), &sms_ready);
+ }
+ }
+}
+
+TelReturn __imc_sim_start_to_cache(CoreObject *co)
+{
+ TelReturn ret;
+ IMC_SIM_READ_FILE(co, NULL, NULL, TEL_SIM_EF_IMSI, ret);
+ IMC_SIM_READ_FILE(co, NULL, NULL, TEL_SIM_EF_CPHS_CPHS_INFO, ret);
+ IMC_SIM_READ_FILE(co, NULL, NULL, TEL_SIM_EF_ICCID, ret);
+ IMC_SIM_READ_FILE(co, NULL, NULL, TEL_SIM_EF_SPN, ret);
+ IMC_SIM_READ_FILE(co, NULL, NULL, TEL_SIM_EF_SST, ret);
+ IMC_SIM_READ_FILE(co, NULL, NULL, TEL_SIM_EF_ECC, ret);
+ IMC_SIM_READ_FILE(co, NULL, NULL, TEL_SIM_EF_MSISDN, ret);
+ IMC_SIM_READ_FILE(co, NULL, NULL, TEL_SIM_EF_SMSP, ret);
+
+ return ret;
+}
+
+static void __on_response_imc_sim_get_sim_type_internal(CoreObject *co,
+ gint result, const void *response, void *user_data)
+{
+ dbg("SIM Response - SIM Type (internal): [+XUICC]");
+
+ if (result == TEL_SIM_RESULT_SUCCESS) {
+ TelSimCardType *sim_type = (TelSimCardType *)response;
+ dbg("SIM Type: [%d]", *sim_type);
+
+ /* Update SIM type */
+ tcore_sim_set_type(co, *sim_type);
+ if (*sim_type != TEL_SIM_CARD_TYPE_UNKNOWN) {
+ TelReturn ret;
+
+ /* Start Caching SIM files */
+ ret = __imc_sim_start_to_cache(co);
+
+ /* Send SIM Type notification */
+ tcore_object_send_notification(co,
+ TCORE_NOTIFICATION_SIM_TYPE,
+ sizeof(TelSimCardType), sim_type);
+ }
+ }
+}
+
+static void __on_response_imc_sim_get_sim_type(TcorePending *p,
+ guint data_len, const void *data, void *user_data)
+{
+ const TcoreAtResponse *at_resp = data;
+ CoreObject *co = tcore_pending_ref_core_object(p);
+ ImcRespCbData *resp_cb_data = user_data;
+ TelSimCardType sim_type = TEL_SIM_CARD_TYPE_UNKNOWN;
+
+ TelSimResult result = TEL_SIM_RESULT_FAILURE;
+
+ dbg("SIM Response - SIM Type: [+XUICC]");
+
+ 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;
+
+ line = (const gchar *)at_resp->lines->data;
+
+ /*
+ * Tokenize
+ *
+ * +XUICC: <state>
+ */
+ tokens = tcore_at_tok_new(line);
+
+ /* <state> */
+ if (g_slist_length(tokens) == 1) {
+ guint state = atoi(g_slist_nth_data(tokens, 0));
+
+ if (state == 0) /* 0 - 2G SIM */
+ sim_type = TEL_SIM_CARD_TYPE_GSM;
+ else if (state == 1) /* 1 - 3G SIM */
+ sim_type = TEL_SIM_CARD_TYPE_USIM;
+
+ 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, (gint)result, &sim_type, resp_cb_data->cb_data);
+
+ /* Free callback data */
+ imc_destroy_resp_cb_data(resp_cb_data);
+}
+
+/*
+ * Operation - get_sim_type
+ *
+ * Request -
+ * AT-Command: AT+XUICC?
+ *
+ * Response - sim_type (TelSimCardType)
+ * Success: (Single line) -
+ * + XUICC: <state>
+ * OK
+ * Failure:
+ * +CME ERROR: <error>
+ */
+gboolean __imc_sim_get_sim_type(CoreObject *co,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ ImcRespCbData *resp_cb_data;
+ TelReturn ret;
+
+ /* Response callback data */
+ resp_cb_data = imc_create_resp_cb_data(cb, cb_data,
+ NULL, 0);
+
+ /* Send Request to modem */
+ ret = tcore_at_prepare_and_send_request(co,
+ "AT+XUICC?", "+XUICC:",
+ TCORE_AT_COMMAND_TYPE_SINGLELINE,
+ TCORE_PENDING_PRIORITY_DEFAULT,
+ NULL,
+ __on_response_imc_sim_get_sim_type, resp_cb_data,
+ on_send_imc_request, NULL,
+ 0, NULL, NULL);
+ IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Get SIM Type");
+
+ return ret;
+}
+
+static void __imc_sim_process_sim_status(CoreObject *co, guint sim_state)
+{
+ TelSimCardStatus sim_card_status;
+
+ switch (sim_state) {
+ case 0:
+ sim_card_status = TEL_SIM_STATUS_CARD_NOT_PRESENT;
+ dbg("NO SIM");
+ break;
+
+ case 1:
+ sim_card_status = TEL_SIM_STATUS_SIM_PIN_REQUIRED;
+ dbg("PIN REQUIRED");
+ break;
+
+ case 2:
+ sim_card_status = TEL_SIM_STATUS_SIM_INITIALIZING;
+ dbg("PIN DISABLED AT BOOT UP");
+ break;
+
+ case 3:
+ sim_card_status = TEL_SIM_STATUS_SIM_INITIALIZING;
+ dbg("PIN VERIFIED");
+ break;
+
+ case 4:
+ sim_card_status = TEL_SIM_STATUS_SIM_PUK_REQUIRED;
+ dbg("PUK REQUIRED");
+ break;
+
+ case 5:
+ sim_card_status = TEL_SIM_STATUS_SIM_PUK_REQUIRED;
+ dbg("CARD PERMANENTLY BLOCKED");
+ break;
+
+ case 6:
+ sim_card_status = TEL_SIM_STATUS_CARD_ERROR;
+ dbg("SIM CARD ERROR");
+ break;
+
+ case 7:
+ sim_card_status = TEL_SIM_STATUS_SIM_INIT_COMPLETED;
+ dbg("SIM INIT COMPLETED");
+ break;
+
+ case 8:
+ sim_card_status = TEL_SIM_STATUS_CARD_ERROR;
+ dbg("SIM CARD ERROR");
+ break;
+
+ case 9:
+ sim_card_status = TEL_SIM_STATUS_CARD_REMOVED;
+ dbg("SIM REMOVED");
+ break;
+
+ case 12:
+ dbg("SIM SMS Ready");
+
+ /* Notify SMS status */
+ return __imc_sim_notify_sms_state(co, TRUE);
+
+ case 99:
+ sim_card_status = TEL_SIM_STATUS_UNKNOWN;
+ dbg("SIM STATE UNKNOWN");
+ break;
+
+ default:
+ err("Unknown/Unsupported SIM state: [%d]", sim_state);
+ return;
+ }
+
+ switch (sim_card_status) {
+ case TEL_SIM_STATUS_SIM_INIT_COMPLETED: {
+ TelSimCardType sim_type;
+
+ dbg("SIM INIT COMPLETED");
+
+ (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
+ */
+ (void)__imc_sim_get_sim_type(co,
+ __on_response_imc_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 __imc_sim_update_sim_status(co, sim_card_status);
+}
+
+static void __on_response_imc_sim_get_sim_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);
+ ImcRespCbData *resp_cb_data = (ImcRespCbData *)user_data;
+ dbg("Enter");
+
+ dbg("SIM Response - SIM status: [+XSIMSTATE]");
+
+ 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 = NULL;
+
+ /* Process +XSIMSTATE response */
+ line = (const gchar *) (at_resp->lines->data);
+ if (line != NULL) {
+ GSList *tokens;
+ guint sim_state, sms_state;
+
+ /*
+ * Tokenize
+ *
+ * +XSIMSTATE: <mode>,<SIM state>,<PB Ready>,<SMS Ready>
+ */
+ tokens = tcore_at_tok_new(line);
+
+ if (g_slist_length(tokens) == 4) {
+ /* <SIM state> */
+ sim_state = atoi(g_slist_nth_data(tokens, 1));
+
+ /* Process SIM Status */
+ __imc_sim_process_sim_status(co, sim_state);
+
+ /* <SMS Ready> */
+ sms_state = atoi(g_slist_nth_data(tokens, 3));
+
+ /* Notify SMS status */
+ __imc_sim_notify_sms_state(co, (sms_state > 0));
+
+ } else {
+ err("Invalid message");
+ }
+
+ tcore_at_tok_free(tokens);
+ }
+ }
+ }
+
+ /* Free callback data */
+ imc_destroy_resp_cb_data(resp_cb_data);
+}
+
+/*
+ * Operation - get_sim_status
+ *
+ * Request -
+ * AT-Command: AT+XSIMSTATE?
+ *
+ * Response - sim_status
+ * Success: (Single line) -
+ * +XSIMSTATE: <mode>,<SIM state>,<PB Ready>,<SMS Ready>
+ * OK
+ * Failure:
+ * +CME ERROR: <error>
+ */
+static gboolean __imc_sim_get_sim_status(CoreObject *co,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ ImcRespCbData *resp_cb_data;
+ TelReturn ret;
+
+ /* Response callback data */
+ resp_cb_data = imc_create_resp_cb_data(cb, cb_data,
+ NULL, 0);
+
+ /* Send Request to modem */
+ ret = tcore_at_prepare_and_send_request(co,
+ "AT+XSIMSTATE?", "+XSIMSTATE:",
+ TCORE_AT_COMMAND_TYPE_SINGLELINE,
+ TCORE_PENDING_PRIORITY_DEFAULT,
+ NULL,
+ __on_response_imc_sim_get_sim_status, resp_cb_data,
+ on_send_imc_request, NULL,
+ 0, NULL, NULL);
+ IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Get SIM Status");
+
+ return TRUE;
+}
+
+static void __imc_sim_next_from_read_binary(CoreObject *co, ImcRespCbData *resp_cb_data, TelSimResult sim_result, gboolean decode_ret)
+{
+ ImcSimMetaInfo *file_meta = (ImcSimMetaInfo *)IMC_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;
+ __imc_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;
+ __imc_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++;
+ __imc_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:
+ if (resp_cb_data->cb) {
+ resp_cb_data->cb(co, (gint)sim_result, &file_meta->imsi, resp_cb_data->cb_data);
+ } else {
+ file_meta->file_id = TEL_SIM_EF_CPHS_CPHS_INFO;
+ file_meta->file_result = TEL_SIM_RESULT_FAILURE;
+ __imc_sim_get_response(co, resp_cb_data);
+ }
+ /* Update SIM INIT status - INIT COMPLETE */
+ __imc_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) {
+ guint i;
+ dbg("rec_count [%d], msisdn_count[%d]", file_meta->rec_count,
+ file_meta->files.data.msisdn_list.count);
+ if (resp_cb_data->cb) {
+ resp_cb_data->cb(co, (gint)sim_result,
+ &file_meta->files.data.msisdn_list, resp_cb_data->cb_data);
+ }
+
+ /* Free resources */
+ for (i = 0; i < file_meta->files.data.msisdn_list.count; i++) {
+ tcore_free(file_meta->files.data.msisdn_list.list[i].alpha_id);
+ tcore_free(file_meta->files.data.msisdn_list.list[i].num);
+ }
+ tcore_free(file_meta->files.data.msisdn_list.list);
+ } else {
+ file_meta->current_index++;
+ __imc_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++;
+ __imc_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++;
+ __imc_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++;
+ __imc_sim_read_record(co, resp_cb_data);
+ }
+ break;
+
+ case TEL_SIM_EF_CPHS_OPERATOR_NAME_STRING:
+ {
+ ImcSimMetaInfo *file_meta_new = (ImcSimMetaInfo *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
+
+ file_meta->files.result = sim_result;
+ if (decode_ret == TRUE && sim_result == TEL_SIM_RESULT_SUCCESS) {
+ file_meta_new->files.data.cphs_net.full_name = file_meta->files.data.cphs_net.full_name;
+ dbg("file_meta_new->files.data.cphs_net.full_name[%s]", file_meta_new->files.data.cphs_net.full_name);
+ }
+
+ file_meta_new->file_id = TEL_SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING;
+ file_meta_new->file_result = TEL_SIM_RESULT_FAILURE;
+
+ __imc_sim_get_response(co, resp_cb_data);
+ }
+ break;
+
+ case TEL_SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING:
+ if (resp_cb_data->cb)
+ resp_cb_data->cb(co, (gint)sim_result, &file_meta->files.data.cphs_net, resp_cb_data->cb_data);
+
+ tcore_free(file_meta->files.data.cphs_net.full_name);
+ tcore_free(file_meta->files.data.cphs_net.short_name);
+ file_meta->files.data.cphs_net.full_name = NULL;
+ file_meta->files.data.cphs_net.short_name = NULL;
+ 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 __imc_sim_next_from_get_response(CoreObject *co, ImcRespCbData *resp_cb_data, TelSimResult sim_result)
+{
+ ImcSimMetaInfo *file_meta = (ImcSimMetaInfo *)IMC_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;
+ if (file_meta->file_id != TEL_SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING)
+ 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)");
+ __imc_sim_read_binary(co, resp_cb_data);
+ } else {
+ tcore_sim_get_type(co, &card_type);
+ if (TEL_SIM_CARD_TYPE_GSM == card_type) {
+ ImcSimMetaInfo 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(ImcSimMetaInfo));
+
+ __imc_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)");
+ __imc_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) {
+ ImcSimMetaInfo 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(ImcSimMetaInfo));
+
+ __imc_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)");
+ __imc_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) {
+ __imc_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++;
+ __imc_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:
+ __imc_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);
+ __imc_sim_read_binary(co, resp_cb_data);
+ } else {
+ tcore_sim_set_cphs_status(co, FALSE);
+ 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++;
+ __imc_sim_read_record(co, resp_cb_data);
+ break;
+
+ case TEL_SIM_EF_MSISDN:
+ file_meta->files.data.msisdn_list.list =
+ tcore_malloc0(sizeof(TelSimSubscriberInfo) * file_meta->rec_count);
+
+ 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:
+ file_meta->current_index++;
+ __imc_sim_read_record(co, resp_cb_data);
+ break;
+
+ case TEL_SIM_EF_SMSP:
+ {
+ ImcSimPrivateInfo *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;
+}
+
+static void __on_response_imc_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;
+ ImcRespCbData *resp_cb_data = (ImcRespCbData *) user_data;
+ ImcSimMetaInfo *file_meta = (ImcSimMetaInfo *)IMC_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 = __imc_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");
+}
+
+static void __on_response_imc_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;
+ int res_len;
+ int sw1 = 0;
+ int sw2 = 0;
+ TelSimCardType card_type = TEL_SIM_CARD_TYPE_UNKNOWN;
+ ImcRespCbData *resp_cb_data = (ImcRespCbData *) user_data;
+ ImcSimMetaInfo *file_meta = (ImcSimMetaInfo *)IMC_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) != 3) {
+ 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, (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);
+ dr = tcore_sim_decode_imsi((unsigned char *)res, res_len, &file_meta->imsi);
+ if (dr == FALSE) {
+ err("IMSI decoding failed");
+ } else {
+ __imc_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 = tcore_malloc0(sizeof(TelSimSubscriberInfo));
+ 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 */
+ dbg("Freeing resources");
+ tcore_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) {
+ guint count = file_meta->files.data.mw.profile_count;
+
+ memcpy(&file_meta->files.data.mw.mw[count], mw, sizeof(TelSimMwis));
+
+ /**
+ * The Profile Identity shall be between 1 and 4 as defined
+ * in TS 23.097 for MSP
+ */
+ file_meta->files.data.mw.mw[count].profile_id = count+1;
+
+ 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:
+ file_meta->files.data.cphs_net.full_name = tcore_malloc0(TEL_SIM_CPHS_OPERATOR_NAME_LEN_MAX+1);
+ 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:
+ file_meta->files.data.cphs_net.short_name = tcore_malloc0(TEL_SIM_CPHS_OPERATOR_NAME_SHORT_FORM_LEN_MAX+1);
+ 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 = __imc_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 */
+ __imc_sim_next_from_read_binary(tcore_pending_ref_core_object(p), resp_cb_data, sim_result, dr);
+
+ dbg("Exit");
+}
+
+static void __on_response_imc_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;
+ ImcRespCbData *resp_cb_data = (ImcRespCbData *)user_data;
+ ImcSimMetaInfo *file_meta =
+ (ImcSimMetaInfo *)IMC_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 = IMC_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 */
+ IMC_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 = IMC_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 */
+ IMC_SWAP_BYTES_16(record_len);
+ ptr_data = ptr_data + 2;
+ num_of_records = *ptr_data++;
+ file_type = IMC_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 */
+ IMC_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 */
+ IMC_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 */
+ IMC_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 */
+ IMC_SWAP_BYTES_16(file_size);
+ /* parsed file size */
+ ptr_data = ptr_data + 2;
+ /* file id */
+ memcpy(&file_id, ptr_data, 2);
+ IMC_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) ? IMC_SIM_FILE_TYPE_TRANSPARENT : IMC_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 = IMC_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 = __imc_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 __imc_sim_next_from_get_response");
+ __imc_sim_next_from_get_response(co, resp_cb_data, sim_result);
+ dbg("Exit");
+}
+
+static TelReturn __imc_sim_update_file(CoreObject *co, ImcRespCbData *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;
+ ImcSimMetaInfo *file_meta = (ImcSimMetaInfo *)IMC_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_imc_sim_update_file, resp_cb_data,
+ on_send_imc_request, NULL, 0, NULL, NULL);
+
+ IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Update SIM File");
+
+ tcore_free(encoded_data);
+ g_free(cmd_str);
+
+ dbg("Exit");
+ return ret;
+}
+static void __imc_sim_read_record(CoreObject *co, ImcRespCbData *resp_cb_data)
+{
+ gchar *at_cmd = NULL;
+ int p1 = 0;
+ int p2 = 0;
+ int p3 = 0;
+ ImcSimMetaInfo *file_meta = (ImcSimMetaInfo *)IMC_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",
+ IMC_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_imc_sim_read_data, resp_cb_data,
+ on_send_imc_request, NULL, 0, NULL, NULL);
+
+ IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Get File Record");
+
+ dbg("ret:[%d]", ret);
+ g_free(at_cmd);
+
+ dbg("Exit");
+}
+
+static void __imc_sim_read_binary(CoreObject *co, ImcRespCbData *resp_cb_data)
+{
+ gchar *at_cmd = NULL;
+ int p1 = 0;
+ int p2 = 0;
+ int p3 = 0;
+ int offset = 0;
+ ImcSimMetaInfo *file_meta = (ImcSimMetaInfo *)IMC_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",
+ IMC_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_imc_sim_read_data, resp_cb_data,
+ on_send_imc_request, NULL, 0, NULL, NULL);
+
+ IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Get File Data");
+
+ dbg("ret:[%d]", ret);
+ g_free(at_cmd);
+
+ dbg("Exit");
+}
+
+static TelReturn __imc_sim_get_response(CoreObject *co, ImcRespCbData *resp_cb_data)
+{
+ gchar *at_cmd = NULL;
+ ImcSimMetaInfo *file_meta =
+ (ImcSimMetaInfo *)IMC_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",
+ IMC_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_imc_sim_get_response, resp_cb_data,
+ on_send_imc_request, NULL,
+ 0, NULL, NULL);
+ IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Get File Info");
+
+ g_free(at_cmd);
+ dbg("Exit");
+ return ret;
+}
+
+static void __on_response_imc_sim_get_retry_count(TcorePending *p, guint data_len,
+ const void *data, void *user_data)
+{
+ TelSimResult result = TEL_SIM_RESULT_INCORRECT_PASSWORD;
+ const TcoreAtResponse *at_resp = data;
+ ImcRespCbData *resp_cb_data = user_data;
+ CoreObject *co = tcore_pending_ref_core_object(p);
+ ImcSimCurrSecOp *sec_op = NULL;
+ GSList *tokens = NULL;
+ const char *line = NULL;
+ int lock_type = 0;
+ int attempts_left = 0;
+ int time_penalty = 0;
+
+ dbg("Entry");
+
+ tcore_check_return_assert(co != NULL);
+ tcore_check_return_assert(resp_cb_data != NULL);
+
+ sec_op = (ImcSimCurrSecOp *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
+
+ if (at_resp && at_resp->success) {
+ dbg("Sim Get Retry Count [OK]");
+
+ if (at_resp->lines) {
+ line = (const char *)at_resp->lines->data;
+ tokens = tcore_at_tok_new(line);
+ if (g_slist_length(tokens) < 3) {
+ err("Invalid message");
+ goto Failure;
+ }
+ }
+ lock_type = atoi(g_slist_nth_data(tokens, 0));
+ attempts_left = atoi(g_slist_nth_data(tokens, 1));
+ time_penalty = atoi(g_slist_nth_data(tokens, 2));
+
+ dbg("lock_type = %d, attempts_left = %d, time_penalty = %d",
+ lock_type, attempts_left, time_penalty);
+
+ switch (*sec_op) {
+ case IMC_SIM_CURR_SEC_OP_PIN1_VERIFY:
+ case IMC_SIM_CURR_SEC_OP_PIN2_VERIFY:
+ {
+ TelSimSecPinResult verify_pin = {0, };
+
+ if (*sec_op == IMC_SIM_CURR_SEC_OP_PIN1_VERIFY)
+ verify_pin.pin_type = TEL_SIM_PIN_TYPE_PIN1;
+ else if (*sec_op == IMC_SIM_CURR_SEC_OP_PIN2_VERIFY)
+ verify_pin.pin_type = TEL_SIM_PIN_TYPE_PIN2;
+
+ verify_pin.retry_count = attempts_left;
+
+ if(resp_cb_data->cb)
+ resp_cb_data->cb(co, (gint)result,
+ &verify_pin, resp_cb_data->cb_data);
+ break;
+ }
+ case IMC_SIM_CURR_SEC_OP_PUK1_VERIFY:
+ case IMC_SIM_CURR_SEC_OP_PUK2_VERIFY:
+ {
+ TelSimSecPukResult verify_puk = {0, };
+
+ if (*sec_op == IMC_SIM_CURR_SEC_OP_PUK1_VERIFY)
+ verify_puk.puk_type = TEL_SIM_PUK_TYPE_PUK1;
+ else if (*sec_op == IMC_SIM_CURR_SEC_OP_PUK2_VERIFY)
+ verify_puk.puk_type = TEL_SIM_PUK_TYPE_PUK2;
+
+ verify_puk.retry_count = attempts_left;
+
+ if(resp_cb_data->cb)
+ resp_cb_data->cb(co, (gint)result,
+ &verify_puk, resp_cb_data->cb_data);
+ break;
+ }
+ case IMC_SIM_CURR_SEC_OP_PIN1_CHANGE:
+ case IMC_SIM_CURR_SEC_OP_PIN2_CHANGE:
+ {
+ TelSimSecPinResult change_pin = {0, };
+
+ if (*sec_op == IMC_SIM_CURR_SEC_OP_PIN1_CHANGE)
+ change_pin.pin_type = TEL_SIM_PIN_TYPE_PIN1;
+ else if (*sec_op == IMC_SIM_CURR_SEC_OP_PIN2_CHANGE)
+ change_pin.pin_type = TEL_SIM_PIN_TYPE_PIN2;
+
+ change_pin.retry_count = attempts_left;
+
+ if(resp_cb_data->cb)
+ resp_cb_data->cb(co, (gint)result,
+ &change_pin, resp_cb_data->cb_data);
+ break;
+ }
+ case IMC_SIM_CURR_SEC_OP_PIN1_DISABLE:
+ case IMC_SIM_CURR_SEC_OP_PIN2_DISABLE:
+ case IMC_SIM_CURR_SEC_OP_FDN_DISABLE:
+ case IMC_SIM_CURR_SEC_OP_SIM_DISABLE:
+ case IMC_SIM_CURR_SEC_OP_NET_DISABLE:
+ case IMC_SIM_CURR_SEC_OP_NS_DISABLE:
+ case IMC_SIM_CURR_SEC_OP_SP_DISABLE:
+ case IMC_SIM_CURR_SEC_OP_CP_DISABLE:
+ {
+ TelSimFacilityResult disable_facility = {0, };
+ int lock_type;
+
+ lock_type = __imc_sim_get_lock_type(*sec_op);
+ if (lock_type == -1)
+ goto Failure;
+
+ disable_facility.type = lock_type;
+ disable_facility.retry_count = attempts_left;
+
+ if(resp_cb_data->cb)
+ resp_cb_data->cb(co, (gint)result,
+ &disable_facility, resp_cb_data->cb_data);
+ break;
+ }
+ case IMC_SIM_CURR_SEC_OP_PIN1_ENABLE:
+ case IMC_SIM_CURR_SEC_OP_PIN2_ENABLE:
+ case IMC_SIM_CURR_SEC_OP_FDN_ENABLE:
+ case IMC_SIM_CURR_SEC_OP_SIM_ENABLE:
+ case IMC_SIM_CURR_SEC_OP_NET_ENABLE:
+ case IMC_SIM_CURR_SEC_OP_NS_ENABLE:
+ case IMC_SIM_CURR_SEC_OP_SP_ENABLE:
+ case IMC_SIM_CURR_SEC_OP_CP_ENABLE:
+ {
+ TelSimFacilityResult enable_facility = {0, };
+ int lock_type;
+
+ lock_type = __imc_sim_get_lock_type(*sec_op);
+ if (lock_type == -1)
+ goto Failure;
+
+ enable_facility.type = lock_type;
+ enable_facility.retry_count = attempts_left;
+
+ if(resp_cb_data->cb)
+ resp_cb_data->cb(co, (gint)result,
+ &enable_facility, resp_cb_data->cb_data);
+ break;
+ }
+ default:
+ err("Unhandled sec op [%d]", *sec_op);
+ break;
+ }
+
+ tcore_at_tok_free(tokens);
+ imc_destroy_resp_cb_data(resp_cb_data);
+ return;
+ }
+ err("Sim Get Retry Count [NOK]");
+Failure :
+ /*TODO - send response for verify pin, puk etc.,
+ * when get_retry_count fails
+ */
+ tcore_at_tok_free(tokens);
+ imc_destroy_resp_cb_data(resp_cb_data);
+}
+
+static TelReturn __imc_sim_get_retry_count(CoreObject *co,
+ ImcRespCbData *resp_cb_data)
+{
+ TelReturn ret = TEL_RETURN_FAILURE;
+ ImcSimCurrSecOp *sec_op = (
+ ImcSimCurrSecOp *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
+ int lock_type = 0;
+ gchar *cmd_str = NULL;
+
+ dbg("Entry");
+
+ switch (*sec_op) {
+ case IMC_SIM_CURR_SEC_OP_PIN1_VERIFY:
+ case IMC_SIM_CURR_SEC_OP_PIN1_CHANGE:
+ case IMC_SIM_CURR_SEC_OP_PIN1_ENABLE:
+ case IMC_SIM_CURR_SEC_OP_PIN1_DISABLE:
+ lock_type = 1;
+ break;
+ case IMC_SIM_CURR_SEC_OP_PIN2_VERIFY:
+ case IMC_SIM_CURR_SEC_OP_PIN2_CHANGE:
+ case IMC_SIM_CURR_SEC_OP_PIN2_ENABLE:
+ case IMC_SIM_CURR_SEC_OP_PIN2_DISABLE:
+ case IMC_SIM_CURR_SEC_OP_FDN_ENABLE:
+ case IMC_SIM_CURR_SEC_OP_FDN_DISABLE:
+ lock_type = 2;
+ break;
+ case IMC_SIM_CURR_SEC_OP_PUK1_VERIFY:
+ lock_type = 3;
+ break;
+ case IMC_SIM_CURR_SEC_OP_PUK2_VERIFY:
+ lock_type = 4;
+ break;
+ case IMC_SIM_CURR_SEC_OP_NET_ENABLE:
+ case IMC_SIM_CURR_SEC_OP_NET_DISABLE:
+ lock_type = 5;
+ break;
+ case IMC_SIM_CURR_SEC_OP_NS_ENABLE:
+ case IMC_SIM_CURR_SEC_OP_NS_DISABLE:
+ lock_type = 6;
+ break;
+ case IMC_SIM_CURR_SEC_OP_SP_ENABLE:
+ case IMC_SIM_CURR_SEC_OP_SP_DISABLE:
+ lock_type = 7;
+ break;
+ case IMC_SIM_CURR_SEC_OP_CP_ENABLE:
+ case IMC_SIM_CURR_SEC_OP_CP_DISABLE:
+ lock_type = 8;
+ break;
+ case IMC_SIM_CURR_SEC_OP_ADM_VERIFY:
+ lock_type = 9;
+ break;
+ default:
+ break;
+ }
+ cmd_str = g_strdup_printf("AT+XPINCNT=%d", lock_type);
+
+ ret = tcore_at_prepare_and_send_request(co, cmd_str, NULL,
+ TCORE_AT_COMMAND_TYPE_SINGLELINE,
+ TCORE_PENDING_PRIORITY_DEFAULT,
+ NULL,
+ __on_response_imc_sim_get_retry_count,
+ resp_cb_data,
+ on_send_imc_request,
+ NULL, 0, NULL, NULL);
+
+ IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Get Retry Count");
+ g_free(cmd_str);
+ return ret;
+}
+
+static TelSimLockType __imc_sim_lock_type(int lock_type)
+{
+ switch(lock_type) {
+ case 1 :
+ return TEL_SIM_LOCK_SC;
+ case 2 :
+ return TEL_SIM_LOCK_FD;
+ case 5 :
+ return TEL_SIM_LOCK_PN;
+ case 6 :
+ return TEL_SIM_LOCK_PU;
+ case 7 :
+ return TEL_SIM_LOCK_PP;
+ case 8 :
+ return TEL_SIM_LOCK_PC ;
+ case 9 :
+ return TEL_SIM_LOCK_PS ;
+ default :
+ err("Invalid lock_type [%d]", lock_type);
+ return -1;
+ }
+}
+
+static char *__imc_sim_get_fac_from_lock_type(TelSimLockType lock_type,
+ ImcSimCurrSecOp *sec_op, int flag)
+{
+ char *fac = NULL;
+ switch(lock_type) {
+ case TEL_SIM_LOCK_PS :
+ fac = "PS";
+ if (flag == ENABLE_FLAG)
+ *sec_op = IMC_SIM_CURR_SEC_OP_SIM_ENABLE;
+ else if (flag == DISABLE_FLAG)
+ *sec_op = IMC_SIM_CURR_SEC_OP_SIM_DISABLE;
+ else
+ *sec_op = IMC_SIM_CURR_SEC_OP_SIM_STATUS;
+ break;
+ case TEL_SIM_LOCK_SC :
+ fac = "SC";
+ if (flag == ENABLE_FLAG)
+ *sec_op = IMC_SIM_CURR_SEC_OP_PIN1_ENABLE;
+ else if (flag == DISABLE_FLAG)
+ *sec_op = IMC_SIM_CURR_SEC_OP_PIN1_DISABLE;
+ else
+ *sec_op = IMC_SIM_CURR_SEC_OP_PIN1_STATUS;
+ break;
+ case TEL_SIM_LOCK_FD :
+ fac = "FD";
+ if (flag == ENABLE_FLAG)
+ *sec_op = IMC_SIM_CURR_SEC_OP_FDN_ENABLE;
+ else if (flag == DISABLE_FLAG)
+ *sec_op = IMC_SIM_CURR_SEC_OP_FDN_DISABLE;
+ else
+ *sec_op = IMC_SIM_CURR_SEC_OP_FDN_STATUS;
+ break;
+ case TEL_SIM_LOCK_PN :
+ fac = "PN";
+ if (flag == ENABLE_FLAG)
+ *sec_op = IMC_SIM_CURR_SEC_OP_NET_ENABLE;
+ else if (flag == DISABLE_FLAG)
+ *sec_op = IMC_SIM_CURR_SEC_OP_NET_DISABLE;
+ else
+ *sec_op = IMC_SIM_CURR_SEC_OP_NET_STATUS;
+ break;
+ case TEL_SIM_LOCK_PU :
+ fac = "PU";
+ if (flag == ENABLE_FLAG)
+ *sec_op = IMC_SIM_CURR_SEC_OP_NS_ENABLE;
+ else if (flag == DISABLE_FLAG)
+ *sec_op = IMC_SIM_CURR_SEC_OP_NS_DISABLE;
+ else
+ *sec_op = IMC_SIM_CURR_SEC_OP_NS_STATUS;
+ break;
+ case TEL_SIM_LOCK_PP :
+ fac = "PP";
+ if (flag == ENABLE_FLAG)
+ *sec_op = IMC_SIM_CURR_SEC_OP_SP_ENABLE;
+ else if (flag == DISABLE_FLAG)
+ *sec_op = IMC_SIM_CURR_SEC_OP_SP_DISABLE;
+ else
+ *sec_op = IMC_SIM_CURR_SEC_OP_SP_STATUS;
+ break;
+ case TEL_SIM_LOCK_PC :
+ fac = "PC";
+ if (flag == ENABLE_FLAG)
+ *sec_op = IMC_SIM_CURR_SEC_OP_CP_ENABLE;
+ else if (flag == DISABLE_FLAG)
+ *sec_op = IMC_SIM_CURR_SEC_OP_CP_DISABLE;
+ else
+ *sec_op = IMC_SIM_CURR_SEC_OP_CP_STATUS;
+ break;
+ default :
+ err("Unhandled sim lock type [%d]", lock_type);
+ }
+ return fac;
+}
+
+static int __imc_sim_get_lock_type(ImcSimCurrSecOp sec_op)
+{
+ switch(sec_op) {
+ case IMC_SIM_CURR_SEC_OP_SIM_DISABLE :
+ case IMC_SIM_CURR_SEC_OP_SIM_ENABLE :
+ case IMC_SIM_CURR_SEC_OP_SIM_STATUS :
+ return TEL_SIM_LOCK_PS;
+ case IMC_SIM_CURR_SEC_OP_PIN1_DISABLE :
+ case IMC_SIM_CURR_SEC_OP_PIN1_ENABLE :
+ case IMC_SIM_CURR_SEC_OP_PIN1_STATUS :
+ return TEL_SIM_LOCK_SC;
+ case IMC_SIM_CURR_SEC_OP_FDN_DISABLE :
+ case IMC_SIM_CURR_SEC_OP_FDN_ENABLE :
+ case IMC_SIM_CURR_SEC_OP_FDN_STATUS :
+ return TEL_SIM_LOCK_FD;
+ case IMC_SIM_CURR_SEC_OP_NET_DISABLE :
+ case IMC_SIM_CURR_SEC_OP_NET_ENABLE :
+ case IMC_SIM_CURR_SEC_OP_NET_STATUS :
+ return TEL_SIM_LOCK_PN;
+ case IMC_SIM_CURR_SEC_OP_NS_DISABLE :
+ case IMC_SIM_CURR_SEC_OP_NS_ENABLE :
+ case IMC_SIM_CURR_SEC_OP_NS_STATUS :
+ return TEL_SIM_LOCK_PU;
+ case IMC_SIM_CURR_SEC_OP_SP_DISABLE :
+ case IMC_SIM_CURR_SEC_OP_SP_ENABLE :
+ case IMC_SIM_CURR_SEC_OP_SP_STATUS :
+ return TEL_SIM_LOCK_PP;
+ case IMC_SIM_CURR_SEC_OP_CP_DISABLE :
+ case IMC_SIM_CURR_SEC_OP_CP_ENABLE :
+ case IMC_SIM_CURR_SEC_OP_CP_STATUS :
+ return TEL_SIM_LOCK_PC ;
+ default :
+ err("Invalid sec op [%d]", sec_op);
+ return -1;
+ }
+}
+
+/* Notifications */
+/*
+ * Notification: +XSIM: <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_imc_sim_status(CoreObject *co,
+ const void *event_info, void *user_data)
+{
+ GSList *lines = (GSList *)event_info;
+ const gchar *line;
+
+ dbg("SIM notification - SIM status: [+XSIM]");
+
+ if (g_slist_length(lines) != 1) {
+ err("+XSIM unsolicited message expected to be "
+ "Single line but received multiple lines");
+ return TRUE;
+ }
+
+ line = (const gchar *) (lines->data);
+ if (line != NULL) {
+ GSList *tokens;
+ guint sim_state;
+
+ /*
+ * Tokenize
+ *
+ * +XSIM: <SIM state>
+ */
+ tokens = tcore_at_tok_new(line);
+ if (g_slist_length(tokens) == 1) {
+ /* <SIM state> */
+ sim_state = atoi(g_slist_nth_data(tokens, 0));
+
+ /* Process SIM Status */
+ __imc_sim_process_sim_status(co, sim_state);
+ } else {
+ err("Invalid message");
+ }
+
+ tcore_at_tok_free(tokens);
+ }
+
+ return TRUE;
+}
+
+/* Hooks */
+static TcoreHookReturn on_hook_imc_modem_power(TcorePlugin *source,
+ TcoreNotification command, guint data_len, void *data, void *user_data)
+{
+ CoreObject *co = (CoreObject *)user_data;
+
+ tcore_check_return_value(co != NULL, TCORE_HOOK_RETURN_CONTINUE);
+
+ dbg("Get SIM status");
+ (void)__imc_sim_get_sim_status(co, NULL, NULL);
+
+ return TCORE_HOOK_RETURN_CONTINUE;
+}
+
+/* Response Functions */
+static void on_response_imc_sim_req_authentication(TcorePending *p, guint data_len,
+ const void *data, void *user_data)
+{
+ const TcoreAtResponse *at_resp = data;
+ GSList *tokens = NULL;
+ CoreObject *co = tcore_pending_ref_core_object(p);
+ TelSimAuthenticationResponse auth_resp = {0, };
+ TelSimResult sim_result = TEL_SIM_RESULT_FAILURE;
+ ImcRespCbData *resp_cb_data = user_data;
+ TelSimAuthenticationType *auth_type = (TelSimAuthenticationType *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
+
+ dbg("Entry");
+
+ if (NULL == at_resp) {
+ err("at_resp is NULL");
+ auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
+ goto out;
+ }
+
+ auth_resp.auth_type = *auth_type;
+
+ if (at_resp->success == TRUE) {
+ const char *line;
+ int status;
+
+ dbg("RESPONSE OK");
+ if (at_resp->lines != NULL) {
+ line = at_resp->lines->data;
+ dbg("Received data: [%s]", line);
+ } else {
+ err("at_resp->lines is NULL");
+ auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
+ goto out;
+ }
+
+ tokens = tcore_at_tok_new(line);
+ if (tokens == NULL) {
+ err("tokens is NULL");
+ auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
+ goto out;
+ }
+
+ status = atoi(g_slist_nth_data(tokens, 0));
+ switch (status) {
+ case 0:
+ dbg("Authentications successful");
+ auth_resp.detailed_result = TEL_SIM_AUTH_NO_ERROR;
+ break;
+ case 1:
+ err("Synchronize fail");
+ auth_resp.detailed_result = TEL_SIM_AUTH_SYNCH_FAILURE;
+ goto out;
+ case 2:
+ err("MAC wrong");
+ auth_resp.detailed_result = TEL_SIM_AUTH_MAK_CODE_FAILURE;
+ goto out;
+ case 3:
+ err("Does not support security context");
+ auth_resp.detailed_result = TEL_SIM_AUTH_UNSUPPORTED_CONTEXT;
+ goto out;
+ default:
+ err("Other failure");
+ auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
+ goto out;
+ }
+
+ if (auth_resp.auth_type == TEL_SIM_AUTH_GSM) {
+ char *kc, *sres;
+ char *convert_kc, *convert_sres;
+
+ kc = g_slist_nth_data(tokens, 1);
+ if (kc != NULL) {
+ guint convert_kc_len = 0;
+ kc = tcore_at_tok_extract(kc);
+ dbg("Kc: [%s]", kc);
+
+ tcore_util_hexstring_to_bytes(kc, &convert_kc, &convert_kc_len);
+ if (convert_kc_len && convert_kc_len <= TEL_SIM_AUTH_MAX_RESP_DATA_LEN) {
+ auth_resp.authentication_key_length = convert_kc_len;
+ memcpy(&auth_resp.authentication_key, convert_kc, convert_kc_len);
+ } else {
+ err("Invalid Kc");
+ auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
+ }
+ g_free(kc);
+ g_free(convert_kc);
+ } else {
+ err("Invalid Kc");
+ auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
+ goto out;
+ }
+
+ sres = g_slist_nth_data(tokens, 2);
+ if (sres != NULL) {
+ guint convert_sres_len = 0;
+ sres = tcore_at_tok_extract(sres);
+ dbg("SRES: [%s]", sres);
+
+ tcore_util_hexstring_to_bytes(sres, &convert_sres, &convert_sres_len);
+ if (convert_sres_len && convert_sres_len <= TEL_SIM_AUTH_MAX_RESP_DATA_LEN) {
+ auth_resp.resp_length = convert_sres_len;
+ memcpy(&auth_resp.resp_data, convert_sres, convert_sres_len);
+ } else {
+ err("Invalid SRES");
+ auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
+ }
+ g_free(sres);
+ g_free(convert_sres);
+ } else {
+ err("Invalid SRES");
+ auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
+ goto out;
+ }
+ } else if (auth_resp.auth_type == TEL_SIM_AUTH_3G_CTX) {
+ char *res, *ck, *ik, *kc;
+ char *convert_res, *convert_ck;
+ char *convert_ik, *convert_kc;
+
+ res = g_slist_nth_data(tokens, 1);
+ if (res != NULL) {
+ guint convert_res_len = 0;
+ res = tcore_at_tok_extract(res);
+ dbg("RES/AUTS: [%s]", res);
+
+ tcore_util_hexstring_to_bytes(res, &convert_res, &convert_res_len);
+ if (convert_res_len && convert_res_len <= TEL_SIM_AUTH_MAX_RESP_DATA_LEN) {
+ auth_resp.resp_length = convert_res_len;
+ memcpy(auth_resp.resp_data, convert_res, convert_res_len);
+ } else {
+ err("Invalid RES/AUTS");
+ auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
+ }
+ g_free(res);
+ g_free(convert_res);
+ } else {
+ err("Invalid RES/AUTS");
+ auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
+ goto out;
+ }
+
+ ck = g_slist_nth_data(tokens, 2);
+ if (ck != NULL) {
+ guint convert_ck_len = 0;
+ ck = tcore_at_tok_extract(ck);
+ dbg("CK: [%s]", ck);
+
+ tcore_util_hexstring_to_bytes(ck, &convert_ck, &convert_ck_len);
+ if (convert_ck_len && convert_ck_len <= TEL_SIM_AUTH_MAX_RESP_DATA_LEN) {
+ auth_resp.cipher_length = convert_ck_len;
+ memcpy(&auth_resp.cipher_data, convert_ck, convert_ck_len);
+ } else {
+ err("Invalid CK");
+ auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
+ }
+ g_free(ck);
+ g_free(convert_ck);
+ } else {
+ err("Invalid CK");
+ auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
+ goto out;
+ }
+
+ ik = g_slist_nth_data(tokens, 3);
+ if (ik != NULL) {
+ guint convert_ik_len = 0;
+ ik = tcore_at_tok_extract(ik);
+ dbg("IK: [%s]", ik);
+
+ tcore_util_hexstring_to_bytes(ik, &convert_ik, &convert_ik_len);
+ if (convert_ik_len && convert_ik_len <= TEL_SIM_AUTH_MAX_RESP_DATA_LEN) {
+ auth_resp.integrity_length = convert_ik_len;
+ memcpy(&auth_resp.integrity_data, convert_ik, convert_ik_len);
+ } else {
+ err("Invalid IK");
+ auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
+ }
+ g_free(ik);
+ g_free(convert_ik);
+ } else {
+ err("Invalid IK");
+ auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
+ goto out;
+ }
+
+ kc = g_slist_nth_data(tokens, 4);
+ if (kc != NULL) {
+ guint convert_kc_len = 0;
+ kc = tcore_at_tok_extract(kc);
+ dbg("Kc: [%s]", kc);
+
+ tcore_util_hexstring_to_bytes(kc, &convert_kc, &convert_kc_len);
+ if (convert_kc_len && convert_kc_len <= TEL_SIM_AUTH_MAX_RESP_DATA_LEN) {
+ auth_resp.authentication_key_length = convert_kc_len;
+ memcpy(&auth_resp.authentication_key, convert_kc, convert_kc_len);
+ } else {
+ err("Invalid Kc");
+ auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
+ }
+ g_free(kc);
+ g_free(convert_kc);
+ } else {
+ err("Invalid Kc");
+ auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
+ goto out;
+ }
+ } else {
+ err("Not supported");
+ auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
+ goto out;
+ }
+ sim_result = TEL_SIM_RESULT_SUCCESS;
+ } else {
+ err("RESPONSE NOK");
+ auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
+ }
+
+out:
+ if(resp_cb_data->cb)
+ resp_cb_data->cb(co, (gint)sim_result, &auth_resp, resp_cb_data->cb_data);
+
+ tcore_at_tok_free(tokens);
+}
+
+static void on_response_imc_sim_verify_pins(TcorePending *p, guint data_len,
+ const void *data, void *user_data)
+{
+ const TcoreAtResponse *at_resp = data;
+ ImcRespCbData *resp_cb_data = user_data;
+ CoreObject *co = tcore_pending_ref_core_object(p);
+ TelSimResult result = TEL_SIM_RESULT_FAILURE;
+ ImcSimCurrSecOp *sec_op = NULL;
+ TelSimSecPinResult verify_pin_resp = {0, };
+
+ dbg("Entry");
+
+ tcore_check_return_assert(co != NULL);
+ tcore_check_return_assert(resp_cb_data != NULL);
+
+ sec_op = (ImcSimCurrSecOp *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
+
+ if (at_resp && at_resp->success) {
+ dbg("Sim Verify Pin Response- [OK]");
+
+ result = TEL_SIM_RESULT_SUCCESS;
+
+ if (*sec_op == IMC_SIM_CURR_SEC_OP_PIN1_VERIFY) {
+ TelSimCardStatus status;
+
+ verify_pin_resp.pin_type = TEL_SIM_PIN_TYPE_PIN1;
+
+ tcore_sim_get_status(co, &status);
+ if (status != TEL_SIM_STATUS_SIM_INIT_COMPLETED) {
+ /*Update sim status*/
+ __imc_sim_update_sim_status(co,
+ TEL_SIM_STATUS_SIM_INITIALIZING);
+ }
+ } else if (*sec_op == IMC_SIM_CURR_SEC_OP_PIN2_VERIFY) {
+ verify_pin_resp.pin_type = TEL_SIM_PIN_TYPE_PIN2;
+ }
+
+ /*Invoke callback*/
+ if(resp_cb_data->cb)
+ resp_cb_data->cb(co, (gint)result,
+ &verify_pin_resp,
+ resp_cb_data->cb_data);
+ imc_destroy_resp_cb_data(resp_cb_data);
+ } else {
+ err("Sim Verify Pin Response- [NOK]");
+ /* Get retry count */
+ __imc_sim_get_retry_count(co, resp_cb_data);
+ }
+}
+
+static void on_response_imc_sim_verify_puks(TcorePending *p, guint data_len,
+ const void *data, void *user_data)
+{
+ const TcoreAtResponse *at_resp = data;
+ ImcRespCbData *resp_cb_data = user_data;
+ CoreObject *co = tcore_pending_ref_core_object(p);
+ TelSimResult result = TEL_SIM_RESULT_FAILURE;
+ ImcSimCurrSecOp *sec_op = NULL;
+ TelSimSecPukResult verify_puk_resp = {0, };
+
+ dbg("Entry");
+
+ tcore_check_return_assert(co != NULL);
+ tcore_check_return_assert(resp_cb_data != NULL);
+
+ sec_op = (ImcSimCurrSecOp *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
+
+ if (at_resp && at_resp->success) {
+ dbg("Sim Verify Puk Response- [OK]");
+
+ result = TEL_SIM_RESULT_SUCCESS;
+
+ if (*sec_op == IMC_SIM_CURR_SEC_OP_PUK1_VERIFY) {
+ verify_puk_resp.puk_type = TEL_SIM_PUK_TYPE_PUK1;
+ } else if (*sec_op == IMC_SIM_CURR_SEC_OP_PUK2_VERIFY) {
+ verify_puk_resp.puk_type = TEL_SIM_PUK_TYPE_PUK2;
+ }
+ /*Invoke callback*/
+ if(resp_cb_data->cb)
+ resp_cb_data->cb(co, (gint)result,
+ &verify_puk_resp,
+ resp_cb_data->cb_data);
+ imc_destroy_resp_cb_data(resp_cb_data);
+ } else {
+ err("Sim Verify Puk Response- [NOK]");
+ /* Get retry count */
+ __imc_sim_get_retry_count(co, resp_cb_data);
+ }
+}
+
+static void on_response_imc_sim_change_pins(TcorePending *p, guint data_len,
+ const void *data, void *user_data)
+{
+ const TcoreAtResponse *at_resp = data;
+ ImcRespCbData *resp_cb_data = user_data;
+ CoreObject *co = tcore_pending_ref_core_object(p);
+ TelSimResult result = TEL_SIM_RESULT_FAILURE;
+ ImcSimCurrSecOp *sec_op = NULL;
+ TelSimSecPinResult change_pin_resp = {0, };
+
+ dbg("Entry");
+
+ tcore_check_return_assert(co != NULL);
+ tcore_check_return_assert(resp_cb_data != NULL);
+
+ sec_op = (ImcSimCurrSecOp *)IMC_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 == IMC_SIM_CURR_SEC_OP_PIN1_CHANGE) {
+ change_pin_resp.pin_type = TEL_SIM_PIN_TYPE_PIN1;
+ } else if (*sec_op == IMC_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, (gint)result,
+ &change_pin_resp,
+ resp_cb_data->cb_data);
+ imc_destroy_resp_cb_data(resp_cb_data);
+ } else {
+ err("Sim Change Pin Response- [NOK]");
+ /* Get retry count */
+ __imc_sim_get_retry_count(co, resp_cb_data);
+ }
+}
+
+static void on_response_imc_sim_disable_facility(TcorePending *p, guint data_len,
+ const void *data, void *user_data)
+{
+ const TcoreAtResponse *at_resp = data;
+ ImcRespCbData *resp_cb_data = user_data;
+ CoreObject *co = tcore_pending_ref_core_object(p);
+ TelSimResult result = TEL_SIM_RESULT_FAILURE;
+ ImcSimCurrSecOp *sec_op = NULL;
+ TelSimFacilityResult disable_facility_resp = {0, };
+
+ dbg("Entry");
+
+ tcore_check_return_assert(co != NULL);
+ tcore_check_return_assert(resp_cb_data != NULL);
+
+ sec_op = (ImcSimCurrSecOp *)IMC_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 = __imc_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, (gint)result,
+ NULL,
+ resp_cb_data->cb_data);
+ imc_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, (gint)result,
+ &disable_facility_resp,
+ resp_cb_data->cb_data);
+ imc_destroy_resp_cb_data(resp_cb_data);
+ } else {
+ err("Sim Disable Facility Response- [NOK]");
+ /* Get retry count */
+ __imc_sim_get_retry_count(co, resp_cb_data);
+ }
+}
+
+static void on_response_imc_sim_enable_facility(TcorePending *p, guint data_len,
+ const void *data, void *user_data)
+{
+ const TcoreAtResponse *at_resp = data;
+ ImcRespCbData *resp_cb_data = user_data;
+ CoreObject *co = tcore_pending_ref_core_object(p);
+ TelSimResult result = TEL_SIM_RESULT_FAILURE;
+ ImcSimCurrSecOp *sec_op = NULL;
+ TelSimFacilityResult enable_facility_resp = {0, };
+
+ dbg("Entry");
+
+ tcore_check_return_assert(co != NULL);
+ tcore_check_return_assert(resp_cb_data != NULL);
+
+ sec_op = (ImcSimCurrSecOp *)IMC_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 = __imc_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, (gint)result,
+ NULL,
+ resp_cb_data->cb_data);
+ imc_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, (gint)result,
+ &enable_facility_resp,
+ resp_cb_data->cb_data);
+ imc_destroy_resp_cb_data(resp_cb_data);
+ } else {
+ err("Sim Enable Facility Response- [NOK]");
+ /* Get retry count */
+ __imc_sim_get_retry_count(co, resp_cb_data);
+ }
+}
+
+static void on_response_imc_sim_get_facility(TcorePending *p, guint data_len,
+ const void *data, void *user_data)
+{
+ const TcoreAtResponse *at_resp = data;
+ ImcRespCbData *resp_cb_data = user_data;
+ CoreObject *co = tcore_pending_ref_core_object(p);
+ TelSimResult result = TEL_SIM_RESULT_FAILURE;
+ ImcSimCurrSecOp *sec_op = NULL;
+ TelSimFacilityInfo get_facility_resp = {0, };
+
+ dbg("Entry");
+
+ tcore_check_return_assert(co != NULL);
+ tcore_check_return_assert(resp_cb_data != NULL);
+
+ sec_op = (ImcSimCurrSecOp *)IMC_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 = __imc_sim_get_lock_type(*sec_op);
+ if (lock_type == -1) {
+ result = TEL_SIM_RESULT_INVALID_PARAMETER;
+ goto EXIT;
+ }
+ 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 EXIT;
+ }
+ 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]");
+ }
+EXIT:
+ /* Invoke callback */
+ if(resp_cb_data->cb)
+ resp_cb_data->cb(co, (gint)result, &get_facility_resp, resp_cb_data->cb_data);
+ imc_destroy_resp_cb_data(resp_cb_data);
+}
+
+static void on_response_imc_sim_get_lock_info(TcorePending *p, guint data_len,
+ const void *data, void *user_data)
+{
+ const TcoreAtResponse *at_resp = data;
+ ImcRespCbData *resp_cb_data = user_data;
+ CoreObject *co = tcore_pending_ref_core_object(p);
+ TelSimResult result = TEL_SIM_RESULT_FAILURE;
+ TelSimLockInfo get_lock_info_resp = {0, };
+
+ dbg("Entry");
+
+ tcore_check_return_assert(co != NULL);
+ tcore_check_return_assert(resp_cb_data != NULL);
+
+ if(at_resp && at_resp->success) {
+ GSList *tokens = NULL;
+ const char *line;
+ int lock_type = 0;
+ int attempts_left = 0;
+ int time_penalty = 0;
+
+ dbg("Sim Get Lock Info Response- [OK]");
+
+ if (at_resp->lines) {
+ line = (const char *)at_resp->lines->data;
+ tokens = tcore_at_tok_new(line);
+ if (g_slist_length(tokens) < 3) {
+ err("Invalid message");
+ tcore_at_tok_free(tokens);
+ goto EXIT;
+ }
+
+ lock_type = atoi(g_slist_nth_data(tokens, 0));
+ attempts_left = atoi(g_slist_nth_data(tokens, 1));
+ time_penalty = atoi(g_slist_nth_data(tokens, 2));
+
+ dbg("lock_type = %d, attempts_left = %d, time_penalty = %d",
+ lock_type, attempts_left, time_penalty);
+
+ get_lock_info_resp.lock_type = __imc_sim_lock_type(lock_type);
+ get_lock_info_resp.retry_count = attempts_left;
+ result = TEL_SIM_RESULT_SUCCESS;
+ }
+ tcore_at_tok_free(tokens);
+ } else {
+ err("Sim Get Lock Info Response- [NOK]");
+ }
+EXIT:
+ /* Invoke callback */
+ if(resp_cb_data->cb)
+ resp_cb_data->cb(co, (gint)result, &get_lock_info_resp, resp_cb_data->cb_data);
+ imc_destroy_resp_cb_data(resp_cb_data);
+}
+
+static void on_response_imc_sim_req_apdu (TcorePending *p, guint data_len, const void *data, void *user_data)
+{
+ const TcoreAtResponse *resp = data;
+ CoreObject *co = NULL;
+ TelSimApduResp apdu_resp = {0,};
+ TelSimResult sim_result = TEL_SIM_RESULT_FAILURE;
+ GSList *tokens = NULL;
+ const char *line;
+ ImcRespCbData *resp_cb_data = (ImcRespCbData *) user_data;
+
+ dbg("Entry");
+
+ co = tcore_pending_ref_core_object(p);
+
+ if (resp->success > 0) {
+ dbg("RESPONSE OK");
+ if (resp->lines) {
+ char *tmp = NULL;
+ char *decoded_data = NULL;
+ guint decoded_data_len = 0;
+ line = (const char *)resp->lines->data;
+ tokens = tcore_at_tok_new(line);
+ if (g_slist_length(tokens) != 2) {
+ err("Invalid message");
+ goto OUT;
+ }
+
+ tmp = tcore_at_tok_extract(g_slist_nth_data(tokens, 1));
+ tcore_util_hexstring_to_bytes(tmp, &decoded_data, &decoded_data_len);
+
+ apdu_resp.apdu_resp_len = decoded_data_len;
+ memcpy((char *)apdu_resp.apdu_resp, decoded_data, decoded_data_len);
+ g_free(tmp);
+ g_free(decoded_data);
+ sim_result = TEL_SIM_RESULT_SUCCESS;
+ }
+ } else {
+ err("RESPONSE NOK");
+ }
+
+OUT:
+ /* Send Response */
+ if (resp_cb_data->cb)
+ resp_cb_data->cb(co, (gint)sim_result, &apdu_resp, resp_cb_data->cb_data);
+ tcore_at_tok_free(tokens);
+ dbg("Exit");
+}
+
+static void on_response_imc_sim_req_atr(TcorePending *p, guint data_len, const void *data, void *user_data)
+{
+ const TcoreAtResponse *resp = data;
+ CoreObject *co = NULL;
+ TelSimAtr atr_res = {0,};
+ TelSimResult sim_result = TEL_SIM_RESULT_FAILURE;
+ GSList *tokens = NULL;
+ const char *line;
+ ImcRespCbData *resp_cb_data = (ImcRespCbData *) user_data;
+
+ dbg("Entry");
+
+ co = tcore_pending_ref_core_object(p);
+
+ if (resp->success > 0) {
+ dbg("RESPONSE OK");
+ if (resp->lines) {
+ char *tmp = NULL;
+ char *decoded_data = NULL;
+ guint decoded_data_len = 0;
+ line = (const char *)resp->lines->data;
+ tokens = tcore_at_tok_new(line);
+ if (g_slist_length(tokens) < 1) {
+ err("Invalid message");
+ goto OUT;
+ }
+
+ tmp = tcore_at_tok_extract(g_slist_nth_data(tokens, 0));
+ tcore_util_hexstring_to_bytes(tmp, &decoded_data, &decoded_data_len);
+
+ atr_res.atr_len = decoded_data_len;
+ memcpy((char *)atr_res.atr, decoded_data, decoded_data_len);
+ g_free(tmp);
+ g_free(decoded_data);
+ sim_result = TEL_SIM_RESULT_SUCCESS;
+ }
+ } else {
+ err("RESPONSE NOK");
+ }
+
+OUT:
+ /* Send Response */
+ if (resp_cb_data->cb)
+ resp_cb_data->cb(co, (gint)sim_result, &atr_res, resp_cb_data->cb_data);
+ tcore_at_tok_free(tokens);
+ dbg("Exit");
+}
+
+/* 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 imc_sim_get_imsi (CoreObject *co,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ TelReturn ret;
+ dbg("Entry");
+
+ IMC_SIM_READ_FILE(co, cb, cb_data, TEL_SIM_EF_IMSI, ret);
+
+ return ret;
+}
+
+static TelReturn imc_sim_get_ecc (CoreObject *co,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ TelReturn ret;
+ dbg("Entry");
+
+ IMC_SIM_READ_FILE(co, cb, cb_data, TEL_SIM_EF_ECC, ret);
+
+ return ret;
+}
+
+static TelReturn imc_sim_get_iccid (CoreObject *co,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ TelReturn ret;
+ dbg("Entry");
+
+ IMC_SIM_READ_FILE(co, cb, cb_data, TEL_SIM_EF_ICCID, ret);
+
+ return ret;
+}
+
+static TelReturn imc_sim_get_language (CoreObject *co,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ TelReturn ret;
+ dbg("Entry");
+
+ IMC_SIM_READ_FILE(co, cb, cb_data, TEL_SIM_EF_LP, ret);
+
+ return ret;
+}
+
+static TelReturn imc_sim_set_language (CoreObject *co,
+ TelSimLanguagePreferenceCode language,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ ImcSimMetaInfo file_meta = {0, };
+ TelSimCardType card_type = TEL_SIM_CARD_TYPE_UNKNOWN;
+ ImcRespCbData *resp_cb_data = NULL;
+ char *tmp = NULL;
+ int tmp_len = 0;
+ char *encoded_data = NULL;
+ int encoded_data_len = 0;
+ int p1 = 0;
+ int p2 = 0;
+ int p3 = 0;
+
+ dbg("Entry");
+
+ file_meta.file_id = TEL_SIM_EF_LP;
+ file_meta.file_result = TEL_SIM_RESULT_FAILURE;
+
+ tcore_sim_get_type(co, &card_type);
+
+ dbg("language[%d], card_type[%d]", language, card_type);
+
+ if (TEL_SIM_CARD_TYPE_GSM == card_type) {
+ dbg("2G");
+ tcore_sim_encode_lp(language, &tmp, &tmp_len);
+ } else if (TEL_SIM_CARD_TYPE_USIM == card_type) {
+ dbg("3G");
+ tcore_sim_encode_li(language, &tmp, &tmp_len);
+ } else {
+ err("Invalid card_type:[%d]", card_type);
+ return TEL_RETURN_OPERATION_NOT_SUPPORTED;
+ }
+ if (!tmp_len) {
+ err("Failed to encode Language [%d]", language);
+ return TEL_RETURN_FAILURE;
+ }
+ dbg("Encoded Language [%s]", tmp);
+
+ encoded_data_len = 2 * tmp_len;
+ encoded_data = (char *)tcore_malloc0(encoded_data_len + 1);
+ tcore_util_byte_to_hex(tmp, encoded_data, tmp_len);
+ tcore_free(tmp);
+
+ p1 = 0;
+ p2 = 0;
+ p3 = encoded_data_len;
+ dbg("encoded_data - [%s], encoded_data_len - %d", encoded_data, encoded_data_len);
+
+ resp_cb_data = imc_create_resp_cb_data(cb, cb_data, &file_meta, sizeof(ImcSimMetaInfo));
+
+ return __imc_sim_update_file(co, resp_cb_data, IMC_SIM_ACCESS_UPDATE_BINARY,
+ TEL_SIM_EF_LP, p1, p2, p3, encoded_data);
+}
+
+static TelReturn imc_sim_get_callforwarding_info (CoreObject *co,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ TelReturn ret;
+ dbg("Entry");
+
+ IMC_SIM_READ_FILE(co, cb, cb_data, TEL_SIM_EF_USIM_CFIS, ret);
+
+ return ret;
+}
+
+static TelReturn imc_sim_get_messagewaiting_info (CoreObject *co,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ TelReturn ret;
+ dbg("Entry");
+
+ IMC_SIM_READ_FILE(co, cb, cb_data, TEL_SIM_EF_USIM_MWIS, ret);
+
+ return ret;
+}
+
+static TelReturn imc_sim_set_messagewaiting_info (CoreObject *co,
+ const TelSimMwis *request, TcoreObjectResponseCallback cb, void *cb_data)
+{
+ ImcSimMetaInfo file_meta = {0, };
+ ImcRespCbData *resp_cb_data = NULL;
+ gchar *encoded_mwis;
+ guint encoded_mwis_len = 0;
+ gchar *encoded_data = NULL;
+ guint encoded_data_len = 0;
+ int p1 = 0;
+ int p2 = 0;
+ int p3 = 0;
+
+ dbg("Entry");
+
+ /*
+ * Videomail is not supported.
+ */
+ if (!tcore_sim_encode_mwis(request, TEL_SIM_MAILBOX_TYPE_MAX,
+ &encoded_mwis, &encoded_mwis_len)) {
+ err("Failed to encode mwis");
+ return TEL_RETURN_FAILURE;
+ }
+
+ encoded_data_len = 2 * encoded_mwis_len;
+ encoded_data = (char *)tcore_malloc0(encoded_data_len + 1);
+ tcore_util_byte_to_hex(encoded_mwis, encoded_data, encoded_mwis_len);
+ tcore_free(encoded_mwis);
+ dbg("Encoded data: [%s] Encoded data length: [%d]", encoded_data, encoded_data_len);
+
+ p1 = 1;
+ p2 = 0x04;
+ p3 = TEL_SIM_MAILBOX_TYPE_MAX; /* Indicator Status | Voicemail | Fax | Electronic Mail | Others */
+ dbg("p1: [%d] p2: [%d] p3: [%d]", p1, p2, p3);
+
+ file_meta.file_id = TEL_SIM_EF_USIM_MWIS;
+ file_meta.file_result = TEL_SIM_RESULT_FAILURE;
+
+ resp_cb_data = imc_create_resp_cb_data(cb, cb_data, &file_meta, sizeof(ImcSimMetaInfo));
+
+ return __imc_sim_update_file(co, resp_cb_data, IMC_SIM_ACCESS_UPDATE_RECORD,
+ TEL_SIM_EF_USIM_MWIS, p1, p2, p3, encoded_data);
+}
+
+static TelReturn imc_sim_get_mailbox_info (CoreObject *co,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ TelReturn ret;
+ dbg("Entry");
+
+ IMC_SIM_READ_FILE(co, cb, cb_data, TEL_SIM_EF_USIM_MBI, ret);
+
+ return ret;
+}
+
+static TelReturn imc_sim_set_mailbox_info (CoreObject *co,
+ const TelSimMailBoxNumber *request, TcoreObjectResponseCallback cb, void *cb_data)
+{
+ ImcSimMetaInfo file_meta = {0, };
+ ImcRespCbData *resp_cb_data = NULL;
+ char *tmp = NULL;
+ int tmp_len = 0;
+ char *encoded_data = NULL;
+ int encoded_data_len = 0;
+ int p1 = 0;
+ int p2 = 0;
+ int p3 = 0;
+
+ dbg("Entry");
+
+ file_meta.file_id = TEL_SIM_EF_USIM_MBI;
+ file_meta.file_result = TEL_SIM_RESULT_FAILURE;
+
+ /* TBD - Do Encoding.
+ if (!tcore_sim_encode_mbi(request, sizeof(request), tmp, &tmp_len)) {
+ err("Failed to encode mwis");
+ return TEL_RETURN_FAILURE;
+ } */
+
+ encoded_data_len = tmp_len * 2;
+ encoded_data = (char *)tcore_malloc0(encoded_data_len + 1);
+ tcore_util_byte_to_hex(tmp, encoded_data, tmp_len);
+ if (!encoded_data) {
+ err("Failed to convert byte to hex");
+ tcore_free(encoded_data);
+ return TEL_RETURN_FAILURE;
+ }
+
+ p1 = 1;
+ p2 = 0x04;
+ p3 = encoded_data_len;
+ dbg("encoded_data - [%s], encoded_data_len - %d", encoded_data, encoded_data_len);
+
+ resp_cb_data = imc_create_resp_cb_data(cb, cb_data, &file_meta, sizeof(ImcSimMetaInfo));
+
+ return __imc_sim_update_file(co, resp_cb_data, IMC_SIM_ACCESS_UPDATE_RECORD,
+ TEL_SIM_EF_USIM_MBI, p1, p2, p3, encoded_data);
+}
+
+static TelReturn imc_sim_get_msisdn (CoreObject *co,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ TelReturn ret;
+ dbg("Entry");
+
+ IMC_SIM_READ_FILE(co, cb, cb_data, TEL_SIM_EF_MSISDN, ret);
+
+ return ret;
+}
+
+static TelReturn imc_sim_get_spn (CoreObject *co,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ TelReturn ret;
+ dbg("Entry");
+
+ IMC_SIM_READ_FILE(co, cb, cb_data, TEL_SIM_EF_SPN, ret);
+
+ return ret;
+}
+
+static TelReturn imc_sim_get_cphs_netname (CoreObject *co,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ TelReturn ret;
+ dbg("Entry");
+
+ IMC_SIM_READ_FILE(co, cb, cb_data, TEL_SIM_EF_CPHS_OPERATOR_NAME_STRING, ret);
+
+ return ret;
+}
+
+static TelReturn imc_sim_get_sp_display_info (CoreObject *co,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ TelReturn ret;
+ dbg("Entry");
+
+ IMC_SIM_READ_FILE(co, cb, cb_data, TEL_SIM_EF_SPDI, ret);
+
+ return ret;
+}
+
+static TelReturn imc_sim_req_authentication (CoreObject *co,
+ const TelSimAuthenticationData *request,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ gchar *cmd_str = NULL;
+ ImcRespCbData *resp_cb_data = NULL;
+ TelReturn ret = TEL_RETURN_FAILURE;
+ TelSimCardType card_type = TEL_SIM_CARD_TYPE_UNKNOWN;
+ char *convert_rand = NULL;
+ char *convert_autn = NULL;
+ int session_id;
+ int context_type;
+
+ dbg("Entry");
+
+ tcore_sim_get_type(co, &card_type);
+ if (TEL_SIM_CARD_TYPE_GSM == card_type || TEL_SIM_CARD_TYPE_USIM == card_type) {
+ session_id = 0;
+ } else {
+ err("Not Supported SIM type:[%d]", card_type);
+ return TEL_SIM_RESULT_OPERATION_NOT_SUPPORTED;
+ }
+
+ if (request->rand_data != NULL) {
+ convert_rand = tcore_malloc0(request->rand_length*2 + 1);
+ tcore_util_byte_to_hex(request->rand_data, convert_rand, request->rand_length);
+ dbg("Convert RAND hex to string: [%s]", convert_rand);
+ } else {
+ err("rand_data is NULL");
+ goto EXIT;
+ }
+
+ switch (request->auth_type) {
+ case TEL_SIM_AUTH_GSM:
+ context_type = 2;
+ cmd_str = g_strdup_printf("AT+XAUTH=%d,%d,\"%s\"",
+ session_id, context_type, convert_rand);
+ break;
+ case TEL_SIM_AUTH_3G_CTX:
+ context_type = 1;
+ if (request->autn_data != NULL) {
+ convert_autn = tcore_malloc0(request->autn_length*2 + 1);
+ tcore_util_byte_to_hex(request->autn_data, convert_autn, request->autn_length);
+ dbg("Convert AUTN hex to string: [%s]", convert_autn);
+ } else {
+ err("autn_data is NULL");
+ goto EXIT;
+ }
+ cmd_str = g_strdup_printf("AT+XAUTH=%d,%d,\"%s\",\"%s\"",
+ session_id, context_type, convert_rand, convert_autn);
+ break;
+ default:
+ err("Not supported Authentication type:[%d]", request->auth_type);
+ ret = TEL_SIM_RESULT_OPERATION_NOT_SUPPORTED;
+ goto EXIT;
+ }
+
+ resp_cb_data = imc_create_resp_cb_data(cb, cb_data, (void *)&request->auth_type, sizeof(TelSimAuthenticationType));
+
+ ret = tcore_at_prepare_and_send_request(co, cmd_str, "+XAUTH:",
+ TCORE_AT_COMMAND_TYPE_SINGLELINE,
+ TCORE_PENDING_PRIORITY_DEFAULT, NULL,
+ on_response_imc_sim_req_authentication, resp_cb_data,
+ on_send_imc_request, NULL, 0, NULL, NULL);
+
+ IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Sim request authentication");
+EXIT:
+ g_free(cmd_str);
+ tcore_free(convert_rand);
+ tcore_free(convert_autn);
+ dbg("Exit");
+ return ret;
+}
+
+/*
+ * Operation - verify_pins/verify_puks
+ *
+ * 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 imc_sim_verify_pins(CoreObject *co, const TelSimSecPinPw *request,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ TelReturn ret = TEL_RETURN_FAILURE;
+ ImcRespCbData *resp_cb_data = NULL;
+ ImcSimCurrSecOp sec_op;
+ gchar *cmd_str = NULL;
+
+ dbg("Entry");
+
+ if (request->pin_type == TEL_SIM_PIN_TYPE_PIN1) {
+ sec_op = IMC_SIM_CURR_SEC_OP_PIN1_VERIFY;
+ cmd_str = g_strdup_printf("AT+CPIN=\"%s\"", request->pw);
+ } else if (request->pin_type == TEL_SIM_PIN_TYPE_PIN2) {
+ sec_op = IMC_SIM_CURR_SEC_OP_PIN2_VERIFY;
+ cmd_str = g_strdup_printf("AT+CPIN2=\"%s\"", request->pw);
+ } else {
+ err("Invalid pin type [%d]", request->pin_type);
+ return TEL_RETURN_INVALID_PARAMETER;
+ }
+
+ resp_cb_data = imc_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_imc_sim_verify_pins,
+ resp_cb_data,
+ on_send_imc_request,
+ NULL, 0, NULL, NULL);
+
+ IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Sim Verify Pins");
+ g_free(cmd_str);
+ return ret;
+}
+
+static TelReturn imc_sim_verify_puks(CoreObject *co, const TelSimSecPukPw *request,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ TelReturn ret = TEL_RETURN_FAILURE;
+ ImcRespCbData *resp_cb_data = NULL;
+ ImcSimCurrSecOp sec_op;
+ gchar *cmd_str = NULL;
+
+ dbg("Entry");
+
+ if (request->puk_type == TEL_SIM_PUK_TYPE_PUK1) {
+ sec_op = IMC_SIM_CURR_SEC_OP_PUK1_VERIFY;
+ cmd_str = g_strdup_printf("AT+CPIN=\"%s\", \"%s\"",
+ request->puk_pw, request->new_pin_pw);
+ } else if (request->puk_type == TEL_SIM_PUK_TYPE_PUK2) {
+ sec_op = IMC_SIM_CURR_SEC_OP_PUK2_VERIFY;
+ cmd_str = g_strdup_printf("AT+CPIN2=\"%s\", \"%s\"",
+ request->puk_pw, request->new_pin_pw);
+ } else {
+ err("Invalid puk type [%d]", request->puk_type);
+ return TEL_RETURN_INVALID_PARAMETER;
+ }
+
+ resp_cb_data = imc_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_imc_sim_verify_puks,
+ resp_cb_data,
+ on_send_imc_request,
+ NULL, 0, NULL, NULL);
+
+ IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Sim Verify Puks");
+ g_free(cmd_str);
+ return ret;
+}
+
+/*
+ * Operation - change_pins
+ *
+ * Request -
+ * AT-Command: AT+CPWD= <fac>,<oldpwd>,<newpwd>
+ * where,
+ * <fac>
+ * SIM facility
+ *
+ * <oldpwd>
+ * Old Password
+ *
+ * <newpwd>
+ * New Password
+ *
+ * Success:
+ * OK
+ *
+ * Failure:
+ * +CME ERROR: <error>
+ */
+static TelReturn imc_sim_change_pins(CoreObject *co, const TelSimSecChangePinPw *request,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ TelReturn ret = TEL_RETURN_FAILURE;
+ ImcRespCbData *resp_cb_data = NULL;
+ ImcSimCurrSecOp sec_op;
+ gchar *cmd_str = NULL;
+ char *pin1_fac = "SC";
+ char *pin2_fac = "P2";
+
+ dbg("Entry");
+
+ if (request->pin_type == TEL_SIM_PIN_TYPE_PIN1) {
+ sec_op = IMC_SIM_CURR_SEC_OP_PIN1_CHANGE;
+ cmd_str = g_strdup_printf("AT+CPWD=\"%s\",\"%s\",\"%s\"",
+ pin1_fac, request->old_pw, request->new_pw);
+ } else if (request->pin_type == TEL_SIM_PIN_TYPE_PIN2) {
+ sec_op = IMC_SIM_CURR_SEC_OP_PIN2_CHANGE;
+ cmd_str = g_strdup_printf("AT+CPWD=\"%s\",\"%s\",\"%s\"",
+ pin2_fac, request->old_pw, request->new_pw);
+ } else {
+ err("Invalid pin type [%d]", request->pin_type);
+ return TEL_RETURN_INVALID_PARAMETER;
+ }
+
+ resp_cb_data = imc_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_imc_sim_change_pins,
+ resp_cb_data,
+ on_send_imc_request,
+ NULL, 0, NULL, NULL);
+
+ IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Sim Change Pins");
+ 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 imc_sim_disable_facility(CoreObject *co, const TelSimFacilityPw *request,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ TelReturn ret = TEL_RETURN_FAILURE;
+ ImcRespCbData *resp_cb_data = NULL;
+ ImcSimCurrSecOp sec_op;
+ gchar *cmd_str = NULL;
+ char *fac = "SC";
+ int mode = 0; /*mode = 0 for disable lock*/
+
+ dbg("Entry");
+
+ fac = __imc_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 = imc_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_imc_sim_disable_facility,
+ resp_cb_data,
+ on_send_imc_request,
+ NULL, 0, NULL, NULL);
+
+ IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Sim Disable Facility");
+ g_free(cmd_str);
+ return ret;
+}
+
+static TelReturn imc_sim_enable_facility(CoreObject *co, const TelSimFacilityPw *request,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ TelReturn ret = TEL_RETURN_FAILURE;
+ ImcRespCbData *resp_cb_data = NULL;
+ ImcSimCurrSecOp sec_op;
+ gchar *cmd_str = NULL;
+ char *fac = "SC";
+ int mode = 1; /*mode = 1 for enable lock*/
+
+ dbg("Entry");
+
+ fac = __imc_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 = imc_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_imc_sim_enable_facility,
+ resp_cb_data,
+ on_send_imc_request,
+ NULL, 0, NULL, NULL);
+
+ IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Sim Disable Facility");
+ g_free(cmd_str);
+ return ret;
+}
+
+static TelReturn imc_sim_get_facility(CoreObject *co, TelSimLockType lock_type,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ TelReturn ret = TEL_RETURN_FAILURE;
+ ImcRespCbData *resp_cb_data = NULL;
+ ImcSimCurrSecOp sec_op;
+ gchar *cmd_str = NULL;
+ char *fac = "SC";
+ int mode = 2; /*mode = 2 for Get Facility*/
+
+ dbg("Entry");
+
+ fac = __imc_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 = imc_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_imc_sim_get_facility,
+ resp_cb_data,
+ on_send_imc_request,
+ NULL, 0, NULL, NULL);
+
+ IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Sim Get Facility");
+ g_free(cmd_str);
+ return ret;
+}
+
+static TelReturn imc_sim_get_lock_info(CoreObject *co, TelSimLockType lock_type,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ TelReturn ret = TEL_RETURN_FAILURE;
+ ImcRespCbData *resp_cb_data = NULL;
+ gchar *cmd_str = NULL;
+ int lockType = 0;
+
+ dbg("Entry");
+
+ resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
+
+ switch (lock_type) {
+ case TEL_SIM_LOCK_PS:
+ lockType = 9;
+ break;
+
+ case TEL_SIM_LOCK_SC:
+ lockType = 1;
+ break;
+
+ case TEL_SIM_LOCK_FD:
+ lockType = 2;
+ break;
+
+ case TEL_SIM_LOCK_PN:
+ lockType = 5;
+ break;
+
+ case TEL_SIM_LOCK_PU:
+ lockType = 6;
+ break;
+
+ case TEL_SIM_LOCK_PP:
+ lockType = 7;
+ break;
+
+ case TEL_SIM_LOCK_PC:
+ lockType = 8;
+ break;
+
+ default:
+ break;
+ }
+
+ cmd_str = g_strdup_printf("AT+XPINCNT=%d", lockType);
+
+ ret = tcore_at_prepare_and_send_request(co, cmd_str, "+XPINCNT:",
+ TCORE_AT_COMMAND_TYPE_SINGLELINE,
+ TCORE_PENDING_PRIORITY_DEFAULT,
+ NULL,
+ on_response_imc_sim_get_lock_info,
+ resp_cb_data,
+ on_send_imc_request,
+ NULL, 0, NULL, NULL);
+
+ IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Sim Get Lock Info");
+ g_free(cmd_str);
+ return ret;
+}
+
+static TelReturn imc_sim_req_apdu (CoreObject *co, const TelSimApdu *request, TcoreObjectResponseCallback cb, void *cb_data)
+{
+ gchar *cmd_str = NULL;
+ char *apdu = NULL;
+ ImcRespCbData *resp_cb_data = NULL;
+ TelReturn ret = TEL_RETURN_FAILURE;
+
+ dbg("Entry");
+
+ resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
+
+ apdu = (char *)tcore_malloc0((2 * request->apdu_len) + 1);
+ tcore_util_byte_to_hex((char *)request->apdu, apdu, request->apdu_len);
+
+ cmd_str = g_strdup_printf("AT+CSIM=%d,\"%s\"", strlen((const char *)apdu), apdu);
+
+ ret = tcore_at_prepare_and_send_request(co, cmd_str, "+CSIM:",
+ TCORE_AT_COMMAND_TYPE_SINGLELINE,
+ TCORE_PENDING_PRIORITY_DEFAULT, NULL,
+ on_response_imc_sim_req_apdu, resp_cb_data,
+ on_send_imc_request, NULL, 0, NULL, NULL);
+
+ IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Sim Request APDU");
+
+ g_free(cmd_str);
+ g_free(apdu);
+
+ dbg("Exit");
+ return ret;
+}
+
+static TelReturn imc_sim_req_atr (CoreObject *co, TcoreObjectResponseCallback cb, void *cb_data)
+{
+ gchar *cmd_str = NULL;
+ ImcRespCbData *resp_cb_data = NULL;
+ TelReturn ret = TEL_RETURN_FAILURE;
+
+ dbg("Entry");
+
+ resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
+
+ cmd_str = g_strdup_printf("AT+XGATR");
+
+ ret = tcore_at_prepare_and_send_request(co, cmd_str, "+XGATR:",
+ TCORE_AT_COMMAND_TYPE_SINGLELINE,
+ TCORE_PENDING_PRIORITY_DEFAULT, NULL,
+ on_response_imc_sim_req_atr, resp_cb_data,
+ on_send_imc_request, NULL, 0, NULL, NULL);
+
+ IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Sim Request ATR");
+
+ g_free(cmd_str);
+
+ dbg("Exit");
+ return ret;
+}
+
+/* SIM Operations */
+static TcoreSimOps imc_sim_ops = {
+ .get_imsi = imc_sim_get_imsi,
+ .get_ecc = imc_sim_get_ecc,
+ .get_iccid = imc_sim_get_iccid,
+ .get_language = imc_sim_get_language,
+ .set_language = imc_sim_set_language,
+ .get_callforwarding_info = imc_sim_get_callforwarding_info,
+ .get_messagewaiting_info = imc_sim_get_messagewaiting_info,
+ .set_messagewaiting_info = imc_sim_set_messagewaiting_info,
+ .get_mailbox_info = imc_sim_get_mailbox_info,
+ .set_mailbox_info = imc_sim_set_mailbox_info,
+ .get_msisdn = imc_sim_get_msisdn,
+ .get_spn = imc_sim_get_spn,
+ .get_cphs_netname = imc_sim_get_cphs_netname,
+ .get_sp_display_info = imc_sim_get_sp_display_info,
+ .req_authentication = imc_sim_req_authentication,
+ .verify_pins = imc_sim_verify_pins,
+ .verify_puks = imc_sim_verify_puks,
+ .change_pins = imc_sim_change_pins,
+ .disable_facility = imc_sim_disable_facility,
+ .enable_facility = imc_sim_enable_facility,
+ .get_facility = imc_sim_get_facility,
+ .get_lock_info = imc_sim_get_lock_info,
+ .req_apdu = imc_sim_req_apdu,
+ .req_atr = imc_sim_req_atr
+};
+
+gboolean imc_sim_init(TcorePlugin *p, CoreObject *co)
+{
+ ImcSimPrivateInfo *priv_info = NULL;
+
+ dbg("Entry");
+
+ priv_info = g_try_new0(ImcSimPrivateInfo, 1);
+ if (priv_info == NULL)
+ return FALSE;
+
+ tcore_sim_link_userdata(co, priv_info);
+
+ /* Set operations */
+ tcore_sim_set_ops(co, &imc_sim_ops);
+
+ /* Add Callbacks */
+ tcore_object_add_callback(co, "+XSIM:",
+ on_notification_imc_sim_status, NULL);
+
+ /* Hooks */
+ tcore_plugin_add_notification_hook(p,
+ TCORE_NOTIFICATION_MODEM_POWER,
+ on_hook_imc_modem_power, co);
+
+ dbg("Exit");
+ return TRUE;
+}
+
+void imc_sim_exit(TcorePlugin *plugin, CoreObject *co)
+{
+ ImcSimPrivateInfo *priv_info = NULL;
+
+ dbg("Entry");
+
+ priv_info = tcore_sim_ref_userdata(co);
+ g_free(priv_info);
+
+ dbg("Exit");
+}
--- /dev/null
+/*
+ * tel-plugin-imc
+ *
+ * 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 "imc_sms.h"
+#include "imc_sim.h"
+#include "imc_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 IMC_NUM_PLAN_ID(sca) (gchar)(sca & 0x0F)
+#define IMC_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 IMC_SIM_TON_INTERNATIONAL 1
+#define IMC_SIM_TON_NATIONAL 2
+
+#define IMC_AT_EF_SMS_RECORD_LEN 176
+
+typedef struct {
+ guint total_param_count;
+ guint count;
+ guint index;
+ TelSmsParamsInfo *params;
+} ImcSmsParamsCbData;
+
+/*
+ * 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_imc_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;
+
+ TelSmsDatapackageInfo incoming_msg = {{0}, };
+ int sca_length = 0;
+ gchar *byte_pdu;
+ guint byte_pdu_len;
+ 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);
+
+ /* Split Line 1 into tokens */
+ tokens = tcore_at_tok_new(line);
+ 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) {
+ /* Token 0: PDU Length */
+ pdu_len = atoi((char *)g_slist_nth_data(tokens, 0));
+ dbg("pdu_len: [%d]", pdu_len);
+ }
+ tcore_at_tok_free(tokens);
+
+ /* Fetch Line 2 */
+ line = (char *)g_slist_nth_data(lines, 1);
+ if (!line) {
+ err("Line 2 is invalid");
+ return TRUE;
+ }
+ dbg("Line 2: [%s]", line);
+
+ /* Convert to Bytes */
+ tcore_util_hexstring_to_bytes(line, &byte_pdu, &byte_pdu_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 = IMC_TYPE_OF_NUM(byte_pdu[1]);
+ incoming_msg.sca.npi = IMC_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);
+
+ tcore_util_hex_dump(" ",incoming_msg.tpdu_length, &byte_pdu[sca_length+1]);
+
+ /* Send notification */
+ tcore_object_send_notification(co,
+ TCORE_NOTIFICATION_SMS_INCOM_MSG,
+ sizeof(TelSmsDatapackageInfo), &incoming_msg);
+
+ g_free(byte_pdu);
+ return TRUE;
+}
+
+/*
+ * Notification
+ * +CBM: <length><CR><LF><pdu> (PDU mode enabled);
+ *
+ * where,
+ * <length> length of the PDU
+ * <pdu> Incomming SMS CB PDU
+ *
+ */
+static gboolean on_notification_imc_sms_cb_incom_msg(CoreObject *co,
+ const void *event_info, void *user_data)
+{
+ char * line = NULL, *pdu = NULL, *line_token = NULL;
+ GSList *tokens = NULL;
+ unsigned char *byte_pdu = NULL;
+ guint byte_pdu_len = 0;
+ GSList *lines = NULL;
+
+ TelSmsCbMsgInfo cb_noti = { 0, };
+ dbg("Enter");
+
+ lines = (GSList *)event_info;
+
+ line = (char *)(lines->data);/*Fetch Line 1*/
+ if (line != NULL) {
+ tokens = tcore_at_tok_new(line); /* Split Line 1 into tokens */
+ line_token = g_slist_nth_data(tokens, 0);
+ if (line_token) {
+ cb_noti.length = atoi(line_token);
+ } else {
+ dbg("token 0 is NULL");
+ tcore_at_tok_free(tokens);
+ return TRUE;
+ }
+ pdu = g_slist_nth_data(lines, 1);
+ if (pdu != NULL) {
+ cb_noti.cb_type = TEL_SMS_CB_MSG_GSM;
+
+ dbg("CB Msg LENGTH [%d]", cb_noti.length);
+
+ if ((cb_noti.length > 0) && (TEL_SMS_CB_DATA_SIZE_MAX >= cb_noti.length)) {
+ tcore_util_hexstring_to_bytes(pdu, (gchar **)&byte_pdu, &byte_pdu_len);
+
+ memcpy(cb_noti.cb_data, (char*)byte_pdu, cb_noti.length);
+ } else {
+ err("Invalid Message Length");
+ tcore_at_tok_free(tokens);
+ return TRUE;
+ }
+ } else {
+ err("NULL PDU Recieved ");
+ tcore_at_tok_free(tokens);
+ return TRUE;
+ }
+ tcore_object_send_notification(co,
+ TCORE_NOTIFICATION_SMS_CB_INCOM_MSG, sizeof(TelSmsCbMsgInfo), &cb_noti);
+ g_free(byte_pdu);
+ } else {
+ err("Response NOK");
+ }
+
+ tcore_at_tok_free(tokens);
+ return TRUE;
+}
+
+/*
+ * Notification
+ * TODO - AT Command Description Not available
+ *
+ */
+static gboolean on_notification_imc_sms_memory_status(CoreObject *co,
+ const void *event_info, void *user_data)
+{
+ gboolean memory_status = TRUE;
+
+ GSList *tokens = NULL;
+ GSList *lines = NULL;
+ char *line = NULL , *line_token = NULL;
+ dbg(" Enter");
+
+ lines = (GSList *)event_info;
+ if (1 != g_slist_length(lines)) {
+ dbg("Unsolicited msg but multiple line");
+ return TRUE;
+ }
+
+ line = (char*)(lines->data);
+ if (line) {
+ tokens = tcore_at_tok_new(line);
+ line_token = g_slist_nth_data(tokens, 0);
+ if (line_token) {
+ /* SIM Full condition */
+ if (0 == atoi(line_token))
+ memory_status = FALSE;
+
+ /* Send notification */
+ tcore_object_send_notification(co,
+ TCORE_NOTIFICATION_SMS_MEMORY_STATUS,
+ sizeof(gboolean), &memory_status);
+ }
+ tcore_at_tok_free(tokens);
+ } else {
+ err("Response NOK");
+ }
+
+ return TRUE;
+}
+
+static void on_response_imc_class2_sms_incom_msg(TcorePending *p,
+ guint data_len, const void *data, void *user_data)
+{
+ const TcoreAtResponse *at_resp = data;
+ CoreObject *co = tcore_pending_ref_core_object(p);
+
+ TelSmsDatapackageInfo incoming_msg = { { 0 }, };
+
+ GSList *tokens=NULL;
+ char *gslist_line = NULL, *line_token = NULL, *byte_pdu = NULL, *hex_pdu = NULL;
+ gint sca_length = 0;
+ guint byte_pdu_len = 0;
+ dbg("Enter");
+
+ if (at_resp && at_resp->success) {
+ dbg("RESPONSE OK");
+ if (at_resp->lines) {
+ /*
+ * TCORE_AT_PDU:
+ * Multi-line output
+ *
+ * Fetching First Line
+ */
+ gslist_line = (char *)at_resp->lines->data;
+ dbg("gslist_line: [%s]", gslist_line);
+
+ /*Tokenize*/
+ tokens = tcore_at_tok_new(gslist_line);
+ dbg("Number of tokens: [%d]", g_slist_length(tokens));
+
+ /* First Token : status
+ * Second Token: Alpha ID - not needed
+ */
+ line_token = g_slist_nth_data(tokens, 2); /* Third Token: PDU Length */
+ if (line_token != NULL) {
+ incoming_msg.tpdu_length = atoi(line_token);
+ dbg("Length: [%d]", incoming_msg.tpdu_length);
+ }
+ else {
+ err("Line Token for PDU Length is NULL");
+ return;
+ }
+
+ /* Fetching line: Second line is PDU */
+ hex_pdu = (char *) at_resp->lines->next->data;
+ dbg("EF-SMS PDU: [%s]", hex_pdu);
+
+ tcore_at_tok_free(tokens); /* free the consumed token */
+ if (NULL != hex_pdu) {
+ tcore_util_hexstring_to_bytes(hex_pdu, &byte_pdu, &byte_pdu_len);
+
+ sca_length = (int)byte_pdu[0];
+
+ dbg("SCA Length [%d], msgLength: [%d]", sca_length, incoming_msg.tpdu_length);
+
+ if (ZERO == sca_length) {
+ memcpy(incoming_msg.tpdu, &byte_pdu[1], incoming_msg.tpdu_length);
+ }
+ else {
+ char sca_toa;
+
+ /*
+ * byte_pdu[1] - sca_address_type
+ * Excluding sca_address_type and copy SCA
+ */
+ memcpy(incoming_msg.sca.number, &byte_pdu[2], (sca_length-1));
+
+ /*
+ * SCA Conversion: Address Type
+ * 3GPP TS 23.040 V6.5.0 Section: 9.1.2.5
+ */
+ sca_toa = byte_pdu[1];
+ incoming_msg.sca.npi = IMC_NUM_PLAN_ID(sca_toa);
+ incoming_msg.sca.ton = IMC_TYPE_OF_NUM(sca_toa);
+
+ memcpy(incoming_msg.tpdu,
+ &byte_pdu[sca_length+1],
+ incoming_msg.tpdu_length);
+ }
+ }
+
+ tcore_object_send_notification(co,
+ TCORE_NOTIFICATION_SMS_INCOM_MSG,
+ sizeof(TelSmsDatapackageInfo), &incoming_msg);
+ tcore_at_tok_free(tokens);
+ g_free(byte_pdu);
+ }
+ else {
+ err("Invalid Response Received");
+ }
+ }
+ else {
+ err("RESPONSE NOK");
+ }
+}
+
+/*
+ * Notification
+ * +CMTI: <mem>,<index>
+ *
+ * where,
+ * <mem> memory location
+ * <index> index where msg is stored
+ */
+static gboolean on_notification_imc_sms_class2_incoming_msg(CoreObject *co, const void *event_info, void *user_data)
+{
+ gchar *at_cmd;
+ TelReturn ret;
+
+ GSList *tokens = NULL , *lines = NULL;
+ char *line = NULL;
+ gint index, mem_type = 0;
+ dbg("Enter");
+
+ lines = (GSList *)event_info;
+ 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 */
+ mem_type = atoi(g_slist_nth_data(tokens, 0));/* Type of Memory stored */
+ dbg("mem_type=[%d]", mem_type);
+ index = atoi((char *) g_slist_nth_data(tokens, 1));
+ dbg("index: [%d]", index);
+
+ /*
+ * Operation - read_sms_in_sim
+ *
+ * Request -
+ * AT-Command: At+CMGR=<index>
+ * where
+ * <index> index of the message to be read.
+ *
+ * Response -
+ * Success: (PDU: Multi-line output)
+ * +CMGR: <stat>,[<alpha>],<length><CR><LF><pdu>
+ *
+ * Failure:
+ * +CMS ERROR: <error>
+ */
+ /*AT Command*/
+ at_cmd = g_strdup_printf("AT+CMGR=%d", index);
+
+ /* Send Request to modem */
+ ret = tcore_at_prepare_and_send_request(co,
+ at_cmd, "+CMGR:",
+ TCORE_AT_COMMAND_TYPE_PDU,
+ TCORE_PENDING_PRIORITY_DEFAULT,
+ NULL,
+ on_response_imc_class2_sms_incom_msg, NULL,
+ on_send_imc_request, NULL,
+ 0, NULL, NULL);
+ if (ret != TEL_RETURN_SUCCESS) {
+ err("Failed to Read Class2 Incomming Message");
+ }
+ g_free(at_cmd);
+ return TRUE;
+}
+
+static void on_response_imc_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_imc_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);
+ ImcRespCbData *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 */
+ imc_destroy_resp_cb_data(resp_cb_data);
+}
+
+static void on_response_imc_sms_write_sms_in_sim(TcorePending *p,
+ guint data_len, const void *data, void *user_data)
+{
+ const TcoreAtResponse *at_resp = data;
+ CoreObject *co = tcore_pending_ref_core_object(p);
+ ImcRespCbData *resp_cb_data = user_data;
+
+ TelSmsResult result = TEL_SMS_RESULT_FAILURE;
+
+ GSList *tokens = NULL;
+ char *line = NULL, *line_token = NULL;
+ guint index = -1;
+
+ dbg("Enter");
+
+ if (at_resp && at_resp->success) {
+ dbg("Response OK");
+ if (at_resp->lines) {
+ line = (char *)at_resp->lines->data;
+ tokens = tcore_at_tok_new(line);
+ line_token = g_slist_nth_data(tokens, 0);
+ if (line_token) {
+ index = (atoi(line_token));
+ dbg("SMS written to '%d' index", index);
+ result = TEL_SMS_RESULT_SUCCESS;
+ }
+ else {
+ dbg("No Tokens");
+ result = TEL_SMS_RESULT_FAILURE;
+ }
+ }
+ else {
+ err("Lines NOT present");
+ }
+ }
+ else {
+ dbg("Response NOK");
+ }
+
+ /* Invoke callback */
+ if (resp_cb_data->cb)
+ resp_cb_data->cb(co, (gint)result, &index, resp_cb_data->cb_data);
+
+ /* Free callback data */
+ imc_destroy_resp_cb_data(resp_cb_data);
+}
+
+static void on_response_imc_sms_read_sms_in_sim(TcorePending *p,
+ guint data_len, const void *data, void *user_data)
+{
+ const TcoreAtResponse *at_resp = data;
+ CoreObject *co = tcore_pending_ref_core_object(p);
+ ImcRespCbData *resp_cb_data = user_data;
+ TelSmsSimDataInfo read_resp;
+ GSList *tokens = NULL;
+
+ TelSmsResult result = TEL_SMS_RESULT_FAILURE;/* CMS error mapping required */
+ dbg("Enter");
+
+ memset(&read_resp, 0x0, sizeof(TelSmsSimDataInfo));
+
+ if (at_resp && at_resp->success) {
+ dbg("RESPONSE OK");
+ if (at_resp->lines) {
+ char *gslist_line = NULL,*line_token = NULL,*byte_pdu = NULL,*hex_pdu = NULL;
+ gint msg_status = 0, pdu_len = 0, alpha_id = 0;
+
+ /*
+ * TCORE_AT_PDU:
+ * Multi-line output
+ *
+ * Fetching First Line
+ */
+ gslist_line = (char *)at_resp->lines->data;
+ dbg("gslist_line: [%s]", gslist_line);
+
+ /*Tokenize*/
+ tokens = tcore_at_tok_new(gslist_line);
+ dbg("Number of tokens: [%d]", g_slist_length(tokens));
+
+ /*+CMGR: <stat>,[<alpha>],<length><CR><LF><pdu>*/
+ line_token = g_slist_nth_data(tokens, 0); /*First Token: Message status*/
+ if (line_token == NULL) {
+ err("Invalid stat");
+ goto OUT;
+ }
+
+ msg_status = atoi(line_token);
+ dbg("msg_status is %d",msg_status);
+
+ switch (msg_status) {
+ case AT_MT_UNREAD:
+ read_resp.status = TEL_SMS_STATUS_MT_UNREAD;
+ break;
+ case AT_MT_READ:
+ read_resp.status = TEL_SMS_STATUS_MT_READ;
+ break;
+ case AT_MO_UNSENT:
+ read_resp.status = TEL_SMS_STATUS_MO_NOT_SENT;
+ break;
+ case AT_MO_SENT:
+ read_resp.status = TEL_SMS_STATUS_MO_SENT;
+ break;
+ case AT_ALL:
+ default:
+ read_resp.status = TEL_SMS_STATUS_REPLACED;
+ break;
+ }
+
+ /*Second Token: Alpha ID*/
+ line_token = g_slist_nth_data(tokens, 1);
+ if (line_token != NULL) {
+ alpha_id = atoi(line_token);
+ dbg("alpha_id: [%d]", alpha_id);
+ }
+
+ /*Third Token: Length*/
+ line_token = g_slist_nth_data(tokens, 2);
+ if (line_token == NULL) {
+ err("Invalid PDU length");
+ goto OUT;
+ }
+ pdu_len = atoi(line_token);
+ dbg("PDU length: [%d]", pdu_len);
+
+ /*Fetching line: Second line is PDU*/
+ hex_pdu = (char *) at_resp->lines->next->data;
+ dbg("EF-SMS PDU: [%s]", hex_pdu);
+
+ if (NULL != hex_pdu) {
+ gint sca_length = 0;
+ guint byte_pdu_len = 0;
+
+ tcore_util_hex_dump(" ", sizeof(hex_pdu), (void *)hex_pdu);
+
+ tcore_util_hexstring_to_bytes(hex_pdu, &byte_pdu, &byte_pdu_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);
+ memcpy(read_resp.data.sca.number, decoded_sca, TEL_SMS_SCA_LEN_MAX);
+ tcore_free(decoded_sca);
+
+ /*SCA Conversion for Address type*/
+ read_resp.data.sca.ton = IMC_TYPE_OF_NUM(byte_pdu[1]);
+ read_resp.data.sca.npi = IMC_NUM_PLAN_ID(byte_pdu[1]);
+ dbg("TON: [%d] NPI: [%d] SCA: [%s]",
+ read_resp.data.sca.ton, read_resp.data.sca.npi,
+ read_resp.data.sca.number);
+ } else {
+ err("NO SCA Present");
+ }
+
+ /* TPDU */
+ read_resp.data.tpdu_length = pdu_len;
+ if ((read_resp.data.tpdu_length > 0)
+ && (read_resp.data.tpdu_length <= TEL_SMS_SMDATA_SIZE_MAX)) {
+ memcpy(read_resp.data.tpdu, &byte_pdu[sca_length+1],
+ read_resp.data.tpdu_length);
+ } else {
+ warn("Invalid TPDU length: [%d]", read_resp.data.tpdu_length);
+ }
+
+ result = TEL_SMS_RESULT_SUCCESS;
+ g_free(byte_pdu);
+ }
+ } else {
+ err("Invalid Response Received");
+ }
+ }
+ else {
+ err("RESPONSE NOK");
+ }
+OUT:
+ /* Invoke callback */
+ if (resp_cb_data->cb)
+ resp_cb_data->cb(co, (gint)result, &read_resp, resp_cb_data->cb_data);
+
+ /* Free callback data */
+ imc_destroy_resp_cb_data(resp_cb_data);
+
+ /*free the consumed token*/
+ tcore_at_tok_free(tokens);
+}
+
+static void on_response_imc_sms_delete_sms_in_sim(TcorePending *p,
+ guint data_len, const void *data, void *user_data)
+{
+ const TcoreAtResponse *at_resp = data;
+ CoreObject *co = tcore_pending_ref_core_object(p);
+ ImcRespCbData *resp_cb_data = user_data;
+
+ TelSmsResult result = TEL_SMS_RESULT_FAILURE;
+ dbg("Enter");
+
+ tcore_check_return_assert(co != NULL);
+
+ if (at_resp && at_resp->success) {
+ dbg("Response OK");
+ result = TEL_SMS_RESULT_SUCCESS;
+ }
+ else {
+ dbg("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 */
+ imc_destroy_resp_cb_data(resp_cb_data);
+}
+
+static void on_response_imc_sms_get_msg_indices(TcorePending *p,
+ guint data_len, const void *data, void *user_data)
+{
+ TelSmsStoredMsgCountInfo *count_info;/*Response from get_count Request*/
+ TelSmsResult result = TEL_SMS_RESULT_FAILURE;/*TODO: CMS error mapping required */
+
+ const TcoreAtResponse *at_resp = data;
+ CoreObject *co = tcore_pending_ref_core_object(p);
+ ImcRespCbData *resp_cb_data = user_data;
+ dbg("Enter");
+
+ count_info = (TelSmsStoredMsgCountInfo *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
+
+ if (at_resp && at_resp->success) {
+ dbg("RESPONSE OK");
+ if (at_resp->lines) {
+ char *gslist_line = NULL;
+ gint gslist_line_count = 0, ctr_loop = 0;
+
+ gslist_line_count = g_slist_length(at_resp->lines);
+
+ if (gslist_line_count > TEL_SMS_GSM_MSG_NUM_MAX)
+ gslist_line_count = TEL_SMS_GSM_MSG_NUM_MAX;
+ dbg("Number of lines: [%d]", gslist_line_count);
+
+ for (ctr_loop = 0; ctr_loop < gslist_line_count; ctr_loop++) {
+ /* Fetch Line 'ctr_loop' */
+ gslist_line = (char *)g_slist_nth_data(at_resp->lines, ctr_loop);
+ dbg("gslist_line [%d] is [%s]", ctr_loop, gslist_line);
+
+ if (NULL != gslist_line) {
+ GSList *tokens = NULL;
+ char *line_token = NULL;
+
+ tokens = tcore_at_tok_new(gslist_line);
+
+ line_token = g_slist_nth_data(tokens, 0);
+ if (NULL != line_token) {
+ count_info->index_list[ctr_loop] = atoi(line_token);
+ }
+ else {
+ dbg("line_token of gslist_line [%d] is NULL", ctr_loop);
+ }
+
+ tcore_at_tok_free(tokens);
+ }
+ else {
+ err("gslist_line is NULL");
+ goto ERROR;
+ }
+ }
+
+ result = TEL_SMS_RESULT_SUCCESS;
+ }
+ else {
+ err("Invalid Response received. No Lines present in Response");
+
+ /* Check if used count is zero*/
+ if (count_info->used_count == 0)
+ result = TEL_SMS_RESULT_SUCCESS;
+ }
+ }
+ else {
+ err("RESPONSE NOK");
+ }
+
+ERROR:
+ /* Invoke callback */
+ if (resp_cb_data->cb)
+ resp_cb_data->cb(co, (gint)result, count_info, resp_cb_data->cb_data);
+
+ /* Free callback data */
+ imc_destroy_resp_cb_data(resp_cb_data);
+}
+
+static void on_response_imc_sms_get_sms_count(TcorePending *p,
+ guint data_len, const void *data, void *user_data)
+{
+ gchar *at_cmd;
+ TelReturn ret;
+
+ TelSmsStoredMsgCountInfo count_info = {0, };
+ TelSmsResult result = TEL_SMS_RESULT_FAILURE;
+ int used_count = 0, total_count = 0;
+
+ const TcoreAtResponse *at_resp = data;
+ CoreObject *co = tcore_pending_ref_core_object(p);
+ ImcRespCbData *resp_cb_data = user_data;
+ ImcRespCbData *getcnt_resp_cb_data;
+ dbg("Enter");
+
+ if (at_resp && at_resp->success) {
+ dbg("RESPONSE OK");
+ if (at_resp->lines) {
+ GSList *tokens = NULL;
+ 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) {
+ used_count =atoi(line_token);
+ dbg("used cnt is %d",used_count);
+ }
+ else {
+ err("Line Token for used count is NULL");
+ tcore_at_tok_free(tokens);
+ goto ERROR;
+ }
+
+ /* <total1> */
+ line_token = g_slist_nth_data(tokens, 1);
+ if (line_token) {
+ total_count = atoi(line_token);
+
+ count_info.total_count = total_count;
+ count_info.used_count = used_count;
+ dbg("Count - used: [%d] total: [%d]", used_count, total_count);
+
+ /*
+ * Operation - get_msg_indices_in_sim
+ *
+ * Request -
+ * AT-Command: AT+CMGL
+ * +CPMS=<mem1>[, <mem2>[,<mem3>]]
+ * where
+ * <mem1> memory storage to read.
+ *
+ * Response -
+ * Success: (Multi-line output)
+ * +CMGL=<stat>]
+ *
+ * <stat> status of the message.
+ * Failure:
+ * +CMS ERROR: <error>
+ */
+
+ /* Sending the Second AT Request to fetch msg indices */
+ at_cmd = g_strdup_printf("AT+CMGL=4");
+
+ /* Response callback data */
+ getcnt_resp_cb_data = imc_create_resp_cb_data(resp_cb_data->cb,
+ resp_cb_data->cb_data,
+ &count_info, sizeof(TelSmsStoredMsgCountInfo));
+
+ /* Free previous request callback data */
+ imc_destroy_resp_cb_data(resp_cb_data);
+
+ /* Send Request to modem */
+ ret = tcore_at_prepare_and_send_request(co,
+ at_cmd, "+CMGL",
+ TCORE_AT_COMMAND_TYPE_MULTILINE,
+ TCORE_PENDING_PRIORITY_DEFAULT,
+ NULL,
+ on_response_imc_sms_get_msg_indices, getcnt_resp_cb_data,
+ on_send_imc_request, NULL,
+ 0, NULL, NULL);
+
+ /* free the consumed token */
+ tcore_at_tok_free(tokens);
+ g_free(at_cmd);
+
+ IMC_CHECK_REQUEST_RET(ret, getcnt_resp_cb_data, "Get Indices in SIM");
+ if (ret != TEL_RETURN_SUCCESS) {
+ err("Failed to Process Get Msg Indices Request");
+ goto ERROR;
+ }
+
+ dbg("Exit");
+ return;
+ }
+ else {
+ err("Line Token for Total count is NULL");
+
+ /* free the consumed token */
+ tcore_at_tok_free(tokens);
+ goto ERROR;
+ }
+ }
+ 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, NULL, resp_cb_data->cb_data);
+
+ /* Free callback data */
+ imc_destroy_resp_cb_data(resp_cb_data);
+}
+
+static void on_response_imc_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);
+ ImcRespCbData *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 */
+ imc_destroy_resp_cb_data(resp_cb_data);
+}
+
+static void on_response_imc_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);
+ ImcRespCbData *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)) {
+ memcpy(sca_resp.number, sca_addr, strlen(sca_addr));
+
+ /* Type-of-Address */
+ if (145 == atoi(sca_toa)) {
+ sca_resp.ton = IMC_SIM_TON_INTERNATIONAL;
+ }
+ else {
+ sca_resp.ton = IMC_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 */
+ imc_destroy_resp_cb_data(resp_cb_data);
+}
+
+static void on_response_imc_sms_set_cb_config(TcorePending *p,
+ guint data_len, const void *data, void *user_data)
+{
+ const TcoreAtResponse *at_resp = data;
+ CoreObject *co = tcore_pending_ref_core_object(p);
+ ImcRespCbData *resp_cb_data = user_data;
+
+ TelSmsResult result = TEL_SMS_RESULT_FAILURE;/*TODO: CME error mapping required */
+ 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 */
+ imc_destroy_resp_cb_data(resp_cb_data);
+}
+
+static void on_response_imc_sms_get_cb_config(TcorePending *p,
+ guint data_len, const void *data, void *user_data)
+{
+ const TcoreAtResponse *at_resp = data;
+ CoreObject *co = tcore_pending_ref_core_object(p);
+ ImcRespCbData *resp_cb_data = user_data;
+
+ GSList *cb_tokens = NULL;
+ char *cb_str_token = NULL;
+ int num_cb_tokens = 0;
+ char *mid_tok = NULL;
+ char *first_tok = NULL, *second_tok = NULL;
+ gint i = 0, mode = 0;
+ char delim[] = "-";
+
+ TelSmsCbConfigInfo get_cb_conf = {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;
+ char *line_token = NULL, *line = NULL;
+ line = (char*)at_resp->lines->data;
+ if (line != NULL) {
+ tokens = tcore_at_tok_new(line);
+ /*
+ * Response -
+ * +CSCB: <mode>,<mids>,<dcss>
+ */
+ line_token = g_slist_nth_data(tokens, 0);
+ if (line_token) {
+ mode = atoi(line_token);
+ dbg("mode:[%d]", mode);
+ get_cb_conf.cb_enabled = mode;
+ }
+ else {
+ err("Line Token for Mode is NULL");
+ tcore_at_tok_free(tokens);
+ goto OUT;
+ }
+ line_token = g_slist_nth_data(tokens, 1);
+ if (line_token) {
+ cb_str_token = tcore_at_tok_extract(line_token);
+ cb_tokens = tcore_at_tok_new((const char *)cb_str_token);
+
+ num_cb_tokens = g_slist_length(cb_tokens);
+ dbg("num_cb_tokens = %d", num_cb_tokens);
+ if (num_cb_tokens == 0) {
+ if (mode == 1) { /* All CBS Enabled */
+ get_cb_conf.msg_id_range_cnt = 1;
+ get_cb_conf.msg_ids[0].from_msg_id = 0x0000;
+ get_cb_conf.msg_ids[0].to_msg_id = TEL_SMS_GSM_CBMI_LIST_SIZE_MAX + 1;
+ get_cb_conf.msg_ids[0].selected = TRUE;
+ }
+ else { /* All CBS Disabled */
+ get_cb_conf.msg_id_range_cnt = 0;
+ get_cb_conf.msg_ids[0].selected = FALSE;
+ }
+ }
+
+ for(i = 0; i < num_cb_tokens; i++) {
+ get_cb_conf.msg_ids[i].selected = TRUE;
+ dbg("msgIdRangeCount:[%d]", get_cb_conf.msg_id_range_cnt);
+ get_cb_conf.msg_id_range_cnt++;
+ dbg("Incremented msgIdRangeCount:[%d]", get_cb_conf.msg_id_range_cnt);
+
+ mid_tok = tcore_at_tok_nth(cb_tokens, i);
+ first_tok = strtok(mid_tok, delim);
+ second_tok = strtok(NULL, delim);
+
+ if ((first_tok != NULL) && (second_tok != NULL)) {/* mids in range (320-478) */
+ get_cb_conf.msg_ids[i].from_msg_id = atoi(first_tok);
+ get_cb_conf.msg_ids[i].to_msg_id = atoi(second_tok);
+ }
+ else {/* single mid value (0,1,5, 922)*/
+ get_cb_conf.msg_ids[i].from_msg_id = atoi(mid_tok);
+ get_cb_conf.msg_ids[i].to_msg_id = atoi(mid_tok);
+ }
+ }
+ }
+ else {
+ err("Line Token for MID is NULL");
+ tcore_at_tok_free(tokens);
+ goto OUT;
+ }
+ }
+ else {
+ err("Line is NULL");
+ }
+ result = TEL_SMS_RESULT_SUCCESS;
+ tcore_at_tok_free(tokens);
+ tcore_at_tok_free(cb_tokens);
+ g_free(cb_str_token);
+ }
+ else {
+ err("Invalid Response.No Lines Received");
+ }
+ }
+ else {
+ err("Response NOK");
+ }
+
+OUT:
+ /* Invoke callback */
+ if (resp_cb_data->cb)
+ resp_cb_data->cb(co, (gint)result, &get_cb_conf, resp_cb_data->cb_data);
+
+ /* Free callback data */
+ imc_destroy_resp_cb_data(resp_cb_data);
+}
+
+static void on_response_imc_sms_set_memory_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);
+ ImcRespCbData *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 */
+ imc_destroy_resp_cb_data(resp_cb_data);
+}
+
+static void on_response_imc_sms_set_message_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);
+ ImcRespCbData *resp_cb_data = user_data;
+
+ TelSmsResult result = TEL_SMS_RESULT_FAILURE;
+ int response = 0, sw1 = 0, sw2 = 0;
+ const char *line = NULL;
+ char *line_token = NULL;
+ GSList *tokens = NULL;
+ dbg("Enter");
+
+ if (at_resp && at_resp->success) {
+ dbg("RESPONSE OK");
+ if (at_resp->lines) {
+ line = (const char *) at_resp->lines->data;
+ tokens = tcore_at_tok_new(line);
+ line_token = g_slist_nth_data(tokens, 0);
+ if (line_token != NULL) {
+ sw1 = atoi(line_token);
+ }
+ else {
+ dbg("sw1 is NULL");
+ }
+ line_token = g_slist_nth_data(tokens, 1);
+ if (line_token != NULL) {
+ sw2 = atoi(line_token);
+ if ((sw1 == 0x90) && (sw2 == 0)) {
+ result = TEL_SMS_RESULT_SUCCESS;
+ }
+ }
+ else {
+ dbg("sw2 is NULL");
+ }
+ line_token = g_slist_nth_data(tokens, 3);
+
+ if (line_token != NULL) {
+ response = atoi(line_token);
+ dbg("response is %s", response);
+ }
+ tcore_at_tok_free(tokens);
+ }
+ else {
+ dbg("No lines");
+ }
+ }
+ 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 */
+ imc_destroy_resp_cb_data(resp_cb_data);
+}
+
+static void _response_get_efsms_data(TcorePending *p,
+ guint data_len, const void *data, void *user_data)
+{
+ gchar *at_cmd;
+ const TcoreAtResponse *at_resp = data;
+ CoreObject *co = tcore_pending_ref_core_object(p);
+ ImcRespCbData *resp_cb_data = user_data;
+
+ TelSmsStatusInfo *status_info;
+ TelSmsResult result = TEL_SMS_RESULT_FAILURE;
+ TelReturn ret;
+
+ char *encoded_data = NULL;
+ int encoded_len = 0;
+ char msg_status = 0;
+ char *line_token = NULL;
+ GSList *tokens=NULL;
+ const char *line = NULL;
+ int sw1 = 0;
+ int sw2 = 0;
+ dbg("Enter");
+
+ status_info = (TelSmsStatusInfo *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
+ if (at_resp && at_resp->success) {
+ dbg("RESPONSE OK");
+ if (at_resp->lines) {
+ dbg("Entry:lines Ok");
+ line = (const char *) at_resp->lines->data;
+ tokens = tcore_at_tok_new(line);
+
+ sw1 = atoi(g_slist_nth_data(tokens, 0));
+ sw2 = atoi(g_slist_nth_data(tokens, 1));
+ line_token = g_slist_nth_data(tokens, 2);
+
+ dbg("line_token:[%s], Length of line token:[%d]", line_token, strlen(line_token));
+
+ if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
+ switch (status_info->status) {
+ case TEL_SMS_STATUS_MT_READ:
+ msg_status = 0x01;
+ break;
+
+ case TEL_SMS_STATUS_MT_UNREAD:
+ msg_status = 0x03;
+ break;
+
+ case TEL_SMS_STATUS_MO_NOT_SENT:
+ msg_status = 0x07;
+ break;
+
+ case TEL_SMS_STATUS_MO_SENT:
+ msg_status = 0x05;
+ break;
+
+ case TEL_SMS_STATUS_MO_DELIVERED:
+ msg_status = 0x1D;
+ break;
+
+ case TEL_SMS_STATUS_MO_DELIVERY_NOT_CONFIRMED:
+ msg_status = 0xD;
+ break;
+
+ case TEL_SMS_STATUS_REPLACED:/*Fall Through*/
+ default:
+ msg_status = 0x03;
+ break;
+ }
+ }
+ encoded_len = strlen(line_token);
+ dbg("Encoded data length:[%d]", encoded_len);
+
+ encoded_data = tcore_malloc0(2*encoded_len + 1);
+
+ memcpy(encoded_data, line_token, encoded_len);
+ dbg("encoded_data: [%s]", encoded_data);
+
+ /* overwrite Status byte information */
+ tcore_util_byte_to_hex((const char *)&msg_status, encoded_data, 1);
+
+ /*
+ * Updating EF-SMS File with status byte
+ * Rest 175 bytes are same as received in Read Record
+ *
+ */
+ at_cmd = g_strdup_printf("AT+CRSM=220,28476,%d, 4, %d, \"%s\"",
+ (status_info->index), IMC_AT_EF_SMS_RECORD_LEN, encoded_data);
+
+ /* Send Request to modem */
+ ret = tcore_at_prepare_and_send_request(co,
+ at_cmd, "+CRSM:",
+ TCORE_AT_COMMAND_TYPE_SINGLELINE,
+ TCORE_PENDING_PRIORITY_DEFAULT,
+ NULL,
+ on_response_imc_sms_set_message_status, resp_cb_data,
+ on_send_imc_request, NULL,
+ 0, NULL, NULL);
+ IMC_CHECK_REQUEST_RET(ret, resp_cb_data,
+ "Set Message Status-Updating status in Record");
+
+ g_free(encoded_data);
+ g_free(status_info);
+ tcore_at_tok_free(tokens);
+ return;
+ }
+ else {
+ err("Invalid Response Received");
+ }
+ }
+ 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 */
+ imc_destroy_resp_cb_data(resp_cb_data);
+}
+
+static void on_response_imc_sms_get_sms_params(TcorePending *p,
+ guint data_len, const void *data, void *user_data)
+{
+ const TcoreAtResponse *at_resp = data;
+ CoreObject *co = tcore_pending_ref_core_object(p);
+ ImcRespCbData *resp_cb_data = user_data;
+ ImcSmsParamsCbData *params_req_data;
+ gint sw1 = 0, sw2 = 0, decoding_length = 0;
+ const char *line = NULL;
+ char *hex_data = NULL, *record_data = NULL;
+ GSList *tokens = NULL;
+
+ TelSmsResult result = TEL_SMS_RESULT_FAILURE;
+ dbg("Enter");
+
+ params_req_data = (ImcSmsParamsCbData *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
+
+ if (at_resp && at_resp->success) {
+ dbg("RESPONSE OK");
+ if (at_resp->lines) {
+ line = (const char *) at_resp->lines->data;
+ tokens = tcore_at_tok_new(line);
+
+ sw1 = atoi(g_slist_nth_data(tokens, 0));
+ sw2 = atoi(g_slist_nth_data(tokens, 1));
+ dbg("sw1 [0x%x], sw2[0x%x]", sw1, sw2);
+
+ if (!(sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
+ err("invalid response received");
+ goto OUT;
+ }
+
+ hex_data = g_slist_nth_data(tokens, 2);
+ if (hex_data == NULL) {
+ err("invalid response received");
+ goto OUT;
+ }
+
+ tcore_util_hexstring_to_bytes(hex_data, &record_data, (guint*)&decoding_length);
+ /*
+ * Decrementing the Record Count and Filling the ParamsInfo List
+ * Final Response will be posted when Record count is ZERO
+ */
+ params_req_data->params[params_req_data->index].index = params_req_data->index;
+
+ tcore_util_decode_sms_parameters((unsigned char *)record_data,
+ decoding_length,
+ ¶ms_req_data->params[params_req_data->index]);
+
+ params_req_data->total_param_count -= 1;
+
+ if (params_req_data->total_param_count == 0) {
+ dbg("Reading all Records - Complete");
+ result = TEL_SMS_RESULT_SUCCESS;
+ goto OUT;
+ } else {
+ dbg("Reading all records incomplete [%d - Pending]",
+ params_req_data->total_param_count);
+ tcore_at_tok_free(tokens);
+ return;
+ }
+ } else {
+ err("Invalid Response Received");
+ }
+ } else {
+ err("RESPONSE NOK");
+ }
+
+OUT:
+ {
+ TelSmsParamsInfoList param_info_list = {0, };
+
+ if (result == TEL_SMS_RESULT_SUCCESS) {
+ param_info_list.params = params_req_data->params;
+ param_info_list.count = params_req_data->count;
+ }
+
+ /* Invoke callback */
+ if (resp_cb_data->cb)
+ resp_cb_data->cb(co, (gint)result, (void *)¶m_info_list, resp_cb_data->cb_data);
+ }
+
+ /* Free resource */
+ tcore_at_tok_free(tokens);
+
+ tcore_free(params_req_data->params);
+ g_free(record_data);
+
+ /* Free callback data */
+ imc_destroy_resp_cb_data(resp_cb_data);
+}
+
+static void on_response_imc_sms_set_sms_params(TcorePending *p,
+ guint data_len, const void *data, void *user_data)
+{
+ const TcoreAtResponse *at_resp = data;
+ CoreObject *co = tcore_pending_ref_core_object(p);
+ ImcRespCbData *resp_cb_data = user_data;
+
+ TelSmsResult result = TEL_SMS_RESULT_FAILURE;
+ gint sw1 = 0 , sw2 = 0;
+ const char *line = NULL;
+ GSList *tokens=NULL;
+ dbg("Enter");
+
+ if (at_resp && at_resp->success) {
+ dbg("Response OK");
+ if (at_resp->lines) {
+ line = (const char *) at_resp->lines->data;
+ tokens = tcore_at_tok_new(line);
+
+ sw1 = atoi(g_slist_nth_data(tokens, 0));
+ sw2 = atoi(g_slist_nth_data(tokens, 1));
+
+ if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
+ result = TEL_SMS_RESULT_SUCCESS;
+ }
+ else {
+ result = TEL_SMS_RESULT_FAILURE;
+ }
+ }
+ 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 */
+ imc_destroy_resp_cb_data(resp_cb_data);
+}
+
+static gboolean async_callback(gpointer data)
+{
+ ImcRespCbData *resp_cb_data = data;
+ CoreObject **co;
+ TelSmsResult result = TEL_SMS_RESULT_SUCCESS;
+
+ co = ((CoreObject **)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data));
+
+ /* Invoke callback */
+ if (resp_cb_data->cb)
+ resp_cb_data->cb(*co, (gint)result, NULL, resp_cb_data->cb_data);
+
+ /* Free callback data */
+ imc_destroy_resp_cb_data(resp_cb_data);
+
+ return FALSE;
+}
+
+/* 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 imc_sms_send_sms(CoreObject *co,
+ const TelSmsSendInfo *send_info, TcoreObjectResponseCallback cb, void *cb_data)
+{
+ gchar *at_cmd;
+
+ ImcRespCbData *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;
+
+ /* Use same Radio Resource Channel :More Messages to send*/
+ dbg("More messages: [%d]", send_info->more_msgs);
+
+ /* 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_hex_dump(" ", pdu_byte_len, pdu);
+
+ tcore_util_encode_hex((unsigned char *)pdu, pdu_byte_len, buf);
+
+ /* Response callback data */
+ resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
+
+ if (send_info->more_msgs == TRUE) {
+ /* 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_imc_sms_send_more_msg, NULL,
+ on_send_imc_request, NULL,
+ 0, NULL, NULL);
+ IMC_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_imc_sms_send_sms, resp_cb_data,
+ on_send_imc_request, NULL,
+ 0, NULL, NULL);
+ IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Send SMS");
+
+ /* Free resources */
+ g_free(at_cmd);
+
+ return ret;
+}
+
+/*
+ * Operation - write_sms_in_sim
+ *
+ * Request -
+ * AT-Command: AT+CMGW
+ * AT+CMGW = <length>[,<stat>]<CR>PDU is given<ctrl-Z/ESC>
+ * where
+ * <length> length of the tpdu
+ * <stat> status of the message
+ * <PDU> PDu of the message
+ *
+ * Response -
+ * +CMGW: <index>
+ * Success: (Single line)
+ * OK
+ * Failure:
+ * +CMS ERROR: <error>
+ */
+static TelReturn imc_sms_write_sms_in_sim(CoreObject *co,
+ const TelSmsSimDataInfo *wdata, TcoreObjectResponseCallback cb, void *cb_data)
+{
+ gchar *at_cmd;
+
+ ImcRespCbData *resp_cb_data;
+ TelReturn ret;
+
+ const unsigned char *tpdu_byte_data;
+ int tpdu_byte_len, pdu_byte_len;
+ char buf[HEX_PDU_LEN_MAX];
+ char hex_pdu[PDU_LEN_MAX];
+ gint status = 0;
+ dbg("Enter");
+
+ switch (wdata->status) {
+ case TEL_SMS_STATUS_MT_UNREAD:
+ status = AT_MT_UNREAD;
+ break;
+
+ case TEL_SMS_STATUS_MT_READ:
+ status = AT_MT_READ;
+ break;
+
+ case TEL_SMS_STATUS_MO_NOT_SENT:
+ status = AT_MO_UNSENT;
+ break;
+
+ case TEL_SMS_STATUS_MO_SENT:
+ status = AT_MO_SENT;
+ break;
+
+ default:
+ err("Invalid Message Status");
+ return TEL_RETURN_INVALID_PARAMETER;
+ }
+ tpdu_byte_data = wdata->data.tpdu;
+
+ tpdu_byte_len = wdata->data.tpdu_length;
+ dbg("TDPU length: [%d]", tpdu_byte_len);
+
+ /* Prepare PDU for hex encoding */
+ pdu_byte_len = tcore_util_encode_pdu(&(wdata->data.sca),
+ tpdu_byte_data, tpdu_byte_len, hex_pdu);
+ tcore_util_hex_dump(" ", pdu_byte_len, hex_pdu);
+
+ tcore_util_encode_hex((unsigned char *)hex_pdu, pdu_byte_len, buf);
+
+ /*AT Command*/
+ at_cmd = g_strdup_printf("AT+CMGW=%d,%d%c%s%c",
+ tpdu_byte_len, status, CR, buf, CTRL_Z);
+
+ /* Response callback data */
+ resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
+
+ /* Send Request to modem */
+ ret = tcore_at_prepare_and_send_request(co,
+ at_cmd, "+CMGW:",
+ TCORE_AT_COMMAND_TYPE_SINGLELINE,
+ TCORE_PENDING_PRIORITY_DEFAULT,
+ NULL,
+ on_response_imc_sms_write_sms_in_sim, resp_cb_data,
+ on_send_imc_request, NULL,
+ 0, NULL, NULL);
+ IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Write SMS in SIM");
+
+ /* Free resources */
+ g_free(at_cmd);
+
+ return ret;
+}
+
+/*
+ * Operation - read_sms_in_sim
+ *
+ * Request -
+ * AT-Command: At+CMGR=<index>
+ * where
+ * <index> index of the message to be read.
+ *
+ * Response -
+ * Success: (PDU: Multi-line output)
+ * +CMGR: <stat>,[<alpha>],<length><CR><LF><pdu>
+ *
+ * Failure:
+ * +CMS ERROR: <error>
+ */
+static TelReturn imc_sms_read_sms_in_sim(CoreObject *co,
+ unsigned int index, TcoreObjectResponseCallback cb, void *cb_data)
+{
+ gchar *at_cmd;
+
+ ImcRespCbData *resp_cb_data;
+ TelReturn ret;
+ dbg("Enter");
+
+ /* AT+Command */
+ at_cmd = g_strdup_printf("AT+CMGR=%d", index);
+
+ /* Response callback data */
+ resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, ZERO);
+
+ /* Send Request to modem */
+ ret = tcore_at_prepare_and_send_request(co,
+ at_cmd, "+CMGR:",
+ TCORE_AT_COMMAND_TYPE_PDU,
+ TCORE_PENDING_PRIORITY_DEFAULT,
+ NULL,
+ on_response_imc_sms_read_sms_in_sim, resp_cb_data,
+ on_send_imc_request, NULL,
+ 0, NULL, NULL);
+ IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Read SMS in SIM");
+
+ /* Free resources */
+ g_free(at_cmd);
+
+ return ret;
+}
+
+/*
+ * Operation - delete_sms_in_sim
+ *
+ * Request -
+ * AT-Command: AT+CGMD
+ * +CMGD=<index>[,<delflag>]
+ *
+ * Response -
+ * Success: (NO RESULT) -
+ * OK
+ * Failure:
+ * +CMS ERROR: <error>
+ */
+static TelReturn imc_sms_delete_sms_in_sim(CoreObject *co,
+ unsigned int index,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ gchar *at_cmd;
+
+ ImcRespCbData *resp_cb_data;
+ TelReturn ret;
+ dbg("Enter");
+
+ /* Response callback data */
+ resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
+ /*
+ * TODO: Delete All Messages
+ *
+ * at_cmd = g_strdup_printf("AT+CMGD=0,4");
+ * Need to convey MSG_SERVICE to pass an index of
+ * guint value to delete all Messages.probably as 0.
+ */
+
+ /* AT-Command */
+ at_cmd = g_strdup_printf("AT+CMGD=%d,0", index); /*Delete specified index*/
+
+ /* Send Request to modem */
+ ret = tcore_at_prepare_and_send_request(co,
+ at_cmd, "+CMGD:",
+ TCORE_AT_COMMAND_TYPE_NO_RESULT,
+ TCORE_PENDING_PRIORITY_DEFAULT,
+ NULL,
+ on_response_imc_sms_delete_sms_in_sim, resp_cb_data,
+ on_send_imc_request, NULL,
+ 0, NULL, NULL);
+ IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Delete SMS in SIM");
+
+ /* 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 imc_sms_get_msg_count_in_sim(CoreObject *co,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ gchar *at_cmd;
+
+ ImcRespCbData *resp_cb_data;
+ TelReturn ret;
+ dbg("Enter");
+
+ /*AT Command*/
+ at_cmd = g_strdup_printf("AT+CPMS=\"SM\"");
+
+ /* Response callback data */
+ resp_cb_data = imc_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_imc_sms_get_sms_count, resp_cb_data,
+ on_send_imc_request, NULL,
+ 0, NULL, NULL);
+ IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Get SMS Count");
+
+ /* 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 imc_sms_set_sca(CoreObject *co,
+ const TelSmsSca *sca, TcoreObjectResponseCallback cb, void *cb_data)
+{
+ gchar *at_cmd;
+
+ ImcRespCbData *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 = imc_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_imc_sms_set_sca, resp_cb_data,
+ on_send_imc_request, NULL,
+ 0, NULL, NULL);
+ IMC_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 imc_sms_get_sca(CoreObject *co,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ gchar *at_cmd;
+
+ ImcRespCbData *resp_cb_data;
+ TelReturn ret;
+ dbg("Enter");
+
+ /* AT Command */
+ at_cmd = g_strdup_printf("AT+CSCA?");
+
+ /* Response callback data */
+ resp_cb_data = imc_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_imc_sms_get_sca, resp_cb_data,
+ on_send_imc_request, NULL,
+ 0, NULL, NULL);
+ IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Get SCA");
+
+ /* Free resources */
+ g_free(at_cmd);
+
+ return ret;
+}
+
+/*
+ * Operation - set_cb_config
+ *
+ * Request -
+ * AT-Command: AT+CSCB
+ * +CSCB=[<mode>[,<mids>[,<dcss>]]]
+ *
+ * Response -
+ * Success
+ * OK
+ *
+ * Failure:
+ * +CME ERROR: <error>
+ */
+static TelReturn imc_sms_set_cb_config(CoreObject *co,
+ const TelSmsCbConfigInfo *cb_conf,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ gchar *at_cmd;
+
+ ImcRespCbData *resp_cb_data;
+ TelReturn ret;
+
+ unsigned short ctr1 = 0, ctr2 = 0, msg_id_range = 0;
+ unsigned short append_msg_id = 0;
+ dbg("Enter");
+
+ if (cb_conf->msg_id_range_cnt != 0) { /* Enable Specific Msgid's */
+ gchar *mids_str = NULL;
+ GString *mid_string = NULL;
+ at_cmd = NULL;
+
+ mid_string = g_string_new("AT+CSCB=0,\"");
+ for(ctr1 = 0; ctr1 < cb_conf->msg_id_range_cnt; ctr1++) {
+ if (cb_conf->msg_ids[ctr1].selected == FALSE)
+ continue;
+ msg_id_range = ((cb_conf->msg_ids[ctr1].to_msg_id) - (cb_conf->msg_ids[ctr1].from_msg_id));
+
+ if (TEL_SMS_GSM_CBMI_LIST_SIZE_MAX <= msg_id_range) {
+ mid_string = g_string_new("AT+CSCB=1"); /* Enable All CBS */
+ break;
+ }
+ append_msg_id = cb_conf->msg_ids[ctr1].from_msg_id;
+ dbg( "%x", append_msg_id);
+
+ for(ctr2 = 0; ctr2 <= msg_id_range; ctr2++) {
+ mid_string = g_string_append(mid_string, g_strdup_printf("%d", append_msg_id));
+ if (ctr2 == msg_id_range) {
+ mid_string = g_string_append(mid_string, "\""); /*Mids string termination*/
+ }
+ else {
+ mid_string = g_string_append(mid_string, ",");
+ }
+ append_msg_id++;
+ }
+ }
+ mids_str = g_string_free(mid_string, FALSE);
+ at_cmd = g_strdup_printf("%s", mids_str);
+ g_free(mids_str);
+ }
+ else {
+ at_cmd = g_strdup_printf("AT+CSCB=%d", cb_conf->cb_enabled); /* Enable or Disable MsgId's */
+ }
+
+ /* Response callback data */
+ resp_cb_data = imc_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_imc_sms_set_cb_config, resp_cb_data,
+ on_send_imc_request, NULL,
+ 0, NULL, NULL);
+ IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Set Cb Config");
+
+ /* Free resources */
+ g_free(at_cmd);
+
+ return ret;
+}
+
+/*
+ * Operation - get_cb_config
+ *
+ * Request -
+ * AT-Command: AT+CSCB
+ * +CSCB?
+ *
+ * Response -
+ * Success - (Single line)
+ * +CSCB : <mode>,<mids>,<dcss>
+ * OK
+ *
+ */
+ static TelReturn imc_sms_get_cb_config(CoreObject *co,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ gchar *at_cmd;
+
+ ImcRespCbData *resp_cb_data;
+ TelReturn ret;
+ dbg("Enter");
+
+ /* AT Command */
+ at_cmd = g_strdup_printf("AT+CSCB?");
+
+ /* Response callback data */
+ resp_cb_data = imc_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_SINGLELINE,
+ TCORE_PENDING_PRIORITY_DEFAULT,
+ NULL,
+ on_response_imc_sms_get_cb_config, resp_cb_data,
+ on_send_imc_request, NULL,
+ 0, NULL, NULL);
+ IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Get Cb Config");
+
+ /* 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 imc_sms_send_deliver_report(CoreObject *co,
+ const TelSmsDeliverReportInfo *dr_info,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ ImcRespCbData *resp_cb_data;
+ TelReturn ret = TEL_RETURN_FAILURE;
+
+ dbg("CP takes care of sending SMS ack to network for all "
+ "classes of SMS. Sending default success.!!!");
+ ret = TEL_RETURN_SUCCESS;
+
+ /* Response callback data */
+ resp_cb_data = imc_create_resp_cb_data(cb, cb_data,
+ (void *)&co, sizeof(CoreObject*));
+
+ g_idle_add(async_callback, (gpointer)resp_cb_data);
+
+ return ret;
+}
+
+
+/* Operation - set memory status
+ *
+ * Request -
+ * AT-Command: AT+XTESM=<mem_capacity>
+ * <mem_capacity> status of the external SMS storage which may be:
+ * 0: memory capacity free
+ * 1: memory capacity full
+ *
+ * Response -No Result
+ * Success
+ * OK
+ *
+ * Failure:
+ * +CME ERROR: <error>
+ */
+static TelReturn imc_sms_set_memory_status(CoreObject *co,
+ gboolean available, TcoreObjectResponseCallback cb, void *cb_data)
+{
+ gchar *at_cmd;
+
+ ImcRespCbData *resp_cb_data;
+ TelReturn ret;
+
+ /*AT+Command*/
+ at_cmd = g_strdup_printf("AT+XTESM=%d", available? 0: 1);
+
+ /* Response callback data */
+ resp_cb_data = imc_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_imc_sms_set_memory_status, resp_cb_data,
+ on_send_imc_request, NULL,
+ 0, NULL, NULL);
+ IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Set Memory Status");
+
+ /* Free resources */
+ g_free(at_cmd);
+
+ return ret;
+}
+
+/* Operation - set Message status
+ *
+ * Request -
+ * AT-Command: AT+CRSM= command>[,<fileid>[,<P1>,<P2>,<P3>[,<data>[,<pathid>]]]]
+ * p1 Index
+ * p3 SMSP record length
+ *
+ *
+ * Response -Single Line
+ * Success
+ * OK
+ *
+ * Failure:
+ * +CME ERROR: <error>
+ */
+static TelReturn imc_sms_set_message_status(CoreObject *co,
+ const TelSmsStatusInfo *status_info,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ gchar *at_cmd;
+
+ ImcRespCbData *resp_cb_data;
+ TelReturn ret;
+
+ /*AT+Command*/
+ at_cmd = g_strdup_printf("AT+CRSM=178,28476,%d,4,%d",
+ (status_info->index), IMC_AT_EF_SMS_RECORD_LEN);
+
+ /* Response callback data */
+ resp_cb_data = imc_create_resp_cb_data(cb, cb_data,
+ (void *)status_info, sizeof(TelSmsStatusInfo));
+
+ /* Send Request to modem */
+ ret = tcore_at_prepare_and_send_request(co,
+ at_cmd, "+CRSM:",
+ TCORE_AT_COMMAND_TYPE_SINGLELINE,
+ TCORE_PENDING_PRIORITY_DEFAULT,
+ NULL,
+ _response_get_efsms_data, resp_cb_data,
+ on_send_imc_request, NULL,
+ 0, NULL, NULL);
+ IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Set Message Status");
+
+ /* Free resources */
+ g_free(at_cmd);
+
+ return ret;
+}
+
+/*
+ * Operation - get_sms_parameters
+ *
+ * Request -
+ * AT-Command: AT+CRSM
+ * AT+CRSM= command>[,<fileid>[,<P1>,<P2>,<P3>[,<data>[,<pathid>]]]]
+ *
+ * Response -
+ * Success: (Single-line output)
+ * +CRSM:
+ * <sw1>,<sw2>[,<response>]
+ * OK
+ *
+ * Failure:
+ * +CME ERROR: <error>
+ */
+static TelReturn imc_sms_get_sms_params(CoreObject *co,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ TcorePlugin *plugin;
+ ImcRespCbData *resp_cb_data;
+ ImcSmsParamsCbData params_req_data = {0, };
+ gint loop_count, record_count = 0, smsp_record_len = 0;
+ TelReturn ret = TEL_RETURN_INVALID_PARAMETER;
+
+ dbg("Enter");
+
+ plugin = tcore_object_ref_plugin(co);
+
+ /* Get Record count and SMSP record length*/
+ if (FALSE == (imc_sim_get_smsp_info(plugin, &record_count,
+ &smsp_record_len))) {
+ err("Failed to get SMSP record Count and Record length");
+ return ret;
+ }
+
+ dbg("Record Count: [%d] SMSP Record Length: [%d]",
+ record_count, smsp_record_len);
+
+ /* Allocate Memory for params list data */
+ params_req_data.params = tcore_malloc0(sizeof(TelSmsParamsInfo) * record_count);
+ /* Counter */
+ params_req_data.total_param_count = record_count;
+ /* Saving actual count to be returned */
+ params_req_data.count = record_count;
+ /* Response callback data */
+ resp_cb_data = imc_create_resp_cb_data(cb, cb_data,
+ (void *)¶ms_req_data,
+ sizeof(ImcSmsParamsCbData));
+
+ for (loop_count = 1; loop_count <= record_count; loop_count++) {
+ gchar *at_cmd;
+
+ /* Updating the Index */
+ params_req_data.index = loop_count;
+ /* AT-Command */
+ at_cmd = g_strdup_printf("AT+CRSM=178,28482,%d,4,%d",
+ params_req_data.index, smsp_record_len);
+
+ /* Send Request to modem */
+ ret = tcore_at_prepare_and_send_request(co,
+ at_cmd, "+CRSM",
+ TCORE_AT_COMMAND_TYPE_SINGLELINE,
+ TCORE_PENDING_PRIORITY_DEFAULT,
+ NULL,
+ on_response_imc_sms_get_sms_params, resp_cb_data,
+ on_send_imc_request, NULL,
+ 0, NULL, NULL);
+
+ IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Get SMS Parameters");
+
+ /* Free resources */
+ if (ret != TEL_RETURN_SUCCESS)
+ tcore_free(params_req_data.params);
+ g_free(at_cmd);
+ }
+
+ return ret;
+}
+
+/*
+ * Operation - set_sms_params
+ *
+ * Request -
+ * AT-Command: AT+CRSM
+ * AT+CRSM= command>[,<fileid>[,<P1>,<P2>,<P3>[,<data>[,<pathid>]]]]
+ *
+ * Response -
+ * Success: (Single-line output)
+ * +CRSM:
+ * <sw1>,<sw2>[,<response>]
+ * OK
+ *
+ * Failure:
+ * +CME ERROR: <error>
+ */
+static TelReturn imc_sms_set_sms_params(CoreObject *co,
+ const TelSmsParamsInfo *params,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ gchar *at_cmd;
+ ImcRespCbData *resp_cb_data;
+ TelReturn ret;
+
+ TcorePlugin *plugin;
+ gint smsp_record_len = 0;
+ gchar *set_params_data = NULL;
+ gchar *encoded_data = NULL;
+ gint record_count;
+ dbg("Enter");
+
+ plugin = tcore_object_ref_plugin(co);
+
+ if (FALSE == imc_sim_get_smsp_info(plugin, &record_count, &smsp_record_len)) {
+ err("Failed to get SMSP record Count and Record length");
+ return TEL_RETURN_INVALID_PARAMETER;
+ }
+
+ dbg("SMSP Record Length: [%d]", smsp_record_len);
+
+ /* Allocate memory for set_params_data */
+ set_params_data = tcore_malloc0(sizeof(smsp_record_len));
+
+ /* Allocate memory for encoded data*/
+ encoded_data = tcore_malloc0((2 * sizeof(smsp_record_len)+1));
+
+ tcore_util_encode_sms_parameters((TelSmsParamsInfo *)params,
+ set_params_data, smsp_record_len);
+
+ tcore_util_byte_to_hex((const char *)set_params_data,
+ (char *)encoded_data, smsp_record_len);
+
+ /* Response callback data */
+ resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, sizeof(gint));
+
+ /* AT+ Command*/
+ at_cmd = g_strdup_printf("AT+CRSM=220,28482,%d,4,%d,\"%s\"",
+ params->index, smsp_record_len, encoded_data);
+ dbg("at_cmd - %s", at_cmd);
+ /* Send Request to modem */
+ ret = tcore_at_prepare_and_send_request(co,
+ at_cmd, "+CRSM",
+ TCORE_AT_COMMAND_TYPE_SINGLELINE,
+ TCORE_PENDING_PRIORITY_DEFAULT,
+ NULL,
+ on_response_imc_sms_set_sms_params, resp_cb_data,
+ on_send_imc_request, NULL,
+ 0, NULL, NULL);
+ IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Set SMS Parameters");
+
+ /* Free resources */
+ g_free(at_cmd);
+ g_free(set_params_data);
+ g_free(encoded_data);
+
+ return ret;
+}
+
+/* SMS Operations */
+static TcoreSmsOps imc_sms_ops = {
+ .send_sms = imc_sms_send_sms,
+ .read_in_sim = imc_sms_read_sms_in_sim,
+ .write_in_sim = imc_sms_write_sms_in_sim,
+ .delete_in_sim = imc_sms_delete_sms_in_sim,
+ .get_count = imc_sms_get_msg_count_in_sim,
+ .set_cb_config = imc_sms_set_cb_config,
+ .get_cb_config = imc_sms_get_cb_config,
+ .get_parameters = imc_sms_get_sms_params,
+ .set_parameters = imc_sms_set_sms_params,
+ .send_deliver_report = imc_sms_send_deliver_report,
+ .set_sca = imc_sms_set_sca,
+ .get_sca = imc_sms_get_sca,
+ .set_memory_status = imc_sms_set_memory_status,
+ .set_message_status = imc_sms_set_message_status
+};
+
+gboolean imc_sms_init(TcorePlugin *p, CoreObject *co)
+{
+ dbg("Entry");
+
+ /* Set operations */
+ tcore_sms_set_ops(co, &imc_sms_ops);
+
+ /* Add Callbacks */
+ tcore_object_add_callback(co, "\e+CMT:",
+ on_notification_imc_sms_incoming_msg, NULL);
+ tcore_object_add_callback(co, "\e+CDS",
+ on_notification_imc_sms_incoming_msg, NULL);
+
+ tcore_object_add_callback(co, "\e+CBM",
+ on_notification_imc_sms_cb_incom_msg, NULL);
+ tcore_object_add_callback(co, "+CMTI",
+ on_notification_imc_sms_class2_incoming_msg, NULL);
+
+ /*
+ * Notification
+ * TODO - AT Command Description Not available
+ */
+ tcore_object_add_callback(co, "+XSMSMMSTAT",
+ on_notification_imc_sms_memory_status, NULL);
+
+ dbg("Exit");
+ return TRUE;
+}
+
+void imc_sms_exit(TcorePlugin *p, CoreObject *co)
+{
+ dbg("Exit");
+}
--- /dev/null
+/*
+ * tel-plugin-imc
+ *
+ * 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 "imc_ss.h"
+#include "imc_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_imc_ss_ussd(CoreObject *co, const void *event_data, void *user_data)
+{
+ gchar *cmd = 0;
+ gchar *resp_str = NULL;
+ guchar *dcs_str = NULL;
+ TelUtilAlphabetFormat dcs = TEL_UTIL_ALPHABET_FORMAT_SMS_DEFAULT;
+ gushort len;
+ GSList *tokens = NULL;
+ GSList *lines = NULL;
+ int 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 = (char *) (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");
+ tcore_at_tok_free(tokens);
+ return TRUE;
+ } 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");
+ tcore_at_tok_free(tokens);
+ return TRUE;
+ }
+
+ /* 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 */
+ UssdSession *ussd_session;
+ ussd_session = tcore_ss_ussd_get_session(co);
+
+ if (ussd_session)
+ tcore_ss_ussd_destroy_session(ussd_session);
+
+ tcore_at_tok_free(tokens);
+ return TRUE;
+ }
+
+ /* 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], len: [%d]", resp_str, len);
+ } else {
+ dbg("Ussd strings is missing from %CUSD Notification");
+ tcore_at_tok_free(tokens);
+ return TRUE;
+ }
+
+ 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);
+
+ if ((tcore_util_convert_str_to_utf8(ussd_noti.str, &len, dcs,
+ (const guchar *)resp_str, len+1)) == FALSE) {
+ /* In case of Unhandled dcs type(Reserved), ussd string to ussd_noti.str */
+ memcpy(ussd_noti.str, resp_str, len);
+ }
+
+ dbg("ussd_noti.str[%s]", ussd_noti.str);
+
+ ussd_noti.status = ussd_status;
+
+ tcore_object_send_notification(co,
+ TCORE_NOTIFICATION_SS_USSD,
+ sizeof(TelSsUssdNoti), (void *)&ussd_noti);
+
+ tcore_at_tok_free(tokens);
+ tcore_free(resp_str);
+ tcore_free(ussd_noti.str);
+
+ return TRUE;
+}
+
+static gboolean __imc_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 __imc_ss_convert_class_to_imc_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 __imc_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 __imc_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 __imc_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 gint __imc_ss_convert_cli_status_modem_status(gint cli_status)
+{
+ if (cli_status == TEL_SS_CLI_DISABLE)
+ return 0;
+ else if (cli_status == TEL_SS_CLI_ENABLE)
+ return 1;
+ else {
+ err("Invalid CLI status: [%d]", cli_status);
+ return -1;
+ }
+}
+
+static gint __imc_ss_convert_clir_status_modem_status(gint clir_status)
+{
+ if (clir_status == TEL_CLIR_STATUS_DEFAULT)
+ return 0;
+ else if (clir_status == TEL_CLIR_STATUS_INVOCATION)
+ return 1;
+ else if (clir_status == TEL_CLIR_STATUS_SUPPRESSION)
+ return 2;
+ else {
+ err("Invalid CLIR status: [%d]", clir_status);
+ return -1;
+ }
+}
+
+static gboolean __imc_ss_convert_cli_info_modem_info(const TelSsCliInfo **cli_info, gint *status,
+ gchar **cmd_prefix)
+{
+ switch((*cli_info)->type)
+ {
+ case TEL_SS_CLI_CLIR:
+ if ((*status = __imc_ss_convert_clir_status_modem_status((*cli_info)->status.clir)) != -1)
+ *cmd_prefix = "+CLIR";
+ else
+ err("invalid clir status");
+ break;
+
+ case TEL_SS_CLI_CLIP:
+ if ((*status =__imc_ss_convert_cli_status_modem_status((*cli_info)->status.clip) != -1))
+ *cmd_prefix = "+CLIP";
+ else
+ err("invalid cli status");
+ break;
+ case TEL_SS_CLI_COLP:
+ if ((*status =__imc_ss_convert_cli_status_modem_status((*cli_info)->status.colp) != -1))
+ *cmd_prefix = "+COLP";
+ else
+ err("invalid cli status");
+ break;
+ case TEL_SS_CLI_COLR:
+ if ((*status =__imc_ss_convert_cli_status_modem_status((*cli_info)->status.colr) != -1))
+ *cmd_prefix = "+COLR";
+ else
+ err("invalid cli status");
+ break;
+
+ case TEL_SS_CLI_CNAP:
+ if ((*status =__imc_ss_convert_cli_status_modem_status((*cli_info)->status.cnap) != -1))
+ *cmd_prefix = "+CNAP";
+ else
+ err("invalid cli status");
+
+ break;
+ case TEL_SS_CLI_CDIP:
+ default:
+ err("Unsupported CLI type: [%d]", (*cli_info)->type);
+ return FALSE;
+ }
+
+ if (*cmd_prefix == NULL)
+ return FALSE;
+
+ return TRUE;
+}
+
+static gboolean __imc_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;
+}
+
+static gboolean __imc_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;
+}
+
+/* SS Responses */
+static void on_response_imc_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);
+ ImcRespCbData *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);
+
+ imc_destroy_resp_cb_data(resp_cb_data);
+}
+
+static void on_response_imc_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);
+ ImcRespCbData *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 *)IMC_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 char *) 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 (__imc_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);
+
+ imc_destroy_resp_cb_data(resp_cb_data);
+
+ if (barring_resp.records) {
+ tcore_free(barring_resp.records);
+ }
+}
+
+static void on_response_imc_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);
+ ImcRespCbData *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);
+
+ imc_destroy_resp_cb_data(resp_cb_data);
+}
+
+static void on_response_imc_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);
+ ImcRespCbData *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);
+
+ imc_destroy_resp_cb_data(resp_cb_data);
+}
+
+static void on_response_imc_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);
+ ImcRespCbData *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 *)IMC_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 char *) 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 (__imc_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) {
+ number = tcore_at_tok_extract(number);
+ memcpy((forwarding_resp.records[valid_records].number), number, strlen(number));
+ g_free(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);
+
+ imc_destroy_resp_cb_data(resp_cb_data);
+
+ if (forwarding_resp.records) {
+ tcore_free(forwarding_resp.records);
+ }
+}
+
+static void on_response_imc_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);
+ ImcRespCbData *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);
+
+ imc_destroy_resp_cb_data(resp_cb_data);
+}
+
+static void on_response_imc_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);
+ ImcRespCbData *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 *)IMC_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 char *) 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 (__imc_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);
+
+ imc_destroy_resp_cb_data(resp_cb_data);
+
+ if (waiting_resp.records) {
+ tcore_free(waiting_resp.records);
+ }
+}
+
+static void on_response_imc_ss_set_cli(TcorePending *p,
+ guint data_len, const void *data, void *user_data)
+{
+ const TcoreAtResponse *at_resp = data;
+ CoreObject *co = tcore_pending_ref_core_object(p);
+ ImcRespCbData *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 Cli 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);
+
+ imc_destroy_resp_cb_data(resp_cb_data);
+}
+
+static void on_response_imc_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);
+ ImcRespCbData *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 *)IMC_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 END;
+ }
+
+ 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 END;
+ }
+ line = (const gchar *)at_resp->lines->data;
+ tokens = tcore_at_tok_new(line);
+ if (g_slist_length(tokens) < 1) {
+ err("Invalid response message");
+ goto END;
+ }
+
+ dbg("RESPONSE OK");
+ status = g_slist_nth_data(tokens, 0);
+ if (!status) {
+ err("dev_status is missing");
+ goto END;
+ }
+ if (!__imc_ss_convert_modem_cli_dev_status_cli_status(*cli_type, atoi(status), &dev_status))
+ goto END;
+
+ status = g_slist_nth_data(tokens, 1);
+ if (!status) {
+ err("net_status is missing");
+ goto END;
+ }
+ if (!__imc_ss_convert_modem_cli_net_status_cli_status(*cli_type, atoi(status), &net_status))
+ goto END;
+
+ 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 END;
+ }
+
+ cli_resp.type = *cli_type;
+ result = TEL_SS_RESULT_SUCCESS;
+ } else{
+ err("RESPONSE NOK");
+ }
+
+END:
+ 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);
+
+ imc_destroy_resp_cb_data(resp_cb_data);
+}
+
+static void on_response_imc_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);
+ ImcRespCbData *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;
+ /* Need to initialise ussd response string */
+ ussd_resp.str = (unsigned char *)g_strdup("Operation success");
+ } else {
+ ussd_resp.str = (unsigned char *)g_strdup("Operation failed");
+ }
+
+
+ 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);
+
+ imc_destroy_resp_cb_data(resp_cb_data);
+ g_free(ussd_resp.str);
+}
+
+/* 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 imc_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;
+ ImcRespCbData *resp_cb_data = NULL;
+ TelReturn ret = TEL_RETURN_INVALID_PARAMETER;
+
+ if (barring_info->enable == TRUE)
+ mode = 1;
+ else
+ mode = 0;
+
+ if (__imc_ss_convert_barring_type_to_facility(barring_info->type, &facility) == FALSE) {
+ err("Invalid arguments");
+ return ret;
+ }
+
+ classx = __imc_ss_convert_class_to_imc_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 = imc_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_imc_ss_set_barring, resp_cb_data,
+ on_send_imc_request, NULL,
+ 0, NULL, NULL);
+
+ IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Set Barring");
+
+ g_free(at_cmd);
+
+ return ret;
+}
+
+static TelReturn imc_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;
+ ImcRespCbData *resp_cb_data = NULL;
+ TelReturn ret = TEL_RETURN_INVALID_PARAMETER;
+
+ mode = 2; /* query status - mode is fixed to 2 */
+
+ if (__imc_ss_convert_barring_type_to_facility(get_barring_info->type, &facility) == FALSE) {
+ err("Invalid arguments");
+ return ret;
+ }
+
+ classx = __imc_ss_convert_class_to_imc_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 = imc_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_imc_ss_get_barring_status, resp_cb_data,
+ on_send_imc_request, NULL,
+ 0, NULL, NULL);
+
+ IMC_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 imc_ss_change_barring_password(CoreObject *co, const TelSsBarringPwdInfo *barring_pwd_info,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ gchar *at_cmd = NULL;
+ ImcRespCbData *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 = imc_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_imc_ss_change_barring_password, resp_cb_data,
+ on_send_imc_request, NULL,
+ 0, NULL, NULL);
+
+ IMC_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 imc_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;
+ ImcRespCbData *resp_cb_data = NULL;
+ TelReturn ret = TEL_RETURN_INVALID_PARAMETER;
+
+ classx = __imc_ss_convert_class_to_imc_class(forwarding_info->class);
+
+ if (__imc_ss_convert_forwarding_mode_to_modem_mode(forwarding_info->mode, &mode) == FALSE) {
+ err("Invalid arguments");
+ return ret;
+ }
+
+ if (__imc_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 = imc_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_imc_ss_set_forwarding, resp_cb_data,
+ on_send_imc_request, NULL,
+ 0, NULL, NULL);
+
+ IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Set Forwarding");
+
+ g_free(tmp_cmd);
+ g_free(at_cmd);
+
+ return ret;
+}
+
+static TelReturn imc_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 */
+ ImcRespCbData *resp_cb_data = NULL;
+ TelReturn ret = TEL_RETURN_INVALID_PARAMETER;
+
+ classx = __imc_ss_convert_class_to_imc_class(get_forwarding_info->class);
+
+ if (__imc_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 = imc_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_imc_ss_get_forwarding_status, resp_cb_data,
+ on_send_imc_request, NULL,
+ 0, NULL, NULL);
+
+ IMC_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 imc_ss_set_waiting(CoreObject *co, const TelSsWaitingInfo *waiting_info,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ gchar *at_cmd = NULL;
+ guint classx;
+ guint mode;
+ ImcRespCbData *resp_cb_data = NULL;
+ TelReturn ret = TEL_RETURN_INVALID_PARAMETER;
+
+ if (waiting_info->enable == TRUE)
+ mode = 1;
+ else
+ mode = 0;
+
+ classx = __imc_ss_convert_class_to_imc_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 = imc_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_imc_ss_set_waiting, resp_cb_data,
+ on_send_imc_request, NULL,
+ 0, NULL, NULL);
+
+ IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Set Waiting");
+
+ g_free(at_cmd);
+
+ return ret;
+}
+
+static TelReturn imc_ss_get_waiting_status(CoreObject *co, TelSsClass ss_class,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ gchar *at_cmd = NULL;
+ guint classx;
+ ImcRespCbData *resp_cb_data = NULL;
+ TelReturn ret = TEL_RETURN_INVALID_PARAMETER;
+
+ classx = __imc_ss_convert_class_to_imc_class(ss_class);
+
+ dbg("class: [%d]", classx);
+
+ at_cmd = g_strdup_printf("AT+CCWA=1,2,%d", classx);
+
+ resp_cb_data = imc_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_imc_ss_get_waiting_status, resp_cb_data,
+ on_send_imc_request, NULL,
+ 0, NULL, NULL);
+
+ IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Get Waiting Status");
+
+ g_free(at_cmd);
+
+ return ret;
+}
+
+/*
+ * Operation - set_cli/get_cli_status
+ *
+ * Request -
+ * AT-Command:
+ * For CLIR: AT+CLIR= [<n>]
+ * For CLIP: AT+CLIP= [<n>]
+ * For COLP: AT+COLP= [<n>]
+ * For COLR: AT+COLR= [<n>]
+ * For CNAP: AT+CNAP= [<n>]
+ *
+ * where,
+ * <n> All CLI except CLIR
+ * 0 disable(default)
+ * 1 enable
+ *
+ * <n> for CLIR
+ * 0 default
+ * 1 CLIR invocation
+ * 2 CLIR suppression
+ *
+ * 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 imc_ss_set_cli(CoreObject *co, const TelSsCliInfo *cli_info,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ gchar *at_cmd = NULL;
+ gchar *cmd_prefix = NULL;
+ gint status = 0;
+ ImcRespCbData *resp_cb_data = NULL;
+ TelReturn ret = TEL_RETURN_INVALID_PARAMETER;
+
+ if (__imc_ss_convert_cli_info_modem_info(&cli_info, &status, &cmd_prefix) == FALSE)
+ return ret;
+
+ at_cmd = g_strdup_printf("AT%s=%d", cmd_prefix, status);
+
+ resp_cb_data = imc_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_imc_ss_set_cli, resp_cb_data,
+ on_send_imc_request, NULL,
+ 0, NULL, NULL);
+
+ IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Set Cli");
+
+ g_free(at_cmd);
+
+ return ret;
+}
+
+static TelReturn imc_ss_get_cli_status(CoreObject *co, TelSsCliType cli_type,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ gchar *at_cmd = NULL;
+ gchar *cmd_prefix = NULL;
+ ImcRespCbData *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 = imc_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_imc_ss_get_cli_status, resp_cb_data,
+ on_send_imc_request, NULL,
+ 0, NULL, NULL);
+
+ IMC_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 imc_ss_send_ussd_request(CoreObject *co, const TelSsUssdInfo *ussd_request,
+ TcoreObjectResponseCallback cb, void *cb_data)
+{
+ gchar *at_cmd = NULL;
+ UssdSession *ussd_s = NULL;
+ ImcRespCbData *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((char *)ussd_request->str));
+ } else {
+ if (ussd_request->type == TEL_SS_USSD_TYPE_USER_INIT) {
+ err("Ussd session is already exist");
+ 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 = imc_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_imc_ss_send_ussd_request, resp_cb_data,
+ on_send_imc_request, NULL,
+ 0, NULL, NULL);
+
+ IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Send Ussd Request");
+
+ g_free(at_cmd);
+
+ return ret;
+}
+
+/* SS Operations */
+static TcoreSsOps imc_ss_ops = {
+ .set_barring = imc_ss_set_barring,
+ .get_barring_status = imc_ss_get_barring_status,
+ .change_barring_password = imc_ss_change_barring_password,
+ .set_forwarding = imc_ss_set_forwarding,
+ .get_forwarding_status = imc_ss_get_forwarding_status,
+ .set_waiting = imc_ss_set_waiting,
+ .get_waiting_status = imc_ss_get_waiting_status,
+ .set_cli = imc_ss_set_cli,
+ .get_cli_status = imc_ss_get_cli_status,
+ .send_ussd_request = imc_ss_send_ussd_request
+};
+
+gboolean imc_ss_init(TcorePlugin *p, CoreObject *co)
+{
+ dbg("Entry");
+
+ /* Set operations */
+ tcore_ss_set_ops(co, &imc_ss_ops);
+
+ /* Add Callbacks */
+ tcore_object_add_callback(co, "+CUSD", on_notification_imc_ss_ussd, NULL);
+
+ dbg("Exit");
+ return TRUE;
+}
+
+void imc_ss_exit(TcorePlugin *p, CoreObject *co)
+{
+ dbg("Exit");
+}
/*
* tel-plugin-imc
*
- * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: Paresh Agarwal <paresh.agwl@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
-/*
- * tel-plugin-imc
- *
- * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: sharanayya mathapati <sharan.m@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 <storage.h>
-#include <co_call.h>
-#include <user_request.h>
-#include <server.h>
-#include <at.h>
-
-#include "s_common.h"
-#include "s_call.h"
-
-
-#define STATUS_INCOMING 4
-#define STATUS_WAITING 5
-#define STATUS_CONNECTED 7
-#define COMMA 0X2c
-
-static gboolean setsoundpath = FALSE;
-static gboolean soundvolume = FALSE;
-
-// End Cause field - Call state end cause
-
-typedef enum {
- CALL_END_NO_CAUSE,
-
- // These definitions are taken from GSM 04.08 Table 10.86
-
- CC_CAUSE_UNASSIGNED_NUMBER,
- CC_CAUSE_NO_ROUTE_TO_DEST,
- CC_CAUSE_CHANNEL_UNACCEPTABLE,
- CC_CAUSE_OPERATOR_DETERMINED_BARRING,
- CC_CAUSE_NORMAL_CALL_CLEARING,
- CC_CAUSE_USER_BUSY,
- CC_CAUSE_NO_USER_RESPONDING,
- CC_CAUSE_USER_ALERTING_NO_ANSWER,
- CC_CAUSE_CALL_REJECTED,
- CC_CAUSE_NUMBER_CHANGED,
- CC_CAUSE_NON_SELECTED_USER_CLEARING,
- CC_CAUSE_DESTINATION_OUT_OF_ORDER,
- CC_CAUSE_INVALID_NUMBER_FORMAT,
- CC_CAUSE_FACILITY_REJECTED,
- CC_CAUSE_RESPONSE_TO_STATUS_ENQUIRY,
- CC_CAUSE_NORMAL_UNSPECIFIED,
- CC_CAUSE_NO_CIRCUIT_CHANNEL_AVAILABLE,
- CC_CAUSE_NETWORK_OUT_OF_ORDER,
- CC_CAUSE_TEMPORARY_FAILURE,
- CC_CAUSE_SWITCHING_EQUIPMENT_CONGESTION,
- CC_CAUSE_ACCESS_INFORMATION_DISCARDED,
- CC_CAUSE_REQUESTED_CIRCUIT_CHANNEL_NOT_AVAILABLE,
- CC_CAUSE_RESOURCES_UNAVAILABLE_UNSPECIFIED,
- CC_CAUSE_QUALITY_OF_SERVICE_UNAVAILABLE,
- CC_CAUSE_REQUESTED_FACILITY_NOT_SUBSCRIBED,
- CC_CAUSE_INCOMING_CALL_BARRED_WITHIN_CUG,
- CC_CAUSE_BEARER_CAPABILITY_NOT_AUTHORISED,
- CC_CAUSE_BEARER_CAPABILITY_NOT_PRESENTLY_AVAILABLE,
- CC_CAUSE_SERVICE_OR_OPTION_NOT_AVAILABLE,
- CC_CAUSE_BEARER_SERVICE_NOT_IMPLEMENTED,
- CC_CAUSE_ACM_GEQ_ACMMAX,
- CC_CAUSE_REQUESTED_FACILITY_NOT_IMPLEMENTED,
- CC_CAUSE_ONLY_RESTRICTED_DIGITAL_INFO_BC_AVAILABLE,
- CC_CAUSE_SERVICE_OR_OPTION_NOT_IMPLEMENTED,
- CC_CAUSE_INVALID_TRANSACTION_ID_VALUE,
- CC_CAUSE_USER_NOT_MEMBER_OF_CUG,
- CC_CAUSE_INCOMPATIBLE_DESTINATION,
- CC_CAUSE_INVALID_TRANSIT_NETWORK_SELECTION,
- CC_CAUSE_SEMANTICALLY_INCORRECT_MESSAGE,
- CC_CAUSE_INVALID_MANDATORY_INFORMATION,
- CC_CAUSE_MESSAGE_TYPE_NON_EXISTENT,
- CC_CAUSE_MESSAGE_TYPE_NOT_COMPATIBLE_WITH_PROT_STATE,
- CC_CAUSE_IE_NON_EXISTENT_OR_NOT_IMPLEMENTED,
- CC_CAUSE_CONDITIONAL_IE_ERROR,
- CC_CAUSE_MESSAGE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE,
- CC_CAUSE_RECOVERY_ON_TIMER_EXPIRY,
- CC_CAUSE_PROTOCOL_ERROR_UNSPECIFIED,
- CC_CAUSE_INTERWORKING_UNSPECIFIED,
- CC_CAUSE_END = 128,
-
- // Reject causes
- REJECT_CAUSE_IMSI_UNKNOWN_IN_HLR,
- REJECT_CAUSE_ILLEGAL_MS,
- REJECT_CAUSE_IMSI_UNKNOWN_IN_VLR,
- REJECT_CAUSE_IMEI_NOT_ACCEPTED,
- REJECT_CAUSE_ILLEGAL_ME,
- REJECT_CAUSE_GPRS_SERVICES_NOT_ALLOWED,
- REJECT_CAUSE_GPRS_SERVICES_AND_NON_GPRS_SERVICES_NOT_ALLOWED,
- REJECT_CAUSE_MS_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK,
- REJECT_CAUSE_IMPLICITLY_DETACHED,
- REJECT_CAUSE_PLMN_NOT_ALLOWED,
- REJECT_CAUSE_LA_NOT_ALLOWED,
- REJECT_CAUSE_NATIONAL_ROAMING_NOT_ALLOWED,
- REJECT_CAUSE_GPRS_SERVICES_NOT_ALLOWED_IN_THIS_PLMN,
- REJECT_CAUSE_NO_SUITABLE_CELLS_IN_LA,
- REJECT_CAUSE_MSC_TEMPORARILY_NOT_REACHABLE,
- REJECT_CAUSE_NETWORK_FAILURE,
- REJECT_CAUSE_MAC_FAILURE,
- REJECT_CAUSE_SYNCH_FAILURE,
- REJECT_CAUSE_CONGESTTION,
- REJECT_CAUSE_GSM_AUTH_UNACCEPTED,
- REJECT_CAUSE_SERVICE_OPTION_NOT_SUPPORTED,
- REJECT_CAUSE_REQ_SERV_OPT_NOT_SUBSCRIBED,
- REJECT_CAUSE_SERVICE_OPT__OUT_OF_ORDER,
- REJECT_CAUSE_CALL_CANNOT_BE_IDENTIFIED,
- REJECT_CAUSE_NO_PDP_CONTEXT_ACTIVATED,
- REJECT_CAUSE_RETRY_UPON_ENTRY_INTO_A_NEW_CELL_MIN_VALUE,
- REJECT_CAUSE_RETRY_UPON_ENTRY_INTO_A_NEW_CELL_MAX_VALUE,
- REJECT_CAUSE_SEMANTICALLY_INCORRECT_MSG,
- REJECT_CAUSE_INVALID_MANDATORY_INFO,
- REJECT_CAUSE_MESSAGE_TYPE_NON_EXISTANT,
- REJECT_CAUSE_MESSAGE_TYPE_NOT_COMP_PRT_ST,
- REJECT_CAUSE_IE_NON_EXISTANT,
- REJECT_CAUSE_MSG_NOT_COMPATIBLE_PROTOCOL_STATE,
-
-
- // Connection Management establishment rejection cause
- REJECT_CAUSE_REJ_UNSPECIFIED,
-
- // AS reject causes
- REJECT_CAUSE_AS_REJ_RR_REL_IND,
- REJECT_CAUSE_AS_REJ_RR_RANDOM_ACCESS_FAILURE,
- REJECT_CAUSE_AS_REJ_RRC_REL_IND,
- REJECT_CAUSE_AS_REJ_RRC_CLOSE_SESSION_IND,
- REJECT_CAUSE_AS_REJ_RRC_OPEN_SESSION_FAILURE,
- REJECT_CAUSE_AS_REJ_LOW_LEVEL_FAIL,
- REJECT_CAUSE_AS_REJ_LOW_LEVEL_FAIL_REDIAL_NOT_ALLOWED,
- REJECT_CAUSE_AS_REJ_LOW_LEVEL_IMMED_RETRY,
-
- // MM reject causes
- REJECT_CAUSE_MM_REJ_INVALID_SIM,
- REJECT_CAUSE_MM_REJ_NO_SERVICE,
- REJECT_CAUSE_MM_REJ_TIMER_T3230_EXP,
- REJECT_CAUSE_MM_REJ_NO_CELL_AVAILABLE,
- REJECT_CAUSE_MM_REJ_WRONG_STATE,
- REJECT_CAUSE_MM_REJ_ACCESS_CLASS_BLOCKED,
- // Definitions for release ind causes between MM and CNM
- REJECT_CAUSE_ABORT_MSG_RECEIVED,
- REJECT_CAUSE_OTHER_CAUSE,
-
- // CNM reject causes
- REJECT_CAUSE_CNM_REJ_TIMER_T303_EXP,
- REJECT_CAUSE_CNM_REJ_NO_RESOURCES,
- REJECT_CAUSE_CNM_MM_REL_PENDING,
- REJECT_CAUSE_CNM_INVALID_USER_DATA,
- CALL_END_CAUSE_MAX = 255
-} call_end_cause_e_type;
-
-
-struct clcc_call_t {
- struct call_CLCC_info {
- 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];
-};
-
-typedef struct {
- int network_cause;
- int tapi_cause;
-} call_end_cause_info;
-
-/**************************************************************************
- * Local Function Prototypes
- **************************************************************************/
-/************************* REQUESTS ***************************/
-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 TReturn _call_list_get(CoreObject *o, gboolean *event_flag);
-static TReturn _set_dtmf_tone_duration(CoreObject *o, UserRequest *ur);
-
-/************************* CONFIRMATION ***************************/
-static void on_confirmation_call_message_send(TcorePending *p, gboolean result, void *user_data); // from Kernel
-static void on_confirmation_call_hold(TcorePending *p, int data_len, const void *data, void *user_data);
-static void on_confirmation_call_swap(TcorePending *p, int data_len, const void *data, void *user_data);
-static void on_confirmation_call_split(TcorePending *p, int data_len, const void *data, void *user_data);
-static void on_confirmation_call_hold_and_accept(TcorePending *p, int data_len, const void *data, void *user_data);
-
-static void _on_confirmation_call_release(TcorePending *p, int data_len, const void *data, void *user_data, int type);
-static void _on_confirmation_call(TcorePending *p, int data_len, const void *data, void *user_data, int type);
-static void _on_confirmation_dtmf_tone_duration(TcorePending *p, int data_len, const void *data, void *user_data);
-static void _on_confirmation_call_end_cause(TcorePending *p, int data_len, const void *data, void *user_data);
-
-/************************* RESPONSES ***************************/
-static void on_response_call_list_get(TcorePending *p, int data_len, const void *data, void *user_data);
-
-/************************* NOTIIFICATIONS ***************************/
-static void on_notification_call_waiting(CoreObject *o, const void *data, void *user_data);
-static void on_notification_call_incoming(CoreObject *o, const void *data, void *user_data);
-static void on_notification_call_status(CoreObject *o, const void *data, void *user_data);
-static gboolean on_notification_call_info(CoreObject *o, const void *data, void *user_data);
-static gboolean on_notification_call_clip_info(CoreObject *o, const void *data, void *user_data);
-
-
-/**************************************************************************
- * Local Utility Function Prototypes
- **************************************************************************/
-static gboolean _call_request_message(TcorePending *pending, CoreObject *o, UserRequest *ur, void *on_resp, void *user_data);
-static void _call_branch_by_status(TcorePlugin *p, CallObject *co, unsigned int status);
-static int _callFromCLCCLine(char *line, struct clcc_call_t *p_call);
-
-/**************************************************************************
- * Local Function Definitions
- **************************************************************************/
-
-const call_end_cause_info call_end_cause_table[] = // call end cause table to convert Netwotk cause to TAPI cause
-{
- { 1, CC_CAUSE_UNASSIGNED_NUMBER}, { 3, CC_CAUSE_NO_ROUTE_TO_DEST},
- { 6, CC_CAUSE_CHANNEL_UNACCEPTABLE}, { 8, CC_CAUSE_OPERATOR_DETERMINED_BARRING},
- { 16, CC_CAUSE_NORMAL_CALL_CLEARING}, { 17, CC_CAUSE_USER_BUSY},
- { 18, CC_CAUSE_NO_USER_RESPONDING}, { 19, CC_CAUSE_USER_ALERTING_NO_ANSWER},
- { 21, CC_CAUSE_CALL_REJECTED}, { 22, CC_CAUSE_NUMBER_CHANGED},
- { 26, CC_CAUSE_NON_SELECTED_USER_CLEARING}, { 27, CC_CAUSE_DESTINATION_OUT_OF_ORDER},
- { 28, CC_CAUSE_INVALID_NUMBER_FORMAT}, { 29, CC_CAUSE_FACILITY_REJECTED},
- { 30, CC_CAUSE_RESPONSE_TO_STATUS_ENQUIRY}, { 31, CC_CAUSE_NORMAL_UNSPECIFIED},
- { 34, CC_CAUSE_NO_CIRCUIT_CHANNEL_AVAILABLE}, { 38, CC_CAUSE_NETWORK_OUT_OF_ORDER},
- { 41, CC_CAUSE_TEMPORARY_FAILURE}, { 42, CC_CAUSE_SWITCHING_EQUIPMENT_CONGESTION},
- { 43, CC_CAUSE_ACCESS_INFORMATION_DISCARDED}, { 44, CC_CAUSE_REQUESTED_CIRCUIT_CHANNEL_NOT_AVAILABLE},
- { 47, CC_CAUSE_RESOURCES_UNAVAILABLE_UNSPECIFIED}, { 49, CC_CAUSE_QUALITY_OF_SERVICE_UNAVAILABLE},
- { 50, CC_CAUSE_REQUESTED_FACILITY_NOT_SUBSCRIBED}, { 55, CC_CAUSE_INCOMING_CALL_BARRED_WITHIN_CUG},
- { 57, CC_CAUSE_BEARER_CAPABILITY_NOT_AUTHORISED}, { 58, CC_CAUSE_BEARER_CAPABILITY_NOT_PRESENTLY_AVAILABLE},
- { 63, CC_CAUSE_SERVICE_OR_OPTION_NOT_AVAILABLE}, { 65, CC_CAUSE_BEARER_SERVICE_NOT_IMPLEMENTED},
- { 68, CC_CAUSE_ACM_GEQ_ACMMAX}, { 69, CC_CAUSE_REQUESTED_FACILITY_NOT_IMPLEMENTED},
- { 70, CC_CAUSE_ONLY_RESTRICTED_DIGITAL_INFO_BC_AVAILABLE}, { 79, CC_CAUSE_SERVICE_OR_OPTION_NOT_IMPLEMENTED},
- { 81, CC_CAUSE_INVALID_TRANSACTION_ID_VALUE}, { 87, CC_CAUSE_USER_NOT_MEMBER_OF_CUG},
- { 88, CC_CAUSE_INCOMPATIBLE_DESTINATION}, { 91, CC_CAUSE_INVALID_TRANSIT_NETWORK_SELECTION},
- { 95, CC_CAUSE_SEMANTICALLY_INCORRECT_MESSAGE}, { 96, CC_CAUSE_INVALID_MANDATORY_INFORMATION},
- { 97, CC_CAUSE_MESSAGE_TYPE_NON_EXISTENT}, { 98, CC_CAUSE_MESSAGE_TYPE_NOT_COMPATIBLE_WITH_PROT_STATE},
- { 99, CC_CAUSE_IE_NON_EXISTENT_OR_NOT_IMPLEMENTED}, { 100, CC_CAUSE_CONDITIONAL_IE_ERROR},
- { 101, CC_CAUSE_MESSAGE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE}, { 102, CC_CAUSE_RECOVERY_ON_TIMER_EXPIRY},
- { 111, CC_CAUSE_PROTOCOL_ERROR_UNSPECIFIED}, {127, CC_CAUSE_INTERWORKING_UNSPECIFIED},
-};
-
-static enum tcore_call_cli_mode _get_clir_status(char *num)
-{
- enum tcore_call_cli_mode clir = TCORE_CALL_CLI_MODE_DEFAULT;
-
- dbg("Entry");
-
- if (!strncmp(num, "*31#", 4)) {
- dbg("CLI mode restricted");
- return TCORE_CALL_CLI_MODE_RESTRICT;
- }
-
- if (!strncmp(num, "#31#", 4)) {
- dbg("CLI mode allowed");
- return TCORE_CALL_CLI_MODE_PRESENT;
- }
-
- dbg("CLI mode default");
-
- dbg("Exit");
-
- return clir;
-}
-
-static enum tcore_call_status _call_status(unsigned int status)
-{
- dbg("Entry");
-
- 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: // DISCONNECTED state // FALL THROUGH
- default:
- return TCORE_CALL_STATUS_IDLE;
- }
-}
-
-static gboolean _call_is_in_mpty(int mpty)
-{
- dbg("Entry");
-
- switch (mpty) {
- case 0:
- return FALSE;
-
- case 1:
- return TRUE;
-
- default:
- break;
- }
-
- return FALSE;
-}
-
-static enum tcore_call_type call_type(int type)
-{
- dbg("Entry");
-
- switch (type) {
- case 0:
- return TCORE_CALL_TYPE_VOICE;
-
- case 1:
- return TCORE_CALL_TYPE_VIDEO;
-
- default:
- break;
- }
-
- return TCORE_CALL_TYPE_VOICE;
-}
-
-static int _compare_call_end_cause(int networkcause)
-{
- unsigned int count;
-
- for (count = 0; count < sizeof(call_end_cause_table) / sizeof(call_end_cause_info); count++) {
- if (call_end_cause_table[count].network_cause == networkcause)
- return (call_end_cause_table[count].tapi_cause);
- }
- return CC_CAUSE_NORMAL_CALL_CLEARING;
- dbg("Exit");
-}
-
-static gboolean on_notification_call_clip_info(CoreObject *o, const void *data, void *user_data)
-{
- dbg("Entry");
-
- // TODO
-
- return TRUE;
-}
-
-static gboolean on_notification_call_info(CoreObject *o, const void *data, void *user_data)
-{
- GSList *tokens = NULL;
- GSList *lines = NULL;
- const char *line = NULL;
- char *stat;
- int status;
-
- dbg("Entry");
-
- lines = (GSList *) data;
- if (1 != g_slist_length(lines)) {
- err("Unsolicited message, BUT multiple lines present");
- goto OUT;
- }
-
- line = (char *) (lines->data);
- tokens = tcore_at_tok_new(line);
-
- stat = g_slist_nth_data(tokens, 1);
- if (!stat) {
- dbg("Stat is missing from %XCALLSTAT indiaction");
- } else {
- status = atoi(stat);
-
- switch (status) {
- case STATUS_INCOMING:
- dbg("calling on_notification_call_incoming");
- on_notification_call_incoming(o, line, user_data);
- break;
-
- case STATUS_WAITING:
- dbg("calling on_notification_call_waiting");
- on_notification_call_waiting(o, line, user_data);
- break;
-
- case STATUS_CONNECTED: /*igonre Connected state. */
- dbg("Connected state");
- break;
-
- default:
- dbg("calling on_notification_call_status");
- on_notification_call_status(o, line, user_data);
- break;
- }
- }
-
- // Free tokens
- tcore_at_tok_free(tokens);
-
-OUT:
- dbg("Exit");
- return TRUE;
-}
-
-static gboolean _call_request_message(TcorePending *pending,
- CoreObject *o,
- UserRequest *ur,
- void *on_resp,
- void *user_data)
-{
- TcoreHal *hal = NULL;
- TReturn ret;
-
- dbg("Entry");
-
- 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) {
- tcore_pending_link_user_request(pending, ur);
- } else {
- err("User Request is NULL, is this internal request??");
- }
-
- // HAL
- hal = tcore_object_get_hal(o);
- // Send request to HAL
- ret = tcore_hal_send_request(hal, pending);
- if (TCORE_RETURN_SUCCESS != ret) {
- err("Request send failed");
- return FALSE;
- }
-
- dbg("Exit");
- return TRUE;
-}
-
-static void _call_status_idle(TcorePlugin *p, CallObject *co)
-{
- CoreObject *core_obj = NULL;
- char *cmd_str = NULL;
- TcorePending *pending = NULL;
- TcoreATRequest *req = NULL;
- gboolean ret = FALSE;
- UserRequest *ur;
-
- dbg("Entry");
- core_obj = 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) {
- // get call end cause.
- cmd_str = g_strdup_printf("%s", "AT+XCEER");
- dbg("Request command string: %s", cmd_str);
-
- // Create new Pending request
- pending = tcore_pending_new(core_obj, 0);
-
- // Create new AT-Command request
- req = tcore_at_request_new(cmd_str, "+XCEER", TCORE_AT_SINGLELINE);
- dbg("Command: %s, prefix(if any): %s, Command length: %d", req->cmd, req->prefix, strlen(req->cmd));
- // Free command string
- g_free(cmd_str);
-
- // Set request data (AT command) to Pending request
- tcore_pending_set_request_data(pending, 0, req);
-
- ur = tcore_user_request_new(NULL, NULL);
- // Send request
- ret = _call_request_message(pending, core_obj, ur, _on_confirmation_call_end_cause, co);
-
- if (!ret) {
- err("Failed to send AT-Command request");
- // free only UserRequest.
- if (ur) {
- tcore_user_request_free(ur);
- ur = NULL;
- }
- return;
- }
- } else {
- err("Call object was not free");
- tcore_call_object_free(core_obj, co);
- }
- dbg("Exit");
- return;
-}
-
-static void _call_status_dialing(TcorePlugin *p, CallObject *co)
-{
- struct tnoti_call_status_dialing data;
-
- dbg("Entry");
-
- 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);
-
- // Set Status
- tcore_call_object_set_status(co, TCORE_CALL_STATUS_DIALING);
-
- // Send notification to TAPI
- 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);
- }
-
- dbg("Exit");
- return;
-}
-
-static void _call_status_alert(TcorePlugin *p, CallObject *co)
-{
- struct tnoti_call_status_alert data;
-
- dbg("Entry");
-
- // Alerting has just 1 data 'CALL ID'
- 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);
-
- // Set Status
- tcore_call_object_set_status(co, TCORE_CALL_STATUS_ALERT);
-
- // Send notification to TAPI
- 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);
- }
-
- dbg("Exit");
- return;
-}
-
-static void _call_status_active(TcorePlugin *p, CallObject *co)
-{
- struct tnoti_call_status_active data;
-
- dbg("Entry");
-
- 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);
-
- // Set Status
- tcore_call_object_set_status(co, TCORE_CALL_STATUS_ACTIVE);
-
- // Send notification to TAPI
- 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);
- }
-
- dbg("Exit");
- return;
-}
-
-static void _call_status_held(TcorePlugin *p, CallObject *co)
-{
- struct tnoti_call_status_held data;
-
- dbg("Entry");
-
- 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);
-
- // Set Status
- tcore_call_object_set_status(co, TCORE_CALL_STATUS_HELD);
-
- // Send notification to TAPI
- 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);
- }
-
- dbg("Exit");
- return;
-}
-
-static void _call_status_incoming(TcorePlugin *p, CallObject *co)
-{
- struct tnoti_call_status_incoming data;
-
- dbg("Entry");
-
- 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);
-
- // Send notification to TAPI
- 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);
- }
-
- dbg("Exit");
- return;
-}
-
-static void _call_status_waiting(TcorePlugin *p, CallObject *co)
-{
- dbg("Entry");
- _call_status_incoming(p, co);
-
- dbg("Exit");
- return;
-}
-
-static void _call_branch_by_status(TcorePlugin *p, CallObject *co, unsigned int status)
-{
- dbg("Entry");
-
- dbg("Call Status is %d", 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;
- }
-
- dbg("Exit");
- return;
-}
-
-static TReturn _call_list_get(CoreObject *o, gboolean *event_flag)
-{
- UserRequest *ur = NULL;
- TcorePending *pending = NULL;
- char *cmd_str = NULL;
- TcoreATRequest *req = NULL;
- gboolean ret = FALSE;
-
- dbg("Entry");
- if (!o) {
- err("Core Object is NULL");
- return TCORE_RETURN_FAILURE;
- }
-
- // Create new User Request
- ur = tcore_user_request_new(NULL, NULL);
-
- // Command string
- cmd_str = g_strdup("AT+CLCC");
-
- // Create new Pending Request
- pending = tcore_pending_new(o, 0);
- req = tcore_at_request_new(cmd_str, "+CLCC", TCORE_AT_MULTILINE);
-
- g_free(cmd_str);
-
- dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
-
- tcore_pending_set_request_data(pending, 0, req);
-
- ret = _call_request_message(pending, o, ur, on_response_call_list_get, event_flag);
- if (!ret) {
- err("AT request (%s) sending failed", req->cmd);
- // free only UserRequest.
- if (ur) {
- tcore_user_request_free(ur);
- ur = NULL;
- }
- return TCORE_RETURN_FAILURE;
- }
-
- dbg("AT request sent success");
- return TCORE_RETURN_SUCCESS;
-}
-
-// CONFIRMATION
-static void on_confirmation_call_message_send(TcorePending *p, gboolean result, void *user_data)
-{
- dbg("Entry");
-
- if (result == FALSE) { // Fail
- dbg("SEND FAIL");
- } else {
- dbg("SEND OK");
- }
-
- dbg("Exit");
- return;
-}
-
-static void call_prepare_and_send_pending_request(CoreObject *co, const char *at_cmd, const char *prefix, enum tcore_at_command_type at_cmd_type, TcorePendingResponseCallback callback)
-{
- TcoreATRequest *req = NULL;
- TcoreHal *hal = NULL;
- TcorePending *pending = NULL;
- TReturn ret;
-
- hal = tcore_object_get_hal(co);
- dbg("hal: %p", hal);
-
- pending = tcore_pending_new(co, 0);
- if (!pending)
- dbg("Pending is NULL");
- req = tcore_at_request_new(at_cmd, prefix, at_cmd_type);
-
- dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
-
- tcore_pending_set_request_data(pending, 0, req);
- tcore_pending_set_response_callback(pending, callback, NULL);
- tcore_pending_set_send_callback(pending, on_confirmation_call_message_send, NULL);
- ret = tcore_hal_send_request(hal, pending);
-}
-
-static void on_confirmation_call_outgoing(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- UserRequest *ur = NULL;
- GSList *tokens = NULL;
- const char *line = NULL;
- const TcoreATResponse *response = data;
- struct tresp_call_dial resp;
- enum telephony_call_error error;
- dbg("Entry");
-
- ur = tcore_pending_ref_user_request(p);
- if (ur) {
- if (response->success > 0) {
- dbg("RESPONSE OK");
- resp.err = CALL_ERROR_NONE;
- } else {
- dbg("RESPONSE NOT OK");
-
- line = (const char *) response->final_response;
- tokens = tcore_at_tok_new(line);
-
- if (g_slist_length(tokens) < 1) {
- err("Unspecified error cause OR string corrupted");
- resp.err = CALL_ERROR_SERVICE_UNAVAIL;
- } else {
- error = atoi(g_slist_nth_data(tokens, 0));
-
- // TODO: CMEE error mapping is required.
- resp.err = CALL_ERROR_SERVICE_UNAVAIL;
- }
-
- // Free tokens
- tcore_at_tok_free(tokens);
- }
-
- // Send Response to TAPI
- tcore_user_request_send_response(ur, TRESP_CALL_DIAL, sizeof(struct tresp_call_dial), &resp);
- } else {
- err("User Request is NULL");
- }
-
- dbg("Exit");
- return;
-}
-
-static void on_confirmation_call_accept(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- UserRequest *ur = NULL;
- GSList *tokens = NULL;
- const char *line = NULL;
- const TcoreATResponse *response = data;
- struct tresp_call_answer resp;
- enum telephony_call_error error;
- dbg("Entry");
-
- ur = tcore_pending_ref_user_request(p);
- if (ur) {
- if (response->success > 0) {
- dbg("RESPONSE OK");
- resp.err = CALL_ERROR_NONE;
- } else {
- dbg("RESPONSE NOT OK");
-
- line = (const char *) response->final_response;
- tokens = tcore_at_tok_new(line);
-
- if (g_slist_length(tokens) < 1) {
- err("Unspecified error cause OR string corrupted");
- resp.err = CALL_ERROR_SERVICE_UNAVAIL;
- } else {
- error = atoi(g_slist_nth_data(tokens, 0));
-
- // TODO: CMEE error mapping is required.
- resp.err = CALL_ERROR_SERVICE_UNAVAIL;
- }
-
- // Free tokens
- tcore_at_tok_free(tokens);
- }
-
- resp.id = tcore_call_object_get_id((CallObject *) user_data);
-
- // Send Response to TAPI
- tcore_user_request_send_response(ur, TRESP_CALL_ANSWER, sizeof(struct tresp_call_answer), &resp);
- } else {
- err("User Request is NULL");
- }
-
- dbg("Exit");
- return;
-}
-
-
-static void on_confirmation_call_reject(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- UserRequest *ur = NULL;
- GSList *tokens = NULL;
- const char *line = NULL;
- const TcoreATResponse *response = data;
- struct tresp_call_answer resp;
- enum telephony_call_error error;
-
- dbg("Entry");
-
- ur = tcore_pending_ref_user_request(p);
- if (ur) {
- if (response->success > 0) {
- dbg("RESPONSE OK");
- resp.err = CALL_ERROR_NONE;
- } else {
- dbg("RESPONSE NOT OK");
- line = (const char *) response->final_response;
- tokens = tcore_at_tok_new(line);
-
- if (g_slist_length(tokens) < 1) {
- err("Unspecified error cause OR string corrupted");
- resp.err = CALL_ERROR_SERVICE_UNAVAIL;
- } else {
- error = atoi(g_slist_nth_data(tokens, 0));
- // TODO: CMEE error mapping is required.
- resp.err = CALL_ERROR_SERVICE_UNAVAIL;
- }
-
- // Free tokens
- tcore_at_tok_free(tokens);
- }
-
- resp.id = tcore_call_object_get_id((CallObject *) user_data);
-
- // Send Response to TAPI
- tcore_user_request_send_response(ur, TRESP_CALL_ANSWER, sizeof(struct tresp_call_answer), &resp);
- } else {
- err("User Request is NULL");
- }
-
- dbg("Exit");
- return;
-}
-
-static void on_confirmation_call_replace(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- UserRequest *ur = NULL;
- GSList *tokens = NULL;
- const char *line = NULL;
- const TcoreATResponse *response = data;
- struct tresp_call_answer resp;
- enum telephony_call_error error;
-
- dbg("Entry");
- ur = tcore_pending_ref_user_request(p);
- if (ur) {
- if (response->success > 0) {
- dbg("RESPONSE OK");
- resp.err = CALL_ERROR_NONE;
- } else {
- dbg("RESPONSE NOT OK");
- line = (const char *) response->final_response;
- tokens = tcore_at_tok_new(line);
-
- if (g_slist_length(tokens) < 1) {
- err("Unspecified error cause OR string corrupted");
- resp.err = CALL_ERROR_SERVICE_UNAVAIL;
- } else {
- error = atoi(g_slist_nth_data(tokens, 0));
- // TODO: CMEE error mapping is required.
- resp.err = CALL_ERROR_SERVICE_UNAVAIL;
- }
-
- // Free tokens
- tcore_at_tok_free(tokens);
- }
- resp.id = tcore_call_object_get_id((CallObject *) user_data);
-
- // Send Response to TAPI
- tcore_user_request_send_response(ur, TRESP_CALL_ANSWER, sizeof(struct tresp_call_answer), &resp);
- } else {
- dbg("User Request is NULL");
- }
-
- dbg("Exit");
- return;
-}
-
-static void on_confirmation_call_hold_and_accept(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- CoreObject *o = NULL;
- UserRequest *ur = NULL;
- GSList *tokens = NULL;
- const char *line = NULL;
- const TcoreATResponse *response = data;
- struct tresp_call_answer resp;
- enum telephony_call_error error;
-
- dbg("Entry");
-
- 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 (ur) {
- if (response->success > 0) {
- dbg("RESPONSE OK");
- resp.err = CALL_ERROR_NONE;
- } else {
- err("RESPONSE NOT OK");
- line = (const char *) response->final_response;
- tokens = tcore_at_tok_new(line);
-
- if (g_slist_length(tokens) < 1) {
- err("Unspecified error cause OR string corrupted");
- resp.err = CALL_ERROR_SERVICE_UNAVAIL;
- } else {
- error = atoi(g_slist_nth_data(tokens, 0));
-
- // TODO: CMEE error mapping is required.
- resp.err = CALL_ERROR_SERVICE_UNAVAIL;
- }
-
- // Free tokens
- tcore_at_tok_free(tokens);
- }
-
- // Send response to TAPI
- tcore_user_request_send_response(ur, TRESP_CALL_ANSWER, sizeof(struct tresp_call_answer), &resp);
- if (!resp.err) {
- GSList *list = 0;
- CallObject *co = NULL;
-
- // Active Call
- list = tcore_call_object_find_by_status(o, TCORE_CALL_STATUS_ACTIVE);
- if (!list) {
- err("Can't find active Call");
- return;
- }
-
- co = (CallObject *) list->data;
- if (!co) {
- err("Can't get active Call object");
- return;
- }
-
- // Set Call Status
- tcore_call_object_set_status(co, TCORE_CALL_STATUS_HELD);
- dbg("Call status is set to HELD");
- }
- } else {
- err("User Request is NULL");
- }
-
- dbg("Exit");
- return;
-}
-
-static void _on_confirmation_call_release(TcorePending *p, int data_len, const void *data, void *user_data, int type)
-{
- UserRequest *ur = NULL;
- struct tresp_call_end resp;
- GSList *tokens = NULL;
- const char *line = NULL;
- enum telephony_call_error error;
- const TcoreATResponse *response = data;
-
- dbg("Entry");
- ur = tcore_pending_ref_user_request(p);
- if (ur) {
- if (response->success > 0) {
- dbg("RESPONSE OK");
- resp.err = CALL_ERROR_NONE;
- } else {
- err("RESPONSE NOT OK");
-
- line = (const char *) response->final_response;
- tokens = tcore_at_tok_new(line);
-
- if (g_slist_length(tokens) < 1) {
- err("Unspecified error cause OR string corrupted");
- resp.err = CALL_ERROR_SERVICE_UNAVAIL;
- } else {
- error = atoi(g_slist_nth_data(tokens, 0));
-
- // TODO: CMEE error mapping is required.
- resp.err = CALL_ERROR_SERVICE_UNAVAIL;
- }
- tcore_at_tok_free(tokens);
- }
-
- resp.type = type;
- resp.id = tcore_call_object_get_id((CallObject *) user_data);
- dbg("resp.type = %d resp.id= %d", resp.type, resp.id);
-
- // Send reponse to TAPI
- tcore_user_request_send_response(ur, TRESP_CALL_END, sizeof(struct tresp_call_end), &resp);
- } else {
- err("User Request is NULL");
- }
-
- dbg("Exit");
- return;
-}
-
-// RESPONSE
-static void on_confirmation_call_endall(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- // skip response handling - actual result will be handled in on_confirmation_call_release_all
- const TcoreATResponse *response = data;
-
- dbg("Entry");
-
- if (response->success > 0) {
- dbg("RESPONSE OK");
- } else {
- err("RESPONSE NOT OK");
- }
-
- dbg("Exit");
- return;
-}
-
-
-static void on_confirmation_call_release_all(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- dbg("Entry");
- _on_confirmation_call_release(p, data_len, data, user_data, CALL_END_TYPE_ALL);
-
- return;
-}
-
-
-static void on_confirmation_call_release_specific(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- dbg("Entry");
- _on_confirmation_call_release(p, data_len, data, user_data, CALL_END_TYPE_DEFAULT);
-
- return;
-}
-
-static void on_confirmation_call_release_all_active(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- dbg("Entry");
- _on_confirmation_call_release(p, data_len, data, user_data, CALL_END_TYPE_ACTIVE_ALL);
-
- return;
-}
-
-static void on_confirmation_call_release_all_held(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- dbg("Entry");
- _on_confirmation_call_release(p, data_len, data, user_data, CALL_END_TYPE_HOLD_ALL);
-
- return;
-}
-
-static void _on_confirmation_call(TcorePending *p, int data_len, const void *data, void *user_data, int type)
-{
- UserRequest *ur = NULL;
- GSList *tokens = NULL;
- const char *line = NULL;
- const TcoreATResponse *response = NULL;
- enum telephony_call_error error;
-
- dbg("Entry");
- ur = tcore_pending_ref_user_request(p);
- response = (TcoreATResponse *) data;
- if (response->success > 0) {
- dbg("RESPONSE OK");
- error = CALL_ERROR_NONE;
- } else {
- err("RESPONSE NOT OK");
-
- line = (const char *) response->final_response;
- tokens = tcore_at_tok_new(line);
-
- if (g_slist_length(tokens) < 1) {
- err("Unspecified error cause OR string corrupted");
- error = CALL_ERROR_SERVICE_UNAVAIL;
- } else {
- error = atoi(g_slist_nth_data(tokens, 0));
-
- // TODO: CMEE error mapping is required.
- error = CALL_ERROR_SERVICE_UNAVAIL;
- }
-
- // Free tokens
- tcore_at_tok_free(tokens);
- }
-
- dbg("Response Call type -%d", type);
- switch (type) {
- case TRESP_CALL_HOLD:
- {
- struct tresp_call_hold resp;
-
- resp.err = error;
- resp.id = tcore_call_object_get_id((CallObject *) user_data);
- dbg("call hold response");
- // Send reponse to TAPI
- tcore_user_request_send_response(ur, TRESP_CALL_HOLD, sizeof(struct tresp_call_hold), &resp);
- }
- break;
-
- case TRESP_CALL_ACTIVE:
- {
- struct tresp_call_active resp;
-
- resp.err = error;
- resp.id = tcore_call_object_get_id((CallObject *) user_data);
- dbg("call active response");
- // Send reponse to TAPI
- tcore_user_request_send_response(ur, TRESP_CALL_ACTIVE, sizeof(struct tresp_call_active), &resp);
- }
- break;
-
- case TRESP_CALL_JOIN:
- {
- struct tresp_call_join resp;
-
- resp.err = error;
- resp.id = tcore_call_object_get_id((CallObject *) user_data);
- dbg("call join response");
-
- // Send reponse to TAPI
- tcore_user_request_send_response(ur, TRESP_CALL_JOIN, sizeof(struct tresp_call_join), &resp);
- }
- break;
-
- case TRESP_CALL_SPLIT:
- {
- struct tresp_call_split resp;
-
- resp.err = error;
- resp.id = tcore_call_object_get_id((CallObject *) user_data);
- dbg("call split response");
- // Send reponse to TAPI
- tcore_user_request_send_response(ur, TRESP_CALL_SPLIT, sizeof(struct tresp_call_split), &resp);
- }
- break;
-
- case TRESP_CALL_DEFLECT:
- {
- struct tresp_call_deflect resp;
-
- resp.err = error;
- resp.id = tcore_call_object_get_id((CallObject *) user_data);
- dbg("call deflect response");
- // Send reponse to TAPI
- tcore_user_request_send_response(ur, TRESP_CALL_DEFLECT, sizeof(struct tresp_call_deflect), &resp);
- }
-
- break;
-
- case TRESP_CALL_TRANSFER:
- {
- struct tresp_call_transfer resp;
-
- resp.err = error;
- resp.id = tcore_call_object_get_id((CallObject *) user_data);
- dbg("call transfer response");
- // Send reponse to TAPI
- tcore_user_request_send_response(ur, TRESP_CALL_TRANSFER, sizeof(struct tresp_call_transfer), &resp);
- }
- break;
-
- case TRESP_CALL_SEND_DTMF:
- {
- struct tresp_call_dtmf resp;
-
- resp.err = error;
- dbg("call dtmf response");
- // Send reponse to TAPI
- tcore_user_request_send_response(ur, TRESP_CALL_SEND_DTMF, sizeof(struct tresp_call_dtmf), &resp);
- }
- break;
-
- default:
- {
- dbg("type not supported");
- return;
- }
- }
-
- if ((type == TRESP_CALL_HOLD) || (type == TRESP_CALL_ACTIVE) || (type == TRESP_CALL_JOIN)
- || (type == TRESP_CALL_SPLIT)) {
- if (!error) {
- CoreObject *core_obj = NULL;
- gboolean *eflag = g_new0(gboolean, 1);
-
- core_obj = tcore_pending_ref_core_object(p);
- *eflag = FALSE;
-
- dbg("Calling _call_list_get");
- _call_list_get(core_obj, eflag);
- }
- }
-
- dbg("Exit");
- return;
-}
-
-static void on_confirmation_call_hold(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- dbg("Entry");
- _on_confirmation_call(p, data_len, data, user_data, TRESP_CALL_HOLD);
-
- return;
-}
-
-static void on_confirmation_call_active(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- dbg("Entry");
- _on_confirmation_call(p, data_len, data, user_data, TRESP_CALL_ACTIVE);
-
- return;
-}
-
-static void on_confirmation_call_join(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- dbg("Entry");
- _on_confirmation_call(p, data_len, data, user_data, TRESP_CALL_JOIN);
-
- return;
-}
-
-static void on_confirmation_call_split(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- dbg("Entry");
- _on_confirmation_call(p, data_len, data, user_data, TRESP_CALL_SPLIT);
-
- return;
-}
-
-static void on_confirmation_call_deflect(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- dbg("Entry");
- _on_confirmation_call(p, data_len, data, user_data, TRESP_CALL_DEFLECT);
-
- return;
-}
-
-static void on_confirmation_call_transfer(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- dbg("Entry");
- _on_confirmation_call(p, data_len, data, user_data, TRESP_CALL_TRANSFER);
-
- return;
-}
-
-static void on_confirmation_call_dtmf(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- dbg("Entry");
- _on_confirmation_call(p, data_len, data, user_data, TRESP_CALL_SEND_DTMF);
-
- return;
-}
-
-static void _on_confirmation_dtmf_tone_duration(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- GSList *tokens = NULL;
- const char *line = NULL;
- const TcoreATResponse *response = data;
- enum telephony_call_error error;
-
- dbg("Entry");
-
- if (response->success > 0) {
- dbg("RESPONSE OK");
- error = CALL_ERROR_NONE;
- } else {
- err("RESPONSE NOT OK");
- line = (const char *) response->final_response;
- tokens = tcore_at_tok_new(line);
- if (g_slist_length(tokens) < 1) {
- err("err cause not specified or string corrupted");
- error = CALL_ERROR_SERVICE_UNAVAIL;
- } else {
- error = atoi(g_slist_nth_data(tokens, 0));
- // TODO: CMEE error mapping is required.
- }
-
- // Free tokens
- tcore_at_tok_free(tokens);
- }
-
- dbg("Set dtmf tone duration response - %d", error);
- return;
-}
-
-static void on_confirmation_call_swap(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- CoreObject *core_obj = NULL;
- UserRequest *ur = NULL;
- const TcoreATResponse *response = data;
- struct tresp_call_swap resp;
- GSList *tokens = NULL;
- const char *line = NULL;
-
- dbg("Entry");
- core_obj = tcore_pending_ref_core_object(p);
- ur = tcore_pending_ref_user_request(p);
-
- if (ur) {
- if (response->success > 0) {
- dbg("RESPONSE OK");
- resp.err = CALL_ERROR_NONE;
- } else {
- err("RESPONSE NOT OK");
- line = (const char *) response->final_response;
- tokens = tcore_at_tok_new(line);
- if (g_slist_length(tokens) < 1) {
- err("err cause not specified or string corrupted");
- resp.err = CALL_ERROR_SERVICE_UNAVAIL;
- } else {
- resp.err = atoi(g_slist_nth_data(tokens, 0));
-
- // TODO: CMEE error mapping is required.
- resp.err = CALL_ERROR_SERVICE_UNAVAIL;
- }
-
- // Free tokens
- tcore_at_tok_free(tokens);
- }
-
- resp.id = tcore_call_object_get_id((CallObject *) user_data);
- dbg("resp.id = %d", resp.id);
-
- // Send response to TAPI
- tcore_user_request_send_response(ur, TRESP_CALL_SWAP, sizeof(struct tresp_call_swap), &resp);
-
- if (!resp.err) {
- GSList *active = NULL;
- GSList *held = NULL;
- CallObject *co = NULL;
- gboolean *eflag = NULL;
-
- held = tcore_call_object_find_by_status(core_obj, TCORE_CALL_STATUS_HELD);
- if (!held) {
- err("Can't find held Call");
- return;
- }
-
- active = tcore_call_object_find_by_status(core_obj, TCORE_CALL_STATUS_ACTIVE);
- if (!active) {
- dbg("Can't find active Call");
- return;
- }
-
- while (held) {
- co = (CallObject *) held->data;
- if (!co) {
- err("Can't get held Call object");
- return;
- }
-
- resp.id = tcore_call_object_get_id(co);
-
- // Send response to TAPI
- tcore_user_request_send_response(ur, TRESP_CALL_ACTIVE, sizeof(struct tresp_call_active), &resp);
-
- held = g_slist_next(held);
- }
-
- while (active) {
- co = (CallObject *) active->data;
- if (!co) {
- err("[ error ] can't get active call object");
- return;
- }
-
- resp.id = tcore_call_object_get_id(co);
-
- // Send response to TAPI
- tcore_user_request_send_response(ur, TRESP_CALL_HOLD, sizeof(struct tresp_call_hold), &resp);
- active = g_slist_next(active);
- }
-
- eflag = g_new0(gboolean, 1);
- *eflag = FALSE;
-
- dbg("calling _call_list_get");
- _call_list_get(core_obj, eflag);
- }
- } else {
- err("User Request is NULL");
- }
-
- dbg("Exit");
- return;
-}
-
-static void on_confirmation_set_sound_path(TcorePending *p, int data_len,
- const void *data,
- void *user_data)
-{
- const TcoreATResponse *resp = data;
- struct tnoti_call_sound_path *snd_path = user_data;
- struct tresp_call_sound_set_path resp_set_sound_path;
- UserRequest *ur = tcore_pending_ref_user_request(p);
- TcorePlugin *plugin = tcore_pending_ref_plugin(p);
- CoreObject *co_call;
-
- if (ur == NULL) {
- err("User Request is NULL");
- g_free(user_data);
- return;
- }
-
- if (resp->success <= 0) {
-
- dbg("RESPONSE NOT OK");
- resp_set_sound_path.err = TRUE;
-
- goto out;
- }
-
- dbg("RESPONSE OK");
- resp_set_sound_path.err = FALSE;
-
- co_call = tcore_plugin_ref_core_object(plugin, CORE_OBJECT_TYPE_CALL);
-
- /* Notify control plugin about sound path */
- tcore_server_send_notification(tcore_plugin_ref_server(plugin),
- co_call, TNOTI_CALL_SOUND_PATH,
- sizeof(struct tnoti_call_sound_path),
- snd_path);
-
-out:
- /* Answer TAPI request */
- tcore_user_request_send_response(ur, TRESP_CALL_SET_SOUND_PATH,
- sizeof(resp_set_sound_path),
- &resp_set_sound_path);
-
- g_free(user_data);
-}
-
-static void on_confirmation_call_set_source_sound_path(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- UserRequest *ur = NULL;
- GSList *tokens = NULL;
- const char *line = NULL;
- const TcoreATResponse *response = data;
- char *resp_str = NULL;
- struct tresp_call_sound_set_path resp;
- gboolean error;
-
- dbg("Entry");
- ur = tcore_pending_ref_user_request(p);
-
- // +XDRV: <group_id>,<function_id>,<xdrv_result>[,<response_n>]\ 3
- if (!response) {
- err("Input data is NULL");
- return;
- }
-
- if (response->success > 0) {
- dbg("RESPONSE OK");
-
- line = (const char *) (((GSList *) response->lines)->data);
- tokens = tcore_at_tok_new(line);
-
- resp_str = g_slist_nth_data(tokens, 0);
- if (!g_slist_nth_data(tokens, 0)) {
- err("group_id is missing");
- resp.err = TRUE;
- goto OUT;
- }
-
- if (!g_slist_nth_data(tokens, 1)) {
- err(" function_id is missing");
- resp.err = TRUE;
- goto OUT;
- }
-
- resp_str = g_slist_nth_data(tokens, 2);
-
- if (resp_str) {
- error = atoi(resp_str);
- if (0 == error) {
- dbg("Response is Success");
- resp.err = FALSE;
- } else {
- resp.err = TRUE;
- }
- }
-OUT:
- // Free tokens
- tcore_at_tok_free(tokens);
- } else {
- dbg("RESPONSE NOT OK");
-
- line = (const char *) response->final_response;
- tokens = tcore_at_tok_new(line);
-
- if (g_slist_length(tokens) < 1) {
- err("err cause not specified or string corrupted");
- resp.err = TRUE;
- } else {
- error = atoi(g_slist_nth_data(tokens, 0));
-
- // TODO: CMEE error mapping is required.
- resp.err = TRUE;
- }
-
- // Free tokens
- tcore_at_tok_free(tokens);
- }
-
- if (ur) {
- if ( resp.err ) { // Send only failed notification . success notification send when destination device is set.
- // Send notification to TAPI
- tcore_user_request_send_response(ur, TRESP_CALL_SET_SOUND_PATH, sizeof(struct tresp_call_sound_set_path), &resp);
- setsoundpath = TRUE;
- }
- } else {
- err("User Request is NULL");
- }
-
- dbg("Exit");
- return;
-}
-
-static void on_confirmation_call_set_destination_sound_path(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- UserRequest *ur = NULL;
- GSList *tokens = NULL;
- const char *line = NULL;
- char *resp_str = NULL;
- struct tresp_call_sound_set_path resp;
- const TcoreATResponse *response = data;
- gboolean error;
-
- dbg("Entry");
-
- ur = tcore_pending_ref_user_request(p);
- // +XDRV: <group_id>,<function_id>,<xdrv_result>[,<response_n>]\ 3
-
- if (!response) {
- err("Input data is NULL");
- return;
- }
-
- if (ur) {
- if (response->success > 0) {
- dbg("RESPONSE OK");
-
- line = (const char *) (((GSList *) response->lines)->data);
- tokens = tcore_at_tok_new(line);
-
- resp_str = g_slist_nth_data(tokens, 0);
- if (!g_slist_nth_data(tokens, 0)) {
- dbg("group_id is missing");
- resp.err = TRUE;
- goto OUT;
- }
-
- if (!g_slist_nth_data(tokens, 1)) {
- dbg("function_id is missing");
- resp.err = TRUE;
- goto OUT;
- }
-
- resp_str = g_slist_nth_data(tokens, 2);
- if (resp_str) {
- error = atoi(resp_str);
- if (0 == error) {
- dbg("Response is Success");
- resp.err = FALSE;
- } else {
- resp.err = TRUE;
- }
- }
-
-OUT:
- // Free tokens
- tcore_at_tok_free(tokens);
- } else {
- dbg("RESPONSE NOT OK");
-
- line = (const char *) response->final_response;
- tokens = tcore_at_tok_new(line);
-
- if (g_slist_length(tokens) < 1) {
- err("err cause not specified or string corrupted");
- resp.err = TRUE;
- } else {
- error = atoi(g_slist_nth_data(tokens, 0));
- // TODO: CMEE error mapping is required.
- resp.err = TRUE;
- }
-
- // Free tokens
- tcore_at_tok_free(tokens);
- }
-
- if (setsoundpath == TRUE) {
- setsoundpath = FALSE;
- } else {
- // Send response to TAPI
- tcore_user_request_send_response(ur, TRESP_CALL_SET_SOUND_PATH, sizeof(struct tresp_call_sound_set_path), &resp);
- }
- } else {
- dbg("User Request is NULL");
- }
-
- dbg("Exit");
- return;
-}
-
-static void on_confirmation_call_set_source_sound_volume_level(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- UserRequest *ur = NULL;
- GSList *tokens = NULL;
- const char *line = NULL;
- const TcoreATResponse *response = data;
- char *resp_str = NULL;
- struct tresp_call_sound_set_volume_level resp;
- gboolean error;
-
- ur = tcore_pending_ref_user_request(p);
- dbg("Entry");
- // +XDRV: <group_id>,<function_id>,<xdrv_result>[,<response_n>]\ 3
- if (!response) {
- err("Input data is NULL");
- return;
- }
-
- if (response->success > 0) {
- dbg("RESPONSE OK");
-
- line = (const char *) (((GSList *) response->lines)->data);
- tokens = tcore_at_tok_new(line);
-
- resp_str = g_slist_nth_data(tokens, 0);
- if (!g_slist_nth_data(tokens, 0)) {
- err("group_id is missing");
- resp.err = TRUE;
- goto OUT;
- }
-
- if (!g_slist_nth_data(tokens, 1)) {
- err("function_id is missing");
- resp.err = TRUE;
- goto OUT;
- }
-
- resp_str = g_slist_nth_data(tokens, 2);
- if (resp_str) {
- error = atoi(resp_str);
-
- if (0 == error) {
- dbg("Response is Success ");
- resp.err = FALSE;
- } else {
- resp.err = TRUE;
- }
- }
-
-OUT:
- // Free tokens
- tcore_at_tok_free(tokens);
- } else {
- dbg("RESPONSE NOT OK");
-
- line = (const char *) response->final_response;
- tokens = tcore_at_tok_new(line);
-
- if (g_slist_length(tokens) < 1) {
- err("err cause not specified or string corrupted");
- resp.err = TRUE;
- } else {
- error = atoi(g_slist_nth_data(tokens, 0));
-
- // TODO: CMEE error mapping is required.
- resp.err = TRUE;
- }
-
- // Free tokens
- tcore_at_tok_free(tokens);
- }
-
- if (ur) {
- if (resp.err && soundvolume == FALSE) { // Send only failed notification . success notification send when destination device is set.
- // Send reposne to TAPI
- tcore_user_request_send_response(ur, TRESP_CALL_SET_SOUND_VOLUME_LEVEL, sizeof(struct tresp_call_sound_set_volume_level), &resp);
- soundvolume = TRUE;
- }
- } else {
- err("User Request is NULL");
- }
-
- dbg("Exit");
- return;
-}
-
-
-static void on_confirmation_call_set_destination_sound_volume_level(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- UserRequest *ur = NULL;
- GSList *tokens = NULL;
- const char *line = NULL;
- char *resp_str = NULL;
- const TcoreATResponse *response = data;
- struct tresp_call_sound_set_volume_level resp;
- gboolean error;
-
- dbg("Entry");
-
- ur = tcore_pending_ref_user_request(p);
-
- // +XDRV: <group_id>,<function_id>,<xdrv_result>[,<response_n>]\ 3
- if (!response) {
- err("Input data is NULL");
- return;
- }
-
- if (ur) {
- if (response->success > 0) {
- dbg("RESPONSE OK");
- line = (const char *) (((GSList *) response->lines)->data);
- tokens = tcore_at_tok_new(line);
- resp_str = g_slist_nth_data(tokens, 0);
-
- if (!g_slist_nth_data(tokens, 0)) {
- err("group_id is missing");
- resp.err = TRUE;
- goto OUT;
- }
-
- if (!g_slist_nth_data(tokens, 1)) {
- err("function_id is missing");
- resp.err = TRUE;
- goto OUT;
- }
-
- resp_str = g_slist_nth_data(tokens, 2);
-
- if (resp_str) {
- error = atoi(resp_str);
-
- if (0 == error) {
- dbg("Response is Success");
- resp.err = FALSE;
- } else {
- resp.err = TRUE;
- }
- }
-
-OUT:
- // Free tokens
- tcore_at_tok_free(tokens);
- } else {
- dbg("RESPONSE NOT OK");
-
- line = (const char *) response->final_response;
- tokens = tcore_at_tok_new(line);
-
- if (g_slist_length(tokens) < 1) {
- err("err cause not specified or string corrupted");
- resp.err = TRUE;
- } else {
- error = atoi(g_slist_nth_data(tokens, 0));
-
- // TODO: CMEE error mapping is required.
- resp.err = TRUE;
- }
-
- tcore_at_tok_free(tokens);
- }
-
- if (soundvolume == TRUE) {
- soundvolume = FALSE;
- } else {
- // Send reposne to TAPI
- tcore_user_request_send_response(ur, TRESP_CALL_SET_SOUND_VOLUME_LEVEL, sizeof(struct tresp_call_sound_set_volume_level), &resp);
- }
- } else {
- err("User Request is NULL");
- }
-
- dbg("Exit");
- return;
-}
-
-
-static void on_confirmation_call_mute(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- UserRequest *ur = NULL;
- GSList *tokens = NULL;
- const char *line = NULL;
- char *resp_str = NULL;
- struct tresp_call_mute resp;
- const TcoreATResponse *response = data;
- gboolean error;
-
- dbg("Entry");
-
- ur = tcore_pending_ref_user_request(p);
-
- if (!response) {
- err("Input data is NULL");
- return;
- }
-
- if (response->success > 0) {
- dbg("RESPONSE OK");
-
- line = (const char *) (((GSList *) response->lines)->data);
- tokens = tcore_at_tok_new(line);
- resp_str = g_slist_nth_data(tokens, 0);
-
- if (!g_slist_nth_data(tokens, 0)) {
- err("group_id is missing");
- resp.err = TRUE;
- goto OUT;
- }
-
- if (!g_slist_nth_data(tokens, 1)) {
- err(" function_id is missing");
- resp.err = TRUE;
- goto OUT;
- }
-
- resp_str = g_slist_nth_data(tokens, 2);
-
- if (resp_str) {
- error = atoi(resp_str);
- if (0 == error) {
- dbg("Response is Success");
- resp.err = FALSE;
- } else {
- resp.err = TRUE;
- }
- }
-OUT:
- // Free tokens
- tcore_at_tok_free(tokens);
- } else {
- dbg("RESPONSE NOT OK");
-
- line = (const char *) response->final_response;
- tokens = tcore_at_tok_new(line);
-
- if (g_slist_length(tokens) < 1) {
- err("err cause not specified or string corrupted");
- resp.err = TRUE;
- } else {
- error = atoi(g_slist_nth_data(tokens, 0));
-
- // TODO: CMEE error mapping is required.
- resp.err = TRUE;
- }
-
- // Free tokens
- tcore_at_tok_free(tokens);
- }
-
- if (ur) {
- tcore_user_request_send_response(ur, TRESP_CALL_MUTE, sizeof(struct tresp_call_mute), &resp);
- } else {
- err("User Request is NULL");
- }
-
- dbg("Exit");
- return;
-}
-
-static void on_confirmation_call_unmute(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- const TcoreATResponse *response = NULL;
- struct tresp_call_unmute resp;
- GSList *tokens = NULL;
- const char *line = NULL;
- UserRequest *ur = NULL;
- char *resp_str = NULL;
- gboolean error;
-
- dbg("Entry");
-
- response = (TcoreATResponse *) data;
- ur = tcore_pending_ref_user_request(p);
-
- if (!response) {
- err("Input data is NULL");
- return;
- }
-
- if (response->success > 0) {
- dbg("RESPONSE OK");
-
- line = (const char *) (((GSList *) response->lines)->data);
- tokens = tcore_at_tok_new(line);
- resp_str = g_slist_nth_data(tokens, 0);
-
- if (!g_slist_nth_data(tokens, 0)) {
- err("group_id is missing");
- resp.err = TRUE;
- goto OUT;
- }
-
- if (!g_slist_nth_data(tokens, 1)) {
- err(" function_id is missing");
- resp.err = TRUE;
- goto OUT;
- }
-
- resp_str = g_slist_nth_data(tokens, 2);
-
- if (resp_str) {
- error = atoi(resp_str);
- if (0 == error) {
- dbg("Response is Success");
- resp.err = FALSE;
- } else {
- resp.err = TRUE;
- }
- }
-OUT:
- // Free tokens
- tcore_at_tok_free(tokens);
- } else {
- dbg("RESPONSE NOT OK");
-
- line = (const char *) response->final_response;
- tokens = tcore_at_tok_new(line);
-
- if (g_slist_length(tokens) < 1) {
- err("err cause not specified or string corrupted");
- resp.err = TRUE;
- } else {
- error = atoi(g_slist_nth_data(tokens, 0));
-
- // TODO: CMEE error mapping is required.
- resp.err = TRUE;
- }
-
- // Free tokens
- tcore_at_tok_free(tokens);
- }
-
- if (ur) {
- tcore_user_request_send_response(ur, TRESP_CALL_UNMUTE, sizeof(struct tresp_call_unmute), &resp);
- } else {
- err("User Request is NULL");
- }
-
- dbg("Exit");
- return;
-}
-
-// RESPONSE
-static void on_response_call_list_get(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- TcorePlugin *plugin = NULL;
- CoreObject *core_obj = NULL;
- CallObject *co = NULL;
- struct clcc_call_t *call_list = NULL;
- gboolean *event_flag = (gboolean *) user_data;
- const TcoreATResponse *response = data;
- GSList *resp_data = NULL;
- char *line = NULL;
-
- int cllc_info = 0, countCalls = 0, countValidCalls = 0;
- int error = 0;
-
- dbg("Entry");
-
- plugin = tcore_pending_ref_plugin(p);
- core_obj = tcore_pending_ref_core_object(p);
-
- if (response->success > 0) {
- dbg("RESPONCE OK");
- if (response->lines) {
- resp_data = (GSList *) response->lines;
- countCalls = g_slist_length(resp_data);
- dbg("Total records : %d", countCalls);
- }
-
- if (0 == countCalls) {
- err("Call count is zero");
- if (event_flag) {
- g_free(event_flag);
- event_flag = NULL;
- }
- return;
- }
-
- call_list = g_new0(struct clcc_call_t, countCalls);
-
- for (countValidCalls = 0; resp_data != NULL; resp_data = resp_data->next, countValidCalls++, cllc_info++) {
- line = (char *) (resp_data->data);
-
- error = _callFromCLCCLine(line, call_list + countValidCalls);
- if (0 != error) {
- continue;
- }
-
- co = tcore_call_object_find_by_id(core_obj, call_list[cllc_info].info.id);
- if (!co) {
- co = tcore_call_object_new(core_obj, call_list[cllc_info].info.id);
- if (!co) {
- err("error : tcore_call_object_new [ id : %d ]", call_list[cllc_info].info.id);
- continue;
- }
- }
-
- // Call set parameters
- tcore_call_object_set_type(co, call_type(call_list[cllc_info].info.type));
- tcore_call_object_set_direction(co, call_list[cllc_info].info.direction);
- tcore_call_object_set_multiparty_state(co, _call_is_in_mpty(call_list[cllc_info].info.mpty));
- tcore_call_object_set_cli_info(co, CALL_CLI_MODE_DEFAULT, call_list[cllc_info].number);
- tcore_call_object_set_active_line(co, 0);
-
- if (*event_flag) {
- dbg("Call status before calling _call_branch_by_status() : (%d)", call_list[cllc_info].info.status);
- _call_branch_by_status(plugin, co, call_list[cllc_info].info.status);
- } else {
- // Set Status
- tcore_call_object_set_status(co, call_list[cllc_info].info.status);
-
- dbg("Call id : (%d)", call_list[cllc_info].info.id);
- dbg("Call direction : (%d)", call_list[cllc_info].info.direction);
- dbg("Call type : (%d)", call_list[cllc_info].info.type);
- dbg("Call mpty : (%d)", call_list[cllc_info].info.mpty);
- dbg("Call number : (%s)", call_list[cllc_info].number);
- dbg("Call status : (%d)", call_list[cllc_info].info.status);
- }
- }
-
- // Free Call list
- g_free(call_list);
- }
-
- // Free User data
- if (event_flag) {
- g_free(event_flag);
- event_flag = NULL;
- }
-
- dbg("Exit");
- return;
-}
-
-static void _on_confirmation_call_end_cause(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- TcorePlugin *plugin = NULL;
- CoreObject *core_obj = NULL;
- CallObject *co = (CallObject *) user_data;
- const TcoreATResponse *response = data;
- const char *line = NULL;
- struct tnoti_call_status_idle call_status;
- GSList *tokens = NULL;
- char *resp_str;
- int error;
-
- dbg("Entry");
- plugin = tcore_pending_ref_plugin(p);
- core_obj = tcore_pending_ref_core_object(p);
-
- if (response->success > 0) {
- dbg("RESPONSE OK");
- line = (const char *) (((GSList *) response->lines)->data);
- tokens = tcore_at_tok_new(line);
- resp_str = g_slist_nth_data(tokens, 0);
- if (!resp_str) {
- err("call end cause - report value missing");
- } else {
- resp_str = g_slist_nth_data(tokens, 1);
- if (!resp_str) {
- err("call end cause value missing");
- }
- error = atoi(resp_str);
- dbg("call end cause - %d", error);
- call_status.cause = _compare_call_end_cause(error);
- dbg("TAPI call end cause - %d", call_status.cause);
- }
-
- // Free tokens
- tcore_at_tok_free(tokens);
- } else {
- err("RESPONSE NOT OK");
- line = (char *) response->final_response;
- tokens = tcore_at_tok_new(line);
- if (g_slist_length(tokens) < 1) {
- err("err cause not specified or string corrupted");
- } else {
- err(" err cause value: %d", atoi(g_slist_nth_data(tokens, 0)));
- }
- call_status.cause = CC_CAUSE_NORMAL_CALL_CLEARING;
- // Free tokens
- tcore_at_tok_free(tokens);
- }
-
- call_status.type = tcore_call_object_get_type(co);
- dbg("data.type : [%d]", call_status.type);
-
- call_status.id = tcore_call_object_get_id(co);
- dbg("data.id : [%d]", call_status.id);
-
- // Set Status
- tcore_call_object_set_status(co, TCORE_CALL_STATUS_IDLE);
-
- // Send Notification to TAPI
- tcore_server_send_notification(tcore_plugin_ref_server(plugin),
- core_obj,
- TNOTI_CALL_STATUS_IDLE,
- sizeof(struct tnoti_call_status_idle),
- (void *) &call_status);
-
- // Free Call object
- tcore_call_object_free(core_obj, co);
-}
-
-static int _callFromCLCCLine(char *line, struct clcc_call_t *p_call)
-{
- // +CLCC: 1,0,2,0,0,"18005551212",145
- // [+CLCC: <id1>, <dir>, <stat>, <mode>,<mpty>[,<number>,<type>[,<alpha>[,<priority>]]]
- int state;
- int mode;
- int isMT;
- char *num = NULL;
- unsigned int num_type;
- GSList *tokens = NULL;
- char *resp = NULL;
-
- dbg("Entry");
-
- tokens = tcore_at_tok_new(line);
- // parse <id>
- resp = g_slist_nth_data(tokens, 0);
- if (!resp) {
- err("InValid ID");
- goto ERROR;
- }
- p_call->info.id = atoi(resp);
- dbg("id : [%d]\n", p_call->info.id);
-
- // parse <dir>
- resp = g_slist_nth_data(tokens, 1);
- if (!resp) {
- err("InValid Dir");
- goto ERROR;
- }
- isMT = atoi(resp);
- if (0 == isMT) {
- 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);
-
- // parse <stat>
- resp = g_slist_nth_data(tokens, 2);
- if (!resp) {
- err("InValid Stat");
- goto ERROR;
- }
- state = atoi(resp);
- dbg("Call state : %d", state);
- 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);
-
- // parse <mode>
- resp = g_slist_nth_data(tokens, 3);
- if (!resp) {
- err("InValid Mode");
- goto ERROR;
- }
- mode = atoi(resp);
- 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;
- }
- dbg("Call type : [%d]\n", p_call->info.type);
-
- // parse <mpty>
- resp = g_slist_nth_data(tokens, 4);
- if (!resp) {
- err("InValid Mpty");
- goto ERROR;
- }
-
- p_call->info.mpty = atoi(resp);
- dbg("Mpty : [ %d ]\n", p_call->info.mpty);
-
- // parse <num>
- resp = g_slist_nth_data(tokens, 5);
- dbg("Incoming number - %s and its len - %d", resp, strlen(resp));
-
- // tolerate null here
- if (!resp) {
- err("Number is NULL");
- goto ERROR;
- }
- // Strike off double quotes
- num = util_removeQuotes(resp);
- dbg("num after removing quotes - %s", num);
-
- p_call->info.num_len = strlen(resp);
- dbg("num_len : [0x%x]\n", p_call->info.num_len);
-
- // parse <num type>
- resp = g_slist_nth_data(tokens, 6);
- if (!resp) {
- dbg("InValid Num type");
- goto ERROR;
- }
- p_call->info.num_type = atoi(resp);
- dbg("BCD num type: [0x%x]\n", p_call->info.num_type);
-
- // check number is international or national.
- num_type = ((p_call->info.num_type) >> 4) & 0x07;
- dbg("called party's type of number : [0x%x]\n", num_type);
-
- if (num_type == 1 && num[0] != '+') {
- // international number
- p_call->number[0] = '+';
- memcpy(&(p_call->number[1]), num, strlen(num));
- } else {
- memcpy(&(p_call->number), num, strlen(num));
- }
- dbg("incoming number - %s", p_call->number);
-
- g_free(num);
- num = NULL;
- // Free tokens
- tcore_at_tok_free(tokens);
-
- dbg("Exit");
- return 0;
-
-ERROR:
- err("Invalid CLCC line");
-
- g_free(num);
-
- // Free tokens
- tcore_at_tok_free(tokens);
- err("Exit");
- return -1;
-}
-
-// NOTIFICATION
-static void on_notification_call_waiting(CoreObject *o, const void *data, void *user_data)
-{
- GSList *tokens = NULL;
- const char *line = NULL;
- char *pId;
- int call_id;
- gboolean *eflag;
- GSList *pList = NULL;
- CallObject *co = NULL, *dupco = NULL;
-
- dbg("function entrance");
- // check call with waiting status already exist
- pList = tcore_call_object_find_by_status(o, TCORE_CALL_STATUS_WAITING);
-
- if (pList != NULL) {
- dbg("[error]Waiting call already exist. skip");
- return;
- }
- // check call with incoming status already exist
- pList = tcore_call_object_find_by_status(o, TCORE_CALL_STATUS_INCOMING);
-
- if (pList != NULL) {
- dbg("[error]incoming call already exist. skip");
- return;
- }
- line = (char *) data;
- tokens = tcore_at_tok_new(line);
-
- pId = g_slist_nth_data(tokens, 0);
- if (!pId) {
- dbg("[error]:Call id is missing from +XCALLSTAT indication");
- tcore_at_tok_free(tokens);
- return;
- }
-
- call_id = atoi(pId);
- dupco = tcore_call_object_find_by_id(o, call_id);
- if (dupco != NULL) {
- dbg("co with same id already exist. skip");
- tcore_at_tok_free(tokens);
- return;
- }
- co = tcore_call_object_new(o, call_id);
- if (!co) {
- dbg("[ error ] co is NULL");
- tcore_at_tok_free(tokens);
- return;
- }
-
- tcore_at_tok_free(tokens);
-
- eflag = g_new0(gboolean, 1);
- *eflag = TRUE;
- dbg("calling _call_list_get");
- _call_list_get(o, eflag);
-}
-
-static void on_notification_call_incoming(CoreObject *o, const void *data, void *user_data)
-{
- GSList *tokens = NULL;
- const char *line = NULL;
- char *pId;
- int call_id;
- gboolean *eflag;
- GSList *pList = NULL;
- CallObject *co = NULL, *dupco = NULL;
-
- dbg("function entrance");
- // 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;
- }
-
- line = (char *) data;
- tokens = tcore_at_tok_new(line);
-
- pId = g_slist_nth_data(tokens, 0);
- if (!pId) {
- dbg("Error:Call id is missing from %XCALLSTAT indication");
- tcore_at_tok_free(tokens);
- return;
- }
-
- call_id = atoi(pId);
-
- dupco = tcore_call_object_find_by_id(o, call_id);
- if (dupco != NULL) {
- dbg("co with same id already exist. skip");
- tcore_at_tok_free(tokens);
- return;
- }
-
- co = tcore_call_object_new(o, call_id);
- if (!co) {
- dbg("[ error ] co is NULL");
- tcore_at_tok_free(tokens);
- return;
- }
-
- dbg("freeing at token");
- tcore_at_tok_free(tokens);
-
- eflag = g_new0(gboolean, 1);
- *eflag = TRUE;
-
- dbg("calling _call_list_get");
- _call_list_get(o, eflag);
-}
-
-static void on_notification_call_status(CoreObject *o, const void *data, void *user_data)
-{
- char *cmd = NULL;
- TcorePlugin *plugin = NULL;
- CallObject *co = NULL;
- int id = -1;
- int status = 0;
- int type = 0;
- char *stat = NULL;
- char *pCallId = NULL;
- GSList *tokens = NULL;
- gboolean *eflag = NULL;
- enum tcore_call_status co_status;
-
- dbg("function entrance");
- plugin = tcore_object_ref_plugin(o);
- cmd = (char *) data;
- tokens = tcore_at_tok_new(cmd);
-
- // parse <Call Id>
- pCallId = g_slist_nth_data(tokens, 0);
- if (!pCallId) {
- dbg("CallId is missing from %XCALLSTAT indication");
- tcore_at_tok_free(tokens);
- return;
- } else {
- id = atoi(pCallId);
- dbg("call id = %d", id);
- // parse <Stat>
- if ((stat = g_slist_nth_data(tokens, 1))) {
- status = atoi(stat);
- }
- dbg("call status = %d", status);
- }
-
- tcore_at_tok_free(tokens);
- co_status = _call_status(status);
-
- dbg("co_status = %d", co_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;
- }
- _call_status_active(plugin, co);
- }
- break;
-
- case CALL_STATUS_HELD:
- dbg("call(%d) status : [ held ]", id);
- 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;
- }
- }
-
- tcore_call_object_set_type(co, call_type(type));
- tcore_call_object_set_direction(co, TCORE_CALL_DIRECTION_OUTGOING);
- _call_status_dialing(plugin, 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;
- }
- // Store dialed number information into Call object.
- eflag = g_new0(gboolean, 1);
- *eflag = TRUE;
- dbg("calling _call_list_get");
- _call_list_get(o, eflag);
- }
- break;
-
- case CALL_STATUS_INCOMING:
- case CALL_STATUS_WAITING:
- dbg("call(%d) status : [ incoming ]", id);
- 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");
- return;
- }
-
- plugin = tcore_object_ref_plugin(o);
- if (!plugin) {
- dbg("plugin is NULL");
- return;
- }
- _call_status_idle(plugin, co);
- }
- break;
-
- default:
- dbg("invalid call status", id);
- break;
- }
-}
-
-static TReturn s_call_outgoing(CoreObject *o, UserRequest *ur)
-{
- struct treq_call_dial *data = 0;
- char *cmd_str;
- const char *cclir, *num;
- enum tcore_call_cli_mode clir = CALL_CLI_MODE_DEFAULT;
- TcorePending *pending;
- TcoreATRequest *req;
- gboolean ret;
-
- dbg("Entry");
-
- data = (struct treq_call_dial *) tcore_user_request_ref_data(ur, 0);
- if (data->type == CALL_TYPE_VIDEO) {
- dbg("invalid call type");
- return TCORE_RETURN_FAILURE;
- }
-
- clir = _get_clir_status(data->number);
-
- if (clir == TCORE_CALL_CLI_MODE_DEFAULT) {
- TcorePlugin *plugin = tcore_object_ref_plugin(o);
- Server *server = tcore_plugin_ref_server(plugin);
- Storage *strg;
-
- dbg("Reading VCONF key");
-
- strg = tcore_server_find_storage(server, "vconf");
- clir = tcore_storage_get_int(strg,
- STORAGE_KEY_CISSAPPL_SHOW_MY_NUMBER_INT);
-
- num = data->number;
- } else
- /* Need to remove CLIR code from dialing number */
- num = data->number + 4;
-
- /* Compose ATD Cmd string */
- switch (clir) {
- case TCORE_CALL_CLI_MODE_PRESENT:
- dbg("CALL_CLI_MODE_PRESENT");
- cclir = "i";
- break;
-
- case TCORE_CALL_CLI_MODE_RESTRICT:
- dbg("CALL_CLI_MODE_RESTRICT");
- cclir = "I";
- break;
-
- case TCORE_CALL_CLI_MODE_DEFAULT:
- default:
- cclir = "";
- dbg("CALL_CLI_MODE_DEFAULT");
- break;
- }
-
- dbg("data->number = %s", data->number);
-
- cmd_str = g_strdup_printf("ATD%s%s;", num, cclir);
-
- dbg("request command : %s", cmd_str);
-
- pending = tcore_pending_new(o, 0);
- req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
- dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
-
- tcore_pending_set_request_data(pending, 0, req);
- ret = _call_request_message(pending, o, ur, on_confirmation_call_outgoing, NULL);
-
- g_free(cmd_str);
-
- if (ret == FALSE) {
- dbg("AT request(%s) sent failed", req->cmd);
- return TCORE_RETURN_FAILURE;
- }
-
- dbg("AT request(%s) sent success", req->cmd);
-
- dbg("Exit");
-
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn s_call_answer(CoreObject *o, UserRequest *ur)
-{
- char *cmd_str = NULL;
- CallObject *co = NULL;
- struct treq_call_answer *data = 0;
- TcorePending *pending = NULL;
- TcoreATRequest *req;
- gboolean ret = FALSE;
-
- dbg("function entrance");
-
- if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
- dbg("cp not ready/n");
- return TCORE_RETURN_ENOSYS;
- }
-
- data = (struct treq_call_answer *) tcore_user_request_ref_data(ur, 0);
- co = tcore_call_object_find_by_id(o, data->id);
- if (data->type == CALL_ANSWER_TYPE_ACCEPT) {
- dbg(" request type CALL_ANSWER_TYPE_ACCEPT");
-
- cmd_str = g_strdup_printf("%s", "ATA");
- pending = tcore_pending_new(o, 0);
- req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
- dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
-
- tcore_pending_set_request_data(pending, 0, req);
- ret = _call_request_message(pending, o, ur, on_confirmation_call_accept, co);
- g_free(cmd_str);
-
- if (!ret) {
- dbg("AT request(%s) sent failed", req->cmd);
- 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 = NULL;
- struct treq_call_end *data = 0;
- UserRequest *ur_dup = NULL;
- char *chld0_cmd = NULL;
- char *chld1_cmd = NULL;
- TcorePending *pending = NULL, *pending1 = NULL;
- TcoreATRequest *req, *req1;
- gboolean ret = FALSE;
-
- dbg("function entrance");
- if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
- dbg("cp not ready/n");
- return TCORE_RETURN_ENOSYS;
- }
- data = (struct treq_call_end *) tcore_user_request_ref_data(ur, 0);
- co = tcore_call_object_find_by_id(o, data->id);
-
- dbg("type of release call = %d", data->type);
-
- 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");
- chld1_cmd = g_strdup("AT+CHLD=1");
-
- pending = tcore_pending_new(o, 0);
- req = tcore_at_request_new(chld0_cmd, NULL, TCORE_AT_NO_RESULT);
-
- dbg("input command is %s", chld0_cmd);
- dbg("req-cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
-
- tcore_pending_set_request_data(pending, 0, req);
- ur_dup = tcore_user_request_new(NULL, NULL);
- ret = _call_request_message(pending, o, ur_dup, on_confirmation_call_endall, NULL);
- g_free(chld0_cmd);
-
- if (!ret) {
- dbg("AT request %s has failed ", req->cmd);
- if (ur_dup) {
- tcore_user_request_free(ur_dup);
- ur_dup = NULL;
- }
- g_free(chld1_cmd);
- return TCORE_RETURN_FAILURE;
- }
-
- pending1 = tcore_pending_new(o, 0);
- req1 = tcore_at_request_new(chld1_cmd, NULL, TCORE_AT_NO_RESULT);
-
- dbg("input command is %s", chld1_cmd);
- dbg("req-cmd : %s, prefix(if any) :%s, cmd_len : %d", req1->cmd, req1->prefix, strlen(req1->cmd));
-
- tcore_pending_set_request_data(pending1, 0, req1);
- ret = _call_request_message(pending1, o, ur, on_confirmation_call_release_all, co);
- g_free(chld1_cmd);
-
- if (!ret) {
- dbg("AT request %s has failed ", req->cmd);
- 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 CALL_END_TYPE_HOLD_ALL:
- {
- 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 = NULL;
-
- dbg("function entrance");
-
- if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
- dbg("cp not ready/n");
- return TCORE_RETURN_ENOSYS;
- }
-
- hold = (struct treq_call_hold *) tcore_user_request_ref_data(ur, 0);
- 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 = NULL;
-
- if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
- dbg("cp not ready/n");
- return TCORE_RETURN_ENOSYS;
- }
-
- active = (struct treq_call_active *) tcore_user_request_ref_data(ur, 0);
- 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 = NULL;
- CallObject *co = NULL;
-
- if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
- dbg("cp not ready/n");
- return TCORE_RETURN_ENOSYS;
- }
-
- 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 = NULL;
-
- if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
- dbg("cp not ready/n");
- return TCORE_RETURN_ENOSYS;
- }
-
- 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 = NULL;
-
- if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
- dbg("cp not ready/n");
- return TCORE_RETURN_ENOSYS;
- }
-
- split = (struct treq_call_split *) tcore_user_request_ref_data(ur, 0);
- co = tcore_call_object_find_by_id(o, split->id);
- dbg("call id : [ %d ]", 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 = NULL;
-
- if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
- dbg("cp not ready/n");
- return TCORE_RETURN_ENOSYS;
- }
-
- deflect = (struct treq_call_deflect *) tcore_user_request_ref_data(ur, 0);
- co = tcore_call_object_find_by_number(o, deflect->number);
- dbg("deflect number: [ %s ]", 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 = NULL;
-
- if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
- dbg("cp not ready/n");
- return TCORE_RETURN_ENOSYS;
- }
-
- 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)
-{
- char *cmd_str = NULL;
- TcorePending *pending = NULL;
- TcoreATRequest *req;
- UserRequest *dup;
- gboolean ret = FALSE;
- struct treq_call_dtmf *dtmf = 0;
- char *dtmfstr = NULL, *tmp_dtmf = NULL;
- unsigned int dtmf_count;
-
- dbg("Function enter");
-
- if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
- dbg("cp not ready/n");
- return TCORE_RETURN_ENOSYS;
- }
-
- dup = tcore_user_request_new(NULL, NULL);
- (void) _set_dtmf_tone_duration(o, dup);
-
- dtmf = (struct treq_call_dtmf *) tcore_user_request_ref_data(ur, 0);
- dtmfstr = g_malloc0((MAX_CALL_DTMF_DIGITS_LEN * 2) + 1); // DTMF digits + comma for each dtmf digit.
-
- if (dtmfstr == NULL) {
- dbg("Memory allocation failed");
- return TCORE_RETURN_FAILURE;
- }
-
- tmp_dtmf = dtmfstr;
-
- for (dtmf_count = 0; dtmf_count < strlen(dtmf->digits); dtmf_count++) {
- *tmp_dtmf = dtmf->digits[dtmf_count];
- tmp_dtmf++;
-
- *tmp_dtmf = COMMA;
- tmp_dtmf++;
- }
-
- // last digit is having COMMA , overwrite it with '\0' .
- *(--tmp_dtmf) = '\0';
- dbg("Input DTMF string(%s)", dtmfstr);
-
- // AT+VTS = <d1>,<d2>,<d3>,<d4>,<d5>,<d6>, ..... <d32>
- cmd_str = g_strdup_printf("AT+VTS=%s", dtmfstr);
- dbg("request command : %s", cmd_str);
-
- pending = tcore_pending_new(o, 0);
- req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
- dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
-
- tcore_pending_set_request_data(pending, 0, req);
- ret = _call_request_message(pending, o, ur, on_confirmation_call_dtmf, NULL);
- g_free(dtmfstr);
- g_free(cmd_str);
-
- if (!ret) {
- dbg("AT request sent failed");
- return TCORE_RETURN_FAILURE;
- }
-
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn s_call_set_sound_path(CoreObject *o, UserRequest *ur)
-{
- UserRequest *ur_dup = NULL;
- TcorePending *pending = NULL, *pending1 = NULL;
- TcoreATRequest *req, *req1;
- char *cmd_str = NULL, *cmd_str1 = NULL;
- int device_type = -1;
- struct treq_call_sound_set_path *sound_path = 0;
- gboolean ret = FALSE;
- TcorePlugin *plugin = tcore_object_ref_plugin(o);
- const char *cp_name = tcore_server_get_cp_name_by_plugin(plugin);
-
- dbg("function entrance");
-
- if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
- dbg("cp not ready/n");
- return TCORE_RETURN_ENOSYS;
- }
- sound_path = (struct treq_call_sound_set_path *) tcore_user_request_ref_data(ur, 0);
- if (sound_path == NULL) {
- dbg("invaling user request");
- return TCORE_RETURN_FAILURE;
- }
- dbg("audio device type - 0x%x", sound_path->path);
- switch (sound_path->path) {
- case CALL_SOUND_PATH_HANDSET:
- device_type = 1;
- break;
-
- case CALL_SOUND_PATH_HEADSET:
- device_type = 2;
- break;
-
- case CALL_SOUND_PATH_HEADSET_3_5PI:
- device_type = 3;
- break;
-
- case CALL_SOUND_PATH_SPEAKER:
- device_type = 4;
- break;
-
- case CALL_SOUND_PATH_HANDFREE:
- device_type = 5;
- break;
-
- case CALL_SOUND_PATH_HEADSET_HAC:
- device_type = 6;
- break;
-
- case CALL_SOUND_PATH_BLUETOOTH:
- case CALL_SOUND_PATH_STEREO_BLUETOOTH:
- device_type = 7;
- break;
-
- case CALL_SOUND_PATH_BT_NSEC_OFF:
- case CALL_SOUND_PATH_MIC1:
- case CALL_SOUND_PATH_MIC2:
- default:
- dbg("unsupported device type");
- return TCORE_RETURN_FAILURE;
- }
-
- if (g_str_has_prefix(cp_name, "mfld_blackbay") == TRUE) {
- struct tnoti_call_sound_path *tnoti_snd_path;
-
- tnoti_snd_path = g_try_new0(struct tnoti_call_sound_path, 1);
- if (!tnoti_snd_path)
- return TCORE_RETURN_ENOMEM;
-
- tnoti_snd_path->path = sound_path->path;
-
- /* Configure modem I2S1 to 8khz, mono, PCM if routing to bluetooth */
- if (sound_path->path == CALL_SOUND_PATH_BLUETOOTH || sound_path->path == CALL_SOUND_PATH_STEREO_BLUETOOTH) {
- call_prepare_and_send_pending_request(o, "AT+XDRV=40,4,3,0,1,0,0,0,0,0,0,0,21", NULL, TCORE_AT_NO_RESULT, NULL);
- call_prepare_and_send_pending_request(o, "AT+XDRV=40,5,2,0,1,0,0,0,0,0,0,0,22", NULL, TCORE_AT_NO_RESULT, NULL);
- }
- else {
- call_prepare_and_send_pending_request(o, "AT+XDRV=40,4,3,0,1,0,8,0,1,0,2,0,21", NULL, TCORE_AT_NO_RESULT, NULL);
- call_prepare_and_send_pending_request(o, "AT+XDRV=40,5,2,0,1,0,8,0,1,0,2,0,22", NULL, TCORE_AT_NO_RESULT, NULL);
- }
-
- /* Configure modem I2S2 and do the modem routing */
- call_prepare_and_send_pending_request(o, "AT+XDRV=40,4,4,0,0,0,8,0,1,0,2,0,21", NULL, TCORE_AT_NO_RESULT, NULL);
- call_prepare_and_send_pending_request(o, "AT+XDRV=40,5,3,0,0,0,8,0,1,0,2,0,22", NULL, TCORE_AT_NO_RESULT, NULL);
- call_prepare_and_send_pending_request(o, "AT+XDRV=40,6,0,4", NULL, TCORE_AT_NO_RESULT, NULL);
- call_prepare_and_send_pending_request(o, "AT+XDRV=40,6,3,0", NULL, TCORE_AT_NO_RESULT, NULL);
- call_prepare_and_send_pending_request(o, "AT+XDRV=40,6,4,2", NULL, TCORE_AT_NO_RESULT, NULL);
- call_prepare_and_send_pending_request(o, "AT+XDRV=40,6,5,2", NULL, TCORE_AT_NO_RESULT, NULL);
-
- /* amc enable */
- call_prepare_and_send_pending_request(o, "AT+XDRV=40,2,4", NULL, TCORE_AT_NO_RESULT, NULL); //AMC_I2S2_RX
- call_prepare_and_send_pending_request(o, "AT+XDRV=40,2,3", NULL, TCORE_AT_NO_RESULT, NULL); //AMC_I2S1_RX
- /* amc route: AMC_RADIO_RX => AMC_I2S1_TX */
-
- pending = tcore_pending_new(o, 0);
- req = tcore_at_request_new("AT+XDRV=40,6,0,2", "+XDRV", TCORE_AT_SINGLELINE);
- dbg("XDRV req-cmd for source type : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
- tcore_pending_set_request_data(pending, 0, req);
- ur_dup = tcore_user_request_ref(ur);
- ret = _call_request_message(pending, o, ur_dup, on_confirmation_set_sound_path, tnoti_snd_path);
-
- } else {
-
- cmd_str = g_strdup_printf("AT+XDRV=40,4,3,0,0,0,0,0,1,0,1,0,%d",device_type); // source type.
- pending = tcore_pending_new(o, 0);
- req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);
- dbg("XDRV req-cmd for source type : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
- tcore_pending_set_request_data(pending, 0, req);
- ur_dup = tcore_user_request_ref(ur);
- ret = _call_request_message(pending, o, ur_dup, on_confirmation_call_set_source_sound_path, NULL);
- g_free(cmd_str);
-
- if (!ret) {
- dbg("At request(%s) sent failed", req->cmd);
- return TCORE_RETURN_FAILURE;
- }
-
- cmd_str1 = g_strdup_printf("AT+XDRV=40,5,2,0,0,0,0,0,1,0,1,0,%d",device_type); // destination type
- pending1 = tcore_pending_new(o, 0);
- req1 = tcore_at_request_new(cmd_str1, "+XDRV", TCORE_AT_SINGLELINE);
- dbg("XDRV req-cmd for destination type : %s, prefix(if any) :%s, cmd_len : %d", req1->cmd, req1->prefix, strlen(req1->cmd));
- tcore_pending_set_request_data(pending1, 0, req1);
- ret = _call_request_message(pending1, o, ur, on_confirmation_call_set_destination_sound_path, NULL);
- g_free(cmd_str1);
-
- if (!ret) {
- dbg("AT request %s has failed ", req1->cmd);
- return TCORE_RETURN_FAILURE;
- }
- }
-
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn s_call_set_sound_volume_level(CoreObject *o, UserRequest *ur)
-{
- UserRequest *src_ur = NULL;
- UserRequest *dest_ur = NULL;
- TcorePending *src_pending = NULL;
- TcorePending *dest_pending = NULL;
- TcoreATRequest *src_req = NULL;
- TcoreATRequest *dest_req = NULL;
- char *cmd_str = NULL, *volume_level = NULL;
- gboolean ret = FALSE;
- struct treq_call_sound_set_volume_level *data = NULL;
-
- dbg("Entry");
-
- if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
- dbg("cp not ready/n");
- return TCORE_RETURN_ENOSYS;
- }
-
- data = (struct treq_call_sound_set_volume_level *) tcore_user_request_ref_data(ur, 0);
-
- // Hard-coded values for MIC & Speakers
- // Source volume
- dbg("Set Source volume");
-
- cmd_str = g_strdup_printf("%s", "AT+XDRV=40,7,3,88"); // Source type
- dbg("Request command string: %s", cmd_str);
-
- // Create new Pending request
- src_pending = tcore_pending_new(o, 0);
-
- // Create new AT-Command request
- src_req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);
- dbg("Command: %s, prefix(if any): %s, Command length: %d", src_req->cmd, src_req->prefix, strlen(src_req->cmd));
-
- // Free Command string
- g_free(cmd_str);
-
- tcore_pending_set_request_data(src_pending, 0, src_req);
- src_ur = tcore_user_request_ref(ur);
-
- // Send request
- ret = _call_request_message(src_pending, o, src_ur, on_confirmation_call_set_source_sound_volume_level, NULL);
- if (!ret) {
- err("Failed to send AT-Command request");
- return TCORE_RETURN_FAILURE;
- }
-
- cmd_str = g_strdup_printf("%s", "AT+XDRV=40,7,0,88"); // Destination type
- dbg("Request command string: %s", cmd_str);
-
- // Create new Pending request
- src_pending = tcore_pending_new(o, 0);
-
- // Create new AT-Command request
- src_req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);
- dbg("Command: %s, prefix(if any): %s, Command length: %d", src_req->cmd, src_req->prefix, strlen(src_req->cmd));
-
- // Free Command string
- g_free(cmd_str);
-
- tcore_pending_set_request_data(src_pending, 0, src_req);
-
- src_ur = tcore_user_request_ref(ur);
-
- // Send request
- ret = _call_request_message(src_pending, o, src_ur, on_confirmation_call_set_source_sound_volume_level, NULL);
- if (!ret) {
- err("Failed to send AT-Command request");
- return TCORE_RETURN_FAILURE;
- }
-
- // Destination volume
- dbg("Set Source volume");
-
- cmd_str = g_strdup_printf("%s", "AT+XDRV=40,8,0,88"); // Source type
- dbg("Request command string: %s", cmd_str);
-
- // Create new Pending request
- dest_pending = tcore_pending_new(o, 0);
-
- // Create new AT-Command request
- dest_req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);
- dbg("Command: %s, prefix(if any): %s, Command length: %d", dest_req->cmd, dest_req->prefix, strlen(dest_req->cmd));
-
- // Free Command string
- g_free(cmd_str);
-
- tcore_pending_set_request_data(dest_pending, 0, dest_req);
- dest_ur = tcore_user_request_ref(ur);
-
- // Send request
- ret = _call_request_message(dest_pending, o, dest_ur, on_confirmation_call_set_source_sound_volume_level, NULL);
- if (!ret) {
- err("Failed to send AT-Command request");
- return TCORE_RETURN_FAILURE;
- }
-
- dbg("Input volume level - %d", data->volume);
- switch (data->volume) {
- case CALL_SOUND_MUTE:
- volume_level = "0";
- break;
-
- case CALL_SOUND_VOLUME_LEVEL_1:
- volume_level = "40";
- break;
-
- case CALL_SOUND_VOLUME_LEVEL_2:
- volume_level = "46";
- break;
-
- case CALL_SOUND_VOLUME_LEVEL_3:
- volume_level = "52";
- break;
-
- case CALL_SOUND_VOLUME_LEVEL_4:
- volume_level = "58";
- break;
-
- case CALL_SOUND_VOLUME_LEVEL_5:
- volume_level = "64";
- break;
-
- case CALL_SOUND_VOLUME_LEVEL_6:
- volume_level = "70";
- break;
-
- case CALL_SOUND_VOLUME_LEVEL_7:
- volume_level = "76";
- break;
-
- case CALL_SOUND_VOLUME_LEVEL_8:
- volume_level = "82";
- break;
-
- case CALL_SOUND_VOLUME_LEVEL_9:
- default:
- volume_level = "88";
- break;
- }
- cmd_str = g_strdup_printf("%s%s", "AT+XDRV=40,8,2,", volume_level); // Destination type
- dbg("Request command string: %s", cmd_str);
-
- // Create new Pending request
- dest_pending = tcore_pending_new(o, 0);
-
- // Create new AT-Command request
- dest_req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);
- dbg("Command: %s, prefix(if any): %s, Command length: %d", dest_req->cmd, dest_req->prefix, strlen(dest_req->cmd));
-
- // Free Command string
- g_free(cmd_str);
-
- tcore_pending_set_request_data(dest_pending, 0, dest_req);
-
- // Send request
- ret = _call_request_message(dest_pending, o, ur, on_confirmation_call_set_destination_sound_volume_level, NULL);
- if (!ret) {
- err("Failed to send AT-Command request");
- return TCORE_RETURN_FAILURE;
- }
-
- return TCORE_RETURN_SUCCESS;
-}
-
-
-static TReturn s_call_get_sound_volume_level(CoreObject *o, UserRequest *ur)
-{
- dbg("Entry");
-
- dbg("Exit");
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn s_call_mute(CoreObject *o, UserRequest *ur)
-{
- char *cmd_str = NULL;
- TcorePending *pending = NULL;
- TcoreATRequest *req = NULL;
- gboolean ret = FALSE;
-
- dbg("Entry");
-
- if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
- dbg("cp not ready/n");
- return TCORE_RETURN_ENOSYS;
- }
-
- cmd_str = g_strdup_printf("%s", "AT+XDRV=40,8,0,0,0");
-
- dbg("Request command string: %s", cmd_str);
-
- // Create new Pending request
- pending = tcore_pending_new(o, 0);
-
- // Create new AT-Command request
- req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);
- dbg("Command: %s, prefix(if any): %s, Command length: %d", req->cmd, req->prefix, strlen(req->cmd));
-
- // Free command string
- g_free(cmd_str);
-
- // Set request data (AT command) to Pending request
- tcore_pending_set_request_data(pending, 0, req);
-
- // Send request
- ret = _call_request_message(pending, o, ur, on_confirmation_call_mute, NULL);
- if (!ret) {
- err("Failed to send AT-Command request");
- return TCORE_RETURN_FAILURE;
- }
-
- dbg("Exit");
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn s_call_unmute(CoreObject *o, UserRequest *ur)
-{
- char *cmd_str = NULL;
- TcorePending *pending = NULL;
- TcoreATRequest *req = NULL;
- gboolean ret = FALSE;
-
- dbg("Entry");
-
- if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
- dbg("cp not ready/n");
- return TCORE_RETURN_ENOSYS;
- }
-
- cmd_str = g_strdup_printf("%s", "AT+XDRV=40,8,0,0,88");
- dbg("Request command string: %s", cmd_str);
-
- // Create new Pending request
- pending = tcore_pending_new(o, 0);
-
- // Create new AT-Command request
- req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);
- dbg("Command: %s, prefix(if any): %s, Command length: %d", req->cmd, req->prefix, strlen(req->cmd));
-
- // Free command string
- g_free(cmd_str);
-
- // Set request data (AT command) to Pending request
- tcore_pending_set_request_data(pending, 0, req);
-
- // Send request
- ret = _call_request_message(pending, o, ur, on_confirmation_call_unmute, NULL);
- if (!ret) {
- err("Failed to send AT-Command request");
- return TCORE_RETURN_FAILURE;
- }
-
- dbg("Exit");
- return TCORE_RETURN_SUCCESS;
-}
-
-
-static TReturn s_call_get_mute_status(CoreObject *o, UserRequest *ur)
-{
- dbg("Entry");
-
- dbg("Exit");
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn _set_dtmf_tone_duration(CoreObject *o, UserRequest *ur)
-{
- char *cmd_str = NULL;
- TcorePending *pending = NULL;
- TcoreATRequest *req = NULL;
- gboolean ret = FALSE;
-
- dbg("Entry");
-
- cmd_str = g_strdup_printf("%s", "AT+VTD=3"); // ~300 mili secs. +VTD= n, where n = (0 - 255) * 1/10 secs.
- dbg("Request command string: %s", cmd_str);
-
- // Create new Pending request
- pending = tcore_pending_new(o, 0);
-
- // Create new AT-Command request
- req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
- dbg("Command: %s, prefix(if any): %s, Command length: %d", req->cmd, req->prefix, strlen(req->cmd));
-
- // Free command string */
- g_free(cmd_str);
-
- // Set request data (AT command) to Pending request
- tcore_pending_set_request_data(pending, 0, req);
-
- // Send request
- ret = _call_request_message(pending, o, ur, _on_confirmation_dtmf_tone_duration, NULL);
- if (!ret) {
- err("Failed to send AT-Command request");
- if (ur) {
- tcore_user_request_free(ur);
- ur = NULL;
- }
- return TCORE_RETURN_FAILURE;
- }
-
- dbg("Exit");
- return TCORE_RETURN_SUCCESS;
-}
-
-// Call Operations
-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,
- .set_sound_recording = NULL,
- .set_sound_equalization = NULL,
- .set_sound_noise_reduction = NULL,
-};
-
-gboolean s_call_init(TcorePlugin *cp, CoreObject *co_call)
-{
- dbg("Entry");
-
- tcore_call_override_ops(co_call, &call_ops, NULL);
-
- /* Add Callbacks */
- tcore_object_override_callback(co_call, "+XCALLSTAT", on_notification_call_info, NULL);
- tcore_object_override_callback(co_call, "+CLIP", on_notification_call_clip_info, NULL);
-
- dbg("Exit");
-
- return TRUE;
-}
-
-void s_call_exit(TcorePlugin *cp, CoreObject *co_call)
-{
- dbg("Exit");
-}
+++ /dev/null
-/*
- * tel-plugin-imc
- *
- * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: Harish Bishnoi <hbishnoi@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 <user_request.h>
-#include <queue.h>
-#include <co_modem.h>
-#include <storage.h>
-#include <server.h>
-#include <at.h>
-#include <mux.h>
-
-#include "s_common.h"
-#include "s_modem.h"
-#include "nvm/nvm.h"
-
-
-#define ID_RESERVED_AT 0x0229
-
-#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
-
-#define CPAS_RES_READY 0
-#define CPAS_RES_UNAVAIL 1
-#define CPAS_RES_UNKNOWN 2
-#define CPAS_RES_RINGING 3
-#define CPAS_RES_CALL_PROGRESS 4
-#define CPAS_RES_ASLEEP 5
-#define AT_VER_LEN 20
-
-
-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,
-};
-
-typedef enum {
- 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 */
-} TelMiscSNIndexType_t;
-
-typedef struct {
- TelMiscSNIndexType_t sn_index; /**< serial number index */
- int sn_len; /**< Length */
- unsigned char szNumber[TAPI_MISC_ME_SN_LEN_MAX]; /**< Number */
-} TelMiscSNInformation;
-
-/**
- * Mobile Equipment Version Information
- */
-typedef struct {
- 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 */
-} TelMiscVersionInformation;
-
-
-static void prepare_and_send_pending_request(CoreObject *co, const char *at_cmd, const char *prefix, enum tcore_at_command_type at_cmd_type, TcorePendingResponseCallback callback);
-static void on_confirmation_modem_message_send(TcorePending *p, gboolean result, void *user_data);
-static void on_response_network_registration(TcorePending *p, int data_len, const void *data, void *user_data);
-static void on_response_enable_proactive_command(TcorePending *p, int data_len, const void *data, void *user_data);
-
-/* NVM */
-static gboolean on_event_nvm_update(CoreObject *o, const void *event_info, void *user_data);
-static void modem_unsuspend_nvm_updates(CoreObject *o);
-static void modem_send_nvm_update_ack(CoreObject *o);
-static void modem_send_nvm_update_request_ack(CoreObject *o);
-
-static void on_confirmation_modem_message_send(TcorePending *p, gboolean result, void *user_data)
-{
- dbg("on_confirmation_modem_message_send - msg out from queue.\n");
-
- if (result == FALSE) {
- /* Fail */
- dbg("SEND FAIL");
- } else {
- dbg("SEND OK");
- }
-}
-
-static void on_response_enable_proactive_command(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- const TcoreATResponse *resp = data;
-
- if (resp->success > 0) {
- dbg("RESPONSE OK proactive command enabled");
- } else {
- dbg("RESPONSE NOK proactive command disabled");
- }
-}
-
-static void on_response_network_registration(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- const TcoreATResponse *resp = data;
-
- if (resp->success > 0) {
- dbg("registration attempt OK");
- } else {
- dbg("registration attempt failed");
- }
-}
-
-void prepare_and_send_pending_request(CoreObject *co, const char *at_cmd, const char *prefix, enum tcore_at_command_type at_cmd_type, TcorePendingResponseCallback callback)
-{
- TcoreATRequest *req = NULL;
- TcoreHal *hal = NULL;
- TcorePending *pending = NULL;
- TReturn ret;
-
- hal = tcore_object_get_hal(co);
- dbg("hal: %p", hal);
-
- pending = tcore_pending_new(co, 0);
- if (!pending)
- dbg("Pending is NULL");
- req = tcore_at_request_new(at_cmd, prefix, at_cmd_type);
-
- dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
-
- tcore_pending_set_request_data(pending, 0, req);
- tcore_pending_set_response_callback(pending, callback, NULL);
- tcore_pending_set_send_callback(pending, on_confirmation_modem_message_send, NULL);
- ret = tcore_hal_send_request(hal, pending);
-}
-
-static void on_response_power_off(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- CoreObject *o = 0;
- TcoreHal *h = 0;
-
- o = tcore_pending_ref_core_object(p);
- h = tcore_object_get_hal(o);
-
- dbg("modem power off");
-
- tcore_hal_set_power_state(h, FALSE);
-}
-
-static void on_response_set_flight_mode(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- CoreObject *o = NULL;
- UserRequest *ur = NULL;
- const TcoreATResponse *ATresp = data;
- GSList *tokens = NULL;
- const char *line = NULL;
- struct tresp_modem_set_flightmode res = {0};
- int response = 0;
- struct tnoti_modem_flight_mode modem_flight_mode = {0};
- const struct treq_modem_set_flightmode *req_data = NULL;
-
- o = tcore_pending_ref_core_object(p);
-
- if (ATresp->success > 0) {
- dbg("RESPONSE OK - flight mode operation finished");
- res.result = TCORE_RETURN_SUCCESS;
- } else {
- dbg("RESPONSE NOK");
- line = (const char *) ATresp->final_response;
- tokens = tcore_at_tok_new(line);
-
- if (g_slist_length(tokens) < 1) {
- dbg("err cause not specified or string corrupted");
- res.result = TCORE_RETURN_3GPP_ERROR;
- } else {
- response = atoi(g_slist_nth_data(tokens, 0));
- /* TODO: CMEE error mapping is required. */
- res.result = TCORE_RETURN_3GPP_ERROR;
- }
- }
-
- ur = tcore_pending_ref_user_request(p);
- if (NULL == ur) {
- dbg("No user request. Internal request created during boot-up sequence");
-
- if (ATresp->success > 0) {
- modem_flight_mode.enable = tcore_modem_get_flight_mode_state(o);
- dbg("sucess case - Sending Flight Mode Notification (%d) to Telephony Server", modem_flight_mode.enable);
-
- tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_MODEM_FLIGHT_MODE,
- sizeof(struct tnoti_modem_flight_mode), &modem_flight_mode);
- }
- } else {
- dbg("Sending response for Flight mode operation");
-
- req_data = tcore_user_request_ref_data(ur, NULL);
-
- if (TCORE_RETURN_SUCCESS == res.result) {
- if (TRUE == req_data->enable)
- res.result = 1;
- else
- res.result = 2;
- } else {
- res.result = 3;
- }
-
- tcore_user_request_send_response(ur, TRESP_MODEM_SET_FLIGHTMODE, sizeof(struct tresp_modem_set_flightmode), &res);
-
- if (req_data->enable == 0) {
- dbg("Flight mode is disabled, trigger COPS to register on network");
- /* Trigger Network registration (for the moment automatic) */
- prepare_and_send_pending_request(o, "AT+COPS=0", NULL, TCORE_AT_NO_RESULT, NULL);
- }
- }
-
- tcore_at_tok_free(tokens);
-}
-
-static void on_response_imei(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- const TcoreATResponse *resp = data;
- TcorePlugin *plugin = NULL;
- struct tresp_modem_get_imei res;
- TelMiscSNInformation *imei_property = NULL;
- UserRequest *ur = NULL;
- GSList *tokens = NULL;
- const char *line;
- int response = 0;
-
- memset(&res, 0, sizeof(struct tresp_modem_get_imei));
-
- 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) != 1) {
- msg("invalid message");
- goto OUT;
- }
- }
- res.result = TCORE_RETURN_SUCCESS;
- strncpy(res.imei, g_slist_nth_data(tokens, 0), 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");
- if (resp->lines) {
- line = (const char *) resp->lines->data;
- tokens = tcore_at_tok_new(line);
- }
-
-
- if (g_slist_length(tokens) < 1) {
- dbg("err cause not specified or string corrupted");
- res.result = TCORE_RETURN_3GPP_ERROR;
- } else {
- response = atoi(g_slist_nth_data(tokens, 0));
- /* TODO: CMEE error mapping is required. */
- res.result = TCORE_RETURN_3GPP_ERROR;
- }
- }
-
- ur = tcore_pending_ref_user_request(p);
- tcore_user_request_send_response(ur, TRESP_MODEM_GET_IMEI,
- sizeof(struct tresp_modem_get_imei), &res);
-
-OUT:
- if (tokens != NULL)
- tcore_at_tok_free(tokens);
-
- return;
-}
-
-static void on_response_version(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- const TcoreATResponse *resp = data;
- TcorePlugin *plugin = NULL;
- struct tresp_modem_get_version res = {0};
- TelMiscVersionInformation *vi_property = NULL;
- TelMiscVersionInformation *vi = NULL;
- UserRequest *ur = NULL;
- GSList *tokens = NULL;
- const char *line = NULL;
- char *swver = NULL;
- char *hwver = NULL;
- char *caldate = NULL;
- char *pcode = NULL;
- char *id = NULL;
-
- int response = 0;
-
- 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) == 1) {
- swver = g_slist_nth_data(tokens, 0);
- dbg("version: sw=[%s]", swver);
- } else if (g_slist_length(tokens) == 5) {
- swver = g_slist_nth_data(tokens, 0);
- hwver = g_slist_nth_data(tokens, 1);
- caldate = g_slist_nth_data(tokens, 2);
- pcode = g_slist_nth_data(tokens, 3);
- id = g_slist_nth_data(tokens, 4);
-
- dbg("version: sw=[%s], hw=[%s], rf_cal=[%s], product_code=[%s], model_id=[%s]",
- swver, hwver, caldate, pcode, id);
- } else {
- msg("invalid message");
- goto OUT;
- }
- }
-
- vi = g_try_new0(TelMiscVersionInformation, 1);
- if (NULL != swver)
- memcpy(vi->szSwVersion, swver, strlen(swver));
- if (NULL != hwver)
- memcpy(vi->szHwVersion, hwver, strlen(hwver));
- if (NULL != caldate)
- memcpy(vi->szRfCalDate, caldate, strlen(caldate));
- if (NULL != pcode)
- memcpy(vi->szProductCode, pcode, strlen(pcode));
- if (NULL != id)
- memcpy(vi->szModelId, id, strlen(id));
-
- memset(&res, 0, sizeof(struct tresp_modem_get_version));
-
- if (NULL != swver) {
- snprintf(res.software,
- (AT_VER_LEN > strlen(swver) ? strlen(swver) : AT_VER_LEN),
- "%s", swver);
- }
-
- if (NULL != hwver) {
- 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(TelMiscVersionInformation));
- g_free(vi);
- } else {
- dbg("RESPONSE NOK");
- if (resp->lines) {
- line = (const char *) resp->lines->data;
- tokens = tcore_at_tok_new(line);
- }
-
- memset(&res, 0, sizeof(struct tresp_modem_get_version));
-
-
- if (g_slist_length(tokens) < 1) {
- dbg("err cause not specified or string corrupted");
- res.result = TCORE_RETURN_3GPP_ERROR;
- } else {
- response = atoi(g_slist_nth_data(tokens, 0));
- /* TODO: CMEE error mapping is required. */
- res.result = TCORE_RETURN_3GPP_ERROR;
- }
- }
-
- ur = tcore_pending_ref_user_request(p);
- tcore_user_request_send_response(ur, TRESP_MODEM_GET_VERSION,
- sizeof(struct tresp_modem_get_version), &res);
-
-OUT:
- if (tokens != NULL)
- tcore_at_tok_free(tokens);
-
- return;
-}
-
-static enum tcore_hook_return on_hook_sim_status(Server *s,
- CoreObject *source, enum tcore_notification_command command,
- unsigned int data_len, void *data, void *user_data)
-{
- TcorePlugin *plugin;
- const struct tnoti_sim_status *noti_sim_status;
- CoreObject *co_sat;
- CoreObject *co_network;
-
- plugin = tcore_object_ref_plugin(source);
- co_sat = tcore_plugin_ref_core_object(plugin, CORE_OBJECT_TYPE_SAT);
- if (co_sat == NULL)
- return TCORE_HOOK_RETURN_CONTINUE;
-
- co_network = tcore_plugin_ref_core_object(plugin, CORE_OBJECT_TYPE_NETWORK);
- if (co_network == NULL)
- return TCORE_HOOK_RETURN_CONTINUE;
-
- dbg("Get SIM status");
- noti_sim_status = data;
- if (noti_sim_status == NULL)
- return TCORE_HOOK_RETURN_CONTINUE;
-
- /* If SIM is initialized, Enable STK and and attach to Network */
- dbg("SIM Status: [%d]", noti_sim_status->sim_status);
- if (noti_sim_status->sim_status == SIM_STATUS_INIT_COMPLETED) {
- dbg("SIM ready for attach!!! Enable STK and attach to Network");
-
- /* Sending AT+CFUN=6 */
- prepare_and_send_pending_request(co_sat, "AT+CFUN=6", NULL,
- TCORE_AT_NO_RESULT, on_response_enable_proactive_command);
-
- /* Sending AT+COPS */
- prepare_and_send_pending_request(co_network, "AT+COPS=0", NULL,
- TCORE_AT_NO_RESULT, on_response_network_registration);
- }
-
- return TCORE_HOOK_RETURN_CONTINUE;
-}
-
-gboolean modem_power_on(TcorePlugin *plugin)
-{
- CoreObject *co_modem = NULL;
- struct treq_modem_set_flightmode flight_mode_set = {0};
- struct tnoti_modem_power modem_power = {0};
- Storage *strg = NULL;
-
- co_modem = tcore_plugin_ref_core_object(plugin, CORE_OBJECT_TYPE_MODEM);
- if (co_modem == NULL) {
- err("Modem Core object is NULL");
- return FALSE;
- }
-
- /* Set Modem Power State to 'ON' */
- tcore_modem_set_powered(co_modem, TRUE);
-
- /* Get Flight mode from VCONFKEY */
- strg = tcore_server_find_storage(tcore_plugin_ref_server(plugin), "vconf");
- flight_mode_set.enable = tcore_storage_get_bool(strg, STORAGE_KEY_FLIGHT_MODE_BOOL);
-
- /* Set Flight mode as per AP settings */
- if (flight_mode_set.enable) { /* Radio OFF */
- prepare_and_send_pending_request(co_modem, "AT+CFUN=4", NULL,
- TCORE_AT_NO_RESULT, on_response_set_flight_mode);
-
- /* Set Flight mode TRUE */
- tcore_modem_set_flight_mode_state(co_modem, TRUE);
- } else { /* Radio ON */
- prepare_and_send_pending_request(co_modem, "AT+CFUN=1", NULL,
- TCORE_AT_NO_RESULT, on_response_set_flight_mode);
-
- /* Set Flight mode FALSE */
- tcore_modem_set_flight_mode_state(co_modem, FALSE);
- }
-
- /* Get IMEI */
- prepare_and_send_pending_request(co_modem, "AT+CGSN", NULL,
- TCORE_AT_NUMERIC, on_response_imei);
-
- /* Get Version Number */
- prepare_and_send_pending_request(co_modem, "AT+CGMR", NULL,
- TCORE_AT_SINGLELINE, on_response_version);
-
- /* Send Notification to TAPI - MODEM_POWER */
- modem_power.state = MODEM_STATE_ONLINE;
-
- dbg("Sending notification - Modem Power state: [ONLINE]");
- tcore_server_send_notification(tcore_plugin_ref_server(plugin),
- co_modem, TNOTI_MODEM_POWER, sizeof(modem_power), &modem_power);
-
- return TRUE;
-}
-
-static TReturn power_off(CoreObject *o, UserRequest *ur)
-{
- TcoreHal *hal = NULL;
- TcoreATRequest *req = NULL;
- TcorePending *pending = NULL;
-
- hal = tcore_object_get_hal(o);
- pending = tcore_pending_new(o, 0);
-
- req = tcore_at_request_new("AT+CFUN=0", NULL, TCORE_AT_NO_RESULT);
-
- dbg("Command: [%s], Prefix(if any): [%s], Command Length: [%d]",
- req->cmd, req->prefix, strlen(req->cmd));
-
- tcore_pending_set_request_data(pending, 0, req);
- tcore_pending_set_response_callback(pending, on_response_power_off, hal);
- tcore_pending_link_user_request(pending, ur);
- tcore_pending_set_send_callback(pending, on_confirmation_modem_message_send, NULL);
-
- tcore_hal_send_request(hal, pending);
-
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn get_imei(CoreObject *o, UserRequest *ur)
-{
- TcoreHal *hal;
- TcoreATRequest *req;
- TcorePending *pending = NULL;
-
- hal = tcore_object_get_hal(o);
- if (FALSE == tcore_hal_get_power_state(hal)) {
- dbg("cp not ready/n");
- return TCORE_RETURN_ENOSYS;
- }
- pending = tcore_pending_new(o, 0);
-
- req = tcore_at_request_new("AT+CGSN", NULL, TCORE_AT_NUMERIC);
-
- dbg("Command: [%s], Prefix(if any): [%s], Command Length: [%d]",
- req->cmd, req->prefix, strlen(req->cmd));
-
- tcore_pending_set_request_data(pending, 0, req);
- tcore_pending_set_response_callback(pending, on_response_imei, hal);
- tcore_pending_link_user_request(pending, ur);
- tcore_pending_set_send_callback(pending, on_confirmation_modem_message_send, NULL);
-
- return tcore_hal_send_request(hal, pending);
-}
-
-
-static TReturn get_version(CoreObject *o, UserRequest *ur)
-{
- TcoreHal *hal;
- TcoreATRequest *req;
- TcorePending *pending = NULL;
-
- hal = tcore_object_get_hal(o);
- if (FALSE == tcore_hal_get_power_state(hal)) {
- dbg("cp not ready/n");
- return TCORE_RETURN_ENOSYS;
- }
- pending = tcore_pending_new(o, 0);
-
- req = tcore_at_request_new("AT+CGMR", NULL, TCORE_AT_SINGLELINE);
-
- dbg("Command: [%s], Prefix(if any): [%s], Command Length: [%d]",
- req->cmd, req->prefix, strlen(req->cmd));
-
- tcore_pending_set_request_data(pending, 0, req);
- tcore_pending_set_response_callback(pending, on_response_version, hal);
- tcore_pending_link_user_request(pending, ur);
- tcore_pending_set_send_callback(pending, on_confirmation_modem_message_send, NULL);
-
- return tcore_hal_send_request(hal, pending);
-}
-
-static TReturn set_flight_mode(CoreObject *o, UserRequest *ur)
-{
- TcoreHal *hal = NULL;
- TcoreATRequest *req = NULL;
- TcorePending *pending = NULL;
- const struct treq_modem_set_flightmode *req_data = NULL;
- char *cmd_str = NULL;
-
- hal = tcore_object_get_hal(o);
- if (FALSE == tcore_hal_get_power_state(hal)) {
- dbg("cp not ready/n");
- return TCORE_RETURN_ENOSYS;
- }
- pending = tcore_pending_new(o, 0);
-
- req_data = tcore_user_request_ref_data(ur, NULL);
-
- if (req_data->enable) {
- dbg("Flight mode on/n");
- cmd_str = g_strdup("AT+CFUN=4");
- } else {
- dbg("Flight mode off/n");
- cmd_str = g_strdup("AT+CFUN=1");
- }
-
- req = tcore_at_request_new((const char *)cmd_str, NULL, TCORE_AT_NO_RESULT);
- g_free(cmd_str);
-
- dbg("Command: [%s], Prefix(if any): [%s], Command Length: [%d]",
- req->cmd, req->prefix, strlen(req->cmd));
-
- tcore_pending_set_request_data(pending, 0, req);
- tcore_pending_set_response_callback(pending, on_response_set_flight_mode, hal);
- tcore_pending_link_user_request(pending, ur);
- tcore_pending_set_send_callback(pending, on_confirmation_modem_message_send, NULL);
-
- return tcore_hal_send_request(hal, pending);
-}
-
-
-static struct tcore_modem_operations modem_ops = {
- .power_on = NULL,
- .power_off = power_off,
- .power_reset = NULL,
- .set_flight_mode = set_flight_mode,
- .get_imei = get_imei,
- .get_version = get_version,
- .get_sn = NULL,
- .dun_pin_ctrl = NULL,
-};
-
-gboolean s_modem_init(TcorePlugin *cp, CoreObject *co_modem)
-{
- TelMiscVersionInformation *vi_property;
- TelMiscSNInformation *imei_property;
- TelMiscSNInformation *sn_property;
-
- dbg("Enter");
-
- tcore_modem_override_ops(co_modem, &modem_ops);
-
- vi_property = g_try_new0(TelMiscVersionInformation, 1);
- tcore_plugin_link_property(cp, "VERSION", vi_property);
-
- imei_property = g_try_new0(TelMiscSNInformation, 1);
- tcore_plugin_link_property(cp, "IMEI", imei_property);
-
- sn_property = g_try_new0(TelMiscSNInformation, 1);
- tcore_plugin_link_property(cp, "SN", sn_property);
-
- tcore_server_add_notification_hook(tcore_plugin_ref_server(cp),
- TNOTI_SIM_STATUS, on_hook_sim_status, NULL);
- dbg("Registering for +XDRVI event");
- tcore_object_add_callback(co_modem, "+XDRVI", on_event_nvm_update, NULL);
-
- dbg("Exit");
- return TRUE;
-}
-
-void s_modem_exit(TcorePlugin *cp, CoreObject *co_modem)
-{
- TelMiscVersionInformation *vi_property;
- TelMiscSNInformation *imei_property;
- TelMiscSNInformation *sn_property;
- TcorePlugin *plugin = tcore_object_ref_plugin(co_modem);
-
- vi_property = tcore_plugin_ref_property(plugin, "VERSION");
- g_free(vi_property);
-
- imei_property = tcore_plugin_ref_property(plugin, "IMEI");
- g_free(imei_property);
-
- sn_property = tcore_plugin_ref_property(plugin, "SN");
- g_free(sn_property);
-
- dbg("Exit");
-}
-
-/*
- * NV Manager - Support for Remote File System
- */
-/* NVM Hook */
-static gboolean modem_rfs_hook(const char *data)
-{
- if (data != NULL)
- if (data[NVM_FUNCTION_ID_OFFSET] == XDRV_INDICATION)
- return TRUE;
-
- return FALSE;
-}
-
-/* NVM event Notification */
-static gboolean on_event_nvm_update(CoreObject *o, const void *event_info, void *user_data)
-{
- GSList *tokens = NULL;
- GSList *lines;
- const char *line;
- int function_id;
-
- gboolean ret = TRUE;
- dbg("Entered");
-
- lines = (GSList *)event_info;
- line = lines->data;
- dbg("Line: [%s]", line);
-
- function_id = nvm_sum_4_bytes(&line[NVM_FUNCTION_ID_OFFSET]);
- dbg("Function ID: [%d]", function_id);
- if (IUFP_UPDATE == function_id) {
- dbg("Calling process nvm_update");
-
- /*
- * Process NV Update indication
- *
- * +XDRVI: IUFP_GROUP, IUFP_UPDATE, <xdrv_result>, <data>
- */
- if (NVM_NO_ERR == nvm_process_nv_update(line)) {
- dbg("NV data processed successfully");
-
- /* Acknowledge NV Update */
- modem_send_nvm_update_ack(o);
-
- return ret;
- } else {
- err("NV data processing failed");
- ret = FALSE;
- }
- } else {
- tokens = tcore_at_tok_new(line);
- if (g_slist_length(tokens) < 3) {
- err("XDRVI event with less number of tokens, Ignore!!!");
- ret = FALSE;
- }
- else if (IUFP_GROUP_ID != atoi(g_slist_nth_data(tokens, 0))) {
- err("Group ID mismatch, Ignore!!!");
- ret = FALSE;
- }
- else {
- switch (atoi(g_slist_nth_data(tokens, 1))) {
- case IUFP_UPDATE_REQ:
- dbg("NV Update Request");
-
- /* Acknowledge the Update Request */
- modem_send_nvm_update_request_ack(o);
- break;
-
- case IUFP_NO_PENDING_UPDATE:
- dbg("NO pending NV Update(s)!!!");
- /* Can send FLUSH request to get fresh updates */
- break;
-
- default:
- err("Unspported Function ID [%d], Ignore", atoi(g_slist_nth_data(tokens, 1)));
- ret = FALSE;
- }
- }
-
- tcore_at_tok_free(tokens);
- }
-
- dbg("Exit");
- return ret;
-}
-
-/* NVM Responses */
-static gboolean __modem_check_nvm_response(const void *data, int command)
-{
- const TcoreATResponse *resp = data;
- const char *line;
- char *resp_str;
- GSList *tokens = NULL;
- gboolean ret = FALSE;
- dbg("Entered");
-
- /* +XDRV: <group_id>,<function_id>,<xdrv_result>[,<response_n>] */
- if (NULL == resp) {
- err("Input data is NULL");
- return FALSE;
- }
-
- if (resp->success > 0) {
- dbg("RESPONSE OK");
- line = (const char *) (((GSList *) resp->lines)->data);
- tokens = tcore_at_tok_new(line);
-
- /* Group ID */
- resp_str = g_slist_nth_data(tokens, 0);
- if (NULL == resp_str) {
- err("Group ID is missing ");
- goto OUT;
- }
- else if (IUFP_GROUP_ID != atoi(resp_str)) {
- err("Group ID mismatch");
- goto OUT;
- }
-
- /* Function ID */
- resp_str = g_slist_nth_data(tokens, 1);
- if (NULL == resp_str) {
- err("Function ID is missing ");
- goto OUT;
- }
- else if (command != atoi(resp_str)) {
- err("Function ID mismatch");
- goto OUT;
- }
-
- /* XDRV Result */
- resp_str = g_slist_nth_data(tokens, 2);
- if (NULL == resp_str) {
- err("XDRV result is missing ");
- goto OUT;
- }
- else if (XDRV_RESULT_OK != atoi(resp_str)) {
- err("XDRV result[%d] ", atoi(resp_str));
- goto OUT;
- }
-
- /* Result code */
- resp_str = g_slist_nth_data(tokens, 3);
- if (NULL == resp_str) {
- err("UTA result is missing ");
- goto OUT;
- }
- else if (UTA_SUCCESS != atoi(resp_str)) {
- err("uta result[%d] ", atoi(resp_str));
- goto OUT;
- }
-
- ret = TRUE;
- } else {
- dbg("Response NOK");
- }
-
-OUT:
- tcore_at_tok_free(tokens);
-
- dbg("Exit");
- return ret;
-}
-
-static void _on_response_modem_unsuspend_nvm_updates(TcorePending *p,
- int data_len, const void *data, void *user_data)
-{
- /* Check NVM response */
- if (TRUE == __modem_check_nvm_response(data, IUFP_SUSPEND)) {
- dbg("Priority level is set to get all updates since Boot-up");
-
- /* Create NV data file */
- if (nvm_create_nvm_data() == FALSE) {
- err("Failed to Create NV data file");
- }
-
- return;
- }
-
- err("Response NOT OK");
-}
-
-static void _on_response_modem_send_nvm_update_ack(TcorePending *p,
- int data_len, const void *data, void *user_data)
-{
- /* Check NVM response */
- if (TRUE == __modem_check_nvm_response(data, IUFP_UPDATE_ACK)) {
- dbg("[UPDATE ACK] OK");
- return;
- }
-
- err("[UPDATE ACK] NOT OK");
-}
-
-static void _on_response_modem_send_nvm_update_request_ack(TcorePending *p,
- int data_len, const void *data, void *user_data)
-{
- /* Check NVM response */
- if (TRUE == __modem_check_nvm_response(data, IUFP_UPDATE_REQ_ACK)) {
- dbg("[REQUEST ACK] OK");
- return;
- }
-
- err("[REQUEST ACK] NOT OK");
-}
-
-static void _on_response_modem_register_nvm(TcorePending *p,
- int data_len, const void *data, void *user_data)
-{
- /* Check NVM response */
- if (TRUE == __modem_check_nvm_response(data, IUFP_REGISTER)) {
- dbg("Registering successful");
-
- /* Send SUSPEND_UPDATE for all UPDATES */
- modem_unsuspend_nvm_updates(tcore_pending_ref_core_object(p));
-
- dbg("Exit");
- return;
- }
-
- err("Response NOT OK");
-}
-
-/* NVM Requests */
-static void modem_unsuspend_nvm_updates(CoreObject *o)
-{
- TcorePending *pending = NULL;
- char *cmd_str;
- dbg("Entered");
-
- /* Prepare AT-Command */
- cmd_str = g_strdup_printf("AT+XDRV=%d, %d, %d, %d",
- IUFP_GROUP_ID, IUFP_SUSPEND,
- 0, UTA_FLASH_PLUGIN_PRIO_UNSUSPEND_ALL);
-
- /* Prepare pending request */
- pending = tcore_at_pending_new(o,
- cmd_str,
- "+XDRV:",
- TCORE_AT_SINGLELINE,
- _on_response_modem_unsuspend_nvm_updates,
- NULL);
- if (pending == NULL) {
- err("Failed to form pending request");
- }
- else if (tcore_hal_send_request(tcore_object_get_hal(o), pending)
- != TCORE_RETURN_SUCCESS) {
- err("IUFP_SUSPEND - Unable to send AT-Command");
- }
- else {
- dbg("IUFP_SUSPEND - Successfully sent AT-Command");
- }
-
- g_free(cmd_str);
-}
-
-static void modem_send_nvm_update_ack(CoreObject *o)
-{
- TcorePending *pending = NULL;
- char *cmd_str;
- dbg("Entered");
-
- /* Prepare AT-Command */
- cmd_str = g_strdup_printf("AT+XDRV=%s, %s", IUFP_GROUP, IUFP_UPDATE_ACK_STR);
-
- /* Prepare pending request */
- pending = tcore_at_pending_new(o,
- cmd_str,
- "+XDRV:",
- TCORE_AT_SINGLELINE,
- _on_response_modem_send_nvm_update_ack,
- NULL);
- if (pending == NULL) {
- err("Failed to form pending request");
- }
- else if (tcore_hal_send_request(tcore_object_get_hal(o), pending)
- != TCORE_RETURN_SUCCESS) {
- err("IUFP_UPDATE_ACK - Unable to send AT-Command");
- }
- else {
- dbg("IUFP_UPDATE_ACK - Successfully sent AT-Command");
- }
-
- g_free(cmd_str);
-}
-
-static void modem_send_nvm_update_request_ack(CoreObject *o)
-{
- TcorePending *pending = NULL;
- char *cmd_str;
- dbg("Entered");
-
- /* Prepare AT-Command */
- cmd_str = g_strdup_printf("AT+XDRV=%s, %s", IUFP_GROUP, IUFP_UPDATE_REQ_ACK_STR);
-
- /* Prepare pending request */
- pending = tcore_at_pending_new(o,
- cmd_str,
- "+XDRV:",
- TCORE_AT_SINGLELINE,
- _on_response_modem_send_nvm_update_request_ack,
- NULL);
-
-
- if (pending == NULL) {
- err("Failed to form pending request");
- }
- else if (tcore_hal_send_request(tcore_object_get_hal(o), pending)
- != TCORE_RETURN_SUCCESS) {
- err("IUFP_UPDATE_REQ_ACK - Unable to send AT-Ccommand");
- }
- else {
- dbg("IUFP_UPDATE_REQ_ACK - Successfully sent AT-Command");
- }
-
- g_free(cmd_str);
-}
-
-void modem_register_nvm(CoreObject *co_modem)
-{
- TcorePending *pending = NULL;
- char *cmd_str;
- dbg("Entered");
-
- /* Prepare AT-Command */
- cmd_str = g_strdup_printf("AT+XDRV=%s, %s, %s",
- IUFP_GROUP, IUFP_REGISTER_STR, XDRV_ENABLE);
-
- /* Prepare pending request */
- pending = tcore_at_pending_new(co_modem,
- cmd_str,
- "+XDRV:",
- TCORE_AT_SINGLELINE,
- _on_response_modem_register_nvm,
- NULL);
- if (pending == NULL) {
- err("Failed to form pending request");
- }
- else if (tcore_hal_send_request(tcore_object_get_hal(co_modem), pending)
- != TCORE_RETURN_SUCCESS) {
- err("IUFP_REGISTER (Enable) -Unable to send AT-Command");
- }
- else {
- dbg("IUFP_REGISTER (Enable) -Successfully sent AT-Command");
-
- /* Add RFS hook */
- tcore_at_add_hook(tcore_object_get_hal(co_modem), modem_rfs_hook);
- }
-
- g_free(cmd_str);
-}
+++ /dev/null
-/*
- * tel-plugin-imc
- *
- * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: Harish Bishnoi <hbishnoi@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 <user_request.h>
-#include <queue.h>
-#include <co_network.h>
-#include <co_ps.h>
-#include <server.h>
-#include <storage.h>
-#include <util.h>
-#include <at.h>
-#include <tzplatform_config.h>
-
-#include "s_common.h"
-#include "s_network.h"
-
-#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 */
-
-#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_MODE_MANUAL_AUTOMATIC 4 /*automatic - manual*/
-
-#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 */
-
-#define AT_GSM_XBANDSEL_AUTOMATIC 0
-#define AT_GSM_XBANDSEL_1800 1800
-#define AT_GSM_XBANDSEL_1900 1900
-#define AT_GSM_XBANDSEL_900 900
-#define AT_GSM_XBANDSEL_850 850
-#define AT_GSM_XBANDSEL_450 450
-#define AT_GSM_XBANDSEL_480 480
-#define AT_GSM_XBANDSEL_750 750
-#define AT_GSM_XBANDSEL_380 380
-#define AT_GSM_XBANDSEL_410 410
-
-#define AT_XRAT_GSM 0
-#define AT_XRAT_DUAL 1
-#define AT_XRAT_UMTS 2
-
-#define MAX_NETWORKS_PREF_PLMN_SUPPORT 150
-#define MAX_NETWORKS_MANUAL_SEARCH_SUPPORT 20
-
-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,
-};
-
-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 gboolean get_serving_network(CoreObject *o, UserRequest *ur);
-
-
-static void on_confirmation_network_message_send(TcorePending *p, gboolean result, void *user_data)
-{
- dbg("on_confirmation_modem_message_send - msg out from queue.\n");
-
- if (result == FALSE) {
- /* Fail */
- dbg("SEND FAIL");
- } else {
- dbg("SEND OK");
- }
-}
-
-static void nwk_prepare_and_send_pending_request(CoreObject *co, const char *at_cmd, const char *prefix, enum tcore_at_command_type at_cmd_type, UserRequest *ur, TcorePendingResponseCallback callback)
-{
- TcoreATRequest *req = NULL;
- TcoreHal *hal;
- TcorePending *pending = NULL;
- TReturn ret;
-
- hal = tcore_object_get_hal(co);
-
- pending = tcore_pending_new(co, 0);
- req = tcore_at_request_new(at_cmd, prefix, at_cmd_type);
-
- dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
-
- tcore_pending_set_request_data(pending, 0, req);
- tcore_pending_set_response_callback(pending, callback, req->cmd);
- tcore_pending_link_user_request(pending, ur);
- tcore_pending_set_send_callback(pending, on_confirmation_network_message_send, NULL);
-
- ret = tcore_hal_send_request(hal, pending);
- return;
-}
-
-
-static void _insert_mcc_mnc_oper_list(TcorePlugin *p, 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(p);
- 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", (char *) g_hash_table_lookup(row, "1"));
- snprintf(noi->mnc, 4, "%s", (char *) g_hash_table_lookup(row, "2"));
- snprintf(noi->name, 41, "%s", (char *) g_hash_table_lookup(row, "3"));
- snprintf(noi->country, 4, "%s", (char *) 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 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_UNKNOWN:
- 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_EGPRS:
- return NETWORK_SERVICE_TYPE_2_5G_EDGE;
- break;
-
- case NETWORK_ACT_UMTS:
- 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 *p, int status)
-{
- CoreObject *co_ps;
-
- co_ps = tcore_plugin_ref_core_object(p, CORE_OBJECT_TYPE_PS);
- if (co_ps == NULL) {
- err("No PS Core Object on plugin");
- return;
- }
-
- if (status == NETWORK_SERVICE_DOMAIN_STATUS_FULL)
- tcore_ps_set_online(co_ps, TRUE);
- else
- tcore_ps_set_online(co_ps, FALSE);
-}
-
-static void on_timeout_search_network(TcorePending *p, void *user_data)
-{
- UserRequest *ur;
- struct tresp_network_search resp;
-
- dbg("TIMEOUT !!!!! pending=%p", p);
-
- memset(&resp, 0, sizeof(struct tresp_network_search));
-
- resp.result = TCORE_RETURN_FAILURE;
- resp.list_count = 0;
-
- ur = tcore_pending_ref_user_request(p);
- if (ur) {
- tcore_user_request_send_response(ur, TRESP_NETWORK_SEARCH, sizeof(struct tresp_network_search), &resp);
- }
-}
-
-static void on_response_set_plmn_selection_mode(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- UserRequest *ur;
- const TcoreATResponse *atResp = data;
- // GSList *tokens = NULL;
- // char * line = NULL;
- struct tresp_network_set_plmn_selection_mode resp = {0};
-
- if (atResp->success > 0) {
- dbg("RESPONSE OK");
- resp.result = TCORE_RETURN_SUCCESS;
- } else {
- dbg("RESPONSE NOK");
- resp.result = TCORE_RETURN_FAILURE;
- }
-
- ur = tcore_pending_ref_user_request(p);
- 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 *p, int data_len, const void *data, void *user_data)
-{
- UserRequest *ur;
- struct tresp_network_get_plmn_selection_mode resp = {0};
- const TcoreATResponse *atResp = data;
- GSList *tokens = NULL;
- char *line = NULL;
- int mode = 0;
-
- resp.result = TCORE_RETURN_FAILURE;
-
- if (atResp->success > 0) {
- dbg("RESPONSE OK");
- /* Format of output
- +COPS: <mode>[,<format>,<oper>[,< AcT>]]
- */
-
- if (atResp->lines) {
- line = (char *) atResp->lines->data;
- tokens = tcore_at_tok_new(line);
- if (g_slist_length(tokens) < 1) {
- msg("invalid message");
- goto OUT;
- }
- mode = atoi(tcore_at_tok_nth(tokens, 0));
- dbg("mode = %d", mode);
-
- switch (mode) {
- case AT_COPS_MODE_AUTOMATIC:
- resp.mode = NETWORK_SELECT_MODE_AUTOMATIC;
- break;
-
- case AT_COPS_MODE_MANUAL:
- case AT_COPS_MODE_MANUAL_AUTOMATIC:
- resp.mode = NETWORK_SELECT_MODE_MANUAL;
- break;
-
- case AT_COPS_MODE_DEREGISTER:
- case AT_COPS_MODE_SET_ONLY:
- resp.result = TCORE_RETURN_FAILURE;
- goto OUT;
- }
- resp.result = TCORE_RETURN_SUCCESS;
- }
- } else {
- dbg("RESPONSE NOK");
- resp.result = TCORE_RETURN_FAILURE;
- }
-
-OUT:
- ur = tcore_pending_ref_user_request(p);
- if (ur) {
- tcore_user_request_send_response(ur, TRESP_NETWORK_GET_PLMN_SELECTION_MODE, sizeof(struct tresp_network_get_plmn_selection_mode), &resp);
- }
-
- if (tokens != NULL)
- tcore_at_tok_free(tokens);
-
- return;
-}
-
-static void on_response_search_network(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- UserRequest *ur;
- struct tresp_network_search resp;
- int i = 0;
- char *line = NULL;
- const TcoreATResponse *atResp = data;
- GSList *tokens = NULL;
- GSList *network_token = NULL;
- int AcT = 0;
- char *temp_plmn_info = NULL;
- char *alpha_name = NULL;
- char *pResp = NULL;
- int num_network_avail = 0;
-
- memset(&resp, 0, sizeof(struct tresp_network_search));
- resp.result = TCORE_RETURN_FAILURE;
- resp.list_count = 0;
-
- if (atResp->success > 0) {
- dbg("RESPONSE OK");
- if (atResp->lines) {
- line = (char *) atResp->lines->data;
- tokens = tcore_at_tok_new(line);
- num_network_avail = g_slist_length(tokens);
- dbg(" length of tokens is %d\n", num_network_avail);
- if (num_network_avail < 1) {
- msg("invalid message");
- goto OUT;
- }
- }
-
- resp.result = TCORE_RETURN_SUCCESS;
- /*
- * +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)]
- */
-
- for (i = 0; ((i < num_network_avail) && (i < MAX_NETWORKS_MANUAL_SEARCH_SUPPORT)); i++) {
- network_token = tcore_at_tok_new(g_slist_nth_data(tokens, i));
-
- pResp = (tcore_at_tok_nth(network_token, 0));
- if (pResp != NULL) {
- dbg("status : %s", pResp);
- resp.list[i].status = (enum telephony_network_plmn_status) atoi(pResp);
- }
-
- if ((pResp = tcore_at_tok_nth(network_token, 1))) { /* Long Alpha name */
- dbg("Long Alpha name : %s", pResp);
-
- if (strlen(pResp) > 0)
- /* Strip off starting quote & ending quote */
- strncpy(resp.list[i].name, pResp + 1, strlen(pResp) - 2);
- }
-
- if ((pResp = tcore_at_tok_nth(network_token, 2))) {
- dbg("Short Aplha name : %s", pResp);
- /* Short Aplha name */
- /* Strip off starting quote & ending quote */
- if (strlen(pResp) > 0)
- strncpy(resp.list[i].name, pResp + 1, strlen(pResp) - 2);
- }
-
- /* PLMN ID */
- pResp = tcore_at_tok_nth(network_token, 3);
- if (pResp != NULL) {
- dbg("PLMN ID : %s", pResp);
- temp_plmn_info = tcore_at_tok_extract((const char *)pResp);
- strncpy(resp.list[i].plmn, temp_plmn_info, 6);
- resp.list[i].plmn[6] = '\0';
- }
-
- /* Parse Access Technology */
- if ((pResp = tcore_at_tok_nth(network_token, 4))) {
- if (strlen(pResp) > 0) {
- AcT = atoi(pResp);
-
- if (0 == AcT)
- resp.list[i].act = NETWORK_ACT_GSM;
- else if (2 == AcT)
- resp.list[i].act = NETWORK_ACT_UMTS;
- }
- }
-
- dbg("Operator [%d] :: stat = %d, Name =%s, plmnId = %s, AcT=%d\n", resp.list_count, resp.list[i].status, resp.list[i].name, resp.list[i].plmn, resp.list[i].act);
- resp.list_count++;
-
- tcore_at_tok_free(network_token);
- g_free(alpha_name);
- g_free(temp_plmn_info);
- }
- } else {
- dbg("RESPONSE NOK");
- resp.result = TCORE_RETURN_FAILURE;
- }
-
-OUT:
- ur = tcore_pending_ref_user_request(p);
- if (ur) {
- tcore_user_request_send_response(ur, TRESP_NETWORK_SEARCH, sizeof(struct tresp_network_search), &resp);
- }
-
- /* Free tokens */
- tcore_at_tok_free(tokens);
-}
-
-static void on_response_set_umts_band(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- const TcoreATResponse *atResp = data;
-
- dbg("On Response Set UMTS Band");
-
- if (atResp->success > 0) {
- dbg("Response OK");
- } else {
- dbg("Response NOK");
- }
-
- dbg("Wait for response of XRAT before sending final band setting response to AP");
- return;
-}
-
-
-static void on_response_set_gsm_band(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- const TcoreATResponse *atResp = data;
-
- dbg("On Response Set GSM Band");
- if (atResp->success > 0) {
- dbg("Response OK");
- } else {
- dbg("Response NOK");
- }
-
- dbg("Wait for response of XRAT before sending final band setting response to AP");
- return;
-}
-
-static void on_response_get_umts_band(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- const TcoreATResponse *atResp = data;
- GSList *tokens = NULL;
- const char *line = NULL;
- int total_umts_bands = 0;
- int i = 0;
- char *band_token = NULL;
- char umts_band[20] = {0};
- char umts_band_1 = 0;
- char umts_band_2 = 0;
- char umts_band_5 = 0;
- UserRequest *ur = NULL;
- struct tresp_network_get_band resp = {0};
-
- dbg("Entry on_response_get_umts_band");
-
- resp.mode = NETWORK_BAND_MODE_PREFERRED;
- resp.result = TCORE_RETURN_SUCCESS;
-
- if (atResp->success > 0) {
- dbg("RESPONSE OK");
- if (atResp->lines) {
- line = (char *) atResp->lines->data;
- tokens = tcore_at_tok_new(line);
- total_umts_bands = g_slist_length(tokens);
- dbg("Total UMTS bands enabled are : %d\n", total_umts_bands);
- if (total_umts_bands < 1) {
- goto OUT;
- }
- }
- } else {
- dbg("RESPONSE NOK");
- goto OUT;
- }
-
- for (i = 0; i < total_umts_bands; i++) {
- band_token = tcore_at_tok_nth(tokens, i);
-
- if (band_token == NULL)
- continue;
-
- memset(umts_band, 0x00, sizeof(umts_band));
-
- if (atoi(band_token) == 0) { /* 0 means UMTS automatic */
- umts_band_1 = umts_band_2 = umts_band_5 = TRUE;
- break;
- }
-
- /* Strip off starting quotes & ending quotes */
- strncpy(umts_band, band_token + 1, strlen(band_token) - 2);
-
- if (!strcmp(umts_band, "UMTS_BAND_I")) {
- umts_band_1 = TRUE;
- } else if (!strcmp(umts_band, "UMTS_BAND_II")) {
- umts_band_2 = TRUE;
- } else if (!strcmp(umts_band, "UMTS_BAND_II")) {
- umts_band_5 = TRUE;
- } else {
- /* Telephony is not interest */
- dbg("Telephony is not interested in %s band", umts_band);
- }
- }
-
-OUT:
- if ((umts_band_1) && (umts_band_2) && (umts_band_5)) {
- resp.band = NETWORK_BAND_TYPE_WCDMA;
- } else if (umts_band_1) {
- resp.band = NETWORK_BAND_TYPE_WCDMA2100;
- } else if (umts_band_2) {
- resp.band = NETWORK_BAND_TYPE_WCDMA1900;
- } else if (umts_band_5) {
- resp.band = NETWORK_BAND_TYPE_WCDMA850;
- } else {
- resp.result = TCORE_RETURN_FAILURE;
- }
-
- dbg("Final resp.band sent to TS = %d", resp.band);
-
- ur = tcore_pending_ref_user_request(p);
- if (ur) {
- tcore_user_request_send_response(ur, TRESP_NETWORK_GET_BAND, sizeof(struct tresp_network_get_band), &resp);
- }
-
- if (tokens != NULL)
- tcore_at_tok_free(tokens);
-
- dbg("Exit on_response_get_umts_band");
- return;
-}
-
-static void on_response_get_gsm_band(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- struct tresp_network_get_band resp = {0};
- const TcoreATResponse *atResp = data;
- GSList *tokens = NULL;
- int total_gsm_bands = 0;
- const char *line = NULL;
- int i = 0;
- char *band_token = NULL;
- UserRequest *ur = NULL;
- int gsm_850 = 0;
- int gsm_900 = 0;
- int gsm_1800 = 0;
- int gsm_1900 = 0;
-
- dbg("Entry on_response_get_gsm_band");
-
- resp.mode = NETWORK_BAND_MODE_PREFERRED;
- resp.result = TCORE_RETURN_SUCCESS;
-
- if (atResp->success > 0) {
- dbg("RESPONSE OK");
- if (atResp->lines) {
- line = (char *) atResp->lines->data;
- tokens = tcore_at_tok_new(line);
- total_gsm_bands = g_slist_length(tokens);
- dbg("Total GSM bands enabled are : %d\n", total_gsm_bands);
- if (total_gsm_bands < 1)
- goto OUT;
- }
- }
-
- for (i = 0; i < total_gsm_bands; i++) {
- band_token = tcore_at_tok_nth(tokens, i);
-
- if (band_token == NULL)
- continue;
-
- if (atoi(band_token) == 0) { /* 0 means GSM automatic */
- gsm_850 = gsm_900 = gsm_1800 = gsm_1900 = TRUE;
- break;
- }
-
- switch (atoi(band_token)) {
- case AT_GSM_XBANDSEL_850:
- gsm_850 = TRUE;
- break;
-
- case AT_GSM_XBANDSEL_900:
- gsm_900 = TRUE;
- break;
-
- case AT_GSM_XBANDSEL_1800:
- gsm_1800 = TRUE;
- break;
-
- case AT_GSM_XBANDSEL_1900:
- gsm_1900 = TRUE;
- break;
-
- default:
- break;
- }
- }
-
-OUT:
-
- if (gsm_850 && gsm_900 && gsm_1800 && gsm_1900) {
- resp.band = NETWORK_BAND_TYPE_GSM;
- } else if (gsm_850 && gsm_1900) {
- resp.band = NETWORK_BAND_TYPE_GSM_850_1900;
- } else if (gsm_900 && gsm_1800) {
- resp.band = NETWORK_BAND_TYPE_GSM_900_1800;
- } else if (gsm_1900) {
- resp.band = NETWORK_BAND_TYPE_GSM1900;
- } else if (gsm_850) {
- resp.band = NETWORK_BAND_TYPE_GSM850;
- } else if (gsm_1800) {
- resp.band = NETWORK_BAND_TYPE_GSM1800;
- } else if (gsm_900) {
- resp.band = NETWORK_BAND_TYPE_GSM900;
- } else {
- resp.result = TCORE_RETURN_FAILURE;
- }
-
- dbg("Final resp.band sent to TS = %d", resp.band);
-
- ur = tcore_pending_ref_user_request(p);
- if (ur) {
- tcore_user_request_send_response(ur, TRESP_NETWORK_GET_BAND, sizeof(struct tresp_network_get_band), &resp);
- }
-
- if (tokens != NULL)
- tcore_at_tok_free(tokens);
-
- dbg("Exit on_response_get_gsm_band");
- return;
-}
-
-
-static void on_response_get_xrat(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- TcoreHal *h = NULL;
- UserRequest *ur = NULL;
-
- TcoreATRequest *atreq;
- char *cmd_str = NULL;
- UserRequest *dup_ur = NULL;
- const TcoreATResponse *atResp = data;
- const char *line = NULL;
- char *pResp = NULL;
- GSList *tokens = NULL;
- TcorePending *pending = NULL;
- CoreObject *o = NULL;
- int cp_xrat = 0;
- struct tresp_network_get_band resp = {0};
-
- dbg("Enter on_response_get_xrat !!");
-
- resp.mode = NETWORK_BAND_MODE_PREFERRED;
-
- ur = tcore_pending_ref_user_request(p);
- h = tcore_object_get_hal(tcore_pending_ref_core_object(p));
- o = tcore_pending_ref_core_object(p);
-
- if (atResp->success > 0) {
- dbg("RESPONSE OK");
- if (atResp->lines) {
- line = (char *) atResp->lines->data;
- tokens = tcore_at_tok_new(line);
- if (g_slist_length(tokens) < 1) {
- msg("invalid message");
- goto OUT;
- }
- }
-
- if ((pResp = tcore_at_tok_nth(tokens, 0))) {
- cp_xrat = atoi(pResp);
-
- if ((cp_xrat == AT_XRAT_DUAL)) { /* mode is Dual, send reply to Telephony */
- resp.result = TCORE_RETURN_SUCCESS;
- resp.band = NETWORK_BAND_TYPE_ANY;
-
- ur = tcore_pending_ref_user_request(p);
- if (ur) {
- tcore_user_request_send_response(ur, TRESP_NETWORK_GET_BAND, sizeof(struct tresp_network_get_band), &resp);
- }
- goto OUT;
- } else if ((cp_xrat == AT_XRAT_UMTS)) {
- /* Get UMTS Band Information */
- dup_ur = tcore_user_request_ref(ur); /* duplicate user request for AT+XUBANDSEL */
- cmd_str = g_strdup_printf("AT+XUBANDSEL?");
- atreq = tcore_at_request_new(cmd_str, "+XUBANDSEL", TCORE_AT_SINGLELINE);
- pending = tcore_pending_new(o, 0);
- tcore_pending_set_request_data(pending, 0, atreq);
- tcore_pending_set_response_callback(pending, on_response_get_umts_band, NULL);
- tcore_pending_link_user_request(pending, ur);
- tcore_pending_set_send_callback(pending, on_confirmation_network_message_send, NULL);
- tcore_hal_send_request(h, pending);
- g_free(cmd_str);
- } else if ((cp_xrat == AT_XRAT_UMTS)) {
- /* Get GSM Band Information */
- dup_ur = tcore_user_request_ref(ur); /* duplicate user request for AT+XBANDSEL */
- cmd_str = g_strdup_printf("AT+XBANDSEL?");
- atreq = tcore_at_request_new(cmd_str, "+XBANDSEL", TCORE_AT_SINGLELINE);
- pending = tcore_pending_new(o, 0);
- tcore_pending_set_request_data(pending, 0, atreq);
- tcore_pending_set_response_callback(pending, on_response_get_gsm_band, NULL);
- tcore_pending_link_user_request(pending, dup_ur);
- tcore_pending_set_send_callback(pending, on_confirmation_network_message_send, NULL);
- tcore_hal_send_request(h, pending);
- g_free(cmd_str);
- }
- }
- } else {
- dbg("RESPONSE NOK");
-
- resp.result = TCORE_RETURN_FAILURE;
- resp.band = NETWORK_BAND_TYPE_ANY;
-
- ur = tcore_pending_ref_user_request(p);
- if (ur) {
- tcore_user_request_send_response(ur, TRESP_NETWORK_GET_BAND, sizeof(struct tresp_network_get_band), &resp);
- }
- }
-OUT:
-
- if (tokens != NULL)
- tcore_at_tok_free(tokens);
-
- dbg("Exit on_response_get_xrat !!");
-
- return;
-}
-
-
-static void on_response_set_xrat(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- UserRequest *ur = NULL;
- struct tresp_network_set_band resp = {0};
- const TcoreATResponse *atResp = data;
-
- dbg("On Response Set XRAT");
-
- if (atResp->success > 0) {
- dbg("Response OK");
- resp.result = TCORE_RETURN_SUCCESS;
- } else {
- dbg("Response NOK");
- resp.result = TCORE_RETURN_FAILURE;
- }
-
- ur = tcore_pending_ref_user_request(p);
- if (ur) {
- tcore_user_request_send_response(ur, TRESP_NETWORK_SET_BAND, sizeof(struct tresp_network_set_band), &resp);
- }
-
- return;
-}
-
-static void on_response_set_preferred_plmn(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- UserRequest *ur = NULL;
- struct tresp_network_set_preferred_plmn resp = {0};
- const TcoreATResponse *atResp = data;
-
- dbg("ENTER on_response_set_preferred_plmn");
-
- if (atResp->success > 0) {
- dbg("Response OK");
- resp.result = TCORE_RETURN_SUCCESS;
- } else {
- dbg("Response NOK");
- resp.result = TCORE_RETURN_FAILURE;
- }
-
- ur = tcore_pending_ref_user_request(p);
- if (ur) {
- tcore_user_request_send_response(ur, TRESP_NETWORK_SET_PREFERRED_PLMN, sizeof(struct tresp_network_set_preferred_plmn), &resp);
- }
-
- dbg("Exit on_response_set_preferred_plmn");
- return;
-}
-
-static void on_response_get_nitz_name(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- const TcoreATResponse *atResp = data;
- GSList *tokens = NULL;
- const char *line = NULL;
- CoreObject *o = NULL;
- struct tnoti_network_identity noti;
- int nol = 0;
- int count = 0;
- int net_name_type = 0;
- char *pResp = NULL;
- char *net_name = NULL;
-
- dbg("Entry on_response_get_nitz_name (+XCOPS)");
- o = tcore_pending_ref_core_object(p);
- if (atResp->success > 0) {
- dbg("RESPONSE OK");
-
- if (atResp->lines) {
- nol = g_slist_length(atResp->lines);
- if (nol > 3) {
- msg("invalid message");
- goto OUT;
- }
-
- memset(¬i, 0, sizeof(struct tnoti_network_identity));
-
- for (count = 0; count < nol; count++) {
- // parse each line
- line = g_slist_nth_data(atResp->lines, count);
- tokens = tcore_at_tok_new(line);
- dbg("line %d start---------------", count);
-
- if ((pResp = tcore_at_tok_nth(tokens, 0))) {
- net_name_type = atoi(pResp);
- dbg("Net name type : %d", net_name_type);
-
- switch (net_name_type) {
- case 0: /* plmn_id (mcc, mnc) */
- if ((pResp = tcore_at_tok_nth(tokens, 1))) {
- if (strlen(pResp) > 0) {
- net_name = tcore_at_tok_extract((const char *)pResp);
- strncpy(noti.plmn, net_name, 6);
- noti.plmn[6] = '\0';
- }
- }
- break;
-
- case 5: /* Short NITZ name*/
- case 3: /* Short Network Name (CPHS) */
- if ((pResp = tcore_at_tok_nth(tokens, 1))) {
- if (strlen(pResp) > 0) {
- net_name = tcore_at_tok_extract((const char *)pResp);
- strncpy(noti.short_name, net_name, 16);
- noti.short_name[16] = '\0';
- }
- }
- break;
-
- case 6: /* Full NITZ name */
- case 4: /* Long Network Name (CPHS) */
- if ((pResp = tcore_at_tok_nth(tokens, 1))) {
- if (strlen(pResp) > 0) {
- net_name = tcore_at_tok_extract((const char *)pResp);
- strncpy(noti.full_name, net_name, 32);
- noti.full_name[32] = '\0';
- }
- }
- break;
-
- default:
- break;
- }
-
- g_free(net_name);
- net_name = NULL;
- }
-
- tcore_at_tok_free(tokens);
- }
-
- dbg("plmn <%s> short NITZ name<%s> full NITZ name<%s>",
- noti.plmn, noti.short_name, noti.full_name);
- tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_NETWORK_IDENTITY,
- sizeof(struct tnoti_network_identity), ¬i);
- }
- } else {
- dbg("RESPONSE NOK");
- }
-
-OUT:
- dbg("Exit on_response_get_nitz_name");
-}
-
-static void on_response_get_preferred_plmn(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- UserRequest *ur;
- int i = 0;
- char *line = NULL;
- const TcoreATResponse *atResp = data;
- GSList *tokens = NULL;
- char *pResp = NULL;
- int plmn_format = 0;
-
- struct tresp_network_get_preferred_plmn resp = {0};
- int total_lines = 0;
- int GSM_AcT2 = 0, GSM_Compact_AcT2 = 0, UTRAN_AcT2 = 0;
-
- dbg("Entry");
-
- if (atResp->success > 0) {
- dbg("RESPONSE OK");
- if (atResp->lines) {
- total_lines = g_slist_length(atResp->lines);
- dbg("Total number of network present in Preferred PLMN list is %d\n", total_lines);
-
- if (total_lines < 1) {
- msg("invalid message");
- goto OUT;
- }
-
- if (total_lines >= MAX_NETWORKS_PREF_PLMN_SUPPORT)
- total_lines = MAX_NETWORKS_PREF_PLMN_SUPPORT;
-
-/*
-+CPOL: <index1>,<format>,<oper1>[,<GSM_AcT1>,<GSM_Compact_AcT1>,<UTRAN_AcT1>,<E-UTRAN_AcT1>] [<CR><LF>
-+CPOL: <index2>,<format>,<oper2>[,<GSM_AcT2>,<GSM_Compact_AcT2>,<UTRAN_AcT2>,<E-UTRAN_AcT2>]
-*/
- resp.result = TCORE_RETURN_SUCCESS;
-
- for (i = 0; i < total_lines; i++) {
- /* Take each line response at a time & parse it */
- line = tcore_at_tok_nth(atResp->lines, i);
- tokens = tcore_at_tok_new(line);
-
- /* <index2>,<format>,<oper2>[,<GSM_AcT2>,<GSM_Compact_AcT2>,<UTRAN_AcT2>,<E-UTRAN_AcT2>] */
-
- /* EF Index */
- if ((pResp = tcore_at_tok_nth(tokens, 0))) {
- dbg("Index : %s", pResp);
- resp.list[i].index = atoi(pResp);
- }
- /* Format */
- if ((pResp = tcore_at_tok_nth(tokens, 1))) {
- dbg("format : %s", pResp);
- plmn_format = atoi(pResp);
- }
-
- /* Operator PLMN ID */
- if ((pResp = tcore_at_tok_nth(tokens, 2))) {
- dbg("plmn ID : %s", pResp);
-
- if (strlen(pResp) > 0) {
- char *oper;
-
- oper = tcore_at_tok_extract((const char *)pResp);
- dbg("operator <%s>", oper);
-
- // Get only PLMN ID
- if (plmn_format == 2) {
- strncpy(resp.list[i].plmn, oper, 6);
- resp.list[i].plmn[6] = '\0';
- }
-
- g_free (oper);
- }
- }
-
- if ((pResp = tcore_at_tok_nth(tokens, 3))) {
- dbg("GSM_AcT2 : %s", pResp);
- GSM_AcT2 = atoi(pResp);
- }
-
- if ((pResp = tcore_at_tok_nth(tokens, 4))) {
- dbg("GSM_Compact AcT2 : %s", pResp);
- GSM_Compact_AcT2 = atoi(pResp);
- }
-
- if ((pResp = tcore_at_tok_nth(tokens, 5))) {
- dbg("UTRAN_AcT2 : %s", pResp);
- UTRAN_AcT2 = atoi(pResp);
- }
-
- if (UTRAN_AcT2 && (GSM_AcT2 || GSM_Compact_AcT2))
- resp.list[i].act = NETWORK_ACT_GSM_UTRAN;
- else if (UTRAN_AcT2)
- resp.list[i].act = NETWORK_ACT_UMTS;
- else if (GSM_AcT2 || GSM_Compact_AcT2)
- resp.list[i].act = NETWORK_ACT_GPRS;
-
- (resp.list_count)++;
-
- tcore_at_tok_free(tokens);
- }
- }
- } else {
- dbg("RESPONSE NOT OK");
- // TODO: CMEE error mapping is required.
- resp.result = TCORE_RETURN_FAILURE;
- }
-
-OUT:
- ur = tcore_pending_ref_user_request(p);
- if (ur) {
- tcore_user_request_send_response(ur, TRESP_NETWORK_GET_PREFERRED_PLMN, sizeof(struct tresp_network_get_preferred_plmn), &resp);
- }
- dbg("Exit");
- return;
-}
-
-static void on_response_get_serving_network(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- const TcoreATResponse *resp = data;
- UserRequest *ur;
- struct tresp_network_get_serving_network Tresp = {0};
- char *long_plmn_name = NULL;
- char *short_plmn_name = NULL;
- char *plmn_id = NULL;
- CoreObject *o;
- GSList *tokens = NULL;
- const char *line;
- int network_mode = -1;
- int plmn_format = -1;
- int AcT = -1;
- struct tnoti_network_identity noti;
- char *pResp = NULL;
- int nol, count = 0;
-
- o = tcore_pending_ref_core_object(p);
-
- if (resp->success <= 0) {
- dbg("RESPONSE NOK");
-
- ur = tcore_pending_ref_user_request(p);
- if (ur) {
- Tresp.result = TCORE_RETURN_FAILURE;
- tcore_user_request_send_response(ur, TRESP_NETWORK_GET_SERVING_NETWORK, sizeof(struct tresp_network_get_serving_network), &Tresp);
- }
-
- return;
- } else {
- dbg("RESPONSE OK");
- nol = g_slist_length(resp->lines);
- dbg("nol : %d", nol);
-
- for (count = 0; count < nol; count++) {
- // parse each line
- line = g_slist_nth_data(resp->lines, count);
- tokens = tcore_at_tok_new(line);
- dbg("line %d start---------------", count);
- // mode
- if ((pResp = tcore_at_tok_nth(tokens, 0))) {
- dbg("mode : %s", pResp);
- network_mode = atoi(pResp);
- }
-
- // format (optional)
- if ((pResp = tcore_at_tok_nth(tokens, 1))) {
- dbg("format : %s", pResp);
- if (strlen(pResp) > 0)
- plmn_format = atoi(pResp);
- }
-
- // plmn
- switch (plmn_format) {
- case AT_COPS_FORMAT_LONG_ALPHANUMERIC:
- if ((pResp = tcore_at_tok_nth(tokens, 2))) {
- dbg("long PLMN : %s", pResp);
- if (strlen(pResp) > 0) {
- long_plmn_name = tcore_at_tok_extract((const char *)pResp);
-
- // set network name into po
- tcore_network_set_network_name(o, TCORE_NETWORK_NAME_TYPE_FULL, long_plmn_name);
- }
- }
- break;
-
- case AT_COPS_FORMAT_SHORT_ALPHANUMERIC:
- if ((pResp = tcore_at_tok_nth(tokens, 2))) {
- dbg("short PLMN : %s", pResp);
- if (strlen(pResp) > 0) {
- short_plmn_name = tcore_at_tok_extract((const char *)pResp);
-
- // set network name into po
- tcore_network_set_network_name(o, TCORE_NETWORK_NAME_TYPE_SHORT, short_plmn_name);
- }
- }
- break;
-
- case AT_COPS_FORMAT_NUMERIC:
- if ((pResp = tcore_at_tok_nth(tokens, 2))) {
- dbg("numeric : %s", pResp);
- if (strlen(pResp) > 0) {
- plmn_id = tcore_at_tok_extract((const char *)pResp);
-
- // set plmn id into po
- tcore_network_set_plmn(o, plmn_id);
- }
- }
- break;
-
- default:
- break;
- }
-
- // act
- if ((pResp = tcore_at_tok_nth(tokens, 3))) {
- dbg("AcT : %s", pResp);
- if (strlen(pResp) > 0) {
- AcT = atoi(pResp);
- tcore_network_set_access_technology(o, lookup_tbl_access_technology[AcT]);
- }
- }
-
- tcore_at_tok_free(tokens);
- }
-
- if(plmn_id)
- memcpy(Tresp.plmn, plmn_id, strlen(plmn_id));
- tcore_network_get_access_technology(o, &(Tresp.act));
- tcore_network_get_lac(o, &(Tresp.gsm.lac));
-
- ur = tcore_pending_ref_user_request(p);
- if (ur) {
- Tresp.result = TCORE_RETURN_SUCCESS;
- tcore_user_request_send_response(ur, TRESP_NETWORK_GET_SERVING_NETWORK, sizeof(struct tresp_network_get_serving_network), &Tresp);
- } else {
- /* Network change noti */
- struct tnoti_network_change network_change;
-
- memset(&network_change, 0, sizeof(struct tnoti_network_change));
- if(plmn_id)
- memcpy(network_change.plmn, plmn_id, strlen(plmn_id));
- tcore_network_get_access_technology(o, &(network_change.act));
- tcore_network_get_lac(o, &(network_change.gsm.lac));
-
- tcore_server_send_notification(tcore_plugin_ref_server(tcore_pending_ref_plugin(p)), tcore_pending_ref_core_object(p),
- TNOTI_NETWORK_CHANGE, sizeof(struct tnoti_network_change), &network_change);
- dbg("dbg.. network_change.plmn : %s", network_change.plmn);
- dbg("dbg.. network_change.act : %d", network_change.act);
- dbg("dbg.. network_change.gsm.lac : %d", network_change.gsm.lac);
-
- if ((AT_COPS_MODE_DEREGISTER != network_mode) &&
- (AT_COPS_MODE_SET_ONLY != network_mode)) {
- /*Network identity noti*/
- memset(¬i, 0x0, sizeof(struct tnoti_network_identity));
- if (long_plmn_name)
- memcpy(noti.full_name, long_plmn_name, MIN(32, strlen(long_plmn_name)));
- if (short_plmn_name)
- memcpy(noti.short_name, short_plmn_name, MIN(16, strlen(short_plmn_name)));
- if (plmn_id)
- memcpy(noti.plmn, plmn_id, strlen(plmn_id)); // plmn_id length is necessarily <= 6
-
- tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)),
- o, TNOTI_NETWORK_IDENTITY, sizeof(struct tnoti_network_identity), ¬i);
- dbg("dbg.. noti.short_name : %s", noti.short_name);
- dbg("dbg.. noti.full_name : %s", noti.full_name);
- dbg("dbg.. noti.plmn : %s", noti.plmn);
- }
- }
-
- g_free(long_plmn_name);
- g_free(short_plmn_name);
- g_free(plmn_id);
- }
- return;
-}
-
-static gboolean on_event_ps_network_regist(CoreObject *o, const void *data, 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;
- struct tnoti_network_location_cellinfo net_lac_cell_info = {0};
- struct tnoti_ps_protocol_status noti = {0};
- unsigned char svc_domain = NETWORK_SERVICE_DOMAIN_PS;
- int stat = 0, AcT = 0;
- unsigned int lac = 0xffff, ci = 0xffff;
- unsigned int rac = 0xffff;
- GSList *tokens = NULL;
- char *pResp;
- char *line = NULL;
- GSList *lines = NULL;
-
- lines = (GSList *) data;
- if (1 != g_slist_length(lines)) {
- dbg("unsolicited msg but multiple line");
- goto OUT;
- }
- line = (char *) (lines->data);
- dbg("+CGREG NOTI RECEIVED");
-
-/*
-+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
-Note: <Act> is supporting from R7 and above Protocol Stack.
-
-<rac>: is R7 and above feature, string type; one byte routing area code in hexadecimal format.
-*/
- if (line != NULL) {
- tokens = tcore_at_tok_new(line);
- if (g_slist_length(tokens) < 1) {
- msg("invalid message");
- goto OUT;
- }
-
- if (!(pResp = g_slist_nth_data(tokens, 0))) {
- dbg("No STAT in +CGREG");
- goto OUT;
- } else {
- stat = atoi(pResp);
- if ((pResp = g_slist_nth_data(tokens, 1))) {
- pResp = util_removeQuotes(pResp);
- lac = strtol(pResp, NULL, 16);
- g_free(pResp);
- }
-
- if ((pResp = g_slist_nth_data(tokens, 2))) {
- pResp = util_removeQuotes(pResp);
- ci = strtol(pResp, NULL, 16);
- g_free(pResp);
- } else {
- dbg("No ci in +CGREG");
- }
-
- if ((pResp = g_slist_nth_data(tokens, 3)))
- AcT = atoi(pResp);
- else
- dbg("No AcT in +CGREG");
-
- if ((pResp = g_slist_nth_data(tokens, 4))) {
- pResp = util_removeQuotes(pResp);
- rac = strtol(pResp, NULL, 16);
- g_free(pResp);
- } else {
- dbg("No rac in +CGREG");
- }
- }
-
-
- dbg("stat=%d, lac=0x%lx, ci=0x%lx, Act=%d, rac = 0x%x", stat, lac, ci, AcT, rac);
-
- 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);
-
- tcore_network_get_service_status(o, TCORE_NETWORK_SERVICE_DOMAIN_TYPE_CIRCUIT, &cs_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_cell_id(o, ci);
- tcore_network_set_rac(o, rac);
-
- 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(regist_status), ®ist_status);
-#if 0
- if (service_type == NETWORK_SERVICE_TYPE_HSDPA)
- noti.status = TELEPHONY_HSDPA_ON;
- else
- noti.status = TELEPHONY_HSDPA_OFF;
-#else
- switch(AcT){
- case AT_COPS_ACT_GSM:/*Fall Through*/
- case AT_COPS_ACT_GSM_COMPACT:/*Fall Through*/
- case AT_COPS_ACT_UTRAN:/*Fall Through*/
- case AT_COPS_ACT_GSM_EGPRS:/*Fall Through*/
- case AT_COPS_ACT_E_UTRAN:
- {
- dbg("Not required for Protocol Status Notification");
- goto OUT;
- }
- case AT_COPS_ACT_UTRAN_HSDPA:
- {
- dbg("HSDPA");
- noti.status = TELEPHONY_HSDPA_ON;
- break;
- }
- case AT_COPS_ACT_UTRAN_HSUPA:
- {
- dbg("HSUPA");
- noti.status = TELEPHONY_HSUPA_ON;
- break;
- }
- case AT_COPS_ACT_UTRAN_HSDPA_HSUPA:
- {
- dbg("HSPA");
- noti.status = TELEPHONY_HSPA_ON;
- break;
- }
- default:
- {
- dbg("Ignore");
- goto OUT;
- }
- }
-#endif
- tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_PS_PROTOCOL_STATUS,
- sizeof(struct tnoti_ps_protocol_status), ¬i);
-
- /* Get PLMN ID needed to application */
- // get_serving_network(o, NULL);
- } else {
- dbg("Response NOK");
- }
-
-OUT:
- if (NULL != tokens)
- tcore_at_tok_free(tokens);
- return TRUE;
-}
-
-static gboolean on_event_cs_network_regist(CoreObject *o, const void *event_info, void *user_data)
-{
- GSList *lines = NULL;
- char *line = NULL;
- 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;
- struct tnoti_network_location_cellinfo net_lac_cell_info = {0};
-
-
- unsigned char svc_domain = NETWORK_SERVICE_DOMAIN_CS;
- int stat = 0, AcT = 0;
- unsigned int lac = 0xffff, ci = 0xffff;
- GSList *tokens = NULL;
- char *pResp;
-
- lines = (GSList *) event_info;
- if (1 != g_slist_length(lines)) {
- dbg("unsolicited msg but multiple line");
- goto OUT;
- }
- line = (char *) (lines->data);
-
- dbg("+CREG NOTI RECEIVED");
-
-/*
-+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
-Note: <Act> is supporting from R7 and above Protocol Stack.
-*/
- if (line != NULL) {
- tokens = tcore_at_tok_new(line);
- if (g_slist_length(tokens) < 1) {
- msg("invalid message");
- goto OUT;
- }
-
- if (!(pResp = g_slist_nth_data(tokens, 0))) {
- dbg("No STAT in +CREG");
- goto OUT;
- } else {
- stat = atoi(pResp);
- if ((pResp = g_slist_nth_data(tokens, 1))) {
- pResp = util_removeQuotes(pResp);
- lac = strtol(pResp, NULL, 16);
- g_free(pResp);
- }
-
- if ((pResp = g_slist_nth_data(tokens, 2))) {
- pResp = util_removeQuotes(pResp);
- ci = strtol(pResp, NULL, 16);
- g_free(pResp);
- } else {
- dbg("No ci in +CREG");
- }
-
- if ((pResp = g_slist_nth_data(tokens, 3)))
- AcT = atoi(pResp);
- else
- dbg("No AcT in +CREG");
- }
-
-
- dbg("stat=%d, lac=0x%lx, ci=0x%lx, Act=%d", stat, lac, ci, AcT);
-
- cs_status = lookup_tbl_net_status[stat];
- tcore_network_set_service_status(o, TCORE_NETWORK_SERVICE_DOMAIN_TYPE_CIRCUIT, cs_status);
-
- // 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_cell_id(o, ci);
-
- 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 PLMN ID needed to application */
- if ((NETWORK_SERVICE_DOMAIN_STATUS_FULL == cs_status) ||
- NETWORK_SERVICE_DOMAIN_STATUS_FULL == ps_status)
- get_serving_network(o, NULL);
- } else {
- dbg("Response NOK");
- }
-
-OUT:
- if (NULL != tokens)
- tcore_at_tok_free(tokens);
- return TRUE;
-}
-
-static gboolean on_event_network_icon_info(CoreObject *o, const void *event_info, void *user_data)
-{
- struct tnoti_network_icon_info net_icon_info = {0};
- char *line = NULL;
- char *rssiToken = NULL;
- char *batteryToken = NULL;
- GSList *tokens = NULL;
- GSList *lines = NULL;
-
- lines = (GSList *) event_info;
- if (1 != g_slist_length(lines)) {
- dbg("unsolicited msg but multiple line");
- goto OUT;
- }
- line = (char *) (lines->data);
- dbg("+XCIEV Network Icon Info Noti Recieve");
- memset(&net_icon_info, 0, sizeof(struct tnoti_network_icon_info));
-
- if (line != NULL) {
- dbg("Response OK");
-
- tokens = tcore_at_tok_new(line);
- if (g_slist_length(tokens) != 2) {
- msg("invalid message");
- goto OUT;
- }
-
- rssiToken = (char *) g_slist_nth_data(tokens, 0);
-
- if (strlen(rssiToken) > 0) {
- net_icon_info.type = NETWORK_ICON_INFO_RSSI;
- net_icon_info.rssi = atoi(g_slist_nth_data(tokens, 0));
- dbg("rssi level : %d", net_icon_info.rssi);
- }
-
- batteryToken = (char *) g_slist_nth_data(tokens, 1);
- if (strlen(batteryToken) > 0) {
- net_icon_info.type = NETWORK_ICON_INFO_BATTERY;
- net_icon_info.battery = atoi(g_slist_nth_data(tokens, 1));
- dbg("battery level : %d", net_icon_info.battery);
- }
-
- 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);
- } else {
- dbg("Response NOK");
- }
-
-
-OUT:
- if (NULL != tokens)
- tcore_at_tok_free(tokens);
-
- return TRUE;
-}
-
-static gboolean on_event_network_ctzv_time_info(CoreObject *o, const void *event_info, void *user_data)
-{
- struct tnoti_network_timeinfo net_time_info = {0};
- char *line = NULL;
- GSList *tokens = NULL;
- char *time = NULL;
- char *time_zone = NULL;
- GSList *lines = NULL;
- char ptime_param[20] = {0};
- UserRequest *ur = NULL;
- dbg("Enter : on_event_network_ctzv_time_info");
-
- lines = (GSList *) event_info;
- if (1 != g_slist_length(lines)) {
- dbg("unsolicited msg but multiple line");
- goto OUT;
- }
- line = (char *) (lines->data);
-
-/*
-+CTZV: <tz>,<time>
-<tz> integer value indicating the time zone (e.g. -22 or +34)
-<time> string type value; format is yy/MM/dd,hh:mms, wherein characters indicates year, month, day, hour,
-minutes, seconds.*/
-
- dbg("Network time info (+CTZV) recieved");
-
- if (line != NULL) {
- dbg("Response OK");
- dbg("noti line is %s", line);
-
- tokens = tcore_at_tok_new(line);
-
- if (g_slist_length(tokens) < 2) {
- msg("invalid message");
- goto OUT;
- }
-
- if ((time_zone = g_slist_nth_data(tokens, 0))) {
- net_time_info.gmtoff = atoi(time_zone) * 15; /* TZ in minutes */
- }
-
- if (tcore_network_get_plmn(o) != NULL)
- strcpy(net_time_info.plmn, tcore_network_get_plmn(o));
-
- if ((time = g_slist_nth_data(tokens, 1)) && (strlen(time) > 18)) {
- strncpy(ptime_param, time + 1, 2); /* skip past initial quote (") */
- net_time_info.year = atoi(ptime_param);
-
- strncpy(ptime_param, time + 4, 2); /* skip slash (/) after year param */
- net_time_info.month = atoi(ptime_param);
-
- strncpy(ptime_param, time + 7, 2); /* skip past slash (/) after month param */
- net_time_info.day = atoi(ptime_param);
-
- strncpy(ptime_param, time + 10, 2); /* skip past comma (,) after day param */
- net_time_info.hour = atoi(ptime_param);
-
- strncpy(ptime_param, time + 13, 2); /* skip past colon (:) after hour param */
- net_time_info.minute = atoi(ptime_param);
-
- strncpy(ptime_param, time + 16, 2); /* skip past colon (:) after minute param */
- net_time_info.second = atoi(ptime_param);
- }
- tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_NETWORK_TIMEINFO, sizeof(struct tnoti_network_timeinfo), &net_time_info);
-
- dbg("new pending(AT+XOPS=0/5/6 for Nitz PLMN name)");
-
- /* Get NITZ name and plmn_id via AT+XCOPS = 0/5/6 */
- nwk_prepare_and_send_pending_request(o, "AT+XCOPS=0;+XCOPS=5;+XCOPS=6", "+XCOPS", TCORE_AT_MULTILINE, ur, on_response_get_nitz_name);
- } else {
- dbg("line is NULL");
- }
-
-OUT:
- if (NULL != tokens)
- tcore_at_tok_free(tokens);
-
- dbg("Exit: on_event_network_ctzv_time_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;
-
- 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);
- }
-
- // fallback in case no SPN name is provided
- if (resp->data.spn.spn[0] == '\0')
- tcore_network_set_network_name_priority(o, TCORE_NETWORK_NAME_PRIORITY_NETWORK);
- }
-}
-
-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)
-{
- TcoreHal *h = NULL;
- TcorePending *pending = NULL;
- TcoreATRequest *atreq = NULL;
- char *cmd_str = NULL;
- dbg("search_network - ENTER!!");
-
- if (!o || !ur)
- return TCORE_RETURN_EINVAL;
-
- h = tcore_object_get_hal(o);
- if(FALSE == tcore_hal_get_power_state(h)){
- dbg("cp not ready/n");
- return TCORE_RETURN_ENOSYS;
- }
-
- pending = tcore_pending_new(o, 0);
-
- cmd_str = g_strdup_printf("AT+COPS=?");
- atreq = tcore_at_request_new(cmd_str, "+COPS", TCORE_AT_SINGLELINE);
-
- tcore_pending_set_request_data(pending, 0, atreq);
- tcore_pending_set_timeout(pending, 60);
- tcore_pending_set_priority(pending, TCORE_PENDING_PRIORITY_DEFAULT);
- tcore_pending_set_response_callback(pending, on_response_search_network, NULL);
- tcore_pending_set_timeout_callback(pending, on_timeout_search_network, NULL);
- tcore_pending_link_user_request(pending, ur);
- tcore_pending_set_send_callback(pending, on_confirmation_network_message_send, NULL);
-
- tcore_hal_send_request(h, pending);
- g_free(cmd_str);
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn set_plmn_selection_mode(CoreObject *o, UserRequest *ur)
-{
- TcoreHal *h = NULL;
- TcorePending *pending = NULL;
- TcoreATRequest *atreq;
- char *cmd_str = NULL;
- int format = 0; /* default value for long alphanumeric */
- int mode = 0;
- char plmn[7] = {0};
- int act = 0;
-
- const struct treq_network_set_plmn_selection_mode *req_data = NULL;
-
-
- dbg("set_plmn_selection_mode - ENTER!!");
-
- if (!o || !ur)
- return TCORE_RETURN_EINVAL;
-
- req_data = tcore_user_request_ref_data(ur, NULL);
- h = tcore_object_get_hal(o);
- if(FALSE == tcore_hal_get_power_state(h)){
- dbg("cp not ready/n");
- return TCORE_RETURN_ENOSYS;
- }
- pending = tcore_pending_new(o, 0);
-
- // Command Format - AT+COPS=[<mode>[,<format>[,<oper>[,< AcT>]]]]
- /* oper parameter format
- - 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.
- */
-
- if ((req_data->act == NETWORK_ACT_GSM) || (req_data->act == NETWORK_ACT_EGPRS))
- act = 0;
- else
- act = 2;
-
- switch (req_data->mode) {
- case NETWORK_SELECT_MODE_MANUAL:
- {
- mode = AT_COPS_MODE_MANUAL;
- format = AT_COPS_FORMAT_NUMERIC;
-
- memset(plmn, 0, 7);
- memcpy(plmn, req_data->plmn, 6);
-
- if (strlen(req_data->plmn) == 6) {
- if (plmn[5] == '#')
- plmn[5] = 0;
- }
-
- cmd_str = g_strdup_printf("AT+COPS=%d,%d,\"%s\",%d", mode, format, plmn, act);
- }
- break;
-
- case NETWORK_SELECT_MODE_AUTOMATIC:
- default:
- cmd_str = g_strdup("AT+COPS=0");
- break;
- }
-
-
- atreq = tcore_at_request_new(cmd_str, "+COPS", TCORE_AT_NO_RESULT);
-
- tcore_pending_set_request_data(pending, 0, atreq);
- tcore_pending_set_response_callback(pending, on_response_set_plmn_selection_mode, NULL);
- tcore_pending_link_user_request(pending, ur);
- tcore_pending_set_send_callback(pending, on_confirmation_network_message_send, NULL);
-
- tcore_hal_send_request(h, pending);
- g_free(cmd_str);
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn get_plmn_selection_mode(CoreObject *o, UserRequest *ur)
-{
- TcoreHal *h = NULL;
- TcorePending *pending = NULL;
- TcoreATRequest *atreq;
- char *cmd_str = NULL;
-
- dbg("get_plmn_selection_mode - ENTER!!");
-
- if (!o || !ur)
- return TCORE_RETURN_EINVAL;
-
- h = tcore_object_get_hal(o);
- if(FALSE == tcore_hal_get_power_state(h)){
- dbg("cp not ready/n");
- return TCORE_RETURN_ENOSYS;
- }
- pending = tcore_pending_new(o, 0);
-
- cmd_str = g_strdup_printf("AT+COPS?");
- atreq = tcore_at_request_new(cmd_str, "+COPS", TCORE_AT_SINGLELINE);
-
- tcore_pending_set_request_data(pending, 0, atreq);
- tcore_pending_set_response_callback(pending, on_response_get_plmn_selection_mode, NULL);
- tcore_pending_link_user_request(pending, ur);
- tcore_pending_set_send_callback(pending, on_confirmation_network_message_send, NULL);
-
- tcore_hal_send_request(h, pending);
- g_free(cmd_str);
- return TCORE_RETURN_SUCCESS;
-}
-
-
-static TReturn set_band(CoreObject *o, UserRequest *ur)
-{
- TcoreHal *h = NULL;
- TcorePending *pending = NULL;
- TcorePending *pending_gsm = NULL;
- TcorePending *pending_umts = NULL;
- TcoreATRequest *atreq;
- char *cmd_str = NULL;
- const struct treq_network_set_band *req_data;
- gboolean set_gsm_band = 0;
- gboolean set_umts_band = 0;
- int gsm_band = 255;
- int gsm_band2 = 255;
- char *umts_band = NULL;
- UserRequest *dup_ur_gsm = NULL;
- UserRequest *dup_ur_umts = NULL;
-
- dbg("set_band - ENTER!!");
-
- if (!o || !ur)
- return TCORE_RETURN_EINVAL;
-
- req_data = tcore_user_request_ref_data(ur, NULL);
- h = tcore_object_get_hal(o);
- if(FALSE == tcore_hal_get_power_state(h)){
- dbg("cp not ready/n");
- return TCORE_RETURN_ENOSYS;
- }
-
- dbg("set_band - called with band = %d", req_data->band);
-
- switch (req_data->band) {
- case NETWORK_BAND_TYPE_GSM850:
- gsm_band = AT_GSM_XBANDSEL_850;
- set_gsm_band = TRUE;
- break;
-
- case NETWORK_BAND_TYPE_GSM_900_1800:
- gsm_band = AT_GSM_XBANDSEL_900;
- gsm_band2 = AT_GSM_XBANDSEL_1800;
- set_gsm_band = TRUE;
- break;
-
- case NETWORK_BAND_TYPE_GSM1900:
- gsm_band = AT_GSM_XBANDSEL_1900;
- set_gsm_band = TRUE;
- break;
-
- case NETWORK_BAND_TYPE_GSM1800:
- gsm_band = AT_GSM_XBANDSEL_1800;
- set_gsm_band = TRUE;
- break;
-
- case NETWORK_BAND_TYPE_GSM_850_1900:
- gsm_band = AT_GSM_XBANDSEL_850;
- gsm_band2 = AT_GSM_XBANDSEL_1900;
- set_gsm_band = TRUE;
- break;
-
- case NETWORK_BAND_TYPE_ANY:
- gsm_band = AT_GSM_XBANDSEL_AUTOMATIC;
- set_umts_band = TRUE;
- set_gsm_band = TRUE;
- break;
-
- case NETWORK_BAND_TYPE_WCDMA:
- set_umts_band = TRUE;
- break;
-
- case NETWORK_BAND_TYPE_WCDMA2100:
- umts_band = "UMTS_BAND_I";
- set_umts_band = TRUE;
- break;
-
- case NETWORK_BAND_TYPE_WCDMA1900:
- umts_band = "UMTS_BAND_II";
- set_umts_band = TRUE;
- break;
-
- case NETWORK_BAND_TYPE_WCDMA850:
- umts_band = "UMTS_BAND_V";
- set_umts_band = TRUE;
- break;
-
- default:
- break;
- }
-
- dbg("set_band > set_umts_band = %d, set_gsm_band = %d", set_umts_band, set_gsm_band);
-
- if (set_umts_band == TRUE) {
- if ((req_data->band == NETWORK_BAND_TYPE_WCDMA) || (req_data->band == NETWORK_BAND_TYPE_ANY))
- cmd_str = g_strdup_printf("AT+XUBANDSEL=0");
- else
- cmd_str = g_strdup_printf("AT+XUBANDSEL=%s", umts_band);
-
- atreq = tcore_at_request_new(cmd_str, "+XUBANDSEL", TCORE_AT_NO_RESULT);
- pending_umts = tcore_pending_new(o, 0);
-
- tcore_pending_set_request_data(pending_umts, 0, atreq);
- tcore_pending_set_priority(pending_umts, TCORE_PENDING_PRIORITY_DEFAULT);
- tcore_pending_set_response_callback(pending_umts, on_response_set_umts_band, NULL);
-
- /* duplicate user request for UMTS Band setting AT command for same UR */
- dup_ur_umts = tcore_user_request_ref(ur);
- tcore_pending_link_user_request(pending_umts, dup_ur_umts);
- tcore_pending_set_send_callback(pending_umts, on_confirmation_network_message_send, NULL);
-
- tcore_hal_send_request(h, pending_umts);
- g_free(cmd_str);
- }
-
- if (set_gsm_band == TRUE) {
- dbg("Entered set_gsm_band");
- if (gsm_band2 == 255)
- cmd_str = g_strdup_printf("AT+XBANDSEL=%d", gsm_band);
- else
- cmd_str = g_strdup_printf("AT+XBANDSEL=%d,%d", gsm_band, gsm_band2);
-
- dbg("Command string: %s", cmd_str);
- atreq = tcore_at_request_new(cmd_str, "+XBANDSEL", TCORE_AT_NO_RESULT);
- pending_gsm = tcore_pending_new(o, 0);
-
- tcore_pending_set_request_data(pending_gsm, 0, atreq);
- tcore_pending_set_priority(pending_gsm, TCORE_PENDING_PRIORITY_DEFAULT);
- tcore_pending_set_response_callback(pending_gsm, on_response_set_gsm_band, NULL);
-
- /* duplicate user request for GSM Band setting AT command for same UR */
- dup_ur_gsm = tcore_user_request_ref(ur);
- tcore_pending_link_user_request(pending_gsm, dup_ur_gsm);
- tcore_pending_set_send_callback(pending_gsm, on_confirmation_network_message_send, NULL);
-
- tcore_hal_send_request(h, pending_gsm);
- g_free(cmd_str);
- }
-
- /* Lock device to specific RAT as requested by application */
-/*
-AT+XRAT=<Act>[,<PreferredAct>]
-<AcT> indicates the radio access technology and may be
-0 GSM single mode
-1 GSM / UMTS Dual mode
-2 UTRAN (UMTS)
-*/
- if ((set_umts_band == TRUE) && (set_gsm_band == TRUE)) {
- cmd_str = g_strdup_printf("AT+XRAT=%d", AT_XRAT_DUAL);
- } else if (set_umts_band == TRUE) {
- cmd_str = g_strdup_printf("AT+XRAT=%d", AT_XRAT_UMTS);
- } else {
- cmd_str = g_strdup_printf("AT+XRAT=%d", AT_XRAT_GSM);
- }
- atreq = tcore_at_request_new(cmd_str, "+XRAT", TCORE_AT_NO_RESULT);
- pending = tcore_pending_new(o, 0);
-
- tcore_pending_set_request_data(pending, 0, atreq);
- tcore_pending_set_priority(pending, TCORE_PENDING_PRIORITY_DEFAULT);
- tcore_pending_set_response_callback(pending, on_response_set_xrat, NULL);
- tcore_pending_link_user_request(pending, ur);
- tcore_pending_set_send_callback(pending, on_confirmation_network_message_send, NULL);
-
- tcore_hal_send_request(h, pending);
- g_free(cmd_str);
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn get_band(CoreObject *o, UserRequest *ur)
-{
- TcoreHal *h = NULL;
- TcorePending *pending = NULL;
- TcoreATRequest *atreq;
- char *cmd_str = NULL;
- dbg("get_band - ENTER!!");
-
- if (!o || !ur)
- return TCORE_RETURN_EINVAL;
-
- h = tcore_object_get_hal(o);
- if(FALSE == tcore_hal_get_power_state(h)){
- dbg("cp not ready/n");
- return TCORE_RETURN_ENOSYS;
- }
-
- /* Get RAT Information Information. Based on RAT read response, we will get specific RAT bands only */
- cmd_str = g_strdup_printf("AT+XRAT?");
- atreq = tcore_at_request_new(cmd_str, "+XRAT", TCORE_AT_SINGLELINE);
- pending = tcore_pending_new(o, 0);
- tcore_pending_set_request_data(pending, 0, atreq);
- tcore_pending_set_response_callback(pending, on_response_get_xrat, NULL);
- tcore_pending_link_user_request(pending, ur);
- tcore_pending_set_send_callback(pending, on_confirmation_network_message_send, NULL);
- tcore_hal_send_request(h, pending);
-
- g_free(cmd_str);
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn set_preferred_plmn(CoreObject *o, UserRequest *ur)
-{
- TcoreHal *h = NULL;
- TcorePlugin *p = NULL;
- TcorePending *pending = NULL;
- TcoreATRequest *atreq = NULL;
- struct treq_network_set_preferred_plmn *req_data = NULL;
- char *cmd_str = NULL;
- int format = 2; /* Alway use numeric format, as application gives data in this default format */
- int gsm_act = 0;
- int gsm_compact_act = 0;
- int utran_act = 0;
-
- if (!o || !ur)
- return TCORE_RETURN_EINVAL;
-
- p = tcore_object_ref_plugin(o);
- h = tcore_object_get_hal(o);
- if(FALSE == tcore_hal_get_power_state(h)){
- dbg("cp not ready/n");
- return TCORE_RETURN_ENOSYS;
- }
-
- req_data = (struct treq_network_set_preferred_plmn *) tcore_user_request_ref_data(ur, NULL);
- pending = tcore_pending_new(o, 0);
-
- dbg("Entry set_preferred_plmn");
-/*
-AT+CPOL=
-[<index>][,<format>[,<oper>[,<GSM_AcT>,
-<GSM_Compact_AcT>,<UTRAN_AcT>]]]
- */
-
- if ((req_data->act == NETWORK_ACT_GSM) || (req_data->act == NETWORK_ACT_GPRS) || (req_data->act == NETWORK_ACT_EGPRS))
- gsm_act = TRUE;
- else if ((req_data->act == NETWORK_ACT_UMTS) || (req_data->act == NETWORK_ACT_UTRAN))
- utran_act = TRUE;
- else if (req_data->act == NETWORK_ACT_GSM_UTRAN)
- gsm_act = utran_act = TRUE;
-
- if (strlen(req_data->plmn) > 6) {
- req_data->plmn[6] = '\0';
- } else if (strlen(req_data->plmn) == 6) {
- if (req_data->plmn[5] == '#') {
- req_data->plmn[5] = '\0';
- }
- }
- cmd_str = g_strdup_printf("AT+CPOL=%d,%d,\"%s\",%d,%d,%d", req_data->index + 1, format, req_data->plmn, gsm_act, gsm_compact_act, utran_act);
-
- dbg("cmd_str - %s", cmd_str);
- atreq = tcore_at_request_new(cmd_str, "+CPOL", TCORE_AT_NO_RESULT);
-
- tcore_pending_set_request_data(pending, 0, atreq);
- tcore_pending_set_response_callback(pending, on_response_set_preferred_plmn, NULL);
- tcore_pending_link_user_request(pending, ur);
- tcore_pending_set_send_callback(pending, on_confirmation_network_message_send, NULL);
-
- tcore_hal_send_request(h, pending);
-
- g_free(cmd_str);
-
- dbg("Exit set_preferred_plmn");
-
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn get_preferred_plmn(CoreObject *o, UserRequest *ur)
-{
- TcoreHal *h = NULL;
- TcorePending *pending = NULL;
- TcoreATRequest *atreq = NULL;
-
- char *cmd_str = NULL;
-
- dbg("get_preferred_plmn - ENTER!!");
-
- if (!o || !ur)
- return TCORE_RETURN_EINVAL;
-
- h = tcore_object_get_hal(o);
- if(FALSE == tcore_hal_get_power_state(h)){
- dbg("cp not ready/n");
- return TCORE_RETURN_ENOSYS;
- }
-
- pending = tcore_pending_new(o, 0);
-
- cmd_str = g_strdup_printf("AT+CPOL=,2;+CPOL?");
- atreq = tcore_at_request_new(cmd_str, "+CPOL", TCORE_AT_MULTILINE);
-
- tcore_pending_set_request_data(pending, 0, atreq);
- tcore_pending_set_response_callback(pending, on_response_get_preferred_plmn, NULL);
- tcore_pending_link_user_request(pending, ur);
- tcore_pending_set_send_callback(pending, on_confirmation_network_message_send, NULL);
-
- tcore_hal_send_request(h, pending);
-
- g_free(cmd_str);
-
- dbg("get_preferred_plmn - EXIT!!");
-
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn get_serving_network(CoreObject *o, UserRequest *ur)
-{
- dbg("get_serving_network - ENTER!!");
-
- if (!o)
- return TCORE_RETURN_EINVAL;
-
- if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
- dbg("cp not ready/n");
- return TCORE_RETURN_ENOSYS;
- }
-
- dbg("new pending(AT+COPS?)");
-
- nwk_prepare_and_send_pending_request(o, "AT+COPS=3,2;+COPS?;+COPS=3,0;+COPS?", "+COPS", TCORE_AT_MULTILINE, ur, on_response_get_serving_network);
- 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 = NULL,
- .get_service_domain = NULL,
- .set_band = set_band,
- .get_band = get_band,
- .set_preferred_plmn = set_preferred_plmn,
- .get_preferred_plmn = get_preferred_plmn,
- .set_order = NULL,
- .get_order = NULL,
- .set_power_on_attach = NULL,
- .get_power_on_attach = NULL,
- .set_cancel_manual_search = NULL,
- .get_serving_network = get_serving_network,
-};
-
-gboolean s_network_init(TcorePlugin *cp, CoreObject *co_network)
-{
- dbg("Enter");
-
- tcore_network_override_ops(co_network, &network_ops);
-
- tcore_object_override_callback(co_network, "+CREG", on_event_cs_network_regist, NULL);
- tcore_object_override_callback(co_network, "+CGREG", on_event_ps_network_regist, NULL);
- tcore_object_override_callback(co_network, "+XCIEV", on_event_network_icon_info, NULL);
-
- /* +CTZV: <tz>,<time> */
- tcore_object_override_callback(co_network, "+CTZV", on_event_network_ctzv_time_info, NULL);
-
- tcore_server_add_notification_hook(tcore_plugin_ref_server(cp), TNOTI_SIM_STATUS, on_hook_sim_init, co_network);
-
- _insert_mcc_mnc_oper_list(cp, co_network);
-
- dbg("Exit");
-
- return TRUE;
-}
-
-void s_network_exit(TcorePlugin *cp, CoreObject *co_network)
-{
- dbg("Exit");
-}
+++ /dev/null
-/**
- * tel-plugin-imc
- *
- * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Contact: Ankit Jogi <ankit.jogi@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_phonebook.h>
-#include <co_sim.h>
-#include <user_request.h>
-#include <server.h>
-#include <at.h>
-
-#include "s_common.h"
-#include "s_phonebook.h"
-
-/* Constants */
-#define VAL_ZERO 0
-#define VAL_ONE 1
-#define VAL_TWO 2
-#define VAL_THREE 3
-#define VAL_FOUR 4
-#define VAL_FIVE 5
-#define VAL_SIX 6
-#define VAL_SEVEN 7
-#define VAL_NINE 9
-
-/* Type Of Number and Number Plan */
-#define TON_INTERNATIONAL 145
-#define TON_UNKNOWN 129
-#define NUM_PLAN_INTERNATIONAL 0x0070
-#define NUM_PLAN_UNKNOWN 0x0060
-
-struct valid_pb_index{
- int used_count;
- int total_count;
- int indexlist_populated;
- int *indexlist;
- int current_index;
-};
-static struct valid_pb_index __pbindex;
-
-enum pb_usim_file_type {
- PB_USIM_NAME = 0x01, /**< Name */
- PB_USIM_NUMBER, /**< Number */
- PB_USIM_ANR, /**< Another number */
- PB_USIM_EMAIL, /**< Email */
- PB_USIM_SNE, /**< Second name entry */
- PB_USIM_GRP, /**< Group file */
- PB_USIM_PBC, /** <1 byte control info and 1 byte hidden info*/
- PB_USIM_ANRA, /**< Another number a*/
- PB_USIM_ANRB, /**< Another number b*/
- PB_USIM_ANRC, /**< Another number c*/
- PB_USIM_EMAILA, /**< email a*/
- PB_USIM_EMAILB, /**< email b*/
- PB_USIM_EMAILC, /**< email c*/
-};
-
-static TReturn _get_support_list(CoreObject *o);
-static TReturn s_get_count(CoreObject *o, UserRequest *ur);
-static TReturn s_get_info(CoreObject *o, UserRequest *ur);
-static TReturn s_get_usim_info(CoreObject *o, UserRequest *ur);
-static TReturn s_read_record(CoreObject *o, UserRequest *ur);
-static TReturn s_update_record(CoreObject *o, UserRequest *ur);
-static TReturn s_delete_record(CoreObject *o, UserRequest *ur);
-
-
-static void pbindex_reset()
-{
- if(__pbindex.indexlist){
- free(__pbindex.indexlist);
- }
- memset(&__pbindex, 0x00, sizeof(struct valid_pb_index));
-}
-
-static enum tcore_response_command _find_resp_command(UserRequest *ur)
-{
- switch(tcore_user_request_get_command(ur))
- {
- case TREQ_PHONEBOOK_GETCOUNT:
- return TRESP_PHONEBOOK_GETCOUNT;
- case TREQ_PHONEBOOK_GETMETAINFO:
- return TRESP_PHONEBOOK_GETMETAINFO;
- case TREQ_PHONEBOOK_GETUSIMINFO:
- return TRESP_PHONEBOOK_GETUSIMINFO;
- case TREQ_PHONEBOOK_READRECORD:
- return TRESP_PHONEBOOK_READRECORD;
- case TREQ_PHONEBOOK_UPDATERECORD:
- return TRESP_PHONEBOOK_UPDATERECORD;
- case TREQ_PHONEBOOK_DELETERECORD:
- return TRESP_PHONEBOOK_DELETERECORD;
- default:
- return TRESP_UNKNOWN;
- }
-}
-
-static enum tel_phonebook_ton _find_num_plan(int number_plan)
-{
- enum tel_phonebook_ton result;
- dbg("number_plan : 0x%04x", number_plan);
-
- if(number_plan & NUM_PLAN_INTERNATIONAL) {
- result = PB_TON_INTERNATIONAL;
- }
- else {
- result = PB_TON_UNKNOWN;
- }
- dbg("result : %d", result);
- return result;
-}
-
-static char* _get_phonebook_type(enum tel_phonebook_type pb_type)
-{
- dbg("pb_type = %d", pb_type);
-
- switch(pb_type) {
- case PB_TYPE_FDN:
- return "FD";
- case PB_TYPE_ADN:
- case PB_TYPE_AAS:
- case PB_TYPE_GAS:
- return "SM";
- case PB_TYPE_SDN:
- return "SN";
- case PB_TYPE_USIM:
- return "AP";
- default:
- dbg("Invalid pb_type [%02x]", pb_type);
- return NULL;
- }
-}
-
-static enum tel_phonebook_type _get_phonebook_enum(const char* pb_type)
-{
- enum tel_phonebook_type phonebook_type = PB_TYPE_UNKNOWNN;
- dbg(" Function entry ");
- dbg("pb_type = %s", pb_type);
-
- if(strcmp("FD", pb_type) == VAL_ZERO) {
- phonebook_type = PB_TYPE_FDN;
- }
- else if(strcmp("SM", pb_type) == VAL_ZERO) {
- phonebook_type = PB_TYPE_ADN;
- }
- else if(strcmp("SN", pb_type) == VAL_ZERO) {
- phonebook_type = PB_TYPE_SDN;
- }
- else if(strcmp("AP", pb_type) == VAL_ZERO) {
- phonebook_type = PB_TYPE_USIM;
- }
-
- dbg(" Function exit");
- return phonebook_type;
-}
-
-static gboolean on_event_phonebook_status(CoreObject *o, const void *event_info, void *user_data)
-{
- dbg("Phonebook init received from modem");
-
- _get_support_list(o);
-
- return TRUE;
-}
-
-static void _on_response_select(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- const TcoreATResponse *resp = data;
- UserRequest *ur = NULL;
- enum tcore_request_command req_cmd = TREQ_UNKNOWN;
- int *selected_pb = user_data;
-
- dbg(" Function entry ");
-
- ur = tcore_pending_ref_user_request(p);
- if (!ur){
- dbg("error - current ur is NULL");
- return;
- }
-
- req_cmd = tcore_user_request_get_command(ur);
- dbg("origin treq command [%x]", req_cmd);
-
- if(resp->success > VAL_ZERO) {
- CoreObject *o = NULL;
- o = tcore_pending_ref_core_object(p);
-
- dbg("RESPONSE OK");
- tcore_phonebook_set_selected_type(o, *selected_pb);
- switch (req_cmd)
- {
- case TREQ_PHONEBOOK_GETCOUNT:
- s_get_count(o, ur);
- break;
- case TREQ_PHONEBOOK_GETMETAINFO:
- s_get_info(o, ur);
- break;
- case TREQ_PHONEBOOK_GETUSIMINFO:
- s_get_usim_info(o, ur);
- break;
- case TREQ_PHONEBOOK_READRECORD:
- s_read_record(o, ur);
- break;
- case TREQ_PHONEBOOK_UPDATERECORD:
- s_update_record(o, ur);
- break;
- case TREQ_PHONEBOOK_DELETERECORD:
- s_delete_record(o, ur);
- break;
- default:
- dbg("not handled treq cmd[%d]", req_cmd);
- break;
- }
- }
- else
- {
- dbg("RESPONSE NOK");
- switch (req_cmd)
- {
- case TREQ_PHONEBOOK_GETCOUNT:
- {
- struct tresp_phonebook_get_count resp_getcount;
- dbg("error TREQ_PHONEBOOK_GETCOUNT");
- memset(&resp_getcount, 0x00, sizeof(struct tresp_phonebook_get_count));
- resp_getcount.result = PB_FAIL;
- tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_phonebook_get_count), &resp_getcount);
- }
- break;
- case TREQ_PHONEBOOK_GETMETAINFO:
- {
- dbg("error TREQ_PHONEBOOK_GETMETAINFO");
- }
- break;
- case TREQ_PHONEBOOK_GETUSIMINFO:
- {
- dbg("error TREQ_PHONEBOOK_GETUSIMINFO");
- }
- break;
- case TREQ_PHONEBOOK_READRECORD:
- {
- struct tresp_phonebook_read_record resp_readrecord;
- dbg("error TREQ_PHONEBOOK_READRECORD");
- pbindex_reset();
- memset(&resp_readrecord, 0x00, sizeof(struct tresp_phonebook_read_record));
- resp_readrecord.result = PB_FAIL;
- resp_readrecord.phonebook_type = *selected_pb;
- tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_phonebook_read_record), &resp_readrecord);
- }
- break;
- case TREQ_PHONEBOOK_UPDATERECORD:
- {
- struct tresp_phonebook_update_record resp_updaterecord;
- dbg("error TREQ_PHONEBOOK_UPDATERECORD");
- memset(&resp_updaterecord, 0x00, sizeof(struct tresp_phonebook_update_record));
- resp_updaterecord.result = PB_FAIL;
- tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_phonebook_update_record), &resp_updaterecord);
- }
- break;
- case TREQ_PHONEBOOK_DELETERECORD:
- {
- struct tresp_phonebook_delete_record resp_deleterecord;
- dbg("error TREQ_PHONEBOOK_DELETERECORD");
- memset(&resp_deleterecord, 0x00, sizeof(struct tresp_phonebook_delete_record));
- resp_deleterecord.result = PB_FAIL;
- tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_phonebook_delete_record), &resp_deleterecord);
- }
- break;
- default:
- dbg("not handled treq cmd[%d]", req_cmd);
- break;
- }
-
- }
-
- free(selected_pb);
- selected_pb = NULL;
- dbg(" Function exit");
-}
-
-static void _on_response_getindexlist(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- const TcoreATResponse *resp = data;
- UserRequest *ur = NULL;
- struct tresp_phonebook_read_record resp_readrecord;
- int *selected_pb = user_data;
- int total_lines = 0;
- int count = 0;
- GSList *tokens=NULL;
- const char *line;
-
- dbg(" Function entry ");
-
- ur = tcore_pending_ref_user_request(p);
- if (!ur){
- dbg("error - current ur is NULL");
- return;
- }
- memset(&resp_readrecord, 0x00, sizeof(struct tresp_phonebook_read_record));
- resp_readrecord.result = PB_FAIL;
- resp_readrecord.phonebook_type = *selected_pb;
-
- if(resp->success > 0)
- {
- CoreObject *o = NULL;
- o = tcore_pending_ref_core_object(p);
-
- dbg("RESPONSE OK");
- tcore_phonebook_set_selected_type(o, *selected_pb);
- if (resp->lines) {
- total_lines = g_slist_length(resp->lines);
- dbg("Total number of PB entry %d\n", total_lines);
- if (total_lines < 1) {
- msg("invalid message");
- pbindex_reset();
- goto EXIT;
- }
- __pbindex.indexlist = (int*)malloc(__pbindex.used_count * sizeof(int));
- if(__pbindex.indexlist == NULL){
- dbg("Failed to allocate memory");
- pbindex_reset();
- goto EXIT;
- }
- resp_readrecord.result = PB_SUCCESS;
- for (count = 0; count < total_lines; count++) {
- /* Take each line response at a time & parse it */
- line = tcore_at_tok_nth(resp->lines, count);
- tokens = tcore_at_tok_new(line);
- __pbindex.indexlist[count] = atoi(g_slist_nth_data(tokens, 0));
- dbg("__pbindex.indexlist[%d] = %d", count, __pbindex.indexlist[count]);
- tcore_at_tok_free(tokens);
- }
- }
- __pbindex.indexlist_populated = 1;
- s_read_record(o, ur);
- free(selected_pb);
- selected_pb = NULL;
- return;
- }
- else{
- dbg("RESPONSE NOK");
- }
-EXIT:
- tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_phonebook_read_record), &resp_readrecord);
-
- free(selected_pb);
- selected_pb = NULL;
- dbg(" Function exit");
-}
-
-static void on_response_get_count(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- const TcoreATResponse *resp = data;
- UserRequest *ur = NULL;
- GSList *tokens=NULL;
- const char *temp = NULL;
- struct tresp_phonebook_get_count res;
- char *pbtype = NULL;
- dbg(" Function entry ");
-
- ur = tcore_pending_ref_user_request(p);
- if (!ur){
- dbg("error - current ur is NULL");
- return;
- }
-
- memset(&res, 0x00, sizeof(struct tresp_phonebook_get_count));
- res.result = PB_FAIL;
-
- if(resp->success > VAL_ZERO) {
- dbg("RESPONSE OK");
- if(resp->lines) {
- temp = (const char*)resp->lines->data;
- tokens = tcore_at_tok_new(temp);
- if (g_slist_length(tokens) < VAL_THREE) {
- //No of tokens must be three. We cannot proceed without used and total count.
- msg("invalid message");
- goto EXIT;
- }
- }
- res.result = PB_SUCCESS;
-
- temp = (const char*)g_slist_nth_data(tokens, VAL_ZERO);
- pbtype = util_removeQuotes((void*)temp);
- res.type = _get_phonebook_enum(pbtype);
-
- if(NULL != g_slist_nth_data(tokens, VAL_ONE)){
- res.used_count = atoi(g_slist_nth_data(tokens, VAL_ONE));
- __pbindex.used_count = res.used_count;
- dbg("used_count %d", __pbindex.used_count);
- }
-
- if(NULL != g_slist_nth_data(tokens, VAL_TWO)){
- res.total_count = atoi(g_slist_nth_data(tokens, VAL_TWO));
- __pbindex.total_count = res.total_count;
- }
- dbg("used count = %d, total count= %d", res.used_count, res.total_count);
- g_free(pbtype);
- pbtype = NULL;
- }
- else{
- dbg("RESPONSE NOK");
- }
-EXIT:
- tcore_at_tok_free(tokens);
- tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_phonebook_get_count), &res);
- dbg(" Function exit");
-}
-
-static void on_response_get_info(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- struct tresp_phonebook_get_info res = {0,};
- const TcoreATResponse *resp = data;
- UserRequest *ur = NULL;
- GSList *tokens=NULL;
- const char *line;
- int *selected_pb = (int*)user_data;
-
- dbg(" Function entry ");
-
- ur = tcore_pending_ref_user_request(p);
- if (!ur){
- dbg("error - current ur is NULL");
- return;
- }
-
- memset(&res, 0x00, sizeof(struct tresp_phonebook_get_info));
- res.result = PB_FAIL;
- res.type = *selected_pb;
-
- if(resp->success > VAL_ZERO) {
- dbg("RESPONSE OK");
- if(resp->lines) {
- line = (const char*)resp->lines->data;
- tokens = tcore_at_tok_new(line);
- if (g_slist_length(tokens) < VAL_ONE) {
- msg("invalid message");
- goto EXIT;
- }
- }
- res.result = PB_SUCCESS;
-
- res.number_length_max = atoi(g_slist_nth_data(tokens, VAL_ZERO));
- res.text_length_max = atoi(g_slist_nth_data(tokens, VAL_ONE));
- dbg("number_length_max %d text_length_max %d",res.number_length_max,res.text_length_max);
- }
- else{
- dbg("RESPONSE NOK");
- }
-EXIT:
- tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_phonebook_get_info), &res);
- free(selected_pb);
- selected_pb = NULL;
- tcore_at_tok_free(tokens);
- dbg(" Function exit");
-
-}
-
-static void on_response_read_record(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- const TcoreATResponse *resp = data;
- UserRequest *ur = NULL;
- GSList *tokens=NULL;
- const char *line;
- struct tresp_phonebook_read_record res;
- int num_len = VAL_ZERO;
- int name_len = VAL_ZERO;
- int num_plan = VAL_ZERO;
- char *member = NULL;
- char *temp = NULL;
- int *selected_pb = (int*)user_data;
-
- dbg(" Function entry ");
-
- ur = tcore_pending_ref_user_request(p);
- if (!ur){
- dbg("error - current ur is NULL");
- return;
- }
-
- memset(&res, 0x00, sizeof(struct tresp_phonebook_read_record));
- res.result = PB_FAIL;
- res.phonebook_type = *selected_pb;
-
- if(resp->success > VAL_ZERO) {
- dbg("RESPONSE OK");
- if(resp->lines) {
- line = (const char*)resp->lines->data;
- tokens = tcore_at_tok_new(line);
- if (g_slist_length(tokens) < VAL_ONE) {
- msg("invalid message");
- pbindex_reset();
- goto EXIT;
- }
- }
- res.result = PB_SUCCESS;
- res.index = atoi(g_slist_nth_data(tokens, 0));
- __pbindex.current_index++;
- if(__pbindex.current_index >= __pbindex.used_count){
- dbg("RESET");
- res.next_index = 0;
- pbindex_reset();
- }else{
- dbg("__pbindex.current_index %d", __pbindex.current_index);
- res.next_index = __pbindex.indexlist[__pbindex.current_index];
- }
- num_plan = atoi(g_slist_nth_data(tokens, 2));
- res.ton = _find_num_plan(num_plan);
-
- /*Remove the quotes("") from the number string*/
- temp = g_slist_nth_data(tokens, 1);
- member = util_removeQuotes((void*)temp);
- memcpy(res.number, member, strlen(member));
- dbg("number %s - %d", res.number, strlen((const char*)res.number));
- g_free(member);
- member = NULL;
-
- /*Remove the quotes("") from the name string*/
- temp = g_slist_nth_data(tokens, 3);
- member = util_removeQuotes((void*)temp);
- memcpy(res.name, member, strlen(member));
- dbg("name %s - %d", res.name, strlen((const char*)res.name));
- g_free(member);
- member = NULL;
- res.dcs = PB_TEXT_ASCII;
- res.name_len = strlen((const char*)res.name);
- if(NULL != g_slist_nth_data(tokens, VAL_FOUR)) {
- if(atoi(g_slist_nth_data(tokens, VAL_FOUR)) == VAL_ZERO) {
- dbg("phonebook entry not hidden");
- }
- else{
- dbg("phonebook entry hidden");
- }
- }
-
- if(NULL != g_slist_nth_data(tokens, VAL_SIX)){
- num_len = strlen(g_slist_nth_data(tokens, VAL_SIX));
- snprintf((char *)res.anr1, num_len+1, "%s", (char*)g_slist_nth_data(tokens, VAL_SIX));
- }
-
- if(NULL != g_slist_nth_data(tokens, VAL_SEVEN)){
- num_plan = atoi(g_slist_nth_data(tokens, VAL_SEVEN));
- res.anr1_ton = _find_num_plan(num_plan);
- }
-
- if(NULL != g_slist_nth_data(tokens, VAL_NINE)){
- name_len = strlen(g_slist_nth_data(tokens, VAL_NINE));
- memcpy(res.email1, g_slist_nth_data(tokens, VAL_NINE), name_len);
- }
- }
- else{
- dbg("RESPONSE NOK");
- pbindex_reset();
- }
-EXIT:
- tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_phonebook_read_record), &res);
- free(selected_pb);
- selected_pb = NULL;
- tcore_at_tok_free(tokens);
- dbg(" Function exit");
-
-}
-
-static void on_response_update_record(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- const TcoreATResponse *resp = data;
- UserRequest *ur = NULL;
- struct tresp_phonebook_update_record res;
- dbg(" Function entry ");
-
- if(resp->success > VAL_ZERO) {
- dbg("RESPONSE OK");
- res.result = PB_SUCCESS;
- }
- else{
- dbg("RESPONSE NOK");
- res.result = PB_FAIL;
- }
-
- ur = tcore_pending_ref_user_request(p);
- if (ur){
- tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_phonebook_update_record),
- &res);
- }
- else{
- dbg("error - current ur is NULL");
- }
- dbg(" Function exit");
-}
-
-static void on_response_delete_record(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- const TcoreATResponse *resp = data;
- UserRequest *ur = NULL;
- struct tresp_phonebook_delete_record res;
-
- dbg(" Function entry ");
-
- if(resp->success > VAL_ZERO) {
- dbg("RESPONSE OK");
- res.result = PB_SUCCESS;
- }
- else{
- dbg("RESPONSE NOK");
- res.result = PB_FAIL;
- }
-
- ur = tcore_pending_ref_user_request(p);
- if (ur){
- tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_phonebook_delete_record), &res);
- }
- else{
- dbg("error - current ur is NULL");
- }
- dbg(" Function exit");
-}
-
-static void _response_get_support_list(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- const TcoreATResponse *resp = data;
- CoreObject*o = NULL;
- GSList *tokens=NULL;
- const char *line;
- char *temp = NULL;
- char *pbtype = NULL;
- struct tnoti_phonebook_status noti_data = {0,};
-
- dbg(" Function entry ");
-
- o = tcore_pending_ref_core_object(p);
- if(!o){
- dbg("error - core object is null");
- return;
- }
-
- noti_data.b_init = FALSE;
-
- if(resp->success > VAL_ZERO) {
- dbg("RESPONSE OK");
- if(resp->lines) {
- line = (const char*)resp->lines->data;
- tokens = tcore_at_tok_new(line);
- if (g_slist_length(tokens) < VAL_ONE) {
- msg("invalid message");
- goto EXIT;
- }
- }
-
- temp = (char*)g_slist_nth_data(tokens, VAL_ZERO);
- pbtype = strtok(temp, "(,)");
- while(pbtype != NULL) {
- temp = util_removeQuotes((void*)pbtype);
- dbg("pbtype %s", temp);
- if (VAL_ZERO == strcmp(temp, "FD")) {
- dbg("SIM fixed-dialing phonebook");
- noti_data.support_list.b_fdn = VAL_ONE;
- }
- else if (VAL_ZERO == strcmp(temp, "SN")) {
- dbg("Service Dialing Number");
- noti_data.support_list.b_sdn = VAL_ONE;
- }
- else if (VAL_ZERO == strcmp(temp, "SM")) {
- dbg("2G SIM ADN phonebook");
- noti_data.support_list.b_adn = VAL_ONE;
- }
- else if (VAL_ZERO == strcmp(temp, "LD")) {
- dbg("SIM/UICC last-dialling-phonebook");
- }
- else if (VAL_ZERO == strcmp(temp, "ON")) {
- dbg("SIM (or MT) own numbers (MSISDNs) list");
- }
- else if (VAL_ZERO == strcmp(temp, "BL")) {
- dbg("Blacklist phonebook");
- }
- else if (VAL_ZERO == strcmp(temp, "EC")) {
- dbg("SIM emergency-call-codes phonebook");
- }
- else if (VAL_ZERO == strcmp(temp, "AP")) {
- dbg("Selected application phonebook");
- }
- else if (VAL_ZERO == strcmp(temp, "BN")) {
- dbg("SIM barred-dialling-number");
- }
- pbtype = strtok (NULL, "(,)");
- g_free(temp);
- }
-
- noti_data.b_init = TRUE;
- tcore_phonebook_set_support_list(o, ¬i_data.support_list);
- tcore_phonebook_set_status(o, noti_data.b_init);
- }
- else{
- dbg("RESPONSE NOK");
- tcore_phonebook_set_status(o, noti_data.b_init);
- }
-EXIT:
- tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_PHONEBOOK_STATUS,
- sizeof(struct tnoti_phonebook_status), ¬i_data);
- tcore_at_tok_free(tokens);
- dbg(" Function exit");
-}
-
-static TReturn _get_support_list(CoreObject *o)
-{
- TcoreHal *hal = NULL;
- TcoreATRequest *req = NULL;
- TcorePending *pending = NULL;
- char *cmd_str = NULL;
-
- dbg(" Function entry ");
-
- if (!o){
- return TCORE_RETURN_EINVAL;
- }
-
- hal = tcore_object_get_hal(o);
- pending = tcore_pending_new(o, VAL_ZERO);
-
- cmd_str = g_strdup_printf("AT+CPBS=?");
- req = tcore_at_request_new(cmd_str, "+CPBS:", TCORE_AT_SINGLELINE);
- dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
-
- tcore_pending_set_request_data(pending, VAL_ZERO, req);
- tcore_pending_set_response_callback(pending, _response_get_support_list, NULL);
-
- tcore_hal_send_request(hal, pending);
-
- g_free(cmd_str);
- dbg(" Function exit");
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn _select(CoreObject *o, UserRequest *ur, enum tel_phonebook_type pbt)
-{
- TcoreHal *hal = NULL;
- TcoreATRequest *req = NULL;
- TcorePending *pending = NULL;
- char *cmd_str = NULL;
- const struct treq_phonebook_get_count *req_data;
- int *pb_type = NULL;
- char *phonebook_type = NULL;
- UserRequest *ur_dup = NULL;
-
- dbg(" Function entry ");
-
- if (!o || !ur)
- return TCORE_RETURN_EINVAL;
-
- req_data = tcore_user_request_ref_data(ur, NULL);
- ur_dup = tcore_user_request_ref(ur);
-
- phonebook_type = (char*)_get_phonebook_type(req_data->phonebook_type);
- if(NULL == phonebook_type){
- err("phonebook_type is NULL");
- return TCORE_RETURN_FAILURE;
- }
-
- pb_type = calloc(sizeof(enum tel_phonebook_type),VAL_ONE);
- if(pb_type == NULL) {
- err("Failed to allocate memory");
- return TCORE_RETURN_FAILURE;
- }
- *pb_type = pbt;
-
- cmd_str = g_strdup_printf("AT+CPBS=\"%s\"", phonebook_type);
- req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
- dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
-
- hal = tcore_object_get_hal(o);
- pending = tcore_pending_new(o, VAL_ZERO);
- tcore_pending_set_request_data(pending, VAL_ZERO, req);
- tcore_pending_set_response_callback(pending, _on_response_select, (void*)pb_type);
- tcore_pending_link_user_request(pending, ur_dup);
-
- tcore_hal_send_request(hal, pending);
-
- g_free(cmd_str);
- dbg(" Function exit");
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn _getindexlist(CoreObject *o, UserRequest *ur, enum tel_phonebook_type pbt)
-{
- TcoreHal *hal = NULL;
- TcoreATRequest *req = NULL;
- TcorePending *pending = NULL;
- char *cmd_str = NULL;
- const struct treq_phonebook_get_count *req_data;
- int start_index = 1;
- int *pb_type = NULL;
- UserRequest *ur_dup = NULL;
-
- dbg(" Function entry ");
-
- if (!o || !ur)
- return TCORE_RETURN_EINVAL;
-
- pb_type = calloc(sizeof(enum tel_phonebook_type),1);
- if(pb_type == NULL) {
- err("Failed to allocate memory");
- return TCORE_RETURN_FAILURE;
- }
- *pb_type = pbt;
-
- req_data = tcore_user_request_ref_data(ur, NULL);
- ur_dup = tcore_user_request_ref(ur);
-
- cmd_str = g_strdup_printf("AT+CPBR=%d,%d", start_index, __pbindex.total_count);
- req = tcore_at_request_new(cmd_str, "+CPBR:", TCORE_AT_MULTILINE);
- dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
-
- hal = tcore_object_get_hal(o);
- pending = tcore_pending_new(o, 0);
-
- tcore_pending_set_request_data(pending, 0, req);
- tcore_pending_set_response_callback(pending, _on_response_getindexlist, (void*)pb_type);
- tcore_pending_link_user_request(pending, ur_dup);
- tcore_hal_send_request(hal, pending);
-
- free(cmd_str);
- dbg(" Function exit");
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn s_get_count(CoreObject *o, UserRequest *ur)
-{
- TcoreHal *hal = NULL;
- TcoreATRequest *req = NULL;
- TcorePending *pending = NULL;
- char *cmd_str = NULL;
- const struct treq_phonebook_get_count *req_data = NULL;
- enum tel_phonebook_type pbt = PB_TYPE_UNKNOWNN;
-
- dbg("Function Entry");
- if (!o || !ur)
- return TCORE_RETURN_EINVAL;
-
- req_data = tcore_user_request_ref_data(ur, NULL);
- pbt = tcore_phonebook_get_selected_type(o);
- if (req_data->phonebook_type != pbt) {
- dbg("req pb[%d] is different with tcore pb[%d]", req_data->phonebook_type, pbt);
- return _select(o, ur, req_data->phonebook_type);
- }
-
- cmd_str = g_strdup_printf("AT+CPBS?");
- req = tcore_at_request_new(cmd_str, "+CPBS:", TCORE_AT_SINGLELINE);
- dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
-
- hal = tcore_object_get_hal(o);
- pending = tcore_pending_new(o, VAL_ZERO);
-
- tcore_pending_set_request_data(pending, VAL_ZERO, req);
- tcore_pending_set_response_callback(pending, on_response_get_count, hal);
- tcore_pending_link_user_request(pending, ur);
-
- tcore_hal_send_request(hal, pending);
-
- g_free(cmd_str);
- dbg("Function exit");
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn s_get_info(CoreObject *o, UserRequest *ur)
-{
- TcoreHal *hal = NULL;
- TcoreATRequest *req = NULL;
- TcorePending *pending = NULL;
- char *cmd_str = NULL;
- const struct treq_phonebook_get_info *req_data = NULL;
- enum tel_phonebook_type pbt = PB_TYPE_UNKNOWNN;
- int *pb_type = NULL;
-
- dbg(" Function entry ");
-
- if (!o || !ur)
- return TCORE_RETURN_EINVAL;
-
- req_data = tcore_user_request_ref_data(ur, NULL);
- pbt = tcore_phonebook_get_selected_type(o);
- if (req_data->phonebook_type != pbt) {
- dbg("req pb[%d] is different with tcore pb[%d]", req_data->phonebook_type, pbt);
- return _select(o, ur, req_data->phonebook_type);
- }
-
- pb_type = calloc(sizeof(enum tel_phonebook_type),VAL_ONE);
- if(pb_type == NULL) {
- err("Failed to allocate memory");
- return TCORE_RETURN_FAILURE;
- }
- *pb_type = pbt;
- dbg("pb_type %d", *pb_type);
-
- cmd_str = g_strdup_printf("AT+CPBF=?");
- req = tcore_at_request_new(cmd_str, "+CPBF:", TCORE_AT_SINGLELINE);
- dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
-
- hal = tcore_object_get_hal(o);
- pending = tcore_pending_new(o, VAL_ZERO);
-
- tcore_pending_set_request_data(pending, VAL_ZERO, req);
- tcore_pending_set_response_callback(pending, on_response_get_info, (void*)pb_type);
- tcore_pending_link_user_request(pending, ur);
-
- tcore_hal_send_request(hal, pending);
-
- g_free(cmd_str);
- dbg(" Function exit");
- return TCORE_RETURN_SUCCESS;
-
-}
-
-static TReturn s_get_usim_info(CoreObject *o, UserRequest *ur)
-{
- dbg("NOT IMPLEMENTED");
-
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn s_read_record(CoreObject *o, UserRequest *ur)
-{
- TcoreHal*hal = NULL;
- TcoreATRequest *req = NULL;
- TcorePending *pending = NULL;
- char *cmd_str = NULL;
- const struct treq_phonebook_read_record *req_data = NULL;
- enum tel_phonebook_type pbt = PB_TYPE_UNKNOWNN;
- int *pb_type = NULL;
-
- dbg(" Function entry ");
-
- if (!o || !ur)
- return TCORE_RETURN_EINVAL;
-
- req_data = tcore_user_request_ref_data(ur, NULL);
- pbt = tcore_phonebook_get_selected_type(o);
- if (req_data->phonebook_type != pbt) {
- dbg("req pb[%d] is different with tcore pb[%d]", req_data->phonebook_type, pbt);
- return _select(o, ur, req_data->phonebook_type);
- }
- if(!__pbindex.indexlist_populated){
- return _getindexlist(o, ur, req_data->phonebook_type);
- }
- pb_type = calloc(sizeof(enum tel_phonebook_type),VAL_ONE);
- if(pb_type == NULL) {
- err("Failed to allocate memory");
- return TCORE_RETURN_FAILURE;
- }
- *pb_type = pbt;
- dbg("pb_type %d", *pb_type);
- cmd_str = g_strdup_printf("AT+CPBR=%d", __pbindex.indexlist[__pbindex.current_index]);
- req = tcore_at_request_new(cmd_str, "+CPBR", TCORE_AT_MULTILINE);
- dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
-
- hal = tcore_object_get_hal(o);
- pending = tcore_pending_new(o, VAL_ZERO);
-
- tcore_pending_set_request_data(pending, VAL_ZERO, req);
- tcore_pending_set_response_callback(pending, on_response_read_record, (void*)pb_type);
- tcore_pending_link_user_request(pending, ur);
-
- tcore_hal_send_request(hal, pending);
-
- g_free(cmd_str);
- dbg(" Function exit");
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn s_update_record(CoreObject *o, UserRequest *ur)
-{
- TcoreHal *hal = NULL;
- TcoreATRequest *req = NULL;
- TcorePending *pending = NULL;
- char *cmd_str = NULL;
- const struct treq_phonebook_update_record *req_data = NULL;
- enum tel_phonebook_type pbt = PB_TYPE_UNKNOWNN;
-
- dbg(" Function entry ");
-
- if (!o || !ur)
- return TCORE_RETURN_EINVAL;
-
- req_data = tcore_user_request_ref_data(ur, NULL);
- pbt = tcore_phonebook_get_selected_type(o);
- if (req_data->phonebook_type != pbt) {
- dbg("req pb[%d] is different with tcore pb[%d]", req_data->phonebook_type, pbt);
- return _select(o, ur, req_data->phonebook_type);
- }
-
- cmd_str = g_strdup_printf("AT+CPBW=,\"%s\",%d,\"%s\"", req_data->number, ((PB_TON_INTERNATIONAL == req_data->ton) ? TON_INTERNATIONAL: TON_UNKNOWN), req_data->name);
- req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_SINGLELINE);
- dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
-
- hal = tcore_object_get_hal(o);
- pending = tcore_pending_new(o, VAL_ZERO);
-
- tcore_pending_set_request_data(pending, VAL_ZERO, req);
- tcore_pending_set_response_callback(pending, on_response_update_record, hal);
- tcore_pending_link_user_request(pending, ur);
-
- tcore_hal_send_request(hal, pending);
-
- g_free(cmd_str);
- dbg(" Function exit");
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn s_delete_record(CoreObject *o, UserRequest *ur)
-{
- TcoreHal *hal = NULL;
- TcoreATRequest *req = NULL;
- TcorePending *pending = NULL;
- char *cmd_str = NULL;
- const struct treq_phonebook_delete_record *req_data;
- enum tel_phonebook_type pbt = PB_TYPE_UNKNOWNN;
-
- dbg(" Function entry ");
-
- if (!o || !ur)
- return TCORE_RETURN_EINVAL;
-
- req_data = tcore_user_request_ref_data(ur, NULL);
- pbt = tcore_phonebook_get_selected_type(o);
- if (req_data->phonebook_type != pbt) {
- dbg("req pb[%d] is different with tcore pb[%d]", req_data->phonebook_type, pbt);
- return _select(o, ur, req_data->phonebook_type);
- }
-
- cmd_str = g_strdup_printf("AT+CPBW=%d", req_data->index);
- req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_SINGLELINE);
- dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
-
- hal = tcore_object_get_hal(o);
- pending = tcore_pending_new(o, VAL_ZERO);
-
- tcore_pending_set_request_data(pending, VAL_ZERO, req);
- tcore_pending_set_response_callback(pending, on_response_delete_record, hal);
- tcore_pending_link_user_request(pending, ur);
-
- tcore_hal_send_request(hal, pending);
-
- g_free(cmd_str);
- dbg(" Function exit");
- return TCORE_RETURN_SUCCESS;
-}
-
-static struct tcore_phonebook_operations phonebook_ops = {
- .get_count = s_get_count,
- .get_info = s_get_info,
- .get_usim_info = s_get_usim_info,
- .read_record = s_read_record,
- .update_record = s_update_record,
- .delete_record = s_delete_record,
-};
-
-gboolean s_phonebook_init(TcorePlugin *cp, CoreObject *co_phonebook)
-{
- dbg("Entry");
-
- tcore_phonebook_override_ops(co_phonebook, &phonebook_ops);
-
- tcore_object_override_callback(co_phonebook, "+PBREADY", on_event_phonebook_status, NULL);
-
- dbg("Exit");
-
- return TRUE;
-}
-
-void s_phonebook_exit(TcorePlugin *cp, CoreObject *co_phonebook)
-{
- dbg("Exit");
-}
+++ /dev/null
-/*
- * tel-plugin-imc
- *
- * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: Arun Shukla <arun.shukla@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 <fcntl.h>
-#include <sys/ioctl.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 <storage.h>
-#include <server.h>
-#include <at.h>
-#include <util.h>
-#include <type/ps.h>
-
-#include "s_common.h"
-#include "s_ps.h"
-
-/*Invalid Session ID*/
-#define PS_INVALID_CID 999 /*Need to check */
-
-/*Maximum String length Of the Command*/
-#define MAX_AT_CMD_STR_LEN 150
-
-/*Command for PDP activation and Deactivation*/
-#define AT_PDP_ACTIVATE 1
-#define AT_PDP_DEACTIVATE 0
-
-#define AT_XDNS_ENABLE 1
-#define AT_XDNS_DISABLE 0
-#define AT_SESSION_DOWN 0
-
-static void _unable_to_get_pending(CoreObject *co_ps, CoreObject *ps_context)
-{
- struct tnoti_ps_call_status data_resp = {0};
- dbg("Entry");
-
- data_resp.context_id = tcore_context_get_id(ps_context);
- data_resp.state = PS_DATA_CALL_NOT_CONNECTED;
- dbg("Sending Call Status Notification - Context ID: [%d] Context State: [NOT CONNECTED]",
- data_resp.context_id);
-
- /* Send CALL Status Notification */
- tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(co_ps)),
- co_ps, TNOTI_PS_CALL_STATUS, sizeof(data_resp), &data_resp);
-
- /* Set PS State to Deactivated */
- (void) tcore_context_set_state(ps_context, CONTEXT_STATE_DEACTIVATED);
- dbg("Exit");
-}
-
-static gboolean on_event_dun_call_notification(CoreObject *o, const void *data, void *user_data)
-{
- GSList *tokens = NULL;
- const char *line = NULL;
- int value = 0;
- GSList *lines = NULL;
- dbg("Entry");
-
- lines = (GSList *) data;
- if (g_slist_length(lines) != 1) {
- dbg("Unsolicited message BUT multiple lines");
- goto OUT;
- }
-
- line = (char *) (lines->data);
- tokens = tcore_at_tok_new(line);
- value = atoi(g_slist_nth_data(tokens, 0));
-
- /*
- * <status> may be
- * 0: DUN Activation in progress
- * 1: DUN Deactivation in progress
- * 2: DUN Activated
- * 3: DUN Deactivated
- */
- switch (value) {
- case 0: /* FALL THROUGH */
- case 1:
- {
- break;
- }
-
- case 2:
- {
- /* TODO:- Fill Data structure: 'data' */
- tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o,
- TNOTI_PS_EXTERNAL_CALL, sizeof(struct tnoti_ps_external_call), &data);
- }
-
- case 3:
- {
- /* TODO:- Fill Data structure: 'data' */
- tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o,
- TNOTI_PS_EXTERNAL_CALL, sizeof(struct tnoti_ps_external_call), &data);
- }
- break;
-
- default:
- break;
- }
-
-OUT:
- /* Free tokens */
- tcore_at_tok_free(tokens);
-
- return TRUE;
-}
-static void on_response_undefine_context_cmd(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- CoreObject *co_ps = NULL;
- const TcoreATResponse *resp = data;
- CoreObject *ps_context = user_data;
- dbg("Entry");
-
- co_ps = tcore_pending_ref_core_object(p);
- if (resp->success) {
- dbg("Response Ok");
- goto exit;
- }
- dbg("Response NOk");
-
-exit:
- _unable_to_get_pending(co_ps, ps_context);
- return;
-}
-
-static void send_undefine_context_cmd(CoreObject *co_ps, CoreObject *ps_context)
-{
- TcoreHal *hal = NULL;
- TcorePending *pending = NULL;
- char cmd_str[MAX_AT_CMD_STR_LEN];
- int cid = 0;
-
- dbg("Entry");
- memset(cmd_str, 0x0, MAX_AT_CMD_STR_LEN);
-
- /* FIXME: Before MUX setup, use PHY HAL directly. */
- hal = tcore_object_get_hal(co_ps);
-
- /*Getting Context ID from Core Object*/
- cid = tcore_context_get_id(ps_context);
-
- (void) sprintf(cmd_str, "AT+CGDCONT=%d", cid);
- dbg("Command: [%s] Command Length: [%d]", cmd_str, strlen(cmd_str));
-
- pending = tcore_at_pending_new(co_ps, cmd_str, NULL, TCORE_AT_NO_RESULT,
- on_response_undefine_context_cmd, ps_context);
- if (NULL == pending) {
- err("Unable to get the create a AT request ");
- goto error;
- }
- tcore_hal_send_request(hal, pending);
- dbg("Exit: Successfully");
- return;
-error:
- {
- dbg("Exit: With error");
- _unable_to_get_pending(co_ps, ps_context);
- return;
- }
-}
-
-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_response_get_dns_cmnd(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- GSList *tokens = NULL;
- GSList *pRespData;
- const char *line = NULL;
- char *dns_prim = NULL;
- char *dns_sec = NULL;
- char *token_dns = NULL;
- int no_pdp_active = 0;
- CoreObject *ps_context = user_data;
- const TcoreATResponse *resp = data;
- CoreObject *co_ps = tcore_pending_ref_core_object(p);
- int cid = tcore_context_get_id(ps_context);
- TcoreHal *h = tcore_object_get_hal(co_ps);
-
- dbg("Entry");
-
- if (resp->final_response) {
- dbg("Response OK");
- if (resp->lines) {
- dbg("DNS data present in the Response");
- pRespData = (GSList *) resp->lines;
- no_pdp_active = g_slist_length(pRespData);
- dbg("Total Number of Active PS Context: [%d]", no_pdp_active);
- if (0 == no_pdp_active) {
- goto exit_fail;
- }
-
- while (pRespData) {
- line = (const char *) pRespData->data;
- dbg("Received Data: [%s]", line);
- tokens = tcore_at_tok_new(line);
-
- /* Check if Context ID is matching */
- if (cid == atoi(g_slist_nth_data(tokens, 0))) {
- dbg("Found the DNS details for the Current Context - Context ID: [%d]", cid);
- break;
- }
-
- /* Free tokens */
- tcore_at_tok_free(tokens);
- tokens = NULL;
-
- /* Move to next line */
- pRespData = pRespData->next;
- }
-
- /* Read primary DNS */
- {
- token_dns = g_slist_nth_data(tokens, 1);
-
- /* Strip off starting " and ending " from this token to read actual PDP address */
- dns_prim = util_removeQuotes((void *)token_dns);
- dbg("Primary DNS: [%s]", dns_prim);
- }
-
- /* Read Secondary DNS */
- {
- token_dns = g_slist_nth_data(tokens, 2);
-
- /* Strip off starting " and ending " from this token to read actual PDP address */
- dns_sec = util_removeQuotes((void *)token_dns);
- dbg("Secondary DNS: [%s]", dns_sec);
- }
-
- if ((g_strcmp0("0.0.0.0", dns_prim) == 0)
- && (g_strcmp0("0.0.0.0", dns_sec) == 0)) {
- dbg("Invalid DNS");
-
- g_free(dns_prim);
- g_free(dns_sec);
-
- tcore_at_tok_free(tokens);
- tokens = NULL;
-
- goto exit_fail;
- }
-
- /* Set DNS Address */
- tcore_context_set_ipv4_dns(ps_context, dns_prim, dns_sec);
- g_free(dns_prim);
- g_free(dns_sec);
-
- tcore_at_tok_free(tokens);
- tokens = NULL;
- goto exit_success;
- } else {
- dbg("No data present in the Response");
- }
- }
- dbg("Response NOK");
-
-exit_fail:
- dbg("Adding default DNS");
- tcore_context_set_ipv4_dns(ps_context, "8.8.8.8", "8.8.4.4");
-
-exit_success:
- /* Mount network interface */
- if (tcore_hal_setup_netif(h, co_ps, on_setup_pdp, ps_context, cid, TRUE)
- != TCORE_RETURN_SUCCESS) {
- err("Setup network interface failed");
- return;
- }
-
- dbg("EXIT : Without error");
-}
-
-static TReturn send_get_dns_cmd(CoreObject *co_ps, CoreObject *ps_context)
-{
- TcoreHal *hal = NULL;
- TcorePending *pending = NULL;
- char cmd_str[MAX_AT_CMD_STR_LEN];
-
- memset(cmd_str, 0x0, MAX_AT_CMD_STR_LEN);
-
- dbg("Entry");
- hal = tcore_object_get_hal(co_ps);
-
- (void) sprintf(cmd_str, "AT+XDNS?");
- dbg("Command: [%s] Command Length: [%d]", cmd_str, strlen(cmd_str));
-
- pending = tcore_at_pending_new(co_ps, cmd_str, "+XDNS", TCORE_AT_MULTILINE,
- on_response_get_dns_cmnd, ps_context);
- if (TCORE_RETURN_SUCCESS == tcore_hal_send_request(hal, pending)) {
- return TCORE_RETURN_SUCCESS;
- }
- _unable_to_get_pending(co_ps, ps_context);
- return TCORE_RETURN_FAILURE;
-}
-
-static void on_response_get_pdp_address(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- const TcoreATResponse *resp = data;
- CoreObject *co_ps = tcore_pending_ref_core_object(p);
- CoreObject *ps_context = user_data;
- GSList *tokens = NULL;
- const char *line;
- char *token_pdp_address;
- dbg("Enetered");
- if (resp->final_response) {
- dbg("RESPONSE OK");
- if (resp->lines != NULL) {
- line = (const char *) resp->lines->data;
- tokens = tcore_at_tok_new(line);
- if (g_slist_length(tokens) < 2) {
- msg("Invalid message");
- goto error;
- }
- dbg("Received Data: [%s]", line);
-
- /* CID is already stored in ps_context, skip over & read PDP address */
- token_pdp_address = g_slist_nth_data(tokens, 1);
- token_pdp_address = util_removeQuotes((void *)token_pdp_address);
- dbg("IP Address: [%s]", token_pdp_address);
-
- /* Strip off starting " and ending " from this token to read actual PDP address */
- /* Set IP Address */
- (void)tcore_context_set_ipv4_addr(ps_context, (const char *)token_pdp_address);
-
- g_free(token_pdp_address);
- }
-
- /* Get DNS Address */
- (void) send_get_dns_cmd(co_ps, ps_context);
- } else {
- dbg("Response NOK");
-
- /*without PDP address we will not be able to start packet service*/
- tcore_ps_deactivate_context(co_ps, ps_context, NULL);
- }
-error:
- tcore_at_tok_free(tokens);
- return;
-}
-
-static TReturn send_get_pdp_address_cmd(CoreObject *co_ps, CoreObject *ps_context)
-{
- TcoreHal *hal = NULL;
- TcorePending *pending = NULL;
- unsigned int cid = PS_INVALID_CID;
- char cmd_str[MAX_AT_CMD_STR_LEN] = {0};
-
- dbg("Entry");
- hal = tcore_object_get_hal(co_ps);
-
- cid = tcore_context_get_id(ps_context);
- (void) sprintf(cmd_str, "AT+CGPADDR=%d", cid);
- dbg("Command: [%s] Command Length: [%d]", cmd_str, strlen(cmd_str));
-
- pending = tcore_at_pending_new(co_ps, cmd_str, "+CGPADDR", TCORE_AT_SINGLELINE,
- on_response_get_pdp_address, ps_context);
- if (TCORE_RETURN_SUCCESS == tcore_hal_send_request(hal, pending)) {
- return TCORE_RETURN_SUCCESS;
- }
- _unable_to_get_pending(co_ps, ps_context);
- return TCORE_RETURN_FAILURE;
-}
-
-static void on_response_send_pdp_activate_cmd(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- CoreObject *co_ps = NULL;
- const TcoreATResponse *resp = data;
- CoreObject *ps_context = user_data;
-
- int cid;
- cid = tcore_context_get_id(ps_context);
-
-
- dbg("Entry");
- if (!p) {
- goto error;
- }
- co_ps = tcore_pending_ref_core_object(p);
-
- if (resp->success) {
- dbg("Response OK");
-
- /* Getting the IP address and DNS from the modem */
- dbg("Getting IP Address");
- (void) send_get_pdp_address_cmd(co_ps, ps_context);
- return;
- } else {
- dbg("Unable to activate PDP context - Context ID: [%d]", cid);
- dbg("Undefining PDP context");
- (void) tcore_context_set_state(ps_context, CONTEXT_STATE_DEACTIVATED);
- send_undefine_context_cmd(co_ps, ps_context);
- return;
- }
-error:
- {
- _unable_to_get_pending(co_ps, ps_context);
- return;
- }
-}
-
-static TReturn send_pdp_activate_cmd(CoreObject *co_ps, CoreObject *ps_context)
-{
- TcoreHal *hal = NULL;
- TcorePending *pending = NULL;
- char cmd_str[MAX_AT_CMD_STR_LEN] = {0};
- int cid = 0;
- dbg("Entry");
- /* FIXME: Before MUX setup, use PHY HAL directly. */
- hal = tcore_object_get_hal(co_ps);
-
- /*Getting Context ID from Core Object*/
- cid = tcore_context_get_id(ps_context);
- (void) sprintf(cmd_str, "AT+CGACT=%d,%d", AT_PDP_ACTIVATE, cid);
- dbg("Command: [%s] Command Length: [%d]", cmd_str, strlen(cmd_str));
-
- pending = tcore_at_pending_new(co_ps, cmd_str, NULL, TCORE_AT_NO_RESULT,
- on_response_send_pdp_activate_cmd, ps_context);
- if (TCORE_RETURN_SUCCESS == tcore_hal_send_request(hal, pending)) {
- return TCORE_RETURN_SUCCESS;
- }
- _unable_to_get_pending(co_ps, ps_context);
- return TCORE_RETURN_FAILURE;
-}
-
-static TReturn activate_ps_context(CoreObject *co_ps, CoreObject *ps_context, void *user_data)
-{
- dbg("Entry");
- return send_pdp_activate_cmd(co_ps, ps_context);
-}
-
-static void on_response_xdns_enable_cmd(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- TcoreATResponse *resp = (TcoreATResponse *) data;
- CoreObject *co_ps = tcore_pending_ref_core_object(p);
- CoreObject *ps_context = user_data;
- struct tnoti_ps_call_status noti = {0};
- int cid = -1;
-
- dbg("Entry");
-
- cid = tcore_context_get_id(ps_context);
-
- if (resp->success) {
- dbg("Response OK");
- dbg("DNS address getting is Enabled");
- noti.context_id = cid;
- noti.state = PS_DATA_CALL_CTX_DEFINED;
- } else {
- dbg("Response NOK");
- noti.context_id = cid;
- noti.state = PS_DATA_CALL_NOT_CONNECTED;
- /*If response to enable the DNS NOK then we will use google DNS for the PDP context*/
- }
-
- tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(co_ps)), co_ps,
- TNOTI_PS_CALL_STATUS, sizeof(struct tnoti_ps_call_status), ¬i);
- return;
-}
-
-static TReturn send_xdns_enable_cmd(CoreObject *co_ps, CoreObject *ps_context)
-{
- TcoreHal *hal = NULL;
- TcorePending *pending = NULL;
- int cid = -1;
- char cmd_str[MAX_AT_CMD_STR_LEN];
-
- dbg("Entry");
- memset(cmd_str, 0x0, MAX_AT_CMD_STR_LEN);
-
- hal = tcore_object_get_hal(co_ps);
- cid = tcore_context_get_id(ps_context);
-
- (void) sprintf(cmd_str, "AT+XDNS=%d,%d", cid, AT_XDNS_ENABLE);
- dbg("Command: [%s] Command Length: [%d]", cmd_str, strlen(cmd_str));
-
- pending = tcore_at_pending_new(co_ps, cmd_str, NULL, TCORE_AT_NO_RESULT,
- on_response_xdns_enable_cmd, ps_context);
- if (TCORE_RETURN_SUCCESS == tcore_hal_send_request(hal, pending)) {
- return TCORE_RETURN_SUCCESS;
- }
- _unable_to_get_pending(co_ps, ps_context);
- return TCORE_RETURN_FAILURE;
-}
-
-static void on_response_define_pdp_context(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- const TcoreATResponse *resp = data;
- CoreObject *ps_context = (CoreObject *) user_data;
- CoreObject *co_ps = tcore_pending_ref_core_object(p);
-
- dbg("Entry");
- if (resp->success) {
- dbg("Response OK");
- send_xdns_enable_cmd(co_ps, ps_context);
- } else {
- dbg("response NOK");
- _unable_to_get_pending(co_ps, ps_context);
- dbg("Exiting");
- }
- return;
-}
-
-static TReturn define_ps_context(CoreObject *co_ps, CoreObject *ps_context, void *user_data)
-{
- TcoreHal *hal = NULL;
- TcorePending *pending = NULL;
- char *apn = NULL;
- char cmd_str[MAX_AT_CMD_STR_LEN] = {0};
- char pdp_type_str[10] = {0};
- unsigned int cid = PS_INVALID_CID;
- enum co_context_type pdp_type;
- enum co_context_d_comp d_comp;
- enum co_context_h_comp h_comp;
-
- dbg("Entry");
-
- 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);
- apn = tcore_context_get_apn(ps_context);
-
- hal = tcore_object_get_hal(co_ps);
- switch (pdp_type) {
- case CONTEXT_TYPE_X25:
- {
- dbg("CONTEXT_TYPE_X25");
- strcpy(pdp_type_str, "X.25");
- break;
- }
-
- case CONTEXT_TYPE_IP:
- {
- dbg("CONTEXT_TYPE_IP");
- strcpy(pdp_type_str, "IP");
- }
- break;
-
- case CONTEXT_TYPE_PPP:
- {
- dbg("CONTEXT_TYPE_PPP");
- strcpy(pdp_type_str, "PPP");
- }
- break;
-
- case CONTEXT_TYPE_IPV6:
- {
- dbg("CONTEXT_TYPE_IPV6");
- strcpy(pdp_type_str, "IPV6");
- break;
- }
-
- default:
- {
- /*PDP Type not supported supported*/
- dbg("Unsupported PDP type: %d returning ", pdp_type);
- return TCORE_RETURN_FAILURE;
- }
- }
- dbg("Activating context for CID: %d", cid);
- (void) sprintf(cmd_str, "AT+CGDCONT=%d,\"%s\",\"%s\",,%d,%d", cid, pdp_type_str, apn, d_comp, h_comp);
- dbg("Command: [%s] Command Length: [%d]", cmd_str, strlen(cmd_str));
-
- pending = tcore_at_pending_new(co_ps, cmd_str, NULL, TCORE_AT_NO_RESULT,
- on_response_define_pdp_context, ps_context);
- if (TCORE_RETURN_SUCCESS == tcore_hal_send_request(hal, pending)) {
- return TCORE_RETURN_SUCCESS;
- }
- _unable_to_get_pending(co_ps, ps_context);
- return TCORE_RETURN_FAILURE;
-}
-
-
-static struct tcore_ps_operations ps_ops = {
- .define_context = define_ps_context,
- .activate_context = activate_ps_context,
- /* Use AT_standard entry point */
- .deactivate_context = NULL
-};
-
-gboolean s_ps_init(TcorePlugin *cp, CoreObject *co_ps)
-{
- TcorePlugin *plugin = tcore_object_ref_plugin(co_ps);
-
- dbg("Entry");
-
- tcore_ps_override_ops(co_ps, &ps_ops);
-
- /*
- * AT_standard handles standard CGEV notifications:
- * tcore_object_override_callback(co, "+CGEV", on_cgev_notification, NULL);
- * no need to handle it here.
- */
-
- tcore_object_override_callback(co_ps, "+XNOTIFYDUNSTATUS", on_event_dun_call_notification, plugin);
-
- dbg("Exit");
-
- return TRUE;
-}
-
-void s_ps_exit(TcorePlugin *cp, CoreObject *co_ps)
-{
- dbg("Exit");
-}
+++ /dev/null
-/*
- * tel-plugin-imc
- *
- * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Contact: Ankit Jogi <ankit.jogi@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_sap.h>
-#include <co_sim.h>
-#include <user_request.h>
-#include <server.h>
-#include <at.h>
-
-#include "s_common.h"
-#include "s_sap.h"
-
-
-static void on_confirmation_sap_message_send(TcorePending *p, gboolean result, void *user_data)
-{
- dbg("on_confirmation_sap_message_send - msg out from queue.\n");
-
- if (result == FALSE) {
- /* Fail */
- dbg("SEND FAIL");
- } else {
- dbg("SEND OK");
- }
-}
-
-static gboolean on_event_sap_status(CoreObject *o, const void *event_info, void *user_data)
-{
- struct tnoti_sap_status_changed noti;
- GSList *tokens = NULL;
- GSList *lines = NULL;
- const char *line = NULL;
- int status = 0;
-
- dbg(" Function entry ");
-
- lines = (GSList *) event_info;
- if (1 != g_slist_length(lines)) {
- dbg("unsolicited msg but multiple line");
- return FALSE;
- }
- line = (char *) (lines->data);
-
- tokens = tcore_at_tok_new(line);
- if (g_slist_length(tokens) != 1) {
- msg("invalid message");
- tcore_at_tok_free(tokens);
- return FALSE;
- }
- status = atoi(g_slist_nth_data(tokens, 0));
-
- switch(status){
- case 0:
- noti.status = SAP_CARD_STATUS_UNKNOWN;
- break;
- case 1:
- noti.status = SAP_CARD_STATUS_RESET;
- break;
- case 2:
- noti.status = SAP_CARD_STATUS_NOT_ACCESSIBLE;
- break;
- case 3:
- noti.status = SAP_CARD_STATUS_REMOVED;
- break;
- case 4:
- noti.status = SAP_CARD_STATUS_INSERTED;
- break;
- case 5:
- noti.status = SAP_CARD_STATUS_RECOVERED;
- break;
- default:
- noti.status = SAP_CARD_STATUS_NOT_ACCESSIBLE;
- break;
- }
-
- tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_SAP_STATUS,
- sizeof(struct tnoti_sap_status_changed), ¬i);
- return TRUE;
-}
-
-/*static void on_event_sap_disconnect(CoreObject *o, const void *event_info, void *user_data)
-{
- //ToDo - Indication not present
-
- const ipc_sap_disconnect_noti_type *ipc = event_info;
- struct tnoti_sap_disconnect noti;
-
- dbg("NOTI RECEIVED");
-
- noti.type = ipc->disconnect_type;
- tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_SAP_DISCONNECT,
- sizeof(struct tnoti_sap_disconnect), ¬i);
-}*/
-
-static void on_response_connect(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- const TcoreATResponse *resp = data;
- UserRequest *ur = NULL;
- struct tresp_sap_req_connect res;
- int *max_msg_size = (int *)user_data;
-
- dbg(" Function entry ");
-
- memset(&res, 0x00, sizeof(struct tresp_sap_req_connect));
- ur = tcore_pending_ref_user_request(p);
-
- if(resp->success > 0)
- {
- dbg("RESPONSE OK");
-
- res.status = SAP_CONNECTION_STATUS_OK;
- res.max_msg_size = *max_msg_size;
-
- }else{
- dbg("RESPONSE NOK");
- res.status = SAP_CONNECTION_STATUS_UNABLE_TO_ESTABLISH;
- res.max_msg_size = 0;
- }
-
- if (ur) {
- tcore_user_request_send_response(ur, TRESP_SAP_REQ_CONNECT, sizeof(struct tresp_sap_req_connect), &res);
- }
- dbg(" Function exit");
-}
-
-static void on_response_disconnect(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- const TcoreATResponse *resp = data;
- UserRequest *ur = NULL;
- struct tresp_sap_req_disconnect res;
-
- dbg(" Function entry ");
- memset(&res, 0x00, sizeof(struct tresp_sap_req_disconnect));
- ur = tcore_pending_ref_user_request(p);
-
- if(resp->success > 0)
- {
- dbg("RESPONSE OK");
-
- res.result = SAP_RESULT_CODE_OK;
-
- }else{
- dbg("RESPONSE NOK");
- //ToDo - Error mapping
- }
-
- if (ur) {
- tcore_user_request_send_response(ur, TRESP_SAP_REQ_DISCONNECT, sizeof(struct tresp_sap_req_disconnect), &res);
- }
- dbg(" Function exit");
-}
-
-static void on_response_req_status(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- const TcoreATResponse *resp = data;
- UserRequest *ur = NULL;
- struct tresp_sap_req_status res;
-
- dbg(" Function entry ");
-
- ur = tcore_pending_ref_user_request(p);
-
- if(resp->success > 0)
- {
- dbg("RESPONSE OK");
- //ToDo - No AT command present
- //res.status = NULL;
-
- }else{
- dbg("RESPONSE NOK");
- //ToDo - Error mapping
- }
-
- if (ur) {
- tcore_user_request_send_response(ur, TRESP_SAP_REQ_STATUS, sizeof(struct tresp_sap_req_status), &res);
- }
- dbg(" Function exit");
-}
-
-static void on_response_set_transfort_protocol(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- const TcoreATResponse *resp = data;
- UserRequest *ur = NULL;
- struct tresp_sap_set_protocol res;
-
- dbg(" Function entry ");
-
- ur = tcore_pending_ref_user_request(p);
-
- if(resp->success > 0)
- {
- dbg("RESPONSE OK");
- //ToDo - No AT command present
- //res.result = NULL;
-
- }else{
- dbg("RESPONSE NOK");
- //ToDo - Error mapping
- }
-
- if (ur) {
- tcore_user_request_send_response(ur, TRESP_SAP_SET_PROTOCOL, sizeof(struct tresp_sap_set_protocol), &res);
- }
- dbg(" Function exit");
-}
-
-static void on_response_set_power(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- const TcoreATResponse *resp = data;
- UserRequest *ur = NULL;
- struct tresp_sap_set_power res;
- GSList *tokens=NULL;
- const char *line;
- int sap_status = -1;
-
- dbg(" Function entry ");
-
- ur = tcore_pending_ref_user_request(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) < 1) {
- msg("invalid message");
- tcore_at_tok_free(tokens);
- return;
- }
- }
- sap_status = atoi(g_slist_nth_data(tokens, 0));
-
- switch(sap_status){
- case 0:
- res.result = SAP_RESULT_CODE_OK;
- break;
- case 1:
- res.result = SAP_RESULT_CODE_NO_REASON;
- break;
- case 2:
- res.result = SAP_RESULT_CODE_CARD_NOT_ACCESSIBLE;
- break;
- case 3:
- res.result = SAP_RESULT_CODE_CARD_ALREADY_POWER_OFF;
- break;
- case 4:
- res.result = SAP_RESULT_CODE_CARD_REMOVED;
- break;
- case 5:
- res.result = SAP_RESULT_CODE_CARD_ALREADY_POWER_ON;
- break;
- case 6:
- res.result = SAP_RESULT_CODE_DATA_NOT_AVAILABLE;
- break;
- case 7:
- res.result = SAP_RESULT_CODE_NOT_SUPPORT;
- break;
- default:
- res.result = SAP_RESULT_CODE_NOT_SUPPORT;
- break;
- }
-
- }else{
- dbg("RESPONSE NOK");
- res.result = SAP_RESULT_CODE_NOT_SUPPORT;
- }
-
- if (ur) {
- tcore_user_request_send_response(ur, TRESP_SAP_SET_POWER, sizeof(struct tresp_sap_set_power), &res);
- }
- tcore_at_tok_free(tokens);
- dbg(" Function exit");
-}
-
-static void on_response_get_atr(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- const TcoreATResponse *resp = data;
- UserRequest *ur = NULL;
- struct tresp_sap_req_atr res;
- GSList *tokens=NULL;
- const char *line;
- int sap_status = -1;
- char *atr_data = NULL;
-
- dbg(" Function entry ");
-
- ur = tcore_pending_ref_user_request(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) < 1) {
- msg("invalid message");
- tcore_at_tok_free(tokens);
- return;
- }
- }
- sap_status = atoi(g_slist_nth_data(tokens, 0));
- atr_data = (char *) g_slist_nth_data(tokens, 1);
-
- res.atr_length = strlen(atr_data);
- if( res.atr_length > 256 ) {
- dbg(" Memory overflow handling");
- return;
- }
- memcpy(res.atr, atr_data, res.atr_length);
-
- switch(sap_status){
- case 0:
- res.result = SAP_RESULT_CODE_OK;
- break;
- case 1:
- res.result = SAP_RESULT_CODE_NO_REASON;
- break;
- case 2:
- res.result = SAP_RESULT_CODE_CARD_NOT_ACCESSIBLE;
- break;
- case 3:
- res.result = SAP_RESULT_CODE_CARD_ALREADY_POWER_OFF;
- break;
- case 4:
- res.result = SAP_RESULT_CODE_CARD_REMOVED;
- break;
- case 5:
- res.result = SAP_RESULT_CODE_CARD_ALREADY_POWER_ON;
- break;
- case 6:
- res.result = SAP_RESULT_CODE_DATA_NOT_AVAILABLE;
- break;
- case 7:
- res.result = SAP_RESULT_CODE_NOT_SUPPORT;
- break;
- default:
- res.result = SAP_RESULT_CODE_NOT_SUPPORT;
- break;
- }
-
- }else{
- dbg("RESPONSE NOK");
- res.result = SAP_RESULT_CODE_NOT_SUPPORT;
- }
-
- if (ur) {
- tcore_user_request_send_response(ur, TRESP_SAP_REQ_ATR, sizeof(struct tresp_sap_req_atr), &res);
- }
- dbg(" Function exit");
-}
-
-static void on_response_transfer_apdu(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- const TcoreATResponse *resp = data;
- UserRequest *ur = NULL;
- struct tresp_sap_transfer_apdu res;
- GSList *tokens=NULL;
- const char *line;
- int sap_status = -1;
- char *apdu_data = NULL;
-
- dbg(" Function entry ");
-
- ur = tcore_pending_ref_user_request(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) < 1) {
- msg("invalid message");
- tcore_at_tok_free(tokens);
- return;
- }
- }
- sap_status = atoi(g_slist_nth_data(tokens, 0));
- apdu_data = (char *) g_slist_nth_data(tokens, 1);
-
- res.resp_apdu_length = strlen(apdu_data);
- if( res.resp_apdu_length > 256 ) {
- dbg(" Memory overflow handling");
- return;
- }
- memcpy(res.resp_adpdu, apdu_data, res.resp_apdu_length);
-
- switch(sap_status){
- case 0:
- res.result = SAP_RESULT_CODE_OK;
- break;
- case 1:
- res.result = SAP_RESULT_CODE_NO_REASON;
- break;
- case 2:
- res.result = SAP_RESULT_CODE_CARD_NOT_ACCESSIBLE;
- break;
- case 3:
- res.result = SAP_RESULT_CODE_CARD_ALREADY_POWER_OFF;
- break;
- case 4:
- res.result = SAP_RESULT_CODE_CARD_REMOVED;
- break;
- case 5:
- res.result = SAP_RESULT_CODE_CARD_ALREADY_POWER_ON;
- break;
- case 6:
- res.result = SAP_RESULT_CODE_DATA_NOT_AVAILABLE;
- break;
- case 7:
- res.result = SAP_RESULT_CODE_NOT_SUPPORT;
- break;
- default:
- res.result = SAP_RESULT_CODE_NOT_SUPPORT;
- break;
- }
-
- }else{
- dbg("RESPONSE NOK");
- res.result = SAP_RESULT_CODE_NOT_SUPPORT;
- }
-
- if (ur) {
- tcore_user_request_send_response(ur, TRESP_SAP_TRANSFER_APDU, sizeof(struct tresp_sap_transfer_apdu), &res);
- }
- dbg(" Function exit");
-}
-
-static void on_response_get_cardreader_status(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- const TcoreATResponse *resp = data;
- UserRequest *ur = NULL;
- struct tresp_sap_req_cardreaderstatus res;
- GSList *tokens=NULL;
- const char *line;
- int sap_status = -1;
- char *card_reader_status = NULL;
-
- dbg(" Function entry ");
-
- ur = tcore_pending_ref_user_request(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) < 1) {
- msg("invalid message");
- tcore_at_tok_free(tokens);
- return;
- }
- }
- sap_status = atoi(g_slist_nth_data(tokens, 0));
- card_reader_status = (char *) g_slist_nth_data(tokens, 1);
-
- res.reader_status = *card_reader_status;
-
- switch(sap_status){
- case 0:
- res.result = SAP_RESULT_CODE_OK;
- break;
- case 1:
- res.result = SAP_RESULT_CODE_NO_REASON;
- break;
- case 2:
- res.result = SAP_RESULT_CODE_CARD_NOT_ACCESSIBLE;
- break;
- case 3:
- res.result = SAP_RESULT_CODE_CARD_ALREADY_POWER_OFF;
- break;
- case 4:
- res.result = SAP_RESULT_CODE_CARD_REMOVED;
- break;
- case 5:
- res.result = SAP_RESULT_CODE_CARD_ALREADY_POWER_ON;
- break;
- case 6:
- res.result = SAP_RESULT_CODE_DATA_NOT_AVAILABLE;
- break;
- case 7:
- res.result = SAP_RESULT_CODE_NOT_SUPPORT;
- break;
- default:
- res.result = SAP_RESULT_CODE_NOT_SUPPORT;
- break;
- }
-
- }else{
- dbg("RESPONSE NOK");
- res.result = SAP_RESULT_CODE_NOT_SUPPORT;
- }
-
- if (ur) {
- tcore_user_request_send_response(ur, TRESP_SAP_REQ_CARDREADERSTATUS, sizeof(struct tresp_sap_req_cardreaderstatus), &res);
- }
- dbg(" Function exit");
-}
-
-static TReturn s_connect(CoreObject *o, UserRequest *ur)
-{
- TcoreHal *hal;
- TcoreATRequest *req;
- TcorePending *pending = NULL;
- char *cmd_str = NULL;
- const struct treq_sap_req_connect *req_data;
- int *usr_data = NULL;
-
- dbg(" Function entry");
- if (!o || !ur)
- return TCORE_RETURN_EINVAL;
- hal = tcore_object_get_hal(o);
- if(FALSE == tcore_hal_get_power_state(hal)){
- dbg("cp not ready/n");
- return TCORE_RETURN_ENOSYS;
- }
- req_data = tcore_user_request_ref_data(ur, NULL);
- usr_data = (int*)malloc(sizeof(int));
- *usr_data = req_data->max_msg_size;
- cmd_str = g_strdup_printf("AT+XBCON=0,0,0");
-
- req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_SINGLELINE);
-
- dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
-
- tcore_pending_set_request_data(pending, 0, req);
- tcore_pending_set_response_callback(pending, on_response_connect, usr_data);
- tcore_pending_link_user_request(pending, ur);
- tcore_pending_set_send_callback(pending, on_confirmation_sap_message_send, NULL);
-
- tcore_hal_send_request(hal, pending);
-
- free(cmd_str);
- dbg(" Function exit");
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn s_disconnect(CoreObject *o, UserRequest *ur)
-{
- TcoreHal *hal;
- TcoreATRequest *req;
- TcorePending *pending = NULL;
- char *cmd_str = NULL;
- const struct treq_sap_req_disconnect *req_data;
-
- dbg(" Function entry");
- if (!o || !ur)
- return TCORE_RETURN_EINVAL;
- hal = tcore_object_get_hal(o);
- if(FALSE == tcore_hal_get_power_state(hal)){
- dbg("cp not ready/n");
- return TCORE_RETURN_ENOSYS;
- }
-
- req_data = tcore_user_request_ref_data(ur, NULL);
-
- cmd_str = g_strdup_printf("AT+ XBDISC");
-
- req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_SINGLELINE);
-
- dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
-
- tcore_pending_set_request_data(pending, 0, req);
- tcore_pending_set_response_callback(pending, on_response_disconnect, NULL);
- tcore_pending_link_user_request(pending, ur);
- tcore_pending_set_send_callback(pending, on_confirmation_sap_message_send, NULL);
-
- tcore_hal_send_request(hal, pending);
-
- free(cmd_str);
- dbg(" Function exit");
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn s_req_status(CoreObject *o, UserRequest *ur)
-{
- TcoreHal *hal;
- TcoreATRequest *req;
- TcorePending *pending = NULL;
- char *cmd_str = NULL;
- const struct treq_sap_req_status *req_data;
-
- dbg(" Function entry");
- if (!o || !ur)
- return TCORE_RETURN_EINVAL;
- hal = tcore_object_get_hal(o);
- if(FALSE == tcore_hal_get_power_state(hal)){
- dbg("cp not ready/n");
- return TCORE_RETURN_ENOSYS;
- }
-
- req_data = tcore_user_request_ref_data(ur, NULL);
-
- //cmd_str = g_strdup_printf("");//ToDo - No AT command present.
-
- req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_SINGLELINE);
-
- dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
-
- tcore_pending_set_request_data(pending, 0, req);
- tcore_pending_set_response_callback(pending, on_response_req_status, NULL);
- tcore_pending_link_user_request(pending, ur);
- tcore_pending_set_send_callback(pending, on_confirmation_sap_message_send, NULL);
-
- tcore_hal_send_request(hal, pending);
-
- free(cmd_str);
- dbg(" Function exit");
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn s_set_transport_protocol(CoreObject *o, UserRequest *ur)
-{
- TcoreHal *hal;
- TcoreATRequest *req;
- TcorePending *pending = NULL;
- char *cmd_str = NULL;
- const struct treq_sap_set_protocol *req_data;
-
- dbg(" Function entry");
- if (!o || !ur)
- return TCORE_RETURN_EINVAL;
- hal = tcore_object_get_hal(o);
- if(FALSE == tcore_hal_get_power_state(hal)){
- dbg("cp not ready/n");
- return TCORE_RETURN_ENOSYS;
- }
-
- req_data = tcore_user_request_ref_data(ur, NULL);
-
- //cmd_str = g_strdup_printf("");//ToDo - No AT command present.
-
- req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_SINGLELINE);
-
- dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
-
- tcore_pending_set_request_data(pending, 0, req);
- tcore_pending_set_response_callback(pending, on_response_set_transfort_protocol, NULL);
- tcore_pending_link_user_request(pending, ur);
- tcore_pending_set_send_callback(pending, on_confirmation_sap_message_send, NULL);
-
- tcore_hal_send_request(hal, pending);
-
- free(cmd_str);
- dbg(" Function exit");
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn s_set_power(CoreObject *o, UserRequest *ur)
-{
- TcoreHal *hal;
- TcoreATRequest *req;
- TcorePending *pending = NULL;
- char *cmd_str = NULL;
- const struct treq_sap_set_power *req_data;
- int action = -1;
-
- dbg(" Function entry");
- if (!o || !ur)
- return TCORE_RETURN_EINVAL;
- hal = tcore_object_get_hal(o);
- if(FALSE == tcore_hal_get_power_state(hal)){
- dbg("cp not ready/n");
- return TCORE_RETURN_ENOSYS;
- }
-
- req_data = tcore_user_request_ref_data(ur, NULL);
-
- if(req_data->mode == SAP_POWER_ON) {
- action = 0;
- } else if ( req_data->mode == SAP_POWER_OFF ) {
- action = 1;
- } else if ( req_data->mode == SAP_POWER_RESET ) {
- action = 2;
- } else {
- action = -1;;
- }
-
- cmd_str = g_strdup_printf("AT+ XBPWR=%d", action);
-
- req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_SINGLELINE);
-
- dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
-
- tcore_pending_set_request_data(pending, 0, req);
- tcore_pending_set_response_callback(pending, on_response_set_power, NULL);
- tcore_pending_link_user_request(pending, ur);
- tcore_pending_set_send_callback(pending, on_confirmation_sap_message_send, NULL);
-
- tcore_hal_send_request(hal, pending);
-
- free(cmd_str);
- dbg(" Function exit");
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn s_get_atr(CoreObject *o, UserRequest *ur)
-{
- TcoreHal *hal;
- TcoreATRequest *req;
- TcorePending *pending = NULL;
- char *cmd_str = NULL;
- const struct treq_sap_req_atr *req_data;
-
- dbg(" Function entry");
- if (!o || !ur)
- return TCORE_RETURN_EINVAL;
- hal = tcore_object_get_hal(o);
- if(FALSE == tcore_hal_get_power_state(hal)){
- dbg("cp not ready/n");
- return TCORE_RETURN_ENOSYS;
- }
-
- req_data = tcore_user_request_ref_data(ur, NULL);
-
- cmd_str = g_strdup_printf("AT+ XBATR");
-
- req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_SINGLELINE);
-
- dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
-
- tcore_pending_set_request_data(pending, 0, req);
- tcore_pending_set_response_callback(pending, on_response_get_atr, NULL);
- tcore_pending_link_user_request(pending, ur);
- tcore_pending_set_send_callback(pending, on_confirmation_sap_message_send, NULL);
-
- tcore_hal_send_request(hal, pending);
-
- free(cmd_str);
- dbg(" Function exit");
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn s_transfer_apdu(CoreObject *o, UserRequest *ur)
-{
- TcoreHal *hal;
- TcoreATRequest *req;
- TcorePending *pending = NULL;
- char *cmd_str = NULL;
- const struct treq_sap_transfer_apdu *req_data;
-
- dbg(" Function entry");
- if (!o || !ur)
- return TCORE_RETURN_EINVAL;
- hal = tcore_object_get_hal(o);
- if(FALSE == tcore_hal_get_power_state(hal)){
- dbg("cp not ready/n");
- return TCORE_RETURN_ENOSYS;
- }
-
- req_data = tcore_user_request_ref_data(ur, NULL);
-
- cmd_str = g_strdup_printf("AT+ XBAPDU=\"%s\"", req_data->apdu_data); //ToDo - Need to check passing input as a string.
-
- req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_SINGLELINE);
-
- dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
-
- tcore_pending_set_request_data(pending, 0, req);
- tcore_pending_set_response_callback(pending, on_response_transfer_apdu, NULL);
- tcore_pending_link_user_request(pending, ur);
- tcore_pending_set_send_callback(pending, on_confirmation_sap_message_send, NULL);
-
- tcore_hal_send_request(hal, pending);
-
- free(cmd_str);
- dbg(" Function exit");
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn s_get_cardreader_status(CoreObject *o, UserRequest *ur)
-{
- TcoreHal *hal;
- TcoreATRequest *req;
- TcorePending *pending = NULL;
- char *cmd_str = NULL;
- const struct treq_sap_req_cardreaderstatus *req_data;
-
- dbg(" Function entry");
- if (!o || !ur)
- return TCORE_RETURN_EINVAL;
- hal = tcore_object_get_hal(o);
- if(FALSE == tcore_hal_get_power_state(hal)){
- dbg("cp not ready/n");
- return TCORE_RETURN_ENOSYS;
- }
-
- req_data = tcore_user_request_ref_data(ur, NULL);
-
- cmd_str = g_strdup_printf("AT+ XBCRDSTAT");
-
- req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_SINGLELINE);
-
- dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
-
- tcore_pending_set_request_data(pending, 0, req);
- tcore_pending_set_response_callback(pending, on_response_get_cardreader_status, NULL);
- tcore_pending_link_user_request(pending, ur);
- tcore_pending_set_send_callback(pending, on_confirmation_sap_message_send, NULL);
-
- tcore_hal_send_request(hal, pending);
-
- free(cmd_str);
- dbg(" Function exit");
- return TCORE_RETURN_SUCCESS;
-}
-
-static struct tcore_sap_operations sap_ops =
-{
- .connect = s_connect,
- .disconnect = s_disconnect,
- .req_status = s_req_status,
- .set_transport_protocol = s_set_transport_protocol,
- .set_power = s_set_power,
- .get_atr = s_get_atr,
- .transfer_apdu = s_transfer_apdu,
- .get_cardreader_status = s_get_cardreader_status,
-};
-
-
-gboolean s_sap_init(TcorePlugin *cp, CoreObject *co_sap)
-{
- dbg("Entry");
-
- tcore_sap_override_ops(co_sap, &sap_ops);
-
- tcore_object_override_callback(co_sap,"+XBCSTAT", on_event_sap_status, NULL);
-
- dbg("Exit");
-
- return TRUE;
-}
-
-void s_sap_exit(TcorePlugin *cp, CoreObject *co_sap)
-{
- dbg("Exit");
-}
+++ /dev/null
-/*
- * tel-plugin-imc
- *
- * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: Chandan Swarup Patra <chandan.sp@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_sat.h>
-#include <user_request.h>
-#include <at.h>
-
-#include "s_common.h"
-#include "s_sat.h"
-#define ENVELOPE_CMD_LEN 256
-
-static TReturn s_terminal_response(CoreObject *o, UserRequest *ur);
-static void on_confirmation_sat_message_send(TcorePending *p, gboolean result, void *user_data); // from Kernel
-
-static void on_confirmation_sat_message_send(TcorePending *p, gboolean result, void *user_data)
-{
- dbg("on_confirmation_modem_message_send - msg out from queue.\n");
-
- if (result == FALSE) {
- /* Fail */
- dbg("SEND FAIL");
- } else {
- dbg("SEND OK");
- }
-}
-
-static gboolean on_response_terminal_response_confirm(CoreObject *o, const void *event_info, void *user_data)
-{
- dbg("Function Entry");
- return TRUE;
- dbg("Function Exit");
-}
-
-static gboolean on_event_sat_proactive_command(CoreObject *o, const void *event_info, void *user_data)
-{
- struct tcore_sat_proactive_command decoded_data;
- struct tnoti_sat_proactive_ind proactive_noti;
- int len_proactive_cmd = 0;
- GSList *lines = NULL;
- GSList *tokens = NULL;
- char *line = NULL;
- char *hexData = NULL;
- char *tmp = NULL;
- char *recordData = NULL;
-
- dbg("Function Entry");
-
- memset(&proactive_noti, 0x00, sizeof(struct tnoti_sat_proactive_ind));
- memset(&decoded_data, 0x00, sizeof(struct tcore_sat_proactive_command));
- lines = (GSList *) event_info;
- line = (char *) lines->data;
- tokens = tcore_at_tok_new(line);
- if (g_slist_length(tokens) != 1) {
- err("Invalid message");
- tcore_at_tok_free(tokens);
- return FALSE;
- }
-
- hexData = (char *)g_slist_nth_data(tokens, 0);
- dbg("SAT data: [%s] SAT data length: [%d]", hexData, strlen(hexData));
-
- tmp = util_removeQuotes(hexData);
- recordData = util_hexStringToBytes(tmp);
- dbg("recordData: %x", recordData);
- g_free(tmp);
- util_hex_dump(" ", strlen(hexData) / 2, recordData);
- len_proactive_cmd = strlen(recordData);
- dbg("len_proactive_cmd = %d", len_proactive_cmd);
- tcore_sat_decode_proactive_command((unsigned char *) recordData, (strlen(hexData) / 2) - 1, &decoded_data);
- g_free(recordData);
-
- proactive_noti.cmd_number = decoded_data.cmd_num;
- proactive_noti.cmd_type = decoded_data.cmd_type;
-
- switch (decoded_data.cmd_type) {
- case SAT_PROATV_CMD_DISPLAY_TEXT:
- dbg("decoded command is display text!!");
- memcpy(&proactive_noti.proactive_ind_data.display_text, &decoded_data.data.display_text, sizeof(struct tel_sat_display_text_tlv));
- break;
-
- case SAT_PROATV_CMD_GET_INKEY:
- dbg("decoded command is get inkey!!");
- memcpy(&proactive_noti.proactive_ind_data.get_inkey, &decoded_data.data.get_inkey, sizeof(struct tel_sat_get_inkey_tlv));
- break;
-
- case SAT_PROATV_CMD_GET_INPUT:
- dbg("decoded command is get input!!");
- memcpy(&proactive_noti.proactive_ind_data.get_input, &decoded_data.data.get_input, sizeof(struct tel_sat_get_input_tlv));
- break;
-
- case SAT_PROATV_CMD_MORE_TIME:
- dbg("decoded command is more time!!");
- memcpy(&proactive_noti.proactive_ind_data.more_time, &decoded_data.data.more_time, sizeof(struct tel_sat_more_time_tlv));
- break;
-
- case SAT_PROATV_CMD_PLAY_TONE:
- dbg("decoded command is play tone!!");
- memcpy(&proactive_noti.proactive_ind_data.play_tone, &decoded_data.data.play_tone, sizeof(struct tel_sat_play_tone_tlv));
- break;
-
- case SAT_PROATV_CMD_SETUP_MENU:
- dbg("decoded command is SETUP MENU!!");
- memcpy(&proactive_noti.proactive_ind_data.setup_menu, &decoded_data.data.setup_menu, sizeof(struct tel_sat_setup_menu_tlv));
- break;
-
- case SAT_PROATV_CMD_SELECT_ITEM:
- dbg("decoded command is select item!!");
- memcpy(&proactive_noti.proactive_ind_data.select_item, &decoded_data.data.select_item, sizeof(struct tel_sat_select_item_tlv));
- break;
-
- case SAT_PROATV_CMD_SEND_SMS:
- dbg("decoded command is send sms!!");
- memcpy(&proactive_noti.proactive_ind_data.send_sms, &decoded_data.data.send_sms, sizeof(struct tel_sat_send_sms_tlv));
- break;
-
- case SAT_PROATV_CMD_SEND_SS:
- dbg("decoded command is send ss!!");
- memcpy(&proactive_noti.proactive_ind_data.send_ss, &decoded_data.data.send_ss, sizeof(struct tel_sat_send_ss_tlv));
- break;
-
- case SAT_PROATV_CMD_SEND_USSD:
- dbg("decoded command is send ussd!!");
- memcpy(&proactive_noti.proactive_ind_data.send_ussd, &decoded_data.data.send_ussd, sizeof(struct tel_sat_send_ussd_tlv));
- break;
-
- case SAT_PROATV_CMD_SETUP_CALL:
- dbg("decoded command is setup call!!");
- memcpy(&proactive_noti.proactive_ind_data.setup_call, &decoded_data.data.setup_call, sizeof(struct tel_sat_setup_call_tlv));
- break;
-
- case SAT_PROATV_CMD_REFRESH:
- dbg("decoded command is refresh");
- memcpy(&proactive_noti.proactive_ind_data.refresh, &decoded_data.data.refresh, sizeof(struct tel_sat_refresh_tlv));
- break;
-
- case SAT_PROATV_CMD_PROVIDE_LOCAL_INFO:
- dbg("decoded command is provide local info");
- memcpy(&proactive_noti.proactive_ind_data.provide_local_info, &decoded_data.data.provide_local_info, sizeof(struct tel_sat_provide_local_info_tlv));
- break;
-
- case SAT_PROATV_CMD_SETUP_EVENT_LIST:
- dbg("decoded command is setup event list!!");
- memcpy(&proactive_noti.proactive_ind_data.setup_event_list, &decoded_data.data.setup_event_list, sizeof(struct tel_sat_setup_event_list_tlv));
- // setup_event_rsp_get(o, &decoded_data.data.setup_event_list);
- break;
-
- case SAT_PROATV_CMD_SETUP_IDLE_MODE_TEXT:
- dbg("decoded command is setup idle mode text");
- memcpy(&proactive_noti.proactive_ind_data.setup_idle_mode_text, &decoded_data.data.setup_idle_mode_text, sizeof(struct tel_sat_setup_idle_mode_text_tlv));
- break;
-
- case SAT_PROATV_CMD_SEND_DTMF:
- dbg("decoded command is send dtmf");
- memcpy(&proactive_noti.proactive_ind_data.send_dtmf, &decoded_data.data.send_dtmf, sizeof(struct tel_sat_send_dtmf_tlv));
- break;
-
- case SAT_PROATV_CMD_LANGUAGE_NOTIFICATION:
- dbg("decoded command is language notification");
- memcpy(&proactive_noti.proactive_ind_data.language_notification, &decoded_data.data.language_notification, sizeof(struct tel_sat_language_notification_tlv));
- break;
-
- case SAT_PROATV_CMD_LAUNCH_BROWSER:
- dbg("decoded command is launch browser");
- memcpy(&proactive_noti.proactive_ind_data.launch_browser, &decoded_data.data.launch_browser, sizeof(struct tel_sat_launch_browser_tlv));
- break;
-
- case SAT_PROATV_CMD_OPEN_CHANNEL:
- dbg("decoded command is open channel!!");
- memcpy(&proactive_noti.proactive_ind_data.open_channel, &decoded_data.data.open_channel, sizeof(struct tel_sat_open_channel_tlv));
- break;
-
- case SAT_PROATV_CMD_CLOSE_CHANNEL:
- dbg("decoded command is close channel!!");
- memcpy(&proactive_noti.proactive_ind_data.close_channel, &decoded_data.data.close_channel, sizeof(struct tel_sat_close_channel_tlv));
- break;
-
- case SAT_PROATV_CMD_RECEIVE_DATA:
- dbg("decoded command is receive data!!");
- memcpy(&proactive_noti.proactive_ind_data.receive_data, &decoded_data.data.receive_data, sizeof(struct tel_sat_receive_channel_tlv));
- break;
-
- case SAT_PROATV_CMD_SEND_DATA:
- dbg("decoded command is send data!!");
- memcpy(&proactive_noti.proactive_ind_data.send_data, &decoded_data.data.send_data, sizeof(struct tel_sat_send_channel_tlv));
- break;
-
- case SAT_PROATV_CMD_GET_CHANNEL_STATUS:
- dbg("decoded command is get channel status!!");
- memcpy(&proactive_noti.proactive_ind_data.get_channel_status, &decoded_data.data.get_channel_status, sizeof(struct tel_sat_get_channel_status_tlv));
- break;
-
- default:
- dbg("wrong input");
- break;
- }
- if (decoded_data.cmd_type == SAT_PROATV_CMD_REFRESH) {
- /*Not supported*/
- dbg("Not suported Proactive command");
- return FALSE;
- }
- tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_SAT_PROACTIVE_CMD,
- sizeof(struct tnoti_sat_proactive_ind), &proactive_noti);
- tcore_at_tok_free(tokens);
- dbg("Function Exit");
- return TRUE;
-}
-
-static void on_response_envelop_cmd(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- const TcoreATResponse *resp = data;
- UserRequest *ur = NULL;
- CoreObject *o = NULL;
- const struct treq_sat_envelop_cmd_data *req_data = NULL;
- GSList *tokens = NULL;
- struct tresp_sat_envelop_data res;
- const char *line = NULL;
- const char *env_res = NULL;
- int sw2 = -1;
-
- ur = tcore_pending_ref_user_request(p);
- req_data = tcore_user_request_ref_data(ur, NULL);
- o = tcore_pending_ref_core_object(p);
-
- if (!req_data) {
- dbg("request data is NULL");
- return;
- }
- memset(&res, 0, sizeof(struct tresp_sat_envelop_data));
-
- res.sub_cmd = req_data->sub_cmd;
-
- 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) < 1) {
- msg("invalid message");
- tcore_at_tok_free(tokens);
- return;
- }
- }
- env_res = g_slist_nth_data(tokens, 0);
- res.result = 0x8000;
- res.envelop_resp = ENVELOPE_SUCCESS;
- dbg("RESPONSE OK 3");
- if (NULL != g_slist_nth_data(tokens, 1)) {
- sw2 = atoi(g_slist_nth_data(tokens, 1));
- dbg("RESPONSE OK 4");
- if (sw2 == 0) {
- dbg("RESPONSE OK 5");
- tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_SAT_SESSION_END, 0, NULL);
- }
- }
- } else {
- dbg("RESPONSE NOK");
- res.result = -1;
- res.envelop_resp = ENVELOPE_FAILED;
- }
-
- if (ur) {
- tcore_user_request_send_response(ur, TRESP_SAT_REQ_ENVELOPE, sizeof(struct tresp_sat_envelop_data), &res);
- }
- tcore_at_tok_free(tokens);
- dbg(" Function exit");
-}
-
-
-static void on_response_terminal_response(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- UserRequest *ur = NULL;
- CoreObject *o = NULL;
- const TcoreATResponse *resp = data;
- gpointer tmp = NULL;
-
- dbg("Function Entry");
-
- if (resp->success > 0) {
- dbg("RESPONSE OK");
- dbg(" resp->success = %d", resp->success);
- ur = tcore_pending_ref_user_request(p);
- tmp = (gpointer) tcore_user_request_ref_communicator(ur);
- if (!ur || !tmp) {
- dbg("error - current ur is NULL");
- return;
- }
-
- o = tcore_pending_ref_core_object(p);
- if (!o)
- dbg("error - current sat core is NULL");
- tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_SAT_SESSION_END, 0, NULL);
- }
- dbg("Function Exit");
-}
-
-static TReturn s_envelope(CoreObject *o, UserRequest *ur)
-{
- TcoreHal *hal;
- TcoreATRequest *req = NULL;
- TcorePending *pending = NULL;
- char *cmd_str = NULL;
- const struct treq_sat_envelop_cmd_data *req_data = NULL;
- int envelope_cmd_len = 0;
- char envelope_cmd[ENVELOPE_CMD_LEN];
- int count = 0;
- char envelope_cmdhex[ENVELOPE_CMD_LEN * 2];
- char *pbuffer = NULL;
-
- dbg("Function Entry");
- memset(&envelope_cmdhex, 0x00, sizeof(envelope_cmdhex));
- pbuffer = envelope_cmdhex;
-
- hal = tcore_object_get_hal(o);
- if(FALSE == tcore_hal_get_power_state(hal)){
- dbg("cp not ready/n");
- return TCORE_RETURN_ENOSYS;
- }
-
- pending = tcore_pending_new(o, 0);
- req_data = tcore_user_request_ref_data(ur, NULL);
- dbg("new pending sub cmd(%d)", req_data->sub_cmd);
-
- envelope_cmd_len = tcore_sat_encode_envelop_cmd(req_data, (char *) envelope_cmd);
-
- dbg("envelope_cmd_len %d", envelope_cmd_len);
- if (envelope_cmd_len == 0) {
- return TCORE_RETURN_EINVAL;
- }
- for (count = 0; count < envelope_cmd_len; count++) {
- dbg("envelope_cmd %02x", (unsigned char)envelope_cmd[count]);
- sprintf(pbuffer, "%02x", (unsigned char)envelope_cmd[count]);
- pbuffer += 2;
- }
- dbg("pbuffer %s", envelope_cmdhex);
- cmd_str = g_strdup_printf("AT+SATE=\"%s\"", envelope_cmdhex);
- req = tcore_at_request_new(cmd_str, "+SATE:", TCORE_AT_SINGLELINE);
- dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
-
- tcore_pending_set_request_data(pending, 0, req);
- tcore_pending_set_response_callback(pending, on_response_envelop_cmd, hal);
- tcore_pending_link_user_request(pending, ur);
- tcore_pending_set_send_callback(pending, on_confirmation_sat_message_send, NULL);
- tcore_hal_send_request(hal, pending);
-
- g_free(cmd_str);
- dbg("Function Exit");
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn s_terminal_response(CoreObject *o, UserRequest *ur)
-{
- TcoreHal *hal = NULL;
- TcoreATRequest *req = NULL;
- TcorePending *pending = NULL;
- char *cmd_str = NULL;
- const struct treq_sat_terminal_rsp_data *req_data = NULL;
- int proactive_resp_len = 0;
- char proactive_resp[ENVELOPE_CMD_LEN];
- char proactive_resphex[ENVELOPE_CMD_LEN * 2];
- char *pbuffer = NULL;
- int i = 0;
- char *hexString = NULL;
-
- dbg("Function Entry");
- memset(&proactive_resphex, 0x00, sizeof(proactive_resphex));
- pbuffer = proactive_resphex;
- hal = tcore_object_get_hal(o);
- if(FALSE == tcore_hal_get_power_state(hal)){
- dbg("cp not ready/n");
- return TCORE_RETURN_ENOSYS;
- }
-
- pending = tcore_pending_new(o, 0);
- req_data = tcore_user_request_ref_data(ur, NULL);
-
- proactive_resp_len = tcore_sat_encode_terminal_response(req_data, (char *) proactive_resp);
- dbg("proactive_resp %s", proactive_resp);
- dbg("proactive_resp length %d", strlen(proactive_resp));
- if (proactive_resp_len == 0) {
- return TCORE_RETURN_EINVAL;
- }
- hexString = calloc((proactive_resp_len * 2) + 1, 1);
-
- for (i = 0; i < proactive_resp_len * 2; i += 2) {
- char value = 0;
- value = (proactive_resp[i / 2] & 0xf0) >> 4;
- if (value < 0xA)
- hexString[i] = ((proactive_resp[i / 2] & 0xf0) >> 4) + '0';
- else
- hexString[i] = ((proactive_resp[i / 2] & 0xf0) >> 4) + 'A' - 10;
-
- value = proactive_resp[i / 2] & 0x0f;
- if (value < 0xA)
- hexString[i + 1] = (proactive_resp[i / 2] & 0x0f) + '0';
- else
- hexString[i + 1] = (proactive_resp[i / 2] & 0x0f) + 'A' - 10;
- }
-
- dbg("hexString %s", hexString);
- cmd_str = g_strdup_printf("AT+SATR=\"%s\"", hexString);
-
- req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
- dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
-
- tcore_pending_set_request_data(pending, 0, req);
- tcore_pending_set_response_callback(pending, on_response_terminal_response, hal);
- tcore_pending_link_user_request(pending, ur);
- tcore_pending_set_send_callback(pending, on_confirmation_sat_message_send, NULL);
- tcore_hal_send_request(hal, pending);
-
- g_free(cmd_str);
- dbg("Function Exit");
- return TCORE_RETURN_SUCCESS;
-}
-
-static struct tcore_sat_operations sat_ops = {
- .envelope = s_envelope,
- .terminal_response = s_terminal_response,
-};
-
-gboolean s_sat_init(TcorePlugin *cp, CoreObject *co_sat)
-{
- dbg("Entry");
-
- tcore_sat_override_ops(co_sat, &sat_ops);
-
- tcore_object_override_callback(co_sat, "+SATI", on_event_sat_proactive_command, NULL);
- tcore_object_override_callback(co_sat, "+SATN", on_event_sat_proactive_command, NULL);
- tcore_object_override_callback(co_sat, "+SATF", on_response_terminal_response_confirm, NULL);
-
- dbg("Exit");
-
- return TRUE;
-}
-
-void s_sat_exit(TcorePlugin *cp, CoreObject *co_sat)
-{
- dbg("Exit");
-}
+++ /dev/null
-/*
- * tel-plugin-imc
- *
- * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: Ankit Jogi <ankit.jogi@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_sim.h>
-#include <co_sms.h>
-#include <storage.h>
-#include <user_request.h>
-#include <server.h>
-#include <at.h>
-
-#include "s_common.h"
-#include "s_sms.h"
-#include "s_sim.h"
-
-#define ID_RESERVED_AT 0x0229
-
-#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,
- SEC_SIM_UNKNOWN = 0xff
-};
-
-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 s_sim_sec_op_e current_sec_op; /**< current index to read */
- struct tel_sim_mbi_list mbi_list;
- struct tel_sim_mb_number mb_list[SIM_MSP_CNT_MAX*5];
- struct tresp_sim_read files;
-};
-
-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);
-extern gboolean util_byte_to_hex(const char *byte_pdu, char *hex_pdu, int num_bytes);
-
-static void sim_prepare_and_send_pending_request(CoreObject *co, const char *at_cmd, const char *prefix, enum tcore_at_command_type at_cmd_type, TcorePendingResponseCallback callback)
-{
- TcoreATRequest *req = NULL;
- TcoreHal *hal = NULL;
- TcorePending *pending = NULL;
- TReturn ret;
-
-
- hal = tcore_object_get_hal(co);
- dbg("hal: %p", hal);
-
- pending = tcore_pending_new(co, 0);
- if (!pending)
- dbg("Pending is NULL");
- req = tcore_at_request_new(at_cmd, prefix, at_cmd_type);
-
- dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
-
- tcore_pending_set_request_data(pending, 0, req);
- tcore_pending_set_response_callback(pending, callback, NULL);
- tcore_pending_link_user_request(pending, NULL); // set user request to NULL - this is internal request
- ret = tcore_hal_send_request(hal, pending);
- return;
-}
-
-
-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_GET_LOCK_INFO:
- return TRESP_SIM_GET_LOCK_INFO;
- 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_SET_CALLFORWARDING:
- return TRESP_SIM_SET_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(enum s_sim_sec_op_e op)
-{
- int ret_type = 0;
-
- dbg("current sec_op[%d]", op);
-
- switch (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 sec op[%d]", 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));
- file_meta = (struct s_sim_property *)tcore_user_request_ref_metainfo(ur, NULL);
-
- if ((ef != SIM_EF_ELP && ef != SIM_EF_LP && ef != SIM_EF_USIM_PL && ef != SIM_EF_CPHS_CPHS_INFO)
- && (rt != SIM_ACCESS_SUCCESS)) {
- tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &resp);
- return;
- }
-
- 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)");
- _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) {
- 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)");
- _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");
- 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_SST:
- case SIM_EF_SPN:
- case SIM_EF_SPDI:
- case SIM_EF_CPHS_CALL_FORWARD_FLAGS:
- case SIM_EF_CPHS_VOICE_MSG_WAITING:
- case SIM_EF_CPHS_OPERATOR_NAME_STRING:
- case SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING:
- 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:
- _get_file_data(o, ur, ef, 0, file_meta->data_size);
- break;
-
- case SIM_EF_CPHS_CPHS_INFO:
- if (rt == SIM_ACCESS_SUCCESS) {
- tcore_sim_set_cphs_status(o, TRUE);
- if (!tcore_user_request_ref_communicator(ur)) {
- dbg("internal CPHS INFO request before sim status update");
- _sim_status_update(o, SIM_STATUS_INIT_COMPLETED);
- } else {
- dbg("external CPHS INFO request");
- _get_file_data(o, ur, ef, 0, file_meta->data_size);
- }
- } else {
- tcore_sim_set_cphs_status(o, FALSE);
- if (!tcore_user_request_ref_communicator(ur)) {
- dbg("internal CPHS INFO request before sim status update");
- _sim_status_update(o, SIM_STATUS_INIT_COMPLETED);
- } else {
- dbg("external CPHS INFO request");
- tcore_user_request_send_response(ur, _find_resp_command(ur),
- sizeof(struct tresp_sim_read), &resp);
- }
- }
- break;
-
-
- case SIM_EF_USIM_CFIS:
- if (file_meta->rec_count > SIM_CF_RECORD_CNT_MAX) {
- file_meta->rec_count = SIM_CF_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_OPL:
- case SIM_EF_PNN:
- 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_MSISDN:
- file_meta->current_index++;
- _get_file_record(o, ur, ef, file_meta->current_index, file_meta->rec_length);
- break;
-
- 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;
-
- dbg("Entry");
-
- 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) {
- 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:
- ur = tcore_user_request_new(NULL, NULL); // this is for using ur metainfo set/ref functionality.
- _get_file_info(o, ur, SIM_EF_CPHS_CPHS_INFO);
- break;
-
- case SIM_EF_MSISDN:
- 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_OPL:
- 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:
- 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_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:
- 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_CPHS_OPERATOR_NAME_STRING:
- file_meta->files.result = rt;
- if (decode_ret == TRUE && rt == SIM_ACCESS_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));
- }
- _get_file_info(o, ur, SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING);
- break;
-
- case SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING:
- if (file_meta->files.result == SIM_ACCESS_SUCCESS || file_meta->files.result == SIM_ACCESS_SUCCESS) {
- file_meta->files.result = SIM_ACCESS_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));
- }
- tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
- break;
-
- case SIM_EF_ICCID:
- case SIM_EF_SST:
- case SIM_EF_SPN:
- case SIM_EF_SPDI:
- case SIM_EF_OPLMN_ACT:
- case SIM_EF_CPHS_CPHS_INFO:
- 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:
- tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
- break;
-
- 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, };
-
- if (sim_status != tcore_sim_get_status(o)) {
- dbg("Change in SIM State - Old State: [0x%02x] New State: [0x%02x]",
- tcore_sim_get_status(o), sim_status);
-
- /* Update SIM Status */
- tcore_sim_set_status(o, sim_status);
- noti_data.sim_status = sim_status;
-
- /* Send notification */
- tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)),
- o, TNOTI_SIM_STATUS, sizeof(noti_data), ¬i_data);
- }
-}
-
-static void _response_get_sim_type(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- const TcoreATResponse *resp = data;
- UserRequest *ur = NULL;
- CoreObject *co_sim = NULL;
- struct s_sim_property *sp = NULL;
- GSList *tokens = NULL;
- enum tel_sim_type sim_type = SIM_TYPE_UNKNOWN;
- const char *line;
- int state;
-
- dbg("Entry");
-
- co_sim = tcore_pending_ref_core_object(p);
- sp = tcore_sim_ref_userdata(co_sim);
- ur = tcore_pending_ref_user_request(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) != 1) {
- msg("Invalid message");
- tcore_at_tok_free(tokens);
- return;
- }
- }
- state = atoi(g_slist_nth_data(tokens, 0));
- dbg("SIM Type is %d", state);
-
- if (state == 0) {
- sim_type = SIM_TYPE_GSM;
- } else if (state == 1) {
- sim_type = SIM_TYPE_USIM;
- } else {
- sim_type = SIM_TYPE_UNKNOWN;
- }
- } else {
- dbg("RESPONSE NOK");
- sim_type = SIM_TYPE_UNKNOWN;
- }
-
- tcore_sim_set_type(co_sim, sim_type);
-
- if (sim_type != SIM_TYPE_UNKNOWN) {
- /* set user request for using ur metainfo set/ref functionality */
- ur = tcore_user_request_new(NULL, NULL);
- _get_file_info(co_sim, ur, SIM_EF_IMSI);
- }
-
- tcore_at_tok_free(tokens);
- dbg("Exit");
-}
-
-static void _response_get_file_info(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- const TcoreATResponse *resp = data;
- UserRequest *ur = NULL;
- CoreObject *co_sim = NULL;
- struct s_sim_property *file_meta = NULL;
- GSList *tokens = NULL;
- enum tel_sim_access_result rt;
- const char *line = NULL;
- int sw1 = 0;
- int sw2 = 0;
-
- dbg("Entry");
-
- co_sim = tcore_pending_ref_core_object(p);
- ur = tcore_pending_ref_user_request(p);
- file_meta = (struct s_sim_property *)tcore_user_request_ref_metainfo(ur, NULL);
-
- 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; /* 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 *tmp;
- char *recordData = NULL;
- hexData = g_slist_nth_data(tokens, 2);
- dbg("hexData: %s", hexData);
- dbg("hexData: %s", hexData + 1);
-
- tmp = util_removeQuotes(hexData);
- recordData = util_hexStringToBytes(tmp);
- util_hex_dump(" ", strlen(hexData) / 2, recordData);
- g_free(tmp);
-
- 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++;
- 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++;
- /* 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*/
- 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 = SIM_FTYPE_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 */
- 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!");
- tcore_at_tok_free(tokens);
- g_free(recordData);
- 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++;
- dbg("file_id_len: %02x", file_id_len);
-
- memcpy(&file_id, ptr_data, file_id_len);
- dbg("file_id: %x", file_id);
-
- /* swap bytes */
- SWAPBYTES16(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(recordData);
- 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 */
- 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);
- tcore_at_tok_free(tokens);
- g_free(recordData);
- 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!");
- tcore_at_tok_free(tokens);
- g_free(recordData);
- 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!");
- tcore_at_tok_free(tokens);
- g_free(recordData);
- 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;
- g_free(recordData);
- } else {
- /*2. SIM access fail case*/
- dbg("error to get ef[0x%x]", file_meta->file_id);
- dbg("error to get ef[0x%x] (file_meta->file_id) ", file_meta->file_id);
- rt = _decode_status_word(sw1, sw2);
- }
- ur = tcore_user_request_ref(ur);
-
- dbg("Calling _next_from_get_file_info");
- _next_from_get_file_info(co_sim, ur, file_meta->file_id, rt);
- tcore_at_tok_free(tokens);
- } else {
- dbg("RESPONSE NOK");
- dbg("error to get ef[0x%x]", file_meta->file_id);
- dbg("error to get ef[0x%x] (file_meta->file_id) ", 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);
- }
- dbg("Exit");
-}
-
-static void _response_get_file_data(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- const TcoreATResponse *resp = data;
- UserRequest *ur = NULL;
- CoreObject *co_sim = NULL;
- struct s_sim_property *file_meta = NULL;
- GSList *tokens = NULL;
- enum tel_sim_access_result rt;
- gboolean dr = FALSE;
- const char *line = NULL;
- char *res = NULL;
- char *tmp = NULL;
- int res_len;
- int sw1 = 0;
- int sw2 = 0;
-
- dbg("Entry");
-
- co_sim = tcore_pending_ref_core_object(p);
- ur = tcore_pending_ref_user_request(p);
- file_meta = (struct s_sim_property *)tcore_user_request_ref_metainfo(ur, NULL);
-
- 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) != 3) {
- 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 = util_removeQuotes(res);
- res = util_hexStringToBytes(tmp);
- res_len = strlen(tmp) / 2;
- dbg("Response: [%s] Response length: [%d]", res, res_len);
-
- if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
- rt = SIM_ACCESS_SUCCESS;
- file_meta->files.result = rt;
-
- dbg("File ID: [0x%x]", file_meta->file_id);
- switch (file_meta->file_id) {
- case SIM_EF_IMSI:
- {
- struct tel_sim_imsi *imsi = NULL;
-
- dbg("Data: [%s]", res);
- imsi = g_try_new0(struct tel_sim_imsi, 1);
- dr = tcore_sim_decode_imsi(imsi, (unsigned char *)res, res_len);
- if (dr == FALSE) {
- err("IMSI decoding failed");
- } else {
- _sim_check_identity(co_sim, imsi);
- tcore_sim_set_imsi(co_sim, imsi);
- }
-
- /* Free memory */
- g_free(imsi);
- }
- break;
-
- case SIM_EF_ICCID:
- dr = tcore_sim_decode_iccid(&file_meta->files.data.iccid, (unsigned char *)res, res_len);
- 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 *)res, res_len);
- } 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 *)res, res_len);
- }
- break;
-
- case SIM_EF_SPN:
- dr = tcore_sim_decode_spn(&file_meta->files.data.spn,
- (unsigned char *)res, res_len);
- break;
-
- case SIM_EF_SPDI:
- dr = tcore_sim_decode_spdi(&file_meta->files.data.spdi,
- (unsigned char *)res, res_len);
- break;
-
- case SIM_EF_SST: //EF UST has same address
- {
- struct tel_sim_service_table *svct = NULL;
-
- svct = g_try_new0(struct tel_sim_service_table, 1);
- if (tcore_sim_get_type(co_sim) == SIM_TYPE_GSM) {
- dr = tcore_sim_decode_sst(&svct->sst , (unsigned char *)res, res_len);
- } else if (tcore_sim_get_type(co_sim) == SIM_TYPE_USIM) {
- dr = tcore_sim_decode_ust(&svct->ust , (unsigned char *)res, res_len);
- } else {
- dbg("err not handled tcore_sim_get_type(o)[%d] in here",tcore_sim_get_type(co_sim));
- }
-
- if (dr == FALSE) {
- dbg("SST/UST decoding failed");
- } else {
- tcore_sim_set_service_table(co_sim, svct);
- }
-
- /* Free memory */
- g_free(svct);
- }
- 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 *)res, res_len);
- } else if (tcore_sim_get_type(co_sim) == SIM_TYPE_USIM) {
- struct tel_sim_ecc *ecc = NULL;
-
- ecc = g_try_new0(struct tel_sim_ecc, 1);
- dbg("Index [%d]", file_meta->current_index);
-
- dr = tcore_sim_decode_uecc(ecc, (unsigned char *)res, res_len);
- if (dr == TRUE) {
- memcpy(&file_meta->files.data.ecc.ecc[file_meta->files.data.ecc.ecc_count], ecc, sizeof(struct tel_sim_ecc));
- file_meta->files.data.ecc.ecc_count++;
- }
-
- /* Free memory */
- g_free(ecc);
- } else {
- dbg("Unknown/Unsupported SIM Type: [%d]", tcore_sim_get_type(co_sim));
- }
- }
- break;
-
- case SIM_EF_MSISDN:
- {
- struct tel_sim_msisdn *msisdn = NULL;
-
- dbg("Index [%d]", file_meta->current_index);
- msisdn = g_try_new0(struct tel_sim_msisdn, 1);
- dr = tcore_sim_decode_msisdn(msisdn, (unsigned char *)res, res_len);
- if (dr == TRUE) {
- memcpy(&file_meta->files.data.msisdn_list.msisdn[file_meta->files.data.msisdn_list.count],
- msisdn, sizeof(struct tel_sim_msisdn));
-
- file_meta->files.data.msisdn_list.count++;
- }
-
- /* Free memory */
- g_free(msisdn);
- }
- break;
-
- case SIM_EF_OPL:
- {
- struct tel_sim_opl *opl = NULL;
-
- dbg("decode w/ index [%d]", file_meta->current_index);
- opl = g_try_new0(struct tel_sim_opl, 1);
-
- dr = tcore_sim_decode_opl(opl, (unsigned char *)res, res_len);
- if (dr == TRUE) {
- memcpy(&file_meta->files.data.opl.opl[file_meta->files.data.opl.opl_count],
- opl, sizeof(struct tel_sim_opl));
-
- file_meta->files.data.opl.opl_count++;
- }
-
- /* Free memory */
- g_free(opl);
- }
- break;
-
- case SIM_EF_PNN:
- {
- struct tel_sim_pnn *pnn = NULL;
-
- dbg("decode w/ index [%d]", file_meta->current_index);
- pnn = g_try_new0(struct tel_sim_pnn, 1);
-
- dr = tcore_sim_decode_pnn(pnn, (unsigned char *)res, res_len);
- if (dr == TRUE) {
- memcpy(&file_meta->files.data.pnn.pnn[file_meta->files.data.pnn.pnn_count],
- pnn, sizeof(struct tel_sim_pnn));
-
- file_meta->files.data.pnn.pnn_count++;
- }
-
- /* Free memory */
- g_free(pnn);
- }
- break;
-
- case SIM_EF_OPLMN_ACT:
- dr = tcore_sim_decode_oplmnwact(&file_meta->files.data.opwa,
- (unsigned char *)res, res_len);
- break;
-
- case SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE:
- /*dr = tcore_sim_decode_csp(&po->p_cphs->csp,
- p_data->response, p_data->response_len);*/
- break;
-
- case SIM_EF_USIM_MBI: //linear type
- {
- struct tel_sim_mbi *mbi = NULL;
-
- mbi = g_try_new0(struct tel_sim_mbi, 1);
- dr = tcore_sim_decode_mbi(mbi, (unsigned char *)res, res_len);
- if (dr == TRUE) {
- memcpy(&file_meta->mbi_list.mbi[file_meta->mbi_list.profile_count],
- mbi, sizeof(struct tel_sim_mbi));
- file_meta->mbi_list.profile_count++;
-
- dbg("mbi count[%d]", file_meta->mbi_list.profile_count);
- dbg("voice_index[%d]", file_meta->mbi_list.mbi[file_meta->mbi_list.profile_count -1].voice_index);
- dbg("fax_index[%d]", file_meta->mbi_list.mbi[file_meta->mbi_list.profile_count -1].fax_index);
- dbg("email_index[%d]", file_meta->mbi_list.mbi[file_meta->mbi_list.profile_count -1].email_index);
- dbg("other_index[%d]", file_meta->mbi_list.mbi[file_meta->mbi_list.profile_count -1].other_index);
- dbg("video_index[%d]", file_meta->mbi_list.mbi[file_meta->mbi_list.profile_count -1].video_index);
- }
-
- /* Free memory */
- g_free(mbi);
- }
- break;
-
- case SIM_EF_CPHS_MAILBOX_NUMBERS: // linear type
- case SIM_EF_MBDN: //linear type
- dr = tcore_sim_decode_xdn(&file_meta->mb_list[file_meta->current_index-1].number_info,
- (unsigned char *)res, res_len);
- file_meta->mb_list[file_meta->current_index-1].rec_index = file_meta->current_index;
- break;
-
- case SIM_EF_CPHS_VOICE_MSG_WAITING: // transparent type
- dr = tcore_sim_decode_vmwf(&file_meta->files.data.mw.cphs_mw,
- (unsigned char *)res, res_len);
- break;
-
- case SIM_EF_USIM_MWIS: //linear type
- {
- struct tel_sim_mw *mw = NULL;
-
- mw = g_try_new0(struct tel_sim_mw, 1);
-
- dr = tcore_sim_decode_mwis(mw, (unsigned char *)res, res_len);
- if (dr == TRUE) {
- memcpy(&file_meta->files.data.mw.mw_list.mw[file_meta->files.data.mw.mw_list.profile_count], mw, sizeof(struct tel_sim_mw));
- file_meta->files.data.mw.mw_list.mw[file_meta->files.data.mw.mw_list.profile_count].rec_index = file_meta->current_index;
- file_meta->files.data.mw.mw_list.profile_count++;
- }
-
- /* Free memory */
- g_free(mw);
- }
- break;
-
- case SIM_EF_CPHS_CALL_FORWARD_FLAGS: //transparent type
- dr = tcore_sim_decode_cff(&file_meta->files.data.cf.cphs_cf,
- (unsigned char *)res, res_len);
- break;
-
- case SIM_EF_USIM_CFIS: //linear type
- {
- struct tel_sim_cfis *cf = NULL;
-
- cf = g_try_new0(struct tel_sim_cfis, 1);
- dr = tcore_sim_decode_cfis(cf, (unsigned char *)res, res_len);
- if (dr == TRUE) {
- memcpy(&file_meta->files.data.cf.cf_list.cf[file_meta->files.data.cf.cf_list.profile_count],
- cf, sizeof(struct tel_sim_cfis));
-
- file_meta->files.data.cf.cf_list.cf[file_meta->files.data.cf.cf_list.profile_count].rec_index = file_meta->current_index;
- file_meta->files.data.cf.cf_list.profile_count++;
- }
-
- /* Free memory */
- g_free(cf);
- }
- break;
-
- case SIM_EF_CPHS_SERVICE_STRING_TABLE:
- dbg("not handled -SIM_EF_CPHS_SERVICE_STRING_TABLE ");
- 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 *)res, res_len);
- 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 SIM_EF_CPHS_DYNAMICFLAGS:
- /*dr = tcore_sim_decode_dynamic_flag(&po->p_cphs->dflagsinfo,
- p_data->response, p_data->response_len);*/
- break;
-
- case SIM_EF_CPHS_DYNAMIC2FLAG:
- /*dr = tcore_sim_decode_dynamic2_flag(&po->p_cphs->d2flagsinfo, p_data->response,
- p_data->response_len);*/
- break;
-
- case SIM_EF_CPHS_CPHS_INFO:
- dr = tcore_sim_decode_cphs_info(&file_meta->files.data.cphs,
- (unsigned char *)res, res_len);
- 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 *)res, res_len);
- break;
-
- case 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 {
- rt = _decode_status_word(sw1, sw2);
- file_meta->files.result = rt;
- }
-
- /* 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);
- rt = SIM_ACCESS_FAILED;
- }
-
- /* Reference User Request */
- ur = tcore_user_request_ref(ur);
-
- /* Get File data */
- _next_from_get_file_data(tcore_pending_ref_core_object(p), ur, rt, dr);
-
- dbg("Exit");
-}
-
-static void _on_response_get_retry_count(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- const TcoreATResponse *resp = data;
- UserRequest *ur = NULL;
- CoreObject *co_sim = NULL;
- struct s_sim_property *sp = NULL;
- GSList *tokens = NULL;
- const char *line = NULL;
- int lock_type = 0;
- int attempts_left = 0;
- int time_penalty = 0;
-
- dbg("Entry");
-
- co_sim = tcore_pending_ref_core_object(p);
- sp = tcore_sim_ref_userdata(co_sim);
- ur = tcore_pending_ref_user_request(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) < 3) {
- msg("Invalid message");
- tcore_at_tok_free(tokens);
- return;
- }
- }
- lock_type = atoi(g_slist_nth_data(tokens, 0));
- attempts_left = atoi(g_slist_nth_data(tokens, 1));
- time_penalty = atoi(g_slist_nth_data(tokens, 2));
-
- dbg("lock_type = %d, attempts_left = %d, time_penalty = %d",
- lock_type, attempts_left, time_penalty);
-
- switch (sp->current_sec_op) {
- case SEC_PIN1_VERIFY:
- case SEC_PIN2_VERIFY:
- case SEC_SIM_VERIFY:
- case SEC_ADM_VERIFY:
- {
- struct tresp_sim_verify_pins v_pin = {0, };
-
- v_pin.result = SIM_INCORRECT_PASSWORD;
- v_pin.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
- v_pin.retry_count = attempts_left;
- tcore_user_request_send_response(ur, _find_resp_command(ur),
- sizeof(struct tresp_sim_verify_pins), &v_pin);
- }
- break;
-
- case SEC_PUK1_VERIFY:
- case SEC_PUK2_VERIFY:
- {
- struct tresp_sim_verify_puks v_puk = {0, };
-
- v_puk.result = SIM_INCORRECT_PASSWORD;
- v_puk.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
- v_puk.retry_count = attempts_left;
- tcore_user_request_send_response(ur, _find_resp_command(ur),
- sizeof(struct tresp_sim_verify_puks), &v_puk);
- }
- break;
-
- case SEC_PIN1_CHANGE:
- case SEC_PIN2_CHANGE:
- {
- struct tresp_sim_change_pins change_pin = {0, };
-
- change_pin.result = SIM_INCORRECT_PASSWORD;
- change_pin.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
- change_pin.retry_count = attempts_left;
- tcore_user_request_send_response(ur, _find_resp_command(ur),
- sizeof(struct tresp_sim_change_pins), &change_pin);
- }
- break;
-
- case SEC_PIN1_DISABLE:
- case SEC_PIN2_DISABLE:
- case SEC_FDN_DISABLE:
- case SEC_SIM_DISABLE:
- case SEC_NET_DISABLE:
- case SEC_NS_DISABLE:
- case SEC_SP_DISABLE:
- case SEC_CP_DISABLE:
- {
- struct tresp_sim_disable_facility dis_facility = {0, };
-
- dis_facility.result = SIM_INCORRECT_PASSWORD;
- dis_facility.type = _sim_get_current_pin_facility(sp->current_sec_op);
- dis_facility.retry_count = attempts_left;
- tcore_user_request_send_response(ur, _find_resp_command(ur),
- sizeof(struct tresp_sim_disable_facility), &dis_facility);
- }
- break;
-
- case SEC_PIN1_ENABLE:
- case SEC_PIN2_ENABLE:
- case SEC_FDN_ENABLE:
- case SEC_SIM_ENABLE:
- case SEC_NET_ENABLE:
- case SEC_NS_ENABLE:
- case SEC_SP_ENABLE:
- case SEC_CP_ENABLE:
- {
- struct tresp_sim_enable_facility en_facility = {0, };
-
- en_facility.result = SIM_INCORRECT_PASSWORD;
- en_facility.type = _sim_get_current_pin_facility(sp->current_sec_op);
- en_facility.retry_count = attempts_left;
- tcore_user_request_send_response(ur, _find_resp_command(ur),
- sizeof(struct tresp_sim_enable_facility), &en_facility);
- }
- break;
-
- default:
- dbg("not handled sec op[%d]", sp->current_sec_op);
- break;
- }
-
- /* Free tokens */
- tcore_at_tok_free(tokens);
- }
-
- dbg("Exit");
-}
-
-static gboolean _get_sim_type(CoreObject *o)
-{
- TcoreHal *hal = NULL;
- TcoreATRequest *req = NULL;
- TcorePending *pending = NULL;
- UserRequest *ur = NULL;
- char *cmd_str = NULL;
-
- dbg("Entry");
-
- hal = tcore_object_get_hal(o);
- pending = tcore_pending_new(o, 0);
-
- cmd_str = g_strdup_printf("AT+XUICC?");
- req = tcore_at_request_new(cmd_str, "+XUICC:", TCORE_AT_SINGLELINE);
- g_free(cmd_str);
-
- dbg("Command: [%s] Prefix(if any): [%s] Command length: [%d]",
- req->cmd, req->prefix, strlen(req->cmd));
-
- tcore_pending_set_request_data(pending, 0, req);
- tcore_pending_set_response_callback(pending, _response_get_sim_type, hal);
- tcore_pending_link_user_request(pending, ur);
- tcore_hal_send_request(hal, pending);
-
- dbg("Exit");
- return TRUE;
-}
-
-static TReturn _get_file_info(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef)
-{
- TcoreHal *hal = NULL;
- TcorePending *pending = NULL;
- struct s_sim_property file_meta = {0, };
- char *cmd_str = NULL;
- TReturn ret = TCORE_RETURN_FAILURE;
- int trt = 0;
-
- dbg("Entry");
-
- file_meta.file_id = ef;
- dbg("file_meta.file_id: [0x%02x]", file_meta.file_id);
- hal = tcore_object_get_hal(o);
- dbg("hal: %x", hal);
-
- trt = tcore_user_request_set_metainfo(ur, sizeof(struct s_sim_property), &file_meta);
- dbg("trt[%d]", trt);
- cmd_str = g_strdup_printf("AT+CRSM=192, %d", ef); /*command - 192 : GET RESPONSE*/
- dbg("Command: [%s] Command length: [%d]", cmd_str, strlen(cmd_str));
-
- pending = tcore_at_pending_new(o, cmd_str, "+CRSM:", TCORE_AT_SINGLELINE, _response_get_file_info, NULL);
- tcore_pending_link_user_request(pending, ur);
- ret = tcore_hal_send_request(hal, pending);
- if (TCORE_RETURN_SUCCESS != ret) {
- tcore_user_request_free(ur);
- }
-
- g_free(cmd_str);
- dbg("Exit");
- 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)
-{
- TcoreHal *hal = NULL;
- TcoreATRequest *req = NULL;
- TcorePending *pending = NULL;
- char *cmd_str = NULL;
- int p1 = 0;
- int p2 = 0;
- int p3 = 0;
-
- dbg("Entry");
- hal = tcore_object_get_hal(o);
- pending = tcore_pending_new(o, 0);
-
- dbg("file_id: %x", ef);
-
- p1 = (unsigned char) (offset & 0xFF00) >> 8;
- p2 = (unsigned char) offset & 0x00FF; // offset low
- p3 = (unsigned char) length;
-
- cmd_str = g_strdup_printf("AT+CRSM=176, %d, %d, %d, %d", ef, p1, p2, p3); /*command - 176 : READ BINARY*/
-
- req = tcore_at_request_new(cmd_str, "+CRSM:", TCORE_AT_SINGLELINE);
- g_free(cmd_str);
-
- dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
- req->cmd, req->prefix, strlen(req->cmd));
-
- tcore_pending_set_request_data(pending, 0, req);
- tcore_pending_set_response_callback(pending, _response_get_file_data, hal);
- tcore_pending_link_user_request(pending, ur);
- tcore_hal_send_request(hal, pending);
-
- dbg("Exit");
- return TRUE;
-}
-
-static gboolean _get_file_record(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef, const int index, const int length)
-{
- TcoreHal *hal = NULL;
- TcoreATRequest *req = NULL;
- TcorePending *pending = NULL;
- char *cmd_str = NULL;
- int p1 = 0;
- int p2 = 0;
- int p3 = 0;
-
- dbg("Entry");
-
- hal = tcore_object_get_hal(o);
- pending = tcore_pending_new(o, 0);
-
- p1 = (unsigned char) index;
- p2 = (unsigned char) 0x04; /* 0x4 for absolute mode */
- p3 = (unsigned char) length;
-
- cmd_str = g_strdup_printf("AT+CRSM=178, %d, %d, %d, %d", ef, p1, p2, p3); /*command - 178 : READ RECORD*/
-
- req = tcore_at_request_new(cmd_str, "+CRSM:", TCORE_AT_SINGLELINE);
- g_free(cmd_str);
-
- dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
- req->cmd, req->prefix, strlen(req->cmd));
-
- tcore_pending_set_request_data(pending, 0, req);
- tcore_pending_set_response_callback(pending, _response_get_file_data, hal);
- tcore_pending_link_user_request(pending, ur);
- tcore_hal_send_request(hal, pending);
-
- dbg("Exit");
- return TRUE;
-}
-
-static TReturn _get_retry_count(CoreObject *o, UserRequest *ur)
-{
- TcoreHal *hal = NULL;
- TcoreATRequest *req = NULL;
- TcorePending *pending = NULL;
- char *cmd_str = NULL;
- int lock_type = 0;
- struct s_sim_property *sp = NULL;
- const struct treq_sim_get_lock_info *req_data = NULL;
-
- dbg("Entry");
-
- hal = tcore_object_get_hal(o);
- pending = tcore_pending_new(o, 0);
- req_data = tcore_user_request_ref_data(ur, NULL);
- sp = tcore_sim_ref_userdata(o);
-
- switch (sp->current_sec_op) {
- case SEC_PIN1_VERIFY:
- case SEC_PIN1_CHANGE:
- case SEC_PIN1_ENABLE:
- case SEC_PIN1_DISABLE:
- lock_type = 1;
- break;
-
- case SEC_PIN2_VERIFY:
- case SEC_PIN2_CHANGE:
- case SEC_PIN2_ENABLE:
- case SEC_PIN2_DISABLE:
- case SEC_FDN_ENABLE:
- case SEC_FDN_DISABLE:
- lock_type = 2;
- break;
-
- case SEC_PUK1_VERIFY:
- lock_type = 3;
- break;
-
- case SEC_PUK2_VERIFY:
- lock_type = 4;
- break;
-
- case SEC_NET_ENABLE:
- case SEC_NET_DISABLE:
- lock_type = 5;
- break;
-
- case SEC_NS_ENABLE:
- case SEC_NS_DISABLE:
- lock_type = 6;
- break;
-
- case SEC_SP_ENABLE:
- case SEC_SP_DISABLE:
- lock_type = 7;
- break;
-
- case SEC_CP_ENABLE:
- case SEC_CP_DISABLE:
- lock_type = 8;
- break;
-
- case SEC_ADM_VERIFY:
- lock_type = 9;
- break;
-
- default:
- break;
- }
-
- cmd_str = g_strdup_printf("AT+XPINCNT=%d", lock_type);
- req = tcore_at_request_new(cmd_str, "+XPINCNT:", TCORE_AT_SINGLELINE);
- g_free(cmd_str);
-
- dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
- req->cmd, req->prefix, strlen(req->cmd));
-
- tcore_pending_set_request_data(pending, 0, req);
- tcore_pending_set_response_callback(pending, _on_response_get_retry_count, hal);
- tcore_pending_link_user_request(pending, ur);
- tcore_hal_send_request(hal, pending);
-
- dbg("Exit");
- return TCORE_RETURN_SUCCESS;
-}
-
-static gboolean on_event_facility_lock_status(CoreObject *o, const void *event_info, void *user_data)
-{
- struct s_sim_property *sp = NULL;
- char *line = NULL;
- GSList *tokens = NULL;
- GSList *lines = NULL;
-
- dbg("Function entry");
- return TRUE;
-
- sp = tcore_sim_ref_userdata(o);
- lines = (GSList *)event_info;
- if (1 != g_slist_length(lines)) {
- dbg("unsolicited msg but multiple line");
- goto OUT;
- }
- line = (char *)(lines->data);
- tokens = tcore_at_tok_new(line);
- if (g_slist_length(tokens) != 1) {
- msg("Invalid message");
- tcore_at_tok_free(tokens);
- return TRUE;
- }
-
-OUT:
- dbg("Exit");
- if (NULL != tokens)
- tcore_at_tok_free(tokens);
- return TRUE;
-}
-
-static void notify_sms_state(TcorePlugin *plugin, CoreObject *co_sim,
- gboolean sms_ready)
-{
- Server *server = tcore_plugin_ref_server(plugin);
- struct tnoti_sms_ready_status sms_ready_noti;
- CoreObject *co_sms;
-
- dbg("Entry");
-
- co_sms = tcore_plugin_ref_core_object(plugin, CORE_OBJECT_TYPE_SMS);
- if (co_sms == NULL) {
- err("Can't find SMS core object");
- return;
- }
-
- if (tcore_sms_get_ready_status(co_sms) == sms_ready)
- return;
-
- tcore_sms_set_ready_status(co_sms, sms_ready);
-
- if (tcore_sim_get_status(co_sim) == SIM_STATUS_INIT_COMPLETED) {
- sms_ready_noti.status = sms_ready;
- tcore_server_send_notification(server, co_sms,
- TNOTI_SMS_DEVICE_READY,
- sizeof(sms_ready_noti),
- &sms_ready_noti);
- }
-
- dbg("Exit");
-}
-
-static gboolean on_event_pin_status(CoreObject *o, const void *event_info, void *user_data)
-{
- TcorePlugin *plugin = tcore_object_ref_plugin(o);
- enum tel_sim_status sim_status = SIM_STATUS_INITIALIZING;
- GSList *tokens = NULL;
- GSList *lines;
- const char *line;
- int sim_state = 0;
- int sms_state = 0;
-
- dbg("Entry");
-
- lines = (GSList *)event_info;
- if (g_slist_length(lines) != 1) {
- err("Unsolicited message BUT multiple lines");
- goto out;
- }
-
- line = lines->data;
-
- /* Create 'tokens' */
- tokens = tcore_at_tok_new(line);
-
- /* SIM State */
- if (g_slist_length(tokens) == 4) {
- sim_state = atoi(g_slist_nth_data(tokens, 1));
- sms_state = atoi(g_slist_nth_data(tokens, 3));
- notify_sms_state(plugin, o, (sms_state > 0));
- } else if (g_slist_length(tokens) == 1) {
- sim_state = atoi(g_slist_nth_data(tokens, 0));
- } else {
- err("Invalid message");
- goto out;
- }
-
- switch (sim_state) {
- case 0:
- sim_status = SIM_STATUS_CARD_NOT_PRESENT;
- dbg("NO SIM");
- break;
-
- case 1:
- sim_status = SIM_STATUS_PIN_REQUIRED;
- dbg("PIN REQUIRED");
- break;
-
- case 2:
- sim_status = SIM_STATUS_INITIALIZING;
- dbg("PIN DISABLED AT BOOT UP");
- break;
-
- case 3:
- sim_status = SIM_STATUS_INITIALIZING;
- dbg("PIN VERIFIED");
- break;
-
- case 4:
- sim_status = SIM_STATUS_PUK_REQUIRED;
- dbg("PUK REQUIRED");
- break;
-
- case 5:
- sim_status = SIM_STATUS_CARD_BLOCKED;
- dbg("CARD PERMANENTLY BLOCKED");
- break;
-
- case 6:
- sim_status = SIM_STATUS_CARD_ERROR;
- dbg("SIM CARD ERROR");
- break;
-
- case 7:
- sim_status = SIM_STATUS_INIT_COMPLETED;
- dbg("SIM INIT COMPLETED");
- break;
-
- case 8:
- sim_status = SIM_STATUS_CARD_ERROR;
- dbg("SIM CARD ERROR");
- break;
-
- case 9:
- sim_status = SIM_STATUS_CARD_REMOVED;
- dbg("SIM REMOVED");
- break;
-
- case 12:
- dbg("SIM SMS Ready");
- notify_sms_state(plugin, o, TRUE);
- goto out;
-
- case 99:
- sim_status = SIM_STATUS_UNKNOWN;
- dbg("SIM STATE UNKNOWN");
- break;
-
- default:
- err("Unknown/Unsupported SIM state: [%d]", sim_state);
- goto out;
- }
-
- switch (sim_status) {
- case SIM_STATUS_INIT_COMPLETED:
- dbg("[SIM] SIM INIT COMPLETED");
- if (tcore_sim_get_type(o) == SIM_TYPE_UNKNOWN) {
- _get_sim_type(o);
- goto out;
- }
-
- break;
-
- case SIM_STATUS_CARD_REMOVED:
- dbg("[SIM] SIM CARD REMOVED");
- tcore_sim_set_type(o, SIM_TYPE_UNKNOWN);
- break;
-
- case SIM_STATUS_CARD_NOT_PRESENT:
- dbg("[SIM] SIM CARD NOT PRESENT");
- tcore_sim_set_type(o, SIM_TYPE_UNKNOWN);
- break;
-
- case SIM_STATUS_CARD_ERROR:
- dbg("[SIM] SIM CARD ERROR");
- tcore_sim_set_type(o, SIM_TYPE_UNKNOWN);
- break;
-
- default:
- dbg("SIM Status: [0x%02x]", sim_status);
- break;
- }
-
- _sim_status_update(o, sim_status);
-
-out:
- tcore_at_tok_free(tokens);
-
- dbg("Exit");
- return TRUE;
-}
-
-static void on_response_get_sim_status(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- const TcoreATResponse *resp = data;
- CoreObject *co_sim = NULL;
-
- dbg("Entry");
-
- co_sim = tcore_pending_ref_core_object(p);
-
- if (resp->success > 0) {
- dbg("RESPONSE OK");
- if (resp->lines)
- on_event_pin_status(co_sim, resp->lines, NULL);
- } else {
- dbg("RESPONSE NOK");
- }
-
- dbg("Exit");
-}
-
-static enum tcore_hook_return on_hook_modem_power(Server *s, CoreObject *source, enum tcore_notification_command command,
- unsigned int data_len, void *data, void *user_data)
-{
- TcorePlugin *plugin = tcore_object_ref_plugin(source);
- CoreObject *co_sim = tcore_plugin_ref_core_object(plugin, CORE_OBJECT_TYPE_SIM);
-
- if (co_sim == NULL)
- return TCORE_HOOK_RETURN_CONTINUE;
-
- dbg("Get SIM status");
-
- sim_prepare_and_send_pending_request(co_sim, "AT+XSIMSTATE?", "+XSIMSTATE:", TCORE_AT_SINGLELINE, on_response_get_sim_status);
-
- return TCORE_HOOK_RETURN_CONTINUE;
-}
-
-static void on_response_verify_pins(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- const TcoreATResponse *resp = data;
- UserRequest *ur = NULL;
- CoreObject *co_sim = NULL;
- struct s_sim_property *sp = NULL;
- GSList *tokens = NULL;
- struct tresp_sim_verify_pins res;
- GQueue *queue = NULL;
- const char *line;
- int err;
-
- dbg("Entry");
-
- co_sim = tcore_pending_ref_core_object(p);
- sp = tcore_sim_ref_userdata(co_sim);
- ur = tcore_pending_ref_user_request(p);
-
- memset(&res, 0, sizeof(struct tresp_sim_verify_pins));
-
- if (resp->success > 0) {
- dbg("RESPONSE OK");
- res.result = SIM_PIN_OPERATION_SUCCESS;
-
- /* Get PIN facility */
- res.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
- if ((res.pin_type == SIM_PTYPE_PIN1)
- || (res.pin_type == SIM_PTYPE_SIM)) {
- if (tcore_sim_get_status(co_sim) != SIM_STATUS_INIT_COMPLETED) {
- /* Update SIM Status */
- _sim_status_update(co_sim, SIM_STATUS_INITIALIZING);
- }
- }
-
- /* Send Response */
- tcore_user_request_send_response(ur, _find_resp_command(ur),
- sizeof(struct tresp_sim_verify_pins), &res);
- } else {
- dbg("RESPONSE NOK");
- line = (const char *)resp->final_response;
- tokens = tcore_at_tok_new(line);
- if (g_slist_length(tokens) < 1) {
- dbg("Unkown Error OR String corrupted");
- res.result = TCORE_RETURN_3GPP_ERROR;
-
- /* Send Response */
- tcore_user_request_send_response(ur, _find_resp_command(ur),
- sizeof(struct tresp_sim_verify_pins), &res);
- } else {
- err = atoi(g_slist_nth_data(tokens, 0));
- dbg("Error: [%d]", err);
-
- queue = tcore_object_ref_user_data(co_sim);
- ur = tcore_user_request_ref(ur);
-
- /* Get retry count */
- _get_retry_count(co_sim, ur);
- }
-
- /* Free tokens */
- tcore_at_tok_free(tokens);
- }
-
- dbg("Exit");
-}
-
-static void on_response_verify_puks(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- const TcoreATResponse *resp = data;
- UserRequest *ur = NULL;
- CoreObject *co_sim = NULL;
- struct s_sim_property *sp = NULL;
- GSList *tokens = NULL;
- struct tresp_sim_verify_puks res;
- GQueue *queue = NULL;
- const char *line;
- int err;
-
- dbg("Entry");
-
- co_sim = tcore_pending_ref_core_object(p);
- sp = tcore_sim_ref_userdata(co_sim);
- ur = tcore_pending_ref_user_request(p);
-
- memset(&res, 0, sizeof(struct tresp_sim_verify_pins));
-
- if (resp->success > 0) {
- dbg("RESPONSE OK");
- res.result = SIM_PIN_OPERATION_SUCCESS;
- res.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
-
- /* Send Response */
- tcore_user_request_send_response(ur, _find_resp_command(ur),
- sizeof(struct tresp_sim_verify_pins), &res);
- } else {
- dbg("RESPONSE NOK");
- line = (const char *)resp->final_response;
- tokens = tcore_at_tok_new(line);
-
- if (g_slist_length(tokens) < 1) {
- dbg("Unkown Error OR String corrupted");
- res.result = TCORE_RETURN_3GPP_ERROR;
-
- /* Send Response */
- tcore_user_request_send_response(ur, _find_resp_command(ur),
- sizeof(struct tresp_sim_verify_pins), &res);
- } else {
- err = atoi(g_slist_nth_data(tokens, 0));
- queue = tcore_object_ref_user_data(co_sim);
- ur = tcore_user_request_ref(ur);
- _get_retry_count(co_sim, ur);
- }
- tcore_at_tok_free(tokens);
- }
- dbg("Exit");
-}
-
-static void on_response_change_pins(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- const TcoreATResponse *resp = data;
- UserRequest *ur = NULL;
- CoreObject *co_sim = NULL;
- struct s_sim_property *sp = NULL;
- GSList *tokens = NULL;
- struct tresp_sim_change_pins res;
- GQueue *queue;
- const char *line;
- int err;
-
- dbg("Entry");
-
- co_sim = tcore_pending_ref_core_object(p);
- sp = tcore_sim_ref_userdata(co_sim);
- ur = tcore_pending_ref_user_request(p);
-
- memset(&res, 0, sizeof(struct tresp_sim_change_pins));
-
- if (resp->success > 0) {
- dbg("RESPONSE OK");
- res.result = SIM_PIN_OPERATION_SUCCESS;
- res.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
-
- /* Send Response */
- tcore_user_request_send_response(ur, _find_resp_command(ur),
- sizeof(struct tresp_sim_change_pins), &res);
- } else {
- dbg("RESPONSE NOK");
- line = (const char *)resp->final_response;
- tokens = tcore_at_tok_new(line);
-
- if (g_slist_length(tokens) < 1) {
- dbg("Unkown Error OR String corrupted");
- res.result = TCORE_RETURN_3GPP_ERROR;
-
- /* Send Response */
- tcore_user_request_send_response(ur, _find_resp_command(ur),
- sizeof(struct tresp_sim_change_pins), &res);
- } else {
- err = atoi(g_slist_nth_data(tokens, 0));
- queue = tcore_object_ref_user_data(co_sim);
- ur = tcore_user_request_ref(ur);
- _get_retry_count(co_sim, ur);
- }
-
- /* Free tokens */
- tcore_at_tok_free(tokens);
- }
- dbg("Exit");
-}
-
-static void on_response_get_facility_status(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- const TcoreATResponse *resp = data;
- UserRequest *ur = NULL;
- GSList *tokens = NULL;
- struct tresp_sim_get_facility_status *res = user_data;
- const char *line;
-
- dbg("Entry");
-
- ur = tcore_pending_ref_user_request(p);
-
- res->result = SIM_PIN_OPERATION_SUCCESS;
-
- 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) != 1) {
- msg("Invalid message");
- tcore_at_tok_free(tokens);
- return;
- }
- }
- res->b_enable = atoi(g_slist_nth_data(tokens, 0));
- } else {
- dbg("RESPONSE NOK");
- res->result = SIM_INCOMPATIBLE_PIN_OPERATION;
- }
-
- /* Send Response */
- if (ur) {
- tcore_user_request_send_response(ur, _find_resp_command(ur),
- sizeof(struct tresp_sim_get_facility_status), res);
- }
- tcore_at_tok_free(tokens);
- g_free(res);
- dbg("Exit");
-}
-
-static void on_response_enable_facility(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- const TcoreATResponse *resp = data;
- UserRequest *ur = NULL;
- CoreObject *co_sim = NULL;
- struct s_sim_property *sp = NULL;
- GSList *tokens = NULL;
- struct tresp_sim_enable_facility res;
- GQueue *queue;
- const char *line;
-
- dbg("Entry");
-
- co_sim = tcore_pending_ref_core_object(p);
- sp = tcore_sim_ref_userdata(co_sim);
- ur = tcore_pending_ref_user_request(p);
-
- memset(&res, 0, sizeof(struct tresp_sim_enable_facility));
-
- res.result = SIM_CARD_ERROR;
- res.type = _sim_get_current_pin_facility(sp->current_sec_op);
-
- 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) != 1) {
- msg("Invalid message");
-
- /* Send Response */
- tcore_user_request_send_response(ur, _find_resp_command(ur),
- sizeof(struct tresp_sim_enable_facility), &res);
- tcore_at_tok_free(tokens);
- return;
- }
- }
-
- res.result = SIM_PIN_OPERATION_SUCCESS;
-
- /* Send Response */
- if (ur) {
- tcore_user_request_send_response(ur, _find_resp_command(ur),
- sizeof(struct tresp_sim_enable_facility), &res);
- }
-
- /* Free tokens */
- tcore_at_tok_free(tokens);
- } else {
- dbg("RESPONSE NOK");
- queue = tcore_object_ref_user_data(co_sim);
- ur = tcore_user_request_ref(ur);
- _get_retry_count(co_sim, ur);
- }
- dbg("Exit");
-}
-
-static void on_response_disable_facility(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- const TcoreATResponse *resp = data;
- UserRequest *ur = NULL;
- CoreObject *co_sim = NULL;
- struct s_sim_property *sp = NULL;
- GSList *tokens = NULL;
- struct tresp_sim_disable_facility res;
- GQueue *queue;
- const char *line;
-
- dbg("Entry");
-
- co_sim = tcore_pending_ref_core_object(p);
- sp = tcore_sim_ref_userdata(co_sim);
- ur = tcore_pending_ref_user_request(p);
-
- memset(&res, 0, sizeof(struct tresp_sim_disable_facility));
-
- res.result = SIM_CARD_ERROR;
- res.type = _sim_get_current_pin_facility(sp->current_sec_op);
-
- 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) != 1) {
- msg("Invalid message");
-
- /* Send Response */
- tcore_user_request_send_response(ur, _find_resp_command(ur),
- sizeof(struct tresp_sim_disable_facility), &res);
- tcore_at_tok_free(tokens);
- return;
- }
- }
-
- res.result = SIM_PIN_OPERATION_SUCCESS;
- /* Send Response */
- if (ur) {
- tcore_user_request_send_response(ur, _find_resp_command(ur),
- sizeof(struct tresp_sim_disable_facility), &res);
- }
-
- /* Free tokens */
- tcore_at_tok_free(tokens);
- } else {
- dbg("RESPONSE NOK");
- queue = tcore_object_ref_user_data(co_sim);
- ur = tcore_user_request_ref(ur);
- _get_retry_count(co_sim, ur);
- }
- dbg("Exit");
-}
-
-static void on_response_get_lock_info(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- const TcoreATResponse *resp = data;
- UserRequest *ur = NULL;
- CoreObject *co_sim = NULL;
- struct s_sim_property *sp = NULL;
- GSList *tokens = NULL;
- const char *line;
- int lock_type;
- int attempts_left = 0;
- int time_penalty = 0;
-
- dbg("Entry");
-
- co_sim = tcore_pending_ref_core_object(p);
- sp = tcore_sim_ref_userdata(co_sim);
- ur = tcore_pending_ref_user_request(p);
-
- if (resp->success > 0) {
- dbg("RESPONSE OK");
- if (resp->lines) {
- line = (const char *)resp->lines->data;
- dbg("Line: [%s]", line);
- tokens = tcore_at_tok_new(line);
- if (g_slist_length(tokens) != 3) {
- msg("Invalid message");
- tcore_at_tok_free(tokens);
- return;
- }
- }
-
- lock_type = atoi(g_slist_nth_data(tokens, 0));
- attempts_left = atoi(g_slist_nth_data(tokens, 1));
- time_penalty = atoi(g_slist_nth_data(tokens, 2));
-
- switch (sp->current_sec_op) {
- case SEC_PIN1_VERIFY:
- case SEC_PIN2_VERIFY:
- case SEC_SIM_VERIFY:
- case SEC_ADM_VERIFY:
- {
- struct tresp_sim_verify_pins v_pin = {0, };
-
- v_pin.result = SIM_INCORRECT_PASSWORD;
- v_pin.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
- v_pin.retry_count = attempts_left;
- dbg("PIN Type: [0x%02x] Attempts left: [%d]",
- v_pin.pin_type, v_pin.retry_count);
-
- /* Send Response */
- tcore_user_request_send_response(ur, _find_resp_command(ur),
- sizeof(v_pin), &v_pin);
- }
- break;
-
- case SEC_PUK1_VERIFY:
- case SEC_PUK2_VERIFY:
- {
- struct tresp_sim_verify_puks v_puk = {0, };
-
- v_puk.result = SIM_INCORRECT_PASSWORD;
- v_puk.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
- v_puk.retry_count = attempts_left;
- dbg("PUK Type: [0x%02x] Attempts left: [%d]",
- v_puk.pin_type, v_puk.retry_count);
-
- /* Send Response */
- tcore_user_request_send_response(ur, _find_resp_command(ur),
- sizeof(v_puk), &v_puk);
- }
- break;
-
- case SEC_PIN1_CHANGE:
- case SEC_PIN2_CHANGE:
- {
- struct tresp_sim_change_pins change_pin = {0, };
-
- change_pin.result = SIM_INCORRECT_PASSWORD;
- change_pin.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
- change_pin.retry_count = attempts_left;
- dbg("PIN Type: [0x%02x] Attempts left: [%d]",
- change_pin.pin_type, change_pin.retry_count);
-
- /* Send Response */
- tcore_user_request_send_response(ur, _find_resp_command(ur),
- sizeof(change_pin), &change_pin);
- }
- break;
-
- case SEC_PIN1_DISABLE:
- case SEC_PIN2_DISABLE:
- case SEC_FDN_DISABLE:
- case SEC_SIM_DISABLE:
- case SEC_NET_DISABLE:
- case SEC_NS_DISABLE:
- case SEC_SP_DISABLE:
- case SEC_CP_DISABLE:
- {
- struct tresp_sim_disable_facility dis_facility = {0, };
-
- dis_facility.result = SIM_INCORRECT_PASSWORD;
- dis_facility.type = _sim_get_current_pin_facility(sp->current_sec_op);
- dis_facility.retry_count = attempts_left;
- dbg("Facility Type: [0x%02x] Attempts left: [%d]",
- dis_facility.type, dis_facility.retry_count);
-
- /* Send Response */
- tcore_user_request_send_response(ur, _find_resp_command(ur),
- sizeof(dis_facility), &dis_facility);
- }
- break;
-
- case SEC_PIN1_ENABLE:
- case SEC_PIN2_ENABLE:
- case SEC_FDN_ENABLE:
- case SEC_SIM_ENABLE:
- case SEC_NET_ENABLE:
- case SEC_NS_ENABLE:
- case SEC_SP_ENABLE:
- case SEC_CP_ENABLE:
- {
- struct tresp_sim_enable_facility en_facility = {0, };
-
- en_facility.result = SIM_INCORRECT_PASSWORD;
- en_facility.type = _sim_get_current_pin_facility(sp->current_sec_op);
- en_facility.retry_count = attempts_left;
- dbg("Facility Type: [0x%02x] Attempts left: [%d]",
- en_facility.type, en_facility.retry_count);
-
- /* Send Response */
- tcore_user_request_send_response(ur, _find_resp_command(ur),
- sizeof(en_facility), &en_facility);
- }
- break;
-
- default:
- dbg("not handled sec op[%d]", sp->current_sec_op);
- break;
- }
-
- /* Free tokens */
- tcore_at_tok_free(tokens);
- }
- dbg("Exit");
-}
-
-static void on_response_update_file(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- const TcoreATResponse *resp = data;
- UserRequest *ur = NULL;
- CoreObject *co_sim = NULL;
- struct tresp_sim_set_data resp_cf = {0, };
- struct tresp_sim_set_data resp_language = {0, };
- struct s_sim_property *sp = NULL;
- GSList *tokens = NULL;
- enum tel_sim_access_result result = SIM_CARD_ERROR;
- const char *line;
- int sw1 = 0;
- int sw2 = 0;
-
- dbg("Entry");
-
- co_sim = tcore_pending_ref_core_object(p);
- ur = tcore_pending_ref_user_request(p);
- sp = (struct s_sim_property *)tcore_user_request_ref_metainfo(ur, NULL);
-
- 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");
- 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) {
- result = SIM_ACCESS_SUCCESS;
- } else {
- result = _decode_status_word(sw1, sw2);
- }
- } else {
- dbg("RESPONSE NOK");
- result = SIM_ACCESS_FAILED;
- }
-OUT:
- switch (sp->file_id) {
- case SIM_EF_CPHS_CALL_FORWARD_FLAGS:
- case SIM_EF_USIM_CFIS:
- resp_cf.result = result;
-
- /* Send Response */
- tcore_user_request_send_response(ur, _find_resp_command(ur),
- sizeof(struct tresp_sim_set_data), &resp_cf);
- break;
-
- case SIM_EF_ELP:
- case SIM_EF_LP:
- case SIM_EF_USIM_LI:
- case SIM_EF_USIM_PL:
- resp_language.result = result;
-
- /* Send Response */
- tcore_user_request_send_response(ur, _find_resp_command(ur),
- sizeof(struct tresp_sim_set_data), &resp_language);
- break;
-
- default:
- dbg("Invalid File ID - %d", sp->file_id);
- break;
- }
- tcore_at_tok_free(tokens);
- dbg("Exit");
-}
-
-static void on_response_transmit_apdu(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- const TcoreATResponse *resp = data;
- UserRequest *ur = NULL;
- CoreObject *co_sim = NULL;
- GSList *tokens = NULL;
- struct tresp_sim_transmit_apdu res;
- const char *line;
-
- dbg("Entry");
-
- co_sim = tcore_pending_ref_core_object(p);
- ur = tcore_pending_ref_user_request(p);
-
- memset(&res, 0, sizeof(struct tresp_sim_transmit_apdu));
- res.result = SIM_ACCESS_FAILED;
-
- if (resp->success > 0) {
- dbg("RESPONSE OK");
- if (resp->lines) {
- char *tmp = NULL;
- char *decoded_data = NULL;
- line = (const char *)resp->lines->data;
- tokens = tcore_at_tok_new(line);
- if (g_slist_length(tokens) != 2) {
- msg("Invalid message");
- goto OUT;
- }
- res.apdu_resp_length = atoi(g_slist_nth_data(tokens, 0)) / 2;
-
- tmp = util_removeQuotes(g_slist_nth_data(tokens, 1));
- decoded_data = util_hexStringToBytes(tmp);
-
- memcpy((char *)res.apdu_resp, decoded_data, res.apdu_resp_length);
- g_free(tmp);
- g_free(decoded_data);
- res.result = SIM_ACCESS_SUCCESS;
- }
- } else {
- dbg("RESPONSE NOK");
- }
-
-OUT:
- /* Send Response */
- if (ur) {
- tcore_user_request_send_response(ur, _find_resp_command(ur),
- sizeof(struct tresp_sim_transmit_apdu), &res);
- }
- tcore_at_tok_free(tokens);
- dbg("Exit");
-}
-
-static void on_response_get_atr(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- const TcoreATResponse *resp = data;
- UserRequest *ur = NULL;
- GSList *tokens = NULL;
- struct tresp_sim_get_atr res;
- const char *line;
-
- dbg("Entry");
-
- memset(&res, 0, sizeof(struct tresp_sim_get_atr));
- ur = tcore_pending_ref_user_request(p);
-
- res.result = SIM_ACCESS_FAILED;
- if (resp->success > 0) {
- dbg("RESPONSE OK");
- if (resp->lines) {
- char *tmp = NULL;
- char *decoded_data = NULL;
- line = (const char *)resp->lines->data;
- tokens = tcore_at_tok_new(line);
- if (g_slist_length(tokens) < 1) {
- msg("Invalid message");
- goto OUT;
- }
-
- tmp = util_removeQuotes(g_slist_nth_data(tokens, 0));
- decoded_data = util_hexStringToBytes(tmp);
-
- res.atr_length = strlen(tmp) / 2;
- memcpy((char *)res.atr, decoded_data, res.atr_length);
- g_free(tmp);
- g_free(decoded_data);
- res.result = SIM_ACCESS_SUCCESS;
- }
- } else {
- dbg("RESPONSE NOK");
- }
-
-OUT:
- /* Send Response */
- if (ur) {
- tcore_user_request_send_response(ur, _find_resp_command(ur),
- sizeof(struct tresp_sim_get_atr), &res);
- }
- tcore_at_tok_free(tokens);
- dbg("Exit");
-}
-
-static void on_response_req_authentication(TcorePending *p, int data_len,
- const void *data, void *user_data)
-{
- const TcoreATResponse *at_resp = data;
- GSList *tokens = NULL;
- struct tresp_sim_req_authentication resp_auth;
- const struct treq_sim_req_authentication *req_data;
- UserRequest *ur = tcore_pending_ref_user_request(p);
-
- dbg("Entry");
-
- memset(&resp_auth, 0, sizeof(struct tresp_sim_req_authentication));
-
- if (at_resp == NULL) {
- err("at_resp is NULL");
- resp_auth.result = SIM_ACCESS_FAILED;
- resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
- goto out;
- }
-
- req_data = tcore_user_request_ref_data(ur, NULL);
- if (req_data == NULL) {
- err("req_data is NULL");
- resp_auth.result = SIM_ACCESS_FAILED;
- resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
- goto out;
- }
- resp_auth.auth_type = req_data->auth_type;
-
- if (at_resp->success == TRUE) {
- const char *line;
- int status;
-
- dbg("RESPONSE OK");
- if (at_resp->lines != NULL) {
- line = at_resp->lines->data;
- dbg("Received data: [%s]", line);
- } else {
- err("at_resp->lines is NULL");
- resp_auth.result = SIM_ACCESS_FAILED;
- resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
- goto out;
- }
-
- tokens = tcore_at_tok_new(line);
- if (tokens == NULL) {
- err("tokens is NULL");
- resp_auth.result = SIM_ACCESS_FAILED;
- resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
- goto out;
- }
-
- status = atoi(g_slist_nth_data(tokens, 0));
- switch (status) {
- case 0:
- dbg("Authentications successful");
- resp_auth.auth_result = SIM_AUTH_NO_ERROR;
- break;
- case 1:
- err("Synchronize fail");
- resp_auth.auth_result = SIM_AUTH_SYNCH_FAILURE;
- goto out;
- case 2:
- err("MAC wrong");
- resp_auth.auth_result = SIM_AUTH_MAK_CODE_FAILURE;
- goto out;
- case 3:
- err("Does not support security context");
- resp_auth.auth_result = SIM_AUTH_UNSUPPORTED_CONTEXT;
- goto out;
- default:
- err("Other failure");
- resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
- goto out;
- }
-
- if (resp_auth.auth_type == SIM_AUTH_TYPE_GSM) {
- char *kc, *sres;
- char *convert_kc, *convert_sres;
-
- kc = g_slist_nth_data(tokens, 1);
- if (kc != NULL) {
- kc = tcore_at_tok_extract(kc);
- dbg("Kc: [%s]", kc);
- convert_kc = util_hexStringToBytes(kc);
- if (convert_kc && strlen(convert_kc) <= SIM_AUTH_RESP_DATA_LEN_MAX) {
- resp_auth.authentication_key_length = strlen(convert_kc);
- memcpy(&resp_auth.authentication_key, convert_kc, strlen(convert_kc));
- } else {
- err("Invalid Kc");
- resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
- }
- g_free(kc);
- g_free(convert_kc);
- } else {
- err("Invalid Kc");
- resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
- goto out;
- }
-
- sres = g_slist_nth_data(tokens, 2);
- if (sres != NULL) {
- sres = tcore_at_tok_extract(sres);
- dbg("SRES: [%s]", sres);
- convert_sres = util_hexStringToBytes(sres);
- if (convert_sres && strlen(sres) <= SIM_AUTH_RESP_DATA_LEN_MAX) {
- resp_auth.resp_length = strlen(convert_sres);
- memcpy(&resp_auth.resp_data, convert_sres, strlen(convert_sres));
- } else {
- err("Invalid SRES");
- resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
- }
- g_free(sres);
- g_free(convert_sres);
- } else {
- err("Invalid SRES");
- resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
- goto out;
- }
- } else if (resp_auth.auth_type == SIM_AUTH_TYPE_3G) {
- char *res, *ck, *ik, *kc;
- char *convert_res, *convert_ck;
- char *convert_ik, *convert_kc;
-
- res = g_slist_nth_data(tokens, 1);
- if (res != NULL) {
- res = tcore_at_tok_extract(res);
- dbg("RES/AUTS: [%s]", res);
- convert_res = util_hexStringToBytes(res);
- if (convert_ck && strlen(res) <= SIM_AUTH_RESP_DATA_LEN_MAX) {
- resp_auth.resp_length = strlen(convert_res);
- memcpy(resp_auth.resp_data, convert_res, strlen(convert_res));
- } else {
- err("Invalid RES/AUTS");
- resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
- }
- g_free(res);
- g_free(convert_res);
- } else {
- err("Invalid RES/AUTS");
- resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
- goto out;
- }
-
- ck = g_slist_nth_data(tokens, 2);
- if (ck != NULL) {
- ck = tcore_at_tok_extract(ck);
- dbg("CK: [%s]", ck);
- convert_ck = util_hexStringToBytes(ck);
- if (convert_ck && strlen(ck) <= SIM_AUTH_RESP_DATA_LEN_MAX) {
- resp_auth.cipher_length = strlen(convert_ck);
- memcpy(&resp_auth.cipher_data, convert_ck, strlen(convert_ck));
- } else {
- err("Invalid CK");
- resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
- }
- g_free(ck);
- g_free(convert_ck);
- } else {
- err("Invalid CK");
- resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
- goto out;
- }
-
- ik = g_slist_nth_data(tokens, 3);
- if (ik != NULL) {
- ik = tcore_at_tok_extract(ik);
- dbg("IK: [%s]", ik);
- convert_ik = util_hexStringToBytes(ik);
- if (convert_ik && strlen(ik) <= SIM_AUTH_RESP_DATA_LEN_MAX) {
- resp_auth.integrity_length = strlen(convert_ik);
- memcpy(&resp_auth.integrity_data, convert_ik, strlen(convert_ik));
- } else {
- err("Invalid IK");
- resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
- }
- g_free(ik);
- g_free(convert_ik);
- } else {
- err("Invalid IK");
- resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
- goto out;
- }
-
- kc = g_slist_nth_data(tokens, 4);
- if (kc != NULL) {
- kc = tcore_at_tok_extract(kc);
- dbg("Kc: [%s]", kc);
- convert_kc = util_hexStringToBytes(kc);
- if (convert_kc && strlen(convert_kc) <= SIM_AUTH_RESP_DATA_LEN_MAX) {
- resp_auth.authentication_key_length = strlen(convert_kc);
- memcpy(&resp_auth.authentication_key, convert_kc, strlen(convert_kc));
- } else {
- err("Invalid Kc");
- resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
- }
- g_free(kc);
- g_free(convert_kc);
- } else {
- err("Invalid Kc");
- resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
- goto out;
- }
- } else if (resp_auth.auth_type == SIM_AUTH_TYPE_IMS) {
- err("Not supported");
- }
- } else {
- err("RESPONSE NOK");
- resp_auth.result = SIM_ACCESS_FAILED;
- resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
- }
-
-out:
- tcore_user_request_send_response(ur, TRESP_SIM_REQ_AUTHENTICATION,
- sizeof(struct tresp_sim_req_authentication), &resp_auth);
-
- tcore_at_tok_free(tokens);
-}
-
-static TReturn s_verify_pins(CoreObject *o, UserRequest *ur)
-{
- TcoreHal *hal = NULL;
- TcoreATRequest *req = NULL;
- TcorePending *pending = NULL;
- char *cmd_str = NULL;
- const struct treq_sim_verify_pins *req_data = NULL;
- struct s_sim_property *sp = NULL;
- TReturn ret = TCORE_RETURN_FAILURE;
-
- dbg("Entry");
-
- if ((o == NULL )|| (ur == NULL))
- return TCORE_RETURN_EINVAL;
-
- hal = tcore_object_get_hal(o);
- if (FALSE == tcore_hal_get_power_state(hal)) {
- err("CP NOT READY");
- return TCORE_RETURN_ENOSYS;
- }
-
- sp = tcore_sim_ref_userdata(o);
- pending = tcore_pending_new(o, 0);
- req_data = tcore_user_request_ref_data(ur, NULL);
-
- if (req_data->pin_type == SIM_PTYPE_PIN1) {
- sp->current_sec_op = SEC_PIN1_VERIFY;
- cmd_str = g_strdup_printf("AT+CPIN=\"%s\"", req_data->pin);
- } else if (req_data->pin_type == SIM_PTYPE_PIN2) {
- sp->current_sec_op = SEC_PIN2_VERIFY;
- cmd_str = g_strdup_printf("AT+CPIN2=\"%s\"", req_data->pin);
- } else if (req_data->pin_type == SIM_PTYPE_SIM) {
- sp->current_sec_op = SEC_SIM_VERIFY;
- cmd_str = g_strdup_printf("AT+CPIN=\"%s\"", req_data->pin);
- } else if (req_data->pin_type == SIM_PTYPE_ADM) {
- sp->current_sec_op = SEC_ADM_VERIFY;
- cmd_str = g_strdup_printf("AT+CPIN=\"%s\"", req_data->pin);
- } else {
- return TCORE_RETURN_EINVAL;
- }
-
- req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
- g_free(cmd_str);
-
- dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
- req->cmd, req->prefix, strlen(req->cmd));
-
- tcore_pending_set_request_data(pending, 0, req);
- tcore_pending_set_response_callback(pending, on_response_verify_pins, hal);
- tcore_pending_link_user_request(pending, ur);
- ret = tcore_hal_send_request(hal, pending);
-
- dbg("Exit");
- return ret;
-}
-
-static TReturn s_verify_puks(CoreObject *o, UserRequest *ur)
-{
- TcoreHal *hal = NULL;
- TcoreATRequest *req = NULL;
- TcorePending *pending = NULL;
- char *cmd_str = NULL;
- const struct treq_sim_verify_puks *req_data;
- struct s_sim_property *sp = NULL;
- TReturn ret = TCORE_RETURN_FAILURE;
-
- dbg("Entry");
-
- if ((o == NULL )|| (ur == NULL))
- return TCORE_RETURN_EINVAL;
-
- hal = tcore_object_get_hal(o);
- if (FALSE == tcore_hal_get_power_state(hal)) {
- err("CP NOT READY");
- return TCORE_RETURN_ENOSYS;
- }
-
- sp = tcore_sim_ref_userdata(o);
- pending = tcore_pending_new(o, 0);
- req_data = tcore_user_request_ref_data(ur, NULL);
-
- if (req_data->puk_type == SIM_PTYPE_PUK1) {
- sp->current_sec_op = SEC_PUK1_VERIFY;
- cmd_str = g_strdup_printf("AT+CPIN=\"%s\", \"%s\"", req_data->puk, req_data->pin);
- } else if (req_data->puk_type == SIM_PTYPE_PUK2) {
- sp->current_sec_op = SEC_PUK2_VERIFY;
- cmd_str = g_strdup_printf("AT+CPIN2=\"%s\", \"%s\"", req_data->puk, req_data->pin);
- } else {
- return TCORE_RETURN_EINVAL;
- }
-
- req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
- g_free(cmd_str);
-
- dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
- req->cmd, req->prefix, strlen(req->cmd));
-
- tcore_pending_set_request_data(pending, 0, req);
- tcore_pending_set_response_callback(pending, on_response_verify_puks, hal);
- tcore_pending_link_user_request(pending, ur);
- ret = tcore_hal_send_request(hal, pending);
-
- dbg("Exit");
- return ret;
-}
-
-static TReturn s_change_pins(CoreObject *o, UserRequest *ur)
-{
- TcoreHal *hal = NULL;
- TcoreATRequest *req = NULL;
- TcorePending *pending = NULL;
- char *cmd_str = NULL;
- const struct treq_sim_change_pins *req_data;
- struct s_sim_property *sp = NULL;
- char *pin1 = "SC";
- char *pin2 = "P2";
- TReturn ret = TCORE_RETURN_FAILURE;
-
- dbg("Entry");
-
- if ((o == NULL )|| (ur == NULL))
- return TCORE_RETURN_EINVAL;
-
- hal = tcore_object_get_hal(o);
- if (FALSE == tcore_hal_get_power_state(hal)) {
- err("CP NOT READY");
- return TCORE_RETURN_ENOSYS;
- }
-
- sp = tcore_sim_ref_userdata(o);
- pending = tcore_pending_new(o, 0);
- req_data = tcore_user_request_ref_data(ur, NULL);
-
- if (req_data->type == SIM_PTYPE_PIN1) {
- sp->current_sec_op = SEC_PIN1_CHANGE;
- cmd_str = g_strdup_printf("AT+CPWD=\"%s\",\"%s\",\"%s\"", pin1, req_data->old_pin, req_data->new_pin);
- } else if (req_data->type == SIM_PTYPE_PIN2) {
- sp->current_sec_op = SEC_PIN2_CHANGE;
- cmd_str = g_strdup_printf("AT+CPWD=\"%s\",\"%s\",\"%s\"", pin2, req_data->old_pin, req_data->new_pin);
- } else {
- return TCORE_RETURN_EINVAL;
- }
- req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
- g_free(cmd_str);
-
- dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
- req->cmd, req->prefix, strlen(req->cmd));
-
- tcore_pending_set_request_data(pending, 0, req);
- tcore_pending_set_response_callback(pending, on_response_change_pins, hal);
- tcore_pending_link_user_request(pending, ur);
- ret = tcore_hal_send_request(hal, pending);
-
- dbg("Exit");
- return ret;
-}
-
-static TReturn s_get_facility_status(CoreObject *o, UserRequest *ur)
-{
- TcoreHal *hal = NULL;
- TcoreATRequest *req = NULL;
- TcorePending *pending = NULL;
- char *cmd_str = NULL;
- const struct treq_sim_get_facility_status *req_data;
- struct tresp_sim_get_facility_status *res;
- char *fac = "SC";
- int mode = 2; /* 0:unlock, 1:lock, 2:query*/
- TReturn ret = TCORE_RETURN_FAILURE;
-
- dbg("Entry");
-
- if ((o == NULL )|| (ur == NULL))
- return TCORE_RETURN_EINVAL;
-
- hal = tcore_object_get_hal(o);
- if (FALSE == tcore_hal_get_power_state(hal)) {
- err("CP NOT READY");
- return TCORE_RETURN_ENOSYS;
- }
-
- pending = tcore_pending_new(o, 0);
- req_data = tcore_user_request_ref_data(ur, NULL);
-
- res = g_try_new0(struct tresp_sim_get_facility_status, 1);
- if (!res)
- return TCORE_RETURN_ENOMEM;
-
- res->type = req_data->type;
-
- if (req_data->type == SIM_FACILITY_PS) {
- fac = "PS"; /*PH-SIM, Lock PHone to SIM/UICC card*/
- } else if (req_data->type == SIM_FACILITY_SC) {
- fac = "SC"; /*Lock SIM/UICC card, simply PIN1*/
- } else if (req_data->type == SIM_FACILITY_FD) {
- fac = "FD"; /*Fixed Dialing Number feature, need PIN2*/
- } else if (req_data->type == SIM_FACILITY_PN) {
- fac = "PN"; /*Network Personalization*/
- } else if (req_data->type == SIM_FACILITY_PU) {
- fac = "PU"; /*network sUbset Personalization*/
- } else if (req_data->type == SIM_FACILITY_PP) {
- fac = "PP"; /*service Provider Personalization*/
- } else if (req_data->type == SIM_FACILITY_PC) {
- fac = "PC"; /*Corporate Personalization*/
- } else {
- return TCORE_RETURN_EINVAL;
- }
- cmd_str = g_strdup_printf("AT+CLCK=\"%s\", %d", fac, mode);
- req = tcore_at_request_new(cmd_str, "+CLCK:", TCORE_AT_SINGLELINE);
- g_free(cmd_str);
-
- dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
- req->cmd, req->prefix, strlen(req->cmd));
-
- tcore_pending_set_request_data(pending, 0, req);
- tcore_pending_set_response_callback(pending, on_response_get_facility_status, res);
- tcore_pending_link_user_request(pending, ur);
- ret = tcore_hal_send_request(hal, pending);
-
- dbg("Exit");
- return ret;
-}
-
-static TReturn s_enable_facility(CoreObject *o, UserRequest *ur)
-{
- TcoreHal *hal = NULL;
- TcoreATRequest *req = NULL;
- TcorePending *pending = NULL;
- char *cmd_str = NULL;
- const struct treq_sim_enable_facility *req_data;
- struct s_sim_property *sp = NULL;
- char *fac = "SC";
- int mode = 1; /* 0:unlock, 1:lock, 2:query*/
- TReturn ret = TCORE_RETURN_FAILURE;
-
- dbg("Entry");
-
- if ((o == NULL )|| (ur == NULL))
- return TCORE_RETURN_EINVAL;
-
- hal = tcore_object_get_hal(o);
- if (FALSE == tcore_hal_get_power_state(hal)) {
- err("CP NOT READY");
- return TCORE_RETURN_ENOSYS;
- }
-
- sp = tcore_sim_ref_userdata(o);
- pending = tcore_pending_new(o, 0);
- req_data = tcore_user_request_ref_data(ur, NULL);
-
- if (req_data->type == SIM_FACILITY_PS) {
- fac = "PS"; /*PH-SIM, Lock PHone to SIM/UICC card*/
- sp->current_sec_op = SEC_SIM_ENABLE;
- } else if (req_data->type == SIM_FACILITY_SC) {
- fac = "SC"; /*Lock SIM/UICC card, simply PIN1*/
- sp->current_sec_op = SEC_PIN1_ENABLE;
- } else if (req_data->type == SIM_FACILITY_FD) {
- fac = "FD"; /*Fixed Dialing Number feature, need PIN2*/
- sp->current_sec_op = SEC_FDN_ENABLE;
- } else if (req_data->type == SIM_FACILITY_PN) {
- fac = "PN"; /*Network Personalization*/
- sp->current_sec_op = SEC_NET_ENABLE;
- } else if (req_data->type == SIM_FACILITY_PU) {
- fac = "PU"; /*network sUbset Personalization*/
- sp->current_sec_op = SEC_NS_ENABLE;
- } else if (req_data->type == SIM_FACILITY_PP) {
- fac = "PP"; /*service Provider Personalization*/
- sp->current_sec_op = SEC_SP_ENABLE;
- } else if (req_data->type == SIM_FACILITY_PC) {
- fac = "PC"; /*Corporate Personalization*/
- sp->current_sec_op = SEC_CP_ENABLE;
- } else {
- return TCORE_RETURN_EINVAL;
- }
- cmd_str = g_strdup_printf("AT+CLCK=\"%s\", %d, \"%s\"", fac, mode, req_data->password);
- req = tcore_at_request_new(cmd_str, "+CLCK:", TCORE_AT_SINGLELINE);
- g_free(cmd_str);
-
- dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
- req->cmd, req->prefix, strlen(req->cmd));
-
- tcore_pending_set_request_data(pending, 0, req);
- tcore_pending_set_response_callback(pending, on_response_enable_facility, hal);
- tcore_pending_link_user_request(pending, ur);
- ret = tcore_hal_send_request(hal, pending);
-
- dbg("Exit");
- return ret;
-}
-
-static TReturn s_disable_facility(CoreObject *o, UserRequest *ur)
-{
- TcoreHal *hal;
- TcoreATRequest *req;
- TcorePending *pending = NULL;
- char *cmd_str = NULL;
- const struct treq_sim_enable_facility *req_data;
- struct s_sim_property *sp = NULL;
- char *fac = "SC";
- int mode = 0; /* 0:unlock, 1:lock, 2:query*/
- TReturn ret = TCORE_RETURN_FAILURE;
-
- dbg("Entry");
-
- if ((o == NULL )|| (ur == NULL))
- return TCORE_RETURN_EINVAL;
-
- hal = tcore_object_get_hal(o);
- if (FALSE == tcore_hal_get_power_state(hal)) {
- err("CP NOT READY");
- return TCORE_RETURN_ENOSYS;
- }
-
- sp = tcore_sim_ref_userdata(o);
- pending = tcore_pending_new(o, 0);
- req_data = tcore_user_request_ref_data(ur, NULL);
-
- if (req_data->type == SIM_FACILITY_PS) {
- fac = "PS"; /*PH-SIM, Lock PHone to SIM/UICC card*/
- sp->current_sec_op = SEC_SIM_DISABLE;
- } else if (req_data->type == SIM_FACILITY_SC) {
- fac = "SC"; /*Lock SIM/UICC card, simply PIN1*/
- sp->current_sec_op = SEC_PIN1_DISABLE;
- } else if (req_data->type == SIM_FACILITY_FD) {
- fac = "FD"; /*Fixed Dialing Number feature, need PIN2*/
- sp->current_sec_op = SEC_FDN_DISABLE;
- } else if (req_data->type == SIM_FACILITY_PN) {
- fac = "PN"; /*Network Personalization*/
- sp->current_sec_op = SEC_NET_DISABLE;
- } else if (req_data->type == SIM_FACILITY_PU) {
- fac = "PU"; /*network sUbset Personalization*/
- sp->current_sec_op = SEC_NS_DISABLE;
- } else if (req_data->type == SIM_FACILITY_PP) {
- fac = "PP"; /*service Provider Personalization*/
- sp->current_sec_op = SEC_SP_DISABLE;
- } else if (req_data->type == SIM_FACILITY_PC) {
- fac = "PC"; /*Corporate Personalization*/
- sp->current_sec_op = SEC_CP_DISABLE;
- } else {
- return TCORE_RETURN_EINVAL;
- }
- cmd_str = g_strdup_printf("AT+CLCK=\"%s\", %d, \"%s\"", fac, mode, req_data->password);
- req = tcore_at_request_new(cmd_str, "+CLCK:", TCORE_AT_SINGLELINE);
- g_free(cmd_str);
-
- dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
- req->cmd, req->prefix, strlen(req->cmd));
-
- tcore_pending_set_request_data(pending, 0, req);
- tcore_pending_set_response_callback(pending, on_response_disable_facility, hal);
- tcore_pending_link_user_request(pending, ur);
- ret = tcore_hal_send_request(hal, pending);
-
- dbg("Exit");
- return ret;
-}
-
-static TReturn s_get_lock_info(CoreObject *o, UserRequest *ur)
-{
- TcoreHal *hal = NULL;
- TcoreATRequest *req = NULL;
- TcorePending *pending = NULL;
- char *cmd_str = NULL;
- int lock_type = 0;
- const struct treq_sim_get_lock_info *req_data;
- struct s_sim_property *sp = NULL;
-
- dbg("Entry");
-
- hal = tcore_object_get_hal(o);
-
- sp = tcore_sim_ref_userdata(o);
- pending = tcore_pending_new(o, 0);
- req_data = tcore_user_request_ref_data(ur, NULL);
-
- if ((o == NULL )|| (ur == NULL))
- return TCORE_RETURN_EINVAL;
-
- switch (req_data->type) {
- case SIM_FACILITY_PS:
- lock_type = 9; // IMSI lock
- break;
-
- case SIM_FACILITY_SC:
- lock_type = 1;
- break;
-
- case SIM_FACILITY_FD:
- lock_type = 2;
- break;
-
- case SIM_FACILITY_PN:
- lock_type = 5;
- break;
-
- case SIM_FACILITY_PU:
- lock_type = 6;
- break;
-
- case SIM_FACILITY_PP:
- lock_type = 7;
- break;
-
- case SIM_FACILITY_PC:
- lock_type = 8;
- break;
-
- default:
- break;
- }
- cmd_str = g_strdup_printf("AT+XPINCNT=%d", lock_type);
- req = tcore_at_request_new(cmd_str, "+XPINCNT:", TCORE_AT_SINGLELINE);
- g_free(cmd_str);
-
- dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
- req->cmd, req->prefix, strlen(req->cmd));
-
- tcore_pending_set_request_data(pending, 0, req);
- tcore_pending_set_response_callback(pending, on_response_get_lock_info, hal);
- tcore_pending_link_user_request(pending, ur);
- tcore_hal_send_request(hal, pending);
-
- dbg("Exit");
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn s_read_file(CoreObject *o, UserRequest *ur)
-{
- TReturn api_ret = TCORE_RETURN_SUCCESS;
- enum tcore_request_command command;
-
- dbg("Entry");
-
- if ((o == NULL )|| (ur == NULL))
- return TCORE_RETURN_EINVAL;
-
- command = tcore_user_request_get_command(ur);
- if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
- err("CP NOT READY");
- return TCORE_RETURN_ENOSYS;
- }
-
- 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:
- api_ret = _get_file_info(o, ur, SIM_EF_CPHS_CPHS_INFO);
- 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;
- }
- dbg("Exit");
- return api_ret;
-}
-
-static TReturn s_update_file(CoreObject *o, UserRequest *ur)
-{
- TcoreHal *hal;
- char *cmd_str = NULL;
- TReturn ret = TCORE_RETURN_SUCCESS;
- char *encoded_data = NULL;
- int encoded_len = 0;
- enum tcore_request_command command;
- enum tel_sim_file_id ef = SIM_EF_INVALID;
- const struct treq_sim_set_callforwarding *cf;
- const struct treq_sim_set_language *cl;
- struct s_sim_property file_meta = {0, };
- int p1 = 0;
- int p2 = 0;
- int p3 = 0;
- int cmd = 0;
- int out_length = 0;
- int trt = 0;
- struct tel_sim_language sim_language;
- char *tmp = NULL;
- gboolean result;
-
- command = tcore_user_request_get_command(ur);
-
- dbg("Entry");
-
- if ((o == NULL )|| (ur == NULL)) {
- return TCORE_RETURN_EINVAL;
- }
-
- hal = tcore_object_get_hal(o);
- if (FALSE == tcore_hal_get_power_state(hal)) {
- err("CP NOT READY");
- return TCORE_RETURN_ENOSYS;
- }
-
- switch (command) {
- case TREQ_SIM_SET_LANGUAGE:
- cl = tcore_user_request_ref_data(ur, NULL);
- memset(&sim_language, 0x00, sizeof(struct tel_sim_language));
- cmd = 214;
-
- sim_language.language_count = 1;
- sim_language.language[0] = cl->language;
- dbg("language %d", cl->language);
-
- if (tcore_sim_get_type(o) == SIM_TYPE_GSM) {
- dbg("2G");
- ef = SIM_EF_LP;
- tmp = tcore_sim_encode_lp(&out_length, &sim_language);
-
- encoded_data = (char *)malloc(2 * (sim_language.language_count) + 1);
- memset(encoded_data, 0x00, (2 * sim_language.language_count) + 1);
- result = util_byte_to_hex(tmp, encoded_data, out_length);
-
- p1 = 0;
- p2 = 0;
- p3 = out_length;
- dbg("encoded_data - %s ---", encoded_data);
- dbg("out_length - %d ---", out_length);
- } else if (tcore_sim_get_type(o) == SIM_TYPE_USIM) {
- dbg("3G");
- ef = SIM_EF_LP;
- tmp = tcore_sim_encode_li(&out_length, &sim_language);
-
- encoded_data = (char *)malloc(2 * (out_length) + 1);
- memset(encoded_data, 0x00, (2 * out_length) + 1);
- result = util_byte_to_hex(tmp, encoded_data, out_length);
-
- p1 = 0;
- p2 = 0;
- p3 = out_length;
- dbg("encoded_data - %s ---", encoded_data);
- dbg("out_length - %d ---", out_length);
- } else {
- ret = TCORE_RETURN_ENOSYS;
- }
- break;
-
- case TREQ_SIM_SET_CALLFORWARDING:
- cf = tcore_user_request_ref_data(ur, NULL);
- if (tcore_sim_get_cphs_status(o)) {
- tmp = tcore_sim_encode_cff((const struct tel_sim_cphs_cf*)&cf->cphs_cf);
- ef = SIM_EF_CPHS_CALL_FORWARD_FLAGS;
- p1 = 0;
- p2 = 0;
- p3 = strlen(tmp);
- encoded_data = (char *)g_try_malloc0(2 * (p3) + 1);
- result = util_byte_to_hex(tmp, encoded_data, p3);
- cmd = 214; /*command - 214 : UPDATE BINARY*/
- } else {
- tmp = tcore_sim_encode_cfis(&encoded_len, (const struct tel_sim_cfis*)&cf->cf);
- ef = SIM_EF_USIM_CFIS;
- p1 = 1;
- p2 = 0x04;
- p3 = encoded_len;
- encoded_data = (char *)g_try_malloc0(2 * (encoded_len) + 1);
- result = util_byte_to_hex(tmp, encoded_data, encoded_len);
- cmd = 220; /*command - 220 : UPDATE RECORD*/
- }
- break;
-
- default:
- dbg("error - not handled update treq command[%d]", command);
- ret = TCORE_RETURN_EINVAL;
- break;
- }
-
- file_meta.file_id = ef;
- dbg("File ID: [0x%x]", file_meta.file_id);
-
- trt = tcore_user_request_set_metainfo(ur,
- sizeof(struct s_sim_property), &file_meta);
- dbg("trt[%d]", trt);
-
- cmd_str = g_strdup_printf("AT+CRSM=%d,%d,%d,%d,%d,\"%s\"", cmd, ef, p1, p2, p3, encoded_data);
-
- ret = tcore_prepare_and_send_at_request(o, cmd_str, "+CRSM:",
- TCORE_AT_SINGLELINE, ur,
- on_response_update_file, hal,
- NULL, NULL);
-
- g_free(cmd_str);
- g_free(encoded_data);
- if (tmp) {
- free(tmp);
- }
-
- dbg("Exit");
- return ret;
-}
-
-static TReturn s_transmit_apdu(CoreObject *o, UserRequest *ur)
-{
- const struct treq_sim_transmit_apdu *req_data;
- TcoreHal *hal = NULL;
- char *cmd_str = NULL;
- char *apdu = NULL;
- int result = 0;
- TReturn ret = TCORE_RETURN_FAILURE;
-
- dbg("Entry");
-
- if ((o == NULL )|| (ur == NULL))
- return TCORE_RETURN_EINVAL;
-
- hal = tcore_object_get_hal(o);
- if (FALSE == tcore_hal_get_power_state(hal)) {
- err("CP NOT READY");
- return TCORE_RETURN_ENOSYS;
- }
-
- req_data = tcore_user_request_ref_data(ur, NULL);
-
- apdu = (char *)g_try_malloc0((2 * req_data->apdu_length) + 1);
- result = util_byte_to_hex((const char *)req_data->apdu, apdu, req_data->apdu_length);
- cmd_str = g_strdup_printf("AT+CSIM=%d,\"%s\"", strlen(apdu), apdu);
-
- ret = tcore_prepare_and_send_at_request(o, cmd_str, "+CSIM:",
- TCORE_AT_SINGLELINE, ur,
- on_response_transmit_apdu, hal,
- NULL, NULL);
- g_free(cmd_str);
- g_free(apdu);
-
- dbg("Exit");
- return ret;
-}
-
-static TReturn s_get_atr(CoreObject *o, UserRequest *ur)
-{
- TcoreHal *hal = NULL;
-
- dbg("Entry");
-
- if ((o == NULL )|| (ur == NULL)) {
- err("Invalid parameters");
- return TCORE_RETURN_EINVAL;
- }
-
- hal = tcore_object_get_hal(o);
- if (FALSE == tcore_hal_get_power_state(hal)) {
- err("CP NOT READY");
- return TCORE_RETURN_ENOSYS;
- }
-
- return tcore_prepare_and_send_at_request(o, "AT+XGATR", "+XGATR:",
- TCORE_AT_SINGLELINE, ur,
- on_response_get_atr, hal,
- NULL, NULL);
-}
-
-static TReturn s_req_authentication(CoreObject *co, UserRequest *ur)
-{
- const struct treq_sim_req_authentication *req_data;
- char *cmd_str = NULL;
- enum tel_sim_type sim_type;
- int session_id;
- int context_type;
- TReturn ret = TCORE_RETURN_FAILURE;
- char *convert_rand = NULL;
- char *convert_autn = NULL;
-
- dbg("Entry");
-
- req_data = tcore_user_request_ref_data(ur, NULL);
- if (req_data == NULL) {
- err("req_data is NULL");
- return ret;
- }
-
- if (req_data->rand_data != NULL) {
- convert_rand = util_hex_to_string(req_data->rand_data,
- req_data->rand_length);
- dbg("Convert RAND hex to string: [%s]", convert_rand);
- } else {
- err("rand_data is NULL");
- return ret;
- }
-
- sim_type = tcore_sim_get_type(co);
- switch (sim_type) {
- case SIM_TYPE_GSM:
- case SIM_TYPE_USIM:
- session_id = 0;
- break;
- default:
- err("Not supported");
- ret = TCORE_RETURN_ENOSYS;
- goto out;
- }
-
- switch (req_data->auth_type) {
- case SIM_AUTH_TYPE_GSM:
- context_type = 2;
- cmd_str = g_strdup_printf("AT+XAUTH=%d,%d,\"%s\"", session_id,
- context_type, convert_rand);
- break;
- case SIM_AUTH_TYPE_3G:
- context_type = 1;
- if (req_data->autn_data != NULL) {
- convert_autn = util_hex_to_string(req_data->autn_data,
- req_data->autn_length);
- dbg("Convert AUTN hex to string: [%s]", convert_autn);
- } else {
- err("autn_data is NULL");
- goto out;
- }
- cmd_str = g_strdup_printf("AT+XAUTH=%d,%d,\"%s\",\"%s\"",
- session_id, context_type,
- convert_rand, convert_autn);
- break;
- default:
- err("Not supported");
- ret = TCORE_RETURN_ENOSYS;
- goto out;
- }
-
- ret = tcore_prepare_and_send_at_request(co, cmd_str, "+XAUTH",
- TCORE_AT_SINGLELINE, ur,
- on_response_req_authentication, NULL, NULL, NULL);
-
-out:
- g_free(cmd_str);
- g_free(convert_rand);
- g_free(convert_autn);
-
- return ret;
-}
-
-/* SIM Operations */
-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,
- .get_lock_info = s_get_lock_info,
- .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_sim)
-{
- struct s_sim_property *file_meta;
-
- dbg("Entry");
-
- tcore_sim_override_ops(co_sim, &sim_ops);
-
- file_meta = g_try_new0(struct s_sim_property, 1);
- if (file_meta == NULL)
- return FALSE;
-
- tcore_sim_link_userdata(co_sim, file_meta);
-
- tcore_object_override_callback(co_sim, "+XLOCK:",
- on_event_facility_lock_status, NULL);
- tcore_object_override_callback(co_sim, "+XSIM:",
- on_event_pin_status, NULL);
-
- tcore_server_add_notification_hook(tcore_plugin_ref_server(cp),
- TNOTI_MODEM_POWER, on_hook_modem_power, co_sim);
-
- dbg("Exit");
-
- return TRUE;
-}
-
-void s_sim_exit(TcorePlugin *cp, CoreObject *co_sim)
-{
- struct s_sim_property *file_meta;
-
- file_meta = tcore_sim_ref_userdata(co_sim);
- g_free(file_meta);
-
- dbg("Exit");
-}
+++ /dev/null
-/*
- * tel-plugin-imc
- *
- * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: Madhavi Akella <madhavi.a@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 <stdint.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 <at.h>
-#include <plugin.h>
-
-#include <util.h>
-
-#include "common/TelErr.h"
-#include "s_common.h"
-#include "s_sms.h"
-
-/*=============================================================
- GSM-SMS Size
-==============================================================*/
-#define MAX_GSM_SMS_TPDU_SIZE 244
-#define MAX_GSM_SMS_MSG_NUM 255
-#define MAX_GSM_SMS_SERVICE_CENTER_ADDR 12 /* Maximum number of bytes of service center address */
-#define MAX_GSM_SMS_CBMI_LIST_SIZE 100 /* Maximum number of CBMI list size for CBS 30*2=60 */
-#define MAX_GSM_SMS_PARAM_RECORD_SIZE 156 /* Maximum number of bytes SMSP Record size (Y + 28), y : 0 ~ 128 */
-#define MAX_GSM_SMS_STATUS_FILE_SIZE 2 /* Last Used TP-MR + SMS "Memory Cap. Exceeded" Noti Flag */
-#define TAPI_SIM_SMSP_ADDRESS_LEN 20
-
-/*=============================================================
- Device Ready
-==============================================================*/
-#define SMS_DEVICE_READY 1 /* Telephony device ready */
-#define SMS_DEVICE_NOT_READY 0 /* Telephony device not ready */
-
-/*=============================================================
- CBMI Selection
-==============================================================*/
-#define SMS_CBMI_SELECTED_SOME 0x02 /* Some CBMIs are selected */
-#define SMS_CBMI_SELECTED_ALL 0x01 /* All CBMIs are selected */
-
-/*=============================================================
- Message Status
-==============================================================*/
-#define AT_REC_UNREAD 0 /* Received and Unread */
-#define AT_REC_READ 1 /* Received and Read */
-#define AT_STO_UNSENT 2 /* Unsent */
-#define AT_STO_SENT 3 /* Sent */
-#define AT_ALL 4 /* Unknown */
-
-/*=============================================================
- Memory Status
-==============================================================*/
-#define AT_MEMORY_AVAILABLE 0 /* Memory Available */
-#define AT_MEMORY_FULL 1 /* Memory Full */
-
-/*=============================================================
- SIM CRSM SW1 and Sw2 Error definitions */
-
-#define AT_SW1_SUCCESS 0x90
-#define AT_SW2_SUCCESS 0
-#define AT_SW1_LEN_RESP 0x9F
-
-#define AT_MAX_RECORD_LEN 256
- /* 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)
-
-/*=============================================================
- String Preprocessor
-==============================================================*/
-#define CR '\r' /* Carriage Return */
-
-/*=============================================================
- Developer
-==============================================================*/
-#define SMS_SWAPBYTES16(x) (((x) & 0xffff0000) | (((x) & 0x0000ff00) >> 8) | (((x) & 0x000000ff) << 8))
-
-void print_glib_list_elem(gpointer data, gpointer user_data);
-
-static void on_response_class2_read_msg(TcorePending *pending, int data_len, const void *data, void *user_data);
-
-
-gboolean util_byte_to_hex(const char *byte_pdu, char *hex_pdu, int num_bytes);
-
-void print_glib_list_elem(gpointer data, gpointer user_data)
-{
- char *item = (char *)data;
-
- dbg("item: [%s]", item);
-}
-
-/*=============================================================
- Send Callback
-==============================================================*/
-static void on_confirmation_sms_message_send(TcorePending *p, gboolean result, void *user_data)
-{
- dbg("Entered Function. Request message out from queue");
-
- dbg("TcorePending: [%p]", p);
- dbg("result: [%02x]", result);
- dbg("user_data: [%p]", user_data);
-
- if (result == TRUE) {
- dbg("SEND OK");
- } else { /* Failed */
- dbg("SEND NOK");
- }
-
- dbg("Exiting Function. Nothing to return");
-}
-
-/*=============================================================
- Utilities
-==============================================================*/
-static void util_sms_free_memory(void *sms_ptr)
-{
- dbg("Entry");
-
- if (NULL != sms_ptr) {
- dbg("Freeing memory location: [%p]", sms_ptr);
- free(sms_ptr);
- sms_ptr = NULL;
- } else {
- err("Invalid memory location. Nothing to do.");
- }
-
- dbg("Exit");
-}
-
-
-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");
- }
-
- params->paramIndicator = incoming[alpha_id_len];
-
- dbg(" Param Indicator = %02x", params->paramIndicator);
-
- 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);
- }
- } else {
- params->tpDestAddr.dialNumLen = 0;
- }
-
- 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;
- }
- }
- } 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;
-}
-
-/*=============================================================
- Notifications
-==============================================================*/
-static gboolean on_event_class2_sms_incom_msg(CoreObject *obj,
- const void *event_info, void *user_data)
-{
- //+CMTI: <mem>,<index>
-
- GSList *tokens = NULL , *lines = NULL;
- char *line = NULL, *cmd_str = NULL;
- int index = 0, mem_type = 0;
- TcoreHal *hal = NULL;
- TcoreATRequest *atreq = NULL;
- TcorePending *pending = NULL;
-
- dbg("Entered Function");
-
- lines = (GSList *)event_info;
- line = (char *)g_slist_nth_data(lines, 0); /* Fetch Line 1 */
-
- dbg("Line 1: [%s]", line);
-
- if (!line) {
- err("Line 1 is invalid");
- return FALSE;
- }
-
- tokens = tcore_at_tok_new(line); /* Split Line 1 into tokens */
- mem_type = atoi(g_slist_nth_data(tokens, 0)); // Type of Memory stored
- index = atoi((char *) g_slist_nth_data(tokens, 1));
-
- hal = tcore_object_get_hal(obj);
- if (NULL == hal) {
- err("NULL input. Unable to proceed");
- dbg("readMsg: hal: [%p]", hal);
-
- dbg("Exit");
- return TCORE_RETURN_EINVAL;
- }
-
- dbg("index: [%d]", index);
-
- cmd_str = g_strdup_printf("AT+CMGR=%d", index);
- atreq = tcore_at_request_new((const char *)cmd_str, "+CMGR", TCORE_AT_PDU);
- pending = tcore_pending_new(obj, 0);
-
- if (NULL == cmd_str || NULL == atreq || NULL == pending) {
- err("Out of memory. Unable to proceed");
- dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
-
- //free memory we own
- g_free(cmd_str);
- util_sms_free_memory(atreq);
- util_sms_free_memory(pending);
-
- dbg("Exit");
- return TCORE_RETURN_ENOMEM;
- }
-
- util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
-
- tcore_pending_set_request_data(pending, 0, atreq);
- tcore_pending_set_response_callback(pending, on_response_class2_read_msg, (void *)(uintptr_t)index); //storing index as user data for response
- tcore_pending_link_user_request(pending, NULL);
- tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
- tcore_hal_send_request(hal, pending);
- g_free(cmd_str);
-
- if(tokens)
- tcore_at_tok_free(tokens);
-
- return TRUE;
-}
-
-static gboolean on_event_sms_incom_msg(CoreObject *o, const void *event_info, void *user_data)
-{
- //+CMT: [<alpha>],<length><CR><LF><pdu> (PDU mode enabled);
-
- int rtn = -1;
- GSList *tokens = NULL;
- GSList *lines = NULL;
- char *line = NULL;
- int pdu_len = 0, no_of_tokens = 0;
- unsigned char *bytePDU = NULL;
- struct tnoti_sms_umts_msg gsmMsgInfo;
- int sca_length = 0;
-
- dbg("Entered Function");
-
- lines = (GSList *)event_info;
- memset(&gsmMsgInfo, 0x00, sizeof(struct tnoti_sms_umts_msg));
-
- if (2 != g_slist_length(lines)) {
- err("Invalid number of lines for +CMT. Must be 2");
- return FALSE;
- }
-
- line = (char *)g_slist_nth_data(lines, 0); /* Fetch Line 1 */
-
- dbg("Line 1: [%s]", line);
-
- if (!line) {
- err("Line 1 is invalid");
- return FALSE;
- }
-
- tokens = tcore_at_tok_new(line); /* Split Line 1 into tokens */
-
- no_of_tokens = g_slist_length(tokens);
-
- if (no_of_tokens == 2) { // in case of incoming SMS +CMT
- dbg("Alpha ID: [%02x]", g_slist_nth_data(tokens, 0)); /* 0: Alpha ID */
- pdu_len = atoi((char *)g_slist_nth_data(tokens, 1));
- dbg("pdu_len: [%d]", pdu_len); /* 1: PDU Length */
- } else if (no_of_tokens == 1) { // in case of incoming status report +CDS
- pdu_len = atoi((char *)g_slist_nth_data(tokens, 0));
- dbg("pdu_len: [%d]", pdu_len); /* 1: PDU Length */
- }
-
- line = (char *)g_slist_nth_data(lines, 1); /* Fetch Line 2 */
-
- dbg("Line 2: [%s]", line);
-
- if (!line) {
- err("Line 2 is invalid");
- return FALSE;
- }
-
- /* Convert to Bytes */
- bytePDU = (unsigned char *)util_hexStringToBytes(line);
-
- sca_length = bytePDU[0];
-
- dbg("SCA length = %d", sca_length);
-
- gsmMsgInfo.msgInfo.msgLength = pdu_len;
-
- if (sca_length == 0) {
- memcpy(gsmMsgInfo.msgInfo.tpduData, &bytePDU[1], gsmMsgInfo.msgInfo.msgLength);
- } else {
- memcpy(gsmMsgInfo.msgInfo.sca, &bytePDU[1], sca_length);
- memcpy(gsmMsgInfo.msgInfo.tpduData, &bytePDU[sca_length+1], gsmMsgInfo.msgInfo.msgLength);
- }
-
- util_hex_dump(" ", strlen(line)/2, bytePDU);
- util_hex_dump(" ", sca_length, gsmMsgInfo.msgInfo.sca);
- util_hex_dump(" ", gsmMsgInfo.msgInfo.msgLength,gsmMsgInfo.msgInfo.tpduData);
-
- rtn = tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_SMS_INCOM_MSG, sizeof(struct tnoti_sms_umts_msg), &gsmMsgInfo);
-
- if(tokens)
- tcore_at_tok_free(tokens);
-
- g_free(bytePDU);
-
- return TRUE;
-}
-
-
-
-static gboolean on_event_sms_memory_status(CoreObject *o, const void *event_info, void *user_data)
-{
- struct tnoti_sms_memory_status memStatusInfo = {0,};
-
- int rtn = -1 ,memoryStatus = -1;
- GSList *tokens=NULL;
- GSList *lines=NULL;
- char *line = NULL , *pResp = NULL;
-
- dbg(" Entry");
-
- lines = (GSList *)event_info;
- if (1 != g_slist_length(lines)) {
- dbg("unsolicited msg but multiple line");
- }
-
- line = (char*)(lines->data);
-
- if (line) {
- dbg("Response OK");
- tokens = tcore_at_tok_new(line);
- pResp = g_slist_nth_data(tokens, 0);
-
- if (pResp) {
- memoryStatus = atoi(pResp);
- dbg("memoryStatus is %d",memoryStatus);
- if (memoryStatus == 0) {//SIM Full condition
- memStatusInfo.status = SMS_PHONE_MEMORY_STATUS_FULL;
- }
- rtn = tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_SMS_MEMORY_STATUS, sizeof(struct tnoti_sms_memory_status), &memStatusInfo);
- }
- tcore_at_tok_free(tokens);
- }else {
- dbg("Response NOK");
- }
-
- dbg(" Exit ");
- return TRUE;
-}
-
-static gboolean on_event_sms_cb_incom_msg(CoreObject *o, const void *event_info, void *user_data)
-{
- //+CBM: <length><CR><LF><pdu>
-
- struct tnoti_sms_cellBroadcast_msg cbMsgInfo;
-
- int rtn = -1 , length = 0;
- char * line = NULL, *pdu = NULL, *pResp = NULL;
- GSList *tokens = NULL;
- GSList *lines = NULL;
-
- dbg(" Func Entrance");
-
- lines = (GSList *)event_info;
-
- memset(&cbMsgInfo, 0, sizeof(struct tnoti_sms_cellBroadcast_msg));
-
- line = (char *)(lines->data);
-
- if (line != NULL) {
- dbg("Response OK");
- dbg("Noti line is %s",line);
- tokens = tcore_at_tok_new(line); /* Split Line 1 into tokens */
-
- pResp = g_slist_nth_data(tokens, 0);
- if (pResp) {
- length = atoi(pResp);
- } else {
- dbg("token 0 is null");
- }
-
- pdu = g_slist_nth_data(lines, 1);
- if (pdu != NULL) {
- cbMsgInfo.cbMsg.length = length;
- cbMsgInfo.cbMsg.cbMsgType = SMS_CB_MSG_GSM;
-
- dbg("CB Msg LENGTH [%2x]", length);
-
- if ((cbMsgInfo.cbMsg.length >0) && (SMS_CB_SIZE_MAX >= cbMsgInfo.cbMsg.length)) {
- unsigned char *byte_pdu = NULL;
-
- byte_pdu = (unsigned char *)util_hexStringToBytes(pdu);
-
- memcpy(cbMsgInfo.cbMsg.msgData, (char*)byte_pdu, cbMsgInfo.cbMsg.length);
- rtn = tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_SMS_CB_INCOM_MSG, sizeof(struct tnoti_sms_cellBroadcast_msg), &cbMsgInfo);
- g_free(byte_pdu);
- } else {
- dbg("Invalid Message Length");
- }
- } else {
- dbg("Recieved NULL pdu");
- }
- } else {
- dbg("Response NOK");
- }
-
- dbg(" Return value [%d]",rtn);
-
- if(tokens)
- tcore_at_tok_free(tokens);
-
- return TRUE;
-}
-
-
-/*=============================================================
- Responses
-==============================================================*/
-static void on_response_sms_delete_msg(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- struct tresp_sms_delete_msg delMsgInfo = {0,};
- UserRequest *ur = NULL;
- const TcoreATResponse *atResp = data;
-
- int rtn = -1;
- int index = (int) user_data;
-
- dbg(" Func Entrance");
-
- ur = tcore_pending_ref_user_request(p);
- if (atResp->success) {
- dbg("Response OK");
- delMsgInfo.index = index;
- delMsgInfo.result = SMS_SENDSMS_SUCCESS;
- } else {
- dbg("Response NOK");
- delMsgInfo.index = index;
- delMsgInfo.result = SMS_DEVICE_FAILURE;
- }
-
- rtn = tcore_user_request_send_response(ur, TRESP_SMS_DELETE_MSG, sizeof(struct tresp_sms_delete_msg), &delMsgInfo);
-
- return;
-}
-
-static void on_response_sms_save_msg(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- struct tresp_sms_save_msg saveMsgInfo = {0,};
- UserRequest *ur = NULL;
- const TcoreATResponse *atResp = data;
- GSList *tokens = NULL;
- char *line = NULL;
- char *pResp = NULL;
- int rtn = -1;
-
- ur = tcore_pending_ref_user_request(p);
- if (atResp->success) {
- dbg("Response OK");
- if (atResp->lines) {
- line = (char *)atResp->lines->data;
- tokens = tcore_at_tok_new(line);
- pResp = g_slist_nth_data(tokens, 0);
- if (pResp) {
- dbg("0: %s", pResp);
- saveMsgInfo.index = atoi(pResp);
- saveMsgInfo.result = SMS_SENDSMS_SUCCESS;
- } else {
- dbg("No Tokens");
- saveMsgInfo.index = -1;
- saveMsgInfo.result = SMS_DEVICE_FAILURE;
- }
- tcore_at_tok_free(tokens);
- }
- } else {
- dbg("Response NOK");
- saveMsgInfo.index = -1;
- saveMsgInfo.result = SMS_DEVICE_FAILURE;
- }
-
- rtn = tcore_user_request_send_response(ur, TRESP_SMS_SAVE_MSG, sizeof(struct tresp_sms_save_msg), &saveMsgInfo);
- dbg("Return value [%d]", rtn);
- return;
-}
-
-static void on_response_send_umts_msg(TcorePending *pending, int data_len, const void *data, void *user_data)
-{
- const TcoreATResponse *at_response = data;
- struct tresp_sms_send_umts_msg resp_umts;
- UserRequest *user_req = NULL;
-
- int msg_ref = 0;
- GSList *tokens = NULL;
- char *gslist_line = NULL, *line_token = NULL;
-
- dbg("Entry");
-
- user_req = tcore_pending_ref_user_request(pending);
-
- if (NULL == user_req) {
- err("No user request");
-
- dbg("Exit");
- return;
- }
-
- memset(&resp_umts, 0x00, sizeof(resp_umts));
- resp_umts.result = SMS_DEVICE_FAILURE;
-
- if (at_response->success > 0) { /* SUCCESS */
- dbg("Response OK");
- if (at_response->lines) { // lines present in at_response
- gslist_line = (char *)at_response->lines->data;
- dbg("gslist_line: [%s]", gslist_line);
-
- tokens = tcore_at_tok_new(gslist_line); //extract tokens
-
- line_token = g_slist_nth_data(tokens, 0);
- if (line_token != NULL) {
- msg_ref = atoi(line_token);
- dbg("Message Reference: [%d]", msg_ref);
-
- resp_umts.result = SMS_SENDSMS_SUCCESS;
- } else {
- dbg("No Message Reference received");
- }
- tcore_at_tok_free(tokens);
- } else { // no lines in at_response
- dbg("No lines");
- }
- } else { // failure
- dbg("Response NOK");
- }
-
- tcore_user_request_send_response(user_req, TRESP_SMS_SEND_UMTS_MSG, sizeof(resp_umts), &resp_umts);
-
- dbg("Exit");
- return;
-}
-
-static void on_response_class2_read_msg(TcorePending *pending, int data_len, const void *data, void *user_data)
-{
- const TcoreATResponse *at_response = data;
- GSList *tokens=NULL;
- char *gslist_line = NULL, *line_token = NULL, *hex_pdu = NULL;
- int pdu_len = 0, rtn = 0;
- unsigned char *bytePDU = NULL;
- struct tnoti_sms_umts_msg gsmMsgInfo;
- int sca_length= 0;
-
- dbg("Entry");
- dbg("lines: [%p]", at_response->lines);
- g_slist_foreach(at_response->lines, print_glib_list_elem, NULL); //for debug log
-
- if (at_response->success <= 0) {
- err("Response NOK");
- return;
- }
-
- dbg("Response OK");
- if (at_response->lines == NULL) {
- err("No lines");
- return;
- }
-
- //fetch first line
- gslist_line = (char *)at_response->lines->data;
- if (gslist_line == NULL) {
- err("Error response data");
- return;
- }
-
- dbg("gslist_line: [%s]", gslist_line);
-
- tokens = tcore_at_tok_new(gslist_line);
- dbg("Number of tokens: [%d]", g_slist_length(tokens));
- g_slist_foreach(tokens, print_glib_list_elem, NULL); //for debug log
-
- line_token = g_slist_nth_data(tokens, 2); //Third Token: Length
- if (line_token == NULL) {
- err("Error response data");
- tcore_at_tok_free(tokens);
- return;
- }
-
- pdu_len = atoi(line_token);
- dbg("Length: [%d]", pdu_len);
- tcore_at_tok_free(tokens);
-
- //fetch second line
- if (at_response->lines->next == NULL) {
- err("Error response data");
- return;
- }
- gslist_line = (char *)at_response->lines->next->data;
- if (gslist_line == NULL) {
- err("Error response data");
- return;
- }
-
- dbg("gslist_line: [%s]", gslist_line);
-
- tokens = tcore_at_tok_new(gslist_line);
- dbg("Number of tokens: [%d]", g_slist_length(tokens));
- g_slist_foreach(tokens, print_glib_list_elem, NULL); //for debug log
-
- hex_pdu = g_slist_nth_data(tokens, 0); //Fetch SMS PDU
-
- /* Convert to Bytes */
- bytePDU = (unsigned char *)util_hexStringToBytes(hex_pdu);
- if (bytePDU == NULL) {
- tcore_at_tok_free(tokens);
- return;
- }
-
- sca_length = bytePDU[0];
- dbg("SCA length = %d", sca_length);
-
- gsmMsgInfo.msgInfo.msgLength = pdu_len;
-
- if (sca_length == 0) {
- memcpy(gsmMsgInfo.msgInfo.tpduData, &bytePDU[1], gsmMsgInfo.msgInfo.msgLength);
- } else {
- memcpy(gsmMsgInfo.msgInfo.sca, bytePDU, sca_length);
- memcpy(gsmMsgInfo.msgInfo.tpduData, &bytePDU[sca_length+1], gsmMsgInfo.msgInfo.msgLength);
- }
-
- util_hex_dump(" ", strlen(hex_pdu)/2, bytePDU);
- util_hex_dump(" ", sca_length, gsmMsgInfo.msgInfo.sca);
- util_hex_dump(" ", gsmMsgInfo.msgInfo.msgLength,gsmMsgInfo.msgInfo.tpduData);
-
- rtn = tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(tcore_pending_ref_core_object(pending))), tcore_pending_ref_core_object(pending), TNOTI_SMS_INCOM_MSG, sizeof(struct tnoti_sms_umts_msg), &gsmMsgInfo);
-
- g_free(bytePDU);
- tcore_at_tok_free(tokens);
-}
-
-static void on_response_read_msg(TcorePending *pending, int data_len, const void *data, void *user_data)
-{
- const TcoreATResponse *at_response = data;
- struct tresp_sms_read_msg resp_read_msg;
- UserRequest *user_req = NULL;
-
- GSList *tokens=NULL;
- char *gslist_line = NULL, *line_token = NULL, *byte_pdu = NULL, *hex_pdu = NULL;
- int sca_length = 0;
- int msg_status = 0, alpha_id = 0, pdu_len = 0;
- int index = (int)(uintptr_t)user_data;
-
- dbg("Entry");
- dbg("index: [%d]", index);
- g_slist_foreach(at_response->lines, print_glib_list_elem, NULL); //for debug log
-
- user_req = tcore_pending_ref_user_request(pending);
- if (NULL == user_req) {
- err("No user request");
-
- dbg("Exit");
- return;
- }
-
- memset(&resp_read_msg, 0x00, sizeof(resp_read_msg));
- resp_read_msg.result = SMS_PHONE_FAILURE;
-
- if (at_response->success > 0) {
- dbg("Response OK");
- if (at_response->lines) {
- //fetch first line
- gslist_line = (char *)at_response->lines->data;
-
- dbg("gslist_line: [%s]", gslist_line);
-
- tokens = tcore_at_tok_new(gslist_line);
- dbg("Number of tokens: [%d]", g_slist_length(tokens));
- g_slist_foreach(tokens, print_glib_list_elem, NULL); //for debug log
-
- line_token = g_slist_nth_data(tokens, 0); //First Token: Message Status
- if (line_token != NULL) {
- msg_status = atoi(line_token);
- dbg("msg_status is %d",msg_status);
- switch (msg_status) {
- case AT_REC_UNREAD:
- resp_read_msg.dataInfo.msgStatus = SMS_STATUS_UNREAD;
- break;
-
- case AT_REC_READ:
- resp_read_msg.dataInfo.msgStatus = SMS_STATUS_READ;
- break;
-
- case AT_STO_UNSENT:
- resp_read_msg.dataInfo.msgStatus = SMS_STATUS_UNSENT;
- break;
-
- case AT_STO_SENT:
- resp_read_msg.dataInfo.msgStatus = SMS_STATUS_SENT;
- break;
-
- case AT_ALL: //Fall Through
- default: //Fall Through
- resp_read_msg.dataInfo.msgStatus = SMS_STATUS_RESERVED;
- break;
- }
- }
-
- line_token = g_slist_nth_data(tokens, 1); //Second Token: AlphaID
- if (line_token != NULL) {
- alpha_id = atoi(line_token);
- dbg("AlphaID: [%d]", alpha_id);
- }
-
- line_token = g_slist_nth_data(tokens, 2); //Third Token: Length
- if (line_token != NULL) {
- pdu_len = atoi(line_token);
- dbg("Length: [%d]", pdu_len);
- }
-
- //fetch second line
- hex_pdu = (char *) at_response->lines->next->data;
-
- dbg("EF-SMS PDU: [%s]", hex_pdu);
-
- //free the consumed token
- tcore_at_tok_free(tokens);
-
- if (NULL != hex_pdu) {
- util_hex_dump(" ", sizeof(hex_pdu), (void *)hex_pdu);
-
- byte_pdu = util_hexStringToBytes(hex_pdu);
-
- sca_length = (int)byte_pdu[0];
-
- resp_read_msg.dataInfo.simIndex = index; //Retrieving index stored as user_data
-
- dbg("SCA Length : %d", sca_length);
-
- resp_read_msg.dataInfo.smsData.msgLength = pdu_len;
- dbg("msgLength: [%d]", resp_read_msg.dataInfo.smsData.msgLength);
-
- if(0 == sca_length) {
- if ((resp_read_msg.dataInfo.smsData.msgLength > 0)
- && (resp_read_msg.dataInfo.smsData.msgLength <= SMS_SMDATA_SIZE_MAX)) {
- memset(resp_read_msg.dataInfo.smsData.sca, 0, TAPI_SIM_SMSP_ADDRESS_LEN);
- memcpy(resp_read_msg.dataInfo.smsData.tpduData, &byte_pdu[1], resp_read_msg.dataInfo.smsData.msgLength);
-
- resp_read_msg.result = SMS_SUCCESS;
- } else {
- dbg("Invalid Message Length");
- resp_read_msg.result = SMS_INVALID_PARAMETER_FORMAT;
- }
- } else if (sca_length > SMS_ENCODED_SCA_LEN_MAX) {
- dbg("Invalid Message Length");
- resp_read_msg.result = SMS_INVALID_PARAMETER_FORMAT;
- } else {
- if ((resp_read_msg.dataInfo.smsData.msgLength > 0)
- && (resp_read_msg.dataInfo.smsData.msgLength <= SMS_SMDATA_SIZE_MAX)) {
- memcpy(resp_read_msg.dataInfo.smsData.sca, (char *)byte_pdu, (sca_length+1));
- memcpy(resp_read_msg.dataInfo.smsData.tpduData, &byte_pdu[sca_length+1], resp_read_msg.dataInfo.smsData.msgLength);
-
- util_hex_dump(" ", SMS_SMSP_ADDRESS_LEN, (void *)resp_read_msg.dataInfo.smsData.sca);
- util_hex_dump(" ", (SMS_SMDATA_SIZE_MAX + 1), (void *)resp_read_msg.dataInfo.smsData.tpduData);
- util_hex_dump(" ", sizeof(byte_pdu), (void *)byte_pdu);
-
- resp_read_msg.result = SMS_SUCCESS;
- } else {
- dbg("Invalid Message Length");
- resp_read_msg.result = SMS_INVALID_PARAMETER_FORMAT;
- }
- }
- g_free(byte_pdu);
- }else {
- dbg("NULL PDU");
- }
- }else {
- dbg("No lines");
- }
- } else {
- err("Response NOK");
- }
-
- tcore_user_request_send_response(user_req, TRESP_SMS_READ_MSG, sizeof(resp_read_msg), &resp_read_msg);
-
- dbg("Exit");
- return;
-}
-
-static void on_response_get_msg_indices(TcorePending *pending, int data_len, const void *data, void *user_data)
-{
- const TcoreATResponse *at_response = data;
- struct tresp_sms_get_storedMsgCnt resp_stored_msg_cnt;
- UserRequest *user_req = NULL;
- struct tresp_sms_get_storedMsgCnt *resp_stored_msg_cnt_prev = NULL;
-
- GSList *tokens = NULL;
- char *gslist_line = NULL, *line_token = NULL;
- int gslist_line_count = 0, ctr_loop = 0;
-
- dbg("Entry");
-
- resp_stored_msg_cnt_prev = (struct tresp_sms_get_storedMsgCnt *)user_data;
- user_req = tcore_pending_ref_user_request(pending);
-
- memset(&resp_stored_msg_cnt, 0x00, sizeof(resp_stored_msg_cnt));
- resp_stored_msg_cnt.result = SMS_DEVICE_FAILURE;
-
- if (at_response->success) {
- dbg("Response OK");
- if (at_response->lines) {
- gslist_line_count = g_slist_length(at_response->lines);
-
- if (gslist_line_count > SMS_GSM_SMS_MSG_NUM_MAX)
- gslist_line_count = SMS_GSM_SMS_MSG_NUM_MAX;
-
- dbg("Number of lines: [%d]", gslist_line_count);
- g_slist_foreach(at_response->lines, print_glib_list_elem, NULL); //for debug log
-
- for (ctr_loop = 0; ctr_loop < gslist_line_count; ctr_loop++) {
- gslist_line = (char *)g_slist_nth_data(at_response->lines, ctr_loop); /* Fetch Line i */
-
- dbg("gslist_line [%d] is [%s]", ctr_loop, gslist_line);
-
- if (NULL != gslist_line) {
- tokens = tcore_at_tok_new(gslist_line);
-
- g_slist_foreach(tokens, print_glib_list_elem, NULL); //for debug log
-
- line_token = g_slist_nth_data(tokens, 0);
- if (NULL != line_token) {
- resp_stored_msg_cnt.storedMsgCnt.indexList[ctr_loop] = atoi(line_token);
- resp_stored_msg_cnt.result = SMS_SENDSMS_SUCCESS;
- } else {
- dbg("line_token of gslist_line [%d] is NULL", ctr_loop);
- continue;
- }
- tcore_at_tok_free(tokens);
- } else {
- dbg("gslist_line [%d] is NULL", ctr_loop);
- continue;
- }
- }
- } else {
- dbg("No lines.");
- if (resp_stored_msg_cnt_prev->storedMsgCnt.usedCount == 0) { // Check if used count is zero
- resp_stored_msg_cnt.result = SMS_SENDSMS_SUCCESS;
- }
- }
- } else {
- dbg("Respnose NOK");
- }
-
- resp_stored_msg_cnt.storedMsgCnt.totalCount = resp_stored_msg_cnt_prev->storedMsgCnt.totalCount;
- resp_stored_msg_cnt.storedMsgCnt.usedCount = resp_stored_msg_cnt_prev->storedMsgCnt.usedCount;
-
- util_sms_free_memory(resp_stored_msg_cnt_prev);
-
- dbg("total: [%d], used: [%d], result: [%d]", resp_stored_msg_cnt.storedMsgCnt.totalCount, resp_stored_msg_cnt.storedMsgCnt.usedCount, resp_stored_msg_cnt.result);
- for (ctr_loop = 0; ctr_loop < gslist_line_count; ctr_loop++) {
- dbg("index: [%d]", resp_stored_msg_cnt.storedMsgCnt.indexList[ctr_loop]);
- }
-
- tcore_user_request_send_response(user_req, TRESP_SMS_GET_STORED_MSG_COUNT, sizeof(resp_stored_msg_cnt), &resp_stored_msg_cnt);
-
- dbg("Exit");
- return;
-}
-
-static void on_response_get_stored_msg_cnt(TcorePending *pending, int data_len, const void *data, void *user_data)
-{
- UserRequest *ur = NULL, *ur_dup = NULL;
- struct tresp_sms_get_storedMsgCnt *respStoredMsgCnt = NULL;
- const TcoreATResponse *atResp = data;
- GSList *tokens=NULL;
- char *line = NULL , *pResp = NULL , *cmd_str = NULL;
- TcoreATRequest *atReq = NULL;
- int usedCnt = 0, totalCnt = 0, result = 0;
-
- TcorePending *pending_new = NULL;
- CoreObject *o = NULL;
-
- dbg("Entered");
-
- respStoredMsgCnt = malloc(sizeof(struct tresp_sms_get_storedMsgCnt));
- result = SMS_DEVICE_FAILURE;
-
- ur = tcore_pending_ref_user_request(pending);
- ur_dup = tcore_user_request_ref(ur);
- o = tcore_pending_ref_core_object(pending);
-
- if (atResp->success > 0) {
- dbg("Response OK");
- if (NULL != atResp->lines) {
- line = (char *)atResp->lines->data;
- dbg("line is %s",line);
-
- tokens = tcore_at_tok_new(line);
- pResp = g_slist_nth_data(tokens, 0);
-
- if (pResp) {
- usedCnt =atoi(pResp);
- dbg("used cnt is %d",usedCnt);
- }
-
- pResp = g_slist_nth_data(tokens, 1);
- if (pResp) {
- totalCnt =atoi(pResp);
- result = SMS_SENDSMS_SUCCESS;
-
- respStoredMsgCnt->storedMsgCnt.usedCount = usedCnt;
- respStoredMsgCnt->storedMsgCnt.totalCount = totalCnt;
- respStoredMsgCnt->result = result;
-
- dbg("used %d, total %d, result %d",usedCnt, totalCnt,result);
-
- pending_new = tcore_pending_new(o, 0);
- //Get all messages information
- cmd_str = g_strdup_printf("AT+CMGL=4");
- atReq = tcore_at_request_new((const char *)cmd_str, "+CMGL", TCORE_AT_MULTILINE);
-
- dbg("cmd str is %s",cmd_str);
-
- tcore_pending_set_request_data(pending_new, 0,atReq);
- tcore_pending_set_response_callback(pending_new, on_response_get_msg_indices, (void *)respStoredMsgCnt);
- tcore_pending_link_user_request(pending_new, ur_dup);
- tcore_pending_set_send_callback(pending_new, on_confirmation_sms_message_send, NULL);
- tcore_hal_send_request(tcore_object_get_hal(o), pending_new);
-
- //free the consumed token
- tcore_at_tok_free(tokens);
-
- g_free(cmd_str);
-
- dbg("Exit");
- return;
- }
- //free the consumed token
- if (tokens)
- tcore_at_tok_free(tokens);
- } else {
- dbg("No data");
- }
- } else {
- err("Response NOK");
- }
- respStoredMsgCnt->result = result;
- tcore_user_request_send_response(ur, TRESP_SMS_GET_STORED_MSG_COUNT, sizeof(struct tresp_sms_get_storedMsgCnt), &respStoredMsgCnt);
-
-
- dbg("Exit");
- return;
-}
-
-static void on_response_get_sca(TcorePending *pending, int data_len, const void *data, void *user_data)
-{
- const TcoreATResponse *at_response = data;
- struct tresp_sms_get_sca respGetSca;
- UserRequest *user_req = NULL;
-
- GSList *tokens = NULL;
- const char *sca_tok_addr;
- char *gslist_line = NULL, *sca_addr = NULL, *sca_toa = NULL;
-
- dbg("Entry");
-
- memset(&respGetSca, 0, sizeof(respGetSca));
- respGetSca.result = SMS_DEVICE_FAILURE;
-
- user_req = tcore_pending_ref_user_request(pending);
-
- if (at_response->success) {
- dbg("Response OK");
- if (at_response->lines) {
- gslist_line = (char *)at_response->lines->data;
-
- tokens = tcore_at_tok_new(gslist_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);
- if ((NULL != sca_addr)
- && (NULL != sca_toa)) {
- dbg("sca_addr: [%s]. sca_toa: [%s]", sca_addr, sca_toa);
-
- respGetSca.scaAddress.dialNumLen = strlen(sca_addr);
-
- if (145 == atoi(sca_toa)) {
- respGetSca.scaAddress.typeOfNum = SIM_TON_INTERNATIONAL;
- } else {
- respGetSca.scaAddress.typeOfNum = SIM_TON_NATIONAL;
- }
-
- respGetSca.scaAddress.numPlanId = 0;
-
- memcpy(respGetSca.scaAddress.diallingNum, sca_addr, strlen(sca_addr));
-
- dbg("len [%d], sca_addr [%s], TON [%d], NPI [%d]", respGetSca.scaAddress.dialNumLen, respGetSca.scaAddress.diallingNum, respGetSca.scaAddress.typeOfNum, respGetSca.scaAddress.numPlanId);
-
- respGetSca.result = SMS_SENDSMS_SUCCESS;
- } else {
- err("sca_addr OR sca_toa NULL");
- }
- } else {
- dbg("NO Lines");
- }
- } else {
- dbg("Response NOK");
- }
-
- tcore_user_request_send_response(user_req, TRESP_SMS_GET_SCA, sizeof(respGetSca), &respGetSca);
-
- tcore_at_tok_free(tokens);
- g_free(sca_addr);
-
- dbg("Exit");
- return;
-}
-
-static void on_response_set_sca(TcorePending *pending, int data_len, const void *data, void *user_data)
-{
- /*
- Response is expected in this format
- OK
- or
- +CMS ERROR: <err>
- */
- UserRequest *ur;
- //copies the AT response data to resp
- const TcoreATResponse *atResp = data;
- struct tresp_sms_set_sca respSetSca;
-
- memset(&respSetSca, 0, sizeof(struct tresp_sms_set_sca));
-
- ur = tcore_pending_ref_user_request(pending);
- if (!ur) {
- dbg("no user_request");
- return;
- }
-
- if (atResp->success > 0) {
- dbg("RESPONSE OK");
- respSetSca.result = SMS_SUCCESS;
- } else {
- dbg("RESPONSE NOK");
- respSetSca.result = SMS_DEVICE_FAILURE;
- }
-
- tcore_user_request_send_response(ur, TRESP_SMS_SET_SCA, sizeof(struct tresp_sms_set_sca), &respSetSca);
-
- return;
-}
-
-static void on_response_get_cb_config(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- UserRequest *ur;
- struct tresp_sms_get_cb_config respGetCbConfig;
- const TcoreATResponse *atResp = data;
- GSList *tokens=NULL;
- int i = 0, mode =0;
- char *pResp = NULL, *line = NULL;
- char delim[] = "-";
-
- memset(&respGetCbConfig, 0, sizeof(struct tresp_sms_get_cb_config));
- respGetCbConfig.result = SMS_DEVICE_FAILURE;
-
- ur = tcore_pending_ref_user_request(p);
- if (!ur) {
- dbg("no user_request");
- return;
- }
-
- respGetCbConfig.cbConfig.net3gppType = SMS_NETTYPE_3GPP;
-
- if (atResp->success) {
- dbg("Response OK");
- if (atResp->lines) {
- line = (char*)atResp->lines->data;
- if (line != NULL) {
- dbg("line is %s",line);
- tokens = tcore_at_tok_new(line);
- pResp = g_slist_nth_data(tokens, 0);
- if (pResp) {
- mode = atoi(pResp);
- respGetCbConfig.cbConfig.cbEnabled = mode;
-
- pResp = g_slist_nth_data(tokens, 1);
- if (pResp) {
- GSList *cb_tokens = NULL;
- char *cb_mid_str = NULL;
- int num_cb_tokens = 0;
- char *mid_tok = NULL;
- char *first_tok = NULL, *second_tok = NULL;
-
- // 0,1,5,320-478,922
- cb_mid_str = util_removeQuotes(pResp);
- cb_tokens = tcore_at_tok_new((const char *) cb_mid_str);
-
- g_free(cb_mid_str);
-
- num_cb_tokens = g_slist_length(cb_tokens);
- dbg("num_cb_tokens = %d", num_cb_tokens);
-
- if (num_cb_tokens == 0) {
- if (mode == 1) { // Enable all CBs
- respGetCbConfig.cbConfig.msgIdRangeCount = 1;
- respGetCbConfig.cbConfig.msgIDs[0].net3gpp.fromMsgId = 0x0000;
- respGetCbConfig.cbConfig.msgIDs[0].net3gpp.toMsgId = SMS_GSM_SMS_CBMI_LIST_SIZE_MAX + 1;
- respGetCbConfig.cbConfig.msgIDs[0].net3gpp.selected = TRUE;
- respGetCbConfig.result = SMS_SENDSMS_SUCCESS;
- } else { // all CBs disabled
- respGetCbConfig.cbConfig.msgIdRangeCount = 0;
- respGetCbConfig.cbConfig.msgIDs[0].net3gpp.selected = FALSE;
- respGetCbConfig.result = SMS_SENDSMS_SUCCESS;
- }
- } else {
- respGetCbConfig.cbConfig.msgIdRangeCount = 0;
- respGetCbConfig.cbConfig.msgIDs[0].net3gpp.selected = FALSE;
- respGetCbConfig.result = SMS_SENDSMS_SUCCESS;
- }
-
- for (i = 0; i < num_cb_tokens; i++) {
- respGetCbConfig.cbConfig.msgIDs[i].net3gpp.selected = TRUE;
- respGetCbConfig.cbConfig.msgIdRangeCount++;
-
- mid_tok = tcore_at_tok_nth(cb_tokens, i);
- first_tok = strtok(mid_tok, delim);
- second_tok = strtok(NULL, delim);
-
- if ((first_tok != NULL) && (second_tok != NULL)) { // mids in range (320-478)
- dbg("inside if mid_range");
- respGetCbConfig.cbConfig.msgIDs[i].net3gpp.fromMsgId = atoi(first_tok);
- respGetCbConfig.cbConfig.msgIDs[i].net3gpp.toMsgId = atoi(second_tok);
- } // single mid value (0,1,5, 922)
- else {
- respGetCbConfig.cbConfig.msgIDs[i].net3gpp.fromMsgId = atoi(mid_tok);
- respGetCbConfig.cbConfig.msgIDs[i].net3gpp.toMsgId = atoi(mid_tok);
- }
- }
- }
- }else {
- if (mode == 1) {
- respGetCbConfig.cbConfig.msgIdRangeCount = 1;
- respGetCbConfig.cbConfig.msgIDs[0].net3gpp.fromMsgId = 0x0000;
- respGetCbConfig.cbConfig.msgIDs[0].net3gpp.toMsgId = SMS_GSM_SMS_CBMI_LIST_SIZE_MAX + 1;
- respGetCbConfig.cbConfig.msgIDs[0].net3gpp.selected = TRUE;
- respGetCbConfig.result = SMS_SENDSMS_SUCCESS;
- } else {
- respGetCbConfig.cbConfig.msgIdRangeCount = 0;
- respGetCbConfig.cbConfig.msgIDs[0].net3gpp.selected = FALSE;
- respGetCbConfig.result = SMS_SENDSMS_SUCCESS;
- }
- }
- } else {
- dbg("line is NULL");
- }
- } else {
- dbg("atresp->lines is NULL");
- }
- } else {
- dbg("RESPONSE NOK");
- }
-
- tcore_user_request_send_response(ur, TRESP_SMS_GET_CB_CONFIG, sizeof(struct tresp_sms_get_cb_config), &respGetCbConfig);
-
- if(tokens)
- tcore_at_tok_free(tokens);
-
- return;
-}
-
-static void on_response_set_cb_config(TcorePending *pending, int data_len, const void *data, void *user_data)
-{
- /*
- Response is expected in this format
- OK
- or
- +CMS ERROR: <err>
- */
-
- UserRequest *ur;
- const TcoreATResponse *resp = data;
- int response = 0;
- const char *line = NULL;
- GSList *tokens=NULL;
-
- struct tresp_sms_set_cb_config respSetCbConfig = {0,};
-
- memset(&respSetCbConfig, 0, sizeof(struct tresp_sms_set_cb_config));
-
- ur = tcore_pending_ref_user_request(pending);
- respSetCbConfig.result = SMS_SENDSMS_SUCCESS;
-
- if (resp->success > 0) {
- dbg("RESPONSE OK");
- } else {
- dbg("RESPONSE NOK");
- line = (const char*)resp->final_response;
- tokens = tcore_at_tok_new(line);
-
- if (g_slist_length(tokens) < 1) {
- dbg("err cause not specified or string corrupted");
- respSetCbConfig.result = SMS_DEVICE_FAILURE;
- } else {
- response = atoi(g_slist_nth_data(tokens, 0));
- /* TODO: CMEE error mapping is required. */
- respSetCbConfig.result = SMS_DEVICE_FAILURE;
- }
- }
- if (!ur) {
- dbg("no user_request");
- return;
- }
-
- tcore_user_request_send_response(ur, TRESP_SMS_SET_CB_CONFIG, sizeof(struct tresp_sms_set_cb_config), &respSetCbConfig);
-
- if(tokens)
- tcore_at_tok_free(tokens);
-
- return;
-}
-
-static void on_response_set_mem_status(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- UserRequest *ur;
- struct tresp_sms_set_mem_status respSetMemStatus = {0,};
- const TcoreATResponse *resp = data;
-
- memset(&respSetMemStatus, 0, sizeof(struct tresp_sms_set_mem_status));
-
- if (resp->success > 0) {
- dbg("RESPONSE OK");
- respSetMemStatus.result = SMS_SENDSMS_SUCCESS;
- } else {
- dbg("RESPONSE NOK");
- respSetMemStatus.result = SMS_DEVICE_FAILURE;
- }
-
- ur = tcore_pending_ref_user_request(p);
- if (!ur) {
- dbg("no user_request");
- return;
- }
-
- tcore_user_request_send_response(ur, TRESP_SMS_SET_MEM_STATUS, sizeof(struct tresp_sms_set_mem_status), &respSetMemStatus);
-
- return;
-}
-
-static void on_response_set_msg_status(TcorePending *pending, int data_len, const void *data, void *user_data)
-{
- UserRequest *ur;
- struct tresp_sms_set_msg_status respMsgStatus = {0, };
- const TcoreATResponse *atResp = data;
- int response = 0, sw1 = 0, sw2 = 0;
- const char *line = NULL;
- char *pResp = NULL;
- GSList *tokens = NULL;
-
- dbg("Entry");
-
- memset(&respMsgStatus, 0, sizeof(struct tresp_sms_set_msg_status));
- respMsgStatus.result = SMS_DEVICE_FAILURE;
-
- ur = tcore_pending_ref_user_request(pending);
-
- if (atResp->success > 0) {
- dbg("RESPONSE OK");
-
- if (atResp->lines) {
- line = (const char *) atResp->lines->data;
- tokens = tcore_at_tok_new(line);
- pResp = g_slist_nth_data(tokens, 0);
- if (pResp != NULL) {
- sw1 = atoi(pResp);
- } else {
- dbg("sw1 is NULL");
- }
- pResp = g_slist_nth_data(tokens, 1);
- if (pResp != NULL) {
- sw2 = atoi(pResp);
- if ((sw1 == AT_SW1_SUCCESS) && (sw2 == 0)) {
- respMsgStatus.result = SMS_SENDSMS_SUCCESS;
- }
- } else {
- dbg("sw2 is NULL");
- }
- pResp = g_slist_nth_data(tokens, 3);
-
- if (pResp != NULL) {
- response = atoi(pResp);
- dbg("response is %s", response);
- }
- } else {
- dbg("No lines");
- }
- } else {
- dbg("RESPONSE NOK");
- }
-
- tcore_user_request_send_response(ur, TRESP_SMS_SET_MSG_STATUS , sizeof(struct tresp_sms_set_msg_status), &respMsgStatus);
-
- if(tokens)
- tcore_at_tok_free(tokens);
-
- dbg("Exit");
- return;
-}
-
-static void on_response_get_sms_params(TcorePending *pending, int data_len, const void *data, void *user_data)
-{
- UserRequest *ur;
- struct tresp_sms_get_params respGetParams ;
- const TcoreATResponse *atResp = data;
- int sw1 = 0, sw2 = 0;
- const char *line = NULL;
- char *pResp = NULL;
- GSList *tokens=NULL;
- char *hexData = NULL;
- char *recordData = NULL;
- int i = 0;
-
- memset(&respGetParams, 0, sizeof(struct tresp_sms_get_params));
- respGetParams.result = SMS_DEVICE_FAILURE;
-
- ur = tcore_pending_ref_user_request(pending);
-
- if (atResp->success > 0) {
- dbg("RESPONSE OK");
-
- if (atResp->lines) {
- line = (const char *) atResp->lines->data;
- tokens = tcore_at_tok_new(line);
- pResp = g_slist_nth_data(tokens, 0);
- if (pResp != NULL) {
- sw1 = atoi(pResp);
- dbg("sw1 is %d", sw1);
- } else {
- dbg("sw1 is NULL");
- }
- pResp = g_slist_nth_data(tokens, 1);
- if (pResp != NULL) {
- sw2 = atoi(pResp);
- dbg("sw2 is %d", sw2);
- if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
- respGetParams.result = SMS_SENDSMS_SUCCESS;
- }
- } else {
- dbg("sw2 is NULL");
- }
- pResp = g_slist_nth_data(tokens, 2);
- if (pResp != NULL) {
- hexData = util_removeQuotes(pResp);
-
- recordData = util_hexStringToBytes(hexData);
- util_hex_dump(" ", strlen(hexData) / 2, recordData);
-
- respGetParams.paramsInfo.recordLen = strlen(hexData) / 2;
-
- util_sms_decode_smsParameters((unsigned char *) recordData, strlen(hexData) / 2, &(respGetParams.paramsInfo));
- respGetParams.result = SMS_SENDSMS_SUCCESS;
-
- for (i = 0; i < (int) respGetParams.paramsInfo.tpSvcCntrAddr.dialNumLen; i++)
- dbg("SCAddr = %d [%02x]", i, respGetParams.paramsInfo.tpSvcCntrAddr.diallingNum[i]);
-
- g_free(recordData);
- g_free(hexData);
- } else {
- dbg("No response");
- }
- tcore_at_tok_free(tokens);
- }
- } else {
- dbg("RESPONSE NOK");
- }
-
- tcore_user_request_send_response(ur, TRESP_SMS_GET_PARAMS, sizeof(struct tresp_sms_get_params), &respGetParams);
-
- dbg("Exit");
- return;
-}
-
-static void on_response_set_sms_params(TcorePending *pending, int data_len, const void *data, void *user_data)
-{
- UserRequest *ur;
- struct tresp_sms_set_params respSetParams = {0, };
- const TcoreATResponse *atResp = data;
- int sw1 =0 , sw2 = 0;
- const char *line = NULL;
- char *pResp = NULL;
- GSList *tokens=NULL;
-
-
- memset(&respSetParams, 0, sizeof(struct tresp_sms_set_params));
- ur = tcore_pending_ref_user_request(pending);
-
- respSetParams.result = SMS_DEVICE_FAILURE;
-
- if (atResp->success > 0) {
- dbg("RESPONSE OK");
-
- if (atResp->lines) {
- line = (const char *) atResp->lines->data;
- tokens = tcore_at_tok_new(line);
- pResp = g_slist_nth_data(tokens, 0);
- if (pResp != NULL) {
- sw1 = atoi(pResp);
- } else {
- dbg("sw1 is NULL");
- }
-
- pResp = g_slist_nth_data(tokens, 1);
- if (pResp != NULL) {
- sw2 = atoi(pResp);
- if (((sw1 == AT_SW1_SUCCESS) && (sw2 == AT_SW2_SUCCESS)) || (sw1 == 0x91)) {
- respSetParams.result = SMS_SENDSMS_SUCCESS;
- }
- } else {
- dbg("sw2 is NULL");
- }
- } else {
- dbg("No lines");
- }
- } else {
- dbg("RESPONSE NOK");
- }
-
- tcore_user_request_send_response(ur, TRESP_SMS_SET_PARAMS , sizeof(struct tresp_sms_set_params), &respSetParams);
-
- if(tokens)
- tcore_at_tok_free(tokens);
-
- dbg("Exit");
- return;
-}
-
-static void on_response_get_paramcnt(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- UserRequest *ur = NULL;
- struct tresp_sms_get_paramcnt respGetParamCnt = {0, };
- const TcoreATResponse *atResp = data;
- char *line = NULL , *pResp = NULL;
- int sw1 = 0 , sw2 = 0, *smsp_record_len = NULL;
- int sim_type = 0;
- GSList *tokens=NULL;
- CoreObject *co_sim = NULL; //need this to get the sim type GSM/USIM
- TcorePlugin *plugin = NULL;
-
- dbg("Entry");
-
- ur = tcore_pending_ref_user_request(p);
- respGetParamCnt.result = SMS_DEVICE_FAILURE;
-
- if (atResp->success > 0) {
- dbg("RESPONSE OK");
-
- if (atResp->lines) {
- line = (char *) atResp->lines->data;
-
- dbg("line is %s", line);
-
- tokens = tcore_at_tok_new(line);
- pResp = g_slist_nth_data(tokens, 0);
- if (pResp != NULL) {
- sw1 = atoi(pResp);
- } else {
- dbg("sw1 is NULL");
- }
- pResp = g_slist_nth_data(tokens, 1);
- if (pResp != NULL) {
- sw2 = atoi(pResp);
- if ((sw1 == 144) && (sw2 == 0)) {
- respGetParamCnt.result = SMS_SENDSMS_SUCCESS;
- }
- } else {
- dbg("sw2 is NULL");
- }
- pResp = g_slist_nth_data(tokens, 2);
- if (pResp != NULL) {
- char *hexData = NULL;
- char *recordData = NULL;
- hexData = util_removeQuotes(pResp);
-
- /*1. SIM access success case*/
- if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
- unsigned char tag_len = 0; /* 1 or 2 bytes ??? */
- int 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;
-
- 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);
- sim_type = tcore_sim_get_type(co_sim);
- dbg("sim type is %d",sim_type);
-
- if (sim_type == 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 */
- record_len = SMS_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 */
- record_len = SMS_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!");
- g_free(hexData);
- g_free(recordData);
- tcore_at_tok_free(tokens);
- 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 */
- file_id = SMS_SWAPBYTES16(file_id);
- ptr_data = ptr_data + 2;
- dbg("Getting FileID=[0x%x]", file_id);
- } else {
- dbg("INVALID FCP received - DEbug!");
- g_free(hexData);
- g_free(recordData);
- tcore_at_tok_free(tokens);
- 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("[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 */
- arr_file_id = SMS_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);
- g_free(hexData);
- g_free(recordData);
- tcore_at_tok_free(tokens);
- 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 */
- file_size = SMS_SWAPBYTES16(file_size);
- ptr_data = ptr_data + 2;
- } else {
- dbg("INVALID FCP received - DEbug!");
- g_free(hexData);
- g_free(recordData);
- tcore_at_tok_free(tokens);
- 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!");
- g_free(hexData);
- g_free(recordData);
- tcore_at_tok_free(tokens);
- return;
- }
- } else if (sim_type == 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 */
- file_size = SMS_SWAPBYTES16(file_size);
- /* parsed file size */
- ptr_data = ptr_data + 2;
- /* file id */
- memcpy(&file_id, ptr_data, 2);
- file_id = SMS_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]", sim_type);
- }
-
- 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;
-
- //TO Store smsp record length in the property
- plugin = tcore_pending_ref_plugin(p);
- smsp_record_len = tcore_plugin_ref_property(plugin, "SMSPRECORDLEN");
- memcpy(smsp_record_len, &record_len, sizeof(int));
-
- g_free(recordData);
- g_free(hexData);
- } else {
- /*2. SIM access fail case*/
- dbg("SIM access fail");
- respGetParamCnt.result = SMS_UNKNOWN;
- }
- } else {
- dbg("presp is NULL");
- }
- } else {
- dbg("line is blank");
- }
- } else {
- dbg("RESPONSE NOK");
- }
-
- tcore_user_request_send_response(ur, TRESP_SMS_GET_PARAMCNT, sizeof(struct tresp_sms_get_paramcnt), &respGetParamCnt);
-
- if(tokens)
- tcore_at_tok_free(tokens);
-
- dbg("Exit");
- return;
-}
-
-static void _response_get_efsms_data(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- UserRequest *ur = NULL;
- UserRequest *dup_ur = NULL;
- struct tresp_sms_set_msg_status resp_msg_status = {0,};
- const struct treq_sms_set_msg_status *req_msg_status = NULL ;
-
- const TcoreATResponse *resp = data;
- char *encoded_data = NULL;
- char msg_status = 0;
- char *pResp = NULL;
- GSList *tokens=NULL;
- const char *line = NULL;
- int sw1 = 0;
- int sw2 = 0;
-
- TcoreHal *hal = NULL;
- TcoreATRequest *atreq = NULL;
- TcorePending *pending = NULL;
- gchar *cmd_str = NULL;
-
- ur = tcore_pending_ref_user_request(p);
-
- req_msg_status = tcore_user_request_ref_data(ur, NULL);
-
- resp_msg_status.result = SMS_DEVICE_FAILURE;
-
- hal = tcore_object_get_hal(tcore_pending_ref_core_object(pending));
- dbg("msgStatus: [%x], index [%x]", req_msg_status->msgStatus, req_msg_status->index);
-
- if (resp->success <= 0) {
- goto OUT;
- }
-
- {
- dbg("RESPONSE OK");
- if (resp->lines) {
- line = (const char *) resp->lines->data;
- tokens = tcore_at_tok_new(line);
- if (g_slist_length(tokens) != 3) {
- msg("invalid message");
- goto OUT;
- }
- }
- sw1 = atoi(g_slist_nth_data(tokens, 0));
- sw2 = atoi(g_slist_nth_data(tokens, 1));
- pResp = g_slist_nth_data(tokens, 2);
-
- if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
- switch (req_msg_status->msgStatus) {
- case SMS_STATUS_READ:
- msg_status = 0x01;
- break;
-
- case SMS_STATUS_UNREAD:
- msg_status = 0x03;
- break;
-
- case SMS_STATUS_UNSENT:
- msg_status = 0x07;
- break;
-
- case SMS_STATUS_SENT:
- msg_status = 0x05;
- break;
-
- case SMS_STATUS_DELIVERED:
- msg_status = 0x1D;
- break;
-
- case SMS_STATUS_DELIVERY_UNCONFIRMED:
- msg_status = 0xD;
- break;
-
- case SMS_STATUS_MESSAGE_REPLACED:
- case SMS_STATUS_RESERVED:
- default:
- msg_status = 0x03;
- break;
- }
-
- encoded_data = util_removeQuotes(pResp);
-
- //overwrite Status byte information
- util_byte_to_hex((const char *)&msg_status, (char *)encoded_data, 1);
-
- //Update EF-SMS with just status byte overwritten, rest 175 bytes are same as received in read information
- cmd_str = g_strdup_printf("AT+CRSM=220,28476,%d, 4, %d, \"%s\"", req_msg_status->index, PDU_LEN_MAX, encoded_data);
- atreq = tcore_at_request_new((const char *)cmd_str, "+CRSM", TCORE_AT_SINGLELINE);
- pending = tcore_pending_new(tcore_pending_ref_core_object(pending), 0);
- if (NULL == cmd_str || NULL == atreq || NULL == pending) {
- err("Out of memory. Unable to proceed");
- dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
-
- //free memory we own
- g_free(cmd_str);
- g_free(encoded_data);
- util_sms_free_memory(atreq);
- util_sms_free_memory(pending);
-
- goto OUT;
- }
-
- util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
-
- dup_ur = tcore_user_request_ref(ur);
-
- tcore_pending_set_request_data(pending, 0, atreq);
- tcore_pending_set_response_callback(pending, on_response_set_msg_status, NULL);
- tcore_pending_link_user_request(pending, dup_ur);
- tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
- tcore_hal_send_request(hal, pending);
-
- g_free(cmd_str);
- g_free(encoded_data);
- }
- }
-
-OUT:
- if(tokens)
- tcore_at_tok_free(tokens);
-
- tcore_user_request_send_response(ur, TRESP_SMS_SET_MSG_STATUS , sizeof(struct tresp_sms_set_msg_status), &msg_status);
-
- dbg("Exit");
-
- return;
-}
-
-/*=============================================================
- Requests
-==============================================================*/
-static TReturn send_umts_msg(CoreObject *co_sms, UserRequest *ur)
-{
- const struct treq_sms_send_umts_msg *send_msg;
- const unsigned char *tpdu_byte_data, *sca_byte_data;
- int tpdu_byte_len, pdu_byte_len;
- char buf[HEX_PDU_LEN_MAX];
- char pdu[PDU_LEN_MAX];
- char *cmd_str;
- int pdu_hex_len, mms;
- TReturn ret;
-
- dbg("Enter");
-
- send_msg = tcore_user_request_ref_data(ur, NULL);
-
- tpdu_byte_data = send_msg->msgDataPackage.tpduData;
- sca_byte_data = send_msg->msgDataPackage.sca;
-
-
- /* TPDU length is in byte */
- tpdu_byte_len = send_msg->msgDataPackage.msgLength;
-
- /* Use same Radio Resource Channel */
- mms = send_msg->more;
-
- dbg("TDPU length: [%d]", tpdu_byte_len);
- dbg("SCA semi-octet length: [%d]", sca_byte_data[0]);
-
- /* Prepare PDU for hex encoding */
- pdu_byte_len = tcore_util_pdu_encode(sca_byte_data, tpdu_byte_data,
- tpdu_byte_len, pdu);
-
- pdu_hex_len = (int) tcore_util_encode_hex((unsigned char *) pdu,
- pdu_byte_len, buf);
-
- dbg("PDU hexadecimal length: [%d]", pdu_hex_len);
-
- if (mms > 0) {
- cmd_str = g_strdup_printf("AT+CMMS=%d", mms);
-
- ret = tcore_prepare_and_send_at_request(co_sms, cmd_str, NULL,
- TCORE_AT_NO_RESULT, NULL, NULL, NULL,
- on_confirmation_sms_message_send,
- NULL);
- if (ret != TCORE_RETURN_SUCCESS) {
- err("Failed to prepare and send AT request");
- goto error;
- }
-
- g_free(cmd_str);
- }
-
- cmd_str = g_strdup_printf("AT+CMGS=%d\r%s\x1A", tpdu_byte_len, buf);
-
- ret = tcore_prepare_and_send_at_request(co_sms, cmd_str, "+CMGS:",
- TCORE_AT_SINGLELINE, ur,
- on_response_send_umts_msg, NULL,
- on_confirmation_sms_message_send, NULL);
- if (ret != TCORE_RETURN_SUCCESS)
- err("Failed to prepare and send AT request");
-
-error:
- g_free(cmd_str);
-
- dbg("Exit");
-
- return ret;
-}
-
-static TReturn read_msg(CoreObject *obj, UserRequest *ur)
-{
- gchar *cmd_str = NULL;
- TcoreHal *hal = NULL;
- TcoreATRequest *atreq = NULL;
- TcorePending *pending = NULL;
- const struct treq_sms_read_msg *readMsg = NULL;
-
- dbg("Entry");
-
- readMsg = tcore_user_request_ref_data(ur, NULL);
- hal = tcore_object_get_hal(obj);
- if (NULL == readMsg || NULL == hal) {
- err("NULL input. Unable to proceed");
- dbg("readMsg: [%p], hal: [%p]", readMsg, hal);
-
- dbg("Exit");
- return TCORE_RETURN_EINVAL;
- }
-
- if(FALSE == tcore_hal_get_power_state(hal)){
- dbg("cp not ready/n");
- return TCORE_RETURN_ENOSYS;
- }
- dbg("index: [%d]", readMsg->index);
-
- cmd_str = g_strdup_printf("AT+CMGR=%d", readMsg->index); //IMC index is one ahead of TAPI
- atreq = tcore_at_request_new((const char *)cmd_str, "+CMGR", TCORE_AT_PDU);
- pending = tcore_pending_new(obj, 0);
-
- if (NULL == cmd_str || NULL == atreq || NULL == pending) {
- err("Out of memory. Unable to proceed");
- dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
-
- //free memory we own
- g_free(cmd_str);
- util_sms_free_memory(atreq);
- util_sms_free_memory(pending);
-
- dbg("Exit");
- return TCORE_RETURN_ENOMEM;
- }
-
- util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
-
- tcore_pending_set_request_data(pending, 0, atreq);
- tcore_pending_set_response_callback(pending, on_response_read_msg, (void *)(uintptr_t)(readMsg->index)); //storing index as user data for response
- tcore_pending_link_user_request(pending, ur);
- tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
- tcore_hal_send_request(hal, pending);
-
- g_free(cmd_str);
-
- dbg("Exit");
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn save_msg(CoreObject *obj, UserRequest *ur)
-{
- gchar *cmd_str = NULL;
- TcoreHal *hal = NULL;
- TcoreATRequest *atreq = NULL;
- TcorePending *pending = NULL;
- const struct treq_sms_save_msg *saveMsg = NULL;
- int ScLength = 0, pdu_len = 0, stat = 0;
- char buf[2*(SMS_SMSP_ADDRESS_LEN+SMS_SMDATA_SIZE_MAX)+1] = {0};
- char *hex_pdu = NULL;
-
- dbg("Entry");
-
- saveMsg = tcore_user_request_ref_data(ur, NULL);
- hal = tcore_object_get_hal(obj);
- if (NULL == saveMsg || NULL == hal) {
- err("NULL input. Unable to proceed");
- dbg("saveMsg: [%p], hal: [%p]", saveMsg, hal);
-
- dbg("Exit");
- return TCORE_RETURN_EINVAL;
- }
- if(FALSE == tcore_hal_get_power_state(hal)){
- dbg("cp not ready/n");
- return TCORE_RETURN_ENOSYS;
- }
-
- dbg("msgStatus: %x, msgLength: [%d]", saveMsg->msgStatus, saveMsg->msgDataPackage.msgLength);
- util_hex_dump(" ", (SMS_SMDATA_SIZE_MAX+1), (void *)saveMsg->msgDataPackage.tpduData);
- util_hex_dump(" ", SMS_SMSP_ADDRESS_LEN, (void *)saveMsg->msgDataPackage.sca);
-
- switch (saveMsg->msgStatus) {
- case SMS_STATUS_READ:
- stat = AT_REC_READ;
- break;
-
- case SMS_STATUS_UNREAD:
- stat = AT_REC_UNREAD;
- break;
-
- case SMS_STATUS_SENT:
- stat = AT_STO_SENT;
- break;
-
- case SMS_STATUS_UNSENT:
- stat = AT_STO_UNSENT;
- break;
-
- default:
- err("Invalid msgStatus");
- dbg("Exit");
- return TCORE_RETURN_EINVAL;
- }
-
- if ((saveMsg->msgDataPackage.msgLength > 0)
- && (saveMsg->msgDataPackage.msgLength <= SMS_SMDATA_SIZE_MAX)) {
- ScLength = (int)saveMsg->msgDataPackage.sca[0];
-
- buf[0] = ScLength;
- dbg("ScLength = %d", ScLength);
-
- if(ScLength == 0) {
- buf[0] = 0;
- } else {
- memcpy(&buf[1], saveMsg->msgDataPackage.sca, ScLength);
- }
-
- memcpy(&buf[ScLength+1], saveMsg->msgDataPackage.tpduData, saveMsg->msgDataPackage.msgLength);
-
- pdu_len= saveMsg->msgDataPackage.msgLength + ScLength + 1;
- dbg("pdu_len: [%d]", pdu_len);
-
- hex_pdu = malloc(pdu_len * 2 + 1);
- util_hex_dump(" ", sizeof(buf), (void *)buf);
-
- memset (hex_pdu, 0x00, pdu_len * 2 + 1);
-
- util_byte_to_hex((const char *)buf, (char *)hex_pdu, pdu_len);
-
- //AT+CMGW=<length>[,<stat>]<CR>PDU is given<ctrl-Z/ESC>
- cmd_str = g_strdup_printf("AT+CMGW=%d,%d%s%s\x1A", saveMsg->msgDataPackage.msgLength, stat, "\r", hex_pdu);
- pending = tcore_pending_new(obj, 0);
- atreq = tcore_at_request_new((const char *)cmd_str, "+CMGW", TCORE_AT_SINGLELINE);
-
- if(NULL == cmd_str || NULL == atreq || NULL == pending) {
- err("Out of memory. Unable to proceed");
- dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
-
- //free memory we own
- g_free(cmd_str);
- util_sms_free_memory(atreq);
- util_sms_free_memory(pending);
- util_sms_free_memory(hex_pdu);
-
- dbg("Exit");
- return TCORE_RETURN_ENOMEM;
- }
-
- util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
-
- tcore_pending_set_request_data(pending, 0, atreq);
- tcore_pending_set_response_callback(pending, on_response_sms_save_msg, NULL);
- tcore_pending_link_user_request(pending, ur);
- tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
- tcore_hal_send_request(hal, pending);
-
- g_free(cmd_str);
- free(hex_pdu);
-
- dbg("Exit");
- return TCORE_RETURN_SUCCESS;
- }
-
- err("Invalid Data len");
- dbg("Exit");
- return TCORE_RETURN_SMS_INVALID_DATA_LEN;
-}
-
-static TReturn delete_msg(CoreObject *obj, UserRequest *ur)
-{
- gchar *cmd_str = NULL;
- TcoreHal *hal = NULL;
- TcoreATRequest *atreq = NULL;
- TcorePending *pending = NULL;
- const struct treq_sms_delete_msg *delete_msg = NULL;
-
- dbg("Entry");
-
- delete_msg = tcore_user_request_ref_data(ur, NULL);
- hal = tcore_object_get_hal(obj);
- if (NULL == delete_msg || NULL == hal) {
- err("NULL input. Unable to proceed");
- dbg("deleteMsg: [%p], hal: [%p]", delete_msg, hal);
-
- dbg("Exit");
- return TCORE_RETURN_EINVAL;
- }
-
- if(FALSE == tcore_hal_get_power_state(hal)){
- dbg("cp not ready/n");
- return TCORE_RETURN_ENOSYS;
- }
-
- dbg("index: %d", delete_msg->index);
-
- if (delete_msg->index == -1) {
- cmd_str = g_strdup_printf("AT+CMGD=0,4"); // Delete All Messages
- } else {
- cmd_str = g_strdup_printf("AT+CMGD=%d,0", delete_msg->index); // Delete specified index
- }
-
- pending = tcore_pending_new(obj, 0);
- atreq = tcore_at_request_new((const char *)cmd_str, NULL, TCORE_AT_NO_RESULT);
- if (NULL == cmd_str || NULL == atreq || NULL == pending) {
- err("Out of memory. Unable to proceed");
- dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
-
- //free memory we own
- g_free(cmd_str);
- util_sms_free_memory(atreq);
- util_sms_free_memory(pending);
-
- dbg("Exit");
- return TCORE_RETURN_ENOMEM;
- }
-
- util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
-
- tcore_pending_set_request_data(pending, 0, atreq);
- tcore_pending_set_response_callback(pending, on_response_sms_delete_msg, (void *) (uintptr_t) (delete_msg->index)); // storing index as user data for response
- tcore_pending_link_user_request(pending, ur);
- tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
- tcore_hal_send_request(hal, pending);
-
- g_free(cmd_str);
-
- dbg("Exit");
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn get_stored_msg_cnt(CoreObject *obj, UserRequest *ur)
-{
- gchar *cmd_str = NULL;
- TcoreHal *hal = NULL;
- TcoreATRequest *atreq = NULL;
- TcorePending *pending = NULL;
-
- dbg("Entry");
-
- hal = tcore_object_get_hal(obj);
- if (NULL == hal) {
- err("NULL HAL. Unable to proceed");
-
- dbg("Exit");
- return TCORE_RETURN_EINVAL;
- }
-
- if(FALSE == tcore_hal_get_power_state(hal)){
- dbg("cp not ready/n");
- return TCORE_RETURN_ENOSYS;
- }
-
- cmd_str = g_strdup_printf("AT+CPMS=\"SM\"");
- pending = tcore_pending_new(obj, 0);
- atreq = tcore_at_request_new((const char *)cmd_str, "+CPMS", TCORE_AT_SINGLELINE);
-
- if (NULL == cmd_str || NULL == atreq || NULL == pending) {
- err("Out of memory. Unable to proceed");
- dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
-
- //free memory we own
- g_free(cmd_str);
- util_sms_free_memory(atreq);
- util_sms_free_memory(pending);
-
- dbg("Exit");
- return TCORE_RETURN_ENOMEM;
- }
-
- util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
-
- tcore_pending_set_request_data(pending, 0, atreq);
- tcore_pending_set_response_callback(pending, on_response_get_stored_msg_cnt, NULL);
- tcore_pending_link_user_request(pending, ur);
- tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
- tcore_hal_send_request(hal, pending);
-
- g_free(cmd_str);
-
- dbg("Exit");
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn get_sca(CoreObject *obj, UserRequest *ur)
-{
- gchar * cmd_str = NULL;
- TcoreHal *hal = NULL;
- TcoreATRequest *atreq = NULL;
- TcorePending *pending = NULL;
-
- dbg("Entry");
-
- hal = tcore_object_get_hal(obj);
- if (NULL == hal) {
- err("HAL NULL. Unable to proceed");
-
- dbg("Exit");
- return TCORE_RETURN_EINVAL;
- }
- if(FALSE == tcore_hal_get_power_state(hal)){
- dbg("cp not ready/n");
- return TCORE_RETURN_ENOSYS;
- }
-
- cmd_str = g_strdup_printf("AT+CSCA?");
- pending = tcore_pending_new(obj, 0);
- atreq = tcore_at_request_new((const char *)cmd_str, "+CSCA", TCORE_AT_SINGLELINE);
-
- if (NULL == cmd_str || NULL == atreq || NULL == pending) {
- err("Out of memory. Unable to proceed");
- dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
-
- //free memory we own
- g_free(cmd_str);
- util_sms_free_memory(atreq);
- util_sms_free_memory(pending);
-
- dbg("Exit");
- return TCORE_RETURN_ENOMEM;
- }
-
- util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
-
- tcore_pending_set_request_data(pending, 0, atreq);
- 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);
- tcore_hal_send_request(hal, pending);
-
- g_free(cmd_str);
-
- dbg("Exit");
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn set_sca(CoreObject *obj, UserRequest *ur)
-{
- gchar *cmd_str = NULL;
- TcoreHal *hal = NULL;
- TcoreATRequest *atreq = NULL;
- TcorePending *pending = NULL;
- const struct treq_sms_set_sca *setSca = NULL;
- int addrType = 0;
-
- dbg("Entry");
-
- setSca = tcore_user_request_ref_data(ur, NULL);
- hal = tcore_object_get_hal(obj);
- if (NULL == setSca || NULL == hal) {
- err("NULL input. Unable to proceed");
- dbg("setSca: [%p], hal: [%p]", setSca, hal);
-
- dbg("Exit");
- return TCORE_RETURN_EINVAL;
- }
- if(FALSE == tcore_hal_get_power_state(hal)){
- dbg("cp not ready/n");
- return TCORE_RETURN_ENOSYS;
- }
-
- dbg("dialNumLen: %u, typeOfNum: %d, numPlanId: %d, ", setSca->scaInfo.dialNumLen, setSca->scaInfo.typeOfNum, setSca->scaInfo.numPlanId);
-
- util_hex_dump(" ", (SMS_SMSP_ADDRESS_LEN+1), (void *)setSca->scaInfo.diallingNum);
-
- addrType = ((setSca->scaInfo.typeOfNum << 4) | setSca->scaInfo.numPlanId) | 0x80;
-
- cmd_str = g_strdup_printf("AT+CSCA=\"%s\",%d", setSca->scaInfo.diallingNum, addrType);
- pending = tcore_pending_new(obj, 0);
- atreq = tcore_at_request_new((const char *)cmd_str, NULL, TCORE_AT_NO_RESULT);
-
- if (NULL == cmd_str || NULL == atreq || NULL == pending) {
- err("Out of memory. Unable to proceed");
- dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
-
- //free memory we own
- g_free(cmd_str);
- util_sms_free_memory(atreq);
- util_sms_free_memory(pending);
-
- dbg("Exit");
- return TCORE_RETURN_ENOMEM;
- }
-
- util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
-
- tcore_pending_set_request_data(pending, 0, atreq);
- 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);
- tcore_hal_send_request(hal, pending);
-
- g_free(cmd_str);
-
- dbg("Exit");
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn get_cb_config(CoreObject *obj, UserRequest *ur)
-{
- gchar *cmd_str = NULL;
- TcoreHal *hal = NULL;
- TcoreATRequest *atreq = NULL;
- TcorePending *pending = NULL;
-
- dbg("Entry");
-
- hal = tcore_object_get_hal(obj);
- if (NULL == hal) {
- err("NULL HAL. Unable to proceed");
-
- dbg("Exit");
- return TCORE_RETURN_EINVAL;
- }
- if(FALSE == tcore_hal_get_power_state(hal)){
- dbg("cp not ready/n");
- return TCORE_RETURN_ENOSYS;
- }
-
- cmd_str = g_strdup_printf("AT+CSCB?");
- pending = tcore_pending_new(obj, 0);
- atreq = tcore_at_request_new((const char *)cmd_str, "+CSCB", TCORE_AT_SINGLELINE);
- if (NULL == cmd_str || NULL == atreq || NULL == pending) {
- err("Out of memory. Unable to proceed");
- dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
-
- //free memory we own
- g_free(cmd_str);
- util_sms_free_memory(atreq);
- util_sms_free_memory(pending);
-
- dbg("Exit");
- return TCORE_RETURN_ENOMEM;
- }
-
- util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
-
- tcore_pending_set_request_data(pending, 0, atreq);
- tcore_pending_set_response_callback(pending, on_response_get_cb_config, NULL);
- tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
- tcore_pending_link_user_request(pending, ur);
- tcore_hal_send_request(hal, pending);
-
- g_free(cmd_str);
-
- dbg("Exit");
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn set_cb_config(CoreObject *obj, UserRequest *ur)
-{
- gchar *cmd_str = NULL;
- gchar *mids_str = NULL;
- GString *mids_GString = NULL;
-
- TcoreHal *hal = NULL;
- TcoreATRequest *atreq = NULL;
- TcorePending *pending = NULL;
- const struct treq_sms_set_cb_config *setCbConfig = NULL;
- int ctr1= 0, ctr2 =0;
- unsigned short appendMsgId = 0;
-
- dbg("Entry");
-
- setCbConfig = tcore_user_request_ref_data(ur, NULL);
- hal = tcore_object_get_hal(obj);
- if (NULL == setCbConfig || NULL == hal) {
- err("NULL input. Unable to proceed");
- dbg("setCbConfig: [%p], hal: [%p]", setCbConfig, hal);
-
- dbg("Exit");
- return TCORE_RETURN_EINVAL;
- }
- if(FALSE == tcore_hal_get_power_state(hal)){
- dbg("cp not ready/n");
- return TCORE_RETURN_ENOSYS;
- }
-
- dbg("bCBEnabled: %d, msgIdCount: %d", setCbConfig->cbEnabled, setCbConfig->msgIdRangeCount);
-
- if (setCbConfig->cbEnabled == 2) { //Enable all CBS
- cmd_str = g_strdup_printf("AT+CSCB=1");
- } else if ((setCbConfig->cbEnabled == 1) && (setCbConfig->msgIdRangeCount == 0)) { // Special case: Enable all CBS
- cmd_str = g_strdup_printf("AT+CSCB=1");
- } else if (setCbConfig->cbEnabled == 0) {//AT+CSCB=0: Disable CBS
- cmd_str = g_strdup_printf("AT+CSCB=0");
- } else {
- mids_GString = g_string_new("AT+CSCB=0,\"");
-
- for(ctr1 = 0; ctr1 < setCbConfig->msgIdRangeCount; ctr1++ ) {
- if( setCbConfig->msgIDs[ctr1].net3gpp.selected == FALSE )
- continue;
-
- if( SMS_GSM_SMS_CBMI_LIST_SIZE_MAX <= (setCbConfig->msgIDs[ctr1].net3gpp.toMsgId - setCbConfig->msgIDs[ctr1].net3gpp.fromMsgId) ) {
- mids_GString = g_string_new("AT+CSCB=1");
- break;
- }
-
- appendMsgId = setCbConfig->msgIDs[ctr1].net3gpp.fromMsgId;
-
- for( ctr2 = 0; (ctr2 <= ((setCbConfig->msgIDs[ctr1].net3gpp.toMsgId) - (setCbConfig->msgIDs[ctr1].net3gpp.fromMsgId))); ctr2++ ) {
- dbg( "%x", appendMsgId);
- mids_GString = g_string_append(mids_GString, g_strdup_printf("%d", appendMsgId));
-
- if (ctr2 == ((setCbConfig->msgIDs[ctr1].net3gpp.toMsgId) - (setCbConfig->msgIDs[ctr1].net3gpp.fromMsgId))) {
- mids_GString = g_string_append(mids_GString, "\""); //Mids string termination
- } else {
- mids_GString = g_string_append(mids_GString, ",");
- }
-
- appendMsgId++;
- }
- }
- mids_str = g_string_free(mids_GString, FALSE);
- cmd_str = g_strdup_printf("%s", mids_str);
- g_free(mids_str);
- }
-
- pending = tcore_pending_new(obj, 0);
- atreq = tcore_at_request_new((const char *)cmd_str, NULL, TCORE_AT_NO_RESULT);
- if(NULL == cmd_str || NULL == atreq || NULL == pending) {
- err("Out of memory. Unable to proceed");
- dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
-
- //free memory we own
- g_free(cmd_str);
- util_sms_free_memory(atreq);
- util_sms_free_memory(pending);
-
- dbg("Exit");
- return TCORE_RETURN_ENOMEM;
- }
-
- util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
-
- tcore_pending_set_request_data(pending, 0, atreq);
- tcore_pending_set_response_callback(pending, on_response_set_cb_config, NULL);
- tcore_pending_link_user_request(pending, ur);
- tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
- tcore_hal_send_request(hal, pending);
-
- g_free(cmd_str);
-
- dbg("Exit");
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn set_mem_status(CoreObject *obj, UserRequest *ur)
-{
- gchar *cmd_str = NULL;
- TcoreHal *hal = NULL;
- TcoreATRequest *atreq = NULL;
- TcorePending *pending = NULL;
- const struct treq_sms_set_mem_status *setMemStatus = NULL;
- int memoryStatus = 0;
-
- dbg("Entry");
-
- setMemStatus = tcore_user_request_ref_data(ur, NULL);
- hal = tcore_object_get_hal(obj);
- if (NULL == setMemStatus || NULL == hal) {
- err("NULL input. Unable to proceed");
- dbg("setMemStatus: [%p], hal: [%p]", setMemStatus, hal);
-
- dbg("Exit");
- return TCORE_RETURN_EINVAL;
- }
- if(FALSE == tcore_hal_get_power_state(hal)){
- dbg("cp not ready/n");
- return TCORE_RETURN_ENOSYS;
- }
-
- dbg("memory_status: %d", setMemStatus->memory_status);
-
- if(setMemStatus->memory_status < SMS_PDA_MEMORY_STATUS_AVAILABLE
- || setMemStatus->memory_status > SMS_PDA_MEMORY_STATUS_FULL) {
- err("Invalid memory_status");
-
- dbg("Exit");
- return TCORE_RETURN_EINVAL;
- }
-
- switch (setMemStatus->memory_status) {
- case SMS_PDA_MEMORY_STATUS_AVAILABLE:
- memoryStatus = AT_MEMORY_AVAILABLE;
- break;
-
- case SMS_PDA_MEMORY_STATUS_FULL:
- memoryStatus = AT_MEMORY_FULL;
- break;
-
- default:
- err("Invalid memory_status");
- dbg("Exit");
- return TCORE_RETURN_EINVAL;
- }
-
- cmd_str = g_strdup_printf("AT+XTESM=%d", memoryStatus);
- pending = tcore_pending_new(obj, 0);
- atreq = tcore_at_request_new((const char *)cmd_str, NULL, TCORE_AT_NO_RESULT);
-
- if (NULL == cmd_str || NULL == atreq || NULL == pending) {
- err("Out of memory. Unable to proceed");
- dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
-
- //free memory we own
- g_free(cmd_str);
- util_sms_free_memory(atreq);
- util_sms_free_memory(pending);
-
- dbg("Exit");
- return TCORE_RETURN_ENOMEM;
- }
-
- util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
-
- tcore_pending_set_request_data(pending, 0, atreq);
- tcore_pending_set_response_callback(pending, on_response_set_mem_status, NULL);
- tcore_pending_link_user_request(pending, ur);
- tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
- tcore_hal_send_request(hal, pending);
-
- g_free(cmd_str);
-
- dbg("Exit");
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn set_delivery_report(CoreObject *obj, UserRequest *ur)
-{
- struct tresp_sms_set_delivery_report respSetDeliveryReport = {0,};
-
- respSetDeliveryReport.result = SMS_SUCCESS;
-
- dbg("Entry");
- if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(obj))){
- dbg("cp not ready/n");
- return TCORE_RETURN_ENOSYS;
- }
-
- dbg("CP takes care of sending SMS ack to network for all classes of SMS. Sending default success.");
-
- tcore_user_request_send_response(ur, TRESP_SMS_SET_DELIVERY_REPORT, sizeof(struct tresp_sms_set_delivery_report), &respSetDeliveryReport);
-
- dbg("Exit");
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn set_msg_status(CoreObject *obj, UserRequest *ur)
-{
- gchar *cmd_str = NULL;
- TcoreHal *hal = NULL;
- TcoreATRequest *atreq = NULL;
- TcorePending *pending = NULL;
- const struct treq_sms_set_msg_status *msg_status = NULL;
-
- dbg("Entry");
- hal = tcore_object_get_hal(obj);
- if(FALSE == tcore_hal_get_power_state(hal)){
- dbg("cp not ready/n");
- return TCORE_RETURN_ENOSYS;
- }
- msg_status = tcore_user_request_ref_data(ur, NULL);
-
- cmd_str = g_strdup_printf("AT+CRSM=178,28476,%d,4,%d", msg_status->index, PDU_LEN_MAX);
- atreq = tcore_at_request_new((const char *)cmd_str, "+CRSM", TCORE_AT_SINGLELINE);
- pending = tcore_pending_new(obj, 0);
- if (NULL == cmd_str || NULL == atreq || NULL == pending) {
- err("Out of memory. Unable to proceed");
- dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
-
- //free memory we own
- g_free(cmd_str);
- util_sms_free_memory(atreq);
- util_sms_free_memory(pending);
-
- dbg("Exit");
- return TCORE_RETURN_ENOMEM;
- }
-
- util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
-
- tcore_pending_set_request_data(pending, 0, atreq);
- tcore_pending_set_response_callback(pending, _response_get_efsms_data, NULL);
- tcore_pending_link_user_request(pending, ur);
- tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
- tcore_hal_send_request(hal, pending);
-
- g_free(cmd_str);
-
- dbg("Exit");
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn get_sms_params(CoreObject *obj, UserRequest *ur)
-{
- gchar *cmd_str = NULL;
- TcoreHal *hal = NULL;
- TcoreATRequest *atreq = NULL;
- TcorePending *pending = NULL;
- const struct treq_sms_get_params *getSmsParams = NULL;
- int record_len = 0 , *smsp_record_len = NULL;
-
- dbg("Entry");
-
- getSmsParams = tcore_user_request_ref_data(ur, NULL);
- hal = tcore_object_get_hal(obj);
- if (NULL == getSmsParams || NULL == hal) {
- err("NULL input. Unable to proceed");
- dbg("getSmsParams: [%p], hal: [%p]", getSmsParams, hal);
-
- dbg("Exit");
- return TCORE_RETURN_EINVAL;
- }
- if(FALSE == tcore_hal_get_power_state(hal)){
- dbg("cp not ready/n");
- return TCORE_RETURN_ENOSYS;
- }
-
- smsp_record_len = tcore_plugin_ref_property(tcore_object_ref_plugin(obj), "SMSPRECORDLEN");
- record_len = *smsp_record_len;
- dbg("record len from property %d", record_len);
-
- //AT+CRSM=command>[,<fileid>[,<P1>,<P2>,<P3>[,<data>[,<pathid>]]]]
- cmd_str = g_strdup_printf("AT+CRSM=178,28482,%d,4,%d", (getSmsParams->index + 1), record_len);
-
- dbg("cmd_str is %s",cmd_str);
-
- atreq = tcore_at_request_new((const char *)cmd_str, "+CRSM", TCORE_AT_SINGLELINE);
- pending = tcore_pending_new(obj, 0);
- if (NULL == cmd_str || NULL == atreq || NULL == pending) {
- err("Out of memory. Unable to proceed");
- dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
-
- //free memory we own
- g_free(cmd_str);
- util_sms_free_memory(atreq);
- util_sms_free_memory(pending);
-
- dbg("Exit");
- return TCORE_RETURN_ENOMEM;
- }
-
- util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
-
- tcore_pending_set_request_data(pending, 0, atreq);
- 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);
- tcore_hal_send_request(hal, pending);
-
- g_free(cmd_str);
-
- dbg("Exit");
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn set_sms_params(CoreObject *obj, UserRequest *ur)
-{
- gchar *cmd_str = NULL;
- char *encoded_data = NULL;
- unsigned char *temp_data = NULL;
- int SMSPRecordLen = 0;
- int *smsp_record_len;
-
- TcoreHal *hal = NULL;
- TcoreATRequest *atreq = NULL;
- TcorePending *pending = NULL;
- const struct treq_sms_set_params *setSmsParams = NULL;
- int encoded_data_len = 0;
-
- dbg("Entry");
-
- setSmsParams = tcore_user_request_ref_data(ur, NULL);
- hal = tcore_object_get_hal(obj);
- if (NULL == setSmsParams || NULL == hal) {
- err("NULL input. Unable to proceed");
- dbg("setSmsParams: [%p], hal: [%p]", setSmsParams, hal);
- return FALSE;
- }
- if(FALSE == tcore_hal_get_power_state(hal)){
- dbg("cp not ready/n");
- return TCORE_RETURN_ENOSYS;
- }
-
- //EFsmsp file size is 28 +Y bytes (Y is alpha id size)
- smsp_record_len = tcore_plugin_ref_property(tcore_object_ref_plugin(obj), "SMSPRECORDLEN");
- SMSPRecordLen = *smsp_record_len;
- if (SMSPRecordLen < nDefaultSMSPWithoutAlphaId)
- return FALSE;
-
- 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);
-
- hal = tcore_object_get_hal(obj);
- pending = tcore_pending_new(obj, 0);
-
- dbg("alpha id len %d encoded data %s. Encoded data len %d",setSmsParams->params.alphaIdLen,encoded_data, encoded_data_len);
- cmd_str = g_strdup_printf("AT+CRSM=220,28482,%d,4,%d,\"%s\"",(setSmsParams->params.recordIndex+1),SMSPRecordLen,encoded_data);
-
- dbg("cmd str is %s",cmd_str);
- atreq = tcore_at_request_new(cmd_str, "+CRSM:", TCORE_AT_SINGLELINE);
-
- if (NULL == cmd_str || NULL == atreq || NULL == pending) {
- err("Out of memory. Unable to proceed");
- dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
-
- //free memory we own
- g_free(cmd_str);
- util_sms_free_memory(atreq);
- util_sms_free_memory(pending);
-
- util_sms_free_memory(temp_data);
- util_sms_free_memory(encoded_data);
-
- dbg("Exit");
- return TCORE_RETURN_ENOMEM;
- }
-
- util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
-
- tcore_pending_set_request_data(pending, 0,atreq);
- 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);
- tcore_hal_send_request(hal, pending);
-
- g_free(cmd_str);
- util_sms_free_memory(temp_data);
- util_sms_free_memory(encoded_data);
-
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn get_paramcnt(CoreObject *obj, UserRequest *ur)
-{
- gchar *cmd_str = NULL;
- TcoreHal *hal = NULL;
- TcoreATRequest *atreq = NULL;
- TcorePending *pending = NULL;
-
- dbg("Entry");
-
- hal = tcore_object_get_hal(obj);
- if (NULL == hal) {
- err("NULL HAL. Unable to proceed");
-
- dbg("Exit");
- return TCORE_RETURN_EINVAL;
- }
- if(FALSE == tcore_hal_get_power_state(hal)){
- dbg("cp not ready/n");
- return TCORE_RETURN_ENOSYS;
- }
-
- //AT+CRSM=command>[,<fileid>[,<P1>,<P2>,<P3>[,<data>[,<pathid>]]]]
- cmd_str = g_strdup_printf("AT+CRSM=192,28482");
- atreq = tcore_at_request_new((const char *)cmd_str, "+CRSM", TCORE_AT_SINGLELINE);
- pending = tcore_pending_new(obj, 0);
-
- if (NULL == cmd_str || NULL == atreq || NULL == pending) {
- err("NULL pointer. Unable to proceed");
- dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
-
- //free memory we own
- g_free(cmd_str);
- util_sms_free_memory(atreq);
- util_sms_free_memory(pending);
-
- dbg("Exit");
- return TCORE_RETURN_FAILURE;
- }
-
- util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
-
- tcore_pending_set_request_data(pending, 0, atreq);
- 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);
- tcore_hal_send_request(hal, pending);
-
- g_free(cmd_str);
-
- dbg("Exit");
- return TCORE_RETURN_SUCCESS;
-}
-
-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_stored_msg_cnt,
- .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 = NULL,
- .set_pref_brearer = NULL,
- .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,
-};
-
-gboolean s_sms_init(TcorePlugin *cp, CoreObject *co_sms)
-{
- int *smsp_record_len;
- dbg("Entry");
-
- /* Override SMS Operations */
- tcore_sms_override_ops(co_sms, &sms_ops);
-
- /* Registering for SMS notifications */
- tcore_object_override_callback(co_sms, "+CMTI:", on_event_class2_sms_incom_msg, NULL);
- tcore_object_override_callback(co_sms, "\e+CMT:", on_event_sms_incom_msg, NULL);
-
- tcore_object_override_callback(co_sms, "\e+CDS", on_event_sms_incom_msg, NULL);
- tcore_object_override_callback(co_sms, "+XSMSMMSTAT", on_event_sms_memory_status, NULL);
- tcore_object_override_callback(co_sms, "+CMS", on_event_sms_memory_status, NULL);
-
- tcore_object_override_callback(co_sms, "+CBMI:", on_event_sms_cb_incom_msg, NULL);
- tcore_object_override_callback(co_sms, "\e+CBM:", on_event_sms_cb_incom_msg, 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_sms)
-{
- int *smsp_record_len;
-
- smsp_record_len = tcore_plugin_ref_property(cp, "SMSPRECORDLEN");
- g_free(smsp_record_len);
-
- dbg("Exit");
-}
+++ /dev/null
-/*
- * tel-plugin-imc
- *
- * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: sharanayya mathapati <sharan.m@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 <util.h>
-#include <server.h>
-#include <at.h>
-
-#include "s_common.h"
-#include "s_ss.h"
-
-#define NUM_TYPE_INTERNATIONAL 0x01
-#define NUM_PLAN_ISDN 0x01
-
-// To avoid sending multiple response to application
-static gboolean UssdResp = FALSE;
-
-enum telephony_ss_opcode {
- SS_OPCO_REG = 0x01, /* 0x01 : Registration */
- SS_OPCO_DEREG, /* 0x02 : De-registration(erase) */
- SS_OPCO_ACTIVATE, /* 0x03 : Activation */
- SS_OPCO_DEACTIVATE, /* 0x04 : De-activation */
- 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;
-};
-
-static gboolean _ss_request_message(TcorePending *pending, CoreObject *o, UserRequest *ur, void *on_resp, void *user_data);
-
-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 void on_confirmation_ss_message_send(TcorePending *p, gboolean result, 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_info(CoreObject *o, const void *data, void *user_data);
-static gboolean on_notification_ss_ussd(CoreObject *o, const void *data, void *user_data);
-
-
-static gboolean _ss_request_message(TcorePending *pending,
- CoreObject *o,
- UserRequest *ur,
- void *on_resp,
- void *user_data)
-{
- TcoreHal *hal = NULL;
- TReturn ret;
- dbg("Entry");
-
- if (on_resp) {
- tcore_pending_set_response_callback(pending, on_resp, user_data);
- }
- tcore_pending_set_send_callback(pending, on_confirmation_ss_message_send, NULL);
- if (ur) {
- tcore_pending_link_user_request(pending, ur);
- } else {
- err("User Request is NULL, is this internal request??");
- }
-
- hal = tcore_object_get_hal(o);
-
- // Send request to HAL
- ret = tcore_hal_send_request(hal, pending);
- if (TCORE_RETURN_SUCCESS != ret) {
- err("Request send failed");
- return FALSE;
- }
-
- dbg("Exit");
- return TRUE;
-}
-
-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;
- dbg("Entry");
-
- if (ur) {
- memset(&resp, 0x0, sizeof(struct tresp_ss_ussd));
- resp.type = type;
- resp.status = status;
- resp.err = SS_ERROR_NONE;
- dbg("ussd_str = %s resp.type - %d resp.status - %d", ussd_str, resp.type, resp.status);
-
- 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("Response string: %s", resp.str);
- } else {
- dbg("USSD string is not present");
- memset(resp.str, '\0', MAX_SS_USSD_LEN);
- }
- UssdResp = TRUE;
- // Send response to TAPI
- tcore_user_request_send_response(ur, TRESP_SS_SEND_USSD, sizeof(struct tresp_ss_ussd), &resp);
- } else {
- err("User request is NULL");
- }
-
- dbg("Exit");
- return;
-}
-
-static void _ss_ussd_notification(TcorePlugin *p, const char *ussd_str, enum telephony_ss_ussd_status status)
-{
- CoreObject *core_obj = 0;
- struct tnoti_ss_ussd noti;
-
- dbg("function enter");
- 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);
- }
- dbg("noti.str - %s", noti.str);
-
- core_obj = tcore_plugin_ref_core_object(p, CORE_OBJECT_TYPE_SS);
- tcore_server_send_notification(tcore_plugin_ref_server(p),
- core_obj,
- 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;
- TcorePlugin *plugin = 0;
- int m = -1, dcs = 0;
- char *ussdnoti = NULL, *str = NULL, *dcs_str = NULL;
- GSList *tokens = NULL;
- GSList *lines = NULL;
- char *ussd_string = NULL;
- unsigned int len;
-
- plugin = tcore_object_ref_plugin(o);
- ussd_session = tcore_ss_ussd_get_session(o);
-
- dbg("function enter");
- lines = (GSList *) data;
- if (1 != g_slist_length(lines)) {
- dbg("unsolicited msg but multiple line");
- return TRUE;
- }
- cmd = (char *) (lines->data);
- // parse ussd status
- tokens = tcore_at_tok_new(cmd);
-
- // parse <m>
- ussdnoti = g_slist_nth_data(tokens, 0);
- if (!ussdnoti) {
- dbg("+CUSD<m> is missing from %CUSD Notification");
- } else {
- m = atoi(ussdnoti);
- dbg("USSD status %d", m);
- // parse [ <str>, <dcs>]
- ussd_string = g_slist_nth_data(tokens, 1);
- if (ussd_string) {
- /* Strike off starting & ending quotes. 1 extra character for NULL termination */
- str = malloc(strlen(ussd_string) - 1);
- dbg("length of Ussd Stirng - %d", strlen(ussd_string));
- if (str) {
- memset(str, 0x00, strlen(ussd_string) - 1);
- } else {
- dbg("malloc failed");
- if (NULL != tokens) {
- tcore_at_tok_free(tokens);
- }
- return FALSE;
- }
- len = strlen(ussd_string) - 1;
- ++ussd_string;
- strncpy(str, ussd_string, len);
-
- dbg("USSD String - %s len = %d", str, strlen(str));
- }
- if ((dcs_str = g_slist_nth_data(tokens, 2))) {
- dcs = atoi(dcs_str);
- dbg("USSD dcs %d", dcs);
- }
- }
-
- 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;
- }
-
- switch (tcore_util_get_cbs_coding_scheme(dcs)) {
- case TCORE_DCS_TYPE_7_BIT:
- case TCORE_DCS_TYPE_UNSPECIFIED:
- // ussd_str = tcore_util_unpack_gsm7bit(str, strlen(str));
- // break;
-
- case TCORE_DCS_TYPE_UCS2:
- case TCORE_DCS_TYPE_8_BIT:
- if ((str != NULL) && (strlen(str) > 0)) {
- ussd_str = g_new0(char, strlen(str) + 1);
- if (ussd_str != NULL) {
- memcpy(ussd_str, str, strlen(str));
- ussd_str[strlen(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)");
- goto CATCH;
- }
-
- type = (enum telephony_ss_ussd_type) tcore_ss_ussd_get_session_type(ussd_session);
- dbg("ussd type - %d", type);
-
- _ss_ussd_response(ur, ussd_str, type, status);
- }
-
-CATCH:
- if (NULL != tokens) {
- tcore_at_tok_free(tokens);
- }
-
- if (NULL != str) {
- free(str);
- }
- return FALSE;
- }
-
- 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:
- {
- 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)");
- if (NULL != tokens) {
- tcore_at_tok_free(tokens);
- }
-
- if (NULL != str) {
- free(str);
- }
-
- if (ussd_str) {
- g_free(ussd_str);
- }
- return FALSE;
- }
- type = (enum telephony_ss_ussd_type) tcore_ss_ussd_get_session_type(ussd_session);
- dbg("ussd type - %d", type);
- _ss_ussd_response(ur, (const char *) ussd_str, type, status);
- if (ussd_str)
- g_free(ussd_str);
- } else {
- tcore_ss_ussd_create_session(o, TCORE_SS_USSD_TYPE_NETWORK_INITIATED, 0, 0);
- _ss_ussd_notification(plugin, (const char *) ussd_str, status);
-
- if (ussd_str)
- 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;
- }
-
- if (NULL != tokens) {
- tcore_at_tok_free(tokens);
- }
-
- if (NULL != str) {
- free(str);
- }
-
- dbg("Exit");
- return TRUE;
-}
-
-static gboolean on_notification_ss_info(CoreObject *o, const void *data, void *user_data)
-{
- TcorePlugin *plugin = 0;
- CoreObject *co = 0;
- char *cmd = 0, *number = 0, *pos;
- int code1 = -1, code2 = -1, index = 0, ton = 0;
- char *str_code1, *str_code2, *str_ton, *str_index;
- GSList *tokens = NULL;
- char *buf;
- gboolean cssu = FALSE, cssi = FALSE;
- GSList *lines = NULL;
- char *resp = NULL;
- dbg("function enter");
-
- plugin = tcore_object_ref_plugin(o);
- co = tcore_plugin_ref_core_object(plugin, CORE_OBJECT_TYPE_CALL);
- if (!co) {
- dbg("[ error ] plugin_ref_core_object : call");
- return FALSE;
- }
-
- lines = (GSList *) data;
- if (1 != g_slist_length(lines)) {
- dbg("unsolicited msg but multiple line");
- goto OUT;
- }
-
- cmd = (char *) (lines->data);
- pos = strchr(cmd, ':');
- if (!pos) {
- dbg("[ error ] not valid SS- notification ");
- return TRUE;
- }
- buf = calloc(pos - cmd + 2, 1);
- memcpy(buf, cmd, pos - cmd);
- dbg("buf is %s", buf);
-
- if (!strcmp(buf, "+CSSU")) {
- dbg("SS - +CSSU indication");
- cssu = TRUE;
- } else if (!strcmp(buf, "+CSSI")) {
- dbg("SS - +CSSI indication");
- cssi = TRUE;
- }
- free(buf);
-
- // handle %CSSU notification
- if (cssu) {
- tokens = tcore_at_tok_new(cmd);
- // parse <code2>
- str_code2 = g_slist_nth_data(tokens, 0);
- if (!str_code2) {
- dbg("Code2 is missing from %CSSU indiaction");
- } else {
- code2 = atoi(str_code2);
- // parse [ <index>, <number> <type>]
- if ((str_index = g_slist_nth_data(tokens, 1))) {
- index = atoi(str_index);
- }
-
- if ((resp = g_slist_nth_data(tokens, 2))) {
- // Strike off double quotes
- number = util_removeQuotes(resp);
- str_ton = g_slist_nth_data(tokens, 3);
-
- if (str_ton) {
- ton = atoi(str_ton);
- }
- }
- }
-
- dbg("CSSU - code2 = %d index = %d number = %s type = %d", code2, index, number, 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("CSSU - unsupported code2 : %d", code2);
- break;
- }
- }
- // handle %CSSI notification
-
- if (cssi) {
- tokens = tcore_at_tok_new(cmd);
- // parse <code1>
- str_code1 = g_slist_nth_data(tokens, 0);
- if (!str_code1) {
- dbg("Code1 is missing from %CSSI indiaction");
- } else {
- code1 = atoi(str_code1);
- // parse [ <index> ]
- if ((str_index = g_slist_nth_data(tokens, 1))) {
- index = atoi(str_index);
- }
- }
-
- dbg("CSSI - code1 - %d index - %d ", code1, index);
-
- switch (code1) {
- case 0: // Unconditional CF is active
- tcore_call_information_mo_cfu(co);
- break;
-
- case 1: // some of the conditional call forwarding are active
- tcore_call_information_mo_cfc(co);
- break;
-
- case 2: // outgoing call is forwarded
- tcore_call_information_mo_forwarded(co);
- break;
-
- case 3: // this call is waiting
- tcore_call_information_mo_waiting(co);
- break;
-
- case 5: // outgoing call is barred
- tcore_call_information_mo_barred_outgoing(co);
- break;
-
- case 6: // incoming call is barred
- tcore_call_information_mo_barred_incoming(co);
- break;
-
- case 7: // CLIR suppression rejected
- tcore_call_information_mo_clir_suppression_reject(co);
- break;
-
- case 8: // outgoing call is deflected
- tcore_call_information_mo_deflected(co);
- break;
-
- default:
- dbg("unsupported cmd : %d", code1);
- break;
- }
- }
-OUT:
- if (NULL != tokens) {
- tcore_at_tok_free(tokens);
- }
-
- g_free(number);
- return TRUE;
-}
-
-static void on_confirmation_ss_message_send(TcorePending *p, gboolean result, void *user_data)
-{
- dbg("");
-
- if (result == FALSE) {
- // Fail
- dbg("FAIL");
- } else {
- dbg("SEND OK");
- }
-}
-
-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 = {0, };
- UserRequest *ur_dup = 0;
- GSList *tokens = NULL;
- const char *line;
- int err;
- const TcoreATResponse *response;
-
- dbg("function enter");
- response = data;
- o = tcore_pending_ref_core_object(p);
- ur = tcore_pending_ref_user_request(p);
-
- info = (struct ss_confirm_info *)user_data;
- class = info->class;
-
- if (response->success > 0) {
- dbg("RESPONSE OK");
- resp.err = SS_ERROR_NONE;
- } else {
- dbg("RESPONSE NOT OK");
- line = (const char *)response->final_response;
- tokens = tcore_at_tok_new(line);
-
- if (g_slist_length(tokens) < 1) {
- dbg("err cause not specified or string corrupted");
- resp.err = SS_ERROR_SYSTEMFAILURE;
- } else {
- err = atoi(g_slist_nth_data(tokens, 0));
- /* TODO: CMEE error mapping is required. */
- resp.err = SS_ERROR_SYSTEMFAILURE;
- }
- tcore_at_tok_free(tokens);
- }
-
- dbg("on_response_ss_barring_set - rsp.err : %d, ur : %x flavor_type = %d", resp.err, ur, info->flavor_type);
- dbg("[ check ] class : 0x%x", info->class);
-
- if (response->success > 0) {
- 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 {
- 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)
-{
- const TcoreATResponse *response = data;
- struct ss_confirm_info *info = 0;
- UserRequest *ur;
- struct tresp_ss_general resp;
- int err;
- GSList *tokens = NULL;
- const char *line;
-
- dbg("function enter");
- ur = tcore_pending_ref_user_request(p);
- info = (struct ss_confirm_info *) user_data;
-
- if (response->success > 0) {
- dbg("RESPONSE OK");
- resp.err = SS_ERROR_NONE;
- } else {
- dbg("RESPONSE NOT OK");
-
- line = (const char *) response->final_response;
- tokens = tcore_at_tok_new(line);
-
- if (g_slist_length(tokens) < 1) {
- dbg("err cause not specified or string corrupted");
- resp.err = SS_ERROR_SYSTEMFAILURE;
- } else {
- err = atoi(g_slist_nth_data(tokens, 0));
- // TODO: CMEE error mapping is required.
- resp.err = SS_ERROR_SYSTEMFAILURE;
- }
- tcore_at_tok_free(tokens);
- }
-
- 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_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_forwarding resp = {0,};
- GSList *tokens = NULL;
- const char *line;
- int error;
- const TcoreATResponse *response;
-
- dbg("function enter");
-
- response = data;
- o = tcore_pending_ref_core_object(p);
- ur = tcore_pending_ref_user_request(p);
-
- info = (struct ss_confirm_info *) user_data;
-
- if (response->success > 0) {
- dbg("RESPONSE OK");
- resp.err = SS_ERROR_NONE;
- } else {
- dbg("RESPONSE NOT OK");
-
- /* Extract Error */
- line = (const char *) response->final_response;
- tokens = tcore_at_tok_new(line);
-
- if (g_slist_length(tokens) < 1) {
- dbg("Error cause not specified or string corrupted");
- resp.err = SS_ERROR_SYSTEMFAILURE;
- } else {
- error = atoi(g_slist_nth_data(tokens, 0));
- err("Error: [%d]", error);
- // / TODO: CMEE error mapping is required.
- resp.err = SS_ERROR_SYSTEMFAILURE;
- }
-
- tcore_at_tok_free(tokens);
- }
-
- 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 (response->success > 0) {
- 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_forwarding), &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 {
- 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 *core_obj = 0;
- UserRequest *ur = 0;
- UserRequest *ur_dup = 0;
- struct ss_confirm_info *info = 0;
- struct tresp_ss_waiting resp = {0,};
- GSList *tokens = NULL;
- const char *line;
- int err;
- const TcoreATResponse *response;
-
- dbg("function enter");
- response = data;
- core_obj = tcore_pending_ref_core_object(p);
- ur = tcore_pending_ref_user_request(p);
-
- info = (struct ss_confirm_info *)user_data;
-
- if (response->success > 0) {
- dbg("RESPONSE OK");
- resp.err = SS_ERROR_NONE;
- } else {
- dbg("RESPONSE NOT OK");
-
- /* Extract Error */
- line = (const char *) response->final_response;
- tokens = tcore_at_tok_new(line);
-
- if (g_slist_length(tokens) < 1) {
- dbg("Error cause not specified or string corrupted");
- resp.err = SS_ERROR_SYSTEMFAILURE;
- } else {
- err = atoi(g_slist_nth_data(tokens, 0));
-
- /* TODO: CMEE error mapping is required. */
- resp.err = SS_ERROR_SYSTEMFAILURE;
- }
-
- /* Free tokens */
- tcore_at_tok_free(tokens);
- }
-
- dbg("Call Waiting - Error: [%d], UR: [0x%x] class: [0x%2x]", resp.err, ur, info->class);
- if (resp.err == SS_ERROR_NONE) {
- ur_dup = tcore_user_request_ref(ur);
-
- dbg("Get Call Waiting status");
- _ss_waiting_get(core_obj, ur_dup, info->class, info->resp);
- } else {
- if (ur) {
- tcore_user_request_send_response(ur, info->resp, sizeof(struct tresp_ss_waiting), &resp);
- } else {
- err("User request is NULL");
- }
- }
- g_free(user_data);
-}
-
-
-static void on_confirmation_ss_ussd(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- CoreObject *core_obj = 0;
- struct ss_confirm_info *info = 0;
- struct tresp_ss_ussd resp;
- UserRequest *ur = NULL, *ussd_ur = NULL;
- GSList *tokens = NULL;
- const char *line;
- int err;
- UssdSession *ussd_s = NULL;
- enum tcore_ss_ussd_type type = TCORE_SS_USSD_TYPE_MAX;
- const TcoreATResponse *response;
-
- dbg("function enter");
- response = data;
- ur = tcore_pending_ref_user_request(p);
- info = (struct ss_confirm_info *) user_data;
-
- memset(resp.str, 0x00, MAX_SS_USSD_LEN);
-
- core_obj = tcore_pending_ref_core_object(p);
- ussd_s = tcore_ss_ussd_get_session(core_obj);
-
- 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;
- resp.status = SS_USSD_MAX; // hardcoded value.
-
- if (response->success > 0) {
- dbg("RESPONSE OK");
- resp.err = SS_ERROR_NONE;
- } else {
- dbg("RESPONSE NOT OK");
-
- line = (const char *) response->final_response;
- tokens = tcore_at_tok_new(line);
-
- if (g_slist_length(tokens) < 1) {
- dbg("err cause not specified or string corrupted");
- resp.err = SS_ERROR_SYSTEMFAILURE;
- } else {
- err = atoi(g_slist_nth_data(tokens, 0));
- // TODO: CMEE error mapping is required.
- resp.err = SS_ERROR_SYSTEMFAILURE;
- }
- tcore_at_tok_free(tokens);
- }
-
- dbg("on_confirmation_ss_ussd - rsp.err : %d, ur : %x", resp.err, ur);
-
- if (response->success > 0) {
- if (type == TCORE_SS_USSD_TYPE_USER_INITIATED) {
- dbg("ussd type %d", resp.type);
-
- if (ussd_s) {
- tcore_ss_ussd_get_session_data(ussd_s, (void **) &ussd_ur);
- if (ussd_ur)
- tcore_user_request_free(ussd_ur);
- }
- }
- }
-
- if (ussd_s)
- tcore_ss_ussd_destroy_session(ussd_s);
-
- if (ur) {
- if (UssdResp == FALSE) { // to avoid sending multiple response to application.
- tcore_user_request_send_response(ur, info->resp, sizeof(struct tresp_ss_ussd), &resp);
- }
- UssdResp = FALSE;
- } else
- dbg("[ error ] ur : (0)");
-
- g_free(user_data);
-}
-
-static void on_response_ss_barring_get(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- UserRequest *ur = 0;
- int status = 0, classx = 0, err = 0;
- GSList *respdata;
- struct ss_confirm_info *info = 0;
- struct tresp_ss_barring resp;
- int countRecords = 0, countValidRecords = 0;
- GSList *tokens = NULL;
- const char *line;
- char *classx_str;
- char *stat = NULL;
- const TcoreATResponse *response;
-
- dbg("function enter");
-
- response = data;
- ur = tcore_pending_ref_user_request(p);
- info = (struct ss_confirm_info *) user_data;
-
- if (response->lines) {
- respdata = (GSList *) response->lines;
- countRecords = g_slist_length(respdata);
- dbg("total records : %d", countRecords);
- } else {
- countRecords = 0;
- dbg("no active status - return to user");
- }
- resp.record_num = countRecords;
- resp.record = 0;
- if (resp.record_num > 0) {
- resp.record = g_new0(struct barring_info, resp.record_num);
- for (countValidRecords = 0; respdata != NULL; respdata = respdata->next) {
- line = (const char *) (respdata->data);
- tokens = tcore_at_tok_new(line);
-
- // parse <status>
- stat = g_slist_nth_data(tokens, 0);
- if (!stat) {
- dbg("Stat is missing");
- goto error;
- }
-
- status = atoi(stat);
- if (status == 1) {
- resp.record[countValidRecords].status = SS_STATUS_ACTIVATE;
- } else {
- resp.record[countValidRecords].status = SS_STATUS_DEACTIVATE;
- }
- dbg("call barring status - %d", status);
-
- // Parse <class>
- classx_str = g_slist_nth_data(tokens, 1);
-
- if (!classx_str) {
- 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;
- }
- } else {
- classx = atoi(classx_str);
- dbg("call barring classx - %d", classx);
- }
-
- 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++;
- tcore_at_tok_free(tokens);
- continue;
-
-error:
- dbg("invalid field found. coutinue");
- tcore_at_tok_free(tokens);
- continue;
- }
-
- dbg("valid count :%d", countValidRecords);
- resp.record_num = countValidRecords;
- resp.err = SS_ERROR_NONE;
- } else {
- dbg("no active status - return to user");
- }
-
- if (response->success > 0) {
- dbg("RESPONSE OK");
- resp.err = SS_ERROR_NONE;
- } else {
- dbg("RESPONSE NOT OK");
- resp.err = TCORE_RETURN_FAILURE;
- resp.record = 0;
- resp.record_num = 0;
-
- line = (const char *) response->final_response;
- tokens = tcore_at_tok_new(line);
-
- if (g_slist_length(tokens) < 1) {
- dbg("err cause not specified or string corrupted");
- resp.err = SS_ERROR_SYSTEMFAILURE;
- } else {
- err = atoi(g_slist_nth_data(tokens, 0));
- // TODO: CMEE error mapping is required.
- resp.err = SS_ERROR_SYSTEMFAILURE;
- }
- tcore_at_tok_free(tokens);
- }
-
- dbg("on_response_ss_barring_get- rsp.err : %d, ur : %x", resp.err, ur);
-
- if (ur)
- tcore_user_request_send_response(ur, info->resp, sizeof(struct tresp_ss_barring), &resp);
- else
- dbg("[ error ] ur is 0");
-
- if (resp.record) {
- g_free(resp.record);
- resp.record = NULL;
- }
-
- g_free(user_data);
-}
-
-static void on_response_ss_forwarding_get(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- UserRequest *ur = 0;
- int classx = 0, err = 0, time = 0;
- char *num;
- struct ss_confirm_info *info = 0;
- struct tresp_ss_forwarding resp;
- int countRecords = 0, countValidRecords = 0;
-
- GSList *respdata = NULL, *tokens = NULL;
- const char *line;
- char *classx_str, *status, *ton, *time_str;
- const TcoreATResponse *response;
-
- dbg("function enter");
- response = data;
-
- ur = tcore_pending_ref_user_request(p);
- info = (struct ss_confirm_info *) user_data;
- if (response->lines) {
- respdata = (GSList *) response->lines;
- countRecords = g_slist_length(respdata);
- dbg("total records : %d", countRecords);
- } else {
- countRecords = 0;
- dbg("no active status - return to user");
- }
- resp.record_num = countRecords;
- resp.record = 0;
- if (resp.record_num > 0) {
- resp.record = g_new0(struct forwarding_info, resp.record_num);
-
- for (countValidRecords = 0; respdata != NULL; respdata = respdata->next) {
- line = (const char *) (respdata->data);
- tokens = tcore_at_tok_new(line);
-
- // parse <status>
- status = g_slist_nth_data(tokens, 0);
- if (!status) {
- dbg("start line error. skip this line");
- goto error;
- } else {
- if (atoi(status) == 1) {
- resp.record[countValidRecords].status = SS_STATUS_ACTIVATE;
- } else {
- resp.record[countValidRecords].status = SS_STATUS_DEACTIVATE;
- }
- }
-
- // Parse <class>
- classx_str = g_slist_nth_data(tokens, 1);
- if (!classx_str) {
- dbg("class error. skip this line");
- goto error;
- } else {
- switch (atoi(classx_str)) {
- 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;
- }
- }
-
- // parse <numer> <type>
- num = g_slist_nth_data(tokens, 2);
- if (num) {
- dbg("number - %s", num);
- memcpy((resp.record[countValidRecords].number), num, strlen(num));
- resp.record[countValidRecords].number_present = TRUE;
-
- ton = g_slist_nth_data(tokens, 3);
- if (ton) {
- resp.record[countValidRecords].number_type = atoi(ton);
- dbg("number type - %d", resp.record[countValidRecords].number_type);
- }
- }
-
- // skip <subaddr> <satype>
- // parse <time>
- time_str = g_slist_nth_data(tokens, 6);
- if (time_str) {
- time = atoi(time_str);
- resp.record[countValidRecords].time = (enum telephony_ss_forwarding_no_reply_time) time;
- dbg("time - %d", time);
- }
-
- resp.record[countValidRecords].mode = (enum telephony_ss_forwarding_mode) (info->flavor_type);
- dbg("flavor_type - %d", (enum telephony_ss_forwarding_mode) (info->flavor_type));
-
- countValidRecords++;
- tcore_at_tok_free(tokens);
- continue;
-error:
- dbg("invalid field found. coutinue");
- tcore_at_tok_free(tokens);
- continue;
- }
- dbg("valid count :%d", countValidRecords);
- resp.record_num = countValidRecords;
- resp.err = SS_ERROR_NONE;
- } else {
- dbg("no active status - return to user");
- }
-
- if (response->success > 0) {
- dbg("RESPONSE OK");
- resp.err = SS_ERROR_NONE;
- } else {
- dbg("RESPONSE NOT OK");
- resp.record = 0;
- resp.record_num = 0;
- line = (const char *) response->final_response;
- tokens = tcore_at_tok_new(line);
-
- if (g_slist_length(tokens) < 1) {
- dbg("err cause not specified or string corrupted");
- resp.err = SS_ERROR_SYSTEMFAILURE;
- } else {
- err = atoi(g_slist_nth_data(tokens, 0));
- /* TODO: CMEE error mapping is required. */
- resp.err = SS_ERROR_SYSTEMFAILURE;
- }
- tcore_at_tok_free(tokens);
- }
-
- 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");
-
- if (resp.record) {
- g_free(resp.record);
- resp.record = NULL;
- }
- g_free(user_data);
-}
-
-static void on_response_ss_waiting_get(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- UserRequest *ur = 0;
- GSList *respdata, *tokens = NULL;
- int classx = 0, err = 0;
- struct ss_confirm_info *info = 0;
- struct tresp_ss_waiting resp;
- int countRecords = 0, countValidRecords = 0;
- const char *line;
- char *classx_str, *status;
- const TcoreATResponse *response;
-
- dbg("function enter");
- response = data;
- ur = tcore_pending_ref_user_request(p);
- info = (struct ss_confirm_info *) user_data;
-
- if (response->lines) {
- respdata = (GSList *) response->lines;
- countRecords = g_slist_length(respdata);
- dbg("total records : %d", countRecords);
- } else {
- countRecords = 0;
- dbg("no active status - return to user");
- }
- resp.record_num = countRecords;
- resp.record = 0;
-
- if (resp.record_num > 0) {
- resp.record = g_new0(struct waiting_info, resp.record_num);
-
- for (countValidRecords = 0; respdata != NULL; respdata = respdata->next) {
- line = (const char *) (respdata->data);
- tokens = tcore_at_tok_new(line);
-
- // parse <status>
- status = g_slist_nth_data(tokens, 0);
- if (!status) {
- dbg("Missing stat in responce ");
- goto error;
- } else {
- if (atoi(status) == 1) {
- resp.record[countValidRecords].status = SS_STATUS_ACTIVATE;
- } else {
- resp.record[countValidRecords].status = SS_STATUS_DEACTIVATE;
- }
- }
- dbg("status = %d", resp.record[countValidRecords].status);
-
- // Parse <class>
- classx_str = g_slist_nth_data(tokens, 1);
- if (!classx_str) {
- dbg("error - class is missing");
- goto error;
- } else {
- switch (atoi(classx_str)) {
- 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;
- }
- dbg("class info %d", resp.record[countValidRecords].class);
- }
-
- countValidRecords++;
- tcore_at_tok_free(tokens);
- continue;
-error:
- dbg("invalid field found. coutinue");
- tcore_at_tok_free(tokens);
- continue;
- }
-
- dbg("valid count :%d", countValidRecords);
- resp.record_num = countValidRecords;
- resp.err = SS_ERROR_NONE;
- } else {
- dbg("no active status - return to user");
- }
-
- if (response->success > 0) {
- dbg("RESPONSE OK");
- resp.err = SS_ERROR_NONE;
- } else {
- dbg("RESPONSE NOT OK");
- resp.record = 0;
- resp.record_num = 0;
- line = (const char *) response->final_response;
- tokens = tcore_at_tok_new(line);
-
- if (g_slist_length(tokens) < 1) {
- dbg("err cause not specified or string corrupted");
- resp.err = SS_ERROR_SYSTEMFAILURE;
- } else {
- err = atoi(g_slist_nth_data(tokens, 0));
- // TODO: CMEE error mapping is required.
- resp.err = SS_ERROR_SYSTEMFAILURE;
- }
- tcore_at_tok_free(tokens);
- }
-
- dbg("on_response_ss_waiting_get - rsp.err : %d, ur : %x", resp.err, ur);
- if (ur)
- tcore_user_request_send_response(ur, info->resp, sizeof(struct tresp_ss_waiting), &resp);
- else
- dbg("[ error ] ur is 0");
-
- if (resp.record) {
- g_free(resp.record);
- resp.record = NULL;
- }
- g_free(user_data);
-}
-
-
-static void on_response_ss_cli_get(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- UserRequest *ur = 0;
- struct tresp_ss_cli resp;
- enum telephony_ss_cli_type *p_type = NULL;
- char *line = NULL, *status;
- int err = FALSE;
- int cli_adj, stat;
- GSList *tokens = NULL;
- const TcoreATResponse *response;
-
- dbg("function enter");
- response = data;
- ur = tcore_pending_ref_user_request(p);
- p_type = (enum telephony_ss_cli_type *) (user_data);
-
- if (response->success > 0) {
- line = (char *) (((GSList *) response->lines)->data);
- tokens = tcore_at_tok_new(line);
-
- if (*p_type == SS_CLI_TYPE_CLIR) {
- // +CLIR: <n> <m>
- dbg("CLI type is CLIR");
- // parse <n>
- status = g_slist_nth_data(tokens, 0);
-
- if (!status) {
- dbg("Call line identification adjustment missing <n>");
- } else {
- cli_adj = atoi(status);
- dbg("CLIR response value of <n> - %d", cli_adj);
-
- if (cli_adj == 0) {
- // parse <m>
- status = g_slist_nth_data(tokens, 1);
- if (!status) {
- dbg("status is missing<m>");
- }
- stat = atoi(status);
- dbg("CLIR response value of <m> - %d", stat);
-
- if (stat == 1 || stat == 3) {
- resp.status = TRUE;
- } else {
- resp.status = FALSE;
- }
- } else if (cli_adj == 1) {
- resp.status = TRUE;
- } else {
- resp.status = FALSE;
- }
- dbg("resp.status - %d", resp.status);
- }
- tcore_at_tok_free(tokens);
- } else {
- // parse <n>
- status = g_slist_nth_data(tokens, 0);
- if (!status) {
- dbg("Stat is missing");
- } else {
- stat = atoi(status);
- if (stat == 1)
- resp.status = TRUE;
- else
- resp.status = FALSE;
-
- dbg("resp.status - %d", resp.status);
- }
- tcore_at_tok_free(tokens);
- }
- }
-
- if (response->success > 0) {
- dbg("RESPONSE OK");
- resp.err = SS_ERROR_NONE;
- } else {
- dbg("RESPONSE NOT OK");
-
- line = (char *) response->final_response;
- tokens = tcore_at_tok_new(line);
-
- if (g_slist_length(tokens) < 1) {
- dbg("err cause not specified or string corrupted");
- resp.err = SS_ERROR_SYSTEMFAILURE;
- } else {
- err = atoi(g_slist_nth_data(tokens, 0));
- // TODO: CMEE error mapping is required.
- resp.err = SS_ERROR_SYSTEMFAILURE;
- }
- tcore_at_tok_free(tokens);
- }
-
- resp.type = *p_type;
- dbg("check - resp.type = %d ", resp.type);
- if (ur)
- tcore_user_request_send_response(ur, TRESP_SS_CLI_GET_STATUS, sizeof(struct tresp_ss_cli), &resp);
- else
- dbg("[ error ] ur : (0)");
-
- 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;
- struct ss_confirm_info *user_data = 0;
- char *cmd_str = NULL;
- TcoreHal *hal;
- TcorePending *pending = NULL;
- TcoreATRequest *req;
- char passwd[MAX_SS_BARRING_PASSWORD_LEN + 1];
- int opco;
- int classx;
- char *facility = NULL;
- gboolean ret = FALSE;
-
- dbg("function enter");
- barring = (struct treq_ss_barring *) tcore_user_request_ref_data(ur, 0);
-
- switch (op) {
- case SS_OPCO_ACTIVATE:
- opco = 1;
- break;
-
- case SS_OPCO_DEACTIVATE:
- opco = 0;
- break;
-
- default:
- dbg("unsupported opco : %d", op);
- return TCORE_RETURN_FAILURE;
- }
- dbg("opco - %d", opco);
-
- 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";
- default:
- dbg("unspported mode %d", barring->mode);
- return TCORE_RETURN_FAILURE;
- }
-
- dbg("facility - %s", facility);
-
- 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;
- }
-
- dbg("classx - %d", classx);
-
- // 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';
- dbg("passwd - %s", passwd);
-
- hal = tcore_object_get_hal(o);
- pending = tcore_pending_new(o, 0);
-
- cmd_str = g_strdup_printf("AT+CLCK=\"%s\",%d,\"%s\",%d", facility, opco, passwd, classx);
- dbg("request command : %s", cmd_str);
-
- req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
- dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
-
- tcore_pending_set_request_data(pending, 0, req);
-
- user_data = g_new0(struct ss_confirm_info, 1);
- if (op == SS_OPCO_ACTIVATE) {
- user_data->resp = TRESP_SS_BARRING_ACTIVATE;
- } else if (op == SS_OPCO_DEACTIVATE) {
- user_data->resp = TRESP_SS_BARRING_DEACTIVATE;
- } else {
- dbg("[ error ] wrong ss opco (0x%x)", op);
- if (user_data != NULL) {
- g_free(user_data);
- }
- g_free(cmd_str);
- return TCORE_RETURN_FAILURE;
- }
- user_data->flavor_type = (int) (barring->mode);
- user_data->class = barring->class;
-
- ret = _ss_request_message(pending, o, ur, on_response_ss_barring_set, user_data);
- g_free(cmd_str);
-
- if (!ret) {
- dbg("AT request sent failed ");
- if (user_data != NULL) {
- g_free(user_data);
- }
- 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)
-{
- struct ss_confirm_info *user_data = 0;
- gboolean ret = FALSE;
- char *cmd_str = NULL;
- int opco, classx;
- char *facility = NULL;
- TcoreHal *hal;
- TcorePending *pending = NULL;
- TcoreATRequest *req;
-
- dbg("function enter");
-
- // 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:
- case SS_BARR_MODE_AOB:
- case SS_BARR_MODE_AIB:
- case SS_BARR_MODE_BIC_NOT_SIM:
- default:
- dbg("unsupported mode %d", mode);
- return TCORE_RETURN_FAILURE;
- }
-
- dbg("facility - %s", facility);
-
- 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;
- }
- dbg("class - %d", classx);
-
- if (classx == 7)
- cmd_str = g_strdup_printf("AT+CLCK=\"%s\",%d", facility, opco);
- else
- cmd_str = g_strdup_printf("AT+CLCK=\"%s\",%d,,%d", facility, opco, classx);
-
- dbg("request command : %s", cmd_str);
-
- hal = tcore_object_get_hal(o);
- pending = tcore_pending_new(o, 0);
- req = tcore_at_request_new(cmd_str, "+CLCK", TCORE_AT_MULTILINE);
- dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
-
- tcore_pending_set_request_data(pending, 0, req);
-
- 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(pending, o, ur, on_response_ss_barring_get, user_data);
- g_free(cmd_str);
-
- if (!ret) {
- dbg("AT request sent failed ");
- if (user_data != NULL) {
- g_free(user_data);
- }
- return TCORE_RETURN_FAILURE;
- }
-
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn s_ss_barring_activate(CoreObject *o, UserRequest *ur)
-{
- if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
- dbg("cp not ready/n");
- return TCORE_RETURN_ENOSYS;
- }
- return _ss_barring_set(o, ur, SS_OPCO_ACTIVATE);
-}
-
-static TReturn s_ss_barring_deactivate(CoreObject *o, UserRequest *ur)
-{
- if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
- dbg("cp not ready/n");
- return TCORE_RETURN_ENOSYS;
- }
- return _ss_barring_set(o, ur, SS_OPCO_DEACTIVATE);
-}
-
-static TReturn s_ss_barring_change_password(CoreObject *o, UserRequest *ur)
-{
- TcoreHal *hal;
- TcorePending *pending = NULL;
- TcoreATRequest *req;
- struct treq_ss_barring_change_password *barring = 0;
- struct ss_confirm_info *user_data = 0;
- char *cmd_str = NULL;
- gboolean ret = FALSE;
- char old_password[MAX_SS_BARRING_PASSWORD_LEN + 1];
- char new_password[MAX_SS_BARRING_PASSWORD_LEN + 1];
-
- dbg("function enter");
-
- if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
- dbg("cp not ready/n");
- return TCORE_RETURN_ENOSYS;
- }
-
- barring = (struct treq_ss_barring_change_password *) tcore_user_request_ref_data(ur, 0);
-
- if (barring->password_old == NULL || barring->password_new == NULL) {
- dbg("[error]password is null");
- return TCORE_RETURN_FAILURE;
- }
- memcpy(old_password, barring->password_old, MAX_SS_BARRING_PASSWORD_LEN);
- old_password[MAX_SS_BARRING_PASSWORD_LEN] = '\0';
- memcpy(new_password, barring->password_new, MAX_SS_BARRING_PASSWORD_LEN);
- new_password[MAX_SS_BARRING_PASSWORD_LEN] = '\0';
-
- dbg("old passwd - %s new passwd- %s", old_password, new_password);
- cmd_str = g_strdup_printf("AT+CPWD=\"%s\",\"%s\",\"%s\"", "AB", old_password, new_password);
- dbg("request command : %s", cmd_str);
-
- hal = tcore_object_get_hal(o);
- pending = tcore_pending_new(o, 0);
- req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
- dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
-
- tcore_pending_set_request_data(pending, 0, req);
-
- user_data = g_new0(struct ss_confirm_info, 1);
- user_data->resp = TRESP_SS_BARRING_CHANGE_PASSWORD;
-
- ret = _ss_request_message(pending, o, ur, on_response_ss_barring_change_pwd, user_data);
- g_free(cmd_str);
- if (!ret) {
- dbg("AT request sent failed ");
- if (user_data != NULL) {
- g_free(user_data);
- }
- 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;
-
- if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
- dbg("cp not ready/n");
- return TCORE_RETURN_ENOSYS;
- }
- 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)
-{
- struct treq_ss_forwarding *forwarding = 0;
- struct ss_confirm_info *user_data = 0;
- gboolean ret = FALSE;
- int 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;
- TcoreHal *hal;
- TcorePending *pending = NULL;
- TcoreATRequest *req;
-
- dbg("_ss_forwarding_set with opco %d ", op);
-
- forwarding = (struct treq_ss_forwarding *) tcore_user_request_ref_data(ur, 0);
- 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");
- return TCORE_RETURN_FAILURE;
- break;
- }
-
- dbg("reason = %d", reason);
- switch (op) {
- case SS_OPCO_DEACTIVATE:
- mode = 0;
- break;
-
- case SS_OPCO_ACTIVATE:
- mode = 1;
- break;
-
- case SS_OPCO_REG:
- mode = 3;
- break;
-
- case SS_OPCO_DEREG:
- mode = 4;
- break;
-
- default:
- dbg("unsupported opco : %d", op);
- return TCORE_RETURN_FAILURE;
- }
-
- dbg("mode = %d", mode);
-
- // 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;
- }
- dbg("classx = %d", classx);
-
- // number
- len = strlen(forwarding->number);
- if (len > 0) {
- valid_num = TRUE;
- if (forwarding->number[0] == '+')
- num_type = ((NUM_TYPE_INTERNATIONAL << 4) | NUM_PLAN_ISDN);
- else
- num_type = 0;
- }
- dbg("number = %s", forwarding->number);
-
- user_data = g_new0(struct ss_confirm_info, 1);
-
- switch (op) {
- case SS_OPCO_REG:
- user_data->resp = TRESP_SS_FORWARDING_REGISTER;
- break;
-
- case SS_OPCO_DEREG:
- user_data->resp = TRESP_SS_FORWARDING_DEREGISTER;
- break;
-
- case SS_OPCO_ACTIVATE:
- user_data->resp = TRESP_SS_FORWARDING_ACTIVATE;
- break;
-
- case SS_OPCO_DEACTIVATE:
- user_data->resp = TRESP_SS_FORWARDING_DEACTIVATE;
- break;
-
- default:
- dbg("[ error ] unknown op (0x%x)", op);
- break;
- }
-
- if (forwarding->number[0] == '+')
- num_type = 145;
- else
- num_type = 129;
-
- if (op == 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", tmp_str, time);
- } else {
- cmd_str = g_strdup_printf("%s", tmp_str);
- }
-
- dbg("request command : %s", cmd_str);
- hal = tcore_object_get_hal(o);
- pending = tcore_pending_new(o, 0);
- req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
- dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
-
- tcore_pending_set_request_data(pending, 0, req);
-
- user_data->flavor_type = forwarding->mode;
- user_data->class = forwarding->class;
-
- ret = _ss_request_message(pending, o, ur, on_response_ss_forwarding_set, user_data);
-
- g_free(tmp_str);
- g_free(cmd_str);
-
- if (!ret) {
- dbg("AT request sent failed ");
- if (user_data != NULL) {
- g_free(user_data);
- }
- 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)
-{
- struct ss_confirm_info *user_data = 0;
- gboolean ret = FALSE;
- char *cmd_str = NULL;
- int reason = 0, mode = 0, classx = 0;
- TcoreHal *hal;
- TcorePending *pending = NULL;
- TcoreATRequest *req;
-
- dbg("function enter");
-
- 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;
- }
- dbg("reason = %d", reason);
-
- 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;
- }
-
- dbg("classx = %d", classx);
-
- // 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", reason, mode);
- else
- cmd_str = g_strdup_printf("AT+CCFC=%d,%d,,,%d", reason, mode, classx);
-
- dbg("request command : %s", cmd_str);
-
- hal = tcore_object_get_hal(o);
- pending = tcore_pending_new(o, 0);
- req = tcore_at_request_new(cmd_str, "+CCFC", TCORE_AT_MULTILINE);
- dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
-
- tcore_pending_set_request_data(pending, 0, req);
-
- ret = _ss_request_message(pending, o, ur, on_response_ss_forwarding_get, user_data);
- g_free(cmd_str);
-
- if (!ret) {
- dbg("AT request sent failed ");
- if (user_data != NULL) {
- g_free(user_data);
- }
- return TCORE_RETURN_FAILURE;
- }
-
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn s_ss_forwarding_activate(CoreObject *o, UserRequest *ur)
-{
- if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
- dbg("cp not ready/n");
- return TCORE_RETURN_ENOSYS;
- }
- return _ss_forwarding_set(o, ur, SS_OPCO_ACTIVATE);
-}
-
-static TReturn s_ss_forwarding_deactivate(CoreObject *o, UserRequest *ur)
-{
- if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
- dbg("cp not ready/n");
- return TCORE_RETURN_ENOSYS;
- }
- return _ss_forwarding_set(o, ur, SS_OPCO_DEACTIVATE);
-}
-
-static TReturn s_ss_forwarding_register(CoreObject *o, UserRequest *ur)
-{
- if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
- dbg("cp not ready/n");
- return TCORE_RETURN_ENOSYS;
- }
- return _ss_forwarding_set(o, ur, SS_OPCO_REG);
-}
-
-static TReturn s_ss_forwarding_deregister(CoreObject *o, UserRequest *ur)
-{
- if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
- dbg("cp not ready/n");
- return TCORE_RETURN_ENOSYS;
- }
- return _ss_forwarding_set(o, ur, SS_OPCO_DEREG);
-}
-
-static TReturn s_ss_forwarding_get_status(CoreObject *o, UserRequest *ur)
-{
- struct treq_ss_forwarding *forwarding = 0;
-
- if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
- dbg("cp not ready/n");
- return TCORE_RETURN_ENOSYS;
- }
-
- 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)
-{
- struct treq_ss_waiting *waiting = 0;
- struct ss_confirm_info *user_data = 0;
- gboolean ret = FALSE;
- int mode = 0, classx = 0;
- char *cmd_str;
- TcoreHal *hal;
- TcorePending *pending = NULL;
- TcoreATRequest *req;
-
- dbg("function enter ");
- waiting = (struct treq_ss_waiting *) tcore_user_request_ref_data(ur, 0);
- user_data = g_new0(struct ss_confirm_info, 1);
-
- if (opco == SS_OPCO_ACTIVATE) {
- user_data->resp = TRESP_SS_WAITING_ACTIVATE;
- mode = 1; // enable
- } else if (opco == SS_OPCO_DEACTIVATE) {
- user_data->resp = TRESP_SS_WAITING_DEACTIVATE;
- mode = 0; // disable
- } 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 = 1;
- dbg("unsupported class %d. set to default : 1", waiting->class);
- break;
- }
- dbg("mode = %d classxx- %d", mode, classx);
-
- user_data->class = waiting->class;
- user_data->flavor_type = (int) opco;
-
- cmd_str = g_strdup_printf("AT+CCWA=1,%d,%d", mode, classx); // always enable +CCWA: unsolicited cmd
- dbg("request command : %s", cmd_str);
-
- hal = tcore_object_get_hal(o);
- pending = tcore_pending_new(o, 0);
- req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
- dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
-
- tcore_pending_set_request_data(pending, 0, req);
-
- ret = _ss_request_message(pending, o, ur, on_response_ss_waiting_set, user_data);
- g_free(cmd_str);
- if (!ret) {
- dbg("AT request sent failed ");
- if (user_data != NULL) {
- g_free(user_data);
- }
- 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)
-{
- struct ss_confirm_info *user_data = 0;
- gboolean ret = FALSE;
- int classx; // mode,
- char *cmd_str;
- TcoreHal *hal;
- TcorePending *pending = NULL;
- TcoreATRequest *req;
-
- dbg("function enter");
- 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("classx - %d", classx);
-
- 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", classx); // always enable +CCWA: unsolicited cmd , mode is fixed to 2(query status)
- dbg("request cmd : %s", cmd_str);
-
- hal = tcore_object_get_hal(o);
- pending = tcore_pending_new(o, 0);
- req = tcore_at_request_new(cmd_str, "+CCWA", TCORE_AT_MULTILINE);
- dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
-
- tcore_pending_set_request_data(pending, 0, req);
-
- ret = _ss_request_message(pending, o, ur, on_response_ss_waiting_get, user_data);
- g_free(cmd_str);
- if (!ret) {
- dbg("AT request sent failed ");
- if (user_data != NULL) {
- g_free(user_data);
- }
- return TCORE_RETURN_FAILURE;
- }
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn s_ss_waiting_activate(CoreObject *o, UserRequest *ur)
-{
- if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
- dbg("cp not ready/n");
- return TCORE_RETURN_ENOSYS;
- }
- return _ss_waiting_set(o, ur, SS_OPCO_ACTIVATE);
-}
-
-static TReturn s_ss_waiting_deactivate(CoreObject *o, UserRequest *ur)
-{
- if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
- dbg("cp not ready/n");
- return TCORE_RETURN_ENOSYS;
- }
- return _ss_waiting_set(o, ur, SS_OPCO_DEACTIVATE);
-}
-
-static TReturn s_ss_waiting_get_status(CoreObject *o, UserRequest *ur)
-{
- struct treq_ss_waiting *waiting = 0;
-
- if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
- dbg("cp not ready/n");
- return TCORE_RETURN_ENOSYS;
- }
- 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)
-{
- if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
- dbg("cp not ready/n");
- return TCORE_RETURN_ENOSYS;
- }
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn s_ss_cli_deactivate(CoreObject *o, UserRequest *ur)
-{
- if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
- dbg("cp not ready/n");
- return TCORE_RETURN_ENOSYS;
- }
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn s_ss_cli_get_status(CoreObject *o, UserRequest *ur)
-{
- struct treq_ss_cli *cli = 0;
- gboolean ret = FALSE;
- char *cmd_prefix = NULL, *rsp_prefix = NULL, *cmd_str = NULL;
- enum telephony_ss_cli_type *user_data = 0;
- TcoreHal *hal;
- TcorePending *pending = NULL;
- TcoreATRequest *req;
-
- if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
- dbg("cp not ready/n");
- return TCORE_RETURN_ENOSYS;
- }
-
- 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_COLR:
- cmd_prefix = "+COLR";
- rsp_prefix = "+COLR";
- break;
-
- case SS_CLI_TYPE_CNAP:
- cmd_prefix = "+CNAP";
- rsp_prefix = "+CNAP";
- break;
-
- case SS_CLI_TYPE_CDIP:
- default:
- dbg("unsupported cli_type : %d", cli->type);
- return TCORE_RETURN_FAILURE;
- break;
- }
- dbg("cmd_prefix : %s", cmd_prefix);
-
- cmd_str = g_strdup_printf("AT%s?", cmd_prefix);
- dbg("request cmd : %s", cmd_str);
-
- user_data = g_new0(enum telephony_ss_cli_type, 1);
- *user_data = cli->type;
-
- hal = tcore_object_get_hal(o);
- pending = tcore_pending_new(o, 0);
-
- req = tcore_at_request_new(cmd_str, rsp_prefix, TCORE_AT_SINGLELINE);
- dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
- tcore_pending_set_request_data(pending, 0, req);
-
- ret = _ss_request_message(pending, o, ur, on_response_ss_cli_get, user_data);
- g_free(cmd_str);
- if (!ret) {
- dbg("AT request sent failed ");
- if (user_data != NULL) {
- g_free(user_data);
- }
- return TCORE_RETURN_FAILURE;
- }
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn s_ss_send_ussd(CoreObject *o, UserRequest *ur)
-{
- UssdSession *ussd_s = 0;
- struct treq_ss_ussd *ussd = 0;
- struct ss_confirm_info *user_data = 0;
- gboolean ret = FALSE;
- char *cmd_str;
- TcoreHal *hal;
- TcorePending *pending = NULL;
- TcoreATRequest *req;
-
- dbg("function enter");
-
- if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
- dbg("cp not ready/n");
- return TCORE_RETURN_ENOSYS;
- }
-
- ussd = (struct treq_ss_ussd *) tcore_user_request_ref_data(ur, 0);
- cmd_str = g_strdup_printf("AT+CUSD=1,\"%s\",%d", ussd->str, 0x0f); // 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) {
- dbg("USSD session does not exist");
- 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);
- }
-
- hal = tcore_object_get_hal(o);
- pending = tcore_pending_new(o, 0);
- req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
- dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
-
- tcore_pending_set_request_data(pending, 0, req);
-
- ret = _ss_request_message(pending, o, ur, on_confirmation_ss_ussd, user_data);
- g_free(cmd_str);
-
- if (!ret) {
- dbg("AT request sent failed ");
- if (user_data != NULL) {
- g_free(user_data);
- }
- return TCORE_RETURN_FAILURE;
- }
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn s_ss_set_aoc(CoreObject *o, UserRequest *ur)
-{
- if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
- dbg("cp not ready/n");
- return TCORE_RETURN_ENOSYS;
- }
-
- dbg("[ error ] unsupported function");
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn s_ss_get_aoc(CoreObject *o, UserRequest *ur)
-{
- if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
- dbg("cp not ready/n");
- return TCORE_RETURN_ENOSYS;
- }
-
- 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_send(CoreObject *o, UserRequest *ur, const char *cmd, ConfirmCallback cb, void *user_data)
-{
- TcorePending *pending = NULL;
- TcoreATRequest *req;
- gboolean ret = FALSE;
-
- pending = tcore_pending_new(o, 0);
- req = tcore_at_request_new(cmd, NULL, TCORE_AT_NO_RESULT);
- dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
- tcore_pending_set_request_data(pending, 0, req);
-
- ret = _ss_request_message(pending, o, ur, (TcorePendingResponseCallback) cb, user_data);
- if (!ret) {
- dbg("AT request sent failed ");
- return TCORE_RETURN_FAILURE;
- }
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn s_ss_manage_call_0_send(CoreObject *o, UserRequest *ur, ConfirmCallback cb, void *user_data)
-{
- char *cmd_str = NULL;
- gboolean ret = FALSE;
-
- dbg("function enter");
- cmd_str = g_strdup_printf("%s", "AT+CHLD=0");
- dbg("cmd : %s, prefix(if any) : %s, cmd_len : %d", cmd_str, "N/A", strlen(cmd_str));
-
- ret = s_ss_manage_call_send(o, ur, cmd_str, cb, user_data);
- g_free(cmd_str);
- return ret;
-}
-
-static TReturn s_ss_manage_call_1_send(CoreObject *o, UserRequest *ur, ConfirmCallback cb, void *user_data)
-{
- char *cmd_str = NULL;
- gboolean ret = FALSE;
-
- dbg("function enter");
- cmd_str = g_strdup_printf("%s", "AT+CHLD=1");
- dbg("cmd : %s, prefix(if any) : %s, cmd_len : %d", cmd_str, "N/A", strlen(cmd_str));
-
- ret = s_ss_manage_call_send(o, ur, cmd_str, cb, user_data);
- g_free(cmd_str);
- return ret;
-}
-
-static TReturn s_ss_manage_call_1x_send(CoreObject *o, UserRequest *ur, const int id, ConfirmCallback cb, void *user_data)
-{
- char *cmd_str = NULL;
- gboolean ret = FALSE;
-
- dbg("function enter");
- cmd_str = g_strdup_printf("%s%d", "AT+CHLD=1", id);
- dbg("cmd : %s, prefix(if any) : %s, cmd_len : %d", cmd_str, "N/A", strlen(cmd_str));
-
- ret = s_ss_manage_call_send(o, ur, cmd_str, cb, user_data);
- g_free(cmd_str);
- return ret;
-}
-
-static TReturn s_ss_manage_call_2_send(CoreObject *o, UserRequest *ur, ConfirmCallback cb, void *user_data)
-{
- char *cmd_str = NULL;
- gboolean ret = FALSE;
-
- dbg("function enter");
- cmd_str = g_strdup_printf("%s", "AT+CHLD=2");
- dbg("cmd : %s, prefix(if any) : %s, cmd_len : %d", cmd_str, "N/A", strlen(cmd_str));
-
- ret = s_ss_manage_call_send(o, ur, cmd_str, cb, user_data);
- g_free(cmd_str);
- return ret;
-}
-
-static TReturn s_ss_manage_call_2x_send(CoreObject *o, UserRequest *ur, const int id, ConfirmCallback cb, void *user_data)
-{
- char *cmd_str = NULL;
- gboolean ret = FALSE;
-
- dbg("function enter");
- cmd_str = g_strdup_printf("%s%d", "AT+CHLD=2", id);
- dbg("cmd : %s, prefix(if any) : %s, cmd_len : %d", cmd_str, "N/A", strlen(cmd_str));
-
- ret = s_ss_manage_call_send(o, ur, cmd_str, cb, user_data);
- g_free(cmd_str);
- return ret;
-}
-
-static TReturn s_ss_manage_call_3_send(CoreObject *o, UserRequest *ur, ConfirmCallback cb, void *user_data)
-{
- char *cmd_str = NULL;
- gboolean ret = FALSE;
-
- dbg("function enter");
- cmd_str = g_strdup_printf("%s", "AT+CHLD=3");
-
- ret = s_ss_manage_call_send(o, ur, cmd_str, cb, user_data);
- g_free(cmd_str);
- return ret;
-}
-
-
-static TReturn s_ss_manage_call_4_send(CoreObject *o, UserRequest *ur, ConfirmCallback cb, void *user_data)
-{
- char *cmd_str = NULL;
- gboolean ret = FALSE;
-
- dbg("function enter");
- cmd_str = g_strdup_printf("%s", "AT+CHLD=4");
-
- ret = s_ss_manage_call_send(o, ur, cmd_str, cb, user_data);
- g_free(cmd_str);
- return ret;
-}
-
-static TReturn s_ss_manage_call_4dn_send(CoreObject *o, UserRequest *ur, const char *number, ConfirmCallback cb, void *user_data)
-{
- char *cmd_str = NULL;
- gboolean ret = FALSE;
-
- dbg("function enter");
- cmd_str = g_strdup_printf("%s%s", "AT+CHLD=4", number);
-
- ret = s_ss_manage_call_send(o, ur, cmd_str, cb, user_data);
- g_free(cmd_str);
-
- return ret;
-}
-
-gboolean s_ss_init(TcorePlugin *cp, CoreObject *co_ss)
-{
- CoreObject *co_call = NULL;
-
- tcore_ss_override_ops(co_ss, &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_override_callback(co_ss, "+CSSU", on_notification_ss_info, NULL);
- tcore_object_override_callback(co_ss, "+CSSI", on_notification_ss_info, NULL);
- tcore_object_override_callback(co_ss, "+CUSD", on_notification_ss_ussd, NULL);
-
- return TRUE;
-}
-
-void s_ss_exit(TcorePlugin *cp, CoreObject *co_ss)
-{
- dbg("Exit");
-}