Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1502118
  • 博文数量: 213
  • 博客积分: 10418
  • 博客等级: 上将
  • 技术积分: 3358
  • 用 户 组: 普通用户
  • 注册时间: 2008-04-09 23:49
文章分类

全部博文(213)

文章存档

2014年(1)

2013年(5)

2012年(11)

2011年(2)

2010年(8)

2009年(26)

2008年(160)

分类:

2009-05-26 19:54:01

一、开机流程

开机之后,初始化时,在InitializeAll()中call mmi_phb_init_protocol(),设置如下几个PS消息CBack函数:

SetProtocolEventHandler(mmi_phb_ind_startup_finish, PRT_PHB_STARTUP_FINISH_IND);

SetProtocolEventHandler(mmi_phb_ind_startup_begin, PRT_PHB_STARTUP_BEGIN_IND);

SetProtocolEventHandler(mmi_phb_ind_startup_read, PRT_PHB_STARTUP_READ_IND);

 

 

1.L4在到NVRAM读取data之前,发送消息到MMI:PRT_PHB_STARTUP_BEGIN_IND,进入:

mmi_phb_ind_startup_begin()

       初始化一些变量,准备重新reload entries.

 

2.L4每读取一个AND entry,都有发送消息到MMI:PRT_PHB_STARTUP_READ_IND,进入:
       L4返回消息的结构:

       typedef struct

       {

              LOCAL_PARA_HDR

              l4c_phb_entries_struct phb_entries[1];

              kal_uint8       access_id;

       } mmi_phb_startup_read_ind_struct;

       typedef struct

       {

              kal_uint16 num_of_entry;

              l4c_phb_bcd_entry_struct  phb_entry[2000/NVRAM_PHB_SIZE];

       } l4c_phb_entries_struct;

       typedef struct {

           kal_uint8 storage;

           kal_uint8 type;

           kal_uint16 index;

           kal_uint16 record_index;

           l4_addr_bcd_struct tel;

           l4_name_struct alpha_id;

       } l4c_phb_bcd_entry_struct;

 

       MMI中,保存电话entries的全局变量PhoneBook结构如下:

       MMI_PHB_ENTRY_BCD_STRUCT PhoneBook[MAX_PB_ENTRIES];

       typedef struct

       {

          //U8         storage;

         //U8         type;

          //U16                index;

          //U16                record_index;

          MMI_PHB_NUMBER_BCD_STRUCT tel;

          MMI_PHB_NAME_STRUCT alpha_id;

          U8 field;   /* Indicate if an entry has the field */

          U8 dummy;   /* Make sure each phb structure is two-bytes aligned. */

       } MMI_PHB_ENTRY_BCD_STRUCT;

 

       typedef struct

       {

          U8 type;                                    /* 129-default; 145-international, begin with ''+'' */

          U8 length;

          U8 number[(MAX_PB_NUMBER_LENGTH + 1) / 2];  /* half space to store BCD format. */

       } MMI_PHB_NUMBER_BCD_STRUCT;

 

       typedef struct

       {

          U8 name_length; /* Name Length */

          U8 name_dcs;    /* Name Data Coding Scheme */

          U8 name[(MAX_PB_NAME_LENGTH + 1) *ENCODING_LENGTH];

       } MMI_PHB_NAME_STRUCT;

 

 

       mmi_phb_ind_startup_read()

               mmi_phb_ind_startup_read_next_req(LocalPtr->access_id);

                     MMI发消息到PRT_PHB_STARTUP_READ_NEXT_REQL4,请求read next。

               //假定是读取NVRAM中的entry

               for (i = 0; i < LocalPtr->phb_entries[0].num_of_entry; i++)

        {

            g_phb_cntx.phone_used++;

            store_index = LocalPtr->phb_entries[0].phb_entry[i].record_index - 1;       /* Storage Location in array. */

            MMI_ASSERT((g_phb_cntx.phone_used <= MAX_PB_PHONE_ENTRIES) && (store_index < MAX_PB_PHONE_ENTRIES));

            mmi_phb_startup_read_entry(LocalPtr->phb_entries[0].phb_entry[i], store_index);

        }

 

       mmi_phb_startup_read_entry()    把消息保存到全局变量PhoneBook中。

              信息保存在PhoneBook[store_index]中。可见:PhoneBook[]中的存储顺序就是L4中的存储顺序。

              PhoneBook[store_index].tel.number中保存的是ASCII码。

 

              //根据号码的第一个位置来设置是SIM entry还是NVRAM entry.

              PhoneBook[store_index].field = 0;

         if (PhoneBook[store_index].tel.number[0] != 0xff)

          {

             PhoneBook[store_index].field |= MMI_PHB_ENTRY_FIELD_NUMBER;

          }
             

              g_phb_name_index[PhoneBookEntryCount] = store_index;        姓名列表,保存的是PhoneBook中entry的位置

          PhoneBookEntryCount++;

 

3.当L4从NVRAM中读取完之后,发送消息PRT_PHB_STARTUP_FINISH_IND到MMI,表示L4已经读完了。MMI接收到这个消息之后,开始load all entries from L4。

返回的消息结构:

       typedef struct

       {

              LOCAL_PARA_HDR

              kal_uint16     sim_max_num;

              kal_uint16     phb_max_num;

              kal_uint8       phb_len;

              kal_uint8       fdn_len;

              kal_uint8       bdn_len;

              kal_uint8       owner_len;

       } mmi_phb_startup_finish_ind_struct;

 

       mi_phb_ind_startup_finish()

              //初始化g_phb_cntx中的结构

               g_phb_cntx.sim_name_len = localPtr->phb_len;

        g_phb_cntx.fdn_name_len = localPtr->fdn_len;

        g_phb_cntx.bdn_name_len = localPtr->bdn_len;

        g_phb_cntx.owner_name_len = localPtr->owner_len;

        g_phb_cntx.sim_total = localPtr->sim_max_num;

        g_phb_cntx.phone_total = localPtr->phb_max_num;

 

               if (!g_phb_cntx.nvram_data_init)

        {

            mmi_phb_init_get_data_from_nvram(); //从NVRAM中读取电话簿的一些信息。比如:群组,栏位设置,存储选择等等。

                                   g_phb_cntx.view_field

                                   g_phb_cntx.prefer_storage

                                   g_phb_cntx.name_list_filter

                                   g_phb_cntx.caller_group

 

            g_phb_cntx.nvram_data_init = TRUE;

        }

 

              mmi_phb_sort_build_name_index();         //sort name list g_phb_name_index。这个函数完成后,PoneBook中所有entries,如果按照g_phb_name_index[]中                                                                                                                        //的值作为顺序来排列的话,将是按照姓名中字母从小到大的顺序。

                     // quick sort and insertion sort g_phb_name_index[]。g_phb_name_index[]中存储的是PhoneBook[]中entries的存储索引。这个函数的过程就是通过                                                                                   //g_phb_name_index[]中的值,找到PhoneBook中相应的entries,然后比较PhoneBook中entries的 name,从而来排列g_phb_name_index的值。

                     mmi_phb_sort_name_fast_quicksort(0, (U16) (PhoneBookEntryCount - 1), mmi_phb_sort_compare_name_index_by_pinyin_cache);

                     mmi_phb_sort_name_insertionsort(left, right, compare);

 

              //当FDN启动之后,AND就不能从SIM卡中读取出来了。就是为了防止未授权拨号

              //当获取到FDN list之后,一定要获取speed dial number。

               if (gSecuritySetupContext.FdlStatus)

        {

            mmi_phb_fdn_get_list_to_ram();    //把FND list拷贝到AND的存储区。

                                   if (g_phb_cntx.sim_used == 0)

                               {

                                  g_phb_fdn_count = 0;

                                  mmi_phb_fdn_get_list_to_ram_req();      

                                                 发送消息PRT_PHB_GET_ENTRY_BY_INDEX_REQ到L4,去读取FDN。

                                                 返回消息PRT_PHB_GET_ENTRY_BY_INDEX_RSP,进入CBack函数:

                                                 mmi_phb_fdn_get_list_to_ram_rsp()

                                                        store_index = g_phb_fdn_count + MAX_PB_PHONE_ENTRIES;  

                                                        把读取的信息保存到PhoneBook[store_index]中。可见:PhoneBook是先保存NVRAM号码,然后是SIM号码。

                                     

                                          /* Retrieve Speed Dial List after retrieve FDN list, because they all use same message. */

                                      PhbGetSpeedDialInfo();

                                   }

                               else

                               {

                                  PhbGetSpeedDialInfo();  /* Retrieve Speed Dial List after retrieve FDN list, because they all use same message. */

                                                 PhbReadSpeedDialNVRAM();        //从NVRAM中读取速拨信息

                                                g_phb_cntx.phb_ready = TRUE;

                                         mmi_phb_init_build_lookup_table(); // builds the lookup table for cross-referencing during MO/MT calls.

                               }

        }

        else

        {

            if (gInsertSimAppFlag == 1)

            {

                g_phb_cntx.phb_ready = TRUE;

                mmi_phb_init_build_lookup_table();

                                          mmi_phb_util_read_compare_length()//获取g_phb_compare_length,即需要比较的号码最后几位

                                          把PhoneBook中以g_phb_name_index[]中的内容为索引的entry的号码,转换成ASCII码,然后转换成32为int型数据,并保存                                                                                          在全局变量LookUpTable[]中。注意:一并保存的还有store_index也就是该entry在PhoneBook中存储位置。

                                          StartTimer(PHB_READ_OPT_FILED_TIMER, 500, mmi_phb_init_populate_lookup_table);

            }

            else

            {

                PhbGetSpeedDialInfo();

            }

        }

 

500ms之后,定时器溢出,进入:

mmi_phb_init_populate_lookup_table()

       //This function populates the lookup table with home/fax/mobile/office numbers after converting the last 7(or 9) characters of the phone number into digits.

       以g_phb_name_index[]中的内容为索引,到NVRAM中读取option fields数据ReadMultiRecord()。然后把读取的数据保存在LookUpTable[]中。包括:       传真号码,家庭号码,公司号码。每读取10次,就暂停250ms,然后继续读取。

       全部读完之后,进入:mmi_phb_lookup_table_sort( )    All entries populated, begin to sort it。因为在装载电话号码的时候,LookUpTable[]中的内容是按照字母顺装载的,但是在装载NVRAM中的传真,家庭,公司号码时,是按照存储顺序装载的。而这里的排序,是根据电话号码的大小来排序的。

即:按照电话号码的大小,从小到大排列。 当来电的时候,采取对半查找效率就很高了。

 

小结:到这里,就完成了电话簿的初始化。即:

1)从NVRAMSIM卡中读取了数据,并保存在L4中了;

2MMI中的全局变量PhoneBook[]L4中的电话簿已经同步了;

3g_phb_name_index[]中按照字母的大小顺序,存储了每一个entryPhoneBook[]中的存储位置;

4)所有的号码,包括SIM卡,NVRAM,移动电话,家庭,公司,传真号码,都按照大小顺序,存储在LookUpTable[]中了,并且存储在PhoneBook中的存储位置索引。

二、增加一个entry

//这是菜单的初始化函数

void mmi_phb_init(void)

{

    mmi_phb_search_init();

    mmi_phb_operate_single_init();

    mmi_phb_operate_mass_init();

    mmi_phb_caller_group_init();

    mmi_phb_extra_number_init();

    mmi_phb_setting_init();

    PhbInitSpeedDial();

    mmi_phb_stubs_to_others_init();

}

 

mmi_phb_highlight_op_add_entry()

       memset(pbNumber, 0, ENCODING_LENGTH);

    g_phb_cntx.set_done_flag = 0;

 

按下左软件,进入:

mmi_phb_op_add_pre_entry()

       判断是否已经存储满了?

       mmi_phb_util_clear_buffer() //清除一些全局变量

       mmi_phb_entry_op_add_choose_storage() 选择存储位置:SIM, phone

       ShowCategory52Screen( )//根据g_phb_cntx.prefer_storage来判断当前应该默认那个高亮

 

PHONE,高亮:

mmi_phb_highlight_op_add_entry_to_phone()

       g_phb_cntx.selected_storage = MMI_NVRAM;

 

SIM高亮:

mmi_phb_highlight_op_add_entry_to_sim()

       g_phb_cntx.selected_storage = MMI_SIM;

      

按下左软件,SHOW的画面是(全部栏位):

Name                   姓名

Number                电话号码

Home Number     家庭电话

Company Name   公司名称

Email Address      电子信箱

Office Number     公司号码

Fax Number         传真号码

None                    无(生日)

None                    无(大头贴)g_phb_cntx.image_name_list(名称),g_phb_cntx.image_id_list(图片的ID)

None                    无(来电录像)g_phb_cntx.video_name_list(名称),g_phb_cntx.video_id_list(录像ID)

None                    无(来电铃声)g_phb_cntx.ring_tone_name_list(名称),g_phb_cntx.ring_tone_list(铃声ID)

None                    无(用户群组)myCallerGrpnames

 

 

无论选择了哪个存储,都进入:

mmi_phb_entry_op_add_entry()

       if (g_phb_cntx.selected_storage == MMI_SIM)

       {

              g_phbnameLength = g_phb_cntx.sim_name_len;

              g_phbnumberLength = MAX_PB_SIM_NUMBER_LENGTH; //20

       }    

       else

       {

              g_phbnameLength = MAX_PB_NAME_LENGTH;

              g_phbnumberLength = MAX_PB_NUMBER_LENGTH;          //40

       }

 

       很多的初始化操作mmi_phb_op_fill_inline_item()

       InitializeCategory57Screen();

       ShowCategory57Screen

 

高亮响应:mmi_phb_op_edit_highlight_hdlr()

 

按下保存键,进入:

mmi_phb_entry_op_add_entry_confirm()

mmi_phb_op_add_pre_save()

       if (!mmi_phb_op_check_pre_save())       //check输入是否正确:姓名号码是否为空pbName,pbNumber,pbHomeNumber,pbOfficeNumber,pbFaxNumber

    {

        return;

    }

       mmi_phb_op_add_entry_req()    //发送消息到L4保存entry

              mmi_phb_show_in_progress()   //显示消息:正在处理

              mmi_phb_op_set_entry_prepare_name_number(&myMsgPtr->list, pbName, pbNumber);    //装载姓名和号码,没有装载optional fields and IDs。

              发送消息:PRT_PHB_SET_ENTRY_REQ

              SetProtocolEventHandler(mmi_phb_op_add_entry_rsp, PRT_PHB_SET_ENTRY_RSP);

             

 

返回消息后,进入CBACK函数:

mmi_phb_op_add_entry_rsp()

{

       if (localPtr->result.flag == 0) //存储成功

       {

              store_index = mmi_phb_op_get_store_index_and_increase_counter(localPtr->list[0].storage, localPtr->list[0].record_index);

                     // record_index是entry的物理存储位置,从1开始。

                     //store_index是entry在数组PhoneBook中的存储位置,从0开始。

              if (localPtr->list[0].storage == MMI_NVRAM)     //存储在NVRAM

              {

                     mmi_phb_op_update_optional_field(store_index, MMI_NVRAM, 1);      //保存optional field to NVRAM

                            //把用户输入的信息拷贝到中PhoneBookOptionalFields

                            UnicodeToAnsii((PS8) PhoneBookOptionalFields.homeNumber, pbHomeNumber);

                    pfnUnicodeStrcpy((PS8) PhoneBookOptionalFields.companyName, pbCompanyName);

                    UnicodeToAnsii((PS8) PhoneBookOptionalFields.emailAddress, pbEmailAddress);

                    UnicodeToAnsii((PS8) PhoneBookOptionalFields.officeNumber, pbOfficeNumber);

                    UnicodeToAnsii((PS8) PhoneBookOptionalFields.faxNumber, pbFaxNumber);

 

                            //写入到NVRAM。可见:在NVRAM中,也是按照store_index的顺序存储的,与PhoneBook一样。不过是从1开始。

                            WriteRecord( NVRAM_EF_PHB_FIELDS_LID, (U16) (store_index + 1), (void*)&PhoneBookOptionalFields,

                                     OPTIONAL_FIELDS_RECORD_SIZE,  &pError);

 

                            //根据store_index来读取这个entry的optional IDS.

                            optid_record = (store_index / OPTIONAL_IDS_RECORD_TOTAL) + 1;

                        optid_index = store_index - (optid_record - 1) * OPTIONAL_IDS_RECORD_TOTAL;

                        ReadRecord(NVRAM_EF_PHB_IDS_LID, optid_record, (void*)PhbOptIDs, OPTIONAL_IDS_RECORD_SIZE, &pError);

 

                            把g_phb_cntx.image_id_list,g_phb_cntx.selected_grp_index,g_phb_cntx.ring_tone_list信息拷贝到刚刚读取出来的PhbOptIDs中。

                            然后再写入NVRAM中

                            WriteRecord(NVRAM_EF_PHB_IDS_LID, optid_record, PhbOptIDs, OPTIONAL_IDS_RECORD_SIZE, &pError);

             

                     mmi_phb_op_increase_lookup_table( );   //把家庭,公司,传真号码加入到数组LookUpTable[]中。

                     mmi_phb_video_update_by_index(store_index);    //保存来电的video到NVRAM中。

                    

                     UnicodeToAnsii((PS8) num_ascii, (PS8) pbNumber);

              flag += mmi_phb_op_increase_lookup_table(store_index, (S8*) num_ascii, NULL, NULL, NULL);  //把电话加入LookUpTable[]中。

                     mmi_phb_lookup_table_sort()     ;//对数组LookUpTable[]按照号码大小顺序排序

 

                     mmi_phb_op_set_entry_rsp_name_number(&localPtr->list[0], store_index);    //把姓名和号码保存在PhoneBook[store_index]中。

 

                     mmi_phb_op_update_field_flag();//update fileter flag of each entry.

 

                     mmi_phb_bday_update_field(); //保存生日信息

                            ReadRecord(NVRAM_EF_PHB_BIRTHDAY_LID, bday_record, (void*)bday_data, NVRAM_EF_PHB_BIRTHDAY_SIZE, &pError);

                            拷贝pbYear, pbMon, pbDay到bday_data中;

                            WriteRecord(NVRAM_EF_PHB_BIRTHDAY_LID, bday_record, (void*)bday_data, NVRAM_EF_PHB_BIRTHDAY_SIZE, &pError);

 

                     mmi_phb_util_make_pinyin_cache(store_index);    // 把PhoneBook[store_index] 中姓名的拼音加入到g_phb_name_pinyin_index[store_index]中。

 

                     /* Insert name to name mapping table. */

              mmi_phb_sort_insert_name_index(store_index);

 

                     //如果是从CALL LOG中来保存一个entry,那么就更新这个call log

                     ReqUpdateCallLogName(PhoneBook[store_index].alpha_id.name_length, PhoneBook[store_index].alpha_id.name_dcs,

                                                PhoneBook[store_index].alpha_id.name);

 

                     mmi_phb_clear_old_add_history();   //删除历史screen                   

              }

       }

       else                                    //存储失败

       {

              提示错误信息;

              删除历史screen;             

       }

      

       g_phb_enter_from = MMI_PHB_ENTER_NONE;

    g_phb_cntx.current_op = MMI_PHB_OP_NONE;

}

 

 

三、电话列表

Phone Book

       3.View Phonebook         分类查看

              1.View SIM           SIM卡           MITEM111_PBOOK_VIEW_SIM_ENTRY

              2.View Phone         本机              MITEM111_PBOOK_VIEW_PHONE_ENTRY

1.SIM卡

mmi_phb_highlight_view_sim()

       mmi_phb_view_sim()

              g_edit_listview  = MMI_PHB_LIST_FOR_SIM; //每次进入phone entry list view时,都要设置这个变量。

              检查电话簿已经读取完毕,并且此刻没有电话簿的操作,SIM卡有号码

              mmi_phb_entry_list2(g_phb_cntx.sim_used, /*Total Entry*/

                                                   STR_PHB_VIEW, /*Title String*/

                                                   IMG_SCR_PBOOK_CAPTION, /*Title Image*/

                                                   STR_GLOBAL_OPTIONS, /*LSK*/

                                                   IMG_GLOBAL_OPTIONS, /*LSK*/

                                                   #if defined( __MMI_INTELLIGENT_CALL_ALERT__ )

                                                              mmi_phb_get_index_speak_name_sim,

                                                   #else

                                                             mmi_phb_get_index_sim,//mmi_phb_get_index, /*Highlight Callback*/    

                                                   #endif                                             

                                                   mmi_phb_entry_op_option_sim, /*LSK Callback*/

                                                   mmi_phb_choose_number_normal, /*SEND Key Callback*/

                                                   mmi_phb_list_get_item_sim,//mmi_phb_list_get_item, /*List Callback*/

                                                   mmi_phb_list_get_hint_sim,//mmi_phb_list_get_hint, /*Hint Callback*/

                                                   mmi_phb_view_sim, /*Re-Entry Callback*/

                                                   TRUE, /*Alpha Index*/

                                                   TRUE);       /*Right Arrow Key*/

       详细看上面注册的函数:

       (1)高亮:mmi_phb_get_index_sim()

                     设置:g_phb_cntx.active_index。注意:g_phb_cntx.active_index是在g_phb_name_index[]数组中的位置。0,1,2,3,4…。即:当前高亮的entry在数组:                         g_phb_name_index[]中的顺序位置。

       (2)左软件响应mmi_phb_entry_op_option_sim()

              ShowCategory15Screen() 每一个entry的选项菜单

       (3)SEND键响应mmi_phb_choose_number_normal()

              mmi_phb_list_pre_choose_number() //当该entry有多个号码时,让用户选择拨哪个

                     mmi_phb_entry_list_choose_number()

       (4)获取SIM卡item:mmi_phb_list_get_item_sim()

                     获取SIM卡中entry的姓名。没有姓名的就获取号码

       (5)hint callback:mmi_phb_list_get_hint_sim()

                     获取hint信息:号码

 

mmi_phb_entry_list2( )

       mmi_phb_list_build_alpha_index()   //用户快捷方式。按照g_phb_name_index[]中保存的字母顺序,提取PhoneBook中的姓名,按照首字母的顺序以字母(26个)为索                 引,把每个entry在电话列表中的list index保存在g_phb_alpha_index_list[]中。即:g_phb_alpha_index_list[]中保存的是该entry的list index。这样,当用户输入某个字         母时,如:c,那么就可以直接跳转到g_phb_alpha_index_list[2]的值所指示的位置。

       ShowCategory184Screen()

              ShowCategory185Screen()

                     init_dynamic_item_buffer()

                            dynamic_item_buffer.load_func = get_item_func;

                         dynamic_item_buffer.hint_func = get_hint_func;

                     load_dynamic_item_buffer()

                            for (i = 0; i < n_items; i++)

                         {

                             if (dynamic_item_buffer.load_func(i, (UI_string_type) subMenuData[i], &image, 3))//调用刚才注册的获取item函数。

                             {

                                 MMI_fixed_icontext_menuitems[i].item_icon = image;

                                 MMI_fixed_icontext_menuitems[i].item_text = (UI_string_type) subMenuData[i];

                                 MMI_fixed_icontext_menuitems[i].flags = flags;  /* 032905 Calvin modified */

                                 dynamic_item_buffer.count++;

                             }

                             else

                             {

                                 break;

                             }

                         }

 

 

       if(alpha_index)       //快捷方式所需要的设置。其他地方如果需要这样处理的可以参考。比如:在gap205的区号查询中。

       {

              register_multitap_no_draw_key_handlers();

              set_multitap_functions(mmi_phb_list_alpha_index, mmi_phb_list_alpha_index_input_callback);

              change_multitap_mode(0);

       }

 

小结:在show 电话号码列表时,也就是SHOW动态的 LIST。过程是:从g_phb_name_index[]中取出每个entryPhoneBook[]中的store_index,然后获取PhoneBook[]中的姓名,转载subMenuData[],最后拷贝到MMI_fixed_icontext_menuitems[]中。

阅读(3003) | 评论(1) | 转发(1) |
0

上一篇:start_kernel()函数分析

下一篇:當我已老

给主人留下些什么吧!~~

chinaunix网友2010-01-28 13:38:47

写得很详细啊。