Exemple #1
0
/*****************************************************************************
 * FUNCTION
 *  phb_search_handler
 * DESCRIPTION
 *  This is phb_search_handler function of PHB module.
 *  Handles write request from L4C.
 * PARAMETERS
 *  ilm_ptr             [IN]        The primitives
 *  control_block       [?]         
 * RETURNS
 *  void
 *****************************************************************************/
void phb_search_handler(ilm_struct *ilm_ptr, control_block_type *control_block)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/

    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    kal_trace(TRACE_FUNC, FUNC_PHB_SEARCH);

    if (ilm_ptr != NULL)
    {
        l4cphb_search_req_struct *l4cphb_search_req;

        l4cphb_search_req = (l4cphb_search_req_struct*) ilm_ptr->local_para_ptr;

        /* Cannot allocate, means that PHB is still operating. Reject request! */
        control_block = phb_alloc_control_block();
        if (control_block == NULL)
        {
            phb_search_confirm(PHB_ERRNO_BUSY, 0, l4cphb_search_req->src_id, MSG_ID_INVALID_TYPE, control_block);
            return;
        }

        control_block->src_id = l4cphb_search_req->src_id;

        /* Retain msg_id */
        control_block->cnf_msg_id = ilm_ptr->msg_id;

        if ((phb_ptr->state == PHB_STATE_READY) &&
            ((l4cphb_search_req->type == PHB_PHONEBOOK) ||
             (l4cphb_search_req->type == PHB_FDN) ||
             (l4cphb_search_req->type == PHB_BDN)) && ((l4cphb_search_req->pattern_tag == PHB_BYNAME) ||
    #ifdef __PHB_SORT_ENABLE__
                                                       (l4cphb_search_req->pattern_tag == PHB_BYNAME_EXACT) ||
    #endif 
                                                       (l4cphb_search_req->pattern_tag == PHB_BYNUMBER)))
        {
            if (control_block->proc_stage == SEARCH_NONE)
            {
                kal_bool is_more_candidates;
                l4_name_struct *alpha_id;

            #ifdef __PHB_SORT_ENABLE__
                l4_addr_bcd_struct *tel_number;
            #endif 

            /**
             * Here we borrow total_piggyback to store pattern_tag.
             * When used!?
             */
                /* control_block->total_piggyback = l4cphb_search_req->pattern_tag; */
                control_block->total_piggyback = l4cphb_search_req->total;

                /* Search by name, valid for both of PHB_PHONEBOOK, PHB_FDN and PHB_BDN */
                if ((l4cphb_search_req->pattern_tag == PHB_BYNAME) ||
                    (l4cphb_search_req->pattern_tag == PHB_BYNAME_EXACT))
                {
                    alpha_id = &l4cphb_search_req->pattern_value.alpha_id;
                    control_block->candidate_name_num_index = phb_se_search_by_name(
                                                                l4cphb_search_req->type,
                                                                (alpha_id_type*) alpha_id,
                                                                &control_block->candidate,
                                                                &is_more_candidates);

               /**
                * For SEARCH_BYNAME, no candidate is impossible.
                * Because a nearest one is always found,
                * therefore candidate_count is at least 1.
                */
                }

            #ifdef __PHB_SORT_ENABLE__
                /* Search by telephone number, only valid for PHB_PHONEBOOK */
                else if ((l4cphb_search_req->pattern_tag == PHB_BYNUMBER) && (l4cphb_search_req->type == PHB_PHONEBOOK))
                {
                    tel_number = &l4cphb_search_req->pattern_value.tel_number;
                    control_block->candidate_name_num_index = phb_se_search_by_tel_num(
                                                                l4cphb_search_req->type,
                                                                tel_number,
                                                                &control_block->candidate,
                                                                &is_more_candidates);

                }
            #endif /* __PHB_SORT_ENABLE__ */ 
                /* Illegal comination of parameters. */
                else
                {
                    phb_search_err_handler(NULL, control_block);
                    return;
                }

                /* Search telephone number in phonebook: nvram_ef_phb_lid and ADN */

                /* No candidate, great!! */
                if ((control_block->candidate == (kal_uint16) PHB_INVALID_VALUE) ||
                    (control_block->candidate_name_num_index == NULL))
                {
                    control_block->actual_count = 0;
                    phb_search_confirm(
                        PHB_ERRNO_SUCCESS,
                        control_block->actual_count,
                        control_block->src_id,
                        control_block->cnf_msg_id,
                        control_block);
                    return;
                }

                /* Exactly only one candidate is found! Great!! */
            /**
             * Q: The query pattern may exceeds ALPHA_ID_DEPTH,
             *   why NOT exact match alpha_id, then retrieves the following
             *   entries begun from the index to that one?
             *
             * A: Though exact matching is possible, retrieves from that index is
             *   non-sense, because the sorted array is not precise, that means
             *   the following entries begun from that index could be erroneous.
             */
                if (l4cphb_search_req->pattern_tag == PHB_BYNAME)
                {
                    kal_uint16 index;

               /**
                * Search BYNAME, if alpha_id.name_length <= PHB_ALPHA_ID_DEPTH,
                * then there must be exactly one nearest hit!
                *
                * Note: hit must start from 1.
                */
                    index = control_block->candidate;

                    if (l4cphb_search_req->total < 1)
                    {
                        l4cphb_search_req->total = 1;
                    }

                    phb_control_block_set_IO(control_block, l4cphb_search_req->type, ++index, l4cphb_search_req->total);

                    if (phb_se_is_in_range(control_block->type, index, &control_block->total) == KAL_FALSE)
                    {
                        control_block->actual_count = 0;
                        phb_search_confirm(
                            PHB_ERRNO_FAIL,
                            control_block->actual_count,
                            control_block->src_id,
                            control_block->cnf_msg_id,
                            control_block);
                        return;
                    }

                    /* Piggyback is ALWAYS required. */

               /**
                * Now we have to transform the state to a *FAKE* read state.
                * The fakes status ALWAYS read from index, instead of specific record.
                */

                    /* If any critial error occured. read_err_handler will handle it. */
                    if (phb_read_fake(control_block, NULL) == KAL_FALSE)
                    {
                        return;
                    }

                    /* Finally, faking complete....Now continue reading */
                    phb_read_continue(NULL, control_block);
                    return;
                }
            #ifdef __PHB_SORT_ENABLE__
                else if (l4cphb_search_req->pattern_tag == PHB_BYNAME_EXACT)
                {
                    kal_uint16 i, start, count = 0;
                    pindex_type *name_index;
                    data_entry_table_type *desc_table;

                    if (l4cphb_search_req->type == PHB_PHONEBOOK)
                    {
                        control_block->type = l4cphb_search_req->type;
                        name_index = (pindex_type*) & phb_ptr->indices.phb_index.name_index;
                        desc_table = (data_entry_table_type*) & phb_ptr->indices.phb_index.data_entry_table;
                    }
                    else
                    {
                        control_block->actual_count = 0;
                        phb_search_confirm(
                            PHB_ERRNO_FAIL,
                            control_block->actual_count,
                            control_block->src_id,
                            control_block->cnf_msg_id,
                            control_block);
                        return;
                    }

                    for (i = control_block->candidate; i < name_index->used_count; i++)
                        if (phb_is_prefix(
                                (alpha_id_type*) & l4cphb_search_req->pattern_value.alpha_id,
                                (alpha_id_type*) & desc_table->table[name_index->table[i].position]. alpha_id))
                        {
                            break;
                        }

                    if (i == name_index->used_count)
                    {
                        /* NOT found any match */
                        control_block->actual_count = 0;
                        phb_search_confirm(
                            PHB_ERRNO_SUCCESS,
                            control_block->actual_count,
                            control_block->src_id,
                            control_block->cnf_msg_id,
                            control_block);
                        return;
                    }
                    count++;
                    start = i;
                    for (i = start + 1; i < name_index->used_count; i++)
                        if (phb_is_prefix(
                                (alpha_id_type*) & l4cphb_search_req->pattern_value.alpha_id,
                                (alpha_id_type*) & desc_table->table[name_index->table[i].position]. alpha_id))
                        {
                            count++;
                        }
                    /* total "count" matches starting from "start" */

                    control_block->index = start + 1;
                    control_block->record_index = (kal_uint16) PHB_INVALID_VALUE;
                    if (count > 15)
                    {
                        count = 15;
                    }
                    control_block->total = count;
                    /* If any critial error occured. read_err_handler will handle it. */
                    if (phb_read_fake(control_block, NULL) == KAL_FALSE)
                    {
                        return;
                    }

                    /* Finally, faking complete....Now continue reading */
                    phb_read_continue(NULL, control_block);
                    return;
                }
            #endif /* __PHB_SORT_ENABLE__ */ 

                /* For PHB_BYNAME, more than 1 candidate exists, sigh, verification is necessary */

            /**
             * Even only exactly one candidate is found for searching BYNUMBER,
             * verification is still needed.
             */

            /**
             * Only search of PHB_BYNUMBER can reach here.
             *
             * Candidates of searching telephone number are selected.
             * Now verify them. So lousy..
             */

            /**
             * Initialize hit and same_count of control_block, also
             * increment index to candidate, since it begins from 1.
             */
                control_block->match_result = MATCH_FAIL;

                phb_search_fake(
                    control_block,
                    ilm_ptr,
                    l4cphb_search_req->type,
                    &l4cphb_search_req->pattern_value.tel_number);

                phb_search_continue(NULL, control_block);
            }
            /* error */
            else
            {
                phb_search_err_handler(NULL, control_block);
                return;
            }
        }
        /* error, either STATE_NOT_READY or incorrect type requested for searching */
        else
        {
            kal_trace(TRACE_ERROR, ERROR_PHB_STATE);

            if (phb_ptr->state != PHB_STATE_READY)
            {
                control_block->actual_count = 0;
                phb_search_confirm(
                    PHB_ERRNO_NOT_READY,
                    control_block->actual_count,
                    control_block->src_id,
                    control_block->cnf_msg_id,
                    control_block);
            }
            else
            {
                phb_search_err_handler(NULL, control_block);
            }
            return;
        }

    }
    else
    {
        /* Verification over. */
        if (control_block->proc_stage == SEARCH_CONTINUE)
        {
         /**
          * Only search of PHB_BYNUMBER can reach here.
          * And no piggyback is provided, so confirmation can be sent back now.
          * Hence, if found, actual_count is 1 and will be transfered to `total' field of
          * confirmation primitive; otherwise it is 0.
          */

            /* No candidate matches! */
            if (control_block->actual_count == 0)
            {
                control_block->actual_count = 0;
                phb_search_confirm(
                    PHB_ERRNO_FAIL,
                    control_block->actual_count,
                    control_block->src_id,
                    control_block->cnf_msg_id,
                    control_block);
            }
            else
            {
                name_num_index_type *name_num_index = (name_num_index_type*) control_block->candidate_name_num_index;
                data_entry_struct *data_entry;
                l4cphb_phb_entry_array_struct *phb_entry_array;

                kal_uint8 *pdu_ptr;
                kal_uint16 pdu_length;

                data_entry =
                    &name_num_index->data_entry_table.table[name_num_index->num_index.table[control_block->candidate].
                                                            position];
            /**
             * To reduce code size, another possible function which
             * searches index to name_index by index to num_index
             * is not implemented .
             */
                pdu_ptr = get_pdu_ptr(control_block->peer_buf_ptr, &pdu_length);
                phb_entry_array = ((l4cphb_phb_entry_array_struct*) get_32bits_aligned_val(pdu_ptr));
                phb_entry_array->array[0].index = phb_se_search_by_record_index_name(
                                                    control_block->type,
                                                    data_entry->storage,
                                                    data_entry->record_index,
                                                    &data_entry->alpha_id);
                phb_entry_array->array[0].index++;
                control_block->actual_count = 1;
                phb_search_confirm(
                    PHB_ERRNO_SUCCESS,
                    control_block->actual_count,
                    control_block->src_id,
                    control_block->cnf_msg_id,
                    control_block);
            }
        }
        /* error */
        else
        {
            phb_search_err_handler(NULL, control_block);
            return;
        }
    }
}   /* end of phb_search_handler */
/*****************************************************************************
 * FUNCTION
 *  phb_sat_file_change_handler
 * DESCRIPTION
 *  In current implementation, all related EF's will be rescanned.
 *  Hence, actually the file_change request will be forwarded to
 *  startup_handler().
 * PARAMETERS
 *  ilm_ptr             [IN]        The primitives
 *  control_block       [?]         
 * RETURNS
 *  void
 *****************************************************************************/
void phb_sat_file_change_handler(ilm_struct *ilm_ptr, control_block_type *control_block)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/

    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    kal_trace(TRACE_FUNC, FUNC_PHB_SAT_FILE_CHANGE);

    if (ilm_ptr != NULL)
    {
        kal_uint16 i;
        kal_bool need_reset_flag = KAL_FALSE;
        sat_file_change_ind_struct *sat_file_change_ind;

        sat_file_change_ind = (sat_file_change_ind_struct*) ilm_ptr->local_para_ptr;

      /**
       * Since sat_file_change is an implicit reset, there 2 ways to implement this:
       *
       * 1. Interrupts other being processed operations and forbids 
       *   other further requests to PHB, except approve and search:
       *   In this implementation, 
       *   startup handler should always uses the first control_block, 
       *   and lock all control_blocks are locked temporarily;
       *   thus prevent other operations, except approve and search, 
       *   from accessing PHB while it is busy.
       *
       * 2. Allow all other operations to provide maximum possible
       *   concurrency degrees.
       *
       * Curretly, solution 1 is implemented.
       * Control_blocks are all locked to interrupt all other in-processing
       * operations and reject all further requests, to prevent
       * multiple access to PHB when it is not ready.
       */
        /* LN not ready means phb haven't been inited yet */
        if (phb_ptr->state == PHB_STATE_LN_NOT_READY)
        {
        }
        else if (sat_file_change_ind->is_full_changed)
        {
            need_reset_flag = KAL_TRUE;
        }
        else
        {
            for (i = 0; i < sat_file_change_ind->num_of_file; i++)
            {
                switch (sat_file_change_ind->file_list[i])
                {
                    case FILE_ADN_IDX:
                    case FILE_ECC_IDX:
                    case FILE_EXT1_IDX:                       
                #ifdef __PHB_USIM_SUPPORT__
                       need_reset_flag = KAL_TRUE;
                       /* MUST: Break CAN'T BE REMOVED */
                       break;                   
                    case FILE_U_ECC_IDX:
                        
                    case FILE_G_ADN_IDX:
                    case FILE_U_ADN_IDX:
                        
                    case FILE_G_PBR_IDX:
                    case FILE_U_PBR_IDX:
                        
                    case FILE_G_EXT1_IDX:
                    case FILE_U_EXT1_IDX:
                        
                    case FILE_U_FDN_IDX:
                    case FILE_U_SDN_IDX:
                    case FILE_U_EXT2_IDX:
                    case FILE_U_EXT3_IDX:
                    case FILE_U_BDN_IDX:
                    case FILE_U_EXT4_IDX:
                    case FILE_U_MSISDN_IDX:
                    case FILE_U_EXT5_IDX:
                #ifdef __PHB_USIM_ADDITIONAL_SUPPORT__
                    case FILE_G_IAP_IDX:
                    case FILE_U_IAP_IDX:
                        
                    case FILE_G_ANR_IDX:
                    case FILE_U_ANR_IDX:
                        
                    case FILE_G_EMAIL_IDX:
                    case FILE_U_EMAIL_IDX:
                        
                    case FILE_G_SNE_IDX:
                    case FILE_U_SNE_IDX:
                        
                    case FILE_G_GAS_IDX:
                    case FILE_U_GAS_IDX:
                        
                    case FILE_G_AAS_IDX:
                    case FILE_U_AAS_IDX:
                        
                    case FILE_G_GRP_IDX:
                    case FILE_U_GRP_IDX:
                #endif /* __PHB_USIM_ADDITIONAL_SUPPORT__ */
                       ASSERT(is_usim_type(PHB_WHICH_SIM));
                #endif /* __PHB_USIM_SUPPORT__ */
                    case FILE_FDN_IDX:
                    case FILE_SDN_IDX:
                    case FILE_EXT2_IDX:
                    case FILE_EXT3_IDX:
                    case FILE_BDN_IDX:
                    case FILE_EXT4_IDX:
                    case FILE_MSISDN_IDX:
                        need_reset_flag = KAL_TRUE;
                        break;
                    default:
                        break;
                }
            }
        }
        if (need_reset_flag)
        {
            for (i = 0; i < PHB_CONCURRENCY_DEGREE; i++)
            {
                if (phb_ptr->control_block[i].is_allocated == KAL_TRUE)
                {
                    phb_ptr->control_block[i].err_handler(NULL, &(phb_ptr->control_block[i]));
                }
            }

            phb_reset_all_control_blocks();
            control_block = phb_alloc_control_block();
            
            ASSERT(control_block != NULL);

            control_block->src_id = sat_file_change_ind->src_id;
            /* Retain msg_id */
            control_block->cnf_msg_id = ilm_ptr->msg_id;

            phb_is_sim_file_support();
        }
        phb_ptr->dn_type = l4csmu_get_dial_mode();

        if (need_reset_flag == KAL_FALSE)
        {
            phb_sat_file_change_confirm(PHB_ERRNO_SUCCESS, sat_file_change_ind->src_id, NULL);
        }
        else if ((phb_ptr->state == PHB_STATE_READY) ||
                 (phb_ptr->state == PHB_STATE_NOT_READY_FDN_READY) || (phb_ptr->state == PHB_STATE_NOT_READY))
        {
         /** 
          * Assume data descriptor obtained from nvram_get_infor() and
          * sim_service_table_query() remains consistent, DO NOT reset it.
          * What needs to be reset is their free_count!
          */
            phb_data_desc_reset();
            
            phb_se_reset();

            /* Reset context */
            kal_mem_set(&phb_ptr->ecc, 0, sizeof(sim_ecc_struct));
            phb_ptr->state = PHB_STATE_NOT_READY;
        #ifdef __PHB_USIM_SUPPORT__
            phb_ptr->is_global = KAL_TRUE;
        #endif
            kal_trace(TRACE_STATE, STATE_PHB_NOT_READY);

            // TODO: need to be able to reload specific files
            /*  
             *  Since SIM file changed, need to reload file info, and MMI also need to reload
             *  send begin inication to MMI, MMI will clear it's variable and reload phonebook.
             */
            {
            #if !defined(__PHB_STORAGE_BY_MMI__)
                kal_uint16 phb_total, phb_size;

                if (nvram_get_info(NVRAM_EF_PHB_LID, &phb_total, &phb_size) == NVRAM_ERRNO_SUCCESS)
                {
                    phb_data_desc_set_is_support(DATA_DESC_PHB, KAL_TRUE);

                /*
                 * MAX_ENTRIES_COUNT must NOT be exceeded. See comment
                 * of phb_get_info_set_value() for detail.
                 */
                    if (phb_total > NVRAM_PHB_INDEX_MAX_ENTRIES_COUNT)
                    {
                        phb_total = NVRAM_PHB_INDEX_MAX_ENTRIES_COUNT;
                    }
                    phb_data_desc_set(DATA_DESC_PHB, phb_total, phb_size);
                }
                else
            #endif /* __PHB_STORAGE_BY_MMI__ */
                {
                    phb_data_desc_set_is_support(DATA_DESC_PHB, KAL_FALSE);
                }
            }
            /* phb_get_info() will return to startup_handler() */
            control_block->proc_stage = startup_none;

        #if defined(__GEMINI__) || defined(GEMINI_PLUS)
            l4csmu_get_chv_info_status(NULL, &chv_status[phb_current_mod - MOD_PHB]);
            phb_query_count[phb_current_mod - MOD_PHB] = 0;
        #else
            l4csmu_get_chv_info_status(NULL, &chv_status[0]);
            phb_query_count[0] = 0;
        #endif
        
            phb_send_ilm(MOD_L4C, MSG_ID_L4CPHB_STARTUP_BEGIN_IND, NULL, NULL);
            
            phb_get_info(ilm_ptr, control_block);
            
        }
        /* error */
        else
        {
            kal_trace(TRACE_ERROR, ERROR_PHB_STATE);

            phb_sat_file_change_confirm(PHB_ERRNO_FAIL, control_block->src_id, control_block);
            return;
        }

    }
    else
    {
        kal_trace(TRACE_ERROR, ERROR_PHB_STATE);

        control_block->cnf_msg_id = MSG_ID_SAT_FILE_CHANGE_IND;
        phb_sat_file_change_confirm(PHB_ERRNO_FAIL, control_block->src_id, control_block);
        return;
    }
}   /* end of phb_sat_file_change_handler function */