Implment handling of set sound path on mfld
[platform/core/telephony/tel-plugin-imc.git] / src / s_sim.c
index 5e30771..8229246 100644 (file)
 #include <plugin.h>
 #include <queue.h>
 #include <co_sim.h>
+#include <co_sms.h>
 #include <storage.h>
 #include <user_request.h>
 #include <server.h>
 #include <at.h>
 
 #include "s_common.h"
+#include "s_sms.h"
 #include "s_sim.h"
 
 #define ID_RESERVED_AT 0x0229
@@ -98,7 +100,6 @@ struct s_sim_property {
        int rec_count; /**< Number of records in file */
        int data_size; /**< File size */
        int current_index; /**< current index to read */
-       enum tel_sim_status first_recv_status;
        enum s_sim_sec_op_e current_sec_op; /**< current index to read */
        struct tel_sim_mbi_list mbi_list;
        struct tel_sim_mb_number mb_list[SIM_MSP_CNT_MAX*5];
@@ -114,6 +115,32 @@ static gboolean _get_file_record(CoreObject *o, UserRequest *ur, const enum tel_
 static void _sim_status_update(CoreObject *o, enum tel_sim_status sim_status);
 extern gboolean util_byte_to_hex(const char *byte_pdu, char *hex_pdu, int num_bytes);
 
+static void sim_prepare_and_send_pending_request(CoreObject *co, const char *at_cmd, const char *prefix, enum tcore_at_command_type at_cmd_type, TcorePendingResponseCallback callback)
+{
+       TcoreATRequest *req = NULL;
+       TcoreHal *hal = NULL;
+       TcorePending *pending = NULL;
+       TReturn ret;
+
+
+       hal = tcore_object_get_hal(co);
+       dbg("hal: %p", hal);
+
+       pending = tcore_pending_new(co, 0);
+       if (!pending)
+               dbg("Pending is NULL");
+       req = tcore_at_request_new(at_cmd, prefix, at_cmd_type);
+
+       dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
+
+       tcore_pending_set_request_data(pending, 0, req);
+       tcore_pending_set_response_callback(pending, callback, NULL);
+       tcore_pending_link_user_request(pending, NULL); // set user request to NULL - this is internal request
+       ret = tcore_hal_send_request(hal, pending);
+       return;
+}
+
+
 static enum tcore_response_command _find_resp_command(UserRequest *ur)
 {
        enum tcore_request_command command;
@@ -587,6 +614,7 @@ static void _next_from_get_file_info(CoreObject *o, UserRequest *ur, enum tel_si
        case SIM_EF_MBDN:
        case SIM_EF_CPHS_MAILBOX_NUMBERS:
        case SIM_EF_CPHS_INFORMATION_NUMBERS:
+       case SIM_EF_MSISDN:
                file_meta->current_index++;
                _get_file_record(o, ur, ef, file_meta->current_index, file_meta->rec_length);
                break;
@@ -801,7 +829,13 @@ static void _response_get_sim_type(TcorePending *p, int data_len, const void *da
        }
 
        tcore_sim_set_type(co_sim, sim_type);
-       _sim_status_update(co_sim, sp->first_recv_status);
+
+       if (sim_type != SIM_TYPE_UNKNOWN) {
+               /* set user request for using ur metainfo set/ref functionality */
+               ur = tcore_user_request_new(NULL, NULL);
+               _get_file_info(co_sim, ur, SIM_EF_IMSI);
+       }
+
        tcore_at_tok_free(tokens);
        dbg(" Function exit");
 }
@@ -1672,7 +1706,7 @@ static TReturn _get_file_info(CoreObject *o, UserRequest *ur, const enum tel_sim
        trt = tcore_user_request_set_metainfo(ur, sizeof(struct s_sim_property), &file_meta);
        dbg("trt[%d]", trt);
        cmd_str = g_strdup_printf("AT+CRSM=192, %d", ef);           /*command - 192 : GET RESPONSE*/
-       dbg("cmd_str: %x", cmd_str);
+       dbg("cmd_str: %s", cmd_str);
 
        pending = tcore_at_pending_new(o, cmd_str, "+CRSM:", TCORE_AT_SINGLELINE, _response_get_file_info, NULL);
        tcore_pending_link_user_request(pending, ur);
@@ -1875,13 +1909,14 @@ OUT:
 
 static gboolean on_event_pin_status(CoreObject *o, const void *event_info, void *user_data)
 {
-       UserRequest *ur = NULL;
+
        struct s_sim_property *sp = NULL;
        enum tel_sim_status sim_status = SIM_STATUS_INITIALIZING;
        GSList *tokens = NULL;
        GSList *lines = NULL;
        const char *line = NULL;
        int sim_state = 0;
+       int sms_state = 0;
 
        dbg(" Function entry ");
 
@@ -1895,12 +1930,17 @@ static gboolean on_event_pin_status(CoreObject *o, const void *event_info, void
        line = (char *) (lines->data);
 
        tokens = tcore_at_tok_new(line);
-       if (g_slist_length(tokens) != 1) {
+
+       if (g_slist_length(tokens) == 4) {
+               sim_state = atoi(g_slist_nth_data(tokens, 1));
+               sms_state = atoi(g_slist_nth_data(tokens, 3));
+       } else if (g_slist_length(tokens) == 1)
+               sim_state = atoi(g_slist_nth_data(tokens, 0));
+       else {
                msg("invalid message");
                tcore_at_tok_free(tokens);
                return TRUE;
        }
-       sim_state = atoi(g_slist_nth_data(tokens, 0));
 
        switch (sim_state) {
        case 0:                                                         // sim state = SIM not present
@@ -1965,8 +2005,24 @@ static gboolean on_event_pin_status(CoreObject *o, const void *event_info, void
 
        switch (sim_status) {
        case SIM_STATUS_INIT_COMPLETED:
-               ur = tcore_user_request_new(NULL, NULL);     // this is for using ur metainfo set/ref functionality.
-               _get_file_info(o, ur, SIM_EF_IMSI);
+               if (tcore_sim_get_type(o) == SIM_TYPE_UNKNOWN)
+                       _get_sim_type(o);
+               else
+                       _sim_status_update(o, sim_status);
+
+               if (sms_state) {
+                       struct tnoti_sms_ready_status readyStatusInfo = {0, };
+                       CoreObject *sms;
+                       TcorePlugin *plugin;
+
+                       dbg("SMS Ready");
+                       readyStatusInfo.status = TRUE;
+                       plugin = tcore_object_ref_plugin(o);
+                       sms = tcore_plugin_ref_core_object(plugin, CORE_OBJECT_TYPE_SMS);
+                       tcore_sms_set_ready_status(sms, readyStatusInfo.status);
+
+                       tcore_server_send_notification(tcore_plugin_ref_server(plugin), sms, TNOTI_SMS_DEVICE_READY, sizeof(struct tnoti_sms_ready_status), &readyStatusInfo);
+               }
                break;
 
        case SIM_STATUS_INITIALIZING:
@@ -1978,17 +2034,7 @@ static gboolean on_event_pin_status(CoreObject *o, const void *event_info, void
        case SIM_STATUS_SPCK_REQUIRED:
        case SIM_STATUS_CCK_REQUIRED:
        case SIM_STATUS_LOCK_REQUIRED:
-               if (sp->first_recv_status == SIM_STATUS_UNKNOWN) {
-                       dbg("first received sim status[%d]", sim_status);
-                       sp->first_recv_status = sim_status;
-                       _get_sim_type(o);
-               } else {
-                       dbg("second or later received lock status[%d]", sim_status);
-                       if (tcore_sim_get_status(o) != SIM_STATUS_INIT_COMPLETED) {
-                               dbg("sim is not init complete in telephony side yet");
-                               _sim_status_update(o, sim_status);
-                       }
-               }
+               _sim_status_update(o, sim_status);
                break;
 
        case SIM_STATUS_CARD_REMOVED:
@@ -1998,6 +2044,8 @@ static gboolean on_event_pin_status(CoreObject *o, const void *event_info, void
                        dbg("[SIM]SIM CARD REMOVED!!");
                        sim_status = SIM_STATUS_CARD_REMOVED;
                }
+
+               tcore_sim_set_type(o, SIM_TYPE_UNKNOWN);
                _sim_status_update(o, sim_status);
                break;
 
@@ -2013,6 +2061,42 @@ OUT:
        return TRUE;
 }
 
+static void on_response_get_sim_status(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+       const TcoreATResponse *resp = data;
+       CoreObject *co_sim = NULL;
+
+       dbg(" Function entry ");
+
+       co_sim = tcore_pending_ref_core_object(p);
+
+       if (resp->success > 0) {
+               dbg("RESPONSE OK");
+               if (resp->lines)
+                       on_event_pin_status(co_sim, resp->lines, NULL);
+       } else {
+               dbg("RESPONSE NOK");
+       }
+
+       dbg(" Function exit");
+}
+
+static enum tcore_hook_return on_hook_modem_power(Server *s, CoreObject *source, enum tcore_notification_command command,
+                                                                                          unsigned int data_len, void *data, void *user_data)
+{
+       TcorePlugin *plugin = tcore_object_ref_plugin(source);
+       CoreObject *co_sim = tcore_plugin_ref_core_object(plugin, CORE_OBJECT_TYPE_SIM);
+
+       if (co_sim == NULL)
+               return TCORE_HOOK_RETURN_CONTINUE;
+
+       dbg("Get SIM status");
+       
+       sim_prepare_and_send_pending_request(co_sim, "AT+XSIMSTATE?", "+XSIMSTATE:", TCORE_AT_SINGLELINE, on_response_get_sim_status);
+
+       return TCORE_HOOK_RETURN_CONTINUE;
+}
+
 static void on_response_verify_pins(TcorePending *p, int data_len, const void *data, void *user_data)
 {
        const TcoreATResponse *resp = data;
@@ -2156,22 +2240,15 @@ static void on_response_get_facility_status(TcorePending *p, int data_len, const
 {
        const TcoreATResponse *resp = data;
        UserRequest *ur = NULL;
-       CoreObject *co_sim = NULL;
-       struct s_sim_property *sp = NULL;
        GSList *tokens = NULL;
-       struct tresp_sim_get_facility_status res;
+       struct tresp_sim_get_facility_status *res = user_data;
        const char *line;
 
        dbg(" Function entry ");
 
-       co_sim = tcore_pending_ref_core_object(p);
-       sp = tcore_sim_ref_userdata(co_sim);
        ur = tcore_pending_ref_user_request(p);
 
-       memset(&res, 0, sizeof(struct tresp_sim_get_facility_status));
-
-       res.result = SIM_INCOMPATIBLE_PIN_OPERATION;
-       res.type = _sim_get_current_pin_facility(sp->current_sec_op);
+       res->result = SIM_PIN_OPERATION_SUCCESS;
 
        if (resp->success > 0) {
                dbg("RESPONSE OK");
@@ -2180,19 +2257,22 @@ static void on_response_get_facility_status(TcorePending *p, int data_len, const
                        tokens = tcore_at_tok_new(line);
                        if (g_slist_length(tokens) != 1) {
                                msg("invalid message");
-                               goto OUT;
+                               tcore_at_tok_free(tokens);
+                               return;
                        }
                }
-               res.b_enable = atoi(g_slist_nth_data(tokens, 0));
+               res->b_enable = atoi(g_slist_nth_data(tokens, 0));
        } else {
                dbg("RESPONSE NOK");
+               res->result = SIM_INCOMPATIBLE_PIN_OPERATION;
        }
-OUT:
+
        if (ur) {
                tcore_user_request_send_response(ur, _find_resp_command(ur),
-                                                                                sizeof(struct tresp_sim_get_facility_status), &res);
+                                                                                sizeof(struct tresp_sim_get_facility_status), res);
        }
        tcore_at_tok_free(tokens);
+       g_free(res);
        dbg(" Function exit");
 }
 
@@ -2725,6 +2805,7 @@ static TReturn s_get_facility_status(CoreObject *o, UserRequest *ur)
        TcorePending *pending = NULL;
        char *cmd_str = NULL;
        const struct treq_sim_get_facility_status *req_data;
+       struct tresp_sim_get_facility_status *res;
        char *fac = "SC";
        int mode = 2;       /* 0:unlock, 1:lock, 2:query*/
        TReturn ret = TCORE_RETURN_FAILURE;
@@ -2743,6 +2824,12 @@ static TReturn s_get_facility_status(CoreObject *o, UserRequest *ur)
        pending = tcore_pending_new(o, 0);
        req_data = tcore_user_request_ref_data(ur, NULL);
 
+       res = g_try_new0(struct tresp_sim_get_facility_status, 1);
+       if (!res)
+               return TCORE_RETURN_ENOMEM;
+
+       res->type = req_data->type;
+
        if (req_data->type == SIM_FACILITY_PS) {
                fac = "PS";                             /*PH-SIM, Lock PHone to SIM/UICC card*/
        } else if (req_data->type == SIM_FACILITY_SC) {
@@ -2766,7 +2853,7 @@ static TReturn s_get_facility_status(CoreObject *o, UserRequest *ur)
        dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
 
        tcore_pending_set_request_data(pending, 0, req);
-       tcore_pending_set_response_callback(pending, on_response_get_facility_status, hal);
+       tcore_pending_set_response_callback(pending, on_response_get_facility_status, res);
        tcore_pending_link_user_request(pending, ur);
        ret = tcore_hal_send_request(hal, pending);
 
@@ -2907,7 +2994,75 @@ static TReturn s_disable_facility(CoreObject *o, UserRequest *ur)
        return ret;
 }
 
-static TReturn s_get_lock_info(CoreObject *o, UserRequest *ur)
+static TReturn s_get_lock_info_n(CoreObject *o, UserRequest *ur)
+{
+       TcoreHal *hal = NULL;
+       TcoreATRequest *req = NULL;
+       TcorePending *pending = NULL;
+       char *cmd_str = NULL;
+       int lock_type = 0;
+       const struct treq_sim_get_lock_info *req_data;
+       struct s_sim_property *sp = NULL;
+
+       dbg(" Function entry ");
+
+       hal = tcore_object_get_hal(o);
+
+       sp = tcore_sim_ref_userdata(o);
+       pending = tcore_pending_new(o, 0);
+       req_data = tcore_user_request_ref_data(ur, NULL);
+
+       if (!o || !ur)
+               return TCORE_RETURN_EINVAL;
+
+       switch (req_data->type) {
+       case SIM_FACILITY_PS:
+               lock_type = 9; // IMSI lock
+               break;
+
+       case SIM_FACILITY_SC:
+               lock_type = 1;
+               break;
+
+       case SIM_FACILITY_FD:
+               lock_type = 2;
+               break;
+
+       case SIM_FACILITY_PN:
+               lock_type = 5;
+               break;
+
+       case SIM_FACILITY_PU:
+               lock_type = 6;
+               break;
+
+       case SIM_FACILITY_PP:
+               lock_type = 7;
+               break;
+
+       case SIM_FACILITY_PC:
+               lock_type = 8;
+               break;
+
+       default:
+               break;
+       }
+       cmd_str = g_strdup_printf("AT+XPINCNT =%d", lock_type);
+       req = tcore_at_request_new(cmd_str, "+XPINCNT:", TCORE_AT_SINGLELINE);
+
+       dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
+
+       tcore_pending_set_request_data(pending, 0, req);
+       tcore_pending_set_response_callback(pending, on_response_get_lock_info, hal);
+       tcore_pending_link_user_request(pending, ur);
+       tcore_hal_send_request(hal, pending);
+
+       free(cmd_str);
+       dbg(" Function exit");
+       return TCORE_RETURN_SUCCESS;
+}
+
+static TReturn s_get_lock_info_str(CoreObject *o, UserRequest *ur)
 {
        TcoreHal *hal = NULL;
        TcoreATRequest *req = NULL;
@@ -2923,10 +3078,7 @@ static TReturn s_get_lock_info(CoreObject *o, UserRequest *ur)
                return TCORE_RETURN_EINVAL;
 
        hal = tcore_object_get_hal(o);
-       if(FALSE == tcore_hal_get_power_state(hal)){
-               dbg("cp not ready/n");
-               return TCORE_RETURN_ENOSYS;
-       }
+
        pending = tcore_pending_new(o, 0);
        req_data = tcore_user_request_ref_data(ur, NULL);
 
@@ -2977,6 +3129,17 @@ static TReturn s_get_lock_info(CoreObject *o, UserRequest *ur)
        return ret;
 }
 
+static TReturn s_get_lock_info(CoreObject *o, UserRequest *ur)
+{
+       TcorePlugin *plugin = tcore_object_ref_plugin(o);
+       const char *cpname = tcore_server_get_cp_name_by_plugin(plugin);
+
+       if (g_str_has_prefix(cpname, "mfld_blackbay") == TRUE)
+               return s_get_lock_info_n(o, ur);
+       else
+               return s_get_lock_info_str(o, ur);
+}
+
 static TReturn s_read_file(CoreObject *o, UserRequest *ur)
 {
        TReturn api_ret = TCORE_RETURN_SUCCESS;
@@ -3327,6 +3490,8 @@ gboolean s_sim_init(TcorePlugin *cp, CoreObject *co_sim)
        tcore_object_override_callback(co_sim, "+XLOCK", on_event_facility_lock_status, NULL);
        tcore_object_override_callback(co_sim, "+XSIM", on_event_pin_status, NULL);
 
+       tcore_server_add_notification_hook(tcore_plugin_ref_server(cp), TNOTI_MODEM_POWER, on_hook_modem_power, co_sim);
+
        dbg("Exit");
 
        return TRUE;