src/queue.c
src/user_request.c
src/util.c
- src/core_object.c
- src/co_modem.c
- src/co_sim.c
- src/co_network.c
- src/co_call.c
- src/co_sms.c
- src/co_ss.c
- src/co_phonebook.c
- src/co_ps.c
- src/co_context.c
- src/co_sat.c
- src/co_sap.c
- src/co_gps.c
- src/co_custom.c
+ src/core_object/core_object.c
+ src/core_object/co_modem.c
+ src/core_object/co_sim.c
+ src/core_object/co_network.c
+ src/core_object/co_call.c
+ src/core_object/co_sms.c
+ src/core_object/co_ss.c
+ src/core_object/co_phonebook.c
+ src/core_object/co_ps.c
+ src/core_object/co_context.c
+ src/core_object/co_sat.c
+ src/core_object/co_sap.c
+ src/core_object/co_gps.c
+ src/core_object/co_custom.c
src/mux.c
)
};
enum tcore_call_silent_redial_reason{
- TCORE_CALL_SILENT_REDIAL_REASON_NULL,
- TCORE_CALL_SILENT_REDIAL_REASONL_MULTIRAT_EMERGENCY,
+ TCORE_CALL_SILENT_REDIAL_REASON_NONE,
+ TCORE_CALL_SILENT_REDIAL_REASON_MULTIRAT_EMERGENCY,
+ TCORE_CALL_SILENT_REDIAL_REASON_CS_FALLBACK //VoLTE call Fail with some reason which is pre-defined by network operator. Need to silent-redial to CS bearer
};
typedef struct call_object CallObject;
CallObject *tcore_call_object_find_by_id(CoreObject *o, int id);
CallObject *tcore_call_object_find_by_handle(CoreObject *o, int handle);
CallObject *tcore_call_object_find_by_number(CoreObject *o, char *num);
+int tcore_call_get_id_by_handle(CoreObject *o, int handle);
+int tcore_call_get_handle_by_id(CoreObject *o, int call_id);
GSList *tcore_call_object_find_by_status(CoreObject *o, enum tcore_call_status cs);
gboolean tcore_call_object_set_id(CallObject *co , int call_id);
void tcore_call_control_set_operations(CoreObject *o, struct tcore_call_control_operations *ops);
-
void tcore_call_information_mo_col(CoreObject *o, char *number);
void tcore_call_information_mo_waiting(CoreObject *o);
void tcore_call_information_mo_cug(CoreObject *o, int cug_index);
pcscf_addr *tcore_context_get_pcscf_ipv6_addr(CoreObject *o);
TReturn tcore_context_set_attach_apn(CoreObject *o, gboolean flag);
gboolean tcore_context_get_attach_apn(CoreObject *o);
+TReturn tcore_context_set_roaming_apn(CoreObject *o, gboolean flag);
+gboolean tcore_context_get_roaming_apn(CoreObject *o);
__END_DECLS
TReturn (*get_roaming_preference)(CoreObject *o, UserRequest *ur); /* 3GPP2 spcefic */
TReturn (*get_subscription_info)(CoreObject *o, UserRequest *ur); /* 3GPP2 spcefic */
TReturn (*search_ecc_rat)(CoreObject *o, UserRequest *ur);
+ TReturn (*ims_deregister)(CoreObject *o, UserRequest *ur);
};
TReturn (*get_atr)(CoreObject *o, UserRequest *ur);
TReturn (*req_authentication)(CoreObject *o, UserRequest *ur);
TReturn (*set_powerstate)(CoreObject *o, UserRequest *ur);
+ TReturn (*set_provisioning)(CoreObject *o, UserRequest *ur);
};
enum tcore_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_CYCLIC = 0x06, /**< Cyclic - record type*/
SIM_FTYPE_INVALID_TYPE = 0xFF /**< Invalid type */
};
#define nDCSOffset 26
#define nVPOffset 27
-struct property_sms_info {
- int g_trans_id;
- int SMSPRecordLen;
-};
-
struct tcore_sms_operations {
TReturn (*send_umts_msg)(CoreObject *o, UserRequest *ur);
TReturn (*read_msg)(CoreObject *o, UserRequest *ur);
__BEGIN_DECLS
-struct tcore_communitor_operations {
+struct tcore_communicator_operations {
TReturn (*send_response)(Communicator *comm, UserRequest *ur,
enum tcore_response_command command,
unsigned int data_len, const void *data);
};
Communicator *tcore_communicator_new(TcorePlugin *plugin,
- const char *name, struct tcore_communitor_operations *ops);
+ const char *name, struct tcore_communicator_operations *ops);
void tcore_communicator_free();
TcorePlugin *tcore_communicator_ref_plugin(Communicator *comm);
TReturn tcore_server_send_notification(Server *s,
CoreObject *source, enum tcore_notification_command command,
unsigned int data_len, void *data);
-
+TReturn tcore_server_broadcast_notification(Server *s, CoreObject *source,
+ enum tcore_notification_command command, unsigned int data_len, void *data);
TReturn tcore_server_add_request_hook(Server *s,
enum tcore_request_command command,
TcoreServerRequestHook func, void *user_data);
STORAGE_KEY_SETAPPL_STATE_DATA_ROAMING_BOOL,
STORAGE_KEY_SETAPPL_STATE_AUTOMATIC_TIME_UPDATE_BOOL,
STORAGE_KEY_SETAPPL_NETWORK_RESTRICT_MODE,
- STORAGE_KEY_SETAPPL_MOBILE_DATA_POPUP_DONE_BOOL,
STORAGE_KEY_MSG_SERVER_READY_BOOL,
STORAGE_KEY_FLIGHT_MODE_BOOL,
STORAGE_KEY_TESTMODE_FAST_DORMANCY_BOOL,
gboolean (*read_query_database)(Storage *strg, void *handle,
const char *query, GHashTable *in_param,
GHashTable *out_param, int out_param_cnt);
+ gboolean (*read_query_database_in_order)(Storage *strg, void *handle,
+ const char *query, GHashTable *in_param,
+ GSList **out_param, int out_param_cnt);
gboolean (*insert_query_database)(Storage *strg, void *handle,
const char *query, GHashTable *in_param);
gboolean (*remove_query_database)(Storage *strg, void *handle,
gboolean tcore_storage_read_query_database(Storage *strg, void *handle,
const char *query, GHashTable *in_param,
GHashTable *out_param, int out_param_cnt);
+gboolean tcore_storage_read_query_database_in_order(Storage *strg, void *handle,
+ const char *query, GHashTable *in_param,
+ GSList **out_param, int out_param_cnt);
gboolean tcore_storage_insert_query_database(Storage *strg, void *handle,
const char *query, GHashTable *in_param);
gboolean tcore_storage_remove_query_database(Storage *strg, void *handle,
struct telephony_call_cna_info cna;
gboolean forward;
unsigned int active_line;
+ char number_plus[MAX_CALL_NUMBER_LEN];
};
struct tnoti_call_status_waiting {
/* IMS specific */
enum telephony_network_ims_reg_network_type {
- NETWORK_IMS_REG_NETWORK_TYPE_INTERNET = 1, /**< VoLTE Feature type */
- NETWORK_IMS_REG_NETWORK_TYPE_WIFI, /**< SMSoverIP Feature type */
- NETWORK_IMS_REG_NETWORK_TYPE_IMS, /**< RCS Feature type */
- NETWORK_IMS_REG_NETWORK_TYPE_EMERGENCY /**< VT Feature type */
+ NETWORK_IMS_REG_NETWORK_TYPE_UNKNOWN, /**< Unknown */
+ NETWORK_IMS_REG_NETWORK_TYPE_MOBILE, /**< Mobile */
+ NETWORK_IMS_REG_NETWORK_TYPE_WIFI, /**< WiFi */
};
/* IMS specific */
TReturn result;
};
+struct tresp_network_ims_deregister {
+ TReturn result;
+};
+
struct tnoti_network_registration_status {
enum telephony_network_service_domain_status cs_domain_status;
enum telephony_network_service_domain_status ps_domain_status;
TREQ_SIM_GET_DOMAIN,
TREQ_SIM_GET_PCSCF,
TREQ_SIM_GET_ISIM_SERVICE_TABLE,
+ TREQ_SIM_SET_PROVISIONING,
TREQ_SAT = TCORE_REQUEST | TCORE_TYPE_SAT,
TREQ_SAT_REQ_ENVELOPE,
TREQ_NETWORK_GET_ROAMING_PREFERENCE,
TREQ_NETWORK_GET_SUBSCRIPTION_INFO,
TREQ_NETWORK_SEARCH_ECC_RAT,
+ TREQ_NETWORK_IMS_DEREGISTER,
TREQ_PS = TCORE_REQUEST | TCORE_TYPE_PS,
TREQ_PS_SET_PDP_ACTIVATE,
TRESP_NETWORK_GET_ROAMING_PREFERENCE,
TRESP_NETWORK_GET_SUBSCRIPTION_INFO,
TRESP_NETWORK_SEARCH_ECC_RAT,
+ TRESP_NETWORK_IMS_DEREGISTER,
TRESP_PS = TCORE_RESPONSE | TCORE_TYPE_PS,
TRESP_PS_SET_PDP_ACTIVATE,
struct tel_sat_icon{
unsigned char width;
unsigned char height;
- enum img_coding_scheme ics;
+ enum tel_sim_img_coding_scheme ics;
unsigned short icon_data_len;
unsigned short clut_data_len;
char icon_file[SAT_IMG_DATA_FILE_PATH_LEN_MAX];
SIM_PCSCF_TYPE_IPV6, /**< IPv6 */
};
+enum tel_sim_powerstate {
+ SIM_POWER_OFF = 0x00, /**< OFF */
+ SIM_POWER_ON = 0x01, /**< ON */
+ SIM_POWER_UNSPECIFIED = 0xFF /**< Unspecified */
+};
+
+enum tel_sim_provision {
+ SIM_PROVISION_DEACTIVATE = 0x00, /**< De-activate Provisioning */
+ SIM_PROVISION_ACTIVATE = 0x01, /**< Activate Provisioning */
+ SIM_PROVISION_UNSPECIFIED = 0xFF /**< Unspecified */
+};
+
+enum tel_sim_img_coding_scheme{
+ SIM_IMG_CODING_SCHEME_BASIC = 0x11,
+ SIM_IMG_CODING_SCHEME_COLOUR = 0x21,
+ SIM_IMG_CODING_SCHEME_RESERVED = 0xFF
+};
+
struct tel_sim_sst {
char service[SIM_SST_SERVICE_CNT_MAX]; /**< should accessed with 'enum tel_sim_sst_service' as index */
};
unsigned char Ext1RecordId; /**< Extensiion1 Record Identifier */
};
-enum tel_sim_powerstate {
- SIM_POWER_OFF = 0x00, /**< OFF */
- SIM_POWER_ON = 0x01, /**< ON */
- SIM_POWER_UNSPECIFIED = 0xFF /**< Unspecified */
-};
-
-
-struct treq_sim_verify_pins {
- enum tel_sim_pin_type pin_type;
- unsigned int pin_length;
- char pin[9];
-};
-
-struct treq_sim_verify_puks {
- enum tel_sim_pin_type puk_type;
- unsigned int puk_length;
- char puk[9];
- unsigned int pin_length;
- char pin[9];
-};
-
-struct treq_sim_change_pins {
- enum tel_sim_pin_type type;
- unsigned int old_pin_length;
- char old_pin[9];
- unsigned int new_pin_length;
- char new_pin[9];
-};
-
-struct treq_sim_get_facility_status {
- enum tel_sim_facility_type type;
-};
-
-struct treq_sim_disable_facility {
- enum tel_sim_facility_type type;
- unsigned int password_length;
- char password[39];
-};
-
-struct treq_sim_enable_facility {
- enum tel_sim_facility_type type;
- unsigned int password_length;
- char password[39];
-};
-
-struct treq_sim_get_lock_info {
- enum tel_sim_facility_type type;
-};
-
-struct treq_sim_transmit_apdu {
- unsigned int apdu_length;
- unsigned char apdu[SIM_APDU_DATA_LEN_MAX];
-};
-
-struct treq_sim_set_language {
- enum tel_sim_language_type language;
-};
-
-struct treq_sim_req_authentication {
- enum tel_sim_auth_type auth_type; /**< Authentication type */
- unsigned int rand_length; /**< the length of RAND */
- unsigned int autn_length; /**< the length of AUTN. it is not used in case of GSM AUTH */
- char rand_data[SIM_AUTH_REQ_DATA_LEN_MAX + 1]; /**< RAND data */
- char autn_data[SIM_AUTH_REQ_DATA_LEN_MAX + 1]; /**< AUTN data. it is not used in case of GSM AUTH */
-};
-
-struct treq_sim_set_powerstate {
- enum tel_sim_powerstate state;
-};
-
-struct tresp_sim_set_powerstate {
- enum tel_sim_power_set_result result;
-};
-
-
-
-struct tresp_sim_verify_pins {
- enum tel_sim_pin_operation_result result;
- enum tel_sim_pin_type pin_type;
- int retry_count;
-};
-
-struct tresp_sim_verify_puks {
- enum tel_sim_pin_operation_result result;
- enum tel_sim_pin_type pin_type;
- int retry_count;
-};
-
-struct tresp_sim_change_pins {
- enum tel_sim_pin_operation_result result;
- enum tel_sim_pin_type pin_type;
- int retry_count;
-};
-
-struct tresp_sim_get_facility_status {
- enum tel_sim_pin_operation_result result;
- enum tel_sim_facility_type type;
- gboolean b_enable;
-};
-
-struct tresp_sim_disable_facility {
- enum tel_sim_pin_operation_result result;
- enum tel_sim_facility_type type;
- int retry_count;
-};
-
-struct tresp_sim_enable_facility {
- enum tel_sim_pin_operation_result result;
- enum tel_sim_facility_type type;
- int retry_count;
-};
-
-struct tresp_sim_get_lock_info {
- enum tel_sim_pin_operation_result result;
- enum tel_sim_facility_type type;
- enum tel_sim_lock_status lock_status;
- int retry_count;
-};
-
-struct tresp_sim_transmit_apdu {
- enum tel_sim_access_result result;
- unsigned int apdu_resp_length;
- unsigned char *apdu_resp;
-};
-
-struct tresp_sim_get_atr {
- enum tel_sim_access_result result;
- unsigned int atr_length;
- unsigned char atr[256 + 2];
-};
-
struct tel_sim_ecc {
char ecc_num[SIM_ECC_BYTE_LEN_MAX * 2 + 1]; /**< Emergency Call Code info-ECC is coded in BCD format. null termination used*/
char ecc_string[SIM_ECC_STRING_LEN_MAX + 1]; /**< Alphabet identifier. null termination used*/
enum tel_sim_language_type language[SIM_LANG_CNT_MAX];
};
-struct tresp_sim_set_data {
- enum tel_sim_access_result result;
-};
-
struct tel_sim_iccid {
char iccid[SIM_ICCID_LEN_MAX + 1];
};
struct tel_sim_mb_number mb[SIM_MSP_CNT_MAX*5]; /**< each profile mailbox number can exist 5 numbers */
};
-struct treq_sim_set_mailbox {
- gboolean b_cphs;
- struct tel_sim_mb_number mb_info;
-};
-
struct tel_sim_cfis {
int rec_index;
unsigned char msp_num; /**< MSP number*/
struct tel_sim_cphs_cf cphs_cf;
};
-struct treq_sim_set_callforwarding {
- gboolean b_cphs;
- struct tel_sim_cfis cf;
- struct tel_sim_cphs_cf cphs_cf;
-};
-
struct tel_sim_mw {
int rec_index;
unsigned char indicator_status; /**< Indicator status*/
enum tel_sim_file_id file_id[SIM_FILE_ID_LIST_MAX_COUNT];
};
-enum img_coding_scheme{
- IMAGE_CODING_SCHEME_BASIC = 0x11,
- IMAGE_CODING_SCHEME_COLOUR = 0x21,
- IMAGE_CODING_SCHEME_RESERVED = 0xFF
-};
-
struct tel_sim_img{
unsigned char width;
unsigned char height;
- enum img_coding_scheme ics;
+ enum tel_sim_img_coding_scheme ics;
unsigned short iidf_fileid;
unsigned short offset;
unsigned short length;
};
struct tel_sim_impi {
- char *impi;
+ char *impi; /**< ISIM IMPI data */
};
struct tel_sim_impu {
- char *impu;
+ char *impu; /**< ISIM IMPU data */
};
struct tel_sim_impu_list {
- unsigned int count;
- struct tel_sim_impu impu[SIM_IMPU_CNT_MAX];
+ unsigned int count; /**< ISIM IMPU data count */
+ struct tel_sim_impu impu[SIM_IMPU_CNT_MAX]; /**< ISIM IMPU list */
};
struct tel_sim_domain {
- char *domain;
+ char *domain; /**< ISIM Domain data */
};
struct tel_sim_pcscf {
- enum tel_sim_pcscf_type type;
- char *pcscf;
+ enum tel_sim_pcscf_type type; /**< ISIM P-CSCF type */
+ char *pcscf; /**< ISIM P-CSCF data */
};
struct tel_sim_pcscf_list {
- unsigned int count;
- struct tel_sim_pcscf pcscf[SIM_PCSCF_CNT_MAX];
+ unsigned int count; /**< ISIM P-CSCF data count */
+ struct tel_sim_pcscf pcscf[SIM_PCSCF_CNT_MAX]; /**< ISIM P-CSCF list */
+};
+
+struct treq_sim_verify_pins {
+ enum tel_sim_pin_type pin_type;
+ unsigned int pin_length;
+ char pin[9];
+};
+
+struct treq_sim_verify_puks {
+ enum tel_sim_pin_type puk_type;
+ unsigned int puk_length;
+ char puk[9];
+ unsigned int pin_length;
+ char pin[9];
+};
+
+struct treq_sim_change_pins {
+ enum tel_sim_pin_type type;
+ unsigned int old_pin_length;
+ char old_pin[9];
+ unsigned int new_pin_length;
+ char new_pin[9];
+};
+
+struct treq_sim_get_facility_status {
+ enum tel_sim_facility_type type;
+};
+
+struct treq_sim_disable_facility {
+ enum tel_sim_facility_type type;
+ unsigned int password_length;
+ char password[39];
+};
+
+struct treq_sim_enable_facility {
+ enum tel_sim_facility_type type;
+ unsigned int password_length;
+ char password[39];
+};
+
+struct treq_sim_get_lock_info {
+ enum tel_sim_facility_type type;
+};
+
+struct treq_sim_transmit_apdu {
+ unsigned int apdu_length;
+ unsigned char apdu[SIM_APDU_DATA_LEN_MAX];
+};
+
+struct treq_sim_set_language {
+ enum tel_sim_language_type language;
+};
+
+struct treq_sim_req_authentication {
+ enum tel_sim_auth_type auth_type; /**< Authentication type */
+ unsigned int rand_length; /**< the length of RAND */
+ unsigned int autn_length; /**< the length of AUTN. it is not used in case of GSM AUTH */
+ char rand_data[SIM_AUTH_REQ_DATA_LEN_MAX + 1]; /**< RAND data */
+ char autn_data[SIM_AUTH_REQ_DATA_LEN_MAX + 1]; /**< AUTN data. it is not used in case of GSM AUTH */
+};
+
+struct treq_sim_set_powerstate {
+ enum tel_sim_powerstate state;
+};
+
+struct treq_sim_set_mailbox {
+ gboolean b_cphs;
+ struct tel_sim_mb_number mb_info;
+};
+
+struct treq_sim_set_callforwarding {
+ gboolean b_cphs;
+ struct tel_sim_cfis cf;
+ struct tel_sim_cphs_cf cphs_cf;
+};
+
+struct treq_sim_set_provisioning {
+ enum tel_sim_provision cmd;
+};
+
+struct tresp_sim_set_powerstate {
+ enum tel_sim_power_set_result result;
+};
+
+struct tresp_sim_verify_pins {
+ enum tel_sim_pin_operation_result result;
+ enum tel_sim_pin_type pin_type;
+ int retry_count;
+};
+
+struct tresp_sim_verify_puks {
+ enum tel_sim_pin_operation_result result;
+ enum tel_sim_pin_type pin_type;
+ int retry_count;
+};
+
+struct tresp_sim_change_pins {
+ enum tel_sim_pin_operation_result result;
+ enum tel_sim_pin_type pin_type;
+ int retry_count;
+};
+
+struct tresp_sim_get_facility_status {
+ enum tel_sim_pin_operation_result result;
+ enum tel_sim_facility_type type;
+ gboolean b_enable;
+};
+
+struct tresp_sim_disable_facility {
+ enum tel_sim_pin_operation_result result;
+ enum tel_sim_facility_type type;
+ int retry_count;
+};
+
+struct tresp_sim_enable_facility {
+ enum tel_sim_pin_operation_result result;
+ enum tel_sim_facility_type type;
+ int retry_count;
+};
+
+struct tresp_sim_get_lock_info {
+ enum tel_sim_pin_operation_result result;
+ enum tel_sim_facility_type type;
+ enum tel_sim_lock_status lock_status;
+ int retry_count;
+};
+
+struct tresp_sim_transmit_apdu {
+ enum tel_sim_access_result result;
+ unsigned int apdu_resp_length;
+ unsigned char *apdu_resp;
+};
+
+struct tresp_sim_get_atr {
+ enum tel_sim_access_result result;
+ unsigned int atr_length;
+ unsigned char atr[256 + 2];
+};
+
+struct tresp_sim_set_data {
+ enum tel_sim_access_result result;
};
struct tresp_sim_read {
char integrity_data[SIM_AUTH_RESP_DATA_LEN_MAX + 1]; /**< integrity key */
};
+struct tresp_sim_set_provisioning {
+ enum tel_sim_access_result result;
+};
+
struct tnoti_sim_status {
enum tel_sim_status sim_status;
gboolean b_changed;
%define major 0
%define minor 2
-%define patchlevel 91
+%define patchlevel 92
Name: libtcore
Version: %{major}.%{minor}.%{patchlevel}
if (!at || !line)
return;
- dbg("pdu_status: [%s] data_mode: [%s]",
- (at->pdu_status ? "TRUE" : "FALSE"),
- (at->data_mode == MODE_BIN ? "Binary" : "Hex"));
if (at->pdu_status == FALSE) {
g_hash_table_iter_init(&iter, at->unsolicited_table);
/* Validate Request */
if (!at->req) {
- err("at->req is NULL");
_emit_unsolicited_message(at, pos);
} else {
tcore_at_final_response ret;
+++ /dev/null
-/*
- * libtcore
- *
- * 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.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <glib.h>
-
-#include "tcore.h"
-#include "internal/tcore_types.h"
-#include "plugin.h"
-#include "queue.h"
-#include "user_request.h"
-#include "co_call.h"
-
-
-#define MAX_CALL_OBJECTS 6
-
-struct call_cli_info {
- enum tcore_call_cli_mode mode;
- enum tcore_call_no_cli_cause no_cli_cause;
- char number[MAX_CALL_NUMBER_LEN];
- int number_len;
-};
-
-struct call_cna_info {
- enum tcore_call_cna_mode mode;
- int dcs;
- char name[MAX_CALL_NAME_LEN];
- int name_len;
-};
-
-struct call_object {
- enum tcore_call_type type;
-
- unsigned int handle;
- unsigned int id;
-
- enum tcore_call_direction direction;
- enum tcore_call_status status;
- gboolean mpty;
- struct call_cli_info cli;
- struct call_cna_info cna;
- unsigned int cug_id;
- unsigned int active_line;
- struct call_time {
- long start; /* In seconds */
- long end; /* In seconds */
- } time;
-
- gboolean is_volte_call;
- int session_id; /* VoLTE only */
- int conf_call_session_id; /* Conference call session-id (VoLTE only) */
- gboolean early_media; /* VoLTE only */
-
- gboolean is_release_pending;
- enum tcore_call_silent_redial_reason redial_reason;
-};
-
-struct private_object_data {
- GSList *cobjs;
- struct tcore_call_operations *ops[TCORE_OPS_TYPE_MAX];
- struct tcore_call_control_operations *cops;
- struct tcore_call_information_operations *iops;
-};
-
-static unsigned int __assign_handle(CoreObject *o)
-{
- unsigned int handle_candidate = MIN_HANDLE;
- CallObject *co = NULL;
-
- /* Find unused 'handle' - starting from 1 */
- while (handle_candidate < MAX_HANDLE) {
- co = tcore_call_object_find_by_handle(o, handle_candidate);
- if (NULL == co) {
- /* Unused handle found */
- return handle_candidate;
- } else {
- /* 'handle' already used, try next value */
- handle_candidate++;
- co = NULL;
- }
- }
-
- err("available handle not found, serious");
- return INVALID_HANDLE;
-}
-
-static TReturn _dispatcher(CoreObject *o, UserRequest *ur, enum tcore_ops_type ops_type)
-{
- enum tcore_request_command command;
-
- struct private_object_data *po = tcore_object_ref_object(o);
- struct tcore_call_operations *ops = NULL;
-
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_CALL, TCORE_RETURN_EINVAL);
- CORE_OBJECT_VALIDATE_OPS_RETURN_VAL(ops_type, TCORE_RETURN_EINVAL);
-
- tcore_check_null_ret_err("po", po, TCORE_RETURN_EINVAL);
- tcore_check_null_ret_err("ur", ur, TCORE_RETURN_EINVAL);
-
- ops = po->ops[ops_type];
- tcore_check_null_ret_err("ops", ops, TCORE_RETURN_FAILURE);
-
- command = tcore_user_request_get_command(ur);
- switch (command) {
- case TREQ_CALL_DIAL:
- tcore_check_null_ret_err("ops->dial",
- ops->dial, TCORE_RETURN_ENOSYS);
-
- return ops->dial(o, ur);
-
- case TREQ_CALL_ANSWER:
- tcore_check_null_ret_err("ops->answer",
- ops->answer, TCORE_RETURN_ENOSYS);
-
- return ops->answer(o, ur);
-
- case TREQ_CALL_END:
- tcore_check_null_ret_err("ops->end",
- ops->end, TCORE_RETURN_ENOSYS);
-
- return ops->end(o, ur);
-
- case TREQ_CALL_HOLD:
- tcore_check_null_ret_err("ops->hold",
- ops->hold, TCORE_RETURN_ENOSYS);
-
- return ops->hold(o, ur);
-
- case TREQ_CALL_ACTIVE:
- tcore_check_null_ret_err("ops->active",
- ops->active, TCORE_RETURN_ENOSYS);
-
- return ops->active(o, ur);
-
- case TREQ_CALL_SWAP:
- tcore_check_null_ret_err("ops->swap",
- ops->swap, TCORE_RETURN_ENOSYS);
-
- return ops->swap(o, ur);
-
- case TREQ_CALL_JOIN:
- tcore_check_null_ret_err("ops->join",
- ops->join, TCORE_RETURN_ENOSYS);
-
- return ops->join(o, ur);
-
- case TREQ_CALL_SPLIT:
- tcore_check_null_ret_err("ops->split",
- ops->split, TCORE_RETURN_ENOSYS);
-
- return ops->split(o, ur);
-
- case TREQ_CALL_DEFLECT:
- tcore_check_null_ret_err("ops->deflect",
- ops->deflect, TCORE_RETURN_ENOSYS);
-
- return ops->deflect(o, ur);
-
- case TREQ_CALL_TRANSFER:
- tcore_check_null_ret_err("ops->transfer",
- ops->transfer, TCORE_RETURN_ENOSYS);
-
- return ops->transfer(o, ur);
-
- case TREQ_CALL_START_CONT_DTMF:
- tcore_check_null_ret_err("ops->start_cont_dtmf",
- ops->start_cont_dtmf, TCORE_RETURN_ENOSYS);
-
- return ops->start_cont_dtmf(o, ur);
-
- case TREQ_CALL_STOP_CONT_DTMF:
- tcore_check_null_ret_err("ops->stop_cont_dtmf",
- ops->stop_cont_dtmf, TCORE_RETURN_ENOSYS);
-
- return ops->stop_cont_dtmf(o, ur);
-
- case TREQ_CALL_SEND_BURST_DTMF:
- tcore_check_null_ret_err("ops->send_burst_dtmf",
- ops->send_burst_dtmf, TCORE_RETURN_ENOSYS);
-
- return ops->send_burst_dtmf(o, ur);
-
- case TREQ_CALL_GET_PRIVACY_MODE:
- tcore_check_null_ret_err("ops->get_privacy_mode",
- ops->get_privacy_mode, TCORE_RETURN_ENOSYS);
-
- return ops->get_privacy_mode(o, ur);
-
- case TREQ_CALL_SET_PRIVACY_MODE:
- tcore_check_null_ret_err("ops->set_privacy_mode",
- ops->set_privacy_mode, TCORE_RETURN_ENOSYS);
-
- return ops->set_privacy_mode(o, ur);
-
- case TREQ_CALL_SET_SOUND_PATH:
- tcore_check_null_ret_err("ops->set_sound_path",
- ops->set_sound_path, TCORE_RETURN_ENOSYS);
-
- return ops->set_sound_path(o, ur);
-
- case TREQ_CALL_GET_SOUND_VOLUME_LEVEL:
- tcore_check_null_ret_err("ops->get_sound_volume_level",
- ops->get_sound_volume_level, TCORE_RETURN_ENOSYS);
-
- return ops->get_sound_volume_level(o, ur);
-
- case TREQ_CALL_SET_SOUND_VOLUME_LEVEL:
- tcore_check_null_ret_err("ops->set_sound_volume_level",
- ops->set_sound_volume_level, TCORE_RETURN_ENOSYS);
-
- return ops->set_sound_volume_level(o, ur);
-
- case TREQ_CALL_SET_SOUND_MUTE_STATUS:
- tcore_check_null_ret_err("ops->set_sound_mute_status",
- ops->set_sound_mute_status, TCORE_RETURN_ENOSYS);
-
- return ops->set_sound_mute_status(o, ur);
-
- case TREQ_CALL_GET_SOUND_MUTE_STATUS:
- tcore_check_null_ret_err("ops->get_sound_mute_status",
- ops->get_sound_mute_status, TCORE_RETURN_ENOSYS);
-
- return ops->get_sound_mute_status(o, ur);
-
- case TREQ_CALL_SET_SOUND_RECORDING:
- tcore_check_null_ret_err("ops->set_sound_recording",
- ops->set_sound_recording, TCORE_RETURN_ENOSYS);
-
- return ops->set_sound_recording(o, ur);
-
- case TREQ_CALL_SET_SOUND_EQUALIZATION:
- tcore_check_null_ret_err("ops->set_sound_equalization",
- ops->set_sound_equalization, TCORE_RETURN_ENOSYS);
-
- return ops->set_sound_equalization(o, ur);
-
- case TREQ_CALL_SET_SOUND_NOISE_REDUCTION:
- tcore_check_null_ret_err("ops->set_sound_noise_reduction",
- ops->set_sound_noise_reduction, TCORE_RETURN_ENOSYS);
-
- return ops->set_sound_noise_reduction(o, ur);
-
- case TREQ_CALL_SET_SOUND_CLOCK_STATUS:
- tcore_check_null_ret_err("ops->set_sound_clock_status",
- ops->set_sound_clock_status, TCORE_RETURN_ENOSYS);
-
- return ops->set_sound_clock_status(o, ur);
-
- case TREQ_CALL_SET_PREFERRED_VOICE_SUBSCRIPTION:
- tcore_check_null_ret_err("ops->set_preferred_voice_subscription",
- ops->set_preferred_voice_subscription, TCORE_RETURN_ENOSYS);
-
- return ops->set_preferred_voice_subscription(o, ur);
-
- case TREQ_CALL_GET_PREFERRED_VOICE_SUBSCRIPTION:
- tcore_check_null_ret_err("ops->get_preferred_voice_subscription",
- ops->get_preferred_voice_subscription, TCORE_RETURN_ENOSYS);
-
- return ops->get_preferred_voice_subscription(o, ur);
-
- case TREQ_CALL_MODIFY:
- tcore_check_null_ret_err("ops->modify",
- ops->modify, TCORE_RETURN_ENOSYS);
-
- return ops->modify(o, ur);
-
- case TREQ_CALL_CONFIRM_MODIFY:
- tcore_check_null_ret_err("ops->confirm_modify",
- ops->confirm_modify, TCORE_RETURN_ENOSYS);
-
- return ops->confirm_modify(o, ur);
-
- default:
- break;
- }
-
- return TCORE_RETURN_SUCCESS;
-}
-
-static void _free_hook(CoreObject *o)
-{
- struct private_object_data *po = NULL;
-
- po = tcore_object_ref_object(o);
- if (!po)
- return;
-
- g_slist_free_full(po->cobjs, g_free);
- g_free(po);
-
- tcore_object_link_object(o, NULL);
-}
-
-typedef gboolean(*func)(CallObject *co, void *data);
-static CallObject *_find_object(GSList *objs, void *data, func compare)
-{
- CallObject *co = NULL;
- GSList *l = NULL;
-
- tcore_check_null_ret_err("objs", objs, NULL);
- tcore_check_null_ret_err("compare", compare, NULL);
-
- l = objs;
- while (l) {
- co = (CallObject *) l->data;
-
- if (compare(co, data))
- return co;
-
- l = g_slist_next(l);
- }
-
- return NULL;
-}
-
-static GSList *_find_object_all(GSList *objs, void *data, func compare)
-{
- CallObject *co = NULL;
- GSList *l = NULL;
- GSList *ret = NULL;
-
- tcore_check_null_ret_err("objs", objs, NULL);
- tcore_check_null_ret_err("compare", compare, NULL);
-
- l = objs;
- while (l) {
- co = (CallObject *) l->data;
-
- if (compare(co, data))
- ret = g_slist_append(ret, co);
-
- l = g_slist_next(l);
- }
-
- return ret;
-}
-
-static gboolean _compare_by_id(CallObject *co, void *data)
-{
- unsigned int *id = (unsigned int *) data;
-
- tcore_check_null_ret_err("co", co, FALSE);
- tcore_check_null_ret_err("data", data, FALSE);
-
- if (co->id == *id)
- return TRUE;
-
- return FALSE;
-}
-
-static gboolean _compare_by_handle(CallObject *co, void *data)
-{
- unsigned int *handle = (unsigned int *) data;
-
- tcore_check_null_ret_err("co", co, FALSE);
- tcore_check_null_ret_err("data", data, FALSE);
-
- if (co->handle == *handle)
- return TRUE;
-
- return FALSE;
-}
-
-
-static gboolean _compare_by_session_id(CallObject *co, void *data)
-{
- int *session_id = data;
-
- tcore_check_null_ret_err("co", co, FALSE);
- tcore_check_null_ret_err("data", data, FALSE);
-
- if (co->session_id == *session_id)
- return TRUE;
-
- return FALSE;
-}
-
-static gboolean _compare_by_status(CallObject *co, void *data)
-{
- enum tcore_call_status *ct = (enum tcore_call_status *) data;
-
- tcore_check_null_ret_err("co", co, FALSE);
- tcore_check_null_ret_err("data", data, FALSE);
-
- if (co->status == *ct)
- return TRUE;
-
- return FALSE;
-}
-
-static gboolean _compare_by_number(CallObject *co, void *data)
-{
- char *number = (char *) data;
-
- tcore_check_null_ret_err("co", co, FALSE);
- tcore_check_null_ret_err("data", data, FALSE);
-
- if (!strcmp(co->cli.number, number))
- return TRUE;
-
- return FALSE;
-}
-
-static enum tcore_call_cli_mode _check_cli_mode_by_number(char *num)
-{
- tcore_check_null_ret_err("num", num, TCORE_CALL_CLI_MODE_DEFAULT);
-
- if (!strncmp(num, "*31#", 4))
- return TCORE_CALL_CLI_MODE_PRESENT;
-
- if (!strncmp(num, "#31#", 4))
- return TCORE_CALL_CLI_MODE_RESTRICT;
-
- return TCORE_CALL_CLI_MODE_DEFAULT;
-}
-
-
-/* Call Object APIs */
-CallObject *tcore_call_object_new(CoreObject *o)
-{
- struct private_object_data *po = NULL;
- CallObject *co = NULL;
-
- po = tcore_object_ref_object(o);
-
- tcore_check_null_ret_err("po", po, NULL);
-
- co = g_try_malloc0(sizeof(struct call_object));
- if (co == NULL)
- return NULL;
-
- co->handle = __assign_handle(o);
-
- if (INVALID_HANDLE == co->handle) {
- err("valid handle not available. call object creation failed");
- g_free(co);
- return NULL;
- }
- co->id = -1;
-
- po->cobjs = g_slist_append(po->cobjs, co);
-
- dbg("new call object handle : [%d]", co->handle);
-
- return co;
-}
-
-gboolean tcore_call_object_free(CoreObject *o, CallObject *co)
-{
- struct private_object_data *po = NULL;
- po = tcore_object_ref_object(o);
-
- tcore_check_null_ret_err("po", po, FALSE);
- tcore_check_null_ret_err("po->cobjs", po->cobjs, FALSE);
- tcore_check_null_ret_err("co", co, FALSE);
-
- po->cobjs = g_slist_remove(po->cobjs, co);
- g_free(co);
-
- return TRUE;
-}
-
-int tcore_call_object_total_length(CoreObject *o)
-{
- struct private_object_data *po = NULL;
- po = tcore_object_ref_object(o);
-
- tcore_check_null_ret_err("po", po, 0);
- tcore_check_null_ret_err("po->cobjs", po->cobjs, 0);
-
- return (int)g_slist_length(po->cobjs);
-}
-
-CallObject *tcore_call_object_current_on_mt_processing(CoreObject *o)
-{
- struct private_object_data *po = NULL;
- CallObject *call_obj = NULL;
- GSList *l = NULL;
-
- enum tcore_call_status cs = TCORE_CALL_STATUS_INCOMING;
- po = tcore_object_ref_object(o);
-
- tcore_check_null_ret_err("po", po, NULL);
- tcore_check_null_ret_err("po->cobjs", po->cobjs, NULL);
-
- l = _find_object_all(po->cobjs, (void *)&cs, (void *)_compare_by_status);
- if (!l) {
- cs = TCORE_CALL_STATUS_WAITING;
- l = _find_object_all(po->cobjs, (void *)&cs, (void *)_compare_by_status);
- if (!l)
- return 0;
- }
-
- call_obj = (CallObject *)(l->data);
- g_slist_free(l);
-
- return call_obj;
-}
-
-CallObject *tcore_call_object_current_on_mo_processing(CoreObject *o)
-{
- struct private_object_data *po = NULL;
- CallObject *call_obj = NULL;
- GSList *l = NULL;
-
- po = tcore_object_ref_object(o);
-
- tcore_check_null_ret_err("po", po, NULL);
- tcore_check_null_ret_err("po->cobjs", po->cobjs, NULL);
-
- l = tcore_call_object_find_by_status(o, TCORE_CALL_STATUS_DIALING);
- if (!l) {
- l = tcore_call_object_find_by_status(o, TCORE_CALL_STATUS_ALERT);
- if (!l) {
- l = tcore_call_object_find_by_status(o, TCORE_CALL_STATUS_SETUP);
- if (!l) {
- l = tcore_call_object_find_by_status(o, TCORE_CALL_STATUS_SETUP_PENDING);
- if (!l)
- return NULL;
- }
- }
- }
-
- call_obj = (CallObject *)(l->data);
- g_slist_free(l);
-
- return call_obj;
-}
-
-CallObject *tcore_call_object_find_by_id(CoreObject *o, int id)
-{
- struct private_object_data *po = NULL;
-
- po = tcore_object_ref_object(o);
-
- tcore_check_null_ret_err("po", po, NULL);
- tcore_check_null_ret_err("po->cobjs", po->cobjs, NULL);
-
- return _find_object(po->cobjs, (void *) &id, (void *) _compare_by_id);
-}
-
-CallObject *tcore_call_object_find_by_handle(CoreObject *o, int handle)
-{
- struct private_object_data *po = NULL;
-
- po = tcore_object_ref_object(o);
-
- tcore_check_null_ret_err("po", po, NULL);
- tcore_check_null_ret_err("po->cobjs", po->cobjs, NULL);
-
- return _find_object(po->cobjs, (void *) &handle, (void *) _compare_by_handle);
-
-}
-
-
-CallObject *tcore_call_object_find_by_number(CoreObject *o, char *num)
-{
- struct private_object_data *po = NULL;
-
- po = tcore_object_ref_object(o);
-
- tcore_check_null_ret_err("po", po, NULL);
- tcore_check_null_ret_err("po->cobjs", po->cobjs, NULL);
- tcore_check_null_ret_err("num", num, NULL);
-
- return _find_object(po->cobjs, (void *) num, (void *) _compare_by_number);
-}
-
-GSList *tcore_call_object_find_by_status(CoreObject *o, enum tcore_call_status cs)
-{
- struct private_object_data *po = NULL;
-
- po = tcore_object_ref_object(o);
-
- tcore_check_null_ret_err("po", po, NULL);
- tcore_check_null_ret_err("po->cobjs", po->cobjs, NULL);
-
- return _find_object_all(po->cobjs, (void *) &cs, (void *) _compare_by_status);
-}
-
-int tcore_call_object_get_id(CallObject *co)
-{
- tcore_check_null_ret_err("co", co, -1);
-
- return co->id;
-}
-
-gboolean tcore_call_object_set_id(CallObject *co , int call_id)
-{
- tcore_check_null_ret_err("co", co, FALSE);
- co->id = call_id;
-
- return TRUE;
-}
-
-int tcore_call_object_get_handle(CallObject *co)
-{
- tcore_check_null_ret_err("co", co, -1);
-
- return co->handle;
-}
-
-
-gboolean tcore_call_object_set_type(CallObject *co, enum tcore_call_type ct)
-{
- tcore_check_null_ret_err("co", co, FALSE);
-
- co->type = ct;
- return TRUE;
-}
-
-enum tcore_call_type tcore_call_object_get_type(CallObject *co)
-{
- tcore_check_null_ret_err("co", co, -1);
-
- return co->type;
-}
-
-gboolean tcore_call_object_set_direction(CallObject *co, enum tcore_call_direction cd)
-{
- tcore_check_null_ret_err("co", co, FALSE);
-
- co->direction = cd;
- return TRUE;
-}
-
-enum tcore_call_direction tcore_call_object_get_direction(CallObject *co)
-{
- tcore_check_null_ret_err("co", co, -1);
-
- return co->direction;
-}
-
-gboolean tcore_call_object_set_status(CallObject *co, enum tcore_call_status cs)
-{
- tcore_check_null_ret_err("co", co, FALSE);
-
- co->status = cs;
- return TRUE;
-}
-
-enum tcore_call_status tcore_call_object_get_status(CallObject *co)
-{
- tcore_check_null_ret_err("co", co, -1);
-
- return co->status;
-}
-
-gboolean tcore_call_object_set_cli_info(CallObject *co,
- enum tcore_call_cli_mode mode, enum tcore_call_no_cli_cause cause,
- char *num, int num_len)
-{
- char *pos = NULL;
-
- tcore_check_null_ret_err("co", co, FALSE);
-
- dbg("num : %s", num);
- dbg("mode : 0x%x", mode);
-
- if (!num) {
- co->cli.mode = mode;
- if (mode == TCORE_CALL_CLI_MODE_RESTRICT)
- co->cli.no_cli_cause = cause;
- else
- co->cli.no_cli_cause = TCORE_CALL_NO_CLI_CAUSE_NONE;
-
- co->cli.number_len = num_len ;
- co->cli.number[0] = '\0';
-
- return TRUE;
- }
-
- pos = num;
-
- if (mode == TCORE_CALL_CLI_MODE_DEFAULT) {
- co->cli.mode = _check_cli_mode_by_number(num);
-
- if (co->cli.mode != TCORE_CALL_CLI_MODE_DEFAULT)
- pos = (num + 4);
- } else {
- co->cli.mode = mode;
- if (mode == TCORE_CALL_CLI_MODE_RESTRICT)
- co->cli.no_cli_cause = cause;
- else
- co->cli.no_cli_cause = TCORE_CALL_NO_CLI_CAUSE_NONE;
- }
-
- strncpy(co->cli.number, pos, ((num_len - (pos - num)) + 1));
- co->cli.number_len = strlen(co->cli.number);
-
- dbg("co->cli.mode: [0x%x]", co->cli.mode);
- dbg("co->cli.no_cli_cause: [0x%x]", co->cli.no_cli_cause);
- dbg("co->cli.number: [%s]", co->cli.number);
- dbg("co->cli.number_len: [%d]", co->cli.number_len);
-
- return TRUE;
-}
-
-int tcore_call_object_get_number(CallObject *co, char *num)
-{
- tcore_check_null_ret_err("co", co, 0);
- tcore_check_null_ret_err("num", num, 0);
-
- strncpy(num, co->cli.number, MAX_CALL_NUMBER_LEN);
- return co->cli.number_len;
-}
-
-enum tcore_call_cli_mode tcore_call_object_get_cli_mode(CallObject *co)
-{
- tcore_check_null_ret_err("co", co, -1);
-
- return co->cli.mode;
-}
-
-enum tcore_call_no_cli_cause tcore_call_object_get_no_cli_cause(CallObject *co)
-{
- tcore_check_null_ret_err("co", co, -1);
-
- return co->cli.no_cli_cause;
-}
-
-
-gboolean tcore_call_object_set_cna_info(CallObject *co, enum tcore_call_cna_mode mode, char *name, int dcs)
-{
- int len;
- tcore_check_null_ret_err("co", co, FALSE);
- tcore_check_null_ret_err("name", name, FALSE);
-
- len = strlen(name);
- if (len >= MAX_CALL_NAME_LEN)
- return FALSE;
-
- strncpy(co->cna.name, name, len);
- co->cna.name[len] = '\0';
-
- co->cna.mode = mode;
-
- return TRUE;
-}
-
-int tcore_call_object_get_name(CallObject *co, char *name)
-{
- tcore_check_null_ret_err("co", co, 0);
- tcore_check_null_ret_err("name", name, 0);
-
- strncpy(name, co->cna.name, MAX_CALL_NAME_LEN);
- return co->cna.name_len;
-}
-
-enum tcore_call_cna_mode tcore_call_object_get_cna_mode(CallObject *co)
-{
- tcore_check_null_ret_err("co", co, -1);
-
- return co->cna.mode;
-}
-
-gboolean tcore_call_object_set_multiparty_state(CallObject *co, gboolean is)
-{
- tcore_check_null_ret_err("co", co, FALSE);
-
- co->mpty = is;
-
- return TRUE;
-}
-
-gboolean tcore_call_object_get_multiparty_state(CallObject *co)
-{
- tcore_check_null_ret_err("co", co, FALSE);
-
- return co->mpty;
-}
-
-gboolean tcore_call_object_set_active_line(CallObject *co, unsigned int line)
-{
- tcore_check_null_ret_err("co", co, FALSE);
-
- co->active_line = line;
-
- return TRUE;
-}
-
-int tcore_call_object_get_active_line(CallObject *co)
-{
- tcore_check_null_ret_err("co", co, -1);
-
- return co->active_line;
-}
-
-gboolean tcore_call_object_set_is_volte_call(CallObject *co, gboolean flag)
-{
- tcore_check_null_ret_err("co", co, FALSE);
-
- co->is_volte_call = flag;
-
- return TRUE;
-}
-
-gboolean tcore_call_object_get_is_volte_call(CallObject *co)
-{
- tcore_check_null_ret_err("co", co, FALSE);
-
- return co->is_volte_call;
-}
-
-gboolean tcore_call_object_set_session_id(CallObject *co, int session_id)
-{
- tcore_check_null_ret_err("co", co, FALSE);
-
- co->session_id = session_id;
-
- return TRUE;
-}
-
-int tcore_call_object_get_session_id(CallObject *co)
-{
- tcore_check_null_ret_err("co", co, FALSE);
-
- return co->session_id;
-}
-
-gboolean tcore_call_object_set_conf_call_session_id(CallObject *co, int session_id)
-{
- tcore_check_null_ret_err("co", co, FALSE);
-
- co->conf_call_session_id = session_id;
-
- return TRUE;
-}
-
-gboolean tcore_call_object_get_conf_call_session_id(CallObject *co)
-{
- tcore_check_null_ret_err("co", co, FALSE);
-
- return co->conf_call_session_id;
-}
-
-gboolean tcore_call_object_set_early_media(CallObject *co, gboolean flag)
-{
- tcore_check_null_ret_err("co", co, FALSE);
-
- co->early_media = flag;
-
- return TRUE;
-}
-
-gboolean tcore_call_object_get_early_media(CallObject *co)
-{
- tcore_check_null_ret_err("co", co, FALSE);
-
- return co->early_media;
-}
-
-CallObject *tcore_call_object_find_by_session_id(CoreObject *o, int session_id)
-{
- struct private_object_data *po = NULL;
- po = tcore_object_ref_object(o);
-
- tcore_check_null_ret_err("po", po, NULL);
- tcore_check_null_ret_err("po->cobjs", po->cobjs, NULL);
-
- return _find_object(po->cobjs, &session_id, _compare_by_session_id);
-}
-
-gboolean tcore_call_object_check_cs_call_existence(CoreObject *o)
-{
- struct private_object_data *po = NULL;
- CallObject *call_obj = NULL;
- GSList *call_list = NULL;
-
- po = tcore_object_ref_object(o);
- tcore_check_null_ret_err("po", po, FALSE);
-
- call_list = po->cobjs;
- while (call_list) {
- call_obj = call_list->data;
- if (call_obj->is_volte_call == FALSE)
- return TRUE;
-
- call_list = g_slist_next(call_list);
- }
-
- return FALSE;
-}
-
-GSList *tcore_call_object_get_all_session_ids(CoreObject *o)
-{
- struct private_object_data *po = NULL;
- CallObject *call_obj = NULL;
- GSList *call_list = NULL;
- GSList *session_ids = NULL;
-
- po = tcore_object_ref_object(o);
- tcore_check_null_ret_err("po", po, NULL);
-
- call_list = po->cobjs;
- while (call_list) {
- call_obj = call_list->data;
- if (call_obj->is_volte_call == TRUE)
- session_ids = g_slist_append(session_ids, GINT_TO_POINTER(call_obj->session_id));
-
- call_list = g_slist_next(call_list);
- }
-
- return session_ids;
-}
-
-gboolean tcore_call_object_set_is_release_pending(CallObject *co, gboolean flag)
-{
- tcore_check_null_ret_err("co", co, FALSE);
-
- co->is_release_pending = flag;
-
- return TRUE;
-
-}
-
-gboolean tcore_call_object_get_is_release_pending(CallObject *co)
-{
- tcore_check_null_ret_err("co", co, FALSE);
-
- return co->is_release_pending;
-}
-
-gboolean tcore_call_object_set_silent_redial_reason(CallObject *co, enum tcore_call_silent_redial_reason reason)
-{
- tcore_check_null_ret_err("co", co, FALSE);
-
- co->redial_reason = reason;
-
- return TRUE;
-
-}
-enum tcore_call_silent_redial_reason tcore_call_object_get_silent_redial_reason(CallObject *co)
-{
- tcore_check_null_ret_err("co", co, -1);
-
- return co->redial_reason;
-}
-
-TReturn tcore_call_control_answer_hold_and_accept(CoreObject *o, UserRequest* ur, ConfirmCallback cb, void *user_data)
-{
- struct private_object_data *po = NULL;
- po = tcore_object_ref_object(o);
-
- tcore_check_null_ret_err("po", po, TCORE_RETURN_FAILURE);
- tcore_check_null_ret_err("po->cops", po->cops, TCORE_RETURN_FAILURE);
- tcore_check_null_ret_err("po->cops->answer_hold_and_accept", po->cops->answer_hold_and_accept, TCORE_RETURN_ENOSYS);
-
- return po->cops->answer_hold_and_accept(o, ur, cb, user_data);
-}
-
-TReturn tcore_call_control_answer_replace(CoreObject *o, UserRequest* ur, ConfirmCallback cb, void *user_data)
-{
- struct private_object_data *po = NULL;
- po = tcore_object_ref_object(o);
-
- tcore_check_null_ret_err("po", po, TCORE_RETURN_FAILURE);
- tcore_check_null_ret_err("po->cops", po->cops, TCORE_RETURN_FAILURE);
- tcore_check_null_ret_err("po->cops->answer_replace", po->cops->answer_replace, TCORE_RETURN_ENOSYS);
-
- return po->cops->answer_replace(o, ur, cb, user_data);
-}
-
-TReturn tcore_call_control_answer_reject(CoreObject *o, UserRequest* ur, ConfirmCallback cb, void *user_data)
-{
- struct private_object_data *po = NULL;
- po = tcore_object_ref_object(o);
-
- tcore_check_null_ret_err("po", po, TCORE_RETURN_FAILURE);
- tcore_check_null_ret_err("po->cops", po->cops, TCORE_RETURN_FAILURE);
- tcore_check_null_ret_err("po->cops->answer_reject", po->cops->answer_reject, TCORE_RETURN_ENOSYS);
-
- return po->cops->answer_reject(o, ur, cb, user_data);
-}
-
-TReturn tcore_call_control_end_specific(CoreObject *o, UserRequest* ur, const int id, ConfirmCallback cb,
- void *user_data)
-{
- struct private_object_data *po = NULL;
- po = tcore_object_ref_object(o);
-
- tcore_check_null_ret_err("po", po, TCORE_RETURN_FAILURE);
- tcore_check_null_ret_err("po->cops", po->cops, TCORE_RETURN_FAILURE);
- tcore_check_null_ret_err("po->cops->end_specific", po->cops->end_specific, TCORE_RETURN_ENOSYS);
-
- return po->cops->end_specific(o, ur, id, cb, user_data);
-}
-
-TReturn tcore_call_control_end_all_active(CoreObject *o, UserRequest* ur, ConfirmCallback cb, void *user_data)
-{
- struct private_object_data *po = NULL;
- po = tcore_object_ref_object(o);
-
- tcore_check_null_ret_err("po", po, TCORE_RETURN_FAILURE);
- tcore_check_null_ret_err("po->cops", po->cops, TCORE_RETURN_FAILURE);
- tcore_check_null_ret_err("po->cops->end_all_active", po->cops->end_all_active, TCORE_RETURN_ENOSYS);
-
- return po->cops->end_all_active(o, ur, cb, user_data);
-}
-
-TReturn tcore_call_control_end_all_held(CoreObject *o, UserRequest* ur, ConfirmCallback cb, void *user_data)
-{
- struct private_object_data *po = NULL;
- po = tcore_object_ref_object(o);
-
- tcore_check_null_ret_err("po", po, TCORE_RETURN_FAILURE);
- tcore_check_null_ret_err("po->cops", po->cops, TCORE_RETURN_FAILURE);
- tcore_check_null_ret_err("po->cops->end_all_held", po->cops->end_all_held, TCORE_RETURN_ENOSYS);
-
- return po->cops->end_all_held(o, ur, cb, user_data);
-}
-
-TReturn tcore_call_control_active(CoreObject *o, UserRequest* ur, ConfirmCallback cb, void *user_data)
-{
- struct private_object_data *po = NULL;
- po = tcore_object_ref_object(o);
-
- tcore_check_null_ret_err("po", po, TCORE_RETURN_FAILURE);
- tcore_check_null_ret_err("po->cops", po->cops, TCORE_RETURN_FAILURE);
- tcore_check_null_ret_err("po->cops->active", po->cops->active, TCORE_RETURN_ENOSYS);
-
- return po->cops->active(o, ur, cb, user_data);
-}
-
-TReturn tcore_call_control_hold(CoreObject *o, UserRequest* ur, ConfirmCallback cb, void *user_data)
-{
- struct private_object_data *po = NULL;
- po = tcore_object_ref_object(o);
-
- tcore_check_null_ret_err("po", po, TCORE_RETURN_FAILURE);
- tcore_check_null_ret_err("po->cops", po->cops, TCORE_RETURN_FAILURE);
- tcore_check_null_ret_err("po->cops->hold", po->cops->hold, TCORE_RETURN_ENOSYS);
-
- return po->cops->hold(o, ur, cb, user_data);
-}
-
-TReturn tcore_call_control_swap(CoreObject *o, UserRequest* ur, ConfirmCallback cb, void *user_data)
-{
- struct private_object_data *po = NULL;
- po = tcore_object_ref_object(o);
-
- tcore_check_null_ret_err("po", po, TCORE_RETURN_FAILURE);
- tcore_check_null_ret_err("po->cops", po->cops, TCORE_RETURN_FAILURE);
- tcore_check_null_ret_err("po->cops->swap", po->cops->swap, TCORE_RETURN_ENOSYS);
-
- return po->cops->swap(o, ur, cb, user_data);
-}
-
-TReturn tcore_call_control_join(CoreObject *o, UserRequest* ur, ConfirmCallback cb, void *user_data)
-{
- struct private_object_data *po = NULL;
- po = tcore_object_ref_object(o);
-
- tcore_check_null_ret_err("po", po, TCORE_RETURN_FAILURE);
- tcore_check_null_ret_err("po->cops", po->cops, TCORE_RETURN_FAILURE);
- tcore_check_null_ret_err("po->cops->join", po->cops->join, TCORE_RETURN_ENOSYS);
-
- return po->cops->join(o, ur, cb, user_data);
-}
-
-TReturn tcore_call_control_split(CoreObject *o, UserRequest* ur, const int id, ConfirmCallback cb, void *user_data)
-{
- struct private_object_data *po = NULL;
- po = tcore_object_ref_object(o);
-
- tcore_check_null_ret_err("po", po, TCORE_RETURN_FAILURE);
- tcore_check_null_ret_err("po->cops", po->cops, TCORE_RETURN_FAILURE);
- tcore_check_null_ret_err("po->cops->split", po->cops->split, TCORE_RETURN_ENOSYS);
-
- return po->cops->split(o, ur, id, cb, user_data);
-}
-
-TReturn tcore_call_control_transfer(CoreObject *o, UserRequest* ur, ConfirmCallback cb, void *user_data)
-{
- struct private_object_data *po = NULL;
- po = tcore_object_ref_object(o);
-
- tcore_check_null_ret_err("po", po, TCORE_RETURN_FAILURE);
- tcore_check_null_ret_err("po->cops", po->cops, TCORE_RETURN_FAILURE);
- tcore_check_null_ret_err("po->cops->transfer", po->cops->transfer, TCORE_RETURN_ENOSYS);
-
- return po->cops->transfer(o, ur, cb, user_data);
-}
-
-TReturn tcore_call_control_deflect(CoreObject *o, UserRequest* ur, const char *number, ConfirmCallback cb,
- void *user_data)
-{
- struct private_object_data *po = NULL;
- po = tcore_object_ref_object(o);
-
- tcore_check_null_ret_err("po", po, TCORE_RETURN_FAILURE);
- tcore_check_null_ret_err("po->cops", po->cops, TCORE_RETURN_FAILURE);
- tcore_check_null_ret_err("po->cops->deflect", po->cops->deflect, TCORE_RETURN_ENOSYS);
-
- return po->cops->deflect(o, ur, number, cb, user_data);
-}
-
-void tcore_call_control_set_operations(CoreObject *o, struct tcore_call_control_operations *cops)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_CALL);
-
- po = tcore_object_ref_object(o);
- if (!po) {
- err("po is NULL");
- return;
- }
-
- po->cops = cops;
-}
-
-void tcore_call_information_mo_col(CoreObject *o, char *number)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_CALL);
-
- po = tcore_object_ref_object(o);
-
- tcore_check_null_ret("po", po);
- tcore_check_null_ret("po->iops", po->iops);
- tcore_check_null_ret("po->iops->mo_call_col", po->iops->mo_call_col);
-
- po->iops->mo_call_col(o, number);
-}
-
-void tcore_call_information_mo_waiting(CoreObject *o)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_CALL);
-
- po = tcore_object_ref_object(o);
-
- tcore_check_null_ret("po", po);
- tcore_check_null_ret("po->iops", po->iops);
- tcore_check_null_ret("po->iops->mo_call_waiting", po->iops->mo_call_waiting);
-
- po->iops->mo_call_waiting(o);
-}
-
-void tcore_call_information_mo_cug(CoreObject *o, int cug_index)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_CALL);
-
- po = tcore_object_ref_object(o);
-
- tcore_check_null_ret("po", po);
- tcore_check_null_ret("po->iops", po->iops);
- tcore_check_null_ret("po->iops->mo_call_cug", po->iops->mo_call_cug);
-
- po->iops->mo_call_cug(o, cug_index);
-}
-
-void tcore_call_information_mo_forwarded(CoreObject *o)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_CALL);
-
- po = tcore_object_ref_object(o);
-
- tcore_check_null_ret("po", po);
- tcore_check_null_ret("po->iops", po->iops);
- tcore_check_null_ret("po->iops->mo_call_forwarded", po->iops->mo_call_forwarded);
-
- po->iops->mo_call_forwarded(o);
-}
-
-void tcore_call_information_mo_barred_incoming(CoreObject *o)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_CALL);
-
- po = tcore_object_ref_object(o);
-
- tcore_check_null_ret("po", po);
- tcore_check_null_ret("po->iops", po->iops);
- tcore_check_null_ret("po->iops->mo_call_barred_incoming", po->iops->mo_call_barred_incoming);
-
- po->iops->mo_call_barred_incoming(o);
-}
-
-void tcore_call_information_mo_barred_outgoing(CoreObject *o)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_CALL);
-
- po = tcore_object_ref_object(o);
-
- tcore_check_null_ret("po", po);
- tcore_check_null_ret("po->iops", po->iops);
- tcore_check_null_ret("po->iops->mo_call_barred_outgoing", po->iops->mo_call_barred_outgoing);
-
- po->iops->mo_call_barred_outgoing(o);
-}
-
-void tcore_call_information_mo_deflected(CoreObject *o)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_CALL);
-
- po = tcore_object_ref_object(o);
-
- tcore_check_null_ret("po", po);
- tcore_check_null_ret("po->iops", po->iops);
- tcore_check_null_ret("po->iops->mo_call_deflected", po->iops->mo_call_deflected);
-
- po->iops->mo_call_deflected(o);
-}
-
-void tcore_call_information_mo_clir_suppression_reject(CoreObject *o)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_CALL);
-
- po = tcore_object_ref_object(o);
-
- tcore_check_null_ret("po", po);
- tcore_check_null_ret("po->iops", po->iops);
- tcore_check_null_ret("po->iops->mo_call_clir_suppression_reject", po->iops->mo_call_clir_suppression_reject);
-
- po->iops->mo_call_clir_suppression_reject(o);
-}
-
-void tcore_call_information_mo_cfu(CoreObject *o)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_CALL);
-
- po = tcore_object_ref_object(o);
-
- tcore_check_null_ret("po", po);
- tcore_check_null_ret("po->iops", po->iops);
- tcore_check_null_ret("po->iops->mo_call_cfu", po->iops->mo_call_cfu);
-
- po->iops->mo_call_cfu(o);
-}
-
-void tcore_call_information_mo_cfc(CoreObject *o)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_CALL);
-
- po = tcore_object_ref_object(o);
-
- tcore_check_null_ret("po", po);
- tcore_check_null_ret("po->iops", po->iops);
- tcore_check_null_ret("po->iops->mo_call_cfc", po->iops->mo_call_cfc);
-
- po->iops->mo_call_cfc(o);
-}
-
-void tcore_call_information_mt_cli(CoreObject *o, enum tcore_call_cli_mode mode, char *number)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_CALL);
-
- po = tcore_object_ref_object(o);
-
- tcore_check_null_ret("po", po);
- tcore_check_null_ret("po->iops", po->iops);
- tcore_check_null_ret("po->iops->mt_call_cli", po->iops->mt_call_cli);
-
- po->iops->mt_call_cli(o, mode, number);
-}
-
-void tcore_call_information_mt_cna(CoreObject *o, enum tcore_call_cna_mode mode, char *name, int dcs)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_CALL);
-
- po = tcore_object_ref_object(o);
-
- tcore_check_null_ret("po", po);
- tcore_check_null_ret("po->iops", po->iops);
- tcore_check_null_ret("po->iops->mt_call_cna", po->iops->mt_call_cna);
-
- po->iops->mt_call_cna(o, mode, name, dcs);
-}
-
-void tcore_call_information_mt_forwarded_call(CoreObject *o, char *number)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_CALL);
-
- po = tcore_object_ref_object(o);
-
- tcore_check_null_ret("po", po);
- tcore_check_null_ret("po->iops", po->iops);
- tcore_check_null_ret("po->iops->mt_call_forwarded_call", po->iops->mt_call_forwarded_call);
-
- po->iops->mt_call_forwarded_call(o, number);
-}
-
-void tcore_call_information_mt_cug_call(CoreObject *o, int cug_index, char *number)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_CALL);
-
- po = tcore_object_ref_object(o);
-
- tcore_check_null_ret("po", po);
- tcore_check_null_ret("po->iops", po->iops);
- tcore_check_null_ret("po->iops->mt_call_cug_call", po->iops->mt_call_cug_call);
-
- po->iops->mt_call_cug_call(o, cug_index, number);
-}
-
-void tcore_call_information_mt_deflected_call(CoreObject *o, char *number)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_CALL);
-
- po = tcore_object_ref_object(o);
-
- tcore_check_null_ret("po", po);
- tcore_check_null_ret("po->iops", po->iops);
- tcore_check_null_ret("po->iops->mt_call_deflected_call", po->iops->mt_call_deflected_call);
-
- po->iops->mt_call_deflected_call(o, number);
-}
-
-void tcore_call_information_mt_transfered(CoreObject *o, char *number)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_CALL);
-
- po = tcore_object_ref_object(o);
-
- tcore_check_null_ret("po", po);
- tcore_check_null_ret("po->iops", po->iops);
- tcore_check_null_ret("po->iops->mt_call_transfered", po->iops->mt_call_transfered);
-
- po->iops->mt_call_transfered(o, number);
-}
-
-void tcore_call_information_held(CoreObject *o, char *number)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_CALL);
-
- po = tcore_object_ref_object(o);
-
- tcore_check_null_ret("po", po);
- tcore_check_null_ret("po->iops", po->iops);
- tcore_check_null_ret("po->iops->call_held", po->iops->call_held);
-
- po->iops->call_held(o, number);
-}
-
-void tcore_call_information_active(CoreObject *o, char *number)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_CALL);
-
- po = tcore_object_ref_object(o);
-
- tcore_check_null_ret("po", po);
- tcore_check_null_ret("po->iops", po->iops);
- tcore_check_null_ret("po->iops->call_active", po->iops->call_active);
-
- po->iops->call_active(o, number);
-}
-
-void tcore_call_information_joined(CoreObject *o, char *number)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_CALL);
-
- po = tcore_object_ref_object(o);
-
- tcore_check_null_ret("po", po);
- tcore_check_null_ret("po->iops", po->iops);
- tcore_check_null_ret("po->iops->call_joined", po->iops->call_joined);
-
- po->iops->call_joined(o, number);
-}
-
-void tcore_call_information_released_on_hold(CoreObject *o, char *number)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_CALL);
-
- po = tcore_object_ref_object(o);
-
- tcore_check_null_ret("po", po);
- tcore_check_null_ret("po->iops", po->iops);
- tcore_check_null_ret("po->iops->call_released_on_hold", po->iops->call_released_on_hold);
-
- po->iops->call_released_on_hold(o, number);
-}
-
-void tcore_call_information_transfer_alert(CoreObject *o, char *number)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_CALL);
-
- po = tcore_object_ref_object(o);
-
- tcore_check_null_ret("po", po);
- tcore_check_null_ret("po->iops", po->iops);
- tcore_check_null_ret("po->iops->call_transfer_alert", po->iops->call_transfer_alert);
-
- po->iops->call_transfer_alert(o, number);
-}
-
-void tcore_call_information_transfered(CoreObject *o, char *number)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_CALL);
-
- po = tcore_object_ref_object(o);
-
- tcore_check_null_ret("po", po);
- tcore_check_null_ret("po->iops", po->iops);
- tcore_check_null_ret("po->iops->call_transfered", po->iops->call_transfered);
-
- po->iops->call_transfered(o, number);
-}
-
-void tcore_call_information_cf_check_ss_message(CoreObject *o, char *number)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_CALL);
-
- po = tcore_object_ref_object(o);
-
- tcore_check_null_ret("po", po);
- tcore_check_null_ret("po->iops", po->iops);
- tcore_check_null_ret("po->iops->call_cf_check_message", po->iops->call_cf_check_message);
-
- po->iops->call_cf_check_message(o, number);
-}
-
-void tcore_call_information_set_operations(CoreObject *o, struct tcore_call_information_operations *iops)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_CALL);
-
- po = tcore_object_ref_object(o);
- if (!po)
- return;
-
- po->iops = iops;
-}
-
-CoreObject *tcore_call_new(TcorePlugin *p, const char *name, struct tcore_call_operations *ops, TcoreHal *hal)
-{
- CoreObject *o = NULL;
- struct private_object_data *po = NULL;
-
- if (!p)
- return NULL;
-
- o = tcore_object_new(p, name, hal);
- if (!o)
- return NULL;
-
- po = g_try_malloc0(sizeof(struct private_object_data));
- if (po == NULL) {
- tcore_object_free(o);
- return NULL;
- }
-
- /* set ops to default type when core object is created. */
- po->ops[TCORE_OPS_TYPE_CP] = ops;
-
- tcore_object_set_type(o, CORE_OBJECT_TYPE_CALL);
- tcore_object_link_object(o, po);
- tcore_object_set_free_hook(o, _free_hook);
- tcore_object_set_dispatcher(o, _dispatcher);
-
- return o;
-}
-
-void tcore_call_free(CoreObject *o)
-{
- CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_CALL);
- tcore_object_free(o);
-}
-
-void tcore_call_set_ops(CoreObject *o, struct tcore_call_operations *ops, enum tcore_ops_type ops_type)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_CALL);
- CORE_OBJECT_VALIDATE_OPS_RETURN(ops_type);
-
- po = (struct private_object_data *)tcore_object_ref_object(o);
- if (!po) {
- err("po is NULL");
- return;
- }
-
- /* set ops according to ops_type */
- po->ops[ops_type] = ops;
-}
+++ /dev/null
-/*
- * libtcore
- *
- * 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.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <glib.h>
-
-#include "tcore.h"
-#include "util.h"
-#include "plugin.h"
-#include "user_request.h"
-#include "co_context.h"
-
-struct private_object_data {
- enum co_context_state state;
- unsigned char id;
- enum co_context_role role;
- gboolean default_profile;
- gboolean attach_apn;
-
- char *apn;
- char *addr;
- enum co_context_type type;
- enum co_context_d_comp d_comp;
- enum co_context_h_comp h_comp;
- enum co_context_tech tech_pref;
- char *username;
- char *password;
- char *dns1;
- char *dns2;
- enum co_context_auth auth;
-
- union tcore_ip4_type ip_v4;
- union tcore_ip4_type gateway_v4;
- union tcore_ip4_type dns_primary_v4;
- union tcore_ip4_type dns_secondary_v4;
-
- /* IPv6 will be supported */
- char *ip_v6;
- char *gateway_v6;
- char *dns_primary_v6;
- char *dns_secondary_v6;
-
- pcscf_addr *pcscf_ipv4;
- pcscf_addr *pcscf_ipv6;
-
- char *proxy;
- char *mmsurl;
- char *profile_name;
- char devname[16];
-
- /* Dedicated bearer information */
- struct dedicated_bearer_info dedicated_bearer;
-};
-
-static void _free_hook(CoreObject *o)
-{
- struct private_object_data *po = NULL;
-
- po = tcore_object_ref_object(o);
- if (po) {
- free(po);
- tcore_object_link_object(o, NULL);
- }
-}
-
-CoreObject *tcore_context_new(TcorePlugin *p, const char *name, TcoreHal *hal)
-{
- CoreObject *o = NULL;
- struct private_object_data *po = NULL;
-
- if (!p)
- return NULL;
-
- o = tcore_object_new(p, name, hal);
- if (!o)
- return NULL;
-
- po = calloc(1, sizeof(struct private_object_data));
- if (!po) {
- tcore_object_free(o);
- return NULL;
- }
-
- po->type = CONTEXT_TYPE_IP;
- po->d_comp = CONTEXT_D_COMP_OFF;
- po->h_comp = CONTEXT_H_COMP_OFF;
- po->role = CONTEXT_ROLE_UNKNOWN;
- po->auth = CONTEXT_AUTH_NONE;
- po->tech_pref = CONTEXT_TECH_3GPP;
-
- tcore_object_set_type(o, CORE_OBJECT_TYPE_PS_CONTEXT);
- tcore_object_link_object(o, po);
- tcore_object_set_free_hook(o, _free_hook);
-
- return o;
-}
-
-void tcore_context_free(CoreObject *o)
-{
- CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_PS_CONTEXT);
- tcore_object_free(o);
-}
-
-TReturn tcore_context_set_state(CoreObject *o, enum co_context_state state)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, TCORE_RETURN_EINVAL);
-
- po = tcore_object_ref_object(o);
- if (!po)
- return TCORE_RETURN_EINVAL;
-
- po->state = state;
-
- return TCORE_RETURN_SUCCESS;
-}
-
-enum co_context_state tcore_context_get_state(CoreObject *o)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, 0);
-
- po = tcore_object_ref_object(o);
- if (!po)
- return 0;
-
- return po->state;
-}
-
-TReturn tcore_context_set_id(CoreObject *o, unsigned char id)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, TCORE_RETURN_EINVAL);
-
- po = tcore_object_ref_object(o);
- if (!po)
- return TCORE_RETURN_EINVAL;
-
- po->id = id;
-
- return TCORE_RETURN_SUCCESS;
-}
-
-unsigned char tcore_context_get_id(CoreObject *o)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, 0);
-
- po = tcore_object_ref_object(o);
- if (!po)
- return 0;
-
- return po->id;
-}
-
-TReturn tcore_context_set_apn(CoreObject *o, const char *apn)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, TCORE_RETURN_EINVAL);
-
- po = tcore_object_ref_object(o);
- if (!po)
- return FALSE;
-
- if (po->apn) {
- free(po->apn);
- po->apn = NULL;
- }
-
- if (apn)
- po->apn = g_strdup(apn);
-
- return TCORE_RETURN_SUCCESS;
-}
-
-char *tcore_context_get_apn(CoreObject *o)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, NULL);
-
- po = tcore_object_ref_object(o);
- if (!po)
- return NULL;
-
- if (!po->apn)
- return NULL;
-
- return g_strdup(po->apn);
-}
-
-TReturn tcore_context_set_address(CoreObject *o, const char *addr)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, TCORE_RETURN_EINVAL);
-
- po = tcore_object_ref_object(o);
- if (!po)
- return TCORE_RETURN_EINVAL;
-
- if (po->addr) {
- free(po->addr);
- po->addr = NULL;
- }
-
- if (addr)
- po->addr = g_strdup(addr);
-
- return TCORE_RETURN_SUCCESS;
-}
-
-char *tcore_context_get_address(CoreObject *o)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, NULL);
-
- po = tcore_object_ref_object(o);
- if (!po)
- return NULL;
-
- if (!po->addr)
- return NULL;
-
- return g_strdup(po->addr);
-}
-
-TReturn tcore_context_set_role(CoreObject *o, enum co_context_role role)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, TCORE_RETURN_EINVAL);
-
- po = tcore_object_ref_object(o);
- if (!po)
- return TCORE_RETURN_EINVAL;
-
- po->role = role;
-
- return TCORE_RETURN_SUCCESS;
-}
-
-enum co_context_role tcore_context_get_role(CoreObject *o)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, 0);
-
- po = tcore_object_ref_object(o);
- if (!po)
- return 0;
-
- return po->role;
-}
-
-TReturn tcore_context_set_type(CoreObject *o, enum co_context_type type)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, TCORE_RETURN_EINVAL);
-
- po = tcore_object_ref_object(o);
- if (!po)
- return TCORE_RETURN_EINVAL;
-
- po->type = type;
-
- return TCORE_RETURN_SUCCESS;
-}
-
-enum co_context_type tcore_context_get_type(CoreObject *o)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, 0);
-
- po = tcore_object_ref_object(o);
- if (!po)
- return 0;
-
- return po->type;
-}
-
-TReturn tcore_context_set_data_compression(CoreObject *o, enum co_context_d_comp comp)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, TCORE_RETURN_EINVAL);
-
- po = tcore_object_ref_object(o);
- if (!po)
- return TCORE_RETURN_EINVAL;
-
- po->d_comp = comp;
-
- return TCORE_RETURN_SUCCESS;
-}
-
-enum co_context_d_comp tcore_context_get_data_compression(CoreObject *o)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, 0);
-
- po = tcore_object_ref_object(o);
- if (!po)
- return 0;
-
- return po->d_comp;
-}
-
-TReturn tcore_context_set_header_compression(CoreObject *o, enum co_context_h_comp comp)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, TCORE_RETURN_EINVAL);
-
- po = tcore_object_ref_object(o);
- if (!po)
- return TCORE_RETURN_EINVAL;
-
- po->h_comp = comp;
-
- return TCORE_RETURN_SUCCESS;
-}
-
-enum co_context_h_comp tcore_context_get_header_compression(CoreObject *o)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, 0);
-
- po = tcore_object_ref_object(o);
- if (!po)
- return 0;
-
- return po->h_comp;
-}
-
-TReturn tcore_context_set_tech_preference(CoreObject *o, enum co_context_tech tech)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, TCORE_RETURN_EINVAL);
-
- po = tcore_object_ref_object(o);
- if (!po)
- return TCORE_RETURN_EINVAL;
-
- po->tech_pref = tech;
-
- return TCORE_RETURN_SUCCESS;
-}
-
-enum co_context_tech tcore_context_get_tech_preference(CoreObject *o)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, 0);
-
- po = tcore_object_ref_object(o);
- if (!po)
- return CONTEXT_TECH_INVALID;
-
- return po->tech_pref;
-}
-
-TReturn tcore_context_set_username(CoreObject *o, const char *username)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, TCORE_RETURN_EINVAL);
-
- po = tcore_object_ref_object(o);
- if (!po)
- return TCORE_RETURN_EINVAL;
-
- if (po->username) {
- free(po->username);
- po->username = NULL;
- }
-
- if (username)
- po->username = g_strdup(username);
-
- return TCORE_RETURN_SUCCESS;
-}
-
-char *tcore_context_get_username(CoreObject *o)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, NULL);
-
- po = tcore_object_ref_object(o);
- if (!po)
- return NULL;
-
- if (!po->username)
- return NULL;
-
- return g_strdup(po->username);
-}
-
-TReturn tcore_context_set_password(CoreObject *o, const char *password)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, TCORE_RETURN_EINVAL);
-
- po = tcore_object_ref_object(o);
- if (!po)
- return TCORE_RETURN_EINVAL;
-
- if (po->password) {
- free(po->password);
- po->password = NULL;
- }
-
- if (password)
- po->password = g_strdup(password);
-
- return TCORE_RETURN_SUCCESS;
-}
-
-char *tcore_context_get_password(CoreObject *o)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, NULL);
-
- po = tcore_object_ref_object(o);
- if (!po)
- return NULL;
-
- if (!po->password)
- return NULL;
-
- return g_strdup(po->password);
-}
-
-TReturn tcore_context_set_dns1(CoreObject *o, const char *dns)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, TCORE_RETURN_EINVAL);
-
- po = tcore_object_ref_object(o);
- if (!po)
- return TCORE_RETURN_EINVAL;
-
- if (po->dns1) {
- free(po->dns1);
- po->dns1 = NULL;
- }
-
- if (dns)
- po->dns1 = g_strdup(dns);
-
- return TCORE_RETURN_SUCCESS;
-}
-
-TReturn tcore_context_set_ipv6_dns1(CoreObject *o, const char *dns)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, TCORE_RETURN_EINVAL);
-
- po = tcore_object_ref_object(o);
- if (!po)
- return TCORE_RETURN_EINVAL;
-
- if (po->dns_primary_v6) {
- free(po->dns_primary_v6);
- po->dns_primary_v6 = NULL;
- }
-
- if (dns)
- po->dns_primary_v6 = g_strdup(dns);
-
- return TCORE_RETURN_SUCCESS;
-}
-
-char *tcore_context_get_dns1(CoreObject *o)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, NULL);
-
- po = tcore_object_ref_object(o);
- if (!po)
- return NULL;
-
- if (!po->dns1)
- return NULL;
-
- return g_strdup(po->dns1);
-}
-
-TReturn tcore_context_set_dns2(CoreObject *o, const char *dns)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, TCORE_RETURN_EINVAL);
-
- po = tcore_object_ref_object(o);
- if (!po)
- return TCORE_RETURN_EINVAL;
-
- if (po->dns2) {
- free(po->dns2);
- po->dns2 = NULL;
- }
-
- if (dns)
- po->dns2 = g_strdup(dns);
-
- return TCORE_RETURN_SUCCESS;
-}
-
-TReturn tcore_context_set_ipv6_dns2(CoreObject *o, const char *dns)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, TCORE_RETURN_EINVAL);
-
- po = tcore_object_ref_object(o);
- if (!po)
- return TCORE_RETURN_EINVAL;
-
- if (po->dns_secondary_v6) {
- free(po->dns_secondary_v6);
- po->dns_secondary_v6 = NULL;
- }
-
- if (dns)
- po->dns_secondary_v6 = g_strdup(dns);
-
- return TCORE_RETURN_SUCCESS;
-}
-
-char *tcore_context_get_dns2(CoreObject *o)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, NULL);
-
- po = tcore_object_ref_object(o);
- if (!po)
- return NULL;
-
- if (!po->dns2)
- return NULL;
-
- return g_strdup(po->dns2);
-}
-
-TReturn tcore_context_set_auth(CoreObject *o, enum co_context_auth auth)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, TCORE_RETURN_EINVAL);
-
- po = tcore_object_ref_object(o);
- if (!po)
- return TCORE_RETURN_EINVAL;
-
- po->auth = auth;
-
- return TCORE_RETURN_SUCCESS;
-}
-
-enum co_context_auth tcore_context_get_auth(CoreObject *o)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, 0);
-
- po = tcore_object_ref_object(o);
- if (!po)
- return 0;
-
- return po->auth;
-}
-
-TReturn tcore_context_set_proxy(CoreObject *o, const char *proxy)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, TCORE_RETURN_EINVAL);
-
- po = tcore_object_ref_object(o);
- if (!po)
- return FALSE;
-
- if (po->proxy) {
- free(po->proxy);
- po->apn = NULL;
- }
-
- if (proxy)
- po->proxy = g_strdup(proxy);
-
- return TCORE_RETURN_SUCCESS;
-}
-
-char *tcore_context_get_proxy(CoreObject *o)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, NULL);
-
- po = tcore_object_ref_object(o);
- if (!po)
- return NULL;
-
- if (!po->proxy)
- return NULL;
-
- return g_strdup(po->proxy);
-}
-
-TReturn tcore_context_set_mmsurl(CoreObject *o, const char *mmsurl)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, TCORE_RETURN_EINVAL);
-
- po = tcore_object_ref_object(o);
- if (!po)
- return FALSE;
-
- if (po->mmsurl) {
- free(po->mmsurl);
- po->mmsurl = NULL;
- }
-
- if (mmsurl)
- po->mmsurl = g_strdup(mmsurl);
-
- return TCORE_RETURN_SUCCESS;
-}
-
-char *tcore_context_get_mmsurl(CoreObject *o)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, NULL);
-
- po = tcore_object_ref_object(o);
- if (!po)
- return NULL;
-
- if (!po->mmsurl)
- return NULL;
-
- return g_strdup(po->mmsurl);
-}
-
-TReturn tcore_context_set_profile_name(CoreObject *o, const char *profile_name)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, TCORE_RETURN_EINVAL);
-
- po = tcore_object_ref_object(o);
- if (!po)
- return FALSE;
-
- if (po->profile_name) {
- free(po->profile_name);
- po->profile_name = NULL;
- }
-
- if (profile_name)
- po->profile_name = g_strdup(profile_name);
-
- return TCORE_RETURN_SUCCESS;
-}
-
-char *tcore_context_get_profile_name(CoreObject *o)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, NULL);
-
- po = tcore_object_ref_object(o);
- if (!po)
- return NULL;
-
- if (!po->profile_name)
- return NULL;
-
- return g_strdup(po->profile_name);
-}
-
-TReturn tcore_context_set_default_profile(CoreObject *o, gboolean default_conn)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, TCORE_RETURN_EINVAL);
-
- po = tcore_object_ref_object(o);
- if (!po)
- return TCORE_RETURN_EINVAL;
-
- po->default_profile = default_conn;
-
- return TCORE_RETURN_SUCCESS;
-}
-
-gboolean tcore_context_get_default_profile(CoreObject *o)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, FALSE);
-
- po = tcore_object_ref_object(o);
- if (!po)
- return FALSE;
-
- return po->default_profile;
-}
-
-TReturn tcore_context_set_devinfo(CoreObject *o, struct tnoti_ps_pdp_ipconfiguration *devinfo)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, TCORE_RETURN_EINVAL);
-
- po = tcore_object_ref_object(o);
-
- if (!po || !devinfo)
- return TCORE_RETURN_EINVAL;
-
- /* Free context resource if it was already allocated */
- tcore_context_reset_devinfo(o);
-
- po->ip_v6 = g_strdup((gchar *)devinfo->ipv6_address);
- po->dns_primary_v6 = g_strdup((gchar *)devinfo->ipv6_primary_dns);
- po->dns_secondary_v6 = g_strdup((gchar *)devinfo->ipv6_secondary_dns);
- po->gateway_v6 = g_strdup((gchar *)devinfo->ipv6_gateway);
- memcpy(&(po->ip_v4), devinfo->ip_address, sizeof(union tcore_ip4_type));
- memcpy(&(po->dns_primary_v4), devinfo->primary_dns, sizeof(union tcore_ip4_type));
- memcpy(&(po->dns_secondary_v4), devinfo->secondary_dns, sizeof(union tcore_ip4_type));
- memcpy(&(po->gateway_v4), devinfo->gateway, sizeof(union tcore_ip4_type));
- memcpy(po->devname, devinfo->devname, sizeof(char) * 16);
-
- po->pcscf_ipv4 = g_try_malloc0(sizeof(pcscf_addr));
- if (po->pcscf_ipv4) {
- po->pcscf_ipv4->count = devinfo->pcscf_ipv4_count;
- if (po->pcscf_ipv4->count > 0) {
- unsigned int i;
- po->pcscf_ipv4->addr = g_try_malloc0(sizeof(char *) * po->pcscf_ipv4->count);
- if ((po->pcscf_ipv4->addr) && (devinfo->pcscf_ipv4))
- for (i = 0; i < po->pcscf_ipv4->count; i++)
- po->pcscf_ipv4->addr[i] = g_strdup(devinfo->pcscf_ipv4[i]);
- }
- }
-
- po->pcscf_ipv6 = g_try_malloc0(sizeof(pcscf_addr));
- if (po->pcscf_ipv6) {
- po->pcscf_ipv6->count = devinfo->pcscf_ipv6_count;
- if (po->pcscf_ipv6->count > 0) {
- unsigned int i;
- po->pcscf_ipv6->addr = g_try_malloc0(sizeof(char *) * po->pcscf_ipv6->count);
- if ((po->pcscf_ipv6->addr) && (devinfo->pcscf_ipv6))
- for (i = 0; i < po->pcscf_ipv6->count; i++)
- po->pcscf_ipv6->addr[i] = g_strdup(devinfo->pcscf_ipv6[i]);
- }
- }
-
- return TCORE_RETURN_SUCCESS;
-}
-
-TReturn tcore_context_reset_devinfo(CoreObject *o)
-{
- struct private_object_data *po = NULL;
- unsigned int i;
-
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, TCORE_RETURN_EINVAL);
-
- po = tcore_object_ref_object(o);
- if (!po)
- return TCORE_RETURN_EINVAL;
-
- if (po->ip_v6) {
- g_free(po->ip_v6);
- po->ip_v6 = NULL;
- }
-
- if (po->dns_primary_v6) {
- g_free(po->dns_primary_v6);
- po->dns_primary_v6 = NULL;
- }
-
- if (po->dns_secondary_v6) {
- g_free(po->dns_secondary_v6);
- po->dns_secondary_v6 = NULL;
- }
-
- if (po->gateway_v6) {
- g_free(po->gateway_v6);
- po->gateway_v6 = NULL;
- }
-
- if (po->pcscf_ipv4) {
- for (i = 0; i < po->pcscf_ipv4->count; i++)
- g_free(po->pcscf_ipv4->addr[i]);
- g_free(po->pcscf_ipv4);
- po->pcscf_ipv4 = NULL;
- }
-
- if (po->pcscf_ipv6) {
- for (i = 0; i < po->pcscf_ipv6->count; i++)
- g_free(po->pcscf_ipv6->addr[i]);
- g_free(po->pcscf_ipv6);
- po->pcscf_ipv6 = NULL;
- }
-
- memset(&(po->ip_v4), 0, sizeof(union tcore_ip4_type));
- memset(&(po->dns_primary_v4), 0, sizeof(union tcore_ip4_type));
- memset(&(po->dns_secondary_v4), 0, sizeof(union tcore_ip4_type));
- memset(&(po->gateway_v4), 0, sizeof(union tcore_ip4_type));
- memset(po->devname, 0, sizeof(char) * 16);
-
- return TCORE_RETURN_SUCCESS;
-}
-
-TReturn tcore_context_set_bearer_info(CoreObject *o, struct tnoti_ps_dedicated_bearer_info *bearer_info)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, TCORE_RETURN_EINVAL);
-
- po = tcore_object_ref_object(o);
- if (!po)
- return TCORE_RETURN_EINVAL;
-
- if (!bearer_info)
- return TCORE_RETURN_EINVAL;
-
- if (bearer_info->dedicated_bearer.num_dedicated_bearer > 0)
- memcpy(&(po->dedicated_bearer), &(bearer_info->dedicated_bearer), sizeof(struct dedicated_bearer_info));
-
- return TCORE_RETURN_SUCCESS;
-}
-
-TReturn tcore_context_get_bearer_info(CoreObject *o, struct dedicated_bearer_info *bearer_info)
-{
- struct private_object_data *po = NULL;
- guchar count = 0;
-
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, TCORE_RETURN_EINVAL);
-
- po = tcore_object_ref_object(o);
- if (!po)
- return TCORE_RETURN_EINVAL;
-
- if (!bearer_info)
- return TCORE_RETURN_EINVAL;
-
- count = po->dedicated_bearer.num_dedicated_bearer;
- if (count > MAX_NUM_DEDICATED_BEARER)
- return TCORE_RETURN_EINVAL;
-
- if (count > 0) {
- bearer_info->num_dedicated_bearer = count;
- bearer_info->secondary_context_id = po->dedicated_bearer.secondary_context_id;
- memcpy(bearer_info->qos, po->dedicated_bearer.qos, count*sizeof(struct qos_parameter));
- }
-
- return TCORE_RETURN_SUCCESS;
-}
-
-TReturn tcore_context_reset_bearer_info(CoreObject *o)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, TCORE_RETURN_EINVAL);
-
- po = tcore_object_ref_object(o);
- if (!po)
- return TCORE_RETURN_EINVAL;
-
- if (po->dedicated_bearer.num_dedicated_bearer > 0)
- memset(&(po->dedicated_bearer), 0, sizeof(struct dedicated_bearer_info));
-
- return TCORE_RETURN_SUCCESS;
-}
-
-void tcore_context_cp_service_info(CoreObject *dest, CoreObject *src)
-{
- struct private_object_data *d_po = NULL;
- struct private_object_data *s_po = NULL;
-
- CORE_OBJECT_CHECK(dest, CORE_OBJECT_TYPE_PS_CONTEXT);
- CORE_OBJECT_CHECK(src, CORE_OBJECT_TYPE_PS_CONTEXT);
-
- d_po = tcore_object_ref_object(dest);
- s_po = tcore_object_ref_object(src);
-
- d_po->state = s_po->state;
- d_po->id = s_po->id;
-
- d_po->ip_v6 = g_strdup(s_po->ip_v6);
- d_po->dns_primary_v6 = g_strdup(s_po->dns_primary_v6);
- d_po->dns_secondary_v6 = g_strdup(s_po->dns_secondary_v6);
- d_po->gateway_v6 = g_strdup(s_po->gateway_v6);
-
- memcpy(&(d_po->ip_v4), &(s_po->ip_v4), sizeof(union tcore_ip4_type));
- memcpy(&(d_po->dns_primary_v4), &(s_po->dns_primary_v4), sizeof(union tcore_ip4_type));
- memcpy(&(d_po->dns_secondary_v4), &(s_po->dns_secondary_v4), sizeof(union tcore_ip4_type));
- memcpy(&(d_po->gateway_v4), &(s_po->gateway_v4), sizeof(union tcore_ip4_type));
- memcpy(d_po->devname, s_po->devname, sizeof(char) * 16);
-}
-
-char *tcore_context_get_ipv4_addr(CoreObject *o)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, NULL);
-
- po = tcore_object_ref_object(o);
- if (!po)
- return NULL;
-
- return tcore_util_get_string_by_ip4type(po->ip_v4);
-}
-
-char *tcore_context_get_ipv4_dns1(CoreObject *o)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, NULL);
-
- po = tcore_object_ref_object(o);
- if (!po)
- return NULL;
-
- return tcore_util_get_string_by_ip4type(po->dns_primary_v4);
-}
-
-char *tcore_context_get_ipv4_dns2(CoreObject *o)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, NULL);
-
- po = tcore_object_ref_object(o);
- if (!po)
- return NULL;
-
- return tcore_util_get_string_by_ip4type(po->dns_secondary_v4);
-}
-
-char *tcore_context_get_ipv4_gw(CoreObject *o)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, NULL);
-
- po = tcore_object_ref_object(o);
- if (!po)
- return NULL;
-
- return tcore_util_get_string_by_ip4type(po->gateway_v4);
-}
-
-char *tcore_context_get_ipv4_devname(CoreObject *o)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, NULL);
-
- po = tcore_object_ref_object(o);
- if (!po)
- return NULL;
-
- if (po->devname[0] == 0)
- return NULL;
-
- return g_strdup(po->devname);
-}
-
-char *tcore_context_get_ipv6_addr(CoreObject *o)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, NULL);
-
- po = tcore_object_ref_object(o);
- if (!po)
- return NULL;
-
- return g_strdup(po->ip_v6);
-}
-
-char *tcore_context_get_ipv6_dns1(CoreObject *o)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, NULL);
-
- po = tcore_object_ref_object(o);
- if (!po)
- return NULL;
-
- return g_strdup(po->dns_primary_v6);
-}
-
-char *tcore_context_get_ipv6_dns2(CoreObject *o)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, NULL);
-
- po = tcore_object_ref_object(o);
- if (!po)
- return NULL;
-
- return g_strdup(po->dns_secondary_v6);
-}
-
-char *tcore_context_get_ipv6_gw(CoreObject *o)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, NULL);
-
- po = tcore_object_ref_object(o);
- if (!po)
- return NULL;
-
- return g_strdup(po->gateway_v6);
-}
-
-pcscf_addr *tcore_context_get_pcscf_ipv4_addr(CoreObject *o)
-{
- struct private_object_data *po = NULL;
- pcscf_addr *pcscf_tmp;
-
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, NULL);
-
- po = tcore_object_ref_object(o);
- if (!po)
- return NULL;
-
- if (!po->pcscf_ipv4)
- return NULL;
-
- pcscf_tmp = g_try_malloc0(sizeof(pcscf_addr));
- if (!pcscf_tmp)
- return NULL;
-
- pcscf_tmp->count = po->pcscf_ipv4->count;
- if (pcscf_tmp->count > 0) {
- unsigned int i;
- pcscf_tmp->addr = g_try_malloc0(sizeof(char *) * po->pcscf_ipv4->count);
- if (!pcscf_tmp->addr) {
- g_free(pcscf_tmp);
- return NULL;
- }
-
- for (i = 0; i < po->pcscf_ipv4->count; i++)
- pcscf_tmp->addr[i] = g_strdup(po->pcscf_ipv4->addr[i]);
- }
-
- return pcscf_tmp;
-}
-
-pcscf_addr *tcore_context_get_pcscf_ipv6_addr(CoreObject *o)
-{
- struct private_object_data *po = NULL;
- pcscf_addr *pcscf_tmp;
-
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, NULL);
-
- po = tcore_object_ref_object(o);
- if (!po)
- return NULL;
-
- if (!po->pcscf_ipv6)
- return NULL;
-
- pcscf_tmp = g_try_malloc0(sizeof(pcscf_addr));
- if (!pcscf_tmp)
- return NULL;
-
- pcscf_tmp->count = po->pcscf_ipv6->count;
- if (pcscf_tmp->count > 0) {
- unsigned int i;
- pcscf_tmp->addr = g_try_malloc0(sizeof(char *) * po->pcscf_ipv6->count);
- if (!pcscf_tmp->addr) {
- g_free(pcscf_tmp);
- return NULL;
- }
-
- for (i = 0; i < po->pcscf_ipv6->count; i++)
- pcscf_tmp->addr[i] = g_strdup(po->pcscf_ipv6->addr[i]);
- }
-
- return pcscf_tmp;
-}
-
-TReturn tcore_context_set_attach_apn(CoreObject *o, gboolean flag)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, TCORE_RETURN_EINVAL);
-
- po = tcore_object_ref_object(o);
- if (!po)
- return TCORE_RETURN_EINVAL;
-
- po->attach_apn = flag;
-
- return TCORE_RETURN_SUCCESS;
-}
-
-gboolean tcore_context_get_attach_apn(CoreObject *o)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, FALSE);
-
- po = tcore_object_ref_object(o);
- if (!po)
- return FALSE;
-
- return po->attach_apn;
-}
+++ /dev/null
-/*
- * custom
- *
- * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: Anga Santhosh Kumar <santhosh.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 <glib.h>
-
-#include "tcore.h"
-#include "core_object.h"
-#include "co_custom.h"
-
-static void _free_hook(CoreObject *co)
-{
- CORE_OBJECT_CHECK(co, CORE_OBJECT_TYPE_CUSTOM);
-
- tcore_object_link_object(co, NULL);
-}
-
-CoreObject *tcore_custom_new(TcorePlugin *p,
- const char *name, tcore_custom_operations ops,
- CoreObjectDispatcher dispatcher, TcoreHal *hal)
-{
- CoreObject *co = NULL;
-
- if (!p)
- return NULL;
-
- co = tcore_object_new(p, name, hal);
- if (!co)
- return NULL;
-
- tcore_object_set_type(co, CORE_OBJECT_TYPE_CUSTOM);
-
- tcore_object_link_object(co, ops);
- tcore_object_set_free_hook(co, _free_hook);
- tcore_object_set_dispatcher(co, dispatcher);
-
- return co;
-}
-
-void tcore_custom_free(CoreObject *co)
-{
- CORE_OBJECT_CHECK(co, CORE_OBJECT_TYPE_CUSTOM);
-
- tcore_object_free(co);
-}
+++ /dev/null
-/*
- * libtcore
- *
- * 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.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <glib.h>
-
-#include "tcore.h"
-#include "internal/tcore_types.h"
-#include "plugin.h"
-#include "user_request.h"
-#include "co_gps.h"
-
-struct private_object_data {
- struct tcore_gps_operations *ops[TCORE_OPS_TYPE_MAX];
-};
-
-static void _free_hook(CoreObject *o)
-{
- struct private_object_data *po = NULL;
-
- po = tcore_object_ref_object(o);
- if (po) {
- g_free(po);
- tcore_object_link_object(o, NULL);
- }
-}
-
-static TReturn _dispatcher(CoreObject *o, UserRequest *ur, enum tcore_ops_type ops_type)
-{
- enum tcore_request_command command;
- struct private_object_data *po = tcore_object_ref_object(o);
- struct tcore_gps_operations *ops = NULL;
-
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_GPS, TCORE_RETURN_EINVAL);
- CORE_OBJECT_VALIDATE_OPS_RETURN_VAL(ops_type, TCORE_RETURN_EINVAL);
-
- tcore_check_null_ret_err("po", po, TCORE_RETURN_EINVAL);
- tcore_check_null_ret_err("ur", ur, TCORE_RETURN_EINVAL);
-
- ops = po->ops[ops_type];
- tcore_check_null_ret_err("ops", ops, TCORE_RETURN_FAILURE);
-
- command = tcore_user_request_get_command(ur);
- switch (command) {
- case TREQ_GPS_CONFIRM_MEASURE_POS:
- dbg("TREQ_GPS_CONFIRM_MEASURE_POS");
- tcore_check_null_ret_err("ops->confirm_measure_pos",
- ops->confirm_measure_pos, TCORE_RETURN_ENOSYS);
-
- return ops->confirm_measure_pos(o, ur);
-
- case TREQ_GPS_SET_FREQUENCY_AIDING:
- dbg("TREQ_GPS_SET_FREQUENCY_AIDING");
- tcore_check_null_ret_err("ops->set_frequency_aiding",
- ops->set_frequency_aiding, TCORE_RETURN_ENOSYS);
-
- return ops->set_frequency_aiding(o, ur);
-
- case TREQ_ENABLE_SMART_ASSISTANT:
- dbg("TREQ_ENABLE_SMART_ASSISTANT");
- tcore_check_null_ret_err("ops->enable_smart_assistant",
- ops->enable_smart_assistant, TCORE_RETURN_ENOSYS);
-
- return ops->enable_smart_assistant(o, ur);
-
- case TREQ_DISABLE_SMART_ASSISTANT:
- dbg("TREQ_DISABLE_SMART_ASSISTANT");
- tcore_check_null_ret_err("ops->disable_smart_assistant",
- ops->disable_smart_assistant, TCORE_RETURN_ENOSYS);
-
- return ops->disable_smart_assistant(o, ur);
-
- case TREQ_SYNC_SMART_ASSISTANT_AREA_LIST:
- dbg("TREQ_SYNC_SMART_ASSISTANT_AREA_LIST");
- tcore_check_null_ret_err("ops->sync_smart_assistant_area_list",
- ops->sync_smart_assistant_area_list, TCORE_RETURN_ENOSYS);
-
- return ops->sync_smart_assistant_area_list(o, ur);
-
- case TREQ_DEL_SMART_ASSISTANT_AREA_LIST:
- dbg("TREQ_DEL_SMART_ASSISTANT_AREA_LIST");
- tcore_check_null_ret_err("ops->del_smart_assistant_area_list",
- ops->del_smart_assistant_area_list, TCORE_RETURN_ENOSYS);
-
- return ops->del_smart_assistant_area_list(o, ur);
-
- case TREQ_ADD_SMART_ASSISTANT_AREA:
- dbg("TREQ_ADD_SMART_ASSISTANT_AREA");
- tcore_check_null_ret_err("ops->add_smart_assistant_area",
- ops->add_smart_assistant_area, TCORE_RETURN_ENOSYS);
-
- return ops->add_smart_assistant_area(o, ur);
-
- case TREQ_MODIFY_SMART_ASSISTANT_AREA:
- dbg("TREQ_MODIFY_SMART_ASSISTANT_AREA");
- tcore_check_null_ret_err("ops->modify_smart_assistant_area",
- ops->modify_smart_assistant_area, TCORE_RETURN_ENOSYS);
-
- return ops->modify_smart_assistant_area(o, ur);
-
- case TREQ_SET_SMART_ASSISTANT_INFO:
- dbg("TREQ_SET_SMART_ASSISTANT_INFO");
- tcore_check_null_ret_err("ops->set_smart_assistant_info",
- ops->set_smart_assistant_info, TCORE_RETURN_ENOSYS);
-
- return ops->set_smart_assistant_info(o, ur);
-
- default:
- dbg("not supported cmd");
- break;
- }
-
- return TCORE_RETURN_SUCCESS;
-}
-
-CoreObject *tcore_gps_new(TcorePlugin *p, const char *name,
- struct tcore_gps_operations *ops, TcoreHal *hal)
-{
- CoreObject *o = NULL;
- struct private_object_data *po = NULL;
-
- if (!p)
- return NULL;
-
- o = tcore_object_new(p, name, hal);
- if (!o)
- return NULL;
-
- po = g_try_malloc0(sizeof(struct private_object_data));
- if (!po) {
- tcore_object_free(o);
- return NULL;
- }
-
- /* set ops to default type when core object is created. */
- po->ops[TCORE_OPS_TYPE_CP] = ops;
-
- tcore_object_set_type(o, CORE_OBJECT_TYPE_GPS);
- tcore_object_link_object(o, po);
- tcore_object_set_dispatcher(o, _dispatcher);
- tcore_object_set_free_hook(o, _free_hook);
-
- return o;
-}
-
-void tcore_gps_free(CoreObject *o)
-{
- CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_GPS);
-
- tcore_object_free(o);
-}
-
-void tcore_gps_set_ops(CoreObject *o,
- struct tcore_gps_operations *ops, enum tcore_ops_type ops_type)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_GPS);
- CORE_OBJECT_VALIDATE_OPS_RETURN(ops_type);
-
- po = (struct private_object_data *)tcore_object_ref_object(o);
- if (!po) {
- err("po is NULL");
- return;
- }
-
- /* set ops according to ops_type */
- po->ops[ops_type] = ops;
-}
+++ /dev/null
-/*
- * libtcore
- *
- * 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.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <glib.h>
-
-#include "tcore.h"
-#include "internal/tcore_types.h"
-#include "plugin.h"
-#include "user_request.h"
-#include "co_modem.h"
-#include "hal.h"
-
-struct private_object_data {
- struct tcore_modem_operations *ops[TCORE_OPS_TYPE_MAX];
-
- gboolean flight_mode;
- gboolean powered;
-};
-
-static void _free_hook(CoreObject *o)
-{
- struct private_object_data *po = NULL;
-
- po = tcore_object_ref_object(o);
- if (po) {
- free(po);
- tcore_object_link_object(o, NULL);
- }
-}
-
-static TReturn _dispatcher(CoreObject *o, UserRequest *ur, enum tcore_ops_type ops_type)
-{
- enum tcore_request_command command;
- struct private_object_data *po = tcore_object_ref_object(o);
- struct tcore_modem_operations *ops = NULL;
-
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_MODEM, TCORE_RETURN_EINVAL);
- CORE_OBJECT_VALIDATE_OPS_RETURN_VAL(ops_type, TCORE_RETURN_EINVAL);
-
- tcore_check_null_ret_err("po", po, TCORE_RETURN_EINVAL);
- tcore_check_null_ret_err("ur", ur, TCORE_RETURN_EINVAL);
-
- ops = po->ops[ops_type];
- tcore_check_null_ret_err("ops", ops, TCORE_RETURN_FAILURE);
-
- command = tcore_user_request_get_command(ur);
- switch (command) {
- case TREQ_MODEM_POWER_ON:
- tcore_check_null_ret_err("ops->power_on",
- ops->power_on, TCORE_RETURN_ENOSYS);
-
- return ops->power_on(o, ur);
-
- case TREQ_MODEM_POWER_OFF:
- tcore_check_null_ret_err("ops->power_off",
- ops->power_off, TCORE_RETURN_ENOSYS);
-
- return ops->power_off(o, ur);
-
- case TREQ_MODEM_POWER_RESET:
- tcore_check_null_ret_err("ops->power_reset",
- ops->power_reset, TCORE_RETURN_ENOSYS);
-
- return ops->power_reset(o, ur);
-
- case TREQ_MODEM_POWER_LOW:
- tcore_check_null_ret_err("ops->power_low",
- ops->power_low, TCORE_RETURN_ENOSYS);
-
- return ops->power_low(o, ur);
-
- case TREQ_MODEM_SET_FLIGHTMODE:
- tcore_check_null_ret_err("ops->set_flight_mode",
- ops->set_flight_mode, TCORE_RETURN_ENOSYS);
-
- return ops->set_flight_mode(o, ur);
-
- case TREQ_MODEM_GET_IMEI:
- tcore_check_null_ret_err("ops->get_imei",
- ops->get_imei, TCORE_RETURN_ENOSYS);
-
- return ops->get_imei(o, ur);
-
- case TREQ_MODEM_GET_VERSION:
- tcore_check_null_ret_err("ops->get_version",
- ops->get_version, TCORE_RETURN_ENOSYS);
-
- return ops->get_version(o, ur);
-
- case TREQ_MODEM_GET_SN:
- tcore_check_null_ret_err("ops->get_sn",
- ops->get_sn, TCORE_RETURN_ENOSYS);
-
- return ops->get_sn(o, ur);
-
- case TREQ_MODEM_SET_DUN_PIN_CONTROL:
- tcore_check_null_ret_err("ops->dun_pin_ctrl",
- ops->dun_pin_ctrl, TCORE_RETURN_ENOSYS);
-
- return ops->dun_pin_ctrl(o, ur);
-
- case TREQ_MODEM_GET_FLIGHTMODE:
- tcore_check_null_ret_err("ops->get_flight_mode",
- ops->get_flight_mode, TCORE_RETURN_ENOSYS);
-
- return ops->get_flight_mode(o, ur);
-
- case TREQ_MODEM_GET_DEVICE_INFO:
- tcore_check_null_ret_err("ops->get_device_info",
- ops->get_device_info, TCORE_RETURN_ENOSYS);
-
- return ops->get_device_info(o, ur);
-
- default:
- return TCORE_RETURN_EINVAL;
- }
-
- return TCORE_RETURN_SUCCESS;
-}
-
-CoreObject *tcore_modem_new(TcorePlugin *p, const char *name,
- struct tcore_modem_operations *ops, TcoreHal *hal)
-{
- CoreObject *o = NULL;
- struct private_object_data *po = NULL;
-
- if (!p)
- return NULL;
-
- o = tcore_object_new(p, name, hal);
- if (!o)
- return NULL;
-
- po = calloc(1, sizeof(struct private_object_data));
- if (!po) {
- tcore_object_free(o);
- return NULL;
- }
-
- /* set ops to default type when core object is created. */
- po->ops[TCORE_OPS_TYPE_CP] = ops;
-
- tcore_object_set_type(o, CORE_OBJECT_TYPE_MODEM);
- tcore_object_link_object(o, po);
- tcore_object_set_free_hook(o, _free_hook);
- tcore_object_set_dispatcher(o, _dispatcher);
-
- return o;
-}
-
-void tcore_modem_free(CoreObject *o)
-{
- CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_MODEM);
- tcore_object_free(o);
-}
-
-void tcore_modem_set_ops(CoreObject *o, struct tcore_modem_operations *ops, enum tcore_ops_type ops_type)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_MODEM);
- CORE_OBJECT_VALIDATE_OPS_RETURN(ops_type);
-
- po = (struct private_object_data *)tcore_object_ref_object(o);
- if (!po) {
- err("po is NULL");
- return;
- }
-
- po->ops[ops_type] = ops;
-}
-
-TReturn tcore_modem_set_flight_mode_state(CoreObject *o, gboolean flag)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_MODEM, TCORE_RETURN_EINVAL);
-
- po = tcore_object_ref_object(o);
- if (!po)
- return TCORE_RETURN_EINVAL;
-
- po->flight_mode = flag;
-
- return TCORE_RETURN_SUCCESS;
-}
-
-gboolean tcore_modem_get_flight_mode_state(CoreObject *o)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_MODEM, FALSE);
-
- po = tcore_object_ref_object(o);
- if (!po)
- return FALSE;
-
- return po->flight_mode;
-}
-
-TReturn tcore_modem_set_powered(CoreObject *o, gboolean pwr)
-{
- TcoreHal *h;
-
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_MODEM, TCORE_RETURN_EINVAL);
-
- h = tcore_object_get_hal(o);
- if (!h)
- return TCORE_RETURN_FAILURE;
-
- tcore_hal_set_power_state(h, pwr);
-
- return TCORE_RETURN_SUCCESS;
-}
-
-gboolean tcore_modem_get_powered(CoreObject *o)
-{
- TcoreHal *h;
-
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_MODEM, FALSE);
-
- h = tcore_object_get_hal(o);
- if (!h)
- return FALSE;
-
- return tcore_hal_get_power_state(h);
-}
+++ /dev/null
-/*
- * libtcore
- *
- * 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.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <glib.h>
-
-#include "tcore.h"
-#include "internal/tcore_types.h"
-#include "plugin.h"
-#include "queue.h"
-#include "server.h"
-#include "user_request.h"
-#include "co_network.h"
-#include "storage.h"
-
-struct private_object_data {
- struct tcore_network_operations *ops[TCORE_OPS_TYPE_MAX];
-
- enum telephony_network_service_type service_type;
- enum telephony_network_access_technology act;
- enum telephony_network_service_domain_status cs_domain_status;
- enum telephony_network_service_domain_status ps_domain_status;
- char *plmn;
- gboolean roaming_state;
- int restricted_state;
- unsigned int lac;
- unsigned int rac;
- unsigned int cell_id;
- gboolean gsm_dtm_support; /* DTM (Dual Transfer Mode) */
-
- char *network_name_short;
- char *network_name_full;
- char *network_name_spn;
- enum tcore_network_name_priority network_name_priority;
- GHashTable *operator_info_hash;
- struct tel_network_ims_registration_info ims_reg_info; /* IMS specific */
- gboolean ims_voice_status;
- enum telephony_network_ecc_rat_search_status rat_search_status;
- enum telephony_network_access_technology ecc_rat;
-};
-
-static TReturn _dispatcher(CoreObject *co, UserRequest *ur, enum tcore_ops_type ops_type)
-{
- enum tcore_request_command command;
- struct private_object_data *po = tcore_object_ref_object(co);
- struct tcore_network_operations *ops = NULL;
-
- CORE_OBJECT_CHECK_RETURN(co, CORE_OBJECT_TYPE_NETWORK, TCORE_RETURN_EINVAL);
- CORE_OBJECT_VALIDATE_OPS_RETURN_VAL(ops_type, TCORE_RETURN_EINVAL);
-
- tcore_check_null_ret_err("po", po, TCORE_RETURN_EINVAL);
- tcore_check_null_ret_err("ur", ur, TCORE_RETURN_EINVAL);
-
- ops = po->ops[ops_type];
- tcore_check_null_ret_err("ops", ops, TCORE_RETURN_FAILURE);
-
- command = tcore_user_request_get_command(ur);
- switch (command) {
- case TREQ_NETWORK_SEARCH:
- tcore_check_null_ret_err("ops->search",
- ops->search, TCORE_RETURN_ENOSYS);
-
- return ops->search(co, ur);
-
- case TREQ_NETWORK_SET_PLMN_SELECTION_MODE:
- tcore_check_null_ret_err("ops->set_plmn_selection_mode",
- ops->set_plmn_selection_mode, TCORE_RETURN_ENOSYS);
-
- return ops->set_plmn_selection_mode(co, ur);
-
- case TREQ_NETWORK_GET_PLMN_SELECTION_MODE:
- tcore_check_null_ret_err("ops->get_plmn_selection_mode",
- ops->get_plmn_selection_mode, TCORE_RETURN_ENOSYS);
-
- return ops->get_plmn_selection_mode(co, ur);
-
- case TREQ_NETWORK_SET_SERVICE_DOMAIN:
- tcore_check_null_ret_err("ops->set_service_domain",
- ops->set_service_domain, TCORE_RETURN_ENOSYS);
-
- return ops->set_service_domain(co, ur);
-
- case TREQ_NETWORK_GET_SERVICE_DOMAIN:
- tcore_check_null_ret_err("ops->get_service_domain",
- ops->get_service_domain, TCORE_RETURN_ENOSYS);
-
- return ops->get_service_domain(co, ur);
-
- case TREQ_NETWORK_SET_BAND:
- tcore_check_null_ret_err("ops->set_band",
- ops->set_band, TCORE_RETURN_ENOSYS);
-
- return ops->set_band(co, ur);
-
- case TREQ_NETWORK_GET_BAND:
- tcore_check_null_ret_err("ops->get_band",
- ops->get_band, TCORE_RETURN_ENOSYS);
-
- return ops->get_band(co, ur);
-
- case TREQ_NETWORK_SET_PREFERRED_PLMN:
- tcore_check_null_ret_err("ops->set_preferred_plmn",
- ops->set_preferred_plmn, TCORE_RETURN_ENOSYS);
-
- return ops->set_preferred_plmn(co, ur);
-
- case TREQ_NETWORK_GET_PREFERRED_PLMN:
- tcore_check_null_ret_err("ops->get_preferred_plmn",
- ops->get_preferred_plmn, TCORE_RETURN_ENOSYS);
-
- return ops->get_preferred_plmn(co, ur);
-
- case TREQ_NETWORK_SET_ORDER:
- tcore_check_null_ret_err("ops->set_order",
- ops->set_order, TCORE_RETURN_ENOSYS);
-
- return ops->set_order(co, ur);
-
- case TREQ_NETWORK_GET_ORDER:
- tcore_check_null_ret_err("ops->get_order",
- ops->get_order, TCORE_RETURN_ENOSYS);
-
- return ops->get_order(co, ur);
-
- case TREQ_NETWORK_SET_POWER_ON_ATTACH:
- tcore_check_null_ret_err("ops->set_power_on_attach",
- ops->set_power_on_attach, TCORE_RETURN_ENOSYS);
-
- return ops->set_power_on_attach(co, ur);
-
- case TREQ_NETWORK_GET_POWER_ON_ATTACH:
- tcore_check_null_ret_err("ops->get_power_on_attach",
- ops->get_power_on_attach, TCORE_RETURN_ENOSYS);
-
- return ops->get_power_on_attach(co, ur);
-
- case TREQ_NETWORK_SET_CANCEL_MANUAL_SEARCH:
- tcore_check_null_ret_err("ops->set_cancel_manual_search",
- ops->set_cancel_manual_search, TCORE_RETURN_ENOSYS);
-
- return ops->set_cancel_manual_search(co, ur);
-
- case TREQ_NETWORK_GET_SERVING_NETWORK:
- tcore_check_null_ret_err("ops->get_serving_network",
- ops->get_serving_network, TCORE_RETURN_ENOSYS);
-
- return ops->get_serving_network(co, ur);
-
- case TREQ_NETWORK_SET_MODE:
- tcore_check_null_ret_err("ops->set_mode",
- ops->set_mode, TCORE_RETURN_ENOSYS);
-
- return ops->set_mode(co, ur);
-
- case TREQ_NETWORK_GET_MODE:
- tcore_check_null_ret_err("ops->get_mode",
- ops->get_mode, TCORE_RETURN_ENOSYS);
-
- return ops->get_mode(co, ur);
-
- case TREQ_NETWORK_SET_NEIGHBORING_CELL_INFO:
- tcore_check_null_ret_err("ops->set_neighboring_cell_info",
- ops->set_neighboring_cell_info, TCORE_RETURN_ENOSYS);
-
- return ops->set_neighboring_cell_info(co, ur);
-
- case TREQ_NETWORK_GET_NEIGHBORING_CELL_INFO:
- tcore_check_null_ret_err("ops->get_neighboring_cell_info",
- ops->get_neighboring_cell_info, TCORE_RETURN_ENOSYS);
-
- return ops->get_neighboring_cell_info(co, ur);
-
- case TREQ_NETWORK_SET_DEFAULT_DATA_SUBSCRIPTION:
- tcore_check_null_ret_err("ops->set_default_data_subscription",
- ops->set_default_data_subscription, TCORE_RETURN_ENOSYS);
-
- return ops->set_default_data_subscription(co, ur);
-
- case TREQ_NETWORK_GET_DEFAULT_DATA_SUBSCRIPTION:
- tcore_check_null_ret_err("ops->get_default_data_subscription",
- ops->get_default_data_subscription, TCORE_RETURN_ENOSYS);
-
- return ops->get_default_data_subscription(co, ur);
-
- case TREQ_NETWORK_SET_DEFAULT_SUBSCRIPTION:
- tcore_check_null_ret_err("ops->set_default_subscription",
- ops->set_default_subscription, TCORE_RETURN_ENOSYS);
-
- return ops->set_default_subscription(co, ur);
-
- case TREQ_NETWORK_GET_DEFAULT_SUBSCRIPTION:
- tcore_check_null_ret_err("ops->get_default_subscription",
- ops->get_default_subscription, TCORE_RETURN_ENOSYS);
-
- return ops->get_default_subscription(co, ur);
-
- case TREQ_NETWORK_SET_EMERGENCY_CALLBACK_MODE:
- tcore_check_null_ret_err("ops->set_emergency_callback_mode",
- ops->set_emergency_callback_mode, TCORE_RETURN_ENOSYS);
-
- return ops->set_emergency_callback_mode(co, ur);
-
- case TREQ_NETWORK_SET_ROAMING_PREFERENCE:
- tcore_check_null_ret_err("ops->set_roaming_preference",
- ops->set_roaming_preference, TCORE_RETURN_ENOSYS);
-
- return ops->set_roaming_preference(co, ur);
-
- case TREQ_NETWORK_GET_ROAMING_PREFERENCE:
- tcore_check_null_ret_err("ops->get_roaming_preference",
- ops->get_roaming_preference, TCORE_RETURN_ENOSYS);
-
- return ops->get_roaming_preference(co, ur);
-
- case TREQ_NETWORK_GET_SUBSCRIPTION_INFO:
- tcore_check_null_ret_err("ops->get_subscription_info",
- ops->get_subscription_info, TCORE_RETURN_ENOSYS);
-
- return ops->get_subscription_info(co, ur);
-
- case TREQ_NETWORK_SEARCH_ECC_RAT:
- tcore_check_null_ret_err("ops->search_ecc_rat",
- ops->search_ecc_rat, TCORE_RETURN_ENOSYS);
-
- return ops->search_ecc_rat(co, ur);
-
- default:
- break;
- }
-
- return TCORE_RETURN_SUCCESS;
-}
-
-static void _free_hook(CoreObject *co)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK(co, CORE_OBJECT_TYPE_NETWORK);
-
- po = tcore_object_ref_object(co);
- if (po) {
- g_free(po);
- tcore_object_link_object(co, NULL);
- }
-}
-
-CoreObject *tcore_network_new(TcorePlugin *plugin, const char *name,
- struct tcore_network_operations *ops, TcoreHal *hal)
-{
- CoreObject *o = NULL;
- struct private_object_data *po = NULL;
-
- if (!plugin)
- return NULL;
-
- o = tcore_object_new(plugin, name, hal);
- if (!o)
- return NULL;
-
- po = g_try_malloc0(sizeof(struct private_object_data));
- if (!po) {
- tcore_object_free(o);
- return NULL;
- }
-
- /* set ops to default type when core object is created. */
- po->ops[TCORE_OPS_TYPE_CP] = ops;
-
- po->operator_info_hash = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
-
- tcore_object_set_type(o, CORE_OBJECT_TYPE_NETWORK);
- tcore_object_link_object(o, po);
- tcore_object_set_free_hook(o, _free_hook);
- tcore_object_set_dispatcher(o, _dispatcher);
-
- return o;
-}
-
-void tcore_network_free(CoreObject *co)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK(co, CORE_OBJECT_TYPE_NETWORK);
-
- po = tcore_object_ref_object(co);
- if (!po)
- return;
-
- if (po->network_name_short)
- free(po->network_name_short);
-
- if (po->network_name_full)
- free(po->network_name_full);
-
- if (po->network_name_spn)
- free(po->network_name_spn);
-
- if (po->plmn)
- free(po->plmn);
-
- if (po->operator_info_hash)
- g_hash_table_destroy(po->operator_info_hash);
-
- tcore_object_free(co);
-}
-
-void tcore_network_set_ops(CoreObject *o,
- struct tcore_network_operations *ops, enum tcore_ops_type ops_type)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_NETWORK);
- CORE_OBJECT_VALIDATE_OPS_RETURN(ops_type);
-
- po = (struct private_object_data *)tcore_object_ref_object(o);
- if (!po) {
- err("po is NULL");
- return;
- }
-
- po->ops[ops_type] = ops;
-}
-
-char *tcore_network_get_plmn(CoreObject *co)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(co, CORE_OBJECT_TYPE_NETWORK, NULL);
-
- po = tcore_object_ref_object(co);
- if (!po)
- return NULL;
-
- return g_strdup(po->plmn);
-}
-
-TReturn tcore_network_set_plmn(CoreObject *co, const char *plmn)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(co, CORE_OBJECT_TYPE_NETWORK, TCORE_RETURN_EINVAL);
-
- po = tcore_object_ref_object(co);
- if (!po)
- return TCORE_RETURN_EINVAL;
-
- if (po->plmn)
- free(po->plmn);
-
- po->plmn = g_strdup(plmn);
-
- return TCORE_RETURN_SUCCESS;
-}
-
-
-char *tcore_network_get_network_name(CoreObject *co,
- enum tcore_network_name_type type)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(co, CORE_OBJECT_TYPE_NETWORK, NULL);
-
- po = tcore_object_ref_object(co);
- if (!po)
- return NULL;
-
- if (type == TCORE_NETWORK_NAME_TYPE_SHORT)
- return g_strdup(po->network_name_short);
- else if (type == TCORE_NETWORK_NAME_TYPE_FULL)
- return g_strdup(po->network_name_full);
- else if (type == TCORE_NETWORK_NAME_TYPE_SPN)
- return g_strdup(po->network_name_spn);
- else
- return NULL;
-}
-
-TReturn tcore_network_set_network_name(CoreObject *co,
- enum tcore_network_name_type type, const char *network_name)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(co, CORE_OBJECT_TYPE_NETWORK, TCORE_RETURN_EINVAL);
-
- po = tcore_object_ref_object(co);
- if (!po)
- return TCORE_RETURN_EINVAL;
-
- switch (type) {
- case TCORE_NETWORK_NAME_TYPE_SHORT:
- if (po->network_name_short) {
- free(po->network_name_short);
- po->network_name_short = NULL;
- }
-
- if (network_name)
- po->network_name_short = g_strdup(network_name);
-
- break;
-
- case TCORE_NETWORK_NAME_TYPE_FULL:
- if (po->network_name_full) {
- free(po->network_name_full);
- po->network_name_full = NULL;
- }
-
- if (network_name)
- po->network_name_full = g_strdup(network_name);
-
- break;
-
- case TCORE_NETWORK_NAME_TYPE_SPN:
- if (po->network_name_spn) {
- free(po->network_name_spn);
- po->network_name_spn = NULL;
- }
-
- if (network_name)
- po->network_name_spn = g_strdup(network_name);
-
- break;
-
- default:
- return TCORE_RETURN_EINVAL;
- }
-
- return TCORE_RETURN_SUCCESS;
-}
-
-TReturn tcore_network_get_network_name_priority(CoreObject *co,
- enum tcore_network_name_priority *priority)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(co, CORE_OBJECT_TYPE_NETWORK, TCORE_RETURN_EINVAL);
-
- if (!priority)
- return TCORE_RETURN_EINVAL;
-
- po = tcore_object_ref_object(co);
- if (!po)
- return FALSE;
-
- *priority = po->network_name_priority;
-
- return TCORE_RETURN_SUCCESS;
-}
-
-TReturn tcore_network_set_network_name_priority(CoreObject *co,
- enum tcore_network_name_priority priority)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(co, CORE_OBJECT_TYPE_NETWORK, TCORE_RETURN_EINVAL);
-
- po = tcore_object_ref_object(co);
- if (!po)
- return TCORE_RETURN_EINVAL;
-
- po->network_name_priority = priority;
-
- return TCORE_RETURN_SUCCESS;
-}
-
-gboolean tcore_network_get_roaming_state(CoreObject *co)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(co, CORE_OBJECT_TYPE_NETWORK, FALSE);
-
- po = tcore_object_ref_object(co);
- if (!po)
- return FALSE;
-
- return po->roaming_state;
-}
-
-TReturn tcore_network_set_roaming_state(CoreObject *co, gboolean state)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(co, CORE_OBJECT_TYPE_NETWORK, TCORE_RETURN_EINVAL);
-
- po = tcore_object_ref_object(co);
- if (!po)
- return TCORE_RETURN_EINVAL;
-
- po->roaming_state = state;
- dbg("roaming_state = 0x%x", state);
-
- return TCORE_RETURN_SUCCESS;
-}
-
-int tcore_network_get_restricted_state(CoreObject *co)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(co, CORE_OBJECT_TYPE_NETWORK, FALSE);
-
- po = tcore_object_ref_object(co);
- if (!po)
- return FALSE;
-
- return po->restricted_state;
-}
-
-TReturn tcore_network_set_restricted_state(CoreObject *co, int state)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(co, CORE_OBJECT_TYPE_NETWORK, TCORE_RETURN_EINVAL);
-
- po = tcore_object_ref_object(co);
- if (!po)
- return TCORE_RETURN_EINVAL;
-
- po->restricted_state = state;
- dbg("restricted_state = 0x%x", state);
-
- return TCORE_RETURN_SUCCESS;
-}
-
-TReturn tcore_network_get_service_status(CoreObject *co,
- enum tcore_network_service_domain_type type,
- enum telephony_network_service_domain_status *result)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(co, CORE_OBJECT_TYPE_NETWORK, TCORE_RETURN_EINVAL);
-
- if (!result)
- return TCORE_RETURN_EINVAL;
-
- po = tcore_object_ref_object(co);
- if (!po)
- return TCORE_RETURN_EINVAL;
-
- switch (type) {
- case TCORE_NETWORK_SERVICE_DOMAIN_TYPE_CIRCUIT:
- *result = po->cs_domain_status;
- break;
-
- case TCORE_NETWORK_SERVICE_DOMAIN_TYPE_PACKET:
- *result = po->ps_domain_status;
- break;
-
- default:
- err("invalid network type");
- break;
- }
-
- return TCORE_RETURN_SUCCESS;
-}
-
-TReturn tcore_network_set_service_status(CoreObject *co,
- enum tcore_network_service_domain_type type,
- enum telephony_network_service_domain_status status)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(co, CORE_OBJECT_TYPE_NETWORK, TCORE_RETURN_EINVAL);
-
- po = tcore_object_ref_object(co);
- if (!po)
- return TCORE_RETURN_EINVAL;
-
- switch (type) {
- case TCORE_NETWORK_SERVICE_DOMAIN_TYPE_CIRCUIT:
- po->cs_domain_status = status;
- dbg("cs.status = 0x%x", status);
- break;
-
- case TCORE_NETWORK_SERVICE_DOMAIN_TYPE_PACKET:
- po->ps_domain_status = status;
- dbg("ps.status = 0x%x", status);
- break;
-
- default:
- err("invalid network type");
- break;
- }
-
- return TCORE_RETURN_SUCCESS;
-}
-
-TReturn tcore_network_set_access_technology(CoreObject *co,
- enum telephony_network_access_technology act)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(co, CORE_OBJECT_TYPE_NETWORK, TCORE_RETURN_EINVAL);
-
- po = tcore_object_ref_object(co);
- if (!po)
- return TCORE_RETURN_EINVAL;
-
- po->act = act;
-
- return TCORE_RETURN_SUCCESS;
-}
-
-TReturn tcore_network_get_access_technology(CoreObject *co,
- enum telephony_network_access_technology *result)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(co, CORE_OBJECT_TYPE_NETWORK, TCORE_RETURN_EINVAL);
-
- if (!result)
- return TCORE_RETURN_EINVAL;
-
- po = tcore_object_ref_object(co);
- if (!po)
- return TCORE_RETURN_EINVAL;
-
- *result = po->act;
-
- return TCORE_RETURN_SUCCESS;
-}
-
-TReturn tcore_network_set_lac(CoreObject *co, unsigned int lac)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(co, CORE_OBJECT_TYPE_NETWORK, TCORE_RETURN_EINVAL);
-
- po = tcore_object_ref_object(co);
- if (!po)
- return TCORE_RETURN_EINVAL;
-
- po->lac = lac;
-
- return TCORE_RETURN_SUCCESS;
-}
-
-TReturn tcore_network_get_lac(CoreObject *co, unsigned int *result)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(co, CORE_OBJECT_TYPE_NETWORK, TCORE_RETURN_EINVAL);
-
- if (!result)
- return TCORE_RETURN_EINVAL;
-
- po = tcore_object_ref_object(co);
- if (!po)
- return TCORE_RETURN_EINVAL;
-
- *result = po->lac;
-
- return TCORE_RETURN_SUCCESS;
-}
-
-TReturn tcore_network_set_rac(CoreObject *co, unsigned int rac)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(co, CORE_OBJECT_TYPE_NETWORK, TCORE_RETURN_EINVAL);
-
- po = tcore_object_ref_object(co);
- if (!po)
- return TCORE_RETURN_EINVAL;
-
- po->rac = rac;
-
- return TCORE_RETURN_SUCCESS;
-}
-
-TReturn tcore_network_get_rac(CoreObject *co, unsigned int *result)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(co, CORE_OBJECT_TYPE_NETWORK, TCORE_RETURN_EINVAL);
-
- if (!result)
- return TCORE_RETURN_EINVAL;
-
- po = tcore_object_ref_object(co);
- if (!po)
- return TCORE_RETURN_EINVAL;
-
- *result = po->rac;
-
- return TCORE_RETURN_SUCCESS;
-}
-
-TReturn tcore_network_set_cell_id(CoreObject *co, unsigned int cell_id)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(co, CORE_OBJECT_TYPE_NETWORK, TCORE_RETURN_EINVAL);
-
- po = tcore_object_ref_object(co);
- if (!po)
- return TCORE_RETURN_EINVAL;
-
- po->cell_id = cell_id;
-
- return TCORE_RETURN_SUCCESS;
-}
-
-TReturn tcore_network_get_cell_id(CoreObject *co, unsigned int *result)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(co, CORE_OBJECT_TYPE_NETWORK, TCORE_RETURN_EINVAL);
-
- if (!result)
- return TCORE_RETURN_EINVAL;
-
- po = tcore_object_ref_object(co);
- if (!po)
- return TCORE_RETURN_EINVAL;
-
- *result = po->cell_id;
-
- return TCORE_RETURN_SUCCESS;
-}
-
-gboolean tcore_network_get_gsm_dtm_support(CoreObject *co)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(co, CORE_OBJECT_TYPE_NETWORK, FALSE);
-
- po = tcore_object_ref_object(co);
- if (!po)
- return FALSE;
-
- return po->gsm_dtm_support;
-}
-
-TReturn tcore_network_set_gsm_dtm_support(CoreObject *co, gboolean state)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(co, CORE_OBJECT_TYPE_NETWORK, TCORE_RETURN_EINVAL);
-
- po = tcore_object_ref_object(co);
- if (!po)
- return TCORE_RETURN_EINVAL;
-
- po->gsm_dtm_support = state;
- dbg("gsm_dtm_support = %d", state);
-
- return TCORE_RETURN_SUCCESS;
-}
-
-TReturn tcore_network_set_service_type(CoreObject *co,
- enum telephony_network_service_type service_type)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(co, CORE_OBJECT_TYPE_NETWORK, TCORE_RETURN_EINVAL);
-
- po = tcore_object_ref_object(co);
- if (!po)
- return TCORE_RETURN_EINVAL;
-
- po->service_type = service_type;
-
- return TCORE_RETURN_SUCCESS;
-}
-
-TReturn tcore_network_get_service_type(CoreObject *co,
- enum telephony_network_service_type *result)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(co, CORE_OBJECT_TYPE_NETWORK, TCORE_RETURN_EINVAL);
-
- if (!result)
- return TCORE_RETURN_EINVAL;
-
- po = tcore_object_ref_object(co);
- if (!po)
- return TCORE_RETURN_EINVAL;
-
- *result = po->service_type;
-
- return TCORE_RETURN_SUCCESS;
-}
-
-TReturn tcore_network_set_ims_reg_info(CoreObject *co,
- struct tel_network_ims_registration_info ims_reg_info)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(co, CORE_OBJECT_TYPE_NETWORK, TCORE_RETURN_EINVAL);
-
- po = tcore_object_ref_object(co);
- if (!po)
- return TCORE_RETURN_EINVAL;
-
- po->ims_reg_info.is_registered = ims_reg_info.is_registered;
- po->ims_reg_info.feature_mask = ims_reg_info.feature_mask;
- po->ims_reg_info.network_type = ims_reg_info.network_type;
- po->ims_reg_info.ecmp_mode = ims_reg_info.ecmp_mode;
-
- return TCORE_RETURN_SUCCESS;
-}
-
-TReturn tcore_network_get_ims_reg_info(CoreObject *co,
- struct tel_network_ims_registration_info *ims_reg_info)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(co, CORE_OBJECT_TYPE_NETWORK, TCORE_RETURN_EINVAL);
-
- if (!ims_reg_info)
- return TCORE_RETURN_EINVAL;
-
- po = tcore_object_ref_object(co);
- if (!po)
- return TCORE_RETURN_EINVAL;
-
- ims_reg_info->is_registered = po->ims_reg_info.is_registered;
- ims_reg_info->feature_mask = po->ims_reg_info.feature_mask;
- ims_reg_info->network_type = po->ims_reg_info.network_type;
- ims_reg_info->ecmp_mode = po->ims_reg_info.ecmp_mode;
-
- return TCORE_RETURN_SUCCESS;
-}
-
-TReturn tcore_network_set_ims_voice_status(CoreObject *co, gboolean status)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(co, CORE_OBJECT_TYPE_NETWORK, TCORE_RETURN_EINVAL);
-
- po = tcore_object_ref_object(co);
- if (!po)
- return TCORE_RETURN_EINVAL;
-
- po->ims_voice_status = status;
-
- return TCORE_RETURN_SUCCESS;
-}
-
-TReturn tcore_network_get_ims_voice_status(CoreObject *co, gboolean *status)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(co, CORE_OBJECT_TYPE_NETWORK, TCORE_RETURN_EINVAL);
-
- if (!status)
- return TCORE_RETURN_EINVAL;
-
- po = tcore_object_ref_object(co);
- if (!po)
- return TCORE_RETURN_EINVAL;
-
- *status = po->ims_voice_status;
-
- return TCORE_RETURN_SUCCESS;
-}
-
-TReturn tcore_network_set_ecc_rat_search_status(CoreObject *co,
- enum telephony_network_ecc_rat_search_status status)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(co, CORE_OBJECT_TYPE_NETWORK, TCORE_RETURN_EINVAL);
-
- po = tcore_object_ref_object(co);
- if (!po)
- return TCORE_RETURN_EINVAL;
-
- po->rat_search_status = status;
-
- return TCORE_RETURN_SUCCESS;
-}
-
-TReturn tcore_network_get_ecc_rat_search_status(CoreObject *co,
- enum telephony_network_ecc_rat_search_status *status)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(co, CORE_OBJECT_TYPE_NETWORK, TCORE_RETURN_EINVAL);
-
- if (!status)
- return TCORE_RETURN_EINVAL;
-
- po = tcore_object_ref_object(co);
- if (!po)
- return TCORE_RETURN_EINVAL;
-
- *status = po->rat_search_status;
-
- return TCORE_RETURN_SUCCESS;
-}
-
-TReturn tcore_network_set_ecc_rat(CoreObject *co,
- enum telephony_network_access_technology ecc_rat)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(co, CORE_OBJECT_TYPE_NETWORK, TCORE_RETURN_EINVAL);
-
- po = tcore_object_ref_object(co);
- if (!po)
- return TCORE_RETURN_EINVAL;
-
- po->ecc_rat = ecc_rat;
-
- return TCORE_RETURN_SUCCESS;
-}
-
-TReturn tcore_network_get_ecc_rat(CoreObject *co,
- enum telephony_network_access_technology *ecc_rat)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(co, CORE_OBJECT_TYPE_NETWORK, TCORE_RETURN_EINVAL);
-
- if (!ecc_rat)
- return TCORE_RETURN_EINVAL;
-
- po = tcore_object_ref_object(co);
- if (!po)
- return TCORE_RETURN_EINVAL;
-
- *ecc_rat = po->ecc_rat;
-
- return TCORE_RETURN_SUCCESS;
-}
-
-TReturn tcore_network_operator_info_add(CoreObject *co,
- const struct tcore_network_operator_info *noi)
-{
- struct private_object_data *po = NULL;
- char plmn[7];
- int mcc_index, mnc_index;
-
- CORE_OBJECT_CHECK_RETURN(co, CORE_OBJECT_TYPE_NETWORK, TCORE_RETURN_EINVAL);
-
- if (!noi)
- return TCORE_RETURN_EINVAL;
-
- mcc_index = atoi(noi->mcc);
- mnc_index = atoi(noi->mnc);
-
- if (mcc_index > 999 || mnc_index > 999) {
- err("mcc_index %d mnc_index %d", mcc_index, mnc_index);
- return TCORE_RETURN_EINVAL;
- }
-
- po = tcore_object_ref_object(co);
- if (!po)
- return TCORE_RETURN_EINVAL;
-
- g_strlcpy(plmn, noi->mcc, NETWORK_MAX_MCC_LEN + 1);
- g_strlcpy(plmn + NETWORK_MAX_MCC_LEN, noi->mnc, NETWORK_MAX_MNC_LEN + 1);
-
- if (g_hash_table_lookup(po->operator_info_hash, plmn))
- g_hash_table_remove(po->operator_info_hash, plmn);
-
- g_hash_table_insert(po->operator_info_hash,
- g_strdup(plmn),
- g_memdup(noi, sizeof(struct tcore_network_operator_info)));
-
- return TCORE_RETURN_SUCCESS;
-}
-
-struct tcore_network_operator_info *
-tcore_network_operator_info_find(CoreObject *co, const char *mcc, const char *mnc)
-{
- struct private_object_data *po = NULL;
- struct tcore_network_operator_info *data;
- char plmn[NETWORK_MAX_PLMN_LEN+1];
- int mcc_index, mnc_index;
-
- CORE_OBJECT_CHECK_RETURN(co, CORE_OBJECT_TYPE_NETWORK, NULL);
-
- if (!mcc || !mnc)
- return NULL;
-
- mcc_index = atoi(mcc);
- mnc_index = atoi(mnc);
-
- if (mcc_index > 999 || mnc_index > 999) {
- err("mcc_index %d mnc_index %d", mcc_index, mnc_index);
- return NULL;
- }
-
- po = tcore_object_ref_object(co);
- if (!po)
- return NULL;
-
- g_strlcpy(plmn, mcc, NETWORK_MAX_MCC_LEN + 1);
- g_strlcpy(plmn + NETWORK_MAX_MCC_LEN, mnc, NETWORK_MAX_MNC_LEN + 1);
-
- data = g_hash_table_lookup(po->operator_info_hash, plmn);
-
- if (data) {
- dbg("found mcc[%s], mnc[%s] name[%s] type[%d] in operator info table (%p)",
- data->mcc, data->mnc, data->name, data->type, po->operator_info_hash);
- } else {
- dbg("mcc[%s] mnc[%s] not present in operator table (%p)",
- mcc, mnc, po->operator_info_hash);
- }
-
- return data;
-}
-
-void tcore_network_update_mcc_mnc_oper_list(CoreObject *co,
- const char *plmn, const char *name, enum tcore_network_operator_info_type type)
-{
- char mcc[NETWORK_MAX_MCC_LEN+1] = { 0, };
- const char *mnc;
- struct tcore_network_operator_info *noi = NULL;
-
- CORE_OBJECT_CHECK(co, CORE_OBJECT_TYPE_NETWORK);
-
- if (!plmn) {
- err("plmn is NULL");
- return;
- }
-
- if (strlen(plmn) < NETWORK_MAX_MCC_LEN+1) {
- err("strlen of plmn is %d", strlen(plmn));
- return;
- }
-
- memcpy(mcc, plmn, NETWORK_MAX_MCC_LEN);
- mnc = plmn + NETWORK_MAX_MCC_LEN;
-
- if (atoi(mcc) == 0) {
- err("atoi(mcc) is Zero. mcc[%s]", mcc);
- return;
- }
-
- noi = g_try_malloc0(sizeof(struct tcore_network_operator_info));
- if (noi == NULL) {
- err("Memory alloc failed");
- return;
- }
-
- g_snprintf(noi->mcc, NETWORK_MAX_MCC_LEN+1, "%s", mcc);
- g_snprintf(noi->mnc, NETWORK_MAX_MNC_LEN+1, "%s", mnc);
- g_snprintf(noi->name, NETWORK_MAX_NETWORK_NAME_LEN+1, "%s", name);
- noi->type = type;
-
- info("[NETINFO] Update mcc[%s] mnc[%s] name[%s] type[%d] oper_list", noi->mcc, noi->mnc, noi->name, noi->type);
- tcore_network_operator_info_add(co, noi);
-
- g_free(noi);
-}
-
-/* Loads operator info from database */
-gboolean tcore_network_load_mcc_mnc_oper_list_from_db(TcorePlugin *p,
- CoreObject *co, const char *mcc, const char *mnc, const char *db_path)
-{
- Server *s;
- Storage *strg;
- void *handle;
- char query[256] = {0, };
- char mcc_str[NETWORK_MAX_MCC_LEN+1] = { 0, };
- GHashTableIter iter;
- gpointer key, value;
- GHashTable *result = NULL, *row = NULL;
- struct tcore_network_operator_info *noi = NULL;
- int count = 0;
-
- s = tcore_plugin_ref_server(p);
- strg = tcore_server_find_storage(s, "database");
-
- handle = tcore_storage_create_handle(strg, db_path);
- if (!handle) {
- err("fail to create database handle");
- return FALSE;
- }
-
- g_snprintf(query, 255,
- "select country, mcc, mnc, oper from mcc_mnc_oper_list where mcc='%s' and mnc='%s'",
- mcc, mnc);
- dbg("query = [%s]", query);
-
- result = g_hash_table_new_full(g_str_hash, g_str_equal, NULL,
- (GDestroyNotify) g_hash_table_destroy);
- if (!result) {
- err("fail to create new hash table");
- tcore_storage_remove_handle(strg, handle);
- return FALSE;
- }
-
- if (tcore_storage_read_query_database(strg, handle, query, NULL, result, 4) == FALSE) {
- tcore_storage_remove_handle(strg, handle);
- g_hash_table_destroy(result);
- return FALSE;
- }
-
- g_hash_table_iter_init(&iter, result);
- noi = g_try_malloc0(sizeof(struct tcore_network_operator_info));
- if (noi == NULL) {
- err("Memory alloc failed");
- tcore_storage_remove_handle(strg, handle);
- g_hash_table_destroy(result);
- return FALSE;
- }
-
- while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
- row = value;
-
- memset(noi, 0x0, sizeof(struct tcore_network_operator_info));
- memset(mcc_str, 0, sizeof(mcc_str));
-
- g_snprintf(mcc_str, NETWORK_MAX_MCC_LEN+1, "%s", (char *)g_hash_table_lookup(row, "1"));
- if (strlen(mcc_str) == 1)
- g_snprintf(noi->mcc, NETWORK_MAX_MCC_LEN+1, "00%s", mcc_str);
- else if (strlen(mcc_str) == 2)
- g_snprintf(noi->mcc, NETWORK_MAX_MCC_LEN+1, "0%s", mcc_str);
- else
- g_snprintf(noi->mcc, NETWORK_MAX_MCC_LEN+1, "%s", mcc_str);
- g_snprintf(noi->mnc, NETWORK_MAX_MNC_LEN+1, "%s", (char *)g_hash_table_lookup(row, "2"));
- g_snprintf(noi->name, NETWORK_MAX_NETWORK_NAME_LEN+1, "%s", (char *)g_hash_table_lookup(row, "3"));
- g_snprintf(noi->country, NETWORK_MAX_COUNTRY_CODE_LEN+1, "%s", (char *)g_hash_table_lookup(row, "0"));
- if (g_strcmp0(NETWORK_MCC_MNC_OPER_LIST_GSMA_DB, db_path) == 0)
- noi->type = TCORE_NETWORK_OPERATOR_INFO_TYPE_TS25_DB;
- else
- noi->type = TCORE_NETWORK_OPERATOR_INFO_TYPE_DELTA_DB;
- info("[NETINFO] load name from DB : mcc[%s] mnc[%s] name[%s] type:[%d]", noi->mcc, noi->mnc, noi->name, noi->type);
- tcore_network_operator_info_add(co, noi);
- count++;
- }
- g_free(noi);
-
- g_hash_table_destroy(result);
-
- tcore_storage_remove_handle(strg, handle);
-
- if (count == 0)
- return FALSE;
-
- return TRUE;
-}
-
-/* Updates Operator info in the database */
-void tcore_network_update_mcc_mnc_oper_list_db(TcorePlugin *p, const char *mcc, const char *mnc, const char *oper_name)
-{
- Server *s;
- Storage *strg;
- void *handle;
- char query[256] = {0, };
- struct tcore_network_operator_info *noi = NULL;
- GHashTable *result, *row = NULL;
- GHashTableIter iter;
- gpointer key, value;
- gboolean field_exist = FALSE;
-
- if (G_UNLIKELY(!mcc || !mnc || !oper_name || !p)) {
- err("Input Parameter Addresses : mcc[%p] mnc[%p] oper_name[%p] plugin[%p]", mcc, mnc, oper_name, p);
- return;
- }
-
- if (G_UNLIKELY(strlen(oper_name) == 0)) {
- err("strlen of oper_name is Zero");
- return;
- }
-
- dbg("mcc[%s] mnc[%s] oper_name[%s]", mcc, mnc, oper_name);
-
- /* 1. Get DB handle */
- s = tcore_plugin_ref_server(p);
- strg = tcore_server_find_storage(s, "database");
-
- handle = tcore_storage_create_handle(strg, NETWORK_MCC_MNC_OPER_LIST_GSMA_DB);
- if (!handle) {
- err("fail to create database handle");
- return;
- }
-
- /* 2. Check duplicated network operator name in DB */
- g_snprintf(query, 255,
- "select country, mcc, mnc, oper from mcc_mnc_oper_list where mcc='%s' and mnc='%s'",
- mcc, mnc);
- dbg("query = [%s]", query);
-
- result = g_hash_table_new_full(g_str_hash, g_str_equal, NULL,
- (GDestroyNotify) g_hash_table_destroy);
- if (!result) {
- err("fail to create new hash table");
- tcore_storage_remove_handle(strg, handle);
- return;
- }
-
- tcore_storage_read_query_database(strg, handle, query, NULL, result, 4);
-
- g_hash_table_iter_init(&iter, result);
- noi = g_try_malloc0(sizeof(struct tcore_network_operator_info));
- if (noi == NULL) {
- err("Memory alloc failed");
- tcore_storage_remove_handle(strg, handle);
- g_hash_table_destroy(result);
- return;
- }
- while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
- row = value;
-
- memset(noi, 0x0, sizeof(struct tcore_network_operator_info));
-
- g_snprintf(noi->mcc, NETWORK_MAX_MCC_LEN+1, "%s", (char *)g_hash_table_lookup(row, "1"));
- g_snprintf(noi->mnc, NETWORK_MAX_MNC_LEN+1, "%s", (char *)g_hash_table_lookup(row, "2"));
- g_snprintf(noi->name, NETWORK_MAX_NETWORK_NAME_LEN+1, "%s", (char *)g_hash_table_lookup(row, "3"));
- g_snprintf(noi->country, NETWORK_MAX_COUNTRY_CODE_LEN+1, "%s", (char *)g_hash_table_lookup(row, "0"));
-
- info("This field (mcc[%s] mnc[%s] name[%s]) will be updated ", noi->mcc, noi->mnc, noi->name);
- field_exist = TRUE;
- }
- g_free(noi);
- g_hash_table_destroy(result);
-
- /* 3. Update Network Operator name DB */
- result = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, g_free);
- if (!result) {
- err("fail to create new hash table");
- tcore_storage_remove_handle(strg, handle);
- return;
- }
-
- if (field_exist) {
- /* Update DB */
- snprintf(query, 255, "update mcc_mnc_oper_list set oper = ? where mcc = ? and mnc = ?");
- dbg("query[%s]", query);
-
- g_hash_table_insert(result, (gpointer)"1", g_strdup(oper_name));
- g_hash_table_insert(result, (gpointer)"2", g_strdup(mcc));
- g_hash_table_insert(result, (gpointer)"3", g_strdup(mnc));
-
- if (tcore_storage_update_query_database(strg, handle, query, result) == FALSE)
- err("update query failed");
- } else {
- /* Insert DB */
- snprintf(query, 255, "insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values (?, ?, ?, ?)");
- dbg("query[%s]", query);
-
- g_hash_table_insert(result, (gpointer)"1", g_strdup("__"));
- g_hash_table_insert(result, (gpointer)"2", g_strdup(mcc));
- g_hash_table_insert(result, (gpointer)"3", g_strdup(mnc));
- g_hash_table_insert(result, (gpointer)"4", g_strdup(oper_name));
-
- if (tcore_storage_insert_query_database(strg, handle, query, result) == FALSE)
- err("insert query failed");
- }
-
- g_hash_table_destroy(result);
- tcore_storage_remove_handle(strg, handle);
-}
+++ /dev/null
-/*
- * libtcore
- *
- * 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.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <glib.h>
-
-#include "tcore.h"
-#include "internal/tcore_types.h"
-#include "plugin.h"
-#include "queue.h"
-#include "user_request.h"
-#include "core_object.h"
-#include "co_phonebook.h"
-
-struct private_object_data {
- struct tcore_phonebook_operations *ops[TCORE_OPS_TYPE_MAX];
-
- gboolean b_init;
- struct tel_phonebook_support_list support_list;
- struct tel_phonebook_field_support_list field_support_list;
- enum tel_phonebook_type selected;
-};
-
-static TReturn _dispatcher(CoreObject *o, UserRequest *ur, enum tcore_ops_type ops_type)
-{
- enum tcore_request_command command;
- struct private_object_data *po = tcore_object_ref_object(o);
- struct tcore_phonebook_operations *ops = NULL;
-
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PHONEBOOK, TCORE_RETURN_EINVAL);
- CORE_OBJECT_VALIDATE_OPS_RETURN_VAL(ops_type, TCORE_RETURN_EINVAL);
-
- tcore_check_null_ret_err("po", po, TCORE_RETURN_EINVAL);
- tcore_check_null_ret_err("ur", ur, TCORE_RETURN_EINVAL);
-
- ops = po->ops[ops_type];
- tcore_check_null_ret_err("ops", ops, TCORE_RETURN_FAILURE);
-
- command = tcore_user_request_get_command(ur);
- switch (command) {
- case TREQ_PHONEBOOK_GETCOUNT:
- tcore_check_null_ret_err("ops->get_count",
- ops->get_count, TCORE_RETURN_ENOSYS);
-
- return ops->get_count(o, ur);
-
- case TREQ_PHONEBOOK_GETMETAINFO:
- tcore_check_null_ret_err("ops->get_info",
- ops->get_info, TCORE_RETURN_ENOSYS);
-
- return ops->get_info(o, ur);
-
- case TREQ_PHONEBOOK_GETUSIMINFO:
- tcore_check_null_ret_err("ops->get_usim_info",
- ops->get_usim_info, TCORE_RETURN_ENOSYS);
-
- return ops->get_usim_info(o, ur);
-
- case TREQ_PHONEBOOK_READRECORD:
- tcore_check_null_ret_err("ops->read_record",
- ops->read_record, TCORE_RETURN_ENOSYS);
-
- return ops->read_record(o, ur);
-
- case TREQ_PHONEBOOK_UPDATERECORD:
- tcore_check_null_ret_err("ops->update_record",
- ops->update_record, TCORE_RETURN_ENOSYS);
-
- return ops->update_record(o, ur);
-
- case TREQ_PHONEBOOK_DELETERECORD:
- tcore_check_null_ret_err("ops->delete_record",
- ops->delete_record, TCORE_RETURN_ENOSYS);
-
- return ops->delete_record(o, ur);
-
- default:
- break;
- }
-
- return TCORE_RETURN_SUCCESS;
-}
-
-static void _free_hook(CoreObject *o)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_PHONEBOOK);
-
- po = tcore_object_ref_object(o);
- if (po) {
- free(po);
- tcore_object_link_object(o, NULL);
- }
-}
-
-gboolean tcore_phonebook_get_status(CoreObject *o)
-{
- struct private_object_data *po = NULL;
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PHONEBOOK, FALSE);
- po = tcore_object_ref_object(o);
-
- return po->b_init;
-}
-
-gboolean tcore_phonebook_set_status(CoreObject *o, gboolean b_init)
-{
- struct private_object_data *po = NULL;
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PHONEBOOK, FALSE);
- po = tcore_object_ref_object(o);
-
- po->b_init = b_init;
-
- return TRUE;
-}
-
-struct tel_phonebook_support_list *tcore_phonebook_get_support_list(CoreObject *o)
-{
- struct private_object_data *po = NULL;
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PHONEBOOK, NULL);
- po = tcore_object_ref_object(o);
-
- if (po == NULL)
- return NULL;
-
- return g_memdup(&po->support_list, sizeof(struct tel_phonebook_support_list));
-}
-
-gboolean tcore_phonebook_set_support_list(CoreObject *o, struct tel_phonebook_support_list *list)
-{
- struct private_object_data *po = NULL;
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PHONEBOOK, FALSE);
- po = tcore_object_ref_object(o);
-
- memcpy(&po->support_list, list, sizeof(struct tel_phonebook_support_list));
-
- return TRUE;
-}
-
-struct tel_phonebook_field_support_list *tcore_phonebook_get_field_support_list(CoreObject *o)
-{
- struct private_object_data *po = NULL;
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PHONEBOOK, NULL);
- po = tcore_object_ref_object(o);
-
- if (po == NULL)
- return NULL;
-
- return g_memdup(&po->field_support_list, sizeof(struct tel_phonebook_field_support_list));
-}
-
-gboolean tcore_phonebook_set_field_support_list(CoreObject *o, struct tel_phonebook_field_support_list *list)
-{
- struct private_object_data *po = NULL;
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PHONEBOOK, FALSE);
- po = tcore_object_ref_object(o);
-
- memcpy(&po->field_support_list, list, sizeof(struct tel_phonebook_field_support_list));
-
- return TRUE;
-}
-
-enum tel_phonebook_type tcore_phonebook_get_selected_type(CoreObject *o)
-{
- struct private_object_data *po = NULL;
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PHONEBOOK, PB_TYPE_UNKNOWNN);
- po = tcore_object_ref_object(o);
-
- return po->selected;
-}
-
-gboolean tcore_phonebook_set_selected_type(CoreObject *o, enum tel_phonebook_type t)
-{
- struct private_object_data *po = NULL;
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PHONEBOOK, FALSE);
- po = tcore_object_ref_object(o);
-
- po->selected = t;
-
- return TRUE;
-}
-
-CoreObject *tcore_phonebook_new(TcorePlugin *p, const char *name,
- struct tcore_phonebook_operations *ops, TcoreHal *hal)
-{
- CoreObject *o = NULL;
- struct private_object_data *po = NULL;
-
- if (!p)
- return NULL;
-
- o = tcore_object_new(p, name, hal);
- if (!o)
- return NULL;
-
- po = calloc(1, sizeof(struct private_object_data));
- if (!po) {
- tcore_object_free(o);
- return NULL;
- }
-
- /* set ops to default type when core object is created. */
- po->ops[TCORE_OPS_TYPE_CP] = ops;
-
- po->selected = PB_TYPE_UNKNOWNN;
-
- tcore_object_set_type(o, CORE_OBJECT_TYPE_PHONEBOOK);
- tcore_object_link_object(o, po);
- tcore_object_set_free_hook(o, _free_hook);
- tcore_object_set_dispatcher(o, _dispatcher);
-
- return o;
-}
-
-void tcore_phonebook_free(CoreObject *o)
-{
- CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_PHONEBOOK);
- tcore_object_free(o);
-}
-
-void tcore_phonebook_set_ops(CoreObject *o, struct tcore_phonebook_operations *ops, enum tcore_ops_type ops_type)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_PHONEBOOK);
- CORE_OBJECT_VALIDATE_OPS_RETURN(ops_type);
-
- po = (struct private_object_data *)tcore_object_ref_object(o);
- if (!po) {
- err("po is NULL");
- return;
- }
-
- po->ops[ops_type] = ops;
-}
+++ /dev/null
-/*
- * libtcore
- *
- * 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.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <glib.h>
-
-#include "tcore.h"
-#include "internal/tcore_types.h"
-#include "plugin.h"
-#include "user_request.h"
-#include "co_ps.h"
-#include "co_network.h"
-
-struct p_callid_type {
- unsigned int cid;
- gboolean active;
- gboolean connected;
- gchar *apn;
- GSList *contexts;
-};
-
-struct private_object_data {
- struct tcore_ps_operations *ops[TCORE_OPS_TYPE_MAX];
-
- gboolean online;
- gint num_of_pdn;
-
- /* 1 ~ UMTS_PS_MAX_CID */
- struct p_callid_type cid[PS_MAX_CID + 1];
-
- GSList *context_list;
-};
-
-static TReturn _dispatcher(CoreObject *o, UserRequest *ur, enum tcore_ops_type ops_type)
-{
- enum tcore_request_command command;
- struct private_object_data *po = tcore_object_ref_object(o);
- struct tcore_ps_operations *ops = NULL;
-
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_MODEM, TCORE_RETURN_EINVAL);
- CORE_OBJECT_VALIDATE_OPS_RETURN_VAL(ops_type, TCORE_RETURN_EINVAL);
-
- tcore_check_null_ret_err("po", po, TCORE_RETURN_EINVAL);
- tcore_check_null_ret_err("ur", ur, TCORE_RETURN_EINVAL);
-
- ops = po->ops[ops_type];
- tcore_check_null_ret_err("ops", ops, TCORE_RETURN_FAILURE);
-
- command = tcore_user_request_get_command(ur);
- switch (command) {
- default:
- break;
- }
-
- return TCORE_RETURN_SUCCESS;
-}
-
-static void _free_hook(CoreObject *o)
-{
- struct private_object_data *po = NULL;
- GSList *list;
-
- po = tcore_object_ref_object(o);
- if (!po)
- return;
-
- if (po->context_list) {
- for (list = po->context_list; list; list = list->next) {
- if (list->data)
- free(list->data);
-
- list->data = NULL;
- }
-
- g_slist_free(po->context_list);
- po->context_list = NULL;
- }
-
- g_free(po);
- tcore_object_link_object(o, NULL);
-}
-
-static gboolean _ps_is_active_context(CoreObject *o, CoreObject *ps_context)
-{
- GSList *contexts = NULL;
- CoreObject *s_context = NULL;
-
- int idx_cid = 0;
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, FALSE);
-
- po = tcore_object_ref_object(o);
-
- for (idx_cid = 1; idx_cid <= po->num_of_pdn; idx_cid++) {
- if (po->cid[idx_cid].cid == 0)
- continue;
-
- contexts = po->cid[idx_cid].contexts;
- if (!contexts)
- continue;
-
- while (contexts) {
- s_context = contexts->data;
- if (!s_context) {
- contexts = contexts->next;
- continue;
- }
-
- if (ps_context == s_context) {
- dbg("find contexts(%p) in cid(%d)", ps_context, idx_cid);
- return TRUE;
- }
-
- contexts = contexts->next;
- }
- }
-
- dbg("cannot find contexts(%p) ", ps_context);
-
- return FALSE;
-}
-
-static gboolean _ps_is_duplicated_apn(CoreObject *o, CoreObject *ps_context)
-{
- GSList *contexts = NULL;
- CoreObject *s_context = NULL;
- gchar *t_apn = NULL, *s_apn = NULL;
-
- int idx_cid = 0;
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, FALSE);
-
- po = tcore_object_ref_object(o);
- t_apn = tcore_context_get_apn(ps_context);
-
- for (idx_cid = 1; idx_cid <= po->num_of_pdn; idx_cid++) {
- if (po->cid[idx_cid].cid == 0)
- continue;
-
- contexts = po->cid[idx_cid].contexts;
- if (!contexts)
- continue;
-
- while (contexts) {
- s_context = contexts->data;
- if (!s_context) {
- contexts = contexts->next;
- continue;
- }
-
- if (ps_context == s_context) {
- contexts = contexts->next;
- continue;
- }
-
- s_apn = tcore_context_get_apn(s_context);
- if (g_strcmp0(t_apn, s_apn) == 0) {
- dbg("target and source context have same APN");
- tcore_context_cp_service_info(ps_context, s_context);
- g_free(t_apn);
- g_free(s_apn);
-
- return TRUE;
- }
- g_free(s_apn);
-
- contexts = contexts->next;
- }
- }
-
- g_free(t_apn);
- return FALSE;
-}
-
-static void _deactivate_context(gpointer context, gpointer user_data)
-{
- if (!context || !user_data)
- return;
-
- tcore_ps_deactivate_context(user_data, context, NULL);
-}
-
-CoreObject *tcore_ps_new(TcorePlugin *p, const char *name,
- struct tcore_ps_operations *ops, TcoreHal *hal)
-{
- CoreObject *o = NULL;
- struct private_object_data *po = NULL;
-
- if (!p)
- return NULL;
-
- o = tcore_object_new(p, name, hal);
- if (!o)
- return NULL;
-
- po = g_try_malloc0(sizeof(struct private_object_data));
- if (!po) {
- tcore_object_free(o);
- return NULL;
- }
-
- /* set ops to default type when core object is created. */
- po->ops[TCORE_OPS_TYPE_CP] = ops;
-
- tcore_object_set_type(o, CORE_OBJECT_TYPE_PS);
- tcore_object_link_object(o, po);
- tcore_object_set_free_hook(o, _free_hook);
- tcore_object_set_dispatcher(o, _dispatcher);
-
- return o;
-}
-
-void tcore_ps_free(CoreObject *o)
-{
- CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_PS);
- tcore_object_free(o);
-}
-
-void tcore_ps_set_ops(CoreObject *o,
- struct tcore_ps_operations *ops, enum tcore_ops_type ops_type)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_PS);
- CORE_OBJECT_VALIDATE_OPS_RETURN(ops_type);
-
- po = (struct private_object_data *)tcore_object_ref_object(o);
- if (!po) {
- err("po is NULL");
- return;
- }
-
- po->ops[ops_type] = ops;
-}
-
-TReturn tcore_ps_add_context(CoreObject *o, CoreObject *ctx_o)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, TCORE_RETURN_EINVAL);
- CORE_OBJECT_CHECK_RETURN(ctx_o, CORE_OBJECT_TYPE_PS_CONTEXT, TCORE_RETURN_EINVAL);
-
- po = tcore_object_ref_object(o);
- if (!po)
- return TCORE_RETURN_EINVAL;
-
- po->context_list = g_slist_insert(po->context_list, ctx_o, 0);
-
- return TCORE_RETURN_SUCCESS;
-}
-
-TReturn tcore_ps_remove_context(CoreObject *o, CoreObject *ctx_o)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, TCORE_RETURN_EINVAL);
- CORE_OBJECT_CHECK_RETURN(ctx_o, CORE_OBJECT_TYPE_PS_CONTEXT, TCORE_RETURN_EINVAL);
-
- po = tcore_object_ref_object(o);
- if (!po)
- return TCORE_RETURN_EINVAL;
-
- tcore_ps_clear_context_id(o, ctx_o);
- po->context_list = g_slist_remove(po->context_list, ctx_o);
-
- return TCORE_RETURN_SUCCESS;
-}
-
-TReturn tcore_ps_set_online(CoreObject *o, gboolean state)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, TCORE_RETURN_EINVAL);
-
- po = tcore_object_ref_object(o);
- if (!po)
- return TCORE_RETURN_EINVAL;
-
- po->online = state;
- dbg("PS Status: [%s]", (po->online ? "ONLINE" : "OFFLINE"));
-
- return TCORE_RETURN_SUCCESS;
-}
-
-TReturn tcore_ps_set_num_of_pdn(CoreObject *o, gint numbers)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, TCORE_RETURN_EINVAL);
-
- po = tcore_object_ref_object(o);
- if (!po)
- return TCORE_RETURN_EINVAL;
-
- if (numbers <= 0 || numbers > PS_MAX_CID)
- po->num_of_pdn = PS_MAX_CID;
- else
- po->num_of_pdn = numbers;
-
- dbg("ps num of pdn = %d, numbers = %d", po->num_of_pdn, numbers);
-
- return TCORE_RETURN_SUCCESS;
-}
-
-unsigned int tcore_ps_get_num_of_pdn(CoreObject *o)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, 0);
-
- po = tcore_object_ref_object(o);
- if (!po)
- return 0;
-
- return po->num_of_pdn;
-}
-
-unsigned int tcore_ps_set_cid_active(CoreObject *o, unsigned int cid, unsigned int enable)
-{
- int idx_cid = 0;
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, 0);
- if (cid == 0)
- return 0;
-
- po = tcore_object_ref_object(o);
- for (idx_cid = 1; idx_cid <= po->num_of_pdn; idx_cid++) {
- if (po->cid[idx_cid].cid == cid) {
- po->cid[idx_cid].active = enable;
- return 1;
- }
- }
-
- return 0;
-}
-
-unsigned int tcore_ps_get_cid_active(CoreObject *o, unsigned int cid)
-{
- int idx_cid = 0;
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, 0);
- if (cid == 0)
- return 0;
-
- po = tcore_object_ref_object(o);
- for (idx_cid = 1; idx_cid <= po->num_of_pdn; idx_cid++)
- if (po->cid[idx_cid].cid == cid)
- return po->cid[idx_cid].active;
-
- return 0;
-}
-
-GSList *tcore_ps_get_active_cids(CoreObject *o)
-{
- int idx_cid = 0;
- GSList *active_list = NULL;
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, NULL);
-
- po = tcore_object_ref_object(o);
-
- for (idx_cid = 1; idx_cid <= po->num_of_pdn; idx_cid++)
- if (po->cid[idx_cid].active)
- active_list = g_slist_append(active_list, &po->cid[idx_cid].cid);
-
- return active_list;
-}
-
-unsigned int tcore_ps_set_cid_connected(CoreObject *o, unsigned int cid, unsigned int connected)
-{
- int idx_cid = 0;
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, 0);
- if (cid == 0)
- return 0;
-
- po = tcore_object_ref_object(o);
- for (idx_cid = 1; idx_cid <= po->num_of_pdn; idx_cid++) {
- if (po->cid[idx_cid].cid == cid) {
- po->cid[idx_cid].connected = connected;
- return 1;
- }
- }
-
- return 0;
-}
-
-unsigned int tcore_ps_get_cid_connected(CoreObject *o, unsigned int cid)
-{
- int idx_cid = 0;
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, 0);
- if (cid == 0)
- return 0;
-
- po = tcore_object_ref_object(o);
- for (idx_cid = 1; idx_cid <= po->num_of_pdn; idx_cid++)
- if (po->cid[idx_cid].cid == cid)
- return po->cid[idx_cid].connected;
-
- return 0;
-}
-
-GSList *tcore_ps_get_connected_cids(CoreObject *o)
-{
- int idx_cid = 0;
- GSList *active_list = NULL;
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, NULL);
-
- po = tcore_object_ref_object(o);
-
- for (idx_cid = 1; idx_cid <= po->num_of_pdn; idx_cid++)
- if (po->cid[idx_cid].connected)
- active_list = g_slist_append(active_list, &po->cid[idx_cid].cid);
-
- return active_list;
-}
-
-unsigned int tcore_ps_is_active_apn(CoreObject *o, const char *apn)
-{
- int idx_cid = 0;
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, 0);
-
- po = tcore_object_ref_object(o);
-
- for (idx_cid = 1; idx_cid <= po->num_of_pdn; idx_cid++) {
- if (po->cid[idx_cid].cid == 0)
- continue;
-
- if (g_strcmp0((const char *)po->cid[idx_cid].apn, apn) == 0 && po->cid[idx_cid].active)
- return 1;
- }
-
- return 0;
-}
-
-CoreObject *tcore_ps_ref_context_by_role(CoreObject *o, enum co_context_role role)
-{
- struct private_object_data *po = NULL;
- GSList *list;
- CoreObject *pdp_o;
- TcorePlugin *p;
-
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, NULL);
-
- po = tcore_object_ref_object(o);
- if (!po)
- return NULL;
-
- p = tcore_object_ref_plugin(o);
- if (!p)
- return NULL;
-
- if (po->context_list) {
- for (list = po->context_list; list; list = list->next) {
- if (!list->data)
- continue;
-
- pdp_o = list->data;
- if (!pdp_o)
- continue;
-
- if (tcore_object_get_type(pdp_o) != CORE_OBJECT_TYPE_PS_CONTEXT)
- continue;
-
- if (tcore_context_get_role(pdp_o) == role)
- return pdp_o;
- }
- }
-
- return NULL;
-}
-
-GSList *tcore_ps_ref_context_by_id(CoreObject *o, unsigned int id)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, NULL);
-
- po = tcore_object_ref_object(o);
- if (!po)
- return NULL;
-
- if (id == 0 || id > (unsigned int)po->num_of_pdn)
- return NULL;
-
- if (po->cid[id].cid != id)
- return NULL;
-
- return po->cid[id].contexts;
-}
-
-gboolean tcore_ps_any_context_activating_activated(CoreObject *o, int * state)
-{
- struct private_object_data *po = NULL;
- CoreObject *pdp_o;
- gboolean ret = FALSE;
- GSList *list = NULL;
- enum co_context_state context_state = CONTEXT_STATE_DEACTIVATED;
-
- po = tcore_object_ref_object(o);
- if (!po)
- return ret;
-
- if (po->context_list) {
- for (list = po->context_list; list; list = list->next) {
- if (!list->data)
- continue;
-
- pdp_o = list->data;
-
- if (tcore_object_get_type(pdp_o) != CORE_OBJECT_TYPE_PS_CONTEXT)
- continue;
-
- context_state = tcore_context_get_state(pdp_o);
-
- if (CONTEXT_STATE_ACTIVATED == context_state) {
- *state = CONTEXT_STATE_ACTIVATED;
- return TRUE;
- } else if (CONTEXT_STATE_ACTIVATING == context_state) {
- *state = CONTEXT_STATE_ACTIVATING;
- ret = TRUE;
- continue;
- } else if (CONTEXT_STATE_DEACTIVATING == context_state) {
- *state = CONTEXT_STATE_DEACTIVATING;
- ret = TRUE;
- continue;
- }
- }
- }
-
- return ret;
-}
-
-
-TReturn tcore_ps_assign_context_id(CoreObject *o, CoreObject *context, unsigned char cid)
-{
- struct private_object_data *po = NULL;
- unsigned char idx;
-
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, TCORE_RETURN_EINVAL);
- CORE_OBJECT_CHECK_RETURN(context, CORE_OBJECT_TYPE_PS_CONTEXT, TCORE_RETURN_EINVAL);
-
- po = tcore_object_ref_object(o);
- if (!po)
- return TCORE_RETURN_EINVAL;
-
- if (cid > (unsigned int)po->num_of_pdn)
- return TCORE_RETURN_PS_CID_ERROR;
-
- if (cid == 0) {
- /* Automatic assign */
- for (idx = 1; idx <= po->num_of_pdn; idx++) {
- if (po->cid[idx].cid == 0) {
- po->cid[idx].cid = idx;
- po->cid[idx].contexts = g_slist_append(po->cid[idx].contexts, context);
- po->cid[idx].apn = tcore_context_get_apn(context);
-
- dbg("assign contexts(%p) in cid(%d), apn(%s)", context, idx, po->cid[idx].apn);
-
- return tcore_context_set_id(context, idx);
- } else
- dbg("cid[%d] is not null", idx);
- }
-
- dbg("can't find empty cid");
- } else {
- /* Manual assign */
- if (po->cid[cid].cid == cid) {
- po->cid[cid].contexts = g_slist_append(po->cid[cid].contexts, context);
- return tcore_context_set_id(context, cid);
- } else
- dbg("cid[%d] is not null", cid);
- }
-
- return TCORE_RETURN_PS_CID_ERROR;
-}
-
-TReturn tcore_ps_send_dormant_request(CoreObject *o, void *user_data)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, TCORE_RETURN_EINVAL);
-
- po = tcore_object_ref_object(o);
- if (!po)
- return TCORE_RETURN_EINVAL;
-
- if (!po->online) {
- dbg("ps network is not online !");
- return TCORE_RETURN_PS_NETWORK_NOT_READY;
- }
-
- /* By 'default' considering Modem/CP opearations */
- return po->ops[TCORE_OPS_TYPE_CP]->send_dormant_request(o, user_data);
-}
-
-TReturn tcore_ps_clear_context_id(CoreObject *o, CoreObject *context)
-{
- struct private_object_data *po = NULL;
- unsigned char i = 0, cnt = 0;
-
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, TCORE_RETURN_EINVAL);
- CORE_OBJECT_CHECK_RETURN(context, CORE_OBJECT_TYPE_PS_CONTEXT, TCORE_RETURN_EINVAL);
-
- po = tcore_object_ref_object(o);
- if (!po)
- return TCORE_RETURN_EINVAL;
-
- i = tcore_context_get_id(context);
- if (i == 0)
- return TCORE_RETURN_PS_CID_ERROR;
-
- if (i > po->num_of_pdn)
- return TCORE_RETURN_PS_CID_ERROR;
-
- po->cid[i].contexts = g_slist_remove(po->cid[i].contexts, context);
- cnt = g_slist_length(po->cid[i].contexts);
- if (cnt <= 0) {
- po->cid[i].cid = 0;
- po->cid[i].active = FALSE;
- po->cid[i].connected = FALSE;
- g_free(po->cid[i].apn);
- po->cid[i].apn = NULL;
- }
-
- return tcore_context_set_id(context, 0);
-}
-
-TReturn tcore_ps_define_context(CoreObject *o, CoreObject *ps_context, void *user_data)
-{
- int rv;
- struct private_object_data *po = NULL;
- CoreObject *co_nw = NULL;
- enum telephony_network_access_technology act = NETWORK_ACT_UNKNOWN;
-
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, TCORE_RETURN_EINVAL);
-
- po = tcore_object_ref_object(o);
- if (!po)
- return TCORE_RETURN_EINVAL;
-
- if (!ps_context)
- return TCORE_RETURN_EINVAL;
-
- rv = _ps_is_active_context(o, ps_context);
- if (rv)
- return TCORE_RETURN_SUCCESS;
-
- co_nw = tcore_plugin_ref_core_object(tcore_object_ref_plugin(o), CORE_OBJECT_TYPE_NETWORK);
- tcore_network_get_access_technology(co_nw, &act);
- if (act >= NETWORK_ACT_IS95A && act <= NETWORK_ACT_EHRPD)
- tcore_context_set_tech_preference(ps_context, CONTEXT_TECH_3GPP2);
- else {
- tcore_context_set_tech_preference(ps_context, CONTEXT_TECH_3GPP);
- dbg("3GPP preference by default");
- }
-
- rv = _ps_is_duplicated_apn(o, ps_context);
- if (rv) {
- unsigned char cid = 0;
- cid = tcore_context_get_id(ps_context);
- po->cid[cid].contexts = g_slist_append(po->cid[cid].contexts, ps_context);
- return TCORE_RETURN_SUCCESS;
- }
-
- if (tcore_context_get_id(ps_context) == 0)
- if (tcore_ps_assign_context_id(o, ps_context, 0) != TCORE_RETURN_SUCCESS)
- return TCORE_RETURN_PS_CID_ERROR;
-
- dbg("contexts(%p), cid = %d", ps_context, tcore_context_get_id(ps_context));
-
- /* By 'default' considering Modem/CP opearations */
- return po->ops[TCORE_OPS_TYPE_CP]->define_context(o, ps_context, user_data);
-}
-
-TReturn tcore_ps_activate_context(CoreObject *o, CoreObject *ps_context, void *user_data)
-{
- int rv;
- struct private_object_data *po = NULL;
- enum co_context_state context_state = CONTEXT_STATE_DEACTIVATED;
-
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, TCORE_RETURN_EINVAL);
-
- po = tcore_object_ref_object(o);
- if (!po)
- return TCORE_RETURN_EINVAL;
-
- if (!po->online) {
- dbg("ps network is not online !");
- return TCORE_RETURN_PS_NETWORK_NOT_READY;
- }
-
- if (!ps_context)
- return TCORE_RETURN_EINVAL;
-
- rv = _ps_is_active_context(o, ps_context);
- if (!rv) {
- dbg("it is not defined context");
- return TCORE_RETURN_EINVAL;
- }
-
- rv = _ps_is_duplicated_apn(o, ps_context);
- if (rv) {
- dbg("context activation is already requested for the same apn(%s)",
- tcore_context_get_apn(ps_context));
- return TCORE_RETURN_SUCCESS;
- }
-
- context_state = tcore_context_get_state(ps_context);
-
- if (context_state == CONTEXT_STATE_ACTIVATED) {
- dbg("Context state : CONTEXT_STATE_ACTIVATED");
- return TCORE_RETURN_SUCCESS;
- } else if (context_state == CONTEXT_STATE_ACTIVATING) {
- dbg("Context state : CONTEXT_STATE_ACTIVATING");
- return TCORE_RETURN_SUCCESS;
- } else if (context_state == CONTEXT_STATE_DEACTIVATING) {
- dbg("Context state : CONTEXT_STATE_DEACTIVATING");
- return TCORE_RETURN_PS_DEACTIVATING;
- }
-
- dbg("cid = %d", tcore_context_get_id(ps_context));
-
- tcore_context_set_state(ps_context, CONTEXT_STATE_ACTIVATING);
-
- /* By 'default' considering Modem/CP opearations */
- rv = po->ops[TCORE_OPS_TYPE_CP]->activate_context(o, ps_context, user_data);
- if (rv != TCORE_RETURN_SUCCESS)
- tcore_context_set_state(ps_context, CONTEXT_STATE_DEACTIVATED);
-
- return rv;
-}
-
-TReturn tcore_ps_deactivate_context(CoreObject *o, CoreObject *ps_context, void *user_data)
-{
- int rv;
- struct private_object_data *po = NULL;
- enum co_context_state context_state = CONTEXT_STATE_DEACTIVATED;
-
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, TCORE_RETURN_EINVAL);
-
- po = tcore_object_ref_object(o);
- if (!po)
- return TCORE_RETURN_EINVAL;
-
- if (!po->online) {
- dbg("ps network is not online !");
- return TCORE_RETURN_PS_NETWORK_NOT_READY;
- }
-
- if (!ps_context)
- return TCORE_RETURN_EINVAL;
-
- rv = _ps_is_active_context(o, ps_context);
- if (!rv)
- return TCORE_RETURN_EINVAL;
-
- rv = _ps_is_duplicated_apn(o, ps_context);
- if (rv) {
- unsigned char cid = 0;
- cid = tcore_context_get_id(ps_context);
- po->cid[cid].contexts = g_slist_remove(po->cid[cid].contexts, ps_context);
- tcore_context_set_state(ps_context, CONTEXT_STATE_DEACTIVATED);
- return TCORE_RETURN_SUCCESS;
- }
-
- context_state = tcore_context_get_state(ps_context);
- if (context_state == CONTEXT_STATE_DEACTIVATED) {
- dbg("Context State : CONTEXT_STATE_DEACTIVATED");
- return TCORE_RETURN_SUCCESS;
- } else if (context_state == CONTEXT_STATE_DEACTIVATING) {
- dbg("Context State : CONTEXT_STATE_DEACTIVATING");
- return TCORE_RETURN_SUCCESS;
- } else if (context_state == CONTEXT_STATE_ACTIVATING) {
- dbg("Context State :CONTEXT_STATE_ACTIVATING");
- return TCORE_RETURN_PS_ACTIVATING;
- }
-
- tcore_context_set_state(ps_context, CONTEXT_STATE_DEACTIVATING);
-
- /* By 'default' considering Modem/CP opearations */
- rv = po->ops[TCORE_OPS_TYPE_CP]->deactivate_context(o, ps_context, user_data);
- if (rv != TCORE_RETURN_SUCCESS)
- tcore_context_set_state(ps_context, CONTEXT_STATE_ACTIVATED);
-
- return rv;
-}
-
-TReturn tcore_ps_deactivate_contexts(CoreObject *o)
-{
- int temp_index = 0;
- struct private_object_data *po = NULL;
- GSList *contexts = NULL;
-
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, TCORE_RETURN_EINVAL);
-
- po = tcore_object_ref_object(o);
- if (!po)
- return TCORE_RETURN_EINVAL;
-
- if (!po->online) {
- dbg("ps network is not online !");
- return TCORE_RETURN_PS_NETWORK_NOT_READY;
- }
-
- for (temp_index = 1; temp_index <= po->num_of_pdn; temp_index++) {
- if (po->cid[temp_index].cid != 0) {
- contexts = po->cid[temp_index].contexts;
- if (!contexts)
- continue;
-
- g_slist_foreach(contexts, _deactivate_context, o);
- }
- }
-
- return TCORE_RETURN_SUCCESS;
-}
-
-TReturn tcore_ps_deactivate_cid(CoreObject *o, unsigned int cid)
-{
- int temp_index = 0;
- struct private_object_data *po = NULL;
- GSList *contexts = NULL;
-
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, TCORE_RETURN_EINVAL);
-
- po = tcore_object_ref_object(o);
- if (!po)
- return TCORE_RETURN_EINVAL;
-
- if (!po->online) {
- dbg("ps network is not online !");
- return TCORE_RETURN_PS_NETWORK_NOT_READY;
- }
-
- for (temp_index = 1; temp_index <= po->num_of_pdn; temp_index++) {
- if (po->cid[temp_index].cid != 0 && po->cid[temp_index].cid == cid) {
- contexts = po->cid[temp_index].contexts;
- if (!contexts)
- continue;
-
- g_slist_foreach(contexts, _deactivate_context, o);
- }
- }
-
- return TCORE_RETURN_SUCCESS;
-}
+++ /dev/null
-/*
- * libtcore
- *
- * 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.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <glib.h>
-
-#include "tcore.h"
-#include "internal/tcore_types.h"
-#include "plugin.h"
-#include "queue.h"
-#include "user_request.h"
-#include "co_sap.h"
-
-struct private_object_data {
- struct tcore_sap_operations *ops[TCORE_OPS_TYPE_MAX];
-};
-
-static TReturn _dispatcher(CoreObject *o, UserRequest *ur, enum tcore_ops_type ops_type)
-{
- enum tcore_request_command command;
- struct private_object_data *po = tcore_object_ref_object(o);
- struct tcore_sap_operations *ops = NULL;
-
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_SAP, TCORE_RETURN_EINVAL);
- CORE_OBJECT_VALIDATE_OPS_RETURN_VAL(ops_type, TCORE_RETURN_EINVAL);
-
- tcore_check_null_ret_err("po", po, TCORE_RETURN_EINVAL);
- tcore_check_null_ret_err("ur", ur, TCORE_RETURN_EINVAL);
-
- ops = po->ops[ops_type];
- tcore_check_null_ret_err("ops", ops, TCORE_RETURN_FAILURE);
-
- command = tcore_user_request_get_command(ur);
- switch (command) {
- case TREQ_SAP_REQ_CONNECT:
- tcore_check_null_ret_err("ops->connect",
- ops->connect, TCORE_RETURN_ENOSYS);
-
- return ops->connect(o, ur);
-
- case TREQ_SAP_REQ_DISCONNECT:
- tcore_check_null_ret_err("ops->disconnect",
- ops->disconnect, TCORE_RETURN_ENOSYS);
-
- return ops->disconnect(o, ur);
-
- case TREQ_SAP_REQ_STATUS:
- tcore_check_null_ret_err("ops->req_status",
- ops->req_status, TCORE_RETURN_ENOSYS);
-
- return ops->req_status(o, ur);
-
- case TREQ_SAP_REQ_ATR:
- tcore_check_null_ret_err("ops->get_atr",
- ops->get_atr, TCORE_RETURN_ENOSYS);
-
- return ops->get_atr(o, ur);
-
- case TREQ_SAP_TRANSFER_APDU:
- tcore_check_null_ret_err("ops->transfer_apdu",
- ops->transfer_apdu, TCORE_RETURN_ENOSYS);
-
- return ops->transfer_apdu(o, ur);
-
- case TREQ_SAP_SET_PROTOCOL:
- tcore_check_null_ret_err("ops->set_transport_protocol",
- ops->set_transport_protocol, TCORE_RETURN_ENOSYS);
-
- return ops->set_transport_protocol(o, ur);
-
- case TREQ_SAP_SET_POWER:
- tcore_check_null_ret_err("ops->set_power",
- ops->set_power, TCORE_RETURN_ENOSYS);
-
- return ops->set_power(o, ur);
-
- case TREQ_SAP_REQ_CARDREADERSTATUS:
- tcore_check_null_ret_err("ops->get_cardreader_status",
- ops->get_cardreader_status, TCORE_RETURN_ENOSYS);
-
- return ops->get_cardreader_status(o, ur);
-
- default:
- break;
- }
-
- return TCORE_RETURN_SUCCESS;
-}
-
-static void _free_hook(CoreObject *o)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_SAP);
-
- po = tcore_object_ref_object(o);
- if (po) {
- free(po);
- tcore_object_link_object(o, NULL);
- }
-}
-
-CoreObject *tcore_sap_new(TcorePlugin *p, const char *name,
- struct tcore_sap_operations *ops, TcoreHal *hal)
-{
- CoreObject *o = NULL;
- struct private_object_data *po = NULL;
-
- if (!p)
- return NULL;
-
- o = tcore_object_new(p, name, hal);
- if (!o)
- return NULL;
-
- po = calloc(1, sizeof(struct private_object_data));
- if (!po) {
- tcore_object_free(o);
- return NULL;
- }
-
- /* set ops to default type when core object is created. */
- po->ops[TCORE_OPS_TYPE_CP] = ops;
-
- tcore_object_set_type(o, CORE_OBJECT_TYPE_SAP);
- tcore_object_link_object(o, po);
- tcore_object_set_free_hook(o, _free_hook);
- tcore_object_set_dispatcher(o, _dispatcher);
-
- return o;
-}
-
-void tcore_sap_free(CoreObject *o)
-{
- CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_SAP);
- tcore_object_free(o);
-}
-
-void tcore_sap_set_ops(CoreObject *o, struct tcore_sap_operations *ops, enum tcore_ops_type ops_type)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_SAP);
- CORE_OBJECT_VALIDATE_OPS_RETURN(ops_type);
-
- po = (struct private_object_data *)tcore_object_ref_object(o);
- if (!po) {
- err("po is NULL");
- return;
- }
-
- po->ops[ops_type] = ops;
-}
+++ /dev/null
-/*
- * libtcore
- *
- * 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.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <glib.h>
-
-#include "tcore.h"
-#include "internal/tcore_types.h"
-#include "plugin.h"
-#include "queue.h"
-#include "user_request.h"
-#include "core_object.h"
-#include "util.h"
-#include "co_sat.h"
-
-#define SATK_PROACTIVE_CMD_TAG 0xD0 /* Proactive Command Tag */
-#define SATK_MENU_SELECTION_TAG 0xD3 /* Menu Selection Tag */
-#define SATK_EVENT_DOWNLOAD_TAG 0xD6 /* Event Download Tag */
-
-/*
- * Tag Values (without Comprehension bit)
- */
-#define SATK_COMMAND_DETAILS_TAG 0x01 /* COMMAND DETAILS TAG */
-#define SATK_DEVICE_IDENTITY_TAG 0x02 /* DEVICE IDENTITY TAG */
-#define SATK_RESULT_TAG 0x03 /* RESULT TAG */
-#define SATK_DURATION_TAG 0x04 /* DURATION TAG */
-#define SATK_ALPHA_IDENTIFIER_TAG 0x05 /* ALPHA IDENTIFIER TAG */
-#define SATK_ADDRESS_TAG 0x06 /* ADDRESS TAG */
-#define SATK_CAPABILITY_CONFIGURATION_PARAMETERS_TAG 0x07 /* CAPABILITY CONFIGURATION PARAMETERS TAG */
-#define SATK_SUB_ADDRESS_TAG 0x08 /* SUB ADDRESS TAG */
-#define SATK_SS_STRING_TAG 0x09 /* SS STRING TAG */
-#define SATK_USSD_STRING_TAG 0x0A /* USSD STRING TAG */
-#define SATK_SMS_TPDU_TAG 0x0B /* SMS TPDU TAG */
-#define SATK_CELL_BROADCAST_PAGE_TAG 0x0C /* CELL BROADCAST PAGE TAG */
-#define SATK_TEXT_STRING_TAG 0x0D /* TEXT STRING TAG */
-#define SATK_TONE_TAG 0x0E /* TONE TAG */
-#define SATK_ITEM_TAG 0x0F /* ITEM TAG */
-#define SATK_ITEM_IDENTIFIER_TAG 0x10 /* ITEM IDENTIFIER TAG */
-#define SATK_RESPONSE_LENGTH_TAG 0x11 /* RESPONSE LENGTH TAG */
-#define SATK_FILE_LIST_TAG 0x12 /* FILE LIST TAG */
-#define SATK_LOCATION_INFORMATION_TAG 0x13 /* LOCATION INFORMATION TAG */
-#define SATK_IMEI_TAG 0x14 /* IMEI TAG */
-#define SATK_HELP_REQUEST_TAG 0x15 /* HELP REQUEST TAG */
-#define SATK_NETWORK_MEASUREMENT_RESULTS_TAG 0x16 /* NETWORK MEASUREMENT RESULTS TAG */
-#define SATK_DEFAULT_TEXT_TAG 0x17 /* DEFAULT TEXT TAG */
-#define SATK_ITEMS_NEXT_ACTION_INDICATOR_TAG 0x18 /* ITEMS NEXT ACTION INDICATOR TAG */
-#define SATK_EVENT_LIST_TAG 0x19 /* EVENT LIST TAG */
-#define SATK_CAUSE_TAG 0x1A /* CAUSE TAG */
-#define SATK_LOCATION_STATUS_TAG 0x1B /* LOCATION STATUS TAG */
-#define SATK_BCCH_CHANNEL_LIST_TAG 0x1D /* BCCH CHANNEL LIST TAG */
-#define SATK_ICON_IDENTIFIER_TAG 0x1E /* ICON IDENTIFIER TAG */
-#define SATK_ITEM_ICON_IDENTIFIER_LIST_TAG 0x1F /* ITEM ICON IDENTIFIER LIST TAG */
-#define SATK_DATE_TIME_AND_TIME_ZONE_TAG 0x26 /* DATE TIME AND TIME ZONE TAG */
-#define SATK_CALL_CONTROL_REQUESTED_ACTION_TAG 0x27 /* CALL CONTROL REQUESTED ACTION TAG */
-#define SATK_AT_COMMAND_TAG 0x28 /* AT COMMAND TAG */
-#define SATK_AT_RESPONSE_TAG 0x29 /* AT RESPONSE TAG */
-#define SATK_BC_REPEAT_INDICATOR_TAG 0x2A /* BC REPEAT INDICATOR TAG */
-#define SATK_IMMEDIATE_RESPONSE_TAG 0x2B /* IMMEDIATE RESPONSE TAG */
-#define SATK_DTMF_STRING_TAG 0x2C /* DTMF STRING TAG */
-#define SATK_LANGUAGE_TAG 0x2D /* LANGUAGE TAG */
-#define SATK_BROWSER_IDENTITY_TAG 0x30 /* BROWSER IDENTITY TAG */
-#define SATK_URL_TAG 0x31 /* URL TAG */
-#define SATK_BEARER_TAG 0x32 /* BEARER TAG */
-#define SATK_PROVISIONING_REF_FILE_TAG 0x33 /* PROVISIONING REFERENCE FILE TAG */
-#define SATK_BROWSER_TERMINATION_CAUSE_TAG 0x34 /* BROWSER TERMINATION CAUSE TAG */
-#define SATK_BEARER_DISCRIPTION_TAG 0x35 /* BEARER DISCRIPTION TAG */
-#define SATK_CHANNEL_DATA_TAG 0x36 /* CHANNEL DATA TAG */
-#define SATK_CHANNEL_DATA_LEN_TAG 0x37 /* CHANNEL DATA LEN TAG */
-#define SATK_CHANNEL_STATUS_TAG 0x38 /* CHANNEL STATUS TAG */
-#define SATK_BUFFER_SIZE_TAG 0x39 /* BUFFER SIZE TAG */
-#define SATK_CARD_READER_IDENTIFIER_TAG 0x3A /* CARD READER IDENTIFIER TAG */
-#define SATK_USIM_ME_INTERFACE_TRANSPORT_LEVEL_TAG 0x3C /* USIM ME INTERFACE TRANSPORT LEVEL */
-#define SATK_OTHER_ADDRESS_TAG 0x3E /* OTHER ADDRESS */
-#define SATK_NETWORK_ACCESS_TAG 0x47 /* NETWORK ACCESS NAME TAG */
-#define SATK_CDMA_SMS_TPDU_TAG 0x48 /* CDMA SMS TPDU TAG */
-#define SATK_REMOTE_ENTITY_ADDRESS_TAG 0x49 /* REMOTE ENTITY ADDRESS TAG */
-#define SATK_TEXT_ATTRIBUTE_TAG 0x50 /* TEXT ATTRIBUTE TAG */
-#define SATK_TEXT_ATTRIBUTE_LIST_TAG 0x51 /* TEXT ATTRIBUTE LIST TAG */
-
-/* general data object lengths */
-#define SATK_DCS_LENGTH 0x01
-#define SATK_COMMAND_DETAILS_LENGTH 0x03 /* COMMAND DETAILS LENGTH */
-#define SATK_DEVICE_IDENTITY_LENGTH 0x02 /* DEVICE IDENTITY LENGTH */
-#define SATK_ICON_IDENTITY_LENGTH 0x02 /* ICON IDENTITY LENGTH */
-#define SATK_DURATION_LENGTH 0x02 /* DURATION LENGTH */
-#define SATK_ITEM_IDENTIFIER_LENGTH 0x01 /* ITEM IDENTIFIER LENGTH */
-#define SATK_LOCATION_INFORMATION_LENGTH 0x07 /* LOCATION INFORMATION LENGTH */
-#define SATK_HELP_REQUEST_LENGTH 0x00 /* HELP REQUEST LENGTH */
-#define SATK_LOCATION_STATUS_LENGTH 0x01 /* LOCATION STATUS LENGTH */
-#define SATK_DATE_TIME_AND_TIME_ZONE_LENGTH 0x07 /* DATE TIME AND TIME ZONE LENGTH */
-#define SATK_LANGUAGE_LENGTH 0x02 /* LANGUAGE LENGTH */
-#define SATK_BC_REPEAT_IND_LENGTH 0x01 /* BC REPEAT INDICATION LENGTH */
-#define SATK_RESPONSE_LENGTH_LENGTH 0x02 /* RESPONSE LENGTH LENGTH */
-#define SATK_TONE_LENGTH 0x01 /* TONE LENGTH */
-#define SATK_BROWSER_ID_LENGTH 0x01 /* BROWSER ID LENGTH */
-#define SATK_BROWSER_TERMINATION_CAUSE_LENGTH 0x01 /* BROWSER TERMINATION CAUSE LENGTH */
-#define SATK_BUFFER_SIZE_LENGTH 0x02 /* BUFFER SIZE LENGTH */
-#define SATK_UICC_ME_TRANS_INTERFACE_LEVEL_LENGTH 0x03 /* UICC TERMINAL TRANSPORT INTERFACE LEVEL LENGTH */
-#define SATK_CHANNEL_DATA_LENGTH_VALUE_LENGTH 0x01 /* CHANNEL DATA LENGTH VALUE LENGTH */
-#define SATK_CHANNEL_STATUS_LENGTH 0x02 /* CHANNEL STATUS LENGTH */
-
-struct private_object_data {
- struct tcore_sat_operations *ops[TCORE_OPS_TYPE_MAX];
-};
-
-gboolean b_comprehensive = FALSE;
-
-static TReturn _dispatcher(CoreObject *o, UserRequest *ur, enum tcore_ops_type ops_type)
-{
- enum tcore_request_command command;
- struct private_object_data *po = tcore_object_ref_object(o);
- struct tcore_sat_operations *ops = NULL;
-
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_SAT, TCORE_RETURN_EINVAL);
- CORE_OBJECT_VALIDATE_OPS_RETURN_VAL(ops_type, TCORE_RETURN_EINVAL);
-
- tcore_check_null_ret_err("po", po, TCORE_RETURN_EINVAL);
- tcore_check_null_ret_err("ur", ur, TCORE_RETURN_EINVAL);
-
- ops = po->ops[ops_type];
- tcore_check_null_ret_err("ops", ops, TCORE_RETURN_FAILURE);
-
- command = tcore_user_request_get_command(ur);
- switch (command) {
- case TREQ_SAT_REQ_ENVELOPE:
- tcore_check_null_ret_err("ops->envelope",
- ops->envelope, TCORE_RETURN_ENOSYS);
-
- return ops->envelope(o, ur);
-
- case TREQ_SAT_REQ_TERMINALRESPONSE:
- tcore_check_null_ret_err("ops->terminal_response",
- ops->terminal_response, TCORE_RETURN_ENOSYS);
-
- return ops->terminal_response(o, ur);
-
- case TREQ_SAT_REQ_USERCONFIRMATION:
- tcore_check_null_ret_err("ops->user_confirmation",
- ops->user_confirmation, TCORE_RETURN_ENOSYS);
-
- return ops->user_confirmation(o, ur);
-
- default:
- break;
- }
-
- return TCORE_RETURN_SUCCESS;
-}
-
-static void _free_hook(CoreObject *o)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_SAT);
-
- po = tcore_object_ref_object(o);
- if (po) {
- free(po);
- tcore_object_link_object(o, NULL);
- }
-}
-
-static gboolean _check_file_for_refresh(enum tel_sim_file_id file_id)
-{
- int i;
- enum tel_sim_file_id ef_under_mf[3] = {SIM_EF_DIR, SIM_EF_ELP, SIM_EF_ICCID};
- enum tel_sim_file_id ef_under_df[29] = {
- SIM_EF_IMSI, SIM_EF_SST,
- SIM_EF_EST, SIM_EF_OPLMN_ACT,
- SIM_EF_GID1, SIM_EF_GID2,
- SIM_EF_LP, SIM_EF_ECC,
- SIM_EF_SPN, SIM_EF_SPDI,
- SIM_EF_PNN, SIM_EF_OPL,
- SIM_EF_MBDN, SIM_EF_MSISDN,
- SIM_EF_USIM_MBI, SIM_EF_USIM_MWIS,
- SIM_EF_USIM_CFIS, SIM_EF_CPHS_VOICE_MSG_WAITING,
- SIM_EF_CPHS_SERVICE_STRING_TABLE, SIM_EF_CPHS_CALL_FORWARD_FLAGS,
- SIM_EF_CPHS_OPERATOR_NAME_STRING, SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE,
- SIM_EF_CPHS_CPHS_INFO, SIM_EF_CPHS_MAILBOX_NUMBERS,
- SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING, SIM_EF_CPHS_INFORMATION_NUMBERS,
- SIM_EF_CPHS_DYNAMICFLAGS, SIM_EF_CPHS_DYNAMIC2FLAG,
- SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE_LINE2};
-
- dbg("[SAT] SAT PARSER - FILE ID=0x%04x", (unsigned int)file_id);
-
- if ((file_id & 0x2F00) == 0x2F00) {
- dbg("[SAT] SAT PARSER - MF, EF=0x%04x", file_id);
- for (i = 0; i < 3; i++) {
- if (file_id == ef_under_mf[i]) {
- dbg("[SAT] SAT PARSER - MATCH!");
- return TRUE;
- }
- }
- } else if ((file_id & 0x6F00) == 0x6F00) {
- dbg("[SAT] SAT PARSER - ADF_USIM EF=0x%04x", file_id);
- for (i = 0; i < 29; i++) {
- if (file_id == ef_under_df[i]) {
- dbg("[SAT] SAT PARSER - MATCH!");
- return TRUE;
- }
- }
- }
-
- return FALSE;
-}
-
-static int _get_length_filed_size(unsigned char firstLenByte)
-{
- if (firstLenByte <= 0x7F)
- return 1;
- else if (firstLenByte == 0x81)
- return 2;
- else
- return 0; /* return zero, as the length field can only be 1 or 2. */
-}
-
-static void _get_string_data(unsigned char *src, int len,
- struct tel_sat_text_string_object *text_obj)
-{
- if (!src || !text_obj) return;
-
- switch (text_obj->dcs.a_format) {
- case ALPHABET_FORMAT_SMS_DEFAULT: {
- char *unpacked_str;
-
- text_obj->string_length = 0;
- unpacked_str = (char *)tcore_util_unpack_gsm7bit(src, (unsigned int)len);
- if (!unpacked_str)
- return;
-
- text_obj->dcs.a_format = ALPHABET_FORMAT_8BIT_DATA;
- text_obj->string_length = strlen(unpacked_str);
-
- if (text_obj->string_length >= SAT_TEXT_STRING_LEN_MAX) {
- text_obj->string_length = SAT_TEXT_STRING_LEN_MAX;
- memcpy(text_obj->string, unpacked_str, SAT_TEXT_STRING_LEN_MAX);
- text_obj->string[SAT_TEXT_STRING_LEN_MAX] = 0x00;
- } else {
- memcpy(text_obj->string, unpacked_str, text_obj->string_length);
- text_obj->string[text_obj->string_length] = 0x00;
- }
-
- g_free(unpacked_str);
- }
- break;
-
- case ALPHABET_FORMAT_UCS2:
- case ALPHABET_FORMAT_8BIT_DATA: {
- text_obj->string_length = len;
- if (text_obj->string_length >= SAT_TEXT_STRING_LEN_MAX) {
- text_obj->string_length = SAT_TEXT_STRING_LEN_MAX;
- memcpy(text_obj->string, src, SAT_TEXT_STRING_LEN_MAX);
- text_obj->string[SAT_TEXT_STRING_LEN_MAX] = 0x00;
- } else {
- memcpy(text_obj->string, src, text_obj->string_length);
- text_obj->string[text_obj->string_length + 1] = 0x00;
- }
- }
- break;
-
- default: {
- dbg("[SAT] SAT PARSER - Unknown alphabet format(%d)", text_obj->dcs.a_format);
- }
- break;
- }
-}
-
-static void _sat_decode_dcs(unsigned char dcs, struct data_coding_scheme *dsc_obj)
-{
- dbg("[SAT] SAT PARSER - dcs=[0x%x]", dcs);
- dsc_obj->raw_dcs = dcs;
- /* bit 5 of DCS byte will tell us if the text is compressed or not. */
-
- if (dcs & 0x20)
- dsc_obj->is_compressed_format = TRUE;
- else
- dsc_obj->is_compressed_format = FALSE;
-
- /* bit 4 when set, indicates that bits 0 & 1 have message class meaning. */
- dsc_obj->m_class = MSG_CLASS_NONE;
- if (dcs & 0x10) {
- switch (dcs & 0x03) {
- case 0x00:
- dsc_obj->m_class = MSG_CLASS_0;
- break;
-
- case 0x01:
- dsc_obj->m_class = MSG_CLASS_1;
- break;
-
- case 0x02:
- dsc_obj->m_class = MSG_CLASS_2;
- break;
-
- case 0x03:
- dsc_obj->m_class = MSG_CLASS_3;
- break;
-
- default:
- err("invalid dcs type");
- break;
- }
- }
-
- /* bits 2 & 3 indicate the character set being used */
- switch (dcs & 0x0C) {
- case 0x00:
- case 0x0C:
- dsc_obj->a_format = ALPHABET_FORMAT_SMS_DEFAULT;
- break;
-
- case 0x04:
- dsc_obj->a_format = ALPHABET_FORMAT_8BIT_DATA;
- break;
-
- case 0X08:
- dsc_obj->a_format = ALPHABET_FORMAT_UCS2;
- break;
-
- default:
- dsc_obj->a_format = ALPHABET_FORMAT_RESERVED;
- break;
- }
-
- dbg("[SAT] SAT PARSER - is_compressed_format(%d), msgClass(0x%x), alpha_format(0x%x)",
- dsc_obj->is_compressed_format, dsc_obj->m_class, dsc_obj->a_format);
-}
-
-static void _sat_decode_ton_npi(unsigned char ton_npi, enum type_of_number *ton, enum numbering_plan_identifier *npi)
-{
- int ton_value = 0;
- int npi_value = 0;
-
- if (!ton || !npi)
- return;
-
- ton_value = (ton_npi & 0x70) >> 4;
- *ton = ton_value;
- if (*ton > TON_NETWORK_SPECIFIC)
- *ton = TON_RESERVED_FOR_EXT;
-
- npi_value = (ton_npi & 0x0F);
- switch (npi_value) {
- case NPI_ISDN_TEL:
- case NPI_DATA_NUMBERING_PLAN:
- case NPI_TELEX:
- case NPI_PRIVATE:
- case NPI_RESERVED_FOR_EXT:
- *npi = npi_value;
- break;
-
- default:
- *npi = NPI_UNKNOWN;
- break;
- }
-
- dbg("[SAT] SAT PATSER - ton(0x%x) npi(0x%x)", *ton, *npi);
-}
-
-static enum tel_sim_language_type _sat_decode_language(unsigned char byte1, unsigned char byte2)
-{
- if ((byte1 == 'e') && (byte2 == 'n'))
- return SIM_LANG_ENGLISH;
- else if ((byte1 == 'd') && (byte2 == 'e'))
- return SIM_LANG_GERMAN;
- else if ((byte1 == 'i') && (byte2 == 't'))
- return SIM_LANG_ITALIAN;
- else if ((byte1 == 'f') && (byte2 == 'r'))
- return SIM_LANG_FRENCH;
- else if ((byte1 == 'e') && (byte2 == 's'))
- return SIM_LANG_SPANISH;
- else if ((byte1 == 'n') && (byte2 == 'l'))
- return SIM_LANG_DUTCH;
- else if ((byte1 == 's') && (byte2 == 'v'))
- return SIM_LANG_SWEDISH;
- else if ((byte1 == 'd') && (byte2 == 'a'))
- return SIM_LANG_DANISH;
- else if ((byte1 == 'p') && (byte2 == 't'))
- return SIM_LANG_PORTUGUESE;
- else if ((byte1 == 'f') && (byte2 == 'i'))
- return SIM_LANG_FINNISH;
- else if ((byte1 == 'n') && (byte2 == 'o'))
- return SIM_LANG_NORWEGIAN;
- else if ((byte1 == 'e') && (byte2 == 'l'))
- return SIM_LANG_GREEK;
- else if ((byte1 == 't') && (byte2 == 'r'))
- return SIM_LANG_TURKISH;
- else if ((byte1 == 'h') && (byte2 == 'u'))
- return SIM_LANG_HUNGARIAN;
- else if ((byte1 == 'p') && (byte2 == 'i'))
- return SIM_LANG_POLISH;
- else {
- dbg("[SAT] SAT PARSER - unknown language, default to english.");
- return SIM_LANG_ENGLISH;
- }
-}
-
-/*
- * Decode TLV data object
- */
-static enum tcore_sat_result _sat_decode_address_tlv(unsigned char *tlv_str, int tlv_len,
- int curr_offset, struct tel_sat_address *address_obj, int *consumed_data_len)
-{
- unsigned char *src_data;
- int temp_index, len_of_len = 0;
- int address_len = 0;
- gboolean comprehensive_req = FALSE;
-
- if (tlv_str == NULL || consumed_data_len == NULL || address_obj == NULL) {
- dbg("[SAT] SAT PARSER - tlv_str == NULL || consumed_data_len == NULL || address_obj == NULL");
- return TCORE_SAT_ERROR_FATAL;
- }
-
- if (tlv_len <= (curr_offset + 1)) {
- dbg("[SAT] SAT PARSER - incorrect length original_command_len=%d", tlv_len);
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- /* tag */
- temp_index = curr_offset;
- src_data = &tlv_str[0];
- if ((src_data[temp_index] & 0x7F) != SATK_ADDRESS_TAG) {
- dbg("[SAT] SAT PARSER - address TAG missing");
- return TCORE_SAT_REQUIRED_VALUE_MISSING;
- }
-
- /* comprehensive required */
- if ((src_data[temp_index++] & 0x80))
- comprehensive_req = TRUE;
-
- /* length */
- len_of_len = _get_length_filed_size(src_data[temp_index]);
- if (!len_of_len) {
- dbg("[SAT] SAT PARSER - incorrect length");
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
- address_len = src_data[temp_index + len_of_len - 1];
-
- /* check the address length */
- temp_index += len_of_len;
- if ((temp_index + address_len) > tlv_len) {
- dbg("[SAT] SAT PARSER - incorrect length");
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- address_obj->dialing_number_len = 0;
- if (address_len > 1) {
- char *str_ascii = NULL;
- _sat_decode_ton_npi(src_data[temp_index++], &address_obj->ton, &address_obj->npi);
- str_ascii = tcore_util_convert_bcd2ascii((const char *)&src_data[temp_index], address_len - 1, SAT_DIALING_NUMBER_LEN_MAX);
- if (str_ascii) {
- memcpy(address_obj->dialing_number, str_ascii, strlen(str_ascii));
- address_obj->dialing_number_len = strlen(str_ascii);
- g_free(str_ascii);
- }
- }
-
- if (address_obj->dialing_number_len == 0) {
- if (comprehensive_req) {
- err("[SAT] SAT PARSER - incorrect address");
- return TCORE_SAT_REQUIRED_VALUE_MISSING;
- }
-
- dbg("comprehensive partial proactive command");
- /* global variable (comprehensive_partial= TRUE) */
- }
-
- *consumed_data_len = 1 + len_of_len + address_len;
- return TCORE_SAT_SUCCESS;
-}
-
-static enum tcore_sat_result _sat_decode_subaddress_tlv(unsigned char *tlv_str, int tlv_len,
- int curr_offset, struct tel_sat_subaddress *sub_address_obj, int *consumed_data_len)
-{
- unsigned char *src_data;
- int temp_index, len_of_len = 0;
- int sub_address_len = 0;
- gboolean comprehensive_req = FALSE;
-
- if (tlv_str == NULL || consumed_data_len == NULL || sub_address_obj == NULL) {
- dbg("[SAT] SAT PARSER - tlv_str == NULL || consumed_data_len == NULL || sub_address_obj == NULL");
- return TCORE_SAT_ERROR_FATAL;
- }
-
- if (tlv_len <= (curr_offset + 1)) {
- dbg("[SAT] SAT PARSER - incorrect length original_command_len=%d", tlv_len);
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- /* tag */
- temp_index = curr_offset;
- src_data = &tlv_str[0];
- if ((src_data[temp_index] & 0x7F) != SATK_SUB_ADDRESS_TAG) {
- dbg("[SAT] SAT PARSER - sub address TAG missing");
- return TCORE_SAT_REQUIRED_VALUE_MISSING;
- }
-
- /* comprehensive required */
- if ((src_data[temp_index++] & 0x80))
- comprehensive_req = TRUE;
-
- /* length */
- len_of_len = _get_length_filed_size(src_data[temp_index]);
- if (!len_of_len) {
- dbg("[SAT] SAT PARSER - incorrect length");
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- sub_address_len = src_data[temp_index + len_of_len - 1];
-
- /* check the address length */
- temp_index += len_of_len;
- if ((temp_index + sub_address_len) > tlv_len) {
- dbg("[SAT] SAT PARSER - incorrect length");
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- /* sub address */
- if (sub_address_len <= 0) {
- dbg("[SAT] SAT PARSER - no sub address data");
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- sub_address_obj->subaddress_len = sub_address_len;
- if (sub_address_obj->subaddress_len > SAT_CCP_DATA_LEN_MAX) {
- if (comprehensive_req) {
- dbg("[SAT] SAT PARSER - sub address is too big");
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- } else {
- /* bIsComprehensionPartial = TRUE; */
- sub_address_obj->subaddress_len = 0;
- }
- } else
- memcpy(sub_address_obj->subaddress, &src_data[temp_index], sub_address_obj->subaddress_len);
-
- *consumed_data_len = 1 + len_of_len + sub_address_len;
- return TCORE_SAT_SUCCESS;
-}
-
-static enum tcore_sat_result _sat_decode_alpha_identifier_tlv(unsigned char *tlv_str, int tlv_len,
- int curr_offset, struct tel_sat_alpha_identifier *alpha_id_obj, int *consumed_data_len)
-{
- unsigned char *src_data;
- int temp_index, len_of_len = 0;
- int alpha_len = 0;
-
- if (tlv_str == NULL || consumed_data_len == NULL || alpha_id_obj == NULL) {
- dbg("[SAT] SAT PARSER - tlv_str == NULL || consumed_data_len == NULL || alpha_id_obj == NULL");
- return TCORE_SAT_ERROR_FATAL;
- }
-
- if (tlv_len <= (curr_offset + 1)) {
- dbg("[SAT] SAT PARSER - incorrect length original_command_len=%d", tlv_len);
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- /* tag */
- temp_index = curr_offset;
- src_data = &tlv_str[0];
- if ((src_data[temp_index++] & 0x7F) != SATK_ALPHA_IDENTIFIER_TAG) {
- dbg("[SAT] SAT PARSER - alphaID TAG missing");
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- /* length */
- alpha_id_obj->is_exist = TRUE;
- len_of_len = _get_length_filed_size(src_data[temp_index]);
- if (!len_of_len) {
- dbg("[SAT] SAT PARSER - incorrect length");
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- alpha_len = alpha_id_obj->alpha_data_len = src_data[temp_index + len_of_len - 1];
-
- /* alpha identifier */
- temp_index += len_of_len;
- if ((temp_index + alpha_len) > tlv_len) {
- dbg("[SAT] SAT PARSER - incorrect length");
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- if (alpha_id_obj->alpha_data_len > 0) {
-
- unsigned char dcs;
-
- if (alpha_id_obj->alpha_data_len >= SAT_ALPHA_ID_LEN_MAX)
- alpha_id_obj->alpha_data_len = SAT_ALPHA_ID_LEN_MAX - 1;
-
- memcpy(alpha_id_obj->alpha_data, &src_data[temp_index], alpha_id_obj->alpha_data_len);
- alpha_id_obj->alpha_data[alpha_id_obj->alpha_data_len] = 0x00;
-
- if (src_data[temp_index] == 0x80 || src_data[temp_index] == 0x81 || src_data[temp_index] == 0x82)
- dcs = 0X08;
- else
- dcs = 0x04;
-
- _sat_decode_dcs(dcs, &alpha_id_obj->dcs);
- }
-
- *consumed_data_len = 1 + len_of_len + alpha_len;
- dbg("[SAT] SAT PARSER alphaId= %s", alpha_id_obj->alpha_data);
- return TCORE_SAT_SUCCESS;
-}
-
-static enum tcore_sat_result _sat_decode_sub_address_tlv(unsigned char *tlv_str, int tlv_len,
- int curr_offset, struct tel_sat_subaddress *sub_address_obj, int *consumed_data_len)
-{
- int i = 0;
- int temp_index, len_of_len = 0;
- int sub_address_len = 0;
- unsigned char *src_data;
- gboolean comprehension_req = FALSE;
-
- if (tlv_str == NULL || consumed_data_len == NULL || sub_address_obj == NULL) {
- dbg("[SAT] SAT PARSER - tlv_str == NULL || consumed_data_len == NULL || sub_address_obj == NULL");
- return TCORE_SAT_ERROR_FATAL;
- }
-
- if (tlv_len <= (curr_offset + 1)) {
- dbg("[SAT] SAT PARSER - incorrect length original_command_len=%d", tlv_len);
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- /* tag */
- temp_index = curr_offset;
- src_data = &tlv_str[0];
- if ((src_data[temp_index] & 0x7F) != SATK_SUB_ADDRESS_TAG) {
- dbg("[SAT] SAT PARSER - address TAG missing");
- return TCORE_SAT_REQUIRED_VALUE_MISSING;
- }
-
- /* comprehensive required */
- if ((src_data[temp_index++] & 0x80))
- comprehension_req = TRUE;
-
- /* length */
- len_of_len = _get_length_filed_size(src_data[temp_index]);
- if (!len_of_len) {
- dbg("[SAT] SAT PARSER - incorrect length");
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
- sub_address_len = src_data[temp_index + len_of_len - 1];
-
- /* check the address length */
- temp_index += len_of_len;
- if ((temp_index + sub_address_len) > tlv_len) {
- dbg("[SAT] SAT PARSER - incorrect length");
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- if (sub_address_len <= 0) {
- dbg("[SAT] SAT PARSER - no sub address");
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- sub_address_obj->subaddress_len = sub_address_len;
- if (sub_address_obj->subaddress_len > SAT_SUB_ADDR_LEN_MAX) {
- if (comprehension_req)
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- else
- sub_address_obj->subaddress_len = 0;
- } else
- memcpy(sub_address_obj->subaddress, &src_data[temp_index], sub_address_obj->subaddress_len);
-
- dbg("[SAT] SAT PARSER - subAddressLen=%d", sub_address_obj->subaddress_len);
- for (i = 0; i < sub_address_obj->subaddress_len; i++)
- dbg("[SAT] SAT PARSER - 0x%02x\t", sub_address_obj->subaddress[i]);
-
- *consumed_data_len = 1 + len_of_len + sub_address_len;
- return TCORE_SAT_SUCCESS;
-}
-
-static enum tcore_sat_result _sat_decode_ccp_tlv(unsigned char *tlv_str, int tlv_len,
- int curr_offset, struct tel_sat_ccp *ccp_obj, int *consumed_data_len)
-{
- int i = 0;
- int temp_index, len_of_len = 0;
- int ccp_len = 0;
- unsigned char *src_data;
- gboolean comprehension_req = FALSE;
-
- if (tlv_str == NULL || consumed_data_len == NULL || ccp_obj == NULL) {
- dbg("[SAT] SAT PARSER - tlv_str == NULL || consumed_data_len == NULL || ccp_obj == NULL");
- return TCORE_SAT_ERROR_FATAL;
- }
-
- if (tlv_len <= (curr_offset + 1)) {
- dbg("[SAT] SAT PARSER - incorrect length original_command_len=%d", tlv_len);
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- /* tag */
- temp_index = curr_offset;
- src_data = &tlv_str[0];
- if ((src_data[temp_index] & 0x7F)
- != SATK_CAPABILITY_CONFIGURATION_PARAMETERS_TAG) {
- dbg("[SAT] SAT PARSER - CCP TAG missing");
- return TCORE_SAT_REQUIRED_VALUE_MISSING;
- }
-
- /* comprehensive required */
- if ((src_data[temp_index++] & 0x80))
- comprehension_req = TRUE;
-
- /* length */
- len_of_len = _get_length_filed_size(src_data[temp_index]);
- if (!len_of_len) {
- dbg("[SAT] SAT PARSER - incorrect length");
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- ccp_len = src_data[temp_index + len_of_len - 1];
-
- /* check the address length */
- temp_index += len_of_len;
- if ((temp_index + ccp_len) > tlv_len) {
- dbg("[SAT] SAT PARSER - incorrect length");
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- if (ccp_len <= 0) {
- dbg("[SAT] SAT PARSER - no ccp data");
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- ccp_obj->data_len = ccp_len;
- if (ccp_obj->data_len > SAT_CCP_DATA_LEN_MAX) {
- if (comprehension_req)
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- else
- ccp_obj->data_len = 0;
- } else
- memcpy(ccp_obj->data, &src_data[temp_index], ccp_obj->data_len);
-
- dbg("[SAT] SAT PARSER - ccp len=%d", ccp_obj->data_len);
- for (i = 0; i < ccp_obj->data_len; i++)
- dbg("[SAT] SAT PARSER - 0x%02x\t", ccp_obj->data[i]);
-
- *consumed_data_len = 1 + len_of_len + ccp_len;
- return TCORE_SAT_SUCCESS;
-}
-
-static enum tcore_sat_result _sat_decode_device_identities_tlv(unsigned char *tlv_str,
- struct tel_sat_device_identities *dev_id_obj)
-{
- int temp_index = 0, i;
-
- if (tlv_str == NULL || dev_id_obj == NULL) {
- dbg("[SAT] SAT PARSER - tlv_str == NULL || dev_id_obj == NULL");
- return TCORE_SAT_ERROR_FATAL;
- }
-
- if ((tlv_str[temp_index++] & 0x7F) != SATK_DEVICE_IDENTITY_TAG) {
- dbg("[SAT] SAT PARSER - device identity tag missing.");
- return TCORE_SAT_REQUIRED_VALUE_MISSING; /* Send TR */
- }
-
- if (tlv_str[temp_index++] != SATK_DEVICE_IDENTITY_LENGTH) {
- dbg("[SAT] SAT PARSER - device identity length incorrect.");
- return TCORE_SAT_REQUIRED_VALUE_MISSING; /* Send TR */
- }
-
- for (i = 0; i < 2; i++) {
- switch (tlv_str[temp_index]) {
- case DEVICE_ID_KEYPAD:
- case DEVICE_ID_DISPLAY:
- case DEVICE_ID_EARPIECE:
- case DEVICE_ID_SIM:
- case DEVICE_ID_ME:
- case DEVICE_ID_NETWORK:
- if (i == 0) dev_id_obj->src = tlv_str[temp_index];
- if (i == 1) dev_id_obj->dest = tlv_str[temp_index];
- break;
-
- default:
- if (tlv_str[temp_index] >= 0x21 && tlv_str[temp_index] <= 0x27) {
- dbg("BIP channel id(0x%x)", tlv_str[temp_index]);
- if (i == 0) dev_id_obj->src = tlv_str[temp_index];
- if (i == 1) dev_id_obj->dest = tlv_str[temp_index];
- } else {
- dbg("unmatched device id");
- return TCORE_SAT_REQUIRED_VALUE_MISSING;
- }
- break;
- }
-
- temp_index++;
- }
-
- dbg("[SAT] SAT PARSER - source=%d, dest=%d", dev_id_obj->src, dev_id_obj->dest);
- return TCORE_SAT_SUCCESS;
-}
-
-static enum tcore_sat_result _sat_decode_duration_tlv(unsigned char *tlv_str, int tlv_len,
- int curr_offset, struct tel_sat_duration *duration_obj, int *consumed_data_len)
-{
- int temp_index = 0;
- unsigned char *src_data = NULL;
-
- if (!tlv_str || !duration_obj || !consumed_data_len) {
- err("[SAT] SAT PARSER data is null");
- return TCORE_SAT_ERROR_FATAL;
- }
-
- if (tlv_len < curr_offset + 3) {
- err("[SAT] SAT PARSER - incorrect length original_command_len=%d", tlv_len);
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- temp_index = curr_offset;
- src_data = &tlv_str[0];
- if ((src_data[temp_index++] & 0x7F) != SATK_DURATION_TAG) {
- err("[SAT] SAT PARSER - duration tag missing.");
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; /* Send TR */
- }
-
- if (src_data[temp_index++] != SATK_DURATION_LENGTH) {
- err("[SAT] SAT PARSER - incorrect length value.");
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; /* Send TR */
- }
-
- /* time unit */
- switch (src_data[temp_index]) {
- case TIME_UNIT_MINUTES:
- case TIME_UNIT_SECONDS:
- case TIME_UNIT_TENTHS_OF_SECONDS:
- duration_obj->time_unit = src_data[temp_index];
- break;
-
- default:
- duration_obj->time_unit = TIME_UNIT_RESERVED;
- break;
- }
-
- /* interval */
- temp_index++;
- duration_obj->time_interval = src_data[temp_index];
- *consumed_data_len = 4;
-
- dbg("[SAT] SAT PARSER - timeUnit=%d, interval=%d",
- duration_obj->time_unit, duration_obj->time_interval);
-
- return TCORE_SAT_SUCCESS;
-}
-
-static enum tcore_sat_result _sat_decode_item_tlv(unsigned char *tlv_str, int tlv_len,
- int curr_offset, struct tel_sat_item_info *item_obj, int *consumed_data_len)
-{
- int temp_index, len_of_len = 0, i = 0;
- int item_len = 0;
- unsigned char dcs;
- unsigned char *src_data = NULL;
-
- if (tlv_str == NULL || consumed_data_len == NULL || item_obj == NULL) {
- dbg("[SAT] SAT PARSER - tlv_str == NULL || consumed_data_len == NULL || item_obj == NULL");
- return TCORE_SAT_ERROR_FATAL;
- }
-
- if (tlv_len <= (curr_offset + 1)) {
- dbg("[SAT] SAT PARSER - incorrect length original_command_len=%d", tlv_len);
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- /* tag */
- temp_index = curr_offset;
- src_data = &tlv_str[0];
- if ((src_data[temp_index++] & 0x7F) != SATK_ITEM_TAG) {
- dbg("[SAT] SAT PARSER - tag not found.=%d", src_data[temp_index-1]);
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- /* length */
- len_of_len = _get_length_filed_size(src_data[temp_index]);
- if (!len_of_len) {
- dbg("[SAT] SAT PARSER - incorrect length");
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- item_len = src_data[temp_index + len_of_len-1];
-
- temp_index += len_of_len; /* temp_index pointing to item. */
- if ((temp_index + item_len) > tlv_len) {
- dbg("[SAT] SAT PARSER - incorrect length");
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- memset(item_obj->text, 0x00, (SAT_ITEM_TEXT_LEN_MAX + 1));
- if (item_len <= 0) {
- dbg("[SAT] SAT PARSER - menu_text is NULL, remove the menu");
- *consumed_data_len = 1 + len_of_len + item_len;
- return TCORE_SAT_SUCCESS;
- }
-
- /* item */
- item_obj->item_id = src_data[temp_index++];
-
- /*
- * fix for orange SIM issue
- * H0100078487 Strange Character display on SIM SAT
- * The string length was less than its real length
- * So garbage characters was displayed. To fix it, we would recalculate the real length.
- */
- for (i = 0; i < item_len-1; i++) {
- dbg("[SAT] %d: %c", i, src_data[temp_index + i]);
- if (src_data[temp_index + i] == 0xFF) break;
- }
-
- item_obj->text_len = i;
-
- if (item_obj->text_len <= 0) {
- dbg("[SAT] SAT PARSER - text len = 0");
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- if (item_obj->text_len >= SAT_ITEM_TEXT_LEN_MAX)
- item_obj->text_len = SAT_ITEM_TEXT_LEN_MAX-1;
-
- memcpy(item_obj->text, &src_data[temp_index], item_obj->text_len);
- if (src_data[temp_index] == 0x80 || src_data[temp_index] == 0x81 || src_data[temp_index] == 0x82)
- dcs = 0X08;
- else
- dcs = 0x04;
-
- _sat_decode_dcs(dcs, &item_obj->dcs);
-
-
- dbg("[SAT] SAT PARSER - item_text=%s", item_obj->text);
- *consumed_data_len = 1 + len_of_len + item_len;
- return TCORE_SAT_SUCCESS;
-}
-
-static enum tcore_sat_result _sat_decode_response_length_tlv(unsigned char *tlv_str, int tlv_len,
- int curr_offset, struct tel_sat_response_length *response_obj, int *consumed_data_len)
-{
- int temp_index = 0;
- unsigned char *src_data = NULL;
-
- if (!tlv_str || !response_obj || !consumed_data_len) {
- err("[SAT] SAT PARSER data is null");
- return TCORE_SAT_ERROR_FATAL;
- }
-
- if (tlv_len <= curr_offset + 1) {
- err("[SAT] SAT PARSER - incorrect length original_command_len=%d", tlv_len);
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- temp_index = curr_offset;
- src_data = &tlv_str[0];
- if ((src_data[temp_index++] & 0x7F) != SATK_RESPONSE_LENGTH_TAG) {
- err("[SAT] SAT PARSER - response length tag missing.");
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; /* Send TR */
- }
-
- if (src_data[temp_index++] != SATK_RESPONSE_LENGTH_LENGTH) {
- err("[SAT] SAT PARSER - incorrect length value.");
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; /* Send TR */
- }
-
- response_obj->min = src_data[temp_index++];
- response_obj->max = src_data[temp_index++];
- dbg("[SAT] SAT PARSER min length(%d), max length(%d)", response_obj->min, response_obj->max);
-
- *consumed_data_len = 4;
- if (response_obj->min > response_obj->max) {
- err("[SAT] SAT PARSER - : min length is larger than max length");
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- return TCORE_SAT_SUCCESS;
-}
-
-static enum tcore_sat_result _sat_decode_sms_tpdu_tlv(unsigned char *tlv_str, int tlv_len,
- int curr_offset, struct tel_sat_sms_tpdu *sms_tpdu_obj, int *consumed_data_len)
-{
- int temp_index = 0, len_of_len = 0;
- int tpdu_len = 0;
- unsigned char *src_data = NULL;
-
- if (!tlv_str || !sms_tpdu_obj || !consumed_data_len) {
- err("[SAT] SAT PARSER data is null");
- return TCORE_SAT_ERROR_FATAL;
- }
-
- if (tlv_len <= curr_offset + 1) {
- err("[SAT] SAT PARSER - incorrect length original_command_len=%d", tlv_len);
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- temp_index = curr_offset;
- src_data = &tlv_str[0];
- if ((src_data[temp_index++] & 0x7F) != SATK_SMS_TPDU_TAG) {
- err("[SAT] SAT PARSER - sat tpdu tag missing.");
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- /* length */
- len_of_len = _get_length_filed_size(src_data[temp_index]);
- if (!len_of_len) {
- err("[SAT] parser: invalid length.");
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
- tpdu_len = src_data[temp_index + len_of_len-1];
- temp_index += len_of_len;
-
- if (tpdu_len <= 0)
- return TCORE_SAT_REQUIRED_VALUE_MISSING;
-
- /* data len */
- sms_tpdu_obj->data_len = tpdu_len;
- if (sms_tpdu_obj->data_len > SAT_SMS_TPDU_SMS_DATA_LEN_MAX)
- sms_tpdu_obj->data_len = SAT_SMS_TPDU_SMS_DATA_LEN_MAX;
-
- /* data */
- memcpy(sms_tpdu_obj->data, &src_data[temp_index], sms_tpdu_obj->data_len);
- dbg("[SAT] SAT PARSER tpdu_len (%d)", sms_tpdu_obj->data_len);
-
- *consumed_data_len = 1 + len_of_len + tpdu_len;
- return TCORE_SAT_SUCCESS;
-}
-
-static enum tcore_sat_result _sat_decode_item_identifier_tlv(unsigned char *tlv_str, int tlv_len,
- int curr_offset, struct tel_sat_item_identifier *item_identifier_obj, int *consumed_data_len)
-{
- int temp_index = 0;
- unsigned char *src_data = NULL;
-
- if (!tlv_str || !item_identifier_obj || !consumed_data_len) {
- err("[SAT] SAT PARSER data is null");
- return TCORE_SAT_ERROR_FATAL;
- }
-
- if (tlv_len <= curr_offset + 1) {
- err("[SAT] SAT PARSER - incorrect length original_command_len=%d", tlv_len);
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- temp_index = curr_offset;
- src_data = &tlv_str[0];
- if ((src_data[temp_index++] & 0x7F) != SATK_ITEM_IDENTIFIER_TAG) {
- err("[SAT] SAT PARSER - Item identifier tag missing.");
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; /* Send TR */
- }
-
- if (src_data[temp_index++] != SATK_ITEM_IDENTIFIER_LENGTH) {
- err("[SAT] SAT PARSER - incorrect length value.");
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; /* Send TR */
- }
-
- item_identifier_obj->item_identifier = src_data[temp_index++];
- *consumed_data_len = 3;
- dbg("[SAT] SAT PARSER item identifier(0x%02x)", item_identifier_obj->item_identifier);
-
- return TCORE_SAT_SUCCESS;
-}
-
-static enum tcore_sat_result _sat_decode_ss_string_tlv(unsigned char *tlv_str, int tlv_len,
- int curr_offset, struct tel_sat_ss_string *ss_str_obj, int *consumed_data_len)
-{
- char *str_ascii = NULL;
- int temp_index, len_of_len = 0;
- int ss_len = 0;
- unsigned char *src_data;
- gboolean comprehension_req = FALSE;
-
- if (!tlv_str || !ss_str_obj || !consumed_data_len) {
- err("[SAT] SAT PARSER data is null");
- return TCORE_SAT_ERROR_FATAL;
- }
-
- if (tlv_len <= curr_offset + 1) {
- err("[SAT] SAT PARSER - incorrect length original_command_len=%d", tlv_len);
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- temp_index = curr_offset;
- src_data = &tlv_str[0];
- if ((src_data[temp_index] & 0x7F) != SATK_SS_STRING_TAG) {
- err("[SAT] SAT PARSER - SS string tag missing.");
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; /* Send TR */
- }
-
- if (src_data[temp_index++] & 0x80)
- comprehension_req = TRUE;
-
- dbg("comprehension_req=[%d]", comprehension_req);
-
- /* length */
- len_of_len = _get_length_filed_size(src_data[temp_index]);
- if (!len_of_len) {
- err("[SAT] parser: invalid length.");
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- ss_len = src_data[temp_index + len_of_len-1];
- dbg("[SAT] parser: ss_tlv len=%d", ss_len);
-
- temp_index += len_of_len;
- ss_str_obj->string_len = 0;
-
- /* ss data */
- if (ss_len <= 1)
- return TCORE_SAT_REQUIRED_VALUE_MISSING;
-
- _sat_decode_ton_npi(src_data[temp_index++], &ss_str_obj->ton, &ss_str_obj->npi);
- str_ascii = tcore_util_convert_bcd2ascii((const char *)&src_data[temp_index], ss_len-1, SAT_SS_STRING_LEN_MAX);
- if (str_ascii) {
- memcpy(ss_str_obj->ss_string, str_ascii, strlen(str_ascii));
- ss_str_obj->string_len = strlen(str_ascii);
- g_free(str_ascii);
- }
-
- /* 1 is the length of Tag. */
- *consumed_data_len = 1 + len_of_len + ss_len;
- return TCORE_SAT_SUCCESS;
-}
-
-static enum tcore_sat_result _sat_decode_text_tlv(unsigned char *tlv_str, int tlv_len,
- int curr_offset, struct tel_sat_text_string_object *text_obj, int *consumed_data_len)
-{
- int temp_index, len_of_len = 0;
- int text_len = 0;
- unsigned char *src_data;
- gboolean comprehension_req = FALSE;
-
- if (!tlv_str || !consumed_data_len) {
- err("[SAT] parser: data is null");
- return TCORE_SAT_ERROR_FATAL;
- }
-
- if (tlv_len <= (curr_offset + 1)) {
- err("[SAT] parser: incorrect length");
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- /* tag */
- temp_index = curr_offset;
- src_data = &tlv_str[0];
- if ((src_data[temp_index] & 0x7F) != SATK_TEXT_STRING_TAG
- && (src_data[temp_index] & 0x7F) != SATK_DEFAULT_TEXT_TAG) {
- err("[SAT] parser: text string tag missing, tag=0x%x",
- src_data[temp_index]);
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- if (src_data[temp_index++] & 0x80)
- comprehension_req = TRUE;
-
- dbg("comprehension_req=[%d]", comprehension_req);
-
- /* length */
- len_of_len = _get_length_filed_size(src_data[temp_index]);
- if (!len_of_len) {
- err("[SAT] parser: invalid length.");
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- text_len = src_data[temp_index + len_of_len-1];
- temp_index += len_of_len;
- memset(text_obj->string, 0x00, SAT_TEXT_STRING_LEN_MAX);
-
- /* text */
- if (text_len <= 1) {
- text_obj->string_length = 0;
- } else {
- _sat_decode_dcs(src_data[temp_index++], &text_obj->dcs);
- _get_string_data(&src_data[temp_index], text_len-1, text_obj);
- }
-
- dbg("[SAT] parser: text_tlv_len=%d, parsed text length=%d", text_len, text_obj->string_length);
-
- /* 1 is the length of Tag. */
- *consumed_data_len = 1 + len_of_len + text_len;
-
- return TCORE_SAT_SUCCESS;
-}
-
-static enum tcore_sat_result _sat_decode_tone_tlv(unsigned char *tlv_str, int tlv_len,
- int curr_offset, struct tel_sat_tone *tone_obj, int *consumed_data_len)
-{
- int temp_index;
- unsigned char *src_data;
- gboolean comprehension_req = FALSE;
-
- if (tlv_str == NULL || consumed_data_len == NULL || tone_obj == NULL) {
- dbg("[SAT] SAT PARSER - tlv_str == NULL || consumed_data_len == NULL || tone_obj == NULL");
- return TCORE_SAT_ERROR_FATAL;
- }
-
- if (tlv_len <= (curr_offset + 1)) {
- dbg("[SAT] SAT PARSER - incorrect length original_command_len=%d", tlv_len);
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- /* tag */
- temp_index = curr_offset;
- src_data = &tlv_str[0];
- if ((src_data[temp_index] & 0x7F) != SATK_TONE_TAG) {
- err("[SAT] parser: tone tag missing");
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- if (src_data[temp_index++] & 0x80)
- comprehension_req = TRUE;
-
- /* length */
- if (src_data[temp_index++] != SATK_TONE_LENGTH) {
- err("[SAT] SAT PARSER - incorrect length value.");
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; /* Send TR */
- }
-
- if ((temp_index + SATK_TONE_LENGTH) > tlv_len) {
- err("[SAT] SAT PARSER - incorrect cmd len, expected len = %d, orig_len=%d",
- (temp_index + SATK_TONE_LENGTH), tlv_len);
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- /* tone */
- switch (src_data[temp_index]) {
- /* standard supervisory tones */
- case DIAL_TONE:
- case CALLED_SUBSCRIBER_BUSY:
- case CONGESTION:
- case RADIO_PATH_ACK:
- case RADIO_PATH_NOT_AVAILABLE_CALL_DROPPED:
- case ERR_SPECIAL_INFO:
- case CALL_WAITING_TONE:
- case RINGING_TONE:
- /* ME proprietary tones */
- case GENERAL_BEEP:
- case POSITIVE_ACK_TONE:
- case NEGATIVE_ACK_OR_ERROR_TONE:
- case RINGING_TONE_SLCTD_BY_USR_FOR_INCOM_SPEECH_CALL:
- case ALERT_TONE_SELECTED_BY_USER_FOR_INCOMING_SMS:
- case CRITICAL_ALERT:
- /* Themed tones */
- case HAPPY_TONE:
- case SAD_TONE:
- case URGENT_ACTION_TONE:
- case QUESTION_TONE:
- case MESSAGE_RECEIVED_TONE:
- /* Melody tones */
- case MELODY_1:
- case MELODY_2:
- case MELODY_3:
- case MELODY_4:
- case MELODY_5:
- case MELODY_6:
- case MELODY_7:
- case MELODY_8:
- dbg("[SAT] SAT PARSER - Tone =0x%x", src_data[temp_index]);
- tone_obj->tone_type = src_data[temp_index];
- break;
-
- case TONE_TYPE_RESERVED: /* Fallthrough */
- default:
- dbg("[SAT] SAT PARSER - Reserved value of Tone =0x%x", src_data[temp_index]);
- if (comprehension_req)
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- break;
- }
-
- *consumed_data_len = 3;
- return TCORE_SAT_SUCCESS;
-}
-
-static enum tcore_sat_result _sat_decode_ussd_string_tlv(unsigned char *tlv_str, int tlv_len,
- int curr_offset, struct tel_sat_ussd_string *ussd_str_obj, int *consumed_data_len)
-{
- int temp_index, len_of_len = 0;
- int ussd_len = 0;
- unsigned char *src_data;
- gboolean comprehension_req = FALSE;
-
- if (!tlv_str || !ussd_str_obj || !consumed_data_len) {
- err("[SAT] SAT PARSER data is null");
- return TCORE_SAT_ERROR_FATAL;
- }
-
- if (tlv_len <= curr_offset + 1) {
- err("[SAT] SAT PARSER - incorrect length original_command_len=%d", tlv_len);
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- temp_index = curr_offset;
- src_data = &tlv_str[0];
- if ((src_data[temp_index] & 0x7F) != SATK_USSD_STRING_TAG) {
- err("[SAT] SAT PARSER - SS string tag missing.");
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; /* Send TR */
- }
-
- if (src_data[temp_index++] & 0x80)
- comprehension_req = TRUE;
-
- dbg("comprehension_req=[%d]", comprehension_req);
-
- /* length */
- len_of_len = _get_length_filed_size(src_data[temp_index]);
- if (!len_of_len) {
- err("[SAT] parser: invalid length.");
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- ussd_len = src_data[temp_index + len_of_len-1];
- dbg("[SAT] parser: ussd_tlv len=%d", ussd_len);
-
- temp_index += len_of_len;
- ussd_str_obj->string_len = 0;
-
- /* ussd data */
- if (ussd_len <= 1)
- return TCORE_SAT_REQUIRED_VALUE_MISSING;
-
- _sat_decode_dcs(src_data[temp_index++], &ussd_str_obj->dsc);
- ussd_str_obj->string_len = ussd_len - 1;
- memcpy(ussd_str_obj->ussd_string, &src_data[temp_index], ussd_str_obj->string_len);
-
- /* 1 is the length of Tag. */
- *consumed_data_len = 1 + len_of_len + ussd_len;
- return TCORE_SAT_SUCCESS;
-}
-
-static enum tcore_sat_result _sat_decode_file_list_tlv(unsigned char *tlv_str, int tlv_len,
- int curr_offset, struct tel_sat_file_list *file_list_obj, int *consumed_data_len)
-{
- /* tmp */
- int tmp_cnt;
- int f_count;
- unsigned int ef = 0x0000;
-
- int temp_index, len_of_len = 0;
- int file_list_len = 0;
- unsigned char *src_data;
-
- if (tlv_str == NULL || consumed_data_len == NULL || file_list_obj == NULL) {
- dbg("[SAT] SAT PARSER - tlv_str == NULL || consumed_data_len == NULL || file_list_obj == NULL");
- return TCORE_SAT_ERROR_FATAL;
- }
-
- if (tlv_len <= (curr_offset + 1)) {
- dbg("[SAT] SAT PARSER - incorrect length original_command_len=%d", tlv_len);
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- /* tag */
- temp_index = curr_offset;
- src_data = &tlv_str[0];
- if ((src_data[temp_index] & 0x7F) != SATK_FILE_LIST_TAG) {
- err("[SAT] parser: tag missing, tag=0x%x", src_data[temp_index]);
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- /* length */
- len_of_len = _get_length_filed_size(src_data[temp_index]);
- if (!len_of_len) {
- err("[SAT] parser: invalid length.");
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- file_list_len = src_data[temp_index + len_of_len-1];
- temp_index += len_of_len;
-
- if ((temp_index + file_list_len) > tlv_len) {
- dbg("[SAT] SAT PARSER - incorrect cmd len, expected len = %d, orig_len=%d",
- (temp_index + file_list_len), tlv_len);
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- tmp_cnt = src_data[temp_index++];
- file_list_obj->file_count = 0;
- memset(file_list_obj->file_id, 0, SAT_FILE_ID_LIST_MAX_COUNT);
-
- if (!tmp_cnt) {
- dbg("file cnt = 0");
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- f_count = 0;
- do {
- ef = 0x0000;
- if (src_data[temp_index] != 0x3F || src_data[temp_index + 1] != 0x00) {
- temp_index++;
- if (temp_index > tlv_len)
- break;
- else
- continue;
- }
-
- temp_index += 2; /* MASTER FILE (DIR) 0x3F00 */
-
- if (src_data[temp_index] == 0x2F) {
- /* ELEMENTRY FILE (VALUE) */
- ef = src_data[temp_index] << 8;
- temp_index++;
- ef = ef | src_data[temp_index];
-
- if (_check_file_for_refresh((enum tel_sim_file_id)ef)) {/* check file registered for refresh? */
- file_list_obj->file_id[file_list_obj->file_count] = ef;
- file_list_obj->file_count++;
- }
- } else if (src_data[temp_index] == 0x7F && src_data[temp_index + 1] == 0xFF) {
- /* USIM DIRECTORY FILE (DIR) 0x7FFF */
- temp_index += 2;
- if (src_data[temp_index] == 0x6F) {
- ef = 0x6A << 8;
- temp_index++;
- ef = ef | src_data[temp_index];
-
- if (_check_file_for_refresh((enum tel_sim_file_id)ef)) {/* check file registered for refresh? */
- file_list_obj->file_id[file_list_obj->file_count] = ef;
- file_list_obj->file_count++;
- }
- } else
- temp_index++;
- } else if (src_data[temp_index] == 0x7F && (src_data[temp_index + 1] == 0x10
- || src_data[temp_index + 1] == 0x20)) {
- /* TELECOM DIRECTORY FILE 0x7F10 or GSM DIRECTORY FILE 0x7F20 */
- temp_index += 2;
- if (src_data[temp_index] == 0x6F) {
- ef = src_data[temp_index] << 8;
- temp_index++;
- ef = ef | src_data[temp_index];
-
- if (_check_file_for_refresh((enum tel_sim_file_id)ef)) {/* check file registered for refresh? */
- file_list_obj->file_id[file_list_obj->file_count] = ef;
- file_list_obj->file_count++;
- }
- } else
- temp_index++;
- }
-
- f_count++;
- temp_index++;
- } while (f_count < tmp_cnt);
-
- dbg("[SAT] SAT PARSER - total file count=%d, PDA file count = %d", tmp_cnt, file_list_obj->file_count);
- *consumed_data_len = 1 + len_of_len + file_list_len;
- return TCORE_SAT_SUCCESS;
-}
-
-static enum tcore_sat_result _sat_decode_item_next_action_indicator_tlv(unsigned char *tlv_str, int tlv_len, int curr_offset,
- struct tel_sat_item_next_action_indicatior_list *item_next_act_indi_obj, int *consumed_data_len)
-{
- int temp_index;
- int item_nai_len;
- unsigned char *src_data;
- gboolean comprehension_req = FALSE;
-
- if (tlv_str == NULL || consumed_data_len == NULL || item_next_act_indi_obj == NULL) {
- dbg("[SAT] SAT PARSER - tlv_str == NULL || consumed_data_len == NULL || item_next_act_indi_obj == NULL");
- return TCORE_SAT_ERROR_FATAL;
- }
-
- if (tlv_len <= (curr_offset + 1)) {
- dbg("[SAT] SAT PARSER - incorrect length original_command_len=%d", tlv_len);
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- /* tag */
- temp_index = curr_offset;
- src_data = &tlv_str[0];
- if ((src_data[temp_index] & 0x7F) != SATK_ITEMS_NEXT_ACTION_INDICATOR_TAG) {
- dbg("[SAT] SAT PARSER - tag not found.=%d", src_data[temp_index]);
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- if ((src_data[temp_index++] & 0x7F))
- comprehension_req = TRUE;
-
- /* item cnt */
- item_nai_len = item_next_act_indi_obj->cnt = src_data[temp_index++];
- if ((temp_index + item_nai_len) > tlv_len) {
- dbg("[SAT] SAT PARSER - incorrect cmd len, expected len = %d, orig_len=%d",
- (temp_index + item_nai_len), tlv_len);
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- if (item_next_act_indi_obj->cnt > SAT_ITEMS_NEXT_ACTION_INDI_LIST_MAX_COUNT) {
- if (comprehension_req == TRUE) {
- dbg("[SAT] SAT PARSER - list count exceeds maximum allowed count=%d", item_next_act_indi_obj->cnt);
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- item_next_act_indi_obj->cnt = 0;
- }
-
- memset(item_next_act_indi_obj->indicator_list, 0xFF, SAT_ITEMS_NEXT_ACTION_INDI_LIST_MAX_COUNT);
- if (item_next_act_indi_obj->cnt > 0)
- memcpy(item_next_act_indi_obj->indicator_list, &src_data[temp_index], item_next_act_indi_obj->cnt);
-
- *consumed_data_len = 1 + 1 + item_nai_len;
- dbg("[SAT] SAT PARSER - listCount=%d, consumed_data_len = %d", item_next_act_indi_obj->cnt, *consumed_data_len);
- return TCORE_SAT_SUCCESS;
-}
-
-static enum tcore_sat_result _sat_decode_event_list_tlv(unsigned char *tlv_str, int tlv_len,
- int curr_offset, struct tel_sat_event_list *event_list_obj, int *consumed_data_len)
-{
- int i = 0;
- int temp_index, len_of_len = 0;
- int evt_list_len;
- unsigned char *src_data;
- gboolean comprehension_req = FALSE;
-
- if (tlv_str == NULL || consumed_data_len == NULL || event_list_obj == NULL) {
- dbg("[SAT] SAT PARSER - tlv_str == NULL || consumed_data_len == NULL || event_list_obj == NULL");
- return TCORE_SAT_ERROR_FATAL;
- }
-
- if (tlv_len <= (curr_offset + 1)) {
- dbg("[SAT] SAT PARSER - incorrect length original_command_len=%d", tlv_len);
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- /* tag */
- temp_index = curr_offset;
- src_data = &tlv_str[0];
- if ((src_data[temp_index] & 0x7F) != SATK_EVENT_LIST_TAG) {
- dbg("[SAT] SAT PARSER - tag not found.=%d", src_data[temp_index]);
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- if ((src_data[temp_index++] & 0x80))
- comprehension_req = TRUE;
-
- /* length */
- len_of_len = _get_length_filed_size(src_data[temp_index]);
- if (!len_of_len) {
- err("[SAT] parser: invalid length.");
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- evt_list_len = src_data[temp_index + len_of_len-1];
- dbg("[SAT] parser: evt_list_len=%d", evt_list_len);
- temp_index += len_of_len;
-
- if ((temp_index + evt_list_len) > tlv_len) {
- dbg("[SAT] SAT PARSER - incorrect cmd len, expected len = %d, orig_len=%d",
- (temp_index + evt_list_len), tlv_len);
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- if (evt_list_len > SAT_EVENT_LIST_MAX) {
- dbg("[SAT] SAT PARSER - event list contains more items than it is supposed to have! len=%d",
- evt_list_len);
- if (comprehension_req)
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- else
- evt_list_len = SAT_EVENT_LIST_MAX;
- }
-
- event_list_obj->event_list_cnt = 0;
- memset(event_list_obj->evt_list, 0xFF, SAT_EVENT_LIST_MAX);
-
- /* event list */
- for (i = 0; i < evt_list_len; i++) {
- dbg("[SAT] SAT PARSER - event[%d]=0x%x",
- i, src_data[temp_index]);
- switch (src_data[temp_index]) {
- /* PDA events */
- case EVENT_USER_ACTIVITY:
- case EVENT_IDLE_SCREEN_AVAILABLE:
- case EVENT_LANGUAGE_SELECTION:
- case EVENT_BROWSER_TERMINATION:
- case EVENT_DATA_AVAILABLE:
- case EVENT_CHANNEL_STATUS:
- case EVENT_MT_CALL:
- case EVENT_CALL_CONNECTED:
- case EVENT_CALL_DISCONNECTED:
- case EVENT_LOCATION_STATUS:
- case EVENT_ACCESS_TECHNOLOGY_CHANGED:
- event_list_obj->evt_list[i] = src_data[temp_index];
- event_list_obj->event_list_cnt++;
- break;
-
- case EVENT_UNKNOWN: /* Fallthrough */
- default:
- if (comprehension_req)
- return TCORE_SAT_BEYOND_ME_CAPABILITY;
- break;
- }
- temp_index++;
- }
-
- /* 1 is the length of Tag. */
- *consumed_data_len = 1 + len_of_len + evt_list_len;
- return TCORE_SAT_SUCCESS;
-}
-
-static enum tcore_sat_result _sat_decode_icon_identifier_tlv(unsigned char *tlv_str, int tlv_len,
- int curr_offset, struct tel_sat_icon_identifier *icon_id_obj, int *consumed_data_len)
-{
- unsigned char *src_data;
- int temp_index = 0;
-
- if (tlv_str == NULL || icon_id_obj == NULL || consumed_data_len == NULL) {
- dbg("[SAT] SAT PARSER - tlv_str == NULL || icon_id_obj == NULL ||consumed_data_len == NULL");
- return TCORE_SAT_ERROR_FATAL;
- }
-
- if (tlv_len <= (curr_offset + 1)) {/* length of icon id tlv is 4 */
- dbg("[SAT] SAT PARSER - incorrect length original_command_len=%d", tlv_len);
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- /* tag */
- temp_index = curr_offset;
- src_data = &tlv_str[0];
- if ((src_data[temp_index++] & 0x7F) != SATK_ICON_IDENTIFIER_TAG) {
- dbg("[SAT] SAT PARSER - icon identity tag missing.");
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; /* Send TR */
- }
-
- if (src_data[temp_index++] != SATK_ICON_IDENTITY_LENGTH) {
- dbg("[SAT] SAT PARSER - incorrect length value.");
- return FALSE; /* Send TR */
- }
-
- if ((temp_index + SATK_ICON_IDENTITY_LENGTH) > tlv_len) {
- dbg("[SAT] SAT PARSER - incorrect cmd len, expected len = %d, orig_len=%d",
- (temp_index + SATK_ICON_IDENTITY_LENGTH), tlv_len);
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- icon_id_obj->is_exist = TRUE;
-
- if ((src_data[temp_index++] & 0x01))
- icon_id_obj->icon_qualifer = ICON_QUALI_NOT_SELF_EXPLANATORY;
- else
- icon_id_obj->icon_qualifer = ICON_QUALI_SELF_EXPLANATORY;
-
- if (src_data[temp_index] > 0x00)
- icon_id_obj->icon_identifier = src_data[temp_index];
- else {
- dbg("[SAT] SAT PARSER - incorrect icon identifier");
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; /* Send TR */
- }
-
- dbg("[SAT] SAT PARSER - icon_qual=%d, iconId=%d", icon_id_obj->icon_qualifer, icon_id_obj->icon_identifier);
- *consumed_data_len = 4;
- return TCORE_SAT_SUCCESS;
-}
-
-static enum tcore_sat_result _sat_decode_icon_identifier_list_tlv(unsigned char *tlv_str, int tlv_len,
- int curr_offset, struct tel_sat_icon_identifier_list *icon_list_obj, int *consumed_data_len)
-{
- int temp_index, i;
- int len_value = 0;
- unsigned char *src_data;
- gboolean comprehension_req = FALSE;
-
- if (tlv_str == NULL || consumed_data_len == NULL || icon_list_obj == NULL) {
- dbg("[SAT] SAT PARSER - tlv_str == NULL || consumed_data_len == NULL || icon_list_obj == NULL");
- return TCORE_SAT_ERROR_FATAL;
- }
-
- if (tlv_len <= (curr_offset + 1) + 1) {
- dbg("[SAT] SAT PARSER - incorrect length original_command_len=%d", tlv_len);
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- /* tag */
- temp_index = curr_offset;
- src_data = &tlv_str[0];
- if ((src_data[temp_index] & 0x7F) != SATK_ITEM_ICON_IDENTIFIER_LIST_TAG) {
- dbg("[SAT] SAT PARSER - icon identity tag missing.");
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; /* Send TR */
- }
-
- icon_list_obj->is_exist = TRUE;
- if (src_data[temp_index++] & 0x80)
- comprehension_req = TRUE;
-
- len_value = src_data[temp_index++];
- if (src_data[temp_index++] & 0x01)
- icon_list_obj->icon_qualifer = ICON_QUALI_NOT_SELF_EXPLANATORY;
- else
- icon_list_obj->icon_qualifer = ICON_QUALI_SELF_EXPLANATORY;
-
- icon_list_obj->icon_cnt = len_value-1;
- if (icon_list_obj->icon_cnt > SAT_ICON_LIST_MAX_COUNT) {
- if (comprehension_req == TRUE) {
- dbg("[SAT] SAT PARSER - list count exceeds maximum allowed count=%d", icon_list_obj->icon_cnt);
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- icon_list_obj->icon_cnt = 0;
- } else {
-
- for (i = 0; i < icon_list_obj->icon_cnt; i++) {
- if (src_data[temp_index] > 0x00) {
- icon_list_obj->icon_id_list[i] = src_data[temp_index++];
- } else {
- dbg("[SAT] SAT PARSER - incorrect icon identifier");
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; /* Send TR */
- }
- }
- }
-
- *consumed_data_len = 1 + 1 + len_value;
- dbg("[SAT] SAT PARSER - icon_qual=%d, iconCount=%d", icon_list_obj->icon_qualifer, icon_list_obj->icon_cnt);
- return TCORE_SAT_SUCCESS;
-}
-
-static enum tcore_sat_result _sat_decode_dtmf_string_tlv(unsigned char *tlv_str, int tlv_len,
- int curr_offset, struct tel_sat_dtmf_string *dtmf_string_obj, int *consumed_data_len)
-{
- unsigned char *src_data;
- int temp_index, len_of_len = 0;
- int dtmf_len = 0;
- gboolean comprehension_req = FALSE;
- char *str_ascii = NULL;
-
- if (tlv_str == NULL || consumed_data_len == NULL || dtmf_string_obj == NULL) {
- dbg("[SAT] SAT PARSER - tlv_str == NULL || consumed_data_len == NULL || dtmf_string_obj == NULL");
- return TCORE_SAT_ERROR_FATAL;
- }
-
- src_data = &tlv_str[0];
-
- if (tlv_len <= (curr_offset + 1)) {
- dbg("[SAT] SAT PARSER - incorrect length original_command_len=%d", tlv_len);
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- /* Tag */
- temp_index = curr_offset;
- if ((src_data[temp_index] & 0x7F) != SATK_DTMF_STRING_TAG) {
- dbg("[SAT] SAT PARSER - address tag missing");
- return TCORE_SAT_REQUIRED_VALUE_MISSING;
- }
-
- /* comprehensive required */
- if ((src_data[temp_index++] & 0x80))
- comprehension_req = TRUE;
-
- dbg("comprehension_req=[%d]", comprehension_req);
-
- /* length */
- len_of_len = _get_length_filed_size(src_data[temp_index]);
- if (!len_of_len) {
- err("[SAT] parser: invalid length.");
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- dtmf_len = src_data[temp_index + len_of_len - 1];
- temp_index += len_of_len; /* temp_index pointing to TON/NPI */
-
- if ((temp_index + dtmf_len) > tlv_len) {
- dbg("[SAT] SAT PARSER - incorrect cmd len, expected len = %d, orig_len=%d",
- (temp_index + dtmf_len), tlv_len);
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- dtmf_string_obj->dtmf_length = 0;
-
- if (dtmf_len > 0) {
- str_ascii = tcore_util_convert_bcd2ascii((const char *)&src_data[temp_index], dtmf_len, SAT_DTMF_STRING_LEN_MAX);
- if (str_ascii) {
- memcpy(dtmf_string_obj->dtmf_string, str_ascii, strlen(str_ascii));
- dtmf_string_obj->dtmf_length = strlen(str_ascii);
- g_free(str_ascii);
- }
- }
-
- if (dtmf_string_obj->dtmf_length == 0) {
- dbg("[SAT] SAT PARSER - DTMF string length is either 0 or it is too long for the ME to handle.");
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- *consumed_data_len = 1 + len_of_len + dtmf_len;
- return TCORE_SAT_SUCCESS;
-}
-
-static enum tcore_sat_result _sat_decode_language_tlv(unsigned char *tlv_str, int tlv_len,
- int curr_offset, enum tel_sim_language_type *language_obj)
-{
- unsigned char *src_data;
- int temp_index = 0;
-
- if (tlv_len <= (curr_offset + 1)) {
- dbg("[SAT] SAT PARSER - incorrect length original_command_len=%d", tlv_len);
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- src_data = &tlv_str[0];
- temp_index = curr_offset;
-
- if ((src_data[temp_index++] & 0x7F) != SATK_LANGUAGE_TAG) {
- dbg("[SAT] SAT PARSER - Language tag missing.");
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- if (src_data[temp_index++] != SATK_LANGUAGE_LENGTH) {
- dbg("[SAT] SAT PARSER - incorrect length value.");
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- if ((temp_index + SATK_LANGUAGE_LENGTH) > tlv_len) {
- dbg("[SAT] SAT PARSER - incorrect cmd len, expected len = %d, orig_len=%d",
- (temp_index + SATK_LANGUAGE_LENGTH), tlv_len);
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- *language_obj = _sat_decode_language(src_data[temp_index], src_data[temp_index + 1]);
- dbg("[SAT] SAT PARSER - <in> %c %c, <out> %d", src_data[temp_index], src_data[temp_index + 1], *language_obj);
- return TCORE_SAT_SUCCESS;
-}
-
-static enum tcore_sat_result _sat_decode_browser_identity_tlv(unsigned char *tlv_str, int tlv_len,
- int curr_offset, enum browser_identity *browser_id, int *consumed_data_len)
-{
- unsigned char *src_data;
- int temp_index = 0;
-
- if (tlv_str == NULL || browser_id == NULL || consumed_data_len == NULL) {
- dbg("[SAT] SAT PARSER - tlv_str == NULL || browser_id == NULL ||consumed_data_len == NULL");
- return TCORE_SAT_ERROR_FATAL;
- }
-
- if (tlv_len <= (curr_offset + 1)) {
- dbg("[SAT] SAT PARSER - incorrect length original_command_len=%d", tlv_len);
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- temp_index = curr_offset;
- src_data = &tlv_str[0];
-
- if ((src_data[temp_index++] & 0x7F) != SATK_BROWSER_IDENTITY_TAG) {
- dbg("[SAT] SAT PARSER - Browser ID tag missing.");
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- if (src_data[temp_index++] != SATK_BROWSER_ID_LENGTH) {
- dbg("[SAT] SAT PARSER - incorrect length value.");
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- dbg("[SAT] SAT PARSER - : browser ID value:ox%x", src_data[temp_index]);
-
- switch (src_data[temp_index]) {
- case 0x00:
- *browser_id = BROWSER_ID_DEFAULT;
- break;
-
- case 0x01:
- *browser_id = BROWSER_ID_WML;
- break;
-
- case 0x02:
- *browser_id = BROWSER_ID_HTML;
- break;
-
- case 0x03:
- *browser_id = BROWSER_ID_XHTML;
- break;
-
- case 0x04:
- *browser_id = BROWSER_ID_CHTML;
- break;
-
- default:
- *browser_id = BROWSER_ID_RESERVED;
- break;
- }
-
- *consumed_data_len = 3;
- return TCORE_SAT_SUCCESS;
-}
-
-static enum tcore_sat_result _sat_decode_url_tlv(unsigned char *tlv_str, int tlv_len,
- int curr_offset, struct tel_sat_url *url, int *consumed_data_len)
-{
- unsigned char *src_data;
- int temp_index = curr_offset;
- int len_of_len = 0, url_len = 0;
-
- if (tlv_str == NULL || url == NULL || consumed_data_len == NULL) {
- dbg("[SAT] SAT PARSER - tlv_str == NULL || url == NULL ||consumed_data_len == NULL");
- return TCORE_SAT_ERROR_FATAL;
- }
-
- src_data = &tlv_str[0];
- if (tlv_len <= (curr_offset + 1)) {
- dbg("[SAT] SAT PARSER - incorrect length original_command_len=%d", tlv_len);
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- if ((src_data[temp_index++] & 0x7F) != SATK_URL_TAG) {
- dbg("[SAT] SAT PARSER - Browser URL tag missing.");
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; /* Send TR */
- }
-
- /* length */
- len_of_len = _get_length_filed_size(src_data[temp_index]);
- if (!len_of_len) {
- err("[SAT] parser: invalid length.");
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- url_len = src_data[temp_index + len_of_len-1];
- url->url_length = url_len;
- temp_index += len_of_len; /* temp_index pointing to url. */
- dbg("URL length (%d)", url_len);
-
- if (url_len < 0) {
- dbg("[SAT] URL is null");
- *consumed_data_len = 1 + len_of_len + url_len;
- return TCORE_SAT_SUCCESS;
- }
-
- if (url_len > SAT_URL_LEN_MAX) {
- dbg("[SAT] URL length is wrong");
- *consumed_data_len = 1 + len_of_len + url_len;
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- memcpy(url->url, &src_data[temp_index], url_len);
- dbg("[SAT] url(%s)", url->url);
- *consumed_data_len = 1 + len_of_len + url_len;
-
- return TCORE_SAT_SUCCESS;
-}
-
-static enum tcore_sat_result _sat_decode_bearer_tlv(unsigned char *tlv_str, int tlv_len,
- int curr_offset, struct tel_sat_bearer_list *satk_bearer, int *consumed_data_len)
-{
- unsigned char *src_data;
- int temp_index, len_of_len = 0;
- int list_len = 0, list_idx = 0;
-
- if (tlv_str == NULL || consumed_data_len == NULL || satk_bearer == NULL) {
- dbg("[SAT] SAT PARSER - tlv_str == NULL || consumed_data_len == NULL || satk_bearer == NULL");
- return TCORE_SAT_ERROR_FATAL;
- }
-
- if (tlv_len <= (curr_offset + 1)) {
- dbg("[SAT] SAT PARSER - incorrect length original_command_len=%d",
- tlv_len);
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- src_data = &tlv_str[0];
- temp_index = curr_offset;
-
- if ((src_data[temp_index++] & 0x7F) != SATK_BEARER_TAG) {
- dbg("[SAT] SAT PARSER - _sat_decode_bearer_tlv: alphaID TAG missing");
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- /* length */
- len_of_len = _get_length_filed_size(src_data[temp_index]);
- if (!len_of_len) {
- err("[SAT] parser: invalid length.");
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- satk_bearer->count = src_data[temp_index + len_of_len - 1];
- list_len = satk_bearer->count;
- temp_index += len_of_len;
-
- if ((temp_index + list_len) > tlv_len) {
- dbg("[SAT] SAT PARSER - incorrect cmd len, expected len = %d, orig_len=%d",
- (temp_index + list_len), tlv_len);
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- if (satk_bearer->count > 0) {
- if (list_len > SAT_BEARER_LIST_MAX_COUNT)
- list_len = SAT_BEARER_LIST_MAX_COUNT;
-
- for (list_idx = 0; list_idx < list_len; list_idx++) {
- switch (src_data[temp_index]) {
- case 0x00:
- satk_bearer->bear[list_idx] = BEARER_LIST_SMS;
- break;
-
- case 0x01:
- satk_bearer->bear[list_idx] = BEARER_LIST_CSD;
- break;
-
- case 0x02:
- satk_bearer->bear[list_idx] = BEARER_LIST_USSD;
- break;
-
- case 0x03:
- satk_bearer->bear[list_idx] = BEARER_LIST_GPRS;
- break;
-
- default:
- satk_bearer->bear[list_idx] = BEARER_LIST_RESERVED;
- break;
- }
-
- dbg("[SAT] SAT PARSER - bearer[%d]=0x%x", list_idx, satk_bearer->bear[list_idx]);
- temp_index++;
- }
- } else
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
-
- *consumed_data_len = 1 + len_of_len + list_len;
- return TCORE_SAT_SUCCESS;
-}
-
-static enum tcore_sat_result _sat_decode_provisioning_file_ref_tlv(unsigned char *tlv_str, int tlv_len,
- int curr_offset, struct tel_sat_provisioning_file_ref *prf, int *data_len_consumed)
-{
- unsigned char *src_data;
- int temp_index = curr_offset;
- int len_of_len = 0, prf_len = 0;
-
- if (tlv_str == NULL || prf == NULL || data_len_consumed == NULL) {
- dbg("[SAT] SAT PARSER - tlv_str == NULL || prf == NULL ||data_len_consumed == NULL");
- return TCORE_SAT_ERROR_FATAL;
- }
-
- src_data = &tlv_str[0];
- if (tlv_len <= (curr_offset + 1)) {
- dbg("[SAT] SAT PARSER - incorrect length original_command_len=%d", tlv_len);
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- if ((src_data[temp_index++] & 0x7F) != SATK_PROVISIONING_REF_FILE_TAG) {
- dbg("[SAT] SAT PARSER - PRF tag missing.");
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; /* Send TR */
- }
-
- /* length */
- len_of_len = _get_length_filed_size(src_data[temp_index]);
- if (!len_of_len) {
- err("[SAT] parser: invalid length.");
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- prf_len = src_data[temp_index + len_of_len - 1];
- prf->file_path_length = prf_len;
- temp_index += len_of_len; /* temp_index pointing to prf. */
-
- if (prf_len > 0) {
- if (prf_len > SAT_PROVISIONING_FILE_PATH_LEN_MAX)
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- else
- memcpy(prf->file_path, &src_data[temp_index], prf_len);
- } else {
- dbg("[SAT] SAT PARSER - NULL string for PRF");
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- *data_len_consumed = 1 + len_of_len + prf_len;
- return TCORE_SAT_SUCCESS;
-}
-
-static enum tcore_sat_result _sat_decode_bearer_description_tlv(unsigned char *tlv_str, int tlv_len,
- int curr_offset, struct tel_sat_bearer_description *bearer_desc_obj, int *consumed_data_len)
-{
- int temp_index, length = 0;
- unsigned char *src_data;
-
- if (tlv_len <= (curr_offset + 1) + 1) {
- dbg("[SAT] SAT PARSER - incorrect length original_command_len=%d", tlv_len);
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- temp_index = curr_offset;
- src_data = &tlv_str[0];
- while (1) {
- if (temp_index >= tlv_len) {
- dbg("bearer desc cannot find. UICC Server mode");
- *consumed_data_len = 0;
- return TCORE_SAT_SUCCESS;
- }
-
- if ((src_data[temp_index] & 0x7F) == SATK_BEARER_DISCRIPTION_TAG) {
- dbg("find bearer description tag temp_index(%d)", temp_index);
- temp_index++;
- break;
- }
-
- temp_index++;
- }
-
- /* length */
- length = src_data[temp_index++];
- dbg("bearer description length (%d)", length);
-
- /* bearer parameter */
- switch (src_data[temp_index++]) {
- case BEARER_CSD:
- bearer_desc_obj->bearer_type = BEARER_CSD;
- bearer_desc_obj->bearer_parameter.cs_bearer_param.data_rate = src_data[temp_index++];
- bearer_desc_obj->bearer_parameter.cs_bearer_param.service_type = src_data[temp_index++];
- bearer_desc_obj->bearer_parameter.cs_bearer_param.connection_element_type = src_data[temp_index++];
- break;
-
- case BEARER_GPRS:
- bearer_desc_obj->bearer_type = BEARER_GPRS;
- bearer_desc_obj->bearer_parameter.ps_bearer_param.precedence_class = src_data[temp_index++];
- bearer_desc_obj->bearer_parameter.ps_bearer_param.delay_class = src_data[temp_index++];
- bearer_desc_obj->bearer_parameter.ps_bearer_param.reliability_class = src_data[temp_index++];
- bearer_desc_obj->bearer_parameter.ps_bearer_param.peak_throughput_class = src_data[temp_index++];
- bearer_desc_obj->bearer_parameter.ps_bearer_param.mean_throughput_class = src_data[temp_index++];
- bearer_desc_obj->bearer_parameter.ps_bearer_param.pdp_type = BIP_GPRS_PDP_TYPE_RESERVED;
- if (src_data[temp_index] == BIP_GPRS_PDP_TYPE_IP)
- bearer_desc_obj->bearer_parameter.ps_bearer_param.pdp_type = BIP_GPRS_PDP_TYPE_IP;
- break;
-
- case BEARER_DEFAULT_BEARER_FROM_TRANSPORT_LAYER:
- bearer_desc_obj->bearer_type = BEARER_DEFAULT_BEARER_FROM_TRANSPORT_LAYER;
- break;
-
- case BEARER_LOCAL_LINK_TECHNOLOGY_INDEPENDENT:
- bearer_desc_obj->bearer_type = BEARER_DEFAULT_BEARER_FROM_TRANSPORT_LAYER;
- break;
-
- default:
- bearer_desc_obj->bearer_type = BEARER_RESERVED;
- dbg("bearer type not supported");
- return TCORE_SAT_BEYOND_ME_CAPABILITY;
- }
-
- *consumed_data_len = 1 + 1 + length;
- return TCORE_SAT_SUCCESS;
-}
-
-static enum tcore_sat_result _sat_decode_channel_data_tlv(unsigned char *tlv_str, int tlv_len,
- int curr_offset, struct tel_sat_channel_data *channel_data_obj, int *consumed_data_len)
-{
- int temp_index = 0;
- int len_of_len = 0, channel_data_len = 0;
- unsigned char *src_data;
-
- if (tlv_str == NULL || consumed_data_len == NULL || channel_data_obj == NULL) {
- dbg("[SAT] SAT PARSER - tlv_str == NULL || consumed_data_len == NULL || channel_data_obj == NULL");
- return TCORE_SAT_ERROR_FATAL;
- }
-
- if (tlv_len <= (curr_offset + 1)) {
- dbg("[SAT] SAT PARSER - incorrect length original_command_len=%d", tlv_len);
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- /* tag */
- temp_index = curr_offset;
- src_data = &tlv_str[0];
- if ((src_data[temp_index++] & 0x7F) != SATK_CHANNEL_DATA_TAG) {
- dbg("[SAT] SAT PARSER - tag not found.=%d", src_data[temp_index]);
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- /* length */
- len_of_len = _get_length_filed_size(src_data[temp_index]);
- if (!len_of_len) {
- err("[SAT] parser: invalid length.");
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- channel_data_len = src_data[temp_index + len_of_len-1];
- dbg("[SAT] parser: channel_data_len=%d", channel_data_len);
- temp_index += len_of_len;
-
- if ((temp_index + channel_data_len) > tlv_len) {
- dbg("[SAT] SAT PARSER - incorrect cmd len, expected len = %d, orig_len=%d", (temp_index + channel_data_len), tlv_len);
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- /* data */
- channel_data_obj->data_string_len = channel_data_len;
- memcpy(channel_data_obj->data_string, &src_data[temp_index], channel_data_len);
-
- *consumed_data_len = 1 + len_of_len + channel_data_len;
- return TCORE_SAT_SUCCESS;
-}
-
-static enum tcore_sat_result _sat_decode_channel_data_length_tlv(unsigned char *tlv_str, int tlv_len,
- int curr_offset, struct tel_sat_channel_data_len *data_len_obj, int *consumed_data_len)
-{
- int temp_index;
- unsigned char *src_data;
-
- if (tlv_str == NULL || consumed_data_len == NULL || data_len_obj == NULL) {
- dbg("[SAT] SAT PARSER - tlv_str == NULL || consumed_data_len == NULL || data_len_obj == NULL");
- return TCORE_SAT_ERROR_FATAL;
- }
-
- /* tag */
- temp_index = curr_offset;
- src_data = &tlv_str[0];
- if ((src_data[temp_index++] & 0x7F) != SATK_CHANNEL_DATA_LEN_TAG) {
- dbg("[SAT] SAT PARSER - channel data tag missing.");
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; /* Send TR */
- }
-
- /* length */
- if (src_data[temp_index++] != SATK_CHANNEL_DATA_LENGTH_VALUE_LENGTH) {
- dbg("[SAT] SAT PARSER - incorrect length");
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; /* Send TR */
- }
-
- /* data */
- data_len_obj->data_len = src_data[temp_index];
-
- *consumed_data_len = 3;
- return TCORE_SAT_SUCCESS;
-}
-
-static enum tcore_sat_result _sat_decode_buffer_size_tlv(unsigned char *tlv_str, int tlv_len,
- int curr_offset, struct tel_sat_buffer_size *buffer_size_obj, int *consumed_data_len)
-{
- int temp_index;
- unsigned char *src_data;
-
- if (tlv_str == NULL || consumed_data_len == NULL || buffer_size_obj == NULL) {
- dbg("[SAT] SAT PARSER - tlv_str == NULL || consumed_data_len == NULL || buffer_size_obj == NULL");
- return TCORE_SAT_ERROR_FATAL;
- }
-
- if (tlv_len <= (curr_offset + 1) + SATK_BUFFER_SIZE_LENGTH) {
- dbg("[SAT] SAT PARSER - incorrect length original_command_len=%d", tlv_len);
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- /* tag */
- temp_index = curr_offset;
- src_data = &tlv_str[0];
- if ((src_data[temp_index++] & 0x7F) != SATK_BUFFER_SIZE_TAG) {
- dbg("[SAT] SAT PARSER - buffer size tag missing.");
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; /* Send TR */
- }
-
- /* length */
- if (src_data[temp_index++] != SATK_BUFFER_SIZE_LENGTH) {
- dbg("[SAT] SAT PARSER - incorrect length");
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; /* Send TR */
- }
-
- buffer_size_obj->size[0] = src_data[temp_index++];
- buffer_size_obj->size[1] = src_data[temp_index];
-
- *consumed_data_len = 4;
- dbg("[SAT] SAT PARSER - buffer size = 0x%x%x", buffer_size_obj->size[0], buffer_size_obj->size[1]);
- return TCORE_SAT_SUCCESS;
-}
-
-static enum tcore_sat_result _sat_decode_other_address_tlv(unsigned char *tlv_str, int tlv_len,
- int curr_offset, struct tel_sat_other_address *other_address_obj, int *consumed_data_len)
-{
- gchar *address = NULL;
- int temp_index, address_len;
- unsigned char *src_data;
-
- if (tlv_str == NULL || consumed_data_len == NULL || other_address_obj == NULL) {
- dbg("[SAT] SAT PARSER - tlv_str == NULL || consumed_data_len == NULL || other_address_obj == NULL");
- return TCORE_SAT_ERROR_FATAL;
- }
-
- if (tlv_len <= (curr_offset + 1)) {
- dbg("[SAT] SAT PARSER - incorrect length original_command_len=%d", tlv_len);
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- /* tag */
- temp_index = curr_offset;
- src_data = &tlv_str[0];
- if ((src_data[temp_index++] & 0x7F) != SATK_OTHER_ADDRESS_TAG) {
- dbg("[SAT] SAT PARSER - other address tag missing.");
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; /* Send TR */
- }
-
- /* length */
- address_len = src_data[temp_index++];
- if ((temp_index + address_len) > tlv_len) {
- dbg("[SAT] SAT PARSER - incorrect cmd len, expected len = %d, orig_len=%d", (temp_index + address_len), tlv_len);
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- if (address_len-1 > SAT_OTHER_ADDR_LEN_MAX) {
- dbg("[SAT] SAT PARSER - address is longer than capability");
- return TCORE_SAT_BEYOND_ME_CAPABILITY;
- }
-
- /* other address type */
- switch (src_data[temp_index++]) {
- case ADDR_TYPE_IPv4: {
- other_address_obj->address_type = ADDR_TYPE_IPv4;
- address = g_strdup_printf("%d.%d.%d.%d", src_data[temp_index], src_data[temp_index + 1], src_data[temp_index + 2], src_data[temp_index + 3]);
- }
- break;
-
- case ADDR_TYPE_IPv6: {
- other_address_obj->address_type = ADDR_TYPE_IPv6;
- address = g_strdup_printf("%x%x:%x%x:%x%x:%x%x:%x%x:%x%x:%x%x:%x%x:",
- src_data[temp_index], src_data[temp_index + 1], src_data[temp_index + 2], src_data[temp_index + 3],
- src_data[temp_index + 4], src_data[temp_index + 5], src_data[temp_index + 6], src_data[temp_index + 7],
- src_data[temp_index + 8], src_data[temp_index + 9], src_data[temp_index + 10], src_data[temp_index + 11],
- src_data[temp_index + 12], src_data[temp_index + 13], src_data[temp_index + 14], src_data[temp_index + 15]);
- }
- break;
-
- default: {
- other_address_obj->address_type = ADDR_RESERVED;
- address = g_strdup("");
- }
- break;
- } /* end of switch */
-
- /* address */
- if (address) {
- memcpy(other_address_obj->address, address, strlen(address));
- other_address_obj->address_len = strlen(address);
-
- g_free(address);
- dbg("destination address(%s)", other_address_obj->address);
- }
-
- *consumed_data_len = 2 + address_len;
- return TCORE_SAT_SUCCESS;
-}
-
-static enum tcore_sat_result _sat_decode_uicc_terminal_interface_tlv(unsigned char *tlv_str,
- int tlv_len, int curr_offset, struct tel_sat_uicc_terminal_interface_transport_level *level_obj,
- int *consumed_data_len)
-{
- int temp_index;
- unsigned char *src_data;
-
- if (tlv_str == NULL || consumed_data_len == NULL || level_obj == NULL) {
- dbg("[SAT] SAT PARSER - tlv_str == NULL || consumed_data_len == NULL || level_obj == NULL");
- return TCORE_SAT_ERROR_FATAL;
- }
-
- if (tlv_len <= (curr_offset + 1) + SATK_UICC_ME_TRANS_INTERFACE_LEVEL_LENGTH) {
- dbg("[SAT] SAT PARSER - incorrect length original_command_len=%d", tlv_len);
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- /* tag */
- temp_index = curr_offset;
- src_data = &tlv_str[0];
- if ((src_data[temp_index++] & 0x7F) != SATK_USIM_ME_INTERFACE_TRANSPORT_LEVEL_TAG) {
- dbg("[SAT] SAT PARSER - UICC/TERMINAL Interface transport level tag missing.");
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; /* Send TR */
- }
-
- /* length */
- if (src_data[temp_index++] != SATK_UICC_ME_TRANS_INTERFACE_LEVEL_LENGTH) {
- dbg("[SAT] SAT PARSER - incorrect length");
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; /* Send TR */
- }
-
- level_obj->protocol_type = src_data[temp_index++];
- level_obj->port_number = src_data[temp_index++] << 8;
- level_obj->port_number |= src_data[temp_index];
-
- *consumed_data_len = 2 + SATK_UICC_ME_TRANS_INTERFACE_LEVEL_LENGTH;
- dbg("[SAT] SAT PARSER - protocol type(%d) , port number(%d)", level_obj->protocol_type, level_obj->port_number);
- return TCORE_SAT_SUCCESS;
-}
-
-static enum tcore_sat_result _sat_decode_remote_entity_address_tlv(unsigned char *tlv_str,
- int tlv_len, int curr_offset, struct tel_sat_remote_entity_address *remote_address_obj,
- int *consumed_data_len)
-{
- int temp_index = 0;
- int len_of_len = 0, remote_data_len = 0;
- unsigned char *src_data;
-
- if (tlv_str == NULL || consumed_data_len == NULL || remote_address_obj == NULL) {
- dbg("[SAT] SAT PARSER - tlv_str == NULL || consumed_data_len == NULL || remote_address_obj == NULL");
- return TCORE_SAT_ERROR_FATAL;
- }
-
- if (tlv_len <= (curr_offset + 1)) {
- dbg("[SAT] SAT PARSER - incorrect length original_command_len=%d", tlv_len);
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- /* tag */
- temp_index = curr_offset;
- src_data = &tlv_str[0];
- if ((src_data[temp_index] & 0x7F) != SATK_REMOTE_ENTITY_ADDRESS_TAG) {
- dbg("[SAT] SAT PARSER - tag not found.=%d", src_data[temp_index]);
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- /* length */
- len_of_len = _get_length_filed_size(src_data[temp_index]);
- if (!len_of_len) {
- err("[SAT] parser: invalid length.");
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- remote_data_len = src_data[temp_index + len_of_len-1];
- dbg("[SAT] parser: remote_data_len=%d", remote_data_len);
- temp_index += len_of_len;
-
- /* data */
- switch (src_data[temp_index++]) {
- case REMOTE_ENTITY_ADDR_CODING_TYPE_IEEE802_48BIT:
- remote_address_obj->coding_type = REMOTE_ENTITY_ADDR_CODING_TYPE_IEEE802_48BIT;
- break;
-
- case REMOTE_ENTITY_ADDR_CODING_TYPE_IRDA_32BIT:
- remote_address_obj->coding_type = REMOTE_ENTITY_ADDR_CODING_TYPE_IRDA_32BIT;
- break;
-
- default:
- remote_address_obj->coding_type = REMOTE_ENTITY_ADDR_CODING_TYPE_RESERVED;
- break;
- }
-
- remote_address_obj->length = remote_data_len - 1;
- memcpy(remote_address_obj->remote_entity_address, &src_data[temp_index], remote_address_obj->length);
-
- *consumed_data_len = 1 + len_of_len + remote_data_len;
- return TCORE_SAT_SUCCESS;
-}
-
-static enum tcore_sat_result _sat_decode_network_access_name_tlv(unsigned char *tlv_str, int tlv_len,
- int curr_offset, struct tel_sat_network_access_name *access_name_obj, int *consumed_data_len)
-{
- int temp_index, idx, name_idx, name_length;
- unsigned char *src_data;
-
- if (tlv_str == NULL || consumed_data_len == NULL || access_name_obj == NULL) {
- dbg("[SAT] SAT PARSER - tlv_str == NULL || consumed_data_len == NULL || access_name_obj == NULL");
- return TCORE_SAT_ERROR_FATAL;
- }
-
- if (tlv_len <= (curr_offset + 1)) {
- dbg("[SAT] SAT PARSER - incorrect length original_command_len=%d", tlv_len);
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- /* tag */
- temp_index = curr_offset;
- src_data = &tlv_str[0];
- if ((src_data[temp_index++] & 0x7F) != SATK_NETWORK_ACCESS_TAG) {
- dbg("[SAT] SAT PARSER - network access name tag missing.");
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; /* Send TR */
- }
-
- /* length */
- name_length = src_data[temp_index++];
- if ((temp_index + name_length) > tlv_len) {
- dbg("[SAT] SAT PARSER - incorrect cmd len, expected len = %d, orig_len=%d",
- (temp_index + name_length), tlv_len);
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- access_name_obj->length = name_length;
- if (access_name_obj->length > SAT_NET_ACC_NAM_LEN_MAX) {
- dbg("[SAT] SAT PARSER - network access name is longer than capability");
- return TCORE_SAT_BEYOND_ME_CAPABILITY;
- }
-
- name_idx = 0;
- for (idx = 0; idx < access_name_obj->length; idx++) {
- dbg("data (%c) Bool(%d)", src_data[temp_index], g_ascii_isalpha(src_data[temp_index]));
-
- if (g_ascii_isalpha(src_data[temp_index])) {
- access_name_obj->network_access_name[name_idx] = src_data[temp_index];
- name_idx++;
- } else {
- if (src_data[temp_index] == 0x02) {/* 02 convert to "." */
- access_name_obj->network_access_name[name_idx] = '.';
- name_idx++;
- }
- }
-
- temp_index++;
- }
-
- /* network access name */
- dbg("network access name(%s)", access_name_obj->network_access_name);
-
- *consumed_data_len = 2 + name_length;
- return TCORE_SAT_SUCCESS;
-}
-
-static enum tcore_sat_result _sat_decode_text_attribute_tlv(unsigned char *tlv_str, int tlv_len,
- int curr_offset, struct tel_sat_text_attribute *text_attribute_obj, int *consumed_data_len)
-{
- int temp_index, length;
- unsigned char *src_data;
-
- if (tlv_str == NULL || consumed_data_len == NULL || text_attribute_obj == NULL) {
- dbg("[SAT] SAT PARSER - tlv_str == NULL || consumed_data_len == NULL || text_attribute_obj == NULL");
- return TCORE_SAT_ERROR_FATAL;
- }
-
- if (tlv_len <= (curr_offset + 1)) {
- dbg("[SAT] SAT PARSER - incorrect length original_command_len=%d", tlv_len);
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- /* tag */
- temp_index = curr_offset;
- src_data = &tlv_str[0];
- if ((src_data[temp_index++] & 0x7F) != SATK_TEXT_ATTRIBUTE_TAG) {
- dbg("[SAT] SAT PARSER - text attribute tag is missing");
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; /* Send TR */
- }
-
- /* length */
- length = src_data[temp_index++];
- if ((temp_index + length) > tlv_len) {
- dbg("[SAT] SAT PARSER - incorrect cmd len, expected len = %d, orig_len=%d", (temp_index + length), tlv_len);
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- /* attribute data */
- text_attribute_obj->b_txt_attr = TRUE;
- memcpy(text_attribute_obj->text_formatting, &src_data[temp_index], length);
-
- *consumed_data_len = 2 + length;
- return TCORE_SAT_SUCCESS;
-}
-
-/*
- * decode proactive cmd
- */
-/*
- * 6.4.1 DISPLAY TEXT
- */
-static enum tcore_sat_result _sat_decode_display_text(unsigned char *o_cmd_data, int o_length,
- int curr_offset, struct tcore_sat_proactive_command *sat_cmd_ind_data)
-{
- int temp_index = 0;
- int tlv_length = 0, remain_len = 0, expected_len = 0;
- int data_len_consumed = 0;
- unsigned char dev_id[4];
- unsigned char *cmd_data = NULL;
- enum tcore_sat_result rv = TCORE_SAT_SUCCESS;
-
- if (o_cmd_data == NULL) {
- dbg("[SAT] SAT PARSER - o_cmd_data == NULL");
- return TCORE_SAT_ERROR_FATAL;
- }
-
- cmd_data = &o_cmd_data[0];
- tlv_length = cmd_data[curr_offset-1];
- temp_index = curr_offset + 2;
- sat_cmd_ind_data->data.display_text.command_detail.cmd_num = cmd_data[temp_index++];
- sat_cmd_ind_data->data.display_text.command_detail.cmd_type = cmd_data[temp_index++];
-
- /* decode command qualifier */
- if (cmd_data[temp_index] & 0x01) {
- sat_cmd_ind_data->data.display_text.command_detail.cmd_qualifier.display_text.text_priority =
- TEXT_PRIORITY_HIGH;
- dbg("[SAT] SAT PARSER - msg_prio=TAPI_SAT_MSG_PRIORITY_HIGH.");
- } else {
- sat_cmd_ind_data->data.display_text.command_detail.cmd_qualifier.display_text.text_priority =
- TEXT_PRIORITY_NORMAL;
- dbg("[SAT] SAT PARSER - : msg_prio=TAPI_SAT_MSG_PRIORITY_NORMAL.");
- }
-
- if (cmd_data[temp_index] & 0x80) {
- sat_cmd_ind_data->data.display_text.command_detail.cmd_qualifier.display_text.text_clear_type =
- TEXT_WAIT_FOR_USER_TO_CLEAR_MSG;
- dbg("[SAT] SAT PARSER - : msgClear=TAPI_SAT_WAIT_FOR_USER_TO_CLEAR_MSG.");
- } else {
- sat_cmd_ind_data->data.display_text.command_detail.cmd_qualifier.display_text.text_clear_type =
- TEXT_AUTO_CLEAR_MSG_AFTER_A_DELAY;
- dbg("[SAT] SAT PARSER - msgClear=TAPI_SAT_AUTO_CLEAR_MSG_AFTER_A_DELAY.");
- }
-
- temp_index++;
- memcpy(dev_id, &cmd_data[temp_index], 4);
- rv = _sat_decode_device_identities_tlv(dev_id, &sat_cmd_ind_data->data.display_text.device_id);
- if (rv != TCORE_SAT_SUCCESS)
- return rv;
-
- temp_index += 4; /* device identities consumes 4 bytes. */
-
- remain_len = o_length-temp_index;
- expected_len = tlv_length-5-4;
- if (remain_len != expected_len) {
- dbg("[SAT] SAT PARSER - : mismatch!! remain_len=%d, expected_len=%d", remain_len, expected_len);
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- rv = _sat_decode_text_tlv(o_cmd_data, o_length, temp_index,
- &sat_cmd_ind_data->data.display_text.text,
- &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv;
-
- if (sat_cmd_ind_data->data.display_text.text.string_length <= 0) {
- err("[SAT] SAT PARSER - :string length is 0");
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- dbg("[SAT] SAT PARSER text(%s)", sat_cmd_ind_data->data.display_text.text.string);
- dbg("[SAT] SAT PARSER o_len(%d) temp_index(%d) data_len_consumed(%d)",
- o_length , temp_index, data_len_consumed);
-
- if (o_length-temp_index < data_len_consumed) {
- dbg("[SAT] SAT PARSER - :wrong text TLV.");
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- if (o_length-temp_index == data_len_consumed) {
- dbg("[SAT] SAT PARSER - :no more TLVs to decode.");
- return TCORE_SAT_SUCCESS;
- }
-
- temp_index += data_len_consumed; /* temp_index pointing to the Tag of next TLV */
-
- /* icon identifier */
- if ((cmd_data[temp_index] & 0x7F) == SATK_ICON_IDENTIFIER_TAG) {
- rv = _sat_decode_icon_identifier_tlv(o_cmd_data, o_length, temp_index,
- &sat_cmd_ind_data->data.display_text.icon_id,
- &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv; /* Send TR */
-
- if (o_length-temp_index == data_len_consumed) {
- dbg("[SAT] SAT PARSER - :no more TLVs to decode.");
- return TCORE_SAT_SUCCESS;
- }
-
- temp_index += data_len_consumed; /* temp_index pointing to the Tag of next TLV */
- }
-
- /* immediate response */
- sat_cmd_ind_data->data.display_text.immediate_response_requested = FALSE;
- if ((cmd_data[temp_index] & 0x7F) == SATK_IMMEDIATE_RESPONSE_TAG) {
- data_len_consumed = 2;
- dbg("[SAT] SAT PARSER - :immediate response required.");
- sat_cmd_ind_data->data.display_text.immediate_response_requested = TRUE;
- if (o_length-temp_index == data_len_consumed) {
- dbg("[SAT] SAT PARSER - :no more TLVs to decode.");
- return TCORE_SAT_SUCCESS;
- }
-
- temp_index += data_len_consumed; /* temp_index pointing to the Tag of next TLV */
- }
-
- /* time duration - optional */
- if ((cmd_data[temp_index] & 0x7F) == SATK_DURATION_TAG) {
- rv = _sat_decode_duration_tlv(o_cmd_data, o_length, temp_index,
- &sat_cmd_ind_data->data.display_text.duration,
- &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv; /* Send TR */
-
- if (o_length-temp_index == data_len_consumed) {
- dbg("[SAT] SAT PARSER - :no more TLVs to decode.");
- return TCORE_SAT_SUCCESS;
- }
-
- temp_index += data_len_consumed; /* temp_index pointing to the Tag of next TLV */
- }
-
- /* text attribute - optional */
- if ((cmd_data[temp_index] & 0x7F) == SATK_TEXT_ATTRIBUTE_TAG) {
- rv = _sat_decode_text_attribute_tlv(o_cmd_data, o_length, temp_index,
- &sat_cmd_ind_data->data.display_text.text_attribute,
- &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv; /* Send TR */
-
- if (o_length-temp_index == data_len_consumed) {
- dbg("[SAT] SAT PARSER - :no more TLVs to decode.");
- return TCORE_SAT_SUCCESS;
- }
-
- temp_index += data_len_consumed; /* temp_index pointing to the Tag of next TLV */
- }
-
- if (o_length > temp_index) {
- dbg("[SAT] SAT PARSER - : wrong text TLV, remaining data is found!!");
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- dbg("[SAT] SAT PARSER - :decoding done!.");
- return TCORE_SAT_SUCCESS;
-}
-
-/*
- * 6.4.2 GET INKEY
- */
-static enum tcore_sat_result _sat_decode_get_inkey(unsigned char *o_cmd_data, int o_length,
- int curr_offset, struct tcore_sat_proactive_command *sat_cmd_ind_data)
-{
- int temp_index = 0;
- int tlv_length = 0, remain_len = 0, expected_len = 0;
- int data_len_consumed = 0;
- unsigned char dev_id[4];
- unsigned char *cmd_data = NULL;
- enum tcore_sat_result rv = TCORE_SAT_SUCCESS;
-
- if (o_cmd_data == NULL) {
- dbg("[SAT] SAT PARSER - o_cmd_data == NULL");
- return TCORE_SAT_ERROR_FATAL;
- }
-
- cmd_data = &o_cmd_data[0];
- tlv_length = cmd_data[curr_offset-1];
- temp_index = curr_offset + 2;
- sat_cmd_ind_data->data.get_inkey.command_detail.cmd_num = cmd_data[temp_index++];
- sat_cmd_ind_data->data.get_inkey.command_detail.cmd_type = cmd_data[temp_index++];
-
- /* decode command qualifier */
- if (cmd_data[temp_index] & 0x01) {
- sat_cmd_ind_data->data.get_inkey.command_detail.cmd_qualifier.get_inkey.alphabet_set = TRUE;
- dbg("[SAT] SAT PARSER - Alphabet set");
- }
-
- if (cmd_data[temp_index] & 0x02) {
- sat_cmd_ind_data->data.get_inkey.command_detail.cmd_qualifier.get_inkey.alphabet_type = INPUT_ALPHABET_TYPE_UCS2;
- dbg("[SAT] SAT PARSER - INPUT_ALPHABET_TYPE_UCS2");
- } else {
- sat_cmd_ind_data->data.get_inkey.command_detail.cmd_qualifier.get_inkey.alphabet_type = INPUT_ALPHABET_TYPE_SMS_DEFAULT;
- dbg("[SAT] SAT PARSER - INPUT_ALPHABET_TYPE_SMS_DEFAULT");
- }
-
- if (cmd_data[temp_index] & 0x04) {
- sat_cmd_ind_data->data.get_inkey.command_detail.cmd_qualifier.get_inkey.inkey_type = INKEY_TYPE_YES_NO_REQUESTED;
- dbg("[SAT] SAT PARSER - INKEY_TYPE_YES_NO_REQUESTED");
- } else {
- sat_cmd_ind_data->data.get_inkey.command_detail.cmd_qualifier.get_inkey.inkey_type = INKEY_TYPE_CHARACTER_SET_ENABLED;
- dbg("[SAT] SAT PARSER - INKEY_TYPE_YES_NO_REQUESTED");
- }
-
- if (cmd_data[temp_index] & 0x08) {
- sat_cmd_ind_data->data.get_inkey.command_detail.cmd_qualifier.get_inkey.immediate_rsp_required = TRUE;
- dbg("[SAT] SAT PARSER - immediate response requested");
- }
-
- if (cmd_data[temp_index] & 0x80) {
- sat_cmd_ind_data->data.get_inkey.command_detail.cmd_qualifier.get_inkey.help_info = TRUE;
- dbg("[SAT] SAT PARSER - Help info");
- }
-
- /* device identities */
- temp_index++;
- memcpy(dev_id, &cmd_data[temp_index], 4);
- rv = _sat_decode_device_identities_tlv(dev_id, &sat_cmd_ind_data->data.get_inkey.device_id);
- if (rv != TCORE_SAT_SUCCESS)
- return rv;
-
- /* text */
- temp_index += 4;
-
- remain_len = o_length-temp_index;
- expected_len = tlv_length-5-4;
- if (remain_len != expected_len) {
- dbg("[SAT] SAT PARSER - : mismatch!! remain_len=%d, expected_len=%d", remain_len, expected_len);
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- rv = _sat_decode_text_tlv(o_cmd_data, o_length, temp_index,
- &sat_cmd_ind_data->data.get_inkey.text,
- &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv;
-
- if (sat_cmd_ind_data->data.get_inkey.text.string_length <= 0) {
- err("[SAT] SAT PARSER - :string length is 0");
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- dbg("[SAT] SAT PARSER text(%s)", sat_cmd_ind_data->data.get_inkey.text.string);
- dbg("[SAT] SAT PARSER o_len(%d) temp_index(%d) data_len_consumed(%d)",
- o_length , temp_index, data_len_consumed);
-
- if (o_length-temp_index < data_len_consumed) {
- dbg("[SAT] SAT PARSER - :wrong text TLV.");
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- if (o_length-temp_index == data_len_consumed) {
- dbg("[SAT] SAT PARSER - :no more TLVs to decode.");
- return TCORE_SAT_SUCCESS;
- }
-
- temp_index += data_len_consumed; /* temp_index pointing to the Tag of next TLV */
-
- /* icon identifier - optional */
- if ((cmd_data[temp_index] & 0x7F) == SATK_ICON_IDENTIFIER_TAG) {
- rv = _sat_decode_icon_identifier_tlv(o_cmd_data, o_length, temp_index,
- &sat_cmd_ind_data->data.get_inkey.icon_id,
- &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv; /* Send TR */
-
- if (o_length-temp_index == data_len_consumed) {
- dbg("[SAT] SAT PARSER - :no more TLVs to decode.");
- return TCORE_SAT_SUCCESS;
- }
-
- temp_index += data_len_consumed; /* temp_index pointing to the Tag of next TLV */
- }
-
- /* time duration - optional */
- if ((cmd_data[temp_index] & 0x7F) == SATK_DURATION_TAG) {
- rv = _sat_decode_duration_tlv(o_cmd_data, o_length, temp_index,
- &sat_cmd_ind_data->data.get_inkey.duration,
- &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv; /* Send TR */
-
- if (o_length-temp_index == data_len_consumed) {
- dbg("[SAT] SAT PARSER - :no more TLVs to decode.");
- return TCORE_SAT_SUCCESS;
- }
-
- temp_index += data_len_consumed; /* temp_index pointing to the Tag of next TLV */
- }
-
- /* text attribute - optional */
- if ((cmd_data[temp_index] & 0x7F) == SATK_TEXT_ATTRIBUTE_TAG) {
- rv = _sat_decode_text_attribute_tlv(o_cmd_data, o_length, temp_index,
- &sat_cmd_ind_data->data.get_inkey.text_attribute,
- &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv; /* Send TR */
-
- if (o_length-temp_index == data_len_consumed) {
- dbg("[SAT] SAT PARSER - :no more TLVs to decode.");
- return TCORE_SAT_SUCCESS;
- }
-
- temp_index += data_len_consumed; /* temp_index pointing to the Tag of next TLV */
- }
-
- if (o_length > temp_index) {
- dbg("[SAT] SAT PARSER - : wrong text TLV, remaining data is found!!");
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- dbg("[SAT] SAT PARSER - :decoding done!.");
- return TCORE_SAT_SUCCESS;
-}
-
-/*
- * 6.4.3 GET INPUT
- */
-static enum tcore_sat_result _sat_decode_get_input(unsigned char *o_cmd_data, int o_length,
- int curr_offset, struct tcore_sat_proactive_command *sat_cmd_ind_data)
-{
- int temp_index = 0;
- int tlv_length = 0, remain_len = 0, expected_len = 0;
- int data_len_consumed = 0;
- unsigned char dev_id[4];
- unsigned char *cmd_data = NULL;
- enum tcore_sat_result rv = TCORE_SAT_SUCCESS;
-
- if (o_cmd_data == NULL) {
- dbg("[SAT] SAT PARSER - o_cmd_data == NULL");
- return TCORE_SAT_ERROR_FATAL;
- }
-
- cmd_data = &o_cmd_data[0];
- tlv_length = cmd_data[curr_offset-1];
- temp_index = curr_offset + 2;
- sat_cmd_ind_data->data.get_input.command_detail.cmd_num = cmd_data[temp_index++];
- sat_cmd_ind_data->data.get_input.command_detail.cmd_type = cmd_data[temp_index++];
-
- /* decode command qualifier */
- if (cmd_data[temp_index] & 0x01) {
- sat_cmd_ind_data->data.get_input.command_detail.cmd_qualifier.get_input.alphabet_set = TRUE;
- dbg("[SAT] SAT PARSER - Alphabet set");
- } else {
- sat_cmd_ind_data->data.get_input.command_detail.cmd_qualifier.get_input.alphabet_set = FALSE;
- dbg("[SAT] SAT PARSER - Numeric info");
- }
-
- if (cmd_data[temp_index] & 0x02) {
- sat_cmd_ind_data->data.get_input.command_detail.cmd_qualifier.get_input.alphabet_type = INPUT_ALPHABET_TYPE_UCS2;
- dbg("[SAT] SAT PARSER - INPUT_ALPHABET_TYPE_UCS2");
- } else {
- sat_cmd_ind_data->data.get_input.command_detail.cmd_qualifier.get_input.alphabet_type = INPUT_ALPHABET_TYPE_SMS_DEFAULT;
- dbg("[SAT] SAT PARSER - INPUT_ALPHABET_TYPE_SMS_DEFAULT");
- }
-
- if (cmd_data[temp_index] & 0x04) {
- sat_cmd_ind_data->data.get_input.command_detail.cmd_qualifier.get_input.me_echo_user_input = FALSE;
- dbg("[SAT] SAT PARSER - user input not be revealed");
- } else {
- sat_cmd_ind_data->data.get_input.command_detail.cmd_qualifier.get_input.me_echo_user_input = TRUE;
- dbg("[SAT] SAT PARSER - Me echo user input");
- }
-
- if (cmd_data[temp_index] & 0x08) {
- sat_cmd_ind_data->data.get_input.command_detail.cmd_qualifier.get_input.user_input_unpacked_format = FALSE;
- dbg("[SAT] SAT PARSER - packing required");
- } else {
- sat_cmd_ind_data->data.get_input.command_detail.cmd_qualifier.get_input.user_input_unpacked_format = TRUE;
- dbg("[SAT] SAT PARSER - unpacked format");
- }
-
- if (cmd_data[temp_index] & 0x80) {
- sat_cmd_ind_data->data.get_input.command_detail.cmd_qualifier.get_input.help_info = TRUE;
- dbg("[SAT] SAT PARSER - Help info");
- }
-
- /* device identities */
- temp_index++;
- memcpy(dev_id, &cmd_data[temp_index], 4);
- rv = _sat_decode_device_identities_tlv(dev_id, &sat_cmd_ind_data->data.get_input.device_id);
- if (rv != TCORE_SAT_SUCCESS)
- return rv;
-
- /* text - mandatory */
- temp_index += 4;
-
- remain_len = o_length-temp_index;
- expected_len = tlv_length - 5 - 4;
- if (remain_len != expected_len) {
- dbg("[SAT] SAT PARSER - : mismatch!! remain_len=%d, expected_len=%d", remain_len, expected_len);
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- rv = _sat_decode_text_tlv(o_cmd_data, o_length, temp_index,
- &sat_cmd_ind_data->data.get_input.text,
- &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv;
-
- if (sat_cmd_ind_data->data.get_input.text.string_length <= 0)
- err("[SAT] SAT PARSER - :string length is 0");
-
- dbg("[SAT] SAT PARSER text(%s)", sat_cmd_ind_data->data.get_input.text.string);
- dbg("[SAT] SAT PARSER o_len(%d) temp_index(%d) data_len_consumed(%d)",
- o_length , temp_index, data_len_consumed);
-
- if (o_length-temp_index < data_len_consumed) {
- dbg("[SAT] SAT PARSER - :wrong text TLV.");
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- if (o_length-temp_index == data_len_consumed) {
- dbg("[SAT] SAT PARSER - :no more TLVs to decode.");
- return TCORE_SAT_SUCCESS;
- }
-
- temp_index += data_len_consumed; /* temp_index pointing to the Tag of next TLV */
-
- /* response length - mandatory */
- rv = _sat_decode_response_length_tlv(o_cmd_data, o_length, temp_index,
- &sat_cmd_ind_data->data.get_input.rsp_len,
- &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv;
-
- if (o_length-temp_index == data_len_consumed) {
- dbg("[SAT] SAT PARSER - :no more TLVs to decode.");
- return TCORE_SAT_SUCCESS;
- }
-
- temp_index += data_len_consumed; /* temp_index pointing to the Tag of next TLV */
-
- /* default text - optional */
- if ((o_cmd_data[temp_index] & 0x7F) == SATK_DEFAULT_TEXT_TAG) {
- rv = _sat_decode_text_tlv(o_cmd_data, o_length, temp_index,
- &sat_cmd_ind_data->data.get_input.default_text,
- &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv;
-
- if (sat_cmd_ind_data->data.get_input.default_text.string_length <= 0)
- err("[SAT] SAT PARSER - :string length is 0");
-
- dbg("[SAT] SAT PARSER default text(%s)", sat_cmd_ind_data->data.get_input.default_text.string);
- if (o_length-temp_index == data_len_consumed) {
- dbg("[SAT] SAT PARSER - :no more TLVs to decode.");
- return TCORE_SAT_SUCCESS;
- }
-
- temp_index += data_len_consumed; /* temp_index pointing to the Tag of next TLV */
- }
-
- /* icon identifier */
- if ((cmd_data[temp_index] & 0x7F) == SATK_ICON_IDENTIFIER_TAG) {
- rv = _sat_decode_icon_identifier_tlv(o_cmd_data, o_length, temp_index,
- &sat_cmd_ind_data->data.get_input.icon_id,
- &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv; /* Send TR */
-
- if (o_length-temp_index == data_len_consumed) {
- dbg("[SAT] SAT PARSER - :no more TLVs to decode.");
- return TCORE_SAT_SUCCESS;
- }
- temp_index += data_len_consumed; /* temp_index pointing to the Tag of next TLV */
- }
-
- /* text attribute - optional */
- if ((cmd_data[temp_index] & 0x7F) == SATK_TEXT_ATTRIBUTE_TAG) {
- rv = _sat_decode_text_attribute_tlv(o_cmd_data, o_length, temp_index,
- &sat_cmd_ind_data->data.get_input.text_attribute,
- &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv; /* Send TR */
-
- if (o_length-temp_index == data_len_consumed) {
- dbg("[SAT] SAT PARSER - :no more TLVs to decode.");
- return TCORE_SAT_SUCCESS;
- }
-
- temp_index += data_len_consumed; /* temp_index pointing to the Tag of next TLV */
- }
-
- if (o_length > temp_index) {
- dbg("[SAT] SAT PARSER - : wrong text TLV, remaining data is found!!");
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- dbg("[SAT] SAT PARSER - :decoding done!.");
- return TCORE_SAT_SUCCESS;
-}
-
-/*
- * 6.4.4 MORE TIME
- */
-static enum tcore_sat_result _sat_decode_more_time(unsigned char *o_cmd_data, int o_length,
- int curr_offset, struct tcore_sat_proactive_command *sat_cmd_ind_data)
-{
- int temp_index = 0;
- unsigned char dev_id[4];
- unsigned char *cmd_data = NULL;
- enum tcore_sat_result rv = TCORE_SAT_SUCCESS;
-
- if (o_cmd_data == NULL) {
- dbg("[SAT] SAT PARSER - o_cmd_data == NULL");
- return TCORE_SAT_ERROR_FATAL;
- }
-
- /* command detail */
- cmd_data = &o_cmd_data[0];
- temp_index = curr_offset + 2;
- sat_cmd_ind_data->data.setup_event_list.command_detail.cmd_num = cmd_data[temp_index++];
- sat_cmd_ind_data->data.setup_event_list.command_detail.cmd_type = cmd_data[temp_index++];
-
- /* device identifier */
- temp_index++;
- memcpy(dev_id, &cmd_data[temp_index], 4);
- rv = _sat_decode_device_identities_tlv(dev_id, &sat_cmd_ind_data->data.setup_event_list.device_id);
- if (rv != TCORE_SAT_SUCCESS)
- return rv;
-
- temp_index += 4;
- dbg("[SAT] SAT PARSER - :decoding done!.");
- return TCORE_SAT_SUCCESS;
-}
-
-/*
- * 6.4.5 PLAY TONE
- */
-static enum tcore_sat_result _sat_decode_play_tone(unsigned char *o_cmd_data, int o_length,
- int curr_offset, struct tcore_sat_proactive_command *sat_cmd_ind_data)
-{
- int temp_index = 0, data_len_consumed = 0;
- unsigned char dev_id[4];
- unsigned char *cmd_data = NULL;
- enum tcore_sat_result rv = TCORE_SAT_SUCCESS;
-
- if (o_cmd_data == NULL) {
- dbg("[SAT] SAT PARSER - o_cmd_data == NULL");
- return TCORE_SAT_ERROR_FATAL;
- }
-
- /* command detail */
- cmd_data = &o_cmd_data[0];
- temp_index = curr_offset + 2;
- sat_cmd_ind_data->data.play_tone.command_detail.cmd_num = cmd_data[temp_index++];
- sat_cmd_ind_data->data.play_tone.command_detail.cmd_type = cmd_data[temp_index++];
-
- /* decode command qualifier */
- if (cmd_data[temp_index] & 0x01)
- sat_cmd_ind_data->data.play_tone.command_detail.cmd_qualifier.play_tone.vibration_alert = VIBRATE_ALERT_REQUIRED;
- else
- sat_cmd_ind_data->data.play_tone.command_detail.cmd_qualifier.play_tone.vibration_alert = VIBRATE_ALERT_OPTIONAL;
-
- /* device identifier */
- temp_index++;
- memcpy(dev_id, &cmd_data[temp_index], 4);
- rv = _sat_decode_device_identities_tlv(dev_id, &sat_cmd_ind_data->data.play_tone.device_id);
- if (rv != TCORE_SAT_SUCCESS)
- return rv;
-
- /* alpha id - optional */
- temp_index += 4;
- if ((cmd_data[temp_index] & 0x7F) == SATK_ALPHA_IDENTIFIER_TAG) {
- rv = _sat_decode_alpha_identifier_tlv(o_cmd_data, o_length, temp_index,
- &sat_cmd_ind_data->data.play_tone.alpha_id,
- &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv;
-
- temp_index += data_len_consumed;
- if (temp_index >= o_length) {
- dbg("[SAT] SAT PARSER - no more TLVs to decode.");
- dbg("[SAT] SAT PARSER - default value is set - tone type, duration");
- sat_cmd_ind_data->data.play_tone.tone.tone_type = GENERAL_BEEP;
- sat_cmd_ind_data->data.play_tone.duration.time_unit = TIME_UNIT_SECONDS;
- sat_cmd_ind_data->data.play_tone.duration.time_interval = 2;
-
- return TCORE_SAT_SUCCESS;
- }
- }
-
- /* tone - optional */
- if ((cmd_data[temp_index] & 0x7F) == SATK_TONE_TAG) {
- rv = _sat_decode_tone_tlv(o_cmd_data, o_length, temp_index,
- &sat_cmd_ind_data->data.play_tone.tone,
- &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv;
-
- temp_index += data_len_consumed;
- } else
- sat_cmd_ind_data->data.play_tone.tone.tone_type = GENERAL_BEEP;
-
- /* time duration - optional */
- if ((cmd_data[temp_index] & 0x7F) == SATK_DURATION_TAG) {
- rv = _sat_decode_duration_tlv(o_cmd_data, o_length, temp_index,
- &sat_cmd_ind_data->data.play_tone.duration,
- &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv; /* Send TR */
-
- temp_index += data_len_consumed;
- if (temp_index >= o_length) {
- dbg("[SAT] SAT PARSER - no more TLVs to decode.");
- return TCORE_SAT_SUCCESS;
- }
- } else {
- dbg("[SAT] SAT PARSER - Duration TLV not present, ME should use a default value.");
- sat_cmd_ind_data->data.play_tone.duration.time_unit = TIME_UNIT_SECONDS;
- sat_cmd_ind_data->data.play_tone.duration.time_interval = 2;
- }
-
- /* icon identifier */
- if ((cmd_data[temp_index] & 0x7F) == SATK_ICON_IDENTIFIER_TAG) {
- data_len_consumed = 0;
- rv = _sat_decode_icon_identifier_tlv(o_cmd_data, o_length, temp_index,
- &sat_cmd_ind_data->data.play_tone.icon_id,
- &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; /* Send TR */
-
- if (temp_index + data_len_consumed >= o_length) {
- dbg("[SAT] SAT PARSER - no more TLVs to decode.");
- return TCORE_SAT_SUCCESS;
- }
-
- temp_index += data_len_consumed; /* temp_index pointing to the Tag of next TLV */
- }
-
- /* text attribute - optional */
- if ((cmd_data[temp_index] & 0x7F) == SATK_TEXT_ATTRIBUTE_TAG) {
- rv = _sat_decode_text_attribute_tlv(o_cmd_data, o_length, temp_index,
- &sat_cmd_ind_data->data.play_tone.text_attribute,
- &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv; /* Send TR */
-
- if (temp_index + data_len_consumed >= o_length) {
- dbg("[SAT] SAT PARSER - no more TLVs to decode.");
- return TCORE_SAT_SUCCESS;
- }
-
- temp_index += data_len_consumed; /* temp_index pointing to the Tag of next TLV */
- }
-
- /*
- * TODO:
- * frames
- */
-
- dbg("[SAT] SAT PARSER - :decoding done!.");
- return TCORE_SAT_SUCCESS;
-}
-
-/*
- * 6.4.7 REFRESH
- */
-static enum tcore_sat_result _sat_decode_refresh(unsigned char *o_cmd_data, int o_length,
- int curr_offset, struct tcore_sat_proactive_command *sat_cmd_ind_data)
-{
- int temp_index = 0, data_len_consumed = 0;
- unsigned char dev_id[4];
- unsigned char *cmd_data = NULL;
- enum tcore_sat_result rv = TCORE_SAT_SUCCESS;
-
- if (o_cmd_data == NULL) {
- dbg("[SAT] SAT PARSER - o_cmd_data == NULL");
- return TCORE_SAT_ERROR_FATAL;
- }
-
- /* command detail */
- cmd_data = &o_cmd_data[0];
- temp_index = curr_offset + 2;
- sat_cmd_ind_data->data.refresh.command_detail.cmd_num = cmd_data[temp_index++];
- sat_cmd_ind_data->data.refresh.command_detail.cmd_type = cmd_data[temp_index++];
-
- /* decode command qualifier */
- switch (cmd_data[temp_index]) {
- case SIM_REFRESH_CMD_INIT_AND_FULL_FCN:
- case SIM_REFRESH_CMD_FCN:
- case SIM_REFRESH_CMD_INIT_AND_FCN:
- case SIM_REFRESH_CMD_INIT:
- case SIM_REFRESH_CMD_RESET:
- sat_cmd_ind_data->data.refresh.command_detail.cmd_qualifier.refresh.refresh = cmd_data[temp_index];
- dbg("[SAT] SAT PARSER - : refresh mode=[0x%02x]:0-init&FFCN, 1-FCN, 2-init&FCN, 3-init, 4-reset",
- cmd_data[temp_index]);
- break;
-
- case SIM_REFRESH_CMD_3G_APPLICATION_RESET:
- case SIM_REFRESH_CMD_3G_SESSION_RESET:
- case SIM_REFRESH_CMD_RESERVED:
- default:
- dbg("[SAT] SAT PARSER - : refresh mode=0x%02x Not Supported", cmd_data[temp_index]);
- return TCORE_SAT_BEYOND_ME_CAPABILITY;
- }
-
- /* device identifier */
- temp_index++;
- memcpy(dev_id, &cmd_data[temp_index], 4);
- rv = _sat_decode_device_identities_tlv(dev_id, &sat_cmd_ind_data->data.refresh.device_id);
- if (rv != TCORE_SAT_SUCCESS)
- return rv;
-
- /* check file list */
- temp_index += 4;
- if ((sat_cmd_ind_data->data.refresh.command_detail.cmd_qualifier.refresh.refresh == SIM_REFRESH_CMD_FCN)
- || (sat_cmd_ind_data->data.refresh.command_detail.cmd_qualifier.refresh.refresh == SIM_REFRESH_CMD_INIT_AND_FCN)) {
- rv = _sat_decode_file_list_tlv(o_cmd_data, o_length, temp_index,
- &sat_cmd_ind_data->data.refresh.file_list,
- &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv;
- } else
- sat_cmd_ind_data->data.refresh.file_list.file_count = 0;
-
- dbg("[SAT] SAT PARSER - :decoding done!.");
- return TCORE_SAT_SUCCESS;
-}
-
-/*
- * 6.4.8 SETUP MENU
- */
-static enum tcore_sat_result _sat_decode_setup_menu(unsigned char *tlv_str, int tlv_len,
- int curr_offset, struct tcore_sat_proactive_command *pactive_cmd_ind_obj)
-{
- int temp_index = 0;
- int data_len_consumed = 0;
- unsigned char dev_id[4];
- unsigned char *src_data;
- enum tcore_sat_result rv = TCORE_SAT_SUCCESS;
-
- /* access command detail */
- temp_index = curr_offset + 2; /* move the temp_index to command detail info + 2(tag and length) */
- src_data = &tlv_str[0];
-
- /* In this time, the point of temp_index is COMMAND NUMBER */
- /* [1] insert command detail information into each proactive command data structure. */
- pactive_cmd_ind_obj->data.setup_menu.command_detail.cmd_num = src_data[temp_index++];
- pactive_cmd_ind_obj->data.setup_menu.command_detail.cmd_type = src_data[temp_index++];
-
- /* [2] decode COMMAND QUALIFIER */
- /*
- * -bit 1: 0 = no selection preference;
- * 1 = selection using soft key preferred.
- * -bits 2 to 7: = RFU.
- * -bit 8: 0 = no help information available;
- * 1 = help information available.
- */
-
- /* [2-1] selection preference */
- if (src_data[temp_index] & 0x01) {
- pactive_cmd_ind_obj->data.setup_menu.command_detail.cmd_qualifier.setup_menu.select_preference =
- SELECTION_PREFERENCE_USING_SOFT_KEY;
- dbg("[SAT] SAT PARSER - sel_pref=SAT_SELECTION_PREFERENCE_USING_SOFT_KEY.");
- } else {
- pactive_cmd_ind_obj->data.setup_menu.command_detail.cmd_qualifier.setup_menu.select_preference =
- SELECTION_PREFERENCE_NONE_REQUESTED;
- dbg("[SAT] SAT PARSER - : sel_pref=SAT_SELECTION_PREFERENCE_NONE_REQUESTED.");
- }
-
- /* [2-2] help available */
- if (src_data[temp_index] & 0x80) {
- pactive_cmd_ind_obj->data.setup_menu.command_detail.cmd_qualifier.setup_menu.help_info =
- TRUE;
- dbg("[SAT] SAT PARSER - : is help Available=TRUE.");
- } else {
- pactive_cmd_ind_obj->data.setup_menu.command_detail.cmd_qualifier.setup_menu.help_info =
- FALSE;
- dbg("[SAT] SAT PARSER - is help Available=FALSE.");
- }
-
- /* In this time, the point of temp_index is DEVICE IDENTITIES. */
- /* [3] decode DEVICE IDENTITIES TLV */
- temp_index++;
- memcpy(dev_id, &src_data[temp_index], 4);
- rv = _sat_decode_device_identities_tlv(dev_id, &pactive_cmd_ind_obj->data.setup_menu.device_id);
- if (rv != TCORE_SAT_SUCCESS) {
- /* send TR in SatkProcessProactiveCmdInd() */
- return rv;
- }
-
- /* In this time, the point of temp_index is ALPHA IDENTIFIER. 11 or 12. */
- /* [4] decode ALPHA IDENTIFIER TLV */
- temp_index += 4;
- dbg("[SAT] SAT PARSER - :temp_index=%d", temp_index);
- rv = _sat_decode_alpha_identifier_tlv(src_data, tlv_len, temp_index,
- &pactive_cmd_ind_obj->data.setup_menu.alpha_id,
- &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv;
-
- /* In this time, the point of temp_index is ITEM TLV */
- /* [5] decode ITEM LIST (at least one is mandatory) */
- temp_index += data_len_consumed;
- pactive_cmd_ind_obj->data.setup_menu.menu_item_cnt = 0;
- do {
- data_len_consumed = 0;
- if ((src_data[temp_index] & 0x7F) == SATK_ITEM_TAG) {
- rv = _sat_decode_item_tlv(src_data, tlv_len, temp_index,
- &pactive_cmd_ind_obj->data.setup_menu.menu_item[pactive_cmd_ind_obj->data.setup_menu.menu_item_cnt],
- &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv;
-
- if (!pactive_cmd_ind_obj->data.setup_menu.menu_item[0].text_len)
- break;
- } else {
- if (pactive_cmd_ind_obj->data.setup_menu.menu_item_cnt == 0) {
- dbg("menu item is not exist.");
- return TCORE_SAT_REQUIRED_VALUE_MISSING;
- }
- /* else */
- break; /* ??? */
- }
- pactive_cmd_ind_obj->data.setup_menu.menu_item_cnt++;
- temp_index += data_len_consumed;
-
- if (temp_index >= tlv_len)
- break;
- } while (pactive_cmd_ind_obj->data.setup_menu.menu_item_cnt < SAT_MENU_ITEM_COUNT_MAX);
-
- dbg("[SAT] SAT PARSER - :setup menu item_count=%d", pactive_cmd_ind_obj->data.setup_menu.menu_item_cnt);
- if (temp_index >= tlv_len) {
- dbg("[SAT] SAT PARSER - :no more TLVs to decode.");
- /* send TR in SatkProcessProactiveCmdInd() */
- return TCORE_SAT_SUCCESS;
- }
-
- /* [6] (optional TLV) decode ITEMS NEXT ACTION INDICATOR TLV */
- if ((src_data[temp_index] & 0x7F) == SATK_ITEMS_NEXT_ACTION_INDICATOR_TAG) {
- data_len_consumed = 0;
- rv = _sat_decode_item_next_action_indicator_tlv(tlv_str, tlv_len, temp_index,
- &pactive_cmd_ind_obj->data.setup_menu.next_act_ind_list,
- &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv;
-
- if (temp_index + data_len_consumed >= tlv_len) {
- dbg("[SAT] SAT PARSER - no more TLVs to decode.");
- /* send the data to Noti manager. */
- return TCORE_SAT_SUCCESS;
- }
-
- temp_index += data_len_consumed; /* temp_index pointing to the Tag of next TLV */
- } else {
- dbg("[SAT] SAT PARSER - ITEMS NEXT ACTION INDICATOR TLV Not present");
- }
-
- /* [7] (optional TLV) decode ICON IDENTIFIER TLV */
- if ((src_data[temp_index] & 0x7F) == SATK_ICON_IDENTIFIER_TAG) {
- data_len_consumed = 0;
- rv = _sat_decode_icon_identifier_tlv(tlv_str, tlv_len, temp_index,
- &pactive_cmd_ind_obj->data.setup_menu.icon_id,
- &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv;
-
- if (temp_index + data_len_consumed >= tlv_len) {
- dbg("[SAT] SAT PARSER - no more TLVs to decode.");
- /* send the data to Noti manager. */
- return TCORE_SAT_SUCCESS;
- }
-
- temp_index += data_len_consumed; /* temp_index pointing to the Tag of next TLV */
- } else {
- dbg("[SAT] SAT PARSER - ICON IDENTIFIER TLV Not present");
- }
-
- /* [8] (optional TLV) decode ICON IDENTIFIER LIST TLV */
- if ((src_data[temp_index] & 0x7F) == SATK_ITEM_ICON_IDENTIFIER_LIST_TAG) {
- data_len_consumed = 0;
- rv = _sat_decode_icon_identifier_list_tlv(tlv_str, tlv_len, temp_index,
- &pactive_cmd_ind_obj->data.setup_menu.icon_list,
- &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv; /* Send TR */
-
- if (temp_index + data_len_consumed >= tlv_len) {
- dbg("[SAT] SAT PARSER - no more TLVs to decode.");
- /* send the data to Noti manager. */
- return TCORE_SAT_SUCCESS;
- }
-
- temp_index += data_len_consumed; /* temp_index pointing to the Tag of next TLV */
-
- } else {
- dbg("[SAT] SAT PARSER - ICON IDENTIFIER LIST TLV not present");
- }
-
- /* text attribute - optional */
- if ((src_data[temp_index] & 0x7F) == SATK_TEXT_ATTRIBUTE_TAG) {
- rv = _sat_decode_text_attribute_tlv(tlv_str, tlv_len, temp_index,
- &pactive_cmd_ind_obj->data.setup_menu.text_attribute,
- &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv; /* Send TR */
-
- if (temp_index + data_len_consumed >= tlv_len) {
- dbg("[SAT] SAT PARSER - no more TLVs to decode.");
- return TCORE_SAT_SUCCESS;
- }
-
- temp_index += data_len_consumed; /* temp_index pointing to the Tag of next TLV */
- }
-
- /* text attribute list - optional */
- if ((src_data[temp_index] & 0x7F) == SATK_TEXT_ATTRIBUTE_LIST_TAG) {
- int attr_item_temp_index = 0, item_cnt = 0;
- int txt_attr_list_len = 0;
-
- struct tel_sat_text_attribute_list *txt_attr_list = NULL;
-
- txt_attr_list = &pactive_cmd_ind_obj->data.setup_menu.text_attribute_list;
-
- /* length */
- temp_index++;
- txt_attr_list_len = src_data[temp_index];
- if (txt_attr_list_len == 0) {
- dbg("[SAT] - Text Attribute List is nothing");
- return TCORE_SAT_REQUIRED_VALUE_MISSING;
- }
-
- /* item cnt - each text attribute length is 4byte */
- item_cnt = txt_attr_list_len/4;
- txt_attr_list->list_cnt = item_cnt;
- dbg("[SAT] - text attribute item cnt(%d)", item_cnt);
-
- /* get attribute data */
- temp_index++;
- for (attr_item_temp_index = 0; attr_item_temp_index < item_cnt; attr_item_temp_index++) {
- memcpy(txt_attr_list->text_attribute_list[attr_item_temp_index].text_formatting, &src_data[temp_index], 4);
- temp_index += 4;
- }
-
- dbg("[SAT] SAT PARSER - done to decode text attribute list");
- }
-
- dbg("[SAT] SAT PARSER - no more TLVs to decode.");
- return TCORE_SAT_SUCCESS;
-}
-
-/*
- * 6.4.9 SELECT ITEM
- */
-static enum tcore_sat_result _sat_decode_select_item(unsigned char *o_cmd_data, int o_length,
- int curr_offset, struct tcore_sat_proactive_command *sat_cmd_ind_data)
-{
- int temp_index = 0;
- int data_len_consumed = 0;
- unsigned char dev_id[4];
- unsigned char *cmd_data = NULL;
- enum tcore_sat_result rv = TCORE_SAT_SUCCESS;
-
- if (o_cmd_data == NULL) {
- dbg("[SAT] SAT PARSER - o_cmd_data == NULL");
- return TCORE_SAT_ERROR_FATAL;
- }
-
- cmd_data = &o_cmd_data[0];
- temp_index = curr_offset + 2;
- sat_cmd_ind_data->data.select_item.command_detail.cmd_num = cmd_data[temp_index++];
- sat_cmd_ind_data->data.select_item.command_detail.cmd_type = cmd_data[temp_index++];
-
- /* decode command qualifier */
- if (cmd_data[temp_index] & 0x01) {
- if (cmd_data[temp_index] & 0x02) {
- sat_cmd_ind_data->data.select_item.command_detail.cmd_qualifier.select_item.presentation_type = PRESENTATION_TYPE_NAVIGATION_OPTION;
- dbg("[SAT] SAT PARSER - PRESENTATION_TYPE_NAVIGATION_OPTION");
- } else {
- sat_cmd_ind_data->data.select_item.command_detail.cmd_qualifier.select_item.presentation_type = PRESENTATION_TYPE_DATA_VALUE;
- dbg("[SAT] SAT PARSER - PRESENTATION_TYPE_DATA_VALUE");
- }
- } else {
- sat_cmd_ind_data->data.select_item.command_detail.cmd_qualifier.select_item.presentation_type = PRESENTATION_TYPE_NOT_SPECIFIED;
- dbg("[SAT] SAT PARSER - PRESENTATION_TYPE_NOT_SPECIFIED");
- }
-
- if (cmd_data[temp_index] & 0x04) {
- sat_cmd_ind_data->data.select_item.command_detail.cmd_qualifier.select_item.select_preference = SELECTION_PREFERENCE_USING_SOFT_KEY;
- dbg("[SAT] SAT PARSER - SELECTION_PREFERENCE_USING_SOFT_KEY");
- } else {
- sat_cmd_ind_data->data.select_item.command_detail.cmd_qualifier.select_item.select_preference = SELECTION_PREFERENCE_NONE_REQUESTED;
- dbg("[SAT] SAT PARSER - SELECTION_PREFERENCE_NONE_REQUESTED");
- }
-
- if (cmd_data[temp_index] & 0x80) {
- sat_cmd_ind_data->data.select_item.command_detail.cmd_qualifier.select_item.help_info = TRUE;
- dbg("[SAT] SAT PARSER - Help info");
- }
-
- /* device identities */
- temp_index++;
- memcpy(dev_id, &cmd_data[temp_index], 4);
- rv = _sat_decode_device_identities_tlv(dev_id, &sat_cmd_ind_data->data.select_item.device_id);
- if (rv != TCORE_SAT_SUCCESS)
- return rv;
-
- /* alpha identifier */
- temp_index += 4;
- if ((cmd_data[temp_index] & 0x7F) == SATK_ALPHA_IDENTIFIER_TAG) {
- rv = _sat_decode_alpha_identifier_tlv(o_cmd_data, o_length, temp_index,
- &sat_cmd_ind_data->data.select_item.alpha_id,
- &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv;
-
- temp_index += data_len_consumed;
- }
-
- /* item objects */
- sat_cmd_ind_data->data.select_item.menu_item_cnt = 0;
- do {
- data_len_consumed = 0;
-
- if ((cmd_data[temp_index] & 0x7F) == SATK_ITEM_TAG) {
- rv = _sat_decode_item_tlv(o_cmd_data, o_length, temp_index,
- &sat_cmd_ind_data->data.select_item.menu_item[sat_cmd_ind_data->data.select_item.menu_item_cnt],
- &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv;
- } else {
- if (sat_cmd_ind_data->data.select_item.menu_item_cnt == 0) {
- dbg("menu item is not exist.");
- return TCORE_SAT_REQUIRED_VALUE_MISSING;
- }
- /* else */
- break; /* ??? */
- }
-
- sat_cmd_ind_data->data.select_item.menu_item_cnt++;
- temp_index += data_len_consumed;
-
- if (temp_index >= o_length)
- break;
-
- } while (sat_cmd_ind_data->data.select_item.menu_item_cnt < SAT_MENU_ITEM_COUNT_MAX);
-
- dbg("[SAT] SAT PARSER - select menu item_count=%d", sat_cmd_ind_data->data.select_item.menu_item_cnt);
- if (temp_index >= o_length) {
- dbg("[SAT] SAT PARSER - :no more TLVs to decode.");
- return TCORE_SAT_SUCCESS;
- }
-
- /* item next action indicator */
- if ((cmd_data[temp_index] & 0x7F) == SATK_ITEMS_NEXT_ACTION_INDICATOR_TAG) {
- data_len_consumed = 0;
- rv = _sat_decode_item_next_action_indicator_tlv(o_cmd_data, o_length, temp_index,
- &sat_cmd_ind_data->data.select_item.item_next_act_ind_list, &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv;
-
- if (temp_index + data_len_consumed >= o_length) {
- dbg("[SAT] SAT PARSER - no more TLVs to decode.");
- return TCORE_SAT_SUCCESS;
- }
-
- temp_index += data_len_consumed;
- }
-
- /* item identifier */
- if ((cmd_data[temp_index] & 0x7F) == SATK_ITEM_IDENTIFIER_TAG) {
- data_len_consumed = 0;
- rv = _sat_decode_item_identifier_tlv(o_cmd_data, o_length, temp_index,
- &sat_cmd_ind_data->data.select_item.item_identifier,
- &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv;
-
- if (temp_index + data_len_consumed >= o_length) {
- dbg("[SAT] SAT PARSER - no more TLVs to decode.");
- return TCORE_SAT_SUCCESS;
- }
-
- temp_index += data_len_consumed; /* temp_index pointing to the Tag of next TLV */
- }
-
- /* icon identifier */
- if ((cmd_data[temp_index] & 0x7F) == SATK_ICON_IDENTIFIER_TAG) {
- data_len_consumed = 0;
- rv = _sat_decode_icon_identifier_tlv(o_cmd_data, o_length, temp_index,
- &sat_cmd_ind_data->data.select_item.icon_id,
- &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; /* Send TR */
-
- if (temp_index + data_len_consumed >= o_length) {
- dbg("[SAT] SAT PARSER - no more TLVs to decode.");
- return TCORE_SAT_SUCCESS;
- }
-
- temp_index += data_len_consumed; /* temp_index pointing to the Tag of next TLV */
- }
-
- if ((cmd_data[temp_index] & 0x7F) == SATK_ITEM_ICON_IDENTIFIER_LIST_TAG) {
- data_len_consumed = 0;
- rv = _sat_decode_icon_identifier_list_tlv(o_cmd_data, o_length, temp_index,
- &sat_cmd_ind_data->data.select_item.icon_list,
- &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv; /* Send TR */
-
- if (temp_index + data_len_consumed >= o_length) {
- dbg("[SAT] SAT PARSER - no more TLVs to decode.");
- return TCORE_SAT_SUCCESS;
- }
-
- temp_index += data_len_consumed; /* temp_index pointing to the Tag of next TLV */
- }
-
- /* text attribute - optional */
- if ((cmd_data[temp_index] & 0x7F) == SATK_TEXT_ATTRIBUTE_TAG) {
- rv = _sat_decode_text_attribute_tlv(o_cmd_data, o_length, temp_index,
- &sat_cmd_ind_data->data.select_item.text_attribute,
- &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv; /* Send TR */
-
- if (temp_index + data_len_consumed >= o_length) {
- dbg("[SAT] SAT PARSER - no more TLVs to decode.");
- return TCORE_SAT_SUCCESS;
- }
-
- temp_index += data_len_consumed; /* temp_index pointing to the Tag of next TLV */
- }
-
- /* text attribute list - optional */
- if ((cmd_data[temp_index] & 0x7F) == SATK_TEXT_ATTRIBUTE_LIST_TAG) {
- int attr_item_temp_index = 0, item_cnt = 0;
- int txt_attr_list_len = 0;
-
- struct tel_sat_text_attribute_list *txt_attr_list = NULL;
-
- txt_attr_list = &sat_cmd_ind_data->data.select_item.text_attribute_list;
-
- /* length */
- temp_index++;
- txt_attr_list_len = cmd_data[temp_index];
- if (txt_attr_list_len == 0) {
- dbg("[SAT] - Text Attribute List is nothing");
- return TCORE_SAT_REQUIRED_VALUE_MISSING;
- }
-
- /* item cnt - each text attribute length is 4byte */
- item_cnt = txt_attr_list_len/4;
- txt_attr_list->list_cnt = item_cnt;
- dbg("[SAT] - text attribute item cnt(%d)", item_cnt);
-
- /* get attribute data */
- temp_index++;
- for (attr_item_temp_index = 0; attr_item_temp_index < item_cnt; attr_item_temp_index++) {
- memcpy(txt_attr_list->text_attribute_list[attr_item_temp_index].text_formatting, &cmd_data[temp_index], 4);
- temp_index += 4;
- }
-
- dbg("[SAT] SAT PARSER - done to decode text attribute list");
- }
-
- dbg("[SAT] SAT PARSER - :decoding done!.");
- return TCORE_SAT_SUCCESS;
-}
-
-/*
- * 6.4.10 SEND SMS
- */
-static enum tcore_sat_result _sat_decode_send_sms(unsigned char *o_cmd_data, int o_length,
- int curr_offset, struct tcore_sat_proactive_command *sat_cmd_ind_data)
-{
- int temp_index = 0;
- int data_len_consumed = 0;
- unsigned char dev_id[4];
- unsigned char *cmd_data = NULL;
- enum tcore_sat_result rv = TCORE_SAT_SUCCESS;
-
- if (o_cmd_data == NULL) {
- dbg("[SAT] SAT PARSER - o_cmd_data == NULL");
- return TCORE_SAT_ERROR_FATAL;
- }
-
- cmd_data = &o_cmd_data[0];
- temp_index = curr_offset + 2;
- sat_cmd_ind_data->data.send_sms.command_detail.cmd_num = cmd_data[temp_index++];
- sat_cmd_ind_data->data.send_sms.command_detail.cmd_type = cmd_data[temp_index++];
-
- /* decode command qualifier */
- if (cmd_data[temp_index] & 0x01)
- sat_cmd_ind_data->data.send_sms.command_detail.cmd_qualifier.send_sms.packing_by_me_required = TRUE;
- else {
- sat_cmd_ind_data->data.send_sms.command_detail.cmd_qualifier.send_sms.packing_by_me_required = FALSE;
- dbg("[SAT] SAT PARSER - packing by me required is false");
- }
-
- /* device identities */
- temp_index++;
- memcpy(dev_id, &cmd_data[temp_index], 4);
- rv = _sat_decode_device_identities_tlv(dev_id, &sat_cmd_ind_data->data.send_sms.device_id);
- if (rv != TCORE_SAT_SUCCESS)
- return rv;
-
- /* alpha identifier */
- temp_index += 4;
- if ((cmd_data[temp_index] & 0x7F) == SATK_ALPHA_IDENTIFIER_TAG) {
- data_len_consumed = 0;
- rv = _sat_decode_alpha_identifier_tlv(o_cmd_data, o_length, temp_index,
- &sat_cmd_ind_data->data.send_sms.alpha_id,
- &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv;
-
- temp_index += data_len_consumed;
- }
-
- /* address */
- if ((cmd_data[temp_index] & 0x7F) == SATK_ADDRESS_TAG) {
- data_len_consumed = 0;
- rv = _sat_decode_address_tlv(o_cmd_data, o_length, temp_index,
- &sat_cmd_ind_data->data.send_sms.address,
- &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv;
-
- temp_index += data_len_consumed;
- }
-
- /* SMS-TPDU */
- data_len_consumed = 0;
- rv = _sat_decode_sms_tpdu_tlv(o_cmd_data, o_length, temp_index,
- &sat_cmd_ind_data->data.send_sms.sms_tpdu,
- &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv;
-
- if (temp_index + data_len_consumed >= o_length) {
- dbg("[SAT] SAT PARSER - no more TLVs to decode.");
- return TCORE_SAT_SUCCESS;
- }
-
- /* icon identifier */
- temp_index += data_len_consumed;
- if ((cmd_data[temp_index] & 0x7F) == SATK_ICON_IDENTIFIER_TAG) {
- data_len_consumed = 0;
- rv = _sat_decode_icon_identifier_tlv(o_cmd_data, o_length, temp_index,
- &sat_cmd_ind_data->data.send_sms.icon_id,
- &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; /* Send TR */
-
- if (temp_index + data_len_consumed >= o_length) {
- dbg("[SAT] SAT PARSER - no more TLVs to decode.");
- return TCORE_SAT_SUCCESS;
- }
-
- temp_index += data_len_consumed; /* temp_index pointing to the Tag of next TLV */
- }
-
- dbg("[SAT] SAT PARSER - :decoding done!.");
- return TCORE_SAT_SUCCESS;
-}
-
-/*
- * 6.4.11 SEND SS
- */
-static enum tcore_sat_result _sat_decode_send_ss(unsigned char *o_cmd_data, int o_length,
- int curr_offset, struct tcore_sat_proactive_command *sat_cmd_ind_data)
-{
- int temp_index = 0, data_len_consumed = 0;
- unsigned char dev_id[4];
- unsigned char *cmd_data = NULL;
- enum tcore_sat_result rv = TCORE_SAT_SUCCESS;
-
- if (o_cmd_data == NULL || sat_cmd_ind_data == NULL) {
- dbg("[SAT] SAT PARSER - o_cmd_data == NULL");
- return TCORE_SAT_ERROR_FATAL;
- }
-
- cmd_data = &o_cmd_data[0];
- temp_index = curr_offset + 2;
- sat_cmd_ind_data->data.send_ss.command_detail.cmd_num = cmd_data[temp_index++];
- sat_cmd_ind_data->data.send_ss.command_detail.cmd_type = cmd_data[temp_index++];
-
- /* command detail */
- temp_index++; /* RFU */
-
- /* device identities */
- memcpy(dev_id, &cmd_data[temp_index], 4);
- rv = _sat_decode_device_identities_tlv(dev_id, &sat_cmd_ind_data->data.send_ss.device_id);
- if (rv != TCORE_SAT_SUCCESS)
- return rv;
-
- /* alpha identifier - optional */
- temp_index += 4;
- if ((cmd_data[temp_index] & 0x7F) == SATK_ALPHA_IDENTIFIER_TAG) {
- rv = _sat_decode_alpha_identifier_tlv(o_cmd_data, o_length, temp_index,
- &sat_cmd_ind_data->data.send_ss.alpha_id,
- &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv;
-
- temp_index += data_len_consumed;
- }
-
- /* ss string */
- rv = _sat_decode_ss_string_tlv(o_cmd_data, o_length, temp_index,
- &sat_cmd_ind_data->data.send_ss.ss_string,
- &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv;
-
- /* icon identifier - optional */
- temp_index += data_len_consumed;
- if ((cmd_data[temp_index] & 0x7F) == SATK_ICON_IDENTIFIER_TAG) {
- data_len_consumed = 0;
-
- rv = _sat_decode_icon_identifier_tlv(o_cmd_data, o_length, temp_index,
- &sat_cmd_ind_data->data.send_ss.icon_id,
- &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; /* Send TR */
- }
-
- dbg("[SAT] SAT PARSER - :decoding done!.");
- return TCORE_SAT_SUCCESS;
-}
-
-/*
- * 6.4.12 SEND USSD
- */
-static enum tcore_sat_result _sat_decode_send_ussd(unsigned char *o_cmd_data, int o_length,
- int curr_offset, struct tcore_sat_proactive_command *sat_cmd_ind_data)
-{
- int temp_index = 0, data_len_consumed = 0;
- unsigned char dev_id[4];
- unsigned char *cmd_data = NULL;
- enum tcore_sat_result rv = TCORE_SAT_SUCCESS;
-
- if (o_cmd_data == NULL || sat_cmd_ind_data == NULL) {
- dbg("[SAT] SAT PARSER - o_cmd_data == NULL");
- return TCORE_SAT_ERROR_FATAL;
- }
-
- cmd_data = &o_cmd_data[0];
- temp_index = curr_offset + 2;
- sat_cmd_ind_data->data.send_ussd.command_detail.cmd_num = cmd_data[temp_index++];
- sat_cmd_ind_data->data.send_ussd.command_detail.cmd_type = cmd_data[temp_index++];
-
- /* command detail */
- temp_index++; /* RFU */
-
- /* device identities */
- memcpy(dev_id, &cmd_data[temp_index], 4);
- rv = _sat_decode_device_identities_tlv(dev_id, &sat_cmd_ind_data->data.send_ussd.device_id);
- if (rv != TCORE_SAT_SUCCESS)
- return rv;
-
- /* alpha identifier - optional */
- temp_index += 4;
- if ((cmd_data[temp_index] & 0x7F) == SATK_ALPHA_IDENTIFIER_TAG) {
- rv = _sat_decode_alpha_identifier_tlv(o_cmd_data, o_length, temp_index,
- &sat_cmd_ind_data->data.send_ussd.alpha_id,
- &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv;
-
- temp_index += data_len_consumed;
- }
-
- /* ussd string */
- rv = _sat_decode_ussd_string_tlv(o_cmd_data, o_length, temp_index,
- &sat_cmd_ind_data->data.send_ussd.ussd_string,
- &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv;
-
- /* icon identifier- optional */
- temp_index += data_len_consumed;
- if ((cmd_data[temp_index] & 0x7F) == SATK_ICON_IDENTIFIER_TAG) {
- data_len_consumed = 0;
-
- rv = _sat_decode_icon_identifier_tlv(o_cmd_data, o_length, temp_index,
- &sat_cmd_ind_data->data.send_ussd.icon_id,
- &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; /* Send TR */
- }
-
- dbg("[SAT] SAT PARSER - :decoding done!.");
- return TCORE_SAT_SUCCESS;
-}
-
-/*
- * 6.4.13 SETUP CALL
- */
-static enum tcore_sat_result _sat_decode_setup_call(unsigned char *o_cmd_data, int o_length,
- int curr_offset, struct tcore_sat_proactive_command *sat_cmd_ind_data)
-{
- int temp_index = 0, data_len_consumed = 0;
- unsigned char dev_id[4];
- unsigned char *cmd_data = NULL;
- enum tcore_sat_result rv = TCORE_SAT_SUCCESS;
-
- if (o_cmd_data == NULL || sat_cmd_ind_data == NULL) {
- dbg("[SAT] SAT PARSER - o_cmd_data == NULL");
- return TCORE_SAT_ERROR_FATAL;
- }
-
- /* command detail */
- cmd_data = &o_cmd_data[0];
- temp_index = curr_offset + 2;
- sat_cmd_ind_data->data.setup_call.command_detail.cmd_num = cmd_data[temp_index++];
- sat_cmd_ind_data->data.setup_call.command_detail.cmd_type = cmd_data[temp_index++];
-
- /* decode command qualifier */
- switch (cmd_data[temp_index]) {
- case SETUP_CALL_IF_ANOTHER_CALL_NOT_BUSY:
- case SETUP_CALL_IF_ANOTHER_CALL_NOT_BUSY_WITH_REDIAL:
- case SETUP_CALL_PUT_ALL_OTHER_CALLS_ON_HOLD:
- case SETUP_CALL_PUT_ALL_OTHER_CALLS_ON_HOLD_WITH_REDIAL:
- case SETUP_CALL_DISCONN_ALL_OTHER_CALLS:
- case SETUP_CALL_DISCONN_ALL_OTHER_CALLS_WITH_REDIAL:
- sat_cmd_ind_data->data.setup_call.command_detail.cmd_qualifier.setup_call.setup_call = cmd_data[temp_index];
- dbg("[SAT] SAT PARSER - setup_call.cmd_qualifier= 0x%02x",
- sat_cmd_ind_data->data.setup_call.command_detail.cmd_qualifier.setup_call.setup_call);
- break;
-
- case SETUP_CALL_RESERVED: /* Fallthrough */
- default:
- dbg("[SAT] SAT PARSER - setup_call.cmd_qualifier= 0x%02x", cmd_data[temp_index]);
- return TCORE_SAT_BEYOND_ME_CAPABILITY;
- }
-
- /* device identifier */
- temp_index++;
- memcpy(dev_id, &cmd_data[temp_index], 4);
- rv = _sat_decode_device_identities_tlv(dev_id, &sat_cmd_ind_data->data.setup_call.device_id);
- if (rv != TCORE_SAT_SUCCESS)
- return rv;
-
- /* alpha identifier (user confirmation) - optional */
- temp_index += 4;
- if ((cmd_data[temp_index] & 0x7F) == SATK_ALPHA_IDENTIFIER_TAG) {
- rv = _sat_decode_alpha_identifier_tlv(o_cmd_data, o_length, temp_index,
- &sat_cmd_ind_data->data.setup_call.user_confirm_alpha_id,
- &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv;
-
- temp_index += data_len_consumed;
- }
-
- /* address */
- rv = _sat_decode_address_tlv(o_cmd_data, o_length, temp_index,
- &sat_cmd_ind_data->data.setup_call.address,
- &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv;
-
- temp_index += data_len_consumed;
- if (temp_index >= o_length) {
- dbg("[SAT] SAT PARSER - no more TLVs to decode.");
- return TCORE_SAT_SUCCESS;
- }
-
- /* capability configuration parameter - optional */
- if ((cmd_data[temp_index] & 0x7F) == SATK_CAPABILITY_CONFIGURATION_PARAMETERS_TAG) {
- rv = _sat_decode_ccp_tlv(o_cmd_data, o_length, temp_index,
- &sat_cmd_ind_data->data.setup_call.ccp,
- &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv; /* Send TR */
-
- temp_index += data_len_consumed;
- if (temp_index >= o_length) {
- dbg("[SAT] SAT PARSER - no more TLVs to decode.");
- return TCORE_SAT_SUCCESS;
- }
- }
-
- /* sub address - optional */
- if ((cmd_data[temp_index] & 0x7F) == SATK_SUB_ADDRESS_TAG) {
- rv = _sat_decode_sub_address_tlv(o_cmd_data, o_length, temp_index,
- &sat_cmd_ind_data->data.setup_call.subaddress,
- &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv; /* Send TR */
-
- temp_index += data_len_consumed;
- if (temp_index >= o_length) {
- dbg("[SAT] SAT PARSER - no more TLVs to decode.");
- return TCORE_SAT_SUCCESS;
- }
- }
-
- /* time duration - optional */
- if ((cmd_data[temp_index] & 0x7F) == SATK_DURATION_TAG) {
- rv = _sat_decode_duration_tlv(o_cmd_data, o_length, temp_index,
- &sat_cmd_ind_data->data.setup_call.duration,
- &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv; /* Send TR */
-
- temp_index += data_len_consumed;
- if (temp_index >= o_length) {
- dbg("[SAT] SAT PARSER - no more TLVs to decode.");
- return TCORE_SAT_SUCCESS;
- }
- }
-
- /* icon identifier (user confirmation) - optional */
- if ((cmd_data[temp_index] & 0x7F) == SATK_ICON_IDENTIFIER_TAG) {
- data_len_consumed = 0;
- rv = _sat_decode_icon_identifier_tlv(o_cmd_data, o_length, temp_index,
- &sat_cmd_ind_data->data.setup_call.user_confirm_icon_id,
- &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; /* Send TR */
-
- temp_index += data_len_consumed;
- if (temp_index >= o_length) {
- dbg("[SAT] SAT PARSER - no more TLVs to decode.");
- return TCORE_SAT_SUCCESS;
- }
- }
-
- /* alpha identifier (call setup) - optional */
- if ((cmd_data[temp_index] & 0x7F) == SATK_ALPHA_IDENTIFIER_TAG) {
- rv = _sat_decode_alpha_identifier_tlv(o_cmd_data, o_length, temp_index,
- &sat_cmd_ind_data->data.setup_call.call_setup_alpha_id,
- &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv;
-
- temp_index += data_len_consumed;
- if (temp_index >= o_length) {
- dbg("[SAT] SAT PARSER - no more TLVs to decode.");
- return TCORE_SAT_SUCCESS;
- }
- }
-
- /* icon identifier (call setup) - optional */
- if ((cmd_data[temp_index] & 0x7F) == SATK_ICON_IDENTIFIER_TAG) {
- data_len_consumed = 0;
- rv = _sat_decode_icon_identifier_tlv(o_cmd_data, o_length, temp_index,
- &sat_cmd_ind_data->data.setup_call.call_setup_icon_id,
- &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; /* Send TR */
-
- temp_index += data_len_consumed;
- if (temp_index >= o_length) {
- dbg("[SAT] SAT PARSER - no more TLVs to decode.");
- return TCORE_SAT_SUCCESS;
- }
- }
-
- /*
- * TODO -
- * Text Attribute (user_confirmation , call_setup)
- */
-
- dbg("[SAT] SAT PARSER - :decoding done!.");
- return TCORE_SAT_SUCCESS;
-}
-
-/*
- * 6.4.15 PROVIDE LOCAL INFO
- */
-static enum tcore_sat_result _sat_decode_provide_local_info(unsigned char *o_cmd_data, int o_length,
- int curr_offset, struct tcore_sat_proactive_command *sat_cmd_ind_data)
-{
- int temp_index = 0;
- unsigned char dev_id[4];
- unsigned char *cmd_data = NULL;
- enum tcore_sat_result rv = TCORE_SAT_SUCCESS;
-
- if (o_cmd_data == NULL) {
- dbg("[SAT] SAT PARSER - o_cmd_data == NULL");
- return TCORE_SAT_ERROR_FATAL;
- }
-
- /* command detail */
- cmd_data = &o_cmd_data[0];
- temp_index = curr_offset + 2;
- sat_cmd_ind_data->data.setup_event_list.command_detail.cmd_num = cmd_data[temp_index++];
- sat_cmd_ind_data->data.setup_event_list.command_detail.cmd_type = cmd_data[temp_index++];
-
- /* decode command qualifier */
- switch (cmd_data[temp_index]) {
- case LOCAL_INFO_DATE_TIME_AND_TIMEZONE:
- case LOCAL_INFO_LANGUAGE:
- sat_cmd_ind_data->data.setup_event_list.command_detail.cmd_qualifier.provide_local_info.provide_local_info = cmd_data[temp_index];
- break;
-
- /*
- * TODO -
- * Other cases
- */
- default:
- sat_cmd_ind_data->data.setup_event_list.command_detail.cmd_qualifier.provide_local_info.provide_local_info = LOCAL_INFO_RESERVED;
- break;
- }
-
- /* device identifier */
- temp_index++;
- memcpy(dev_id, &cmd_data[temp_index], 4);
- rv = _sat_decode_device_identities_tlv(dev_id, &sat_cmd_ind_data->data.setup_event_list.device_id);
- if (rv != TCORE_SAT_SUCCESS)
- return rv;
-
- /*
- * TODO -
- * UTRAN Measurement Qualifier
- */
-
- dbg("[SAT] SAT PARSER - :decoding done!.");
- return TCORE_SAT_SUCCESS;
-}
-
-/*
- * 6.4.16 SETUP EVENT LIST
- */
-static enum tcore_sat_result _sat_decode_setup_event_list(unsigned char *o_cmd_data, int o_length,
- int curr_offset, struct tcore_sat_proactive_command *sat_cmd_ind_data)
-{
- int temp_index = 0, data_len_consumed = 0;
- unsigned char dev_id[4];
- unsigned char *cmd_data = NULL;
- enum tcore_sat_result rv = TCORE_SAT_SUCCESS;
-
- if (o_cmd_data == NULL) {
- dbg("[SAT] SAT PARSER - o_cmd_data == NULL");
- return TCORE_SAT_ERROR_FATAL;
- }
-
- /* command detail */
- cmd_data = &o_cmd_data[0];
- temp_index = curr_offset + 2;
- sat_cmd_ind_data->data.setup_event_list.command_detail.cmd_num = cmd_data[temp_index++];
- sat_cmd_ind_data->data.setup_event_list.command_detail.cmd_type = cmd_data[temp_index++];
-
- /* device identifier */
- temp_index++;
- memcpy(dev_id, &cmd_data[temp_index], 4);
- rv = _sat_decode_device_identities_tlv(dev_id, &sat_cmd_ind_data->data.setup_event_list.device_id);
- if (rv != TCORE_SAT_SUCCESS)
- return rv;
-
- /* event list */
- temp_index += 4;
- rv = _sat_decode_event_list_tlv(o_cmd_data, o_length, temp_index,
- &sat_cmd_ind_data->data.setup_event_list.event_list,
- &data_len_consumed);
-
- dbg("[SAT] SAT PARSER - :decoding done!.");
- return TCORE_SAT_SUCCESS;
-}
-
-/*
- * 6.4.22 SETUP IDLE MODE TEXT
- */
-static enum tcore_sat_result _sat_decode_setup_idle_mode_text(unsigned char *o_cmd_data, int o_length,
- int curr_offset, struct tcore_sat_proactive_command *sat_cmd_ind_data)
-{
- int temp_index = 0, data_len_consumed = 0;
- unsigned char dev_id[4];
- unsigned char *cmd_data = NULL;
- enum tcore_sat_result rv = TCORE_SAT_SUCCESS;
-
- if (o_cmd_data == NULL) {
- dbg("[SAT] SAT PARSER - o_cmd_data == NULL");
- return TCORE_SAT_ERROR_FATAL;
- }
-
- /* command detail */
- cmd_data = &o_cmd_data[0];
- temp_index = curr_offset + 2;
- sat_cmd_ind_data->data.setup_idle_mode_text.command_detail.cmd_num = cmd_data[temp_index++];
- sat_cmd_ind_data->data.setup_idle_mode_text.command_detail.cmd_type = cmd_data[temp_index++];
-
- /* device identifier */
- temp_index++;
- memcpy(dev_id, &cmd_data[temp_index], 4);
- rv = _sat_decode_device_identities_tlv(dev_id, &sat_cmd_ind_data->data.setup_idle_mode_text.device_id);
- if (rv != TCORE_SAT_SUCCESS)
- return rv;
-
- /* text string */
- temp_index += 4;
- rv = _sat_decode_text_tlv(o_cmd_data, o_length, temp_index,
- &sat_cmd_ind_data->data.setup_idle_mode_text.text,
- &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv;
-
- if (sat_cmd_ind_data->data.setup_idle_mode_text.text.string_length < 0) {
- err("[SAT] SAT PARSER - :string length is less than 0");
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- dbg("[SAT] SAT PARSER text(%s)", sat_cmd_ind_data->data.setup_idle_mode_text.text.string);
- dbg("[SAT] SAT PARSER o_len(%d) temp_index(%d) data_len_consumed(%d)",
- o_length , temp_index, data_len_consumed);
-
- if (temp_index + data_len_consumed > o_length) {
- err("[SAT] SAT PARSER - Wrong String TLV");
- return TCORE_SAT_BEYOND_ME_CAPABILITY;
- } else if (temp_index + data_len_consumed == o_length) {
- dbg("[SAT] SAT PARSER - :no more TLVs to decode.");
- return TCORE_SAT_SUCCESS;
- }
-
- /* icon identifier */
- temp_index += data_len_consumed;
- if ((cmd_data[temp_index] & 0x7F) == SATK_ICON_IDENTIFIER_TAG) {
- data_len_consumed = 0;
- rv = _sat_decode_icon_identifier_tlv(o_cmd_data, o_length, temp_index,
- &sat_cmd_ind_data->data.setup_idle_mode_text.icon_id,
- &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; /* Send TR */
-
- if (temp_index + data_len_consumed >= o_length) {
- dbg("[SAT] SAT PARSER - no more TLVs to decode.");
- return TCORE_SAT_SUCCESS;
- }
-
- temp_index += data_len_consumed; /* temp_index pointing to the Tag of next TLV */
- }
-
- /*
- * TODO:
- * Text Attribute
- */
-
- dbg("[SAT] SAT PARSER - :decoding done!.");
- return TCORE_SAT_SUCCESS;
-}
-
-/*
- * 6.4.24 SEND DTMF
- */
-static enum tcore_sat_result _sat_decode_send_dtmf(unsigned char *o_cmd_data, int o_length,
- int curr_offset, struct tcore_sat_proactive_command *sat_cmd_ind_data)
-{
- int temp_index = 0, data_len_consumed = 0;
- unsigned char dev_id[4];
- unsigned char *cmd_data = NULL;
- enum tcore_sat_result rv = TCORE_SAT_SUCCESS;
-
- if (o_cmd_data == NULL) {
- dbg("[SAT] SAT PARSER - o_cmd_data == NULL");
- return TCORE_SAT_ERROR_FATAL;
- }
-
- /* command detail */
- cmd_data = &o_cmd_data[0];
- temp_index = curr_offset + 2;
- sat_cmd_ind_data->data.send_dtmf.command_detail.cmd_num = cmd_data[temp_index++];
- sat_cmd_ind_data->data.send_dtmf.command_detail.cmd_type = cmd_data[temp_index++];
-
- /* device identifier */
- temp_index++;
- memcpy(dev_id, &cmd_data[temp_index], 4);
- rv = _sat_decode_device_identities_tlv(dev_id, &sat_cmd_ind_data->data.send_dtmf.device_id);
- if (rv != TCORE_SAT_SUCCESS)
- return rv;
-
- /* alpha identifier - optional */
- temp_index += 4;
- if ((cmd_data[temp_index] & 0x7F) == SATK_ALPHA_IDENTIFIER_TAG) {
- rv = _sat_decode_alpha_identifier_tlv(o_cmd_data, o_length, temp_index,
- &sat_cmd_ind_data->data.send_dtmf.alpha_id,
- &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv;
-
- temp_index += data_len_consumed;
- }
-
- /* DTMF string - mandatory */
- if ((cmd_data[temp_index] & 0x7F) == SATK_DTMF_STRING_TAG) {
- rv = _sat_decode_dtmf_string_tlv(o_cmd_data, o_length, temp_index,
- &sat_cmd_ind_data->data.send_dtmf.dtmf_string,
- &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv;
-
- if (temp_index + data_len_consumed >= o_length) {
- dbg("[SAT] SAT PARSER - no more TLVs to decode.");
- return TCORE_SAT_SUCCESS;
- }
-
- temp_index += data_len_consumed;
- } else {
- dbg("[SAT] SAT PARSER - DTMF tlv is missed.");
- return TCORE_SAT_REQUIRED_VALUE_MISSING;
- }
-
- /* icon identifier - optional */
- if ((cmd_data[temp_index] & 0x7F) == SATK_ICON_IDENTIFIER_TAG) {
- data_len_consumed = 0;
- rv = _sat_decode_icon_identifier_tlv(o_cmd_data, o_length, temp_index,
- &sat_cmd_ind_data->data.send_dtmf.icon_id,
- &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
-
- if (temp_index + data_len_consumed >= o_length) {
- dbg("[SAT] SAT PARSER - no more TLVs to decode.");
- return TCORE_SAT_SUCCESS;
- }
-
- temp_index += data_len_consumed; /* temp_index pointing to the Tag of next TLV */
- }
-
- /*
- * TODO:
- * Text Attribute, Frame Identifier
- */
-
- dbg("[SAT] SAT PARSER - :decoding done!.");
- return TCORE_SAT_SUCCESS;
-}
-
-/*
- * 6.4.25 LANGUAGE NOTIFICATION
- */
-static enum tcore_sat_result _sat_decode_language_notification(unsigned char *o_cmd_data, int o_length,
- int curr_offset, struct tcore_sat_proactive_command *sat_cmd_ind_data)
-{
- int temp_index = 0;
- unsigned char dev_id[4];
- unsigned char *cmd_data = NULL;
- enum tcore_sat_result rv = TCORE_SAT_SUCCESS;
-
- if (o_cmd_data == NULL) {
- dbg("[SAT] SAT PARSER - o_cmd_data == NULL");
- return TCORE_SAT_ERROR_FATAL;
- }
-
- /* command detail */
- cmd_data = &o_cmd_data[0];
- temp_index = curr_offset + 2;
- sat_cmd_ind_data->data.language_notification.command_detail.cmd_num = cmd_data[temp_index++];
- sat_cmd_ind_data->data.language_notification.command_detail.cmd_type = cmd_data[temp_index++];
-
- /* decode command qualifier */
- if (cmd_data[temp_index] & 0x01)
- sat_cmd_ind_data->data.language_notification.command_detail.cmd_qualifier.language_notification.specific_language = TRUE;
- else
- sat_cmd_ind_data->data.language_notification.command_detail.cmd_qualifier.language_notification.specific_language = FALSE;
-
- /* device identifier */
- temp_index++;
- memcpy(dev_id, &cmd_data[temp_index], 4);
- rv = _sat_decode_device_identities_tlv(dev_id, &sat_cmd_ind_data->data.language_notification.device_id);
- if (rv != TCORE_SAT_SUCCESS)
- return rv;
-
- /* language - conditional */
- temp_index += 4;
- if (sat_cmd_ind_data->data.language_notification.command_detail.cmd_qualifier.language_notification.specific_language == TRUE) {
- if ((cmd_data[temp_index] & 0x7F) == SATK_LANGUAGE_TAG) {
- rv = _sat_decode_language_tlv(cmd_data, o_length, temp_index,
- &sat_cmd_ind_data->data.language_notification.language);
- if (rv != TCORE_SAT_SUCCESS)
- return rv;
- } else {
- dbg("[SAT] SAT PARSER - Language TLV is required but missing.");
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
- } else {
- sat_cmd_ind_data->data.language_notification.language = SIM_LANG_UNSPECIFIED;
- dbg("[SAT] SAT PARSER - non-specific language");
- }
-
- dbg("[SAT] SAT PARSER - :decoding done!.");
- return TCORE_SAT_SUCCESS;
-}
-
-/*
- * 6.4.26 LAUNCH BROWSER
- */
-static enum tcore_sat_result _sat_decode_launch_browser(unsigned char *o_cmd_data, int o_length,
- int curr_offset, struct tcore_sat_proactive_command *sat_cmd_ind_data)
-{
- int temp_index = 0, data_len_consumed = 0;
- unsigned char dev_id[4];
- unsigned char *cmd_data = NULL;
- enum tcore_sat_result rv = TCORE_SAT_SUCCESS;
-
- if (o_cmd_data == NULL) {
- dbg("[SAT] SAT PARSER - o_cmd_data == NULL");
- return TCORE_SAT_ERROR_FATAL;
- }
-
- /* command detail */
- cmd_data = &o_cmd_data[0];
- temp_index = curr_offset + 2;
- sat_cmd_ind_data->data.launch_browser.command_detail.cmd_num = cmd_data[temp_index++];
- sat_cmd_ind_data->data.launch_browser.command_detail.cmd_type = cmd_data[temp_index++];
-
- /* decode command qualifier */
- switch (cmd_data[temp_index]) {
- case 0x00:
- sat_cmd_ind_data->data.launch_browser.command_detail.cmd_qualifier.launch_browser.launch_browser =
- LAUNCH_BROWSER_IF_NOT_ALREADY_LAUNCHED;
- break;
-
- case 0x01:
- sat_cmd_ind_data->data.launch_browser.command_detail.cmd_qualifier.launch_browser.launch_browser =
- LAUNCH_BROWSER_NOT_USED;
- break;
-
- case 0x02:
- sat_cmd_ind_data->data.launch_browser.command_detail.cmd_qualifier.launch_browser.launch_browser =
- LAUNCH_BROWSER_USE_EXISTING_BROWSER;
- break;
-
- case 0x03:
- sat_cmd_ind_data->data.launch_browser.command_detail.cmd_qualifier.launch_browser.launch_browser =
- LAUNCH_BROWSER_CLOSE_AND_LAUNCH_NEW_BROWSER;
- break;
-
- case 0x04:
- sat_cmd_ind_data->data.launch_browser.command_detail.cmd_qualifier.launch_browser.launch_browser =
- LAUNCH_BROWSER_NOT_USED2;
- break;
-
- default:
- sat_cmd_ind_data->data.launch_browser.command_detail.cmd_qualifier.launch_browser.launch_browser =
- LAUNCH_BROWSER_RESERVED;
- break;
- }
-
- /* device identifier */
- temp_index++;
- memcpy(dev_id, &cmd_data[temp_index], 4);
- rv = _sat_decode_device_identities_tlv(dev_id, &sat_cmd_ind_data->data.language_notification.device_id);
- if (rv != TCORE_SAT_SUCCESS)
- return rv;
-
- temp_index += 4;
-
- /* Browser Identity TLV - Optional */
- if ((cmd_data[temp_index] & 0x7F) == SATK_BROWSER_IDENTITY_TAG) {
- rv = _sat_decode_browser_identity_tlv(o_cmd_data, o_length, temp_index,
- &sat_cmd_ind_data->data.launch_browser.browser_id,
- &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv;
-
- temp_index += data_len_consumed;
- } else {
- dbg("[SAT] SAT PARSER - Browser ID NOT present");
- }
-
- /* URL TLV - Mandatory */
- if ((cmd_data[temp_index] & 0x7F) == SATK_URL_TAG) {
- rv = _sat_decode_url_tlv(o_cmd_data, o_length, temp_index,
- &sat_cmd_ind_data->data.launch_browser.url,
- &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv;
-
- if (temp_index + data_len_consumed >= o_length) {
- dbg("[SAT] SAT PARSER - No more TLVs to decode, decoding done.");
- return TCORE_SAT_SUCCESS;
- } else {
- dbg("[SAT] SAT PARSER - more TLVs to decode, decoding continue.");
- temp_index += data_len_consumed;
- }
- } else {
- dbg("[SAT] SAT PARSER - Browser URL NOT present! BUG! this value is mandatory!!!");
- return TCORE_SAT_REQUIRED_VALUE_MISSING;
- }
-
- /* bearer - optional */
- if ((cmd_data[temp_index] & 0x7F) == SATK_BEARER_TAG) {
- rv = _sat_decode_bearer_tlv(o_cmd_data, o_length, temp_index,
- &sat_cmd_ind_data->data.launch_browser.bearer,
- &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv;
-
- if (temp_index + data_len_consumed >= o_length) {
- dbg("[SAT] SAT PARSER - No more TLVs to decode, decoding done.");
- return TCORE_SAT_SUCCESS;
- } else
- temp_index += data_len_consumed;
- } else {
- dbg("[SAT] SAT PARSER - Bearer TLV Not present.");
- }
-
- /* Provisioning reference file - optional */
- sat_cmd_ind_data->data.launch_browser.file_ref_count = 0;
- while ((cmd_data[temp_index] & 0x7F) == SATK_PROVISIONING_REF_FILE_TAG) {
- if (sat_cmd_ind_data->data.launch_browser.file_ref_count >= SAT_PROVISIONING_REF_MAX_COUNT) {
- dbg("[SAT] SAT PARSER - More number of PRF entries than can be handled");
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- rv = _sat_decode_provisioning_file_ref_tlv(o_cmd_data, o_length, temp_index,
- &sat_cmd_ind_data->data.launch_browser.file_list[sat_cmd_ind_data->data.launch_browser.file_ref_count],
- &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv;
- else
- sat_cmd_ind_data->data.launch_browser.file_ref_count++;
-
- if (temp_index + data_len_consumed >= o_length) {
- dbg("[SAT] SAT PARSER - No more TLVs to decode, decoding done.");
- return TCORE_SAT_SUCCESS;
- } else
- temp_index += data_len_consumed;
- }
-
- /* text string(gateway/proxy identity) - optional */
- if ((cmd_data[temp_index] & 0x7F) == SATK_TEXT_STRING_TAG) {
- rv = _sat_decode_text_tlv(o_cmd_data, o_length, temp_index,
- &sat_cmd_ind_data->data.launch_browser.gateway_proxy_text,
- &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv;
-
- if (temp_index + data_len_consumed >= o_length) {
- dbg("[SAT] SAT PARSER - No more TLVs to decode, decoding done.");
- return TCORE_SAT_SUCCESS;
- } else
- temp_index += data_len_consumed;
- }
-
- /* alpha identifier - optional */
- if ((cmd_data[temp_index] & 0x7F) == SATK_ALPHA_IDENTIFIER_TAG) {
- rv = _sat_decode_alpha_identifier_tlv(o_cmd_data, o_length, temp_index,
- &sat_cmd_ind_data->data.launch_browser.user_confirm_alpha_id,
- &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv;
-
- if (temp_index + data_len_consumed >= o_length) {
- dbg("[SAT] SAT PARSER - No more TLVs to decode, decoding done.");
- return TCORE_SAT_SUCCESS;
- }
- temp_index += data_len_consumed;
- } else {
- dbg("[SAT] SAT PARSER - No Alpha ID TLV.");
- }
-
- /* icon identifier - optional */
- if ((cmd_data[temp_index] & 0x7F) == SATK_ICON_IDENTIFIER_TAG) {
- data_len_consumed = 0;
- rv = _sat_decode_icon_identifier_tlv(o_cmd_data, o_length, temp_index,
- &sat_cmd_ind_data->data.launch_browser.user_confirm_icon_id,
- &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
-
- if (temp_index + data_len_consumed >= o_length) {
- dbg("[SAT] SAT PARSER - no more TLVs to decode.");
- return TCORE_SAT_SUCCESS;
- }
-
- temp_index += data_len_consumed; /* temp_index pointing to the Tag of next TLV */
- }
-
- /*
- * TODO:
- * Text Attribute, Frame Identifier
- */
-
- dbg("[SAT] SAT PARSER - :decoding done!.");
- return TCORE_SAT_SUCCESS;
-}
-
-/*
- * 6.4.27 OPEN CHANNEL
- */
-static enum tcore_sat_result _sat_decode_open_channel(unsigned char *o_cmd_data, int o_length,
- int curr_offset, struct tcore_sat_proactive_command *sat_cmd_ind_data)
-{
- int temp_index = 0;
- gboolean b_1st_duration = FALSE;
- int bearer_desc_len = 0, data_len_consumed = 0;
- unsigned char dev_id[4];
- unsigned char *cmd_data = NULL;
- enum tcore_sat_result rv = TCORE_SAT_SUCCESS;
-
- if (o_cmd_data == NULL) {
- dbg("[SAT] SAT PARSER - o_cmd_data == NULL");
- return TCORE_SAT_ERROR_FATAL;
- }
-
- cmd_data = &o_cmd_data[0];
- temp_index = curr_offset + 2;
- sat_cmd_ind_data->data.open_channel.command_detail.cmd_num = cmd_data[temp_index++];
- sat_cmd_ind_data->data.open_channel.command_detail.cmd_type = cmd_data[temp_index++];
-
- /* command detail */
- sat_cmd_ind_data->data.open_channel.command_detail.cmd_qualifier.open_channel.immediate_link = FALSE;
- sat_cmd_ind_data->data.open_channel.command_detail.cmd_qualifier.open_channel.automatic_reconnection = FALSE;
- sat_cmd_ind_data->data.open_channel.command_detail.cmd_qualifier.open_channel.background_mode = FALSE;
-
- if (cmd_data[temp_index] & 0x01) {
- sat_cmd_ind_data->data.open_channel.command_detail.cmd_qualifier.open_channel.immediate_link = TRUE;
- dbg("[SAT] SAT PARSER - Immediate Link Establishment");
- }
-
- if (cmd_data[temp_index] & 0x02) {
- sat_cmd_ind_data->data.open_channel.command_detail.cmd_qualifier.open_channel.automatic_reconnection = TRUE;
- dbg("[SAT] SAT PARSER - Auto Reconnection");
- }
-
- if (cmd_data[temp_index] & 0x04) {
- sat_cmd_ind_data->data.open_channel.command_detail.cmd_qualifier.open_channel.background_mode = TRUE;
- dbg("[SAT] SAT PARSER - Background mode");
- }
-
- /* device identities */
- temp_index++;
- memcpy(dev_id, &cmd_data[temp_index], 4);
- rv = _sat_decode_device_identities_tlv(dev_id,
- &sat_cmd_ind_data->data.open_channel.device_id);
- if (rv != TCORE_SAT_SUCCESS)
- return rv;
-
- /* alpha identifier - optional */
- temp_index += 4;
- if ((cmd_data[temp_index] & 0x7F) == SATK_ALPHA_IDENTIFIER_TAG) {
- rv = _sat_decode_alpha_identifier_tlv(o_cmd_data, o_length, temp_index,
- &sat_cmd_ind_data->data.open_channel.alpha_id,
- &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv;
-
- temp_index += data_len_consumed;
- }
-
- /* icon id - optional */
- if ((cmd_data[temp_index] & 0x7F) == SATK_ICON_IDENTIFIER_TAG) {
- data_len_consumed = 0;
- rv = _sat_decode_icon_identifier_tlv(o_cmd_data, o_length, temp_index,
- &sat_cmd_ind_data->data.open_channel.icon_id,
- &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv; /* Send TR */
-
- temp_index += data_len_consumed; /* temp_index pointing to the Tag of next TLV */
- }
-
- /* bearer description */
- rv = _sat_decode_bearer_description_tlv(o_cmd_data, o_length, temp_index,
- &sat_cmd_ind_data->data.open_channel.bearer_desc,
- &data_len_consumed);
- bearer_desc_len = data_len_consumed;
- if (rv != TCORE_SAT_SUCCESS)
- return rv;
-
- /*
- * TODO -
- * UICC SERVER MODE
- */
-
- switch (sat_cmd_ind_data->data.open_channel.bearer_desc.bearer_type) {
- case BEARER_CSD:
- /* address */
- rv = _sat_decode_address_tlv(o_cmd_data, o_length, temp_index,
- &sat_cmd_ind_data->data.open_channel.bearer_detail.cs_bearer.address,
- &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv;
-
- temp_index += data_len_consumed;
-
- /* sub address - optional */
- if ((cmd_data[temp_index] & 0x7F) == SATK_SUB_ADDRESS_TAG) {
- data_len_consumed = 0;
- rv = _sat_decode_subaddress_tlv(o_cmd_data, o_length, temp_index,
- &sat_cmd_ind_data->data.open_channel.bearer_detail.cs_bearer.subaddress,
- &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv;
-
- temp_index += data_len_consumed;
- }
-
- /* time duration 1- optional */
- if ((cmd_data[temp_index] & 0x7F) == SATK_DURATION_TAG) {
- data_len_consumed = 0;
- rv = _sat_decode_duration_tlv(o_cmd_data, o_length, temp_index,
- &sat_cmd_ind_data->data.open_channel.bearer_detail.cs_bearer.duration1,
- &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv; /* Send TR */
-
- temp_index += data_len_consumed;
- b_1st_duration = TRUE;
- }
-
- /* time duration 2- optional */
- if ((cmd_data[temp_index] & 0x7F) == SATK_DURATION_TAG) {
-
- if (!b_1st_duration) {
- dbg("duration 1 does not present!");
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- data_len_consumed = 0;
- rv = _sat_decode_duration_tlv(o_cmd_data, o_length, temp_index,
- &sat_cmd_ind_data->data.open_channel.bearer_detail.cs_bearer.duration2,
- &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv; /* Send TR */
-
- temp_index += data_len_consumed;
- }
-
- /* bearer description - already did it */
- temp_index += bearer_desc_len;
-
- /* buffer size */
- rv = _sat_decode_buffer_size_tlv(o_cmd_data, o_length, temp_index,
- &sat_cmd_ind_data->data.open_channel.buffer_size,
- &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv; /* Send TR */
-
- temp_index += data_len_consumed;
- if (temp_index >= o_length) {
- dbg("[SAT] SAT PARSER - no more TLVs to decode.");
- return TCORE_SAT_SUCCESS;
- }
-
- /* other address - optional */
- if ((cmd_data[temp_index] & 0x7F) == SATK_OTHER_ADDRESS_TAG) {
- data_len_consumed = 0;
- rv = _sat_decode_other_address_tlv(o_cmd_data, o_length, temp_index,
- &sat_cmd_ind_data->data.open_channel.bearer_detail.cs_bearer.other_address,
- &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv; /* Send TR */
-
- temp_index += data_len_consumed;
- if (temp_index >= o_length) {
- dbg("[SAT] SAT PARSER - no more TLVs to decode.");
- return TCORE_SAT_SUCCESS;
- }
- }
-
- /* text string - user login - optional */
- if ((cmd_data[temp_index] & 0x7F) == SATK_TEXT_STRING_TAG) {
- data_len_consumed = 0;
- rv = _sat_decode_text_tlv(o_cmd_data, o_length, temp_index,
- &sat_cmd_ind_data->data.open_channel.bearer_detail.cs_bearer.text_user_login,
- &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv;
-
- temp_index += data_len_consumed;
- if (temp_index >= o_length) {
- dbg("[SAT] SAT PARSER - no more TLVs to decode.");
- return TCORE_SAT_SUCCESS;
- }
- }
-
- /* text string - user password - optional */
- if ((cmd_data[temp_index] & 0x7F) == SATK_TEXT_STRING_TAG) {
- data_len_consumed = 0;
- rv = _sat_decode_text_tlv(o_cmd_data, o_length, temp_index,
- &sat_cmd_ind_data->data.open_channel.bearer_detail.cs_bearer.text_user_pwd,
- &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv;
-
- temp_index += data_len_consumed;
- if (temp_index >= o_length) {
- dbg("[SAT] SAT PARSER - no more TLVs to decode.");
- return TCORE_SAT_SUCCESS;
- }
- }
-
- /* UICC/TERMINAL interface transport level - optional */
- if ((cmd_data[temp_index] & 0x7F) == SATK_USIM_ME_INTERFACE_TRANSPORT_LEVEL_TAG) {
- data_len_consumed = 0;
- rv = _sat_decode_uicc_terminal_interface_tlv(o_cmd_data, o_length, temp_index,
- &sat_cmd_ind_data->data.open_channel.interface_transport_level,
- &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv;
-
- temp_index += data_len_consumed;
- if (temp_index >= o_length) {
- dbg("[SAT] SAT PARSER - no more TLVs to decode.");
- return TCORE_SAT_SUCCESS;
- }
- }
-
- /* destination address - optional */
- if ((cmd_data[temp_index] & 0x7F) == SATK_OTHER_ADDRESS_TAG) {
- data_len_consumed = 0;
- rv = _sat_decode_other_address_tlv(o_cmd_data, o_length, temp_index,
- &sat_cmd_ind_data->data.open_channel.data_destination_address,
- &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv; /* Send TR */
-
- temp_index += data_len_consumed;
- if (temp_index >= o_length) {
- dbg("[SAT] SAT PARSER - no more TLVs to decode.");
- return TCORE_SAT_SUCCESS;
- }
- }
- break;
-
- case BEARER_GPRS:
- /* bearer description - already did it */
- temp_index += bearer_desc_len;
-
- /* buffer size */
- rv = _sat_decode_buffer_size_tlv(o_cmd_data, o_length, temp_index,
- &sat_cmd_ind_data->data.open_channel.buffer_size,
- &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv; /* Send TR */
-
- temp_index += data_len_consumed;
- if (temp_index >= o_length) {
- dbg("[SAT] SAT PARSER - no more TLVs to decode.");
- return TCORE_SAT_SUCCESS;
- }
-
- /* Network Access Name - optional */
- if ((cmd_data[temp_index] & 0x7F) == SATK_NETWORK_ACCESS_TAG) {
- data_len_consumed = 0;
- rv = _sat_decode_network_access_name_tlv(o_cmd_data, o_length, temp_index,
- &sat_cmd_ind_data->data.open_channel.bearer_detail.ps_bearer.network_access_name,
- &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv; /* Send TR */
-
- temp_index += data_len_consumed;
- if (temp_index >= o_length) {
- dbg("[SAT] SAT PARSER - no more TLVs to decode.");
- return TCORE_SAT_SUCCESS;
- }
- }
-
- /* other address - optional */
- if ((cmd_data[temp_index] & 0x7F) == SATK_OTHER_ADDRESS_TAG) {
- data_len_consumed = 0;
- rv = _sat_decode_other_address_tlv(o_cmd_data, o_length, temp_index,
- &sat_cmd_ind_data->data.open_channel.bearer_detail.ps_bearer.other_address,
- &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv; /* Send TR */
-
- temp_index += data_len_consumed;
- if (temp_index >= o_length) {
- dbg("[SAT] SAT PARSER - no more TLVs to decode.");
- return TCORE_SAT_SUCCESS;
- }
- }
-
- /* text string - user login - optional */
- if ((cmd_data[temp_index] & 0x7F) == SATK_TEXT_STRING_TAG) {
- data_len_consumed = 0;
- rv = _sat_decode_text_tlv(o_cmd_data, o_length, temp_index,
- &sat_cmd_ind_data->data.open_channel.bearer_detail.ps_bearer.text_user_login,
- &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv;
-
- temp_index += data_len_consumed;
- if (temp_index >= o_length) {
- dbg("[SAT] SAT PARSER - no more TLVs to decode.");
- return TCORE_SAT_SUCCESS;
- }
- }
-
- /* text string - user password - optional */
- if ((cmd_data[temp_index] & 0x7F) == SATK_TEXT_STRING_TAG) {
- data_len_consumed = 0;
- rv = _sat_decode_text_tlv(o_cmd_data, o_length, temp_index,
- &sat_cmd_ind_data->data.open_channel.bearer_detail.ps_bearer.text_user_pwd,
- &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv;
-
- temp_index += data_len_consumed;
- if (temp_index >= o_length) {
- dbg("[SAT] SAT PARSER - no more TLVs to decode.");
- return TCORE_SAT_SUCCESS;
- }
- }
-
- /* UICC/TERMINAL interface transport level - optional */
- if ((cmd_data[temp_index] & 0x7F) == SATK_USIM_ME_INTERFACE_TRANSPORT_LEVEL_TAG) {
- data_len_consumed = 0;
- rv = _sat_decode_uicc_terminal_interface_tlv(o_cmd_data, o_length, temp_index,
- &sat_cmd_ind_data->data.open_channel.interface_transport_level,
- &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv;
-
- temp_index += data_len_consumed;
- if (temp_index >= o_length) {
- dbg("[SAT] SAT PARSER - no more TLVs to decode.");
- return TCORE_SAT_SUCCESS;
- }
- }
-
- dbg("the value (0x%x) after interface transport level", cmd_data[temp_index] & 0x7F);
-
- /* destination address - optional */
- if ((cmd_data[temp_index] & 0x7F) == SATK_OTHER_ADDRESS_TAG) {
- data_len_consumed = 0;
- rv = _sat_decode_other_address_tlv(o_cmd_data, o_length, temp_index,
- &sat_cmd_ind_data->data.open_channel.data_destination_address,
- &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv; /* Send TR */
-
- temp_index += data_len_consumed;
- if (temp_index >= o_length) {
- dbg("[SAT] SAT PARSER - no more TLVs to decode.");
- return TCORE_SAT_SUCCESS;
- }
- }
- break;
-
- case BEARER_DEFAULT_BEARER_FROM_TRANSPORT_LAYER:
- /* bearer description - already did it */
- temp_index += bearer_desc_len;
-
- /* buffer size */
- rv = _sat_decode_buffer_size_tlv(o_cmd_data, o_length, temp_index,
- &sat_cmd_ind_data->data.open_channel.buffer_size,
- &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv; /* Send TR */
-
- temp_index += data_len_consumed;
- if (temp_index >= o_length) {
- dbg("[SAT] SAT PARSER - no more TLVs to decode.");
- return TCORE_SAT_SUCCESS;
- }
-
- /* other address - optional */
- if ((cmd_data[temp_index] & 0x7F) == SATK_OTHER_ADDRESS_TAG) {
- data_len_consumed = 0;
- rv = _sat_decode_other_address_tlv(o_cmd_data, o_length, temp_index,
- &sat_cmd_ind_data->data.open_channel.bearer_detail.default_bearer.other_address,
- &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv; /* Send TR */
-
- temp_index += data_len_consumed;
- if (temp_index >= o_length) {
- dbg("[SAT] SAT PARSER - no more TLVs to decode.");
- return TCORE_SAT_SUCCESS;
- }
- }
-
- /* text string - user login - optional */
- if ((cmd_data[temp_index] & 0x7F) == SATK_TEXT_STRING_TAG) {
- data_len_consumed = 0;
- rv = _sat_decode_text_tlv(o_cmd_data, o_length, temp_index,
- &sat_cmd_ind_data->data.open_channel.bearer_detail.default_bearer.text_user_login,
- &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv;
-
- temp_index += data_len_consumed;
- if (temp_index >= o_length) {
- dbg("[SAT] SAT PARSER - no more TLVs to decode.");
- return TCORE_SAT_SUCCESS;
- }
- }
-
- /* text string - user password - optional */
- if ((cmd_data[temp_index] & 0x7F) == SATK_TEXT_STRING_TAG) {
- data_len_consumed = 0;
- rv = _sat_decode_text_tlv(o_cmd_data, o_length, temp_index,
- &sat_cmd_ind_data->data.open_channel.bearer_detail.default_bearer.text_user_pwd,
- &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv;
-
- temp_index += data_len_consumed;
- if (temp_index >= o_length) {
- dbg("[SAT] SAT PARSER - no more TLVs to decode.");
- return TCORE_SAT_SUCCESS;
- }
- }
-
- /* UICC/TERMINAL interface transport level - optional */
- if ((cmd_data[temp_index] & 0x7F) == SATK_USIM_ME_INTERFACE_TRANSPORT_LEVEL_TAG) {
- data_len_consumed = 0;
- rv = _sat_decode_uicc_terminal_interface_tlv(o_cmd_data, o_length, temp_index,
- &sat_cmd_ind_data->data.open_channel.interface_transport_level,
- &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv;
-
- temp_index += data_len_consumed;
- if (temp_index >= o_length) {
- dbg("[SAT] SAT PARSER - no more TLVs to decode.");
- return TCORE_SAT_SUCCESS;
- }
- }
-
- /* destination address - optional */
- if ((cmd_data[temp_index] & 0x7F) == SATK_OTHER_ADDRESS_TAG) {
- data_len_consumed = 0;
- rv = _sat_decode_other_address_tlv(o_cmd_data, o_length, temp_index,
- &sat_cmd_ind_data->data.open_channel.data_destination_address,
- &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv; /* Send TR */
-
- temp_index += data_len_consumed;
- if (temp_index >= o_length) {
- dbg("[SAT] SAT PARSER - no more TLVs to decode.");
- return TCORE_SAT_SUCCESS;
- }
- }
- break;
-
- case BEARER_LOCAL_LINK_TECHNOLOGY_INDEPENDENT:
- /* time duration 1- optional */
- if ((cmd_data[temp_index] & 0x7F) == SATK_DURATION_TAG) {
- data_len_consumed = 0;
- rv = _sat_decode_duration_tlv(o_cmd_data, o_length, temp_index,
- &sat_cmd_ind_data->data.open_channel.bearer_detail.local_bearer.duration1,
- &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv; /* Send TR */
-
- temp_index += data_len_consumed;
- b_1st_duration = TRUE;
- }
-
- /* time duration 2- optional */
- if ((cmd_data[temp_index] & 0x7F) == SATK_DURATION_TAG) {
- if (!b_1st_duration) {
- dbg("duration 1 does not present!");
- return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
- }
-
- data_len_consumed = 0;
- rv = _sat_decode_duration_tlv(o_cmd_data, o_length, temp_index,
- &sat_cmd_ind_data->data.open_channel.bearer_detail.local_bearer.duration2,
- &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv; /* Send TR */
-
- temp_index += data_len_consumed;
- }
-
- /* bearer description - already did it */
- temp_index += bearer_desc_len;
-
- /* buffer size */
- rv = _sat_decode_buffer_size_tlv(o_cmd_data, o_length, temp_index,
- &sat_cmd_ind_data->data.open_channel.buffer_size,
- &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv; /* Send TR */
-
- temp_index += data_len_consumed;
- if (temp_index >= o_length) {
- dbg("[SAT] SAT PARSER - no more TLVs to decode.");
- return TCORE_SAT_SUCCESS;
- }
-
- /* text string - user password - optional */
- if ((cmd_data[temp_index] & 0x7F) == SATK_TEXT_STRING_TAG) {
- data_len_consumed = 0;
- rv = _sat_decode_text_tlv(o_cmd_data, o_length, temp_index,
- &sat_cmd_ind_data->data.open_channel.bearer_detail.local_bearer.text_user_pwd,
- &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv;
-
- temp_index += data_len_consumed;
- if (temp_index >= o_length) {
- dbg("[SAT] SAT PARSER - no more TLVs to decode.");
- return TCORE_SAT_SUCCESS;
- }
- }
-
- /* UICC/TERMINAL interface transport level - optional */
- if ((cmd_data[temp_index] & 0x7F) == SATK_USIM_ME_INTERFACE_TRANSPORT_LEVEL_TAG) {
- data_len_consumed = 0;
- rv = _sat_decode_uicc_terminal_interface_tlv(o_cmd_data, o_length, temp_index,
- &sat_cmd_ind_data->data.open_channel.interface_transport_level,
- &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv;
-
- temp_index += data_len_consumed;
- if (temp_index >= o_length) {
- dbg("[SAT] SAT PARSER - no more TLVs to decode.");
- return TCORE_SAT_SUCCESS;
- }
- }
-
- /* destination address - optional */
- if ((cmd_data[temp_index] & 0x7F) == SATK_OTHER_ADDRESS_TAG) {
- data_len_consumed = 0;
- rv = _sat_decode_other_address_tlv(o_cmd_data, o_length, temp_index,
- &sat_cmd_ind_data->data.open_channel.data_destination_address,
- &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv; /* Send TR */
-
- temp_index += data_len_consumed;
- if (temp_index >= o_length) {
- dbg("[SAT] SAT PARSER - no more TLVs to decode.");
- return TCORE_SAT_SUCCESS;
- }
- }
-
- /* remote entity address - optional */
- if ((cmd_data[temp_index] & 0x7F) == SATK_REMOTE_ENTITY_ADDRESS_TAG) {
- data_len_consumed = 0;
- rv = _sat_decode_remote_entity_address_tlv(o_cmd_data, o_length, temp_index,
- &sat_cmd_ind_data->data.open_channel.bearer_detail.local_bearer.remote_entity_address,
- &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv; /* Send TR */
-
- temp_index += data_len_consumed;
- if (temp_index >= o_length) {
- dbg("[SAT] SAT PARSER - no more TLVs to decode.");
- return TCORE_SAT_SUCCESS;
- }
- }
- break;
-
- default:
- break;
- } /* end of switch */
-
- dbg("[SAT] SAT PARSER - :decoding done!.");
- return TCORE_SAT_SUCCESS;
-}
-
-/*
- * 6.4.28 CLOSE CHANNEL
- */
-static enum tcore_sat_result _sat_decode_close_channel(unsigned char *o_cmd_data, int o_length,
- int curr_offset, struct tcore_sat_proactive_command *sat_cmd_ind_data)
-{
- int temp_index = 0;
- int data_len_consumed = 0;
- unsigned char dev_id[4];
- unsigned char *cmd_data = NULL;
- enum tcore_sat_result rv = TCORE_SAT_SUCCESS;
-
- if (o_cmd_data == NULL) {
- dbg("[SAT] SAT PARSER - o_cmd_data == NULL");
- return TCORE_SAT_ERROR_FATAL;
- }
-
- cmd_data = &o_cmd_data[0];
- temp_index = curr_offset + 2;
- sat_cmd_ind_data->data.close_channel.command_detail.cmd_num = cmd_data[temp_index++];
- sat_cmd_ind_data->data.close_channel.command_detail.cmd_type = cmd_data[temp_index++];
-
- /* command detail */
- temp_index++; /* RFU */
-
- /* device identities */
- memcpy(dev_id, &cmd_data[temp_index], 4);
- rv = _sat_decode_device_identities_tlv(dev_id, &sat_cmd_ind_data->data.close_channel.device_id);
- if (rv != TCORE_SAT_SUCCESS)
- return rv;
-
- /* alpha identifier - optional */
- temp_index += 4;
- if ((cmd_data[temp_index] & 0x7F) == SATK_ALPHA_IDENTIFIER_TAG) {
- rv = _sat_decode_alpha_identifier_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.close_channel.alpha_id, &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv;
-
- temp_index += data_len_consumed;
- }
-
- /* icon id - optional */
- if ((cmd_data[temp_index] & 0x7F) == SATK_ICON_IDENTIFIER_TAG) {
- data_len_consumed = 0;
- rv = _sat_decode_icon_identifier_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.close_channel.icon_id, &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv; /* Send TR */
-
- temp_index += data_len_consumed; /* temp_index pointing to the Tag of next TLV */
- }
-
- /*
- * TODO:
- * Text Attribute and frames
- */
-
- dbg("[SAT] SAT PARSER - :decoding done!.");
- return TCORE_SAT_SUCCESS;
-}
-
-/*
- * 6.4.29 RECEIVE DATA
- */
-static enum tcore_sat_result _sat_decode_receive_data(unsigned char *o_cmd_data, int o_length,
- int curr_offset, struct tcore_sat_proactive_command *sat_cmd_ind_data)
-{
- int temp_index = 0;
- int data_len_consumed = 0;
- unsigned char dev_id[4];
- unsigned char *cmd_data = NULL;
- enum tcore_sat_result rv = TCORE_SAT_SUCCESS;
-
- if (o_cmd_data == NULL) {
- dbg("[SAT] SAT PARSER - o_cmd_data == NULL");
- return TCORE_SAT_ERROR_FATAL;
- }
-
- cmd_data = &o_cmd_data[0];
- temp_index = curr_offset + 2;
- sat_cmd_ind_data->data.receive_data.command_detail.cmd_num = cmd_data[temp_index++];
- sat_cmd_ind_data->data.receive_data.command_detail.cmd_type = cmd_data[temp_index++];
-
- /* command detail */
- temp_index++; /* RFU */
-
- /* device identities */
- memcpy(dev_id, &cmd_data[temp_index], 4);
- rv = _sat_decode_device_identities_tlv(dev_id, &sat_cmd_ind_data->data.receive_data.device_id);
- if (rv != TCORE_SAT_SUCCESS)
- return rv;
-
- /* alpha identifier - optional */
- temp_index += 4;
- if ((cmd_data[temp_index] & 0x7F) == SATK_ALPHA_IDENTIFIER_TAG) {
- rv = _sat_decode_alpha_identifier_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.receive_data.alpha_id, &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv;
-
- temp_index += data_len_consumed;
- }
-
- /* icon id - optional */
- if ((cmd_data[temp_index] & 0x7F) == SATK_ICON_IDENTIFIER_TAG) {
- data_len_consumed = 0;
- rv = _sat_decode_icon_identifier_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.receive_data.icon_id, &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv; /* Send TR */
-
- temp_index += data_len_consumed; /* temp_index pointing to the Tag of next TLV */
- }
-
- /* channel data length */
- rv = _sat_decode_channel_data_length_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.receive_data.channel_data_len, &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv; /* Send TR */
-
- /*
- * TODO:
- * Text Attribute and frames
- */
-
- dbg("[SAT] SAT PARSER - :decoding done!.");
- return TCORE_SAT_SUCCESS;
-}
-
-/*
- * 6.4.30 SEND DATA
- */
-static enum tcore_sat_result _sat_decode_send_data(unsigned char *o_cmd_data, int o_length,
- int curr_offset, struct tcore_sat_proactive_command *sat_cmd_ind_data)
-{
- int temp_index = 0;
- int data_len_consumed = 0;
- unsigned char dev_id[4];
- unsigned char *cmd_data = NULL;
- enum tcore_sat_result rv = TCORE_SAT_SUCCESS;
-
- if (o_cmd_data == NULL) {
- dbg("[SAT] SAT PARSER - o_cmd_data == NULL");
- return TCORE_SAT_ERROR_FATAL;
- }
-
- cmd_data = &o_cmd_data[0];
- temp_index = curr_offset + 2;
- sat_cmd_ind_data->data.send_data.command_detail.cmd_num = cmd_data[temp_index++];
- sat_cmd_ind_data->data.send_data.command_detail.cmd_type = cmd_data[temp_index++];
-
- /* command detail */
- sat_cmd_ind_data->data.send_data.command_detail.cmd_qualifier.send_data.send_data_immediately = FALSE;
- if (cmd_data[temp_index] & 0x01) {
- sat_cmd_ind_data->data.send_data.command_detail.cmd_qualifier.send_data.send_data_immediately = TRUE;
- dbg("[SAT] SAT PARSER - Send data immediately");
- }
-
- /* device identities */
- temp_index++;
- memcpy(dev_id, &cmd_data[temp_index], 4);
- rv = _sat_decode_device_identities_tlv(dev_id, &sat_cmd_ind_data->data.send_data.device_id);
- if (rv != TCORE_SAT_SUCCESS)
- return rv;
-
- /* alpha identifier - optional */
- temp_index += 4;
- if ((cmd_data[temp_index] & 0x7F) == SATK_ALPHA_IDENTIFIER_TAG) {
- rv = _sat_decode_alpha_identifier_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.send_data.alpha_id, &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv;
-
- temp_index += data_len_consumed;
- }
-
- /* icon id - optional */
- if ((cmd_data[temp_index] & 0x7F) == SATK_ICON_IDENTIFIER_TAG) {
- data_len_consumed = 0;
- rv = _sat_decode_icon_identifier_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.send_data.icon_id, &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv; /* Send TR */
-
- temp_index += data_len_consumed; /* temp_index pointing to the Tag of next TLV */
- }
-
- /* channel data */
- rv = _sat_decode_channel_data_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.send_data.channel_data, &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv; /* Send TR */
-
- /*
- * TODO:
- * Text Attribute and frames
- */
-
- dbg("[SAT] SAT PARSER - :decoding done!.");
- return TCORE_SAT_SUCCESS;
-}
-
-/*
- * 6.4.31 GET CHANNEL STATUS
- */
-static enum tcore_sat_result _sat_decode_get_channel_status(unsigned char *o_cmd_data, int o_length,
- int curr_offset, struct tcore_sat_proactive_command *sat_cmd_ind_data)
-{
- int temp_index = 0;
- unsigned char dev_id[4];
- unsigned char *cmd_data = NULL;
- enum tcore_sat_result rv = TCORE_SAT_SUCCESS;
-
- if (o_cmd_data == NULL) {
- dbg("[SAT] SAT PARSER - o_cmd_data == NULL");
- return TCORE_SAT_ERROR_FATAL;
- }
-
- cmd_data = &o_cmd_data[0];
- temp_index = curr_offset + 2;
- sat_cmd_ind_data->data.get_channel_status.command_detail.cmd_num = cmd_data[temp_index++];
- sat_cmd_ind_data->data.get_channel_status.command_detail.cmd_type = cmd_data[temp_index++];
-
- /* command detail */
- temp_index++; /* RFU */
-
- /* device identities */
- memcpy(dev_id, &cmd_data[temp_index], 4);
- rv = _sat_decode_device_identities_tlv(dev_id, &sat_cmd_ind_data->data.get_channel_status.device_id);
- if (rv != TCORE_SAT_SUCCESS)
- return rv;
-
- dbg("[SAT] SAT PARSER - :decoding done!.");
- return TCORE_SAT_SUCCESS;
-}
-
-/*
- * 6.4.XX Unsupported Command
- */
-static enum tcore_sat_result _sat_decode_unsupported_command(unsigned char *o_cmd_data, int o_length,
- int curr_offset, struct tcore_sat_proactive_command *sat_cmd_ind_data)
-{
- int temp_index = 0;
- unsigned char dev_id[4];
- unsigned char *cmd_data = NULL;
- enum tcore_sat_result rv = TCORE_SAT_SUCCESS;
-
- if (o_cmd_data == NULL) {
- dbg("[SAT] SAT PARSER - o_cmd_data == NULL");
- return TCORE_SAT_ERROR_FATAL;
- }
-
- cmd_data = &o_cmd_data[0];
- temp_index = curr_offset + 2;
- sat_cmd_ind_data->data.unsupport_cmd.command_detail.cmd_num = cmd_data[temp_index++];
- sat_cmd_ind_data->data.unsupport_cmd.command_detail.cmd_type = cmd_data[temp_index++];
-
- /* command detail */
- temp_index++; /* RFU */
-
- /* device identities */
- memcpy(dev_id, &cmd_data[temp_index], 4);
- rv = _sat_decode_device_identities_tlv(dev_id, &sat_cmd_ind_data->data.unsupport_cmd.device_id);
- if (rv != TCORE_SAT_SUCCESS)
- return rv;
-
- dbg("[SAT] SAT PARSER - :decoding done!.");
- return TCORE_SAT_SUCCESS;
-}
-
-int tcore_sat_decode_proactive_command(unsigned char *tlv_origin, unsigned int tlv_length,
- struct tcore_sat_proactive_command *decoded_tlv)
-{
- unsigned int temp_index = 0;
- int length_field_len = 0;
- enum tcore_sat_result rv = TCORE_SAT_SUCCESS;
-
- if (tlv_origin == NULL || tlv_length <= 2) {
- dbg("[SAT] SAT PARSER - pointer pData passed is NULL or invalid length.");
- return TCORE_SAT_ERROR_FATAL;
- }
-
- /* tag */
- if (tlv_origin[temp_index++] != SATK_PROACTIVE_CMD_TAG) {
- dbg("[SAT] SAT PARSER - Did not find Proactive command tag.tag=%d", tlv_origin[temp_index-1]);
- return TCORE_SAT_ERROR_FATAL;
- }
-
- /* length */
- length_field_len = _get_length_filed_size(tlv_origin[temp_index]);
- if (length_field_len == 0) {
- dbg("[SAT] SAT PARSER - Invalid length.");
- return TCORE_SAT_ERROR_FATAL;
- }
-
- /* length */
- dbg("[SAT] SAT PARSER - tlv_length=%d", tlv_length);
- temp_index += length_field_len;
-
- /* check command validation */
- if (tlv_length < temp_index + 5 + 4)/* command detail(5) and device identities(4) */
- return TCORE_SAT_ERROR_FATAL;
-
- /* check comprehensive value */
- if ((tlv_origin[temp_index] | 0x7F) != 0x7F) {
- dbg("comprehensive value 0x%x", tlv_origin[temp_index] | 0x7F);
- b_comprehensive = TRUE;
- }
-
- if ((tlv_origin[temp_index] & 0x7F) != SATK_COMMAND_DETAILS_TAG) {
- err("[SAT] no command detail info");
- return TCORE_SAT_ERROR_FATAL;
- }
-
- if (tlv_origin[temp_index + 1] != SATK_COMMAND_DETAILS_LENGTH) {
- err("[SAT] invalid command detail length");
- return TCORE_SAT_ERROR_FATAL;
- }
-
- decoded_tlv->cmd_num = tlv_origin[temp_index + 2];
- decoded_tlv->cmd_type = tlv_origin[temp_index + 3];
-
- switch (decoded_tlv->cmd_type) {
- case SAT_PROATV_CMD_DISPLAY_TEXT: /* 6.4.1 */
- dbg("[SAT] SAT PARSER - SAT_CMD_TYPE_DISPLAY_TEXT");
- rv = _sat_decode_display_text(tlv_origin, tlv_length, temp_index, decoded_tlv);
- break;
-
- case SAT_PROATV_CMD_GET_INKEY: /* 6.4.2 */
- dbg("[SAT] SAT PARSER - SAT_CMD_TYPE_GET_INKEY");
- rv = _sat_decode_get_inkey(tlv_origin, tlv_length, temp_index, decoded_tlv);
- break;
-
- case SAT_PROATV_CMD_GET_INPUT: /* 6.4.3 */
- dbg("[SAT] SAT PARSER - SAT_CMD_TYPE_GET_INPUT");
- rv = _sat_decode_get_input(tlv_origin, tlv_length, temp_index, decoded_tlv);
- break;
-
- case SAT_PROATV_CMD_MORE_TIME: /* 6.4.4 */
- dbg("[SAT] SAT PARSER - SAT_CMD_TYPE_MORE_TIME");
- rv = _sat_decode_more_time(tlv_origin, tlv_length, temp_index, decoded_tlv);
- break;
-
- case SAT_PROATV_CMD_PLAY_TONE: /* 6.4.5 */
- dbg("[SAT] SAT PARSER - SAT_CMD_TYPE_PLAY TONE");
- rv = _sat_decode_play_tone(tlv_origin, tlv_length, temp_index, decoded_tlv);
- break;
-
- /* case POLL INTERVAL //6.4.6 processing by cp */
- case SAT_PROATV_CMD_REFRESH: /* 6.4.7 */
- dbg("[SAT] SAT PARSER - SAT_CMD_TYPE_REFRESH");
- rv = _sat_decode_refresh(tlv_origin, tlv_length, temp_index, decoded_tlv);
- break;
-
- case SAT_PROATV_CMD_SETUP_MENU: /* 6.4.8 */
- dbg("[SAT] SAT PARSER - SAT_PROATV_CMD_SETUP_MENU");
- rv = _sat_decode_setup_menu(tlv_origin, tlv_length, temp_index, decoded_tlv);
- break;
-
- case SAT_PROATV_CMD_SELECT_ITEM: /* 6.4.9 */
- dbg("[SAT] SAT PARSER - SAT_CMD_TYPE_SELECT_ITEM");
- rv = _sat_decode_select_item(tlv_origin, tlv_length, temp_index, decoded_tlv);
- break;
-
- case SAT_PROATV_CMD_SEND_SMS: /* 6.4.10 */
- dbg("[SAT] SAT PARSER - SAT_CMD_TYPE_SEND_SMS");
- rv = _sat_decode_send_sms(tlv_origin, tlv_length, temp_index, decoded_tlv);
- break;
-
- case SAT_PROATV_CMD_SEND_SS: /* 6.4.11 */
- dbg("[SAT] SAT PARSER - SAT_CMD_TYPE_SEND_SS");
- rv = _sat_decode_send_ss(tlv_origin, tlv_length, temp_index, decoded_tlv);
- break;
-
- case SAT_PROATV_CMD_SEND_USSD: /* 6.4.12 */
- dbg("[SAT] SAT PARSER - SAT_CMD_TYPE_SEND_USSD");
- rv = _sat_decode_send_ussd(tlv_origin, tlv_length, temp_index, decoded_tlv);
- break;
-
- case SAT_PROATV_CMD_SETUP_CALL: /* 6.4.13 */
- dbg("[SAT] SAT PARSER - SAT_CMD_TYPE_SETUP_CALL");
- rv = _sat_decode_setup_call(tlv_origin, tlv_length, temp_index, decoded_tlv);
- break;
-
- case SAT_PROATV_CMD_PROVIDE_LOCAL_INFO: /* 6.4.15 */
- dbg("[SAT] SAT PARSER - SAT_PROATV_CMD_PROVIDE_LOCAL_INFO");
- rv = _sat_decode_provide_local_info(tlv_origin, tlv_length, temp_index, decoded_tlv);
- break;
-
- case SAT_PROATV_CMD_SETUP_EVENT_LIST: /* 6.4.16 */
- dbg("[SAT] SAT PARSER - SAT_CMD_TYPE_SETUP_EVENT_LIST");
- rv = _sat_decode_setup_event_list(tlv_origin, tlv_length, temp_index, decoded_tlv);
- break;
-
- case SAT_PROATV_CMD_SETUP_IDLE_MODE_TEXT: /* 6.4.22 */
- dbg("[SAT] SAT PARSER - SAT_PROATV_CMD_SETUP_IDLE_MODE_TEXT");
- rv = _sat_decode_setup_idle_mode_text(tlv_origin, tlv_length, temp_index, decoded_tlv);
- break;
-
- case SAT_PROATV_CMD_SEND_DTMF: /* 6.4.24 */
- dbg("[SAT] SAT PARSER - SAT_PROATV_CMD_SEND_DTMF");
- rv = _sat_decode_send_dtmf(tlv_origin, tlv_length, temp_index, decoded_tlv);
- break;
-
- case SAT_PROATV_CMD_LANGUAGE_NOTIFICATION: /* 6.4.25 */
- dbg("[SAT] SAT PARSER - SAT_PROATV_CMD_LANGUAGE_NOTIFICATION");
- rv = _sat_decode_language_notification(tlv_origin, tlv_length, temp_index, decoded_tlv);
- break;
-
- case SAT_PROATV_CMD_LAUNCH_BROWSER: /* 6.4.26 */
- dbg("[SAT] SAT PARSER - SAT_PROATV_CMD_LAUNCH_BROWSER");
- rv = _sat_decode_launch_browser(tlv_origin, tlv_length, temp_index, decoded_tlv);
- break;
-
- case SAT_PROATV_CMD_OPEN_CHANNEL:/* 6.4.27 */
- dbg("[SAT] SAT PARSER - SAT_CMD_TYPE_OPEN_CHANNEL");
- rv = _sat_decode_open_channel(tlv_origin, tlv_length, temp_index, decoded_tlv);
- break;
-
- case SAT_PROATV_CMD_CLOSE_CHANNEL:/* 6.4.28 */
- dbg("[SAT] SAT PARSER - SAT_CMD_TYPE_CLOSE_CHANNEL");
- rv = _sat_decode_close_channel(tlv_origin, tlv_length, temp_index, decoded_tlv);
- break;
-
- case SAT_PROATV_CMD_RECEIVE_DATA:/* 6.4.29 */
- dbg("[SAT] SAT PARSER - SAT_CMD_TYPE_RECEIVE_DATA");
- rv = _sat_decode_receive_data(tlv_origin, tlv_length, temp_index, decoded_tlv);
- break;
-
- case SAT_PROATV_CMD_SEND_DATA:/* 6.4.30 */
- dbg("[SAT] SAT PARSER - SAT_CMD_TYPE_SEND_DATA");
- rv = _sat_decode_send_data(tlv_origin, tlv_length, temp_index, decoded_tlv);
- break;
-
- case SAT_PROATV_CMD_GET_CHANNEL_STATUS:/* 6.4.31 */
- dbg("[SAT] SAT PARSER - SAT_CMD_TYPE_GET_CHANNEL_STATUS");
- rv = _sat_decode_get_channel_status(tlv_origin, tlv_length, temp_index, decoded_tlv);
- break;
-
- default:
- dbg("[SAT] SAT PARSER - ME cannot perform this command =0x[%02x]", decoded_tlv->cmd_type);
- rv = _sat_decode_unsupported_command(tlv_origin, tlv_length, temp_index, decoded_tlv);
- break;
- }
-
- dbg("[SAT] SAT PARSER - each command parsing done.");
- return rv;
-}
-
-int tcore_sat_decode_call_control_result(unsigned char *tlv_origin, unsigned int tlv_length, struct tnoti_sat_call_control_result_ind *call_ctrl_result_tlv)
-{
- unsigned int temp_index = 0;
- int length = 0, data_len = 0, data_len_consumed = 0;
- enum tcore_sat_result rv = TCORE_SAT_SUCCESS;
-
- if (tlv_origin == NULL || tlv_length <= 2) {
- dbg("[SAT] SAT PARSER - pointer pData passed is NULL or invalid length.");
- return TCORE_SAT_ERROR_FATAL;
- }
-
- /* call conrol result */
- call_ctrl_result_tlv->cc_result = tlv_origin[temp_index++];
- length = _get_length_filed_size(tlv_origin[temp_index]);
- if (length == 0) {
- dbg("[SAT] fail to get the call control result length");
- return TCORE_SAT_ERROR_FATAL;
- }
-
- temp_index = temp_index + length-1;
- data_len = tlv_origin[temp_index];
- dbg("[SAT] call control result (%d), data len(%d)", call_ctrl_result_tlv->cc_result, data_len);
- if (data_len == 0) {
- dbg("no more call control result - decoding done");
- return rv;
- }
- temp_index++;
-
- /* address - optional (voice call) */
- if ((tlv_origin[temp_index] & 0x7F) == SATK_ADDRESS_TAG) {
- rv = _sat_decode_address_tlv(tlv_origin, tlv_length, temp_index, &call_ctrl_result_tlv->address, &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv;
-
- temp_index += data_len_consumed;
-
- if (temp_index >= tlv_length) {
- dbg("[SAT] call control decoding done");
- return TCORE_SAT_SUCCESS;
- }
- }
-
- /* ss string - optional (ss) */
- if ((tlv_origin[temp_index] & 0x7F) == SATK_SS_STRING_TAG) {
- rv = _sat_decode_ss_string_tlv(tlv_origin, tlv_length, temp_index, &call_ctrl_result_tlv->ss_string, &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv;
-
- temp_index += data_len_consumed;
-
- if (temp_index >= tlv_length) {
- dbg("[SAT] call control decoding done");
- return TCORE_SAT_SUCCESS;
- }
- }
-
- /* ccp1 - optional */
- if ((tlv_origin[temp_index] & 0x7F) == SATK_CAPABILITY_CONFIGURATION_PARAMETERS_TAG) {
- rv = _sat_decode_ccp_tlv(tlv_origin, tlv_length, temp_index, &call_ctrl_result_tlv->ccp1, &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv; /* Send TR */
-
- temp_index += data_len_consumed;
-
- if (temp_index >= tlv_length) {
- dbg("[SAT] call control decoding done");
- return TCORE_SAT_SUCCESS;
- }
- }
-
- /* sub address */
- if ((tlv_origin[temp_index] & 0x7F) == SATK_SUB_ADDRESS_TAG) {
- rv = _sat_decode_sub_address_tlv(tlv_origin, tlv_length, temp_index, &call_ctrl_result_tlv->sub_address, &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv;
-
- temp_index += data_len_consumed;
-
- if (temp_index >= tlv_length) {
- dbg("[SAT] call control decoding done");
- return TCORE_SAT_SUCCESS;
- }
- }
-
- /* alpha id */
- if ((tlv_origin[temp_index] & 0x7F) == SATK_ALPHA_IDENTIFIER_TAG) {
- rv = _sat_decode_alpha_identifier_tlv(tlv_origin, tlv_length, temp_index, &call_ctrl_result_tlv->alpha_id, &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv;
-
- temp_index += data_len_consumed;
-
- if (temp_index >= tlv_length) {
- dbg("[SAT] call control decoding done");
- return TCORE_SAT_SUCCESS;
- }
- }
-
- /* bc repeated indicator */
- if ((tlv_origin[temp_index] & 0x7F) == SATK_BC_REPEAT_INDICATOR_TAG) {
- int tag = 0;
- int bc_repeat_ind_len = 0;
-
- tag = tlv_origin[temp_index++];
- bc_repeat_ind_len = tlv_origin[temp_index++];
- call_ctrl_result_tlv->bc_repeat_type.bc_indi_repeat_type = tlv_origin[temp_index++];
-
- dbg("bc repeated indication tag(%x) len(%x) type(%x)", tag, bc_repeat_ind_len, call_ctrl_result_tlv->bc_repeat_type.bc_indi_repeat_type);
- if (temp_index >= tlv_length) {
- dbg("[SAT] call control decoding done");
- return TCORE_SAT_SUCCESS;
- }
- }
-
- /* ccp2 */
- if ((tlv_origin[temp_index] & 0x7F) == SATK_CAPABILITY_CONFIGURATION_PARAMETERS_TAG) {
- rv = _sat_decode_ccp_tlv(tlv_origin, tlv_length, temp_index, &call_ctrl_result_tlv->ccp2, &data_len_consumed);
- if (rv != TCORE_SAT_SUCCESS)
- return rv; /* Send TR */
-
- temp_index += data_len_consumed;
-
- if (temp_index >= tlv_length) {
- dbg("[SAT] call control decoding done");
- return TCORE_SAT_SUCCESS;
- }
- }
-
- return rv;
-}
-
-static unsigned char _sat_encode_dcs_tlv(const struct data_coding_scheme *src)
-{
- unsigned char rv = 0x00;
-
- if (src == NULL)
- return 0;
-
- if (src->is_compressed_format)
- rv |= 0x20;
-
- /* msg class */
- switch (src->m_class) {
- case MSG_CLASS_0:
- case MSG_CLASS_1:
- case MSG_CLASS_2:
- case MSG_CLASS_3:
- rv |= 0x10;
- rv |= src->m_class;
- break;
-
- case MSG_CLASS_RESERVED:
- case MSG_CLASS_NONE:
- default:
- rv &= 0xEF;
- break;
- }
-
- /* alphabet format */
- switch (src->a_format) {
- case ALPHABET_FORMAT_SMS_DEFAULT:
- rv &= 0xF3;
- break;
-
- case ALPHABET_FORMAT_8BIT_DATA:
- rv |= 0x04;
- break;
-
- case ALPHABET_FORMAT_UCS2:
- rv |= 0x08;
- break;
-
- default:
- rv |= 0x0C;
- break;
- }
-
- return rv;
-}
-
-static int _sat_encode_command_detail_tlv(const struct tel_sat_cmd_detail_info *src, char *dst, int current_temp_index)
-{
- dst[current_temp_index++] = (b_comprehensive ? (SATK_COMMAND_DETAILS_TAG | 0x80) : SATK_COMMAND_DETAILS_TAG);
- dst[current_temp_index++] = SATK_COMMAND_DETAILS_LENGTH;
- dst[current_temp_index++] = src->cmd_num;
- dst[current_temp_index++] = src->cmd_type;
- dst[current_temp_index] = 0x00;
-
- switch (src->cmd_type) {
- case SAT_PROATV_CMD_DISPLAY_TEXT:
- /* command detail text priority */
- if (src->cmd_qualifier.display_text.text_priority == TEXT_PRIORITY_HIGH)
- dst[current_temp_index] += 0x01;
-
- /* command detail text clear type */
- if (src->cmd_qualifier.display_text.text_clear_type == TEXT_WAIT_FOR_USER_TO_CLEAR_MSG)
- dst[current_temp_index] += 0x80;
- break;
-
- case SAT_PROATV_CMD_GET_INKEY:
- /* command detail alphabet set */
- if (src->cmd_qualifier.get_inkey.alphabet_set)
- dst[current_temp_index] += 0x01;
-
- /* command detail alphabet type */
- if (src->cmd_qualifier.get_inkey.alphabet_type == INPUT_ALPHABET_TYPE_UCS2)
- dst[current_temp_index] += 0x02;
-
- /* command detail get inkey type */
- if (src->cmd_qualifier.get_inkey.inkey_type == INKEY_TYPE_YES_NO_REQUESTED)
- dst[current_temp_index] += 0x04;
-
-
- /* command detail immediate response required */
- if (src->cmd_qualifier.get_inkey.immediate_rsp_required)
- dst[current_temp_index] += 0x08;
-
- /* command detail help available */
- if (src->cmd_qualifier.get_inkey.help_info)
- dst[current_temp_index] += 0x80;
- break;
-
- case SAT_PROATV_CMD_GET_INPUT:
- /* command detail alphabet set */
- if (src->cmd_qualifier.get_input.alphabet_set)
- dst[current_temp_index] += 0x01;
-
- /* command detail alphabet type */
- if (src->cmd_qualifier.get_input.alphabet_type == INPUT_ALPHABET_TYPE_UCS2)
- dst[current_temp_index] += 0x02;
-
- /* command detail echo user input */
- if (!src->cmd_qualifier.get_input.me_echo_user_input)
- dst[current_temp_index] += 0x04;
-
- /* command detail user input unpacked format */
- if (!src->cmd_qualifier.get_input.user_input_unpacked_format)
- dst[current_temp_index] += 0x08;
-
- /* command detail help available */
- if (src->cmd_qualifier.get_input.help_info)
- dst[current_temp_index] += 0x80;
- break;
-
- case SAT_PROATV_CMD_MORE_TIME:
- dbg("more time : 1bit RFU");
- break;
-
- case SAT_PROATV_CMD_PLAY_TONE:
- /* command detail vibration alert */
- if (src->cmd_qualifier.play_tone.vibration_alert == VIBRATE_ALERT_REQUIRED)
- dst[current_temp_index] += 0x01;
- break;
-
- case SAT_PROATV_CMD_REFRESH:
- /* command detail refresh command */
- dst[current_temp_index] += src->cmd_qualifier.refresh.refresh;
- break;
-
- case SAT_PROATV_CMD_SETUP_MENU:
- /* command detail preferences */
- if (src->cmd_qualifier.setup_menu.select_preference == SELECTION_PREFERENCE_USING_SOFT_KEY)
- dst[current_temp_index] += 0x01;
-
- /* command detail help available */
- if (src->cmd_qualifier.setup_menu.help_info)
- dst[current_temp_index] += 0x80;
- break;
-
- case SAT_PROATV_CMD_SELECT_ITEM:
- /* command detail presentation */
- if (src->cmd_qualifier.select_item.presentation_type != PRESENTATION_TYPE_NOT_SPECIFIED) {
- dst[current_temp_index] += 0x01;
- if (src->cmd_qualifier.select_item.presentation_type == PRESENTATION_TYPE_NAVIGATION_OPTION)
- dst[current_temp_index] += PRESENTATION_TYPE_NAVIGATION_OPTION;
- }
-
- /* command detail selection preference */
- if (src->cmd_qualifier.select_item.select_preference == SELECTION_PREFERENCE_USING_SOFT_KEY)
- dst[current_temp_index] += 0x04;
-
- /* command detail help available */
- if (src->cmd_qualifier.select_item.help_info)
- dst[current_temp_index] += 0x80;
- break;
-
- case SAT_PROATV_CMD_SEND_SMS:
- /* command detail sms packing by me required */
- if (src->cmd_qualifier.send_sms.packing_by_me_required)
- dst[current_temp_index] += 0x01;
- break;
-
- case SAT_PROATV_CMD_SETUP_CALL:
- /* command detail setup call command */
- dst[current_temp_index] += src->cmd_qualifier.setup_call.setup_call;
- break;
-
- case SAT_PROATV_CMD_SETUP_EVENT_LIST:
- dbg("setup evnet list : 1bit RFU");
- break;
-
- case SAT_PROATV_CMD_OPEN_CHANNEL:
- if (src->cmd_qualifier.open_channel.immediate_link)
- dst[current_temp_index] += 0x01;
-
- if (src->cmd_qualifier.open_channel.automatic_reconnection)
- dst[current_temp_index] += 0x02;
-
- if (src->cmd_qualifier.open_channel.background_mode)
- dst[current_temp_index] += 0x04;
- break;
-
- case SAT_PROATV_CMD_SEND_DATA:
- if (src->cmd_qualifier.send_data.send_data_immediately)
- dst[current_temp_index] += 0x01;
- break;
-
- case SAT_PROATV_CMD_PROVIDE_LOCAL_INFO:
- dst[current_temp_index] += src->cmd_qualifier.provide_local_info.provide_local_info;
- break;
-
- case SAT_PROATV_CMD_LANGUAGE_NOTIFICATION:
- if (src->cmd_qualifier.language_notification.specific_language)
- dst[current_temp_index] += 0x01;
- break;
-
- case SAT_PROATV_CMD_LAUNCH_BROWSER:
- dst[current_temp_index] += src->cmd_qualifier.launch_browser.launch_browser;
- break;
-
- default:
- err("no matched cmd type(%d)", src->cmd_type);
- break;
- }
-
- return 5;
-}
-
-static int _sat_encode_device_identities_tlv(const struct tel_sat_device_identities *src, char *dst, int current_temp_index)
-{
- dst[current_temp_index++] = SATK_DEVICE_IDENTITY_TAG;
- dst[current_temp_index++] = SATK_DEVICE_IDENTITY_LENGTH;
- dst[current_temp_index++] = src->src;
- dst[current_temp_index++] = src->dest;
-
- /* device identities total len 4 */
- return 4;
-}
-
-static int _sat_encode_item_identifier_tlv(const struct tel_sat_item_identifier *src, char *dst, int current_temp_index)
-{
- dst[current_temp_index++] = SATK_ITEM_IDENTIFIER_TAG;
- dst[current_temp_index++] = SATK_ITEM_IDENTIFIER_LENGTH;
- dst[current_temp_index++] = src->item_identifier;
-
- /* item identifier total len 3 */
- return 3;
-}
-
-#if 0
-static int _sat_encode_duration_tlv(const struct tel_sat_duration *src, char *dst, int current_temp_index)
-{
- dst[current_temp_index++] = SATK_DURATION_TAG;
- dst[current_temp_index++] = SATK_DURATION_LENGTH;
- dst[current_temp_index++] = src->time_unit;
- dst[current_temp_index++] = src->time_interval;
-
- /*duration total len 4 */
- return 4;
-}
-#endif
-
-static int _sat_encode_text_tlv(const struct tel_sat_text_string_object *src, char *dst, int current_temp_index, gboolean raw_dcs)
-{
- int total_len = 0;
- int length_temp_index = 0;
-
- /* tag */
- dst[current_temp_index++] = SATK_TEXT_STRING_TAG;
-
- /* length */
- if (src->string_length <= 0x7F) {
- dst[current_temp_index++] = SATK_DCS_LENGTH + src->string_length;
- length_temp_index = 1;
- } else {
- dst[current_temp_index++] = 0x81;
- dst[current_temp_index++] = SATK_DCS_LENGTH + src->string_length;
- length_temp_index = 2;
- }
-
- /* dcs */
- if (raw_dcs)
- dst[current_temp_index++] = src->dcs.raw_dcs;
- else
- dst[current_temp_index++] = _sat_encode_dcs_tlv(&(src->dcs));
-
- /* value */
- if (src->string_length > 0)
- memcpy(&(dst[current_temp_index]), src->string, src->string_length);
-
- /* tag + temp_index + dcs + data */
- total_len = 1 + length_temp_index + 1 + src->string_length;
-
- return total_len;
-}
-
-static int _sat_encode_eventlist_tlv(const enum event_list src, char *dst, int current_temp_index)
-{
- dst[current_temp_index++] = SATK_EVENT_LIST_TAG;
- dst[current_temp_index++] = 0x01;
- dst[current_temp_index++] = src;
-
- return 3;
-}
-
-static int _sat_encode_date_time_and_timezone_tlv(const struct tel_sat_date_time_and_timezone *src, char *dst, int current_temp_index)
-{
- dst[current_temp_index++] = SATK_DATE_TIME_AND_TIME_ZONE_TAG;
- dst[current_temp_index++] = SATK_DATE_TIME_AND_TIME_ZONE_LENGTH;
- dst[current_temp_index++] = src->year;
- dst[current_temp_index++] = src->month;
- dst[current_temp_index++] = src->day;
- dst[current_temp_index++] = src->hour;
- dst[current_temp_index++] = src->minute;
- dst[current_temp_index++] = src->second;
- dst[current_temp_index++] = src->timeZone;
-
- return 1 + 1 + SATK_DATE_TIME_AND_TIME_ZONE_LENGTH; /* tag length + len field length + value length; */
-}
-
-static int _sat_encode_language_tlv(const enum tel_sim_language_type src, char *dst, int current_temp_index)
-{
- dst[current_temp_index++] = SATK_LANGUAGE_TAG;
- dst[current_temp_index++] = SATK_LANGUAGE_LENGTH;
-
- dbg("language (%d)", src);
-
- switch (src) {
- case SIM_LANG_GERMAN:
- dst[current_temp_index++] = 'd';
- dst[current_temp_index++] = 'e';
- break;
-
- case SIM_LANG_ENGLISH:
- dst[current_temp_index++] = 'e';
- dst[current_temp_index++] = 'n';
- break;
-
- case SIM_LANG_ITALIAN:
- dst[current_temp_index++] = 'i';
- dst[current_temp_index++] = 't';
- break;
-
- case SIM_LANG_FRENCH:
- dst[current_temp_index++] = 'f';
- dst[current_temp_index++] = 'r';
- break;
-
- case SIM_LANG_SPANISH:
- dst[current_temp_index++] = 'e';
- dst[current_temp_index++] = 's';
- break;
-
- case SIM_LANG_DUTCH:
- dst[current_temp_index++] = 'n';
- dst[current_temp_index++] = 'l';
- break;
-
- case SIM_LANG_SWEDISH:
- dst[current_temp_index++] = 's';
- dst[current_temp_index++] = 'v';
- break;
-
- case SIM_LANG_DANISH:
- dst[current_temp_index++] = 'd';
- dst[current_temp_index++] = 'a';
- break;
-
- case SIM_LANG_PORTUGUESE:
- dst[current_temp_index++] = 'p';
- dst[current_temp_index++] = 't';
- break;
-
- case SIM_LANG_FINNISH:
- dst[current_temp_index++] = 'f';
- dst[current_temp_index++] = 'i';
- break;
-
- case SIM_LANG_NORWEGIAN:
- dst[current_temp_index++] = 'n';
- dst[current_temp_index++] = 'b';
- break;
-
- case SIM_LANG_GREEK:
- dst[current_temp_index++] = 'e';
- dst[current_temp_index++] = 'l';
- break;
-
- case SIM_LANG_TURKISH:
- dst[current_temp_index++] = 't';
- dst[current_temp_index++] = 'k';
- break;
-
- case SIM_LANG_HUNGARIAN:
- dst[current_temp_index++] = 'h';
- dst[current_temp_index++] = 'u';
- break;
-
- case SIM_LANG_POLISH:
- dst[current_temp_index++] = 'p';
- dst[current_temp_index++] = 'l';
- break;
-
- case SIM_LANG_KOREAN:
- dst[current_temp_index++] = 'k';
- dst[current_temp_index++] = 'o';
- break;
-
- case SIM_LANG_CHINESE:
- dst[current_temp_index++] = 'z';
- dst[current_temp_index++] = 'h';
- break;
-
- case SIM_LANG_RUSSIAN:
- dst[current_temp_index++] = 'r';
- dst[current_temp_index++] = 'u';
- break;
-
- case SIM_LANG_JAPANESE:
- dst[current_temp_index++] = 'j';
- dst[current_temp_index++] = 'a';
- break;
-
- default:
- dst[current_temp_index++] = 'e';
- dst[current_temp_index++] = 'n';
- dbg("[SAT] SAT PARSER - Unknown Language: 0x%x", src);
- break;
- }
-
- return 4;
-}
-
-static int _sat_encode_browser_termination_tlv(const enum browser_termination_cause src, char *dst, int current_temp_index)
-{
- dst[current_temp_index++] = SATK_BROWSER_TERMINATION_CAUSE_TAG;
- dst[current_temp_index++] = SATK_BROWSER_TERMINATION_CAUSE_LENGTH;
- dst[current_temp_index++] = src;
-
- return 3;
-}
-
-#if 0
-static int _sat_encode_bearer_desc_tlv(const struct tel_sat_bearer_description *src, char *dst, int current_temp_index)
-{
- int total_len = 0;
- int length_temp_index = 0;
-
- dst[current_temp_index++] = SATK_BEARER_DISCRIPTION_TAG;
-
- /* length temp_index */
- length_temp_index = current_temp_index++;
-
- /* bearer type */
- dst[current_temp_index++] = src->bearer_type;
-
- switch (src->bearer_type) {
- case BEARER_CSD: {
- dst[current_temp_index++] = src->bearer_parameter.cs_bearer_param.data_rate;
- dst[current_temp_index++] = src->bearer_parameter.cs_bearer_param.service_type;
- dst[current_temp_index++] = src->bearer_parameter.cs_bearer_param.connection_element_type;
- }
- break;
-
- case BEARER_GPRS: {
- dst[current_temp_index++] = src->bearer_parameter.ps_bearer_param.precedence_class;
- dst[current_temp_index++] = src->bearer_parameter.ps_bearer_param.delay_class;
- dst[current_temp_index++] = src->bearer_parameter.ps_bearer_param.reliability_class;
- dst[current_temp_index++] = src->bearer_parameter.ps_bearer_param.peak_throughput_class;
- dst[current_temp_index++] = src->bearer_parameter.ps_bearer_param.mean_throughput_class;
- dst[current_temp_index++] = src->bearer_parameter.ps_bearer_param.pdp_type;
- }
- break;
-
- case BEARER_DEFAULT_BEARER_FROM_TRANSPORT_LAYER:
- case BEARER_LOCAL_LINK_TECHNOLOGY_INDEPENDENT:
- default:
- break;
- }
-
- dst[length_temp_index] = (current_temp_index-1) - length_temp_index;
- total_len = (current_temp_index-1) - length_temp_index + 2; /* tag and length */
-
- return total_len;
-}
-
-static int _sat_encode_buffer_size_tlv(const struct tel_sat_buffer_size *src, char *dst, int current_temp_index)
-{
- dst[current_temp_index++] = SATK_BUFFER_SIZE_TAG;
- dst[current_temp_index++] = SATK_BUFFER_SIZE_LENGTH;
- dst[current_temp_index++] = src->size[0];
- dst[current_temp_index++] = src->size[1];
-
- return 4;
-}
-#endif
-
-static int _sat_encode_channel_data_tlv(const struct tel_sat_channel_data *src, char *dst, int current_temp_index)
-{
- int total_len = 0;
- int length_temp_index = 0;
-
- dst[current_temp_index++] = SATK_CHANNEL_DATA_TAG;
-
- if (src->data_string_len <= 0x7F) {
- dst[current_temp_index++] = src->data_string_len;
- length_temp_index = 1;
- } else {
- dst[current_temp_index++] = 0x81;
- dst[current_temp_index++] = src->data_string_len;
- length_temp_index = 2;
- }
-
- memcpy(&(dst[current_temp_index]), src->data_string, src->data_string_len);
-
- total_len = 1 + length_temp_index + src->data_string_len;
-
- return total_len;
-}
-
-static int _sat_encode_channel_data_length_tlv(const struct tel_sat_channel_data_len *src, char *dst, int current_temp_index)
-{
- dst[current_temp_index++] = SATK_CHANNEL_DATA_LEN_TAG;
- dst[current_temp_index++] = SATK_CHANNEL_DATA_LENGTH_VALUE_LENGTH;
- dst[current_temp_index++] = src->data_len;
-
- return 3;
-}
-
-static int _sat_encode_channel_status_tlv(const struct tel_sat_channel_status *src, char *dst, int current_temp_index)
-{
- dst[current_temp_index++] = SATK_CHANNEL_STATUS_TAG;
- dst[current_temp_index++] = SATK_CHANNEL_STATUS_LENGTH;
-
- if (src->status == link_or_packet_service_activated) /* (bit 8) */
- dst[current_temp_index] += 0x80;
-
- dst[current_temp_index++] += src->channel_id; /* (bit 1~3) */
- dst[current_temp_index++] = src->status_info;
-
- return 4;
-}
-
-static int _sat_encode_download_event(const struct tel_sat_envelop_event_download_tlv *evt_dl, char *dst_envelop)
-{
- int temp_index = 2;
- int encoded_len = 0;
-
- dbg("event type(%d)", evt_dl->event);
-
- /* event list */
- encoded_len = _sat_encode_eventlist_tlv(evt_dl->event, dst_envelop, temp_index);
- temp_index += encoded_len;
-
- /* device id - len 4 */
- encoded_len = _sat_encode_device_identities_tlv(&(evt_dl->device_identitie), dst_envelop, temp_index);
- temp_index += encoded_len;
-
- switch (evt_dl->event) {
- case EVENT_LANGUAGE_SELECTION:
- encoded_len = _sat_encode_language_tlv(evt_dl->language, dst_envelop, temp_index);
- temp_index += encoded_len;
- break;
-
- case EVENT_BROWSER_TERMINATION:
- encoded_len = _sat_encode_browser_termination_tlv(evt_dl->browser_termination, dst_envelop, temp_index);
- temp_index += encoded_len;
- break;
-
- case EVENT_DATA_AVAILABLE:
- encoded_len = _sat_encode_channel_status_tlv(&(evt_dl->channel_status), dst_envelop, temp_index);
- temp_index += encoded_len;
-
- encoded_len = _sat_encode_channel_data_length_tlv(&(evt_dl->channel_data_len), dst_envelop, temp_index);
- temp_index += encoded_len;
- break;
-
- case EVENT_CHANNEL_STATUS:
- encoded_len = _sat_encode_channel_status_tlv(&(evt_dl->channel_status), dst_envelop, temp_index);
- temp_index += encoded_len;
- break;
-
- default:
- break;
- }
-
- dst_envelop[0] = SATK_EVENT_DOWNLOAD_TAG;
- dst_envelop[1] = temp_index-2;
-
- dbg("download envelop cmd len(%d)", temp_index);
-
- if (temp_index-2 > 0x7F) {
- int idx = 0;
- for (idx = temp_index; idx > 0; idx--)
- dst_envelop[idx] = dst_envelop[idx + 1];
- dst_envelop[1] = 0x81;
- temp_index += 1;
- dbg("download envelop added cmd len(%d)", temp_index);
- }
-
- return temp_index;
-}
-
-int tcore_sat_encode_envelop_cmd(const struct treq_sat_envelop_cmd_data *src_envelop, char *dst_envelop)
-{
- int temp_index = 0, encoded_len = 0;
-
- if (!dst_envelop)
- return 0;
-
- if (src_envelop->sub_cmd
- == ENVELOP_MENU_SELECTION) {
- temp_index = 2; /* set the cursor to device identity */
- dbg("item id(%d)", src_envelop->envelop_data.menu_select.item_identifier.item_identifier);
- encoded_len = _sat_encode_device_identities_tlv(&(src_envelop->envelop_data.menu_select.device_identitie), dst_envelop, temp_index);
- temp_index += encoded_len;
-
- /* item identifier */
- encoded_len = _sat_encode_item_identifier_tlv(&(src_envelop->envelop_data.menu_select.item_identifier), dst_envelop, temp_index);
- temp_index += encoded_len;
-
- if (src_envelop->envelop_data.menu_select.help_request) {
- encoded_len = 2;/* help request */
- dst_envelop[temp_index++] = SATK_HELP_REQUEST_TAG;
- dst_envelop[temp_index++] = SATK_HELP_REQUEST_LENGTH;
- }
-
- dbg("menu selection cmd len(%d)", temp_index);
-
- /* main cmd */
- dst_envelop[0] = SATK_MENU_SELECTION_TAG;
- dst_envelop[1] = temp_index-2;
- } else if (src_envelop->sub_cmd
- == ENVELOP_EVENT_DOWNLOAD)
- temp_index = _sat_encode_download_event(&(src_envelop->envelop_data.event_download), dst_envelop);
-
- return temp_index;
-}
-
-
-
-static int _sat_encode_display_text(const struct tel_sat_tr_display_text_tlv *src_tr, char *dst_tr)
-{
- int temp_index = 0, encoded_len = 0;
-
- /* set command detail info */
- encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, temp_index);
- temp_index += encoded_len;
-
- /* set device identities info */
- encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, temp_index);
- temp_index += encoded_len;
-
- /* set result info */
- dst_tr[temp_index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG);
- switch (src_tr->result_type) {
- case RESULT_SUCCESS:
- case RESULT_SUCCESS_WITH_PARTIAL_COMPREHENSION:
- case RESULT_SUCCESS_WITH_MISSING_INFO:
- case RESULT_SUCCESS_BUT_REQUESTED_ICON_NOT_DISPLAYED:
- case RESULT_PROACTIVE_SESSION_TERMINATED_BY_USER:
- case RESULT_BACKWARD_MOVE_BY_USER:
- case RESULT_NO_RESPONSE_FROM_USER:
- case RESULT_BEYOND_ME_CAPABILITIES:
- case RESULT_COMMAND_TYPE_NOT_UNDERSTOOD_BY_ME:
- case RESULT_COMMAND_DATA_NOT_UNDERSTOOD_BY_ME:
- case RESULT_COMMAND_NUMBER_NOT_KNOWN_BY_ME:
- case RESULT_ERROR_REQUIRED_VALUES_ARE_MISSING:
- dst_tr[temp_index++] = 1;
- dst_tr[temp_index++] = src_tr->result_type;
- break;
-
- case RESULT_ME_UNABLE_TO_PROCESS_COMMAND:
- case RESULT_FRAMES_ERROR:
- dst_tr[temp_index++] = 2;
- dst_tr[temp_index++] = src_tr->result_type;
- dst_tr[temp_index++] = src_tr->me_problem_type;
- break;
-
- default:
- dbg("invalid response value[0x%x] in current TR", src_tr->result_type);
- temp_index = 0;
- break;
- }
-
- return temp_index;
-}
-
-static int _sat_encode_get_inkey(const struct tel_sat_tr_get_inkey_tlv *src_tr, char *dst_tr)
-{
- int temp_index = 0, encoded_len = 0;
-
- /* set command detail info */
- encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, temp_index);
- temp_index += encoded_len;
-
- /* set device identities info */
- encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, temp_index);
- temp_index += encoded_len;
-
- /* set result info */
- dst_tr[temp_index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG);
-
- switch (src_tr->result_type) {
- case RESULT_SUCCESS:
- case RESULT_SUCCESS_WITH_PARTIAL_COMPREHENSION:
- case RESULT_SUCCESS_WITH_MISSING_INFO:
- case RESULT_SUCCESS_BUT_REQUESTED_ICON_NOT_DISPLAYED:
- dst_tr[temp_index++] = 1;
- dst_tr[temp_index++] = src_tr->result_type;
-
- encoded_len = _sat_encode_text_tlv(&(src_tr->text), dst_tr, temp_index, FALSE);
- temp_index += encoded_len;
- break;
-
- case RESULT_PROACTIVE_SESSION_TERMINATED_BY_USER:
- case RESULT_BACKWARD_MOVE_BY_USER:
- case RESULT_HELP_INFO_REQUIRED_BY_USER:
- case RESULT_BEYOND_ME_CAPABILITIES:
- case RESULT_COMMAND_TYPE_NOT_UNDERSTOOD_BY_ME:
- case RESULT_COMMAND_DATA_NOT_UNDERSTOOD_BY_ME:
- case RESULT_COMMAND_NUMBER_NOT_KNOWN_BY_ME:
- case RESULT_ERROR_REQUIRED_VALUES_ARE_MISSING:
- case RESULT_NO_RESPONSE_FROM_USER:
- dst_tr[temp_index++] = 1;
- dst_tr[temp_index++] = src_tr->result_type;
- break;
-
- case RESULT_ME_UNABLE_TO_PROCESS_COMMAND:
- case RESULT_FRAMES_ERROR:
- dst_tr[temp_index++] = 2;
- dst_tr[temp_index++] = src_tr->result_type;
- dst_tr[temp_index++] = src_tr->me_problem_type;
- break;
-
- default:
- dbg("invalid response value[0x%x] in current TR", src_tr->result_type);
- temp_index = 0;
- break;
- }
-
- return temp_index;
-}
-
-static int _sat_encode_get_input(const struct tel_sat_tr_get_input_tlv *src_tr, char *dst_tr)
-{
- int temp_index = 0, encoded_len = 0;
-
- /* set command detail info */
- encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, temp_index);
- temp_index += encoded_len;
-
- /* set device identities info */
- encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, temp_index);
- temp_index += encoded_len;
-
- /* set result info */
- dst_tr[temp_index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG);
-
- switch (src_tr->result_type) {
- case RESULT_SUCCESS:
- case RESULT_SUCCESS_WITH_PARTIAL_COMPREHENSION:
- case RESULT_SUCCESS_WITH_MISSING_INFO:
- case RESULT_SUCCESS_BUT_REQUESTED_ICON_NOT_DISPLAYED:
- dst_tr[temp_index++] = 1;
- dst_tr[temp_index++] = src_tr->result_type;
-
- encoded_len = _sat_encode_text_tlv(&(src_tr->text), dst_tr, temp_index, FALSE);
- temp_index += encoded_len;
- break;
-
- case RESULT_PROACTIVE_SESSION_TERMINATED_BY_USER:
- case RESULT_BACKWARD_MOVE_BY_USER:
- case RESULT_NO_RESPONSE_FROM_USER:
- case RESULT_HELP_INFO_REQUIRED_BY_USER:
- case RESULT_BEYOND_ME_CAPABILITIES:
- case RESULT_COMMAND_TYPE_NOT_UNDERSTOOD_BY_ME:
- case RESULT_COMMAND_DATA_NOT_UNDERSTOOD_BY_ME:
- case RESULT_COMMAND_NUMBER_NOT_KNOWN_BY_ME:
- case RESULT_ERROR_REQUIRED_VALUES_ARE_MISSING:
- dst_tr[temp_index++] = 1;
- dst_tr[temp_index++] = src_tr->result_type;
- break;
-
- case RESULT_ME_UNABLE_TO_PROCESS_COMMAND:
- case RESULT_FRAMES_ERROR:
- dst_tr[temp_index++] = 2;
- dst_tr[temp_index++] = src_tr->result_type;
- dst_tr[temp_index++] = src_tr->me_problem_type;
- break;
-
- default:
- dbg("invalid response value[0x%x] in current TR", src_tr->result_type);
- temp_index = 0;
- break;
- }
-
- return temp_index;
-}
-
-static int _sat_encode_more_time(const struct tel_sat_tr_more_time_tlv *src_tr, char *dst_tr)
-{
- int temp_index = 0, encoded_len = 0;
-
- /* set command detail info */
- encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, temp_index);
- temp_index += encoded_len;
-
- /* set device identities info */
- encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, temp_index);
- temp_index += encoded_len;
-
- /* set result info */
- dst_tr[temp_index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG);
-
- switch (src_tr->result_type) {
- case RESULT_SUCCESS:
- case RESULT_SUCCESS_WITH_PARTIAL_COMPREHENSION:
- case RESULT_SUCCESS_WITH_MISSING_INFO:
- case RESULT_BEYOND_ME_CAPABILITIES:
- case RESULT_COMMAND_TYPE_NOT_UNDERSTOOD_BY_ME:
- case RESULT_COMMAND_DATA_NOT_UNDERSTOOD_BY_ME:
- case RESULT_COMMAND_NUMBER_NOT_KNOWN_BY_ME:
- case RESULT_ERROR_REQUIRED_VALUES_ARE_MISSING:
- dst_tr[temp_index++] = 1;
- dst_tr[temp_index++] = src_tr->result_type;
- break;
-
- case RESULT_ME_UNABLE_TO_PROCESS_COMMAND:
- dst_tr[temp_index++] = 2;
- dst_tr[temp_index++] = src_tr->result_type;
- dst_tr[temp_index++] = src_tr->me_problem_type;
- break;
-
- default:
- dbg("invalid response value[0x%x] in current TR", src_tr->result_type);
- temp_index = 0;
- break;
- }
-
- return temp_index;
-}
-
-static int _sat_encode_play_tone(const struct tel_sat_tr_play_tone_tlv *src_tr, char *dst_tr)
-{
- int temp_index = 0, encoded_len = 0;
-
- /* set command detail info */
- encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, temp_index);
- temp_index += encoded_len;
-
- /* set device identities info */
- encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, temp_index);
- temp_index += encoded_len;
-
- /* set result info */
- dst_tr[temp_index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG);
-
- switch (src_tr->result_type) {
- case RESULT_SUCCESS:
- case RESULT_SUCCESS_WITH_PARTIAL_COMPREHENSION:
- case RESULT_SUCCESS_WITH_MISSING_INFO:
- case RESULT_SUCCESS_BUT_REQUESTED_ICON_NOT_DISPLAYED:
- case RESULT_SUCCESS_BUT_TONE_NOT_PLAYED:
- case RESULT_PROACTIVE_SESSION_TERMINATED_BY_USER:
- case RESULT_BEYOND_ME_CAPABILITIES:
- case RESULT_COMMAND_TYPE_NOT_UNDERSTOOD_BY_ME:
- case RESULT_COMMAND_DATA_NOT_UNDERSTOOD_BY_ME:
- case RESULT_COMMAND_NUMBER_NOT_KNOWN_BY_ME:
- case RESULT_ERROR_REQUIRED_VALUES_ARE_MISSING:
- dst_tr[temp_index++] = 1;
- dst_tr[temp_index++] = src_tr->result_type;
- break;
-
- case RESULT_ME_UNABLE_TO_PROCESS_COMMAND:
- case RESULT_FRAMES_ERROR:
- dst_tr[temp_index++] = 2;
- dst_tr[temp_index++] = src_tr->result_type;
- dst_tr[temp_index++] = src_tr->me_problem_type;
- break;
-
- default:
- dbg("invalid response value[0x%x] in current TR", src_tr->result_type);
- temp_index = 0;
- break;
- }
-
- return temp_index;
-}
-
-static int _sat_encode_refresh(const struct tel_sat_tr_refresh_tlv *src_tr, char *dst_tr)
-{
- int temp_index = 0, encoded_len = 0;
-
- /* set command detail info */
- encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, temp_index);
- temp_index += encoded_len;
-
- /* set device identities info */
- encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, temp_index);
- temp_index += encoded_len;
-
- /* set result info */
- dst_tr[temp_index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG);
-
- switch (src_tr->result_type) {
- case RESULT_SUCCESS:
- case RESULT_SUCCESS_WITH_PARTIAL_COMPREHENSION:
- case RESULT_SUCCESS_WITH_MISSING_INFO:
- case RESULT_REFRESH_PERFORMED_WITH_ADDITIONAL_EFS_READ:
- case RESULT_REFRESH_PRFRMD_BUT_INDICATED_USIM_NOT_ACTIVE:
- case RESULT_BEYOND_ME_CAPABILITIES:
- case RESULT_COMMAND_TYPE_NOT_UNDERSTOOD_BY_ME:
- case RESULT_COMMAND_DATA_NOT_UNDERSTOOD_BY_ME:
- case RESULT_COMMAND_NUMBER_NOT_KNOWN_BY_ME:
- case RESULT_ERROR_REQUIRED_VALUES_ARE_MISSING:
- dst_tr[temp_index++] = 1;
- dst_tr[temp_index++] = src_tr->result_type;
- break;
-
- case RESULT_ME_UNABLE_TO_PROCESS_COMMAND:
- dst_tr[temp_index++] = 2;
- dst_tr[temp_index++] = src_tr->result_type;
- dst_tr[temp_index++] = src_tr->me_problem_type;
- break;
-
- default:
- dbg("invalid response value[0x%x] in current TR", src_tr->result_type);
- temp_index = 0;
- break;
- }
-
- return temp_index;
-}
-
-static int _sat_encode_setup_menu(const struct tel_sat_tr_setup_menu_tlv *src_tr, char *dst_tr)
-{
- int temp_index = 0, encoded_len = 0;
-
- /* set command detail info */
- encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, temp_index);
- temp_index += encoded_len;
-
- /* set device identities info */
- encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, temp_index);
- temp_index += encoded_len;
-
- /* set result info */
- dst_tr[temp_index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG);
- switch (src_tr->result_type) {
- case RESULT_SUCCESS:
- case RESULT_SUCCESS_WITH_PARTIAL_COMPREHENSION:
- case RESULT_SUCCESS_WITH_MISSING_INFO:
- case RESULT_SUCCESS_BUT_REQUESTED_ICON_NOT_DISPLAYED:
- case RESULT_BEYOND_ME_CAPABILITIES:
- case RESULT_COMMAND_TYPE_NOT_UNDERSTOOD_BY_ME:
- case RESULT_COMMAND_DATA_NOT_UNDERSTOOD_BY_ME:
- case RESULT_COMMAND_NUMBER_NOT_KNOWN_BY_ME:
- case RESULT_ERROR_REQUIRED_VALUES_ARE_MISSING:
- dst_tr[temp_index++] = 1;
- dst_tr[temp_index++] = src_tr->result_type;
- break;
-
- case RESULT_ME_UNABLE_TO_PROCESS_COMMAND:
- dst_tr[temp_index++] = 2;
- dst_tr[temp_index++] = src_tr->result_type;
- dst_tr[temp_index++] = src_tr->me_problem_type;
- break;
-
- default:
- dbg("invalid response value[0x%x] in current TR", src_tr->result_type);
- temp_index = 0;
- break;
- }
-
- return temp_index;
-}
-
-static int _sat_encode_select_item(const struct tel_sat_tr_select_item_tlv *src_tr, char *dst_tr)
-{
- int temp_index = 0, encoded_len = 0;
-
- /* set command detail info */
- encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, temp_index);
- temp_index += encoded_len;
-
- /* set device identities info */
- encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, temp_index);
- temp_index += encoded_len;
-
- /* set result info */
- dst_tr[temp_index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG);
-
- switch (src_tr->result_type) {
- case RESULT_SUCCESS:
- case RESULT_SUCCESS_WITH_PARTIAL_COMPREHENSION:
- case RESULT_SUCCESS_WITH_MISSING_INFO:
- case RESULT_SUCCESS_BUT_REQUESTED_ICON_NOT_DISPLAYED:
- case RESULT_HELP_INFO_REQUIRED_BY_USER:
- dst_tr[temp_index++] = 1;
- dst_tr[temp_index++] = src_tr->result_type;
- encoded_len = _sat_encode_item_identifier_tlv(&(src_tr->item_identifier), dst_tr, temp_index);
- temp_index += encoded_len;
- break;
-
- case RESULT_PROACTIVE_SESSION_TERMINATED_BY_USER:
- case RESULT_BACKWARD_MOVE_BY_USER:
- case RESULT_NO_RESPONSE_FROM_USER:
- case RESULT_BEYOND_ME_CAPABILITIES:
- case RESULT_COMMAND_TYPE_NOT_UNDERSTOOD_BY_ME:
- case RESULT_COMMAND_DATA_NOT_UNDERSTOOD_BY_ME:
- case RESULT_COMMAND_NUMBER_NOT_KNOWN_BY_ME:
- case RESULT_ERROR_REQUIRED_VALUES_ARE_MISSING:
- dst_tr[temp_index++] = 1;
- dst_tr[temp_index++] = src_tr->result_type;
- break;
-
- case RESULT_ME_UNABLE_TO_PROCESS_COMMAND:
- case RESULT_FRAMES_ERROR:
- dst_tr[temp_index++] = 2;
- dst_tr[temp_index++] = src_tr->result_type;
- dst_tr[temp_index++] = src_tr->me_problem_type;
- break;
-
- default:
- dbg("invalid response value[0x%x] in current TR", src_tr->result_type);
- temp_index = 0;
- break;
- }
-
- return temp_index;
-}
-
-static int _sat_encode_send_sms(const struct tel_sat_tr_send_sms_tlv *src_tr, char *dst_tr)
-{
- int temp_index = 0, encoded_len = 0;
-
- /* set command detail info */
- encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, temp_index);
- temp_index += encoded_len;
-
- /* set device identities info */
- encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, temp_index);
- temp_index += encoded_len;
-
- /* set result info */
- dst_tr[temp_index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG);
-
- switch (src_tr->result_type) {
- case RESULT_SUCCESS:
- case RESULT_SUCCESS_WITH_PARTIAL_COMPREHENSION:
- case RESULT_SUCCESS_WITH_MISSING_INFO:
- case RESULT_SUCCESS_BUT_REQUESTED_ICON_NOT_DISPLAYED:
- dst_tr[temp_index++] = 1;
- dst_tr[temp_index++] = src_tr->result_type;
- break;
-
- case RESULT_ME_UNABLE_TO_PROCESS_COMMAND:
- case RESULT_NETWORK_UNABLE_TO_PROCESS_COMMAND:
- case RESULT_BEYOND_ME_CAPABILITIES:
- case RESULT_COMMAND_TYPE_NOT_UNDERSTOOD_BY_ME:
- case RESULT_COMMAND_DATA_NOT_UNDERSTOOD_BY_ME:
- case RESULT_SMS_RP_ERROR:
- case RESULT_ERROR_REQUIRED_VALUES_ARE_MISSING:
- dst_tr[temp_index++] = 2;
- dst_tr[temp_index++] = src_tr->result_type;
- dst_tr[temp_index++] = src_tr->me_problem_type;
- break;
-
- case RESULT_INTRCTN_WITH_CC_OR_SMS_CTRL_PRMNT_PRBLM:
- dst_tr[temp_index++] = 2;
- dst_tr[temp_index++] = src_tr->result_type;
- dst_tr[temp_index++] = src_tr->cc_problem_type;
- break;
-
- default:
- dbg("invalid response value[0x%x] in current TR", src_tr->result_type);
- temp_index = 0;
- break;
- }
-
- return temp_index;
-}
-
-static int _sat_encode_send_ss(const struct tel_sat_tr_send_ss_tlv *src_tr, char *dst_tr)
-{
- int temp_index = 0, encoded_len = 0;
-
- /* set command detail info */
- encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, temp_index);
- temp_index += encoded_len;
-
- /* set device identities info */
- encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, temp_index);
- temp_index += encoded_len;
-
- /* set result info */
- dst_tr[temp_index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG);
-
- switch (src_tr->result_type) {
- case RESULT_SUCCESS:
- case RESULT_SUCCESS_WITH_PARTIAL_COMPREHENSION:
- case RESULT_SUCCESS_WITH_MISSING_INFO:
- case RESULT_SUCCESS_BUT_REQUESTED_ICON_NOT_DISPLAYED:
- case RESULT_SUCCESS_BUT_MODIFIED_BY_CALL_CONTROL_BY_SIM:
- case RESULT_USSD_OR_SS_TRANSACTION_TERMINATED_BY_USER:
- dst_tr[temp_index++] = 1 + src_tr->text.string_length;
- dst_tr[temp_index++] = src_tr->result_type;
-
- memcpy(&(dst_tr[temp_index]), src_tr->text.string, src_tr->text.string_length);
- encoded_len = src_tr->text.string_length;
- temp_index += encoded_len;
- break;
- case RESULT_COMMAND_DATA_NOT_UNDERSTOOD_BY_ME:
- dst_tr[temp_index++] = 1;
- dst_tr[temp_index++] = src_tr->result_type;
- break;
-
- case RESULT_ME_UNABLE_TO_PROCESS_COMMAND:
- case RESULT_NETWORK_UNABLE_TO_PROCESS_COMMAND:
- dst_tr[temp_index++] = 2;
- dst_tr[temp_index++] = src_tr->result_type;
- dst_tr[temp_index++] = src_tr->me_problem_type;
- break;
-
- case RESULT_INTRCTN_WITH_CC_OR_SMS_CTRL_PRMNT_PRBLM:
- dst_tr[temp_index++] = 2;
- dst_tr[temp_index++] = src_tr->result_type;
- dst_tr[temp_index++] = src_tr->cc_problem_type;
- break;
-
- case RESULT_SS_RETURN_ERROR:
- dst_tr[temp_index++] = 2;
- dst_tr[temp_index++] = src_tr->result_type;
- dst_tr[temp_index++] = src_tr->ss_problem;
- break;
-
- case RESULT_BEYOND_ME_CAPABILITIES:
- dst_tr[temp_index++] = 1;
- dst_tr[temp_index++] = src_tr->result_type;
- break;
-
- default:
- dbg("invalid response value[0x%x] in current TR", src_tr->result_type);
- temp_index = 0;
- break;
- }
-
- return temp_index;
-}
-
-static int _sat_encode_send_ussd(const struct tel_sat_tr_send_ussd_tlv *src_tr, char *dst_tr)
-{
- int temp_index = 0, encoded_len = 0;
-
- /* set command detail info */
- encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, temp_index);
- temp_index += encoded_len;
-
- /* set device identities info */
- encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, temp_index);
- temp_index += encoded_len;
-
- /* set result info */
- dst_tr[temp_index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG);
-
- switch (src_tr->result_type) {
- case RESULT_SUCCESS:
- case RESULT_SUCCESS_WITH_PARTIAL_COMPREHENSION:
- case RESULT_SUCCESS_WITH_MISSING_INFO:
- case RESULT_SUCCESS_BUT_REQUESTED_ICON_NOT_DISPLAYED:
- case RESULT_SUCCESS_BUT_MODIFIED_BY_CALL_CONTROL_BY_SIM:
- case RESULT_USSD_OR_SS_TRANSACTION_TERMINATED_BY_USER:
- dst_tr[temp_index++] = 1;
- dst_tr[temp_index++] = src_tr->result_type;
-
- encoded_len = _sat_encode_text_tlv(&(src_tr->text), dst_tr, temp_index, TRUE);
- temp_index += encoded_len;
- break;
-
- case RESULT_COMMAND_DATA_NOT_UNDERSTOOD_BY_ME:
- case RESULT_BEYOND_ME_CAPABILITIES:
- dst_tr[temp_index++] = 1;
- dst_tr[temp_index++] = src_tr->result_type;
- break;
-
- case RESULT_ME_UNABLE_TO_PROCESS_COMMAND:
- case RESULT_NETWORK_UNABLE_TO_PROCESS_COMMAND:
- dst_tr[temp_index++] = 2;
- dst_tr[temp_index++] = src_tr->result_type;
- dst_tr[temp_index++] = src_tr->me_problem_type;
- break;
-
- case RESULT_INTRCTN_WITH_CC_OR_SMS_CTRL_PRMNT_PRBLM:
- dst_tr[temp_index++] = 2;
- dst_tr[temp_index++] = src_tr->result_type;
- dst_tr[temp_index++] = src_tr->cc_problem_type;
- break;
-
- case RESULT_USSD_RETURN_ERROR:
- dst_tr[temp_index++] = 2;
- dst_tr[temp_index++] = src_tr->result_type;
- dst_tr[temp_index++] = src_tr->ussd_problem;
- break;
-
- default:
- dbg("invalid response value[0x%x] in current TR", src_tr->result_type);
- temp_index = 0;
- break;
- }
-
- return temp_index;
-}
-
-static int _sat_encode_setup_call(const struct tel_sat_tr_setup_call_tlv *src_tr, char *dst_tr)
-{
- int temp_index = 0, encoded_len = 0;
-
- /* set command detail info */
- encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, temp_index);
- temp_index += encoded_len;
-
- /* set device identities info */
- encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, temp_index);
- temp_index += encoded_len;
-
- /* set result info */
- dst_tr[temp_index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG);
-
- switch (src_tr->result_type) {
- case RESULT_SUCCESS:
- case RESULT_SUCCESS_WITH_PARTIAL_COMPREHENSION:
- case RESULT_SUCCESS_WITH_MISSING_INFO:
- case RESULT_SUCCESS_BUT_REQUESTED_ICON_NOT_DISPLAYED:
- case RESULT_SUCCESS_BUT_MODIFIED_BY_CALL_CONTROL_BY_SIM:
- case RESULT_PROACTIVE_SESSION_TERMINATED_BY_USER:
- case RESULT_BEYOND_ME_CAPABILITIES:
- case RESULT_COMMAND_TYPE_NOT_UNDERSTOOD_BY_ME:
- case RESULT_COMMAND_DATA_NOT_UNDERSTOOD_BY_ME:
- case RESULT_COMMAND_NUMBER_NOT_KNOWN_BY_ME:
- case RESULT_ERROR_REQUIRED_VALUES_ARE_MISSING:
- case RESULT_SS_RETURN_ERROR:
- dst_tr[temp_index++] = 1;
- dst_tr[temp_index++] = src_tr->result_type;
- break;
-
- case RESULT_ME_UNABLE_TO_PROCESS_COMMAND:
- case RESULT_USER_DID_NOT_ACCEPT_CALL_SETUP_REQ:
- case RESULT_USER_CLEAR_DOWN_CALL_BEFORE_CONN:
- case RESULT_FRAMES_ERROR:
- dst_tr[temp_index++] = 2;
- dst_tr[temp_index++] = src_tr->result_type;
- dst_tr[temp_index++] = src_tr->me_problem_type;
- break;
-
- case RESULT_NETWORK_UNABLE_TO_PROCESS_COMMAND:
- dst_tr[temp_index++] = 2;
- dst_tr[temp_index++] = src_tr->result_type;
- dst_tr[temp_index++] = src_tr->network_problem_type;
- break;
-
- case RESULT_INTRCTN_WITH_CC_OR_SMS_CTRL_PRMNT_PRBLM:
- dst_tr[temp_index++] = 2;
- dst_tr[temp_index++] = src_tr->result_type;
- dst_tr[temp_index++] = src_tr->cc_problem_type;
- break;
-
- default:
- dbg("invalid response value[0x%x] in current TR", src_tr->result_type);
- temp_index = 0;
- break;
- }
-
- return temp_index;
-}
-
-static int _sat_encode_provide_local_info(const struct tel_sat_tr_provide_local_info_tlv *src_tr, char *dst_tr)
-{
- int temp_index = 0, encoded_len = 0;
-
- /* set command detail info */
- encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, temp_index);
- temp_index += encoded_len;
-
- /* set device identities info */
- encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, temp_index);
- temp_index += encoded_len;
-
- /* set result info */
- dst_tr[temp_index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG);
- switch (src_tr->result_type) {
- case RESULT_SUCCESS:
- case RESULT_SUCCESS_WITH_PARTIAL_COMPREHENSION:
- case RESULT_SUCCESS_WITH_MISSING_INFO:
- case RESULT_SUCCESS_LIMITED_SERVICE:
- dst_tr[temp_index++] = 1;
- dst_tr[temp_index++] = src_tr->result_type;
- switch (src_tr->command_detail.cmd_qualifier.provide_local_info.provide_local_info) {
- case LOCAL_INFO_DATE_TIME_AND_TIMEZONE:
- encoded_len = _sat_encode_date_time_and_timezone_tlv(&(src_tr->other.date_time_and_timezone), dst_tr, temp_index);
- break;
-
- case LOCAL_INFO_LANGUAGE:
- encoded_len = _sat_encode_language_tlv(src_tr->other.language, dst_tr, temp_index);
- break;
-
- default:
- dbg("local info type[%d] is not handled", src_tr->command_detail.cmd_qualifier.provide_local_info.provide_local_info);
- break;
- }
-
- temp_index += encoded_len;
- break;
-
- case RESULT_BEYOND_ME_CAPABILITIES:
- case RESULT_COMMAND_TYPE_NOT_UNDERSTOOD_BY_ME:
- case RESULT_COMMAND_DATA_NOT_UNDERSTOOD_BY_ME:
- case RESULT_COMMAND_NUMBER_NOT_KNOWN_BY_ME:
- case RESULT_ERROR_REQUIRED_VALUES_ARE_MISSING:
- dst_tr[temp_index++] = 1;
- dst_tr[temp_index++] = src_tr->result_type;
- break;
-
- case RESULT_ME_UNABLE_TO_PROCESS_COMMAND:
- dst_tr[temp_index++] = 2;
- dst_tr[temp_index++] = src_tr->result_type;
- dst_tr[temp_index++] = src_tr->me_problem_type;
- break;
-
- default:
- dbg("invalid response value[0x%x] in current TR", src_tr->result_type);
- temp_index = 0;
- break;
- }
-
- return temp_index;
-}
-
-static int _sat_encode_setup_event_list(const struct tel_sat_tr_setup_event_list_tlv *src_tr, char *dst_tr)
-{
- int temp_index = 0, encoded_len = 0;
-
- /* set command detail info */
- encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, temp_index);
- temp_index += encoded_len;
-
- /* set device identities info */
- encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, temp_index);
- temp_index += encoded_len;
-
- /* set result info */
- dst_tr[temp_index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG);
- switch (src_tr->result_type) {
- case RESULT_SUCCESS:
- case RESULT_SUCCESS_WITH_PARTIAL_COMPREHENSION:
- case RESULT_SUCCESS_WITH_MISSING_INFO:
- case RESULT_BEYOND_ME_CAPABILITIES:
- case RESULT_COMMAND_TYPE_NOT_UNDERSTOOD_BY_ME:
- case RESULT_COMMAND_DATA_NOT_UNDERSTOOD_BY_ME:
- case RESULT_COMMAND_NUMBER_NOT_KNOWN_BY_ME:
- case RESULT_ERROR_REQUIRED_VALUES_ARE_MISSING:
- dst_tr[temp_index++] = 1;
- dst_tr[temp_index++] = src_tr->result_type;
- break;
-
- case RESULT_ME_UNABLE_TO_PROCESS_COMMAND:
- dst_tr[temp_index++] = 2;
- dst_tr[temp_index++] = src_tr->result_type;
- dst_tr[temp_index++] = src_tr->me_problem_type;
- break;
-
- default:
- dbg("invalid response value[0x%x] in current TR", src_tr->result_type);
- temp_index = 0;
- break;
- }
-
- return temp_index;
-}
-
-static int _sat_encode_setup_idle_mode_text(const struct tel_sat_tr_setup_idle_mode_text_tlv *src_tr, char *dst_tr)
-{
- int temp_index = 0, encoded_len = 0;
-
- /* set command detail info */
- encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, temp_index);
- temp_index += encoded_len;
-
- /* set device identities info */
- encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, temp_index);
- temp_index += encoded_len;
-
- /* set result info */
- dst_tr[temp_index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG);
-
- switch (src_tr->result_type) {
- case RESULT_SUCCESS:
- case RESULT_SUCCESS_WITH_PARTIAL_COMPREHENSION:
- case RESULT_SUCCESS_WITH_MISSING_INFO:
- case RESULT_SUCCESS_BUT_REQUESTED_ICON_NOT_DISPLAYED:
- case RESULT_BEYOND_ME_CAPABILITIES:
- case RESULT_COMMAND_TYPE_NOT_UNDERSTOOD_BY_ME:
- case RESULT_COMMAND_DATA_NOT_UNDERSTOOD_BY_ME:
- case RESULT_COMMAND_NUMBER_NOT_KNOWN_BY_ME:
- case RESULT_ERROR_REQUIRED_VALUES_ARE_MISSING:
- dst_tr[temp_index++] = 1;
- dst_tr[temp_index++] = src_tr->result_type;
- break;
-
- case RESULT_ME_UNABLE_TO_PROCESS_COMMAND:
- case RESULT_FRAMES_ERROR:
- dst_tr[temp_index++] = 2;
- dst_tr[temp_index++] = src_tr->result_type;
- dst_tr[temp_index++] = src_tr->me_problem_type;
- break;
-
- default:
- dbg("invalid response value[0x%x] in current TR", src_tr->result_type);
- temp_index = 0;
- break;
- }
-
- return temp_index;
-}
-
-static int _sat_encode_send_dtmf(const struct tel_sat_tr_send_dtmf_tlv *src_tr, char *dst_tr)
-{
- int temp_index = 0, encoded_len = 0;
-
- /* set command detail info */
- encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, temp_index);
- temp_index += encoded_len;
-
- /* set device identities info */
- encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, temp_index);
- temp_index += encoded_len;
-
- /* set result info */
- dst_tr[temp_index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG);
-
- switch (src_tr->result_type) {
- case RESULT_SUCCESS:
- case RESULT_SUCCESS_WITH_PARTIAL_COMPREHENSION:
- case RESULT_SUCCESS_WITH_MISSING_INFO:
- case RESULT_SUCCESS_BUT_REQUESTED_ICON_NOT_DISPLAYED:
- case RESULT_PROACTIVE_SESSION_TERMINATED_BY_USER:
- case RESULT_BEYOND_ME_CAPABILITIES:
- case RESULT_COMMAND_TYPE_NOT_UNDERSTOOD_BY_ME:
- case RESULT_COMMAND_DATA_NOT_UNDERSTOOD_BY_ME:
- case RESULT_COMMAND_NUMBER_NOT_KNOWN_BY_ME:
- case RESULT_ERROR_REQUIRED_VALUES_ARE_MISSING:
- dst_tr[temp_index++] = 1;
- dst_tr[temp_index++] = src_tr->result_type;
- break;
-
- case RESULT_ME_UNABLE_TO_PROCESS_COMMAND:
- dst_tr[temp_index++] = 2;
- dst_tr[temp_index++] = src_tr->result_type;
- dst_tr[temp_index++] = src_tr->me_problem_type;
- break;
-
- default:
- dbg("invalid response value[0x%x] in current TR", src_tr->result_type);
- temp_index = 0;
- break;
- }
-
- return temp_index;
-}
-
-static int _sat_encode_language_notification(const struct tel_sat_tr_language_notification_tlv *src_tr, char *dst_tr)
-{
- int temp_index = 0, encoded_len = 0;
-
- /* set command detail info */
- encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, temp_index);
- temp_index += encoded_len;
-
- /* set device identities info */
- encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, temp_index);
- temp_index += encoded_len;
-
- /* set result info */
- dst_tr[temp_index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG);
-
- switch (src_tr->result_type) {
- case RESULT_SUCCESS:
- case RESULT_SUCCESS_WITH_PARTIAL_COMPREHENSION:
- case RESULT_SUCCESS_WITH_MISSING_INFO:
- case RESULT_BEYOND_ME_CAPABILITIES:
- case RESULT_COMMAND_TYPE_NOT_UNDERSTOOD_BY_ME:
- case RESULT_COMMAND_DATA_NOT_UNDERSTOOD_BY_ME:
- case RESULT_COMMAND_NUMBER_NOT_KNOWN_BY_ME:
- case RESULT_ERROR_REQUIRED_VALUES_ARE_MISSING:
- dst_tr[temp_index++] = 1;
- dst_tr[temp_index++] = src_tr->result_type;
- break;
-
- case RESULT_ME_UNABLE_TO_PROCESS_COMMAND:
- case RESULT_FRAMES_ERROR:
- dst_tr[temp_index++] = 2;
- dst_tr[temp_index++] = src_tr->result_type;
- dst_tr[temp_index++] = src_tr->me_problem_type;
- break;
-
- default:
- dbg("invalid response value[0x%x] in current TR", src_tr->result_type);
- temp_index = 0;
- break;
- }
-
- return temp_index;
-}
-
-static int _sat_encode_launch_browser(const struct tel_sat_tr_launch_browser_tlv *src_tr, char *dst_tr)
-{
- int temp_index = 0, encoded_len = 0;
-
- /* set command detail info */
- encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, temp_index);
- temp_index += encoded_len;
-
- /* set device identities info */
- encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, temp_index);
- temp_index += encoded_len;
-
- /* set result info */
- dst_tr[temp_index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG);
-
- switch (src_tr->result_type) {
- case RESULT_SUCCESS:
- case RESULT_SUCCESS_WITH_PARTIAL_COMPREHENSION:
- case RESULT_SUCCESS_WITH_MISSING_INFO:
- case RESULT_PROACTIVE_SESSION_TERMINATED_BY_USER:
- case RESULT_BACKWARD_MOVE_BY_USER:
- case RESULT_NO_RESPONSE_FROM_USER:
- case RESULT_BEYOND_ME_CAPABILITIES:
- case RESULT_COMMAND_TYPE_NOT_UNDERSTOOD_BY_ME:
- case RESULT_COMMAND_DATA_NOT_UNDERSTOOD_BY_ME:
- case RESULT_COMMAND_NUMBER_NOT_KNOWN_BY_ME:
- case RESULT_SUCCESS_BUT_REQUESTED_ICON_NOT_DISPLAYED:
- dst_tr[temp_index++] = 1;
- dst_tr[temp_index++] = src_tr->result_type;
- break;
-
- case RESULT_ME_UNABLE_TO_PROCESS_COMMAND:
- case RESULT_NETWORK_UNABLE_TO_PROCESS_COMMAND:
- case RESULT_FRAMES_ERROR:
- dst_tr[temp_index++] = 2;
- dst_tr[temp_index++] = src_tr->result_type;
- dst_tr[temp_index++] = src_tr->me_problem_type;
- break;
-
- case RESULT_LAUNCH_BROWSER_GENERIC_ERROR_CODE:
- dst_tr[temp_index++] = 2;
- dst_tr[temp_index++] = src_tr->result_type;
- dst_tr[temp_index++] = src_tr->browser_problem_type;
- break;
-
- default:
- dbg("invalid response value[0x%x] in current TR", src_tr->result_type);
- temp_index = 0;
- break;
- }
-
- return temp_index;
-}
-
-static int _sat_encode_open_channel(const struct tel_sat_tr_open_channel_tlv *src_tr, char *dst_tr)
-{
- int temp_index = 0, encoded_len = 0;
-
- /* set command detail info */
- encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, temp_index);
- temp_index += encoded_len;
-
- /* set device identities info */
- encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, temp_index);
- temp_index += encoded_len;
-
- /* set result info */
- dst_tr[temp_index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG);
- switch (src_tr->result_type) {
- case RESULT_SUCCESS:
- case RESULT_SUCCESS_WITH_PARTIAL_COMPREHENSION:
- case RESULT_SUCCESS_WITH_MISSING_INFO:
- case RESULT_SUCCESS_BUT_REQUESTED_ICON_NOT_DISPLAYED:
- case RESULT_SUCCESS_WITH_MODIFICATION:
- dst_tr[temp_index++] = 1;
- dst_tr[temp_index++] = src_tr->result_type;
-
- /* set channel status */
- encoded_len = _sat_encode_channel_status_tlv(&(src_tr->channel_status), dst_tr, temp_index);
- temp_index += encoded_len;
- break;
-
- case RESULT_REFRESH_PRFRMD_BUT_INDICATED_USIM_NOT_ACTIVE:
- case RESULT_PROACTIVE_SESSION_TERMINATED_BY_USER:
- case RESULT_INTERACTION_WITH_CC_BY_SIM_IN_TMP_PRBLM:
- case RESULT_BEYOND_ME_CAPABILITIES:
- case RESULT_COMMAND_TYPE_NOT_UNDERSTOOD_BY_ME:
- case RESULT_COMMAND_DATA_NOT_UNDERSTOOD_BY_ME:
- case RESULT_COMMAND_NUMBER_NOT_KNOWN_BY_ME:
- case RESULT_ERROR_REQUIRED_VALUES_ARE_MISSING:
- case RESULT_USER_DID_NOT_ACCEPT_CALL_SETUP_REQ:
- dst_tr[temp_index++] = 1;
- dst_tr[temp_index++] = src_tr->result_type;
- break;
-
- case RESULT_ME_UNABLE_TO_PROCESS_COMMAND:
- case RESULT_NETWORK_UNABLE_TO_PROCESS_COMMAND:
- case RESULT_FRAMES_ERROR:
- dst_tr[temp_index++] = 2;
- dst_tr[temp_index++] = src_tr->result_type;
- dst_tr[temp_index++] = src_tr->me_problem_type;
- break;
-
- case RESULT_BEARER_INDEPENDENT_PROTOCOL_ERROR:
- dst_tr[temp_index++] = 2;
- dst_tr[temp_index++] = src_tr->result_type;
- dst_tr[temp_index++] = src_tr->bip_problem_type;
- break;
-
- default:
- dbg("invalid response value[0x%x] in current TR", src_tr->result_type);
- return 0;
- }
-
- return temp_index;
-}
-
-static int _sat_encode_close_channel(const struct tel_sat_tr_close_channel_tlv *src_tr, char *dst_tr)
-{
- int temp_index = 0, encoded_len = 0;
-
- /* set command detail info */
- encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, temp_index);
- temp_index += encoded_len;
-
- /* set device identities info */
- encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, temp_index);
- temp_index += encoded_len;
-
- /* set result info */
- dst_tr[temp_index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG);
- switch (src_tr->result_type) {
- case RESULT_SUCCESS:
- case RESULT_SUCCESS_WITH_PARTIAL_COMPREHENSION:
- case RESULT_SUCCESS_WITH_MISSING_INFO:
- case RESULT_SUCCESS_BUT_REQUESTED_ICON_NOT_DISPLAYED:
- case RESULT_PROACTIVE_SESSION_TERMINATED_BY_USER:
- case RESULT_BEYOND_ME_CAPABILITIES:
- case RESULT_COMMAND_TYPE_NOT_UNDERSTOOD_BY_ME:
- case RESULT_COMMAND_DATA_NOT_UNDERSTOOD_BY_ME:
- case RESULT_COMMAND_NUMBER_NOT_KNOWN_BY_ME:
- case RESULT_ERROR_REQUIRED_VALUES_ARE_MISSING:
- dst_tr[temp_index++] = 1;
- dst_tr[temp_index++] = src_tr->result_type;
- break;
-
- case RESULT_ME_UNABLE_TO_PROCESS_COMMAND:
- case RESULT_FRAMES_ERROR:
- dst_tr[temp_index++] = 2;
- dst_tr[temp_index++] = src_tr->result_type;
- dst_tr[temp_index++] = src_tr->me_problem_type;
- break;
-
- case RESULT_BEARER_INDEPENDENT_PROTOCOL_ERROR:
- dst_tr[temp_index++] = 2;
- dst_tr[temp_index++] = src_tr->result_type;
- dst_tr[temp_index++] = src_tr->bip_problem_type;
- break;
-
- default:
- dbg("invalid response value[0x%x] in current TR", src_tr->result_type);
- temp_index = 0;
- break;
- }
-
- return temp_index;
-}
-
-static int _sat_encode_send_data(const struct tel_sat_tr_send_data_tlv *src_tr, char *dst_tr)
-{
- int temp_index = 0, encoded_len = 0;
-
- /* set command detail info */
- encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, temp_index);
- temp_index += encoded_len;
-
- /* set device identities info */
- encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, temp_index);
- temp_index += encoded_len;
-
- /* set result info */
- dst_tr[temp_index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG);
- switch (src_tr->result_type) {
- case RESULT_SUCCESS:
- case RESULT_SUCCESS_WITH_PARTIAL_COMPREHENSION:
- case RESULT_SUCCESS_WITH_MISSING_INFO:
- case RESULT_SUCCESS_BUT_REQUESTED_ICON_NOT_DISPLAYED:
- case RESULT_PROACTIVE_SESSION_TERMINATED_BY_USER:
- case RESULT_BEYOND_ME_CAPABILITIES:
- case RESULT_COMMAND_TYPE_NOT_UNDERSTOOD_BY_ME:
- case RESULT_COMMAND_DATA_NOT_UNDERSTOOD_BY_ME:
- case RESULT_COMMAND_NUMBER_NOT_KNOWN_BY_ME:
- case RESULT_ERROR_REQUIRED_VALUES_ARE_MISSING:
- dst_tr[temp_index++] = 1;
- dst_tr[temp_index++] = src_tr->result_type;
- encoded_len = _sat_encode_channel_data_length_tlv(&(src_tr->channel_data_len), dst_tr, temp_index);
- temp_index += encoded_len;
- break;
-
- case RESULT_ME_UNABLE_TO_PROCESS_COMMAND:
- case RESULT_NETWORK_UNABLE_TO_PROCESS_COMMAND:
- case RESULT_FRAMES_ERROR:
- dst_tr[temp_index++] = 2;
- dst_tr[temp_index++] = src_tr->result_type;
- dst_tr[temp_index++] = src_tr->me_problem_type;
- break;
-
- case RESULT_BEARER_INDEPENDENT_PROTOCOL_ERROR:
- dst_tr[temp_index++] = 2;
- dst_tr[temp_index++] = src_tr->result_type;
- dst_tr[temp_index++] = src_tr->bip_problem_type;
- break;
-
- default:
- dbg("invalid response value[0x%x] in current TR", src_tr->result_type);
- temp_index = 0;
- break;
- }
-
- return temp_index;
-}
-
-static int _sat_encode_receive_data(const struct tel_sat_tr_receive_data_tlv *src_tr, char *dst_tr)
-{
- int temp_index = 0, encoded_len = 0;
-
- /* set command detail info */
- encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, temp_index);
- temp_index += encoded_len;
-
- /* set device identities info */
- encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, temp_index);
- temp_index += encoded_len;
-
- /* set result info */
- dst_tr[temp_index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG);
- switch (src_tr->result_type) {
- case RESULT_SUCCESS:
- case RESULT_SUCCESS_WITH_PARTIAL_COMPREHENSION:
- case RESULT_SUCCESS_WITH_MISSING_INFO:
- case RESULT_SUCCESS_BUT_REQUESTED_ICON_NOT_DISPLAYED:
- case RESULT_PROACTIVE_SESSION_TERMINATED_BY_USER:
- case RESULT_BEYOND_ME_CAPABILITIES:
- case RESULT_COMMAND_TYPE_NOT_UNDERSTOOD_BY_ME:
- case RESULT_COMMAND_DATA_NOT_UNDERSTOOD_BY_ME:
- case RESULT_COMMAND_NUMBER_NOT_KNOWN_BY_ME:
- case RESULT_ERROR_REQUIRED_VALUES_ARE_MISSING:
- dst_tr[temp_index++] = 1;
- dst_tr[temp_index++] = src_tr->result_type;
- encoded_len = _sat_encode_channel_data_tlv(&(src_tr->channel_data), dst_tr, temp_index);
- temp_index += encoded_len;
- encoded_len = _sat_encode_channel_data_length_tlv(&(src_tr->channel_data_len), dst_tr, temp_index);
- temp_index += encoded_len;
- break;
-
- case RESULT_ME_UNABLE_TO_PROCESS_COMMAND:
- case RESULT_FRAMES_ERROR:
- dst_tr[temp_index++] = 2;
- dst_tr[temp_index++] = src_tr->result_type;
- dst_tr[temp_index++] = src_tr->me_problem_type;
- break;
-
- case RESULT_BEARER_INDEPENDENT_PROTOCOL_ERROR:
- dst_tr[temp_index++] = 2;
- dst_tr[temp_index++] = src_tr->result_type;
- dst_tr[temp_index++] = src_tr->bip_problem_type;
- break;
-
- default:
- dbg("invalid response value[0x%x] in current TR", src_tr->result_type);
- temp_index = 0;
- break;
- }
-
- return temp_index;
-}
-
-static int _sat_encode_get_channel_status(const struct tel_sat_tr_get_channel_status_tlv *src_tr, char *dst_tr)
-{
- int temp_index = 0, encoded_len = 0;
-
- /* set command detail info */
- encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, temp_index);
- temp_index += encoded_len;
-
- /* set device identities info */
- encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, temp_index);
- temp_index += encoded_len;
-
- /* set result info */
- dst_tr[temp_index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG);
- switch (src_tr->result_type) {
- case RESULT_SUCCESS:
- case RESULT_SUCCESS_WITH_PARTIAL_COMPREHENSION:
- case RESULT_SUCCESS_WITH_MISSING_INFO:
- case RESULT_SUCCESS_BUT_REQUESTED_ICON_NOT_DISPLAYED:
- dst_tr[temp_index++] = 1;
- dst_tr[temp_index++] = src_tr->result_type;
- encoded_len = _sat_encode_channel_status_tlv(&(src_tr->channel_status), dst_tr, temp_index);
- temp_index += encoded_len;
- break;
-
- case RESULT_PROACTIVE_SESSION_TERMINATED_BY_USER:
- case RESULT_BEYOND_ME_CAPABILITIES:
- case RESULT_COMMAND_TYPE_NOT_UNDERSTOOD_BY_ME:
- case RESULT_COMMAND_DATA_NOT_UNDERSTOOD_BY_ME:
- case RESULT_COMMAND_NUMBER_NOT_KNOWN_BY_ME:
- case RESULT_ERROR_REQUIRED_VALUES_ARE_MISSING:
- dst_tr[temp_index++] = 1;
- dst_tr[temp_index++] = src_tr->result_type;
- break;
-
- case RESULT_ME_UNABLE_TO_PROCESS_COMMAND:
- case RESULT_NETWORK_UNABLE_TO_PROCESS_COMMAND:
- dst_tr[temp_index++] = 2;
- dst_tr[temp_index++] = src_tr->result_type;
- dst_tr[temp_index++] = src_tr->me_problem_type;
- break;
-
- case RESULT_BEARER_INDEPENDENT_PROTOCOL_ERROR:
- dst_tr[temp_index++] = 2;
- dst_tr[temp_index++] = src_tr->result_type;
- dst_tr[temp_index++] = src_tr->bip_problem_type;
- break;
-
- default:
- dbg("invalid response value[0x%x] in current TR", src_tr->result_type);
- temp_index = 0;
- break;
- }
-
- return temp_index;
-}
-
-static int _sat_encode_unsupport_command(const struct tel_sat_tr_unsupport_command_tlv *src_tr, char *dst_tr)
-{
- int temp_index = 0, encoded_len = 0;
-
- /* set command detail info */
- encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, temp_index);
- temp_index += encoded_len;
-
- /* set device identities info */
- encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, temp_index);
- temp_index += encoded_len;
-
- /* set result info */
- dst_tr[temp_index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG);
- dst_tr[temp_index++] = 1;
- dst_tr[temp_index++] = src_tr->result_type;
-
- return temp_index;
-}
-
-int tcore_sat_encode_terminal_response(const struct treq_sat_terminal_rsp_data *src_tr, char *dst_tr)
-{
- int tr_len = 0;
-
- if (!dst_tr)
- return 0;
-
- switch (src_tr->cmd_type) {
- case SAT_PROATV_CMD_DISPLAY_TEXT:
- tr_len = _sat_encode_display_text(&(src_tr->terminal_rsp_data.display_text), dst_tr);
- break;
-
- case SAT_PROATV_CMD_GET_INKEY:
- tr_len = _sat_encode_get_inkey(&(src_tr->terminal_rsp_data.get_inkey), dst_tr);
- break;
-
- case SAT_PROATV_CMD_GET_INPUT:
- tr_len = _sat_encode_get_input(&(src_tr->terminal_rsp_data.get_input), dst_tr);
- break;
-
- case SAT_PROATV_CMD_MORE_TIME:
- tr_len = _sat_encode_more_time(&(src_tr->terminal_rsp_data.more_time), dst_tr);
- break;
-
- case SAT_PROATV_CMD_PLAY_TONE:
- tr_len = _sat_encode_play_tone(&(src_tr->terminal_rsp_data.play_tone), dst_tr);
- break;
-
- case SAT_PROATV_CMD_REFRESH:
- tr_len = _sat_encode_refresh(&(src_tr->terminal_rsp_data.refresh), dst_tr);
- break;
-
- case SAT_PROATV_CMD_SETUP_MENU:
- tr_len = _sat_encode_setup_menu(&(src_tr->terminal_rsp_data.setup_menu), dst_tr);
- break;
-
- case SAT_PROATV_CMD_SELECT_ITEM:
- tr_len = _sat_encode_select_item(&(src_tr->terminal_rsp_data.select_item), dst_tr);
- break;
-
- case SAT_PROATV_CMD_SEND_SMS:
- tr_len = _sat_encode_send_sms(&(src_tr->terminal_rsp_data.send_sms), dst_tr);
- break;
-
- case SAT_PROATV_CMD_SEND_SS:
- tr_len = _sat_encode_send_ss(&(src_tr->terminal_rsp_data.send_ss), dst_tr);
- break;
-
- case SAT_PROATV_CMD_SEND_USSD:
- tr_len = _sat_encode_send_ussd(&(src_tr->terminal_rsp_data.send_ussd), dst_tr);
- break;
-
- case SAT_PROATV_CMD_SETUP_CALL:
- tr_len = _sat_encode_setup_call(&(src_tr->terminal_rsp_data.setup_call), dst_tr);
- break;
-
- case SAT_PROATV_CMD_PROVIDE_LOCAL_INFO:
- tr_len = _sat_encode_provide_local_info(&(src_tr->terminal_rsp_data.provide_local_info), dst_tr);
- break;
-
- case SAT_PROATV_CMD_SETUP_EVENT_LIST:
- tr_len = _sat_encode_setup_event_list(&(src_tr->terminal_rsp_data.setup_event_list), dst_tr);
- break;
-
- case SAT_PROATV_CMD_SETUP_IDLE_MODE_TEXT:
- tr_len = _sat_encode_setup_idle_mode_text(&(src_tr->terminal_rsp_data.setup_idle_mode_text), dst_tr);
- break;
-
- case SAT_PROATV_CMD_SEND_DTMF:
- tr_len = _sat_encode_send_dtmf(&(src_tr->terminal_rsp_data.send_dtmf), dst_tr);
- break;
-
- case SAT_PROATV_CMD_LANGUAGE_NOTIFICATION:
- tr_len = _sat_encode_language_notification(&(src_tr->terminal_rsp_data.language_notification), dst_tr);
- break;
-
- case SAT_PROATV_CMD_LAUNCH_BROWSER:
- tr_len = _sat_encode_launch_browser(&(src_tr->terminal_rsp_data.launch_browser), dst_tr);
- break;
-
- case SAT_PROATV_CMD_OPEN_CHANNEL:
- tr_len = _sat_encode_open_channel(&(src_tr->terminal_rsp_data.open_channel), dst_tr);
- break;
-
- case SAT_PROATV_CMD_CLOSE_CHANNEL:
- tr_len = _sat_encode_close_channel(&(src_tr->terminal_rsp_data.close_channel), dst_tr);
- break;
-
- case SAT_PROATV_CMD_SEND_DATA:
- tr_len = _sat_encode_send_data(&(src_tr->terminal_rsp_data.send_data), dst_tr);
- break;
-
- case SAT_PROATV_CMD_RECEIVE_DATA:
- tr_len = _sat_encode_receive_data(&(src_tr->terminal_rsp_data.receive_data), dst_tr);
- break;
-
- case SAT_PROATV_CMD_GET_CHANNEL_STATUS:
- tr_len = _sat_encode_get_channel_status(&(src_tr->terminal_rsp_data.get_channel_status), dst_tr);
- break;
-
- default:
- tr_len = _sat_encode_unsupport_command(&(src_tr->terminal_rsp_data.unsupport_cmd), dst_tr);
- break;
- }
-
- return tr_len;
-}
-
-CoreObject *tcore_sat_new(TcorePlugin *p, const char *name,
- struct tcore_sat_operations *ops, TcoreHal *hal)
-{
- CoreObject *o = NULL;
- struct private_object_data *po = NULL;
-
- if (!p)
- return NULL;
-
- o = tcore_object_new(p, name, hal);
- if (!o)
- return NULL;
-
- po = calloc(1, sizeof(struct private_object_data));
- if (!po) {
- tcore_object_free(o);
- return NULL;
- }
-
- /* set ops to default type when core object is created. */
- po->ops[TCORE_OPS_TYPE_CP] = ops;
-
- tcore_object_set_type(o, CORE_OBJECT_TYPE_SAT);
- tcore_object_link_object(o, po);
- tcore_object_set_free_hook(o, _free_hook);
- tcore_object_set_dispatcher(o, _dispatcher);
-
- return o;
-}
-
-void tcore_sat_free(CoreObject *o)
-{
- CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_SAT);
-
- tcore_object_free(o);
-}
-
-void tcore_sat_set_ops(CoreObject *o, struct tcore_sat_operations *ops, enum tcore_ops_type ops_type)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_SAT);
- CORE_OBJECT_VALIDATE_OPS_RETURN(ops_type);
-
- po = (struct private_object_data *)tcore_object_ref_object(o);
- if (!po) {
- err("po is NULL");
- return;
- }
-
- po->ops[ops_type] = ops;
-}
+++ /dev/null
-/*
- * libtcore
- *
- * 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.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <glib.h>
-
-#include "tcore.h"
-#include "internal/tcore_types.h"
-#include "plugin.h"
-#include "queue.h"
-#include "user_request.h"
-#include "core_object.h"
-#include "co_sim.h"
-
-#define SIM_FILE_TYPE_TAG 0x07
-#define SIM_FCP_TEMPLATE_TAG 0x62
-#define SIM_FILE_DESCRIPTOR_TAG 0x82
-#define SIM_FILE_IDENTIFIER_TAG 0x83
-#define SIM_PROPRIETARY_INFORMATION_TAG 0xA5
-#define SIM_LIFE_CYCLE_STATUS_TAG 0x8A
-#define SIM_FILE_SIZE_TAG 0x80
-#define SIM_TOTAL_FILE_SIZE_TAG 0x81
-#define SIM_SHORT_FILE_IDENTIFIER_TAG 0x88
-
-/* USIM file types */
-#define SIM_FTYPE_TRANSPARENT 0x1
-#define SIM_FTYPE_LINEAR_FIXED 0x2
-#define SIM_FTYPE_CYCLIC 0x6
-
-/* GSM file types */
-#define SIM_FTYPE_RFU 0x0
-#define SIM_FTYPE_MF 0x1
-#define SIM_FTYPE_DF 0x2
-#define SIM_FTYPE_EF 0x4
-
-struct private_object_data {
- struct tcore_sim_operations *ops[TCORE_OPS_TYPE_MAX];
-
- unsigned char app_list;
- enum tel_sim_type type; /**< Provides the SIM card type*/
- enum tel_sim_status sim_status; /**< Provides the card status*/
- struct tel_sim_imsi imsi; /**< Provides IMSI information*/
- gboolean b_sim_changed; /**< Provides SIM card Identification- 0:no changed, 1:changed*/
- gboolean b_cphs; /**< Whether current SIM is for CPHS or not*/
- struct tel_sim_service_table *svct; /**< (U)SIM Service Table information*/
- struct tel_sim_ecc_list *ecc_list;
- struct tel_sim_msisdn_list *msisdn_list;
- struct tel_sim_spn *spn;
- struct tel_sim_cphs_netname *cphs_netname;
- struct tel_sim_iccid *iccid;
- struct tel_sim_cphs_csp *csp;
- struct tel_sim_ist *ist;
- void *userdata; /**< free use data*/
-};
-
-/*
- * Below table is created by referring two sites:
- *
- * 1) ITU "Mobile Network Code (MNC) for the international
- * identification plan for mobile terminals and mobile users"
- * which is available as an annex to the ITU operational bulletin
- * available here: http://www.itu.int/itu-t/bulletin/annex.html
- *
- * 2) The ISO 3166 country codes list, available here:
- * http://www.iso.org/iso/en/prods-services/iso3166ma/02iso-3166-code-lists/index.html
- *
- */
-static const char *mcc_having_3digits_mnc[] = {
- "302", /* Canada */
- "310", "311", "312", "313", "314", "315", "316", /* United States of America */
- /* "334",*/ /* Mexico (uses 3-digits MNC only partially.) */
- "338", /* Jamaica */
- "342", /* Barbados */
- "344", /* Antigua and Barbuda */
- "346", /* Cayman Islands */
- "348", /* British Virgin Islands */
- "365", /* Anguilla */
- "708", /* Honduras (Republic of) */
- /* "722", */ /* Argentine Republic (uses 3-digits MNC only partially.) */
- "732", /* Colombia (Republic of) */
-};
-
-static const char *plmn_having_3digits_mnc[] = {
- /* Mexico */
- "334020", /* Telcel */
- "334050", /* Iusacell/Unefon */
- /* India */
- "405025", "405026", "405027", "405028", "405029", "405030", "405031", "405032",
- "405033", "405034", "405035", "405036", "405037", "405038", "405039", "405040",
- "405041", "405042", "405043", "405044", "405045", "405046", "405047", "405750",
- "405751", "405752", "405753", "405754", "405755", "405756", "405799", "405800",
- "405801", "405802", "405803", "405804", "405805", "405806", "405807", "405808",
- "405809", "405810", "405811", "405812", "405813", "405814", "405815", "405816",
- "405817", "405818", "405819", "405820", "405821", "405822", "405823", "405824",
- "405825", "405826", "405827", "405828", "405829", "405830", "405831", "405832",
- "405833", "405834", "405835", "405836", "405837", "405838", "405839", "405840",
- "405841", "405842", "405843", "405844", "405845", "405846", "405847", "405848",
- "405849", "405850", "405851", "405852", "405853", "405875", "405876", "405877",
- "405878", "405879", "405880", "405881", "405882", "405883", "405884", "405885",
- "405886", "405908", "405909", "405910", "405911", "405912", "405913", "405914",
- "405915", "405916", "405917", "405918", "405919", "405920", "405921", "405922",
- "405923", "405924", "405925", "405926", "405927", "405928", "405929", "405930",
- "405931", "405932",
- /* Malaysia */
- "502142", "502143", "502145", "502146", "502147", "502148",
- /* Argentina */
- "722070", /* Movistar AR */
- "722310", /* Claro AR */
- "722341", /* Personal AR */
-};
-
-gboolean tcore_sim_check_plmn_having_3digits_mnc(char *plmn)
-{
- int num = 0;
- int i = 0;
- char *mcc = NULL;
-
- mcc = g_strndup(plmn, 3 + 1);
- if (mcc) {
- mcc[3] = '\0';
- num = G_N_ELEMENTS(mcc_having_3digits_mnc);
- for (i = 0; i < num; i++) {
- if (strcmp((const char *)mcc, mcc_having_3digits_mnc[i]) == 0) {
- g_free(mcc);
- return TRUE;
- }
- }
- g_free(mcc);
- }
-
- num = G_N_ELEMENTS(plmn_having_3digits_mnc);
- for (i = 0; i < num; i++)
- if (strcmp((const char *)plmn, plmn_having_3digits_mnc[i]) == 0)
- return TRUE;
-
- return FALSE;
-}
-
-static TReturn _dispatcher(CoreObject *o, UserRequest *ur, enum tcore_ops_type ops_type)
-{
- enum tcore_request_command command;
- struct private_object_data *po = tcore_object_ref_object(o);
- struct tcore_sim_operations *ops = NULL;
-
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_SIM, TCORE_RETURN_EINVAL);
- CORE_OBJECT_VALIDATE_OPS_RETURN_VAL(ops_type, TCORE_RETURN_EINVAL);
-
- tcore_check_null_ret_err("po", po, TCORE_RETURN_EINVAL);
- tcore_check_null_ret_err("ur", ur, TCORE_RETURN_EINVAL);
-
- ops = po->ops[ops_type];
- tcore_check_null_ret_err("ops", ops, TCORE_RETURN_FAILURE);
-
- command = tcore_user_request_get_command(ur);
-
- switch (command) {
- case TREQ_SIM_VERIFY_PINS:
- tcore_check_null_ret_err("ops->verify_pins",
- ops->verify_pins, TCORE_RETURN_ENOSYS);
-
- return ops->verify_pins(o, ur);
-
- case TREQ_SIM_VERIFY_PUKS:
- tcore_check_null_ret_err("ops->verify_puks",
- ops->verify_puks, TCORE_RETURN_ENOSYS);
-
- return ops->verify_puks(o, ur);
-
- case TREQ_SIM_CHANGE_PINS:
- tcore_check_null_ret_err("ops->change_pins",
- ops->change_pins, TCORE_RETURN_ENOSYS);
-
- return ops->change_pins(o, ur);
-
- case TREQ_SIM_GET_FACILITY_STATUS:
- tcore_check_null_ret_err("ops->get_facility_status",
- ops->get_facility_status, TCORE_RETURN_ENOSYS);
-
- return ops->get_facility_status(o, ur);
-
- case TREQ_SIM_DISABLE_FACILITY:
- tcore_check_null_ret_err("ops->disable_facility",
- ops->disable_facility, TCORE_RETURN_ENOSYS);
-
- return ops->disable_facility(o, ur);
-
- case TREQ_SIM_ENABLE_FACILITY:
- tcore_check_null_ret_err("ops->enable_facility",
- ops->enable_facility, TCORE_RETURN_ENOSYS);
-
- return ops->enable_facility(o, ur);
-
- case TREQ_SIM_GET_LOCK_INFO:
- tcore_check_null_ret_err("ops->get_lock_info",
- ops->get_lock_info, TCORE_RETURN_ENOSYS);
-
- return ops->get_lock_info(o, ur);
-
- case TREQ_SIM_TRANSMIT_APDU:
- tcore_check_null_ret_err("ops->transmit_apdu",
- ops->transmit_apdu, TCORE_RETURN_ENOSYS);
-
- return ops->transmit_apdu(o, ur);
-
- case TREQ_SIM_GET_ATR:
- tcore_check_null_ret_err("ops->get_atr",
- ops->get_atr, TCORE_RETURN_ENOSYS);
-
- return ops->get_atr(o, ur);
-
- case TREQ_SIM_SET_LANGUAGE:
- case TREQ_SIM_SET_CALLFORWARDING:
- case TREQ_SIM_SET_MESSAGEWAITING:
- case TREQ_SIM_SET_MAILBOX:
-#if defined TIZEN_GLOBALCONFIG_ENABLE_CSP
- case TREQ_SIM_SET_CPHS_CSP_INFO:
-#endif
- tcore_check_null_ret_err("ops->update_file",
- ops->update_file, TCORE_RETURN_ENOSYS);
-
- return ops->update_file(o, ur);
-
- case TREQ_SIM_GET_ECC:
- case TREQ_SIM_GET_LANGUAGE:
- case TREQ_SIM_GET_ICCID:
- case TREQ_SIM_GET_MAILBOX:
- case TREQ_SIM_GET_CALLFORWARDING:
- case TREQ_SIM_GET_MESSAGEWAITING:
- case TREQ_SIM_GET_CPHS_INFO:
- case TREQ_SIM_GET_SERVICE_TABLE:
- case TREQ_SIM_GET_MSISDN:
- case TREQ_SIM_GET_SPN:
- case TREQ_SIM_GET_SPDI:
- case TREQ_SIM_GET_OPL:
- case TREQ_SIM_GET_PNN:
- case TREQ_SIM_GET_CPHS_NETNAME:
- case TREQ_SIM_GET_OPLMNWACT:
- case TREQ_SIM_GET_ICON:
- case TREQ_SIM_GET_IMPI:
- case TREQ_SIM_GET_IMPU:
- case TREQ_SIM_GET_GID:
- case TREQ_SIM_GET_DOMAIN:
- case TREQ_SIM_GET_PCSCF:
- case TREQ_SIM_GET_ISIM_SERVICE_TABLE:
- tcore_check_null_ret_err("ops->read_file",
- ops->read_file, TCORE_RETURN_ENOSYS);
-
- return ops->read_file(o, ur);
-
- case TREQ_SIM_REQ_AUTHENTICATION:
- tcore_check_null_ret_err("ops->req_authentication",
- ops->req_authentication, TCORE_RETURN_ENOSYS);
-
- return ops->req_authentication(o, ur);
-
- case TREQ_SIM_SET_POWERSTATE:
- tcore_check_null_ret_err("ops->set_powerstate",
- ops->set_powerstate, TCORE_RETURN_ENOSYS);
-
- return ops->set_powerstate(o, ur);
-
- default:
- warn("unhandled request command[%d]", command);
- break;
- }
-
- return TCORE_RETURN_SUCCESS;
-}
-
-static void _free_hook(CoreObject *o)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_SIM);
-
- po = tcore_object_ref_object(o);
- if (po) {
- if (po->svct)
- free(po->svct);
-
- if (po->ecc_list)
- free(po->ecc_list);
-
- if (po->msisdn_list)
- free(po->msisdn_list);
-
- if (po->spn)
- free(po->spn);
-
- if (po->cphs_netname)
- free(po->cphs_netname);
-
- if (po->iccid)
- free(po->iccid);
-
- if (po->csp)
- free(po->csp);
-
- if (po->ist)
- free(po->ist);
-
- free(po);
- tcore_object_link_object(o, NULL);
- }
-}
-
-static void _reverse(char *p_in, int length)
-{
- int i, j = length - 1;
-
- for (i = 0; i < j; i++) {
- int t = p_in[i];
- p_in[i] = p_in[j];
- p_in[j--] = t;
- }
-}
-
-static char *_acitoa(int n, char *str, int b)
-{
- int i = 0;
-
- do {
- str[i++] = "0123456789ABCDEF"[n % b];
- } while ((n /= b) > 0);
-
- _reverse(str, i);
-
- str[i] = '\0';
-
- return str;
-}
-
-/*******************************************************************************
- Convert Digit to BCD (BCD to Digit)
-
- bcd <---> digit
- 0xa 0x2a '*'
- 0xb 0x23 '#'
- 0xc 0x70 'P'
- 0xd '?'
- 0xf 0
- 1032547698 0123456789
-
- ********************************************************************************/
-/**
- * This function is used to Convert Digit to BCD (Digit to BCD)
- *
- * @return None
- * @param[out] bcdCode - BCD output
- * @param[in] digits - Digit input
- * @param[in] digitLen - digit length
- * @Interface Synchronous.
- * @remark
- * @Refer
- */
-static void _digit_to_bcd(char *bcdCode, char *digits, int digitLen)
-{
- int i, j, digit;
- unsigned char higher, lower;
-
- /* 0123456789 -> 1032547698 */
- for (i = 0, j = 0; i < digitLen; i = i + 2, j++) {
- if (digits[i] == '*')
- digit = 0x0A;
- else if (digits[i] == '#')
- digit = 0x0B;
- else if (toupper((int) digits[i]) == 'P')
- digit = 0x0C;
- else if ((digits[i]) == '?')
- digit = 0x0D;
- else
- digit = (int) digits[i];
-
- lower = digit & 0x0F;
-
- if (digitLen != i + 1) {
- if (digits[i + 1] == '*')
- digit = 0x0A;
- else if (digits[i + 1] == '#')
- digit = 0x0B;
- else if (toupper((int) digits[i + 1]) == 'P')
- digit = 0x0C;
- else if (digits[i + 1] == '?')
- digit = 0x0D;
- else
- digit = (int) digits[i + 1];
- higher = digit & 0x0F;
- } else
- higher = 0xFF;
-
- bcdCode[j] = (higher << 4) | lower;
- }
-}
-
-/**
- * This function is used to Convert BCD to Digit (BCD to Digit)
- *
- * @return None
- * @param[out] digit - Digit output output
- * @param[in] bcdCode - BCD Input
- * @param[in] bcdLen - BCD length
- * @Interface Synchronous.
- * @remark
- * @Refer
- */
-static unsigned long _bcd_to_digit(char *digit, char *bcdCode, int bcdLen)
-{
- int i, h, l;
- char c[2];
- unsigned char higher, lower;
- unsigned long digitLen = 0;
-
- /* 0123456789 <- 1032547698 */
- memset((void *)digit, 0, bcdLen * 2);
-
- for (i = 0; i < bcdLen; i++) {
- higher = (bcdCode[i] >> 4) & 0x0F; /* get high nibble */
-
- if (higher == 0x0A)
- higher = '*'; /* =0x2A */
- else if (higher == 0x0B)
- higher = '#'; /* =0x23 */
- else if (higher == 0x0C)
- higher = 'P'; /* =0x70, DTMF Control digit */
- else if (higher == 0x0D)
- higher = '?';
- else if (higher == 0x0F)
- higher = 0;
- else {
- h = (int) higher;
- _acitoa(h, c, 16);
- higher = (char) toupper(*c);
- }
-
- lower = bcdCode[i] & 0x0F; /* get low nibble */
-
- if (lower == 0x0A)
- lower = '*';
- else if (lower == 0x0B)
- lower = '#';
- else if (lower == 0x0C)
- lower = 'P'; /* DTMF Control digit */
- else if (lower == 0x0D)
- lower = '?';
- else if (lower == 0x0F)
- lower = 0;
- else {
- l = (int) lower;
- _acitoa(l, c, 16);
- lower = (char) toupper(*c);
- }
-
- digit[i * 2] = lower;
- digit[i * 2 + 1] = higher;
- }
-
- digitLen = (unsigned long)strlen(digit);
- return digitLen;
-}
-
-/**
- * This function is used to get(decode) string name
- *
- * @return length of string
- * @param[out] palpha_id - Alpha string
- * @param[in] pRecord - Input raw data
- * @param[in] alphaIDMaxLen - Max size of alpha id array
- * @Interface Synchronous.
- * @remark
- * @Refer
- */
-static unsigned long _get_string(unsigned char *palpha_id, unsigned char *pRecord, unsigned long alphaIDMaxLen)
-{
- unsigned long i, alphaIDLen = 0;
- unsigned char *pAlphaID = (unsigned char *) palpha_id;
-
- memset((void *)pAlphaID, 0, alphaIDMaxLen);
-
- if (pRecord[0] == 0xFF)
- return alphaIDLen;
-
- for (i = 0; i < alphaIDMaxLen; i++) {
- if (pRecord[0] <= 0x7F && pRecord[i] == 0xFF)
- break;
-
- pAlphaID[i] = pRecord[i];
- alphaIDLen++;
- }
-
- return alphaIDLen;
-}
-
-/**
- * This function is used to set(encode) string name
- *
- * @return length of string
- * @param[in] palpha_id - Alpha string input
- * @param[out] pRecord - output raw data
- * @param[in] alphaIDMaxLen - Max size of alpha id array
- * @Interface Synchronous.
- * @remark
- * @Refer
- */
-static void _set_string(unsigned char *pRecord, unsigned char *palpha_id, unsigned long alphaIDMaxLen)
-{
- unsigned long i;
- unsigned char *pAlphaID = (unsigned char *) palpha_id;
-
- memset((void *) pRecord, 0xFF, alphaIDMaxLen);
-
- for (i = 0; i < alphaIDMaxLen; i++)
- pRecord[i] = pAlphaID[i];
-}
-
-static gboolean _is_empty(unsigned char *p_in, int in_length)
-{
- int i;
- for (i = 0; i < in_length; i++) {
- if (p_in[i] != 0xFF)
- return FALSE;
- }
-
- dbg("current index has empty data");
- return TRUE; /* this is empty record */
-}
-
-/**
- * This function is used to get BCD length
- *
- * @return length of string
- * @param[in] pBcdData - BCD Input data
- * @param[in] bcdMaxLen - BCD Max data Length
- * @Interface Synchronous.
- * @remark
- * @Refer
- */
-static int _get_valid_bcd_byte(unsigned char *pBcdData, int bcdMaxLen)
-{
- int i, bcd_length = 0;
-
- for (i = 0; i < bcdMaxLen; i++) {
- if (pBcdData[i] == 0xFF)
- break;
-
- bcd_length++;
- }
-
- return bcd_length;
-}
-
-/**
- * This function is used to get unpacked 8bit Format from GSM 7bit packed string.
- *
- * @return the length of unpacked characters .
- * @param[out] out_string Specifies the unpacked output string
- * @param[in] in_string Contains the input string to be unpacked
- * @param[in] in_string_len Contains the input string length
- * @remark
- */
-static int _unpack_7bit28bit(unsigned char *pInString, unsigned int inStringLen, unsigned char *pOutString)
-{
- int i = 0;
- unsigned int pos = 0;
- unsigned short shift = 0;
- int outlen = 0;
- outlen = (short int)((inStringLen * 8) / 7);
-
- for (i = 0; pos < inStringLen; i++, pos++) {
- pOutString[i] = (pInString[pos] << shift) & 0x7F;
-
- if (pos != 0) {
- /* except the first byte, a character contains some bits from the previous byte. */
- pOutString[i] |= pInString[pos - 1] >> (8 - shift);
- }
-
- shift++;
-
- if (shift == 7) {
- shift = 0;
-
- /* a possible extra complete character is available */
- i++;
- pOutString[i] = pInString[pos] >> 1;
- }
- }
-
- /* If a character is '\r'(13), change it to space(32) */
- for (i = 0; i < outlen; i++)
- if (pOutString[i] == 13) pOutString[i] = 32;
-
- pOutString[outlen] = '\0';
-
- dbg("unpack is done with outlen[%d] and array index[%d], out string[%s]", outlen, i, pOutString);
- return (unsigned int)(i);
-}
-
-static int _ucs2_to_utf8(int in_length, unsigned char *in_data, int *out_length, unsigned char *out_data)
-{
- int i, j;
-
- if (in_length == 0 || in_data == NULL || out_data == NULL) {
- dbg("Unicode Decode Failed as text length is 0");
- return FALSE;
- }
-
- if (0 != (in_length % 2)) {
- dbg(" ##### Unicode decoding failed due to invalid text length [%d]",
- in_length);
- return FALSE;
- }
-
- for (i = 0, j = 0; i < in_length; i++) {
- out_data[i] = in_data[j];
- j = j + 2;
- }
-
- *out_length = (in_length / 2);
- out_data[i] = '\0';
- return TRUE;
-}
-
-static int _decode_cdma_imsi_util(char *imsi, unsigned short *mcc, unsigned char *mnc,
- unsigned long *min1, unsigned short *min2)
-{
- unsigned short country_code = *mcc;
- unsigned char nw_code = *mnc;
- unsigned long imsi_min1 = *min1;
- unsigned short imsi_min2 = *min2;
- unsigned short second_three = 0;
- unsigned char thousands = 0;
- unsigned short last_three = 0;
- unsigned char min_to_digit[] = {'1', '2', '3', '4', '5', '6', '7', '8', '9', '0'};
- unsigned char bcd_to_num[] = {0xFF, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
- int p_digit = 0;
- int digit = 0;
-
- /* Convert Country code of IMSI */
- if (country_code <= 999) {
- digit = min_to_digit[country_code/100];
- imsi[p_digit++] = digit;
- country_code %= 100;
-
- digit = min_to_digit[country_code / 10];
- imsi[p_digit++] = digit;
-
- digit = min_to_digit[country_code % 10];
- imsi[p_digit++] = digit;
-
- } else {
- err("Invalid Country code");
- return -1;
- }
-
- /* Convert Network code of IMSI */
- if (nw_code <= 99) {
- digit = min_to_digit[nw_code / 10];
- imsi[p_digit++] = digit;
-
- digit = min_to_digit[nw_code % 10];
- imsi[p_digit++] = digit;
- } else {
- err("Invalid Network code");
- return -1;
- }
-
- /* Convert First Three Digits of IMSI */
- if (imsi_min2 <= 999) {
- digit = min_to_digit[imsi_min2 / 100];
- imsi[p_digit++] = digit;
- imsi_min2 %= 100;
-
- digit = min_to_digit[imsi_min2 / 10];
- imsi[p_digit++] = digit;
-
- digit = min_to_digit[imsi_min2 % 10];
- imsi[p_digit++] = digit;
- } else {
- err("Invalid IMSI_MIN2 code");
- return -1;
- }
-
- /* Convert Last Seven digits of IMSI */
- second_three = (imsi_min1 & 0x00FFC000) >> 14;
- thousands = (imsi_min1 & 0x00003C00) >> 10;
- last_three = (imsi_min1 & 0x000003FF) >> 0;
-
- thousands = bcd_to_num[thousands];
- if ((thousands != 0xFF) && (second_three <= 999) && (last_three <= 999)) {
- digit = min_to_digit[second_three / 100];
- imsi[p_digit++] = digit;
-
- second_three %= 100;
-
- digit = min_to_digit[second_three / 10];
- imsi[p_digit++] = digit;
-
- digit = min_to_digit[second_three % 10];
- imsi[p_digit++] = digit;
-
- imsi[p_digit++] = thousands;
-
- digit = min_to_digit[last_three / 100];
- imsi[p_digit++] = digit;
-
- last_three %= 100;
-
- digit = min_to_digit[last_three / 10];
- imsi[p_digit++] = digit;
-
- digit = min_to_digit[last_three % 10];
- imsi[p_digit++] = digit;
- } else {
- err("Invalid IMSI_MIN1 code");
- return -1;
- }
-
- return p_digit;
-}
-
-/**
- * This function is used to decode 3 bytes of plmn string encoded as TS 24.008 to 6 bytes char string.
- *
- * @return void .
- * @param[out] out decoded output string (must be 6 + 1 bytes)
- * @param[in] in encoded input string (must be 3 bytes)
- * @remark
- */
-static void _decode_plmn(const unsigned char *in, unsigned char *out)
-{
- unsigned char temp[6 + 1] = {0, };
- int i;
- unsigned char higher, lower;
-
- for (i = 0; i < 3; i++) {
- higher = (in[i] >> 4) & 0x0F; /* get high nibble */
- if (higher < 0x0A) {
- /* if it is a number */
- temp[i*2] = higher + 0x30;
- } else if (higher == 0x0D) {
- /* 0x0D (BCD digit) is regarded as wild character by TS 24.008 */
- temp[i*2] = 'D';
- } else
- temp[i*2] = 0x00;
-
- lower = in[i] & 0x0F; /* get low nibble */
- if (lower < 0x0A) {
- /* if it is a number */
- temp[i*2 + 1] = lower + 0x30;
- } else if (lower == 0x0D) {
- /* 0x0D (BCD digit) is regarded as wild character by TS 24.008 */
- temp[i*2 + 1] = 'D';
- } else
- temp[i*2 + 1] = 0x00;
- }
-
- /* according to PLMN digits order by TS 24.008 */
- /* MCC */
- out[0] = temp[1];
- out[1] = temp[0];
- out[2] = temp[3];
- /* MNC */
- out[3] = temp[5];
- out[4] = temp[4];
- out[5] = temp[2];
-
- out[6] = '\0';
-
- /*
- * [14.08.21]
- * As NA Operators requested,
- * for NA operators (MCC 310 ~ 316),
- * if 6th digit of MNC is 'F' then should be regarded as '0'.
- */
- if (out[5] == 0x00
- && strncmp((const char *)out, "31", 2) == 0
- && ('0' <= out[2] && out[2] <= '6')) {
- out[5] = '0';
- }
-}
-
-static inline unsigned short int _swap_bytes16(unsigned short int x)
-{
- return ((x & 0xFF00) >> 8) | ((x & 0x00FF) << 8);
-}
-
-/**
- * According to ETSI 102.221 (3GPP specification refers it), EF-ICCID is coded by BCD, left justified and padded with 'F'.
- * This EF is mandatory and byte length is fixed with 10 bytes. So actual maximum length of ICCID is 20 digits.
- */
-gboolean tcore_sim_decode_iccid(struct tel_sim_iccid *p_out, unsigned char *p_in, int in_length)
-{
- int bcd_byte = 0;
- int char_length = 0;
-
- if (p_in == NULL || p_out == NULL)
- return FALSE;
-
- if (in_length == 0 || in_length > 10)
- return FALSE;
-
- memset((void *)p_out->iccid, 0, SIM_ICCID_LEN_MAX+1);
-
- bcd_byte = _get_valid_bcd_byte(p_in, in_length);
- char_length = _bcd_to_digit(p_out->iccid, (char *) p_in, bcd_byte);
- dbg("bcd byte:[%d] string length:[%d]", bcd_byte, char_length);
-
- *(p_out->iccid+char_length) = '\0';
-
- return TRUE;
-}
-
-/**
- * This function is used to decode EFLP (2G)
- */
-gboolean tcore_sim_decode_lp(struct tel_sim_language *p_out, unsigned char *p_in, int in_length)
-{
- int i = 0;
-
- memset((void *) p_out, 0xFF, sizeof(struct tel_sim_language));
- p_out->language_count = 0;
-
- if (in_length == 0)
- return FALSE;
-
- /*
- * Description of problem: language decoding was not correctly done if we
- * used 7layers's test SIM
- *
- * Patch Description : The tested SIM at 7layers has 3 language codes like [ff][ff][01].
- * In this case we could not decode 3rd language code.
- * So, the below 2 lines checking the UNSPECIFIED language are commented.
- */
-
- if (in_length > SIM_LANG_CNT_MAX)
- in_length = SIM_LANG_CNT_MAX;
-
- for (i = 0; i < in_length; i++) {
- /*
- * Description of problem: Language decoding was not correctly done if we used some test SIM
- * Patch Description : Test SIM at some place has 3 language codes like [ff][ff][01].
- * In this case we could not decode 3rd language code.
- * So, the below 2 lines checking the UNSPECIFIED language are commented.
- */
- if (p_in[i] == 0xFF)
- continue;
-
- p_out->language[p_out->language_count] = (enum tel_sim_language_type) p_in[i];
- dbg("p_out->language[%d]=[%d] ", i, p_out->language[p_out->language_count]);
- p_out->language_count++;
- }
-
- dbg("in_length %d, lang_cnt %d ", in_length, p_out->language_count);
- return TRUE;
-}
-
-/**
- * This function is used to encode EFLP (2G)
- */
-char *tcore_sim_encode_lp(int *out_length, struct tel_sim_language *p_in)
-{
- int i = 0;
- char *tmp_out = NULL;
-
- if (out_length == NULL || p_in == NULL) {
- dbg("out_length or p_in is null");
- return NULL;
- }
-
- tmp_out = (char *)malloc(p_in->language_count);
- if (!tmp_out)
- return NULL;
-
- memset((void *) tmp_out, 0xff, p_in->language_count);
-
- for (i = 0; i < p_in->language_count; i++)
- tmp_out[i] = p_in->language[i];
-
- *out_length = i;
- return tmp_out;
-}
-
-/**
- * This function is used to decode LI (3G)
- */
-gboolean tcore_sim_decode_li(enum tel_sim_file_id file_id, struct tel_sim_language *p_out, unsigned char *p_in, int in_length)
-{
- int i;
- unsigned short defaultLi;
- unsigned char tempLi[3] = { 0, 0, 0 };
-
- memset((void *)p_out, 0xFF, sizeof(struct tel_sim_language));
- p_out->language_count = 0;
-
- if (in_length == 0)
- return FALSE;
-
- /*
- * Description of problem: language decoding was not correctly done if we
- * used 7layers's test SIM
- *
- * Patch Description : TS31.102 If the EFLI has the value 'FFFF' in its highest priority position,
- * then the preferred language selection shall be the language preference in the EFPL
- */
- if (/*TODO g_sim.CardType == SIM_TYPE_USIM && */(file_id == SIM_EF_USIM_LI || file_id == SIM_EF_LP)) {
- defaultLi = p_in[0];
- defaultLi = ((defaultLi << 8) & 0xFF00) + p_in[1];
-
- if (defaultLi == 0xFFFF) /* 1st language is default. */
- return FALSE;
- }
-
- if (in_length > SIM_LANG_CNT_MAX)
- in_length = SIM_LANG_CNT_MAX;
-
- for (i = 0; i < in_length; i++) {
- tempLi[0] = p_in[i++];
- tempLi[1] = p_in[i];
-
- /*
- * Description of problem: language decoding was not correctly
- * done if we used 7layers's test SIM
- *
- * Patch Description : The tested SIM at specific test lab has
- * 3 language codes like [ff][ff][ff][ff][64][65].
- * In this case we could not decode 3rd language code.
- * So, the below 2 lines checking the UNSPECIFIED language are commented.
- */
- if (tempLi[0] == 0xFF || tempLi[1] == 0xFF) /* this is always 2 bytes */
- continue;
-
- p_out->language[p_out->language_count] = SIM_LANG_UNSPECIFIED;
-
- if (tempLi[0] == 'e') {
- switch (tempLi[1]) {
- case 'n':
- p_out->language[p_out->language_count] = SIM_LANG_ENGLISH;
- break;
-
- case 's':
- p_out->language[p_out->language_count] = SIM_LANG_SPANISH;
- break;
-
- case 'l':
- p_out->language[p_out->language_count] = SIM_LANG_GREEK;
- break;
-
- default:
- warn("invalid language");
- break;
- }
- } else if (tempLi[0] == 'd') {
- switch (tempLi[1]) {
- case 'e':
- p_out->language[p_out->language_count] = SIM_LANG_GERMAN;
- break;
-
- case 'a':
- p_out->language[p_out->language_count] = SIM_LANG_DANISH;
- break;
-
- default:
- warn("invalid language");
- break;
- }
- } else if (tempLi[0] == 'i' && tempLi[1] == 't')
- p_out->language[p_out->language_count] = SIM_LANG_ITALIAN;
- else if (tempLi[0] == 'f' && tempLi[1] == 'r')
- p_out->language[p_out->language_count] = SIM_LANG_FRENCH;
- else if (tempLi[0] == 'n' && tempLi[1] == 'l')
- p_out->language[p_out->language_count] = SIM_LANG_DUTCH;
- else if (tempLi[0] == 's' && tempLi[1] == 'v')
- p_out->language[p_out->language_count] = SIM_LANG_SWEDISH;
- else if (tempLi[0] == 'f' && tempLi[1] == 'i')
- p_out->language[p_out->language_count] = SIM_LANG_FINNISH;
- else if (tempLi[0] == 'n' && tempLi[1] == 'o')
- p_out->language[p_out->language_count] = SIM_LANG_NORWEGIAN;
- else if (tempLi[0] == 't' && tempLi[1] == 'r')
- p_out->language[p_out->language_count] = SIM_LANG_TURKISH;
- else if (tempLi[0] == 'h' && tempLi[1] == 'u')
- p_out->language[p_out->language_count] = SIM_LANG_HUNGARIAN;
- else if (tempLi[0] == 'p') {
- switch (tempLi[1]) {
- case 'l':
- p_out->language[p_out->language_count] = SIM_LANG_POLISH;
- break;
-
- case 't':
- p_out->language[p_out->language_count] = SIM_LANG_PORTUGUESE;
- break;
-
- default:
- warn("invalid language");
- break;
- }
- } else if (tempLi[0] == 'k' && tempLi[1] == 'o')
- p_out->language[p_out->language_count] = SIM_LANG_KOREAN;
- else if (tempLi[0] == 'z' && tempLi[1] == 'h')
- p_out->language[p_out->language_count] = SIM_LANG_CHINESE;
- else if (tempLi[0] == 'r' && tempLi[1] == 'u')
- p_out->language[p_out->language_count] = SIM_LANG_RUSSIAN;
- else if (tempLi[0] == 'j' && tempLi[1] == 'a')
- p_out->language[p_out->language_count] = SIM_LANG_JAPANESE;
-
- dbg("count %d & Codes %d ", p_out->language_count, p_out->language[p_out->language_count]);
- p_out->language_count++;
- }
-
- if (p_out->language_count == 0) {
- dbg("p_out->language_count = %d ", p_out->language_count);
- return FALSE;
- } else {
- return TRUE;
- }
-}
-
-/**
- * This function is used to encode EFLI (3G)
- */
-char *tcore_sim_encode_li(int *out_length, struct tel_sim_language *p_in)
-{
- int i = 0;
- char *tmp_out = NULL;
- const char *LanguageCode[] = {
- "de", "en", "it", "fr",
- "es", "nl", "sv", "da",
- "pt", "fi", "no", "el",
- "tr", "hu", "pl", "ko",
- "zh", "ru", "ja"};
-
- if (out_length == NULL || p_in == NULL) {
- dbg("out_length or p_in is null");
- return NULL;
- }
-
- tmp_out = (char *)malloc((p_in->language_count) * 2);
- if (!tmp_out)
- return NULL;
-
- memset((void *)tmp_out, 0xff, (p_in->language_count) * 2);
-
- for (i = 0; i < p_in->language_count; i++) {
- if (p_in->language[i] < SIM_LANG_UNSPECIFIED) {
- strncpy((char *) &tmp_out[i * 2], LanguageCode[p_in->language[i]], 2);
- dbg("sim_encode_li: p_out[%s]:[%x][%x]", tmp_out, tmp_out[i*2], tmp_out[(i*2)+1]);
- }
- }
-
- *out_length = i*2;
- return tmp_out;
-}
-
-gboolean tcore_sim_decode_imsi(struct tel_sim_imsi *p_out, unsigned char *p_in, int in_length)
-{
- int i = 0, j = 0;
- char imsi_raw[16];
- char *plmn = NULL;
- int plmn_digits = 5;
-
- if ((NULL == p_out) || (NULL == p_in))
- return FALSE;
-
- /*
- * According to 3GPP specification, the length of raw IMSI data is 9 bytes.
- * first byte is length of IMSI
- * second byte byte has parity nibble, so second byte has one digit of IMSI.
- * other byte has two digit of IMSI
- */
- if ((in_length == 0) || (in_length == 0xff) || (4 > in_length) || (9 < in_length)) {
- dbg("No valid IMSI present to convert - length:[%x]", in_length);
- return FALSE;
- }
-
- /* Decode IMSI value from nibbles */
- for (i = 1; i < in_length; i++) {
- if (i == 1) { /* first byte, ignore lower nibble */
- imsi_raw[j++] = ((p_in[i] & 0xF0) >> 4) + '0';
- } else if (i == p_in[0] + 1) { /* last byte */
- imsi_raw[j++] = (p_in[i] & 0x0F) + '0';
- if (p_in[0] % 2) /* count the last one if odd digits */
- imsi_raw[j++] = ((p_in[i] & 0xF0) >> 4) + '0';
- } else {
- imsi_raw[j++] = (p_in[i] & 0x0F) + '0';
- imsi_raw[j++] = ((p_in[i] & 0xF0) >> 4) + '0';
- }
- }
-
- /* Determine # of PLMN digits (5 or 6) */
- plmn = g_strndup(imsi_raw, 6 + 1);
- if (plmn) {
- plmn[6] = '\0';
- if (tcore_sim_check_plmn_having_3digits_mnc(plmn))
- plmn_digits = 6;
- g_free(plmn);
- }
-
- /* Terminate string */
- imsi_raw[j] = '\0';
- memcpy(p_out->plmn, imsi_raw, plmn_digits);
- p_out->plmn[plmn_digits] = '\0';
- memcpy(p_out->msin, imsi_raw + plmn_digits, strlen(imsi_raw) - plmn_digits);
- p_out->msin[strlen(imsi_raw) - plmn_digits] = '\0';
-
- dbg("plmn in imsi = [%s]", p_out->plmn);
-
- return TRUE;
-}
-
-gboolean tcore_sim_decode_cdma_imsi(struct tel_sim_imsi *p_out, unsigned char *p_in, int in_length)
-{
- char imsi_raw[16] = {0, };
- int digits = 0;
- unsigned short mcc;
- unsigned char mnc;
- unsigned long min1;
- unsigned short min2;
- char *plmn = NULL;
- int plmn_digits = 5;
-
- if ((NULL == p_out) || (NULL == p_in))
- return FALSE;
-
- /*
- * According to 3GPP2 specification, the length of raw IMSI data is 10 bytes.
- * byte Description
- *-----------------------------------------------------------------
- * 1 Class assignment of IMSI_M
- * 2-3 IMSI_M_S2 : MSIN2
- * 4-6 IMSI_M_S1 : MSIN1
- * 7 IMSI_M_11_12 : MNC
- * 8 IMSI_M_ADDR_NUM : No of IMSI_M address digits.
- * 9-10 MCC_M : MCC
- */
- if ((in_length == 0) || (in_length == 0xff) || (4 > in_length) || (10 < in_length)) {
- dbg("No valid IMSI present to convert - length:[%x]", in_length);
- return FALSE;
- }
-
- /* Decode IMSI value from nibbles */
- mcc = (p_in[9] << 8) | p_in[8];
- mnc = p_in[6];
- min1 = (p_in[5] << 16) | (p_in[4] << 8) | (p_in[3]);
- min2 = (p_in[2] << 8) | p_in[1];
-
- digits = _decode_cdma_imsi_util(imsi_raw, &mcc, &mnc, &min1, &min2);
-
- if (digits < 0)
- return FALSE;
-
- /* Determine # of PLMN digits (5 or 6) */
- plmn = g_strndup(imsi_raw, 6 + 1);
- if (plmn) {
- plmn[6] = '\0';
- if (tcore_sim_check_plmn_having_3digits_mnc(plmn))
- plmn_digits = 6;
-
- g_free(plmn);
- }
-
- /* Terminate string */
- imsi_raw[digits] = '\0';
- memcpy(p_out->plmn, imsi_raw, plmn_digits);
- p_out->plmn[plmn_digits] = '\0';
- memcpy(p_out->msin, imsi_raw + plmn_digits, strlen(imsi_raw) - plmn_digits);
- p_out->msin[strlen(imsi_raw) - plmn_digits] = '\0';
-
- dbg("plmn in imsi = [%s]", p_out->plmn);
-
- return TRUE;
-}
-
-gboolean tcore_sim_decode_sst(struct tel_sim_sst *p_sst, unsigned char *p_in, int in_length)
-{
- unsigned char sstByte, rast, mask = 0;
- char simServiceID = 1; /* set "CHV1 disable function" */
- int i, svc_count;
- char *p_index;
-
- memset((void *)p_sst, 0, sizeof(struct tel_sim_sst));
-
- if (in_length == 0) {
- err("invalid length. return FALSE.");
- return FALSE;
- }
-
- /* get count of SIM service id. one byte has four service status. */
- svc_count = in_length * 4;
-
- /*
- * 3GPP 51.011 SST shows 56 kinds of service types.
- * current tel_sim_sst has also 56 elements
- */
- if (svc_count > SIM_SST_SERVICE_CNT_MAX) {
- warn("out of range[%d]. cut off the tail.", svc_count);
- svc_count = SIM_SST_SERVICE_CNT_MAX;
- }
-
- p_index = (char *)p_sst;
-
- for (i = 0; i < svc_count; i++) {
- sstByte = p_in[(simServiceID - 1) / 4];
- rast = simServiceID - 4 * (simServiceID / 4);
-
- switch (rast) {
- case 1:
- mask = 0x02;
- break;
-
- case 2:
- mask = 0x08;
- break;
-
- case 3:
- mask = 0x20;
- break;
-
- case 0:
- mask = 0x80;
- break;
-
- default:
- warn("invalid rast");
- break;
- }
-
- if (sstByte & mask)
- *p_index = 1;
- else
- *p_index = 0;
-
- p_index += sizeof(char);
- simServiceID++; /* next service id */
- }
-
- return TRUE;
-}
-
-gboolean tcore_sim_decode_cdma_st(struct tel_sim_cst *p_cdma_st, unsigned char *p_in, int in_length)
-{
- unsigned char sstByte, rast, mask = 0;
- char simServiceID = 1; /* set "CHV1 disable function" */
- int i, svc_count;
- char *p_index;
-
- memset((void *)p_cdma_st, 0, sizeof(struct tel_sim_cst));
-
- if (in_length == 0 || in_length > SIM_CDMA_ST_SERVICE_LEN_MAX)
- return FALSE;
-
- /* get count of SIM service id. one byte has four service status. */
- svc_count = in_length * 4;
-
- /*
- * CDMA_ST service is described to 47(1 byte includes 4 service status) in C.S0023 3.4.18.
- * Current tel_sim_cst.serivce.cdma_service has 47 services. so in_length should be under 12 byte.
- */
- if (svc_count > SIM_CDMA_ST_SERVICE_CNT_MAX)
- svc_count = SIM_CDMA_ST_SERVICE_CNT_MAX;
-
- p_cdma_st->cdma_svc_table = SIM_CDMA_SVC_TABLE;
-
- p_index = (char *)p_cdma_st->service.cdma_service;
-
- for (i = 0; i < svc_count; i++) {
- sstByte = p_in[(simServiceID - 1) / 4];
- rast = simServiceID - 4 * (simServiceID / 4);
-
- switch (rast) {
- case 1:
- mask = 0x02;
- break;
-
- case 2:
- mask = 0x08;
- break;
-
- case 3:
- mask = 0x20;
- break;
-
- case 0:
- mask = 0x80;
- break;
-
- default:
- warn("invalid rast");
- break;
- }
-
- if (sstByte & mask)
- *p_index = 1;
- else
- *p_index = 0;
-
- p_index += sizeof(char);
- simServiceID++; /* next service id */
- }
-
- return TRUE;
-}
-
-gboolean tcore_sim_decode_csim_st(struct tel_sim_cst *p_csim_st, unsigned char *p_in, int in_length)
-{
- int i, j;
- char mask;
- char *p_index;
- memset((void *) p_csim_st, 0, sizeof(struct tel_sim_cst));
-
- p_csim_st->cdma_svc_table = SIM_CSIM_SVC_TABLE;
- p_index = (char *)p_csim_st->service.csim_service;
-
- /*
- * CSIM_ST service is described to 41(1 byte includes 8 service status) in C.S0065 5.2.18.
- * Current tel_sim_cst.serivce.csim_service has 41 services. so in_length should be under 6 byte.
- */
- if (in_length > SIM_CSIM_ST_SERVICE_LEN_MAX)
- in_length = SIM_CSIM_ST_SERVICE_LEN_MAX;
-
- for (i = 0; i < in_length; i++) {
- mask = 0x01; /* reset mask to check first bit */
-
- for (j = 0; j < 8; j++) {
- if (p_in[i] & mask)
- *p_index = 1;
-
- p_index += sizeof(char);
- mask = mask << 1;
- }
- }
-
- return TRUE;
-}
-
-gboolean tcore_sim_decode_spn(struct tel_sim_spn *p_spn, unsigned char *p_in, int in_length)
-{
- int i;
-
- if (in_length == 0)
- return FALSE;
-
- p_spn->display_condition = p_in[0] & 0x3;
-
- for (i = 1; i < SIM_SPN_LEN_MAX + 1; i++) {
- if (p_in[i] == 0xFF)
- break; /* loop break*/
-
- p_spn->spn[i - 1] = p_in[i];
- }
-
- p_spn->spn[i-1] = '\0';
-
- dbg("spn:[%s] display condition : [%d]", p_spn->spn, p_spn->display_condition);
-
- return TRUE;
-}
-
-gboolean tcore_sim_decode_cdma_spn(struct tel_sim_spn *p_spn, unsigned char *p_in, int in_length)
-{
- int i = 0;
-
- if (in_length == 0)
- return FALSE;
-
- p_spn->display_condition = p_in[0] & 0x1;
-
- /*
- * Note : Character Encoding (1 byte) and Language Indicator (1 byte)
- * are ignored, will be added later if required by Application
- */
- for (i = 3; i < SIM_CDMA_SPN_LEN_MAX + 1; i++) {
- if (p_in[i] == 0xFF)
- break; /* loop break*/
-
- p_spn->spn[i - 3] = p_in[i];
- }
- p_spn->spn[i - 3] = '\0';
-
- dbg("spn:[%s] display condition : [%d]", p_spn->spn, p_spn->display_condition);
-
- return TRUE;
-}
-
-gboolean tcore_sim_decode_spdi(struct tel_sim_spdi *p_spdi, unsigned char *p_in, int in_length)
-{
- int i, Src_plmn_start_len, total_data_len;
-
- if (in_length == 0)
- return FALSE;
-
- if (p_in[0] == 0xff) {
- dbg("file is exist but there is no valid records");
-
- p_spdi->plmn_count = 0;
- memset(p_spdi->list, 0x00, sizeof(unsigned char)*7*SIM_SPDI_PLMN_MAX);
-
- return TRUE;
- }
-
- /* Display info tag('A3') */
- if (p_in[0] == 0xA3) {
- total_data_len = p_in[1];
- dbg("total_data_len=[%d]", total_data_len);
-
- /* PLMN list tag('80') */
- if (p_in[2] == 0x80) {
- p_spdi->plmn_count = p_in[3] / 3;
-
- /*
- * plmn tag 1byte
- * length 1byte
- * each plmn entry 3byte
- */
- if (p_spdi->plmn_count > SIM_SPDI_PLMN_MAX)
- p_spdi->plmn_count = SIM_SPDI_PLMN_MAX;
-
- Src_plmn_start_len = 4;
-
- dbg("p_spdi->num_of_plmn_entries[%d]", p_spdi->plmn_count);
-
- for (i = 0; i < p_spdi->plmn_count; i++) {
- _decode_plmn(&p_in[Src_plmn_start_len], p_spdi->list[i].plmn);
- dbg("SPDI PLMN[%d][%s]", i, p_spdi->list[i].plmn);
-
- Src_plmn_start_len = Src_plmn_start_len + 3;
- }
-
- return TRUE;
- }
-
- dbg("Current EF-SPDI has invalid data");
- return FALSE;
- }
-
- dbg("Current EF-SPDI has invalid data");
- return FALSE;
-}
-
-gboolean tcore_sim_decode_msisdn(struct tel_sim_msisdn *p_msisdn, unsigned char *p_in, int in_length)
-{
- int X = 0; /* alpha id max length */
- int alpha_id_length = 0;
- int value_length = 0;
- int bcd_byte = 0; /* dialing number max length */
-
- memset((void *) p_msisdn, 0, sizeof(struct tel_sim_msisdn));
-
- if (in_length < 14) {
- err("invalid in_length[%d]", in_length);
- return FALSE;
- }
-
- if (_is_empty(p_in, in_length) == TRUE) {
- memset(p_msisdn, 0, sizeof(struct tel_sim_msisdn));
- return FALSE;
- }
-
- X = in_length - 14; /* get alpha id max length */
-
- if (X != 0) {
- alpha_id_length = X;
- dbg("alpha_id_length[%d]", alpha_id_length);
- if (alpha_id_length > SIM_XDN_ALPHA_ID_LEN_MAX)
- alpha_id_length = SIM_XDN_ALPHA_ID_LEN_MAX;
-
- value_length = _get_string((unsigned char *)p_msisdn->name, p_in, alpha_id_length);
- p_msisdn->name[value_length] = '\0';
- }
-
- /* get dialing number length */
- /* p_in[X] is BCD length of dialing number length plus TON/NPI 1 bytes. */
- /* Convert to digit length and subtract TON/NPI length. */
- if (p_in[X] != 0xFF) {
- dbg("Dialing number Length %d, BCD length 0x%x ", (p_in[X] - 1) * 2, p_in[X]);
-
- /* get TON and NPI */
- p_msisdn->ton = (p_in[X + 1] >> 4) & 0x07;
-
- /* get actual dialing number length */
- bcd_byte = _get_valid_bcd_byte(&p_in[X + 2], SIM_XDN_NUMBER_LEN_MAX / 2);
- dbg("bcd_byte[%x]", bcd_byte);
-
- /* get dialing number/SSC string */
- value_length = _bcd_to_digit((char *)p_msisdn->num, (char *) &p_in[X + 2], bcd_byte); /* actual dialing number length in BCD. */
- p_msisdn->num[value_length] = '\0';
- p_msisdn->next_record = p_in[X+13];
- dbg("p_msisdn->num[%s]", p_msisdn->num);
- }
-
- return TRUE;
-}
-
-gboolean tcore_sim_decode_mdn(struct tel_sim_msisdn *p_msisdn, unsigned char *p_in, int in_length)
-{
- int value_length = 0;
- int bcd_byte = 0; /* dialing number max length */
-
- memset((void *)p_msisdn, 0, sizeof(struct tel_sim_msisdn));
-
- if (in_length == 0)
- return FALSE;
-
- if (_is_empty(p_in, in_length) == TRUE)
- return FALSE;
-
- /* Note : Alpha identifier is not present in EF-MDN file. */
- if (p_in[0] != 0xFF) {
- dbg("Dialing number Length %d, BCD length 0x%x ", (p_in[0] - 1) * 2, p_in[0]);
-
- /* get TON and NPI */
- p_msisdn->ton = (p_in[9] >> 4) & 0x07;
-
- /* get actual dialing number length */
- bcd_byte = _get_valid_bcd_byte(&p_in[1], 8);
- dbg("bcd_byte[%x]", bcd_byte);
-
- /* get dialing number/SSC string */
- value_length = _bcd_to_digit((char *) p_msisdn->num, (char *) &p_in[1], bcd_byte); /* actual dialing number length in BCD. */
- p_msisdn->num[value_length] = '\0';
-
- /*p_msisdn->next_record = p_in[];*/ /* Need to check with next_record field */
- dbg("p_msisdn->num[%s]", p_msisdn->num);
- }
-
- return TRUE;
-}
-
-gboolean tcore_sim_decode_xdn(struct tel_sim_dialing_number *p_xdn, unsigned char *p_in, int in_length)
-{
- int X; /* alpha id max length */
- int bcd_byte; /* dialing number max length */
-
- memset((void *)p_xdn, 0, sizeof(struct tel_sim_dialing_number));
-
- if (in_length == 0)
- return FALSE;
-
- if (_is_empty(p_in, in_length) == TRUE)
- return FALSE; /* this is empty record */
-
- X = in_length - 14; /* get alpha id max length */
-
- if (X != 0) {
- _get_string((unsigned char *)p_xdn->alpha_id, p_in, X);
- p_xdn->alpha_id_max_len = X;
- }
-
- /* get dialing number length */
- /* p_in[X] is BCD length of dialing number length plus TON/NPI 1 bytes. */
- /* Convert to digit length and subtract TON/NPI length. */
- if (p_in[X] != 0xFF) {
- dbg("Dialing number Length %d, BCD length 0x%x ",
- (p_in[X] - 1) * 2, p_in[X]);
-
- /*
- if (p_xdn->num_max_len > SIM_XDN_NUMBER_LEN_MAX) {
-
- this may be broken record.
- p_xdn->b_used = FALSE;
- memset((void *)p_xdn, 0, sizeof(tapi_sim_dialing_number_info_t));
- return FALSE;
-
- ADN record cannot have more than 20 digits. Anyway we can restrict this as per 31.102
- X+1 Length of BCD number/SSC contents M 1 byte
- X+2 TON and NPI M 1 byte
- X+3 to X+12 Dialing Number/SSC String M 10 bytes
- X+13 Capability/Configuration1 Identifier M 1 byte
- X+14 Extension1 Record Identifier M 1 byte
-
- Anyway we are doing this check @
- bcd_byte = _get_valid_bcd_byte (&p_in[X+2], TAPI_SIM_XDN_DIALING_NUMBER_LEN/2);
- by using the 20/2; so don`t return false.
-
- if (p_in[X] == 0x00)
- p_xdn->num_max_len = 0;
- else
- p_xdn->num_max_len = SIM_XDN_NUMBER_LEN_MAX;
- }
- */
-
- /* get TON and NPI */
- p_xdn->ton = (p_in[X + 1] >> 4) & 0x07;
- p_xdn->npi = p_in[X + 1] & 0x0F;
-
- /* get actual dialing number length */
- bcd_byte = _get_valid_bcd_byte(&p_in[X + 2], SIM_XDN_NUMBER_LEN_MAX / 2);
- dbg("bcd_byte[%x]", bcd_byte);
-
- /* get dialing number/SSC string */
- _bcd_to_digit((char *) p_xdn->num, (char *) &p_in[X + 2], bcd_byte); /* actual dialing number length in BCD. */
- dbg("p_xdn->DiallingNum[%s]", p_xdn->num);
-
- /* get Capability/Configuration id */
- p_xdn->cc_id = p_in[X + 12];
-
- /* get Extension1 id */
- p_xdn->ext1_id = p_in[X + 13];
- }
- return TRUE;
-}
-
-char *tcore_sim_encode_xdn(int in_length, struct tel_sim_dialing_number *p_xdn)
-{
- int alpha_id_space = 0, digit_len = 0, str_len = 0;
- char bcdCode[SIM_XDN_NUMBER_LEN_MAX / 2];
- char *p_out = NULL;
-
- if (in_length < 14) {
- dbg("in_length[%d] should be greater than or equal to 14.", in_length);
- return NULL;
- }
-
- p_out = calloc(1, in_length + 1);
- if (!p_out)
- return NULL;
-
- memset((void *)p_out, 0xFF, in_length);
-
- /* get alpha id max length */
- alpha_id_space = in_length - 14;
-
- /* alpha id is too big */
- str_len = strlen(p_xdn->alpha_id);
- if (alpha_id_space < str_len) {
- dbg("SIM space for alpha_id is [%d] but input alpha_id length is [%d]. so we will use [%d] byte",
- alpha_id_space, str_len, alpha_id_space);
- str_len = alpha_id_space;
- }
-
- digit_len = strlen(p_xdn->num);
- /* this is digit length */
- if (digit_len > SIM_XDN_NUMBER_LEN_MAX) {
- dbg("SIM space for number is [%d] but input number length is [%d]. so we will use [%d] byte",
- SIM_XDN_NUMBER_LEN_MAX, digit_len, SIM_XDN_NUMBER_LEN_MAX);
- digit_len = SIM_XDN_NUMBER_LEN_MAX;
- }
-
- _set_string((unsigned char *)p_out, (unsigned char *)p_xdn->alpha_id, str_len);
-
- /* set length of BCD number/SSC contents */
- /* p_xdn->diallingnumLen is maximum digit length. = 20 bytes. */
- /* convert to BCD length and add 1 byte. */
- p_out[alpha_id_space] = ((digit_len + 1) / 2) + 1;
-
- /* set TON and NPI */
- p_out[alpha_id_space + 1] = 0x80;
- p_out[alpha_id_space + 1] |= (p_xdn->ton & 0x07) << 4;
- p_out[alpha_id_space + 1] |= p_xdn->npi & 0x0F;
-
- /* set dialing number/SSC string */
- memset((void *) bcdCode, 0xFF, SIM_XDN_NUMBER_LEN_MAX / 2);
-
- _digit_to_bcd((char *)bcdCode, (char *)p_xdn->num, digit_len);
-
- memcpy((void *)&p_out[alpha_id_space + 2], bcdCode, SIM_XDN_NUMBER_LEN_MAX / 2);
-
- /* set Capability/Configuration Identifier */
- if (p_xdn->cc_id == 0x00)
- p_out[alpha_id_space + 12] = 0xff;
- else
- p_out[alpha_id_space + 12] = (unsigned char)p_xdn->cc_id;
-
- /* set extension1 record Identifier */
- if (p_xdn->ext1_id == 0x00)
- p_out[alpha_id_space + 13] = 0xff;
- else
- p_out[alpha_id_space + 13] = (unsigned char)p_xdn->ext1_id;
-
- return p_out;
-}
-
-gboolean tcore_sim_decode_ecc(struct tel_sim_ecc_list *p_ecc, unsigned char *p_in, int in_length)
-{
- int bcd_byte; /* dialing number max length */
- int i;
- int valid_ecc_length;
-
- memset((void *)p_ecc, 0x00, sizeof(struct tel_sim_ecc_list));
-
- if (in_length % 3 != 0) {
- dbg("error - invalid data length");
- return FALSE;
- }
-
- for (i = 0; i < in_length / 3; i++) {
- /* get the BCD length of the ECC */
- bcd_byte = _get_valid_bcd_byte((unsigned char *) p_in+(i*3), 3);
- if (bcd_byte != 0) {
- valid_ecc_length = _bcd_to_digit(p_ecc->ecc[p_ecc->ecc_count].ecc_num, (char *)p_in+(i*3), bcd_byte);
- p_ecc->ecc[p_ecc->ecc_count].ecc_num[valid_ecc_length] = '\0';
- p_ecc->ecc_count++;
- }
- }
-
- return TRUE;
-}
-
-gboolean tcore_sim_decode_ext(struct tel_sim_ext *p_ext, unsigned char *p_in, int in_length)
-{
- int bcd_byte; /* dialing number max length */
- gboolean res = FALSE;
-
- memset((void *)p_ext, 0x00, sizeof(struct tel_sim_ext));
-
- if (*p_in & 0x01) {
- dbg("Record type - Called Party Subaddress - NOT SUPPORTED");
- } else if (*p_in & 0x02) {
- dbg("Record type - Additional data");
- bcd_byte = _get_valid_bcd_byte(&p_in[2], SIM_XDN_NUMBER_LEN_MAX / 2);
- p_ext->ext_len = _bcd_to_digit((char *) p_ext->ext, (char *) &p_in[2], bcd_byte); /* actual dialing number length in BCD. */
- p_ext->next_record = p_in[12];
- dbg("Dialing number Length[%d]", p_ext->ext_len);
- res = TRUE;
- } else {
- dbg("Record type - Invalid");
- }
-
- return res;
-}
-
-gboolean tcore_sim_decode_ust(struct tel_sim_ust *p_ust, unsigned char *p_in, int in_length)
-{
- int i, j;
- char mask;
- char *p_index;
-
- memset((void *)p_ust, 0, sizeof(struct tel_sim_ust));
- p_index = (char *)p_ust;
-
- if (in_length == 0) {
- err("invalid length. return FALSE.");
- return FALSE;
- }
-
- /*
- * UST service is described to 74(1 byte includes 8 service status) in 31.102 r7.
- * current sim_ust_s has 64 services. so in_length should be under 8 byte.
- */
- if (in_length > (SIM_UST_SERVICE_CNT_MAX / 8)) {
- warn("out of range[%d]. cut off the tail.", in_length);
- in_length = SIM_SST_SERVICE_CNT_MAX / 8;
- }
-
- for (i = 0; i < in_length; i++) {
- mask = 0x01; /* reset mast to check first bit */
-
- for (j = 0; j < 8; j++) {
- if (p_in[i] & mask)
- *p_index = 1;
-
- p_index += sizeof(char);
- mask = mask << 1;
- }
- }
-
- return TRUE;
-}
-
-gboolean tcore_sim_decode_ist(struct tel_sim_ist *p_ist, unsigned char *p_in, int in_length)
-{
- int i, j;
- char mask;
- char *p_index;
-
- memset((void *)p_ist, 0, sizeof(struct tel_sim_ist));
- p_index = (char *)p_ist;
-
- /*
- * IST service is described to 11(1 byte includes 8 service status) in 31.103 release12.
- * current tel_sim_ist_service has 11 services. so in_length should be under 2 byte.
- */
- if (in_length > SIM_IST_BYTE_LEN_MAX)
- in_length = SIM_IST_BYTE_LEN_MAX;
-
- for (i = 0; i < in_length; i++) {
- mask = 0x01; /* reset mast to check first bit */
-
- for (j = 0; j < 8; j++) {
- if (p_in[i] & mask)
- *p_index = 1;
-
- p_index += sizeof(char);
- mask = mask << 1;
- }
- }
-
- return TRUE;
-}
-
-gboolean tcore_sim_decode_est(struct tel_sim_est *p_est, unsigned char *p_in, int in_length)
-{
- memset((void *)p_est, 0, sizeof(struct tel_sim_est));
-
- if (*p_in & 0x01)
- p_est->bFdnEnabled = TRUE;
-
- if (*p_in & 0x02)
- p_est->bBdnEnabled = TRUE;
-
- if (*p_in & 0x04)
- p_est->bAclEnabled = TRUE;
-
- return TRUE;
-}
-
-gboolean tcore_sim_decode_uecc(struct tel_sim_ecc *p_ecc, unsigned char *p_in, int in_length)
-{
- int bcd_byte; /* dialing number max length */
- unsigned char eccServiceCategory;
-
- if (_is_empty(p_in, in_length) == TRUE) {
- memset(p_ecc, 0, sizeof(struct tel_sim_ecc));
- return FALSE;
- }
-
- /* get the BCD length of the ECC */
- bcd_byte = _get_valid_bcd_byte(&p_in[0], SIM_ECC_BYTE_LEN_MAX);
-
- /* get the ECC codes in digits and the length as well */
- _bcd_to_digit((char *) p_ecc->ecc_num, (char *)&p_in[0], bcd_byte);
-
- /* get the alpha identifier of ECC */
- _get_string((unsigned char *) p_ecc->ecc_string, (unsigned char *)&p_in[3], in_length - 3);
-
- eccServiceCategory = p_in[in_length - 1];
-
- /*
- * Assign the service category
- * 3GPP TS24.008 Emergency Service Category Value.
- * Bit 8, 7, 6 are spare, 5~1 bit is used.
- * The meaning of the Emergency Category Value is derived from the following settings
- * (see 3GPP TS 22.101 clause 10):
- * Bit 1 Police 0x01
- * Bit 2 Ambulance 0x02
- * Bit 3 Fire Brigade 0x04
- * Bit 4 Marine Guard 0x08
- * Bit 5 Mountain Rescue 0x10
- * Bit 6 manually initiated eCall
- * Bit 7 automatically initiated eCall
- * Bit 8 is spare and set to "0"
- */
-
- if (eccServiceCategory == 0xFF) /* if category vaule is unused (unchecked) then just return 0xff */
- p_ecc->ecc_category = eccServiceCategory;
- else
- p_ecc->ecc_category = eccServiceCategory & 0x1F; /* Check for the first 5 bits */
-
- return TRUE;
-}
-
-gboolean tcore_sim_decode_gid(struct tel_sim_gid *p_gid, unsigned char *p_in, int in_length)
-{
- int i;
-
- memset((void *) p_gid, 0, sizeof(struct tel_sim_gid));
-
- if (in_length == 0)
- return FALSE;
-
- /* regarding 31.102, EF-GID data byte is not defined. currently 10. */
- if (in_length >= SIM_GROUP_IDENTIFIER_LEN_MAX)
- in_length = SIM_GROUP_IDENTIFIER_LEN_MAX;
-
- for (i = 0; i < in_length; i++) {
- if (p_in[i] == 0xFF)
- break;
-
- p_gid->szGroupIdentifier[i] = p_in[i];
- p_gid->GroupIdentifierLen++;
- }
-
- return TRUE;
-}
-
-gboolean tcore_sim_decode_mbi(struct tel_sim_mbi *p_mbi, unsigned char *p_in, int in_length)
-{
- /* EF-MBI is defined 4 mandatory, 1 optional byte in 31.102 */
- if (in_length == 0 || in_length > SIM_MAIL_BOX_IDENTIFIER_LEN_MAX)
- return FALSE;
-
- if (_is_empty(p_in, in_length) == TRUE)
- return FALSE; /* this is empty record */
-
- p_mbi->voice_index = p_in[0];
- p_mbi->fax_index = p_in[1];
- p_mbi->email_index = p_in[2];
- p_mbi->other_index = p_in[3];
-
- /* 5th byte is optional */
- if (in_length == 5)
- p_mbi->video_index = p_in[4];
-
- return TRUE;
-}
-
-char *tcore_sim_encode_mbi(const struct tel_sim_mbi *p_mbi, int in_length)
-{
- char *p_out = NULL;
-
- if (in_length < 4) {
- dbg("in_length[%d] should be greater than or equal to 4.", in_length);
- return NULL;
- }
-
- p_out = calloc(1, in_length);
- if (!p_out)
- return NULL;
-
- p_out[0] = p_mbi->voice_index;
- p_out[1] = p_mbi->fax_index;
- p_out[2] = p_mbi->email_index;
- p_out[3] = p_mbi->other_index;
-
- if (in_length == 5)
- p_out[4] = p_mbi->video_index;
-
- return p_out;
-}
-
-gboolean tcore_sim_decode_cff(struct tel_sim_cphs_cf *p_cff, unsigned char *p_in, int in_length)
-{
- if (in_length == 0)
- return FALSE;
-
- dbg("flag(0)=%x, packetlen=%d ", (unsigned int)p_in[0], in_length);
- dbg("flag(1)=%x", p_in[1]);
-
- if ((p_in[0] & 0x0F) == 0x0A)
- p_cff->b_line1 = TRUE;
-
- if ((p_in[0] & 0xF0) == 0xA0)
- p_cff->b_line2 = TRUE;
-
- if (in_length > 1) {
- if ((p_in[1] & 0x0F) == 0x0A)
- p_cff->b_fax = TRUE;
-
- if ((p_in[1] & 0xF0) == 0xA0)
- p_cff->b_data = TRUE;
- }
-
- dbg("Line1 = %d, line2 = %d, Fax = %d, Data = %d ",
- p_cff->b_line1,
- p_cff->b_line2,
- p_cff->b_fax,
- p_cff->b_data);
- return TRUE;
-}
-
-char *tcore_sim_encode_cff(const struct tel_sim_cphs_cf *cff, int in_length)
-{
- int i, j = 0;
- char *p_out = NULL;
- unsigned char *pTemp = (unsigned char *) cff;
- unsigned char present = 0x0A;
- unsigned char absent = 0x05;
-
- if (in_length < SIM_CPHS_CALL_FORWARDING_LEN_MIN) {
- err("in_length[%d] is smaller than SIM_CPHS_CALL_FORWARDING_LEN_MIN[%d]",
- in_length, SIM_CPHS_CALL_FORWARDING_LEN_MIN);
- return NULL;
- }
-
- p_out = calloc(1, SIM_CPHS_CALL_FORWARDING_LEN_MIN+1);
- if (!p_out)
- return NULL;
-
- for (i = 0; i < SIM_CPHS_CALL_FORWARDING_LEN_MIN; i++) {
- present = 0x0A;
- absent = 0x05;
-
- for (j = 0; j < 2; j++) {
- if (*pTemp)
- p_out[i] = p_out[i] | present;
- else
- p_out[i] = p_out[i] | absent;
-
- pTemp += sizeof(gboolean);
- present = present << 4;
- absent = absent << 4;
- }
- }
-
- p_out[SIM_CPHS_CALL_FORWARDING_LEN_MIN] = '\0';
- return p_out;
-}
-
-gboolean tcore_sim_decode_csp(struct tel_sim_cphs_csp *p_csp, unsigned char *p_in, int in_length)
-{
- int i, j, k = 0;
- unsigned char byteSignificance = 0x00;
- unsigned char mask = 0x80;
-
- if (in_length == 0)
- return FALSE;
-
- memset((void *) p_csp, 0, sizeof(struct tel_sim_cphs_csp));
-
- /* current telephony supports 22 byte cphs-csp data. 18 byte is mandatory, the other is optional. */
- for (i = 0, j = 0; i < SIM_CPHS_CSP_LEN_MAX && j < SIM_CPHS_CSP_ENTRY_CNT_MAX; i++, j++) {
- p_csp->service_profile_entry[j].customer_service_group = (enum tel_sim_cphs_csp_group) p_in[i];
- byteSignificance = p_in[++i];
- mask = 0x80;
-
- switch (p_csp->service_profile_entry[j].customer_service_group) {
- case 0x01:
- for (k = 0; k < 5; k++) {
- switch (byteSignificance & mask) {
- case 0x80:
- p_csp->service_profile_entry[j].service.call_offering.b_call_forwarding_unconditional = TRUE;
- break;
-
- case 0x40:
- p_csp->service_profile_entry[j].service.call_offering.b_call_forwarding_on_user_busy = TRUE;
- break;
-
- case 0x20:
- p_csp->service_profile_entry[j].service.call_offering.b_call_forwarding_on_no_reply = TRUE;
- break;
-
- case 0x10:
- p_csp->service_profile_entry[j].service.call_offering.b_call_forwarding_on_user_not_reachable = TRUE;
- break;
-
- case 0x08:
- p_csp->service_profile_entry[j].service.call_offering.b_call_transfer = TRUE;
- break;
-
- default:
- break;
- }
- mask = mask >> 1;
- }
- break;
-
- case 0x02:
- for (k = 0; k < 5; k++) {
- switch (byteSignificance & mask) {
- case 0x80:
- p_csp->service_profile_entry[j].service.call_restriction.b_barring_of_all_outgoing_calls = TRUE;
- break;
-
- case 0x40:
- p_csp->service_profile_entry[j].service.call_restriction.b_barring_of_outgoing_international_calls = TRUE;
- break;
-
- case 0x20:
- p_csp->service_profile_entry[j].service.call_restriction.b_barring_of_outgoing_international_calls_except_hplmn = TRUE;
- break;
-
- case 0x10:
- p_csp->service_profile_entry[j].service.call_restriction.b_barring_of_all_incoming_calls_roaming_outside_hplmn = TRUE;
- break;
-
- case 0x08:
- p_csp->service_profile_entry[j].service.call_restriction.b_barring_of_incoming_calls_when_roaming = TRUE;
- break;
-
- default:
- break;
- }
- mask = mask >> 1;
- }
- break;
-
- case 0x03:
- for (k = 0; k < 5; k++) {
- switch (byteSignificance & mask) {
- case 0x80:
- p_csp->service_profile_entry[j].service.other_supp_services.b_multi_party_service = TRUE;
- break;
-
- case 0x40:
- p_csp->service_profile_entry[j].service.other_supp_services.b_closed_user_group = TRUE;
- break;
-
- case 0x20:
- p_csp->service_profile_entry[j].service.other_supp_services.b_advice_of_charge = TRUE;
- break;
-
- case 0x10:
- p_csp->service_profile_entry[j].service.other_supp_services.b_preferential_closed_user_group = TRUE;
- break;
-
- case 0x08:
- p_csp->service_profile_entry[j].service.other_supp_services.b_closed_user_group_outgoing_access = TRUE;
- break;
-
- default:
- break;
- }
- mask = mask >> 1;
- }
- break;
-
- case 0x04:
- for (k = 0; k < 4; k++) {
- switch (byteSignificance & mask) {
- case 0x80:
- p_csp->service_profile_entry[j].service.call_complete.b_call_hold = TRUE;
- break;
-
- case 0x40:
- p_csp->service_profile_entry[j].service.call_complete.b_call_waiting = TRUE;
- break;
-
- case 0x20:
- p_csp->service_profile_entry[j].service.call_complete.b_completion_of_call_to_busy_subscriber = TRUE;
- break;
-
- case 0x10:
- p_csp->service_profile_entry[j].service.call_complete.b_user_user_signalling = TRUE;
- break;
-
- default:
- break;
- }
- mask = mask >> 1;
- }
- break;
-
- case 0x05:
- for (k = 0; k < 7; k++) {
- switch (byteSignificance & mask) {
- case 0x80:
- p_csp->service_profile_entry[j].service.teleservices.b_short_message_mobile_terminated = TRUE;
- break;
-
- case 0x40:
- p_csp->service_profile_entry[j].service.teleservices.b_short_message_mobile_originated = TRUE;
- break;
-
- case 0x20:
- p_csp->service_profile_entry[j].service.teleservices.b_short_message_cell_broadcast = TRUE;
- break;
-
- case 0x10:
- p_csp->service_profile_entry[j].service.teleservices.b_short_message_reply_path = TRUE;
- break;
-
- case 0x08:
- p_csp->service_profile_entry[j].service.teleservices.b_short_message_delivery_conf = TRUE;
- break;
-
- case 0x04:
- p_csp->service_profile_entry[j].service.teleservices.b_short_message_protocol_identifier = TRUE;
- break;
-
- case 0x02:
- p_csp->service_profile_entry[j].service.teleservices.b_short_message_validity_period = TRUE;
- break;
-
- default:
- break;
- }
- mask = mask >> 1;
- }
- break;
-
- case 0x06:
- for (k = 0; k < 1; k++) {
- switch (byteSignificance & mask) {
- case 0x80:
- p_csp->service_profile_entry[j].service.cphs_teleservices.b_alternative_line_service = TRUE;
- break;
-
- default:
- break;
- }
- mask = mask >> 1;
- }
- break;
-
- case 0x07:
- for (k = 0; k < 1; k++) {
- switch (byteSignificance & mask) {
- case 0x80:
- p_csp->service_profile_entry[j].service.cphs_features.b_string_service_table = TRUE;
- break;
-
- default:
- break;
- }
- mask = mask >> 1;
- }
- break;
-
- case 0x08:
- for (k = 0; k < 8; k++) {
- switch (byteSignificance & mask) {
- case 0x80:
- p_csp->service_profile_entry[j].service.number_identifiers.b_calling_line_identification_present = TRUE;
- break;
-
- case 0x20:
- p_csp->service_profile_entry[j].service.number_identifiers.b_connected_line_identification_restrict = TRUE;
- break;
-
- case 0x10:
- p_csp->service_profile_entry[j].service.number_identifiers.b_connected_line_identification_present = TRUE;
- break;
-
- case 0x08:
- p_csp->service_profile_entry[j].service.number_identifiers.b_malicious_call_identifier = TRUE;
- break;
-
- case 0x02:
- p_csp->service_profile_entry[j].service.number_identifiers.b_calling_line_identification_send = TRUE;
- break;
-
- case 0x01:
- p_csp->service_profile_entry[j].service.number_identifiers.b_calling_line_identification_block = TRUE;
- break;
-
- default:
- break;
- }
- mask = mask >> 1;
- }
- break;
-
- case 0x09:
- for (k = 0; k < 6; k++) {
- switch (byteSignificance & mask) {
- case 0x80:
- p_csp->service_profile_entry[j].service.phase_services.b_menu_for_gprs = TRUE;
- break;
-
- case 0x40:
- p_csp->service_profile_entry[j].service.phase_services.b_menu_for_high_speed_csd = TRUE;
- break;
-
- case 0x20:
- p_csp->service_profile_entry[j].service.phase_services.b_menu_for_voice_group_call = TRUE;
- break;
-
- case 0x10:
- p_csp->service_profile_entry[j].service.phase_services.b_menu_for_voice_broadcast_service = TRUE;
- break;
-
- case 0x08:
- p_csp->service_profile_entry[j].service.phase_services.b_menu_for_multiple_subscriber_profile = TRUE;
- break;
-
- case 0x04:
- p_csp->service_profile_entry[j].service.phase_services.b_menu_for_multiple_band = TRUE;
- break;
-
- default:
- break;
- }
- mask = mask >> 1;
- }
- break;
-
- case 0xC0:
- for (k = 0; k < 8; k++) {
- switch (byteSignificance & mask) {
- case 0x80:
- p_csp->service_profile_entry[j].service.value_added_services.b_restrict_menu_for_manual_selection = TRUE;
- break;
-
- case 0x40:
- p_csp->service_profile_entry[j].service.value_added_services.b_restrict_menu_for_voice_mail = TRUE;
- break;
-
- case 0x20:
- p_csp->service_profile_entry[j].service.value_added_services.b_restrict_menu_for_mo_sms_and_paging = TRUE;
- break;
-
- case 0x10:
- p_csp->service_profile_entry[j].service.value_added_services.b_restrict_menu_for_mo_sms_with_emial_type = TRUE;
- break;
-
- case 0x08:
- p_csp->service_profile_entry[j].service.value_added_services.b_restrict_menu_for_fax_calls = TRUE;
- break;
-
- case 0x04:
- p_csp->service_profile_entry[j].service.value_added_services.b_restrict_menu_for_data_calls = TRUE;
- break;
-
- case 0x01:
- p_csp->service_profile_entry[j].service.value_added_services.b_restrict_menu_for_change_language = TRUE;
- break;
-
- default:
- break;
- }
- mask = mask >> 1;
- }
- break;
-
- case 0xD5:
- for (k = 0; k < 8; k++) {
- switch (byteSignificance & mask) {
- case 0x80:
- case 0x40:
- case 0x20:
- case 0x10:
- case 0x08:
- case 0x04:
- case 0x02:
- case 0x01:
- p_csp->service_profile_entry[j].service.information_numbers.b_information_numbers = TRUE;
- break;
-
- default:
- break;
- }
- mask = mask >> 1;
- }
- break;
-
- default:
- break;
- }
- }
- return TRUE;
-}
-
-gboolean tcore_sim_encode_csp(unsigned char *p_out, int out_length, struct tel_sim_cphs_csp *p_csp)
-{
- unsigned char i, j = 0;
-
- if (out_length == 0)
- return FALSE;
-
- memset((void *) p_out, 0xFF, out_length);
-
- /*
- * current telephony supports 22 byte cphs-csp data.
- * 18 byte is mandatory, the other is optional.
- */
- for (i = 0, j = 0;
- i < SIM_CPHS_CSP_LEN_MAX && j < SIM_CPHS_CSP_ENTRY_CNT_MAX;
- i++, j++) {
- p_out[i] = (unsigned char) p_csp->service_profile_entry[j].customer_service_group;
- switch (p_out[i]) {
- case 0x01:
- p_out[++i] = (((unsigned char) p_csp->service_profile_entry[j].service.call_offering.b_call_forwarding_unconditional) << 7)
- + (((unsigned char) p_csp->service_profile_entry[j].service.call_offering.b_call_forwarding_on_user_busy) << 6)
- + (((unsigned char) p_csp->service_profile_entry[j].service.call_offering.b_call_forwarding_on_no_reply) << 5)
- + (((unsigned char) p_csp->service_profile_entry[j].service.call_offering.b_call_forwarding_on_user_not_reachable) << 4)
- + (((unsigned char) p_csp->service_profile_entry[j].service.call_offering.b_call_transfer) << 3);
- break;
-
- case 0x02:
- p_out[++i] = (((unsigned char) p_csp->service_profile_entry[j].service.call_restriction.b_barring_of_all_outgoing_calls) << 7)
- + (((unsigned char) p_csp->service_profile_entry[j].service.call_restriction.b_barring_of_outgoing_international_calls) << 6)
- + (((unsigned char) p_csp->service_profile_entry[j].service.call_restriction.b_barring_of_outgoing_international_calls_except_hplmn) << 5)
- + (((unsigned char) p_csp->service_profile_entry[j].service.call_restriction.b_barring_of_all_incoming_calls_roaming_outside_hplmn) << 4)
- + (((unsigned char) p_csp->service_profile_entry[j].service.call_restriction.b_barring_of_incoming_calls_when_roaming) << 3);
- break;
-
- case 0x03:
- p_out[++i] = (((unsigned char) p_csp->service_profile_entry[j].service.other_supp_services.b_multi_party_service) << 7)
- + (((unsigned char) p_csp->service_profile_entry[j].service.other_supp_services.b_closed_user_group) << 6)
- + (((unsigned char) p_csp->service_profile_entry[j].service.other_supp_services.b_advice_of_charge) << 5)
- + (((unsigned char) p_csp->service_profile_entry[j].service.other_supp_services.b_preferential_closed_user_group) << 4)
- + (((unsigned char) p_csp->service_profile_entry[j].service.other_supp_services.b_closed_user_group_outgoing_access) << 3);
- break;
-
- case 0x04:
- p_out[++i] = (((unsigned char) p_csp->service_profile_entry[j].service.call_complete.b_call_hold) << 7)
- + (((unsigned char) p_csp->service_profile_entry[j].service.call_complete.b_call_waiting) << 6)
- + (((unsigned char) p_csp->service_profile_entry[j].service.call_complete.b_completion_of_call_to_busy_subscriber) << 5)
- + (((unsigned char) p_csp->service_profile_entry[j].service.call_complete.b_user_user_signalling) << 4);
- break;
-
- case 0x05:
- p_out[++i] = (((unsigned char) p_csp->service_profile_entry[j].service.teleservices.b_short_message_mobile_terminated) << 7)
- + (((unsigned char) p_csp->service_profile_entry[j].service.teleservices.b_short_message_mobile_originated) << 6)
- + (((unsigned char) p_csp->service_profile_entry[j].service.teleservices.b_short_message_cell_broadcast) << 5)
- + (((unsigned char) p_csp->service_profile_entry[j].service.teleservices.b_short_message_reply_path) << 4)
- + (((unsigned char) p_csp->service_profile_entry[j].service.teleservices.b_short_message_delivery_conf) << 3)
- + (((unsigned char) p_csp->service_profile_entry[j].service.teleservices.b_short_message_protocol_identifier) << 2)
- + (((unsigned char) p_csp->service_profile_entry[j].service.teleservices.b_short_message_validity_period) << 1);
- break;
-
- case 0x06:
- p_out[++i] = (((unsigned char) p_csp->service_profile_entry[j].service.cphs_teleservices.b_alternative_line_service) << 7);
- break;
-
- case 0x07:
- p_out[++i] = (((unsigned char) p_csp->service_profile_entry[j].service.cphs_features.b_string_service_table) << 7);
- break;
-
- case 0x08:
- p_out[++i] = (((unsigned char) p_csp->service_profile_entry[j].service.number_identifiers.b_calling_line_identification_present) << 7)
- + (((unsigned char) p_csp->service_profile_entry[j].service.number_identifiers.b_connected_line_identification_restrict) << 5)
- + (((unsigned char) p_csp->service_profile_entry[j].service.number_identifiers.b_connected_line_identification_present) << 4)
- + (((unsigned char) p_csp->service_profile_entry[j].service.number_identifiers.b_malicious_call_identifier) << 3)
- + (((unsigned char) p_csp->service_profile_entry[j].service.number_identifiers.b_calling_line_identification_send) << 1)
- + ((unsigned char) p_csp->service_profile_entry[j].service.number_identifiers.b_calling_line_identification_block);
- break;
-
- case 0x09:
- p_out[++i] = (((unsigned char) p_csp->service_profile_entry[j].service.phase_services.b_menu_for_gprs) << 7)
- + (((unsigned char) p_csp->service_profile_entry[j].service.phase_services.b_menu_for_high_speed_csd) << 6)
- + (((unsigned char) p_csp->service_profile_entry[j].service.phase_services.b_menu_for_voice_group_call) << 5)
- + (((unsigned char) p_csp->service_profile_entry[j].service.phase_services.b_menu_for_voice_broadcast_service) << 4)
- + (((unsigned char) p_csp->service_profile_entry[j].service.phase_services.b_menu_for_multiple_subscriber_profile) << 3)
- + (((unsigned char) p_csp->service_profile_entry[j].service.phase_services.b_menu_for_multiple_band) << 2);
- break;
-
- case 0xC0:
- p_out[++i] = (((unsigned char) p_csp->service_profile_entry[j].service.value_added_services.b_restrict_menu_for_manual_selection) << 7)
- + (((unsigned char) p_csp->service_profile_entry[j].service.value_added_services.b_restrict_menu_for_voice_mail) << 6)
- + (((unsigned char) p_csp->service_profile_entry[j].service.value_added_services.b_restrict_menu_for_mo_sms_and_paging) << 5)
- + (((unsigned char) p_csp->service_profile_entry[j].service.value_added_services.b_restrict_menu_for_mo_sms_with_emial_type) << 4)
- + (((unsigned char) p_csp->service_profile_entry[j].service.value_added_services.b_restrict_menu_for_fax_calls) << 3)
- + (((unsigned char) p_csp->service_profile_entry[j].service.value_added_services.b_restrict_menu_for_data_calls) << 2)
- + ((unsigned char) p_csp->service_profile_entry[j].service.value_added_services.b_restrict_menu_for_change_language);
- break;
-
- case 0xD5:
- if (p_csp->service_profile_entry[j].service.information_numbers.b_information_numbers)
- p_out[++i] = 0xFF;
- else
- p_out[++i] = 0x00;
- break;
-
- default:
- break;
- }
- }
-
- return TRUE;
-}
-
-gboolean tcore_sim_decode_mwis(struct tel_sim_mw *pMwis, unsigned char *p_in, int in_length)
-{
- int i;
- unsigned char type = 0;
- unsigned char mask = 0x01;
-
- if (in_length == 0)
- return FALSE;
-
- memset((void *) pMwis, 0, sizeof(struct tel_sim_mw));
-
- type = p_in[0]; /* 0x07 */
-
- if (type) {
- for (i = 0; i < 5; i++) {
- switch (type & mask) {
- case 0x01:
- pMwis->indicator_status = pMwis->indicator_status | SIM_MWIS_VOICE;
- break;
-
- case 0x02:
- pMwis->indicator_status = pMwis->indicator_status | SIM_MWIS_FAX;
- break;
-
- case 0x04:
- pMwis->indicator_status = pMwis->indicator_status | SIM_MWIS_EMAIL;
- break;
-
- case 0x08:
- pMwis->indicator_status = pMwis->indicator_status | SIM_MWIS_OTHER;
- break;
-
- case 0x10:
- pMwis->indicator_status = pMwis->indicator_status | SIM_MWIS_VIDEO;
- break;
-
- default:
- pMwis->indicator_status = pMwis->indicator_status | SIM_MWIS_NONE;
- break;
- }
- mask = mask << 1;
- }
-
- pMwis->voice_count = p_in[1];
- pMwis->fax_count = p_in[2];
- pMwis->email_count = p_in[3];
- pMwis->other_count = p_in[4];
-
- if (in_length == 6)
- pMwis->video_count = p_in[5];
- }
-
- return TRUE;
-}
-
-char *tcore_sim_encode_mwis(int *out_length, const struct tel_sim_mw *pMwis, int in_length)
-{
- char *p_out = NULL;
- int i = 0;
- int encoded_size = 0;
-
- if (out_length == 0)
- return NULL;
-
- /*
- * by 3GPP spec (31.102),
- * EF-MWIS record length should be <= 6. (5 or 6)
- */
- if (in_length > 6)
- encoded_size = 6;
- else
- encoded_size = in_length;
-
- p_out = calloc(1, encoded_size);
- if (!p_out)
- return NULL;
-
- for (i = 0; i < encoded_size; i++) {
- switch (i) {
- case 0:
- p_out[0] = (unsigned char) pMwis->indicator_status;
- break;
-
- case 1:
- p_out[1] = pMwis->voice_count;
- break;
-
- case 2:
- p_out[2] = pMwis->fax_count;
- break;
-
- case 3:
- p_out[3] = pMwis->email_count;
- break;
-
- case 4:
- p_out[4] = pMwis->other_count;
- break;
-
- case 5:
- p_out[5] = pMwis->video_count;
- break;
-
- default:
- break;
- }
- }
-
- *out_length = encoded_size;
- return p_out;
-}
-
-gboolean tcore_sim_decode_vmwf(struct tel_sim_cphs_mw *p_vmwf, unsigned char *p_in, unsigned long in_length)
-{
- int i, j = 0;
- unsigned char *pTemp = (unsigned char *) p_vmwf;
- unsigned char mask = 0x0F;
- unsigned char voiceMsgFlg = 0;
-
- if (in_length == 0) {
- dbg("fail - input length is zero");
- return FALSE;
- }
-
- /* current telephony supports 2 byte cphs-vmwf data */
- for (i = 0; i < SIM_CPHS_VMWF_LEN_MAX; i++) {
- voiceMsgFlg = p_in[i];
- for (j = 0; j < 2; j++) {
- if ((voiceMsgFlg & mask) == 0x0A)
- *pTemp = 1; /* TRUE */
- else if ((voiceMsgFlg & mask) == 0x05)
- *pTemp = 0; /* FALSE */
-
- pTemp += sizeof(gboolean);
- voiceMsgFlg = voiceMsgFlg >> 4;
- }
- }
- return TRUE;
-}
-
-char *tcore_sim_encode_vmwf(int *out_length, const struct tel_sim_cphs_mw *p_vmwf, int in_length)
-{
- int i, j = 0;
- char *p_out = NULL;
- unsigned char *pTemp = (unsigned char *) p_vmwf;
- unsigned char present = 0x0A;
- unsigned char absent = 0x05;
-
- if (out_length == 0)
- return NULL;
-
- p_out = calloc(1, in_length);
- if (!p_out)
- return NULL;
-
- for (i = 0; i < in_length; i++) {
- present = 0x0A;
- absent = 0x05;
-
- p_out[i] = 0x00;
-
- for (j = 0; j < 2; j++) {
- if (*pTemp)
- p_out[i] = p_out[i] | present; /* TRUE */
- else
- p_out[i] = p_out[i] | absent; /* TRUE */
-
- pTemp += sizeof(gboolean);
- present = present << 4;
- absent = absent << 4;
- }
- }
-
- *out_length = in_length;
- return p_out;
-}
-
-gboolean tcore_sim_decode_ons(unsigned char *p_out, unsigned char *p_in, int in_length)
-{
- int length;
- memset((void *) p_out, 0, SIM_CPHS_OPERATOR_NAME_LEN_MAX+1);
-
- if (in_length == 0)
- return FALSE;
-
- if (_is_empty(p_in, in_length) == TRUE)
- return FALSE;
-
- /* current telephony supports 25 byte cphs-operator name string. */
- if (in_length >= SIM_CPHS_OPERATOR_NAME_LEN_MAX)
- in_length = SIM_CPHS_OPERATOR_NAME_LEN_MAX;
-
- length = _get_string(p_out, p_in, in_length);
- p_out[length] = '\0';
- dbg("Operator Name is (%s) & Length (%d) ", p_out, length);
-
- return TRUE;
-}
-
-gboolean tcore_sim_decode_cfis(struct tel_sim_cfis *p_cfis, unsigned char *p_in, int in_length)
-{
- int bcd_byte; /* dialing number max length */
- int digit_len;
- int i = 0;
- if (in_length == 0)
- return FALSE;
-
- if (_is_empty(p_in, in_length) == TRUE) {
- dbg("empty record. all data is set 0xff");
- return TRUE; /* this is empty record */
- }
-
- p_cfis->msp_num = p_in[i++];
- p_cfis->cfu_status = p_in[i++];
-
- /* get TON and NPI */
- p_cfis->ton = (p_in[++i] >> 4) & 0x07;
- p_cfis->npi = p_in[i++] & 0x0F;
-
- /* get actual dialing number length */
- /* current telephony supports 20 byte dialing number format. */
- bcd_byte = _get_valid_bcd_byte(&p_in[i], SIM_XDN_NUMBER_LEN_MAX / 2);
-
- /* get dialing number/SSC string */
- digit_len = _bcd_to_digit((char *) p_cfis->cfu_num, (char *) &p_in[i], bcd_byte); /* actual dialing number length in BCD. */
- dbg("Dialing number Length[%d]", digit_len);
-
- i = i + SIM_XDN_NUMBER_LEN_MAX / 2;
-
- /* get Capability/Configuration id */
- p_cfis->cc2_id = p_in[i++];
-
- /* get Extension1 id */
- p_cfis->ext7_id = p_in[i];
-
- dbg("MspNumber 0x%x", p_cfis->msp_num);
- dbg("Status 0x%x", p_cfis->cfu_status);
- dbg("TypeOfNumber %d", p_cfis->ton);
- dbg("NumberingPlanIdent %d", p_cfis->npi);
- dbg("Dialing number[%s]", p_cfis->cfu_num);
-
- return TRUE;
-}
-
-gboolean tcore_sim_decode_img(struct tel_sim_img *p_out, unsigned char *p_in, int in_length)
-{
- int i = 1;
-
- dbg("Func Entrance");
-
- if ((NULL == p_out) || (NULL == p_in))
- return FALSE;
-
- if ((in_length == 0) || (in_length == 0xff) || (10 > in_length)) {
- dbg("No valid IMG data present - length:[%x]", in_length);
- return FALSE;
- }
-
- if (_is_empty(p_in, in_length) == TRUE) {
- dbg("empty record. all data is set 0xff");
- return FALSE; /* this is empty record */
- }
-
- /* We are trying to decode only the 1st valid image data property and ignoring other for time being */
- p_out->width = p_in[i++];
- p_out->height = p_in[i++];
- p_out->ics = p_in[i++];
- p_out->iidf_fileid = (*(p_in+4) << 8) | (*(p_in+5) & 0x00ff); /*index is 4 and 5 because the 1st byte is number of actual image instance */
- p_out->offset = (*(p_in+6) << 8) | (*(p_in+7) & 0x00ff);
- p_out->length = (*(p_in+8) << 8) | (*(p_in+9) & 0x00ff);
-
- dbg("p_out->width[%d], p_out->height[%d], p_out->ics[%d], p_out->offset[%d], p_out->length[%d], p_out->iidf_fileid[0x%02x]",
- p_out->width, p_out->height, p_out->ics, p_out->offset, p_out->length, p_out->iidf_fileid);
-
- return TRUE;
-}
-
-gboolean tcore_sim_decode_isim_impi(struct tel_sim_impi *p_out, unsigned char *p_in, int in_length)
-{
- unsigned char tag = 0, len = 0;
-
- if (p_in == NULL || p_out == NULL || in_length < 2)
- return FALSE;
-
- tag = p_in[0];
- if (tag != 0x80) {
- err("tag[0x%x] should be 0x80. return FALSE.", tag);
- return FALSE;
- }
-
- len = p_in[1];
-
- if (in_length < len + 2)
- err("invalid length. in_length[%d] < TLV_len[%d] + 2", in_length, len);
-
- p_out->impi = g_memdup(&p_in[2], len);
-
- return TRUE;
-}
-
-gboolean tcore_sim_decode_isim_domain(struct tel_sim_domain *p_out, unsigned char *p_in, int in_length)
-{
- unsigned char tag = 0, len = 0;
-
- if (p_in == NULL || p_out == NULL || in_length < 2)
- return FALSE;
-
- tag = p_in[0];
- if (tag != 0x80) {
- err("tag[0x%x] should be 0x80. return FALSE.", tag);
- return FALSE;
- }
-
- len = p_in[1];
-
- if (in_length < len + 2)
- err("invalid length. in_length[%d] < TLV_len[%d] + 2", in_length, len);
-
- p_out->domain = g_memdup(&p_in[2], len);
-
- return TRUE;
-}
-
-gboolean tcore_sim_decode_isim_impu(struct tel_sim_impu *p_out, unsigned char *p_in, int in_length)
-{
- unsigned char tag = 0, len = 0;
-
- if (p_in == NULL || p_out == NULL || in_length < 2)
- return FALSE;
-
- tag = p_in[0];
- if (tag != 0x80) {
- err("tag[0x%x] should be 0x80. return FALSE.", tag);
- return FALSE;
- }
-
- len = p_in[1];
-
- if (in_length < len + 2)
- err("invalid length. in_length[%d] < TLV_len[%d] + 2", in_length, len);
-
- p_out->impu = g_memdup(&p_in[2], len);
-
- return TRUE;
-}
-
-gboolean tcore_sim_decode_isim_pcscf(struct tel_sim_pcscf *p_out, unsigned char *p_in, int in_length)
-{
- unsigned char tag = 0, len = 0;
-
- if (p_in == NULL || p_out == NULL || in_length < 2)
- return FALSE;
-
- tag = p_in[0];
- if (tag != 0x80) {
- err("tag[0x%x] should be 0x80. return FALSE.", tag);
- return FALSE;
- }
-
- /* P-CSCF Address length */
- len = p_in[1];
-
- if (in_length < len + 2)
- err("invalid length. in_length[%d] < TLV_len[%d] + 2", in_length, len);
-
- /* P-CSCF Address type */
- if (p_in[2] == 0x00)
- p_out->type = SIM_PCSCF_TYPE_FQDN;
- else if (p_in[2] == 0x01)
- p_out->type = SIM_PCSCF_TYPE_IPV4;
- else if (p_in[2] == 0x02)
- p_out->type = SIM_PCSCF_TYPE_IPV6;
-
- /*
- * If P-CSCF Address type is "00" (FQDN), then address shall be
- * encoded to an octet string according to UTF-8 encoding rules.
- * So, no need to convert it to UTF-8.
- */
- if (p_out->type == SIM_PCSCF_TYPE_FQDN) {
- p_out->pcscf = g_memdup(&p_in[3], len - 1);
- } else {
- unsigned char buf[255] = {0, };
- unsigned short buf_len;
- gboolean ret = FALSE;
-
- ret = tcore_util_convert_string_to_utf8(buf, &buf_len, ALPHABET_FORMAT_SMS_DEFAULT,
- (const unsigned char *)&p_in[3], len - 1);
- if (ret)
- p_out->pcscf = g_memdup(buf, buf_len);
- }
-
- return TRUE;
-}
-
-char *tcore_sim_encode_cfis(int *out_length, const struct tel_sim_cfis *p_cfis)
-{
- char *encoded_o = NULL;
- char bcd[10];
-
- encoded_o = calloc(1, 16); /* EF-CFIS record length is 16 */
- if (!encoded_o)
- return NULL;
-
- memset(bcd, 0xff, 10);
-
- /*
- * Bytes Description M/O Length
- *----------------------------------------------------------------------------------------
- * 1 MSP number M 1 byte
- * 2 CFU indicator status M 1 byte
- * 3 Length of BCD number M 1 byte
- * 4 TON and NPI M 1 byte
- * 5 to 14 Dialing Number M 10 bytes. unused byte should be set with 'F'
- * 15 Capability/Configuration2 Record Identifier M 1 byte
- * 16 Extension 7 Record Identifier M 1 byte
- */
- encoded_o[0] = p_cfis->msp_num;
- encoded_o[1] = p_cfis->cfu_status;
-
- encoded_o[2] = (strlen(p_cfis->cfu_num) + 1) / 2;
-
- /* set TON and NPI */
- encoded_o[3] = 0x80;
- encoded_o[3] |= (p_cfis->ton & 0x07) << 4;
- encoded_o[3] |= p_cfis->npi & 0x0F;
-
- _digit_to_bcd(bcd, (char *)&p_cfis->cfu_num, strlen(p_cfis->cfu_num));
- memcpy(&encoded_o[4], bcd, 10);
-
- encoded_o[14] = p_cfis->cc2_id;
- encoded_o[15] = p_cfis->ext7_id;
-
- *out_length = 16;
- return encoded_o;
-}
-
-gboolean tcore_sim_decode_dynamic_flag(struct tel_sim_cphs_dflag *p_df, unsigned char *p_in, int in_length)
-{
- if (in_length == 0)
- return FALSE;
-
- memset((void *)p_df, 0, sizeof(struct tel_sim_cphs_dflag));
-
- switch (p_in[0] & 0x01) {
- case 0x00:
- p_df->DynamicFlags = SIM_DYNAMIC_FLAGS_LINE2;
- break;
-
- case 0x01:
- p_df->DynamicFlags = SIM_DYNAMIC_FLAGS_LINE1;
- break;
-
- default:
- warn("invalid input");
- break;
- }
-
- return TRUE;
-}
-
-gboolean tcore_sim_decode_dynamic2_flag(struct tel_sim_cphs_dflag2 *p_d2f, unsigned char *p_in, int in_length)
-{
- if (in_length == 0)
- return FALSE;
-
- memset((void *) p_d2f, 0, sizeof(struct tel_sim_cphs_dflag2));
-
- switch (p_in[0] & 0x01) {
- case 0x00:
- p_d2f->Dynamic2Flag = SIM_PIN2_ACCESSIBLE_FLAGS_UNLOCKED;
- break;
-
- case 0x01:
- p_d2f->Dynamic2Flag = SIM_PIN2_ACCESSIBLE_FLAGS_LOCKED;
- break;
-
- default:
- warn("invalid input");
- break;
- }
-
- return TRUE;
-}
-
-gboolean tcore_sim_encode_dynamic_flag(char *p_out, int out_length, struct tel_sim_cphs_dflag *p_df)
-{
- if (out_length == 0 || out_length > 1)
- return FALSE;
-
- memset((void *)p_out, 0xFF, out_length);
- p_out[0] = p_df->DynamicFlags;
-
- return TRUE;
-}
-
-gboolean tcore_sim_encode_dynamic2_flag(char *p_out, int out_length, struct tel_sim_cphs_dflag2 *p_d2f)
-{
- if (out_length == 0 || out_length > 1)
- return FALSE;
-
- memset((void *)p_out, 0xFF, out_length);
- p_out[0] = p_d2f->Dynamic2Flag;
-
- return TRUE;
-}
-
-gboolean tcore_sim_decode_cphs_info(struct tel_sim_cphs_info *pCphsInfo, unsigned char *p_in, int in_length)
-{
- int i, j = 0;
- unsigned char mask = 0x03;
- unsigned char *pTemp = (unsigned char *) &pCphsInfo->CphsServiceTable;
-
- memset((void *)pCphsInfo, 0, sizeof(struct tel_sim_cphs_info));
-
- if (in_length == 0)
- return FALSE;
-
- /* CPHS info EF has 3 bytes data. */
- if (in_length >= SIM_CPHS_INFO_LEN_MAX)
- in_length = SIM_CPHS_INFO_LEN_MAX;
-
- switch (p_in[0]) {
- case 0x01:
- pCphsInfo->CphsPhase = SIM_CPHS_PHASE1;
- break;
-
- case 0x02:
- pCphsInfo->CphsPhase = SIM_CPHS_PHASE2;
- break;
-
- default:
- pCphsInfo->CphsPhase = SIM_CPHS_PHASE_RFU;
- break;
- }
-
- dbg("Cphs Phase %d \n", pCphsInfo->CphsPhase);
-
- for (i = 1; i < in_length; i++) { /* CPHS SST is only 2 bytes */
- mask = 0x03; /* reset mast to check first bit */
- for (j = 0; j < 4; j++) {
- if (p_in[i] & mask)
- *pTemp = 1;
-
- dbg("Byte (%d), service (%d) ", i + 1, *pTemp);
- pTemp += sizeof(gboolean);
- mask = mask << 2;
- }
- }
-
- return TRUE;
-}
-
-gboolean tcore_sim_decode_short_ons(unsigned char *p_out, unsigned char *p_in, int in_length)
-{
- int length;
-
- memset(p_out, 0x00, SIM_CPHS_OPERATOR_NAME_SHORT_FORM_LEN_MAX+1);
-
- if (_is_empty(p_in, in_length) == TRUE)
- return FALSE; /* this is empty record */
-
- /* CPHS specification shows current EF include 10 bytes */
- if (in_length == 0)
- return FALSE;
-
- if (in_length > SIM_CPHS_OPERATOR_NAME_SHORT_FORM_LEN_MAX)
- in_length = SIM_CPHS_OPERATOR_NAME_SHORT_FORM_LEN_MAX;
-
- length = _get_string(p_out, p_in, in_length);
- p_out[length] = '\0';
- dbg("Operator short Name is (%s) & length (%d)", p_out, length);
-
- return TRUE;
-}
-
-gboolean tcore_sim_decode_information_number(struct tel_sim_cphs_info_number *p_info, unsigned char *p_in, int in_length)
-{
- int i;
-
- if (in_length == 0)
- return FALSE;
-
- for (i = 0; i < in_length; i++)
- dbg(" \t0x%04X.", p_in[i]);
-
- if (_is_empty(p_in, in_length) == TRUE)
- return FALSE; /* this is empty record */
-
- p_info->AlphaIdLength = p_in[0];
-
- if (p_in[1] & 0x0F)
- p_info->IndexLevelIndicator = (enum tel_sim_cphs_index_level)(p_in[1] & 0x0F);
-
- if (p_in[1] & 0x10)
- p_info->PremiumServiceIndicator = TRUE;
-
- if (p_in[1] & 0x20)
- p_info->PremiumServiceIndicator = TRUE;
-
- _get_string(p_info->Alpha_id, &p_in[2], p_info->AlphaIdLength);
-
- p_info->DiallingnumLength = p_in[2 + p_info->AlphaIdLength] * 2;
- p_info->TypeOfNumber = (p_in[3 + p_info->AlphaIdLength] >> 4) & 0x07;
- p_info->NumberingPlanIdentity = p_in[3 + p_info->AlphaIdLength] & 0x0F;
-
- /* get dialing number/SSC string */
- _bcd_to_digit((char *)p_info->DiallingnumLength,
- (char *)&p_in[4 + p_info->AlphaIdLength],
- p_info->DiallingnumLength / 2); /* actual dialing number length in BCD. */
-
- /* get Extension1 id */
- p_info->Ext1RecordId = p_in[4 + p_info->AlphaIdLength + p_info->DiallingnumLength / 2];
-
- return TRUE;
-}
-
-gboolean tcore_sim_decode_opl(struct tel_sim_opl *p_opl, unsigned char *p_in, int in_length)
-{
- if (_is_empty(p_in, in_length) == TRUE) {
- memset(p_opl, 0x00, sizeof(struct tel_sim_opl));
- return FALSE; /* this is empty record */
- }
-
- _decode_plmn(p_in, p_opl->plmn);
- dbg(" PLMN Code[%s]", p_opl->plmn);
-
- p_opl->lac_from = (*(p_in+3) << 8) | (*(p_in+4) & 0x00ff);
- dbg(" Start value of the LAC range[%x]", p_opl->lac_from);
-
- p_opl->lac_to = (*(p_in+5) << 8) | (*(p_in+6) & 0x00ff);
- dbg(" End value of the LAC range[%x]", p_opl->lac_to);
-
- p_opl->rec_identifier = p_in[7];
- dbg(" PNN Record identifier[%x]", p_opl->rec_identifier);
-
- return TRUE;
-}
-
-gboolean tcore_sim_decode_pnn(struct tel_sim_pnn *p_pnn, unsigned char *p_in, int in_length)
-{
- int f_name_len = 0, s_name_len = 0;
- int cvt_leng = 0, s_name_base = 0;
-
- if (_is_empty(p_in, in_length) == TRUE) {
- memset(p_pnn, 0x00, sizeof(struct tel_sim_pnn));
- return FALSE; /* this is empty record */
- }
-
- /* Full name for network IEI(Information Element Identifier), 0x43 */
- if (p_in[0] == 0x43) {
- dbg(" Full name of network IEI exist");
- /* f_name_part includes information byte. */
- f_name_len = (int)p_in[1] - 1;
-
- /*
- * 3rd byte information element(according to TS 24.008 for Network Name)
- * 8 :ext1
- * 7 6 5 : coding scheme
- * 4 : Add CI
- * 3 2 1 : number of spare bits in last octet
- *
- * Coding Scheme (octet 3, bits 5-7)
- * 0 0 0 Cell Broadcast data coding scheme, GSM default alphabet, language unspecified, defined in 3GPP TS 23.038 [8b]
- * 0 0 1 UCS2 (16 bit) [72]
- * 0 1 0 to reserved
- * 1 1 1 to reserved
- */
- if ((p_in[2] & 0x70) >> 4 == 0) {
- dbg("DCS:GSM7");
-
- /*
- * In case of GSM7, 35byte packing data will be
- * converted 40 bytes unpacking string.
- */
- if (f_name_len > (SIM_NW_FULL_NAME_LEN_MAX * 7) / 8)
- f_name_len = (SIM_NW_FULL_NAME_LEN_MAX * 7) / 8;
-
- _unpack_7bit28bit(p_in + 3,
- f_name_len, (unsigned char *)(p_pnn->full_name));
- } else if ((p_in[2] & 0x70) >> 4 == 1) {
- dbg("DCS:UCS2");
-
- /* current telephony supports 40 bytes network name string */
- if (f_name_len > SIM_NW_FULL_NAME_LEN_MAX)
- f_name_len = SIM_NW_FULL_NAME_LEN_MAX;
-
- _ucs2_to_utf8(f_name_len, p_in + 3,
- (int *)&cvt_leng, (unsigned char *)(p_pnn->full_name));
- } else {
- dbg("DCS:unknown");
-
- return FALSE;
- }
-
- dbg(" Full name of network contents[%s]", p_pnn->full_name);
-
- s_name_base = (int)p_in[1] + 2;
- dbg(" short name base byte [0x%02x]", s_name_base);
-
- /* Short Name for network IEI(Information Element Identifier), 0x45 */
- if (p_in[s_name_base] == 0x45) {
- dbg(" Short name of network IEI exist");
-
- /* s_name_part includes information byte. */
- s_name_len = p_in[s_name_base + 1] - 1;
-
- if ((p_in[s_name_base + 2] & 0x70) >> 4 == 0) {
- dbg("DCS:GSM7");
-
- /*
- * In case of GSM7, 35byte packing data
- * will be converted 40 bytes unpacking string.
- */
- if (s_name_len > (SIM_NW_FULL_NAME_LEN_MAX * 7) / 8)
- s_name_len = (SIM_NW_FULL_NAME_LEN_MAX * 7) / 8;
-
- _unpack_7bit28bit(p_in + s_name_base + 3,
- s_name_len, (unsigned char *)(p_pnn->short_name));
- } else if ((p_in[s_name_base + 2] & 0x70) >> 4 == 1) {
- dbg("DCS:UCS2");
-
- if (s_name_len > SIM_NW_FULL_NAME_LEN_MAX)
- s_name_len = SIM_NW_FULL_NAME_LEN_MAX;
-
- _ucs2_to_utf8(s_name_len, p_in + s_name_base + 3,
- (int *)&cvt_leng, (unsigned char *)(p_pnn->short_name));
- } else {
- dbg("DCS:unknown");
-
- return FALSE;
- }
-
- dbg(" Short name of network contents[%s]", p_pnn->short_name);
- }
-
- return TRUE;
- }
-
- return FALSE;
-}
-
-gboolean tcore_sim_decode_oplmnwact(struct tel_sim_oplmnwact_list *p_list, unsigned char *p_in, int in_length)
-{
- unsigned long m = 0;
-
- /*
- * current raw data can include invalid OPLMN data(ex: ff ff ff 00 00).
- * so we can`t decide the number of OPLMN records directly.
- */
- int rawOplmnWactCount = 0;
- int i = 0;
-
- memset((void *)p_list, 0, sizeof(struct tel_sim_oplmnwact_list));
-
- rawOplmnWactCount = in_length / 5;
-
- dbg("rawOplmnWactCount[%d]", rawOplmnWactCount);
-
- for (i = 0; i < rawOplmnWactCount; i++) {
- /*
- * Regarding current IPC data, even if there`s no OPLMN value,
- * IPC data is sending with 'ff ff ff 00 00'. so we should check for validation.
- */
- if (p_in[m] == 0xff) {
- p_list->opwa_count = m / 5;
- dbg("OPLMN(MCC+MNC) value is not found at p_in[m]=[%lu].So OPLMN count is [%d]",
- m, p_list->opwa_count);
- return TRUE;
- }
-
- _decode_plmn(&p_in[m], p_list->opwa[i].plmn);
- dbg("[%d] OPLMN PLMN Code[%s]", i, p_list->opwa[i].plmn);
-
- if (p_in[m+3] & 0x80)
- p_list->opwa[i].b_umts = 1;
-
- if (p_in[m+4] & 0x80)
- p_list->opwa[i].b_gsm = 1;
-
- m = m + 5;
- }
-
- p_list->opwa_count = rawOplmnWactCount;
- dbg("OPLMN count is p_list->opwa_count[%d]", p_list->opwa_count);
-
- return TRUE;
-}
-
-gboolean tcore_sim_decode_ef_info(struct tcore_sim_ef_info *p_ef_info, CoreObject *o, char *p_in, int in_length)
-{
- unsigned short arr_file_id = 0;
- char *record_data = NULL;
- unsigned char file_type_tag = SIM_FILE_TYPE_TAG;
- unsigned char *ptr_data;
- unsigned char file_id_len = 0;
- gboolean ret = FALSE;
-
- if (!p_ef_info) {
- err("output parameter is null");
- return ret;
- }
-
- if (_is_empty((unsigned char *)p_in, in_length) == TRUE) {
- memset(p_ef_info, 0x00, sizeof(struct tcore_sim_ef_info));
- return ret; /* Empty record */
- }
-
- record_data = tcore_util_convert_hexstring_to_bytes(p_in);
- if (!record_data) {
- err("tcore_util_convert_hexstring_to_bytes Failed!!");
- return ret;
- }
- tcore_util_hex_dump(" ", strlen(p_in) / 2, record_data);
-
- ptr_data = (unsigned char *)record_data;
- switch (tcore_sim_get_type(o)) {
- case 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)
- */
-
- /* FCP template tag - File Control Parameters tag*/
- if (*ptr_data == SIM_FCP_TEMPLATE_TAG) {
- /* parse complete FCP tag. increment to next byte*/
- ptr_data++;
-
- dbg("tag_len: %02x", *ptr_data++);
- /* FCP file descriptor - file type, accessibility, DF, ADF etc*/
- if (*ptr_data == SIM_FILE_DESCRIPTOR_TAG) {
- /* increment to next byte */
- ptr_data++;
-
- /* 2 or 5 value*/
- ptr_data++;
-
- /* consider only last 3 bits*/
- file_type_tag = file_type_tag & (*ptr_data);
- dbg("File Type Tag: %02x", file_type_tag);
-
- switch (file_type_tag) {
- case SIM_FTYPE_TRANSPARENT:
- dbg("FileType: [Transparent file type]");
- p_ef_info->file_type = SIM_FTYPE_TRANSPARENT;
-
- /* increment to next byte */
- ptr_data++;
-
- /* increment to next byte */
- ptr_data++;
- break;
-
- case SIM_FTYPE_LINEAR_FIXED:
- dbg("FileType: [Linear fixed file type]");
- /* increment to next byte */
- ptr_data++;
-
- /* data coding byte - value 21 */
- ptr_data++;
-
- /* 2bytes */
- memcpy(&p_ef_info->record_length, ptr_data, 2);
-
- /* swap bytes */
- p_ef_info->record_length = _swap_bytes16(p_ef_info->record_length);
- ptr_data = ptr_data + 2;
- p_ef_info->number_of_records = *ptr_data++;
-
- /* Data lossy conversation from enum (int) to unsigned char */
- p_ef_info->file_type = SIM_FTYPE_LINEAR_FIXED;
- break;
-
- case SIM_FTYPE_CYCLIC:
- dbg("FileType: [Cyclic fixed file type]");
- /* increment to next byte */
- ptr_data++;
-
- /* data coding byte - value 21 */
- ptr_data++;
-
- /* 2bytes */
- memcpy(&p_ef_info->record_length, ptr_data, 2);
-
- /* swap bytes */
- p_ef_info->record_length = _swap_bytes16(p_ef_info->record_length);
- ptr_data = ptr_data + 2;
- p_ef_info->number_of_records = *ptr_data++;
- p_ef_info->file_type = SIM_FTYPE_CYCLIC;
-
- break;
-
- default:
- err("Unhandled File Type [0x%x]", *ptr_data);
- break;
- }
- } else {
- err("INVALID FCP received[0x%x] - Debug!", *ptr_data);
- goto EXIT;
- }
-
- /* File identifier - file id */ /* 0x84, 0x85, 0x86 etc are currently ignored and not handled */
- if (*ptr_data == SIM_FILE_IDENTIFIER_TAG) {
- /* increment to next byte */
- ptr_data++;
- file_id_len = *ptr_data++;
- dbg("File ID length: %02x", file_id_len);
-
- memcpy(&p_ef_info->file_id, ptr_data, file_id_len);
- dbg("File ID: %x", p_ef_info->file_id);
-
- /* swap bytes */
- p_ef_info->file_id = _swap_bytes16(p_ef_info->file_id);
-
- ptr_data = ptr_data + 2;
- } else {
- err("INVALID FCP received[0x%x] - Debug!", *ptr_data);
- goto EXIT;
- }
-
- /* proprietary information */
- if (*ptr_data == SIM_PROPRIETARY_INFORMATION_TAG) {
- 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 {
- err("INVALID FCP received[0x%x] - Debug!", *ptr_data);
- }
-
- /* 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 == SIM_LIFE_CYCLE_STATUS_TAG) {
- /* increment to next byte */
- ptr_data++;
-
- /* length - value 1 */
- ptr_data++;
-
- switch (*ptr_data) {
- case 0x04:
- case 0x06:
- dbg("Operation state - Deactivated");
- ptr_data++;
- break;
-
- case 0x05:
- case 0x07:
- dbg("Operation state - Activated");
- ptr_data++;
- break;
-
- default:
- dbg("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 = _swap_bytes16(arr_file_id);
- ptr_data = ptr_data + 2;
- ptr_data++;
- } else {
- /* if tag length is not 3 */
- /* ignoring bytes */
- dbg("Useless security attributes, so jump to next tag");
- ptr_data = ptr_data + (*ptr_data + 1);
- }
- } else {
- err("INVALID FCP received[0x%x] - Debug!", *ptr_data);
- goto EXIT;
- }
-
- /* file size excluding structural info*/
- if (*ptr_data == SIM_FILE_SIZE_TAG) {
- /*
- * 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(&p_ef_info->file_size, ptr_data, 2);
-
- /* swap bytes */
- p_ef_info->file_size = _swap_bytes16(p_ef_info->file_size);
- ptr_data = ptr_data + 2;
- } else {
- err("INVALID FCP received[0x%x] - Debug!", *ptr_data);
- goto EXIT;
- }
-
- /* total file size including structural info*/
- if (*ptr_data == SIM_TOTAL_FILE_SIZE_TAG) {
- /* increment to next byte */
- ptr_data++;
- /* ignored bytes */
- ptr_data = ptr_data + 3;
- } else {
- err("INVALID FCP received[0x%x] - Debug!", *ptr_data);
- /* 0x81 is optional tag?? check out! so do not return -1 from here! */
- }
-
- /*short file identifier ignored*/
- if (*ptr_data == SIM_SHORT_FILE_IDENTIFIER_TAG) {
- dbg("0x88: Do Nothing");
- /* DO NOTHING */
- }
- } else {
- err("INVALID FCP received[0x%x] - Debug!", *ptr_data);
- goto EXIT;
- }
- }
- break;
- case SIM_TYPE_GSM: {
- /*Ignore RFU byte1 and byte2 */
- ptr_data++;
- ptr_data++;
-
- /* file size */
- memcpy(&p_ef_info->file_size, ptr_data, 2);
-
- /* swap bytes */
- p_ef_info->file_size = _swap_bytes16(p_ef_info->file_size);
-
- /* parsed file size */
- ptr_data = ptr_data + 2;
-
- /* file id */
- memcpy(&p_ef_info->file_id, ptr_data, 2);
- p_ef_info->file_id = _swap_bytes16(p_ef_info->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 SIM_FTYPE_RFU:
- /* RFU file type */
- dbg("RFU file type- not handled - Debug!");
- break;
-
- case SIM_FTYPE_MF:
- /* MF file type */
- dbg("MF file type - not handled - Debug!");
- break;
-
- case SIM_FTYPE_DF:
- /* DF file type */
- dbg("DF file type - not handled - Debug!");
- break;
-
- case SIM_FTYPE_EF:
- /* EF file type */
- dbg("EF file type tag[%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++;
- p_ef_info->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. */
- p_ef_info->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 */
- 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. */
- p_ef_info->record_length = *ptr_data;
- if (p_ef_info->record_length != 0)
- p_ef_info->number_of_records = (p_ef_info->file_size / p_ef_info->record_length);
- break;
-
- default:
- err("Unhandled file type[0x%x]", *ptr_data);
- break;
- }
- }
- break;
- default:
- err("Unknown SIM type [%d]", tcore_sim_get_type(o));
- break;
- }
-
- ret = TRUE;
-
-EXIT:
- g_free(record_data);
- return ret;
-}
-
-enum tel_sim_status tcore_sim_get_status(CoreObject *o)
-{
- struct private_object_data *po = NULL;
-
- po = tcore_object_ref_object(o);
- if (!po) {
- dbg("po access fail");
- return -1;
- }
-
- return po->sim_status;
-}
-
-gboolean tcore_sim_set_status(CoreObject *o, enum tel_sim_status status)
-{
- struct private_object_data *po = NULL;
-
- po = tcore_object_ref_object(o);
- if (!po) {
- dbg("po access fail");
- return FALSE;
- }
-
- po->sim_status = status;
-
- return TRUE;
-}
-
-gboolean tcore_sim_get_identification(CoreObject *o)
-{
- struct private_object_data *po = NULL;
-
- po = tcore_object_ref_object(o);
- if (!po) {
- dbg("po access fail");
- return -1;
- }
-
- return po->b_sim_changed;
-}
-
-gboolean tcore_sim_set_identification(CoreObject *o, gboolean b_changed)
-{
- struct private_object_data *po = NULL;
- po = tcore_object_ref_object(o);
- if (!po) {
- dbg("po access fail");
- return FALSE;
- }
- po->b_sim_changed = b_changed;
-
- return TRUE;
-}
-
-enum tel_sim_type tcore_sim_get_type(CoreObject *o)
-{
- struct private_object_data *po = NULL;
-
- po = tcore_object_ref_object(o);
- if (!po) {
- dbg("po access fail");
- return -1;
- }
-
- return po->type;
-}
-
-gboolean tcore_sim_set_type(CoreObject *o, enum tel_sim_type type)
-{
- struct private_object_data *po = NULL;
-
- po = tcore_object_ref_object(o);
- if (!po) {
- dbg("po access fail");
- return FALSE;
- }
-
- po->type = type;
-
- return TRUE;
-}
-
-struct tel_sim_imsi *tcore_sim_get_imsi(CoreObject *o)
-{
- struct private_object_data *po = NULL;
-
- po = tcore_object_ref_object(o);
- if (!po) {
- dbg("po access fail");
- return NULL;
- }
-
- return g_memdup(&po->imsi, sizeof(struct tel_sim_imsi));
-}
-
-gboolean tcore_sim_set_imsi(CoreObject *o, const struct tel_sim_imsi *imsi)
-{
- struct private_object_data *po = NULL;
-
- po = tcore_object_ref_object(o);
- if (!po) {
- dbg("po access fail");
- return FALSE;
- }
-
- memcpy(&po->imsi, imsi, sizeof(struct tel_sim_imsi));
-
- return TRUE;
-}
-
-struct tel_sim_msisdn_list *tcore_sim_get_msisdn_list(CoreObject *o)
-{
- struct private_object_data *po = NULL;
-
- po = tcore_object_ref_object(o);
- if (!po) {
- dbg("po access fail");
- return NULL;
- } else if (!po->msisdn_list) {
- dbg("po->msisdn_list is NULL");
- return NULL;
- }
-
- return g_memdup(po->msisdn_list, sizeof(struct tel_sim_msisdn_list));
-}
-
-gboolean tcore_sim_set_msisdn_list(CoreObject *o, const struct tel_sim_msisdn_list *msisdn_list)
-{
- struct private_object_data *po = NULL;
-
- po = tcore_object_ref_object(o);
- if (!po) {
- dbg("po access fail");
- return FALSE;
- }
-
- if (po->msisdn_list) {
- if (msisdn_list)
- memcpy(po->msisdn_list, msisdn_list, sizeof(struct tel_sim_msisdn_list));
- else
- memset(po->msisdn_list, 0x0, sizeof(struct tel_sim_msisdn_list));
- } else {
- if (msisdn_list)
- po->msisdn_list = g_memdup(msisdn_list, sizeof(struct tel_sim_msisdn_list));
- else
- po->msisdn_list = g_malloc0(sizeof(struct tel_sim_msisdn_list));
- }
-
- return TRUE;
-}
-
-enum tcore_return tcore_sim_delete_msisdn_list(CoreObject *o)
-{
- struct private_object_data *po = NULL;
-
- po = tcore_object_ref_object(o);
- if (!po) {
- dbg("po access fail");
- return TCORE_RETURN_EINVAL;
- }
-
- if (po->msisdn_list) {
- free(po->msisdn_list);
- po->msisdn_list = NULL;
- }
-
- return TCORE_RETURN_SUCCESS;
-}
-
-struct tel_sim_service_table *tcore_sim_get_service_table(CoreObject *o)
-{
- struct private_object_data *po = NULL;
-
- po = tcore_object_ref_object(o);
- if (!po) {
- dbg("po access fail");
- return NULL;
- } else if (!po->svct) {
- dbg("po->svct is NULL.");
- return NULL;
- }
-
- return g_memdup(po->svct, sizeof(struct tel_sim_service_table));
-}
-
-gboolean tcore_sim_set_service_table(CoreObject *o, const struct tel_sim_service_table *svct)
-{
- struct private_object_data *po = NULL;
-
- po = tcore_object_ref_object(o);
- if (!po) {
- dbg("po access fail");
- return FALSE;
- }
-
- if (po->svct) {
- if (svct)
- memcpy(po->svct, svct, sizeof(struct tel_sim_service_table));
- else
- memset(po->svct, 0x0, sizeof(struct tel_sim_service_table));
- } else {
- if (svct)
- po->svct = g_memdup(svct, sizeof(struct tel_sim_service_table));
- else
- po->svct = g_malloc0(sizeof(struct tel_sim_service_table));
- }
-
- return TRUE;
-}
-
-enum tcore_return tcore_sim_delete_service_table(CoreObject *o)
-{
- struct private_object_data *po = NULL;
-
- po = tcore_object_ref_object(o);
- if (!po) {
- dbg("po access fail");
- return TCORE_RETURN_EINVAL;
- }
-
- if (po->svct) {
- free(po->svct);
- po->svct = NULL;
- }
-
- return TCORE_RETURN_SUCCESS;
-}
-
-gboolean tcore_sim_get_cphs_status(CoreObject *o)
-{
- struct private_object_data *po = NULL;
-
- po = tcore_object_ref_object(o);
- if (!po) {
- dbg("po access fail");
- return FALSE;
- }
-
- return po->b_cphs;
-}
-
-gboolean tcore_sim_set_cphs_status(CoreObject *o, gboolean b_support)
-{
- struct private_object_data *po = NULL;
-
- po = tcore_object_ref_object(o);
- if (!po) {
- dbg("po access fail");
- return FALSE;
- }
-
- po->b_cphs = b_support;
-
- return TRUE;
-}
-
-struct tel_sim_cphs_csp *tcore_sim_get_csp(CoreObject *o)
-{
- struct private_object_data *po = NULL;
-
- po = tcore_object_ref_object(o);
- if (!po) {
- dbg("po access fail");
- return NULL;
- } else if (!po->csp) {
- dbg("po->csp is NULL");
- return NULL;
- }
-
- return g_memdup(po->csp, sizeof(struct tel_sim_cphs_csp));
-}
-
-gboolean tcore_sim_set_csp(CoreObject *o, const struct tel_sim_cphs_csp *csp)
-{
- struct private_object_data *po = NULL;
-
- po = tcore_object_ref_object(o);
- if (!po) {
- dbg("po access fail");
- return FALSE;
- }
-
- if (po->csp) {
- if (csp)
- memcpy(po->csp, csp, sizeof(struct tel_sim_cphs_csp));
- else
- memset(po->csp, 0x0, sizeof(struct tel_sim_cphs_csp));
- } else {
- if (csp)
- po->csp = g_memdup(csp, sizeof(struct tel_sim_cphs_csp));
- else
- po->csp = g_malloc0(sizeof(struct tel_sim_cphs_csp));
- }
-
- return TRUE;
-}
-
-gboolean tcore_sim_delete_csp(CoreObject *o)
-{
- struct private_object_data *po = NULL;
-
- po = tcore_object_ref_object(o);
- if (!po) {
- dbg("po access fail");
- return FALSE;
- }
-
- if (po->csp) {
- free(po->csp);
- po->csp = NULL;
- }
-
- return TRUE;
-}
-
-struct tel_sim_ecc_list *tcore_sim_get_ecc_list(CoreObject *o)
-{
- struct private_object_data *po = NULL;
-
- po = tcore_object_ref_object(o);
- if (!po) {
- dbg("po access fail");
- return NULL;
- } else if (!po->ecc_list) {
- dbg("po->ecc_list is NULL");
- return NULL;
- }
-
- return g_memdup(po->ecc_list, sizeof(struct tel_sim_ecc_list));
-}
-
-gboolean tcore_sim_set_ecc_list(CoreObject *o, const struct tel_sim_ecc_list *ecc_list)
-{
- struct private_object_data *po = NULL;
-
- po = tcore_object_ref_object(o);
- if (!po) {
- dbg("po access fail");
- return FALSE;
- }
-
- if (po->ecc_list) {
- if (ecc_list)
- memcpy(po->ecc_list, ecc_list, sizeof(struct tel_sim_ecc_list));
- else
- memset(po->ecc_list, 0x0, sizeof(struct tel_sim_ecc_list));
- } else {
- if (ecc_list)
- po->ecc_list = g_memdup(ecc_list, sizeof(struct tel_sim_ecc_list));
- else
- po->ecc_list = g_malloc0(sizeof(struct tel_sim_ecc_list));
- }
-
- return TRUE;
-}
-
-enum tcore_return tcore_sim_delete_ecc_list(CoreObject *o)
-{
- struct private_object_data *po = NULL;
-
- po = tcore_object_ref_object(o);
- if (!po) {
- dbg("po access fail");
- return TCORE_RETURN_EINVAL;
- }
-
- if (po->ecc_list) {
- free(po->ecc_list);
- po->ecc_list = NULL;
- }
-
- return TCORE_RETURN_SUCCESS;
-}
-
-struct tel_sim_spn *tcore_sim_get_spn(CoreObject *o)
-{
- struct private_object_data *po = NULL;
-
- po = tcore_object_ref_object(o);
- if (!po) {
- dbg("po access fail");
- return NULL;
- } else if (!po->spn) {
- dbg("po->spn is NULL");
- return NULL;
- }
-
- return g_memdup(po->spn, sizeof(struct tel_sim_spn));
-}
-
-gboolean tcore_sim_set_spn(CoreObject *o, const struct tel_sim_spn *spn)
-{
- struct private_object_data *po = NULL;
-
- po = tcore_object_ref_object(o);
- if (!po) {
- dbg("po access fail");
- return FALSE;
- }
-
- if (po->spn) {
- if (spn)
- memcpy(po->spn, spn, sizeof(struct tel_sim_spn));
- else
- memset(po->spn, 0x0, sizeof(struct tel_sim_spn));
- } else {
- if (spn)
- po->spn = g_memdup(spn, sizeof(struct tel_sim_spn));
- else
- po->spn = g_malloc0(sizeof(struct tel_sim_spn));
- }
-
- return TRUE;
-}
-
-enum tcore_return tcore_sim_delete_spn(CoreObject *o)
-{
- struct private_object_data *po = NULL;
-
- po = tcore_object_ref_object(o);
- if (!po) {
- dbg("po access fail");
- return TCORE_RETURN_EINVAL;
- }
-
- if (po->spn) {
- free(po->spn);
- po->spn = NULL;
- }
-
- return TCORE_RETURN_SUCCESS;
-}
-
-struct tel_sim_cphs_netname *tcore_sim_get_cphs_netname(CoreObject *o)
-{
- struct private_object_data *po = NULL;
-
- po = tcore_object_ref_object(o);
- if (!po) {
- dbg("po access fail");
- return NULL;
- } else if (!po->cphs_netname) {
- dbg("po->cphs_netname is NULL");
- return NULL;
- }
-
- return g_memdup(po->cphs_netname, sizeof(struct tel_sim_cphs_netname));
-}
-
-gboolean tcore_sim_set_cphs_netname(CoreObject *o, const struct tel_sim_cphs_netname *cphs_netname)
-{
- struct private_object_data *po = NULL;
-
- po = tcore_object_ref_object(o);
- if (!po) {
- dbg("po access fail");
- return FALSE;
- }
-
- if (po->cphs_netname) {
- if (cphs_netname)
- memcpy(po->cphs_netname, cphs_netname, sizeof(struct tel_sim_cphs_netname));
- else
- memset(po->cphs_netname, 0x0, sizeof(struct tel_sim_cphs_netname));
- } else {
- if (cphs_netname)
- po->cphs_netname = g_memdup(cphs_netname, sizeof(struct tel_sim_cphs_netname));
- else
- po->cphs_netname = g_malloc0(sizeof(struct tel_sim_cphs_netname));
- }
-
- return TRUE;
-}
-
-enum tcore_return tcore_sim_delete_cphs_netname(CoreObject *o)
-{
- struct private_object_data *po = NULL;
-
- po = tcore_object_ref_object(o);
- if (!po) {
- dbg("po access fail");
- return TCORE_RETURN_EINVAL;
- }
-
- if (po->cphs_netname) {
- free(po->cphs_netname);
- po->cphs_netname = NULL;
- }
-
- return TCORE_RETURN_SUCCESS;
-}
-
-struct tel_sim_iccid *tcore_sim_get_iccid(CoreObject *o)
-{
- struct private_object_data *po = NULL;
-
- po = tcore_object_ref_object(o);
- if (!po) {
- dbg("po access fail");
- return NULL;
- } else if (!po->iccid) {
- dbg("po->iccid is NULL");
- return NULL;
- }
-
- return g_memdup(po->iccid, sizeof(struct tel_sim_iccid));
-}
-
-gboolean tcore_sim_set_iccid(CoreObject *o, const struct tel_sim_iccid *iccid)
-{
- struct private_object_data *po = NULL;
-
- po = tcore_object_ref_object(o);
- if (!po) {
- dbg("po access fail");
- return FALSE;
- }
-
- if (po->iccid) {
- if (iccid)
- memcpy(po->iccid, iccid, sizeof(struct tel_sim_iccid));
- else
- memset(po->iccid, 0x0, sizeof(struct tel_sim_iccid));
- } else {
- if (iccid)
- po->iccid = g_memdup(iccid, sizeof(struct tel_sim_iccid));
- else
- po->iccid = g_malloc0(sizeof(struct tel_sim_iccid));
- }
-
- return TRUE;
-}
-
-enum tcore_return tcore_sim_delete_iccid(CoreObject *o)
-{
- struct private_object_data *po = NULL;
-
- po = tcore_object_ref_object(o);
- if (!po) {
- dbg("po access fail");
- return TCORE_RETURN_EINVAL;
- }
-
- if (po->iccid) {
- free(po->iccid);
- po->iccid = NULL;
- }
-
- return TCORE_RETURN_SUCCESS;
-}
-
-gboolean tcore_sim_link_userdata(CoreObject *o, void *userdata)
-{
- struct private_object_data *po = NULL;
-
- po = tcore_object_ref_object(o);
- if (!po) {
- dbg("po access fail");
- return FALSE;
- }
-
- po->userdata = userdata;
-
- return TRUE;
-}
-
-void *tcore_sim_ref_userdata(CoreObject *o)
-{
- struct private_object_data *po = NULL;
-
- po = tcore_object_ref_object(o);
- if (!po || !po->userdata) {
- dbg("po access fail");
- return NULL;
- }
-
- return po->userdata;
-}
-
-static void tcore_sim_initialize_context(CoreObject *o)
-{
- struct tcore_sim_operations *tmp_ops = NULL;
- struct private_object_data *po = NULL;
-
- po = tcore_object_ref_object(o);
- if (!po) {
- dbg("po access fail");
- return;
- }
-
- /* set ops to default type when core object is created. */
- tmp_ops = po->ops[TCORE_OPS_TYPE_CP];
-
- memset(po, 0x00, sizeof(struct private_object_data));
- po->ops[TCORE_OPS_TYPE_CP] = tmp_ops;
- po->sim_status = SIM_STATUS_UNKNOWN;
-}
-
-unsigned char tcore_sim_get_app_list(CoreObject *o)
-{
- struct private_object_data *po = NULL;
-
- po = tcore_object_ref_object(o);
- if (!po) {
- err("po access fail");
- return 0;
- }
-
- return po->app_list;
-}
-
-gboolean tcore_sim_set_app_list(CoreObject *o, unsigned char app_list)
-{
- struct private_object_data *po = NULL;
-
- po = tcore_object_ref_object(o);
- if (!po) {
- err("po access fail");
- return FALSE;
- }
-
- po->app_list = app_list;
-
- return TRUE;
-}
-
-struct tel_sim_ist *tcore_sim_get_isim_service_table(CoreObject *o)
-{
- struct private_object_data *po = NULL;
-
- po = tcore_object_ref_object(o);
- if (!po) {
- err("po access fail");
- return NULL;
- }
-
- if (!po->ist) {
- err("po->ist is NULL");
- return NULL;
- }
-
- return g_memdup(po->ist, sizeof(struct tel_sim_ist));
-}
-
-gboolean tcore_sim_set_isim_service_table(CoreObject *o, struct tel_sim_ist *ist)
-{
- struct private_object_data *po = NULL;
-
- po = tcore_object_ref_object(o);
- if (!po) {
- err("po access fail");
- return FALSE;
- }
-
- if (!ist) {
- err("ist is NULL");
- return FALSE;
- }
-
- if (po->ist)
- memcpy(po->ist, ist, sizeof(struct tel_sim_ist));
- else
- po->ist = g_memdup(ist, sizeof(struct tel_sim_ist));
-
- return TRUE;
-}
-
-enum tcore_return tcore_sim_delete_isim_service_table(CoreObject *o)
-{
- struct private_object_data *po = NULL;
- po = tcore_object_ref_object(o);
- if (!po) {
- err("po access fail");
- return TCORE_RETURN_EINVAL;
- }
-
- if (po->ist) {
- free(po->ist);
- po->ist = NULL;
- }
-
- return TCORE_RETURN_SUCCESS;
-}
-
-CoreObject *tcore_sim_new(TcorePlugin *p, const char *name,
- struct tcore_sim_operations *ops, TcoreHal *hal)
-{
- CoreObject *o = NULL;
- struct private_object_data *po = NULL;
-
- if (!p)
- return NULL;
-
- o = tcore_object_new(p, name, hal);
- if (!o)
- return NULL;
-
- po = calloc(1, sizeof(struct private_object_data));
- if (!po) {
- tcore_object_free(o);
- return NULL;
- }
-
- /* set ops to default type when core object is created. */
- po->ops[TCORE_OPS_TYPE_CP] = ops;
-
- tcore_object_set_type(o, CORE_OBJECT_TYPE_SIM);
- tcore_object_link_object(o, po);
- tcore_object_set_free_hook(o, _free_hook);
- tcore_object_set_dispatcher(o, _dispatcher);
-
- tcore_sim_initialize_context(o);
-
- return o;
-}
-
-void tcore_sim_free(CoreObject *o)
-{
- CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_SIM);
- tcore_object_free(o);
-}
-
-void tcore_sim_set_ops(CoreObject *o, struct tcore_sim_operations *ops, enum tcore_ops_type ops_type)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_SIM);
- CORE_OBJECT_VALIDATE_OPS_RETURN(ops_type);
-
- po = (struct private_object_data *)tcore_object_ref_object(o);
- if (!po) {
- err("po is NULL");
- return;
- }
-
- po->ops[ops_type] = ops;
-}
+++ /dev/null
-/*
- * libtcore
- *
- * 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.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <glib.h>
-
-#include "tcore.h"
-#include "internal/tcore_types.h"
-#include "plugin.h"
-#include "user_request.h"
-#include "co_sms.h"
-
-struct private_object_data {
- struct tcore_sms_operations *ops[TCORE_OPS_TYPE_MAX];
- enum telephony_sms_ready_status SmsReadyStatus;
-};
-
-int _tcore_util_sms_encode_smsParameters(const struct telephony_sms_Params *incoming,
- unsigned char *data, int SMSPRecordLen)
-{
- struct telephony_sms_Params *smsParams = (struct telephony_sms_Params *)incoming;
- unsigned int nPIDIndex = 0;
- unsigned char nOffset = 0;
-
- if (incoming == NULL || data == NULL)
- return FALSE;
-
- memset(data, 0xff, SMSPRecordLen);
-
- dbg(" Record index = %d", (int) smsParams->recordIndex);
- dbg(" Alpha ID Len = %d", (int) smsParams->alphaIdLen);
- dbg(" Record Length : %d", SMSPRecordLen);
-
- if (SMSPRecordLen/*pSmsParam->RecordLen*/>= nDefaultSMSPWithoutAlphaId)
- nPIDIndex = SMSPRecordLen /*pSmsParam->RecordLen*/- nDefaultSMSPWithoutAlphaId;
-
- /* dongil01.park(2008/12/27) - Check Point */
- memcpy(data, smsParams->szAlphaId, (int)nPIDIndex/*pSmsParam->AlphaIdLen*/);
-
- dbg(" Alpha ID : %s", smsParams->szAlphaId);
- dbg(" nPIDIndex = %d", nPIDIndex);
-
- data[nPIDIndex] = smsParams->paramIndicator;
-
- dbg(" Param Indicator = %02x", smsParams->paramIndicator);
-
- if ((smsParams->paramIndicator & SMSPValidDestAddr) == 0x00) {
- nOffset = nDestAddrOffset;
-
- data[nPIDIndex + (nOffset)] = smsParams->tpDestAddr.dialNumLen + 1;
- data[nPIDIndex + (++nOffset)] = ((smsParams->tpDestAddr.typeOfNum << 4) | smsParams->tpDestAddr.numPlanId) | 0x80;
-
- memcpy(&data[nPIDIndex + (++nOffset)], &smsParams->tpDestAddr.diallingNum, smsParams->tpDestAddr.dialNumLen);
-
- dbg(" nextIndex = %d", nPIDIndex);
- }
-
- if ((smsParams->paramIndicator & SMSPValidSvcAddr) == 0x00) {
- dbg("TON [%d] / NPI [%d]", smsParams->tpSvcCntrAddr.typeOfNum, smsParams->tpSvcCntrAddr.numPlanId);
-
- nOffset = nSCAAddrOffset;
-
- dbg("SCA Length : %d", smsParams->tpSvcCntrAddr.dialNumLen);
-
- data[nPIDIndex + (nOffset)] = smsParams->tpSvcCntrAddr.dialNumLen + 1;
- data[nPIDIndex + (++nOffset)] = ((smsParams->tpSvcCntrAddr.typeOfNum << 4) | smsParams->tpSvcCntrAddr.numPlanId) | 0x80;
-
- memcpy(&data[nPIDIndex + (++nOffset)], &smsParams->tpSvcCntrAddr.diallingNum, smsParams->tpSvcCntrAddr.dialNumLen);
-
- dbg(" nextIndex = %d", nPIDIndex);
- }
-
- if ((smsParams->paramIndicator & SMSPValidPID) == 0x00) {
- nOffset = nPIDOffset;
-
- data[nPIDIndex + nOffset] = smsParams->tpProtocolId;
- dbg(" PID = %02x", smsParams->tpProtocolId);
- dbg(" nextIndex = %d", nPIDIndex);
- }
-
- if ((smsParams->paramIndicator & SMSPValidDCS) == 0x00) {
- nOffset = nDCSOffset;
-
- data[nPIDIndex + nOffset] = smsParams->tpDataCodingScheme;
- dbg(" DCS = %02x", smsParams->tpDataCodingScheme);
- dbg(" nextIndex = %d", nPIDIndex);
- }
-
- if ((smsParams->paramIndicator & SMSPValidVP) == 0x00) {
- nOffset = nVPOffset;
-
- data[nPIDIndex + nOffset] = smsParams->tpValidityPeriod;
- dbg(" VP = %02x", smsParams->tpValidityPeriod);
- dbg(" nextIndex = %d", nPIDIndex);
- }
-
- return TRUE;
-
-}
-
-void tcore_util_sms_semioctet_to_octect(int *nScLength)
-{
- if (*nScLength % 2)
- *nScLength = (*nScLength / 2) + 1;
- else
- *nScLength = *nScLength / 2;
-}
-
-int tcore_util_sms_decode_smsParameters(uint8_t *incoming, uint32_t 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");
- }
-
- /* dongil01.park - start parse from here. */
- params->paramIndicator = incoming[alpha_id_len];
-
- dbg(" Param Indicator = %02x", params->paramIndicator);
-
- /* dongil01.park(2008/12/26) - DestAddr */
- if ((params->paramIndicator & SMSPValidDestAddr) == 0) {
- nOffset = nDestAddrOffset;
-
- if (0x00 == incoming[alpha_id_len + nOffset] || 0xff == incoming[alpha_id_len + nOffset]) {
- params->tpDestAddr.dialNumLen = 0;
-
- dbg("DestAddr Length is 0");
- } else {
- if (0 < (int)incoming[alpha_id_len + nOffset]) {
- params->tpDestAddr.dialNumLen = (int)(incoming[alpha_id_len + nOffset] - 1);
-
- if (params->tpDestAddr.dialNumLen > SMS_SMSP_ADDRESS_LEN)
- params->tpDestAddr.dialNumLen = SMS_SMSP_ADDRESS_LEN;
- } else {
- params->tpDestAddr.dialNumLen = 0;
- }
-
- params->tpDestAddr.numPlanId = incoming[alpha_id_len + (++nOffset)] & 0x0f ;
- params->tpDestAddr.typeOfNum = (incoming[alpha_id_len + nOffset] & 0x70)>>4 ;
-
- memcpy(params->tpDestAddr.diallingNum, &incoming[alpha_id_len + (++nOffset)], (params->tpDestAddr.dialNumLen)) ;
-
- dbg("Dest TON is %d", params->tpDestAddr.typeOfNum);
- dbg("Dest NPI is %d", params->tpDestAddr.numPlanId);
- dbg("Dest Length = %d", params->tpDestAddr.dialNumLen);
- dbg("Dest Addr = %s", params->tpDestAddr.diallingNum);
- }
- }
-
- /* dongil01.park(2008/12/26) - SvcAddr */
- if ((params->paramIndicator & SMSPValidSvcAddr) == 0) {
- nOffset = nSCAAddrOffset;
-
- if (0x00 == (int)incoming[alpha_id_len + nOffset] || 0xff == (int)incoming[alpha_id_len + nOffset]) {
- params->tpSvcCntrAddr.dialNumLen = 0;
-
- dbg(" SCAddr Length is 0");
- } else {
- if (0 < (int)incoming[alpha_id_len + nOffset]) {
- params->tpSvcCntrAddr.dialNumLen = (int)(incoming[alpha_id_len + nOffset] - 1);
-
- if (params->tpSvcCntrAddr.dialNumLen > SMS_SMSP_ADDRESS_LEN)
- params->tpSvcCntrAddr.dialNumLen = SMS_SMSP_ADDRESS_LEN;
-
- params->tpSvcCntrAddr.numPlanId = incoming[alpha_id_len + (++nOffset)] & 0x0f ;
- params->tpSvcCntrAddr.typeOfNum = (incoming[alpha_id_len + nOffset] & 0x70) >> 4;
-
- memcpy(params->tpSvcCntrAddr.diallingNum, &incoming[alpha_id_len + (++nOffset)], (params->tpSvcCntrAddr.dialNumLen));
-
- dbg("SCAddr Length = %d ", params->tpSvcCntrAddr.dialNumLen);
- dbg("SCAddr TON is %d", params->tpSvcCntrAddr.typeOfNum);
- dbg("SCAddr NPI is %d", params->tpSvcCntrAddr.numPlanId);
-
- for (i = 0 ; i < (int)params->tpSvcCntrAddr.dialNumLen ; i++)
- dbg("SCAddr = %d [%02x]", i, params->tpSvcCntrAddr.diallingNum[i]);
- } else
- params->tpSvcCntrAddr.dialNumLen = 0;
- }
- } else if ((0x00 < (int)incoming[alpha_id_len + nSCAAddrOffset]
- && (int)incoming[alpha_id_len + nSCAAddrOffset] <= 12)
- || 0xff != (int)incoming[alpha_id_len + nSCAAddrOffset]) {
- nOffset = nSCAAddrOffset;
-
- if (0x00 == (int)incoming[alpha_id_len + nOffset] || 0xff == (int)incoming[alpha_id_len + nOffset]) {
- params->tpSvcCntrAddr.dialNumLen = 0;
- dbg("SCAddr Length is 0");
- } else {
-
- if (0 < (int)incoming[alpha_id_len + nOffset]) {
- params->tpSvcCntrAddr.dialNumLen = (int)(incoming[alpha_id_len + nOffset] - 1);
-
- params->tpSvcCntrAddr.dialNumLen = incoming[alpha_id_len + nOffset] - 1;
-
- if (params->tpSvcCntrAddr.dialNumLen > SMS_SMSP_ADDRESS_LEN)
- params->tpSvcCntrAddr.dialNumLen = SMS_SMSP_ADDRESS_LEN;
-
- params->tpSvcCntrAddr.numPlanId = incoming[alpha_id_len + (++nOffset)] & 0x0f ;
- params->tpSvcCntrAddr.typeOfNum = (incoming[alpha_id_len + nOffset] & 0x70) >> 4;
-
- memcpy(params->tpSvcCntrAddr.diallingNum, &incoming[alpha_id_len + (++nOffset)],
- (params->tpSvcCntrAddr.dialNumLen)) ;
-
- dbg("SCAddr Length = %d ", params->tpSvcCntrAddr.dialNumLen);
- dbg("SCAddr TON is %d", params->tpSvcCntrAddr.typeOfNum);
- dbg("SCAddr NPI is %d", params->tpSvcCntrAddr.numPlanId);
-
- for (i = 0 ; i < (int)params->tpSvcCntrAddr.dialNumLen ; i++)
- dbg("SCAddr = %d [%02x]", i, params->tpSvcCntrAddr.diallingNum[i]);
- } else
- params->tpSvcCntrAddr.dialNumLen = 0;
- }
-
- }
-
- if ((params->paramIndicator & SMSPValidPID) == 0
- && (alpha_id_len + nPIDOffset) < SMS_MAX_EFSMSP_RECORD_LENGTH)
- params->tpProtocolId = incoming[alpha_id_len + nPIDOffset];
-
- if ((params->paramIndicator & SMSPValidDCS) == 0
- && (alpha_id_len + nDCSOffset) < SMS_MAX_EFSMSP_RECORD_LENGTH)
- params->tpDataCodingScheme = incoming[alpha_id_len + nDCSOffset];
-
- if ((params->paramIndicator & SMSPValidVP) == 0
- && (alpha_id_len + nVPOffset) < SMS_MAX_EFSMSP_RECORD_LENGTH)
- params->tpValidityPeriod = incoming[alpha_id_len + nVPOffset];
-
- dbg(" Alpha Id(Len) = %d", (int)params->alphaIdLen);
-
- for (i = 0; i < (int)params->alphaIdLen ; i++)
- dbg(" Alpha Id = [%d] [%c]", i, params->szAlphaId[i]);
-
- dbg(" PID = %d", params->tpProtocolId);
- dbg(" DCS = %d", params->tpDataCodingScheme);
- dbg(" VP = %d", params->tpValidityPeriod);
-
- return TRUE;
-}
-
-
-static TReturn _dispatcher(CoreObject *o, UserRequest *ur, enum tcore_ops_type ops_type)
-{
- enum tcore_request_command command;
- struct private_object_data *po = tcore_object_ref_object(o);
- struct tcore_sms_operations *ops = NULL;
- TReturn rtn = TCORE_RETURN_SUCCESS;
-
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_SMS, TCORE_RETURN_EINVAL);
- CORE_OBJECT_VALIDATE_OPS_RETURN_VAL(ops_type, TCORE_RETURN_EINVAL);
-
- tcore_check_null_ret_err("po", po, TCORE_RETURN_EINVAL);
- tcore_check_null_ret_err("ur", ur, TCORE_RETURN_EINVAL);
-
- if (po->SmsReadyStatus == SMS_READY_STATUS_NONE) {
- dbg("[tcore_SMS] DEVICE_NOT_READY");
- return TCORE_RETURN_ENOSYS; /* TAPI_API_NETTEXT_DEVICE_NOT_READY */
- }
-
- ops = po->ops[ops_type];
- tcore_check_null_ret_err("ops", ops, TCORE_RETURN_FAILURE);
-
- command = tcore_user_request_get_command(ur);
- switch (command) {
- case TREQ_SMS_SEND_UMTS_MSG:
- tcore_check_null_ret_err("ops->send_umts_msg",
- ops->send_umts_msg, TCORE_RETURN_ENOSYS);
-
- rtn = ops->send_umts_msg(o, ur);
- break;
-
- case TREQ_SMS_READ_MSG:
- tcore_check_null_ret_err("ops->connect",
- ops->read_msg, TCORE_RETURN_ENOSYS);
-
- rtn = ops->read_msg(o, ur);
- break;
-
- case TREQ_SMS_SAVE_MSG:
- tcore_check_null_ret_err("ops->save_msg",
- ops->save_msg, TCORE_RETURN_ENOSYS);
-
- rtn = ops->save_msg(o, ur);
- break;
-
- case TREQ_SMS_DELETE_MSG:
- tcore_check_null_ret_err("ops->delete_msg",
- ops->delete_msg, TCORE_RETURN_ENOSYS);
-
- rtn = ops->delete_msg(o, ur);
- break;
-
- case TREQ_SMS_GET_COUNT:
- tcore_check_null_ret_err("ops->get_storedMsgCnt",
- ops->get_storedMsgCnt, TCORE_RETURN_ENOSYS);
-
- rtn = ops->get_storedMsgCnt(o, ur);
- break;
-
- case TREQ_SMS_GET_SCA:
- tcore_check_null_ret_err("ops->get_sca",
- ops->get_sca, TCORE_RETURN_ENOSYS);
-
- rtn = ops->get_sca(o, ur);
- break;
-
- case TREQ_SMS_SET_SCA:
- tcore_check_null_ret_err("ops->set_sca",
- ops->set_sca, TCORE_RETURN_ENOSYS);
-
- rtn = ops->set_sca(o, ur);
- break;
-
- case TREQ_SMS_GET_CB_CONFIG:
- tcore_check_null_ret_err("ops->get_cb_config",
- ops->get_cb_config, TCORE_RETURN_ENOSYS);
-
- rtn = ops->get_cb_config(o, ur);
- break;
-
- case TREQ_SMS_SET_CB_CONFIG:
- tcore_check_null_ret_err("ops->set_cb_config",
- ops->set_cb_config, TCORE_RETURN_ENOSYS);
-
- rtn = ops->set_cb_config(o, ur);
- break;
-
- case TREQ_SMS_SET_MEM_STATUS:
- tcore_check_null_ret_err("ops->set_mem_status",
- ops->set_mem_status, TCORE_RETURN_ENOSYS);
-
- rtn = ops->set_mem_status(o, ur);
- break;
-
- case TREQ_SMS_GET_PREF_BEARER:
- tcore_check_null_ret_err("ops->get_pref_brearer",
- ops->get_pref_brearer, TCORE_RETURN_ENOSYS);
-
- rtn = ops->get_pref_brearer(o, ur);
- break;
-
- case TREQ_SMS_SET_PREF_BEARER:
- tcore_check_null_ret_err("ops->set_pref_brearer",
- ops->set_pref_brearer, TCORE_RETURN_ENOSYS);
-
- rtn = ops->set_pref_brearer(o, ur);
- break;
-
- case TREQ_SMS_SET_DELIVERY_REPORT:
- tcore_check_null_ret_err("ops->set_delivery_report",
- ops->set_delivery_report, TCORE_RETURN_ENOSYS);
-
- rtn = ops->set_delivery_report(o, ur);
- break;
-
- case TREQ_SMS_SET_MSG_STATUS:
- tcore_check_null_ret_err("ops->set_msg_status",
- ops->set_msg_status, TCORE_RETURN_ENOSYS);
-
- rtn = ops->set_msg_status(o, ur);
- break;
-
- case TREQ_SMS_GET_PARAMS:
- tcore_check_null_ret_err("ops->get_sms_params",
- ops->get_sms_params, TCORE_RETURN_ENOSYS);
-
- rtn = ops->get_sms_params(o, ur);
- break;
-
- case TREQ_SMS_SET_PARAMS:
- tcore_check_null_ret_err("ops->set_sms_params",
- ops->set_sms_params, TCORE_RETURN_ENOSYS);
-
- rtn = ops->set_sms_params(o, ur);
- break;
-
- case TREQ_SMS_GET_PARAMCNT:
- tcore_check_null_ret_err("ops->get_paramcnt",
- ops->get_paramcnt, TCORE_RETURN_ENOSYS);
-
- rtn = ops->get_paramcnt(o, ur);
- break;
-
- case TREQ_SMS_SEND_CDMA_MSG:
- tcore_check_null_ret_err("ops->send_cdma_msg",
- ops->send_cdma_msg, TCORE_RETURN_ENOSYS);
-
- rtn = ops->send_cdma_msg(o, ur);
- break;
-
- default:
- break;
- }
-
- dbg("[tcore_SMS] result = [0x%x], command = [0x%x]", rtn, command);
-
- return rtn;
-}
-
-static void _free_hook(CoreObject *o)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_SMS);
-
- po = tcore_object_ref_object(o);
- if (po) {
- free(po);
- tcore_object_link_object(o, NULL);
- }
-}
-
-enum telephony_sms_ready_status tcore_sms_get_ready_status(CoreObject *o)
-{
- struct private_object_data *po = NULL;
- po = tcore_object_ref_object(o);
- if (!po) {
- dbg("po access fail");
- return SMS_READY_STATUS_NONE;
- }
-
- return po->SmsReadyStatus;
-}
-
-gboolean tcore_sms_set_ready_status(CoreObject *o, enum telephony_sms_ready_status status)
-{
- struct private_object_data *po = NULL;
- po = tcore_object_ref_object(o);
- if (!po) {
- dbg("po access fail");
- return FALSE;
- }
-
- po->SmsReadyStatus = status;
-
- return TRUE;
-}
-
-CoreObject *tcore_sms_new(TcorePlugin *p, const char *name,
- struct tcore_sms_operations *ops, TcoreHal *hal)
-{
- CoreObject *o = NULL;
- struct private_object_data *po = NULL;
-
- if (!p)
- return NULL;
-
- o = tcore_object_new(p, name, hal);
- if (!o)
- return NULL;
-
- po = calloc(1, sizeof(struct private_object_data));
- if (!po) {
- tcore_object_free(o);
- return NULL;
- }
-
- /* set ops to default type when core object is created. */
- po->ops[TCORE_OPS_TYPE_CP] = ops;
-
- tcore_object_set_type(o, CORE_OBJECT_TYPE_SMS);
- tcore_object_link_object(o, po);
- tcore_object_set_free_hook(o, _free_hook);
- tcore_object_set_dispatcher(o, _dispatcher);
-
- return o;
-}
-
-void tcore_sms_free(CoreObject *o)
-{
- CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_SMS);
- tcore_object_free(o);
-}
-
-void tcore_sms_set_ops(CoreObject *o, struct tcore_sms_operations *ops, enum tcore_ops_type ops_type)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_SMS);
- CORE_OBJECT_VALIDATE_OPS_RETURN(ops_type);
-
- po = (struct private_object_data *)tcore_object_ref_object(o);
- if (!po) {
- err("po is NULL");
- return;
- }
-
- po->ops[ops_type] = ops;
-}
+++ /dev/null
-/*
- * libtcore
- *
- * 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.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <glib.h>
-
-#include "tcore.h"
-#include "internal/tcore_types.h"
-#include "plugin.h"
-#include "queue.h"
-#include "user_request.h"
-#include "co_ss.h"
-
-struct ussd_session {
- gboolean session;
- enum tcore_ss_ussd_type type;
- void *data;
- int data_len;
-};
-
-struct ss_routing_policy {
- enum tcore_ss_routing_policy ss_routing_policy;
- enum tcore_ussd_routing_policy ussd_routing_policy;
-};
-
-struct private_object_data {
- struct tcore_ss_operations *ops[TCORE_OPS_TYPE_MAX];
-
- struct ussd_session ussd_s;
- struct ss_routing_policy routing_policy;
-};
-
-static TReturn _dispatcher(CoreObject *o, UserRequest *ur, enum tcore_ops_type ops_type)
-{
- enum tcore_request_command command;
- struct private_object_data *po = tcore_object_ref_object(o);
- struct tcore_ss_operations *ops = NULL;
- TReturn ret = 0;
-
- CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_SS, TCORE_RETURN_EINVAL);
- CORE_OBJECT_VALIDATE_OPS_RETURN_VAL(ops_type, TCORE_RETURN_EINVAL);
-
- tcore_check_null_ret_err("po", po, TCORE_RETURN_EINVAL);
- tcore_check_null_ret_err("ur", ur, TCORE_RETURN_EINVAL);
-
- ops = po->ops[ops_type];
- tcore_check_null_ret_err("ops", ops, TCORE_RETURN_FAILURE);
-
- command = tcore_user_request_get_command(ur);
- switch (command) {
- case TREQ_SS_BARRING_ACTIVATE:
- tcore_check_null_ret_err("ops->barring_activate",
- ops->barring_activate, TCORE_RETURN_ENOSYS);
-
- ret = ops->barring_activate(o, ur);
- break;
-
- case TREQ_SS_BARRING_DEACTIVATE:
- tcore_check_null_ret_err("ops->barring_deactivate",
- ops->barring_deactivate, TCORE_RETURN_ENOSYS);
-
- ret = ops->barring_deactivate(o, ur);
- break;
-
- case TREQ_SS_BARRING_CHANGE_PASSWORD:
- tcore_check_null_ret_err("ops->barring_change_password",
- ops->barring_change_password, TCORE_RETURN_ENOSYS);
-
- ret = ops->barring_change_password(o, ur);
- break;
-
- case TREQ_SS_BARRING_GET_STATUS:
- tcore_check_null_ret_err("ops->barring_get_status",
- ops->barring_get_status, TCORE_RETURN_ENOSYS);
-
- ret = ops->barring_get_status(o, ur);
- break;
-
- case TREQ_SS_FORWARDING_ACTIVATE:
- tcore_check_null_ret_err("ops->forwarding_activate",
- ops->forwarding_activate, TCORE_RETURN_ENOSYS);
-
- ret = ops->forwarding_activate(o, ur);
- break;
-
- case TREQ_SS_FORWARDING_DEACTIVATE:
- tcore_check_null_ret_err("ops->forwarding_deactivate",
- ops->forwarding_deactivate, TCORE_RETURN_ENOSYS);
-
- ret = ops->forwarding_deactivate(o, ur);
- break;
-
- case TREQ_SS_FORWARDING_REGISTER:
- tcore_check_null_ret_err("ops->forwarding_register",
- ops->forwarding_register, TCORE_RETURN_ENOSYS);
-
- ret = ops->forwarding_register(o, ur);
- break;
-
- case TREQ_SS_FORWARDING_DEREGISTER:
- tcore_check_null_ret_err("ops->forwarding_deregister",
- ops->forwarding_deregister, TCORE_RETURN_ENOSYS);
-
- ret = ops->forwarding_deregister(o, ur);
- break;
-
- case TREQ_SS_FORWARDING_GET_STATUS:
- tcore_check_null_ret_err("ops->forwarding_get_status",
- ops->forwarding_get_status, TCORE_RETURN_ENOSYS);
-
- ret = ops->forwarding_get_status(o, ur);
- break;
-
- case TREQ_SS_WAITING_ACTIVATE:
- tcore_check_null_ret_err("ops->waiting_activate",
- ops->waiting_activate, TCORE_RETURN_ENOSYS);
-
- ret = ops->waiting_activate(o, ur);
- break;
-
- case TREQ_SS_WAITING_DEACTIVATE:
- tcore_check_null_ret_err("ops->waiting_deactivate",
- ops->waiting_deactivate, TCORE_RETURN_ENOSYS);
-
- ret = ops->waiting_deactivate(o, ur);
- break;
-
- case TREQ_SS_WAITING_GET_STATUS:
- tcore_check_null_ret_err("ops->waiting_get_status",
- ops->waiting_get_status, TCORE_RETURN_ENOSYS);
-
- ret = ops->waiting_get_status(o, ur);
- break;
-
- case TREQ_SS_CLI_ACTIVATE:
- tcore_check_null_ret_err("ops->cli_activate",
- ops->cli_activate, TCORE_RETURN_ENOSYS);
-
- ret = ops->cli_activate(o, ur);
- break;
-
- case TREQ_SS_CLI_DEACTIVATE:
- tcore_check_null_ret_err("ops->cli_deactivate",
- ops->cli_deactivate, TCORE_RETURN_ENOSYS);
-
- ret = ops->cli_deactivate(o, ur);
- break;
-
- case TREQ_SS_CLI_SET_STATUS:
- tcore_check_null_ret_err("ops->cli_set_status",
- ops->cli_set_status, TCORE_RETURN_ENOSYS);
-
- ret = ops->cli_set_status(o, ur);
- break;
-
- case TREQ_SS_CLI_GET_STATUS:
- tcore_check_null_ret_err("ops->cli_get_status",
- ops->cli_get_status, TCORE_RETURN_ENOSYS);
-
- ret = ops->cli_get_status(o, ur);
- break;
-
- case TREQ_SS_SEND_USSD:
- tcore_check_null_ret_err("ops->send_ussd",
- ops->send_ussd, TCORE_RETURN_ENOSYS);
-
- ret = ops->send_ussd(o, ur);
- break;
-
- case TREQ_SS_SET_AOC:
- tcore_check_null_ret_err("ops->set_aoc",
- ops->set_aoc, TCORE_RETURN_ENOSYS);
-
- ret = ops->set_aoc(o, ur);
- break;
-
- case TREQ_SS_GET_AOC:
- tcore_check_null_ret_err("ops->get_aoc",
- ops->get_aoc, TCORE_RETURN_ENOSYS);
-
- ret = ops->get_aoc(o, ur);
- break;
-
- default:
- break;
- }
-
- return ret;
-}
-
-static void _free_hook(CoreObject *o)
-{
- struct private_object_data *po = NULL;
-
- po = tcore_object_ref_object(o);
- if (!po)
- return;
-
- free(po);
- tcore_object_link_object(o, NULL);
-}
-
-static void _ussd_session_init(struct ussd_session *ussd_s)
-{
- ussd_s->session = FALSE;
- ussd_s->type = 0;
- ussd_s->data = 0;
- ussd_s->data_len = 0;
-}
-
-struct ussd_session *tcore_ss_ussd_create_session(CoreObject *o,
- enum tcore_ss_ussd_type type, void *data, int data_len)
-{
- struct private_object_data *po = NULL;
-
- po = tcore_object_ref_object(o);
- if (!po)
- return 0;
-
- if (type < TCORE_SS_USSD_TYPE_USER_INITIATED
- || type > TCORE_SS_USSD_TYPE_NETWORK_INITIATED) {
- dbg("[ error ] wrong ussd type : (0x%x)", type);
- return 0;
- }
-
- if (!po->ussd_s.session) {
- po->ussd_s.session = TRUE;
- po->ussd_s.type = type;
- po->ussd_s.data = data;
-
- if (data_len < 0)
- po->ussd_s.data_len = 0;
- else
- po->ussd_s.data_len = data_len;
-
- return &po->ussd_s;
-
- } else {
- dbg("[ error ] already exist ussd session, type : (0x%x)", po->ussd_s.type);
- return 0;
- }
-}
-
-void tcore_ss_ussd_destroy_session(struct ussd_session *ussd_s)
-{
- if (!ussd_s || !ussd_s->session)
- return;
-
- _ussd_session_init(ussd_s);
-}
-
-struct ussd_session *tcore_ss_ussd_get_session(CoreObject *o)
-{
- struct private_object_data *po = NULL;
-
- po = tcore_object_ref_object(o);
- if (!po)
- return 0;
-
- if (!po->ussd_s.session)
- return 0;
- else
- return &po->ussd_s;
-}
-
-enum tcore_ss_ussd_type tcore_ss_ussd_get_session_type(struct ussd_session *ussd_s)
-{
- if (!ussd_s || !ussd_s->session) {
- dbg("[ error ] there is no session");
- return 0;
- }
-
- return ussd_s->type;
-}
-
-void tcore_ss_ussd_set_session_type(struct ussd_session *ussd_s,
- enum tcore_ss_ussd_type type)
-{
- if (!ussd_s || !ussd_s->session) {
- dbg("[ error ] there is no session");
- return;
- }
-
- ussd_s->type = type;
-}
-
-int tcore_ss_ussd_get_session_data(struct ussd_session *ussd_s, void **data)
-{
- if (!ussd_s || !ussd_s->session) {
- dbg("[ error ] there is no session");
- return -1;
- }
-
- *data = ussd_s->data;
- return ussd_s->data_len;
-}
-
-void tcore_ss_ussd_set_session_data(struct ussd_session *ussd_s, void *data, int data_len)
-{
- if (!ussd_s || !ussd_s->session) {
- dbg("[ error ] there is no session");
- return;
- }
-
- ussd_s->data = data;
- ussd_s->data_len = data_len;
-}
-
-void tcore_ss_set_ussd_routing(CoreObject *o, enum tcore_ussd_routing_policy ussd_routing_policy)
-{
- struct private_object_data *po = NULL;
-
- po = tcore_object_ref_object(o);
- if (!po)
- return;
-
- po->routing_policy.ussd_routing_policy = ussd_routing_policy;
-}
-
-enum tcore_ussd_routing_policy tcore_ss_get_ussd_routing(CoreObject *o)
-{
- struct private_object_data *po = NULL;
-
- po = tcore_object_ref_object(o);
- if (!po)
- return TCORE_SS_USSD_ROUTING_POLICY_CS_ALWAYS; /* 'default' to CS */
-
- return po->routing_policy.ussd_routing_policy;
-}
-
-void tcore_ss_set_ss_routing(CoreObject *o, enum tcore_ss_routing_policy ss_routing_policy)
-{
- struct private_object_data *po = NULL;
-
- po = tcore_object_ref_object(o);
- if (!po)
- return;
-
- po->routing_policy.ss_routing_policy = ss_routing_policy;
-}
-
-enum tcore_ss_routing_policy tcore_ss_get_ss_routing(CoreObject *o)
-{
- struct private_object_data *po = NULL;
-
- po = tcore_object_ref_object(o);
- if (!po)
- return TCORE_SS_ROUTING_POLICY_CS_ALWAYS; /* 'default' to CS */
-
- return po->routing_policy.ss_routing_policy;
-}
-
-CoreObject *tcore_ss_new(TcorePlugin *p, const char *name,
- struct tcore_ss_operations *ops, TcoreHal *hal)
-{
- CoreObject *o = NULL;
- struct private_object_data *po = NULL;
-
- if (!p)
- return NULL;
-
- o = tcore_object_new(p, name, hal);
- if (!o)
- return NULL;
-
- po = calloc(1, sizeof(struct private_object_data));
- if (!po) {
- tcore_object_free(o);
- return NULL;
- }
-
- /* set ops to default type when core object is created. */
- po->ops[TCORE_OPS_TYPE_CP] = ops;
- po->routing_policy.ss_routing_policy = TCORE_SS_ROUTING_POLICY_CS_ALWAYS; /* 'default' to CS */
- po->routing_policy.ussd_routing_policy = TCORE_SS_USSD_ROUTING_POLICY_CS_ALWAYS; /* 'default' to CS */
-
- _ussd_session_init(&po->ussd_s);
-
- tcore_object_set_type(o, CORE_OBJECT_TYPE_SS);
- tcore_object_link_object(o, po);
- tcore_object_set_free_hook(o, _free_hook);
- tcore_object_set_dispatcher(o, _dispatcher);
-
- return o;
-}
-
-void tcore_ss_free(CoreObject *o)
-{
- CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_SS);
-
- tcore_object_free(o);
-}
-
-void tcore_ss_set_ops(CoreObject *o, struct tcore_ss_operations *ops, enum tcore_ops_type ops_type)
-{
- struct private_object_data *po = NULL;
-
- CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_SS);
- CORE_OBJECT_VALIDATE_OPS_RETURN(ops_type);
-
- po = (struct private_object_data *)tcore_object_ref_object(o);
- if (!po) {
- err("po is NULL");
- return;
- }
-
- po->ops[ops_type] = ops;
-}
-
struct tcore_communicator_type {
char *name;
- struct tcore_communitor_operations *ops;
+ struct tcore_communicator_operations *ops;
void *user_data;
Communicator *tcore_communicator_new(TcorePlugin *plugin,
- const char *name, struct tcore_communitor_operations *ops)
+ const char *name, struct tcore_communicator_operations *ops)
{
Communicator *comm;
if (!comm || !comm->ops || !comm->ops->send_response)
return TCORE_RETURN_EINVAL;
- dbg("ur = 0x%x", ur);
+ dbg("ur: [%p]", ur);
return comm->ops->send_response(comm, ur, command, data_len, data);
}
+++ /dev/null
-/*
- * libtcore
- *
- * 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.
- */
-
-#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 "co_call.h"
-#include "co_modem.h"
-#include "co_ps.h"
-#include "co_network.h"
-#include "co_ss.h"
-#include "co_sim.h"
-#include "co_sat.h"
-#include "co_sap.h"
-#include "co_sms.h"
-#include "co_phonebook.h"
-#include "co_gps.h"
-
-struct callback_type {
- CoreObject *co;
- char *event;
- CoreObjectCallback callback;
- void *user_data;
-};
-
-struct tcore_object_type {
- unsigned int type;
- char *name;
-
- TcorePlugin *parent_plugin;
-
- void *object;
- void *user_data;
-
- CoreObjectFreeHook free_hook;
- CoreObjectDispatcher dispatcher;
- GSList *callbacks;
- GHashTable *property;
-
- TcoreHal *hal;
-};
-
-
-/* Mapping Table */
-struct tcore_object_mapping_tbl {
- TcoreHal *hal;
- GSList *object_type;
-};
-
-static void _util_print_mapping_tbl_entry(object_mapping_table_t *tbl_entry)
-{
- GSList *co_list;
-
- msg("------> Table Entry - HAL: [0x%x]", tbl_entry->hal);
-
- co_list = tbl_entry->object_type;
- if (co_list == NULL) {
- err("No Core Objects defined for this Mapping Table Entry");
- return;
- }
-
- /* Search all the Table entries with matching 'type' */
- for (; co_list ; co_list = co_list->next) {
- if (co_list->data == NULL)
- continue;
-
- msg(" Core Object type: [0x%x]", co_list->data);
- }
-}
-
-static void _free_tbl_entry(gpointer data)
-{
- object_mapping_table_t *tbl_entry;
-
- if (data == NULL)
- return;
-
- tbl_entry = data;
-
- dbg("Removing Mapping Table Entry - HAL: [0x%x]", tbl_entry->hal);
- _util_print_mapping_tbl_entry(tbl_entry);
-
- /* Free Core Object types list */
- g_slist_free(tbl_entry->object_type);
-
- /* Free Table entry */
- g_free(tbl_entry);
-}
-static CoreObject *_object_new(TcorePlugin *plugin, unsigned int type)
-{
- CoreObject *co;
-
- co = g_try_malloc0(sizeof(struct tcore_object_type));
- if (!co)
- return NULL;
-
- co->parent_plugin = plugin;
-
- co->type = type;
- co->property = g_hash_table_new_full(g_str_hash, g_str_equal, free, free);
-
- return co;
-}
-
-static gboolean _on_at_event(TcoreAT *at, const GSList *lines, void *user_data)
-{
- gboolean ret;
-
- struct callback_type *cb = user_data;
-
- ret = cb->callback(cb->co, lines, cb->user_data);
- if (ret == FALSE)
- err("Callback processing failed!");
-
- return ret;
-}
-
-static void _remove_at_callback(TcoreAT *at, struct callback_type *cb)
-{
- tcore_at_remove_notification_full(at, cb->event, _on_at_event, cb);
-}
-
-static object_mapping_table_t *_object_search_mapping_tbl_entry(GSList *mapping_tbl_list,
- TcoreHal *hal)
-{
- GSList *list;
- object_mapping_table_t *tbl_entry = NULL;
-
- for (list = mapping_tbl_list; list ; list = list->next) {
- tbl_entry = list->data;
- if (tbl_entry == NULL)
- continue;
-
- /* Search for Table entry with matching 'hal' */
- if (tbl_entry->hal == hal)
- return tbl_entry;
- }
-
- return NULL;
-}
-
-static object_mapping_table_t *_object_search_mapping_tbl_entry_by_type(
- GSList *mapping_tbl_list, unsigned int type)
-{
- GSList *list;
- GSList *co_list;
- object_mapping_table_t *tbl_entry = NULL;
-
- for (list = mapping_tbl_list; list ; list = list->next) {
- tbl_entry = list->data;
- if (tbl_entry == NULL)
- continue;
-
- /* Search all the Table entries with matching 'type' */
- for (co_list = tbl_entry->object_type ; co_list ; co_list = co_list->next) {
- if (co_list->data == NULL)
- continue;
-
- if (type == GPOINTER_TO_UINT(co_list->data))
- return tbl_entry;
- }
- }
-
- return tbl_entry;
-}
-
-static CoreObject *_create_core_object_by_type(guint type,
- TcorePlugin *plugin, TcoreHal *hal)
-{
- CoreObject *co = NULL;
-
- switch (type) {
- case CORE_OBJECT_TYPE_MODEM:
- /* Create Core Object */
- co = tcore_modem_new(plugin, "modem", NULL, hal);
- break;
-
- case CORE_OBJECT_TYPE_CALL:
- /* Create Core Object */
- co = tcore_call_new(plugin, "call", NULL, hal);
- break;
-
- case CORE_OBJECT_TYPE_SS:
- /* Create Core Object */
- co = tcore_ss_new(plugin, "ss", NULL, hal);
- break;
-
- case CORE_OBJECT_TYPE_NETWORK:
- /* Create Core Object */
- co = tcore_network_new(plugin, "network", NULL, hal);
- break;
-
- case CORE_OBJECT_TYPE_PS:
- /* Create Core Object */
- co = tcore_ps_new(plugin, "ps", NULL, hal);
- break;
-
- case CORE_OBJECT_TYPE_SIM:
- /* Create Core Object */
- co = tcore_sim_new(plugin, "sim", NULL, hal);
- break;
-
- case CORE_OBJECT_TYPE_SAT:
- /* Create Core Object */
- co = tcore_sat_new(plugin, "sat", NULL, hal);
- break;
-
- case CORE_OBJECT_TYPE_SAP:
- /* Create Core Object */
- co = tcore_sap_new(plugin, "sap", NULL, hal);
- break;
-
- case CORE_OBJECT_TYPE_SMS:
- /* Create Core Object */
- co = tcore_sms_new(plugin, "sms", NULL, hal);
- break;
-
- case CORE_OBJECT_TYPE_PHONEBOOK:
- /* Create Core Object */
- co = tcore_phonebook_new(plugin, "phonebook", NULL, hal);
- break;
-
- case CORE_OBJECT_TYPE_GPS:
- /* Create Core Object */
- co = tcore_gps_new(plugin, "gps", NULL, hal);
- break;
-
- case CORE_OBJECT_TYPE_CUSTOM: /* Fall through */
- default:
- err("Unsupport/Invalid Core Object Type [0x%x]", type);
- break;
- }
-
- return co;
-}
-
-
-static gboolean _init_core_object_by_type(unsigned int type,
- TcorePlugin *plugin, struct object_initializer *initializer_list)
-{
- gboolean ret = FALSE;
- CoreObject *co = tcore_plugin_ref_core_object(plugin, type);
- if (co == NULL) {
- err("No Core Object of type: [0x%x]", type);
- return FALSE;
- }
-
- switch (type) {
- case CORE_OBJECT_TYPE_MODEM: {
- /* Invoke initializer */
- if (initializer_list->modem_init)
- ret = initializer_list->modem_init(plugin, co);
- }
- break;
-
- case CORE_OBJECT_TYPE_CALL: {
- /* Invoke initializer */
- if (initializer_list->call_init)
- ret = initializer_list->call_init(plugin, co);
- }
- break;
-
- case CORE_OBJECT_TYPE_SS: {
- /* Invoke initializer */
- if (initializer_list->ss_init)
- ret = initializer_list->ss_init(plugin, co);
- }
- break;
-
- case CORE_OBJECT_TYPE_NETWORK: {
- /* Invoke initializer */
- if (initializer_list->network_init)
- ret = initializer_list->network_init(plugin, co);
- }
- break;
-
- case CORE_OBJECT_TYPE_PS: {
- /* Invoke initializer */
- if (initializer_list->ps_init)
- ret = initializer_list->ps_init(plugin, co);
- }
- break;
-
- case CORE_OBJECT_TYPE_SIM: {
- /* Invoke initializer */
- if (initializer_list->sim_init)
- ret = initializer_list->sim_init(plugin, co);
- }
- break;
-
- case CORE_OBJECT_TYPE_SAT: {
- /* Invoke initializer */
- if (initializer_list->sat_init)
- ret = initializer_list->sat_init(plugin, co);
- }
- break;
-
- case CORE_OBJECT_TYPE_SAP: {
- /* Invoke initializer */
- if (initializer_list->sap_init)
- ret = initializer_list->sap_init(plugin, co);
- }
- break;
-
- case CORE_OBJECT_TYPE_SMS:{
- /* Invoke initializer */
- if (initializer_list->sms_init)
- ret = initializer_list->sms_init(plugin, co);
- }
- break;
-
- case CORE_OBJECT_TYPE_PHONEBOOK: {
- /* Invoke initializer */
- if (initializer_list->phonebook_init)
- ret = initializer_list->phonebook_init(plugin, co);
- }
- break;
-
- case CORE_OBJECT_TYPE_GPS:{
- /* Invoke initializer */
- if (initializer_list->gps_init)
- ret = initializer_list->gps_init(plugin, co);
- }
- break;
-
- case CORE_OBJECT_TYPE_CUSTOM: /* Fall through */
- default:
- dbg("Unsupport/Invalid Core Object Type [0x%x]", type);
- break;
- }
-
- return ret;
-}
-
-
-static void _deinit_core_object_by_type(unsigned int type,
- TcorePlugin *plugin, struct object_deinitializer *deinitializer_list)
-{
- CoreObject *co;
-
- co = tcore_plugin_ref_core_object(plugin, type);
- if (co == NULL) {
- err("No Core Object of type: [0x%x]", type);
- return;
- }
-
- switch (type) {
- case CORE_OBJECT_TYPE_MODEM: {
- if (deinitializer_list->modem_deinit) {
- /* Invoke deinitializer */
- deinitializer_list->modem_deinit(plugin, co);
- }
- }
- break;
-
- case CORE_OBJECT_TYPE_CALL: {
- if (deinitializer_list->call_deinit) {
- /* Invoke deinitializer */
- deinitializer_list->call_deinit(plugin, co);
- }
- }
- break;
-
- case CORE_OBJECT_TYPE_SS: {
- if (deinitializer_list->ss_deinit) {
- /* Invoke deinitializer */
- deinitializer_list->ss_deinit(plugin, co);
- }
- }
- break;
-
- case CORE_OBJECT_TYPE_NETWORK: {
- if (deinitializer_list->network_deinit) {
- /* Invoke deinitializer */
- deinitializer_list->network_deinit(plugin, co);
- }
- }
- break;
-
- case CORE_OBJECT_TYPE_PS: {
- if (deinitializer_list->ps_deinit) {
- /* Invoke deinitializer */
- deinitializer_list->ps_deinit(plugin, co);
- }
- }
- break;
-
- case CORE_OBJECT_TYPE_SIM: {
- if (deinitializer_list->sim_deinit) {
- /* Invoke deinitializer */
- deinitializer_list->sim_deinit(plugin, co);
- }
- }
- break;
-
- case CORE_OBJECT_TYPE_SAT: {
- if (deinitializer_list->sat_deinit) {
- /* Invoke deinitializer */
- deinitializer_list->sat_deinit(plugin, co);
- }
- }
- break;
-
- case CORE_OBJECT_TYPE_SAP: {
- if (deinitializer_list->sap_deinit) {
- /* Invoke deinitializer */
- deinitializer_list->sap_deinit(plugin, co);
- }
- }
- break;
-
- case CORE_OBJECT_TYPE_SMS:{
- if (deinitializer_list->sms_deinit) {
- /* Invoke deinitializer */
- deinitializer_list->sms_deinit(plugin, co);
- }
- }
- break;
-
- case CORE_OBJECT_TYPE_PHONEBOOK: {
- if (deinitializer_list->phonebook_deinit) {
- /* Invoke deinitializer */
- deinitializer_list->phonebook_deinit(plugin, co);
- }
- }
- break;
-
- case CORE_OBJECT_TYPE_GPS:{
- if (deinitializer_list->gps_deinit) {
- /* Invoke deinitializer */
- deinitializer_list->gps_deinit(plugin, co);
- }
- }
- break;
-
- case CORE_OBJECT_TYPE_CUSTOM: /* Fall through */
- default:
- dbg("Unsupport/Invalid Core Object Type [0x%x]", type);
- return;
- }
-
- /* Free Core Object */
- tcore_object_free(co);
-}
-
-
-CoreObject *tcore_object_new(TcorePlugin *plugin,
- const char *name, TcoreHal *hal)
-{
- CoreObject *co;
-
- co = _object_new(plugin, CORE_OBJECT_TYPE_DEFAULT);
- if (!co)
- return NULL;
-
- tcore_object_set_hal(co, hal);
- tcore_object_set_name(co, name);
-
- if (plugin)
- tcore_plugin_add_core_object(plugin, co);
-
- return co;
-}
-
-void tcore_object_free(CoreObject *co)
-{
- GSList *l = NULL;
- struct callback_type *cb = NULL;
-
- if (!co)
- return;
-
- dbg("co_name=%s", co->name);
-
- if (co->free_hook)
- co->free_hook(co);
- else {
- if (co->object)
- warn("free_hook is null, private-object couldn't be freed!!");
- }
-
- if (co->property)
- g_hash_table_destroy(co->property);
-
- if (co->callbacks) {
- for (l = co->callbacks; l; l = l->next) {
- cb = l->data;
- if (!cb)
- continue;
-
- if (cb->event)
- free(cb->event);
-
- free(cb);
- }
-
- g_slist_free(co->callbacks);
- co->callbacks = NULL;
- }
-
- if (co->parent_plugin)
- tcore_plugin_remove_core_object(co->parent_plugin, co);
-
- if (co->name)
- free(co->name);
-
- memset(co, 0, sizeof(CoreObject));
- free(co);
-}
-
-const char *tcore_object_ref_name(CoreObject *co)
-{
- if (!co)
- return NULL;
-
- return co->name;
-}
-
-TReturn tcore_object_set_free_hook(CoreObject *co,
- CoreObjectFreeHook free_hook)
-{
- if (!co)
- return TCORE_RETURN_EINVAL;
-
- co->free_hook = free_hook;
-
- return TCORE_RETURN_SUCCESS;
-}
-
-TReturn tcore_object_set_name(CoreObject *co, const char *name)
-{
- if (!co)
- return TCORE_RETURN_EINVAL;
-
- if (co->name) {
- free(co->name);
- co->name = NULL;
- }
-
- if (name)
- co->name = strdup(name);
-
- return TCORE_RETURN_SUCCESS;
-}
-
-TcorePlugin *tcore_object_ref_plugin(CoreObject *co)
-{
- if (!co)
- return NULL;
-
- return co->parent_plugin;
-}
-
-TReturn tcore_object_link_object(CoreObject *co, void *object)
-{
- if (!co)
- return TCORE_RETURN_EINVAL;
-
- co->object = object;
-
- return TCORE_RETURN_SUCCESS;
-}
-
-void *tcore_object_ref_object(CoreObject *co)
-{
- if (!co)
- return NULL;
-
- return co->object;
-}
-
-TReturn tcore_object_set_type(CoreObject *co, unsigned int type)
-{
- if (!co)
- return TCORE_RETURN_EINVAL;
-
- co->type = type;
-
- return TCORE_RETURN_SUCCESS;
-}
-
-unsigned int tcore_object_get_type(CoreObject *co)
-{
- if (!co)
- return 0;
-
- return co->type;
-}
-
-TReturn tcore_object_set_hal(CoreObject *co, TcoreHal *hal)
-{
- TcoreAT *at;
- struct callback_type *cb = NULL;
- GSList *l = NULL;
-
- if (!co)
- return TCORE_RETURN_EINVAL;
-
- if (co->hal) {
- /* Remove unsolicited callbacks */
- if (tcore_hal_get_mode(co->hal) == TCORE_HAL_MODE_AT) {
- at = tcore_hal_get_at(co->hal);
- for (l = co->callbacks; l; l = l->next) {
- cb = l->data;
- if (!cb)
- continue;
-
- tcore_at_remove_notification_full(at, cb->event, _on_at_event, cb);
- }
- }
- }
-
- co->hal = hal;
- if (!hal)
- return TCORE_RETURN_SUCCESS;
-
- /* Register unsolicited callbacks */
- if (tcore_hal_get_mode(hal) == TCORE_HAL_MODE_AT) {
- at = tcore_hal_get_at(hal);
- for (l = co->callbacks; l; l = l->next) {
- cb = l->data;
- if (!cb)
- continue;
-
- if (cb->event[0] == 27)
- tcore_at_add_notification(at, cb->event + 1, TRUE, _on_at_event, cb);
- else
- tcore_at_add_notification(at, cb->event, FALSE, _on_at_event, cb);
- }
- }
-
- return TCORE_RETURN_SUCCESS;
-}
-
-TcoreHal *tcore_object_get_hal(CoreObject *co)
-{
- if (!co)
- return NULL;
-
- return co->hal;
-}
-
-TReturn tcore_object_link_user_data(CoreObject *co,
- void *user_data)
-{
- if (!co)
- return TCORE_RETURN_EINVAL;
-
- co->user_data = user_data;
-
- return TCORE_RETURN_SUCCESS;
-}
-
-void *tcore_object_ref_user_data(CoreObject *co)
-{
- if (!co)
- return NULL;
-
- return co->user_data;
-}
-
-/* This API will dispatch the request to default ops(i.e. CP) */
-TReturn tcore_object_dispatch_request(CoreObject *co,
- UserRequest *ur)
-{
- return tcore_object_dispatch_request_with_type(co, ur, TCORE_OPS_TYPE_CP);
-}
-
-/* This API will dispatch the request according to ops type */
-TReturn tcore_object_dispatch_request_with_type(CoreObject *co,
- UserRequest *ur, enum tcore_ops_type ops_type)
-{
- if (!co || !ur)
- return TCORE_RETURN_EINVAL;
-
- if (!co->dispatcher)
- return TCORE_RETURN_ENOSYS;
-
- return co->dispatcher(co, ur, ops_type);
-}
-
-TReturn tcore_object_set_dispatcher(CoreObject *co,
- CoreObjectDispatcher func)
-{
- if (!co || !func)
- return TCORE_RETURN_EINVAL;
-
- co->dispatcher = func;
-
- return TCORE_RETURN_SUCCESS;
-}
-
-TReturn tcore_object_override_callback(CoreObject *co,
- const char *event, tcore_object_callback callback, void *user_data)
-{
- struct callback_type *cb = NULL;
- GSList *l = NULL;
- TcoreAT *at = NULL;
-
- if ((co == NULL) || (event == NULL) || (callback == NULL))
- return TCORE_RETURN_EINVAL;
-
- if (strlen(event) < 1)
- return TCORE_RETURN_EINVAL;
-
- if (co->hal) {
- if (tcore_hal_get_mode(co->hal) == TCORE_HAL_MODE_AT)
- at = tcore_hal_get_at(co->hal);
- }
-
- for (l = co->callbacks; l; l = l->next) {
- cb = l->data;
- if (cb == NULL)
- continue;
-
- if (g_strcmp0(cb->event, event) != 0)
- continue;
-
- if (at)
- _remove_at_callback(at, cb);
-
- g_free(cb->event);
- co->callbacks = g_slist_remove(co->callbacks, cb);
- g_free(cb);
- }
-
- return tcore_object_add_callback(co, event, callback, user_data);
-}
-
-TReturn tcore_object_add_callback(CoreObject *co,
- const char *event,
- CoreObjectCallback callback, void *user_data)
-{
- struct callback_type *cb = NULL;
- TcoreAT *at = NULL;
-
- if (!co || !event || !callback)
- return TCORE_RETURN_EINVAL;
-
- if (strlen(event) < 1)
- return TCORE_RETURN_EINVAL;
-
- cb = calloc(1, sizeof(struct callback_type));
- if (!cb)
- return TCORE_RETURN_ENOMEM;
-
- cb->co = co;
- cb->event = strdup(event);
- cb->callback = callback;
- cb->user_data = user_data;
-
- co->callbacks = g_slist_append(co->callbacks, cb);
-
- if (co->hal) {
- if (tcore_hal_get_mode(co->hal) == TCORE_HAL_MODE_AT) {
- at = tcore_hal_get_at(co->hal);
- if (event[0] == 27)
- tcore_at_add_notification(at, cb->event + 1, TRUE, _on_at_event, cb);
- else
- tcore_at_add_notification(at, cb->event, FALSE, _on_at_event, cb);
-
- }
- }
-
- return TCORE_RETURN_SUCCESS;
-}
-
-TReturn tcore_object_del_callback(CoreObject *co,
- const char *event, CoreObjectCallback callback)
-{
- struct callback_type *cb = NULL;
- GSList *l = NULL;
- TcoreAT *at = NULL;
-
- if (!co || !event || !callback || !co->callbacks)
- return TCORE_RETURN_EINVAL;
-
- if (strlen(event) == 0)
- return TCORE_RETURN_EINVAL;
-
- if (co->hal) {
- if (tcore_hal_get_mode(co->hal) == TCORE_HAL_MODE_AT)
- at = tcore_hal_get_at(co->hal);
- }
-
- l = co->callbacks;
- while (l) {
- cb = l->data;
- if (!cb) {
- l = l->next;
- continue;
- }
-
- if (cb->callback != callback) {
- l = l->next;
- continue;
- }
-
- if (g_strcmp0(cb->event, event) != 0) {
- l = l->next;
- continue;
- }
-
- if (at)
- _remove_at_callback(at, cb);
-
- l = l->next;
- co->callbacks = g_slist_remove(co->callbacks, cb);
- free(cb->event);
- free(cb);
- }
-
- return TCORE_RETURN_SUCCESS;
-}
-
-TReturn tcore_object_emit_callback(CoreObject *co,
- const char *event, const void *event_info)
-{
- struct callback_type *cb = NULL;
- GSList *l = NULL;
- TReturn ret;
-
- if (!co || !event)
- return TCORE_RETURN_EINVAL;
-
- l = co->callbacks;
- while (l) {
- cb = l->data;
- if (!cb) {
- l = l->next;
- continue;
- }
-
- if (g_strcmp0(cb->event, event) != 0) {
- l = l->next;
- continue;
- }
-
- if (cb->callback) {
- ret = cb->callback(co, event_info, cb->user_data);
- if (ret == FALSE) {
- l = l->next;
- co->callbacks = g_slist_remove(co->callbacks, cb);
- continue;
- }
- }
-
- l = l->next;
- }
-
- return TCORE_RETURN_SUCCESS;
-}
-
-static GSList *_set_property_real(CoreObject *co, const char *key,
- const char *value, GSList *list)
-{
- char *prev;
-
- if (!co || !key)
- return list;
-
- if (!value) {
- g_hash_table_remove(co->property, key);
- return g_slist_append(list, (char *)key);
- }
-
- prev = g_hash_table_lookup(co->property, key);
- if (prev != NULL) {
- /*
- * If same data, no change & no callback emit
- */
- if (strcmp(prev, value) == 0)
- return list;
-
- g_hash_table_replace(co->property, strdup(key), strdup(value));
- } else
- g_hash_table_insert(co->property, strdup(key), strdup(value));
-
- return g_slist_append(list, (char *)key);
-}
-
-TReturn tcore_object_set_property_full(CoreObject *co, const char *first_property, ...)
-{
- va_list argptr;
- GSList *list = NULL;
- const char *k;
- const char *v;
-
- if (!co || !first_property)
- return TCORE_RETURN_EINVAL;
-
- va_start(argptr, first_property);
-
- k = first_property;
- v = va_arg(argptr, char *);
- list = _set_property_real(co, k, v, list);
-
- while (1) {
- k = va_arg(argptr, char *);
- if (!k)
- break;
-
- v = va_arg(argptr, char *);
- list = _set_property_real(co, k, v, list);
- }
-
- va_end(argptr);
-
- if (!list)
- return TCORE_RETURN_SUCCESS;
-
- if (g_slist_length(list) > 0)
- tcore_object_emit_callback(co,
- CORE_OBJECT_EVENT_PROPERTY_CHANGED, list);
-
- g_slist_free(list);
-
- return TCORE_RETURN_SUCCESS;
-}
-
-const char *tcore_object_ref_property(CoreObject *co, const char *key)
-{
- if (!co || !key)
- return NULL;
-
- return g_hash_table_lookup(co->property, key);
-}
-
-GHashTable *tcore_object_ref_property_hash(CoreObject *co)
-{
- if (!co)
- return NULL;
-
- return co->property;
-}
-void *tcore_object_add_mapping_tbl_entry(void *mapping_tbl,
- unsigned int object_type, TcoreHal *hal)
-{
- GSList *mapping_tbl_list = mapping_tbl;
- object_mapping_table_t *tbl_entry;
-
- if (hal == NULL) {
- err("Mapping Table: [0x%x] HAL: [0x%x]", mapping_tbl, hal);
- return mapping_tbl;
- }
-
- /*
- * Search 'hal' across all the Table entries of the Mapping Table
- *
- * Table entry MAY NOT be found as -
- * 1. Mapping Table is NOT yet created
- * 2. Table entry for corresponding 'hal' is NOT present
- *
- * In each of the above cases, the new Mapping Table entry should be added
- * to the Mapping Table.
- */
- tbl_entry = _object_search_mapping_tbl_entry(mapping_tbl_list, hal);
- if (tbl_entry == NULL) {
- dbg("Creating New Table entry for HAL: [0x%x]", hal);
- /*
- * If there is NO previously added Table entry for the 'hal' then
- * new Table entry is created
- */
-
- tbl_entry = g_try_malloc0(sizeof(object_mapping_table_t));
- if (tbl_entry != NULL)
- tbl_entry->hal = hal;
- else {
- err("Failed to allocate memory");
- return mapping_tbl_list;
- }
-
- /* Add the Mapping Table entry to Mapping Table */
- mapping_tbl_list = g_slist_append(mapping_tbl_list, tbl_entry);
- }
-
- /*
- * Appending the Core Object type to the list of Core Objects types
- */
- tbl_entry->object_type = g_slist_append(tbl_entry->object_type, GUINT_TO_POINTER(object_type));
- dbg("Added Mapping Table entry - HAL: [0x%x] Object type: [0x%x]", hal, object_type);
-
- return mapping_tbl_list;
-}
-
-void tcore_object_remove_mapping_tbl(void *mapping_tbl)
-{
- GSList *mapping_tbl_list = mapping_tbl;
-
- if (mapping_tbl_list == NULL) {
- err("Mapping Table is NULL");
- return;
- }
-
- /* Freeing Mapping Table */
- g_slist_free_full(mapping_tbl_list, _free_tbl_entry);
-}
-
-void *tcore_object_remove_mapping_tbl_entry(void *mapping_tbl, TcoreHal *hal)
-{
- GSList *mapping_tbl_list = mapping_tbl;
- object_mapping_table_t *tbl_entry;
-
- if (mapping_tbl_list == NULL) {
- err("Mapping Table is NULL");
- return mapping_tbl;
- }
-
- tbl_entry = _object_search_mapping_tbl_entry(mapping_tbl_list, hal);
- if (tbl_entry == NULL) {
- err("Table entry is NOT available");
- return mapping_tbl_list;
- }
-
- dbg("Removing Mapping Table Entry - HAL: [0x%x]", hal);
- _util_print_mapping_tbl_entry(tbl_entry);
-
- /* Free Core Object types list */
- g_slist_free(tbl_entry->object_type);
-
- /* Remove mapping Table entry */
- mapping_tbl_list = g_slist_remove(mapping_tbl_list, tbl_entry);
-
- /* Free Table entry */
- g_free(tbl_entry);
-
- return mapping_tbl_list;
-}
-
-void tcore_object_remove_mapping_tbl_entry_by_type(void *mapping_tbl,
- unsigned int co_type)
-{
- GSList *mapping_tbl_list;
- object_mapping_table_t *tbl_entry;
-
- if (mapping_tbl == NULL) {
- err("Mapping Table is NULL");
- return;
- }
-
- mapping_tbl_list = mapping_tbl;
-
- tbl_entry =
- _object_search_mapping_tbl_entry_by_type(mapping_tbl_list, co_type);
- if (tbl_entry == NULL) {
- err("Table entry is NOT available");
- return;
- }
-
- /* Remove the Core Object type from the list */
- tbl_entry->object_type = g_slist_remove(tbl_entry->object_type, GUINT_TO_POINTER(co_type));
-}
-
-void tcore_object_print_mapping_tbl(void *mapping_tbl)
-{
- GSList *mapping_tbl_list;
- object_mapping_table_t *tbl_entry = NULL;
-
-
- if (mapping_tbl == NULL) {
- err("Mapping Table is NULL");
- return;
- }
-
- mapping_tbl_list = mapping_tbl;
-
- for (; mapping_tbl_list ; mapping_tbl_list = mapping_tbl_list->next) {
- tbl_entry = mapping_tbl_list->data;
- if (tbl_entry == NULL)
- continue;
-
- _util_print_mapping_tbl_entry(tbl_entry);
- }
-}
-
-/* Initialize Core Objects */
-TReturn tcore_object_init_objects(TcorePlugin *plugin,
- struct object_initializer *initializer_list)
-{
- GSList *mapping_tbl_list;
- gboolean ret = FALSE;
-
- /* Refer mapping_tbl from Server's Modem list */
- mapping_tbl_list = tcore_server_get_cp_mapping_tbl(plugin);
-
- /*
- * Mapping Table is a MUST
- * If Mapping Table is NOT NULL, then initialization would be guided by the
- * Mapping Table entries,
- * else, it is treated as a Failure.
- */
- if (mapping_tbl_list != NULL) {
- object_mapping_table_t *tbl_entry;
- GSList *mtbl_list;
- GSList *object_type_list;
- unsigned int type;
-
- /* Create each Core Object based on the Mapping Table entries */
- mtbl_list = mapping_tbl_list;
- for (; mtbl_list ; mtbl_list = mtbl_list->next) {
- tbl_entry = mtbl_list->data;
- if (tbl_entry != NULL) {
- CoreObject *co;
-
- object_type_list = tbl_entry->object_type;
- for (; object_type_list ; object_type_list = object_type_list->next) {
- type = GPOINTER_TO_UINT(object_type_list->data);
-
- co = _create_core_object_by_type(type, plugin, tbl_entry->hal);
- if (co == NULL) {
- err("Failed to create Core Object - Type: [0x%x]", type);
- return TCORE_RETURN_FAILURE;
- }
-
- dbg("Created Core Object - Type: [0x%x]", type);
- }
- }
- }
-
-
- /* Initialize each Core Object based on the Mapping Table entries */
- mtbl_list = mapping_tbl_list;
- for (; mtbl_list ; mtbl_list = mtbl_list->next) {
- tbl_entry = mtbl_list->data;
- if (tbl_entry != NULL) {
- /* To handle NULL 'init' function case */
- ret = FALSE;
-
- object_type_list = tbl_entry->object_type;
-
- for (; object_type_list ; object_type_list = object_type_list->next) {
- type = GPOINTER_TO_UINT(object_type_list->data);
- dbg("Core Object type: [0x%x]", type);
-
- ret = _init_core_object_by_type(type, plugin, initializer_list);
- if (ret == FALSE) {
- err("Failed to initialize Core Object Type [0x%x]", type);
- return TCORE_RETURN_FAILURE;
- }
-
- dbg("Initialized Core Object - Type: [0x%x]", type);
- }
- }
- }
- } else
- err("Mapping Table is NOT present");
-
- if (ret == FALSE) {
- err("Failed to create/initialize Core Objects");
- return TCORE_RETURN_FAILURE;
- }
-
- dbg("Successfully initialized Core Objects");
- return TCORE_RETURN_SUCCESS;
-}
-
-/* De-initialize Core Objects */
-void tcore_object_deinit_objects(TcorePlugin *plugin,
- struct object_deinitializer *deinitializer_list)
-{
- GSList *mapping_tbl_list;
-
- /* Refer mapping_tbl from Server's Modem list */
- mapping_tbl_list = tcore_server_get_cp_mapping_tbl(plugin);
-
- /*
- * Mapping Table is a MUST
- * If Mapping Table is NOT NULL, then de-initialization would be guided by the
- * Mapping Table entries,
- * else,
- * just return with an Error log.
- */
- if (mapping_tbl_list != NULL) {
- object_mapping_table_t *tbl_entry;
- GSList *object_type_list;
- unsigned int type;
-
- /* De-initialize each Core Object based on the Mapping Table entries */
- for (; mapping_tbl_list ; mapping_tbl_list = mapping_tbl_list->next) {
- tbl_entry = mapping_tbl_list->data;
- if (tbl_entry == NULL)
- continue;
-
- object_type_list = tbl_entry->object_type;
-
- for (; object_type_list ; object_type_list = object_type_list->next) {
- type = GPOINTER_TO_UINT(object_type_list->data);
- dbg("Core Object type: [0x%x]", type);
-
- _deinit_core_object_by_type(type, plugin, deinitializer_list);
- }
- }
-
- dbg("Successfully de-initialized Core Objects");
- } else
- err("Mapping Table is NOT present");
-}
--- /dev/null
+/*
+ * libtcore
+ *
+ * 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.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <glib.h>
+
+#include "tcore.h"
+#include "internal/tcore_types.h"
+#include "plugin.h"
+#include "queue.h"
+#include "user_request.h"
+#include "co_call.h"
+
+
+#define MAX_CALL_OBJECTS 6
+
+struct call_cli_info {
+ enum tcore_call_cli_mode mode;
+ enum tcore_call_no_cli_cause no_cli_cause;
+ char number[MAX_CALL_NUMBER_LEN];
+ int number_len;
+};
+
+struct call_cna_info {
+ enum tcore_call_cna_mode mode;
+ int dcs;
+ char name[MAX_CALL_NAME_LEN];
+ int name_len;
+};
+
+struct call_object {
+ enum tcore_call_type type;
+
+ unsigned int handle;
+ unsigned int id;
+
+ enum tcore_call_direction direction;
+ enum tcore_call_status status;
+ gboolean mpty;
+ struct call_cli_info cli;
+ struct call_cna_info cna;
+ unsigned int cug_id;
+ unsigned int active_line;
+ struct call_time {
+ long start; /* In seconds */
+ long end; /* In seconds */
+ } time;
+
+ gboolean is_volte_call;
+ int session_id; /* VoLTE only */
+ int conf_call_session_id; /* Conference call session-id (VoLTE only) */
+ gboolean early_media; /* VoLTE only */
+
+ gboolean is_release_pending;
+ enum tcore_call_silent_redial_reason redial_reason;
+};
+
+struct private_object_data {
+ GSList *cobjs;
+ struct tcore_call_operations *ops[TCORE_OPS_TYPE_MAX];
+ struct tcore_call_control_operations *cops;
+ struct tcore_call_information_operations *iops;
+};
+
+static unsigned int __assign_handle(CoreObject *o)
+{
+ unsigned int handle_candidate = MIN_HANDLE;
+ CallObject *co = NULL;
+
+ /* Find unused 'handle' - starting from 1 */
+ while (handle_candidate < MAX_HANDLE) {
+ co = tcore_call_object_find_by_handle(o, handle_candidate);
+ if (NULL == co) {
+ /* Unused handle found */
+ return handle_candidate;
+ } else {
+ /* 'handle' already used, try next value */
+ handle_candidate++;
+ co = NULL;
+ }
+ }
+
+ err("available handle not found, serious");
+ return INVALID_HANDLE;
+}
+
+static TReturn _dispatcher(CoreObject *o, UserRequest *ur, enum tcore_ops_type ops_type)
+{
+ enum tcore_request_command command;
+
+ struct private_object_data *po = tcore_object_ref_object(o);
+ struct tcore_call_operations *ops = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_CALL, TCORE_RETURN_EINVAL);
+ CORE_OBJECT_VALIDATE_OPS_RETURN_VAL(ops_type, TCORE_RETURN_EINVAL);
+
+ tcore_check_null_ret_err("po", po, TCORE_RETURN_EINVAL);
+ tcore_check_null_ret_err("ur", ur, TCORE_RETURN_EINVAL);
+
+ ops = po->ops[ops_type];
+ tcore_check_null_ret_err("ops", ops, TCORE_RETURN_FAILURE);
+
+ command = tcore_user_request_get_command(ur);
+ switch (command) {
+ case TREQ_CALL_DIAL:
+ tcore_check_null_ret_err("ops->dial",
+ ops->dial, TCORE_RETURN_ENOSYS);
+
+ return ops->dial(o, ur);
+
+ case TREQ_CALL_ANSWER:
+ tcore_check_null_ret_err("ops->answer",
+ ops->answer, TCORE_RETURN_ENOSYS);
+
+ return ops->answer(o, ur);
+
+ case TREQ_CALL_END:
+ tcore_check_null_ret_err("ops->end",
+ ops->end, TCORE_RETURN_ENOSYS);
+
+ return ops->end(o, ur);
+
+ case TREQ_CALL_HOLD:
+ tcore_check_null_ret_err("ops->hold",
+ ops->hold, TCORE_RETURN_ENOSYS);
+
+ return ops->hold(o, ur);
+
+ case TREQ_CALL_ACTIVE:
+ tcore_check_null_ret_err("ops->active",
+ ops->active, TCORE_RETURN_ENOSYS);
+
+ return ops->active(o, ur);
+
+ case TREQ_CALL_SWAP:
+ tcore_check_null_ret_err("ops->swap",
+ ops->swap, TCORE_RETURN_ENOSYS);
+
+ return ops->swap(o, ur);
+
+ case TREQ_CALL_JOIN:
+ tcore_check_null_ret_err("ops->join",
+ ops->join, TCORE_RETURN_ENOSYS);
+
+ return ops->join(o, ur);
+
+ case TREQ_CALL_SPLIT:
+ tcore_check_null_ret_err("ops->split",
+ ops->split, TCORE_RETURN_ENOSYS);
+
+ return ops->split(o, ur);
+
+ case TREQ_CALL_DEFLECT:
+ tcore_check_null_ret_err("ops->deflect",
+ ops->deflect, TCORE_RETURN_ENOSYS);
+
+ return ops->deflect(o, ur);
+
+ case TREQ_CALL_TRANSFER:
+ tcore_check_null_ret_err("ops->transfer",
+ ops->transfer, TCORE_RETURN_ENOSYS);
+
+ return ops->transfer(o, ur);
+
+ case TREQ_CALL_START_CONT_DTMF:
+ tcore_check_null_ret_err("ops->start_cont_dtmf",
+ ops->start_cont_dtmf, TCORE_RETURN_ENOSYS);
+
+ return ops->start_cont_dtmf(o, ur);
+
+ case TREQ_CALL_STOP_CONT_DTMF:
+ tcore_check_null_ret_err("ops->stop_cont_dtmf",
+ ops->stop_cont_dtmf, TCORE_RETURN_ENOSYS);
+
+ return ops->stop_cont_dtmf(o, ur);
+
+ case TREQ_CALL_SEND_BURST_DTMF:
+ tcore_check_null_ret_err("ops->send_burst_dtmf",
+ ops->send_burst_dtmf, TCORE_RETURN_ENOSYS);
+
+ return ops->send_burst_dtmf(o, ur);
+
+ case TREQ_CALL_GET_PRIVACY_MODE:
+ tcore_check_null_ret_err("ops->get_privacy_mode",
+ ops->get_privacy_mode, TCORE_RETURN_ENOSYS);
+
+ return ops->get_privacy_mode(o, ur);
+
+ case TREQ_CALL_SET_PRIVACY_MODE:
+ tcore_check_null_ret_err("ops->set_privacy_mode",
+ ops->set_privacy_mode, TCORE_RETURN_ENOSYS);
+
+ return ops->set_privacy_mode(o, ur);
+
+ case TREQ_CALL_SET_SOUND_PATH:
+ tcore_check_null_ret_err("ops->set_sound_path",
+ ops->set_sound_path, TCORE_RETURN_ENOSYS);
+
+ return ops->set_sound_path(o, ur);
+
+ case TREQ_CALL_GET_SOUND_VOLUME_LEVEL:
+ tcore_check_null_ret_err("ops->get_sound_volume_level",
+ ops->get_sound_volume_level, TCORE_RETURN_ENOSYS);
+
+ return ops->get_sound_volume_level(o, ur);
+
+ case TREQ_CALL_SET_SOUND_VOLUME_LEVEL:
+ tcore_check_null_ret_err("ops->set_sound_volume_level",
+ ops->set_sound_volume_level, TCORE_RETURN_ENOSYS);
+
+ return ops->set_sound_volume_level(o, ur);
+
+ case TREQ_CALL_SET_SOUND_MUTE_STATUS:
+ tcore_check_null_ret_err("ops->set_sound_mute_status",
+ ops->set_sound_mute_status, TCORE_RETURN_ENOSYS);
+
+ return ops->set_sound_mute_status(o, ur);
+
+ case TREQ_CALL_GET_SOUND_MUTE_STATUS:
+ tcore_check_null_ret_err("ops->get_sound_mute_status",
+ ops->get_sound_mute_status, TCORE_RETURN_ENOSYS);
+
+ return ops->get_sound_mute_status(o, ur);
+
+ case TREQ_CALL_SET_SOUND_RECORDING:
+ tcore_check_null_ret_err("ops->set_sound_recording",
+ ops->set_sound_recording, TCORE_RETURN_ENOSYS);
+
+ return ops->set_sound_recording(o, ur);
+
+ case TREQ_CALL_SET_SOUND_EQUALIZATION:
+ tcore_check_null_ret_err("ops->set_sound_equalization",
+ ops->set_sound_equalization, TCORE_RETURN_ENOSYS);
+
+ return ops->set_sound_equalization(o, ur);
+
+ case TREQ_CALL_SET_SOUND_NOISE_REDUCTION:
+ tcore_check_null_ret_err("ops->set_sound_noise_reduction",
+ ops->set_sound_noise_reduction, TCORE_RETURN_ENOSYS);
+
+ return ops->set_sound_noise_reduction(o, ur);
+
+ case TREQ_CALL_SET_SOUND_CLOCK_STATUS:
+ tcore_check_null_ret_err("ops->set_sound_clock_status",
+ ops->set_sound_clock_status, TCORE_RETURN_ENOSYS);
+
+ return ops->set_sound_clock_status(o, ur);
+
+ case TREQ_CALL_SET_PREFERRED_VOICE_SUBSCRIPTION:
+ tcore_check_null_ret_err("ops->set_preferred_voice_subscription",
+ ops->set_preferred_voice_subscription, TCORE_RETURN_ENOSYS);
+
+ return ops->set_preferred_voice_subscription(o, ur);
+
+ case TREQ_CALL_GET_PREFERRED_VOICE_SUBSCRIPTION:
+ tcore_check_null_ret_err("ops->get_preferred_voice_subscription",
+ ops->get_preferred_voice_subscription, TCORE_RETURN_ENOSYS);
+
+ return ops->get_preferred_voice_subscription(o, ur);
+
+ case TREQ_CALL_MODIFY:
+ tcore_check_null_ret_err("ops->modify",
+ ops->modify, TCORE_RETURN_ENOSYS);
+
+ return ops->modify(o, ur);
+
+ case TREQ_CALL_CONFIRM_MODIFY:
+ tcore_check_null_ret_err("ops->confirm_modify",
+ ops->confirm_modify, TCORE_RETURN_ENOSYS);
+
+ return ops->confirm_modify(o, ur);
+
+ default:
+ break;
+ }
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+static void _free_hook(CoreObject *o)
+{
+ struct private_object_data *po = NULL;
+
+ po = tcore_object_ref_object(o);
+ if (!po)
+ return;
+
+ g_slist_free_full(po->cobjs, g_free);
+ g_free(po);
+
+ tcore_object_link_object(o, NULL);
+}
+
+typedef gboolean(*func)(CallObject *co, void *data);
+static CallObject *_find_object(GSList *objs, void *data, func compare)
+{
+ CallObject *co = NULL;
+ GSList *l = NULL;
+
+ tcore_check_null_ret_err("objs", objs, NULL);
+ tcore_check_null_ret_err("compare", compare, NULL);
+
+ l = objs;
+ while (l) {
+ co = (CallObject *) l->data;
+
+ if (compare(co, data))
+ return co;
+
+ l = g_slist_next(l);
+ }
+
+ return NULL;
+}
+
+static GSList *_find_object_all(GSList *objs, void *data, func compare)
+{
+ CallObject *co = NULL;
+ GSList *l = NULL;
+ GSList *ret = NULL;
+
+ tcore_check_null_ret_err("objs", objs, NULL);
+ tcore_check_null_ret_err("compare", compare, NULL);
+
+ l = objs;
+ while (l) {
+ co = (CallObject *) l->data;
+
+ if (compare(co, data))
+ ret = g_slist_append(ret, co);
+
+ l = g_slist_next(l);
+ }
+
+ return ret;
+}
+
+static gboolean _compare_by_id(CallObject *co, void *data)
+{
+ unsigned int *id = (unsigned int *) data;
+
+ tcore_check_null_ret_err("co", co, FALSE);
+ tcore_check_null_ret_err("data", data, FALSE);
+
+ if (co->id == *id)
+ return TRUE;
+
+ return FALSE;
+}
+
+static gboolean _compare_by_handle(CallObject *co, void *data)
+{
+ unsigned int *handle = (unsigned int *) data;
+
+ tcore_check_null_ret_err("co", co, FALSE);
+ tcore_check_null_ret_err("data", data, FALSE);
+
+ if (co->handle == *handle)
+ return TRUE;
+
+ return FALSE;
+}
+
+
+static gboolean _compare_by_session_id(CallObject *co, void *data)
+{
+ int *session_id = data;
+
+ tcore_check_null_ret_err("co", co, FALSE);
+ tcore_check_null_ret_err("data", data, FALSE);
+
+ if (co->session_id == *session_id)
+ return TRUE;
+
+ return FALSE;
+}
+
+static gboolean _compare_by_status(CallObject *co, void *data)
+{
+ enum tcore_call_status *ct = (enum tcore_call_status *) data;
+
+ tcore_check_null_ret_err("co", co, FALSE);
+ tcore_check_null_ret_err("data", data, FALSE);
+
+ if (co->status == *ct)
+ return TRUE;
+
+ return FALSE;
+}
+
+static gboolean _compare_by_number(CallObject *co, void *data)
+{
+ char *number = (char *) data;
+
+ tcore_check_null_ret_err("co", co, FALSE);
+ tcore_check_null_ret_err("data", data, FALSE);
+
+ if (!strcmp(co->cli.number, number))
+ return TRUE;
+
+ return FALSE;
+}
+
+static enum tcore_call_cli_mode _check_cli_mode_by_number(char *num)
+{
+ tcore_check_null_ret_err("num", num, TCORE_CALL_CLI_MODE_DEFAULT);
+
+ if (!strncmp(num, "*31#", 4))
+ return TCORE_CALL_CLI_MODE_PRESENT;
+
+ if (!strncmp(num, "#31#", 4))
+ return TCORE_CALL_CLI_MODE_RESTRICT;
+
+ return TCORE_CALL_CLI_MODE_DEFAULT;
+}
+
+
+/* Call Object APIs */
+CallObject *tcore_call_object_new(CoreObject *o)
+{
+ struct private_object_data *po = NULL;
+ CallObject *co = NULL;
+
+ po = tcore_object_ref_object(o);
+
+ tcore_check_null_ret_err("po", po, NULL);
+
+ co = g_try_malloc0(sizeof(struct call_object));
+ if (co == NULL)
+ return NULL;
+
+ co->handle = __assign_handle(o);
+
+ if (INVALID_HANDLE == co->handle) {
+ err("valid handle not available. call object creation failed");
+ g_free(co);
+ return NULL;
+ }
+ co->id = -1;
+
+ po->cobjs = g_slist_append(po->cobjs, co);
+
+ dbg("new call object handle : [%d]", co->handle);
+
+ return co;
+}
+
+gboolean tcore_call_object_free(CoreObject *o, CallObject *co)
+{
+ struct private_object_data *po = NULL;
+ po = tcore_object_ref_object(o);
+
+ tcore_check_null_ret_err("po", po, FALSE);
+ tcore_check_null_ret_err("po->cobjs", po->cobjs, FALSE);
+ tcore_check_null_ret_err("co", co, FALSE);
+
+ po->cobjs = g_slist_remove(po->cobjs, co);
+ g_free(co);
+
+ return TRUE;
+}
+
+int tcore_call_object_total_length(CoreObject *o)
+{
+ struct private_object_data *po = NULL;
+ po = tcore_object_ref_object(o);
+
+ tcore_check_null_ret_err("po", po, 0);
+ tcore_check_null_ret_err("po->cobjs", po->cobjs, 0);
+
+ return (int)g_slist_length(po->cobjs);
+}
+
+CallObject *tcore_call_object_current_on_mt_processing(CoreObject *o)
+{
+ struct private_object_data *po = NULL;
+ CallObject *call_obj = NULL;
+ GSList *l = NULL;
+
+ enum tcore_call_status cs = TCORE_CALL_STATUS_INCOMING;
+ po = tcore_object_ref_object(o);
+
+ tcore_check_null_ret_err("po", po, NULL);
+ tcore_check_null_ret_err("po->cobjs", po->cobjs, NULL);
+
+ l = _find_object_all(po->cobjs, (void *)&cs, (void *)_compare_by_status);
+ if (!l) {
+ cs = TCORE_CALL_STATUS_WAITING;
+ l = _find_object_all(po->cobjs, (void *)&cs, (void *)_compare_by_status);
+ if (!l)
+ return 0;
+ }
+
+ call_obj = (CallObject *)(l->data);
+ g_slist_free(l);
+
+ return call_obj;
+}
+
+CallObject *tcore_call_object_current_on_mo_processing(CoreObject *o)
+{
+ struct private_object_data *po = NULL;
+ CallObject *call_obj = NULL;
+ GSList *l = NULL;
+
+ po = tcore_object_ref_object(o);
+
+ tcore_check_null_ret_err("po", po, NULL);
+ tcore_check_null_ret_err("po->cobjs", po->cobjs, NULL);
+
+ l = tcore_call_object_find_by_status(o, TCORE_CALL_STATUS_DIALING);
+ if (!l) {
+ l = tcore_call_object_find_by_status(o, TCORE_CALL_STATUS_ALERT);
+ if (!l) {
+ l = tcore_call_object_find_by_status(o, TCORE_CALL_STATUS_SETUP);
+ if (!l) {
+ l = tcore_call_object_find_by_status(o, TCORE_CALL_STATUS_SETUP_PENDING);
+ if (!l)
+ return NULL;
+ }
+ }
+ }
+
+ call_obj = (CallObject *)(l->data);
+ g_slist_free(l);
+
+ return call_obj;
+}
+
+int tcore_call_get_id_by_handle(CoreObject *o, int handle)
+{
+ CallObject *co = NULL;
+
+ co = tcore_call_object_find_by_handle(o, handle);
+ tcore_check_null_ret_err("co", co, -1);
+
+ return tcore_call_object_get_id(co);
+}
+
+int tcore_call_get_handle_by_id(CoreObject *o, int call_id)
+{
+ CallObject *co = NULL;
+
+ co = tcore_call_object_find_by_id(o, call_id);
+ tcore_check_null_ret_err("co", co, -1);
+
+ return tcore_call_object_get_handle(co);
+}
+
+CallObject *tcore_call_object_find_by_id(CoreObject *o, int id)
+{
+ struct private_object_data *po = NULL;
+
+ po = tcore_object_ref_object(o);
+
+ tcore_check_null_ret_err("po", po, NULL);
+ tcore_check_null_ret_err("po->cobjs", po->cobjs, NULL);
+
+ return _find_object(po->cobjs, (void *) &id, (void *) _compare_by_id);
+}
+
+CallObject *tcore_call_object_find_by_handle(CoreObject *o, int handle)
+{
+ struct private_object_data *po = NULL;
+
+ po = tcore_object_ref_object(o);
+
+ tcore_check_null_ret_err("po", po, NULL);
+ tcore_check_null_ret_err("po->cobjs", po->cobjs, NULL);
+
+ return _find_object(po->cobjs, (void *) &handle, (void *) _compare_by_handle);
+
+}
+
+
+CallObject *tcore_call_object_find_by_number(CoreObject *o, char *num)
+{
+ struct private_object_data *po = NULL;
+
+ po = tcore_object_ref_object(o);
+
+ tcore_check_null_ret_err("po", po, NULL);
+ tcore_check_null_ret_err("po->cobjs", po->cobjs, NULL);
+ tcore_check_null_ret_err("num", num, NULL);
+
+ return _find_object(po->cobjs, (void *) num, (void *) _compare_by_number);
+}
+
+GSList *tcore_call_object_find_by_status(CoreObject *o, enum tcore_call_status cs)
+{
+ struct private_object_data *po = NULL;
+
+ po = tcore_object_ref_object(o);
+
+ tcore_check_null_ret_err("po", po, NULL);
+ tcore_check_null_ret_err("po->cobjs", po->cobjs, NULL);
+
+ return _find_object_all(po->cobjs, (void *) &cs, (void *) _compare_by_status);
+}
+
+int tcore_call_object_get_id(CallObject *co)
+{
+ tcore_check_null_ret_err("co", co, -1);
+
+ return co->id;
+}
+
+gboolean tcore_call_object_set_id(CallObject *co , int call_id)
+{
+ tcore_check_null_ret_err("co", co, FALSE);
+ co->id = call_id;
+
+ return TRUE;
+}
+
+int tcore_call_object_get_handle(CallObject *co)
+{
+ tcore_check_null_ret_err("co", co, -1);
+
+ return co->handle;
+}
+
+
+gboolean tcore_call_object_set_type(CallObject *co, enum tcore_call_type ct)
+{
+ tcore_check_null_ret_err("co", co, FALSE);
+
+ co->type = ct;
+ return TRUE;
+}
+
+enum tcore_call_type tcore_call_object_get_type(CallObject *co)
+{
+ tcore_check_null_ret_err("co", co, -1);
+
+ return co->type;
+}
+
+gboolean tcore_call_object_set_direction(CallObject *co, enum tcore_call_direction cd)
+{
+ tcore_check_null_ret_err("co", co, FALSE);
+
+ co->direction = cd;
+ return TRUE;
+}
+
+enum tcore_call_direction tcore_call_object_get_direction(CallObject *co)
+{
+ tcore_check_null_ret_err("co", co, -1);
+
+ return co->direction;
+}
+
+gboolean tcore_call_object_set_status(CallObject *co, enum tcore_call_status cs)
+{
+ tcore_check_null_ret_err("co", co, FALSE);
+
+ co->status = cs;
+ return TRUE;
+}
+
+enum tcore_call_status tcore_call_object_get_status(CallObject *co)
+{
+ tcore_check_null_ret_err("co", co, -1);
+
+ return co->status;
+}
+
+gboolean tcore_call_object_set_cli_info(CallObject *co,
+ enum tcore_call_cli_mode mode, enum tcore_call_no_cli_cause cause,
+ char *num, int num_len)
+{
+ char *pos = NULL;
+
+ tcore_check_null_ret_err("co", co, FALSE);
+
+ dbg("num : %s", num);
+ dbg("mode : 0x%x", mode);
+
+ if (!num) {
+ co->cli.mode = mode;
+ if (mode == TCORE_CALL_CLI_MODE_RESTRICT)
+ co->cli.no_cli_cause = cause;
+ else
+ co->cli.no_cli_cause = TCORE_CALL_NO_CLI_CAUSE_NONE;
+
+ co->cli.number_len = num_len ;
+ co->cli.number[0] = '\0';
+
+ return TRUE;
+ }
+
+ pos = num;
+
+ if (mode == TCORE_CALL_CLI_MODE_DEFAULT) {
+ co->cli.mode = _check_cli_mode_by_number(num);
+
+ if (co->cli.mode != TCORE_CALL_CLI_MODE_DEFAULT)
+ pos = (num + 4);
+ } else {
+ co->cli.mode = mode;
+ if (mode == TCORE_CALL_CLI_MODE_RESTRICT)
+ co->cli.no_cli_cause = cause;
+ else
+ co->cli.no_cli_cause = TCORE_CALL_NO_CLI_CAUSE_NONE;
+ }
+
+ strncpy(co->cli.number, pos, ((num_len - (pos - num)) + 1));
+ co->cli.number_len = strlen(co->cli.number);
+
+ dbg("co->cli.mode: [0x%x]", co->cli.mode);
+ dbg("co->cli.no_cli_cause: [0x%x]", co->cli.no_cli_cause);
+ dbg("co->cli.number: [%s]", co->cli.number);
+ dbg("co->cli.number_len: [%d]", co->cli.number_len);
+
+ return TRUE;
+}
+
+int tcore_call_object_get_number(CallObject *co, char *num)
+{
+ tcore_check_null_ret_err( "co", co, -1);
+ tcore_check_null_ret_err( "num", num, -1);
+
+ strncpy(num, co->cli.number, MAX_CALL_NUMBER_LEN);
+ return co->cli.number_len;
+}
+
+enum tcore_call_cli_mode tcore_call_object_get_cli_mode(CallObject *co)
+{
+ tcore_check_null_ret_err("co", co, -1);
+
+ return co->cli.mode;
+}
+
+enum tcore_call_no_cli_cause tcore_call_object_get_no_cli_cause(CallObject *co)
+{
+ tcore_check_null_ret_err("co", co, -1);
+
+ return co->cli.no_cli_cause;
+}
+
+
+gboolean tcore_call_object_set_cna_info(CallObject *co, enum tcore_call_cna_mode mode, char *name, int dcs)
+{
+ int len;
+ tcore_check_null_ret_err("co", co, FALSE);
+ tcore_check_null_ret_err("name", name, FALSE);
+
+ len = strlen(name);
+ if (len >= MAX_CALL_NAME_LEN)
+ return FALSE;
+
+ strncpy(co->cna.name, name, len);
+ co->cna.name[len] = '\0';
+
+ co->cna.mode = mode;
+
+ return TRUE;
+}
+
+int tcore_call_object_get_name(CallObject *co, char *name)
+{
+ tcore_check_null_ret_err( "co", co, -1);
+ tcore_check_null_ret_err( "name", name, -1);
+
+ strncpy(name, co->cna.name, MAX_CALL_NAME_LEN);
+ return co->cna.name_len;
+}
+
+enum tcore_call_cna_mode tcore_call_object_get_cna_mode(CallObject *co)
+{
+ tcore_check_null_ret_err("co", co, -1);
+
+ return co->cna.mode;
+}
+
+gboolean tcore_call_object_set_multiparty_state(CallObject *co, gboolean is)
+{
+ tcore_check_null_ret_err("co", co, FALSE);
+
+ co->mpty = is;
+
+ return TRUE;
+}
+
+gboolean tcore_call_object_get_multiparty_state(CallObject *co)
+{
+ tcore_check_null_ret_err("co", co, FALSE);
+
+ return co->mpty;
+}
+
+gboolean tcore_call_object_set_active_line(CallObject *co, unsigned int line)
+{
+ tcore_check_null_ret_err("co", co, FALSE);
+
+ co->active_line = line;
+
+ return TRUE;
+}
+
+int tcore_call_object_get_active_line(CallObject *co)
+{
+ tcore_check_null_ret_err("co", co, -1);
+
+ return co->active_line;
+}
+
+gboolean tcore_call_object_set_is_volte_call(CallObject *co, gboolean flag)
+{
+ tcore_check_null_ret_err("co", co, FALSE);
+
+ co->is_volte_call = flag;
+
+ return TRUE;
+}
+
+gboolean tcore_call_object_get_is_volte_call(CallObject *co)
+{
+ tcore_check_null_ret_err("co", co, FALSE);
+
+ return co->is_volte_call;
+}
+
+gboolean tcore_call_object_set_session_id(CallObject *co, int session_id)
+{
+ tcore_check_null_ret_err("co", co, FALSE);
+
+ co->session_id = session_id;
+
+ return TRUE;
+}
+
+int tcore_call_object_get_session_id(CallObject *co)
+{
+ tcore_check_null_ret_err("co", co, FALSE);
+
+ return co->session_id;
+}
+
+gboolean tcore_call_object_set_conf_call_session_id(CallObject *co, int session_id)
+{
+ tcore_check_null_ret_err("co", co, FALSE);
+
+ co->conf_call_session_id = session_id;
+
+ return TRUE;
+}
+
+gboolean tcore_call_object_get_conf_call_session_id(CallObject *co)
+{
+ tcore_check_null_ret_err("co", co, FALSE);
+
+ return co->conf_call_session_id;
+}
+
+gboolean tcore_call_object_set_early_media(CallObject *co, gboolean flag)
+{
+ tcore_check_null_ret_err("co", co, FALSE);
+
+ co->early_media = flag;
+
+ return TRUE;
+}
+
+gboolean tcore_call_object_get_early_media(CallObject *co)
+{
+ tcore_check_null_ret_err("co", co, FALSE);
+
+ return co->early_media;
+}
+
+CallObject *tcore_call_object_find_by_session_id(CoreObject *o, int session_id)
+{
+ struct private_object_data *po = NULL;
+ po = tcore_object_ref_object(o);
+
+ tcore_check_null_ret_err("po", po, NULL);
+ tcore_check_null_ret_err("po->cobjs", po->cobjs, NULL);
+
+ return _find_object(po->cobjs, &session_id, _compare_by_session_id);
+}
+
+gboolean tcore_call_object_check_cs_call_existence(CoreObject *o)
+{
+ struct private_object_data *po = NULL;
+ CallObject *call_obj = NULL;
+ GSList *call_list = NULL;
+
+ po = tcore_object_ref_object(o);
+ tcore_check_null_ret_err("po", po, FALSE);
+
+ call_list = po->cobjs;
+ while (call_list) {
+ call_obj = call_list->data;
+ if (call_obj->is_volte_call == FALSE)
+ return TRUE;
+
+ call_list = g_slist_next(call_list);
+ }
+
+ return FALSE;
+}
+
+GSList *tcore_call_object_get_all_session_ids(CoreObject *o)
+{
+ struct private_object_data *po = NULL;
+ CallObject *call_obj = NULL;
+ GSList *call_list = NULL;
+ GSList *session_ids = NULL;
+
+ po = tcore_object_ref_object(o);
+ tcore_check_null_ret_err("po", po, NULL);
+
+ call_list = po->cobjs;
+ while (call_list) {
+ call_obj = call_list->data;
+ if (call_obj->is_volte_call == TRUE)
+ session_ids = g_slist_append(session_ids, GINT_TO_POINTER(call_obj->session_id));
+
+ call_list = g_slist_next(call_list);
+ }
+
+ return session_ids;
+}
+
+gboolean tcore_call_object_set_is_release_pending(CallObject *co, gboolean flag)
+{
+ tcore_check_null_ret_err("co", co, FALSE);
+
+ co->is_release_pending = flag;
+
+ return TRUE;
+
+}
+
+gboolean tcore_call_object_get_is_release_pending(CallObject *co)
+{
+ tcore_check_null_ret_err("co", co, FALSE);
+
+ return co->is_release_pending;
+}
+
+gboolean tcore_call_object_set_silent_redial_reason(CallObject *co, enum tcore_call_silent_redial_reason reason)
+{
+ tcore_check_null_ret_err("co", co, FALSE);
+
+ co->redial_reason = reason;
+
+ return TRUE;
+
+}
+enum tcore_call_silent_redial_reason tcore_call_object_get_silent_redial_reason(CallObject *co)
+{
+ tcore_check_null_ret_err("co", co, -1);
+
+ return co->redial_reason;
+}
+
+TReturn tcore_call_control_answer_hold_and_accept(CoreObject *o, UserRequest* ur, ConfirmCallback cb, void *user_data)
+{
+ struct private_object_data *po = NULL;
+ po = tcore_object_ref_object(o);
+
+ tcore_check_null_ret_err("po", po, TCORE_RETURN_FAILURE);
+ tcore_check_null_ret_err("po->cops", po->cops, TCORE_RETURN_FAILURE);
+ tcore_check_null_ret_err("po->cops->answer_hold_and_accept", po->cops->answer_hold_and_accept, TCORE_RETURN_ENOSYS);
+
+ return po->cops->answer_hold_and_accept(o, ur, cb, user_data);
+}
+
+TReturn tcore_call_control_answer_replace(CoreObject *o, UserRequest* ur, ConfirmCallback cb, void *user_data)
+{
+ struct private_object_data *po = NULL;
+ po = tcore_object_ref_object(o);
+
+ tcore_check_null_ret_err("po", po, TCORE_RETURN_FAILURE);
+ tcore_check_null_ret_err("po->cops", po->cops, TCORE_RETURN_FAILURE);
+ tcore_check_null_ret_err("po->cops->answer_replace", po->cops->answer_replace, TCORE_RETURN_ENOSYS);
+
+ return po->cops->answer_replace(o, ur, cb, user_data);
+}
+
+TReturn tcore_call_control_answer_reject(CoreObject *o, UserRequest* ur, ConfirmCallback cb, void *user_data)
+{
+ struct private_object_data *po = NULL;
+ po = tcore_object_ref_object(o);
+
+ tcore_check_null_ret_err("po", po, TCORE_RETURN_FAILURE);
+ tcore_check_null_ret_err("po->cops", po->cops, TCORE_RETURN_FAILURE);
+ tcore_check_null_ret_err("po->cops->answer_reject", po->cops->answer_reject, TCORE_RETURN_ENOSYS);
+
+ return po->cops->answer_reject(o, ur, cb, user_data);
+}
+
+TReturn tcore_call_control_end_specific(CoreObject *o, UserRequest* ur, const int id, ConfirmCallback cb,
+ void *user_data)
+{
+ struct private_object_data *po = NULL;
+ po = tcore_object_ref_object(o);
+
+ tcore_check_null_ret_err("po", po, TCORE_RETURN_FAILURE);
+ tcore_check_null_ret_err("po->cops", po->cops, TCORE_RETURN_FAILURE);
+ tcore_check_null_ret_err("po->cops->end_specific", po->cops->end_specific, TCORE_RETURN_ENOSYS);
+
+ return po->cops->end_specific(o, ur, id, cb, user_data);
+}
+
+TReturn tcore_call_control_end_all_active(CoreObject *o, UserRequest* ur, ConfirmCallback cb, void *user_data)
+{
+ struct private_object_data *po = NULL;
+ po = tcore_object_ref_object(o);
+
+ tcore_check_null_ret_err("po", po, TCORE_RETURN_FAILURE);
+ tcore_check_null_ret_err("po->cops", po->cops, TCORE_RETURN_FAILURE);
+ tcore_check_null_ret_err("po->cops->end_all_active", po->cops->end_all_active, TCORE_RETURN_ENOSYS);
+
+ return po->cops->end_all_active(o, ur, cb, user_data);
+}
+
+TReturn tcore_call_control_end_all_held(CoreObject *o, UserRequest* ur, ConfirmCallback cb, void *user_data)
+{
+ struct private_object_data *po = NULL;
+ po = tcore_object_ref_object(o);
+
+ tcore_check_null_ret_err("po", po, TCORE_RETURN_FAILURE);
+ tcore_check_null_ret_err("po->cops", po->cops, TCORE_RETURN_FAILURE);
+ tcore_check_null_ret_err("po->cops->end_all_held", po->cops->end_all_held, TCORE_RETURN_ENOSYS);
+
+ return po->cops->end_all_held(o, ur, cb, user_data);
+}
+
+TReturn tcore_call_control_active(CoreObject *o, UserRequest* ur, ConfirmCallback cb, void *user_data)
+{
+ struct private_object_data *po = NULL;
+ po = tcore_object_ref_object(o);
+
+ tcore_check_null_ret_err("po", po, TCORE_RETURN_FAILURE);
+ tcore_check_null_ret_err("po->cops", po->cops, TCORE_RETURN_FAILURE);
+ tcore_check_null_ret_err("po->cops->active", po->cops->active, TCORE_RETURN_ENOSYS);
+
+ return po->cops->active(o, ur, cb, user_data);
+}
+
+TReturn tcore_call_control_hold(CoreObject *o, UserRequest* ur, ConfirmCallback cb, void *user_data)
+{
+ struct private_object_data *po = NULL;
+ po = tcore_object_ref_object(o);
+
+ tcore_check_null_ret_err("po", po, TCORE_RETURN_FAILURE);
+ tcore_check_null_ret_err("po->cops", po->cops, TCORE_RETURN_FAILURE);
+ tcore_check_null_ret_err("po->cops->hold", po->cops->hold, TCORE_RETURN_ENOSYS);
+
+ return po->cops->hold(o, ur, cb, user_data);
+}
+
+TReturn tcore_call_control_swap(CoreObject *o, UserRequest* ur, ConfirmCallback cb, void *user_data)
+{
+ struct private_object_data *po = NULL;
+ po = tcore_object_ref_object(o);
+
+ tcore_check_null_ret_err("po", po, TCORE_RETURN_FAILURE);
+ tcore_check_null_ret_err("po->cops", po->cops, TCORE_RETURN_FAILURE);
+ tcore_check_null_ret_err("po->cops->swap", po->cops->swap, TCORE_RETURN_ENOSYS);
+
+ return po->cops->swap(o, ur, cb, user_data);
+}
+
+TReturn tcore_call_control_join(CoreObject *o, UserRequest* ur, ConfirmCallback cb, void *user_data)
+{
+ struct private_object_data *po = NULL;
+ po = tcore_object_ref_object(o);
+
+ tcore_check_null_ret_err("po", po, TCORE_RETURN_FAILURE);
+ tcore_check_null_ret_err("po->cops", po->cops, TCORE_RETURN_FAILURE);
+ tcore_check_null_ret_err("po->cops->join", po->cops->join, TCORE_RETURN_ENOSYS);
+
+ return po->cops->join(o, ur, cb, user_data);
+}
+
+TReturn tcore_call_control_split(CoreObject *o, UserRequest* ur, const int id, ConfirmCallback cb, void *user_data)
+{
+ struct private_object_data *po = NULL;
+ po = tcore_object_ref_object(o);
+
+ tcore_check_null_ret_err("po", po, TCORE_RETURN_FAILURE);
+ tcore_check_null_ret_err("po->cops", po->cops, TCORE_RETURN_FAILURE);
+ tcore_check_null_ret_err("po->cops->split", po->cops->split, TCORE_RETURN_ENOSYS);
+
+ return po->cops->split(o, ur, id, cb, user_data);
+}
+
+TReturn tcore_call_control_transfer(CoreObject *o, UserRequest* ur, ConfirmCallback cb, void *user_data)
+{
+ struct private_object_data *po = NULL;
+ po = tcore_object_ref_object(o);
+
+ tcore_check_null_ret_err("po", po, TCORE_RETURN_FAILURE);
+ tcore_check_null_ret_err("po->cops", po->cops, TCORE_RETURN_FAILURE);
+ tcore_check_null_ret_err("po->cops->transfer", po->cops->transfer, TCORE_RETURN_ENOSYS);
+
+ return po->cops->transfer(o, ur, cb, user_data);
+}
+
+TReturn tcore_call_control_deflect(CoreObject *o, UserRequest* ur, const char *number, ConfirmCallback cb,
+ void *user_data)
+{
+ struct private_object_data *po = NULL;
+ po = tcore_object_ref_object(o);
+
+ tcore_check_null_ret_err("po", po, TCORE_RETURN_FAILURE);
+ tcore_check_null_ret_err("po->cops", po->cops, TCORE_RETURN_FAILURE);
+ tcore_check_null_ret_err("po->cops->deflect", po->cops->deflect, TCORE_RETURN_ENOSYS);
+
+ return po->cops->deflect(o, ur, number, cb, user_data);
+}
+
+void tcore_call_control_set_operations(CoreObject *o, struct tcore_call_control_operations *cops)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_CALL);
+
+ po = tcore_object_ref_object(o);
+ if (!po) {
+ err("po is NULL");
+ return;
+ }
+
+ po->cops = cops;
+}
+
+void tcore_call_information_mo_col(CoreObject *o, char *number)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_CALL);
+
+ po = tcore_object_ref_object(o);
+
+ tcore_check_null_ret("po", po);
+ tcore_check_null_ret("po->iops", po->iops);
+ tcore_check_null_ret("po->iops->mo_call_col", po->iops->mo_call_col);
+
+ po->iops->mo_call_col(o, number);
+}
+
+void tcore_call_information_mo_waiting(CoreObject *o)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_CALL);
+
+ po = tcore_object_ref_object(o);
+
+ tcore_check_null_ret("po", po);
+ tcore_check_null_ret("po->iops", po->iops);
+ tcore_check_null_ret("po->iops->mo_call_waiting", po->iops->mo_call_waiting);
+
+ po->iops->mo_call_waiting(o);
+}
+
+void tcore_call_information_mo_cug(CoreObject *o, int cug_index)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_CALL);
+
+ po = tcore_object_ref_object(o);
+
+ tcore_check_null_ret("po", po);
+ tcore_check_null_ret("po->iops", po->iops);
+ tcore_check_null_ret("po->iops->mo_call_cug", po->iops->mo_call_cug);
+
+ po->iops->mo_call_cug(o, cug_index);
+}
+
+void tcore_call_information_mo_forwarded(CoreObject *o)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_CALL);
+
+ po = tcore_object_ref_object(o);
+
+ tcore_check_null_ret("po", po);
+ tcore_check_null_ret("po->iops", po->iops);
+ tcore_check_null_ret("po->iops->mo_call_forwarded", po->iops->mo_call_forwarded);
+
+ po->iops->mo_call_forwarded(o);
+}
+
+void tcore_call_information_mo_barred_incoming(CoreObject *o)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_CALL);
+
+ po = tcore_object_ref_object(o);
+
+ tcore_check_null_ret("po", po);
+ tcore_check_null_ret("po->iops", po->iops);
+ tcore_check_null_ret("po->iops->mo_call_barred_incoming", po->iops->mo_call_barred_incoming);
+
+ po->iops->mo_call_barred_incoming(o);
+}
+
+void tcore_call_information_mo_barred_outgoing(CoreObject *o)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_CALL);
+
+ po = tcore_object_ref_object(o);
+
+ tcore_check_null_ret("po", po);
+ tcore_check_null_ret("po->iops", po->iops);
+ tcore_check_null_ret("po->iops->mo_call_barred_outgoing", po->iops->mo_call_barred_outgoing);
+
+ po->iops->mo_call_barred_outgoing(o);
+}
+
+void tcore_call_information_mo_deflected(CoreObject *o)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_CALL);
+
+ po = tcore_object_ref_object(o);
+
+ tcore_check_null_ret("po", po);
+ tcore_check_null_ret("po->iops", po->iops);
+ tcore_check_null_ret("po->iops->mo_call_deflected", po->iops->mo_call_deflected);
+
+ po->iops->mo_call_deflected(o);
+}
+
+void tcore_call_information_mo_clir_suppression_reject(CoreObject *o)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_CALL);
+
+ po = tcore_object_ref_object(o);
+
+ tcore_check_null_ret("po", po);
+ tcore_check_null_ret("po->iops", po->iops);
+ tcore_check_null_ret("po->iops->mo_call_clir_suppression_reject", po->iops->mo_call_clir_suppression_reject);
+
+ po->iops->mo_call_clir_suppression_reject(o);
+}
+
+void tcore_call_information_mo_cfu(CoreObject *o)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_CALL);
+
+ po = tcore_object_ref_object(o);
+
+ tcore_check_null_ret("po", po);
+ tcore_check_null_ret("po->iops", po->iops);
+ tcore_check_null_ret("po->iops->mo_call_cfu", po->iops->mo_call_cfu);
+
+ po->iops->mo_call_cfu(o);
+}
+
+void tcore_call_information_mo_cfc(CoreObject *o)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_CALL);
+
+ po = tcore_object_ref_object(o);
+
+ tcore_check_null_ret("po", po);
+ tcore_check_null_ret("po->iops", po->iops);
+ tcore_check_null_ret("po->iops->mo_call_cfc", po->iops->mo_call_cfc);
+
+ po->iops->mo_call_cfc(o);
+}
+
+void tcore_call_information_mt_cli(CoreObject *o, enum tcore_call_cli_mode mode, char *number)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_CALL);
+
+ po = tcore_object_ref_object(o);
+
+ tcore_check_null_ret("po", po);
+ tcore_check_null_ret("po->iops", po->iops);
+ tcore_check_null_ret("po->iops->mt_call_cli", po->iops->mt_call_cli);
+
+ po->iops->mt_call_cli(o, mode, number);
+}
+
+void tcore_call_information_mt_cna(CoreObject *o, enum tcore_call_cna_mode mode, char *name, int dcs)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_CALL);
+
+ po = tcore_object_ref_object(o);
+
+ tcore_check_null_ret("po", po);
+ tcore_check_null_ret("po->iops", po->iops);
+ tcore_check_null_ret("po->iops->mt_call_cna", po->iops->mt_call_cna);
+
+ po->iops->mt_call_cna(o, mode, name, dcs);
+}
+
+void tcore_call_information_mt_forwarded_call(CoreObject *o, char *number)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_CALL);
+
+ po = tcore_object_ref_object(o);
+
+ tcore_check_null_ret("po", po);
+ tcore_check_null_ret("po->iops", po->iops);
+ tcore_check_null_ret("po->iops->mt_call_forwarded_call", po->iops->mt_call_forwarded_call);
+
+ po->iops->mt_call_forwarded_call(o, number);
+}
+
+void tcore_call_information_mt_cug_call(CoreObject *o, int cug_index, char *number)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_CALL);
+
+ po = tcore_object_ref_object(o);
+
+ tcore_check_null_ret("po", po);
+ tcore_check_null_ret("po->iops", po->iops);
+ tcore_check_null_ret("po->iops->mt_call_cug_call", po->iops->mt_call_cug_call);
+
+ po->iops->mt_call_cug_call(o, cug_index, number);
+}
+
+void tcore_call_information_mt_deflected_call(CoreObject *o, char *number)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_CALL);
+
+ po = tcore_object_ref_object(o);
+
+ tcore_check_null_ret("po", po);
+ tcore_check_null_ret("po->iops", po->iops);
+ tcore_check_null_ret("po->iops->mt_call_deflected_call", po->iops->mt_call_deflected_call);
+
+ po->iops->mt_call_deflected_call(o, number);
+}
+
+void tcore_call_information_mt_transfered(CoreObject *o, char *number)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_CALL);
+
+ po = tcore_object_ref_object(o);
+
+ tcore_check_null_ret("po", po);
+ tcore_check_null_ret("po->iops", po->iops);
+ tcore_check_null_ret("po->iops->mt_call_transfered", po->iops->mt_call_transfered);
+
+ po->iops->mt_call_transfered(o, number);
+}
+
+void tcore_call_information_held(CoreObject *o, char *number)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_CALL);
+
+ po = tcore_object_ref_object(o);
+
+ tcore_check_null_ret("po", po);
+ tcore_check_null_ret("po->iops", po->iops);
+ tcore_check_null_ret("po->iops->call_held", po->iops->call_held);
+
+ po->iops->call_held(o, number);
+}
+
+void tcore_call_information_active(CoreObject *o, char *number)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_CALL);
+
+ po = tcore_object_ref_object(o);
+
+ tcore_check_null_ret("po", po);
+ tcore_check_null_ret("po->iops", po->iops);
+ tcore_check_null_ret("po->iops->call_active", po->iops->call_active);
+
+ po->iops->call_active(o, number);
+}
+
+void tcore_call_information_joined(CoreObject *o, char *number)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_CALL);
+
+ po = tcore_object_ref_object(o);
+
+ tcore_check_null_ret("po", po);
+ tcore_check_null_ret("po->iops", po->iops);
+ tcore_check_null_ret("po->iops->call_joined", po->iops->call_joined);
+
+ po->iops->call_joined(o, number);
+}
+
+void tcore_call_information_released_on_hold(CoreObject *o, char *number)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_CALL);
+
+ po = tcore_object_ref_object(o);
+
+ tcore_check_null_ret("po", po);
+ tcore_check_null_ret("po->iops", po->iops);
+ tcore_check_null_ret("po->iops->call_released_on_hold", po->iops->call_released_on_hold);
+
+ po->iops->call_released_on_hold(o, number);
+}
+
+void tcore_call_information_transfer_alert(CoreObject *o, char *number)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_CALL);
+
+ po = tcore_object_ref_object(o);
+
+ tcore_check_null_ret("po", po);
+ tcore_check_null_ret("po->iops", po->iops);
+ tcore_check_null_ret("po->iops->call_transfer_alert", po->iops->call_transfer_alert);
+
+ po->iops->call_transfer_alert(o, number);
+}
+
+void tcore_call_information_transfered(CoreObject *o, char *number)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_CALL);
+
+ po = tcore_object_ref_object(o);
+
+ tcore_check_null_ret("po", po);
+ tcore_check_null_ret("po->iops", po->iops);
+ tcore_check_null_ret("po->iops->call_transfered", po->iops->call_transfered);
+
+ po->iops->call_transfered(o, number);
+}
+
+void tcore_call_information_cf_check_ss_message(CoreObject *o, char *number)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_CALL);
+
+ po = tcore_object_ref_object(o);
+
+ tcore_check_null_ret("po", po);
+ tcore_check_null_ret("po->iops", po->iops);
+ tcore_check_null_ret("po->iops->call_cf_check_message", po->iops->call_cf_check_message);
+
+ po->iops->call_cf_check_message(o, number);
+}
+
+void tcore_call_information_set_operations(CoreObject *o, struct tcore_call_information_operations *iops)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_CALL);
+
+ po = tcore_object_ref_object(o);
+ if (!po)
+ return;
+
+ po->iops = iops;
+}
+
+CoreObject *tcore_call_new(TcorePlugin *p, const char *name, struct tcore_call_operations *ops, TcoreHal *hal)
+{
+ CoreObject *o = NULL;
+ struct private_object_data *po = NULL;
+
+ if (!p)
+ return NULL;
+
+ o = tcore_object_new(p, name, hal);
+ if (!o)
+ return NULL;
+
+ po = g_try_malloc0(sizeof(struct private_object_data));
+ if (po == NULL) {
+ tcore_object_free(o);
+ return NULL;
+ }
+
+ /* set ops to default type when core object is created. */
+ po->ops[TCORE_OPS_TYPE_CP] = ops;
+
+ tcore_object_set_type(o, CORE_OBJECT_TYPE_CALL);
+ tcore_object_link_object(o, po);
+ tcore_object_set_free_hook(o, _free_hook);
+ tcore_object_set_dispatcher(o, _dispatcher);
+
+ return o;
+}
+
+void tcore_call_free(CoreObject *o)
+{
+ CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_CALL);
+ tcore_object_free(o);
+}
+
+void tcore_call_set_ops(CoreObject *o, struct tcore_call_operations *ops, enum tcore_ops_type ops_type)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_CALL);
+ CORE_OBJECT_VALIDATE_OPS_RETURN(ops_type);
+
+ po = (struct private_object_data *)tcore_object_ref_object(o);
+ if (!po) {
+ err("po is NULL");
+ return;
+ }
+
+ /* set ops according to ops_type */
+ po->ops[ops_type] = ops;
+}
--- /dev/null
+/*
+ * libtcore
+ *
+ * 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.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <glib.h>
+
+#include "tcore.h"
+#include "util.h"
+#include "plugin.h"
+#include "user_request.h"
+#include "co_context.h"
+
+struct private_object_data {
+ enum co_context_state state;
+ unsigned char id;
+ enum co_context_role role;
+ gboolean default_profile;
+ gboolean attach_apn;
+ gboolean roaming_apn;
+
+ char *apn;
+ char *addr;
+ enum co_context_type type;
+ enum co_context_d_comp d_comp;
+ enum co_context_h_comp h_comp;
+ enum co_context_tech tech_pref;
+ char *username;
+ char *password;
+ char *dns1;
+ char *dns2;
+ enum co_context_auth auth;
+
+ union tcore_ip4_type ip_v4;
+ union tcore_ip4_type gateway_v4;
+ union tcore_ip4_type dns_primary_v4;
+ union tcore_ip4_type dns_secondary_v4;
+
+ /* IPv6 will be supported */
+ char *ip_v6;
+ char *gateway_v6;
+ char *dns_primary_v6;
+ char *dns_secondary_v6;
+
+ pcscf_addr *pcscf_ipv4;
+ pcscf_addr *pcscf_ipv6;
+
+ char *proxy;
+ char *mmsurl;
+ char *profile_name;
+ char devname[16];
+
+ /* Dedicated bearer information */
+ struct dedicated_bearer_info dedicated_bearer;
+};
+
+static void _free_hook(CoreObject *o)
+{
+ struct private_object_data *po = NULL;
+
+ po = tcore_object_ref_object(o);
+ if (po) {
+ free(po);
+ tcore_object_link_object(o, NULL);
+ }
+}
+
+CoreObject *tcore_context_new(TcorePlugin *p, const char *name, TcoreHal *hal)
+{
+ CoreObject *o = NULL;
+ struct private_object_data *po = NULL;
+
+ if (!p)
+ return NULL;
+
+ o = tcore_object_new(p, name, hal);
+ if (!o)
+ return NULL;
+
+ po = calloc(1, sizeof(struct private_object_data));
+ if (!po) {
+ tcore_object_free(o);
+ return NULL;
+ }
+
+ po->type = CONTEXT_TYPE_IP;
+ po->d_comp = CONTEXT_D_COMP_OFF;
+ po->h_comp = CONTEXT_H_COMP_OFF;
+ po->role = CONTEXT_ROLE_UNKNOWN;
+ po->auth = CONTEXT_AUTH_NONE;
+ po->tech_pref = CONTEXT_TECH_3GPP;
+
+ tcore_object_set_type(o, CORE_OBJECT_TYPE_PS_CONTEXT);
+ tcore_object_link_object(o, po);
+ tcore_object_set_free_hook(o, _free_hook);
+
+ return o;
+}
+
+void tcore_context_free(CoreObject *o)
+{
+ CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_PS_CONTEXT);
+ tcore_object_free(o);
+}
+
+TReturn tcore_context_set_state(CoreObject *o, enum co_context_state state)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, TCORE_RETURN_EINVAL);
+
+ po = tcore_object_ref_object(o);
+ if (!po)
+ return TCORE_RETURN_EINVAL;
+
+ po->state = state;
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+enum co_context_state tcore_context_get_state(CoreObject *o)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, 0);
+
+ po = tcore_object_ref_object(o);
+ if (!po)
+ return 0;
+
+ return po->state;
+}
+
+TReturn tcore_context_set_id(CoreObject *o, unsigned char id)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, TCORE_RETURN_EINVAL);
+
+ po = tcore_object_ref_object(o);
+ if (!po)
+ return TCORE_RETURN_EINVAL;
+
+ po->id = id;
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+unsigned char tcore_context_get_id(CoreObject *o)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, 0);
+
+ po = tcore_object_ref_object(o);
+ if (!po)
+ return 0;
+
+ return po->id;
+}
+
+TReturn tcore_context_set_apn(CoreObject *o, const char *apn)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, TCORE_RETURN_EINVAL);
+
+ po = tcore_object_ref_object(o);
+ if (!po)
+ return FALSE;
+
+ if (po->apn) {
+ free(po->apn);
+ po->apn = NULL;
+ }
+
+ if (apn)
+ po->apn = g_strdup(apn);
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+char *tcore_context_get_apn(CoreObject *o)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, NULL);
+
+ po = tcore_object_ref_object(o);
+ if (!po)
+ return NULL;
+
+ if (!po->apn)
+ return NULL;
+
+ return g_strdup(po->apn);
+}
+
+TReturn tcore_context_set_address(CoreObject *o, const char *addr)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, TCORE_RETURN_EINVAL);
+
+ po = tcore_object_ref_object(o);
+ if (!po)
+ return TCORE_RETURN_EINVAL;
+
+ if (po->addr) {
+ free(po->addr);
+ po->addr = NULL;
+ }
+
+ if (addr)
+ po->addr = g_strdup(addr);
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+char *tcore_context_get_address(CoreObject *o)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, NULL);
+
+ po = tcore_object_ref_object(o);
+ if (!po)
+ return NULL;
+
+ if (!po->addr)
+ return NULL;
+
+ return g_strdup(po->addr);
+}
+
+TReturn tcore_context_set_role(CoreObject *o, enum co_context_role role)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, TCORE_RETURN_EINVAL);
+
+ po = tcore_object_ref_object(o);
+ if (!po)
+ return TCORE_RETURN_EINVAL;
+
+ po->role = role;
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+enum co_context_role tcore_context_get_role(CoreObject *o)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, 0);
+
+ po = tcore_object_ref_object(o);
+ if (!po)
+ return 0;
+
+ return po->role;
+}
+
+TReturn tcore_context_set_type(CoreObject *o, enum co_context_type type)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, TCORE_RETURN_EINVAL);
+
+ po = tcore_object_ref_object(o);
+ if (!po)
+ return TCORE_RETURN_EINVAL;
+
+ po->type = type;
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+enum co_context_type tcore_context_get_type(CoreObject *o)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, 0);
+
+ po = tcore_object_ref_object(o);
+ if (!po)
+ return 0;
+
+ return po->type;
+}
+
+TReturn tcore_context_set_data_compression(CoreObject *o, enum co_context_d_comp comp)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, TCORE_RETURN_EINVAL);
+
+ po = tcore_object_ref_object(o);
+ if (!po)
+ return TCORE_RETURN_EINVAL;
+
+ po->d_comp = comp;
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+enum co_context_d_comp tcore_context_get_data_compression(CoreObject *o)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, 0);
+
+ po = tcore_object_ref_object(o);
+ if (!po)
+ return 0;
+
+ return po->d_comp;
+}
+
+TReturn tcore_context_set_header_compression(CoreObject *o, enum co_context_h_comp comp)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, TCORE_RETURN_EINVAL);
+
+ po = tcore_object_ref_object(o);
+ if (!po)
+ return TCORE_RETURN_EINVAL;
+
+ po->h_comp = comp;
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+enum co_context_h_comp tcore_context_get_header_compression(CoreObject *o)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, 0);
+
+ po = tcore_object_ref_object(o);
+ if (!po)
+ return 0;
+
+ return po->h_comp;
+}
+
+TReturn tcore_context_set_tech_preference(CoreObject *o, enum co_context_tech tech)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, TCORE_RETURN_EINVAL);
+
+ po = tcore_object_ref_object(o);
+ if (!po)
+ return TCORE_RETURN_EINVAL;
+
+ po->tech_pref = tech;
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+enum co_context_tech tcore_context_get_tech_preference(CoreObject *o)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, 0);
+
+ po = tcore_object_ref_object(o);
+ if (!po)
+ return CONTEXT_TECH_INVALID;
+
+ return po->tech_pref;
+}
+
+TReturn tcore_context_set_username(CoreObject *o, const char *username)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, TCORE_RETURN_EINVAL);
+
+ po = tcore_object_ref_object(o);
+ if (!po)
+ return TCORE_RETURN_EINVAL;
+
+ if (po->username) {
+ free(po->username);
+ po->username = NULL;
+ }
+
+ if (username)
+ po->username = g_strdup(username);
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+char *tcore_context_get_username(CoreObject *o)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, NULL);
+
+ po = tcore_object_ref_object(o);
+ if (!po)
+ return NULL;
+
+ if (!po->username)
+ return NULL;
+
+ return g_strdup(po->username);
+}
+
+TReturn tcore_context_set_password(CoreObject *o, const char *password)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, TCORE_RETURN_EINVAL);
+
+ po = tcore_object_ref_object(o);
+ if (!po)
+ return TCORE_RETURN_EINVAL;
+
+ if (po->password) {
+ free(po->password);
+ po->password = NULL;
+ }
+
+ if (password)
+ po->password = g_strdup(password);
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+char *tcore_context_get_password(CoreObject *o)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, NULL);
+
+ po = tcore_object_ref_object(o);
+ if (!po)
+ return NULL;
+
+ if (!po->password)
+ return NULL;
+
+ return g_strdup(po->password);
+}
+
+TReturn tcore_context_set_dns1(CoreObject *o, const char *dns)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, TCORE_RETURN_EINVAL);
+
+ po = tcore_object_ref_object(o);
+ if (!po)
+ return TCORE_RETURN_EINVAL;
+
+ if (po->dns1) {
+ free(po->dns1);
+ po->dns1 = NULL;
+ }
+
+ if (dns)
+ po->dns1 = g_strdup(dns);
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+TReturn tcore_context_set_ipv6_dns1(CoreObject *o, const char *dns)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, TCORE_RETURN_EINVAL);
+
+ po = tcore_object_ref_object(o);
+ if (!po)
+ return TCORE_RETURN_EINVAL;
+
+ if (po->dns_primary_v6) {
+ free(po->dns_primary_v6);
+ po->dns_primary_v6 = NULL;
+ }
+
+ if (dns)
+ po->dns_primary_v6 = g_strdup(dns);
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+char *tcore_context_get_dns1(CoreObject *o)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, NULL);
+
+ po = tcore_object_ref_object(o);
+ if (!po)
+ return NULL;
+
+ if (!po->dns1)
+ return NULL;
+
+ return g_strdup(po->dns1);
+}
+
+TReturn tcore_context_set_dns2(CoreObject *o, const char *dns)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, TCORE_RETURN_EINVAL);
+
+ po = tcore_object_ref_object(o);
+ if (!po)
+ return TCORE_RETURN_EINVAL;
+
+ if (po->dns2) {
+ free(po->dns2);
+ po->dns2 = NULL;
+ }
+
+ if (dns)
+ po->dns2 = g_strdup(dns);
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+TReturn tcore_context_set_ipv6_dns2(CoreObject *o, const char *dns)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, TCORE_RETURN_EINVAL);
+
+ po = tcore_object_ref_object(o);
+ if (!po)
+ return TCORE_RETURN_EINVAL;
+
+ if (po->dns_secondary_v6) {
+ free(po->dns_secondary_v6);
+ po->dns_secondary_v6 = NULL;
+ }
+
+ if (dns)
+ po->dns_secondary_v6 = g_strdup(dns);
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+char *tcore_context_get_dns2(CoreObject *o)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, NULL);
+
+ po = tcore_object_ref_object(o);
+ if (!po)
+ return NULL;
+
+ if (!po->dns2)
+ return NULL;
+
+ return g_strdup(po->dns2);
+}
+
+TReturn tcore_context_set_auth(CoreObject *o, enum co_context_auth auth)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, TCORE_RETURN_EINVAL);
+
+ po = tcore_object_ref_object(o);
+ if (!po)
+ return TCORE_RETURN_EINVAL;
+
+ po->auth = auth;
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+enum co_context_auth tcore_context_get_auth(CoreObject *o)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, 0);
+
+ po = tcore_object_ref_object(o);
+ if (!po)
+ return 0;
+
+ return po->auth;
+}
+
+TReturn tcore_context_set_proxy(CoreObject *o, const char *proxy)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, TCORE_RETURN_EINVAL);
+
+ po = tcore_object_ref_object(o);
+ if (!po)
+ return FALSE;
+
+ if (po->proxy) {
+ free(po->proxy);
+ po->apn = NULL;
+ }
+
+ if (proxy)
+ po->proxy = g_strdup(proxy);
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+char *tcore_context_get_proxy(CoreObject *o)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, NULL);
+
+ po = tcore_object_ref_object(o);
+ if (!po)
+ return NULL;
+
+ if (!po->proxy)
+ return NULL;
+
+ return g_strdup(po->proxy);
+}
+
+TReturn tcore_context_set_mmsurl(CoreObject *o, const char *mmsurl)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, TCORE_RETURN_EINVAL);
+
+ po = tcore_object_ref_object(o);
+ if (!po)
+ return FALSE;
+
+ if (po->mmsurl) {
+ free(po->mmsurl);
+ po->mmsurl = NULL;
+ }
+
+ if (mmsurl)
+ po->mmsurl = g_strdup(mmsurl);
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+char *tcore_context_get_mmsurl(CoreObject *o)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, NULL);
+
+ po = tcore_object_ref_object(o);
+ if (!po)
+ return NULL;
+
+ if (!po->mmsurl)
+ return NULL;
+
+ return g_strdup(po->mmsurl);
+}
+
+TReturn tcore_context_set_profile_name(CoreObject *o, const char *profile_name)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, TCORE_RETURN_EINVAL);
+
+ po = tcore_object_ref_object(o);
+ if (!po)
+ return FALSE;
+
+ if (po->profile_name) {
+ free(po->profile_name);
+ po->profile_name = NULL;
+ }
+
+ if (profile_name)
+ po->profile_name = g_strdup(profile_name);
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+char *tcore_context_get_profile_name(CoreObject *o)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, NULL);
+
+ po = tcore_object_ref_object(o);
+ if (!po)
+ return NULL;
+
+ if (!po->profile_name)
+ return NULL;
+
+ return g_strdup(po->profile_name);
+}
+
+TReturn tcore_context_set_default_profile(CoreObject *o, gboolean default_conn)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, TCORE_RETURN_EINVAL);
+
+ po = tcore_object_ref_object(o);
+ if (!po)
+ return TCORE_RETURN_EINVAL;
+
+ po->default_profile = default_conn;
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+gboolean tcore_context_get_default_profile(CoreObject *o)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, FALSE);
+
+ po = tcore_object_ref_object(o);
+ if (!po)
+ return FALSE;
+
+ return po->default_profile;
+}
+
+TReturn tcore_context_set_devinfo(CoreObject *o, struct tnoti_ps_pdp_ipconfiguration *devinfo)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, TCORE_RETURN_EINVAL);
+
+ po = tcore_object_ref_object(o);
+
+ if (!po || !devinfo)
+ return TCORE_RETURN_EINVAL;
+
+ /* Free context resource if it was already allocated */
+ tcore_context_reset_devinfo(o);
+
+ po->ip_v6 = g_strdup((gchar *)devinfo->ipv6_address);
+ po->dns_primary_v6 = g_strdup((gchar *)devinfo->ipv6_primary_dns);
+ po->dns_secondary_v6 = g_strdup((gchar *)devinfo->ipv6_secondary_dns);
+ po->gateway_v6 = g_strdup((gchar *)devinfo->ipv6_gateway);
+ memcpy(&(po->ip_v4), devinfo->ip_address, sizeof(union tcore_ip4_type));
+ memcpy(&(po->dns_primary_v4), devinfo->primary_dns, sizeof(union tcore_ip4_type));
+ memcpy(&(po->dns_secondary_v4), devinfo->secondary_dns, sizeof(union tcore_ip4_type));
+ memcpy(&(po->gateway_v4), devinfo->gateway, sizeof(union tcore_ip4_type));
+ memcpy(po->devname, devinfo->devname, sizeof(char) * 16);
+
+ po->pcscf_ipv4 = g_try_malloc0(sizeof(pcscf_addr));
+ if (po->pcscf_ipv4) {
+ po->pcscf_ipv4->count = devinfo->pcscf_ipv4_count;
+ if (po->pcscf_ipv4->count > 0) {
+ unsigned int i;
+ po->pcscf_ipv4->addr = g_try_malloc0(sizeof(char *) * po->pcscf_ipv4->count);
+ if ((po->pcscf_ipv4->addr) && (devinfo->pcscf_ipv4))
+ for (i = 0; i < po->pcscf_ipv4->count; i++)
+ po->pcscf_ipv4->addr[i] = g_strdup(devinfo->pcscf_ipv4[i]);
+ }
+ }
+
+ po->pcscf_ipv6 = g_try_malloc0(sizeof(pcscf_addr));
+ if (po->pcscf_ipv6) {
+ po->pcscf_ipv6->count = devinfo->pcscf_ipv6_count;
+ if (po->pcscf_ipv6->count > 0) {
+ unsigned int i;
+ po->pcscf_ipv6->addr = g_try_malloc0(sizeof(char *) * po->pcscf_ipv6->count);
+ if ((po->pcscf_ipv6->addr) && (devinfo->pcscf_ipv6))
+ for (i = 0; i < po->pcscf_ipv6->count; i++)
+ po->pcscf_ipv6->addr[i] = g_strdup(devinfo->pcscf_ipv6[i]);
+ }
+ }
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+TReturn tcore_context_reset_devinfo(CoreObject *o)
+{
+ struct private_object_data *po = NULL;
+ unsigned int i;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, TCORE_RETURN_EINVAL);
+
+ po = tcore_object_ref_object(o);
+ if (!po)
+ return TCORE_RETURN_EINVAL;
+
+ if (po->ip_v6) {
+ g_free(po->ip_v6);
+ po->ip_v6 = NULL;
+ }
+
+ if (po->dns_primary_v6) {
+ g_free(po->dns_primary_v6);
+ po->dns_primary_v6 = NULL;
+ }
+
+ if (po->dns_secondary_v6) {
+ g_free(po->dns_secondary_v6);
+ po->dns_secondary_v6 = NULL;
+ }
+
+ if (po->gateway_v6) {
+ g_free(po->gateway_v6);
+ po->gateway_v6 = NULL;
+ }
+
+ if (po->pcscf_ipv4) {
+ for (i = 0; i < po->pcscf_ipv4->count; i++)
+ g_free(po->pcscf_ipv4->addr[i]);
+ g_free(po->pcscf_ipv4);
+ po->pcscf_ipv4 = NULL;
+ }
+
+ if (po->pcscf_ipv6) {
+ for (i = 0; i < po->pcscf_ipv6->count; i++)
+ g_free(po->pcscf_ipv6->addr[i]);
+ g_free(po->pcscf_ipv6);
+ po->pcscf_ipv6 = NULL;
+ }
+
+ memset(&(po->ip_v4), 0, sizeof(union tcore_ip4_type));
+ memset(&(po->dns_primary_v4), 0, sizeof(union tcore_ip4_type));
+ memset(&(po->dns_secondary_v4), 0, sizeof(union tcore_ip4_type));
+ memset(&(po->gateway_v4), 0, sizeof(union tcore_ip4_type));
+ memset(po->devname, 0, sizeof(char) * 16);
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+TReturn tcore_context_set_bearer_info(CoreObject *o, struct tnoti_ps_dedicated_bearer_info *bearer_info)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, TCORE_RETURN_EINVAL);
+
+ po = tcore_object_ref_object(o);
+ if (!po)
+ return TCORE_RETURN_EINVAL;
+
+ if (!bearer_info)
+ return TCORE_RETURN_EINVAL;
+
+ if (bearer_info->dedicated_bearer.num_dedicated_bearer > 0)
+ memcpy(&(po->dedicated_bearer), &(bearer_info->dedicated_bearer), sizeof(struct dedicated_bearer_info));
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+TReturn tcore_context_get_bearer_info(CoreObject *o, struct dedicated_bearer_info *bearer_info)
+{
+ struct private_object_data *po = NULL;
+ guchar count = 0;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, TCORE_RETURN_EINVAL);
+
+ po = tcore_object_ref_object(o);
+ if (!po)
+ return TCORE_RETURN_EINVAL;
+
+ if (!bearer_info)
+ return TCORE_RETURN_EINVAL;
+
+ count = po->dedicated_bearer.num_dedicated_bearer;
+ if (count > MAX_NUM_DEDICATED_BEARER)
+ return TCORE_RETURN_EINVAL;
+
+ if (count > 0) {
+ bearer_info->num_dedicated_bearer = count;
+ bearer_info->secondary_context_id = po->dedicated_bearer.secondary_context_id;
+ memcpy(bearer_info->qos, po->dedicated_bearer.qos, count*sizeof(struct qos_parameter));
+ }
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+TReturn tcore_context_reset_bearer_info(CoreObject *o)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, TCORE_RETURN_EINVAL);
+
+ po = tcore_object_ref_object(o);
+ if (!po)
+ return TCORE_RETURN_EINVAL;
+
+ if (po->dedicated_bearer.num_dedicated_bearer > 0)
+ memset(&(po->dedicated_bearer), 0, sizeof(struct dedicated_bearer_info));
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+void tcore_context_cp_service_info(CoreObject *dest, CoreObject *src)
+{
+ struct private_object_data *d_po = NULL;
+ struct private_object_data *s_po = NULL;
+
+ CORE_OBJECT_CHECK(dest, CORE_OBJECT_TYPE_PS_CONTEXT);
+ CORE_OBJECT_CHECK(src, CORE_OBJECT_TYPE_PS_CONTEXT);
+
+ d_po = tcore_object_ref_object(dest);
+ s_po = tcore_object_ref_object(src);
+
+ d_po->state = s_po->state;
+ d_po->id = s_po->id;
+
+ d_po->ip_v6 = g_strdup(s_po->ip_v6);
+ d_po->dns_primary_v6 = g_strdup(s_po->dns_primary_v6);
+ d_po->dns_secondary_v6 = g_strdup(s_po->dns_secondary_v6);
+ d_po->gateway_v6 = g_strdup(s_po->gateway_v6);
+
+ memcpy(&(d_po->ip_v4), &(s_po->ip_v4), sizeof(union tcore_ip4_type));
+ memcpy(&(d_po->dns_primary_v4), &(s_po->dns_primary_v4), sizeof(union tcore_ip4_type));
+ memcpy(&(d_po->dns_secondary_v4), &(s_po->dns_secondary_v4), sizeof(union tcore_ip4_type));
+ memcpy(&(d_po->gateway_v4), &(s_po->gateway_v4), sizeof(union tcore_ip4_type));
+ memcpy(d_po->devname, s_po->devname, sizeof(char) * 16);
+}
+
+char *tcore_context_get_ipv4_addr(CoreObject *o)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, NULL);
+
+ po = tcore_object_ref_object(o);
+ if (!po)
+ return NULL;
+
+ return tcore_util_get_string_by_ip4type(po->ip_v4);
+}
+
+char *tcore_context_get_ipv4_dns1(CoreObject *o)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, NULL);
+
+ po = tcore_object_ref_object(o);
+ if (!po)
+ return NULL;
+
+ return tcore_util_get_string_by_ip4type(po->dns_primary_v4);
+}
+
+char *tcore_context_get_ipv4_dns2(CoreObject *o)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, NULL);
+
+ po = tcore_object_ref_object(o);
+ if (!po)
+ return NULL;
+
+ return tcore_util_get_string_by_ip4type(po->dns_secondary_v4);
+}
+
+char *tcore_context_get_ipv4_gw(CoreObject *o)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, NULL);
+
+ po = tcore_object_ref_object(o);
+ if (!po)
+ return NULL;
+
+ return tcore_util_get_string_by_ip4type(po->gateway_v4);
+}
+
+char *tcore_context_get_ipv4_devname(CoreObject *o)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, NULL);
+
+ po = tcore_object_ref_object(o);
+ if (!po)
+ return NULL;
+
+ if (po->devname[0] == 0)
+ return NULL;
+
+ return g_strdup(po->devname);
+}
+
+char *tcore_context_get_ipv6_addr(CoreObject *o)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, NULL);
+
+ po = tcore_object_ref_object(o);
+ if (!po)
+ return NULL;
+
+ return g_strdup(po->ip_v6);
+}
+
+char *tcore_context_get_ipv6_dns1(CoreObject *o)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, NULL);
+
+ po = tcore_object_ref_object(o);
+ if (!po)
+ return NULL;
+
+ return g_strdup(po->dns_primary_v6);
+}
+
+char *tcore_context_get_ipv6_dns2(CoreObject *o)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, NULL);
+
+ po = tcore_object_ref_object(o);
+ if (!po)
+ return NULL;
+
+ return g_strdup(po->dns_secondary_v6);
+}
+
+char *tcore_context_get_ipv6_gw(CoreObject *o)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, NULL);
+
+ po = tcore_object_ref_object(o);
+ if (!po)
+ return NULL;
+
+ return g_strdup(po->gateway_v6);
+}
+
+pcscf_addr *tcore_context_get_pcscf_ipv4_addr(CoreObject *o)
+{
+ struct private_object_data *po = NULL;
+ pcscf_addr *pcscf_tmp;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, NULL);
+
+ po = tcore_object_ref_object(o);
+ if (!po)
+ return NULL;
+
+ if (!po->pcscf_ipv4)
+ return NULL;
+
+ pcscf_tmp = g_try_malloc0(sizeof(pcscf_addr));
+ if (!pcscf_tmp)
+ return NULL;
+
+ pcscf_tmp->count = po->pcscf_ipv4->count;
+ if (pcscf_tmp->count > 0) {
+ unsigned int i;
+ pcscf_tmp->addr = g_try_malloc0(sizeof(char *) * po->pcscf_ipv4->count);
+ if (!pcscf_tmp->addr) {
+ g_free(pcscf_tmp);
+ return NULL;
+ }
+
+ for (i = 0; i < po->pcscf_ipv4->count; i++)
+ pcscf_tmp->addr[i] = g_strdup(po->pcscf_ipv4->addr[i]);
+ }
+
+ return pcscf_tmp;
+}
+
+pcscf_addr *tcore_context_get_pcscf_ipv6_addr(CoreObject *o)
+{
+ struct private_object_data *po = NULL;
+ pcscf_addr *pcscf_tmp;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, NULL);
+
+ po = tcore_object_ref_object(o);
+ if (!po)
+ return NULL;
+
+ if (!po->pcscf_ipv6)
+ return NULL;
+
+ pcscf_tmp = g_try_malloc0(sizeof(pcscf_addr));
+ if (!pcscf_tmp)
+ return NULL;
+
+ pcscf_tmp->count = po->pcscf_ipv6->count;
+ if (pcscf_tmp->count > 0) {
+ unsigned int i;
+ pcscf_tmp->addr = g_try_malloc0(sizeof(char *) * po->pcscf_ipv6->count);
+ if (!pcscf_tmp->addr) {
+ g_free(pcscf_tmp);
+ return NULL;
+ }
+
+ for (i = 0; i < po->pcscf_ipv6->count; i++)
+ pcscf_tmp->addr[i] = g_strdup(po->pcscf_ipv6->addr[i]);
+ }
+
+ return pcscf_tmp;
+}
+
+TReturn tcore_context_set_attach_apn(CoreObject *o, gboolean flag)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, TCORE_RETURN_EINVAL);
+
+ po = tcore_object_ref_object(o);
+ if (!po)
+ return TCORE_RETURN_EINVAL;
+
+ po->attach_apn = flag;
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+gboolean tcore_context_get_attach_apn(CoreObject *o)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, FALSE);
+
+ po = tcore_object_ref_object(o);
+ if (!po)
+ return FALSE;
+
+ return po->attach_apn;
+}
+
+TReturn tcore_context_set_roaming_apn(CoreObject *o, gboolean flag)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, TCORE_RETURN_EINVAL);
+
+ po = tcore_object_ref_object(o);
+ if (!po)
+ return TCORE_RETURN_EINVAL;
+
+ po->roaming_apn = flag;
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+gboolean tcore_context_get_roaming_apn(CoreObject *o)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, FALSE);
+
+ po = tcore_object_ref_object(o);
+ if (!po)
+ return FALSE;
+
+ return po->roaming_apn;
+}
--- /dev/null
+/*
+ * custom
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Anga Santhosh Kumar <santhosh.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 <glib.h>
+
+#include "tcore.h"
+#include "core_object.h"
+#include "co_custom.h"
+
+static void _free_hook(CoreObject *co)
+{
+ CORE_OBJECT_CHECK(co, CORE_OBJECT_TYPE_CUSTOM);
+
+ tcore_object_link_object(co, NULL);
+}
+
+CoreObject *tcore_custom_new(TcorePlugin *p,
+ const char *name, tcore_custom_operations ops,
+ CoreObjectDispatcher dispatcher, TcoreHal *hal)
+{
+ CoreObject *co = NULL;
+
+ if (!p)
+ return NULL;
+
+ co = tcore_object_new(p, name, hal);
+ if (!co)
+ return NULL;
+
+ tcore_object_set_type(co, CORE_OBJECT_TYPE_CUSTOM);
+
+ tcore_object_link_object(co, ops);
+ tcore_object_set_free_hook(co, _free_hook);
+ tcore_object_set_dispatcher(co, dispatcher);
+
+ return co;
+}
+
+void tcore_custom_free(CoreObject *co)
+{
+ CORE_OBJECT_CHECK(co, CORE_OBJECT_TYPE_CUSTOM);
+
+ tcore_object_free(co);
+}
--- /dev/null
+/*
+ * libtcore
+ *
+ * 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.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <glib.h>
+
+#include "tcore.h"
+#include "internal/tcore_types.h"
+#include "plugin.h"
+#include "user_request.h"
+#include "co_gps.h"
+
+struct private_object_data {
+ struct tcore_gps_operations *ops[TCORE_OPS_TYPE_MAX];
+};
+
+static void _free_hook(CoreObject *o)
+{
+ struct private_object_data *po = NULL;
+
+ po = tcore_object_ref_object(o);
+ if (po) {
+ g_free(po);
+ tcore_object_link_object(o, NULL);
+ }
+}
+
+static TReturn _dispatcher(CoreObject *o, UserRequest *ur, enum tcore_ops_type ops_type)
+{
+ enum tcore_request_command command;
+ struct private_object_data *po = tcore_object_ref_object(o);
+ struct tcore_gps_operations *ops = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_GPS, TCORE_RETURN_EINVAL);
+ CORE_OBJECT_VALIDATE_OPS_RETURN_VAL(ops_type, TCORE_RETURN_EINVAL);
+
+ tcore_check_null_ret_err("po", po, TCORE_RETURN_EINVAL);
+ tcore_check_null_ret_err("ur", ur, TCORE_RETURN_EINVAL);
+
+ ops = po->ops[ops_type];
+ tcore_check_null_ret_err("ops", ops, TCORE_RETURN_FAILURE);
+
+ command = tcore_user_request_get_command(ur);
+ switch (command) {
+ case TREQ_GPS_CONFIRM_MEASURE_POS:
+ dbg("TREQ_GPS_CONFIRM_MEASURE_POS");
+ tcore_check_null_ret_err("ops->confirm_measure_pos",
+ ops->confirm_measure_pos, TCORE_RETURN_ENOSYS);
+
+ return ops->confirm_measure_pos(o, ur);
+
+ case TREQ_GPS_SET_FREQUENCY_AIDING:
+ dbg("TREQ_GPS_SET_FREQUENCY_AIDING");
+ tcore_check_null_ret_err("ops->set_frequency_aiding",
+ ops->set_frequency_aiding, TCORE_RETURN_ENOSYS);
+
+ return ops->set_frequency_aiding(o, ur);
+
+ case TREQ_ENABLE_SMART_ASSISTANT:
+ dbg("TREQ_ENABLE_SMART_ASSISTANT");
+ tcore_check_null_ret_err("ops->enable_smart_assistant",
+ ops->enable_smart_assistant, TCORE_RETURN_ENOSYS);
+
+ return ops->enable_smart_assistant(o, ur);
+
+ case TREQ_DISABLE_SMART_ASSISTANT:
+ dbg("TREQ_DISABLE_SMART_ASSISTANT");
+ tcore_check_null_ret_err("ops->disable_smart_assistant",
+ ops->disable_smart_assistant, TCORE_RETURN_ENOSYS);
+
+ return ops->disable_smart_assistant(o, ur);
+
+ case TREQ_SYNC_SMART_ASSISTANT_AREA_LIST:
+ dbg("TREQ_SYNC_SMART_ASSISTANT_AREA_LIST");
+ tcore_check_null_ret_err("ops->sync_smart_assistant_area_list",
+ ops->sync_smart_assistant_area_list, TCORE_RETURN_ENOSYS);
+
+ return ops->sync_smart_assistant_area_list(o, ur);
+
+ case TREQ_DEL_SMART_ASSISTANT_AREA_LIST:
+ dbg("TREQ_DEL_SMART_ASSISTANT_AREA_LIST");
+ tcore_check_null_ret_err("ops->del_smart_assistant_area_list",
+ ops->del_smart_assistant_area_list, TCORE_RETURN_ENOSYS);
+
+ return ops->del_smart_assistant_area_list(o, ur);
+
+ case TREQ_ADD_SMART_ASSISTANT_AREA:
+ dbg("TREQ_ADD_SMART_ASSISTANT_AREA");
+ tcore_check_null_ret_err("ops->add_smart_assistant_area",
+ ops->add_smart_assistant_area, TCORE_RETURN_ENOSYS);
+
+ return ops->add_smart_assistant_area(o, ur);
+
+ case TREQ_MODIFY_SMART_ASSISTANT_AREA:
+ dbg("TREQ_MODIFY_SMART_ASSISTANT_AREA");
+ tcore_check_null_ret_err("ops->modify_smart_assistant_area",
+ ops->modify_smart_assistant_area, TCORE_RETURN_ENOSYS);
+
+ return ops->modify_smart_assistant_area(o, ur);
+
+ case TREQ_SET_SMART_ASSISTANT_INFO:
+ dbg("TREQ_SET_SMART_ASSISTANT_INFO");
+ tcore_check_null_ret_err("ops->set_smart_assistant_info",
+ ops->set_smart_assistant_info, TCORE_RETURN_ENOSYS);
+
+ return ops->set_smart_assistant_info(o, ur);
+
+ default:
+ dbg("not supported cmd");
+ break;
+ }
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+CoreObject *tcore_gps_new(TcorePlugin *p, const char *name,
+ struct tcore_gps_operations *ops, TcoreHal *hal)
+{
+ CoreObject *o = NULL;
+ struct private_object_data *po = NULL;
+
+ if (!p)
+ return NULL;
+
+ o = tcore_object_new(p, name, hal);
+ if (!o)
+ return NULL;
+
+ po = g_try_malloc0(sizeof(struct private_object_data));
+ if (!po) {
+ tcore_object_free(o);
+ return NULL;
+ }
+
+ /* set ops to default type when core object is created. */
+ po->ops[TCORE_OPS_TYPE_CP] = ops;
+
+ tcore_object_set_type(o, CORE_OBJECT_TYPE_GPS);
+ tcore_object_link_object(o, po);
+ tcore_object_set_dispatcher(o, _dispatcher);
+ tcore_object_set_free_hook(o, _free_hook);
+
+ return o;
+}
+
+void tcore_gps_free(CoreObject *o)
+{
+ CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_GPS);
+
+ tcore_object_free(o);
+}
+
+void tcore_gps_set_ops(CoreObject *o,
+ struct tcore_gps_operations *ops, enum tcore_ops_type ops_type)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_GPS);
+ CORE_OBJECT_VALIDATE_OPS_RETURN(ops_type);
+
+ po = (struct private_object_data *)tcore_object_ref_object(o);
+ if (!po) {
+ err("po is NULL");
+ return;
+ }
+
+ /* set ops according to ops_type */
+ po->ops[ops_type] = ops;
+}
--- /dev/null
+/*
+ * libtcore
+ *
+ * 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.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <glib.h>
+
+#include "tcore.h"
+#include "internal/tcore_types.h"
+#include "plugin.h"
+#include "user_request.h"
+#include "co_modem.h"
+#include "hal.h"
+
+struct private_object_data {
+ struct tcore_modem_operations *ops[TCORE_OPS_TYPE_MAX];
+
+ gboolean flight_mode;
+ gboolean powered;
+};
+
+static void _free_hook(CoreObject *o)
+{
+ struct private_object_data *po = NULL;
+
+ po = tcore_object_ref_object(o);
+ if (po) {
+ free(po);
+ tcore_object_link_object(o, NULL);
+ }
+}
+
+static TReturn _dispatcher(CoreObject *o, UserRequest *ur, enum tcore_ops_type ops_type)
+{
+ enum tcore_request_command command;
+ struct private_object_data *po = tcore_object_ref_object(o);
+ struct tcore_modem_operations *ops = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_MODEM, TCORE_RETURN_EINVAL);
+ CORE_OBJECT_VALIDATE_OPS_RETURN_VAL(ops_type, TCORE_RETURN_EINVAL);
+
+ tcore_check_null_ret_err("po", po, TCORE_RETURN_EINVAL);
+ tcore_check_null_ret_err("ur", ur, TCORE_RETURN_EINVAL);
+
+ ops = po->ops[ops_type];
+ tcore_check_null_ret_err("ops", ops, TCORE_RETURN_FAILURE);
+
+ command = tcore_user_request_get_command(ur);
+ switch (command) {
+ case TREQ_MODEM_POWER_ON:
+ tcore_check_null_ret_err("ops->power_on",
+ ops->power_on, TCORE_RETURN_ENOSYS);
+
+ return ops->power_on(o, ur);
+
+ case TREQ_MODEM_POWER_OFF:
+ tcore_check_null_ret_err("ops->power_off",
+ ops->power_off, TCORE_RETURN_ENOSYS);
+
+ return ops->power_off(o, ur);
+
+ case TREQ_MODEM_POWER_RESET:
+ tcore_check_null_ret_err("ops->power_reset",
+ ops->power_reset, TCORE_RETURN_ENOSYS);
+
+ return ops->power_reset(o, ur);
+
+ case TREQ_MODEM_POWER_LOW:
+ tcore_check_null_ret_err("ops->power_low",
+ ops->power_low, TCORE_RETURN_ENOSYS);
+
+ return ops->power_low(o, ur);
+
+ case TREQ_MODEM_SET_FLIGHTMODE:
+ tcore_check_null_ret_err("ops->set_flight_mode",
+ ops->set_flight_mode, TCORE_RETURN_ENOSYS);
+
+ return ops->set_flight_mode(o, ur);
+
+ case TREQ_MODEM_GET_IMEI:
+ tcore_check_null_ret_err("ops->get_imei",
+ ops->get_imei, TCORE_RETURN_ENOSYS);
+
+ return ops->get_imei(o, ur);
+
+ case TREQ_MODEM_GET_VERSION:
+ tcore_check_null_ret_err("ops->get_version",
+ ops->get_version, TCORE_RETURN_ENOSYS);
+
+ return ops->get_version(o, ur);
+
+ case TREQ_MODEM_GET_SN:
+ tcore_check_null_ret_err("ops->get_sn",
+ ops->get_sn, TCORE_RETURN_ENOSYS);
+
+ return ops->get_sn(o, ur);
+
+ case TREQ_MODEM_SET_DUN_PIN_CONTROL:
+ tcore_check_null_ret_err("ops->dun_pin_ctrl",
+ ops->dun_pin_ctrl, TCORE_RETURN_ENOSYS);
+
+ return ops->dun_pin_ctrl(o, ur);
+
+ case TREQ_MODEM_GET_FLIGHTMODE:
+ tcore_check_null_ret_err("ops->get_flight_mode",
+ ops->get_flight_mode, TCORE_RETURN_ENOSYS);
+
+ return ops->get_flight_mode(o, ur);
+
+ case TREQ_MODEM_GET_DEVICE_INFO:
+ tcore_check_null_ret_err("ops->get_device_info",
+ ops->get_device_info, TCORE_RETURN_ENOSYS);
+
+ return ops->get_device_info(o, ur);
+
+ default:
+ return TCORE_RETURN_EINVAL;
+ }
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+CoreObject *tcore_modem_new(TcorePlugin *p, const char *name,
+ struct tcore_modem_operations *ops, TcoreHal *hal)
+{
+ CoreObject *o = NULL;
+ struct private_object_data *po = NULL;
+
+ if (!p)
+ return NULL;
+
+ o = tcore_object_new(p, name, hal);
+ if (!o)
+ return NULL;
+
+ po = calloc(1, sizeof(struct private_object_data));
+ if (!po) {
+ tcore_object_free(o);
+ return NULL;
+ }
+
+ /* set ops to default type when core object is created. */
+ po->ops[TCORE_OPS_TYPE_CP] = ops;
+
+ tcore_object_set_type(o, CORE_OBJECT_TYPE_MODEM);
+ tcore_object_link_object(o, po);
+ tcore_object_set_free_hook(o, _free_hook);
+ tcore_object_set_dispatcher(o, _dispatcher);
+
+ return o;
+}
+
+void tcore_modem_free(CoreObject *o)
+{
+ CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_MODEM);
+ tcore_object_free(o);
+}
+
+void tcore_modem_set_ops(CoreObject *o, struct tcore_modem_operations *ops, enum tcore_ops_type ops_type)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_MODEM);
+ CORE_OBJECT_VALIDATE_OPS_RETURN(ops_type);
+
+ po = (struct private_object_data *)tcore_object_ref_object(o);
+ if (!po) {
+ err("po is NULL");
+ return;
+ }
+
+ po->ops[ops_type] = ops;
+}
+
+TReturn tcore_modem_set_flight_mode_state(CoreObject *o, gboolean flag)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_MODEM, TCORE_RETURN_EINVAL);
+
+ po = tcore_object_ref_object(o);
+ if (!po)
+ return TCORE_RETURN_EINVAL;
+
+ po->flight_mode = flag;
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+gboolean tcore_modem_get_flight_mode_state(CoreObject *o)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_MODEM, FALSE);
+
+ po = tcore_object_ref_object(o);
+ if (!po)
+ return FALSE;
+
+ return po->flight_mode;
+}
+
+TReturn tcore_modem_set_powered(CoreObject *o, gboolean pwr)
+{
+ TcoreHal *h;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_MODEM, TCORE_RETURN_EINVAL);
+
+ h = tcore_object_get_hal(o);
+ if (!h)
+ return TCORE_RETURN_FAILURE;
+
+ tcore_hal_set_power_state(h, pwr);
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+gboolean tcore_modem_get_powered(CoreObject *o)
+{
+ TcoreHal *h;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_MODEM, FALSE);
+
+ h = tcore_object_get_hal(o);
+ if (!h)
+ return FALSE;
+
+ return tcore_hal_get_power_state(h);
+}
--- /dev/null
+/*
+ * libtcore
+ *
+ * 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.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <glib.h>
+
+#include "tcore.h"
+#include "internal/tcore_types.h"
+#include "plugin.h"
+#include "queue.h"
+#include "server.h"
+#include "user_request.h"
+#include "co_network.h"
+#include "storage.h"
+
+struct private_object_data {
+ struct tcore_network_operations *ops[TCORE_OPS_TYPE_MAX];
+
+ enum telephony_network_service_type service_type;
+ enum telephony_network_access_technology act;
+ enum telephony_network_service_domain_status cs_domain_status;
+ enum telephony_network_service_domain_status ps_domain_status;
+ char *plmn;
+ gboolean roaming_state;
+ int restricted_state;
+ unsigned int lac; /* represent LAC or TAC(in case of LTE) */
+ unsigned int rac;
+ unsigned int cell_id;
+ gboolean gsm_dtm_support; /* DTM (Dual Transfer Mode) */
+
+ char *network_name_short;
+ char *network_name_full;
+ char *network_name_spn;
+ enum tcore_network_name_priority network_name_priority;
+ GHashTable *operator_info_hash;
+ struct tel_network_ims_registration_info ims_reg_info; /* IMS specific */
+ gboolean ims_voice_status;
+ enum telephony_network_ecc_rat_search_status rat_search_status;
+ enum telephony_network_access_technology ecc_rat;
+};
+
+static TReturn _dispatcher(CoreObject *co, UserRequest *ur, enum tcore_ops_type ops_type)
+{
+ enum tcore_request_command command;
+ struct private_object_data *po = tcore_object_ref_object(co);
+ struct tcore_network_operations *ops = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(co, CORE_OBJECT_TYPE_NETWORK, TCORE_RETURN_EINVAL);
+ CORE_OBJECT_VALIDATE_OPS_RETURN_VAL(ops_type, TCORE_RETURN_EINVAL);
+
+ tcore_check_null_ret_err("po", po, TCORE_RETURN_EINVAL);
+ tcore_check_null_ret_err("ur", ur, TCORE_RETURN_EINVAL);
+
+ ops = po->ops[ops_type];
+ tcore_check_null_ret_err("ops", ops, TCORE_RETURN_FAILURE);
+
+ command = tcore_user_request_get_command(ur);
+ switch (command) {
+ case TREQ_NETWORK_SEARCH:
+ tcore_check_null_ret_err("ops->search",
+ ops->search, TCORE_RETURN_ENOSYS);
+
+ return ops->search(co, ur);
+
+ case TREQ_NETWORK_SET_PLMN_SELECTION_MODE:
+ tcore_check_null_ret_err("ops->set_plmn_selection_mode",
+ ops->set_plmn_selection_mode, TCORE_RETURN_ENOSYS);
+
+ return ops->set_plmn_selection_mode(co, ur);
+
+ case TREQ_NETWORK_GET_PLMN_SELECTION_MODE:
+ tcore_check_null_ret_err("ops->get_plmn_selection_mode",
+ ops->get_plmn_selection_mode, TCORE_RETURN_ENOSYS);
+
+ return ops->get_plmn_selection_mode(co, ur);
+
+ case TREQ_NETWORK_SET_SERVICE_DOMAIN:
+ tcore_check_null_ret_err("ops->set_service_domain",
+ ops->set_service_domain, TCORE_RETURN_ENOSYS);
+
+ return ops->set_service_domain(co, ur);
+
+ case TREQ_NETWORK_GET_SERVICE_DOMAIN:
+ tcore_check_null_ret_err("ops->get_service_domain",
+ ops->get_service_domain, TCORE_RETURN_ENOSYS);
+
+ return ops->get_service_domain(co, ur);
+
+ case TREQ_NETWORK_SET_BAND:
+ tcore_check_null_ret_err("ops->set_band",
+ ops->set_band, TCORE_RETURN_ENOSYS);
+
+ return ops->set_band(co, ur);
+
+ case TREQ_NETWORK_GET_BAND:
+ tcore_check_null_ret_err("ops->get_band",
+ ops->get_band, TCORE_RETURN_ENOSYS);
+
+ return ops->get_band(co, ur);
+
+ case TREQ_NETWORK_SET_PREFERRED_PLMN:
+ tcore_check_null_ret_err("ops->set_preferred_plmn",
+ ops->set_preferred_plmn, TCORE_RETURN_ENOSYS);
+
+ return ops->set_preferred_plmn(co, ur);
+
+ case TREQ_NETWORK_GET_PREFERRED_PLMN:
+ tcore_check_null_ret_err("ops->get_preferred_plmn",
+ ops->get_preferred_plmn, TCORE_RETURN_ENOSYS);
+
+ return ops->get_preferred_plmn(co, ur);
+
+ case TREQ_NETWORK_SET_ORDER:
+ tcore_check_null_ret_err("ops->set_order",
+ ops->set_order, TCORE_RETURN_ENOSYS);
+
+ return ops->set_order(co, ur);
+
+ case TREQ_NETWORK_GET_ORDER:
+ tcore_check_null_ret_err("ops->get_order",
+ ops->get_order, TCORE_RETURN_ENOSYS);
+
+ return ops->get_order(co, ur);
+
+ case TREQ_NETWORK_SET_POWER_ON_ATTACH:
+ tcore_check_null_ret_err("ops->set_power_on_attach",
+ ops->set_power_on_attach, TCORE_RETURN_ENOSYS);
+
+ return ops->set_power_on_attach(co, ur);
+
+ case TREQ_NETWORK_GET_POWER_ON_ATTACH:
+ tcore_check_null_ret_err("ops->get_power_on_attach",
+ ops->get_power_on_attach, TCORE_RETURN_ENOSYS);
+
+ return ops->get_power_on_attach(co, ur);
+
+ case TREQ_NETWORK_SET_CANCEL_MANUAL_SEARCH:
+ tcore_check_null_ret_err("ops->set_cancel_manual_search",
+ ops->set_cancel_manual_search, TCORE_RETURN_ENOSYS);
+
+ return ops->set_cancel_manual_search(co, ur);
+
+ case TREQ_NETWORK_GET_SERVING_NETWORK:
+ tcore_check_null_ret_err("ops->get_serving_network",
+ ops->get_serving_network, TCORE_RETURN_ENOSYS);
+
+ return ops->get_serving_network(co, ur);
+
+ case TREQ_NETWORK_SET_MODE:
+ tcore_check_null_ret_err("ops->set_mode",
+ ops->set_mode, TCORE_RETURN_ENOSYS);
+
+ return ops->set_mode(co, ur);
+
+ case TREQ_NETWORK_GET_MODE:
+ tcore_check_null_ret_err("ops->get_mode",
+ ops->get_mode, TCORE_RETURN_ENOSYS);
+
+ return ops->get_mode(co, ur);
+
+ case TREQ_NETWORK_SET_NEIGHBORING_CELL_INFO:
+ tcore_check_null_ret_err("ops->set_neighboring_cell_info",
+ ops->set_neighboring_cell_info, TCORE_RETURN_ENOSYS);
+
+ return ops->set_neighboring_cell_info(co, ur);
+
+ case TREQ_NETWORK_GET_NEIGHBORING_CELL_INFO:
+ tcore_check_null_ret_err("ops->get_neighboring_cell_info",
+ ops->get_neighboring_cell_info, TCORE_RETURN_ENOSYS);
+
+ return ops->get_neighboring_cell_info(co, ur);
+
+ case TREQ_NETWORK_SET_DEFAULT_DATA_SUBSCRIPTION:
+ tcore_check_null_ret_err("ops->set_default_data_subscription",
+ ops->set_default_data_subscription, TCORE_RETURN_ENOSYS);
+
+ return ops->set_default_data_subscription(co, ur);
+
+ case TREQ_NETWORK_GET_DEFAULT_DATA_SUBSCRIPTION:
+ tcore_check_null_ret_err("ops->get_default_data_subscription",
+ ops->get_default_data_subscription, TCORE_RETURN_ENOSYS);
+
+ return ops->get_default_data_subscription(co, ur);
+
+ case TREQ_NETWORK_SET_DEFAULT_SUBSCRIPTION:
+ tcore_check_null_ret_err("ops->set_default_subscription",
+ ops->set_default_subscription, TCORE_RETURN_ENOSYS);
+
+ return ops->set_default_subscription(co, ur);
+
+ case TREQ_NETWORK_GET_DEFAULT_SUBSCRIPTION:
+ tcore_check_null_ret_err("ops->get_default_subscription",
+ ops->get_default_subscription, TCORE_RETURN_ENOSYS);
+
+ return ops->get_default_subscription(co, ur);
+
+ case TREQ_NETWORK_SET_EMERGENCY_CALLBACK_MODE:
+ tcore_check_null_ret_err("ops->set_emergency_callback_mode",
+ ops->set_emergency_callback_mode, TCORE_RETURN_ENOSYS);
+
+ return ops->set_emergency_callback_mode(co, ur);
+
+ case TREQ_NETWORK_SET_ROAMING_PREFERENCE:
+ tcore_check_null_ret_err("ops->set_roaming_preference",
+ ops->set_roaming_preference, TCORE_RETURN_ENOSYS);
+
+ return ops->set_roaming_preference(co, ur);
+
+ case TREQ_NETWORK_GET_ROAMING_PREFERENCE:
+ tcore_check_null_ret_err("ops->get_roaming_preference",
+ ops->get_roaming_preference, TCORE_RETURN_ENOSYS);
+
+ return ops->get_roaming_preference(co, ur);
+
+ case TREQ_NETWORK_GET_SUBSCRIPTION_INFO:
+ tcore_check_null_ret_err("ops->get_subscription_info",
+ ops->get_subscription_info, TCORE_RETURN_ENOSYS);
+
+ return ops->get_subscription_info(co, ur);
+
+ case TREQ_NETWORK_SEARCH_ECC_RAT:
+ tcore_check_null_ret_err("ops->search_ecc_rat",
+ ops->search_ecc_rat, TCORE_RETURN_ENOSYS);
+
+ return ops->search_ecc_rat(co, ur);
+
+ case TREQ_NETWORK_IMS_DEREGISTER:
+ tcore_check_null_ret_err("ops->ims_deregister",
+ ops->ims_deregister, TCORE_RETURN_ENOSYS);
+
+ return ops->ims_deregister(co, ur);
+
+ default:
+ break;
+ }
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+static void _free_hook(CoreObject *co)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK(co, CORE_OBJECT_TYPE_NETWORK);
+
+ po = tcore_object_ref_object(co);
+ if (po) {
+ g_free(po);
+ tcore_object_link_object(co, NULL);
+ }
+}
+
+CoreObject *tcore_network_new(TcorePlugin *plugin, const char *name,
+ struct tcore_network_operations *ops, TcoreHal *hal)
+{
+ CoreObject *o = NULL;
+ struct private_object_data *po = NULL;
+
+ if (!plugin)
+ return NULL;
+
+ o = tcore_object_new(plugin, name, hal);
+ if (!o)
+ return NULL;
+
+ po = g_try_malloc0(sizeof(struct private_object_data));
+ if (!po) {
+ tcore_object_free(o);
+ return NULL;
+ }
+
+ /* set ops to default type when core object is created. */
+ po->ops[TCORE_OPS_TYPE_CP] = ops;
+
+ po->operator_info_hash = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
+
+ tcore_object_set_type(o, CORE_OBJECT_TYPE_NETWORK);
+ tcore_object_link_object(o, po);
+ tcore_object_set_free_hook(o, _free_hook);
+ tcore_object_set_dispatcher(o, _dispatcher);
+
+ return o;
+}
+
+void tcore_network_free(CoreObject *co)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK(co, CORE_OBJECT_TYPE_NETWORK);
+
+ po = tcore_object_ref_object(co);
+ if (!po)
+ return;
+
+ if (po->network_name_short)
+ free(po->network_name_short);
+
+ if (po->network_name_full)
+ free(po->network_name_full);
+
+ if (po->network_name_spn)
+ free(po->network_name_spn);
+
+ if (po->plmn)
+ free(po->plmn);
+
+ if (po->operator_info_hash)
+ g_hash_table_destroy(po->operator_info_hash);
+
+ tcore_object_free(co);
+}
+
+void tcore_network_set_ops(CoreObject *o,
+ struct tcore_network_operations *ops, enum tcore_ops_type ops_type)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_NETWORK);
+ CORE_OBJECT_VALIDATE_OPS_RETURN(ops_type);
+
+ po = (struct private_object_data *)tcore_object_ref_object(o);
+ if (!po) {
+ err("po is NULL");
+ return;
+ }
+
+ po->ops[ops_type] = ops;
+}
+
+char *tcore_network_get_plmn(CoreObject *co)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(co, CORE_OBJECT_TYPE_NETWORK, NULL);
+
+ po = tcore_object_ref_object(co);
+ if (!po)
+ return NULL;
+
+ return g_strdup(po->plmn);
+}
+
+TReturn tcore_network_set_plmn(CoreObject *co, const char *plmn)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(co, CORE_OBJECT_TYPE_NETWORK, TCORE_RETURN_EINVAL);
+
+ po = tcore_object_ref_object(co);
+ if (!po)
+ return TCORE_RETURN_EINVAL;
+
+ if (po->plmn)
+ free(po->plmn);
+
+ po->plmn = g_strdup(plmn);
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+
+char *tcore_network_get_network_name(CoreObject *co,
+ enum tcore_network_name_type type)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(co, CORE_OBJECT_TYPE_NETWORK, NULL);
+
+ po = tcore_object_ref_object(co);
+ if (!po)
+ return NULL;
+
+ if (type == TCORE_NETWORK_NAME_TYPE_SHORT)
+ return g_strdup(po->network_name_short);
+ else if (type == TCORE_NETWORK_NAME_TYPE_FULL)
+ return g_strdup(po->network_name_full);
+ else if (type == TCORE_NETWORK_NAME_TYPE_SPN)
+ return g_strdup(po->network_name_spn);
+ else
+ return NULL;
+}
+
+TReturn tcore_network_set_network_name(CoreObject *co,
+ enum tcore_network_name_type type, const char *network_name)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(co, CORE_OBJECT_TYPE_NETWORK, TCORE_RETURN_EINVAL);
+
+ po = tcore_object_ref_object(co);
+ if (!po)
+ return TCORE_RETURN_EINVAL;
+
+ switch (type) {
+ case TCORE_NETWORK_NAME_TYPE_SHORT:
+ if (po->network_name_short) {
+ free(po->network_name_short);
+ po->network_name_short = NULL;
+ }
+
+ if (network_name)
+ po->network_name_short = g_strdup(network_name);
+
+ break;
+
+ case TCORE_NETWORK_NAME_TYPE_FULL:
+ if (po->network_name_full) {
+ free(po->network_name_full);
+ po->network_name_full = NULL;
+ }
+
+ if (network_name)
+ po->network_name_full = g_strdup(network_name);
+
+ break;
+
+ case TCORE_NETWORK_NAME_TYPE_SPN:
+ if (po->network_name_spn) {
+ free(po->network_name_spn);
+ po->network_name_spn = NULL;
+ }
+
+ if (network_name)
+ po->network_name_spn = g_strdup(network_name);
+
+ break;
+
+ default:
+ return TCORE_RETURN_EINVAL;
+ }
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+TReturn tcore_network_get_network_name_priority(CoreObject *co,
+ enum tcore_network_name_priority *priority)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(co, CORE_OBJECT_TYPE_NETWORK, TCORE_RETURN_EINVAL);
+
+ if (!priority)
+ return TCORE_RETURN_EINVAL;
+
+ po = tcore_object_ref_object(co);
+ if (!po)
+ return FALSE;
+
+ *priority = po->network_name_priority;
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+TReturn tcore_network_set_network_name_priority(CoreObject *co,
+ enum tcore_network_name_priority priority)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(co, CORE_OBJECT_TYPE_NETWORK, TCORE_RETURN_EINVAL);
+
+ po = tcore_object_ref_object(co);
+ if (!po)
+ return TCORE_RETURN_EINVAL;
+
+ po->network_name_priority = priority;
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+gboolean tcore_network_get_roaming_state(CoreObject *co)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(co, CORE_OBJECT_TYPE_NETWORK, FALSE);
+
+ po = tcore_object_ref_object(co);
+ if (!po)
+ return FALSE;
+
+ return po->roaming_state;
+}
+
+TReturn tcore_network_set_roaming_state(CoreObject *co, gboolean state)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(co, CORE_OBJECT_TYPE_NETWORK, TCORE_RETURN_EINVAL);
+
+ po = tcore_object_ref_object(co);
+ if (!po)
+ return TCORE_RETURN_EINVAL;
+
+ po->roaming_state = state;
+ dbg("roaming_state = 0x%x", state);
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+int tcore_network_get_restricted_state(CoreObject *co)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(co, CORE_OBJECT_TYPE_NETWORK, FALSE);
+
+ po = tcore_object_ref_object(co);
+ if (!po)
+ return FALSE;
+
+ return po->restricted_state;
+}
+
+TReturn tcore_network_set_restricted_state(CoreObject *co, int state)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(co, CORE_OBJECT_TYPE_NETWORK, TCORE_RETURN_EINVAL);
+
+ po = tcore_object_ref_object(co);
+ if (!po)
+ return TCORE_RETURN_EINVAL;
+
+ po->restricted_state = state;
+ dbg("restricted_state = 0x%x", state);
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+TReturn tcore_network_get_service_status(CoreObject *co,
+ enum tcore_network_service_domain_type type,
+ enum telephony_network_service_domain_status *result)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(co, CORE_OBJECT_TYPE_NETWORK, TCORE_RETURN_EINVAL);
+
+ if (!result)
+ return TCORE_RETURN_EINVAL;
+
+ po = tcore_object_ref_object(co);
+ if (!po)
+ return TCORE_RETURN_EINVAL;
+
+ switch (type) {
+ case TCORE_NETWORK_SERVICE_DOMAIN_TYPE_CIRCUIT:
+ *result = po->cs_domain_status;
+ break;
+
+ case TCORE_NETWORK_SERVICE_DOMAIN_TYPE_PACKET:
+ *result = po->ps_domain_status;
+ break;
+
+ default:
+ err("invalid network type");
+ break;
+ }
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+TReturn tcore_network_set_service_status(CoreObject *co,
+ enum tcore_network_service_domain_type type,
+ enum telephony_network_service_domain_status status)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(co, CORE_OBJECT_TYPE_NETWORK, TCORE_RETURN_EINVAL);
+
+ po = tcore_object_ref_object(co);
+ if (!po)
+ return TCORE_RETURN_EINVAL;
+
+ switch (type) {
+ case TCORE_NETWORK_SERVICE_DOMAIN_TYPE_CIRCUIT:
+ po->cs_domain_status = status;
+ dbg("cs.status = 0x%x", status);
+ break;
+
+ case TCORE_NETWORK_SERVICE_DOMAIN_TYPE_PACKET:
+ po->ps_domain_status = status;
+ dbg("ps.status = 0x%x", status);
+ break;
+
+ default:
+ err("invalid network type");
+ break;
+ }
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+TReturn tcore_network_set_access_technology(CoreObject *co,
+ enum telephony_network_access_technology act)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(co, CORE_OBJECT_TYPE_NETWORK, TCORE_RETURN_EINVAL);
+
+ po = tcore_object_ref_object(co);
+ if (!po)
+ return TCORE_RETURN_EINVAL;
+
+ po->act = act;
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+TReturn tcore_network_get_access_technology(CoreObject *co,
+ enum telephony_network_access_technology *result)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(co, CORE_OBJECT_TYPE_NETWORK, TCORE_RETURN_EINVAL);
+
+ if (!result)
+ return TCORE_RETURN_EINVAL;
+
+ po = tcore_object_ref_object(co);
+ if (!po)
+ return TCORE_RETURN_EINVAL;
+
+ *result = po->act;
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+TReturn tcore_network_set_lac(CoreObject *co, unsigned int lac)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(co, CORE_OBJECT_TYPE_NETWORK, TCORE_RETURN_EINVAL);
+
+ po = tcore_object_ref_object(co);
+ if (!po)
+ return TCORE_RETURN_EINVAL;
+
+ po->lac = lac;
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+TReturn tcore_network_get_lac(CoreObject *co, unsigned int *result)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(co, CORE_OBJECT_TYPE_NETWORK, TCORE_RETURN_EINVAL);
+
+ if (!result)
+ return TCORE_RETURN_EINVAL;
+
+ po = tcore_object_ref_object(co);
+ if (!po)
+ return TCORE_RETURN_EINVAL;
+
+ *result = po->lac;
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+TReturn tcore_network_set_rac(CoreObject *co, unsigned int rac)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(co, CORE_OBJECT_TYPE_NETWORK, TCORE_RETURN_EINVAL);
+
+ po = tcore_object_ref_object(co);
+ if (!po)
+ return TCORE_RETURN_EINVAL;
+
+ po->rac = rac;
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+TReturn tcore_network_get_rac(CoreObject *co, unsigned int *result)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(co, CORE_OBJECT_TYPE_NETWORK, TCORE_RETURN_EINVAL);
+
+ if (!result)
+ return TCORE_RETURN_EINVAL;
+
+ po = tcore_object_ref_object(co);
+ if (!po)
+ return TCORE_RETURN_EINVAL;
+
+ *result = po->rac;
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+TReturn tcore_network_set_cell_id(CoreObject *co, unsigned int cell_id)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(co, CORE_OBJECT_TYPE_NETWORK, TCORE_RETURN_EINVAL);
+
+ po = tcore_object_ref_object(co);
+ if (!po)
+ return TCORE_RETURN_EINVAL;
+
+ po->cell_id = cell_id;
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+TReturn tcore_network_get_cell_id(CoreObject *co, unsigned int *result)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(co, CORE_OBJECT_TYPE_NETWORK, TCORE_RETURN_EINVAL);
+
+ if (!result)
+ return TCORE_RETURN_EINVAL;
+
+ po = tcore_object_ref_object(co);
+ if (!po)
+ return TCORE_RETURN_EINVAL;
+
+ *result = po->cell_id;
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+gboolean tcore_network_get_gsm_dtm_support(CoreObject *co)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(co, CORE_OBJECT_TYPE_NETWORK, FALSE);
+
+ po = tcore_object_ref_object(co);
+ if (!po)
+ return FALSE;
+
+ return po->gsm_dtm_support;
+}
+
+TReturn tcore_network_set_gsm_dtm_support(CoreObject *co, gboolean state)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(co, CORE_OBJECT_TYPE_NETWORK, TCORE_RETURN_EINVAL);
+
+ po = tcore_object_ref_object(co);
+ if (!po)
+ return TCORE_RETURN_EINVAL;
+
+ po->gsm_dtm_support = state;
+ dbg("gsm_dtm_support = %d", state);
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+TReturn tcore_network_set_service_type(CoreObject *co,
+ enum telephony_network_service_type service_type)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(co, CORE_OBJECT_TYPE_NETWORK, TCORE_RETURN_EINVAL);
+
+ po = tcore_object_ref_object(co);
+ if (!po)
+ return TCORE_RETURN_EINVAL;
+
+ po->service_type = service_type;
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+TReturn tcore_network_get_service_type(CoreObject *co,
+ enum telephony_network_service_type *result)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(co, CORE_OBJECT_TYPE_NETWORK, TCORE_RETURN_EINVAL);
+
+ if (!result)
+ return TCORE_RETURN_EINVAL;
+
+ po = tcore_object_ref_object(co);
+ if (!po)
+ return TCORE_RETURN_EINVAL;
+
+ *result = po->service_type;
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+TReturn tcore_network_set_ims_reg_info(CoreObject *co,
+ struct tel_network_ims_registration_info ims_reg_info)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(co, CORE_OBJECT_TYPE_NETWORK, TCORE_RETURN_EINVAL);
+
+ po = tcore_object_ref_object(co);
+ if (!po)
+ return TCORE_RETURN_EINVAL;
+
+ po->ims_reg_info.is_registered = ims_reg_info.is_registered;
+ po->ims_reg_info.feature_mask = ims_reg_info.feature_mask;
+ po->ims_reg_info.network_type = ims_reg_info.network_type;
+ po->ims_reg_info.ecmp_mode = ims_reg_info.ecmp_mode;
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+TReturn tcore_network_get_ims_reg_info(CoreObject *co,
+ struct tel_network_ims_registration_info *ims_reg_info)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(co, CORE_OBJECT_TYPE_NETWORK, TCORE_RETURN_EINVAL);
+
+ if (!ims_reg_info)
+ return TCORE_RETURN_EINVAL;
+
+ po = tcore_object_ref_object(co);
+ if (!po)
+ return TCORE_RETURN_EINVAL;
+
+ ims_reg_info->is_registered = po->ims_reg_info.is_registered;
+ ims_reg_info->feature_mask = po->ims_reg_info.feature_mask;
+ ims_reg_info->network_type = po->ims_reg_info.network_type;
+ ims_reg_info->ecmp_mode = po->ims_reg_info.ecmp_mode;
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+TReturn tcore_network_set_ims_voice_status(CoreObject *co, gboolean status)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(co, CORE_OBJECT_TYPE_NETWORK, TCORE_RETURN_EINVAL);
+
+ po = tcore_object_ref_object(co);
+ if (!po)
+ return TCORE_RETURN_EINVAL;
+
+ po->ims_voice_status = status;
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+TReturn tcore_network_get_ims_voice_status(CoreObject *co, gboolean *status)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(co, CORE_OBJECT_TYPE_NETWORK, TCORE_RETURN_EINVAL);
+
+ if (!status)
+ return TCORE_RETURN_EINVAL;
+
+ po = tcore_object_ref_object(co);
+ if (!po)
+ return TCORE_RETURN_EINVAL;
+
+ *status = po->ims_voice_status;
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+TReturn tcore_network_set_ecc_rat_search_status(CoreObject *co,
+ enum telephony_network_ecc_rat_search_status status)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(co, CORE_OBJECT_TYPE_NETWORK, TCORE_RETURN_EINVAL);
+
+ po = tcore_object_ref_object(co);
+ if (!po)
+ return TCORE_RETURN_EINVAL;
+
+ po->rat_search_status = status;
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+TReturn tcore_network_get_ecc_rat_search_status(CoreObject *co,
+ enum telephony_network_ecc_rat_search_status *status)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(co, CORE_OBJECT_TYPE_NETWORK, TCORE_RETURN_EINVAL);
+
+ if (!status)
+ return TCORE_RETURN_EINVAL;
+
+ po = tcore_object_ref_object(co);
+ if (!po)
+ return TCORE_RETURN_EINVAL;
+
+ *status = po->rat_search_status;
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+TReturn tcore_network_set_ecc_rat(CoreObject *co,
+ enum telephony_network_access_technology ecc_rat)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(co, CORE_OBJECT_TYPE_NETWORK, TCORE_RETURN_EINVAL);
+
+ po = tcore_object_ref_object(co);
+ if (!po)
+ return TCORE_RETURN_EINVAL;
+
+ po->ecc_rat = ecc_rat;
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+TReturn tcore_network_get_ecc_rat(CoreObject *co,
+ enum telephony_network_access_technology *ecc_rat)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(co, CORE_OBJECT_TYPE_NETWORK, TCORE_RETURN_EINVAL);
+
+ if (!ecc_rat)
+ return TCORE_RETURN_EINVAL;
+
+ po = tcore_object_ref_object(co);
+ if (!po)
+ return TCORE_RETURN_EINVAL;
+
+ *ecc_rat = po->ecc_rat;
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+TReturn tcore_network_operator_info_add(CoreObject *co,
+ const struct tcore_network_operator_info *noi)
+{
+ struct private_object_data *po = NULL;
+ char plmn[7];
+ int mcc_index, mnc_index;
+
+ CORE_OBJECT_CHECK_RETURN(co, CORE_OBJECT_TYPE_NETWORK, TCORE_RETURN_EINVAL);
+
+ if (!noi)
+ return TCORE_RETURN_EINVAL;
+
+ mcc_index = atoi(noi->mcc);
+ mnc_index = atoi(noi->mnc);
+
+ if (mcc_index > 999 || mnc_index > 999) {
+ err("mcc_index %d mnc_index %d", mcc_index, mnc_index);
+ return TCORE_RETURN_EINVAL;
+ }
+
+ po = tcore_object_ref_object(co);
+ if (!po)
+ return TCORE_RETURN_EINVAL;
+
+ g_strlcpy(plmn, noi->mcc, NETWORK_MAX_MCC_LEN + 1);
+ g_strlcpy(plmn + NETWORK_MAX_MCC_LEN, noi->mnc, NETWORK_MAX_MNC_LEN + 1);
+
+ if (g_hash_table_lookup(po->operator_info_hash, plmn))
+ g_hash_table_remove(po->operator_info_hash, plmn);
+
+ g_hash_table_insert(po->operator_info_hash,
+ g_strdup(plmn),
+ g_memdup(noi, sizeof(struct tcore_network_operator_info)));
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+struct tcore_network_operator_info *
+tcore_network_operator_info_find(CoreObject *co, const char *mcc, const char *mnc)
+{
+ struct private_object_data *po = NULL;
+ struct tcore_network_operator_info *data;
+ char plmn[NETWORK_MAX_PLMN_LEN+1];
+ int mcc_index, mnc_index;
+
+ CORE_OBJECT_CHECK_RETURN(co, CORE_OBJECT_TYPE_NETWORK, NULL);
+
+ if (!mcc || !mnc)
+ return NULL;
+
+ mcc_index = atoi(mcc);
+ mnc_index = atoi(mnc);
+
+ if (mcc_index > 999 || mnc_index > 999) {
+ err("mcc_index %d mnc_index %d", mcc_index, mnc_index);
+ return NULL;
+ }
+
+ po = tcore_object_ref_object(co);
+ if (!po)
+ return NULL;
+
+ g_strlcpy(plmn, mcc, NETWORK_MAX_MCC_LEN + 1);
+ g_strlcpy(plmn + NETWORK_MAX_MCC_LEN, mnc, NETWORK_MAX_MNC_LEN + 1);
+
+ data = g_hash_table_lookup(po->operator_info_hash, plmn);
+
+ if (data) {
+ dbg("found mcc[%s], mnc[%s] name[%s] type[%d] in operator info table (%p)",
+ data->mcc, data->mnc, data->name, data->type, po->operator_info_hash);
+ } else {
+ dbg("mcc[%s] mnc[%s] not present in operator table (%p)",
+ mcc, mnc, po->operator_info_hash);
+ }
+
+ return data;
+}
+
+void tcore_network_update_mcc_mnc_oper_list(CoreObject *co,
+ const char *plmn, const char *name, enum tcore_network_operator_info_type type)
+{
+ char mcc[NETWORK_MAX_MCC_LEN+1] = { 0, };
+ const char *mnc;
+ struct tcore_network_operator_info *noi = NULL;
+
+ CORE_OBJECT_CHECK(co, CORE_OBJECT_TYPE_NETWORK);
+
+ if (!plmn) {
+ err("plmn is NULL");
+ return;
+ }
+
+ if (strlen(plmn) < NETWORK_MAX_MCC_LEN+1) {
+ err("strlen of plmn is %d", strlen(plmn));
+ return;
+ }
+
+ memcpy(mcc, plmn, NETWORK_MAX_MCC_LEN);
+ mnc = plmn + NETWORK_MAX_MCC_LEN;
+
+ if (atoi(mcc) == 0) {
+ err("atoi(mcc) is Zero. mcc[%s]", mcc);
+ return;
+ }
+
+ noi = g_try_malloc0(sizeof(struct tcore_network_operator_info));
+ if (noi == NULL) {
+ err("Memory alloc failed");
+ return;
+ }
+
+ g_snprintf(noi->mcc, NETWORK_MAX_MCC_LEN+1, "%s", mcc);
+ g_snprintf(noi->mnc, NETWORK_MAX_MNC_LEN+1, "%s", mnc);
+ g_snprintf(noi->name, NETWORK_MAX_NETWORK_NAME_LEN+1, "%s", name);
+ noi->type = type;
+
+ info("[NETINFO] Update mcc[%s] mnc[%s] name[%s] type[%d] oper_list", noi->mcc, noi->mnc, noi->name, noi->type);
+ tcore_network_operator_info_add(co, noi);
+
+ g_free(noi);
+}
+
+/* Loads operator info from database */
+gboolean tcore_network_load_mcc_mnc_oper_list_from_db(TcorePlugin *p,
+ CoreObject *co, const char *mcc, const char *mnc, const char *db_path)
+{
+ Server *s;
+ Storage *strg;
+ void *handle;
+ char query[256] = {0, };
+ char mcc_str[NETWORK_MAX_MCC_LEN+1] = { 0, };
+ GHashTableIter iter;
+ gpointer key, value;
+ GHashTable *result = NULL, *row = NULL;
+ struct tcore_network_operator_info *noi = NULL;
+ int count = 0;
+
+ s = tcore_plugin_ref_server(p);
+ strg = tcore_server_find_storage(s, "database");
+
+ handle = tcore_storage_create_handle(strg, db_path);
+ if (!handle) {
+ err("fail to create database handle");
+ return FALSE;
+ }
+
+ g_snprintf(query, 255,
+ "select country, mcc, mnc, oper from mcc_mnc_oper_list where mcc='%s' and mnc='%s'",
+ mcc, mnc);
+ dbg("query = [%s]", query);
+
+ result = g_hash_table_new_full(g_str_hash, g_str_equal, NULL,
+ (GDestroyNotify) g_hash_table_destroy);
+ if (!result) {
+ err("fail to create new hash table");
+ tcore_storage_remove_handle(strg, handle);
+ return FALSE;
+ }
+
+ if (tcore_storage_read_query_database(strg, handle, query, NULL, result, 4) == FALSE) {
+ tcore_storage_remove_handle(strg, handle);
+ g_hash_table_destroy(result);
+ return FALSE;
+ }
+
+ g_hash_table_iter_init(&iter, result);
+ noi = g_try_malloc0(sizeof(struct tcore_network_operator_info));
+ if (noi == NULL) {
+ err("Memory alloc failed");
+ tcore_storage_remove_handle(strg, handle);
+ g_hash_table_destroy(result);
+ return FALSE;
+ }
+
+ while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
+ row = value;
+
+ memset(noi, 0x0, sizeof(struct tcore_network_operator_info));
+ memset(mcc_str, 0, sizeof(mcc_str));
+
+ g_snprintf(mcc_str, NETWORK_MAX_MCC_LEN+1, "%s", (char *)g_hash_table_lookup(row, "1"));
+ if (strlen(mcc_str) == 1)
+ g_snprintf(noi->mcc, NETWORK_MAX_MCC_LEN+1, "00%s", mcc_str);
+ else if (strlen(mcc_str) == 2)
+ g_snprintf(noi->mcc, NETWORK_MAX_MCC_LEN+1, "0%s", mcc_str);
+ else
+ g_snprintf(noi->mcc, NETWORK_MAX_MCC_LEN+1, "%s", mcc_str);
+ g_snprintf(noi->mnc, NETWORK_MAX_MNC_LEN+1, "%s", (char *)g_hash_table_lookup(row, "2"));
+ g_snprintf(noi->name, NETWORK_MAX_NETWORK_NAME_LEN+1, "%s", (char *)g_hash_table_lookup(row, "3"));
+ g_snprintf(noi->country, NETWORK_MAX_COUNTRY_CODE_LEN+1, "%s", (char *)g_hash_table_lookup(row, "0"));
+ if (g_strcmp0(NETWORK_MCC_MNC_OPER_LIST_GSMA_DB, db_path) == 0)
+ noi->type = TCORE_NETWORK_OPERATOR_INFO_TYPE_TS25_DB;
+ else
+ noi->type = TCORE_NETWORK_OPERATOR_INFO_TYPE_DELTA_DB;
+ info("[NETINFO] load name from DB : mcc[%s] mnc[%s] name[%s] type:[%d]", noi->mcc, noi->mnc, noi->name, noi->type);
+ tcore_network_operator_info_add(co, noi);
+ count++;
+ }
+ g_free(noi);
+
+ g_hash_table_destroy(result);
+
+ tcore_storage_remove_handle(strg, handle);
+
+ if (count == 0)
+ return FALSE;
+
+ return TRUE;
+}
+
+/* Updates Operator info in the database */
+void tcore_network_update_mcc_mnc_oper_list_db(TcorePlugin *p, const char *mcc, const char *mnc, const char *oper_name)
+{
+ Server *s;
+ Storage *strg;
+ void *handle;
+ char query[256] = {0, };
+ struct tcore_network_operator_info *noi = NULL;
+ GHashTable *result, *row = NULL;
+ GHashTableIter iter;
+ gpointer key, value;
+ gboolean field_exist = FALSE;
+
+ if (G_UNLIKELY(!mcc || !mnc || !oper_name || !p)) {
+ err("Input Parameter Addresses : mcc[%p] mnc[%p] oper_name[%p] plugin[%p]", mcc, mnc, oper_name, p);
+ return;
+ }
+
+ if (G_UNLIKELY(strlen(oper_name) == 0)) {
+ err("strlen of oper_name is Zero");
+ return;
+ }
+
+ dbg("mcc[%s] mnc[%s] oper_name[%s]", mcc, mnc, oper_name);
+
+ /* 1. Get DB handle */
+ s = tcore_plugin_ref_server(p);
+ strg = tcore_server_find_storage(s, "database");
+
+ handle = tcore_storage_create_handle(strg, NETWORK_MCC_MNC_OPER_LIST_GSMA_DB);
+ if (!handle) {
+ err("fail to create database handle");
+ return;
+ }
+
+ /* 2. Check duplicated network operator name in DB */
+ g_snprintf(query, 255,
+ "select country, mcc, mnc, oper from mcc_mnc_oper_list where mcc='%s' and mnc='%s'",
+ mcc, mnc);
+ dbg("query = [%s]", query);
+
+ result = g_hash_table_new_full(g_str_hash, g_str_equal, NULL,
+ (GDestroyNotify) g_hash_table_destroy);
+ if (!result) {
+ err("fail to create new hash table");
+ tcore_storage_remove_handle(strg, handle);
+ return;
+ }
+
+ tcore_storage_read_query_database(strg, handle, query, NULL, result, 4);
+
+ g_hash_table_iter_init(&iter, result);
+ noi = g_try_malloc0(sizeof(struct tcore_network_operator_info));
+ if (noi == NULL) {
+ err("Memory alloc failed");
+ tcore_storage_remove_handle(strg, handle);
+ g_hash_table_destroy(result);
+ return;
+ }
+ while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
+ row = value;
+
+ memset(noi, 0x0, sizeof(struct tcore_network_operator_info));
+
+ g_snprintf(noi->mcc, NETWORK_MAX_MCC_LEN+1, "%s", (char *)g_hash_table_lookup(row, "1"));
+ g_snprintf(noi->mnc, NETWORK_MAX_MNC_LEN+1, "%s", (char *)g_hash_table_lookup(row, "2"));
+ g_snprintf(noi->name, NETWORK_MAX_NETWORK_NAME_LEN+1, "%s", (char *)g_hash_table_lookup(row, "3"));
+ g_snprintf(noi->country, NETWORK_MAX_COUNTRY_CODE_LEN+1, "%s", (char *)g_hash_table_lookup(row, "0"));
+
+ info("This field (mcc[%s] mnc[%s] name[%s]) will be updated ", noi->mcc, noi->mnc, noi->name);
+ field_exist = TRUE;
+ }
+ g_free(noi);
+ g_hash_table_destroy(result);
+
+ /* 3. Update Network Operator name DB */
+ result = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, g_free);
+ if (!result) {
+ err("fail to create new hash table");
+ tcore_storage_remove_handle(strg, handle);
+ return;
+ }
+
+ if (field_exist) {
+ /* Update DB */
+ snprintf(query, 255, "update mcc_mnc_oper_list set oper = ? where mcc = ? and mnc = ?");
+ dbg("query[%s]", query);
+
+ g_hash_table_insert(result, (gpointer)"1", g_strdup(oper_name));
+ g_hash_table_insert(result, (gpointer)"2", g_strdup(mcc));
+ g_hash_table_insert(result, (gpointer)"3", g_strdup(mnc));
+
+ if (tcore_storage_update_query_database(strg, handle, query, result) == FALSE)
+ err("update query failed");
+ } else {
+ /* Insert DB */
+ snprintf(query, 255, "insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values (?, ?, ?, ?)");
+ dbg("query[%s]", query);
+
+ g_hash_table_insert(result, (gpointer)"1", g_strdup("__"));
+ g_hash_table_insert(result, (gpointer)"2", g_strdup(mcc));
+ g_hash_table_insert(result, (gpointer)"3", g_strdup(mnc));
+ g_hash_table_insert(result, (gpointer)"4", g_strdup(oper_name));
+
+ if (tcore_storage_insert_query_database(strg, handle, query, result) == FALSE)
+ err("insert query failed");
+ }
+
+ g_hash_table_destroy(result);
+ tcore_storage_remove_handle(strg, handle);
+}
--- /dev/null
+/*
+ * libtcore
+ *
+ * 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.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <glib.h>
+
+#include "tcore.h"
+#include "internal/tcore_types.h"
+#include "plugin.h"
+#include "queue.h"
+#include "user_request.h"
+#include "core_object.h"
+#include "co_phonebook.h"
+
+struct private_object_data {
+ struct tcore_phonebook_operations *ops[TCORE_OPS_TYPE_MAX];
+
+ gboolean b_init;
+ struct tel_phonebook_support_list support_list;
+ struct tel_phonebook_field_support_list field_support_list;
+ enum tel_phonebook_type selected;
+};
+
+static TReturn _dispatcher(CoreObject *o, UserRequest *ur, enum tcore_ops_type ops_type)
+{
+ enum tcore_request_command command;
+ struct private_object_data *po = tcore_object_ref_object(o);
+ struct tcore_phonebook_operations *ops = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PHONEBOOK, TCORE_RETURN_EINVAL);
+ CORE_OBJECT_VALIDATE_OPS_RETURN_VAL(ops_type, TCORE_RETURN_EINVAL);
+
+ tcore_check_null_ret_err("po", po, TCORE_RETURN_EINVAL);
+ tcore_check_null_ret_err("ur", ur, TCORE_RETURN_EINVAL);
+
+ ops = po->ops[ops_type];
+ tcore_check_null_ret_err("ops", ops, TCORE_RETURN_FAILURE);
+
+ command = tcore_user_request_get_command(ur);
+ switch (command) {
+ case TREQ_PHONEBOOK_GETCOUNT:
+ tcore_check_null_ret_err("ops->get_count",
+ ops->get_count, TCORE_RETURN_ENOSYS);
+
+ return ops->get_count(o, ur);
+
+ case TREQ_PHONEBOOK_GETMETAINFO:
+ tcore_check_null_ret_err("ops->get_info",
+ ops->get_info, TCORE_RETURN_ENOSYS);
+
+ return ops->get_info(o, ur);
+
+ case TREQ_PHONEBOOK_GETUSIMINFO:
+ tcore_check_null_ret_err("ops->get_usim_info",
+ ops->get_usim_info, TCORE_RETURN_ENOSYS);
+
+ return ops->get_usim_info(o, ur);
+
+ case TREQ_PHONEBOOK_READRECORD:
+ tcore_check_null_ret_err("ops->read_record",
+ ops->read_record, TCORE_RETURN_ENOSYS);
+
+ return ops->read_record(o, ur);
+
+ case TREQ_PHONEBOOK_UPDATERECORD:
+ tcore_check_null_ret_err("ops->update_record",
+ ops->update_record, TCORE_RETURN_ENOSYS);
+
+ return ops->update_record(o, ur);
+
+ case TREQ_PHONEBOOK_DELETERECORD:
+ tcore_check_null_ret_err("ops->delete_record",
+ ops->delete_record, TCORE_RETURN_ENOSYS);
+
+ return ops->delete_record(o, ur);
+
+ default:
+ break;
+ }
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+static void _free_hook(CoreObject *o)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_PHONEBOOK);
+
+ po = tcore_object_ref_object(o);
+ if (po) {
+ free(po);
+ tcore_object_link_object(o, NULL);
+ }
+}
+
+gboolean tcore_phonebook_get_status(CoreObject *o)
+{
+ struct private_object_data *po = NULL;
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PHONEBOOK, FALSE);
+ po = tcore_object_ref_object(o);
+
+ return po->b_init;
+}
+
+gboolean tcore_phonebook_set_status(CoreObject *o, gboolean b_init)
+{
+ struct private_object_data *po = NULL;
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PHONEBOOK, FALSE);
+ po = tcore_object_ref_object(o);
+
+ po->b_init = b_init;
+
+ return TRUE;
+}
+
+struct tel_phonebook_support_list *tcore_phonebook_get_support_list(CoreObject *o)
+{
+ struct private_object_data *po = NULL;
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PHONEBOOK, NULL);
+ po = tcore_object_ref_object(o);
+
+ if (po == NULL)
+ return NULL;
+
+ return g_memdup(&po->support_list, sizeof(struct tel_phonebook_support_list));
+}
+
+gboolean tcore_phonebook_set_support_list(CoreObject *o, struct tel_phonebook_support_list *list)
+{
+ struct private_object_data *po = NULL;
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PHONEBOOK, FALSE);
+ po = tcore_object_ref_object(o);
+
+ memcpy(&po->support_list, list, sizeof(struct tel_phonebook_support_list));
+
+ return TRUE;
+}
+
+struct tel_phonebook_field_support_list *tcore_phonebook_get_field_support_list(CoreObject *o)
+{
+ struct private_object_data *po = NULL;
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PHONEBOOK, NULL);
+ po = tcore_object_ref_object(o);
+
+ if (po == NULL)
+ return NULL;
+
+ return g_memdup(&po->field_support_list, sizeof(struct tel_phonebook_field_support_list));
+}
+
+gboolean tcore_phonebook_set_field_support_list(CoreObject *o, struct tel_phonebook_field_support_list *list)
+{
+ struct private_object_data *po = NULL;
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PHONEBOOK, FALSE);
+ po = tcore_object_ref_object(o);
+
+ memcpy(&po->field_support_list, list, sizeof(struct tel_phonebook_field_support_list));
+
+ return TRUE;
+}
+
+enum tel_phonebook_type tcore_phonebook_get_selected_type(CoreObject *o)
+{
+ struct private_object_data *po = NULL;
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PHONEBOOK, PB_TYPE_UNKNOWNN);
+ po = tcore_object_ref_object(o);
+
+ return po->selected;
+}
+
+gboolean tcore_phonebook_set_selected_type(CoreObject *o, enum tel_phonebook_type t)
+{
+ struct private_object_data *po = NULL;
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PHONEBOOK, FALSE);
+ po = tcore_object_ref_object(o);
+
+ po->selected = t;
+
+ return TRUE;
+}
+
+CoreObject *tcore_phonebook_new(TcorePlugin *p, const char *name,
+ struct tcore_phonebook_operations *ops, TcoreHal *hal)
+{
+ CoreObject *o = NULL;
+ struct private_object_data *po = NULL;
+
+ if (!p)
+ return NULL;
+
+ o = tcore_object_new(p, name, hal);
+ if (!o)
+ return NULL;
+
+ po = calloc(1, sizeof(struct private_object_data));
+ if (!po) {
+ tcore_object_free(o);
+ return NULL;
+ }
+
+ /* set ops to default type when core object is created. */
+ po->ops[TCORE_OPS_TYPE_CP] = ops;
+
+ po->selected = PB_TYPE_UNKNOWNN;
+
+ tcore_object_set_type(o, CORE_OBJECT_TYPE_PHONEBOOK);
+ tcore_object_link_object(o, po);
+ tcore_object_set_free_hook(o, _free_hook);
+ tcore_object_set_dispatcher(o, _dispatcher);
+
+ return o;
+}
+
+void tcore_phonebook_free(CoreObject *o)
+{
+ CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_PHONEBOOK);
+ tcore_object_free(o);
+}
+
+void tcore_phonebook_set_ops(CoreObject *o, struct tcore_phonebook_operations *ops, enum tcore_ops_type ops_type)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_PHONEBOOK);
+ CORE_OBJECT_VALIDATE_OPS_RETURN(ops_type);
+
+ po = (struct private_object_data *)tcore_object_ref_object(o);
+ if (!po) {
+ err("po is NULL");
+ return;
+ }
+
+ po->ops[ops_type] = ops;
+}
--- /dev/null
+/*
+ * libtcore
+ *
+ * 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.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <glib.h>
+
+#include "tcore.h"
+#include "internal/tcore_types.h"
+#include "plugin.h"
+#include "user_request.h"
+#include "co_ps.h"
+#include "co_network.h"
+
+struct p_callid_type {
+ unsigned int cid;
+ gboolean active;
+ gboolean connected;
+ gchar *apn;
+ GSList *contexts;
+};
+
+struct private_object_data {
+ struct tcore_ps_operations *ops[TCORE_OPS_TYPE_MAX];
+
+ gboolean online;
+ gint num_of_pdn;
+
+ /* 1 ~ UMTS_PS_MAX_CID */
+ struct p_callid_type cid[PS_MAX_CID + 1];
+
+ GSList *context_list;
+};
+
+static TReturn _dispatcher(CoreObject *o, UserRequest *ur, enum tcore_ops_type ops_type)
+{
+ enum tcore_request_command command;
+ struct private_object_data *po = tcore_object_ref_object(o);
+ struct tcore_ps_operations *ops = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_MODEM, TCORE_RETURN_EINVAL);
+ CORE_OBJECT_VALIDATE_OPS_RETURN_VAL(ops_type, TCORE_RETURN_EINVAL);
+
+ tcore_check_null_ret_err("po", po, TCORE_RETURN_EINVAL);
+ tcore_check_null_ret_err("ur", ur, TCORE_RETURN_EINVAL);
+
+ ops = po->ops[ops_type];
+ tcore_check_null_ret_err("ops", ops, TCORE_RETURN_FAILURE);
+
+ command = tcore_user_request_get_command(ur);
+ switch (command) {
+ default:
+ break;
+ }
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+static void _free_hook(CoreObject *o)
+{
+ struct private_object_data *po = NULL;
+ GSList *list;
+
+ po = tcore_object_ref_object(o);
+ if (!po)
+ return;
+
+ if (po->context_list) {
+ for (list = po->context_list; list; list = list->next) {
+ if (list->data)
+ free(list->data);
+
+ list->data = NULL;
+ }
+
+ g_slist_free(po->context_list);
+ po->context_list = NULL;
+ }
+
+ g_free(po);
+ tcore_object_link_object(o, NULL);
+}
+
+static gboolean _ps_is_active_context(CoreObject *o, CoreObject *ps_context)
+{
+ GSList *contexts = NULL;
+ CoreObject *s_context = NULL;
+
+ int idx_cid = 0;
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, FALSE);
+
+ po = tcore_object_ref_object(o);
+
+ for (idx_cid = 1; idx_cid <= po->num_of_pdn; idx_cid++) {
+ if (po->cid[idx_cid].cid == 0)
+ continue;
+
+ contexts = po->cid[idx_cid].contexts;
+ if (!contexts)
+ continue;
+
+ while (contexts) {
+ s_context = contexts->data;
+ if (!s_context) {
+ contexts = contexts->next;
+ continue;
+ }
+
+ if (ps_context == s_context) {
+ dbg("find contexts(%p) in cid(%d)", ps_context, idx_cid);
+ return TRUE;
+ }
+
+ contexts = contexts->next;
+ }
+ }
+
+ dbg("cannot find contexts(%p) ", ps_context);
+
+ return FALSE;
+}
+
+static gboolean _ps_is_duplicated_apn(CoreObject *o, CoreObject *ps_context)
+{
+ GSList *contexts = NULL;
+ CoreObject *s_context = NULL;
+ gchar *t_apn = NULL, *s_apn = NULL;
+
+ int idx_cid = 0;
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, FALSE);
+
+ po = tcore_object_ref_object(o);
+ t_apn = tcore_context_get_apn(ps_context);
+
+ for (idx_cid = 1; idx_cid <= po->num_of_pdn; idx_cid++) {
+ if (po->cid[idx_cid].cid == 0)
+ continue;
+
+ contexts = po->cid[idx_cid].contexts;
+ if (!contexts)
+ continue;
+
+ while (contexts) {
+ s_context = contexts->data;
+ if (!s_context) {
+ contexts = contexts->next;
+ continue;
+ }
+
+ if (ps_context == s_context) {
+ contexts = contexts->next;
+ continue;
+ }
+
+ s_apn = tcore_context_get_apn(s_context);
+ if (g_strcmp0(t_apn, s_apn) == 0) {
+ dbg("target and source context have same APN");
+ tcore_context_cp_service_info(ps_context, s_context);
+ g_free(t_apn);
+ g_free(s_apn);
+
+ return TRUE;
+ }
+ g_free(s_apn);
+
+ contexts = contexts->next;
+ }
+ }
+
+ g_free(t_apn);
+ return FALSE;
+}
+
+static void _deactivate_context(gpointer context, gpointer user_data)
+{
+ if (!context || !user_data)
+ return;
+
+ tcore_ps_deactivate_context(user_data, context, NULL);
+}
+
+CoreObject *tcore_ps_new(TcorePlugin *p, const char *name,
+ struct tcore_ps_operations *ops, TcoreHal *hal)
+{
+ CoreObject *o = NULL;
+ struct private_object_data *po = NULL;
+
+ if (!p)
+ return NULL;
+
+ o = tcore_object_new(p, name, hal);
+ if (!o)
+ return NULL;
+
+ po = g_try_malloc0(sizeof(struct private_object_data));
+ if (!po) {
+ tcore_object_free(o);
+ return NULL;
+ }
+
+ /* set ops to default type when core object is created. */
+ po->ops[TCORE_OPS_TYPE_CP] = ops;
+
+ tcore_object_set_type(o, CORE_OBJECT_TYPE_PS);
+ tcore_object_link_object(o, po);
+ tcore_object_set_free_hook(o, _free_hook);
+ tcore_object_set_dispatcher(o, _dispatcher);
+
+ return o;
+}
+
+void tcore_ps_free(CoreObject *o)
+{
+ CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_PS);
+ tcore_object_free(o);
+}
+
+void tcore_ps_set_ops(CoreObject *o,
+ struct tcore_ps_operations *ops, enum tcore_ops_type ops_type)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_PS);
+ CORE_OBJECT_VALIDATE_OPS_RETURN(ops_type);
+
+ po = (struct private_object_data *)tcore_object_ref_object(o);
+ if (!po) {
+ err("po is NULL");
+ return;
+ }
+
+ po->ops[ops_type] = ops;
+}
+
+TReturn tcore_ps_add_context(CoreObject *o, CoreObject *ctx_o)
+{
+ struct private_object_data *po = NULL;
+ unsigned int count;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, TCORE_RETURN_EINVAL);
+ CORE_OBJECT_CHECK_RETURN(ctx_o, CORE_OBJECT_TYPE_PS_CONTEXT, TCORE_RETURN_EINVAL);
+
+ po = tcore_object_ref_object(o);
+ if (!po)
+ return TCORE_RETURN_EINVAL;
+
+ count = g_slist_length(po->context_list);
+ po->context_list = g_slist_insert(po->context_list, ctx_o, 0);
+ dbg("num. of contexts: %d -> %d", count, g_slist_length(po->context_list));
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+TReturn tcore_ps_remove_context(CoreObject *o, CoreObject *ctx_o)
+{
+ struct private_object_data *po = NULL;
+ unsigned int count;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, TCORE_RETURN_EINVAL);
+ CORE_OBJECT_CHECK_RETURN(ctx_o, CORE_OBJECT_TYPE_PS_CONTEXT, TCORE_RETURN_EINVAL);
+
+ po = tcore_object_ref_object(o);
+ if (!po)
+ return TCORE_RETURN_EINVAL;
+
+ tcore_ps_clear_context_id(o, ctx_o);
+ count = g_slist_length(po->context_list);
+ po->context_list = g_slist_remove(po->context_list, ctx_o);
+ dbg("num. of contexts: %d -> %d", count, g_slist_length(po->context_list));
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+TReturn tcore_ps_set_online(CoreObject *o, gboolean state)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, TCORE_RETURN_EINVAL);
+
+ po = tcore_object_ref_object(o);
+ if (!po)
+ return TCORE_RETURN_EINVAL;
+
+ po->online = state;
+ dbg("PS Status: [%s]", (po->online ? "ONLINE" : "OFFLINE"));
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+TReturn tcore_ps_set_num_of_pdn(CoreObject *o, gint numbers)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, TCORE_RETURN_EINVAL);
+
+ po = tcore_object_ref_object(o);
+ if (!po)
+ return TCORE_RETURN_EINVAL;
+
+ if (numbers <= 0 || numbers > PS_MAX_CID)
+ po->num_of_pdn = PS_MAX_CID;
+ else
+ po->num_of_pdn = numbers;
+
+ dbg("ps num of pdn = %d, numbers = %d", po->num_of_pdn, numbers);
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+unsigned int tcore_ps_get_num_of_pdn(CoreObject *o)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, 0);
+
+ po = tcore_object_ref_object(o);
+ if (!po)
+ return 0;
+
+ return po->num_of_pdn;
+}
+
+unsigned int tcore_ps_set_cid_active(CoreObject *o, unsigned int cid, unsigned int enable)
+{
+ int idx_cid = 0;
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, 0);
+ if (cid == 0)
+ return 0;
+
+ po = tcore_object_ref_object(o);
+ for (idx_cid = 1; idx_cid <= po->num_of_pdn; idx_cid++) {
+ if (po->cid[idx_cid].cid == cid) {
+ po->cid[idx_cid].active = enable;
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+unsigned int tcore_ps_get_cid_active(CoreObject *o, unsigned int cid)
+{
+ int idx_cid = 0;
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, 0);
+ if (cid == 0)
+ return 0;
+
+ po = tcore_object_ref_object(o);
+ for (idx_cid = 1; idx_cid <= po->num_of_pdn; idx_cid++)
+ if (po->cid[idx_cid].cid == cid)
+ return po->cid[idx_cid].active;
+
+ return 0;
+}
+
+GSList *tcore_ps_get_active_cids(CoreObject *o)
+{
+ int idx_cid = 0;
+ GSList *active_list = NULL;
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, NULL);
+
+ po = tcore_object_ref_object(o);
+
+ for (idx_cid = 1; idx_cid <= po->num_of_pdn; idx_cid++)
+ if (po->cid[idx_cid].active)
+ active_list = g_slist_append(active_list, &po->cid[idx_cid].cid);
+
+ return active_list;
+}
+
+unsigned int tcore_ps_set_cid_connected(CoreObject *o, unsigned int cid, unsigned int connected)
+{
+ int idx_cid = 0;
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, 0);
+ if (cid == 0)
+ return 0;
+
+ po = tcore_object_ref_object(o);
+ for (idx_cid = 1; idx_cid <= po->num_of_pdn; idx_cid++) {
+ if (po->cid[idx_cid].cid == cid) {
+ po->cid[idx_cid].connected = connected;
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+unsigned int tcore_ps_get_cid_connected(CoreObject *o, unsigned int cid)
+{
+ int idx_cid = 0;
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, 0);
+ if (cid == 0)
+ return 0;
+
+ po = tcore_object_ref_object(o);
+ for (idx_cid = 1; idx_cid <= po->num_of_pdn; idx_cid++)
+ if (po->cid[idx_cid].cid == cid)
+ return po->cid[idx_cid].connected;
+
+ return 0;
+}
+
+GSList *tcore_ps_get_connected_cids(CoreObject *o)
+{
+ int idx_cid = 0;
+ GSList *active_list = NULL;
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, NULL);
+
+ po = tcore_object_ref_object(o);
+
+ for (idx_cid = 1; idx_cid <= po->num_of_pdn; idx_cid++)
+ if (po->cid[idx_cid].connected)
+ active_list = g_slist_append(active_list, &po->cid[idx_cid].cid);
+
+ return active_list;
+}
+
+unsigned int tcore_ps_is_active_apn(CoreObject *o, const char *apn)
+{
+ int idx_cid = 0;
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, 0);
+
+ po = tcore_object_ref_object(o);
+
+ for (idx_cid = 1; idx_cid <= po->num_of_pdn; idx_cid++) {
+ if (po->cid[idx_cid].cid == 0)
+ continue;
+
+ if (g_strcmp0((const char *)po->cid[idx_cid].apn, apn) == 0 && po->cid[idx_cid].active)
+ return 1;
+ }
+
+ return 0;
+}
+
+CoreObject *tcore_ps_ref_context_by_role(CoreObject *o, enum co_context_role role)
+{
+ struct private_object_data *po = NULL;
+ GSList *list;
+ CoreObject *pdp_o;
+ TcorePlugin *p;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, NULL);
+
+ po = tcore_object_ref_object(o);
+ if (!po)
+ return NULL;
+
+ p = tcore_object_ref_plugin(o);
+ if (!p)
+ return NULL;
+
+ if (po->context_list) {
+ for (list = po->context_list; list; list = list->next) {
+ if (!list->data)
+ continue;
+
+ pdp_o = list->data;
+ if (!pdp_o)
+ continue;
+
+ if (tcore_object_get_type(pdp_o) != CORE_OBJECT_TYPE_PS_CONTEXT)
+ continue;
+
+ if (tcore_context_get_role(pdp_o) == role)
+ return pdp_o;
+ }
+ }
+
+ return NULL;
+}
+
+GSList *tcore_ps_ref_context_by_id(CoreObject *o, unsigned int id)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, NULL);
+
+ po = tcore_object_ref_object(o);
+ if (!po)
+ return NULL;
+
+ if (id == 0 || id > (unsigned int)po->num_of_pdn)
+ return NULL;
+
+ if (po->cid[id].cid != id)
+ return NULL;
+
+ return po->cid[id].contexts;
+}
+
+gboolean tcore_ps_any_context_activating_activated(CoreObject *o, int * state)
+{
+ struct private_object_data *po = NULL;
+ CoreObject *pdp_o;
+ gboolean ret = FALSE;
+ GSList *list = NULL;
+ enum co_context_state context_state = CONTEXT_STATE_DEACTIVATED;
+
+ po = tcore_object_ref_object(o);
+ if (!po)
+ return ret;
+
+ if (po->context_list) {
+ for (list = po->context_list; list; list = list->next) {
+ if (!list->data)
+ continue;
+
+ pdp_o = list->data;
+
+ if (tcore_object_get_type(pdp_o) != CORE_OBJECT_TYPE_PS_CONTEXT)
+ continue;
+
+ context_state = tcore_context_get_state(pdp_o);
+
+ if (CONTEXT_STATE_ACTIVATED == context_state) {
+ *state = CONTEXT_STATE_ACTIVATED;
+ return TRUE;
+ } else if (CONTEXT_STATE_ACTIVATING == context_state) {
+ *state = CONTEXT_STATE_ACTIVATING;
+ ret = TRUE;
+ continue;
+ } else if (CONTEXT_STATE_DEACTIVATING == context_state) {
+ *state = CONTEXT_STATE_DEACTIVATING;
+ ret = TRUE;
+ continue;
+ }
+ }
+ }
+
+ return ret;
+}
+
+
+TReturn tcore_ps_assign_context_id(CoreObject *o, CoreObject *context, unsigned char cid)
+{
+ struct private_object_data *po = NULL;
+ unsigned char idx;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, TCORE_RETURN_EINVAL);
+ CORE_OBJECT_CHECK_RETURN(context, CORE_OBJECT_TYPE_PS_CONTEXT, TCORE_RETURN_EINVAL);
+
+ po = tcore_object_ref_object(o);
+ if (!po)
+ return TCORE_RETURN_EINVAL;
+
+ if (cid > (unsigned int)po->num_of_pdn)
+ return TCORE_RETURN_PS_CID_ERROR;
+
+ if (cid == 0) {
+ /* Automatic assign */
+ for (idx = 1; idx <= po->num_of_pdn; idx++) {
+ if (po->cid[idx].cid == 0) {
+ po->cid[idx].cid = idx;
+ po->cid[idx].contexts = g_slist_append(po->cid[idx].contexts, context);
+ po->cid[idx].apn = tcore_context_get_apn(context);
+
+ dbg("assign contexts(%p) in cid(%d), apn(%s)", context, idx, po->cid[idx].apn);
+
+ return tcore_context_set_id(context, idx);
+ } else
+ dbg("cid[%d] is not null", idx);
+ }
+
+ dbg("can't find empty cid");
+ } else {
+ /* Manual assign */
+ if (po->cid[cid].cid == cid) {
+ po->cid[cid].contexts = g_slist_append(po->cid[cid].contexts, context);
+ return tcore_context_set_id(context, cid);
+ } else
+ dbg("cid[%d] is not null", cid);
+ }
+
+ return TCORE_RETURN_PS_CID_ERROR;
+}
+
+TReturn tcore_ps_send_dormant_request(CoreObject *o, void *user_data)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, TCORE_RETURN_EINVAL);
+
+ po = tcore_object_ref_object(o);
+ if (!po)
+ return TCORE_RETURN_EINVAL;
+
+ if (!po->online) {
+ dbg("ps network is not online !");
+ return TCORE_RETURN_PS_NETWORK_NOT_READY;
+ }
+
+ /* By 'default' considering Modem/CP opearations */
+ return po->ops[TCORE_OPS_TYPE_CP]->send_dormant_request(o, user_data);
+}
+
+TReturn tcore_ps_clear_context_id(CoreObject *o, CoreObject *context)
+{
+ struct private_object_data *po = NULL;
+ unsigned char i = 0, cnt = 0;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, TCORE_RETURN_EINVAL);
+ CORE_OBJECT_CHECK_RETURN(context, CORE_OBJECT_TYPE_PS_CONTEXT, TCORE_RETURN_EINVAL);
+
+ po = tcore_object_ref_object(o);
+ if (!po)
+ return TCORE_RETURN_EINVAL;
+
+ i = tcore_context_get_id(context);
+ if (i == 0)
+ return TCORE_RETURN_PS_CID_ERROR;
+
+ if (i > po->num_of_pdn)
+ return TCORE_RETURN_PS_CID_ERROR;
+
+ po->cid[i].contexts = g_slist_remove(po->cid[i].contexts, context);
+ cnt = g_slist_length(po->cid[i].contexts);
+ if (cnt <= 0) {
+ po->cid[i].cid = 0;
+ po->cid[i].active = FALSE;
+ po->cid[i].connected = FALSE;
+ g_free(po->cid[i].apn);
+ po->cid[i].apn = NULL;
+ }
+
+ return tcore_context_set_id(context, 0);
+}
+
+TReturn tcore_ps_define_context(CoreObject *o, CoreObject *ps_context, void *user_data)
+{
+ int rv;
+ struct private_object_data *po = NULL;
+ CoreObject *co_nw = NULL;
+ enum telephony_network_access_technology act = NETWORK_ACT_UNKNOWN;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, TCORE_RETURN_EINVAL);
+
+ po = tcore_object_ref_object(o);
+ if (!po)
+ return TCORE_RETURN_EINVAL;
+
+ if (!ps_context)
+ return TCORE_RETURN_EINVAL;
+
+ rv = _ps_is_active_context(o, ps_context);
+ if (rv)
+ return TCORE_RETURN_SUCCESS;
+
+ co_nw = tcore_plugin_ref_core_object(tcore_object_ref_plugin(o), CORE_OBJECT_TYPE_NETWORK);
+ tcore_network_get_access_technology(co_nw, &act);
+ if (act >= NETWORK_ACT_IS95A && act <= NETWORK_ACT_EHRPD)
+ tcore_context_set_tech_preference(ps_context, CONTEXT_TECH_3GPP2);
+ else {
+ tcore_context_set_tech_preference(ps_context, CONTEXT_TECH_3GPP);
+ dbg("3GPP preference by default");
+ }
+
+ rv = _ps_is_duplicated_apn(o, ps_context);
+ if (rv) {
+ unsigned char cid = 0;
+ cid = tcore_context_get_id(ps_context);
+ po->cid[cid].contexts = g_slist_append(po->cid[cid].contexts, ps_context);
+ return TCORE_RETURN_SUCCESS;
+ }
+
+ if (tcore_context_get_id(ps_context) == 0)
+ if (tcore_ps_assign_context_id(o, ps_context, 0) != TCORE_RETURN_SUCCESS)
+ return TCORE_RETURN_PS_CID_ERROR;
+
+ dbg("contexts(%p), cid = %d", ps_context, tcore_context_get_id(ps_context));
+
+ /* By 'default' considering Modem/CP opearations */
+ return po->ops[TCORE_OPS_TYPE_CP]->define_context(o, ps_context, user_data);
+}
+
+TReturn tcore_ps_activate_context(CoreObject *o, CoreObject *ps_context, void *user_data)
+{
+ int rv;
+ struct private_object_data *po = NULL;
+ enum co_context_state context_state = CONTEXT_STATE_DEACTIVATED;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, TCORE_RETURN_EINVAL);
+
+ po = tcore_object_ref_object(o);
+ if (!po)
+ return TCORE_RETURN_EINVAL;
+
+ if (!po->online) {
+ dbg("ps network is not online !");
+ return TCORE_RETURN_PS_NETWORK_NOT_READY;
+ }
+
+ if (!ps_context)
+ return TCORE_RETURN_EINVAL;
+
+ rv = _ps_is_active_context(o, ps_context);
+ if (!rv) {
+ dbg("it is not defined context");
+ return TCORE_RETURN_EINVAL;
+ }
+
+ rv = _ps_is_duplicated_apn(o, ps_context);
+ if (rv) {
+ dbg("context activation is already requested for the same apn(%s)",
+ tcore_context_get_apn(ps_context));
+ return TCORE_RETURN_SUCCESS;
+ }
+
+ context_state = tcore_context_get_state(ps_context);
+
+ if (context_state == CONTEXT_STATE_ACTIVATED) {
+ dbg("Context state : CONTEXT_STATE_ACTIVATED");
+ return TCORE_RETURN_SUCCESS;
+ } else if (context_state == CONTEXT_STATE_ACTIVATING) {
+ dbg("Context state : CONTEXT_STATE_ACTIVATING");
+ return TCORE_RETURN_SUCCESS;
+ } else if (context_state == CONTEXT_STATE_DEACTIVATING) {
+ dbg("Context state : CONTEXT_STATE_DEACTIVATING");
+ return TCORE_RETURN_PS_DEACTIVATING;
+ }
+
+ dbg("cid = %d", tcore_context_get_id(ps_context));
+
+ tcore_context_set_state(ps_context, CONTEXT_STATE_ACTIVATING);
+
+ /* By 'default' considering Modem/CP opearations */
+ rv = po->ops[TCORE_OPS_TYPE_CP]->activate_context(o, ps_context, user_data);
+ if (rv != TCORE_RETURN_SUCCESS)
+ tcore_context_set_state(ps_context, CONTEXT_STATE_DEACTIVATED);
+
+ return rv;
+}
+
+TReturn tcore_ps_deactivate_context(CoreObject *o, CoreObject *ps_context, void *user_data)
+{
+ int rv;
+ struct private_object_data *po = NULL;
+ enum co_context_state context_state = CONTEXT_STATE_DEACTIVATED;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, TCORE_RETURN_EINVAL);
+
+ po = tcore_object_ref_object(o);
+ if (!po)
+ return TCORE_RETURN_EINVAL;
+
+ if (!po->online) {
+ dbg("ps network is not online !");
+ return TCORE_RETURN_PS_NETWORK_NOT_READY;
+ }
+
+ if (!ps_context)
+ return TCORE_RETURN_EINVAL;
+
+ rv = _ps_is_active_context(o, ps_context);
+ if (!rv)
+ return TCORE_RETURN_EINVAL;
+
+ rv = _ps_is_duplicated_apn(o, ps_context);
+ if (rv) {
+ unsigned char cid = 0;
+ cid = tcore_context_get_id(ps_context);
+ po->cid[cid].contexts = g_slist_remove(po->cid[cid].contexts, ps_context);
+ tcore_context_set_state(ps_context, CONTEXT_STATE_DEACTIVATED);
+ return TCORE_RETURN_SUCCESS;
+ }
+
+ context_state = tcore_context_get_state(ps_context);
+ if (context_state == CONTEXT_STATE_DEACTIVATED) {
+ warn("Context State : CONTEXT_STATE_DEACTIVATED");
+ tcore_ps_clear_context_id(o, ps_context);
+ return TCORE_RETURN_SUCCESS;
+ } else if (context_state == CONTEXT_STATE_DEACTIVATING) {
+ dbg("Context State : CONTEXT_STATE_DEACTIVATING");
+ return TCORE_RETURN_SUCCESS;
+ } else if (context_state == CONTEXT_STATE_ACTIVATING) {
+ dbg("Context State :CONTEXT_STATE_ACTIVATING");
+ return TCORE_RETURN_PS_ACTIVATING;
+ }
+
+ tcore_context_set_state(ps_context, CONTEXT_STATE_DEACTIVATING);
+
+ /* By 'default' considering Modem/CP opearations */
+ rv = po->ops[TCORE_OPS_TYPE_CP]->deactivate_context(o, ps_context, user_data);
+ if (rv != TCORE_RETURN_SUCCESS)
+ tcore_context_set_state(ps_context, CONTEXT_STATE_ACTIVATED);
+
+ return rv;
+}
+
+TReturn tcore_ps_deactivate_contexts(CoreObject *o)
+{
+ int temp_index = 0;
+ struct private_object_data *po = NULL;
+ GSList *contexts = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, TCORE_RETURN_EINVAL);
+
+ po = tcore_object_ref_object(o);
+ if (!po)
+ return TCORE_RETURN_EINVAL;
+
+ if (!po->online) {
+ dbg("ps network is not online !");
+ return TCORE_RETURN_PS_NETWORK_NOT_READY;
+ }
+
+ for (temp_index = 1; temp_index <= po->num_of_pdn; temp_index++) {
+ if (po->cid[temp_index].cid != 0) {
+ contexts = po->cid[temp_index].contexts;
+ if (!contexts)
+ continue;
+
+ g_slist_foreach(contexts, _deactivate_context, o);
+ }
+ }
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+TReturn tcore_ps_deactivate_cid(CoreObject *o, unsigned int cid)
+{
+ int temp_index = 0;
+ struct private_object_data *po = NULL;
+ GSList *contexts = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, TCORE_RETURN_EINVAL);
+
+ po = tcore_object_ref_object(o);
+ if (!po)
+ return TCORE_RETURN_EINVAL;
+
+ if (!po->online) {
+ dbg("ps network is not online !");
+ return TCORE_RETURN_PS_NETWORK_NOT_READY;
+ }
+
+ for (temp_index = 1; temp_index <= po->num_of_pdn; temp_index++) {
+ if (po->cid[temp_index].cid != 0 && po->cid[temp_index].cid == cid) {
+ contexts = po->cid[temp_index].contexts;
+ if (!contexts)
+ continue;
+
+ g_slist_foreach(contexts, _deactivate_context, o);
+ }
+ }
+
+ return TCORE_RETURN_SUCCESS;
+}
--- /dev/null
+/*
+ * libtcore
+ *
+ * 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.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <glib.h>
+
+#include "tcore.h"
+#include "internal/tcore_types.h"
+#include "plugin.h"
+#include "queue.h"
+#include "user_request.h"
+#include "co_sap.h"
+
+struct private_object_data {
+ struct tcore_sap_operations *ops[TCORE_OPS_TYPE_MAX];
+};
+
+static TReturn _dispatcher(CoreObject *o, UserRequest *ur, enum tcore_ops_type ops_type)
+{
+ enum tcore_request_command command;
+ struct private_object_data *po = tcore_object_ref_object(o);
+ struct tcore_sap_operations *ops = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_SAP, TCORE_RETURN_EINVAL);
+ CORE_OBJECT_VALIDATE_OPS_RETURN_VAL(ops_type, TCORE_RETURN_EINVAL);
+
+ tcore_check_null_ret_err("po", po, TCORE_RETURN_EINVAL);
+ tcore_check_null_ret_err("ur", ur, TCORE_RETURN_EINVAL);
+
+ ops = po->ops[ops_type];
+ tcore_check_null_ret_err("ops", ops, TCORE_RETURN_FAILURE);
+
+ command = tcore_user_request_get_command(ur);
+ switch (command) {
+ case TREQ_SAP_REQ_CONNECT:
+ tcore_check_null_ret_err("ops->connect",
+ ops->connect, TCORE_RETURN_ENOSYS);
+
+ return ops->connect(o, ur);
+
+ case TREQ_SAP_REQ_DISCONNECT:
+ tcore_check_null_ret_err("ops->disconnect",
+ ops->disconnect, TCORE_RETURN_ENOSYS);
+
+ return ops->disconnect(o, ur);
+
+ case TREQ_SAP_REQ_STATUS:
+ tcore_check_null_ret_err("ops->req_status",
+ ops->req_status, TCORE_RETURN_ENOSYS);
+
+ return ops->req_status(o, ur);
+
+ case TREQ_SAP_REQ_ATR:
+ tcore_check_null_ret_err("ops->get_atr",
+ ops->get_atr, TCORE_RETURN_ENOSYS);
+
+ return ops->get_atr(o, ur);
+
+ case TREQ_SAP_TRANSFER_APDU:
+ tcore_check_null_ret_err("ops->transfer_apdu",
+ ops->transfer_apdu, TCORE_RETURN_ENOSYS);
+
+ return ops->transfer_apdu(o, ur);
+
+ case TREQ_SAP_SET_PROTOCOL:
+ tcore_check_null_ret_err("ops->set_transport_protocol",
+ ops->set_transport_protocol, TCORE_RETURN_ENOSYS);
+
+ return ops->set_transport_protocol(o, ur);
+
+ case TREQ_SAP_SET_POWER:
+ tcore_check_null_ret_err("ops->set_power",
+ ops->set_power, TCORE_RETURN_ENOSYS);
+
+ return ops->set_power(o, ur);
+
+ case TREQ_SAP_REQ_CARDREADERSTATUS:
+ tcore_check_null_ret_err("ops->get_cardreader_status",
+ ops->get_cardreader_status, TCORE_RETURN_ENOSYS);
+
+ return ops->get_cardreader_status(o, ur);
+
+ default:
+ break;
+ }
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+static void _free_hook(CoreObject *o)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_SAP);
+
+ po = tcore_object_ref_object(o);
+ if (po) {
+ free(po);
+ tcore_object_link_object(o, NULL);
+ }
+}
+
+CoreObject *tcore_sap_new(TcorePlugin *p, const char *name,
+ struct tcore_sap_operations *ops, TcoreHal *hal)
+{
+ CoreObject *o = NULL;
+ struct private_object_data *po = NULL;
+
+ if (!p)
+ return NULL;
+
+ o = tcore_object_new(p, name, hal);
+ if (!o)
+ return NULL;
+
+ po = calloc(1, sizeof(struct private_object_data));
+ if (!po) {
+ tcore_object_free(o);
+ return NULL;
+ }
+
+ /* set ops to default type when core object is created. */
+ po->ops[TCORE_OPS_TYPE_CP] = ops;
+
+ tcore_object_set_type(o, CORE_OBJECT_TYPE_SAP);
+ tcore_object_link_object(o, po);
+ tcore_object_set_free_hook(o, _free_hook);
+ tcore_object_set_dispatcher(o, _dispatcher);
+
+ return o;
+}
+
+void tcore_sap_free(CoreObject *o)
+{
+ CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_SAP);
+ tcore_object_free(o);
+}
+
+void tcore_sap_set_ops(CoreObject *o, struct tcore_sap_operations *ops, enum tcore_ops_type ops_type)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_SAP);
+ CORE_OBJECT_VALIDATE_OPS_RETURN(ops_type);
+
+ po = (struct private_object_data *)tcore_object_ref_object(o);
+ if (!po) {
+ err("po is NULL");
+ return;
+ }
+
+ po->ops[ops_type] = ops;
+}
--- /dev/null
+/*
+ * libtcore
+ *
+ * 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.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <glib.h>
+
+#include "tcore.h"
+#include "internal/tcore_types.h"
+#include "plugin.h"
+#include "queue.h"
+#include "user_request.h"
+#include "core_object.h"
+#include "util.h"
+#include "co_sat.h"
+
+#define SATK_PROACTIVE_CMD_TAG 0xD0 /* Proactive Command Tag */
+#define SATK_MENU_SELECTION_TAG 0xD3 /* Menu Selection Tag */
+#define SATK_EVENT_DOWNLOAD_TAG 0xD6 /* Event Download Tag */
+
+/*
+ * Tag Values (without Comprehension bit)
+ */
+#define SATK_COMMAND_DETAILS_TAG 0x01 /* COMMAND DETAILS TAG */
+#define SATK_DEVICE_IDENTITY_TAG 0x02 /* DEVICE IDENTITY TAG */
+#define SATK_RESULT_TAG 0x03 /* RESULT TAG */
+#define SATK_DURATION_TAG 0x04 /* DURATION TAG */
+#define SATK_ALPHA_IDENTIFIER_TAG 0x05 /* ALPHA IDENTIFIER TAG */
+#define SATK_ADDRESS_TAG 0x06 /* ADDRESS TAG */
+#define SATK_CAPABILITY_CONFIGURATION_PARAMETERS_TAG 0x07 /* CAPABILITY CONFIGURATION PARAMETERS TAG */
+#define SATK_SUB_ADDRESS_TAG 0x08 /* SUB ADDRESS TAG */
+#define SATK_SS_STRING_TAG 0x09 /* SS STRING TAG */
+#define SATK_USSD_STRING_TAG 0x0A /* USSD STRING TAG */
+#define SATK_SMS_TPDU_TAG 0x0B /* SMS TPDU TAG */
+#define SATK_CELL_BROADCAST_PAGE_TAG 0x0C /* CELL BROADCAST PAGE TAG */
+#define SATK_TEXT_STRING_TAG 0x0D /* TEXT STRING TAG */
+#define SATK_TONE_TAG 0x0E /* TONE TAG */
+#define SATK_ITEM_TAG 0x0F /* ITEM TAG */
+#define SATK_ITEM_IDENTIFIER_TAG 0x10 /* ITEM IDENTIFIER TAG */
+#define SATK_RESPONSE_LENGTH_TAG 0x11 /* RESPONSE LENGTH TAG */
+#define SATK_FILE_LIST_TAG 0x12 /* FILE LIST TAG */
+#define SATK_LOCATION_INFORMATION_TAG 0x13 /* LOCATION INFORMATION TAG */
+#define SATK_IMEI_TAG 0x14 /* IMEI TAG */
+#define SATK_HELP_REQUEST_TAG 0x15 /* HELP REQUEST TAG */
+#define SATK_NETWORK_MEASUREMENT_RESULTS_TAG 0x16 /* NETWORK MEASUREMENT RESULTS TAG */
+#define SATK_DEFAULT_TEXT_TAG 0x17 /* DEFAULT TEXT TAG */
+#define SATK_ITEMS_NEXT_ACTION_INDICATOR_TAG 0x18 /* ITEMS NEXT ACTION INDICATOR TAG */
+#define SATK_EVENT_LIST_TAG 0x19 /* EVENT LIST TAG */
+#define SATK_CAUSE_TAG 0x1A /* CAUSE TAG */
+#define SATK_LOCATION_STATUS_TAG 0x1B /* LOCATION STATUS TAG */
+#define SATK_BCCH_CHANNEL_LIST_TAG 0x1D /* BCCH CHANNEL LIST TAG */
+#define SATK_ICON_IDENTIFIER_TAG 0x1E /* ICON IDENTIFIER TAG */
+#define SATK_ITEM_ICON_IDENTIFIER_LIST_TAG 0x1F /* ITEM ICON IDENTIFIER LIST TAG */
+#define SATK_DATE_TIME_AND_TIME_ZONE_TAG 0x26 /* DATE TIME AND TIME ZONE TAG */
+#define SATK_CALL_CONTROL_REQUESTED_ACTION_TAG 0x27 /* CALL CONTROL REQUESTED ACTION TAG */
+#define SATK_AT_COMMAND_TAG 0x28 /* AT COMMAND TAG */
+#define SATK_AT_RESPONSE_TAG 0x29 /* AT RESPONSE TAG */
+#define SATK_BC_REPEAT_INDICATOR_TAG 0x2A /* BC REPEAT INDICATOR TAG */
+#define SATK_IMMEDIATE_RESPONSE_TAG 0x2B /* IMMEDIATE RESPONSE TAG */
+#define SATK_DTMF_STRING_TAG 0x2C /* DTMF STRING TAG */
+#define SATK_LANGUAGE_TAG 0x2D /* LANGUAGE TAG */
+#define SATK_BROWSER_IDENTITY_TAG 0x30 /* BROWSER IDENTITY TAG */
+#define SATK_URL_TAG 0x31 /* URL TAG */
+#define SATK_BEARER_TAG 0x32 /* BEARER TAG */
+#define SATK_PROVISIONING_REF_FILE_TAG 0x33 /* PROVISIONING REFERENCE FILE TAG */
+#define SATK_BROWSER_TERMINATION_CAUSE_TAG 0x34 /* BROWSER TERMINATION CAUSE TAG */
+#define SATK_BEARER_DISCRIPTION_TAG 0x35 /* BEARER DISCRIPTION TAG */
+#define SATK_CHANNEL_DATA_TAG 0x36 /* CHANNEL DATA TAG */
+#define SATK_CHANNEL_DATA_LEN_TAG 0x37 /* CHANNEL DATA LEN TAG */
+#define SATK_CHANNEL_STATUS_TAG 0x38 /* CHANNEL STATUS TAG */
+#define SATK_BUFFER_SIZE_TAG 0x39 /* BUFFER SIZE TAG */
+#define SATK_CARD_READER_IDENTIFIER_TAG 0x3A /* CARD READER IDENTIFIER TAG */
+#define SATK_USIM_ME_INTERFACE_TRANSPORT_LEVEL_TAG 0x3C /* USIM ME INTERFACE TRANSPORT LEVEL */
+#define SATK_OTHER_ADDRESS_TAG 0x3E /* OTHER ADDRESS */
+#define SATK_NETWORK_ACCESS_TAG 0x47 /* NETWORK ACCESS NAME TAG */
+#define SATK_CDMA_SMS_TPDU_TAG 0x48 /* CDMA SMS TPDU TAG */
+#define SATK_REMOTE_ENTITY_ADDRESS_TAG 0x49 /* REMOTE ENTITY ADDRESS TAG */
+#define SATK_TEXT_ATTRIBUTE_TAG 0x50 /* TEXT ATTRIBUTE TAG */
+#define SATK_TEXT_ATTRIBUTE_LIST_TAG 0x51 /* TEXT ATTRIBUTE LIST TAG */
+
+/* general data object lengths */
+#define SATK_DCS_LENGTH 0x01
+#define SATK_COMMAND_DETAILS_LENGTH 0x03 /* COMMAND DETAILS LENGTH */
+#define SATK_DEVICE_IDENTITY_LENGTH 0x02 /* DEVICE IDENTITY LENGTH */
+#define SATK_ICON_IDENTITY_LENGTH 0x02 /* ICON IDENTITY LENGTH */
+#define SATK_DURATION_LENGTH 0x02 /* DURATION LENGTH */
+#define SATK_ITEM_IDENTIFIER_LENGTH 0x01 /* ITEM IDENTIFIER LENGTH */
+#define SATK_LOCATION_INFORMATION_LENGTH 0x07 /* LOCATION INFORMATION LENGTH */
+#define SATK_HELP_REQUEST_LENGTH 0x00 /* HELP REQUEST LENGTH */
+#define SATK_LOCATION_STATUS_LENGTH 0x01 /* LOCATION STATUS LENGTH */
+#define SATK_DATE_TIME_AND_TIME_ZONE_LENGTH 0x07 /* DATE TIME AND TIME ZONE LENGTH */
+#define SATK_LANGUAGE_LENGTH 0x02 /* LANGUAGE LENGTH */
+#define SATK_BC_REPEAT_IND_LENGTH 0x01 /* BC REPEAT INDICATION LENGTH */
+#define SATK_RESPONSE_LENGTH_LENGTH 0x02 /* RESPONSE LENGTH LENGTH */
+#define SATK_TONE_LENGTH 0x01 /* TONE LENGTH */
+#define SATK_BROWSER_ID_LENGTH 0x01 /* BROWSER ID LENGTH */
+#define SATK_BROWSER_TERMINATION_CAUSE_LENGTH 0x01 /* BROWSER TERMINATION CAUSE LENGTH */
+#define SATK_BUFFER_SIZE_LENGTH 0x02 /* BUFFER SIZE LENGTH */
+#define SATK_UICC_ME_TRANS_INTERFACE_LEVEL_LENGTH 0x03 /* UICC TERMINAL TRANSPORT INTERFACE LEVEL LENGTH */
+#define SATK_CHANNEL_DATA_LENGTH_VALUE_LENGTH 0x01 /* CHANNEL DATA LENGTH VALUE LENGTH */
+#define SATK_CHANNEL_STATUS_LENGTH 0x02 /* CHANNEL STATUS LENGTH */
+
+struct private_object_data {
+ struct tcore_sat_operations *ops[TCORE_OPS_TYPE_MAX];
+};
+
+gboolean b_comprehensive = FALSE;
+
+static TReturn _dispatcher(CoreObject *o, UserRequest *ur, enum tcore_ops_type ops_type)
+{
+ enum tcore_request_command command;
+ struct private_object_data *po = tcore_object_ref_object(o);
+ struct tcore_sat_operations *ops = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_SAT, TCORE_RETURN_EINVAL);
+ CORE_OBJECT_VALIDATE_OPS_RETURN_VAL(ops_type, TCORE_RETURN_EINVAL);
+
+ tcore_check_null_ret_err("po", po, TCORE_RETURN_EINVAL);
+ tcore_check_null_ret_err("ur", ur, TCORE_RETURN_EINVAL);
+
+ ops = po->ops[ops_type];
+ tcore_check_null_ret_err("ops", ops, TCORE_RETURN_FAILURE);
+
+ command = tcore_user_request_get_command(ur);
+ switch (command) {
+ case TREQ_SAT_REQ_ENVELOPE:
+ tcore_check_null_ret_err("ops->envelope",
+ ops->envelope, TCORE_RETURN_ENOSYS);
+
+ return ops->envelope(o, ur);
+
+ case TREQ_SAT_REQ_TERMINALRESPONSE:
+ tcore_check_null_ret_err("ops->terminal_response",
+ ops->terminal_response, TCORE_RETURN_ENOSYS);
+
+ return ops->terminal_response(o, ur);
+
+ case TREQ_SAT_REQ_USERCONFIRMATION:
+ tcore_check_null_ret_err("ops->user_confirmation",
+ ops->user_confirmation, TCORE_RETURN_ENOSYS);
+
+ return ops->user_confirmation(o, ur);
+
+ default:
+ break;
+ }
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+static void _free_hook(CoreObject *o)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_SAT);
+
+ po = tcore_object_ref_object(o);
+ if (po) {
+ free(po);
+ tcore_object_link_object(o, NULL);
+ }
+}
+
+static gboolean _check_file_for_refresh(enum tel_sim_file_id file_id)
+{
+ int i;
+ enum tel_sim_file_id ef_under_mf[3] = {SIM_EF_DIR, SIM_EF_ELP, SIM_EF_ICCID};
+ enum tel_sim_file_id ef_under_df[29] = {
+ SIM_EF_IMSI, SIM_EF_SST,
+ SIM_EF_EST, SIM_EF_OPLMN_ACT,
+ SIM_EF_GID1, SIM_EF_GID2,
+ SIM_EF_LP, SIM_EF_ECC,
+ SIM_EF_SPN, SIM_EF_SPDI,
+ SIM_EF_PNN, SIM_EF_OPL,
+ SIM_EF_MBDN, SIM_EF_MSISDN,
+ SIM_EF_USIM_MBI, SIM_EF_USIM_MWIS,
+ SIM_EF_USIM_CFIS, SIM_EF_CPHS_VOICE_MSG_WAITING,
+ SIM_EF_CPHS_SERVICE_STRING_TABLE, SIM_EF_CPHS_CALL_FORWARD_FLAGS,
+ SIM_EF_CPHS_OPERATOR_NAME_STRING, SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE,
+ SIM_EF_CPHS_CPHS_INFO, SIM_EF_CPHS_MAILBOX_NUMBERS,
+ SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING, SIM_EF_CPHS_INFORMATION_NUMBERS,
+ SIM_EF_CPHS_DYNAMICFLAGS, SIM_EF_CPHS_DYNAMIC2FLAG,
+ SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE_LINE2};
+
+ dbg("[SAT] SAT PARSER - FILE ID=0x%04x", (unsigned int)file_id);
+
+ if ((file_id & 0x2F00) == 0x2F00) {
+ dbg("[SAT] SAT PARSER - MF, EF=0x%04x", file_id);
+ for (i = 0; i < 3; i++) {
+ if (file_id == ef_under_mf[i]) {
+ dbg("[SAT] SAT PARSER - MATCH!");
+ return TRUE;
+ }
+ }
+ } else if ((file_id & 0x6F00) == 0x6F00) {
+ dbg("[SAT] SAT PARSER - ADF_USIM EF=0x%04x", file_id);
+ for (i = 0; i < 29; i++) {
+ if (file_id == ef_under_df[i]) {
+ dbg("[SAT] SAT PARSER - MATCH!");
+ return TRUE;
+ }
+ }
+ }
+
+ return FALSE;
+}
+
+static int _get_length_filed_size(unsigned char firstLenByte)
+{
+ if (firstLenByte <= 0x7F)
+ return 1;
+ else if (firstLenByte == 0x81)
+ return 2;
+ else
+ return 0; /* return zero, as the length field can only be 1 or 2. */
+}
+
+static void _get_string_data(unsigned char *src, int len,
+ struct tel_sat_text_string_object *text_obj)
+{
+ if (!src || !text_obj) return;
+
+ switch (text_obj->dcs.a_format) {
+ case ALPHABET_FORMAT_SMS_DEFAULT: {
+ char *unpacked_str;
+
+ text_obj->string_length = 0;
+ unpacked_str = (char *)tcore_util_unpack_gsm7bit(src, (unsigned int)len);
+ if (!unpacked_str)
+ return;
+
+ text_obj->dcs.a_format = ALPHABET_FORMAT_8BIT_DATA;
+ text_obj->string_length = strlen(unpacked_str);
+
+ if (text_obj->string_length >= SAT_TEXT_STRING_LEN_MAX) {
+ text_obj->string_length = SAT_TEXT_STRING_LEN_MAX;
+ memcpy(text_obj->string, unpacked_str, SAT_TEXT_STRING_LEN_MAX);
+ text_obj->string[SAT_TEXT_STRING_LEN_MAX] = 0x00;
+ } else {
+ memcpy(text_obj->string, unpacked_str, text_obj->string_length);
+ text_obj->string[text_obj->string_length] = 0x00;
+ }
+
+ g_free(unpacked_str);
+ }
+ break;
+
+ case ALPHABET_FORMAT_UCS2:
+ case ALPHABET_FORMAT_8BIT_DATA: {
+ text_obj->string_length = len;
+ if (text_obj->string_length >= SAT_TEXT_STRING_LEN_MAX) {
+ text_obj->string_length = SAT_TEXT_STRING_LEN_MAX;
+ memcpy(text_obj->string, src, SAT_TEXT_STRING_LEN_MAX);
+ text_obj->string[SAT_TEXT_STRING_LEN_MAX] = 0x00;
+ } else {
+ memcpy(text_obj->string, src, text_obj->string_length);
+ text_obj->string[text_obj->string_length + 1] = 0x00;
+ }
+ }
+ break;
+
+ default: {
+ dbg("[SAT] SAT PARSER - Unknown alphabet format(%d)", text_obj->dcs.a_format);
+ }
+ break;
+ }
+}
+
+static void _sat_decode_dcs(unsigned char dcs, struct data_coding_scheme *dsc_obj)
+{
+ dbg("[SAT] SAT PARSER - dcs=[0x%x]", dcs);
+ dsc_obj->raw_dcs = dcs;
+ /* bit 5 of DCS byte will tell us if the text is compressed or not. */
+
+ if (dcs & 0x20)
+ dsc_obj->is_compressed_format = TRUE;
+ else
+ dsc_obj->is_compressed_format = FALSE;
+
+ /* bit 4 when set, indicates that bits 0 & 1 have message class meaning. */
+ dsc_obj->m_class = MSG_CLASS_NONE;
+ if (dcs & 0x10) {
+ switch (dcs & 0x03) {
+ case 0x00:
+ dsc_obj->m_class = MSG_CLASS_0;
+ break;
+
+ case 0x01:
+ dsc_obj->m_class = MSG_CLASS_1;
+ break;
+
+ case 0x02:
+ dsc_obj->m_class = MSG_CLASS_2;
+ break;
+
+ case 0x03:
+ dsc_obj->m_class = MSG_CLASS_3;
+ break;
+
+ default:
+ err("invalid dcs type");
+ break;
+ }
+ }
+
+ /* bits 2 & 3 indicate the character set being used */
+ switch (dcs & 0x0C) {
+ case 0x00:
+ case 0x0C:
+ dsc_obj->a_format = ALPHABET_FORMAT_SMS_DEFAULT;
+ break;
+
+ case 0x04:
+ dsc_obj->a_format = ALPHABET_FORMAT_8BIT_DATA;
+ break;
+
+ case 0X08:
+ dsc_obj->a_format = ALPHABET_FORMAT_UCS2;
+ break;
+
+ default:
+ dsc_obj->a_format = ALPHABET_FORMAT_RESERVED;
+ break;
+ }
+
+ dbg("[SAT] SAT PARSER - is_compressed_format(%d), msgClass(0x%x), alpha_format(0x%x)",
+ dsc_obj->is_compressed_format, dsc_obj->m_class, dsc_obj->a_format);
+}
+
+static void _sat_decode_ton_npi(unsigned char ton_npi, enum type_of_number *ton, enum numbering_plan_identifier *npi)
+{
+ int ton_value = 0;
+ int npi_value = 0;
+
+ if (!ton || !npi)
+ return;
+
+ ton_value = (ton_npi & 0x70) >> 4;
+ *ton = ton_value;
+ if (*ton > TON_NETWORK_SPECIFIC)
+ *ton = TON_RESERVED_FOR_EXT;
+
+ npi_value = (ton_npi & 0x0F);
+ switch (npi_value) {
+ case NPI_ISDN_TEL:
+ case NPI_DATA_NUMBERING_PLAN:
+ case NPI_TELEX:
+ case NPI_PRIVATE:
+ case NPI_RESERVED_FOR_EXT:
+ *npi = npi_value;
+ break;
+
+ default:
+ *npi = NPI_UNKNOWN;
+ break;
+ }
+
+ dbg("[SAT] SAT PATSER - ton(0x%x) npi(0x%x)", *ton, *npi);
+}
+
+static enum tel_sim_language_type _sat_decode_language(unsigned char byte1, unsigned char byte2)
+{
+ if ((byte1 == 'e') && (byte2 == 'n'))
+ return SIM_LANG_ENGLISH;
+ else if ((byte1 == 'd') && (byte2 == 'e'))
+ return SIM_LANG_GERMAN;
+ else if ((byte1 == 'i') && (byte2 == 't'))
+ return SIM_LANG_ITALIAN;
+ else if ((byte1 == 'f') && (byte2 == 'r'))
+ return SIM_LANG_FRENCH;
+ else if ((byte1 == 'e') && (byte2 == 's'))
+ return SIM_LANG_SPANISH;
+ else if ((byte1 == 'n') && (byte2 == 'l'))
+ return SIM_LANG_DUTCH;
+ else if ((byte1 == 's') && (byte2 == 'v'))
+ return SIM_LANG_SWEDISH;
+ else if ((byte1 == 'd') && (byte2 == 'a'))
+ return SIM_LANG_DANISH;
+ else if ((byte1 == 'p') && (byte2 == 't'))
+ return SIM_LANG_PORTUGUESE;
+ else if ((byte1 == 'f') && (byte2 == 'i'))
+ return SIM_LANG_FINNISH;
+ else if ((byte1 == 'n') && (byte2 == 'o'))
+ return SIM_LANG_NORWEGIAN;
+ else if ((byte1 == 'e') && (byte2 == 'l'))
+ return SIM_LANG_GREEK;
+ else if ((byte1 == 't') && (byte2 == 'r'))
+ return SIM_LANG_TURKISH;
+ else if ((byte1 == 'h') && (byte2 == 'u'))
+ return SIM_LANG_HUNGARIAN;
+ else if ((byte1 == 'p') && (byte2 == 'i'))
+ return SIM_LANG_POLISH;
+ else {
+ dbg("[SAT] SAT PARSER - unknown language, default to english.");
+ return SIM_LANG_ENGLISH;
+ }
+}
+
+/*
+ * Decode TLV data object
+ */
+static enum tcore_sat_result _sat_decode_address_tlv(unsigned char *tlv_str, int tlv_len,
+ int curr_offset, struct tel_sat_address *address_obj, int *consumed_data_len)
+{
+ unsigned char *src_data;
+ int temp_index, len_of_len = 0;
+ int address_len = 0;
+ gboolean comprehensive_req = FALSE;
+
+ if (tlv_str == NULL || consumed_data_len == NULL || address_obj == NULL) {
+ dbg("[SAT] SAT PARSER - tlv_str == NULL || consumed_data_len == NULL || address_obj == NULL");
+ return TCORE_SAT_ERROR_FATAL;
+ }
+
+ if (tlv_len <= (curr_offset + 1)) {
+ dbg("[SAT] SAT PARSER - incorrect length original_command_len=%d", tlv_len);
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ /* tag */
+ temp_index = curr_offset;
+ src_data = &tlv_str[0];
+ if ((src_data[temp_index] & 0x7F) != SATK_ADDRESS_TAG) {
+ dbg("[SAT] SAT PARSER - address TAG missing");
+ return TCORE_SAT_REQUIRED_VALUE_MISSING;
+ }
+
+ /* comprehensive required */
+ if ((src_data[temp_index++] & 0x80))
+ comprehensive_req = TRUE;
+
+ /* length */
+ len_of_len = _get_length_filed_size(src_data[temp_index]);
+ if (!len_of_len) {
+ dbg("[SAT] SAT PARSER - incorrect length");
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+ address_len = src_data[temp_index + len_of_len - 1];
+
+ /* check the address length */
+ temp_index += len_of_len;
+ if ((temp_index + address_len) > tlv_len) {
+ dbg("[SAT] SAT PARSER - incorrect length");
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ address_obj->dialing_number_len = 0;
+ if (address_len > 1) {
+ char *str_ascii = NULL;
+ _sat_decode_ton_npi(src_data[temp_index++], &address_obj->ton, &address_obj->npi);
+ str_ascii = tcore_util_convert_bcd2ascii((const char *)&src_data[temp_index], address_len - 1, SAT_DIALING_NUMBER_LEN_MAX);
+ if (str_ascii) {
+ memcpy(address_obj->dialing_number, str_ascii, strlen(str_ascii));
+ address_obj->dialing_number_len = strlen(str_ascii);
+ g_free(str_ascii);
+ }
+ }
+
+ if (address_obj->dialing_number_len == 0) {
+ if (comprehensive_req) {
+ err("[SAT] SAT PARSER - incorrect address");
+ return TCORE_SAT_REQUIRED_VALUE_MISSING;
+ }
+
+ dbg("comprehensive partial proactive command");
+ /* global variable (comprehensive_partial= TRUE) */
+ }
+
+ *consumed_data_len = 1 + len_of_len + address_len;
+ return TCORE_SAT_SUCCESS;
+}
+
+static enum tcore_sat_result _sat_decode_subaddress_tlv(unsigned char *tlv_str, int tlv_len,
+ int curr_offset, struct tel_sat_subaddress *sub_address_obj, int *consumed_data_len)
+{
+ unsigned char *src_data;
+ int temp_index, len_of_len = 0;
+ int sub_address_len = 0;
+ gboolean comprehensive_req = FALSE;
+
+ if (tlv_str == NULL || consumed_data_len == NULL || sub_address_obj == NULL) {
+ dbg("[SAT] SAT PARSER - tlv_str == NULL || consumed_data_len == NULL || sub_address_obj == NULL");
+ return TCORE_SAT_ERROR_FATAL;
+ }
+
+ if (tlv_len <= (curr_offset + 1)) {
+ dbg("[SAT] SAT PARSER - incorrect length original_command_len=%d", tlv_len);
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ /* tag */
+ temp_index = curr_offset;
+ src_data = &tlv_str[0];
+ if ((src_data[temp_index] & 0x7F) != SATK_SUB_ADDRESS_TAG) {
+ dbg("[SAT] SAT PARSER - sub address TAG missing");
+ return TCORE_SAT_REQUIRED_VALUE_MISSING;
+ }
+
+ /* comprehensive required */
+ if ((src_data[temp_index++] & 0x80))
+ comprehensive_req = TRUE;
+
+ /* length */
+ len_of_len = _get_length_filed_size(src_data[temp_index]);
+ if (!len_of_len) {
+ dbg("[SAT] SAT PARSER - incorrect length");
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ sub_address_len = src_data[temp_index + len_of_len - 1];
+
+ /* check the address length */
+ temp_index += len_of_len;
+ if ((temp_index + sub_address_len) > tlv_len) {
+ dbg("[SAT] SAT PARSER - incorrect length");
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ /* sub address */
+ if (sub_address_len <= 0) {
+ dbg("[SAT] SAT PARSER - no sub address data");
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ sub_address_obj->subaddress_len = sub_address_len;
+ if (sub_address_obj->subaddress_len > SAT_CCP_DATA_LEN_MAX) {
+ if (comprehensive_req) {
+ dbg("[SAT] SAT PARSER - sub address is too big");
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ } else {
+ /* bIsComprehensionPartial = TRUE; */
+ sub_address_obj->subaddress_len = 0;
+ }
+ } else
+ memcpy(sub_address_obj->subaddress, &src_data[temp_index], sub_address_obj->subaddress_len);
+
+ *consumed_data_len = 1 + len_of_len + sub_address_len;
+ return TCORE_SAT_SUCCESS;
+}
+
+static enum tcore_sat_result _sat_decode_alpha_identifier_tlv(unsigned char *tlv_str, int tlv_len,
+ int curr_offset, struct tel_sat_alpha_identifier *alpha_id_obj, int *consumed_data_len)
+{
+ unsigned char *src_data;
+ int temp_index, len_of_len = 0;
+ int alpha_len = 0;
+
+ if (tlv_str == NULL || consumed_data_len == NULL || alpha_id_obj == NULL) {
+ dbg("[SAT] SAT PARSER - tlv_str == NULL || consumed_data_len == NULL || alpha_id_obj == NULL");
+ return TCORE_SAT_ERROR_FATAL;
+ }
+
+ if (tlv_len <= (curr_offset + 1)) {
+ dbg("[SAT] SAT PARSER - incorrect length original_command_len=%d", tlv_len);
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ /* tag */
+ temp_index = curr_offset;
+ src_data = &tlv_str[0];
+ if ((src_data[temp_index++] & 0x7F) != SATK_ALPHA_IDENTIFIER_TAG) {
+ dbg("[SAT] SAT PARSER - alphaID TAG missing");
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ /* length */
+ alpha_id_obj->is_exist = TRUE;
+ len_of_len = _get_length_filed_size(src_data[temp_index]);
+ if (!len_of_len) {
+ dbg("[SAT] SAT PARSER - incorrect length");
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ alpha_len = alpha_id_obj->alpha_data_len = src_data[temp_index + len_of_len - 1];
+
+ /* alpha identifier */
+ temp_index += len_of_len;
+ if ((temp_index + alpha_len) > tlv_len) {
+ dbg("[SAT] SAT PARSER - incorrect length");
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ if (alpha_id_obj->alpha_data_len > 0) {
+
+ unsigned char dcs;
+
+ if (alpha_id_obj->alpha_data_len >= SAT_ALPHA_ID_LEN_MAX)
+ alpha_id_obj->alpha_data_len = SAT_ALPHA_ID_LEN_MAX - 1;
+
+ memcpy(alpha_id_obj->alpha_data, &src_data[temp_index], alpha_id_obj->alpha_data_len);
+ alpha_id_obj->alpha_data[alpha_id_obj->alpha_data_len] = 0x00;
+
+ if (src_data[temp_index] == 0x80 || src_data[temp_index] == 0x81 || src_data[temp_index] == 0x82)
+ dcs = 0X08;
+ else
+ dcs = 0x04;
+
+ _sat_decode_dcs(dcs, &alpha_id_obj->dcs);
+ }
+
+ *consumed_data_len = 1 + len_of_len + alpha_len;
+ dbg("[SAT] SAT PARSER alphaId= %s", alpha_id_obj->alpha_data);
+ return TCORE_SAT_SUCCESS;
+}
+
+static enum tcore_sat_result _sat_decode_sub_address_tlv(unsigned char *tlv_str, int tlv_len,
+ int curr_offset, struct tel_sat_subaddress *sub_address_obj, int *consumed_data_len)
+{
+ int i = 0;
+ int temp_index, len_of_len = 0;
+ int sub_address_len = 0;
+ unsigned char *src_data;
+ gboolean comprehension_req = FALSE;
+
+ if (tlv_str == NULL || consumed_data_len == NULL || sub_address_obj == NULL) {
+ dbg("[SAT] SAT PARSER - tlv_str == NULL || consumed_data_len == NULL || sub_address_obj == NULL");
+ return TCORE_SAT_ERROR_FATAL;
+ }
+
+ if (tlv_len <= (curr_offset + 1)) {
+ dbg("[SAT] SAT PARSER - incorrect length original_command_len=%d", tlv_len);
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ /* tag */
+ temp_index = curr_offset;
+ src_data = &tlv_str[0];
+ if ((src_data[temp_index] & 0x7F) != SATK_SUB_ADDRESS_TAG) {
+ dbg("[SAT] SAT PARSER - address TAG missing");
+ return TCORE_SAT_REQUIRED_VALUE_MISSING;
+ }
+
+ /* comprehensive required */
+ if ((src_data[temp_index++] & 0x80))
+ comprehension_req = TRUE;
+
+ /* length */
+ len_of_len = _get_length_filed_size(src_data[temp_index]);
+ if (!len_of_len) {
+ dbg("[SAT] SAT PARSER - incorrect length");
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+ sub_address_len = src_data[temp_index + len_of_len - 1];
+
+ /* check the address length */
+ temp_index += len_of_len;
+ if ((temp_index + sub_address_len) > tlv_len) {
+ dbg("[SAT] SAT PARSER - incorrect length");
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ if (sub_address_len <= 0) {
+ dbg("[SAT] SAT PARSER - no sub address");
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ sub_address_obj->subaddress_len = sub_address_len;
+ if (sub_address_obj->subaddress_len > SAT_SUB_ADDR_LEN_MAX) {
+ if (comprehension_req)
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ else
+ sub_address_obj->subaddress_len = 0;
+ } else
+ memcpy(sub_address_obj->subaddress, &src_data[temp_index], sub_address_obj->subaddress_len);
+
+ dbg("[SAT] SAT PARSER - subAddressLen=%d", sub_address_obj->subaddress_len);
+ for (i = 0; i < sub_address_obj->subaddress_len; i++)
+ dbg("[SAT] SAT PARSER - 0x%02x\t", sub_address_obj->subaddress[i]);
+
+ *consumed_data_len = 1 + len_of_len + sub_address_len;
+ return TCORE_SAT_SUCCESS;
+}
+
+static enum tcore_sat_result _sat_decode_ccp_tlv(unsigned char *tlv_str, int tlv_len,
+ int curr_offset, struct tel_sat_ccp *ccp_obj, int *consumed_data_len)
+{
+ int i = 0;
+ int temp_index, len_of_len = 0;
+ int ccp_len = 0;
+ unsigned char *src_data;
+ gboolean comprehension_req = FALSE;
+
+ if (tlv_str == NULL || consumed_data_len == NULL || ccp_obj == NULL) {
+ dbg("[SAT] SAT PARSER - tlv_str == NULL || consumed_data_len == NULL || ccp_obj == NULL");
+ return TCORE_SAT_ERROR_FATAL;
+ }
+
+ if (tlv_len <= (curr_offset + 1)) {
+ dbg("[SAT] SAT PARSER - incorrect length original_command_len=%d", tlv_len);
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ /* tag */
+ temp_index = curr_offset;
+ src_data = &tlv_str[0];
+ if ((src_data[temp_index] & 0x7F)
+ != SATK_CAPABILITY_CONFIGURATION_PARAMETERS_TAG) {
+ dbg("[SAT] SAT PARSER - CCP TAG missing");
+ return TCORE_SAT_REQUIRED_VALUE_MISSING;
+ }
+
+ /* comprehensive required */
+ if ((src_data[temp_index++] & 0x80))
+ comprehension_req = TRUE;
+
+ /* length */
+ len_of_len = _get_length_filed_size(src_data[temp_index]);
+ if (!len_of_len) {
+ dbg("[SAT] SAT PARSER - incorrect length");
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ ccp_len = src_data[temp_index + len_of_len - 1];
+
+ /* check the address length */
+ temp_index += len_of_len;
+ if ((temp_index + ccp_len) > tlv_len) {
+ dbg("[SAT] SAT PARSER - incorrect length");
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ if (ccp_len <= 0) {
+ dbg("[SAT] SAT PARSER - no ccp data");
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ ccp_obj->data_len = ccp_len;
+ if (ccp_obj->data_len > SAT_CCP_DATA_LEN_MAX) {
+ if (comprehension_req)
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ else
+ ccp_obj->data_len = 0;
+ } else
+ memcpy(ccp_obj->data, &src_data[temp_index], ccp_obj->data_len);
+
+ dbg("[SAT] SAT PARSER - ccp len=%d", ccp_obj->data_len);
+ for (i = 0; i < ccp_obj->data_len; i++)
+ dbg("[SAT] SAT PARSER - 0x%02x\t", ccp_obj->data[i]);
+
+ *consumed_data_len = 1 + len_of_len + ccp_len;
+ return TCORE_SAT_SUCCESS;
+}
+
+static enum tcore_sat_result _sat_decode_device_identities_tlv(unsigned char *tlv_str,
+ struct tel_sat_device_identities *dev_id_obj)
+{
+ int temp_index = 0, i;
+
+ if (tlv_str == NULL || dev_id_obj == NULL) {
+ dbg("[SAT] SAT PARSER - tlv_str == NULL || dev_id_obj == NULL");
+ return TCORE_SAT_ERROR_FATAL;
+ }
+
+ if ((tlv_str[temp_index++] & 0x7F) != SATK_DEVICE_IDENTITY_TAG) {
+ dbg("[SAT] SAT PARSER - device identity tag missing.");
+ return TCORE_SAT_REQUIRED_VALUE_MISSING; /* Send TR */
+ }
+
+ if (tlv_str[temp_index++] != SATK_DEVICE_IDENTITY_LENGTH) {
+ dbg("[SAT] SAT PARSER - device identity length incorrect.");
+ return TCORE_SAT_REQUIRED_VALUE_MISSING; /* Send TR */
+ }
+
+ for (i = 0; i < 2; i++) {
+ switch (tlv_str[temp_index]) {
+ case DEVICE_ID_KEYPAD:
+ case DEVICE_ID_DISPLAY:
+ case DEVICE_ID_EARPIECE:
+ case DEVICE_ID_SIM:
+ case DEVICE_ID_ME:
+ case DEVICE_ID_NETWORK:
+ if (i == 0) dev_id_obj->src = tlv_str[temp_index];
+ if (i == 1) dev_id_obj->dest = tlv_str[temp_index];
+ break;
+
+ default:
+ if (tlv_str[temp_index] >= 0x21 && tlv_str[temp_index] <= 0x27) {
+ dbg("BIP channel id(0x%x)", tlv_str[temp_index]);
+ if (i == 0) dev_id_obj->src = tlv_str[temp_index];
+ if (i == 1) dev_id_obj->dest = tlv_str[temp_index];
+ } else {
+ dbg("unmatched device id");
+ return TCORE_SAT_REQUIRED_VALUE_MISSING;
+ }
+ break;
+ }
+
+ temp_index++;
+ }
+
+ dbg("[SAT] SAT PARSER - source=%d, dest=%d", dev_id_obj->src, dev_id_obj->dest);
+ return TCORE_SAT_SUCCESS;
+}
+
+static enum tcore_sat_result _sat_decode_duration_tlv(unsigned char *tlv_str, int tlv_len,
+ int curr_offset, struct tel_sat_duration *duration_obj, int *consumed_data_len)
+{
+ int temp_index = 0;
+ unsigned char *src_data = NULL;
+
+ if (!tlv_str || !duration_obj || !consumed_data_len) {
+ err("[SAT] SAT PARSER data is null");
+ return TCORE_SAT_ERROR_FATAL;
+ }
+
+ if (tlv_len < curr_offset + 3) {
+ err("[SAT] SAT PARSER - incorrect length original_command_len=%d", tlv_len);
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ temp_index = curr_offset;
+ src_data = &tlv_str[0];
+ if ((src_data[temp_index++] & 0x7F) != SATK_DURATION_TAG) {
+ err("[SAT] SAT PARSER - duration tag missing.");
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; /* Send TR */
+ }
+
+ if (src_data[temp_index++] != SATK_DURATION_LENGTH) {
+ err("[SAT] SAT PARSER - incorrect length value.");
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; /* Send TR */
+ }
+
+ /* time unit */
+ switch (src_data[temp_index]) {
+ case TIME_UNIT_MINUTES:
+ case TIME_UNIT_SECONDS:
+ case TIME_UNIT_TENTHS_OF_SECONDS:
+ duration_obj->time_unit = src_data[temp_index];
+ break;
+
+ default:
+ duration_obj->time_unit = TIME_UNIT_RESERVED;
+ break;
+ }
+
+ /* interval */
+ temp_index++;
+ duration_obj->time_interval = src_data[temp_index];
+ *consumed_data_len = 4;
+
+ dbg("[SAT] SAT PARSER - timeUnit=%d, interval=%d",
+ duration_obj->time_unit, duration_obj->time_interval);
+
+ return TCORE_SAT_SUCCESS;
+}
+
+static enum tcore_sat_result _sat_decode_item_tlv(unsigned char *tlv_str, int tlv_len,
+ int curr_offset, struct tel_sat_item_info *item_obj, int *consumed_data_len)
+{
+ int temp_index, len_of_len = 0, i = 0;
+ int item_len = 0;
+ unsigned char dcs;
+ unsigned char *src_data = NULL;
+
+ if (tlv_str == NULL || consumed_data_len == NULL || item_obj == NULL) {
+ dbg("[SAT] SAT PARSER - tlv_str == NULL || consumed_data_len == NULL || item_obj == NULL");
+ return TCORE_SAT_ERROR_FATAL;
+ }
+
+ if (tlv_len <= (curr_offset + 1)) {
+ dbg("[SAT] SAT PARSER - incorrect length original_command_len=%d", tlv_len);
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ /* tag */
+ temp_index = curr_offset;
+ src_data = &tlv_str[0];
+ if ((src_data[temp_index++] & 0x7F) != SATK_ITEM_TAG) {
+ dbg("[SAT] SAT PARSER - tag not found.=%d", src_data[temp_index-1]);
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ /* length */
+ len_of_len = _get_length_filed_size(src_data[temp_index]);
+ if (!len_of_len) {
+ dbg("[SAT] SAT PARSER - incorrect length");
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ item_len = src_data[temp_index + len_of_len-1];
+
+ temp_index += len_of_len; /* temp_index pointing to item. */
+ if ((temp_index + item_len) > tlv_len) {
+ dbg("[SAT] SAT PARSER - incorrect length");
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ memset(item_obj->text, 0x00, (SAT_ITEM_TEXT_LEN_MAX + 1));
+ if (item_len <= 0) {
+ dbg("[SAT] SAT PARSER - menu_text is NULL, remove the menu");
+ *consumed_data_len = 1 + len_of_len + item_len;
+ return TCORE_SAT_SUCCESS;
+ }
+
+ /* item */
+ item_obj->item_id = src_data[temp_index++];
+
+ /*
+ * fix for orange SIM issue
+ * H0100078487 Strange Character display on SIM SAT
+ * The string length was less than its real length
+ * So garbage characters was displayed. To fix it, we would recalculate the real length.
+ */
+ for (i = 0; i < item_len-1; i++) {
+ dbg("[SAT] %d: %c", i, src_data[temp_index + i]);
+ if (src_data[temp_index + i] == 0xFF) break;
+ }
+
+ item_obj->text_len = i;
+
+ if (item_obj->text_len <= 0) {
+ dbg("[SAT] SAT PARSER - text len = 0");
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ if (item_obj->text_len >= SAT_ITEM_TEXT_LEN_MAX)
+ item_obj->text_len = SAT_ITEM_TEXT_LEN_MAX-1;
+
+ memcpy(item_obj->text, &src_data[temp_index], item_obj->text_len);
+ if (src_data[temp_index] == 0x80 || src_data[temp_index] == 0x81 || src_data[temp_index] == 0x82)
+ dcs = 0X08;
+ else
+ dcs = 0x04;
+
+ _sat_decode_dcs(dcs, &item_obj->dcs);
+
+
+ dbg("[SAT] SAT PARSER - item_text=%s", item_obj->text);
+ *consumed_data_len = 1 + len_of_len + item_len;
+ return TCORE_SAT_SUCCESS;
+}
+
+static enum tcore_sat_result _sat_decode_response_length_tlv(unsigned char *tlv_str, int tlv_len,
+ int curr_offset, struct tel_sat_response_length *response_obj, int *consumed_data_len)
+{
+ int temp_index = 0;
+ unsigned char *src_data = NULL;
+
+ if (!tlv_str || !response_obj || !consumed_data_len) {
+ err("[SAT] SAT PARSER data is null");
+ return TCORE_SAT_ERROR_FATAL;
+ }
+
+ if (tlv_len <= curr_offset + 1) {
+ err("[SAT] SAT PARSER - incorrect length original_command_len=%d", tlv_len);
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ temp_index = curr_offset;
+ src_data = &tlv_str[0];
+ if ((src_data[temp_index++] & 0x7F) != SATK_RESPONSE_LENGTH_TAG) {
+ err("[SAT] SAT PARSER - response length tag missing.");
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; /* Send TR */
+ }
+
+ if (src_data[temp_index++] != SATK_RESPONSE_LENGTH_LENGTH) {
+ err("[SAT] SAT PARSER - incorrect length value.");
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; /* Send TR */
+ }
+
+ response_obj->min = src_data[temp_index++];
+ response_obj->max = src_data[temp_index++];
+ dbg("[SAT] SAT PARSER min length(%d), max length(%d)", response_obj->min, response_obj->max);
+
+ *consumed_data_len = 4;
+ if (response_obj->min > response_obj->max) {
+ err("[SAT] SAT PARSER - : min length is larger than max length");
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ return TCORE_SAT_SUCCESS;
+}
+
+static enum tcore_sat_result _sat_decode_sms_tpdu_tlv(unsigned char *tlv_str, int tlv_len,
+ int curr_offset, struct tel_sat_sms_tpdu *sms_tpdu_obj, int *consumed_data_len)
+{
+ int temp_index = 0, len_of_len = 0;
+ int tpdu_len = 0;
+ unsigned char *src_data = NULL;
+
+ if (!tlv_str || !sms_tpdu_obj || !consumed_data_len) {
+ err("[SAT] SAT PARSER data is null");
+ return TCORE_SAT_ERROR_FATAL;
+ }
+
+ if (tlv_len <= curr_offset + 1) {
+ err("[SAT] SAT PARSER - incorrect length original_command_len=%d", tlv_len);
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ temp_index = curr_offset;
+ src_data = &tlv_str[0];
+ if ((src_data[temp_index++] & 0x7F) != SATK_SMS_TPDU_TAG) {
+ err("[SAT] SAT PARSER - sat tpdu tag missing.");
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ /* length */
+ len_of_len = _get_length_filed_size(src_data[temp_index]);
+ if (!len_of_len) {
+ err("[SAT] parser: invalid length.");
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+ tpdu_len = src_data[temp_index + len_of_len-1];
+ temp_index += len_of_len;
+
+ if (tpdu_len <= 0)
+ return TCORE_SAT_REQUIRED_VALUE_MISSING;
+
+ /* data len */
+ sms_tpdu_obj->data_len = tpdu_len;
+ if (sms_tpdu_obj->data_len > SAT_SMS_TPDU_SMS_DATA_LEN_MAX)
+ sms_tpdu_obj->data_len = SAT_SMS_TPDU_SMS_DATA_LEN_MAX;
+
+ /* data */
+ memcpy(sms_tpdu_obj->data, &src_data[temp_index], sms_tpdu_obj->data_len);
+ dbg("[SAT] SAT PARSER tpdu_len (%d)", sms_tpdu_obj->data_len);
+
+ *consumed_data_len = 1 + len_of_len + tpdu_len;
+ return TCORE_SAT_SUCCESS;
+}
+
+static enum tcore_sat_result _sat_decode_item_identifier_tlv(unsigned char *tlv_str, int tlv_len,
+ int curr_offset, struct tel_sat_item_identifier *item_identifier_obj, int *consumed_data_len)
+{
+ int temp_index = 0;
+ unsigned char *src_data = NULL;
+
+ if (!tlv_str || !item_identifier_obj || !consumed_data_len) {
+ err("[SAT] SAT PARSER data is null");
+ return TCORE_SAT_ERROR_FATAL;
+ }
+
+ if (tlv_len <= curr_offset + 1) {
+ err("[SAT] SAT PARSER - incorrect length original_command_len=%d", tlv_len);
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ temp_index = curr_offset;
+ src_data = &tlv_str[0];
+ if ((src_data[temp_index++] & 0x7F) != SATK_ITEM_IDENTIFIER_TAG) {
+ err("[SAT] SAT PARSER - Item identifier tag missing.");
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; /* Send TR */
+ }
+
+ if (src_data[temp_index++] != SATK_ITEM_IDENTIFIER_LENGTH) {
+ err("[SAT] SAT PARSER - incorrect length value.");
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; /* Send TR */
+ }
+
+ item_identifier_obj->item_identifier = src_data[temp_index++];
+ *consumed_data_len = 3;
+ dbg("[SAT] SAT PARSER item identifier(0x%02x)", item_identifier_obj->item_identifier);
+
+ return TCORE_SAT_SUCCESS;
+}
+
+static enum tcore_sat_result _sat_decode_ss_string_tlv(unsigned char *tlv_str, int tlv_len,
+ int curr_offset, struct tel_sat_ss_string *ss_str_obj, int *consumed_data_len)
+{
+ char *str_ascii = NULL;
+ int temp_index, len_of_len = 0;
+ int ss_len = 0;
+ unsigned char *src_data;
+ gboolean comprehension_req = FALSE;
+
+ if (!tlv_str || !ss_str_obj || !consumed_data_len) {
+ err("[SAT] SAT PARSER data is null");
+ return TCORE_SAT_ERROR_FATAL;
+ }
+
+ if (tlv_len <= curr_offset + 1) {
+ err("[SAT] SAT PARSER - incorrect length original_command_len=%d", tlv_len);
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ temp_index = curr_offset;
+ src_data = &tlv_str[0];
+ if ((src_data[temp_index] & 0x7F) != SATK_SS_STRING_TAG) {
+ err("[SAT] SAT PARSER - SS string tag missing.");
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; /* Send TR */
+ }
+
+ if (src_data[temp_index++] & 0x80)
+ comprehension_req = TRUE;
+
+ dbg("comprehension_req=[%d]", comprehension_req);
+
+ /* length */
+ len_of_len = _get_length_filed_size(src_data[temp_index]);
+ if (!len_of_len) {
+ err("[SAT] parser: invalid length.");
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ ss_len = src_data[temp_index + len_of_len-1];
+ dbg("[SAT] parser: ss_tlv len=%d", ss_len);
+
+ temp_index += len_of_len;
+ ss_str_obj->string_len = 0;
+
+ /* ss data */
+ if (ss_len <= 1)
+ return TCORE_SAT_REQUIRED_VALUE_MISSING;
+
+ _sat_decode_ton_npi(src_data[temp_index++], &ss_str_obj->ton, &ss_str_obj->npi);
+ str_ascii = tcore_util_convert_bcd2ascii((const char *)&src_data[temp_index], ss_len-1, SAT_SS_STRING_LEN_MAX);
+ if (str_ascii) {
+ memcpy(ss_str_obj->ss_string, str_ascii, strlen(str_ascii));
+ ss_str_obj->string_len = strlen(str_ascii);
+ g_free(str_ascii);
+ }
+
+ /* 1 is the length of Tag. */
+ *consumed_data_len = 1 + len_of_len + ss_len;
+ return TCORE_SAT_SUCCESS;
+}
+
+static enum tcore_sat_result _sat_decode_text_tlv(unsigned char *tlv_str, int tlv_len,
+ int curr_offset, struct tel_sat_text_string_object *text_obj, int *consumed_data_len)
+{
+ int temp_index, len_of_len = 0;
+ int text_len = 0;
+ unsigned char *src_data;
+ gboolean comprehension_req = FALSE;
+
+ if (!tlv_str || !consumed_data_len) {
+ err("[SAT] parser: data is null");
+ return TCORE_SAT_ERROR_FATAL;
+ }
+
+ if (tlv_len <= (curr_offset + 1)) {
+ err("[SAT] parser: incorrect length");
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ /* tag */
+ temp_index = curr_offset;
+ src_data = &tlv_str[0];
+ if ((src_data[temp_index] & 0x7F) != SATK_TEXT_STRING_TAG
+ && (src_data[temp_index] & 0x7F) != SATK_DEFAULT_TEXT_TAG) {
+ err("[SAT] parser: text string tag missing, tag=0x%x",
+ src_data[temp_index]);
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ if (src_data[temp_index++] & 0x80)
+ comprehension_req = TRUE;
+
+ dbg("comprehension_req=[%d]", comprehension_req);
+
+ /* length */
+ len_of_len = _get_length_filed_size(src_data[temp_index]);
+ if (!len_of_len) {
+ err("[SAT] parser: invalid length.");
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ text_len = src_data[temp_index + len_of_len-1];
+ temp_index += len_of_len;
+ memset(text_obj->string, 0x00, SAT_TEXT_STRING_LEN_MAX);
+
+ /* text */
+ if (text_len <= 1) {
+ text_obj->string_length = 0;
+ } else {
+ _sat_decode_dcs(src_data[temp_index++], &text_obj->dcs);
+ _get_string_data(&src_data[temp_index], text_len-1, text_obj);
+ }
+
+ dbg("[SAT] parser: text_tlv_len=%d, parsed text length=%d", text_len, text_obj->string_length);
+
+ /* 1 is the length of Tag. */
+ *consumed_data_len = 1 + len_of_len + text_len;
+
+ return TCORE_SAT_SUCCESS;
+}
+
+static enum tcore_sat_result _sat_decode_tone_tlv(unsigned char *tlv_str, int tlv_len,
+ int curr_offset, struct tel_sat_tone *tone_obj, int *consumed_data_len)
+{
+ int temp_index;
+ unsigned char *src_data;
+ gboolean comprehension_req = FALSE;
+
+ if (tlv_str == NULL || consumed_data_len == NULL || tone_obj == NULL) {
+ dbg("[SAT] SAT PARSER - tlv_str == NULL || consumed_data_len == NULL || tone_obj == NULL");
+ return TCORE_SAT_ERROR_FATAL;
+ }
+
+ if (tlv_len <= (curr_offset + 1)) {
+ dbg("[SAT] SAT PARSER - incorrect length original_command_len=%d", tlv_len);
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ /* tag */
+ temp_index = curr_offset;
+ src_data = &tlv_str[0];
+ if ((src_data[temp_index] & 0x7F) != SATK_TONE_TAG) {
+ err("[SAT] parser: tone tag missing");
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ if (src_data[temp_index++] & 0x80)
+ comprehension_req = TRUE;
+
+ /* length */
+ if (src_data[temp_index++] != SATK_TONE_LENGTH) {
+ err("[SAT] SAT PARSER - incorrect length value.");
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; /* Send TR */
+ }
+
+ if ((temp_index + SATK_TONE_LENGTH) > tlv_len) {
+ err("[SAT] SAT PARSER - incorrect cmd len, expected len = %d, orig_len=%d",
+ (temp_index + SATK_TONE_LENGTH), tlv_len);
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ /* tone */
+ switch (src_data[temp_index]) {
+ /* standard supervisory tones */
+ case DIAL_TONE:
+ case CALLED_SUBSCRIBER_BUSY:
+ case CONGESTION:
+ case RADIO_PATH_ACK:
+ case RADIO_PATH_NOT_AVAILABLE_CALL_DROPPED:
+ case ERR_SPECIAL_INFO:
+ case CALL_WAITING_TONE:
+ case RINGING_TONE:
+ /* ME proprietary tones */
+ case GENERAL_BEEP:
+ case POSITIVE_ACK_TONE:
+ case NEGATIVE_ACK_OR_ERROR_TONE:
+ case RINGING_TONE_SLCTD_BY_USR_FOR_INCOM_SPEECH_CALL:
+ case ALERT_TONE_SELECTED_BY_USER_FOR_INCOMING_SMS:
+ case CRITICAL_ALERT:
+ /* Themed tones */
+ case HAPPY_TONE:
+ case SAD_TONE:
+ case URGENT_ACTION_TONE:
+ case QUESTION_TONE:
+ case MESSAGE_RECEIVED_TONE:
+ /* Melody tones */
+ case MELODY_1:
+ case MELODY_2:
+ case MELODY_3:
+ case MELODY_4:
+ case MELODY_5:
+ case MELODY_6:
+ case MELODY_7:
+ case MELODY_8:
+ dbg("[SAT] SAT PARSER - Tone =0x%x", src_data[temp_index]);
+ tone_obj->tone_type = src_data[temp_index];
+ break;
+
+ case TONE_TYPE_RESERVED: /* Fallthrough */
+ default:
+ dbg("[SAT] SAT PARSER - Reserved value of Tone =0x%x", src_data[temp_index]);
+ if (comprehension_req)
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ break;
+ }
+
+ *consumed_data_len = 3;
+ return TCORE_SAT_SUCCESS;
+}
+
+static enum tcore_sat_result _sat_decode_ussd_string_tlv(unsigned char *tlv_str, int tlv_len,
+ int curr_offset, struct tel_sat_ussd_string *ussd_str_obj, int *consumed_data_len)
+{
+ int temp_index, len_of_len = 0;
+ int ussd_len = 0;
+ unsigned char *src_data;
+ gboolean comprehension_req = FALSE;
+
+ if (!tlv_str || !ussd_str_obj || !consumed_data_len) {
+ err("[SAT] SAT PARSER data is null");
+ return TCORE_SAT_ERROR_FATAL;
+ }
+
+ if (tlv_len <= curr_offset + 1) {
+ err("[SAT] SAT PARSER - incorrect length original_command_len=%d", tlv_len);
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ temp_index = curr_offset;
+ src_data = &tlv_str[0];
+ if ((src_data[temp_index] & 0x7F) != SATK_USSD_STRING_TAG) {
+ err("[SAT] SAT PARSER - SS string tag missing.");
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; /* Send TR */
+ }
+
+ if (src_data[temp_index++] & 0x80)
+ comprehension_req = TRUE;
+
+ dbg("comprehension_req=[%d]", comprehension_req);
+
+ /* length */
+ len_of_len = _get_length_filed_size(src_data[temp_index]);
+ if (!len_of_len) {
+ err("[SAT] parser: invalid length.");
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ ussd_len = src_data[temp_index + len_of_len-1];
+ dbg("[SAT] parser: ussd_tlv len=%d", ussd_len);
+
+ temp_index += len_of_len;
+ ussd_str_obj->string_len = 0;
+
+ /* ussd data */
+ if (ussd_len <= 1)
+ return TCORE_SAT_REQUIRED_VALUE_MISSING;
+
+ _sat_decode_dcs(src_data[temp_index++], &ussd_str_obj->dsc);
+ ussd_str_obj->string_len = ussd_len - 1;
+ memcpy(ussd_str_obj->ussd_string, &src_data[temp_index], ussd_str_obj->string_len);
+
+ /* 1 is the length of Tag. */
+ *consumed_data_len = 1 + len_of_len + ussd_len;
+ return TCORE_SAT_SUCCESS;
+}
+
+static enum tcore_sat_result _sat_decode_file_list_tlv(unsigned char *tlv_str, int tlv_len,
+ int curr_offset, struct tel_sat_file_list *file_list_obj, int *consumed_data_len)
+{
+ /* tmp */
+ int tmp_cnt;
+ int f_count;
+ unsigned int ef = 0x0000;
+
+ int temp_index, len_of_len = 0;
+ int file_list_len = 0;
+ unsigned char *src_data;
+
+ if (tlv_str == NULL || consumed_data_len == NULL || file_list_obj == NULL) {
+ dbg("[SAT] SAT PARSER - tlv_str == NULL || consumed_data_len == NULL || file_list_obj == NULL");
+ return TCORE_SAT_ERROR_FATAL;
+ }
+
+ if (tlv_len <= (curr_offset + 1)) {
+ dbg("[SAT] SAT PARSER - incorrect length original_command_len=%d", tlv_len);
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ /* tag */
+ temp_index = curr_offset;
+ src_data = &tlv_str[0];
+ if ((src_data[temp_index] & 0x7F) != SATK_FILE_LIST_TAG) {
+ err("[SAT] parser: tag missing, tag=0x%x", src_data[temp_index]);
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ /* length */
+ len_of_len = _get_length_filed_size(src_data[temp_index]);
+ if (!len_of_len) {
+ err("[SAT] parser: invalid length.");
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ file_list_len = src_data[temp_index + len_of_len-1];
+ temp_index += len_of_len;
+
+ if ((temp_index + file_list_len) > tlv_len) {
+ dbg("[SAT] SAT PARSER - incorrect cmd len, expected len = %d, orig_len=%d",
+ (temp_index + file_list_len), tlv_len);
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ tmp_cnt = src_data[temp_index++];
+ file_list_obj->file_count = 0;
+ memset(file_list_obj->file_id, 0, SAT_FILE_ID_LIST_MAX_COUNT);
+
+ if (!tmp_cnt) {
+ dbg("file cnt = 0");
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ f_count = 0;
+ do {
+ ef = 0x0000;
+ if (src_data[temp_index] != 0x3F || src_data[temp_index + 1] != 0x00) {
+ temp_index++;
+ if (temp_index > tlv_len)
+ break;
+ else
+ continue;
+ }
+
+ temp_index += 2; /* MASTER FILE (DIR) 0x3F00 */
+
+ if (src_data[temp_index] == 0x2F) {
+ /* ELEMENTRY FILE (VALUE) */
+ ef = src_data[temp_index] << 8;
+ temp_index++;
+ ef = ef | src_data[temp_index];
+
+ if (_check_file_for_refresh((enum tel_sim_file_id)ef)) {/* check file registered for refresh? */
+ file_list_obj->file_id[file_list_obj->file_count] = ef;
+ file_list_obj->file_count++;
+ }
+ } else if (src_data[temp_index] == 0x7F && src_data[temp_index + 1] == 0xFF) {
+ /* USIM DIRECTORY FILE (DIR) 0x7FFF */
+ temp_index += 2;
+ if (src_data[temp_index] == 0x6F) {
+ ef = 0x6A << 8;
+ temp_index++;
+ ef = ef | src_data[temp_index];
+
+ if (_check_file_for_refresh((enum tel_sim_file_id)ef)) {/* check file registered for refresh? */
+ file_list_obj->file_id[file_list_obj->file_count] = ef;
+ file_list_obj->file_count++;
+ }
+ } else
+ temp_index++;
+ } else if (src_data[temp_index] == 0x7F && (src_data[temp_index + 1] == 0x10
+ || src_data[temp_index + 1] == 0x20)) {
+ /* TELECOM DIRECTORY FILE 0x7F10 or GSM DIRECTORY FILE 0x7F20 */
+ temp_index += 2;
+ if (src_data[temp_index] == 0x6F) {
+ ef = src_data[temp_index] << 8;
+ temp_index++;
+ ef = ef | src_data[temp_index];
+
+ if (_check_file_for_refresh((enum tel_sim_file_id)ef)) {/* check file registered for refresh? */
+ file_list_obj->file_id[file_list_obj->file_count] = ef;
+ file_list_obj->file_count++;
+ }
+ } else
+ temp_index++;
+ }
+
+ f_count++;
+ temp_index++;
+ } while (f_count < tmp_cnt);
+
+ dbg("[SAT] SAT PARSER - total file count=%d, PDA file count = %d", tmp_cnt, file_list_obj->file_count);
+ *consumed_data_len = 1 + len_of_len + file_list_len;
+ return TCORE_SAT_SUCCESS;
+}
+
+static enum tcore_sat_result _sat_decode_item_next_action_indicator_tlv(unsigned char *tlv_str, int tlv_len, int curr_offset,
+ struct tel_sat_item_next_action_indicatior_list *item_next_act_indi_obj, int *consumed_data_len)
+{
+ int temp_index;
+ int item_nai_len;
+ unsigned char *src_data;
+ gboolean comprehension_req = FALSE;
+
+ if (tlv_str == NULL || consumed_data_len == NULL || item_next_act_indi_obj == NULL) {
+ dbg("[SAT] SAT PARSER - tlv_str == NULL || consumed_data_len == NULL || item_next_act_indi_obj == NULL");
+ return TCORE_SAT_ERROR_FATAL;
+ }
+
+ if (tlv_len <= (curr_offset + 1)) {
+ dbg("[SAT] SAT PARSER - incorrect length original_command_len=%d", tlv_len);
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ /* tag */
+ temp_index = curr_offset;
+ src_data = &tlv_str[0];
+ if ((src_data[temp_index] & 0x7F) != SATK_ITEMS_NEXT_ACTION_INDICATOR_TAG) {
+ dbg("[SAT] SAT PARSER - tag not found.=%d", src_data[temp_index]);
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ if ((src_data[temp_index++] & 0x7F))
+ comprehension_req = TRUE;
+
+ /* item cnt */
+ item_nai_len = item_next_act_indi_obj->cnt = src_data[temp_index++];
+ if ((temp_index + item_nai_len) > tlv_len) {
+ dbg("[SAT] SAT PARSER - incorrect cmd len, expected len = %d, orig_len=%d",
+ (temp_index + item_nai_len), tlv_len);
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ if (item_next_act_indi_obj->cnt > SAT_ITEMS_NEXT_ACTION_INDI_LIST_MAX_COUNT) {
+ if (comprehension_req == TRUE) {
+ dbg("[SAT] SAT PARSER - list count exceeds maximum allowed count=%d", item_next_act_indi_obj->cnt);
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ item_next_act_indi_obj->cnt = 0;
+ }
+
+ memset(item_next_act_indi_obj->indicator_list, 0xFF, SAT_ITEMS_NEXT_ACTION_INDI_LIST_MAX_COUNT);
+ if (item_next_act_indi_obj->cnt > 0)
+ memcpy(item_next_act_indi_obj->indicator_list, &src_data[temp_index], item_next_act_indi_obj->cnt);
+
+ *consumed_data_len = 1 + 1 + item_nai_len;
+ dbg("[SAT] SAT PARSER - listCount=%d, consumed_data_len = %d", item_next_act_indi_obj->cnt, *consumed_data_len);
+ return TCORE_SAT_SUCCESS;
+}
+
+static enum tcore_sat_result _sat_decode_event_list_tlv(unsigned char *tlv_str, int tlv_len,
+ int curr_offset, struct tel_sat_event_list *event_list_obj, int *consumed_data_len)
+{
+ int i = 0;
+ int temp_index, len_of_len = 0;
+ int evt_list_len;
+ unsigned char *src_data;
+ gboolean comprehension_req = FALSE;
+
+ if (tlv_str == NULL || consumed_data_len == NULL || event_list_obj == NULL) {
+ dbg("[SAT] SAT PARSER - tlv_str == NULL || consumed_data_len == NULL || event_list_obj == NULL");
+ return TCORE_SAT_ERROR_FATAL;
+ }
+
+ if (tlv_len <= (curr_offset + 1)) {
+ dbg("[SAT] SAT PARSER - incorrect length original_command_len=%d", tlv_len);
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ /* tag */
+ temp_index = curr_offset;
+ src_data = &tlv_str[0];
+ if ((src_data[temp_index] & 0x7F) != SATK_EVENT_LIST_TAG) {
+ dbg("[SAT] SAT PARSER - tag not found.=%d", src_data[temp_index]);
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ if ((src_data[temp_index++] & 0x80))
+ comprehension_req = TRUE;
+
+ /* length */
+ len_of_len = _get_length_filed_size(src_data[temp_index]);
+ if (!len_of_len) {
+ err("[SAT] parser: invalid length.");
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ evt_list_len = src_data[temp_index + len_of_len-1];
+ dbg("[SAT] parser: evt_list_len=%d", evt_list_len);
+ temp_index += len_of_len;
+
+ if ((temp_index + evt_list_len) > tlv_len) {
+ dbg("[SAT] SAT PARSER - incorrect cmd len, expected len = %d, orig_len=%d",
+ (temp_index + evt_list_len), tlv_len);
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ if (evt_list_len > SAT_EVENT_LIST_MAX) {
+ dbg("[SAT] SAT PARSER - event list contains more items than it is supposed to have! len=%d",
+ evt_list_len);
+ if (comprehension_req)
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ else
+ evt_list_len = SAT_EVENT_LIST_MAX;
+ }
+
+ event_list_obj->event_list_cnt = 0;
+ memset(event_list_obj->evt_list, 0xFF, SAT_EVENT_LIST_MAX);
+
+ /* event list */
+ for (i = 0; i < evt_list_len; i++) {
+ dbg("[SAT] SAT PARSER - event[%d]=0x%x",
+ i, src_data[temp_index]);
+ switch (src_data[temp_index]) {
+ /* PDA events */
+ case EVENT_USER_ACTIVITY:
+ case EVENT_IDLE_SCREEN_AVAILABLE:
+ case EVENT_LANGUAGE_SELECTION:
+ case EVENT_BROWSER_TERMINATION:
+ case EVENT_DATA_AVAILABLE:
+ case EVENT_CHANNEL_STATUS:
+ case EVENT_MT_CALL:
+ case EVENT_CALL_CONNECTED:
+ case EVENT_CALL_DISCONNECTED:
+ case EVENT_LOCATION_STATUS:
+ case EVENT_ACCESS_TECHNOLOGY_CHANGED:
+ event_list_obj->evt_list[i] = src_data[temp_index];
+ event_list_obj->event_list_cnt++;
+ break;
+
+ case EVENT_UNKNOWN: /* Fallthrough */
+ default:
+ if (comprehension_req)
+ return TCORE_SAT_BEYOND_ME_CAPABILITY;
+ break;
+ }
+ temp_index++;
+ }
+
+ /* 1 is the length of Tag. */
+ *consumed_data_len = 1 + len_of_len + evt_list_len;
+ return TCORE_SAT_SUCCESS;
+}
+
+static enum tcore_sat_result _sat_decode_icon_identifier_tlv(unsigned char *tlv_str, int tlv_len,
+ int curr_offset, struct tel_sat_icon_identifier *icon_id_obj, int *consumed_data_len)
+{
+ unsigned char *src_data;
+ int temp_index = 0;
+
+ if (tlv_str == NULL || icon_id_obj == NULL || consumed_data_len == NULL) {
+ dbg("[SAT] SAT PARSER - tlv_str == NULL || icon_id_obj == NULL ||consumed_data_len == NULL");
+ return TCORE_SAT_ERROR_FATAL;
+ }
+
+ if (tlv_len <= (curr_offset + 1)) {/* length of icon id tlv is 4 */
+ dbg("[SAT] SAT PARSER - incorrect length original_command_len=%d", tlv_len);
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ /* tag */
+ temp_index = curr_offset;
+ src_data = &tlv_str[0];
+ if ((src_data[temp_index++] & 0x7F) != SATK_ICON_IDENTIFIER_TAG) {
+ dbg("[SAT] SAT PARSER - icon identity tag missing.");
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; /* Send TR */
+ }
+
+ if (src_data[temp_index++] != SATK_ICON_IDENTITY_LENGTH) {
+ dbg("[SAT] SAT PARSER - incorrect length value.");
+ return FALSE; /* Send TR */
+ }
+
+ if ((temp_index + SATK_ICON_IDENTITY_LENGTH) > tlv_len) {
+ dbg("[SAT] SAT PARSER - incorrect cmd len, expected len = %d, orig_len=%d",
+ (temp_index + SATK_ICON_IDENTITY_LENGTH), tlv_len);
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ icon_id_obj->is_exist = TRUE;
+
+ if ((src_data[temp_index++] & 0x01))
+ icon_id_obj->icon_qualifer = ICON_QUALI_NOT_SELF_EXPLANATORY;
+ else
+ icon_id_obj->icon_qualifer = ICON_QUALI_SELF_EXPLANATORY;
+
+ if (src_data[temp_index] > 0x00)
+ icon_id_obj->icon_identifier = src_data[temp_index];
+ else {
+ dbg("[SAT] SAT PARSER - incorrect icon identifier");
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; /* Send TR */
+ }
+
+ dbg("[SAT] SAT PARSER - icon_qual=%d, iconId=%d", icon_id_obj->icon_qualifer, icon_id_obj->icon_identifier);
+ *consumed_data_len = 4;
+ return TCORE_SAT_SUCCESS;
+}
+
+static enum tcore_sat_result _sat_decode_icon_identifier_list_tlv(unsigned char *tlv_str, int tlv_len,
+ int curr_offset, struct tel_sat_icon_identifier_list *icon_list_obj, int *consumed_data_len)
+{
+ int temp_index, i;
+ int len_value = 0;
+ unsigned char *src_data;
+ gboolean comprehension_req = FALSE;
+
+ if (tlv_str == NULL || consumed_data_len == NULL || icon_list_obj == NULL) {
+ dbg("[SAT] SAT PARSER - tlv_str == NULL || consumed_data_len == NULL || icon_list_obj == NULL");
+ return TCORE_SAT_ERROR_FATAL;
+ }
+
+ if (tlv_len <= (curr_offset + 1) + 1) {
+ dbg("[SAT] SAT PARSER - incorrect length original_command_len=%d", tlv_len);
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ /* tag */
+ temp_index = curr_offset;
+ src_data = &tlv_str[0];
+ if ((src_data[temp_index] & 0x7F) != SATK_ITEM_ICON_IDENTIFIER_LIST_TAG) {
+ dbg("[SAT] SAT PARSER - icon identity tag missing.");
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; /* Send TR */
+ }
+
+ icon_list_obj->is_exist = TRUE;
+ if (src_data[temp_index++] & 0x80)
+ comprehension_req = TRUE;
+
+ len_value = src_data[temp_index++];
+ if (src_data[temp_index++] & 0x01)
+ icon_list_obj->icon_qualifer = ICON_QUALI_NOT_SELF_EXPLANATORY;
+ else
+ icon_list_obj->icon_qualifer = ICON_QUALI_SELF_EXPLANATORY;
+
+ icon_list_obj->icon_cnt = len_value-1;
+ if (icon_list_obj->icon_cnt > SAT_ICON_LIST_MAX_COUNT) {
+ if (comprehension_req == TRUE) {
+ dbg("[SAT] SAT PARSER - list count exceeds maximum allowed count=%d", icon_list_obj->icon_cnt);
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ icon_list_obj->icon_cnt = 0;
+ } else {
+
+ for (i = 0; i < icon_list_obj->icon_cnt; i++) {
+ if (src_data[temp_index] > 0x00) {
+ icon_list_obj->icon_id_list[i] = src_data[temp_index++];
+ } else {
+ dbg("[SAT] SAT PARSER - incorrect icon identifier");
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; /* Send TR */
+ }
+ }
+ }
+
+ *consumed_data_len = 1 + 1 + len_value;
+ dbg("[SAT] SAT PARSER - icon_qual=%d, iconCount=%d", icon_list_obj->icon_qualifer, icon_list_obj->icon_cnt);
+ return TCORE_SAT_SUCCESS;
+}
+
+static enum tcore_sat_result _sat_decode_dtmf_string_tlv(unsigned char *tlv_str, int tlv_len,
+ int curr_offset, struct tel_sat_dtmf_string *dtmf_string_obj, int *consumed_data_len)
+{
+ unsigned char *src_data;
+ int temp_index, len_of_len = 0;
+ int dtmf_len = 0;
+ gboolean comprehension_req = FALSE;
+ char *str_ascii = NULL;
+
+ if (tlv_str == NULL || consumed_data_len == NULL || dtmf_string_obj == NULL) {
+ dbg("[SAT] SAT PARSER - tlv_str == NULL || consumed_data_len == NULL || dtmf_string_obj == NULL");
+ return TCORE_SAT_ERROR_FATAL;
+ }
+
+ src_data = &tlv_str[0];
+
+ if (tlv_len <= (curr_offset + 1)) {
+ dbg("[SAT] SAT PARSER - incorrect length original_command_len=%d", tlv_len);
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ /* Tag */
+ temp_index = curr_offset;
+ if ((src_data[temp_index] & 0x7F) != SATK_DTMF_STRING_TAG) {
+ dbg("[SAT] SAT PARSER - address tag missing");
+ return TCORE_SAT_REQUIRED_VALUE_MISSING;
+ }
+
+ /* comprehensive required */
+ if ((src_data[temp_index++] & 0x80))
+ comprehension_req = TRUE;
+
+ dbg("comprehension_req=[%d]", comprehension_req);
+
+ /* length */
+ len_of_len = _get_length_filed_size(src_data[temp_index]);
+ if (!len_of_len) {
+ err("[SAT] parser: invalid length.");
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ dtmf_len = src_data[temp_index + len_of_len - 1];
+ temp_index += len_of_len; /* temp_index pointing to TON/NPI */
+
+ if ((temp_index + dtmf_len) > tlv_len) {
+ dbg("[SAT] SAT PARSER - incorrect cmd len, expected len = %d, orig_len=%d",
+ (temp_index + dtmf_len), tlv_len);
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ dtmf_string_obj->dtmf_length = 0;
+
+ if (dtmf_len > 0) {
+ str_ascii = tcore_util_convert_bcd2ascii((const char *)&src_data[temp_index], dtmf_len, SAT_DTMF_STRING_LEN_MAX);
+ if (str_ascii) {
+ memcpy(dtmf_string_obj->dtmf_string, str_ascii, strlen(str_ascii));
+ dtmf_string_obj->dtmf_length = strlen(str_ascii);
+ g_free(str_ascii);
+ }
+ }
+
+ if (dtmf_string_obj->dtmf_length == 0) {
+ dbg("[SAT] SAT PARSER - DTMF string length is either 0 or it is too long for the ME to handle.");
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ *consumed_data_len = 1 + len_of_len + dtmf_len;
+ return TCORE_SAT_SUCCESS;
+}
+
+static enum tcore_sat_result _sat_decode_language_tlv(unsigned char *tlv_str, int tlv_len,
+ int curr_offset, enum tel_sim_language_type *language_obj)
+{
+ unsigned char *src_data;
+ int temp_index = 0;
+
+ if (tlv_len <= (curr_offset + 1)) {
+ dbg("[SAT] SAT PARSER - incorrect length original_command_len=%d", tlv_len);
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ src_data = &tlv_str[0];
+ temp_index = curr_offset;
+
+ if ((src_data[temp_index++] & 0x7F) != SATK_LANGUAGE_TAG) {
+ dbg("[SAT] SAT PARSER - Language tag missing.");
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ if (src_data[temp_index++] != SATK_LANGUAGE_LENGTH) {
+ dbg("[SAT] SAT PARSER - incorrect length value.");
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ if ((temp_index + SATK_LANGUAGE_LENGTH) > tlv_len) {
+ dbg("[SAT] SAT PARSER - incorrect cmd len, expected len = %d, orig_len=%d",
+ (temp_index + SATK_LANGUAGE_LENGTH), tlv_len);
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ *language_obj = _sat_decode_language(src_data[temp_index], src_data[temp_index + 1]);
+ dbg("[SAT] SAT PARSER - <in> %c %c, <out> %d", src_data[temp_index], src_data[temp_index + 1], *language_obj);
+ return TCORE_SAT_SUCCESS;
+}
+
+static enum tcore_sat_result _sat_decode_browser_identity_tlv(unsigned char *tlv_str, int tlv_len,
+ int curr_offset, enum browser_identity *browser_id, int *consumed_data_len)
+{
+ unsigned char *src_data;
+ int temp_index = 0;
+
+ if (tlv_str == NULL || browser_id == NULL || consumed_data_len == NULL) {
+ dbg("[SAT] SAT PARSER - tlv_str == NULL || browser_id == NULL ||consumed_data_len == NULL");
+ return TCORE_SAT_ERROR_FATAL;
+ }
+
+ if (tlv_len <= (curr_offset + 1)) {
+ dbg("[SAT] SAT PARSER - incorrect length original_command_len=%d", tlv_len);
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ temp_index = curr_offset;
+ src_data = &tlv_str[0];
+
+ if ((src_data[temp_index++] & 0x7F) != SATK_BROWSER_IDENTITY_TAG) {
+ dbg("[SAT] SAT PARSER - Browser ID tag missing.");
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ if (src_data[temp_index++] != SATK_BROWSER_ID_LENGTH) {
+ dbg("[SAT] SAT PARSER - incorrect length value.");
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ dbg("[SAT] SAT PARSER - : browser ID value:ox%x", src_data[temp_index]);
+
+ switch (src_data[temp_index]) {
+ case 0x00:
+ *browser_id = BROWSER_ID_DEFAULT;
+ break;
+
+ case 0x01:
+ *browser_id = BROWSER_ID_WML;
+ break;
+
+ case 0x02:
+ *browser_id = BROWSER_ID_HTML;
+ break;
+
+ case 0x03:
+ *browser_id = BROWSER_ID_XHTML;
+ break;
+
+ case 0x04:
+ *browser_id = BROWSER_ID_CHTML;
+ break;
+
+ default:
+ *browser_id = BROWSER_ID_RESERVED;
+ break;
+ }
+
+ *consumed_data_len = 3;
+ return TCORE_SAT_SUCCESS;
+}
+
+static enum tcore_sat_result _sat_decode_url_tlv(unsigned char *tlv_str, int tlv_len,
+ int curr_offset, struct tel_sat_url *url, int *consumed_data_len)
+{
+ unsigned char *src_data;
+ int temp_index = curr_offset;
+ int len_of_len = 0, url_len = 0;
+
+ if (tlv_str == NULL || url == NULL || consumed_data_len == NULL) {
+ dbg("[SAT] SAT PARSER - tlv_str == NULL || url == NULL ||consumed_data_len == NULL");
+ return TCORE_SAT_ERROR_FATAL;
+ }
+
+ src_data = &tlv_str[0];
+ if (tlv_len <= (curr_offset + 1)) {
+ dbg("[SAT] SAT PARSER - incorrect length original_command_len=%d", tlv_len);
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ if ((src_data[temp_index++] & 0x7F) != SATK_URL_TAG) {
+ dbg("[SAT] SAT PARSER - Browser URL tag missing.");
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; /* Send TR */
+ }
+
+ /* length */
+ len_of_len = _get_length_filed_size(src_data[temp_index]);
+ if (!len_of_len) {
+ err("[SAT] parser: invalid length.");
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ url_len = src_data[temp_index + len_of_len-1];
+ url->url_length = url_len;
+ temp_index += len_of_len; /* temp_index pointing to url. */
+ dbg("URL length (%d)", url_len);
+
+ if (url_len < 0) {
+ dbg("[SAT] URL is null");
+ *consumed_data_len = 1 + len_of_len + url_len;
+ return TCORE_SAT_SUCCESS;
+ }
+
+ if (url_len > SAT_URL_LEN_MAX) {
+ dbg("[SAT] URL length is wrong");
+ *consumed_data_len = 1 + len_of_len + url_len;
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ memcpy(url->url, &src_data[temp_index], url_len);
+ dbg("[SAT] url(%s)", url->url);
+ *consumed_data_len = 1 + len_of_len + url_len;
+
+ return TCORE_SAT_SUCCESS;
+}
+
+static enum tcore_sat_result _sat_decode_bearer_tlv(unsigned char *tlv_str, int tlv_len,
+ int curr_offset, struct tel_sat_bearer_list *satk_bearer, int *consumed_data_len)
+{
+ unsigned char *src_data;
+ int temp_index, len_of_len = 0;
+ int list_len = 0, list_idx = 0;
+
+ if (tlv_str == NULL || consumed_data_len == NULL || satk_bearer == NULL) {
+ dbg("[SAT] SAT PARSER - tlv_str == NULL || consumed_data_len == NULL || satk_bearer == NULL");
+ return TCORE_SAT_ERROR_FATAL;
+ }
+
+ if (tlv_len <= (curr_offset + 1)) {
+ dbg("[SAT] SAT PARSER - incorrect length original_command_len=%d",
+ tlv_len);
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ src_data = &tlv_str[0];
+ temp_index = curr_offset;
+
+ if ((src_data[temp_index++] & 0x7F) != SATK_BEARER_TAG) {
+ dbg("[SAT] SAT PARSER - _sat_decode_bearer_tlv: alphaID TAG missing");
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ /* length */
+ len_of_len = _get_length_filed_size(src_data[temp_index]);
+ if (!len_of_len) {
+ err("[SAT] parser: invalid length.");
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ satk_bearer->count = src_data[temp_index + len_of_len - 1];
+ list_len = satk_bearer->count;
+ temp_index += len_of_len;
+
+ if ((temp_index + list_len) > tlv_len) {
+ dbg("[SAT] SAT PARSER - incorrect cmd len, expected len = %d, orig_len=%d",
+ (temp_index + list_len), tlv_len);
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ if (satk_bearer->count > 0) {
+ if (list_len > SAT_BEARER_LIST_MAX_COUNT)
+ list_len = SAT_BEARER_LIST_MAX_COUNT;
+
+ for (list_idx = 0; list_idx < list_len; list_idx++) {
+ switch (src_data[temp_index]) {
+ case 0x00:
+ satk_bearer->bear[list_idx] = BEARER_LIST_SMS;
+ break;
+
+ case 0x01:
+ satk_bearer->bear[list_idx] = BEARER_LIST_CSD;
+ break;
+
+ case 0x02:
+ satk_bearer->bear[list_idx] = BEARER_LIST_USSD;
+ break;
+
+ case 0x03:
+ satk_bearer->bear[list_idx] = BEARER_LIST_GPRS;
+ break;
+
+ default:
+ satk_bearer->bear[list_idx] = BEARER_LIST_RESERVED;
+ break;
+ }
+
+ dbg("[SAT] SAT PARSER - bearer[%d]=0x%x", list_idx, satk_bearer->bear[list_idx]);
+ temp_index++;
+ }
+ } else
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+
+ *consumed_data_len = 1 + len_of_len + list_len;
+ return TCORE_SAT_SUCCESS;
+}
+
+static enum tcore_sat_result _sat_decode_provisioning_file_ref_tlv(unsigned char *tlv_str, int tlv_len,
+ int curr_offset, struct tel_sat_provisioning_file_ref *prf, int *data_len_consumed)
+{
+ unsigned char *src_data;
+ int temp_index = curr_offset;
+ int len_of_len = 0, prf_len = 0;
+
+ if (tlv_str == NULL || prf == NULL || data_len_consumed == NULL) {
+ dbg("[SAT] SAT PARSER - tlv_str == NULL || prf == NULL ||data_len_consumed == NULL");
+ return TCORE_SAT_ERROR_FATAL;
+ }
+
+ src_data = &tlv_str[0];
+ if (tlv_len <= (curr_offset + 1)) {
+ dbg("[SAT] SAT PARSER - incorrect length original_command_len=%d", tlv_len);
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ if ((src_data[temp_index++] & 0x7F) != SATK_PROVISIONING_REF_FILE_TAG) {
+ dbg("[SAT] SAT PARSER - PRF tag missing.");
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; /* Send TR */
+ }
+
+ /* length */
+ len_of_len = _get_length_filed_size(src_data[temp_index]);
+ if (!len_of_len) {
+ err("[SAT] parser: invalid length.");
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ prf_len = src_data[temp_index + len_of_len - 1];
+ prf->file_path_length = prf_len;
+ temp_index += len_of_len; /* temp_index pointing to prf. */
+
+ if (prf_len > 0) {
+ if (prf_len > SAT_PROVISIONING_FILE_PATH_LEN_MAX)
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ else
+ memcpy(prf->file_path, &src_data[temp_index], prf_len);
+ } else {
+ dbg("[SAT] SAT PARSER - NULL string for PRF");
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ *data_len_consumed = 1 + len_of_len + prf_len;
+ return TCORE_SAT_SUCCESS;
+}
+
+static enum tcore_sat_result _sat_decode_bearer_description_tlv(unsigned char *tlv_str, int tlv_len,
+ int curr_offset, struct tel_sat_bearer_description *bearer_desc_obj, int *consumed_data_len)
+{
+ int temp_index, length = 0;
+ unsigned char *src_data;
+
+ if (tlv_len <= (curr_offset + 1) + 1) {
+ dbg("[SAT] SAT PARSER - incorrect length original_command_len=%d", tlv_len);
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ temp_index = curr_offset;
+ src_data = &tlv_str[0];
+ while (1) {
+ if (temp_index >= tlv_len) {
+ dbg("bearer desc cannot find. UICC Server mode");
+ *consumed_data_len = 0;
+ return TCORE_SAT_SUCCESS;
+ }
+
+ if ((src_data[temp_index] & 0x7F) == SATK_BEARER_DISCRIPTION_TAG) {
+ dbg("find bearer description tag temp_index(%d)", temp_index);
+ temp_index++;
+ break;
+ }
+
+ temp_index++;
+ }
+
+ /* length */
+ length = src_data[temp_index++];
+ dbg("bearer description length (%d)", length);
+
+ /* bearer parameter */
+ switch (src_data[temp_index++]) {
+ case BEARER_CSD:
+ bearer_desc_obj->bearer_type = BEARER_CSD;
+ bearer_desc_obj->bearer_parameter.cs_bearer_param.data_rate = src_data[temp_index++];
+ bearer_desc_obj->bearer_parameter.cs_bearer_param.service_type = src_data[temp_index++];
+ bearer_desc_obj->bearer_parameter.cs_bearer_param.connection_element_type = src_data[temp_index++];
+ break;
+
+ case BEARER_GPRS:
+ bearer_desc_obj->bearer_type = BEARER_GPRS;
+ bearer_desc_obj->bearer_parameter.ps_bearer_param.precedence_class = src_data[temp_index++];
+ bearer_desc_obj->bearer_parameter.ps_bearer_param.delay_class = src_data[temp_index++];
+ bearer_desc_obj->bearer_parameter.ps_bearer_param.reliability_class = src_data[temp_index++];
+ bearer_desc_obj->bearer_parameter.ps_bearer_param.peak_throughput_class = src_data[temp_index++];
+ bearer_desc_obj->bearer_parameter.ps_bearer_param.mean_throughput_class = src_data[temp_index++];
+ bearer_desc_obj->bearer_parameter.ps_bearer_param.pdp_type = BIP_GPRS_PDP_TYPE_RESERVED;
+ if (src_data[temp_index] == BIP_GPRS_PDP_TYPE_IP)
+ bearer_desc_obj->bearer_parameter.ps_bearer_param.pdp_type = BIP_GPRS_PDP_TYPE_IP;
+ break;
+
+ case BEARER_DEFAULT_BEARER_FROM_TRANSPORT_LAYER:
+ bearer_desc_obj->bearer_type = BEARER_DEFAULT_BEARER_FROM_TRANSPORT_LAYER;
+ break;
+
+ case BEARER_LOCAL_LINK_TECHNOLOGY_INDEPENDENT:
+ bearer_desc_obj->bearer_type = BEARER_DEFAULT_BEARER_FROM_TRANSPORT_LAYER;
+ break;
+
+ default:
+ bearer_desc_obj->bearer_type = BEARER_RESERVED;
+ dbg("bearer type not supported");
+ return TCORE_SAT_BEYOND_ME_CAPABILITY;
+ }
+
+ *consumed_data_len = 1 + 1 + length;
+ return TCORE_SAT_SUCCESS;
+}
+
+static enum tcore_sat_result _sat_decode_channel_data_tlv(unsigned char *tlv_str, int tlv_len,
+ int curr_offset, struct tel_sat_channel_data *channel_data_obj, int *consumed_data_len)
+{
+ int temp_index = 0;
+ int len_of_len = 0, channel_data_len = 0;
+ unsigned char *src_data;
+
+ if (tlv_str == NULL || consumed_data_len == NULL || channel_data_obj == NULL) {
+ dbg("[SAT] SAT PARSER - tlv_str == NULL || consumed_data_len == NULL || channel_data_obj == NULL");
+ return TCORE_SAT_ERROR_FATAL;
+ }
+
+ if (tlv_len <= (curr_offset + 1)) {
+ dbg("[SAT] SAT PARSER - incorrect length original_command_len=%d", tlv_len);
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ /* tag */
+ temp_index = curr_offset;
+ src_data = &tlv_str[0];
+ if ((src_data[temp_index++] & 0x7F) != SATK_CHANNEL_DATA_TAG) {
+ dbg("[SAT] SAT PARSER - tag not found.=%d", src_data[temp_index]);
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ /* length */
+ len_of_len = _get_length_filed_size(src_data[temp_index]);
+ if (!len_of_len) {
+ err("[SAT] parser: invalid length.");
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ channel_data_len = src_data[temp_index + len_of_len-1];
+ dbg("[SAT] parser: channel_data_len=%d", channel_data_len);
+ temp_index += len_of_len;
+
+ if ((temp_index + channel_data_len) > tlv_len) {
+ dbg("[SAT] SAT PARSER - incorrect cmd len, expected len = %d, orig_len=%d", (temp_index + channel_data_len), tlv_len);
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ /* data */
+ channel_data_obj->data_string_len = channel_data_len;
+ memcpy(channel_data_obj->data_string, &src_data[temp_index], channel_data_len);
+
+ *consumed_data_len = 1 + len_of_len + channel_data_len;
+ return TCORE_SAT_SUCCESS;
+}
+
+static enum tcore_sat_result _sat_decode_channel_data_length_tlv(unsigned char *tlv_str, int tlv_len,
+ int curr_offset, struct tel_sat_channel_data_len *data_len_obj, int *consumed_data_len)
+{
+ int temp_index;
+ unsigned char *src_data;
+
+ if (tlv_str == NULL || consumed_data_len == NULL || data_len_obj == NULL) {
+ dbg("[SAT] SAT PARSER - tlv_str == NULL || consumed_data_len == NULL || data_len_obj == NULL");
+ return TCORE_SAT_ERROR_FATAL;
+ }
+
+ /* tag */
+ temp_index = curr_offset;
+ src_data = &tlv_str[0];
+ if ((src_data[temp_index++] & 0x7F) != SATK_CHANNEL_DATA_LEN_TAG) {
+ dbg("[SAT] SAT PARSER - channel data tag missing.");
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; /* Send TR */
+ }
+
+ /* length */
+ if (src_data[temp_index++] != SATK_CHANNEL_DATA_LENGTH_VALUE_LENGTH) {
+ dbg("[SAT] SAT PARSER - incorrect length");
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; /* Send TR */
+ }
+
+ /* data */
+ data_len_obj->data_len = src_data[temp_index];
+
+ *consumed_data_len = 3;
+ return TCORE_SAT_SUCCESS;
+}
+
+static enum tcore_sat_result _sat_decode_buffer_size_tlv(unsigned char *tlv_str, int tlv_len,
+ int curr_offset, struct tel_sat_buffer_size *buffer_size_obj, int *consumed_data_len)
+{
+ int temp_index;
+ unsigned char *src_data;
+
+ if (tlv_str == NULL || consumed_data_len == NULL || buffer_size_obj == NULL) {
+ dbg("[SAT] SAT PARSER - tlv_str == NULL || consumed_data_len == NULL || buffer_size_obj == NULL");
+ return TCORE_SAT_ERROR_FATAL;
+ }
+
+ if (tlv_len <= (curr_offset + 1) + SATK_BUFFER_SIZE_LENGTH) {
+ dbg("[SAT] SAT PARSER - incorrect length original_command_len=%d", tlv_len);
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ /* tag */
+ temp_index = curr_offset;
+ src_data = &tlv_str[0];
+ if ((src_data[temp_index++] & 0x7F) != SATK_BUFFER_SIZE_TAG) {
+ dbg("[SAT] SAT PARSER - buffer size tag missing.");
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; /* Send TR */
+ }
+
+ /* length */
+ if (src_data[temp_index++] != SATK_BUFFER_SIZE_LENGTH) {
+ dbg("[SAT] SAT PARSER - incorrect length");
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; /* Send TR */
+ }
+
+ buffer_size_obj->size[0] = src_data[temp_index++];
+ buffer_size_obj->size[1] = src_data[temp_index];
+
+ *consumed_data_len = 4;
+ dbg("[SAT] SAT PARSER - buffer size = 0x%x%x", buffer_size_obj->size[0], buffer_size_obj->size[1]);
+ return TCORE_SAT_SUCCESS;
+}
+
+static enum tcore_sat_result _sat_decode_other_address_tlv(unsigned char *tlv_str, int tlv_len,
+ int curr_offset, struct tel_sat_other_address *other_address_obj, int *consumed_data_len)
+{
+ gchar *address = NULL;
+ int temp_index, address_len;
+ unsigned char *src_data;
+
+ if (tlv_str == NULL || consumed_data_len == NULL || other_address_obj == NULL) {
+ dbg("[SAT] SAT PARSER - tlv_str == NULL || consumed_data_len == NULL || other_address_obj == NULL");
+ return TCORE_SAT_ERROR_FATAL;
+ }
+
+ if (tlv_len <= (curr_offset + 1)) {
+ dbg("[SAT] SAT PARSER - incorrect length original_command_len=%d", tlv_len);
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ /* tag */
+ temp_index = curr_offset;
+ src_data = &tlv_str[0];
+ if ((src_data[temp_index++] & 0x7F) != SATK_OTHER_ADDRESS_TAG) {
+ dbg("[SAT] SAT PARSER - other address tag missing.");
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; /* Send TR */
+ }
+
+ /* length */
+ address_len = src_data[temp_index++];
+ if ((temp_index + address_len) > tlv_len) {
+ dbg("[SAT] SAT PARSER - incorrect cmd len, expected len = %d, orig_len=%d", (temp_index + address_len), tlv_len);
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ if (address_len-1 > SAT_OTHER_ADDR_LEN_MAX) {
+ dbg("[SAT] SAT PARSER - address is longer than capability");
+ return TCORE_SAT_BEYOND_ME_CAPABILITY;
+ }
+
+ /* other address type */
+ switch (src_data[temp_index++]) {
+ case ADDR_TYPE_IPv4: {
+ other_address_obj->address_type = ADDR_TYPE_IPv4;
+ address = g_strdup_printf("%d.%d.%d.%d", src_data[temp_index], src_data[temp_index + 1], src_data[temp_index + 2], src_data[temp_index + 3]);
+ }
+ break;
+
+ case ADDR_TYPE_IPv6: {
+ other_address_obj->address_type = ADDR_TYPE_IPv6;
+ address = g_strdup_printf("%x%x:%x%x:%x%x:%x%x:%x%x:%x%x:%x%x:%x%x:",
+ src_data[temp_index], src_data[temp_index + 1], src_data[temp_index + 2], src_data[temp_index + 3],
+ src_data[temp_index + 4], src_data[temp_index + 5], src_data[temp_index + 6], src_data[temp_index + 7],
+ src_data[temp_index + 8], src_data[temp_index + 9], src_data[temp_index + 10], src_data[temp_index + 11],
+ src_data[temp_index + 12], src_data[temp_index + 13], src_data[temp_index + 14], src_data[temp_index + 15]);
+ }
+ break;
+
+ default: {
+ other_address_obj->address_type = ADDR_RESERVED;
+ address = g_strdup("");
+ }
+ break;
+ } /* end of switch */
+
+ /* address */
+ if (address) {
+ memcpy(other_address_obj->address, address, strlen(address));
+ other_address_obj->address_len = strlen(address);
+
+ g_free(address);
+ dbg("destination address(%s)", other_address_obj->address);
+ }
+
+ *consumed_data_len = 2 + address_len;
+ return TCORE_SAT_SUCCESS;
+}
+
+static enum tcore_sat_result _sat_decode_uicc_terminal_interface_tlv(unsigned char *tlv_str,
+ int tlv_len, int curr_offset, struct tel_sat_uicc_terminal_interface_transport_level *level_obj,
+ int *consumed_data_len)
+{
+ int temp_index;
+ unsigned char *src_data;
+
+ if (tlv_str == NULL || consumed_data_len == NULL || level_obj == NULL) {
+ dbg("[SAT] SAT PARSER - tlv_str == NULL || consumed_data_len == NULL || level_obj == NULL");
+ return TCORE_SAT_ERROR_FATAL;
+ }
+
+ if (tlv_len <= (curr_offset + 1) + SATK_UICC_ME_TRANS_INTERFACE_LEVEL_LENGTH) {
+ dbg("[SAT] SAT PARSER - incorrect length original_command_len=%d", tlv_len);
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ /* tag */
+ temp_index = curr_offset;
+ src_data = &tlv_str[0];
+ if ((src_data[temp_index++] & 0x7F) != SATK_USIM_ME_INTERFACE_TRANSPORT_LEVEL_TAG) {
+ dbg("[SAT] SAT PARSER - UICC/TERMINAL Interface transport level tag missing.");
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; /* Send TR */
+ }
+
+ /* length */
+ if (src_data[temp_index++] != SATK_UICC_ME_TRANS_INTERFACE_LEVEL_LENGTH) {
+ dbg("[SAT] SAT PARSER - incorrect length");
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; /* Send TR */
+ }
+
+ level_obj->protocol_type = src_data[temp_index++];
+ level_obj->port_number = src_data[temp_index++] << 8;
+ level_obj->port_number |= src_data[temp_index];
+
+ *consumed_data_len = 2 + SATK_UICC_ME_TRANS_INTERFACE_LEVEL_LENGTH;
+ dbg("[SAT] SAT PARSER - protocol type(%d) , port number(%d)", level_obj->protocol_type, level_obj->port_number);
+ return TCORE_SAT_SUCCESS;
+}
+
+static enum tcore_sat_result _sat_decode_remote_entity_address_tlv(unsigned char *tlv_str,
+ int tlv_len, int curr_offset, struct tel_sat_remote_entity_address *remote_address_obj,
+ int *consumed_data_len)
+{
+ int temp_index = 0;
+ int len_of_len = 0, remote_data_len = 0;
+ unsigned char *src_data;
+
+ if (tlv_str == NULL || consumed_data_len == NULL || remote_address_obj == NULL) {
+ dbg("[SAT] SAT PARSER - tlv_str == NULL || consumed_data_len == NULL || remote_address_obj == NULL");
+ return TCORE_SAT_ERROR_FATAL;
+ }
+
+ if (tlv_len <= (curr_offset + 1)) {
+ dbg("[SAT] SAT PARSER - incorrect length original_command_len=%d", tlv_len);
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ /* tag */
+ temp_index = curr_offset;
+ src_data = &tlv_str[0];
+ if ((src_data[temp_index] & 0x7F) != SATK_REMOTE_ENTITY_ADDRESS_TAG) {
+ dbg("[SAT] SAT PARSER - tag not found.=%d", src_data[temp_index]);
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ /* length */
+ len_of_len = _get_length_filed_size(src_data[temp_index]);
+ if (!len_of_len) {
+ err("[SAT] parser: invalid length.");
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ remote_data_len = src_data[temp_index + len_of_len-1];
+ dbg("[SAT] parser: remote_data_len=%d", remote_data_len);
+ temp_index += len_of_len;
+
+ /* data */
+ switch (src_data[temp_index++]) {
+ case REMOTE_ENTITY_ADDR_CODING_TYPE_IEEE802_48BIT:
+ remote_address_obj->coding_type = REMOTE_ENTITY_ADDR_CODING_TYPE_IEEE802_48BIT;
+ break;
+
+ case REMOTE_ENTITY_ADDR_CODING_TYPE_IRDA_32BIT:
+ remote_address_obj->coding_type = REMOTE_ENTITY_ADDR_CODING_TYPE_IRDA_32BIT;
+ break;
+
+ default:
+ remote_address_obj->coding_type = REMOTE_ENTITY_ADDR_CODING_TYPE_RESERVED;
+ break;
+ }
+
+ remote_address_obj->length = remote_data_len - 1;
+ memcpy(remote_address_obj->remote_entity_address, &src_data[temp_index], remote_address_obj->length);
+
+ *consumed_data_len = 1 + len_of_len + remote_data_len;
+ return TCORE_SAT_SUCCESS;
+}
+
+static enum tcore_sat_result _sat_decode_network_access_name_tlv(unsigned char *tlv_str, int tlv_len,
+ int curr_offset, struct tel_sat_network_access_name *access_name_obj, int *consumed_data_len)
+{
+ int temp_index, idx, name_idx, name_length;
+ unsigned char *src_data;
+
+ if (tlv_str == NULL || consumed_data_len == NULL || access_name_obj == NULL) {
+ dbg("[SAT] SAT PARSER - tlv_str == NULL || consumed_data_len == NULL || access_name_obj == NULL");
+ return TCORE_SAT_ERROR_FATAL;
+ }
+
+ if (tlv_len <= (curr_offset + 1)) {
+ dbg("[SAT] SAT PARSER - incorrect length original_command_len=%d", tlv_len);
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ /* tag */
+ temp_index = curr_offset;
+ src_data = &tlv_str[0];
+ if ((src_data[temp_index++] & 0x7F) != SATK_NETWORK_ACCESS_TAG) {
+ dbg("[SAT] SAT PARSER - network access name tag missing.");
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; /* Send TR */
+ }
+
+ /* length */
+ name_length = src_data[temp_index++];
+ if ((temp_index + name_length) > tlv_len) {
+ dbg("[SAT] SAT PARSER - incorrect cmd len, expected len = %d, orig_len=%d",
+ (temp_index + name_length), tlv_len);
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ access_name_obj->length = name_length;
+ if (access_name_obj->length > SAT_NET_ACC_NAM_LEN_MAX) {
+ dbg("[SAT] SAT PARSER - network access name is longer than capability");
+ return TCORE_SAT_BEYOND_ME_CAPABILITY;
+ }
+
+ name_idx = 0;
+ for (idx = 0; idx < access_name_obj->length; idx++) {
+ dbg("data (%c) Bool(%d)", src_data[temp_index], g_ascii_isalpha(src_data[temp_index]));
+
+ if (g_ascii_isalpha(src_data[temp_index])) {
+ access_name_obj->network_access_name[name_idx] = src_data[temp_index];
+ name_idx++;
+ } else {
+ if (src_data[temp_index] == 0x02) {/* 02 convert to "." */
+ access_name_obj->network_access_name[name_idx] = '.';
+ name_idx++;
+ }
+ }
+
+ temp_index++;
+ }
+
+ /* network access name */
+ dbg("network access name(%s)", access_name_obj->network_access_name);
+
+ *consumed_data_len = 2 + name_length;
+ return TCORE_SAT_SUCCESS;
+}
+
+static enum tcore_sat_result _sat_decode_text_attribute_tlv(unsigned char *tlv_str, int tlv_len,
+ int curr_offset, struct tel_sat_text_attribute *text_attribute_obj, int *consumed_data_len)
+{
+ int temp_index, length;
+ unsigned char *src_data;
+
+ if (tlv_str == NULL || consumed_data_len == NULL || text_attribute_obj == NULL) {
+ dbg("[SAT] SAT PARSER - tlv_str == NULL || consumed_data_len == NULL || text_attribute_obj == NULL");
+ return TCORE_SAT_ERROR_FATAL;
+ }
+
+ if (tlv_len <= (curr_offset + 1)) {
+ dbg("[SAT] SAT PARSER - incorrect length original_command_len=%d", tlv_len);
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ /* tag */
+ temp_index = curr_offset;
+ src_data = &tlv_str[0];
+ if ((src_data[temp_index++] & 0x7F) != SATK_TEXT_ATTRIBUTE_TAG) {
+ dbg("[SAT] SAT PARSER - text attribute tag is missing");
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; /* Send TR */
+ }
+
+ /* length */
+ length = src_data[temp_index++];
+ if ((temp_index + length) > tlv_len) {
+ dbg("[SAT] SAT PARSER - incorrect cmd len, expected len = %d, orig_len=%d", (temp_index + length), tlv_len);
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ /* attribute data */
+ text_attribute_obj->b_txt_attr = TRUE;
+ memcpy(text_attribute_obj->text_formatting, &src_data[temp_index], length);
+
+ *consumed_data_len = 2 + length;
+ return TCORE_SAT_SUCCESS;
+}
+
+/*
+ * decode proactive cmd
+ */
+/*
+ * 6.4.1 DISPLAY TEXT
+ */
+static enum tcore_sat_result _sat_decode_display_text(unsigned char *o_cmd_data, int o_length,
+ int curr_offset, struct tcore_sat_proactive_command *sat_cmd_ind_data)
+{
+ int temp_index = 0;
+ int tlv_length = 0, remain_len = 0, expected_len = 0;
+ int data_len_consumed = 0;
+ unsigned char dev_id[4];
+ unsigned char *cmd_data = NULL;
+ enum tcore_sat_result rv = TCORE_SAT_SUCCESS;
+
+ if (o_cmd_data == NULL) {
+ dbg("[SAT] SAT PARSER - o_cmd_data == NULL");
+ return TCORE_SAT_ERROR_FATAL;
+ }
+
+ cmd_data = &o_cmd_data[0];
+ tlv_length = cmd_data[curr_offset-1];
+ temp_index = curr_offset + 2;
+ sat_cmd_ind_data->data.display_text.command_detail.cmd_num = cmd_data[temp_index++];
+ sat_cmd_ind_data->data.display_text.command_detail.cmd_type = cmd_data[temp_index++];
+
+ /* decode command qualifier */
+ if (cmd_data[temp_index] & 0x01) {
+ sat_cmd_ind_data->data.display_text.command_detail.cmd_qualifier.display_text.text_priority =
+ TEXT_PRIORITY_HIGH;
+ dbg("[SAT] SAT PARSER - msg_prio=TAPI_SAT_MSG_PRIORITY_HIGH.");
+ } else {
+ sat_cmd_ind_data->data.display_text.command_detail.cmd_qualifier.display_text.text_priority =
+ TEXT_PRIORITY_NORMAL;
+ dbg("[SAT] SAT PARSER - : msg_prio=TAPI_SAT_MSG_PRIORITY_NORMAL.");
+ }
+
+ if (cmd_data[temp_index] & 0x80) {
+ sat_cmd_ind_data->data.display_text.command_detail.cmd_qualifier.display_text.text_clear_type =
+ TEXT_WAIT_FOR_USER_TO_CLEAR_MSG;
+ dbg("[SAT] SAT PARSER - : msgClear=TAPI_SAT_WAIT_FOR_USER_TO_CLEAR_MSG.");
+ } else {
+ sat_cmd_ind_data->data.display_text.command_detail.cmd_qualifier.display_text.text_clear_type =
+ TEXT_AUTO_CLEAR_MSG_AFTER_A_DELAY;
+ dbg("[SAT] SAT PARSER - msgClear=TAPI_SAT_AUTO_CLEAR_MSG_AFTER_A_DELAY.");
+ }
+
+ temp_index++;
+ memcpy(dev_id, &cmd_data[temp_index], 4);
+ rv = _sat_decode_device_identities_tlv(dev_id, &sat_cmd_ind_data->data.display_text.device_id);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv;
+
+ temp_index += 4; /* device identities consumes 4 bytes. */
+
+ remain_len = o_length-temp_index;
+ expected_len = tlv_length-5-4;
+ if (remain_len != expected_len) {
+ dbg("[SAT] SAT PARSER - : mismatch!! remain_len=%d, expected_len=%d", remain_len, expected_len);
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ rv = _sat_decode_text_tlv(o_cmd_data, o_length, temp_index,
+ &sat_cmd_ind_data->data.display_text.text,
+ &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv;
+
+ if (sat_cmd_ind_data->data.display_text.text.string_length <= 0) {
+ err("[SAT] SAT PARSER - :string length is 0");
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ dbg("[SAT] SAT PARSER text(%s)", sat_cmd_ind_data->data.display_text.text.string);
+ dbg("[SAT] SAT PARSER o_len(%d) temp_index(%d) data_len_consumed(%d)",
+ o_length , temp_index, data_len_consumed);
+
+ if (o_length-temp_index < data_len_consumed) {
+ dbg("[SAT] SAT PARSER - :wrong text TLV.");
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ if (o_length-temp_index == data_len_consumed) {
+ dbg("[SAT] SAT PARSER - :no more TLVs to decode.");
+ return TCORE_SAT_SUCCESS;
+ }
+
+ temp_index += data_len_consumed; /* temp_index pointing to the Tag of next TLV */
+
+ /* icon identifier */
+ if ((cmd_data[temp_index] & 0x7F) == SATK_ICON_IDENTIFIER_TAG) {
+ rv = _sat_decode_icon_identifier_tlv(o_cmd_data, o_length, temp_index,
+ &sat_cmd_ind_data->data.display_text.icon_id,
+ &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv; /* Send TR */
+
+ if (o_length-temp_index == data_len_consumed) {
+ dbg("[SAT] SAT PARSER - :no more TLVs to decode.");
+ return TCORE_SAT_SUCCESS;
+ }
+
+ temp_index += data_len_consumed; /* temp_index pointing to the Tag of next TLV */
+ }
+
+ /* immediate response */
+ sat_cmd_ind_data->data.display_text.immediate_response_requested = FALSE;
+ if ((cmd_data[temp_index] & 0x7F) == SATK_IMMEDIATE_RESPONSE_TAG) {
+ data_len_consumed = 2;
+ dbg("[SAT] SAT PARSER - :immediate response required.");
+ sat_cmd_ind_data->data.display_text.immediate_response_requested = TRUE;
+ if (o_length-temp_index == data_len_consumed) {
+ dbg("[SAT] SAT PARSER - :no more TLVs to decode.");
+ return TCORE_SAT_SUCCESS;
+ }
+
+ temp_index += data_len_consumed; /* temp_index pointing to the Tag of next TLV */
+ }
+
+ /* time duration - optional */
+ if ((cmd_data[temp_index] & 0x7F) == SATK_DURATION_TAG) {
+ rv = _sat_decode_duration_tlv(o_cmd_data, o_length, temp_index,
+ &sat_cmd_ind_data->data.display_text.duration,
+ &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv; /* Send TR */
+
+ if (o_length-temp_index == data_len_consumed) {
+ dbg("[SAT] SAT PARSER - :no more TLVs to decode.");
+ return TCORE_SAT_SUCCESS;
+ }
+
+ temp_index += data_len_consumed; /* temp_index pointing to the Tag of next TLV */
+ }
+
+ /* text attribute - optional */
+ if ((cmd_data[temp_index] & 0x7F) == SATK_TEXT_ATTRIBUTE_TAG) {
+ rv = _sat_decode_text_attribute_tlv(o_cmd_data, o_length, temp_index,
+ &sat_cmd_ind_data->data.display_text.text_attribute,
+ &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv; /* Send TR */
+
+ if (o_length-temp_index == data_len_consumed) {
+ dbg("[SAT] SAT PARSER - :no more TLVs to decode.");
+ return TCORE_SAT_SUCCESS;
+ }
+
+ temp_index += data_len_consumed; /* temp_index pointing to the Tag of next TLV */
+ }
+
+ if (o_length > temp_index) {
+ dbg("[SAT] SAT PARSER - : wrong text TLV, remaining data is found!!");
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ dbg("[SAT] SAT PARSER - :decoding done!.");
+ return TCORE_SAT_SUCCESS;
+}
+
+/*
+ * 6.4.2 GET INKEY
+ */
+static enum tcore_sat_result _sat_decode_get_inkey(unsigned char *o_cmd_data, int o_length,
+ int curr_offset, struct tcore_sat_proactive_command *sat_cmd_ind_data)
+{
+ int temp_index = 0;
+ int tlv_length = 0, remain_len = 0, expected_len = 0;
+ int data_len_consumed = 0;
+ unsigned char dev_id[4];
+ unsigned char *cmd_data = NULL;
+ enum tcore_sat_result rv = TCORE_SAT_SUCCESS;
+
+ if (o_cmd_data == NULL) {
+ dbg("[SAT] SAT PARSER - o_cmd_data == NULL");
+ return TCORE_SAT_ERROR_FATAL;
+ }
+
+ cmd_data = &o_cmd_data[0];
+ tlv_length = cmd_data[curr_offset-1];
+ temp_index = curr_offset + 2;
+ sat_cmd_ind_data->data.get_inkey.command_detail.cmd_num = cmd_data[temp_index++];
+ sat_cmd_ind_data->data.get_inkey.command_detail.cmd_type = cmd_data[temp_index++];
+
+ /* decode command qualifier */
+ if (cmd_data[temp_index] & 0x01) {
+ sat_cmd_ind_data->data.get_inkey.command_detail.cmd_qualifier.get_inkey.alphabet_set = TRUE;
+ dbg("[SAT] SAT PARSER - Alphabet set");
+ }
+
+ if (cmd_data[temp_index] & 0x02) {
+ sat_cmd_ind_data->data.get_inkey.command_detail.cmd_qualifier.get_inkey.alphabet_type = INPUT_ALPHABET_TYPE_UCS2;
+ dbg("[SAT] SAT PARSER - INPUT_ALPHABET_TYPE_UCS2");
+ } else {
+ sat_cmd_ind_data->data.get_inkey.command_detail.cmd_qualifier.get_inkey.alphabet_type = INPUT_ALPHABET_TYPE_SMS_DEFAULT;
+ dbg("[SAT] SAT PARSER - INPUT_ALPHABET_TYPE_SMS_DEFAULT");
+ }
+
+ if (cmd_data[temp_index] & 0x04) {
+ sat_cmd_ind_data->data.get_inkey.command_detail.cmd_qualifier.get_inkey.inkey_type = INKEY_TYPE_YES_NO_REQUESTED;
+ dbg("[SAT] SAT PARSER - INKEY_TYPE_YES_NO_REQUESTED");
+ } else {
+ sat_cmd_ind_data->data.get_inkey.command_detail.cmd_qualifier.get_inkey.inkey_type = INKEY_TYPE_CHARACTER_SET_ENABLED;
+ dbg("[SAT] SAT PARSER - INKEY_TYPE_YES_NO_REQUESTED");
+ }
+
+ if (cmd_data[temp_index] & 0x08) {
+ sat_cmd_ind_data->data.get_inkey.command_detail.cmd_qualifier.get_inkey.immediate_rsp_required = TRUE;
+ dbg("[SAT] SAT PARSER - immediate response requested");
+ }
+
+ if (cmd_data[temp_index] & 0x80) {
+ sat_cmd_ind_data->data.get_inkey.command_detail.cmd_qualifier.get_inkey.help_info = TRUE;
+ dbg("[SAT] SAT PARSER - Help info");
+ }
+
+ /* device identities */
+ temp_index++;
+ memcpy(dev_id, &cmd_data[temp_index], 4);
+ rv = _sat_decode_device_identities_tlv(dev_id, &sat_cmd_ind_data->data.get_inkey.device_id);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv;
+
+ /* text */
+ temp_index += 4;
+
+ remain_len = o_length-temp_index;
+ expected_len = tlv_length-5-4;
+ if (remain_len != expected_len) {
+ dbg("[SAT] SAT PARSER - : mismatch!! remain_len=%d, expected_len=%d", remain_len, expected_len);
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ rv = _sat_decode_text_tlv(o_cmd_data, o_length, temp_index,
+ &sat_cmd_ind_data->data.get_inkey.text,
+ &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv;
+
+ if (sat_cmd_ind_data->data.get_inkey.text.string_length <= 0) {
+ err("[SAT] SAT PARSER - :string length is 0");
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ dbg("[SAT] SAT PARSER text(%s)", sat_cmd_ind_data->data.get_inkey.text.string);
+ dbg("[SAT] SAT PARSER o_len(%d) temp_index(%d) data_len_consumed(%d)",
+ o_length , temp_index, data_len_consumed);
+
+ if (o_length-temp_index < data_len_consumed) {
+ dbg("[SAT] SAT PARSER - :wrong text TLV.");
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ if (o_length-temp_index == data_len_consumed) {
+ dbg("[SAT] SAT PARSER - :no more TLVs to decode.");
+ return TCORE_SAT_SUCCESS;
+ }
+
+ temp_index += data_len_consumed; /* temp_index pointing to the Tag of next TLV */
+
+ /* icon identifier - optional */
+ if ((cmd_data[temp_index] & 0x7F) == SATK_ICON_IDENTIFIER_TAG) {
+ rv = _sat_decode_icon_identifier_tlv(o_cmd_data, o_length, temp_index,
+ &sat_cmd_ind_data->data.get_inkey.icon_id,
+ &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv; /* Send TR */
+
+ if (o_length-temp_index == data_len_consumed) {
+ dbg("[SAT] SAT PARSER - :no more TLVs to decode.");
+ return TCORE_SAT_SUCCESS;
+ }
+
+ temp_index += data_len_consumed; /* temp_index pointing to the Tag of next TLV */
+ }
+
+ /* time duration - optional */
+ if ((cmd_data[temp_index] & 0x7F) == SATK_DURATION_TAG) {
+ rv = _sat_decode_duration_tlv(o_cmd_data, o_length, temp_index,
+ &sat_cmd_ind_data->data.get_inkey.duration,
+ &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv; /* Send TR */
+
+ if (o_length-temp_index == data_len_consumed) {
+ dbg("[SAT] SAT PARSER - :no more TLVs to decode.");
+ return TCORE_SAT_SUCCESS;
+ }
+
+ temp_index += data_len_consumed; /* temp_index pointing to the Tag of next TLV */
+ }
+
+ /* text attribute - optional */
+ if ((cmd_data[temp_index] & 0x7F) == SATK_TEXT_ATTRIBUTE_TAG) {
+ rv = _sat_decode_text_attribute_tlv(o_cmd_data, o_length, temp_index,
+ &sat_cmd_ind_data->data.get_inkey.text_attribute,
+ &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv; /* Send TR */
+
+ if (o_length-temp_index == data_len_consumed) {
+ dbg("[SAT] SAT PARSER - :no more TLVs to decode.");
+ return TCORE_SAT_SUCCESS;
+ }
+
+ temp_index += data_len_consumed; /* temp_index pointing to the Tag of next TLV */
+ }
+
+ if (o_length > temp_index) {
+ dbg("[SAT] SAT PARSER - : wrong text TLV, remaining data is found!!");
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ dbg("[SAT] SAT PARSER - :decoding done!.");
+ return TCORE_SAT_SUCCESS;
+}
+
+/*
+ * 6.4.3 GET INPUT
+ */
+static enum tcore_sat_result _sat_decode_get_input(unsigned char *o_cmd_data, int o_length,
+ int curr_offset, struct tcore_sat_proactive_command *sat_cmd_ind_data)
+{
+ int temp_index = 0;
+ int tlv_length = 0, remain_len = 0, expected_len = 0;
+ int data_len_consumed = 0;
+ unsigned char dev_id[4];
+ unsigned char *cmd_data = NULL;
+ enum tcore_sat_result rv = TCORE_SAT_SUCCESS;
+
+ if (o_cmd_data == NULL) {
+ dbg("[SAT] SAT PARSER - o_cmd_data == NULL");
+ return TCORE_SAT_ERROR_FATAL;
+ }
+
+ cmd_data = &o_cmd_data[0];
+ tlv_length = cmd_data[curr_offset-1];
+ temp_index = curr_offset + 2;
+ sat_cmd_ind_data->data.get_input.command_detail.cmd_num = cmd_data[temp_index++];
+ sat_cmd_ind_data->data.get_input.command_detail.cmd_type = cmd_data[temp_index++];
+
+ /* decode command qualifier */
+ if (cmd_data[temp_index] & 0x01) {
+ sat_cmd_ind_data->data.get_input.command_detail.cmd_qualifier.get_input.alphabet_set = TRUE;
+ dbg("[SAT] SAT PARSER - Alphabet set");
+ } else {
+ sat_cmd_ind_data->data.get_input.command_detail.cmd_qualifier.get_input.alphabet_set = FALSE;
+ dbg("[SAT] SAT PARSER - Numeric info");
+ }
+
+ if (cmd_data[temp_index] & 0x02) {
+ sat_cmd_ind_data->data.get_input.command_detail.cmd_qualifier.get_input.alphabet_type = INPUT_ALPHABET_TYPE_UCS2;
+ dbg("[SAT] SAT PARSER - INPUT_ALPHABET_TYPE_UCS2");
+ } else {
+ sat_cmd_ind_data->data.get_input.command_detail.cmd_qualifier.get_input.alphabet_type = INPUT_ALPHABET_TYPE_SMS_DEFAULT;
+ dbg("[SAT] SAT PARSER - INPUT_ALPHABET_TYPE_SMS_DEFAULT");
+ }
+
+ if (cmd_data[temp_index] & 0x04) {
+ sat_cmd_ind_data->data.get_input.command_detail.cmd_qualifier.get_input.me_echo_user_input = FALSE;
+ dbg("[SAT] SAT PARSER - user input not be revealed");
+ } else {
+ sat_cmd_ind_data->data.get_input.command_detail.cmd_qualifier.get_input.me_echo_user_input = TRUE;
+ dbg("[SAT] SAT PARSER - Me echo user input");
+ }
+
+ if (cmd_data[temp_index] & 0x08) {
+ sat_cmd_ind_data->data.get_input.command_detail.cmd_qualifier.get_input.user_input_unpacked_format = FALSE;
+ dbg("[SAT] SAT PARSER - packing required");
+ } else {
+ sat_cmd_ind_data->data.get_input.command_detail.cmd_qualifier.get_input.user_input_unpacked_format = TRUE;
+ dbg("[SAT] SAT PARSER - unpacked format");
+ }
+
+ if (cmd_data[temp_index] & 0x80) {
+ sat_cmd_ind_data->data.get_input.command_detail.cmd_qualifier.get_input.help_info = TRUE;
+ dbg("[SAT] SAT PARSER - Help info");
+ }
+
+ /* device identities */
+ temp_index++;
+ memcpy(dev_id, &cmd_data[temp_index], 4);
+ rv = _sat_decode_device_identities_tlv(dev_id, &sat_cmd_ind_data->data.get_input.device_id);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv;
+
+ /* text - mandatory */
+ temp_index += 4;
+
+ remain_len = o_length-temp_index;
+ expected_len = tlv_length - 5 - 4;
+ if (remain_len != expected_len) {
+ dbg("[SAT] SAT PARSER - : mismatch!! remain_len=%d, expected_len=%d", remain_len, expected_len);
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ rv = _sat_decode_text_tlv(o_cmd_data, o_length, temp_index,
+ &sat_cmd_ind_data->data.get_input.text,
+ &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv;
+
+ if (sat_cmd_ind_data->data.get_input.text.string_length <= 0)
+ err("[SAT] SAT PARSER - :string length is 0");
+
+ dbg("[SAT] SAT PARSER text(%s)", sat_cmd_ind_data->data.get_input.text.string);
+ dbg("[SAT] SAT PARSER o_len(%d) temp_index(%d) data_len_consumed(%d)",
+ o_length , temp_index, data_len_consumed);
+
+ if (o_length-temp_index < data_len_consumed) {
+ dbg("[SAT] SAT PARSER - :wrong text TLV.");
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ if (o_length-temp_index == data_len_consumed) {
+ dbg("[SAT] SAT PARSER - :no more TLVs to decode.");
+ return TCORE_SAT_SUCCESS;
+ }
+
+ temp_index += data_len_consumed; /* temp_index pointing to the Tag of next TLV */
+
+ /* response length - mandatory */
+ rv = _sat_decode_response_length_tlv(o_cmd_data, o_length, temp_index,
+ &sat_cmd_ind_data->data.get_input.rsp_len,
+ &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv;
+
+ if (o_length-temp_index == data_len_consumed) {
+ dbg("[SAT] SAT PARSER - :no more TLVs to decode.");
+ return TCORE_SAT_SUCCESS;
+ }
+
+ temp_index += data_len_consumed; /* temp_index pointing to the Tag of next TLV */
+
+ /* default text - optional */
+ if ((o_cmd_data[temp_index] & 0x7F) == SATK_DEFAULT_TEXT_TAG) {
+ rv = _sat_decode_text_tlv(o_cmd_data, o_length, temp_index,
+ &sat_cmd_ind_data->data.get_input.default_text,
+ &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv;
+
+ if (sat_cmd_ind_data->data.get_input.default_text.string_length <= 0)
+ err("[SAT] SAT PARSER - :string length is 0");
+
+ dbg("[SAT] SAT PARSER default text(%s)", sat_cmd_ind_data->data.get_input.default_text.string);
+ if (o_length-temp_index == data_len_consumed) {
+ dbg("[SAT] SAT PARSER - :no more TLVs to decode.");
+ return TCORE_SAT_SUCCESS;
+ }
+
+ temp_index += data_len_consumed; /* temp_index pointing to the Tag of next TLV */
+ }
+
+ /* icon identifier */
+ if ((cmd_data[temp_index] & 0x7F) == SATK_ICON_IDENTIFIER_TAG) {
+ rv = _sat_decode_icon_identifier_tlv(o_cmd_data, o_length, temp_index,
+ &sat_cmd_ind_data->data.get_input.icon_id,
+ &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv; /* Send TR */
+
+ if (o_length-temp_index == data_len_consumed) {
+ dbg("[SAT] SAT PARSER - :no more TLVs to decode.");
+ return TCORE_SAT_SUCCESS;
+ }
+ temp_index += data_len_consumed; /* temp_index pointing to the Tag of next TLV */
+ }
+
+ /* text attribute - optional */
+ if ((cmd_data[temp_index] & 0x7F) == SATK_TEXT_ATTRIBUTE_TAG) {
+ rv = _sat_decode_text_attribute_tlv(o_cmd_data, o_length, temp_index,
+ &sat_cmd_ind_data->data.get_input.text_attribute,
+ &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv; /* Send TR */
+
+ if (o_length-temp_index == data_len_consumed) {
+ dbg("[SAT] SAT PARSER - :no more TLVs to decode.");
+ return TCORE_SAT_SUCCESS;
+ }
+
+ temp_index += data_len_consumed; /* temp_index pointing to the Tag of next TLV */
+ }
+
+ if (o_length > temp_index) {
+ dbg("[SAT] SAT PARSER - : wrong text TLV, remaining data is found!!");
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ dbg("[SAT] SAT PARSER - :decoding done!.");
+ return TCORE_SAT_SUCCESS;
+}
+
+/*
+ * 6.4.4 MORE TIME
+ */
+static enum tcore_sat_result _sat_decode_more_time(unsigned char *o_cmd_data, int o_length,
+ int curr_offset, struct tcore_sat_proactive_command *sat_cmd_ind_data)
+{
+ int temp_index = 0;
+ unsigned char dev_id[4];
+ unsigned char *cmd_data = NULL;
+ enum tcore_sat_result rv = TCORE_SAT_SUCCESS;
+
+ if (o_cmd_data == NULL) {
+ dbg("[SAT] SAT PARSER - o_cmd_data == NULL");
+ return TCORE_SAT_ERROR_FATAL;
+ }
+
+ /* command detail */
+ cmd_data = &o_cmd_data[0];
+ temp_index = curr_offset + 2;
+ sat_cmd_ind_data->data.setup_event_list.command_detail.cmd_num = cmd_data[temp_index++];
+ sat_cmd_ind_data->data.setup_event_list.command_detail.cmd_type = cmd_data[temp_index++];
+
+ /* device identifier */
+ temp_index++;
+ memcpy(dev_id, &cmd_data[temp_index], 4);
+ rv = _sat_decode_device_identities_tlv(dev_id, &sat_cmd_ind_data->data.setup_event_list.device_id);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv;
+
+ temp_index += 4;
+ dbg("[SAT] SAT PARSER - :decoding done!.");
+ return TCORE_SAT_SUCCESS;
+}
+
+/*
+ * 6.4.5 PLAY TONE
+ */
+static enum tcore_sat_result _sat_decode_play_tone(unsigned char *o_cmd_data, int o_length,
+ int curr_offset, struct tcore_sat_proactive_command *sat_cmd_ind_data)
+{
+ int temp_index = 0, data_len_consumed = 0;
+ unsigned char dev_id[4];
+ unsigned char *cmd_data = NULL;
+ enum tcore_sat_result rv = TCORE_SAT_SUCCESS;
+
+ if (o_cmd_data == NULL) {
+ dbg("[SAT] SAT PARSER - o_cmd_data == NULL");
+ return TCORE_SAT_ERROR_FATAL;
+ }
+
+ /* command detail */
+ cmd_data = &o_cmd_data[0];
+ temp_index = curr_offset + 2;
+ sat_cmd_ind_data->data.play_tone.command_detail.cmd_num = cmd_data[temp_index++];
+ sat_cmd_ind_data->data.play_tone.command_detail.cmd_type = cmd_data[temp_index++];
+
+ /* decode command qualifier */
+ if (cmd_data[temp_index] & 0x01)
+ sat_cmd_ind_data->data.play_tone.command_detail.cmd_qualifier.play_tone.vibration_alert = VIBRATE_ALERT_REQUIRED;
+ else
+ sat_cmd_ind_data->data.play_tone.command_detail.cmd_qualifier.play_tone.vibration_alert = VIBRATE_ALERT_OPTIONAL;
+
+ /* device identifier */
+ temp_index++;
+ memcpy(dev_id, &cmd_data[temp_index], 4);
+ rv = _sat_decode_device_identities_tlv(dev_id, &sat_cmd_ind_data->data.play_tone.device_id);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv;
+
+ /* alpha id - optional */
+ temp_index += 4;
+ if ((cmd_data[temp_index] & 0x7F) == SATK_ALPHA_IDENTIFIER_TAG) {
+ rv = _sat_decode_alpha_identifier_tlv(o_cmd_data, o_length, temp_index,
+ &sat_cmd_ind_data->data.play_tone.alpha_id,
+ &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv;
+
+ temp_index += data_len_consumed;
+ if (temp_index >= o_length) {
+ dbg("[SAT] SAT PARSER - no more TLVs to decode.");
+ dbg("[SAT] SAT PARSER - default value is set - tone type, duration");
+ sat_cmd_ind_data->data.play_tone.tone.tone_type = GENERAL_BEEP;
+ sat_cmd_ind_data->data.play_tone.duration.time_unit = TIME_UNIT_SECONDS;
+ sat_cmd_ind_data->data.play_tone.duration.time_interval = 2;
+
+ return TCORE_SAT_SUCCESS;
+ }
+ }
+
+ /* tone - optional */
+ if ((cmd_data[temp_index] & 0x7F) == SATK_TONE_TAG) {
+ rv = _sat_decode_tone_tlv(o_cmd_data, o_length, temp_index,
+ &sat_cmd_ind_data->data.play_tone.tone,
+ &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv;
+
+ temp_index += data_len_consumed;
+ } else
+ sat_cmd_ind_data->data.play_tone.tone.tone_type = GENERAL_BEEP;
+
+ /* time duration - optional */
+ if ((cmd_data[temp_index] & 0x7F) == SATK_DURATION_TAG) {
+ rv = _sat_decode_duration_tlv(o_cmd_data, o_length, temp_index,
+ &sat_cmd_ind_data->data.play_tone.duration,
+ &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv; /* Send TR */
+
+ temp_index += data_len_consumed;
+ if (temp_index >= o_length) {
+ dbg("[SAT] SAT PARSER - no more TLVs to decode.");
+ return TCORE_SAT_SUCCESS;
+ }
+ } else {
+ dbg("[SAT] SAT PARSER - Duration TLV not present, ME should use a default value.");
+ sat_cmd_ind_data->data.play_tone.duration.time_unit = TIME_UNIT_SECONDS;
+ sat_cmd_ind_data->data.play_tone.duration.time_interval = 2;
+ }
+
+ /* icon identifier */
+ if ((cmd_data[temp_index] & 0x7F) == SATK_ICON_IDENTIFIER_TAG) {
+ data_len_consumed = 0;
+ rv = _sat_decode_icon_identifier_tlv(o_cmd_data, o_length, temp_index,
+ &sat_cmd_ind_data->data.play_tone.icon_id,
+ &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; /* Send TR */
+
+ if (temp_index + data_len_consumed >= o_length) {
+ dbg("[SAT] SAT PARSER - no more TLVs to decode.");
+ return TCORE_SAT_SUCCESS;
+ }
+
+ temp_index += data_len_consumed; /* temp_index pointing to the Tag of next TLV */
+ }
+
+ /* text attribute - optional */
+ if ((cmd_data[temp_index] & 0x7F) == SATK_TEXT_ATTRIBUTE_TAG) {
+ rv = _sat_decode_text_attribute_tlv(o_cmd_data, o_length, temp_index,
+ &sat_cmd_ind_data->data.play_tone.text_attribute,
+ &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv; /* Send TR */
+
+ if (temp_index + data_len_consumed >= o_length) {
+ dbg("[SAT] SAT PARSER - no more TLVs to decode.");
+ return TCORE_SAT_SUCCESS;
+ }
+
+ temp_index += data_len_consumed; /* temp_index pointing to the Tag of next TLV */
+ }
+
+ /*
+ * TODO:
+ * frames
+ */
+
+ dbg("[SAT] SAT PARSER - :decoding done!.");
+ return TCORE_SAT_SUCCESS;
+}
+
+/*
+ * 6.4.7 REFRESH
+ */
+static enum tcore_sat_result _sat_decode_refresh(unsigned char *o_cmd_data, int o_length,
+ int curr_offset, struct tcore_sat_proactive_command *sat_cmd_ind_data)
+{
+ int temp_index = 0, data_len_consumed = 0;
+ unsigned char dev_id[4];
+ unsigned char *cmd_data = NULL;
+ enum tcore_sat_result rv = TCORE_SAT_SUCCESS;
+
+ if (o_cmd_data == NULL) {
+ dbg("[SAT] SAT PARSER - o_cmd_data == NULL");
+ return TCORE_SAT_ERROR_FATAL;
+ }
+
+ /* command detail */
+ cmd_data = &o_cmd_data[0];
+ temp_index = curr_offset + 2;
+ sat_cmd_ind_data->data.refresh.command_detail.cmd_num = cmd_data[temp_index++];
+ sat_cmd_ind_data->data.refresh.command_detail.cmd_type = cmd_data[temp_index++];
+
+ /* decode command qualifier */
+ switch (cmd_data[temp_index]) {
+ case SIM_REFRESH_CMD_INIT_AND_FULL_FCN:
+ case SIM_REFRESH_CMD_FCN:
+ case SIM_REFRESH_CMD_INIT_AND_FCN:
+ case SIM_REFRESH_CMD_INIT:
+ case SIM_REFRESH_CMD_RESET:
+ sat_cmd_ind_data->data.refresh.command_detail.cmd_qualifier.refresh.refresh = cmd_data[temp_index];
+ dbg("[SAT] SAT PARSER - : refresh mode=[0x%02x]:0-init&FFCN, 1-FCN, 2-init&FCN, 3-init, 4-reset",
+ cmd_data[temp_index]);
+ break;
+
+ case SIM_REFRESH_CMD_3G_APPLICATION_RESET:
+ case SIM_REFRESH_CMD_3G_SESSION_RESET:
+ case SIM_REFRESH_CMD_RESERVED:
+ default:
+ dbg("[SAT] SAT PARSER - : refresh mode=0x%02x Not Supported", cmd_data[temp_index]);
+ return TCORE_SAT_BEYOND_ME_CAPABILITY;
+ }
+
+ /* device identifier */
+ temp_index++;
+ memcpy(dev_id, &cmd_data[temp_index], 4);
+ rv = _sat_decode_device_identities_tlv(dev_id, &sat_cmd_ind_data->data.refresh.device_id);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv;
+
+ /* check file list */
+ temp_index += 4;
+ if ((sat_cmd_ind_data->data.refresh.command_detail.cmd_qualifier.refresh.refresh == SIM_REFRESH_CMD_FCN)
+ || (sat_cmd_ind_data->data.refresh.command_detail.cmd_qualifier.refresh.refresh == SIM_REFRESH_CMD_INIT_AND_FCN)) {
+ rv = _sat_decode_file_list_tlv(o_cmd_data, o_length, temp_index,
+ &sat_cmd_ind_data->data.refresh.file_list,
+ &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv;
+ } else
+ sat_cmd_ind_data->data.refresh.file_list.file_count = 0;
+
+ dbg("[SAT] SAT PARSER - :decoding done!.");
+ return TCORE_SAT_SUCCESS;
+}
+
+/*
+ * 6.4.8 SETUP MENU
+ */
+static enum tcore_sat_result _sat_decode_setup_menu(unsigned char *tlv_str, int tlv_len,
+ int curr_offset, struct tcore_sat_proactive_command *pactive_cmd_ind_obj)
+{
+ int temp_index = 0;
+ int data_len_consumed = 0;
+ unsigned char dev_id[4];
+ unsigned char *src_data;
+ enum tcore_sat_result rv = TCORE_SAT_SUCCESS;
+
+ /* access command detail */
+ temp_index = curr_offset + 2; /* move the temp_index to command detail info + 2(tag and length) */
+ src_data = &tlv_str[0];
+
+ /* In this time, the point of temp_index is COMMAND NUMBER */
+ /* [1] insert command detail information into each proactive command data structure. */
+ pactive_cmd_ind_obj->data.setup_menu.command_detail.cmd_num = src_data[temp_index++];
+ pactive_cmd_ind_obj->data.setup_menu.command_detail.cmd_type = src_data[temp_index++];
+
+ /* [2] decode COMMAND QUALIFIER */
+ /*
+ * -bit 1: 0 = no selection preference;
+ * 1 = selection using soft key preferred.
+ * -bits 2 to 7: = RFU.
+ * -bit 8: 0 = no help information available;
+ * 1 = help information available.
+ */
+
+ /* [2-1] selection preference */
+ if (src_data[temp_index] & 0x01) {
+ pactive_cmd_ind_obj->data.setup_menu.command_detail.cmd_qualifier.setup_menu.select_preference =
+ SELECTION_PREFERENCE_USING_SOFT_KEY;
+ dbg("[SAT] SAT PARSER - sel_pref=SAT_SELECTION_PREFERENCE_USING_SOFT_KEY.");
+ } else {
+ pactive_cmd_ind_obj->data.setup_menu.command_detail.cmd_qualifier.setup_menu.select_preference =
+ SELECTION_PREFERENCE_NONE_REQUESTED;
+ dbg("[SAT] SAT PARSER - : sel_pref=SAT_SELECTION_PREFERENCE_NONE_REQUESTED.");
+ }
+
+ /* [2-2] help available */
+ if (src_data[temp_index] & 0x80) {
+ pactive_cmd_ind_obj->data.setup_menu.command_detail.cmd_qualifier.setup_menu.help_info =
+ TRUE;
+ dbg("[SAT] SAT PARSER - : is help Available=TRUE.");
+ } else {
+ pactive_cmd_ind_obj->data.setup_menu.command_detail.cmd_qualifier.setup_menu.help_info =
+ FALSE;
+ dbg("[SAT] SAT PARSER - is help Available=FALSE.");
+ }
+
+ /* In this time, the point of temp_index is DEVICE IDENTITIES. */
+ /* [3] decode DEVICE IDENTITIES TLV */
+ temp_index++;
+ memcpy(dev_id, &src_data[temp_index], 4);
+ rv = _sat_decode_device_identities_tlv(dev_id, &pactive_cmd_ind_obj->data.setup_menu.device_id);
+ if (rv != TCORE_SAT_SUCCESS) {
+ /* send TR in SatkProcessProactiveCmdInd() */
+ return rv;
+ }
+
+ /* In this time, the point of temp_index is ALPHA IDENTIFIER. 11 or 12. */
+ /* [4] decode ALPHA IDENTIFIER TLV */
+ temp_index += 4;
+ dbg("[SAT] SAT PARSER - :temp_index=%d", temp_index);
+ rv = _sat_decode_alpha_identifier_tlv(src_data, tlv_len, temp_index,
+ &pactive_cmd_ind_obj->data.setup_menu.alpha_id,
+ &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv;
+
+ /* In this time, the point of temp_index is ITEM TLV */
+ /* [5] decode ITEM LIST (at least one is mandatory) */
+ temp_index += data_len_consumed;
+ pactive_cmd_ind_obj->data.setup_menu.menu_item_cnt = 0;
+ do {
+ data_len_consumed = 0;
+ if ((src_data[temp_index] & 0x7F) == SATK_ITEM_TAG) {
+ rv = _sat_decode_item_tlv(src_data, tlv_len, temp_index,
+ &pactive_cmd_ind_obj->data.setup_menu.menu_item[pactive_cmd_ind_obj->data.setup_menu.menu_item_cnt],
+ &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv;
+
+ if (!pactive_cmd_ind_obj->data.setup_menu.menu_item[0].text_len)
+ break;
+ } else {
+ if (pactive_cmd_ind_obj->data.setup_menu.menu_item_cnt == 0) {
+ dbg("menu item is not exist.");
+ return TCORE_SAT_REQUIRED_VALUE_MISSING;
+ }
+ /* else */
+ break; /* ??? */
+ }
+ pactive_cmd_ind_obj->data.setup_menu.menu_item_cnt++;
+ temp_index += data_len_consumed;
+
+ if (temp_index >= tlv_len)
+ break;
+ } while (pactive_cmd_ind_obj->data.setup_menu.menu_item_cnt < SAT_MENU_ITEM_COUNT_MAX);
+
+ dbg("[SAT] SAT PARSER - :setup menu item_count=%d", pactive_cmd_ind_obj->data.setup_menu.menu_item_cnt);
+ if (temp_index >= tlv_len) {
+ dbg("[SAT] SAT PARSER - :no more TLVs to decode.");
+ /* send TR in SatkProcessProactiveCmdInd() */
+ return TCORE_SAT_SUCCESS;
+ }
+
+ /* [6] (optional TLV) decode ITEMS NEXT ACTION INDICATOR TLV */
+ if ((src_data[temp_index] & 0x7F) == SATK_ITEMS_NEXT_ACTION_INDICATOR_TAG) {
+ data_len_consumed = 0;
+ rv = _sat_decode_item_next_action_indicator_tlv(tlv_str, tlv_len, temp_index,
+ &pactive_cmd_ind_obj->data.setup_menu.next_act_ind_list,
+ &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv;
+
+ if (temp_index + data_len_consumed >= tlv_len) {
+ dbg("[SAT] SAT PARSER - no more TLVs to decode.");
+ /* send the data to Noti manager. */
+ return TCORE_SAT_SUCCESS;
+ }
+
+ temp_index += data_len_consumed; /* temp_index pointing to the Tag of next TLV */
+ } else {
+ dbg("[SAT] SAT PARSER - ITEMS NEXT ACTION INDICATOR TLV Not present");
+ }
+
+ /* [7] (optional TLV) decode ICON IDENTIFIER TLV */
+ if ((src_data[temp_index] & 0x7F) == SATK_ICON_IDENTIFIER_TAG) {
+ data_len_consumed = 0;
+ rv = _sat_decode_icon_identifier_tlv(tlv_str, tlv_len, temp_index,
+ &pactive_cmd_ind_obj->data.setup_menu.icon_id,
+ &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv;
+
+ if (temp_index + data_len_consumed >= tlv_len) {
+ dbg("[SAT] SAT PARSER - no more TLVs to decode.");
+ /* send the data to Noti manager. */
+ return TCORE_SAT_SUCCESS;
+ }
+
+ temp_index += data_len_consumed; /* temp_index pointing to the Tag of next TLV */
+ } else {
+ dbg("[SAT] SAT PARSER - ICON IDENTIFIER TLV Not present");
+ }
+
+ /* [8] (optional TLV) decode ICON IDENTIFIER LIST TLV */
+ if ((src_data[temp_index] & 0x7F) == SATK_ITEM_ICON_IDENTIFIER_LIST_TAG) {
+ data_len_consumed = 0;
+ rv = _sat_decode_icon_identifier_list_tlv(tlv_str, tlv_len, temp_index,
+ &pactive_cmd_ind_obj->data.setup_menu.icon_list,
+ &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv; /* Send TR */
+
+ if (temp_index + data_len_consumed >= tlv_len) {
+ dbg("[SAT] SAT PARSER - no more TLVs to decode.");
+ /* send the data to Noti manager. */
+ return TCORE_SAT_SUCCESS;
+ }
+
+ temp_index += data_len_consumed; /* temp_index pointing to the Tag of next TLV */
+
+ } else {
+ dbg("[SAT] SAT PARSER - ICON IDENTIFIER LIST TLV not present");
+ }
+
+ /* text attribute - optional */
+ if ((src_data[temp_index] & 0x7F) == SATK_TEXT_ATTRIBUTE_TAG) {
+ rv = _sat_decode_text_attribute_tlv(tlv_str, tlv_len, temp_index,
+ &pactive_cmd_ind_obj->data.setup_menu.text_attribute,
+ &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv; /* Send TR */
+
+ if (temp_index + data_len_consumed >= tlv_len) {
+ dbg("[SAT] SAT PARSER - no more TLVs to decode.");
+ return TCORE_SAT_SUCCESS;
+ }
+
+ temp_index += data_len_consumed; /* temp_index pointing to the Tag of next TLV */
+ }
+
+ /* text attribute list - optional */
+ if ((src_data[temp_index] & 0x7F) == SATK_TEXT_ATTRIBUTE_LIST_TAG) {
+ int attr_item_temp_index = 0, item_cnt = 0;
+ int txt_attr_list_len = 0;
+
+ struct tel_sat_text_attribute_list *txt_attr_list = NULL;
+
+ txt_attr_list = &pactive_cmd_ind_obj->data.setup_menu.text_attribute_list;
+
+ /* length */
+ temp_index++;
+ txt_attr_list_len = src_data[temp_index];
+ if (txt_attr_list_len == 0) {
+ dbg("[SAT] - Text Attribute List is nothing");
+ return TCORE_SAT_REQUIRED_VALUE_MISSING;
+ }
+
+ /* item cnt - each text attribute length is 4byte */
+ item_cnt = txt_attr_list_len/4;
+ txt_attr_list->list_cnt = item_cnt;
+ dbg("[SAT] - text attribute item cnt(%d)", item_cnt);
+
+ /* get attribute data */
+ temp_index++;
+ for (attr_item_temp_index = 0; attr_item_temp_index < item_cnt; attr_item_temp_index++) {
+ memcpy(txt_attr_list->text_attribute_list[attr_item_temp_index].text_formatting, &src_data[temp_index], 4);
+ temp_index += 4;
+ }
+
+ dbg("[SAT] SAT PARSER - done to decode text attribute list");
+ }
+
+ dbg("[SAT] SAT PARSER - no more TLVs to decode.");
+ return TCORE_SAT_SUCCESS;
+}
+
+/*
+ * 6.4.9 SELECT ITEM
+ */
+static enum tcore_sat_result _sat_decode_select_item(unsigned char *o_cmd_data, int o_length,
+ int curr_offset, struct tcore_sat_proactive_command *sat_cmd_ind_data)
+{
+ int temp_index = 0;
+ int data_len_consumed = 0;
+ unsigned char dev_id[4];
+ unsigned char *cmd_data = NULL;
+ enum tcore_sat_result rv = TCORE_SAT_SUCCESS;
+
+ if (o_cmd_data == NULL) {
+ dbg("[SAT] SAT PARSER - o_cmd_data == NULL");
+ return TCORE_SAT_ERROR_FATAL;
+ }
+
+ cmd_data = &o_cmd_data[0];
+ temp_index = curr_offset + 2;
+ sat_cmd_ind_data->data.select_item.command_detail.cmd_num = cmd_data[temp_index++];
+ sat_cmd_ind_data->data.select_item.command_detail.cmd_type = cmd_data[temp_index++];
+
+ /* decode command qualifier */
+ if (cmd_data[temp_index] & 0x01) {
+ if (cmd_data[temp_index] & 0x02) {
+ sat_cmd_ind_data->data.select_item.command_detail.cmd_qualifier.select_item.presentation_type = PRESENTATION_TYPE_NAVIGATION_OPTION;
+ dbg("[SAT] SAT PARSER - PRESENTATION_TYPE_NAVIGATION_OPTION");
+ } else {
+ sat_cmd_ind_data->data.select_item.command_detail.cmd_qualifier.select_item.presentation_type = PRESENTATION_TYPE_DATA_VALUE;
+ dbg("[SAT] SAT PARSER - PRESENTATION_TYPE_DATA_VALUE");
+ }
+ } else {
+ sat_cmd_ind_data->data.select_item.command_detail.cmd_qualifier.select_item.presentation_type = PRESENTATION_TYPE_NOT_SPECIFIED;
+ dbg("[SAT] SAT PARSER - PRESENTATION_TYPE_NOT_SPECIFIED");
+ }
+
+ if (cmd_data[temp_index] & 0x04) {
+ sat_cmd_ind_data->data.select_item.command_detail.cmd_qualifier.select_item.select_preference = SELECTION_PREFERENCE_USING_SOFT_KEY;
+ dbg("[SAT] SAT PARSER - SELECTION_PREFERENCE_USING_SOFT_KEY");
+ } else {
+ sat_cmd_ind_data->data.select_item.command_detail.cmd_qualifier.select_item.select_preference = SELECTION_PREFERENCE_NONE_REQUESTED;
+ dbg("[SAT] SAT PARSER - SELECTION_PREFERENCE_NONE_REQUESTED");
+ }
+
+ if (cmd_data[temp_index] & 0x80) {
+ sat_cmd_ind_data->data.select_item.command_detail.cmd_qualifier.select_item.help_info = TRUE;
+ dbg("[SAT] SAT PARSER - Help info");
+ }
+
+ /* device identities */
+ temp_index++;
+ memcpy(dev_id, &cmd_data[temp_index], 4);
+ rv = _sat_decode_device_identities_tlv(dev_id, &sat_cmd_ind_data->data.select_item.device_id);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv;
+
+ /* alpha identifier */
+ temp_index += 4;
+ if ((cmd_data[temp_index] & 0x7F) == SATK_ALPHA_IDENTIFIER_TAG) {
+ rv = _sat_decode_alpha_identifier_tlv(o_cmd_data, o_length, temp_index,
+ &sat_cmd_ind_data->data.select_item.alpha_id,
+ &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv;
+
+ temp_index += data_len_consumed;
+ }
+
+ /* item objects */
+ sat_cmd_ind_data->data.select_item.menu_item_cnt = 0;
+ do {
+ data_len_consumed = 0;
+
+ if ((cmd_data[temp_index] & 0x7F) == SATK_ITEM_TAG) {
+ rv = _sat_decode_item_tlv(o_cmd_data, o_length, temp_index,
+ &sat_cmd_ind_data->data.select_item.menu_item[sat_cmd_ind_data->data.select_item.menu_item_cnt],
+ &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv;
+ } else {
+ if (sat_cmd_ind_data->data.select_item.menu_item_cnt == 0) {
+ dbg("menu item is not exist.");
+ return TCORE_SAT_REQUIRED_VALUE_MISSING;
+ }
+ /* else */
+ break; /* ??? */
+ }
+
+ sat_cmd_ind_data->data.select_item.menu_item_cnt++;
+ temp_index += data_len_consumed;
+
+ if (temp_index >= o_length)
+ break;
+
+ } while (sat_cmd_ind_data->data.select_item.menu_item_cnt < SAT_MENU_ITEM_COUNT_MAX);
+
+ dbg("[SAT] SAT PARSER - select menu item_count=%d", sat_cmd_ind_data->data.select_item.menu_item_cnt);
+ if (temp_index >= o_length) {
+ dbg("[SAT] SAT PARSER - :no more TLVs to decode.");
+ return TCORE_SAT_SUCCESS;
+ }
+
+ /* item next action indicator */
+ if ((cmd_data[temp_index] & 0x7F) == SATK_ITEMS_NEXT_ACTION_INDICATOR_TAG) {
+ data_len_consumed = 0;
+ rv = _sat_decode_item_next_action_indicator_tlv(o_cmd_data, o_length, temp_index,
+ &sat_cmd_ind_data->data.select_item.item_next_act_ind_list, &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv;
+
+ if (temp_index + data_len_consumed >= o_length) {
+ dbg("[SAT] SAT PARSER - no more TLVs to decode.");
+ return TCORE_SAT_SUCCESS;
+ }
+
+ temp_index += data_len_consumed;
+ }
+
+ /* item identifier */
+ if ((cmd_data[temp_index] & 0x7F) == SATK_ITEM_IDENTIFIER_TAG) {
+ data_len_consumed = 0;
+ rv = _sat_decode_item_identifier_tlv(o_cmd_data, o_length, temp_index,
+ &sat_cmd_ind_data->data.select_item.item_identifier,
+ &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv;
+
+ if (temp_index + data_len_consumed >= o_length) {
+ dbg("[SAT] SAT PARSER - no more TLVs to decode.");
+ return TCORE_SAT_SUCCESS;
+ }
+
+ temp_index += data_len_consumed; /* temp_index pointing to the Tag of next TLV */
+ }
+
+ /* icon identifier */
+ if ((cmd_data[temp_index] & 0x7F) == SATK_ICON_IDENTIFIER_TAG) {
+ data_len_consumed = 0;
+ rv = _sat_decode_icon_identifier_tlv(o_cmd_data, o_length, temp_index,
+ &sat_cmd_ind_data->data.select_item.icon_id,
+ &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; /* Send TR */
+
+ if (temp_index + data_len_consumed >= o_length) {
+ dbg("[SAT] SAT PARSER - no more TLVs to decode.");
+ return TCORE_SAT_SUCCESS;
+ }
+
+ temp_index += data_len_consumed; /* temp_index pointing to the Tag of next TLV */
+ }
+
+ if ((cmd_data[temp_index] & 0x7F) == SATK_ITEM_ICON_IDENTIFIER_LIST_TAG) {
+ data_len_consumed = 0;
+ rv = _sat_decode_icon_identifier_list_tlv(o_cmd_data, o_length, temp_index,
+ &sat_cmd_ind_data->data.select_item.icon_list,
+ &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv; /* Send TR */
+
+ if (temp_index + data_len_consumed >= o_length) {
+ dbg("[SAT] SAT PARSER - no more TLVs to decode.");
+ return TCORE_SAT_SUCCESS;
+ }
+
+ temp_index += data_len_consumed; /* temp_index pointing to the Tag of next TLV */
+ }
+
+ /* text attribute - optional */
+ if ((cmd_data[temp_index] & 0x7F) == SATK_TEXT_ATTRIBUTE_TAG) {
+ rv = _sat_decode_text_attribute_tlv(o_cmd_data, o_length, temp_index,
+ &sat_cmd_ind_data->data.select_item.text_attribute,
+ &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv; /* Send TR */
+
+ if (temp_index + data_len_consumed >= o_length) {
+ dbg("[SAT] SAT PARSER - no more TLVs to decode.");
+ return TCORE_SAT_SUCCESS;
+ }
+
+ temp_index += data_len_consumed; /* temp_index pointing to the Tag of next TLV */
+ }
+
+ /* text attribute list - optional */
+ if ((cmd_data[temp_index] & 0x7F) == SATK_TEXT_ATTRIBUTE_LIST_TAG) {
+ int attr_item_temp_index = 0, item_cnt = 0;
+ int txt_attr_list_len = 0;
+
+ struct tel_sat_text_attribute_list *txt_attr_list = NULL;
+
+ txt_attr_list = &sat_cmd_ind_data->data.select_item.text_attribute_list;
+
+ /* length */
+ temp_index++;
+ txt_attr_list_len = cmd_data[temp_index];
+ if (txt_attr_list_len == 0) {
+ dbg("[SAT] - Text Attribute List is nothing");
+ return TCORE_SAT_REQUIRED_VALUE_MISSING;
+ }
+
+ /* item cnt - each text attribute length is 4byte */
+ item_cnt = txt_attr_list_len/4;
+ txt_attr_list->list_cnt = item_cnt;
+ dbg("[SAT] - text attribute item cnt(%d)", item_cnt);
+
+ /* get attribute data */
+ temp_index++;
+ for (attr_item_temp_index = 0; attr_item_temp_index < item_cnt; attr_item_temp_index++) {
+ memcpy(txt_attr_list->text_attribute_list[attr_item_temp_index].text_formatting, &cmd_data[temp_index], 4);
+ temp_index += 4;
+ }
+
+ dbg("[SAT] SAT PARSER - done to decode text attribute list");
+ }
+
+ dbg("[SAT] SAT PARSER - :decoding done!.");
+ return TCORE_SAT_SUCCESS;
+}
+
+/*
+ * 6.4.10 SEND SMS
+ */
+static enum tcore_sat_result _sat_decode_send_sms(unsigned char *o_cmd_data, int o_length,
+ int curr_offset, struct tcore_sat_proactive_command *sat_cmd_ind_data)
+{
+ int temp_index = 0;
+ int data_len_consumed = 0;
+ unsigned char dev_id[4];
+ unsigned char *cmd_data = NULL;
+ enum tcore_sat_result rv = TCORE_SAT_SUCCESS;
+
+ if (o_cmd_data == NULL) {
+ dbg("[SAT] SAT PARSER - o_cmd_data == NULL");
+ return TCORE_SAT_ERROR_FATAL;
+ }
+
+ cmd_data = &o_cmd_data[0];
+ temp_index = curr_offset + 2;
+ sat_cmd_ind_data->data.send_sms.command_detail.cmd_num = cmd_data[temp_index++];
+ sat_cmd_ind_data->data.send_sms.command_detail.cmd_type = cmd_data[temp_index++];
+
+ /* decode command qualifier */
+ if (cmd_data[temp_index] & 0x01)
+ sat_cmd_ind_data->data.send_sms.command_detail.cmd_qualifier.send_sms.packing_by_me_required = TRUE;
+ else {
+ sat_cmd_ind_data->data.send_sms.command_detail.cmd_qualifier.send_sms.packing_by_me_required = FALSE;
+ dbg("[SAT] SAT PARSER - packing by me required is false");
+ }
+
+ /* device identities */
+ temp_index++;
+ memcpy(dev_id, &cmd_data[temp_index], 4);
+ rv = _sat_decode_device_identities_tlv(dev_id, &sat_cmd_ind_data->data.send_sms.device_id);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv;
+
+ /* alpha identifier */
+ temp_index += 4;
+ if ((cmd_data[temp_index] & 0x7F) == SATK_ALPHA_IDENTIFIER_TAG) {
+ data_len_consumed = 0;
+ rv = _sat_decode_alpha_identifier_tlv(o_cmd_data, o_length, temp_index,
+ &sat_cmd_ind_data->data.send_sms.alpha_id,
+ &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv;
+
+ temp_index += data_len_consumed;
+ }
+
+ /* address */
+ if ((cmd_data[temp_index] & 0x7F) == SATK_ADDRESS_TAG) {
+ data_len_consumed = 0;
+ rv = _sat_decode_address_tlv(o_cmd_data, o_length, temp_index,
+ &sat_cmd_ind_data->data.send_sms.address,
+ &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv;
+
+ temp_index += data_len_consumed;
+ }
+
+ /* SMS-TPDU */
+ data_len_consumed = 0;
+ rv = _sat_decode_sms_tpdu_tlv(o_cmd_data, o_length, temp_index,
+ &sat_cmd_ind_data->data.send_sms.sms_tpdu,
+ &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv;
+
+ if (temp_index + data_len_consumed >= o_length) {
+ dbg("[SAT] SAT PARSER - no more TLVs to decode.");
+ return TCORE_SAT_SUCCESS;
+ }
+
+ /* icon identifier */
+ temp_index += data_len_consumed;
+ if ((cmd_data[temp_index] & 0x7F) == SATK_ICON_IDENTIFIER_TAG) {
+ data_len_consumed = 0;
+ rv = _sat_decode_icon_identifier_tlv(o_cmd_data, o_length, temp_index,
+ &sat_cmd_ind_data->data.send_sms.icon_id,
+ &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; /* Send TR */
+
+ if (temp_index + data_len_consumed >= o_length) {
+ dbg("[SAT] SAT PARSER - no more TLVs to decode.");
+ return TCORE_SAT_SUCCESS;
+ }
+
+ temp_index += data_len_consumed; /* temp_index pointing to the Tag of next TLV */
+ }
+
+ dbg("[SAT] SAT PARSER - :decoding done!.");
+ return TCORE_SAT_SUCCESS;
+}
+
+/*
+ * 6.4.11 SEND SS
+ */
+static enum tcore_sat_result _sat_decode_send_ss(unsigned char *o_cmd_data, int o_length,
+ int curr_offset, struct tcore_sat_proactive_command *sat_cmd_ind_data)
+{
+ int temp_index = 0, data_len_consumed = 0;
+ unsigned char dev_id[4];
+ unsigned char *cmd_data = NULL;
+ enum tcore_sat_result rv = TCORE_SAT_SUCCESS;
+
+ if (o_cmd_data == NULL || sat_cmd_ind_data == NULL) {
+ dbg("[SAT] SAT PARSER - o_cmd_data == NULL");
+ return TCORE_SAT_ERROR_FATAL;
+ }
+
+ cmd_data = &o_cmd_data[0];
+ temp_index = curr_offset + 2;
+ sat_cmd_ind_data->data.send_ss.command_detail.cmd_num = cmd_data[temp_index++];
+ sat_cmd_ind_data->data.send_ss.command_detail.cmd_type = cmd_data[temp_index++];
+
+ /* command detail */
+ temp_index++; /* RFU */
+
+ /* device identities */
+ memcpy(dev_id, &cmd_data[temp_index], 4);
+ rv = _sat_decode_device_identities_tlv(dev_id, &sat_cmd_ind_data->data.send_ss.device_id);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv;
+
+ /* alpha identifier - optional */
+ temp_index += 4;
+ if ((cmd_data[temp_index] & 0x7F) == SATK_ALPHA_IDENTIFIER_TAG) {
+ rv = _sat_decode_alpha_identifier_tlv(o_cmd_data, o_length, temp_index,
+ &sat_cmd_ind_data->data.send_ss.alpha_id,
+ &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv;
+
+ temp_index += data_len_consumed;
+ }
+
+ /* ss string */
+ rv = _sat_decode_ss_string_tlv(o_cmd_data, o_length, temp_index,
+ &sat_cmd_ind_data->data.send_ss.ss_string,
+ &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv;
+
+ /* icon identifier - optional */
+ temp_index += data_len_consumed;
+ if ((cmd_data[temp_index] & 0x7F) == SATK_ICON_IDENTIFIER_TAG) {
+ data_len_consumed = 0;
+
+ rv = _sat_decode_icon_identifier_tlv(o_cmd_data, o_length, temp_index,
+ &sat_cmd_ind_data->data.send_ss.icon_id,
+ &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; /* Send TR */
+ }
+
+ dbg("[SAT] SAT PARSER - :decoding done!.");
+ return TCORE_SAT_SUCCESS;
+}
+
+/*
+ * 6.4.12 SEND USSD
+ */
+static enum tcore_sat_result _sat_decode_send_ussd(unsigned char *o_cmd_data, int o_length,
+ int curr_offset, struct tcore_sat_proactive_command *sat_cmd_ind_data)
+{
+ int temp_index = 0, data_len_consumed = 0;
+ unsigned char dev_id[4];
+ unsigned char *cmd_data = NULL;
+ enum tcore_sat_result rv = TCORE_SAT_SUCCESS;
+
+ if (o_cmd_data == NULL || sat_cmd_ind_data == NULL) {
+ dbg("[SAT] SAT PARSER - o_cmd_data == NULL");
+ return TCORE_SAT_ERROR_FATAL;
+ }
+
+ cmd_data = &o_cmd_data[0];
+ temp_index = curr_offset + 2;
+ sat_cmd_ind_data->data.send_ussd.command_detail.cmd_num = cmd_data[temp_index++];
+ sat_cmd_ind_data->data.send_ussd.command_detail.cmd_type = cmd_data[temp_index++];
+
+ /* command detail */
+ temp_index++; /* RFU */
+
+ /* device identities */
+ memcpy(dev_id, &cmd_data[temp_index], 4);
+ rv = _sat_decode_device_identities_tlv(dev_id, &sat_cmd_ind_data->data.send_ussd.device_id);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv;
+
+ /* alpha identifier - optional */
+ temp_index += 4;
+ if ((cmd_data[temp_index] & 0x7F) == SATK_ALPHA_IDENTIFIER_TAG) {
+ rv = _sat_decode_alpha_identifier_tlv(o_cmd_data, o_length, temp_index,
+ &sat_cmd_ind_data->data.send_ussd.alpha_id,
+ &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv;
+
+ temp_index += data_len_consumed;
+ }
+
+ /* ussd string */
+ rv = _sat_decode_ussd_string_tlv(o_cmd_data, o_length, temp_index,
+ &sat_cmd_ind_data->data.send_ussd.ussd_string,
+ &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv;
+
+ /* icon identifier- optional */
+ temp_index += data_len_consumed;
+ if ((cmd_data[temp_index] & 0x7F) == SATK_ICON_IDENTIFIER_TAG) {
+ data_len_consumed = 0;
+
+ rv = _sat_decode_icon_identifier_tlv(o_cmd_data, o_length, temp_index,
+ &sat_cmd_ind_data->data.send_ussd.icon_id,
+ &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; /* Send TR */
+ }
+
+ dbg("[SAT] SAT PARSER - :decoding done!.");
+ return TCORE_SAT_SUCCESS;
+}
+
+/*
+ * 6.4.13 SETUP CALL
+ */
+static enum tcore_sat_result _sat_decode_setup_call(unsigned char *o_cmd_data, int o_length,
+ int curr_offset, struct tcore_sat_proactive_command *sat_cmd_ind_data)
+{
+ int temp_index = 0, data_len_consumed = 0;
+ unsigned char dev_id[4];
+ unsigned char *cmd_data = NULL;
+ enum tcore_sat_result rv = TCORE_SAT_SUCCESS;
+
+ if (o_cmd_data == NULL || sat_cmd_ind_data == NULL) {
+ dbg("[SAT] SAT PARSER - o_cmd_data == NULL");
+ return TCORE_SAT_ERROR_FATAL;
+ }
+
+ /* command detail */
+ cmd_data = &o_cmd_data[0];
+ temp_index = curr_offset + 2;
+ sat_cmd_ind_data->data.setup_call.command_detail.cmd_num = cmd_data[temp_index++];
+ sat_cmd_ind_data->data.setup_call.command_detail.cmd_type = cmd_data[temp_index++];
+
+ /* decode command qualifier */
+ switch (cmd_data[temp_index]) {
+ case SETUP_CALL_IF_ANOTHER_CALL_NOT_BUSY:
+ case SETUP_CALL_IF_ANOTHER_CALL_NOT_BUSY_WITH_REDIAL:
+ case SETUP_CALL_PUT_ALL_OTHER_CALLS_ON_HOLD:
+ case SETUP_CALL_PUT_ALL_OTHER_CALLS_ON_HOLD_WITH_REDIAL:
+ case SETUP_CALL_DISCONN_ALL_OTHER_CALLS:
+ case SETUP_CALL_DISCONN_ALL_OTHER_CALLS_WITH_REDIAL:
+ sat_cmd_ind_data->data.setup_call.command_detail.cmd_qualifier.setup_call.setup_call = cmd_data[temp_index];
+ dbg("[SAT] SAT PARSER - setup_call.cmd_qualifier= 0x%02x",
+ sat_cmd_ind_data->data.setup_call.command_detail.cmd_qualifier.setup_call.setup_call);
+ break;
+
+ case SETUP_CALL_RESERVED: /* Fallthrough */
+ default:
+ dbg("[SAT] SAT PARSER - setup_call.cmd_qualifier= 0x%02x", cmd_data[temp_index]);
+ return TCORE_SAT_BEYOND_ME_CAPABILITY;
+ }
+
+ /* device identifier */
+ temp_index++;
+ memcpy(dev_id, &cmd_data[temp_index], 4);
+ rv = _sat_decode_device_identities_tlv(dev_id, &sat_cmd_ind_data->data.setup_call.device_id);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv;
+
+ /* alpha identifier (user confirmation) - optional */
+ temp_index += 4;
+ if ((cmd_data[temp_index] & 0x7F) == SATK_ALPHA_IDENTIFIER_TAG) {
+ rv = _sat_decode_alpha_identifier_tlv(o_cmd_data, o_length, temp_index,
+ &sat_cmd_ind_data->data.setup_call.user_confirm_alpha_id,
+ &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv;
+
+ temp_index += data_len_consumed;
+ }
+
+ /* address */
+ rv = _sat_decode_address_tlv(o_cmd_data, o_length, temp_index,
+ &sat_cmd_ind_data->data.setup_call.address,
+ &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv;
+
+ temp_index += data_len_consumed;
+ if (temp_index >= o_length) {
+ dbg("[SAT] SAT PARSER - no more TLVs to decode.");
+ return TCORE_SAT_SUCCESS;
+ }
+
+ /* capability configuration parameter - optional */
+ if ((cmd_data[temp_index] & 0x7F) == SATK_CAPABILITY_CONFIGURATION_PARAMETERS_TAG) {
+ rv = _sat_decode_ccp_tlv(o_cmd_data, o_length, temp_index,
+ &sat_cmd_ind_data->data.setup_call.ccp,
+ &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv; /* Send TR */
+
+ temp_index += data_len_consumed;
+ if (temp_index >= o_length) {
+ dbg("[SAT] SAT PARSER - no more TLVs to decode.");
+ return TCORE_SAT_SUCCESS;
+ }
+ }
+
+ /* sub address - optional */
+ if ((cmd_data[temp_index] & 0x7F) == SATK_SUB_ADDRESS_TAG) {
+ rv = _sat_decode_sub_address_tlv(o_cmd_data, o_length, temp_index,
+ &sat_cmd_ind_data->data.setup_call.subaddress,
+ &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv; /* Send TR */
+
+ temp_index += data_len_consumed;
+ if (temp_index >= o_length) {
+ dbg("[SAT] SAT PARSER - no more TLVs to decode.");
+ return TCORE_SAT_SUCCESS;
+ }
+ }
+
+ /* time duration - optional */
+ if ((cmd_data[temp_index] & 0x7F) == SATK_DURATION_TAG) {
+ rv = _sat_decode_duration_tlv(o_cmd_data, o_length, temp_index,
+ &sat_cmd_ind_data->data.setup_call.duration,
+ &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv; /* Send TR */
+
+ temp_index += data_len_consumed;
+ if (temp_index >= o_length) {
+ dbg("[SAT] SAT PARSER - no more TLVs to decode.");
+ return TCORE_SAT_SUCCESS;
+ }
+ }
+
+ /* icon identifier (user confirmation) - optional */
+ if ((cmd_data[temp_index] & 0x7F) == SATK_ICON_IDENTIFIER_TAG) {
+ data_len_consumed = 0;
+ rv = _sat_decode_icon_identifier_tlv(o_cmd_data, o_length, temp_index,
+ &sat_cmd_ind_data->data.setup_call.user_confirm_icon_id,
+ &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; /* Send TR */
+
+ temp_index += data_len_consumed;
+ if (temp_index >= o_length) {
+ dbg("[SAT] SAT PARSER - no more TLVs to decode.");
+ return TCORE_SAT_SUCCESS;
+ }
+ }
+
+ /* alpha identifier (call setup) - optional */
+ if ((cmd_data[temp_index] & 0x7F) == SATK_ALPHA_IDENTIFIER_TAG) {
+ rv = _sat_decode_alpha_identifier_tlv(o_cmd_data, o_length, temp_index,
+ &sat_cmd_ind_data->data.setup_call.call_setup_alpha_id,
+ &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv;
+
+ temp_index += data_len_consumed;
+ if (temp_index >= o_length) {
+ dbg("[SAT] SAT PARSER - no more TLVs to decode.");
+ return TCORE_SAT_SUCCESS;
+ }
+ }
+
+ /* icon identifier (call setup) - optional */
+ if ((cmd_data[temp_index] & 0x7F) == SATK_ICON_IDENTIFIER_TAG) {
+ data_len_consumed = 0;
+ rv = _sat_decode_icon_identifier_tlv(o_cmd_data, o_length, temp_index,
+ &sat_cmd_ind_data->data.setup_call.call_setup_icon_id,
+ &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; /* Send TR */
+
+ temp_index += data_len_consumed;
+ if (temp_index >= o_length) {
+ dbg("[SAT] SAT PARSER - no more TLVs to decode.");
+ return TCORE_SAT_SUCCESS;
+ }
+ }
+
+ /*
+ * TODO -
+ * Text Attribute (user_confirmation , call_setup)
+ */
+
+ dbg("[SAT] SAT PARSER - :decoding done!.");
+ return TCORE_SAT_SUCCESS;
+}
+
+/*
+ * 6.4.15 PROVIDE LOCAL INFO
+ */
+static enum tcore_sat_result _sat_decode_provide_local_info(unsigned char *o_cmd_data, int o_length,
+ int curr_offset, struct tcore_sat_proactive_command *sat_cmd_ind_data)
+{
+ int temp_index = 0;
+ unsigned char dev_id[4];
+ unsigned char *cmd_data = NULL;
+ enum tcore_sat_result rv = TCORE_SAT_SUCCESS;
+
+ if (o_cmd_data == NULL) {
+ dbg("[SAT] SAT PARSER - o_cmd_data == NULL");
+ return TCORE_SAT_ERROR_FATAL;
+ }
+
+ /* command detail */
+ cmd_data = &o_cmd_data[0];
+ temp_index = curr_offset + 2;
+ sat_cmd_ind_data->data.setup_event_list.command_detail.cmd_num = cmd_data[temp_index++];
+ sat_cmd_ind_data->data.setup_event_list.command_detail.cmd_type = cmd_data[temp_index++];
+
+ /* decode command qualifier */
+ switch (cmd_data[temp_index]) {
+ case LOCAL_INFO_DATE_TIME_AND_TIMEZONE:
+ case LOCAL_INFO_LANGUAGE:
+ sat_cmd_ind_data->data.setup_event_list.command_detail.cmd_qualifier.provide_local_info.provide_local_info = cmd_data[temp_index];
+ break;
+
+ /*
+ * TODO -
+ * Other cases
+ */
+ default:
+ sat_cmd_ind_data->data.setup_event_list.command_detail.cmd_qualifier.provide_local_info.provide_local_info = LOCAL_INFO_RESERVED;
+ break;
+ }
+
+ /* device identifier */
+ temp_index++;
+ memcpy(dev_id, &cmd_data[temp_index], 4);
+ rv = _sat_decode_device_identities_tlv(dev_id, &sat_cmd_ind_data->data.setup_event_list.device_id);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv;
+
+ /*
+ * TODO -
+ * UTRAN Measurement Qualifier
+ */
+
+ dbg("[SAT] SAT PARSER - :decoding done!.");
+ return TCORE_SAT_SUCCESS;
+}
+
+/*
+ * 6.4.16 SETUP EVENT LIST
+ */
+static enum tcore_sat_result _sat_decode_setup_event_list(unsigned char *o_cmd_data, int o_length,
+ int curr_offset, struct tcore_sat_proactive_command *sat_cmd_ind_data)
+{
+ int temp_index = 0, data_len_consumed = 0;
+ unsigned char dev_id[4];
+ unsigned char *cmd_data = NULL;
+ enum tcore_sat_result rv = TCORE_SAT_SUCCESS;
+
+ if (o_cmd_data == NULL) {
+ dbg("[SAT] SAT PARSER - o_cmd_data == NULL");
+ return TCORE_SAT_ERROR_FATAL;
+ }
+
+ /* command detail */
+ cmd_data = &o_cmd_data[0];
+ temp_index = curr_offset + 2;
+ sat_cmd_ind_data->data.setup_event_list.command_detail.cmd_num = cmd_data[temp_index++];
+ sat_cmd_ind_data->data.setup_event_list.command_detail.cmd_type = cmd_data[temp_index++];
+
+ /* device identifier */
+ temp_index++;
+ memcpy(dev_id, &cmd_data[temp_index], 4);
+ rv = _sat_decode_device_identities_tlv(dev_id, &sat_cmd_ind_data->data.setup_event_list.device_id);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv;
+
+ /* event list */
+ temp_index += 4;
+ rv = _sat_decode_event_list_tlv(o_cmd_data, o_length, temp_index,
+ &sat_cmd_ind_data->data.setup_event_list.event_list,
+ &data_len_consumed);
+
+ dbg("[SAT] SAT PARSER - :decoding done!.");
+ return TCORE_SAT_SUCCESS;
+}
+
+/*
+ * 6.4.22 SETUP IDLE MODE TEXT
+ */
+static enum tcore_sat_result _sat_decode_setup_idle_mode_text(unsigned char *o_cmd_data, int o_length,
+ int curr_offset, struct tcore_sat_proactive_command *sat_cmd_ind_data)
+{
+ int temp_index = 0, data_len_consumed = 0;
+ unsigned char dev_id[4];
+ unsigned char *cmd_data = NULL;
+ enum tcore_sat_result rv = TCORE_SAT_SUCCESS;
+
+ if (o_cmd_data == NULL) {
+ dbg("[SAT] SAT PARSER - o_cmd_data == NULL");
+ return TCORE_SAT_ERROR_FATAL;
+ }
+
+ /* command detail */
+ cmd_data = &o_cmd_data[0];
+ temp_index = curr_offset + 2;
+ sat_cmd_ind_data->data.setup_idle_mode_text.command_detail.cmd_num = cmd_data[temp_index++];
+ sat_cmd_ind_data->data.setup_idle_mode_text.command_detail.cmd_type = cmd_data[temp_index++];
+
+ /* device identifier */
+ temp_index++;
+ memcpy(dev_id, &cmd_data[temp_index], 4);
+ rv = _sat_decode_device_identities_tlv(dev_id, &sat_cmd_ind_data->data.setup_idle_mode_text.device_id);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv;
+
+ /* text string */
+ temp_index += 4;
+ rv = _sat_decode_text_tlv(o_cmd_data, o_length, temp_index,
+ &sat_cmd_ind_data->data.setup_idle_mode_text.text,
+ &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv;
+
+ if (sat_cmd_ind_data->data.setup_idle_mode_text.text.string_length < 0) {
+ err("[SAT] SAT PARSER - :string length is less than 0");
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ dbg("[SAT] SAT PARSER text(%s)", sat_cmd_ind_data->data.setup_idle_mode_text.text.string);
+ dbg("[SAT] SAT PARSER o_len(%d) temp_index(%d) data_len_consumed(%d)",
+ o_length , temp_index, data_len_consumed);
+
+ if (temp_index + data_len_consumed > o_length) {
+ err("[SAT] SAT PARSER - Wrong String TLV");
+ return TCORE_SAT_BEYOND_ME_CAPABILITY;
+ } else if (temp_index + data_len_consumed == o_length) {
+ dbg("[SAT] SAT PARSER - :no more TLVs to decode.");
+ return TCORE_SAT_SUCCESS;
+ }
+
+ /* icon identifier */
+ temp_index += data_len_consumed;
+ if ((cmd_data[temp_index] & 0x7F) == SATK_ICON_IDENTIFIER_TAG) {
+ data_len_consumed = 0;
+ rv = _sat_decode_icon_identifier_tlv(o_cmd_data, o_length, temp_index,
+ &sat_cmd_ind_data->data.setup_idle_mode_text.icon_id,
+ &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; /* Send TR */
+
+ if (temp_index + data_len_consumed >= o_length) {
+ dbg("[SAT] SAT PARSER - no more TLVs to decode.");
+ return TCORE_SAT_SUCCESS;
+ }
+
+ temp_index += data_len_consumed; /* temp_index pointing to the Tag of next TLV */
+ }
+
+ /*
+ * TODO:
+ * Text Attribute
+ */
+
+ dbg("[SAT] SAT PARSER - :decoding done!.");
+ return TCORE_SAT_SUCCESS;
+}
+
+/*
+ * 6.4.24 SEND DTMF
+ */
+static enum tcore_sat_result _sat_decode_send_dtmf(unsigned char *o_cmd_data, int o_length,
+ int curr_offset, struct tcore_sat_proactive_command *sat_cmd_ind_data)
+{
+ int temp_index = 0, data_len_consumed = 0;
+ unsigned char dev_id[4];
+ unsigned char *cmd_data = NULL;
+ enum tcore_sat_result rv = TCORE_SAT_SUCCESS;
+
+ if (o_cmd_data == NULL) {
+ dbg("[SAT] SAT PARSER - o_cmd_data == NULL");
+ return TCORE_SAT_ERROR_FATAL;
+ }
+
+ /* command detail */
+ cmd_data = &o_cmd_data[0];
+ temp_index = curr_offset + 2;
+ sat_cmd_ind_data->data.send_dtmf.command_detail.cmd_num = cmd_data[temp_index++];
+ sat_cmd_ind_data->data.send_dtmf.command_detail.cmd_type = cmd_data[temp_index++];
+
+ /* device identifier */
+ temp_index++;
+ memcpy(dev_id, &cmd_data[temp_index], 4);
+ rv = _sat_decode_device_identities_tlv(dev_id, &sat_cmd_ind_data->data.send_dtmf.device_id);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv;
+
+ /* alpha identifier - optional */
+ temp_index += 4;
+ if ((cmd_data[temp_index] & 0x7F) == SATK_ALPHA_IDENTIFIER_TAG) {
+ rv = _sat_decode_alpha_identifier_tlv(o_cmd_data, o_length, temp_index,
+ &sat_cmd_ind_data->data.send_dtmf.alpha_id,
+ &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv;
+
+ temp_index += data_len_consumed;
+ }
+
+ /* DTMF string - mandatory */
+ if ((cmd_data[temp_index] & 0x7F) == SATK_DTMF_STRING_TAG) {
+ rv = _sat_decode_dtmf_string_tlv(o_cmd_data, o_length, temp_index,
+ &sat_cmd_ind_data->data.send_dtmf.dtmf_string,
+ &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv;
+
+ if (temp_index + data_len_consumed >= o_length) {
+ dbg("[SAT] SAT PARSER - no more TLVs to decode.");
+ return TCORE_SAT_SUCCESS;
+ }
+
+ temp_index += data_len_consumed;
+ } else {
+ dbg("[SAT] SAT PARSER - DTMF tlv is missed.");
+ return TCORE_SAT_REQUIRED_VALUE_MISSING;
+ }
+
+ /* icon identifier - optional */
+ if ((cmd_data[temp_index] & 0x7F) == SATK_ICON_IDENTIFIER_TAG) {
+ data_len_consumed = 0;
+ rv = _sat_decode_icon_identifier_tlv(o_cmd_data, o_length, temp_index,
+ &sat_cmd_ind_data->data.send_dtmf.icon_id,
+ &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+
+ if (temp_index + data_len_consumed >= o_length) {
+ dbg("[SAT] SAT PARSER - no more TLVs to decode.");
+ return TCORE_SAT_SUCCESS;
+ }
+
+ temp_index += data_len_consumed; /* temp_index pointing to the Tag of next TLV */
+ }
+
+ /*
+ * TODO:
+ * Text Attribute, Frame Identifier
+ */
+
+ dbg("[SAT] SAT PARSER - :decoding done!.");
+ return TCORE_SAT_SUCCESS;
+}
+
+/*
+ * 6.4.25 LANGUAGE NOTIFICATION
+ */
+static enum tcore_sat_result _sat_decode_language_notification(unsigned char *o_cmd_data, int o_length,
+ int curr_offset, struct tcore_sat_proactive_command *sat_cmd_ind_data)
+{
+ int temp_index = 0;
+ unsigned char dev_id[4];
+ unsigned char *cmd_data = NULL;
+ enum tcore_sat_result rv = TCORE_SAT_SUCCESS;
+
+ if (o_cmd_data == NULL) {
+ dbg("[SAT] SAT PARSER - o_cmd_data == NULL");
+ return TCORE_SAT_ERROR_FATAL;
+ }
+
+ /* command detail */
+ cmd_data = &o_cmd_data[0];
+ temp_index = curr_offset + 2;
+ sat_cmd_ind_data->data.language_notification.command_detail.cmd_num = cmd_data[temp_index++];
+ sat_cmd_ind_data->data.language_notification.command_detail.cmd_type = cmd_data[temp_index++];
+
+ /* decode command qualifier */
+ if (cmd_data[temp_index] & 0x01)
+ sat_cmd_ind_data->data.language_notification.command_detail.cmd_qualifier.language_notification.specific_language = TRUE;
+ else
+ sat_cmd_ind_data->data.language_notification.command_detail.cmd_qualifier.language_notification.specific_language = FALSE;
+
+ /* device identifier */
+ temp_index++;
+ memcpy(dev_id, &cmd_data[temp_index], 4);
+ rv = _sat_decode_device_identities_tlv(dev_id, &sat_cmd_ind_data->data.language_notification.device_id);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv;
+
+ /* language - conditional */
+ temp_index += 4;
+ if (sat_cmd_ind_data->data.language_notification.command_detail.cmd_qualifier.language_notification.specific_language == TRUE) {
+ if ((cmd_data[temp_index] & 0x7F) == SATK_LANGUAGE_TAG) {
+ rv = _sat_decode_language_tlv(cmd_data, o_length, temp_index,
+ &sat_cmd_ind_data->data.language_notification.language);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv;
+ } else {
+ dbg("[SAT] SAT PARSER - Language TLV is required but missing.");
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+ } else {
+ sat_cmd_ind_data->data.language_notification.language = SIM_LANG_UNSPECIFIED;
+ dbg("[SAT] SAT PARSER - non-specific language");
+ }
+
+ dbg("[SAT] SAT PARSER - :decoding done!.");
+ return TCORE_SAT_SUCCESS;
+}
+
+/*
+ * 6.4.26 LAUNCH BROWSER
+ */
+static enum tcore_sat_result _sat_decode_launch_browser(unsigned char *o_cmd_data, int o_length,
+ int curr_offset, struct tcore_sat_proactive_command *sat_cmd_ind_data)
+{
+ int temp_index = 0, data_len_consumed = 0;
+ unsigned char dev_id[4];
+ unsigned char *cmd_data = NULL;
+ enum tcore_sat_result rv = TCORE_SAT_SUCCESS;
+
+ if (o_cmd_data == NULL) {
+ dbg("[SAT] SAT PARSER - o_cmd_data == NULL");
+ return TCORE_SAT_ERROR_FATAL;
+ }
+
+ /* command detail */
+ cmd_data = &o_cmd_data[0];
+ temp_index = curr_offset + 2;
+ sat_cmd_ind_data->data.launch_browser.command_detail.cmd_num = cmd_data[temp_index++];
+ sat_cmd_ind_data->data.launch_browser.command_detail.cmd_type = cmd_data[temp_index++];
+
+ /* decode command qualifier */
+ switch (cmd_data[temp_index]) {
+ case 0x00:
+ sat_cmd_ind_data->data.launch_browser.command_detail.cmd_qualifier.launch_browser.launch_browser =
+ LAUNCH_BROWSER_IF_NOT_ALREADY_LAUNCHED;
+ break;
+
+ case 0x01:
+ sat_cmd_ind_data->data.launch_browser.command_detail.cmd_qualifier.launch_browser.launch_browser =
+ LAUNCH_BROWSER_NOT_USED;
+ break;
+
+ case 0x02:
+ sat_cmd_ind_data->data.launch_browser.command_detail.cmd_qualifier.launch_browser.launch_browser =
+ LAUNCH_BROWSER_USE_EXISTING_BROWSER;
+ break;
+
+ case 0x03:
+ sat_cmd_ind_data->data.launch_browser.command_detail.cmd_qualifier.launch_browser.launch_browser =
+ LAUNCH_BROWSER_CLOSE_AND_LAUNCH_NEW_BROWSER;
+ break;
+
+ case 0x04:
+ sat_cmd_ind_data->data.launch_browser.command_detail.cmd_qualifier.launch_browser.launch_browser =
+ LAUNCH_BROWSER_NOT_USED2;
+ break;
+
+ default:
+ sat_cmd_ind_data->data.launch_browser.command_detail.cmd_qualifier.launch_browser.launch_browser =
+ LAUNCH_BROWSER_RESERVED;
+ break;
+ }
+
+ /* device identifier */
+ temp_index++;
+ memcpy(dev_id, &cmd_data[temp_index], 4);
+ rv = _sat_decode_device_identities_tlv(dev_id, &sat_cmd_ind_data->data.language_notification.device_id);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv;
+
+ temp_index += 4;
+
+ /* Browser Identity TLV - Optional */
+ if ((cmd_data[temp_index] & 0x7F) == SATK_BROWSER_IDENTITY_TAG) {
+ rv = _sat_decode_browser_identity_tlv(o_cmd_data, o_length, temp_index,
+ &sat_cmd_ind_data->data.launch_browser.browser_id,
+ &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv;
+
+ temp_index += data_len_consumed;
+ } else {
+ dbg("[SAT] SAT PARSER - Browser ID NOT present");
+ }
+
+ /* URL TLV - Mandatory */
+ if ((cmd_data[temp_index] & 0x7F) == SATK_URL_TAG) {
+ rv = _sat_decode_url_tlv(o_cmd_data, o_length, temp_index,
+ &sat_cmd_ind_data->data.launch_browser.url,
+ &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv;
+
+ if (temp_index + data_len_consumed >= o_length) {
+ dbg("[SAT] SAT PARSER - No more TLVs to decode, decoding done.");
+ return TCORE_SAT_SUCCESS;
+ } else {
+ dbg("[SAT] SAT PARSER - more TLVs to decode, decoding continue.");
+ temp_index += data_len_consumed;
+ }
+ } else {
+ dbg("[SAT] SAT PARSER - Browser URL NOT present! BUG! this value is mandatory!!!");
+ return TCORE_SAT_REQUIRED_VALUE_MISSING;
+ }
+
+ /* bearer - optional */
+ if ((cmd_data[temp_index] & 0x7F) == SATK_BEARER_TAG) {
+ rv = _sat_decode_bearer_tlv(o_cmd_data, o_length, temp_index,
+ &sat_cmd_ind_data->data.launch_browser.bearer,
+ &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv;
+
+ if (temp_index + data_len_consumed >= o_length) {
+ dbg("[SAT] SAT PARSER - No more TLVs to decode, decoding done.");
+ return TCORE_SAT_SUCCESS;
+ } else
+ temp_index += data_len_consumed;
+ } else {
+ dbg("[SAT] SAT PARSER - Bearer TLV Not present.");
+ }
+
+ /* Provisioning reference file - optional */
+ sat_cmd_ind_data->data.launch_browser.file_ref_count = 0;
+ while ((cmd_data[temp_index] & 0x7F) == SATK_PROVISIONING_REF_FILE_TAG) {
+ if (sat_cmd_ind_data->data.launch_browser.file_ref_count >= SAT_PROVISIONING_REF_MAX_COUNT) {
+ dbg("[SAT] SAT PARSER - More number of PRF entries than can be handled");
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ rv = _sat_decode_provisioning_file_ref_tlv(o_cmd_data, o_length, temp_index,
+ &sat_cmd_ind_data->data.launch_browser.file_list[sat_cmd_ind_data->data.launch_browser.file_ref_count],
+ &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv;
+ else
+ sat_cmd_ind_data->data.launch_browser.file_ref_count++;
+
+ if (temp_index + data_len_consumed >= o_length) {
+ dbg("[SAT] SAT PARSER - No more TLVs to decode, decoding done.");
+ return TCORE_SAT_SUCCESS;
+ } else
+ temp_index += data_len_consumed;
+ }
+
+ /* text string(gateway/proxy identity) - optional */
+ if ((cmd_data[temp_index] & 0x7F) == SATK_TEXT_STRING_TAG) {
+ rv = _sat_decode_text_tlv(o_cmd_data, o_length, temp_index,
+ &sat_cmd_ind_data->data.launch_browser.gateway_proxy_text,
+ &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv;
+
+ if (temp_index + data_len_consumed >= o_length) {
+ dbg("[SAT] SAT PARSER - No more TLVs to decode, decoding done.");
+ return TCORE_SAT_SUCCESS;
+ } else
+ temp_index += data_len_consumed;
+ }
+
+ /* alpha identifier - optional */
+ if ((cmd_data[temp_index] & 0x7F) == SATK_ALPHA_IDENTIFIER_TAG) {
+ rv = _sat_decode_alpha_identifier_tlv(o_cmd_data, o_length, temp_index,
+ &sat_cmd_ind_data->data.launch_browser.user_confirm_alpha_id,
+ &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv;
+
+ if (temp_index + data_len_consumed >= o_length) {
+ dbg("[SAT] SAT PARSER - No more TLVs to decode, decoding done.");
+ return TCORE_SAT_SUCCESS;
+ }
+ temp_index += data_len_consumed;
+ } else {
+ dbg("[SAT] SAT PARSER - No Alpha ID TLV.");
+ }
+
+ /* icon identifier - optional */
+ if ((cmd_data[temp_index] & 0x7F) == SATK_ICON_IDENTIFIER_TAG) {
+ data_len_consumed = 0;
+ rv = _sat_decode_icon_identifier_tlv(o_cmd_data, o_length, temp_index,
+ &sat_cmd_ind_data->data.launch_browser.user_confirm_icon_id,
+ &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+
+ if (temp_index + data_len_consumed >= o_length) {
+ dbg("[SAT] SAT PARSER - no more TLVs to decode.");
+ return TCORE_SAT_SUCCESS;
+ }
+
+ temp_index += data_len_consumed; /* temp_index pointing to the Tag of next TLV */
+ }
+
+ /*
+ * TODO:
+ * Text Attribute, Frame Identifier
+ */
+
+ dbg("[SAT] SAT PARSER - :decoding done!.");
+ return TCORE_SAT_SUCCESS;
+}
+
+/*
+ * 6.4.27 OPEN CHANNEL
+ */
+static enum tcore_sat_result _sat_decode_open_channel(unsigned char *o_cmd_data, int o_length,
+ int curr_offset, struct tcore_sat_proactive_command *sat_cmd_ind_data)
+{
+ int temp_index = 0;
+ gboolean b_1st_duration = FALSE;
+ int bearer_desc_len = 0, data_len_consumed = 0;
+ unsigned char dev_id[4];
+ unsigned char *cmd_data = NULL;
+ enum tcore_sat_result rv = TCORE_SAT_SUCCESS;
+
+ if (o_cmd_data == NULL) {
+ dbg("[SAT] SAT PARSER - o_cmd_data == NULL");
+ return TCORE_SAT_ERROR_FATAL;
+ }
+
+ cmd_data = &o_cmd_data[0];
+ temp_index = curr_offset + 2;
+ sat_cmd_ind_data->data.open_channel.command_detail.cmd_num = cmd_data[temp_index++];
+ sat_cmd_ind_data->data.open_channel.command_detail.cmd_type = cmd_data[temp_index++];
+
+ /* command detail */
+ sat_cmd_ind_data->data.open_channel.command_detail.cmd_qualifier.open_channel.immediate_link = FALSE;
+ sat_cmd_ind_data->data.open_channel.command_detail.cmd_qualifier.open_channel.automatic_reconnection = FALSE;
+ sat_cmd_ind_data->data.open_channel.command_detail.cmd_qualifier.open_channel.background_mode = FALSE;
+
+ if (cmd_data[temp_index] & 0x01) {
+ sat_cmd_ind_data->data.open_channel.command_detail.cmd_qualifier.open_channel.immediate_link = TRUE;
+ dbg("[SAT] SAT PARSER - Immediate Link Establishment");
+ }
+
+ if (cmd_data[temp_index] & 0x02) {
+ sat_cmd_ind_data->data.open_channel.command_detail.cmd_qualifier.open_channel.automatic_reconnection = TRUE;
+ dbg("[SAT] SAT PARSER - Auto Reconnection");
+ }
+
+ if (cmd_data[temp_index] & 0x04) {
+ sat_cmd_ind_data->data.open_channel.command_detail.cmd_qualifier.open_channel.background_mode = TRUE;
+ dbg("[SAT] SAT PARSER - Background mode");
+ }
+
+ /* device identities */
+ temp_index++;
+ memcpy(dev_id, &cmd_data[temp_index], 4);
+ rv = _sat_decode_device_identities_tlv(dev_id,
+ &sat_cmd_ind_data->data.open_channel.device_id);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv;
+
+ /* alpha identifier - optional */
+ temp_index += 4;
+ if ((cmd_data[temp_index] & 0x7F) == SATK_ALPHA_IDENTIFIER_TAG) {
+ rv = _sat_decode_alpha_identifier_tlv(o_cmd_data, o_length, temp_index,
+ &sat_cmd_ind_data->data.open_channel.alpha_id,
+ &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv;
+
+ temp_index += data_len_consumed;
+ }
+
+ /* icon id - optional */
+ if ((cmd_data[temp_index] & 0x7F) == SATK_ICON_IDENTIFIER_TAG) {
+ data_len_consumed = 0;
+ rv = _sat_decode_icon_identifier_tlv(o_cmd_data, o_length, temp_index,
+ &sat_cmd_ind_data->data.open_channel.icon_id,
+ &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv; /* Send TR */
+
+ temp_index += data_len_consumed; /* temp_index pointing to the Tag of next TLV */
+ }
+
+ /* bearer description */
+ rv = _sat_decode_bearer_description_tlv(o_cmd_data, o_length, temp_index,
+ &sat_cmd_ind_data->data.open_channel.bearer_desc,
+ &data_len_consumed);
+ bearer_desc_len = data_len_consumed;
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv;
+
+ /*
+ * TODO -
+ * UICC SERVER MODE
+ */
+
+ switch (sat_cmd_ind_data->data.open_channel.bearer_desc.bearer_type) {
+ case BEARER_CSD:
+ /* address */
+ rv = _sat_decode_address_tlv(o_cmd_data, o_length, temp_index,
+ &sat_cmd_ind_data->data.open_channel.bearer_detail.cs_bearer.address,
+ &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv;
+
+ temp_index += data_len_consumed;
+
+ /* sub address - optional */
+ if ((cmd_data[temp_index] & 0x7F) == SATK_SUB_ADDRESS_TAG) {
+ data_len_consumed = 0;
+ rv = _sat_decode_subaddress_tlv(o_cmd_data, o_length, temp_index,
+ &sat_cmd_ind_data->data.open_channel.bearer_detail.cs_bearer.subaddress,
+ &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv;
+
+ temp_index += data_len_consumed;
+ }
+
+ /* time duration 1- optional */
+ if ((cmd_data[temp_index] & 0x7F) == SATK_DURATION_TAG) {
+ data_len_consumed = 0;
+ rv = _sat_decode_duration_tlv(o_cmd_data, o_length, temp_index,
+ &sat_cmd_ind_data->data.open_channel.bearer_detail.cs_bearer.duration1,
+ &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv; /* Send TR */
+
+ temp_index += data_len_consumed;
+ b_1st_duration = TRUE;
+ }
+
+ /* time duration 2- optional */
+ if ((cmd_data[temp_index] & 0x7F) == SATK_DURATION_TAG) {
+
+ if (!b_1st_duration) {
+ dbg("duration 1 does not present!");
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ data_len_consumed = 0;
+ rv = _sat_decode_duration_tlv(o_cmd_data, o_length, temp_index,
+ &sat_cmd_ind_data->data.open_channel.bearer_detail.cs_bearer.duration2,
+ &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv; /* Send TR */
+
+ temp_index += data_len_consumed;
+ }
+
+ /* bearer description - already did it */
+ temp_index += bearer_desc_len;
+
+ /* buffer size */
+ rv = _sat_decode_buffer_size_tlv(o_cmd_data, o_length, temp_index,
+ &sat_cmd_ind_data->data.open_channel.buffer_size,
+ &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv; /* Send TR */
+
+ temp_index += data_len_consumed;
+ if (temp_index >= o_length) {
+ dbg("[SAT] SAT PARSER - no more TLVs to decode.");
+ return TCORE_SAT_SUCCESS;
+ }
+
+ /* other address - optional */
+ if ((cmd_data[temp_index] & 0x7F) == SATK_OTHER_ADDRESS_TAG) {
+ data_len_consumed = 0;
+ rv = _sat_decode_other_address_tlv(o_cmd_data, o_length, temp_index,
+ &sat_cmd_ind_data->data.open_channel.bearer_detail.cs_bearer.other_address,
+ &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv; /* Send TR */
+
+ temp_index += data_len_consumed;
+ if (temp_index >= o_length) {
+ dbg("[SAT] SAT PARSER - no more TLVs to decode.");
+ return TCORE_SAT_SUCCESS;
+ }
+ }
+
+ /* text string - user login - optional */
+ if ((cmd_data[temp_index] & 0x7F) == SATK_TEXT_STRING_TAG) {
+ data_len_consumed = 0;
+ rv = _sat_decode_text_tlv(o_cmd_data, o_length, temp_index,
+ &sat_cmd_ind_data->data.open_channel.bearer_detail.cs_bearer.text_user_login,
+ &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv;
+
+ temp_index += data_len_consumed;
+ if (temp_index >= o_length) {
+ dbg("[SAT] SAT PARSER - no more TLVs to decode.");
+ return TCORE_SAT_SUCCESS;
+ }
+ }
+
+ /* text string - user password - optional */
+ if ((cmd_data[temp_index] & 0x7F) == SATK_TEXT_STRING_TAG) {
+ data_len_consumed = 0;
+ rv = _sat_decode_text_tlv(o_cmd_data, o_length, temp_index,
+ &sat_cmd_ind_data->data.open_channel.bearer_detail.cs_bearer.text_user_pwd,
+ &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv;
+
+ temp_index += data_len_consumed;
+ if (temp_index >= o_length) {
+ dbg("[SAT] SAT PARSER - no more TLVs to decode.");
+ return TCORE_SAT_SUCCESS;
+ }
+ }
+
+ /* UICC/TERMINAL interface transport level - optional */
+ if ((cmd_data[temp_index] & 0x7F) == SATK_USIM_ME_INTERFACE_TRANSPORT_LEVEL_TAG) {
+ data_len_consumed = 0;
+ rv = _sat_decode_uicc_terminal_interface_tlv(o_cmd_data, o_length, temp_index,
+ &sat_cmd_ind_data->data.open_channel.interface_transport_level,
+ &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv;
+
+ temp_index += data_len_consumed;
+ if (temp_index >= o_length) {
+ dbg("[SAT] SAT PARSER - no more TLVs to decode.");
+ return TCORE_SAT_SUCCESS;
+ }
+ }
+
+ /* destination address - optional */
+ if ((cmd_data[temp_index] & 0x7F) == SATK_OTHER_ADDRESS_TAG) {
+ data_len_consumed = 0;
+ rv = _sat_decode_other_address_tlv(o_cmd_data, o_length, temp_index,
+ &sat_cmd_ind_data->data.open_channel.data_destination_address,
+ &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv; /* Send TR */
+
+ temp_index += data_len_consumed;
+ if (temp_index >= o_length) {
+ dbg("[SAT] SAT PARSER - no more TLVs to decode.");
+ return TCORE_SAT_SUCCESS;
+ }
+ }
+ break;
+
+ case BEARER_GPRS:
+ /* bearer description - already did it */
+ temp_index += bearer_desc_len;
+
+ /* buffer size */
+ rv = _sat_decode_buffer_size_tlv(o_cmd_data, o_length, temp_index,
+ &sat_cmd_ind_data->data.open_channel.buffer_size,
+ &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv; /* Send TR */
+
+ temp_index += data_len_consumed;
+ if (temp_index >= o_length) {
+ dbg("[SAT] SAT PARSER - no more TLVs to decode.");
+ return TCORE_SAT_SUCCESS;
+ }
+
+ /* Network Access Name - optional */
+ if ((cmd_data[temp_index] & 0x7F) == SATK_NETWORK_ACCESS_TAG) {
+ data_len_consumed = 0;
+ rv = _sat_decode_network_access_name_tlv(o_cmd_data, o_length, temp_index,
+ &sat_cmd_ind_data->data.open_channel.bearer_detail.ps_bearer.network_access_name,
+ &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv; /* Send TR */
+
+ temp_index += data_len_consumed;
+ if (temp_index >= o_length) {
+ dbg("[SAT] SAT PARSER - no more TLVs to decode.");
+ return TCORE_SAT_SUCCESS;
+ }
+ }
+
+ /* other address - optional */
+ if ((cmd_data[temp_index] & 0x7F) == SATK_OTHER_ADDRESS_TAG) {
+ data_len_consumed = 0;
+ rv = _sat_decode_other_address_tlv(o_cmd_data, o_length, temp_index,
+ &sat_cmd_ind_data->data.open_channel.bearer_detail.ps_bearer.other_address,
+ &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv; /* Send TR */
+
+ temp_index += data_len_consumed;
+ if (temp_index >= o_length) {
+ dbg("[SAT] SAT PARSER - no more TLVs to decode.");
+ return TCORE_SAT_SUCCESS;
+ }
+ }
+
+ /* text string - user login - optional */
+ if ((cmd_data[temp_index] & 0x7F) == SATK_TEXT_STRING_TAG) {
+ data_len_consumed = 0;
+ rv = _sat_decode_text_tlv(o_cmd_data, o_length, temp_index,
+ &sat_cmd_ind_data->data.open_channel.bearer_detail.ps_bearer.text_user_login,
+ &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv;
+
+ temp_index += data_len_consumed;
+ if (temp_index >= o_length) {
+ dbg("[SAT] SAT PARSER - no more TLVs to decode.");
+ return TCORE_SAT_SUCCESS;
+ }
+ }
+
+ /* text string - user password - optional */
+ if ((cmd_data[temp_index] & 0x7F) == SATK_TEXT_STRING_TAG) {
+ data_len_consumed = 0;
+ rv = _sat_decode_text_tlv(o_cmd_data, o_length, temp_index,
+ &sat_cmd_ind_data->data.open_channel.bearer_detail.ps_bearer.text_user_pwd,
+ &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv;
+
+ temp_index += data_len_consumed;
+ if (temp_index >= o_length) {
+ dbg("[SAT] SAT PARSER - no more TLVs to decode.");
+ return TCORE_SAT_SUCCESS;
+ }
+ }
+
+ /* UICC/TERMINAL interface transport level - optional */
+ if ((cmd_data[temp_index] & 0x7F) == SATK_USIM_ME_INTERFACE_TRANSPORT_LEVEL_TAG) {
+ data_len_consumed = 0;
+ rv = _sat_decode_uicc_terminal_interface_tlv(o_cmd_data, o_length, temp_index,
+ &sat_cmd_ind_data->data.open_channel.interface_transport_level,
+ &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv;
+
+ temp_index += data_len_consumed;
+ if (temp_index >= o_length) {
+ dbg("[SAT] SAT PARSER - no more TLVs to decode.");
+ return TCORE_SAT_SUCCESS;
+ }
+ }
+
+ dbg("the value (0x%x) after interface transport level", cmd_data[temp_index] & 0x7F);
+
+ /* destination address - optional */
+ if ((cmd_data[temp_index] & 0x7F) == SATK_OTHER_ADDRESS_TAG) {
+ data_len_consumed = 0;
+ rv = _sat_decode_other_address_tlv(o_cmd_data, o_length, temp_index,
+ &sat_cmd_ind_data->data.open_channel.data_destination_address,
+ &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv; /* Send TR */
+
+ temp_index += data_len_consumed;
+ if (temp_index >= o_length) {
+ dbg("[SAT] SAT PARSER - no more TLVs to decode.");
+ return TCORE_SAT_SUCCESS;
+ }
+ }
+ break;
+
+ case BEARER_DEFAULT_BEARER_FROM_TRANSPORT_LAYER:
+ /* bearer description - already did it */
+ temp_index += bearer_desc_len;
+
+ /* buffer size */
+ rv = _sat_decode_buffer_size_tlv(o_cmd_data, o_length, temp_index,
+ &sat_cmd_ind_data->data.open_channel.buffer_size,
+ &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv; /* Send TR */
+
+ temp_index += data_len_consumed;
+ if (temp_index >= o_length) {
+ dbg("[SAT] SAT PARSER - no more TLVs to decode.");
+ return TCORE_SAT_SUCCESS;
+ }
+
+ /* other address - optional */
+ if ((cmd_data[temp_index] & 0x7F) == SATK_OTHER_ADDRESS_TAG) {
+ data_len_consumed = 0;
+ rv = _sat_decode_other_address_tlv(o_cmd_data, o_length, temp_index,
+ &sat_cmd_ind_data->data.open_channel.bearer_detail.default_bearer.other_address,
+ &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv; /* Send TR */
+
+ temp_index += data_len_consumed;
+ if (temp_index >= o_length) {
+ dbg("[SAT] SAT PARSER - no more TLVs to decode.");
+ return TCORE_SAT_SUCCESS;
+ }
+ }
+
+ /* text string - user login - optional */
+ if ((cmd_data[temp_index] & 0x7F) == SATK_TEXT_STRING_TAG) {
+ data_len_consumed = 0;
+ rv = _sat_decode_text_tlv(o_cmd_data, o_length, temp_index,
+ &sat_cmd_ind_data->data.open_channel.bearer_detail.default_bearer.text_user_login,
+ &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv;
+
+ temp_index += data_len_consumed;
+ if (temp_index >= o_length) {
+ dbg("[SAT] SAT PARSER - no more TLVs to decode.");
+ return TCORE_SAT_SUCCESS;
+ }
+ }
+
+ /* text string - user password - optional */
+ if ((cmd_data[temp_index] & 0x7F) == SATK_TEXT_STRING_TAG) {
+ data_len_consumed = 0;
+ rv = _sat_decode_text_tlv(o_cmd_data, o_length, temp_index,
+ &sat_cmd_ind_data->data.open_channel.bearer_detail.default_bearer.text_user_pwd,
+ &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv;
+
+ temp_index += data_len_consumed;
+ if (temp_index >= o_length) {
+ dbg("[SAT] SAT PARSER - no more TLVs to decode.");
+ return TCORE_SAT_SUCCESS;
+ }
+ }
+
+ /* UICC/TERMINAL interface transport level - optional */
+ if ((cmd_data[temp_index] & 0x7F) == SATK_USIM_ME_INTERFACE_TRANSPORT_LEVEL_TAG) {
+ data_len_consumed = 0;
+ rv = _sat_decode_uicc_terminal_interface_tlv(o_cmd_data, o_length, temp_index,
+ &sat_cmd_ind_data->data.open_channel.interface_transport_level,
+ &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv;
+
+ temp_index += data_len_consumed;
+ if (temp_index >= o_length) {
+ dbg("[SAT] SAT PARSER - no more TLVs to decode.");
+ return TCORE_SAT_SUCCESS;
+ }
+ }
+
+ /* destination address - optional */
+ if ((cmd_data[temp_index] & 0x7F) == SATK_OTHER_ADDRESS_TAG) {
+ data_len_consumed = 0;
+ rv = _sat_decode_other_address_tlv(o_cmd_data, o_length, temp_index,
+ &sat_cmd_ind_data->data.open_channel.data_destination_address,
+ &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv; /* Send TR */
+
+ temp_index += data_len_consumed;
+ if (temp_index >= o_length) {
+ dbg("[SAT] SAT PARSER - no more TLVs to decode.");
+ return TCORE_SAT_SUCCESS;
+ }
+ }
+ break;
+
+ case BEARER_LOCAL_LINK_TECHNOLOGY_INDEPENDENT:
+ /* time duration 1- optional */
+ if ((cmd_data[temp_index] & 0x7F) == SATK_DURATION_TAG) {
+ data_len_consumed = 0;
+ rv = _sat_decode_duration_tlv(o_cmd_data, o_length, temp_index,
+ &sat_cmd_ind_data->data.open_channel.bearer_detail.local_bearer.duration1,
+ &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv; /* Send TR */
+
+ temp_index += data_len_consumed;
+ b_1st_duration = TRUE;
+ }
+
+ /* time duration 2- optional */
+ if ((cmd_data[temp_index] & 0x7F) == SATK_DURATION_TAG) {
+ if (!b_1st_duration) {
+ dbg("duration 1 does not present!");
+ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD;
+ }
+
+ data_len_consumed = 0;
+ rv = _sat_decode_duration_tlv(o_cmd_data, o_length, temp_index,
+ &sat_cmd_ind_data->data.open_channel.bearer_detail.local_bearer.duration2,
+ &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv; /* Send TR */
+
+ temp_index += data_len_consumed;
+ }
+
+ /* bearer description - already did it */
+ temp_index += bearer_desc_len;
+
+ /* buffer size */
+ rv = _sat_decode_buffer_size_tlv(o_cmd_data, o_length, temp_index,
+ &sat_cmd_ind_data->data.open_channel.buffer_size,
+ &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv; /* Send TR */
+
+ temp_index += data_len_consumed;
+ if (temp_index >= o_length) {
+ dbg("[SAT] SAT PARSER - no more TLVs to decode.");
+ return TCORE_SAT_SUCCESS;
+ }
+
+ /* text string - user password - optional */
+ if ((cmd_data[temp_index] & 0x7F) == SATK_TEXT_STRING_TAG) {
+ data_len_consumed = 0;
+ rv = _sat_decode_text_tlv(o_cmd_data, o_length, temp_index,
+ &sat_cmd_ind_data->data.open_channel.bearer_detail.local_bearer.text_user_pwd,
+ &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv;
+
+ temp_index += data_len_consumed;
+ if (temp_index >= o_length) {
+ dbg("[SAT] SAT PARSER - no more TLVs to decode.");
+ return TCORE_SAT_SUCCESS;
+ }
+ }
+
+ /* UICC/TERMINAL interface transport level - optional */
+ if ((cmd_data[temp_index] & 0x7F) == SATK_USIM_ME_INTERFACE_TRANSPORT_LEVEL_TAG) {
+ data_len_consumed = 0;
+ rv = _sat_decode_uicc_terminal_interface_tlv(o_cmd_data, o_length, temp_index,
+ &sat_cmd_ind_data->data.open_channel.interface_transport_level,
+ &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv;
+
+ temp_index += data_len_consumed;
+ if (temp_index >= o_length) {
+ dbg("[SAT] SAT PARSER - no more TLVs to decode.");
+ return TCORE_SAT_SUCCESS;
+ }
+ }
+
+ /* destination address - optional */
+ if ((cmd_data[temp_index] & 0x7F) == SATK_OTHER_ADDRESS_TAG) {
+ data_len_consumed = 0;
+ rv = _sat_decode_other_address_tlv(o_cmd_data, o_length, temp_index,
+ &sat_cmd_ind_data->data.open_channel.data_destination_address,
+ &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv; /* Send TR */
+
+ temp_index += data_len_consumed;
+ if (temp_index >= o_length) {
+ dbg("[SAT] SAT PARSER - no more TLVs to decode.");
+ return TCORE_SAT_SUCCESS;
+ }
+ }
+
+ /* remote entity address - optional */
+ if ((cmd_data[temp_index] & 0x7F) == SATK_REMOTE_ENTITY_ADDRESS_TAG) {
+ data_len_consumed = 0;
+ rv = _sat_decode_remote_entity_address_tlv(o_cmd_data, o_length, temp_index,
+ &sat_cmd_ind_data->data.open_channel.bearer_detail.local_bearer.remote_entity_address,
+ &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv; /* Send TR */
+
+ temp_index += data_len_consumed;
+ if (temp_index >= o_length) {
+ dbg("[SAT] SAT PARSER - no more TLVs to decode.");
+ return TCORE_SAT_SUCCESS;
+ }
+ }
+ break;
+
+ default:
+ break;
+ } /* end of switch */
+
+ dbg("[SAT] SAT PARSER - :decoding done!.");
+ return TCORE_SAT_SUCCESS;
+}
+
+/*
+ * 6.4.28 CLOSE CHANNEL
+ */
+static enum tcore_sat_result _sat_decode_close_channel(unsigned char *o_cmd_data, int o_length,
+ int curr_offset, struct tcore_sat_proactive_command *sat_cmd_ind_data)
+{
+ int temp_index = 0;
+ int data_len_consumed = 0;
+ unsigned char dev_id[4];
+ unsigned char *cmd_data = NULL;
+ enum tcore_sat_result rv = TCORE_SAT_SUCCESS;
+
+ if (o_cmd_data == NULL) {
+ dbg("[SAT] SAT PARSER - o_cmd_data == NULL");
+ return TCORE_SAT_ERROR_FATAL;
+ }
+
+ cmd_data = &o_cmd_data[0];
+ temp_index = curr_offset + 2;
+ sat_cmd_ind_data->data.close_channel.command_detail.cmd_num = cmd_data[temp_index++];
+ sat_cmd_ind_data->data.close_channel.command_detail.cmd_type = cmd_data[temp_index++];
+
+ /* command detail */
+ temp_index++; /* RFU */
+
+ /* device identities */
+ memcpy(dev_id, &cmd_data[temp_index], 4);
+ rv = _sat_decode_device_identities_tlv(dev_id, &sat_cmd_ind_data->data.close_channel.device_id);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv;
+
+ /* alpha identifier - optional */
+ temp_index += 4;
+ if ((cmd_data[temp_index] & 0x7F) == SATK_ALPHA_IDENTIFIER_TAG) {
+ rv = _sat_decode_alpha_identifier_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.close_channel.alpha_id, &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv;
+
+ temp_index += data_len_consumed;
+ }
+
+ /* icon id - optional */
+ if ((cmd_data[temp_index] & 0x7F) == SATK_ICON_IDENTIFIER_TAG) {
+ data_len_consumed = 0;
+ rv = _sat_decode_icon_identifier_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.close_channel.icon_id, &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv; /* Send TR */
+
+ temp_index += data_len_consumed; /* temp_index pointing to the Tag of next TLV */
+ }
+
+ /*
+ * TODO:
+ * Text Attribute and frames
+ */
+
+ dbg("[SAT] SAT PARSER - :decoding done!.");
+ return TCORE_SAT_SUCCESS;
+}
+
+/*
+ * 6.4.29 RECEIVE DATA
+ */
+static enum tcore_sat_result _sat_decode_receive_data(unsigned char *o_cmd_data, int o_length,
+ int curr_offset, struct tcore_sat_proactive_command *sat_cmd_ind_data)
+{
+ int temp_index = 0;
+ int data_len_consumed = 0;
+ unsigned char dev_id[4];
+ unsigned char *cmd_data = NULL;
+ enum tcore_sat_result rv = TCORE_SAT_SUCCESS;
+
+ if (o_cmd_data == NULL) {
+ dbg("[SAT] SAT PARSER - o_cmd_data == NULL");
+ return TCORE_SAT_ERROR_FATAL;
+ }
+
+ cmd_data = &o_cmd_data[0];
+ temp_index = curr_offset + 2;
+ sat_cmd_ind_data->data.receive_data.command_detail.cmd_num = cmd_data[temp_index++];
+ sat_cmd_ind_data->data.receive_data.command_detail.cmd_type = cmd_data[temp_index++];
+
+ /* command detail */
+ temp_index++; /* RFU */
+
+ /* device identities */
+ memcpy(dev_id, &cmd_data[temp_index], 4);
+ rv = _sat_decode_device_identities_tlv(dev_id, &sat_cmd_ind_data->data.receive_data.device_id);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv;
+
+ /* alpha identifier - optional */
+ temp_index += 4;
+ if ((cmd_data[temp_index] & 0x7F) == SATK_ALPHA_IDENTIFIER_TAG) {
+ rv = _sat_decode_alpha_identifier_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.receive_data.alpha_id, &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv;
+
+ temp_index += data_len_consumed;
+ }
+
+ /* icon id - optional */
+ if ((cmd_data[temp_index] & 0x7F) == SATK_ICON_IDENTIFIER_TAG) {
+ data_len_consumed = 0;
+ rv = _sat_decode_icon_identifier_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.receive_data.icon_id, &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv; /* Send TR */
+
+ temp_index += data_len_consumed; /* temp_index pointing to the Tag of next TLV */
+ }
+
+ /* channel data length */
+ rv = _sat_decode_channel_data_length_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.receive_data.channel_data_len, &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv; /* Send TR */
+
+ /*
+ * TODO:
+ * Text Attribute and frames
+ */
+
+ dbg("[SAT] SAT PARSER - :decoding done!.");
+ return TCORE_SAT_SUCCESS;
+}
+
+/*
+ * 6.4.30 SEND DATA
+ */
+static enum tcore_sat_result _sat_decode_send_data(unsigned char *o_cmd_data, int o_length,
+ int curr_offset, struct tcore_sat_proactive_command *sat_cmd_ind_data)
+{
+ int temp_index = 0;
+ int data_len_consumed = 0;
+ unsigned char dev_id[4];
+ unsigned char *cmd_data = NULL;
+ enum tcore_sat_result rv = TCORE_SAT_SUCCESS;
+
+ if (o_cmd_data == NULL) {
+ dbg("[SAT] SAT PARSER - o_cmd_data == NULL");
+ return TCORE_SAT_ERROR_FATAL;
+ }
+
+ cmd_data = &o_cmd_data[0];
+ temp_index = curr_offset + 2;
+ sat_cmd_ind_data->data.send_data.command_detail.cmd_num = cmd_data[temp_index++];
+ sat_cmd_ind_data->data.send_data.command_detail.cmd_type = cmd_data[temp_index++];
+
+ /* command detail */
+ sat_cmd_ind_data->data.send_data.command_detail.cmd_qualifier.send_data.send_data_immediately = FALSE;
+ if (cmd_data[temp_index] & 0x01) {
+ sat_cmd_ind_data->data.send_data.command_detail.cmd_qualifier.send_data.send_data_immediately = TRUE;
+ dbg("[SAT] SAT PARSER - Send data immediately");
+ }
+
+ /* device identities */
+ temp_index++;
+ memcpy(dev_id, &cmd_data[temp_index], 4);
+ rv = _sat_decode_device_identities_tlv(dev_id, &sat_cmd_ind_data->data.send_data.device_id);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv;
+
+ /* alpha identifier - optional */
+ temp_index += 4;
+ if ((cmd_data[temp_index] & 0x7F) == SATK_ALPHA_IDENTIFIER_TAG) {
+ rv = _sat_decode_alpha_identifier_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.send_data.alpha_id, &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv;
+
+ temp_index += data_len_consumed;
+ }
+
+ /* icon id - optional */
+ if ((cmd_data[temp_index] & 0x7F) == SATK_ICON_IDENTIFIER_TAG) {
+ data_len_consumed = 0;
+ rv = _sat_decode_icon_identifier_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.send_data.icon_id, &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv; /* Send TR */
+
+ temp_index += data_len_consumed; /* temp_index pointing to the Tag of next TLV */
+ }
+
+ /* channel data */
+ rv = _sat_decode_channel_data_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.send_data.channel_data, &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv; /* Send TR */
+
+ /*
+ * TODO:
+ * Text Attribute and frames
+ */
+
+ dbg("[SAT] SAT PARSER - :decoding done!.");
+ return TCORE_SAT_SUCCESS;
+}
+
+/*
+ * 6.4.31 GET CHANNEL STATUS
+ */
+static enum tcore_sat_result _sat_decode_get_channel_status(unsigned char *o_cmd_data, int o_length,
+ int curr_offset, struct tcore_sat_proactive_command *sat_cmd_ind_data)
+{
+ int temp_index = 0;
+ unsigned char dev_id[4];
+ unsigned char *cmd_data = NULL;
+ enum tcore_sat_result rv = TCORE_SAT_SUCCESS;
+
+ if (o_cmd_data == NULL) {
+ dbg("[SAT] SAT PARSER - o_cmd_data == NULL");
+ return TCORE_SAT_ERROR_FATAL;
+ }
+
+ cmd_data = &o_cmd_data[0];
+ temp_index = curr_offset + 2;
+ sat_cmd_ind_data->data.get_channel_status.command_detail.cmd_num = cmd_data[temp_index++];
+ sat_cmd_ind_data->data.get_channel_status.command_detail.cmd_type = cmd_data[temp_index++];
+
+ /* command detail */
+ temp_index++; /* RFU */
+
+ /* device identities */
+ memcpy(dev_id, &cmd_data[temp_index], 4);
+ rv = _sat_decode_device_identities_tlv(dev_id, &sat_cmd_ind_data->data.get_channel_status.device_id);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv;
+
+ dbg("[SAT] SAT PARSER - :decoding done!.");
+ return TCORE_SAT_SUCCESS;
+}
+
+/*
+ * 6.4.XX Unsupported Command
+ */
+static enum tcore_sat_result _sat_decode_unsupported_command(unsigned char *o_cmd_data, int o_length,
+ int curr_offset, struct tcore_sat_proactive_command *sat_cmd_ind_data)
+{
+ int temp_index = 0;
+ unsigned char dev_id[4];
+ unsigned char *cmd_data = NULL;
+ enum tcore_sat_result rv = TCORE_SAT_SUCCESS;
+
+ if (o_cmd_data == NULL) {
+ dbg("[SAT] SAT PARSER - o_cmd_data == NULL");
+ return TCORE_SAT_ERROR_FATAL;
+ }
+
+ cmd_data = &o_cmd_data[0];
+ temp_index = curr_offset + 2;
+ sat_cmd_ind_data->data.unsupport_cmd.command_detail.cmd_num = cmd_data[temp_index++];
+ sat_cmd_ind_data->data.unsupport_cmd.command_detail.cmd_type = cmd_data[temp_index++];
+
+ /* command detail */
+ temp_index++; /* RFU */
+
+ /* device identities */
+ memcpy(dev_id, &cmd_data[temp_index], 4);
+ rv = _sat_decode_device_identities_tlv(dev_id, &sat_cmd_ind_data->data.unsupport_cmd.device_id);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv;
+
+ dbg("[SAT] SAT PARSER - :decoding done!.");
+ return TCORE_SAT_SUCCESS;
+}
+
+int tcore_sat_decode_proactive_command(unsigned char *tlv_origin, unsigned int tlv_length,
+ struct tcore_sat_proactive_command *decoded_tlv)
+{
+ unsigned int temp_index = 0;
+ int length_field_len = 0;
+ enum tcore_sat_result rv = TCORE_SAT_SUCCESS;
+
+ if (tlv_origin == NULL || tlv_length <= 2) {
+ dbg("[SAT] SAT PARSER - pointer pData passed is NULL or invalid length.");
+ return TCORE_SAT_ERROR_FATAL;
+ }
+
+ /* tag */
+ if (tlv_origin[temp_index++] != SATK_PROACTIVE_CMD_TAG) {
+ dbg("[SAT] SAT PARSER - Did not find Proactive command tag.tag=%d", tlv_origin[temp_index-1]);
+ return TCORE_SAT_ERROR_FATAL;
+ }
+
+ /* length */
+ length_field_len = _get_length_filed_size(tlv_origin[temp_index]);
+ if (length_field_len == 0) {
+ dbg("[SAT] SAT PARSER - Invalid length.");
+ return TCORE_SAT_ERROR_FATAL;
+ }
+
+ /* length */
+ dbg("[SAT] SAT PARSER - tlv_length=%d", tlv_length);
+ temp_index += length_field_len;
+
+ /* check command validation */
+ if (tlv_length < temp_index + 5 + 4)/* command detail(5) and device identities(4) */
+ return TCORE_SAT_ERROR_FATAL;
+
+ /* check comprehensive value */
+ if ((tlv_origin[temp_index] | 0x7F) != 0x7F) {
+ dbg("comprehensive value 0x%x", tlv_origin[temp_index] | 0x7F);
+ b_comprehensive = TRUE;
+ }
+
+ if ((tlv_origin[temp_index] & 0x7F) != SATK_COMMAND_DETAILS_TAG) {
+ err("[SAT] no command detail info");
+ return TCORE_SAT_ERROR_FATAL;
+ }
+
+ if (tlv_origin[temp_index + 1] != SATK_COMMAND_DETAILS_LENGTH) {
+ err("[SAT] invalid command detail length");
+ return TCORE_SAT_ERROR_FATAL;
+ }
+
+ decoded_tlv->cmd_num = tlv_origin[temp_index + 2];
+ decoded_tlv->cmd_type = tlv_origin[temp_index + 3];
+
+ switch (decoded_tlv->cmd_type) {
+ case SAT_PROATV_CMD_DISPLAY_TEXT: /* 6.4.1 */
+ dbg("[SAT] SAT PARSER - SAT_CMD_TYPE_DISPLAY_TEXT");
+ rv = _sat_decode_display_text(tlv_origin, tlv_length, temp_index, decoded_tlv);
+ break;
+
+ case SAT_PROATV_CMD_GET_INKEY: /* 6.4.2 */
+ dbg("[SAT] SAT PARSER - SAT_CMD_TYPE_GET_INKEY");
+ rv = _sat_decode_get_inkey(tlv_origin, tlv_length, temp_index, decoded_tlv);
+ break;
+
+ case SAT_PROATV_CMD_GET_INPUT: /* 6.4.3 */
+ dbg("[SAT] SAT PARSER - SAT_CMD_TYPE_GET_INPUT");
+ rv = _sat_decode_get_input(tlv_origin, tlv_length, temp_index, decoded_tlv);
+ break;
+
+ case SAT_PROATV_CMD_MORE_TIME: /* 6.4.4 */
+ dbg("[SAT] SAT PARSER - SAT_CMD_TYPE_MORE_TIME");
+ rv = _sat_decode_more_time(tlv_origin, tlv_length, temp_index, decoded_tlv);
+ break;
+
+ case SAT_PROATV_CMD_PLAY_TONE: /* 6.4.5 */
+ dbg("[SAT] SAT PARSER - SAT_CMD_TYPE_PLAY TONE");
+ rv = _sat_decode_play_tone(tlv_origin, tlv_length, temp_index, decoded_tlv);
+ break;
+
+ /* case POLL INTERVAL //6.4.6 processing by cp */
+ case SAT_PROATV_CMD_REFRESH: /* 6.4.7 */
+ dbg("[SAT] SAT PARSER - SAT_CMD_TYPE_REFRESH");
+ rv = _sat_decode_refresh(tlv_origin, tlv_length, temp_index, decoded_tlv);
+ break;
+
+ case SAT_PROATV_CMD_SETUP_MENU: /* 6.4.8 */
+ dbg("[SAT] SAT PARSER - SAT_PROATV_CMD_SETUP_MENU");
+ rv = _sat_decode_setup_menu(tlv_origin, tlv_length, temp_index, decoded_tlv);
+ break;
+
+ case SAT_PROATV_CMD_SELECT_ITEM: /* 6.4.9 */
+ dbg("[SAT] SAT PARSER - SAT_CMD_TYPE_SELECT_ITEM");
+ rv = _sat_decode_select_item(tlv_origin, tlv_length, temp_index, decoded_tlv);
+ break;
+
+ case SAT_PROATV_CMD_SEND_SMS: /* 6.4.10 */
+ dbg("[SAT] SAT PARSER - SAT_CMD_TYPE_SEND_SMS");
+ rv = _sat_decode_send_sms(tlv_origin, tlv_length, temp_index, decoded_tlv);
+ break;
+
+ case SAT_PROATV_CMD_SEND_SS: /* 6.4.11 */
+ dbg("[SAT] SAT PARSER - SAT_CMD_TYPE_SEND_SS");
+ rv = _sat_decode_send_ss(tlv_origin, tlv_length, temp_index, decoded_tlv);
+ break;
+
+ case SAT_PROATV_CMD_SEND_USSD: /* 6.4.12 */
+ dbg("[SAT] SAT PARSER - SAT_CMD_TYPE_SEND_USSD");
+ rv = _sat_decode_send_ussd(tlv_origin, tlv_length, temp_index, decoded_tlv);
+ break;
+
+ case SAT_PROATV_CMD_SETUP_CALL: /* 6.4.13 */
+ dbg("[SAT] SAT PARSER - SAT_CMD_TYPE_SETUP_CALL");
+ rv = _sat_decode_setup_call(tlv_origin, tlv_length, temp_index, decoded_tlv);
+ break;
+
+ case SAT_PROATV_CMD_PROVIDE_LOCAL_INFO: /* 6.4.15 */
+ dbg("[SAT] SAT PARSER - SAT_PROATV_CMD_PROVIDE_LOCAL_INFO");
+ rv = _sat_decode_provide_local_info(tlv_origin, tlv_length, temp_index, decoded_tlv);
+ break;
+
+ case SAT_PROATV_CMD_SETUP_EVENT_LIST: /* 6.4.16 */
+ dbg("[SAT] SAT PARSER - SAT_CMD_TYPE_SETUP_EVENT_LIST");
+ rv = _sat_decode_setup_event_list(tlv_origin, tlv_length, temp_index, decoded_tlv);
+ break;
+
+ case SAT_PROATV_CMD_SETUP_IDLE_MODE_TEXT: /* 6.4.22 */
+ dbg("[SAT] SAT PARSER - SAT_PROATV_CMD_SETUP_IDLE_MODE_TEXT");
+ rv = _sat_decode_setup_idle_mode_text(tlv_origin, tlv_length, temp_index, decoded_tlv);
+ break;
+
+ case SAT_PROATV_CMD_SEND_DTMF: /* 6.4.24 */
+ dbg("[SAT] SAT PARSER - SAT_PROATV_CMD_SEND_DTMF");
+ rv = _sat_decode_send_dtmf(tlv_origin, tlv_length, temp_index, decoded_tlv);
+ break;
+
+ case SAT_PROATV_CMD_LANGUAGE_NOTIFICATION: /* 6.4.25 */
+ dbg("[SAT] SAT PARSER - SAT_PROATV_CMD_LANGUAGE_NOTIFICATION");
+ rv = _sat_decode_language_notification(tlv_origin, tlv_length, temp_index, decoded_tlv);
+ break;
+
+ case SAT_PROATV_CMD_LAUNCH_BROWSER: /* 6.4.26 */
+ dbg("[SAT] SAT PARSER - SAT_PROATV_CMD_LAUNCH_BROWSER");
+ rv = _sat_decode_launch_browser(tlv_origin, tlv_length, temp_index, decoded_tlv);
+ break;
+
+ case SAT_PROATV_CMD_OPEN_CHANNEL:/* 6.4.27 */
+ dbg("[SAT] SAT PARSER - SAT_CMD_TYPE_OPEN_CHANNEL");
+ rv = _sat_decode_open_channel(tlv_origin, tlv_length, temp_index, decoded_tlv);
+ break;
+
+ case SAT_PROATV_CMD_CLOSE_CHANNEL:/* 6.4.28 */
+ dbg("[SAT] SAT PARSER - SAT_CMD_TYPE_CLOSE_CHANNEL");
+ rv = _sat_decode_close_channel(tlv_origin, tlv_length, temp_index, decoded_tlv);
+ break;
+
+ case SAT_PROATV_CMD_RECEIVE_DATA:/* 6.4.29 */
+ dbg("[SAT] SAT PARSER - SAT_CMD_TYPE_RECEIVE_DATA");
+ rv = _sat_decode_receive_data(tlv_origin, tlv_length, temp_index, decoded_tlv);
+ break;
+
+ case SAT_PROATV_CMD_SEND_DATA:/* 6.4.30 */
+ dbg("[SAT] SAT PARSER - SAT_CMD_TYPE_SEND_DATA");
+ rv = _sat_decode_send_data(tlv_origin, tlv_length, temp_index, decoded_tlv);
+ break;
+
+ case SAT_PROATV_CMD_GET_CHANNEL_STATUS:/* 6.4.31 */
+ dbg("[SAT] SAT PARSER - SAT_CMD_TYPE_GET_CHANNEL_STATUS");
+ rv = _sat_decode_get_channel_status(tlv_origin, tlv_length, temp_index, decoded_tlv);
+ break;
+
+ default:
+ dbg("[SAT] SAT PARSER - ME cannot perform this command =0x[%02x]", decoded_tlv->cmd_type);
+ rv = _sat_decode_unsupported_command(tlv_origin, tlv_length, temp_index, decoded_tlv);
+ break;
+ }
+
+ dbg("[SAT] SAT PARSER - each command parsing done.");
+ return rv;
+}
+
+int tcore_sat_decode_call_control_result(unsigned char *tlv_origin, unsigned int tlv_length, struct tnoti_sat_call_control_result_ind *call_ctrl_result_tlv)
+{
+ unsigned int temp_index = 0;
+ int length = 0, data_len = 0, data_len_consumed = 0;
+ enum tcore_sat_result rv = TCORE_SAT_SUCCESS;
+
+ if (tlv_origin == NULL || tlv_length <= 2) {
+ dbg("[SAT] SAT PARSER - pointer pData passed is NULL or invalid length.");
+ return TCORE_SAT_ERROR_FATAL;
+ }
+
+ /* call conrol result */
+ call_ctrl_result_tlv->cc_result = tlv_origin[temp_index++];
+ length = _get_length_filed_size(tlv_origin[temp_index]);
+ if (length == 0) {
+ dbg("[SAT] fail to get the call control result length");
+ return TCORE_SAT_ERROR_FATAL;
+ }
+
+ temp_index = temp_index + length-1;
+ data_len = tlv_origin[temp_index];
+ dbg("[SAT] call control result (%d), data len(%d)", call_ctrl_result_tlv->cc_result, data_len);
+ if (data_len == 0) {
+ dbg("no more call control result - decoding done");
+ return rv;
+ }
+ temp_index++;
+
+ /* address - optional (voice call) */
+ if ((tlv_origin[temp_index] & 0x7F) == SATK_ADDRESS_TAG) {
+ rv = _sat_decode_address_tlv(tlv_origin, tlv_length, temp_index, &call_ctrl_result_tlv->address, &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv;
+
+ temp_index += data_len_consumed;
+
+ if (temp_index >= tlv_length) {
+ dbg("[SAT] call control decoding done");
+ return TCORE_SAT_SUCCESS;
+ }
+ }
+
+ /* ss string - optional (ss) */
+ if ((tlv_origin[temp_index] & 0x7F) == SATK_SS_STRING_TAG) {
+ rv = _sat_decode_ss_string_tlv(tlv_origin, tlv_length, temp_index, &call_ctrl_result_tlv->ss_string, &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv;
+
+ temp_index += data_len_consumed;
+
+ if (temp_index >= tlv_length) {
+ dbg("[SAT] call control decoding done");
+ return TCORE_SAT_SUCCESS;
+ }
+ }
+
+ /* ccp1 - optional */
+ if ((tlv_origin[temp_index] & 0x7F) == SATK_CAPABILITY_CONFIGURATION_PARAMETERS_TAG) {
+ rv = _sat_decode_ccp_tlv(tlv_origin, tlv_length, temp_index, &call_ctrl_result_tlv->ccp1, &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv; /* Send TR */
+
+ temp_index += data_len_consumed;
+
+ if (temp_index >= tlv_length) {
+ dbg("[SAT] call control decoding done");
+ return TCORE_SAT_SUCCESS;
+ }
+ }
+
+ /* sub address */
+ if ((tlv_origin[temp_index] & 0x7F) == SATK_SUB_ADDRESS_TAG) {
+ rv = _sat_decode_sub_address_tlv(tlv_origin, tlv_length, temp_index, &call_ctrl_result_tlv->sub_address, &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv;
+
+ temp_index += data_len_consumed;
+
+ if (temp_index >= tlv_length) {
+ dbg("[SAT] call control decoding done");
+ return TCORE_SAT_SUCCESS;
+ }
+ }
+
+ /* alpha id */
+ if ((tlv_origin[temp_index] & 0x7F) == SATK_ALPHA_IDENTIFIER_TAG) {
+ rv = _sat_decode_alpha_identifier_tlv(tlv_origin, tlv_length, temp_index, &call_ctrl_result_tlv->alpha_id, &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv;
+
+ temp_index += data_len_consumed;
+
+ if (temp_index >= tlv_length) {
+ dbg("[SAT] call control decoding done");
+ return TCORE_SAT_SUCCESS;
+ }
+ }
+
+ /* bc repeated indicator */
+ if ((tlv_origin[temp_index] & 0x7F) == SATK_BC_REPEAT_INDICATOR_TAG) {
+ int tag = 0;
+ int bc_repeat_ind_len = 0;
+
+ tag = tlv_origin[temp_index++];
+ bc_repeat_ind_len = tlv_origin[temp_index++];
+ call_ctrl_result_tlv->bc_repeat_type.bc_indi_repeat_type = tlv_origin[temp_index++];
+
+ dbg("bc repeated indication tag(%x) len(%x) type(%x)", tag, bc_repeat_ind_len, call_ctrl_result_tlv->bc_repeat_type.bc_indi_repeat_type);
+ if (temp_index >= tlv_length) {
+ dbg("[SAT] call control decoding done");
+ return TCORE_SAT_SUCCESS;
+ }
+ }
+
+ /* ccp2 */
+ if ((tlv_origin[temp_index] & 0x7F) == SATK_CAPABILITY_CONFIGURATION_PARAMETERS_TAG) {
+ rv = _sat_decode_ccp_tlv(tlv_origin, tlv_length, temp_index, &call_ctrl_result_tlv->ccp2, &data_len_consumed);
+ if (rv != TCORE_SAT_SUCCESS)
+ return rv; /* Send TR */
+
+ temp_index += data_len_consumed;
+
+ if (temp_index >= tlv_length) {
+ dbg("[SAT] call control decoding done");
+ return TCORE_SAT_SUCCESS;
+ }
+ }
+
+ return rv;
+}
+
+static unsigned char _sat_encode_dcs_tlv(const struct data_coding_scheme *src)
+{
+ unsigned char rv = 0x00;
+
+ if (src == NULL)
+ return 0;
+
+ if (src->is_compressed_format)
+ rv |= 0x20;
+
+ /* msg class */
+ switch (src->m_class) {
+ case MSG_CLASS_0:
+ case MSG_CLASS_1:
+ case MSG_CLASS_2:
+ case MSG_CLASS_3:
+ rv |= 0x10;
+ rv |= src->m_class;
+ break;
+
+ case MSG_CLASS_RESERVED:
+ case MSG_CLASS_NONE:
+ default:
+ rv &= 0xEF;
+ break;
+ }
+
+ /* alphabet format */
+ switch (src->a_format) {
+ case ALPHABET_FORMAT_SMS_DEFAULT:
+ rv &= 0xF3;
+ break;
+
+ case ALPHABET_FORMAT_8BIT_DATA:
+ rv |= 0x04;
+ break;
+
+ case ALPHABET_FORMAT_UCS2:
+ rv |= 0x08;
+ break;
+
+ default:
+ rv |= 0x0C;
+ break;
+ }
+
+ return rv;
+}
+
+static int _sat_encode_command_detail_tlv(const struct tel_sat_cmd_detail_info *src, char *dst, int current_temp_index)
+{
+ dst[current_temp_index++] = (b_comprehensive ? (SATK_COMMAND_DETAILS_TAG | 0x80) : SATK_COMMAND_DETAILS_TAG);
+ dst[current_temp_index++] = SATK_COMMAND_DETAILS_LENGTH;
+ dst[current_temp_index++] = src->cmd_num;
+ dst[current_temp_index++] = src->cmd_type;
+ dst[current_temp_index] = 0x00;
+
+ switch (src->cmd_type) {
+ case SAT_PROATV_CMD_DISPLAY_TEXT:
+ /* command detail text priority */
+ if (src->cmd_qualifier.display_text.text_priority == TEXT_PRIORITY_HIGH)
+ dst[current_temp_index] += 0x01;
+
+ /* command detail text clear type */
+ if (src->cmd_qualifier.display_text.text_clear_type == TEXT_WAIT_FOR_USER_TO_CLEAR_MSG)
+ dst[current_temp_index] += 0x80;
+ break;
+
+ case SAT_PROATV_CMD_GET_INKEY:
+ /* command detail alphabet set */
+ if (src->cmd_qualifier.get_inkey.alphabet_set)
+ dst[current_temp_index] += 0x01;
+
+ /* command detail alphabet type */
+ if (src->cmd_qualifier.get_inkey.alphabet_type == INPUT_ALPHABET_TYPE_UCS2)
+ dst[current_temp_index] += 0x02;
+
+ /* command detail get inkey type */
+ if (src->cmd_qualifier.get_inkey.inkey_type == INKEY_TYPE_YES_NO_REQUESTED)
+ dst[current_temp_index] += 0x04;
+
+
+ /* command detail immediate response required */
+ if (src->cmd_qualifier.get_inkey.immediate_rsp_required)
+ dst[current_temp_index] += 0x08;
+
+ /* command detail help available */
+ if (src->cmd_qualifier.get_inkey.help_info)
+ dst[current_temp_index] += 0x80;
+ break;
+
+ case SAT_PROATV_CMD_GET_INPUT:
+ /* command detail alphabet set */
+ if (src->cmd_qualifier.get_input.alphabet_set)
+ dst[current_temp_index] += 0x01;
+
+ /* command detail alphabet type */
+ if (src->cmd_qualifier.get_input.alphabet_type == INPUT_ALPHABET_TYPE_UCS2)
+ dst[current_temp_index] += 0x02;
+
+ /* command detail echo user input */
+ if (!src->cmd_qualifier.get_input.me_echo_user_input)
+ dst[current_temp_index] += 0x04;
+
+ /* command detail user input unpacked format */
+ if (!src->cmd_qualifier.get_input.user_input_unpacked_format)
+ dst[current_temp_index] += 0x08;
+
+ /* command detail help available */
+ if (src->cmd_qualifier.get_input.help_info)
+ dst[current_temp_index] += 0x80;
+ break;
+
+ case SAT_PROATV_CMD_MORE_TIME:
+ dbg("more time : 1bit RFU");
+ break;
+
+ case SAT_PROATV_CMD_PLAY_TONE:
+ /* command detail vibration alert */
+ if (src->cmd_qualifier.play_tone.vibration_alert == VIBRATE_ALERT_REQUIRED)
+ dst[current_temp_index] += 0x01;
+ break;
+
+ case SAT_PROATV_CMD_REFRESH:
+ /* command detail refresh command */
+ dst[current_temp_index] += src->cmd_qualifier.refresh.refresh;
+ break;
+
+ case SAT_PROATV_CMD_SETUP_MENU:
+ /* command detail preferences */
+ if (src->cmd_qualifier.setup_menu.select_preference == SELECTION_PREFERENCE_USING_SOFT_KEY)
+ dst[current_temp_index] += 0x01;
+
+ /* command detail help available */
+ if (src->cmd_qualifier.setup_menu.help_info)
+ dst[current_temp_index] += 0x80;
+ break;
+
+ case SAT_PROATV_CMD_SELECT_ITEM:
+ /* command detail presentation */
+ if (src->cmd_qualifier.select_item.presentation_type != PRESENTATION_TYPE_NOT_SPECIFIED) {
+ dst[current_temp_index] += 0x01;
+ if (src->cmd_qualifier.select_item.presentation_type == PRESENTATION_TYPE_NAVIGATION_OPTION)
+ dst[current_temp_index] += PRESENTATION_TYPE_NAVIGATION_OPTION;
+ }
+
+ /* command detail selection preference */
+ if (src->cmd_qualifier.select_item.select_preference == SELECTION_PREFERENCE_USING_SOFT_KEY)
+ dst[current_temp_index] += 0x04;
+
+ /* command detail help available */
+ if (src->cmd_qualifier.select_item.help_info)
+ dst[current_temp_index] += 0x80;
+ break;
+
+ case SAT_PROATV_CMD_SEND_SMS:
+ /* command detail sms packing by me required */
+ if (src->cmd_qualifier.send_sms.packing_by_me_required)
+ dst[current_temp_index] += 0x01;
+ break;
+
+ case SAT_PROATV_CMD_SETUP_CALL:
+ /* command detail setup call command */
+ dst[current_temp_index] += src->cmd_qualifier.setup_call.setup_call;
+ break;
+
+ case SAT_PROATV_CMD_SETUP_EVENT_LIST:
+ dbg("setup evnet list : 1bit RFU");
+ break;
+
+ case SAT_PROATV_CMD_OPEN_CHANNEL:
+ if (src->cmd_qualifier.open_channel.immediate_link)
+ dst[current_temp_index] += 0x01;
+
+ if (src->cmd_qualifier.open_channel.automatic_reconnection)
+ dst[current_temp_index] += 0x02;
+
+ if (src->cmd_qualifier.open_channel.background_mode)
+ dst[current_temp_index] += 0x04;
+ break;
+
+ case SAT_PROATV_CMD_SEND_DATA:
+ if (src->cmd_qualifier.send_data.send_data_immediately)
+ dst[current_temp_index] += 0x01;
+ break;
+
+ case SAT_PROATV_CMD_PROVIDE_LOCAL_INFO:
+ dst[current_temp_index] += src->cmd_qualifier.provide_local_info.provide_local_info;
+ break;
+
+ case SAT_PROATV_CMD_LANGUAGE_NOTIFICATION:
+ if (src->cmd_qualifier.language_notification.specific_language)
+ dst[current_temp_index] += 0x01;
+ break;
+
+ case SAT_PROATV_CMD_LAUNCH_BROWSER:
+ dst[current_temp_index] += src->cmd_qualifier.launch_browser.launch_browser;
+ break;
+
+ default:
+ err("no matched cmd type(%d)", src->cmd_type);
+ break;
+ }
+
+ return 5;
+}
+
+static int _sat_encode_device_identities_tlv(const struct tel_sat_device_identities *src, char *dst, int current_temp_index)
+{
+ dst[current_temp_index++] = SATK_DEVICE_IDENTITY_TAG;
+ dst[current_temp_index++] = SATK_DEVICE_IDENTITY_LENGTH;
+ dst[current_temp_index++] = src->src;
+ dst[current_temp_index++] = src->dest;
+
+ /* device identities total len 4 */
+ return 4;
+}
+
+static int _sat_encode_item_identifier_tlv(const struct tel_sat_item_identifier *src, char *dst, int current_temp_index)
+{
+ dst[current_temp_index++] = SATK_ITEM_IDENTIFIER_TAG;
+ dst[current_temp_index++] = SATK_ITEM_IDENTIFIER_LENGTH;
+ dst[current_temp_index++] = src->item_identifier;
+
+ /* item identifier total len 3 */
+ return 3;
+}
+
+#if 0
+static int _sat_encode_duration_tlv(const struct tel_sat_duration *src, char *dst, int current_temp_index)
+{
+ dst[current_temp_index++] = SATK_DURATION_TAG;
+ dst[current_temp_index++] = SATK_DURATION_LENGTH;
+ dst[current_temp_index++] = src->time_unit;
+ dst[current_temp_index++] = src->time_interval;
+
+ /*duration total len 4 */
+ return 4;
+}
+#endif
+
+static int _sat_encode_text_tlv(const struct tel_sat_text_string_object *src, char *dst, int current_temp_index, gboolean raw_dcs)
+{
+ int total_len = 0;
+ int length_temp_index = 0;
+
+ /* tag */
+ dst[current_temp_index++] = SATK_TEXT_STRING_TAG;
+
+ /* length */
+ if (src->string_length <= 0x7F) {
+ dst[current_temp_index++] = SATK_DCS_LENGTH + src->string_length;
+ length_temp_index = 1;
+ } else {
+ dst[current_temp_index++] = 0x81;
+ dst[current_temp_index++] = SATK_DCS_LENGTH + src->string_length;
+ length_temp_index = 2;
+ }
+
+ /* dcs */
+ if (raw_dcs)
+ dst[current_temp_index++] = src->dcs.raw_dcs;
+ else
+ dst[current_temp_index++] = _sat_encode_dcs_tlv(&(src->dcs));
+
+ /* value */
+ if (src->string_length > 0)
+ memcpy(&(dst[current_temp_index]), src->string, src->string_length);
+
+ /* tag + temp_index + dcs + data */
+ total_len = 1 + length_temp_index + 1 + src->string_length;
+
+ return total_len;
+}
+
+static int _sat_encode_eventlist_tlv(const enum event_list src, char *dst, int current_temp_index)
+{
+ dst[current_temp_index++] = SATK_EVENT_LIST_TAG;
+ dst[current_temp_index++] = 0x01;
+ dst[current_temp_index++] = src;
+
+ return 3;
+}
+
+static int _sat_encode_date_time_and_timezone_tlv(const struct tel_sat_date_time_and_timezone *src, char *dst, int current_temp_index)
+{
+ dst[current_temp_index++] = SATK_DATE_TIME_AND_TIME_ZONE_TAG;
+ dst[current_temp_index++] = SATK_DATE_TIME_AND_TIME_ZONE_LENGTH;
+ dst[current_temp_index++] = src->year;
+ dst[current_temp_index++] = src->month;
+ dst[current_temp_index++] = src->day;
+ dst[current_temp_index++] = src->hour;
+ dst[current_temp_index++] = src->minute;
+ dst[current_temp_index++] = src->second;
+ dst[current_temp_index++] = src->timeZone;
+
+ return 1 + 1 + SATK_DATE_TIME_AND_TIME_ZONE_LENGTH; /* tag length + len field length + value length; */
+}
+
+static int _sat_encode_language_tlv(const enum tel_sim_language_type src, char *dst, int current_temp_index)
+{
+ dst[current_temp_index++] = SATK_LANGUAGE_TAG;
+ dst[current_temp_index++] = SATK_LANGUAGE_LENGTH;
+
+ dbg("language (%d)", src);
+
+ switch (src) {
+ case SIM_LANG_GERMAN:
+ dst[current_temp_index++] = 'd';
+ dst[current_temp_index++] = 'e';
+ break;
+
+ case SIM_LANG_ENGLISH:
+ dst[current_temp_index++] = 'e';
+ dst[current_temp_index++] = 'n';
+ break;
+
+ case SIM_LANG_ITALIAN:
+ dst[current_temp_index++] = 'i';
+ dst[current_temp_index++] = 't';
+ break;
+
+ case SIM_LANG_FRENCH:
+ dst[current_temp_index++] = 'f';
+ dst[current_temp_index++] = 'r';
+ break;
+
+ case SIM_LANG_SPANISH:
+ dst[current_temp_index++] = 'e';
+ dst[current_temp_index++] = 's';
+ break;
+
+ case SIM_LANG_DUTCH:
+ dst[current_temp_index++] = 'n';
+ dst[current_temp_index++] = 'l';
+ break;
+
+ case SIM_LANG_SWEDISH:
+ dst[current_temp_index++] = 's';
+ dst[current_temp_index++] = 'v';
+ break;
+
+ case SIM_LANG_DANISH:
+ dst[current_temp_index++] = 'd';
+ dst[current_temp_index++] = 'a';
+ break;
+
+ case SIM_LANG_PORTUGUESE:
+ dst[current_temp_index++] = 'p';
+ dst[current_temp_index++] = 't';
+ break;
+
+ case SIM_LANG_FINNISH:
+ dst[current_temp_index++] = 'f';
+ dst[current_temp_index++] = 'i';
+ break;
+
+ case SIM_LANG_NORWEGIAN:
+ dst[current_temp_index++] = 'n';
+ dst[current_temp_index++] = 'b';
+ break;
+
+ case SIM_LANG_GREEK:
+ dst[current_temp_index++] = 'e';
+ dst[current_temp_index++] = 'l';
+ break;
+
+ case SIM_LANG_TURKISH:
+ dst[current_temp_index++] = 't';
+ dst[current_temp_index++] = 'k';
+ break;
+
+ case SIM_LANG_HUNGARIAN:
+ dst[current_temp_index++] = 'h';
+ dst[current_temp_index++] = 'u';
+ break;
+
+ case SIM_LANG_POLISH:
+ dst[current_temp_index++] = 'p';
+ dst[current_temp_index++] = 'l';
+ break;
+
+ case SIM_LANG_KOREAN:
+ dst[current_temp_index++] = 'k';
+ dst[current_temp_index++] = 'o';
+ break;
+
+ case SIM_LANG_CHINESE:
+ dst[current_temp_index++] = 'z';
+ dst[current_temp_index++] = 'h';
+ break;
+
+ case SIM_LANG_RUSSIAN:
+ dst[current_temp_index++] = 'r';
+ dst[current_temp_index++] = 'u';
+ break;
+
+ case SIM_LANG_JAPANESE:
+ dst[current_temp_index++] = 'j';
+ dst[current_temp_index++] = 'a';
+ break;
+
+ default:
+ dst[current_temp_index++] = 'e';
+ dst[current_temp_index++] = 'n';
+ dbg("[SAT] SAT PARSER - Unknown Language: 0x%x", src);
+ break;
+ }
+
+ return 4;
+}
+
+static int _sat_encode_browser_termination_tlv(const enum browser_termination_cause src, char *dst, int current_temp_index)
+{
+ dst[current_temp_index++] = SATK_BROWSER_TERMINATION_CAUSE_TAG;
+ dst[current_temp_index++] = SATK_BROWSER_TERMINATION_CAUSE_LENGTH;
+ dst[current_temp_index++] = src;
+
+ return 3;
+}
+
+#if 0
+static int _sat_encode_bearer_desc_tlv(const struct tel_sat_bearer_description *src, char *dst, int current_temp_index)
+{
+ int total_len = 0;
+ int length_temp_index = 0;
+
+ dst[current_temp_index++] = SATK_BEARER_DISCRIPTION_TAG;
+
+ /* length temp_index */
+ length_temp_index = current_temp_index++;
+
+ /* bearer type */
+ dst[current_temp_index++] = src->bearer_type;
+
+ switch (src->bearer_type) {
+ case BEARER_CSD: {
+ dst[current_temp_index++] = src->bearer_parameter.cs_bearer_param.data_rate;
+ dst[current_temp_index++] = src->bearer_parameter.cs_bearer_param.service_type;
+ dst[current_temp_index++] = src->bearer_parameter.cs_bearer_param.connection_element_type;
+ }
+ break;
+
+ case BEARER_GPRS: {
+ dst[current_temp_index++] = src->bearer_parameter.ps_bearer_param.precedence_class;
+ dst[current_temp_index++] = src->bearer_parameter.ps_bearer_param.delay_class;
+ dst[current_temp_index++] = src->bearer_parameter.ps_bearer_param.reliability_class;
+ dst[current_temp_index++] = src->bearer_parameter.ps_bearer_param.peak_throughput_class;
+ dst[current_temp_index++] = src->bearer_parameter.ps_bearer_param.mean_throughput_class;
+ dst[current_temp_index++] = src->bearer_parameter.ps_bearer_param.pdp_type;
+ }
+ break;
+
+ case BEARER_DEFAULT_BEARER_FROM_TRANSPORT_LAYER:
+ case BEARER_LOCAL_LINK_TECHNOLOGY_INDEPENDENT:
+ default:
+ break;
+ }
+
+ dst[length_temp_index] = (current_temp_index-1) - length_temp_index;
+ total_len = (current_temp_index-1) - length_temp_index + 2; /* tag and length */
+
+ return total_len;
+}
+
+static int _sat_encode_buffer_size_tlv(const struct tel_sat_buffer_size *src, char *dst, int current_temp_index)
+{
+ dst[current_temp_index++] = SATK_BUFFER_SIZE_TAG;
+ dst[current_temp_index++] = SATK_BUFFER_SIZE_LENGTH;
+ dst[current_temp_index++] = src->size[0];
+ dst[current_temp_index++] = src->size[1];
+
+ return 4;
+}
+#endif
+
+static int _sat_encode_channel_data_tlv(const struct tel_sat_channel_data *src, char *dst, int current_temp_index)
+{
+ int total_len = 0;
+ int length_temp_index = 0;
+
+ dst[current_temp_index++] = SATK_CHANNEL_DATA_TAG;
+
+ if (src->data_string_len <= 0x7F) {
+ dst[current_temp_index++] = src->data_string_len;
+ length_temp_index = 1;
+ } else {
+ dst[current_temp_index++] = 0x81;
+ dst[current_temp_index++] = src->data_string_len;
+ length_temp_index = 2;
+ }
+
+ memcpy(&(dst[current_temp_index]), src->data_string, src->data_string_len);
+
+ total_len = 1 + length_temp_index + src->data_string_len;
+
+ return total_len;
+}
+
+static int _sat_encode_channel_data_length_tlv(const struct tel_sat_channel_data_len *src, char *dst, int current_temp_index)
+{
+ dst[current_temp_index++] = SATK_CHANNEL_DATA_LEN_TAG;
+ dst[current_temp_index++] = SATK_CHANNEL_DATA_LENGTH_VALUE_LENGTH;
+ dst[current_temp_index++] = src->data_len;
+
+ return 3;
+}
+
+static int _sat_encode_channel_status_tlv(const struct tel_sat_channel_status *src, char *dst, int current_temp_index)
+{
+ dst[current_temp_index++] = SATK_CHANNEL_STATUS_TAG;
+ dst[current_temp_index++] = SATK_CHANNEL_STATUS_LENGTH;
+
+ if (src->status == link_or_packet_service_activated) /* (bit 8) */
+ dst[current_temp_index] += 0x80;
+
+ dst[current_temp_index++] += src->channel_id; /* (bit 1~3) */
+ dst[current_temp_index++] = src->status_info;
+
+ return 4;
+}
+
+static int _sat_encode_download_event(const struct tel_sat_envelop_event_download_tlv *evt_dl, char *dst_envelop)
+{
+ int temp_index = 2;
+ int encoded_len = 0;
+
+ dbg("event type(%d)", evt_dl->event);
+
+ /* event list */
+ encoded_len = _sat_encode_eventlist_tlv(evt_dl->event, dst_envelop, temp_index);
+ temp_index += encoded_len;
+
+ /* device id - len 4 */
+ encoded_len = _sat_encode_device_identities_tlv(&(evt_dl->device_identitie), dst_envelop, temp_index);
+ temp_index += encoded_len;
+
+ switch (evt_dl->event) {
+ case EVENT_LANGUAGE_SELECTION:
+ encoded_len = _sat_encode_language_tlv(evt_dl->language, dst_envelop, temp_index);
+ temp_index += encoded_len;
+ break;
+
+ case EVENT_BROWSER_TERMINATION:
+ encoded_len = _sat_encode_browser_termination_tlv(evt_dl->browser_termination, dst_envelop, temp_index);
+ temp_index += encoded_len;
+ break;
+
+ case EVENT_DATA_AVAILABLE:
+ encoded_len = _sat_encode_channel_status_tlv(&(evt_dl->channel_status), dst_envelop, temp_index);
+ temp_index += encoded_len;
+
+ encoded_len = _sat_encode_channel_data_length_tlv(&(evt_dl->channel_data_len), dst_envelop, temp_index);
+ temp_index += encoded_len;
+ break;
+
+ case EVENT_CHANNEL_STATUS:
+ encoded_len = _sat_encode_channel_status_tlv(&(evt_dl->channel_status), dst_envelop, temp_index);
+ temp_index += encoded_len;
+ break;
+
+ default:
+ break;
+ }
+
+ dst_envelop[0] = SATK_EVENT_DOWNLOAD_TAG;
+ dst_envelop[1] = temp_index-2;
+
+ dbg("download envelop cmd len(%d)", temp_index);
+
+ if (temp_index-2 > 0x7F) {
+ int idx = 0;
+ for (idx = temp_index; idx > 0; idx--)
+ dst_envelop[idx] = dst_envelop[idx + 1];
+ dst_envelop[1] = 0x81;
+ temp_index += 1;
+ dbg("download envelop added cmd len(%d)", temp_index);
+ }
+
+ return temp_index;
+}
+
+int tcore_sat_encode_envelop_cmd(const struct treq_sat_envelop_cmd_data *src_envelop, char *dst_envelop)
+{
+ int temp_index = 0, encoded_len = 0;
+
+ if (!dst_envelop)
+ return 0;
+
+ if (src_envelop->sub_cmd
+ == ENVELOP_MENU_SELECTION) {
+ temp_index = 2; /* set the cursor to device identity */
+ dbg("item id(%d)", src_envelop->envelop_data.menu_select.item_identifier.item_identifier);
+ encoded_len = _sat_encode_device_identities_tlv(&(src_envelop->envelop_data.menu_select.device_identitie), dst_envelop, temp_index);
+ temp_index += encoded_len;
+
+ /* item identifier */
+ encoded_len = _sat_encode_item_identifier_tlv(&(src_envelop->envelop_data.menu_select.item_identifier), dst_envelop, temp_index);
+ temp_index += encoded_len;
+
+ if (src_envelop->envelop_data.menu_select.help_request) {
+ encoded_len = 2;/* help request */
+ dst_envelop[temp_index++] = SATK_HELP_REQUEST_TAG;
+ dst_envelop[temp_index++] = SATK_HELP_REQUEST_LENGTH;
+ }
+
+ dbg("menu selection cmd len(%d)", temp_index);
+
+ /* main cmd */
+ dst_envelop[0] = SATK_MENU_SELECTION_TAG;
+ dst_envelop[1] = temp_index-2;
+ } else if (src_envelop->sub_cmd
+ == ENVELOP_EVENT_DOWNLOAD)
+ temp_index = _sat_encode_download_event(&(src_envelop->envelop_data.event_download), dst_envelop);
+
+ return temp_index;
+}
+
+
+
+static int _sat_encode_display_text(const struct tel_sat_tr_display_text_tlv *src_tr, char *dst_tr)
+{
+ int temp_index = 0, encoded_len = 0;
+
+ /* set command detail info */
+ encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, temp_index);
+ temp_index += encoded_len;
+
+ /* set device identities info */
+ encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, temp_index);
+ temp_index += encoded_len;
+
+ /* set result info */
+ dst_tr[temp_index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG);
+ switch (src_tr->result_type) {
+ case RESULT_SUCCESS:
+ case RESULT_SUCCESS_WITH_PARTIAL_COMPREHENSION:
+ case RESULT_SUCCESS_WITH_MISSING_INFO:
+ case RESULT_SUCCESS_BUT_REQUESTED_ICON_NOT_DISPLAYED:
+ case RESULT_PROACTIVE_SESSION_TERMINATED_BY_USER:
+ case RESULT_BACKWARD_MOVE_BY_USER:
+ case RESULT_NO_RESPONSE_FROM_USER:
+ case RESULT_BEYOND_ME_CAPABILITIES:
+ case RESULT_COMMAND_TYPE_NOT_UNDERSTOOD_BY_ME:
+ case RESULT_COMMAND_DATA_NOT_UNDERSTOOD_BY_ME:
+ case RESULT_COMMAND_NUMBER_NOT_KNOWN_BY_ME:
+ case RESULT_ERROR_REQUIRED_VALUES_ARE_MISSING:
+ dst_tr[temp_index++] = 1;
+ dst_tr[temp_index++] = src_tr->result_type;
+ break;
+
+ case RESULT_ME_UNABLE_TO_PROCESS_COMMAND:
+ case RESULT_FRAMES_ERROR:
+ dst_tr[temp_index++] = 2;
+ dst_tr[temp_index++] = src_tr->result_type;
+ dst_tr[temp_index++] = src_tr->me_problem_type;
+ break;
+
+ default:
+ dbg("invalid response value[0x%x] in current TR", src_tr->result_type);
+ temp_index = 0;
+ break;
+ }
+
+ return temp_index;
+}
+
+static int _sat_encode_get_inkey(const struct tel_sat_tr_get_inkey_tlv *src_tr, char *dst_tr)
+{
+ int temp_index = 0, encoded_len = 0;
+
+ /* set command detail info */
+ encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, temp_index);
+ temp_index += encoded_len;
+
+ /* set device identities info */
+ encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, temp_index);
+ temp_index += encoded_len;
+
+ /* set result info */
+ dst_tr[temp_index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG);
+
+ switch (src_tr->result_type) {
+ case RESULT_SUCCESS:
+ case RESULT_SUCCESS_WITH_PARTIAL_COMPREHENSION:
+ case RESULT_SUCCESS_WITH_MISSING_INFO:
+ case RESULT_SUCCESS_BUT_REQUESTED_ICON_NOT_DISPLAYED:
+ dst_tr[temp_index++] = 1;
+ dst_tr[temp_index++] = src_tr->result_type;
+
+ encoded_len = _sat_encode_text_tlv(&(src_tr->text), dst_tr, temp_index, FALSE);
+ temp_index += encoded_len;
+ break;
+
+ case RESULT_PROACTIVE_SESSION_TERMINATED_BY_USER:
+ case RESULT_BACKWARD_MOVE_BY_USER:
+ case RESULT_HELP_INFO_REQUIRED_BY_USER:
+ case RESULT_BEYOND_ME_CAPABILITIES:
+ case RESULT_COMMAND_TYPE_NOT_UNDERSTOOD_BY_ME:
+ case RESULT_COMMAND_DATA_NOT_UNDERSTOOD_BY_ME:
+ case RESULT_COMMAND_NUMBER_NOT_KNOWN_BY_ME:
+ case RESULT_ERROR_REQUIRED_VALUES_ARE_MISSING:
+ case RESULT_NO_RESPONSE_FROM_USER:
+ dst_tr[temp_index++] = 1;
+ dst_tr[temp_index++] = src_tr->result_type;
+ break;
+
+ case RESULT_ME_UNABLE_TO_PROCESS_COMMAND:
+ case RESULT_FRAMES_ERROR:
+ dst_tr[temp_index++] = 2;
+ dst_tr[temp_index++] = src_tr->result_type;
+ dst_tr[temp_index++] = src_tr->me_problem_type;
+ break;
+
+ default:
+ dbg("invalid response value[0x%x] in current TR", src_tr->result_type);
+ temp_index = 0;
+ break;
+ }
+
+ return temp_index;
+}
+
+static int _sat_encode_get_input(const struct tel_sat_tr_get_input_tlv *src_tr, char *dst_tr)
+{
+ int temp_index = 0, encoded_len = 0;
+
+ /* set command detail info */
+ encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, temp_index);
+ temp_index += encoded_len;
+
+ /* set device identities info */
+ encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, temp_index);
+ temp_index += encoded_len;
+
+ /* set result info */
+ dst_tr[temp_index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG);
+
+ switch (src_tr->result_type) {
+ case RESULT_SUCCESS:
+ case RESULT_SUCCESS_WITH_PARTIAL_COMPREHENSION:
+ case RESULT_SUCCESS_WITH_MISSING_INFO:
+ case RESULT_SUCCESS_BUT_REQUESTED_ICON_NOT_DISPLAYED:
+ dst_tr[temp_index++] = 1;
+ dst_tr[temp_index++] = src_tr->result_type;
+
+ encoded_len = _sat_encode_text_tlv(&(src_tr->text), dst_tr, temp_index, FALSE);
+ temp_index += encoded_len;
+ break;
+
+ case RESULT_PROACTIVE_SESSION_TERMINATED_BY_USER:
+ case RESULT_BACKWARD_MOVE_BY_USER:
+ case RESULT_NO_RESPONSE_FROM_USER:
+ case RESULT_HELP_INFO_REQUIRED_BY_USER:
+ case RESULT_BEYOND_ME_CAPABILITIES:
+ case RESULT_COMMAND_TYPE_NOT_UNDERSTOOD_BY_ME:
+ case RESULT_COMMAND_DATA_NOT_UNDERSTOOD_BY_ME:
+ case RESULT_COMMAND_NUMBER_NOT_KNOWN_BY_ME:
+ case RESULT_ERROR_REQUIRED_VALUES_ARE_MISSING:
+ dst_tr[temp_index++] = 1;
+ dst_tr[temp_index++] = src_tr->result_type;
+ break;
+
+ case RESULT_ME_UNABLE_TO_PROCESS_COMMAND:
+ case RESULT_FRAMES_ERROR:
+ dst_tr[temp_index++] = 2;
+ dst_tr[temp_index++] = src_tr->result_type;
+ dst_tr[temp_index++] = src_tr->me_problem_type;
+ break;
+
+ default:
+ dbg("invalid response value[0x%x] in current TR", src_tr->result_type);
+ temp_index = 0;
+ break;
+ }
+
+ return temp_index;
+}
+
+static int _sat_encode_more_time(const struct tel_sat_tr_more_time_tlv *src_tr, char *dst_tr)
+{
+ int temp_index = 0, encoded_len = 0;
+
+ /* set command detail info */
+ encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, temp_index);
+ temp_index += encoded_len;
+
+ /* set device identities info */
+ encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, temp_index);
+ temp_index += encoded_len;
+
+ /* set result info */
+ dst_tr[temp_index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG);
+
+ switch (src_tr->result_type) {
+ case RESULT_SUCCESS:
+ case RESULT_SUCCESS_WITH_PARTIAL_COMPREHENSION:
+ case RESULT_SUCCESS_WITH_MISSING_INFO:
+ case RESULT_BEYOND_ME_CAPABILITIES:
+ case RESULT_COMMAND_TYPE_NOT_UNDERSTOOD_BY_ME:
+ case RESULT_COMMAND_DATA_NOT_UNDERSTOOD_BY_ME:
+ case RESULT_COMMAND_NUMBER_NOT_KNOWN_BY_ME:
+ case RESULT_ERROR_REQUIRED_VALUES_ARE_MISSING:
+ dst_tr[temp_index++] = 1;
+ dst_tr[temp_index++] = src_tr->result_type;
+ break;
+
+ case RESULT_ME_UNABLE_TO_PROCESS_COMMAND:
+ dst_tr[temp_index++] = 2;
+ dst_tr[temp_index++] = src_tr->result_type;
+ dst_tr[temp_index++] = src_tr->me_problem_type;
+ break;
+
+ default:
+ dbg("invalid response value[0x%x] in current TR", src_tr->result_type);
+ temp_index = 0;
+ break;
+ }
+
+ return temp_index;
+}
+
+static int _sat_encode_play_tone(const struct tel_sat_tr_play_tone_tlv *src_tr, char *dst_tr)
+{
+ int temp_index = 0, encoded_len = 0;
+
+ /* set command detail info */
+ encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, temp_index);
+ temp_index += encoded_len;
+
+ /* set device identities info */
+ encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, temp_index);
+ temp_index += encoded_len;
+
+ /* set result info */
+ dst_tr[temp_index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG);
+
+ switch (src_tr->result_type) {
+ case RESULT_SUCCESS:
+ case RESULT_SUCCESS_WITH_PARTIAL_COMPREHENSION:
+ case RESULT_SUCCESS_WITH_MISSING_INFO:
+ case RESULT_SUCCESS_BUT_REQUESTED_ICON_NOT_DISPLAYED:
+ case RESULT_SUCCESS_BUT_TONE_NOT_PLAYED:
+ case RESULT_PROACTIVE_SESSION_TERMINATED_BY_USER:
+ case RESULT_BEYOND_ME_CAPABILITIES:
+ case RESULT_COMMAND_TYPE_NOT_UNDERSTOOD_BY_ME:
+ case RESULT_COMMAND_DATA_NOT_UNDERSTOOD_BY_ME:
+ case RESULT_COMMAND_NUMBER_NOT_KNOWN_BY_ME:
+ case RESULT_ERROR_REQUIRED_VALUES_ARE_MISSING:
+ dst_tr[temp_index++] = 1;
+ dst_tr[temp_index++] = src_tr->result_type;
+ break;
+
+ case RESULT_ME_UNABLE_TO_PROCESS_COMMAND:
+ case RESULT_FRAMES_ERROR:
+ dst_tr[temp_index++] = 2;
+ dst_tr[temp_index++] = src_tr->result_type;
+ dst_tr[temp_index++] = src_tr->me_problem_type;
+ break;
+
+ default:
+ dbg("invalid response value[0x%x] in current TR", src_tr->result_type);
+ temp_index = 0;
+ break;
+ }
+
+ return temp_index;
+}
+
+static int _sat_encode_refresh(const struct tel_sat_tr_refresh_tlv *src_tr, char *dst_tr)
+{
+ int temp_index = 0, encoded_len = 0;
+
+ /* set command detail info */
+ encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, temp_index);
+ temp_index += encoded_len;
+
+ /* set device identities info */
+ encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, temp_index);
+ temp_index += encoded_len;
+
+ /* set result info */
+ dst_tr[temp_index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG);
+
+ switch (src_tr->result_type) {
+ case RESULT_SUCCESS:
+ case RESULT_SUCCESS_WITH_PARTIAL_COMPREHENSION:
+ case RESULT_SUCCESS_WITH_MISSING_INFO:
+ case RESULT_REFRESH_PERFORMED_WITH_ADDITIONAL_EFS_READ:
+ case RESULT_REFRESH_PRFRMD_BUT_INDICATED_USIM_NOT_ACTIVE:
+ case RESULT_BEYOND_ME_CAPABILITIES:
+ case RESULT_COMMAND_TYPE_NOT_UNDERSTOOD_BY_ME:
+ case RESULT_COMMAND_DATA_NOT_UNDERSTOOD_BY_ME:
+ case RESULT_COMMAND_NUMBER_NOT_KNOWN_BY_ME:
+ case RESULT_ERROR_REQUIRED_VALUES_ARE_MISSING:
+ dst_tr[temp_index++] = 1;
+ dst_tr[temp_index++] = src_tr->result_type;
+ break;
+
+ case RESULT_ME_UNABLE_TO_PROCESS_COMMAND:
+ dst_tr[temp_index++] = 2;
+ dst_tr[temp_index++] = src_tr->result_type;
+ dst_tr[temp_index++] = src_tr->me_problem_type;
+ break;
+
+ default:
+ dbg("invalid response value[0x%x] in current TR", src_tr->result_type);
+ temp_index = 0;
+ break;
+ }
+
+ return temp_index;
+}
+
+static int _sat_encode_setup_menu(const struct tel_sat_tr_setup_menu_tlv *src_tr, char *dst_tr)
+{
+ int temp_index = 0, encoded_len = 0;
+
+ /* set command detail info */
+ encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, temp_index);
+ temp_index += encoded_len;
+
+ /* set device identities info */
+ encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, temp_index);
+ temp_index += encoded_len;
+
+ /* set result info */
+ dst_tr[temp_index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG);
+ switch (src_tr->result_type) {
+ case RESULT_SUCCESS:
+ case RESULT_SUCCESS_WITH_PARTIAL_COMPREHENSION:
+ case RESULT_SUCCESS_WITH_MISSING_INFO:
+ case RESULT_SUCCESS_BUT_REQUESTED_ICON_NOT_DISPLAYED:
+ case RESULT_BEYOND_ME_CAPABILITIES:
+ case RESULT_COMMAND_TYPE_NOT_UNDERSTOOD_BY_ME:
+ case RESULT_COMMAND_DATA_NOT_UNDERSTOOD_BY_ME:
+ case RESULT_COMMAND_NUMBER_NOT_KNOWN_BY_ME:
+ case RESULT_ERROR_REQUIRED_VALUES_ARE_MISSING:
+ dst_tr[temp_index++] = 1;
+ dst_tr[temp_index++] = src_tr->result_type;
+ break;
+
+ case RESULT_ME_UNABLE_TO_PROCESS_COMMAND:
+ dst_tr[temp_index++] = 2;
+ dst_tr[temp_index++] = src_tr->result_type;
+ dst_tr[temp_index++] = src_tr->me_problem_type;
+ break;
+
+ default:
+ dbg("invalid response value[0x%x] in current TR", src_tr->result_type);
+ temp_index = 0;
+ break;
+ }
+
+ return temp_index;
+}
+
+static int _sat_encode_select_item(const struct tel_sat_tr_select_item_tlv *src_tr, char *dst_tr)
+{
+ int temp_index = 0, encoded_len = 0;
+
+ /* set command detail info */
+ encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, temp_index);
+ temp_index += encoded_len;
+
+ /* set device identities info */
+ encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, temp_index);
+ temp_index += encoded_len;
+
+ /* set result info */
+ dst_tr[temp_index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG);
+
+ switch (src_tr->result_type) {
+ case RESULT_SUCCESS:
+ case RESULT_SUCCESS_WITH_PARTIAL_COMPREHENSION:
+ case RESULT_SUCCESS_WITH_MISSING_INFO:
+ case RESULT_SUCCESS_BUT_REQUESTED_ICON_NOT_DISPLAYED:
+ case RESULT_HELP_INFO_REQUIRED_BY_USER:
+ dst_tr[temp_index++] = 1;
+ dst_tr[temp_index++] = src_tr->result_type;
+ encoded_len = _sat_encode_item_identifier_tlv(&(src_tr->item_identifier), dst_tr, temp_index);
+ temp_index += encoded_len;
+ break;
+
+ case RESULT_PROACTIVE_SESSION_TERMINATED_BY_USER:
+ case RESULT_BACKWARD_MOVE_BY_USER:
+ case RESULT_NO_RESPONSE_FROM_USER:
+ case RESULT_BEYOND_ME_CAPABILITIES:
+ case RESULT_COMMAND_TYPE_NOT_UNDERSTOOD_BY_ME:
+ case RESULT_COMMAND_DATA_NOT_UNDERSTOOD_BY_ME:
+ case RESULT_COMMAND_NUMBER_NOT_KNOWN_BY_ME:
+ case RESULT_ERROR_REQUIRED_VALUES_ARE_MISSING:
+ dst_tr[temp_index++] = 1;
+ dst_tr[temp_index++] = src_tr->result_type;
+ break;
+
+ case RESULT_ME_UNABLE_TO_PROCESS_COMMAND:
+ case RESULT_FRAMES_ERROR:
+ dst_tr[temp_index++] = 2;
+ dst_tr[temp_index++] = src_tr->result_type;
+ dst_tr[temp_index++] = src_tr->me_problem_type;
+ break;
+
+ default:
+ dbg("invalid response value[0x%x] in current TR", src_tr->result_type);
+ temp_index = 0;
+ break;
+ }
+
+ return temp_index;
+}
+
+static int _sat_encode_send_sms(const struct tel_sat_tr_send_sms_tlv *src_tr, char *dst_tr)
+{
+ int temp_index = 0, encoded_len = 0;
+
+ /* set command detail info */
+ encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, temp_index);
+ temp_index += encoded_len;
+
+ /* set device identities info */
+ encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, temp_index);
+ temp_index += encoded_len;
+
+ /* set result info */
+ dst_tr[temp_index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG);
+
+ switch (src_tr->result_type) {
+ case RESULT_SUCCESS:
+ case RESULT_SUCCESS_WITH_PARTIAL_COMPREHENSION:
+ case RESULT_SUCCESS_WITH_MISSING_INFO:
+ case RESULT_SUCCESS_BUT_REQUESTED_ICON_NOT_DISPLAYED:
+ dst_tr[temp_index++] = 1;
+ dst_tr[temp_index++] = src_tr->result_type;
+ break;
+
+ case RESULT_ME_UNABLE_TO_PROCESS_COMMAND:
+ case RESULT_NETWORK_UNABLE_TO_PROCESS_COMMAND:
+ case RESULT_BEYOND_ME_CAPABILITIES:
+ case RESULT_COMMAND_TYPE_NOT_UNDERSTOOD_BY_ME:
+ case RESULT_COMMAND_DATA_NOT_UNDERSTOOD_BY_ME:
+ case RESULT_SMS_RP_ERROR:
+ case RESULT_ERROR_REQUIRED_VALUES_ARE_MISSING:
+ dst_tr[temp_index++] = 2;
+ dst_tr[temp_index++] = src_tr->result_type;
+ dst_tr[temp_index++] = src_tr->me_problem_type;
+ break;
+
+ case RESULT_INTRCTN_WITH_CC_OR_SMS_CTRL_PRMNT_PRBLM:
+ dst_tr[temp_index++] = 2;
+ dst_tr[temp_index++] = src_tr->result_type;
+ dst_tr[temp_index++] = src_tr->cc_problem_type;
+ break;
+
+ default:
+ dbg("invalid response value[0x%x] in current TR", src_tr->result_type);
+ temp_index = 0;
+ break;
+ }
+
+ return temp_index;
+}
+
+static int _sat_encode_send_ss(const struct tel_sat_tr_send_ss_tlv *src_tr, char *dst_tr)
+{
+ int temp_index = 0, encoded_len = 0;
+
+ /* set command detail info */
+ encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, temp_index);
+ temp_index += encoded_len;
+
+ /* set device identities info */
+ encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, temp_index);
+ temp_index += encoded_len;
+
+ /* set result info */
+ dst_tr[temp_index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG);
+
+ switch (src_tr->result_type) {
+ case RESULT_SUCCESS:
+ case RESULT_SUCCESS_WITH_PARTIAL_COMPREHENSION:
+ case RESULT_SUCCESS_WITH_MISSING_INFO:
+ case RESULT_SUCCESS_BUT_REQUESTED_ICON_NOT_DISPLAYED:
+ case RESULT_SUCCESS_BUT_MODIFIED_BY_CALL_CONTROL_BY_SIM:
+ case RESULT_USSD_OR_SS_TRANSACTION_TERMINATED_BY_USER:
+ dst_tr[temp_index++] = 1 + src_tr->text.string_length;
+ dst_tr[temp_index++] = src_tr->result_type;
+
+ memcpy(&(dst_tr[temp_index]), src_tr->text.string, src_tr->text.string_length);
+ encoded_len = src_tr->text.string_length;
+ temp_index += encoded_len;
+ break;
+ case RESULT_COMMAND_DATA_NOT_UNDERSTOOD_BY_ME:
+ dst_tr[temp_index++] = 1;
+ dst_tr[temp_index++] = src_tr->result_type;
+ break;
+
+ case RESULT_ME_UNABLE_TO_PROCESS_COMMAND:
+ case RESULT_NETWORK_UNABLE_TO_PROCESS_COMMAND:
+ dst_tr[temp_index++] = 2;
+ dst_tr[temp_index++] = src_tr->result_type;
+ dst_tr[temp_index++] = src_tr->me_problem_type;
+ break;
+
+ case RESULT_INTRCTN_WITH_CC_OR_SMS_CTRL_PRMNT_PRBLM:
+ dst_tr[temp_index++] = 2;
+ dst_tr[temp_index++] = src_tr->result_type;
+ dst_tr[temp_index++] = src_tr->cc_problem_type;
+ break;
+
+ case RESULT_SS_RETURN_ERROR:
+ dst_tr[temp_index++] = 2;
+ dst_tr[temp_index++] = src_tr->result_type;
+ dst_tr[temp_index++] = src_tr->ss_problem;
+ break;
+
+ case RESULT_BEYOND_ME_CAPABILITIES:
+ dst_tr[temp_index++] = 1;
+ dst_tr[temp_index++] = src_tr->result_type;
+ break;
+
+ default:
+ dbg("invalid response value[0x%x] in current TR", src_tr->result_type);
+ temp_index = 0;
+ break;
+ }
+
+ return temp_index;
+}
+
+static int _sat_encode_send_ussd(const struct tel_sat_tr_send_ussd_tlv *src_tr, char *dst_tr)
+{
+ int temp_index = 0, encoded_len = 0;
+
+ /* set command detail info */
+ encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, temp_index);
+ temp_index += encoded_len;
+
+ /* set device identities info */
+ encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, temp_index);
+ temp_index += encoded_len;
+
+ /* set result info */
+ dst_tr[temp_index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG);
+
+ switch (src_tr->result_type) {
+ case RESULT_SUCCESS:
+ case RESULT_SUCCESS_WITH_PARTIAL_COMPREHENSION:
+ case RESULT_SUCCESS_WITH_MISSING_INFO:
+ case RESULT_SUCCESS_BUT_REQUESTED_ICON_NOT_DISPLAYED:
+ case RESULT_SUCCESS_BUT_MODIFIED_BY_CALL_CONTROL_BY_SIM:
+ case RESULT_USSD_OR_SS_TRANSACTION_TERMINATED_BY_USER:
+ dst_tr[temp_index++] = 1;
+ dst_tr[temp_index++] = src_tr->result_type;
+
+ encoded_len = _sat_encode_text_tlv(&(src_tr->text), dst_tr, temp_index, TRUE);
+ temp_index += encoded_len;
+ break;
+
+ case RESULT_COMMAND_DATA_NOT_UNDERSTOOD_BY_ME:
+ case RESULT_BEYOND_ME_CAPABILITIES:
+ dst_tr[temp_index++] = 1;
+ dst_tr[temp_index++] = src_tr->result_type;
+ break;
+
+ case RESULT_ME_UNABLE_TO_PROCESS_COMMAND:
+ case RESULT_NETWORK_UNABLE_TO_PROCESS_COMMAND:
+ dst_tr[temp_index++] = 2;
+ dst_tr[temp_index++] = src_tr->result_type;
+ dst_tr[temp_index++] = src_tr->me_problem_type;
+ break;
+
+ case RESULT_INTRCTN_WITH_CC_OR_SMS_CTRL_PRMNT_PRBLM:
+ dst_tr[temp_index++] = 2;
+ dst_tr[temp_index++] = src_tr->result_type;
+ dst_tr[temp_index++] = src_tr->cc_problem_type;
+ break;
+
+ case RESULT_USSD_RETURN_ERROR:
+ dst_tr[temp_index++] = 2;
+ dst_tr[temp_index++] = src_tr->result_type;
+ dst_tr[temp_index++] = src_tr->ussd_problem;
+ break;
+
+ default:
+ dbg("invalid response value[0x%x] in current TR", src_tr->result_type);
+ temp_index = 0;
+ break;
+ }
+
+ return temp_index;
+}
+
+static int _sat_encode_setup_call(const struct tel_sat_tr_setup_call_tlv *src_tr, char *dst_tr)
+{
+ int temp_index = 0, encoded_len = 0;
+
+ /* set command detail info */
+ encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, temp_index);
+ temp_index += encoded_len;
+
+ /* set device identities info */
+ encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, temp_index);
+ temp_index += encoded_len;
+
+ /* set result info */
+ dst_tr[temp_index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG);
+
+ switch (src_tr->result_type) {
+ case RESULT_SUCCESS:
+ case RESULT_SUCCESS_WITH_PARTIAL_COMPREHENSION:
+ case RESULT_SUCCESS_WITH_MISSING_INFO:
+ case RESULT_SUCCESS_BUT_REQUESTED_ICON_NOT_DISPLAYED:
+ case RESULT_SUCCESS_BUT_MODIFIED_BY_CALL_CONTROL_BY_SIM:
+ case RESULT_PROACTIVE_SESSION_TERMINATED_BY_USER:
+ case RESULT_BEYOND_ME_CAPABILITIES:
+ case RESULT_COMMAND_TYPE_NOT_UNDERSTOOD_BY_ME:
+ case RESULT_COMMAND_DATA_NOT_UNDERSTOOD_BY_ME:
+ case RESULT_COMMAND_NUMBER_NOT_KNOWN_BY_ME:
+ case RESULT_ERROR_REQUIRED_VALUES_ARE_MISSING:
+ case RESULT_SS_RETURN_ERROR:
+ dst_tr[temp_index++] = 1;
+ dst_tr[temp_index++] = src_tr->result_type;
+ break;
+
+ case RESULT_ME_UNABLE_TO_PROCESS_COMMAND:
+ case RESULT_USER_DID_NOT_ACCEPT_CALL_SETUP_REQ:
+ case RESULT_USER_CLEAR_DOWN_CALL_BEFORE_CONN:
+ case RESULT_FRAMES_ERROR:
+ dst_tr[temp_index++] = 2;
+ dst_tr[temp_index++] = src_tr->result_type;
+ dst_tr[temp_index++] = src_tr->me_problem_type;
+ break;
+
+ case RESULT_NETWORK_UNABLE_TO_PROCESS_COMMAND:
+ dst_tr[temp_index++] = 2;
+ dst_tr[temp_index++] = src_tr->result_type;
+ dst_tr[temp_index++] = src_tr->network_problem_type;
+ break;
+
+ case RESULT_INTRCTN_WITH_CC_OR_SMS_CTRL_PRMNT_PRBLM:
+ dst_tr[temp_index++] = 2;
+ dst_tr[temp_index++] = src_tr->result_type;
+ dst_tr[temp_index++] = src_tr->cc_problem_type;
+ break;
+
+ default:
+ dbg("invalid response value[0x%x] in current TR", src_tr->result_type);
+ temp_index = 0;
+ break;
+ }
+
+ return temp_index;
+}
+
+static int _sat_encode_provide_local_info(const struct tel_sat_tr_provide_local_info_tlv *src_tr, char *dst_tr)
+{
+ int temp_index = 0, encoded_len = 0;
+
+ /* set command detail info */
+ encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, temp_index);
+ temp_index += encoded_len;
+
+ /* set device identities info */
+ encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, temp_index);
+ temp_index += encoded_len;
+
+ /* set result info */
+ dst_tr[temp_index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG);
+ switch (src_tr->result_type) {
+ case RESULT_SUCCESS:
+ case RESULT_SUCCESS_WITH_PARTIAL_COMPREHENSION:
+ case RESULT_SUCCESS_WITH_MISSING_INFO:
+ case RESULT_SUCCESS_LIMITED_SERVICE:
+ dst_tr[temp_index++] = 1;
+ dst_tr[temp_index++] = src_tr->result_type;
+ switch (src_tr->command_detail.cmd_qualifier.provide_local_info.provide_local_info) {
+ case LOCAL_INFO_DATE_TIME_AND_TIMEZONE:
+ encoded_len = _sat_encode_date_time_and_timezone_tlv(&(src_tr->other.date_time_and_timezone), dst_tr, temp_index);
+ break;
+
+ case LOCAL_INFO_LANGUAGE:
+ encoded_len = _sat_encode_language_tlv(src_tr->other.language, dst_tr, temp_index);
+ break;
+
+ default:
+ dbg("local info type[%d] is not handled", src_tr->command_detail.cmd_qualifier.provide_local_info.provide_local_info);
+ break;
+ }
+
+ temp_index += encoded_len;
+ break;
+
+ case RESULT_BEYOND_ME_CAPABILITIES:
+ case RESULT_COMMAND_TYPE_NOT_UNDERSTOOD_BY_ME:
+ case RESULT_COMMAND_DATA_NOT_UNDERSTOOD_BY_ME:
+ case RESULT_COMMAND_NUMBER_NOT_KNOWN_BY_ME:
+ case RESULT_ERROR_REQUIRED_VALUES_ARE_MISSING:
+ dst_tr[temp_index++] = 1;
+ dst_tr[temp_index++] = src_tr->result_type;
+ break;
+
+ case RESULT_ME_UNABLE_TO_PROCESS_COMMAND:
+ dst_tr[temp_index++] = 2;
+ dst_tr[temp_index++] = src_tr->result_type;
+ dst_tr[temp_index++] = src_tr->me_problem_type;
+ break;
+
+ default:
+ dbg("invalid response value[0x%x] in current TR", src_tr->result_type);
+ temp_index = 0;
+ break;
+ }
+
+ return temp_index;
+}
+
+static int _sat_encode_setup_event_list(const struct tel_sat_tr_setup_event_list_tlv *src_tr, char *dst_tr)
+{
+ int temp_index = 0, encoded_len = 0;
+
+ /* set command detail info */
+ encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, temp_index);
+ temp_index += encoded_len;
+
+ /* set device identities info */
+ encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, temp_index);
+ temp_index += encoded_len;
+
+ /* set result info */
+ dst_tr[temp_index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG);
+ switch (src_tr->result_type) {
+ case RESULT_SUCCESS:
+ case RESULT_SUCCESS_WITH_PARTIAL_COMPREHENSION:
+ case RESULT_SUCCESS_WITH_MISSING_INFO:
+ case RESULT_BEYOND_ME_CAPABILITIES:
+ case RESULT_COMMAND_TYPE_NOT_UNDERSTOOD_BY_ME:
+ case RESULT_COMMAND_DATA_NOT_UNDERSTOOD_BY_ME:
+ case RESULT_COMMAND_NUMBER_NOT_KNOWN_BY_ME:
+ case RESULT_ERROR_REQUIRED_VALUES_ARE_MISSING:
+ dst_tr[temp_index++] = 1;
+ dst_tr[temp_index++] = src_tr->result_type;
+ break;
+
+ case RESULT_ME_UNABLE_TO_PROCESS_COMMAND:
+ dst_tr[temp_index++] = 2;
+ dst_tr[temp_index++] = src_tr->result_type;
+ dst_tr[temp_index++] = src_tr->me_problem_type;
+ break;
+
+ default:
+ dbg("invalid response value[0x%x] in current TR", src_tr->result_type);
+ temp_index = 0;
+ break;
+ }
+
+ return temp_index;
+}
+
+static int _sat_encode_setup_idle_mode_text(const struct tel_sat_tr_setup_idle_mode_text_tlv *src_tr, char *dst_tr)
+{
+ int temp_index = 0, encoded_len = 0;
+
+ /* set command detail info */
+ encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, temp_index);
+ temp_index += encoded_len;
+
+ /* set device identities info */
+ encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, temp_index);
+ temp_index += encoded_len;
+
+ /* set result info */
+ dst_tr[temp_index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG);
+
+ switch (src_tr->result_type) {
+ case RESULT_SUCCESS:
+ case RESULT_SUCCESS_WITH_PARTIAL_COMPREHENSION:
+ case RESULT_SUCCESS_WITH_MISSING_INFO:
+ case RESULT_SUCCESS_BUT_REQUESTED_ICON_NOT_DISPLAYED:
+ case RESULT_BEYOND_ME_CAPABILITIES:
+ case RESULT_COMMAND_TYPE_NOT_UNDERSTOOD_BY_ME:
+ case RESULT_COMMAND_DATA_NOT_UNDERSTOOD_BY_ME:
+ case RESULT_COMMAND_NUMBER_NOT_KNOWN_BY_ME:
+ case RESULT_ERROR_REQUIRED_VALUES_ARE_MISSING:
+ dst_tr[temp_index++] = 1;
+ dst_tr[temp_index++] = src_tr->result_type;
+ break;
+
+ case RESULT_ME_UNABLE_TO_PROCESS_COMMAND:
+ case RESULT_FRAMES_ERROR:
+ dst_tr[temp_index++] = 2;
+ dst_tr[temp_index++] = src_tr->result_type;
+ dst_tr[temp_index++] = src_tr->me_problem_type;
+ break;
+
+ default:
+ dbg("invalid response value[0x%x] in current TR", src_tr->result_type);
+ temp_index = 0;
+ break;
+ }
+
+ return temp_index;
+}
+
+static int _sat_encode_send_dtmf(const struct tel_sat_tr_send_dtmf_tlv *src_tr, char *dst_tr)
+{
+ int temp_index = 0, encoded_len = 0;
+
+ /* set command detail info */
+ encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, temp_index);
+ temp_index += encoded_len;
+
+ /* set device identities info */
+ encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, temp_index);
+ temp_index += encoded_len;
+
+ /* set result info */
+ dst_tr[temp_index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG);
+
+ switch (src_tr->result_type) {
+ case RESULT_SUCCESS:
+ case RESULT_SUCCESS_WITH_PARTIAL_COMPREHENSION:
+ case RESULT_SUCCESS_WITH_MISSING_INFO:
+ case RESULT_SUCCESS_BUT_REQUESTED_ICON_NOT_DISPLAYED:
+ case RESULT_PROACTIVE_SESSION_TERMINATED_BY_USER:
+ case RESULT_BEYOND_ME_CAPABILITIES:
+ case RESULT_COMMAND_TYPE_NOT_UNDERSTOOD_BY_ME:
+ case RESULT_COMMAND_DATA_NOT_UNDERSTOOD_BY_ME:
+ case RESULT_COMMAND_NUMBER_NOT_KNOWN_BY_ME:
+ case RESULT_ERROR_REQUIRED_VALUES_ARE_MISSING:
+ dst_tr[temp_index++] = 1;
+ dst_tr[temp_index++] = src_tr->result_type;
+ break;
+
+ case RESULT_ME_UNABLE_TO_PROCESS_COMMAND:
+ dst_tr[temp_index++] = 2;
+ dst_tr[temp_index++] = src_tr->result_type;
+ dst_tr[temp_index++] = src_tr->me_problem_type;
+ break;
+
+ default:
+ dbg("invalid response value[0x%x] in current TR", src_tr->result_type);
+ temp_index = 0;
+ break;
+ }
+
+ return temp_index;
+}
+
+static int _sat_encode_language_notification(const struct tel_sat_tr_language_notification_tlv *src_tr, char *dst_tr)
+{
+ int temp_index = 0, encoded_len = 0;
+
+ /* set command detail info */
+ encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, temp_index);
+ temp_index += encoded_len;
+
+ /* set device identities info */
+ encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, temp_index);
+ temp_index += encoded_len;
+
+ /* set result info */
+ dst_tr[temp_index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG);
+
+ switch (src_tr->result_type) {
+ case RESULT_SUCCESS:
+ case RESULT_SUCCESS_WITH_PARTIAL_COMPREHENSION:
+ case RESULT_SUCCESS_WITH_MISSING_INFO:
+ case RESULT_BEYOND_ME_CAPABILITIES:
+ case RESULT_COMMAND_TYPE_NOT_UNDERSTOOD_BY_ME:
+ case RESULT_COMMAND_DATA_NOT_UNDERSTOOD_BY_ME:
+ case RESULT_COMMAND_NUMBER_NOT_KNOWN_BY_ME:
+ case RESULT_ERROR_REQUIRED_VALUES_ARE_MISSING:
+ dst_tr[temp_index++] = 1;
+ dst_tr[temp_index++] = src_tr->result_type;
+ break;
+
+ case RESULT_ME_UNABLE_TO_PROCESS_COMMAND:
+ case RESULT_FRAMES_ERROR:
+ dst_tr[temp_index++] = 2;
+ dst_tr[temp_index++] = src_tr->result_type;
+ dst_tr[temp_index++] = src_tr->me_problem_type;
+ break;
+
+ default:
+ dbg("invalid response value[0x%x] in current TR", src_tr->result_type);
+ temp_index = 0;
+ break;
+ }
+
+ return temp_index;
+}
+
+static int _sat_encode_launch_browser(const struct tel_sat_tr_launch_browser_tlv *src_tr, char *dst_tr)
+{
+ int temp_index = 0, encoded_len = 0;
+
+ /* set command detail info */
+ encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, temp_index);
+ temp_index += encoded_len;
+
+ /* set device identities info */
+ encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, temp_index);
+ temp_index += encoded_len;
+
+ /* set result info */
+ dst_tr[temp_index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG);
+
+ switch (src_tr->result_type) {
+ case RESULT_SUCCESS:
+ case RESULT_SUCCESS_WITH_PARTIAL_COMPREHENSION:
+ case RESULT_SUCCESS_WITH_MISSING_INFO:
+ case RESULT_PROACTIVE_SESSION_TERMINATED_BY_USER:
+ case RESULT_BACKWARD_MOVE_BY_USER:
+ case RESULT_NO_RESPONSE_FROM_USER:
+ case RESULT_BEYOND_ME_CAPABILITIES:
+ case RESULT_COMMAND_TYPE_NOT_UNDERSTOOD_BY_ME:
+ case RESULT_COMMAND_DATA_NOT_UNDERSTOOD_BY_ME:
+ case RESULT_COMMAND_NUMBER_NOT_KNOWN_BY_ME:
+ case RESULT_SUCCESS_BUT_REQUESTED_ICON_NOT_DISPLAYED:
+ dst_tr[temp_index++] = 1;
+ dst_tr[temp_index++] = src_tr->result_type;
+ break;
+
+ case RESULT_ME_UNABLE_TO_PROCESS_COMMAND:
+ case RESULT_NETWORK_UNABLE_TO_PROCESS_COMMAND:
+ case RESULT_FRAMES_ERROR:
+ dst_tr[temp_index++] = 2;
+ dst_tr[temp_index++] = src_tr->result_type;
+ dst_tr[temp_index++] = src_tr->me_problem_type;
+ break;
+
+ case RESULT_LAUNCH_BROWSER_GENERIC_ERROR_CODE:
+ dst_tr[temp_index++] = 2;
+ dst_tr[temp_index++] = src_tr->result_type;
+ dst_tr[temp_index++] = src_tr->browser_problem_type;
+ break;
+
+ default:
+ dbg("invalid response value[0x%x] in current TR", src_tr->result_type);
+ temp_index = 0;
+ break;
+ }
+
+ return temp_index;
+}
+
+static int _sat_encode_open_channel(const struct tel_sat_tr_open_channel_tlv *src_tr, char *dst_tr)
+{
+ int temp_index = 0, encoded_len = 0;
+
+ /* set command detail info */
+ encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, temp_index);
+ temp_index += encoded_len;
+
+ /* set device identities info */
+ encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, temp_index);
+ temp_index += encoded_len;
+
+ /* set result info */
+ dst_tr[temp_index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG);
+ switch (src_tr->result_type) {
+ case RESULT_SUCCESS:
+ case RESULT_SUCCESS_WITH_PARTIAL_COMPREHENSION:
+ case RESULT_SUCCESS_WITH_MISSING_INFO:
+ case RESULT_SUCCESS_BUT_REQUESTED_ICON_NOT_DISPLAYED:
+ case RESULT_SUCCESS_WITH_MODIFICATION:
+ dst_tr[temp_index++] = 1;
+ dst_tr[temp_index++] = src_tr->result_type;
+
+ /* set channel status */
+ encoded_len = _sat_encode_channel_status_tlv(&(src_tr->channel_status), dst_tr, temp_index);
+ temp_index += encoded_len;
+ break;
+
+ case RESULT_REFRESH_PRFRMD_BUT_INDICATED_USIM_NOT_ACTIVE:
+ case RESULT_PROACTIVE_SESSION_TERMINATED_BY_USER:
+ case RESULT_INTERACTION_WITH_CC_BY_SIM_IN_TMP_PRBLM:
+ case RESULT_BEYOND_ME_CAPABILITIES:
+ case RESULT_COMMAND_TYPE_NOT_UNDERSTOOD_BY_ME:
+ case RESULT_COMMAND_DATA_NOT_UNDERSTOOD_BY_ME:
+ case RESULT_COMMAND_NUMBER_NOT_KNOWN_BY_ME:
+ case RESULT_ERROR_REQUIRED_VALUES_ARE_MISSING:
+ case RESULT_USER_DID_NOT_ACCEPT_CALL_SETUP_REQ:
+ dst_tr[temp_index++] = 1;
+ dst_tr[temp_index++] = src_tr->result_type;
+ break;
+
+ case RESULT_ME_UNABLE_TO_PROCESS_COMMAND:
+ case RESULT_NETWORK_UNABLE_TO_PROCESS_COMMAND:
+ case RESULT_FRAMES_ERROR:
+ dst_tr[temp_index++] = 2;
+ dst_tr[temp_index++] = src_tr->result_type;
+ dst_tr[temp_index++] = src_tr->me_problem_type;
+ break;
+
+ case RESULT_BEARER_INDEPENDENT_PROTOCOL_ERROR:
+ dst_tr[temp_index++] = 2;
+ dst_tr[temp_index++] = src_tr->result_type;
+ dst_tr[temp_index++] = src_tr->bip_problem_type;
+ break;
+
+ default:
+ dbg("invalid response value[0x%x] in current TR", src_tr->result_type);
+ return 0;
+ }
+
+ return temp_index;
+}
+
+static int _sat_encode_close_channel(const struct tel_sat_tr_close_channel_tlv *src_tr, char *dst_tr)
+{
+ int temp_index = 0, encoded_len = 0;
+
+ /* set command detail info */
+ encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, temp_index);
+ temp_index += encoded_len;
+
+ /* set device identities info */
+ encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, temp_index);
+ temp_index += encoded_len;
+
+ /* set result info */
+ dst_tr[temp_index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG);
+ switch (src_tr->result_type) {
+ case RESULT_SUCCESS:
+ case RESULT_SUCCESS_WITH_PARTIAL_COMPREHENSION:
+ case RESULT_SUCCESS_WITH_MISSING_INFO:
+ case RESULT_SUCCESS_BUT_REQUESTED_ICON_NOT_DISPLAYED:
+ case RESULT_PROACTIVE_SESSION_TERMINATED_BY_USER:
+ case RESULT_BEYOND_ME_CAPABILITIES:
+ case RESULT_COMMAND_TYPE_NOT_UNDERSTOOD_BY_ME:
+ case RESULT_COMMAND_DATA_NOT_UNDERSTOOD_BY_ME:
+ case RESULT_COMMAND_NUMBER_NOT_KNOWN_BY_ME:
+ case RESULT_ERROR_REQUIRED_VALUES_ARE_MISSING:
+ dst_tr[temp_index++] = 1;
+ dst_tr[temp_index++] = src_tr->result_type;
+ break;
+
+ case RESULT_ME_UNABLE_TO_PROCESS_COMMAND:
+ case RESULT_FRAMES_ERROR:
+ dst_tr[temp_index++] = 2;
+ dst_tr[temp_index++] = src_tr->result_type;
+ dst_tr[temp_index++] = src_tr->me_problem_type;
+ break;
+
+ case RESULT_BEARER_INDEPENDENT_PROTOCOL_ERROR:
+ dst_tr[temp_index++] = 2;
+ dst_tr[temp_index++] = src_tr->result_type;
+ dst_tr[temp_index++] = src_tr->bip_problem_type;
+ break;
+
+ default:
+ dbg("invalid response value[0x%x] in current TR", src_tr->result_type);
+ temp_index = 0;
+ break;
+ }
+
+ return temp_index;
+}
+
+static int _sat_encode_send_data(const struct tel_sat_tr_send_data_tlv *src_tr, char *dst_tr)
+{
+ int temp_index = 0, encoded_len = 0;
+
+ /* set command detail info */
+ encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, temp_index);
+ temp_index += encoded_len;
+
+ /* set device identities info */
+ encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, temp_index);
+ temp_index += encoded_len;
+
+ /* set result info */
+ dst_tr[temp_index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG);
+ switch (src_tr->result_type) {
+ case RESULT_SUCCESS:
+ case RESULT_SUCCESS_WITH_PARTIAL_COMPREHENSION:
+ case RESULT_SUCCESS_WITH_MISSING_INFO:
+ case RESULT_SUCCESS_BUT_REQUESTED_ICON_NOT_DISPLAYED:
+ case RESULT_PROACTIVE_SESSION_TERMINATED_BY_USER:
+ case RESULT_BEYOND_ME_CAPABILITIES:
+ case RESULT_COMMAND_TYPE_NOT_UNDERSTOOD_BY_ME:
+ case RESULT_COMMAND_DATA_NOT_UNDERSTOOD_BY_ME:
+ case RESULT_COMMAND_NUMBER_NOT_KNOWN_BY_ME:
+ case RESULT_ERROR_REQUIRED_VALUES_ARE_MISSING:
+ dst_tr[temp_index++] = 1;
+ dst_tr[temp_index++] = src_tr->result_type;
+ encoded_len = _sat_encode_channel_data_length_tlv(&(src_tr->channel_data_len), dst_tr, temp_index);
+ temp_index += encoded_len;
+ break;
+
+ case RESULT_ME_UNABLE_TO_PROCESS_COMMAND:
+ case RESULT_NETWORK_UNABLE_TO_PROCESS_COMMAND:
+ case RESULT_FRAMES_ERROR:
+ dst_tr[temp_index++] = 2;
+ dst_tr[temp_index++] = src_tr->result_type;
+ dst_tr[temp_index++] = src_tr->me_problem_type;
+ break;
+
+ case RESULT_BEARER_INDEPENDENT_PROTOCOL_ERROR:
+ dst_tr[temp_index++] = 2;
+ dst_tr[temp_index++] = src_tr->result_type;
+ dst_tr[temp_index++] = src_tr->bip_problem_type;
+ break;
+
+ default:
+ dbg("invalid response value[0x%x] in current TR", src_tr->result_type);
+ temp_index = 0;
+ break;
+ }
+
+ return temp_index;
+}
+
+static int _sat_encode_receive_data(const struct tel_sat_tr_receive_data_tlv *src_tr, char *dst_tr)
+{
+ int temp_index = 0, encoded_len = 0;
+
+ /* set command detail info */
+ encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, temp_index);
+ temp_index += encoded_len;
+
+ /* set device identities info */
+ encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, temp_index);
+ temp_index += encoded_len;
+
+ /* set result info */
+ dst_tr[temp_index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG);
+ switch (src_tr->result_type) {
+ case RESULT_SUCCESS:
+ case RESULT_SUCCESS_WITH_PARTIAL_COMPREHENSION:
+ case RESULT_SUCCESS_WITH_MISSING_INFO:
+ case RESULT_SUCCESS_BUT_REQUESTED_ICON_NOT_DISPLAYED:
+ case RESULT_PROACTIVE_SESSION_TERMINATED_BY_USER:
+ case RESULT_BEYOND_ME_CAPABILITIES:
+ case RESULT_COMMAND_TYPE_NOT_UNDERSTOOD_BY_ME:
+ case RESULT_COMMAND_DATA_NOT_UNDERSTOOD_BY_ME:
+ case RESULT_COMMAND_NUMBER_NOT_KNOWN_BY_ME:
+ case RESULT_ERROR_REQUIRED_VALUES_ARE_MISSING:
+ dst_tr[temp_index++] = 1;
+ dst_tr[temp_index++] = src_tr->result_type;
+ encoded_len = _sat_encode_channel_data_tlv(&(src_tr->channel_data), dst_tr, temp_index);
+ temp_index += encoded_len;
+ encoded_len = _sat_encode_channel_data_length_tlv(&(src_tr->channel_data_len), dst_tr, temp_index);
+ temp_index += encoded_len;
+ break;
+
+ case RESULT_ME_UNABLE_TO_PROCESS_COMMAND:
+ case RESULT_FRAMES_ERROR:
+ dst_tr[temp_index++] = 2;
+ dst_tr[temp_index++] = src_tr->result_type;
+ dst_tr[temp_index++] = src_tr->me_problem_type;
+ break;
+
+ case RESULT_BEARER_INDEPENDENT_PROTOCOL_ERROR:
+ dst_tr[temp_index++] = 2;
+ dst_tr[temp_index++] = src_tr->result_type;
+ dst_tr[temp_index++] = src_tr->bip_problem_type;
+ break;
+
+ default:
+ dbg("invalid response value[0x%x] in current TR", src_tr->result_type);
+ temp_index = 0;
+ break;
+ }
+
+ return temp_index;
+}
+
+static int _sat_encode_get_channel_status(const struct tel_sat_tr_get_channel_status_tlv *src_tr, char *dst_tr)
+{
+ int temp_index = 0, encoded_len = 0;
+
+ /* set command detail info */
+ encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, temp_index);
+ temp_index += encoded_len;
+
+ /* set device identities info */
+ encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, temp_index);
+ temp_index += encoded_len;
+
+ /* set result info */
+ dst_tr[temp_index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG);
+ switch (src_tr->result_type) {
+ case RESULT_SUCCESS:
+ case RESULT_SUCCESS_WITH_PARTIAL_COMPREHENSION:
+ case RESULT_SUCCESS_WITH_MISSING_INFO:
+ case RESULT_SUCCESS_BUT_REQUESTED_ICON_NOT_DISPLAYED:
+ dst_tr[temp_index++] = 1;
+ dst_tr[temp_index++] = src_tr->result_type;
+ encoded_len = _sat_encode_channel_status_tlv(&(src_tr->channel_status), dst_tr, temp_index);
+ temp_index += encoded_len;
+ break;
+
+ case RESULT_PROACTIVE_SESSION_TERMINATED_BY_USER:
+ case RESULT_BEYOND_ME_CAPABILITIES:
+ case RESULT_COMMAND_TYPE_NOT_UNDERSTOOD_BY_ME:
+ case RESULT_COMMAND_DATA_NOT_UNDERSTOOD_BY_ME:
+ case RESULT_COMMAND_NUMBER_NOT_KNOWN_BY_ME:
+ case RESULT_ERROR_REQUIRED_VALUES_ARE_MISSING:
+ dst_tr[temp_index++] = 1;
+ dst_tr[temp_index++] = src_tr->result_type;
+ break;
+
+ case RESULT_ME_UNABLE_TO_PROCESS_COMMAND:
+ case RESULT_NETWORK_UNABLE_TO_PROCESS_COMMAND:
+ dst_tr[temp_index++] = 2;
+ dst_tr[temp_index++] = src_tr->result_type;
+ dst_tr[temp_index++] = src_tr->me_problem_type;
+ break;
+
+ case RESULT_BEARER_INDEPENDENT_PROTOCOL_ERROR:
+ dst_tr[temp_index++] = 2;
+ dst_tr[temp_index++] = src_tr->result_type;
+ dst_tr[temp_index++] = src_tr->bip_problem_type;
+ break;
+
+ default:
+ dbg("invalid response value[0x%x] in current TR", src_tr->result_type);
+ temp_index = 0;
+ break;
+ }
+
+ return temp_index;
+}
+
+static int _sat_encode_unsupport_command(const struct tel_sat_tr_unsupport_command_tlv *src_tr, char *dst_tr)
+{
+ int temp_index = 0, encoded_len = 0;
+
+ /* set command detail info */
+ encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, temp_index);
+ temp_index += encoded_len;
+
+ /* set device identities info */
+ encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, temp_index);
+ temp_index += encoded_len;
+
+ /* set result info */
+ dst_tr[temp_index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG);
+ dst_tr[temp_index++] = 1;
+ dst_tr[temp_index++] = src_tr->result_type;
+
+ return temp_index;
+}
+
+int tcore_sat_encode_terminal_response(const struct treq_sat_terminal_rsp_data *src_tr, char *dst_tr)
+{
+ int tr_len = 0;
+
+ if (!dst_tr)
+ return 0;
+
+ switch (src_tr->cmd_type) {
+ case SAT_PROATV_CMD_DISPLAY_TEXT:
+ tr_len = _sat_encode_display_text(&(src_tr->terminal_rsp_data.display_text), dst_tr);
+ break;
+
+ case SAT_PROATV_CMD_GET_INKEY:
+ tr_len = _sat_encode_get_inkey(&(src_tr->terminal_rsp_data.get_inkey), dst_tr);
+ break;
+
+ case SAT_PROATV_CMD_GET_INPUT:
+ tr_len = _sat_encode_get_input(&(src_tr->terminal_rsp_data.get_input), dst_tr);
+ break;
+
+ case SAT_PROATV_CMD_MORE_TIME:
+ tr_len = _sat_encode_more_time(&(src_tr->terminal_rsp_data.more_time), dst_tr);
+ break;
+
+ case SAT_PROATV_CMD_PLAY_TONE:
+ tr_len = _sat_encode_play_tone(&(src_tr->terminal_rsp_data.play_tone), dst_tr);
+ break;
+
+ case SAT_PROATV_CMD_REFRESH:
+ tr_len = _sat_encode_refresh(&(src_tr->terminal_rsp_data.refresh), dst_tr);
+ break;
+
+ case SAT_PROATV_CMD_SETUP_MENU:
+ tr_len = _sat_encode_setup_menu(&(src_tr->terminal_rsp_data.setup_menu), dst_tr);
+ break;
+
+ case SAT_PROATV_CMD_SELECT_ITEM:
+ tr_len = _sat_encode_select_item(&(src_tr->terminal_rsp_data.select_item), dst_tr);
+ break;
+
+ case SAT_PROATV_CMD_SEND_SMS:
+ tr_len = _sat_encode_send_sms(&(src_tr->terminal_rsp_data.send_sms), dst_tr);
+ break;
+
+ case SAT_PROATV_CMD_SEND_SS:
+ tr_len = _sat_encode_send_ss(&(src_tr->terminal_rsp_data.send_ss), dst_tr);
+ break;
+
+ case SAT_PROATV_CMD_SEND_USSD:
+ tr_len = _sat_encode_send_ussd(&(src_tr->terminal_rsp_data.send_ussd), dst_tr);
+ break;
+
+ case SAT_PROATV_CMD_SETUP_CALL:
+ tr_len = _sat_encode_setup_call(&(src_tr->terminal_rsp_data.setup_call), dst_tr);
+ break;
+
+ case SAT_PROATV_CMD_PROVIDE_LOCAL_INFO:
+ tr_len = _sat_encode_provide_local_info(&(src_tr->terminal_rsp_data.provide_local_info), dst_tr);
+ break;
+
+ case SAT_PROATV_CMD_SETUP_EVENT_LIST:
+ tr_len = _sat_encode_setup_event_list(&(src_tr->terminal_rsp_data.setup_event_list), dst_tr);
+ break;
+
+ case SAT_PROATV_CMD_SETUP_IDLE_MODE_TEXT:
+ tr_len = _sat_encode_setup_idle_mode_text(&(src_tr->terminal_rsp_data.setup_idle_mode_text), dst_tr);
+ break;
+
+ case SAT_PROATV_CMD_SEND_DTMF:
+ tr_len = _sat_encode_send_dtmf(&(src_tr->terminal_rsp_data.send_dtmf), dst_tr);
+ break;
+
+ case SAT_PROATV_CMD_LANGUAGE_NOTIFICATION:
+ tr_len = _sat_encode_language_notification(&(src_tr->terminal_rsp_data.language_notification), dst_tr);
+ break;
+
+ case SAT_PROATV_CMD_LAUNCH_BROWSER:
+ tr_len = _sat_encode_launch_browser(&(src_tr->terminal_rsp_data.launch_browser), dst_tr);
+ break;
+
+ case SAT_PROATV_CMD_OPEN_CHANNEL:
+ tr_len = _sat_encode_open_channel(&(src_tr->terminal_rsp_data.open_channel), dst_tr);
+ break;
+
+ case SAT_PROATV_CMD_CLOSE_CHANNEL:
+ tr_len = _sat_encode_close_channel(&(src_tr->terminal_rsp_data.close_channel), dst_tr);
+ break;
+
+ case SAT_PROATV_CMD_SEND_DATA:
+ tr_len = _sat_encode_send_data(&(src_tr->terminal_rsp_data.send_data), dst_tr);
+ break;
+
+ case SAT_PROATV_CMD_RECEIVE_DATA:
+ tr_len = _sat_encode_receive_data(&(src_tr->terminal_rsp_data.receive_data), dst_tr);
+ break;
+
+ case SAT_PROATV_CMD_GET_CHANNEL_STATUS:
+ tr_len = _sat_encode_get_channel_status(&(src_tr->terminal_rsp_data.get_channel_status), dst_tr);
+ break;
+
+ default:
+ tr_len = _sat_encode_unsupport_command(&(src_tr->terminal_rsp_data.unsupport_cmd), dst_tr);
+ break;
+ }
+
+ return tr_len;
+}
+
+CoreObject *tcore_sat_new(TcorePlugin *p, const char *name,
+ struct tcore_sat_operations *ops, TcoreHal *hal)
+{
+ CoreObject *o = NULL;
+ struct private_object_data *po = NULL;
+
+ if (!p)
+ return NULL;
+
+ o = tcore_object_new(p, name, hal);
+ if (!o)
+ return NULL;
+
+ po = calloc(1, sizeof(struct private_object_data));
+ if (!po) {
+ tcore_object_free(o);
+ return NULL;
+ }
+
+ /* set ops to default type when core object is created. */
+ po->ops[TCORE_OPS_TYPE_CP] = ops;
+
+ tcore_object_set_type(o, CORE_OBJECT_TYPE_SAT);
+ tcore_object_link_object(o, po);
+ tcore_object_set_free_hook(o, _free_hook);
+ tcore_object_set_dispatcher(o, _dispatcher);
+
+ return o;
+}
+
+void tcore_sat_free(CoreObject *o)
+{
+ CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_SAT);
+
+ tcore_object_free(o);
+}
+
+void tcore_sat_set_ops(CoreObject *o, struct tcore_sat_operations *ops, enum tcore_ops_type ops_type)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_SAT);
+ CORE_OBJECT_VALIDATE_OPS_RETURN(ops_type);
+
+ po = (struct private_object_data *)tcore_object_ref_object(o);
+ if (!po) {
+ err("po is NULL");
+ return;
+ }
+
+ po->ops[ops_type] = ops;
+}
--- /dev/null
+/*
+ * libtcore
+ *
+ * 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.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <glib.h>
+
+#include "tcore.h"
+#include "internal/tcore_types.h"
+#include "plugin.h"
+#include "queue.h"
+#include "user_request.h"
+#include "core_object.h"
+#include "co_sim.h"
+
+#define SIM_FILE_TYPE_TAG 0x07
+#define SIM_FCP_TEMPLATE_TAG 0x62
+#define SIM_FILE_DESCRIPTOR_TAG 0x82
+#define SIM_FILE_IDENTIFIER_TAG 0x83
+#define SIM_PROPRIETARY_INFORMATION_TAG 0xA5
+#define SIM_LIFE_CYCLE_STATUS_TAG 0x8A
+#define SIM_FILE_SIZE_TAG 0x80
+#define SIM_TOTAL_FILE_SIZE_TAG 0x81
+#define SIM_SHORT_FILE_IDENTIFIER_TAG 0x88
+
+/* GSM file types */
+#define SIM_FTYPE_RFU 0x0
+#define SIM_FTYPE_MF 0x1
+#define SIM_FTYPE_DF 0x2
+#define SIM_FTYPE_EF 0x4
+
+struct private_object_data {
+ struct tcore_sim_operations *ops[TCORE_OPS_TYPE_MAX];
+
+ unsigned char app_list;
+ enum tel_sim_type type; /**< Provides the SIM card type*/
+ enum tel_sim_status sim_status; /**< Provides the card status*/
+ struct tel_sim_imsi imsi; /**< Provides IMSI information*/
+ gboolean b_sim_changed; /**< Provides SIM card Identification- 0:no changed, 1:changed*/
+ gboolean b_cphs; /**< Whether current SIM is for CPHS or not*/
+ struct tel_sim_service_table *svct; /**< (U)SIM Service Table information*/
+ struct tel_sim_ecc_list *ecc_list;
+ struct tel_sim_msisdn_list *msisdn_list;
+ struct tel_sim_spn *spn;
+ struct tel_sim_cphs_netname *cphs_netname;
+ struct tel_sim_iccid *iccid;
+ struct tel_sim_cphs_csp *csp;
+ struct tel_sim_ist *ist;
+ void *userdata; /**< free use data*/
+};
+
+/*
+ * Below table is created by referring two sites:
+ *
+ * 1) ITU "Mobile Network Code (MNC) for the international
+ * identification plan for mobile terminals and mobile users"
+ * which is available as an annex to the ITU operational bulletin
+ * available here: http://www.itu.int/itu-t/bulletin/annex.html
+ *
+ * 2) The ISO 3166 country codes list, available here:
+ * http://www.iso.org/iso/en/prods-services/iso3166ma/02iso-3166-code-lists/index.html
+ *
+ */
+static const char *mcc_having_3digits_mnc[] = {
+ "302", /* Canada */
+ "310", "311", "312", "313", "314", "315", "316", /* United States of America */
+ /* "334",*/ /* Mexico (uses 3-digits MNC only partially.) */
+ "338", /* Jamaica */
+ "342", /* Barbados */
+ "344", /* Antigua and Barbuda */
+ "346", /* Cayman Islands */
+ "348", /* British Virgin Islands */
+ "365", /* Anguilla */
+ "708", /* Honduras (Republic of) */
+ /* "722", */ /* Argentine Republic (uses 3-digits MNC only partially.) */
+ "732", /* Colombia (Republic of) */
+};
+
+static const char *plmn_having_3digits_mnc[] = {
+ /* Mexico */
+ "334020", /* Telcel */
+ "334050", /* Iusacell/Unefon */
+ /* India */
+ "405025", "405026", "405027", "405028", "405029", "405030", "405031", "405032",
+ "405033", "405034", "405035", "405036", "405037", "405038", "405039", "405040",
+ "405041", "405042", "405043", "405044", "405045", "405046", "405047", "405750",
+ "405751", "405752", "405753", "405754", "405755", "405756", "405799", "405800",
+ "405801", "405802", "405803", "405804", "405805", "405806", "405807", "405808",
+ "405809", "405810", "405811", "405812", "405813", "405814", "405815", "405816",
+ "405817", "405818", "405819", "405820", "405821", "405822", "405823", "405824",
+ "405825", "405826", "405827", "405828", "405829", "405830", "405831", "405832",
+ "405833", "405834", "405835", "405836", "405837", "405838", "405839", "405840",
+ "405841", "405842", "405843", "405844", "405845", "405846", "405847", "405848",
+ "405849", "405850", "405851", "405852", "405853", "405875", "405876", "405877",
+ "405878", "405879", "405880", "405881", "405882", "405883", "405884", "405885",
+ "405886", "405908", "405909", "405910", "405911", "405912", "405913", "405914",
+ "405915", "405916", "405917", "405918", "405919", "405920", "405921", "405922",
+ "405923", "405924", "405925", "405926", "405927", "405928", "405929", "405930",
+ "405931", "405932",
+ /* Malaysia */
+ "502142", "502143", "502145", "502146", "502147", "502148",
+ /* Argentina */
+ "722070", /* Movistar AR */
+ "722310", /* Claro AR */
+ "722341", /* Personal AR */
+};
+
+gboolean tcore_sim_check_plmn_having_3digits_mnc(char *plmn)
+{
+ int num = 0;
+ int i = 0;
+ char *mcc = NULL;
+
+ mcc = g_strndup(plmn, 3 + 1);
+ if (mcc) {
+ mcc[3] = '\0';
+ num = G_N_ELEMENTS(mcc_having_3digits_mnc);
+ for (i = 0; i < num; i++) {
+ if (strcmp((const char *)mcc, mcc_having_3digits_mnc[i]) == 0) {
+ g_free(mcc);
+ return TRUE;
+ }
+ }
+ g_free(mcc);
+ }
+
+ num = G_N_ELEMENTS(plmn_having_3digits_mnc);
+ for (i = 0; i < num; i++)
+ if (strcmp((const char *)plmn, plmn_having_3digits_mnc[i]) == 0)
+ return TRUE;
+
+ return FALSE;
+}
+
+static TReturn _dispatcher(CoreObject *o, UserRequest *ur, enum tcore_ops_type ops_type)
+{
+ enum tcore_request_command command;
+ struct private_object_data *po = tcore_object_ref_object(o);
+ struct tcore_sim_operations *ops = NULL;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_SIM, TCORE_RETURN_EINVAL);
+ CORE_OBJECT_VALIDATE_OPS_RETURN_VAL(ops_type, TCORE_RETURN_EINVAL);
+
+ tcore_check_null_ret_err("po", po, TCORE_RETURN_EINVAL);
+ tcore_check_null_ret_err("ur", ur, TCORE_RETURN_EINVAL);
+
+ ops = po->ops[ops_type];
+ tcore_check_null_ret_err("ops", ops, TCORE_RETURN_FAILURE);
+
+ command = tcore_user_request_get_command(ur);
+
+ switch (command) {
+ case TREQ_SIM_VERIFY_PINS:
+ tcore_check_null_ret_err("ops->verify_pins",
+ ops->verify_pins, TCORE_RETURN_ENOSYS);
+
+ return ops->verify_pins(o, ur);
+
+ case TREQ_SIM_VERIFY_PUKS:
+ tcore_check_null_ret_err("ops->verify_puks",
+ ops->verify_puks, TCORE_RETURN_ENOSYS);
+
+ return ops->verify_puks(o, ur);
+
+ case TREQ_SIM_CHANGE_PINS:
+ tcore_check_null_ret_err("ops->change_pins",
+ ops->change_pins, TCORE_RETURN_ENOSYS);
+
+ return ops->change_pins(o, ur);
+
+ case TREQ_SIM_GET_FACILITY_STATUS:
+ tcore_check_null_ret_err("ops->get_facility_status",
+ ops->get_facility_status, TCORE_RETURN_ENOSYS);
+
+ return ops->get_facility_status(o, ur);
+
+ case TREQ_SIM_DISABLE_FACILITY:
+ tcore_check_null_ret_err("ops->disable_facility",
+ ops->disable_facility, TCORE_RETURN_ENOSYS);
+
+ return ops->disable_facility(o, ur);
+
+ case TREQ_SIM_ENABLE_FACILITY:
+ tcore_check_null_ret_err("ops->enable_facility",
+ ops->enable_facility, TCORE_RETURN_ENOSYS);
+
+ return ops->enable_facility(o, ur);
+
+ case TREQ_SIM_GET_LOCK_INFO:
+ tcore_check_null_ret_err("ops->get_lock_info",
+ ops->get_lock_info, TCORE_RETURN_ENOSYS);
+
+ return ops->get_lock_info(o, ur);
+
+ case TREQ_SIM_TRANSMIT_APDU:
+ tcore_check_null_ret_err("ops->transmit_apdu",
+ ops->transmit_apdu, TCORE_RETURN_ENOSYS);
+
+ return ops->transmit_apdu(o, ur);
+
+ case TREQ_SIM_GET_ATR:
+ tcore_check_null_ret_err("ops->get_atr",
+ ops->get_atr, TCORE_RETURN_ENOSYS);
+
+ return ops->get_atr(o, ur);
+
+ case TREQ_SIM_SET_LANGUAGE:
+ case TREQ_SIM_SET_CALLFORWARDING:
+ case TREQ_SIM_SET_MESSAGEWAITING:
+ case TREQ_SIM_SET_MAILBOX:
+#if defined TIZEN_GLOBALCONFIG_ENABLE_CSP
+ case TREQ_SIM_SET_CPHS_CSP_INFO:
+#endif
+ tcore_check_null_ret_err("ops->update_file",
+ ops->update_file, TCORE_RETURN_ENOSYS);
+
+ return ops->update_file(o, ur);
+
+ case TREQ_SIM_GET_ECC:
+ case TREQ_SIM_GET_LANGUAGE:
+ case TREQ_SIM_GET_ICCID:
+ case TREQ_SIM_GET_MAILBOX:
+ case TREQ_SIM_GET_CALLFORWARDING:
+ case TREQ_SIM_GET_MESSAGEWAITING:
+ case TREQ_SIM_GET_CPHS_INFO:
+ case TREQ_SIM_GET_SERVICE_TABLE:
+ case TREQ_SIM_GET_MSISDN:
+ case TREQ_SIM_GET_SPN:
+ case TREQ_SIM_GET_SPDI:
+ case TREQ_SIM_GET_OPL:
+ case TREQ_SIM_GET_PNN:
+ case TREQ_SIM_GET_CPHS_NETNAME:
+ case TREQ_SIM_GET_OPLMNWACT:
+ case TREQ_SIM_GET_ICON:
+ case TREQ_SIM_GET_IMPI:
+ case TREQ_SIM_GET_IMPU:
+ case TREQ_SIM_GET_GID:
+ case TREQ_SIM_GET_DOMAIN:
+ case TREQ_SIM_GET_PCSCF:
+ case TREQ_SIM_GET_ISIM_SERVICE_TABLE:
+ tcore_check_null_ret_err("ops->read_file",
+ ops->read_file, TCORE_RETURN_ENOSYS);
+
+ return ops->read_file(o, ur);
+
+ case TREQ_SIM_REQ_AUTHENTICATION:
+ tcore_check_null_ret_err("ops->req_authentication",
+ ops->req_authentication, TCORE_RETURN_ENOSYS);
+
+ return ops->req_authentication(o, ur);
+
+ case TREQ_SIM_SET_POWERSTATE:
+ tcore_check_null_ret_err("ops->set_powerstate",
+ ops->set_powerstate, TCORE_RETURN_ENOSYS);
+
+ return ops->set_powerstate(o, ur);
+
+ case TREQ_SIM_SET_PROVISIONING:
+ tcore_check_null_ret_err("ops->set_provisioning",
+ ops->set_provisioning, TCORE_RETURN_ENOSYS);
+
+ return ops->set_provisioning(o, ur);
+
+ default:
+ warn("unhandled request command[%d]", command);
+ break;
+ }
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+static void _free_hook(CoreObject *o)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_SIM);
+
+ po = tcore_object_ref_object(o);
+ if (po) {
+ if (po->svct)
+ free(po->svct);
+
+ if (po->ecc_list)
+ free(po->ecc_list);
+
+ if (po->msisdn_list)
+ free(po->msisdn_list);
+
+ if (po->spn)
+ free(po->spn);
+
+ if (po->cphs_netname)
+ free(po->cphs_netname);
+
+ if (po->iccid)
+ free(po->iccid);
+
+ if (po->csp)
+ free(po->csp);
+
+ if (po->ist)
+ free(po->ist);
+
+ free(po);
+ tcore_object_link_object(o, NULL);
+ }
+}
+
+static void _reverse(char *p_in, int length)
+{
+ int i, j = length - 1;
+
+ for (i = 0; i < j; i++) {
+ int t = p_in[i];
+ p_in[i] = p_in[j];
+ p_in[j--] = t;
+ }
+}
+
+static char *_acitoa(int n, char *str, int b)
+{
+ int i = 0;
+
+ do {
+ str[i++] = "0123456789ABCDEF"[n % b];
+ } while ((n /= b) > 0);
+
+ _reverse(str, i);
+
+ str[i] = '\0';
+
+ return str;
+}
+
+/*******************************************************************************
+ Convert Digit to BCD (BCD to Digit)
+
+ bcd <---> digit
+ 0xa 0x2a '*'
+ 0xb 0x23 '#'
+ 0xc 0x70 'P'
+ 0xd '?'
+ 0xf 0
+ 1032547698 0123456789
+
+ ********************************************************************************/
+/**
+ * This function is used to Convert Digit to BCD (Digit to BCD)
+ *
+ * @return None
+ * @param[out] bcdCode - BCD output
+ * @param[in] digits - Digit input
+ * @param[in] digitLen - digit length
+ * @Interface Synchronous.
+ * @remark
+ * @Refer
+ */
+static void _digit_to_bcd(char *bcdCode, char *digits, int digitLen)
+{
+ int i, j, digit;
+ unsigned char higher, lower;
+
+ /* 0123456789 -> 1032547698 */
+ for (i = 0, j = 0; i < digitLen; i = i + 2, j++) {
+ if (digits[i] == '*')
+ digit = 0x0A;
+ else if (digits[i] == '#')
+ digit = 0x0B;
+ else if (toupper((int) digits[i]) == 'P')
+ digit = 0x0C;
+ else if ((digits[i]) == '?')
+ digit = 0x0D;
+ else
+ digit = (int) digits[i];
+
+ lower = digit & 0x0F;
+
+ if (digitLen != i + 1) {
+ if (digits[i + 1] == '*')
+ digit = 0x0A;
+ else if (digits[i + 1] == '#')
+ digit = 0x0B;
+ else if (toupper((int) digits[i + 1]) == 'P')
+ digit = 0x0C;
+ else if (digits[i + 1] == '?')
+ digit = 0x0D;
+ else
+ digit = (int) digits[i + 1];
+ higher = digit & 0x0F;
+ } else
+ higher = 0xFF;
+
+ bcdCode[j] = (higher << 4) | lower;
+ }
+}
+
+/**
+ * This function is used to Convert BCD to Digit (BCD to Digit)
+ *
+ * @return None
+ * @param[out] digit - Digit output output
+ * @param[in] bcdCode - BCD Input
+ * @param[in] bcdLen - BCD length
+ * @Interface Synchronous.
+ * @remark
+ * @Refer
+ */
+static unsigned long _bcd_to_digit(char *digit, char *bcdCode, int bcdLen)
+{
+ int i, h, l;
+ char c[2];
+ unsigned char higher, lower;
+ unsigned long digitLen = 0;
+
+ /* 0123456789 <- 1032547698 */
+ memset((void *)digit, 0, bcdLen * 2);
+
+ for (i = 0; i < bcdLen; i++) {
+ higher = (bcdCode[i] >> 4) & 0x0F; /* get high nibble */
+
+ if (higher == 0x0A)
+ higher = '*'; /* =0x2A */
+ else if (higher == 0x0B)
+ higher = '#'; /* =0x23 */
+ else if (higher == 0x0C)
+ higher = 'P'; /* =0x70, DTMF Control digit */
+ else if (higher == 0x0D)
+ higher = '?';
+ else if (higher == 0x0F)
+ higher = 0;
+ else {
+ h = (int) higher;
+ _acitoa(h, c, 16);
+ higher = (char) toupper(*c);
+ }
+
+ lower = bcdCode[i] & 0x0F; /* get low nibble */
+
+ if (lower == 0x0A)
+ lower = '*';
+ else if (lower == 0x0B)
+ lower = '#';
+ else if (lower == 0x0C)
+ lower = 'P'; /* DTMF Control digit */
+ else if (lower == 0x0D)
+ lower = '?';
+ else if (lower == 0x0F)
+ lower = 0;
+ else {
+ l = (int) lower;
+ _acitoa(l, c, 16);
+ lower = (char) toupper(*c);
+ }
+
+ digit[i * 2] = lower;
+ digit[i * 2 + 1] = higher;
+ }
+
+ digitLen = (unsigned long)strlen(digit);
+ return digitLen;
+}
+
+/**
+ * This function is used to get(decode) string name
+ *
+ * @return length of string
+ * @param[out] palpha_id - Alpha string
+ * @param[in] pRecord - Input raw data
+ * @param[in] alphaIDMaxLen - Max size of alpha id array
+ * @Interface Synchronous.
+ * @remark
+ * @Refer
+ */
+static unsigned long _get_string(unsigned char *palpha_id, unsigned char *pRecord, unsigned long alphaIDMaxLen)
+{
+ unsigned long i, alphaIDLen = 0;
+ unsigned char *pAlphaID = (unsigned char *) palpha_id;
+
+ memset((void *)pAlphaID, 0, alphaIDMaxLen);
+
+ if (pRecord[0] == 0xFF)
+ return alphaIDLen;
+
+ for (i = 0; i < alphaIDMaxLen; i++) {
+ if (pRecord[0] <= 0x7F && pRecord[i] == 0xFF)
+ break;
+
+ pAlphaID[i] = pRecord[i];
+ alphaIDLen++;
+ }
+
+ return alphaIDLen;
+}
+
+/**
+ * This function is used to set(encode) string name
+ *
+ * @return length of string
+ * @param[in] palpha_id - Alpha string input
+ * @param[out] pRecord - output raw data
+ * @param[in] alphaIDMaxLen - Max size of alpha id array
+ * @Interface Synchronous.
+ * @remark
+ * @Refer
+ */
+static void _set_string(unsigned char *pRecord, unsigned char *palpha_id, unsigned long alphaIDMaxLen)
+{
+ unsigned long i;
+ unsigned char *pAlphaID = (unsigned char *) palpha_id;
+
+ memset((void *) pRecord, 0xFF, alphaIDMaxLen);
+
+ for (i = 0; i < alphaIDMaxLen; i++)
+ pRecord[i] = pAlphaID[i];
+}
+
+static gboolean _is_empty(unsigned char *p_in, int in_length)
+{
+ int i;
+ for (i = 0; i < in_length; i++) {
+ if (p_in[i] != 0xFF)
+ return FALSE;
+ }
+
+ dbg("current index has empty data");
+ return TRUE; /* this is empty record */
+}
+
+/**
+ * This function is used to get BCD length
+ *
+ * @return length of string
+ * @param[in] pBcdData - BCD Input data
+ * @param[in] bcdMaxLen - BCD Max data Length
+ * @Interface Synchronous.
+ * @remark
+ * @Refer
+ */
+static int _get_valid_bcd_byte(unsigned char *pBcdData, int bcdMaxLen)
+{
+ int i, bcd_length = 0;
+
+ for (i = 0; i < bcdMaxLen; i++) {
+ if (pBcdData[i] == 0xFF)
+ break;
+
+ bcd_length++;
+ }
+
+ return bcd_length;
+}
+
+/**
+ * This function is used to get unpacked 8bit Format from GSM 7bit packed string.
+ *
+ * @return the length of unpacked characters .
+ * @param[out] out_string Specifies the unpacked output string
+ * @param[in] in_string Contains the input string to be unpacked
+ * @param[in] in_string_len Contains the input string length
+ * @remark
+ */
+static int _unpack_7bit28bit(unsigned char *pInString, unsigned int inStringLen, unsigned char *pOutString)
+{
+ int i = 0;
+ unsigned int pos = 0;
+ unsigned short shift = 0;
+ int outlen = 0;
+ outlen = (short int)((inStringLen * 8) / 7);
+
+ for (i = 0; pos < inStringLen; i++, pos++) {
+ pOutString[i] = (pInString[pos] << shift) & 0x7F;
+
+ if (pos != 0) {
+ /* except the first byte, a character contains some bits from the previous byte. */
+ pOutString[i] |= pInString[pos - 1] >> (8 - shift);
+ }
+
+ shift++;
+
+ if (shift == 7) {
+ shift = 0;
+
+ /* a possible extra complete character is available */
+ i++;
+ pOutString[i] = pInString[pos] >> 1;
+ }
+ }
+
+ /* If a character is '\r'(13), change it to space(32) */
+ for (i = 0; i < outlen; i++)
+ if (pOutString[i] == 13) pOutString[i] = 32;
+
+ pOutString[outlen] = '\0';
+
+ dbg("unpack is done with outlen[%d] and array index[%d], out string[%s]", outlen, i, pOutString);
+ return (unsigned int)(i);
+}
+
+static int _ucs2_to_utf8(int in_length, unsigned char *in_data, int *out_length, unsigned char *out_data)
+{
+ int i, j;
+
+ if (in_length == 0 || in_data == NULL || out_data == NULL) {
+ dbg("Unicode Decode Failed as text length is 0");
+ return FALSE;
+ }
+
+ if (0 != (in_length % 2)) {
+ dbg(" ##### Unicode decoding failed due to invalid text length [%d]",
+ in_length);
+ return FALSE;
+ }
+
+ for (i = 0, j = 0; i < in_length; i++) {
+ out_data[i] = in_data[j];
+ j = j + 2;
+ }
+
+ *out_length = (in_length / 2);
+ out_data[i] = '\0';
+ return TRUE;
+}
+
+static int _decode_cdma_imsi_util(char *imsi, unsigned short *mcc, unsigned char *mnc,
+ unsigned long *min1, unsigned short *min2)
+{
+ unsigned short country_code = *mcc;
+ unsigned char nw_code = *mnc;
+ unsigned long imsi_min1 = *min1;
+ unsigned short imsi_min2 = *min2;
+ unsigned short second_three = 0;
+ unsigned char thousands = 0;
+ unsigned short last_three = 0;
+ unsigned char min_to_digit[] = {'1', '2', '3', '4', '5', '6', '7', '8', '9', '0'};
+ unsigned char bcd_to_num[] = {0xFF, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
+ int p_digit = 0;
+ int digit = 0;
+
+ /* Convert Country code of IMSI */
+ if (country_code <= 999) {
+ digit = min_to_digit[country_code/100];
+ imsi[p_digit++] = digit;
+ country_code %= 100;
+
+ digit = min_to_digit[country_code / 10];
+ imsi[p_digit++] = digit;
+
+ digit = min_to_digit[country_code % 10];
+ imsi[p_digit++] = digit;
+
+ } else {
+ err("Invalid Country code");
+ return -1;
+ }
+
+ /* Convert Network code of IMSI */
+ if (nw_code <= 99) {
+ digit = min_to_digit[nw_code / 10];
+ imsi[p_digit++] = digit;
+
+ digit = min_to_digit[nw_code % 10];
+ imsi[p_digit++] = digit;
+ } else {
+ err("Invalid Network code");
+ return -1;
+ }
+
+ /* Convert First Three Digits of IMSI */
+ if (imsi_min2 <= 999) {
+ digit = min_to_digit[imsi_min2 / 100];
+ imsi[p_digit++] = digit;
+ imsi_min2 %= 100;
+
+ digit = min_to_digit[imsi_min2 / 10];
+ imsi[p_digit++] = digit;
+
+ digit = min_to_digit[imsi_min2 % 10];
+ imsi[p_digit++] = digit;
+ } else {
+ err("Invalid IMSI_MIN2 code");
+ return -1;
+ }
+
+ /* Convert Last Seven digits of IMSI */
+ second_three = (imsi_min1 & 0x00FFC000) >> 14;
+ thousands = (imsi_min1 & 0x00003C00) >> 10;
+ last_three = (imsi_min1 & 0x000003FF) >> 0;
+
+ thousands = bcd_to_num[thousands];
+ if ((thousands != 0xFF) && (second_three <= 999) && (last_three <= 999)) {
+ digit = min_to_digit[second_three / 100];
+ imsi[p_digit++] = digit;
+
+ second_three %= 100;
+
+ digit = min_to_digit[second_three / 10];
+ imsi[p_digit++] = digit;
+
+ digit = min_to_digit[second_three % 10];
+ imsi[p_digit++] = digit;
+
+ imsi[p_digit++] = thousands;
+
+ digit = min_to_digit[last_three / 100];
+ imsi[p_digit++] = digit;
+
+ last_three %= 100;
+
+ digit = min_to_digit[last_three / 10];
+ imsi[p_digit++] = digit;
+
+ digit = min_to_digit[last_three % 10];
+ imsi[p_digit++] = digit;
+ } else {
+ err("Invalid IMSI_MIN1 code");
+ return -1;
+ }
+
+ return p_digit;
+}
+
+/**
+ * This function is used to decode 3 bytes of plmn string encoded as TS 24.008 to 6 bytes char string.
+ *
+ * @return void .
+ * @param[out] out decoded output string (must be 6 + 1 bytes)
+ * @param[in] in encoded input string (must be 3 bytes)
+ * @remark
+ */
+static void _decode_plmn(const unsigned char *in, unsigned char *out)
+{
+ unsigned char temp[6 + 1] = {0, };
+ int i;
+ unsigned char higher, lower;
+
+ for (i = 0; i < 3; i++) {
+ higher = (in[i] >> 4) & 0x0F; /* get high nibble */
+ if (higher < 0x0A) {
+ /* if it is a number */
+ temp[i*2] = higher + 0x30;
+ } else if (higher == 0x0D) {
+ /* 0x0D (BCD digit) is regarded as wild character by TS 24.008 */
+ temp[i*2] = 'D';
+ } else
+ temp[i*2] = 0x00;
+
+ lower = in[i] & 0x0F; /* get low nibble */
+ if (lower < 0x0A) {
+ /* if it is a number */
+ temp[i*2 + 1] = lower + 0x30;
+ } else if (lower == 0x0D) {
+ /* 0x0D (BCD digit) is regarded as wild character by TS 24.008 */
+ temp[i*2 + 1] = 'D';
+ } else
+ temp[i*2 + 1] = 0x00;
+ }
+
+ /* according to PLMN digits order by TS 24.008 */
+ /* MCC */
+ out[0] = temp[1];
+ out[1] = temp[0];
+ out[2] = temp[3];
+ /* MNC */
+ out[3] = temp[5];
+ out[4] = temp[4];
+ out[5] = temp[2];
+
+ out[6] = '\0';
+
+ /*
+ * [14.08.21]
+ * As NA Operators requested,
+ * for NA operators (MCC 310 ~ 316),
+ * if 6th digit of MNC is 'F' then should be regarded as '0'.
+ */
+ if (out[5] == 0x00
+ && strncmp((const char *)out, "31", 2) == 0
+ && ('0' <= out[2] && out[2] <= '6')) {
+ out[5] = '0';
+ }
+}
+
+static inline unsigned short int _swap_bytes16(unsigned short int x)
+{
+ return ((x & 0xFF00) >> 8) | ((x & 0x00FF) << 8);
+}
+
+/**
+ * According to ETSI 102.221 (3GPP specification refers it), EF-ICCID is coded by BCD, left justified and padded with 'F'.
+ * This EF is mandatory and byte length is fixed with 10 bytes. So actual maximum length of ICCID is 20 digits.
+ */
+gboolean tcore_sim_decode_iccid(struct tel_sim_iccid *p_out, unsigned char *p_in, int in_length)
+{
+ int bcd_byte = 0;
+ int char_length = 0;
+
+ if (p_in == NULL || p_out == NULL)
+ return FALSE;
+
+ if (in_length == 0 || in_length > 10)
+ return FALSE;
+
+ memset((void *)p_out->iccid, 0, SIM_ICCID_LEN_MAX+1);
+
+ bcd_byte = _get_valid_bcd_byte(p_in, in_length);
+ char_length = _bcd_to_digit(p_out->iccid, (char *) p_in, bcd_byte);
+ dbg("bcd byte:[%d] string length:[%d]", bcd_byte, char_length);
+
+ *(p_out->iccid+char_length) = '\0';
+
+ return TRUE;
+}
+
+/**
+ * This function is used to decode EFLP (2G)
+ */
+gboolean tcore_sim_decode_lp(struct tel_sim_language *p_out, unsigned char *p_in, int in_length)
+{
+ int i = 0;
+
+ memset((void *) p_out, 0xFF, sizeof(struct tel_sim_language));
+ p_out->language_count = 0;
+
+ if (in_length == 0)
+ return FALSE;
+
+ /*
+ * Description of problem: language decoding was not correctly done if we
+ * used 7layers's test SIM
+ *
+ * Patch Description : The tested SIM at 7layers has 3 language codes like [ff][ff][01].
+ * In this case we could not decode 3rd language code.
+ * So, the below 2 lines checking the UNSPECIFIED language are commented.
+ */
+
+ if (in_length > SIM_LANG_CNT_MAX)
+ in_length = SIM_LANG_CNT_MAX;
+
+ for (i = 0; i < in_length; i++) {
+ /*
+ * Description of problem: Language decoding was not correctly done if we used some test SIM
+ * Patch Description : Test SIM at some place has 3 language codes like [ff][ff][01].
+ * In this case we could not decode 3rd language code.
+ * So, the below 2 lines checking the UNSPECIFIED language are commented.
+ */
+ if (p_in[i] == 0xFF)
+ continue;
+
+ p_out->language[p_out->language_count] = (enum tel_sim_language_type) p_in[i];
+ dbg("p_out->language[%d]=[%d] ", i, p_out->language[p_out->language_count]);
+ p_out->language_count++;
+ }
+
+ dbg("in_length %d, lang_cnt %d ", in_length, p_out->language_count);
+ return TRUE;
+}
+
+/**
+ * This function is used to encode EFLP (2G)
+ */
+char *tcore_sim_encode_lp(int *out_length, struct tel_sim_language *p_in)
+{
+ int i = 0;
+ char *tmp_out = NULL;
+
+ if (out_length == NULL || p_in == NULL) {
+ dbg("out_length or p_in is null");
+ return NULL;
+ }
+
+ tmp_out = (char *)malloc(p_in->language_count);
+ if (!tmp_out)
+ return NULL;
+
+ memset((void *) tmp_out, 0xff, p_in->language_count);
+
+ for (i = 0; i < p_in->language_count; i++)
+ tmp_out[i] = p_in->language[i];
+
+ *out_length = i;
+ return tmp_out;
+}
+
+/**
+ * This function is used to decode LI (3G)
+ */
+gboolean tcore_sim_decode_li(enum tel_sim_file_id file_id, struct tel_sim_language *p_out, unsigned char *p_in, int in_length)
+{
+ int i;
+ unsigned short defaultLi;
+ unsigned char tempLi[3] = { 0, 0, 0 };
+
+ memset((void *)p_out, 0xFF, sizeof(struct tel_sim_language));
+ p_out->language_count = 0;
+
+ if (in_length == 0)
+ return FALSE;
+
+ /*
+ * Description of problem: language decoding was not correctly done if we
+ * used 7layers's test SIM
+ *
+ * Patch Description : TS31.102 If the EFLI has the value 'FFFF' in its highest priority position,
+ * then the preferred language selection shall be the language preference in the EFPL
+ */
+ if (/*TODO g_sim.CardType == SIM_TYPE_USIM && */(file_id == SIM_EF_USIM_LI || file_id == SIM_EF_LP)) {
+ defaultLi = p_in[0];
+ defaultLi = ((defaultLi << 8) & 0xFF00) + p_in[1];
+
+ if (defaultLi == 0xFFFF) /* 1st language is default. */
+ return FALSE;
+ }
+
+ if (in_length > SIM_LANG_CNT_MAX)
+ in_length = SIM_LANG_CNT_MAX;
+
+ for (i = 0; i < in_length; i++) {
+ tempLi[0] = p_in[i++];
+ tempLi[1] = p_in[i];
+
+ /*
+ * Description of problem: language decoding was not correctly
+ * done if we used 7layers's test SIM
+ *
+ * Patch Description : The tested SIM at specific test lab has
+ * 3 language codes like [ff][ff][ff][ff][64][65].
+ * In this case we could not decode 3rd language code.
+ * So, the below 2 lines checking the UNSPECIFIED language are commented.
+ */
+ if (tempLi[0] == 0xFF || tempLi[1] == 0xFF) /* this is always 2 bytes */
+ continue;
+
+ p_out->language[p_out->language_count] = SIM_LANG_UNSPECIFIED;
+
+ if (tempLi[0] == 'e') {
+ switch (tempLi[1]) {
+ case 'n':
+ p_out->language[p_out->language_count] = SIM_LANG_ENGLISH;
+ break;
+
+ case 's':
+ p_out->language[p_out->language_count] = SIM_LANG_SPANISH;
+ break;
+
+ case 'l':
+ p_out->language[p_out->language_count] = SIM_LANG_GREEK;
+ break;
+
+ default:
+ warn("invalid language");
+ break;
+ }
+ } else if (tempLi[0] == 'd') {
+ switch (tempLi[1]) {
+ case 'e':
+ p_out->language[p_out->language_count] = SIM_LANG_GERMAN;
+ break;
+
+ case 'a':
+ p_out->language[p_out->language_count] = SIM_LANG_DANISH;
+ break;
+
+ default:
+ warn("invalid language");
+ break;
+ }
+ } else if (tempLi[0] == 'i' && tempLi[1] == 't')
+ p_out->language[p_out->language_count] = SIM_LANG_ITALIAN;
+ else if (tempLi[0] == 'f' && tempLi[1] == 'r')
+ p_out->language[p_out->language_count] = SIM_LANG_FRENCH;
+ else if (tempLi[0] == 'n' && tempLi[1] == 'l')
+ p_out->language[p_out->language_count] = SIM_LANG_DUTCH;
+ else if (tempLi[0] == 's' && tempLi[1] == 'v')
+ p_out->language[p_out->language_count] = SIM_LANG_SWEDISH;
+ else if (tempLi[0] == 'f' && tempLi[1] == 'i')
+ p_out->language[p_out->language_count] = SIM_LANG_FINNISH;
+ else if (tempLi[0] == 'n' && tempLi[1] == 'o')
+ p_out->language[p_out->language_count] = SIM_LANG_NORWEGIAN;
+ else if (tempLi[0] == 't' && tempLi[1] == 'r')
+ p_out->language[p_out->language_count] = SIM_LANG_TURKISH;
+ else if (tempLi[0] == 'h' && tempLi[1] == 'u')
+ p_out->language[p_out->language_count] = SIM_LANG_HUNGARIAN;
+ else if (tempLi[0] == 'p') {
+ switch (tempLi[1]) {
+ case 'l':
+ p_out->language[p_out->language_count] = SIM_LANG_POLISH;
+ break;
+
+ case 't':
+ p_out->language[p_out->language_count] = SIM_LANG_PORTUGUESE;
+ break;
+
+ default:
+ warn("invalid language");
+ break;
+ }
+ } else if (tempLi[0] == 'k' && tempLi[1] == 'o')
+ p_out->language[p_out->language_count] = SIM_LANG_KOREAN;
+ else if (tempLi[0] == 'z' && tempLi[1] == 'h')
+ p_out->language[p_out->language_count] = SIM_LANG_CHINESE;
+ else if (tempLi[0] == 'r' && tempLi[1] == 'u')
+ p_out->language[p_out->language_count] = SIM_LANG_RUSSIAN;
+ else if (tempLi[0] == 'j' && tempLi[1] == 'a')
+ p_out->language[p_out->language_count] = SIM_LANG_JAPANESE;
+
+ dbg("count %d & Codes %d ", p_out->language_count, p_out->language[p_out->language_count]);
+ p_out->language_count++;
+ }
+
+ if (p_out->language_count == 0) {
+ dbg("p_out->language_count = %d ", p_out->language_count);
+ return FALSE;
+ } else {
+ return TRUE;
+ }
+}
+
+/**
+ * This function is used to encode EFLI (3G)
+ */
+char *tcore_sim_encode_li(int *out_length, struct tel_sim_language *p_in)
+{
+ int i = 0;
+ char *tmp_out = NULL;
+ const char *LanguageCode[] = {
+ "de", "en", "it", "fr",
+ "es", "nl", "sv", "da",
+ "pt", "fi", "no", "el",
+ "tr", "hu", "pl", "ko",
+ "zh", "ru", "ja"};
+
+ if (out_length == NULL || p_in == NULL) {
+ dbg("out_length or p_in is null");
+ return NULL;
+ }
+
+ tmp_out = (char *)malloc((p_in->language_count) * 2);
+ if (!tmp_out)
+ return NULL;
+
+ memset((void *)tmp_out, 0xff, (p_in->language_count) * 2);
+
+ for (i = 0; i < p_in->language_count; i++) {
+ if (p_in->language[i] < SIM_LANG_UNSPECIFIED) {
+ strncpy((char *) &tmp_out[i * 2], LanguageCode[p_in->language[i]], 2);
+ dbg("sim_encode_li: p_out[%s]:[%x][%x]", tmp_out, tmp_out[i*2], tmp_out[(i*2)+1]);
+ }
+ }
+
+ *out_length = i*2;
+ return tmp_out;
+}
+
+gboolean tcore_sim_decode_imsi(struct tel_sim_imsi *p_out, unsigned char *p_in, int in_length)
+{
+ int i = 0, j = 0;
+ char imsi_raw[16];
+ char *plmn = NULL;
+ int plmn_digits = 5;
+
+ if ((NULL == p_out) || (NULL == p_in))
+ return FALSE;
+
+ /*
+ * According to 3GPP specification, the length of raw IMSI data is 9 bytes.
+ * first byte is length of IMSI
+ * second byte byte has parity nibble, so second byte has one digit of IMSI.
+ * other byte has two digit of IMSI
+ */
+ if ((in_length == 0) || (in_length == 0xff) || (4 > in_length) || (9 < in_length)) {
+ dbg("No valid IMSI present to convert - length:[%x]", in_length);
+ return FALSE;
+ }
+
+ /* Decode IMSI value from nibbles */
+ for (i = 1; i < in_length; i++) {
+ if (i == 1) { /* first byte, ignore lower nibble */
+ imsi_raw[j++] = ((p_in[i] & 0xF0) >> 4) + '0';
+ } else if (i == p_in[0] + 1) { /* last byte */
+ imsi_raw[j++] = (p_in[i] & 0x0F) + '0';
+ if (p_in[0] % 2) /* count the last one if odd digits */
+ imsi_raw[j++] = ((p_in[i] & 0xF0) >> 4) + '0';
+ } else {
+ imsi_raw[j++] = (p_in[i] & 0x0F) + '0';
+ imsi_raw[j++] = ((p_in[i] & 0xF0) >> 4) + '0';
+ }
+ }
+
+ /* Determine # of PLMN digits (5 or 6) */
+ plmn = g_strndup(imsi_raw, 6 + 1);
+ if (plmn) {
+ plmn[6] = '\0';
+ if (tcore_sim_check_plmn_having_3digits_mnc(plmn))
+ plmn_digits = 6;
+ g_free(plmn);
+ }
+
+ /* Terminate string */
+ imsi_raw[j] = '\0';
+ memcpy(p_out->plmn, imsi_raw, plmn_digits);
+ p_out->plmn[plmn_digits] = '\0';
+ memcpy(p_out->msin, imsi_raw + plmn_digits, strlen(imsi_raw) - plmn_digits);
+ p_out->msin[strlen(imsi_raw) - plmn_digits] = '\0';
+
+ dbg("plmn in imsi = [%s]", p_out->plmn);
+
+ return TRUE;
+}
+
+gboolean tcore_sim_decode_cdma_imsi(struct tel_sim_imsi *p_out, unsigned char *p_in, int in_length)
+{
+ char imsi_raw[16] = {0, };
+ int digits = 0;
+ unsigned short mcc;
+ unsigned char mnc;
+ unsigned long min1;
+ unsigned short min2;
+ char *plmn = NULL;
+ int plmn_digits = 5;
+
+ if ((NULL == p_out) || (NULL == p_in))
+ return FALSE;
+
+ /*
+ * According to 3GPP2 specification, the length of raw IMSI data is 10 bytes.
+ * byte Description
+ *-----------------------------------------------------------------
+ * 1 Class assignment of IMSI_M
+ * 2-3 IMSI_M_S2 : MSIN2
+ * 4-6 IMSI_M_S1 : MSIN1
+ * 7 IMSI_M_11_12 : MNC
+ * 8 IMSI_M_ADDR_NUM : No of IMSI_M address digits.
+ * 9-10 MCC_M : MCC
+ */
+ if ((in_length == 0) || (in_length == 0xff) || (4 > in_length) || (10 < in_length)) {
+ dbg("No valid IMSI present to convert - length:[%x]", in_length);
+ return FALSE;
+ }
+
+ /* Decode IMSI value from nibbles */
+ mcc = (p_in[9] << 8) | p_in[8];
+ mnc = p_in[6];
+ min1 = (p_in[5] << 16) | (p_in[4] << 8) | (p_in[3]);
+ min2 = (p_in[2] << 8) | p_in[1];
+
+ digits = _decode_cdma_imsi_util(imsi_raw, &mcc, &mnc, &min1, &min2);
+
+ if (digits < 0)
+ return FALSE;
+
+ /* Determine # of PLMN digits (5 or 6) */
+ plmn = g_strndup(imsi_raw, 6 + 1);
+ if (plmn) {
+ plmn[6] = '\0';
+ if (tcore_sim_check_plmn_having_3digits_mnc(plmn))
+ plmn_digits = 6;
+
+ g_free(plmn);
+ }
+
+ /* Terminate string */
+ imsi_raw[digits] = '\0';
+ memcpy(p_out->plmn, imsi_raw, plmn_digits);
+ p_out->plmn[plmn_digits] = '\0';
+ memcpy(p_out->msin, imsi_raw + plmn_digits, strlen(imsi_raw) - plmn_digits);
+ p_out->msin[strlen(imsi_raw) - plmn_digits] = '\0';
+
+ dbg("plmn in imsi = [%s]", p_out->plmn);
+
+ return TRUE;
+}
+
+gboolean tcore_sim_decode_sst(struct tel_sim_sst *p_sst, unsigned char *p_in, int in_length)
+{
+ unsigned char sstByte, rast, mask = 0;
+ char simServiceID = 1; /* set "CHV1 disable function" */
+ int i, svc_count;
+ char *p_index;
+
+ memset((void *)p_sst, 0, sizeof(struct tel_sim_sst));
+
+ if (in_length == 0) {
+ err("invalid length. return FALSE.");
+ return FALSE;
+ }
+
+ /* get count of SIM service id. one byte has four service status. */
+ svc_count = in_length * 4;
+
+ /*
+ * 3GPP 51.011 SST shows 56 kinds of service types.
+ * current tel_sim_sst has also 56 elements
+ */
+ if (svc_count > SIM_SST_SERVICE_CNT_MAX) {
+ warn("out of range[%d]. cut off the tail.", svc_count);
+ svc_count = SIM_SST_SERVICE_CNT_MAX;
+ }
+
+ p_index = (char *)p_sst;
+
+ for (i = 0; i < svc_count; i++) {
+ sstByte = p_in[(simServiceID - 1) / 4];
+ rast = simServiceID - 4 * (simServiceID / 4);
+
+ switch (rast) {
+ case 1:
+ mask = 0x02;
+ break;
+
+ case 2:
+ mask = 0x08;
+ break;
+
+ case 3:
+ mask = 0x20;
+ break;
+
+ case 0:
+ mask = 0x80;
+ break;
+
+ default:
+ warn("invalid rast");
+ break;
+ }
+
+ if (sstByte & mask)
+ *p_index = 1;
+ else
+ *p_index = 0;
+
+ p_index += sizeof(char);
+ simServiceID++; /* next service id */
+ }
+
+ return TRUE;
+}
+
+gboolean tcore_sim_decode_cdma_st(struct tel_sim_cst *p_cdma_st, unsigned char *p_in, int in_length)
+{
+ unsigned char sstByte, rast, mask = 0;
+ char simServiceID = 1; /* set "CHV1 disable function" */
+ int i, svc_count;
+ char *p_index;
+
+ memset((void *)p_cdma_st, 0, sizeof(struct tel_sim_cst));
+
+ if (in_length == 0 || in_length > SIM_CDMA_ST_SERVICE_LEN_MAX)
+ return FALSE;
+
+ /* get count of SIM service id. one byte has four service status. */
+ svc_count = in_length * 4;
+
+ /*
+ * CDMA_ST service is described to 47(1 byte includes 4 service status) in C.S0023 3.4.18.
+ * Current tel_sim_cst.serivce.cdma_service has 47 services. so in_length should be under 12 byte.
+ */
+ if (svc_count > SIM_CDMA_ST_SERVICE_CNT_MAX)
+ svc_count = SIM_CDMA_ST_SERVICE_CNT_MAX;
+
+ p_cdma_st->cdma_svc_table = SIM_CDMA_SVC_TABLE;
+
+ p_index = (char *)p_cdma_st->service.cdma_service;
+
+ for (i = 0; i < svc_count; i++) {
+ sstByte = p_in[(simServiceID - 1) / 4];
+ rast = simServiceID - 4 * (simServiceID / 4);
+
+ switch (rast) {
+ case 1:
+ mask = 0x02;
+ break;
+
+ case 2:
+ mask = 0x08;
+ break;
+
+ case 3:
+ mask = 0x20;
+ break;
+
+ case 0:
+ mask = 0x80;
+ break;
+
+ default:
+ warn("invalid rast");
+ break;
+ }
+
+ if (sstByte & mask)
+ *p_index = 1;
+ else
+ *p_index = 0;
+
+ p_index += sizeof(char);
+ simServiceID++; /* next service id */
+ }
+
+ return TRUE;
+}
+
+gboolean tcore_sim_decode_csim_st(struct tel_sim_cst *p_csim_st, unsigned char *p_in, int in_length)
+{
+ int i, j;
+ char mask;
+ char *p_index;
+ memset((void *) p_csim_st, 0, sizeof(struct tel_sim_cst));
+
+ p_csim_st->cdma_svc_table = SIM_CSIM_SVC_TABLE;
+ p_index = (char *)p_csim_st->service.csim_service;
+
+ /*
+ * CSIM_ST service is described to 41(1 byte includes 8 service status) in C.S0065 5.2.18.
+ * Current tel_sim_cst.serivce.csim_service has 41 services. so in_length should be under 6 byte.
+ */
+ if (in_length > SIM_CSIM_ST_SERVICE_LEN_MAX)
+ in_length = SIM_CSIM_ST_SERVICE_LEN_MAX;
+
+ for (i = 0; i < in_length; i++) {
+ mask = 0x01; /* reset mask to check first bit */
+
+ for (j = 0; j < 8; j++) {
+ if (p_in[i] & mask)
+ *p_index = 1;
+
+ p_index += sizeof(char);
+ mask = mask << 1;
+ }
+ }
+
+ return TRUE;
+}
+
+gboolean tcore_sim_decode_spn(struct tel_sim_spn *p_spn, unsigned char *p_in, int in_length)
+{
+ int i;
+
+ if (in_length == 0)
+ return FALSE;
+
+ p_spn->display_condition = p_in[0] & 0x3;
+
+ for (i = 1; i < SIM_SPN_LEN_MAX + 1; i++) {
+ if (p_in[i] == 0xFF)
+ break; /* loop break*/
+
+ p_spn->spn[i - 1] = p_in[i];
+ }
+
+ p_spn->spn[i-1] = '\0';
+
+ dbg("spn:[%s] display condition : [%d]", p_spn->spn, p_spn->display_condition);
+
+ return TRUE;
+}
+
+gboolean tcore_sim_decode_cdma_spn(struct tel_sim_spn *p_spn, unsigned char *p_in, int in_length)
+{
+ int i = 0;
+
+ if (in_length == 0)
+ return FALSE;
+
+ p_spn->display_condition = p_in[0] & 0x1;
+
+ /*
+ * Note : Character Encoding (1 byte) and Language Indicator (1 byte)
+ * are ignored, will be added later if required by Application
+ */
+ for (i = 3; i < SIM_CDMA_SPN_LEN_MAX + 1; i++) {
+ if (p_in[i] == 0xFF)
+ break; /* loop break*/
+
+ p_spn->spn[i - 3] = p_in[i];
+ }
+ p_spn->spn[i - 3] = '\0';
+
+ dbg("spn:[%s] display condition : [%d]", p_spn->spn, p_spn->display_condition);
+
+ return TRUE;
+}
+
+gboolean tcore_sim_decode_spdi(struct tel_sim_spdi *p_spdi, unsigned char *p_in, int in_length)
+{
+ int i, Src_plmn_start_len, total_data_len;
+
+ if (in_length == 0)
+ return FALSE;
+
+ if (p_in[0] == 0xff) {
+ dbg("file is exist but there is no valid records");
+
+ p_spdi->plmn_count = 0;
+ memset(p_spdi->list, 0x00, sizeof(unsigned char)*7*SIM_SPDI_PLMN_MAX);
+
+ return TRUE;
+ }
+
+ /* Display info tag('A3') */
+ if (p_in[0] == 0xA3) {
+ total_data_len = p_in[1];
+ dbg("total_data_len=[%d]", total_data_len);
+
+ /* PLMN list tag('80') */
+ if (p_in[2] == 0x80) {
+ p_spdi->plmn_count = p_in[3] / 3;
+
+ /*
+ * plmn tag 1byte
+ * length 1byte
+ * each plmn entry 3byte
+ */
+ if (p_spdi->plmn_count > SIM_SPDI_PLMN_MAX)
+ p_spdi->plmn_count = SIM_SPDI_PLMN_MAX;
+
+ Src_plmn_start_len = 4;
+
+ dbg("p_spdi->num_of_plmn_entries[%d]", p_spdi->plmn_count);
+
+ for (i = 0; i < p_spdi->plmn_count; i++) {
+ _decode_plmn(&p_in[Src_plmn_start_len], p_spdi->list[i].plmn);
+ dbg("SPDI PLMN[%d][%s]", i, p_spdi->list[i].plmn);
+
+ Src_plmn_start_len = Src_plmn_start_len + 3;
+ }
+
+ return TRUE;
+ }
+
+ dbg("Current EF-SPDI has invalid data");
+ return FALSE;
+ }
+
+ dbg("Current EF-SPDI has invalid data");
+ return FALSE;
+}
+
+gboolean tcore_sim_decode_msisdn(struct tel_sim_msisdn *p_msisdn, unsigned char *p_in, int in_length)
+{
+ int X = 0; /* alpha id max length */
+ int alpha_id_length = 0;
+ int value_length = 0;
+ int bcd_byte = 0; /* dialing number max length */
+
+ memset((void *) p_msisdn, 0, sizeof(struct tel_sim_msisdn));
+
+ if (in_length < 14) {
+ err("invalid in_length[%d]", in_length);
+ return FALSE;
+ }
+
+ if (_is_empty(p_in, in_length) == TRUE) {
+ memset(p_msisdn, 0, sizeof(struct tel_sim_msisdn));
+ return FALSE;
+ }
+
+ X = in_length - 14; /* get alpha id max length */
+
+ if (X != 0) {
+ alpha_id_length = X;
+ dbg("alpha_id_length[%d]", alpha_id_length);
+ if (alpha_id_length > SIM_XDN_ALPHA_ID_LEN_MAX)
+ alpha_id_length = SIM_XDN_ALPHA_ID_LEN_MAX;
+
+ value_length = _get_string((unsigned char *)p_msisdn->name, p_in, alpha_id_length);
+ p_msisdn->name[value_length] = '\0';
+ }
+
+ /* get dialing number length */
+ /* p_in[X] is BCD length of dialing number length plus TON/NPI 1 bytes. */
+ /* Convert to digit length and subtract TON/NPI length. */
+ if (p_in[X] != 0xFF) {
+ dbg("Dialing number Length %d, BCD length 0x%x ", (p_in[X] - 1) * 2, p_in[X]);
+
+ /* get TON and NPI */
+ p_msisdn->ton = (p_in[X + 1] >> 4) & 0x07;
+
+ /* get actual dialing number length */
+ bcd_byte = _get_valid_bcd_byte(&p_in[X + 2], SIM_XDN_NUMBER_LEN_MAX / 2);
+ dbg("bcd_byte[%x]", bcd_byte);
+
+ /* get dialing number/SSC string */
+ value_length = _bcd_to_digit((char *)p_msisdn->num, (char *) &p_in[X + 2], bcd_byte); /* actual dialing number length in BCD. */
+ p_msisdn->num[value_length] = '\0';
+ p_msisdn->next_record = p_in[X+13];
+ dbg("p_msisdn->num[%s]", p_msisdn->num);
+ }
+
+ return TRUE;
+}
+
+gboolean tcore_sim_decode_mdn(struct tel_sim_msisdn *p_msisdn, unsigned char *p_in, int in_length)
+{
+ int value_length = 0;
+ int bcd_byte = 0; /* dialing number max length */
+
+ memset((void *)p_msisdn, 0, sizeof(struct tel_sim_msisdn));
+
+ if (in_length == 0)
+ return FALSE;
+
+ if (_is_empty(p_in, in_length) == TRUE)
+ return FALSE;
+
+ /* Note : Alpha identifier is not present in EF-MDN file. */
+ if (p_in[0] != 0xFF) {
+ dbg("Dialing number Length %d, BCD length 0x%x ", (p_in[0] - 1) * 2, p_in[0]);
+
+ /* get TON and NPI */
+ p_msisdn->ton = (p_in[9] >> 4) & 0x07;
+
+ /* get actual dialing number length */
+ bcd_byte = _get_valid_bcd_byte(&p_in[1], 8);
+ dbg("bcd_byte[%x]", bcd_byte);
+
+ /* get dialing number/SSC string */
+ value_length = _bcd_to_digit((char *) p_msisdn->num, (char *) &p_in[1], bcd_byte); /* actual dialing number length in BCD. */
+ p_msisdn->num[value_length] = '\0';
+
+ /*p_msisdn->next_record = p_in[];*/ /* Need to check with next_record field */
+ dbg("p_msisdn->num[%s]", p_msisdn->num);
+ }
+
+ return TRUE;
+}
+
+gboolean tcore_sim_decode_xdn(struct tel_sim_dialing_number *p_xdn, unsigned char *p_in, int in_length)
+{
+ int X; /* alpha id max length */
+ int bcd_byte; /* dialing number max length */
+
+ memset((void *)p_xdn, 0, sizeof(struct tel_sim_dialing_number));
+
+ if (in_length == 0)
+ return FALSE;
+
+ if (_is_empty(p_in, in_length) == TRUE)
+ return FALSE; /* this is empty record */
+
+ X = in_length - 14; /* get alpha id max length */
+
+ if (X != 0) {
+ _get_string((unsigned char *)p_xdn->alpha_id, p_in, X);
+ p_xdn->alpha_id_max_len = X;
+ }
+
+ /* get dialing number length */
+ /* p_in[X] is BCD length of dialing number length plus TON/NPI 1 bytes. */
+ /* Convert to digit length and subtract TON/NPI length. */
+ if (p_in[X] != 0xFF) {
+ dbg("Dialing number Length %d, BCD length 0x%x ",
+ (p_in[X] - 1) * 2, p_in[X]);
+
+ /*
+ if (p_xdn->num_max_len > SIM_XDN_NUMBER_LEN_MAX) {
+
+ this may be broken record.
+ p_xdn->b_used = FALSE;
+ memset((void *)p_xdn, 0, sizeof(tapi_sim_dialing_number_info_t));
+ return FALSE;
+
+ ADN record cannot have more than 20 digits. Anyway we can restrict this as per 31.102
+ X+1 Length of BCD number/SSC contents M 1 byte
+ X+2 TON and NPI M 1 byte
+ X+3 to X+12 Dialing Number/SSC String M 10 bytes
+ X+13 Capability/Configuration1 Identifier M 1 byte
+ X+14 Extension1 Record Identifier M 1 byte
+
+ Anyway we are doing this check @
+ bcd_byte = _get_valid_bcd_byte (&p_in[X+2], TAPI_SIM_XDN_DIALING_NUMBER_LEN/2);
+ by using the 20/2; so don`t return false.
+
+ if (p_in[X] == 0x00)
+ p_xdn->num_max_len = 0;
+ else
+ p_xdn->num_max_len = SIM_XDN_NUMBER_LEN_MAX;
+ }
+ */
+
+ /* get TON and NPI */
+ p_xdn->ton = (p_in[X + 1] >> 4) & 0x07;
+ p_xdn->npi = p_in[X + 1] & 0x0F;
+
+ /* get actual dialing number length */
+ bcd_byte = _get_valid_bcd_byte(&p_in[X + 2], SIM_XDN_NUMBER_LEN_MAX / 2);
+ dbg("bcd_byte[%x]", bcd_byte);
+
+ /* get dialing number/SSC string */
+ _bcd_to_digit((char *) p_xdn->num, (char *) &p_in[X + 2], bcd_byte); /* actual dialing number length in BCD. */
+ dbg("p_xdn->DiallingNum[%s]", p_xdn->num);
+
+ /* get Capability/Configuration id */
+ p_xdn->cc_id = p_in[X + 12];
+
+ /* get Extension1 id */
+ p_xdn->ext1_id = p_in[X + 13];
+ }
+ return TRUE;
+}
+
+char *tcore_sim_encode_xdn(int in_length, struct tel_sim_dialing_number *p_xdn)
+{
+ int alpha_id_space = 0, digit_len = 0, str_len = 0;
+ char bcdCode[SIM_XDN_NUMBER_LEN_MAX / 2];
+ char *p_out = NULL;
+
+ if (in_length < 14) {
+ dbg("in_length[%d] should be greater than or equal to 14.", in_length);
+ return NULL;
+ }
+
+ p_out = calloc(1, in_length + 1);
+ if (!p_out)
+ return NULL;
+
+ memset((void *)p_out, 0xFF, in_length);
+
+ /* get alpha id max length */
+ alpha_id_space = in_length - 14;
+
+ /* alpha id is too big */
+ str_len = strlen(p_xdn->alpha_id);
+ if (alpha_id_space < str_len) {
+ dbg("SIM space for alpha_id is [%d] but input alpha_id length is [%d]. so we will use [%d] byte",
+ alpha_id_space, str_len, alpha_id_space);
+ str_len = alpha_id_space;
+ }
+
+ digit_len = strlen(p_xdn->num);
+ /* this is digit length */
+ if (digit_len > SIM_XDN_NUMBER_LEN_MAX) {
+ dbg("SIM space for number is [%d] but input number length is [%d]. so we will use [%d] byte",
+ SIM_XDN_NUMBER_LEN_MAX, digit_len, SIM_XDN_NUMBER_LEN_MAX);
+ digit_len = SIM_XDN_NUMBER_LEN_MAX;
+ }
+
+ _set_string((unsigned char *)p_out, (unsigned char *)p_xdn->alpha_id, str_len);
+
+ /* set length of BCD number/SSC contents */
+ /* p_xdn->diallingnumLen is maximum digit length. = 20 bytes. */
+ /* convert to BCD length and add 1 byte. */
+ p_out[alpha_id_space] = ((digit_len + 1) / 2) + 1;
+
+ /* set TON and NPI */
+ p_out[alpha_id_space + 1] = 0x80;
+ p_out[alpha_id_space + 1] |= (p_xdn->ton & 0x07) << 4;
+ p_out[alpha_id_space + 1] |= p_xdn->npi & 0x0F;
+
+ /* set dialing number/SSC string */
+ memset((void *) bcdCode, 0xFF, SIM_XDN_NUMBER_LEN_MAX / 2);
+
+ _digit_to_bcd((char *)bcdCode, (char *)p_xdn->num, digit_len);
+
+ memcpy((void *)&p_out[alpha_id_space + 2], bcdCode, SIM_XDN_NUMBER_LEN_MAX / 2);
+
+ /* set Capability/Configuration Identifier */
+ if (p_xdn->cc_id == 0x00)
+ p_out[alpha_id_space + 12] = 0xff;
+ else
+ p_out[alpha_id_space + 12] = (unsigned char)p_xdn->cc_id;
+
+ /* set extension1 record Identifier */
+ if (p_xdn->ext1_id == 0x00)
+ p_out[alpha_id_space + 13] = 0xff;
+ else
+ p_out[alpha_id_space + 13] = (unsigned char)p_xdn->ext1_id;
+
+ return p_out;
+}
+
+gboolean tcore_sim_decode_ecc(struct tel_sim_ecc_list *p_ecc, unsigned char *p_in, int in_length)
+{
+ int bcd_byte; /* dialing number max length */
+ int i;
+ int valid_ecc_length;
+
+ memset((void *)p_ecc, 0x00, sizeof(struct tel_sim_ecc_list));
+
+ if (in_length % 3 != 0) {
+ dbg("error - invalid data length");
+ return FALSE;
+ }
+
+ for (i = 0; i < in_length / 3; i++) {
+ /* get the BCD length of the ECC */
+ bcd_byte = _get_valid_bcd_byte((unsigned char *) p_in+(i*3), 3);
+ if (bcd_byte != 0) {
+ valid_ecc_length = _bcd_to_digit(p_ecc->ecc[p_ecc->ecc_count].ecc_num, (char *)p_in+(i*3), bcd_byte);
+ p_ecc->ecc[p_ecc->ecc_count].ecc_num[valid_ecc_length] = '\0';
+ p_ecc->ecc_count++;
+ }
+ }
+
+ return TRUE;
+}
+
+gboolean tcore_sim_decode_ext(struct tel_sim_ext *p_ext, unsigned char *p_in, int in_length)
+{
+ int bcd_byte; /* dialing number max length */
+ gboolean res = FALSE;
+
+ memset((void *)p_ext, 0x00, sizeof(struct tel_sim_ext));
+
+ if (*p_in & 0x01) {
+ dbg("Record type - Called Party Subaddress - NOT SUPPORTED");
+ } else if (*p_in & 0x02) {
+ dbg("Record type - Additional data");
+ bcd_byte = _get_valid_bcd_byte(&p_in[2], SIM_XDN_NUMBER_LEN_MAX / 2);
+ p_ext->ext_len = _bcd_to_digit((char *) p_ext->ext, (char *) &p_in[2], bcd_byte); /* actual dialing number length in BCD. */
+ p_ext->next_record = p_in[12];
+ dbg("Dialing number Length[%d]", p_ext->ext_len);
+ res = TRUE;
+ } else {
+ dbg("Record type - Invalid");
+ }
+
+ return res;
+}
+
+gboolean tcore_sim_decode_ust(struct tel_sim_ust *p_ust, unsigned char *p_in, int in_length)
+{
+ int i, j;
+ char mask;
+ char *p_index;
+
+ memset((void *)p_ust, 0, sizeof(struct tel_sim_ust));
+ p_index = (char *)p_ust;
+
+ if (in_length == 0) {
+ err("invalid length. return FALSE.");
+ return FALSE;
+ }
+
+ /*
+ * UST service is described to 74(1 byte includes 8 service status) in 31.102 r7.
+ * current sim_ust_s has 64 services. so in_length should be under 8 byte.
+ */
+ if (in_length > (SIM_UST_SERVICE_CNT_MAX / 8)) {
+ warn("out of range[%d]. cut off the tail.", in_length);
+ in_length = SIM_SST_SERVICE_CNT_MAX / 8;
+ }
+
+ for (i = 0; i < in_length; i++) {
+ mask = 0x01; /* reset mast to check first bit */
+
+ for (j = 0; j < 8; j++) {
+ if (p_in[i] & mask)
+ *p_index = 1;
+
+ p_index += sizeof(char);
+ mask = mask << 1;
+ }
+ }
+
+ return TRUE;
+}
+
+gboolean tcore_sim_decode_ist(struct tel_sim_ist *p_ist, unsigned char *p_in, int in_length)
+{
+ int i, j;
+ char mask;
+ char *p_index;
+
+ memset((void *)p_ist, 0, sizeof(struct tel_sim_ist));
+ p_index = (char *)p_ist;
+
+ /*
+ * IST service is described to 11(1 byte includes 8 service status) in 31.103 release12.
+ * current tel_sim_ist_service has 11 services. so in_length should be under 2 byte.
+ */
+ if (in_length > SIM_IST_BYTE_LEN_MAX)
+ in_length = SIM_IST_BYTE_LEN_MAX;
+
+ for (i = 0; i < in_length; i++) {
+ mask = 0x01; /* reset mast to check first bit */
+
+ for (j = 0; j < 8; j++) {
+ if (p_in[i] & mask)
+ *p_index = 1;
+
+ p_index += sizeof(char);
+ mask = mask << 1;
+ }
+ }
+
+ return TRUE;
+}
+
+gboolean tcore_sim_decode_est(struct tel_sim_est *p_est, unsigned char *p_in, int in_length)
+{
+ memset((void *)p_est, 0, sizeof(struct tel_sim_est));
+
+ if (*p_in & 0x01)
+ p_est->bFdnEnabled = TRUE;
+
+ if (*p_in & 0x02)
+ p_est->bBdnEnabled = TRUE;
+
+ if (*p_in & 0x04)
+ p_est->bAclEnabled = TRUE;
+
+ return TRUE;
+}
+
+gboolean tcore_sim_decode_uecc(struct tel_sim_ecc *p_ecc, unsigned char *p_in, int in_length)
+{
+ int bcd_byte; /* dialing number max length */
+ unsigned char eccServiceCategory;
+
+ if (_is_empty(p_in, in_length) == TRUE) {
+ memset(p_ecc, 0, sizeof(struct tel_sim_ecc));
+ return FALSE;
+ }
+
+ /* get the BCD length of the ECC */
+ bcd_byte = _get_valid_bcd_byte(&p_in[0], SIM_ECC_BYTE_LEN_MAX);
+
+ /* get the ECC codes in digits and the length as well */
+ _bcd_to_digit((char *) p_ecc->ecc_num, (char *)&p_in[0], bcd_byte);
+
+ /* get the alpha identifier of ECC */
+ _get_string((unsigned char *) p_ecc->ecc_string, (unsigned char *)&p_in[3], in_length - 3);
+
+ eccServiceCategory = p_in[in_length - 1];
+
+ /*
+ * Assign the service category
+ * 3GPP TS24.008 Emergency Service Category Value.
+ * Bit 8, 7, 6 are spare, 5~1 bit is used.
+ * The meaning of the Emergency Category Value is derived from the following settings
+ * (see 3GPP TS 22.101 clause 10):
+ * Bit 1 Police 0x01
+ * Bit 2 Ambulance 0x02
+ * Bit 3 Fire Brigade 0x04
+ * Bit 4 Marine Guard 0x08
+ * Bit 5 Mountain Rescue 0x10
+ * Bit 6 manually initiated eCall
+ * Bit 7 automatically initiated eCall
+ * Bit 8 is spare and set to "0"
+ */
+
+ if (eccServiceCategory == 0xFF) /* if category vaule is unused (unchecked) then just return 0xff */
+ p_ecc->ecc_category = eccServiceCategory;
+ else
+ p_ecc->ecc_category = eccServiceCategory & 0x1F; /* Check for the first 5 bits */
+
+ return TRUE;
+}
+
+gboolean tcore_sim_decode_gid(struct tel_sim_gid *p_gid, unsigned char *p_in, int in_length)
+{
+ int i;
+
+ memset((void *) p_gid, 0, sizeof(struct tel_sim_gid));
+
+ if (in_length == 0)
+ return FALSE;
+
+ /* regarding 31.102, EF-GID data byte is not defined. currently 10. */
+ if (in_length >= SIM_GROUP_IDENTIFIER_LEN_MAX)
+ in_length = SIM_GROUP_IDENTIFIER_LEN_MAX;
+
+ for (i = 0; i < in_length; i++) {
+ if (p_in[i] == 0xFF)
+ break;
+
+ p_gid->szGroupIdentifier[i] = p_in[i];
+ p_gid->GroupIdentifierLen++;
+ }
+
+ return TRUE;
+}
+
+gboolean tcore_sim_decode_mbi(struct tel_sim_mbi *p_mbi, unsigned char *p_in, int in_length)
+{
+ /* EF-MBI is defined 4 mandatory, 1 optional byte in 31.102 */
+ if (in_length == 0 || in_length > SIM_MAIL_BOX_IDENTIFIER_LEN_MAX)
+ return FALSE;
+
+ if (_is_empty(p_in, in_length) == TRUE)
+ return FALSE; /* this is empty record */
+
+ p_mbi->voice_index = p_in[0];
+ p_mbi->fax_index = p_in[1];
+ p_mbi->email_index = p_in[2];
+ p_mbi->other_index = p_in[3];
+
+ /* 5th byte is optional */
+ if (in_length == 5)
+ p_mbi->video_index = p_in[4];
+
+ return TRUE;
+}
+
+char *tcore_sim_encode_mbi(const struct tel_sim_mbi *p_mbi, int in_length)
+{
+ char *p_out = NULL;
+
+ if (in_length < 4) {
+ dbg("in_length[%d] should be greater than or equal to 4.", in_length);
+ return NULL;
+ }
+
+ p_out = calloc(1, in_length);
+ if (!p_out)
+ return NULL;
+
+ p_out[0] = p_mbi->voice_index;
+ p_out[1] = p_mbi->fax_index;
+ p_out[2] = p_mbi->email_index;
+ p_out[3] = p_mbi->other_index;
+
+ if (in_length == 5)
+ p_out[4] = p_mbi->video_index;
+
+ return p_out;
+}
+
+gboolean tcore_sim_decode_cff(struct tel_sim_cphs_cf *p_cff, unsigned char *p_in, int in_length)
+{
+ if (in_length == 0)
+ return FALSE;
+
+ dbg("flag(0)=%x, packetlen=%d ", (unsigned int)p_in[0], in_length);
+ dbg("flag(1)=%x", p_in[1]);
+
+ if ((p_in[0] & 0x0F) == 0x0A)
+ p_cff->b_line1 = TRUE;
+
+ if ((p_in[0] & 0xF0) == 0xA0)
+ p_cff->b_line2 = TRUE;
+
+ if (in_length > 1) {
+ if ((p_in[1] & 0x0F) == 0x0A)
+ p_cff->b_fax = TRUE;
+
+ if ((p_in[1] & 0xF0) == 0xA0)
+ p_cff->b_data = TRUE;
+ }
+
+ dbg("Line1 = %d, line2 = %d, Fax = %d, Data = %d ",
+ p_cff->b_line1,
+ p_cff->b_line2,
+ p_cff->b_fax,
+ p_cff->b_data);
+ return TRUE;
+}
+
+char *tcore_sim_encode_cff(const struct tel_sim_cphs_cf *cff, int in_length)
+{
+ int i, j = 0;
+ char *p_out = NULL;
+ unsigned char *pTemp = (unsigned char *) cff;
+ unsigned char present = 0x0A;
+ unsigned char absent = 0x05;
+
+ if (in_length < SIM_CPHS_CALL_FORWARDING_LEN_MIN) {
+ err("in_length[%d] is smaller than SIM_CPHS_CALL_FORWARDING_LEN_MIN[%d]",
+ in_length, SIM_CPHS_CALL_FORWARDING_LEN_MIN);
+ return NULL;
+ }
+
+ p_out = calloc(1, SIM_CPHS_CALL_FORWARDING_LEN_MIN+1);
+ if (!p_out)
+ return NULL;
+
+ for (i = 0; i < SIM_CPHS_CALL_FORWARDING_LEN_MIN; i++) {
+ present = 0x0A;
+ absent = 0x05;
+
+ for (j = 0; j < 2; j++) {
+ if (*pTemp)
+ p_out[i] = p_out[i] | present;
+ else
+ p_out[i] = p_out[i] | absent;
+
+ pTemp += sizeof(gboolean);
+ present = present << 4;
+ absent = absent << 4;
+ }
+ }
+
+ p_out[SIM_CPHS_CALL_FORWARDING_LEN_MIN] = '\0';
+ return p_out;
+}
+
+gboolean tcore_sim_decode_csp(struct tel_sim_cphs_csp *p_csp, unsigned char *p_in, int in_length)
+{
+ int i, j, k = 0;
+ unsigned char byteSignificance = 0x00;
+ unsigned char mask = 0x80;
+
+ if (in_length == 0)
+ return FALSE;
+
+ memset((void *) p_csp, 0, sizeof(struct tel_sim_cphs_csp));
+
+ /* current telephony supports 22 byte cphs-csp data. 18 byte is mandatory, the other is optional. */
+ for (i = 0, j = 0; i < SIM_CPHS_CSP_LEN_MAX && j < SIM_CPHS_CSP_ENTRY_CNT_MAX; i++, j++) {
+ p_csp->service_profile_entry[j].customer_service_group = (enum tel_sim_cphs_csp_group) p_in[i];
+ byteSignificance = p_in[++i];
+ mask = 0x80;
+
+ switch (p_csp->service_profile_entry[j].customer_service_group) {
+ case 0x01:
+ for (k = 0; k < 5; k++) {
+ switch (byteSignificance & mask) {
+ case 0x80:
+ p_csp->service_profile_entry[j].service.call_offering.b_call_forwarding_unconditional = TRUE;
+ break;
+
+ case 0x40:
+ p_csp->service_profile_entry[j].service.call_offering.b_call_forwarding_on_user_busy = TRUE;
+ break;
+
+ case 0x20:
+ p_csp->service_profile_entry[j].service.call_offering.b_call_forwarding_on_no_reply = TRUE;
+ break;
+
+ case 0x10:
+ p_csp->service_profile_entry[j].service.call_offering.b_call_forwarding_on_user_not_reachable = TRUE;
+ break;
+
+ case 0x08:
+ p_csp->service_profile_entry[j].service.call_offering.b_call_transfer = TRUE;
+ break;
+
+ default:
+ break;
+ }
+ mask = mask >> 1;
+ }
+ break;
+
+ case 0x02:
+ for (k = 0; k < 5; k++) {
+ switch (byteSignificance & mask) {
+ case 0x80:
+ p_csp->service_profile_entry[j].service.call_restriction.b_barring_of_all_outgoing_calls = TRUE;
+ break;
+
+ case 0x40:
+ p_csp->service_profile_entry[j].service.call_restriction.b_barring_of_outgoing_international_calls = TRUE;
+ break;
+
+ case 0x20:
+ p_csp->service_profile_entry[j].service.call_restriction.b_barring_of_outgoing_international_calls_except_hplmn = TRUE;
+ break;
+
+ case 0x10:
+ p_csp->service_profile_entry[j].service.call_restriction.b_barring_of_all_incoming_calls_roaming_outside_hplmn = TRUE;
+ break;
+
+ case 0x08:
+ p_csp->service_profile_entry[j].service.call_restriction.b_barring_of_incoming_calls_when_roaming = TRUE;
+ break;
+
+ default:
+ break;
+ }
+ mask = mask >> 1;
+ }
+ break;
+
+ case 0x03:
+ for (k = 0; k < 5; k++) {
+ switch (byteSignificance & mask) {
+ case 0x80:
+ p_csp->service_profile_entry[j].service.other_supp_services.b_multi_party_service = TRUE;
+ break;
+
+ case 0x40:
+ p_csp->service_profile_entry[j].service.other_supp_services.b_closed_user_group = TRUE;
+ break;
+
+ case 0x20:
+ p_csp->service_profile_entry[j].service.other_supp_services.b_advice_of_charge = TRUE;
+ break;
+
+ case 0x10:
+ p_csp->service_profile_entry[j].service.other_supp_services.b_preferential_closed_user_group = TRUE;
+ break;
+
+ case 0x08:
+ p_csp->service_profile_entry[j].service.other_supp_services.b_closed_user_group_outgoing_access = TRUE;
+ break;
+
+ default:
+ break;
+ }
+ mask = mask >> 1;
+ }
+ break;
+
+ case 0x04:
+ for (k = 0; k < 4; k++) {
+ switch (byteSignificance & mask) {
+ case 0x80:
+ p_csp->service_profile_entry[j].service.call_complete.b_call_hold = TRUE;
+ break;
+
+ case 0x40:
+ p_csp->service_profile_entry[j].service.call_complete.b_call_waiting = TRUE;
+ break;
+
+ case 0x20:
+ p_csp->service_profile_entry[j].service.call_complete.b_completion_of_call_to_busy_subscriber = TRUE;
+ break;
+
+ case 0x10:
+ p_csp->service_profile_entry[j].service.call_complete.b_user_user_signalling = TRUE;
+ break;
+
+ default:
+ break;
+ }
+ mask = mask >> 1;
+ }
+ break;
+
+ case 0x05:
+ for (k = 0; k < 7; k++) {
+ switch (byteSignificance & mask) {
+ case 0x80:
+ p_csp->service_profile_entry[j].service.teleservices.b_short_message_mobile_terminated = TRUE;
+ break;
+
+ case 0x40:
+ p_csp->service_profile_entry[j].service.teleservices.b_short_message_mobile_originated = TRUE;
+ break;
+
+ case 0x20:
+ p_csp->service_profile_entry[j].service.teleservices.b_short_message_cell_broadcast = TRUE;
+ break;
+
+ case 0x10:
+ p_csp->service_profile_entry[j].service.teleservices.b_short_message_reply_path = TRUE;
+ break;
+
+ case 0x08:
+ p_csp->service_profile_entry[j].service.teleservices.b_short_message_delivery_conf = TRUE;
+ break;
+
+ case 0x04:
+ p_csp->service_profile_entry[j].service.teleservices.b_short_message_protocol_identifier = TRUE;
+ break;
+
+ case 0x02:
+ p_csp->service_profile_entry[j].service.teleservices.b_short_message_validity_period = TRUE;
+ break;
+
+ default:
+ break;
+ }
+ mask = mask >> 1;
+ }
+ break;
+
+ case 0x06:
+ for (k = 0; k < 1; k++) {
+ switch (byteSignificance & mask) {
+ case 0x80:
+ p_csp->service_profile_entry[j].service.cphs_teleservices.b_alternative_line_service = TRUE;
+ break;
+
+ default:
+ break;
+ }
+ mask = mask >> 1;
+ }
+ break;
+
+ case 0x07:
+ for (k = 0; k < 1; k++) {
+ switch (byteSignificance & mask) {
+ case 0x80:
+ p_csp->service_profile_entry[j].service.cphs_features.b_string_service_table = TRUE;
+ break;
+
+ default:
+ break;
+ }
+ mask = mask >> 1;
+ }
+ break;
+
+ case 0x08:
+ for (k = 0; k < 8; k++) {
+ switch (byteSignificance & mask) {
+ case 0x80:
+ p_csp->service_profile_entry[j].service.number_identifiers.b_calling_line_identification_present = TRUE;
+ break;
+
+ case 0x20:
+ p_csp->service_profile_entry[j].service.number_identifiers.b_connected_line_identification_restrict = TRUE;
+ break;
+
+ case 0x10:
+ p_csp->service_profile_entry[j].service.number_identifiers.b_connected_line_identification_present = TRUE;
+ break;
+
+ case 0x08:
+ p_csp->service_profile_entry[j].service.number_identifiers.b_malicious_call_identifier = TRUE;
+ break;
+
+ case 0x02:
+ p_csp->service_profile_entry[j].service.number_identifiers.b_calling_line_identification_send = TRUE;
+ break;
+
+ case 0x01:
+ p_csp->service_profile_entry[j].service.number_identifiers.b_calling_line_identification_block = TRUE;
+ break;
+
+ default:
+ break;
+ }
+ mask = mask >> 1;
+ }
+ break;
+
+ case 0x09:
+ for (k = 0; k < 6; k++) {
+ switch (byteSignificance & mask) {
+ case 0x80:
+ p_csp->service_profile_entry[j].service.phase_services.b_menu_for_gprs = TRUE;
+ break;
+
+ case 0x40:
+ p_csp->service_profile_entry[j].service.phase_services.b_menu_for_high_speed_csd = TRUE;
+ break;
+
+ case 0x20:
+ p_csp->service_profile_entry[j].service.phase_services.b_menu_for_voice_group_call = TRUE;
+ break;
+
+ case 0x10:
+ p_csp->service_profile_entry[j].service.phase_services.b_menu_for_voice_broadcast_service = TRUE;
+ break;
+
+ case 0x08:
+ p_csp->service_profile_entry[j].service.phase_services.b_menu_for_multiple_subscriber_profile = TRUE;
+ break;
+
+ case 0x04:
+ p_csp->service_profile_entry[j].service.phase_services.b_menu_for_multiple_band = TRUE;
+ break;
+
+ default:
+ break;
+ }
+ mask = mask >> 1;
+ }
+ break;
+
+ case 0xC0:
+ for (k = 0; k < 8; k++) {
+ switch (byteSignificance & mask) {
+ case 0x80:
+ p_csp->service_profile_entry[j].service.value_added_services.b_restrict_menu_for_manual_selection = TRUE;
+ break;
+
+ case 0x40:
+ p_csp->service_profile_entry[j].service.value_added_services.b_restrict_menu_for_voice_mail = TRUE;
+ break;
+
+ case 0x20:
+ p_csp->service_profile_entry[j].service.value_added_services.b_restrict_menu_for_mo_sms_and_paging = TRUE;
+ break;
+
+ case 0x10:
+ p_csp->service_profile_entry[j].service.value_added_services.b_restrict_menu_for_mo_sms_with_emial_type = TRUE;
+ break;
+
+ case 0x08:
+ p_csp->service_profile_entry[j].service.value_added_services.b_restrict_menu_for_fax_calls = TRUE;
+ break;
+
+ case 0x04:
+ p_csp->service_profile_entry[j].service.value_added_services.b_restrict_menu_for_data_calls = TRUE;
+ break;
+
+ case 0x01:
+ p_csp->service_profile_entry[j].service.value_added_services.b_restrict_menu_for_change_language = TRUE;
+ break;
+
+ default:
+ break;
+ }
+ mask = mask >> 1;
+ }
+ break;
+
+ case 0xD5:
+ for (k = 0; k < 8; k++) {
+ switch (byteSignificance & mask) {
+ case 0x80:
+ case 0x40:
+ case 0x20:
+ case 0x10:
+ case 0x08:
+ case 0x04:
+ case 0x02:
+ case 0x01:
+ p_csp->service_profile_entry[j].service.information_numbers.b_information_numbers = TRUE;
+ break;
+
+ default:
+ break;
+ }
+ mask = mask >> 1;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ return TRUE;
+}
+
+gboolean tcore_sim_encode_csp(unsigned char *p_out, int out_length, struct tel_sim_cphs_csp *p_csp)
+{
+ unsigned char i, j = 0;
+
+ if (out_length == 0)
+ return FALSE;
+
+ memset((void *) p_out, 0xFF, out_length);
+
+ /*
+ * current telephony supports 22 byte cphs-csp data.
+ * 18 byte is mandatory, the other is optional.
+ */
+ for (i = 0, j = 0;
+ i < SIM_CPHS_CSP_LEN_MAX && j < SIM_CPHS_CSP_ENTRY_CNT_MAX;
+ i++, j++) {
+ p_out[i] = (unsigned char) p_csp->service_profile_entry[j].customer_service_group;
+ switch (p_out[i]) {
+ case 0x01:
+ p_out[++i] = (((unsigned char) p_csp->service_profile_entry[j].service.call_offering.b_call_forwarding_unconditional) << 7)
+ + (((unsigned char) p_csp->service_profile_entry[j].service.call_offering.b_call_forwarding_on_user_busy) << 6)
+ + (((unsigned char) p_csp->service_profile_entry[j].service.call_offering.b_call_forwarding_on_no_reply) << 5)
+ + (((unsigned char) p_csp->service_profile_entry[j].service.call_offering.b_call_forwarding_on_user_not_reachable) << 4)
+ + (((unsigned char) p_csp->service_profile_entry[j].service.call_offering.b_call_transfer) << 3);
+ break;
+
+ case 0x02:
+ p_out[++i] = (((unsigned char) p_csp->service_profile_entry[j].service.call_restriction.b_barring_of_all_outgoing_calls) << 7)
+ + (((unsigned char) p_csp->service_profile_entry[j].service.call_restriction.b_barring_of_outgoing_international_calls) << 6)
+ + (((unsigned char) p_csp->service_profile_entry[j].service.call_restriction.b_barring_of_outgoing_international_calls_except_hplmn) << 5)
+ + (((unsigned char) p_csp->service_profile_entry[j].service.call_restriction.b_barring_of_all_incoming_calls_roaming_outside_hplmn) << 4)
+ + (((unsigned char) p_csp->service_profile_entry[j].service.call_restriction.b_barring_of_incoming_calls_when_roaming) << 3);
+ break;
+
+ case 0x03:
+ p_out[++i] = (((unsigned char) p_csp->service_profile_entry[j].service.other_supp_services.b_multi_party_service) << 7)
+ + (((unsigned char) p_csp->service_profile_entry[j].service.other_supp_services.b_closed_user_group) << 6)
+ + (((unsigned char) p_csp->service_profile_entry[j].service.other_supp_services.b_advice_of_charge) << 5)
+ + (((unsigned char) p_csp->service_profile_entry[j].service.other_supp_services.b_preferential_closed_user_group) << 4)
+ + (((unsigned char) p_csp->service_profile_entry[j].service.other_supp_services.b_closed_user_group_outgoing_access) << 3);
+ break;
+
+ case 0x04:
+ p_out[++i] = (((unsigned char) p_csp->service_profile_entry[j].service.call_complete.b_call_hold) << 7)
+ + (((unsigned char) p_csp->service_profile_entry[j].service.call_complete.b_call_waiting) << 6)
+ + (((unsigned char) p_csp->service_profile_entry[j].service.call_complete.b_completion_of_call_to_busy_subscriber) << 5)
+ + (((unsigned char) p_csp->service_profile_entry[j].service.call_complete.b_user_user_signalling) << 4);
+ break;
+
+ case 0x05:
+ p_out[++i] = (((unsigned char) p_csp->service_profile_entry[j].service.teleservices.b_short_message_mobile_terminated) << 7)
+ + (((unsigned char) p_csp->service_profile_entry[j].service.teleservices.b_short_message_mobile_originated) << 6)
+ + (((unsigned char) p_csp->service_profile_entry[j].service.teleservices.b_short_message_cell_broadcast) << 5)
+ + (((unsigned char) p_csp->service_profile_entry[j].service.teleservices.b_short_message_reply_path) << 4)
+ + (((unsigned char) p_csp->service_profile_entry[j].service.teleservices.b_short_message_delivery_conf) << 3)
+ + (((unsigned char) p_csp->service_profile_entry[j].service.teleservices.b_short_message_protocol_identifier) << 2)
+ + (((unsigned char) p_csp->service_profile_entry[j].service.teleservices.b_short_message_validity_period) << 1);
+ break;
+
+ case 0x06:
+ p_out[++i] = (((unsigned char) p_csp->service_profile_entry[j].service.cphs_teleservices.b_alternative_line_service) << 7);
+ break;
+
+ case 0x07:
+ p_out[++i] = (((unsigned char) p_csp->service_profile_entry[j].service.cphs_features.b_string_service_table) << 7);
+ break;
+
+ case 0x08:
+ p_out[++i] = (((unsigned char) p_csp->service_profile_entry[j].service.number_identifiers.b_calling_line_identification_present) << 7)
+ + (((unsigned char) p_csp->service_profile_entry[j].service.number_identifiers.b_connected_line_identification_restrict) << 5)
+ + (((unsigned char) p_csp->service_profile_entry[j].service.number_identifiers.b_connected_line_identification_present) << 4)
+ + (((unsigned char) p_csp->service_profile_entry[j].service.number_identifiers.b_malicious_call_identifier) << 3)
+ + (((unsigned char) p_csp->service_profile_entry[j].service.number_identifiers.b_calling_line_identification_send) << 1)
+ + ((unsigned char) p_csp->service_profile_entry[j].service.number_identifiers.b_calling_line_identification_block);
+ break;
+
+ case 0x09:
+ p_out[++i] = (((unsigned char) p_csp->service_profile_entry[j].service.phase_services.b_menu_for_gprs) << 7)
+ + (((unsigned char) p_csp->service_profile_entry[j].service.phase_services.b_menu_for_high_speed_csd) << 6)
+ + (((unsigned char) p_csp->service_profile_entry[j].service.phase_services.b_menu_for_voice_group_call) << 5)
+ + (((unsigned char) p_csp->service_profile_entry[j].service.phase_services.b_menu_for_voice_broadcast_service) << 4)
+ + (((unsigned char) p_csp->service_profile_entry[j].service.phase_services.b_menu_for_multiple_subscriber_profile) << 3)
+ + (((unsigned char) p_csp->service_profile_entry[j].service.phase_services.b_menu_for_multiple_band) << 2);
+ break;
+
+ case 0xC0:
+ p_out[++i] = (((unsigned char) p_csp->service_profile_entry[j].service.value_added_services.b_restrict_menu_for_manual_selection) << 7)
+ + (((unsigned char) p_csp->service_profile_entry[j].service.value_added_services.b_restrict_menu_for_voice_mail) << 6)
+ + (((unsigned char) p_csp->service_profile_entry[j].service.value_added_services.b_restrict_menu_for_mo_sms_and_paging) << 5)
+ + (((unsigned char) p_csp->service_profile_entry[j].service.value_added_services.b_restrict_menu_for_mo_sms_with_emial_type) << 4)
+ + (((unsigned char) p_csp->service_profile_entry[j].service.value_added_services.b_restrict_menu_for_fax_calls) << 3)
+ + (((unsigned char) p_csp->service_profile_entry[j].service.value_added_services.b_restrict_menu_for_data_calls) << 2)
+ + ((unsigned char) p_csp->service_profile_entry[j].service.value_added_services.b_restrict_menu_for_change_language);
+ break;
+
+ case 0xD5:
+ if (p_csp->service_profile_entry[j].service.information_numbers.b_information_numbers)
+ p_out[++i] = 0xFF;
+ else
+ p_out[++i] = 0x00;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return TRUE;
+}
+
+gboolean tcore_sim_decode_mwis(struct tel_sim_mw *pMwis, unsigned char *p_in, int in_length)
+{
+ int i;
+ unsigned char type = 0;
+ unsigned char mask = 0x01;
+
+ if (in_length == 0)
+ return FALSE;
+
+ memset((void *) pMwis, 0, sizeof(struct tel_sim_mw));
+
+ type = p_in[0]; /* 0x07 */
+
+ if (type) {
+ for (i = 0; i < 5; i++) {
+ switch (type & mask) {
+ case 0x01:
+ pMwis->indicator_status = pMwis->indicator_status | SIM_MWIS_VOICE;
+ break;
+
+ case 0x02:
+ pMwis->indicator_status = pMwis->indicator_status | SIM_MWIS_FAX;
+ break;
+
+ case 0x04:
+ pMwis->indicator_status = pMwis->indicator_status | SIM_MWIS_EMAIL;
+ break;
+
+ case 0x08:
+ pMwis->indicator_status = pMwis->indicator_status | SIM_MWIS_OTHER;
+ break;
+
+ case 0x10:
+ pMwis->indicator_status = pMwis->indicator_status | SIM_MWIS_VIDEO;
+ break;
+
+ default:
+ pMwis->indicator_status = pMwis->indicator_status | SIM_MWIS_NONE;
+ break;
+ }
+ mask = mask << 1;
+ }
+
+ pMwis->voice_count = p_in[1];
+ pMwis->fax_count = p_in[2];
+ pMwis->email_count = p_in[3];
+ pMwis->other_count = p_in[4];
+
+ if (in_length == 6)
+ pMwis->video_count = p_in[5];
+ }
+
+ return TRUE;
+}
+
+char *tcore_sim_encode_mwis(int *out_length, const struct tel_sim_mw *pMwis, int in_length)
+{
+ char *p_out = NULL;
+ int i = 0;
+ int encoded_size = 0;
+
+ if (out_length == 0)
+ return NULL;
+
+ /*
+ * by 3GPP spec (31.102),
+ * EF-MWIS record length should be <= 6. (5 or 6)
+ */
+ if (in_length > 6)
+ encoded_size = 6;
+ else
+ encoded_size = in_length;
+
+ p_out = calloc(1, encoded_size);
+ if (!p_out)
+ return NULL;
+
+ for (i = 0; i < encoded_size; i++) {
+ switch (i) {
+ case 0:
+ p_out[0] = (unsigned char) pMwis->indicator_status;
+ break;
+
+ case 1:
+ p_out[1] = pMwis->voice_count;
+ break;
+
+ case 2:
+ p_out[2] = pMwis->fax_count;
+ break;
+
+ case 3:
+ p_out[3] = pMwis->email_count;
+ break;
+
+ case 4:
+ p_out[4] = pMwis->other_count;
+ break;
+
+ case 5:
+ p_out[5] = pMwis->video_count;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ *out_length = encoded_size;
+ return p_out;
+}
+
+gboolean tcore_sim_decode_vmwf(struct tel_sim_cphs_mw *p_vmwf, unsigned char *p_in, unsigned long in_length)
+{
+ int i, j = 0;
+ unsigned char *pTemp = (unsigned char *) p_vmwf;
+ unsigned char mask = 0x0F;
+ unsigned char voiceMsgFlg = 0;
+
+ if (in_length == 0) {
+ dbg("fail - input length is zero");
+ return FALSE;
+ }
+
+ /* current telephony supports 2 byte cphs-vmwf data */
+ for (i = 0; i < SIM_CPHS_VMWF_LEN_MAX; i++) {
+ voiceMsgFlg = p_in[i];
+ for (j = 0; j < 2; j++) {
+ if ((voiceMsgFlg & mask) == 0x0A)
+ *pTemp = 1; /* TRUE */
+ else if ((voiceMsgFlg & mask) == 0x05)
+ *pTemp = 0; /* FALSE */
+
+ pTemp += sizeof(gboolean);
+ voiceMsgFlg = voiceMsgFlg >> 4;
+ }
+ }
+ return TRUE;
+}
+
+char *tcore_sim_encode_vmwf(int *out_length, const struct tel_sim_cphs_mw *p_vmwf, int in_length)
+{
+ int i, j = 0;
+ char *p_out = NULL;
+ unsigned char *pTemp = (unsigned char *) p_vmwf;
+ unsigned char present = 0x0A;
+ unsigned char absent = 0x05;
+
+ if (out_length == 0)
+ return NULL;
+
+ p_out = calloc(1, in_length);
+ if (!p_out)
+ return NULL;
+
+ for (i = 0; i < in_length; i++) {
+ present = 0x0A;
+ absent = 0x05;
+
+ p_out[i] = 0x00;
+
+ for (j = 0; j < 2; j++) {
+ if (*pTemp)
+ p_out[i] = p_out[i] | present; /* TRUE */
+ else
+ p_out[i] = p_out[i] | absent; /* TRUE */
+
+ pTemp += sizeof(gboolean);
+ present = present << 4;
+ absent = absent << 4;
+ }
+ }
+
+ *out_length = in_length;
+ return p_out;
+}
+
+gboolean tcore_sim_decode_ons(unsigned char *p_out, unsigned char *p_in, int in_length)
+{
+ int length;
+ memset((void *) p_out, 0, SIM_CPHS_OPERATOR_NAME_LEN_MAX+1);
+
+ if (in_length == 0)
+ return FALSE;
+
+ if (_is_empty(p_in, in_length) == TRUE)
+ return FALSE;
+
+ /* current telephony supports 25 byte cphs-operator name string. */
+ if (in_length >= SIM_CPHS_OPERATOR_NAME_LEN_MAX)
+ in_length = SIM_CPHS_OPERATOR_NAME_LEN_MAX;
+
+ length = _get_string(p_out, p_in, in_length);
+ p_out[length] = '\0';
+ dbg("Operator Name is (%s) & Length (%d) ", p_out, length);
+
+ return TRUE;
+}
+
+gboolean tcore_sim_decode_cfis(struct tel_sim_cfis *p_cfis, unsigned char *p_in, int in_length)
+{
+ int bcd_byte; /* dialing number max length */
+ int digit_len;
+ int i = 0;
+ if (in_length == 0)
+ return FALSE;
+
+ if (_is_empty(p_in, in_length) == TRUE) {
+ dbg("empty record. all data is set 0xff");
+ return TRUE; /* this is empty record */
+ }
+
+ p_cfis->msp_num = p_in[i++];
+ p_cfis->cfu_status = p_in[i++];
+
+ /* get TON and NPI */
+ p_cfis->ton = (p_in[++i] >> 4) & 0x07;
+ p_cfis->npi = p_in[i++] & 0x0F;
+
+ /* get actual dialing number length */
+ /* current telephony supports 20 byte dialing number format. */
+ bcd_byte = _get_valid_bcd_byte(&p_in[i], SIM_XDN_NUMBER_LEN_MAX / 2);
+
+ /* get dialing number/SSC string */
+ digit_len = _bcd_to_digit((char *) p_cfis->cfu_num, (char *) &p_in[i], bcd_byte); /* actual dialing number length in BCD. */
+ dbg("Dialing number Length[%d]", digit_len);
+
+ i = i + SIM_XDN_NUMBER_LEN_MAX / 2;
+
+ /* get Capability/Configuration id */
+ p_cfis->cc2_id = p_in[i++];
+
+ /* get Extension1 id */
+ p_cfis->ext7_id = p_in[i];
+
+ dbg("MspNumber 0x%x", p_cfis->msp_num);
+ dbg("Status 0x%x", p_cfis->cfu_status);
+ dbg("TypeOfNumber %d", p_cfis->ton);
+ dbg("NumberingPlanIdent %d", p_cfis->npi);
+ dbg("Dialing number[%s]", p_cfis->cfu_num);
+
+ return TRUE;
+}
+
+gboolean tcore_sim_decode_img(struct tel_sim_img *p_out, unsigned char *p_in, int in_length)
+{
+ int i = 1;
+
+ dbg("Func Entrance");
+
+ if ((NULL == p_out) || (NULL == p_in))
+ return FALSE;
+
+ if ((in_length == 0) || (in_length == 0xff) || (10 > in_length)) {
+ dbg("No valid IMG data present - length:[%x]", in_length);
+ return FALSE;
+ }
+
+ if (_is_empty(p_in, in_length) == TRUE) {
+ dbg("empty record. all data is set 0xff");
+ return FALSE; /* this is empty record */
+ }
+
+ /* We are trying to decode only the 1st valid image data property and ignoring other for time being */
+ p_out->width = p_in[i++];
+ p_out->height = p_in[i++];
+ p_out->ics = p_in[i++];
+ p_out->iidf_fileid = (*(p_in+4) << 8) | (*(p_in+5) & 0x00ff); /*index is 4 and 5 because the 1st byte is number of actual image instance */
+ p_out->offset = (*(p_in+6) << 8) | (*(p_in+7) & 0x00ff);
+ p_out->length = (*(p_in+8) << 8) | (*(p_in+9) & 0x00ff);
+
+ dbg("p_out->width[%d], p_out->height[%d], p_out->ics[%d], p_out->offset[%d], p_out->length[%d], p_out->iidf_fileid[0x%02x]",
+ p_out->width, p_out->height, p_out->ics, p_out->offset, p_out->length, p_out->iidf_fileid);
+
+ return TRUE;
+}
+
+gboolean tcore_sim_decode_isim_impi(struct tel_sim_impi *p_out, unsigned char *p_in, int in_length)
+{
+ unsigned char tag = 0, len = 0;
+
+ if (p_in == NULL || p_out == NULL || in_length < 2)
+ return FALSE;
+
+ tag = p_in[0];
+ if (tag != 0x80) {
+ err("tag[0x%x] should be 0x80. return FALSE.", tag);
+ return FALSE;
+ }
+
+ len = p_in[1];
+
+ if (in_length < len + 2)
+ err("invalid length. in_length[%d] < TLV_len[%d] + 2", in_length, len);
+
+ p_out->impi = g_memdup(&p_in[2], len);
+
+ return TRUE;
+}
+
+gboolean tcore_sim_decode_isim_domain(struct tel_sim_domain *p_out, unsigned char *p_in, int in_length)
+{
+ unsigned char tag = 0, len = 0;
+
+ if (p_in == NULL || p_out == NULL || in_length < 2)
+ return FALSE;
+
+ tag = p_in[0];
+ if (tag != 0x80) {
+ err("tag[0x%x] should be 0x80. return FALSE.", tag);
+ return FALSE;
+ }
+
+ len = p_in[1];
+
+ if (in_length < len + 2)
+ err("invalid length. in_length[%d] < TLV_len[%d] + 2", in_length, len);
+
+ p_out->domain = g_memdup(&p_in[2], len);
+
+ return TRUE;
+}
+
+gboolean tcore_sim_decode_isim_impu(struct tel_sim_impu *p_out, unsigned char *p_in, int in_length)
+{
+ unsigned char tag = 0, len = 0;
+
+ if (p_in == NULL || p_out == NULL || in_length < 2)
+ return FALSE;
+
+ tag = p_in[0];
+ if (tag != 0x80) {
+ err("tag[0x%x] should be 0x80. return FALSE.", tag);
+ return FALSE;
+ }
+
+ len = p_in[1];
+
+ if (in_length < len + 2)
+ err("invalid length. in_length[%d] < TLV_len[%d] + 2", in_length, len);
+
+ p_out->impu = g_memdup(&p_in[2], len);
+
+ return TRUE;
+}
+
+gboolean tcore_sim_decode_isim_pcscf(struct tel_sim_pcscf *p_out, unsigned char *p_in, int in_length)
+{
+ unsigned char tag = 0, len = 0;
+
+ if (p_in == NULL || p_out == NULL || in_length < 2)
+ return FALSE;
+
+ tag = p_in[0];
+ if (tag != 0x80) {
+ err("tag[0x%x] should be 0x80. return FALSE.", tag);
+ return FALSE;
+ }
+
+ /* P-CSCF Address length */
+ len = p_in[1];
+
+ if (in_length < len + 2)
+ err("invalid length. in_length[%d] < TLV_len[%d] + 2", in_length, len);
+
+ /* P-CSCF Address type */
+ if (p_in[2] == 0x00)
+ p_out->type = SIM_PCSCF_TYPE_FQDN;
+ else if (p_in[2] == 0x01)
+ p_out->type = SIM_PCSCF_TYPE_IPV4;
+ else if (p_in[2] == 0x02)
+ p_out->type = SIM_PCSCF_TYPE_IPV6;
+
+ /*
+ * If P-CSCF Address type is "00" (FQDN), then address shall be
+ * encoded to an octet string according to UTF-8 encoding rules.
+ * So, no need to convert it to UTF-8.
+ */
+ if (p_out->type == SIM_PCSCF_TYPE_FQDN) {
+ p_out->pcscf = g_memdup(&p_in[3], len - 1);
+ } else {
+ unsigned char buf[255] = {0, };
+ unsigned short buf_len;
+ gboolean ret = FALSE;
+
+ ret = tcore_util_convert_string_to_utf8(buf, &buf_len, ALPHABET_FORMAT_SMS_DEFAULT,
+ (const unsigned char *)&p_in[3], len - 1);
+ if (ret)
+ p_out->pcscf = g_memdup(buf, buf_len);
+ }
+
+ return TRUE;
+}
+
+char *tcore_sim_encode_cfis(int *out_length, const struct tel_sim_cfis *p_cfis)
+{
+ char *encoded_o = NULL;
+ char bcd[10];
+
+ encoded_o = calloc(1, 16); /* EF-CFIS record length is 16 */
+ if (!encoded_o)
+ return NULL;
+
+ memset(bcd, 0xff, 10);
+
+ /*
+ * Bytes Description M/O Length
+ *----------------------------------------------------------------------------------------
+ * 1 MSP number M 1 byte
+ * 2 CFU indicator status M 1 byte
+ * 3 Length of BCD number M 1 byte
+ * 4 TON and NPI M 1 byte
+ * 5 to 14 Dialing Number M 10 bytes. unused byte should be set with 'F'
+ * 15 Capability/Configuration2 Record Identifier M 1 byte
+ * 16 Extension 7 Record Identifier M 1 byte
+ */
+ encoded_o[0] = p_cfis->msp_num;
+ encoded_o[1] = p_cfis->cfu_status;
+
+ encoded_o[2] = (strlen(p_cfis->cfu_num) + 1) / 2;
+
+ /* set TON and NPI */
+ encoded_o[3] = 0x80;
+ encoded_o[3] |= (p_cfis->ton & 0x07) << 4;
+ encoded_o[3] |= p_cfis->npi & 0x0F;
+
+ _digit_to_bcd(bcd, (char *)&p_cfis->cfu_num, strlen(p_cfis->cfu_num));
+ memcpy(&encoded_o[4], bcd, 10);
+
+ encoded_o[14] = p_cfis->cc2_id;
+ encoded_o[15] = p_cfis->ext7_id;
+
+ *out_length = 16;
+ return encoded_o;
+}
+
+gboolean tcore_sim_decode_dynamic_flag(struct tel_sim_cphs_dflag *p_df, unsigned char *p_in, int in_length)
+{
+ if (in_length == 0)
+ return FALSE;
+
+ memset((void *)p_df, 0, sizeof(struct tel_sim_cphs_dflag));
+
+ switch (p_in[0] & 0x01) {
+ case 0x00:
+ p_df->DynamicFlags = SIM_DYNAMIC_FLAGS_LINE2;
+ break;
+
+ case 0x01:
+ p_df->DynamicFlags = SIM_DYNAMIC_FLAGS_LINE1;
+ break;
+
+ default:
+ warn("invalid input");
+ break;
+ }
+
+ return TRUE;
+}
+
+gboolean tcore_sim_decode_dynamic2_flag(struct tel_sim_cphs_dflag2 *p_d2f, unsigned char *p_in, int in_length)
+{
+ if (in_length == 0)
+ return FALSE;
+
+ memset((void *) p_d2f, 0, sizeof(struct tel_sim_cphs_dflag2));
+
+ switch (p_in[0] & 0x01) {
+ case 0x00:
+ p_d2f->Dynamic2Flag = SIM_PIN2_ACCESSIBLE_FLAGS_UNLOCKED;
+ break;
+
+ case 0x01:
+ p_d2f->Dynamic2Flag = SIM_PIN2_ACCESSIBLE_FLAGS_LOCKED;
+ break;
+
+ default:
+ warn("invalid input");
+ break;
+ }
+
+ return TRUE;
+}
+
+gboolean tcore_sim_encode_dynamic_flag(char *p_out, int out_length, struct tel_sim_cphs_dflag *p_df)
+{
+ if (out_length == 0 || out_length > 1)
+ return FALSE;
+
+ memset((void *)p_out, 0xFF, out_length);
+ p_out[0] = p_df->DynamicFlags;
+
+ return TRUE;
+}
+
+gboolean tcore_sim_encode_dynamic2_flag(char *p_out, int out_length, struct tel_sim_cphs_dflag2 *p_d2f)
+{
+ if (out_length == 0 || out_length > 1)
+ return FALSE;
+
+ memset((void *)p_out, 0xFF, out_length);
+ p_out[0] = p_d2f->Dynamic2Flag;
+
+ return TRUE;
+}
+
+gboolean tcore_sim_decode_cphs_info(struct tel_sim_cphs_info *pCphsInfo, unsigned char *p_in, int in_length)
+{
+ int i, j = 0;
+ unsigned char mask = 0x03;
+ unsigned char *pTemp = (unsigned char *) &pCphsInfo->CphsServiceTable;
+
+ memset((void *)pCphsInfo, 0, sizeof(struct tel_sim_cphs_info));
+
+ if (in_length == 0)
+ return FALSE;
+
+ /* CPHS info EF has 3 bytes data. */
+ if (in_length >= SIM_CPHS_INFO_LEN_MAX)
+ in_length = SIM_CPHS_INFO_LEN_MAX;
+
+ switch (p_in[0]) {
+ case 0x01:
+ pCphsInfo->CphsPhase = SIM_CPHS_PHASE1;
+ break;
+
+ case 0x02:
+ pCphsInfo->CphsPhase = SIM_CPHS_PHASE2;
+ break;
+
+ default:
+ pCphsInfo->CphsPhase = SIM_CPHS_PHASE_RFU;
+ break;
+ }
+
+ dbg("Cphs Phase %d \n", pCphsInfo->CphsPhase);
+
+ for (i = 1; i < in_length; i++) { /* CPHS SST is only 2 bytes */
+ mask = 0x03; /* reset mast to check first bit */
+ for (j = 0; j < 4; j++) {
+ if (p_in[i] & mask)
+ *pTemp = 1;
+
+ dbg("Byte (%d), service (%d) ", i + 1, *pTemp);
+ pTemp += sizeof(gboolean);
+ mask = mask << 2;
+ }
+ }
+
+ return TRUE;
+}
+
+gboolean tcore_sim_decode_short_ons(unsigned char *p_out, unsigned char *p_in, int in_length)
+{
+ int length;
+
+ memset(p_out, 0x00, SIM_CPHS_OPERATOR_NAME_SHORT_FORM_LEN_MAX+1);
+
+ if (_is_empty(p_in, in_length) == TRUE)
+ return FALSE; /* this is empty record */
+
+ /* CPHS specification shows current EF include 10 bytes */
+ if (in_length == 0)
+ return FALSE;
+
+ if (in_length > SIM_CPHS_OPERATOR_NAME_SHORT_FORM_LEN_MAX)
+ in_length = SIM_CPHS_OPERATOR_NAME_SHORT_FORM_LEN_MAX;
+
+ length = _get_string(p_out, p_in, in_length);
+ p_out[length] = '\0';
+ dbg("Operator short Name is (%s) & length (%d)", p_out, length);
+
+ return TRUE;
+}
+
+gboolean tcore_sim_decode_information_number(struct tel_sim_cphs_info_number *p_info, unsigned char *p_in, int in_length)
+{
+ int i;
+
+ if (in_length == 0)
+ return FALSE;
+
+ for (i = 0; i < in_length; i++)
+ dbg(" \t0x%04X.", p_in[i]);
+
+ if (_is_empty(p_in, in_length) == TRUE)
+ return FALSE; /* this is empty record */
+
+ p_info->AlphaIdLength = p_in[0];
+
+ if (p_in[1] & 0x0F)
+ p_info->IndexLevelIndicator = (enum tel_sim_cphs_index_level)(p_in[1] & 0x0F);
+
+ if (p_in[1] & 0x10)
+ p_info->PremiumServiceIndicator = TRUE;
+
+ if (p_in[1] & 0x20)
+ p_info->PremiumServiceIndicator = TRUE;
+
+ _get_string(p_info->Alpha_id, &p_in[2], p_info->AlphaIdLength);
+
+ p_info->DiallingnumLength = p_in[2 + p_info->AlphaIdLength] * 2;
+ p_info->TypeOfNumber = (p_in[3 + p_info->AlphaIdLength] >> 4) & 0x07;
+ p_info->NumberingPlanIdentity = p_in[3 + p_info->AlphaIdLength] & 0x0F;
+
+ /* get dialing number/SSC string */
+ _bcd_to_digit((char *)p_info->DiallingnumLength,
+ (char *)&p_in[4 + p_info->AlphaIdLength],
+ p_info->DiallingnumLength / 2); /* actual dialing number length in BCD. */
+
+ /* get Extension1 id */
+ p_info->Ext1RecordId = p_in[4 + p_info->AlphaIdLength + p_info->DiallingnumLength / 2];
+
+ return TRUE;
+}
+
+gboolean tcore_sim_decode_opl(struct tel_sim_opl *p_opl, unsigned char *p_in, int in_length)
+{
+ if (_is_empty(p_in, in_length) == TRUE) {
+ memset(p_opl, 0x00, sizeof(struct tel_sim_opl));
+ return FALSE; /* this is empty record */
+ }
+
+ _decode_plmn(p_in, p_opl->plmn);
+ dbg(" PLMN Code[%s]", p_opl->plmn);
+
+ p_opl->lac_from = (*(p_in+3) << 8) | (*(p_in+4) & 0x00ff);
+ dbg(" Start value of the LAC range[%x]", p_opl->lac_from);
+
+ p_opl->lac_to = (*(p_in+5) << 8) | (*(p_in+6) & 0x00ff);
+ dbg(" End value of the LAC range[%x]", p_opl->lac_to);
+
+ p_opl->rec_identifier = p_in[7];
+ dbg(" PNN Record identifier[%x]", p_opl->rec_identifier);
+
+ return TRUE;
+}
+
+gboolean tcore_sim_decode_pnn(struct tel_sim_pnn *p_pnn, unsigned char *p_in, int in_length)
+{
+ int f_name_len = 0, s_name_len = 0;
+ int cvt_leng = 0, s_name_base = 0;
+
+ if (_is_empty(p_in, in_length) == TRUE) {
+ memset(p_pnn, 0x00, sizeof(struct tel_sim_pnn));
+ return FALSE; /* this is empty record */
+ }
+
+ /* Full name for network IEI(Information Element Identifier), 0x43 */
+ if (p_in[0] == 0x43) {
+ dbg(" Full name of network IEI exist");
+ /* f_name_part includes information byte. */
+ f_name_len = (int)p_in[1] - 1;
+
+ /*
+ * 3rd byte information element(according to TS 24.008 for Network Name)
+ * 8 :ext1
+ * 7 6 5 : coding scheme
+ * 4 : Add CI
+ * 3 2 1 : number of spare bits in last octet
+ *
+ * Coding Scheme (octet 3, bits 5-7)
+ * 0 0 0 Cell Broadcast data coding scheme, GSM default alphabet, language unspecified, defined in 3GPP TS 23.038 [8b]
+ * 0 0 1 UCS2 (16 bit) [72]
+ * 0 1 0 to reserved
+ * 1 1 1 to reserved
+ */
+ if ((p_in[2] & 0x70) >> 4 == 0) {
+ dbg("DCS:GSM7");
+
+ /*
+ * In case of GSM7, 35byte packing data will be
+ * converted 40 bytes unpacking string.
+ */
+ if (f_name_len > (SIM_NW_FULL_NAME_LEN_MAX * 7) / 8)
+ f_name_len = (SIM_NW_FULL_NAME_LEN_MAX * 7) / 8;
+
+ _unpack_7bit28bit(p_in + 3,
+ f_name_len, (unsigned char *)(p_pnn->full_name));
+ } else if ((p_in[2] & 0x70) >> 4 == 1) {
+ dbg("DCS:UCS2");
+
+ /* current telephony supports 40 bytes network name string */
+ if (f_name_len > SIM_NW_FULL_NAME_LEN_MAX)
+ f_name_len = SIM_NW_FULL_NAME_LEN_MAX;
+
+ _ucs2_to_utf8(f_name_len, p_in + 3,
+ (int *)&cvt_leng, (unsigned char *)(p_pnn->full_name));
+ } else {
+ dbg("DCS:unknown");
+
+ return FALSE;
+ }
+
+ dbg(" Full name of network contents[%s]", p_pnn->full_name);
+
+ s_name_base = (int)p_in[1] + 2;
+ dbg(" short name base byte [0x%02x]", s_name_base);
+
+ /* Short Name for network IEI(Information Element Identifier), 0x45 */
+ if (p_in[s_name_base] == 0x45) {
+ dbg(" Short name of network IEI exist");
+
+ /* s_name_part includes information byte. */
+ s_name_len = p_in[s_name_base + 1] - 1;
+
+ if ((p_in[s_name_base + 2] & 0x70) >> 4 == 0) {
+ dbg("DCS:GSM7");
+
+ /*
+ * In case of GSM7, 35byte packing data
+ * will be converted 40 bytes unpacking string.
+ */
+ if (s_name_len > (SIM_NW_FULL_NAME_LEN_MAX * 7) / 8)
+ s_name_len = (SIM_NW_FULL_NAME_LEN_MAX * 7) / 8;
+
+ _unpack_7bit28bit(p_in + s_name_base + 3,
+ s_name_len, (unsigned char *)(p_pnn->short_name));
+ } else if ((p_in[s_name_base + 2] & 0x70) >> 4 == 1) {
+ dbg("DCS:UCS2");
+
+ if (s_name_len > SIM_NW_FULL_NAME_LEN_MAX)
+ s_name_len = SIM_NW_FULL_NAME_LEN_MAX;
+
+ _ucs2_to_utf8(s_name_len, p_in + s_name_base + 3,
+ (int *)&cvt_leng, (unsigned char *)(p_pnn->short_name));
+ } else {
+ dbg("DCS:unknown");
+
+ return FALSE;
+ }
+
+ dbg(" Short name of network contents[%s]", p_pnn->short_name);
+ }
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+gboolean tcore_sim_decode_oplmnwact(struct tel_sim_oplmnwact_list *p_list, unsigned char *p_in, int in_length)
+{
+ unsigned long m = 0;
+
+ /*
+ * current raw data can include invalid OPLMN data(ex: ff ff ff 00 00).
+ * so we can`t decide the number of OPLMN records directly.
+ */
+ int rawOplmnWactCount = 0;
+ int i = 0;
+
+ memset((void *)p_list, 0, sizeof(struct tel_sim_oplmnwact_list));
+
+ rawOplmnWactCount = in_length / 5;
+
+ dbg("rawOplmnWactCount[%d]", rawOplmnWactCount);
+
+ for (i = 0; i < rawOplmnWactCount; i++) {
+ /*
+ * Regarding current IPC data, even if there`s no OPLMN value,
+ * IPC data is sending with 'ff ff ff 00 00'. so we should check for validation.
+ */
+ if (p_in[m] == 0xff) {
+ p_list->opwa_count = m / 5;
+ dbg("OPLMN(MCC+MNC) value is not found at p_in[m]=[%lu].So OPLMN count is [%d]",
+ m, p_list->opwa_count);
+ return TRUE;
+ }
+
+ _decode_plmn(&p_in[m], p_list->opwa[i].plmn);
+ dbg("[%d] OPLMN PLMN Code[%s]", i, p_list->opwa[i].plmn);
+
+ if (p_in[m+3] & 0x80)
+ p_list->opwa[i].b_umts = 1;
+
+ if (p_in[m+4] & 0x80)
+ p_list->opwa[i].b_gsm = 1;
+
+ m = m + 5;
+ }
+
+ p_list->opwa_count = rawOplmnWactCount;
+ dbg("OPLMN count is p_list->opwa_count[%d]", p_list->opwa_count);
+
+ return TRUE;
+}
+
+gboolean tcore_sim_decode_ef_info(struct tcore_sim_ef_info *p_ef_info, CoreObject *o, char *p_in, int in_length)
+{
+ unsigned short arr_file_id = 0;
+ char *record_data = NULL;
+ unsigned char file_type_tag = SIM_FILE_TYPE_TAG;
+ unsigned char *ptr_data;
+ unsigned char file_id_len = 0;
+ gboolean ret = FALSE;
+
+ if (!p_ef_info) {
+ err("output parameter is null");
+ return ret;
+ }
+
+ if (_is_empty((unsigned char *)p_in, in_length) == TRUE) {
+ memset(p_ef_info, 0x00, sizeof(struct tcore_sim_ef_info));
+ return ret; /* Empty record */
+ }
+
+ record_data = tcore_util_convert_hexstring_to_bytes(p_in);
+ if (!record_data) {
+ err("tcore_util_convert_hexstring_to_bytes Failed!!");
+ return ret;
+ }
+ tcore_util_hex_dump(" ", strlen(p_in) / 2, record_data);
+
+ ptr_data = (unsigned char *)record_data;
+ switch (tcore_sim_get_type(o)) {
+ case 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)
+ */
+
+ /* FCP template tag - File Control Parameters tag*/
+ if (*ptr_data == SIM_FCP_TEMPLATE_TAG) {
+ /* parse complete FCP tag. increment to next byte*/
+ ptr_data++;
+
+ dbg("tag_len: %02x", *ptr_data++);
+ /* FCP file descriptor - file type, accessibility, DF, ADF etc*/
+ if (*ptr_data == SIM_FILE_DESCRIPTOR_TAG) {
+ /* increment to next byte */
+ ptr_data++;
+
+ /* 2 or 5 value*/
+ ptr_data++;
+
+ /* consider only last 3 bits*/
+ file_type_tag = file_type_tag & (*ptr_data);
+ dbg("File Type Tag: %02x", file_type_tag);
+
+ switch (file_type_tag) {
+ case SIM_FTYPE_TRANSPARENT:
+ dbg("FileType: [Transparent file type]");
+ p_ef_info->file_type = SIM_FTYPE_TRANSPARENT;
+
+ /* increment to next byte */
+ ptr_data++;
+
+ /* increment to next byte */
+ ptr_data++;
+ break;
+
+ case SIM_FTYPE_LINEAR_FIXED:
+ dbg("FileType: [Linear fixed file type]");
+ /* increment to next byte */
+ ptr_data++;
+
+ /* data coding byte - value 21 */
+ ptr_data++;
+
+ /* 2bytes */
+ memcpy(&p_ef_info->record_length, ptr_data, 2);
+
+ /* swap bytes */
+ p_ef_info->record_length = _swap_bytes16(p_ef_info->record_length);
+ ptr_data = ptr_data + 2;
+ p_ef_info->number_of_records = *ptr_data++;
+
+ /* Data lossy conversation from enum (int) to unsigned char */
+ p_ef_info->file_type = SIM_FTYPE_LINEAR_FIXED;
+ break;
+
+ case SIM_FTYPE_CYCLIC:
+ dbg("FileType: [Cyclic fixed file type]");
+ /* increment to next byte */
+ ptr_data++;
+
+ /* data coding byte - value 21 */
+ ptr_data++;
+
+ /* 2bytes */
+ memcpy(&p_ef_info->record_length, ptr_data, 2);
+
+ /* swap bytes */
+ p_ef_info->record_length = _swap_bytes16(p_ef_info->record_length);
+ ptr_data = ptr_data + 2;
+ p_ef_info->number_of_records = *ptr_data++;
+ p_ef_info->file_type = SIM_FTYPE_CYCLIC;
+
+ break;
+
+ default:
+ err("Unhandled File Type [0x%x]", *ptr_data);
+ break;
+ }
+ } else {
+ err("INVALID FCP received[0x%x] - Debug!", *ptr_data);
+ goto EXIT;
+ }
+
+ /* File identifier - file id */ /* 0x84, 0x85, 0x86 etc are currently ignored and not handled */
+ if (*ptr_data == SIM_FILE_IDENTIFIER_TAG) {
+ /* increment to next byte */
+ ptr_data++;
+ file_id_len = *ptr_data++;
+ dbg("File ID length: %02x", file_id_len);
+
+ memcpy(&p_ef_info->file_id, ptr_data, file_id_len);
+ dbg("File ID: %x", p_ef_info->file_id);
+
+ /* swap bytes */
+ p_ef_info->file_id = _swap_bytes16(p_ef_info->file_id);
+
+ ptr_data = ptr_data + 2;
+ } else {
+ err("INVALID FCP received[0x%x] - Debug!", *ptr_data);
+ goto EXIT;
+ }
+
+ /* proprietary information */
+ if (*ptr_data == SIM_PROPRIETARY_INFORMATION_TAG) {
+ 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 {
+ err("INVALID FCP received[0x%x] - Debug!", *ptr_data);
+ }
+
+ /* 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 == SIM_LIFE_CYCLE_STATUS_TAG) {
+ /* increment to next byte */
+ ptr_data++;
+
+ /* length - value 1 */
+ ptr_data++;
+
+ switch (*ptr_data) {
+ case 0x04:
+ case 0x06:
+ dbg("Operation state - Deactivated");
+ ptr_data++;
+ break;
+
+ case 0x05:
+ case 0x07:
+ dbg("Operation state - Activated");
+ ptr_data++;
+ break;
+
+ default:
+ dbg("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 = _swap_bytes16(arr_file_id);
+ ptr_data = ptr_data + 2;
+ ptr_data++;
+ } else {
+ /* if tag length is not 3 */
+ /* ignoring bytes */
+ dbg("Useless security attributes, so jump to next tag");
+ ptr_data = ptr_data + (*ptr_data + 1);
+ }
+ } else {
+ err("INVALID FCP received[0x%x] - Debug!", *ptr_data);
+ goto EXIT;
+ }
+
+ /* file size excluding structural info*/
+ if (*ptr_data == SIM_FILE_SIZE_TAG) {
+ /*
+ * 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(&p_ef_info->file_size, ptr_data, 2);
+
+ /* swap bytes */
+ p_ef_info->file_size = _swap_bytes16(p_ef_info->file_size);
+ ptr_data = ptr_data + 2;
+ } else {
+ err("INVALID FCP received[0x%x] - Debug!", *ptr_data);
+ goto EXIT;
+ }
+
+ /* total file size including structural info*/
+ if (*ptr_data == SIM_TOTAL_FILE_SIZE_TAG) {
+ /* increment to next byte */
+ ptr_data++;
+ /* ignored bytes */
+ ptr_data = ptr_data + 3;
+ } else {
+ err("INVALID FCP received[0x%x] - Debug!", *ptr_data);
+ /* 0x81 is optional tag?? check out! so do not return -1 from here! */
+ }
+
+ /*short file identifier ignored*/
+ if (*ptr_data == SIM_SHORT_FILE_IDENTIFIER_TAG) {
+ dbg("0x88: Do Nothing");
+ /* DO NOTHING */
+ }
+ } else {
+ err("INVALID FCP received[0x%x] - Debug!", *ptr_data);
+ goto EXIT;
+ }
+ }
+ break;
+ case SIM_TYPE_GSM: {
+ /*Ignore RFU byte1 and byte2 */
+ ptr_data++;
+ ptr_data++;
+
+ /* file size */
+ memcpy(&p_ef_info->file_size, ptr_data, 2);
+
+ /* swap bytes */
+ p_ef_info->file_size = _swap_bytes16(p_ef_info->file_size);
+
+ /* parsed file size */
+ ptr_data = ptr_data + 2;
+
+ /* file id */
+ memcpy(&p_ef_info->file_id, ptr_data, 2);
+ p_ef_info->file_id = _swap_bytes16(p_ef_info->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 SIM_FTYPE_RFU:
+ /* RFU file type */
+ dbg("RFU file type- not handled - Debug!");
+ break;
+
+ case SIM_FTYPE_MF:
+ /* MF file type */
+ dbg("MF file type - not handled - Debug!");
+ break;
+
+ case SIM_FTYPE_DF:
+ /* DF file type */
+ dbg("DF file type - not handled - Debug!");
+ break;
+
+ case SIM_FTYPE_EF:
+ /* EF file type */
+ dbg("EF file type tag[%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++;
+ p_ef_info->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. */
+ p_ef_info->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 */
+ 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. */
+ p_ef_info->record_length = *ptr_data;
+ if (p_ef_info->record_length != 0)
+ p_ef_info->number_of_records = (p_ef_info->file_size / p_ef_info->record_length);
+ break;
+
+ default:
+ err("Unhandled file type[0x%x]", *ptr_data);
+ break;
+ }
+ }
+ break;
+ default:
+ err("Unknown SIM type [%d]", tcore_sim_get_type(o));
+ break;
+ }
+
+ ret = TRUE;
+
+EXIT:
+ g_free(record_data);
+ return ret;
+}
+
+enum tel_sim_status tcore_sim_get_status(CoreObject *o)
+{
+ struct private_object_data *po = NULL;
+
+ po = tcore_object_ref_object(o);
+ if (!po) {
+ dbg("po access fail");
+ return -1;
+ }
+
+ return po->sim_status;
+}
+
+gboolean tcore_sim_set_status(CoreObject *o, enum tel_sim_status status)
+{
+ struct private_object_data *po = NULL;
+
+ po = tcore_object_ref_object(o);
+ if (!po) {
+ dbg("po access fail");
+ return FALSE;
+ }
+
+ po->sim_status = status;
+
+ return TRUE;
+}
+
+gboolean tcore_sim_get_identification(CoreObject *o)
+{
+ struct private_object_data *po = NULL;
+
+ po = tcore_object_ref_object(o);
+ if (!po) {
+ dbg("po access fail");
+ return -1;
+ }
+
+ return po->b_sim_changed;
+}
+
+gboolean tcore_sim_set_identification(CoreObject *o, gboolean b_changed)
+{
+ struct private_object_data *po = NULL;
+ po = tcore_object_ref_object(o);
+ if (!po) {
+ dbg("po access fail");
+ return FALSE;
+ }
+ po->b_sim_changed = b_changed;
+
+ return TRUE;
+}
+
+enum tel_sim_type tcore_sim_get_type(CoreObject *o)
+{
+ struct private_object_data *po = NULL;
+
+ po = tcore_object_ref_object(o);
+ if (!po) {
+ dbg("po access fail");
+ return -1;
+ }
+
+ return po->type;
+}
+
+gboolean tcore_sim_set_type(CoreObject *o, enum tel_sim_type type)
+{
+ struct private_object_data *po = NULL;
+
+ po = tcore_object_ref_object(o);
+ if (!po) {
+ dbg("po access fail");
+ return FALSE;
+ }
+
+ po->type = type;
+
+ return TRUE;
+}
+
+struct tel_sim_imsi *tcore_sim_get_imsi(CoreObject *o)
+{
+ struct private_object_data *po = NULL;
+
+ po = tcore_object_ref_object(o);
+ if (!po) {
+ dbg("po access fail");
+ return NULL;
+ }
+
+ return g_memdup(&po->imsi, sizeof(struct tel_sim_imsi));
+}
+
+gboolean tcore_sim_set_imsi(CoreObject *o, const struct tel_sim_imsi *imsi)
+{
+ struct private_object_data *po = NULL;
+
+ po = tcore_object_ref_object(o);
+ if (!po) {
+ dbg("po access fail");
+ return FALSE;
+ }
+
+ memcpy(&po->imsi, imsi, sizeof(struct tel_sim_imsi));
+
+ return TRUE;
+}
+
+struct tel_sim_msisdn_list *tcore_sim_get_msisdn_list(CoreObject *o)
+{
+ struct private_object_data *po = NULL;
+
+ po = tcore_object_ref_object(o);
+ if (!po) {
+ dbg("po access fail");
+ return NULL;
+ } else if (!po->msisdn_list) {
+ dbg("po->msisdn_list is NULL");
+ return NULL;
+ }
+
+ return g_memdup(po->msisdn_list, sizeof(struct tel_sim_msisdn_list));
+}
+
+gboolean tcore_sim_set_msisdn_list(CoreObject *o, const struct tel_sim_msisdn_list *msisdn_list)
+{
+ struct private_object_data *po = NULL;
+
+ po = tcore_object_ref_object(o);
+ if (!po) {
+ dbg("po access fail");
+ return FALSE;
+ }
+
+ if (po->msisdn_list) {
+ if (msisdn_list)
+ memcpy(po->msisdn_list, msisdn_list, sizeof(struct tel_sim_msisdn_list));
+ else
+ memset(po->msisdn_list, 0x0, sizeof(struct tel_sim_msisdn_list));
+ } else {
+ if (msisdn_list)
+ po->msisdn_list = g_memdup(msisdn_list, sizeof(struct tel_sim_msisdn_list));
+ else
+ po->msisdn_list = g_malloc0(sizeof(struct tel_sim_msisdn_list));
+ }
+
+ return TRUE;
+}
+
+enum tcore_return tcore_sim_delete_msisdn_list(CoreObject *o)
+{
+ struct private_object_data *po = NULL;
+
+ po = tcore_object_ref_object(o);
+ if (!po) {
+ dbg("po access fail");
+ return TCORE_RETURN_EINVAL;
+ }
+
+ if (po->msisdn_list) {
+ free(po->msisdn_list);
+ po->msisdn_list = NULL;
+ }
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+struct tel_sim_service_table *tcore_sim_get_service_table(CoreObject *o)
+{
+ struct private_object_data *po = NULL;
+
+ po = tcore_object_ref_object(o);
+ if (!po) {
+ dbg("po access fail");
+ return NULL;
+ } else if (!po->svct) {
+ dbg("po->svct is NULL.");
+ return NULL;
+ }
+
+ return g_memdup(po->svct, sizeof(struct tel_sim_service_table));
+}
+
+gboolean tcore_sim_set_service_table(CoreObject *o, const struct tel_sim_service_table *svct)
+{
+ struct private_object_data *po = NULL;
+
+ po = tcore_object_ref_object(o);
+ if (!po) {
+ dbg("po access fail");
+ return FALSE;
+ }
+
+ if (po->svct) {
+ if (svct)
+ memcpy(po->svct, svct, sizeof(struct tel_sim_service_table));
+ else
+ memset(po->svct, 0x0, sizeof(struct tel_sim_service_table));
+ } else {
+ if (svct)
+ po->svct = g_memdup(svct, sizeof(struct tel_sim_service_table));
+ else
+ po->svct = g_malloc0(sizeof(struct tel_sim_service_table));
+ }
+
+ return TRUE;
+}
+
+enum tcore_return tcore_sim_delete_service_table(CoreObject *o)
+{
+ struct private_object_data *po = NULL;
+
+ po = tcore_object_ref_object(o);
+ if (!po) {
+ dbg("po access fail");
+ return TCORE_RETURN_EINVAL;
+ }
+
+ if (po->svct) {
+ free(po->svct);
+ po->svct = NULL;
+ }
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+gboolean tcore_sim_get_cphs_status(CoreObject *o)
+{
+ struct private_object_data *po = NULL;
+
+ po = tcore_object_ref_object(o);
+ if (!po) {
+ dbg("po access fail");
+ return FALSE;
+ }
+
+ return po->b_cphs;
+}
+
+gboolean tcore_sim_set_cphs_status(CoreObject *o, gboolean b_support)
+{
+ struct private_object_data *po = NULL;
+
+ po = tcore_object_ref_object(o);
+ if (!po) {
+ dbg("po access fail");
+ return FALSE;
+ }
+
+ po->b_cphs = b_support;
+
+ return TRUE;
+}
+
+struct tel_sim_cphs_csp *tcore_sim_get_csp(CoreObject *o)
+{
+ struct private_object_data *po = NULL;
+
+ po = tcore_object_ref_object(o);
+ if (!po) {
+ dbg("po access fail");
+ return NULL;
+ } else if (!po->csp) {
+ dbg("po->csp is NULL");
+ return NULL;
+ }
+
+ return g_memdup(po->csp, sizeof(struct tel_sim_cphs_csp));
+}
+
+gboolean tcore_sim_set_csp(CoreObject *o, const struct tel_sim_cphs_csp *csp)
+{
+ struct private_object_data *po = NULL;
+
+ po = tcore_object_ref_object(o);
+ if (!po) {
+ dbg("po access fail");
+ return FALSE;
+ }
+
+ if (po->csp) {
+ if (csp)
+ memcpy(po->csp, csp, sizeof(struct tel_sim_cphs_csp));
+ else
+ memset(po->csp, 0x0, sizeof(struct tel_sim_cphs_csp));
+ } else {
+ if (csp)
+ po->csp = g_memdup(csp, sizeof(struct tel_sim_cphs_csp));
+ else
+ po->csp = g_malloc0(sizeof(struct tel_sim_cphs_csp));
+ }
+
+ return TRUE;
+}
+
+gboolean tcore_sim_delete_csp(CoreObject *o)
+{
+ struct private_object_data *po = NULL;
+
+ po = tcore_object_ref_object(o);
+ if (!po) {
+ dbg("po access fail");
+ return FALSE;
+ }
+
+ if (po->csp) {
+ free(po->csp);
+ po->csp = NULL;
+ }
+
+ return TRUE;
+}
+
+struct tel_sim_ecc_list *tcore_sim_get_ecc_list(CoreObject *o)
+{
+ struct private_object_data *po = NULL;
+
+ po = tcore_object_ref_object(o);
+ if (!po) {
+ dbg("po access fail");
+ return NULL;
+ } else if (!po->ecc_list) {
+ dbg("po->ecc_list is NULL");
+ return NULL;
+ }
+
+ return g_memdup(po->ecc_list, sizeof(struct tel_sim_ecc_list));
+}
+
+gboolean tcore_sim_set_ecc_list(CoreObject *o, const struct tel_sim_ecc_list *ecc_list)
+{
+ struct private_object_data *po = NULL;
+
+ po = tcore_object_ref_object(o);
+ if (!po) {
+ dbg("po access fail");
+ return FALSE;
+ }
+
+ if (po->ecc_list) {
+ if (ecc_list)
+ memcpy(po->ecc_list, ecc_list, sizeof(struct tel_sim_ecc_list));
+ else
+ memset(po->ecc_list, 0x0, sizeof(struct tel_sim_ecc_list));
+ } else {
+ if (ecc_list)
+ po->ecc_list = g_memdup(ecc_list, sizeof(struct tel_sim_ecc_list));
+ else
+ po->ecc_list = g_malloc0(sizeof(struct tel_sim_ecc_list));
+ }
+
+ return TRUE;
+}
+
+enum tcore_return tcore_sim_delete_ecc_list(CoreObject *o)
+{
+ struct private_object_data *po = NULL;
+
+ po = tcore_object_ref_object(o);
+ if (!po) {
+ dbg("po access fail");
+ return TCORE_RETURN_EINVAL;
+ }
+
+ if (po->ecc_list) {
+ free(po->ecc_list);
+ po->ecc_list = NULL;
+ }
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+struct tel_sim_spn *tcore_sim_get_spn(CoreObject *o)
+{
+ struct private_object_data *po = NULL;
+
+ po = tcore_object_ref_object(o);
+ if (!po) {
+ dbg("po access fail");
+ return NULL;
+ } else if (!po->spn) {
+ dbg("po->spn is NULL");
+ return NULL;
+ }
+
+ return g_memdup(po->spn, sizeof(struct tel_sim_spn));
+}
+
+gboolean tcore_sim_set_spn(CoreObject *o, const struct tel_sim_spn *spn)
+{
+ struct private_object_data *po = NULL;
+
+ po = tcore_object_ref_object(o);
+ if (!po) {
+ dbg("po access fail");
+ return FALSE;
+ }
+
+ if (po->spn) {
+ if (spn)
+ memcpy(po->spn, spn, sizeof(struct tel_sim_spn));
+ else
+ memset(po->spn, 0x0, sizeof(struct tel_sim_spn));
+ } else {
+ if (spn)
+ po->spn = g_memdup(spn, sizeof(struct tel_sim_spn));
+ else
+ po->spn = g_malloc0(sizeof(struct tel_sim_spn));
+ }
+
+ return TRUE;
+}
+
+enum tcore_return tcore_sim_delete_spn(CoreObject *o)
+{
+ struct private_object_data *po = NULL;
+
+ po = tcore_object_ref_object(o);
+ if (!po) {
+ dbg("po access fail");
+ return TCORE_RETURN_EINVAL;
+ }
+
+ if (po->spn) {
+ free(po->spn);
+ po->spn = NULL;
+ }
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+struct tel_sim_cphs_netname *tcore_sim_get_cphs_netname(CoreObject *o)
+{
+ struct private_object_data *po = NULL;
+
+ po = tcore_object_ref_object(o);
+ if (!po) {
+ dbg("po access fail");
+ return NULL;
+ } else if (!po->cphs_netname) {
+ dbg("po->cphs_netname is NULL");
+ return NULL;
+ }
+
+ return g_memdup(po->cphs_netname, sizeof(struct tel_sim_cphs_netname));
+}
+
+gboolean tcore_sim_set_cphs_netname(CoreObject *o, const struct tel_sim_cphs_netname *cphs_netname)
+{
+ struct private_object_data *po = NULL;
+
+ po = tcore_object_ref_object(o);
+ if (!po) {
+ dbg("po access fail");
+ return FALSE;
+ }
+
+ if (po->cphs_netname) {
+ if (cphs_netname)
+ memcpy(po->cphs_netname, cphs_netname, sizeof(struct tel_sim_cphs_netname));
+ else
+ memset(po->cphs_netname, 0x0, sizeof(struct tel_sim_cphs_netname));
+ } else {
+ if (cphs_netname)
+ po->cphs_netname = g_memdup(cphs_netname, sizeof(struct tel_sim_cphs_netname));
+ else
+ po->cphs_netname = g_malloc0(sizeof(struct tel_sim_cphs_netname));
+ }
+
+ return TRUE;
+}
+
+enum tcore_return tcore_sim_delete_cphs_netname(CoreObject *o)
+{
+ struct private_object_data *po = NULL;
+
+ po = tcore_object_ref_object(o);
+ if (!po) {
+ dbg("po access fail");
+ return TCORE_RETURN_EINVAL;
+ }
+
+ if (po->cphs_netname) {
+ free(po->cphs_netname);
+ po->cphs_netname = NULL;
+ }
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+struct tel_sim_iccid *tcore_sim_get_iccid(CoreObject *o)
+{
+ struct private_object_data *po = NULL;
+
+ po = tcore_object_ref_object(o);
+ if (!po) {
+ dbg("po access fail");
+ return NULL;
+ } else if (!po->iccid) {
+ dbg("po->iccid is NULL");
+ return NULL;
+ }
+
+ return g_memdup(po->iccid, sizeof(struct tel_sim_iccid));
+}
+
+gboolean tcore_sim_set_iccid(CoreObject *o, const struct tel_sim_iccid *iccid)
+{
+ struct private_object_data *po = NULL;
+
+ po = tcore_object_ref_object(o);
+ if (!po) {
+ dbg("po access fail");
+ return FALSE;
+ }
+
+ if (po->iccid) {
+ if (iccid)
+ memcpy(po->iccid, iccid, sizeof(struct tel_sim_iccid));
+ else
+ memset(po->iccid, 0x0, sizeof(struct tel_sim_iccid));
+ } else {
+ if (iccid)
+ po->iccid = g_memdup(iccid, sizeof(struct tel_sim_iccid));
+ else
+ po->iccid = g_malloc0(sizeof(struct tel_sim_iccid));
+ }
+
+ return TRUE;
+}
+
+enum tcore_return tcore_sim_delete_iccid(CoreObject *o)
+{
+ struct private_object_data *po = NULL;
+
+ po = tcore_object_ref_object(o);
+ if (!po) {
+ dbg("po access fail");
+ return TCORE_RETURN_EINVAL;
+ }
+
+ if (po->iccid) {
+ free(po->iccid);
+ po->iccid = NULL;
+ }
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+gboolean tcore_sim_link_userdata(CoreObject *o, void *userdata)
+{
+ struct private_object_data *po = NULL;
+
+ po = tcore_object_ref_object(o);
+ if (!po) {
+ dbg("po access fail");
+ return FALSE;
+ }
+
+ po->userdata = userdata;
+
+ return TRUE;
+}
+
+void *tcore_sim_ref_userdata(CoreObject *o)
+{
+ struct private_object_data *po = NULL;
+
+ po = tcore_object_ref_object(o);
+ if (!po || !po->userdata) {
+ dbg("po access fail");
+ return NULL;
+ }
+
+ return po->userdata;
+}
+
+static void tcore_sim_initialize_context(CoreObject *o)
+{
+ struct tcore_sim_operations *tmp_ops = NULL;
+ struct private_object_data *po = NULL;
+
+ po = tcore_object_ref_object(o);
+ if (!po) {
+ dbg("po access fail");
+ return;
+ }
+
+ /* set ops to default type when core object is created. */
+ tmp_ops = po->ops[TCORE_OPS_TYPE_CP];
+
+ memset(po, 0x00, sizeof(struct private_object_data));
+ po->ops[TCORE_OPS_TYPE_CP] = tmp_ops;
+ po->sim_status = SIM_STATUS_UNKNOWN;
+}
+
+unsigned char tcore_sim_get_app_list(CoreObject *o)
+{
+ struct private_object_data *po = NULL;
+
+ po = tcore_object_ref_object(o);
+ if (!po) {
+ err("po access fail");
+ return 0;
+ }
+
+ return po->app_list;
+}
+
+gboolean tcore_sim_set_app_list(CoreObject *o, unsigned char app_list)
+{
+ struct private_object_data *po = NULL;
+
+ po = tcore_object_ref_object(o);
+ if (!po) {
+ err("po access fail");
+ return FALSE;
+ }
+
+ po->app_list = app_list;
+
+ return TRUE;
+}
+
+struct tel_sim_ist *tcore_sim_get_isim_service_table(CoreObject *o)
+{
+ struct private_object_data *po = NULL;
+
+ po = tcore_object_ref_object(o);
+ if (!po) {
+ err("po access fail");
+ return NULL;
+ }
+
+ if (!po->ist) {
+ err("po->ist is NULL");
+ return NULL;
+ }
+
+ return g_memdup(po->ist, sizeof(struct tel_sim_ist));
+}
+
+gboolean tcore_sim_set_isim_service_table(CoreObject *o, struct tel_sim_ist *ist)
+{
+ struct private_object_data *po = NULL;
+
+ po = tcore_object_ref_object(o);
+ if (!po) {
+ err("po access fail");
+ return FALSE;
+ }
+
+ if (!ist) {
+ err("ist is NULL");
+ return FALSE;
+ }
+
+ if (po->ist)
+ memcpy(po->ist, ist, sizeof(struct tel_sim_ist));
+ else
+ po->ist = g_memdup(ist, sizeof(struct tel_sim_ist));
+
+ return TRUE;
+}
+
+enum tcore_return tcore_sim_delete_isim_service_table(CoreObject *o)
+{
+ struct private_object_data *po = NULL;
+ po = tcore_object_ref_object(o);
+ if (!po) {
+ err("po access fail");
+ return TCORE_RETURN_EINVAL;
+ }
+
+ if (po->ist) {
+ free(po->ist);
+ po->ist = NULL;
+ }
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+CoreObject *tcore_sim_new(TcorePlugin *p, const char *name,
+ struct tcore_sim_operations *ops, TcoreHal *hal)
+{
+ CoreObject *o = NULL;
+ struct private_object_data *po = NULL;
+
+ if (!p)
+ return NULL;
+
+ o = tcore_object_new(p, name, hal);
+ if (!o)
+ return NULL;
+
+ po = calloc(1, sizeof(struct private_object_data));
+ if (!po) {
+ tcore_object_free(o);
+ return NULL;
+ }
+
+ /* set ops to default type when core object is created. */
+ po->ops[TCORE_OPS_TYPE_CP] = ops;
+
+ tcore_object_set_type(o, CORE_OBJECT_TYPE_SIM);
+ tcore_object_link_object(o, po);
+ tcore_object_set_free_hook(o, _free_hook);
+ tcore_object_set_dispatcher(o, _dispatcher);
+
+ tcore_sim_initialize_context(o);
+
+ return o;
+}
+
+void tcore_sim_free(CoreObject *o)
+{
+ CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_SIM);
+ tcore_object_free(o);
+}
+
+void tcore_sim_set_ops(CoreObject *o, struct tcore_sim_operations *ops, enum tcore_ops_type ops_type)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_SIM);
+ CORE_OBJECT_VALIDATE_OPS_RETURN(ops_type);
+
+ po = (struct private_object_data *)tcore_object_ref_object(o);
+ if (!po) {
+ err("po is NULL");
+ return;
+ }
+
+ po->ops[ops_type] = ops;
+}
--- /dev/null
+/*
+ * libtcore
+ *
+ * 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.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <glib.h>
+
+#include "tcore.h"
+#include "internal/tcore_types.h"
+#include "plugin.h"
+#include "user_request.h"
+#include "co_sms.h"
+
+struct private_object_data {
+ struct tcore_sms_operations *ops[TCORE_OPS_TYPE_MAX];
+ enum telephony_sms_ready_status SmsReadyStatus;
+};
+
+int _tcore_util_sms_encode_smsParameters(const struct telephony_sms_Params *incoming,
+ unsigned char *data, int SMSPRecordLen)
+{
+ struct telephony_sms_Params *smsParams = (struct telephony_sms_Params *)incoming;
+ unsigned int nPIDIndex = 0;
+ unsigned char nOffset = 0;
+
+ if (incoming == NULL || data == NULL)
+ return FALSE;
+
+ memset(data, 0xff, SMSPRecordLen);
+
+ dbg(" Record index = %d", (int) smsParams->recordIndex);
+ dbg(" Alpha ID Len = %d", (int) smsParams->alphaIdLen);
+ dbg(" Record Length : %d", SMSPRecordLen);
+
+ if (SMSPRecordLen/*pSmsParam->RecordLen*/>= nDefaultSMSPWithoutAlphaId)
+ nPIDIndex = SMSPRecordLen /*pSmsParam->RecordLen*/- nDefaultSMSPWithoutAlphaId;
+
+ /* dongil01.park(2008/12/27) - Check Point */
+ memcpy(data, smsParams->szAlphaId, (int)nPIDIndex/*pSmsParam->AlphaIdLen*/);
+
+ dbg(" Alpha ID : %s", smsParams->szAlphaId);
+ dbg(" nPIDIndex = %d", nPIDIndex);
+
+ data[nPIDIndex] = smsParams->paramIndicator;
+
+ dbg(" Param Indicator = %02x", smsParams->paramIndicator);
+
+ if ((smsParams->paramIndicator & SMSPValidDestAddr) == 0x00) {
+ nOffset = nDestAddrOffset;
+
+ data[nPIDIndex + (nOffset)] = smsParams->tpDestAddr.dialNumLen + 1;
+ data[nPIDIndex + (++nOffset)] = ((smsParams->tpDestAddr.typeOfNum << 4) | smsParams->tpDestAddr.numPlanId) | 0x80;
+
+ memcpy(&data[nPIDIndex + (++nOffset)], &smsParams->tpDestAddr.diallingNum, smsParams->tpDestAddr.dialNumLen);
+
+ dbg(" nextIndex = %d", nPIDIndex);
+ }
+
+ if ((smsParams->paramIndicator & SMSPValidSvcAddr) == 0x00) {
+ dbg("TON [%d] / NPI [%d]", smsParams->tpSvcCntrAddr.typeOfNum, smsParams->tpSvcCntrAddr.numPlanId);
+
+ nOffset = nSCAAddrOffset;
+
+ dbg("SCA Length : %d", smsParams->tpSvcCntrAddr.dialNumLen);
+
+ data[nPIDIndex + (nOffset)] = smsParams->tpSvcCntrAddr.dialNumLen + 1;
+ data[nPIDIndex + (++nOffset)] = ((smsParams->tpSvcCntrAddr.typeOfNum << 4) | smsParams->tpSvcCntrAddr.numPlanId) | 0x80;
+
+ memcpy(&data[nPIDIndex + (++nOffset)], &smsParams->tpSvcCntrAddr.diallingNum, smsParams->tpSvcCntrAddr.dialNumLen);
+
+ dbg(" nextIndex = %d", nPIDIndex);
+ }
+
+ if ((smsParams->paramIndicator & SMSPValidPID) == 0x00) {
+ nOffset = nPIDOffset;
+
+ data[nPIDIndex + nOffset] = smsParams->tpProtocolId;
+ dbg(" PID = %02x", smsParams->tpProtocolId);
+ dbg(" nextIndex = %d", nPIDIndex);
+ }
+
+ if ((smsParams->paramIndicator & SMSPValidDCS) == 0x00) {
+ nOffset = nDCSOffset;
+
+ data[nPIDIndex + nOffset] = smsParams->tpDataCodingScheme;
+ dbg(" DCS = %02x", smsParams->tpDataCodingScheme);
+ dbg(" nextIndex = %d", nPIDIndex);
+ }
+
+ if ((smsParams->paramIndicator & SMSPValidVP) == 0x00) {
+ nOffset = nVPOffset;
+
+ data[nPIDIndex + nOffset] = smsParams->tpValidityPeriod;
+ dbg(" VP = %02x", smsParams->tpValidityPeriod);
+ dbg(" nextIndex = %d", nPIDIndex);
+ }
+
+ return TRUE;
+
+}
+
+void tcore_util_sms_semioctet_to_octect(int *nScLength)
+{
+ if (*nScLength % 2)
+ *nScLength = (*nScLength / 2) + 1;
+ else
+ *nScLength = *nScLength / 2;
+}
+
+int tcore_util_sms_decode_smsParameters(uint8_t *incoming, uint32_t 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");
+ }
+
+ /* dongil01.park - start parse from here. */
+ params->paramIndicator = incoming[alpha_id_len];
+
+ dbg(" Param Indicator = %02x", params->paramIndicator);
+
+ /* dongil01.park(2008/12/26) - DestAddr */
+ if ((params->paramIndicator & SMSPValidDestAddr) == 0) {
+ nOffset = nDestAddrOffset;
+
+ if (0x00 == incoming[alpha_id_len + nOffset] || 0xff == incoming[alpha_id_len + nOffset]) {
+ params->tpDestAddr.dialNumLen = 0;
+
+ dbg("DestAddr Length is 0");
+ } else {
+ if (0 < (int)incoming[alpha_id_len + nOffset]) {
+ params->tpDestAddr.dialNumLen = (int)(incoming[alpha_id_len + nOffset] - 1);
+
+ if (params->tpDestAddr.dialNumLen > SMS_SMSP_ADDRESS_LEN)
+ params->tpDestAddr.dialNumLen = SMS_SMSP_ADDRESS_LEN;
+ } else {
+ params->tpDestAddr.dialNumLen = 0;
+ }
+
+ params->tpDestAddr.numPlanId = incoming[alpha_id_len + (++nOffset)] & 0x0f ;
+ params->tpDestAddr.typeOfNum = (incoming[alpha_id_len + nOffset] & 0x70)>>4 ;
+
+ memcpy(params->tpDestAddr.diallingNum, &incoming[alpha_id_len + (++nOffset)], (params->tpDestAddr.dialNumLen)) ;
+
+ dbg("Dest TON is %d", params->tpDestAddr.typeOfNum);
+ dbg("Dest NPI is %d", params->tpDestAddr.numPlanId);
+ dbg("Dest Length = %d", params->tpDestAddr.dialNumLen);
+ dbg("Dest Addr = %s", params->tpDestAddr.diallingNum);
+ }
+ }
+
+ /* dongil01.park(2008/12/26) - SvcAddr */
+ if ((params->paramIndicator & SMSPValidSvcAddr) == 0) {
+ nOffset = nSCAAddrOffset;
+
+ if (0x00 == (int)incoming[alpha_id_len + nOffset] || 0xff == (int)incoming[alpha_id_len + nOffset]) {
+ params->tpSvcCntrAddr.dialNumLen = 0;
+
+ dbg(" SCAddr Length is 0");
+ } else {
+ if (0 < (int)incoming[alpha_id_len + nOffset]) {
+ params->tpSvcCntrAddr.dialNumLen = (int)(incoming[alpha_id_len + nOffset] - 1);
+
+ if (params->tpSvcCntrAddr.dialNumLen > SMS_SMSP_ADDRESS_LEN)
+ params->tpSvcCntrAddr.dialNumLen = SMS_SMSP_ADDRESS_LEN;
+
+ params->tpSvcCntrAddr.numPlanId = incoming[alpha_id_len + (++nOffset)] & 0x0f ;
+ params->tpSvcCntrAddr.typeOfNum = (incoming[alpha_id_len + nOffset] & 0x70) >> 4;
+
+ memcpy(params->tpSvcCntrAddr.diallingNum, &incoming[alpha_id_len + (++nOffset)], (params->tpSvcCntrAddr.dialNumLen));
+
+ dbg("SCAddr Length = %d ", params->tpSvcCntrAddr.dialNumLen);
+ dbg("SCAddr TON is %d", params->tpSvcCntrAddr.typeOfNum);
+ dbg("SCAddr NPI is %d", params->tpSvcCntrAddr.numPlanId);
+
+ for (i = 0 ; i < (int)params->tpSvcCntrAddr.dialNumLen ; i++)
+ dbg("SCAddr = %d [%02x]", i, params->tpSvcCntrAddr.diallingNum[i]);
+ } else
+ params->tpSvcCntrAddr.dialNumLen = 0;
+ }
+ } else if ((0x00 < (int)incoming[alpha_id_len + nSCAAddrOffset]
+ && (int)incoming[alpha_id_len + nSCAAddrOffset] <= 12)
+ || 0xff != (int)incoming[alpha_id_len + nSCAAddrOffset]) {
+ nOffset = nSCAAddrOffset;
+
+ if (0x00 == (int)incoming[alpha_id_len + nOffset] || 0xff == (int)incoming[alpha_id_len + nOffset]) {
+ params->tpSvcCntrAddr.dialNumLen = 0;
+ dbg("SCAddr Length is 0");
+ } else {
+
+ if (0 < (int)incoming[alpha_id_len + nOffset]) {
+ params->tpSvcCntrAddr.dialNumLen = (int)(incoming[alpha_id_len + nOffset] - 1);
+
+ params->tpSvcCntrAddr.dialNumLen = incoming[alpha_id_len + nOffset] - 1;
+
+ if (params->tpSvcCntrAddr.dialNumLen > SMS_SMSP_ADDRESS_LEN)
+ params->tpSvcCntrAddr.dialNumLen = SMS_SMSP_ADDRESS_LEN;
+
+ params->tpSvcCntrAddr.numPlanId = incoming[alpha_id_len + (++nOffset)] & 0x0f ;
+ params->tpSvcCntrAddr.typeOfNum = (incoming[alpha_id_len + nOffset] & 0x70) >> 4;
+
+ memcpy(params->tpSvcCntrAddr.diallingNum, &incoming[alpha_id_len + (++nOffset)],
+ (params->tpSvcCntrAddr.dialNumLen)) ;
+
+ dbg("SCAddr Length = %d ", params->tpSvcCntrAddr.dialNumLen);
+ dbg("SCAddr TON is %d", params->tpSvcCntrAddr.typeOfNum);
+ dbg("SCAddr NPI is %d", params->tpSvcCntrAddr.numPlanId);
+
+ for (i = 0 ; i < (int)params->tpSvcCntrAddr.dialNumLen ; i++)
+ dbg("SCAddr = %d [%02x]", i, params->tpSvcCntrAddr.diallingNum[i]);
+ } else
+ params->tpSvcCntrAddr.dialNumLen = 0;
+ }
+
+ }
+
+ if ((params->paramIndicator & SMSPValidPID) == 0
+ && (alpha_id_len + nPIDOffset) < SMS_MAX_EFSMSP_RECORD_LENGTH)
+ params->tpProtocolId = incoming[alpha_id_len + nPIDOffset];
+
+ if ((params->paramIndicator & SMSPValidDCS) == 0
+ && (alpha_id_len + nDCSOffset) < SMS_MAX_EFSMSP_RECORD_LENGTH)
+ params->tpDataCodingScheme = incoming[alpha_id_len + nDCSOffset];
+
+ if ((params->paramIndicator & SMSPValidVP) == 0
+ && (alpha_id_len + nVPOffset) < SMS_MAX_EFSMSP_RECORD_LENGTH)
+ params->tpValidityPeriod = incoming[alpha_id_len + nVPOffset];
+
+ dbg(" Alpha Id(Len) = %d", (int)params->alphaIdLen);
+
+ for (i = 0; i < (int)params->alphaIdLen ; i++)
+ dbg(" Alpha Id = [%d] [%c]", i, params->szAlphaId[i]);
+
+ dbg(" PID = %d", params->tpProtocolId);
+ dbg(" DCS = %d", params->tpDataCodingScheme);
+ dbg(" VP = %d", params->tpValidityPeriod);
+
+ return TRUE;
+}
+
+
+static TReturn _dispatcher(CoreObject *o, UserRequest *ur, enum tcore_ops_type ops_type)
+{
+ enum tcore_request_command command;
+ struct private_object_data *po = tcore_object_ref_object(o);
+ struct tcore_sms_operations *ops = NULL;
+ TReturn rtn = TCORE_RETURN_SUCCESS;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_SMS, TCORE_RETURN_EINVAL);
+ CORE_OBJECT_VALIDATE_OPS_RETURN_VAL(ops_type, TCORE_RETURN_EINVAL);
+
+ tcore_check_null_ret_err("po", po, TCORE_RETURN_EINVAL);
+ tcore_check_null_ret_err("ur", ur, TCORE_RETURN_EINVAL);
+
+ if (po->SmsReadyStatus == SMS_READY_STATUS_NONE) {
+ dbg("[tcore_SMS] DEVICE_NOT_READY");
+ return TCORE_RETURN_ENOSYS; /* TAPI_API_NETTEXT_DEVICE_NOT_READY */
+ }
+
+ ops = po->ops[ops_type];
+ tcore_check_null_ret_err("ops", ops, TCORE_RETURN_FAILURE);
+
+ command = tcore_user_request_get_command(ur);
+ switch (command) {
+ case TREQ_SMS_SEND_UMTS_MSG:
+ tcore_check_null_ret_err("ops->send_umts_msg",
+ ops->send_umts_msg, TCORE_RETURN_ENOSYS);
+
+ rtn = ops->send_umts_msg(o, ur);
+ break;
+
+ case TREQ_SMS_READ_MSG:
+ tcore_check_null_ret_err("ops->connect",
+ ops->read_msg, TCORE_RETURN_ENOSYS);
+
+ rtn = ops->read_msg(o, ur);
+ break;
+
+ case TREQ_SMS_SAVE_MSG:
+ tcore_check_null_ret_err("ops->save_msg",
+ ops->save_msg, TCORE_RETURN_ENOSYS);
+
+ rtn = ops->save_msg(o, ur);
+ break;
+
+ case TREQ_SMS_DELETE_MSG:
+ tcore_check_null_ret_err("ops->delete_msg",
+ ops->delete_msg, TCORE_RETURN_ENOSYS);
+
+ rtn = ops->delete_msg(o, ur);
+ break;
+
+ case TREQ_SMS_GET_COUNT:
+ tcore_check_null_ret_err("ops->get_storedMsgCnt",
+ ops->get_storedMsgCnt, TCORE_RETURN_ENOSYS);
+
+ rtn = ops->get_storedMsgCnt(o, ur);
+ break;
+
+ case TREQ_SMS_GET_SCA:
+ tcore_check_null_ret_err("ops->get_sca",
+ ops->get_sca, TCORE_RETURN_ENOSYS);
+
+ rtn = ops->get_sca(o, ur);
+ break;
+
+ case TREQ_SMS_SET_SCA:
+ tcore_check_null_ret_err("ops->set_sca",
+ ops->set_sca, TCORE_RETURN_ENOSYS);
+
+ rtn = ops->set_sca(o, ur);
+ break;
+
+ case TREQ_SMS_GET_CB_CONFIG:
+ tcore_check_null_ret_err("ops->get_cb_config",
+ ops->get_cb_config, TCORE_RETURN_ENOSYS);
+
+ rtn = ops->get_cb_config(o, ur);
+ break;
+
+ case TREQ_SMS_SET_CB_CONFIG:
+ tcore_check_null_ret_err("ops->set_cb_config",
+ ops->set_cb_config, TCORE_RETURN_ENOSYS);
+
+ rtn = ops->set_cb_config(o, ur);
+ break;
+
+ case TREQ_SMS_SET_MEM_STATUS:
+ tcore_check_null_ret_err("ops->set_mem_status",
+ ops->set_mem_status, TCORE_RETURN_ENOSYS);
+
+ rtn = ops->set_mem_status(o, ur);
+ break;
+
+ case TREQ_SMS_GET_PREF_BEARER:
+ tcore_check_null_ret_err("ops->get_pref_brearer",
+ ops->get_pref_brearer, TCORE_RETURN_ENOSYS);
+
+ rtn = ops->get_pref_brearer(o, ur);
+ break;
+
+ case TREQ_SMS_SET_PREF_BEARER:
+ tcore_check_null_ret_err("ops->set_pref_brearer",
+ ops->set_pref_brearer, TCORE_RETURN_ENOSYS);
+
+ rtn = ops->set_pref_brearer(o, ur);
+ break;
+
+ case TREQ_SMS_SET_DELIVERY_REPORT:
+ tcore_check_null_ret_err("ops->set_delivery_report",
+ ops->set_delivery_report, TCORE_RETURN_ENOSYS);
+
+ rtn = ops->set_delivery_report(o, ur);
+ break;
+
+ case TREQ_SMS_SET_MSG_STATUS:
+ tcore_check_null_ret_err("ops->set_msg_status",
+ ops->set_msg_status, TCORE_RETURN_ENOSYS);
+
+ rtn = ops->set_msg_status(o, ur);
+ break;
+
+ case TREQ_SMS_GET_PARAMS:
+ tcore_check_null_ret_err("ops->get_sms_params",
+ ops->get_sms_params, TCORE_RETURN_ENOSYS);
+
+ rtn = ops->get_sms_params(o, ur);
+ break;
+
+ case TREQ_SMS_SET_PARAMS:
+ tcore_check_null_ret_err("ops->set_sms_params",
+ ops->set_sms_params, TCORE_RETURN_ENOSYS);
+
+ rtn = ops->set_sms_params(o, ur);
+ break;
+
+ case TREQ_SMS_GET_PARAMCNT:
+ tcore_check_null_ret_err("ops->get_paramcnt",
+ ops->get_paramcnt, TCORE_RETURN_ENOSYS);
+
+ rtn = ops->get_paramcnt(o, ur);
+ break;
+
+ case TREQ_SMS_SEND_CDMA_MSG:
+ tcore_check_null_ret_err("ops->send_cdma_msg",
+ ops->send_cdma_msg, TCORE_RETURN_ENOSYS);
+
+ rtn = ops->send_cdma_msg(o, ur);
+ break;
+
+ default:
+ break;
+ }
+
+ dbg("[tcore_SMS] result = [0x%x], command = [0x%x]", rtn, command);
+
+ return rtn;
+}
+
+static void _free_hook(CoreObject *o)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_SMS);
+
+ po = tcore_object_ref_object(o);
+ if (po) {
+ free(po);
+ tcore_object_link_object(o, NULL);
+ }
+}
+
+enum telephony_sms_ready_status tcore_sms_get_ready_status(CoreObject *o)
+{
+ struct private_object_data *po = NULL;
+ po = tcore_object_ref_object(o);
+ if (!po) {
+ dbg("po access fail");
+ return SMS_READY_STATUS_NONE;
+ }
+
+ return po->SmsReadyStatus;
+}
+
+gboolean tcore_sms_set_ready_status(CoreObject *o, enum telephony_sms_ready_status status)
+{
+ struct private_object_data *po = NULL;
+ po = tcore_object_ref_object(o);
+ if (!po) {
+ dbg("po access fail");
+ return FALSE;
+ }
+
+ po->SmsReadyStatus = status;
+
+ return TRUE;
+}
+
+CoreObject *tcore_sms_new(TcorePlugin *p, const char *name,
+ struct tcore_sms_operations *ops, TcoreHal *hal)
+{
+ CoreObject *o = NULL;
+ struct private_object_data *po = NULL;
+
+ if (!p)
+ return NULL;
+
+ o = tcore_object_new(p, name, hal);
+ if (!o)
+ return NULL;
+
+ po = calloc(1, sizeof(struct private_object_data));
+ if (!po) {
+ tcore_object_free(o);
+ return NULL;
+ }
+
+ /* set ops to default type when core object is created. */
+ po->ops[TCORE_OPS_TYPE_CP] = ops;
+
+ tcore_object_set_type(o, CORE_OBJECT_TYPE_SMS);
+ tcore_object_link_object(o, po);
+ tcore_object_set_free_hook(o, _free_hook);
+ tcore_object_set_dispatcher(o, _dispatcher);
+
+ return o;
+}
+
+void tcore_sms_free(CoreObject *o)
+{
+ CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_SMS);
+ tcore_object_free(o);
+}
+
+void tcore_sms_set_ops(CoreObject *o, struct tcore_sms_operations *ops, enum tcore_ops_type ops_type)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_SMS);
+ CORE_OBJECT_VALIDATE_OPS_RETURN(ops_type);
+
+ po = (struct private_object_data *)tcore_object_ref_object(o);
+ if (!po) {
+ err("po is NULL");
+ return;
+ }
+
+ po->ops[ops_type] = ops;
+}
--- /dev/null
+/*
+ * libtcore
+ *
+ * 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.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <glib.h>
+
+#include "tcore.h"
+#include "internal/tcore_types.h"
+#include "plugin.h"
+#include "queue.h"
+#include "user_request.h"
+#include "co_ss.h"
+
+struct ussd_session {
+ gboolean session;
+ enum tcore_ss_ussd_type type;
+ void *data;
+ int data_len;
+};
+
+struct ss_routing_policy {
+ enum tcore_ss_routing_policy ss_routing_policy;
+ enum tcore_ussd_routing_policy ussd_routing_policy;
+};
+
+struct private_object_data {
+ struct tcore_ss_operations *ops[TCORE_OPS_TYPE_MAX];
+
+ struct ussd_session ussd_s;
+ struct ss_routing_policy routing_policy;
+};
+
+static TReturn _dispatcher(CoreObject *o, UserRequest *ur, enum tcore_ops_type ops_type)
+{
+ enum tcore_request_command command;
+ struct private_object_data *po = tcore_object_ref_object(o);
+ struct tcore_ss_operations *ops = NULL;
+ TReturn ret = 0;
+
+ CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_SS, TCORE_RETURN_EINVAL);
+ CORE_OBJECT_VALIDATE_OPS_RETURN_VAL(ops_type, TCORE_RETURN_EINVAL);
+
+ tcore_check_null_ret_err("po", po, TCORE_RETURN_EINVAL);
+ tcore_check_null_ret_err("ur", ur, TCORE_RETURN_EINVAL);
+
+ ops = po->ops[ops_type];
+ tcore_check_null_ret_err("ops", ops, TCORE_RETURN_FAILURE);
+
+ command = tcore_user_request_get_command(ur);
+ switch (command) {
+ case TREQ_SS_BARRING_ACTIVATE:
+ tcore_check_null_ret_err("ops->barring_activate",
+ ops->barring_activate, TCORE_RETURN_ENOSYS);
+
+ ret = ops->barring_activate(o, ur);
+ break;
+
+ case TREQ_SS_BARRING_DEACTIVATE:
+ tcore_check_null_ret_err("ops->barring_deactivate",
+ ops->barring_deactivate, TCORE_RETURN_ENOSYS);
+
+ ret = ops->barring_deactivate(o, ur);
+ break;
+
+ case TREQ_SS_BARRING_CHANGE_PASSWORD:
+ tcore_check_null_ret_err("ops->barring_change_password",
+ ops->barring_change_password, TCORE_RETURN_ENOSYS);
+
+ ret = ops->barring_change_password(o, ur);
+ break;
+
+ case TREQ_SS_BARRING_GET_STATUS:
+ tcore_check_null_ret_err("ops->barring_get_status",
+ ops->barring_get_status, TCORE_RETURN_ENOSYS);
+
+ ret = ops->barring_get_status(o, ur);
+ break;
+
+ case TREQ_SS_FORWARDING_ACTIVATE:
+ tcore_check_null_ret_err("ops->forwarding_activate",
+ ops->forwarding_activate, TCORE_RETURN_ENOSYS);
+
+ ret = ops->forwarding_activate(o, ur);
+ break;
+
+ case TREQ_SS_FORWARDING_DEACTIVATE:
+ tcore_check_null_ret_err("ops->forwarding_deactivate",
+ ops->forwarding_deactivate, TCORE_RETURN_ENOSYS);
+
+ ret = ops->forwarding_deactivate(o, ur);
+ break;
+
+ case TREQ_SS_FORWARDING_REGISTER:
+ tcore_check_null_ret_err("ops->forwarding_register",
+ ops->forwarding_register, TCORE_RETURN_ENOSYS);
+
+ ret = ops->forwarding_register(o, ur);
+ break;
+
+ case TREQ_SS_FORWARDING_DEREGISTER:
+ tcore_check_null_ret_err("ops->forwarding_deregister",
+ ops->forwarding_deregister, TCORE_RETURN_ENOSYS);
+
+ ret = ops->forwarding_deregister(o, ur);
+ break;
+
+ case TREQ_SS_FORWARDING_GET_STATUS:
+ tcore_check_null_ret_err("ops->forwarding_get_status",
+ ops->forwarding_get_status, TCORE_RETURN_ENOSYS);
+
+ ret = ops->forwarding_get_status(o, ur);
+ break;
+
+ case TREQ_SS_WAITING_ACTIVATE:
+ tcore_check_null_ret_err("ops->waiting_activate",
+ ops->waiting_activate, TCORE_RETURN_ENOSYS);
+
+ ret = ops->waiting_activate(o, ur);
+ break;
+
+ case TREQ_SS_WAITING_DEACTIVATE:
+ tcore_check_null_ret_err("ops->waiting_deactivate",
+ ops->waiting_deactivate, TCORE_RETURN_ENOSYS);
+
+ ret = ops->waiting_deactivate(o, ur);
+ break;
+
+ case TREQ_SS_WAITING_GET_STATUS:
+ tcore_check_null_ret_err("ops->waiting_get_status",
+ ops->waiting_get_status, TCORE_RETURN_ENOSYS);
+
+ ret = ops->waiting_get_status(o, ur);
+ break;
+
+ case TREQ_SS_CLI_ACTIVATE:
+ tcore_check_null_ret_err("ops->cli_activate",
+ ops->cli_activate, TCORE_RETURN_ENOSYS);
+
+ ret = ops->cli_activate(o, ur);
+ break;
+
+ case TREQ_SS_CLI_DEACTIVATE:
+ tcore_check_null_ret_err("ops->cli_deactivate",
+ ops->cli_deactivate, TCORE_RETURN_ENOSYS);
+
+ ret = ops->cli_deactivate(o, ur);
+ break;
+
+ case TREQ_SS_CLI_SET_STATUS:
+ tcore_check_null_ret_err("ops->cli_set_status",
+ ops->cli_set_status, TCORE_RETURN_ENOSYS);
+
+ ret = ops->cli_set_status(o, ur);
+ break;
+
+ case TREQ_SS_CLI_GET_STATUS:
+ tcore_check_null_ret_err("ops->cli_get_status",
+ ops->cli_get_status, TCORE_RETURN_ENOSYS);
+
+ ret = ops->cli_get_status(o, ur);
+ break;
+
+ case TREQ_SS_SEND_USSD:
+ tcore_check_null_ret_err("ops->send_ussd",
+ ops->send_ussd, TCORE_RETURN_ENOSYS);
+
+ ret = ops->send_ussd(o, ur);
+ break;
+
+ case TREQ_SS_SET_AOC:
+ tcore_check_null_ret_err("ops->set_aoc",
+ ops->set_aoc, TCORE_RETURN_ENOSYS);
+
+ ret = ops->set_aoc(o, ur);
+ break;
+
+ case TREQ_SS_GET_AOC:
+ tcore_check_null_ret_err("ops->get_aoc",
+ ops->get_aoc, TCORE_RETURN_ENOSYS);
+
+ ret = ops->get_aoc(o, ur);
+ break;
+
+ default:
+ break;
+ }
+
+ return ret;
+}
+
+static void _free_hook(CoreObject *o)
+{
+ struct private_object_data *po = NULL;
+
+ po = tcore_object_ref_object(o);
+ if (!po)
+ return;
+
+ free(po);
+ tcore_object_link_object(o, NULL);
+}
+
+static void _ussd_session_init(struct ussd_session *ussd_s)
+{
+ ussd_s->session = FALSE;
+ ussd_s->type = 0;
+ ussd_s->data = 0;
+ ussd_s->data_len = 0;
+}
+
+struct ussd_session *tcore_ss_ussd_create_session(CoreObject *o,
+ enum tcore_ss_ussd_type type, void *data, int data_len)
+{
+ struct private_object_data *po = NULL;
+
+ po = tcore_object_ref_object(o);
+ if (!po)
+ return 0;
+
+ if (type < TCORE_SS_USSD_TYPE_USER_INITIATED
+ || type > TCORE_SS_USSD_TYPE_NETWORK_INITIATED) {
+ dbg("[ error ] wrong ussd type : (0x%x)", type);
+ return 0;
+ }
+
+ if (!po->ussd_s.session) {
+ po->ussd_s.session = TRUE;
+ po->ussd_s.type = type;
+ po->ussd_s.data = data;
+
+ if (data_len < 0)
+ po->ussd_s.data_len = 0;
+ else
+ po->ussd_s.data_len = data_len;
+
+ return &po->ussd_s;
+
+ } else {
+ dbg("[ error ] already exist ussd session, type : (0x%x)", po->ussd_s.type);
+ return 0;
+ }
+}
+
+void tcore_ss_ussd_destroy_session(struct ussd_session *ussd_s)
+{
+ if (!ussd_s || !ussd_s->session)
+ return;
+
+ _ussd_session_init(ussd_s);
+}
+
+struct ussd_session *tcore_ss_ussd_get_session(CoreObject *o)
+{
+ struct private_object_data *po = NULL;
+
+ po = tcore_object_ref_object(o);
+ if (!po)
+ return 0;
+
+ if (!po->ussd_s.session)
+ return 0;
+ else
+ return &po->ussd_s;
+}
+
+enum tcore_ss_ussd_type tcore_ss_ussd_get_session_type(struct ussd_session *ussd_s)
+{
+ if (!ussd_s || !ussd_s->session) {
+ dbg("[ error ] there is no session");
+ return 0;
+ }
+
+ return ussd_s->type;
+}
+
+void tcore_ss_ussd_set_session_type(struct ussd_session *ussd_s,
+ enum tcore_ss_ussd_type type)
+{
+ if (!ussd_s || !ussd_s->session) {
+ dbg("[ error ] there is no session");
+ return;
+ }
+
+ ussd_s->type = type;
+}
+
+int tcore_ss_ussd_get_session_data(struct ussd_session *ussd_s, void **data)
+{
+ if (!ussd_s || !ussd_s->session) {
+ dbg("[ error ] there is no session");
+ return -1;
+ }
+
+ *data = ussd_s->data;
+ return ussd_s->data_len;
+}
+
+void tcore_ss_ussd_set_session_data(struct ussd_session *ussd_s, void *data, int data_len)
+{
+ if (!ussd_s || !ussd_s->session) {
+ dbg("[ error ] there is no session");
+ return;
+ }
+
+ ussd_s->data = data;
+ ussd_s->data_len = data_len;
+}
+
+void tcore_ss_set_ussd_routing(CoreObject *o, enum tcore_ussd_routing_policy ussd_routing_policy)
+{
+ struct private_object_data *po = NULL;
+
+ po = tcore_object_ref_object(o);
+ if (!po)
+ return;
+
+ po->routing_policy.ussd_routing_policy = ussd_routing_policy;
+}
+
+enum tcore_ussd_routing_policy tcore_ss_get_ussd_routing(CoreObject *o)
+{
+ struct private_object_data *po = NULL;
+
+ po = tcore_object_ref_object(o);
+ if (!po)
+ return TCORE_SS_USSD_ROUTING_POLICY_CS_ALWAYS; /* 'default' to CS */
+
+ return po->routing_policy.ussd_routing_policy;
+}
+
+void tcore_ss_set_ss_routing(CoreObject *o, enum tcore_ss_routing_policy ss_routing_policy)
+{
+ struct private_object_data *po = NULL;
+
+ po = tcore_object_ref_object(o);
+ if (!po)
+ return;
+
+ po->routing_policy.ss_routing_policy = ss_routing_policy;
+}
+
+enum tcore_ss_routing_policy tcore_ss_get_ss_routing(CoreObject *o)
+{
+ struct private_object_data *po = NULL;
+
+ po = tcore_object_ref_object(o);
+ if (!po)
+ return TCORE_SS_ROUTING_POLICY_CS_ALWAYS; /* 'default' to CS */
+
+ return po->routing_policy.ss_routing_policy;
+}
+
+CoreObject *tcore_ss_new(TcorePlugin *p, const char *name,
+ struct tcore_ss_operations *ops, TcoreHal *hal)
+{
+ CoreObject *o = NULL;
+ struct private_object_data *po = NULL;
+
+ if (!p)
+ return NULL;
+
+ o = tcore_object_new(p, name, hal);
+ if (!o)
+ return NULL;
+
+ po = calloc(1, sizeof(struct private_object_data));
+ if (!po) {
+ tcore_object_free(o);
+ return NULL;
+ }
+
+ /* set ops to default type when core object is created. */
+ po->ops[TCORE_OPS_TYPE_CP] = ops;
+ po->routing_policy.ss_routing_policy = TCORE_SS_ROUTING_POLICY_CS_ALWAYS; /* 'default' to CS */
+ po->routing_policy.ussd_routing_policy = TCORE_SS_USSD_ROUTING_POLICY_CS_ALWAYS; /* 'default' to CS */
+
+ _ussd_session_init(&po->ussd_s);
+
+ tcore_object_set_type(o, CORE_OBJECT_TYPE_SS);
+ tcore_object_link_object(o, po);
+ tcore_object_set_free_hook(o, _free_hook);
+ tcore_object_set_dispatcher(o, _dispatcher);
+
+ return o;
+}
+
+void tcore_ss_free(CoreObject *o)
+{
+ CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_SS);
+
+ tcore_object_free(o);
+}
+
+void tcore_ss_set_ops(CoreObject *o, struct tcore_ss_operations *ops, enum tcore_ops_type ops_type)
+{
+ struct private_object_data *po = NULL;
+
+ CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_SS);
+ CORE_OBJECT_VALIDATE_OPS_RETURN(ops_type);
+
+ po = (struct private_object_data *)tcore_object_ref_object(o);
+ if (!po) {
+ err("po is NULL");
+ return;
+ }
+
+ po->ops[ops_type] = ops;
+}
+
--- /dev/null
+/*
+ * libtcore
+ *
+ * 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.
+ */
+
+#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 "co_call.h"
+#include "co_modem.h"
+#include "co_ps.h"
+#include "co_network.h"
+#include "co_ss.h"
+#include "co_sim.h"
+#include "co_sat.h"
+#include "co_sap.h"
+#include "co_sms.h"
+#include "co_phonebook.h"
+#include "co_gps.h"
+
+struct callback_type {
+ CoreObject *co;
+ char *event;
+ CoreObjectCallback callback;
+ void *user_data;
+};
+
+struct tcore_object_type {
+ unsigned int type;
+ char *name;
+
+ TcorePlugin *parent_plugin;
+
+ void *object;
+ void *user_data;
+
+ CoreObjectFreeHook free_hook;
+ CoreObjectDispatcher dispatcher;
+ GSList *callbacks;
+ GHashTable *property;
+
+ TcoreHal *hal;
+};
+
+
+/* Mapping Table */
+struct tcore_object_mapping_tbl {
+ TcoreHal *hal;
+ GSList *object_type;
+};
+
+static void _util_print_mapping_tbl_entry(object_mapping_table_t *tbl_entry)
+{
+ GSList *co_list;
+
+ msg("------> Table Entry - HAL: [0x%x]", tbl_entry->hal);
+
+ co_list = tbl_entry->object_type;
+ if (co_list == NULL) {
+ err("No Core Objects defined for this Mapping Table Entry");
+ return;
+ }
+
+ /* Search all the Table entries with matching 'type' */
+ for (; co_list ; co_list = co_list->next) {
+ if (co_list->data == NULL)
+ continue;
+
+ msg(" Core Object type: [0x%x]", co_list->data);
+ }
+}
+
+static void _free_tbl_entry(gpointer data)
+{
+ object_mapping_table_t *tbl_entry;
+
+ if (data == NULL)
+ return;
+
+ tbl_entry = data;
+
+ dbg("Removing Mapping Table Entry - HAL: [0x%x]", tbl_entry->hal);
+ _util_print_mapping_tbl_entry(tbl_entry);
+
+ /* Free Core Object types list */
+ g_slist_free(tbl_entry->object_type);
+
+ /* Free Table entry */
+ g_free(tbl_entry);
+}
+static CoreObject *_object_new(TcorePlugin *plugin, unsigned int type)
+{
+ CoreObject *co;
+
+ co = g_try_malloc0(sizeof(struct tcore_object_type));
+ if (!co)
+ return NULL;
+
+ co->parent_plugin = plugin;
+
+ co->type = type;
+ co->property = g_hash_table_new_full(g_str_hash, g_str_equal, free, free);
+
+ return co;
+}
+
+static gboolean _on_at_event(TcoreAT *at, const GSList *lines, void *user_data)
+{
+ gboolean ret;
+
+ struct callback_type *cb = user_data;
+
+ ret = cb->callback(cb->co, lines, cb->user_data);
+ if (ret == FALSE)
+ err("Callback processing failed!");
+
+ return ret;
+}
+
+static void _remove_at_callback(TcoreAT *at, struct callback_type *cb)
+{
+ tcore_at_remove_notification_full(at, cb->event, _on_at_event, cb);
+}
+
+static object_mapping_table_t *_object_search_mapping_tbl_entry(GSList *mapping_tbl_list,
+ TcoreHal *hal)
+{
+ GSList *list;
+ object_mapping_table_t *tbl_entry = NULL;
+
+ for (list = mapping_tbl_list; list ; list = list->next) {
+ tbl_entry = list->data;
+ if (tbl_entry == NULL)
+ continue;
+
+ /* Search for Table entry with matching 'hal' */
+ if (tbl_entry->hal == hal)
+ return tbl_entry;
+ }
+
+ return NULL;
+}
+
+static object_mapping_table_t *_object_search_mapping_tbl_entry_by_type(
+ GSList *mapping_tbl_list, unsigned int type)
+{
+ GSList *list;
+ GSList *co_list;
+ object_mapping_table_t *tbl_entry = NULL;
+
+ for (list = mapping_tbl_list; list ; list = list->next) {
+ tbl_entry = list->data;
+ if (tbl_entry == NULL)
+ continue;
+
+ /* Search all the Table entries with matching 'type' */
+ for (co_list = tbl_entry->object_type ; co_list ; co_list = co_list->next) {
+ if (co_list->data == NULL)
+ continue;
+
+ if (type == GPOINTER_TO_UINT(co_list->data))
+ return tbl_entry;
+ }
+ }
+
+ return tbl_entry;
+}
+
+static CoreObject *_create_core_object_by_type(guint type,
+ TcorePlugin *plugin, TcoreHal *hal)
+{
+ CoreObject *co = NULL;
+
+ switch (type) {
+ case CORE_OBJECT_TYPE_MODEM:
+ /* Create Core Object */
+ co = tcore_modem_new(plugin, "modem", NULL, hal);
+ break;
+
+ case CORE_OBJECT_TYPE_CALL:
+ /* Create Core Object */
+ co = tcore_call_new(plugin, "call", NULL, hal);
+ break;
+
+ case CORE_OBJECT_TYPE_SS:
+ /* Create Core Object */
+ co = tcore_ss_new(plugin, "ss", NULL, hal);
+ break;
+
+ case CORE_OBJECT_TYPE_NETWORK:
+ /* Create Core Object */
+ co = tcore_network_new(plugin, "network", NULL, hal);
+ break;
+
+ case CORE_OBJECT_TYPE_PS:
+ /* Create Core Object */
+ co = tcore_ps_new(plugin, "ps", NULL, hal);
+ break;
+
+ case CORE_OBJECT_TYPE_SIM:
+ /* Create Core Object */
+ co = tcore_sim_new(plugin, "sim", NULL, hal);
+ break;
+
+ case CORE_OBJECT_TYPE_SAT:
+ /* Create Core Object */
+ co = tcore_sat_new(plugin, "sat", NULL, hal);
+ break;
+
+ case CORE_OBJECT_TYPE_SAP:
+ /* Create Core Object */
+ co = tcore_sap_new(plugin, "sap", NULL, hal);
+ break;
+
+ case CORE_OBJECT_TYPE_SMS:
+ /* Create Core Object */
+ co = tcore_sms_new(plugin, "sms", NULL, hal);
+ break;
+
+ case CORE_OBJECT_TYPE_PHONEBOOK:
+ /* Create Core Object */
+ co = tcore_phonebook_new(plugin, "phonebook", NULL, hal);
+ break;
+
+ case CORE_OBJECT_TYPE_GPS:
+ /* Create Core Object */
+ co = tcore_gps_new(plugin, "gps", NULL, hal);
+ break;
+
+ case CORE_OBJECT_TYPE_CUSTOM: /* Fall through */
+ default:
+ err("Unsupport/Invalid Core Object Type [0x%x]", type);
+ break;
+ }
+
+ return co;
+}
+
+
+static gboolean _init_core_object_by_type(unsigned int type,
+ TcorePlugin *plugin, struct object_initializer *initializer_list)
+{
+ gboolean ret = FALSE;
+ CoreObject *co = tcore_plugin_ref_core_object(plugin, type);
+ if (co == NULL) {
+ err("No Core Object of type: [0x%x]", type);
+ return FALSE;
+ }
+
+ switch (type) {
+ case CORE_OBJECT_TYPE_MODEM: {
+ /* Invoke initializer */
+ if (initializer_list->modem_init)
+ ret = initializer_list->modem_init(plugin, co);
+ }
+ break;
+
+ case CORE_OBJECT_TYPE_CALL: {
+ /* Invoke initializer */
+ if (initializer_list->call_init)
+ ret = initializer_list->call_init(plugin, co);
+ }
+ break;
+
+ case CORE_OBJECT_TYPE_SS: {
+ /* Invoke initializer */
+ if (initializer_list->ss_init)
+ ret = initializer_list->ss_init(plugin, co);
+ }
+ break;
+
+ case CORE_OBJECT_TYPE_NETWORK: {
+ /* Invoke initializer */
+ if (initializer_list->network_init)
+ ret = initializer_list->network_init(plugin, co);
+ }
+ break;
+
+ case CORE_OBJECT_TYPE_PS: {
+ /* Invoke initializer */
+ if (initializer_list->ps_init)
+ ret = initializer_list->ps_init(plugin, co);
+ }
+ break;
+
+ case CORE_OBJECT_TYPE_SIM: {
+ /* Invoke initializer */
+ if (initializer_list->sim_init)
+ ret = initializer_list->sim_init(plugin, co);
+ }
+ break;
+
+ case CORE_OBJECT_TYPE_SAT: {
+ /* Invoke initializer */
+ if (initializer_list->sat_init)
+ ret = initializer_list->sat_init(plugin, co);
+ }
+ break;
+
+ case CORE_OBJECT_TYPE_SAP: {
+ /* Invoke initializer */
+ if (initializer_list->sap_init)
+ ret = initializer_list->sap_init(plugin, co);
+ }
+ break;
+
+ case CORE_OBJECT_TYPE_SMS:{
+ /* Invoke initializer */
+ if (initializer_list->sms_init)
+ ret = initializer_list->sms_init(plugin, co);
+ }
+ break;
+
+ case CORE_OBJECT_TYPE_PHONEBOOK: {
+ /* Invoke initializer */
+ if (initializer_list->phonebook_init)
+ ret = initializer_list->phonebook_init(plugin, co);
+ }
+ break;
+
+ case CORE_OBJECT_TYPE_GPS:{
+ /* Invoke initializer */
+ if (initializer_list->gps_init)
+ ret = initializer_list->gps_init(plugin, co);
+ }
+ break;
+
+ case CORE_OBJECT_TYPE_CUSTOM: /* Fall through */
+ default:
+ dbg("Unsupport/Invalid Core Object Type [0x%x]", type);
+ break;
+ }
+
+ return ret;
+}
+
+
+static void _deinit_core_object_by_type(unsigned int type,
+ TcorePlugin *plugin, struct object_deinitializer *deinitializer_list)
+{
+ CoreObject *co;
+
+ co = tcore_plugin_ref_core_object(plugin, type);
+ if (co == NULL) {
+ err("No Core Object of type: [0x%x]", type);
+ return;
+ }
+
+ switch (type) {
+ case CORE_OBJECT_TYPE_MODEM: {
+ if (deinitializer_list->modem_deinit) {
+ /* Invoke deinitializer */
+ deinitializer_list->modem_deinit(plugin, co);
+ }
+ }
+ break;
+
+ case CORE_OBJECT_TYPE_CALL: {
+ if (deinitializer_list->call_deinit) {
+ /* Invoke deinitializer */
+ deinitializer_list->call_deinit(plugin, co);
+ }
+ }
+ break;
+
+ case CORE_OBJECT_TYPE_SS: {
+ if (deinitializer_list->ss_deinit) {
+ /* Invoke deinitializer */
+ deinitializer_list->ss_deinit(plugin, co);
+ }
+ }
+ break;
+
+ case CORE_OBJECT_TYPE_NETWORK: {
+ if (deinitializer_list->network_deinit) {
+ /* Invoke deinitializer */
+ deinitializer_list->network_deinit(plugin, co);
+ }
+ }
+ break;
+
+ case CORE_OBJECT_TYPE_PS: {
+ if (deinitializer_list->ps_deinit) {
+ /* Invoke deinitializer */
+ deinitializer_list->ps_deinit(plugin, co);
+ }
+ }
+ break;
+
+ case CORE_OBJECT_TYPE_SIM: {
+ if (deinitializer_list->sim_deinit) {
+ /* Invoke deinitializer */
+ deinitializer_list->sim_deinit(plugin, co);
+ }
+ }
+ break;
+
+ case CORE_OBJECT_TYPE_SAT: {
+ if (deinitializer_list->sat_deinit) {
+ /* Invoke deinitializer */
+ deinitializer_list->sat_deinit(plugin, co);
+ }
+ }
+ break;
+
+ case CORE_OBJECT_TYPE_SAP: {
+ if (deinitializer_list->sap_deinit) {
+ /* Invoke deinitializer */
+ deinitializer_list->sap_deinit(plugin, co);
+ }
+ }
+ break;
+
+ case CORE_OBJECT_TYPE_SMS:{
+ if (deinitializer_list->sms_deinit) {
+ /* Invoke deinitializer */
+ deinitializer_list->sms_deinit(plugin, co);
+ }
+ }
+ break;
+
+ case CORE_OBJECT_TYPE_PHONEBOOK: {
+ if (deinitializer_list->phonebook_deinit) {
+ /* Invoke deinitializer */
+ deinitializer_list->phonebook_deinit(plugin, co);
+ }
+ }
+ break;
+
+ case CORE_OBJECT_TYPE_GPS:{
+ if (deinitializer_list->gps_deinit) {
+ /* Invoke deinitializer */
+ deinitializer_list->gps_deinit(plugin, co);
+ }
+ }
+ break;
+
+ case CORE_OBJECT_TYPE_CUSTOM: /* Fall through */
+ default:
+ dbg("Unsupport/Invalid Core Object Type [0x%x]", type);
+ return;
+ }
+
+ /* Free Core Object */
+ tcore_object_free(co);
+}
+
+
+CoreObject *tcore_object_new(TcorePlugin *plugin,
+ const char *name, TcoreHal *hal)
+{
+ CoreObject *co;
+
+ co = _object_new(plugin, CORE_OBJECT_TYPE_DEFAULT);
+ if (!co)
+ return NULL;
+
+ tcore_object_set_hal(co, hal);
+ tcore_object_set_name(co, name);
+
+ if (plugin)
+ tcore_plugin_add_core_object(plugin, co);
+
+ return co;
+}
+
+void tcore_object_free(CoreObject *co)
+{
+ GSList *l = NULL;
+ struct callback_type *cb = NULL;
+
+ if (!co)
+ return;
+
+ dbg("co_name=%s", co->name);
+
+ if (co->free_hook)
+ co->free_hook(co);
+ else {
+ if (co->object)
+ warn("free_hook is null, private-object couldn't be freed!!");
+ }
+
+ if (co->property)
+ g_hash_table_destroy(co->property);
+
+ if (co->callbacks) {
+ for (l = co->callbacks; l; l = l->next) {
+ cb = l->data;
+ if (!cb)
+ continue;
+
+ if (cb->event)
+ free(cb->event);
+
+ free(cb);
+ }
+
+ g_slist_free(co->callbacks);
+ co->callbacks = NULL;
+ }
+
+ if (co->parent_plugin)
+ tcore_plugin_remove_core_object(co->parent_plugin, co);
+
+ if (co->name)
+ free(co->name);
+
+ memset(co, 0, sizeof(CoreObject));
+ free(co);
+}
+
+const char *tcore_object_ref_name(CoreObject *co)
+{
+ if (!co)
+ return NULL;
+
+ return co->name;
+}
+
+TReturn tcore_object_set_free_hook(CoreObject *co,
+ CoreObjectFreeHook free_hook)
+{
+ if (!co)
+ return TCORE_RETURN_EINVAL;
+
+ co->free_hook = free_hook;
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+TReturn tcore_object_set_name(CoreObject *co, const char *name)
+{
+ if (!co)
+ return TCORE_RETURN_EINVAL;
+
+ if (co->name) {
+ free(co->name);
+ co->name = NULL;
+ }
+
+ if (name)
+ co->name = strdup(name);
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+TcorePlugin *tcore_object_ref_plugin(CoreObject *co)
+{
+ if (!co)
+ return NULL;
+
+ return co->parent_plugin;
+}
+
+TReturn tcore_object_link_object(CoreObject *co, void *object)
+{
+ if (!co)
+ return TCORE_RETURN_EINVAL;
+
+ co->object = object;
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+void *tcore_object_ref_object(CoreObject *co)
+{
+ if (!co)
+ return NULL;
+
+ return co->object;
+}
+
+TReturn tcore_object_set_type(CoreObject *co, unsigned int type)
+{
+ if (!co)
+ return TCORE_RETURN_EINVAL;
+
+ co->type = type;
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+unsigned int tcore_object_get_type(CoreObject *co)
+{
+ if (!co)
+ return 0;
+
+ return co->type;
+}
+
+TReturn tcore_object_set_hal(CoreObject *co, TcoreHal *hal)
+{
+ TcoreAT *at;
+ struct callback_type *cb = NULL;
+ GSList *l = NULL;
+
+ if (!co)
+ return TCORE_RETURN_EINVAL;
+
+ if (co->hal) {
+ /* Remove unsolicited callbacks */
+ if (tcore_hal_get_mode(co->hal) == TCORE_HAL_MODE_AT) {
+ at = tcore_hal_get_at(co->hal);
+ for (l = co->callbacks; l; l = l->next) {
+ cb = l->data;
+ if (!cb)
+ continue;
+
+ tcore_at_remove_notification_full(at, cb->event, _on_at_event, cb);
+ }
+ }
+ }
+
+ co->hal = hal;
+ if (!hal)
+ return TCORE_RETURN_SUCCESS;
+
+ /* Register unsolicited callbacks */
+ if (tcore_hal_get_mode(hal) == TCORE_HAL_MODE_AT) {
+ at = tcore_hal_get_at(hal);
+ for (l = co->callbacks; l; l = l->next) {
+ cb = l->data;
+ if (!cb)
+ continue;
+
+ if (cb->event[0] == 27)
+ tcore_at_add_notification(at, cb->event + 1, TRUE, _on_at_event, cb);
+ else
+ tcore_at_add_notification(at, cb->event, FALSE, _on_at_event, cb);
+ }
+ }
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+TcoreHal *tcore_object_get_hal(CoreObject *co)
+{
+ if (!co)
+ return NULL;
+
+ return co->hal;
+}
+
+TReturn tcore_object_link_user_data(CoreObject *co,
+ void *user_data)
+{
+ if (!co)
+ return TCORE_RETURN_EINVAL;
+
+ co->user_data = user_data;
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+void *tcore_object_ref_user_data(CoreObject *co)
+{
+ if (!co)
+ return NULL;
+
+ return co->user_data;
+}
+
+/* This API will dispatch the request to default ops(i.e. CP) */
+TReturn tcore_object_dispatch_request(CoreObject *co,
+ UserRequest *ur)
+{
+ return tcore_object_dispatch_request_with_type(co, ur, TCORE_OPS_TYPE_CP);
+}
+
+/* This API will dispatch the request according to ops type */
+TReturn tcore_object_dispatch_request_with_type(CoreObject *co,
+ UserRequest *ur, enum tcore_ops_type ops_type)
+{
+ if (!co || !ur)
+ return TCORE_RETURN_EINVAL;
+
+ if (!co->dispatcher)
+ return TCORE_RETURN_ENOSYS;
+
+ return co->dispatcher(co, ur, ops_type);
+}
+
+TReturn tcore_object_set_dispatcher(CoreObject *co,
+ CoreObjectDispatcher func)
+{
+ if (!co || !func)
+ return TCORE_RETURN_EINVAL;
+
+ co->dispatcher = func;
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+TReturn tcore_object_override_callback(CoreObject *co,
+ const char *event, tcore_object_callback callback, void *user_data)
+{
+ struct callback_type *cb = NULL;
+ GSList *l = NULL;
+ TcoreAT *at = NULL;
+
+ if ((co == NULL) || (event == NULL) || (callback == NULL))
+ return TCORE_RETURN_EINVAL;
+
+ if (strlen(event) < 1)
+ return TCORE_RETURN_EINVAL;
+
+ if (co->hal) {
+ if (tcore_hal_get_mode(co->hal) == TCORE_HAL_MODE_AT)
+ at = tcore_hal_get_at(co->hal);
+ }
+
+ for (l = co->callbacks; l; l = l->next) {
+ cb = l->data;
+ if (cb == NULL)
+ continue;
+
+ if (g_strcmp0(cb->event, event) != 0)
+ continue;
+
+ if (at)
+ _remove_at_callback(at, cb);
+
+ g_free(cb->event);
+ co->callbacks = g_slist_remove(co->callbacks, cb);
+ g_free(cb);
+ }
+
+ return tcore_object_add_callback(co, event, callback, user_data);
+}
+
+TReturn tcore_object_add_callback(CoreObject *co,
+ const char *event,
+ CoreObjectCallback callback, void *user_data)
+{
+ struct callback_type *cb = NULL;
+ TcoreAT *at = NULL;
+
+ if (!co || !event || !callback)
+ return TCORE_RETURN_EINVAL;
+
+ if (strlen(event) < 1)
+ return TCORE_RETURN_EINVAL;
+
+ cb = calloc(1, sizeof(struct callback_type));
+ if (!cb)
+ return TCORE_RETURN_ENOMEM;
+
+ cb->co = co;
+ cb->event = strdup(event);
+ cb->callback = callback;
+ cb->user_data = user_data;
+
+ co->callbacks = g_slist_append(co->callbacks, cb);
+
+ if (co->hal) {
+ if (tcore_hal_get_mode(co->hal) == TCORE_HAL_MODE_AT) {
+ at = tcore_hal_get_at(co->hal);
+ if (event[0] == 27)
+ tcore_at_add_notification(at, cb->event + 1, TRUE, _on_at_event, cb);
+ else
+ tcore_at_add_notification(at, cb->event, FALSE, _on_at_event, cb);
+
+ }
+ }
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+TReturn tcore_object_del_callback(CoreObject *co,
+ const char *event, CoreObjectCallback callback)
+{
+ struct callback_type *cb = NULL;
+ GSList *l = NULL;
+ TcoreAT *at = NULL;
+
+ if (!co || !event || !callback || !co->callbacks)
+ return TCORE_RETURN_EINVAL;
+
+ if (strlen(event) == 0)
+ return TCORE_RETURN_EINVAL;
+
+ if (co->hal) {
+ if (tcore_hal_get_mode(co->hal) == TCORE_HAL_MODE_AT)
+ at = tcore_hal_get_at(co->hal);
+ }
+
+ l = co->callbacks;
+ while (l) {
+ cb = l->data;
+ if (!cb) {
+ l = l->next;
+ continue;
+ }
+
+ if (cb->callback != callback) {
+ l = l->next;
+ continue;
+ }
+
+ if (g_strcmp0(cb->event, event) != 0) {
+ l = l->next;
+ continue;
+ }
+
+ if (at)
+ _remove_at_callback(at, cb);
+
+ l = l->next;
+ co->callbacks = g_slist_remove(co->callbacks, cb);
+ free(cb->event);
+ free(cb);
+ }
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+TReturn tcore_object_emit_callback(CoreObject *co,
+ const char *event, const void *event_info)
+{
+ struct callback_type *cb = NULL;
+ GSList *l = NULL;
+ TReturn ret;
+
+ if (!co || !event)
+ return TCORE_RETURN_EINVAL;
+
+ l = co->callbacks;
+ while (l) {
+ cb = l->data;
+ if (!cb) {
+ l = l->next;
+ continue;
+ }
+
+ if (g_strcmp0(cb->event, event) != 0) {
+ l = l->next;
+ continue;
+ }
+
+ if (cb->callback) {
+ ret = cb->callback(co, event_info, cb->user_data);
+ if (ret == FALSE) {
+ l = l->next;
+ co->callbacks = g_slist_remove(co->callbacks, cb);
+ continue;
+ }
+ }
+
+ l = l->next;
+ }
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+static GSList *_set_property_real(CoreObject *co, const char *key,
+ const char *value, GSList *list)
+{
+ char *prev;
+
+ if (!co || !key)
+ return list;
+
+ if (!value) {
+ g_hash_table_remove(co->property, key);
+ return g_slist_append(list, (char *)key);
+ }
+
+ prev = g_hash_table_lookup(co->property, key);
+ if (prev != NULL) {
+ /*
+ * If same data, no change & no callback emit
+ */
+ if (strcmp(prev, value) == 0)
+ return list;
+
+ g_hash_table_replace(co->property, strdup(key), strdup(value));
+ } else
+ g_hash_table_insert(co->property, strdup(key), strdup(value));
+
+ return g_slist_append(list, (char *)key);
+}
+
+TReturn tcore_object_set_property_full(CoreObject *co, const char *first_property, ...)
+{
+ va_list argptr;
+ GSList *list = NULL;
+ const char *k;
+ const char *v;
+
+ if (!co || !first_property)
+ return TCORE_RETURN_EINVAL;
+
+ va_start(argptr, first_property);
+
+ k = first_property;
+ v = va_arg(argptr, char *);
+ list = _set_property_real(co, k, v, list);
+
+ while (1) {
+ k = va_arg(argptr, char *);
+ if (!k)
+ break;
+
+ v = va_arg(argptr, char *);
+ list = _set_property_real(co, k, v, list);
+ }
+
+ va_end(argptr);
+
+ if (!list)
+ return TCORE_RETURN_SUCCESS;
+
+ if (g_slist_length(list) > 0)
+ tcore_object_emit_callback(co,
+ CORE_OBJECT_EVENT_PROPERTY_CHANGED, list);
+
+ g_slist_free(list);
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+const char *tcore_object_ref_property(CoreObject *co, const char *key)
+{
+ if (!co || !key)
+ return NULL;
+
+ return g_hash_table_lookup(co->property, key);
+}
+
+GHashTable *tcore_object_ref_property_hash(CoreObject *co)
+{
+ if (!co)
+ return NULL;
+
+ return co->property;
+}
+void *tcore_object_add_mapping_tbl_entry(void *mapping_tbl,
+ unsigned int object_type, TcoreHal *hal)
+{
+ GSList *mapping_tbl_list = mapping_tbl;
+ object_mapping_table_t *tbl_entry;
+
+ if (hal == NULL) {
+ err("Mapping Table: [0x%x] HAL: [0x%x]", mapping_tbl, hal);
+ return mapping_tbl;
+ }
+
+ /*
+ * Search 'hal' across all the Table entries of the Mapping Table
+ *
+ * Table entry MAY NOT be found as -
+ * 1. Mapping Table is NOT yet created
+ * 2. Table entry for corresponding 'hal' is NOT present
+ *
+ * In each of the above cases, the new Mapping Table entry should be added
+ * to the Mapping Table.
+ */
+ tbl_entry = _object_search_mapping_tbl_entry(mapping_tbl_list, hal);
+ if (tbl_entry == NULL) {
+ dbg("Creating New Table entry for HAL: [0x%x]", hal);
+ /*
+ * If there is NO previously added Table entry for the 'hal' then
+ * new Table entry is created
+ */
+
+ tbl_entry = g_try_malloc0(sizeof(object_mapping_table_t));
+ if (tbl_entry != NULL)
+ tbl_entry->hal = hal;
+ else {
+ err("Failed to allocate memory");
+ return mapping_tbl_list;
+ }
+
+ /* Add the Mapping Table entry to Mapping Table */
+ mapping_tbl_list = g_slist_append(mapping_tbl_list, tbl_entry);
+ }
+
+ /*
+ * Appending the Core Object type to the list of Core Objects types
+ */
+ tbl_entry->object_type = g_slist_append(tbl_entry->object_type, GUINT_TO_POINTER(object_type));
+ dbg("Added Mapping Table entry - HAL: [0x%x] Object type: [0x%x]", hal, object_type);
+
+ return mapping_tbl_list;
+}
+
+void tcore_object_remove_mapping_tbl(void *mapping_tbl)
+{
+ GSList *mapping_tbl_list = mapping_tbl;
+
+ if (mapping_tbl_list == NULL) {
+ err("Mapping Table is NULL");
+ return;
+ }
+
+ /* Freeing Mapping Table */
+ g_slist_free_full(mapping_tbl_list, _free_tbl_entry);
+}
+
+void *tcore_object_remove_mapping_tbl_entry(void *mapping_tbl, TcoreHal *hal)
+{
+ GSList *mapping_tbl_list = mapping_tbl;
+ object_mapping_table_t *tbl_entry;
+
+ if (mapping_tbl_list == NULL) {
+ err("Mapping Table is NULL");
+ return mapping_tbl;
+ }
+
+ tbl_entry = _object_search_mapping_tbl_entry(mapping_tbl_list, hal);
+ if (tbl_entry == NULL) {
+ err("Table entry is NOT available");
+ return mapping_tbl_list;
+ }
+
+ dbg("Removing Mapping Table Entry - HAL: [0x%x]", hal);
+ _util_print_mapping_tbl_entry(tbl_entry);
+
+ /* Free Core Object types list */
+ g_slist_free(tbl_entry->object_type);
+
+ /* Remove mapping Table entry */
+ mapping_tbl_list = g_slist_remove(mapping_tbl_list, tbl_entry);
+
+ /* Free Table entry */
+ g_free(tbl_entry);
+
+ return mapping_tbl_list;
+}
+
+void tcore_object_remove_mapping_tbl_entry_by_type(void *mapping_tbl,
+ unsigned int co_type)
+{
+ GSList *mapping_tbl_list;
+ object_mapping_table_t *tbl_entry;
+
+ if (mapping_tbl == NULL) {
+ err("Mapping Table is NULL");
+ return;
+ }
+
+ mapping_tbl_list = mapping_tbl;
+
+ tbl_entry =
+ _object_search_mapping_tbl_entry_by_type(mapping_tbl_list, co_type);
+ if (tbl_entry == NULL) {
+ err("Table entry is NOT available");
+ return;
+ }
+
+ /* Remove the Core Object type from the list */
+ tbl_entry->object_type = g_slist_remove(tbl_entry->object_type, GUINT_TO_POINTER(co_type));
+}
+
+void tcore_object_print_mapping_tbl(void *mapping_tbl)
+{
+ GSList *mapping_tbl_list;
+ object_mapping_table_t *tbl_entry = NULL;
+
+
+ if (mapping_tbl == NULL) {
+ err("Mapping Table is NULL");
+ return;
+ }
+
+ mapping_tbl_list = mapping_tbl;
+
+ for (; mapping_tbl_list ; mapping_tbl_list = mapping_tbl_list->next) {
+ tbl_entry = mapping_tbl_list->data;
+ if (tbl_entry == NULL)
+ continue;
+
+ _util_print_mapping_tbl_entry(tbl_entry);
+ }
+}
+
+/* Initialize Core Objects */
+TReturn tcore_object_init_objects(TcorePlugin *plugin,
+ struct object_initializer *initializer_list)
+{
+ GSList *mapping_tbl_list;
+ gboolean ret = FALSE;
+
+ /* Refer mapping_tbl from Server's Modem list */
+ mapping_tbl_list = tcore_server_get_cp_mapping_tbl(plugin);
+
+ /*
+ * Mapping Table is a MUST
+ * If Mapping Table is NOT NULL, then initialization would be guided by the
+ * Mapping Table entries,
+ * else, it is treated as a Failure.
+ */
+ if (mapping_tbl_list != NULL) {
+ object_mapping_table_t *tbl_entry;
+ GSList *mtbl_list;
+ GSList *object_type_list;
+ unsigned int type;
+
+ /* Create each Core Object based on the Mapping Table entries */
+ mtbl_list = mapping_tbl_list;
+ for (; mtbl_list ; mtbl_list = mtbl_list->next) {
+ tbl_entry = mtbl_list->data;
+ if (tbl_entry != NULL) {
+ CoreObject *co;
+
+ object_type_list = tbl_entry->object_type;
+ for (; object_type_list ; object_type_list = object_type_list->next) {
+ type = GPOINTER_TO_UINT(object_type_list->data);
+
+ co = _create_core_object_by_type(type, plugin, tbl_entry->hal);
+ if (co == NULL) {
+ err("Failed to create Core Object - Type: [0x%x]", type);
+ return TCORE_RETURN_FAILURE;
+ }
+
+ dbg("Created Core Object - Type: [0x%x]", type);
+ }
+ }
+ }
+
+
+ /* Initialize each Core Object based on the Mapping Table entries */
+ mtbl_list = mapping_tbl_list;
+ for (; mtbl_list ; mtbl_list = mtbl_list->next) {
+ tbl_entry = mtbl_list->data;
+ if (tbl_entry != NULL) {
+ /* To handle NULL 'init' function case */
+ ret = FALSE;
+
+ object_type_list = tbl_entry->object_type;
+
+ for (; object_type_list ; object_type_list = object_type_list->next) {
+ type = GPOINTER_TO_UINT(object_type_list->data);
+ dbg("Core Object type: [0x%x]", type);
+
+ ret = _init_core_object_by_type(type, plugin, initializer_list);
+ if (ret == FALSE) {
+ err("Failed to initialize Core Object Type [0x%x]", type);
+ return TCORE_RETURN_FAILURE;
+ }
+
+ dbg("Initialized Core Object - Type: [0x%x]", type);
+ }
+ }
+ }
+ } else
+ err("Mapping Table is NOT present");
+
+ if (ret == FALSE) {
+ err("Failed to create/initialize Core Objects");
+ return TCORE_RETURN_FAILURE;
+ }
+
+ dbg("Successfully initialized Core Objects");
+ return TCORE_RETURN_SUCCESS;
+}
+
+/* De-initialize Core Objects */
+void tcore_object_deinit_objects(TcorePlugin *plugin,
+ struct object_deinitializer *deinitializer_list)
+{
+ GSList *mapping_tbl_list;
+
+ /* Refer mapping_tbl from Server's Modem list */
+ mapping_tbl_list = tcore_server_get_cp_mapping_tbl(plugin);
+
+ /*
+ * Mapping Table is a MUST
+ * If Mapping Table is NOT NULL, then de-initialization would be guided by the
+ * Mapping Table entries,
+ * else,
+ * just return with an Error log.
+ */
+ if (mapping_tbl_list != NULL) {
+ object_mapping_table_t *tbl_entry;
+ GSList *object_type_list;
+ unsigned int type;
+
+ /* De-initialize each Core Object based on the Mapping Table entries */
+ for (; mapping_tbl_list ; mapping_tbl_list = mapping_tbl_list->next) {
+ tbl_entry = mapping_tbl_list->data;
+ if (tbl_entry == NULL)
+ continue;
+
+ object_type_list = tbl_entry->object_type;
+
+ for (; object_type_list ; object_type_list = object_type_list->next) {
+ type = GPOINTER_TO_UINT(object_type_list->data);
+ dbg("Core Object type: [0x%x]", type);
+
+ _deinit_core_object_by_type(type, plugin, deinitializer_list);
+ }
+ }
+
+ dbg("Successfully de-initialized Core Objects");
+ } else
+ err("Mapping Table is NOT present");
+}
return FALSE;
}
- dbg("Dispatching to logical HAL - hal: [0x%x]", hal);
+ dbg("Dispatching to logical HAL - hal: [%p]", hal);
if (tcore_hal_dispatch_response_data(hal, 0,
cmux_obj->internal_mux.info_field_len,
cmux_obj->internal_mux.info_field)
if (!s || !ur)
return TCORE_RETURN_EINVAL;
+ /* In case Manager is available, process Request in Manager */
+ if (s->manager) {
+ enum tcore_manager_return mgr_ret;
+
+ mgr_ret = tcore_manager_dispatch_request(s->manager, ur);
+ switch (mgr_ret) {
+ case TCORE_MANAGER_RETURN_FAILURE:
+ return TCORE_RETURN_FAILURE;
+
+ case TCORE_MANAGER_RETURN_STOP:
+ return TCORE_RETURN_SUCCESS;
+
+ case TCORE_MANAGER_RETURN_CONTINUE_IMS:
+ ops_type = TCORE_OPS_TYPE_IMS;
+ break;
+
+ default:
+ ops_type = TCORE_OPS_TYPE_CP;
+ break;
+ }
+ }
+
for (list = s->hook_list_request; list; list = list->next) {
hook = list->data;
if (!hook)
}
}
- /* In case Manager is available, process Request in Manager */
- if (s->manager) {
- enum tcore_manager_return mgr_ret;
-
- mgr_ret = tcore_manager_dispatch_request(s->manager, ur);
-
- if (mgr_ret == TCORE_MANAGER_RETURN_FAILURE)
- return TCORE_RETURN_FAILURE;
- else if (mgr_ret == TCORE_MANAGER_RETURN_STOP)
- return TCORE_RETURN_SUCCESS;
- else if (mgr_ret == TCORE_MANAGER_RETURN_CONTINUE_IMS)
- ops_type = TCORE_OPS_TYPE_IMS;
- else
- ops_type = TCORE_OPS_TYPE_CP;
- }
-
modem_name = tcore_user_request_get_modem_name(ur);
if (!modem_name)
return TCORE_RETURN_EINVAL;
return ret;
}
-TReturn tcore_server_send_notification(Server *s, CoreObject *source,
- enum tcore_notification_command command,
- unsigned int data_len, void *data)
+TReturn tcore_server_broadcast_notification(Server *s, CoreObject *source,
+ enum tcore_notification_command command, unsigned int data_len, void *data)
{
GSList *list;
Communicator *comm;
struct hook_notification_type *hook;
+
if (!s)
return TCORE_RETURN_EINVAL;
- /* In case Manager is available, process Notification in Manager */
- if (s->manager) {
- enum tcore_manager_return mgr_ret;
-
- /* Send notification to 'manager' */
- mgr_ret = tcore_manager_send_notification(s->manager,
- source, command, data_len, data);
-
- if (mgr_ret == TCORE_MANAGER_RETURN_FAILURE)
- return TCORE_RETURN_FAILURE;
- else if (mgr_ret == TCORE_MANAGER_RETURN_STOP)
- return TCORE_RETURN_SUCCESS;
- /* in other cases, send notification to communicator. */
- }
-
- for (list = s->hook_list_notification; list;) {
+ for (list = s->hook_list_notification; list; ) {
hook = list->data;
list = list->next;
if (!hook)
return TCORE_RETURN_SUCCESS;
}
- for (list = s->communicators; list;) {
+ for (list = s->communicators; list; ) {
comm = list->data;
list = list->next;
if (!comm)
return TCORE_RETURN_SUCCESS;
}
+TReturn tcore_server_send_notification(Server *s, CoreObject *source,
+ enum tcore_notification_command command,
+ unsigned int data_len, void *data)
+{
+ if (!s)
+ return TCORE_RETURN_EINVAL;
+
+ /* In case Manager is available, process Notification in Manager */
+ if (s->manager) {
+ enum tcore_manager_return mgr_ret;
+
+ /* Send notification to 'manager' */
+ mgr_ret = tcore_manager_send_notification(s->manager,
+ source, command, data_len, data);
+ if (mgr_ret == TCORE_MANAGER_RETURN_FAILURE)
+ return TCORE_RETURN_FAILURE;
+ else if (mgr_ret == TCORE_MANAGER_RETURN_STOP)
+ return TCORE_RETURN_SUCCESS;
+ /* in other cases, send notification to communicator. */
+ }
+
+ return tcore_server_broadcast_notification(s, source, command, data_len, data);
+}
+
TReturn tcore_server_add_request_hook(Server *s,
enum tcore_request_command command,
TcoreServerRequestHook func, void *user_data)
/* Open '.so' */
handle = dlopen(filename, RTLD_LAZY);
if (handle == NULL) {
- err("Failed to load '%s': %s", filename, dlerror());
+ err("dlopen() failed:[%s]", filename);
goto out;
}
desc = dlsym(handle, "plugin_define_desc");
if (desc == NULL) {
- err("Failed to obtain the address of plugin_define_desc: %s", dlerror());
+ err("dlsym() failed:[%s]", "plugin_define_desc");
dlclose(handle);
goto out;
}
in_param, out_param, out_param_cnt);
}
+gboolean tcore_storage_read_query_database_in_order(Storage *strg, void *handle,
+ const char *query, GHashTable *in_param,
+ GSList **out_param, int out_param_cnt)
+{
+ if (!strg || !handle || !query)
+ return FALSE;
+
+ if (!strg->ops || !strg->ops->read_query_database)
+ return FALSE;
+
+ return strg->ops->read_query_database_in_order(strg, handle, query,
+ in_param, out_param, out_param_cnt);
+}
+
gboolean tcore_storage_insert_query_database(Storage *strg, void *handle,
const char *query, GHashTable *in_param)
{
close(fd);
return TCORE_RETURN_FAILURE;
}
-
- if (ipaddr) {
- dbg("devname: %s, ipaddr: %s", name, ipaddr);
- } else {
- memset(&sai, 0, sizeof(struct sockaddr_in));
- memcpy(&sai, &ifr.ifr_addr, sizeof(struct sockaddr_in));
- dbg("devname: %s, ipaddr: %s", name, inet_ntoa(sai.sin_addr));
- }
+ dbg("devname: [%s], ipaddr: [%s]", name, ipaddr);
close(fd);
return TCORE_RETURN_SUCCESS;